Generalize the flip origin argument to the PDF device constructor.
The argument still has a default value that does what most users will want, but provides more flexibility.
Chrome will use this change to support an initial translation of the origin to simulate a margin and to scale the entire content (needed on Windows).
When landing to Chrome, this will need http://codereview.chromium.org/6820038
Review URL: http://codereview.appspot.com/4373052
git-svn-id: http://skia.googlecode.com/svn/trunk@1111 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/src/pdf/SkPDFDevice.cpp b/src/pdf/SkPDFDevice.cpp
index 3665dd8..4a25511 100644
--- a/src/pdf/SkPDFDevice.cpp
+++ b/src/pdf/SkPDFDevice.cpp
@@ -113,11 +113,13 @@
SkDevice* SkPDFDeviceFactory::newDevice(SkCanvas*, SkBitmap::Config config,
int width, int height, bool isOpaque,
bool isForLayer) {
- SkPDFDevice::OriginTransform flip = SkPDFDevice::kFlip_OriginTransform;
+ SkMatrix initialTransform;
+ initialTransform.reset();
if (isForLayer) {
- flip = SkPDFDevice::kNoFlip_OriginTransform;
+ initialTransform.setTranslate(0, height);
+ initialTransform.preScale(1, -1);
}
- return SkNEW_ARGS(SkPDFDevice, (width, height, flip));
+ return SkNEW_ARGS(SkPDFDevice, (width, height, initialTransform));
}
static inline SkBitmap makeABitmap(int width, int height) {
@@ -126,11 +128,11 @@
return bitmap;
}
-SkPDFDevice::SkPDFDevice(int width, int height, OriginTransform flipOrigin)
+SkPDFDevice::SkPDFDevice(int width, int height,
+ const SkMatrix& initialTransform)
: SkDevice(NULL, makeABitmap(width, height), false),
fWidth(width),
fHeight(height),
- fFlipOrigin(flipOrigin),
fGraphicStackIndex(0) {
fGraphicStack[0].fColor = SK_ColorBLACK;
fGraphicStack[0].fTextSize = SK_ScalarNaN; // This has no default value.
@@ -142,10 +144,14 @@
fGraphicStack[0].fClip.setRect(0,0, width, height);
fGraphicStack[0].fTransform.reset();
- if (flipOrigin == kFlip_OriginTransform) {
- fContent.writeText("1 0 0 -1 0 ");
- fContent.writeDecAsText(fHeight);
- fContent.writeText(" cm\n");
+ // Skia generally uses the top left as the origin but PDF natively has the
+ // origin at the bottom left. This matrix corrects for that. When layering,
+ // we specify an inverse correction to cancel this out.
+ fInitialTransform.setTranslate(0, height);
+ fInitialTransform.preScale(1, -1);
+ fInitialTransform.preConcat(initialTransform);
+ if (fInitialTransform.getType() != SkMatrix::kIdentity_Mask) {
+ SkPDFUtils::AppendTransform(fInitialTransform, &fContent);
}
}
@@ -601,13 +607,10 @@
// PDF positions patterns relative to the initial transform, so
// we need to apply the current transform to the shader parameters.
SkMatrix transform = fGraphicStack[fGraphicStackIndex].fTransform;
- if (fFlipOrigin == kFlip_OriginTransform) {
- transform.postScale(1, -1);
- transform.postTranslate(0, fHeight);
- }
+ transform.postConcat(fInitialTransform);
// PDF doesn't support kClamp_TileMode, so we simulate it by making
- // a pattern the size of the drawing service.
+ // a pattern the size of the drawing surface.
SkIRect bounds = fGraphicStack[fGraphicStackIndex].fClip.getBounds();
pdfShader = SkPDFShader::getPDFShader(*shader, transform, bounds);
SkSafeUnref(pdfShader.get()); // getShader and SkRefPtr both took a ref
@@ -808,13 +811,7 @@
fGraphicStack[fGraphicStackIndex - 1].fClip)
pushGS();
- SkScalar transform[6];
- SkAssertResult(m.pdfTransform(transform));
- for (size_t i = 0; i < SK_ARRAY_COUNT(transform); i++) {
- SkPDFScalar::Append(transform[i], &fContent);
- fContent.writeText(" ");
- }
- fContent.writeText("cm\n");
+ SkPDFUtils::AppendTransform(m, &fContent);
fGraphicStack[fGraphicStackIndex].fTransform = m;
return old;