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 15void 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 34template <class T> T* assert_ptr(T* p) { SkASSERT(p); return p; } 35 36// requires `bool T::equals(const U&) const` 37template <typename T, typename U> 38T* 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 49SkPDFFont* 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 69void 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 78SkPDFFunctionShader* SkPDFCanon::findFunctionShader( 79 const SkPDFShader::State& state) const { 80 return find_item(fFunctionShaderRecords, state); 81} 82void SkPDFCanon::addFunctionShader(SkPDFFunctionShader* pdfShader) { 83 fFunctionShaderRecords.push(SkRef(pdfShader)); 84} 85 86//////////////////////////////////////////////////////////////////////////////// 87 88SkPDFAlphaFunctionShader* SkPDFCanon::findAlphaShader( 89 const SkPDFShader::State& state) const { 90 return find_item(fAlphaShaderRecords, state); 91} 92void SkPDFCanon::addAlphaShader(SkPDFAlphaFunctionShader* pdfShader) { 93 fAlphaShaderRecords.push(SkRef(pdfShader)); 94} 95 96//////////////////////////////////////////////////////////////////////////////// 97 98SkPDFImageShader* SkPDFCanon::findImageShader( 99 const SkPDFShader::State& state) const { 100 return find_item(fImageShaderRecords, state); 101} 102 103void SkPDFCanon::addImageShader(SkPDFImageShader* pdfShader) { 104 fImageShaderRecords.push(SkRef(pdfShader)); 105} 106 107//////////////////////////////////////////////////////////////////////////////// 108 109const SkPDFGraphicState* SkPDFCanon::findGraphicState( 110 const SkPDFGraphicState& key) const { 111 const WrapGS* ptr = fGraphicStateRecords.find(WrapGS(&key)); 112 return ptr ? ptr->fPtr : NULL; 113} 114 115void 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 124SkPDFBitmap* SkPDFCanon::findBitmap(const SkBitmap& bm) const { 125 return find_item(fBitmapRecords, bm); 126} 127 128void SkPDFCanon::addBitmap(SkPDFBitmap* pdfBitmap) { 129 fBitmapRecords.push(SkRef(pdfBitmap)); 130} 131