Home | History | Annotate | Download | only in pdf
      1 /*
      2  * Copyright 2015 Google Inc.
      3  *
      4  * Use of this source code is governed by a BSD-style license that can be
      5  * found in the LICENSE file.
      6  */
      7 #ifndef SkPDFCanon_DEFINED
      8 #define SkPDFCanon_DEFINED
      9 
     10 #include "SkPDFGraphicState.h"
     11 #include "SkPDFShader.h"
     12 #include "SkPixelSerializer.h"
     13 #include "SkTDArray.h"
     14 #include "SkTHash.h"
     15 #include "SkBitmapKey.h"
     16 
     17 class SkAdvancedTypefaceMetrics;
     18 class SkPDFFont;
     19 
     20 /**
     21  *  The SkPDFCanon canonicalizes objects across PDF pages
     22  *  (SkPDFDevices) and across draw calls.
     23  *
     24  *  The PDF backend works correctly if:
     25  *  -  There is no more than one SkPDFCanon for each thread.
     26  *  -  Every SkPDFDevice is given a pointer to a SkPDFCanon on creation.
     27  *  -  All SkPDFDevices in a document share the same SkPDFCanon.
     28  *  The SkPDFDocument class makes this happen by owning a single
     29  *  SkPDFCanon.
     30  *
     31  *  The addFoo() methods will ref the Foo; the canon's destructor will
     32  *  call foo->unref() on all of these objects.
     33  *
     34  *  The findFoo() methods do not change the ref count of the Foo
     35  *  objects.
     36  */
     37 class SkPDFCanon : SkNoncopyable {
     38 public:
     39     ~SkPDFCanon();
     40 
     41     // reset to original setting, unrefs all objects.
     42     void reset();
     43 
     44     sk_sp<SkPDFObject> findFunctionShader(const SkPDFShader::State&) const;
     45     void addFunctionShader(sk_sp<SkPDFObject>, SkPDFShader::State);
     46 
     47     sk_sp<SkPDFObject> findAlphaShader(const SkPDFShader::State&) const;
     48     void addAlphaShader(sk_sp<SkPDFObject>, SkPDFShader::State);
     49 
     50     sk_sp<SkPDFObject> findImageShader(const SkPDFShader::State&) const;
     51     void addImageShader(sk_sp<SkPDFObject>, SkPDFShader::State);
     52 
     53     const SkPDFGraphicState* findGraphicState(const SkPDFGraphicState&) const;
     54     void addGraphicState(const SkPDFGraphicState*);
     55 
     56     sk_sp<SkPDFObject> findPDFBitmap(SkBitmapKey key) const;
     57     void addPDFBitmap(SkBitmapKey key, sk_sp<SkPDFObject>);
     58 
     59     SkTHashMap<uint32_t, SkAdvancedTypefaceMetrics*> fTypefaceMetrics;
     60     SkTHashMap<uint32_t, SkPDFDict*> fFontDescriptors;
     61     SkTHashMap<uint64_t, SkPDFFont*> fFontMap;
     62 
     63     SkPixelSerializer* getPixelSerializer() const { return fPixelSerializer.get(); }
     64     void setPixelSerializer(sk_sp<SkPixelSerializer> ps) {
     65         fPixelSerializer = std::move(ps);
     66     }
     67 
     68     sk_sp<SkPDFStream> makeInvertFunction();
     69     sk_sp<SkPDFDict> makeNoSmaskGraphicState();
     70     sk_sp<SkPDFArray> makeRangeObject();
     71 
     72 private:
     73     struct ShaderRec {
     74         SkPDFShader::State fShaderState;
     75         sk_sp<SkPDFObject> fShaderObject;
     76         ShaderRec(SkPDFShader::State s, sk_sp<SkPDFObject> o)
     77             : fShaderState(std::move(s)), fShaderObject(std::move(o)) {}
     78     };
     79     SkTArray<ShaderRec> fFunctionShaderRecords;
     80     SkTArray<ShaderRec> fAlphaShaderRecords;
     81     SkTArray<ShaderRec> fImageShaderRecords;
     82 
     83     struct WrapGS {
     84         explicit WrapGS(const SkPDFGraphicState* ptr = nullptr) : fPtr(ptr) {}
     85         const SkPDFGraphicState* fPtr;
     86         bool operator==(const WrapGS& rhs) const {
     87             SkASSERT(fPtr);
     88             SkASSERT(rhs.fPtr);
     89             return *fPtr == *rhs.fPtr;
     90         }
     91         struct Hash {
     92             uint32_t operator()(const WrapGS& w) const {
     93                 SkASSERT(w.fPtr);
     94                 return w.fPtr->hash();
     95             }
     96         };
     97     };
     98     SkTHashSet<WrapGS, WrapGS::Hash> fGraphicStateRecords;
     99 
    100     // TODO(halcanary): make SkTHashMap<K, sk_sp<V>> work correctly.
    101     SkTHashMap<SkBitmapKey, SkPDFObject*> fPDFBitmapMap;
    102 
    103     sk_sp<SkPixelSerializer> fPixelSerializer;
    104     sk_sp<SkPDFStream> fInvertFunction;
    105     sk_sp<SkPDFDict> fNoSmaskGraphicState;
    106     sk_sp<SkPDFArray> fRangeObject;
    107 };
    108 #endif  // SkPDFCanon_DEFINED
    109