Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(262)

Side by Side Diff: src/pdf/SkPDFDevice.cpp

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

Powered by Google App Engine
This is Rietveld 408576698