| /* |
| * Copyright 2015 Google Inc. |
| * |
| * Use of this source code is governed by a BSD-style license that can be |
| * found in the LICENSE file. |
| */ |
| |
| #include "SkImage.h" |
| #include "SkPDFBitmap.h" |
| #include "SkPDFCanon.h" |
| #include "SkPDFFont.h" |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| |
| void SkPDFCanon::reset() { |
| for (int i = 0; i < fFontRecords.count(); ++i) { |
| fFontRecords[i].fFont->unref(); |
| } |
| fFontRecords.reset(); |
| fFunctionShaderRecords.unrefAll(); |
| fFunctionShaderRecords.reset(); |
| fAlphaShaderRecords.unrefAll(); |
| fAlphaShaderRecords.reset(); |
| fImageShaderRecords.unrefAll(); |
| fImageShaderRecords.reset(); |
| fGraphicStateRecords.foreach ([](WrapGS w) { w.fPtr->unref(); }); |
| fGraphicStateRecords.reset(); |
| |
| fPDFBitmapMap.foreach([](SkBitmapKey, SkPDFObject** p) { (*p)->unref(); }); |
| fPDFBitmapMap.reset(); |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| |
| template <class T> T* assert_ptr(T* p) { SkASSERT(p); return p; } |
| |
| // requires `bool T::equals(const U&) const` |
| template <typename T, typename U> |
| T* find_item(const SkTDArray<T*>& ptrArray, const U& object) { |
| for (int i = 0; i < ptrArray.count(); ++i) { |
| if (ptrArray[i]->equals(object)) { |
| return ptrArray[i]; |
| } |
| } |
| return nullptr; |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| |
| SkPDFFont* SkPDFCanon::findFont(uint32_t fontID, |
| uint16_t glyphID, |
| SkPDFFont** relatedFontPtr) const { |
| SkASSERT(relatedFontPtr); |
| |
| SkPDFFont* relatedFont = nullptr; |
| for (int i = 0; i < fFontRecords.count(); ++i) { |
| SkPDFFont::Match match = SkPDFFont::IsMatch( |
| fFontRecords[i].fFont, fFontRecords[i].fFontID, |
| fFontRecords[i].fGlyphID, fontID, glyphID); |
| if (SkPDFFont::kExact_Match == match) { |
| return fFontRecords[i].fFont; |
| } else if (!relatedFont && SkPDFFont::kRelated_Match == match) { |
| relatedFont = fFontRecords[i].fFont; |
| } |
| } |
| *relatedFontPtr = relatedFont; // May still be nullptr. |
| return nullptr; |
| } |
| |
| void SkPDFCanon::addFont(SkPDFFont* font, uint32_t fontID, uint16_t fGlyphID) { |
| SkPDFCanon::FontRec* rec = fFontRecords.push(); |
| rec->fFont = SkRef(font); |
| rec->fFontID = fontID; |
| rec->fGlyphID = fGlyphID; |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| |
| SkPDFFunctionShader* SkPDFCanon::findFunctionShader( |
| const SkPDFShader::State& state) const { |
| return find_item(fFunctionShaderRecords, state); |
| } |
| void SkPDFCanon::addFunctionShader(SkPDFFunctionShader* pdfShader) { |
| fFunctionShaderRecords.push(SkRef(pdfShader)); |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| |
| SkPDFAlphaFunctionShader* SkPDFCanon::findAlphaShader( |
| const SkPDFShader::State& state) const { |
| return find_item(fAlphaShaderRecords, state); |
| } |
| void SkPDFCanon::addAlphaShader(SkPDFAlphaFunctionShader* pdfShader) { |
| fAlphaShaderRecords.push(SkRef(pdfShader)); |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| |
| SkPDFImageShader* SkPDFCanon::findImageShader( |
| const SkPDFShader::State& state) const { |
| return find_item(fImageShaderRecords, state); |
| } |
| |
| void SkPDFCanon::addImageShader(SkPDFImageShader* pdfShader) { |
| fImageShaderRecords.push(SkRef(pdfShader)); |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| |
| const SkPDFGraphicState* SkPDFCanon::findGraphicState( |
| const SkPDFGraphicState& key) const { |
| const WrapGS* ptr = fGraphicStateRecords.find(WrapGS(&key)); |
| return ptr ? ptr->fPtr : nullptr; |
| } |
| |
| void SkPDFCanon::addGraphicState(const SkPDFGraphicState* state) { |
| SkASSERT(state); |
| WrapGS w(SkRef(state)); |
| SkASSERT(!fGraphicStateRecords.contains(w)); |
| fGraphicStateRecords.add(w); |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| |
| sk_sp<SkPDFObject> SkPDFCanon::findPDFBitmap(SkBitmapKey key) const { |
| SkPDFObject** ptr = fPDFBitmapMap.find(key); |
| return ptr ? sk_ref_sp(*ptr) : sk_sp<SkPDFObject>(); |
| } |
| |
| void SkPDFCanon::addPDFBitmap(SkBitmapKey key, sk_sp<SkPDFObject> pdfBitmap) { |
| fPDFBitmapMap.set(key, pdfBitmap.release()); |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| |
| sk_sp<SkPDFStream> SkPDFCanon::makeInvertFunction() { |
| if (fInvertFunction) { |
| return fInvertFunction; |
| } |
| fInvertFunction = SkPDFGraphicState::MakeInvertFunction(); |
| return fInvertFunction; |
| } |
| sk_sp<SkPDFDict> SkPDFCanon::makeNoSmaskGraphicState() { |
| if (fNoSmaskGraphicState) { |
| return fNoSmaskGraphicState; |
| } |
| fNoSmaskGraphicState = SkPDFGraphicState::MakeNoSmaskGraphicState(); |
| return fNoSmaskGraphicState; |
| } |
| sk_sp<SkPDFArray> SkPDFCanon::makeRangeObject() { |
| if (fRangeObject) { |
| return fRangeObject; |
| } |
| fRangeObject = SkPDFShader::MakeRangeObject(); |
| return fRangeObject; |
| } |