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 |