blob: 8a5e87a5b27f8741795f7d0b48d0151e43dd9d3d [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 Clarke4aa3712017-09-15 02:56:12 -04004#Class SkPaint
5
Cary Clark8032b982017-07-28 11:04:54 -04006Paint controls options applied when drawing and measuring. Paint collects all
7options outside of the Canvas_Clip and Canvas_Matrix.
8
Herb Derbyfcac00f2018-05-01 11:57:56 -04009Various options apply to text, strokes and fills, and images.
Cary Clark8032b982017-07-28 11:04:54 -040010
11Some options may not be implemented on all platforms; in these cases, setting
12the option has no effect. Some options are conveniences that duplicate Canvas
13functionality; for instance, text size is identical to matrix scale.
14
15Paint options are rarely exclusive; each option modifies a stage of the drawing
16pipeline and multiple pipeline stages may be affected by a single Paint.
17
Herb Derbyfcac00f2018-05-01 11:57:56 -040018Paint collects effects and filters that describe single-pass and multiple-pass
Cary Clark8032b982017-07-28 11:04:54 -040019algorithms that alter the drawing geometry, color, and transparency. For instance,
Herb Derbyfcac00f2018-05-01 11:57:56 -040020Paint does not directly implement dashing or blur, but contains the objects that do so.
Cary Clark8032b982017-07-28 11:04:54 -040021
22The objects contained by Paint are opaque, and cannot be edited outside of the Paint
23to affect it. The implementation is free to defer computations associated with the
24Paint, or ignore them altogether. For instance, some GPU implementations draw all
Cary Clarkffb3d682018-05-17 12:17:28 -040025Path geometries with Anti_Aliasing, regardless of how SkPaint::kAntiAlias_Flag
Cary Clarkbad5ad72017-08-03 17:14:08 -040026is set in Paint.
Cary Clark8032b982017-07-28 11:04:54 -040027
28Paint describes a single color, a single font, a single image quality, and so on.
29Multiple colors are drawn either by using multiple paints or with objects like
30Shader attached to Paint.
31
Cary Clark682c58d2018-05-16 07:07:07 -040032#Subtopic Overview
33#Populate
34##
35
Cary Clark4855f782018-02-06 09:41:53 -050036#Subtopic Related_Function
Cary Clark08895c42018-02-01 09:37:32 -050037#Populate
38##
Cary Clark8032b982017-07-28 11:04:54 -040039
Cary Clark4855f782018-02-06 09:41:53 -050040#Subtopic Constant
Cary Clark08895c42018-02-01 09:37:32 -050041#Populate
42##
Cary Clark8032b982017-07-28 11:04:54 -040043
Cary Clark682c58d2018-05-16 07:07:07 -040044#Subtopic Struct
Cary Clark08895c42018-02-01 09:37:32 -050045#Populate
46##
Cary Clark8032b982017-07-28 11:04:54 -040047
Cary Clark4855f782018-02-06 09:41:53 -050048#Subtopic Constructor
Cary Clark08895c42018-02-01 09:37:32 -050049#Populate
50##
Cary Clark8032b982017-07-28 11:04:54 -040051
Cary Clark4855f782018-02-06 09:41:53 -050052#Subtopic Operator
Cary Clark08895c42018-02-01 09:37:32 -050053#Populate
54##
Cary Clark8032b982017-07-28 11:04:54 -040055
Cary Clark4855f782018-02-06 09:41:53 -050056#Subtopic Member_Function
Cary Clark08895c42018-02-01 09:37:32 -050057#Populate
58##
Cary Clark8032b982017-07-28 11:04:54 -040059
60# ------------------------------------------------------------------------------
Cary Clark08895c42018-02-01 09:37:32 -050061#Subtopic Initializers
62#Line # constructors and initialization ##
Cary Clark8032b982017-07-28 11:04:54 -040063
64#Method SkPaint()
65
Cary Clarkab2621d2018-01-30 10:08:57 -050066#In Initializers
67#Line # constructs with default values ##
Cary Clark8032b982017-07-28 11:04:54 -040068Constructs Paint with default values.
69
70#Table
71#Legend
72# attribute # default value ##
73#Legend ##
Cary Clarkffb3d682018-05-17 12:17:28 -040074# Anti_Alias # false ##
Cary Clarkce101242017-09-01 15:51:02 -040075# Blend_Mode # SkBlendMode::kSrcOver ##
Cary Clark8032b982017-07-28 11:04:54 -040076# Color # SK_ColorBLACK ##
77# Color_Alpha # 255 ##
78# Color_Filter # nullptr ##
79# Dither # false ##
80# Draw_Looper # nullptr ##
81# Fake_Bold # false ##
82# Filter_Quality # kNone_SkFilterQuality ##
83# Font_Embedded_Bitmaps # false ##
84# Automatic_Hinting # false ##
85# Full_Hinting_Spacing # false ##
86# Hinting # kNormal_Hinting ##
87# Image_Filter # nullptr ##
88# LCD_Text # false ##
89# Linear_Text # false ##
90# Miter_Limit # 4 ##
91# Mask_Filter # nullptr ##
92# Path_Effect # nullptr ##
Cary Clark8032b982017-07-28 11:04:54 -040093# Shader # nullptr ##
94# Style # kFill_Style ##
95# Text_Align # kLeft_Align ##
96# Text_Encoding # kUTF8_TextEncoding ##
97# Text_Scale_X # 1 ##
98# Text_Size # 12 ##
99# Text_Skew_X # 0 ##
100# Typeface # nullptr ##
101# Stroke_Cap # kButt_Cap ##
102# Stroke_Join # kMiter_Join ##
103# Stroke_Width # 0 ##
104# Subpixel_Text # false ##
105# Vertical_Text # false ##
106#Table ##
107
108The flags, text size, hinting, and miter limit may be overridden at compile time by defining
Herb Derbyfcac00f2018-05-01 11:57:56 -0400109paint default values. The overrides may be included in "SkUserConfig.h" or predefined by the
Cary Clark8032b982017-07-28 11:04:54 -0400110build system.
111
112#Return default initialized Paint ##
113
114#Example
115#ToDo mark this as no output ##
116#Height 1
117###$ $ redefine markup character so preprocessor commands appear normally
118#ifndef SkUserConfig_DEFINED
119#define SkUserConfig_DEFINED
120
121#define SkPaintDefaults_Flags 0x01 // always enable antialiasing
122#define SkPaintDefaults_TextSize 24.f // double default font size
123#define SkPaintDefaults_Hinting 3 // use full hinting
124#define SkPaintDefaults_MiterLimit 10.f // use HTML Canvas miter limit setting
125
126#endif
127$$$# # restore original markup character
128##
129
130
131##
132
133#Method SkPaint(const SkPaint& paint)
134
Cary Clarkab2621d2018-01-30 10:08:57 -0500135#In Initializers
136#Line # makes a shallow copy ##
Cary Clark8032b982017-07-28 11:04:54 -0400137Makes a shallow copy of Paint. Typeface, Path_Effect, Shader,
Mike Reed8ad91a92018-01-19 19:09:32 -0500138Mask_Filter, Color_Filter, Draw_Looper, and Image_Filter are shared
Cary Clarkbad5ad72017-08-03 17:14:08 -0400139between the original paint and the copy. Objects containing Reference_Count increment
140their references by one.
Cary Clark8032b982017-07-28 11:04:54 -0400141
Mike Reed8ad91a92018-01-19 19:09:32 -0500142The referenced objects Path_Effect, Shader, Mask_Filter, Color_Filter,
Cary Clark8032b982017-07-28 11:04:54 -0400143Draw_Looper, and Image_Filter cannot be modified after they are created.
144This prevents objects with Reference_Count from being modified once Paint refers to them.
145
146#Param paint original to copy ##
147
148#Return shallow copy of paint ##
149
150#Example
151#ToDo why is this double-spaced on Fiddle? ##
152 SkPaint paint1;
153 paint1.setColor(SK_ColorRED);
154 SkPaint paint2(paint1);
155 paint2.setColor(SK_ColorBLUE);
156 SkDebugf("SK_ColorRED %c= paint1.getColor()\n", SK_ColorRED == paint1.getColor() ? '=' : '!');
157 SkDebugf("SK_ColorBLUE %c= paint2.getColor()\n", SK_ColorBLUE == paint2.getColor() ? '=' : '!');
158
159 #StdOut
160 SK_ColorRED == paint1.getColor()
161 SK_ColorBLUE == paint2.getColor()
162 ##
163##
164
165##
166
167#Method SkPaint(SkPaint&& paint)
168
Cary Clarkab2621d2018-01-30 10:08:57 -0500169#In Initializers
170#Line # moves paint without copying it ##
Cary Clarkd0530ba2017-09-14 11:25:39 -0400171 Implements a move constructor to avoid increasing the reference counts
Cary Clark8032b982017-07-28 11:04:54 -0400172 of objects referenced by the paint.
173
174 After the call, paint is undefined, and can be safely destructed.
175
176 #Param paint original to move ##
177
178 #Return content of paint ##
179
180 #Example
181 SkPaint paint;
182 float intervals[] = { 5, 5 };
183 paint.setPathEffect(SkDashPathEffect::Make(intervals, SK_ARRAY_COUNT(intervals), 2.5f));
184 SkPaint dashed(std::move(paint));
185 SkDebugf("path effect unique: %s\n", dashed.getPathEffect()->unique() ? "true" : "false");
186
187 #StdOut
188 path effect unique: true
189 ##
190 ##
191
192##
193
194# ------------------------------------------------------------------------------
195
196#Method void reset()
197
Cary Clarkab2621d2018-01-30 10:08:57 -0500198#In Initializers
199#Line # sets to default values ##
Cary Clarkbc5697d2017-10-04 14:31:33 -0400200Sets all Paint contents to their initial values. This is equivalent to replacing
201Paint with the result of SkPaint().
Cary Clark8032b982017-07-28 11:04:54 -0400202
203#Example
204 SkPaint paint1, paint2;
205 paint1.setColor(SK_ColorRED);
206 paint1.reset();
207 SkDebugf("paint1 %c= paint2", paint1 == paint2 ? '=' : '!');
208
209 #StdOut
210 paint1 == paint2
211 ##
212##
213
214##
215
Cary Clark08895c42018-02-01 09:37:32 -0500216#Subtopic Initializers ##
Cary Clark8032b982017-07-28 11:04:54 -0400217
218# ------------------------------------------------------------------------------
Cary Clark8032b982017-07-28 11:04:54 -0400219
220#Method ~SkPaint()
221
Cary Clarkab2621d2018-01-30 10:08:57 -0500222#Line # decreases Reference_Count of owned objects ##
Cary Clark8032b982017-07-28 11:04:54 -0400223Decreases Paint Reference_Count of owned objects: Typeface, Path_Effect, Shader,
Mike Reed8ad91a92018-01-19 19:09:32 -0500224Mask_Filter, Color_Filter, Draw_Looper, and Image_Filter. If the
Cary Clarkbad5ad72017-08-03 17:14:08 -0400225objects containing Reference_Count go to zero, they are deleted.
Cary Clark8032b982017-07-28 11:04:54 -0400226
Herb Derbyfcac00f2018-05-01 11:57:56 -0400227#NoExample
Cary Clark8032b982017-07-28 11:04:54 -0400228##
229
230##
231
Cary Clark08895c42018-02-01 09:37:32 -0500232
Cary Clark8032b982017-07-28 11:04:54 -0400233# ------------------------------------------------------------------------------
Cary Clark08895c42018-02-01 09:37:32 -0500234#Subtopic Management
235#Line # paint copying, moving, comparing ##
Cary Clark8032b982017-07-28 11:04:54 -0400236
237#Method SkPaint& operator=(const SkPaint& paint)
238
Cary Clarkab2621d2018-01-30 10:08:57 -0500239#In Management
240#Line # makes a shallow copy ##
Cary Clark8032b982017-07-28 11:04:54 -0400241Makes a shallow copy of Paint. Typeface, Path_Effect, Shader,
Mike Reed8ad91a92018-01-19 19:09:32 -0500242Mask_Filter, Color_Filter, Draw_Looper, and Image_Filter are shared
Cary Clarkbad5ad72017-08-03 17:14:08 -0400243between the original paint and the copy. Objects containing Reference_Count in the
Cary Clark8032b982017-07-28 11:04:54 -0400244prior destination are decreased by one, and the referenced objects are deleted if the
Cary Clarkbad5ad72017-08-03 17:14:08 -0400245resulting count is zero. Objects containing Reference_Count in the parameter paint
246are increased by one. paint is unmodified.
Cary Clark8032b982017-07-28 11:04:54 -0400247
248#Param paint original to copy ##
249
250#Return content of paint ##
251
252#Example
253 SkPaint paint1, paint2;
254 paint1.setColor(SK_ColorRED);
255 paint2 = paint1;
256 SkDebugf("SK_ColorRED %c= paint1.getColor()\n", SK_ColorRED == paint1.getColor() ? '=' : '!');
257 SkDebugf("SK_ColorRED %c= paint2.getColor()\n", SK_ColorRED == paint2.getColor() ? '=' : '!');
258
259 #StdOut
260 SK_ColorRED == paint1.getColor()
261 SK_ColorRED == paint2.getColor()
262 ##
263##
264
265##
266
267# ------------------------------------------------------------------------------
268
269#Method SkPaint& operator=(SkPaint&& paint)
270
Cary Clarkab2621d2018-01-30 10:08:57 -0500271#In Management
272#Line # moves paint without copying it ##
Cary Clarkd0530ba2017-09-14 11:25:39 -0400273Moves the paint to avoid increasing the reference counts
Cary Clarkbad5ad72017-08-03 17:14:08 -0400274of objects referenced by the paint parameter. Objects containing Reference_Count in the
275prior destination are decreased by one; those objects are deleted if the resulting count
276is zero.
Cary Clark8032b982017-07-28 11:04:54 -0400277
278After the call, paint is undefined, and can be safely destructed.
279
280 #Param paint original to move ##
281
282 #Return content of paint ##
283
284#Example
285 SkPaint paint1, paint2;
286 paint1.setColor(SK_ColorRED);
287 paint2 = std::move(paint1);
288 SkDebugf("SK_ColorRED == paint2.getColor()\n", SK_ColorRED == paint2.getColor() ? '=' : '!');
289
290 #StdOut
291 SK_ColorRED == paint2.getColor()
292 ##
293##
294
295##
296
297# ------------------------------------------------------------------------------
298
299#Method bool operator==(const SkPaint& a, const SkPaint& b)
300
Cary Clarkab2621d2018-01-30 10:08:57 -0500301#In Management
302#Line # compares paints for equality ##
Cary Clark8032b982017-07-28 11:04:54 -0400303 Compares a and b, and returns true if a and b are equivalent. May return false
Mike Reed8ad91a92018-01-19 19:09:32 -0500304 if Typeface, Path_Effect, Shader, Mask_Filter, Color_Filter,
Cary Clark8032b982017-07-28 11:04:54 -0400305 Draw_Looper, or Image_Filter have identical contents but different pointers.
306
307 #Param a Paint to compare ##
308 #Param b Paint to compare ##
309
310 #Return true if Paint pair are equivalent ##
311
312 #Example
313 SkPaint paint1, paint2;
314 paint1.setColor(SK_ColorRED);
315 paint2.setColor(0xFFFF0000);
316 SkDebugf("paint1 %c= paint2\n", paint1 == paint2 ? '=' : '!');
317 float intervals[] = { 5, 5 };
318 paint1.setPathEffect(SkDashPathEffect::Make(intervals, 2, 2.5f));
319 paint2.setPathEffect(SkDashPathEffect::Make(intervals, 2, 2.5f));
320 SkDebugf("paint1 %c= paint2\n", paint1 == paint2 ? '=' : '!');
321
322 #StdOut
323 paint1 == paint2
324 paint1 != paint2
325 ##
326 ##
Cary Clark06c20f32018-03-20 15:53:27 -0400327#SeeAlso operator!=(const SkPaint& a, const SkPaint& b)
Cary Clark8032b982017-07-28 11:04:54 -0400328##
329
330# ------------------------------------------------------------------------------
331
332#Method bool operator!=(const SkPaint& a, const SkPaint& b)
333
Cary Clarkab2621d2018-01-30 10:08:57 -0500334#In Management
335#Line # compares paints for inequality ##
Cary Clark8032b982017-07-28 11:04:54 -0400336 Compares a and b, and returns true if a and b are not equivalent. May return true
Mike Reed8ad91a92018-01-19 19:09:32 -0500337 if Typeface, Path_Effect, Shader, Mask_Filter, Color_Filter,
Cary Clark8032b982017-07-28 11:04:54 -0400338 Draw_Looper, or Image_Filter have identical contents but different pointers.
339
340 #Param a Paint to compare ##
341 #Param b Paint to compare ##
342
343 #Return true if Paint pair are not equivalent ##
344
345#Example
346 SkPaint paint1, paint2;
347 paint1.setColor(SK_ColorRED);
348 paint2.setColor(0xFFFF0000);
349 SkDebugf("paint1 %c= paint2\n", paint1 == paint2 ? '=' : '!');
350 SkDebugf("paint1 %c= paint2\n", paint1 != paint2 ? '!' : '=');
351
352 #StdOut
353 paint1 == paint2
354 paint1 == paint2
355 ##
356##
Cary Clark06c20f32018-03-20 15:53:27 -0400357#SeeAlso operator==(const SkPaint& a, const SkPaint& b)
Cary Clark8032b982017-07-28 11:04:54 -0400358##
359
360# ------------------------------------------------------------------------------
361
362#Method uint32_t getHash() const
363
Cary Clarkab2621d2018-01-30 10:08:57 -0500364#In Management
365#Line # returns a shallow hash for equality checks ##
Cary Clark8032b982017-07-28 11:04:54 -0400366Returns a hash generated from Paint values and pointers.
367Identical hashes guarantee that the paints are
368equivalent, but differing hashes do not guarantee that the paints have differing
369contents.
370
371If operator==(const SkPaint& a, const SkPaint& b) returns true for two paints,
372their hashes are also equal.
373
374The hash returned is platform and implementation specific.
375
376#Return a shallow hash ##
377
378#Example
379 SkPaint paint1, paint2;
380 paint1.setColor(SK_ColorRED);
381 paint2.setColor(0xFFFF0000);
382 SkDebugf("paint1 %c= paint2\n", paint1 == paint2 ? '=' : '!');
383 SkDebugf("paint1.getHash() %c= paint2.getHash()\n",
384 paint1.getHash() == paint2.getHash() ? '=' : '!');
385
386 #StdOut
387 paint1 == paint2
388 paint1.getHash() == paint2.getHash()
389 ##
390##
391
392##
393
Cary Clark08895c42018-02-01 09:37:32 -0500394#Subtopic Management ##
Cary Clark8032b982017-07-28 11:04:54 -0400395
396# ------------------------------------------------------------------------------
Cary Clark08895c42018-02-01 09:37:32 -0500397#Subtopic Hinting
398#Line # glyph outline adjustment ##
Cary Clark8032b982017-07-28 11:04:54 -0400399
400#Enum Hinting
Cary Clark08895c42018-02-01 09:37:32 -0500401#Line # level of glyph outline adjustment ##
Cary Clark8032b982017-07-28 11:04:54 -0400402
403#Code
404 enum Hinting {
405 kNo_Hinting = 0,
406 kSlight_Hinting = 1,
407 kNormal_Hinting = 2,
Cary Clarkbad5ad72017-08-03 17:14:08 -0400408 kFull_Hinting = 3,
Cary Clark8032b982017-07-28 11:04:54 -0400409 };
410##
411
412Hinting adjusts the glyph outlines so that the shape provides a uniform
413look at a given point size on font engines that support it. Hinting may have a
414muted effect or no effect at all depending on the platform.
415
416The four levels roughly control corresponding features on platforms that use FreeType
417as the Font_Engine.
418
419#Const kNo_Hinting 0
Cary Clark682c58d2018-05-16 07:07:07 -0400420#Line # glyph outlines unchanged ##
Cary Clark8032b982017-07-28 11:04:54 -0400421 Leaves glyph outlines unchanged from their native representation.
422 With FreeType, this is equivalent to the FT_LOAD_NO_HINTING
423 bit-field constant supplied to FT_Load_Glyph, which indicates that the vector
424 outline being loaded should not be fitted to the pixel grid but simply scaled
425 to 26.6 fractional pixels.
426##
427#Const kSlight_Hinting 1
Cary Clark682c58d2018-05-16 07:07:07 -0400428#Line # minimal modification to improve constrast ##
Cary Clark8032b982017-07-28 11:04:54 -0400429 Modifies glyph outlines minimally to improve constrast.
430 With FreeType, this is equivalent in spirit to the
Herb Derbyfcac00f2018-05-01 11:57:56 -0400431 FT_LOAD_TARGET_LIGHT value supplied to FT_Load_Glyph. It chooses a
Cary Clark8032b982017-07-28 11:04:54 -0400432 lighter hinting algorithm for non-monochrome modes.
Cary Clarkce101242017-09-01 15:51:02 -0400433 Generated Glyphs may be fuzzy but better resemble their original shape.
Cary Clark8032b982017-07-28 11:04:54 -0400434##
435#Const kNormal_Hinting 2
Cary Clark682c58d2018-05-16 07:07:07 -0400436#Line # glyph outlines modified to improve constrast ##
Cary Clark8032b982017-07-28 11:04:54 -0400437 Modifies glyph outlines to improve constrast. This is the default.
Cary Clark6fc50412017-09-21 12:31:06 -0400438 With FreeType, this supplies FT_LOAD_TARGET_NORMAL to FT_Load_Glyph,
Herb Derbyfcac00f2018-05-01 11:57:56 -0400439 choosing the default hinting algorithm, which is optimized for standard
440 gray-level rendering.
Cary Clark8032b982017-07-28 11:04:54 -0400441##
442#Const kFull_Hinting 3
Cary Clark137b8742018-05-30 09:21:49 -0400443#Line # modifies glyph outlines for maximum constrast ##
444 Modifies glyph outlines for maximum constrast. With FreeType, this selects
Herb Derbyfcac00f2018-05-01 11:57:56 -0400445 FT_LOAD_TARGET_LCD or FT_LOAD_TARGET_LCD_V if kLCDRenderText_Flag is set.
446 FT_LOAD_TARGET_LCD is a variant of FT_LOAD_TARGET_NORMAL optimized for
447 horizontally decimated LCD displays; FT_LOAD_TARGET_LCD_V is a
Cary Clark8032b982017-07-28 11:04:54 -0400448 variant of FT_LOAD_TARGET_NORMAL optimized for vertically decimated LCD displays.
449##
450
Cary Clark4855f782018-02-06 09:41:53 -0500451#Bug 915
Cary Clark8032b982017-07-28 11:04:54 -0400452On OS_X and iOS, hinting controls whether Core_Graphics dilates the font outlines
Cary Clark137b8742018-05-30 09:21:49 -0400453to account for LCD text. No hinting uses Core_Text Grayscale output.
Cary Clark8032b982017-07-28 11:04:54 -0400454Normal hinting uses Core_Text LCD output. If kLCDRenderText_Flag is clear,
Cary Clark137b8742018-05-30 09:21:49 -0400455the LCD output is reduced to a single Grayscale channel.
Cary Clark8032b982017-07-28 11:04:54 -0400456
457On Windows with DirectWrite, Hinting has no effect.
458
459Hinting defaults to kNormal_Hinting.
460Set SkPaintDefaults_Hinting at compile time to change the default setting.
461
462#ToDo add an illustration? linux running GM:typefacerendering is best for this
463 the hinting variations are every other character horizontally
464#ToDo ##
465
466#Enum ##
467
468#Method Hinting getHinting() const
469
Cary Clarkab2621d2018-01-30 10:08:57 -0500470#In Hinting
471#Line # returns Hinting, glyph outline adjustment level ##
Cary Clark8032b982017-07-28 11:04:54 -0400472 Returns level of glyph outline adjustment.
473
474 #Return one of: kNo_Hinting, kSlight_Hinting, kNormal_Hinting, kFull_Hinting ##
475
476 #Example
477 SkPaint paint;
478 SkDebugf("SkPaint::kNormal_Hinting %c= paint.getHinting()\n",
479 SkPaint::kNormal_Hinting == paint.getHinting() ? '=' : ':');
480
481 #StdOut
482 SkPaint::kNormal_Hinting == paint.getHinting()
483 ##
484 ##
485##
486
487#Method void setHinting(Hinting hintingLevel)
488
Cary Clarkab2621d2018-01-30 10:08:57 -0500489#In Hinting
490#Line # sets Hinting, glyph outline adjustment level ##
Cary Clark8032b982017-07-28 11:04:54 -0400491 Sets level of glyph outline adjustment.
492 Does not check for valid values of hintingLevel.
493
494 #Table
495 #Legend
496 # Hinting # value # effect on generated glyph outlines ##
497 ##
498 # kNo_Hinting # 0 # leaves glyph outlines unchanged from their native representation ##
Cary Clarkce101242017-09-01 15:51:02 -0400499 # kSlight_Hinting # 1 # modifies glyph outlines minimally to improve contrast ##
500 # kNormal_Hinting # 2 # modifies glyph outlines to improve contrast ##
Herb Derbyfcac00f2018-05-01 11:57:56 -0400501 # kFull_Hinting # 3 # modifies glyph outlines for maximum contrast ##
Cary Clark8032b982017-07-28 11:04:54 -0400502 ##
503
504 #Param hintingLevel one of: kNo_Hinting, kSlight_Hinting, kNormal_Hinting, kFull_Hinting ##
505
506 #Example
507 SkPaint paint1, paint2;
508 paint2.setHinting(SkPaint::kNormal_Hinting);
509 SkDebugf("paint1 %c= paint2\n", paint1 == paint2 ? '=' : ':');
510
511 #StdOut
512 paint1 == paint2
513 ##
514 ##
515##
516
Cary Clark08895c42018-02-01 09:37:32 -0500517#Subtopic Hinting ##
Cary Clark8032b982017-07-28 11:04:54 -0400518# ------------------------------------------------------------------------------
Cary Clark08895c42018-02-01 09:37:32 -0500519#Subtopic Flags
520#Line # attributes represented by single bits ##
Cary Clark8032b982017-07-28 11:04:54 -0400521
522#Enum Flags
Cary Clark08895c42018-02-01 09:37:32 -0500523#Line # values described by bits and masks ##
Cary Clark8032b982017-07-28 11:04:54 -0400524
525#Code
526 enum Flags {
527 kAntiAlias_Flag = 0x01,
528 kDither_Flag = 0x04,
529 kFakeBoldText_Flag = 0x20,
530 kLinearText_Flag = 0x40,
531 kSubpixelText_Flag = 0x80,
Cary Clark8032b982017-07-28 11:04:54 -0400532 kLCDRenderText_Flag = 0x200,
533 kEmbeddedBitmapText_Flag = 0x400,
534 kAutoHinting_Flag = 0x800,
535 kVerticalText_Flag = 0x1000,
Cary Clark8032b982017-07-28 11:04:54 -0400536
537 kAllFlags = 0xFFFF,
538 };
539
540##
541
542The bit values stored in Flags.
543The default value for Flags, normally zero, can be changed at compile time
544with a custom definition of SkPaintDefaults_Flags.
545All flags can be read and written explicitly; Flags allows manipulating
546multiple settings at once.
547
Herb Derbyfcac00f2018-05-01 11:57:56 -0400548 #Const kAntiAlias_Flag 0x0001
Cary Clarkffb3d682018-05-17 12:17:28 -0400549 #Line # mask for setting Anti_Alias ##
Cary Clark8032b982017-07-28 11:04:54 -0400550 ##
551 #Const kDither_Flag 0x0004
Cary Clark682c58d2018-05-16 07:07:07 -0400552 #Line # mask for setting Dither ##
Cary Clark8032b982017-07-28 11:04:54 -0400553 ##
Cary Clark8032b982017-07-28 11:04:54 -0400554 #Const kFakeBoldText_Flag 0x0020
Cary Clark682c58d2018-05-16 07:07:07 -0400555 #Line # mask for setting Fake_Bold ##
Cary Clark8032b982017-07-28 11:04:54 -0400556 ##
557 #Const kLinearText_Flag 0x0040
Cary Clark682c58d2018-05-16 07:07:07 -0400558 #Line # mask for setting Linear_Text ##
Cary Clark8032b982017-07-28 11:04:54 -0400559 ##
560 #Const kSubpixelText_Flag 0x0080
Cary Clark682c58d2018-05-16 07:07:07 -0400561 #Line # mask for setting Subpixel_Text ##
Cary Clark8032b982017-07-28 11:04:54 -0400562 ##
Cary Clark8032b982017-07-28 11:04:54 -0400563 #Const kLCDRenderText_Flag 0x0200
Cary Clark682c58d2018-05-16 07:07:07 -0400564 #Line # mask for setting LCD_Text ##
Cary Clark8032b982017-07-28 11:04:54 -0400565 ##
566 #Const kEmbeddedBitmapText_Flag 0x0400
Cary Clark682c58d2018-05-16 07:07:07 -0400567 #Line # mask for setting Font_Embedded_Bitmaps ##
Cary Clark8032b982017-07-28 11:04:54 -0400568 ##
569 #Const kAutoHinting_Flag 0x0800
Cary Clark682c58d2018-05-16 07:07:07 -0400570 #Line # mask for setting Automatic_Hinting ##
Cary Clark8032b982017-07-28 11:04:54 -0400571 ##
572 #Const kVerticalText_Flag 0x1000
Cary Clark682c58d2018-05-16 07:07:07 -0400573 #Line # mask for setting Vertical_Text ##
Cary Clark8032b982017-07-28 11:04:54 -0400574 ##
Cary Clark8032b982017-07-28 11:04:54 -0400575 #Const kAllFlags 0xFFFF
Cary Clark682c58d2018-05-16 07:07:07 -0400576 #Line # mask of all Flags ##
Cary Clark8032b982017-07-28 11:04:54 -0400577 mask of all Flags, including private flags and flags reserved for future use
578 ##
579
580Flags default to all flags clear, disabling the associated feature.
581
582#Enum ##
583
584#Enum ReserveFlags
Cary Clark4855f782018-02-06 09:41:53 -0500585#Deprecated soon
Cary Clark8032b982017-07-28 11:04:54 -0400586
Cary Clark4855f782018-02-06 09:41:53 -0500587Only valid for Android framework.
Cary Clark8032b982017-07-28 11:04:54 -0400588
589#Code
590 enum ReserveFlags {
591 kUnderlineText_ReserveFlag = 0x08,
592 kStrikeThruText_ReserveFlag = 0x10,
593 };
594##
595
Cary Clark4855f782018-02-06 09:41:53 -0500596#Const kUnderlineText_ReserveFlag 0x0008
597#Deprecated soon
598##
599#Const kStrikeThruText_ReserveFlag 0x0010
600#Deprecated soon
601##
602##
Cary Clark8032b982017-07-28 11:04:54 -0400603
604#Method uint32_t getFlags() const
605
Cary Clarkab2621d2018-01-30 10:08:57 -0500606#In Flags
607#Line # returns Flags stored in a bit field ##
Cary Clark8032b982017-07-28 11:04:54 -0400608Returns paint settings described by Flags. Each setting uses one
609bit, and can be tested with Flags members.
610
611#Return zero, one, or more bits described by Flags ##
612
613#Example
614 SkPaint paint;
615 paint.setAntiAlias(true);
616 SkDebugf("(SkPaint::kAntiAlias_Flag & paint.getFlags()) %c= 0\n",
617 SkPaint::kAntiAlias_Flag & paint.getFlags() ? '!' : '=');
618
619 #StdOut
620 (SkPaint::kAntiAlias_Flag & paint.getFlags()) != 0
621 ##
622##
623
624##
625
626#Method void setFlags(uint32_t flags)
627
Cary Clarkab2621d2018-01-30 10:08:57 -0500628#In Flags
629#Line # sets multiple Flags in a bit field ##
Cary Clark8032b982017-07-28 11:04:54 -0400630Replaces Flags with flags, the union of the Flags members.
631All Flags members may be cleared, or one or more may be set.
632
633#Param flags union of Flags for Paint ##
634
635#Example
636 SkPaint paint;
637 paint.setFlags((uint32_t) (SkPaint::kAntiAlias_Flag | SkPaint::kDither_Flag));
638 SkDebugf("paint.isAntiAlias()\n", paint.isAntiAlias() ? '!' : '=');
639 SkDebugf("paint.isDither()\n", paint.isDither() ? '!' : '=');
640
641 #StdOut
642 paint.isAntiAlias()
643 paint.isDither()
644 ##
645##
646
647##
648
Cary Clark08895c42018-02-01 09:37:32 -0500649#Subtopic Flags ##
Cary Clark8032b982017-07-28 11:04:54 -0400650# ------------------------------------------------------------------------------
Cary Clarkffb3d682018-05-17 12:17:28 -0400651#Subtopic Anti_Alias
652#Alias Anti_Alias
Cary Clark137b8742018-05-30 09:21:49 -0400653#Substitute anti-alias
654##
Cary Clarkffb3d682018-05-17 12:17:28 -0400655#Alias Anti_Aliased
Cary Clark137b8742018-05-30 09:21:49 -0400656#Substitute anti-aliased
657##
Cary Clarkffb3d682018-05-17 12:17:28 -0400658#Alias Anti_Aliasing
Cary Clark137b8742018-05-30 09:21:49 -0400659#Substitute anti-aliasing
660##
Cary Clark4855f782018-02-06 09:41:53 -0500661#In Related_Function
Cary Clarkab2621d2018-01-30 10:08:57 -0500662#Line # approximating coverage with transparency ##
Cary Clark8032b982017-07-28 11:04:54 -0400663
Cary Clarkffb3d682018-05-17 12:17:28 -0400664Anti_Alias drawing approximates partial pixel coverage with transparency.
Cary Clark8032b982017-07-28 11:04:54 -0400665If kAntiAlias_Flag is clear, pixel centers contained by the shape edge are drawn opaque.
666If kAntiAlias_Flag is set, pixels are drawn with Color_Alpha equal to their coverage.
667
Herb Derbyfcac00f2018-05-01 11:57:56 -0400668The rule for Aliased pixels is inconsistent across platforms. A shape edge
Cary Clark8032b982017-07-28 11:04:54 -0400669passing through the pixel center may, but is not required to, draw the pixel.
670
Cary Clarkce101242017-09-01 15:51:02 -0400671Raster_Engine draws Aliased pixels whose centers are on or to the right of the start of an
Cary Clark8032b982017-07-28 11:04:54 -0400672active Path edge, and whose center is to the left of the end of the active Path edge.
673
674#ToDo add illustration of raster pixels ##
675
Cary Clarkffb3d682018-05-17 12:17:28 -0400676A platform may only support Anti_Aliased drawing. Some GPU-backed platforms use
677Supersampling to Anti_Alias all drawing, and have no mechanism to selectively
Cary Clarkce101242017-09-01 15:51:02 -0400678Alias.
Cary Clark8032b982017-07-28 11:04:54 -0400679
Cary Clarkffb3d682018-05-17 12:17:28 -0400680The amount of coverage computed for Anti_Aliased pixels also varies across platforms.
Cary Clark8032b982017-07-28 11:04:54 -0400681
Cary Clarkffb3d682018-05-17 12:17:28 -0400682Anti_Alias is disabled by default.
683Anti_Alias can be enabled by default by setting SkPaintDefaults_Flags to kAntiAlias_Flag
Cary Clark8032b982017-07-28 11:04:54 -0400684at compile time.
685
Cary Clarkab2621d2018-01-30 10:08:57 -0500686#Example
Cary Clark8032b982017-07-28 11:04:54 -0400687 #Width 512
688 #Description
689 A red line is drawn with transparency on the edges to make it look smoother.
690 A blue line draws only where the pixel centers are contained.
Cary Clarkce101242017-09-01 15:51:02 -0400691 The lines are drawn into Bitmap, then drawn magnified to make the
692 Aliasing easier to see.
Cary Clark8032b982017-07-28 11:04:54 -0400693 ##
694
695 void draw(SkCanvas* canvas) {
696 SkBitmap bitmap;
697 bitmap.allocN32Pixels(50, 50);
698 SkCanvas offscreen(bitmap);
699 SkPaint paint;
700 paint.setStyle(SkPaint::kStroke_Style);
701 paint.setStrokeWidth(10);
702 for (bool antialias : { false, true }) {
703 paint.setColor(antialias ? SK_ColorRED : SK_ColorBLUE);
704 paint.setAntiAlias(antialias);
705 bitmap.eraseColor(0);
706 offscreen.drawLine(5, 5, 15, 30, paint);
707 canvas->drawLine(5, 5, 15, 30, paint);
708 canvas->save();
709 canvas->scale(10, 10);
710 canvas->drawBitmap(bitmap, antialias ? 12 : 0, 0);
711 canvas->restore();
712 canvas->translate(15, 0);
713 }
714 }
Cary Clarkab2621d2018-01-30 10:08:57 -0500715##
Cary Clark8032b982017-07-28 11:04:54 -0400716
717#Method bool isAntiAlias() const
Cary Clark78de7512018-02-07 07:27:09 -0500718#In Anti_alias
Cary Clarkffb3d682018-05-17 12:17:28 -0400719#Line # returns true if Anti_Alias is set ##
Cary Clark8032b982017-07-28 11:04:54 -0400720
Cary Clark80247e52018-07-11 16:18:41 -0400721 Returns true if pixels on the active edges of Path may be drawn with partial transparency.
Cary Clark8032b982017-07-28 11:04:54 -0400722
723 Equivalent to getFlags masked with kAntiAlias_Flag.
724
725 #Return kAntiAlias_Flag state ##
726
727 #Example
728 SkPaint paint;
729 SkDebugf("paint.isAntiAlias() %c= !!(paint.getFlags() & SkPaint::kAntiAlias_Flag)\n",
730 paint.isAntiAlias() == !!(paint.getFlags() & SkPaint::kAntiAlias_Flag) ? '=' : '!');
731 paint.setAntiAlias(true);
732 SkDebugf("paint.isAntiAlias() %c= !!(paint.getFlags() & SkPaint::kAntiAlias_Flag)\n",
733 paint.isAntiAlias() == !!(paint.getFlags() & SkPaint::kAntiAlias_Flag) ? '=' : '!');
734
735 #StdOut
736 paint.isAntiAlias() == !!(paint.getFlags() & SkPaint::kAntiAlias_Flag)
737 paint.isAntiAlias() == !!(paint.getFlags() & SkPaint::kAntiAlias_Flag)
738 ##
739 ##
740##
741
742#Method void setAntiAlias(bool aa)
743
Cary Clark78de7512018-02-07 07:27:09 -0500744#In Anti_alias
Cary Clarkffb3d682018-05-17 12:17:28 -0400745#Line # sets or clears Anti_Alias ##
Cary Clark8032b982017-07-28 11:04:54 -0400746 Requests, but does not require, that Path edge pixels draw opaque or with
747 partial transparency.
748
749 Sets kAntiAlias_Flag if aa is true.
750 Clears kAntiAlias_Flag if aa is false.
751
752 #Param aa setting for kAntiAlias_Flag ##
753
754 #Example
755 SkPaint paint1, paint2;
756 paint1.setAntiAlias(true);
757 paint2.setFlags(paint2.getFlags() | SkPaint::kAntiAlias_Flag);
758 SkDebugf("paint1 %c= paint2\n", paint1 == paint2 ? '=' : '!');
759
760 #StdOut
761 paint1 == paint2
762 ##
763 ##
764
765##
766
Cary Clarkffb3d682018-05-17 12:17:28 -0400767#Subtopic Anti_Alias ##
Cary Clark8032b982017-07-28 11:04:54 -0400768# ------------------------------------------------------------------------------
Cary Clark08895c42018-02-01 09:37:32 -0500769#Subtopic Dither
770#Line # distributing color error ##
Cary Clark8032b982017-07-28 11:04:54 -0400771
Herb Derbyfcac00f2018-05-01 11:57:56 -0400772Dither increases fidelity by adjusting the color of adjacent pixels.
Cary Clark8032b982017-07-28 11:04:54 -0400773This can help to smooth color transitions and reducing banding in gradients.
774Dithering lessens visible banding from kRGB_565_SkColorType
Herb Derbyfcac00f2018-05-01 11:57:56 -0400775and kRGBA_8888_SkColorType gradients,
Cary Clark8032b982017-07-28 11:04:54 -0400776and improves rendering into a kRGB_565_SkColorType Surface.
777
778Dithering is always enabled for linear gradients drawing into
779kRGB_565_SkColorType Surface and kRGBA_8888_SkColorType Surface.
780Dither cannot be enabled for kAlpha_8_SkColorType Surface and
781kRGBA_F16_SkColorType Surface.
782
783Dither is disabled by default.
784Dither can be enabled by default by setting SkPaintDefaults_Flags to kDither_Flag
785at compile time.
786
787Some platform implementations may ignore dithering. Set
788
Cary Clark2d4bf5f2018-04-16 08:37:38 -0400789#Formula
790SK_IGNORE_GPU_DITHER
791##
Cary Clark8032b982017-07-28 11:04:54 -0400792
793to ignore Dither on GPU_Surface.
794
795#Example
Herb Derbyfcac00f2018-05-01 11:57:56 -0400796#Description
Cary Clark8032b982017-07-28 11:04:54 -0400797Dithering in the bottom half more closely approximates the requested color by
798alternating nearby colors from pixel to pixel.
799##
800void draw(SkCanvas* canvas) {
801 SkBitmap bm16;
802 bm16.allocPixels(SkImageInfo::Make(32, 32, kRGB_565_SkColorType, kOpaque_SkAlphaType));
803 SkCanvas c16(bm16);
804 SkPaint colorPaint;
805 for (auto dither : { false, true } ) {
806 colorPaint.setDither(dither);
807 for (auto colors : { 0xFF333333, 0xFF666666, 0xFF999999, 0xFFCCCCCC } ) {
808 for (auto mask : { 0xFFFF0000, 0xFF00FF00, 0xFF0000FF, 0xFFFFFFFF } ) {
809 colorPaint.setColor(colors & mask);
810 c16.drawRect({0, 0, 8, 4}, colorPaint);
811 c16.translate(8, 0);
812 }
813 c16.translate(-32, 4);
814 }
815 }
816 canvas->scale(8, 8);
817 canvas->drawBitmap(bm16, 0, 0);
818}
819##
820
821#Example
Herb Derbyfcac00f2018-05-01 11:57:56 -0400822#Description
Cary Clark8032b982017-07-28 11:04:54 -0400823Dithering introduces subtle adjustments to color to smooth gradients.
824Drawing the gradient repeatedly with SkBlendMode::kPlus exaggerates the
825dither, making it easier to see.
826##
827void draw(SkCanvas* canvas) {
828 canvas->clear(0);
829 SkBitmap bm32;
830 bm32.allocPixels(SkImageInfo::Make(20, 10, kN32_SkColorType, kPremul_SkAlphaType));
831 SkCanvas c32(bm32);
832 SkPoint points[] = {{0, 0}, {20, 0}};
833 SkColor colors[] = {0xFF334455, 0xFF662211 };
834 SkPaint paint;
835 paint.setShader(SkGradientShader::MakeLinear(
836 points, colors, nullptr, SK_ARRAY_COUNT(colors),
837 SkShader::kClamp_TileMode, 0, nullptr));
838 paint.setDither(true);
839 c32.drawPaint(paint);
840 canvas->scale(12, 12);
841 canvas->drawBitmap(bm32, 0, 0);
842 paint.setBlendMode(SkBlendMode::kPlus);
843 canvas->drawBitmap(bm32, 0, 11, &paint);
844 canvas->drawBitmap(bm32, 0, 11, &paint);
845 canvas->drawBitmap(bm32, 0, 11, &paint);
846}
847##
848
849#Method bool isDither() const
850
Cary Clarkab2621d2018-01-30 10:08:57 -0500851#In Dither
852#Line # returns true if Dither is set ##
Cary Clark80247e52018-07-11 16:18:41 -0400853 Returns true if color error may be distributed to smooth color transition.
Herb Derbyfcac00f2018-05-01 11:57:56 -0400854
Cary Clark8032b982017-07-28 11:04:54 -0400855 Equivalent to getFlags masked with kDither_Flag.
856
857 #Return kDither_Flag state ##
858
859 #Example
860 SkPaint paint;
861 SkDebugf("paint.isDither() %c= !!(paint.getFlags() & SkPaint::kDither_Flag)\n",
862 paint.isDither() == !!(paint.getFlags() & SkPaint::kDither_Flag) ? '=' : '!');
863 paint.setDither(true);
864 SkDebugf("paint.isDither() %c= !!(paint.getFlags() & SkPaint::kDither_Flag)\n",
865 paint.isDither() == !!(paint.getFlags() & SkPaint::kDither_Flag) ? '=' : '!');
866
867 #StdOut
868 paint.isDither() == !!(paint.getFlags() & SkPaint::kDither_Flag)
869 paint.isDither() == !!(paint.getFlags() & SkPaint::kDither_Flag)
870 ##
871 ##
872
873##
874
875#Method void setDither(bool dither)
876
Cary Clarkab2621d2018-01-30 10:08:57 -0500877#In Dither
878#Line # sets or clears Dither ##
Cary Clark8032b982017-07-28 11:04:54 -0400879 Requests, but does not require, to distribute color error.
880
881 Sets kDither_Flag if dither is true.
882 Clears kDither_Flag if dither is false.
883
884 #Param dither setting for kDither_Flag ##
885
886 #Example
887 SkPaint paint1, paint2;
888 paint1.setDither(true);
889 paint2.setFlags(paint2.getFlags() | SkPaint::kDither_Flag);
890 SkDebugf("paint1 %c= paint2\n", paint1 == paint2 ? '=' : '!');
891
892 #StdOut
893 paint1 == paint2
894 ##
895 ##
896
897 #SeeAlso kRGB_565_SkColorType
898
899##
900
Cary Clarkffb3d682018-05-17 12:17:28 -0400901#SeeAlso Gradient kRGB_565_SkColorType
Cary Clark8032b982017-07-28 11:04:54 -0400902
Cary Clark08895c42018-02-01 09:37:32 -0500903#Subtopic Dither ##
Cary Clark8032b982017-07-28 11:04:54 -0400904# ------------------------------------------------------------------------------
Cary Clark08895c42018-02-01 09:37:32 -0500905#Subtopic Device_Text
906#Line # increase precision of glyph position ##
Cary Clark8032b982017-07-28 11:04:54 -0400907
908LCD_Text and Subpixel_Text increase the precision of glyph position.
909
Cary Clarkffb3d682018-05-17 12:17:28 -0400910When set, Flags kLCDRenderText_Flag takes advantage of the organization of RGB stripes that
Cary Clark8032b982017-07-28 11:04:54 -0400911create a color, and relies
Cary Clarkce101242017-09-01 15:51:02 -0400912on the small size of the stripe and visual perception to make the color fringing imperceptible.
Cary Clark8032b982017-07-28 11:04:54 -0400913LCD_Text can be enabled on devices that orient stripes horizontally or vertically, and that order
Cary Clarkffb3d682018-05-17 12:17:28 -0400914the color components as RGB or BGR.
Cary Clark8032b982017-07-28 11:04:54 -0400915
Herb Derbyfcac00f2018-05-01 11:57:56 -0400916Flags kSubpixelText_Flag uses the pixel transparency to represent a fractional offset.
Cary Clark8032b982017-07-28 11:04:54 -0400917As the opaqueness
918of the color increases, the edge of the glyph appears to move towards the outside of the pixel.
919
920Either or both techniques can be enabled.
921kLCDRenderText_Flag and kSubpixelText_Flag are clear by default.
Herb Derbyfcac00f2018-05-01 11:57:56 -0400922LCD_Text or Subpixel_Text can be enabled by default by setting SkPaintDefaults_Flags to
Cary Clark8032b982017-07-28 11:04:54 -0400923kLCDRenderText_Flag or kSubpixelText_Flag (or both) at compile time.
924
925#Example
926 #Description
927 Four commas are drawn normally and with combinations of LCD_Text and Subpixel_Text.
Cary Clarkce101242017-09-01 15:51:02 -0400928 When Subpixel_Text is disabled, the comma Glyphs are identical, but not evenly spaced.
929 When Subpixel_Text is enabled, the comma Glyphs are unique, but appear evenly spaced.
Cary Clark8032b982017-07-28 11:04:54 -0400930 ##
931
932 SkBitmap bitmap;
933 bitmap.allocN32Pixels(24, 33);
934 SkCanvas offscreen(bitmap);
935 offscreen.clear(SK_ColorWHITE);
936 SkPaint paint;
937 paint.setAntiAlias(true);
938 paint.setTextSize(20);
939 for (bool lcd : { false, true }) {
940 paint.setLCDRenderText(lcd);
941 for (bool subpixel : { false, true }) {
942 paint.setSubpixelText(subpixel);
943 offscreen.drawString(",,,,", 0, 4, paint);
944 offscreen.translate(0, 7);
945 }
946 }
947 canvas->drawBitmap(bitmap, 4, 12);
948 canvas->scale(9, 9);
949 canvas->drawBitmap(bitmap, 4, -1);
950##
Cary Clark08895c42018-02-01 09:37:32 -0500951#Subtopic Device_Text ##
Cary Clark8032b982017-07-28 11:04:54 -0400952
953#Subtopic Linear_Text
Cary Clark137b8742018-05-30 09:21:49 -0400954#Alias Linear_Text ##
Cary Clark08895c42018-02-01 09:37:32 -0500955#Line # selects text rendering as Glyph or Path ##
Cary Clark8032b982017-07-28 11:04:54 -0400956
957Linear_Text selects whether text is rendered as a Glyph or as a Path.
958If kLinearText_Flag is set, it has the same effect as setting Hinting to kNormal_Hinting.
Cary Clarkd0530ba2017-09-14 11:25:39 -0400959If kLinearText_Flag is clear, it is the same as setting Hinting to kNo_Hinting.
Cary Clark8032b982017-07-28 11:04:54 -0400960
961#Method bool isLinearText() const
962
Cary Clark08895c42018-02-01 09:37:32 -0500963#Line # returns true if text is converted to Path ##
Cary Clarkab2621d2018-01-30 10:08:57 -0500964#In Linear_Text
Cary Clark80247e52018-07-11 16:18:41 -0400965 Returns true if text is converted to Path before drawing and measuring.
Cary Clark8032b982017-07-28 11:04:54 -0400966
967 Equivalent to getFlags masked with kLinearText_Flag.
968
969 #Return kLinearText_Flag state ##
970
971 #Example
972 #Height 128
973 void draw(SkCanvas* canvas) {
974 SkPaint paint;
975 paint.setAntiAlias(true);
976 const char testStr[] = "xxxx xxxx";
977 for (auto linearText : { false, true } ) {
978 paint.setLinearText(linearText);
979 paint.setTextSize(24);
980 canvas->drawString(paint.isLinearText() ? "linear" : "hinted", 128, 30, paint);
981 for (SkScalar textSize = 8; textSize < 30; textSize *= 1.22f) {
982 paint.setTextSize(textSize);
983 canvas->translate(0, textSize);
984 canvas->drawString(testStr, 10, 0, paint);
985 }
986 }
987 }
988 ##
989
990 #SeeAlso setLinearText Hinting
991##
992
993#Method void setLinearText(bool linearText)
994
Cary Clark08895c42018-02-01 09:37:32 -0500995#Line # converts to Path before draw or measure ##
Cary Clarkab2621d2018-01-30 10:08:57 -0500996#In Linear_Text
Cary Clark80247e52018-07-11 16:18:41 -0400997 Returns true if text is converted to Path before drawing and measuring.
Cary Clark8032b982017-07-28 11:04:54 -0400998 By default, kLinearText_Flag is clear.
999
1000 Sets kLinearText_Flag if linearText is true.
1001 Clears kLinearText_Flag if linearText is false.
1002
1003 #Param linearText setting for kLinearText_Flag ##
1004
1005 #Example
1006 #Height 128
1007 void draw(SkCanvas* canvas) {
1008 SkPaint paint;
1009 paint.setAntiAlias(true);
1010 const char testStr[] = "abcd efgh";
1011 for (int textSize : { 12, 24 } ) {
1012 paint.setTextSize(textSize);
1013 for (auto linearText : { false, true } ) {
1014 paint.setLinearText(linearText);
1015 SkString width;
1016 width.appendScalar(paint.measureText(testStr, SK_ARRAY_COUNT(testStr), nullptr));
1017 canvas->translate(0, textSize + 4);
1018 canvas->drawString(testStr, 10, 0, paint);
1019 canvas->drawString(width, 128, 0, paint);
1020 }
1021 }
Herb Derbyfcac00f2018-05-01 11:57:56 -04001022 }
Cary Clark8032b982017-07-28 11:04:54 -04001023 ##
1024
1025 #SeeAlso isLinearText Hinting
1026##
1027
Cary Clark08895c42018-02-01 09:37:32 -05001028#Subtopic Linear_Text ##
Cary Clark8032b982017-07-28 11:04:54 -04001029
1030#Subtopic Subpixel_Text
Cary Clark137b8742018-05-30 09:21:49 -04001031#Alias Subpixel_Text ##
Cary Clark08895c42018-02-01 09:37:32 -05001032#Line # uses pixel transparency to represent fractional offset ##
Cary Clark8032b982017-07-28 11:04:54 -04001033
Herb Derbyfcac00f2018-05-01 11:57:56 -04001034Flags kSubpixelText_Flag uses the pixel transparency to represent a fractional offset.
Cary Clark8032b982017-07-28 11:04:54 -04001035As the opaqueness
1036of the color increases, the edge of the glyph appears to move towards the outside of the pixel.
1037
1038#Method bool isSubpixelText() const
Herb Derbyfcac00f2018-05-01 11:57:56 -04001039
Cary Clarkab2621d2018-01-30 10:08:57 -05001040#In Subpixel_Text
1041#Line # returns true if Subpixel_Text is set ##
Cary Clark80247e52018-07-11 16:18:41 -04001042 Returns true if Glyphs at different sub-pixel positions may differ on pixel edge coverage.
Cary Clark8032b982017-07-28 11:04:54 -04001043
1044 Equivalent to getFlags masked with kSubpixelText_Flag.
1045
1046 #Return kSubpixelText_Flag state ##
1047
1048 #Example
1049SkPaint paint;
1050SkDebugf("paint.isSubpixelText() %c= !!(paint.getFlags() & SkPaint::kSubpixelText_Flag)\n",
1051 paint.isSubpixelText() == !!(paint.getFlags() & SkPaint::kSubpixelText_Flag) ? '=' : '!');
1052paint.setSubpixelText(true);
1053SkDebugf("paint.isSubpixelText() %c= !!(paint.getFlags() & SkPaint::kSubpixelText_Flag)\n",
1054 paint.isSubpixelText() == !!(paint.getFlags() & SkPaint::kSubpixelText_Flag) ? '=' : '!');
1055
1056 #StdOut
1057 paint.isSubpixelText() == !!(paint.getFlags() & SkPaint::kSubpixelText_Flag)
1058 paint.isSubpixelText() == !!(paint.getFlags() & SkPaint::kSubpixelText_Flag)
1059 ##
1060 ##
1061
1062##
1063
1064#Method void setSubpixelText(bool subpixelText)
1065
Cary Clarkab2621d2018-01-30 10:08:57 -05001066#In Subpixel_Text
1067#Line # sets or clears Subpixel_Text ##
Cary Clarkce101242017-09-01 15:51:02 -04001068 Requests, but does not require, that Glyphs respect sub-pixel positioning.
Cary Clark8032b982017-07-28 11:04:54 -04001069
1070 Sets kSubpixelText_Flag if subpixelText is true.
1071 Clears kSubpixelText_Flag if subpixelText is false.
1072
1073 #Param subpixelText setting for kSubpixelText_Flag ##
1074
1075 #Example
1076 SkPaint paint1, paint2;
1077 paint1.setSubpixelText(true);
1078 paint2.setFlags(paint2.getFlags() | SkPaint::kSubpixelText_Flag);
1079 SkDebugf("paint1 %c= paint2\n", paint1 == paint2 ? '=' : '!');
1080
1081 #StdOut
1082 paint1 == paint2
1083 ##
1084 ##
1085
1086##
1087
Cary Clark08895c42018-02-01 09:37:32 -05001088#Subtopic Subpixel_Text ##
Cary Clark8032b982017-07-28 11:04:54 -04001089
1090#Subtopic LCD_Text
Cary Clarkffb3d682018-05-17 12:17:28 -04001091#Line # text relying on the order of RGB stripes ##
Cary Clark137b8742018-05-30 09:21:49 -04001092
1093# make this a top level name, since it is under subtopic Device_Text
1094#Alias LCD_Text
1095#Substitute LCD text
1096##
Cary Clark8032b982017-07-28 11:04:54 -04001097
Cary Clarkffb3d682018-05-17 12:17:28 -04001098When set, Flags kLCDRenderText_Flag takes advantage of the organization of RGB stripes that
Cary Clark8032b982017-07-28 11:04:54 -04001099create a color, and relies
Cary Clarkce101242017-09-01 15:51:02 -04001100on the small size of the stripe and visual perception to make the color fringing imperceptible.
Cary Clark8032b982017-07-28 11:04:54 -04001101LCD_Text can be enabled on devices that orient stripes horizontally or vertically, and that order
Cary Clarkffb3d682018-05-17 12:17:28 -04001102the color components as RGB or BGR.
Cary Clark8032b982017-07-28 11:04:54 -04001103
1104#Method bool isLCDRenderText() const
1105
Cary Clarkab2621d2018-01-30 10:08:57 -05001106#In LCD_Text
1107#Line # returns true if LCD_Text is set ##
Cary Clark80247e52018-07-11 16:18:41 -04001108 Returns true if Glyphs may use LCD striping to improve glyph edges.
Cary Clark8032b982017-07-28 11:04:54 -04001109
1110 Returns true if Flags kLCDRenderText_Flag is set.
1111
1112 #Return kLCDRenderText_Flag state ##
1113
1114 #Example
1115SkPaint paint;
1116SkDebugf("paint.isLCDRenderText() %c= !!(paint.getFlags() & SkPaint::kLCDRenderText_Flag)\n",
1117 paint.isLCDRenderText() == !!(paint.getFlags() & SkPaint::kLCDRenderText_Flag) ? '=' : '!');
1118paint.setLCDRenderText(true);
1119SkDebugf("paint.isLCDRenderText() %c= !!(paint.getFlags() & SkPaint::kLCDRenderText_Flag)\n",
1120 paint.isLCDRenderText() == !!(paint.getFlags() & SkPaint::kLCDRenderText_Flag) ? '=' : '!');
1121
1122 #StdOut
1123 paint.isLCDRenderText() == !!(paint.getFlags() & SkPaint::kLCDRenderText_Flag)
1124 paint.isLCDRenderText() == !!(paint.getFlags() & SkPaint::kLCDRenderText_Flag)
1125 ##
1126 ##
1127
1128##
1129
1130#Method void setLCDRenderText(bool lcdText)
1131
Cary Clarkab2621d2018-01-30 10:08:57 -05001132#In LCD_Text
1133#Line # sets or clears LCD_Text ##
Cary Clarkce101242017-09-01 15:51:02 -04001134 Requests, but does not require, that Glyphs use LCD striping for glyph edges.
Cary Clark8032b982017-07-28 11:04:54 -04001135
1136 Sets kLCDRenderText_Flag if lcdText is true.
1137 Clears kLCDRenderText_Flag if lcdText is false.
1138
1139 #Param lcdText setting for kLCDRenderText_Flag ##
1140
1141 #Example
1142 SkPaint paint1, paint2;
1143 paint1.setLCDRenderText(true);
1144 paint2.setFlags(paint2.getFlags() | SkPaint::kLCDRenderText_Flag);
1145 SkDebugf("paint1 %c= paint2\n", paint1 == paint2 ? '=' : '!');
1146
1147 #StdOut
1148 paint1 == paint2
1149 ##
1150 ##
1151
1152
1153##
1154
Cary Clark08895c42018-02-01 09:37:32 -05001155#Subtopic LCD_Text ##
Cary Clark8032b982017-07-28 11:04:54 -04001156
Cary Clark8032b982017-07-28 11:04:54 -04001157# ------------------------------------------------------------------------------
Cary Clark08895c42018-02-01 09:37:32 -05001158#Subtopic Font_Embedded_Bitmaps
1159#Line # custom sized bitmap Glyphs ##
Cary Clark137b8742018-05-30 09:21:49 -04001160#Alias Font_Embedded_Bitmaps ## # long-winded enough, alias so I don't type Paint_Font_...
Cary Clark8032b982017-07-28 11:04:54 -04001161
Cary Clarkce101242017-09-01 15:51:02 -04001162Font_Embedded_Bitmaps allows selecting custom sized bitmap Glyphs.
Cary Clark8032b982017-07-28 11:04:54 -04001163Flags kEmbeddedBitmapText_Flag when set chooses an embedded bitmap glyph over an outline contained
Herb Derbyfcac00f2018-05-01 11:57:56 -04001164in a font if the platform supports this option.
Cary Clark8032b982017-07-28 11:04:54 -04001165
1166FreeType selects the bitmap glyph if available when kEmbeddedBitmapText_Flag is set, and selects
1167the outline glyph if kEmbeddedBitmapText_Flag is clear.
1168Windows may select the bitmap glyph but is not required to do so.
1169OS_X and iOS do not support this option.
1170
1171Font_Embedded_Bitmaps is disabled by default.
1172Font_Embedded_Bitmaps can be enabled by default by setting SkPaintDefaults_Flags to
1173kEmbeddedBitmapText_Flag at compile time.
1174
1175#Example
1176 #ToDo image will only output on Ubuntu ... how to handle that in fiddle? ##
1177 #Platform !fiddle
1178 #Description
Cary Clarkce101242017-09-01 15:51:02 -04001179 The "hintgasp" TrueType font in the Skia resources/fonts directory
1180 includes an embedded bitmap Glyph at odd font sizes. This example works
1181 on platforms that use FreeType as their Font_Engine.
1182 Windows may, but is not required to, return a bitmap glyph if
1183 kEmbeddedBitmapText_Flag is set.
Cary Clark8032b982017-07-28 11:04:54 -04001184 ##
1185 #Image embeddedbitmap.png
1186
1187 SkBitmap bitmap;
1188 bitmap.allocN32Pixels(30, 15);
1189 bitmap.eraseColor(0);
1190 SkCanvas offscreen(bitmap);
1191 SkPaint paint;
1192 paint.setAntiAlias(true);
1193 paint.setTextSize(13);
Hal Canary53e5e7d2017-12-08 14:25:14 -05001194 paint.setTypeface(MakeResourceAsTypeface("fonts/hintgasp.ttf"));
Cary Clark8032b982017-07-28 11:04:54 -04001195 for (bool embedded : { false, true}) {
1196 paint.setEmbeddedBitmapText(embedded);
1197 offscreen.drawString("A", embedded ? 5 : 15, 15, paint);
1198 }
1199 canvas->drawBitmap(bitmap, 0, 0);
1200 canvas->scale(10, 10);
1201 canvas->drawBitmap(bitmap, -2, 1);
1202##
1203
1204#Method bool isEmbeddedBitmapText() const
1205
Cary Clarkab2621d2018-01-30 10:08:57 -05001206#In Font_Embedded_Bitmaps
1207#Line # returns true if Font_Embedded_Bitmaps is set ##
Cary Clark80247e52018-07-11 16:18:41 -04001208 Returns true if Font_Engine may return Glyphs from font bitmaps instead of from outlines.
Cary Clark8032b982017-07-28 11:04:54 -04001209
1210 Equivalent to getFlags masked with kEmbeddedBitmapText_Flag.
1211
1212 #Return kEmbeddedBitmapText_Flag state ##
1213
1214 #Example
1215 SkPaint paint;
1216 SkDebugf("paint.isEmbeddedBitmapText() %c="
1217 " !!(paint.getFlags() & SkPaint::kEmbeddedBitmapText_Flag)\n",
1218 paint.isEmbeddedBitmapText() ==
1219 !!(paint.getFlags() & SkPaint::kEmbeddedBitmapText_Flag) ? '=' : '!');
1220 paint.setEmbeddedBitmapText(true);
1221 SkDebugf("paint.isEmbeddedBitmapText() %c="
1222 " !!(paint.getFlags() & SkPaint::kEmbeddedBitmapText_Flag)\n",
1223 paint.isEmbeddedBitmapText() ==
1224 !!(paint.getFlags() & SkPaint::kEmbeddedBitmapText_Flag) ? '=' : '!');
1225
1226 #StdOut
1227 paint.isEmbeddedBitmapText() == !!(paint.getFlags() & SkPaint::kEmbeddedBitmapText_Flag)
1228 paint.isEmbeddedBitmapText() == !!(paint.getFlags() & SkPaint::kEmbeddedBitmapText_Flag)
1229 ##
1230 ##
1231
1232##
1233
1234#Method void setEmbeddedBitmapText(bool useEmbeddedBitmapText)
1235
Cary Clarkab2621d2018-01-30 10:08:57 -05001236#In Font_Embedded_Bitmaps
1237#Line # sets or clears Font_Embedded_Bitmaps ##
Cary Clark8032b982017-07-28 11:04:54 -04001238 Requests, but does not require, to use bitmaps in fonts instead of outlines.
1239
1240 Sets kEmbeddedBitmapText_Flag if useEmbeddedBitmapText is true.
1241 Clears kEmbeddedBitmapText_Flag if useEmbeddedBitmapText is false.
1242
1243 #Param useEmbeddedBitmapText setting for kEmbeddedBitmapText_Flag ##
1244
1245 #Example
1246 SkPaint paint1, paint2;
1247 paint1.setEmbeddedBitmapText(true);
1248 paint2.setFlags(paint2.getFlags() | SkPaint::kEmbeddedBitmapText_Flag);
1249 SkDebugf("paint1 %c= paint2\n", paint1 == paint2 ? '=' : '!');
1250
1251 #StdOut
1252 paint1 == paint2
1253 ##
1254 ##
1255
1256##
1257
Cary Clark08895c42018-02-01 09:37:32 -05001258#Subtopic Font_Embedded_Bitmaps ##
Cary Clark8032b982017-07-28 11:04:54 -04001259# ------------------------------------------------------------------------------
Cary Clark08895c42018-02-01 09:37:32 -05001260#Subtopic Automatic_Hinting
1261#Line # always adjust glyph paths ##
Cary Clark8032b982017-07-28 11:04:54 -04001262#Substitute auto-hinting
1263
1264If Hinting is set to kNormal_Hinting or kFull_Hinting, Automatic_Hinting
Cary Clarkce101242017-09-01 15:51:02 -04001265instructs the Font_Manager to always hint Glyphs.
Cary Clark8032b982017-07-28 11:04:54 -04001266Automatic_Hinting has no effect if Hinting is set to kNo_Hinting or
1267kSlight_Hinting.
1268
1269Automatic_Hinting only affects platforms that use FreeType as the Font_Manager.
1270
1271#Method bool isAutohinted() const
1272
Cary Clarkab2621d2018-01-30 10:08:57 -05001273#In Automatic_Hinting
1274#Line # returns true if Glyphs are always hinted ##
Cary Clark80247e52018-07-11 16:18:41 -04001275 Returns true if Hinting is set to kNormal_Hinting or kFull_Hinting, and if
1276 platform uses FreeType as the Font_Manager. If true, instructs
1277 the Font_Manager to always hint Glyphs.
Cary Clark8032b982017-07-28 11:04:54 -04001278
1279 Equivalent to getFlags masked with kAutoHinting_Flag.
1280
1281 #Return kAutoHinting_Flag state ##
1282
1283 #Example
1284 SkPaint paint;
1285 for (auto forceAutoHinting : { false, true} ) {
1286 paint.setAutohinted(forceAutoHinting);
1287 SkDebugf("paint.isAutohinted() %c="
1288 " !!(paint.getFlags() & SkPaint::kAutoHinting_Flag)\n",
1289 paint.isAutohinted() ==
1290 !!(paint.getFlags() & SkPaint::kAutoHinting_Flag) ? '=' : '!');
1291 }
1292 #StdOut
1293 paint.isAutohinted() == !!(paint.getFlags() & SkPaint::kAutoHinting_Flag)
1294 paint.isAutohinted() == !!(paint.getFlags() & SkPaint::kAutoHinting_Flag)
1295 ##
1296 ##
1297
1298 #SeeAlso setAutohinted Hinting
1299
1300##
1301
1302#Method void setAutohinted(bool useAutohinter)
1303
Cary Clarkab2621d2018-01-30 10:08:57 -05001304#In Automatic_Hinting
1305#Line # sets Glyphs to always be hinted ##
Cary Clark80247e52018-07-11 16:18:41 -04001306 Sets whether to always hint Glyphs.
Cary Clark8032b982017-07-28 11:04:54 -04001307 If Hinting is set to kNormal_Hinting or kFull_Hinting and useAutohinter is set,
Cary Clark80247e52018-07-11 16:18:41 -04001308 instructs the Font_Manager to always hint Glyphs.
Cary Clark8032b982017-07-28 11:04:54 -04001309 Automatic_Hinting has no effect if Hinting is set to kNo_Hinting or
1310 kSlight_Hinting.
1311
Cary Clark579985c2017-07-31 11:48:27 -04001312 Only affects platforms that use FreeType as the Font_Manager.
Cary Clark8032b982017-07-28 11:04:54 -04001313
1314 Sets kAutoHinting_Flag if useAutohinter is true.
1315 Clears kAutoHinting_Flag if useAutohinter is false.
1316
1317 #Param useAutohinter setting for kAutoHinting_Flag ##
1318
1319 #Example
1320 void draw(SkCanvas* canvas) {
1321 SkPaint paint;
1322 paint.setAntiAlias(true);
1323 const char testStr[] = "xxxx xxxx";
1324 for (auto forceAutoHinting : { false, true} ) {
1325 paint.setAutohinted(forceAutoHinting);
1326 paint.setTextSize(24);
1327 canvas->drawString(paint.isAutohinted() ? "auto-hinted" : "default", 108, 30, paint);
1328 for (SkScalar textSize = 8; textSize < 30; textSize *= 1.22f) {
1329 paint.setTextSize(textSize);
1330 canvas->translate(0, textSize);
1331 canvas->drawString(testStr, 10, 0, paint);
1332 }
1333 }
1334 }
1335 ##
1336
1337 #SeeAlso isAutohinted Hinting
1338
1339##
1340
Cary Clark08895c42018-02-01 09:37:32 -05001341#Subtopic Automatic_Hinting ##
Cary Clark8032b982017-07-28 11:04:54 -04001342# ------------------------------------------------------------------------------
Cary Clark08895c42018-02-01 09:37:32 -05001343#Subtopic Vertical_Text
1344#Line # orient text from top to bottom ##
Cary Clark8032b982017-07-28 11:04:54 -04001345
1346Text may be drawn by positioning each glyph, or by positioning the first glyph and
Cary Clarkce101242017-09-01 15:51:02 -04001347using Font_Advance to position subsequent Glyphs. By default, each successive glyph
1348is positioned to the right of the preceding glyph. Vertical_Text sets successive
1349Glyphs to position below the preceding glyph.
Cary Clark8032b982017-07-28 11:04:54 -04001350
Cary Clarkce101242017-09-01 15:51:02 -04001351Skia can translate text character codes as a series of Glyphs, but does not implement
Herb Derbyfcac00f2018-05-01 11:57:56 -04001352font substitution,
Cary Clarkce101242017-09-01 15:51:02 -04001353textual substitution, line layout, or contextual spacing like Kerning pairs. Use
Cary Clark6fc50412017-09-21 12:31:06 -04001354a text shaping engine like
Cary Clark682c58d2018-05-16 07:07:07 -04001355#A HarfBuzz # https://harfbuzz.org/ ##
Cary Clark6fc50412017-09-21 12:31:06 -04001356 to translate text runs
Cary Clark8032b982017-07-28 11:04:54 -04001357into glyph series.
1358
1359Vertical_Text is clear if text is drawn left to right or set if drawn from top to bottom.
1360
1361Flags kVerticalText_Flag if clear draws text left to right.
1362Flags kVerticalText_Flag if set draws text top to bottom.
1363
1364Vertical_Text is clear by default.
1365Vertical_Text can be set by default by setting SkPaintDefaults_Flags to
1366kVerticalText_Flag at compile time.
1367
1368#Example
1369
1370void draw(SkCanvas* canvas) {
1371 SkPaint paint;
1372 paint.setAntiAlias(true);
1373 paint.setTextSize(50);
1374 for (bool vertical : { false, true } ) {
1375 paint.setVerticalText(vertical);
1376 canvas->drawString("aAlL", 25, 50, paint);
1377 }
1378}
1379
1380##
1381
1382#Method bool isVerticalText() const
1383
Cary Clarkab2621d2018-01-30 10:08:57 -05001384#In Vertical_Text
1385#Line # returns true if Vertical_Text is set ##
Cary Clark80247e52018-07-11 16:18:41 -04001386 Returns true if Glyphs are drawn top to bottom instead of left to right.
Cary Clark8032b982017-07-28 11:04:54 -04001387
1388 Equivalent to getFlags masked with kVerticalText_Flag.
1389
1390 #Return kVerticalText_Flag state ##
1391
1392 #Example
1393 SkPaint paint;
1394 SkDebugf("paint.isVerticalText() %c= !!(paint.getFlags() & SkPaint::kVerticalText_Flag)\n",
1395 paint.isVerticalText() == !!(paint.getFlags() & SkPaint::kVerticalText_Flag) ? '=' : '!');
1396 paint.setVerticalText(true);
1397 SkDebugf("paint.isVerticalText() %c= !!(paint.getFlags() & SkPaint::kVerticalText_Flag)\n",
1398 paint.isVerticalText() == !!(paint.getFlags() & SkPaint::kVerticalText_Flag) ? '=' : '!');
1399
1400 #StdOut
1401 paint.isVerticalText() == !!(paint.getFlags() & SkPaint::kVerticalText_Flag)
1402 paint.isVerticalText() == !!(paint.getFlags() & SkPaint::kVerticalText_Flag)
1403 ##
1404 ##
1405
1406##
1407
1408#Method void setVerticalText(bool verticalText)
1409
Cary Clarkab2621d2018-01-30 10:08:57 -05001410#In Vertical_Text
1411#Line # sets or clears Vertical_Text ##
Cary Clark80247e52018-07-11 16:18:41 -04001412 Returns true if text advance positions the next glyph below the previous glyph instead of to the
Cary Clark8032b982017-07-28 11:04:54 -04001413 right of previous glyph.
1414
1415 Sets kVerticalText_Flag if vertical is true.
1416 Clears kVerticalText_Flag if vertical is false.
1417
1418 #Param verticalText setting for kVerticalText_Flag ##
1419
1420 #Example
1421 SkPaint paint1, paint2;
1422 paint1.setVerticalText(true);
1423 paint2.setFlags(paint2.getFlags() | SkPaint::kVerticalText_Flag);
1424 SkDebugf("paint1 %c= paint2\n", paint1 == paint2 ? '=' : '!');
1425
1426 #StdOut
1427 paint1 == paint2
1428 ##
1429 ##
1430
1431##
1432
Cary Clark08895c42018-02-01 09:37:32 -05001433#Subtopic Vertical_Text ##
Cary Clark8032b982017-07-28 11:04:54 -04001434# ------------------------------------------------------------------------------
1435
Cary Clark08895c42018-02-01 09:37:32 -05001436#Subtopic Fake_Bold
1437#Line # approximate font styles ##
Cary Clark8032b982017-07-28 11:04:54 -04001438
1439Fake_Bold approximates the bold font style accompanying a normal font when a bold font face
1440is not available. Skia does not provide font substitution; it is up to the client to find the
Cary Clarkbc5697d2017-10-04 14:31:33 -04001441bold font face using the platform Font_Manager.
Cary Clark8032b982017-07-28 11:04:54 -04001442
Herb Derbyfcac00f2018-05-01 11:57:56 -04001443Use Text_Skew_X to approximate an italic font style when the italic font face
Cary Clark8032b982017-07-28 11:04:54 -04001444is not available.
1445
Cary Clarkce101242017-09-01 15:51:02 -04001446A FreeType based port may define SK_USE_FREETYPE_EMBOLDEN at compile time to direct
1447the font engine to create the bold Glyphs. Otherwise, the extra bold is computed
Herb Derbyfcac00f2018-05-01 11:57:56 -04001448by increasing the stroke width and setting the Style to kStrokeAndFill_Style as needed.
Cary Clark8032b982017-07-28 11:04:54 -04001449
1450Fake_Bold is disabled by default.
1451
1452#Example
1453#Height 128
1454void draw(SkCanvas* canvas) {
1455 SkPaint paint;
1456 paint.setAntiAlias(true);
1457 paint.setTextSize(40);
1458 canvas->drawString("OjYy_-", 10, 35, paint);
1459 paint.setFakeBoldText(true);
1460 canvas->drawString("OjYy_-", 10, 75, paint);
1461 // create a custom fake bold by varying the stroke width
1462 paint.setFakeBoldText(false);
1463 paint.setStyle(SkPaint::kStrokeAndFill_Style);
1464 paint.setStrokeWidth(40.f / 48);
1465 canvas->drawString("OjYy_-", 10, 115, paint);
1466}
1467##
1468
1469#Method bool isFakeBoldText() const
1470
Cary Clarkab2621d2018-01-30 10:08:57 -05001471#In Fake_Bold
1472#Line # returns true if Fake_Bold is set ##
Cary Clark80247e52018-07-11 16:18:41 -04001473 Returns true if approximate bold by increasing the stroke width when creating glyph bitmaps
Cary Clark8032b982017-07-28 11:04:54 -04001474 from outlines.
1475
1476 Equivalent to getFlags masked with kFakeBoldText_Flag.
1477
1478 #Return kFakeBoldText_Flag state ##
1479
1480 #Example
1481 SkPaint paint;
1482 SkDebugf("paint.isFakeBoldText() %c= !!(paint.getFlags() & SkPaint::kFakeBoldText_Flag)\n",
1483 paint.isFakeBoldText() == !!(paint.getFlags() & SkPaint::kFakeBoldText_Flag) ? '=' : '!');
1484 paint.setFakeBoldText(true);
1485 SkDebugf("paint.isFakeBoldText() %c= !!(paint.getFlags() & SkPaint::kFakeBoldText_Flag)\n",
1486 paint.isFakeBoldText() == !!(paint.getFlags() & SkPaint::kFakeBoldText_Flag) ? '=' : '!');
1487
1488 #StdOut
1489 paint.isFakeBoldText() == !!(paint.getFlags() & SkPaint::kFakeBoldText_Flag)
1490 paint.isFakeBoldText() == !!(paint.getFlags() & SkPaint::kFakeBoldText_Flag)
1491 ##
1492 ##
1493
1494##
1495
1496#Method void setFakeBoldText(bool fakeBoldText)
1497
Cary Clarkab2621d2018-01-30 10:08:57 -05001498#In Fake_Bold
1499#Line # sets or clears Fake_Bold ##
Cary Clark80247e52018-07-11 16:18:41 -04001500 Increases stroke width when creating glyph bitmaps to approximate a bold typeface.
Cary Clark8032b982017-07-28 11:04:54 -04001501
1502 Sets kFakeBoldText_Flag if fakeBoldText is true.
1503 Clears kFakeBoldText_Flag if fakeBoldText is false.
1504
1505 #Param fakeBoldText setting for kFakeBoldText_Flag ##
1506
1507 #Example
1508 SkPaint paint1, paint2;
1509 paint1.setFakeBoldText(true);
1510 paint2.setFlags(paint2.getFlags() | SkPaint::kFakeBoldText_Flag);
1511 SkDebugf("paint1 %c= paint2\n", paint1 == paint2 ? '=' : '!');
1512
1513 #StdOut
1514 paint1 == paint2
1515 ##
1516 ##
1517
1518##
1519
Cary Clark08895c42018-02-01 09:37:32 -05001520#Subtopic Fake_Bold ##
Cary Clark8032b982017-07-28 11:04:54 -04001521
1522# ------------------------------------------------------------------------------
Cary Clark08895c42018-02-01 09:37:32 -05001523#Subtopic Full_Hinting_Spacing
1524#Line # glyph spacing affected by hinting ##
Cary Clark137b8742018-05-30 09:21:49 -04001525#Alias Full_Hinting_Spacing ## # long winded enough -- maybe things with two underscores auto-aliased?
Cary Clark8032b982017-07-28 11:04:54 -04001526
Cary Clarkce101242017-09-01 15:51:02 -04001527if Hinting is set to kFull_Hinting, Full_Hinting_Spacing adjusts the character
1528spacing by the difference of the hinted and Unhinted Left_Side_Bearing and
1529Right_Side_Bearing. Full_Hinting_Spacing only applies to platforms that use
1530FreeType as their Font_Engine.
Cary Clark8032b982017-07-28 11:04:54 -04001531
Cary Clarkce101242017-09-01 15:51:02 -04001532Full_Hinting_Spacing is not related to text Kerning, where the space between
Cary Clarkbc5697d2017-10-04 14:31:33 -04001533a specific pair of characters is adjusted using data in the font Kerning tables.
Cary Clark8032b982017-07-28 11:04:54 -04001534
1535#Method bool isDevKernText() const
Herb Derbyfcac00f2018-05-01 11:57:56 -04001536#Deprecated
Cary Clark8032b982017-07-28 11:04:54 -04001537##
1538
Herb Derbyfcac00f2018-05-01 11:57:56 -04001539#Method void setDevKernText(bool)
1540#Deprecated
Cary Clark8032b982017-07-28 11:04:54 -04001541##
1542
Cary Clark08895c42018-02-01 09:37:32 -05001543#Subtopic Full_Hinting_Spacing ##
Cary Clark8032b982017-07-28 11:04:54 -04001544# ------------------------------------------------------------------------------
Cary Clark08895c42018-02-01 09:37:32 -05001545#Subtopic Filter_Quality_Methods
1546#Line # get and set Filter_Quality ##
Cary Clark8032b982017-07-28 11:04:54 -04001547
1548Filter_Quality trades speed for image filtering when the image is scaled.
1549A lower Filter_Quality draws faster, but has less fidelity.
1550A higher Filter_Quality draws slower, but looks better.
Cary Clarkce101242017-09-01 15:51:02 -04001551If the image is drawn without scaling, the Filter_Quality choice will not result
1552in a noticeable difference.
Cary Clark8032b982017-07-28 11:04:54 -04001553
1554Filter_Quality is used in Paint passed as a parameter to
1555#List
1556# SkCanvas::drawBitmap ##
1557# SkCanvas::drawBitmapRect ##
1558# SkCanvas::drawImage ##
1559# SkCanvas::drawImageRect ##
1560 #ToDo probably more... ##
1561#List ##
1562and when Paint has a Shader specialization that uses Image or Bitmap.
1563
1564Filter_Quality is kNone_SkFilterQuality by default.
1565
1566#Example
1567#Image 3
1568void draw(SkCanvas* canvas) {
1569 SkPaint paint;
1570 canvas->scale(.2f, .2f);
Herb Derbyfcac00f2018-05-01 11:57:56 -04001571 for (SkFilterQuality q : { kNone_SkFilterQuality, kLow_SkFilterQuality,
Cary Clark8032b982017-07-28 11:04:54 -04001572 kMedium_SkFilterQuality, kHigh_SkFilterQuality } ) {
1573 paint.setFilterQuality(q);
1574 canvas->drawImage(image.get(), 0, 0, &paint);
1575 canvas->translate(550, 0);
1576 if (kLow_SkFilterQuality == q) canvas->translate(-1100, 550);
1577 }
1578}
1579##
1580
1581#Method SkFilterQuality getFilterQuality() const
1582
Cary Clarkab2621d2018-01-30 10:08:57 -05001583#In Filter_Quality_Methods
1584#Line # returns Filter_Quality, image filtering level ##
Cary Clark8032b982017-07-28 11:04:54 -04001585Returns Filter_Quality, the image filtering level. A lower setting
1586draws faster; a higher setting looks better when the image is scaled.
1587
Herb Derbyfcac00f2018-05-01 11:57:56 -04001588#Return one of: kNone_SkFilterQuality, kLow_SkFilterQuality,
Cary Clark8032b982017-07-28 11:04:54 -04001589 kMedium_SkFilterQuality, kHigh_SkFilterQuality
1590#Return ##
1591
1592#Example
1593 SkPaint paint;
1594 SkDebugf("kNone_SkFilterQuality %c= paint.getFilterQuality()\n",
1595 kNone_SkFilterQuality == paint.getFilterQuality() ? '=' : '!');
1596
1597 #StdOut
1598 kNone_SkFilterQuality == paint.getFilterQuality()
1599 ##
1600##
1601
1602##
1603
1604
1605#Method void setFilterQuality(SkFilterQuality quality)
1606
Cary Clarkab2621d2018-01-30 10:08:57 -05001607#In Filter_Quality_Methods
1608#Line # sets Filter_Quality, the image filtering level ##
Cary Clark8032b982017-07-28 11:04:54 -04001609Sets Filter_Quality, the image filtering level. A lower setting
1610draws faster; a higher setting looks better when the image is scaled.
Herb Derbyfcac00f2018-05-01 11:57:56 -04001611Does not check to see if quality is valid.
Cary Clark8032b982017-07-28 11:04:54 -04001612
Herb Derbyfcac00f2018-05-01 11:57:56 -04001613#Param quality one of: kNone_SkFilterQuality, kLow_SkFilterQuality,
Cary Clark8032b982017-07-28 11:04:54 -04001614 kMedium_SkFilterQuality, kHigh_SkFilterQuality
1615##
1616
1617#Example
1618 SkPaint paint;
1619 paint.setFilterQuality(kHigh_SkFilterQuality);
1620 SkDebugf("kHigh_SkFilterQuality %c= paint.getFilterQuality()\n",
1621 kHigh_SkFilterQuality == paint.getFilterQuality() ? '=' : '!');
1622
1623 #StdOut
1624 kHigh_SkFilterQuality == paint.getFilterQuality()
1625 ##
1626##
1627
1628#SeeAlso SkFilterQuality Image_Scaling
1629
1630##
1631
Cary Clark08895c42018-02-01 09:37:32 -05001632#Subtopic Filter_Quality_Methods ##
Cary Clark8032b982017-07-28 11:04:54 -04001633# ------------------------------------------------------------------------------
Cary Clark08895c42018-02-01 09:37:32 -05001634#Subtopic Color_Methods
1635#Line # get and set Color ##
Cary Clark8032b982017-07-28 11:04:54 -04001636
Cary Clarkab2621d2018-01-30 10:08:57 -05001637#Table
1638#Legend
1639# name # description ##
1640#Legend ##
Cary Clarkffb3d682018-05-17 12:17:28 -04001641# getColor # returns Color_Alpha and RGB, one drawing color ##
1642# setColor # sets Color_Alpha and RGB, one drawing color ##
Cary Clarkab2621d2018-01-30 10:08:57 -05001643#Table ##
Cary Clark8032b982017-07-28 11:04:54 -04001644
Cary Clarkffb3d682018-05-17 12:17:28 -04001645Color specifies the red, blue, green, and Color_Alpha
Cary Clarkab2621d2018-01-30 10:08:57 -05001646values used to draw a filled or stroked shape in a 32-bit value. Each component
1647occupies 8-bits, ranging from zero: no contribution; to 255: full intensity.
1648All values in any combination are valid.
Cary Clark8032b982017-07-28 11:04:54 -04001649
Cary Clarkab2621d2018-01-30 10:08:57 -05001650Color is not Premultiplied; Color_Alpha sets the transparency independent of
Cary Clarkffb3d682018-05-17 12:17:28 -04001651RGB: red, blue, and green.
Cary Clarkab2621d2018-01-30 10:08:57 -05001652
Cary Clarkffb3d682018-05-17 12:17:28 -04001653The bit positions of Color_Alpha and RGB are independent of the bit
Cary Clarkab2621d2018-01-30 10:08:57 -05001654positions on the output device, which may have more or fewer bits, and may have
1655a different arrangement.
Cary Clark8032b982017-07-28 11:04:54 -04001656
1657#Table
1658#Legend
Cary Clarkffb3d682018-05-17 12:17:28 -04001659# bit positions # Color_Alpha # red # blue # green ##
Cary Clark8032b982017-07-28 11:04:54 -04001660#Legend ##
1661# # 31 - 24 # 23 - 16 # 15 - 8 # 7 - 0 ##
1662#Table ##
1663
1664#Example
1665#Height 128
1666 void draw(SkCanvas* canvas) {
1667 SkPaint paint;
1668 paint.setColor(0x8000FF00); // transparent green
1669 canvas->drawCircle(50, 50, 40, paint);
1670 paint.setARGB(128, 255, 0, 0); // transparent red
1671 canvas->drawCircle(80, 50, 40, paint);
1672 paint.setColor(SK_ColorBLUE);
1673 paint.setAlpha(0x80);
1674 canvas->drawCircle(65, 65, 40, paint);
1675 }
1676##
1677
1678#Method SkColor getColor() const
1679
Cary Clarkab2621d2018-01-30 10:08:57 -05001680#In Color_Methods
Cary Clarkffb3d682018-05-17 12:17:28 -04001681#Line # returns Color_Alpha and RGB, one drawing color ##
1682 Retrieves Alpha and RGB, Unpremultiplied, packed into 32 bits.
Cary Clark8032b982017-07-28 11:04:54 -04001683 Use helpers SkColorGetA, SkColorGetR, SkColorGetG, and SkColorGetB to extract
1684 a color component.
1685
Cary Clarkffb3d682018-05-17 12:17:28 -04001686 #Return Unpremultiplied ARGB ##
Cary Clark8032b982017-07-28 11:04:54 -04001687
1688 #Example
1689 SkPaint paint;
1690 paint.setColor(SK_ColorYELLOW);
1691 SkColor y = paint.getColor();
1692 SkDebugf("Yellow is %d%% red, %d%% green, and %d%% blue.\n", (int) (SkColorGetR(y) / 2.55f),
1693 (int) (SkColorGetG(y) / 2.55f), (int) (SkColorGetB(y) / 2.55f));
1694
1695 #StdOut
1696 Yellow is 100% red, 100% green, and 0% blue.
1697 ##
1698 ##
1699
1700 #SeeAlso SkColor
1701
1702##
1703
1704#Method void setColor(SkColor color)
1705
Cary Clarkab2621d2018-01-30 10:08:57 -05001706#In Color_Methods
Cary Clarkffb3d682018-05-17 12:17:28 -04001707#Line # sets Color_Alpha and RGB, one drawing color ##
1708 Sets Alpha and RGB used when stroking and filling. The color is a 32-bit value,
1709 Unpremultiplied, packing 8-bit components for Alpha, red, blue, and green.
Cary Clark8032b982017-07-28 11:04:54 -04001710
Cary Clarkffb3d682018-05-17 12:17:28 -04001711 #Param color Unpremultiplied ARGB ##
Herb Derbyfcac00f2018-05-01 11:57:56 -04001712
Cary Clark0c5f5462017-12-15 11:21:51 -05001713 #Example
Cary Clark8032b982017-07-28 11:04:54 -04001714 SkPaint green1, green2;
1715 unsigned a = 255;
1716 unsigned r = 0;
1717 unsigned g = 255;
1718 unsigned b = 0;
1719 green1.setColor((a << 24) + (r << 16) + (g << 8) + (b << 0));
1720 green2.setColor(0xFF00FF00);
1721 SkDebugf("green1 %c= green2\n", green1 == green2 ? '=' : '!');
1722
1723 #StdOut
1724 green1 == green2
1725 ##
1726 ##
1727
1728 #SeeAlso SkColor setARGB SkColorSetARGB
1729
1730##
Cary Clark08895c42018-02-01 09:37:32 -05001731#Subtopic Color_Methods ##
Cary Clark8032b982017-07-28 11:04:54 -04001732
1733#Subtopic Alpha_Methods
Cary Clark08895c42018-02-01 09:37:32 -05001734#Line # get and set Alpha ##
Cary Clark8032b982017-07-28 11:04:54 -04001735
Cary Clarkffb3d682018-05-17 12:17:28 -04001736Color_Alpha sets the transparency independent of RGB: red, blue, and green.
Cary Clark8032b982017-07-28 11:04:54 -04001737
1738#Method uint8_t getAlpha() const
1739
Cary Clarkab2621d2018-01-30 10:08:57 -05001740#In Alpha_Methods
1741#Line # returns Color_Alpha, color opacity ##
Cary Clarkce101242017-09-01 15:51:02 -04001742 Retrieves Alpha from the Color used when stroking and filling.
Cary Clark8032b982017-07-28 11:04:54 -04001743
Cary Clarkce101242017-09-01 15:51:02 -04001744 #Return Alpha ranging from zero, fully transparent, to 255, fully opaque ##
Cary Clark8032b982017-07-28 11:04:54 -04001745
1746 #Example
1747 SkPaint paint;
1748 SkDebugf("255 %c= paint.getAlpha()\n", 255 == paint.getAlpha() ? '=' : '!');
1749
1750 #StdOut
1751 255 == paint.getAlpha()
1752 ##
1753 ##
1754
1755##
1756
1757#Method void setAlpha(U8CPU a)
1758
Cary Clarkab2621d2018-01-30 10:08:57 -05001759#In Alpha_Methods
1760#Line # sets Color_Alpha, color opacity ##
Cary Clarkffb3d682018-05-17 12:17:28 -04001761 Replaces Alpha, leaving RGB
Cary Clark8032b982017-07-28 11:04:54 -04001762 unchanged. An out of range value triggers an assert in the debug
1763 build. a is a value from zero to 255.
1764 a set to zero makes Color fully transparent; a set to 255 makes Color
1765 fully opaque.
1766
Cary Clarkce101242017-09-01 15:51:02 -04001767 #Param a Alpha component of Color ##
Cary Clark8032b982017-07-28 11:04:54 -04001768
1769 #Example
1770 SkPaint paint;
1771 paint.setColor(0x00112233);
1772 paint.setAlpha(0x44);
1773 SkDebugf("0x44112233 %c= paint.getColor()\n", 0x44112233 == paint.getColor() ? '=' : '!');
1774
1775 #StdOut
1776 0x44112233 == paint.getColor()
1777 ##
1778 ##
1779
1780##
1781
Cary Clark08895c42018-02-01 09:37:32 -05001782#Subtopic Alpha_Methods ##
Cary Clark8032b982017-07-28 11:04:54 -04001783
1784#Method void setARGB(U8CPU a, U8CPU r, U8CPU g, U8CPU b)
1785
Cary Clarkab2621d2018-01-30 10:08:57 -05001786#In Color_Methods
1787#Line # sets color by component ##
Cary Clark8032b982017-07-28 11:04:54 -04001788 Sets Color used when drawing solid fills. The color components range from 0 to 255.
Cary Clarkffb3d682018-05-17 12:17:28 -04001789 The color is Unpremultiplied; Alpha sets the transparency independent of RGB.
Cary Clark8032b982017-07-28 11:04:54 -04001790
1791 #Param a amount of Color_Alpha, from fully transparent (0) to fully opaque (255) ##
Cary Clarkffb3d682018-05-17 12:17:28 -04001792 #Param r amount of red, from no red (0) to full red (255) ##
1793 #Param g amount of green, from no green (0) to full green (255) ##
1794 #Param b amount of blue, from no blue (0) to full blue (255) ##
Herb Derbyfcac00f2018-05-01 11:57:56 -04001795
Cary Clark8032b982017-07-28 11:04:54 -04001796 #Example
1797 SkPaint transRed1, transRed2;
1798 transRed1.setARGB(255 / 2, 255, 0, 0);
1799 transRed2.setColor(SkColorSetARGB(255 / 2, 255, 0, 0));
1800 SkDebugf("transRed1 %c= transRed2", transRed1 == transRed2 ? '=' : '!');
1801
1802 #StdOut
1803 transRed1 == transRed2
1804 ##
1805 ##
1806
1807 #SeeAlso setColor SkColorSetARGB
1808
1809##
1810
Cary Clark8032b982017-07-28 11:04:54 -04001811# ------------------------------------------------------------------------------
Cary Clark08895c42018-02-01 09:37:32 -05001812#Subtopic Style
1813#Line # geometry filling, stroking ##
Cary Clark8032b982017-07-28 11:04:54 -04001814
1815Style specifies if the geometry is filled, stroked, or both filled and stroked.
1816Some shapes ignore Style and are always drawn filled or stroked.
1817
1818Set Style to kFill_Style to fill the shape.
1819The fill covers the area inside the geometry for most shapes.
1820
1821Set Style to kStroke_Style to stroke the shape.
1822
1823# ------------------------------------------------------------------------------
1824#Subtopic Fill
Cary Clark08895c42018-02-01 09:37:32 -05001825#Line # fill and stroke ##
Cary Clark8032b982017-07-28 11:04:54 -04001826#ToDo write up whatever generalities make sense to describe filling ##
1827
1828#SeeAlso Path_Fill_Type
Cary Clark08895c42018-02-01 09:37:32 -05001829#Subtopic Fill ##
Cary Clark8032b982017-07-28 11:04:54 -04001830
1831#Subtopic Stroke
Cary Clark08895c42018-02-01 09:37:32 -05001832#Line # lines and curves with width ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001833The stroke covers the area described by following the shape edge with a pen or brush of
Cary Clark8032b982017-07-28 11:04:54 -04001834Stroke_Width. The area covered where the shape starts and stops is described by Stroke_Cap.
1835The area covered where the shape turns a corner is described by Stroke_Join.
Cary Clarkbc5697d2017-10-04 14:31:33 -04001836The stroke is centered on the shape; it extends equally on either side of the shape edge.
Cary Clark8032b982017-07-28 11:04:54 -04001837
1838As Stroke_Width gets smaller, the drawn path frame is thinner. Stroke_Width less than one
1839may have gaps, and if kAntiAlias_Flag is set, Color_Alpha will increase to visually decrease coverage.
Cary Clark08895c42018-02-01 09:37:32 -05001840#Subtopic Stroke ##
Cary Clark8032b982017-07-28 11:04:54 -04001841
1842#Subtopic Hairline
Cary Clark08895c42018-02-01 09:37:32 -05001843#Line # lines and curves with minimal width ##
Cary Clark137b8742018-05-30 09:21:49 -04001844#Alias Hairline ## # maybe should be Stroke_Hairline ?
Cary Clark8032b982017-07-28 11:04:54 -04001845
1846Stroke_Width of zero has a special meaning and switches drawing to use Hairline.
Herb Derbyfcac00f2018-05-01 11:57:56 -04001847Hairline draws the thinnest continuous frame. If kAntiAlias_Flag is clear, adjacent pixels
1848flow horizontally, vertically,or diagonally.
Cary Clark8032b982017-07-28 11:04:54 -04001849
Cary Clarkffb3d682018-05-17 12:17:28 -04001850#ToDo what is the description of Anti_Aliased hairlines? ##
Cary Clark8032b982017-07-28 11:04:54 -04001851
1852Path drawing with Hairline may hit the same pixel more than once. For instance, Path containing
1853two lines in one Path_Contour will draw the corner point once, but may both lines may draw the adjacent
1854pixel. If kAntiAlias_Flag is set, transparency is applied twice, resulting in a darker pixel. Some
1855GPU-backed implementations apply transparency at a later drawing stage, avoiding double hit pixels
1856while stroking.
1857
Cary Clark08895c42018-02-01 09:37:32 -05001858#Subtopic Hairline ##
Cary Clark8032b982017-07-28 11:04:54 -04001859
1860#Enum Style
Cary Clark08895c42018-02-01 09:37:32 -05001861#Line # stroke, fill, or both ##
Cary Clark8032b982017-07-28 11:04:54 -04001862
1863#Code
1864 enum Style {
1865 kFill_Style,
1866 kStroke_Style,
1867 kStrokeAndFill_Style,
1868 };
Cary Clarkd98f78c2018-04-26 08:32:37 -04001869
1870 static constexpr int kStyleCount = kStrokeAndFill_Style + 1;
Cary Clark8032b982017-07-28 11:04:54 -04001871##
1872
1873Set Style to fill, stroke, or both fill and stroke geometry.
1874The stroke and fill
1875share all paint attributes; for instance, they are drawn with the same color.
1876
1877Use kStrokeAndFill_Style to avoid hitting the same pixels twice with a stroke draw and
1878a fill draw.
1879
1880#Const kFill_Style 0
Cary Clark682c58d2018-05-16 07:07:07 -04001881#Line # set to fill geometry ##
Herb Derbyfcac00f2018-05-01 11:57:56 -04001882 Applies to Rect, Region, Round_Rect, Circles, Ovals, Path, and Text.
Cary Clarkce101242017-09-01 15:51:02 -04001883 Bitmap, Image, Patches, Region, Sprites, and Vertices are painted as if
Cary Clark8032b982017-07-28 11:04:54 -04001884 kFill_Style is set, and ignore the set Style.
1885 The Path_Fill_Type specifies additional rules to fill the area outside the path edge,
1886 and to create an unfilled hole inside the shape.
1887 Style is set to kFill_Style by default.
1888##
1889
1890#Const kStroke_Style 1
Cary Clark682c58d2018-05-16 07:07:07 -04001891#Line # set to stroke geometry ##
Herb Derbyfcac00f2018-05-01 11:57:56 -04001892 Applies to Rect, Region, Round_Rect, Arcs, Circles, Ovals, Path, and Text.
Cary Clark56356312018-02-08 14:45:18 -05001893 Arcs, Lines, and points, are always drawn as if kStroke_Style is set,
Cary Clark8032b982017-07-28 11:04:54 -04001894 and ignore the set Style.
1895 The stroke construction is unaffected by the Path_Fill_Type.
1896##
1897
1898#Const kStrokeAndFill_Style 2
Cary Clark682c58d2018-05-16 07:07:07 -04001899#Line # sets to stroke and fill geometry ##
Cary Clarkce101242017-09-01 15:51:02 -04001900 Applies to Rect, Region, Round_Rect, Circles, Ovals, Path, and Text.
Cary Clark8032b982017-07-28 11:04:54 -04001901 Path is treated as if it is set to SkPath::kWinding_FillType,
Herb Derbyfcac00f2018-05-01 11:57:56 -04001902 and the set Path_Fill_Type is ignored.
Cary Clark8032b982017-07-28 11:04:54 -04001903##
1904
Cary Clark8032b982017-07-28 11:04:54 -04001905#Const kStyleCount 3
Cary Clark682c58d2018-05-16 07:07:07 -04001906#Line # number of different Style values defined ##
Cary Clark8032b982017-07-28 11:04:54 -04001907May be used to verify that Style is a legal value.
1908##
1909
Cary Clarkd98f78c2018-04-26 08:32:37 -04001910#Enum Style ##
Cary Clark8032b982017-07-28 11:04:54 -04001911
1912#Method Style getStyle() const
1913
Cary Clarkab2621d2018-01-30 10:08:57 -05001914#In Style
1915#Line # returns Style: stroke, fill, or both ##
Cary Clark80247e52018-07-11 16:18:41 -04001916 Returns whether the geometry is filled, stroked, or filled and stroked.
Cary Clark8032b982017-07-28 11:04:54 -04001917
1918 #Return one of:kFill_Style, kStroke_Style, kStrokeAndFill_Style ##
1919
1920 #Example
1921 SkPaint paint;
1922 SkDebugf("SkPaint::kFill_Style %c= paint.getStyle()\n",
1923 SkPaint::kFill_Style == paint.getStyle() ? '=' : '!');
1924
1925 #StdOut
1926 SkPaint::kFill_Style == paint.getStyle()
1927 ##
1928 ##
1929
1930#SeeAlso Style setStyle
1931##
1932
1933#Method void setStyle(Style style)
1934
Cary Clarkab2621d2018-01-30 10:08:57 -05001935#In Style
1936#Line # sets Style: stroke, fill, or both ##
Cary Clark8032b982017-07-28 11:04:54 -04001937 Sets whether the geometry is filled, stroked, or filled and stroked.
1938 Has no effect if style is not a legal Style value.
1939
1940 #Param style one of: kFill_Style, kStroke_Style, kStrokeAndFill_Style
1941 ##
1942
1943 #Example
1944 void draw(SkCanvas* canvas) {
1945 SkPaint paint;
1946 paint.setStrokeWidth(5);
1947 SkRegion region;
1948 region.op(140, 10, 160, 30, SkRegion::kUnion_Op);
1949 region.op(170, 40, 190, 60, SkRegion::kUnion_Op);
1950 SkBitmap bitmap;
1951 bitmap.setInfo(SkImageInfo::MakeA8(50, 50), 50);
1952 uint8_t pixels[50][50];
1953 for (int x = 0; x < 50; ++x) {
1954 for (int y = 0; y < 50; ++y) {
1955 pixels[y][x] = (x + y) % 5 ? 0xFF : 0x00;
1956 }
1957 }
1958 bitmap.setPixels(pixels);
1959 for (auto style : { SkPaint::kFill_Style,
1960 SkPaint::kStroke_Style,
1961 SkPaint::kStrokeAndFill_Style }) {
1962 paint.setStyle(style);
1963 canvas->drawLine(10, 10, 60, 60, paint);
1964 canvas->drawRect({80, 10, 130, 60}, paint);
1965 canvas->drawRegion(region, paint);
1966 canvas->drawBitmap(bitmap, 200, 10, &paint);
1967 canvas->translate(0, 80);
1968 }
1969 }
1970 ##
1971
1972#SeeAlso Style getStyle
1973##
1974
1975#SeeAlso Path_Fill_Type Path_Effect Style_Fill Style_Stroke
Cary Clark08895c42018-02-01 09:37:32 -05001976#Subtopic Style ##
Cary Clark8032b982017-07-28 11:04:54 -04001977
1978# ------------------------------------------------------------------------------
Cary Clark08895c42018-02-01 09:37:32 -05001979#Subtopic Stroke_Width
1980#Line # thickness perpendicular to geometry ##
Cary Clark8032b982017-07-28 11:04:54 -04001981
1982Stroke_Width sets the width for stroking. The width is the thickness
Herb Derbyfcac00f2018-05-01 11:57:56 -04001983of the stroke perpendicular to the path direction when the paint style is
Cary Clark8032b982017-07-28 11:04:54 -04001984set to kStroke_Style or kStrokeAndFill_Style.
1985
1986When width is greater than zero, the stroke encompasses as many pixels partially
1987or fully as needed. When the width equals zero, the paint enables hairlines;
Herb Derbyfcac00f2018-05-01 11:57:56 -04001988the stroke is always one pixel wide.
Cary Clark8032b982017-07-28 11:04:54 -04001989
Cary Clarkbc5697d2017-10-04 14:31:33 -04001990The stroke dimensions are scaled by the canvas matrix, but Hairline stroke
Cary Clark8032b982017-07-28 11:04:54 -04001991remains one pixel wide regardless of scaling.
1992
1993The default width for the paint is zero.
1994
1995#Example
1996#Height 170
1997 #Platform raster gpu
1998 #Description
Herb Derbyfcac00f2018-05-01 11:57:56 -04001999 The pixels hit to represent thin lines vary with the angle of the
Cary Clarkbc5697d2017-10-04 14:31:33 -04002000 line and the platform implementation.
Cary Clark8032b982017-07-28 11:04:54 -04002001 ##
2002 void draw(SkCanvas* canvas) {
2003 SkPaint paint;
Herb Derbyfcac00f2018-05-01 11:57:56 -04002004 for (bool antialias : { false, true }) {
Cary Clark8032b982017-07-28 11:04:54 -04002005 paint.setAntiAlias(antialias);
2006 for (int width = 0; width <= 4; ++width) {
2007 SkScalar offset = antialias * 100 + width * 20;
2008 paint.setStrokeWidth(width * 0.25f);
2009 canvas->drawLine(10 + offset, 10, 20 + offset, 60, paint);
2010 canvas->drawLine(10 + offset, 110, 60 + offset, 160, paint);
2011 }
2012 }
2013 }
2014##
2015
2016#Method SkScalar getStrokeWidth() const
2017
Cary Clarkab2621d2018-01-30 10:08:57 -05002018#In Stroke_Width
2019#Line # returns thickness of the stroke ##
Cary Clark8032b982017-07-28 11:04:54 -04002020 Returns the thickness of the pen used by Paint to
2021 outline the shape.
2022
2023 #Return zero for Hairline, greater than zero for pen thickness ##
Herb Derbyfcac00f2018-05-01 11:57:56 -04002024
Cary Clark8032b982017-07-28 11:04:54 -04002025 #Example
2026 SkPaint paint;
2027 SkDebugf("0 %c= paint.getStrokeWidth()\n", 0 == paint.getStrokeWidth() ? '=' : '!');
2028
2029 #StdOut
2030 0 == paint.getStrokeWidth()
2031 ##
2032 ##
2033
2034##
2035
2036#Method void setStrokeWidth(SkScalar width)
2037
Cary Clarkab2621d2018-01-30 10:08:57 -05002038#In Stroke_Width
2039#Line # sets thickness of the stroke ##
Cary Clark8032b982017-07-28 11:04:54 -04002040 Sets the thickness of the pen used by the paint to
Herb Derbyfcac00f2018-05-01 11:57:56 -04002041 outline the shape.
2042 Has no effect if width is less than zero.
Cary Clark8032b982017-07-28 11:04:54 -04002043
Herb Derbyfcac00f2018-05-01 11:57:56 -04002044 #Param width zero thickness for Hairline; greater than zero for pen thickness
Cary Clark8032b982017-07-28 11:04:54 -04002045 ##
2046
2047 #Example
2048 SkPaint paint;
2049 paint.setStrokeWidth(5);
2050 paint.setStrokeWidth(-1);
2051 SkDebugf("5 %c= paint.getStrokeWidth()\n", 5 == paint.getStrokeWidth() ? '=' : '!');
2052
2053 #StdOut
2054 5 == paint.getStrokeWidth()
2055 ##
2056 ##
2057
2058##
2059
Cary Clark08895c42018-02-01 09:37:32 -05002060#Subtopic Stroke_Width ##
Cary Clark8032b982017-07-28 11:04:54 -04002061# ------------------------------------------------------------------------------
Cary Clark08895c42018-02-01 09:37:32 -05002062#Subtopic Miter_Limit
2063#Line # maximum length of stroked corners ##
Cary Clark8032b982017-07-28 11:04:54 -04002064
2065Miter_Limit specifies the maximum miter length,
2066relative to the stroke width.
2067
2068Miter_Limit is used when the Stroke_Join
2069is set to kMiter_Join, and the Style is either kStroke_Style
2070or kStrokeAndFill_Style.
2071
2072If the miter at a corner exceeds this limit, kMiter_Join
2073is replaced with kBevel_Join.
2074
2075Miter_Limit can be computed from the corner angle:
2076
2077#Formula
2078 miter limit = 1 / sin ( angle / 2 )
2079#Formula ##
2080
2081Miter_Limit default value is 4.
2082The default may be changed at compile time by setting SkPaintDefaults_MiterLimit
Cary Clarkce101242017-09-01 15:51:02 -04002083in "SkUserConfig.h" or as a define supplied by the build environment.
Cary Clark8032b982017-07-28 11:04:54 -04002084
2085Here are some miter limits and the angles that triggers them.
2086#Table
2087#Legend
2088 # miter limit # angle in degrees ##
2089#Legend ##
2090 # 10 # 11.48 ##
2091 # 9 # 12.76 ##
2092 # 8 # 14.36 ##
2093 # 7 # 16.43 ##
2094 # 6 # 19.19 ##
2095 # 5 # 23.07 ##
2096 # 4 # 28.96 ##
2097 # 3 # 38.94 ##
2098 # 2 # 60 ##
2099 # 1 # 180 ##
2100#Table ##
2101
2102#Example
2103 #Height 170
2104 #Width 384
2105 #Description
2106 This example draws a stroked corner and the miter length beneath.
2107 When the miter limit is decreased slightly, the miter join is replaced
2108 by a bevel join.
2109 ##
2110 void draw(SkCanvas* canvas) {
2111 SkPoint pts[] = {{ 10, 50 }, { 110, 80 }, { 10, 110 }};
2112 SkVector v[] = { pts[0] - pts[1], pts[2] - pts[1] };
2113 SkScalar angle1 = SkScalarATan2(v[0].fY, v[0].fX);
2114 SkScalar angle2 = SkScalarATan2(v[1].fY, v[1].fX);
2115 const SkScalar strokeWidth = 20;
2116 SkScalar miterLimit = 1 / SkScalarSin((angle2 - angle1) / 2);
2117 SkScalar miterLength = strokeWidth * miterLimit;
2118 SkPath path;
2119 path.moveTo(pts[0]);
2120 path.lineTo(pts[1]);
2121 path.lineTo(pts[2]);
2122 SkPaint paint; // set to default kMiter_Join
2123 paint.setAntiAlias(true);
2124 paint.setStyle(SkPaint::kStroke_Style);
2125 paint.setStrokeMiter(miterLimit);
2126 paint.setStrokeWidth(strokeWidth);
2127 canvas->drawPath(path, paint);
2128 paint.setStrokeWidth(1);
2129 canvas->drawLine(pts[1].fX - miterLength / 2, pts[1].fY + 50,
2130 pts[1].fX + miterLength / 2, pts[1].fY + 50, paint);
2131 canvas->translate(200, 0);
2132 miterLimit *= 0.99f;
2133 paint.setStrokeMiter(miterLimit);
2134 paint.setStrokeWidth(strokeWidth);
2135 canvas->drawPath(path, paint);
2136 paint.setStrokeWidth(1);
2137 canvas->drawLine(pts[1].fX - miterLength / 2, pts[1].fY + 50,
2138 pts[1].fX + miterLength / 2, pts[1].fY + 50, paint);
2139 }
2140##
2141
2142#Method SkScalar getStrokeMiter() const
2143
Cary Clarkab2621d2018-01-30 10:08:57 -05002144#In Miter_Limit
2145#Line # returns Miter_Limit, angles with sharp corners ##
Cary Clark80247e52018-07-11 16:18:41 -04002146 Returns the limit at which a sharp corner is drawn beveled.
Cary Clark8032b982017-07-28 11:04:54 -04002147
2148 #Return zero and greater Miter_Limit ##
2149
2150 #Example
2151 SkPaint paint;
2152 SkDebugf("default miter limit == %g\n", paint.getStrokeMiter());
2153
2154 #StdOut
2155 default miter limit == 4
2156 ##
2157 ##
2158
2159 #SeeAlso Miter_Limit setStrokeMiter Join
2160
2161##
2162
2163#Method void setStrokeMiter(SkScalar miter)
2164
Cary Clarkab2621d2018-01-30 10:08:57 -05002165#In Miter_Limit
2166#Line # sets Miter_Limit, angles with sharp corners ##
Cary Clark80247e52018-07-11 16:18:41 -04002167 Sets the limit at which a sharp corner is drawn beveled.
Cary Clark8032b982017-07-28 11:04:54 -04002168 Valid values are zero and greater.
2169 Has no effect if miter is less than zero.
2170
2171 #Param miter zero and greater Miter_Limit
2172 ##
2173
2174 #Example
2175 SkPaint paint;
2176 paint.setStrokeMiter(8);
2177 paint.setStrokeMiter(-1);
2178 SkDebugf("default miter limit == %g\n", paint.getStrokeMiter());
2179
2180 #StdOut
2181 default miter limit == 8
2182 ##
2183 ##
2184
2185 #SeeAlso Miter_Limit getStrokeMiter Join
2186
2187##
2188
Cary Clark08895c42018-02-01 09:37:32 -05002189#Subtopic Miter_Limit ##
Cary Clark8032b982017-07-28 11:04:54 -04002190# ------------------------------------------------------------------------------
Cary Clark08895c42018-02-01 09:37:32 -05002191#Subtopic Stroke_Cap
2192#Line # decorations at ends of open strokes ##
Cary Clark8032b982017-07-28 11:04:54 -04002193
2194#Enum Cap
Cary Clark08895c42018-02-01 09:37:32 -05002195#Line # start and end geometry on stroked shapes ##
Cary Clark8032b982017-07-28 11:04:54 -04002196
2197#Code
2198 enum Cap {
2199 kButt_Cap,
2200 kRound_Cap,
2201 kSquare_Cap,
2202
2203 kLast_Cap = kSquare_Cap,
Cary Clarkbad5ad72017-08-03 17:14:08 -04002204 kDefault_Cap = kButt_Cap,
Cary Clark8032b982017-07-28 11:04:54 -04002205 };
Cary Clark6fc50412017-09-21 12:31:06 -04002206
Cary Clark8032b982017-07-28 11:04:54 -04002207 static constexpr int kCapCount = kLast_Cap + 1;
2208##
2209
2210Stroke_Cap draws at the beginning and end of an open Path_Contour.
2211
2212 #Const kButt_Cap 0
Cary Clark682c58d2018-05-16 07:07:07 -04002213 #Line # no stroke extension ##
Cary Clark8032b982017-07-28 11:04:54 -04002214 Does not extend the stroke past the beginning or the end.
2215 ##
2216 #Const kRound_Cap 1
Cary Clark682c58d2018-05-16 07:07:07 -04002217 #Line # adds circle ##
Cary Clark8032b982017-07-28 11:04:54 -04002218 Adds a circle with a diameter equal to Stroke_Width at the beginning
2219 and end.
2220 ##
2221 #Const kSquare_Cap 2
Cary Clark682c58d2018-05-16 07:07:07 -04002222 #Line # adds square ##
Cary Clark8032b982017-07-28 11:04:54 -04002223 Adds a square with sides equal to Stroke_Width at the beginning
2224 and end. The square sides are parallel to the initial and final direction
2225 of the stroke.
2226 ##
2227 #Const kLast_Cap 2
Cary Clark682c58d2018-05-16 07:07:07 -04002228 #Line # largest Stroke_Cap value ##
Cary Clark8032b982017-07-28 11:04:54 -04002229 Equivalent to the largest value for Stroke_Cap.
2230 ##
2231 #Const kDefault_Cap 0
Cary Clark682c58d2018-05-16 07:07:07 -04002232 #Line # equivalent to kButt_Cap ##
Cary Clark8032b982017-07-28 11:04:54 -04002233 Stroke_Cap is set to kButt_Cap by default.
2234 ##
2235
2236 #Const kCapCount 3
Cary Clark682c58d2018-05-16 07:07:07 -04002237 #Line # number of different Stroke_Cap values defined ##
Cary Clark8032b982017-07-28 11:04:54 -04002238 May be used to verify that Stroke_Cap is a legal value.
2239 ##
2240#Enum ##
2241
Herb Derbyfcac00f2018-05-01 11:57:56 -04002242Stroke describes the area covered by a pen of Stroke_Width as it
Cary Clarkbc5697d2017-10-04 14:31:33 -04002243follows the Path_Contour, moving parallel to the contour direction.
Cary Clark8032b982017-07-28 11:04:54 -04002244
2245If the Path_Contour is not terminated by SkPath::kClose_Verb, the contour has a
2246visible beginning and end.
2247
2248Path_Contour may start and end at the same point; defining Zero_Length_Contour.
2249
2250kButt_Cap and Zero_Length_Contour is not drawn.
Herb Derbyfcac00f2018-05-01 11:57:56 -04002251kRound_Cap and Zero_Length_Contour draws a circle of diameter Stroke_Width
Cary Clark8032b982017-07-28 11:04:54 -04002252at the contour point.
2253kSquare_Cap and Zero_Length_Contour draws an upright square with a side of
2254Stroke_Width at the contour point.
2255
2256Stroke_Cap is kButt_Cap by default.
2257
2258#Example
Cary Clark2ade9972017-11-02 17:49:34 -04002259#Height 200
Cary Clark8032b982017-07-28 11:04:54 -04002260 SkPaint paint;
2261 paint.setStyle(SkPaint::kStroke_Style);
2262 paint.setStrokeWidth(20);
2263 SkPath path;
2264 path.moveTo(30, 30);
2265 path.lineTo(30, 30);
2266 path.moveTo(70, 30);
2267 path.lineTo(90, 40);
2268 for (SkPaint::Cap c : { SkPaint::kButt_Cap, SkPaint::kRound_Cap, SkPaint::kSquare_Cap } ) {
2269 paint.setStrokeCap(c);
2270 canvas->drawPath(path, paint);
2271 canvas->translate(0, 70);
2272 }
2273##
2274
2275#Method Cap getStrokeCap() const
2276
Cary Clarkab2621d2018-01-30 10:08:57 -05002277#In Stroke_Cap
2278#Line # returns Cap, the area drawn at path ends ##
Cary Clark80247e52018-07-11 16:18:41 -04002279 Returns the geometry drawn at the beginning and end of strokes.
Cary Clark8032b982017-07-28 11:04:54 -04002280
2281 #Return one of: kButt_Cap, kRound_Cap, kSquare_Cap ##
2282
2283 #Example
2284 SkPaint paint;
2285 SkDebugf("kButt_Cap %c= default stroke cap\n",
2286 SkPaint::kButt_Cap == paint.getStrokeCap() ? '=' : '!');
2287
2288 #StdOut
2289 kButt_Cap == default stroke cap
2290 ##
2291 ##
2292
2293 #SeeAlso Stroke_Cap setStrokeCap
2294##
2295
2296#Method void setStrokeCap(Cap cap)
2297
Cary Clarkab2621d2018-01-30 10:08:57 -05002298#In Stroke_Cap
2299#Line # sets Cap, the area drawn at path ends ##
Cary Clark80247e52018-07-11 16:18:41 -04002300 Sets the geometry drawn at the beginning and end of strokes.
Cary Clark8032b982017-07-28 11:04:54 -04002301
2302 #Param cap one of: kButt_Cap, kRound_Cap, kSquare_Cap;
2303 has no effect if cap is not valid
Herb Derbyfcac00f2018-05-01 11:57:56 -04002304 ##
Cary Clark8032b982017-07-28 11:04:54 -04002305
2306 #Example
2307 SkPaint paint;
2308 paint.setStrokeCap(SkPaint::kRound_Cap);
2309 paint.setStrokeCap((SkPaint::Cap) SkPaint::kCapCount);
2310 SkDebugf("kRound_Cap %c= paint.getStrokeCap()\n",
2311 SkPaint::kRound_Cap == paint.getStrokeCap() ? '=' : '!');
Herb Derbyfcac00f2018-05-01 11:57:56 -04002312
Cary Clark8032b982017-07-28 11:04:54 -04002313 #StdOut
2314 kRound_Cap == paint.getStrokeCap()
2315 ##
2316 ##
2317
2318 #SeeAlso Stroke_Cap getStrokeCap
2319##
2320
Cary Clark08895c42018-02-01 09:37:32 -05002321#Subtopic Stroke_Cap ##
Cary Clark8032b982017-07-28 11:04:54 -04002322# ------------------------------------------------------------------------------
Cary Clark08895c42018-02-01 09:37:32 -05002323#Subtopic Stroke_Join
2324#Line # decoration at corners of strokes ##
Cary Clark8032b982017-07-28 11:04:54 -04002325
2326Stroke_Join draws at the sharp corners of an open or closed Path_Contour.
2327
Herb Derbyfcac00f2018-05-01 11:57:56 -04002328Stroke describes the area covered by a pen of Stroke_Width as it
Cary Clarkbc5697d2017-10-04 14:31:33 -04002329follows the Path_Contour, moving parallel to the contour direction.
Cary Clark8032b982017-07-28 11:04:54 -04002330
2331If the contour direction changes abruptly, because the tangent direction leading
2332to the end of a curve within the contour does not match the tangent direction of
2333the following curve, the pair of curves meet at Stroke_Join.
2334
2335#Example
Cary Clark2ade9972017-11-02 17:49:34 -04002336#Height 200
Cary Clarka560c472017-11-27 10:44:06 -05002337 SkPaint paint;
2338 paint.setStyle(SkPaint::kStroke_Style);
2339 paint.setStrokeWidth(20);
2340 SkPath path;
2341 path.moveTo(30, 20);
2342 path.lineTo(40, 40);
2343 path.conicTo(70, 20, 100, 20, .707f);
2344 for (SkPaint::Join j : { SkPaint::kMiter_Join, SkPaint::kRound_Join, SkPaint::kBevel_Join } ) {
2345 paint.setStrokeJoin(j);
2346 canvas->drawPath(path, paint);
2347 canvas->translate(0, 70);
2348 }
Cary Clark8032b982017-07-28 11:04:54 -04002349##
2350
2351#Enum Join
Cary Clark08895c42018-02-01 09:37:32 -05002352#Line # corner geometry on stroked shapes ##
Cary Clark8032b982017-07-28 11:04:54 -04002353#Code
2354 enum Join {
2355 kMiter_Join,
2356 kRound_Join,
2357 kBevel_Join,
2358
2359 kLast_Join = kBevel_Join,
Cary Clarkbad5ad72017-08-03 17:14:08 -04002360 kDefault_Join = kMiter_Join,
Cary Clark8032b982017-07-28 11:04:54 -04002361 };
Cary Clark6fc50412017-09-21 12:31:06 -04002362
Cary Clark8032b982017-07-28 11:04:54 -04002363 static constexpr int kJoinCount = kLast_Join + 1;
2364##
2365
Cary Clark1eace2d2017-07-31 07:52:43 -04002366Join specifies how corners are drawn when a shape is stroked. Join
Cary Clark8032b982017-07-28 11:04:54 -04002367affects the four corners of a stroked rectangle, and the connected segments in a
2368stroked path.
2369
2370Choose miter join to draw sharp corners. Choose round join to draw a circle with a
2371radius equal to the stroke width on top of the corner. Choose bevel join to minimally
2372connect the thick strokes.
2373
Herb Derbyfcac00f2018-05-01 11:57:56 -04002374The fill path constructed to describe the stroked path respects the join setting but may
Cary Clark8032b982017-07-28 11:04:54 -04002375not contain the actual join. For instance, a fill path constructed with round joins does
2376not necessarily include circles at each connected segment.
2377
2378#Const kMiter_Join 0
Cary Clark682c58d2018-05-16 07:07:07 -04002379#Line # extends to Miter_Limit ##
Cary Clark8032b982017-07-28 11:04:54 -04002380 Extends the outside corner to the extent allowed by Miter_Limit.
2381 If the extension exceeds Miter_Limit, kBevel_Join is used instead.
2382##
2383
2384#Const kRound_Join 1
Cary Clark682c58d2018-05-16 07:07:07 -04002385#Line # adds circle ##
Cary Clark8032b982017-07-28 11:04:54 -04002386 Adds a circle with a diameter of Stroke_Width at the sharp corner.
2387##
2388
2389#Const kBevel_Join 2
Cary Clark682c58d2018-05-16 07:07:07 -04002390#Line # connects outside edges ##
Cary Clark8032b982017-07-28 11:04:54 -04002391 Connects the outside edges of the sharp corner.
2392##
2393
2394#Const kLast_Join 2
Cary Clark682c58d2018-05-16 07:07:07 -04002395#Line # equivalent to the largest value for Stroke_Join ##
Cary Clark8032b982017-07-28 11:04:54 -04002396##
2397
2398#Const kDefault_Join 1
Cary Clark682c58d2018-05-16 07:07:07 -04002399#Line # equivalent to kMiter_Join ##
Herb Derbyfcac00f2018-05-01 11:57:56 -04002400 Stroke_Join is set to kMiter_Join by default.
Cary Clark8032b982017-07-28 11:04:54 -04002401##
2402
2403#Const kJoinCount 3
Cary Clark682c58d2018-05-16 07:07:07 -04002404#Line # number of different Stroke_Join values defined ##
Cary Clark8032b982017-07-28 11:04:54 -04002405 May be used to verify that Stroke_Join is a legal value.
2406##
2407
2408#Example
2409#Width 462
2410void draw(SkCanvas* canvas) {
2411 SkPath path;
2412 path.moveTo(10, 50);
2413 path.quadTo(35, 110, 60, 210);
2414 path.quadTo(105, 110, 130, 10);
2415 SkPaint paint; // set to default kMiter_Join
2416 paint.setAntiAlias(true);
2417 paint.setStyle(SkPaint::kStroke_Style);
2418 paint.setStrokeWidth(20);
2419 canvas->drawPath(path, paint);
2420 canvas->translate(150, 0);
2421 paint.setStrokeJoin(SkPaint::kBevel_Join);
2422 canvas->drawPath(path, paint);
2423 canvas->translate(150, 0);
2424 paint.setStrokeJoin(SkPaint::kRound_Join);
2425 canvas->drawPath(path, paint);
2426}
2427##
2428
2429#SeeAlso setStrokeJoin getStrokeJoin setStrokeMiter getStrokeMiter
2430
2431#Enum ##
2432
2433#Method Join getStrokeJoin() const
2434
Cary Clarkab2621d2018-01-30 10:08:57 -05002435#In Stroke_Join
2436#Line # returns Join, geometry on path corners ##
Cary Clark80247e52018-07-11 16:18:41 -04002437 Returns the geometry drawn at the corners of strokes.
Cary Clark8032b982017-07-28 11:04:54 -04002438
2439 #Return one of: kMiter_Join, kRound_Join, kBevel_Join ##
2440
2441 #Example
2442 SkPaint paint;
2443 SkDebugf("kMiter_Join %c= default stroke join\n",
2444 SkPaint::kMiter_Join == paint.getStrokeJoin() ? '=' : '!');
2445
2446 #StdOut
2447 kMiter_Join == default stroke join
2448 ##
2449 ##
2450
2451 #SeeAlso Stroke_Join setStrokeJoin
2452##
2453
2454#Method void setStrokeJoin(Join join)
2455
Cary Clarkab2621d2018-01-30 10:08:57 -05002456#In Stroke_Join
2457#Line # sets Join, geometry on path corners ##
Cary Clark80247e52018-07-11 16:18:41 -04002458 Sets the geometry drawn at the corners of strokes.
Cary Clark8032b982017-07-28 11:04:54 -04002459
2460 #Param join one of: kMiter_Join, kRound_Join, kBevel_Join;
Herb Derbyfcac00f2018-05-01 11:57:56 -04002461 otherwise, has no effect
Cary Clark8032b982017-07-28 11:04:54 -04002462 ##
2463
2464 #Example
2465 SkPaint paint;
2466 paint.setStrokeJoin(SkPaint::kMiter_Join);
2467 paint.setStrokeJoin((SkPaint::Join) SkPaint::kJoinCount);
2468 SkDebugf("kMiter_Join %c= paint.getStrokeJoin()\n",
2469 SkPaint::kMiter_Join == paint.getStrokeJoin() ? '=' : '!');
2470
2471 #StdOut
2472 kMiter_Join == paint.getStrokeJoin()
2473 ##
2474 ##
2475
2476 #SeeAlso Stroke_Join getStrokeJoin
2477##
2478
2479#SeeAlso Miter_Limit
2480
Cary Clark08895c42018-02-01 09:37:32 -05002481#Subtopic Stroke_Join ##
Cary Clark8032b982017-07-28 11:04:54 -04002482# ------------------------------------------------------------------------------
Cary Clark08895c42018-02-01 09:37:32 -05002483#Subtopic Fill_Path
2484#Line # make Path from Path_Effect, stroking ##
Cary Clark8032b982017-07-28 11:04:54 -04002485
2486Fill_Path creates a Path by applying the Path_Effect, followed by the Style_Stroke.
2487
2488If Paint contains Path_Effect, Path_Effect operates on the source Path; the result
2489replaces the destination Path. Otherwise, the source Path is replaces the
2490destination Path.
2491
2492Fill Path can request the Path_Effect to restrict to a culling rectangle, but
2493the Path_Effect is not required to do so.
2494
Herb Derbyfcac00f2018-05-01 11:57:56 -04002495If Style is kStroke_Style or kStrokeAndFill_Style,
Cary Clark8032b982017-07-28 11:04:54 -04002496and Stroke_Width is greater than zero, the Stroke_Width, Stroke_Cap, Stroke_Join,
2497and Miter_Limit operate on the destination Path, replacing it.
2498
Herb Derbyfcac00f2018-05-01 11:57:56 -04002499Fill Path can specify the precision used by Stroke_Width to approximate the stroke geometry.
Cary Clark8032b982017-07-28 11:04:54 -04002500
2501If the Style is kStroke_Style and the Stroke_Width is zero, getFillPath
2502returns false since Hairline has no filled equivalent.
2503
2504#Method bool getFillPath(const SkPath& src, SkPath* dst, const SkRect* cullRect,
2505 SkScalar resScale = 1) const
Cary Clarkab2621d2018-01-30 10:08:57 -05002506#In Fill_Path
2507#Line # returns fill path equivalent to stroke ##
Cary Clark8032b982017-07-28 11:04:54 -04002508
Cary Clark80247e52018-07-11 16:18:41 -04002509 Returns the filled equivalent of the stroked path.
Cary Clark8032b982017-07-28 11:04:54 -04002510
2511 #Param src Path read to create a filled version ##
2512 #Param dst resulting Path; may be the same as src, but may not be nullptr ##
2513 #Param cullRect optional limit passed to Path_Effect ##
2514 #Param resScale if > 1, increase precision, else if (0 < res < 1) reduce precision
2515 to favor speed and size
2516 ##
2517 #Return true if the path represents Style_Fill, or false if it represents Hairline ##
2518
2519 #Example
2520 #Height 192
2521 #Description
Cary Clarkce101242017-09-01 15:51:02 -04002522 A very small Quad stroke is turned into a filled path with increasing levels of precision.
Herb Derbyfcac00f2018-05-01 11:57:56 -04002523 At the lowest precision, the Quad stroke is approximated by a rectangle.
Cary Clark8032b982017-07-28 11:04:54 -04002524 At the highest precision, the filled path has high fidelity compared to the original stroke.
2525 ##
2526 void draw(SkCanvas* canvas) {
2527 SkPaint strokePaint;
2528 strokePaint.setAntiAlias(true);
2529 strokePaint.setStyle(SkPaint::kStroke_Style);
2530 strokePaint.setStrokeWidth(.1f);
2531 SkPath strokePath;
2532 strokePath.moveTo(.08f, .08f);
2533 strokePath.quadTo(.09f, .08f, .17f, .17f);
2534 SkPath fillPath;
2535 SkPaint outlinePaint(strokePaint);
2536 outlinePaint.setStrokeWidth(2);
2537 SkMatrix scale = SkMatrix::MakeScale(300, 300);
2538 for (SkScalar precision : { 0.01f, .1f, 1.f, 10.f, 100.f } ) {
2539 strokePaint.getFillPath(strokePath, &fillPath, nullptr, precision);
2540 fillPath.transform(scale);
2541 canvas->drawPath(fillPath, outlinePaint);
2542 canvas->translate(60, 0);
2543 if (1.f == precision) canvas->translate(-180, 100);
2544 }
2545 strokePath.transform(scale);
2546 strokePaint.setStrokeWidth(30);
2547 canvas->drawPath(strokePath, strokePaint);
2548 }
2549 ##
2550
2551##
2552
2553#Method bool getFillPath(const SkPath& src, SkPath* dst) const
2554
Cary Clarkab2621d2018-01-30 10:08:57 -05002555#In Fill_Path
Cary Clark80247e52018-07-11 16:18:41 -04002556 Returns the filled equivalent of the stroked path.
Cary Clark8032b982017-07-28 11:04:54 -04002557
2558 Replaces dst with the src path modified by Path_Effect and Style_Stroke.
2559 Path_Effect, if any, is not culled. Stroke_Width is created with default precision.
2560
2561 #Param src Path read to create a filled version ##
2562 #Param dst resulting Path dst may be the same as src, but may not be nullptr ##
2563 #Return true if the path represents Style_Fill, or false if it represents Hairline ##
2564
2565 #Example
2566 #Height 128
2567 void draw(SkCanvas* canvas) {
2568 SkPaint paint;
2569 paint.setStyle(SkPaint::kStroke_Style);
2570 paint.setStrokeWidth(10);
2571 SkPath strokePath;
2572 strokePath.moveTo(20, 20);
2573 strokePath.lineTo(100, 100);
2574 canvas->drawPath(strokePath, paint);
2575 SkPath fillPath;
2576 paint.getFillPath(strokePath, &fillPath);
2577 paint.setStrokeWidth(2);
2578 canvas->translate(40, 0);
2579 canvas->drawPath(fillPath, paint);
2580 }
2581 ##
2582
2583##
2584
2585#SeeAlso Style_Stroke Stroke_Width Path_Effect
2586
Cary Clark08895c42018-02-01 09:37:32 -05002587#Subtopic Fill_Path ##
Cary Clark8032b982017-07-28 11:04:54 -04002588# ------------------------------------------------------------------------------
Cary Clark08895c42018-02-01 09:37:32 -05002589#Subtopic Shader_Methods
2590#Line # get and set Shader ##
Cary Clark8032b982017-07-28 11:04:54 -04002591
2592Shader defines the colors used when drawing a shape.
2593Shader may be an image, a gradient, or a computed fill.
Herb Derbyfcac00f2018-05-01 11:57:56 -04002594If Paint has no Shader, then Color fills the shape.
Cary Clark8032b982017-07-28 11:04:54 -04002595
2596Shader is modulated by Color_Alpha component of Color.
2597If Shader object defines only Color_Alpha, then Color modulated by Color_Alpha describes
2598the fill.
2599
2600The drawn transparency can be modified without altering Shader, by changing Color_Alpha.
2601
2602#Example
2603void draw(SkCanvas* canvas) {
2604 SkPaint paint;
2605 SkPoint center = { 50, 50 };
2606 SkScalar radius = 50;
2607 const SkColor colors[] = { 0xFFFFFFFF, 0xFF000000 };
2608 paint.setShader(SkGradientShader::MakeRadial(center, radius, colors,
2609 nullptr, SK_ARRAY_COUNT(colors), SkShader::kClamp_TileMode));
2610 for (SkScalar a : { 0.3f, 0.6f, 1.0f } ) {
2611 paint.setAlpha((int) (a * 255));
2612 canvas->drawCircle(center.fX, center.fY, radius, paint);
2613 canvas->translate(70, 70);
2614 }
2615}
2616##
2617
2618If Shader generates only Color_Alpha then all components of Color modulate the output.
2619
2620#Example
2621void draw(SkCanvas* canvas) {
2622 SkPaint paint;
2623 SkBitmap bitmap;
2624 bitmap.setInfo(SkImageInfo::MakeA8(5, 1), 5); // bitmap only contains alpha
2625 uint8_t pixels[5] = { 0x22, 0x55, 0x88, 0xBB, 0xFF };
2626 bitmap.setPixels(pixels);
Herb Derbyfcac00f2018-05-01 11:57:56 -04002627 paint.setShader(SkShader::MakeBitmapShader(bitmap,
Cary Clark8032b982017-07-28 11:04:54 -04002628 SkShader::kMirror_TileMode, SkShader::kMirror_TileMode));
2629 for (SkColor c : { SK_ColorRED, SK_ColorBLUE, SK_ColorGREEN } ) {
2630 paint.setColor(c); // all components in color affect shader
2631 canvas->drawCircle(50, 50, 50, paint);
2632 canvas->translate(70, 70);
2633 }
2634}
2635##
2636
2637#Method SkShader* getShader() const
2638
Cary Clarkab2621d2018-01-30 10:08:57 -05002639#In Shader_Methods
2640#Line # returns Shader, multiple drawing colors; gradients ##
Cary Clark80247e52018-07-11 16:18:41 -04002641 Returns optional colors used when filling a path, such as a gradient.
Cary Clark8032b982017-07-28 11:04:54 -04002642
2643 Does not alter Shader Reference_Count.
Herb Derbyfcac00f2018-05-01 11:57:56 -04002644
Cary Clark8032b982017-07-28 11:04:54 -04002645 #Return Shader if previously set, nullptr otherwise ##
2646
2647 #Example
2648 void draw(SkCanvas* canvas) {
2649 SkPaint paint;
2650 SkDebugf("nullptr %c= shader\n", paint.getShader() ? '!' : '=');
2651 paint.setShader(SkShader::MakeEmptyShader());
2652 SkDebugf("nullptr %c= shader\n", paint.getShader() ? '!' : '=');
2653 }
2654
2655 #StdOut
2656 nullptr == shader
2657 nullptr != shader
2658 ##
2659 ##
2660
2661##
2662
2663#Method sk_sp<SkShader> refShader() const
2664
Cary Clarkab2621d2018-01-30 10:08:57 -05002665#In Shader_Methods
2666#Line # references Shader, multiple drawing colors; gradients ##
Cary Clark80247e52018-07-11 16:18:41 -04002667 Returns optional colors used when filling a path, such as a gradient.
Cary Clark8032b982017-07-28 11:04:54 -04002668
2669 Increases Shader Reference_Count by one.
2670
2671 #Return Shader if previously set, nullptr otherwise ##
2672
2673 #Example
2674 void draw(SkCanvas* canvas) {
2675 SkPaint paint1, paint2;
2676 paint1.setShader(SkShader::MakeEmptyShader());
2677 SkDebugf("shader unique: %s\n", paint1.getShader()->unique() ? "true" : "false");
2678 paint2.setShader(paint1.refShader());
2679 SkDebugf("shader unique: %s\n", paint1.getShader()->unique() ? "true" : "false");
2680 }
2681
2682 #StdOut
2683 shader unique: true
2684 shader unique: false
2685 ##
2686 ##
2687
2688##
2689
2690#Method void setShader(sk_sp<SkShader> shader)
2691
Cary Clarkab2621d2018-01-30 10:08:57 -05002692#In Shader_Methods
2693#Line # sets Shader, multiple drawing colors; gradients ##
Cary Clark80247e52018-07-11 16:18:41 -04002694 Sets optional colors used when filling a path, such as a gradient.
Cary Clark8032b982017-07-28 11:04:54 -04002695
Cary Clarkd0530ba2017-09-14 11:25:39 -04002696 Sets Shader to shader, decreasing Reference_Count of the previous Shader.
Cary Clark6fc50412017-09-21 12:31:06 -04002697 Increments shader Reference_Count by one.
Cary Clark8032b982017-07-28 11:04:54 -04002698
2699 #Param shader how geometry is filled with color; if nullptr, Color is used instead ##
2700
2701 #Example
2702 #Height 64
2703 void draw(SkCanvas* canvas) {
2704 SkPaint paint;
2705 paint.setColor(SK_ColorBLUE);
2706 paint.setShader(SkShader::MakeColorShader(SK_ColorRED));
2707 canvas->drawRect(SkRect::MakeWH(40, 40), paint);
2708 paint.setShader(nullptr);
2709 canvas->translate(50, 0);
2710 canvas->drawRect(SkRect::MakeWH(40, 40), paint);
2711 }
2712 ##
2713
2714##
2715
Cary Clark08895c42018-02-01 09:37:32 -05002716#Subtopic Shader_Methods ##
Cary Clark8032b982017-07-28 11:04:54 -04002717# ------------------------------------------------------------------------------
Cary Clark08895c42018-02-01 09:37:32 -05002718#Subtopic Color_Filter_Methods
2719#Line # get and set Color_Filter ##
Cary Clark8032b982017-07-28 11:04:54 -04002720
2721Color_Filter alters the color used when drawing a shape.
2722Color_Filter may apply Blend_Mode, transform the color through a matrix, or composite multiple filters.
2723If Paint has no Color_Filter, the color is unaltered.
2724
2725The drawn transparency can be modified without altering Color_Filter, by changing Color_Alpha.
2726
2727#Example
2728#Height 128
2729void draw(SkCanvas* canvas) {
2730 SkPaint paint;
2731 paint.setColorFilter(SkColorMatrixFilter::MakeLightingFilter(0xFFFFFF, 0xFF0000));
2732 for (SkColor c : { SK_ColorBLACK, SK_ColorGREEN } ) {
2733 paint.setColor(c);
2734 canvas->drawRect(SkRect::MakeXYWH(10, 10, 50, 50), paint);
2735 paint.setAlpha(0x80);
2736 canvas->drawRect(SkRect::MakeXYWH(60, 60, 50, 50), paint);
2737 canvas->translate(100, 0);
2738 }
2739}
2740##
2741
2742#Method SkColorFilter* getColorFilter() const
2743
Cary Clarkab2621d2018-01-30 10:08:57 -05002744#In Color_Filter_Methods
2745#Line # returns Color_Filter, how colors are altered ##
Cary Clark8032b982017-07-28 11:04:54 -04002746 Returns Color_Filter if set, or nullptr.
2747 Does not alter Color_Filter Reference_Count.
Herb Derbyfcac00f2018-05-01 11:57:56 -04002748
Cary Clark8032b982017-07-28 11:04:54 -04002749 #Return Color_Filter if previously set, nullptr otherwise ##
2750
2751 #Example
2752 void draw(SkCanvas* canvas) {
2753 SkPaint paint;
2754 SkDebugf("nullptr %c= color filter\n", paint.getColorFilter() ? '!' : '=');
2755 paint.setColorFilter(SkColorFilter::MakeModeFilter(SK_ColorLTGRAY, SkBlendMode::kSrcIn));
2756 SkDebugf("nullptr %c= color filter\n", paint.getColorFilter() ? '!' : '=');
2757 }
2758
2759 #StdOut
2760 nullptr == color filter
2761 nullptr != color filter
2762 ##
2763 ##
2764##
2765
2766#Method sk_sp<SkColorFilter> refColorFilter() const
2767
Cary Clarkab2621d2018-01-30 10:08:57 -05002768#In Color_Filter_Methods
2769#Line # references Color_Filter, how colors are altered ##
Cary Clark8032b982017-07-28 11:04:54 -04002770 Returns Color_Filter if set, or nullptr.
2771 Increases Color_Filter Reference_Count by one.
2772
2773 #Return Color_Filter if set, or nullptr ##
2774
2775 #Example
2776 void draw(SkCanvas* canvas) {
2777 SkPaint paint1, paint2;
2778 paint1.setColorFilter(SkColorFilter::MakeModeFilter(0xFFFF0000, SkBlendMode::kSrcATop));
2779 SkDebugf("color filter unique: %s\n", paint1.getColorFilter()->unique() ? "true" : "false");
2780 paint2.setColorFilter(paint1.refColorFilter());
2781 SkDebugf("color filter unique: %s\n", paint1.getColorFilter()->unique() ? "true" : "false");
2782 }
2783
2784 #StdOut
2785 color filter unique: true
2786 color filter unique: false
2787 ##
2788 ##
2789##
2790
2791#Method void setColorFilter(sk_sp<SkColorFilter> colorFilter)
2792
Cary Clarkab2621d2018-01-30 10:08:57 -05002793#In Color_Filter_Methods
2794#Line # sets Color_Filter, alters color ##
Cary Clark6fc50412017-09-21 12:31:06 -04002795Sets Color_Filter to filter, decreasing Reference_Count of the previous
2796Color_Filter. Pass nullptr to clear Color_Filter.
2797
2798Increments filter Reference_Count by one.
Cary Clark8032b982017-07-28 11:04:54 -04002799
2800 #Param colorFilter Color_Filter to apply to subsequent draw ##
2801
2802 #Example
2803 #Height 64
2804 void draw(SkCanvas* canvas) {
2805 SkPaint paint;
2806 paint.setColorFilter(SkColorFilter::MakeModeFilter(SK_ColorLTGRAY, SkBlendMode::kSrcIn));
2807 canvas->drawRect(SkRect::MakeWH(50, 50), paint);
2808 paint.setColorFilter(nullptr);
2809 canvas->translate(70, 0);
2810 canvas->drawRect(SkRect::MakeWH(50, 50), paint);
2811 }
2812 ##
2813
2814##
2815
Cary Clark08895c42018-02-01 09:37:32 -05002816#Subtopic Color_Filter_Methods ##
Cary Clark8032b982017-07-28 11:04:54 -04002817# ------------------------------------------------------------------------------
Cary Clark08895c42018-02-01 09:37:32 -05002818#Subtopic Blend_Mode_Methods
2819#Line # get and set Blend_Mode ##
Cary Clark8032b982017-07-28 11:04:54 -04002820
2821Blend_Mode describes how Color combines with the destination color.
2822The default setting, SkBlendMode::kSrcOver, draws the source color
2823over the destination color.
2824
2825#Example
2826void draw(SkCanvas* canvas) {
2827 SkPaint normal, blender;
2828 normal.setColor(0xFF58a889);
2829 blender.setColor(0xFF8958a8);
2830 canvas->clear(0);
2831 for (SkBlendMode m : { SkBlendMode::kSrcOver, SkBlendMode::kSrcIn, SkBlendMode::kSrcOut } ) {
2832 normal.setBlendMode(SkBlendMode::kSrcOver);
2833 canvas->drawOval(SkRect::MakeXYWH(30, 30, 30, 80), normal);
2834 blender.setBlendMode(m);
2835 canvas->drawOval(SkRect::MakeXYWH(10, 50, 80, 30), blender);
2836 canvas->translate(70, 70);
2837 }
2838}
2839##
2840
2841#SeeAlso Blend_Mode
2842
2843#Method SkBlendMode getBlendMode() const
2844
Cary Clarkab2621d2018-01-30 10:08:57 -05002845#In Blend_Mode_Methods
2846#Line # returns Blend_Mode, how colors combine with Device ##
Cary Clark8032b982017-07-28 11:04:54 -04002847 Returns Blend_Mode.
Cary Clark579985c2017-07-31 11:48:27 -04002848 By default, returns SkBlendMode::kSrcOver.
Cary Clark8032b982017-07-28 11:04:54 -04002849
2850 #Return mode used to combine source color with destination color ##
2851
2852 #Example
2853 void draw(SkCanvas* canvas) {
2854 SkPaint paint;
Herb Derbyfcac00f2018-05-01 11:57:56 -04002855 SkDebugf("kSrcOver %c= getBlendMode\n",
Cary Clark8032b982017-07-28 11:04:54 -04002856 SkBlendMode::kSrcOver == paint.getBlendMode() ? '=' : '!');
2857 paint.setBlendMode(SkBlendMode::kSrc);
Herb Derbyfcac00f2018-05-01 11:57:56 -04002858 SkDebugf("kSrcOver %c= getBlendMode\n",
Cary Clark8032b982017-07-28 11:04:54 -04002859 SkBlendMode::kSrcOver == paint.getBlendMode() ? '=' : '!');
2860 }
2861
2862 #StdOut
2863 kSrcOver == getBlendMode
2864 kSrcOver != getBlendMode
2865 ##
2866 ##
2867
2868##
2869
2870#Method bool isSrcOver() const
2871
Cary Clarkab2621d2018-01-30 10:08:57 -05002872#In Blend_Mode_Methods
2873#Line # returns true if Blend_Mode is SkBlendMode::kSrcOver ##
Cary Clark8032b982017-07-28 11:04:54 -04002874 Returns true if Blend_Mode is SkBlendMode::kSrcOver, the default.
2875
2876 #Return true if Blend_Mode is SkBlendMode::kSrcOver ##
2877
2878 #Example
2879 void draw(SkCanvas* canvas) {
2880 SkPaint paint;
2881 SkDebugf("isSrcOver %c= true\n", paint.isSrcOver() ? '=' : '!');
2882 paint.setBlendMode(SkBlendMode::kSrc);
2883 SkDebugf("isSrcOver %c= true\n", paint.isSrcOver() ? '=' : '!');
2884 }
2885
2886 #StdOut
2887 isSrcOver == true
2888 isSrcOver != true
2889 ##
2890 ##
2891
2892##
2893
2894#Method void setBlendMode(SkBlendMode mode)
2895
Cary Clarkab2621d2018-01-30 10:08:57 -05002896#In Blend_Mode_Methods
2897#Line # sets Blend_Mode, how colors combine with destination ##
Herb Derbyfcac00f2018-05-01 11:57:56 -04002898 Sets Blend_Mode to mode.
Cary Clark8032b982017-07-28 11:04:54 -04002899 Does not check for valid input.
2900
2901 #Param mode SkBlendMode used to combine source color and destination ##
2902
2903 #Example
2904 void draw(SkCanvas* canvas) {
2905 SkPaint paint;
2906 SkDebugf("isSrcOver %c= true\n", paint.isSrcOver() ? '=' : '!');
2907 paint.setBlendMode(SkBlendMode::kSrc);
2908 SkDebugf("isSrcOver %c= true\n", paint.isSrcOver() ? '=' : '!');
2909 }
2910
2911 #StdOut
2912 isSrcOver == true
2913 isSrcOver != true
2914 ##
2915 ##
2916
2917##
2918
Cary Clark08895c42018-02-01 09:37:32 -05002919#Subtopic Blend_Mode_Methods ##
Cary Clark8032b982017-07-28 11:04:54 -04002920# ------------------------------------------------------------------------------
Cary Clark08895c42018-02-01 09:37:32 -05002921#Subtopic Path_Effect_Methods
2922#Line # get and set Path_Effect ##
Cary Clark8032b982017-07-28 11:04:54 -04002923
2924Path_Effect modifies the path geometry before drawing it.
2925Path_Effect may implement dashing, custom fill effects and custom stroke effects.
2926If Paint has no Path_Effect, the path geometry is unaltered when filled or stroked.
2927
2928#Example
2929#Height 160
2930 void draw(SkCanvas* canvas) {
2931 SkPaint paint;
2932 paint.setStyle(SkPaint::kStroke_Style);
2933 paint.setStrokeWidth(16);
2934 SkScalar intervals[] = {30, 10};
2935 paint.setPathEffect(SkDashPathEffect::Make(intervals, SK_ARRAY_COUNT(intervals), 1));
2936 canvas->drawRoundRect({20, 20, 120, 120}, 20, 20, paint);
2937 }
2938##
2939
2940#SeeAlso Path_Effect
2941
2942#Method SkPathEffect* getPathEffect() const
2943
Cary Clarkab2621d2018-01-30 10:08:57 -05002944#In Path_Effect_Methods
2945#Line # returns Path_Effect, modifications to path geometry; dashing ##
Cary Clark8032b982017-07-28 11:04:54 -04002946 Returns Path_Effect if set, or nullptr.
2947 Does not alter Path_Effect Reference_Count.
Herb Derbyfcac00f2018-05-01 11:57:56 -04002948
Cary Clark8032b982017-07-28 11:04:54 -04002949 #Return Path_Effect if previously set, nullptr otherwise ##
2950
2951 #Example
2952 void draw(SkCanvas* canvas) {
2953 SkPaint paint;
2954 SkDebugf("nullptr %c= path effect\n", paint.getPathEffect() ? '!' : '=');
2955 paint.setPathEffect(SkCornerPathEffect::Make(10));
2956 SkDebugf("nullptr %c= path effect\n", paint.getPathEffect() ? '!' : '=');
2957 }
2958
2959 #StdOut
2960 nullptr == path effect
2961 nullptr != path effect
2962 ##
2963 ##
2964
2965##
2966
2967
2968#Method sk_sp<SkPathEffect> refPathEffect() const
2969
Cary Clarkab2621d2018-01-30 10:08:57 -05002970#In Path_Effect_Methods
2971#Line # references Path_Effect, modifications to path geometry; dashing ##
Cary Clark8032b982017-07-28 11:04:54 -04002972 Returns Path_Effect if set, or nullptr.
2973 Increases Path_Effect Reference_Count by one.
2974
2975 #Return Path_Effect if previously set, nullptr otherwise ##
2976
2977 #Example
2978 void draw(SkCanvas* canvas) {
2979 SkPaint paint1, paint2;
Cary Clarka560c472017-11-27 10:44:06 -05002980 SkScalar intervals[] = {1, 2};
2981 paint1.setPathEffect(SkDashPathEffect::Make(intervals, SK_ARRAY_COUNT(intervals), 10));
Cary Clark8032b982017-07-28 11:04:54 -04002982 SkDebugf("path effect unique: %s\n", paint1.getPathEffect()->unique() ? "true" : "false");
2983 paint2.setPathEffect(paint1.refPathEffect());
2984 SkDebugf("path effect unique: %s\n", paint1.getPathEffect()->unique() ? "true" : "false");
2985 }
2986
2987 #StdOut
2988 path effect unique: true
2989 path effect unique: false
2990 ##
2991 ##
2992
2993##
2994
2995
2996#Method void setPathEffect(sk_sp<SkPathEffect> pathEffect)
2997
Cary Clarkab2621d2018-01-30 10:08:57 -05002998#In Path_Effect_Methods
2999#Line # sets Path_Effect, modifications to path geometry; dashing ##
Cary Clark6fc50412017-09-21 12:31:06 -04003000Sets Path_Effect to pathEffect, decreasing Reference_Count of the previous
3001Path_Effect. Pass nullptr to leave the path geometry unaltered.
3002
3003Increments pathEffect Reference_Count by one.
Cary Clark8032b982017-07-28 11:04:54 -04003004
3005 #Param pathEffect replace Path with a modification when drawn ##
3006
3007 #Example
3008 void draw(SkCanvas* canvas) {
3009 SkPaint paint;
3010 paint.setPathEffect(SkDiscretePathEffect::Make(3, 5));
3011 canvas->drawRect(SkRect::MakeXYWH(40, 40, 175, 175), paint);
3012 }
3013 ##
3014
3015##
3016
Cary Clark08895c42018-02-01 09:37:32 -05003017#Subtopic Path_Effect_Methods ##
Cary Clark8032b982017-07-28 11:04:54 -04003018# ------------------------------------------------------------------------------
Cary Clark08895c42018-02-01 09:37:32 -05003019#Subtopic Mask_Filter_Methods
3020#Line # get and set Mask_Filter ##
Cary Clark8032b982017-07-28 11:04:54 -04003021
Cary Clarkce101242017-09-01 15:51:02 -04003022Mask_Filter uses coverage of the shape drawn to create Mask_Alpha.
Mike Reed8ad91a92018-01-19 19:09:32 -05003023Mask_Filter takes a Mask, and returns a Mask.
Cary Clark6fc50412017-09-21 12:31:06 -04003024
3025Mask_Filter may change the geometry and transparency of the shape, such as
3026creating a blur effect. Set Mask_Filter to nullptr to prevent Mask_Filter from
3027modifying the draw.
Cary Clark8032b982017-07-28 11:04:54 -04003028
3029#Example
3030 void draw(SkCanvas* canvas) {
3031 SkPaint paint;
Cary Clark681287e2018-03-16 11:34:15 -04003032 paint.setMaskFilter(SkMaskFilter::MakeBlur(kSolid_SkBlurStyle, 3));
Cary Clark8032b982017-07-28 11:04:54 -04003033 canvas->drawRect(SkRect::MakeXYWH(40, 40, 175, 175), paint);
3034 }
3035##
3036
3037#Method SkMaskFilter* getMaskFilter() const
3038
Cary Clarkab2621d2018-01-30 10:08:57 -05003039#In Mask_Filter_Methods
3040#Line # returns Mask_Filter, alterations to Mask_Alpha ##
Cary Clark8032b982017-07-28 11:04:54 -04003041 Returns Mask_Filter if set, or nullptr.
3042 Does not alter Mask_Filter Reference_Count.
Herb Derbyfcac00f2018-05-01 11:57:56 -04003043
Cary Clark8032b982017-07-28 11:04:54 -04003044 #Return Mask_Filter if previously set, nullptr otherwise ##
3045
3046 #Example
3047 void draw(SkCanvas* canvas) {
3048 SkPaint paint;
3049 SkDebugf("nullptr %c= mask filter\n", paint.getMaskFilter() ? '!' : '=');
Cary Clark681287e2018-03-16 11:34:15 -04003050 paint.setMaskFilter(SkMaskFilter::MakeBlur(kOuter_SkBlurStyle, 3));
Cary Clark8032b982017-07-28 11:04:54 -04003051 SkDebugf("nullptr %c= mask filter\n", paint.getMaskFilter() ? '!' : '=');
3052 }
3053
3054 #StdOut
3055 nullptr == mask filter
3056 nullptr != mask filter
3057 ##
3058 ##
3059
3060##
3061
3062#Method sk_sp<SkMaskFilter> refMaskFilter() const
3063
Cary Clarkab2621d2018-01-30 10:08:57 -05003064#In Mask_Filter_Methods
3065#Line # references Mask_Filter, alterations to Mask_Alpha ##
Cary Clark8032b982017-07-28 11:04:54 -04003066 Returns Mask_Filter if set, or nullptr.
Cary Clark6fc50412017-09-21 12:31:06 -04003067
Cary Clark8032b982017-07-28 11:04:54 -04003068 Increases Mask_Filter Reference_Count by one.
Herb Derbyfcac00f2018-05-01 11:57:56 -04003069
Cary Clark8032b982017-07-28 11:04:54 -04003070 #Return Mask_Filter if previously set, nullptr otherwise ##
3071
3072 #Example
3073 void draw(SkCanvas* canvas) {
3074 SkPaint paint1, paint2;
Cary Clark681287e2018-03-16 11:34:15 -04003075 paint1.setMaskFilter(SkMaskFilter::MakeBlur(kNormal_SkBlurStyle, 1));
Cary Clark8032b982017-07-28 11:04:54 -04003076 SkDebugf("mask filter unique: %s\n", paint1.getMaskFilter()->unique() ? "true" : "false");
3077 paint2.setMaskFilter(paint1.refMaskFilter());
3078 SkDebugf("mask filter unique: %s\n", paint1.getMaskFilter()->unique() ? "true" : "false");
3079 }
3080
3081 #StdOut
3082 mask filter unique: true
3083 mask filter unique: false
3084 ##
3085 ##
3086
3087##
3088
3089#Method void setMaskFilter(sk_sp<SkMaskFilter> maskFilter)
3090
Cary Clarkab2621d2018-01-30 10:08:57 -05003091#In Mask_Filter_Methods
3092#Line # sets Mask_Filter, alterations to Mask_Alpha ##
Cary Clark6fc50412017-09-21 12:31:06 -04003093Sets Mask_Filter to maskFilter, decreasing Reference_Count of the previous
3094Mask_Filter. Pass nullptr to clear Mask_Filter and leave Mask_Filter effect on
3095Mask_Alpha unaltered.
3096
Cary Clark6fc50412017-09-21 12:31:06 -04003097Increments maskFilter Reference_Count by one.
Cary Clark8032b982017-07-28 11:04:54 -04003098
3099 #Param maskFilter modifies clipping mask generated from drawn geometry ##
3100
3101 #Example
3102 void draw(SkCanvas* canvas) {
3103 SkPaint paint;
3104 paint.setStyle(SkPaint::kStroke_Style);
3105 paint.setStrokeWidth(10);
Cary Clark681287e2018-03-16 11:34:15 -04003106 paint.setMaskFilter(SkMaskFilter::MakeBlur(kNormal_SkBlurStyle, 10));
Cary Clark8032b982017-07-28 11:04:54 -04003107 canvas->drawRect(SkRect::MakeXYWH(40, 40, 175, 175), paint);
3108 }
3109 ##
3110
3111##
3112
Cary Clark08895c42018-02-01 09:37:32 -05003113#Subtopic Mask_Filter_Methods ##
Cary Clark8032b982017-07-28 11:04:54 -04003114# ------------------------------------------------------------------------------
Cary Clark08895c42018-02-01 09:37:32 -05003115#Subtopic Typeface_Methods
3116#Line # get and set Typeface ##
Cary Clark8032b982017-07-28 11:04:54 -04003117
3118Typeface identifies the font used when drawing and measuring text.
3119Typeface may be specified by name, from a file, or from a data stream.
3120The default Typeface defers to the platform-specific default font
3121implementation.
3122
3123#Example
3124#Height 100
3125 void draw(SkCanvas* canvas) {
3126 SkPaint paint;
Ben Wagner700ff172017-11-08 15:37:22 -05003127 paint.setTypeface(SkTypeface::MakeFromName(nullptr, SkFontStyle()));
Cary Clark8032b982017-07-28 11:04:54 -04003128 paint.setAntiAlias(true);
3129 paint.setTextSize(36);
3130 canvas->drawString("A Big Hello!", 10, 40, paint);
3131 paint.setTypeface(nullptr);
3132 paint.setFakeBoldText(true);
3133 canvas->drawString("A Big Hello!", 10, 80, paint);
3134 }
3135##
3136
3137#Method SkTypeface* getTypeface() const
3138
Cary Clarkab2621d2018-01-30 10:08:57 -05003139#In Typeface_Methods
3140#Line # returns Typeface, font description ##
Cary Clark8032b982017-07-28 11:04:54 -04003141 Returns Typeface if set, or nullptr.
Ben Wagner900b5362018-06-22 14:29:08 -04003142 Does not alter Typeface Reference_Count.
Herb Derbyfcac00f2018-05-01 11:57:56 -04003143
Cary Clark8032b982017-07-28 11:04:54 -04003144 #Return Typeface if previously set, nullptr otherwise ##
3145
3146 #Example
3147 void draw(SkCanvas* canvas) {
3148 SkPaint paint;
3149 SkDebugf("nullptr %c= typeface\n", paint.getTypeface() ? '!' : '=');
Cary Clark71961fb2018-01-05 14:21:59 -05003150 paint.setTypeface(SkTypeface::MakeFromName("monospace", SkFontStyle()));
Cary Clark8032b982017-07-28 11:04:54 -04003151 SkDebugf("nullptr %c= typeface\n", paint.getTypeface() ? '!' : '=');
3152 }
3153
3154 #StdOut
3155 nullptr == typeface
3156 nullptr != typeface
3157 ##
3158 ##
3159
3160##
3161
3162#Method sk_sp<SkTypeface> refTypeface() const
3163
Cary Clarkab2621d2018-01-30 10:08:57 -05003164#In Typeface_Methods
3165#Line # references Typeface, font description ##
Cary Clark8032b982017-07-28 11:04:54 -04003166 Increases Typeface Reference_Count by one.
3167
3168 #Return Typeface if previously set, nullptr otherwise ##
3169
3170 #Example
3171 void draw(SkCanvas* canvas) {
3172 SkPaint paint1, paint2;
Herb Derbyfcac00f2018-05-01 11:57:56 -04003173 paint1.setTypeface(SkTypeface::MakeFromName("monospace",
Cary Clark8032b982017-07-28 11:04:54 -04003174 SkFontStyle(SkFontStyle::kNormal_Weight, SkFontStyle::kNormal_Width,
3175 SkFontStyle::kItalic_Slant)));
3176 SkDebugf("typeface1 %c= typeface2\n",
3177 paint1.getTypeface() == paint2.getTypeface() ? '=' : '!');
3178 paint2.setTypeface(paint1.refTypeface());
3179 SkDebugf("typeface1 %c= typeface2\n",
3180 paint1.getTypeface() == paint2.getTypeface() ? '=' : '!');
3181 }
3182
3183 #StdOut
3184 typeface1 != typeface2
3185 typeface1 == typeface2
3186 ##
3187 ##
3188
3189##
3190
3191#Method void setTypeface(sk_sp<SkTypeface> typeface)
3192
Cary Clarkab2621d2018-01-30 10:08:57 -05003193#In Typeface_Methods
3194#Line # sets Typeface, font description ##
Herb Derbyfcac00f2018-05-01 11:57:56 -04003195Sets Typeface to typeface, decreasing Reference_Count of the previous Typeface.
Cary Clark6fc50412017-09-21 12:31:06 -04003196Pass nullptr to clear Typeface and use the default typeface. Increments
3197typeface Reference_Count by one.
Cary Clark8032b982017-07-28 11:04:54 -04003198
3199 #Param typeface font and style used to draw text ##
3200
3201 #Example
3202 #Height 64
3203 void draw(SkCanvas* canvas) {
3204 SkPaint paint;
Cary Clark71961fb2018-01-05 14:21:59 -05003205 paint.setTypeface(SkTypeface::MakeFromName("monospace", SkFontStyle()));
3206 canvas->drawString("hamburgerfons", 10, 30, paint);
Cary Clark8032b982017-07-28 11:04:54 -04003207 paint.setTypeface(nullptr);
Cary Clark71961fb2018-01-05 14:21:59 -05003208 canvas->drawString("hamburgerfons", 10, 50, paint);
Cary Clark8032b982017-07-28 11:04:54 -04003209 }
3210 ##
3211
3212##
3213
Cary Clark08895c42018-02-01 09:37:32 -05003214#Subtopic Typeface_Methods ##
Cary Clark8032b982017-07-28 11:04:54 -04003215# ------------------------------------------------------------------------------
Cary Clark08895c42018-02-01 09:37:32 -05003216#Subtopic Image_Filter_Methods
3217#Line # get and set Image_Filter ##
Cary Clark8032b982017-07-28 11:04:54 -04003218
3219Image_Filter operates on the pixel representation of the shape, as modified by Paint
3220with Blend_Mode set to SkBlendMode::kSrcOver. Image_Filter creates a new bitmap,
3221which is drawn to the device using the set Blend_Mode.
Cary Clark6fc50412017-09-21 12:31:06 -04003222
Cary Clark8032b982017-07-28 11:04:54 -04003223Image_Filter is higher level than Mask_Filter; for instance, an Image_Filter
Cary Clarkce101242017-09-01 15:51:02 -04003224can operate on all channels of Color, while Mask_Filter generates Alpha only.
Cary Clark8032b982017-07-28 11:04:54 -04003225Image_Filter operates independently of and can be used in combination with
Mike Reed8ad91a92018-01-19 19:09:32 -05003226Mask_Filter.
Cary Clark8032b982017-07-28 11:04:54 -04003227
3228#Example
3229 #ToDo explain why the two draws are so different ##
Cary Clark81abc432018-06-25 16:30:08 -04003230 #Function
3231 ###$
3232 #include "SkBlurImageFilter.h"
3233 $$$#
3234 ##
Cary Clark8032b982017-07-28 11:04:54 -04003235 void draw(SkCanvas* canvas) {
3236 SkPaint paint;
3237 paint.setStyle(SkPaint::kStroke_Style);
3238 paint.setStrokeWidth(2);
3239 SkRegion region;
3240 region.op( 10, 10, 50, 50, SkRegion::kUnion_Op);
3241 region.op( 10, 50, 90, 90, SkRegion::kUnion_Op);
Cary Clarka560c472017-11-27 10:44:06 -05003242 paint.setImageFilter(SkBlurImageFilter::Make(5.0f, 5.0f, nullptr));
Cary Clark8032b982017-07-28 11:04:54 -04003243 canvas->drawRegion(region, paint);
3244 paint.setImageFilter(nullptr);
Cary Clarka7b84c52018-03-18 11:46:54 -04003245 paint.setMaskFilter(SkMaskFilter::MakeBlur(kNormal_SkBlurStyle, 5));
Cary Clark8032b982017-07-28 11:04:54 -04003246 canvas->translate(100, 100);
3247 canvas->drawRegion(region, paint);
3248 }
3249##
3250
3251#Method SkImageFilter* getImageFilter() const
3252
Cary Clarkab2621d2018-01-30 10:08:57 -05003253#In Image_Filter_Methods
3254#Line # returns Image_Filter, alter pixels; blur ##
Cary Clark8032b982017-07-28 11:04:54 -04003255 Returns Image_Filter if set, or nullptr.
3256 Does not alter Image_Filter Reference_Count.
Herb Derbyfcac00f2018-05-01 11:57:56 -04003257
Cary Clark8032b982017-07-28 11:04:54 -04003258 #Return Image_Filter if previously set, nullptr otherwise ##
3259
3260 #Example
Cary Clark81abc432018-06-25 16:30:08 -04003261 #Function
3262 ###$
3263 #include "SkBlurImageFilter.h"
3264 $$$#
3265 ##
Cary Clark8032b982017-07-28 11:04:54 -04003266 void draw(SkCanvas* canvas) {
3267 SkPaint paint;
3268 SkDebugf("nullptr %c= image filter\n", paint.getImageFilter() ? '!' : '=');
Cary Clarka560c472017-11-27 10:44:06 -05003269 paint.setImageFilter(SkBlurImageFilter::Make(kOuter_SkBlurStyle, 3, nullptr, nullptr));
Cary Clark8032b982017-07-28 11:04:54 -04003270 SkDebugf("nullptr %c= image filter\n", paint.getImageFilter() ? '!' : '=');
3271 }
3272
3273 #StdOut
3274 nullptr == image filter
3275 nullptr != image filter
3276 ##
3277 ##
3278
3279##
3280
3281#Method sk_sp<SkImageFilter> refImageFilter() const
3282
Cary Clarkab2621d2018-01-30 10:08:57 -05003283#In Image_Filter_Methods
3284#Line # references Image_Filter, alter pixels; blur ##
Cary Clark8032b982017-07-28 11:04:54 -04003285 Returns Image_Filter if set, or nullptr.
3286 Increases Image_Filter Reference_Count by one.
3287
3288 #Return Image_Filter if previously set, nullptr otherwise ##
3289
3290 #Example
3291 void draw(SkCanvas* canvas) {
3292 SkPaint paint1, paint2;
3293 paint1.setImageFilter(SkOffsetImageFilter::Make(25, 25, nullptr));
3294 SkDebugf("image filter unique: %s\n", paint1.getImageFilter()->unique() ? "true" : "false");
3295 paint2.setImageFilter(paint1.refImageFilter());
3296 SkDebugf("image filter unique: %s\n", paint1.getImageFilter()->unique() ? "true" : "false");
3297 }
3298
3299 #StdOut
3300 image filter unique: true
3301 image filter unique: false
3302 ##
3303 ##
3304
3305##
3306
3307#Method void setImageFilter(sk_sp<SkImageFilter> imageFilter)
3308
Cary Clarkab2621d2018-01-30 10:08:57 -05003309#In Image_Filter_Methods
3310#Line # sets Image_Filter, alter pixels; blur ##
Cary Clark6fc50412017-09-21 12:31:06 -04003311Sets Image_Filter to imageFilter, decreasing Reference_Count of the previous
3312Image_Filter. Pass nullptr to clear Image_Filter, and remove Image_Filter effect
3313on drawing.
3314
Cary Clark6fc50412017-09-21 12:31:06 -04003315Increments imageFilter Reference_Count by one.
Cary Clark8032b982017-07-28 11:04:54 -04003316
3317 #Param imageFilter how Image is sampled when transformed ##
3318
3319 #Example
3320 #Height 160
3321 void draw(SkCanvas* canvas) {
3322 SkBitmap bitmap;
3323 bitmap.allocN32Pixels(100, 100);
3324 SkCanvas offscreen(bitmap);
3325 SkPaint paint;
3326 paint.setAntiAlias(true);
3327 paint.setColor(SK_ColorWHITE);
3328 paint.setTextSize(96);
3329 offscreen.clear(0);
3330 offscreen.drawString("e", 20, 70, paint);
3331 paint.setImageFilter(
3332 SkLightingImageFilter::MakePointLitDiffuse(SkPoint3::Make(80, 100, 10),
3333 SK_ColorWHITE, 1, 2, nullptr, nullptr));
3334 canvas->drawBitmap(bitmap, 0, 0, &paint);
3335 }
3336 ##
3337
3338##
3339
Cary Clark08895c42018-02-01 09:37:32 -05003340#Subtopic Image_Filter_Methods ##
Cary Clark8032b982017-07-28 11:04:54 -04003341# ------------------------------------------------------------------------------
Cary Clark08895c42018-02-01 09:37:32 -05003342#Subtopic Draw_Looper_Methods
3343#Line # get and set Draw_Looper ##
Cary Clark8032b982017-07-28 11:04:54 -04003344
3345Draw_Looper sets a modifier that communicates state from one Draw_Layer
3346to another to construct the draw.
Cary Clark6fc50412017-09-21 12:31:06 -04003347
Cary Clark8032b982017-07-28 11:04:54 -04003348Draw_Looper draws one or more times, modifying the canvas and paint each time.
3349Draw_Looper may be used to draw multiple colors or create a colored shadow.
Herb Derbyfcac00f2018-05-01 11:57:56 -04003350Set Draw_Looper to nullptr to prevent Draw_Looper from modifying the draw.
Cary Clark8032b982017-07-28 11:04:54 -04003351
3352#Example
3353#Height 128
3354 void draw(SkCanvas* canvas) {
3355 SkLayerDrawLooper::LayerInfo info;
3356 info.fPaintBits = (SkLayerDrawLooper::BitFlags) SkLayerDrawLooper::kColorFilter_Bit;
3357 info.fColorMode = SkBlendMode::kSrc;
3358 SkLayerDrawLooper::Builder looperBuilder;
3359 SkPaint* loopPaint = looperBuilder.addLayer(info);
3360 loopPaint->setColor(SK_ColorRED);
3361 info.fOffset.set(20, 20);
3362 loopPaint = looperBuilder.addLayer(info);
3363 loopPaint->setColor(SK_ColorBLUE);
3364 SkPaint paint;
3365 paint.setDrawLooper(looperBuilder.detach());
3366 canvas->drawCircle(50, 50, 50, paint);
3367 }
3368
3369##
3370
3371#Method SkDrawLooper* getDrawLooper() const
3372
Cary Clarkab2621d2018-01-30 10:08:57 -05003373#In Draw_Looper_Methods
3374#Line # returns Draw_Looper, multiple layers ##
Cary Clark8032b982017-07-28 11:04:54 -04003375 Returns Draw_Looper if set, or nullptr.
3376 Does not alter Draw_Looper Reference_Count.
Herb Derbyfcac00f2018-05-01 11:57:56 -04003377
Cary Clark8032b982017-07-28 11:04:54 -04003378 #Return Draw_Looper if previously set, nullptr otherwise ##
3379
3380 #Example
3381 void draw(SkCanvas* canvas) {
3382 SkPaint paint;
3383 SkDebugf("nullptr %c= draw looper\n", paint.getDrawLooper() ? '!' : '=');
3384 SkLayerDrawLooper::Builder looperBuilder;
3385 paint.setDrawLooper(looperBuilder.detach());
3386 SkDebugf("nullptr %c= draw looper\n", paint.getDrawLooper() ? '!' : '=');
3387 }
3388
3389 #StdOut
3390 nullptr == draw looper
3391 nullptr != draw looper
3392 ##
3393 ##
3394
3395##
3396
3397#Method sk_sp<SkDrawLooper> refDrawLooper() const
3398
Cary Clarkab2621d2018-01-30 10:08:57 -05003399#In Draw_Looper_Methods
3400#Line # references Draw_Looper, multiple layers ##
Cary Clark8032b982017-07-28 11:04:54 -04003401 Returns Draw_Looper if set, or nullptr.
3402 Increases Draw_Looper Reference_Count by one.
3403
3404 #Return Draw_Looper if previously set, nullptr otherwise ##
3405
3406 #Example
3407 void draw(SkCanvas* canvas) {
3408 SkPaint paint1, paint2;
3409 SkLayerDrawLooper::Builder looperBuilder;
3410 paint1.setDrawLooper(looperBuilder.detach());
3411 SkDebugf("draw looper unique: %s\n", paint1.getDrawLooper()->unique() ? "true" : "false");
3412 paint2.setDrawLooper(paint1.refDrawLooper());
3413 SkDebugf("draw looper unique: %s\n", paint1.getDrawLooper()->unique() ? "true" : "false");
3414 }
3415
3416 #StdOut
3417 draw looper unique: true
3418 draw looper unique: false
3419 ##
3420 ##
3421
3422##
3423
3424#Method SkDrawLooper* getLooper() const
Cary Clark4855f782018-02-06 09:41:53 -05003425#Bug 6259
Cary Clark8032b982017-07-28 11:04:54 -04003426#Deprecated
Cary Clark8032b982017-07-28 11:04:54 -04003427##
3428
3429#Method void setDrawLooper(sk_sp<SkDrawLooper> drawLooper)
Cary Clarkab2621d2018-01-30 10:08:57 -05003430#In Draw_Looper_Methods
3431#Line # sets Draw_Looper, multiple layers ##
Cary Clark6fc50412017-09-21 12:31:06 -04003432Sets Draw_Looper to drawLooper, decreasing Reference_Count of the previous
3433drawLooper. Pass nullptr to clear Draw_Looper and leave Draw_Looper effect on
3434drawing unaltered.
3435
3436Increments drawLooper Reference_Count by one.
Cary Clark8032b982017-07-28 11:04:54 -04003437
Cary Clarka523d2d2017-08-30 08:58:10 -04003438 #Param drawLooper iterates through drawing one or more time, altering Paint ##
Cary Clark8032b982017-07-28 11:04:54 -04003439
3440 #Example
3441 #Height 128
3442 void draw(SkCanvas* canvas) {
3443 SkPaint paint;
3444 paint.setDrawLooper(SkBlurDrawLooper::Make(0x7FFF0000, 4, -5, -10));
3445 paint.setStyle(SkPaint::kStroke_Style);
3446 paint.setStrokeWidth(10);
3447 paint.setAntiAlias(true);
3448 paint.setColor(0x7f0000ff);
3449 canvas->drawCircle(70, 70, 50, paint);
3450 }
3451 ##
3452
3453##
3454
3455#Method void setLooper(sk_sp<SkDrawLooper> drawLooper)
Cary Clark4855f782018-02-06 09:41:53 -05003456#Bug 6259
Cary Clark8032b982017-07-28 11:04:54 -04003457#Deprecated
Cary Clark8032b982017-07-28 11:04:54 -04003458##
3459
Cary Clark08895c42018-02-01 09:37:32 -05003460#Subtopic Draw_Looper_Methods ##
Cary Clark4855f782018-02-06 09:41:53 -05003461
Cary Clark8032b982017-07-28 11:04:54 -04003462# ------------------------------------------------------------------------------
Cary Clark08895c42018-02-01 09:37:32 -05003463#Subtopic Text_Align
3464#Line # text placement relative to position ##
Cary Clark8032b982017-07-28 11:04:54 -04003465
3466#Enum Align
Cary Clark08895c42018-02-01 09:37:32 -05003467#Line # glyph locations relative to text position ##
Cary Clark8032b982017-07-28 11:04:54 -04003468#Code
3469 enum Align {
3470 kLeft_Align,
3471 kCenter_Align,
3472 kRight_Align,
3473 };
Cary Clarkd98f78c2018-04-26 08:32:37 -04003474
3475 static constexpr int kAlignCount = 3;
Cary Clark8032b982017-07-28 11:04:54 -04003476##
3477
3478Align adjusts the text relative to the text position.
Cary Clarkce101242017-09-01 15:51:02 -04003479Align affects Glyphs drawn with: SkCanvas::drawText, SkCanvas::drawPosText,
Herb Derbyfcac00f2018-05-01 11:57:56 -04003480SkCanvas::drawPosTextH, SkCanvas::drawTextOnPath,
Cary Clark8032b982017-07-28 11:04:54 -04003481SkCanvas::drawTextOnPathHV, SkCanvas::drawTextRSXform, SkCanvas::drawTextBlob,
Herb Derbyfcac00f2018-05-01 11:57:56 -04003482and SkCanvas::drawString;
Cary Clarkce101242017-09-01 15:51:02 -04003483as well as calls that place text Glyphs like getTextWidths and getTextPath.
Cary Clark8032b982017-07-28 11:04:54 -04003484
3485The text position is set by the font for both horizontal and vertical text.
3486Typically, for horizontal text, the position is to the left side of the glyph on the
3487base line; and for vertical text, the position is the horizontal center of the glyph
3488at the caps height.
3489
Herb Derbyfcac00f2018-05-01 11:57:56 -04003490Align adjusts the glyph position to center it or move it to abut the position
Cary Clark8032b982017-07-28 11:04:54 -04003491using the metrics returned by the font.
3492
3493Align defaults to kLeft_Align.
3494
3495#Const kLeft_Align 0
Cary Clark682c58d2018-05-16 07:07:07 -04003496#Line # positions glyph by computed font offset ##
Cary Clark8032b982017-07-28 11:04:54 -04003497 Leaves the glyph at the position computed by the font offset by the text position.
3498##
3499
3500#Const kCenter_Align 1
Cary Clark682c58d2018-05-16 07:07:07 -04003501#Line # centers line of glyphs by its width or height ##
Cary Clark8032b982017-07-28 11:04:54 -04003502 Moves the glyph half its width if Flags has kVerticalText_Flag clear, and
3503 half its height if Flags has kVerticalText_Flag set.
3504##
3505
3506#Const kRight_Align 2
Cary Clark682c58d2018-05-16 07:07:07 -04003507#Line # moves lines of glyphs by its width or height ##
Cary Clark8032b982017-07-28 11:04:54 -04003508 Moves the glyph by its width if Flags has kVerticalText_Flag clear,
3509 and by its height if Flags has kVerticalText_Flag set.
3510##
3511
Cary Clark8032b982017-07-28 11:04:54 -04003512#Const kAlignCount 3
Cary Clark682c58d2018-05-16 07:07:07 -04003513#Line # number of different Text_Align values defined ##
Cary Clark137b8742018-05-30 09:21:49 -04003514May be used to verify that Align is a legal value.
Cary Clark8032b982017-07-28 11:04:54 -04003515##
3516
3517#Enum ##
3518
3519#Example
3520 #Height 160
3521 #Description
3522 Each position separately moves the glyph in drawPosText.
3523 ##
3524 void draw(SkCanvas* canvas) {
3525 SkPaint paint;
3526 paint.setTextSize(40);
3527 SkPoint position[] = {{100, 50}, {150, 40}};
3528 for (SkPaint::Align a : { SkPaint::kLeft_Align,
3529 SkPaint::kCenter_Align,
3530 SkPaint::kRight_Align}) {
3531 paint.setTextAlign(a);
3532 canvas->drawPosText("Aa", 2, position, paint);
3533 canvas->translate(0, 50);
3534 }
3535 }
3536##
3537
3538#Example
3539 #Height 160
3540 #Description
3541 Vertical_Text treats kLeft_Align as top align, and kRight_Align as bottom align.
3542 ##
3543 void draw(SkCanvas* canvas) {
3544 SkPaint paint;
3545 paint.setTextSize(40);
3546 paint.setVerticalText(true);
3547 for (SkPaint::Align a : { SkPaint::kLeft_Align,
3548 SkPaint::kCenter_Align,
3549 SkPaint::kRight_Align }) {
3550 paint.setTextAlign(a);
3551 canvas->drawString("Aa", 50, 80, paint);
3552 canvas->translate(50, 0);
3553 }
3554 }
3555##
3556
3557#Method Align getTextAlign() const
3558
Cary Clarkab2621d2018-01-30 10:08:57 -05003559#In Text_Align
3560#Line # returns Align: left, center, or right ##
Cary Clark8032b982017-07-28 11:04:54 -04003561 Returns Text_Align.
3562 Returns kLeft_Align if Text_Align has not been set.
3563
3564 #Return text placement relative to position ##
3565
3566 #Example
3567 SkPaint paint;
3568 SkDebugf("kLeft_Align %c= default\n", SkPaint::kLeft_Align == paint.getTextAlign() ? '=' : '!');
3569
3570 #StdOut
3571 kLeft_Align == default
3572 ##
3573 ##
3574##
3575
3576#Method void setTextAlign(Align align)
3577
Cary Clarkab2621d2018-01-30 10:08:57 -05003578#In Text_Align
3579#Line # sets Align: left, center, or right ##
Cary Clark8032b982017-07-28 11:04:54 -04003580 Sets Text_Align to align.
3581 Has no effect if align is an invalid value.
3582
3583 #Param align text placement relative to position ##
3584
3585 #Example
3586 #Height 160
3587 #Description
3588 Text is left-aligned by default, and then set to center. Setting the
3589 alignment out of range has no effect.
3590 ##
3591 void draw(SkCanvas* canvas) {
3592 SkPaint paint;
3593 paint.setTextSize(40);
3594 canvas->drawString("Aa", 100, 50, paint);
3595 paint.setTextAlign(SkPaint::kCenter_Align);
3596 canvas->drawString("Aa", 100, 100, paint);
3597 paint.setTextAlign((SkPaint::Align) SkPaint::kAlignCount);
3598 canvas->drawString("Aa", 100, 150, paint);
3599 }
3600 ##
3601
3602##
3603
Cary Clark08895c42018-02-01 09:37:32 -05003604#Subtopic Text_Align ##
Cary Clark8032b982017-07-28 11:04:54 -04003605# ------------------------------------------------------------------------------
Cary Clark08895c42018-02-01 09:37:32 -05003606#Subtopic Text_Size
3607#Line # overall height in points ##
Cary Clark8032b982017-07-28 11:04:54 -04003608
3609Text_Size adjusts the overall text size in points.
3610Text_Size can be set to any positive value or zero.
3611Text_Size defaults to 12.
3612Set SkPaintDefaults_TextSize at compile time to change the default setting.
3613
3614#Example
3615#Height 135
3616 void draw(SkCanvas* canvas) {
3617 SkPaint paint;
3618 canvas->drawString("12 point", 10, 20, paint);
3619 paint.setTextSize(24);
3620 canvas->drawString("24 point", 10, 60, paint);
3621 paint.setTextSize(48);
3622 canvas->drawString("48 point", 10, 120, paint);
3623 }
3624##
3625
3626#Method SkScalar getTextSize() const
3627
Cary Clarkab2621d2018-01-30 10:08:57 -05003628#In Text_Size
3629#Line # returns text size in points ##
Cary Clark8032b982017-07-28 11:04:54 -04003630 Returns Text_Size in points.
3631
3632 #Return typographic height of text ##
3633
3634 #Example
3635 SkPaint paint;
3636 SkDebugf("12 %c= default text size\n", 12 == paint.getTextSize() ? '=' : '!');
3637 ##
3638
3639##
3640
3641#Method void setTextSize(SkScalar textSize)
3642
Cary Clarkab2621d2018-01-30 10:08:57 -05003643#In Text_Size
3644#Line # sets text size in points ##
Cary Clark8032b982017-07-28 11:04:54 -04003645 Sets Text_Size in points.
3646 Has no effect if textSize is not greater than or equal to zero.
Herb Derbyfcac00f2018-05-01 11:57:56 -04003647
Cary Clark8032b982017-07-28 11:04:54 -04003648 #Param textSize typographic height of text ##
3649
3650 #Example
3651 SkPaint paint;
3652 SkDebugf("12 %c= text size\n", 12 == paint.getTextSize() ? '=' : '!');
3653 paint.setTextSize(-20);
3654 SkDebugf("12 %c= text size\n", 12 == paint.getTextSize() ? '=' : '!');
3655 ##
3656
3657##
3658
Cary Clark08895c42018-02-01 09:37:32 -05003659#Subtopic Text_Size ##
Cary Clark8032b982017-07-28 11:04:54 -04003660# ------------------------------------------------------------------------------
Cary Clark08895c42018-02-01 09:37:32 -05003661#Subtopic Text_Scale_X
3662#Line # text horizontal scale ##
Cary Clark8032b982017-07-28 11:04:54 -04003663
3664Text_Scale_X adjusts the text horizontal scale.
3665Text scaling approximates condensed and expanded type faces when the actual face
3666is not available.
3667Text_Scale_X can be set to any value.
3668Text_Scale_X defaults to 1.
3669
3670#Example
3671#Height 128
3672 void draw(SkCanvas* canvas) {
3673 SkPaint paint;
3674 paint.setAntiAlias(true);
3675 paint.setTextSize(24);
3676 paint.setTextScaleX(.8f);
3677 canvas->drawString("narrow", 10, 20, paint);
3678 paint.setTextScaleX(1);
3679 canvas->drawString("normal", 10, 60, paint);
3680 paint.setTextScaleX(1.2f);
3681 canvas->drawString("wide", 10, 100, paint);
3682 }
3683##
3684
3685#Method SkScalar getTextScaleX() const
3686
Cary Clarkab2621d2018-01-30 10:08:57 -05003687#In Text_Scale_X
3688#Line # returns the text horizontal scale; condensed text ##
Cary Clark8032b982017-07-28 11:04:54 -04003689 Returns Text_Scale_X.
3690 Default value is 1.
3691
3692 #Return text horizontal scale ##
3693
3694 #Example
3695 SkPaint paint;
3696 SkDebugf("1 %c= default text scale x\n", 1 == paint.getTextScaleX() ? '=' : '!');
3697 ##
3698
3699##
3700
3701
3702#Method void setTextScaleX(SkScalar scaleX)
3703
Cary Clarkab2621d2018-01-30 10:08:57 -05003704#In Text_Scale_X
3705#Line # sets the text horizontal scale; condensed text ##
Cary Clark8032b982017-07-28 11:04:54 -04003706 Sets Text_Scale_X.
3707 Default value is 1.
Herb Derbyfcac00f2018-05-01 11:57:56 -04003708
Cary Clark8032b982017-07-28 11:04:54 -04003709 #Param scaleX text horizontal scale ##
3710
3711 #Example
3712 SkPaint paint;
3713 paint.setTextScaleX(0.f / 0.f);
3714 SkDebugf("text scale %s-a-number\n", SkScalarIsNaN(paint.getTextScaleX()) ? "not" : "is");
3715 ##
3716
3717##
3718
Cary Clark08895c42018-02-01 09:37:32 -05003719#Subtopic Text_Scale_X ##
Cary Clark8032b982017-07-28 11:04:54 -04003720
Cary Clark08895c42018-02-01 09:37:32 -05003721#Subtopic Text_Skew_X
3722#Line # text horizontal slant ##
Cary Clark8032b982017-07-28 11:04:54 -04003723
3724
3725Text_Skew_X adjusts the text horizontal slant.
3726Text skewing approximates italic and oblique type faces when the actual face
3727is not available.
3728Text_Skew_X can be set to any value.
3729Text_Skew_X defaults to 0.
3730
3731#Example
3732#Height 128
3733 void draw(SkCanvas* canvas) {
3734 SkPaint paint;
3735 paint.setAntiAlias(true);
3736 paint.setTextSize(24);
3737 paint.setTextSkewX(-.25f);
3738 canvas->drawString("right-leaning", 10, 100, paint);
3739 paint.setTextSkewX(0);
3740 canvas->drawString("normal", 10, 60, paint);
3741 paint.setTextSkewX(.25f);
3742 canvas->drawString("left-leaning", 10, 20, paint);
3743 }
3744##
3745
3746#Method SkScalar getTextSkewX() const
3747
Cary Clarkab2621d2018-01-30 10:08:57 -05003748#In Text_Skew_X
3749#Line # returns the text horizontal skew; oblique text ##
Cary Clark8032b982017-07-28 11:04:54 -04003750 Returns Text_Skew_X.
3751 Default value is zero.
3752
3753 #Return additional shear in x-axis relative to y-axis ##
3754
3755 #Example
3756 SkPaint paint;
3757 SkDebugf("0 %c= default text skew x\n", 0 == paint.getTextSkewX() ? '=' : '!');
3758 ##
3759
3760##
3761
3762#Method void setTextSkewX(SkScalar skewX)
3763
Cary Clarkab2621d2018-01-30 10:08:57 -05003764#In Text_Skew_X
3765#Line # sets the text horizontal skew; oblique text ##
Cary Clark8032b982017-07-28 11:04:54 -04003766 Sets Text_Skew_X.
3767 Default value is zero.
3768
3769 #Param skewX additional shear in x-axis relative to y-axis ##
3770
3771 #Example
3772 SkPaint paint;
3773 paint.setTextScaleX(1.f / 0.f);
3774 SkDebugf("text scale %s-finite\n", SkScalarIsFinite(paint.getTextScaleX()) ? "is" : "not");
3775 ##
3776
3777##
3778
Cary Clark08895c42018-02-01 09:37:32 -05003779#Subtopic Text_Skew_X ##
Cary Clark8032b982017-07-28 11:04:54 -04003780
3781# ------------------------------------------------------------------------------
Cary Clark08895c42018-02-01 09:37:32 -05003782#Subtopic Text_Encoding
3783#Line # text encoded as characters or Glyphs ##
Cary Clark8032b982017-07-28 11:04:54 -04003784
3785#Enum TextEncoding
Cary Clark08895c42018-02-01 09:37:32 -05003786#Line # character or glyph encoded size ##
Cary Clark8032b982017-07-28 11:04:54 -04003787
3788#Code
3789 enum TextEncoding {
3790 kUTF8_TextEncoding,
3791 kUTF16_TextEncoding,
3792 kUTF32_TextEncoding,
Cary Clarkbad5ad72017-08-03 17:14:08 -04003793 kGlyphID_TextEncoding,
Cary Clark8032b982017-07-28 11:04:54 -04003794 };
3795##
3796
Cary Clark6fc50412017-09-21 12:31:06 -04003797TextEncoding determines whether text specifies character codes and their encoded
Cary Clarkbc5697d2017-10-04 14:31:33 -04003798size, or glyph indices. Characters are encoded as specified by the
Cary Clark682c58d2018-05-16 07:07:07 -04003799#A Unicode standard # https://unicode.org/standard/standard.html ##
Cary Clark6fc50412017-09-21 12:31:06 -04003800.
3801
Cary Clark8032b982017-07-28 11:04:54 -04003802Character codes encoded size are specified by UTF-8, UTF-16, or UTF-32.
Cary Clarkbc5697d2017-10-04 14:31:33 -04003803All character code formats are able to represent all of Unicode, differing only
Cary Clark8032b982017-07-28 11:04:54 -04003804in the total storage required.
3805
Cary Clark6fc50412017-09-21 12:31:06 -04003806#A UTF-8 (RFC 3629) # https://tools.ietf.org/html/rfc3629 ##
3807 encodes each character as one or more 8-bit bytes.
3808
3809#A UTF-16 (RFC 2781) # https://tools.ietf.org/html/rfc2781 ##
3810 encodes each character as one or two 16-bit words.
3811
Cary Clark682c58d2018-05-16 07:07:07 -04003812#A UTF-32 # https://www.unicode.org/versions/Unicode5.0.0/ch03.pdf ##
Cary Clark6fc50412017-09-21 12:31:06 -04003813 encodes each character as one 32-bit word.
Cary Clark8032b982017-07-28 11:04:54 -04003814
Herb Derbyfcac00f2018-05-01 11:57:56 -04003815Font_Manager uses font data to convert character code points into glyph indices.
Cary Clark8032b982017-07-28 11:04:54 -04003816A glyph index is a 16-bit word.
3817
3818TextEncoding is set to kUTF8_TextEncoding by default.
3819
3820#Const kUTF8_TextEncoding 0
Cary Clark682c58d2018-05-16 07:07:07 -04003821#Line # uses bytes to represent UTF-8 or ASCII ##
Cary Clark8032b982017-07-28 11:04:54 -04003822##
3823#Const kUTF16_TextEncoding 1
Cary Clark682c58d2018-05-16 07:07:07 -04003824#Line # uses two byte words to represent most of Unicode ##
Cary Clark8032b982017-07-28 11:04:54 -04003825##
3826#Const kUTF32_TextEncoding 2
Cary Clark682c58d2018-05-16 07:07:07 -04003827#Line # uses four byte words to represent all of Unicode ##
Cary Clark8032b982017-07-28 11:04:54 -04003828##
3829#Const kGlyphID_TextEncoding 3
Cary Clark682c58d2018-05-16 07:07:07 -04003830#Line # uses two byte words to represent glyph indices ##
Cary Clark8032b982017-07-28 11:04:54 -04003831##
3832
3833#Enum ##
3834
3835#Example
3836#Height 128
3837#Description
Cary Clarkbc5697d2017-10-04 14:31:33 -04003838First line is encoded in UTF-8.
3839Second line is encoded in UTF-16.
3840Third line is encoded in UTF-32.
Cary Clark682c58d2018-05-16 07:07:07 -04003841Fourth line has 16-bit glyph indices.
Cary Clark8032b982017-07-28 11:04:54 -04003842##
3843void draw(SkCanvas* canvas) {
3844 SkPaint paint;
3845 const char hello8[] = "Hello" "\xE2" "\x98" "\xBA";
3846 const uint16_t hello16[] = { 'H', 'e', 'l', 'l', 'o', 0x263A };
3847 const uint32_t hello32[] = { 'H', 'e', 'l', 'l', 'o', 0x263A };
3848 paint.setTextSize(24);
3849 canvas->drawText(hello8, sizeof(hello8) - 1, 10, 30, paint);
3850 paint.setTextEncoding(SkPaint::kUTF16_TextEncoding);
3851 canvas->drawText(hello16, sizeof(hello16), 10, 60, paint);
3852 paint.setTextEncoding(SkPaint::kUTF32_TextEncoding);
3853 canvas->drawText(hello32, sizeof(hello32), 10, 90, paint);
3854 uint16_t glyphs[SK_ARRAY_COUNT(hello32)];
3855 paint.textToGlyphs(hello32, sizeof(hello32), glyphs);
3856 paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
3857 canvas->drawText(glyphs, sizeof(glyphs), 10, 120, paint);
3858}
3859##
3860
3861#Method TextEncoding getTextEncoding() const
3862
Cary Clarkab2621d2018-01-30 10:08:57 -05003863#In Text_Encoding
3864#Line # returns character or glyph encoded size ##
Cary Clark8032b982017-07-28 11:04:54 -04003865 Returns Text_Encoding.
3866 Text_Encoding determines how character code points are mapped to font glyph indices.
3867
Herb Derbyfcac00f2018-05-01 11:57:56 -04003868 #Return one of: kUTF8_TextEncoding, kUTF16_TextEncoding, kUTF32_TextEncoding, or
3869 kGlyphID_TextEncoding
Cary Clark8032b982017-07-28 11:04:54 -04003870 ##
3871
3872 #Example
3873 SkPaint paint;
Herb Derbyfcac00f2018-05-01 11:57:56 -04003874 SkDebugf("kUTF8_TextEncoding %c= text encoding\n",
Cary Clark8032b982017-07-28 11:04:54 -04003875 SkPaint::kUTF8_TextEncoding == paint.getTextEncoding() ? '=' : '!');
3876 paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
Herb Derbyfcac00f2018-05-01 11:57:56 -04003877 SkDebugf("kGlyphID_TextEncoding %c= text encoding\n",
Cary Clark8032b982017-07-28 11:04:54 -04003878 SkPaint::kGlyphID_TextEncoding == paint.getTextEncoding() ? '=' : '!');
3879
3880 #StdOut
3881 kUTF8_TextEncoding == text encoding
3882 kGlyphID_TextEncoding == text encoding
3883 ##
3884 ##
3885
3886##
3887
3888
3889#Method void setTextEncoding(TextEncoding encoding)
3890
Cary Clarkab2621d2018-01-30 10:08:57 -05003891#In Text_Encoding
3892#Line # sets character or glyph encoded size ##
Herb Derbyfcac00f2018-05-01 11:57:56 -04003893 Sets Text_Encoding to encoding.
Cary Clark8032b982017-07-28 11:04:54 -04003894 Text_Encoding determines how character code points are mapped to font glyph indices.
3895 Invalid values for encoding are ignored.
3896
Herb Derbyfcac00f2018-05-01 11:57:56 -04003897 #Param encoding one of: kUTF8_TextEncoding, kUTF16_TextEncoding, kUTF32_TextEncoding, or
3898 kGlyphID_TextEncoding
Cary Clark579985c2017-07-31 11:48:27 -04003899 #Param ##
Cary Clark8032b982017-07-28 11:04:54 -04003900
3901 #Example
3902 SkPaint paint;
3903 paint.setTextEncoding((SkPaint::TextEncoding) 4);
Cary Clark75fd4492018-06-20 12:45:16 -04003904 SkDebugf("4 %c= text encoding\n", (SkPaint::TextEncoding) 4 == paint.getTextEncoding() ? '=' : '!');
Cary Clark8032b982017-07-28 11:04:54 -04003905
3906 #StdOut
3907 4 != text encoding
3908 ##
3909 ##
3910
3911##
3912
Cary Clark08895c42018-02-01 09:37:32 -05003913#Subtopic Text_Encoding ##
Cary Clark8032b982017-07-28 11:04:54 -04003914# ------------------------------------------------------------------------------
Cary Clark08895c42018-02-01 09:37:32 -05003915#Subtopic Font_Metrics
3916#Line # common glyph dimensions ##
Cary Clark8032b982017-07-28 11:04:54 -04003917
Cary Clarkce101242017-09-01 15:51:02 -04003918Font_Metrics describe dimensions common to the Glyphs in Typeface.
Herb Derbyfcac00f2018-05-01 11:57:56 -04003919The dimensions are computed by Font_Manager from font data and do not take
Cary Clark8032b982017-07-28 11:04:54 -04003920Paint settings other than Text_Size into account.
3921
3922Font dimensions specify the anchor to the left of the glyph at baseline as the origin.
3923X-axis values to the left of the glyph are negative, and to the right of the left glyph edge
3924are positive.
3925Y-axis values above the baseline are negative, and below the baseline are positive.
Ben Wagnere5806492017-11-09 12:08:31 -05003926
Cary Clark8032b982017-07-28 11:04:54 -04003927#Example
3928#Width 512
3929void draw(SkCanvas* canvas) {
3930 SkPaint paint;
3931 paint.setAntiAlias(true);
3932 paint.setTextSize(120);
3933 SkPaint::FontMetrics fm;
3934 SkScalar lineHeight = paint.getFontMetrics(&fm);
3935 SkPoint pt = { 70, 180 };
3936 canvas->drawString("M", pt.fX, pt.fY, paint);
3937 canvas->drawLine(pt.fX, pt.fY, pt.fX, pt.fY + fm.fTop, paint);
3938 SkScalar ascent = pt.fY + fm.fAscent;
3939 canvas->drawLine(pt.fX - 25, ascent, pt.fX - 25, ascent + lineHeight, paint);
3940 canvas->drawLine(pt.fX - 50, pt.fY, pt.fX - 50, pt.fY + fm.fDescent, paint);
3941 canvas->drawLine(pt.fX + 100, pt.fY, pt.fX + 100, pt.fY + fm.fAscent, paint);
3942 canvas->drawLine(pt.fX + 125, pt.fY, pt.fX + 125, pt.fY - fm.fXHeight, paint);
3943 canvas->drawLine(pt.fX + 150, pt.fY, pt.fX + 150, pt.fY - fm.fCapHeight, paint);
3944 canvas->drawLine(pt.fX + 5, pt.fY, pt.fX + 5, pt.fY + fm.fBottom, paint);
3945 SkScalar xmin = pt.fX + fm.fXMin;
3946 canvas->drawLine(xmin, pt.fY + 60, xmin + fm.fMaxCharWidth, pt.fY + 60, paint);
3947 canvas->drawLine(xmin, pt.fY - 145, pt.fX, pt.fY - 145, paint);
3948 canvas->drawLine(pt.fX + fm.fXMax, pt.fY - 160, pt.fX, pt.fY - 160, paint);
3949 SkScalar upos = pt.fY + fm.fUnderlinePosition;
Ben Wagnere5806492017-11-09 12:08:31 -05003950 canvas->drawLine(pt.fX + 25, upos, pt.fX + 160, upos, paint);
3951 SkScalar ut = fm.fUnderlineThickness;
3952 canvas->drawLine(pt.fX + 130, upos + ut, pt.fX + 160, upos + ut, paint);
Cary Clark8032b982017-07-28 11:04:54 -04003953 paint.setTextSize(12);
3954 canvas->drawString("x-min", pt.fX - 50, pt.fY - 148, paint);
3955 canvas->drawString("x-max", pt.fX + 140, pt.fY - 150, paint);
3956 canvas->drawString("max char width", pt.fX + 120, pt.fY + 57, paint);
3957 canvas->drawString("underline position", pt.fX + 30, pt.fY + 22, paint);
3958 canvas->drawString("underline thickness", pt.fX + 162, pt.fY + 13, paint);
3959 canvas->rotate(-90);
3960 canvas->drawString("descent", -pt.fY - 30, pt.fX - 54, paint);
3961 canvas->drawString("line height", -pt.fY, pt.fX - 29, paint);
3962 canvas->drawString("top", -pt.fY + 30, pt.fX - 4, paint);
3963 canvas->drawString("ascent", -pt.fY, pt.fX + 110, paint);
3964 canvas->drawString("x-height", -pt.fY, pt.fX + 135, paint);
3965 canvas->drawString("cap-height", -pt.fY, pt.fX + 160, paint);
3966 canvas->drawString("bottom", -pt.fY - 50, pt.fX + 15, paint);
3967}
3968##
3969
3970#Struct FontMetrics
Cary Clark08895c42018-02-01 09:37:32 -05003971#Line # values computed by Font_Manager using Typeface ##
Cary Clark8032b982017-07-28 11:04:54 -04003972
3973#Code
3974 struct FontMetrics {
3975 enum FontMetricsFlags {
3976 kUnderlineThicknessIsValid_Flag = 1 << 0,
3977 kUnderlinePositionIsValid_Flag = 1 << 1,
3978 kStrikeoutThicknessIsValid_Flag = 1 << 2,
3979 kStrikeoutPositionIsValid_Flag = 1 << 3,
3980 };
3981
3982 uint32_t fFlags;
3983 SkScalar fTop;
3984 SkScalar fAscent;
3985 SkScalar fDescent;
3986 SkScalar fBottom;
3987 SkScalar fLeading;
3988 SkScalar fAvgCharWidth;
3989 SkScalar fMaxCharWidth;
3990 SkScalar fXMin;
3991 SkScalar fXMax;
3992 SkScalar fXHeight;
3993 SkScalar fCapHeight;
3994 SkScalar fUnderlineThickness;
3995 SkScalar fUnderlinePosition;
3996 SkScalar fStrikeoutThickness;
3997 SkScalar fStrikeoutPosition;
3998
3999 bool hasUnderlineThickness(SkScalar* thickness) const;
4000 bool hasUnderlinePosition(SkScalar* position) const;
4001 bool hasStrikeoutThickness(SkScalar* thickness) const;
4002 bool hasStrikeoutPosition(SkScalar* position) const;
4003 };
4004##
4005
Cary Clark154beea2017-10-26 07:58:48 -04004006 FontMetrics is filled out by getFontMetrics. FontMetrics contents reflect the values
4007 computed by Font_Manager using Typeface. Values are set to zero if they are
4008 not available.
Cary Clarke4aa3712017-09-15 02:56:12 -04004009
Cary Clark5538c132018-06-14 12:28:14 -04004010 All vertical values are relative to the baseline, on a y-axis pointing down.
4011 Zero is on the baseline, negative values are above the baseline, and positive
4012 values are below the baseline.
Ben Wagnere5806492017-11-09 12:08:31 -05004013
Cary Clark154beea2017-10-26 07:58:48 -04004014 fUnderlineThickness and fUnderlinePosition have a bit set in fFlags if their values
4015 are valid, since their value may be zero.
Ben Wagnere5806492017-11-09 12:08:31 -05004016
Cary Clark154beea2017-10-26 07:58:48 -04004017 fStrikeoutThickness and fStrikeoutPosition have a bit set in fFlags if their values
4018 are valid, since their value may be zero.
4019
4020 #Enum FontMetricsFlags
Cary Clark682c58d2018-05-16 07:07:07 -04004021 #Line # valid Font_Metrics ##
Cary Clarke4aa3712017-09-15 02:56:12 -04004022
Cary Clark8032b982017-07-28 11:04:54 -04004023 #Code
4024 enum FontMetricsFlags {
4025 kUnderlineThicknessIsValid_Flag = 1 << 0,
4026 kUnderlinePositionIsValid_Flag = 1 << 1,
4027 kStrikeoutThicknessIsValid_Flag = 1 << 2,
4028 kStrikeoutPositionIsValid_Flag = 1 << 3,
4029 };
4030 ##
4031
Cary Clark154beea2017-10-26 07:58:48 -04004032 FontMetricsFlags are set in fFlags when underline and strikeout metrics are valid;
4033 the underline or strikeout metric may be valid and zero.
4034 Fonts with embedded bitmaps may not have valid underline or strikeout metrics.
4035
Cary Clark8032b982017-07-28 11:04:54 -04004036 #Const kUnderlineThicknessIsValid_Flag 0x0001
Cary Clark682c58d2018-05-16 07:07:07 -04004037 #Line # set if fUnderlineThickness is valid ##
Cary Clark8032b982017-07-28 11:04:54 -04004038 ##
4039 #Const kUnderlinePositionIsValid_Flag 0x0002
Cary Clark682c58d2018-05-16 07:07:07 -04004040 #Line # set if fUnderlinePosition is valid ##
Cary Clark8032b982017-07-28 11:04:54 -04004041 ##
4042 #Const kStrikeoutThicknessIsValid_Flag 0x0004
Cary Clark682c58d2018-05-16 07:07:07 -04004043 #Line # set if fStrikeoutThickness is valid ##
Cary Clark8032b982017-07-28 11:04:54 -04004044 ##
4045 #Const kStrikeoutPositionIsValid_Flag 0x0008
Cary Clark682c58d2018-05-16 07:07:07 -04004046 #Line # set if fStrikeoutPosition is valid ##
Cary Clark8032b982017-07-28 11:04:54 -04004047 ##
4048
4049 #Enum ##
4050
4051 #Member uint32_t fFlags
Cary Clark682c58d2018-05-16 07:07:07 -04004052 #Line # is set to FontMetricsFlags when metrics are valid ##
Cary Clark8032b982017-07-28 11:04:54 -04004053 ##
Ben Wagnere5806492017-11-09 12:08:31 -05004054
Cary Clark8032b982017-07-28 11:04:54 -04004055 #Member SkScalar fTop
Cary Clark682c58d2018-05-16 07:07:07 -04004056 #Line # extent above baseline ##
Ben Wagnere5806492017-11-09 12:08:31 -05004057 Greatest extent above the baseline for any glyph.
4058 Typically less than zero.
Cary Clark8032b982017-07-28 11:04:54 -04004059 ##
Ben Wagnere5806492017-11-09 12:08:31 -05004060
Cary Clark8032b982017-07-28 11:04:54 -04004061 #Member SkScalar fAscent
Cary Clark682c58d2018-05-16 07:07:07 -04004062 #Line # distance to reserve above baseline ##
Cary Clark8032b982017-07-28 11:04:54 -04004063 Recommended distance above the baseline to reserve for a line of text.
Ben Wagnere5806492017-11-09 12:08:31 -05004064 Typically less than zero.
Cary Clark8032b982017-07-28 11:04:54 -04004065 ##
Ben Wagnere5806492017-11-09 12:08:31 -05004066
Cary Clark8032b982017-07-28 11:04:54 -04004067 #Member SkScalar fDescent
Cary Clark682c58d2018-05-16 07:07:07 -04004068 #Line # distance to reserve below baseline ##
Cary Clark8032b982017-07-28 11:04:54 -04004069 Recommended distance below the baseline to reserve for a line of text.
Ben Wagnere5806492017-11-09 12:08:31 -05004070 Typically greater than zero.
Cary Clark8032b982017-07-28 11:04:54 -04004071 ##
Ben Wagnere5806492017-11-09 12:08:31 -05004072
Cary Clark8032b982017-07-28 11:04:54 -04004073 #Member SkScalar fBottom
Cary Clark682c58d2018-05-16 07:07:07 -04004074 #Line # extent below baseline ##
Ben Wagnere5806492017-11-09 12:08:31 -05004075 Greatest extent below the baseline for any glyph.
4076 Typically greater than zero.
Cary Clark8032b982017-07-28 11:04:54 -04004077 ##
Ben Wagnere5806492017-11-09 12:08:31 -05004078
Cary Clark8032b982017-07-28 11:04:54 -04004079 #Member SkScalar fLeading
Cary Clark682c58d2018-05-16 07:07:07 -04004080 #Line # distance to add between lines ##
Cary Clark8032b982017-07-28 11:04:54 -04004081 Recommended distance to add between lines of text.
Ben Wagnere5806492017-11-09 12:08:31 -05004082 Typically greater than or equal to zero.
Cary Clark8032b982017-07-28 11:04:54 -04004083 ##
Ben Wagnere5806492017-11-09 12:08:31 -05004084
Cary Clark8032b982017-07-28 11:04:54 -04004085 #Member SkScalar fAvgCharWidth
Cary Clark682c58d2018-05-16 07:07:07 -04004086 #Line # average character width ##
Cary Clark8032b982017-07-28 11:04:54 -04004087 Average character width, if it is available.
4088 Zero if no average width is stored in the font.
4089 ##
Ben Wagnere5806492017-11-09 12:08:31 -05004090
Cary Clark8032b982017-07-28 11:04:54 -04004091 #Member SkScalar fMaxCharWidth
Cary Clark682c58d2018-05-16 07:07:07 -04004092 #Line # maximum character width ##
Cary Clark8032b982017-07-28 11:04:54 -04004093 ##
Ben Wagnere5806492017-11-09 12:08:31 -05004094
Cary Clark8032b982017-07-28 11:04:54 -04004095 #Member SkScalar fXMin
Cary Clark682c58d2018-05-16 07:07:07 -04004096 #Line # minimum x ##
Cary Clark5538c132018-06-14 12:28:14 -04004097 Minimum bounding box x-axis value for all Glyphs.
Cary Clark8032b982017-07-28 11:04:54 -04004098 Typically less than zero.
4099 ##
Ben Wagnere5806492017-11-09 12:08:31 -05004100
Cary Clark8032b982017-07-28 11:04:54 -04004101 #Member SkScalar fXMax
Cary Clark682c58d2018-05-16 07:07:07 -04004102 #Line # maximum x ##
Cary Clark5538c132018-06-14 12:28:14 -04004103 Maximum bounding box x-axis value for all Glyphs.
Cary Clark8032b982017-07-28 11:04:54 -04004104 Typically greater than zero.
4105 ##
Ben Wagnere5806492017-11-09 12:08:31 -05004106
Cary Clark8032b982017-07-28 11:04:54 -04004107 #Member SkScalar fXHeight
Cary Clark682c58d2018-05-16 07:07:07 -04004108 #Line # height of lower-case 'x' ##
Cary Clark8032b982017-07-28 11:04:54 -04004109 May be zero if no lower-case height is stored in the font.
4110 ##
Ben Wagnere5806492017-11-09 12:08:31 -05004111
Cary Clark8032b982017-07-28 11:04:54 -04004112 #Member SkScalar fCapHeight
Cary Clark682c58d2018-05-16 07:07:07 -04004113 #Line # height of an upper-case letter ##
Cary Clark8032b982017-07-28 11:04:54 -04004114 May be zero if no upper-case height is stored in the font.
4115 ##
Ben Wagnere5806492017-11-09 12:08:31 -05004116
Cary Clark8032b982017-07-28 11:04:54 -04004117 #Member SkScalar fUnderlineThickness
Cary Clark682c58d2018-05-16 07:07:07 -04004118 #Line # underline thickness ##
Ben Wagnere5806492017-11-09 12:08:31 -05004119 If the metric is valid, the kUnderlineThicknessIsValid_Flag is set in fFlags.
Cary Clark8032b982017-07-28 11:04:54 -04004120 If kUnderlineThicknessIsValid_Flag is clear, fUnderlineThickness is zero.
4121 ##
Ben Wagnere5806492017-11-09 12:08:31 -05004122
Cary Clark8032b982017-07-28 11:04:54 -04004123 #Member SkScalar fUnderlinePosition
Cary Clark682c58d2018-05-16 07:07:07 -04004124 #Line # underline position relative to baseline ##
Ben Wagnere5806492017-11-09 12:08:31 -05004125 Position of the top of the underline stroke relative to the baseline.
4126 Typically positive when valid.
Cary Clark8032b982017-07-28 11:04:54 -04004127
4128 If the metric is valid, the kUnderlinePositionIsValid_Flag is set in fFlags.
4129 If kUnderlinePositionIsValid_Flag is clear, fUnderlinePosition is zero.
4130 ##
4131
4132 #Member SkScalar fStrikeoutThickness
Cary Clark682c58d2018-05-16 07:07:07 -04004133 #Line # strikeout thickness ##
Ben Wagnere5806492017-11-09 12:08:31 -05004134
4135 If the metric is valid, the kStrikeoutThicknessIsValid_Flag is set in fFlags.
Cary Clark8032b982017-07-28 11:04:54 -04004136 If kStrikeoutThicknessIsValid_Flag is clear, fStrikeoutThickness is zero.
4137 ##
4138
4139 #Member SkScalar fStrikeoutPosition
Cary Clark682c58d2018-05-16 07:07:07 -04004140 #Line # strikeout position relative to baseline ##
Ben Wagnere5806492017-11-09 12:08:31 -05004141 Position of the bottom of the strikeout stroke relative to the baseline.
4142 Typically negative when valid.
Cary Clark8032b982017-07-28 11:04:54 -04004143
Ben Wagnere5806492017-11-09 12:08:31 -05004144 If the metric is valid, the kStrikeoutPositionIsValid_Flag is set in fFlags.
4145 If kStrikeoutPositionIsValid_Flag is clear, fStrikeoutPosition is zero.
Cary Clark8032b982017-07-28 11:04:54 -04004146 ##
4147
4148 #Method bool hasUnderlineThickness(SkScalar* thickness) const
Cary Clark682c58d2018-05-16 07:07:07 -04004149 #Line # returns underline thickness if set ##
Cary Clark8032b982017-07-28 11:04:54 -04004150
Cary Clark80247e52018-07-11 16:18:41 -04004151 Returns true if Font_Metrics has a valid underline thickness, and sets
Cary Clarkce101242017-09-01 15:51:02 -04004152 thickness to that value. If the underline thickness is not valid,
4153 return false, and ignore thickness.
Cary Clark8032b982017-07-28 11:04:54 -04004154
4155 #Param thickness storage for underline width ##
4156
4157 #Return true if font specifies underline width ##
4158
4159 #NoExample
4160 ##
4161 ##
4162
4163 #Method bool hasUnderlinePosition(SkScalar* position) const
Cary Clark682c58d2018-05-16 07:07:07 -04004164 #Line # returns underline position if set ##
Cary Clark8032b982017-07-28 11:04:54 -04004165
Cary Clark80247e52018-07-11 16:18:41 -04004166 Returns true if Font_Metrics has a valid underline position, and sets
Cary Clarkce101242017-09-01 15:51:02 -04004167 position to that value. If the underline position is not valid,
4168 return false, and ignore position.
Cary Clark8032b982017-07-28 11:04:54 -04004169
4170 #Param position storage for underline position ##
4171
4172 #Return true if font specifies underline position ##
4173
4174 #NoExample
4175 ##
4176 ##
4177
4178 #Method bool hasStrikeoutThickness(SkScalar* thickness) const
Cary Clark682c58d2018-05-16 07:07:07 -04004179 #Line # returns strikeout thickness if set ##
Cary Clark8032b982017-07-28 11:04:54 -04004180
Cary Clark80247e52018-07-11 16:18:41 -04004181 Returns true if Font_Metrics has a valid strikeout thickness, and sets
Cary Clarkce101242017-09-01 15:51:02 -04004182 thickness to that value. If the underline thickness is not valid,
4183 return false, and ignore thickness.
Cary Clark8032b982017-07-28 11:04:54 -04004184
4185 #Param thickness storage for strikeout width ##
4186
4187 #Return true if font specifies strikeout width ##
4188
4189 #NoExample
4190 ##
4191 ##
4192
4193 #Method bool hasStrikeoutPosition(SkScalar* position) const
Cary Clark682c58d2018-05-16 07:07:07 -04004194 #Line # returns strikeout position if set ##
Cary Clark8032b982017-07-28 11:04:54 -04004195
Cary Clark80247e52018-07-11 16:18:41 -04004196 Returns true if Font_Metrics has a valid strikeout position, and sets
Cary Clarkce101242017-09-01 15:51:02 -04004197 position to that value. If the underline position is not valid,
4198 return false, and ignore position.
Cary Clark8032b982017-07-28 11:04:54 -04004199
4200 #Param position storage for strikeout position ##
4201
4202 #Return true if font specifies strikeout position ##
4203
4204 #NoExample
4205 ##
4206 ##
4207
4208#Struct ##
4209
4210#Method SkScalar getFontMetrics(FontMetrics* metrics, SkScalar scale = 0) const
4211
Cary Clarkab2621d2018-01-30 10:08:57 -05004212#In Font_Metrics
4213#Line # returns Typeface metrics scaled by text size ##
Cary Clark8032b982017-07-28 11:04:54 -04004214 Returns Font_Metrics associated with Typeface.
4215 The return value is the recommended spacing between lines: the sum of metrics
4216 descent, ascent, and leading.
4217 If metrics is not nullptr, Font_Metrics is copied to metrics.
4218 Results are scaled by Text_Size but does not take into account
4219 dimensions required by Text_Scale_X, Text_Skew_X, Fake_Bold,
4220 Style_Stroke, and Path_Effect.
4221 Results can be additionally scaled by scale; a scale of zero
4222 is ignored.
4223
4224 #Param metrics storage for Font_Metrics from Typeface; may be nullptr ##
4225 #Param scale additional multiplier for returned values ##
4226
4227 #Return recommended spacing between lines ##
4228
4229 #Example
4230 #Height 128
4231 void draw(SkCanvas* canvas) {
4232 SkPaint paint;
4233 paint.setTextSize(32);
4234 SkScalar lineHeight = paint.getFontMetrics(nullptr);
4235 canvas->drawString("line 1", 10, 40, paint);
4236 canvas->drawString("line 2", 10, 40 + lineHeight, paint);
4237 paint.setStyle(SkPaint::kStroke_Style);
4238 paint.setStrokeWidth(10);
4239 lineHeight = paint.getFontMetrics(nullptr, 1.10f); // account for stroke height
4240 canvas->drawString("line 3", 120, 40, paint);
4241 canvas->drawString("line 4", 120, 40 + lineHeight, paint);
4242 }
4243 ##
4244
4245 #SeeAlso Text_Size Typeface Typeface_Methods
4246
4247##
4248
4249
4250#Method SkScalar getFontSpacing() const
4251
Cary Clarkab2621d2018-01-30 10:08:57 -05004252#In Font_Metrics
4253#Line # returns recommended spacing between lines ##
Cary Clark8032b982017-07-28 11:04:54 -04004254 Returns the recommended spacing between lines: the sum of metrics
4255 descent, ascent, and leading.
4256 Result is scaled by Text_Size but does not take into account
4257 dimensions required by stroking and Path_Effect.
Cary Clark579985c2017-07-31 11:48:27 -04004258 Returns the same result as getFontMetrics.
Cary Clark8032b982017-07-28 11:04:54 -04004259
Cary Clark0c5f5462017-12-15 11:21:51 -05004260 #Return recommended spacing between lines ##
Cary Clark8032b982017-07-28 11:04:54 -04004261
4262 #Example
4263 SkPaint paint;
4264 for (SkScalar textSize : { 12, 18, 24, 32 } ) {
4265 paint.setTextSize(textSize);
4266 SkDebugf("textSize: %g fontSpacing: %g\n", textSize, paint.getFontSpacing());
4267 }
4268
4269 #StdOut
4270 textSize: 12 fontSpacing: 13.9688
4271 textSize: 18 fontSpacing: 20.9531
4272 textSize: 24 fontSpacing: 27.9375
4273 textSize: 32 fontSpacing: 37.25
4274 ##
4275 ##
4276
4277##
4278
4279
4280#Method SkRect getFontBounds() const
4281
Cary Clarkab2621d2018-01-30 10:08:57 -05004282#In Font_Metrics
4283#Line # returns union all glyph bounds ##
Cary Clarkce101242017-09-01 15:51:02 -04004284Returns the union of bounds of all Glyphs.
Herb Derbyfcac00f2018-05-01 11:57:56 -04004285Returned dimensions are computed by Font_Manager from font data,
Cary Clark579985c2017-07-31 11:48:27 -04004286ignoring Hinting. Includes Text_Size, Text_Scale_X,
Cary Clark8032b982017-07-28 11:04:54 -04004287and Text_Skew_X, but not Fake_Bold or Path_Effect.
4288
4289If Text_Size is large, Text_Scale_X is one, and Text_Skew_X is zero,
Herb Derbyfcac00f2018-05-01 11:57:56 -04004290returns the same bounds as Font_Metrics { FontMetrics::fXMin,
Cary Clark8032b982017-07-28 11:04:54 -04004291FontMetrics::fTop, FontMetrics::fXMax, FontMetrics::fBottom }.
4292
Cary Clarkce101242017-09-01 15:51:02 -04004293#Return union of bounds of all Glyphs ##
Cary Clark8032b982017-07-28 11:04:54 -04004294
4295#Example
4296 SkPaint paint;
4297 SkPaint::FontMetrics fm;
4298 paint.getFontMetrics(&fm);
4299 SkRect fb = paint.getFontBounds();
4300 SkDebugf("metrics bounds = { %g, %g, %g, %g }\n", fm.fXMin, fm.fTop, fm.fXMax, fm.fBottom );
4301 SkDebugf("font bounds = { %g, %g, %g, %g }\n", fb.fLeft, fb.fTop, fb.fRight, fm.fBottom );
4302
4303 #StdOut
4304 metrics bounds = { -12.2461, -14.7891, 21.5215, 5.55469 }
4305 font bounds = { -12.2461, -14.7891, 21.5215, 5.55469 }
4306 ##
4307##
4308
4309##
4310
Cary Clark08895c42018-02-01 09:37:32 -05004311#Subtopic Font_Metrics ##
Cary Clark8032b982017-07-28 11:04:54 -04004312# ------------------------------------------------------------------------------
4313
4314#Method int textToGlyphs(const void* text, size_t byteLength,
4315 SkGlyphID glyphs[]) const
Cary Clark78de7512018-02-07 07:27:09 -05004316#In Utility
Cary Clarkab2621d2018-01-30 10:08:57 -05004317#Line # converts text into glyph indices ##
Cary Clark8032b982017-07-28 11:04:54 -04004318
4319Converts text into glyph indices.
4320Returns the number of glyph indices represented by text.
4321Text_Encoding specifies how text represents characters or glyphs.
4322glyphs may be nullptr, to compute the glyph count.
4323
Cary Clarkbc5697d2017-10-04 14:31:33 -04004324Does not check text for valid character codes or valid glyph indices.
Cary Clark8032b982017-07-28 11:04:54 -04004325
Cary Clark579985c2017-07-31 11:48:27 -04004326If byteLength equals zero, returns zero.
Cary Clark8032b982017-07-28 11:04:54 -04004327If byteLength includes a partial character, the partial character is ignored.
4328
4329If Text_Encoding is kUTF8_TextEncoding and
4330text contains an invalid UTF-8 sequence, zero is returned.
4331
Cary Clarkce101242017-09-01 15:51:02 -04004332#Param text character storage encoded with Text_Encoding ##
Cary Clark8032b982017-07-28 11:04:54 -04004333#Param byteLength length of character storage in bytes ##
4334#Param glyphs storage for glyph indices; may be nullptr ##
4335
4336#Return number of glyphs represented by text of length byteLength ##
4337
4338 #Example
4339 #Height 64
4340 void draw(SkCanvas* canvas) {
4341 SkPaint paint;
4342 const uint8_t utf8[] = { 0x24, 0xC2, 0xA2, 0xE2, 0x82, 0xAC, 0xC2, 0xA5, 0xC2, 0xA3 };
4343 std::vector<SkGlyphID> glyphs;
4344 int count = paint.textToGlyphs(utf8, sizeof(utf8), nullptr);
4345 glyphs.resize(count);
4346 (void) paint.textToGlyphs(utf8, sizeof(utf8), &glyphs.front());
4347 paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
4348 paint.setTextSize(32);
4349 canvas->drawText(&glyphs.front(), glyphs.size() * sizeof(SkGlyphID), 10, 40, paint);
4350 }
4351 ##
4352
4353##
4354
4355#Method int countText(const void* text, size_t byteLength) const
Cary Clark78de7512018-02-07 07:27:09 -05004356#In Utility
Cary Clarkab2621d2018-01-30 10:08:57 -05004357#Line # returns number of Glyphs in text ##
Cary Clarkce101242017-09-01 15:51:02 -04004358 Returns the number of Glyphs in text.
4359 Uses Text_Encoding to count the Glyphs.
Cary Clark8032b982017-07-28 11:04:54 -04004360 Returns the same result as textToGlyphs.
4361
Cary Clarkce101242017-09-01 15:51:02 -04004362#Param text character storage encoded with Text_Encoding ##
Cary Clark8032b982017-07-28 11:04:54 -04004363#Param byteLength length of character storage in bytes ##
4364
Cary Clarkce101242017-09-01 15:51:02 -04004365#Return number of Glyphs represented by text of length byteLength ##
Cary Clark8032b982017-07-28 11:04:54 -04004366
4367 #Example
4368 SkPaint paint;
4369 const uint8_t utf8[] = { 0x24, 0xC2, 0xA2, 0xE2, 0x82, 0xAC, 0xC2, 0xA5, 0xC2, 0xA3 };
4370 SkDebugf("count = %d\n", paint.countText(utf8, sizeof(utf8)));
4371
4372 #StdOut
4373 count = 5
4374 ##
4375 ##
4376##
4377
4378# ------------------------------------------------------------------------------
4379
4380#Method bool containsText(const void* text, size_t byteLength) const
Cary Clark78de7512018-02-07 07:27:09 -05004381#In Utility
Cary Clarkab2621d2018-01-30 10:08:57 -05004382#Line # returns if all text corresponds to Glyphs ##
Herb Derbyfcac00f2018-05-01 11:57:56 -04004383 Returns true if all text corresponds to a non-zero glyph index.
Cary Clark8032b982017-07-28 11:04:54 -04004384 Returns false if any characters in text are not supported in
4385 Typeface.
4386
Cary Clark579985c2017-07-31 11:48:27 -04004387 If Text_Encoding is kGlyphID_TextEncoding,
4388 returns true if all glyph indices in text are non-zero;
Cary Clark8032b982017-07-28 11:04:54 -04004389 does not check to see if text contains valid glyph indices for Typeface.
4390
Cary Clarkce101242017-09-01 15:51:02 -04004391 Returns true if byteLength is zero.
Cary Clark8032b982017-07-28 11:04:54 -04004392
Cary Clarkce101242017-09-01 15:51:02 -04004393 #Param text array of characters or Glyphs ##
Cary Clark8032b982017-07-28 11:04:54 -04004394 #Param byteLength number of bytes in text array ##
4395
4396 #Return true if all text corresponds to a non-zero glyph index ##
4397
Ruiqi Mao94d57c42018-07-02 15:20:10 -04004398 #NoExample
Cary Clark8032b982017-07-28 11:04:54 -04004399 #Description
4400 containsText succeeds for degree symbol, but cannot find a glyph index
4401 corresponding to the Unicode surrogate code point.
4402 ##
4403 SkPaint paint;
4404 const uint16_t goodChar = 0x00B0; // degree symbol
4405 const uint16_t badChar = 0xD800; // Unicode surrogate
4406 paint.setTextEncoding(SkPaint::kUTF16_TextEncoding);
Herb Derbyfcac00f2018-05-01 11:57:56 -04004407 SkDebugf("0x%04x %c= has char\n", goodChar,
Cary Clark8032b982017-07-28 11:04:54 -04004408 paint.containsText(&goodChar, 2) ? '=' : '!');
4409 SkDebugf("0x%04x %c= has char\n", badChar,
4410 paint.containsText(&badChar, 2) ? '=' : '!');
4411
4412 #StdOut
4413 0x00b0 == has char
4414 0xd800 != has char
4415 ##
4416 ##
4417
4418 #Example
4419 #Description
4420 containsText returns true that glyph index is greater than zero, not
4421 that it corresponds to an entry in Typeface.
4422 ##
4423 SkPaint paint;
4424 const uint16_t goodGlyph = 511;
4425 const uint16_t zeroGlyph = 0;
4426 const uint16_t badGlyph = 65535; // larger than glyph count in font
4427 paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
Herb Derbyfcac00f2018-05-01 11:57:56 -04004428 SkDebugf("0x%04x %c= has glyph\n", goodGlyph,
Cary Clark8032b982017-07-28 11:04:54 -04004429 paint.containsText(&goodGlyph, 2) ? '=' : '!');
4430 SkDebugf("0x%04x %c= has glyph\n", zeroGlyph,
4431 paint.containsText(&zeroGlyph, 2) ? '=' : '!');
4432 SkDebugf("0x%04x %c= has glyph\n", badGlyph,
4433 paint.containsText(&badGlyph, 2) ? '=' : '!');
4434
4435 #StdOut
4436 0x01ff == has glyph
4437 0x0000 != has glyph
4438 0xffff == has glyph
4439 ##
4440 ##
4441
4442#SeeAlso setTextEncoding Typeface
4443
4444##
4445
4446# ------------------------------------------------------------------------------
4447
4448#Method void glyphsToUnichars(const SkGlyphID glyphs[],
4449 int count, SkUnichar text[]) const
Cary Clark78de7512018-02-07 07:27:09 -05004450#In Utility
Cary Clarkab2621d2018-01-30 10:08:57 -05004451#Line # converts Glyphs into text ##
Cary Clark8032b982017-07-28 11:04:54 -04004452
Herb Derbyfcac00f2018-05-01 11:57:56 -04004453 Converts glyphs into text if possible.
4454 Glyph values without direct Unicode equivalents are mapped to zero.
Cary Clark8032b982017-07-28 11:04:54 -04004455 Uses the Typeface, but is unaffected
4456 by Text_Encoding; the text values returned are equivalent to kUTF32_TextEncoding.
4457
4458 Only supported on platforms that use FreeType as the Font_Engine.
4459
4460 #Param glyphs array of indices into font ##
4461 #Param count length of glyph array ##
4462 #Param text storage for character codes, one per glyph ##
4463
4464 #Example
4465 #Height 64
4466 #Description
4467 Convert UTF-8 text to glyphs; then convert glyphs to Unichar code points.
4468 ##
4469 void draw(SkCanvas* canvas) {
4470 SkPaint paint;
4471 const char hello[] = "Hello!";
4472 const int count = sizeof(hello) - 1;
4473 SkGlyphID glyphs[count];
4474 if (count != paint.textToGlyphs(hello, count, glyphs)) {
4475 return;
4476 }
4477 SkUnichar unichars[count];
4478 paint.glyphsToUnichars(glyphs, count, unichars);
4479 paint.setTextEncoding(SkPaint::kUTF32_TextEncoding);
4480 canvas->drawText(unichars, sizeof(unichars), 10, 30, paint);
4481 }
4482 ##
4483
4484##
4485
4486# ------------------------------------------------------------------------------
Cary Clark08895c42018-02-01 09:37:32 -05004487#Subtopic Measure_Text
4488#Line # width, height, bounds of text ##
Cary Clark8032b982017-07-28 11:04:54 -04004489
4490#Method SkScalar measureText(const void* text, size_t length, SkRect* bounds) const
4491
Cary Clarkab2621d2018-01-30 10:08:57 -05004492#In Measure_Text
4493#Line # returns advance width and bounds of text ##
Cary Clark8032b982017-07-28 11:04:54 -04004494 Returns the advance width of text if kVerticalText_Flag is clear,
4495 and the height of text if kVerticalText_Flag is set.
4496 The advance is the normal distance to move before drawing additional text.
4497 Uses Text_Encoding to decode text, Typeface to get the font metrics,
4498 and Text_Size, Text_Scale_X, Text_Skew_X, Stroke_Width, and
4499 Path_Effect to scale the metrics and bounds.
4500 Returns the bounding box of text if bounds is not nullptr.
4501 The bounding box is computed as if the text was drawn at the origin.
Herb Derbyfcac00f2018-05-01 11:57:56 -04004502
Cary Clark8032b982017-07-28 11:04:54 -04004503 #Param text character codes or glyph indices to be measured ##
4504 #Param length number of bytes of text to measure ##
4505 #Param bounds returns bounding box relative to (0, 0) if not nullptr ##
4506
4507 #Return advance width or height ##
4508
4509 #Example
4510 #Height 64
4511 void draw(SkCanvas* canvas) {
4512 SkPaint paint;
4513 paint.setAntiAlias(true);
4514 paint.setTextSize(50);
4515 const char str[] = "ay^jZ";
4516 const int count = sizeof(str) - 1;
4517 canvas->drawText(str, count, 25, 50, paint);
4518 SkRect bounds;
4519 paint.measureText(str, count, &bounds);
4520 canvas->translate(25, 50);
4521 paint.setStyle(SkPaint::kStroke_Style);
4522 canvas->drawRect(bounds, paint);
4523 }
4524 ##
4525
4526##
4527
4528#Method SkScalar measureText(const void* text, size_t length) const
4529
Cary Clarkab2621d2018-01-30 10:08:57 -05004530#In Measure_Text
Cary Clark8032b982017-07-28 11:04:54 -04004531 Returns the advance width of text if kVerticalText_Flag is clear,
4532 and the height of text if kVerticalText_Flag is set.
4533 The advance is the normal distance to move before drawing additional text.
4534 Uses Text_Encoding to decode text, Typeface to get the font metrics,
4535 and Text_Size to scale the metrics.
4536 Does not scale the advance or bounds by Fake_Bold or Path_Effect.
4537
4538 #Param text character codes or glyph indices to be measured ##
4539 #Param length number of bytes of text to measure ##
4540
4541 #Return advance width or height ##
4542
4543 #Example
4544 SkPaint paint;
4545 SkDebugf("default width = %g\n", paint.measureText("!", 1));
4546 paint.setTextSize(paint.getTextSize() * 2);
4547 SkDebugf("double width = %g\n", paint.measureText("!", 1));
4548
4549 #StdOut
4550 default width = 5
4551 double width = 10
4552 ##
4553 ##
4554
4555##
4556
4557#Method size_t breakText(const void* text, size_t length, SkScalar maxWidth,
Cary Clark73fa9722017-08-29 17:36:51 -04004558 SkScalar* measuredWidth = nullptr) const
Cary Clarkab2621d2018-01-30 10:08:57 -05004559#In Measure_Text
4560#Line # returns text that fits in a width ##
Cary Clark8032b982017-07-28 11:04:54 -04004561
4562 Returns the bytes of text that fit within maxWidth.
4563 If kVerticalText_Flag is clear, the text fragment fits if its advance width is less than or
4564 equal to maxWidth.
4565 If kVerticalText_Flag is set, the text fragment fits if its advance height is less than or
4566 equal to maxWidth.
4567 Measures only while the advance is less than or equal to maxWidth.
4568 Returns the advance or the text fragment in measuredWidth if it not nullptr.
4569 Uses Text_Encoding to decode text, Typeface to get the font metrics,
4570 and Text_Size to scale the metrics.
4571 Does not scale the advance or bounds by Fake_Bold or Path_Effect.
4572
4573 #Param text character codes or glyph indices to be measured ##
4574 #Param length number of bytes of text to measure ##
4575 #Param maxWidth advance limit; text is measured while advance is less than maxWidth ##
4576 #Param measuredWidth returns the width of the text less than or equal to maxWidth ##
4577 #Return bytes of text that fit, always less than or equal to length ##
Herb Derbyfcac00f2018-05-01 11:57:56 -04004578
Cary Clark8032b982017-07-28 11:04:54 -04004579 #Example
4580 #Description
4581 Line under "Breakfast" shows desired width, shorter than available characters.
4582 Line under "Bre" shows measured width after breaking text.
4583 ##
4584 #Height 128
4585 #Width 280
4586 void draw(SkCanvas* canvas) {
4587 SkPaint paint;
4588 paint.setAntiAlias(true);
4589 paint.setTextSize(50);
4590 const char str[] = "Breakfast";
4591 const int count = sizeof(str) - 1;
4592 canvas->drawText(str, count, 25, 50, paint);
4593 SkScalar measuredWidth;
4594 int partialBytes = paint.breakText(str, count, 100, &measuredWidth);
4595 canvas->drawText(str, partialBytes, 25, 100, paint);
4596 canvas->drawLine(25, 60, 25 + 100, 60, paint);
4597 canvas->drawLine(25, 110, 25 + measuredWidth, 110, paint);
4598 }
4599 ##
4600
4601##
4602
4603#Method int getTextWidths(const void* text, size_t byteLength, SkScalar widths[],
Cary Clark73fa9722017-08-29 17:36:51 -04004604 SkRect bounds[] = nullptr) const
Cary Clarkab2621d2018-01-30 10:08:57 -05004605#In Measure_Text
4606#Line # returns advance and bounds for each glyph in text ##
Cary Clark8032b982017-07-28 11:04:54 -04004607
4608 Retrieves the advance and bounds for each glyph in text, and returns
4609 the glyph count in text.
4610 Both widths and bounds may be nullptr.
4611 If widths is not nullptr, widths must be an array of glyph count entries.
Herb Derbyfcac00f2018-05-01 11:57:56 -04004612 if bounds is not nullptr, bounds must be an array of glyph count entries.
Cary Clark8032b982017-07-28 11:04:54 -04004613 If kVerticalText_Flag is clear, widths returns the horizontal advance.
4614 If kVerticalText_Flag is set, widths returns the vertical advance.
4615 Uses Text_Encoding to decode text, Typeface to get the font metrics,
4616 and Text_Size to scale the widths and bounds.
4617 Does not scale the advance by Fake_Bold or Path_Effect.
4618 Does include Fake_Bold and Path_Effect in the bounds.
Herb Derbyfcac00f2018-05-01 11:57:56 -04004619
Cary Clark8032b982017-07-28 11:04:54 -04004620 #Param text character codes or glyph indices to be measured ##
4621 #Param byteLength number of bytes of text to measure ##
4622 #Param widths returns text advances for each glyph; may be nullptr ##
4623 #Param bounds returns bounds for each glyph relative to (0, 0); may be nullptr ##
Herb Derbyfcac00f2018-05-01 11:57:56 -04004624
Cary Clark8032b982017-07-28 11:04:54 -04004625 #Return glyph count in text ##
4626
4627 #Example
4628 #Height 160
4629 #Description
Cary Clarkce101242017-09-01 15:51:02 -04004630 Bounds of Glyphs increase for stroked text, but text advance remains the same.
Cary Clark8032b982017-07-28 11:04:54 -04004631 The underlines show the text advance, spaced to keep them distinct.
4632 ##
4633 void draw(SkCanvas* canvas) {
4634 SkPaint paint;
4635 paint.setAntiAlias(true);
4636 paint.setTextSize(50);
4637 const char str[] = "abc";
4638 const int bytes = sizeof(str) - 1;
4639 int count = paint.getTextWidths(str, bytes, nullptr);
4640 std::vector<SkScalar> widths;
4641 std::vector<SkRect> bounds;
4642 widths.resize(count);
4643 bounds.resize(count);
4644 for (int loop = 0; loop < 2; ++loop) {
4645 (void) paint.getTextWidths(str, count, &widths.front(), &bounds.front());
4646 SkPoint loc = { 25, 50 };
4647 canvas->drawText(str, bytes, loc.fX, loc.fY, paint);
4648 paint.setStyle(SkPaint::kStroke_Style);
4649 paint.setStrokeWidth(0);
4650 SkScalar advanceY = loc.fY + 10;
4651 for (int index = 0; index < count; ++index) {
4652 bounds[index].offset(loc.fX, loc.fY);
4653 canvas->drawRect(bounds[index], paint);
4654 canvas->drawLine(loc.fX, advanceY, loc.fX + widths[index], advanceY, paint);
4655 loc.fX += widths[index];
4656 advanceY += 5;
4657 }
4658 canvas->translate(0, 80);
4659 paint.setStrokeWidth(3);
4660 }
4661 }
4662 ##
4663
4664##
4665
Cary Clark08895c42018-02-01 09:37:32 -05004666#Subtopic Measure_Text ##
Cary Clark8032b982017-07-28 11:04:54 -04004667# ------------------------------------------------------------------------------
Cary Clark08895c42018-02-01 09:37:32 -05004668#Subtopic Text_Path
4669#Line # geometry of Glyphs ##
Cary Clark8032b982017-07-28 11:04:54 -04004670
Cary Clarkce101242017-09-01 15:51:02 -04004671Text_Path describes the geometry of Glyphs used to draw text.
Cary Clark8032b982017-07-28 11:04:54 -04004672
4673#Method void getTextPath(const void* text, size_t length, SkScalar x, SkScalar y,
4674 SkPath* path) const
Cary Clarkab2621d2018-01-30 10:08:57 -05004675#In Text_Path
4676#Line # returns Path equivalent to text ##
Cary Clark8032b982017-07-28 11:04:54 -04004677
4678Returns the geometry as Path equivalent to the drawn text.
4679Uses Text_Encoding to decode text, Typeface to get the glyph paths,
4680and Text_Size, Fake_Bold, and Path_Effect to scale and modify the glyph paths.
4681All of the glyph paths are stored in path.
Cary Clark579985c2017-07-31 11:48:27 -04004682Uses x, y, and Text_Align to position path.
Cary Clark8032b982017-07-28 11:04:54 -04004683
4684 #Param text character codes or glyph indices ##
4685 #Param length number of bytes of text ##
Cary Clark5538c132018-06-14 12:28:14 -04004686 #Param x x-axis value of the origin of the text ##
4687 #Param y y-axis value of the origin of the text ##
Cary Clarkce101242017-09-01 15:51:02 -04004688 #Param path geometry of the Glyphs ##
Cary Clark8032b982017-07-28 11:04:54 -04004689
4690 #Example
4691 #Description
4692 Text is added to Path, offset, and subtracted from Path, then added at
4693 the offset location. The result is rendered with one draw call.
4694 ##
4695 #Height 128
4696 void draw(SkCanvas* canvas) {
4697 SkPaint paint;
4698 paint.setTextSize(80);
4699 SkPath path, path2;
4700 paint.getTextPath("ABC", 3, 20, 80, &path);
4701 path.offset(20, 20, &path2);
4702 Op(path, path2, SkPathOp::kDifference_SkPathOp, &path);
4703 path.addPath(path2);
4704 paint.setStyle(SkPaint::kStroke_Style);
4705 canvas->drawPath(path, paint);
4706 }
4707 ##
4708
4709##
4710
4711#Method void getPosTextPath(const void* text, size_t length,
4712 const SkPoint pos[], SkPath* path) const
Cary Clarkab2621d2018-01-30 10:08:57 -05004713#In Text_Path
4714#Line # returns Path equivalent to positioned text ##
Cary Clark8032b982017-07-28 11:04:54 -04004715
4716Returns the geometry as Path equivalent to the drawn text.
4717Uses Text_Encoding to decode text, Typeface to get the glyph paths,
4718and Text_Size, Fake_Bold, and Path_Effect to scale and modify the glyph paths.
4719All of the glyph paths are stored in path.
4720Uses pos array and Text_Align to position path.
4721pos contains a position for each glyph.
4722
4723 #Param text character codes or glyph indices ##
4724 #Param length number of bytes of text ##
4725 #Param pos positions of each glyph ##
Cary Clarkce101242017-09-01 15:51:02 -04004726 #Param path geometry of the Glyphs ##
Cary Clark8032b982017-07-28 11:04:54 -04004727
4728 #Example
4729 #Height 85
4730 #Description
Cary Clarkce101242017-09-01 15:51:02 -04004731 Simplifies three Glyphs to eliminate overlaps, and strokes the result.
Cary Clark8032b982017-07-28 11:04:54 -04004732 ##
4733 void draw(SkCanvas* canvas) {
4734 SkPaint paint;
4735 paint.setTextSize(80);
4736 SkPath path, path2;
4737 SkPoint pos[] = {{20, 60}, {30, 70}, {40, 80}};
4738 paint.getPosTextPath("ABC", 3, pos, &path);
4739 Simplify(path, &path);
4740 paint.setStyle(SkPaint::kStroke_Style);
4741 canvas->drawPath(path, paint);
4742 }
4743 ##
4744
4745##
4746
Cary Clark08895c42018-02-01 09:37:32 -05004747#Subtopic Text_Path ##
Cary Clark8032b982017-07-28 11:04:54 -04004748# ------------------------------------------------------------------------------
Cary Clark08895c42018-02-01 09:37:32 -05004749#Subtopic Text_Intercepts
4750#Line # advanced underline, strike through ##
Cary Clark8032b982017-07-28 11:04:54 -04004751
Cary Clarkce101242017-09-01 15:51:02 -04004752Text_Intercepts describe the intersection of drawn text Glyphs with a pair
Cary Clark8032b982017-07-28 11:04:54 -04004753of lines parallel to the text advance. Text_Intercepts permits creating a
Cary Clarkce101242017-09-01 15:51:02 -04004754underline that skips Descenders.
Cary Clark8032b982017-07-28 11:04:54 -04004755
4756#Method int getTextIntercepts(const void* text, size_t length, SkScalar x, SkScalar y,
4757 const SkScalar bounds[2], SkScalar* intervals) const
Cary Clarkab2621d2018-01-30 10:08:57 -05004758#In Text_Intercepts
4759#Line # returns where lines intersect text; underlines ##
Cary Clark8032b982017-07-28 11:04:54 -04004760
4761 Returns the number of intervals that intersect bounds.
4762 bounds describes a pair of lines parallel to the text advance.
Cary Clarkce101242017-09-01 15:51:02 -04004763 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 -04004764 the string.
Cary Clark8032b982017-07-28 11:04:54 -04004765 Uses Text_Encoding to decode text, Typeface to get the glyph paths,
4766 and Text_Size, Fake_Bold, and Path_Effect to scale and modify the glyph paths.
4767 Uses x, y, and Text_Align to position intervals.
Herb Derbyfcac00f2018-05-01 11:57:56 -04004768
Cary Clark8032b982017-07-28 11:04:54 -04004769 Pass nullptr for intervals to determine the size of the interval array.
Herb Derbyfcac00f2018-05-01 11:57:56 -04004770
Cary Clark8032b982017-07-28 11:04:54 -04004771 intervals are cached to improve performance for multiple calls.
4772
4773 #Param text character codes or glyph indices ##
4774 #Param length number of bytes of text ##
Cary Clark5538c132018-06-14 12:28:14 -04004775 #Param x x-axis value of the origin of the text ##
4776 #Param y y-axis value of the origin of the text ##
Cary Clark8032b982017-07-28 11:04:54 -04004777 #Param bounds lower and upper line parallel to the advance ##
4778 #Param intervals returned intersections; may be nullptr ##
4779
4780 #Return number of intersections; may be zero ##
4781
4782#Example
4783#Height 128
4784#Description
Cary Clarkce101242017-09-01 15:51:02 -04004785Underline uses intercepts to draw on either side of the glyph Descender.
Cary Clark8032b982017-07-28 11:04:54 -04004786##
4787void draw(SkCanvas* canvas) {
4788 SkPaint paint;
4789 paint.setTextSize(120);
4790 SkPoint textOrigin = { 20, 100 };
4791 SkScalar bounds[] = { 100, 108 };
4792 int count = paint.getTextIntercepts("y", 1, textOrigin.fX, textOrigin.fY, bounds, nullptr);
4793 std::vector<SkScalar> intervals;
4794 intervals.resize(count);
4795 (void) paint.getTextIntercepts("y", 1, textOrigin.fX, textOrigin.fY, bounds,
4796 &intervals.front());
4797 canvas->drawString("y", textOrigin.fX, textOrigin.fY, paint);
4798 paint.setColor(SK_ColorRED);
4799 SkScalar x = textOrigin.fX;
4800 for (int i = 0; i < count; i += 2) {
4801 canvas->drawRect({x, bounds[0], intervals[i], bounds[1]}, paint);
4802 x = intervals[i + 1];
4803 }
4804 canvas->drawRect({intervals[count - 1], bounds[0],
4805 textOrigin.fX + paint.measureText("y", 1), bounds[1]}, paint);
4806}
4807##
4808
4809##
4810
4811#Method int getPosTextIntercepts(const void* text, size_t length, const SkPoint pos[],
4812 const SkScalar bounds[2], SkScalar* intervals) const
Cary Clarkab2621d2018-01-30 10:08:57 -05004813#In Text_Intercepts
4814#Line # returns where lines intersect positioned text; underlines ##
Cary Clark8032b982017-07-28 11:04:54 -04004815
4816 Returns the number of intervals that intersect bounds.
4817 bounds describes a pair of lines parallel to the text advance.
Cary Clarkce101242017-09-01 15:51:02 -04004818 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 -04004819 the string.
Cary Clark8032b982017-07-28 11:04:54 -04004820 Uses Text_Encoding to decode text, Typeface to get the glyph paths,
4821 and Text_Size, Fake_Bold, and Path_Effect to scale and modify the glyph paths.
4822 Uses pos array and Text_Align to position intervals.
Herb Derbyfcac00f2018-05-01 11:57:56 -04004823
Cary Clark8032b982017-07-28 11:04:54 -04004824 Pass nullptr for intervals to determine the size of the interval array.
Herb Derbyfcac00f2018-05-01 11:57:56 -04004825
Cary Clark8032b982017-07-28 11:04:54 -04004826 intervals are cached to improve performance for multiple calls.
4827
4828 #Param text character codes or glyph indices ##
4829 #Param length number of bytes of text ##
4830 #Param pos positions of each glyph ##
4831 #Param bounds lower and upper line parallel to the advance ##
4832 #Param intervals returned intersections; may be nullptr ##
4833
Cary Clarka523d2d2017-08-30 08:58:10 -04004834 #Return number of intersections; may be zero ##
Cary Clark8032b982017-07-28 11:04:54 -04004835
4836 #Example
4837 #Description
Cary Clarkce101242017-09-01 15:51:02 -04004838 Text intercepts draw on either side of, but not inside, Glyphs in a run.
Cary Clark8032b982017-07-28 11:04:54 -04004839 ##
4840 void draw(SkCanvas* canvas) {
4841 SkPaint paint;
4842 paint.setTextSize(120);
4843 paint.setVerticalText(true);
4844 SkPoint textPos[] = {{ 60, 40 }, { 60, 140 }};
4845 SkScalar bounds[] = { 56, 64 };
4846 const char str[] = "A-";
4847 int len = sizeof(str) - 1;
4848 int count = paint.getPosTextIntercepts(str, len, textPos, bounds, nullptr);
4849 std::vector<SkScalar> intervals;
4850 intervals.resize(count);
4851 (void) paint.getPosTextIntercepts(str, len, textPos, bounds, &intervals.front());
4852 canvas->drawPosText(str, len, textPos, paint);
4853 paint.setColor(SK_ColorRED);
4854 SkScalar y = textPos[0].fY;
4855 for (int i = 0; i < count; i+= 2) {
4856 canvas->drawRect({bounds[0], y, bounds[1], intervals[i]}, paint);
4857 y = intervals[i + 1];
4858 }
4859 canvas->drawRect({bounds[0], intervals[count - 1], bounds[1], 240}, paint);
4860 }
4861 ##
4862
4863##
4864
4865#Method int getPosTextHIntercepts(const void* text, size_t length, const SkScalar xpos[],
4866 SkScalar constY, const SkScalar bounds[2],
4867 SkScalar* intervals) const
Cary Clarkab2621d2018-01-30 10:08:57 -05004868#In Text_Intercepts
4869#Line # returns where lines intersect horizontally positioned text; underlines ##
Cary Clark8032b982017-07-28 11:04:54 -04004870
4871 Returns the number of intervals that intersect bounds.
4872 bounds describes a pair of lines parallel to the text advance.
Cary Clarkce101242017-09-01 15:51:02 -04004873 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 -04004874 the string.
Cary Clark8032b982017-07-28 11:04:54 -04004875 Uses Text_Encoding to decode text, Typeface to get the glyph paths,
4876 and Text_Size, Fake_Bold, and Path_Effect to scale and modify the glyph paths.
4877 Uses xpos array, constY, and Text_Align to position intervals.
Herb Derbyfcac00f2018-05-01 11:57:56 -04004878
Cary Clark8032b982017-07-28 11:04:54 -04004879 Pass nullptr for intervals to determine the size of the interval array.
Herb Derbyfcac00f2018-05-01 11:57:56 -04004880
Cary Clark8032b982017-07-28 11:04:54 -04004881 intervals are cached to improve performance for multiple calls.
4882
4883 #Param text character codes or glyph indices ##
4884 #Param length number of bytes of text ##
4885 #Param xpos positions of each glyph in x ##
4886 #Param constY position of each glyph in y ##
4887 #Param bounds lower and upper line parallel to the advance ##
4888 #Param intervals returned intersections; may be nullptr ##
4889
4890 #Return number of intersections; may be zero ##
4891
4892 #Example
4893 #Height 128
4894 #Description
4895 Text intercepts do not take stroke thickness into consideration.
4896 ##
4897 void draw(SkCanvas* canvas) {
4898 SkPaint paint;
4899 paint.setTextSize(120);
4900 paint.setStyle(SkPaint::kStroke_Style);
4901 paint.setStrokeWidth(4);
4902 SkScalar textPosH[] = { 20, 80, 140 };
4903 SkScalar y = 100;
4904 SkScalar bounds[] = { 56, 78 };
4905 const char str[] = "\\-/";
4906 int len = sizeof(str) - 1;
4907 int count = paint.getPosTextHIntercepts(str, len, textPosH, y, bounds, nullptr);
4908 std::vector<SkScalar> intervals;
4909 intervals.resize(count);
4910 (void) paint.getPosTextHIntercepts(str, len, textPosH, y, bounds, &intervals.front());
4911 canvas->drawPosTextH(str, len, textPosH, y, paint);
4912 paint.setColor(0xFFFF7777);
4913 paint.setStyle(SkPaint::kFill_Style);
4914 SkScalar x = textPosH[0];
4915 for (int i = 0; i < count; i+= 2) {
4916 canvas->drawRect({x, bounds[0], intervals[i], bounds[1]}, paint);
4917 x = intervals[i + 1];
4918 }
4919 canvas->drawRect({intervals[count - 1], bounds[0], 180, bounds[1]}, paint);
4920 }
4921 ##
4922
4923##
4924
4925
4926#Method int getTextBlobIntercepts(const SkTextBlob* blob, const SkScalar bounds[2],
4927 SkScalar* intervals) const
Cary Clarkab2621d2018-01-30 10:08:57 -05004928#In Text_Intercepts
4929#Line # returns where lines intersect Text_Blob; underlines ##
Cary Clark8032b982017-07-28 11:04:54 -04004930
4931 Returns the number of intervals that intersect bounds.
4932 bounds describes a pair of lines parallel to the text advance.
Cary Clarkce101242017-09-01 15:51:02 -04004933 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 -04004934 the string.
Cary Clark3cd22cc2017-12-01 11:49:58 -05004935 Uses Typeface to get the glyph paths,
Cary Clark8032b982017-07-28 11:04:54 -04004936 and Text_Size, Fake_Bold, and Path_Effect to scale and modify the glyph paths.
Cary Clarkce101242017-09-01 15:51:02 -04004937 Uses run array and Text_Align to position intervals.
Herb Derbyfcac00f2018-05-01 11:57:56 -04004938
Cary Clark3cd22cc2017-12-01 11:49:58 -05004939 Text_Encoding must be set to SkPaint::kGlyphID_TextEncoding.
4940
Cary Clark8032b982017-07-28 11:04:54 -04004941 Pass nullptr for intervals to determine the size of the interval array.
Herb Derbyfcac00f2018-05-01 11:57:56 -04004942
Cary Clark8032b982017-07-28 11:04:54 -04004943 intervals are cached to improve performance for multiple calls.
4944
Cary Clarkce101242017-09-01 15:51:02 -04004945 #Param blob Glyphs, positions, and text paint attributes ##
Cary Clark8032b982017-07-28 11:04:54 -04004946 #Param bounds lower and upper line parallel to the advance ##
4947 #Param intervals returned intersections; may be nullptr ##
4948
4949 #Return number of intersections; may be zero ##
4950
4951 #Example
4952 #Height 143
4953 void draw(SkCanvas* canvas) {
4954 SkPaint paint;
Cary Clark3cd22cc2017-12-01 11:49:58 -05004955 paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
Cary Clark8032b982017-07-28 11:04:54 -04004956 paint.setTextSize(120);
4957 SkPoint textPos = { 20, 110 };
4958 int len = 3;
4959 SkTextBlobBuilder textBlobBuilder;
Herb Derbyfcac00f2018-05-01 11:57:56 -04004960 const SkTextBlobBuilder::RunBuffer& run =
Cary Clark8032b982017-07-28 11:04:54 -04004961 textBlobBuilder.allocRun(paint, len, textPos.fX, textPos.fY);
4962 run.glyphs[0] = 10;
4963 run.glyphs[1] = 20;
Herb Derbyfcac00f2018-05-01 11:57:56 -04004964 run.glyphs[2] = 30;
Cary Clark8032b982017-07-28 11:04:54 -04004965 sk_sp<const SkTextBlob> blob = textBlobBuilder.make();
4966 canvas->drawTextBlob(blob.get(), textPos.fX, textPos.fY, paint);
4967 SkScalar bounds[] = { 116, 134 };
4968 int count = paint.getTextBlobIntercepts(blob.get(), bounds, nullptr);
4969 std::vector<SkScalar> intervals;
4970 intervals.resize(count);
4971 (void) paint.getTextBlobIntercepts(blob.get(), bounds, &intervals.front());
4972 canvas->drawTextBlob(blob.get(), 0, 0, paint);
4973 paint.setColor(0xFFFF7777);
4974 SkScalar x = textPos.fX;
4975 for (int i = 0; i < count; i+= 2) {
4976 canvas->drawRect({x, bounds[0], intervals[i], bounds[1]}, paint);
4977 x = intervals[i + 1];
4978 }
4979 canvas->drawRect({intervals[count - 1], bounds[0], 180, bounds[1]}, paint);
4980 }
4981 ##
4982
4983##
4984
Cary Clark08895c42018-02-01 09:37:32 -05004985#Subtopic Text_Intercepts ##
Cary Clark8032b982017-07-28 11:04:54 -04004986# ------------------------------------------------------------------------------
4987
4988#Method bool nothingToDraw() const
Cary Clark78de7512018-02-07 07:27:09 -05004989#In Utility
Cary Clarkab2621d2018-01-30 10:08:57 -05004990#Line # returns true if Paint prevents all drawing ##
Cary Clark579985c2017-07-31 11:48:27 -04004991 Returns true if Paint prevents all drawing;
4992 otherwise, the Paint may or may not allow drawing.
Cary Clark8032b982017-07-28 11:04:54 -04004993
Cary Clarkce101242017-09-01 15:51:02 -04004994 Returns true if, for example, Blend_Mode combined with Color_Alpha computes a
4995 new Alpha of zero.
Cary Clark8032b982017-07-28 11:04:54 -04004996
4997 #Return true if Paint prevents all drawing ##
4998
4999 #Example
5000 void draw(SkCanvas* canvas) {
5001 auto debugster = [](const char* prefix, const SkPaint& p) -> void {
Herb Derbyfcac00f2018-05-01 11:57:56 -04005002 SkDebugf("%s nothing to draw: %s\n", prefix,
Cary Clark8032b982017-07-28 11:04:54 -04005003 p.nothingToDraw() ? "true" : "false");
5004 };
5005 SkPaint paint;
5006 debugster("initial", paint);
5007 paint.setBlendMode(SkBlendMode::kDst);
5008 debugster("blend dst", paint);
5009 paint.setBlendMode(SkBlendMode::kSrcOver);
5010 debugster("blend src over", paint);
5011 paint.setAlpha(0);
5012 debugster("alpha 0", paint);
5013 }
5014
5015 #StdOut
5016 initial nothing to draw: false
5017 blend dst nothing to draw: true
5018 blend src over nothing to draw: false
5019 alpha 0 nothing to draw: true
5020 #StdOut ##
5021 ##
5022
5023##
5024
5025# ------------------------------------------------------------------------------
Cary Clark08895c42018-02-01 09:37:32 -05005026#Subtopic Fast_Bounds
5027#Line # approximate area required by Paint ##
Herb Derbyfcac00f2018-05-01 11:57:56 -04005028 #Private
5029 To be made private.
Cary Clark8032b982017-07-28 11:04:54 -04005030 ##
5031
Cary Clark682c58d2018-05-16 07:07:07 -04005032Fast_Bounds functions conservatively outset a drawing bounds by additional area
Cary Clark8032b982017-07-28 11:04:54 -04005033Paint may draw to.
5034
5035#Method bool canComputeFastBounds() const
Herb Derbyfcac00f2018-05-01 11:57:56 -04005036
Cary Clarkab2621d2018-01-30 10:08:57 -05005037#In Fast_Bounds
Cary Clark1a8d7622018-03-05 13:26:16 -05005038#Line # returns true if settings allow for fast bounds computation ##
Herb Derbyfcac00f2018-05-01 11:57:56 -04005039 #Private
Cary Clark8032b982017-07-28 11:04:54 -04005040 (to be made private)
5041 ##
5042
5043 Returns true if Paint does not include elements requiring extensive computation
5044 to compute Device bounds of drawn geometry. For instance, Paint with Path_Effect
5045 always returns false.
5046
5047 #Return true if Paint allows for fast computation of bounds ##
5048##
5049
5050#Method const SkRect& computeFastBounds(const SkRect& orig, SkRect* storage) const
Herb Derbyfcac00f2018-05-01 11:57:56 -04005051
Cary Clarkab2621d2018-01-30 10:08:57 -05005052#In Fast_Bounds
Cary Clark1a8d7622018-03-05 13:26:16 -05005053#Line # returns fill bounds for quick reject tests ##
Herb Derbyfcac00f2018-05-01 11:57:56 -04005054 #Private
Cary Clark8032b982017-07-28 11:04:54 -04005055 (to be made private)
5056 ##
5057
5058 Only call this if canComputeFastBounds returned true. This takes a
5059 raw rectangle (the raw bounds of a shape), and adjusts it for stylistic
5060 effects in the paint (e.g. stroking). If needed, it uses the storage
Cary Clarkce101242017-09-01 15:51:02 -04005061 parameter. It returns the adjusted bounds that can then be used
Cary Clark8032b982017-07-28 11:04:54 -04005062 for SkCanvas::quickReject tests.
5063
Cary Clarkce101242017-09-01 15:51:02 -04005064 The returned Rect will either be orig or storage, thus the caller
Cary Clark8032b982017-07-28 11:04:54 -04005065 should not rely on storage being set to the result, but should always
Cary Clarkce101242017-09-01 15:51:02 -04005066 use the returned value. It is legal for orig and storage to be the same
5067 Rect.
Cary Clark8032b982017-07-28 11:04:54 -04005068
Herb Derbyfcac00f2018-05-01 11:57:56 -04005069 #Private
Cary Clark682c58d2018-05-16 07:07:07 -04005070 For example:
5071 if (!path.isInverseFillType() && paint.canComputeFastBounds()) {
5072 SkRect storage;
5073 if (canvas->quickReject(paint.computeFastBounds(path.getBounds(), &storage))) {
Cary Clark137b8742018-05-30 09:21:49 -04005074 return; // do not draw the path
Cary Clark682c58d2018-05-16 07:07:07 -04005075 }
Cary Clark8032b982017-07-28 11:04:54 -04005076 }
Cary Clark682c58d2018-05-16 07:07:07 -04005077 // draw the path
Cary Clark8032b982017-07-28 11:04:54 -04005078 ##
5079
5080 #Param orig geometry modified by Paint when drawn ##
5081 #Param storage computed bounds of geometry; may not be nullptr ##
5082
5083 #Return fast computed bounds ##
5084##
5085
5086#Method const SkRect& computeFastStrokeBounds(const SkRect& orig,
5087 SkRect* storage) const
Cary Clarkab2621d2018-01-30 10:08:57 -05005088#In Fast_Bounds
5089#Line # returns stroke bounds for quick reject tests ##
Herb Derbyfcac00f2018-05-01 11:57:56 -04005090 #Private
Cary Clark8032b982017-07-28 11:04:54 -04005091 (to be made private)
5092 ##
5093
5094 #Param orig geometry modified by Paint when drawn ##
5095 #Param storage computed bounds of geometry ##
5096
5097 #Return fast computed bounds ##
5098##
5099
5100#Method const SkRect& doComputeFastBounds(const SkRect& orig, SkRect* storage,
5101 Style style) const
Cary Clarkab2621d2018-01-30 10:08:57 -05005102#In Fast_Bounds
5103#Line # returns bounds for quick reject tests ##
Herb Derbyfcac00f2018-05-01 11:57:56 -04005104 #Private
Cary Clark8032b982017-07-28 11:04:54 -04005105 (to be made private)
5106 ##
5107
Cary Clarkce101242017-09-01 15:51:02 -04005108 Computes the bounds, overriding the Paint Style. This can be used to
5109 account for additional width required by stroking orig, without
5110 altering Style set to fill.
Cary Clark8032b982017-07-28 11:04:54 -04005111
5112 #Param orig geometry modified by Paint when drawn ##
5113 #Param storage computed bounds of geometry ##
5114 #Param style overrides Style ##
5115
5116 #Return fast computed bounds ##
5117##
5118
Cary Clark1a8d7622018-03-05 13:26:16 -05005119#Subtopic Fast_Bounds ##
Cary Clark8032b982017-07-28 11:04:54 -04005120
5121# ------------------------------------------------------------------------------
Cary Clark78de7512018-02-07 07:27:09 -05005122#Subtopic Utility
5123#Populate
5124#Line # rarely called management functions ##
5125##
Cary Clark8032b982017-07-28 11:04:54 -04005126
Cary Clark8032b982017-07-28 11:04:54 -04005127# ------------------------------------------------------------------------------
5128
5129#Class SkPaint ##
5130
5131#Topic Paint ##
Cary Clark4855f782018-02-06 09:41:53 -05005132