aboutsummaryrefslogtreecommitdiffhomepage
path: root/include
diff options
context:
space:
mode:
authorGravatar vandebo@chromium.org <vandebo@chromium.org@2bbb7eff-a529-9590-31e7-b0007b416f81>2011-05-09 07:55:58 +0000
committerGravatar vandebo@chromium.org <vandebo@chromium.org@2bbb7eff-a529-9590-31e7-b0007b416f81>2011-05-09 07:55:58 +0000
commit9fbdf875183f5142b8e0ba46ab430cc46ad701bf (patch)
treeed1e33ecd601100a41657012aa66e9e6b5966301 /include
parent7744c205f20b5617e83d4af8f97b5771bfa8d671 (diff)
[PDF] Refactor content stream creation in SkPDFDevice to support more xfermodes.
Instead of writing all drawing and state updates into the final content stream immediately, this change creates a new ContentEntry each time the transform, clip, or paint changes. Drawing is done into a stream in the ContentEntry. When the consumer asks for the content, we combine all the ContentEntries with appropriate updates to the state (clip, transform, paint) in between. This allows us to modify the clip even after a drawing has completed. It also lets us remove ContentEntries with no drawing. Further optimization can be done to better use the stack features of PDF, for now we follow the previous model of having a single clip followed by a single transform on the graphic state stack. Push rectangle logic into SkPDFUtil::AppendRectangle. Change private functions to adhere to coding standards. Review URL: http://codereview.appspot.com/4459041 git-svn-id: http://skia.googlecode.com/svn/trunk@1269 2bbb7eff-a529-9590-31e7-b0007b416f81
Diffstat (limited to 'include')
-rw-r--r--include/core/SkClipStack.h1
-rw-r--r--include/pdf/SkPDFDevice.h85
-rw-r--r--include/pdf/SkPDFUtils.h4
3 files changed, 44 insertions, 46 deletions
diff --git a/include/core/SkClipStack.h b/include/core/SkClipStack.h
index b94ae19246..ae0b974d6e 100644
--- a/include/core/SkClipStack.h
+++ b/include/core/SkClipStack.h
@@ -42,6 +42,7 @@ public:
B2FIter(const SkClipStack& stack);
struct Clip {
+ friend bool operator==(const Clip& a, const Clip& b);
const SkRect* fRect; // if non-null, this is a rect clip
const SkPath* fPath; // if non-null, this is a path clip
SkRegion::Op fOp;
diff --git a/include/pdf/SkPDFDevice.h b/include/pdf/SkPDFDevice.h
index 98a473fed7..0d058fbeb6 100644
--- a/include/pdf/SkPDFDevice.h
+++ b/include/pdf/SkPDFDevice.h
@@ -17,11 +17,12 @@
#ifndef SkPDFDevice_DEFINED
#define SkPDFDevice_DEFINED
-#include "SkRefCnt.h"
#include "SkDevice.h"
-#include "SkStream.h"
#include "SkPaint.h"
#include "SkPath.h"
+#include "SkRefCnt.h"
+#include "SkStream.h"
+#include "SkTScopedPtr.h"
class SkPDFArray;
class SkPDFDevice;
@@ -32,6 +33,10 @@ class SkPDFObject;
class SkPDFShader;
class SkPDFStream;
+// Private classes.
+struct ContentEntry;
+struct GraphicStateEntry;
+
class SkPDFDeviceFactory : public SkDeviceFactory {
virtual SkDevice* newDevice(SkCanvas*, SkBitmap::Config, int width,
int height, bool isOpaque, bool isForLayer);
@@ -70,13 +75,6 @@ public:
virtual void clear(SkColor color);
- /** Called with the correct matrix and clip before this device is drawn
- to using those settings. If your subclass overrides this, be sure to
- call through to the base class as well.
- */
- virtual void setMatrixClip(const SkMatrix&, const SkRegion&,
- const SkClipStack&);
-
virtual bool readPixels(const SkIRect& srcRect, SkBitmap* bitmap) {
return false;
}
@@ -141,7 +139,10 @@ protected:
private:
SkISize fPageSize;
+ SkISize fContentSize;
SkMatrix fInitialTransform;
+ SkClipStack fExistingClipStack;
+ SkRegion fExistingClipRegion;
SkRefPtr<SkPDFDict> fResourceDict;
SkTDArray<SkPDFGraphicState*> fGraphicStateResources;
@@ -149,49 +150,45 @@ private:
SkTDArray<SkPDFFont*> fFontResources;
SkTDArray<SkPDFShader*> fShaderResources;
- // In PDF, transforms and clips can only be undone by popping the graphic
- // state to before the transform or clip was applied. Because it can be
- // a lot of work to reapply a clip and because this class has to apply
- // different transforms to accomplish various operations, the clip is
- // always applied before a transform and always at a different graphic
- // state-stack level than a transform. This strategy results in the
- // following possible states for the graphic state stack:
- // empty: (identity transform and clip to page)
- // one entry: a transform
- // one entry: a clip
- // two entries: a clip and then a transform
- // Pointers are owned by the respective Resources list.
- struct GraphicStackEntry {
- SkColor fColor;
- SkScalar fTextSize;
- SkScalar fTextScaleX;
- SkPaint::Style fTextFill;
- SkPDFFont* fFont;
- SkPDFShader* fShader;
- SkPDFGraphicState* fGraphicState;
- SkRegion fClip;
- SkMatrix fTransform;
- };
- struct GraphicStackEntry fGraphicStack[3];
- int fGraphicStackIndex;
-
- SkDynamicMemoryWStream fContent;
+ SkTScopedPtr<ContentEntry> fContentEntries;
+ ContentEntry* fCurrentContentEntry;
void init();
void cleanUp();
- void updateGSFromPaint(const SkPaint& newPaint, bool forText);
+ void setExistingClip(const SkClipStack& clipStack,
+ const SkRegion& clipRegion);
+
+ void setUpContentEntry(const SkClipStack& clipStack,
+ const SkRegion& clipRegion,
+ const SkMatrix& matrix,
+ const SkPaint& paint,
+ bool hasText = false);
+ void setUpContentEntryForText(const SkClipStack& clipStack,
+ const SkRegion& clipRegion,
+ const SkMatrix& matrix,
+ const SkPaint& paint);
+ void populateGraphicStateEntryFromPaint(const SkMatrix& matrix,
+ const SkClipStack& clipStack,
+ const SkRegion& clipRegion,
+ const SkPaint& paint,
+ bool hasText,
+ GraphicStateEntry* entry);
+
void updateFont(const SkPaint& paint, uint16_t glyphID);
int getFontResourceIndex(SkTypeface* typeface, uint16_t glyphID);
-
- void pushGS();
- void popGS();
void setTextTransform(SkScalar x, SkScalar y, SkScalar textSkewX);
+
void internalDrawPaint(const SkPaint& paint);
- void internalDrawRect(const SkRect& r, const SkPaint& paint);
- void internalDrawBitmap(const SkMatrix& matrix, const SkBitmap& bitmap,
- const SkIRect* srcRect, const SkPaint& paint);
+ void internalDrawBitmap(const SkMatrix& matrix,
+ const SkClipStack& clipStack,
+ const SkRegion& clipRegion,
+ const SkBitmap& bitmap,
+ const SkIRect* srcRect,
+ const SkPaint& paint);
- SkMatrix setTransform(const SkMatrix& matrix);
+ // Disable the default copy and assign implementation.
+ SkPDFDevice(const SkPDFDevice&);
+ void operator=(const SkPDFDevice&);
};
#endif
diff --git a/include/pdf/SkPDFUtils.h b/include/pdf/SkPDFUtils.h
index 62a5120ae7..0db4885332 100644
--- a/include/pdf/SkPDFUtils.h
+++ b/include/pdf/SkPDFUtils.h
@@ -22,6 +22,7 @@
class SkMatrix;
class SkPath;
class SkPDFArray;
+class SkRect;
#if 0
#define PRINT_NOT_IMPL(str) fprintf(stderr, str)
@@ -47,8 +48,7 @@ public:
static void AppendCubic(SkScalar ctl1X, SkScalar ctl1Y,
SkScalar ctl2X, SkScalar ctl2Y,
SkScalar dstX, SkScalar dstY, SkWStream* content);
- static void AppendRectangle(SkScalar x, SkScalar y, SkScalar w, SkScalar h,
- SkWStream* content);
+ static void AppendRectangle(const SkRect& rect, SkWStream* content);
static void EmitPath(const SkPath& path, SkWStream* content);
static void ClosePath(SkWStream* content);
static void PaintPath(SkPaint::Style style, SkPath::FillType fill,