Flutter Engine
The Flutter Engine
Functions
texteffects.cpp File Reference
#include "gm/gm.h"
#include "include/core/SkCanvas.h"
#include "include/core/SkFont.h"
#include "include/core/SkFontStyle.h"
#include "include/core/SkFontTypes.h"
#include "include/core/SkPaint.h"
#include "include/core/SkPath.h"
#include "include/core/SkPoint.h"
#include "include/core/SkRect.h"
#include "include/core/SkRefCnt.h"
#include "include/core/SkScalar.h"
#include "include/core/SkTextBlob.h"
#include "include/core/SkTypeface.h"
#include "include/core/SkTypes.h"
#include "include/private/base/SkTDArray.h"
#include "include/private/base/SkTemplates.h"
#include "include/private/base/SkTo.h"
#include "tools/ToolUtils.h"
#include "tools/fonts/FontToolUtils.h"
#include <string.h>

Go to the source code of this file.

Functions

static SkPath create_underline (const SkTDArray< SkScalar > &intersections, SkScalar last, SkScalar finalPos, SkScalar uPos, SkScalar uWidth, SkScalar textSize)
 
 DEF_SIMPLE_GM (fancyblobunderline, canvas, 1480, 1380)
 
static sk_sp< SkTextBlobmake_text (const SkFont &font, const SkGlyphID glyphs[], int count)
 
static sk_sp< SkTextBlobmake_posh (const SkFont &font, const SkGlyphID glyphs[], int count, SkScalar spacing)
 
static sk_sp< SkTextBlobmake_pos (const SkFont &font, const SkGlyphID glyphs[], int count, SkScalar spacing)
 
static int trim_with_halo (SkScalar intervals[], int count, SkScalar margin)
 
static void draw_blob_adorned (SkCanvas *canvas, sk_sp< SkTextBlob > blob)
 
 DEF_SIMPLE_GM (textblob_intercepts, canvas, 940, 800)
 

Function Documentation

◆ create_underline()

static SkPath create_underline ( const SkTDArray< SkScalar > &  intersections,
SkScalar  last,
SkScalar  finalPos,
SkScalar  uPos,
SkScalar  uWidth,
SkScalar  textSize 
)
static

Definition at line 32 of file texteffects.cpp.

34 {
35 SkPath underline;
36 SkScalar end = last;
37 for (int index = 0; index < intersections.size(); index += 2) {
38 SkScalar start = intersections[index] - uWidth;
39 end = intersections[index + 1] + uWidth;
40 if (start > last && last + textSize / 12 < start) {
41 underline.moveTo(last, uPos);
42 underline.lineTo(start, uPos);
43 }
44 last = end;
45 }
46 if (end < finalPos) {
47 underline.moveTo(end, uPos);
48 underline.lineTo(finalPos, uPos);
49 }
50 return underline;
51}
Definition: SkPath.h:59
SkPath & moveTo(SkScalar x, SkScalar y)
Definition: SkPath.cpp:688
SkPath & lineTo(SkScalar x, SkScalar y)
Definition: SkPath.cpp:728
int size() const
Definition: SkTDArray.h:138
float SkScalar
Definition: extension.cpp:12
glong glong end

◆ DEF_SIMPLE_GM() [1/2]

DEF_SIMPLE_GM ( fancyblobunderline  ,
canvas  ,
1480  ,
1380   
)

Definition at line 112 of file texteffects.cpp.

