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

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: remove sqrt 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
« no previous file with comments | « 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 1971 matching lines...) Expand 10 before | Expand all | Expand 10 after
2033 const SkPaint& paint) { 2035 const SkPaint& paint) {
2034 SkMatrix matrix = origMatrix; 2036 SkMatrix matrix = origMatrix;
2035 SkRegion perspectiveBounds; 2037 SkRegion perspectiveBounds;
2036 const SkRegion* clipRegion = &origClipRegion; 2038 const SkRegion* clipRegion = &origClipRegion;
2037 SkBitmap perspectiveBitmap; 2039 SkBitmap perspectiveBitmap;
2038 const SkBitmap* bitmap = &origBitmap; 2040 const SkBitmap* bitmap = &origBitmap;
2039 SkBitmap tmpSubsetBitmap; 2041 SkBitmap tmpSubsetBitmap;
2040 2042
2041 // Rasterize the bitmap using perspective in a new bitmap. 2043 // Rasterize the bitmap using perspective in a new bitmap.
2042 if (origMatrix.hasPerspective()) { 2044 if (origMatrix.hasPerspective()) {
2045 if (fRasterDpi == 0) {
2046 return;
2047 }
2043 SkBitmap* subsetBitmap; 2048 SkBitmap* subsetBitmap;
2044 if (srcRect) { 2049 if (srcRect) {
2045 if (!origBitmap.extractSubset(&tmpSubsetBitmap, *srcRect)) { 2050 if (!origBitmap.extractSubset(&tmpSubsetBitmap, *srcRect)) {
2046 return; 2051 return;
2047 } 2052 }
2048 subsetBitmap = &tmpSubsetBitmap; 2053 subsetBitmap = &tmpSubsetBitmap;
2049 } else { 2054 } else {
2050 subsetBitmap = &tmpSubsetBitmap; 2055 subsetBitmap = &tmpSubsetBitmap;
2051 *subsetBitmap = origBitmap; 2056 *subsetBitmap = origBitmap;
2052 } 2057 }
2053 srcRect = NULL; 2058 srcRect = NULL;
2054 2059
2055 // Transform the bitmap in the new space. 2060 // Transform the bitmap in the new space.
2056 SkPath perspectiveOutline; 2061 SkPath perspectiveOutline;
2057 perspectiveOutline.addRect( 2062 perspectiveOutline.addRect(
2058 SkRect::MakeWH(SkIntToScalar(subsetBitmap->width()), 2063 SkRect::MakeWH(SkIntToScalar(subsetBitmap->width()),
2059 SkIntToScalar(subsetBitmap->height()))); 2064 SkIntToScalar(subsetBitmap->height())));
2060 perspectiveOutline.transform(origMatrix); 2065 perspectiveOutline.transform(origMatrix);
2061 2066
2062 // TODO(edisonn): perf - use current clip too. 2067 // TODO(edisonn): perf - use current clip too.
2063 // Retrieve the bounds of the new shape. 2068 // Retrieve the bounds of the new shape.
2064 SkRect bounds = perspectiveOutline.getBounds(); 2069 SkRect bounds = perspectiveOutline.getBounds();
2070 float scaleX = fRasterDpi / (float)DPI_FOR_RASTER_SCALE_ONE;
vandebo (ex-Chrome) 2013/10/31 23:20:36 This should probably use SkScalar instead of float
edisonn 2013/11/01 15:00:08 Done.
2071 float scaleY = scaleX;
2065 2072
2066 // TODO(edisonn): add DPI settings. Currently 1 pixel/point, which does 2073 scaleX *= SkScalarToFloat(fInitialTransform.getScaleX());
2067 // not look great, but it is not producing large PDFs. 2074 scaleY *= SkScalarToFloat(fInitialTransform.getScaleY());
2075
2076 scaleX = fabs(scaleX);
vandebo (ex-Chrome) 2013/10/31 23:20:36 SkScalarAbs
edisonn 2013/11/01 15:00:08 Done.
2077 scaleY = fabs(scaleY);
vandebo (ex-Chrome) 2013/10/31 23:20:36 Actually, I don't think you want to do this. When
edisonn 2013/11/01 15:00:08 Yes, but getScaleX()/Y() can can return anything,
vandebo (ex-Chrome) 2013/11/01 22:13:42 True, you do need to use Abs for the bitmap.setCon
edisonn 2013/11/04 18:04:58 Incorrect, the initial transform is not affected b
2068 2078
2069 // TODO(edisonn): A better approach would be to use a bitmap shader 2079 // TODO(edisonn): A better approach would be to use a bitmap shader
2070 // (in clamp mode) and draw a rect over the entire bounding box. Then 2080 // (in clamp mode) and draw a rect over the entire bounding box. Then
2071 // intersect perspectiveOutline to the clip. That will avoid introducing 2081 // intersect perspectiveOutline to the clip. That will avoid introducing
2072 // alpha to the image while still giving good behavior at the edge of 2082 // alpha to the image while still giving good behavior at the edge of
2073 // the image. Avoiding alpha will reduce the pdf size and generation 2083 // the image. Avoiding alpha will reduce the pdf size and generation
2074 // CPU time some. 2084 // CPU time some.
2075 2085
2076 perspectiveBitmap.setConfig(SkBitmap::kARGB_8888_Config, 2086 perspectiveBitmap.setConfig(
2077 SkScalarCeilToInt(bounds.width()), 2087 SkBitmap::kARGB_8888_Config,
2078 SkScalarCeilToInt(bounds.height())); 2088 SkScalarCeilToInt(scaleX * bounds.width()),
2089 SkScalarCeilToInt(scaleY * bounds.height()));
2079 perspectiveBitmap.allocPixels(); 2090 perspectiveBitmap.allocPixels();
2080 perspectiveBitmap.eraseColor(SK_ColorTRANSPARENT); 2091 perspectiveBitmap.eraseColor(SK_ColorTRANSPARENT);
2081 2092
2082 SkBitmapDevice device(perspectiveBitmap); 2093 SkBitmapDevice device(perspectiveBitmap);
2083 SkCanvas canvas(&device); 2094 SkCanvas canvas(&device);
2084 2095
2085 SkScalar deltaX = bounds.left(); 2096 SkScalar deltaX = bounds.left();
2086 SkScalar deltaY = bounds.top(); 2097 SkScalar deltaY = bounds.top();
2087 2098
2088 SkMatrix offsetMatrix = origMatrix; 2099 SkMatrix offsetMatrix = origMatrix;
2089 offsetMatrix.postTranslate(-deltaX, -deltaY); 2100 offsetMatrix.postTranslate(-deltaX, -deltaY);
2101 offsetMatrix.postScale(scaleX, scaleY);
2090 2102
2091 // Translate the draw in the new canvas, so we perfectly fit the 2103 // Translate the draw in the new canvas, so we perfectly fit the
2092 // shape in the bitmap. 2104 // shape in the bitmap.
2093 canvas.setMatrix(offsetMatrix); 2105 canvas.setMatrix(offsetMatrix);
2094 2106
2095 canvas.drawBitmap(*subsetBitmap, SkIntToScalar(0), SkIntToScalar(0)); 2107 canvas.drawBitmap(*subsetBitmap, SkIntToScalar(0), SkIntToScalar(0));
2096 2108
2097 // Make sure the final bits are in the bitmap. 2109 // Make sure the final bits are in the bitmap.
2098 canvas.flush(); 2110 canvas.flush();
2099 2111
2100 // In the new space, we use the identity matrix translated. 2112 // In the new space, we use the identity matrix translated
2101 matrix.setTranslate(deltaX, deltaY); 2113 // and scaled to reflect DPI.
2114 matrix.setScale(1 / scaleX, 1 / scaleY);
2115 matrix.postTranslate(deltaX, deltaY);
2102 perspectiveBounds.setRect( 2116 perspectiveBounds.setRect(
2103 SkIRect::MakeXYWH(SkScalarFloorToInt(bounds.x()), 2117 SkIRect::MakeXYWH(SkScalarFloorToInt(bounds.x()),
2104 SkScalarFloorToInt(bounds.y()), 2118 SkScalarFloorToInt(bounds.y()),
2105 SkScalarCeilToInt(bounds.width()), 2119 SkScalarCeilToInt(bounds.width()),
2106 SkScalarCeilToInt(bounds.height()))); 2120 SkScalarCeilToInt(bounds.height())));
2107 clipRegion = &perspectiveBounds; 2121 clipRegion = &perspectiveBounds;
2108 srcRect = NULL; 2122 srcRect = NULL;
2109 bitmap = &perspectiveBitmap; 2123 bitmap = &perspectiveBitmap;
2110 } 2124 }
2111 2125
(...skipping 26 matching lines...) Expand all
2138 } 2152 }
2139 2153
2140 bool SkPDFDevice::onReadPixels(const SkBitmap& bitmap, int x, int y, 2154 bool SkPDFDevice::onReadPixels(const SkBitmap& bitmap, int x, int y,
2141 SkCanvas::Config8888) { 2155 SkCanvas::Config8888) {
2142 return false; 2156 return false;
2143 } 2157 }
2144 2158
2145 bool SkPDFDevice::allowImageFilter(SkImageFilter*) { 2159 bool SkPDFDevice::allowImageFilter(SkImageFilter*) {
2146 return false; 2160 return false;
2147 } 2161 }
OLDNEW
« no previous file with comments | « include/pdf/SkPDFDevice.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698