Index: src/pdf/SkPDFDevice.cpp |
diff --git a/src/pdf/SkPDFDevice.cpp b/src/pdf/SkPDFDevice.cpp |
index 43117a2b2fc4d5760d692cb50970070721d71b0c..bccb007bec079a9c0d8fd188bb699a31f56b146c 100644 |
--- a/src/pdf/SkPDFDevice.cpp |
+++ b/src/pdf/SkPDFDevice.cpp |
@@ -2028,13 +2028,82 @@ int SkPDFDevice::getFontResourceIndex(SkTypeface* typeface, uint16_t glyphID) { |
return resourceIndex; |
} |
-void SkPDFDevice::internalDrawBitmap(const SkMatrix& matrix, |
+static void setup_transparent_bitmap(SkBitmap* bitmap, int width, int height) { |
+ bitmap->setConfig(SkBitmap::kARGB_8888_Config, width, height); |
+ bitmap->allocPixels(); |
+ bitmap->eraseColor(SK_ColorTRANSPARENT); |
+} |
+ |
+void SkPDFDevice::internalDrawBitmap(const SkMatrix& origMatrix, |
const SkClipStack* clipStack, |
- const SkRegion& clipRegion, |
- const SkBitmap& bitmap, |
- const SkIRect* srcRect, |
+ const SkRegion& origClipRegion, |
+ const SkBitmap& origBitmap2, |
+ const SkIRect* origSrcRect, |
const SkPaint& paint) { |
- // TODO(edisonn): Perspective matrix support implemented here |
+ SkMatrix matrix = origMatrix; |
+ SkRegion all; |
+ const SkRegion* clipRegion = &origClipRegion; |
+ SkBitmap origBitmap; |
+ SkBitmap bitmap = origBitmap; |
+ const SkIRect* srcRect = origSrcRect; |
+ |
+ // Raster the bitmap using perspective in a new bitmap. |
+ if (matrix.hasPerspective()) { |
+ if (origSrcRect) { |
+ if (!origBitmap2.extractSubset(&origBitmap, *origSrcRect)) { |
+ return; |
+ } |
+ } else { |
+ origBitmap = origBitmap2; |
+ } |
+ srcRect = NULL; |
+ |
+ // Transform the bitmap in the new space. |
+ SkPath path; |
+ path.addRect(SkRect::MakeWH(SkIntToScalar(origBitmap.width()), |
+ SkIntToScalar(origBitmap.height()))); |
+ path.transform(matrix); |
+ |
+ // Retrieve the bounds of the new shape. |
+ SkRect bounds = path.getBounds(); |
vandebo (ex-Chrome)
2013/10/15 21:41:32
Should this be further constrained by the current
edisonn
2013/10/16 15:08:03
This is an optimization. I will add a todo. in a n
|
+ |
+ // TODO(edisonn): add DPI settings. Currently 1 pixel/point, which does not look great, |
vandebo (ex-Chrome)
2013/10/15 21:41:32
nit: 80 cols
edisonn
2013/10/16 15:08:03
this file is already 100c
vandebo (ex-Chrome)
2013/10/16 16:46:41
Hardly, 31/2073 lines and most of those are over b
edisonn
2013/10/16 18:28:51
Done.
|
+ // but it is not producing large PDFs. |
+ |
+ // Create transparent bitmap. |
+ setup_transparent_bitmap(&bitmap, bounds.width(), bounds.height()); |
+ |
+ SkAutoTUnref<SkBitmapDevice> device(SkNEW_ARGS(SkBitmapDevice, (bitmap))); |
+ SkCanvas canvas(device); |
+ |
+ // Find where (0,0) gets mapped in the new space. |
+ SkPoint zeroZero = SkPoint::Make(SkIntToScalar(0), SkIntToScalar(0)); |
vandebo (ex-Chrome)
2013/10/15 21:41:32
zeroZero isn't used.
edisonn
2013/10/16 15:08:03
Done.
|
+ matrix.mapPoints(&zeroZero, 1); |
+ |
+ SkScalar deltaX = bounds.left(); |
+ SkScalar deltaY = bounds.top(); |
+ |
+ SkMatrix matrix2 = matrix; |
+ matrix2.postTranslate(-deltaX, -deltaY); |
+ |
+ // Translate the draw in the new canvas, so we perfectly fit the shape in the bitmap. |
+ canvas.setMatrix(matrix2); |
+ |
+ canvas.drawBitmap(origBitmap, SkIntToScalar(0), SkIntToScalar(0)); |
+ |
+ // Make sure the final bits ar in the bitmap. |
vandebo (ex-Chrome)
2013/10/15 21:41:32
ar -> are
edisonn
2013/10/16 15:08:03
Done.
|
+ canvas.flush(); |
+ |
+ // In the new space, we use the identity matrix translated. |
+ matrix.setTranslate(deltaX, deltaY); |
+ all.setRect(SkIRect::MakeXYWH(SkScalarToFixed(bounds.x()), |
+ SkScalarToFixed(bounds.y()), |
+ SkScalarToFixed(bounds.width()), |
+ SkScalarToFixed(bounds.height()))); |
+ clipRegion = &all; |
+ srcRect = NULL; |
+ } |
+ |
SkMatrix scaled; |
// Adjust for origin flip. |
scaled.setScale(SK_Scalar1, -SK_Scalar1); |
@@ -2044,7 +2113,8 @@ void SkPDFDevice::internalDrawBitmap(const SkMatrix& matrix, |
scaled.postScale(SkIntToScalar(subset.width()), |
SkIntToScalar(subset.height())); |
scaled.postConcat(matrix); |
- ScopedContentEntry content(this, clipStack, clipRegion, scaled, paint); |
+ |
+ ScopedContentEntry content(this, clipStack, *clipRegion, scaled, paint); |
if (!content.entry()) { |
return; |
} |