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 |