Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 /* | 1 /* |
| 2 * Copyright 2011 Google Inc. | 2 * Copyright 2011 Google Inc. |
| 3 * | 3 * |
| 4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
| 5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
| 6 */ | 6 */ |
| 7 | 7 |
| 8 #include "SkPDFDevice.h" | 8 #include "SkPDFDevice.h" |
| 9 | 9 |
| 10 #include "SkAnnotation.h" | 10 #include "SkAnnotation.h" |
| (...skipping 705 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 716 fInitialTransform.setTranslate(0, SkIntToScalar(pageSize.fHeight)); | 716 fInitialTransform.setTranslate(0, SkIntToScalar(pageSize.fHeight)); |
| 717 fInitialTransform.preScale(SK_Scalar1, -SK_Scalar1); | 717 fInitialTransform.preScale(SK_Scalar1, -SK_Scalar1); |
| 718 fInitialTransform.preConcat(initialTransform); | 718 fInitialTransform.preConcat(initialTransform); |
| 719 | 719 |
| 720 SkIRect existingClip = SkIRect::MakeWH(this->width(), this->height()); | 720 SkIRect existingClip = SkIRect::MakeWH(this->width(), this->height()); |
| 721 fExistingClipRegion.setRect(existingClip); | 721 fExistingClipRegion.setRect(existingClip); |
| 722 | 722 |
| 723 this->init(); | 723 this->init(); |
| 724 } | 724 } |
| 725 | 725 |
| 726 SkISize SkSizeToISize(const SkSize& size) { | |
| 727 return SkISize::Make(SkScalarRoundToInt(size.width()), SkScalarRoundToInt(si ze.height())); | |
| 728 } | |
| 729 | |
| 730 SkPDFDevice::SkPDFDevice(const SkSize& trimBox, const SkRect& content) | |
| 731 : SkBitmapDevice(makeContentBitmap(SkSizeToISize(SkSize::Make(content.width( ), | |
| 732 content.height ())), | |
| 733 NULL)), | |
| 734 fPageSize(SkSizeToISize(SkSize::Make(content.width(), content.height()))), | |
| 735 fContentSize(SkSizeToISize(trimBox)), | |
| 736 fLastContentEntry(NULL), | |
| 737 fLastMarginContentEntry(NULL), | |
| 738 fClipStack(NULL), | |
| 739 fEncoder(NULL) { | |
| 740 // Skia generally uses the top left as the origin but PDF natively has the | |
| 741 // origin at the bottom left. This matrix corrects for that. But that only | |
| 742 // needs to be done once, we don't do it when layering. | |
| 743 fInitialTransform.reset(); | |
| 744 fInitialTransform.setTranslate(0, SkIntToScalar(fPageSize.fHeight)); | |
| 745 fInitialTransform.preScale(SK_Scalar1, -SK_Scalar1); | |
| 746 fInitialTransform.preTranslate(-content.left(), -content.top()); | |
| 747 | |
| 748 SkIRect existingClip = SkIRect::MakeWH(this->width(), this->height()); | |
| 749 fExistingClipRegion.setRect(existingClip); | |
| 750 | |
| 751 this->init(); | |
| 752 } | |
| 753 | |
| 754 | |
| 726 // TODO(vandebo) change layerSize to SkSize. | 755 // TODO(vandebo) change layerSize to SkSize. |
| 727 SkPDFDevice::SkPDFDevice(const SkISize& layerSize, | 756 SkPDFDevice::SkPDFDevice(const SkISize& layerSize, |
| 728 const SkClipStack& existingClipStack, | 757 const SkClipStack& existingClipStack, |
| 729 const SkRegion& existingClipRegion) | 758 const SkRegion& existingClipRegion) |
| 730 : SkBitmapDevice(makeContentBitmap(layerSize, NULL)), | 759 : SkBitmapDevice(makeContentBitmap(layerSize, NULL)), |
| 731 fPageSize(layerSize), | 760 fPageSize(layerSize), |
| 732 fContentSize(layerSize), | 761 fContentSize(layerSize), |
| 733 fExistingClipStack(existingClipStack), | 762 fExistingClipStack(existingClipStack), |
| 734 fExistingClipRegion(existingClipRegion), | 763 fExistingClipRegion(existingClipRegion), |
| 735 fLastContentEntry(NULL), | 764 fLastContentEntry(NULL), |
| (...skipping 235 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 971 drawPath(d, *pathPtr, noEffectPaint, NULL, true); | 1000 drawPath(d, *pathPtr, noEffectPaint, NULL, true); |
| 972 return; | 1001 return; |
| 973 } | 1002 } |
| 974 | 1003 |
| 975 #ifdef SK_PDF_USE_PATHOPS | 1004 #ifdef SK_PDF_USE_PATHOPS |
| 976 if (handleInversePath(d, origPath, paint, pathIsMutable)) { | 1005 if (handleInversePath(d, origPath, paint, pathIsMutable)) { |
| 977 return; | 1006 return; |
| 978 } | 1007 } |
| 979 #endif | 1008 #endif |
| 980 | 1009 |
| 981 if (handleRectAnnotation(pathPtr->getBounds(), *d.fMatrix, paint)) { | 1010 // fix from another cl |
| 1011 if (handleRectAnnotation(pathPtr->getBounds(), matrix, paint)) { | |
| 982 return; | 1012 return; |
| 983 } | 1013 } |
| 984 | 1014 |
| 985 ScopedContentEntry content(this, d, paint); | 1015 // fix from another cl |
| 1016 ScopedContentEntry content(this, d.fClipStack, *d.fClip, matrix, paint); | |
| 986 if (!content.entry()) { | 1017 if (!content.entry()) { |
| 987 return; | 1018 return; |
| 988 } | 1019 } |
| 989 SkPDFUtils::EmitPath(*pathPtr, paint.getStyle(), | 1020 SkPDFUtils::EmitPath(*pathPtr, paint.getStyle(), |
| 990 &content.entry()->fContent); | 1021 &content.entry()->fContent); |
| 991 SkPDFUtils::PaintPath(paint.getStyle(), pathPtr->getFillType(), | 1022 SkPDFUtils::PaintPath(paint.getStyle(), pathPtr->getFillType(), |
| 992 &content.entry()->fContent); | 1023 &content.entry()->fContent); |
| 993 } | 1024 } |
| 994 | 1025 |
| 995 void SkPDFDevice::drawBitmapRect(const SkDraw& draw, const SkBitmap& bitmap, | 1026 void SkPDFDevice::drawBitmapRect(const SkDraw& draw, const SkBitmap& bitmap, |
| (...skipping 1026 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2022 } | 2053 } |
| 2023 return resourceIndex; | 2054 return resourceIndex; |
| 2024 } | 2055 } |
| 2025 | 2056 |
| 2026 void SkPDFDevice::internalDrawBitmap(const SkMatrix& matrix, | 2057 void SkPDFDevice::internalDrawBitmap(const SkMatrix& matrix, |
| 2027 const SkClipStack* clipStack, | 2058 const SkClipStack* clipStack, |
| 2028 const SkRegion& clipRegion, | 2059 const SkRegion& clipRegion, |
| 2029 const SkBitmap& bitmap, | 2060 const SkBitmap& bitmap, |
| 2030 const SkIRect* srcRect, | 2061 const SkIRect* srcRect, |
| 2031 const SkPaint& paint) { | 2062 const SkPaint& paint) { |
| 2063 // TODO(edisonn): Perspective matrix support implemented here | |
| 2032 SkMatrix scaled; | 2064 SkMatrix scaled; |
| 2033 // Adjust for origin flip. | 2065 // Adjust for origin flip. |
| 2034 scaled.setScale(SK_Scalar1, -SK_Scalar1); | 2066 scaled.setScale(SK_Scalar1, -SK_Scalar1); |
| 2035 scaled.postTranslate(0, SK_Scalar1); | 2067 scaled.postTranslate(0, SK_Scalar1); |
| 2036 // Scale the image up from 1x1 to WxH. | 2068 // Scale the image up from 1x1 to WxH. |
| 2037 SkIRect subset = SkIRect::MakeWH(bitmap.width(), bitmap.height()); | 2069 SkIRect subset = SkIRect::MakeWH(bitmap.width(), bitmap.height()); |
| 2038 scaled.postScale(SkIntToScalar(subset.width()), | 2070 scaled.postScale(SkIntToScalar(subset.width()), |
| 2039 SkIntToScalar(subset.height())); | 2071 SkIntToScalar(subset.height())); |
| 2040 scaled.postConcat(matrix); | 2072 scaled.postConcat(matrix); |
| 2041 ScopedContentEntry content(this, clipStack, clipRegion, scaled, paint); | 2073 ScopedContentEntry content(this, clipStack, clipRegion, scaled, paint); |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 2058 } | 2090 } |
| 2059 | 2091 |
| 2060 bool SkPDFDevice::onReadPixels(const SkBitmap& bitmap, int x, int y, | 2092 bool SkPDFDevice::onReadPixels(const SkBitmap& bitmap, int x, int y, |
| 2061 SkCanvas::Config8888) { | 2093 SkCanvas::Config8888) { |
| 2062 return false; | 2094 return false; |
| 2063 } | 2095 } |
| 2064 | 2096 |
| 2065 bool SkPDFDevice::allowImageFilter(SkImageFilter*) { | 2097 bool SkPDFDevice::allowImageFilter(SkImageFilter*) { |
| 2066 return false; | 2098 return false; |
| 2067 } | 2099 } |
| 2100 | |
| 2101 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.
| |
| 2102 SkMatrix matrix; | |
| 2103 matrix.setTranslate(-content.left(), -content.top()); | |
| 2104 return matrix; | |
| 2105 } | |
| 2106 | |
| 2107 SkPDFDeviceFlattener::SkPDFDeviceFlattener(const SkSize& trimBox, const SkRect& content) | |
| 2108 : SkPDFDevice(SkSizeToISize(trimBox), | |
| 2109 SkSizeToISize(SkSize::Make(content.width(), content.he ight())), | |
| 2110 translate(content)) { | |
| 2111 } | |
| 2112 | |
| 2113 SkPDFDeviceFlattener::~SkPDFDeviceFlattener() { | |
| 2114 } | |
| 2115 | |
| 2116 void SkPDFDeviceFlattener::drawPaint(const SkDraw& d, const SkPaint& paint) { | |
| 2117 INHERITED::drawPaint(d, paint); | |
| 2118 } | |
| 2119 | |
| 2120 void SkPDFDeviceFlattener::drawPoints(const SkDraw& d, SkCanvas::PointMode mode, | |
| 2121 size_t count, const SkPoint points[], | |
| 2122 const SkPaint& paint) { | |
| 2123 if (mustFlatten(d)) { | |
| 2124 SkPoint* flattenedPoints = SkNEW_ARRAY(SkPoint, count); | |
| 2125 d.fMatrix->mapPoints(flattenedPoints, points, count); | |
| 2126 SkDraw draw(d); | |
| 2127 SkMatrix identity = SkMatrix::I(); | |
| 2128 draw.fMatrix = &identity; | |
| 2129 INHERITED::drawPoints(draw, mode, count, flattenedPoints, paint); | |
| 2130 SkDELETE_ARRAY(flattenedPoints); | |
| 2131 return; | |
| 2132 } | |
| 2133 | |
| 2134 INHERITED::drawPoints(d, mode, count, points, paint); | |
| 2135 } | |
| 2136 | |
| 2137 void SkPDFDeviceFlattener::drawRect(const SkDraw& d, const SkRect& r, const SkPa int& paint) { | |
| 2138 if (mustFlatten(d)) { | |
| 2139 SkPath path; | |
| 2140 path.addRect(r); | |
| 2141 path.transform(*d.fMatrix); | |
| 2142 SkDraw draw(d); | |
| 2143 SkMatrix matrix = SkMatrix::I(); | |
| 2144 draw.fMatrix = &matrix; | |
| 2145 | |
| 2146 // todo optimize paint, don't build unless really needed | |
| 2147 SkPaint paintFlatten = paint; | |
| 2148 if (paintFlatten.getShader()) { | |
| 2149 SkMatrix local = paintFlatten.getShader()->getLocalMatrix(); | |
| 2150 local.preConcat(*d.fMatrix); | |
| 2151 paintFlatten.getShader()->setLocalMatrix(local); | |
| 2152 } | |
| 2153 | |
| 2154 INHERITED::drawPath(draw, path, paintFlatten, NULL, true); | |
| 2155 return; | |
| 2156 } | |
| 2157 | |
| 2158 INHERITED::drawRect(d, r, paint); | |
| 2159 } | |
| 2160 | |
| 2161 void SkPDFDeviceFlattener::drawPath(const SkDraw& d, const SkPath& origpath, | |
| 2162 const SkPaint& paint, const SkMatrix* prePat hMatrix, | |
| 2163 bool pathIsMutable) { | |
| 2164 if (mustFlatten(d) || (prePathMatrix && prePathMatrix->hasPerspective())) { | |
| 2165 SkPath path; | |
| 2166 path.addPath(origpath); | |
| 2167 if (prePathMatrix) { | |
| 2168 path.transform(*prePathMatrix); | |
| 2169 } | |
| 2170 path.transform(*d.fMatrix); | |
| 2171 SkDraw draw(d); | |
| 2172 SkMatrix matrix = SkMatrix::I(); | |
| 2173 draw.fMatrix = &matrix; | |
| 2174 | |
| 2175 // todo optimize paint, don't build unless really needed | |
| 2176 SkPaint paintFlatten = paint; | |
| 2177 if (paintFlatten.getShader()) { | |
| 2178 // TODO(edisonn): order? | |
| 2179 SkMatrix local = paintFlatten.getShader()->getLocalMatrix(); | |
| 2180 local.preConcat(*d.fMatrix); | |
| 2181 if (prePathMatrix) { | |
| 2182 local.preConcat(*prePathMatrix); | |
| 2183 } | |
| 2184 paintFlatten.getShader()->setLocalMatrix(local); | |
| 2185 } | |
| 2186 | |
| 2187 INHERITED::drawPath(draw, path, paintFlatten, NULL, true); | |
| 2188 return; | |
| 2189 } | |
| 2190 | |
| 2191 INHERITED::drawPath(d, origpath, paint, prePathMatrix, pathIsMutable); | |
| 2192 } | |
| 2193 | |
| 2194 void SkPDFDeviceFlattener::drawText(const SkDraw& d, const void* text, size_t le n, | |
| 2195 SkScalar x, SkScalar y, const SkPaint& paint ) { | |
| 2196 if (mustPathText(d, paint)) { | |
| 2197 d.drawText_asPaths((const char*)text, len, x, y, paint); | |
| 2198 return; | |
| 2199 } | |
| 2200 | |
| 2201 INHERITED::drawText(d, text, len, x, y, paint); | |
| 2202 } | |
| 2203 | |
| 2204 void SkPDFDeviceFlattener::drawPosText(const SkDraw& d, const void* text, size_t len, | |
| 2205 const SkScalar pos[], SkScalar constY, | |
| 2206 int scalarsPerPos, const SkPaint& paint) { | |
| 2207 if (mustPathText(d, paint)) { | |
| 2208 d.drawPosText_asPaths((const char*)text, len, pos, constY, scalarsPerPos , paint); | |
| 2209 return; | |
| 2210 } | |
| 2211 INHERITED::drawPosText(d, text, len,pos, constY,scalarsPerPos, paint); | |
| 2212 } | |
| 2213 | |
| 2214 void SkPDFDeviceFlattener::drawTextOnPath(const SkDraw& d, const void* text, siz e_t len, | |
| 2215 const SkPath& path, const SkMatrix* ma trix, | |
| 2216 const SkPaint& paint) { | |
| 2217 if (mustPathText(d, paint) || (matrix && matrix->hasPerspective())) { | |
| 2218 d.drawTextOnPath((const char*)text, len, path, matrix, paint); | |
| 2219 return; | |
| 2220 } | |
| 2221 INHERITED::drawTextOnPath(d, text, len, path, matrix, paint); | |
| 2222 } | |
| 2223 | |
| 2224 void SkPDFDeviceFlattener::drawVertices(const SkDraw& d, SkCanvas::VertexMode mo de, | |
| 2225 int vertexCount, const SkPoint verts[], | |
| 2226 const SkPoint texs[], const SkColor colo rs[], | |
| 2227 SkXfermode* xmode, const uint16_t indice s[], | |
| 2228 int indexCount, const SkPaint& paint) { | |
| 2229 INHERITED::drawVertices(d, mode, vertexCount, verts, texs, colors, xmode, in dices, indexCount, | |
| 2230 paint); | |
| 2231 } | |
| 2232 | |
| 2233 void SkPDFDeviceFlattener::drawDevice(const SkDraw& d, SkBaseDevice* dev, int x, int y, | |
| 2234 const SkPaint& paint) { | |
| 2235 INHERITED::drawDevice(d, dev, x, y, paint); | |
| 2236 } | |
| 2237 | |
| 2238 bool SkPDFDeviceFlattener::mustFlatten(const SkDraw& d) const { | |
| 2239 // TODO(edisonn): testability, add flag to force return true. | |
| 2240 return d.fMatrix->hasPerspective(); | |
| 2241 } | |
| 2242 | |
| 2243 bool SkPDFDeviceFlattener::mustPathText(const SkDraw& d, const SkPaint&) { | |
| 2244 // TODO(edisonn): testability, add flag to force return true. | |
| 2245 // TODO(edisonn): TBD: How to flatten MaskFilter. | |
| 2246 return d.fMatrix->hasPerspective(); | |
| 2247 } | |
| OLD | NEW |