Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
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
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
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:181
uint16_t glyphs[5]
int count
@ kNone
glyph outlines unchanged
static void sk_bzero(void *buffer, size_t size)
Definition SkMalloc.h:105
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)
void drawPath(const SkPath &path, const SkPaint &paint)
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
const SkRect & getBounds() const
Definition SkPath.cpp:420
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
LocalizedStrings * createFamilyNameIterator() const
virtual void getPostScriptGlyphNames(SkString *) const =0
void getFontDescriptor(SkFontDescriptor *desc, bool *isLocal) const
Definition SkTypeface.h:326
int getUnitsPerEm() const
virtual void getGlyphToUnicodeMap(SkUnichar *dstArray) const =0
void getFamilyName(SkString *name) const
int getTableTags(SkFontTableTag tags[]) const
void filterRec(SkScalerContextRec *rec) const
Definition SkTypeface.h:322
friend class SkRandomTypeface
Definition SkTypeface.h:420
bool getPostScriptName(SkString *name) const
std::unique_ptr< SkStreamAsset > openStream(int *ttcIndex) const
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
void unicharsToGlyphs(const SkUnichar uni[], int count, SkGlyphID glyphs[]) const
virtual int onGetVariationDesignPosition(SkFontArguments::VariationPosition::Coordinate coordinates[], int coordinateCount) const =0
sk_sp< SkTypeface > makeClone(const SkFontArguments &) const
V * find(const K &key) const
Definition SkTHash.h:479
V * set(K key, V val)
Definition SkTHash.h:472
const Paint & paint
G_BEGIN_DECLS G_MODULE_EXPORT FlValue * args
uint32_t uint32_t * format
size_t length
Definition ref_ptr.h:256
Point 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)