Chromium Code Reviews| Index: src/pdf/SkPDFDevice.cpp |
| diff --git a/src/pdf/SkPDFDevice.cpp b/src/pdf/SkPDFDevice.cpp |
| index 77aa7a353ce74ff5b0562238842751f94f2a22ce..6fe2398b27b06c7312ebd19ab0df9be451ee974b 100644 |
| --- a/src/pdf/SkPDFDevice.cpp |
| +++ b/src/pdf/SkPDFDevice.cpp |
| @@ -49,6 +49,8 @@ struct TypefaceFallbackData { |
| }; |
| #endif |
| +#define DPI_FOR_RASTER_SCALE_ONE 72 |
| + |
| // Utility functions |
| static void emit_pdf_color(SkColor color, SkWStream* result) { |
| @@ -2163,6 +2165,9 @@ void SkPDFDevice::internalDrawBitmap(const SkMatrix& origMatrix, |
| // Rasterize the bitmap using perspective in a new bitmap. |
| if (origMatrix.hasPerspective()) { |
| + if (fRasterDpi == 0) { |
| + return; |
| + } |
| SkBitmap* subsetBitmap; |
| if (srcRect) { |
| if (!origBitmap.extractSubset(&tmpSubsetBitmap, *srcRect)) { |
| @@ -2175,7 +2180,8 @@ void SkPDFDevice::internalDrawBitmap(const SkMatrix& origMatrix, |
| } |
| srcRect = NULL; |
| - // Transform the bitmap in the new space. |
| + // Transform the bitmap in the new space, without taking into |
| + // account the initial transform. |
| SkPath perspectiveOutline; |
| perspectiveOutline.addRect( |
| SkRect::MakeWH(SkIntToScalar(subsetBitmap->width()), |
| @@ -2186,8 +2192,26 @@ void SkPDFDevice::internalDrawBitmap(const SkMatrix& origMatrix, |
| // Retrieve the bounds of the new shape. |
| SkRect bounds = perspectiveOutline.getBounds(); |
| - // TODO(edisonn): add DPI settings. Currently 1 pixel/point, which does |
| - // not look great, but it is not producing large PDFs. |
| + // Transform the bitmap in the new space, taking into |
| + // account the initial transform. |
| + SkMatrix total = origMatrix; |
| + 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.
|
| + SkMatrix scaleDpi; |
| + scaleDpi.setScale(SkIntToScalar(fRasterDpi) / |
| + SkIntToScalar(DPI_FOR_RASTER_SCALE_ONE), |
| + SkIntToScalar(fRasterDpi) / |
| + SkIntToScalar(DPI_FOR_RASTER_SCALE_ONE)); |
| + 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.
|
| + SkPath physicalPerspectiveOutline; |
| + physicalPerspectiveOutline.addRect( |
| + SkRect::MakeWH(SkIntToScalar(subsetBitmap->width()), |
| + SkIntToScalar(subsetBitmap->height()))); |
| + physicalPerspectiveOutline.transform(total); |
| + |
| + SkScalar scaleX = physicalPerspectiveOutline.getBounds().width() / |
| + bounds.width(); |
| + SkScalar scaleY = physicalPerspectiveOutline.getBounds().height() / |
| + bounds.height(); |
| // TODO(edisonn): A better approach would be to use a bitmap shader |
| // (in clamp mode) and draw a rect over the entire bounding box. Then |
| @@ -2196,9 +2220,10 @@ void SkPDFDevice::internalDrawBitmap(const SkMatrix& origMatrix, |
| // the image. Avoiding alpha will reduce the pdf size and generation |
| // CPU time some. |
| - perspectiveBitmap.setConfig(SkBitmap::kARGB_8888_Config, |
| - SkScalarCeilToInt(bounds.width()), |
| - SkScalarCeilToInt(bounds.height())); |
| + perspectiveBitmap.setConfig( |
| + SkBitmap::kARGB_8888_Config, |
| + 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.
|
| + SkScalarCeilToInt(scaleY * bounds.height())); |
| perspectiveBitmap.allocPixels(); |
| perspectiveBitmap.eraseColor(SK_ColorTRANSPARENT); |
| @@ -2210,6 +2235,7 @@ void SkPDFDevice::internalDrawBitmap(const SkMatrix& origMatrix, |
| SkMatrix offsetMatrix = origMatrix; |
| offsetMatrix.postTranslate(-deltaX, -deltaY); |
| + offsetMatrix.postScale(scaleX, scaleY); |
| // Translate the draw in the new canvas, so we perfectly fit the |
| // shape in the bitmap. |
| @@ -2220,8 +2246,11 @@ void SkPDFDevice::internalDrawBitmap(const SkMatrix& origMatrix, |
| // Make sure the final bits are in the bitmap. |
| canvas.flush(); |
| - // In the new space, we use the identity matrix translated. |
| - matrix.setTranslate(deltaX, deltaY); |
| + // In the new space, we use the identity matrix translated |
| + // and scaled to reflect DPI. |
| + matrix.setScale(1 / scaleX, 1 / scaleY); |
| + 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
|
| + |
| perspectiveBounds.setRect( |
| SkIRect::MakeXYWH(SkScalarFloorToInt(bounds.x()), |
| SkScalarFloorToInt(bounds.y()), |