michael@0: michael@0: /* michael@0: * Copyright 2010 The Android Open Source Project michael@0: * michael@0: * Use of this source code is governed by a BSD-style license that can be michael@0: * found in the LICENSE file. michael@0: */ michael@0: michael@0: michael@0: #ifndef SkPDFGraphicState_DEFINED michael@0: #define SkPDFGraphicState_DEFINED michael@0: michael@0: #include "SkPaint.h" michael@0: #include "SkPDFTypes.h" michael@0: #include "SkTemplates.h" michael@0: #include "SkThread.h" michael@0: michael@0: class SkPDFFormXObject; michael@0: michael@0: /** \class SkPDFGraphicState michael@0: SkPaint objects roughly correspond to graphic state dictionaries that can michael@0: be installed. So that a given dictionary is only output to the pdf file michael@0: once, we want to canonicalize them. Static methods in this class manage michael@0: a weakly referenced set of SkPDFGraphicState objects: when the last michael@0: reference to a SkPDFGraphicState is removed, it removes itself from the michael@0: static set of objects. michael@0: michael@0: */ michael@0: class SkPDFGraphicState : public SkPDFDict { michael@0: SK_DECLARE_INST_COUNT(SkPDFGraphicState) michael@0: public: michael@0: enum SkPDFSMaskMode { michael@0: kAlpha_SMaskMode, michael@0: kLuminosity_SMaskMode michael@0: }; michael@0: michael@0: virtual ~SkPDFGraphicState(); michael@0: michael@0: virtual void getResources(const SkTSet& knownResourceObjects, michael@0: SkTSet* newResourceObjects); michael@0: michael@0: // Override emitObject and getOutputSize so that we can populate michael@0: // the dictionary on demand. michael@0: virtual void emitObject(SkWStream* stream, SkPDFCatalog* catalog, michael@0: bool indirect); michael@0: virtual size_t getOutputSize(SkPDFCatalog* catalog, bool indirect); michael@0: michael@0: /** Get the graphic state for the passed SkPaint. The reference count of michael@0: * the object is incremented and it is the caller's responsibility to michael@0: * unreference it when done. This is needed to accommodate the weak michael@0: * reference pattern used when the returned object is new and has no michael@0: * other references. michael@0: * @param paint The SkPaint to emulate. michael@0: */ michael@0: static SkPDFGraphicState* GetGraphicStateForPaint(const SkPaint& paint); michael@0: michael@0: /** Make a graphic state that only sets the passed soft mask. The michael@0: * reference count of the object is incremented and it is the caller's michael@0: * responsibility to unreference it when done. michael@0: * @param sMask The form xobject to use as a soft mask. michael@0: * @param invert Indicates if the alpha of the sMask should be inverted. michael@0: * @param sMaskMode Whether to use alpha or luminosity for the sMask. michael@0: */ michael@0: static SkPDFGraphicState* GetSMaskGraphicState(SkPDFFormXObject* sMask, michael@0: bool invert, michael@0: SkPDFSMaskMode sMaskMode); michael@0: michael@0: /** Get a graphic state that only unsets the soft mask. The reference michael@0: * count of the object is incremented and it is the caller's responsibility michael@0: * to unreference it when done. This is needed to accommodate the weak michael@0: * reference pattern used when the returned object is new and has no michael@0: * other references. michael@0: */ michael@0: static SkPDFGraphicState* GetNoSMaskGraphicState(); michael@0: michael@0: private: michael@0: const SkPaint fPaint; michael@0: SkTDArray fResources; michael@0: bool fPopulated; michael@0: bool fSMask; michael@0: michael@0: class GSCanonicalEntry { michael@0: public: michael@0: SkPDFGraphicState* fGraphicState; michael@0: const SkPaint* fPaint; michael@0: michael@0: bool operator==(const GSCanonicalEntry& b) const; michael@0: explicit GSCanonicalEntry(SkPDFGraphicState* gs) michael@0: : fGraphicState(gs), michael@0: fPaint(&gs->fPaint) {} michael@0: explicit GSCanonicalEntry(const SkPaint* paint) michael@0: : fGraphicState(NULL), michael@0: fPaint(paint) {} michael@0: }; michael@0: michael@0: // This should be made a hash table if performance is a problem. michael@0: static SkTDArray& CanonicalPaints(); michael@0: static SkBaseMutex& CanonicalPaintsMutex(); michael@0: michael@0: SkPDFGraphicState(); michael@0: explicit SkPDFGraphicState(const SkPaint& paint); michael@0: michael@0: void populateDict(); michael@0: michael@0: static SkPDFObject* GetInvertFunction(); michael@0: michael@0: static int Find(const SkPaint& paint); michael@0: typedef SkPDFDict INHERITED; michael@0: }; michael@0: michael@0: #endif