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

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

Issue 54913004: Implement DPI for perspective bitmaps in PDF - we save the bitmap at the resolution requested. (Closed) Base URL: https://skia.googlecode.com/svn/trunk
Patch Set: take 2, matrix handling Created 7 years, 1 month 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 | Annotate | Revision Log
« gm/gmmain.cpp ('K') | « include/pdf/SkPDFDevice.h ('k') | no next file » | 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 "SkAnnotation.h" 10 #include "SkAnnotation.h"
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
42 int upperBounds; 42 int upperBounds;
43 43
44 bool operator==(const TypefaceFallbackData& b) const { 44 bool operator==(const TypefaceFallbackData& b) const {
45 return typeface == b.typeface && 45 return typeface == b.typeface &&
46 lowerBounds == b.lowerBounds && 46 lowerBounds == b.lowerBounds &&
47 upperBounds == b.upperBounds; 47 upperBounds == b.upperBounds;
48 } 48 }
49 }; 49 };
50 #endif 50 #endif
51 51
52 #define DPI_FOR_RASTER_SCALE_ONE 72
53
52 // Utility functions 54 // Utility functions
53 55
54 static void emit_pdf_color(SkColor color, SkWStream* result) { 56 static void emit_pdf_color(SkColor color, SkWStream* result) {
55 SkASSERT(SkColorGetA(color) == 0xFF); // We handle alpha elsewhere. 57 SkASSERT(SkColorGetA(color) == 0xFF); // We handle alpha elsewhere.
56 SkScalar colorMax = SkIntToScalar(0xFF); 58 SkScalar colorMax = SkIntToScalar(0xFF);
57 SkPDFScalar::Append( 59 SkPDFScalar::Append(
58 SkScalarDiv(SkIntToScalar(SkColorGetR(color)), colorMax), result); 60 SkScalarDiv(SkIntToScalar(SkColorGetR(color)), colorMax), result);
59 result->writeText(" "); 61 result->writeText(" ");
60 SkPDFScalar::Append( 62 SkPDFScalar::Append(
61 SkScalarDiv(SkIntToScalar(SkColorGetG(color)), colorMax), result); 63 SkScalarDiv(SkIntToScalar(SkColorGetG(color)), colorMax), result);
(...skipping 2094 matching lines...) Expand 10 before | Expand all | Expand 10 after
2156 const SkPaint& paint) { 2158 const SkPaint& paint) {
2157 SkMatrix matrix = origMatrix; 2159 SkMatrix matrix = origMatrix;
2158 SkRegion perspectiveBounds; 2160 SkRegion perspectiveBounds;
2159 const SkRegion* clipRegion = &origClipRegion; 2161 const SkRegion* clipRegion = &origClipRegion;
2160 SkBitmap perspectiveBitmap; 2162 SkBitmap perspectiveBitmap;
2161 const SkBitmap* bitmap = &origBitmap; 2163 const SkBitmap* bitmap = &origBitmap;
2162 SkBitmap tmpSubsetBitmap; 2164 SkBitmap tmpSubsetBitmap;
2163 2165
2164 // Rasterize the bitmap using perspective in a new bitmap. 2166 // Rasterize the bitmap using perspective in a new bitmap.
2165 if (origMatrix.hasPerspective()) { 2167 if (origMatrix.hasPerspective()) {
2168 if (fRasterDpi == 0) {
2169 return;
2170 }
2166 SkBitmap* subsetBitmap; 2171 SkBitmap* subsetBitmap;
2167 if (srcRect) { 2172 if (srcRect) {
2168 if (!origBitmap.extractSubset(&tmpSubsetBitmap, *srcRect)) { 2173 if (!origBitmap.extractSubset(&tmpSubsetBitmap, *srcRect)) {
2169 return; 2174 return;
2170 } 2175 }
2171 subsetBitmap = &tmpSubsetBitmap; 2176 subsetBitmap = &tmpSubsetBitmap;
2172 } else { 2177 } else {
2173 subsetBitmap = &tmpSubsetBitmap; 2178 subsetBitmap = &tmpSubsetBitmap;
2174 *subsetBitmap = origBitmap; 2179 *subsetBitmap = origBitmap;
2175 } 2180 }
2176 srcRect = NULL; 2181 srcRect = NULL;
2177 2182
2178 // Transform the bitmap in the new space. 2183 // Transform the bitmap in the new space, without taking into
2184 // account the initial transform.
2179 SkPath perspectiveOutline; 2185 SkPath perspectiveOutline;
2180 perspectiveOutline.addRect( 2186 perspectiveOutline.addRect(
2181 SkRect::MakeWH(SkIntToScalar(subsetBitmap->width()), 2187 SkRect::MakeWH(SkIntToScalar(subsetBitmap->width()),
2182 SkIntToScalar(subsetBitmap->height()))); 2188 SkIntToScalar(subsetBitmap->height())));
2183 perspectiveOutline.transform(origMatrix); 2189 perspectiveOutline.transform(origMatrix);
2184 2190
2185 // TODO(edisonn): perf - use current clip too. 2191 // TODO(edisonn): perf - use current clip too.
2186 // Retrieve the bounds of the new shape. 2192 // Retrieve the bounds of the new shape.
2187 SkRect bounds = perspectiveOutline.getBounds(); 2193 SkRect bounds = perspectiveOutline.getBounds();
2188 2194
2189 // TODO(edisonn): add DPI settings. Currently 1 pixel/point, which does 2195 // Transform the bitmap in the new space, taking into
2190 // not look great, but it is not producing large PDFs. 2196 // account the initial transform.
2197 SkMatrix total = origMatrix;
2198 total.postConcat(fInitialTransform);
vandebo (ex-Chrome) 2013/11/07 22:44:00 Should this be preConcat? fInitialTransform is ap
edisonn 2013/11/11 17:26:56 I don't think so, gms fail and they don't output a
vandebo (ex-Chrome) 2013/11/11 17:52:19 Oops, I got Pre/Post mixed up in what they do.
2199 SkMatrix scaleDpi;
2200 scaleDpi.setScale(SkIntToScalar(fRasterDpi) /
2201 SkIntToScalar(DPI_FOR_RASTER_SCALE_ONE),
2202 SkIntToScalar(fRasterDpi) /
2203 SkIntToScalar(DPI_FOR_RASTER_SCALE_ONE));
2204 total.postConcat(scaleDpi);
vandebo (ex-Chrome) 2013/11/07 22:44:00 nit: scaleDPI isn't needed, just do postScale here
edisonn 2013/11/11 17:26:56 Done.
2205 SkPath physicalPerspectiveOutline;
2206 physicalPerspectiveOutline.addRect(
2207 SkRect::MakeWH(SkIntToScalar(subsetBitmap->width()),
2208 SkIntToScalar(subsetBitmap->height())));
2209 physicalPerspectiveOutline.transform(total);
2210
2211 SkScalar scaleX = physicalPerspectiveOutline.getBounds().width() /
2212 bounds.width();
2213 SkScalar scaleY = physicalPerspectiveOutline.getBounds().height() /
2214 bounds.height();
2191 2215
2192 // TODO(edisonn): A better approach would be to use a bitmap shader 2216 // TODO(edisonn): A better approach would be to use a bitmap shader
2193 // (in clamp mode) and draw a rect over the entire bounding box. Then 2217 // (in clamp mode) and draw a rect over the entire bounding box. Then
2194 // intersect perspectiveOutline to the clip. That will avoid introducing 2218 // intersect perspectiveOutline to the clip. That will avoid introducing
2195 // alpha to the image while still giving good behavior at the edge of 2219 // alpha to the image while still giving good behavior at the edge of
2196 // the image. Avoiding alpha will reduce the pdf size and generation 2220 // the image. Avoiding alpha will reduce the pdf size and generation
2197 // CPU time some. 2221 // CPU time some.
2198 2222
2199 perspectiveBitmap.setConfig(SkBitmap::kARGB_8888_Config, 2223 perspectiveBitmap.setConfig(
2200 SkScalarCeilToInt(bounds.width()), 2224 SkBitmap::kARGB_8888_Config,
2201 SkScalarCeilToInt(bounds.height())); 2225 SkScalarCeilToInt(scaleX * bounds.width()),
vandebo (ex-Chrome) 2013/11/07 22:44:00 Just use physicalPerspectiveOutline.getBounds().w
edisonn 2013/11/11 17:26:56 Done.
2226 SkScalarCeilToInt(scaleY * bounds.height()));
2202 perspectiveBitmap.allocPixels(); 2227 perspectiveBitmap.allocPixels();
2203 perspectiveBitmap.eraseColor(SK_ColorTRANSPARENT); 2228 perspectiveBitmap.eraseColor(SK_ColorTRANSPARENT);
2204 2229
2205 SkBitmapDevice device(perspectiveBitmap); 2230 SkBitmapDevice device(perspectiveBitmap);
2206 SkCanvas canvas(&device); 2231 SkCanvas canvas(&device);
2207 2232
2208 SkScalar deltaX = bounds.left(); 2233 SkScalar deltaX = bounds.left();
2209 SkScalar deltaY = bounds.top(); 2234 SkScalar deltaY = bounds.top();
2210 2235
2211 SkMatrix offsetMatrix = origMatrix; 2236 SkMatrix offsetMatrix = origMatrix;
2212 offsetMatrix.postTranslate(-deltaX, -deltaY); 2237 offsetMatrix.postTranslate(-deltaX, -deltaY);
2238 offsetMatrix.postScale(scaleX, scaleY);
2213 2239
2214 // Translate the draw in the new canvas, so we perfectly fit the 2240 // Translate the draw in the new canvas, so we perfectly fit the
2215 // shape in the bitmap. 2241 // shape in the bitmap.
2216 canvas.setMatrix(offsetMatrix); 2242 canvas.setMatrix(offsetMatrix);
2217 2243
2218 canvas.drawBitmap(*subsetBitmap, SkIntToScalar(0), SkIntToScalar(0)); 2244 canvas.drawBitmap(*subsetBitmap, SkIntToScalar(0), SkIntToScalar(0));
2219 2245
2220 // Make sure the final bits are in the bitmap. 2246 // Make sure the final bits are in the bitmap.
2221 canvas.flush(); 2247 canvas.flush();
2222 2248
2223 // In the new space, we use the identity matrix translated. 2249 // In the new space, we use the identity matrix translated
2224 matrix.setTranslate(deltaX, deltaY); 2250 // and scaled to reflect DPI.
2251 matrix.setScale(1 / scaleX, 1 / scaleY);
2252 matrix.postTranslate(deltaX, deltaY);
vandebo (ex-Chrome) 2013/11/07 22:44:00 Not sure, should this be preTranslate ?
edisonn 2013/11/11 17:26:56 gms fail badly if I use preTranslate
2253
2225 perspectiveBounds.setRect( 2254 perspectiveBounds.setRect(
2226 SkIRect::MakeXYWH(SkScalarFloorToInt(bounds.x()), 2255 SkIRect::MakeXYWH(SkScalarFloorToInt(bounds.x()),
2227 SkScalarFloorToInt(bounds.y()), 2256 SkScalarFloorToInt(bounds.y()),
2228 SkScalarCeilToInt(bounds.width()), 2257 SkScalarCeilToInt(bounds.width()),
2229 SkScalarCeilToInt(bounds.height()))); 2258 SkScalarCeilToInt(bounds.height())));
2230 clipRegion = &perspectiveBounds; 2259 clipRegion = &perspectiveBounds;
2231 srcRect = NULL; 2260 srcRect = NULL;
2232 bitmap = &perspectiveBitmap; 2261 bitmap = &perspectiveBitmap;
2233 } 2262 }
2234 2263
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
2267 } 2296 }
2268 2297
2269 bool SkPDFDevice::onReadPixels(const SkBitmap& bitmap, int x, int y, 2298 bool SkPDFDevice::onReadPixels(const SkBitmap& bitmap, int x, int y,
2270 SkCanvas::Config8888) { 2299 SkCanvas::Config8888) {
2271 return false; 2300 return false;
2272 } 2301 }
2273 2302
2274 bool SkPDFDevice::allowImageFilter(SkImageFilter*) { 2303 bool SkPDFDevice::allowImageFilter(SkImageFilter*) {
2275 return false; 2304 return false;
2276 } 2305 }
OLDNEW
« gm/gmmain.cpp ('K') | « include/pdf/SkPDFDevice.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698