blob: 5c03452103249d9e79bff833aa6e34b0f88cdd9e [file] [log] [blame]
Cary Clark0c5f5462017-12-15 11:21:51 -05001#Topic Paint
Cary Clark12799e12017-07-28 15:18:29 -04002#Alias Paint_Reference
Cary Clark8032b982017-07-28 11:04:54 -04003
Cary Clark08895c42018-02-01 09:37:32 -05004#Subtopic Overview
Cary Clark4855f782018-02-06 09:41:53 -05005 #Subtopic Subtopic
Cary Clark08895c42018-02-01 09:37:32 -05006 #Populate
7 ##
8##
9
Cary Clarke4aa3712017-09-15 02:56:12 -040010#Class SkPaint
11
Cary Clark8032b982017-07-28 11:04:54 -040012Paint controls options applied when drawing and measuring. Paint collects all
13options outside of the Canvas_Clip and Canvas_Matrix.
14
15Various options apply to text, strokes and fills, and images.
16
17Some options may not be implemented on all platforms; in these cases, setting
18the option has no effect. Some options are conveniences that duplicate Canvas
19functionality; for instance, text size is identical to matrix scale.
20
21Paint options are rarely exclusive; each option modifies a stage of the drawing
22pipeline and multiple pipeline stages may be affected by a single Paint.
23
24Paint collects effects and filters that describe single-pass and multiple-pass
25algorithms that alter the drawing geometry, color, and transparency. For instance,
26Paint does not directly implement dashing or blur, but contains the objects that do so.
27
28The objects contained by Paint are opaque, and cannot be edited outside of the Paint
29to affect it. The implementation is free to defer computations associated with the
30Paint, or ignore them altogether. For instance, some GPU implementations draw all
Cary Clarkce101242017-09-01 15:51:02 -040031Path geometries with Anti-aliasing, regardless of how SkPaint::kAntiAlias_Flag
Cary Clarkbad5ad72017-08-03 17:14:08 -040032is set in Paint.
Cary Clark8032b982017-07-28 11:04:54 -040033
34Paint describes a single color, a single font, a single image quality, and so on.
35Multiple colors are drawn either by using multiple paints or with objects like
36Shader attached to Paint.
37
Cary Clark4855f782018-02-06 09:41:53 -050038#Subtopic Related_Function
Cary Clark08895c42018-02-01 09:37:32 -050039#Populate
40##
Cary Clark8032b982017-07-28 11:04:54 -040041
Cary Clark4855f782018-02-06 09:41:53 -050042#Subtopic Constant
Cary Clark08895c42018-02-01 09:37:32 -050043#Populate
44##
Cary Clark8032b982017-07-28 11:04:54 -040045
Cary Clark4855f782018-02-06 09:41:53 -050046#Subtopic Class_or_Struct
Cary Clark08895c42018-02-01 09:37:32 -050047#Populate
48##
Cary Clark8032b982017-07-28 11:04:54 -040049
Cary Clark4855f782018-02-06 09:41:53 -050050#Subtopic Constructor
Cary Clark08895c42018-02-01 09:37:32 -050051#Populate
52##
Cary Clark8032b982017-07-28 11:04:54 -040053
Cary Clark4855f782018-02-06 09:41:53 -050054#Subtopic Operator
Cary Clark08895c42018-02-01 09:37:32 -050055#Populate
56##
Cary Clark8032b982017-07-28 11:04:54 -040057
Cary Clark4855f782018-02-06 09:41:53 -050058#Subtopic Member_Function
Cary Clark08895c42018-02-01 09:37:32 -050059#Populate
60##
Cary Clark8032b982017-07-28 11:04:54 -040061
62# ------------------------------------------------------------------------------
Cary Clark08895c42018-02-01 09:37:32 -050063#Subtopic Initializers
64#Line # constructors and initialization ##
Cary Clark8032b982017-07-28 11:04:54 -040065
66#Method SkPaint()
67
Cary Clarkab2621d2018-01-30 10:08:57 -050068#In Initializers
69#Line # constructs with default values ##
Cary Clark8032b982017-07-28 11:04:54 -040070Constructs Paint with default values.
71
72#Table
73#Legend
74# attribute # default value ##
75#Legend ##
76# Anti-alias # false ##
Cary Clarkce101242017-09-01 15:51:02 -040077# Blend_Mode # SkBlendMode::kSrcOver ##
Cary Clark8032b982017-07-28 11:04:54 -040078# Color # SK_ColorBLACK ##
79# Color_Alpha # 255 ##
80# Color_Filter # nullptr ##
81# Dither # false ##
82# Draw_Looper # nullptr ##
83# Fake_Bold # false ##
84# Filter_Quality # kNone_SkFilterQuality ##
85# Font_Embedded_Bitmaps # false ##
86# Automatic_Hinting # false ##
87# Full_Hinting_Spacing # false ##
88# Hinting # kNormal_Hinting ##
89# Image_Filter # nullptr ##
90# LCD_Text # false ##
91# Linear_Text # false ##
92# Miter_Limit # 4 ##
93# Mask_Filter # nullptr ##
94# Path_Effect # nullptr ##
Cary Clark8032b982017-07-28 11:04:54 -040095# Shader # nullptr ##
96# Style # kFill_Style ##
97# Text_Align # kLeft_Align ##
98# Text_Encoding # kUTF8_TextEncoding ##
99# Text_Scale_X # 1 ##
100# Text_Size # 12 ##
101# Text_Skew_X # 0 ##
102# Typeface # nullptr ##
103# Stroke_Cap # kButt_Cap ##
104# Stroke_Join # kMiter_Join ##
105# Stroke_Width # 0 ##
106# Subpixel_Text # false ##
107# Vertical_Text # false ##
108#Table ##
109
110The flags, text size, hinting, and miter limit may be overridden at compile time by defining
Cary Clarkce101242017-09-01 15:51:02 -0400111paint default values. The overrides may be included in "SkUserConfig.h" or predefined by the
Cary Clark8032b982017-07-28 11:04:54 -0400112build system.
113
114#Return default initialized Paint ##
115
116#Example
117#ToDo mark this as no output ##
118#Height 1
119###$ $ redefine markup character so preprocessor commands appear normally
120#ifndef SkUserConfig_DEFINED
121#define SkUserConfig_DEFINED
122
123#define SkPaintDefaults_Flags 0x01 // always enable antialiasing
124#define SkPaintDefaults_TextSize 24.f // double default font size
125#define SkPaintDefaults_Hinting 3 // use full hinting
126#define SkPaintDefaults_MiterLimit 10.f // use HTML Canvas miter limit setting
127
128#endif
129$$$# # restore original markup character
130##
131
132
133##
134
135#Method SkPaint(const SkPaint& paint)
136
Cary Clarkab2621d2018-01-30 10:08:57 -0500137#In Initializers
138#Line # makes a shallow copy ##
Cary Clark8032b982017-07-28 11:04:54 -0400139Makes a shallow copy of Paint. Typeface, Path_Effect, Shader,
Mike Reed8ad91a92018-01-19 19:09:32 -0500140Mask_Filter, Color_Filter, Draw_Looper, and Image_Filter are shared
Cary Clarkbad5ad72017-08-03 17:14:08 -0400141between the original paint and the copy. Objects containing Reference_Count increment
142their references by one.
Cary Clark8032b982017-07-28 11:04:54 -0400143
Mike Reed8ad91a92018-01-19 19:09:32 -0500144The referenced objects Path_Effect, Shader, Mask_Filter, Color_Filter,
Cary Clark8032b982017-07-28 11:04:54 -0400145Draw_Looper, and Image_Filter cannot be modified after they are created.
146This prevents objects with Reference_Count from being modified once Paint refers to them.
147
148#Param paint original to copy ##
149
150#Return shallow copy of paint ##
151
152#Example
153#ToDo why is this double-spaced on Fiddle? ##
154 SkPaint paint1;
155 paint1.setColor(SK_ColorRED);
156 SkPaint paint2(paint1);
157 paint2.setColor(SK_ColorBLUE);
158 SkDebugf("SK_ColorRED %c= paint1.getColor()\n", SK_ColorRED == paint1.getColor() ? '=' : '!');
159 SkDebugf("SK_ColorBLUE %c= paint2.getColor()\n", SK_ColorBLUE == paint2.getColor() ? '=' : '!');
160
161 #StdOut
162 SK_ColorRED == paint1.getColor()
163 SK_ColorBLUE == paint2.getColor()
164 ##
165##
166
167##
168
169#Method SkPaint(SkPaint&& paint)
170
Cary Clarkab2621d2018-01-30 10:08:57 -0500171#In Initializers
172#Line # moves paint without copying it ##
Cary Clarkd0530ba2017-09-14 11:25:39 -0400173 Implements a move constructor to avoid increasing the reference counts
Cary Clark8032b982017-07-28 11:04:54 -0400174 of objects referenced by the paint.
175
176 After the call, paint is undefined, and can be safely destructed.
177
178 #Param paint original to move ##
179
180 #Return content of paint ##
181
182 #Example
183 SkPaint paint;
184 float intervals[] = { 5, 5 };
185 paint.setPathEffect(SkDashPathEffect::Make(intervals, SK_ARRAY_COUNT(intervals), 2.5f));
186 SkPaint dashed(std::move(paint));
187 SkDebugf("path effect unique: %s\n", dashed.getPathEffect()->unique() ? "true" : "false");
188
189 #StdOut
190 path effect unique: true
191 ##
192 ##
193
194##
195
196# ------------------------------------------------------------------------------
197
198#Method void reset()
199
Cary Clarkab2621d2018-01-30 10:08:57 -0500200#In Initializers
201#Line # sets to default values ##
Cary Clarkbc5697d2017-10-04 14:31:33 -0400202Sets all Paint contents to their initial values. This is equivalent to replacing
203Paint with the result of SkPaint().
Cary Clark8032b982017-07-28 11:04:54 -0400204
205#Example
206 SkPaint paint1, paint2;
207 paint1.setColor(SK_ColorRED);
208 paint1.reset();
209 SkDebugf("paint1 %c= paint2", paint1 == paint2 ? '=' : '!');
210
211 #StdOut
212 paint1 == paint2
213 ##
214##
215
216##
217
Cary Clark08895c42018-02-01 09:37:32 -0500218#Subtopic Initializers ##
Cary Clark8032b982017-07-28 11:04:54 -0400219
220# ------------------------------------------------------------------------------
Cary Clark8032b982017-07-28 11:04:54 -0400221
222#Method ~SkPaint()
223
Cary Clarkab2621d2018-01-30 10:08:57 -0500224#Line # decreases Reference_Count of owned objects ##
Cary Clark8032b982017-07-28 11:04:54 -0400225Decreases Paint Reference_Count of owned objects: Typeface, Path_Effect, Shader,
Mike Reed8ad91a92018-01-19 19:09:32 -0500226Mask_Filter, Color_Filter, Draw_Looper, and Image_Filter. If the
Cary Clarkbad5ad72017-08-03 17:14:08 -0400227objects containing Reference_Count go to zero, they are deleted.
Cary Clark8032b982017-07-28 11:04:54 -0400228
229#NoExample
230##
231
232##
233
Cary Clark08895c42018-02-01 09:37:32 -0500234
Cary Clark8032b982017-07-28 11:04:54 -0400235# ------------------------------------------------------------------------------
Cary Clark08895c42018-02-01 09:37:32 -0500236#Subtopic Management
237#Line # paint copying, moving, comparing ##
Cary Clark8032b982017-07-28 11:04:54 -0400238
239#Method SkPaint& operator=(const SkPaint& paint)
240
Cary Clarkab2621d2018-01-30 10:08:57 -0500241#In Management
242#Line # makes a shallow copy ##
Cary Clark8032b982017-07-28 11:04:54 -0400243Makes a shallow copy of Paint. Typeface, Path_Effect, Shader,
Mike Reed8ad91a92018-01-19 19:09:32 -0500244Mask_Filter, Color_Filter, Draw_Looper, and Image_Filter are shared
Cary Clarkbad5ad72017-08-03 17:14:08 -0400245between the original paint and the copy. Objects containing Reference_Count in the
Cary Clark8032b982017-07-28 11:04:54 -0400246prior destination are decreased by one, and the referenced objects are deleted if the
Cary Clarkbad5ad72017-08-03 17:14:08 -0400247resulting count is zero. Objects containing Reference_Count in the parameter paint
248are increased by one. paint is unmodified.
Cary Clark8032b982017-07-28 11:04:54 -0400249
250#Param paint original to copy ##
251
252#Return content of paint ##
253
254#Example
255 SkPaint paint1, paint2;
256 paint1.setColor(SK_ColorRED);
257 paint2 = paint1;
258 SkDebugf("SK_ColorRED %c= paint1.getColor()\n", SK_ColorRED == paint1.getColor() ? '=' : '!');
259 SkDebugf("SK_ColorRED %c= paint2.getColor()\n", SK_ColorRED == paint2.getColor() ? '=' : '!');
260
261 #StdOut
262 SK_ColorRED == paint1.getColor()
263 SK_ColorRED == paint2.getColor()
264 ##
265##
266
267##
268
269# ------------------------------------------------------------------------------
270
271#Method SkPaint& operator=(SkPaint&& paint)
272
Cary Clarkab2621d2018-01-30 10:08:57 -0500273#In Management
274#Line # moves paint without copying it ##
Cary Clarkd0530ba2017-09-14 11:25:39 -0400275Moves the paint to avoid increasing the reference counts
Cary Clarkbad5ad72017-08-03 17:14:08 -0400276of objects referenced by the paint parameter. Objects containing Reference_Count in the
277prior destination are decreased by one; those objects are deleted if the resulting count
278is zero.
Cary Clark8032b982017-07-28 11:04:54 -0400279
280After the call, paint is undefined, and can be safely destructed.
281
282 #Param paint original to move ##
283
284 #Return content of paint ##
285
286#Example
287 SkPaint paint1, paint2;
288 paint1.setColor(SK_ColorRED);
289 paint2 = std::move(paint1);
290 SkDebugf("SK_ColorRED == paint2.getColor()\n", SK_ColorRED == paint2.getColor() ? '=' : '!');
291
292 #StdOut
293 SK_ColorRED == paint2.getColor()
294 ##
295##
296
297##
298
299# ------------------------------------------------------------------------------
300
301#Method bool operator==(const SkPaint& a, const SkPaint& b)
302
Cary Clarkab2621d2018-01-30 10:08:57 -0500303#In Management
304#Line # compares paints for equality ##
Cary Clark8032b982017-07-28 11:04:54 -0400305 Compares a and b, and returns true if a and b are equivalent. May return false
Mike Reed8ad91a92018-01-19 19:09:32 -0500306 if Typeface, Path_Effect, Shader, Mask_Filter, Color_Filter,
Cary Clark8032b982017-07-28 11:04:54 -0400307 Draw_Looper, or Image_Filter have identical contents but different pointers.
308
309 #Param a Paint to compare ##
310 #Param b Paint to compare ##
311
312 #Return true if Paint pair are equivalent ##
313
314 #Example
315 SkPaint paint1, paint2;
316 paint1.setColor(SK_ColorRED);
317 paint2.setColor(0xFFFF0000);
318 SkDebugf("paint1 %c= paint2\n", paint1 == paint2 ? '=' : '!');
319 float intervals[] = { 5, 5 };
320 paint1.setPathEffect(SkDashPathEffect::Make(intervals, 2, 2.5f));
321 paint2.setPathEffect(SkDashPathEffect::Make(intervals, 2, 2.5f));
322 SkDebugf("paint1 %c= paint2\n", paint1 == paint2 ? '=' : '!');
323
324 #StdOut
325 paint1 == paint2
326 paint1 != paint2
327 ##
328 ##
Cary Clark06c20f32018-03-20 15:53:27 -0400329#SeeAlso operator!=(const SkPaint& a, const SkPaint& b)
Cary Clark8032b982017-07-28 11:04:54 -0400330##
331
332# ------------------------------------------------------------------------------
333
334#Method bool operator!=(const SkPaint& a, const SkPaint& b)
335
Cary Clarkab2621d2018-01-30 10:08:57 -0500336#In Management
337#Line # compares paints for inequality ##
Cary Clark8032b982017-07-28 11:04:54 -0400338 Compares a and b, and returns true if a and b are not equivalent. May return true
Mike Reed8ad91a92018-01-19 19:09:32 -0500339 if Typeface, Path_Effect, Shader, Mask_Filter, Color_Filter,
Cary Clark8032b982017-07-28 11:04:54 -0400340 Draw_Looper, or Image_Filter have identical contents but different pointers.
341
342 #Param a Paint to compare ##
343 #Param b Paint to compare ##
344
345 #Return true if Paint pair are not equivalent ##
346
347#Example
348 SkPaint paint1, paint2;
349 paint1.setColor(SK_ColorRED);
350 paint2.setColor(0xFFFF0000);
351 SkDebugf("paint1 %c= paint2\n", paint1 == paint2 ? '=' : '!');
352 SkDebugf("paint1 %c= paint2\n", paint1 != paint2 ? '!' : '=');
353
354 #StdOut
355 paint1 == paint2
356 paint1 == paint2
357 ##
358##
Cary Clark06c20f32018-03-20 15:53:27 -0400359#SeeAlso operator==(const SkPaint& a, const SkPaint& b)
Cary Clark8032b982017-07-28 11:04:54 -0400360##
361
362# ------------------------------------------------------------------------------
363
364#Method uint32_t getHash() const
365
Cary Clarkab2621d2018-01-30 10:08:57 -0500366#In Management
367#Line # returns a shallow hash for equality checks ##
Cary Clark8032b982017-07-28 11:04:54 -0400368Returns a hash generated from Paint values and pointers.
369Identical hashes guarantee that the paints are
370equivalent, but differing hashes do not guarantee that the paints have differing
371contents.
372
373If operator==(const SkPaint& a, const SkPaint& b) returns true for two paints,
374their hashes are also equal.
375
376The hash returned is platform and implementation specific.
377
378#Return a shallow hash ##
379
380#Example
381 SkPaint paint1, paint2;
382 paint1.setColor(SK_ColorRED);
383 paint2.setColor(0xFFFF0000);
384 SkDebugf("paint1 %c= paint2\n", paint1 == paint2 ? '=' : '!');
385 SkDebugf("paint1.getHash() %c= paint2.getHash()\n",
386 paint1.getHash() == paint2.getHash() ? '=' : '!');
387
388 #StdOut
389 paint1 == paint2
390 paint1.getHash() == paint2.getHash()
391 ##
392##
393
394##
395
Cary Clark08895c42018-02-01 09:37:32 -0500396#Subtopic Management ##
Cary Clark8032b982017-07-28 11:04:54 -0400397
398# ------------------------------------------------------------------------------
Cary Clark08895c42018-02-01 09:37:32 -0500399#Subtopic Hinting
400#Line # glyph outline adjustment ##
Cary Clark8032b982017-07-28 11:04:54 -0400401
402#Enum Hinting
Cary Clark08895c42018-02-01 09:37:32 -0500403#Line # level of glyph outline adjustment ##
Cary Clark8032b982017-07-28 11:04:54 -0400404
405#Code
406 enum Hinting {
407 kNo_Hinting = 0,
408 kSlight_Hinting = 1,
409 kNormal_Hinting = 2,
Cary Clarkbad5ad72017-08-03 17:14:08 -0400410 kFull_Hinting = 3,
Cary Clark8032b982017-07-28 11:04:54 -0400411 };
412##
413
414Hinting adjusts the glyph outlines so that the shape provides a uniform
415look at a given point size on font engines that support it. Hinting may have a
416muted effect or no effect at all depending on the platform.
417
418The four levels roughly control corresponding features on platforms that use FreeType
419as the Font_Engine.
420
421#Const kNo_Hinting 0
422 Leaves glyph outlines unchanged from their native representation.
423 With FreeType, this is equivalent to the FT_LOAD_NO_HINTING
424 bit-field constant supplied to FT_Load_Glyph, which indicates that the vector
425 outline being loaded should not be fitted to the pixel grid but simply scaled
426 to 26.6 fractional pixels.
427##
428#Const kSlight_Hinting 1
429 Modifies glyph outlines minimally to improve constrast.
430 With FreeType, this is equivalent in spirit to the
431 FT_LOAD_TARGET_LIGHT value supplied to FT_Load_Glyph. It chooses a
432 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
436 Modifies glyph outlines to improve constrast. This is the default.
Cary Clark6fc50412017-09-21 12:31:06 -0400437 With FreeType, this supplies FT_LOAD_TARGET_NORMAL to FT_Load_Glyph,
Cary Clark8032b982017-07-28 11:04:54 -0400438 choosing the default hinting algorithm, which is optimized for standard
439 gray-level rendering.
440##
441#Const kFull_Hinting 3
Cary Clark6fc50412017-09-21 12:31:06 -0400442 Modifies glyph outlines for maxiumum constrast. With FreeType, this selects
443 FT_LOAD_TARGET_LCD or FT_LOAD_TARGET_LCD_V if kLCDRenderText_Flag is set.
444 FT_LOAD_TARGET_LCD is a variant of FT_LOAD_TARGET_NORMAL optimized for
445 horizontally decimated LCD displays; FT_LOAD_TARGET_LCD_V is a
Cary Clark8032b982017-07-28 11:04:54 -0400446 variant of FT_LOAD_TARGET_NORMAL optimized for vertically decimated LCD displays.
447##
448
449#Track
450#File SkFontHost_mac.cpp:1777,1806
451#Time 2013-03-03 07:16:29 +0000
Cary Clark4855f782018-02-06 09:41:53 -0500452#Bug 915
Cary Clark8032b982017-07-28 11:04:54 -0400453On OS_X and iOS, hinting controls whether Core_Graphics dilates the font outlines
454to account for LCD text. No hinting uses Core_Text gray scale output.
455Normal hinting uses Core_Text LCD output. If kLCDRenderText_Flag is clear,
456the LCD output is reduced to a single grayscale channel.
457#Track ##
458
459On Windows with DirectWrite, Hinting has no effect.
460
461Hinting defaults to kNormal_Hinting.
462Set SkPaintDefaults_Hinting at compile time to change the default setting.
463
464#ToDo add an illustration? linux running GM:typefacerendering is best for this
465 the hinting variations are every other character horizontally
466#ToDo ##
467
468#Enum ##
469
470#Method Hinting getHinting() const
471
Cary Clarkab2621d2018-01-30 10:08:57 -0500472#In Hinting
473#Line # returns Hinting, glyph outline adjustment level ##
Cary Clark8032b982017-07-28 11:04:54 -0400474 Returns level of glyph outline adjustment.
475
476 #Return one of: kNo_Hinting, kSlight_Hinting, kNormal_Hinting, kFull_Hinting ##
477
478 #Example
479 SkPaint paint;
480 SkDebugf("SkPaint::kNormal_Hinting %c= paint.getHinting()\n",
481 SkPaint::kNormal_Hinting == paint.getHinting() ? '=' : ':');
482
483 #StdOut
484 SkPaint::kNormal_Hinting == paint.getHinting()
485 ##
486 ##
487##
488
489#Method void setHinting(Hinting hintingLevel)
490
Cary Clarkab2621d2018-01-30 10:08:57 -0500491#In Hinting
492#Line # sets Hinting, glyph outline adjustment level ##
Cary Clark8032b982017-07-28 11:04:54 -0400493 Sets level of glyph outline adjustment.
494 Does not check for valid values of hintingLevel.
495
496 #Table
497 #Legend
498 # Hinting # value # effect on generated glyph outlines ##
499 ##
500 # kNo_Hinting # 0 # leaves glyph outlines unchanged from their native representation ##
Cary Clarkce101242017-09-01 15:51:02 -0400501 # kSlight_Hinting # 1 # modifies glyph outlines minimally to improve contrast ##
502 # kNormal_Hinting # 2 # modifies glyph outlines to improve contrast ##
503 # kFull_Hinting # 3 # modifies glyph outlines for maximum contrast ##
Cary Clark8032b982017-07-28 11:04:54 -0400504 ##
505
506 #Param hintingLevel one of: kNo_Hinting, kSlight_Hinting, kNormal_Hinting, kFull_Hinting ##
507
508 #Example
509 SkPaint paint1, paint2;
510 paint2.setHinting(SkPaint::kNormal_Hinting);
511 SkDebugf("paint1 %c= paint2\n", paint1 == paint2 ? '=' : ':');
512
513 #StdOut
514 paint1 == paint2
515 ##
516 ##
517##
518
Cary Clark08895c42018-02-01 09:37:32 -0500519#Subtopic Hinting ##
Cary Clark8032b982017-07-28 11:04:54 -0400520# ------------------------------------------------------------------------------
Cary Clark08895c42018-02-01 09:37:32 -0500521#Subtopic Flags
522#Line # attributes represented by single bits ##
Cary Clark8032b982017-07-28 11:04:54 -0400523
524#Enum Flags
Cary Clark08895c42018-02-01 09:37:32 -0500525#Line # values described by bits and masks ##
Cary Clark8032b982017-07-28 11:04:54 -0400526
527#Code
528 enum Flags {
529 kAntiAlias_Flag = 0x01,
530 kDither_Flag = 0x04,
531 kFakeBoldText_Flag = 0x20,
532 kLinearText_Flag = 0x40,
533 kSubpixelText_Flag = 0x80,
534 kDevKernText_Flag = 0x100,
535 kLCDRenderText_Flag = 0x200,
536 kEmbeddedBitmapText_Flag = 0x400,
537 kAutoHinting_Flag = 0x800,
538 kVerticalText_Flag = 0x1000,
539 kGenA8FromLCD_Flag = 0x2000,
540
541 kAllFlags = 0xFFFF,
542 };
543
544##
545
546The bit values stored in Flags.
547The default value for Flags, normally zero, can be changed at compile time
548with a custom definition of SkPaintDefaults_Flags.
549All flags can be read and written explicitly; Flags allows manipulating
550multiple settings at once.
551
552 #Const kAntiAlias_Flag 0x0001
553 mask for setting Anti-alias
554 ##
555 #Const kDither_Flag 0x0004
556 mask for setting Dither
557 ##
558
559 #Const kFakeBoldText_Flag 0x0020
560 mask for setting Fake_Bold
561 ##
562 #Const kLinearText_Flag 0x0040
563 mask for setting Linear_Text
564 ##
565 #Const kSubpixelText_Flag 0x0080
566 mask for setting Subpixel_Text
567 ##
568 #Const kDevKernText_Flag 0x0100
569 mask for setting Full_Hinting_Spacing
570 ##
571 #Const kLCDRenderText_Flag 0x0200
572 mask for setting LCD_Text
573 ##
574 #Const kEmbeddedBitmapText_Flag 0x0400
575 mask for setting Font_Embedded_Bitmaps
576 ##
577 #Const kAutoHinting_Flag 0x0800
578 mask for setting Automatic_Hinting
579 ##
580 #Const kVerticalText_Flag 0x1000
581 mask for setting Vertical_Text
582 ##
583 #Const kGenA8FromLCD_Flag 0x2000
584 #Private
585 Hack for GDI -- do not use if you can help it
586 ##
587 not intended for public use
588 ##
589 #Const kAllFlags 0xFFFF
590 mask of all Flags, including private flags and flags reserved for future use
591 ##
592
593Flags default to all flags clear, disabling the associated feature.
594
595#Enum ##
596
597#Enum ReserveFlags
Cary Clark4855f782018-02-06 09:41:53 -0500598#Deprecated soon
Cary Clark8032b982017-07-28 11:04:54 -0400599
Cary Clark4855f782018-02-06 09:41:53 -0500600Only valid for Android framework.
Cary Clark8032b982017-07-28 11:04:54 -0400601
602#Code
603 enum ReserveFlags {
604 kUnderlineText_ReserveFlag = 0x08,
605 kStrikeThruText_ReserveFlag = 0x10,
606 };
607##
608
Cary Clark4855f782018-02-06 09:41:53 -0500609#Const kUnderlineText_ReserveFlag 0x0008
610#Deprecated soon
611##
612#Const kStrikeThruText_ReserveFlag 0x0010
613#Deprecated soon
614##
615##
Cary Clark8032b982017-07-28 11:04:54 -0400616
617#Method uint32_t getFlags() const
618
Cary Clarkab2621d2018-01-30 10:08:57 -0500619#In Flags
620#Line # returns Flags stored in a bit field ##
Cary Clark8032b982017-07-28 11:04:54 -0400621Returns paint settings described by Flags. Each setting uses one
622bit, and can be tested with Flags members.
623
624#Return zero, one, or more bits described by Flags ##
625
626#Example
627 SkPaint paint;
628 paint.setAntiAlias(true);
629 SkDebugf("(SkPaint::kAntiAlias_Flag & paint.getFlags()) %c= 0\n",
630 SkPaint::kAntiAlias_Flag & paint.getFlags() ? '!' : '=');
631
632 #StdOut
633 (SkPaint::kAntiAlias_Flag & paint.getFlags()) != 0
634 ##
635##
636
637##
638
639#Method void setFlags(uint32_t flags)
640
Cary Clarkab2621d2018-01-30 10:08:57 -0500641#In Flags
642#Line # sets multiple Flags in a bit field ##
Cary Clark8032b982017-07-28 11:04:54 -0400643Replaces Flags with flags, the union of the Flags members.
644All Flags members may be cleared, or one or more may be set.
645
646#Param flags union of Flags for Paint ##
647
648#Example
649 SkPaint paint;
650 paint.setFlags((uint32_t) (SkPaint::kAntiAlias_Flag | SkPaint::kDither_Flag));
651 SkDebugf("paint.isAntiAlias()\n", paint.isAntiAlias() ? '!' : '=');
652 SkDebugf("paint.isDither()\n", paint.isDither() ? '!' : '=');
653
654 #StdOut
655 paint.isAntiAlias()
656 paint.isDither()
657 ##
658##
659
660##
661
Cary Clark08895c42018-02-01 09:37:32 -0500662#Subtopic Flags ##
Cary Clark8032b982017-07-28 11:04:54 -0400663# ------------------------------------------------------------------------------
Cary Clark08895c42018-02-01 09:37:32 -0500664#Subtopic Anti-alias
Cary Clark8032b982017-07-28 11:04:54 -0400665#Alias Anti-alias # permit hyphen in topic name, should probably not substitute hyphen with _
Cary Clark4855f782018-02-06 09:41:53 -0500666#In Related_Function
Cary Clarkab2621d2018-01-30 10:08:57 -0500667#Line # approximating coverage with transparency ##
Cary Clark8032b982017-07-28 11:04:54 -0400668
669Anti-alias drawing approximates partial pixel coverage with transparency.
670If kAntiAlias_Flag is clear, pixel centers contained by the shape edge are drawn opaque.
671If kAntiAlias_Flag is set, pixels are drawn with Color_Alpha equal to their coverage.
672
Cary Clarkce101242017-09-01 15:51:02 -0400673The rule for Aliased pixels is inconsistent across platforms. A shape edge
Cary Clark8032b982017-07-28 11:04:54 -0400674passing through the pixel center may, but is not required to, draw the pixel.
675
Cary Clarkce101242017-09-01 15:51:02 -0400676Raster_Engine draws Aliased pixels whose centers are on or to the right of the start of an
Cary Clark8032b982017-07-28 11:04:54 -0400677active Path edge, and whose center is to the left of the end of the active Path edge.
678
679#ToDo add illustration of raster pixels ##
680
Cary Clarkce101242017-09-01 15:51:02 -0400681A platform may only support Anti-aliased drawing. Some GPU-backed platforms use
682Supersampling to Anti-alias all drawing, and have no mechanism to selectively
683Alias.
Cary Clark8032b982017-07-28 11:04:54 -0400684
Cary Clarkce101242017-09-01 15:51:02 -0400685The amount of coverage computed for Anti-aliased pixels also varies across platforms.
Cary Clark8032b982017-07-28 11:04:54 -0400686
687Anti-alias is disabled by default.
688Anti-alias can be enabled by default by setting SkPaintDefaults_Flags to kAntiAlias_Flag
689at compile time.
690
Cary Clarkab2621d2018-01-30 10:08:57 -0500691#Example
Cary Clark8032b982017-07-28 11:04:54 -0400692 #Width 512
693 #Description
694 A red line is drawn with transparency on the edges to make it look smoother.
695 A blue line draws only where the pixel centers are contained.
Cary Clarkce101242017-09-01 15:51:02 -0400696 The lines are drawn into Bitmap, then drawn magnified to make the
697 Aliasing easier to see.
Cary Clark8032b982017-07-28 11:04:54 -0400698 ##
699
700 void draw(SkCanvas* canvas) {
701 SkBitmap bitmap;
702 bitmap.allocN32Pixels(50, 50);
703 SkCanvas offscreen(bitmap);
704 SkPaint paint;
705 paint.setStyle(SkPaint::kStroke_Style);
706 paint.setStrokeWidth(10);
707 for (bool antialias : { false, true }) {
708 paint.setColor(antialias ? SK_ColorRED : SK_ColorBLUE);
709 paint.setAntiAlias(antialias);
710 bitmap.eraseColor(0);
711 offscreen.drawLine(5, 5, 15, 30, paint);
712 canvas->drawLine(5, 5, 15, 30, paint);
713 canvas->save();
714 canvas->scale(10, 10);
715 canvas->drawBitmap(bitmap, antialias ? 12 : 0, 0);
716 canvas->restore();
717 canvas->translate(15, 0);
718 }
719 }
Cary Clarkab2621d2018-01-30 10:08:57 -0500720##
Cary Clark8032b982017-07-28 11:04:54 -0400721
722#Method bool isAntiAlias() const
Cary Clark78de7512018-02-07 07:27:09 -0500723#In Anti_alias
Cary Clarkab2621d2018-01-30 10:08:57 -0500724#Line # returns true if Anti-alias is set ##
Cary Clark8032b982017-07-28 11:04:54 -0400725
726 If true, pixels on the active edges of Path may be drawn with partial transparency.
727
728 Equivalent to getFlags masked with kAntiAlias_Flag.
729
730 #Return kAntiAlias_Flag state ##
731
732 #Example
733 SkPaint paint;
734 SkDebugf("paint.isAntiAlias() %c= !!(paint.getFlags() & SkPaint::kAntiAlias_Flag)\n",
735 paint.isAntiAlias() == !!(paint.getFlags() & SkPaint::kAntiAlias_Flag) ? '=' : '!');
736 paint.setAntiAlias(true);
737 SkDebugf("paint.isAntiAlias() %c= !!(paint.getFlags() & SkPaint::kAntiAlias_Flag)\n",
738 paint.isAntiAlias() == !!(paint.getFlags() & SkPaint::kAntiAlias_Flag) ? '=' : '!');
739
740 #StdOut
741 paint.isAntiAlias() == !!(paint.getFlags() & SkPaint::kAntiAlias_Flag)
742 paint.isAntiAlias() == !!(paint.getFlags() & SkPaint::kAntiAlias_Flag)
743 ##
744 ##
745##
746
747#Method void setAntiAlias(bool aa)
748
Cary Clark78de7512018-02-07 07:27:09 -0500749#In Anti_alias
Cary Clarkab2621d2018-01-30 10:08:57 -0500750#Line # sets or clears Anti-alias ##
Cary Clark8032b982017-07-28 11:04:54 -0400751 Requests, but does not require, that Path edge pixels draw opaque or with
752 partial transparency.
753
754 Sets kAntiAlias_Flag if aa is true.
755 Clears kAntiAlias_Flag if aa is false.
756
757 #Param aa setting for kAntiAlias_Flag ##
758
759 #Example
760 SkPaint paint1, paint2;
761 paint1.setAntiAlias(true);
762 paint2.setFlags(paint2.getFlags() | SkPaint::kAntiAlias_Flag);
763 SkDebugf("paint1 %c= paint2\n", paint1 == paint2 ? '=' : '!');
764
765 #StdOut
766 paint1 == paint2
767 ##
768 ##
769
770##
771
Cary Clarkf895a422018-02-27 09:54:21 -0500772#Subtopic Anti-alias ##
Cary Clark8032b982017-07-28 11:04:54 -0400773# ------------------------------------------------------------------------------
Cary Clark08895c42018-02-01 09:37:32 -0500774#Subtopic Dither
775#Line # distributing color error ##
Cary Clark8032b982017-07-28 11:04:54 -0400776
Cary Clarkce101242017-09-01 15:51:02 -0400777Dither increases fidelity by adjusting the color of adjacent pixels.
Cary Clark8032b982017-07-28 11:04:54 -0400778This can help to smooth color transitions and reducing banding in gradients.
779Dithering lessens visible banding from kRGB_565_SkColorType
780and kRGBA_8888_SkColorType gradients,
781and improves rendering into a kRGB_565_SkColorType Surface.
782
783Dithering is always enabled for linear gradients drawing into
784kRGB_565_SkColorType Surface and kRGBA_8888_SkColorType Surface.
785Dither cannot be enabled for kAlpha_8_SkColorType Surface and
786kRGBA_F16_SkColorType Surface.
787
788Dither is disabled by default.
789Dither can be enabled by default by setting SkPaintDefaults_Flags to kDither_Flag
790at compile time.
791
792Some platform implementations may ignore dithering. Set
793
794#Define SK_IGNORE_GPU_DITHER
795
796to ignore Dither on GPU_Surface.
797
798#Example
799#Description
800Dithering in the bottom half more closely approximates the requested color by
801alternating nearby colors from pixel to pixel.
802##
803void draw(SkCanvas* canvas) {
804 SkBitmap bm16;
805 bm16.allocPixels(SkImageInfo::Make(32, 32, kRGB_565_SkColorType, kOpaque_SkAlphaType));
806 SkCanvas c16(bm16);
807 SkPaint colorPaint;
808 for (auto dither : { false, true } ) {
809 colorPaint.setDither(dither);
810 for (auto colors : { 0xFF333333, 0xFF666666, 0xFF999999, 0xFFCCCCCC } ) {
811 for (auto mask : { 0xFFFF0000, 0xFF00FF00, 0xFF0000FF, 0xFFFFFFFF } ) {
812 colorPaint.setColor(colors & mask);
813 c16.drawRect({0, 0, 8, 4}, colorPaint);
814 c16.translate(8, 0);
815 }
816 c16.translate(-32, 4);
817 }
818 }
819 canvas->scale(8, 8);
820 canvas->drawBitmap(bm16, 0, 0);
821}
822##
823
824#Example
825#Description
826Dithering introduces subtle adjustments to color to smooth gradients.
827Drawing the gradient repeatedly with SkBlendMode::kPlus exaggerates the
828dither, making it easier to see.
829##
830void draw(SkCanvas* canvas) {
831 canvas->clear(0);
832 SkBitmap bm32;
833 bm32.allocPixels(SkImageInfo::Make(20, 10, kN32_SkColorType, kPremul_SkAlphaType));
834 SkCanvas c32(bm32);
835 SkPoint points[] = {{0, 0}, {20, 0}};
836 SkColor colors[] = {0xFF334455, 0xFF662211 };
837 SkPaint paint;
838 paint.setShader(SkGradientShader::MakeLinear(
839 points, colors, nullptr, SK_ARRAY_COUNT(colors),
840 SkShader::kClamp_TileMode, 0, nullptr));
841 paint.setDither(true);
842 c32.drawPaint(paint);
843 canvas->scale(12, 12);
844 canvas->drawBitmap(bm32, 0, 0);
845 paint.setBlendMode(SkBlendMode::kPlus);
846 canvas->drawBitmap(bm32, 0, 11, &paint);
847 canvas->drawBitmap(bm32, 0, 11, &paint);
848 canvas->drawBitmap(bm32, 0, 11, &paint);
849}
850##
851
852#Method bool isDither() const
853
Cary Clarkab2621d2018-01-30 10:08:57 -0500854#In Dither
855#Line # returns true if Dither is set ##
Cary Clark8032b982017-07-28 11:04:54 -0400856 If true, color error may be distributed to smooth color transition.
857
858 Equivalent to getFlags masked with kDither_Flag.
859
860 #Return kDither_Flag state ##
861
862 #Example
863 SkPaint paint;
864 SkDebugf("paint.isDither() %c= !!(paint.getFlags() & SkPaint::kDither_Flag)\n",
865 paint.isDither() == !!(paint.getFlags() & SkPaint::kDither_Flag) ? '=' : '!');
866 paint.setDither(true);
867 SkDebugf("paint.isDither() %c= !!(paint.getFlags() & SkPaint::kDither_Flag)\n",
868 paint.isDither() == !!(paint.getFlags() & SkPaint::kDither_Flag) ? '=' : '!');
869
870 #StdOut
871 paint.isDither() == !!(paint.getFlags() & SkPaint::kDither_Flag)
872 paint.isDither() == !!(paint.getFlags() & SkPaint::kDither_Flag)
873 ##
874 ##
875
876##
877
878#Method void setDither(bool dither)
879
Cary Clarkab2621d2018-01-30 10:08:57 -0500880#In Dither
881#Line # sets or clears Dither ##
Cary Clark8032b982017-07-28 11:04:54 -0400882 Requests, but does not require, to distribute color error.
883
884 Sets kDither_Flag if dither is true.
885 Clears kDither_Flag if dither is false.
886
887 #Param dither setting for kDither_Flag ##
888
889 #Example
890 SkPaint paint1, paint2;
891 paint1.setDither(true);
892 paint2.setFlags(paint2.getFlags() | SkPaint::kDither_Flag);
893 SkDebugf("paint1 %c= paint2\n", paint1 == paint2 ? '=' : '!');
894
895 #StdOut
896 paint1 == paint2
897 ##
898 ##
899
900 #SeeAlso kRGB_565_SkColorType
901
902##
903
904#SeeAlso Gradient Color_RGB-565
905
Cary Clark08895c42018-02-01 09:37:32 -0500906#Subtopic Dither ##
Cary Clark8032b982017-07-28 11:04:54 -0400907# ------------------------------------------------------------------------------
Cary Clark08895c42018-02-01 09:37:32 -0500908#Subtopic Device_Text
909#Line # increase precision of glyph position ##
Cary Clark8032b982017-07-28 11:04:54 -0400910
911LCD_Text and Subpixel_Text increase the precision of glyph position.
912
913When set, Flags kLCDRenderText_Flag takes advantage of the organization of Color_RGB stripes that
914create a color, and relies
Cary Clarkce101242017-09-01 15:51:02 -0400915on the small size of the stripe and visual perception to make the color fringing imperceptible.
Cary Clark8032b982017-07-28 11:04:54 -0400916LCD_Text can be enabled on devices that orient stripes horizontally or vertically, and that order
917the color components as Color_RGB or Color_RBG.
918
919Flags kSubpixelText_Flag uses the pixel transparency to represent a fractional offset.
920As the opaqueness
921of the color increases, the edge of the glyph appears to move towards the outside of the pixel.
922
923Either or both techniques can be enabled.
924kLCDRenderText_Flag and kSubpixelText_Flag are clear by default.
925LCD_Text or Subpixel_Text can be enabled by default by setting SkPaintDefaults_Flags to
926kLCDRenderText_Flag or kSubpixelText_Flag (or both) at compile time.
927
928#Example
929 #Description
930 Four commas are drawn normally and with combinations of LCD_Text and Subpixel_Text.
Cary Clarkce101242017-09-01 15:51:02 -0400931 When Subpixel_Text is disabled, the comma Glyphs are identical, but not evenly spaced.
932 When Subpixel_Text is enabled, the comma Glyphs are unique, but appear evenly spaced.
Cary Clark8032b982017-07-28 11:04:54 -0400933 ##
934
935 SkBitmap bitmap;
936 bitmap.allocN32Pixels(24, 33);
937 SkCanvas offscreen(bitmap);
938 offscreen.clear(SK_ColorWHITE);
939 SkPaint paint;
940 paint.setAntiAlias(true);
941 paint.setTextSize(20);
942 for (bool lcd : { false, true }) {
943 paint.setLCDRenderText(lcd);
944 for (bool subpixel : { false, true }) {
945 paint.setSubpixelText(subpixel);
946 offscreen.drawString(",,,,", 0, 4, paint);
947 offscreen.translate(0, 7);
948 }
949 }
950 canvas->drawBitmap(bitmap, 4, 12);
951 canvas->scale(9, 9);
952 canvas->drawBitmap(bitmap, 4, -1);
953##
Cary Clark08895c42018-02-01 09:37:32 -0500954#Subtopic Device_Text ##
Cary Clark8032b982017-07-28 11:04:54 -0400955
956#Subtopic Linear_Text
Cary Clark08895c42018-02-01 09:37:32 -0500957#Alias Linear_Text
958#Line # selects text rendering as Glyph or Path ##
Cary Clark8032b982017-07-28 11:04:54 -0400959
960Linear_Text selects whether text is rendered as a Glyph or as a Path.
961If kLinearText_Flag is set, it has the same effect as setting Hinting to kNormal_Hinting.
Cary Clarkd0530ba2017-09-14 11:25:39 -0400962If kLinearText_Flag is clear, it is the same as setting Hinting to kNo_Hinting.
Cary Clark8032b982017-07-28 11:04:54 -0400963
964#Method bool isLinearText() const
965
Cary Clark08895c42018-02-01 09:37:32 -0500966#Line # returns true if text is converted to Path ##
Cary Clarkab2621d2018-01-30 10:08:57 -0500967#In Linear_Text
Cary Clark8032b982017-07-28 11:04:54 -0400968 If true, text is converted to Path before drawing and measuring.
969
970 Equivalent to getFlags masked with kLinearText_Flag.
971
972 #Return kLinearText_Flag state ##
973
974 #Example
975 #Height 128
976 void draw(SkCanvas* canvas) {
977 SkPaint paint;
978 paint.setAntiAlias(true);
979 const char testStr[] = "xxxx xxxx";
980 for (auto linearText : { false, true } ) {
981 paint.setLinearText(linearText);
982 paint.setTextSize(24);
983 canvas->drawString(paint.isLinearText() ? "linear" : "hinted", 128, 30, paint);
984 for (SkScalar textSize = 8; textSize < 30; textSize *= 1.22f) {
985 paint.setTextSize(textSize);
986 canvas->translate(0, textSize);
987 canvas->drawString(testStr, 10, 0, paint);
988 }
989 }
990 }
991 ##
992
993 #SeeAlso setLinearText Hinting
994##
995
996#Method void setLinearText(bool linearText)
997
Cary Clark08895c42018-02-01 09:37:32 -0500998#Line # converts to Path before draw or measure ##
Cary Clarkab2621d2018-01-30 10:08:57 -0500999#In Linear_Text
Cary Clark8032b982017-07-28 11:04:54 -04001000 If true, text is converted to Path before drawing and measuring.
1001 By default, kLinearText_Flag is clear.
1002
1003 Sets kLinearText_Flag if linearText is true.
1004 Clears kLinearText_Flag if linearText is false.
1005
1006 #Param linearText setting for kLinearText_Flag ##
1007
1008 #Example
1009 #Height 128
1010 void draw(SkCanvas* canvas) {
1011 SkPaint paint;
1012 paint.setAntiAlias(true);
1013 const char testStr[] = "abcd efgh";
1014 for (int textSize : { 12, 24 } ) {
1015 paint.setTextSize(textSize);
1016 for (auto linearText : { false, true } ) {
1017 paint.setLinearText(linearText);
1018 SkString width;
1019 width.appendScalar(paint.measureText(testStr, SK_ARRAY_COUNT(testStr), nullptr));
1020 canvas->translate(0, textSize + 4);
1021 canvas->drawString(testStr, 10, 0, paint);
1022 canvas->drawString(width, 128, 0, paint);
1023 }
1024 }
1025 }
1026 ##
1027
1028 #SeeAlso isLinearText Hinting
1029##
1030
Cary Clark08895c42018-02-01 09:37:32 -05001031#Subtopic Linear_Text ##
Cary Clark8032b982017-07-28 11:04:54 -04001032
1033#Subtopic Subpixel_Text
Cary Clark08895c42018-02-01 09:37:32 -05001034#Alias Subpixel_Text
1035#Line # uses pixel transparency to represent fractional offset ##
Cary Clark8032b982017-07-28 11:04:54 -04001036
1037Flags kSubpixelText_Flag uses the pixel transparency to represent a fractional offset.
1038As the opaqueness
1039of the color increases, the edge of the glyph appears to move towards the outside of the pixel.
1040
1041#Method bool isSubpixelText() const
1042
Cary Clarkab2621d2018-01-30 10:08:57 -05001043#In Subpixel_Text
1044#Line # returns true if Subpixel_Text is set ##
Cary Clarkce101242017-09-01 15:51:02 -04001045 If true, Glyphs at different sub-pixel positions may differ on pixel edge coverage.
Cary Clark8032b982017-07-28 11:04:54 -04001046
1047 Equivalent to getFlags masked with kSubpixelText_Flag.
1048
1049 #Return kSubpixelText_Flag state ##
1050
1051 #Example
1052SkPaint paint;
1053SkDebugf("paint.isSubpixelText() %c= !!(paint.getFlags() & SkPaint::kSubpixelText_Flag)\n",
1054 paint.isSubpixelText() == !!(paint.getFlags() & SkPaint::kSubpixelText_Flag) ? '=' : '!');
1055paint.setSubpixelText(true);
1056SkDebugf("paint.isSubpixelText() %c= !!(paint.getFlags() & SkPaint::kSubpixelText_Flag)\n",
1057 paint.isSubpixelText() == !!(paint.getFlags() & SkPaint::kSubpixelText_Flag) ? '=' : '!');
1058
1059 #StdOut
1060 paint.isSubpixelText() == !!(paint.getFlags() & SkPaint::kSubpixelText_Flag)
1061 paint.isSubpixelText() == !!(paint.getFlags() & SkPaint::kSubpixelText_Flag)
1062 ##
1063 ##
1064
1065##
1066
1067#Method void setSubpixelText(bool subpixelText)
1068
Cary Clarkab2621d2018-01-30 10:08:57 -05001069#In Subpixel_Text
1070#Line # sets or clears Subpixel_Text ##
Cary Clarkce101242017-09-01 15:51:02 -04001071 Requests, but does not require, that Glyphs respect sub-pixel positioning.
Cary Clark8032b982017-07-28 11:04:54 -04001072
1073 Sets kSubpixelText_Flag if subpixelText is true.
1074 Clears kSubpixelText_Flag if subpixelText is false.
1075
1076 #Param subpixelText setting for kSubpixelText_Flag ##
1077
1078 #Example
1079 SkPaint paint1, paint2;
1080 paint1.setSubpixelText(true);
1081 paint2.setFlags(paint2.getFlags() | SkPaint::kSubpixelText_Flag);
1082 SkDebugf("paint1 %c= paint2\n", paint1 == paint2 ? '=' : '!');
1083
1084 #StdOut
1085 paint1 == paint2
1086 ##
1087 ##
1088
1089##
1090
Cary Clark08895c42018-02-01 09:37:32 -05001091#Subtopic Subpixel_Text ##
Cary Clark8032b982017-07-28 11:04:54 -04001092
1093#Subtopic LCD_Text
Cary Clarkc68ba1d2018-02-20 10:35:29 -05001094#Substitute LCD text
Cary Clark08895c42018-02-01 09:37:32 -05001095#Line # text relying on the order of Color_RGB stripes ##
Cary Clark8032b982017-07-28 11:04:54 -04001096#Alias LCD_Text # makes this a top level name, since it is under subtopic Device_Text
1097
1098When set, Flags kLCDRenderText_Flag takes advantage of the organization of Color_RGB stripes that
1099create 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
1102the color components as Color_RGB or Color_RBG.
1103
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 Clarkce101242017-09-01 15:51:02 -04001108 If true, 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 Clark8032b982017-07-28 11:04:54 -04001160#Alias Font_Embedded_Bitmaps # long-winded enough, alias so I don't type Paint_Font_...
1161
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
1164in a font if the platform supports this option.
1165
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 Clarkce101242017-09-01 15:51:02 -04001208 If true, 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 Clark8032b982017-07-28 11:04:54 -04001275 If true, and if Hinting is set to kNormal_Hinting or kFull_Hinting, and if
1276 platform uses FreeType as the Font_Manager, instruct the Font_Manager to always hint
Cary Clarkce101242017-09-01 15:51:02 -04001277 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 Clark8032b982017-07-28 11:04:54 -04001306 If Hinting is set to kNormal_Hinting or kFull_Hinting and useAutohinter is set,
Cary Clarkce101242017-09-01 15:51:02 -04001307 instruct the Font_Manager to always hint Glyphs.
Cary Clark8032b982017-07-28 11:04:54 -04001308 Automatic_Hinting has no effect if Hinting is set to kNo_Hinting or
1309 kSlight_Hinting.
1310
Cary Clark579985c2017-07-31 11:48:27 -04001311 Only affects platforms that use FreeType as the Font_Manager.
Cary Clark8032b982017-07-28 11:04:54 -04001312
1313 Sets kAutoHinting_Flag if useAutohinter is true.
1314 Clears kAutoHinting_Flag if useAutohinter is false.
1315
1316 #Param useAutohinter setting for kAutoHinting_Flag ##
1317
1318 #Example
1319 void draw(SkCanvas* canvas) {
1320 SkPaint paint;
1321 paint.setAntiAlias(true);
1322 const char testStr[] = "xxxx xxxx";
1323 for (auto forceAutoHinting : { false, true} ) {
1324 paint.setAutohinted(forceAutoHinting);
1325 paint.setTextSize(24);
1326 canvas->drawString(paint.isAutohinted() ? "auto-hinted" : "default", 108, 30, paint);
1327 for (SkScalar textSize = 8; textSize < 30; textSize *= 1.22f) {
1328 paint.setTextSize(textSize);
1329 canvas->translate(0, textSize);
1330 canvas->drawString(testStr, 10, 0, paint);
1331 }
1332 }
1333 }
1334 ##
1335
1336 #SeeAlso isAutohinted Hinting
1337
1338##
1339
Cary Clark08895c42018-02-01 09:37:32 -05001340#Subtopic Automatic_Hinting ##
Cary Clark8032b982017-07-28 11:04:54 -04001341# ------------------------------------------------------------------------------
Cary Clark08895c42018-02-01 09:37:32 -05001342#Subtopic Vertical_Text
1343#Line # orient text from top to bottom ##
Cary Clark8032b982017-07-28 11:04:54 -04001344
1345Text may be drawn by positioning each glyph, or by positioning the first glyph and
Cary Clarkce101242017-09-01 15:51:02 -04001346using Font_Advance to position subsequent Glyphs. By default, each successive glyph
1347is positioned to the right of the preceding glyph. Vertical_Text sets successive
1348Glyphs to position below the preceding glyph.
Cary Clark8032b982017-07-28 11:04:54 -04001349
Cary Clarkce101242017-09-01 15:51:02 -04001350Skia can translate text character codes as a series of Glyphs, but does not implement
Cary Clark8032b982017-07-28 11:04:54 -04001351font substitution,
Cary Clarkce101242017-09-01 15:51:02 -04001352textual substitution, line layout, or contextual spacing like Kerning pairs. Use
Cary Clark6fc50412017-09-21 12:31:06 -04001353a text shaping engine like
1354#A HarfBuzz # http://harfbuzz.org/ ##
1355 to translate text runs
Cary Clark8032b982017-07-28 11:04:54 -04001356into glyph series.
1357
1358Vertical_Text is clear if text is drawn left to right or set if drawn from top to bottom.
1359
1360Flags kVerticalText_Flag if clear draws text left to right.
1361Flags kVerticalText_Flag if set draws text top to bottom.
1362
1363Vertical_Text is clear by default.
1364Vertical_Text can be set by default by setting SkPaintDefaults_Flags to
1365kVerticalText_Flag at compile time.
1366
1367#Example
1368
1369void draw(SkCanvas* canvas) {
1370 SkPaint paint;
1371 paint.setAntiAlias(true);
1372 paint.setTextSize(50);
1373 for (bool vertical : { false, true } ) {
1374 paint.setVerticalText(vertical);
1375 canvas->drawString("aAlL", 25, 50, paint);
1376 }
1377}
1378
1379##
1380
1381#Method bool isVerticalText() const
1382
Cary Clarkab2621d2018-01-30 10:08:57 -05001383#In Vertical_Text
1384#Line # returns true if Vertical_Text is set ##
Cary Clarkce101242017-09-01 15:51:02 -04001385 If true, Glyphs are drawn top to bottom instead of left to right.
Cary Clark8032b982017-07-28 11:04:54 -04001386
1387 Equivalent to getFlags masked with kVerticalText_Flag.
1388
1389 #Return kVerticalText_Flag state ##
1390
1391 #Example
1392 SkPaint paint;
1393 SkDebugf("paint.isVerticalText() %c= !!(paint.getFlags() & SkPaint::kVerticalText_Flag)\n",
1394 paint.isVerticalText() == !!(paint.getFlags() & SkPaint::kVerticalText_Flag) ? '=' : '!');
1395 paint.setVerticalText(true);
1396 SkDebugf("paint.isVerticalText() %c= !!(paint.getFlags() & SkPaint::kVerticalText_Flag)\n",
1397 paint.isVerticalText() == !!(paint.getFlags() & SkPaint::kVerticalText_Flag) ? '=' : '!');
1398
1399 #StdOut
1400 paint.isVerticalText() == !!(paint.getFlags() & SkPaint::kVerticalText_Flag)
1401 paint.isVerticalText() == !!(paint.getFlags() & SkPaint::kVerticalText_Flag)
1402 ##
1403 ##
1404
1405##
1406
1407#Method void setVerticalText(bool verticalText)
1408
Cary Clarkab2621d2018-01-30 10:08:57 -05001409#In Vertical_Text
1410#Line # sets or clears Vertical_Text ##
Cary Clark8032b982017-07-28 11:04:54 -04001411 If true, text advance positions the next glyph below the previous glyph instead of to the
1412 right of previous glyph.
1413
1414 Sets kVerticalText_Flag if vertical is true.
1415 Clears kVerticalText_Flag if vertical is false.
1416
1417 #Param verticalText setting for kVerticalText_Flag ##
1418
1419 #Example
1420 SkPaint paint1, paint2;
1421 paint1.setVerticalText(true);
1422 paint2.setFlags(paint2.getFlags() | SkPaint::kVerticalText_Flag);
1423 SkDebugf("paint1 %c= paint2\n", paint1 == paint2 ? '=' : '!');
1424
1425 #StdOut
1426 paint1 == paint2
1427 ##
1428 ##
1429
1430##
1431
Cary Clark08895c42018-02-01 09:37:32 -05001432#Subtopic Vertical_Text ##
Cary Clark8032b982017-07-28 11:04:54 -04001433# ------------------------------------------------------------------------------
1434
Cary Clark08895c42018-02-01 09:37:32 -05001435#Subtopic Fake_Bold
1436#Line # approximate font styles ##
Cary Clark8032b982017-07-28 11:04:54 -04001437
1438Fake_Bold approximates the bold font style accompanying a normal font when a bold font face
1439is not available. Skia does not provide font substitution; it is up to the client to find the
Cary Clarkbc5697d2017-10-04 14:31:33 -04001440bold font face using the platform Font_Manager.
Cary Clark8032b982017-07-28 11:04:54 -04001441
1442Use Text_Skew_X to approximate an italic font style when the italic font face
1443is not available.
1444
Cary Clarkce101242017-09-01 15:51:02 -04001445A FreeType based port may define SK_USE_FREETYPE_EMBOLDEN at compile time to direct
1446the font engine to create the bold Glyphs. Otherwise, the extra bold is computed
Cary Clark8032b982017-07-28 11:04:54 -04001447by increasing the stroke width and setting the Style to kStrokeAndFill_Style as needed.
1448
1449Fake_Bold is disabled by default.
1450
1451#Example
1452#Height 128
1453void draw(SkCanvas* canvas) {
1454 SkPaint paint;
1455 paint.setAntiAlias(true);
1456 paint.setTextSize(40);
1457 canvas->drawString("OjYy_-", 10, 35, paint);
1458 paint.setFakeBoldText(true);
1459 canvas->drawString("OjYy_-", 10, 75, paint);
1460 // create a custom fake bold by varying the stroke width
1461 paint.setFakeBoldText(false);
1462 paint.setStyle(SkPaint::kStrokeAndFill_Style);
1463 paint.setStrokeWidth(40.f / 48);
1464 canvas->drawString("OjYy_-", 10, 115, paint);
1465}
1466##
1467
1468#Method bool isFakeBoldText() const
1469
Cary Clarkab2621d2018-01-30 10:08:57 -05001470#In Fake_Bold
1471#Line # returns true if Fake_Bold is set ##
Cary Clark8032b982017-07-28 11:04:54 -04001472 If true, approximate bold by increasing the stroke width when creating glyph bitmaps
1473 from outlines.
1474
1475 Equivalent to getFlags masked with kFakeBoldText_Flag.
1476
1477 #Return kFakeBoldText_Flag state ##
1478
1479 #Example
1480 SkPaint paint;
1481 SkDebugf("paint.isFakeBoldText() %c= !!(paint.getFlags() & SkPaint::kFakeBoldText_Flag)\n",
1482 paint.isFakeBoldText() == !!(paint.getFlags() & SkPaint::kFakeBoldText_Flag) ? '=' : '!');
1483 paint.setFakeBoldText(true);
1484 SkDebugf("paint.isFakeBoldText() %c= !!(paint.getFlags() & SkPaint::kFakeBoldText_Flag)\n",
1485 paint.isFakeBoldText() == !!(paint.getFlags() & SkPaint::kFakeBoldText_Flag) ? '=' : '!');
1486
1487 #StdOut
1488 paint.isFakeBoldText() == !!(paint.getFlags() & SkPaint::kFakeBoldText_Flag)
1489 paint.isFakeBoldText() == !!(paint.getFlags() & SkPaint::kFakeBoldText_Flag)
1490 ##
1491 ##
1492
1493##
1494
1495#Method void setFakeBoldText(bool fakeBoldText)
1496
Cary Clarkab2621d2018-01-30 10:08:57 -05001497#In Fake_Bold
1498#Line # sets or clears Fake_Bold ##
Cary Clarkce101242017-09-01 15:51:02 -04001499 Use increased stroke width when creating glyph bitmaps to approximate a bold typeface.
Cary Clark8032b982017-07-28 11:04:54 -04001500
1501 Sets kFakeBoldText_Flag if fakeBoldText is true.
1502 Clears kFakeBoldText_Flag if fakeBoldText is false.
1503
1504 #Param fakeBoldText setting for kFakeBoldText_Flag ##
1505
1506 #Example
1507 SkPaint paint1, paint2;
1508 paint1.setFakeBoldText(true);
1509 paint2.setFlags(paint2.getFlags() | SkPaint::kFakeBoldText_Flag);
1510 SkDebugf("paint1 %c= paint2\n", paint1 == paint2 ? '=' : '!');
1511
1512 #StdOut
1513 paint1 == paint2
1514 ##
1515 ##
1516
1517##
1518
Cary Clark08895c42018-02-01 09:37:32 -05001519#Subtopic Fake_Bold ##
Cary Clark8032b982017-07-28 11:04:54 -04001520
1521# ------------------------------------------------------------------------------
Cary Clark08895c42018-02-01 09:37:32 -05001522#Subtopic Full_Hinting_Spacing
1523#Line # glyph spacing affected by hinting ##
Cary Clark8032b982017-07-28 11:04:54 -04001524#Alias Full_Hinting_Spacing # long winded enough -- maybe things with two underscores auto-aliased?
1525
Cary Clarkce101242017-09-01 15:51:02 -04001526if Hinting is set to kFull_Hinting, Full_Hinting_Spacing adjusts the character
1527spacing by the difference of the hinted and Unhinted Left_Side_Bearing and
1528Right_Side_Bearing. Full_Hinting_Spacing only applies to platforms that use
1529FreeType as their Font_Engine.
Cary Clark8032b982017-07-28 11:04:54 -04001530
Cary Clarkce101242017-09-01 15:51:02 -04001531Full_Hinting_Spacing is not related to text Kerning, where the space between
Cary Clarkbc5697d2017-10-04 14:31:33 -04001532a specific pair of characters is adjusted using data in the font Kerning tables.
Cary Clark8032b982017-07-28 11:04:54 -04001533
1534#Method bool isDevKernText() const
1535
Cary Clarkab2621d2018-01-30 10:08:57 -05001536#In Full_Hinting_Spacing
1537#Line # returns true if Full_Hinting_Spacing is set ##
Cary Clark8032b982017-07-28 11:04:54 -04001538 Returns if character spacing may be adjusted by the hinting difference.
1539
1540 Equivalent to getFlags masked with kDevKernText_Flag.
1541
1542 #Return kDevKernText_Flag state ##
1543
1544 #Example
1545 SkPaint paint;
1546 SkDebugf("paint.isDevKernText() %c= !!(paint.getFlags() & SkPaint::kDevKernText_Flag)\n",
1547 paint.isDevKernText() == !!(paint.getFlags() & SkPaint::kDevKernText_Flag) ? '=' : '!');
1548 paint.setDevKernText(true);
1549 SkDebugf("paint.isDevKernText() %c= !!(paint.getFlags() & SkPaint::kDevKernText_Flag)\n",
1550 paint.isDevKernText() == !!(paint.getFlags() & SkPaint::kDevKernText_Flag) ? '=' : '!');
1551 ##
1552
1553##
1554
1555#Method void setDevKernText(bool devKernText)
1556
Cary Clarkab2621d2018-01-30 10:08:57 -05001557#In Full_Hinting_Spacing
1558#Line # sets or clears Full_Hinting_Spacing ##
Cary Clark8032b982017-07-28 11:04:54 -04001559 Requests, but does not require, to use hinting to adjust glyph spacing.
1560
1561 Sets kDevKernText_Flag if devKernText is true.
1562 Clears kDevKernText_Flag if devKernText is false.
1563
1564 #Param devKernText setting for devKernText ##
1565
1566 #Example
1567 SkPaint paint1, paint2;
1568 paint1.setDevKernText(true);
1569 paint2.setFlags(paint2.getFlags() | SkPaint::kDevKernText_Flag);
1570 SkDebugf("paint1 %c= paint2\n", paint1 == paint2 ? '=' : '!');
1571
1572 #StdOut
1573 paint1 == paint2
1574 ##
1575 ##
1576
1577##
1578
Cary Clark08895c42018-02-01 09:37:32 -05001579#Subtopic Full_Hinting_Spacing ##
Cary Clark8032b982017-07-28 11:04:54 -04001580# ------------------------------------------------------------------------------
Cary Clark08895c42018-02-01 09:37:32 -05001581#Subtopic Filter_Quality_Methods
1582#Line # get and set Filter_Quality ##
Cary Clark8032b982017-07-28 11:04:54 -04001583
1584Filter_Quality trades speed for image filtering when the image is scaled.
1585A lower Filter_Quality draws faster, but has less fidelity.
1586A higher Filter_Quality draws slower, but looks better.
Cary Clarkce101242017-09-01 15:51:02 -04001587If the image is drawn without scaling, the Filter_Quality choice will not result
1588in a noticeable difference.
Cary Clark8032b982017-07-28 11:04:54 -04001589
1590Filter_Quality is used in Paint passed as a parameter to
1591#List
1592# SkCanvas::drawBitmap ##
1593# SkCanvas::drawBitmapRect ##
1594# SkCanvas::drawImage ##
1595# SkCanvas::drawImageRect ##
1596 #ToDo probably more... ##
1597#List ##
1598and when Paint has a Shader specialization that uses Image or Bitmap.
1599
1600Filter_Quality is kNone_SkFilterQuality by default.
1601
1602#Example
1603#Image 3
1604void draw(SkCanvas* canvas) {
1605 SkPaint paint;
1606 canvas->scale(.2f, .2f);
1607 for (SkFilterQuality q : { kNone_SkFilterQuality, kLow_SkFilterQuality,
1608 kMedium_SkFilterQuality, kHigh_SkFilterQuality } ) {
1609 paint.setFilterQuality(q);
1610 canvas->drawImage(image.get(), 0, 0, &paint);
1611 canvas->translate(550, 0);
1612 if (kLow_SkFilterQuality == q) canvas->translate(-1100, 550);
1613 }
1614}
1615##
1616
1617#Method SkFilterQuality getFilterQuality() const
1618
Cary Clarkab2621d2018-01-30 10:08:57 -05001619#In Filter_Quality_Methods
1620#Line # returns Filter_Quality, image filtering level ##
Cary Clark8032b982017-07-28 11:04:54 -04001621Returns Filter_Quality, the image filtering level. A lower setting
1622draws faster; a higher setting looks better when the image is scaled.
1623
1624#Return one of: kNone_SkFilterQuality, kLow_SkFilterQuality,
1625 kMedium_SkFilterQuality, kHigh_SkFilterQuality
1626#Return ##
1627
1628#Example
1629 SkPaint paint;
1630 SkDebugf("kNone_SkFilterQuality %c= paint.getFilterQuality()\n",
1631 kNone_SkFilterQuality == paint.getFilterQuality() ? '=' : '!');
1632
1633 #StdOut
1634 kNone_SkFilterQuality == paint.getFilterQuality()
1635 ##
1636##
1637
1638##
1639
1640
1641#Method void setFilterQuality(SkFilterQuality quality)
1642
Cary Clarkab2621d2018-01-30 10:08:57 -05001643#In Filter_Quality_Methods
1644#Line # sets Filter_Quality, the image filtering level ##
Cary Clark8032b982017-07-28 11:04:54 -04001645Sets Filter_Quality, the image filtering level. A lower setting
1646draws faster; a higher setting looks better when the image is scaled.
Cary Clark579985c2017-07-31 11:48:27 -04001647Does not check to see if quality is valid.
Cary Clark8032b982017-07-28 11:04:54 -04001648
1649#Param quality one of: kNone_SkFilterQuality, kLow_SkFilterQuality,
1650 kMedium_SkFilterQuality, kHigh_SkFilterQuality
1651##
1652
1653#Example
1654 SkPaint paint;
1655 paint.setFilterQuality(kHigh_SkFilterQuality);
1656 SkDebugf("kHigh_SkFilterQuality %c= paint.getFilterQuality()\n",
1657 kHigh_SkFilterQuality == paint.getFilterQuality() ? '=' : '!');
1658
1659 #StdOut
1660 kHigh_SkFilterQuality == paint.getFilterQuality()
1661 ##
1662##
1663
1664#SeeAlso SkFilterQuality Image_Scaling
1665
1666##
1667
Cary Clark08895c42018-02-01 09:37:32 -05001668#Subtopic Filter_Quality_Methods ##
Cary Clark8032b982017-07-28 11:04:54 -04001669# ------------------------------------------------------------------------------
Cary Clark08895c42018-02-01 09:37:32 -05001670#Subtopic Color_Methods
1671#Line # get and set Color ##
Cary Clark8032b982017-07-28 11:04:54 -04001672
Cary Clarkab2621d2018-01-30 10:08:57 -05001673#Table
1674#Legend
1675# name # description ##
1676#Legend ##
1677# getColor # returns Color_Alpha and Color_RGB, one drawing color ##
1678# setColor # sets Color_Alpha and Color_RGB, one drawing color ##
1679#Table ##
Cary Clark8032b982017-07-28 11:04:54 -04001680
Cary Clarkab2621d2018-01-30 10:08:57 -05001681Color specifies the Color_RGB_Red, Color_RGB_Blue, Color_RGB_Green, and Color_Alpha
1682values used to draw a filled or stroked shape in a 32-bit value. Each component
1683occupies 8-bits, ranging from zero: no contribution; to 255: full intensity.
1684All values in any combination are valid.
Cary Clark8032b982017-07-28 11:04:54 -04001685
Cary Clarkab2621d2018-01-30 10:08:57 -05001686Color is not Premultiplied; Color_Alpha sets the transparency independent of
1687Color_RGB: Color_RGB_Red, Color_RGB_Blue, and Color_RGB_Green.
1688
1689The bit positions of Color_Alpha and Color_RGB are independent of the bit
1690positions on the output device, which may have more or fewer bits, and may have
1691a different arrangement.
Cary Clark8032b982017-07-28 11:04:54 -04001692
1693#Table
1694#Legend
1695# bit positions # Color_Alpha # Color_RGB_Red # Color_RGB_Blue # Color_RGB_Green ##
1696#Legend ##
1697# # 31 - 24 # 23 - 16 # 15 - 8 # 7 - 0 ##
1698#Table ##
1699
1700#Example
1701#Height 128
1702 void draw(SkCanvas* canvas) {
1703 SkPaint paint;
1704 paint.setColor(0x8000FF00); // transparent green
1705 canvas->drawCircle(50, 50, 40, paint);
1706 paint.setARGB(128, 255, 0, 0); // transparent red
1707 canvas->drawCircle(80, 50, 40, paint);
1708 paint.setColor(SK_ColorBLUE);
1709 paint.setAlpha(0x80);
1710 canvas->drawCircle(65, 65, 40, paint);
1711 }
1712##
1713
1714#Method SkColor getColor() const
1715
Cary Clarkab2621d2018-01-30 10:08:57 -05001716#In Color_Methods
1717#Line # returns Color_Alpha and Color_RGB, one drawing color ##
Cary Clarkce101242017-09-01 15:51:02 -04001718 Retrieves Alpha and Color_RGB, Unpremultiplied, packed into 32 bits.
Cary Clark8032b982017-07-28 11:04:54 -04001719 Use helpers SkColorGetA, SkColorGetR, SkColorGetG, and SkColorGetB to extract
1720 a color component.
1721
1722 #Return Unpremultiplied Color_ARGB ##
1723
1724 #Example
1725 SkPaint paint;
1726 paint.setColor(SK_ColorYELLOW);
1727 SkColor y = paint.getColor();
1728 SkDebugf("Yellow is %d%% red, %d%% green, and %d%% blue.\n", (int) (SkColorGetR(y) / 2.55f),
1729 (int) (SkColorGetG(y) / 2.55f), (int) (SkColorGetB(y) / 2.55f));
1730
1731 #StdOut
1732 Yellow is 100% red, 100% green, and 0% blue.
1733 ##
1734 ##
1735
1736 #SeeAlso SkColor
1737
1738##
1739
1740#Method void setColor(SkColor color)
1741
Cary Clarkab2621d2018-01-30 10:08:57 -05001742#In Color_Methods
1743#Line # sets Color_Alpha and Color_RGB, one drawing color ##
Cary Clarkce101242017-09-01 15:51:02 -04001744 Sets Alpha and Color_RGB used when stroking and filling. The color is a 32-bit value,
1745 Unpremultiplied, packing 8-bit components for Alpha, Red, Blue, and Green.
Cary Clark8032b982017-07-28 11:04:54 -04001746
1747 #Param color Unpremultiplied Color_ARGB ##
Cary Clark0c5f5462017-12-15 11:21:51 -05001748
1749 #Example
Cary Clark8032b982017-07-28 11:04:54 -04001750 SkPaint green1, green2;
1751 unsigned a = 255;
1752 unsigned r = 0;
1753 unsigned g = 255;
1754 unsigned b = 0;
1755 green1.setColor((a << 24) + (r << 16) + (g << 8) + (b << 0));
1756 green2.setColor(0xFF00FF00);
1757 SkDebugf("green1 %c= green2\n", green1 == green2 ? '=' : '!');
1758
1759 #StdOut
1760 green1 == green2
1761 ##
1762 ##
1763
1764 #SeeAlso SkColor setARGB SkColorSetARGB
1765
1766##
Cary Clark08895c42018-02-01 09:37:32 -05001767#Subtopic Color_Methods ##
Cary Clark8032b982017-07-28 11:04:54 -04001768
1769#Subtopic Alpha_Methods
Cary Clark08895c42018-02-01 09:37:32 -05001770#Line # get and set Alpha ##
Cary Clark8032b982017-07-28 11:04:54 -04001771
1772Color_Alpha sets the transparency independent of Color_RGB: Color_RGB_Red, Color_RGB_Blue, and Color_RGB_Green.
1773
1774#Method uint8_t getAlpha() const
1775
Cary Clarkab2621d2018-01-30 10:08:57 -05001776#In Alpha_Methods
1777#Line # returns Color_Alpha, color opacity ##
Cary Clarkce101242017-09-01 15:51:02 -04001778 Retrieves Alpha from the Color used when stroking and filling.
Cary Clark8032b982017-07-28 11:04:54 -04001779
Cary Clarkce101242017-09-01 15:51:02 -04001780 #Return Alpha ranging from zero, fully transparent, to 255, fully opaque ##
Cary Clark8032b982017-07-28 11:04:54 -04001781
1782 #Example
1783 SkPaint paint;
1784 SkDebugf("255 %c= paint.getAlpha()\n", 255 == paint.getAlpha() ? '=' : '!');
1785
1786 #StdOut
1787 255 == paint.getAlpha()
1788 ##
1789 ##
1790
1791##
1792
1793#Method void setAlpha(U8CPU a)
1794
Cary Clarkab2621d2018-01-30 10:08:57 -05001795#In Alpha_Methods
1796#Line # sets Color_Alpha, color opacity ##
Cary Clarkce101242017-09-01 15:51:02 -04001797 Replaces Alpha, leaving Color_RGB
Cary Clark8032b982017-07-28 11:04:54 -04001798 unchanged. An out of range value triggers an assert in the debug
1799 build. a is a value from zero to 255.
1800 a set to zero makes Color fully transparent; a set to 255 makes Color
1801 fully opaque.
1802
Cary Clarkce101242017-09-01 15:51:02 -04001803 #Param a Alpha component of Color ##
Cary Clark8032b982017-07-28 11:04:54 -04001804
1805 #Example
1806 SkPaint paint;
1807 paint.setColor(0x00112233);
1808 paint.setAlpha(0x44);
1809 SkDebugf("0x44112233 %c= paint.getColor()\n", 0x44112233 == paint.getColor() ? '=' : '!');
1810
1811 #StdOut
1812 0x44112233 == paint.getColor()
1813 ##
1814 ##
1815
1816##
1817
Cary Clark08895c42018-02-01 09:37:32 -05001818#Subtopic Alpha_Methods ##
Cary Clark8032b982017-07-28 11:04:54 -04001819
1820#Method void setARGB(U8CPU a, U8CPU r, U8CPU g, U8CPU b)
1821
Cary Clarkab2621d2018-01-30 10:08:57 -05001822#In Color_Methods
1823#Line # sets color by component ##
Cary Clark8032b982017-07-28 11:04:54 -04001824 Sets Color used when drawing solid fills. The color components range from 0 to 255.
Cary Clarkce101242017-09-01 15:51:02 -04001825 The color is Unpremultiplied; Alpha sets the transparency independent of Color_RGB.
Cary Clark8032b982017-07-28 11:04:54 -04001826
1827 #Param a amount of Color_Alpha, from fully transparent (0) to fully opaque (255) ##
1828 #Param r amount of Color_RGB_Red, from no red (0) to full red (255) ##
1829 #Param g amount of Color_RGB_Green, from no green (0) to full green (255) ##
1830 #Param b amount of Color_RGB_Blue, from no blue (0) to full blue (255) ##
1831
1832 #Example
1833 SkPaint transRed1, transRed2;
1834 transRed1.setARGB(255 / 2, 255, 0, 0);
1835 transRed2.setColor(SkColorSetARGB(255 / 2, 255, 0, 0));
1836 SkDebugf("transRed1 %c= transRed2", transRed1 == transRed2 ? '=' : '!');
1837
1838 #StdOut
1839 transRed1 == transRed2
1840 ##
1841 ##
1842
1843 #SeeAlso setColor SkColorSetARGB
1844
1845##
1846
Cary Clark8032b982017-07-28 11:04:54 -04001847# ------------------------------------------------------------------------------
Cary Clark08895c42018-02-01 09:37:32 -05001848#Subtopic Style
1849#Line # geometry filling, stroking ##
Cary Clark8032b982017-07-28 11:04:54 -04001850
1851Style specifies if the geometry is filled, stroked, or both filled and stroked.
1852Some shapes ignore Style and are always drawn filled or stroked.
1853
1854Set Style to kFill_Style to fill the shape.
1855The fill covers the area inside the geometry for most shapes.
1856
1857Set Style to kStroke_Style to stroke the shape.
1858
1859# ------------------------------------------------------------------------------
1860#Subtopic Fill
Cary Clark08895c42018-02-01 09:37:32 -05001861#Line # fill and stroke ##
Cary Clark8032b982017-07-28 11:04:54 -04001862#ToDo write up whatever generalities make sense to describe filling ##
1863
1864#SeeAlso Path_Fill_Type
Cary Clark08895c42018-02-01 09:37:32 -05001865#Subtopic Fill ##
Cary Clark8032b982017-07-28 11:04:54 -04001866
1867#Subtopic Stroke
Cary Clark08895c42018-02-01 09:37:32 -05001868#Line # lines and curves with width ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001869The stroke covers the area described by following the shape edge with a pen or brush of
Cary Clark8032b982017-07-28 11:04:54 -04001870Stroke_Width. The area covered where the shape starts and stops is described by Stroke_Cap.
1871The area covered where the shape turns a corner is described by Stroke_Join.
Cary Clarkbc5697d2017-10-04 14:31:33 -04001872The stroke is centered on the shape; it extends equally on either side of the shape edge.
Cary Clark8032b982017-07-28 11:04:54 -04001873
1874As Stroke_Width gets smaller, the drawn path frame is thinner. Stroke_Width less than one
1875may have gaps, and if kAntiAlias_Flag is set, Color_Alpha will increase to visually decrease coverage.
Cary Clark08895c42018-02-01 09:37:32 -05001876#Subtopic Stroke ##
Cary Clark8032b982017-07-28 11:04:54 -04001877
1878#Subtopic Hairline
Cary Clark08895c42018-02-01 09:37:32 -05001879#Line # lines and curves with minimal width ##
Cary Clark8032b982017-07-28 11:04:54 -04001880#Alias Hairline # maybe should be Stroke_Hairline ?
1881
1882Stroke_Width of zero has a special meaning and switches drawing to use Hairline.
1883Hairline draws the thinnest continuous frame. If kAntiAlias_Flag is clear, adjacent pixels
1884flow horizontally, vertically,or diagonally.
1885
Cary Clarkce101242017-09-01 15:51:02 -04001886#ToDo what is the description of Anti-aliased hairlines? ##
Cary Clark8032b982017-07-28 11:04:54 -04001887
1888Path drawing with Hairline may hit the same pixel more than once. For instance, Path containing
1889two lines in one Path_Contour will draw the corner point once, but may both lines may draw the adjacent
1890pixel. If kAntiAlias_Flag is set, transparency is applied twice, resulting in a darker pixel. Some
1891GPU-backed implementations apply transparency at a later drawing stage, avoiding double hit pixels
1892while stroking.
1893
Cary Clark08895c42018-02-01 09:37:32 -05001894#Subtopic Hairline ##
Cary Clark8032b982017-07-28 11:04:54 -04001895
1896#Enum Style
Cary Clark08895c42018-02-01 09:37:32 -05001897#Line # stroke, fill, or both ##
Cary Clark8032b982017-07-28 11:04:54 -04001898
1899#Code
1900 enum Style {
1901 kFill_Style,
1902 kStroke_Style,
1903 kStrokeAndFill_Style,
1904 };
1905##
1906
1907Set Style to fill, stroke, or both fill and stroke geometry.
1908The stroke and fill
1909share all paint attributes; for instance, they are drawn with the same color.
1910
1911Use kStrokeAndFill_Style to avoid hitting the same pixels twice with a stroke draw and
1912a fill draw.
1913
1914#Const kFill_Style 0
1915 Set to fill geometry.
Cary Clarkce101242017-09-01 15:51:02 -04001916 Applies to Rect, Region, Round_Rect, Circles, Ovals, Path, and Text.
1917 Bitmap, Image, Patches, Region, Sprites, and Vertices are painted as if
Cary Clark8032b982017-07-28 11:04:54 -04001918 kFill_Style is set, and ignore the set Style.
1919 The Path_Fill_Type specifies additional rules to fill the area outside the path edge,
1920 and to create an unfilled hole inside the shape.
1921 Style is set to kFill_Style by default.
1922##
1923
1924#Const kStroke_Style 1
1925 Set to stroke geometry.
Cary Clarkce101242017-09-01 15:51:02 -04001926 Applies to Rect, Region, Round_Rect, Arcs, Circles, Ovals, Path, and Text.
Cary Clark56356312018-02-08 14:45:18 -05001927 Arcs, Lines, and points, are always drawn as if kStroke_Style is set,
Cary Clark8032b982017-07-28 11:04:54 -04001928 and ignore the set Style.
1929 The stroke construction is unaffected by the Path_Fill_Type.
1930##
1931
1932#Const kStrokeAndFill_Style 2
1933 Set to stroke and fill geometry.
Cary Clarkce101242017-09-01 15:51:02 -04001934 Applies to Rect, Region, Round_Rect, Circles, Ovals, Path, and Text.
Cary Clark8032b982017-07-28 11:04:54 -04001935 Path is treated as if it is set to SkPath::kWinding_FillType,
1936 and the set Path_Fill_Type is ignored.
1937##
1938
Cary Clark08895c42018-02-01 09:37:32 -05001939#Enum Style ##
Cary Clark8032b982017-07-28 11:04:54 -04001940
1941#Enum
Cary Clark08895c42018-02-01 09:37:32 -05001942#Line # number of Style defines ##
Cary Clark8032b982017-07-28 11:04:54 -04001943#Code
1944 enum {
Cary Clarkbad5ad72017-08-03 17:14:08 -04001945 kStyleCount = kStrokeAndFill_Style + 1,
Cary Clark8032b982017-07-28 11:04:54 -04001946 };
1947##
1948
1949#Const kStyleCount 3
1950The number of different Style values defined.
1951May be used to verify that Style is a legal value.
1952##
1953
1954#Enum ##
1955
1956#Method Style getStyle() const
1957
Cary Clarkab2621d2018-01-30 10:08:57 -05001958#In Style
1959#Line # returns Style: stroke, fill, or both ##
Cary Clark8032b982017-07-28 11:04:54 -04001960 Whether the geometry is filled, stroked, or filled and stroked.
1961
1962 #Return one of:kFill_Style, kStroke_Style, kStrokeAndFill_Style ##
1963
1964 #Example
1965 SkPaint paint;
1966 SkDebugf("SkPaint::kFill_Style %c= paint.getStyle()\n",
1967 SkPaint::kFill_Style == paint.getStyle() ? '=' : '!');
1968
1969 #StdOut
1970 SkPaint::kFill_Style == paint.getStyle()
1971 ##
1972 ##
1973
1974#SeeAlso Style setStyle
1975##
1976
1977#Method void setStyle(Style style)
1978
Cary Clarkab2621d2018-01-30 10:08:57 -05001979#In Style
1980#Line # sets Style: stroke, fill, or both ##
Cary Clark8032b982017-07-28 11:04:54 -04001981 Sets whether the geometry is filled, stroked, or filled and stroked.
1982 Has no effect if style is not a legal Style value.
1983
1984 #Param style one of: kFill_Style, kStroke_Style, kStrokeAndFill_Style
1985 ##
1986
1987 #Example
1988 void draw(SkCanvas* canvas) {
1989 SkPaint paint;
1990 paint.setStrokeWidth(5);
1991 SkRegion region;
1992 region.op(140, 10, 160, 30, SkRegion::kUnion_Op);
1993 region.op(170, 40, 190, 60, SkRegion::kUnion_Op);
1994 SkBitmap bitmap;
1995 bitmap.setInfo(SkImageInfo::MakeA8(50, 50), 50);
1996 uint8_t pixels[50][50];
1997 for (int x = 0; x < 50; ++x) {
1998 for (int y = 0; y < 50; ++y) {
1999 pixels[y][x] = (x + y) % 5 ? 0xFF : 0x00;
2000 }
2001 }
2002 bitmap.setPixels(pixels);
2003 for (auto style : { SkPaint::kFill_Style,
2004 SkPaint::kStroke_Style,
2005 SkPaint::kStrokeAndFill_Style }) {
2006 paint.setStyle(style);
2007 canvas->drawLine(10, 10, 60, 60, paint);
2008 canvas->drawRect({80, 10, 130, 60}, paint);
2009 canvas->drawRegion(region, paint);
2010 canvas->drawBitmap(bitmap, 200, 10, &paint);
2011 canvas->translate(0, 80);
2012 }
2013 }
2014 ##
2015
2016#SeeAlso Style getStyle
2017##
2018
2019#SeeAlso Path_Fill_Type Path_Effect Style_Fill Style_Stroke
Cary Clark08895c42018-02-01 09:37:32 -05002020#Subtopic Style ##
Cary Clark8032b982017-07-28 11:04:54 -04002021
2022# ------------------------------------------------------------------------------
Cary Clark08895c42018-02-01 09:37:32 -05002023#Subtopic Stroke_Width
2024#Line # thickness perpendicular to geometry ##
Cary Clark8032b982017-07-28 11:04:54 -04002025
2026Stroke_Width sets the width for stroking. The width is the thickness
Cary Clarkbc5697d2017-10-04 14:31:33 -04002027of the stroke perpendicular to the path direction when the paint style is
Cary Clark8032b982017-07-28 11:04:54 -04002028set to kStroke_Style or kStrokeAndFill_Style.
2029
2030When width is greater than zero, the stroke encompasses as many pixels partially
2031or fully as needed. When the width equals zero, the paint enables hairlines;
2032the stroke is always one pixel wide.
2033
Cary Clarkbc5697d2017-10-04 14:31:33 -04002034The stroke dimensions are scaled by the canvas matrix, but Hairline stroke
Cary Clark8032b982017-07-28 11:04:54 -04002035remains one pixel wide regardless of scaling.
2036
2037The default width for the paint is zero.
2038
2039#Example
2040#Height 170
2041 #Platform raster gpu
2042 #Description
2043 The pixels hit to represent thin lines vary with the angle of the
Cary Clarkbc5697d2017-10-04 14:31:33 -04002044 line and the platform implementation.
Cary Clark8032b982017-07-28 11:04:54 -04002045 ##
2046 void draw(SkCanvas* canvas) {
2047 SkPaint paint;
2048 for (bool antialias : { false, true }) {
2049 paint.setAntiAlias(antialias);
2050 for (int width = 0; width <= 4; ++width) {
2051 SkScalar offset = antialias * 100 + width * 20;
2052 paint.setStrokeWidth(width * 0.25f);
2053 canvas->drawLine(10 + offset, 10, 20 + offset, 60, paint);
2054 canvas->drawLine(10 + offset, 110, 60 + offset, 160, paint);
2055 }
2056 }
2057 }
2058##
2059
2060#Method SkScalar getStrokeWidth() const
2061
Cary Clarkab2621d2018-01-30 10:08:57 -05002062#In Stroke_Width
2063#Line # returns thickness of the stroke ##
Cary Clark8032b982017-07-28 11:04:54 -04002064 Returns the thickness of the pen used by Paint to
2065 outline the shape.
2066
2067 #Return zero for Hairline, greater than zero for pen thickness ##
2068
2069 #Example
2070 SkPaint paint;
2071 SkDebugf("0 %c= paint.getStrokeWidth()\n", 0 == paint.getStrokeWidth() ? '=' : '!');
2072
2073 #StdOut
2074 0 == paint.getStrokeWidth()
2075 ##
2076 ##
2077
2078##
2079
2080#Method void setStrokeWidth(SkScalar width)
2081
Cary Clarkab2621d2018-01-30 10:08:57 -05002082#In Stroke_Width
2083#Line # sets thickness of the stroke ##
Cary Clark8032b982017-07-28 11:04:54 -04002084 Sets the thickness of the pen used by the paint to
2085 outline the shape.
2086 Has no effect if width is less than zero.
2087
2088 #Param width zero thickness for Hairline; greater than zero for pen thickness
2089 ##
2090
2091 #Example
2092 SkPaint paint;
2093 paint.setStrokeWidth(5);
2094 paint.setStrokeWidth(-1);
2095 SkDebugf("5 %c= paint.getStrokeWidth()\n", 5 == paint.getStrokeWidth() ? '=' : '!');
2096
2097 #StdOut
2098 5 == paint.getStrokeWidth()
2099 ##
2100 ##
2101
2102##
2103
Cary Clark08895c42018-02-01 09:37:32 -05002104#Subtopic Stroke_Width ##
Cary Clark8032b982017-07-28 11:04:54 -04002105# ------------------------------------------------------------------------------
Cary Clark08895c42018-02-01 09:37:32 -05002106#Subtopic Miter_Limit
2107#Line # maximum length of stroked corners ##
Cary Clark8032b982017-07-28 11:04:54 -04002108
2109Miter_Limit specifies the maximum miter length,
2110relative to the stroke width.
2111
2112Miter_Limit is used when the Stroke_Join
2113is set to kMiter_Join, and the Style is either kStroke_Style
2114or kStrokeAndFill_Style.
2115
2116If the miter at a corner exceeds this limit, kMiter_Join
2117is replaced with kBevel_Join.
2118
2119Miter_Limit can be computed from the corner angle:
2120
2121#Formula
2122 miter limit = 1 / sin ( angle / 2 )
2123#Formula ##
2124
2125Miter_Limit default value is 4.
2126The default may be changed at compile time by setting SkPaintDefaults_MiterLimit
Cary Clarkce101242017-09-01 15:51:02 -04002127in "SkUserConfig.h" or as a define supplied by the build environment.
Cary Clark8032b982017-07-28 11:04:54 -04002128
2129Here are some miter limits and the angles that triggers them.
2130#Table
2131#Legend
2132 # miter limit # angle in degrees ##
2133#Legend ##
2134 # 10 # 11.48 ##
2135 # 9 # 12.76 ##
2136 # 8 # 14.36 ##
2137 # 7 # 16.43 ##
2138 # 6 # 19.19 ##
2139 # 5 # 23.07 ##
2140 # 4 # 28.96 ##
2141 # 3 # 38.94 ##
2142 # 2 # 60 ##
2143 # 1 # 180 ##
2144#Table ##
2145
2146#Example
2147 #Height 170
2148 #Width 384
2149 #Description
2150 This example draws a stroked corner and the miter length beneath.
2151 When the miter limit is decreased slightly, the miter join is replaced
2152 by a bevel join.
2153 ##
2154 void draw(SkCanvas* canvas) {
2155 SkPoint pts[] = {{ 10, 50 }, { 110, 80 }, { 10, 110 }};
2156 SkVector v[] = { pts[0] - pts[1], pts[2] - pts[1] };
2157 SkScalar angle1 = SkScalarATan2(v[0].fY, v[0].fX);
2158 SkScalar angle2 = SkScalarATan2(v[1].fY, v[1].fX);
2159 const SkScalar strokeWidth = 20;
2160 SkScalar miterLimit = 1 / SkScalarSin((angle2 - angle1) / 2);
2161 SkScalar miterLength = strokeWidth * miterLimit;
2162 SkPath path;
2163 path.moveTo(pts[0]);
2164 path.lineTo(pts[1]);
2165 path.lineTo(pts[2]);
2166 SkPaint paint; // set to default kMiter_Join
2167 paint.setAntiAlias(true);
2168 paint.setStyle(SkPaint::kStroke_Style);
2169 paint.setStrokeMiter(miterLimit);
2170 paint.setStrokeWidth(strokeWidth);
2171 canvas->drawPath(path, paint);
2172 paint.setStrokeWidth(1);
2173 canvas->drawLine(pts[1].fX - miterLength / 2, pts[1].fY + 50,
2174 pts[1].fX + miterLength / 2, pts[1].fY + 50, paint);
2175 canvas->translate(200, 0);
2176 miterLimit *= 0.99f;
2177 paint.setStrokeMiter(miterLimit);
2178 paint.setStrokeWidth(strokeWidth);
2179 canvas->drawPath(path, paint);
2180 paint.setStrokeWidth(1);
2181 canvas->drawLine(pts[1].fX - miterLength / 2, pts[1].fY + 50,
2182 pts[1].fX + miterLength / 2, pts[1].fY + 50, paint);
2183 }
2184##
2185
2186#Method SkScalar getStrokeMiter() const
2187
Cary Clarkab2621d2018-01-30 10:08:57 -05002188#In Miter_Limit
2189#Line # returns Miter_Limit, angles with sharp corners ##
Cary Clark8032b982017-07-28 11:04:54 -04002190 The limit at which a sharp corner is drawn beveled.
2191
2192 #Return zero and greater Miter_Limit ##
2193
2194 #Example
2195 SkPaint paint;
2196 SkDebugf("default miter limit == %g\n", paint.getStrokeMiter());
2197
2198 #StdOut
2199 default miter limit == 4
2200 ##
2201 ##
2202
2203 #SeeAlso Miter_Limit setStrokeMiter Join
2204
2205##
2206
2207#Method void setStrokeMiter(SkScalar miter)
2208
Cary Clarkab2621d2018-01-30 10:08:57 -05002209#In Miter_Limit
2210#Line # sets Miter_Limit, angles with sharp corners ##
Cary Clark8032b982017-07-28 11:04:54 -04002211 The limit at which a sharp corner is drawn beveled.
2212 Valid values are zero and greater.
2213 Has no effect if miter is less than zero.
2214
2215 #Param miter zero and greater Miter_Limit
2216 ##
2217
2218 #Example
2219 SkPaint paint;
2220 paint.setStrokeMiter(8);
2221 paint.setStrokeMiter(-1);
2222 SkDebugf("default miter limit == %g\n", paint.getStrokeMiter());
2223
2224 #StdOut
2225 default miter limit == 8
2226 ##
2227 ##
2228
2229 #SeeAlso Miter_Limit getStrokeMiter Join
2230
2231##
2232
Cary Clark08895c42018-02-01 09:37:32 -05002233#Subtopic Miter_Limit ##
Cary Clark8032b982017-07-28 11:04:54 -04002234# ------------------------------------------------------------------------------
Cary Clark08895c42018-02-01 09:37:32 -05002235#Subtopic Stroke_Cap
2236#Line # decorations at ends of open strokes ##
Cary Clark8032b982017-07-28 11:04:54 -04002237
2238#Enum Cap
Cary Clark08895c42018-02-01 09:37:32 -05002239#Line # start and end geometry on stroked shapes ##
Cary Clark8032b982017-07-28 11:04:54 -04002240
2241#Code
2242 enum Cap {
2243 kButt_Cap,
2244 kRound_Cap,
2245 kSquare_Cap,
2246
2247 kLast_Cap = kSquare_Cap,
Cary Clarkbad5ad72017-08-03 17:14:08 -04002248 kDefault_Cap = kButt_Cap,
Cary Clark8032b982017-07-28 11:04:54 -04002249 };
Cary Clark6fc50412017-09-21 12:31:06 -04002250
Cary Clark8032b982017-07-28 11:04:54 -04002251 static constexpr int kCapCount = kLast_Cap + 1;
2252##
2253
2254Stroke_Cap draws at the beginning and end of an open Path_Contour.
2255
2256 #Const kButt_Cap 0
2257 Does not extend the stroke past the beginning or the end.
2258 ##
2259 #Const kRound_Cap 1
2260 Adds a circle with a diameter equal to Stroke_Width at the beginning
2261 and end.
2262 ##
2263 #Const kSquare_Cap 2
2264 Adds a square with sides equal to Stroke_Width at the beginning
2265 and end. The square sides are parallel to the initial and final direction
2266 of the stroke.
2267 ##
2268 #Const kLast_Cap 2
2269 Equivalent to the largest value for Stroke_Cap.
2270 ##
2271 #Const kDefault_Cap 0
2272 Equivalent to kButt_Cap.
2273 Stroke_Cap is set to kButt_Cap by default.
2274 ##
2275
2276 #Const kCapCount 3
2277 The number of different Stroke_Cap values defined.
2278 May be used to verify that Stroke_Cap is a legal value.
2279 ##
2280#Enum ##
2281
2282Stroke describes the area covered by a pen of Stroke_Width as it
Cary Clarkbc5697d2017-10-04 14:31:33 -04002283follows the Path_Contour, moving parallel to the contour direction.
Cary Clark8032b982017-07-28 11:04:54 -04002284
2285If the Path_Contour is not terminated by SkPath::kClose_Verb, the contour has a
2286visible beginning and end.
2287
2288Path_Contour may start and end at the same point; defining Zero_Length_Contour.
2289
2290kButt_Cap and Zero_Length_Contour is not drawn.
2291kRound_Cap and Zero_Length_Contour draws a circle of diameter Stroke_Width
2292at the contour point.
2293kSquare_Cap and Zero_Length_Contour draws an upright square with a side of
2294Stroke_Width at the contour point.
2295
2296Stroke_Cap is kButt_Cap by default.
2297
2298#Example
Cary Clark2ade9972017-11-02 17:49:34 -04002299#Height 200
Cary Clark8032b982017-07-28 11:04:54 -04002300 SkPaint paint;
2301 paint.setStyle(SkPaint::kStroke_Style);
2302 paint.setStrokeWidth(20);
2303 SkPath path;
2304 path.moveTo(30, 30);
2305 path.lineTo(30, 30);
2306 path.moveTo(70, 30);
2307 path.lineTo(90, 40);
2308 for (SkPaint::Cap c : { SkPaint::kButt_Cap, SkPaint::kRound_Cap, SkPaint::kSquare_Cap } ) {
2309 paint.setStrokeCap(c);
2310 canvas->drawPath(path, paint);
2311 canvas->translate(0, 70);
2312 }
2313##
2314
2315#Method Cap getStrokeCap() const
2316
Cary Clarkab2621d2018-01-30 10:08:57 -05002317#In Stroke_Cap
2318#Line # returns Cap, the area drawn at path ends ##
Cary Clark8032b982017-07-28 11:04:54 -04002319 The geometry drawn at the beginning and end of strokes.
2320
2321 #Return one of: kButt_Cap, kRound_Cap, kSquare_Cap ##
2322
2323 #Example
2324 SkPaint paint;
2325 SkDebugf("kButt_Cap %c= default stroke cap\n",
2326 SkPaint::kButt_Cap == paint.getStrokeCap() ? '=' : '!');
2327
2328 #StdOut
2329 kButt_Cap == default stroke cap
2330 ##
2331 ##
2332
2333 #SeeAlso Stroke_Cap setStrokeCap
2334##
2335
2336#Method void setStrokeCap(Cap cap)
2337
Cary Clarkab2621d2018-01-30 10:08:57 -05002338#In Stroke_Cap
2339#Line # sets Cap, the area drawn at path ends ##
Cary Clark8032b982017-07-28 11:04:54 -04002340 The geometry drawn at the beginning and end of strokes.
2341
2342 #Param cap one of: kButt_Cap, kRound_Cap, kSquare_Cap;
2343 has no effect if cap is not valid
2344 ##
2345
2346 #Example
2347 SkPaint paint;
2348 paint.setStrokeCap(SkPaint::kRound_Cap);
2349 paint.setStrokeCap((SkPaint::Cap) SkPaint::kCapCount);
2350 SkDebugf("kRound_Cap %c= paint.getStrokeCap()\n",
2351 SkPaint::kRound_Cap == paint.getStrokeCap() ? '=' : '!');
2352
2353 #StdOut
2354 kRound_Cap == paint.getStrokeCap()
2355 ##
2356 ##
2357
2358 #SeeAlso Stroke_Cap getStrokeCap
2359##
2360
Cary Clark08895c42018-02-01 09:37:32 -05002361#Subtopic Stroke_Cap ##
Cary Clark8032b982017-07-28 11:04:54 -04002362# ------------------------------------------------------------------------------
Cary Clark08895c42018-02-01 09:37:32 -05002363#Subtopic Stroke_Join
2364#Line # decoration at corners of strokes ##
Cary Clark8032b982017-07-28 11:04:54 -04002365
2366Stroke_Join draws at the sharp corners of an open or closed Path_Contour.
2367
2368Stroke describes the area covered by a pen of Stroke_Width as it
Cary Clarkbc5697d2017-10-04 14:31:33 -04002369follows the Path_Contour, moving parallel to the contour direction.
Cary Clark8032b982017-07-28 11:04:54 -04002370
2371If the contour direction changes abruptly, because the tangent direction leading
2372to the end of a curve within the contour does not match the tangent direction of
2373the following curve, the pair of curves meet at Stroke_Join.
2374
2375#Example
Cary Clark2ade9972017-11-02 17:49:34 -04002376#Height 200
Cary Clarka560c472017-11-27 10:44:06 -05002377 SkPaint paint;
2378 paint.setStyle(SkPaint::kStroke_Style);
2379 paint.setStrokeWidth(20);
2380 SkPath path;
2381 path.moveTo(30, 20);
2382 path.lineTo(40, 40);
2383 path.conicTo(70, 20, 100, 20, .707f);
2384 for (SkPaint::Join j : { SkPaint::kMiter_Join, SkPaint::kRound_Join, SkPaint::kBevel_Join } ) {
2385 paint.setStrokeJoin(j);
2386 canvas->drawPath(path, paint);
2387 canvas->translate(0, 70);
2388 }
Cary Clark8032b982017-07-28 11:04:54 -04002389##
2390
2391#Enum Join
Cary Clark08895c42018-02-01 09:37:32 -05002392#Line # corner geometry on stroked shapes ##
Cary Clark8032b982017-07-28 11:04:54 -04002393#Code
2394 enum Join {
2395 kMiter_Join,
2396 kRound_Join,
2397 kBevel_Join,
2398
2399 kLast_Join = kBevel_Join,
Cary Clarkbad5ad72017-08-03 17:14:08 -04002400 kDefault_Join = kMiter_Join,
Cary Clark8032b982017-07-28 11:04:54 -04002401 };
Cary Clark6fc50412017-09-21 12:31:06 -04002402
Cary Clark8032b982017-07-28 11:04:54 -04002403 static constexpr int kJoinCount = kLast_Join + 1;
2404##
2405
Cary Clark1eace2d2017-07-31 07:52:43 -04002406Join specifies how corners are drawn when a shape is stroked. Join
Cary Clark8032b982017-07-28 11:04:54 -04002407affects the four corners of a stroked rectangle, and the connected segments in a
2408stroked path.
2409
2410Choose miter join to draw sharp corners. Choose round join to draw a circle with a
2411radius equal to the stroke width on top of the corner. Choose bevel join to minimally
2412connect the thick strokes.
2413
2414The fill path constructed to describe the stroked path respects the join setting but may
2415not contain the actual join. For instance, a fill path constructed with round joins does
2416not necessarily include circles at each connected segment.
2417
2418#Const kMiter_Join 0
2419 Extends the outside corner to the extent allowed by Miter_Limit.
2420 If the extension exceeds Miter_Limit, kBevel_Join is used instead.
2421##
2422
2423#Const kRound_Join 1
2424 Adds a circle with a diameter of Stroke_Width at the sharp corner.
2425##
2426
2427#Const kBevel_Join 2
2428 Connects the outside edges of the sharp corner.
2429##
2430
2431#Const kLast_Join 2
2432 Equivalent to the largest value for Stroke_Join.
2433##
2434
2435#Const kDefault_Join 1
2436 Equivalent to kMiter_Join.
2437 Stroke_Join is set to kMiter_Join by default.
2438##
2439
2440#Const kJoinCount 3
2441 The number of different Stroke_Join values defined.
2442 May be used to verify that Stroke_Join is a legal value.
2443##
2444
2445#Example
2446#Width 462
2447void draw(SkCanvas* canvas) {
2448 SkPath path;
2449 path.moveTo(10, 50);
2450 path.quadTo(35, 110, 60, 210);
2451 path.quadTo(105, 110, 130, 10);
2452 SkPaint paint; // set to default kMiter_Join
2453 paint.setAntiAlias(true);
2454 paint.setStyle(SkPaint::kStroke_Style);
2455 paint.setStrokeWidth(20);
2456 canvas->drawPath(path, paint);
2457 canvas->translate(150, 0);
2458 paint.setStrokeJoin(SkPaint::kBevel_Join);
2459 canvas->drawPath(path, paint);
2460 canvas->translate(150, 0);
2461 paint.setStrokeJoin(SkPaint::kRound_Join);
2462 canvas->drawPath(path, paint);
2463}
2464##
2465
2466#SeeAlso setStrokeJoin getStrokeJoin setStrokeMiter getStrokeMiter
2467
2468#Enum ##
2469
2470#Method Join getStrokeJoin() const
2471
Cary Clarkab2621d2018-01-30 10:08:57 -05002472#In Stroke_Join
2473#Line # returns Join, geometry on path corners ##
Cary Clark0c5f5462017-12-15 11:21:51 -05002474 The geometry drawn at the corners of strokes.
Cary Clark8032b982017-07-28 11:04:54 -04002475
2476 #Return one of: kMiter_Join, kRound_Join, kBevel_Join ##
2477
2478 #Example
2479 SkPaint paint;
2480 SkDebugf("kMiter_Join %c= default stroke join\n",
2481 SkPaint::kMiter_Join == paint.getStrokeJoin() ? '=' : '!');
2482
2483 #StdOut
2484 kMiter_Join == default stroke join
2485 ##
2486 ##
2487
2488 #SeeAlso Stroke_Join setStrokeJoin
2489##
2490
2491#Method void setStrokeJoin(Join join)
2492
Cary Clarkab2621d2018-01-30 10:08:57 -05002493#In Stroke_Join
2494#Line # sets Join, geometry on path corners ##
Cary Clark0c5f5462017-12-15 11:21:51 -05002495 The geometry drawn at the corners of strokes.
Cary Clark8032b982017-07-28 11:04:54 -04002496
2497 #Param join one of: kMiter_Join, kRound_Join, kBevel_Join;
Cary Clark579985c2017-07-31 11:48:27 -04002498 otherwise, has no effect
Cary Clark8032b982017-07-28 11:04:54 -04002499 ##
2500
2501 #Example
2502 SkPaint paint;
2503 paint.setStrokeJoin(SkPaint::kMiter_Join);
2504 paint.setStrokeJoin((SkPaint::Join) SkPaint::kJoinCount);
2505 SkDebugf("kMiter_Join %c= paint.getStrokeJoin()\n",
2506 SkPaint::kMiter_Join == paint.getStrokeJoin() ? '=' : '!');
2507
2508 #StdOut
2509 kMiter_Join == paint.getStrokeJoin()
2510 ##
2511 ##
2512
2513 #SeeAlso Stroke_Join getStrokeJoin
2514##
2515
2516#SeeAlso Miter_Limit
2517
Cary Clark08895c42018-02-01 09:37:32 -05002518#Subtopic Stroke_Join ##
Cary Clark8032b982017-07-28 11:04:54 -04002519# ------------------------------------------------------------------------------
Cary Clark08895c42018-02-01 09:37:32 -05002520#Subtopic Fill_Path
2521#Line # make Path from Path_Effect, stroking ##
Cary Clark8032b982017-07-28 11:04:54 -04002522
2523Fill_Path creates a Path by applying the Path_Effect, followed by the Style_Stroke.
2524
2525If Paint contains Path_Effect, Path_Effect operates on the source Path; the result
2526replaces the destination Path. Otherwise, the source Path is replaces the
2527destination Path.
2528
2529Fill Path can request the Path_Effect to restrict to a culling rectangle, but
2530the Path_Effect is not required to do so.
2531
2532If Style is kStroke_Style or kStrokeAndFill_Style,
2533and Stroke_Width is greater than zero, the Stroke_Width, Stroke_Cap, Stroke_Join,
2534and Miter_Limit operate on the destination Path, replacing it.
2535
2536Fill Path can specify the precision used by Stroke_Width to approximate the stroke geometry.
2537
2538If the Style is kStroke_Style and the Stroke_Width is zero, getFillPath
2539returns false since Hairline has no filled equivalent.
2540
2541#Method bool getFillPath(const SkPath& src, SkPath* dst, const SkRect* cullRect,
2542 SkScalar resScale = 1) const
Cary Clarkab2621d2018-01-30 10:08:57 -05002543#In Fill_Path
2544#Line # returns fill path equivalent to stroke ##
Cary Clark8032b982017-07-28 11:04:54 -04002545
2546 The filled equivalent of the stroked path.
2547
2548 #Param src Path read to create a filled version ##
2549 #Param dst resulting Path; may be the same as src, but may not be nullptr ##
2550 #Param cullRect optional limit passed to Path_Effect ##
2551 #Param resScale if > 1, increase precision, else if (0 < res < 1) reduce precision
2552 to favor speed and size
2553 ##
2554 #Return true if the path represents Style_Fill, or false if it represents Hairline ##
2555
2556 #Example
2557 #Height 192
2558 #Description
Cary Clarkce101242017-09-01 15:51:02 -04002559 A very small Quad stroke is turned into a filled path with increasing levels of precision.
2560 At the lowest precision, the Quad stroke is approximated by a rectangle.
Cary Clark8032b982017-07-28 11:04:54 -04002561 At the highest precision, the filled path has high fidelity compared to the original stroke.
2562 ##
2563 void draw(SkCanvas* canvas) {
2564 SkPaint strokePaint;
2565 strokePaint.setAntiAlias(true);
2566 strokePaint.setStyle(SkPaint::kStroke_Style);
2567 strokePaint.setStrokeWidth(.1f);
2568 SkPath strokePath;
2569 strokePath.moveTo(.08f, .08f);
2570 strokePath.quadTo(.09f, .08f, .17f, .17f);
2571 SkPath fillPath;
2572 SkPaint outlinePaint(strokePaint);
2573 outlinePaint.setStrokeWidth(2);
2574 SkMatrix scale = SkMatrix::MakeScale(300, 300);
2575 for (SkScalar precision : { 0.01f, .1f, 1.f, 10.f, 100.f } ) {
2576 strokePaint.getFillPath(strokePath, &fillPath, nullptr, precision);
2577 fillPath.transform(scale);
2578 canvas->drawPath(fillPath, outlinePaint);
2579 canvas->translate(60, 0);
2580 if (1.f == precision) canvas->translate(-180, 100);
2581 }
2582 strokePath.transform(scale);
2583 strokePaint.setStrokeWidth(30);
2584 canvas->drawPath(strokePath, strokePaint);
2585 }
2586 ##
2587
2588##
2589
2590#Method bool getFillPath(const SkPath& src, SkPath* dst) const
2591
Cary Clarkab2621d2018-01-30 10:08:57 -05002592#In Fill_Path
Cary Clark8032b982017-07-28 11:04:54 -04002593 The filled equivalent of the stroked path.
2594
2595 Replaces dst with the src path modified by Path_Effect and Style_Stroke.
2596 Path_Effect, if any, is not culled. Stroke_Width is created with default precision.
2597
2598 #Param src Path read to create a filled version ##
2599 #Param dst resulting Path dst may be the same as src, but may not be nullptr ##
2600 #Return true if the path represents Style_Fill, or false if it represents Hairline ##
2601
2602 #Example
2603 #Height 128
2604 void draw(SkCanvas* canvas) {
2605 SkPaint paint;
2606 paint.setStyle(SkPaint::kStroke_Style);
2607 paint.setStrokeWidth(10);
2608 SkPath strokePath;
2609 strokePath.moveTo(20, 20);
2610 strokePath.lineTo(100, 100);
2611 canvas->drawPath(strokePath, paint);
2612 SkPath fillPath;
2613 paint.getFillPath(strokePath, &fillPath);
2614 paint.setStrokeWidth(2);
2615 canvas->translate(40, 0);
2616 canvas->drawPath(fillPath, paint);
2617 }
2618 ##
2619
2620##
2621
2622#SeeAlso Style_Stroke Stroke_Width Path_Effect
2623
Cary Clark08895c42018-02-01 09:37:32 -05002624#Subtopic Fill_Path ##
Cary Clark8032b982017-07-28 11:04:54 -04002625# ------------------------------------------------------------------------------
Cary Clark08895c42018-02-01 09:37:32 -05002626#Subtopic Shader_Methods
2627#Line # get and set Shader ##
Cary Clark8032b982017-07-28 11:04:54 -04002628
2629Shader defines the colors used when drawing a shape.
2630Shader may be an image, a gradient, or a computed fill.
2631If Paint has no Shader, then Color fills the shape.
2632
2633Shader is modulated by Color_Alpha component of Color.
2634If Shader object defines only Color_Alpha, then Color modulated by Color_Alpha describes
2635the fill.
2636
2637The drawn transparency can be modified without altering Shader, by changing Color_Alpha.
2638
2639#Example
2640void draw(SkCanvas* canvas) {
2641 SkPaint paint;
2642 SkPoint center = { 50, 50 };
2643 SkScalar radius = 50;
2644 const SkColor colors[] = { 0xFFFFFFFF, 0xFF000000 };
2645 paint.setShader(SkGradientShader::MakeRadial(center, radius, colors,
2646 nullptr, SK_ARRAY_COUNT(colors), SkShader::kClamp_TileMode));
2647 for (SkScalar a : { 0.3f, 0.6f, 1.0f } ) {
2648 paint.setAlpha((int) (a * 255));
2649 canvas->drawCircle(center.fX, center.fY, radius, paint);
2650 canvas->translate(70, 70);
2651 }
2652}
2653##
2654
2655If Shader generates only Color_Alpha then all components of Color modulate the output.
2656
2657#Example
2658void draw(SkCanvas* canvas) {
2659 SkPaint paint;
2660 SkBitmap bitmap;
2661 bitmap.setInfo(SkImageInfo::MakeA8(5, 1), 5); // bitmap only contains alpha
2662 uint8_t pixels[5] = { 0x22, 0x55, 0x88, 0xBB, 0xFF };
2663 bitmap.setPixels(pixels);
2664 paint.setShader(SkShader::MakeBitmapShader(bitmap,
2665 SkShader::kMirror_TileMode, SkShader::kMirror_TileMode));
2666 for (SkColor c : { SK_ColorRED, SK_ColorBLUE, SK_ColorGREEN } ) {
2667 paint.setColor(c); // all components in color affect shader
2668 canvas->drawCircle(50, 50, 50, paint);
2669 canvas->translate(70, 70);
2670 }
2671}
2672##
2673
2674#Method SkShader* getShader() const
2675
Cary Clarkab2621d2018-01-30 10:08:57 -05002676#In Shader_Methods
2677#Line # returns Shader, multiple drawing colors; gradients ##
Cary Clark8032b982017-07-28 11:04:54 -04002678 Optional colors used when filling a path, such as a gradient.
2679
2680 Does not alter Shader Reference_Count.
2681
2682 #Return Shader if previously set, nullptr otherwise ##
2683
2684 #Example
2685 void draw(SkCanvas* canvas) {
2686 SkPaint paint;
2687 SkDebugf("nullptr %c= shader\n", paint.getShader() ? '!' : '=');
2688 paint.setShader(SkShader::MakeEmptyShader());
2689 SkDebugf("nullptr %c= shader\n", paint.getShader() ? '!' : '=');
2690 }
2691
2692 #StdOut
2693 nullptr == shader
2694 nullptr != shader
2695 ##
2696 ##
2697
2698##
2699
2700#Method sk_sp<SkShader> refShader() const
2701
Cary Clarkab2621d2018-01-30 10:08:57 -05002702#In Shader_Methods
2703#Line # references Shader, multiple drawing colors; gradients ##
Cary Clark8032b982017-07-28 11:04:54 -04002704 Optional colors used when filling a path, such as a gradient.
2705
2706 Increases Shader Reference_Count by one.
2707
2708 #Return Shader if previously set, nullptr otherwise ##
2709
2710 #Example
2711 void draw(SkCanvas* canvas) {
2712 SkPaint paint1, paint2;
2713 paint1.setShader(SkShader::MakeEmptyShader());
2714 SkDebugf("shader unique: %s\n", paint1.getShader()->unique() ? "true" : "false");
2715 paint2.setShader(paint1.refShader());
2716 SkDebugf("shader unique: %s\n", paint1.getShader()->unique() ? "true" : "false");
2717 }
2718
2719 #StdOut
2720 shader unique: true
2721 shader unique: false
2722 ##
2723 ##
2724
2725##
2726
2727#Method void setShader(sk_sp<SkShader> shader)
2728
Cary Clarkab2621d2018-01-30 10:08:57 -05002729#In Shader_Methods
2730#Line # sets Shader, multiple drawing colors; gradients ##
Cary Clark8032b982017-07-28 11:04:54 -04002731 Optional colors used when filling a path, such as a gradient.
2732
Cary Clarkd0530ba2017-09-14 11:25:39 -04002733 Sets Shader to shader, decreasing Reference_Count of the previous Shader.
Cary Clark6fc50412017-09-21 12:31:06 -04002734 Increments shader Reference_Count by one.
Cary Clark8032b982017-07-28 11:04:54 -04002735
2736 #Param shader how geometry is filled with color; if nullptr, Color is used instead ##
2737
2738 #Example
2739 #Height 64
2740 void draw(SkCanvas* canvas) {
2741 SkPaint paint;
2742 paint.setColor(SK_ColorBLUE);
2743 paint.setShader(SkShader::MakeColorShader(SK_ColorRED));
2744 canvas->drawRect(SkRect::MakeWH(40, 40), paint);
2745 paint.setShader(nullptr);
2746 canvas->translate(50, 0);
2747 canvas->drawRect(SkRect::MakeWH(40, 40), paint);
2748 }
2749 ##
2750
2751##
2752
Cary Clark08895c42018-02-01 09:37:32 -05002753#Subtopic Shader_Methods ##
Cary Clark8032b982017-07-28 11:04:54 -04002754# ------------------------------------------------------------------------------
Cary Clark08895c42018-02-01 09:37:32 -05002755#Subtopic Color_Filter_Methods
2756#Line # get and set Color_Filter ##
Cary Clark8032b982017-07-28 11:04:54 -04002757
2758Color_Filter alters the color used when drawing a shape.
2759Color_Filter may apply Blend_Mode, transform the color through a matrix, or composite multiple filters.
2760If Paint has no Color_Filter, the color is unaltered.
2761
2762The drawn transparency can be modified without altering Color_Filter, by changing Color_Alpha.
2763
2764#Example
2765#Height 128
2766void draw(SkCanvas* canvas) {
2767 SkPaint paint;
2768 paint.setColorFilter(SkColorMatrixFilter::MakeLightingFilter(0xFFFFFF, 0xFF0000));
2769 for (SkColor c : { SK_ColorBLACK, SK_ColorGREEN } ) {
2770 paint.setColor(c);
2771 canvas->drawRect(SkRect::MakeXYWH(10, 10, 50, 50), paint);
2772 paint.setAlpha(0x80);
2773 canvas->drawRect(SkRect::MakeXYWH(60, 60, 50, 50), paint);
2774 canvas->translate(100, 0);
2775 }
2776}
2777##
2778
2779#Method SkColorFilter* getColorFilter() const
2780
Cary Clarkab2621d2018-01-30 10:08:57 -05002781#In Color_Filter_Methods
2782#Line # returns Color_Filter, how colors are altered ##
Cary Clark8032b982017-07-28 11:04:54 -04002783 Returns Color_Filter if set, or nullptr.
2784 Does not alter Color_Filter Reference_Count.
2785
2786 #Return Color_Filter if previously set, nullptr otherwise ##
2787
2788 #Example
2789 void draw(SkCanvas* canvas) {
2790 SkPaint paint;
2791 SkDebugf("nullptr %c= color filter\n", paint.getColorFilter() ? '!' : '=');
2792 paint.setColorFilter(SkColorFilter::MakeModeFilter(SK_ColorLTGRAY, SkBlendMode::kSrcIn));
2793 SkDebugf("nullptr %c= color filter\n", paint.getColorFilter() ? '!' : '=');
2794 }
2795
2796 #StdOut
2797 nullptr == color filter
2798 nullptr != color filter
2799 ##
2800 ##
2801##
2802
2803#Method sk_sp<SkColorFilter> refColorFilter() const
2804
Cary Clarkab2621d2018-01-30 10:08:57 -05002805#In Color_Filter_Methods
2806#Line # references Color_Filter, how colors are altered ##
Cary Clark8032b982017-07-28 11:04:54 -04002807 Returns Color_Filter if set, or nullptr.
2808 Increases Color_Filter Reference_Count by one.
2809
2810 #Return Color_Filter if set, or nullptr ##
2811
2812 #Example
2813 void draw(SkCanvas* canvas) {
2814 SkPaint paint1, paint2;
2815 paint1.setColorFilter(SkColorFilter::MakeModeFilter(0xFFFF0000, SkBlendMode::kSrcATop));
2816 SkDebugf("color filter unique: %s\n", paint1.getColorFilter()->unique() ? "true" : "false");
2817 paint2.setColorFilter(paint1.refColorFilter());
2818 SkDebugf("color filter unique: %s\n", paint1.getColorFilter()->unique() ? "true" : "false");
2819 }
2820
2821 #StdOut
2822 color filter unique: true
2823 color filter unique: false
2824 ##
2825 ##
2826##
2827
2828#Method void setColorFilter(sk_sp<SkColorFilter> colorFilter)
2829
Cary Clarkab2621d2018-01-30 10:08:57 -05002830#In Color_Filter_Methods
2831#Line # sets Color_Filter, alters color ##
Cary Clark6fc50412017-09-21 12:31:06 -04002832Sets Color_Filter to filter, decreasing Reference_Count of the previous
2833Color_Filter. Pass nullptr to clear Color_Filter.
2834
2835Increments filter Reference_Count by one.
Cary Clark8032b982017-07-28 11:04:54 -04002836
2837 #Param colorFilter Color_Filter to apply to subsequent draw ##
2838
2839 #Example
2840 #Height 64
2841 void draw(SkCanvas* canvas) {
2842 SkPaint paint;
2843 paint.setColorFilter(SkColorFilter::MakeModeFilter(SK_ColorLTGRAY, SkBlendMode::kSrcIn));
2844 canvas->drawRect(SkRect::MakeWH(50, 50), paint);
2845 paint.setColorFilter(nullptr);
2846 canvas->translate(70, 0);
2847 canvas->drawRect(SkRect::MakeWH(50, 50), paint);
2848 }
2849 ##
2850
2851##
2852
Cary Clark08895c42018-02-01 09:37:32 -05002853#Subtopic Color_Filter_Methods ##
Cary Clark8032b982017-07-28 11:04:54 -04002854# ------------------------------------------------------------------------------
Cary Clark08895c42018-02-01 09:37:32 -05002855#Subtopic Blend_Mode_Methods
2856#Line # get and set Blend_Mode ##
Cary Clark8032b982017-07-28 11:04:54 -04002857
2858Blend_Mode describes how Color combines with the destination color.
2859The default setting, SkBlendMode::kSrcOver, draws the source color
2860over the destination color.
2861
2862#Example
2863void draw(SkCanvas* canvas) {
2864 SkPaint normal, blender;
2865 normal.setColor(0xFF58a889);
2866 blender.setColor(0xFF8958a8);
2867 canvas->clear(0);
2868 for (SkBlendMode m : { SkBlendMode::kSrcOver, SkBlendMode::kSrcIn, SkBlendMode::kSrcOut } ) {
2869 normal.setBlendMode(SkBlendMode::kSrcOver);
2870 canvas->drawOval(SkRect::MakeXYWH(30, 30, 30, 80), normal);
2871 blender.setBlendMode(m);
2872 canvas->drawOval(SkRect::MakeXYWH(10, 50, 80, 30), blender);
2873 canvas->translate(70, 70);
2874 }
2875}
2876##
2877
2878#SeeAlso Blend_Mode
2879
2880#Method SkBlendMode getBlendMode() const
2881
Cary Clarkab2621d2018-01-30 10:08:57 -05002882#In Blend_Mode_Methods
2883#Line # returns Blend_Mode, how colors combine with Device ##
Cary Clark8032b982017-07-28 11:04:54 -04002884 Returns Blend_Mode.
Cary Clark579985c2017-07-31 11:48:27 -04002885 By default, returns SkBlendMode::kSrcOver.
Cary Clark8032b982017-07-28 11:04:54 -04002886
2887 #Return mode used to combine source color with destination color ##
2888
2889 #Example
2890 void draw(SkCanvas* canvas) {
2891 SkPaint paint;
2892 SkDebugf("kSrcOver %c= getBlendMode\n",
2893 SkBlendMode::kSrcOver == paint.getBlendMode() ? '=' : '!');
2894 paint.setBlendMode(SkBlendMode::kSrc);
2895 SkDebugf("kSrcOver %c= getBlendMode\n",
2896 SkBlendMode::kSrcOver == paint.getBlendMode() ? '=' : '!');
2897 }
2898
2899 #StdOut
2900 kSrcOver == getBlendMode
2901 kSrcOver != getBlendMode
2902 ##
2903 ##
2904
2905##
2906
2907#Method bool isSrcOver() const
2908
Cary Clarkab2621d2018-01-30 10:08:57 -05002909#In Blend_Mode_Methods
2910#Line # returns true if Blend_Mode is SkBlendMode::kSrcOver ##
Cary Clark8032b982017-07-28 11:04:54 -04002911 Returns true if Blend_Mode is SkBlendMode::kSrcOver, the default.
2912
2913 #Return true if Blend_Mode is SkBlendMode::kSrcOver ##
2914
2915 #Example
2916 void draw(SkCanvas* canvas) {
2917 SkPaint paint;
2918 SkDebugf("isSrcOver %c= true\n", paint.isSrcOver() ? '=' : '!');
2919 paint.setBlendMode(SkBlendMode::kSrc);
2920 SkDebugf("isSrcOver %c= true\n", paint.isSrcOver() ? '=' : '!');
2921 }
2922
2923 #StdOut
2924 isSrcOver == true
2925 isSrcOver != true
2926 ##
2927 ##
2928
2929##
2930
2931#Method void setBlendMode(SkBlendMode mode)
2932
Cary Clarkab2621d2018-01-30 10:08:57 -05002933#In Blend_Mode_Methods
2934#Line # sets Blend_Mode, how colors combine with destination ##
Cary Clark8032b982017-07-28 11:04:54 -04002935 Sets Blend_Mode to mode.
2936 Does not check for valid input.
2937
2938 #Param mode SkBlendMode used to combine source color and destination ##
2939
2940 #Example
2941 void draw(SkCanvas* canvas) {
2942 SkPaint paint;
2943 SkDebugf("isSrcOver %c= true\n", paint.isSrcOver() ? '=' : '!');
2944 paint.setBlendMode(SkBlendMode::kSrc);
2945 SkDebugf("isSrcOver %c= true\n", paint.isSrcOver() ? '=' : '!');
2946 }
2947
2948 #StdOut
2949 isSrcOver == true
2950 isSrcOver != true
2951 ##
2952 ##
2953
2954##
2955
Cary Clark08895c42018-02-01 09:37:32 -05002956#Subtopic Blend_Mode_Methods ##
Cary Clark8032b982017-07-28 11:04:54 -04002957# ------------------------------------------------------------------------------
Cary Clark08895c42018-02-01 09:37:32 -05002958#Subtopic Path_Effect_Methods
2959#Line # get and set Path_Effect ##
Cary Clark8032b982017-07-28 11:04:54 -04002960
2961Path_Effect modifies the path geometry before drawing it.
2962Path_Effect may implement dashing, custom fill effects and custom stroke effects.
2963If Paint has no Path_Effect, the path geometry is unaltered when filled or stroked.
2964
2965#Example
2966#Height 160
2967 void draw(SkCanvas* canvas) {
2968 SkPaint paint;
2969 paint.setStyle(SkPaint::kStroke_Style);
2970 paint.setStrokeWidth(16);
2971 SkScalar intervals[] = {30, 10};
2972 paint.setPathEffect(SkDashPathEffect::Make(intervals, SK_ARRAY_COUNT(intervals), 1));
2973 canvas->drawRoundRect({20, 20, 120, 120}, 20, 20, paint);
2974 }
2975##
2976
2977#SeeAlso Path_Effect
2978
2979#Method SkPathEffect* getPathEffect() const
2980
Cary Clarkab2621d2018-01-30 10:08:57 -05002981#In Path_Effect_Methods
2982#Line # returns Path_Effect, modifications to path geometry; dashing ##
Cary Clark8032b982017-07-28 11:04:54 -04002983 Returns Path_Effect if set, or nullptr.
2984 Does not alter Path_Effect Reference_Count.
2985
2986 #Return Path_Effect if previously set, nullptr otherwise ##
2987
2988 #Example
2989 void draw(SkCanvas* canvas) {
2990 SkPaint paint;
2991 SkDebugf("nullptr %c= path effect\n", paint.getPathEffect() ? '!' : '=');
2992 paint.setPathEffect(SkCornerPathEffect::Make(10));
2993 SkDebugf("nullptr %c= path effect\n", paint.getPathEffect() ? '!' : '=');
2994 }
2995
2996 #StdOut
2997 nullptr == path effect
2998 nullptr != path effect
2999 ##
3000 ##
3001
3002##
3003
3004
3005#Method sk_sp<SkPathEffect> refPathEffect() const
3006
Cary Clarkab2621d2018-01-30 10:08:57 -05003007#In Path_Effect_Methods
3008#Line # references Path_Effect, modifications to path geometry; dashing ##
Cary Clark8032b982017-07-28 11:04:54 -04003009 Returns Path_Effect if set, or nullptr.
3010 Increases Path_Effect Reference_Count by one.
3011
3012 #Return Path_Effect if previously set, nullptr otherwise ##
3013
3014 #Example
3015 void draw(SkCanvas* canvas) {
3016 SkPaint paint1, paint2;
Cary Clarka560c472017-11-27 10:44:06 -05003017 SkScalar intervals[] = {1, 2};
3018 paint1.setPathEffect(SkDashPathEffect::Make(intervals, SK_ARRAY_COUNT(intervals), 10));
Cary Clark8032b982017-07-28 11:04:54 -04003019 SkDebugf("path effect unique: %s\n", paint1.getPathEffect()->unique() ? "true" : "false");
3020 paint2.setPathEffect(paint1.refPathEffect());
3021 SkDebugf("path effect unique: %s\n", paint1.getPathEffect()->unique() ? "true" : "false");
3022 }
3023
3024 #StdOut
3025 path effect unique: true
3026 path effect unique: false
3027 ##
3028 ##
3029
3030##
3031
3032
3033#Method void setPathEffect(sk_sp<SkPathEffect> pathEffect)
3034
Cary Clarkab2621d2018-01-30 10:08:57 -05003035#In Path_Effect_Methods
3036#Line # sets Path_Effect, modifications to path geometry; dashing ##
Cary Clark6fc50412017-09-21 12:31:06 -04003037Sets Path_Effect to pathEffect, decreasing Reference_Count of the previous
3038Path_Effect. Pass nullptr to leave the path geometry unaltered.
3039
3040Increments pathEffect Reference_Count by one.
Cary Clark8032b982017-07-28 11:04:54 -04003041
3042 #Param pathEffect replace Path with a modification when drawn ##
3043
3044 #Example
3045 void draw(SkCanvas* canvas) {
3046 SkPaint paint;
3047 paint.setPathEffect(SkDiscretePathEffect::Make(3, 5));
3048 canvas->drawRect(SkRect::MakeXYWH(40, 40, 175, 175), paint);
3049 }
3050 ##
3051
3052##
3053
Cary Clark08895c42018-02-01 09:37:32 -05003054#Subtopic Path_Effect_Methods ##
Cary Clark8032b982017-07-28 11:04:54 -04003055# ------------------------------------------------------------------------------
Cary Clark08895c42018-02-01 09:37:32 -05003056#Subtopic Mask_Filter_Methods
3057#Line # get and set Mask_Filter ##
Cary Clark8032b982017-07-28 11:04:54 -04003058
Cary Clarkce101242017-09-01 15:51:02 -04003059Mask_Filter uses coverage of the shape drawn to create Mask_Alpha.
Mike Reed8ad91a92018-01-19 19:09:32 -05003060Mask_Filter takes a Mask, and returns a Mask.
Cary Clark6fc50412017-09-21 12:31:06 -04003061
3062Mask_Filter may change the geometry and transparency of the shape, such as
3063creating a blur effect. Set Mask_Filter to nullptr to prevent Mask_Filter from
3064modifying the draw.
Cary Clark8032b982017-07-28 11:04:54 -04003065
3066#Example
3067 void draw(SkCanvas* canvas) {
3068 SkPaint paint;
Cary Clark681287e2018-03-16 11:34:15 -04003069 paint.setMaskFilter(SkMaskFilter::MakeBlur(kSolid_SkBlurStyle, 3));
Cary Clark8032b982017-07-28 11:04:54 -04003070 canvas->drawRect(SkRect::MakeXYWH(40, 40, 175, 175), paint);
3071 }
3072##
3073
3074#Method SkMaskFilter* getMaskFilter() const
3075
Cary Clarkab2621d2018-01-30 10:08:57 -05003076#In Mask_Filter_Methods
3077#Line # returns Mask_Filter, alterations to Mask_Alpha ##
Cary Clark8032b982017-07-28 11:04:54 -04003078 Returns Mask_Filter if set, or nullptr.
3079 Does not alter Mask_Filter Reference_Count.
3080
3081 #Return Mask_Filter if previously set, nullptr otherwise ##
3082
3083 #Example
3084 void draw(SkCanvas* canvas) {
3085 SkPaint paint;
3086 SkDebugf("nullptr %c= mask filter\n", paint.getMaskFilter() ? '!' : '=');
Cary Clark681287e2018-03-16 11:34:15 -04003087 paint.setMaskFilter(SkMaskFilter::MakeBlur(kOuter_SkBlurStyle, 3));
Cary Clark8032b982017-07-28 11:04:54 -04003088 SkDebugf("nullptr %c= mask filter\n", paint.getMaskFilter() ? '!' : '=');
3089 }
3090
3091 #StdOut
3092 nullptr == mask filter
3093 nullptr != mask filter
3094 ##
3095 ##
3096
3097##
3098
3099#Method sk_sp<SkMaskFilter> refMaskFilter() const
3100
Cary Clarkab2621d2018-01-30 10:08:57 -05003101#In Mask_Filter_Methods
3102#Line # references Mask_Filter, alterations to Mask_Alpha ##
Cary Clark8032b982017-07-28 11:04:54 -04003103 Returns Mask_Filter if set, or nullptr.
Cary Clark6fc50412017-09-21 12:31:06 -04003104
Cary Clark8032b982017-07-28 11:04:54 -04003105 Increases Mask_Filter Reference_Count by one.
3106
3107 #Return Mask_Filter if previously set, nullptr otherwise ##
3108
3109 #Example
3110 void draw(SkCanvas* canvas) {
3111 SkPaint paint1, paint2;
Cary Clark681287e2018-03-16 11:34:15 -04003112 paint1.setMaskFilter(SkMaskFilter::MakeBlur(kNormal_SkBlurStyle, 1));
Cary Clark8032b982017-07-28 11:04:54 -04003113 SkDebugf("mask filter unique: %s\n", paint1.getMaskFilter()->unique() ? "true" : "false");
3114 paint2.setMaskFilter(paint1.refMaskFilter());
3115 SkDebugf("mask filter unique: %s\n", paint1.getMaskFilter()->unique() ? "true" : "false");
3116 }
3117
3118 #StdOut
3119 mask filter unique: true
3120 mask filter unique: false
3121 ##
3122 ##
3123
3124##
3125
3126#Method void setMaskFilter(sk_sp<SkMaskFilter> maskFilter)
3127
Cary Clarkab2621d2018-01-30 10:08:57 -05003128#In Mask_Filter_Methods
3129#Line # sets Mask_Filter, alterations to Mask_Alpha ##
Cary Clark6fc50412017-09-21 12:31:06 -04003130Sets Mask_Filter to maskFilter, decreasing Reference_Count of the previous
3131Mask_Filter. Pass nullptr to clear Mask_Filter and leave Mask_Filter effect on
3132Mask_Alpha unaltered.
3133
Cary Clark6fc50412017-09-21 12:31:06 -04003134Increments maskFilter Reference_Count by one.
Cary Clark8032b982017-07-28 11:04:54 -04003135
3136 #Param maskFilter modifies clipping mask generated from drawn geometry ##
3137
3138 #Example
3139 void draw(SkCanvas* canvas) {
3140 SkPaint paint;
3141 paint.setStyle(SkPaint::kStroke_Style);
3142 paint.setStrokeWidth(10);
Cary Clark681287e2018-03-16 11:34:15 -04003143 paint.setMaskFilter(SkMaskFilter::MakeBlur(kNormal_SkBlurStyle, 10));
Cary Clark8032b982017-07-28 11:04:54 -04003144 canvas->drawRect(SkRect::MakeXYWH(40, 40, 175, 175), paint);
3145 }
3146 ##
3147
3148##
3149
Cary Clark08895c42018-02-01 09:37:32 -05003150#Subtopic Mask_Filter_Methods ##
Cary Clark8032b982017-07-28 11:04:54 -04003151# ------------------------------------------------------------------------------
Cary Clark08895c42018-02-01 09:37:32 -05003152#Subtopic Typeface_Methods
3153#Line # get and set Typeface ##
Cary Clark8032b982017-07-28 11:04:54 -04003154
3155Typeface identifies the font used when drawing and measuring text.
3156Typeface may be specified by name, from a file, or from a data stream.
3157The default Typeface defers to the platform-specific default font
3158implementation.
3159
3160#Example
3161#Height 100
3162 void draw(SkCanvas* canvas) {
3163 SkPaint paint;
Ben Wagner700ff172017-11-08 15:37:22 -05003164 paint.setTypeface(SkTypeface::MakeFromName(nullptr, SkFontStyle()));
Cary Clark8032b982017-07-28 11:04:54 -04003165 paint.setAntiAlias(true);
3166 paint.setTextSize(36);
3167 canvas->drawString("A Big Hello!", 10, 40, paint);
3168 paint.setTypeface(nullptr);
3169 paint.setFakeBoldText(true);
3170 canvas->drawString("A Big Hello!", 10, 80, paint);
3171 }
3172##
3173
3174#Method SkTypeface* getTypeface() const
3175
Cary Clarkab2621d2018-01-30 10:08:57 -05003176#In Typeface_Methods
3177#Line # returns Typeface, font description ##
Cary Clark8032b982017-07-28 11:04:54 -04003178 Returns Typeface if set, or nullptr.
Cary Clark6fc50412017-09-21 12:31:06 -04003179 Increments Typeface Reference_Count by one.
Cary Clark8032b982017-07-28 11:04:54 -04003180
3181 #Return Typeface if previously set, nullptr otherwise ##
3182
3183 #Example
3184 void draw(SkCanvas* canvas) {
3185 SkPaint paint;
3186 SkDebugf("nullptr %c= typeface\n", paint.getTypeface() ? '!' : '=');
Cary Clark71961fb2018-01-05 14:21:59 -05003187 paint.setTypeface(SkTypeface::MakeFromName("monospace", SkFontStyle()));
Cary Clark8032b982017-07-28 11:04:54 -04003188 SkDebugf("nullptr %c= typeface\n", paint.getTypeface() ? '!' : '=');
3189 }
3190
3191 #StdOut
3192 nullptr == typeface
3193 nullptr != typeface
3194 ##
3195 ##
3196
3197##
3198
3199#Method sk_sp<SkTypeface> refTypeface() const
3200
Cary Clarkab2621d2018-01-30 10:08:57 -05003201#In Typeface_Methods
3202#Line # references Typeface, font description ##
Cary Clark8032b982017-07-28 11:04:54 -04003203 Increases Typeface Reference_Count by one.
3204
3205 #Return Typeface if previously set, nullptr otherwise ##
3206
3207 #Example
3208 void draw(SkCanvas* canvas) {
3209 SkPaint paint1, paint2;
Cary Clark71961fb2018-01-05 14:21:59 -05003210 paint1.setTypeface(SkTypeface::MakeFromName("monospace",
Cary Clark8032b982017-07-28 11:04:54 -04003211 SkFontStyle(SkFontStyle::kNormal_Weight, SkFontStyle::kNormal_Width,
3212 SkFontStyle::kItalic_Slant)));
3213 SkDebugf("typeface1 %c= typeface2\n",
3214 paint1.getTypeface() == paint2.getTypeface() ? '=' : '!');
3215 paint2.setTypeface(paint1.refTypeface());
3216 SkDebugf("typeface1 %c= typeface2\n",
3217 paint1.getTypeface() == paint2.getTypeface() ? '=' : '!');
3218 }
3219
3220 #StdOut
3221 typeface1 != typeface2
3222 typeface1 == typeface2
3223 ##
3224 ##
3225
3226##
3227
3228#Method void setTypeface(sk_sp<SkTypeface> typeface)
3229
Cary Clarkab2621d2018-01-30 10:08:57 -05003230#In Typeface_Methods
3231#Line # sets Typeface, font description ##
Cary Clark6fc50412017-09-21 12:31:06 -04003232Sets Typeface to typeface, decreasing Reference_Count of the previous Typeface.
3233Pass nullptr to clear Typeface and use the default typeface. Increments
3234typeface Reference_Count by one.
Cary Clark8032b982017-07-28 11:04:54 -04003235
3236 #Param typeface font and style used to draw text ##
3237
3238 #Example
3239 #Height 64
3240 void draw(SkCanvas* canvas) {
3241 SkPaint paint;
Cary Clark71961fb2018-01-05 14:21:59 -05003242 paint.setTypeface(SkTypeface::MakeFromName("monospace", SkFontStyle()));
3243 canvas->drawString("hamburgerfons", 10, 30, paint);
Cary Clark8032b982017-07-28 11:04:54 -04003244 paint.setTypeface(nullptr);
Cary Clark71961fb2018-01-05 14:21:59 -05003245 canvas->drawString("hamburgerfons", 10, 50, paint);
Cary Clark8032b982017-07-28 11:04:54 -04003246 }
3247 ##
3248
3249##
3250
Cary Clark08895c42018-02-01 09:37:32 -05003251#Subtopic Typeface_Methods ##
Cary Clark8032b982017-07-28 11:04:54 -04003252# ------------------------------------------------------------------------------
Cary Clark08895c42018-02-01 09:37:32 -05003253#Subtopic Image_Filter_Methods
3254#Line # get and set Image_Filter ##
Cary Clark8032b982017-07-28 11:04:54 -04003255
3256Image_Filter operates on the pixel representation of the shape, as modified by Paint
3257with Blend_Mode set to SkBlendMode::kSrcOver. Image_Filter creates a new bitmap,
3258which is drawn to the device using the set Blend_Mode.
Cary Clark6fc50412017-09-21 12:31:06 -04003259
Cary Clark8032b982017-07-28 11:04:54 -04003260Image_Filter is higher level than Mask_Filter; for instance, an Image_Filter
Cary Clarkce101242017-09-01 15:51:02 -04003261can operate on all channels of Color, while Mask_Filter generates Alpha only.
Cary Clark8032b982017-07-28 11:04:54 -04003262Image_Filter operates independently of and can be used in combination with
Mike Reed8ad91a92018-01-19 19:09:32 -05003263Mask_Filter.
Cary Clark8032b982017-07-28 11:04:54 -04003264
3265#Example
3266 #ToDo explain why the two draws are so different ##
3267 void draw(SkCanvas* canvas) {
3268 SkPaint paint;
3269 paint.setStyle(SkPaint::kStroke_Style);
3270 paint.setStrokeWidth(2);
3271 SkRegion region;
3272 region.op( 10, 10, 50, 50, SkRegion::kUnion_Op);
3273 region.op( 10, 50, 90, 90, SkRegion::kUnion_Op);
Cary Clarka560c472017-11-27 10:44:06 -05003274 paint.setImageFilter(SkBlurImageFilter::Make(5.0f, 5.0f, nullptr));
Cary Clark8032b982017-07-28 11:04:54 -04003275 canvas->drawRegion(region, paint);
3276 paint.setImageFilter(nullptr);
Cary Clarka7b84c52018-03-18 11:46:54 -04003277 paint.setMaskFilter(SkMaskFilter::MakeBlur(kNormal_SkBlurStyle, 5));
Cary Clark8032b982017-07-28 11:04:54 -04003278 canvas->translate(100, 100);
3279 canvas->drawRegion(region, paint);
3280 }
3281##
3282
3283#Method SkImageFilter* getImageFilter() const
3284
Cary Clarkab2621d2018-01-30 10:08:57 -05003285#In Image_Filter_Methods
3286#Line # returns Image_Filter, alter pixels; blur ##
Cary Clark8032b982017-07-28 11:04:54 -04003287 Returns Image_Filter if set, or nullptr.
3288 Does not alter Image_Filter Reference_Count.
3289
3290 #Return Image_Filter if previously set, nullptr otherwise ##
3291
3292 #Example
3293 void draw(SkCanvas* canvas) {
3294 SkPaint paint;
3295 SkDebugf("nullptr %c= image filter\n", paint.getImageFilter() ? '!' : '=');
Cary Clarka560c472017-11-27 10:44:06 -05003296 paint.setImageFilter(SkBlurImageFilter::Make(kOuter_SkBlurStyle, 3, nullptr, nullptr));
Cary Clark8032b982017-07-28 11:04:54 -04003297 SkDebugf("nullptr %c= image filter\n", paint.getImageFilter() ? '!' : '=');
3298 }
3299
3300 #StdOut
3301 nullptr == image filter
3302 nullptr != image filter
3303 ##
3304 ##
3305
3306##
3307
3308#Method sk_sp<SkImageFilter> refImageFilter() const
3309
Cary Clarkab2621d2018-01-30 10:08:57 -05003310#In Image_Filter_Methods
3311#Line # references Image_Filter, alter pixels; blur ##
Cary Clark8032b982017-07-28 11:04:54 -04003312 Returns Image_Filter if set, or nullptr.
3313 Increases Image_Filter Reference_Count by one.
3314
3315 #Return Image_Filter if previously set, nullptr otherwise ##
3316
3317 #Example
3318 void draw(SkCanvas* canvas) {
3319 SkPaint paint1, paint2;
3320 paint1.setImageFilter(SkOffsetImageFilter::Make(25, 25, nullptr));
3321 SkDebugf("image filter unique: %s\n", paint1.getImageFilter()->unique() ? "true" : "false");
3322 paint2.setImageFilter(paint1.refImageFilter());
3323 SkDebugf("image filter unique: %s\n", paint1.getImageFilter()->unique() ? "true" : "false");
3324 }
3325
3326 #StdOut
3327 image filter unique: true
3328 image filter unique: false
3329 ##
3330 ##
3331
3332##
3333
3334#Method void setImageFilter(sk_sp<SkImageFilter> imageFilter)
3335
Cary Clarkab2621d2018-01-30 10:08:57 -05003336#In Image_Filter_Methods
3337#Line # sets Image_Filter, alter pixels; blur ##
Cary Clark6fc50412017-09-21 12:31:06 -04003338Sets Image_Filter to imageFilter, decreasing Reference_Count of the previous
3339Image_Filter. Pass nullptr to clear Image_Filter, and remove Image_Filter effect
3340on drawing.
3341
Cary Clark6fc50412017-09-21 12:31:06 -04003342Increments imageFilter Reference_Count by one.
Cary Clark8032b982017-07-28 11:04:54 -04003343
3344 #Param imageFilter how Image is sampled when transformed ##
3345
3346 #Example
3347 #Height 160
3348 void draw(SkCanvas* canvas) {
3349 SkBitmap bitmap;
3350 bitmap.allocN32Pixels(100, 100);
3351 SkCanvas offscreen(bitmap);
3352 SkPaint paint;
3353 paint.setAntiAlias(true);
3354 paint.setColor(SK_ColorWHITE);
3355 paint.setTextSize(96);
3356 offscreen.clear(0);
3357 offscreen.drawString("e", 20, 70, paint);
3358 paint.setImageFilter(
3359 SkLightingImageFilter::MakePointLitDiffuse(SkPoint3::Make(80, 100, 10),
3360 SK_ColorWHITE, 1, 2, nullptr, nullptr));
3361 canvas->drawBitmap(bitmap, 0, 0, &paint);
3362 }
3363 ##
3364
3365##
3366
Cary Clark08895c42018-02-01 09:37:32 -05003367#Subtopic Image_Filter_Methods ##
Cary Clark8032b982017-07-28 11:04:54 -04003368# ------------------------------------------------------------------------------
Cary Clark08895c42018-02-01 09:37:32 -05003369#Subtopic Draw_Looper_Methods
3370#Line # get and set Draw_Looper ##
Cary Clark8032b982017-07-28 11:04:54 -04003371
3372Draw_Looper sets a modifier that communicates state from one Draw_Layer
3373to another to construct the draw.
Cary Clark6fc50412017-09-21 12:31:06 -04003374
Cary Clark8032b982017-07-28 11:04:54 -04003375Draw_Looper draws one or more times, modifying the canvas and paint each time.
3376Draw_Looper may be used to draw multiple colors or create a colored shadow.
3377Set Draw_Looper to nullptr to prevent Draw_Looper from modifying the draw.
3378
3379#Example
3380#Height 128
3381 void draw(SkCanvas* canvas) {
3382 SkLayerDrawLooper::LayerInfo info;
3383 info.fPaintBits = (SkLayerDrawLooper::BitFlags) SkLayerDrawLooper::kColorFilter_Bit;
3384 info.fColorMode = SkBlendMode::kSrc;
3385 SkLayerDrawLooper::Builder looperBuilder;
3386 SkPaint* loopPaint = looperBuilder.addLayer(info);
3387 loopPaint->setColor(SK_ColorRED);
3388 info.fOffset.set(20, 20);
3389 loopPaint = looperBuilder.addLayer(info);
3390 loopPaint->setColor(SK_ColorBLUE);
3391 SkPaint paint;
3392 paint.setDrawLooper(looperBuilder.detach());
3393 canvas->drawCircle(50, 50, 50, paint);
3394 }
3395
3396##
3397
3398#Method SkDrawLooper* getDrawLooper() const
3399
Cary Clarkab2621d2018-01-30 10:08:57 -05003400#In Draw_Looper_Methods
3401#Line # returns Draw_Looper, multiple layers ##
Cary Clark8032b982017-07-28 11:04:54 -04003402 Returns Draw_Looper if set, or nullptr.
3403 Does not alter Draw_Looper Reference_Count.
3404
3405 #Return Draw_Looper if previously set, nullptr otherwise ##
3406
3407 #Example
3408 void draw(SkCanvas* canvas) {
3409 SkPaint paint;
3410 SkDebugf("nullptr %c= draw looper\n", paint.getDrawLooper() ? '!' : '=');
3411 SkLayerDrawLooper::Builder looperBuilder;
3412 paint.setDrawLooper(looperBuilder.detach());
3413 SkDebugf("nullptr %c= draw looper\n", paint.getDrawLooper() ? '!' : '=');
3414 }
3415
3416 #StdOut
3417 nullptr == draw looper
3418 nullptr != draw looper
3419 ##
3420 ##
3421
3422##
3423
3424#Method sk_sp<SkDrawLooper> refDrawLooper() const
3425
Cary Clarkab2621d2018-01-30 10:08:57 -05003426#In Draw_Looper_Methods
3427#Line # references Draw_Looper, multiple layers ##
Cary Clark8032b982017-07-28 11:04:54 -04003428 Returns Draw_Looper if set, or nullptr.
3429 Increases Draw_Looper Reference_Count by one.
3430
3431 #Return Draw_Looper if previously set, nullptr otherwise ##
3432
3433 #Example
3434 void draw(SkCanvas* canvas) {
3435 SkPaint paint1, paint2;
3436 SkLayerDrawLooper::Builder looperBuilder;
3437 paint1.setDrawLooper(looperBuilder.detach());
3438 SkDebugf("draw looper unique: %s\n", paint1.getDrawLooper()->unique() ? "true" : "false");
3439 paint2.setDrawLooper(paint1.refDrawLooper());
3440 SkDebugf("draw looper unique: %s\n", paint1.getDrawLooper()->unique() ? "true" : "false");
3441 }
3442
3443 #StdOut
3444 draw looper unique: true
3445 draw looper unique: false
3446 ##
3447 ##
3448
3449##
3450
3451#Method SkDrawLooper* getLooper() const
Cary Clark4855f782018-02-06 09:41:53 -05003452#Bug 6259
Cary Clark8032b982017-07-28 11:04:54 -04003453#Deprecated
Cary Clark8032b982017-07-28 11:04:54 -04003454##
3455
3456#Method void setDrawLooper(sk_sp<SkDrawLooper> drawLooper)
Cary Clarkab2621d2018-01-30 10:08:57 -05003457#In Draw_Looper_Methods
3458#Line # sets Draw_Looper, multiple layers ##
Cary Clark6fc50412017-09-21 12:31:06 -04003459Sets Draw_Looper to drawLooper, decreasing Reference_Count of the previous
3460drawLooper. Pass nullptr to clear Draw_Looper and leave Draw_Looper effect on
3461drawing unaltered.
3462
3463Increments drawLooper Reference_Count by one.
Cary Clark8032b982017-07-28 11:04:54 -04003464
Cary Clarka523d2d2017-08-30 08:58:10 -04003465 #Param drawLooper iterates through drawing one or more time, altering Paint ##
Cary Clark8032b982017-07-28 11:04:54 -04003466
3467 #Example
3468 #Height 128
3469 void draw(SkCanvas* canvas) {
3470 SkPaint paint;
3471 paint.setDrawLooper(SkBlurDrawLooper::Make(0x7FFF0000, 4, -5, -10));
3472 paint.setStyle(SkPaint::kStroke_Style);
3473 paint.setStrokeWidth(10);
3474 paint.setAntiAlias(true);
3475 paint.setColor(0x7f0000ff);
3476 canvas->drawCircle(70, 70, 50, paint);
3477 }
3478 ##
3479
3480##
3481
3482#Method void setLooper(sk_sp<SkDrawLooper> drawLooper)
Cary Clark4855f782018-02-06 09:41:53 -05003483#Bug 6259
Cary Clark8032b982017-07-28 11:04:54 -04003484#Deprecated
Cary Clark8032b982017-07-28 11:04:54 -04003485##
3486
Cary Clark08895c42018-02-01 09:37:32 -05003487#Subtopic Draw_Looper_Methods ##
Cary Clark4855f782018-02-06 09:41:53 -05003488
Cary Clark8032b982017-07-28 11:04:54 -04003489# ------------------------------------------------------------------------------
Cary Clark08895c42018-02-01 09:37:32 -05003490#Subtopic Text_Align
3491#Line # text placement relative to position ##
Cary Clark8032b982017-07-28 11:04:54 -04003492
3493#Enum Align
Cary Clark08895c42018-02-01 09:37:32 -05003494#Line # glyph locations relative to text position ##
Cary Clark8032b982017-07-28 11:04:54 -04003495#Code
3496 enum Align {
3497 kLeft_Align,
3498 kCenter_Align,
3499 kRight_Align,
3500 };
3501##
3502
3503Align adjusts the text relative to the text position.
Cary Clarkce101242017-09-01 15:51:02 -04003504Align affects Glyphs drawn with: SkCanvas::drawText, SkCanvas::drawPosText,
Cary Clark8032b982017-07-28 11:04:54 -04003505SkCanvas::drawPosTextH, SkCanvas::drawTextOnPath,
3506SkCanvas::drawTextOnPathHV, SkCanvas::drawTextRSXform, SkCanvas::drawTextBlob,
3507and SkCanvas::drawString;
Cary Clarkce101242017-09-01 15:51:02 -04003508as well as calls that place text Glyphs like getTextWidths and getTextPath.
Cary Clark8032b982017-07-28 11:04:54 -04003509
3510The text position is set by the font for both horizontal and vertical text.
3511Typically, for horizontal text, the position is to the left side of the glyph on the
3512base line; and for vertical text, the position is the horizontal center of the glyph
3513at the caps height.
3514
3515Align adjusts the glyph position to center it or move it to abut the position
3516using the metrics returned by the font.
3517
3518Align defaults to kLeft_Align.
3519
3520#Const kLeft_Align 0
3521 Leaves the glyph at the position computed by the font offset by the text position.
3522##
3523
3524#Const kCenter_Align 1
3525 Moves the glyph half its width if Flags has kVerticalText_Flag clear, and
3526 half its height if Flags has kVerticalText_Flag set.
3527##
3528
3529#Const kRight_Align 2
3530 Moves the glyph by its width if Flags has kVerticalText_Flag clear,
3531 and by its height if Flags has kVerticalText_Flag set.
3532##
3533
3534#Enum ##
3535
3536#Enum
Cary Clark08895c42018-02-01 09:37:32 -05003537#Line # number of Text_Align values ##
Cary Clark8032b982017-07-28 11:04:54 -04003538
3539#Code
3540 enum {
Cary Clarkbad5ad72017-08-03 17:14:08 -04003541 kAlignCount = 3,
Cary Clark8032b982017-07-28 11:04:54 -04003542 };
3543##
3544
3545#Const kAlignCount 3
3546 The number of different Text_Align values defined.
3547##
3548
3549#Enum ##
3550
3551#Example
3552 #Height 160
3553 #Description
3554 Each position separately moves the glyph in drawPosText.
3555 ##
3556 void draw(SkCanvas* canvas) {
3557 SkPaint paint;
3558 paint.setTextSize(40);
3559 SkPoint position[] = {{100, 50}, {150, 40}};
3560 for (SkPaint::Align a : { SkPaint::kLeft_Align,
3561 SkPaint::kCenter_Align,
3562 SkPaint::kRight_Align}) {
3563 paint.setTextAlign(a);
3564 canvas->drawPosText("Aa", 2, position, paint);
3565 canvas->translate(0, 50);
3566 }
3567 }
3568##
3569
3570#Example
3571 #Height 160
3572 #Description
3573 Vertical_Text treats kLeft_Align as top align, and kRight_Align as bottom align.
3574 ##
3575 void draw(SkCanvas* canvas) {
3576 SkPaint paint;
3577 paint.setTextSize(40);
3578 paint.setVerticalText(true);
3579 for (SkPaint::Align a : { SkPaint::kLeft_Align,
3580 SkPaint::kCenter_Align,
3581 SkPaint::kRight_Align }) {
3582 paint.setTextAlign(a);
3583 canvas->drawString("Aa", 50, 80, paint);
3584 canvas->translate(50, 0);
3585 }
3586 }
3587##
3588
3589#Method Align getTextAlign() const
3590
Cary Clarkab2621d2018-01-30 10:08:57 -05003591#In Text_Align
3592#Line # returns Align: left, center, or right ##
Cary Clark8032b982017-07-28 11:04:54 -04003593 Returns Text_Align.
3594 Returns kLeft_Align if Text_Align has not been set.
3595
3596 #Return text placement relative to position ##
3597
3598 #Example
3599 SkPaint paint;
3600 SkDebugf("kLeft_Align %c= default\n", SkPaint::kLeft_Align == paint.getTextAlign() ? '=' : '!');
3601
3602 #StdOut
3603 kLeft_Align == default
3604 ##
3605 ##
3606##
3607
3608#Method void setTextAlign(Align align)
3609
Cary Clarkab2621d2018-01-30 10:08:57 -05003610#In Text_Align
3611#Line # sets Align: left, center, or right ##
Cary Clark8032b982017-07-28 11:04:54 -04003612 Sets Text_Align to align.
3613 Has no effect if align is an invalid value.
3614
3615 #Param align text placement relative to position ##
3616
3617 #Example
3618 #Height 160
3619 #Description
3620 Text is left-aligned by default, and then set to center. Setting the
3621 alignment out of range has no effect.
3622 ##
3623 void draw(SkCanvas* canvas) {
3624 SkPaint paint;
3625 paint.setTextSize(40);
3626 canvas->drawString("Aa", 100, 50, paint);
3627 paint.setTextAlign(SkPaint::kCenter_Align);
3628 canvas->drawString("Aa", 100, 100, paint);
3629 paint.setTextAlign((SkPaint::Align) SkPaint::kAlignCount);
3630 canvas->drawString("Aa", 100, 150, paint);
3631 }
3632 ##
3633
3634##
3635
Cary Clark08895c42018-02-01 09:37:32 -05003636#Subtopic Text_Align ##
Cary Clark8032b982017-07-28 11:04:54 -04003637# ------------------------------------------------------------------------------
Cary Clark08895c42018-02-01 09:37:32 -05003638#Subtopic Text_Size
3639#Line # overall height in points ##
Cary Clark8032b982017-07-28 11:04:54 -04003640
3641Text_Size adjusts the overall text size in points.
3642Text_Size can be set to any positive value or zero.
3643Text_Size defaults to 12.
3644Set SkPaintDefaults_TextSize at compile time to change the default setting.
3645
3646#Example
3647#Height 135
3648 void draw(SkCanvas* canvas) {
3649 SkPaint paint;
3650 canvas->drawString("12 point", 10, 20, paint);
3651 paint.setTextSize(24);
3652 canvas->drawString("24 point", 10, 60, paint);
3653 paint.setTextSize(48);
3654 canvas->drawString("48 point", 10, 120, paint);
3655 }
3656##
3657
3658#Method SkScalar getTextSize() const
3659
Cary Clarkab2621d2018-01-30 10:08:57 -05003660#In Text_Size
3661#Line # returns text size in points ##
Cary Clark8032b982017-07-28 11:04:54 -04003662 Returns Text_Size in points.
3663
3664 #Return typographic height of text ##
3665
3666 #Example
3667 SkPaint paint;
3668 SkDebugf("12 %c= default text size\n", 12 == paint.getTextSize() ? '=' : '!');
3669 ##
3670
3671##
3672
3673#Method void setTextSize(SkScalar textSize)
3674
Cary Clarkab2621d2018-01-30 10:08:57 -05003675#In Text_Size
3676#Line # sets text size in points ##
Cary Clark8032b982017-07-28 11:04:54 -04003677 Sets Text_Size in points.
3678 Has no effect if textSize is not greater than or equal to zero.
3679
3680 #Param textSize typographic height of text ##
3681
3682 #Example
3683 SkPaint paint;
3684 SkDebugf("12 %c= text size\n", 12 == paint.getTextSize() ? '=' : '!');
3685 paint.setTextSize(-20);
3686 SkDebugf("12 %c= text size\n", 12 == paint.getTextSize() ? '=' : '!');
3687 ##
3688
3689##
3690
Cary Clark08895c42018-02-01 09:37:32 -05003691#Subtopic Text_Size ##
Cary Clark8032b982017-07-28 11:04:54 -04003692# ------------------------------------------------------------------------------
Cary Clark08895c42018-02-01 09:37:32 -05003693#Subtopic Text_Scale_X
3694#Line # text horizontal scale ##
Cary Clark8032b982017-07-28 11:04:54 -04003695
3696Text_Scale_X adjusts the text horizontal scale.
3697Text scaling approximates condensed and expanded type faces when the actual face
3698is not available.
3699Text_Scale_X can be set to any value.
3700Text_Scale_X defaults to 1.
3701
3702#Example
3703#Height 128
3704 void draw(SkCanvas* canvas) {
3705 SkPaint paint;
3706 paint.setAntiAlias(true);
3707 paint.setTextSize(24);
3708 paint.setTextScaleX(.8f);
3709 canvas->drawString("narrow", 10, 20, paint);
3710 paint.setTextScaleX(1);
3711 canvas->drawString("normal", 10, 60, paint);
3712 paint.setTextScaleX(1.2f);
3713 canvas->drawString("wide", 10, 100, paint);
3714 }
3715##
3716
3717#Method SkScalar getTextScaleX() const
3718
Cary Clarkab2621d2018-01-30 10:08:57 -05003719#In Text_Scale_X
3720#Line # returns the text horizontal scale; condensed text ##
Cary Clark8032b982017-07-28 11:04:54 -04003721 Returns Text_Scale_X.
3722 Default value is 1.
3723
3724 #Return text horizontal scale ##
3725
3726 #Example
3727 SkPaint paint;
3728 SkDebugf("1 %c= default text scale x\n", 1 == paint.getTextScaleX() ? '=' : '!');
3729 ##
3730
3731##
3732
3733
3734#Method void setTextScaleX(SkScalar scaleX)
3735
Cary Clarkab2621d2018-01-30 10:08:57 -05003736#In Text_Scale_X
3737#Line # sets the text horizontal scale; condensed text ##
Cary Clark8032b982017-07-28 11:04:54 -04003738 Sets Text_Scale_X.
3739 Default value is 1.
3740
3741 #Param scaleX text horizontal scale ##
3742
3743 #Example
3744 SkPaint paint;
3745 paint.setTextScaleX(0.f / 0.f);
3746 SkDebugf("text scale %s-a-number\n", SkScalarIsNaN(paint.getTextScaleX()) ? "not" : "is");
3747 ##
3748
3749##
3750
Cary Clark08895c42018-02-01 09:37:32 -05003751#Subtopic Text_Scale_X ##
Cary Clark8032b982017-07-28 11:04:54 -04003752
Cary Clark08895c42018-02-01 09:37:32 -05003753#Subtopic Text_Skew_X
3754#Line # text horizontal slant ##
Cary Clark8032b982017-07-28 11:04:54 -04003755
3756
3757Text_Skew_X adjusts the text horizontal slant.
3758Text skewing approximates italic and oblique type faces when the actual face
3759is not available.
3760Text_Skew_X can be set to any value.
3761Text_Skew_X defaults to 0.
3762
3763#Example
3764#Height 128
3765 void draw(SkCanvas* canvas) {
3766 SkPaint paint;
3767 paint.setAntiAlias(true);
3768 paint.setTextSize(24);
3769 paint.setTextSkewX(-.25f);
3770 canvas->drawString("right-leaning", 10, 100, paint);
3771 paint.setTextSkewX(0);
3772 canvas->drawString("normal", 10, 60, paint);
3773 paint.setTextSkewX(.25f);
3774 canvas->drawString("left-leaning", 10, 20, paint);
3775 }
3776##
3777
3778#Method SkScalar getTextSkewX() const
3779
Cary Clarkab2621d2018-01-30 10:08:57 -05003780#In Text_Skew_X
3781#Line # returns the text horizontal skew; oblique text ##
Cary Clark8032b982017-07-28 11:04:54 -04003782 Returns Text_Skew_X.
3783 Default value is zero.
3784
3785 #Return additional shear in x-axis relative to y-axis ##
3786
3787 #Example
3788 SkPaint paint;
3789 SkDebugf("0 %c= default text skew x\n", 0 == paint.getTextSkewX() ? '=' : '!');
3790 ##
3791
3792##
3793
3794#Method void setTextSkewX(SkScalar skewX)
3795
Cary Clarkab2621d2018-01-30 10:08:57 -05003796#In Text_Skew_X
3797#Line # sets the text horizontal skew; oblique text ##
Cary Clark8032b982017-07-28 11:04:54 -04003798 Sets Text_Skew_X.
3799 Default value is zero.
3800
3801 #Param skewX additional shear in x-axis relative to y-axis ##
3802
3803 #Example
3804 SkPaint paint;
3805 paint.setTextScaleX(1.f / 0.f);
3806 SkDebugf("text scale %s-finite\n", SkScalarIsFinite(paint.getTextScaleX()) ? "is" : "not");
3807 ##
3808
3809##
3810
Cary Clark08895c42018-02-01 09:37:32 -05003811#Subtopic Text_Skew_X ##
Cary Clark8032b982017-07-28 11:04:54 -04003812
3813# ------------------------------------------------------------------------------
Cary Clark08895c42018-02-01 09:37:32 -05003814#Subtopic Text_Encoding
3815#Line # text encoded as characters or Glyphs ##
Cary Clark8032b982017-07-28 11:04:54 -04003816
3817#Enum TextEncoding
Cary Clark08895c42018-02-01 09:37:32 -05003818#Line # character or glyph encoded size ##
Cary Clark8032b982017-07-28 11:04:54 -04003819
3820#Code
3821 enum TextEncoding {
3822 kUTF8_TextEncoding,
3823 kUTF16_TextEncoding,
3824 kUTF32_TextEncoding,
Cary Clarkbad5ad72017-08-03 17:14:08 -04003825 kGlyphID_TextEncoding,
Cary Clark8032b982017-07-28 11:04:54 -04003826 };
3827##
3828
Cary Clark6fc50412017-09-21 12:31:06 -04003829TextEncoding determines whether text specifies character codes and their encoded
Cary Clarkbc5697d2017-10-04 14:31:33 -04003830size, or glyph indices. Characters are encoded as specified by the
Cary Clark6fc50412017-09-21 12:31:06 -04003831#A Unicode standard # http://unicode.org/standard/standard.html ##
3832.
3833
Cary Clark8032b982017-07-28 11:04:54 -04003834Character codes encoded size are specified by UTF-8, UTF-16, or UTF-32.
Cary Clarkbc5697d2017-10-04 14:31:33 -04003835All character code formats are able to represent all of Unicode, differing only
Cary Clark8032b982017-07-28 11:04:54 -04003836in the total storage required.
3837
Cary Clark6fc50412017-09-21 12:31:06 -04003838#A UTF-8 (RFC 3629) # https://tools.ietf.org/html/rfc3629 ##
3839 encodes each character as one or more 8-bit bytes.
3840
3841#A UTF-16 (RFC 2781) # https://tools.ietf.org/html/rfc2781 ##
3842 encodes each character as one or two 16-bit words.
3843
3844#A UTF-32 # http://www.unicode.org/versions/Unicode5.0.0/ch03.pdf ##
3845 encodes each character as one 32-bit word.
Cary Clark8032b982017-07-28 11:04:54 -04003846
3847Font_Manager uses font data to convert character code points into glyph indices.
3848A glyph index is a 16-bit word.
3849
3850TextEncoding is set to kUTF8_TextEncoding by default.
3851
3852#Const kUTF8_TextEncoding 0
3853Uses bytes to represent UTF-8 or ASCII.
3854##
3855#Const kUTF16_TextEncoding 1
3856Uses two byte words to represent most of Unicode.
3857##
3858#Const kUTF32_TextEncoding 2
3859Uses four byte words to represent all of Unicode.
3860##
3861#Const kGlyphID_TextEncoding 3
3862Uses two byte words to represent glyph indices.
3863##
3864
3865#Enum ##
3866
3867#Example
3868#Height 128
3869#Description
Cary Clarkbc5697d2017-10-04 14:31:33 -04003870First line is encoded in UTF-8.
3871Second line is encoded in UTF-16.
3872Third line is encoded in UTF-32.
Cary Clark8032b982017-07-28 11:04:54 -04003873Fourth line has 16 bit glyph indices.
3874##
3875void draw(SkCanvas* canvas) {
3876 SkPaint paint;
3877 const char hello8[] = "Hello" "\xE2" "\x98" "\xBA";
3878 const uint16_t hello16[] = { 'H', 'e', 'l', 'l', 'o', 0x263A };
3879 const uint32_t hello32[] = { 'H', 'e', 'l', 'l', 'o', 0x263A };
3880 paint.setTextSize(24);
3881 canvas->drawText(hello8, sizeof(hello8) - 1, 10, 30, paint);
3882 paint.setTextEncoding(SkPaint::kUTF16_TextEncoding);
3883 canvas->drawText(hello16, sizeof(hello16), 10, 60, paint);
3884 paint.setTextEncoding(SkPaint::kUTF32_TextEncoding);
3885 canvas->drawText(hello32, sizeof(hello32), 10, 90, paint);
3886 uint16_t glyphs[SK_ARRAY_COUNT(hello32)];
3887 paint.textToGlyphs(hello32, sizeof(hello32), glyphs);
3888 paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
3889 canvas->drawText(glyphs, sizeof(glyphs), 10, 120, paint);
3890}
3891##
3892
3893#Method TextEncoding getTextEncoding() const
3894
Cary Clarkab2621d2018-01-30 10:08:57 -05003895#In Text_Encoding
3896#Line # returns character or glyph encoded size ##
Cary Clark8032b982017-07-28 11:04:54 -04003897 Returns Text_Encoding.
3898 Text_Encoding determines how character code points are mapped to font glyph indices.
3899
3900 #Return one of: kUTF8_TextEncoding, kUTF16_TextEncoding, kUTF32_TextEncoding, or
3901 kGlyphID_TextEncoding
3902 ##
3903
3904 #Example
3905 SkPaint paint;
3906 SkDebugf("kUTF8_TextEncoding %c= text encoding\n",
3907 SkPaint::kUTF8_TextEncoding == paint.getTextEncoding() ? '=' : '!');
3908 paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
3909 SkDebugf("kGlyphID_TextEncoding %c= text encoding\n",
3910 SkPaint::kGlyphID_TextEncoding == paint.getTextEncoding() ? '=' : '!');
3911
3912 #StdOut
3913 kUTF8_TextEncoding == text encoding
3914 kGlyphID_TextEncoding == text encoding
3915 ##
3916 ##
3917
3918##
3919
3920
3921#Method void setTextEncoding(TextEncoding encoding)
3922
Cary Clarkab2621d2018-01-30 10:08:57 -05003923#In Text_Encoding
3924#Line # sets character or glyph encoded size ##
Cary Clark8032b982017-07-28 11:04:54 -04003925 Sets Text_Encoding to encoding.
3926 Text_Encoding determines how character code points are mapped to font glyph indices.
3927 Invalid values for encoding are ignored.
3928
3929 #Param encoding one of: kUTF8_TextEncoding, kUTF16_TextEncoding, kUTF32_TextEncoding, or
Cary Clark579985c2017-07-31 11:48:27 -04003930 kGlyphID_TextEncoding
3931 #Param ##
Cary Clark8032b982017-07-28 11:04:54 -04003932
3933 #Example
3934 SkPaint paint;
3935 paint.setTextEncoding((SkPaint::TextEncoding) 4);
3936 SkDebugf("4 %c= text encoding\n", 4 == paint.getTextEncoding() ? '=' : '!');
3937
3938 #StdOut
3939 4 != text encoding
3940 ##
3941 ##
3942
3943##
3944
Cary Clark08895c42018-02-01 09:37:32 -05003945#Subtopic Text_Encoding ##
Cary Clark8032b982017-07-28 11:04:54 -04003946# ------------------------------------------------------------------------------
Cary Clark08895c42018-02-01 09:37:32 -05003947#Subtopic Font_Metrics
3948#Line # common glyph dimensions ##
Cary Clark8032b982017-07-28 11:04:54 -04003949
Cary Clarkce101242017-09-01 15:51:02 -04003950Font_Metrics describe dimensions common to the Glyphs in Typeface.
Cary Clark8032b982017-07-28 11:04:54 -04003951The dimensions are computed by Font_Manager from font data and do not take
3952Paint settings other than Text_Size into account.
3953
3954Font dimensions specify the anchor to the left of the glyph at baseline as the origin.
3955X-axis values to the left of the glyph are negative, and to the right of the left glyph edge
3956are positive.
3957Y-axis values above the baseline are negative, and below the baseline are positive.
Ben Wagnere5806492017-11-09 12:08:31 -05003958
Cary Clark8032b982017-07-28 11:04:54 -04003959#Example
3960#Width 512
3961void draw(SkCanvas* canvas) {
3962 SkPaint paint;
3963 paint.setAntiAlias(true);
3964 paint.setTextSize(120);
3965 SkPaint::FontMetrics fm;
3966 SkScalar lineHeight = paint.getFontMetrics(&fm);
3967 SkPoint pt = { 70, 180 };
3968 canvas->drawString("M", pt.fX, pt.fY, paint);
3969 canvas->drawLine(pt.fX, pt.fY, pt.fX, pt.fY + fm.fTop, paint);
3970 SkScalar ascent = pt.fY + fm.fAscent;
3971 canvas->drawLine(pt.fX - 25, ascent, pt.fX - 25, ascent + lineHeight, paint);
3972 canvas->drawLine(pt.fX - 50, pt.fY, pt.fX - 50, pt.fY + fm.fDescent, paint);
3973 canvas->drawLine(pt.fX + 100, pt.fY, pt.fX + 100, pt.fY + fm.fAscent, paint);
3974 canvas->drawLine(pt.fX + 125, pt.fY, pt.fX + 125, pt.fY - fm.fXHeight, paint);
3975 canvas->drawLine(pt.fX + 150, pt.fY, pt.fX + 150, pt.fY - fm.fCapHeight, paint);
3976 canvas->drawLine(pt.fX + 5, pt.fY, pt.fX + 5, pt.fY + fm.fBottom, paint);
3977 SkScalar xmin = pt.fX + fm.fXMin;
3978 canvas->drawLine(xmin, pt.fY + 60, xmin + fm.fMaxCharWidth, pt.fY + 60, paint);
3979 canvas->drawLine(xmin, pt.fY - 145, pt.fX, pt.fY - 145, paint);
3980 canvas->drawLine(pt.fX + fm.fXMax, pt.fY - 160, pt.fX, pt.fY - 160, paint);
3981 SkScalar upos = pt.fY + fm.fUnderlinePosition;
Ben Wagnere5806492017-11-09 12:08:31 -05003982 canvas->drawLine(pt.fX + 25, upos, pt.fX + 160, upos, paint);
3983 SkScalar ut = fm.fUnderlineThickness;
3984 canvas->drawLine(pt.fX + 130, upos + ut, pt.fX + 160, upos + ut, paint);
Cary Clark8032b982017-07-28 11:04:54 -04003985 paint.setTextSize(12);
3986 canvas->drawString("x-min", pt.fX - 50, pt.fY - 148, paint);
3987 canvas->drawString("x-max", pt.fX + 140, pt.fY - 150, paint);
3988 canvas->drawString("max char width", pt.fX + 120, pt.fY + 57, paint);
3989 canvas->drawString("underline position", pt.fX + 30, pt.fY + 22, paint);
3990 canvas->drawString("underline thickness", pt.fX + 162, pt.fY + 13, paint);
3991 canvas->rotate(-90);
3992 canvas->drawString("descent", -pt.fY - 30, pt.fX - 54, paint);
3993 canvas->drawString("line height", -pt.fY, pt.fX - 29, paint);
3994 canvas->drawString("top", -pt.fY + 30, pt.fX - 4, paint);
3995 canvas->drawString("ascent", -pt.fY, pt.fX + 110, paint);
3996 canvas->drawString("x-height", -pt.fY, pt.fX + 135, paint);
3997 canvas->drawString("cap-height", -pt.fY, pt.fX + 160, paint);
3998 canvas->drawString("bottom", -pt.fY - 50, pt.fX + 15, paint);
3999}
4000##
4001
4002#Struct FontMetrics
Cary Clark08895c42018-02-01 09:37:32 -05004003#Line # values computed by Font_Manager using Typeface ##
Cary Clark8032b982017-07-28 11:04:54 -04004004
4005#Code
4006 struct FontMetrics {
4007 enum FontMetricsFlags {
4008 kUnderlineThicknessIsValid_Flag = 1 << 0,
4009 kUnderlinePositionIsValid_Flag = 1 << 1,
4010 kStrikeoutThicknessIsValid_Flag = 1 << 2,
4011 kStrikeoutPositionIsValid_Flag = 1 << 3,
4012 };
4013
4014 uint32_t fFlags;
4015 SkScalar fTop;
4016 SkScalar fAscent;
4017 SkScalar fDescent;
4018 SkScalar fBottom;
4019 SkScalar fLeading;
4020 SkScalar fAvgCharWidth;
4021 SkScalar fMaxCharWidth;
4022 SkScalar fXMin;
4023 SkScalar fXMax;
4024 SkScalar fXHeight;
4025 SkScalar fCapHeight;
4026 SkScalar fUnderlineThickness;
4027 SkScalar fUnderlinePosition;
4028 SkScalar fStrikeoutThickness;
4029 SkScalar fStrikeoutPosition;
4030
4031 bool hasUnderlineThickness(SkScalar* thickness) const;
4032 bool hasUnderlinePosition(SkScalar* position) const;
4033 bool hasStrikeoutThickness(SkScalar* thickness) const;
4034 bool hasStrikeoutPosition(SkScalar* position) const;
4035 };
4036##
4037
Cary Clark154beea2017-10-26 07:58:48 -04004038 FontMetrics is filled out by getFontMetrics. FontMetrics contents reflect the values
4039 computed by Font_Manager using Typeface. Values are set to zero if they are
4040 not available.
Cary Clarke4aa3712017-09-15 02:56:12 -04004041
Ben Wagnere5806492017-11-09 12:08:31 -05004042 All vertical values relative to the baseline are given y-down. As such, zero is on the
4043 baseline, negative values are above the baseline, and positive values are below the
4044 baseline.
4045
Cary Clark154beea2017-10-26 07:58:48 -04004046 fUnderlineThickness and fUnderlinePosition have a bit set in fFlags if their values
4047 are valid, since their value may be zero.
Ben Wagnere5806492017-11-09 12:08:31 -05004048
Cary Clark154beea2017-10-26 07:58:48 -04004049 fStrikeoutThickness and fStrikeoutPosition have a bit set in fFlags if their values
4050 are valid, since their value may be zero.
4051
4052 #Enum FontMetricsFlags
Cary Clark08895c42018-02-01 09:37:32 -05004053#Line # valid Font_Metrics ##
Cary Clarke4aa3712017-09-15 02:56:12 -04004054
Cary Clark8032b982017-07-28 11:04:54 -04004055 #Code
4056 enum FontMetricsFlags {
4057 kUnderlineThicknessIsValid_Flag = 1 << 0,
4058 kUnderlinePositionIsValid_Flag = 1 << 1,
4059 kStrikeoutThicknessIsValid_Flag = 1 << 2,
4060 kStrikeoutPositionIsValid_Flag = 1 << 3,
4061 };
4062 ##
4063
Cary Clark154beea2017-10-26 07:58:48 -04004064 FontMetricsFlags are set in fFlags when underline and strikeout metrics are valid;
4065 the underline or strikeout metric may be valid and zero.
4066 Fonts with embedded bitmaps may not have valid underline or strikeout metrics.
4067
Cary Clark8032b982017-07-28 11:04:54 -04004068 #Const kUnderlineThicknessIsValid_Flag 0x0001
4069 Set if fUnderlineThickness is valid.
4070 ##
4071 #Const kUnderlinePositionIsValid_Flag 0x0002
4072 Set if fUnderlinePosition is valid.
4073 ##
4074 #Const kStrikeoutThicknessIsValid_Flag 0x0004
4075 Set if fStrikeoutThickness is valid.
4076 ##
4077 #Const kStrikeoutPositionIsValid_Flag 0x0008
4078 Set if fStrikeoutPosition is valid.
4079 ##
4080
4081 #Enum ##
4082
4083 #Member uint32_t fFlags
4084 fFlags is set when underline metrics are valid.
4085 ##
Ben Wagnere5806492017-11-09 12:08:31 -05004086
Cary Clark8032b982017-07-28 11:04:54 -04004087 #Member SkScalar fTop
Ben Wagnere5806492017-11-09 12:08:31 -05004088 Greatest extent above the baseline for any glyph.
4089 Typically less than zero.
Cary Clark8032b982017-07-28 11:04:54 -04004090 ##
Ben Wagnere5806492017-11-09 12:08:31 -05004091
Cary Clark8032b982017-07-28 11:04:54 -04004092 #Member SkScalar fAscent
4093 Recommended distance above the baseline to reserve for a line of text.
Ben Wagnere5806492017-11-09 12:08:31 -05004094 Typically less than zero.
Cary Clark8032b982017-07-28 11:04:54 -04004095 ##
Ben Wagnere5806492017-11-09 12:08:31 -05004096
Cary Clark8032b982017-07-28 11:04:54 -04004097 #Member SkScalar fDescent
4098 Recommended distance below the baseline to reserve for a line of text.
Ben Wagnere5806492017-11-09 12:08:31 -05004099 Typically greater than zero.
Cary Clark8032b982017-07-28 11:04:54 -04004100 ##
Ben Wagnere5806492017-11-09 12:08:31 -05004101
Cary Clark8032b982017-07-28 11:04:54 -04004102 #Member SkScalar fBottom
Ben Wagnere5806492017-11-09 12:08:31 -05004103 Greatest extent below the baseline for any glyph.
4104 Typically greater than zero.
Cary Clark8032b982017-07-28 11:04:54 -04004105 ##
Ben Wagnere5806492017-11-09 12:08:31 -05004106
Cary Clark8032b982017-07-28 11:04:54 -04004107 #Member SkScalar fLeading
4108 Recommended distance to add between lines of text.
Ben Wagnere5806492017-11-09 12:08:31 -05004109 Typically greater than or equal to zero.
Cary Clark8032b982017-07-28 11:04:54 -04004110 ##
Ben Wagnere5806492017-11-09 12:08:31 -05004111
Cary Clark8032b982017-07-28 11:04:54 -04004112 #Member SkScalar fAvgCharWidth
4113 Average character width, if it is available.
4114 Zero if no average width is stored in the font.
4115 ##
Ben Wagnere5806492017-11-09 12:08:31 -05004116
Cary Clark8032b982017-07-28 11:04:54 -04004117 #Member SkScalar fMaxCharWidth
4118 Maximum character width.
4119 ##
Ben Wagnere5806492017-11-09 12:08:31 -05004120
Cary Clark8032b982017-07-28 11:04:54 -04004121 #Member SkScalar fXMin
Ben Wagnere5806492017-11-09 12:08:31 -05004122 Minimum bounding box x value for all Glyphs.
Cary Clark8032b982017-07-28 11:04:54 -04004123 Typically less than zero.
4124 ##
Ben Wagnere5806492017-11-09 12:08:31 -05004125
Cary Clark8032b982017-07-28 11:04:54 -04004126 #Member SkScalar fXMax
Cary Clarkce101242017-09-01 15:51:02 -04004127 Maximum bounding box x value for all Glyphs.
Cary Clark8032b982017-07-28 11:04:54 -04004128 Typically greater than zero.
4129 ##
Ben Wagnere5806492017-11-09 12:08:31 -05004130
Cary Clark8032b982017-07-28 11:04:54 -04004131 #Member SkScalar fXHeight
4132 Height of a lower-case 'x'.
4133 May be zero if no lower-case height is stored in the font.
4134 ##
Ben Wagnere5806492017-11-09 12:08:31 -05004135
Cary Clark8032b982017-07-28 11:04:54 -04004136 #Member SkScalar fCapHeight
4137 Height of an upper-case letter.
4138 May be zero if no upper-case height is stored in the font.
4139 ##
Ben Wagnere5806492017-11-09 12:08:31 -05004140
Cary Clark8032b982017-07-28 11:04:54 -04004141 #Member SkScalar fUnderlineThickness
Ben Wagnere5806492017-11-09 12:08:31 -05004142 Underline thickness.
4143
4144 If the metric is valid, the kUnderlineThicknessIsValid_Flag is set in fFlags.
Cary Clark8032b982017-07-28 11:04:54 -04004145 If kUnderlineThicknessIsValid_Flag is clear, fUnderlineThickness is zero.
4146 ##
Ben Wagnere5806492017-11-09 12:08:31 -05004147
Cary Clark8032b982017-07-28 11:04:54 -04004148 #Member SkScalar fUnderlinePosition
Ben Wagnere5806492017-11-09 12:08:31 -05004149 Position of the top of the underline stroke relative to the baseline.
4150 Typically positive when valid.
Cary Clark8032b982017-07-28 11:04:54 -04004151
4152 If the metric is valid, the kUnderlinePositionIsValid_Flag is set in fFlags.
4153 If kUnderlinePositionIsValid_Flag is clear, fUnderlinePosition is zero.
4154 ##
4155
4156 #Member SkScalar fStrikeoutThickness
Ben Wagnere5806492017-11-09 12:08:31 -05004157 Strikeout thickness.
4158
4159 If the metric is valid, the kStrikeoutThicknessIsValid_Flag is set in fFlags.
Cary Clark8032b982017-07-28 11:04:54 -04004160 If kStrikeoutThicknessIsValid_Flag is clear, fStrikeoutThickness is zero.
4161 ##
4162
4163 #Member SkScalar fStrikeoutPosition
Ben Wagnere5806492017-11-09 12:08:31 -05004164 Position of the bottom of the strikeout stroke relative to the baseline.
4165 Typically negative when valid.
Cary Clark8032b982017-07-28 11:04:54 -04004166
Ben Wagnere5806492017-11-09 12:08:31 -05004167 If the metric is valid, the kStrikeoutPositionIsValid_Flag is set in fFlags.
4168 If kStrikeoutPositionIsValid_Flag is clear, fStrikeoutPosition is zero.
Cary Clark8032b982017-07-28 11:04:54 -04004169 ##
4170
4171 #Method bool hasUnderlineThickness(SkScalar* thickness) const
4172
Ben Wagnere5806492017-11-09 12:08:31 -05004173 If Font_Metrics has a valid underline thickness, return true, and set
Cary Clarkce101242017-09-01 15:51:02 -04004174 thickness to that value. If the underline thickness is not valid,
4175 return false, and ignore thickness.
Cary Clark8032b982017-07-28 11:04:54 -04004176
4177 #Param thickness storage for underline width ##
4178
4179 #Return true if font specifies underline width ##
4180
4181 #NoExample
4182 ##
4183 ##
4184
4185 #Method bool hasUnderlinePosition(SkScalar* position) const
4186
Ben Wagnere5806492017-11-09 12:08:31 -05004187 If Font_Metrics has a valid underline position, return true, and set
Cary Clarkce101242017-09-01 15:51:02 -04004188 position to that value. If the underline position is not valid,
4189 return false, and ignore position.
Cary Clark8032b982017-07-28 11:04:54 -04004190
4191 #Param position storage for underline position ##
4192
4193 #Return true if font specifies underline position ##
4194
4195 #NoExample
4196 ##
4197 ##
4198
4199 #Method bool hasStrikeoutThickness(SkScalar* thickness) const
4200
Ben Wagnere5806492017-11-09 12:08:31 -05004201 If Font_Metrics has a valid strikeout thickness, return true, and set
Cary Clarkce101242017-09-01 15:51:02 -04004202 thickness to that value. If the underline thickness is not valid,
4203 return false, and ignore thickness.
Cary Clark8032b982017-07-28 11:04:54 -04004204
4205 #Param thickness storage for strikeout width ##
4206
4207 #Return true if font specifies strikeout width ##
4208
4209 #NoExample
4210 ##
4211 ##
4212
4213 #Method bool hasStrikeoutPosition(SkScalar* position) const
4214
Ben Wagnere5806492017-11-09 12:08:31 -05004215 If Font_Metrics has a valid strikeout position, return true, and set
Cary Clarkce101242017-09-01 15:51:02 -04004216 position to that value. If the underline position is not valid,
4217 return false, and ignore position.
Cary Clark8032b982017-07-28 11:04:54 -04004218
4219 #Param position storage for strikeout position ##
4220
4221 #Return true if font specifies strikeout position ##
4222
4223 #NoExample
4224 ##
4225 ##
4226
4227#Struct ##
4228
4229#Method SkScalar getFontMetrics(FontMetrics* metrics, SkScalar scale = 0) const
4230
Cary Clarkab2621d2018-01-30 10:08:57 -05004231#In Font_Metrics
4232#Line # returns Typeface metrics scaled by text size ##
Cary Clark8032b982017-07-28 11:04:54 -04004233 Returns Font_Metrics associated with Typeface.
4234 The return value is the recommended spacing between lines: the sum of metrics
4235 descent, ascent, and leading.
4236 If metrics is not nullptr, Font_Metrics is copied to metrics.
4237 Results are scaled by Text_Size but does not take into account
4238 dimensions required by Text_Scale_X, Text_Skew_X, Fake_Bold,
4239 Style_Stroke, and Path_Effect.
4240 Results can be additionally scaled by scale; a scale of zero
4241 is ignored.
4242
4243 #Param metrics storage for Font_Metrics from Typeface; may be nullptr ##
4244 #Param scale additional multiplier for returned values ##
4245
4246 #Return recommended spacing between lines ##
4247
4248 #Example
4249 #Height 128
4250 void draw(SkCanvas* canvas) {
4251 SkPaint paint;
4252 paint.setTextSize(32);
4253 SkScalar lineHeight = paint.getFontMetrics(nullptr);
4254 canvas->drawString("line 1", 10, 40, paint);
4255 canvas->drawString("line 2", 10, 40 + lineHeight, paint);
4256 paint.setStyle(SkPaint::kStroke_Style);
4257 paint.setStrokeWidth(10);
4258 lineHeight = paint.getFontMetrics(nullptr, 1.10f); // account for stroke height
4259 canvas->drawString("line 3", 120, 40, paint);
4260 canvas->drawString("line 4", 120, 40 + lineHeight, paint);
4261 }
4262 ##
4263
4264 #SeeAlso Text_Size Typeface Typeface_Methods
4265
4266##
4267
4268
4269#Method SkScalar getFontSpacing() const
4270
Cary Clarkab2621d2018-01-30 10:08:57 -05004271#In Font_Metrics
4272#Line # returns recommended spacing between lines ##
Cary Clark8032b982017-07-28 11:04:54 -04004273 Returns the recommended spacing between lines: the sum of metrics
4274 descent, ascent, and leading.
4275 Result is scaled by Text_Size but does not take into account
4276 dimensions required by stroking and Path_Effect.
Cary Clark579985c2017-07-31 11:48:27 -04004277 Returns the same result as getFontMetrics.
Cary Clark8032b982017-07-28 11:04:54 -04004278
Cary Clark0c5f5462017-12-15 11:21:51 -05004279 #Return recommended spacing between lines ##
Cary Clark8032b982017-07-28 11:04:54 -04004280
4281 #Example
4282 SkPaint paint;
4283 for (SkScalar textSize : { 12, 18, 24, 32 } ) {
4284 paint.setTextSize(textSize);
4285 SkDebugf("textSize: %g fontSpacing: %g\n", textSize, paint.getFontSpacing());
4286 }
4287
4288 #StdOut
4289 textSize: 12 fontSpacing: 13.9688
4290 textSize: 18 fontSpacing: 20.9531
4291 textSize: 24 fontSpacing: 27.9375
4292 textSize: 32 fontSpacing: 37.25
4293 ##
4294 ##
4295
4296##
4297
4298
4299#Method SkRect getFontBounds() const
4300
Cary Clarkab2621d2018-01-30 10:08:57 -05004301#In Font_Metrics
4302#Line # returns union all glyph bounds ##
Cary Clarkce101242017-09-01 15:51:02 -04004303Returns the union of bounds of all Glyphs.
Cary Clark8032b982017-07-28 11:04:54 -04004304Returned dimensions are computed by Font_Manager from font data,
Cary Clark579985c2017-07-31 11:48:27 -04004305ignoring Hinting. Includes Text_Size, Text_Scale_X,
Cary Clark8032b982017-07-28 11:04:54 -04004306and Text_Skew_X, but not Fake_Bold or Path_Effect.
4307
4308If Text_Size is large, Text_Scale_X is one, and Text_Skew_X is zero,
Cary Clark579985c2017-07-31 11:48:27 -04004309returns the same bounds as Font_Metrics { FontMetrics::fXMin,
Cary Clark8032b982017-07-28 11:04:54 -04004310FontMetrics::fTop, FontMetrics::fXMax, FontMetrics::fBottom }.
4311
Cary Clarkce101242017-09-01 15:51:02 -04004312#Return union of bounds of all Glyphs ##
Cary Clark8032b982017-07-28 11:04:54 -04004313
4314#Example
4315 SkPaint paint;
4316 SkPaint::FontMetrics fm;
4317 paint.getFontMetrics(&fm);
4318 SkRect fb = paint.getFontBounds();
4319 SkDebugf("metrics bounds = { %g, %g, %g, %g }\n", fm.fXMin, fm.fTop, fm.fXMax, fm.fBottom );
4320 SkDebugf("font bounds = { %g, %g, %g, %g }\n", fb.fLeft, fb.fTop, fb.fRight, fm.fBottom );
4321
4322 #StdOut
4323 metrics bounds = { -12.2461, -14.7891, 21.5215, 5.55469 }
4324 font bounds = { -12.2461, -14.7891, 21.5215, 5.55469 }
4325 ##
4326##
4327
4328##
4329
Cary Clark08895c42018-02-01 09:37:32 -05004330#Subtopic Font_Metrics ##
Cary Clark8032b982017-07-28 11:04:54 -04004331# ------------------------------------------------------------------------------
4332
4333#Method int textToGlyphs(const void* text, size_t byteLength,
4334 SkGlyphID glyphs[]) const
Cary Clark78de7512018-02-07 07:27:09 -05004335#In Utility
Cary Clarkab2621d2018-01-30 10:08:57 -05004336#Line # converts text into glyph indices ##
Cary Clark8032b982017-07-28 11:04:54 -04004337
4338Converts text into glyph indices.
4339Returns the number of glyph indices represented by text.
4340Text_Encoding specifies how text represents characters or glyphs.
4341glyphs may be nullptr, to compute the glyph count.
4342
Cary Clarkbc5697d2017-10-04 14:31:33 -04004343Does not check text for valid character codes or valid glyph indices.
Cary Clark8032b982017-07-28 11:04:54 -04004344
Cary Clark579985c2017-07-31 11:48:27 -04004345If byteLength equals zero, returns zero.
Cary Clark8032b982017-07-28 11:04:54 -04004346If byteLength includes a partial character, the partial character is ignored.
4347
4348If Text_Encoding is kUTF8_TextEncoding and
4349text contains an invalid UTF-8 sequence, zero is returned.
4350
Cary Clarkce101242017-09-01 15:51:02 -04004351#Param text character storage encoded with Text_Encoding ##
Cary Clark8032b982017-07-28 11:04:54 -04004352#Param byteLength length of character storage in bytes ##
4353#Param glyphs storage for glyph indices; may be nullptr ##
4354
4355#Return number of glyphs represented by text of length byteLength ##
4356
4357 #Example
4358 #Height 64
4359 void draw(SkCanvas* canvas) {
4360 SkPaint paint;
4361 const uint8_t utf8[] = { 0x24, 0xC2, 0xA2, 0xE2, 0x82, 0xAC, 0xC2, 0xA5, 0xC2, 0xA3 };
4362 std::vector<SkGlyphID> glyphs;
4363 int count = paint.textToGlyphs(utf8, sizeof(utf8), nullptr);
4364 glyphs.resize(count);
4365 (void) paint.textToGlyphs(utf8, sizeof(utf8), &glyphs.front());
4366 paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
4367 paint.setTextSize(32);
4368 canvas->drawText(&glyphs.front(), glyphs.size() * sizeof(SkGlyphID), 10, 40, paint);
4369 }
4370 ##
4371
4372##
4373
4374#Method int countText(const void* text, size_t byteLength) const
Cary Clark78de7512018-02-07 07:27:09 -05004375#In Utility
Cary Clarkab2621d2018-01-30 10:08:57 -05004376#Line # returns number of Glyphs in text ##
Cary Clarkce101242017-09-01 15:51:02 -04004377 Returns the number of Glyphs in text.
4378 Uses Text_Encoding to count the Glyphs.
Cary Clark8032b982017-07-28 11:04:54 -04004379 Returns the same result as textToGlyphs.
4380
Cary Clarkce101242017-09-01 15:51:02 -04004381#Param text character storage encoded with Text_Encoding ##
Cary Clark8032b982017-07-28 11:04:54 -04004382#Param byteLength length of character storage in bytes ##
4383
Cary Clarkce101242017-09-01 15:51:02 -04004384#Return number of Glyphs represented by text of length byteLength ##
Cary Clark8032b982017-07-28 11:04:54 -04004385
4386 #Example
4387 SkPaint paint;
4388 const uint8_t utf8[] = { 0x24, 0xC2, 0xA2, 0xE2, 0x82, 0xAC, 0xC2, 0xA5, 0xC2, 0xA3 };
4389 SkDebugf("count = %d\n", paint.countText(utf8, sizeof(utf8)));
4390
4391 #StdOut
4392 count = 5
4393 ##
4394 ##
4395##
4396
4397# ------------------------------------------------------------------------------
4398
4399#Method bool containsText(const void* text, size_t byteLength) const
Cary Clark78de7512018-02-07 07:27:09 -05004400#In Utility
Cary Clarkab2621d2018-01-30 10:08:57 -05004401#Line # returns if all text corresponds to Glyphs ##
Cary Clark8032b982017-07-28 11:04:54 -04004402 Returns true if all text corresponds to a non-zero glyph index.
4403 Returns false if any characters in text are not supported in
4404 Typeface.
4405
Cary Clark579985c2017-07-31 11:48:27 -04004406 If Text_Encoding is kGlyphID_TextEncoding,
4407 returns true if all glyph indices in text are non-zero;
Cary Clark8032b982017-07-28 11:04:54 -04004408 does not check to see if text contains valid glyph indices for Typeface.
4409
Cary Clarkce101242017-09-01 15:51:02 -04004410 Returns true if byteLength is zero.
Cary Clark8032b982017-07-28 11:04:54 -04004411
Cary Clarkce101242017-09-01 15:51:02 -04004412 #Param text array of characters or Glyphs ##
Cary Clark8032b982017-07-28 11:04:54 -04004413 #Param byteLength number of bytes in text array ##
4414
4415 #Return true if all text corresponds to a non-zero glyph index ##
4416
4417 #Example
4418 #Description
4419 containsText succeeds for degree symbol, but cannot find a glyph index
4420 corresponding to the Unicode surrogate code point.
4421 ##
4422 SkPaint paint;
4423 const uint16_t goodChar = 0x00B0; // degree symbol
4424 const uint16_t badChar = 0xD800; // Unicode surrogate
4425 paint.setTextEncoding(SkPaint::kUTF16_TextEncoding);
4426 SkDebugf("0x%04x %c= has char\n", goodChar,
4427 paint.containsText(&goodChar, 2) ? '=' : '!');
4428 SkDebugf("0x%04x %c= has char\n", badChar,
4429 paint.containsText(&badChar, 2) ? '=' : '!');
4430
4431 #StdOut
4432 0x00b0 == has char
4433 0xd800 != has char
4434 ##
4435 ##
4436
4437 #Example
4438 #Description
4439 containsText returns true that glyph index is greater than zero, not
4440 that it corresponds to an entry in Typeface.
4441 ##
4442 SkPaint paint;
4443 const uint16_t goodGlyph = 511;
4444 const uint16_t zeroGlyph = 0;
4445 const uint16_t badGlyph = 65535; // larger than glyph count in font
4446 paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
4447 SkDebugf("0x%04x %c= has glyph\n", goodGlyph,
4448 paint.containsText(&goodGlyph, 2) ? '=' : '!');
4449 SkDebugf("0x%04x %c= has glyph\n", zeroGlyph,
4450 paint.containsText(&zeroGlyph, 2) ? '=' : '!');
4451 SkDebugf("0x%04x %c= has glyph\n", badGlyph,
4452 paint.containsText(&badGlyph, 2) ? '=' : '!');
4453
4454 #StdOut
4455 0x01ff == has glyph
4456 0x0000 != has glyph
4457 0xffff == has glyph
4458 ##
4459 ##
4460
4461#SeeAlso setTextEncoding Typeface
4462
4463##
4464
4465# ------------------------------------------------------------------------------
4466
4467#Method void glyphsToUnichars(const SkGlyphID glyphs[],
4468 int count, SkUnichar text[]) const
Cary Clark78de7512018-02-07 07:27:09 -05004469#In Utility
Cary Clarkab2621d2018-01-30 10:08:57 -05004470#Line # converts Glyphs into text ##
Cary Clark8032b982017-07-28 11:04:54 -04004471
4472 Converts glyphs into text if possible.
4473 Glyph values without direct Unicode equivalents are mapped to zero.
4474 Uses the Typeface, but is unaffected
4475 by Text_Encoding; the text values returned are equivalent to kUTF32_TextEncoding.
4476
4477 Only supported on platforms that use FreeType as the Font_Engine.
4478
4479 #Param glyphs array of indices into font ##
4480 #Param count length of glyph array ##
4481 #Param text storage for character codes, one per glyph ##
4482
4483 #Example
4484 #Height 64
4485 #Description
4486 Convert UTF-8 text to glyphs; then convert glyphs to Unichar code points.
4487 ##
4488 void draw(SkCanvas* canvas) {
4489 SkPaint paint;
4490 const char hello[] = "Hello!";
4491 const int count = sizeof(hello) - 1;
4492 SkGlyphID glyphs[count];
4493 if (count != paint.textToGlyphs(hello, count, glyphs)) {
4494 return;
4495 }
4496 SkUnichar unichars[count];
4497 paint.glyphsToUnichars(glyphs, count, unichars);
4498 paint.setTextEncoding(SkPaint::kUTF32_TextEncoding);
4499 canvas->drawText(unichars, sizeof(unichars), 10, 30, paint);
4500 }
4501 ##
4502
4503##
4504
4505# ------------------------------------------------------------------------------
Cary Clark08895c42018-02-01 09:37:32 -05004506#Subtopic Measure_Text
4507#Line # width, height, bounds of text ##
Cary Clark8032b982017-07-28 11:04:54 -04004508
4509#Method SkScalar measureText(const void* text, size_t length, SkRect* bounds) const
4510
Cary Clarkab2621d2018-01-30 10:08:57 -05004511#In Measure_Text
4512#Line # returns advance width and bounds of text ##
Cary Clark8032b982017-07-28 11:04:54 -04004513 Returns the advance width of text if kVerticalText_Flag is clear,
4514 and the height of text if kVerticalText_Flag is set.
4515 The advance is the normal distance to move before drawing additional text.
4516 Uses Text_Encoding to decode text, Typeface to get the font metrics,
4517 and Text_Size, Text_Scale_X, Text_Skew_X, Stroke_Width, and
4518 Path_Effect to scale the metrics and bounds.
4519 Returns the bounding box of text if bounds is not nullptr.
4520 The bounding box is computed as if the text was drawn at the origin.
4521
4522 #Param text character codes or glyph indices to be measured ##
4523 #Param length number of bytes of text to measure ##
4524 #Param bounds returns bounding box relative to (0, 0) if not nullptr ##
4525
4526 #Return advance width or height ##
4527
4528 #Example
4529 #Height 64
4530 void draw(SkCanvas* canvas) {
4531 SkPaint paint;
4532 paint.setAntiAlias(true);
4533 paint.setTextSize(50);
4534 const char str[] = "ay^jZ";
4535 const int count = sizeof(str) - 1;
4536 canvas->drawText(str, count, 25, 50, paint);
4537 SkRect bounds;
4538 paint.measureText(str, count, &bounds);
4539 canvas->translate(25, 50);
4540 paint.setStyle(SkPaint::kStroke_Style);
4541 canvas->drawRect(bounds, paint);
4542 }
4543 ##
4544
4545##
4546
4547#Method SkScalar measureText(const void* text, size_t length) const
4548
Cary Clarkab2621d2018-01-30 10:08:57 -05004549#In Measure_Text
Cary Clark8032b982017-07-28 11:04:54 -04004550 Returns the advance width of text if kVerticalText_Flag is clear,
4551 and the height of text if kVerticalText_Flag is set.
4552 The advance is the normal distance to move before drawing additional text.
4553 Uses Text_Encoding to decode text, Typeface to get the font metrics,
4554 and Text_Size to scale the metrics.
4555 Does not scale the advance or bounds by Fake_Bold or Path_Effect.
4556
4557 #Param text character codes or glyph indices to be measured ##
4558 #Param length number of bytes of text to measure ##
4559
4560 #Return advance width or height ##
4561
4562 #Example
4563 SkPaint paint;
4564 SkDebugf("default width = %g\n", paint.measureText("!", 1));
4565 paint.setTextSize(paint.getTextSize() * 2);
4566 SkDebugf("double width = %g\n", paint.measureText("!", 1));
4567
4568 #StdOut
4569 default width = 5
4570 double width = 10
4571 ##
4572 ##
4573
4574##
4575
4576#Method size_t breakText(const void* text, size_t length, SkScalar maxWidth,
Cary Clark73fa9722017-08-29 17:36:51 -04004577 SkScalar* measuredWidth = nullptr) const
Cary Clarkab2621d2018-01-30 10:08:57 -05004578#In Measure_Text
4579#Line # returns text that fits in a width ##
Cary Clark8032b982017-07-28 11:04:54 -04004580
4581 Returns the bytes of text that fit within maxWidth.
4582 If kVerticalText_Flag is clear, the text fragment fits if its advance width is less than or
4583 equal to maxWidth.
4584 If kVerticalText_Flag is set, the text fragment fits if its advance height is less than or
4585 equal to maxWidth.
4586 Measures only while the advance is less than or equal to maxWidth.
4587 Returns the advance or the text fragment in measuredWidth if it not nullptr.
4588 Uses Text_Encoding to decode text, Typeface to get the font metrics,
4589 and Text_Size to scale the metrics.
4590 Does not scale the advance or bounds by Fake_Bold or Path_Effect.
4591
4592 #Param text character codes or glyph indices to be measured ##
4593 #Param length number of bytes of text to measure ##
4594 #Param maxWidth advance limit; text is measured while advance is less than maxWidth ##
4595 #Param measuredWidth returns the width of the text less than or equal to maxWidth ##
4596 #Return bytes of text that fit, always less than or equal to length ##
4597
4598 #Example
4599 #Description
4600 Line under "Breakfast" shows desired width, shorter than available characters.
4601 Line under "Bre" shows measured width after breaking text.
4602 ##
4603 #Height 128
4604 #Width 280
4605 void draw(SkCanvas* canvas) {
4606 SkPaint paint;
4607 paint.setAntiAlias(true);
4608 paint.setTextSize(50);
4609 const char str[] = "Breakfast";
4610 const int count = sizeof(str) - 1;
4611 canvas->drawText(str, count, 25, 50, paint);
4612 SkScalar measuredWidth;
4613 int partialBytes = paint.breakText(str, count, 100, &measuredWidth);
4614 canvas->drawText(str, partialBytes, 25, 100, paint);
4615 canvas->drawLine(25, 60, 25 + 100, 60, paint);
4616 canvas->drawLine(25, 110, 25 + measuredWidth, 110, paint);
4617 }
4618 ##
4619
4620##
4621
4622#Method int getTextWidths(const void* text, size_t byteLength, SkScalar widths[],
Cary Clark73fa9722017-08-29 17:36:51 -04004623 SkRect bounds[] = nullptr) const
Cary Clarkab2621d2018-01-30 10:08:57 -05004624#In Measure_Text
4625#Line # returns advance and bounds for each glyph in text ##
Cary Clark8032b982017-07-28 11:04:54 -04004626
4627 Retrieves the advance and bounds for each glyph in text, and returns
4628 the glyph count in text.
4629 Both widths and bounds may be nullptr.
4630 If widths is not nullptr, widths must be an array of glyph count entries.
4631 if bounds is not nullptr, bounds must be an array of glyph count entries.
4632 If kVerticalText_Flag is clear, widths returns the horizontal advance.
4633 If kVerticalText_Flag is set, widths returns the vertical advance.
4634 Uses Text_Encoding to decode text, Typeface to get the font metrics,
4635 and Text_Size to scale the widths and bounds.
4636 Does not scale the advance by Fake_Bold or Path_Effect.
4637 Does include Fake_Bold and Path_Effect in the bounds.
4638
4639 #Param text character codes or glyph indices to be measured ##
4640 #Param byteLength number of bytes of text to measure ##
4641 #Param widths returns text advances for each glyph; may be nullptr ##
4642 #Param bounds returns bounds for each glyph relative to (0, 0); may be nullptr ##
4643
4644 #Return glyph count in text ##
4645
4646 #Example
4647 #Height 160
4648 #Description
Cary Clarkce101242017-09-01 15:51:02 -04004649 Bounds of Glyphs increase for stroked text, but text advance remains the same.
Cary Clark8032b982017-07-28 11:04:54 -04004650 The underlines show the text advance, spaced to keep them distinct.
4651 ##
4652 void draw(SkCanvas* canvas) {
4653 SkPaint paint;
4654 paint.setAntiAlias(true);
4655 paint.setTextSize(50);
4656 const char str[] = "abc";
4657 const int bytes = sizeof(str) - 1;
4658 int count = paint.getTextWidths(str, bytes, nullptr);
4659 std::vector<SkScalar> widths;
4660 std::vector<SkRect> bounds;
4661 widths.resize(count);
4662 bounds.resize(count);
4663 for (int loop = 0; loop < 2; ++loop) {
4664 (void) paint.getTextWidths(str, count, &widths.front(), &bounds.front());
4665 SkPoint loc = { 25, 50 };
4666 canvas->drawText(str, bytes, loc.fX, loc.fY, paint);
4667 paint.setStyle(SkPaint::kStroke_Style);
4668 paint.setStrokeWidth(0);
4669 SkScalar advanceY = loc.fY + 10;
4670 for (int index = 0; index < count; ++index) {
4671 bounds[index].offset(loc.fX, loc.fY);
4672 canvas->drawRect(bounds[index], paint);
4673 canvas->drawLine(loc.fX, advanceY, loc.fX + widths[index], advanceY, paint);
4674 loc.fX += widths[index];
4675 advanceY += 5;
4676 }
4677 canvas->translate(0, 80);
4678 paint.setStrokeWidth(3);
4679 }
4680 }
4681 ##
4682
4683##
4684
Cary Clark08895c42018-02-01 09:37:32 -05004685#Subtopic Measure_Text ##
Cary Clark8032b982017-07-28 11:04:54 -04004686# ------------------------------------------------------------------------------
Cary Clark08895c42018-02-01 09:37:32 -05004687#Subtopic Text_Path
4688#Line # geometry of Glyphs ##
Cary Clark8032b982017-07-28 11:04:54 -04004689
Cary Clarkce101242017-09-01 15:51:02 -04004690Text_Path describes the geometry of Glyphs used to draw text.
Cary Clark8032b982017-07-28 11:04:54 -04004691
4692#Method void getTextPath(const void* text, size_t length, SkScalar x, SkScalar y,
4693 SkPath* path) const
Cary Clarkab2621d2018-01-30 10:08:57 -05004694#In Text_Path
4695#Line # returns Path equivalent to text ##
Cary Clark8032b982017-07-28 11:04:54 -04004696
4697Returns the geometry as Path equivalent to the drawn text.
4698Uses Text_Encoding to decode text, Typeface to get the glyph paths,
4699and Text_Size, Fake_Bold, and Path_Effect to scale and modify the glyph paths.
4700All of the glyph paths are stored in path.
Cary Clark579985c2017-07-31 11:48:27 -04004701Uses x, y, and Text_Align to position path.
Cary Clark8032b982017-07-28 11:04:54 -04004702
4703 #Param text character codes or glyph indices ##
4704 #Param length number of bytes of text ##
4705 #Param x x-coordinate of the origin of the text ##
4706 #Param y y-coordinate of the origin of the text ##
Cary Clarkce101242017-09-01 15:51:02 -04004707 #Param path geometry of the Glyphs ##
Cary Clark8032b982017-07-28 11:04:54 -04004708
4709 #Example
4710 #Description
4711 Text is added to Path, offset, and subtracted from Path, then added at
4712 the offset location. The result is rendered with one draw call.
4713 ##
4714 #Height 128
4715 void draw(SkCanvas* canvas) {
4716 SkPaint paint;
4717 paint.setTextSize(80);
4718 SkPath path, path2;
4719 paint.getTextPath("ABC", 3, 20, 80, &path);
4720 path.offset(20, 20, &path2);
4721 Op(path, path2, SkPathOp::kDifference_SkPathOp, &path);
4722 path.addPath(path2);
4723 paint.setStyle(SkPaint::kStroke_Style);
4724 canvas->drawPath(path, paint);
4725 }
4726 ##
4727
4728##
4729
4730#Method void getPosTextPath(const void* text, size_t length,
4731 const SkPoint pos[], SkPath* path) const
Cary Clarkab2621d2018-01-30 10:08:57 -05004732#In Text_Path
4733#Line # returns Path equivalent to positioned text ##
Cary Clark8032b982017-07-28 11:04:54 -04004734
4735Returns the geometry as Path equivalent to the drawn text.
4736Uses Text_Encoding to decode text, Typeface to get the glyph paths,
4737and Text_Size, Fake_Bold, and Path_Effect to scale and modify the glyph paths.
4738All of the glyph paths are stored in path.
4739Uses pos array and Text_Align to position path.
4740pos contains a position for each glyph.
4741
4742 #Param text character codes or glyph indices ##
4743 #Param length number of bytes of text ##
4744 #Param pos positions of each glyph ##
Cary Clarkce101242017-09-01 15:51:02 -04004745 #Param path geometry of the Glyphs ##
Cary Clark8032b982017-07-28 11:04:54 -04004746
4747 #Example
4748 #Height 85
4749 #Description
Cary Clarkce101242017-09-01 15:51:02 -04004750 Simplifies three Glyphs to eliminate overlaps, and strokes the result.
Cary Clark8032b982017-07-28 11:04:54 -04004751 ##
4752 void draw(SkCanvas* canvas) {
4753 SkPaint paint;
4754 paint.setTextSize(80);
4755 SkPath path, path2;
4756 SkPoint pos[] = {{20, 60}, {30, 70}, {40, 80}};
4757 paint.getPosTextPath("ABC", 3, pos, &path);
4758 Simplify(path, &path);
4759 paint.setStyle(SkPaint::kStroke_Style);
4760 canvas->drawPath(path, paint);
4761 }
4762 ##
4763
4764##
4765
Cary Clark08895c42018-02-01 09:37:32 -05004766#Subtopic Text_Path ##
Cary Clark8032b982017-07-28 11:04:54 -04004767# ------------------------------------------------------------------------------
Cary Clark08895c42018-02-01 09:37:32 -05004768#Subtopic Text_Intercepts
4769#Line # advanced underline, strike through ##
Cary Clark8032b982017-07-28 11:04:54 -04004770
Cary Clarkce101242017-09-01 15:51:02 -04004771Text_Intercepts describe the intersection of drawn text Glyphs with a pair
Cary Clark8032b982017-07-28 11:04:54 -04004772of lines parallel to the text advance. Text_Intercepts permits creating a
Cary Clarkce101242017-09-01 15:51:02 -04004773underline that skips Descenders.
Cary Clark8032b982017-07-28 11:04:54 -04004774
4775#Method int getTextIntercepts(const void* text, size_t length, SkScalar x, SkScalar y,
4776 const SkScalar bounds[2], SkScalar* intervals) const
Cary Clarkab2621d2018-01-30 10:08:57 -05004777#In Text_Intercepts
4778#Line # returns where lines intersect text; underlines ##
Cary Clark8032b982017-07-28 11:04:54 -04004779
4780 Returns the number of intervals that intersect bounds.
4781 bounds describes a pair of lines parallel to the text advance.
Cary Clarkce101242017-09-01 15:51:02 -04004782 The return count is zero or a multiple of two, and is at most twice the number of Glyphs in
Cary Clark8032b982017-07-28 11:04:54 -04004783 the string.
4784 Uses Text_Encoding to decode text, Typeface to get the glyph paths,
4785 and Text_Size, Fake_Bold, and Path_Effect to scale and modify the glyph paths.
4786 Uses x, y, and Text_Align to position intervals.
4787
4788 Pass nullptr for intervals to determine the size of the interval array.
4789
4790 intervals are cached to improve performance for multiple calls.
4791
4792 #Param text character codes or glyph indices ##
4793 #Param length number of bytes of text ##
4794 #Param x x-coordinate of the origin of the text ##
4795 #Param y y-coordinate of the origin of the text ##
4796 #Param bounds lower and upper line parallel to the advance ##
4797 #Param intervals returned intersections; may be nullptr ##
4798
4799 #Return number of intersections; may be zero ##
4800
4801#Example
4802#Height 128
4803#Description
Cary Clarkce101242017-09-01 15:51:02 -04004804Underline uses intercepts to draw on either side of the glyph Descender.
Cary Clark8032b982017-07-28 11:04:54 -04004805##
4806void draw(SkCanvas* canvas) {
4807 SkPaint paint;
4808 paint.setTextSize(120);
4809 SkPoint textOrigin = { 20, 100 };
4810 SkScalar bounds[] = { 100, 108 };
4811 int count = paint.getTextIntercepts("y", 1, textOrigin.fX, textOrigin.fY, bounds, nullptr);
4812 std::vector<SkScalar> intervals;
4813 intervals.resize(count);
4814 (void) paint.getTextIntercepts("y", 1, textOrigin.fX, textOrigin.fY, bounds,
4815 &intervals.front());
4816 canvas->drawString("y", textOrigin.fX, textOrigin.fY, paint);
4817 paint.setColor(SK_ColorRED);
4818 SkScalar x = textOrigin.fX;
4819 for (int i = 0; i < count; i += 2) {
4820 canvas->drawRect({x, bounds[0], intervals[i], bounds[1]}, paint);
4821 x = intervals[i + 1];
4822 }
4823 canvas->drawRect({intervals[count - 1], bounds[0],
4824 textOrigin.fX + paint.measureText("y", 1), bounds[1]}, paint);
4825}
4826##
4827
4828##
4829
4830#Method int getPosTextIntercepts(const void* text, size_t length, const SkPoint pos[],
4831 const SkScalar bounds[2], SkScalar* intervals) const
Cary Clarkab2621d2018-01-30 10:08:57 -05004832#In Text_Intercepts
4833#Line # returns where lines intersect positioned text; underlines ##
Cary Clark8032b982017-07-28 11:04:54 -04004834
4835 Returns the number of intervals that intersect bounds.
4836 bounds describes a pair of lines parallel to the text advance.
Cary Clarkce101242017-09-01 15:51:02 -04004837 The return count is zero or a multiple of two, and is at most twice the number of Glyphs in
Cary Clark8032b982017-07-28 11:04:54 -04004838 the string.
4839 Uses Text_Encoding to decode text, Typeface to get the glyph paths,
4840 and Text_Size, Fake_Bold, and Path_Effect to scale and modify the glyph paths.
4841 Uses pos array and Text_Align to position intervals.
4842
4843 Pass nullptr for intervals to determine the size of the interval array.
4844
4845 intervals are cached to improve performance for multiple calls.
4846
4847 #Param text character codes or glyph indices ##
4848 #Param length number of bytes of text ##
4849 #Param pos positions of each glyph ##
4850 #Param bounds lower and upper line parallel to the advance ##
4851 #Param intervals returned intersections; may be nullptr ##
4852
Cary Clarka523d2d2017-08-30 08:58:10 -04004853 #Return number of intersections; may be zero ##
Cary Clark8032b982017-07-28 11:04:54 -04004854
4855 #Example
4856 #Description
Cary Clarkce101242017-09-01 15:51:02 -04004857 Text intercepts draw on either side of, but not inside, Glyphs in a run.
Cary Clark8032b982017-07-28 11:04:54 -04004858 ##
4859 void draw(SkCanvas* canvas) {
4860 SkPaint paint;
4861 paint.setTextSize(120);
4862 paint.setVerticalText(true);
4863 SkPoint textPos[] = {{ 60, 40 }, { 60, 140 }};
4864 SkScalar bounds[] = { 56, 64 };
4865 const char str[] = "A-";
4866 int len = sizeof(str) - 1;
4867 int count = paint.getPosTextIntercepts(str, len, textPos, bounds, nullptr);
4868 std::vector<SkScalar> intervals;
4869 intervals.resize(count);
4870 (void) paint.getPosTextIntercepts(str, len, textPos, bounds, &intervals.front());
4871 canvas->drawPosText(str, len, textPos, paint);
4872 paint.setColor(SK_ColorRED);
4873 SkScalar y = textPos[0].fY;
4874 for (int i = 0; i < count; i+= 2) {
4875 canvas->drawRect({bounds[0], y, bounds[1], intervals[i]}, paint);
4876 y = intervals[i + 1];
4877 }
4878 canvas->drawRect({bounds[0], intervals[count - 1], bounds[1], 240}, paint);
4879 }
4880 ##
4881
4882##
4883
4884#Method int getPosTextHIntercepts(const void* text, size_t length, const SkScalar xpos[],
4885 SkScalar constY, const SkScalar bounds[2],
4886 SkScalar* intervals) const
Cary Clarkab2621d2018-01-30 10:08:57 -05004887#In Text_Intercepts
4888#Line # returns where lines intersect horizontally positioned text; underlines ##
Cary Clark8032b982017-07-28 11:04:54 -04004889
4890 Returns the number of intervals that intersect bounds.
4891 bounds describes a pair of lines parallel to the text advance.
Cary Clarkce101242017-09-01 15:51:02 -04004892 The return count is zero or a multiple of two, and is at most twice the number of Glyphs in
Cary Clark8032b982017-07-28 11:04:54 -04004893 the string.
4894 Uses Text_Encoding to decode text, Typeface to get the glyph paths,
4895 and Text_Size, Fake_Bold, and Path_Effect to scale and modify the glyph paths.
4896 Uses xpos array, constY, and Text_Align to position intervals.
4897
4898 Pass nullptr for intervals to determine the size of the interval array.
4899
4900 intervals are cached to improve performance for multiple calls.
4901
4902 #Param text character codes or glyph indices ##
4903 #Param length number of bytes of text ##
4904 #Param xpos positions of each glyph in x ##
4905 #Param constY position of each glyph in y ##
4906 #Param bounds lower and upper line parallel to the advance ##
4907 #Param intervals returned intersections; may be nullptr ##
4908
4909 #Return number of intersections; may be zero ##
4910
4911 #Example
4912 #Height 128
4913 #Description
4914 Text intercepts do not take stroke thickness into consideration.
4915 ##
4916 void draw(SkCanvas* canvas) {
4917 SkPaint paint;
4918 paint.setTextSize(120);
4919 paint.setStyle(SkPaint::kStroke_Style);
4920 paint.setStrokeWidth(4);
4921 SkScalar textPosH[] = { 20, 80, 140 };
4922 SkScalar y = 100;
4923 SkScalar bounds[] = { 56, 78 };
4924 const char str[] = "\\-/";
4925 int len = sizeof(str) - 1;
4926 int count = paint.getPosTextHIntercepts(str, len, textPosH, y, bounds, nullptr);
4927 std::vector<SkScalar> intervals;
4928 intervals.resize(count);
4929 (void) paint.getPosTextHIntercepts(str, len, textPosH, y, bounds, &intervals.front());
4930 canvas->drawPosTextH(str, len, textPosH, y, paint);
4931 paint.setColor(0xFFFF7777);
4932 paint.setStyle(SkPaint::kFill_Style);
4933 SkScalar x = textPosH[0];
4934 for (int i = 0; i < count; i+= 2) {
4935 canvas->drawRect({x, bounds[0], intervals[i], bounds[1]}, paint);
4936 x = intervals[i + 1];
4937 }
4938 canvas->drawRect({intervals[count - 1], bounds[0], 180, bounds[1]}, paint);
4939 }
4940 ##
4941
4942##
4943
4944
4945#Method int getTextBlobIntercepts(const SkTextBlob* blob, const SkScalar bounds[2],
4946 SkScalar* intervals) const
Cary Clarkab2621d2018-01-30 10:08:57 -05004947#In Text_Intercepts
4948#Line # returns where lines intersect Text_Blob; underlines ##
Cary Clark8032b982017-07-28 11:04:54 -04004949
4950 Returns the number of intervals that intersect bounds.
4951 bounds describes a pair of lines parallel to the text advance.
Cary Clarkce101242017-09-01 15:51:02 -04004952 The return count is zero or a multiple of two, and is at most twice the number of Glyphs in
Cary Clark8032b982017-07-28 11:04:54 -04004953 the string.
Cary Clark3cd22cc2017-12-01 11:49:58 -05004954 Uses Typeface to get the glyph paths,
Cary Clark8032b982017-07-28 11:04:54 -04004955 and Text_Size, Fake_Bold, and Path_Effect to scale and modify the glyph paths.
Cary Clarkce101242017-09-01 15:51:02 -04004956 Uses run array and Text_Align to position intervals.
Cary Clark8032b982017-07-28 11:04:54 -04004957
Cary Clark3cd22cc2017-12-01 11:49:58 -05004958 Text_Encoding must be set to SkPaint::kGlyphID_TextEncoding.
4959
Cary Clark8032b982017-07-28 11:04:54 -04004960 Pass nullptr for intervals to determine the size of the interval array.
4961
4962 intervals are cached to improve performance for multiple calls.
4963
Cary Clarkce101242017-09-01 15:51:02 -04004964 #Param blob Glyphs, positions, and text paint attributes ##
Cary Clark8032b982017-07-28 11:04:54 -04004965 #Param bounds lower and upper line parallel to the advance ##
4966 #Param intervals returned intersections; may be nullptr ##
4967
4968 #Return number of intersections; may be zero ##
4969
4970 #Example
4971 #Height 143
4972 void draw(SkCanvas* canvas) {
4973 SkPaint paint;
Cary Clark3cd22cc2017-12-01 11:49:58 -05004974 paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
Cary Clark8032b982017-07-28 11:04:54 -04004975 paint.setTextSize(120);
4976 SkPoint textPos = { 20, 110 };
4977 int len = 3;
4978 SkTextBlobBuilder textBlobBuilder;
4979 const SkTextBlobBuilder::RunBuffer& run =
4980 textBlobBuilder.allocRun(paint, len, textPos.fX, textPos.fY);
4981 run.glyphs[0] = 10;
4982 run.glyphs[1] = 20;
4983 run.glyphs[2] = 30;
4984 sk_sp<const SkTextBlob> blob = textBlobBuilder.make();
4985 canvas->drawTextBlob(blob.get(), textPos.fX, textPos.fY, paint);
4986 SkScalar bounds[] = { 116, 134 };
4987 int count = paint.getTextBlobIntercepts(blob.get(), bounds, nullptr);
4988 std::vector<SkScalar> intervals;
4989 intervals.resize(count);
4990 (void) paint.getTextBlobIntercepts(blob.get(), bounds, &intervals.front());
4991 canvas->drawTextBlob(blob.get(), 0, 0, paint);
4992 paint.setColor(0xFFFF7777);
4993 SkScalar x = textPos.fX;
4994 for (int i = 0; i < count; i+= 2) {
4995 canvas->drawRect({x, bounds[0], intervals[i], bounds[1]}, paint);
4996 x = intervals[i + 1];
4997 }
4998 canvas->drawRect({intervals[count - 1], bounds[0], 180, bounds[1]}, paint);
4999 }
5000 ##
5001
5002##
5003
Cary Clark08895c42018-02-01 09:37:32 -05005004#Subtopic Text_Intercepts ##
Cary Clark8032b982017-07-28 11:04:54 -04005005# ------------------------------------------------------------------------------
5006
5007#Method bool nothingToDraw() const
Cary Clark78de7512018-02-07 07:27:09 -05005008#In Utility
Cary Clarkab2621d2018-01-30 10:08:57 -05005009#Line # returns true if Paint prevents all drawing ##
Cary Clark579985c2017-07-31 11:48:27 -04005010 Returns true if Paint prevents all drawing;
5011 otherwise, the Paint may or may not allow drawing.
Cary Clark8032b982017-07-28 11:04:54 -04005012
Cary Clarkce101242017-09-01 15:51:02 -04005013 Returns true if, for example, Blend_Mode combined with Color_Alpha computes a
5014 new Alpha of zero.
Cary Clark8032b982017-07-28 11:04:54 -04005015
5016 #Return true if Paint prevents all drawing ##
5017
5018 #Example
5019 void draw(SkCanvas* canvas) {
5020 auto debugster = [](const char* prefix, const SkPaint& p) -> void {
5021 SkDebugf("%s nothing to draw: %s\n", prefix,
5022 p.nothingToDraw() ? "true" : "false");
5023 };
5024 SkPaint paint;
5025 debugster("initial", paint);
5026 paint.setBlendMode(SkBlendMode::kDst);
5027 debugster("blend dst", paint);
5028 paint.setBlendMode(SkBlendMode::kSrcOver);
5029 debugster("blend src over", paint);
5030 paint.setAlpha(0);
5031 debugster("alpha 0", paint);
5032 }
5033
5034 #StdOut
5035 initial nothing to draw: false
5036 blend dst nothing to draw: true
5037 blend src over nothing to draw: false
5038 alpha 0 nothing to draw: true
5039 #StdOut ##
5040 ##
5041
5042##
5043
5044# ------------------------------------------------------------------------------
Cary Clark08895c42018-02-01 09:37:32 -05005045#Subtopic Fast_Bounds
5046#Line # approximate area required by Paint ##
Cary Clark8032b982017-07-28 11:04:54 -04005047 #Private
5048 To be made private.
5049 ##
5050
5051Fast_Bounds methods conservatively outset a drawing bounds by additional area
5052Paint may draw to.
5053
5054#Method bool canComputeFastBounds() const
Cary Clarkab2621d2018-01-30 10:08:57 -05005055
5056#In Fast_Bounds
Cary Clark1a8d7622018-03-05 13:26:16 -05005057#Line # returns true if settings allow for fast bounds computation ##
5058 #Private
Cary Clark8032b982017-07-28 11:04:54 -04005059 (to be made private)
5060 ##
5061
5062 Returns true if Paint does not include elements requiring extensive computation
5063 to compute Device bounds of drawn geometry. For instance, Paint with Path_Effect
5064 always returns false.
5065
5066 #Return true if Paint allows for fast computation of bounds ##
5067##
5068
5069#Method const SkRect& computeFastBounds(const SkRect& orig, SkRect* storage) const
Cary Clarkab2621d2018-01-30 10:08:57 -05005070
5071#In Fast_Bounds
Cary Clark1a8d7622018-03-05 13:26:16 -05005072#Line # returns fill bounds for quick reject tests ##
5073 #Private
Cary Clark8032b982017-07-28 11:04:54 -04005074 (to be made private)
5075 ##
5076
5077 Only call this if canComputeFastBounds returned true. This takes a
5078 raw rectangle (the raw bounds of a shape), and adjusts it for stylistic
5079 effects in the paint (e.g. stroking). If needed, it uses the storage
Cary Clarkce101242017-09-01 15:51:02 -04005080 parameter. It returns the adjusted bounds that can then be used
Cary Clark8032b982017-07-28 11:04:54 -04005081 for SkCanvas::quickReject tests.
5082
Cary Clarkce101242017-09-01 15:51:02 -04005083 The returned Rect will either be orig or storage, thus the caller
Cary Clark8032b982017-07-28 11:04:54 -04005084 should not rely on storage being set to the result, but should always
Cary Clarkce101242017-09-01 15:51:02 -04005085 use the returned value. It is legal for orig and storage to be the same
5086 Rect.
Cary Clark8032b982017-07-28 11:04:54 -04005087
5088 #Private
5089 e.g.
5090 if (paint.canComputeFastBounds()) {
5091 SkRect r, storage;
5092 path.computeBounds(&r, SkPath::kFast_BoundsType);
5093 const SkRect& fastR = paint.computeFastBounds(r, &storage);
5094 if (canvas->quickReject(fastR, ...)) {
5095 // don't draw the path
5096 }
5097 }
5098 ##
5099
5100 #Param orig geometry modified by Paint when drawn ##
5101 #Param storage computed bounds of geometry; may not be nullptr ##
5102
5103 #Return fast computed bounds ##
5104##
5105
5106#Method const SkRect& computeFastStrokeBounds(const SkRect& orig,
5107 SkRect* storage) const
Cary Clarkab2621d2018-01-30 10:08:57 -05005108#In Fast_Bounds
5109#Line # returns stroke bounds for quick reject tests ##
Cary Clark8032b982017-07-28 11:04:54 -04005110 #Private
5111 (to be made private)
5112 ##
5113
5114 #Param orig geometry modified by Paint when drawn ##
5115 #Param storage computed bounds of geometry ##
5116
5117 #Return fast computed bounds ##
5118##
5119
5120#Method const SkRect& doComputeFastBounds(const SkRect& orig, SkRect* storage,
5121 Style style) const
Cary Clarkab2621d2018-01-30 10:08:57 -05005122#In Fast_Bounds
5123#Line # returns bounds for quick reject tests ##
Cary Clark8032b982017-07-28 11:04:54 -04005124 #Private
5125 (to be made private)
5126 ##
5127
Cary Clarkce101242017-09-01 15:51:02 -04005128 Computes the bounds, overriding the Paint Style. This can be used to
5129 account for additional width required by stroking orig, without
5130 altering Style set to fill.
Cary Clark8032b982017-07-28 11:04:54 -04005131
5132 #Param orig geometry modified by Paint when drawn ##
5133 #Param storage computed bounds of geometry ##
5134 #Param style overrides Style ##
5135
5136 #Return fast computed bounds ##
5137##
5138
Cary Clark1a8d7622018-03-05 13:26:16 -05005139#Subtopic Fast_Bounds ##
Cary Clark8032b982017-07-28 11:04:54 -04005140
5141# ------------------------------------------------------------------------------
Cary Clark78de7512018-02-07 07:27:09 -05005142#Subtopic Utility
5143#Populate
5144#Line # rarely called management functions ##
5145##
Cary Clark8032b982017-07-28 11:04:54 -04005146
Cary Clark78de7512018-02-07 07:27:09 -05005147#Method void toString(SkString* str) const
5148#In Utility
Cary Clarkab2621d2018-01-30 10:08:57 -05005149#Line # converts Paint to machine readable form ##
Cary Clark8032b982017-07-28 11:04:54 -04005150#DefinedBy SK_TO_STRING_NONVIRT() ##
5151
5152#Private
5153macro expands to: void toString(SkString* str) const;
5154##
5155
Cary Clarkce101242017-09-01 15:51:02 -04005156Creates string representation of Paint. The representation is read by
5157internal debugging tools. The interface and implementation may be
5158suppressed by defining SK_IGNORE_TO_STRING.
Cary Clark8032b982017-07-28 11:04:54 -04005159
Cary Clarkce101242017-09-01 15:51:02 -04005160#Param str storage for string representation of Paint ##
Cary Clark8032b982017-07-28 11:04:54 -04005161
5162#Example
5163 SkPaint paint;
5164 SkString str;
5165 paint.toString(&str);
5166 const char textSize[] = "TextSize:";
5167 const int trailerSize = strlen("</dd><dt>");
5168 int textSizeLoc = str.find(textSize) + strlen(textSize) + trailerSize;
5169 const char* sizeStart = &str.c_str()[textSizeLoc];
5170 int textSizeEnd = SkStrFind(sizeStart, "</dd>");
5171 SkDebugf("text size = %.*s\n", textSizeEnd, sizeStart);
5172
5173 #StdOut
5174 text size = 12
5175 ##
5176
5177##
5178
Cary Clark2ade9972017-11-02 17:49:34 -04005179#SeeAlso SkPathEffect::toString SkMaskFilter::toString SkColorFilter::toString SkImageFilter::toString
Cary Clark8032b982017-07-28 11:04:54 -04005180
5181##
5182
5183# ------------------------------------------------------------------------------
5184
5185#Class SkPaint ##
5186
5187#Topic Paint ##
Cary Clark4855f782018-02-06 09:41:53 -05005188