aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar vandebo@chromium.org <vandebo@chromium.org@2bbb7eff-a529-9590-31e7-b0007b416f81>2011-02-24 23:14:04 +0000
committerGravatar vandebo@chromium.org <vandebo@chromium.org@2bbb7eff-a529-9590-31e7-b0007b416f81>2011-02-24 23:14:04 +0000
commitf60a001d1a0052fe21956d8d222d9ba1b5a05981 (patch)
tree9a34daf105a69210b27d548c655e6a17acd0619c
parent112706d4c566e283890322bb246b4b86d59837e1 (diff)
[PDF] Change the way flip origin is done.
The PDF shader matrix is dependent on flip origin or not, so we need to set it at device creation time. Review URL: http://codereview.appspot.com/4216046 git-svn-id: http://skia.googlecode.com/svn/trunk@855 2bbb7eff-a529-9590-31e7-b0007b416f81
-rw-r--r--include/pdf/SkPDFDevice.h18
-rw-r--r--include/pdf/SkPDFFormXObject.h2
-rw-r--r--src/pdf/SkPDFDevice.cpp24
-rw-r--r--src/pdf/SkPDFFormXObject.cpp2
-rw-r--r--src/pdf/SkPDFPage.cpp2
5 files changed, 32 insertions, 16 deletions
diff --git a/include/pdf/SkPDFDevice.h b/include/pdf/SkPDFDevice.h
index 5bcc8e3d36..f9247a7122 100644
--- a/include/pdf/SkPDFDevice.h
+++ b/include/pdf/SkPDFDevice.h
@@ -42,12 +42,24 @@ class SkPDFDeviceFactory : public SkDeviceFactory {
*/
class SkPDFDevice : public SkDevice {
public:
+ /** Skia generally uses the top left as the origin and PDFs natively use
+ the bottom left. We can move the origin to the top left in the PDF
+ with a transform, but we have to be careful to apply the transform
+ only once.
+ */
+ enum OriginTransform {
+ kFlip_OriginTransform,
+ kNoFlip_OriginTransform,
+ };
+
/** Create a PDF drawing context with the given width and height.
* 72 points/in means letter paper is 612x792.
* @param width Page width in points.
* @param height Page height in points.
+ * @param flipOrigin Flip the origin from lower left to upper left.
*/
- SkPDFDevice(int width, int height);
+ SkPDFDevice(int width, int height,
+ OriginTransform flipOrigin = kFlip_OriginTransform);
virtual ~SkPDFDevice();
virtual SkDeviceFactory* getDeviceFactory() {
@@ -121,13 +133,13 @@ public:
SkRefPtr<SkPDFArray> getMediaBox() const;
/** Returns a string with the page contents.
- * @param flipOrigin Flip the origin between top and bottom.
*/
- SkString content(bool flipOrigin) const;
+ SkString content() const;
private:
int fWidth;
int fHeight;
+ OriginTransform fFlipOrigin;
SkRefPtr<SkPDFDict> fResourceDict;
SkTDArray<SkPDFGraphicState*> fGraphicStateResources;
diff --git a/include/pdf/SkPDFFormXObject.h b/include/pdf/SkPDFFormXObject.h
index ed1656680b..41719f0820 100644
--- a/include/pdf/SkPDFFormXObject.h
+++ b/include/pdf/SkPDFFormXObject.h
@@ -28,7 +28,7 @@ class SkPDFCatalog;
/** \class SkPDFFormXObject
- A form XObject; a self containted description of graphics objects. A form
+ A form XObject; a self contained description of graphics objects. A form
XObject is basically a page object with slightly different syntax, that
can be drawn onto a page.
*/
diff --git a/src/pdf/SkPDFDevice.cpp b/src/pdf/SkPDFDevice.cpp
index 72b2e1bf6a..1c6477f9ba 100644
--- a/src/pdf/SkPDFDevice.cpp
+++ b/src/pdf/SkPDFDevice.cpp
@@ -120,8 +120,12 @@ void alignText(SkDrawCacheProc glyphCacheProc, const SkPaint& paint,
SkDevice* SkPDFDeviceFactory::newDevice(SkCanvas*, SkBitmap::Config config,
int width, int height, bool isOpaque,
- bool /*isForLayer*/) {
- return SkNEW_ARGS(SkPDFDevice, (width, height));
+ bool isForLayer) {
+ SkPDFDevice::OriginTransform flip = SkPDFDevice::kFlip_OriginTransform;
+ if (isForLayer) {
+ flip = SkPDFDevice::kNoFlip_OriginTransform;
+ }
+ return SkNEW_ARGS(SkPDFDevice, (width, height, flip));
}
static inline SkBitmap makeABitmap(int width, int height) {
@@ -130,10 +134,11 @@ static inline SkBitmap makeABitmap(int width, int height) {
return bitmap;
}
-SkPDFDevice::SkPDFDevice(int width, int height)
+SkPDFDevice::SkPDFDevice(int width, int height, OriginTransform flipOrigin)
: 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.
@@ -143,6 +148,10 @@ SkPDFDevice::SkPDFDevice(int width, int height)
fGraphicStack[0].fGraphicState = NULL;
fGraphicStack[0].fClip.setRect(0,0, width, height);
fGraphicStack[0].fTransform.reset();
+
+ if (flipOrigin == kFlip_OriginTransform) {
+ fContent.printf("1 0 0 -1 0 %d cm\n", fHeight);
+ }
}
SkPDFDevice::~SkPDFDevice() {
@@ -549,13 +558,8 @@ SkRefPtr<SkPDFArray> SkPDFDevice::getMediaBox() const {
return mediaBox;
}
-SkString SkPDFDevice::content(bool flipOrigin) const {
- SkString result;
- // Scale and translate to move the origin from the lower left to the
- // upper left.
- if (flipOrigin)
- result.printf("1 0 0 -1 0 %d cm\n", fHeight);
- result.append(fContent);
+SkString SkPDFDevice::content() const {
+ SkString result = fContent;
for (int i = 0; i < fGraphicStackIndex; i++)
result.append("Q\n");
return result;
diff --git a/src/pdf/SkPDFFormXObject.cpp b/src/pdf/SkPDFFormXObject.cpp
index ef839a3b4e..40bfad74e3 100644
--- a/src/pdf/SkPDFFormXObject.cpp
+++ b/src/pdf/SkPDFFormXObject.cpp
@@ -28,7 +28,7 @@ SkPDFFormXObject::SkPDFFormXObject(SkPDFDevice* device) {
// resources).
device->getResources(&fResources);
- SkString content = device->content(false);
+ SkString content = device->content();
SkMemoryStream* stream_data = new SkMemoryStream(content.c_str(),
content.size());
SkAutoUnref stream_data_unref(stream_data);
diff --git a/src/pdf/SkPDFPage.cpp b/src/pdf/SkPDFPage.cpp
index 1c470c7d01..2bec90744e 100644
--- a/src/pdf/SkPDFPage.cpp
+++ b/src/pdf/SkPDFPage.cpp
@@ -32,7 +32,7 @@ void SkPDFPage::finalizePage(SkPDFCatalog* catalog, bool firstPage,
insert("Resources", fDevice->getResourceDict().get());
insert("MediaBox", fDevice->getMediaBox().get());
- fContent = fDevice->content(true);
+ fContent = fDevice->content();
SkRefPtr<SkMemoryStream> contentStream = new SkMemoryStream(
fContent.c_str(), fContent.size());
contentStream->unref(); // SkRefPtr and new both took a reference.