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