| 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 "SkAnnotationKeys.h" | 10 #include "SkAnnotationKeys.h" |
| (...skipping 1042 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1053 if (bitmap.isOpaque()) { | 1053 if (bitmap.isOpaque()) { |
| 1054 replace_srcmode_on_opaque_paint(&paint); | 1054 replace_srcmode_on_opaque_paint(&paint); |
| 1055 } | 1055 } |
| 1056 | 1056 |
| 1057 if (d.fClip->isEmpty()) { | 1057 if (d.fClip->isEmpty()) { |
| 1058 return; | 1058 return; |
| 1059 } | 1059 } |
| 1060 | 1060 |
| 1061 SkMatrix transform = matrix; | 1061 SkMatrix transform = matrix; |
| 1062 transform.postConcat(*d.fMatrix); | 1062 transform.postConcat(*d.fMatrix); |
| 1063 const SkImage* image = fDocument->canon()->bitmapToImage(bitmap); | 1063 SkImageBitmap imageBitmap(bitmap); |
| 1064 if (!image) { | 1064 this->internalDrawImage( |
| 1065 return; | 1065 transform, d.fClipStack, *d.fClip, imageBitmap, paint); |
| 1066 } | |
| 1067 this->internalDrawImage(transform, d.fClipStack, *d.fClip, image, nullptr, | |
| 1068 paint); | |
| 1069 } | 1066 } |
| 1070 | 1067 |
| 1071 void SkPDFDevice::drawSprite(const SkDraw& d, | 1068 void SkPDFDevice::drawSprite(const SkDraw& d, |
| 1072 const SkBitmap& bitmap, | 1069 const SkBitmap& bitmap, |
| 1073 int x, | 1070 int x, |
| 1074 int y, | 1071 int y, |
| 1075 const SkPaint& srcPaint) { | 1072 const SkPaint& srcPaint) { |
| 1076 SkPaint paint = srcPaint; | 1073 SkPaint paint = srcPaint; |
| 1077 if (bitmap.isOpaque()) { | 1074 if (bitmap.isOpaque()) { |
| 1078 replace_srcmode_on_opaque_paint(&paint); | 1075 replace_srcmode_on_opaque_paint(&paint); |
| 1079 } | 1076 } |
| 1080 | 1077 |
| 1081 if (d.fClip->isEmpty()) { | 1078 if (d.fClip->isEmpty()) { |
| 1082 return; | 1079 return; |
| 1083 } | 1080 } |
| 1084 | 1081 |
| 1085 SkMatrix matrix; | 1082 SkMatrix matrix; |
| 1086 matrix.setTranslate(SkIntToScalar(x), SkIntToScalar(y)); | 1083 matrix.setTranslate(SkIntToScalar(x), SkIntToScalar(y)); |
| 1087 const SkImage* image = fDocument->canon()->bitmapToImage(bitmap); | 1084 SkImageBitmap imageBitmap(bitmap); |
| 1088 if (!image) { | 1085 this->internalDrawImage( |
| 1089 return; | 1086 matrix, d.fClipStack, *d.fClip, imageBitmap, paint); |
| 1090 } | |
| 1091 this->internalDrawImage(matrix, d.fClipStack, *d.fClip, image, nullptr, | |
| 1092 paint); | |
| 1093 } | 1087 } |
| 1094 | 1088 |
| 1095 void SkPDFDevice::drawImage(const SkDraw& draw, | 1089 void SkPDFDevice::drawImage(const SkDraw& draw, |
| 1096 const SkImage* image, | 1090 const SkImage* image, |
| 1097 SkScalar x, | 1091 SkScalar x, |
| 1098 SkScalar y, | 1092 SkScalar y, |
| 1099 const SkPaint& srcPaint) { | 1093 const SkPaint& srcPaint) { |
| 1100 SkPaint paint = srcPaint; | 1094 SkPaint paint = srcPaint; |
| 1101 if (!image) { | 1095 if (!image) { |
| 1102 return; | 1096 return; |
| 1103 } | 1097 } |
| 1104 if (image->isOpaque()) { | 1098 if (image->isOpaque()) { |
| 1105 replace_srcmode_on_opaque_paint(&paint); | 1099 replace_srcmode_on_opaque_paint(&paint); |
| 1106 } | 1100 } |
| 1107 if (draw.fClip->isEmpty()) { | 1101 if (draw.fClip->isEmpty()) { |
| 1108 return; | 1102 return; |
| 1109 } | 1103 } |
| 1110 SkMatrix transform = SkMatrix::MakeTrans(x, y); | 1104 SkMatrix transform = SkMatrix::MakeTrans(x, y); |
| 1111 transform.postConcat(*draw.fMatrix); | 1105 transform.postConcat(*draw.fMatrix); |
| 1112 this->internalDrawImage(transform, draw.fClipStack, *draw.fClip, image, | 1106 SkImageBitmap imageBitmap(const_cast<SkImage*>(image)); |
| 1113 nullptr, paint); | 1107 this->internalDrawImage( |
| 1108 transform, draw.fClipStack, *draw.fClip, imageBitmap, paint); |
| 1114 } | 1109 } |
| 1115 | 1110 |
| 1116 void SkPDFDevice::drawImageRect(const SkDraw& draw, | 1111 void SkPDFDevice::drawImageRect(const SkDraw& draw, |
| 1117 const SkImage* image, | 1112 const SkImage* image, |
| 1118 const SkRect* src, | 1113 const SkRect* src, |
| 1119 const SkRect& dst, | 1114 const SkRect& dst, |
| 1120 const SkPaint& srcPaint, | 1115 const SkPaint& srcPaint, |
| 1121 SkCanvas::SrcRectConstraint constraint) { | 1116 SkCanvas::SrcRectConstraint constraint) { |
| 1122 SkASSERT(false); | 1117 SkASSERT(false); |
| 1123 } | 1118 } |
| (...skipping 983 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2107 fFontResources.push(newFont.get()); | 2102 fFontResources.push(newFont.get()); |
| 2108 newFont.get()->ref(); | 2103 newFont.get()->ref(); |
| 2109 } | 2104 } |
| 2110 return resourceIndex; | 2105 return resourceIndex; |
| 2111 } | 2106 } |
| 2112 | 2107 |
| 2113 static SkSize rect_to_size(const SkRect& r) { | 2108 static SkSize rect_to_size(const SkRect& r) { |
| 2114 return SkSize::Make(r.width(), r.height()); | 2109 return SkSize::Make(r.width(), r.height()); |
| 2115 } | 2110 } |
| 2116 | 2111 |
| 2117 static const SkImage* color_filter(const SkImage* image, SkColorFilter* colorFil
ter) { | 2112 static sk_sp<SkImage> color_filter(const SkImageBitmap& imageBitmap, |
| 2113 SkColorFilter* colorFilter) { |
| 2118 sk_sp<SkSurface> surface(SkSurface::NewRaster( | 2114 sk_sp<SkSurface> surface(SkSurface::NewRaster( |
| 2119 SkImageInfo::MakeN32Premul(image->dimensions()))); | 2115 SkImageInfo::MakeN32Premul(imageBitmap.dimensions()))); |
| 2120 if (!surface) { | 2116 SkASSERT(surface); |
| 2121 return image; | |
| 2122 } | |
| 2123 SkCanvas* canvas = surface->getCanvas(); | 2117 SkCanvas* canvas = surface->getCanvas(); |
| 2124 canvas->clear(SK_ColorTRANSPARENT); | 2118 canvas->clear(SK_ColorTRANSPARENT); |
| 2125 SkPaint paint; | 2119 SkPaint paint; |
| 2126 paint.setColorFilter(sk_ref_sp(colorFilter)); | 2120 paint.setColorFilter(sk_ref_sp(colorFilter)); |
| 2127 canvas->drawImage(image, 0, 0, &paint); | 2121 imageBitmap.draw(canvas, &paint); |
| 2128 canvas->flush(); | 2122 canvas->flush(); |
| 2129 return surface->makeImageSnapshot().release(); | 2123 return surface->makeImageSnapshot(); |
| 2130 } | 2124 } |
| 2131 | 2125 |
| 2132 //////////////////////////////////////////////////////////////////////////////// | 2126 //////////////////////////////////////////////////////////////////////////////// |
| 2133 void SkPDFDevice::internalDrawImage(const SkMatrix& origMatrix, | 2127 void SkPDFDevice::internalDrawImage(const SkMatrix& origMatrix, |
| 2134 const SkClipStack* clipStack, | 2128 const SkClipStack* clipStack, |
| 2135 const SkRegion& origClipRegion, | 2129 const SkRegion& origClipRegion, |
| 2136 const SkImage* image, | 2130 SkImageBitmap imageBitmap, |
| 2137 const SkIRect* srcRect, | |
| 2138 const SkPaint& paint) { | 2131 const SkPaint& paint) { |
| 2139 SkASSERT(image); | 2132 if (imageBitmap.dimensions().isZero()) { |
| 2133 return; |
| 2134 } |
| 2140 #ifdef SK_PDF_IMAGE_STATS | 2135 #ifdef SK_PDF_IMAGE_STATS |
| 2141 gDrawImageCalls.fetch_add(1); | 2136 gDrawImageCalls.fetch_add(1); |
| 2142 #endif | 2137 #endif |
| 2143 SkMatrix matrix = origMatrix; | 2138 SkMatrix matrix = origMatrix; |
| 2144 SkRegion perspectiveBounds; | 2139 SkRegion perspectiveBounds; |
| 2145 const SkRegion* clipRegion = &origClipRegion; | 2140 const SkRegion* clipRegion = &origClipRegion; |
| 2146 sk_sp<const SkImage> autoImageUnref; | 2141 sk_sp<SkImage> autoImageUnref; |
| 2147 | 2142 |
| 2148 if (srcRect) { | |
| 2149 autoImageUnref = image->makeSubset(*srcRect); | |
| 2150 if (!autoImageUnref) { | |
| 2151 return; | |
| 2152 } | |
| 2153 image = autoImageUnref.get(); | |
| 2154 } | |
| 2155 // Rasterize the bitmap using perspective in a new bitmap. | 2143 // Rasterize the bitmap using perspective in a new bitmap. |
| 2156 if (origMatrix.hasPerspective()) { | 2144 if (origMatrix.hasPerspective()) { |
| 2157 if (fRasterDpi == 0) { | 2145 if (fRasterDpi == 0) { |
| 2158 return; | 2146 return; |
| 2159 } | 2147 } |
| 2160 // Transform the bitmap in the new space, without taking into | 2148 // Transform the bitmap in the new space, without taking into |
| 2161 // account the initial transform. | 2149 // account the initial transform. |
| 2162 SkPath perspectiveOutline; | 2150 SkPath perspectiveOutline; |
| 2163 SkRect imageBounds = SkRect::Make(image->bounds()); | 2151 SkRect imageBounds = SkRect::Make(imageBitmap.bounds()); |
| 2164 perspectiveOutline.addRect(imageBounds); | 2152 perspectiveOutline.addRect(imageBounds); |
| 2165 perspectiveOutline.transform(origMatrix); | 2153 perspectiveOutline.transform(origMatrix); |
| 2166 | 2154 |
| 2167 // TODO(edisonn): perf - use current clip too. | 2155 // TODO(edisonn): perf - use current clip too. |
| 2168 // Retrieve the bounds of the new shape. | 2156 // Retrieve the bounds of the new shape. |
| 2169 SkRect bounds = perspectiveOutline.getBounds(); | 2157 SkRect bounds = perspectiveOutline.getBounds(); |
| 2170 | 2158 |
| 2171 // Transform the bitmap in the new space, taking into | 2159 // Transform the bitmap in the new space, taking into |
| 2172 // account the initial transform. | 2160 // account the initial transform. |
| 2173 SkMatrix total = origMatrix; | 2161 SkMatrix total = origMatrix; |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2205 SkScalar deltaX = bounds.left(); | 2193 SkScalar deltaX = bounds.left(); |
| 2206 SkScalar deltaY = bounds.top(); | 2194 SkScalar deltaY = bounds.top(); |
| 2207 | 2195 |
| 2208 SkMatrix offsetMatrix = origMatrix; | 2196 SkMatrix offsetMatrix = origMatrix; |
| 2209 offsetMatrix.postTranslate(-deltaX, -deltaY); | 2197 offsetMatrix.postTranslate(-deltaX, -deltaY); |
| 2210 offsetMatrix.postScale(scaleX, scaleY); | 2198 offsetMatrix.postScale(scaleX, scaleY); |
| 2211 | 2199 |
| 2212 // Translate the draw in the new canvas, so we perfectly fit the | 2200 // Translate the draw in the new canvas, so we perfectly fit the |
| 2213 // shape in the bitmap. | 2201 // shape in the bitmap. |
| 2214 canvas->setMatrix(offsetMatrix); | 2202 canvas->setMatrix(offsetMatrix); |
| 2215 canvas->drawImage(image, 0, 0, nullptr); | 2203 imageBitmap.draw(canvas, nullptr); |
| 2216 // Make sure the final bits are in the bitmap. | 2204 // Make sure the final bits are in the bitmap. |
| 2217 canvas->flush(); | 2205 canvas->flush(); |
| 2218 | 2206 |
| 2219 // In the new space, we use the identity matrix translated | 2207 // In the new space, we use the identity matrix translated |
| 2220 // and scaled to reflect DPI. | 2208 // and scaled to reflect DPI. |
| 2221 matrix.setScale(1 / scaleX, 1 / scaleY); | 2209 matrix.setScale(1 / scaleX, 1 / scaleY); |
| 2222 matrix.postTranslate(deltaX, deltaY); | 2210 matrix.postTranslate(deltaX, deltaY); |
| 2223 | 2211 |
| 2224 perspectiveBounds.setRect(bounds.roundOut()); | 2212 perspectiveBounds.setRect(bounds.roundOut()); |
| 2225 clipRegion = &perspectiveBounds; | 2213 clipRegion = &perspectiveBounds; |
| 2226 srcRect = nullptr; | |
| 2227 | 2214 |
| 2228 autoImageUnref.reset(surface->makeImageSnapshot().release()); | 2215 autoImageUnref = surface->makeImageSnapshot(); |
| 2229 image = autoImageUnref.get(); | 2216 imageBitmap = SkImageBitmap(autoImageUnref.get()); |
| 2230 } | 2217 } |
| 2231 | 2218 |
| 2232 SkMatrix scaled; | 2219 SkMatrix scaled; |
| 2233 // Adjust for origin flip. | 2220 // Adjust for origin flip. |
| 2234 scaled.setScale(SK_Scalar1, -SK_Scalar1); | 2221 scaled.setScale(SK_Scalar1, -SK_Scalar1); |
| 2235 scaled.postTranslate(0, SK_Scalar1); | 2222 scaled.postTranslate(0, SK_Scalar1); |
| 2236 // Scale the image up from 1x1 to WxH. | 2223 // Scale the image up from 1x1 to WxH. |
| 2237 SkIRect subset = image->bounds(); | 2224 SkIRect subset = imageBitmap.bounds(); |
| 2238 scaled.postScale(SkIntToScalar(image->width()), | 2225 scaled.postScale(SkIntToScalar(imageBitmap.dimensions().width()), |
| 2239 SkIntToScalar(image->height())); | 2226 SkIntToScalar(imageBitmap.dimensions().height())); |
| 2240 scaled.postConcat(matrix); | 2227 scaled.postConcat(matrix); |
| 2241 ScopedContentEntry content(this, clipStack, *clipRegion, scaled, paint); | 2228 ScopedContentEntry content(this, clipStack, *clipRegion, scaled, paint); |
| 2242 if (!content.entry() || (srcRect && !subset.intersect(*srcRect))) { | 2229 if (!content.entry()) { |
| 2243 return; | 2230 return; |
| 2244 } | 2231 } |
| 2245 if (content.needShape()) { | 2232 if (content.needShape()) { |
| 2246 SkPath shape; | 2233 SkPath shape; |
| 2247 shape.addRect(SkRect::Make(subset)); | 2234 shape.addRect(SkRect::Make(subset)); |
| 2248 shape.transform(matrix); | 2235 shape.transform(matrix); |
| 2249 content.setShape(shape); | 2236 content.setShape(shape); |
| 2250 } | 2237 } |
| 2251 if (!content.needSource()) { | 2238 if (!content.needSource()) { |
| 2252 return; | 2239 return; |
| 2253 } | 2240 } |
| 2254 | 2241 |
| 2255 if (SkColorFilter* colorFilter = paint.getColorFilter()) { | 2242 if (SkColorFilter* colorFilter = paint.getColorFilter()) { |
| 2256 // TODO(https://bug.skia.org/4378): implement colorfilter on other | 2243 // TODO(https://bug.skia.org/4378): implement colorfilter on other |
| 2257 // draw calls. This code here works for all | 2244 // draw calls. This code here works for all |
| 2258 // drawBitmap*()/drawImage*() calls amd ImageFilters (which | 2245 // drawBitmap*()/drawImage*() calls amd ImageFilters (which |
| 2259 // rasterize a layer on this backend). Fortuanely, this seems | 2246 // rasterize a layer on this backend). Fortuanely, this seems |
| 2260 // to be how Chromium impements most color-filters. | 2247 // to be how Chromium impements most color-filters. |
| 2261 autoImageUnref.reset(color_filter(image, colorFilter)); | 2248 autoImageUnref = color_filter(imageBitmap, colorFilter); |
| 2262 image = autoImageUnref.get(); | 2249 imageBitmap = SkImageBitmap(autoImageUnref.get()); |
| 2263 // TODO(halcanary): de-dupe this by caching filtered images. | 2250 // TODO(halcanary): de-dupe this by caching filtered images. |
| 2264 // (maybe in the resource cache?) | 2251 // (maybe in the resource cache?) |
| 2265 } | 2252 } |
| 2266 sk_sp<SkPDFObject> pdfimage(SkSafeRef(fDocument->canon()->findPDFBitmap(imag
e))); | 2253 |
| 2254 SkBitmapKey key = imageBitmap.getKey(); |
| 2255 sk_sp<SkPDFObject> pdfimage = fDocument->canon()->findPDFBitmap(key); |
| 2267 if (!pdfimage) { | 2256 if (!pdfimage) { |
| 2268 pdfimage.reset(SkPDFCreateBitmapObject( | 2257 auto img = imageBitmap.makeImage(); |
| 2269 image, fDocument->canon()->getPixelSerializer()))
; | 2258 if (!img) { |
| 2259 return; |
| 2260 } |
| 2261 pdfimage = SkPDFCreateBitmapObject( |
| 2262 std::move(img), fDocument->canon()->getPixelSerializer()); |
| 2270 if (!pdfimage) { | 2263 if (!pdfimage) { |
| 2271 return; | 2264 return; |
| 2272 } | 2265 } |
| 2273 #if SK_PDF_SERIALIZE_IMAGES_EARLY // TODO(halcanary): enable. | 2266 fDocument->serialize(pdfimage); // serialize images early. |
| 2274 sk_sp<SkData> encodedImage(image->refEncodedData()); | 2267 fDocument->canon()->addPDFBitmap(key, pdfimage); |
| 2275 if (!encodedImage) { | |
| 2276 fDocument->serialize(pdfimage); | |
| 2277 } | |
| 2278 #endif | |
| 2279 fDocument->canon()->addPDFBitmap(image->uniqueID(), pdfimage.get()); | |
| 2280 } | 2268 } |
| 2269 // TODO(halcanary): addXObjectResource() should take a sk_sp<SkPDFObject> |
| 2281 SkPDFUtils::DrawFormXObject(this->addXObjectResource(pdfimage.get()), | 2270 SkPDFUtils::DrawFormXObject(this->addXObjectResource(pdfimage.get()), |
| 2282 &content.entry()->fContent); | 2271 &content.entry()->fContent); |
| 2283 } | 2272 } |
| OLD | NEW |