blob: d32fd626043d5a2ac4d9654d1539378a377e8185 [file] [log] [blame]
joshualittaa2f6582015-07-29 10:14:58 -07001/*
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
Hal Canary209e4b12017-05-04 14:23:55 -04008#include "SkAdvancedTypefaceMetrics.h"
Florin Malitaab244f02017-05-03 19:16:58 +00009#include "SkBitmap.h"
joshualittaa2f6582015-07-29 10:14:58 -070010#include "SkCanvas.h"
bungeman7cfd46a2016-10-20 16:06:52 -040011#include "SkGlyph.h"
12#include "SkMakeUnique.h"
13#include "SkPath.h"
14#include "SkRandomScalerContext.h"
Mike Reed1f275852018-04-11 14:30:17 -040015#include "SkRectPriv.h"
joshualittaa2f6582015-07-29 10:14:58 -070016
bungeman7cfd46a2016-10-20 16:06:52 -040017class SkDescriptor;
18
joshualittaa2f6582015-07-29 10:14:58 -070019class SkRandomScalerContext : public SkScalerContext {
20public:
bungeman7cfd46a2016-10-20 16:06:52 -040021 SkRandomScalerContext(sk_sp<SkRandomTypeface>, const SkScalerContextEffects&,
reeda9322c22016-04-12 06:47:05 -070022 const SkDescriptor*, bool fFakeIt);
joshualittaa2f6582015-07-29 10:14:58 -070023
24protected:
25 unsigned generateGlyphCount() override;
26 uint16_t generateCharToGlyph(SkUnichar) override;
27 void generateAdvance(SkGlyph*) override;
28 void generateMetrics(SkGlyph*) override;
29 void generateImage(const SkGlyph&) override;
Ben Wagner5ddb3082018-03-29 11:18:06 -040030 bool generatePath(SkGlyphID, SkPath*) override;
joshualittaa2f6582015-07-29 10:14:58 -070031 void generateFontMetrics(SkPaint::FontMetrics*) override;
32
33private:
bungeman7cfd46a2016-10-20 16:06:52 -040034 SkRandomTypeface* getRandomTypeface() const {
35 return static_cast<SkRandomTypeface*>(this->getTypeface());
36 }
37 std::unique_ptr<SkScalerContext> fProxy;
joshualitt65e96b42015-07-31 11:45:22 -070038 bool fFakeIt;
joshualittaa2f6582015-07-29 10:14:58 -070039};
40
bungeman7cfd46a2016-10-20 16:06:52 -040041SkRandomScalerContext::SkRandomScalerContext(sk_sp<SkRandomTypeface> face,
reeda9322c22016-04-12 06:47:05 -070042 const SkScalerContextEffects& effects,
43 const SkDescriptor* desc,
joshualitt65e96b42015-07-31 11:45:22 -070044 bool fakeIt)
bungeman7cfd46a2016-10-20 16:06:52 -040045 : SkScalerContext(std::move(face), effects, desc)
Ben Wagner20fa1e92018-04-30 15:39:15 -040046 , fProxy(getRandomTypeface()->proxy()->createScalerContext(SkScalerContextEffects(), desc))
47 , fFakeIt(fakeIt)
48{
49 fProxy->forceGenerateImageFromPath();
joshualittaa2f6582015-07-29 10:14:58 -070050}
51
joshualittaa2f6582015-07-29 10:14:58 -070052unsigned SkRandomScalerContext::generateGlyphCount() {
53 return fProxy->getGlyphCount();
54}
55
56uint16_t SkRandomScalerContext::generateCharToGlyph(SkUnichar uni) {
57 return fProxy->charToGlyphID(uni);
58}
59
60void SkRandomScalerContext::generateAdvance(SkGlyph* glyph) {
61 fProxy->getAdvance(glyph);
joshualittaa2f6582015-07-29 10:14:58 -070062}
63
64void SkRandomScalerContext::generateMetrics(SkGlyph* glyph) {
joshualittaa2f6582015-07-29 10:14:58 -070065 // Here we will change the mask format of the glyph
Ben Wagner20fa1e92018-04-30 15:39:15 -040066 // NOTE: this may be overridden by the base class (e.g. if a mask filter is applied).
joshualittd45fb5a2015-08-01 10:33:40 -070067 switch (glyph->getGlyphID() % 4) {
Ben Wagner20fa1e92018-04-30 15:39:15 -040068 case 0: glyph->fMaskFormat = SkMask::kLCD16_Format; break;
69 case 1: glyph->fMaskFormat = SkMask::kA8_Format; break;
70 case 2: glyph->fMaskFormat = SkMask::kARGB32_Format; break;
71 case 3: glyph->fMaskFormat = SkMask::kBW_Format; break;
joshualittaa2f6582015-07-29 10:14:58 -070072 }
73
joshualitt65e96b42015-07-31 11:45:22 -070074 fProxy->getMetrics(glyph);
75
Ben Wagner20fa1e92018-04-30 15:39:15 -040076 if (fFakeIt || (glyph->getGlyphID() % 4) != 2) {
joshualitt65e96b42015-07-31 11:45:22 -070077 return;
78 }
joshualitt65e96b42015-07-31 11:45:22 -070079
Ben Wagner20fa1e92018-04-30 15:39:15 -040080 SkPath path;
81 if (!fProxy->getPath(glyph->getPackedID(), &path)) {
82 return;
joshualitt65e96b42015-07-31 11:45:22 -070083 }
Ben Wagner20fa1e92018-04-30 15:39:15 -040084 glyph->fMaskFormat = SkMask::kARGB32_Format;
85
86 SkRect storage;
87 const SkPaint& paint = this->getRandomTypeface()->paint();
88 const SkRect& newBounds = paint.doComputeFastBounds(path.getBounds(),
89 &storage,
90 SkPaint::kFill_Style);
91 SkIRect ibounds;
92 newBounds.roundOut(&ibounds);
93 glyph->fLeft = ibounds.fLeft;
94 glyph->fTop = ibounds.fTop;
95 glyph->fWidth = ibounds.width();
96 glyph->fHeight = ibounds.height();
joshualittaa2f6582015-07-29 10:14:58 -070097}
98
99void SkRandomScalerContext::generateImage(const SkGlyph& glyph) {
Ben Wagner20fa1e92018-04-30 15:39:15 -0400100 // TODO: can force down but not up
101 /*
joshualittaa2f6582015-07-29 10:14:58 -0700102 SkMask::Format format = (SkMask::Format)glyph.fMaskFormat;
joshualittd45fb5a2015-08-01 10:33:40 -0700103 switch (glyph.getGlyphID() % 4) {
Ben Wagner20fa1e92018-04-30 15:39:15 -0400104 case 0: format = SkMask::kLCD16_Format; break;
105 case 1: format = SkMask::kA8_Format; break;
106 case 2: format = SkMask::kARGB32_Format; break;
107 case 3: format = SkMask::kBW_Format; break;
joshualittaa2f6582015-07-29 10:14:58 -0700108 }
109 const_cast<SkGlyph&>(glyph).fMaskFormat = format;
Ben Wagner20fa1e92018-04-30 15:39:15 -0400110 */
joshualittaa2f6582015-07-29 10:14:58 -0700111
Ben Wagner20fa1e92018-04-30 15:39:15 -0400112 if (fFakeIt) {
joshualitt65e96b42015-07-31 11:45:22 -0700113 sk_bzero(glyph.fImage, glyph.computeImageSize());
Ben Wagner20fa1e92018-04-30 15:39:15 -0400114 return;
joshualittaa2f6582015-07-29 10:14:58 -0700115 }
Ben Wagner20fa1e92018-04-30 15:39:15 -0400116
117 if (SkMask::kARGB32_Format != glyph.fMaskFormat) {
118 fProxy->getImage(glyph);
119 return;
120 }
121
122 // If the format is ARGB, just draw the glyph from path.
123 SkPath path;
124 if (!fProxy->getPath(glyph.getPackedID(), &path)) {
125 fProxy->getImage(glyph);
126 return;
127 }
128
129 SkBitmap bm;
130 bm.installPixels(SkImageInfo::MakeN32Premul(glyph.fWidth, glyph.fHeight),
131 glyph.fImage, glyph.rowBytes());
132 bm.eraseColor(0);
133
134 SkCanvas canvas(bm);
135 canvas.translate(-SkIntToScalar(glyph.fLeft), -SkIntToScalar(glyph.fTop));
136 canvas.drawPath(path, this->getRandomTypeface()->paint());
joshualittaa2f6582015-07-29 10:14:58 -0700137}
138
Ben Wagner5ddb3082018-03-29 11:18:06 -0400139bool SkRandomScalerContext::generatePath(SkGlyphID glyph, SkPath* path) {
140 return fProxy->generatePath(glyph, path);
joshualittaa2f6582015-07-29 10:14:58 -0700141}
142
143void SkRandomScalerContext::generateFontMetrics(SkPaint::FontMetrics* metrics) {
144 fProxy->getFontMetrics(metrics);
joshualittaa2f6582015-07-29 10:14:58 -0700145}
146
147///////////////////////////////////////////////////////////////////////////////
148
bungeman13b9c952016-05-12 10:09:30 -0700149SkRandomTypeface::SkRandomTypeface(sk_sp<SkTypeface> proxy, const SkPaint& paint, bool fakeIt)
bungemane3aea102016-07-13 05:16:58 -0700150 : SkTypeface(proxy->fontStyle(), false)
bungeman13b9c952016-05-12 10:09:30 -0700151 , fProxy(std::move(proxy))
joshualitt65e96b42015-07-31 11:45:22 -0700152 , fPaint(paint)
153 , fFakeIt(fakeIt) {}
joshualittaa2f6582015-07-29 10:14:58 -0700154
reeda9322c22016-04-12 06:47:05 -0700155SkScalerContext* SkRandomTypeface::onCreateScalerContext(const SkScalerContextEffects& effects,
156 const SkDescriptor* desc) const {
bungeman7cfd46a2016-10-20 16:06:52 -0400157 return new SkRandomScalerContext(sk_ref_sp(const_cast<SkRandomTypeface*>(this)),
158 effects, desc, fFakeIt);
joshualittaa2f6582015-07-29 10:14:58 -0700159}
160
161void SkRandomTypeface::onFilterRec(SkScalerContextRec* rec) const {
162 fProxy->filterRec(rec);
163 rec->setHinting(SkPaint::kNo_Hinting);
164 rec->fMaskFormat = SkMask::kARGB32_Format;
165}
166
Hal Canary46cc3da2018-05-09 11:50:34 -0400167void SkRandomTypeface::getGlyphToUnicodeMap(SkUnichar* glyphToUnicode) const {
168 fProxy->getGlyphToUnicodeMap(glyphToUnicode);
169}
170
Hal Canary209e4b12017-05-04 14:23:55 -0400171std::unique_ptr<SkAdvancedTypefaceMetrics> SkRandomTypeface::onGetAdvancedMetrics() const {
172 return fProxy->getAdvancedMetrics();
joshualittaa2f6582015-07-29 10:14:58 -0700173}
174
175SkStreamAsset* SkRandomTypeface::onOpenStream(int* ttcIndex) const {
176 return fProxy->openStream(ttcIndex);
177}
178
Bruce Wang536ad2c2018-06-25 11:37:25 -0400179sk_sp<SkTypeface> SkRandomTypeface::onMakeClone(const SkFontArguments& args) const {
180 sk_sp<SkTypeface> proxy = fProxy->makeClone(args);
181 if (!proxy) {
182 return nullptr;
183 }
184 return sk_make_sp<SkRandomTypeface>(proxy, fPaint, fFakeIt);
185}
186
Ben Wagner20fa1e92018-04-30 15:39:15 -0400187void SkRandomTypeface::onGetFontDescriptor(SkFontDescriptor* desc, bool* isLocal) const {
188 // TODO: anything that uses this typeface isn't correctly serializable, since this typeface
189 // cannot be deserialized.
joshualittaa2f6582015-07-29 10:14:58 -0700190 fProxy->getFontDescriptor(desc, isLocal);
191}
192
193int SkRandomTypeface::onCharsToGlyphs(const void* chars, Encoding encoding,
194 uint16_t glyphs[], int glyphCount) const {
195 return fProxy->charsToGlyphs(chars, encoding, glyphs, glyphCount);
196}
197
198int SkRandomTypeface::onCountGlyphs() const {
199 return fProxy->countGlyphs();
200}
201
202int SkRandomTypeface::onGetUPEM() const {
203 return fProxy->getUnitsPerEm();
204}
205
206void SkRandomTypeface::onGetFamilyName(SkString* familyName) const {
207 fProxy->getFamilyName(familyName);
208}
209
210SkTypeface::LocalizedStrings* SkRandomTypeface::onCreateFamilyNameIterator() const {
211 return fProxy->createFamilyNameIterator();
212}
213
Ben Wagnerfc497342017-02-24 11:15:26 -0500214int SkRandomTypeface::onGetVariationDesignPosition(
215 SkFontArguments::VariationPosition::Coordinate coordinates[], int coordinateCount) const
216{
217 return fProxy->onGetVariationDesignPosition(coordinates, coordinateCount);
218}
219
Ben Wagnere346b1e2018-06-26 11:22:37 -0400220int SkRandomTypeface::onGetVariationDesignParameters(
221 SkFontParameters::Variation::Axis parameters[], int parameterCount) const
222{
223 return fProxy->onGetVariationDesignParameters(parameters, parameterCount);
224}
225
joshualittaa2f6582015-07-29 10:14:58 -0700226int SkRandomTypeface::onGetTableTags(SkFontTableTag tags[]) const {
227 return fProxy->getTableTags(tags);
228}
229
230size_t SkRandomTypeface::onGetTableData(SkFontTableTag tag, size_t offset,
231 size_t length, void* data) const {
232 return fProxy->getTableData(tag, offset, length, data);
233}
234