1 2 /* 3 * Copyright 2010 The Android Open Source Project 4 * 5 * Use of this source code is governed by a BSD-style license that can be 6 * found in the LICENSE file. 7 */ 8 9 10 #ifndef SkPDFGraphicState_DEFINED 11 #define SkPDFGraphicState_DEFINED 12 13 #include "SkPaint.h" 14 #include "SkPDFTypes.h" 15 #include "SkTemplates.h" 16 #include "SkThread.h" 17 18 class SkPDFFormXObject; 19 20 /** \class SkPDFGraphicState 21 SkPaint objects roughly correspond to graphic state dictionaries that can 22 be installed. So that a given dictionary is only output to the pdf file 23 once, we want to canonicalize them. Static methods in this class manage 24 a weakly referenced set of SkPDFGraphicState objects: when the last 25 reference to a SkPDFGraphicState is removed, it removes itself from the 26 static set of objects. 27 28 */ 29 class SkPDFGraphicState : public SkPDFDict { 30 public: 31 virtual ~SkPDFGraphicState(); 32 33 virtual void getResources(SkTDArray<SkPDFObject*>* resourceList); 34 35 // Override emitObject and getOutputSize so that we can populate 36 // the dictionary on demand. 37 virtual void emitObject(SkWStream* stream, SkPDFCatalog* catalog, 38 bool indirect); 39 virtual size_t getOutputSize(SkPDFCatalog* catalog, bool indirect); 40 41 /** Get the graphic state for the passed SkPaint. The reference count of 42 * the object is incremented and it is the caller's responsibility to 43 * unreference it when done. This is needed to accommodate the weak 44 * reference pattern used when the returned object is new and has no 45 * other references. 46 * @param paint The SkPaint to emulate. 47 */ 48 static SkPDFGraphicState* GetGraphicStateForPaint(const SkPaint& paint); 49 50 /** Make a graphic state that only sets the passed soft mask. The 51 * reference count of the object is incremented and it is the caller's 52 * responsibility to unreference it when done. 53 * @param sMask The form xobject to use as a soft mask. 54 * @param invert Indicates if the alpha of the sMask should be inverted. 55 */ 56 static SkPDFGraphicState* GetSMaskGraphicState(SkPDFFormXObject* sMask, 57 bool invert); 58 59 /** Get a graphic state that only unsets the soft mask. The reference 60 * count of the object is incremented and it is the caller's responsibility 61 * to unreference it when done. This is needed to accommodate the weak 62 * reference pattern used when the returned object is new and has no 63 * other references. 64 */ 65 static SkPDFGraphicState* GetNoSMaskGraphicState(); 66 67 private: 68 const SkPaint fPaint; 69 SkTDArray<SkPDFObject*> fResources; 70 bool fPopulated; 71 bool fSMask; 72 73 class GSCanonicalEntry { 74 public: 75 SkPDFGraphicState* fGraphicState; 76 const SkPaint* fPaint; 77 78 bool operator==(const GSCanonicalEntry& b) const; 79 explicit GSCanonicalEntry(SkPDFGraphicState* gs) 80 : fGraphicState(gs), 81 fPaint(&gs->fPaint) {} 82 explicit GSCanonicalEntry(const SkPaint* paint) 83 : fGraphicState(NULL), 84 fPaint(paint) {} 85 }; 86 87 // This should be made a hash table if performance is a problem. 88 static SkTDArray<GSCanonicalEntry>& CanonicalPaints(); 89 static SkBaseMutex& CanonicalPaintsMutex(); 90 91 SkPDFGraphicState(); 92 explicit SkPDFGraphicState(const SkPaint& paint); 93 94 void populateDict(); 95 96 static SkPDFObject* GetInvertFunction(); 97 98 static int Find(const SkPaint& paint); 99 }; 100 101 #endif 102