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