112 {
114 paint.setAntiAlias(true);
115 const char* fam[] = { "sans-serif", "serif", "monospace" };
116 const char test[] = "aAjJgGyY_|{-(~[,]qQ}pP}zZ";
117 const SkPoint blobOffset = { 10, 80 };
118
119 for (size_t font = 0; font < std::size(fam); ++font) {
120 for (SkScalar textSize = 100; textSize > 10; textSize -= 20) {
121 SkFont skFont(ToolUtils::CreatePortableTypeface(fam[font], SkFontStyle()), textSize);
122 const SkScalar uWidth = textSize / 15;
123 paint.setStrokeWidth(uWidth);
124 paint.setStyle(SkPaint::kFill_Style);
125
126 sk_sp<SkTextBlob> blob = MakeFancyBlob(paint, skFont, test);
127 canvas->drawTextBlob(blob, blobOffset.x(), blobOffset.y(), paint);
128
129 const SkScalar uPos = uWidth;
130 const SkScalar bounds[2] = { uPos - uWidth / 2, uPos + uWidth / 2 };
131 const int interceptCount = blob->getIntercepts(bounds, nullptr, &paint);
132 SkASSERT(!(interceptCount % 2));
133
134 SkTDArray<SkScalar> intercepts;
135 intercepts.resize(interceptCount);
136 blob->getIntercepts(bounds, intercepts.begin(), &paint);
137
138 const SkScalar start = blob->bounds().left();
139 const SkScalar end = blob->bounds().right();
140 SkPath underline = create_underline(intercepts, start, end, uPos, uWidth, textSize);
141 underline.offset(blobOffset.x(), blobOffset.y());
143 canvas->drawPath(underline, paint);
144
145 canvas->translate(0, textSize * 1.3f);
146 }
147
148 canvas->translate(0, 60);
149 }
150}
#define SkASSERT(cond)
Definition: SkAssert.h:116
Definition: SkFont.h:35
@ kStroke_Style
set to stroke geometry
Definition: SkPaint.h:194
@ kFill_Style
set to fill geometry
Definition: SkPaint.h:193
void offset(SkScalar dx, SkScalar dy, SkPath *dst) const
Definition: SkPath.cpp:1691
T * begin()
Definition: SkTDArray.h:150
void resize(int count)
Definition: SkTDArray.h:183
int getIntercepts(const SkScalar bounds[2], SkScalar intervals[], const SkPaint *paint=nullptr) const
Definition: SkTextBlob.cpp:927
const SkRect & bounds() const
Definition: SkTextBlob.h:53
const Paint & paint
Definition: color_source.cc:38
Optional< SkRect > bounds
Definition: SkRecords.h:189
sk_sp< SkTypeface > CreatePortableTypeface(const char *name, SkFontStyle style)
it will be possible to load the file into Perfetto s trace viewer disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font Indicates whether the embedding started a prefetch of the default font manager before creating the engine run In non interactive keep the shell running after the Dart script has completed enable serial On low power devices with low core running concurrent GC tasks on threads can cause them to contend with the UI thread which could potentially lead to jank This option turns off all concurrent GC activities domain network JSON encoded network policy per domain This overrides the DisallowInsecureConnections switch Embedder can specify whether to allow or disallow insecure connections at a domain level old gen heap size
Definition: switches.h:259
font
Font Metadata and Metrics.
constexpr float y() const
Definition: SkPoint_impl.h:187
constexpr float x() const
Definition: SkPoint_impl.h:181
constexpr float left() const
Definition: SkRect.h:734
constexpr float right() const
Definition: SkRect.h:748
static SkPath create_underline(const SkTDArray< SkScalar > &intersections, SkScalar last, SkScalar finalPos, SkScalar uPos, SkScalar uWidth, SkScalar textSize)
Definition: texteffects.cpp:32

◆ DEF_SIMPLE_GM() [2/2]

DEF_SIMPLE_GM ( textblob_intercepts  ,
canvas  ,
940  ,
800   
)

Definition at line 240 of file texteffects.cpp.

240 {
241 const char text[] = "Hyjay {worlp}.";
242 const size_t length = strlen(text);
244 font.setSize(100);
246 const int count = font.countText(text, length, SkTextEncoding::kUTF8);
248 font.textToGlyphs(text, length, SkTextEncoding::kUTF8, glyphs.get(), count);
249
250 auto b0 = make_text(font, glyphs.get(), count);
251
252 canvas->translate(20, 120);
253 draw_blob_adorned(canvas, b0);
254 for (SkScalar spacing = 0; spacing < 30; spacing += 20) {
255 auto b1 = make_posh(font, glyphs.get(), count, spacing);
256 auto b2 = make_pos( font, glyphs.get(), count, spacing);
257 canvas->translate(0, 150);
258 draw_blob_adorned(canvas, b1);
259 canvas->translate(0, 150);
260 draw_blob_adorned(canvas, b2);
261 }
262}
uint16_t glyphs[5]
Definition: FontMgrTest.cpp:46
int count
Definition: FontMgrTest.cpp:50
@ kUTF8
uses bytes to represent UTF-8 or ASCII
@ kAntiAlias
may have transparent pixels on glyph edges
size_t length
std::u16string text
SkFont DefaultPortableFont()
static void draw_blob_adorned(SkCanvas *canvas, sk_sp< SkTextBlob > blob)
static sk_sp< SkTextBlob > make_text(const SkFont &font, const SkGlyphID glyphs[], int count)
static sk_sp< SkTextBlob > make_posh(const SkFont &font, const SkGlyphID glyphs[], int count, SkScalar spacing)
static sk_sp< SkTextBlob > make_pos(const SkFont &font, const SkGlyphID glyphs[], int count, SkScalar spacing)

◆ draw_blob_adorned()

static void draw_blob_adorned ( SkCanvas canvas,
sk_sp< SkTextBlob blob 
)
static

Definition at line 207 of file texteffects.cpp.

