blob: 70aaf92605a5376491f6ad7ff60ccfd27eeda380 [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;
Mike Klein0cffcbf92019-03-20 11:08:46 -050028 bool generateAdvance(SkGlyph*) override;
29 void generateMetrics(SkGlyph*) override;
30 void generateImage(const SkGlyph&) override;
31 bool generatePath(SkGlyphID, SkPath*) override;
32 void generateFontMetrics(SkFontMetrics*) override;
joshualittaa2f6582015-07-29 10:14:58 -070033
34private:
bungeman7cfd46a2016-10-20 16:06:52 -040035 SkRandomTypeface* getRandomTypeface() const {
36 return static_cast<SkRandomTypeface*>(this->getTypeface());
37 }
38 std::unique_ptr<SkScalerContext> fProxy;
Mike Klein0cffcbf92019-03-20 11:08:46 -050039 bool fFakeIt;
joshualittaa2f6582015-07-29 10:14:58 -070040};
41
Mike Klein0cffcbf92019-03-20 11:08:46 -050042RandomScalerContext::RandomScalerContext(sk_sp<SkRandomTypeface> face,
43 const SkScalerContextEffects& effects,
44 const SkDescriptor* desc,
45 bool fakeIt)
bungeman7cfd46a2016-10-20 16:06:52 -040046 : SkScalerContext(std::move(face), effects, desc)
Ben Wagner20fa1e92018-04-30 15:39:15 -040047 , fProxy(getRandomTypeface()->proxy()->createScalerContext(SkScalerContextEffects(), desc))
Mike Klein0cffcbf92019-03-20 11:08:46 -050048 , fFakeIt(fakeIt) {
Ben Wagner20fa1e92018-04-30 15:39:15 -040049 fProxy->forceGenerateImageFromPath();
joshualittaa2f6582015-07-29 10:14:58 -070050}
51
Mike Klein0cffcbf92019-03-20 11:08:46 -050052unsigned RandomScalerContext::generateGlyphCount() { return fProxy->getGlyphCount(); }
joshualittaa2f6582015-07-29 10:14:58 -070053
Mike Klein0cffcbf92019-03-20 11:08:46 -050054bool RandomScalerContext::generateAdvance(SkGlyph* glyph) { return fProxy->generateAdvance(glyph); }
joshualittaa2f6582015-07-29 10:14:58 -070055
Mike Klein0cffcbf92019-03-20 11:08:46 -050056void RandomScalerContext::generateMetrics(SkGlyph* glyph) {
joshualittaa2f6582015-07-29 10:14:58 -070057 // Here we will change the mask format of the glyph
Ben Wagner20fa1e92018-04-30 15:39:15 -040058 // NOTE: this may be overridden by the base class (e.g. if a mask filter is applied).
joshualittd45fb5a2015-08-01 10:33:40 -070059 switch (glyph->getGlyphID() % 4) {
Ben Wagner20fa1e92018-04-30 15:39:15 -040060 case 0: glyph->fMaskFormat = SkMask::kLCD16_Format; break;
61 case 1: glyph->fMaskFormat = SkMask::kA8_Format; break;
62 case 2: glyph->fMaskFormat = SkMask::kARGB32_Format; break;
63 case 3: glyph->fMaskFormat = SkMask::kBW_Format; break;
joshualittaa2f6582015-07-29 10:14:58 -070064 }
65
joshualitt65e96b42015-07-31 11:45:22 -070066 fProxy->getMetrics(glyph);
67
Ben Wagner20fa1e92018-04-30 15:39:15 -040068 if (fFakeIt || (glyph->getGlyphID() % 4) != 2) {
joshualitt65e96b42015-07-31 11:45:22 -070069 return;
70 }
joshualitt65e96b42015-07-31 11:45:22 -070071
Ben Wagner20fa1e92018-04-30 15:39:15 -040072 SkPath path;
73 if (!fProxy->getPath(glyph->getPackedID(), &path)) {
74 return;
joshualitt65e96b42015-07-31 11:45:22 -070075 }
Ben Wagner20fa1e92018-04-30 15:39:15 -040076 glyph->fMaskFormat = SkMask::kARGB32_Format;
77
Mike Klein0cffcbf92019-03-20 11:08:46 -050078 SkRect storage;
Ben Wagner20fa1e92018-04-30 15:39:15 -040079 const SkPaint& paint = this->getRandomTypeface()->paint();
Mike Klein0cffcbf92019-03-20 11:08:46 -050080 const SkRect& newBounds =
81 paint.doComputeFastBounds(path.getBounds(), &storage, SkPaint::kFill_Style);
Ben Wagner20fa1e92018-04-30 15:39:15 -040082 SkIRect ibounds;
83 newBounds.roundOut(&ibounds);
Mike Klein0cffcbf92019-03-20 11:08:46 -050084 glyph->fLeft = ibounds.fLeft;
85 glyph->fTop = ibounds.fTop;
86 glyph->fWidth = ibounds.width();
Ben Wagner20fa1e92018-04-30 15:39:15 -040087 glyph->fHeight = ibounds.height();
joshualittaa2f6582015-07-29 10:14:58 -070088}
89
Mike Klein0cffcbf92019-03-20 11:08:46 -050090void RandomScalerContext::generateImage(const SkGlyph& glyph) {
Ben Wagner20fa1e92018-04-30 15:39:15 -040091 // TODO: can force down but not up
92 /*
joshualittaa2f6582015-07-29 10:14:58 -070093 SkMask::Format format = (SkMask::Format)glyph.fMaskFormat;
joshualittd45fb5a2015-08-01 10:33:40 -070094 switch (glyph.getGlyphID() % 4) {
Ben Wagner20fa1e92018-04-30 15:39:15 -040095 case 0: format = SkMask::kLCD16_Format; break;
96 case 1: format = SkMask::kA8_Format; break;
97 case 2: format = SkMask::kARGB32_Format; break;
98 case 3: format = SkMask::kBW_Format; break;
joshualittaa2f6582015-07-29 10:14:58 -070099 }
100 const_cast<SkGlyph&>(glyph).fMaskFormat = format;
Ben Wagner20fa1e92018-04-30 15:39:15 -0400101 */
joshualittaa2f6582015-07-29 10:14:58 -0700102
Ben Wagner20fa1e92018-04-30 15:39:15 -0400103 if (fFakeIt) {
joshualitt65e96b42015-07-31 11:45:22 -0700104 sk_bzero(glyph.fImage, glyph.computeImageSize());
Ben Wagner20fa1e92018-04-30 15:39:15 -0400105 return;
joshualittaa2f6582015-07-29 10:14:58 -0700106 }
Ben Wagner20fa1e92018-04-30 15:39:15 -0400107
108 if (SkMask::kARGB32_Format != glyph.fMaskFormat) {
109 fProxy->getImage(glyph);
110 return;
111 }
112
113 // If the format is ARGB, just draw the glyph from path.
114 SkPath path;
115 if (!fProxy->getPath(glyph.getPackedID(), &path)) {
116 fProxy->getImage(glyph);
117 return;
118 }
119
120 SkBitmap bm;
121 bm.installPixels(SkImageInfo::MakeN32Premul(glyph.fWidth, glyph.fHeight),
Mike Klein0cffcbf92019-03-20 11:08:46 -0500122 glyph.fImage,
123 glyph.rowBytes());
Ben Wagner20fa1e92018-04-30 15:39:15 -0400124 bm.eraseColor(0);
125
126 SkCanvas canvas(bm);
127 canvas.translate(-SkIntToScalar(glyph.fLeft), -SkIntToScalar(glyph.fTop));
128 canvas.drawPath(path, this->getRandomTypeface()->paint());
joshualittaa2f6582015-07-29 10:14:58 -0700129}
130
Mike Klein0cffcbf92019-03-20 11:08:46 -0500131bool RandomScalerContext::generatePath(SkGlyphID glyph, SkPath* path) {
Ben Wagner5ddb3082018-03-29 11:18:06 -0400132 return fProxy->generatePath(glyph, path);
joshualittaa2f6582015-07-29 10:14:58 -0700133}
134
Mike Klein0cffcbf92019-03-20 11:08:46 -0500135void RandomScalerContext::generateFontMetrics(SkFontMetrics* metrics) {
joshualittaa2f6582015-07-29 10:14:58 -0700136 fProxy->getFontMetrics(metrics);
joshualittaa2f6582015-07-29 10:14:58 -0700137}
138
139///////////////////////////////////////////////////////////////////////////////
140
bungeman13b9c952016-05-12 10:09:30 -0700141SkRandomTypeface::SkRandomTypeface(sk_sp<SkTypeface> proxy, const SkPaint& paint, bool fakeIt)
Mike Klein0cffcbf92019-03-20 11:08:46 -0500142 : SkTypeface(proxy->fontStyle(), false)
143 , fProxy(std::move(proxy))
144 , fPaint(paint)
145 , fFakeIt(fakeIt) {}
joshualittaa2f6582015-07-29 10:14:58 -0700146
reeda9322c22016-04-12 06:47:05 -0700147SkScalerContext* SkRandomTypeface::onCreateScalerContext(const SkScalerContextEffects& effects,
Mike Klein0cffcbf92019-03-20 11:08:46 -0500148 const SkDescriptor* desc) const {
149 return new RandomScalerContext(
150 sk_ref_sp(const_cast<SkRandomTypeface*>(this)), effects, desc, fFakeIt);
joshualittaa2f6582015-07-29 10:14:58 -0700151}
152
153void SkRandomTypeface::onFilterRec(SkScalerContextRec* rec) const {
154 fProxy->filterRec(rec);
Mike Reed04346d52018-11-05 12:45:32 -0500155 rec->setHinting(kNo_SkFontHinting);
joshualittaa2f6582015-07-29 10:14:58 -0700156 rec->fMaskFormat = SkMask::kARGB32_Format;
157}
158
Hal Canary46cc3da2018-05-09 11:50:34 -0400159void SkRandomTypeface::getGlyphToUnicodeMap(SkUnichar* glyphToUnicode) const {
160 fProxy->getGlyphToUnicodeMap(glyphToUnicode);
161}
162
Hal Canary209e4b12017-05-04 14:23:55 -0400163std::unique_ptr<SkAdvancedTypefaceMetrics> SkRandomTypeface::onGetAdvancedMetrics() const {
164 return fProxy->getAdvancedMetrics();
joshualittaa2f6582015-07-29 10:14:58 -0700165}
166
Ben Wagner4212a7d2019-02-25 14:27:46 -0500167std::unique_ptr<SkStreamAsset> SkRandomTypeface::onOpenStream(int* ttcIndex) const {
Ben Wagnerff84d8a2019-02-26 15:39:41 -0500168 return fProxy->openStream(ttcIndex);
joshualittaa2f6582015-07-29 10:14:58 -0700169}
170
Bruce Wang536ad2c2018-06-25 11:37:25 -0400171sk_sp<SkTypeface> SkRandomTypeface::onMakeClone(const SkFontArguments& args) const {
172 sk_sp<SkTypeface> proxy = fProxy->makeClone(args);
173 if (!proxy) {
174 return nullptr;
175 }
176 return sk_make_sp<SkRandomTypeface>(proxy, fPaint, fFakeIt);
177}
178
Ben Wagner20fa1e92018-04-30 15:39:15 -0400179void SkRandomTypeface::onGetFontDescriptor(SkFontDescriptor* desc, bool* isLocal) const {
180 // TODO: anything that uses this typeface isn't correctly serializable, since this typeface
181 // cannot be deserialized.
joshualittaa2f6582015-07-29 10:14:58 -0700182 fProxy->getFontDescriptor(desc, isLocal);
183}
184
Mike Reed64670cb2019-04-16 11:37:38 -0700185void SkRandomTypeface::onCharsToGlyphs(const SkUnichar* uni, int count, SkGlyphID glyphs[]) const {
186 fProxy->unicharsToGlyphs(uni, count, glyphs);
joshualittaa2f6582015-07-29 10:14:58 -0700187}
188
Mike Klein0cffcbf92019-03-20 11:08:46 -0500189int SkRandomTypeface::onCountGlyphs() const { return fProxy->countGlyphs(); }
joshualittaa2f6582015-07-29 10:14:58 -0700190
Mike Klein0cffcbf92019-03-20 11:08:46 -0500191int SkRandomTypeface::onGetUPEM() const { return fProxy->getUnitsPerEm(); }
joshualittaa2f6582015-07-29 10:14:58 -0700192
193void SkRandomTypeface::onGetFamilyName(SkString* familyName) const {
194 fProxy->getFamilyName(familyName);
195}
196
197SkTypeface::LocalizedStrings* SkRandomTypeface::onCreateFamilyNameIterator() const {
198 return fProxy->createFamilyNameIterator();
199}
200
Ben Wagner2c2240f2019-04-17 16:04:30 -0400201void SkRandomTypeface::getPostScriptGlyphNames(SkString* names) const {
202 return fProxy->getPostScriptGlyphNames(names);
203}
204
Ben Wagnerfc497342017-02-24 11:15:26 -0500205int SkRandomTypeface::onGetVariationDesignPosition(
Mike Klein0cffcbf92019-03-20 11:08:46 -0500206 SkFontArguments::VariationPosition::Coordinate coordinates[],
207 int coordinateCount) const {
Ben Wagnerfc497342017-02-24 11:15:26 -0500208 return fProxy->onGetVariationDesignPosition(coordinates, coordinateCount);
209}
210
Mike Klein0cffcbf92019-03-20 11:08:46 -0500211int SkRandomTypeface::onGetVariationDesignParameters(SkFontParameters::Variation::Axis parameters[],
212 int parameterCount) const {
Ben Wagnere346b1e2018-06-26 11:22:37 -0400213 return fProxy->onGetVariationDesignParameters(parameters, parameterCount);
214}
215
joshualittaa2f6582015-07-29 10:14:58 -0700216int SkRandomTypeface::onGetTableTags(SkFontTableTag tags[]) const {
217 return fProxy->getTableTags(tags);
218}
219
Mike Klein0cffcbf92019-03-20 11:08:46 -0500220size_t SkRandomTypeface::onGetTableData(SkFontTableTag tag,
221 size_t offset,
222 size_t length,
223 void* data) const {
joshualittaa2f6582015-07-29 10:14:58 -0700224 return fProxy->getTableData(tag, offset, length, data);
225}