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 
      8 #include "SkImage.h"
      9 #include "SkPDFBitmap.h"
     10 #include "SkPDFCanon.h"
     11 #include "SkPDFFont.h"
     12 
     13 ////////////////////////////////////////////////////////////////////////////////
     14 
     15 namespace {
     16 template <typename K, typename V> struct UnrefValue {
     17     void operator()(K, V** v) { SkSafeUnref(*v); }
     18 };
     19 }
     20 
     21 SkPDFCanon::~SkPDFCanon() {
     22     // TODO(halcanary): make SkTHashSet work nicely with sk_sp<>,
     23     // or use std::unordered_set<>
     24     fGraphicStateRecords.foreach ([](WrapGS w) { w.fPtr->unref(); });
     25     fPDFBitmapMap.foreach(UnrefValue<SkBitmapKey, SkPDFObject>());
     26     fTypefaceMetrics.foreach(UnrefValue<uint32_t, SkAdvancedTypefaceMetrics>());
     27     fFontDescriptors.foreach(UnrefValue<uint32_t, SkPDFDict>());
     28     fFontMap.foreach(UnrefValue<uint64_t, SkPDFFont>());
     29 }
     30 
     31 void SkPDFCanon::reset() {
     32     this->~SkPDFCanon();
     33     new (this)SkPDFCanon;
     34 }
     35 
     36 ////////////////////////////////////////////////////////////////////////////////
     37 
     38 template <typename T>
     39 sk_sp<SkPDFObject> find_shader(const SkTArray<T>& records,
     40                                const SkPDFShader::State& state) {
     41     for (const T& record : records) {
     42         if (record.fShaderState == state) {
     43             return record.fShaderObject;
     44         }
     45     }
     46     return nullptr;
     47 }
     48 
     49 sk_sp<SkPDFObject> SkPDFCanon::findFunctionShader(
     50         const SkPDFShader::State& state) const {
     51     return find_shader(fFunctionShaderRecords, state);
     52 }
     53 void SkPDFCanon::addFunctionShader(sk_sp<SkPDFObject> pdfShader,
     54                                    SkPDFShader::State state) {
     55     fFunctionShaderRecords.emplace_back(std::move(state), std::move(pdfShader));
     56 }
     57 
     58 sk_sp<SkPDFObject> SkPDFCanon::findAlphaShader(
     59         const SkPDFShader::State& state) const {
     60     return find_shader(fAlphaShaderRecords, state);
     61 }
     62 void SkPDFCanon::addAlphaShader(sk_sp<SkPDFObject> pdfShader,
     63                                 SkPDFShader::State state) {
     64     fAlphaShaderRecords.emplace_back(std::move(state), std::move(pdfShader));
     65 }
     66 
     67 sk_sp<SkPDFObject> SkPDFCanon::findImageShader(
     68         const SkPDFShader::State& state) const {
     69     return find_shader(fImageShaderRecords, state);
     70 }
     71 
     72 void SkPDFCanon::addImageShader(sk_sp<SkPDFObject> pdfShader,
     73                                 SkPDFShader::State state) {
     74     fImageShaderRecords.emplace_back(std::move(state), std::move(pdfShader));
     75 }
     76 
     77 ////////////////////////////////////////////////////////////////////////////////
     78 
     79 const SkPDFGraphicState* SkPDFCanon::findGraphicState(
     80         const SkPDFGraphicState& key) const {
     81     const WrapGS* ptr = fGraphicStateRecords.find(WrapGS(&key));
     82     return ptr ? ptr->fPtr : nullptr;
     83 }
     84 
     85 void SkPDFCanon::addGraphicState(const SkPDFGraphicState* state) {
     86     SkASSERT(state);
     87     WrapGS w(SkRef(state));
     88     SkASSERT(!fGraphicStateRecords.contains(w));
     89     fGraphicStateRecords.add(w);
     90 }
     91 
     92 ////////////////////////////////////////////////////////////////////////////////
     93 
     94 sk_sp<SkPDFObject> SkPDFCanon::findPDFBitmap(SkBitmapKey key) const {
     95     SkPDFObject** ptr = fPDFBitmapMap.find(key);
     96     return ptr ? sk_ref_sp(*ptr) : sk_sp<SkPDFObject>();
     97 }
     98 
     99 void SkPDFCanon::addPDFBitmap(SkBitmapKey key, sk_sp<SkPDFObject> pdfBitmap) {
    100     fPDFBitmapMap.set(key, pdfBitmap.release());
    101 }
    102 
    103 ////////////////////////////////////////////////////////////////////////////////
    104 
    105 sk_sp<SkPDFStream> SkPDFCanon::makeInvertFunction() {
    106     if (fInvertFunction) {
    107         return fInvertFunction;
    108     }
    109     fInvertFunction = SkPDFGraphicState::MakeInvertFunction();
    110     return fInvertFunction;
    111 }
    112 sk_sp<SkPDFDict> SkPDFCanon::makeNoSmaskGraphicState() {
    113     if (fNoSmaskGraphicState) {
    114         return fNoSmaskGraphicState;
    115     }
    116     fNoSmaskGraphicState = SkPDFGraphicState::MakeNoSmaskGraphicState();
    117     return fNoSmaskGraphicState;
    118 }
    119 sk_sp<SkPDFArray> SkPDFCanon::makeRangeObject() {
    120     if (fRangeObject) {
    121         return fRangeObject;
    122     }
    123     fRangeObject = SkPDFShader::MakeRangeObject();
    124     return fRangeObject;
    125 }
    126