[PDF] Add support for SrcIn, SrcOut, DstIn, DstOut xfermodes.

This change uses the soft mask (aka soft clip) functionality of PDF to implement the xfermodes.  It has to put existing content (dst) into a form xobject as well as putting the new (src) content into a different form xobject.  It then draws one of them with the other as the soft mask.
To accomplish this, we add a call to finishContentEntry after each call to setUpContentEntry - this is kind of a hack, but I don't see a better way to extract src.
Unfortunately, soft mask is specified in the Graphic State PDF object (and not in the form xobject), so when handling one of these modes, we add a one time GS object to set the soft mask and invoke a simple GS to reset the soft mask when done.

Review URL: http://codereview.appspot.com/4496041

git-svn-id: http://skia.googlecode.com/svn/trunk@1320 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/include/pdf/SkPDFGraphicState.h b/include/pdf/SkPDFGraphicState.h
index 7fb09d4..b43c107 100644
--- a/include/pdf/SkPDFGraphicState.h
+++ b/include/pdf/SkPDFGraphicState.h
@@ -22,10 +22,12 @@
 #include "SkTemplates.h"
 #include "SkThread.h"
 
+class SkPDFFormXObject;
+
 /** \class SkPDFGraphicState
     SkPaint objects roughly correspond to graphic state dictionaries that can
-    be installed.  So that a given dictionary is only output to the pdf file
-    once, we want to canonicalize them.  Static methods in this class manage
+    be installed. So that a given dictionary is only output to the pdf file
+    once, we want to canonicalize them. Static methods in this class manage
     a weakly referenced set of SkPDFGraphicState objects: when the last
     reference to a SkPDFGraphicState is removed, it removes itself from the
     static set of objects.
@@ -35,6 +37,8 @@
 public:
     virtual ~SkPDFGraphicState();
 
+    virtual void getResources(SkTDArray<SkPDFObject*>* resourceList);
+
     // Override emitObject and getOutputSize so that we can populate
     // the dictionary on demand.
     virtual void emitObject(SkWStream* stream, SkPDFCatalog* catalog,
@@ -43,16 +47,35 @@
 
     /** Get the graphic state for the passed SkPaint. The reference count of
      *  the object is incremented and it is the caller's responsibility to
-     *  unreference it when done.  This is needed to accommodate the weak
+     *  unreference it when done. This is needed to accommodate the weak
      *  reference pattern used when the returned object is new and has no
      *  other references.
      *  @param paint  The SkPaint to emulate.
      */
     static SkPDFGraphicState* getGraphicStateForPaint(const SkPaint& paint);
 
+    /** Make a graphic state that only sets the passed soft mask. The
+     *  reference count of the object is incremented and it is the caller's
+     *  responsibility to unreference it when done.
+     *  @param sMask  The form xobject to use as a soft mask.
+     *  @param invert Indicates if the alpha of the sMask should be inverted.
+     */
+    static SkPDFGraphicState* getSMaskGraphicState(SkPDFFormXObject* sMask,
+                                                   bool invert);
+
+    /** Get a graphic state that only unsets the soft mask. The reference
+     *  count of the object is incremented and it is the caller's responsibility
+     *  to unreference it when done. This is needed to accommodate the weak
+     *  reference pattern used when the returned object is new and has no
+     *  other references.
+     */
+    static SkPDFGraphicState* getNoSMaskGraphicState();
+
 private:
     const SkPaint fPaint;
+    SkTDArray<SkPDFObject*> fResources;
     bool fPopulated;
+    bool fSMask;
 
     class GSCanonicalEntry {
     public:
@@ -70,6 +93,7 @@
     static SkTDArray<GSCanonicalEntry>& canonicalPaints();
     static SkMutex& canonicalPaintsMutex();
 
+    SkPDFGraphicState();
     explicit SkPDFGraphicState(const SkPaint& paint);
 
     void populateDict();