blob: 4fdaa0db628cf14b27fd4e26b966a913e5a7ead2 [file] [log] [blame]
halcanaryfb62b3d2015-01-21 09:59:14 -08001/*
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
halcanary7a14b312015-10-01 07:28:13 -07008#include "SkImage.h"
halcanary1b5c6042015-02-18 11:29:56 -08009#include "SkPDFBitmap.h"
halcanaryfb62b3d2015-01-21 09:59:14 -080010#include "SkPDFCanon.h"
11#include "SkPDFFont.h"
halcanaryfb62b3d2015-01-21 09:59:14 -080012#include "SkPDFShader.h"
13
14////////////////////////////////////////////////////////////////////////////////
15
halcanary2e3f9d82015-02-27 12:41:03 -080016void 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();
halcanarybe27a112015-04-01 13:31:19 -070027 fGraphicStateRecords.foreach ([](WrapGS w) { w.fPtr->unref(); });
halcanary2e3f9d82015-02-27 12:41:03 -080028 fGraphicStateRecords.reset();
halcanary7a14b312015-10-01 07:28:13 -070029
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();
halcanary2e3f9d82015-02-27 12:41:03 -080036}
halcanaryfb62b3d2015-01-21 09:59:14 -080037
halcanaryfb62b3d2015-01-21 09:59:14 -080038////////////////////////////////////////////////////////////////////////////////
39
halcanary530ea8e2015-01-23 06:17:35 -080040template <class T> T* assert_ptr(T* p) { SkASSERT(p); return p; }
41
halcanary530ea8e2015-01-23 06:17:35 -080042// requires `bool T::equals(const U&) const`
43template <typename T, typename U>
44T* 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 }
halcanary96fcdcc2015-08-27 07:41:13 -070050 return nullptr;
halcanary530ea8e2015-01-23 06:17:35 -080051}
52
53////////////////////////////////////////////////////////////////////////////////
54
halcanaryfb62b3d2015-01-21 09:59:14 -080055SkPDFFont* SkPDFCanon::findFont(uint32_t fontID,
56 uint16_t glyphID,
57 SkPDFFont** relatedFontPtr) const {
halcanaryfb62b3d2015-01-21 09:59:14 -080058 SkASSERT(relatedFontPtr);
59
halcanary96fcdcc2015-08-27 07:41:13 -070060 SkPDFFont* relatedFont = nullptr;
halcanaryfb62b3d2015-01-21 09:59:14 -080061 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 }
halcanary96fcdcc2015-08-27 07:41:13 -070071 *relatedFontPtr = relatedFont; // May still be nullptr.
72 return nullptr;
halcanaryfb62b3d2015-01-21 09:59:14 -080073}
74
75void SkPDFCanon::addFont(SkPDFFont* font, uint32_t fontID, uint16_t fGlyphID) {
halcanaryfb62b3d2015-01-21 09:59:14 -080076 SkPDFCanon::FontRec* rec = fFontRecords.push();
halcanary2e3f9d82015-02-27 12:41:03 -080077 rec->fFont = SkRef(font);
halcanaryfb62b3d2015-01-21 09:59:14 -080078 rec->fFontID = fontID;
79 rec->fGlyphID = fGlyphID;
80}
81
halcanaryfb62b3d2015-01-21 09:59:14 -080082////////////////////////////////////////////////////////////////////////////////
83
halcanary530ea8e2015-01-23 06:17:35 -080084SkPDFFunctionShader* SkPDFCanon::findFunctionShader(
85 const SkPDFShader::State& state) const {
halcanary530ea8e2015-01-23 06:17:35 -080086 return find_item(fFunctionShaderRecords, state);
87}
88void SkPDFCanon::addFunctionShader(SkPDFFunctionShader* pdfShader) {
halcanary2e3f9d82015-02-27 12:41:03 -080089 fFunctionShaderRecords.push(SkRef(pdfShader));
halcanaryfb62b3d2015-01-21 09:59:14 -080090}
91
halcanary530ea8e2015-01-23 06:17:35 -080092////////////////////////////////////////////////////////////////////////////////
93
94SkPDFAlphaFunctionShader* SkPDFCanon::findAlphaShader(
95 const SkPDFShader::State& state) const {
halcanary530ea8e2015-01-23 06:17:35 -080096 return find_item(fAlphaShaderRecords, state);
97}
98void SkPDFCanon::addAlphaShader(SkPDFAlphaFunctionShader* pdfShader) {
halcanary2e3f9d82015-02-27 12:41:03 -080099 fAlphaShaderRecords.push(SkRef(pdfShader));
halcanaryfb62b3d2015-01-21 09:59:14 -0800100}
101
halcanary530ea8e2015-01-23 06:17:35 -0800102////////////////////////////////////////////////////////////////////////////////
103
104SkPDFImageShader* SkPDFCanon::findImageShader(
105 const SkPDFShader::State& state) const {
halcanary530ea8e2015-01-23 06:17:35 -0800106 return find_item(fImageShaderRecords, state);
107}
108
109void SkPDFCanon::addImageShader(SkPDFImageShader* pdfShader) {
halcanary2e3f9d82015-02-27 12:41:03 -0800110 fImageShaderRecords.push(SkRef(pdfShader));
halcanaryfb62b3d2015-01-21 09:59:14 -0800111}
112
113////////////////////////////////////////////////////////////////////////////////
114
halcanarybe27a112015-04-01 13:31:19 -0700115const SkPDFGraphicState* SkPDFCanon::findGraphicState(
116 const SkPDFGraphicState& key) const {
117 const WrapGS* ptr = fGraphicStateRecords.find(WrapGS(&key));
halcanary96fcdcc2015-08-27 07:41:13 -0700118 return ptr ? ptr->fPtr : nullptr;
halcanaryfb62b3d2015-01-21 09:59:14 -0800119}
120
halcanarybe27a112015-04-01 13:31:19 -0700121void SkPDFCanon::addGraphicState(const SkPDFGraphicState* state) {
122 SkASSERT(state);
123 WrapGS w(SkRef(state));
124 SkASSERT(!fGraphicStateRecords.contains(w));
125 fGraphicStateRecords.add(w);
halcanaryfb62b3d2015-01-21 09:59:14 -0800126}
halcanary1b5c6042015-02-18 11:29:56 -0800127
128////////////////////////////////////////////////////////////////////////////////
129
halcanary7a14b312015-10-01 07:28:13 -0700130SkPDFObject* SkPDFCanon::findPDFBitmap(const SkImage* image) const {
131 SkPDFObject** ptr = fPDFBitmapMap.find(image->uniqueID());
132 return ptr ? *ptr : nullptr;
halcanary1b5c6042015-02-18 11:29:56 -0800133}
134
halcanary7a14b312015-10-01 07:28:13 -0700135void SkPDFCanon::addPDFBitmap(uint32_t imageUniqueID, SkPDFObject* pdfBitmap) {
136 fPDFBitmapMap.set(imageUniqueID, SkRef(pdfBitmap));
137}
138
139const 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));
halcanary1b5c6042015-02-18 11:29:56 -0800151}