blob: 1fe188a2a6c4d6b6c56b10c9c44e4c984a62d0ab [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 Kleinc0bd9f92019-04-23 12:05:21 -05008#include "include/core/SkBitmap.h"
9#include "include/core/SkCanvas.h"
10#include "include/core/SkPath.h"
11#include "src/core/SkAdvancedTypefaceMetrics.h"
12#include "src/core/SkGlyph.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050013#include "src/core/SkRectPriv.h"
14#include "tools/fonts/RandomScalerContext.h"
joshualittaa2f6582015-07-29 10:14:58 -070015
bungeman7cfd46a2016-10-20 16:06:52 -040016class SkDescriptor;
17
Mike Klein0cffcbf92019-03-20 11:08:46 -050018class RandomScalerContext : public SkScalerContext {
joshualittaa2f6582015-07-29 10:14:58 -070019public:
Mike Klein0cffcbf92019-03-20 11:08:46 -050020 RandomScalerContext(sk_sp<SkRandomTypeface>,
21 const SkScalerContextEffects&,
22 const SkDescriptor*,
23 bool fFakeIt);
joshualittaa2f6582015-07-29 10:14:58 -070024
25protected:
26 unsigned generateGlyphCount() override;
Mike Klein0cffcbf92019-03-20 11:08:46 -050027 bool generateAdvance(SkGlyph*) override;
28 void generateMetrics(SkGlyph*) override;
29 void generateImage(const SkGlyph&) override;
30 bool generatePath(SkGlyphID, SkPath*) override;
31 void generateFontMetrics(SkFontMetrics*) override;
joshualittaa2f6582015-07-29 10:14:58 -070032
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;
Mike Klein0cffcbf92019-03-20 11:08:46 -050038 bool fFakeIt;
joshualittaa2f6582015-07-29 10:14:58 -070039};
40
Mike Klein0cffcbf92019-03-20 11:08:46 -050041RandomScalerContext::RandomScalerContext(sk_sp<SkRandomTypeface> face,
42 const SkScalerContextEffects& effects,
43 const SkDescriptor* desc,
44 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))
Mike Klein0cffcbf92019-03-20 11:08:46 -050047 , fFakeIt(fakeIt) {
Ben Wagner20fa1e92018-04-30 15:39:15 -040048 fProxy->forceGenerateImageFromPath();
joshualittaa2f6582015-07-29 10:14:58 -070049}
50
Mike Klein0cffcbf92019-03-20 11:08:46 -050051unsigned RandomScalerContext::generateGlyphCount() { return fProxy->getGlyphCount(); }
joshualittaa2f6582015-07-29 10:14:58 -070052
Mike Klein0cffcbf92019-03-20 11:08:46 -050053bool RandomScalerContext::generateAdvance(SkGlyph* glyph) { return fProxy->generateAdvance(glyph); }
joshualittaa2f6582015-07-29 10:14:58 -070054
Mike Klein0cffcbf92019-03-20 11:08:46 -050055void RandomScalerContext::generateMetrics(SkGlyph* glyph) {
joshualittaa2f6582015-07-29 10:14:58 -070056 // Here we will change the mask format of the glyph
Ben Wagner20fa1e92018-04-30 15:39:15 -040057 // NOTE: this may be overridden by the base class (e.g. if a mask filter is applied).
joshualittd45fb5a2015-08-01 10:33:40 -070058 switch (glyph->getGlyphID() % 4) {
Ben Wagner20fa1e92018-04-30 15:39:15 -040059 case 0: glyph->fMaskFormat = SkMask::kLCD16_Format; break;
60 case 1: glyph->fMaskFormat = SkMask::kA8_Format; break;
61 case 2: glyph->fMaskFormat = SkMask::kARGB32_Format; break;
62 case 3: glyph->fMaskFormat = SkMask::kBW_Format; break;
joshualittaa2f6582015-07-29 10:14:58 -070063 }
64
joshualitt65e96b42015-07-31 11:45:22 -070065 fProxy->getMetrics(glyph);
66
Ben Wagner20fa1e92018-04-30 15:39:15 -040067 if (fFakeIt || (glyph->getGlyphID() % 4) != 2) {
joshualitt65e96b42015-07-31 11:45:22 -070068 return;
69 }
joshualitt65e96b42015-07-31 11:45:22 -070070
Ben Wagner20fa1e92018-04-30 15:39:15 -040071 SkPath path;
72 if (!fProxy->getPath(glyph->getPackedID(), &path)) {
73 return;
joshualitt65e96b42015-07-31 11:45:22 -070074 }
Ben Wagner20fa1e92018-04-30 15:39:15 -040075 glyph->fMaskFormat = SkMask::kARGB32_Format;
76
Mike Klein0cffcbf92019-03-20 11:08:46 -050077 SkRect storage;
Ben Wagner20fa1e92018-04-30 15:39:15 -040078 const SkPaint& paint = this->getRandomTypeface()->paint();
Mike Klein0cffcbf92019-03-20 11:08:46 -050079 const SkRect& newBounds =
80 paint.doComputeFastBounds(path.getBounds(), &storage, SkPaint::kFill_Style);
Ben Wagner20fa1e92018-04-30 15:39:15 -040081 SkIRect ibounds;
82 newBounds.roundOut(&ibounds);
Mike Klein0cffcbf92019-03-20 11:08:46 -050083 glyph->fLeft = ibounds.fLeft;
84 glyph->fTop = ibounds.fTop;
85 glyph->fWidth = ibounds.width();
Ben Wagner20fa1e92018-04-30 15:39:15 -040086 glyph->fHeight = ibounds.height();
joshualittaa2f6582015-07-29 10:14:58 -070087}
88
Mike Klein0cffcbf92019-03-20 11:08:46 -050089void RandomScalerContext::generateImage(const SkGlyph& glyph) {
Ben Wagner20fa1e92018-04-30 15:39:15 -040090 // TODO: can force down but not up
91 /*
joshualittaa2f6582015-07-29 10:14:58 -070092 SkMask::Format format = (SkMask::Format)glyph.fMaskFormat;
joshualittd45fb5a2015-08-01 10:33:40 -070093 switch (glyph.getGlyphID() % 4) {
Ben Wagner20fa1e92018-04-30 15:39:15 -040094 case 0: format = SkMask::kLCD16_Format; break;
95 case 1: format = SkMask::kA8_Format; break;
96 case 2: format = SkMask::kARGB32_Format; break;
97 case 3: format = SkMask::kBW_Format; break;
joshualittaa2f6582015-07-29 10:14:58 -070098 }
99 const_cast<SkGlyph&>(glyph).fMaskFormat = format;
Ben Wagner20fa1e92018-04-30 15:39:15 -0400100 */
joshualittaa2f6582015-07-29 10:14:58 -0700101
Ben Wagner20fa1e92018-04-30 15:39:15 -0400102 if (fFakeIt) {
Herb Derby9b06f212019-06-21 14:25:47 -0400103 sk_bzero(glyph.fImage, glyph.imageSize());
Ben Wagner20fa1e92018-04-30 15:39:15 -0400104 return;
joshualittaa2f6582015-07-29 10:14:58 -0700105 }
Ben Wagner20fa1e92018-04-30 15:39:15 -0400106
107 if (SkMask::kARGB32_Format != glyph.fMaskFormat) {
108 fProxy->getImage(glyph);
109 return;
110 }
111
112 // If the format is ARGB, just draw the glyph from path.
113 SkPath path;
114 if (!fProxy->getPath(glyph.getPackedID(), &path)) {
115 fProxy->getImage(glyph);
116 return;
117 }
118
119 SkBitmap bm;
120 bm.installPixels(SkImageInfo::MakeN32Premul(glyph.fWidth, glyph.fHeight),
Mike Klein0cffcbf92019-03-20 11:08:46 -0500121 glyph.fImage,
122 glyph.rowBytes());
Ben Wagner20fa1e92018-04-30 15:39:15 -0400123 bm.eraseColor(0);
124
125 SkCanvas canvas(bm);
126 canvas.translate(-SkIntToScalar(glyph.fLeft), -SkIntToScalar(glyph.fTop));
127 canvas.drawPath(path, this->getRandomTypeface()->paint());
joshualittaa2f6582015-07-29 10:14:58 -0700128}
129
Mike Klein0cffcbf92019-03-20 11:08:46 -0500130bool RandomScalerContext::generatePath(SkGlyphID glyph, SkPath* path) {
Ben Wagner5ddb3082018-03-29 11:18:06 -0400131 return fProxy->generatePath(glyph, path);
joshualittaa2f6582015-07-29 10:14:58 -0700132}
133
Mike Klein0cffcbf92019-03-20 11:08:46 -0500134void RandomScalerContext::generateFontMetrics(SkFontMetrics* metrics) {
joshualittaa2f6582015-07-29 10:14:58 -0700135 fProxy->getFontMetrics(metrics);
joshualittaa2f6582015-07-29 10:14:58 -0700136}
137
138///////////////////////////////////////////////////////////////////////////////
139
bungeman13b9c952016-05-12 10:09:30 -0700140SkRandomTypeface::SkRandomTypeface(sk_sp<SkTypeface> proxy, const SkPaint& paint, bool fakeIt)
Mike Klein0cffcbf92019-03-20 11:08:46 -0500141 : SkTypeface(proxy->fontStyle(), false)
142 , fProxy(std::move(proxy))
143 , fPaint(paint)
144 , fFakeIt(fakeIt) {}
joshualittaa2f6582015-07-29 10:14:58 -0700145
reeda9322c22016-04-12 06:47:05 -0700146SkScalerContext* SkRandomTypeface::onCreateScalerContext(const SkScalerContextEffects& effects,
Mike Klein0cffcbf92019-03-20 11:08:46 -0500147 const SkDescriptor* desc) const {
148 return new RandomScalerContext(
149 sk_ref_sp(const_cast<SkRandomTypeface*>(this)), effects, desc, fFakeIt);
joshualittaa2f6582015-07-29 10:14:58 -0700150}
151
152void SkRandomTypeface::onFilterRec(SkScalerContextRec* rec) const {
153 fProxy->filterRec(rec);
Ben Wagner5785e4a2019-05-07 16:50:29 -0400154 rec->setHinting(SkFontHinting::kNone);
joshualittaa2f6582015-07-29 10:14:58 -0700155 rec->fMaskFormat = SkMask::kARGB32_Format;
156}
157
Hal Canary46cc3da2018-05-09 11:50:34 -0400158void SkRandomTypeface::getGlyphToUnicodeMap(SkUnichar* glyphToUnicode) const {
159 fProxy->getGlyphToUnicodeMap(glyphToUnicode);
160}
161
Hal Canary209e4b12017-05-04 14:23:55 -0400162std::unique_ptr<SkAdvancedTypefaceMetrics> SkRandomTypeface::onGetAdvancedMetrics() const {
163 return fProxy->getAdvancedMetrics();
joshualittaa2f6582015-07-29 10:14:58 -0700164}
165
Ben Wagner4212a7d2019-02-25 14:27:46 -0500166std::unique_ptr<SkStreamAsset> SkRandomTypeface::onOpenStream(int* ttcIndex) const {
Ben Wagnerff84d8a2019-02-26 15:39:41 -0500167 return fProxy->openStream(ttcIndex);
joshualittaa2f6582015-07-29 10:14:58 -0700168}
169
Bruce Wang536ad2c2018-06-25 11:37:25 -0400170sk_sp<SkTypeface> SkRandomTypeface::onMakeClone(const SkFontArguments& args) const {
171 sk_sp<SkTypeface> proxy = fProxy->makeClone(args);
172 if (!proxy) {
173 return nullptr;
174 }
175 return sk_make_sp<SkRandomTypeface>(proxy, fPaint, fFakeIt);
176}
177
Ben Wagner20fa1e92018-04-30 15:39:15 -0400178void SkRandomTypeface::onGetFontDescriptor(SkFontDescriptor* desc, bool* isLocal) const {
179 // TODO: anything that uses this typeface isn't correctly serializable, since this typeface
180 // cannot be deserialized.
joshualittaa2f6582015-07-29 10:14:58 -0700181 fProxy->getFontDescriptor(desc, isLocal);
182}
183
Mike Reed64670cb2019-04-16 11:37:38 -0700184void SkRandomTypeface::onCharsToGlyphs(const SkUnichar* uni, int count, SkGlyphID glyphs[]) const {
185 fProxy->unicharsToGlyphs(uni, count, glyphs);
joshualittaa2f6582015-07-29 10:14:58 -0700186}
187
Mike Klein0cffcbf92019-03-20 11:08:46 -0500188int SkRandomTypeface::onCountGlyphs() const { return fProxy->countGlyphs(); }
joshualittaa2f6582015-07-29 10:14:58 -0700189
Mike Klein0cffcbf92019-03-20 11:08:46 -0500190int SkRandomTypeface::onGetUPEM() const { return fProxy->getUnitsPerEm(); }
joshualittaa2f6582015-07-29 10:14:58 -0700191
192void SkRandomTypeface::onGetFamilyName(SkString* familyName) const {
193 fProxy->getFamilyName(familyName);
194}
195
196SkTypeface::LocalizedStrings* SkRandomTypeface::onCreateFamilyNameIterator() const {
197 return fProxy->createFamilyNameIterator();
198}
199
Ben Wagner2c2240f2019-04-17 16:04:30 -0400200void SkRandomTypeface::getPostScriptGlyphNames(SkString* names) const {
201 return fProxy->getPostScriptGlyphNames(names);
202}
203
Ben Wagnerfc497342017-02-24 11:15:26 -0500204int SkRandomTypeface::onGetVariationDesignPosition(
Mike Klein0cffcbf92019-03-20 11:08:46 -0500205 SkFontArguments::VariationPosition::Coordinate coordinates[],
206 int coordinateCount) const {
Ben Wagnerfc497342017-02-24 11:15:26 -0500207 return fProxy->onGetVariationDesignPosition(coordinates, coordinateCount);
208}
209
Mike Klein0cffcbf92019-03-20 11:08:46 -0500210int SkRandomTypeface::onGetVariationDesignParameters(SkFontParameters::Variation::Axis parameters[],
211 int parameterCount) const {
Ben Wagnere346b1e2018-06-26 11:22:37 -0400212 return fProxy->onGetVariationDesignParameters(parameters, parameterCount);
213}
214
joshualittaa2f6582015-07-29 10:14:58 -0700215int SkRandomTypeface::onGetTableTags(SkFontTableTag tags[]) const {
216 return fProxy->getTableTags(tags);
217}
218
Mike Klein0cffcbf92019-03-20 11:08:46 -0500219size_t SkRandomTypeface::onGetTableData(SkFontTableTag tag,
220 size_t offset,
221 size_t length,
222 void* data) const {
joshualittaa2f6582015-07-29 10:14:58 -0700223 return fProxy->getTableData(tag, offset, length, data);
224}