aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/pdf
diff options
context:
space:
mode:
Diffstat (limited to 'src/pdf')
-rw-r--r--src/pdf/SkPDFDevice.cpp1
-rw-r--r--src/pdf/SkPDFDeviceFlattener.cpp155
-rw-r--r--src/pdf/SkPDFDeviceFlattener.h53
-rw-r--r--src/pdf/SkPDFShader.cpp3
4 files changed, 211 insertions, 1 deletions
diff --git a/src/pdf/SkPDFDevice.cpp b/src/pdf/SkPDFDevice.cpp
index 538422c510..43117a2b2f 100644
--- a/src/pdf/SkPDFDevice.cpp
+++ b/src/pdf/SkPDFDevice.cpp
@@ -2034,6 +2034,7 @@ void SkPDFDevice::internalDrawBitmap(const SkMatrix& matrix,
const SkBitmap& bitmap,
const SkIRect* srcRect,
const SkPaint& paint) {
+ // TODO(edisonn): Perspective matrix support implemented here
SkMatrix scaled;
// Adjust for origin flip.
scaled.setScale(SK_Scalar1, -SK_Scalar1);
diff --git a/src/pdf/SkPDFDeviceFlattener.cpp b/src/pdf/SkPDFDeviceFlattener.cpp
new file mode 100644
index 0000000000..9c0bf41db2
--- /dev/null
+++ b/src/pdf/SkPDFDeviceFlattener.cpp
@@ -0,0 +1,155 @@
+/*
+ * Copyright 2013 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "SkPDFDeviceFlattener.h"
+
+#include "SkDraw.h"
+
+static SkISize SkSizeToISize(const SkSize& size) {
+ return SkISize::Make(SkScalarRoundToInt(size.width()), SkScalarRoundToInt(size.height()));
+}
+
+SkPDFDeviceFlattener::SkPDFDeviceFlattener(const SkSize& pageSize, const SkRect* trimBox)
+ : SkPDFDevice(SkSizeToISize(pageSize),
+ SkSizeToISize(pageSize),
+ SkMatrix::I()) {
+ // TODO(edisonn): store the trimbox on emit.
+}
+
+SkPDFDeviceFlattener::~SkPDFDeviceFlattener() {
+}
+
+static void flattenPaint(const SkDraw& d, SkPaint* paint) {
+ if (paint->getShader()) {
+ SkMatrix local = paint->getShader()->getLocalMatrix();
+ local.preConcat(*d.fMatrix);
+ paint->getShader()->setLocalMatrix(local);
+ }
+}
+
+void SkPDFDeviceFlattener::drawPoints(const SkDraw& d, SkCanvas::PointMode mode,
+ size_t count, const SkPoint points[],
+ const SkPaint& paint) {
+ if (!mustFlatten(d)) {
+ INHERITED::drawPoints(d, mode, count, points, paint);
+ return;
+ }
+
+ SkPaint paintFlatten(paint);
+ flattenPaint(d, &paintFlatten);
+
+ SkPoint* flattenedPoints = SkNEW_ARRAY(SkPoint, count);
+ d.fMatrix->mapPoints(flattenedPoints, points, count);
+ SkDraw draw(d);
+ SkMatrix identity = SkMatrix::I();
+ draw.fMatrix = &identity;
+ INHERITED::drawPoints(draw, mode, count, flattenedPoints, paintFlatten);
+ SkDELETE_ARRAY(flattenedPoints);
+}
+
+void SkPDFDeviceFlattener::drawRect(const SkDraw& d, const SkRect& r, const SkPaint& paint) {
+ if (!mustFlatten(d)) {
+ INHERITED::drawRect(d, r, paint);
+ return;
+ }
+
+ SkPath path;
+ path.addRect(r);
+ path.transform(*d.fMatrix);
+ SkDraw draw(d);
+ SkMatrix matrix = SkMatrix::I();
+ draw.fMatrix = &matrix;
+
+ SkPaint paintFlatten(paint);
+ flattenPaint(d, &paintFlatten);
+
+ INHERITED::drawPath(draw, path, paintFlatten, NULL, true);
+}
+
+void SkPDFDeviceFlattener::drawPath(const SkDraw& d, const SkPath& origPath,
+ const SkPaint& paint, const SkMatrix* prePathMatrix,
+ bool pathIsMutable) {
+ if (!mustFlatten(d) && !(prePathMatrix && prePathMatrix->hasPerspective())) {
+ INHERITED::drawPath(d, origPath, paint, prePathMatrix, pathIsMutable);
+ return;
+ }
+
+ SkPath* pathPtr = (SkPath*)&origPath;
+ SkPath tmpPath;
+
+ if (!pathIsMutable) {
+ tmpPath = origPath;
+ pathPtr = &tmpPath;
+ }
+
+ if (prePathMatrix) {
+ pathPtr->transform(*prePathMatrix);
+ }
+
+ SkPaint paintFlatten(paint);
+ flattenPaint(d, &paintFlatten);
+
+ bool fill = paintFlatten.getFillPath(*pathPtr, &tmpPath);
+ SkDEBUGCODE(pathPtr = (SkPath*)0x12345678); // Don't use pathPtr after this point.
+
+ paintFlatten.setPathEffect(NULL);
+ if (fill) {
+ paintFlatten.setStyle(SkPaint::kFill_Style);
+ } else {
+ paintFlatten.setStyle(SkPaint::kStroke_Style);
+ paintFlatten.setStrokeWidth(0);
+ }
+
+ tmpPath.transform(*d.fMatrix);
+
+ SkDraw draw(d);
+ SkMatrix matrix = SkMatrix::I();
+ draw.fMatrix = &matrix;
+
+ INHERITED::drawPath(draw, tmpPath, paintFlatten, NULL, true);
+}
+
+void SkPDFDeviceFlattener::drawText(const SkDraw& d, const void* text, size_t len,
+ SkScalar x, SkScalar y, const SkPaint& paint) {
+ if (mustPathText(d, paint)) {
+ d.drawText_asPaths((const char*)text, len, x, y, paint);
+ return;
+ }
+
+ INHERITED::drawText(d, text, len, x, y, paint);
+}
+
+void SkPDFDeviceFlattener::drawPosText(const SkDraw& d, const void* text, size_t len,
+ const SkScalar pos[], SkScalar constY,
+ int scalarsPerPos, const SkPaint& paint) {
+ if (mustPathText(d, paint)) {
+ d.drawPosText_asPaths((const char*)text, len, pos, constY, scalarsPerPos, paint);
+ return;
+ }
+ INHERITED::drawPosText(d, text, len, pos, constY,scalarsPerPos, paint);
+}
+
+void SkPDFDeviceFlattener::drawTextOnPath(const SkDraw& d, const void* text, size_t len,
+ const SkPath& path, const SkMatrix* matrix,
+ const SkPaint& paint) {
+ if (mustPathText(d, paint) || (matrix && matrix->hasPerspective())) {
+ d.drawTextOnPath((const char*)text, len, path, matrix, paint);
+ return;
+ }
+ INHERITED::drawTextOnPath(d, text, len, path, matrix, paint);
+}
+
+bool SkPDFDeviceFlattener::mustFlatten(const SkDraw& d) const {
+ // TODO(edisonn): testability, add flag to force return true.
+ return d.fMatrix->hasPerspective();
+}
+
+bool SkPDFDeviceFlattener::mustPathText(const SkDraw& d, const SkPaint&) {
+ // TODO(edisonn): testability, add flag to force return true.
+ // TODO(edisonn): TBD: How to flatten MaskFilter.
+ return d.fMatrix->hasPerspective();
+}
diff --git a/src/pdf/SkPDFDeviceFlattener.h b/src/pdf/SkPDFDeviceFlattener.h
new file mode 100644
index 0000000000..f1047db3fc
--- /dev/null
+++ b/src/pdf/SkPDFDeviceFlattener.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2013 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkPDFDeviceFlattener_DEFINED
+#define SkPDFDeviceFlattener_DEFINED
+
+#include "SkPDFDevice.h"
+
+
+/** \class SkPDFDeviceFlattener
+
+ The PDF Device Flattener is used to flatten features without native support in PDF.
+ For now, the only one implemented is Perspective.
+
+ TODO(edisonn): Rename the class once we know all the things it will do.
+*/
+class SkPDFDeviceFlattener : public SkPDFDevice {
+private:
+ typedef SkPDFDevice INHERITED;
+
+ SK_API SkPDFDeviceFlattener(const SkSize& pageSize, const SkRect* trimBox = NULL);
+
+public:
+ SK_API virtual ~SkPDFDeviceFlattener();
+
+ virtual void drawPoints(const SkDraw&, SkCanvas::PointMode mode,
+ size_t count, const SkPoint[],
+ const SkPaint& paint) SK_OVERRIDE;
+ virtual void drawRect(const SkDraw&, const SkRect& r, const SkPaint& paint);
+ virtual void drawPath(const SkDraw&, const SkPath& origpath,
+ const SkPaint& paint, const SkMatrix* prePathMatrix,
+ bool pathIsMutable) SK_OVERRIDE;
+ virtual void drawText(const SkDraw&, const void* text, size_t len,
+ SkScalar x, SkScalar y, const SkPaint&) SK_OVERRIDE;
+ virtual void drawPosText(const SkDraw&, const void* text, size_t len,
+ const SkScalar pos[], SkScalar constY,
+ int scalarsPerPos, const SkPaint&) SK_OVERRIDE;
+ virtual void drawTextOnPath(const SkDraw&, const void* text, size_t len,
+ const SkPath& path, const SkMatrix* matrix,
+ const SkPaint& paint) SK_OVERRIDE;
+private:
+
+ bool mustFlatten(const SkDraw& d) const;
+ bool mustPathText(const SkDraw& d, const SkPaint& paint);
+
+ friend class SkDocument_PDF;
+};
+
+#endif // SkPDFDeviceFlattener_DEFINED
diff --git a/src/pdf/SkPDFShader.cpp b/src/pdf/SkPDFShader.cpp
index 80ea2f2ce7..70fb616a24 100644
--- a/src/pdf/SkPDFShader.cpp
+++ b/src/pdf/SkPDFShader.cpp
@@ -9,7 +9,6 @@
#include "SkPDFShader.h"
-#include "SkCanvas.h"
#include "SkData.h"
#include "SkPDFCatalog.h"
#include "SkPDFDevice.h"
@@ -870,6 +869,8 @@ SkPDFImageShader::SkPDFImageShader(SkPDFShader::State* state) : fState(state) {
unflip.preScale(SK_Scalar1, -SK_Scalar1);
SkISize size = SkISize::Make(SkScalarRound(deviceBounds.width()),
SkScalarRound(deviceBounds.height()));
+ // TODO(edisonn): should we pass here the DCT encoder of the destination device?
+ // TODO(edisonn): NYI Perspective, use SkPDFDeviceFlattener.
SkPDFDevice pattern(size, size, unflip);
SkCanvas canvas(&pattern);