207 {
209
210 canvas->drawTextBlob(blob.get(), 0, 0, paint);
211
212 const SkScalar yminmax[] = { 8, 16 };
213 int count = blob->getIntercepts(yminmax, nullptr);
214 if (!count) {
215 return;
216 }
217
218 AutoTArray<SkScalar> intervals(count);
219 blob->getIntercepts(yminmax, intervals.get());
220 count = trim_with_halo(intervals.get(), count, SkScalarHalf(yminmax[1] - yminmax[0]) * 1.5f);
221 SkASSERT(count >= 2);
222
223 const SkScalar y = SkScalarAve(yminmax[0], yminmax[1]);
224 SkScalar end = 900;
225 SkPath path;
226 path.moveTo({0, y});
227 for (int i = 0; i < count; i += 2) {
228 path.lineTo(intervals[i], y).moveTo(intervals[i+1], y);
229 }
230 if (intervals[count - 1] < end) {
231 path.lineTo(end, y);
232 }
233
234 paint.setAntiAlias(true);
236 paint.setStrokeWidth(yminmax[1] - yminmax[0]);
237 canvas->drawPath(path, paint);
238}
#define SkScalarHalf(a)
Definition: SkScalar.h:75
#define SkScalarAve(a, b)
Definition: SkScalar.h:74
void drawPath(const SkPath &path, const SkPaint &paint)
Definition: SkCanvas.cpp:1747
void drawTextBlob(const SkTextBlob *blob, SkScalar x, SkScalar y, const SkPaint &paint)
Definition: SkCanvas.cpp:2484
T * get() const
Definition: SkRefCnt.h:303
double y
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
static int trim_with_halo(SkScalar intervals[], int count, SkScalar margin)

◆ make_pos()

static sk_sp< SkTextBlob > make_pos ( const SkFont font,
const SkGlyphID  glyphs[],
int  count,
SkScalar  spacing 
)
static

Definition at line 170 of file texteffects.cpp.

171 {
173 font.getPos(glyphs, count, pos.get());
174 for (int i = 1; i < count; ++i) {
175 pos[i].fX += spacing * i;
176 }
177 return SkTextBlob::MakeFromPosText(glyphs, count * sizeof(SkGlyphID), pos.get(), font,
179}
SkPoint pos
@ kGlyphID
uses two byte words to represent glyph indices
uint16_t SkGlyphID
Definition: SkTypes.h:179
static sk_sp< SkTextBlob > MakeFromPosText(const void *text, size_t byteLength, const SkPoint pos[], const SkFont &font, SkTextEncoding encoding=SkTextEncoding::kUTF8)
Definition: SkTextBlob.cpp:803
float fX
x-axis value
Definition: SkPoint_impl.h:164

◆ make_posh()

static sk_sp< SkTextBlob > make_posh ( const SkFont font,
const SkGlyphID  glyphs[],
int  count,
SkScalar  spacing 
)
static

Definition at line 159 of file texteffects.cpp.

160 {
162 font.getXPos(glyphs, count, xpos.get());
163 for (int i = 1; i < count; ++i) {
164 xpos[i] += spacing * i;
165 }
166 return SkTextBlob::MakeFromPosTextH(glyphs, count * sizeof(SkGlyphID), xpos.get(), 0, font,
168}
static sk_sp< SkTextBlob > MakeFromPosTextH(const void *text, size_t byteLength, const SkScalar xpos[], SkScalar constY, const SkFont &font, SkTextEncoding encoding=SkTextEncoding::kUTF8)
Definition: SkTextBlob.cpp:817

◆ make_text()

static sk_sp< SkTextBlob > make_text ( const SkFont font,
const SkGlyphID  glyphs[],
int  count 
)
static

Definition at line 154 of file texteffects.cpp.

154 {
157}
static sk_sp< SkTextBlob > MakeFromText(const void *text, size_t byteLength, const SkFont &font, SkTextEncoding encoding=SkTextEncoding::kUTF8)
Definition: SkTextBlob.cpp:788

◆ trim_with_halo()

static int trim_with_halo ( SkScalar  intervals[],
int  count,
SkScalar  margin 
)
static

Definition at line 182 of file texteffects.cpp.

182 {
183 SkASSERT(count > 0 && (count & 1) == 0);
184
185 int n = count;
186 SkScalar* stop = intervals + count;
187 *intervals++ -= margin;
188 while (intervals < stop - 1) {
189 intervals[0] += margin;
190 intervals[1] -= margin;
191 if (intervals[0] >= intervals[1]) { // went away
192 int remaining = stop - intervals - 2;
193 SkASSERT(remaining >= 0 && (remaining & 1) == 1);
194 if (remaining > 0) {
195 memmove(intervals, intervals + 2, remaining * sizeof(SkScalar));
196 }
197 stop -= 2;
198 n -= 2;
199 } else {
200 intervals += 2;
201 }
202 }
203 *intervals += margin;
204 return n;
205}