Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(9)

Unified Diff: src/pdf/SkPDFDevice.cpp

Issue 24811002: Update the SkDocument interface to allow for 1) abort won't emit pdf, 2) close can report success/f… (Closed) Base URL: https://skia.googlecode.com/svn/trunk
Patch Set: update comments Created 7 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: src/pdf/SkPDFDevice.cpp
diff --git a/src/pdf/SkPDFDevice.cpp b/src/pdf/SkPDFDevice.cpp
index e4b07f04fa794bcd27373564411445a039cd4afe..c740c0d3a5b70c2ef097db106ed4ae28667e554a 100644
--- a/src/pdf/SkPDFDevice.cpp
+++ b/src/pdf/SkPDFDevice.cpp
@@ -723,6 +723,35 @@ SkPDFDevice::SkPDFDevice(const SkISize& pageSize, const SkISize& contentSize,
this->init();
}
+SkISize SkSizeToISize(const SkSize& size) {
+ return SkISize::Make(SkScalarRoundToInt(size.width()), SkScalarRoundToInt(size.height()));
+}
+
+SkPDFDevice::SkPDFDevice(const SkSize& trimBox, const SkRect& content)
+ : SkBitmapDevice(makeContentBitmap(SkSizeToISize(SkSize::Make(content.width(),
+ content.height())),
+ NULL)),
+ fPageSize(SkSizeToISize(SkSize::Make(content.width(), content.height()))),
+ fContentSize(SkSizeToISize(trimBox)),
+ fLastContentEntry(NULL),
+ fLastMarginContentEntry(NULL),
+ fClipStack(NULL),
+ fEncoder(NULL) {
+ // Skia generally uses the top left as the origin but PDF natively has the
+ // origin at the bottom left. This matrix corrects for that. But that only
+ // needs to be done once, we don't do it when layering.
+ fInitialTransform.reset();
+ fInitialTransform.setTranslate(0, SkIntToScalar(fPageSize.fHeight));
+ fInitialTransform.preScale(SK_Scalar1, -SK_Scalar1);
+ fInitialTransform.preTranslate(-content.left(), -content.top());
+
+ SkIRect existingClip = SkIRect::MakeWH(this->width(), this->height());
+ fExistingClipRegion.setRect(existingClip);
+
+ this->init();
+}
+
+
// TODO(vandebo) change layerSize to SkSize.
SkPDFDevice::SkPDFDevice(const SkISize& layerSize,
const SkClipStack& existingClipStack,
@@ -978,11 +1007,13 @@ void SkPDFDevice::drawPath(const SkDraw& d, const SkPath& origPath,
}
#endif
- if (handleRectAnnotation(pathPtr->getBounds(), *d.fMatrix, paint)) {
+ // fix from another cl
+ if (handleRectAnnotation(pathPtr->getBounds(), matrix, paint)) {
return;
}
- ScopedContentEntry content(this, d, paint);
+ // fix from another cl
+ ScopedContentEntry content(this, d.fClipStack, *d.fClip, matrix, paint);
if (!content.entry()) {
return;
}
@@ -2029,6 +2060,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);
@@ -2065,3 +2097,151 @@ bool SkPDFDevice::onReadPixels(const SkBitmap& bitmap, int x, int y,
bool SkPDFDevice::allowImageFilter(SkImageFilter*) {
return false;
}
+
+SkMatrix translate(const SkRect& content) {
reed1 2013/10/07 13:24:54 I see the need for a function, but can we give it
edisonn 2013/10/07 19:29:06 Done.
+ SkMatrix matrix;
+ matrix.setTranslate(-content.left(), -content.top());
+ return matrix;
+}
+
+SkPDFDeviceFlattener::SkPDFDeviceFlattener(const SkSize& trimBox, const SkRect& content)
+ : SkPDFDevice(SkSizeToISize(trimBox),
+ SkSizeToISize(SkSize::Make(content.width(), content.height())),
+ translate(content)) {
+}
+
+SkPDFDeviceFlattener::~SkPDFDeviceFlattener() {
+}
+
+void SkPDFDeviceFlattener::drawPaint(const SkDraw& d, const SkPaint& paint) {
+ INHERITED::drawPaint(d, paint);
+}
+
+void SkPDFDeviceFlattener::drawPoints(const SkDraw& d, SkCanvas::PointMode mode,
+ size_t count, const SkPoint points[],
+ const SkPaint& paint) {
+ if (mustFlatten(d)) {
+ 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, paint);
+ SkDELETE_ARRAY(flattenedPoints);
+ return;
+ }
+
+ INHERITED::drawPoints(d, mode, count, points, paint);
+}
+
+void SkPDFDeviceFlattener::drawRect(const SkDraw& d, const SkRect& r, const SkPaint& paint) {
+ if (mustFlatten(d)) {
+ SkPath path;
+ path.addRect(r);
+ path.transform(*d.fMatrix);
+ SkDraw draw(d);
+ SkMatrix matrix = SkMatrix::I();
+ draw.fMatrix = &matrix;
+
+ // todo optimize paint, don't build unless really needed
+ SkPaint paintFlatten = paint;
+ if (paintFlatten.getShader()) {
+ SkMatrix local = paintFlatten.getShader()->getLocalMatrix();
+ local.preConcat(*d.fMatrix);
+ paintFlatten.getShader()->setLocalMatrix(local);
+ }
+
+ INHERITED::drawPath(draw, path, paintFlatten, NULL, true);
+ return;
+ }
+
+ INHERITED::drawRect(d, r, paint);
+}
+
+void SkPDFDeviceFlattener::drawPath(const SkDraw& d, const SkPath& origpath,
+ const SkPaint& paint, const SkMatrix* prePathMatrix,
+ bool pathIsMutable) {
+ if (mustFlatten(d) || (prePathMatrix && prePathMatrix->hasPerspective())) {
+ SkPath path;
+ path.addPath(origpath);
+ if (prePathMatrix) {
+ path.transform(*prePathMatrix);
+ }
+ path.transform(*d.fMatrix);
+ SkDraw draw(d);
+ SkMatrix matrix = SkMatrix::I();
+ draw.fMatrix = &matrix;
+
+ // todo optimize paint, don't build unless really needed
+ SkPaint paintFlatten = paint;
+ if (paintFlatten.getShader()) {
+ // TODO(edisonn): order?
+ SkMatrix local = paintFlatten.getShader()->getLocalMatrix();
+ local.preConcat(*d.fMatrix);
+ if (prePathMatrix) {
+ local.preConcat(*prePathMatrix);
+ }
+ paintFlatten.getShader()->setLocalMatrix(local);
+ }
+
+ INHERITED::drawPath(draw, path, paintFlatten, NULL, true);
+ return;
+ }
+
+ INHERITED::drawPath(d, origpath, paint, prePathMatrix, pathIsMutable);
+}
+
+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);
+}
+
+void SkPDFDeviceFlattener::drawVertices(const SkDraw& d, SkCanvas::VertexMode mode,
+ int vertexCount, const SkPoint verts[],
+ const SkPoint texs[], const SkColor colors[],
+ SkXfermode* xmode, const uint16_t indices[],
+ int indexCount, const SkPaint& paint) {
+ INHERITED::drawVertices(d, mode, vertexCount, verts, texs, colors, xmode, indices, indexCount,
+ paint);
+}
+
+void SkPDFDeviceFlattener::drawDevice(const SkDraw& d, SkBaseDevice* dev, int x, int y,
+ const SkPaint& paint) {
+ INHERITED::drawDevice(d, dev, x, y, 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();
+}

Powered by Google App Engine
This is Rietveld 408576698