blob: 8af62ba3cd65ae438985e2c0be508a58ce99d40c [file] [log] [blame]
Cary Clark0c5f5462017-12-15 11:21:51 -05001#Topic Paint
Cary Clark137b8742018-05-30 09:21:49 -04002#Alias Paint_Reference ##
Cary Clark8032b982017-07-28 11:04:54 -04003
Cary Clark61313f32018-10-08 14:57:48 -04004#PhraseDef paint_font_metrics
5Typeface, Paint_Text_Size, Paint_Text_Scale_X,
6Paint_Text_Skew_X, Paint_Text_Align, Paint_Hinting, Anti_Alias, Paint_Fake_Bold,
7Font_Embedded_Bitmaps, Full_Hinting_Spacing, LCD_Text, Linear_Text,
8and Subpixel_Text
9##
10
Cary Clarke4aa3712017-09-15 02:56:12 -040011#Class SkPaint
12
Cary Clark61313f32018-10-08 14:57:48 -040013#Code
14#Populate
15##
16
Cary Clark8032b982017-07-28 11:04:54 -040017Paint controls options applied when drawing and measuring. Paint collects all
18options outside of the Canvas_Clip and Canvas_Matrix.
19
Herb Derbyfcac00f2018-05-01 11:57:56 -040020Various options apply to text, strokes and fills, and images.
Cary Clark8032b982017-07-28 11:04:54 -040021
22Some options may not be implemented on all platforms; in these cases, setting
23the option has no effect. Some options are conveniences that duplicate Canvas
24functionality; for instance, text size is identical to matrix scale.
25
26Paint options are rarely exclusive; each option modifies a stage of the drawing
27pipeline and multiple pipeline stages may be affected by a single Paint.
28
Herb Derbyfcac00f2018-05-01 11:57:56 -040029Paint collects effects and filters that describe single-pass and multiple-pass
Cary Clark8032b982017-07-28 11:04:54 -040030algorithms that alter the drawing geometry, color, and transparency. For instance,
Herb Derbyfcac00f2018-05-01 11:57:56 -040031Paint does not directly implement dashing or blur, but contains the objects that do so.
Cary Clark8032b982017-07-28 11:04:54 -040032
33The objects contained by Paint are opaque, and cannot be edited outside of the Paint
34to affect it. The implementation is free to defer computations associated with the
35Paint, or ignore them altogether. For instance, some GPU implementations draw all
Cary Clarkffb3d682018-05-17 12:17:28 -040036Path geometries with Anti_Aliasing, regardless of how SkPaint::kAntiAlias_Flag
Cary Clarkbad5ad72017-08-03 17:14:08 -040037is set in Paint.
Cary Clark8032b982017-07-28 11:04:54 -040038
39Paint describes a single color, a single font, a single image quality, and so on.
40Multiple colors are drawn either by using multiple paints or with objects like
41Shader attached to Paint.
42
Cary Clark08895c42018-02-01 09:37:32 -050043#Subtopic Initializers
44#Line # constructors and initialization ##
Cary Clark8032b982017-07-28 11:04:54 -040045
46#Method SkPaint()
47
Cary Clarkab2621d2018-01-30 10:08:57 -050048#In Initializers
49#Line # constructs with default values ##
Cary Clark8032b982017-07-28 11:04:54 -040050Constructs Paint with default values.
51
52#Table
53#Legend
54# attribute # default value ##
55#Legend ##
Cary Clarkffb3d682018-05-17 12:17:28 -040056# Anti_Alias # false ##
Cary Clarkce101242017-09-01 15:51:02 -040057# Blend_Mode # SkBlendMode::kSrcOver ##
Cary Clark8032b982017-07-28 11:04:54 -040058# Color # SK_ColorBLACK ##
59# Color_Alpha # 255 ##
60# Color_Filter # nullptr ##
61# Dither # false ##
62# Draw_Looper # nullptr ##
63# Fake_Bold # false ##
64# Filter_Quality # kNone_SkFilterQuality ##
65# Font_Embedded_Bitmaps # false ##
66# Automatic_Hinting # false ##
67# Full_Hinting_Spacing # false ##
68# Hinting # kNormal_Hinting ##
69# Image_Filter # nullptr ##
70# LCD_Text # false ##
71# Linear_Text # false ##
72# Miter_Limit # 4 ##
73# Mask_Filter # nullptr ##
74# Path_Effect # nullptr ##
Cary Clark8032b982017-07-28 11:04:54 -040075# Shader # nullptr ##
76# Style # kFill_Style ##
77# Text_Align # kLeft_Align ##
78# Text_Encoding # kUTF8_TextEncoding ##
79# Text_Scale_X # 1 ##
80# Text_Size # 12 ##
81# Text_Skew_X # 0 ##
82# Typeface # nullptr ##
83# Stroke_Cap # kButt_Cap ##
84# Stroke_Join # kMiter_Join ##
85# Stroke_Width # 0 ##
86# Subpixel_Text # false ##
87# Vertical_Text # false ##
88#Table ##
89
90The flags, text size, hinting, and miter limit may be overridden at compile time by defining
Herb Derbyfcac00f2018-05-01 11:57:56 -040091paint default values. The overrides may be included in "SkUserConfig.h" or predefined by the
Cary Clark8032b982017-07-28 11:04:54 -040092build system.
93
94#Return default initialized Paint ##
95
96#Example
97#ToDo mark this as no output ##
98#Height 1
99###$ $ redefine markup character so preprocessor commands appear normally
100#ifndef SkUserConfig_DEFINED
101#define SkUserConfig_DEFINED
102
103#define SkPaintDefaults_Flags 0x01 // always enable antialiasing
104#define SkPaintDefaults_TextSize 24.f // double default font size
105#define SkPaintDefaults_Hinting 3 // use full hinting
106#define SkPaintDefaults_MiterLimit 10.f // use HTML Canvas miter limit setting
107
108#endif
109$$$# # restore original markup character
110##
111
112
113##
114
115#Method SkPaint(const SkPaint& paint)
116
Cary Clarkab2621d2018-01-30 10:08:57 -0500117#In Initializers
118#Line # makes a shallow copy ##
Cary Clark8032b982017-07-28 11:04:54 -0400119Makes a shallow copy of Paint. Typeface, Path_Effect, Shader,
Mike Reed8ad91a92018-01-19 19:09:32 -0500120Mask_Filter, Color_Filter, Draw_Looper, and Image_Filter are shared
Cary Clarkbad5ad72017-08-03 17:14:08 -0400121between the original paint and the copy. Objects containing Reference_Count increment
122their references by one.
Cary Clark8032b982017-07-28 11:04:54 -0400123
Mike Reed8ad91a92018-01-19 19:09:32 -0500124The referenced objects Path_Effect, Shader, Mask_Filter, Color_Filter,
Cary Clark8032b982017-07-28 11:04:54 -0400125Draw_Looper, and Image_Filter cannot be modified after they are created.
126This prevents objects with Reference_Count from being modified once Paint refers to them.
127
128#Param paint original to copy ##
129
130#Return shallow copy of paint ##
131
132#Example
133#ToDo why is this double-spaced on Fiddle? ##
134 SkPaint paint1;
135 paint1.setColor(SK_ColorRED);
136 SkPaint paint2(paint1);
137 paint2.setColor(SK_ColorBLUE);
138 SkDebugf("SK_ColorRED %c= paint1.getColor()\n", SK_ColorRED == paint1.getColor() ? '=' : '!');
139 SkDebugf("SK_ColorBLUE %c= paint2.getColor()\n", SK_ColorBLUE == paint2.getColor() ? '=' : '!');
140
141 #StdOut
142 SK_ColorRED == paint1.getColor()
143 SK_ColorBLUE == paint2.getColor()
144 ##
145##
146
147##
148
149#Method SkPaint(SkPaint&& paint)
150
Cary Clarkab2621d2018-01-30 10:08:57 -0500151#In Initializers
152#Line # moves paint without copying it ##
Cary Clarkd0530ba2017-09-14 11:25:39 -0400153 Implements a move constructor to avoid increasing the reference counts
Cary Clark8032b982017-07-28 11:04:54 -0400154 of objects referenced by the paint.
155
156 After the call, paint is undefined, and can be safely destructed.
157
158 #Param paint original to move ##
159
160 #Return content of paint ##
161
162 #Example
163 SkPaint paint;
164 float intervals[] = { 5, 5 };
165 paint.setPathEffect(SkDashPathEffect::Make(intervals, SK_ARRAY_COUNT(intervals), 2.5f));
166 SkPaint dashed(std::move(paint));
167 SkDebugf("path effect unique: %s\n", dashed.getPathEffect()->unique() ? "true" : "false");
168
169 #StdOut
170 path effect unique: true
171 ##
172 ##
173
174##
175
176# ------------------------------------------------------------------------------
177
178#Method void reset()
179
Cary Clarkab2621d2018-01-30 10:08:57 -0500180#In Initializers
181#Line # sets to default values ##
Cary Clarkbc5697d2017-10-04 14:31:33 -0400182Sets all Paint contents to their initial values. This is equivalent to replacing
183Paint with the result of SkPaint().
Cary Clark8032b982017-07-28 11:04:54 -0400184
185#Example
186 SkPaint paint1, paint2;
187 paint1.setColor(SK_ColorRED);
188 paint1.reset();
189 SkDebugf("paint1 %c= paint2", paint1 == paint2 ? '=' : '!');
190
191 #StdOut
192 paint1 == paint2
193 ##
194##
195
196##
197
Cary Clark08895c42018-02-01 09:37:32 -0500198#Subtopic Initializers ##
Cary Clark8032b982017-07-28 11:04:54 -0400199
200# ------------------------------------------------------------------------------
Cary Clark8032b982017-07-28 11:04:54 -0400201
202#Method ~SkPaint()
203
Cary Clarkab2621d2018-01-30 10:08:57 -0500204#Line # decreases Reference_Count of owned objects ##
Cary Clark8032b982017-07-28 11:04:54 -0400205Decreases Paint Reference_Count of owned objects: Typeface, Path_Effect, Shader,
Mike Reed8ad91a92018-01-19 19:09:32 -0500206Mask_Filter, Color_Filter, Draw_Looper, and Image_Filter. If the
Cary Clarkbad5ad72017-08-03 17:14:08 -0400207objects containing Reference_Count go to zero, they are deleted.
Cary Clark8032b982017-07-28 11:04:54 -0400208
Herb Derbyfcac00f2018-05-01 11:57:56 -0400209#NoExample
Cary Clark8032b982017-07-28 11:04:54 -0400210##
211
212##
213
Cary Clark08895c42018-02-01 09:37:32 -0500214
Cary Clark8032b982017-07-28 11:04:54 -0400215# ------------------------------------------------------------------------------
Cary Clark61313f32018-10-08 14:57:48 -0400216
Cary Clark08895c42018-02-01 09:37:32 -0500217#Subtopic Management
218#Line # paint copying, moving, comparing ##
Cary Clark8032b982017-07-28 11:04:54 -0400219
220#Method SkPaint& operator=(const SkPaint& paint)
221
Cary Clarkab2621d2018-01-30 10:08:57 -0500222#In Management
223#Line # makes a shallow copy ##
Cary Clark8032b982017-07-28 11:04:54 -0400224Makes a shallow copy of Paint. Typeface, Path_Effect, Shader,
Mike Reed8ad91a92018-01-19 19:09:32 -0500225Mask_Filter, Color_Filter, Draw_Looper, and Image_Filter are shared
Cary Clarkbad5ad72017-08-03 17:14:08 -0400226between the original paint and the copy. Objects containing Reference_Count in the
Cary Clark8032b982017-07-28 11:04:54 -0400227prior destination are decreased by one, and the referenced objects are deleted if the
Cary Clarkbad5ad72017-08-03 17:14:08 -0400228resulting count is zero. Objects containing Reference_Count in the parameter paint
229are increased by one. paint is unmodified.
Cary Clark8032b982017-07-28 11:04:54 -0400230
231#Param paint original to copy ##
232
233#Return content of paint ##
234
235#Example
236 SkPaint paint1, paint2;
237 paint1.setColor(SK_ColorRED);
238 paint2 = paint1;
239 SkDebugf("SK_ColorRED %c= paint1.getColor()\n", SK_ColorRED == paint1.getColor() ? '=' : '!');
240 SkDebugf("SK_ColorRED %c= paint2.getColor()\n", SK_ColorRED == paint2.getColor() ? '=' : '!');
241
242 #StdOut
243 SK_ColorRED == paint1.getColor()
244 SK_ColorRED == paint2.getColor()
245 ##
246##
247
248##
249
250# ------------------------------------------------------------------------------
251
252#Method SkPaint& operator=(SkPaint&& paint)
253
Cary Clarkab2621d2018-01-30 10:08:57 -0500254#In Management
255#Line # moves paint without copying it ##
Cary Clarkd0530ba2017-09-14 11:25:39 -0400256Moves the paint to avoid increasing the reference counts
Cary Clarkbad5ad72017-08-03 17:14:08 -0400257of objects referenced by the paint parameter. Objects containing Reference_Count in the
258prior destination are decreased by one; those objects are deleted if the resulting count
259is zero.
Cary Clark8032b982017-07-28 11:04:54 -0400260
261After the call, paint is undefined, and can be safely destructed.
262
263 #Param paint original to move ##
264
265 #Return content of paint ##
266
267#Example
268 SkPaint paint1, paint2;
269 paint1.setColor(SK_ColorRED);
270 paint2 = std::move(paint1);
271 SkDebugf("SK_ColorRED == paint2.getColor()\n", SK_ColorRED == paint2.getColor() ? '=' : '!');
272
273 #StdOut
274 SK_ColorRED == paint2.getColor()
275 ##
276##
277
278##
279
280# ------------------------------------------------------------------------------
281
282#Method bool operator==(const SkPaint& a, const SkPaint& b)
283
Cary Clarkab2621d2018-01-30 10:08:57 -0500284#In Management
285#Line # compares paints for equality ##
Cary Clark8032b982017-07-28 11:04:54 -0400286 Compares a and b, and returns true if a and b are equivalent. May return false
Mike Reed8ad91a92018-01-19 19:09:32 -0500287 if Typeface, Path_Effect, Shader, Mask_Filter, Color_Filter,
Cary Clark8032b982017-07-28 11:04:54 -0400288 Draw_Looper, or Image_Filter have identical contents but different pointers.
289
290 #Param a Paint to compare ##
291 #Param b Paint to compare ##
292
293 #Return true if Paint pair are equivalent ##
294
295 #Example
296 SkPaint paint1, paint2;
297 paint1.setColor(SK_ColorRED);
298 paint2.setColor(0xFFFF0000);
299 SkDebugf("paint1 %c= paint2\n", paint1 == paint2 ? '=' : '!');
300 float intervals[] = { 5, 5 };
301 paint1.setPathEffect(SkDashPathEffect::Make(intervals, 2, 2.5f));
302 paint2.setPathEffect(SkDashPathEffect::Make(intervals, 2, 2.5f));
303 SkDebugf("paint1 %c= paint2\n", paint1 == paint2 ? '=' : '!');
304
305 #StdOut
306 paint1 == paint2
307 paint1 != paint2
308 ##
309 ##
Cary Clark06c20f32018-03-20 15:53:27 -0400310#SeeAlso operator!=(const SkPaint& a, const SkPaint& b)
Cary Clark8032b982017-07-28 11:04:54 -0400311##
312
313# ------------------------------------------------------------------------------
314
315#Method bool operator!=(const SkPaint& a, const SkPaint& b)
316
Cary Clarkab2621d2018-01-30 10:08:57 -0500317#In Management
318#Line # compares paints for inequality ##
Cary Clark8032b982017-07-28 11:04:54 -0400319 Compares a and b, and returns true if a and b are not equivalent. May return true
Mike Reed8ad91a92018-01-19 19:09:32 -0500320 if Typeface, Path_Effect, Shader, Mask_Filter, Color_Filter,
Cary Clark8032b982017-07-28 11:04:54 -0400321 Draw_Looper, or Image_Filter have identical contents but different pointers.
322
323 #Param a Paint to compare ##
324 #Param b Paint to compare ##
325
326 #Return true if Paint pair are not equivalent ##
327
328#Example
329 SkPaint paint1, paint2;
330 paint1.setColor(SK_ColorRED);
331 paint2.setColor(0xFFFF0000);
332 SkDebugf("paint1 %c= paint2\n", paint1 == paint2 ? '=' : '!');
333 SkDebugf("paint1 %c= paint2\n", paint1 != paint2 ? '!' : '=');
334
335 #StdOut
336 paint1 == paint2
337 paint1 == paint2
338 ##
339##
Cary Clark06c20f32018-03-20 15:53:27 -0400340#SeeAlso operator==(const SkPaint& a, const SkPaint& b)
Cary Clark8032b982017-07-28 11:04:54 -0400341##
342
343# ------------------------------------------------------------------------------
344
345#Method uint32_t getHash() const
346
Cary Clarkab2621d2018-01-30 10:08:57 -0500347#In Management
348#Line # returns a shallow hash for equality checks ##
Cary Clark8032b982017-07-28 11:04:54 -0400349Returns a hash generated from Paint values and pointers.
350Identical hashes guarantee that the paints are
351equivalent, but differing hashes do not guarantee that the paints have differing
352contents.
353
354If operator==(const SkPaint& a, const SkPaint& b) returns true for two paints,
355their hashes are also equal.
356
357The hash returned is platform and implementation specific.
358
359#Return a shallow hash ##
360
361#Example
362 SkPaint paint1, paint2;
363 paint1.setColor(SK_ColorRED);
364 paint2.setColor(0xFFFF0000);
365 SkDebugf("paint1 %c= paint2\n", paint1 == paint2 ? '=' : '!');
366 SkDebugf("paint1.getHash() %c= paint2.getHash()\n",
367 paint1.getHash() == paint2.getHash() ? '=' : '!');
368
369 #StdOut
370 paint1 == paint2
371 paint1.getHash() == paint2.getHash()
372 ##
373##
374
375##
376
Cary Clark08895c42018-02-01 09:37:32 -0500377#Subtopic Management ##
Cary Clark8032b982017-07-28 11:04:54 -0400378
379# ------------------------------------------------------------------------------
Cary Clark61313f32018-10-08 14:57:48 -0400380
Cary Clark08895c42018-02-01 09:37:32 -0500381#Subtopic Hinting
382#Line # glyph outline adjustment ##
Cary Clark8032b982017-07-28 11:04:54 -0400383
384#Enum Hinting
Cary Clark08895c42018-02-01 09:37:32 -0500385#Line # level of glyph outline adjustment ##
Cary Clark8032b982017-07-28 11:04:54 -0400386
387#Code
388 enum Hinting {
389 kNo_Hinting = 0,
390 kSlight_Hinting = 1,
391 kNormal_Hinting = 2,
Cary Clarkbad5ad72017-08-03 17:14:08 -0400392 kFull_Hinting = 3,
Cary Clark8032b982017-07-28 11:04:54 -0400393 };
394##
395
396Hinting adjusts the glyph outlines so that the shape provides a uniform
397look at a given point size on font engines that support it. Hinting may have a
398muted effect or no effect at all depending on the platform.
399
400The four levels roughly control corresponding features on platforms that use FreeType
401as the Font_Engine.
402
403#Const kNo_Hinting 0
Cary Clark682c58d2018-05-16 07:07:07 -0400404#Line # glyph outlines unchanged ##
Cary Clark8032b982017-07-28 11:04:54 -0400405 Leaves glyph outlines unchanged from their native representation.
406 With FreeType, this is equivalent to the FT_LOAD_NO_HINTING
407 bit-field constant supplied to FT_Load_Glyph, which indicates that the vector
408 outline being loaded should not be fitted to the pixel grid but simply scaled
409 to 26.6 fractional pixels.
410##
411#Const kSlight_Hinting 1
Cary Clark682c58d2018-05-16 07:07:07 -0400412#Line # minimal modification to improve constrast ##
Cary Clark8032b982017-07-28 11:04:54 -0400413 Modifies glyph outlines minimally to improve constrast.
414 With FreeType, this is equivalent in spirit to the
Herb Derbyfcac00f2018-05-01 11:57:56 -0400415 FT_LOAD_TARGET_LIGHT value supplied to FT_Load_Glyph. It chooses a
Cary Clark8032b982017-07-28 11:04:54 -0400416 lighter hinting algorithm for non-monochrome modes.
Cary Clarkce101242017-09-01 15:51:02 -0400417 Generated Glyphs may be fuzzy but better resemble their original shape.
Cary Clark8032b982017-07-28 11:04:54 -0400418##
419#Const kNormal_Hinting 2
Cary Clark682c58d2018-05-16 07:07:07 -0400420#Line # glyph outlines modified to improve constrast ##
Cary Clark8032b982017-07-28 11:04:54 -0400421 Modifies glyph outlines to improve constrast. This is the default.
Cary Clark6fc50412017-09-21 12:31:06 -0400422 With FreeType, this supplies FT_LOAD_TARGET_NORMAL to FT_Load_Glyph,
Herb Derbyfcac00f2018-05-01 11:57:56 -0400423 choosing the default hinting algorithm, which is optimized for standard
424 gray-level rendering.
Cary Clark8032b982017-07-28 11:04:54 -0400425##
426#Const kFull_Hinting 3
Cary Clark137b8742018-05-30 09:21:49 -0400427#Line # modifies glyph outlines for maximum constrast ##
428 Modifies glyph outlines for maximum constrast. With FreeType, this selects
Herb Derbyfcac00f2018-05-01 11:57:56 -0400429 FT_LOAD_TARGET_LCD or FT_LOAD_TARGET_LCD_V if kLCDRenderText_Flag is set.
430 FT_LOAD_TARGET_LCD is a variant of FT_LOAD_TARGET_NORMAL optimized for
431 horizontally decimated LCD displays; FT_LOAD_TARGET_LCD_V is a
Cary Clark8032b982017-07-28 11:04:54 -0400432 variant of FT_LOAD_TARGET_NORMAL optimized for vertically decimated LCD displays.
433##
434
Cary Clark4855f782018-02-06 09:41:53 -0500435#Bug 915
Cary Clark8032b982017-07-28 11:04:54 -0400436On OS_X and iOS, hinting controls whether Core_Graphics dilates the font outlines
Cary Clark137b8742018-05-30 09:21:49 -0400437to account for LCD text. No hinting uses Core_Text Grayscale output.
Cary Clark8032b982017-07-28 11:04:54 -0400438Normal hinting uses Core_Text LCD output. If kLCDRenderText_Flag is clear,
Cary Clark137b8742018-05-30 09:21:49 -0400439the LCD output is reduced to a single Grayscale channel.
Cary Clark8032b982017-07-28 11:04:54 -0400440
441On Windows with DirectWrite, Hinting has no effect.
442
443Hinting defaults to kNormal_Hinting.
444Set SkPaintDefaults_Hinting at compile time to change the default setting.
445
446#ToDo add an illustration? linux running GM:typefacerendering is best for this
447 the hinting variations are every other character horizontally
448#ToDo ##
449
450#Enum ##
451
452#Method Hinting getHinting() const
453
Cary Clarkab2621d2018-01-30 10:08:57 -0500454#In Hinting
455#Line # returns Hinting, glyph outline adjustment level ##
Cary Clark8032b982017-07-28 11:04:54 -0400456 Returns level of glyph outline adjustment.
457
458 #Return one of: kNo_Hinting, kSlight_Hinting, kNormal_Hinting, kFull_Hinting ##
459
460 #Example
461 SkPaint paint;
462 SkDebugf("SkPaint::kNormal_Hinting %c= paint.getHinting()\n",
463 SkPaint::kNormal_Hinting == paint.getHinting() ? '=' : ':');
464
465 #StdOut
466 SkPaint::kNormal_Hinting == paint.getHinting()
467 ##
468 ##
469##
470
471#Method void setHinting(Hinting hintingLevel)
472
Cary Clarkab2621d2018-01-30 10:08:57 -0500473#In Hinting
474#Line # sets Hinting, glyph outline adjustment level ##
Cary Clark8032b982017-07-28 11:04:54 -0400475 Sets level of glyph outline adjustment.
476 Does not check for valid values of hintingLevel.
477
478 #Table
479 #Legend
480 # Hinting # value # effect on generated glyph outlines ##
481 ##
482 # kNo_Hinting # 0 # leaves glyph outlines unchanged from their native representation ##
Cary Clarkce101242017-09-01 15:51:02 -0400483 # kSlight_Hinting # 1 # modifies glyph outlines minimally to improve contrast ##
484 # kNormal_Hinting # 2 # modifies glyph outlines to improve contrast ##
Herb Derbyfcac00f2018-05-01 11:57:56 -0400485 # kFull_Hinting # 3 # modifies glyph outlines for maximum contrast ##
Cary Clark8032b982017-07-28 11:04:54 -0400486 ##
487
488 #Param hintingLevel one of: kNo_Hinting, kSlight_Hinting, kNormal_Hinting, kFull_Hinting ##
489
490 #Example
491 SkPaint paint1, paint2;
492 paint2.setHinting(SkPaint::kNormal_Hinting);
493 SkDebugf("paint1 %c= paint2\n", paint1 == paint2 ? '=' : ':');
494
495 #StdOut
496 paint1 == paint2
497 ##
498 ##
499##
500
Cary Clark08895c42018-02-01 09:37:32 -0500501#Subtopic Hinting ##
Cary Clark8032b982017-07-28 11:04:54 -0400502# ------------------------------------------------------------------------------
Cary Clark08895c42018-02-01 09:37:32 -0500503#Subtopic Flags
504#Line # attributes represented by single bits ##
Cary Clark8032b982017-07-28 11:04:54 -0400505
506#Enum Flags
Cary Clark08895c42018-02-01 09:37:32 -0500507#Line # values described by bits and masks ##
Cary Clark8032b982017-07-28 11:04:54 -0400508
509#Code
510 enum Flags {
511 kAntiAlias_Flag = 0x01,
512 kDither_Flag = 0x04,
513 kFakeBoldText_Flag = 0x20,
514 kLinearText_Flag = 0x40,
515 kSubpixelText_Flag = 0x80,
Cary Clark8032b982017-07-28 11:04:54 -0400516 kLCDRenderText_Flag = 0x200,
517 kEmbeddedBitmapText_Flag = 0x400,
518 kAutoHinting_Flag = 0x800,
519 kVerticalText_Flag = 0x1000,
Cary Clark8032b982017-07-28 11:04:54 -0400520
521 kAllFlags = 0xFFFF,
522 };
523
524##
525
526The bit values stored in Flags.
527The default value for Flags, normally zero, can be changed at compile time
528with a custom definition of SkPaintDefaults_Flags.
529All flags can be read and written explicitly; Flags allows manipulating
530multiple settings at once.
531
Herb Derbyfcac00f2018-05-01 11:57:56 -0400532 #Const kAntiAlias_Flag 0x0001
Cary Clarkffb3d682018-05-17 12:17:28 -0400533 #Line # mask for setting Anti_Alias ##
Cary Clark8032b982017-07-28 11:04:54 -0400534 ##
535 #Const kDither_Flag 0x0004
Cary Clark682c58d2018-05-16 07:07:07 -0400536 #Line # mask for setting Dither ##
Cary Clark8032b982017-07-28 11:04:54 -0400537 ##
Cary Clark8032b982017-07-28 11:04:54 -0400538 #Const kFakeBoldText_Flag 0x0020
Cary Clark682c58d2018-05-16 07:07:07 -0400539 #Line # mask for setting Fake_Bold ##
Cary Clark8032b982017-07-28 11:04:54 -0400540 ##
541 #Const kLinearText_Flag 0x0040
Cary Clark682c58d2018-05-16 07:07:07 -0400542 #Line # mask for setting Linear_Text ##
Cary Clark8032b982017-07-28 11:04:54 -0400543 ##
544 #Const kSubpixelText_Flag 0x0080
Cary Clark682c58d2018-05-16 07:07:07 -0400545 #Line # mask for setting Subpixel_Text ##
Cary Clark8032b982017-07-28 11:04:54 -0400546 ##
Cary Clark8032b982017-07-28 11:04:54 -0400547 #Const kLCDRenderText_Flag 0x0200
Cary Clark682c58d2018-05-16 07:07:07 -0400548 #Line # mask for setting LCD_Text ##
Cary Clark8032b982017-07-28 11:04:54 -0400549 ##
550 #Const kEmbeddedBitmapText_Flag 0x0400
Cary Clark682c58d2018-05-16 07:07:07 -0400551 #Line # mask for setting Font_Embedded_Bitmaps ##
Cary Clark8032b982017-07-28 11:04:54 -0400552 ##
553 #Const kAutoHinting_Flag 0x0800
Cary Clark682c58d2018-05-16 07:07:07 -0400554 #Line # mask for setting Automatic_Hinting ##
Cary Clark8032b982017-07-28 11:04:54 -0400555 ##
556 #Const kVerticalText_Flag 0x1000
Cary Clark682c58d2018-05-16 07:07:07 -0400557 #Line # mask for setting Vertical_Text ##
Cary Clark8032b982017-07-28 11:04:54 -0400558 ##
Cary Clark8032b982017-07-28 11:04:54 -0400559 #Const kAllFlags 0xFFFF
Cary Clark682c58d2018-05-16 07:07:07 -0400560 #Line # mask of all Flags ##
Cary Clark8032b982017-07-28 11:04:54 -0400561 mask of all Flags, including private flags and flags reserved for future use
562 ##
563
564Flags default to all flags clear, disabling the associated feature.
565
566#Enum ##
567
568#Enum ReserveFlags
Cary Clark4855f782018-02-06 09:41:53 -0500569#Deprecated soon
Cary Clark8032b982017-07-28 11:04:54 -0400570
Cary Clark4855f782018-02-06 09:41:53 -0500571Only valid for Android framework.
Cary Clark8032b982017-07-28 11:04:54 -0400572
573#Code
574 enum ReserveFlags {
575 kUnderlineText_ReserveFlag = 0x08,
576 kStrikeThruText_ReserveFlag = 0x10,
577 };
578##
579
Cary Clark4855f782018-02-06 09:41:53 -0500580#Const kUnderlineText_ReserveFlag 0x0008
581#Deprecated soon
582##
583#Const kStrikeThruText_ReserveFlag 0x0010
584#Deprecated soon
585##
586##
Cary Clark8032b982017-07-28 11:04:54 -0400587
588#Method uint32_t getFlags() const
589
Cary Clarkab2621d2018-01-30 10:08:57 -0500590#In Flags
591#Line # returns Flags stored in a bit field ##
Cary Clark8032b982017-07-28 11:04:54 -0400592Returns paint settings described by Flags. Each setting uses one
593bit, and can be tested with Flags members.
594
595#Return zero, one, or more bits described by Flags ##
596
597#Example
598 SkPaint paint;
599 paint.setAntiAlias(true);
600 SkDebugf("(SkPaint::kAntiAlias_Flag & paint.getFlags()) %c= 0\n",
601 SkPaint::kAntiAlias_Flag & paint.getFlags() ? '!' : '=');
602
603 #StdOut
604 (SkPaint::kAntiAlias_Flag & paint.getFlags()) != 0
605 ##
606##
607
608##
609
610#Method void setFlags(uint32_t flags)
611
Cary Clarkab2621d2018-01-30 10:08:57 -0500612#In Flags
613#Line # sets multiple Flags in a bit field ##
Cary Clark8032b982017-07-28 11:04:54 -0400614Replaces Flags with flags, the union of the Flags members.
615All Flags members may be cleared, or one or more may be set.
616
617#Param flags union of Flags for Paint ##
618
619#Example
620 SkPaint paint;
621 paint.setFlags((uint32_t) (SkPaint::kAntiAlias_Flag | SkPaint::kDither_Flag));
622 SkDebugf("paint.isAntiAlias()\n", paint.isAntiAlias() ? '!' : '=');
623 SkDebugf("paint.isDither()\n", paint.isDither() ? '!' : '=');
624
625 #StdOut
626 paint.isAntiAlias()
627 paint.isDither()
628 ##
629##
630
631##
632
Cary Clark08895c42018-02-01 09:37:32 -0500633#Subtopic Flags ##
Cary Clark8032b982017-07-28 11:04:54 -0400634# ------------------------------------------------------------------------------
Cary Clarkffb3d682018-05-17 12:17:28 -0400635#Subtopic Anti_Alias
636#Alias Anti_Alias
Cary Clark137b8742018-05-30 09:21:49 -0400637#Substitute anti-alias
638##
Cary Clarkffb3d682018-05-17 12:17:28 -0400639#Alias Anti_Aliased
Cary Clark137b8742018-05-30 09:21:49 -0400640#Substitute anti-aliased
641##
Cary Clarkffb3d682018-05-17 12:17:28 -0400642#Alias Anti_Aliasing
Cary Clark137b8742018-05-30 09:21:49 -0400643#Substitute anti-aliasing
644##
Cary Clark4855f782018-02-06 09:41:53 -0500645#In Related_Function
Cary Clarkab2621d2018-01-30 10:08:57 -0500646#Line # approximating coverage with transparency ##
Cary Clark8032b982017-07-28 11:04:54 -0400647
Cary Clarkffb3d682018-05-17 12:17:28 -0400648Anti_Alias drawing approximates partial pixel coverage with transparency.
Cary Clark8032b982017-07-28 11:04:54 -0400649If kAntiAlias_Flag is clear, pixel centers contained by the shape edge are drawn opaque.
650If kAntiAlias_Flag is set, pixels are drawn with Color_Alpha equal to their coverage.
651
Herb Derbyfcac00f2018-05-01 11:57:56 -0400652The rule for Aliased pixels is inconsistent across platforms. A shape edge
Cary Clark8032b982017-07-28 11:04:54 -0400653passing through the pixel center may, but is not required to, draw the pixel.
654
Cary Clarkce101242017-09-01 15:51:02 -0400655Raster_Engine draws Aliased pixels whose centers are on or to the right of the start of an
Cary Clark8032b982017-07-28 11:04:54 -0400656active Path edge, and whose center is to the left of the end of the active Path edge.
657
658#ToDo add illustration of raster pixels ##
659
Cary Clarkffb3d682018-05-17 12:17:28 -0400660A platform may only support Anti_Aliased drawing. Some GPU-backed platforms use
661Supersampling to Anti_Alias all drawing, and have no mechanism to selectively
Cary Clarkce101242017-09-01 15:51:02 -0400662Alias.
Cary Clark8032b982017-07-28 11:04:54 -0400663
Cary Clarkffb3d682018-05-17 12:17:28 -0400664The amount of coverage computed for Anti_Aliased pixels also varies across platforms.
Cary Clark8032b982017-07-28 11:04:54 -0400665
Cary Clarkffb3d682018-05-17 12:17:28 -0400666Anti_Alias is disabled by default.
667Anti_Alias can be enabled by default by setting SkPaintDefaults_Flags to kAntiAlias_Flag
Cary Clark8032b982017-07-28 11:04:54 -0400668at compile time.
669
Cary Clarkab2621d2018-01-30 10:08:57 -0500670#Example
Cary Clark8032b982017-07-28 11:04:54 -0400671 #Width 512
672 #Description
673 A red line is drawn with transparency on the edges to make it look smoother.
674 A blue line draws only where the pixel centers are contained.
Cary Clarkce101242017-09-01 15:51:02 -0400675 The lines are drawn into Bitmap, then drawn magnified to make the
676 Aliasing easier to see.
Cary Clark8032b982017-07-28 11:04:54 -0400677 ##
678
679 void draw(SkCanvas* canvas) {
680 SkBitmap bitmap;
681 bitmap.allocN32Pixels(50, 50);
682 SkCanvas offscreen(bitmap);
683 SkPaint paint;
684 paint.setStyle(SkPaint::kStroke_Style);
685 paint.setStrokeWidth(10);
686 for (bool antialias : { false, true }) {
687 paint.setColor(antialias ? SK_ColorRED : SK_ColorBLUE);
688 paint.setAntiAlias(antialias);
689 bitmap.eraseColor(0);
690 offscreen.drawLine(5, 5, 15, 30, paint);
691 canvas->drawLine(5, 5, 15, 30, paint);
692 canvas->save();
693 canvas->scale(10, 10);
694 canvas->drawBitmap(bitmap, antialias ? 12 : 0, 0);
695 canvas->restore();
696 canvas->translate(15, 0);
697 }
698 }
Cary Clarkab2621d2018-01-30 10:08:57 -0500699##
Cary Clark8032b982017-07-28 11:04:54 -0400700
701#Method bool isAntiAlias() const
Cary Clark78de7512018-02-07 07:27:09 -0500702#In Anti_alias
Cary Clarkffb3d682018-05-17 12:17:28 -0400703#Line # returns true if Anti_Alias is set ##
Cary Clark8032b982017-07-28 11:04:54 -0400704
Cary Clark80247e52018-07-11 16:18:41 -0400705 Returns true if pixels on the active edges of Path may be drawn with partial transparency.
Cary Clark8032b982017-07-28 11:04:54 -0400706
707 Equivalent to getFlags masked with kAntiAlias_Flag.
708
709 #Return kAntiAlias_Flag state ##
710
711 #Example
712 SkPaint paint;
713 SkDebugf("paint.isAntiAlias() %c= !!(paint.getFlags() & SkPaint::kAntiAlias_Flag)\n",
714 paint.isAntiAlias() == !!(paint.getFlags() & SkPaint::kAntiAlias_Flag) ? '=' : '!');
715 paint.setAntiAlias(true);
716 SkDebugf("paint.isAntiAlias() %c= !!(paint.getFlags() & SkPaint::kAntiAlias_Flag)\n",
717 paint.isAntiAlias() == !!(paint.getFlags() & SkPaint::kAntiAlias_Flag) ? '=' : '!');
718
719 #StdOut
720 paint.isAntiAlias() == !!(paint.getFlags() & SkPaint::kAntiAlias_Flag)
721 paint.isAntiAlias() == !!(paint.getFlags() & SkPaint::kAntiAlias_Flag)
722 ##
723 ##
724##
725
726#Method void setAntiAlias(bool aa)
727
Cary Clark78de7512018-02-07 07:27:09 -0500728#In Anti_alias
Cary Clarkffb3d682018-05-17 12:17:28 -0400729#Line # sets or clears Anti_Alias ##
Cary Clark8032b982017-07-28 11:04:54 -0400730 Requests, but does not require, that Path edge pixels draw opaque or with
731 partial transparency.
732
733 Sets kAntiAlias_Flag if aa is true.
734 Clears kAntiAlias_Flag if aa is false.
735
736 #Param aa setting for kAntiAlias_Flag ##
737
738 #Example
739 SkPaint paint1, paint2;
740 paint1.setAntiAlias(true);
741 paint2.setFlags(paint2.getFlags() | SkPaint::kAntiAlias_Flag);
742 SkDebugf("paint1 %c= paint2\n", paint1 == paint2 ? '=' : '!');
743
744 #StdOut
745 paint1 == paint2
746 ##
747 ##
748
749##
750
Cary Clarkffb3d682018-05-17 12:17:28 -0400751#Subtopic Anti_Alias ##
Cary Clark8032b982017-07-28 11:04:54 -0400752# ------------------------------------------------------------------------------
Cary Clark08895c42018-02-01 09:37:32 -0500753#Subtopic Dither
754#Line # distributing color error ##
Cary Clark8032b982017-07-28 11:04:54 -0400755
Herb Derbyfcac00f2018-05-01 11:57:56 -0400756Dither increases fidelity by adjusting the color of adjacent pixels.
Cary Clark8032b982017-07-28 11:04:54 -0400757This can help to smooth color transitions and reducing banding in gradients.
758Dithering lessens visible banding from kRGB_565_SkColorType
Herb Derbyfcac00f2018-05-01 11:57:56 -0400759and kRGBA_8888_SkColorType gradients,
Cary Clark8032b982017-07-28 11:04:54 -0400760and improves rendering into a kRGB_565_SkColorType Surface.
761
762Dithering is always enabled for linear gradients drawing into
763kRGB_565_SkColorType Surface and kRGBA_8888_SkColorType Surface.
764Dither cannot be enabled for kAlpha_8_SkColorType Surface and
765kRGBA_F16_SkColorType Surface.
766
767Dither is disabled by default.
768Dither can be enabled by default by setting SkPaintDefaults_Flags to kDither_Flag
769at compile time.
770
Cary Clark2be81cf2018-09-13 12:04:30 -0400771Some platform implementations may ignore dithering. Set #Formula # SK_IGNORE_GPU_DITHER ##
Cary Clark8032b982017-07-28 11:04:54 -0400772to ignore Dither on GPU_Surface.
773
774#Example
Herb Derbyfcac00f2018-05-01 11:57:56 -0400775#Description
Cary Clark8032b982017-07-28 11:04:54 -0400776Dithering in the bottom half more closely approximates the requested color by
777alternating nearby colors from pixel to pixel.
778##
779void draw(SkCanvas* canvas) {
780 SkBitmap bm16;
781 bm16.allocPixels(SkImageInfo::Make(32, 32, kRGB_565_SkColorType, kOpaque_SkAlphaType));
782 SkCanvas c16(bm16);
783 SkPaint colorPaint;
784 for (auto dither : { false, true } ) {
785 colorPaint.setDither(dither);
786 for (auto colors : { 0xFF333333, 0xFF666666, 0xFF999999, 0xFFCCCCCC } ) {
787 for (auto mask : { 0xFFFF0000, 0xFF00FF00, 0xFF0000FF, 0xFFFFFFFF } ) {
788 colorPaint.setColor(colors & mask);
789 c16.drawRect({0, 0, 8, 4}, colorPaint);
790 c16.translate(8, 0);
791 }
792 c16.translate(-32, 4);
793 }
794 }
795 canvas->scale(8, 8);
796 canvas->drawBitmap(bm16, 0, 0);
797}
798##
799
800#Example
Herb Derbyfcac00f2018-05-01 11:57:56 -0400801#Description
Cary Clark8032b982017-07-28 11:04:54 -0400802Dithering introduces subtle adjustments to color to smooth gradients.
803Drawing the gradient repeatedly with SkBlendMode::kPlus exaggerates the
804dither, making it easier to see.
805##
806void draw(SkCanvas* canvas) {
807 canvas->clear(0);
808 SkBitmap bm32;
809 bm32.allocPixels(SkImageInfo::Make(20, 10, kN32_SkColorType, kPremul_SkAlphaType));
810 SkCanvas c32(bm32);
811 SkPoint points[] = {{0, 0}, {20, 0}};
812 SkColor colors[] = {0xFF334455, 0xFF662211 };
813 SkPaint paint;
814 paint.setShader(SkGradientShader::MakeLinear(
815 points, colors, nullptr, SK_ARRAY_COUNT(colors),
816 SkShader::kClamp_TileMode, 0, nullptr));
817 paint.setDither(true);
818 c32.drawPaint(paint);
819 canvas->scale(12, 12);
820 canvas->drawBitmap(bm32, 0, 0);
821 paint.setBlendMode(SkBlendMode::kPlus);
822 canvas->drawBitmap(bm32, 0, 11, &paint);
823 canvas->drawBitmap(bm32, 0, 11, &paint);
824 canvas->drawBitmap(bm32, 0, 11, &paint);
825}
826##
827
828#Method bool isDither() const
829
Cary Clarkab2621d2018-01-30 10:08:57 -0500830#In Dither
831#Line # returns true if Dither is set ##
Cary Clark80247e52018-07-11 16:18:41 -0400832 Returns true if color error may be distributed to smooth color transition.
Herb Derbyfcac00f2018-05-01 11:57:56 -0400833
Cary Clark8032b982017-07-28 11:04:54 -0400834 Equivalent to getFlags masked with kDither_Flag.
835
836 #Return kDither_Flag state ##
837
838 #Example
839 SkPaint paint;
840 SkDebugf("paint.isDither() %c= !!(paint.getFlags() & SkPaint::kDither_Flag)\n",
841 paint.isDither() == !!(paint.getFlags() & SkPaint::kDither_Flag) ? '=' : '!');
842 paint.setDither(true);
843 SkDebugf("paint.isDither() %c= !!(paint.getFlags() & SkPaint::kDither_Flag)\n",
844 paint.isDither() == !!(paint.getFlags() & SkPaint::kDither_Flag) ? '=' : '!');
845
846 #StdOut
847 paint.isDither() == !!(paint.getFlags() & SkPaint::kDither_Flag)
848 paint.isDither() == !!(paint.getFlags() & SkPaint::kDither_Flag)
849 ##
850 ##
851
852##
853
854#Method void setDither(bool dither)
855
Cary Clarkab2621d2018-01-30 10:08:57 -0500856#In Dither
857#Line # sets or clears Dither ##
Cary Clark8032b982017-07-28 11:04:54 -0400858 Requests, but does not require, to distribute color error.
859
860 Sets kDither_Flag if dither is true.
861 Clears kDither_Flag if dither is false.
862
863 #Param dither setting for kDither_Flag ##
864
865 #Example
866 SkPaint paint1, paint2;
867 paint1.setDither(true);
868 paint2.setFlags(paint2.getFlags() | SkPaint::kDither_Flag);
869 SkDebugf("paint1 %c= paint2\n", paint1 == paint2 ? '=' : '!');
870
871 #StdOut
872 paint1 == paint2
873 ##
874 ##
875
876 #SeeAlso kRGB_565_SkColorType
877
878##
879
Cary Clarkffb3d682018-05-17 12:17:28 -0400880#SeeAlso Gradient kRGB_565_SkColorType
Cary Clark8032b982017-07-28 11:04:54 -0400881
Cary Clark08895c42018-02-01 09:37:32 -0500882#Subtopic Dither ##
Cary Clark8032b982017-07-28 11:04:54 -0400883# ------------------------------------------------------------------------------
Cary Clark08895c42018-02-01 09:37:32 -0500884#Subtopic Device_Text
885#Line # increase precision of glyph position ##
Cary Clark8032b982017-07-28 11:04:54 -0400886
887LCD_Text and Subpixel_Text increase the precision of glyph position.
888
Cary Clarkffb3d682018-05-17 12:17:28 -0400889When set, Flags kLCDRenderText_Flag takes advantage of the organization of RGB stripes that
Cary Clark8032b982017-07-28 11:04:54 -0400890create a color, and relies
Cary Clarkce101242017-09-01 15:51:02 -0400891on the small size of the stripe and visual perception to make the color fringing imperceptible.
Cary Clark8032b982017-07-28 11:04:54 -0400892LCD_Text can be enabled on devices that orient stripes horizontally or vertically, and that order
Cary Clarkffb3d682018-05-17 12:17:28 -0400893the color components as RGB or BGR.
Cary Clark8032b982017-07-28 11:04:54 -0400894
Herb Derbyfcac00f2018-05-01 11:57:56 -0400895Flags kSubpixelText_Flag uses the pixel transparency to represent a fractional offset.
Cary Clark8032b982017-07-28 11:04:54 -0400896As the opaqueness
897of the color increases, the edge of the glyph appears to move towards the outside of the pixel.
898
899Either or both techniques can be enabled.
900kLCDRenderText_Flag and kSubpixelText_Flag are clear by default.
Herb Derbyfcac00f2018-05-01 11:57:56 -0400901LCD_Text or Subpixel_Text can be enabled by default by setting SkPaintDefaults_Flags to
Cary Clark8032b982017-07-28 11:04:54 -0400902kLCDRenderText_Flag or kSubpixelText_Flag (or both) at compile time.
903
904#Example
905 #Description
906 Four commas are drawn normally and with combinations of LCD_Text and Subpixel_Text.
Cary Clarkce101242017-09-01 15:51:02 -0400907 When Subpixel_Text is disabled, the comma Glyphs are identical, but not evenly spaced.
908 When Subpixel_Text is enabled, the comma Glyphs are unique, but appear evenly spaced.
Cary Clark8032b982017-07-28 11:04:54 -0400909 ##
910
911 SkBitmap bitmap;
912 bitmap.allocN32Pixels(24, 33);
913 SkCanvas offscreen(bitmap);
914 offscreen.clear(SK_ColorWHITE);
915 SkPaint paint;
916 paint.setAntiAlias(true);
917 paint.setTextSize(20);
918 for (bool lcd : { false, true }) {
919 paint.setLCDRenderText(lcd);
920 for (bool subpixel : { false, true }) {
921 paint.setSubpixelText(subpixel);
922 offscreen.drawString(",,,,", 0, 4, paint);
923 offscreen.translate(0, 7);
924 }
925 }
926 canvas->drawBitmap(bitmap, 4, 12);
927 canvas->scale(9, 9);
928 canvas->drawBitmap(bitmap, 4, -1);
929##
Cary Clark08895c42018-02-01 09:37:32 -0500930#Subtopic Device_Text ##
Cary Clark8032b982017-07-28 11:04:54 -0400931
932#Subtopic Linear_Text
Cary Clark137b8742018-05-30 09:21:49 -0400933#Alias Linear_Text ##
Cary Clark08895c42018-02-01 09:37:32 -0500934#Line # selects text rendering as Glyph or Path ##
Cary Clark8032b982017-07-28 11:04:54 -0400935
936Linear_Text selects whether text is rendered as a Glyph or as a Path.
937If kLinearText_Flag is set, it has the same effect as setting Hinting to kNormal_Hinting.
Cary Clarkd0530ba2017-09-14 11:25:39 -0400938If kLinearText_Flag is clear, it is the same as setting Hinting to kNo_Hinting.
Cary Clark8032b982017-07-28 11:04:54 -0400939
940#Method bool isLinearText() const
941
Cary Clark08895c42018-02-01 09:37:32 -0500942#Line # returns true if text is converted to Path ##
Cary Clarkab2621d2018-01-30 10:08:57 -0500943#In Linear_Text
Cary Clark80247e52018-07-11 16:18:41 -0400944 Returns true if text is converted to Path before drawing and measuring.
Cary Clark8032b982017-07-28 11:04:54 -0400945
946 Equivalent to getFlags masked with kLinearText_Flag.
947
948 #Return kLinearText_Flag state ##
949
950 #Example
951 #Height 128
952 void draw(SkCanvas* canvas) {
953 SkPaint paint;
954 paint.setAntiAlias(true);
955 const char testStr[] = "xxxx xxxx";
956 for (auto linearText : { false, true } ) {
957 paint.setLinearText(linearText);
958 paint.setTextSize(24);
959 canvas->drawString(paint.isLinearText() ? "linear" : "hinted", 128, 30, paint);
960 for (SkScalar textSize = 8; textSize < 30; textSize *= 1.22f) {
961 paint.setTextSize(textSize);
962 canvas->translate(0, textSize);
963 canvas->drawString(testStr, 10, 0, paint);
964 }
965 }
966 }
967 ##
968
969 #SeeAlso setLinearText Hinting
970##
971
972#Method void setLinearText(bool linearText)
973
Cary Clark08895c42018-02-01 09:37:32 -0500974#Line # converts to Path before draw or measure ##
Cary Clarkab2621d2018-01-30 10:08:57 -0500975#In Linear_Text
Cary Clark80247e52018-07-11 16:18:41 -0400976 Returns true if text is converted to Path before drawing and measuring.
Cary Clark8032b982017-07-28 11:04:54 -0400977 By default, kLinearText_Flag is clear.
978
979 Sets kLinearText_Flag if linearText is true.
980 Clears kLinearText_Flag if linearText is false.
981
982 #Param linearText setting for kLinearText_Flag ##
983
984 #Example
985 #Height 128
986 void draw(SkCanvas* canvas) {
987 SkPaint paint;
988 paint.setAntiAlias(true);
989 const char testStr[] = "abcd efgh";
990 for (int textSize : { 12, 24 } ) {
991 paint.setTextSize(textSize);
992 for (auto linearText : { false, true } ) {
993 paint.setLinearText(linearText);
994 SkString width;
995 width.appendScalar(paint.measureText(testStr, SK_ARRAY_COUNT(testStr), nullptr));
996 canvas->translate(0, textSize + 4);
997 canvas->drawString(testStr, 10, 0, paint);
998 canvas->drawString(width, 128, 0, paint);
999 }
1000 }
Herb Derbyfcac00f2018-05-01 11:57:56 -04001001 }
Cary Clark8032b982017-07-28 11:04:54 -04001002 ##
1003
1004 #SeeAlso isLinearText Hinting
1005##
1006
Cary Clark08895c42018-02-01 09:37:32 -05001007#Subtopic Linear_Text ##
Cary Clark8032b982017-07-28 11:04:54 -04001008
1009#Subtopic Subpixel_Text
Cary Clark137b8742018-05-30 09:21:49 -04001010#Alias Subpixel_Text ##
Cary Clark08895c42018-02-01 09:37:32 -05001011#Line # uses pixel transparency to represent fractional offset ##
Cary Clark8032b982017-07-28 11:04:54 -04001012
Herb Derbyfcac00f2018-05-01 11:57:56 -04001013Flags kSubpixelText_Flag uses the pixel transparency to represent a fractional offset.
Cary Clark8032b982017-07-28 11:04:54 -04001014As the opaqueness
1015of the color increases, the edge of the glyph appears to move towards the outside of the pixel.
1016
1017#Method bool isSubpixelText() const
Herb Derbyfcac00f2018-05-01 11:57:56 -04001018
Cary Clarkab2621d2018-01-30 10:08:57 -05001019#In Subpixel_Text
1020#Line # returns true if Subpixel_Text is set ##
Cary Clark80247e52018-07-11 16:18:41 -04001021 Returns true if Glyphs at different sub-pixel positions may differ on pixel edge coverage.
Cary Clark8032b982017-07-28 11:04:54 -04001022
1023 Equivalent to getFlags masked with kSubpixelText_Flag.
1024
1025 #Return kSubpixelText_Flag state ##
1026
1027 #Example
1028SkPaint paint;
1029SkDebugf("paint.isSubpixelText() %c= !!(paint.getFlags() & SkPaint::kSubpixelText_Flag)\n",
1030 paint.isSubpixelText() == !!(paint.getFlags() & SkPaint::kSubpixelText_Flag) ? '=' : '!');
1031paint.setSubpixelText(true);
1032SkDebugf("paint.isSubpixelText() %c= !!(paint.getFlags() & SkPaint::kSubpixelText_Flag)\n",
1033 paint.isSubpixelText() == !!(paint.getFlags() & SkPaint::kSubpixelText_Flag) ? '=' : '!');
1034
1035 #StdOut
1036 paint.isSubpixelText() == !!(paint.getFlags() & SkPaint::kSubpixelText_Flag)
1037 paint.isSubpixelText() == !!(paint.getFlags() & SkPaint::kSubpixelText_Flag)
1038 ##
1039 ##
1040
1041##
1042
1043#Method void setSubpixelText(bool subpixelText)
1044
Cary Clarkab2621d2018-01-30 10:08:57 -05001045#In Subpixel_Text
1046#Line # sets or clears Subpixel_Text ##
Cary Clarkce101242017-09-01 15:51:02 -04001047 Requests, but does not require, that Glyphs respect sub-pixel positioning.
Cary Clark8032b982017-07-28 11:04:54 -04001048
1049 Sets kSubpixelText_Flag if subpixelText is true.
1050 Clears kSubpixelText_Flag if subpixelText is false.
1051
1052 #Param subpixelText setting for kSubpixelText_Flag ##
1053
1054 #Example
1055 SkPaint paint1, paint2;
1056 paint1.setSubpixelText(true);
1057 paint2.setFlags(paint2.getFlags() | SkPaint::kSubpixelText_Flag);
1058 SkDebugf("paint1 %c= paint2\n", paint1 == paint2 ? '=' : '!');
1059
1060 #StdOut
1061 paint1 == paint2
1062 ##
1063 ##
1064
1065##
1066
Cary Clark08895c42018-02-01 09:37:32 -05001067#Subtopic Subpixel_Text ##
Cary Clark8032b982017-07-28 11:04:54 -04001068
1069#Subtopic LCD_Text
Cary Clarkffb3d682018-05-17 12:17:28 -04001070#Line # text relying on the order of RGB stripes ##
Cary Clark137b8742018-05-30 09:21:49 -04001071
1072# make this a top level name, since it is under subtopic Device_Text
1073#Alias LCD_Text
1074#Substitute LCD text
1075##
Cary Clark8032b982017-07-28 11:04:54 -04001076
Cary Clarkffb3d682018-05-17 12:17:28 -04001077When set, Flags kLCDRenderText_Flag takes advantage of the organization of RGB stripes that
Cary Clark8032b982017-07-28 11:04:54 -04001078create a color, and relies
Cary Clarkce101242017-09-01 15:51:02 -04001079on the small size of the stripe and visual perception to make the color fringing imperceptible.
Cary Clark8032b982017-07-28 11:04:54 -04001080LCD_Text can be enabled on devices that orient stripes horizontally or vertically, and that order
Cary Clarkffb3d682018-05-17 12:17:28 -04001081the color components as RGB or BGR.
Cary Clark8032b982017-07-28 11:04:54 -04001082
1083#Method bool isLCDRenderText() const
1084
Cary Clarkab2621d2018-01-30 10:08:57 -05001085#In LCD_Text
1086#Line # returns true if LCD_Text is set ##
Cary Clark80247e52018-07-11 16:18:41 -04001087 Returns true if Glyphs may use LCD striping to improve glyph edges.
Cary Clark8032b982017-07-28 11:04:54 -04001088
1089 Returns true if Flags kLCDRenderText_Flag is set.
1090
1091 #Return kLCDRenderText_Flag state ##
1092
1093 #Example
1094SkPaint paint;
1095SkDebugf("paint.isLCDRenderText() %c= !!(paint.getFlags() & SkPaint::kLCDRenderText_Flag)\n",
1096 paint.isLCDRenderText() == !!(paint.getFlags() & SkPaint::kLCDRenderText_Flag) ? '=' : '!');
1097paint.setLCDRenderText(true);
1098SkDebugf("paint.isLCDRenderText() %c= !!(paint.getFlags() & SkPaint::kLCDRenderText_Flag)\n",
1099 paint.isLCDRenderText() == !!(paint.getFlags() & SkPaint::kLCDRenderText_Flag) ? '=' : '!');
1100
1101 #StdOut
1102 paint.isLCDRenderText() == !!(paint.getFlags() & SkPaint::kLCDRenderText_Flag)
1103 paint.isLCDRenderText() == !!(paint.getFlags() & SkPaint::kLCDRenderText_Flag)
1104 ##
1105 ##
1106
1107##
1108
1109#Method void setLCDRenderText(bool lcdText)
1110
Cary Clarkab2621d2018-01-30 10:08:57 -05001111#In LCD_Text
1112#Line # sets or clears LCD_Text ##
Cary Clarkce101242017-09-01 15:51:02 -04001113 Requests, but does not require, that Glyphs use LCD striping for glyph edges.
Cary Clark8032b982017-07-28 11:04:54 -04001114
1115 Sets kLCDRenderText_Flag if lcdText is true.
1116 Clears kLCDRenderText_Flag if lcdText is false.
1117
1118 #Param lcdText setting for kLCDRenderText_Flag ##
1119
1120 #Example
1121 SkPaint paint1, paint2;
1122 paint1.setLCDRenderText(true);
1123 paint2.setFlags(paint2.getFlags() | SkPaint::kLCDRenderText_Flag);
1124 SkDebugf("paint1 %c= paint2\n", paint1 == paint2 ? '=' : '!');
1125
1126 #StdOut
1127 paint1 == paint2
1128 ##
1129 ##
1130
1131
1132##
1133
Cary Clark08895c42018-02-01 09:37:32 -05001134#Subtopic LCD_Text ##
Cary Clark8032b982017-07-28 11:04:54 -04001135
Cary Clark8032b982017-07-28 11:04:54 -04001136# ------------------------------------------------------------------------------
Cary Clark08895c42018-02-01 09:37:32 -05001137#Subtopic Font_Embedded_Bitmaps
1138#Line # custom sized bitmap Glyphs ##
Cary Clark137b8742018-05-30 09:21:49 -04001139#Alias Font_Embedded_Bitmaps ## # long-winded enough, alias so I don't type Paint_Font_...
Cary Clark8032b982017-07-28 11:04:54 -04001140
Cary Clarkce101242017-09-01 15:51:02 -04001141Font_Embedded_Bitmaps allows selecting custom sized bitmap Glyphs.
Cary Clark8032b982017-07-28 11:04:54 -04001142Flags kEmbeddedBitmapText_Flag when set chooses an embedded bitmap glyph over an outline contained
Herb Derbyfcac00f2018-05-01 11:57:56 -04001143in a font if the platform supports this option.
Cary Clark8032b982017-07-28 11:04:54 -04001144
1145FreeType selects the bitmap glyph if available when kEmbeddedBitmapText_Flag is set, and selects
1146the outline glyph if kEmbeddedBitmapText_Flag is clear.
1147Windows may select the bitmap glyph but is not required to do so.
1148OS_X and iOS do not support this option.
1149
1150Font_Embedded_Bitmaps is disabled by default.
1151Font_Embedded_Bitmaps can be enabled by default by setting SkPaintDefaults_Flags to
1152kEmbeddedBitmapText_Flag at compile time.
1153
1154#Example
1155 #ToDo image will only output on Ubuntu ... how to handle that in fiddle? ##
1156 #Platform !fiddle
1157 #Description
Cary Clarkce101242017-09-01 15:51:02 -04001158 The "hintgasp" TrueType font in the Skia resources/fonts directory
1159 includes an embedded bitmap Glyph at odd font sizes. This example works
1160 on platforms that use FreeType as their Font_Engine.
1161 Windows may, but is not required to, return a bitmap glyph if
1162 kEmbeddedBitmapText_Flag is set.
Cary Clark8032b982017-07-28 11:04:54 -04001163 ##
1164 #Image embeddedbitmap.png
1165
1166 SkBitmap bitmap;
1167 bitmap.allocN32Pixels(30, 15);
1168 bitmap.eraseColor(0);
1169 SkCanvas offscreen(bitmap);
1170 SkPaint paint;
1171 paint.setAntiAlias(true);
1172 paint.setTextSize(13);
Hal Canary53e5e7d2017-12-08 14:25:14 -05001173 paint.setTypeface(MakeResourceAsTypeface("fonts/hintgasp.ttf"));
Cary Clark8032b982017-07-28 11:04:54 -04001174 for (bool embedded : { false, true}) {
1175 paint.setEmbeddedBitmapText(embedded);
1176 offscreen.drawString("A", embedded ? 5 : 15, 15, paint);
1177 }
1178 canvas->drawBitmap(bitmap, 0, 0);
1179 canvas->scale(10, 10);
1180 canvas->drawBitmap(bitmap, -2, 1);
1181##
1182
1183#Method bool isEmbeddedBitmapText() const
1184
Cary Clarkab2621d2018-01-30 10:08:57 -05001185#In Font_Embedded_Bitmaps
1186#Line # returns true if Font_Embedded_Bitmaps is set ##
Cary Clark80247e52018-07-11 16:18:41 -04001187 Returns true if Font_Engine may return Glyphs from font bitmaps instead of from outlines.
Cary Clark8032b982017-07-28 11:04:54 -04001188
1189 Equivalent to getFlags masked with kEmbeddedBitmapText_Flag.
1190
1191 #Return kEmbeddedBitmapText_Flag state ##
1192
1193 #Example
1194 SkPaint paint;
1195 SkDebugf("paint.isEmbeddedBitmapText() %c="
1196 " !!(paint.getFlags() & SkPaint::kEmbeddedBitmapText_Flag)\n",
1197 paint.isEmbeddedBitmapText() ==
1198 !!(paint.getFlags() & SkPaint::kEmbeddedBitmapText_Flag) ? '=' : '!');
1199 paint.setEmbeddedBitmapText(true);
1200 SkDebugf("paint.isEmbeddedBitmapText() %c="
1201 " !!(paint.getFlags() & SkPaint::kEmbeddedBitmapText_Flag)\n",
1202 paint.isEmbeddedBitmapText() ==
1203 !!(paint.getFlags() & SkPaint::kEmbeddedBitmapText_Flag) ? '=' : '!');
1204
1205 #StdOut
1206 paint.isEmbeddedBitmapText() == !!(paint.getFlags() & SkPaint::kEmbeddedBitmapText_Flag)
1207 paint.isEmbeddedBitmapText() == !!(paint.getFlags() & SkPaint::kEmbeddedBitmapText_Flag)
1208 ##
1209 ##
1210
1211##
1212
1213#Method void setEmbeddedBitmapText(bool useEmbeddedBitmapText)
1214
Cary Clarkab2621d2018-01-30 10:08:57 -05001215#In Font_Embedded_Bitmaps
1216#Line # sets or clears Font_Embedded_Bitmaps ##
Cary Clark8032b982017-07-28 11:04:54 -04001217 Requests, but does not require, to use bitmaps in fonts instead of outlines.
1218
1219 Sets kEmbeddedBitmapText_Flag if useEmbeddedBitmapText is true.
1220 Clears kEmbeddedBitmapText_Flag if useEmbeddedBitmapText is false.
1221
1222 #Param useEmbeddedBitmapText setting for kEmbeddedBitmapText_Flag ##
1223
1224 #Example
1225 SkPaint paint1, paint2;
1226 paint1.setEmbeddedBitmapText(true);
1227 paint2.setFlags(paint2.getFlags() | SkPaint::kEmbeddedBitmapText_Flag);
1228 SkDebugf("paint1 %c= paint2\n", paint1 == paint2 ? '=' : '!');
1229
1230 #StdOut
1231 paint1 == paint2
1232 ##
1233 ##
1234
1235##
1236
Cary Clark08895c42018-02-01 09:37:32 -05001237#Subtopic Font_Embedded_Bitmaps ##
Cary Clark8032b982017-07-28 11:04:54 -04001238# ------------------------------------------------------------------------------
Cary Clark08895c42018-02-01 09:37:32 -05001239#Subtopic Automatic_Hinting
1240#Line # always adjust glyph paths ##
Cary Clark8032b982017-07-28 11:04:54 -04001241#Substitute auto-hinting
1242
1243If Hinting is set to kNormal_Hinting or kFull_Hinting, Automatic_Hinting
Cary Clarkce101242017-09-01 15:51:02 -04001244instructs the Font_Manager to always hint Glyphs.
Cary Clark8032b982017-07-28 11:04:54 -04001245Automatic_Hinting has no effect if Hinting is set to kNo_Hinting or
1246kSlight_Hinting.
1247
1248Automatic_Hinting only affects platforms that use FreeType as the Font_Manager.
1249
1250#Method bool isAutohinted() const
1251
Cary Clarkab2621d2018-01-30 10:08:57 -05001252#In Automatic_Hinting
1253#Line # returns true if Glyphs are always hinted ##
Cary Clark80247e52018-07-11 16:18:41 -04001254 Returns true if Hinting is set to kNormal_Hinting or kFull_Hinting, and if
1255 platform uses FreeType as the Font_Manager. If true, instructs
1256 the Font_Manager to always hint Glyphs.
Cary Clark8032b982017-07-28 11:04:54 -04001257
1258 Equivalent to getFlags masked with kAutoHinting_Flag.
1259
1260 #Return kAutoHinting_Flag state ##
1261
1262 #Example
1263 SkPaint paint;
1264 for (auto forceAutoHinting : { false, true} ) {
1265 paint.setAutohinted(forceAutoHinting);
1266 SkDebugf("paint.isAutohinted() %c="
1267 " !!(paint.getFlags() & SkPaint::kAutoHinting_Flag)\n",
1268 paint.isAutohinted() ==
1269 !!(paint.getFlags() & SkPaint::kAutoHinting_Flag) ? '=' : '!');
1270 }
1271 #StdOut
1272 paint.isAutohinted() == !!(paint.getFlags() & SkPaint::kAutoHinting_Flag)
1273 paint.isAutohinted() == !!(paint.getFlags() & SkPaint::kAutoHinting_Flag)
1274 ##
1275 ##
1276
1277 #SeeAlso setAutohinted Hinting
1278
1279##
1280
1281#Method void setAutohinted(bool useAutohinter)
1282
Cary Clarkab2621d2018-01-30 10:08:57 -05001283#In Automatic_Hinting
1284#Line # sets Glyphs to always be hinted ##
Cary Clark80247e52018-07-11 16:18:41 -04001285 Sets whether to always hint Glyphs.
Cary Clark8032b982017-07-28 11:04:54 -04001286 If Hinting is set to kNormal_Hinting or kFull_Hinting and useAutohinter is set,
Cary Clark80247e52018-07-11 16:18:41 -04001287 instructs the Font_Manager to always hint Glyphs.
Cary Clark8032b982017-07-28 11:04:54 -04001288 Automatic_Hinting has no effect if Hinting is set to kNo_Hinting or
1289 kSlight_Hinting.
1290
Cary Clark579985c2017-07-31 11:48:27 -04001291 Only affects platforms that use FreeType as the Font_Manager.
Cary Clark8032b982017-07-28 11:04:54 -04001292
1293 Sets kAutoHinting_Flag if useAutohinter is true.
1294 Clears kAutoHinting_Flag if useAutohinter is false.
1295
1296 #Param useAutohinter setting for kAutoHinting_Flag ##
1297
1298 #Example
1299 void draw(SkCanvas* canvas) {
1300 SkPaint paint;
1301 paint.setAntiAlias(true);
1302 const char testStr[] = "xxxx xxxx";
1303 for (auto forceAutoHinting : { false, true} ) {
1304 paint.setAutohinted(forceAutoHinting);
1305 paint.setTextSize(24);
1306 canvas->drawString(paint.isAutohinted() ? "auto-hinted" : "default", 108, 30, paint);
1307 for (SkScalar textSize = 8; textSize < 30; textSize *= 1.22f) {
1308 paint.setTextSize(textSize);
1309 canvas->translate(0, textSize);
1310 canvas->drawString(testStr, 10, 0, paint);
1311 }
1312 }
1313 }
1314 ##
1315
1316 #SeeAlso isAutohinted Hinting
1317
1318##
1319
Cary Clark08895c42018-02-01 09:37:32 -05001320#Subtopic Automatic_Hinting ##
Cary Clark8032b982017-07-28 11:04:54 -04001321# ------------------------------------------------------------------------------
Cary Clark08895c42018-02-01 09:37:32 -05001322#Subtopic Vertical_Text
1323#Line # orient text from top to bottom ##
Cary Clark8032b982017-07-28 11:04:54 -04001324
1325Text may be drawn by positioning each glyph, or by positioning the first glyph and
Cary Clarkce101242017-09-01 15:51:02 -04001326using Font_Advance to position subsequent Glyphs. By default, each successive glyph
1327is positioned to the right of the preceding glyph. Vertical_Text sets successive
1328Glyphs to position below the preceding glyph.
Cary Clark8032b982017-07-28 11:04:54 -04001329
Cary Clarkce101242017-09-01 15:51:02 -04001330Skia can translate text character codes as a series of Glyphs, but does not implement
Herb Derbyfcac00f2018-05-01 11:57:56 -04001331font substitution,
Cary Clarkce101242017-09-01 15:51:02 -04001332textual substitution, line layout, or contextual spacing like Kerning pairs. Use
Cary Clark6fc50412017-09-21 12:31:06 -04001333a text shaping engine like
Cary Clark682c58d2018-05-16 07:07:07 -04001334#A HarfBuzz # https://harfbuzz.org/ ##
Cary Clark6fc50412017-09-21 12:31:06 -04001335 to translate text runs
Cary Clark8032b982017-07-28 11:04:54 -04001336into glyph series.
1337
1338Vertical_Text is clear if text is drawn left to right or set if drawn from top to bottom.
1339
1340Flags kVerticalText_Flag if clear draws text left to right.
1341Flags kVerticalText_Flag if set draws text top to bottom.
1342
1343Vertical_Text is clear by default.
1344Vertical_Text can be set by default by setting SkPaintDefaults_Flags to
1345kVerticalText_Flag at compile time.
1346
1347#Example
1348
1349void draw(SkCanvas* canvas) {
1350 SkPaint paint;
1351 paint.setAntiAlias(true);
1352 paint.setTextSize(50);
1353 for (bool vertical : { false, true } ) {
1354 paint.setVerticalText(vertical);
1355 canvas->drawString("aAlL", 25, 50, paint);
1356 }
1357}
1358
1359##
1360
1361#Method bool isVerticalText() const
1362
Cary Clarkab2621d2018-01-30 10:08:57 -05001363#In Vertical_Text
1364#Line # returns true if Vertical_Text is set ##
Cary Clark80247e52018-07-11 16:18:41 -04001365 Returns true if Glyphs are drawn top to bottom instead of left to right.
Cary Clark8032b982017-07-28 11:04:54 -04001366
1367 Equivalent to getFlags masked with kVerticalText_Flag.
1368
1369 #Return kVerticalText_Flag state ##
1370
1371 #Example
1372 SkPaint paint;
1373 SkDebugf("paint.isVerticalText() %c= !!(paint.getFlags() & SkPaint::kVerticalText_Flag)\n",
1374 paint.isVerticalText() == !!(paint.getFlags() & SkPaint::kVerticalText_Flag) ? '=' : '!');
1375 paint.setVerticalText(true);
1376 SkDebugf("paint.isVerticalText() %c= !!(paint.getFlags() & SkPaint::kVerticalText_Flag)\n",
1377 paint.isVerticalText() == !!(paint.getFlags() & SkPaint::kVerticalText_Flag) ? '=' : '!');
1378
1379 #StdOut
1380 paint.isVerticalText() == !!(paint.getFlags() & SkPaint::kVerticalText_Flag)
1381 paint.isVerticalText() == !!(paint.getFlags() & SkPaint::kVerticalText_Flag)
1382 ##
1383 ##
1384
1385##
1386
1387#Method void setVerticalText(bool verticalText)
1388
Cary Clarkab2621d2018-01-30 10:08:57 -05001389#In Vertical_Text
1390#Line # sets or clears Vertical_Text ##
Cary Clark80247e52018-07-11 16:18:41 -04001391 Returns true if text advance positions the next glyph below the previous glyph instead of to the
Cary Clark8032b982017-07-28 11:04:54 -04001392 right of previous glyph.
1393
1394 Sets kVerticalText_Flag if vertical is true.
1395 Clears kVerticalText_Flag if vertical is false.
1396
1397 #Param verticalText setting for kVerticalText_Flag ##
1398
1399 #Example
1400 SkPaint paint1, paint2;
1401 paint1.setVerticalText(true);
1402 paint2.setFlags(paint2.getFlags() | SkPaint::kVerticalText_Flag);
1403 SkDebugf("paint1 %c= paint2\n", paint1 == paint2 ? '=' : '!');
1404
1405 #StdOut
1406 paint1 == paint2
1407 ##
1408 ##
1409
1410##
1411
Cary Clark08895c42018-02-01 09:37:32 -05001412#Subtopic Vertical_Text ##
Cary Clark8032b982017-07-28 11:04:54 -04001413# ------------------------------------------------------------------------------
1414
Cary Clark08895c42018-02-01 09:37:32 -05001415#Subtopic Fake_Bold
1416#Line # approximate font styles ##
Cary Clark8032b982017-07-28 11:04:54 -04001417
1418Fake_Bold approximates the bold font style accompanying a normal font when a bold font face
1419is not available. Skia does not provide font substitution; it is up to the client to find the
Cary Clarkbc5697d2017-10-04 14:31:33 -04001420bold font face using the platform Font_Manager.
Cary Clark8032b982017-07-28 11:04:54 -04001421
Herb Derbyfcac00f2018-05-01 11:57:56 -04001422Use Text_Skew_X to approximate an italic font style when the italic font face
Cary Clark8032b982017-07-28 11:04:54 -04001423is not available.
1424
Cary Clarkce101242017-09-01 15:51:02 -04001425A FreeType based port may define SK_USE_FREETYPE_EMBOLDEN at compile time to direct
1426the font engine to create the bold Glyphs. Otherwise, the extra bold is computed
Herb Derbyfcac00f2018-05-01 11:57:56 -04001427by increasing the stroke width and setting the Style to kStrokeAndFill_Style as needed.
Cary Clark8032b982017-07-28 11:04:54 -04001428
1429Fake_Bold is disabled by default.
1430
1431#Example
1432#Height 128
1433void draw(SkCanvas* canvas) {
1434 SkPaint paint;
1435 paint.setAntiAlias(true);
1436 paint.setTextSize(40);
1437 canvas->drawString("OjYy_-", 10, 35, paint);
1438 paint.setFakeBoldText(true);
1439 canvas->drawString("OjYy_-", 10, 75, paint);
1440 // create a custom fake bold by varying the stroke width
1441 paint.setFakeBoldText(false);
1442 paint.setStyle(SkPaint::kStrokeAndFill_Style);
1443 paint.setStrokeWidth(40.f / 48);
1444 canvas->drawString("OjYy_-", 10, 115, paint);
1445}
1446##
1447
1448#Method bool isFakeBoldText() const
1449
Cary Clarkab2621d2018-01-30 10:08:57 -05001450#In Fake_Bold
1451#Line # returns true if Fake_Bold is set ##
Cary Clark80247e52018-07-11 16:18:41 -04001452 Returns true if approximate bold by increasing the stroke width when creating glyph bitmaps
Cary Clark8032b982017-07-28 11:04:54 -04001453 from outlines.
1454
1455 Equivalent to getFlags masked with kFakeBoldText_Flag.
1456
1457 #Return kFakeBoldText_Flag state ##
1458
1459 #Example
1460 SkPaint paint;
1461 SkDebugf("paint.isFakeBoldText() %c= !!(paint.getFlags() & SkPaint::kFakeBoldText_Flag)\n",
1462 paint.isFakeBoldText() == !!(paint.getFlags() & SkPaint::kFakeBoldText_Flag) ? '=' : '!');
1463 paint.setFakeBoldText(true);
1464 SkDebugf("paint.isFakeBoldText() %c= !!(paint.getFlags() & SkPaint::kFakeBoldText_Flag)\n",
1465 paint.isFakeBoldText() == !!(paint.getFlags() & SkPaint::kFakeBoldText_Flag) ? '=' : '!');
1466
1467 #StdOut
1468 paint.isFakeBoldText() == !!(paint.getFlags() & SkPaint::kFakeBoldText_Flag)
1469 paint.isFakeBoldText() == !!(paint.getFlags() & SkPaint::kFakeBoldText_Flag)
1470 ##
1471 ##
1472
1473##
1474
1475#Method void setFakeBoldText(bool fakeBoldText)
1476
Cary Clarkab2621d2018-01-30 10:08:57 -05001477#In Fake_Bold
1478#Line # sets or clears Fake_Bold ##
Cary Clark80247e52018-07-11 16:18:41 -04001479 Increases stroke width when creating glyph bitmaps to approximate a bold typeface.
Cary Clark8032b982017-07-28 11:04:54 -04001480
1481 Sets kFakeBoldText_Flag if fakeBoldText is true.
1482 Clears kFakeBoldText_Flag if fakeBoldText is false.
1483
1484 #Param fakeBoldText setting for kFakeBoldText_Flag ##
1485
1486 #Example
1487 SkPaint paint1, paint2;
1488 paint1.setFakeBoldText(true);
1489 paint2.setFlags(paint2.getFlags() | SkPaint::kFakeBoldText_Flag);
1490 SkDebugf("paint1 %c= paint2\n", paint1 == paint2 ? '=' : '!');
1491
1492 #StdOut
1493 paint1 == paint2
1494 ##
1495 ##
1496
1497##
1498
Cary Clark08895c42018-02-01 09:37:32 -05001499#Subtopic Fake_Bold ##
Cary Clark8032b982017-07-28 11:04:54 -04001500
1501# ------------------------------------------------------------------------------
Cary Clark08895c42018-02-01 09:37:32 -05001502#Subtopic Full_Hinting_Spacing
1503#Line # glyph spacing affected by hinting ##
Cary Clark137b8742018-05-30 09:21:49 -04001504#Alias Full_Hinting_Spacing ## # long winded enough -- maybe things with two underscores auto-aliased?
Cary Clark8032b982017-07-28 11:04:54 -04001505
Cary Clarkce101242017-09-01 15:51:02 -04001506if Hinting is set to kFull_Hinting, Full_Hinting_Spacing adjusts the character
1507spacing by the difference of the hinted and Unhinted Left_Side_Bearing and
1508Right_Side_Bearing. Full_Hinting_Spacing only applies to platforms that use
1509FreeType as their Font_Engine.
Cary Clark8032b982017-07-28 11:04:54 -04001510
Cary Clarkce101242017-09-01 15:51:02 -04001511Full_Hinting_Spacing is not related to text Kerning, where the space between
Cary Clarkbc5697d2017-10-04 14:31:33 -04001512a specific pair of characters is adjusted using data in the font Kerning tables.
Cary Clark8032b982017-07-28 11:04:54 -04001513
1514#Method bool isDevKernText() const
Herb Derbyfcac00f2018-05-01 11:57:56 -04001515#Deprecated
Cary Clark8032b982017-07-28 11:04:54 -04001516##
1517
Herb Derbyfcac00f2018-05-01 11:57:56 -04001518#Method void setDevKernText(bool)
1519#Deprecated
Cary Clark8032b982017-07-28 11:04:54 -04001520##
1521
Cary Clark08895c42018-02-01 09:37:32 -05001522#Subtopic Full_Hinting_Spacing ##
Cary Clark8032b982017-07-28 11:04:54 -04001523# ------------------------------------------------------------------------------
Cary Clark08895c42018-02-01 09:37:32 -05001524#Subtopic Filter_Quality_Methods
1525#Line # get and set Filter_Quality ##
Cary Clark8032b982017-07-28 11:04:54 -04001526
1527Filter_Quality trades speed for image filtering when the image is scaled.
1528A lower Filter_Quality draws faster, but has less fidelity.
1529A higher Filter_Quality draws slower, but looks better.
Cary Clarkce101242017-09-01 15:51:02 -04001530If the image is drawn without scaling, the Filter_Quality choice will not result
1531in a noticeable difference.
Cary Clark8032b982017-07-28 11:04:54 -04001532
1533Filter_Quality is used in Paint passed as a parameter to
1534#List
1535# SkCanvas::drawBitmap ##
1536# SkCanvas::drawBitmapRect ##
1537# SkCanvas::drawImage ##
1538# SkCanvas::drawImageRect ##
1539 #ToDo probably more... ##
1540#List ##
1541and when Paint has a Shader specialization that uses Image or Bitmap.
1542
1543Filter_Quality is kNone_SkFilterQuality by default.
1544
1545#Example
1546#Image 3
1547void draw(SkCanvas* canvas) {
1548 SkPaint paint;
1549 canvas->scale(.2f, .2f);
Herb Derbyfcac00f2018-05-01 11:57:56 -04001550 for (SkFilterQuality q : { kNone_SkFilterQuality, kLow_SkFilterQuality,
Cary Clark8032b982017-07-28 11:04:54 -04001551 kMedium_SkFilterQuality, kHigh_SkFilterQuality } ) {
1552 paint.setFilterQuality(q);
1553 canvas->drawImage(image.get(), 0, 0, &paint);
1554 canvas->translate(550, 0);
1555 if (kLow_SkFilterQuality == q) canvas->translate(-1100, 550);
1556 }
1557}
1558##
1559
1560#Method SkFilterQuality getFilterQuality() const
1561
Cary Clarkab2621d2018-01-30 10:08:57 -05001562#In Filter_Quality_Methods
1563#Line # returns Filter_Quality, image filtering level ##
Cary Clark8032b982017-07-28 11:04:54 -04001564Returns Filter_Quality, the image filtering level. A lower setting
1565draws faster; a higher setting looks better when the image is scaled.
1566
Herb Derbyfcac00f2018-05-01 11:57:56 -04001567#Return one of: kNone_SkFilterQuality, kLow_SkFilterQuality,
Cary Clark8032b982017-07-28 11:04:54 -04001568 kMedium_SkFilterQuality, kHigh_SkFilterQuality
1569#Return ##
1570
1571#Example
1572 SkPaint paint;
1573 SkDebugf("kNone_SkFilterQuality %c= paint.getFilterQuality()\n",
1574 kNone_SkFilterQuality == paint.getFilterQuality() ? '=' : '!');
1575
1576 #StdOut
1577 kNone_SkFilterQuality == paint.getFilterQuality()
1578 ##
1579##
1580
1581##
1582
1583
1584#Method void setFilterQuality(SkFilterQuality quality)
1585
Cary Clarkab2621d2018-01-30 10:08:57 -05001586#In Filter_Quality_Methods
1587#Line # sets Filter_Quality, the image filtering level ##
Cary Clark8032b982017-07-28 11:04:54 -04001588Sets Filter_Quality, the image filtering level. A lower setting
1589draws faster; a higher setting looks better when the image is scaled.
Herb Derbyfcac00f2018-05-01 11:57:56 -04001590Does not check to see if quality is valid.
Cary Clark8032b982017-07-28 11:04:54 -04001591
Herb Derbyfcac00f2018-05-01 11:57:56 -04001592#Param quality one of: kNone_SkFilterQuality, kLow_SkFilterQuality,
Cary Clark8032b982017-07-28 11:04:54 -04001593 kMedium_SkFilterQuality, kHigh_SkFilterQuality
1594##
1595
1596#Example
1597 SkPaint paint;
1598 paint.setFilterQuality(kHigh_SkFilterQuality);
1599 SkDebugf("kHigh_SkFilterQuality %c= paint.getFilterQuality()\n",
1600 kHigh_SkFilterQuality == paint.getFilterQuality() ? '=' : '!');
1601
1602 #StdOut
1603 kHigh_SkFilterQuality == paint.getFilterQuality()
1604 ##
1605##
1606
1607#SeeAlso SkFilterQuality Image_Scaling
1608
1609##
1610
Cary Clark08895c42018-02-01 09:37:32 -05001611#Subtopic Filter_Quality_Methods ##
Cary Clark8032b982017-07-28 11:04:54 -04001612# ------------------------------------------------------------------------------
Cary Clark08895c42018-02-01 09:37:32 -05001613#Subtopic Color_Methods
1614#Line # get and set Color ##
Cary Clark8032b982017-07-28 11:04:54 -04001615
Cary Clarkab2621d2018-01-30 10:08:57 -05001616#Table
1617#Legend
1618# name # description ##
1619#Legend ##
Cary Clarkffb3d682018-05-17 12:17:28 -04001620# getColor # returns Color_Alpha and RGB, one drawing color ##
1621# setColor # sets Color_Alpha and RGB, one drawing color ##
Cary Clarkab2621d2018-01-30 10:08:57 -05001622#Table ##
Cary Clark8032b982017-07-28 11:04:54 -04001623
Cary Clarkffb3d682018-05-17 12:17:28 -04001624Color specifies the red, blue, green, and Color_Alpha
Cary Clarkab2621d2018-01-30 10:08:57 -05001625values used to draw a filled or stroked shape in a 32-bit value. Each component
1626occupies 8-bits, ranging from zero: no contribution; to 255: full intensity.
1627All values in any combination are valid.
Cary Clark8032b982017-07-28 11:04:54 -04001628
Cary Clarkab2621d2018-01-30 10:08:57 -05001629Color is not Premultiplied; Color_Alpha sets the transparency independent of
Cary Clarkffb3d682018-05-17 12:17:28 -04001630RGB: red, blue, and green.
Cary Clarkab2621d2018-01-30 10:08:57 -05001631
Cary Clarkffb3d682018-05-17 12:17:28 -04001632The bit positions of Color_Alpha and RGB are independent of the bit
Cary Clarkab2621d2018-01-30 10:08:57 -05001633positions on the output device, which may have more or fewer bits, and may have
1634a different arrangement.
Cary Clark8032b982017-07-28 11:04:54 -04001635
1636#Table
1637#Legend
Cary Clarkffb3d682018-05-17 12:17:28 -04001638# bit positions # Color_Alpha # red # blue # green ##
Cary Clark8032b982017-07-28 11:04:54 -04001639#Legend ##
1640# # 31 - 24 # 23 - 16 # 15 - 8 # 7 - 0 ##
1641#Table ##
1642
1643#Example
1644#Height 128
1645 void draw(SkCanvas* canvas) {
1646 SkPaint paint;
1647 paint.setColor(0x8000FF00); // transparent green
1648 canvas->drawCircle(50, 50, 40, paint);
1649 paint.setARGB(128, 255, 0, 0); // transparent red
1650 canvas->drawCircle(80, 50, 40, paint);
1651 paint.setColor(SK_ColorBLUE);
1652 paint.setAlpha(0x80);
1653 canvas->drawCircle(65, 65, 40, paint);
1654 }
1655##
1656
1657#Method SkColor getColor() const
Cary Clarkab2621d2018-01-30 10:08:57 -05001658#In Color_Methods
Cary Clarkffb3d682018-05-17 12:17:28 -04001659#Line # returns Color_Alpha and RGB, one drawing color ##
1660 Retrieves Alpha and RGB, Unpremultiplied, packed into 32 bits.
Cary Clark8032b982017-07-28 11:04:54 -04001661 Use helpers SkColorGetA, SkColorGetR, SkColorGetG, and SkColorGetB to extract
1662 a color component.
1663
Cary Clarkffb3d682018-05-17 12:17:28 -04001664 #Return Unpremultiplied ARGB ##
Cary Clark8032b982017-07-28 11:04:54 -04001665
1666 #Example
1667 SkPaint paint;
1668 paint.setColor(SK_ColorYELLOW);
1669 SkColor y = paint.getColor();
1670 SkDebugf("Yellow is %d%% red, %d%% green, and %d%% blue.\n", (int) (SkColorGetR(y) / 2.55f),
1671 (int) (SkColorGetG(y) / 2.55f), (int) (SkColorGetB(y) / 2.55f));
1672
1673 #StdOut
1674 Yellow is 100% red, 100% green, and 0% blue.
1675 ##
1676 ##
1677
Cary Clarkbbe8ff92018-09-05 11:39:01 -04001678 #SeeAlso getColor4f SkColor
Cary Clark8032b982017-07-28 11:04:54 -04001679
1680##
1681
Cary Clarkbbe8ff92018-09-05 11:39:01 -04001682#Method SkColor4f getColor4f() const
1683#In Color_Methods
1684#Line # returns Color_Alpha and RGB, one drawing color ##
1685 Retrieves alpha and RGB, unpmreultiplied, as four floating point values. RGB are
1686 are extended sRGB values (sRGB gamut, and encoded with the sRGB transfer function).
Brian Osman3f70d172018-09-04 19:50:28 +00001687
Cary Clarkbbe8ff92018-09-05 11:39:01 -04001688 #Return Unpremultiplied RGBA ##
1689
1690 #ToDo enable and correct example once fiddle picks up getColor4f ##
1691 #Example
1692 SkPaint paint;
1693 paint.setColor(SK_ColorYELLOW);
1694 SkColor4f y = paint.getColor4f();
1695 SkDebugf("Yellow is %d%% red, %d%% green, and %d%% blue.\n", (int) (y.fR * 100),
1696 (int) (y.fG * 100), (int) (y.fB * 100));
1697
1698 #StdOut
1699 Yellow is 100% red, 100% green, and 0% blue.
1700 ##
1701 ##
1702
1703 #SeeAlso getColor SkColor
1704##
1705
1706
1707#Method void setColor(SkColor color)
Cary Clarkab2621d2018-01-30 10:08:57 -05001708#In Color_Methods
Cary Clarkffb3d682018-05-17 12:17:28 -04001709#Line # sets Color_Alpha and RGB, one drawing color ##
1710 Sets Alpha and RGB used when stroking and filling. The color is a 32-bit value,
1711 Unpremultiplied, packing 8-bit components for Alpha, red, blue, and green.
Cary Clark8032b982017-07-28 11:04:54 -04001712
Cary Clarkffb3d682018-05-17 12:17:28 -04001713 #Param color Unpremultiplied ARGB ##
Herb Derbyfcac00f2018-05-01 11:57:56 -04001714
Cary Clark0c5f5462017-12-15 11:21:51 -05001715 #Example
Cary Clark8032b982017-07-28 11:04:54 -04001716 SkPaint green1, green2;
1717 unsigned a = 255;
1718 unsigned r = 0;
1719 unsigned g = 255;
1720 unsigned b = 0;
1721 green1.setColor((a << 24) + (r << 16) + (g << 8) + (b << 0));
1722 green2.setColor(0xFF00FF00);
1723 SkDebugf("green1 %c= green2\n", green1 == green2 ? '=' : '!');
1724
1725 #StdOut
1726 green1 == green2
1727 ##
1728 ##
1729
Cary Clarkbbe8ff92018-09-05 11:39:01 -04001730 #SeeAlso SkColor setColor4f setARGB SkColorSetARGB
Cary Clark8032b982017-07-28 11:04:54 -04001731
1732##
Cary Clarkbbe8ff92018-09-05 11:39:01 -04001733
1734#Method void setColor4f(const SkColor4f& color, SkColorSpace* colorSpace)
1735#In Color_Methods
1736#Line # sets Color_Alpha and RGB, one drawing color ##
1737 Sets alpha and RGB used when stroking and filling. The color is four floating
1738 point values, unpremultiplied. The color values are interpreted as being in
1739 the colorSpace. If colorSpace is nullptr, then color is assumed to be in the
1740 sRGB color space.
1741
1742 #Param color Unpremultiplied RGBA ##
1743 #Param colorSpace Color_Space describing the encoding of color ##
1744
1745 #ToDo enable and correct example once fiddle picks up setColor4f ##
1746 #Example
1747 SkPaint green1, green2;
1748 green1.setColor4f({0, 1, 0, 1}, nullptr); // R=0 G=1 B=0 A=1
1749 green2.setColor(0xFF00FF00); // A=255 R=0 G=255 B=0
1750 SkDebugf("green1 %c= green2\n", green1 == green2 ? '=' : '!');
1751
1752 #StdOut
1753 green1 == green2
1754 ##
1755 ##
1756
1757 #SeeAlso SkColor setColor setARGB SkColorSetARGB
1758
1759##
1760
Cary Clark08895c42018-02-01 09:37:32 -05001761#Subtopic Color_Methods ##
Cary Clark8032b982017-07-28 11:04:54 -04001762
1763#Subtopic Alpha_Methods
Cary Clark08895c42018-02-01 09:37:32 -05001764#Line # get and set Alpha ##
Cary Clark8032b982017-07-28 11:04:54 -04001765
Cary Clarkffb3d682018-05-17 12:17:28 -04001766Color_Alpha sets the transparency independent of RGB: red, blue, and green.
Cary Clark8032b982017-07-28 11:04:54 -04001767
1768#Method uint8_t getAlpha() const
1769
Cary Clarkab2621d2018-01-30 10:08:57 -05001770#In Alpha_Methods
1771#Line # returns Color_Alpha, color opacity ##
Cary Clarkce101242017-09-01 15:51:02 -04001772 Retrieves Alpha from the Color used when stroking and filling.
Cary Clark8032b982017-07-28 11:04:54 -04001773
Cary Clarkce101242017-09-01 15:51:02 -04001774 #Return Alpha ranging from zero, fully transparent, to 255, fully opaque ##
Cary Clark8032b982017-07-28 11:04:54 -04001775
1776 #Example
1777 SkPaint paint;
1778 SkDebugf("255 %c= paint.getAlpha()\n", 255 == paint.getAlpha() ? '=' : '!');
1779
1780 #StdOut
1781 255 == paint.getAlpha()
1782 ##
1783 ##
1784
1785##
1786
1787#Method void setAlpha(U8CPU a)
1788
Cary Clarkab2621d2018-01-30 10:08:57 -05001789#In Alpha_Methods
1790#Line # sets Color_Alpha, color opacity ##
Cary Clarkffb3d682018-05-17 12:17:28 -04001791 Replaces Alpha, leaving RGB
Cary Clark8032b982017-07-28 11:04:54 -04001792 unchanged. An out of range value triggers an assert in the debug
1793 build. a is a value from zero to 255.
1794 a set to zero makes Color fully transparent; a set to 255 makes Color
1795 fully opaque.
1796
Cary Clarkce101242017-09-01 15:51:02 -04001797 #Param a Alpha component of Color ##
Cary Clark8032b982017-07-28 11:04:54 -04001798
1799 #Example
1800 SkPaint paint;
1801 paint.setColor(0x00112233);
1802 paint.setAlpha(0x44);
1803 SkDebugf("0x44112233 %c= paint.getColor()\n", 0x44112233 == paint.getColor() ? '=' : '!');
1804
1805 #StdOut
1806 0x44112233 == paint.getColor()
1807 ##
1808 ##
1809
1810##
1811
Cary Clark08895c42018-02-01 09:37:32 -05001812#Subtopic Alpha_Methods ##
Cary Clark8032b982017-07-28 11:04:54 -04001813
1814#Method void setARGB(U8CPU a, U8CPU r, U8CPU g, U8CPU b)
1815
Cary Clarkab2621d2018-01-30 10:08:57 -05001816#In Color_Methods
1817#Line # sets color by component ##
Cary Clark8032b982017-07-28 11:04:54 -04001818 Sets Color used when drawing solid fills. The color components range from 0 to 255.
Cary Clarkffb3d682018-05-17 12:17:28 -04001819 The color is Unpremultiplied; Alpha sets the transparency independent of RGB.
Cary Clark8032b982017-07-28 11:04:54 -04001820
1821 #Param a amount of Color_Alpha, from fully transparent (0) to fully opaque (255) ##
Cary Clarkffb3d682018-05-17 12:17:28 -04001822 #Param r amount of red, from no red (0) to full red (255) ##
1823 #Param g amount of green, from no green (0) to full green (255) ##
1824 #Param b amount of blue, from no blue (0) to full blue (255) ##
Herb Derbyfcac00f2018-05-01 11:57:56 -04001825
Cary Clark8032b982017-07-28 11:04:54 -04001826 #Example
1827 SkPaint transRed1, transRed2;
1828 transRed1.setARGB(255 / 2, 255, 0, 0);
1829 transRed2.setColor(SkColorSetARGB(255 / 2, 255, 0, 0));
1830 SkDebugf("transRed1 %c= transRed2", transRed1 == transRed2 ? '=' : '!');
1831
1832 #StdOut
1833 transRed1 == transRed2
1834 ##
1835 ##
1836
1837 #SeeAlso setColor SkColorSetARGB
1838
1839##
1840
Cary Clark8032b982017-07-28 11:04:54 -04001841# ------------------------------------------------------------------------------
Cary Clark08895c42018-02-01 09:37:32 -05001842#Subtopic Style
1843#Line # geometry filling, stroking ##
Cary Clark8032b982017-07-28 11:04:54 -04001844
1845Style specifies if the geometry is filled, stroked, or both filled and stroked.
1846Some shapes ignore Style and are always drawn filled or stroked.
1847
1848Set Style to kFill_Style to fill the shape.
1849The fill covers the area inside the geometry for most shapes.
1850
1851Set Style to kStroke_Style to stroke the shape.
1852
1853# ------------------------------------------------------------------------------
1854#Subtopic Fill
Cary Clark08895c42018-02-01 09:37:32 -05001855#Line # fill and stroke ##
Cary Clark8032b982017-07-28 11:04:54 -04001856#ToDo write up whatever generalities make sense to describe filling ##
1857
1858#SeeAlso Path_Fill_Type
Cary Clark08895c42018-02-01 09:37:32 -05001859#Subtopic Fill ##
Cary Clark8032b982017-07-28 11:04:54 -04001860
1861#Subtopic Stroke
Cary Clark08895c42018-02-01 09:37:32 -05001862#Line # lines and curves with width ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001863The stroke covers the area described by following the shape edge with a pen or brush of
Cary Clark8032b982017-07-28 11:04:54 -04001864Stroke_Width. The area covered where the shape starts and stops is described by Stroke_Cap.
1865The area covered where the shape turns a corner is described by Stroke_Join.
Cary Clarkbc5697d2017-10-04 14:31:33 -04001866The stroke is centered on the shape; it extends equally on either side of the shape edge.
Cary Clark8032b982017-07-28 11:04:54 -04001867
1868As Stroke_Width gets smaller, the drawn path frame is thinner. Stroke_Width less than one
1869may have gaps, and if kAntiAlias_Flag is set, Color_Alpha will increase to visually decrease coverage.
Cary Clark08895c42018-02-01 09:37:32 -05001870#Subtopic Stroke ##
Cary Clark8032b982017-07-28 11:04:54 -04001871
1872#Subtopic Hairline
Cary Clark08895c42018-02-01 09:37:32 -05001873#Line # lines and curves with minimal width ##
Cary Clark137b8742018-05-30 09:21:49 -04001874#Alias Hairline ## # maybe should be Stroke_Hairline ?
Cary Clark8032b982017-07-28 11:04:54 -04001875
1876Stroke_Width of zero has a special meaning and switches drawing to use Hairline.
Herb Derbyfcac00f2018-05-01 11:57:56 -04001877Hairline draws the thinnest continuous frame. If kAntiAlias_Flag is clear, adjacent pixels
1878flow horizontally, vertically,or diagonally.
Cary Clark8032b982017-07-28 11:04:54 -04001879
Cary Clarkffb3d682018-05-17 12:17:28 -04001880#ToDo what is the description of Anti_Aliased hairlines? ##
Cary Clark8032b982017-07-28 11:04:54 -04001881
1882Path drawing with Hairline may hit the same pixel more than once. For instance, Path containing
1883two lines in one Path_Contour will draw the corner point once, but may both lines may draw the adjacent
1884pixel. If kAntiAlias_Flag is set, transparency is applied twice, resulting in a darker pixel. Some
1885GPU-backed implementations apply transparency at a later drawing stage, avoiding double hit pixels
1886while stroking.
1887
Cary Clark08895c42018-02-01 09:37:32 -05001888#Subtopic Hairline ##
Cary Clark8032b982017-07-28 11:04:54 -04001889
1890#Enum Style
Cary Clark08895c42018-02-01 09:37:32 -05001891#Line # stroke, fill, or both ##
Cary Clark8032b982017-07-28 11:04:54 -04001892
1893#Code
1894 enum Style {
1895 kFill_Style,
1896 kStroke_Style,
1897 kStrokeAndFill_Style,
1898 };
Cary Clarkd98f78c2018-04-26 08:32:37 -04001899
1900 static constexpr int kStyleCount = kStrokeAndFill_Style + 1;
Cary Clark8032b982017-07-28 11:04:54 -04001901##
1902
1903Set Style to fill, stroke, or both fill and stroke geometry.
1904The stroke and fill
1905share all paint attributes; for instance, they are drawn with the same color.
1906
1907Use kStrokeAndFill_Style to avoid hitting the same pixels twice with a stroke draw and
1908a fill draw.
1909
1910#Const kFill_Style 0
Cary Clark682c58d2018-05-16 07:07:07 -04001911#Line # set to fill geometry ##
Herb Derbyfcac00f2018-05-01 11:57:56 -04001912 Applies to Rect, Region, Round_Rect, Circles, Ovals, Path, and Text.
Cary Clarkce101242017-09-01 15:51:02 -04001913 Bitmap, Image, Patches, Region, Sprites, and Vertices are painted as if
Cary Clark8032b982017-07-28 11:04:54 -04001914 kFill_Style is set, and ignore the set Style.
1915 The Path_Fill_Type specifies additional rules to fill the area outside the path edge,
1916 and to create an unfilled hole inside the shape.
1917 Style is set to kFill_Style by default.
1918##
1919
1920#Const kStroke_Style 1
Cary Clark682c58d2018-05-16 07:07:07 -04001921#Line # set to stroke geometry ##
Herb Derbyfcac00f2018-05-01 11:57:56 -04001922 Applies to Rect, Region, Round_Rect, Arcs, Circles, Ovals, Path, and Text.
Cary Clark56356312018-02-08 14:45:18 -05001923 Arcs, Lines, and points, are always drawn as if kStroke_Style is set,
Cary Clark8032b982017-07-28 11:04:54 -04001924 and ignore the set Style.
1925 The stroke construction is unaffected by the Path_Fill_Type.
1926##
1927
1928#Const kStrokeAndFill_Style 2
Cary Clark682c58d2018-05-16 07:07:07 -04001929#Line # sets to stroke and fill geometry ##
Cary Clarkce101242017-09-01 15:51:02 -04001930 Applies to Rect, Region, Round_Rect, Circles, Ovals, Path, and Text.
Cary Clark8032b982017-07-28 11:04:54 -04001931 Path is treated as if it is set to SkPath::kWinding_FillType,
Herb Derbyfcac00f2018-05-01 11:57:56 -04001932 and the set Path_Fill_Type is ignored.
Cary Clark8032b982017-07-28 11:04:54 -04001933##
1934
Cary Clark8032b982017-07-28 11:04:54 -04001935#Const kStyleCount 3
Cary Clark682c58d2018-05-16 07:07:07 -04001936#Line # number of different Style values defined ##
Cary Clark8032b982017-07-28 11:04:54 -04001937May be used to verify that Style is a legal value.
1938##
1939
Cary Clarkd98f78c2018-04-26 08:32:37 -04001940#Enum Style ##
Cary Clark8032b982017-07-28 11:04:54 -04001941
1942#Method Style getStyle() const
1943
Cary Clarkab2621d2018-01-30 10:08:57 -05001944#In Style
1945#Line # returns Style: stroke, fill, or both ##
Cary Clark80247e52018-07-11 16:18:41 -04001946 Returns whether the geometry is filled, stroked, or filled and stroked.
Cary Clark8032b982017-07-28 11:04:54 -04001947
1948 #Return one of:kFill_Style, kStroke_Style, kStrokeAndFill_Style ##
1949
1950 #Example
1951 SkPaint paint;
1952 SkDebugf("SkPaint::kFill_Style %c= paint.getStyle()\n",
1953 SkPaint::kFill_Style == paint.getStyle() ? '=' : '!');
1954
1955 #StdOut
1956 SkPaint::kFill_Style == paint.getStyle()
1957 ##
1958 ##
1959
1960#SeeAlso Style setStyle
1961##
1962
1963#Method void setStyle(Style style)
1964
Cary Clarkab2621d2018-01-30 10:08:57 -05001965#In Style
1966#Line # sets Style: stroke, fill, or both ##
Cary Clark8032b982017-07-28 11:04:54 -04001967 Sets whether the geometry is filled, stroked, or filled and stroked.
1968 Has no effect if style is not a legal Style value.
1969
1970 #Param style one of: kFill_Style, kStroke_Style, kStrokeAndFill_Style
1971 ##
1972
1973 #Example
1974 void draw(SkCanvas* canvas) {
1975 SkPaint paint;
1976 paint.setStrokeWidth(5);
1977 SkRegion region;
1978 region.op(140, 10, 160, 30, SkRegion::kUnion_Op);
1979 region.op(170, 40, 190, 60, SkRegion::kUnion_Op);
1980 SkBitmap bitmap;
1981 bitmap.setInfo(SkImageInfo::MakeA8(50, 50), 50);
1982 uint8_t pixels[50][50];
1983 for (int x = 0; x < 50; ++x) {
1984 for (int y = 0; y < 50; ++y) {
1985 pixels[y][x] = (x + y) % 5 ? 0xFF : 0x00;
1986 }
1987 }
1988 bitmap.setPixels(pixels);
1989 for (auto style : { SkPaint::kFill_Style,
1990 SkPaint::kStroke_Style,
1991 SkPaint::kStrokeAndFill_Style }) {
1992 paint.setStyle(style);
1993 canvas->drawLine(10, 10, 60, 60, paint);
1994 canvas->drawRect({80, 10, 130, 60}, paint);
1995 canvas->drawRegion(region, paint);
1996 canvas->drawBitmap(bitmap, 200, 10, &paint);
1997 canvas->translate(0, 80);
1998 }
1999 }
2000 ##
2001
2002#SeeAlso Style getStyle
2003##
2004
2005#SeeAlso Path_Fill_Type Path_Effect Style_Fill Style_Stroke
Cary Clark08895c42018-02-01 09:37:32 -05002006#Subtopic Style ##
Cary Clark8032b982017-07-28 11:04:54 -04002007
2008# ------------------------------------------------------------------------------
Cary Clark08895c42018-02-01 09:37:32 -05002009#Subtopic Stroke_Width
2010#Line # thickness perpendicular to geometry ##
Cary Clark8032b982017-07-28 11:04:54 -04002011
2012Stroke_Width sets the width for stroking. The width is the thickness
Herb Derbyfcac00f2018-05-01 11:57:56 -04002013of the stroke perpendicular to the path direction when the paint style is
Cary Clark8032b982017-07-28 11:04:54 -04002014set to kStroke_Style or kStrokeAndFill_Style.
2015
2016When width is greater than zero, the stroke encompasses as many pixels partially
2017or fully as needed. When the width equals zero, the paint enables hairlines;
Herb Derbyfcac00f2018-05-01 11:57:56 -04002018the stroke is always one pixel wide.
Cary Clark8032b982017-07-28 11:04:54 -04002019
Cary Clarkbc5697d2017-10-04 14:31:33 -04002020The stroke dimensions are scaled by the canvas matrix, but Hairline stroke
Cary Clark8032b982017-07-28 11:04:54 -04002021remains one pixel wide regardless of scaling.
2022
2023The default width for the paint is zero.
2024
2025#Example
2026#Height 170
2027 #Platform raster gpu
2028 #Description
Herb Derbyfcac00f2018-05-01 11:57:56 -04002029 The pixels hit to represent thin lines vary with the angle of the
Cary Clarkbc5697d2017-10-04 14:31:33 -04002030 line and the platform implementation.
Cary Clark8032b982017-07-28 11:04:54 -04002031 ##
2032 void draw(SkCanvas* canvas) {
2033 SkPaint paint;
Herb Derbyfcac00f2018-05-01 11:57:56 -04002034 for (bool antialias : { false, true }) {
Cary Clark8032b982017-07-28 11:04:54 -04002035 paint.setAntiAlias(antialias);
2036 for (int width = 0; width <= 4; ++width) {
2037 SkScalar offset = antialias * 100 + width * 20;
2038 paint.setStrokeWidth(width * 0.25f);
2039 canvas->drawLine(10 + offset, 10, 20 + offset, 60, paint);
2040 canvas->drawLine(10 + offset, 110, 60 + offset, 160, paint);
2041 }
2042 }
2043 }
2044##
2045
2046#Method SkScalar getStrokeWidth() const
2047
Cary Clarkab2621d2018-01-30 10:08:57 -05002048#In Stroke_Width
2049#Line # returns thickness of the stroke ##
Cary Clark8032b982017-07-28 11:04:54 -04002050 Returns the thickness of the pen used by Paint to
2051 outline the shape.
2052
2053 #Return zero for Hairline, greater than zero for pen thickness ##
Herb Derbyfcac00f2018-05-01 11:57:56 -04002054
Cary Clark8032b982017-07-28 11:04:54 -04002055 #Example
2056 SkPaint paint;
2057 SkDebugf("0 %c= paint.getStrokeWidth()\n", 0 == paint.getStrokeWidth() ? '=' : '!');
2058
2059 #StdOut
2060 0 == paint.getStrokeWidth()
2061 ##
2062 ##
2063
2064##
2065
2066#Method void setStrokeWidth(SkScalar width)
2067
Cary Clarkab2621d2018-01-30 10:08:57 -05002068#In Stroke_Width
2069#Line # sets thickness of the stroke ##
Cary Clark8032b982017-07-28 11:04:54 -04002070 Sets the thickness of the pen used by the paint to
Herb Derbyfcac00f2018-05-01 11:57:56 -04002071 outline the shape.
2072 Has no effect if width is less than zero.
Cary Clark8032b982017-07-28 11:04:54 -04002073
Herb Derbyfcac00f2018-05-01 11:57:56 -04002074 #Param width zero thickness for Hairline; greater than zero for pen thickness
Cary Clark8032b982017-07-28 11:04:54 -04002075 ##
2076
2077 #Example
2078 SkPaint paint;
2079 paint.setStrokeWidth(5);
2080 paint.setStrokeWidth(-1);
2081 SkDebugf("5 %c= paint.getStrokeWidth()\n", 5 == paint.getStrokeWidth() ? '=' : '!');
2082
2083 #StdOut
2084 5 == paint.getStrokeWidth()
2085 ##
2086 ##
2087
2088##
2089
Cary Clark08895c42018-02-01 09:37:32 -05002090#Subtopic Stroke_Width ##
Cary Clark8032b982017-07-28 11:04:54 -04002091# ------------------------------------------------------------------------------
Cary Clark08895c42018-02-01 09:37:32 -05002092#Subtopic Miter_Limit
2093#Line # maximum length of stroked corners ##
Cary Clark8032b982017-07-28 11:04:54 -04002094
2095Miter_Limit specifies the maximum miter length,
2096relative to the stroke width.
2097
2098Miter_Limit is used when the Stroke_Join
2099is set to kMiter_Join, and the Style is either kStroke_Style
2100or kStrokeAndFill_Style.
2101
2102If the miter at a corner exceeds this limit, kMiter_Join
2103is replaced with kBevel_Join.
2104
Cary Clark2be81cf2018-09-13 12:04:30 -04002105Miter_Limit can be computed from the corner angle using:
2106#Formula # miter limit = 1 / sin ( angle / 2 ) ##.
Cary Clark8032b982017-07-28 11:04:54 -04002107
2108Miter_Limit default value is 4.
2109The default may be changed at compile time by setting SkPaintDefaults_MiterLimit
Cary Clarkce101242017-09-01 15:51:02 -04002110in "SkUserConfig.h" or as a define supplied by the build environment.
Cary Clark8032b982017-07-28 11:04:54 -04002111
2112Here are some miter limits and the angles that triggers them.
2113#Table
2114#Legend
2115 # miter limit # angle in degrees ##
2116#Legend ##
2117 # 10 # 11.48 ##
2118 # 9 # 12.76 ##
2119 # 8 # 14.36 ##
2120 # 7 # 16.43 ##
2121 # 6 # 19.19 ##
2122 # 5 # 23.07 ##
2123 # 4 # 28.96 ##
2124 # 3 # 38.94 ##
2125 # 2 # 60 ##
2126 # 1 # 180 ##
2127#Table ##
2128
2129#Example
2130 #Height 170
2131 #Width 384
2132 #Description
2133 This example draws a stroked corner and the miter length beneath.
2134 When the miter limit is decreased slightly, the miter join is replaced
2135 by a bevel join.
2136 ##
2137 void draw(SkCanvas* canvas) {
2138 SkPoint pts[] = {{ 10, 50 }, { 110, 80 }, { 10, 110 }};
2139 SkVector v[] = { pts[0] - pts[1], pts[2] - pts[1] };
2140 SkScalar angle1 = SkScalarATan2(v[0].fY, v[0].fX);
2141 SkScalar angle2 = SkScalarATan2(v[1].fY, v[1].fX);
2142 const SkScalar strokeWidth = 20;
2143 SkScalar miterLimit = 1 / SkScalarSin((angle2 - angle1) / 2);
2144 SkScalar miterLength = strokeWidth * miterLimit;
2145 SkPath path;
2146 path.moveTo(pts[0]);
2147 path.lineTo(pts[1]);
2148 path.lineTo(pts[2]);
2149 SkPaint paint; // set to default kMiter_Join
2150 paint.setAntiAlias(true);
2151 paint.setStyle(SkPaint::kStroke_Style);
2152 paint.setStrokeMiter(miterLimit);
2153 paint.setStrokeWidth(strokeWidth);
2154 canvas->drawPath(path, paint);
2155 paint.setStrokeWidth(1);
2156 canvas->drawLine(pts[1].fX - miterLength / 2, pts[1].fY + 50,
2157 pts[1].fX + miterLength / 2, pts[1].fY + 50, paint);
2158 canvas->translate(200, 0);
2159 miterLimit *= 0.99f;
2160 paint.setStrokeMiter(miterLimit);
2161 paint.setStrokeWidth(strokeWidth);
2162 canvas->drawPath(path, paint);
2163 paint.setStrokeWidth(1);
2164 canvas->drawLine(pts[1].fX - miterLength / 2, pts[1].fY + 50,
2165 pts[1].fX + miterLength / 2, pts[1].fY + 50, paint);
2166 }
2167##
2168
2169#Method SkScalar getStrokeMiter() const
2170
Cary Clarkab2621d2018-01-30 10:08:57 -05002171#In Miter_Limit
2172#Line # returns Miter_Limit, angles with sharp corners ##
Cary Clark80247e52018-07-11 16:18:41 -04002173 Returns the limit at which a sharp corner is drawn beveled.
Cary Clark8032b982017-07-28 11:04:54 -04002174
2175 #Return zero and greater Miter_Limit ##
2176
2177 #Example
2178 SkPaint paint;
2179 SkDebugf("default miter limit == %g\n", paint.getStrokeMiter());
2180
2181 #StdOut
2182 default miter limit == 4
2183 ##
2184 ##
2185
2186 #SeeAlso Miter_Limit setStrokeMiter Join
2187
2188##
2189
2190#Method void setStrokeMiter(SkScalar miter)
2191
Cary Clarkab2621d2018-01-30 10:08:57 -05002192#In Miter_Limit
2193#Line # sets Miter_Limit, angles with sharp corners ##
Cary Clark80247e52018-07-11 16:18:41 -04002194 Sets the limit at which a sharp corner is drawn beveled.
Cary Clark8032b982017-07-28 11:04:54 -04002195 Valid values are zero and greater.
2196 Has no effect if miter is less than zero.
2197
2198 #Param miter zero and greater Miter_Limit
2199 ##
2200
2201 #Example
2202 SkPaint paint;
2203 paint.setStrokeMiter(8);
2204 paint.setStrokeMiter(-1);
2205 SkDebugf("default miter limit == %g\n", paint.getStrokeMiter());
2206
2207 #StdOut
2208 default miter limit == 8
2209 ##
2210 ##
2211
2212 #SeeAlso Miter_Limit getStrokeMiter Join
2213
2214##
2215
Cary Clark08895c42018-02-01 09:37:32 -05002216#Subtopic Miter_Limit ##
Cary Clark8032b982017-07-28 11:04:54 -04002217# ------------------------------------------------------------------------------
Cary Clark08895c42018-02-01 09:37:32 -05002218#Subtopic Stroke_Cap
2219#Line # decorations at ends of open strokes ##
Cary Clark8032b982017-07-28 11:04:54 -04002220
2221#Enum Cap
Cary Clark08895c42018-02-01 09:37:32 -05002222#Line # start and end geometry on stroked shapes ##
Cary Clark8032b982017-07-28 11:04:54 -04002223
2224#Code
2225 enum Cap {
2226 kButt_Cap,
2227 kRound_Cap,
2228 kSquare_Cap,
2229
2230 kLast_Cap = kSquare_Cap,
Cary Clarkbad5ad72017-08-03 17:14:08 -04002231 kDefault_Cap = kButt_Cap,
Cary Clark8032b982017-07-28 11:04:54 -04002232 };
Cary Clark6fc50412017-09-21 12:31:06 -04002233
Cary Clark8032b982017-07-28 11:04:54 -04002234 static constexpr int kCapCount = kLast_Cap + 1;
2235##
2236
2237Stroke_Cap draws at the beginning and end of an open Path_Contour.
2238
2239 #Const kButt_Cap 0
Cary Clark682c58d2018-05-16 07:07:07 -04002240 #Line # no stroke extension ##
Cary Clark8032b982017-07-28 11:04:54 -04002241 Does not extend the stroke past the beginning or the end.
2242 ##
2243 #Const kRound_Cap 1
Cary Clark682c58d2018-05-16 07:07:07 -04002244 #Line # adds circle ##
Cary Clark8032b982017-07-28 11:04:54 -04002245 Adds a circle with a diameter equal to Stroke_Width at the beginning
2246 and end.
2247 ##
2248 #Const kSquare_Cap 2
Cary Clark682c58d2018-05-16 07:07:07 -04002249 #Line # adds square ##
Cary Clark8032b982017-07-28 11:04:54 -04002250 Adds a square with sides equal to Stroke_Width at the beginning
2251 and end. The square sides are parallel to the initial and final direction
2252 of the stroke.
2253 ##
2254 #Const kLast_Cap 2
Cary Clark682c58d2018-05-16 07:07:07 -04002255 #Line # largest Stroke_Cap value ##
Cary Clark8032b982017-07-28 11:04:54 -04002256 Equivalent to the largest value for Stroke_Cap.
2257 ##
2258 #Const kDefault_Cap 0
Cary Clark682c58d2018-05-16 07:07:07 -04002259 #Line # equivalent to kButt_Cap ##
Cary Clark8032b982017-07-28 11:04:54 -04002260 Stroke_Cap is set to kButt_Cap by default.
2261 ##
2262
2263 #Const kCapCount 3
Cary Clark682c58d2018-05-16 07:07:07 -04002264 #Line # number of different Stroke_Cap values defined ##
Cary Clark8032b982017-07-28 11:04:54 -04002265 May be used to verify that Stroke_Cap is a legal value.
2266 ##
2267#Enum ##
2268
Herb Derbyfcac00f2018-05-01 11:57:56 -04002269Stroke describes the area covered by a pen of Stroke_Width as it
Cary Clarkbc5697d2017-10-04 14:31:33 -04002270follows the Path_Contour, moving parallel to the contour direction.
Cary Clark8032b982017-07-28 11:04:54 -04002271
2272If the Path_Contour is not terminated by SkPath::kClose_Verb, the contour has a
2273visible beginning and end.
2274
2275Path_Contour may start and end at the same point; defining Zero_Length_Contour.
2276
2277kButt_Cap and Zero_Length_Contour is not drawn.
Herb Derbyfcac00f2018-05-01 11:57:56 -04002278kRound_Cap and Zero_Length_Contour draws a circle of diameter Stroke_Width
Cary Clark8032b982017-07-28 11:04:54 -04002279at the contour point.
2280kSquare_Cap and Zero_Length_Contour draws an upright square with a side of
2281Stroke_Width at the contour point.
2282
2283Stroke_Cap is kButt_Cap by default.
2284
2285#Example
Cary Clark2ade9972017-11-02 17:49:34 -04002286#Height 200
Cary Clark8032b982017-07-28 11:04:54 -04002287 SkPaint paint;
2288 paint.setStyle(SkPaint::kStroke_Style);
2289 paint.setStrokeWidth(20);
2290 SkPath path;
2291 path.moveTo(30, 30);
2292 path.lineTo(30, 30);
2293 path.moveTo(70, 30);
2294 path.lineTo(90, 40);
2295 for (SkPaint::Cap c : { SkPaint::kButt_Cap, SkPaint::kRound_Cap, SkPaint::kSquare_Cap } ) {
2296 paint.setStrokeCap(c);
2297 canvas->drawPath(path, paint);
2298 canvas->translate(0, 70);
2299 }
2300##
2301
2302#Method Cap getStrokeCap() const
2303
Cary Clarkab2621d2018-01-30 10:08:57 -05002304#In Stroke_Cap
2305#Line # returns Cap, the area drawn at path ends ##
Cary Clark80247e52018-07-11 16:18:41 -04002306 Returns the geometry drawn at the beginning and end of strokes.
Cary Clark8032b982017-07-28 11:04:54 -04002307
2308 #Return one of: kButt_Cap, kRound_Cap, kSquare_Cap ##
2309
2310 #Example
2311 SkPaint paint;
2312 SkDebugf("kButt_Cap %c= default stroke cap\n",
2313 SkPaint::kButt_Cap == paint.getStrokeCap() ? '=' : '!');
2314
2315 #StdOut
2316 kButt_Cap == default stroke cap
2317 ##
2318 ##
2319
2320 #SeeAlso Stroke_Cap setStrokeCap
2321##
2322
2323#Method void setStrokeCap(Cap cap)
2324
Cary Clarkab2621d2018-01-30 10:08:57 -05002325#In Stroke_Cap
2326#Line # sets Cap, the area drawn at path ends ##
Cary Clark80247e52018-07-11 16:18:41 -04002327 Sets the geometry drawn at the beginning and end of strokes.
Cary Clark8032b982017-07-28 11:04:54 -04002328
2329 #Param cap one of: kButt_Cap, kRound_Cap, kSquare_Cap;
2330 has no effect if cap is not valid
Herb Derbyfcac00f2018-05-01 11:57:56 -04002331 ##
Cary Clark8032b982017-07-28 11:04:54 -04002332
2333 #Example
2334 SkPaint paint;
2335 paint.setStrokeCap(SkPaint::kRound_Cap);
2336 paint.setStrokeCap((SkPaint::Cap) SkPaint::kCapCount);
2337 SkDebugf("kRound_Cap %c= paint.getStrokeCap()\n",
2338 SkPaint::kRound_Cap == paint.getStrokeCap() ? '=' : '!');
Herb Derbyfcac00f2018-05-01 11:57:56 -04002339
Cary Clark8032b982017-07-28 11:04:54 -04002340 #StdOut
2341 kRound_Cap == paint.getStrokeCap()
2342 ##
2343 ##
2344
2345 #SeeAlso Stroke_Cap getStrokeCap
2346##
2347
Cary Clark08895c42018-02-01 09:37:32 -05002348#Subtopic Stroke_Cap ##
Cary Clark8032b982017-07-28 11:04:54 -04002349# ------------------------------------------------------------------------------
Cary Clark08895c42018-02-01 09:37:32 -05002350#Subtopic Stroke_Join
2351#Line # decoration at corners of strokes ##
Cary Clark8032b982017-07-28 11:04:54 -04002352
2353Stroke_Join draws at the sharp corners of an open or closed Path_Contour.
2354
Herb Derbyfcac00f2018-05-01 11:57:56 -04002355Stroke describes the area covered by a pen of Stroke_Width as it
Cary Clarkbc5697d2017-10-04 14:31:33 -04002356follows the Path_Contour, moving parallel to the contour direction.
Cary Clark8032b982017-07-28 11:04:54 -04002357
2358If the contour direction changes abruptly, because the tangent direction leading
2359to the end of a curve within the contour does not match the tangent direction of
2360the following curve, the pair of curves meet at Stroke_Join.
2361
2362#Example
Cary Clark2ade9972017-11-02 17:49:34 -04002363#Height 200
Cary Clarka560c472017-11-27 10:44:06 -05002364 SkPaint paint;
2365 paint.setStyle(SkPaint::kStroke_Style);
2366 paint.setStrokeWidth(20);
2367 SkPath path;
2368 path.moveTo(30, 20);
2369 path.lineTo(40, 40);
2370 path.conicTo(70, 20, 100, 20, .707f);
2371 for (SkPaint::Join j : { SkPaint::kMiter_Join, SkPaint::kRound_Join, SkPaint::kBevel_Join } ) {
2372 paint.setStrokeJoin(j);
2373 canvas->drawPath(path, paint);
2374 canvas->translate(0, 70);
2375 }
Cary Clark8032b982017-07-28 11:04:54 -04002376##
2377
2378#Enum Join
Cary Clark08895c42018-02-01 09:37:32 -05002379#Line # corner geometry on stroked shapes ##
Cary Clark8032b982017-07-28 11:04:54 -04002380#Code
2381 enum Join {
2382 kMiter_Join,
2383 kRound_Join,
2384 kBevel_Join,
2385
2386 kLast_Join = kBevel_Join,
Cary Clarkbad5ad72017-08-03 17:14:08 -04002387 kDefault_Join = kMiter_Join,
Cary Clark8032b982017-07-28 11:04:54 -04002388 };
Cary Clark6fc50412017-09-21 12:31:06 -04002389
Cary Clark8032b982017-07-28 11:04:54 -04002390 static constexpr int kJoinCount = kLast_Join + 1;
2391##
2392
Cary Clark1eace2d2017-07-31 07:52:43 -04002393Join specifies how corners are drawn when a shape is stroked. Join
Cary Clark8032b982017-07-28 11:04:54 -04002394affects the four corners of a stroked rectangle, and the connected segments in a
2395stroked path.
2396
2397Choose miter join to draw sharp corners. Choose round join to draw a circle with a
2398radius equal to the stroke width on top of the corner. Choose bevel join to minimally
2399connect the thick strokes.
2400
Herb Derbyfcac00f2018-05-01 11:57:56 -04002401The fill path constructed to describe the stroked path respects the join setting but may
Cary Clark8032b982017-07-28 11:04:54 -04002402not contain the actual join. For instance, a fill path constructed with round joins does
2403not necessarily include circles at each connected segment.
2404
2405#Const kMiter_Join 0
Cary Clark682c58d2018-05-16 07:07:07 -04002406#Line # extends to Miter_Limit ##
Cary Clark8032b982017-07-28 11:04:54 -04002407 Extends the outside corner to the extent allowed by Miter_Limit.
2408 If the extension exceeds Miter_Limit, kBevel_Join is used instead.
2409##
2410
2411#Const kRound_Join 1
Cary Clark682c58d2018-05-16 07:07:07 -04002412#Line # adds circle ##
Cary Clark8032b982017-07-28 11:04:54 -04002413 Adds a circle with a diameter of Stroke_Width at the sharp corner.
2414##
2415
2416#Const kBevel_Join 2
Cary Clark682c58d2018-05-16 07:07:07 -04002417#Line # connects outside edges ##
Cary Clark8032b982017-07-28 11:04:54 -04002418 Connects the outside edges of the sharp corner.
2419##
2420
2421#Const kLast_Join 2
Cary Clark682c58d2018-05-16 07:07:07 -04002422#Line # equivalent to the largest value for Stroke_Join ##
Cary Clark8032b982017-07-28 11:04:54 -04002423##
2424
2425#Const kDefault_Join 1
Cary Clark682c58d2018-05-16 07:07:07 -04002426#Line # equivalent to kMiter_Join ##
Herb Derbyfcac00f2018-05-01 11:57:56 -04002427 Stroke_Join is set to kMiter_Join by default.
Cary Clark8032b982017-07-28 11:04:54 -04002428##
2429
2430#Const kJoinCount 3
Cary Clark682c58d2018-05-16 07:07:07 -04002431#Line # number of different Stroke_Join values defined ##
Cary Clark8032b982017-07-28 11:04:54 -04002432 May be used to verify that Stroke_Join is a legal value.
2433##
2434
2435#Example
2436#Width 462
2437void draw(SkCanvas* canvas) {
2438 SkPath path;
2439 path.moveTo(10, 50);
2440 path.quadTo(35, 110, 60, 210);
2441 path.quadTo(105, 110, 130, 10);
2442 SkPaint paint; // set to default kMiter_Join
2443 paint.setAntiAlias(true);
2444 paint.setStyle(SkPaint::kStroke_Style);
2445 paint.setStrokeWidth(20);
2446 canvas->drawPath(path, paint);
2447 canvas->translate(150, 0);
2448 paint.setStrokeJoin(SkPaint::kBevel_Join);
2449 canvas->drawPath(path, paint);
2450 canvas->translate(150, 0);
2451 paint.setStrokeJoin(SkPaint::kRound_Join);
2452 canvas->drawPath(path, paint);
2453}
2454##
2455
2456#SeeAlso setStrokeJoin getStrokeJoin setStrokeMiter getStrokeMiter
2457
2458#Enum ##
2459
2460#Method Join getStrokeJoin() const
2461
Cary Clarkab2621d2018-01-30 10:08:57 -05002462#In Stroke_Join
2463#Line # returns Join, geometry on path corners ##
Cary Clark80247e52018-07-11 16:18:41 -04002464 Returns the geometry drawn at the corners of strokes.
Cary Clark8032b982017-07-28 11:04:54 -04002465
2466 #Return one of: kMiter_Join, kRound_Join, kBevel_Join ##
2467
2468 #Example
2469 SkPaint paint;
2470 SkDebugf("kMiter_Join %c= default stroke join\n",
2471 SkPaint::kMiter_Join == paint.getStrokeJoin() ? '=' : '!');
2472
2473 #StdOut
2474 kMiter_Join == default stroke join
2475 ##
2476 ##
2477
2478 #SeeAlso Stroke_Join setStrokeJoin
2479##
2480
2481#Method void setStrokeJoin(Join join)
2482
Cary Clarkab2621d2018-01-30 10:08:57 -05002483#In Stroke_Join
2484#Line # sets Join, geometry on path corners ##
Cary Clark80247e52018-07-11 16:18:41 -04002485 Sets the geometry drawn at the corners of strokes.
Cary Clark8032b982017-07-28 11:04:54 -04002486
2487 #Param join one of: kMiter_Join, kRound_Join, kBevel_Join;
Herb Derbyfcac00f2018-05-01 11:57:56 -04002488 otherwise, has no effect
Cary Clark8032b982017-07-28 11:04:54 -04002489 ##
2490
2491 #Example
2492 SkPaint paint;
2493 paint.setStrokeJoin(SkPaint::kMiter_Join);
2494 paint.setStrokeJoin((SkPaint::Join) SkPaint::kJoinCount);
2495 SkDebugf("kMiter_Join %c= paint.getStrokeJoin()\n",
2496 SkPaint::kMiter_Join == paint.getStrokeJoin() ? '=' : '!');
2497
2498 #StdOut
2499 kMiter_Join == paint.getStrokeJoin()
2500 ##
2501 ##
2502
2503 #SeeAlso Stroke_Join getStrokeJoin
2504##
2505
2506#SeeAlso Miter_Limit
2507
Cary Clark08895c42018-02-01 09:37:32 -05002508#Subtopic Stroke_Join ##
Cary Clark8032b982017-07-28 11:04:54 -04002509# ------------------------------------------------------------------------------
Cary Clark08895c42018-02-01 09:37:32 -05002510#Subtopic Fill_Path
2511#Line # make Path from Path_Effect, stroking ##
Cary Clark8032b982017-07-28 11:04:54 -04002512
2513Fill_Path creates a Path by applying the Path_Effect, followed by the Style_Stroke.
2514
2515If Paint contains Path_Effect, Path_Effect operates on the source Path; the result
2516replaces the destination Path. Otherwise, the source Path is replaces the
2517destination Path.
2518
2519Fill Path can request the Path_Effect to restrict to a culling rectangle, but
2520the Path_Effect is not required to do so.
2521
Herb Derbyfcac00f2018-05-01 11:57:56 -04002522If Style is kStroke_Style or kStrokeAndFill_Style,
Cary Clark8032b982017-07-28 11:04:54 -04002523and Stroke_Width is greater than zero, the Stroke_Width, Stroke_Cap, Stroke_Join,
2524and Miter_Limit operate on the destination Path, replacing it.
2525
Herb Derbyfcac00f2018-05-01 11:57:56 -04002526Fill Path can specify the precision used by Stroke_Width to approximate the stroke geometry.
Cary Clark8032b982017-07-28 11:04:54 -04002527
2528If the Style is kStroke_Style and the Stroke_Width is zero, getFillPath
2529returns false since Hairline has no filled equivalent.
2530
2531#Method bool getFillPath(const SkPath& src, SkPath* dst, const SkRect* cullRect,
2532 SkScalar resScale = 1) const
Cary Clarkab2621d2018-01-30 10:08:57 -05002533#In Fill_Path
2534#Line # returns fill path equivalent to stroke ##
Cary Clark8032b982017-07-28 11:04:54 -04002535
Cary Clark80247e52018-07-11 16:18:41 -04002536 Returns the filled equivalent of the stroked path.
Cary Clark8032b982017-07-28 11:04:54 -04002537
2538 #Param src Path read to create a filled version ##
2539 #Param dst resulting Path; may be the same as src, but may not be nullptr ##
2540 #Param cullRect optional limit passed to Path_Effect ##
2541 #Param resScale if > 1, increase precision, else if (0 < res < 1) reduce precision
2542 to favor speed and size
2543 ##
2544 #Return true if the path represents Style_Fill, or false if it represents Hairline ##
2545
2546 #Example
2547 #Height 192
2548 #Description
Cary Clarkce101242017-09-01 15:51:02 -04002549 A very small Quad stroke is turned into a filled path with increasing levels of precision.
Herb Derbyfcac00f2018-05-01 11:57:56 -04002550 At the lowest precision, the Quad stroke is approximated by a rectangle.
Cary Clark8032b982017-07-28 11:04:54 -04002551 At the highest precision, the filled path has high fidelity compared to the original stroke.
2552 ##
2553 void draw(SkCanvas* canvas) {
2554 SkPaint strokePaint;
2555 strokePaint.setAntiAlias(true);
2556 strokePaint.setStyle(SkPaint::kStroke_Style);
2557 strokePaint.setStrokeWidth(.1f);
2558 SkPath strokePath;
2559 strokePath.moveTo(.08f, .08f);
2560 strokePath.quadTo(.09f, .08f, .17f, .17f);
2561 SkPath fillPath;
2562 SkPaint outlinePaint(strokePaint);
2563 outlinePaint.setStrokeWidth(2);
2564 SkMatrix scale = SkMatrix::MakeScale(300, 300);
2565 for (SkScalar precision : { 0.01f, .1f, 1.f, 10.f, 100.f } ) {
2566 strokePaint.getFillPath(strokePath, &fillPath, nullptr, precision);
2567 fillPath.transform(scale);
2568 canvas->drawPath(fillPath, outlinePaint);
2569 canvas->translate(60, 0);
2570 if (1.f == precision) canvas->translate(-180, 100);
2571 }
2572 strokePath.transform(scale);
2573 strokePaint.setStrokeWidth(30);
2574 canvas->drawPath(strokePath, strokePaint);
2575 }
2576 ##
2577
2578##
2579
2580#Method bool getFillPath(const SkPath& src, SkPath* dst) const
2581
Cary Clarkab2621d2018-01-30 10:08:57 -05002582#In Fill_Path
Cary Clark80247e52018-07-11 16:18:41 -04002583 Returns the filled equivalent of the stroked path.
Cary Clark8032b982017-07-28 11:04:54 -04002584
2585 Replaces dst with the src path modified by Path_Effect and Style_Stroke.
2586 Path_Effect, if any, is not culled. Stroke_Width is created with default precision.
2587
2588 #Param src Path read to create a filled version ##
2589 #Param dst resulting Path dst may be the same as src, but may not be nullptr ##
2590 #Return true if the path represents Style_Fill, or false if it represents Hairline ##
2591
2592 #Example
2593 #Height 128
2594 void draw(SkCanvas* canvas) {
2595 SkPaint paint;
2596 paint.setStyle(SkPaint::kStroke_Style);
2597 paint.setStrokeWidth(10);
2598 SkPath strokePath;
2599 strokePath.moveTo(20, 20);
2600 strokePath.lineTo(100, 100);
2601 canvas->drawPath(strokePath, paint);
2602 SkPath fillPath;
2603 paint.getFillPath(strokePath, &fillPath);
2604 paint.setStrokeWidth(2);
2605 canvas->translate(40, 0);
2606 canvas->drawPath(fillPath, paint);
2607 }
2608 ##
2609
2610##
2611
2612#SeeAlso Style_Stroke Stroke_Width Path_Effect
2613
Cary Clark08895c42018-02-01 09:37:32 -05002614#Subtopic Fill_Path ##
Cary Clark8032b982017-07-28 11:04:54 -04002615# ------------------------------------------------------------------------------
Cary Clark08895c42018-02-01 09:37:32 -05002616#Subtopic Shader_Methods
2617#Line # get and set Shader ##
Cary Clark8032b982017-07-28 11:04:54 -04002618
2619Shader defines the colors used when drawing a shape.
2620Shader may be an image, a gradient, or a computed fill.
Herb Derbyfcac00f2018-05-01 11:57:56 -04002621If Paint has no Shader, then Color fills the shape.
Cary Clark8032b982017-07-28 11:04:54 -04002622
2623Shader is modulated by Color_Alpha component of Color.
2624If Shader object defines only Color_Alpha, then Color modulated by Color_Alpha describes
2625the fill.
2626
2627The drawn transparency can be modified without altering Shader, by changing Color_Alpha.
2628
2629#Example
2630void draw(SkCanvas* canvas) {
2631 SkPaint paint;
2632 SkPoint center = { 50, 50 };
2633 SkScalar radius = 50;
2634 const SkColor colors[] = { 0xFFFFFFFF, 0xFF000000 };
2635 paint.setShader(SkGradientShader::MakeRadial(center, radius, colors,
2636 nullptr, SK_ARRAY_COUNT(colors), SkShader::kClamp_TileMode));
2637 for (SkScalar a : { 0.3f, 0.6f, 1.0f } ) {
2638 paint.setAlpha((int) (a * 255));
2639 canvas->drawCircle(center.fX, center.fY, radius, paint);
2640 canvas->translate(70, 70);
2641 }
2642}
2643##
2644
2645If Shader generates only Color_Alpha then all components of Color modulate the output.
2646
2647#Example
2648void draw(SkCanvas* canvas) {
2649 SkPaint paint;
2650 SkBitmap bitmap;
2651 bitmap.setInfo(SkImageInfo::MakeA8(5, 1), 5); // bitmap only contains alpha
2652 uint8_t pixels[5] = { 0x22, 0x55, 0x88, 0xBB, 0xFF };
2653 bitmap.setPixels(pixels);
Herb Derbyfcac00f2018-05-01 11:57:56 -04002654 paint.setShader(SkShader::MakeBitmapShader(bitmap,
Cary Clark8032b982017-07-28 11:04:54 -04002655 SkShader::kMirror_TileMode, SkShader::kMirror_TileMode));
2656 for (SkColor c : { SK_ColorRED, SK_ColorBLUE, SK_ColorGREEN } ) {
2657 paint.setColor(c); // all components in color affect shader
2658 canvas->drawCircle(50, 50, 50, paint);
2659 canvas->translate(70, 70);
2660 }
2661}
2662##
2663
2664#Method SkShader* getShader() const
2665
Cary Clarkab2621d2018-01-30 10:08:57 -05002666#In Shader_Methods
2667#Line # returns Shader, multiple drawing colors; gradients ##
Cary Clark80247e52018-07-11 16:18:41 -04002668 Returns optional colors used when filling a path, such as a gradient.
Cary Clark8032b982017-07-28 11:04:54 -04002669
2670 Does not alter Shader Reference_Count.
Herb Derbyfcac00f2018-05-01 11:57:56 -04002671
Cary Clark8032b982017-07-28 11:04:54 -04002672 #Return Shader if previously set, nullptr otherwise ##
2673
2674 #Example
2675 void draw(SkCanvas* canvas) {
2676 SkPaint paint;
2677 SkDebugf("nullptr %c= shader\n", paint.getShader() ? '!' : '=');
2678 paint.setShader(SkShader::MakeEmptyShader());
2679 SkDebugf("nullptr %c= shader\n", paint.getShader() ? '!' : '=');
2680 }
2681
2682 #StdOut
2683 nullptr == shader
2684 nullptr != shader
2685 ##
2686 ##
2687
2688##
2689
2690#Method sk_sp<SkShader> refShader() const
2691
Cary Clarkab2621d2018-01-30 10:08:57 -05002692#In Shader_Methods
2693#Line # references Shader, multiple drawing colors; gradients ##
Cary Clark80247e52018-07-11 16:18:41 -04002694 Returns optional colors used when filling a path, such as a gradient.
Cary Clark8032b982017-07-28 11:04:54 -04002695
2696 Increases Shader Reference_Count by one.
2697
2698 #Return Shader if previously set, nullptr otherwise ##
2699
2700 #Example
2701 void draw(SkCanvas* canvas) {
2702 SkPaint paint1, paint2;
2703 paint1.setShader(SkShader::MakeEmptyShader());
2704 SkDebugf("shader unique: %s\n", paint1.getShader()->unique() ? "true" : "false");
2705 paint2.setShader(paint1.refShader());
2706 SkDebugf("shader unique: %s\n", paint1.getShader()->unique() ? "true" : "false");
2707 }
2708
2709 #StdOut
2710 shader unique: true
2711 shader unique: false
2712 ##
2713 ##
2714
2715##
2716
2717#Method void setShader(sk_sp<SkShader> shader)
2718
Cary Clarkab2621d2018-01-30 10:08:57 -05002719#In Shader_Methods
2720#Line # sets Shader, multiple drawing colors; gradients ##
Cary Clark80247e52018-07-11 16:18:41 -04002721 Sets optional colors used when filling a path, such as a gradient.
Cary Clark8032b982017-07-28 11:04:54 -04002722
Cary Clarkd0530ba2017-09-14 11:25:39 -04002723 Sets Shader to shader, decreasing Reference_Count of the previous Shader.
Cary Clark6fc50412017-09-21 12:31:06 -04002724 Increments shader Reference_Count by one.
Cary Clark8032b982017-07-28 11:04:54 -04002725
2726 #Param shader how geometry is filled with color; if nullptr, Color is used instead ##
2727
2728 #Example
2729 #Height 64
2730 void draw(SkCanvas* canvas) {
2731 SkPaint paint;
2732 paint.setColor(SK_ColorBLUE);
2733 paint.setShader(SkShader::MakeColorShader(SK_ColorRED));
2734 canvas->drawRect(SkRect::MakeWH(40, 40), paint);
2735 paint.setShader(nullptr);
2736 canvas->translate(50, 0);
2737 canvas->drawRect(SkRect::MakeWH(40, 40), paint);
2738 }
2739 ##
2740
2741##
2742
Cary Clark08895c42018-02-01 09:37:32 -05002743#Subtopic Shader_Methods ##
Cary Clark8032b982017-07-28 11:04:54 -04002744# ------------------------------------------------------------------------------
Cary Clark08895c42018-02-01 09:37:32 -05002745#Subtopic Color_Filter_Methods
2746#Line # get and set Color_Filter ##
Cary Clark8032b982017-07-28 11:04:54 -04002747
2748Color_Filter alters the color used when drawing a shape.
2749Color_Filter may apply Blend_Mode, transform the color through a matrix, or composite multiple filters.
2750If Paint has no Color_Filter, the color is unaltered.
2751
2752The drawn transparency can be modified without altering Color_Filter, by changing Color_Alpha.
2753
2754#Example
2755#Height 128
2756void draw(SkCanvas* canvas) {
2757 SkPaint paint;
2758 paint.setColorFilter(SkColorMatrixFilter::MakeLightingFilter(0xFFFFFF, 0xFF0000));
2759 for (SkColor c : { SK_ColorBLACK, SK_ColorGREEN } ) {
2760 paint.setColor(c);
2761 canvas->drawRect(SkRect::MakeXYWH(10, 10, 50, 50), paint);
2762 paint.setAlpha(0x80);
2763 canvas->drawRect(SkRect::MakeXYWH(60, 60, 50, 50), paint);
2764 canvas->translate(100, 0);
2765 }
2766}
2767##
2768
2769#Method SkColorFilter* getColorFilter() const
2770
Cary Clarkab2621d2018-01-30 10:08:57 -05002771#In Color_Filter_Methods
2772#Line # returns Color_Filter, how colors are altered ##
Cary Clark8032b982017-07-28 11:04:54 -04002773 Returns Color_Filter if set, or nullptr.
2774 Does not alter Color_Filter Reference_Count.
Herb Derbyfcac00f2018-05-01 11:57:56 -04002775
Cary Clark8032b982017-07-28 11:04:54 -04002776 #Return Color_Filter if previously set, nullptr otherwise ##
2777
2778 #Example
2779 void draw(SkCanvas* canvas) {
2780 SkPaint paint;
2781 SkDebugf("nullptr %c= color filter\n", paint.getColorFilter() ? '!' : '=');
2782 paint.setColorFilter(SkColorFilter::MakeModeFilter(SK_ColorLTGRAY, SkBlendMode::kSrcIn));
2783 SkDebugf("nullptr %c= color filter\n", paint.getColorFilter() ? '!' : '=');
2784 }
2785
2786 #StdOut
2787 nullptr == color filter
2788 nullptr != color filter
2789 ##
2790 ##
2791##
2792
2793#Method sk_sp<SkColorFilter> refColorFilter() const
2794
Cary Clarkab2621d2018-01-30 10:08:57 -05002795#In Color_Filter_Methods
2796#Line # references Color_Filter, how colors are altered ##
Cary Clark8032b982017-07-28 11:04:54 -04002797 Returns Color_Filter if set, or nullptr.
2798 Increases Color_Filter Reference_Count by one.
2799
2800 #Return Color_Filter if set, or nullptr ##
2801
2802 #Example
2803 void draw(SkCanvas* canvas) {
2804 SkPaint paint1, paint2;
2805 paint1.setColorFilter(SkColorFilter::MakeModeFilter(0xFFFF0000, SkBlendMode::kSrcATop));
2806 SkDebugf("color filter unique: %s\n", paint1.getColorFilter()->unique() ? "true" : "false");
2807 paint2.setColorFilter(paint1.refColorFilter());
2808 SkDebugf("color filter unique: %s\n", paint1.getColorFilter()->unique() ? "true" : "false");
2809 }
2810
2811 #StdOut
2812 color filter unique: true
2813 color filter unique: false
2814 ##
2815 ##
2816##
2817
2818#Method void setColorFilter(sk_sp<SkColorFilter> colorFilter)
2819
Cary Clarkab2621d2018-01-30 10:08:57 -05002820#In Color_Filter_Methods
2821#Line # sets Color_Filter, alters color ##
Cary Clark6fc50412017-09-21 12:31:06 -04002822Sets Color_Filter to filter, decreasing Reference_Count of the previous
2823Color_Filter. Pass nullptr to clear Color_Filter.
2824
2825Increments filter Reference_Count by one.
Cary Clark8032b982017-07-28 11:04:54 -04002826
2827 #Param colorFilter Color_Filter to apply to subsequent draw ##
2828
2829 #Example
2830 #Height 64
2831 void draw(SkCanvas* canvas) {
2832 SkPaint paint;
2833 paint.setColorFilter(SkColorFilter::MakeModeFilter(SK_ColorLTGRAY, SkBlendMode::kSrcIn));
2834 canvas->drawRect(SkRect::MakeWH(50, 50), paint);
2835 paint.setColorFilter(nullptr);
2836 canvas->translate(70, 0);
2837 canvas->drawRect(SkRect::MakeWH(50, 50), paint);
2838 }
2839 ##
2840
2841##
2842
Cary Clark08895c42018-02-01 09:37:32 -05002843#Subtopic Color_Filter_Methods ##
Cary Clark8032b982017-07-28 11:04:54 -04002844# ------------------------------------------------------------------------------
Cary Clark08895c42018-02-01 09:37:32 -05002845#Subtopic Blend_Mode_Methods
2846#Line # get and set Blend_Mode ##
Cary Clark8032b982017-07-28 11:04:54 -04002847
2848Blend_Mode describes how Color combines with the destination color.
2849The default setting, SkBlendMode::kSrcOver, draws the source color
2850over the destination color.
2851
2852#Example
2853void draw(SkCanvas* canvas) {
2854 SkPaint normal, blender;
2855 normal.setColor(0xFF58a889);
2856 blender.setColor(0xFF8958a8);
2857 canvas->clear(0);
2858 for (SkBlendMode m : { SkBlendMode::kSrcOver, SkBlendMode::kSrcIn, SkBlendMode::kSrcOut } ) {
2859 normal.setBlendMode(SkBlendMode::kSrcOver);
2860 canvas->drawOval(SkRect::MakeXYWH(30, 30, 30, 80), normal);
2861 blender.setBlendMode(m);
2862 canvas->drawOval(SkRect::MakeXYWH(10, 50, 80, 30), blender);
2863 canvas->translate(70, 70);
2864 }
2865}
2866##
2867
2868#SeeAlso Blend_Mode
2869
2870#Method SkBlendMode getBlendMode() const
2871
Cary Clarkab2621d2018-01-30 10:08:57 -05002872#In Blend_Mode_Methods
2873#Line # returns Blend_Mode, how colors combine with Device ##
Cary Clark8032b982017-07-28 11:04:54 -04002874 Returns Blend_Mode.
Cary Clark579985c2017-07-31 11:48:27 -04002875 By default, returns SkBlendMode::kSrcOver.
Cary Clark8032b982017-07-28 11:04:54 -04002876
2877 #Return mode used to combine source color with destination color ##
2878
2879 #Example
2880 void draw(SkCanvas* canvas) {
2881 SkPaint paint;
Herb Derbyfcac00f2018-05-01 11:57:56 -04002882 SkDebugf("kSrcOver %c= getBlendMode\n",
Cary Clark8032b982017-07-28 11:04:54 -04002883 SkBlendMode::kSrcOver == paint.getBlendMode() ? '=' : '!');
2884 paint.setBlendMode(SkBlendMode::kSrc);
Herb Derbyfcac00f2018-05-01 11:57:56 -04002885 SkDebugf("kSrcOver %c= getBlendMode\n",
Cary Clark8032b982017-07-28 11:04:54 -04002886 SkBlendMode::kSrcOver == paint.getBlendMode() ? '=' : '!');
2887 }
2888
2889 #StdOut
2890 kSrcOver == getBlendMode
2891 kSrcOver != getBlendMode
2892 ##
2893 ##
2894
2895##
2896
2897#Method bool isSrcOver() const
2898
Cary Clarkab2621d2018-01-30 10:08:57 -05002899#In Blend_Mode_Methods
2900#Line # returns true if Blend_Mode is SkBlendMode::kSrcOver ##
Cary Clark8032b982017-07-28 11:04:54 -04002901 Returns true if Blend_Mode is SkBlendMode::kSrcOver, the default.
2902
2903 #Return true if Blend_Mode is SkBlendMode::kSrcOver ##
2904
2905 #Example
2906 void draw(SkCanvas* canvas) {
2907 SkPaint paint;
2908 SkDebugf("isSrcOver %c= true\n", paint.isSrcOver() ? '=' : '!');
2909 paint.setBlendMode(SkBlendMode::kSrc);
2910 SkDebugf("isSrcOver %c= true\n", paint.isSrcOver() ? '=' : '!');
2911 }
2912
2913 #StdOut
2914 isSrcOver == true
2915 isSrcOver != true
2916 ##
2917 ##
2918
2919##
2920
2921#Method void setBlendMode(SkBlendMode mode)
2922
Cary Clarkab2621d2018-01-30 10:08:57 -05002923#In Blend_Mode_Methods
2924#Line # sets Blend_Mode, how colors combine with destination ##
Herb Derbyfcac00f2018-05-01 11:57:56 -04002925 Sets Blend_Mode to mode.
Cary Clark8032b982017-07-28 11:04:54 -04002926 Does not check for valid input.
2927
2928 #Param mode SkBlendMode used to combine source color and destination ##
2929
2930 #Example
2931 void draw(SkCanvas* canvas) {
2932 SkPaint paint;
2933 SkDebugf("isSrcOver %c= true\n", paint.isSrcOver() ? '=' : '!');
2934 paint.setBlendMode(SkBlendMode::kSrc);
2935 SkDebugf("isSrcOver %c= true\n", paint.isSrcOver() ? '=' : '!');
2936 }
2937
2938 #StdOut
2939 isSrcOver == true
2940 isSrcOver != true
2941 ##
2942 ##
2943
2944##
2945
Cary Clark08895c42018-02-01 09:37:32 -05002946#Subtopic Blend_Mode_Methods ##
Cary Clark8032b982017-07-28 11:04:54 -04002947# ------------------------------------------------------------------------------
Cary Clark08895c42018-02-01 09:37:32 -05002948#Subtopic Path_Effect_Methods
2949#Line # get and set Path_Effect ##
Cary Clark8032b982017-07-28 11:04:54 -04002950
2951Path_Effect modifies the path geometry before drawing it.
2952Path_Effect may implement dashing, custom fill effects and custom stroke effects.
2953If Paint has no Path_Effect, the path geometry is unaltered when filled or stroked.
2954
2955#Example
2956#Height 160
2957 void draw(SkCanvas* canvas) {
2958 SkPaint paint;
2959 paint.setStyle(SkPaint::kStroke_Style);
2960 paint.setStrokeWidth(16);
2961 SkScalar intervals[] = {30, 10};
2962 paint.setPathEffect(SkDashPathEffect::Make(intervals, SK_ARRAY_COUNT(intervals), 1));
2963 canvas->drawRoundRect({20, 20, 120, 120}, 20, 20, paint);
2964 }
2965##
2966
2967#SeeAlso Path_Effect
2968
2969#Method SkPathEffect* getPathEffect() const
2970
Cary Clarkab2621d2018-01-30 10:08:57 -05002971#In Path_Effect_Methods
2972#Line # returns Path_Effect, modifications to path geometry; dashing ##
Cary Clark8032b982017-07-28 11:04:54 -04002973 Returns Path_Effect if set, or nullptr.
2974 Does not alter Path_Effect Reference_Count.
Herb Derbyfcac00f2018-05-01 11:57:56 -04002975
Cary Clark8032b982017-07-28 11:04:54 -04002976 #Return Path_Effect if previously set, nullptr otherwise ##
2977
2978 #Example
2979 void draw(SkCanvas* canvas) {
2980 SkPaint paint;
2981 SkDebugf("nullptr %c= path effect\n", paint.getPathEffect() ? '!' : '=');
2982 paint.setPathEffect(SkCornerPathEffect::Make(10));
2983 SkDebugf("nullptr %c= path effect\n", paint.getPathEffect() ? '!' : '=');
2984 }
2985
2986 #StdOut
2987 nullptr == path effect
2988 nullptr != path effect
2989 ##
2990 ##
2991
2992##
2993
2994
2995#Method sk_sp<SkPathEffect> refPathEffect() const
2996
Cary Clarkab2621d2018-01-30 10:08:57 -05002997#In Path_Effect_Methods
2998#Line # references Path_Effect, modifications to path geometry; dashing ##
Cary Clark8032b982017-07-28 11:04:54 -04002999 Returns Path_Effect if set, or nullptr.
3000 Increases Path_Effect Reference_Count by one.
3001
3002 #Return Path_Effect if previously set, nullptr otherwise ##
3003
3004 #Example
3005 void draw(SkCanvas* canvas) {
3006 SkPaint paint1, paint2;
Cary Clarka560c472017-11-27 10:44:06 -05003007 SkScalar intervals[] = {1, 2};
3008 paint1.setPathEffect(SkDashPathEffect::Make(intervals, SK_ARRAY_COUNT(intervals), 10));
Cary Clark8032b982017-07-28 11:04:54 -04003009 SkDebugf("path effect unique: %s\n", paint1.getPathEffect()->unique() ? "true" : "false");
3010 paint2.setPathEffect(paint1.refPathEffect());
3011 SkDebugf("path effect unique: %s\n", paint1.getPathEffect()->unique() ? "true" : "false");
3012 }
3013
3014 #StdOut
3015 path effect unique: true
3016 path effect unique: false
3017 ##
3018 ##
3019
3020##
3021
3022
3023#Method void setPathEffect(sk_sp<SkPathEffect> pathEffect)
3024
Cary Clarkab2621d2018-01-30 10:08:57 -05003025#In Path_Effect_Methods
3026#Line # sets Path_Effect, modifications to path geometry; dashing ##
Cary Clark6fc50412017-09-21 12:31:06 -04003027Sets Path_Effect to pathEffect, decreasing Reference_Count of the previous
3028Path_Effect. Pass nullptr to leave the path geometry unaltered.
3029
3030Increments pathEffect Reference_Count by one.
Cary Clark8032b982017-07-28 11:04:54 -04003031
3032 #Param pathEffect replace Path with a modification when drawn ##
3033
3034 #Example
3035 void draw(SkCanvas* canvas) {
3036 SkPaint paint;
3037 paint.setPathEffect(SkDiscretePathEffect::Make(3, 5));
3038 canvas->drawRect(SkRect::MakeXYWH(40, 40, 175, 175), paint);
3039 }
3040 ##
3041
3042##
3043
Cary Clark08895c42018-02-01 09:37:32 -05003044#Subtopic Path_Effect_Methods ##
Cary Clark8032b982017-07-28 11:04:54 -04003045# ------------------------------------------------------------------------------
Cary Clark08895c42018-02-01 09:37:32 -05003046#Subtopic Mask_Filter_Methods
3047#Line # get and set Mask_Filter ##
Cary Clark8032b982017-07-28 11:04:54 -04003048
Cary Clarkce101242017-09-01 15:51:02 -04003049Mask_Filter uses coverage of the shape drawn to create Mask_Alpha.
Mike Reed8ad91a92018-01-19 19:09:32 -05003050Mask_Filter takes a Mask, and returns a Mask.
Cary Clark6fc50412017-09-21 12:31:06 -04003051
3052Mask_Filter may change the geometry and transparency of the shape, such as
3053creating a blur effect. Set Mask_Filter to nullptr to prevent Mask_Filter from
3054modifying the draw.
Cary Clark8032b982017-07-28 11:04:54 -04003055
3056#Example
3057 void draw(SkCanvas* canvas) {
3058 SkPaint paint;
Cary Clark681287e2018-03-16 11:34:15 -04003059 paint.setMaskFilter(SkMaskFilter::MakeBlur(kSolid_SkBlurStyle, 3));
Cary Clark8032b982017-07-28 11:04:54 -04003060 canvas->drawRect(SkRect::MakeXYWH(40, 40, 175, 175), paint);
3061 }
3062##
3063
3064#Method SkMaskFilter* getMaskFilter() const
3065
Cary Clarkab2621d2018-01-30 10:08:57 -05003066#In Mask_Filter_Methods
3067#Line # returns Mask_Filter, alterations to Mask_Alpha ##
Cary Clark8032b982017-07-28 11:04:54 -04003068 Returns Mask_Filter if set, or nullptr.
3069 Does not alter Mask_Filter Reference_Count.
Herb Derbyfcac00f2018-05-01 11:57:56 -04003070
Cary Clark8032b982017-07-28 11:04:54 -04003071 #Return Mask_Filter if previously set, nullptr otherwise ##
3072
3073 #Example
3074 void draw(SkCanvas* canvas) {
3075 SkPaint paint;
3076 SkDebugf("nullptr %c= mask filter\n", paint.getMaskFilter() ? '!' : '=');
Cary Clark681287e2018-03-16 11:34:15 -04003077 paint.setMaskFilter(SkMaskFilter::MakeBlur(kOuter_SkBlurStyle, 3));
Cary Clark8032b982017-07-28 11:04:54 -04003078 SkDebugf("nullptr %c= mask filter\n", paint.getMaskFilter() ? '!' : '=');
3079 }
3080
3081 #StdOut
3082 nullptr == mask filter
3083 nullptr != mask filter
3084 ##
3085 ##
3086
3087##
3088
3089#Method sk_sp<SkMaskFilter> refMaskFilter() const
3090
Cary Clarkab2621d2018-01-30 10:08:57 -05003091#In Mask_Filter_Methods
3092#Line # references Mask_Filter, alterations to Mask_Alpha ##
Cary Clark8032b982017-07-28 11:04:54 -04003093 Returns Mask_Filter if set, or nullptr.
Cary Clark6fc50412017-09-21 12:31:06 -04003094
Cary Clark8032b982017-07-28 11:04:54 -04003095 Increases Mask_Filter Reference_Count by one.
Herb Derbyfcac00f2018-05-01 11:57:56 -04003096
Cary Clark8032b982017-07-28 11:04:54 -04003097 #Return Mask_Filter if previously set, nullptr otherwise ##
3098
3099 #Example
3100 void draw(SkCanvas* canvas) {
3101 SkPaint paint1, paint2;
Cary Clark681287e2018-03-16 11:34:15 -04003102 paint1.setMaskFilter(SkMaskFilter::MakeBlur(kNormal_SkBlurStyle, 1));
Cary Clark8032b982017-07-28 11:04:54 -04003103 SkDebugf("mask filter unique: %s\n", paint1.getMaskFilter()->unique() ? "true" : "false");
3104 paint2.setMaskFilter(paint1.refMaskFilter());
3105 SkDebugf("mask filter unique: %s\n", paint1.getMaskFilter()->unique() ? "true" : "false");
3106 }
3107
3108 #StdOut
3109 mask filter unique: true
3110 mask filter unique: false
3111 ##
3112 ##
3113
3114##
3115
3116#Method void setMaskFilter(sk_sp<SkMaskFilter> maskFilter)
3117
Cary Clarkab2621d2018-01-30 10:08:57 -05003118#In Mask_Filter_Methods
3119#Line # sets Mask_Filter, alterations to Mask_Alpha ##
Cary Clark6fc50412017-09-21 12:31:06 -04003120Sets Mask_Filter to maskFilter, decreasing Reference_Count of the previous
3121Mask_Filter. Pass nullptr to clear Mask_Filter and leave Mask_Filter effect on
3122Mask_Alpha unaltered.
3123
Cary Clark6fc50412017-09-21 12:31:06 -04003124Increments maskFilter Reference_Count by one.
Cary Clark8032b982017-07-28 11:04:54 -04003125
3126 #Param maskFilter modifies clipping mask generated from drawn geometry ##
3127
3128 #Example
3129 void draw(SkCanvas* canvas) {
3130 SkPaint paint;
3131 paint.setStyle(SkPaint::kStroke_Style);
3132 paint.setStrokeWidth(10);
Cary Clark681287e2018-03-16 11:34:15 -04003133 paint.setMaskFilter(SkMaskFilter::MakeBlur(kNormal_SkBlurStyle, 10));
Cary Clark8032b982017-07-28 11:04:54 -04003134 canvas->drawRect(SkRect::MakeXYWH(40, 40, 175, 175), paint);
3135 }
3136 ##
3137
3138##
3139
Cary Clark08895c42018-02-01 09:37:32 -05003140#Subtopic Mask_Filter_Methods ##
Cary Clark8032b982017-07-28 11:04:54 -04003141# ------------------------------------------------------------------------------
Cary Clark08895c42018-02-01 09:37:32 -05003142#Subtopic Typeface_Methods
3143#Line # get and set Typeface ##
Cary Clark8032b982017-07-28 11:04:54 -04003144
3145Typeface identifies the font used when drawing and measuring text.
3146Typeface may be specified by name, from a file, or from a data stream.
3147The default Typeface defers to the platform-specific default font
3148implementation.
3149
3150#Example
3151#Height 100
3152 void draw(SkCanvas* canvas) {
3153 SkPaint paint;
Ben Wagner700ff172017-11-08 15:37:22 -05003154 paint.setTypeface(SkTypeface::MakeFromName(nullptr, SkFontStyle()));
Cary Clark8032b982017-07-28 11:04:54 -04003155 paint.setAntiAlias(true);
3156 paint.setTextSize(36);
3157 canvas->drawString("A Big Hello!", 10, 40, paint);
3158 paint.setTypeface(nullptr);
3159 paint.setFakeBoldText(true);
3160 canvas->drawString("A Big Hello!", 10, 80, paint);
3161 }
3162##
3163
3164#Method SkTypeface* getTypeface() const
3165
Cary Clarkab2621d2018-01-30 10:08:57 -05003166#In Typeface_Methods
3167#Line # returns Typeface, font description ##
Cary Clark8032b982017-07-28 11:04:54 -04003168 Returns Typeface if set, or nullptr.
Ben Wagner900b5362018-06-22 14:29:08 -04003169 Does not alter Typeface Reference_Count.
Herb Derbyfcac00f2018-05-01 11:57:56 -04003170
Cary Clark8032b982017-07-28 11:04:54 -04003171 #Return Typeface if previously set, nullptr otherwise ##
3172
3173 #Example
3174 void draw(SkCanvas* canvas) {
3175 SkPaint paint;
3176 SkDebugf("nullptr %c= typeface\n", paint.getTypeface() ? '!' : '=');
Cary Clark71961fb2018-01-05 14:21:59 -05003177 paint.setTypeface(SkTypeface::MakeFromName("monospace", SkFontStyle()));
Cary Clark8032b982017-07-28 11:04:54 -04003178 SkDebugf("nullptr %c= typeface\n", paint.getTypeface() ? '!' : '=');
3179 }
3180
3181 #StdOut
3182 nullptr == typeface
3183 nullptr != typeface
3184 ##
3185 ##
3186
3187##
3188
3189#Method sk_sp<SkTypeface> refTypeface() const
3190
Cary Clarkab2621d2018-01-30 10:08:57 -05003191#In Typeface_Methods
3192#Line # references Typeface, font description ##
Cary Clark8032b982017-07-28 11:04:54 -04003193 Increases Typeface Reference_Count by one.
3194
3195 #Return Typeface if previously set, nullptr otherwise ##
3196
3197 #Example
3198 void draw(SkCanvas* canvas) {
3199 SkPaint paint1, paint2;
Herb Derbyfcac00f2018-05-01 11:57:56 -04003200 paint1.setTypeface(SkTypeface::MakeFromName("monospace",
Cary Clark8032b982017-07-28 11:04:54 -04003201 SkFontStyle(SkFontStyle::kNormal_Weight, SkFontStyle::kNormal_Width,
3202 SkFontStyle::kItalic_Slant)));
3203 SkDebugf("typeface1 %c= typeface2\n",
3204 paint1.getTypeface() == paint2.getTypeface() ? '=' : '!');
3205 paint2.setTypeface(paint1.refTypeface());
3206 SkDebugf("typeface1 %c= typeface2\n",
3207 paint1.getTypeface() == paint2.getTypeface() ? '=' : '!');
3208 }
3209
3210 #StdOut
3211 typeface1 != typeface2
3212 typeface1 == typeface2
3213 ##
3214 ##
3215
3216##
3217
3218#Method void setTypeface(sk_sp<SkTypeface> typeface)
3219
Cary Clarkab2621d2018-01-30 10:08:57 -05003220#In Typeface_Methods
3221#Line # sets Typeface, font description ##
Herb Derbyfcac00f2018-05-01 11:57:56 -04003222Sets Typeface to typeface, decreasing Reference_Count of the previous Typeface.
Cary Clark6fc50412017-09-21 12:31:06 -04003223Pass nullptr to clear Typeface and use the default typeface. Increments
3224typeface Reference_Count by one.
Cary Clark8032b982017-07-28 11:04:54 -04003225
3226 #Param typeface font and style used to draw text ##
3227
3228 #Example
3229 #Height 64
3230 void draw(SkCanvas* canvas) {
3231 SkPaint paint;
Cary Clark71961fb2018-01-05 14:21:59 -05003232 paint.setTypeface(SkTypeface::MakeFromName("monospace", SkFontStyle()));
3233 canvas->drawString("hamburgerfons", 10, 30, paint);
Cary Clark8032b982017-07-28 11:04:54 -04003234 paint.setTypeface(nullptr);
Cary Clark71961fb2018-01-05 14:21:59 -05003235 canvas->drawString("hamburgerfons", 10, 50, paint);
Cary Clark8032b982017-07-28 11:04:54 -04003236 }
3237 ##
3238
3239##
3240
Cary Clark08895c42018-02-01 09:37:32 -05003241#Subtopic Typeface_Methods ##
Cary Clark8032b982017-07-28 11:04:54 -04003242# ------------------------------------------------------------------------------
Cary Clark08895c42018-02-01 09:37:32 -05003243#Subtopic Image_Filter_Methods
3244#Line # get and set Image_Filter ##
Cary Clark8032b982017-07-28 11:04:54 -04003245
3246Image_Filter operates on the pixel representation of the shape, as modified by Paint
3247with Blend_Mode set to SkBlendMode::kSrcOver. Image_Filter creates a new bitmap,
3248which is drawn to the device using the set Blend_Mode.
Cary Clark6fc50412017-09-21 12:31:06 -04003249
Cary Clark8032b982017-07-28 11:04:54 -04003250Image_Filter is higher level than Mask_Filter; for instance, an Image_Filter
Cary Clarkce101242017-09-01 15:51:02 -04003251can operate on all channels of Color, while Mask_Filter generates Alpha only.
Cary Clark8032b982017-07-28 11:04:54 -04003252Image_Filter operates independently of and can be used in combination with
Mike Reed8ad91a92018-01-19 19:09:32 -05003253Mask_Filter.
Cary Clark8032b982017-07-28 11:04:54 -04003254
3255#Example
3256 #ToDo explain why the two draws are so different ##
Cary Clark81abc432018-06-25 16:30:08 -04003257 #Function
3258 ###$
3259 #include "SkBlurImageFilter.h"
3260 $$$#
3261 ##
Cary Clark8032b982017-07-28 11:04:54 -04003262 void draw(SkCanvas* canvas) {
3263 SkPaint paint;
3264 paint.setStyle(SkPaint::kStroke_Style);
3265 paint.setStrokeWidth(2);
3266 SkRegion region;
3267 region.op( 10, 10, 50, 50, SkRegion::kUnion_Op);
3268 region.op( 10, 50, 90, 90, SkRegion::kUnion_Op);
Cary Clarka560c472017-11-27 10:44:06 -05003269 paint.setImageFilter(SkBlurImageFilter::Make(5.0f, 5.0f, nullptr));
Cary Clark8032b982017-07-28 11:04:54 -04003270 canvas->drawRegion(region, paint);
3271 paint.setImageFilter(nullptr);
Cary Clarka7b84c52018-03-18 11:46:54 -04003272 paint.setMaskFilter(SkMaskFilter::MakeBlur(kNormal_SkBlurStyle, 5));
Cary Clark8032b982017-07-28 11:04:54 -04003273 canvas->translate(100, 100);
3274 canvas->drawRegion(region, paint);
3275 }
3276##
3277
3278#Method SkImageFilter* getImageFilter() const
3279
Cary Clarkab2621d2018-01-30 10:08:57 -05003280#In Image_Filter_Methods
3281#Line # returns Image_Filter, alter pixels; blur ##
Cary Clark8032b982017-07-28 11:04:54 -04003282 Returns Image_Filter if set, or nullptr.
3283 Does not alter Image_Filter Reference_Count.
Herb Derbyfcac00f2018-05-01 11:57:56 -04003284
Cary Clark8032b982017-07-28 11:04:54 -04003285 #Return Image_Filter if previously set, nullptr otherwise ##
3286
3287 #Example
Cary Clark81abc432018-06-25 16:30:08 -04003288 #Function
3289 ###$
3290 #include "SkBlurImageFilter.h"
3291 $$$#
3292 ##
Cary Clark8032b982017-07-28 11:04:54 -04003293 void draw(SkCanvas* canvas) {
3294 SkPaint paint;
3295 SkDebugf("nullptr %c= image filter\n", paint.getImageFilter() ? '!' : '=');
Cary Clarka560c472017-11-27 10:44:06 -05003296 paint.setImageFilter(SkBlurImageFilter::Make(kOuter_SkBlurStyle, 3, nullptr, nullptr));
Cary Clark8032b982017-07-28 11:04:54 -04003297 SkDebugf("nullptr %c= image filter\n", paint.getImageFilter() ? '!' : '=');
3298 }
3299
3300 #StdOut
3301 nullptr == image filter
3302 nullptr != image filter
3303 ##
3304 ##
3305
3306##
3307
3308#Method sk_sp<SkImageFilter> refImageFilter() const
3309
Cary Clarkab2621d2018-01-30 10:08:57 -05003310#In Image_Filter_Methods
3311#Line # references Image_Filter, alter pixels; blur ##
Cary Clark8032b982017-07-28 11:04:54 -04003312 Returns Image_Filter if set, or nullptr.
3313 Increases Image_Filter Reference_Count by one.
3314
3315 #Return Image_Filter if previously set, nullptr otherwise ##
3316
3317 #Example
3318 void draw(SkCanvas* canvas) {
3319 SkPaint paint1, paint2;
3320 paint1.setImageFilter(SkOffsetImageFilter::Make(25, 25, nullptr));
3321 SkDebugf("image filter unique: %s\n", paint1.getImageFilter()->unique() ? "true" : "false");
3322 paint2.setImageFilter(paint1.refImageFilter());
3323 SkDebugf("image filter unique: %s\n", paint1.getImageFilter()->unique() ? "true" : "false");
3324 }
3325
3326 #StdOut
3327 image filter unique: true
3328 image filter unique: false
3329 ##
3330 ##
3331
3332##
3333
3334#Method void setImageFilter(sk_sp<SkImageFilter> imageFilter)
3335
Cary Clarkab2621d2018-01-30 10:08:57 -05003336#In Image_Filter_Methods
3337#Line # sets Image_Filter, alter pixels; blur ##
Cary Clark6fc50412017-09-21 12:31:06 -04003338Sets Image_Filter to imageFilter, decreasing Reference_Count of the previous
3339Image_Filter. Pass nullptr to clear Image_Filter, and remove Image_Filter effect
3340on drawing.
3341
Cary Clark6fc50412017-09-21 12:31:06 -04003342Increments imageFilter Reference_Count by one.
Cary Clark8032b982017-07-28 11:04:54 -04003343
3344 #Param imageFilter how Image is sampled when transformed ##
3345
3346 #Example
3347 #Height 160
3348 void draw(SkCanvas* canvas) {
3349 SkBitmap bitmap;
3350 bitmap.allocN32Pixels(100, 100);
3351 SkCanvas offscreen(bitmap);
3352 SkPaint paint;
3353 paint.setAntiAlias(true);
3354 paint.setColor(SK_ColorWHITE);
3355 paint.setTextSize(96);
3356 offscreen.clear(0);
3357 offscreen.drawString("e", 20, 70, paint);
3358 paint.setImageFilter(
3359 SkLightingImageFilter::MakePointLitDiffuse(SkPoint3::Make(80, 100, 10),
3360 SK_ColorWHITE, 1, 2, nullptr, nullptr));
3361 canvas->drawBitmap(bitmap, 0, 0, &paint);
3362 }
3363 ##
3364
3365##
3366
Cary Clark08895c42018-02-01 09:37:32 -05003367#Subtopic Image_Filter_Methods ##
Cary Clark8032b982017-07-28 11:04:54 -04003368# ------------------------------------------------------------------------------
Cary Clark08895c42018-02-01 09:37:32 -05003369#Subtopic Draw_Looper_Methods
3370#Line # get and set Draw_Looper ##
Cary Clark8032b982017-07-28 11:04:54 -04003371
3372Draw_Looper sets a modifier that communicates state from one Draw_Layer
3373to another to construct the draw.
Cary Clark6fc50412017-09-21 12:31:06 -04003374
Cary Clark8032b982017-07-28 11:04:54 -04003375Draw_Looper draws one or more times, modifying the canvas and paint each time.
3376Draw_Looper may be used to draw multiple colors or create a colored shadow.
Herb Derbyfcac00f2018-05-01 11:57:56 -04003377Set Draw_Looper to nullptr to prevent Draw_Looper from modifying the draw.
Cary Clark8032b982017-07-28 11:04:54 -04003378
3379#Example
3380#Height 128
3381 void draw(SkCanvas* canvas) {
3382 SkLayerDrawLooper::LayerInfo info;
3383 info.fPaintBits = (SkLayerDrawLooper::BitFlags) SkLayerDrawLooper::kColorFilter_Bit;
3384 info.fColorMode = SkBlendMode::kSrc;
3385 SkLayerDrawLooper::Builder looperBuilder;
3386 SkPaint* loopPaint = looperBuilder.addLayer(info);
3387 loopPaint->setColor(SK_ColorRED);
3388 info.fOffset.set(20, 20);
3389 loopPaint = looperBuilder.addLayer(info);
3390 loopPaint->setColor(SK_ColorBLUE);
3391 SkPaint paint;
3392 paint.setDrawLooper(looperBuilder.detach());
3393 canvas->drawCircle(50, 50, 50, paint);
3394 }
3395
3396##
3397
3398#Method SkDrawLooper* getDrawLooper() const
3399
Cary Clarkab2621d2018-01-30 10:08:57 -05003400#In Draw_Looper_Methods
3401#Line # returns Draw_Looper, multiple layers ##
Cary Clark8032b982017-07-28 11:04:54 -04003402 Returns Draw_Looper if set, or nullptr.
3403 Does not alter Draw_Looper Reference_Count.
Herb Derbyfcac00f2018-05-01 11:57:56 -04003404
Cary Clark8032b982017-07-28 11:04:54 -04003405 #Return Draw_Looper if previously set, nullptr otherwise ##
3406
3407 #Example
3408 void draw(SkCanvas* canvas) {
3409 SkPaint paint;
3410 SkDebugf("nullptr %c= draw looper\n", paint.getDrawLooper() ? '!' : '=');
3411 SkLayerDrawLooper::Builder looperBuilder;
3412 paint.setDrawLooper(looperBuilder.detach());
3413 SkDebugf("nullptr %c= draw looper\n", paint.getDrawLooper() ? '!' : '=');
3414 }
3415
3416 #StdOut
3417 nullptr == draw looper
3418 nullptr != draw looper
3419 ##
3420 ##
3421
3422##
3423
3424#Method sk_sp<SkDrawLooper> refDrawLooper() const
3425
Cary Clarkab2621d2018-01-30 10:08:57 -05003426#In Draw_Looper_Methods
3427#Line # references Draw_Looper, multiple layers ##
Cary Clark8032b982017-07-28 11:04:54 -04003428 Returns Draw_Looper if set, or nullptr.
3429 Increases Draw_Looper Reference_Count by one.
3430
3431 #Return Draw_Looper if previously set, nullptr otherwise ##
3432
3433 #Example
3434 void draw(SkCanvas* canvas) {
3435 SkPaint paint1, paint2;
3436 SkLayerDrawLooper::Builder looperBuilder;
3437 paint1.setDrawLooper(looperBuilder.detach());
3438 SkDebugf("draw looper unique: %s\n", paint1.getDrawLooper()->unique() ? "true" : "false");
3439 paint2.setDrawLooper(paint1.refDrawLooper());
3440 SkDebugf("draw looper unique: %s\n", paint1.getDrawLooper()->unique() ? "true" : "false");
3441 }
3442
3443 #StdOut
3444 draw looper unique: true
3445 draw looper unique: false
3446 ##
3447 ##
3448
3449##
3450
3451#Method SkDrawLooper* getLooper() const
Cary Clark4855f782018-02-06 09:41:53 -05003452#Bug 6259
Cary Clark8032b982017-07-28 11:04:54 -04003453#Deprecated
Cary Clark8032b982017-07-28 11:04:54 -04003454##
3455
3456#Method void setDrawLooper(sk_sp<SkDrawLooper> drawLooper)
Cary Clarkab2621d2018-01-30 10:08:57 -05003457#In Draw_Looper_Methods
3458#Line # sets Draw_Looper, multiple layers ##
Cary Clark6fc50412017-09-21 12:31:06 -04003459Sets Draw_Looper to drawLooper, decreasing Reference_Count of the previous
3460drawLooper. Pass nullptr to clear Draw_Looper and leave Draw_Looper effect on
3461drawing unaltered.
3462
3463Increments drawLooper Reference_Count by one.
Cary Clark8032b982017-07-28 11:04:54 -04003464
Cary Clarka523d2d2017-08-30 08:58:10 -04003465 #Param drawLooper iterates through drawing one or more time, altering Paint ##
Cary Clark8032b982017-07-28 11:04:54 -04003466
3467 #Example
3468 #Height 128
3469 void draw(SkCanvas* canvas) {
3470 SkPaint paint;
3471 paint.setDrawLooper(SkBlurDrawLooper::Make(0x7FFF0000, 4, -5, -10));
3472 paint.setStyle(SkPaint::kStroke_Style);
3473 paint.setStrokeWidth(10);
3474 paint.setAntiAlias(true);
3475 paint.setColor(0x7f0000ff);
3476 canvas->drawCircle(70, 70, 50, paint);
3477 }
3478 ##
3479
3480##
3481
3482#Method void setLooper(sk_sp<SkDrawLooper> drawLooper)
Cary Clark4855f782018-02-06 09:41:53 -05003483#Bug 6259
Cary Clark8032b982017-07-28 11:04:54 -04003484#Deprecated
Cary Clark8032b982017-07-28 11:04:54 -04003485##
3486
Cary Clark08895c42018-02-01 09:37:32 -05003487#Subtopic Draw_Looper_Methods ##
Cary Clark4855f782018-02-06 09:41:53 -05003488
Cary Clark8032b982017-07-28 11:04:54 -04003489# ------------------------------------------------------------------------------
Cary Clark08895c42018-02-01 09:37:32 -05003490#Subtopic Text_Align
3491#Line # text placement relative to position ##
Cary Clark8032b982017-07-28 11:04:54 -04003492
3493#Enum Align
Cary Clark08895c42018-02-01 09:37:32 -05003494#Line # glyph locations relative to text position ##
Cary Clark8032b982017-07-28 11:04:54 -04003495#Code
3496 enum Align {
3497 kLeft_Align,
3498 kCenter_Align,
3499 kRight_Align,
3500 };
Cary Clarkd98f78c2018-04-26 08:32:37 -04003501
3502 static constexpr int kAlignCount = 3;
Cary Clark8032b982017-07-28 11:04:54 -04003503##
3504
3505Align adjusts the text relative to the text position.
Cary Clarkce101242017-09-01 15:51:02 -04003506Align affects Glyphs drawn with: SkCanvas::drawText, SkCanvas::drawPosText,
Cary Clark153e76d2018-08-28 11:48:28 -04003507SkCanvas::drawPosTextH, SkCanvas::drawTextRSXform, SkCanvas::drawTextBlob,
Herb Derbyfcac00f2018-05-01 11:57:56 -04003508and SkCanvas::drawString;
Cary Clarkce101242017-09-01 15:51:02 -04003509as well as calls that place text Glyphs like getTextWidths and getTextPath.
Cary Clark8032b982017-07-28 11:04:54 -04003510
3511The text position is set by the font for both horizontal and vertical text.
3512Typically, for horizontal text, the position is to the left side of the glyph on the
3513base line; and for vertical text, the position is the horizontal center of the glyph
3514at the caps height.
3515
Herb Derbyfcac00f2018-05-01 11:57:56 -04003516Align adjusts the glyph position to center it or move it to abut the position
Cary Clark8032b982017-07-28 11:04:54 -04003517using the metrics returned by the font.
3518
3519Align defaults to kLeft_Align.
3520
3521#Const kLeft_Align 0
Cary Clark682c58d2018-05-16 07:07:07 -04003522#Line # positions glyph by computed font offset ##
Cary Clark8032b982017-07-28 11:04:54 -04003523 Leaves the glyph at the position computed by the font offset by the text position.
3524##
3525
3526#Const kCenter_Align 1
Cary Clark682c58d2018-05-16 07:07:07 -04003527#Line # centers line of glyphs by its width or height ##
Cary Clark8032b982017-07-28 11:04:54 -04003528 Moves the glyph half its width if Flags has kVerticalText_Flag clear, and
3529 half its height if Flags has kVerticalText_Flag set.
3530##
3531
3532#Const kRight_Align 2
Cary Clark682c58d2018-05-16 07:07:07 -04003533#Line # moves lines of glyphs by its width or height ##
Cary Clark8032b982017-07-28 11:04:54 -04003534 Moves the glyph by its width if Flags has kVerticalText_Flag clear,
3535 and by its height if Flags has kVerticalText_Flag set.
3536##
3537
Cary Clark8032b982017-07-28 11:04:54 -04003538#Const kAlignCount 3
Cary Clark682c58d2018-05-16 07:07:07 -04003539#Line # number of different Text_Align values defined ##
Cary Clark137b8742018-05-30 09:21:49 -04003540May be used to verify that Align is a legal value.
Cary Clark8032b982017-07-28 11:04:54 -04003541##
3542
3543#Enum ##
3544
3545#Example
3546 #Height 160
3547 #Description
3548 Each position separately moves the glyph in drawPosText.
3549 ##
3550 void draw(SkCanvas* canvas) {
3551 SkPaint paint;
3552 paint.setTextSize(40);
3553 SkPoint position[] = {{100, 50}, {150, 40}};
3554 for (SkPaint::Align a : { SkPaint::kLeft_Align,
3555 SkPaint::kCenter_Align,
3556 SkPaint::kRight_Align}) {
3557 paint.setTextAlign(a);
3558 canvas->drawPosText("Aa", 2, position, paint);
3559 canvas->translate(0, 50);
3560 }
3561 }
3562##
3563
3564#Example
3565 #Height 160
3566 #Description
3567 Vertical_Text treats kLeft_Align as top align, and kRight_Align as bottom align.
3568 ##
3569 void draw(SkCanvas* canvas) {
3570 SkPaint paint;
3571 paint.setTextSize(40);
3572 paint.setVerticalText(true);
3573 for (SkPaint::Align a : { SkPaint::kLeft_Align,
3574 SkPaint::kCenter_Align,
3575 SkPaint::kRight_Align }) {
3576 paint.setTextAlign(a);
3577 canvas->drawString("Aa", 50, 80, paint);
3578 canvas->translate(50, 0);
3579 }
3580 }
3581##
3582
3583#Method Align getTextAlign() const
3584
Cary Clarkab2621d2018-01-30 10:08:57 -05003585#In Text_Align
3586#Line # returns Align: left, center, or right ##
Cary Clark8032b982017-07-28 11:04:54 -04003587 Returns Text_Align.
3588 Returns kLeft_Align if Text_Align has not been set.
3589
3590 #Return text placement relative to position ##
3591
3592 #Example
3593 SkPaint paint;
3594 SkDebugf("kLeft_Align %c= default\n", SkPaint::kLeft_Align == paint.getTextAlign() ? '=' : '!');
3595
3596 #StdOut
3597 kLeft_Align == default
3598 ##
3599 ##
3600##
3601
3602#Method void setTextAlign(Align align)
3603
Cary Clarkab2621d2018-01-30 10:08:57 -05003604#In Text_Align
3605#Line # sets Align: left, center, or right ##
Cary Clark8032b982017-07-28 11:04:54 -04003606 Sets Text_Align to align.
3607 Has no effect if align is an invalid value.
3608
3609 #Param align text placement relative to position ##
3610
3611 #Example
3612 #Height 160
3613 #Description
3614 Text is left-aligned by default, and then set to center. Setting the
3615 alignment out of range has no effect.
3616 ##
3617 void draw(SkCanvas* canvas) {
3618 SkPaint paint;
3619 paint.setTextSize(40);
3620 canvas->drawString("Aa", 100, 50, paint);
3621 paint.setTextAlign(SkPaint::kCenter_Align);
3622 canvas->drawString("Aa", 100, 100, paint);
3623 paint.setTextAlign((SkPaint::Align) SkPaint::kAlignCount);
3624 canvas->drawString("Aa", 100, 150, paint);
3625 }
3626 ##
3627
3628##
3629
Cary Clark08895c42018-02-01 09:37:32 -05003630#Subtopic Text_Align ##
Cary Clark8032b982017-07-28 11:04:54 -04003631# ------------------------------------------------------------------------------
Cary Clark08895c42018-02-01 09:37:32 -05003632#Subtopic Text_Size
3633#Line # overall height in points ##
Cary Clark8032b982017-07-28 11:04:54 -04003634
3635Text_Size adjusts the overall text size in points.
3636Text_Size can be set to any positive value or zero.
3637Text_Size defaults to 12.
3638Set SkPaintDefaults_TextSize at compile time to change the default setting.
3639
3640#Example
3641#Height 135
3642 void draw(SkCanvas* canvas) {
3643 SkPaint paint;
3644 canvas->drawString("12 point", 10, 20, paint);
3645 paint.setTextSize(24);
3646 canvas->drawString("24 point", 10, 60, paint);
3647 paint.setTextSize(48);
3648 canvas->drawString("48 point", 10, 120, paint);
3649 }
3650##
3651
3652#Method SkScalar getTextSize() const
3653
Cary Clarkab2621d2018-01-30 10:08:57 -05003654#In Text_Size
3655#Line # returns text size in points ##
Cary Clark8032b982017-07-28 11:04:54 -04003656 Returns Text_Size in points.
3657
3658 #Return typographic height of text ##
3659
3660 #Example
3661 SkPaint paint;
3662 SkDebugf("12 %c= default text size\n", 12 == paint.getTextSize() ? '=' : '!');
3663 ##
3664
3665##
3666
3667#Method void setTextSize(SkScalar textSize)
3668
Cary Clarkab2621d2018-01-30 10:08:57 -05003669#In Text_Size
3670#Line # sets text size in points ##
Cary Clark8032b982017-07-28 11:04:54 -04003671 Sets Text_Size in points.
3672 Has no effect if textSize is not greater than or equal to zero.
Herb Derbyfcac00f2018-05-01 11:57:56 -04003673
Cary Clark8032b982017-07-28 11:04:54 -04003674 #Param textSize typographic height of text ##
3675
3676 #Example
3677 SkPaint paint;
3678 SkDebugf("12 %c= text size\n", 12 == paint.getTextSize() ? '=' : '!');
3679 paint.setTextSize(-20);
3680 SkDebugf("12 %c= text size\n", 12 == paint.getTextSize() ? '=' : '!');
3681 ##
3682
3683##
3684
Cary Clark08895c42018-02-01 09:37:32 -05003685#Subtopic Text_Size ##
Cary Clark8032b982017-07-28 11:04:54 -04003686# ------------------------------------------------------------------------------
Cary Clark08895c42018-02-01 09:37:32 -05003687#Subtopic Text_Scale_X
3688#Line # text horizontal scale ##
Cary Clark8032b982017-07-28 11:04:54 -04003689
3690Text_Scale_X adjusts the text horizontal scale.
3691Text scaling approximates condensed and expanded type faces when the actual face
3692is not available.
3693Text_Scale_X can be set to any value.
3694Text_Scale_X defaults to 1.
3695
3696#Example
3697#Height 128
3698 void draw(SkCanvas* canvas) {
3699 SkPaint paint;
3700 paint.setAntiAlias(true);
3701 paint.setTextSize(24);
3702 paint.setTextScaleX(.8f);
3703 canvas->drawString("narrow", 10, 20, paint);
3704 paint.setTextScaleX(1);
3705 canvas->drawString("normal", 10, 60, paint);
3706 paint.setTextScaleX(1.2f);
3707 canvas->drawString("wide", 10, 100, paint);
3708 }
3709##
3710
3711#Method SkScalar getTextScaleX() const
3712
Cary Clarkab2621d2018-01-30 10:08:57 -05003713#In Text_Scale_X
3714#Line # returns the text horizontal scale; condensed text ##
Cary Clark8032b982017-07-28 11:04:54 -04003715 Returns Text_Scale_X.
3716 Default value is 1.
3717
3718 #Return text horizontal scale ##
3719
3720 #Example
3721 SkPaint paint;
3722 SkDebugf("1 %c= default text scale x\n", 1 == paint.getTextScaleX() ? '=' : '!');
3723 ##
3724
3725##
3726
3727
3728#Method void setTextScaleX(SkScalar scaleX)
3729
Cary Clarkab2621d2018-01-30 10:08:57 -05003730#In Text_Scale_X
3731#Line # sets the text horizontal scale; condensed text ##
Cary Clark8032b982017-07-28 11:04:54 -04003732 Sets Text_Scale_X.
3733 Default value is 1.
Herb Derbyfcac00f2018-05-01 11:57:56 -04003734
Cary Clark8032b982017-07-28 11:04:54 -04003735 #Param scaleX text horizontal scale ##
3736
3737 #Example
3738 SkPaint paint;
3739 paint.setTextScaleX(0.f / 0.f);
3740 SkDebugf("text scale %s-a-number\n", SkScalarIsNaN(paint.getTextScaleX()) ? "not" : "is");
3741 ##
3742
3743##
3744
Cary Clark08895c42018-02-01 09:37:32 -05003745#Subtopic Text_Scale_X ##
Cary Clark8032b982017-07-28 11:04:54 -04003746
Cary Clark08895c42018-02-01 09:37:32 -05003747#Subtopic Text_Skew_X
3748#Line # text horizontal slant ##
Cary Clark8032b982017-07-28 11:04:54 -04003749
3750
3751Text_Skew_X adjusts the text horizontal slant.
3752Text skewing approximates italic and oblique type faces when the actual face
3753is not available.
3754Text_Skew_X can be set to any value.
3755Text_Skew_X defaults to 0.
3756
3757#Example
3758#Height 128
3759 void draw(SkCanvas* canvas) {
3760 SkPaint paint;
3761 paint.setAntiAlias(true);
3762 paint.setTextSize(24);
3763 paint.setTextSkewX(-.25f);
3764 canvas->drawString("right-leaning", 10, 100, paint);
3765 paint.setTextSkewX(0);
3766 canvas->drawString("normal", 10, 60, paint);
3767 paint.setTextSkewX(.25f);
3768 canvas->drawString("left-leaning", 10, 20, paint);
3769 }
3770##
3771
3772#Method SkScalar getTextSkewX() const
3773
Cary Clarkab2621d2018-01-30 10:08:57 -05003774#In Text_Skew_X
3775#Line # returns the text horizontal skew; oblique text ##
Cary Clark8032b982017-07-28 11:04:54 -04003776 Returns Text_Skew_X.
3777 Default value is zero.
3778
3779 #Return additional shear in x-axis relative to y-axis ##
3780
3781 #Example
3782 SkPaint paint;
3783 SkDebugf("0 %c= default text skew x\n", 0 == paint.getTextSkewX() ? '=' : '!');
3784 ##
3785
3786##
3787
3788#Method void setTextSkewX(SkScalar skewX)
3789
Cary Clarkab2621d2018-01-30 10:08:57 -05003790#In Text_Skew_X
3791#Line # sets the text horizontal skew; oblique text ##
Cary Clark8032b982017-07-28 11:04:54 -04003792 Sets Text_Skew_X.
3793 Default value is zero.
3794
3795 #Param skewX additional shear in x-axis relative to y-axis ##
3796
3797 #Example
3798 SkPaint paint;
3799 paint.setTextScaleX(1.f / 0.f);
3800 SkDebugf("text scale %s-finite\n", SkScalarIsFinite(paint.getTextScaleX()) ? "is" : "not");
3801 ##
3802
3803##
3804
Cary Clark08895c42018-02-01 09:37:32 -05003805#Subtopic Text_Skew_X ##
Cary Clark8032b982017-07-28 11:04:54 -04003806
3807# ------------------------------------------------------------------------------
Cary Clark08895c42018-02-01 09:37:32 -05003808#Subtopic Text_Encoding
3809#Line # text encoded as characters or Glyphs ##
Cary Clark8032b982017-07-28 11:04:54 -04003810
3811#Enum TextEncoding
Cary Clark08895c42018-02-01 09:37:32 -05003812#Line # character or glyph encoded size ##
Cary Clark8032b982017-07-28 11:04:54 -04003813
3814#Code
3815 enum TextEncoding {
3816 kUTF8_TextEncoding,
3817 kUTF16_TextEncoding,
3818 kUTF32_TextEncoding,
Cary Clarkbad5ad72017-08-03 17:14:08 -04003819 kGlyphID_TextEncoding,
Cary Clark8032b982017-07-28 11:04:54 -04003820 };
3821##
3822
Cary Clark6fc50412017-09-21 12:31:06 -04003823TextEncoding determines whether text specifies character codes and their encoded
Cary Clarkbc5697d2017-10-04 14:31:33 -04003824size, or glyph indices. Characters are encoded as specified by the
Cary Clark682c58d2018-05-16 07:07:07 -04003825#A Unicode standard # https://unicode.org/standard/standard.html ##
Cary Clark6fc50412017-09-21 12:31:06 -04003826.
3827
Cary Clark8032b982017-07-28 11:04:54 -04003828Character codes encoded size are specified by UTF-8, UTF-16, or UTF-32.
Cary Clarkbc5697d2017-10-04 14:31:33 -04003829All character code formats are able to represent all of Unicode, differing only
Cary Clark8032b982017-07-28 11:04:54 -04003830in the total storage required.
3831
Cary Clark6fc50412017-09-21 12:31:06 -04003832#A UTF-8 (RFC 3629) # https://tools.ietf.org/html/rfc3629 ##
3833 encodes each character as one or more 8-bit bytes.
3834
3835#A UTF-16 (RFC 2781) # https://tools.ietf.org/html/rfc2781 ##
3836 encodes each character as one or two 16-bit words.
3837
Cary Clark682c58d2018-05-16 07:07:07 -04003838#A UTF-32 # https://www.unicode.org/versions/Unicode5.0.0/ch03.pdf ##
Cary Clark6fc50412017-09-21 12:31:06 -04003839 encodes each character as one 32-bit word.
Cary Clark8032b982017-07-28 11:04:54 -04003840
Herb Derbyfcac00f2018-05-01 11:57:56 -04003841Font_Manager uses font data to convert character code points into glyph indices.
Cary Clark8032b982017-07-28 11:04:54 -04003842A glyph index is a 16-bit word.
3843
3844TextEncoding is set to kUTF8_TextEncoding by default.
3845
3846#Const kUTF8_TextEncoding 0
Cary Clark682c58d2018-05-16 07:07:07 -04003847#Line # uses bytes to represent UTF-8 or ASCII ##
Cary Clark8032b982017-07-28 11:04:54 -04003848##
3849#Const kUTF16_TextEncoding 1
Cary Clark682c58d2018-05-16 07:07:07 -04003850#Line # uses two byte words to represent most of Unicode ##
Cary Clark8032b982017-07-28 11:04:54 -04003851##
3852#Const kUTF32_TextEncoding 2
Cary Clark682c58d2018-05-16 07:07:07 -04003853#Line # uses four byte words to represent all of Unicode ##
Cary Clark8032b982017-07-28 11:04:54 -04003854##
3855#Const kGlyphID_TextEncoding 3
Cary Clark682c58d2018-05-16 07:07:07 -04003856#Line # uses two byte words to represent glyph indices ##
Cary Clark8032b982017-07-28 11:04:54 -04003857##
3858
3859#Enum ##
3860
3861#Example
3862#Height 128
3863#Description
Cary Clarkbc5697d2017-10-04 14:31:33 -04003864First line is encoded in UTF-8.
3865Second line is encoded in UTF-16.
3866Third line is encoded in UTF-32.
Cary Clark682c58d2018-05-16 07:07:07 -04003867Fourth line has 16-bit glyph indices.
Cary Clark8032b982017-07-28 11:04:54 -04003868##
3869void draw(SkCanvas* canvas) {
3870 SkPaint paint;
3871 const char hello8[] = "Hello" "\xE2" "\x98" "\xBA";
3872 const uint16_t hello16[] = { 'H', 'e', 'l', 'l', 'o', 0x263A };
3873 const uint32_t hello32[] = { 'H', 'e', 'l', 'l', 'o', 0x263A };
3874 paint.setTextSize(24);
3875 canvas->drawText(hello8, sizeof(hello8) - 1, 10, 30, paint);
3876 paint.setTextEncoding(SkPaint::kUTF16_TextEncoding);
3877 canvas->drawText(hello16, sizeof(hello16), 10, 60, paint);
3878 paint.setTextEncoding(SkPaint::kUTF32_TextEncoding);
3879 canvas->drawText(hello32, sizeof(hello32), 10, 90, paint);
3880 uint16_t glyphs[SK_ARRAY_COUNT(hello32)];
3881 paint.textToGlyphs(hello32, sizeof(hello32), glyphs);
3882 paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
3883 canvas->drawText(glyphs, sizeof(glyphs), 10, 120, paint);
3884}
3885##
3886
3887#Method TextEncoding getTextEncoding() const
3888
Cary Clarkab2621d2018-01-30 10:08:57 -05003889#In Text_Encoding
3890#Line # returns character or glyph encoded size ##
Cary Clark8032b982017-07-28 11:04:54 -04003891 Returns Text_Encoding.
3892 Text_Encoding determines how character code points are mapped to font glyph indices.
3893
Herb Derbyfcac00f2018-05-01 11:57:56 -04003894 #Return one of: kUTF8_TextEncoding, kUTF16_TextEncoding, kUTF32_TextEncoding, or
3895 kGlyphID_TextEncoding
Cary Clark8032b982017-07-28 11:04:54 -04003896 ##
3897
3898 #Example
3899 SkPaint paint;
Herb Derbyfcac00f2018-05-01 11:57:56 -04003900 SkDebugf("kUTF8_TextEncoding %c= text encoding\n",
Cary Clark8032b982017-07-28 11:04:54 -04003901 SkPaint::kUTF8_TextEncoding == paint.getTextEncoding() ? '=' : '!');
3902 paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
Herb Derbyfcac00f2018-05-01 11:57:56 -04003903 SkDebugf("kGlyphID_TextEncoding %c= text encoding\n",
Cary Clark8032b982017-07-28 11:04:54 -04003904 SkPaint::kGlyphID_TextEncoding == paint.getTextEncoding() ? '=' : '!');
3905
3906 #StdOut
3907 kUTF8_TextEncoding == text encoding
3908 kGlyphID_TextEncoding == text encoding
3909 ##
3910 ##
3911
3912##
3913
3914
3915#Method void setTextEncoding(TextEncoding encoding)
3916
Cary Clarkab2621d2018-01-30 10:08:57 -05003917#In Text_Encoding
3918#Line # sets character or glyph encoded size ##
Herb Derbyfcac00f2018-05-01 11:57:56 -04003919 Sets Text_Encoding to encoding.
Cary Clark8032b982017-07-28 11:04:54 -04003920 Text_Encoding determines how character code points are mapped to font glyph indices.
3921 Invalid values for encoding are ignored.
3922
Herb Derbyfcac00f2018-05-01 11:57:56 -04003923 #Param encoding one of: kUTF8_TextEncoding, kUTF16_TextEncoding, kUTF32_TextEncoding, or
3924 kGlyphID_TextEncoding
Cary Clark579985c2017-07-31 11:48:27 -04003925 #Param ##
Cary Clark8032b982017-07-28 11:04:54 -04003926
3927 #Example
3928 SkPaint paint;
3929 paint.setTextEncoding((SkPaint::TextEncoding) 4);
Cary Clark75fd4492018-06-20 12:45:16 -04003930 SkDebugf("4 %c= text encoding\n", (SkPaint::TextEncoding) 4 == paint.getTextEncoding() ? '=' : '!');
Cary Clark8032b982017-07-28 11:04:54 -04003931
3932 #StdOut
3933 4 != text encoding
3934 ##
3935 ##
3936
3937##
3938
Cary Clark08895c42018-02-01 09:37:32 -05003939#Subtopic Text_Encoding ##
Cary Clark8032b982017-07-28 11:04:54 -04003940# ------------------------------------------------------------------------------
Cary Clark08895c42018-02-01 09:37:32 -05003941#Subtopic Font_Metrics
3942#Line # common glyph dimensions ##
Cary Clark8032b982017-07-28 11:04:54 -04003943
Cary Clarkce101242017-09-01 15:51:02 -04003944Font_Metrics describe dimensions common to the Glyphs in Typeface.
Herb Derbyfcac00f2018-05-01 11:57:56 -04003945The dimensions are computed by Font_Manager from font data and do not take
Cary Clark8032b982017-07-28 11:04:54 -04003946Paint settings other than Text_Size into account.
3947
3948Font dimensions specify the anchor to the left of the glyph at baseline as the origin.
3949X-axis values to the left of the glyph are negative, and to the right of the left glyph edge
3950are positive.
3951Y-axis values above the baseline are negative, and below the baseline are positive.
Ben Wagnere5806492017-11-09 12:08:31 -05003952
Cary Clark8032b982017-07-28 11:04:54 -04003953#Example
3954#Width 512
3955void draw(SkCanvas* canvas) {
3956 SkPaint paint;
3957 paint.setAntiAlias(true);
3958 paint.setTextSize(120);
3959 SkPaint::FontMetrics fm;
3960 SkScalar lineHeight = paint.getFontMetrics(&fm);
3961 SkPoint pt = { 70, 180 };
3962 canvas->drawString("M", pt.fX, pt.fY, paint);
3963 canvas->drawLine(pt.fX, pt.fY, pt.fX, pt.fY + fm.fTop, paint);
3964 SkScalar ascent = pt.fY + fm.fAscent;
3965 canvas->drawLine(pt.fX - 25, ascent, pt.fX - 25, ascent + lineHeight, paint);
3966 canvas->drawLine(pt.fX - 50, pt.fY, pt.fX - 50, pt.fY + fm.fDescent, paint);
3967 canvas->drawLine(pt.fX + 100, pt.fY, pt.fX + 100, pt.fY + fm.fAscent, paint);
3968 canvas->drawLine(pt.fX + 125, pt.fY, pt.fX + 125, pt.fY - fm.fXHeight, paint);
3969 canvas->drawLine(pt.fX + 150, pt.fY, pt.fX + 150, pt.fY - fm.fCapHeight, paint);
3970 canvas->drawLine(pt.fX + 5, pt.fY, pt.fX + 5, pt.fY + fm.fBottom, paint);
3971 SkScalar xmin = pt.fX + fm.fXMin;
3972 canvas->drawLine(xmin, pt.fY + 60, xmin + fm.fMaxCharWidth, pt.fY + 60, paint);
3973 canvas->drawLine(xmin, pt.fY - 145, pt.fX, pt.fY - 145, paint);
3974 canvas->drawLine(pt.fX + fm.fXMax, pt.fY - 160, pt.fX, pt.fY - 160, paint);
3975 SkScalar upos = pt.fY + fm.fUnderlinePosition;
Ben Wagnere5806492017-11-09 12:08:31 -05003976 canvas->drawLine(pt.fX + 25, upos, pt.fX + 160, upos, paint);
3977 SkScalar ut = fm.fUnderlineThickness;
3978 canvas->drawLine(pt.fX + 130, upos + ut, pt.fX + 160, upos + ut, paint);
Cary Clark8032b982017-07-28 11:04:54 -04003979 paint.setTextSize(12);
3980 canvas->drawString("x-min", pt.fX - 50, pt.fY - 148, paint);
3981 canvas->drawString("x-max", pt.fX + 140, pt.fY - 150, paint);
3982 canvas->drawString("max char width", pt.fX + 120, pt.fY + 57, paint);
3983 canvas->drawString("underline position", pt.fX + 30, pt.fY + 22, paint);
3984 canvas->drawString("underline thickness", pt.fX + 162, pt.fY + 13, paint);
3985 canvas->rotate(-90);
3986 canvas->drawString("descent", -pt.fY - 30, pt.fX - 54, paint);
3987 canvas->drawString("line height", -pt.fY, pt.fX - 29, paint);
3988 canvas->drawString("top", -pt.fY + 30, pt.fX - 4, paint);
3989 canvas->drawString("ascent", -pt.fY, pt.fX + 110, paint);
3990 canvas->drawString("x-height", -pt.fY, pt.fX + 135, paint);
3991 canvas->drawString("cap-height", -pt.fY, pt.fX + 160, paint);
3992 canvas->drawString("bottom", -pt.fY - 50, pt.fX + 15, paint);
3993}
3994##
3995
3996#Struct FontMetrics
Cary Clark08895c42018-02-01 09:37:32 -05003997#Line # values computed by Font_Manager using Typeface ##
Cary Clark8032b982017-07-28 11:04:54 -04003998
3999#Code
4000 struct FontMetrics {
4001 enum FontMetricsFlags {
4002 kUnderlineThicknessIsValid_Flag = 1 << 0,
4003 kUnderlinePositionIsValid_Flag = 1 << 1,
4004 kStrikeoutThicknessIsValid_Flag = 1 << 2,
4005 kStrikeoutPositionIsValid_Flag = 1 << 3,
4006 };
4007
4008 uint32_t fFlags;
4009 SkScalar fTop;
4010 SkScalar fAscent;
4011 SkScalar fDescent;
4012 SkScalar fBottom;
4013 SkScalar fLeading;
4014 SkScalar fAvgCharWidth;
4015 SkScalar fMaxCharWidth;
4016 SkScalar fXMin;
4017 SkScalar fXMax;
4018 SkScalar fXHeight;
4019 SkScalar fCapHeight;
4020 SkScalar fUnderlineThickness;
4021 SkScalar fUnderlinePosition;
4022 SkScalar fStrikeoutThickness;
4023 SkScalar fStrikeoutPosition;
4024
4025 bool hasUnderlineThickness(SkScalar* thickness) const;
4026 bool hasUnderlinePosition(SkScalar* position) const;
4027 bool hasStrikeoutThickness(SkScalar* thickness) const;
4028 bool hasStrikeoutPosition(SkScalar* position) const;
4029 };
4030##
4031
Cary Clark154beea2017-10-26 07:58:48 -04004032 FontMetrics is filled out by getFontMetrics. FontMetrics contents reflect the values
4033 computed by Font_Manager using Typeface. Values are set to zero if they are
4034 not available.
Cary Clarke4aa3712017-09-15 02:56:12 -04004035
Cary Clark5538c132018-06-14 12:28:14 -04004036 All vertical values are relative to the baseline, on a y-axis pointing down.
4037 Zero is on the baseline, negative values are above the baseline, and positive
4038 values are below the baseline.
Ben Wagnere5806492017-11-09 12:08:31 -05004039
Cary Clark154beea2017-10-26 07:58:48 -04004040 fUnderlineThickness and fUnderlinePosition have a bit set in fFlags if their values
4041 are valid, since their value may be zero.
Ben Wagnere5806492017-11-09 12:08:31 -05004042
Cary Clark154beea2017-10-26 07:58:48 -04004043 fStrikeoutThickness and fStrikeoutPosition have a bit set in fFlags if their values
4044 are valid, since their value may be zero.
4045
4046 #Enum FontMetricsFlags
Cary Clark682c58d2018-05-16 07:07:07 -04004047 #Line # valid Font_Metrics ##
Cary Clarke4aa3712017-09-15 02:56:12 -04004048
Cary Clark8032b982017-07-28 11:04:54 -04004049 #Code
4050 enum FontMetricsFlags {
4051 kUnderlineThicknessIsValid_Flag = 1 << 0,
4052 kUnderlinePositionIsValid_Flag = 1 << 1,
4053 kStrikeoutThicknessIsValid_Flag = 1 << 2,
4054 kStrikeoutPositionIsValid_Flag = 1 << 3,
4055 };
4056 ##
4057
Cary Clark154beea2017-10-26 07:58:48 -04004058 FontMetricsFlags are set in fFlags when underline and strikeout metrics are valid;
4059 the underline or strikeout metric may be valid and zero.
4060 Fonts with embedded bitmaps may not have valid underline or strikeout metrics.
4061
Cary Clark8032b982017-07-28 11:04:54 -04004062 #Const kUnderlineThicknessIsValid_Flag 0x0001
Cary Clark682c58d2018-05-16 07:07:07 -04004063 #Line # set if fUnderlineThickness is valid ##
Cary Clark8032b982017-07-28 11:04:54 -04004064 ##
4065 #Const kUnderlinePositionIsValid_Flag 0x0002
Cary Clark682c58d2018-05-16 07:07:07 -04004066 #Line # set if fUnderlinePosition is valid ##
Cary Clark8032b982017-07-28 11:04:54 -04004067 ##
4068 #Const kStrikeoutThicknessIsValid_Flag 0x0004
Cary Clark682c58d2018-05-16 07:07:07 -04004069 #Line # set if fStrikeoutThickness is valid ##
Cary Clark8032b982017-07-28 11:04:54 -04004070 ##
4071 #Const kStrikeoutPositionIsValid_Flag 0x0008
Cary Clark682c58d2018-05-16 07:07:07 -04004072 #Line # set if fStrikeoutPosition is valid ##
Cary Clark8032b982017-07-28 11:04:54 -04004073 ##
4074
4075 #Enum ##
4076
4077 #Member uint32_t fFlags
Cary Clark682c58d2018-05-16 07:07:07 -04004078 #Line # is set to FontMetricsFlags when metrics are valid ##
Cary Clark8032b982017-07-28 11:04:54 -04004079 ##
Ben Wagnere5806492017-11-09 12:08:31 -05004080
Cary Clark8032b982017-07-28 11:04:54 -04004081 #Member SkScalar fTop
Cary Clark682c58d2018-05-16 07:07:07 -04004082 #Line # extent above baseline ##
Ben Wagnere5806492017-11-09 12:08:31 -05004083 Greatest extent above the baseline for any glyph.
4084 Typically less than zero.
Cary Clark8032b982017-07-28 11:04:54 -04004085 ##
Ben Wagnere5806492017-11-09 12:08:31 -05004086
Cary Clark8032b982017-07-28 11:04:54 -04004087 #Member SkScalar fAscent
Cary Clark682c58d2018-05-16 07:07:07 -04004088 #Line # distance to reserve above baseline ##
Cary Clark8032b982017-07-28 11:04:54 -04004089 Recommended distance above the baseline to reserve for a line of text.
Ben Wagnere5806492017-11-09 12:08:31 -05004090 Typically less than zero.
Cary Clark8032b982017-07-28 11:04:54 -04004091 ##
Ben Wagnere5806492017-11-09 12:08:31 -05004092
Cary Clark8032b982017-07-28 11:04:54 -04004093 #Member SkScalar fDescent
Cary Clark682c58d2018-05-16 07:07:07 -04004094 #Line # distance to reserve below baseline ##
Cary Clark8032b982017-07-28 11:04:54 -04004095 Recommended distance below the baseline to reserve for a line of text.
Ben Wagnere5806492017-11-09 12:08:31 -05004096 Typically greater than zero.
Cary Clark8032b982017-07-28 11:04:54 -04004097 ##
Ben Wagnere5806492017-11-09 12:08:31 -05004098
Cary Clark8032b982017-07-28 11:04:54 -04004099 #Member SkScalar fBottom
Cary Clark682c58d2018-05-16 07:07:07 -04004100 #Line # extent below baseline ##
Ben Wagnere5806492017-11-09 12:08:31 -05004101 Greatest extent below the baseline for any glyph.
4102 Typically greater than zero.
Cary Clark8032b982017-07-28 11:04:54 -04004103 ##
Ben Wagnere5806492017-11-09 12:08:31 -05004104
Cary Clark8032b982017-07-28 11:04:54 -04004105 #Member SkScalar fLeading
Cary Clark682c58d2018-05-16 07:07:07 -04004106 #Line # distance to add between lines ##
Cary Clark8032b982017-07-28 11:04:54 -04004107 Recommended distance to add between lines of text.
Ben Wagnere5806492017-11-09 12:08:31 -05004108 Typically greater than or equal to zero.
Cary Clark8032b982017-07-28 11:04:54 -04004109 ##
Ben Wagnere5806492017-11-09 12:08:31 -05004110
Cary Clark8032b982017-07-28 11:04:54 -04004111 #Member SkScalar fAvgCharWidth
Cary Clark682c58d2018-05-16 07:07:07 -04004112 #Line # average character width ##
Cary Clark8032b982017-07-28 11:04:54 -04004113 Average character width, if it is available.
4114 Zero if no average width is stored in the font.
4115 ##
Ben Wagnere5806492017-11-09 12:08:31 -05004116
Cary Clark8032b982017-07-28 11:04:54 -04004117 #Member SkScalar fMaxCharWidth
Cary Clark682c58d2018-05-16 07:07:07 -04004118 #Line # maximum character width ##
Cary Clark8032b982017-07-28 11:04:54 -04004119 ##
Ben Wagnere5806492017-11-09 12:08:31 -05004120
Cary Clark8032b982017-07-28 11:04:54 -04004121 #Member SkScalar fXMin
Cary Clark682c58d2018-05-16 07:07:07 -04004122 #Line # minimum x ##
Cary Clark5538c132018-06-14 12:28:14 -04004123 Minimum bounding box x-axis value for all Glyphs.
Cary Clark8032b982017-07-28 11:04:54 -04004124 Typically less than zero.
4125 ##
Ben Wagnere5806492017-11-09 12:08:31 -05004126
Cary Clark8032b982017-07-28 11:04:54 -04004127 #Member SkScalar fXMax
Cary Clark682c58d2018-05-16 07:07:07 -04004128 #Line # maximum x ##
Cary Clark5538c132018-06-14 12:28:14 -04004129 Maximum bounding box x-axis value for all Glyphs.
Cary Clark8032b982017-07-28 11:04:54 -04004130 Typically greater than zero.
4131 ##
Ben Wagnere5806492017-11-09 12:08:31 -05004132
Cary Clark8032b982017-07-28 11:04:54 -04004133 #Member SkScalar fXHeight
Cary Clark682c58d2018-05-16 07:07:07 -04004134 #Line # height of lower-case 'x' ##
Cary Clark8032b982017-07-28 11:04:54 -04004135 May be zero if no lower-case height is stored in the font.
4136 ##
Ben Wagnere5806492017-11-09 12:08:31 -05004137
Cary Clark8032b982017-07-28 11:04:54 -04004138 #Member SkScalar fCapHeight
Cary Clark682c58d2018-05-16 07:07:07 -04004139 #Line # height of an upper-case letter ##
Cary Clark8032b982017-07-28 11:04:54 -04004140 May be zero if no upper-case height is stored in the font.
4141 ##
Ben Wagnere5806492017-11-09 12:08:31 -05004142
Cary Clark8032b982017-07-28 11:04:54 -04004143 #Member SkScalar fUnderlineThickness
Cary Clark682c58d2018-05-16 07:07:07 -04004144 #Line # underline thickness ##
Ben Wagnere5806492017-11-09 12:08:31 -05004145 If the metric is valid, the kUnderlineThicknessIsValid_Flag is set in fFlags.
Cary Clark8032b982017-07-28 11:04:54 -04004146 If kUnderlineThicknessIsValid_Flag is clear, fUnderlineThickness is zero.
4147 ##
Ben Wagnere5806492017-11-09 12:08:31 -05004148
Cary Clark8032b982017-07-28 11:04:54 -04004149 #Member SkScalar fUnderlinePosition
Cary Clark682c58d2018-05-16 07:07:07 -04004150 #Line # underline position relative to baseline ##
Ben Wagnere5806492017-11-09 12:08:31 -05004151 Position of the top of the underline stroke relative to the baseline.
4152 Typically positive when valid.
Cary Clark8032b982017-07-28 11:04:54 -04004153
4154 If the metric is valid, the kUnderlinePositionIsValid_Flag is set in fFlags.
4155 If kUnderlinePositionIsValid_Flag is clear, fUnderlinePosition is zero.
4156 ##
4157
4158 #Member SkScalar fStrikeoutThickness
Cary Clark682c58d2018-05-16 07:07:07 -04004159 #Line # strikeout thickness ##
Ben Wagnere5806492017-11-09 12:08:31 -05004160
4161 If the metric is valid, the kStrikeoutThicknessIsValid_Flag is set in fFlags.
Cary Clark8032b982017-07-28 11:04:54 -04004162 If kStrikeoutThicknessIsValid_Flag is clear, fStrikeoutThickness is zero.
4163 ##
4164
4165 #Member SkScalar fStrikeoutPosition
Cary Clark682c58d2018-05-16 07:07:07 -04004166 #Line # strikeout position relative to baseline ##
Ben Wagnere5806492017-11-09 12:08:31 -05004167 Position of the bottom of the strikeout stroke relative to the baseline.
4168 Typically negative when valid.
Cary Clark8032b982017-07-28 11:04:54 -04004169
Ben Wagnere5806492017-11-09 12:08:31 -05004170 If the metric is valid, the kStrikeoutPositionIsValid_Flag is set in fFlags.
4171 If kStrikeoutPositionIsValid_Flag is clear, fStrikeoutPosition is zero.
Cary Clark8032b982017-07-28 11:04:54 -04004172 ##
4173
4174 #Method bool hasUnderlineThickness(SkScalar* thickness) const
Cary Clark682c58d2018-05-16 07:07:07 -04004175 #Line # returns underline thickness if set ##
Cary Clark8032b982017-07-28 11:04:54 -04004176
Cary Clark80247e52018-07-11 16:18:41 -04004177 Returns true if Font_Metrics has a valid underline thickness, and sets
Cary Clarkce101242017-09-01 15:51:02 -04004178 thickness to that value. If the underline thickness is not valid,
4179 return false, and ignore thickness.
Cary Clark8032b982017-07-28 11:04:54 -04004180
4181 #Param thickness storage for underline width ##
4182
4183 #Return true if font specifies underline width ##
4184
4185 #NoExample
4186 ##
4187 ##
4188
4189 #Method bool hasUnderlinePosition(SkScalar* position) const
Cary Clark682c58d2018-05-16 07:07:07 -04004190 #Line # returns underline position if set ##
Cary Clark8032b982017-07-28 11:04:54 -04004191
Cary Clark80247e52018-07-11 16:18:41 -04004192 Returns true if Font_Metrics has a valid underline position, and sets
Cary Clarkce101242017-09-01 15:51:02 -04004193 position to that value. If the underline position is not valid,
4194 return false, and ignore position.
Cary Clark8032b982017-07-28 11:04:54 -04004195
4196 #Param position storage for underline position ##
4197
4198 #Return true if font specifies underline position ##
4199
4200 #NoExample
4201 ##
4202 ##
4203
4204 #Method bool hasStrikeoutThickness(SkScalar* thickness) const
Cary Clark682c58d2018-05-16 07:07:07 -04004205 #Line # returns strikeout thickness if set ##
Cary Clark8032b982017-07-28 11:04:54 -04004206
Cary Clark80247e52018-07-11 16:18:41 -04004207 Returns true if Font_Metrics has a valid strikeout thickness, and sets
Cary Clarkce101242017-09-01 15:51:02 -04004208 thickness to that value. If the underline thickness is not valid,
4209 return false, and ignore thickness.
Cary Clark8032b982017-07-28 11:04:54 -04004210
4211 #Param thickness storage for strikeout width ##
4212
4213 #Return true if font specifies strikeout width ##
4214
4215 #NoExample
4216 ##
4217 ##
4218
4219 #Method bool hasStrikeoutPosition(SkScalar* position) const
Cary Clark682c58d2018-05-16 07:07:07 -04004220 #Line # returns strikeout position if set ##
Cary Clark8032b982017-07-28 11:04:54 -04004221
Cary Clark80247e52018-07-11 16:18:41 -04004222 Returns true if Font_Metrics has a valid strikeout position, and sets
Cary Clarkce101242017-09-01 15:51:02 -04004223 position to that value. If the underline position is not valid,
4224 return false, and ignore position.
Cary Clark8032b982017-07-28 11:04:54 -04004225
4226 #Param position storage for strikeout position ##
4227
4228 #Return true if font specifies strikeout position ##
4229
4230 #NoExample
4231 ##
4232 ##
4233
4234#Struct ##
4235
4236#Method SkScalar getFontMetrics(FontMetrics* metrics, SkScalar scale = 0) const
4237
Cary Clarkab2621d2018-01-30 10:08:57 -05004238#In Font_Metrics
4239#Line # returns Typeface metrics scaled by text size ##
Cary Clark8032b982017-07-28 11:04:54 -04004240 Returns Font_Metrics associated with Typeface.
4241 The return value is the recommended spacing between lines: the sum of metrics
4242 descent, ascent, and leading.
4243 If metrics is not nullptr, Font_Metrics is copied to metrics.
4244 Results are scaled by Text_Size but does not take into account
4245 dimensions required by Text_Scale_X, Text_Skew_X, Fake_Bold,
4246 Style_Stroke, and Path_Effect.
4247 Results can be additionally scaled by scale; a scale of zero
4248 is ignored.
4249
4250 #Param metrics storage for Font_Metrics from Typeface; may be nullptr ##
4251 #Param scale additional multiplier for returned values ##
4252
4253 #Return recommended spacing between lines ##
4254
4255 #Example
4256 #Height 128
4257 void draw(SkCanvas* canvas) {
4258 SkPaint paint;
4259 paint.setTextSize(32);
4260 SkScalar lineHeight = paint.getFontMetrics(nullptr);
4261 canvas->drawString("line 1", 10, 40, paint);
4262 canvas->drawString("line 2", 10, 40 + lineHeight, paint);
4263 paint.setStyle(SkPaint::kStroke_Style);
4264 paint.setStrokeWidth(10);
4265 lineHeight = paint.getFontMetrics(nullptr, 1.10f); // account for stroke height
4266 canvas->drawString("line 3", 120, 40, paint);
4267 canvas->drawString("line 4", 120, 40 + lineHeight, paint);
4268 }
4269 ##
4270
4271 #SeeAlso Text_Size Typeface Typeface_Methods
4272
4273##
4274
4275
4276#Method SkScalar getFontSpacing() const
4277
Cary Clarkab2621d2018-01-30 10:08:57 -05004278#In Font_Metrics
4279#Line # returns recommended spacing between lines ##
Cary Clark8032b982017-07-28 11:04:54 -04004280 Returns the recommended spacing between lines: the sum of metrics
4281 descent, ascent, and leading.
4282 Result is scaled by Text_Size but does not take into account
4283 dimensions required by stroking and Path_Effect.
Cary Clark579985c2017-07-31 11:48:27 -04004284 Returns the same result as getFontMetrics.
Cary Clark8032b982017-07-28 11:04:54 -04004285
Cary Clark0c5f5462017-12-15 11:21:51 -05004286 #Return recommended spacing between lines ##
Cary Clark8032b982017-07-28 11:04:54 -04004287
4288 #Example
4289 SkPaint paint;
4290 for (SkScalar textSize : { 12, 18, 24, 32 } ) {
4291 paint.setTextSize(textSize);
4292 SkDebugf("textSize: %g fontSpacing: %g\n", textSize, paint.getFontSpacing());
4293 }
4294
4295 #StdOut
4296 textSize: 12 fontSpacing: 13.9688
4297 textSize: 18 fontSpacing: 20.9531
4298 textSize: 24 fontSpacing: 27.9375
4299 textSize: 32 fontSpacing: 37.25
4300 ##
4301 ##
4302
4303##
4304
4305
4306#Method SkRect getFontBounds() const
4307
Cary Clarkab2621d2018-01-30 10:08:57 -05004308#In Font_Metrics
4309#Line # returns union all glyph bounds ##
Cary Clarkce101242017-09-01 15:51:02 -04004310Returns the union of bounds of all Glyphs.
Herb Derbyfcac00f2018-05-01 11:57:56 -04004311Returned dimensions are computed by Font_Manager from font data,
Cary Clark579985c2017-07-31 11:48:27 -04004312ignoring Hinting. Includes Text_Size, Text_Scale_X,
Cary Clark8032b982017-07-28 11:04:54 -04004313and Text_Skew_X, but not Fake_Bold or Path_Effect.
4314
4315If Text_Size is large, Text_Scale_X is one, and Text_Skew_X is zero,
Herb Derbyfcac00f2018-05-01 11:57:56 -04004316returns the same bounds as Font_Metrics { FontMetrics::fXMin,
Cary Clark8032b982017-07-28 11:04:54 -04004317FontMetrics::fTop, FontMetrics::fXMax, FontMetrics::fBottom }.
4318
Cary Clarkce101242017-09-01 15:51:02 -04004319#Return union of bounds of all Glyphs ##
Cary Clark8032b982017-07-28 11:04:54 -04004320
4321#Example
4322 SkPaint paint;
4323 SkPaint::FontMetrics fm;
4324 paint.getFontMetrics(&fm);
4325 SkRect fb = paint.getFontBounds();
4326 SkDebugf("metrics bounds = { %g, %g, %g, %g }\n", fm.fXMin, fm.fTop, fm.fXMax, fm.fBottom );
4327 SkDebugf("font bounds = { %g, %g, %g, %g }\n", fb.fLeft, fb.fTop, fb.fRight, fm.fBottom );
4328
4329 #StdOut
4330 metrics bounds = { -12.2461, -14.7891, 21.5215, 5.55469 }
4331 font bounds = { -12.2461, -14.7891, 21.5215, 5.55469 }
4332 ##
4333##
4334
4335##
4336
Cary Clark08895c42018-02-01 09:37:32 -05004337#Subtopic Font_Metrics ##
Cary Clark8032b982017-07-28 11:04:54 -04004338# ------------------------------------------------------------------------------
4339
4340#Method int textToGlyphs(const void* text, size_t byteLength,
4341 SkGlyphID glyphs[]) const
Cary Clark78de7512018-02-07 07:27:09 -05004342#In Utility
Cary Clarkab2621d2018-01-30 10:08:57 -05004343#Line # converts text into glyph indices ##
Cary Clark8032b982017-07-28 11:04:54 -04004344
4345Converts text into glyph indices.
4346Returns the number of glyph indices represented by text.
4347Text_Encoding specifies how text represents characters or glyphs.
4348glyphs may be nullptr, to compute the glyph count.
4349
Cary Clarkbc5697d2017-10-04 14:31:33 -04004350Does not check text for valid character codes or valid glyph indices.
Cary Clark8032b982017-07-28 11:04:54 -04004351
Cary Clark579985c2017-07-31 11:48:27 -04004352If byteLength equals zero, returns zero.
Cary Clark8032b982017-07-28 11:04:54 -04004353If byteLength includes a partial character, the partial character is ignored.
4354
4355If Text_Encoding is kUTF8_TextEncoding and
4356text contains an invalid UTF-8 sequence, zero is returned.
4357
Cary Clarkce101242017-09-01 15:51:02 -04004358#Param text character storage encoded with Text_Encoding ##
Cary Clark8032b982017-07-28 11:04:54 -04004359#Param byteLength length of character storage in bytes ##
4360#Param glyphs storage for glyph indices; may be nullptr ##
4361
4362#Return number of glyphs represented by text of length byteLength ##
4363
4364 #Example
4365 #Height 64
4366 void draw(SkCanvas* canvas) {
4367 SkPaint paint;
4368 const uint8_t utf8[] = { 0x24, 0xC2, 0xA2, 0xE2, 0x82, 0xAC, 0xC2, 0xA5, 0xC2, 0xA3 };
4369 std::vector<SkGlyphID> glyphs;
4370 int count = paint.textToGlyphs(utf8, sizeof(utf8), nullptr);
4371 glyphs.resize(count);
4372 (void) paint.textToGlyphs(utf8, sizeof(utf8), &glyphs.front());
4373 paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
4374 paint.setTextSize(32);
4375 canvas->drawText(&glyphs.front(), glyphs.size() * sizeof(SkGlyphID), 10, 40, paint);
4376 }
4377 ##
4378
4379##
4380
4381#Method int countText(const void* text, size_t byteLength) const
Cary Clark78de7512018-02-07 07:27:09 -05004382#In Utility
Cary Clarkab2621d2018-01-30 10:08:57 -05004383#Line # returns number of Glyphs in text ##
Cary Clarkce101242017-09-01 15:51:02 -04004384 Returns the number of Glyphs in text.
4385 Uses Text_Encoding to count the Glyphs.
Cary Clark8032b982017-07-28 11:04:54 -04004386 Returns the same result as textToGlyphs.
4387
Cary Clarkce101242017-09-01 15:51:02 -04004388#Param text character storage encoded with Text_Encoding ##
Cary Clark8032b982017-07-28 11:04:54 -04004389#Param byteLength length of character storage in bytes ##
4390
Cary Clarkce101242017-09-01 15:51:02 -04004391#Return number of Glyphs represented by text of length byteLength ##
Cary Clark8032b982017-07-28 11:04:54 -04004392
4393 #Example
4394 SkPaint paint;
4395 const uint8_t utf8[] = { 0x24, 0xC2, 0xA2, 0xE2, 0x82, 0xAC, 0xC2, 0xA5, 0xC2, 0xA3 };
4396 SkDebugf("count = %d\n", paint.countText(utf8, sizeof(utf8)));
4397
4398 #StdOut
4399 count = 5
4400 ##
4401 ##
4402##
4403
4404# ------------------------------------------------------------------------------
4405
4406#Method bool containsText(const void* text, size_t byteLength) const
Cary Clark78de7512018-02-07 07:27:09 -05004407#In Utility
Cary Clarkab2621d2018-01-30 10:08:57 -05004408#Line # returns if all text corresponds to Glyphs ##
Herb Derbyfcac00f2018-05-01 11:57:56 -04004409 Returns true if all text corresponds to a non-zero glyph index.
Cary Clark8032b982017-07-28 11:04:54 -04004410 Returns false if any characters in text are not supported in
4411 Typeface.
4412
Cary Clark579985c2017-07-31 11:48:27 -04004413 If Text_Encoding is kGlyphID_TextEncoding,
4414 returns true if all glyph indices in text are non-zero;
Cary Clark8032b982017-07-28 11:04:54 -04004415 does not check to see if text contains valid glyph indices for Typeface.
4416
Cary Clarkce101242017-09-01 15:51:02 -04004417 Returns true if byteLength is zero.
Cary Clark8032b982017-07-28 11:04:54 -04004418
Cary Clarkce101242017-09-01 15:51:02 -04004419 #Param text array of characters or Glyphs ##
Cary Clark8032b982017-07-28 11:04:54 -04004420 #Param byteLength number of bytes in text array ##
4421
4422 #Return true if all text corresponds to a non-zero glyph index ##
4423
Ruiqi Mao94d57c42018-07-02 15:20:10 -04004424 #NoExample
Cary Clark8032b982017-07-28 11:04:54 -04004425 #Description
4426 containsText succeeds for degree symbol, but cannot find a glyph index
4427 corresponding to the Unicode surrogate code point.
4428 ##
4429 SkPaint paint;
4430 const uint16_t goodChar = 0x00B0; // degree symbol
4431 const uint16_t badChar = 0xD800; // Unicode surrogate
4432 paint.setTextEncoding(SkPaint::kUTF16_TextEncoding);
Herb Derbyfcac00f2018-05-01 11:57:56 -04004433 SkDebugf("0x%04x %c= has char\n", goodChar,
Cary Clark8032b982017-07-28 11:04:54 -04004434 paint.containsText(&goodChar, 2) ? '=' : '!');
4435 SkDebugf("0x%04x %c= has char\n", badChar,
4436 paint.containsText(&badChar, 2) ? '=' : '!');
4437
4438 #StdOut
4439 0x00b0 == has char
4440 0xd800 != has char
4441 ##
4442 ##
4443
4444 #Example
4445 #Description
4446 containsText returns true that glyph index is greater than zero, not
4447 that it corresponds to an entry in Typeface.
4448 ##
4449 SkPaint paint;
4450 const uint16_t goodGlyph = 511;
4451 const uint16_t zeroGlyph = 0;
4452 const uint16_t badGlyph = 65535; // larger than glyph count in font
4453 paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
Herb Derbyfcac00f2018-05-01 11:57:56 -04004454 SkDebugf("0x%04x %c= has glyph\n", goodGlyph,
Cary Clark8032b982017-07-28 11:04:54 -04004455 paint.containsText(&goodGlyph, 2) ? '=' : '!');
4456 SkDebugf("0x%04x %c= has glyph\n", zeroGlyph,
4457 paint.containsText(&zeroGlyph, 2) ? '=' : '!');
4458 SkDebugf("0x%04x %c= has glyph\n", badGlyph,
4459 paint.containsText(&badGlyph, 2) ? '=' : '!');
4460
4461 #StdOut
4462 0x01ff == has glyph
4463 0x0000 != has glyph
4464 0xffff == has glyph
4465 ##
4466 ##
4467
4468#SeeAlso setTextEncoding Typeface
4469
4470##
4471
4472# ------------------------------------------------------------------------------
4473
4474#Method void glyphsToUnichars(const SkGlyphID glyphs[],
4475 int count, SkUnichar text[]) const
Cary Clark78de7512018-02-07 07:27:09 -05004476#In Utility
Cary Clarkab2621d2018-01-30 10:08:57 -05004477#Line # converts Glyphs into text ##
Cary Clark8032b982017-07-28 11:04:54 -04004478
Herb Derbyfcac00f2018-05-01 11:57:56 -04004479 Converts glyphs into text if possible.
4480 Glyph values without direct Unicode equivalents are mapped to zero.
Cary Clark8032b982017-07-28 11:04:54 -04004481 Uses the Typeface, but is unaffected
4482 by Text_Encoding; the text values returned are equivalent to kUTF32_TextEncoding.
4483
4484 Only supported on platforms that use FreeType as the Font_Engine.
4485
4486 #Param glyphs array of indices into font ##
4487 #Param count length of glyph array ##
4488 #Param text storage for character codes, one per glyph ##
4489
4490 #Example
4491 #Height 64
4492 #Description
4493 Convert UTF-8 text to glyphs; then convert glyphs to Unichar code points.
4494 ##
4495 void draw(SkCanvas* canvas) {
4496 SkPaint paint;
4497 const char hello[] = "Hello!";
4498 const int count = sizeof(hello) - 1;
4499 SkGlyphID glyphs[count];
4500 if (count != paint.textToGlyphs(hello, count, glyphs)) {
4501 return;
4502 }
4503 SkUnichar unichars[count];
4504 paint.glyphsToUnichars(glyphs, count, unichars);
4505 paint.setTextEncoding(SkPaint::kUTF32_TextEncoding);
4506 canvas->drawText(unichars, sizeof(unichars), 10, 30, paint);
4507 }
4508 ##
4509
4510##
4511
4512# ------------------------------------------------------------------------------
Cary Clark08895c42018-02-01 09:37:32 -05004513#Subtopic Measure_Text
4514#Line # width, height, bounds of text ##
Cary Clark8032b982017-07-28 11:04:54 -04004515
4516#Method SkScalar measureText(const void* text, size_t length, SkRect* bounds) const
4517
Cary Clarkab2621d2018-01-30 10:08:57 -05004518#In Measure_Text
4519#Line # returns advance width and bounds of text ##
Cary Clark8032b982017-07-28 11:04:54 -04004520 Returns the advance width of text if kVerticalText_Flag is clear,
4521 and the height of text if kVerticalText_Flag is set.
4522 The advance is the normal distance to move before drawing additional text.
4523 Uses Text_Encoding to decode text, Typeface to get the font metrics,
4524 and Text_Size, Text_Scale_X, Text_Skew_X, Stroke_Width, and
4525 Path_Effect to scale the metrics and bounds.
4526 Returns the bounding box of text if bounds is not nullptr.
4527 The bounding box is computed as if the text was drawn at the origin.
Herb Derbyfcac00f2018-05-01 11:57:56 -04004528
Cary Clark8032b982017-07-28 11:04:54 -04004529 #Param text character codes or glyph indices to be measured ##
4530 #Param length number of bytes of text to measure ##
4531 #Param bounds returns bounding box relative to (0, 0) if not nullptr ##
4532
4533 #Return advance width or height ##
4534
4535 #Example
4536 #Height 64
4537 void draw(SkCanvas* canvas) {
4538 SkPaint paint;
4539 paint.setAntiAlias(true);
4540 paint.setTextSize(50);
4541 const char str[] = "ay^jZ";
4542 const int count = sizeof(str) - 1;
4543 canvas->drawText(str, count, 25, 50, paint);
4544 SkRect bounds;
4545 paint.measureText(str, count, &bounds);
4546 canvas->translate(25, 50);
4547 paint.setStyle(SkPaint::kStroke_Style);
4548 canvas->drawRect(bounds, paint);
4549 }
4550 ##
4551
4552##
4553
4554#Method SkScalar measureText(const void* text, size_t length) const
4555
Cary Clarkab2621d2018-01-30 10:08:57 -05004556#In Measure_Text
Cary Clark8032b982017-07-28 11:04:54 -04004557 Returns the advance width of text if kVerticalText_Flag is clear,
4558 and the height of text if kVerticalText_Flag is set.
4559 The advance is the normal distance to move before drawing additional text.
4560 Uses Text_Encoding to decode text, Typeface to get the font metrics,
4561 and Text_Size to scale the metrics.
4562 Does not scale the advance or bounds by Fake_Bold or Path_Effect.
4563
4564 #Param text character codes or glyph indices to be measured ##
4565 #Param length number of bytes of text to measure ##
4566
4567 #Return advance width or height ##
4568
4569 #Example
4570 SkPaint paint;
4571 SkDebugf("default width = %g\n", paint.measureText("!", 1));
4572 paint.setTextSize(paint.getTextSize() * 2);
4573 SkDebugf("double width = %g\n", paint.measureText("!", 1));
4574
4575 #StdOut
4576 default width = 5
4577 double width = 10
4578 ##
4579 ##
4580
4581##
4582
4583#Method size_t breakText(const void* text, size_t length, SkScalar maxWidth,
Cary Clark73fa9722017-08-29 17:36:51 -04004584 SkScalar* measuredWidth = nullptr) const
Cary Clarkab2621d2018-01-30 10:08:57 -05004585#In Measure_Text
4586#Line # returns text that fits in a width ##
Cary Clark8032b982017-07-28 11:04:54 -04004587
4588 Returns the bytes of text that fit within maxWidth.
4589 If kVerticalText_Flag is clear, the text fragment fits if its advance width is less than or
4590 equal to maxWidth.
4591 If kVerticalText_Flag is set, the text fragment fits if its advance height is less than or
4592 equal to maxWidth.
4593 Measures only while the advance is less than or equal to maxWidth.
4594 Returns the advance or the text fragment in measuredWidth if it not nullptr.
4595 Uses Text_Encoding to decode text, Typeface to get the font metrics,
4596 and Text_Size to scale the metrics.
4597 Does not scale the advance or bounds by Fake_Bold or Path_Effect.
4598
4599 #Param text character codes or glyph indices to be measured ##
4600 #Param length number of bytes of text to measure ##
4601 #Param maxWidth advance limit; text is measured while advance is less than maxWidth ##
4602 #Param measuredWidth returns the width of the text less than or equal to maxWidth ##
4603 #Return bytes of text that fit, always less than or equal to length ##
Herb Derbyfcac00f2018-05-01 11:57:56 -04004604
Cary Clark8032b982017-07-28 11:04:54 -04004605 #Example
4606 #Description
4607 Line under "Breakfast" shows desired width, shorter than available characters.
4608 Line under "Bre" shows measured width after breaking text.
4609 ##
4610 #Height 128
4611 #Width 280
4612 void draw(SkCanvas* canvas) {
4613 SkPaint paint;
4614 paint.setAntiAlias(true);
4615 paint.setTextSize(50);
4616 const char str[] = "Breakfast";
4617 const int count = sizeof(str) - 1;
4618 canvas->drawText(str, count, 25, 50, paint);
4619 SkScalar measuredWidth;
4620 int partialBytes = paint.breakText(str, count, 100, &measuredWidth);
4621 canvas->drawText(str, partialBytes, 25, 100, paint);
4622 canvas->drawLine(25, 60, 25 + 100, 60, paint);
4623 canvas->drawLine(25, 110, 25 + measuredWidth, 110, paint);
4624 }
4625 ##
4626
4627##
4628
4629#Method int getTextWidths(const void* text, size_t byteLength, SkScalar widths[],
Cary Clark73fa9722017-08-29 17:36:51 -04004630 SkRect bounds[] = nullptr) const
Cary Clarkab2621d2018-01-30 10:08:57 -05004631#In Measure_Text
4632#Line # returns advance and bounds for each glyph in text ##
Cary Clark8032b982017-07-28 11:04:54 -04004633
4634 Retrieves the advance and bounds for each glyph in text, and returns
4635 the glyph count in text.
4636 Both widths and bounds may be nullptr.
4637 If widths is not nullptr, widths must be an array of glyph count entries.
Herb Derbyfcac00f2018-05-01 11:57:56 -04004638 if bounds is not nullptr, bounds must be an array of glyph count entries.
Cary Clark8032b982017-07-28 11:04:54 -04004639 If kVerticalText_Flag is clear, widths returns the horizontal advance.
4640 If kVerticalText_Flag is set, widths returns the vertical advance.
4641 Uses Text_Encoding to decode text, Typeface to get the font metrics,
4642 and Text_Size to scale the widths and bounds.
4643 Does not scale the advance by Fake_Bold or Path_Effect.
4644 Does include Fake_Bold and Path_Effect in the bounds.
Herb Derbyfcac00f2018-05-01 11:57:56 -04004645
Cary Clark8032b982017-07-28 11:04:54 -04004646 #Param text character codes or glyph indices to be measured ##
4647 #Param byteLength number of bytes of text to measure ##
4648 #Param widths returns text advances for each glyph; may be nullptr ##
4649 #Param bounds returns bounds for each glyph relative to (0, 0); may be nullptr ##
Herb Derbyfcac00f2018-05-01 11:57:56 -04004650
Cary Clark8032b982017-07-28 11:04:54 -04004651 #Return glyph count in text ##
4652
4653 #Example
4654 #Height 160
4655 #Description
Cary Clarkce101242017-09-01 15:51:02 -04004656 Bounds of Glyphs increase for stroked text, but text advance remains the same.
Cary Clark8032b982017-07-28 11:04:54 -04004657 The underlines show the text advance, spaced to keep them distinct.
4658 ##
4659 void draw(SkCanvas* canvas) {
4660 SkPaint paint;
4661 paint.setAntiAlias(true);
4662 paint.setTextSize(50);
4663 const char str[] = "abc";
4664 const int bytes = sizeof(str) - 1;
4665 int count = paint.getTextWidths(str, bytes, nullptr);
4666 std::vector<SkScalar> widths;
4667 std::vector<SkRect> bounds;
4668 widths.resize(count);
4669 bounds.resize(count);
4670 for (int loop = 0; loop < 2; ++loop) {
4671 (void) paint.getTextWidths(str, count, &widths.front(), &bounds.front());
4672 SkPoint loc = { 25, 50 };
4673 canvas->drawText(str, bytes, loc.fX, loc.fY, paint);
4674 paint.setStyle(SkPaint::kStroke_Style);
4675 paint.setStrokeWidth(0);
4676 SkScalar advanceY = loc.fY + 10;
4677 for (int index = 0; index < count; ++index) {
4678 bounds[index].offset(loc.fX, loc.fY);
4679 canvas->drawRect(bounds[index], paint);
4680 canvas->drawLine(loc.fX, advanceY, loc.fX + widths[index], advanceY, paint);
4681 loc.fX += widths[index];
4682 advanceY += 5;
4683 }
4684 canvas->translate(0, 80);
4685 paint.setStrokeWidth(3);
4686 }
4687 }
4688 ##
4689
4690##
4691
Cary Clark08895c42018-02-01 09:37:32 -05004692#Subtopic Measure_Text ##
Cary Clark8032b982017-07-28 11:04:54 -04004693# ------------------------------------------------------------------------------
Cary Clark08895c42018-02-01 09:37:32 -05004694#Subtopic Text_Path
4695#Line # geometry of Glyphs ##
Cary Clark8032b982017-07-28 11:04:54 -04004696
Cary Clarkce101242017-09-01 15:51:02 -04004697Text_Path describes the geometry of Glyphs used to draw text.
Cary Clark8032b982017-07-28 11:04:54 -04004698
4699#Method void getTextPath(const void* text, size_t length, SkScalar x, SkScalar y,
4700 SkPath* path) const
Cary Clarkab2621d2018-01-30 10:08:57 -05004701#In Text_Path
4702#Line # returns Path equivalent to text ##
Cary Clark8032b982017-07-28 11:04:54 -04004703
4704Returns the geometry as Path equivalent to the drawn text.
4705Uses Text_Encoding to decode text, Typeface to get the glyph paths,
4706and Text_Size, Fake_Bold, and Path_Effect to scale and modify the glyph paths.
4707All of the glyph paths are stored in path.
Cary Clark579985c2017-07-31 11:48:27 -04004708Uses x, y, and Text_Align to position path.
Cary Clark8032b982017-07-28 11:04:54 -04004709
4710 #Param text character codes or glyph indices ##
4711 #Param length number of bytes of text ##
Cary Clark5538c132018-06-14 12:28:14 -04004712 #Param x x-axis value of the origin of the text ##
4713 #Param y y-axis value of the origin of the text ##
Cary Clarkce101242017-09-01 15:51:02 -04004714 #Param path geometry of the Glyphs ##
Cary Clark8032b982017-07-28 11:04:54 -04004715
4716 #Example
4717 #Description
4718 Text is added to Path, offset, and subtracted from Path, then added at
4719 the offset location. The result is rendered with one draw call.
4720 ##
4721 #Height 128
4722 void draw(SkCanvas* canvas) {
4723 SkPaint paint;
4724 paint.setTextSize(80);
4725 SkPath path, path2;
4726 paint.getTextPath("ABC", 3, 20, 80, &path);
4727 path.offset(20, 20, &path2);
4728 Op(path, path2, SkPathOp::kDifference_SkPathOp, &path);
4729 path.addPath(path2);
4730 paint.setStyle(SkPaint::kStroke_Style);
4731 canvas->drawPath(path, paint);
4732 }
4733 ##
4734
4735##
4736
4737#Method void getPosTextPath(const void* text, size_t length,
4738 const SkPoint pos[], SkPath* path) const
Cary Clarkab2621d2018-01-30 10:08:57 -05004739#In Text_Path
4740#Line # returns Path equivalent to positioned text ##
Cary Clark8032b982017-07-28 11:04:54 -04004741
4742Returns the geometry as Path equivalent to the drawn text.
4743Uses Text_Encoding to decode text, Typeface to get the glyph paths,
4744and Text_Size, Fake_Bold, and Path_Effect to scale and modify the glyph paths.
4745All of the glyph paths are stored in path.
4746Uses pos array and Text_Align to position path.
4747pos contains a position for each glyph.
4748
4749 #Param text character codes or glyph indices ##
4750 #Param length number of bytes of text ##
4751 #Param pos positions of each glyph ##
Cary Clarkce101242017-09-01 15:51:02 -04004752 #Param path geometry of the Glyphs ##
Cary Clark8032b982017-07-28 11:04:54 -04004753
4754 #Example
4755 #Height 85
4756 #Description
Cary Clarkce101242017-09-01 15:51:02 -04004757 Simplifies three Glyphs to eliminate overlaps, and strokes the result.
Cary Clark8032b982017-07-28 11:04:54 -04004758 ##
4759 void draw(SkCanvas* canvas) {
4760 SkPaint paint;
4761 paint.setTextSize(80);
4762 SkPath path, path2;
4763 SkPoint pos[] = {{20, 60}, {30, 70}, {40, 80}};
4764 paint.getPosTextPath("ABC", 3, pos, &path);
4765 Simplify(path, &path);
4766 paint.setStyle(SkPaint::kStroke_Style);
4767 canvas->drawPath(path, paint);
4768 }
4769 ##
4770
4771##
4772
Cary Clark08895c42018-02-01 09:37:32 -05004773#Subtopic Text_Path ##
Cary Clark8032b982017-07-28 11:04:54 -04004774# ------------------------------------------------------------------------------
Cary Clark08895c42018-02-01 09:37:32 -05004775#Subtopic Text_Intercepts
4776#Line # advanced underline, strike through ##
Cary Clark8032b982017-07-28 11:04:54 -04004777
Cary Clarkce101242017-09-01 15:51:02 -04004778Text_Intercepts describe the intersection of drawn text Glyphs with a pair
Cary Clark8032b982017-07-28 11:04:54 -04004779of lines parallel to the text advance. Text_Intercepts permits creating a
Cary Clarkce101242017-09-01 15:51:02 -04004780underline that skips Descenders.
Cary Clark8032b982017-07-28 11:04:54 -04004781
4782#Method int getTextIntercepts(const void* text, size_t length, SkScalar x, SkScalar y,
4783 const SkScalar bounds[2], SkScalar* intervals) const
Cary Clarkab2621d2018-01-30 10:08:57 -05004784#In Text_Intercepts
4785#Line # returns where lines intersect text; underlines ##
Cary Clark8032b982017-07-28 11:04:54 -04004786
4787 Returns the number of intervals that intersect bounds.
4788 bounds describes a pair of lines parallel to the text advance.
Cary Clarkce101242017-09-01 15:51:02 -04004789 The return count is zero or a multiple of two, and is at most twice the number of Glyphs in
Herb Derbyfcac00f2018-05-01 11:57:56 -04004790 the string.
Cary Clark8032b982017-07-28 11:04:54 -04004791 Uses Text_Encoding to decode text, Typeface to get the glyph paths,
4792 and Text_Size, Fake_Bold, and Path_Effect to scale and modify the glyph paths.
4793 Uses x, y, and Text_Align to position intervals.
Herb Derbyfcac00f2018-05-01 11:57:56 -04004794
Cary Clark8032b982017-07-28 11:04:54 -04004795 Pass nullptr for intervals to determine the size of the interval array.
Herb Derbyfcac00f2018-05-01 11:57:56 -04004796
Cary Clark8032b982017-07-28 11:04:54 -04004797 intervals are cached to improve performance for multiple calls.
4798
4799 #Param text character codes or glyph indices ##
4800 #Param length number of bytes of text ##
Cary Clark5538c132018-06-14 12:28:14 -04004801 #Param x x-axis value of the origin of the text ##
4802 #Param y y-axis value of the origin of the text ##
Cary Clark8032b982017-07-28 11:04:54 -04004803 #Param bounds lower and upper line parallel to the advance ##
4804 #Param intervals returned intersections; may be nullptr ##
4805
4806 #Return number of intersections; may be zero ##
4807
4808#Example
4809#Height 128
4810#Description
Cary Clarkce101242017-09-01 15:51:02 -04004811Underline uses intercepts to draw on either side of the glyph Descender.
Cary Clark8032b982017-07-28 11:04:54 -04004812##
4813void draw(SkCanvas* canvas) {
4814 SkPaint paint;
4815 paint.setTextSize(120);
4816 SkPoint textOrigin = { 20, 100 };
4817 SkScalar bounds[] = { 100, 108 };
4818 int count = paint.getTextIntercepts("y", 1, textOrigin.fX, textOrigin.fY, bounds, nullptr);
4819 std::vector<SkScalar> intervals;
4820 intervals.resize(count);
4821 (void) paint.getTextIntercepts("y", 1, textOrigin.fX, textOrigin.fY, bounds,
4822 &intervals.front());
4823 canvas->drawString("y", textOrigin.fX, textOrigin.fY, paint);
4824 paint.setColor(SK_ColorRED);
4825 SkScalar x = textOrigin.fX;
4826 for (int i = 0; i < count; i += 2) {
4827 canvas->drawRect({x, bounds[0], intervals[i], bounds[1]}, paint);
4828 x = intervals[i + 1];
4829 }
4830 canvas->drawRect({intervals[count - 1], bounds[0],
4831 textOrigin.fX + paint.measureText("y", 1), bounds[1]}, paint);
4832}
4833##
4834
4835##
4836
4837#Method int getPosTextIntercepts(const void* text, size_t length, const SkPoint pos[],
4838 const SkScalar bounds[2], SkScalar* intervals) const
Cary Clarkab2621d2018-01-30 10:08:57 -05004839#In Text_Intercepts
4840#Line # returns where lines intersect positioned text; underlines ##
Cary Clark8032b982017-07-28 11:04:54 -04004841
4842 Returns the number of intervals that intersect bounds.
4843 bounds describes a pair of lines parallel to the text advance.
Cary Clarkce101242017-09-01 15:51:02 -04004844 The return count is zero or a multiple of two, and is at most twice the number of Glyphs in
Herb Derbyfcac00f2018-05-01 11:57:56 -04004845 the string.
Cary Clark8032b982017-07-28 11:04:54 -04004846 Uses Text_Encoding to decode text, Typeface to get the glyph paths,
4847 and Text_Size, Fake_Bold, and Path_Effect to scale and modify the glyph paths.
4848 Uses pos array and Text_Align to position intervals.
Herb Derbyfcac00f2018-05-01 11:57:56 -04004849
Cary Clark8032b982017-07-28 11:04:54 -04004850 Pass nullptr for intervals to determine the size of the interval array.
Herb Derbyfcac00f2018-05-01 11:57:56 -04004851
Cary Clark8032b982017-07-28 11:04:54 -04004852 intervals are cached to improve performance for multiple calls.
4853
4854 #Param text character codes or glyph indices ##
4855 #Param length number of bytes of text ##
4856 #Param pos positions of each glyph ##
4857 #Param bounds lower and upper line parallel to the advance ##
4858 #Param intervals returned intersections; may be nullptr ##
4859
Cary Clarka523d2d2017-08-30 08:58:10 -04004860 #Return number of intersections; may be zero ##
Cary Clark8032b982017-07-28 11:04:54 -04004861
4862 #Example
4863 #Description
Cary Clarkce101242017-09-01 15:51:02 -04004864 Text intercepts draw on either side of, but not inside, Glyphs in a run.
Cary Clark8032b982017-07-28 11:04:54 -04004865 ##
4866 void draw(SkCanvas* canvas) {
4867 SkPaint paint;
4868 paint.setTextSize(120);
4869 paint.setVerticalText(true);
4870 SkPoint textPos[] = {{ 60, 40 }, { 60, 140 }};
4871 SkScalar bounds[] = { 56, 64 };
4872 const char str[] = "A-";
4873 int len = sizeof(str) - 1;
4874 int count = paint.getPosTextIntercepts(str, len, textPos, bounds, nullptr);
4875 std::vector<SkScalar> intervals;
4876 intervals.resize(count);
4877 (void) paint.getPosTextIntercepts(str, len, textPos, bounds, &intervals.front());
4878 canvas->drawPosText(str, len, textPos, paint);
4879 paint.setColor(SK_ColorRED);
4880 SkScalar y = textPos[0].fY;
4881 for (int i = 0; i < count; i+= 2) {
4882 canvas->drawRect({bounds[0], y, bounds[1], intervals[i]}, paint);
4883 y = intervals[i + 1];
4884 }
4885 canvas->drawRect({bounds[0], intervals[count - 1], bounds[1], 240}, paint);
4886 }
4887 ##
4888
4889##
4890
4891#Method int getPosTextHIntercepts(const void* text, size_t length, const SkScalar xpos[],
4892 SkScalar constY, const SkScalar bounds[2],
4893 SkScalar* intervals) const
Cary Clarkab2621d2018-01-30 10:08:57 -05004894#In Text_Intercepts
4895#Line # returns where lines intersect horizontally positioned text; underlines ##
Cary Clark8032b982017-07-28 11:04:54 -04004896
4897 Returns the number of intervals that intersect bounds.
4898 bounds describes a pair of lines parallel to the text advance.
Cary Clarkce101242017-09-01 15:51:02 -04004899 The return count is zero or a multiple of two, and is at most twice the number of Glyphs in
Herb Derbyfcac00f2018-05-01 11:57:56 -04004900 the string.
Cary Clark8032b982017-07-28 11:04:54 -04004901 Uses Text_Encoding to decode text, Typeface to get the glyph paths,
4902 and Text_Size, Fake_Bold, and Path_Effect to scale and modify the glyph paths.
4903 Uses xpos array, constY, and Text_Align to position intervals.
Herb Derbyfcac00f2018-05-01 11:57:56 -04004904
Cary Clark8032b982017-07-28 11:04:54 -04004905 Pass nullptr for intervals to determine the size of the interval array.
Herb Derbyfcac00f2018-05-01 11:57:56 -04004906
Cary Clark8032b982017-07-28 11:04:54 -04004907 intervals are cached to improve performance for multiple calls.
4908
4909 #Param text character codes or glyph indices ##
4910 #Param length number of bytes of text ##
4911 #Param xpos positions of each glyph in x ##
4912 #Param constY position of each glyph in y ##
4913 #Param bounds lower and upper line parallel to the advance ##
4914 #Param intervals returned intersections; may be nullptr ##
4915
4916 #Return number of intersections; may be zero ##
4917
4918 #Example
4919 #Height 128
4920 #Description
4921 Text intercepts do not take stroke thickness into consideration.
4922 ##
4923 void draw(SkCanvas* canvas) {
4924 SkPaint paint;
4925 paint.setTextSize(120);
4926 paint.setStyle(SkPaint::kStroke_Style);
4927 paint.setStrokeWidth(4);
4928 SkScalar textPosH[] = { 20, 80, 140 };
4929 SkScalar y = 100;
4930 SkScalar bounds[] = { 56, 78 };
4931 const char str[] = "\\-/";
4932 int len = sizeof(str) - 1;
4933 int count = paint.getPosTextHIntercepts(str, len, textPosH, y, bounds, nullptr);
4934 std::vector<SkScalar> intervals;
4935 intervals.resize(count);
4936 (void) paint.getPosTextHIntercepts(str, len, textPosH, y, bounds, &intervals.front());
4937 canvas->drawPosTextH(str, len, textPosH, y, paint);
4938 paint.setColor(0xFFFF7777);
4939 paint.setStyle(SkPaint::kFill_Style);
4940 SkScalar x = textPosH[0];
4941 for (int i = 0; i < count; i+= 2) {
4942 canvas->drawRect({x, bounds[0], intervals[i], bounds[1]}, paint);
4943 x = intervals[i + 1];
4944 }
4945 canvas->drawRect({intervals[count - 1], bounds[0], 180, bounds[1]}, paint);
4946 }
4947 ##
4948
4949##
4950
4951
4952#Method int getTextBlobIntercepts(const SkTextBlob* blob, const SkScalar bounds[2],
4953 SkScalar* intervals) const
Cary Clarkab2621d2018-01-30 10:08:57 -05004954#In Text_Intercepts
4955#Line # returns where lines intersect Text_Blob; underlines ##
Cary Clark8032b982017-07-28 11:04:54 -04004956
4957 Returns the number of intervals that intersect bounds.
4958 bounds describes a pair of lines parallel to the text advance.
Cary Clarkce101242017-09-01 15:51:02 -04004959 The return count is zero or a multiple of two, and is at most twice the number of Glyphs in
Herb Derbyfcac00f2018-05-01 11:57:56 -04004960 the string.
Cary Clark3cd22cc2017-12-01 11:49:58 -05004961 Uses Typeface to get the glyph paths,
Cary Clark8032b982017-07-28 11:04:54 -04004962 and Text_Size, Fake_Bold, and Path_Effect to scale and modify the glyph paths.
Cary Clarkce101242017-09-01 15:51:02 -04004963 Uses run array and Text_Align to position intervals.
Herb Derbyfcac00f2018-05-01 11:57:56 -04004964
Cary Clark3cd22cc2017-12-01 11:49:58 -05004965 Text_Encoding must be set to SkPaint::kGlyphID_TextEncoding.
4966
Cary Clark8032b982017-07-28 11:04:54 -04004967 Pass nullptr for intervals to determine the size of the interval array.
Herb Derbyfcac00f2018-05-01 11:57:56 -04004968
Cary Clark8032b982017-07-28 11:04:54 -04004969 intervals are cached to improve performance for multiple calls.
4970
Cary Clarkce101242017-09-01 15:51:02 -04004971 #Param blob Glyphs, positions, and text paint attributes ##
Cary Clark8032b982017-07-28 11:04:54 -04004972 #Param bounds lower and upper line parallel to the advance ##
4973 #Param intervals returned intersections; may be nullptr ##
4974
4975 #Return number of intersections; may be zero ##
4976
4977 #Example
4978 #Height 143
4979 void draw(SkCanvas* canvas) {
4980 SkPaint paint;
Cary Clark3cd22cc2017-12-01 11:49:58 -05004981 paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
Cary Clark8032b982017-07-28 11:04:54 -04004982 paint.setTextSize(120);
4983 SkPoint textPos = { 20, 110 };
4984 int len = 3;
4985 SkTextBlobBuilder textBlobBuilder;
Herb Derbyfcac00f2018-05-01 11:57:56 -04004986 const SkTextBlobBuilder::RunBuffer& run =
Cary Clark8032b982017-07-28 11:04:54 -04004987 textBlobBuilder.allocRun(paint, len, textPos.fX, textPos.fY);
4988 run.glyphs[0] = 10;
4989 run.glyphs[1] = 20;
Herb Derbyfcac00f2018-05-01 11:57:56 -04004990 run.glyphs[2] = 30;
Cary Clark8032b982017-07-28 11:04:54 -04004991 sk_sp<const SkTextBlob> blob = textBlobBuilder.make();
4992 canvas->drawTextBlob(blob.get(), textPos.fX, textPos.fY, paint);
4993 SkScalar bounds[] = { 116, 134 };
4994 int count = paint.getTextBlobIntercepts(blob.get(), bounds, nullptr);
4995 std::vector<SkScalar> intervals;
4996 intervals.resize(count);
4997 (void) paint.getTextBlobIntercepts(blob.get(), bounds, &intervals.front());
4998 canvas->drawTextBlob(blob.get(), 0, 0, paint);
4999 paint.setColor(0xFFFF7777);
5000 SkScalar x = textPos.fX;
5001 for (int i = 0; i < count; i+= 2) {
5002 canvas->drawRect({x, bounds[0], intervals[i], bounds[1]}, paint);
5003 x = intervals[i + 1];
5004 }
5005 canvas->drawRect({intervals[count - 1], bounds[0], 180, bounds[1]}, paint);
5006 }
5007 ##
5008
5009##
5010
Cary Clark08895c42018-02-01 09:37:32 -05005011#Subtopic Text_Intercepts ##
Cary Clark8032b982017-07-28 11:04:54 -04005012# ------------------------------------------------------------------------------
5013
5014#Method bool nothingToDraw() const
Cary Clark78de7512018-02-07 07:27:09 -05005015#In Utility
Cary Clarkab2621d2018-01-30 10:08:57 -05005016#Line # returns true if Paint prevents all drawing ##
Cary Clark579985c2017-07-31 11:48:27 -04005017 Returns true if Paint prevents all drawing;
5018 otherwise, the Paint may or may not allow drawing.
Cary Clark8032b982017-07-28 11:04:54 -04005019
Cary Clarkce101242017-09-01 15:51:02 -04005020 Returns true if, for example, Blend_Mode combined with Color_Alpha computes a
5021 new Alpha of zero.
Cary Clark8032b982017-07-28 11:04:54 -04005022
5023 #Return true if Paint prevents all drawing ##
5024
5025 #Example
5026 void draw(SkCanvas* canvas) {
5027 auto debugster = [](const char* prefix, const SkPaint& p) -> void {
Herb Derbyfcac00f2018-05-01 11:57:56 -04005028 SkDebugf("%s nothing to draw: %s\n", prefix,
Cary Clark8032b982017-07-28 11:04:54 -04005029 p.nothingToDraw() ? "true" : "false");
5030 };
5031 SkPaint paint;
5032 debugster("initial", paint);
5033 paint.setBlendMode(SkBlendMode::kDst);
5034 debugster("blend dst", paint);
5035 paint.setBlendMode(SkBlendMode::kSrcOver);
5036 debugster("blend src over", paint);
5037 paint.setAlpha(0);
5038 debugster("alpha 0", paint);
5039 }
5040
5041 #StdOut
5042 initial nothing to draw: false
5043 blend dst nothing to draw: true
5044 blend src over nothing to draw: false
5045 alpha 0 nothing to draw: true
5046 #StdOut ##
5047 ##
5048
5049##
5050
5051# ------------------------------------------------------------------------------
Cary Clark08895c42018-02-01 09:37:32 -05005052#Subtopic Fast_Bounds
5053#Line # approximate area required by Paint ##
Herb Derbyfcac00f2018-05-01 11:57:56 -04005054 #Private
5055 To be made private.
Cary Clark8032b982017-07-28 11:04:54 -04005056 ##
5057
Cary Clark682c58d2018-05-16 07:07:07 -04005058Fast_Bounds functions conservatively outset a drawing bounds by additional area
Cary Clark8032b982017-07-28 11:04:54 -04005059Paint may draw to.
5060
5061#Method bool canComputeFastBounds() const
Herb Derbyfcac00f2018-05-01 11:57:56 -04005062
Cary Clarkab2621d2018-01-30 10:08:57 -05005063#In Fast_Bounds
Cary Clark1a8d7622018-03-05 13:26:16 -05005064#Line # returns true if settings allow for fast bounds computation ##
Herb Derbyfcac00f2018-05-01 11:57:56 -04005065 #Private
Cary Clark8032b982017-07-28 11:04:54 -04005066 (to be made private)
5067 ##
5068
5069 Returns true if Paint does not include elements requiring extensive computation
5070 to compute Device bounds of drawn geometry. For instance, Paint with Path_Effect
5071 always returns false.
5072
5073 #Return true if Paint allows for fast computation of bounds ##
5074##
5075
5076#Method const SkRect& computeFastBounds(const SkRect& orig, SkRect* storage) const
Herb Derbyfcac00f2018-05-01 11:57:56 -04005077
Cary Clarkab2621d2018-01-30 10:08:57 -05005078#In Fast_Bounds
Cary Clark1a8d7622018-03-05 13:26:16 -05005079#Line # returns fill bounds for quick reject tests ##
Herb Derbyfcac00f2018-05-01 11:57:56 -04005080 #Private
Cary Clark8032b982017-07-28 11:04:54 -04005081 (to be made private)
5082 ##
5083
5084 Only call this if canComputeFastBounds returned true. This takes a
5085 raw rectangle (the raw bounds of a shape), and adjusts it for stylistic
5086 effects in the paint (e.g. stroking). If needed, it uses the storage
Cary Clarkce101242017-09-01 15:51:02 -04005087 parameter. It returns the adjusted bounds that can then be used
Cary Clark8032b982017-07-28 11:04:54 -04005088 for SkCanvas::quickReject tests.
5089
Cary Clarkce101242017-09-01 15:51:02 -04005090 The returned Rect will either be orig or storage, thus the caller
Cary Clark8032b982017-07-28 11:04:54 -04005091 should not rely on storage being set to the result, but should always
Cary Clarkce101242017-09-01 15:51:02 -04005092 use the returned value. It is legal for orig and storage to be the same
5093 Rect.
Cary Clark8032b982017-07-28 11:04:54 -04005094
Herb Derbyfcac00f2018-05-01 11:57:56 -04005095 #Private
Cary Clark682c58d2018-05-16 07:07:07 -04005096 For example:
5097 if (!path.isInverseFillType() && paint.canComputeFastBounds()) {
5098 SkRect storage;
5099 if (canvas->quickReject(paint.computeFastBounds(path.getBounds(), &storage))) {
Cary Clark137b8742018-05-30 09:21:49 -04005100 return; // do not draw the path
Cary Clark682c58d2018-05-16 07:07:07 -04005101 }
Cary Clark8032b982017-07-28 11:04:54 -04005102 }
Cary Clark682c58d2018-05-16 07:07:07 -04005103 // draw the path
Cary Clark8032b982017-07-28 11:04:54 -04005104 ##
5105
5106 #Param orig geometry modified by Paint when drawn ##
5107 #Param storage computed bounds of geometry; may not be nullptr ##
5108
5109 #Return fast computed bounds ##
5110##
5111
5112#Method const SkRect& computeFastStrokeBounds(const SkRect& orig,
5113 SkRect* storage) const
Cary Clarkab2621d2018-01-30 10:08:57 -05005114#In Fast_Bounds
5115#Line # returns stroke bounds for quick reject tests ##
Herb Derbyfcac00f2018-05-01 11:57:56 -04005116 #Private
Cary Clark8032b982017-07-28 11:04:54 -04005117 (to be made private)
5118 ##
5119
5120 #Param orig geometry modified by Paint when drawn ##
5121 #Param storage computed bounds of geometry ##
5122
5123 #Return fast computed bounds ##
5124##
5125
5126#Method const SkRect& doComputeFastBounds(const SkRect& orig, SkRect* storage,
5127 Style style) const
Cary Clarkab2621d2018-01-30 10:08:57 -05005128#In Fast_Bounds
5129#Line # returns bounds for quick reject tests ##
Herb Derbyfcac00f2018-05-01 11:57:56 -04005130 #Private
Cary Clark8032b982017-07-28 11:04:54 -04005131 (to be made private)
5132 ##
5133
Cary Clarkce101242017-09-01 15:51:02 -04005134 Computes the bounds, overriding the Paint Style. This can be used to
5135 account for additional width required by stroking orig, without
5136 altering Style set to fill.
Cary Clark8032b982017-07-28 11:04:54 -04005137
5138 #Param orig geometry modified by Paint when drawn ##
5139 #Param storage computed bounds of geometry ##
5140 #Param style overrides Style ##
5141
5142 #Return fast computed bounds ##
5143##
5144
Cary Clark1a8d7622018-03-05 13:26:16 -05005145#Subtopic Fast_Bounds ##
Cary Clark8032b982017-07-28 11:04:54 -04005146
5147# ------------------------------------------------------------------------------
Cary Clark78de7512018-02-07 07:27:09 -05005148#Subtopic Utility
Cary Clark78de7512018-02-07 07:27:09 -05005149#Line # rarely called management functions ##
5150##
Cary Clark8032b982017-07-28 11:04:54 -04005151
Cary Clark8032b982017-07-28 11:04:54 -04005152# ------------------------------------------------------------------------------
5153
5154#Class SkPaint ##
5155
5156#Topic Paint ##
Cary Clark4855f782018-02-06 09:41:53 -05005157