| OLD | NEW |
| (Empty) |
| 1 /* | |
| 2 * Copyright 2013 Google Inc. | |
| 3 * | |
| 4 * Use of this source code is governed by a BSD-style license that can be | |
| 5 * found in the LICENSE file. | |
| 6 */ | |
| 7 | |
| 8 #include "SkPDFDeviceFlattener.h" | |
| 9 #include "SkDraw.h" | |
| 10 | |
| 11 static SkISize SkSizeToISize(const SkSize& size) { | |
| 12 return SkISize::Make(SkScalarRoundToInt(size.width()), SkScalarRoundToInt(si
ze.height())); | |
| 13 } | |
| 14 | |
| 15 SkPDFDeviceFlattener::SkPDFDeviceFlattener(const SkSize& pageSize, const SkRect*
trimBox) | |
| 16 : SkPDFDevice(SkSizeToISize(pageSize), | |
| 17 SkSizeToISize(pageSize), | |
| 18 SkMatrix::I()) { | |
| 19 // TODO(edisonn): store the trimbox on emit. | |
| 20 } | |
| 21 | |
| 22 SkPDFDeviceFlattener::~SkPDFDeviceFlattener() { | |
| 23 } | |
| 24 | |
| 25 static void flattenPaint(const SkDraw& d, SkPaint* paint) { | |
| 26 if (paint->getShader()) { | |
| 27 SkAutoTUnref<SkShader> lms(SkShader::CreateLocalMatrixShader(paint->getS
hader(), | |
| 28 *d.fMatrix)
); | |
| 29 paint->setShader(lms); | |
| 30 } | |
| 31 } | |
| 32 | |
| 33 void SkPDFDeviceFlattener::drawPoints(const SkDraw& d, SkCanvas::PointMode mode, | |
| 34 size_t count, const SkPoint points[], | |
| 35 const SkPaint& paint) { | |
| 36 if (!mustFlatten(d)) { | |
| 37 INHERITED::drawPoints(d, mode, count, points, paint); | |
| 38 return; | |
| 39 } | |
| 40 | |
| 41 SkPaint paintFlatten(paint); | |
| 42 flattenPaint(d, &paintFlatten); | |
| 43 | |
| 44 SkPoint* flattenedPoints = SkNEW_ARRAY(SkPoint, count); | |
| 45 d.fMatrix->mapPoints(flattenedPoints, points, SkToS32(count)); | |
| 46 SkDraw draw(d); | |
| 47 SkMatrix identity = SkMatrix::I(); | |
| 48 draw.fMatrix = &identity; | |
| 49 INHERITED::drawPoints(draw, mode, count, flattenedPoints, paintFlatten); | |
| 50 SkDELETE_ARRAY(flattenedPoints); | |
| 51 } | |
| 52 | |
| 53 void SkPDFDeviceFlattener::drawRect(const SkDraw& d, const SkRect& r, const SkPa
int& paint) { | |
| 54 if (!mustFlatten(d)) { | |
| 55 INHERITED::drawRect(d, r, paint); | |
| 56 return; | |
| 57 } | |
| 58 | |
| 59 SkPath path; | |
| 60 path.addRect(r); | |
| 61 path.transform(*d.fMatrix); | |
| 62 SkDraw draw(d); | |
| 63 SkMatrix matrix = SkMatrix::I(); | |
| 64 draw.fMatrix = &matrix; | |
| 65 | |
| 66 SkPaint paintFlatten(paint); | |
| 67 flattenPaint(d, &paintFlatten); | |
| 68 | |
| 69 INHERITED::drawPath(draw, path, paintFlatten, NULL, true); | |
| 70 } | |
| 71 | |
| 72 void SkPDFDeviceFlattener::drawPath(const SkDraw& d, const SkPath& origPath, | |
| 73 const SkPaint& paint, const SkMatrix* prePat
hMatrix, | |
| 74 bool pathIsMutable) { | |
| 75 if (!mustFlatten(d) && !(prePathMatrix && prePathMatrix->hasPerspective()))
{ | |
| 76 INHERITED::drawPath(d, origPath, paint, prePathMatrix, pathIsMutable); | |
| 77 return; | |
| 78 } | |
| 79 | |
| 80 SkPath* pathPtr = (SkPath*)&origPath; | |
| 81 SkPath tmpPath; | |
| 82 | |
| 83 if (!pathIsMutable) { | |
| 84 tmpPath = origPath; | |
| 85 pathPtr = &tmpPath; | |
| 86 } | |
| 87 | |
| 88 if (prePathMatrix) { | |
| 89 pathPtr->transform(*prePathMatrix); | |
| 90 } | |
| 91 | |
| 92 SkPaint paintFlatten(paint); | |
| 93 flattenPaint(d, &paintFlatten); | |
| 94 | |
| 95 bool fill = paintFlatten.getFillPath(*pathPtr, &tmpPath); | |
| 96 SkDEBUGCODE(pathPtr = (SkPath*)0x12345678); // Don't use pathPtr after this
point. | |
| 97 | |
| 98 paintFlatten.setPathEffect(NULL); | |
| 99 if (fill) { | |
| 100 paintFlatten.setStyle(SkPaint::kFill_Style); | |
| 101 } else { | |
| 102 paintFlatten.setStyle(SkPaint::kStroke_Style); | |
| 103 paintFlatten.setStrokeWidth(0); | |
| 104 } | |
| 105 | |
| 106 tmpPath.transform(*d.fMatrix); | |
| 107 | |
| 108 SkDraw draw(d); | |
| 109 SkMatrix matrix = SkMatrix::I(); | |
| 110 draw.fMatrix = &matrix; | |
| 111 | |
| 112 INHERITED::drawPath(draw, tmpPath, paintFlatten, NULL, true); | |
| 113 } | |
| 114 | |
| 115 void SkPDFDeviceFlattener::drawText(const SkDraw& d, const void* text, size_t le
n, | |
| 116 SkScalar x, SkScalar y, const SkPaint& paint
) { | |
| 117 if (mustPathText(d, paint)) { | |
| 118 d.drawText_asPaths((const char*)text, len, x, y, paint); | |
| 119 return; | |
| 120 } | |
| 121 | |
| 122 INHERITED::drawText(d, text, len, x, y, paint); | |
| 123 } | |
| 124 | |
| 125 void SkPDFDeviceFlattener::drawPosText(const SkDraw& d, const void* text, size_t
len, | |
| 126 const SkScalar pos[], int scalarsPerPos, | |
| 127 const SkPoint& offset, const SkPaint& pai
nt) { | |
| 128 if (mustPathText(d, paint)) { | |
| 129 d.drawPosText_asPaths((const char*)text, len, pos, scalarsPerPos, offset
, paint); | |
| 130 return; | |
| 131 } | |
| 132 INHERITED::drawPosText(d, text, len, pos, scalarsPerPos, offset, paint); | |
| 133 } | |
| 134 | |
| 135 bool SkPDFDeviceFlattener::mustFlatten(const SkDraw& d) const { | |
| 136 // TODO(edisonn): testability, add flag to force return true. | |
| 137 return d.fMatrix->hasPerspective(); | |
| 138 } | |
| 139 | |
| 140 bool SkPDFDeviceFlattener::mustPathText(const SkDraw& d, const SkPaint&) { | |
| 141 // TODO(edisonn): testability, add flag to force return true. | |
| 142 // TODO(edisonn): TBD: How to flatten MaskFilter. | |
| 143 return d.fMatrix->hasPerspective(); | |
| 144 } | |
| OLD | NEW |