halcanary | fb62b3d | 2015-01-21 09:59:14 -0800 | [diff] [blame] | 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 | |
halcanary | 7a14b31 | 2015-10-01 07:28:13 -0700 | [diff] [blame] | 8 | #include "SkImage.h" |
halcanary | 1b5c604 | 2015-02-18 11:29:56 -0800 | [diff] [blame] | 9 | #include "SkPDFBitmap.h" |
halcanary | fb62b3d | 2015-01-21 09:59:14 -0800 | [diff] [blame] | 10 | #include "SkPDFCanon.h" |
| 11 | #include "SkPDFFont.h" |
halcanary | fb62b3d | 2015-01-21 09:59:14 -0800 | [diff] [blame] | 12 | #include "SkPDFShader.h" |
| 13 | |
| 14 | //////////////////////////////////////////////////////////////////////////////// |
| 15 | |
halcanary | 2e3f9d8 | 2015-02-27 12:41:03 -0800 | [diff] [blame] | 16 | void SkPDFCanon::reset() { |
| 17 | for (int i = 0; i < fFontRecords.count(); ++i) { |
| 18 | fFontRecords[i].fFont->unref(); |
| 19 | } |
| 20 | fFontRecords.reset(); |
| 21 | fFunctionShaderRecords.unrefAll(); |
| 22 | fFunctionShaderRecords.reset(); |
| 23 | fAlphaShaderRecords.unrefAll(); |
| 24 | fAlphaShaderRecords.reset(); |
| 25 | fImageShaderRecords.unrefAll(); |
| 26 | fImageShaderRecords.reset(); |
halcanary | be27a11 | 2015-04-01 13:31:19 -0700 | [diff] [blame] | 27 | fGraphicStateRecords.foreach ([](WrapGS w) { w.fPtr->unref(); }); |
halcanary | 2e3f9d8 | 2015-02-27 12:41:03 -0800 | [diff] [blame] | 28 | fGraphicStateRecords.reset(); |
halcanary | 7a14b31 | 2015-10-01 07:28:13 -0700 | [diff] [blame] | 29 | |
| 30 | fBitmapToImageMap.foreach( |
| 31 | [](SkBitmapKey, const SkImage** p) { SkSafeUnref(*p); }); |
| 32 | fBitmapToImageMap.reset(); |
| 33 | |
| 34 | fPDFBitmapMap.foreach([](uint32_t, SkPDFObject** p) { SkSafeUnref(*p); }); |
| 35 | fPDFBitmapMap.reset(); |
halcanary | 2e3f9d8 | 2015-02-27 12:41:03 -0800 | [diff] [blame] | 36 | } |
halcanary | fb62b3d | 2015-01-21 09:59:14 -0800 | [diff] [blame] | 37 | |
halcanary | fb62b3d | 2015-01-21 09:59:14 -0800 | [diff] [blame] | 38 | //////////////////////////////////////////////////////////////////////////////// |
| 39 | |
halcanary | 530ea8e | 2015-01-23 06:17:35 -0800 | [diff] [blame] | 40 | template <class T> T* assert_ptr(T* p) { SkASSERT(p); return p; } |
| 41 | |
halcanary | 530ea8e | 2015-01-23 06:17:35 -0800 | [diff] [blame] | 42 | // requires `bool T::equals(const U&) const` |
| 43 | template <typename T, typename U> |
| 44 | T* find_item(const SkTDArray<T*>& ptrArray, const U& object) { |
| 45 | for (int i = 0; i < ptrArray.count(); ++i) { |
| 46 | if (ptrArray[i]->equals(object)) { |
| 47 | return ptrArray[i]; |
| 48 | } |
| 49 | } |
halcanary | 96fcdcc | 2015-08-27 07:41:13 -0700 | [diff] [blame] | 50 | return nullptr; |
halcanary | 530ea8e | 2015-01-23 06:17:35 -0800 | [diff] [blame] | 51 | } |
| 52 | |
| 53 | //////////////////////////////////////////////////////////////////////////////// |
| 54 | |
halcanary | fb62b3d | 2015-01-21 09:59:14 -0800 | [diff] [blame] | 55 | SkPDFFont* SkPDFCanon::findFont(uint32_t fontID, |
| 56 | uint16_t glyphID, |
| 57 | SkPDFFont** relatedFontPtr) const { |
halcanary | fb62b3d | 2015-01-21 09:59:14 -0800 | [diff] [blame] | 58 | SkASSERT(relatedFontPtr); |
| 59 | |
halcanary | 96fcdcc | 2015-08-27 07:41:13 -0700 | [diff] [blame] | 60 | SkPDFFont* relatedFont = nullptr; |
halcanary | fb62b3d | 2015-01-21 09:59:14 -0800 | [diff] [blame] | 61 | for (int i = 0; i < fFontRecords.count(); ++i) { |
| 62 | SkPDFFont::Match match = SkPDFFont::IsMatch( |
| 63 | fFontRecords[i].fFont, fFontRecords[i].fFontID, |
| 64 | fFontRecords[i].fGlyphID, fontID, glyphID); |
| 65 | if (SkPDFFont::kExact_Match == match) { |
| 66 | return fFontRecords[i].fFont; |
| 67 | } else if (!relatedFont && SkPDFFont::kRelated_Match == match) { |
| 68 | relatedFont = fFontRecords[i].fFont; |
| 69 | } |
| 70 | } |
halcanary | 96fcdcc | 2015-08-27 07:41:13 -0700 | [diff] [blame] | 71 | *relatedFontPtr = relatedFont; // May still be nullptr. |
| 72 | return nullptr; |
halcanary | fb62b3d | 2015-01-21 09:59:14 -0800 | [diff] [blame] | 73 | } |
| 74 | |
| 75 | void SkPDFCanon::addFont(SkPDFFont* font, uint32_t fontID, uint16_t fGlyphID) { |
halcanary | fb62b3d | 2015-01-21 09:59:14 -0800 | [diff] [blame] | 76 | SkPDFCanon::FontRec* rec = fFontRecords.push(); |
halcanary | 2e3f9d8 | 2015-02-27 12:41:03 -0800 | [diff] [blame] | 77 | rec->fFont = SkRef(font); |
halcanary | fb62b3d | 2015-01-21 09:59:14 -0800 | [diff] [blame] | 78 | rec->fFontID = fontID; |
| 79 | rec->fGlyphID = fGlyphID; |
| 80 | } |
| 81 | |
halcanary | fb62b3d | 2015-01-21 09:59:14 -0800 | [diff] [blame] | 82 | //////////////////////////////////////////////////////////////////////////////// |
| 83 | |
halcanary | 530ea8e | 2015-01-23 06:17:35 -0800 | [diff] [blame] | 84 | SkPDFFunctionShader* SkPDFCanon::findFunctionShader( |
| 85 | const SkPDFShader::State& state) const { |
halcanary | 530ea8e | 2015-01-23 06:17:35 -0800 | [diff] [blame] | 86 | return find_item(fFunctionShaderRecords, state); |
| 87 | } |
| 88 | void SkPDFCanon::addFunctionShader(SkPDFFunctionShader* pdfShader) { |
halcanary | 2e3f9d8 | 2015-02-27 12:41:03 -0800 | [diff] [blame] | 89 | fFunctionShaderRecords.push(SkRef(pdfShader)); |
halcanary | fb62b3d | 2015-01-21 09:59:14 -0800 | [diff] [blame] | 90 | } |
| 91 | |
halcanary | 530ea8e | 2015-01-23 06:17:35 -0800 | [diff] [blame] | 92 | //////////////////////////////////////////////////////////////////////////////// |
| 93 | |
| 94 | SkPDFAlphaFunctionShader* SkPDFCanon::findAlphaShader( |
| 95 | const SkPDFShader::State& state) const { |
halcanary | 530ea8e | 2015-01-23 06:17:35 -0800 | [diff] [blame] | 96 | return find_item(fAlphaShaderRecords, state); |
| 97 | } |
| 98 | void SkPDFCanon::addAlphaShader(SkPDFAlphaFunctionShader* pdfShader) { |
halcanary | 2e3f9d8 | 2015-02-27 12:41:03 -0800 | [diff] [blame] | 99 | fAlphaShaderRecords.push(SkRef(pdfShader)); |
halcanary | fb62b3d | 2015-01-21 09:59:14 -0800 | [diff] [blame] | 100 | } |
| 101 | |
halcanary | 530ea8e | 2015-01-23 06:17:35 -0800 | [diff] [blame] | 102 | //////////////////////////////////////////////////////////////////////////////// |
| 103 | |
| 104 | SkPDFImageShader* SkPDFCanon::findImageShader( |
| 105 | const SkPDFShader::State& state) const { |
halcanary | 530ea8e | 2015-01-23 06:17:35 -0800 | [diff] [blame] | 106 | return find_item(fImageShaderRecords, state); |
| 107 | } |
| 108 | |
| 109 | void SkPDFCanon::addImageShader(SkPDFImageShader* pdfShader) { |
halcanary | 2e3f9d8 | 2015-02-27 12:41:03 -0800 | [diff] [blame] | 110 | fImageShaderRecords.push(SkRef(pdfShader)); |
halcanary | fb62b3d | 2015-01-21 09:59:14 -0800 | [diff] [blame] | 111 | } |
| 112 | |
| 113 | //////////////////////////////////////////////////////////////////////////////// |
| 114 | |
halcanary | be27a11 | 2015-04-01 13:31:19 -0700 | [diff] [blame] | 115 | const SkPDFGraphicState* SkPDFCanon::findGraphicState( |
| 116 | const SkPDFGraphicState& key) const { |
| 117 | const WrapGS* ptr = fGraphicStateRecords.find(WrapGS(&key)); |
halcanary | 96fcdcc | 2015-08-27 07:41:13 -0700 | [diff] [blame] | 118 | return ptr ? ptr->fPtr : nullptr; |
halcanary | fb62b3d | 2015-01-21 09:59:14 -0800 | [diff] [blame] | 119 | } |
| 120 | |
halcanary | be27a11 | 2015-04-01 13:31:19 -0700 | [diff] [blame] | 121 | void SkPDFCanon::addGraphicState(const SkPDFGraphicState* state) { |
| 122 | SkASSERT(state); |
| 123 | WrapGS w(SkRef(state)); |
| 124 | SkASSERT(!fGraphicStateRecords.contains(w)); |
| 125 | fGraphicStateRecords.add(w); |
halcanary | fb62b3d | 2015-01-21 09:59:14 -0800 | [diff] [blame] | 126 | } |
halcanary | 1b5c604 | 2015-02-18 11:29:56 -0800 | [diff] [blame] | 127 | |
| 128 | //////////////////////////////////////////////////////////////////////////////// |
| 129 | |
halcanary | 7a14b31 | 2015-10-01 07:28:13 -0700 | [diff] [blame] | 130 | SkPDFObject* SkPDFCanon::findPDFBitmap(const SkImage* image) const { |
| 131 | SkPDFObject** ptr = fPDFBitmapMap.find(image->uniqueID()); |
| 132 | return ptr ? *ptr : nullptr; |
halcanary | 1b5c604 | 2015-02-18 11:29:56 -0800 | [diff] [blame] | 133 | } |
| 134 | |
halcanary | 7a14b31 | 2015-10-01 07:28:13 -0700 | [diff] [blame] | 135 | void SkPDFCanon::addPDFBitmap(uint32_t imageUniqueID, SkPDFObject* pdfBitmap) { |
| 136 | fPDFBitmapMap.set(imageUniqueID, SkRef(pdfBitmap)); |
| 137 | } |
| 138 | |
| 139 | const SkImage* SkPDFCanon::bitmapToImage(const SkBitmap& bm) { |
| 140 | // reference remains owned by the fBitmapToImageMap! |
| 141 | SkBitmapKey key(bm); |
| 142 | if (const SkImage** img = fBitmapToImageMap.find(key)) { |
| 143 | return *img; |
| 144 | } |
| 145 | if (SkImage* image = SkImage::NewFromBitmap(bm)) { |
| 146 | return *fBitmapToImageMap.set(key, image); |
| 147 | } |
| 148 | SkBitmap n32bitmap; // SkImage::NewFromBitmap can be finicky. |
| 149 | bm.copyTo(&n32bitmap, kN32_SkColorType); |
| 150 | return *fBitmapToImageMap.set(key, SkImage::NewFromBitmap(n32bitmap)); |
halcanary | 1b5c604 | 2015-02-18 11:29:56 -0800 | [diff] [blame] | 151 | } |