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 SK_DECLARE_INST_COUNT(SkPDFGraphicState) 31 public: 32 enum SkPDFSMaskMode { 33 kAlpha_SMaskMode, 34 kLuminosity_SMaskMode 35 }; 36 37 virtual ~SkPDFGraphicState(); 38 39 virtual void getResources(const SkTSet<SkPDFObject*>& knownResourceObjects, 40 SkTSet<SkPDFObject*>* newResourceObjects); 41 42 // Override emitObject and getOutputSize so that we can populate 43 // the dictionary on demand. 44 virtual void emitObject(SkWStream* stream, SkPDFCatalog* catalog, 45 bool indirect); 46 virtual size_t getOutputSize(SkPDFCatalog* catalog, bool indirect); 47 48 /** Get the graphic state for the passed SkPaint. The reference count of 49 * the object is incremented and it is the caller's responsibility to 50 * unreference it when done. This is needed to accommodate the weak 51 * reference pattern used when the returned object is new and has no 52 * other references. 53 * @param paint The SkPaint to emulate. 54 */ 55 static SkPDFGraphicState* GetGraphicStateForPaint(const SkPaint& paint); 56 57 /** Make a graphic state that only sets the passed soft mask. The 58 * reference count of the object is incremented and it is the caller's 59 * responsibility to unreference it when done. 60 * @param sMask The form xobject to use as a soft mask. 61 * @param invert Indicates if the alpha of the sMask should be inverted. 62 * @param sMaskMode Whether to use alpha or luminosity for the sMask. 63 */ 64 static SkPDFGraphicState* GetSMaskGraphicState(SkPDFFormXObject* sMask, 65 bool invert, 66 SkPDFSMaskMode sMaskMode); 67 68 /** Get a graphic state that only unsets the soft mask. The reference 69 * count of the object is incremented and it is the caller's responsibility 70 * to unreference it when done. This is needed to accommodate the weak 71 * reference pattern used when the returned object is new and has no 72 * other references. 73 */ 74 static SkPDFGraphicState* GetNoSMaskGraphicState(); 75 76 private: 77 const SkPaint fPaint; 78 SkTDArray<SkPDFObject*> fResources; 79 bool fPopulated; 80 bool fSMask; 81 82 class GSCanonicalEntry { 83 public: 84 SkPDFGraphicState* fGraphicState; 85 const SkPaint* fPaint; 86 87 bool operator==(const GSCanonicalEntry& b) const; 88 explicit GSCanonicalEntry(SkPDFGraphicState* gs) 89 : fGraphicState(gs), 90 fPaint(&gs->fPaint) {} 91 explicit GSCanonicalEntry(const SkPaint* paint) 92 : fGraphicState(NULL), 93 fPaint(paint) {} 94 }; 95 96 // This should be made a hash table if performance is a problem. 97 static SkTDArray<GSCanonicalEntry>& CanonicalPaints(); 98 static SkBaseMutex& CanonicalPaintsMutex(); 99 100 SkPDFGraphicState(); 101 explicit SkPDFGraphicState(const SkPaint& paint); 102 103 void populateDict(); 104 105 static SkPDFObject* GetInvertFunction(); 106 107 static int Find(const SkPaint& paint); 108 typedef SkPDFDict INHERITED; 109 }; 110 111 #endif 112