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 "SkPDFBitmap.h"
9 #include "SkPDFCanon.h"
10 #include "SkPDFFont.h"
11 #include "SkPDFShader.h"
12
13 ////////////////////////////////////////////////////////////////////////////////
14
reset()15 void SkPDFCanon::reset() {
16 for (int i = 0; i < fFontRecords.count(); ++i) {
17 fFontRecords[i].fFont->unref();
18 }
19 fFontRecords.reset();
20 fFunctionShaderRecords.unrefAll();
21 fFunctionShaderRecords.reset();
22 fAlphaShaderRecords.unrefAll();
23 fAlphaShaderRecords.reset();
24 fImageShaderRecords.unrefAll();
25 fImageShaderRecords.reset();
26 fGraphicStateRecords.foreach ([](WrapGS w) { w.fPtr->unref(); });
27 fGraphicStateRecords.reset();
28 fBitmapRecords.unrefAll();
29 fBitmapRecords.reset();
30 }
31
32 ////////////////////////////////////////////////////////////////////////////////
33
assert_ptr(T * p)34 template <class T> T* assert_ptr(T* p) { SkASSERT(p); return p; }
35
36 // requires `bool T::equals(const U&) const`
37 template <typename T, typename U>
find_item(const SkTDArray<T * > & ptrArray,const U & object)38 T* find_item(const SkTDArray<T*>& ptrArray, const U& object) {
39 for (int i = 0; i < ptrArray.count(); ++i) {
40 if (ptrArray[i]->equals(object)) {
41 return ptrArray[i];
42 }
43 }
44 return NULL;
45 }
46
47 ////////////////////////////////////////////////////////////////////////////////
48
findFont(uint32_t fontID,uint16_t glyphID,SkPDFFont ** relatedFontPtr) const49 SkPDFFont* SkPDFCanon::findFont(uint32_t fontID,
50 uint16_t glyphID,
51 SkPDFFont** relatedFontPtr) const {
52 SkASSERT(relatedFontPtr);
53
54 SkPDFFont* relatedFont = NULL;
55 for (int i = 0; i < fFontRecords.count(); ++i) {
56 SkPDFFont::Match match = SkPDFFont::IsMatch(
57 fFontRecords[i].fFont, fFontRecords[i].fFontID,
58 fFontRecords[i].fGlyphID, fontID, glyphID);
59 if (SkPDFFont::kExact_Match == match) {
60 return fFontRecords[i].fFont;
61 } else if (!relatedFont && SkPDFFont::kRelated_Match == match) {
62 relatedFont = fFontRecords[i].fFont;
63 }
64 }
65 *relatedFontPtr = relatedFont; // May still be NULL.
66 return NULL;
67 }
68
addFont(SkPDFFont * font,uint32_t fontID,uint16_t fGlyphID)69 void SkPDFCanon::addFont(SkPDFFont* font, uint32_t fontID, uint16_t fGlyphID) {
70 SkPDFCanon::FontRec* rec = fFontRecords.push();
71 rec->fFont = SkRef(font);
72 rec->fFontID = fontID;
73 rec->fGlyphID = fGlyphID;
74 }
75
76 ////////////////////////////////////////////////////////////////////////////////
77
findFunctionShader(const SkPDFShader::State & state) const78 SkPDFFunctionShader* SkPDFCanon::findFunctionShader(
79 const SkPDFShader::State& state) const {
80 return find_item(fFunctionShaderRecords, state);
81 }
addFunctionShader(SkPDFFunctionShader * pdfShader)82 void SkPDFCanon::addFunctionShader(SkPDFFunctionShader* pdfShader) {
83 fFunctionShaderRecords.push(SkRef(pdfShader));
84 }
85
86 ////////////////////////////////////////////////////////////////////////////////
87
findAlphaShader(const SkPDFShader::State & state) const88 SkPDFAlphaFunctionShader* SkPDFCanon::findAlphaShader(
89 const SkPDFShader::State& state) const {
90 return find_item(fAlphaShaderRecords, state);
91 }
addAlphaShader(SkPDFAlphaFunctionShader * pdfShader)92 void SkPDFCanon::addAlphaShader(SkPDFAlphaFunctionShader* pdfShader) {
93 fAlphaShaderRecords.push(SkRef(pdfShader));
94 }
95
96 ////////////////////////////////////////////////////////////////////////////////
97
findImageShader(const SkPDFShader::State & state) const98 SkPDFImageShader* SkPDFCanon::findImageShader(
99 const SkPDFShader::State& state) const {
100 return find_item(fImageShaderRecords, state);
101 }
102
addImageShader(SkPDFImageShader * pdfShader)103 void SkPDFCanon::addImageShader(SkPDFImageShader* pdfShader) {
104 fImageShaderRecords.push(SkRef(pdfShader));
105 }
106
107 ////////////////////////////////////////////////////////////////////////////////
108
findGraphicState(const SkPDFGraphicState & key) const109 const SkPDFGraphicState* SkPDFCanon::findGraphicState(
110 const SkPDFGraphicState& key) const {
111 const WrapGS* ptr = fGraphicStateRecords.find(WrapGS(&key));
112 return ptr ? ptr->fPtr : NULL;
113 }
114
addGraphicState(const SkPDFGraphicState * state)115 void SkPDFCanon::addGraphicState(const SkPDFGraphicState* state) {
116 SkASSERT(state);
117 WrapGS w(SkRef(state));
118 SkASSERT(!fGraphicStateRecords.contains(w));
119 fGraphicStateRecords.add(w);
120 }
121
122 ////////////////////////////////////////////////////////////////////////////////
123
findBitmap(const SkBitmap & bm) const124 SkPDFBitmap* SkPDFCanon::findBitmap(const SkBitmap& bm) const {
125 return find_item(fBitmapRecords, bm);
126 }
127
addBitmap(SkPDFBitmap * pdfBitmap)128 void SkPDFCanon::addBitmap(SkPDFBitmap* pdfBitmap) {
129 fBitmapRecords.push(SkRef(pdfBitmap));
130 }
131