blob: d20834cfe6c101c96ed3f567ffb51dcf598e6d1d [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
Mike Klein0cffcbf92019-03-20 11:08:46 -05008#include "RandomScalerContext.h"
Hal Canary209e4b12017-05-04 14:23:55 -04009#include "SkAdvancedTypefaceMetrics.h"
Florin Malitaab244f02017-05-03 19:16:58 +000010#include "SkBitmap.h"
joshualittaa2f6582015-07-29 10:14:58 -070011#include "SkCanvas.h"
bungeman7cfd46a2016-10-20 16:06:52 -040012#include "SkGlyph.h"
13#include "SkMakeUnique.h"
14#include "SkPath.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
Mike Klein0cffcbf92019-03-20 11:08:46 -050019class RandomScalerContext : public SkScalerContext {
joshualittaa2f6582015-07-29 10:14:58 -070020public:
Mike Klein0cffcbf92019-03-20 11:08:46 -050021 RandomScalerContext(sk_sp<SkRandomTypeface>,
22 const SkScalerContextEffects&,
23 const SkDescriptor*,
24 bool fFakeIt);
joshualittaa2f6582015-07-29 10:14:58 -070025
26protected:
27 unsigned generateGlyphCount() override;
28 uint16_t generateCharToGlyph(SkUnichar) override;
Mike Klein0cffcbf92019-03-20 11:08:46 -050029 bool generateAdvance(SkGlyph*) override;
30 void generateMetrics(SkGlyph*) override;
31 void generateImage(const SkGlyph&) override;
32 bool generatePath(SkGlyphID, SkPath*) override;
33 void generateFontMetrics(SkFontMetrics*) override;
joshualittaa2f6582015-07-29 10:14:58 -070034
35private:
bungeman7cfd46a2016-10-20 16:06:52 -040036 SkRandomTypeface* getRandomTypeface() const {
37 return static_cast<SkRandomTypeface*>(this->getTypeface());
38 }
39 std::unique_ptr<SkScalerContext> fProxy;
Mike Klein0cffcbf92019-03-20 11:08:46 -050040 bool fFakeIt;
joshualittaa2f6582015-07-29 10:14:58 -070041};
42
Mike Klein0cffcbf92019-03-20 11:08:46 -050043RandomScalerContext::RandomScalerContext(sk_sp<SkRandomTypeface> face,
44 const SkScalerContextEffects& effects,
45 const SkDescriptor* desc,
46 bool fakeIt)
bungeman7cfd46a2016-10-20 16:06:52 -040047 : SkScalerContext(std::move(face), effects, desc)
Ben Wagner20fa1e92018-04-30 15:39:15 -040048 , fProxy(getRandomTypeface()->proxy()->createScalerContext(SkScalerContextEffects(), desc))
Mike Klein0cffcbf92019-03-20 11:08:46 -050049 , fFakeIt(fakeIt) {
Ben Wagner20fa1e92018-04-30 15:39:15 -040050 fProxy->forceGenerateImageFromPath();
joshualittaa2f6582015-07-29 10:14:58 -070051}
52
Mike Klein0cffcbf92019-03-20 11:08:46 -050053unsigned RandomScalerContext::generateGlyphCount() { return fProxy->getGlyphCount(); }
joshualittaa2f6582015-07-29 10:14:58 -070054
Mike Klein0cffcbf92019-03-20 11:08:46 -050055uint16_t RandomScalerContext::generateCharToGlyph(SkUnichar uni) {
joshualittaa2f6582015-07-29 10:14:58 -070056 return fProxy->charToGlyphID(uni);
57}
58
Mike Klein0cffcbf92019-03-20 11:08:46 -050059bool RandomScalerContext::generateAdvance(SkGlyph* glyph) { return fProxy->generateAdvance(glyph); }
joshualittaa2f6582015-07-29 10:14:58 -070060
Mike Klein0cffcbf92019-03-20 11:08:46 -050061void RandomScalerContext::generateMetrics(SkGlyph* glyph) {
joshualittaa2f6582015-07-29 10:14:58 -070062 // Here we will change the mask format of the glyph
Ben Wagner20fa1e92018-04-30 15:39:15 -040063 // NOTE: this may be overridden by the base class (e.g. if a mask filter is applied).
joshualittd45fb5a2015-08-01 10:33:40 -070064 switch (glyph->getGlyphID() % 4) {
Ben Wagner20fa1e92018-04-30 15:39:15 -040065 case 0: glyph->fMaskFormat = SkMask::kLCD16_Format; break;
66 case 1: glyph->fMaskFormat = SkMask::kA8_Format; break;
67 case 2: glyph->fMaskFormat = SkMask::kARGB32_Format; break;
68 case 3: glyph->fMaskFormat = SkMask::kBW_Format; break;
joshualittaa2f6582015-07-29 10:14:58 -070069 }
70
joshualitt65e96b42015-07-31 11:45:22 -070071 fProxy->getMetrics(glyph);
72
Ben Wagner20fa1e92018-04-30 15:39:15 -040073 if (fFakeIt || (glyph->getGlyphID() % 4) != 2) {
joshualitt65e96b42015-07-31 11:45:22 -070074 return;
75 }
joshualitt65e96b42015-07-31 11:45:22 -070076
Ben Wagner20fa1e92018-04-30 15:39:15 -040077 SkPath path;
78 if (!fProxy->getPath(glyph->getPackedID(), &path)) {
79 return;
joshualitt65e96b42015-07-31 11:45:22 -070080 }
Ben Wagner20fa1e92018-04-30 15:39:15 -040081 glyph->fMaskFormat = SkMask::kARGB32_Format;
82
Mike Klein0cffcbf92019-03-20 11:08:46 -050083 SkRect storage;
Ben Wagner20fa1e92018-04-30 15:39:15 -040084 const SkPaint& paint = this->getRandomTypeface()->paint();
Mike Klein0cffcbf92019-03-20 11:08:46 -050085 const SkRect& newBounds =
86 paint.doComputeFastBounds(path.getBounds(), &storage, SkPaint::kFill_Style);
Ben Wagner20fa1e92018-04-30 15:39:15 -040087 SkIRect ibounds;
88 newBounds.roundOut(&ibounds);
Mike Klein0cffcbf92019-03-20 11:08:46 -050089 glyph->fLeft = ibounds.fLeft;
90 glyph->fTop = ibounds.fTop;
91 glyph->fWidth = ibounds.width();
Ben Wagner20fa1e92018-04-30 15:39:15 -040092 glyph->fHeight = ibounds.height();
joshualittaa2f6582015-07-29 10:14:58 -070093}
94
Mike Klein0cffcbf92019-03-20 11:08:46 -050095void RandomScalerContext::generateImage(const SkGlyph& glyph) {
Ben Wagner20fa1e92018-04-30 15:39:15 -040096 // TODO: can force down but not up
97 /*
joshualittaa2f6582015-07-29 10:14:58 -070098 SkMask::Format format = (SkMask::Format)glyph.fMaskFormat;
joshualittd45fb5a2015-08-01 10:33:40 -070099 switch (glyph.getGlyphID() % 4) {
Ben Wagner20fa1e92018-04-30 15:39:15 -0400100 case 0: format = SkMask::kLCD16_Format; break;
101 case 1: format = SkMask::kA8_Format; break;
102 case 2: format = SkMask::kARGB32_Format; break;
103 case 3: format = SkMask::kBW_Format; break;
joshualittaa2f6582015-07-29 10:14:58 -0700104 }
105 const_cast<SkGlyph&>(glyph).fMaskFormat = format;
Ben Wagner20fa1e92018-04-30 15:39:15 -0400106 */
joshualittaa2f6582015-07-29 10:14:58 -0700107
Ben Wagner20fa1e92018-04-30 15:39:15 -0400108 if (fFakeIt) {
joshualitt65e96b42015-07-31 11:45:22 -0700109 sk_bzero(glyph.fImage, glyph.computeImageSize());
Ben Wagner20fa1e92018-04-30 15:39:15 -0400110 return;
joshualittaa2f6582015-07-29 10:14:58 -0700111 }
Ben Wagner20fa1e92018-04-30 15:39:15 -0400112
113 if (SkMask::kARGB32_Format != glyph.fMaskFormat) {
114 fProxy->getImage(glyph);
115 return;
116 }
117
118 // If the format is ARGB, just draw the glyph from path.
119 SkPath path;
120 if (!fProxy->getPath(glyph.getPackedID(), &path)) {
121 fProxy->getImage(glyph);
122 return;
123 }
124
125 SkBitmap bm;
126 bm.installPixels(SkImageInfo::MakeN32Premul(glyph.fWidth, glyph.fHeight),
Mike Klein0cffcbf92019-03-20 11:08:46 -0500127 glyph.fImage,
128 glyph.rowBytes());
Ben Wagner20fa1e92018-04-30 15:39:15 -0400129 bm.eraseColor(0);
130
131 SkCanvas canvas(bm);
132 canvas.translate(-SkIntToScalar(glyph.fLeft), -SkIntToScalar(glyph.fTop));
133 canvas.drawPath(path, this->getRandomTypeface()->paint());
joshualittaa2f6582015-07-29 10:14:58 -0700134}
135
Mike Klein0cffcbf92019-03-20 11:08:46 -0500136bool RandomScalerContext::generatePath(SkGlyphID glyph, SkPath* path) {
Ben Wagner5ddb3082018-03-29 11:18:06 -0400137 return fProxy->generatePath(glyph, path);
joshualittaa2f6582015-07-29 10:14:58 -0700138}
139
Mike Klein0cffcbf92019-03-20 11:08:46 -0500140void RandomScalerContext::generateFontMetrics(SkFontMetrics* metrics) {
joshualittaa2f6582015-07-29 10:14:58 -0700141 fProxy->getFontMetrics(metrics);
joshualittaa2f6582015-07-29 10:14:58 -0700142}
143
144///////////////////////////////////////////////////////////////////////////////
145
bungeman13b9c952016-05-12 10:09:30 -0700146SkRandomTypeface::SkRandomTypeface(sk_sp<SkTypeface> proxy, const SkPaint& paint, bool fakeIt)
Mike Klein0cffcbf92019-03-20 11:08:46 -0500147 : SkTypeface(proxy->fontStyle(), false)
148 , fProxy(std::move(proxy))
149 , fPaint(paint)
150 , fFakeIt(fakeIt) {}
joshualittaa2f6582015-07-29 10:14:58 -0700151
reeda9322c22016-04-12 06:47:05 -0700152SkScalerContext* SkRandomTypeface::onCreateScalerContext(const SkScalerContextEffects& effects,
Mike Klein0cffcbf92019-03-20 11:08:46 -0500153 const SkDescriptor* desc) const {
154 return new RandomScalerContext(
155 sk_ref_sp(const_cast<SkRandomTypeface*>(this)), effects, desc, fFakeIt);
joshualittaa2f6582015-07-29 10:14:58 -0700156}
157
158void SkRandomTypeface::onFilterRec(SkScalerContextRec* rec) const {
159 fProxy->filterRec(rec);
Mike Reed04346d52018-11-05 12:45:32 -0500160 rec->setHinting(kNo_SkFontHinting);
joshualittaa2f6582015-07-29 10:14:58 -0700161 rec->fMaskFormat = SkMask::kARGB32_Format;
162}
163
Hal Canary46cc3da2018-05-09 11:50:34 -0400164void SkRandomTypeface::getGlyphToUnicodeMap(SkUnichar* glyphToUnicode) const {
165 fProxy->getGlyphToUnicodeMap(glyphToUnicode);
166}
167
Hal Canary209e4b12017-05-04 14:23:55 -0400168std::unique_ptr<SkAdvancedTypefaceMetrics> SkRandomTypeface::onGetAdvancedMetrics() const {
169 return fProxy->getAdvancedMetrics();
joshualittaa2f6582015-07-29 10:14:58 -0700170}
171
Ben Wagner4212a7d2019-02-25 14:27:46 -0500172std::unique_ptr<SkStreamAsset> SkRandomTypeface::onOpenStream(int* ttcIndex) const {
Ben Wagnerff84d8a2019-02-26 15:39:41 -0500173 return fProxy->openStream(ttcIndex);
joshualittaa2f6582015-07-29 10:14:58 -0700174}
175
Bruce Wang536ad2c2018-06-25 11:37:25 -0400176sk_sp<SkTypeface> SkRandomTypeface::onMakeClone(const SkFontArguments& args) const {
177 sk_sp<SkTypeface> proxy = fProxy->makeClone(args);
178 if (!proxy) {
179 return nullptr;
180 }
181 return sk_make_sp<SkRandomTypeface>(proxy, fPaint, fFakeIt);
182}
183
Ben Wagner20fa1e92018-04-30 15:39:15 -0400184void SkRandomTypeface::onGetFontDescriptor(SkFontDescriptor* desc, bool* isLocal) const {
185 // TODO: anything that uses this typeface isn't correctly serializable, since this typeface
186 // cannot be deserialized.
joshualittaa2f6582015-07-29 10:14:58 -0700187 fProxy->getFontDescriptor(desc, isLocal);
188}
189
Mike Klein0cffcbf92019-03-20 11:08:46 -0500190int SkRandomTypeface::onCharsToGlyphs(const void* chars,
191 Encoding encoding,
192 uint16_t glyphs[],
193 int glyphCount) const {
joshualittaa2f6582015-07-29 10:14:58 -0700194 return fProxy->charsToGlyphs(chars, encoding, glyphs, glyphCount);
195}
196
Mike Klein0cffcbf92019-03-20 11:08:46 -0500197int SkRandomTypeface::onCountGlyphs() const { return fProxy->countGlyphs(); }
joshualittaa2f6582015-07-29 10:14:58 -0700198
Mike Klein0cffcbf92019-03-20 11:08:46 -0500199int SkRandomTypeface::onGetUPEM() const { return fProxy->getUnitsPerEm(); }
joshualittaa2f6582015-07-29 10:14:58 -0700200
201void SkRandomTypeface::onGetFamilyName(SkString* familyName) const {
202 fProxy->getFamilyName(familyName);
203}
204
205SkTypeface::LocalizedStrings* SkRandomTypeface::onCreateFamilyNameIterator() const {
206 return fProxy->createFamilyNameIterator();
207}
208
Ben Wagnerfc497342017-02-24 11:15:26 -0500209int SkRandomTypeface::onGetVariationDesignPosition(
Mike Klein0cffcbf92019-03-20 11:08:46 -0500210 SkFontArguments::VariationPosition::Coordinate coordinates[],
211 int coordinateCount) const {
Ben Wagnerfc497342017-02-24 11:15:26 -0500212 return fProxy->onGetVariationDesignPosition(coordinates, coordinateCount);
213}
214
Mike Klein0cffcbf92019-03-20 11:08:46 -0500215int SkRandomTypeface::onGetVariationDesignParameters(SkFontParameters::Variation::Axis parameters[],
216 int parameterCount) const {
Ben Wagnere346b1e2018-06-26 11:22:37 -0400217 return fProxy->onGetVariationDesignParameters(parameters, parameterCount);
218}
219
joshualittaa2f6582015-07-29 10:14:58 -0700220int SkRandomTypeface::onGetTableTags(SkFontTableTag tags[]) const {
221 return fProxy->getTableTags(tags);
222}
223
Mike Klein0cffcbf92019-03-20 11:08:46 -0500224size_t SkRandomTypeface::onGetTableData(SkFontTableTag tag,
225 size_t offset,
226 size_t length,
227 void* data) const {
joshualittaa2f6582015-07-29 10:14:58 -0700228 return fProxy->getTableData(tag, offset, length, data);
229}