PDF Device should report non-transformed size for width and height.
authorctguil@chromium.org <ctguil@chromium.org@2bbb7eff-a529-9590-31e7-b0007b416f81>
Fri, 29 Apr 2011 17:54:16 +0000 (17:54 +0000)
committerctguil@chromium.org <ctguil@chromium.org@2bbb7eff-a529-9590-31e7-b0007b416f81>
Fri, 29 Apr 2011 17:54:16 +0000 (17:54 +0000)
Review URL: http://codereview.appspot.com/4435074

git-svn-id: http://skia.googlecode.com/svn/trunk@1217 2bbb7eff-a529-9590-31e7-b0007b416f81

gm/gmmain.cpp
include/pdf/SkPDFDevice.h
src/pdf/SkPDFDevice.cpp
src/pdf/SkPDFShader.cpp

index b59182c..6267fd4 100644 (file)
@@ -236,8 +236,7 @@ static void generate_pdf(GM* gm, SkDynamicMemoryWStream& pdf) {
     SkISize size = gm->getISize();
     SkMatrix identity;
     identity.reset();
-    SkPDFDevice* dev = new SkPDFDevice(size.width(), size.height(),
-                                       identity);
+    SkPDFDevice* dev = new SkPDFDevice(size, size, identity);
     SkAutoUnref aur(dev);
 
     SkCanvas c(dev);
index 0d06fe6..26d3087 100644 (file)
@@ -45,8 +45,11 @@ class SkPDFDevice : public SkDevice {
 public:
     /** 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 pageSize Page size in points.
+     *  @param contentSize The content size of the page in points. This will be
+     *         combined with the initial transform to determine the drawing area
+     *         (as reported by the width and height methods). Anything outside
+     *         of the drawing area will be clipped.
      *  @param initialTransform The initial transform to apply to the page.
      *         This may be useful to, for example, move the origin in and
      *         over a bit to account for a margin, scale the canvas,
@@ -58,15 +61,12 @@ public:
      *         inverse scale+translate to accommodate the one that SkPDFDevice
      *         always does.
      */
-    SkPDFDevice(int width, int height, const SkMatrix& initialTransform);
-    virtual ~SkPDFDevice();
+    SK_API SkPDFDevice(const SkISize& pageSize, const SkISize& contentSize,
+                       const SkMatrix& initialTransform);
+    SK_API virtual ~SkPDFDevice();
 
     virtual uint32_t getDeviceCapabilities() { return kVector_Capability; }
 
-    virtual int width() const { return fWidth; };
-
-    virtual int height() const { return fHeight; };
-
     virtual void clear(SkColor color);
 
     /** Called with the correct matrix and clip before this device is drawn
@@ -139,8 +139,7 @@ protected:
     virtual SkDeviceFactory* onNewDeviceFactory();
 
 private:
-    int fWidth;
-    int fHeight;
+    SkISize fPageSize;
     SkMatrix fInitialTransform;
     SkRefPtr<SkPDFDict> fResourceDict;
 
index 13ffd5b..ef06c60 100644 (file)
@@ -120,25 +120,34 @@ SkDevice* SkPDFDeviceFactory::newDevice(SkCanvas*, SkBitmap::Config config,
         initialTransform.setTranslate(0, height);
         initialTransform.preScale(1, -1);
     }
-    return SkNEW_ARGS(SkPDFDevice, (width, height, initialTransform));
+    SkISize size = SkISize::Make(width, height);
+    return SkNEW_ARGS(SkPDFDevice, (size, size, initialTransform));
 }
 
-static inline SkBitmap makeABitmap(int width, int height) {
+static inline SkBitmap makeContentBitmap(const SkISize& contentSize,
+                                         const SkMatrix& initialTransform) {
+    // Compute the size of the drawing area.
+    SkVector drawingSize;
+    SkMatrix inverse;
+    drawingSize.set(contentSize.fWidth, contentSize.fHeight);
+    initialTransform.invert(&inverse);
+    inverse.mapVectors(&drawingSize, 1);
+    SkISize size = SkSize::Make(drawingSize.fX, drawingSize.fY).toRound();
+
     SkBitmap bitmap;
-    bitmap.setConfig(SkBitmap::kNo_Config, width, height);
+    bitmap.setConfig(SkBitmap::kNo_Config, size.fWidth, size.fHeight);
     return bitmap;
 }
 
-SkPDFDevice::SkPDFDevice(int width, int height,
+SkPDFDevice::SkPDFDevice(const SkISize& pageSize, const SkISize& contentSize,
                          const SkMatrix& initialTransform)
-    : SkDevice(NULL, makeABitmap(width, height), false),
-      fWidth(width),
-      fHeight(height),
+    : SkDevice(NULL, makeContentBitmap(contentSize, initialTransform), false),
+      fPageSize(pageSize),
       fGraphicStackIndex(0) {
     // 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.setTranslate(0, pageSize.fHeight);
     fInitialTransform.preScale(1, -1);
     fInitialTransform.preConcat(initialTransform);
 
@@ -157,7 +166,7 @@ void SkPDFDevice::init() {
     fGraphicStack[0].fFont = NULL;
     fGraphicStack[0].fShader = NULL;
     fGraphicStack[0].fGraphicState = NULL;
-    fGraphicStack[0].fClip.setRect(0,0, fWidth, fHeight);
+    fGraphicStack[0].fClip.setRect(0, 0, this->width(), this->height());
     fGraphicStack[0].fTransform.reset();
     fGraphicStackIndex = 0;
     fResourceDict = NULL;
@@ -668,8 +677,8 @@ SkRefPtr<SkPDFArray> SkPDFDevice::getMediaBox() const {
     mediaBox->reserve(4);
     mediaBox->append(zero.get());
     mediaBox->append(zero.get());
-    mediaBox->append(new SkPDFInt(fWidth))->unref();
-    mediaBox->append(new SkPDFInt(fHeight))->unref();
+    mediaBox->append(new SkPDFInt(fPageSize.fWidth))->unref();
+    mediaBox->append(new SkPDFInt(fPageSize.fHeight))->unref();
     return mediaBox;
 }
 
index 3f383e5..2538c0d 100644 (file)
@@ -498,7 +498,8 @@ void SkPDFShader::doImageShader() {
     SkMatrix unflip;
     unflip.setTranslate(0, surfaceBBox.fBottom);
     unflip.preScale(1, -1);
-    SkPDFDevice pattern(surfaceBBox.fRight, surfaceBBox.fBottom, unflip);
+    SkISize size = SkISize::Make(surfaceBBox.width(), surfaceBBox.height());
+    SkPDFDevice pattern(size, size, unflip);
     SkCanvas canvas(&pattern);
     canvas.clipRect(surfaceBBox, SkRegion::kReplace_Op);