Flutter Engine
The Flutter Engine
RandomScalerContext.cpp
Go to the documentation of this file.
1/*
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
9
13#include "include/core/SkPath.h"
16#include "src/core/SkGlyph.h"
17#include "src/core/SkRectPriv.h"
18#include "src/core/SkTHash.h"
19
20using namespace skia_private;
21
22class SkDescriptor;
23
25public:
28 const SkDescriptor*,
29 bool fFakeIt);
30
31protected:
33 void generateImage(const SkGlyph&, void*) override;
34 bool generatePath(const SkGlyph&, SkPath*) override;
36 void generateFontMetrics(SkFontMetrics*) override;
37
38private:
39 SkRandomTypeface* getRandomTypeface() const {
40 return static_cast<SkRandomTypeface*>(this->getTypeface());
41 }
42 std::unique_ptr<SkScalerContext> fProxy;
43 // Many of the SkGlyphs returned are the same as those created by the fProxy.
44 // When they are not, the originals are kept here.
46 bool fFakeIt;
47};
48
50 const SkScalerContextEffects& effects,
51 const SkDescriptor* desc,
52 bool fakeIt)
53 : SkScalerContext(std::move(face), effects, desc)
54 , fProxy(getRandomTypeface()->proxy()->createScalerContext(SkScalerContextEffects(), desc))
55 , fFakeIt(fakeIt) {
56 fProxy->forceGenerateImageFromPath();
57}
58
60 SkArenaAlloc* alloc) {
61 // Here we will change the mask format of the glyph
62 // NOTE: this may be overridden by the base class (e.g. if a mask filter is applied).
64 switch (origGlyph.getGlyphID() % 4) {
65 case 0: format = SkMask::kLCD16_Format; break;
66 case 1: format = SkMask::kA8_Format; break;
67 case 2: format = SkMask::kARGB32_Format; break;
68 case 3: format = SkMask::kBW_Format; break;
69 }
70
71 auto glyph = fProxy->internalMakeGlyph(origGlyph.getPackedID(), format, alloc);
72
74 mx.advance = glyph.advanceVector();
75 mx.bounds = glyph.rect();
76 mx.maskFormat = glyph.maskFormat();
77 mx.extraBits = glyph.extraBits();
78
79 if (fFakeIt || (glyph.getGlyphID() % 4) != 2) {
80 mx.neverRequestPath = glyph.setPathHasBeenCalled() && !glyph.path();
82 return mx;
83 }
84
85 fProxy->getPath(glyph, alloc);
86 if (!glyph.path()) {
87 mx.neverRequestPath = true;
88 return mx;
89 }
90
91 // The proxy glyph has a path, but this glyph does not.
92 // Stash the proxy glyph so it can be used later.
93 const auto packedID = glyph.getPackedID();
94 const SkGlyph* proxyGlyph = fProxyGlyphs.set(packedID, std::move(glyph));
95 const SkPath& proxyPath = *proxyGlyph->path();
96
97 mx.neverRequestPath = true;
99 mx.advance = proxyGlyph->advanceVector();
100 mx.extraBits = proxyGlyph->extraBits();
101
102 SkRect storage;
103 const SkPaint& paint = this->getRandomTypeface()->paint();
104 const SkRect& newBounds =
105 paint.doComputeFastBounds(proxyPath.getBounds(), &storage, SkPaint::kFill_Style);
106 newBounds.roundOut(&mx.bounds);
107
108 return mx;
109}
110
111void RandomScalerContext::generateImage(const SkGlyph& glyph, void* imageBuffer) {
112 if (fFakeIt) {
113 sk_bzero(imageBuffer, glyph.imageSize());
114 return;
115 }
116
117 SkGlyph* proxyGlyph = fProxyGlyphs.find(glyph.getPackedID());
118 if (!proxyGlyph || !proxyGlyph->path()) {
119 fProxy->getImage(glyph);
120 return;
121 }
122 const SkPath& path = *proxyGlyph->path();
123 const bool hairline = proxyGlyph->pathIsHairline();
124
125 SkBitmap bm;
127 imageBuffer, glyph.rowBytes());
128 bm.eraseColor(0);
129
130 SkCanvas canvas(bm);
131 canvas.translate(-SkIntToScalar(glyph.left()), -SkIntToScalar(glyph.top()));
132 SkPaint paint = this->getRandomTypeface()->paint();
133 if (hairline) {
134 // We have a device path with effects already applied which is normally a fill path.
135 // However here we do not have a fill path and there is no area to fill.
137 paint.setStroke(0);
138 }
139 canvas.drawPath(path, paint); //Need to modify the paint if the devPath is hairline
140}
141
143 SkGlyph* shadowProxyGlyph = fProxyGlyphs.find(glyph.getPackedID());
144 if (shadowProxyGlyph && shadowProxyGlyph->path()) {
145 path->reset();
146 return false;
147 }
148 return fProxy->generatePath(glyph, path);
149}
150
152 SkGlyph* shadowProxyGlyph = fProxyGlyphs.find(glyph.getPackedID());
153 if (shadowProxyGlyph && shadowProxyGlyph->path()) {
154 return nullptr;
155 }
156 return fProxy->generateDrawable(glyph);
157}
158
160 fProxy->getFontMetrics(metrics);
161}
162
163///////////////////////////////////////////////////////////////////////////////
164
166 : SkTypeface(proxy->fontStyle(), false)
167 , fProxy(std::move(proxy))
168 , fPaint(paint)
169 , fFakeIt(fakeIt) {}
170
171std::unique_ptr<SkScalerContext> SkRandomTypeface::onCreateScalerContext(
172 const SkScalerContextEffects& effects, const SkDescriptor* desc) const
173{
174 return std::make_unique<RandomScalerContext>(
175 sk_ref_sp(const_cast<SkRandomTypeface*>(this)), effects, desc, fFakeIt);
176}
177
179 fProxy->filterRec(rec);
182}
183
185 fProxy->getGlyphToUnicodeMap(glyphToUnicode);
186}
187
188std::unique_ptr<SkAdvancedTypefaceMetrics> SkRandomTypeface::onGetAdvancedMetrics() const {
189 return fProxy->getAdvancedMetrics();
190}
191
192std::unique_ptr<SkStreamAsset> SkRandomTypeface::onOpenStream(int* ttcIndex) const {
193 return fProxy->openStream(ttcIndex);
194}
195
198 if (!proxy) {
199 return nullptr;
200 }
201 return sk_make_sp<SkRandomTypeface>(proxy, fPaint, fFakeIt);
202}
203
205 // TODO: anything that uses this typeface isn't correctly serializable, since this typeface
206 // cannot be deserialized.
207 fProxy->getFontDescriptor(desc, isLocal);
208}
209
211 fProxy->unicharsToGlyphs(uni, count, glyphs);
212}
213
214int SkRandomTypeface::onCountGlyphs() const { return fProxy->countGlyphs(); }
215
216int SkRandomTypeface::onGetUPEM() const { return fProxy->getUnitsPerEm(); }
217
219 fProxy->getFamilyName(familyName);
220}
221
223 return fProxy->getPostScriptName(postScriptName);
224}
225
227 return fProxy->createFamilyNameIterator();
228}
229
231 return fProxy->getPostScriptGlyphNames(names);
232}
233
235 return fProxy->glyphMaskNeedsCurrentColor();
236}
237
240 int coordinateCount) const {
241 return fProxy->onGetVariationDesignPosition(coordinates, coordinateCount);
242}
243
245 int parameterCount) const {
246 return fProxy->onGetVariationDesignParameters(parameters, parameterCount);
247}
248
250 return fProxy->getTableTags(tags);
251}
252
254 size_t offset,
255 size_t length,
256 void* data) const {
257 return fProxy->getTableData(tag, offset, length, data);
258}
const TextureProxy * fProxy
Definition: DrawPass.cpp:180
sk_bzero(glyphs, sizeof(glyphs))
uint16_t glyphs[5]
Definition: FontMgrTest.cpp:46
int count
Definition: FontMgrTest.cpp:50
@ kNone
glyph outlines unchanged
sk_sp< T > sk_ref_sp(T *obj)
Definition: SkRefCnt.h:381
#define SkIntToScalar(x)
Definition: SkScalar.h:57
uint32_t SkFontTableTag
Definition: SkTypeface.h:41
int32_t SkUnichar
Definition: SkTypes.h:175
uint16_t SkGlyphID
Definition: SkTypes.h:179
bool generatePath(const SkGlyph &, SkPath *) override
GlyphMetrics generateMetrics(const SkGlyph &, SkArenaAlloc *) override
void generateFontMetrics(SkFontMetrics *) override
sk_sp< SkDrawable > generateDrawable(const SkGlyph &) override
void generateImage(const SkGlyph &, void *) override
bool installPixels(const SkImageInfo &info, void *pixels, size_t rowBytes, void(*releaseProc)(void *addr, void *context), void *context)
Definition: SkBitmap.cpp:323
void eraseColor(SkColor4f) const
Definition: SkBitmap.cpp:442
void translate(SkScalar dx, SkScalar dy)
Definition: SkCanvas.cpp:1278
void drawPath(const SkPath &path, const SkPaint &paint)
Definition: SkCanvas.cpp:1747
int top() const
Definition: SkGlyph.h:511
size_t rowBytes() const
Definition: SkGlyph.cpp:233
uint16_t extraBits() const
Definition: SkGlyph.h:519
SkGlyphID getGlyphID() const
Definition: SkGlyph.h:429
size_t imageSize() const
Definition: SkGlyph.cpp:241
const SkPath * path() const
Definition: SkGlyph.cpp:284
bool pathIsHairline() const
Definition: SkGlyph.cpp:293
int height() const
Definition: SkGlyph.h:513
int width() const
Definition: SkGlyph.h:512
int left() const
Definition: SkGlyph.h:510
SkPackedGlyphID getPackedID() const
Definition: SkGlyph.h:430
SkVector advanceVector() const
Definition: SkGlyph.h:425
@ kStroke_Style
set to stroke geometry
Definition: SkPaint.h:194
@ kFill_Style
set to fill geometry
Definition: SkPaint.h:193
Definition: SkPath.h:59
const SkRect & getBounds() const
Definition: SkPath.cpp:430
void getPostScriptGlyphNames(SkString *) const override
SkTypeface::LocalizedStrings * onCreateFamilyNameIterator() const override
int onGetVariationDesignPosition(SkFontArguments::VariationPosition::Coordinate coordinates[], int coordinateCount) const override
void onGetFontDescriptor(SkFontDescriptor *, bool *isLocal) const override
int onGetTableTags(SkFontTableTag tags[]) const override
void onGetFamilyName(SkString *familyName) const override
const SkPaint & paint() const
int onCountGlyphs() const override
std::unique_ptr< SkStreamAsset > onOpenStream(int *ttcIndex) const override
std::unique_ptr< SkAdvancedTypefaceMetrics > onGetAdvancedMetrics() const override
void onFilterRec(SkScalerContextRec *) const override
sk_sp< SkTypeface > onMakeClone(const SkFontArguments &args) const override
std::unique_ptr< SkScalerContext > onCreateScalerContext(const SkScalerContextEffects &, const SkDescriptor *) const override
bool onGetPostScriptName(SkString *) const override
bool onGlyphMaskNeedsCurrentColor() const override
int onGetVariationDesignParameters(SkFontParameters::Variation::Axis parameters[], int parameterCount) const override
void onCharsToGlyphs(const SkUnichar *chars, int count, SkGlyphID glyphs[]) const override
void getGlyphToUnicodeMap(SkUnichar *) const override
SkTypeface * proxy() const
size_t onGetTableData(SkFontTableTag, size_t offset, size_t length, void *data) const override
int onGetUPEM() const override
SkTypeface * getTypeface() const
friend class RandomScalerContext
int countGlyphs() const
Definition: SkTypeface.cpp:432
LocalizedStrings * createFamilyNameIterator() const
Definition: SkTypeface.cpp:455
virtual void getPostScriptGlyphNames(SkString *) const =0
void getFontDescriptor(SkFontDescriptor *desc, bool *isLocal) const
Definition: SkTypeface.h:326
int getUnitsPerEm() const
Definition: SkTypeface.cpp:436
virtual void getGlyphToUnicodeMap(SkUnichar *dstArray) const =0
Definition: SkTypeface.cpp:468
void getFamilyName(SkString *name) const
Definition: SkTypeface.cpp:459
int getTableTags(SkFontTableTag tags[]) const
Definition: SkTypeface.cpp:305
void filterRec(SkScalerContextRec *rec) const
Definition: SkTypeface.h:322
friend class SkRandomTypeface
Definition: SkTypeface.h:420
bool getPostScriptName(SkString *name) const
Definition: SkTypeface.cpp:464
std::unique_ptr< SkStreamAsset > openStream(int *ttcIndex) const
Definition: SkTypeface.cpp:332
virtual int onGetVariationDesignParameters(SkFontParameters::Variation::Axis parameters[], int parameterCount) const =0
size_t getTableData(SkFontTableTag tag, size_t offset, size_t length, void *data) const
Definition: SkTypeface.cpp:313
void unicharsToGlyphs(const SkUnichar uni[], int count, SkGlyphID glyphs[]) const
Definition: SkTypeface.cpp:357
virtual int onGetVariationDesignPosition(SkFontArguments::VariationPosition::Coordinate coordinates[], int coordinateCount) const =0
sk_sp< SkTypeface > makeClone(const SkFontArguments &) const
Definition: SkTypeface.cpp:190
V * find(const K &key) const
Definition: SkTHash.h:494
V * set(K key, V val)
Definition: SkTHash.h:487
const Paint & paint
Definition: color_source.cc:38
G_BEGIN_DECLS G_MODULE_EXPORT FlValue * args
uint32_t uint32_t * format
size_t length
static const char *const names[]
Definition: symbols.cc:24
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot The VM snapshot data that will be memory mapped as read only SnapshotAssetPath must be present isolate snapshot The isolate snapshot data that will be memory mapped as read only SnapshotAssetPath must be present cache dir path
Definition: switches.h:57
Definition: ref_ptr.h:256
SeparatedVector2 offset
static SkImageInfo MakeN32Premul(int width, int height)
Format
Definition: SkMask.h:26
@ kA8_Format
8bits per pixel mask (e.g. antialiasing)
Definition: SkMask.h:28
@ kLCD16_Format
565 alpha for r/g/b
Definition: SkMask.h:31
@ kARGB32_Format
SkPMColor.
Definition: SkMask.h:30
@ kBW_Format
1bit per pixel mask (e.g. monochrome)
Definition: SkMask.h:27
void roundOut(SkIRect *dst) const
Definition: SkRect.h:1241
SkMask::Format fMaskFormat
void setHinting(SkFontHinting)
std::shared_ptr< const fml::Mapping > data
Definition: texture_gles.cc:63