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 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 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> 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 49 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 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 78 SkPDFFunctionShader* SkPDFCanon::findFunctionShader( 79 const SkPDFShader::State& state) const { 80 return find_item(fFunctionShaderRecords, state); 81 } 82 void SkPDFCanon::addFunctionShader(SkPDFFunctionShader* pdfShader) { 83 fFunctionShaderRecords.push(SkRef(pdfShader)); 84 } 85 86 //////////////////////////////////////////////////////////////////////////////// 87 88 SkPDFAlphaFunctionShader* SkPDFCanon::findAlphaShader( 89 const SkPDFShader::State& state) const { 90 return find_item(fAlphaShaderRecords, state); 91 } 92 void SkPDFCanon::addAlphaShader(SkPDFAlphaFunctionShader* pdfShader) { 93 fAlphaShaderRecords.push(SkRef(pdfShader)); 94 } 95 96 //////////////////////////////////////////////////////////////////////////////// 97 98 SkPDFImageShader* SkPDFCanon::findImageShader( 99 const SkPDFShader::State& state) const { 100 return find_item(fImageShaderRecords, state); 101 } 102 103 void SkPDFCanon::addImageShader(SkPDFImageShader* pdfShader) { 104 fImageShaderRecords.push(SkRef(pdfShader)); 105 } 106 107 //////////////////////////////////////////////////////////////////////////////// 108 109 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 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 124 SkPDFBitmap* SkPDFCanon::findBitmap(const SkBitmap& bm) const { 125 return find_item(fBitmapRecords, bm); 126 } 127 128 void SkPDFCanon::addBitmap(SkPDFBitmap* pdfBitmap) { 129 fBitmapRecords.push(SkRef(pdfBitmap)); 130 } 131