blob: 6a40f752cc2fdff3f7680d276111abc5aa4651fe [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 ##
329
330##
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##
359
360##
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
396# ------------------------------------------------------------------------------
397
398#Method void flatten(SkWriteBuffer& buffer) const
399
Cary Clarkab2621d2018-01-30 10:08:57 -0500400#In Management
401#Line # serializes into a buffer ##
Cary Clark8032b982017-07-28 11:04:54 -0400402Serializes Paint into a buffer. A companion unflatten() call
403can reconstitute the paint at a later time.
404
405#Param buffer Write_Buffer receiving the flattened Paint data ##
406
Cary Clark61ca7c52018-01-02 11:34:14 -0500407# why is flatten() public?
Cary Clark4855f782018-02-06 09:41:53 -0500408#Bug 6172
Cary Clark8032b982017-07-28 11:04:54 -0400409
Cary Clark61ca7c52018-01-02 11:34:14 -0500410#NoExample
Cary Clark8032b982017-07-28 11:04:54 -0400411##
412
413##
414
415# ------------------------------------------------------------------------------
416
Mike Reede97e7922018-01-18 15:57:38 -0500417#Method bool unflatten(SkReadBuffer& buffer)
Cary Clark8032b982017-07-28 11:04:54 -0400418
Cary Clarkab2621d2018-01-30 10:08:57 -0500419#In Management
420#Line # populates from a serialized stream ##
Cary Clark8032b982017-07-28 11:04:54 -0400421Populates Paint, typically from a serialized stream, created by calling
422flatten() at an earlier time.
423
424SkReadBuffer class is not public, so unflatten() cannot be meaningfully called
425by the client.
426
Cary Clarkce101242017-09-01 15:51:02 -0400427#Param buffer serialized data describing Paint content ##
Cary Clark8032b982017-07-28 11:04:54 -0400428
Cary Clark5081eed2018-01-22 07:55:48 -0500429#Return false if the buffer contains invalid data ##
Mike Reede97e7922018-01-18 15:57:38 -0500430
Cary Clark8032b982017-07-28 11:04:54 -0400431# why is unflatten() public?
Cary Clark4855f782018-02-06 09:41:53 -0500432#Bug 6172
Cary Clark8032b982017-07-28 11:04:54 -0400433
434#NoExample
435##
436
Cary Clark2ade9972017-11-02 17:49:34 -0400437#SeeAlso SkReadBuffer
Cary Clark8032b982017-07-28 11:04:54 -0400438
439##
440
Cary Clark08895c42018-02-01 09:37:32 -0500441#Subtopic Management ##
Cary Clark8032b982017-07-28 11:04:54 -0400442
443# ------------------------------------------------------------------------------
Cary Clark08895c42018-02-01 09:37:32 -0500444#Subtopic Hinting
445#Line # glyph outline adjustment ##
Cary Clark8032b982017-07-28 11:04:54 -0400446
447#Enum Hinting
Cary Clark08895c42018-02-01 09:37:32 -0500448#Line # level of glyph outline adjustment ##
Cary Clark8032b982017-07-28 11:04:54 -0400449
450#Code
451 enum Hinting {
452 kNo_Hinting = 0,
453 kSlight_Hinting = 1,
454 kNormal_Hinting = 2,
Cary Clarkbad5ad72017-08-03 17:14:08 -0400455 kFull_Hinting = 3,
Cary Clark8032b982017-07-28 11:04:54 -0400456 };
457##
458
459Hinting adjusts the glyph outlines so that the shape provides a uniform
460look at a given point size on font engines that support it. Hinting may have a
461muted effect or no effect at all depending on the platform.
462
463The four levels roughly control corresponding features on platforms that use FreeType
464as the Font_Engine.
465
466#Const kNo_Hinting 0
467 Leaves glyph outlines unchanged from their native representation.
468 With FreeType, this is equivalent to the FT_LOAD_NO_HINTING
469 bit-field constant supplied to FT_Load_Glyph, which indicates that the vector
470 outline being loaded should not be fitted to the pixel grid but simply scaled
471 to 26.6 fractional pixels.
472##
473#Const kSlight_Hinting 1
474 Modifies glyph outlines minimally to improve constrast.
475 With FreeType, this is equivalent in spirit to the
476 FT_LOAD_TARGET_LIGHT value supplied to FT_Load_Glyph. It chooses a
477 lighter hinting algorithm for non-monochrome modes.
Cary Clarkce101242017-09-01 15:51:02 -0400478 Generated Glyphs may be fuzzy but better resemble their original shape.
Cary Clark8032b982017-07-28 11:04:54 -0400479##
480#Const kNormal_Hinting 2
481 Modifies glyph outlines to improve constrast. This is the default.
Cary Clark6fc50412017-09-21 12:31:06 -0400482 With FreeType, this supplies FT_LOAD_TARGET_NORMAL to FT_Load_Glyph,
Cary Clark8032b982017-07-28 11:04:54 -0400483 choosing the default hinting algorithm, which is optimized for standard
484 gray-level rendering.
485##
486#Const kFull_Hinting 3
Cary Clark6fc50412017-09-21 12:31:06 -0400487 Modifies glyph outlines for maxiumum constrast. With FreeType, this selects
488 FT_LOAD_TARGET_LCD or FT_LOAD_TARGET_LCD_V if kLCDRenderText_Flag is set.
489 FT_LOAD_TARGET_LCD is a variant of FT_LOAD_TARGET_NORMAL optimized for
490 horizontally decimated LCD displays; FT_LOAD_TARGET_LCD_V is a
Cary Clark8032b982017-07-28 11:04:54 -0400491 variant of FT_LOAD_TARGET_NORMAL optimized for vertically decimated LCD displays.
492##
493
494#Track
495#File SkFontHost_mac.cpp:1777,1806
496#Time 2013-03-03 07:16:29 +0000
Cary Clark4855f782018-02-06 09:41:53 -0500497#Bug 915
Cary Clark8032b982017-07-28 11:04:54 -0400498On OS_X and iOS, hinting controls whether Core_Graphics dilates the font outlines
499to account for LCD text. No hinting uses Core_Text gray scale output.
500Normal hinting uses Core_Text LCD output. If kLCDRenderText_Flag is clear,
501the LCD output is reduced to a single grayscale channel.
502#Track ##
503
504On Windows with DirectWrite, Hinting has no effect.
505
506Hinting defaults to kNormal_Hinting.
507Set SkPaintDefaults_Hinting at compile time to change the default setting.
508
509#ToDo add an illustration? linux running GM:typefacerendering is best for this
510 the hinting variations are every other character horizontally
511#ToDo ##
512
513#Enum ##
514
515#Method Hinting getHinting() const
516
Cary Clarkab2621d2018-01-30 10:08:57 -0500517#In Hinting
518#Line # returns Hinting, glyph outline adjustment level ##
Cary Clark8032b982017-07-28 11:04:54 -0400519 Returns level of glyph outline adjustment.
520
521 #Return one of: kNo_Hinting, kSlight_Hinting, kNormal_Hinting, kFull_Hinting ##
522
523 #Example
524 SkPaint paint;
525 SkDebugf("SkPaint::kNormal_Hinting %c= paint.getHinting()\n",
526 SkPaint::kNormal_Hinting == paint.getHinting() ? '=' : ':');
527
528 #StdOut
529 SkPaint::kNormal_Hinting == paint.getHinting()
530 ##
531 ##
532##
533
534#Method void setHinting(Hinting hintingLevel)
535
Cary Clarkab2621d2018-01-30 10:08:57 -0500536#In Hinting
537#Line # sets Hinting, glyph outline adjustment level ##
Cary Clark8032b982017-07-28 11:04:54 -0400538 Sets level of glyph outline adjustment.
539 Does not check for valid values of hintingLevel.
540
541 #Table
542 #Legend
543 # Hinting # value # effect on generated glyph outlines ##
544 ##
545 # kNo_Hinting # 0 # leaves glyph outlines unchanged from their native representation ##
Cary Clarkce101242017-09-01 15:51:02 -0400546 # kSlight_Hinting # 1 # modifies glyph outlines minimally to improve contrast ##
547 # kNormal_Hinting # 2 # modifies glyph outlines to improve contrast ##
548 # kFull_Hinting # 3 # modifies glyph outlines for maximum contrast ##
Cary Clark8032b982017-07-28 11:04:54 -0400549 ##
550
551 #Param hintingLevel one of: kNo_Hinting, kSlight_Hinting, kNormal_Hinting, kFull_Hinting ##
552
553 #Example
554 SkPaint paint1, paint2;
555 paint2.setHinting(SkPaint::kNormal_Hinting);
556 SkDebugf("paint1 %c= paint2\n", paint1 == paint2 ? '=' : ':');
557
558 #StdOut
559 paint1 == paint2
560 ##
561 ##
562##
563
Cary Clark08895c42018-02-01 09:37:32 -0500564#Subtopic Hinting ##
Cary Clark8032b982017-07-28 11:04:54 -0400565# ------------------------------------------------------------------------------
Cary Clark08895c42018-02-01 09:37:32 -0500566#Subtopic Flags
567#Line # attributes represented by single bits ##
Cary Clark8032b982017-07-28 11:04:54 -0400568
569#Enum Flags
Cary Clark08895c42018-02-01 09:37:32 -0500570#Line # values described by bits and masks ##
Cary Clark8032b982017-07-28 11:04:54 -0400571
572#Code
573 enum Flags {
574 kAntiAlias_Flag = 0x01,
575 kDither_Flag = 0x04,
576 kFakeBoldText_Flag = 0x20,
577 kLinearText_Flag = 0x40,
578 kSubpixelText_Flag = 0x80,
579 kDevKernText_Flag = 0x100,
580 kLCDRenderText_Flag = 0x200,
581 kEmbeddedBitmapText_Flag = 0x400,
582 kAutoHinting_Flag = 0x800,
583 kVerticalText_Flag = 0x1000,
584 kGenA8FromLCD_Flag = 0x2000,
585
586 kAllFlags = 0xFFFF,
587 };
588
589##
590
591The bit values stored in Flags.
592The default value for Flags, normally zero, can be changed at compile time
593with a custom definition of SkPaintDefaults_Flags.
594All flags can be read and written explicitly; Flags allows manipulating
595multiple settings at once.
596
597 #Const kAntiAlias_Flag 0x0001
598 mask for setting Anti-alias
599 ##
600 #Const kDither_Flag 0x0004
601 mask for setting Dither
602 ##
603
604 #Const kFakeBoldText_Flag 0x0020
605 mask for setting Fake_Bold
606 ##
607 #Const kLinearText_Flag 0x0040
608 mask for setting Linear_Text
609 ##
610 #Const kSubpixelText_Flag 0x0080
611 mask for setting Subpixel_Text
612 ##
613 #Const kDevKernText_Flag 0x0100
614 mask for setting Full_Hinting_Spacing
615 ##
616 #Const kLCDRenderText_Flag 0x0200
617 mask for setting LCD_Text
618 ##
619 #Const kEmbeddedBitmapText_Flag 0x0400
620 mask for setting Font_Embedded_Bitmaps
621 ##
622 #Const kAutoHinting_Flag 0x0800
623 mask for setting Automatic_Hinting
624 ##
625 #Const kVerticalText_Flag 0x1000
626 mask for setting Vertical_Text
627 ##
628 #Const kGenA8FromLCD_Flag 0x2000
629 #Private
630 Hack for GDI -- do not use if you can help it
631 ##
632 not intended for public use
633 ##
634 #Const kAllFlags 0xFFFF
635 mask of all Flags, including private flags and flags reserved for future use
636 ##
637
638Flags default to all flags clear, disabling the associated feature.
639
640#Enum ##
641
642#Enum ReserveFlags
Cary Clark4855f782018-02-06 09:41:53 -0500643#Deprecated soon
Cary Clark8032b982017-07-28 11:04:54 -0400644
Cary Clark4855f782018-02-06 09:41:53 -0500645Only valid for Android framework.
Cary Clark8032b982017-07-28 11:04:54 -0400646
647#Code
648 enum ReserveFlags {
649 kUnderlineText_ReserveFlag = 0x08,
650 kStrikeThruText_ReserveFlag = 0x10,
651 };
652##
653
Cary Clark4855f782018-02-06 09:41:53 -0500654#Const kUnderlineText_ReserveFlag 0x0008
655#Deprecated soon
656##
657#Const kStrikeThruText_ReserveFlag 0x0010
658#Deprecated soon
659##
660##
Cary Clark8032b982017-07-28 11:04:54 -0400661
662#Method uint32_t getFlags() const
663
Cary Clarkab2621d2018-01-30 10:08:57 -0500664#In Flags
665#Line # returns Flags stored in a bit field ##
Cary Clark8032b982017-07-28 11:04:54 -0400666Returns paint settings described by Flags. Each setting uses one
667bit, and can be tested with Flags members.
668
669#Return zero, one, or more bits described by Flags ##
670
671#Example
672 SkPaint paint;
673 paint.setAntiAlias(true);
674 SkDebugf("(SkPaint::kAntiAlias_Flag & paint.getFlags()) %c= 0\n",
675 SkPaint::kAntiAlias_Flag & paint.getFlags() ? '!' : '=');
676
677 #StdOut
678 (SkPaint::kAntiAlias_Flag & paint.getFlags()) != 0
679 ##
680##
681
682##
683
684#Method void setFlags(uint32_t flags)
685
Cary Clarkab2621d2018-01-30 10:08:57 -0500686#In Flags
687#Line # sets multiple Flags in a bit field ##
Cary Clark8032b982017-07-28 11:04:54 -0400688Replaces Flags with flags, the union of the Flags members.
689All Flags members may be cleared, or one or more may be set.
690
691#Param flags union of Flags for Paint ##
692
693#Example
694 SkPaint paint;
695 paint.setFlags((uint32_t) (SkPaint::kAntiAlias_Flag | SkPaint::kDither_Flag));
696 SkDebugf("paint.isAntiAlias()\n", paint.isAntiAlias() ? '!' : '=');
697 SkDebugf("paint.isDither()\n", paint.isDither() ? '!' : '=');
698
699 #StdOut
700 paint.isAntiAlias()
701 paint.isDither()
702 ##
703##
704
705##
706
Cary Clark08895c42018-02-01 09:37:32 -0500707#Subtopic Flags ##
Cary Clark8032b982017-07-28 11:04:54 -0400708# ------------------------------------------------------------------------------
Cary Clark08895c42018-02-01 09:37:32 -0500709#Subtopic Anti-alias
Cary Clark8032b982017-07-28 11:04:54 -0400710#Alias Anti-alias # permit hyphen in topic name, should probably not substitute hyphen with _
Cary Clark4855f782018-02-06 09:41:53 -0500711#In Related_Function
Cary Clarkab2621d2018-01-30 10:08:57 -0500712#Line # approximating coverage with transparency ##
Cary Clark8032b982017-07-28 11:04:54 -0400713
714Anti-alias drawing approximates partial pixel coverage with transparency.
715If kAntiAlias_Flag is clear, pixel centers contained by the shape edge are drawn opaque.
716If kAntiAlias_Flag is set, pixels are drawn with Color_Alpha equal to their coverage.
717
Cary Clarkce101242017-09-01 15:51:02 -0400718The rule for Aliased pixels is inconsistent across platforms. A shape edge
Cary Clark8032b982017-07-28 11:04:54 -0400719passing through the pixel center may, but is not required to, draw the pixel.
720
Cary Clarkce101242017-09-01 15:51:02 -0400721Raster_Engine draws Aliased pixels whose centers are on or to the right of the start of an
Cary Clark8032b982017-07-28 11:04:54 -0400722active Path edge, and whose center is to the left of the end of the active Path edge.
723
724#ToDo add illustration of raster pixels ##
725
Cary Clarkce101242017-09-01 15:51:02 -0400726A platform may only support Anti-aliased drawing. Some GPU-backed platforms use
727Supersampling to Anti-alias all drawing, and have no mechanism to selectively
728Alias.
Cary Clark8032b982017-07-28 11:04:54 -0400729
Cary Clarkce101242017-09-01 15:51:02 -0400730The amount of coverage computed for Anti-aliased pixels also varies across platforms.
Cary Clark8032b982017-07-28 11:04:54 -0400731
732Anti-alias is disabled by default.
733Anti-alias can be enabled by default by setting SkPaintDefaults_Flags to kAntiAlias_Flag
734at compile time.
735
Cary Clarkab2621d2018-01-30 10:08:57 -0500736#Example
Cary Clark8032b982017-07-28 11:04:54 -0400737 #Width 512
738 #Description
739 A red line is drawn with transparency on the edges to make it look smoother.
740 A blue line draws only where the pixel centers are contained.
Cary Clarkce101242017-09-01 15:51:02 -0400741 The lines are drawn into Bitmap, then drawn magnified to make the
742 Aliasing easier to see.
Cary Clark8032b982017-07-28 11:04:54 -0400743 ##
744
745 void draw(SkCanvas* canvas) {
746 SkBitmap bitmap;
747 bitmap.allocN32Pixels(50, 50);
748 SkCanvas offscreen(bitmap);
749 SkPaint paint;
750 paint.setStyle(SkPaint::kStroke_Style);
751 paint.setStrokeWidth(10);
752 for (bool antialias : { false, true }) {
753 paint.setColor(antialias ? SK_ColorRED : SK_ColorBLUE);
754 paint.setAntiAlias(antialias);
755 bitmap.eraseColor(0);
756 offscreen.drawLine(5, 5, 15, 30, paint);
757 canvas->drawLine(5, 5, 15, 30, paint);
758 canvas->save();
759 canvas->scale(10, 10);
760 canvas->drawBitmap(bitmap, antialias ? 12 : 0, 0);
761 canvas->restore();
762 canvas->translate(15, 0);
763 }
764 }
Cary Clarkab2621d2018-01-30 10:08:57 -0500765##
Cary Clark8032b982017-07-28 11:04:54 -0400766
767#Method bool isAntiAlias() const
Cary Clark78de7512018-02-07 07:27:09 -0500768#In Anti_alias
Cary Clarkab2621d2018-01-30 10:08:57 -0500769#Line # returns true if Anti-alias is set ##
Cary Clark8032b982017-07-28 11:04:54 -0400770
771 If true, pixels on the active edges of Path may be drawn with partial transparency.
772
773 Equivalent to getFlags masked with kAntiAlias_Flag.
774
775 #Return kAntiAlias_Flag state ##
776
777 #Example
778 SkPaint paint;
779 SkDebugf("paint.isAntiAlias() %c= !!(paint.getFlags() & SkPaint::kAntiAlias_Flag)\n",
780 paint.isAntiAlias() == !!(paint.getFlags() & SkPaint::kAntiAlias_Flag) ? '=' : '!');
781 paint.setAntiAlias(true);
782 SkDebugf("paint.isAntiAlias() %c= !!(paint.getFlags() & SkPaint::kAntiAlias_Flag)\n",
783 paint.isAntiAlias() == !!(paint.getFlags() & SkPaint::kAntiAlias_Flag) ? '=' : '!');
784
785 #StdOut
786 paint.isAntiAlias() == !!(paint.getFlags() & SkPaint::kAntiAlias_Flag)
787 paint.isAntiAlias() == !!(paint.getFlags() & SkPaint::kAntiAlias_Flag)
788 ##
789 ##
790##
791
792#Method void setAntiAlias(bool aa)
793
Cary Clark78de7512018-02-07 07:27:09 -0500794#In Anti_alias
Cary Clarkab2621d2018-01-30 10:08:57 -0500795#Line # sets or clears Anti-alias ##
Cary Clark8032b982017-07-28 11:04:54 -0400796 Requests, but does not require, that Path edge pixels draw opaque or with
797 partial transparency.
798
799 Sets kAntiAlias_Flag if aa is true.
800 Clears kAntiAlias_Flag if aa is false.
801
802 #Param aa setting for kAntiAlias_Flag ##
803
804 #Example
805 SkPaint paint1, paint2;
806 paint1.setAntiAlias(true);
807 paint2.setFlags(paint2.getFlags() | SkPaint::kAntiAlias_Flag);
808 SkDebugf("paint1 %c= paint2\n", paint1 == paint2 ? '=' : '!');
809
810 #StdOut
811 paint1 == paint2
812 ##
813 ##
814
815##
816
Cary Clarkf895a422018-02-27 09:54:21 -0500817#Subtopic Anti-alias ##
Cary Clark8032b982017-07-28 11:04:54 -0400818# ------------------------------------------------------------------------------
Cary Clark08895c42018-02-01 09:37:32 -0500819#Subtopic Dither
820#Line # distributing color error ##
Cary Clark8032b982017-07-28 11:04:54 -0400821
Cary Clarkce101242017-09-01 15:51:02 -0400822Dither increases fidelity by adjusting the color of adjacent pixels.
Cary Clark8032b982017-07-28 11:04:54 -0400823This can help to smooth color transitions and reducing banding in gradients.
824Dithering lessens visible banding from kRGB_565_SkColorType
825and kRGBA_8888_SkColorType gradients,
826and improves rendering into a kRGB_565_SkColorType Surface.
827
828Dithering is always enabled for linear gradients drawing into
829kRGB_565_SkColorType Surface and kRGBA_8888_SkColorType Surface.
830Dither cannot be enabled for kAlpha_8_SkColorType Surface and
831kRGBA_F16_SkColorType Surface.
832
833Dither is disabled by default.
834Dither can be enabled by default by setting SkPaintDefaults_Flags to kDither_Flag
835at compile time.
836
837Some platform implementations may ignore dithering. Set
838
839#Define SK_IGNORE_GPU_DITHER
840
841to ignore Dither on GPU_Surface.
842
843#Example
844#Description
845Dithering in the bottom half more closely approximates the requested color by
846alternating nearby colors from pixel to pixel.
847##
848void draw(SkCanvas* canvas) {
849 SkBitmap bm16;
850 bm16.allocPixels(SkImageInfo::Make(32, 32, kRGB_565_SkColorType, kOpaque_SkAlphaType));
851 SkCanvas c16(bm16);
852 SkPaint colorPaint;
853 for (auto dither : { false, true } ) {
854 colorPaint.setDither(dither);
855 for (auto colors : { 0xFF333333, 0xFF666666, 0xFF999999, 0xFFCCCCCC } ) {
856 for (auto mask : { 0xFFFF0000, 0xFF00FF00, 0xFF0000FF, 0xFFFFFFFF } ) {
857 colorPaint.setColor(colors & mask);
858 c16.drawRect({0, 0, 8, 4}, colorPaint);
859 c16.translate(8, 0);
860 }
861 c16.translate(-32, 4);
862 }
863 }
864 canvas->scale(8, 8);
865 canvas->drawBitmap(bm16, 0, 0);
866}
867##
868
869#Example
870#Description
871Dithering introduces subtle adjustments to color to smooth gradients.
872Drawing the gradient repeatedly with SkBlendMode::kPlus exaggerates the
873dither, making it easier to see.
874##
875void draw(SkCanvas* canvas) {
876 canvas->clear(0);
877 SkBitmap bm32;
878 bm32.allocPixels(SkImageInfo::Make(20, 10, kN32_SkColorType, kPremul_SkAlphaType));
879 SkCanvas c32(bm32);
880 SkPoint points[] = {{0, 0}, {20, 0}};
881 SkColor colors[] = {0xFF334455, 0xFF662211 };
882 SkPaint paint;
883 paint.setShader(SkGradientShader::MakeLinear(
884 points, colors, nullptr, SK_ARRAY_COUNT(colors),
885 SkShader::kClamp_TileMode, 0, nullptr));
886 paint.setDither(true);
887 c32.drawPaint(paint);
888 canvas->scale(12, 12);
889 canvas->drawBitmap(bm32, 0, 0);
890 paint.setBlendMode(SkBlendMode::kPlus);
891 canvas->drawBitmap(bm32, 0, 11, &paint);
892 canvas->drawBitmap(bm32, 0, 11, &paint);
893 canvas->drawBitmap(bm32, 0, 11, &paint);
894}
895##
896
897#Method bool isDither() const
898
Cary Clarkab2621d2018-01-30 10:08:57 -0500899#In Dither
900#Line # returns true if Dither is set ##
Cary Clark8032b982017-07-28 11:04:54 -0400901 If true, color error may be distributed to smooth color transition.
902
903 Equivalent to getFlags masked with kDither_Flag.
904
905 #Return kDither_Flag state ##
906
907 #Example
908 SkPaint paint;
909 SkDebugf("paint.isDither() %c= !!(paint.getFlags() & SkPaint::kDither_Flag)\n",
910 paint.isDither() == !!(paint.getFlags() & SkPaint::kDither_Flag) ? '=' : '!');
911 paint.setDither(true);
912 SkDebugf("paint.isDither() %c= !!(paint.getFlags() & SkPaint::kDither_Flag)\n",
913 paint.isDither() == !!(paint.getFlags() & SkPaint::kDither_Flag) ? '=' : '!');
914
915 #StdOut
916 paint.isDither() == !!(paint.getFlags() & SkPaint::kDither_Flag)
917 paint.isDither() == !!(paint.getFlags() & SkPaint::kDither_Flag)
918 ##
919 ##
920
921##
922
923#Method void setDither(bool dither)
924
Cary Clarkab2621d2018-01-30 10:08:57 -0500925#In Dither
926#Line # sets or clears Dither ##
Cary Clark8032b982017-07-28 11:04:54 -0400927 Requests, but does not require, to distribute color error.
928
929 Sets kDither_Flag if dither is true.
930 Clears kDither_Flag if dither is false.
931
932 #Param dither setting for kDither_Flag ##
933
934 #Example
935 SkPaint paint1, paint2;
936 paint1.setDither(true);
937 paint2.setFlags(paint2.getFlags() | SkPaint::kDither_Flag);
938 SkDebugf("paint1 %c= paint2\n", paint1 == paint2 ? '=' : '!');
939
940 #StdOut
941 paint1 == paint2
942 ##
943 ##
944
945 #SeeAlso kRGB_565_SkColorType
946
947##
948
949#SeeAlso Gradient Color_RGB-565
950
Cary Clark08895c42018-02-01 09:37:32 -0500951#Subtopic Dither ##
Cary Clark8032b982017-07-28 11:04:54 -0400952# ------------------------------------------------------------------------------
Cary Clark08895c42018-02-01 09:37:32 -0500953#Subtopic Device_Text
954#Line # increase precision of glyph position ##
Cary Clark8032b982017-07-28 11:04:54 -0400955
956LCD_Text and Subpixel_Text increase the precision of glyph position.
957
958When set, Flags kLCDRenderText_Flag takes advantage of the organization of Color_RGB stripes that
959create a color, and relies
Cary Clarkce101242017-09-01 15:51:02 -0400960on the small size of the stripe and visual perception to make the color fringing imperceptible.
Cary Clark8032b982017-07-28 11:04:54 -0400961LCD_Text can be enabled on devices that orient stripes horizontally or vertically, and that order
962the color components as Color_RGB or Color_RBG.
963
964Flags kSubpixelText_Flag uses the pixel transparency to represent a fractional offset.
965As the opaqueness
966of the color increases, the edge of the glyph appears to move towards the outside of the pixel.
967
968Either or both techniques can be enabled.
969kLCDRenderText_Flag and kSubpixelText_Flag are clear by default.
970LCD_Text or Subpixel_Text can be enabled by default by setting SkPaintDefaults_Flags to
971kLCDRenderText_Flag or kSubpixelText_Flag (or both) at compile time.
972
973#Example
974 #Description
975 Four commas are drawn normally and with combinations of LCD_Text and Subpixel_Text.
Cary Clarkce101242017-09-01 15:51:02 -0400976 When Subpixel_Text is disabled, the comma Glyphs are identical, but not evenly spaced.
977 When Subpixel_Text is enabled, the comma Glyphs are unique, but appear evenly spaced.
Cary Clark8032b982017-07-28 11:04:54 -0400978 ##
979
980 SkBitmap bitmap;
981 bitmap.allocN32Pixels(24, 33);
982 SkCanvas offscreen(bitmap);
983 offscreen.clear(SK_ColorWHITE);
984 SkPaint paint;
985 paint.setAntiAlias(true);
986 paint.setTextSize(20);
987 for (bool lcd : { false, true }) {
988 paint.setLCDRenderText(lcd);
989 for (bool subpixel : { false, true }) {
990 paint.setSubpixelText(subpixel);
991 offscreen.drawString(",,,,", 0, 4, paint);
992 offscreen.translate(0, 7);
993 }
994 }
995 canvas->drawBitmap(bitmap, 4, 12);
996 canvas->scale(9, 9);
997 canvas->drawBitmap(bitmap, 4, -1);
998##
Cary Clark08895c42018-02-01 09:37:32 -0500999#Subtopic Device_Text ##
Cary Clark8032b982017-07-28 11:04:54 -04001000
1001#Subtopic Linear_Text
Cary Clark08895c42018-02-01 09:37:32 -05001002#Alias Linear_Text
1003#Line # selects text rendering as Glyph or Path ##
Cary Clark8032b982017-07-28 11:04:54 -04001004
1005Linear_Text selects whether text is rendered as a Glyph or as a Path.
1006If kLinearText_Flag is set, it has the same effect as setting Hinting to kNormal_Hinting.
Cary Clarkd0530ba2017-09-14 11:25:39 -04001007If kLinearText_Flag is clear, it is the same as setting Hinting to kNo_Hinting.
Cary Clark8032b982017-07-28 11:04:54 -04001008
1009#Method bool isLinearText() const
1010
Cary Clark08895c42018-02-01 09:37:32 -05001011#Line # returns true if text is converted to Path ##
Cary Clarkab2621d2018-01-30 10:08:57 -05001012#In Linear_Text
Cary Clark8032b982017-07-28 11:04:54 -04001013 If true, text is converted to Path before drawing and measuring.
1014
1015 Equivalent to getFlags masked with kLinearText_Flag.
1016
1017 #Return kLinearText_Flag state ##
1018
1019 #Example
1020 #Height 128
1021 void draw(SkCanvas* canvas) {
1022 SkPaint paint;
1023 paint.setAntiAlias(true);
1024 const char testStr[] = "xxxx xxxx";
1025 for (auto linearText : { false, true } ) {
1026 paint.setLinearText(linearText);
1027 paint.setTextSize(24);
1028 canvas->drawString(paint.isLinearText() ? "linear" : "hinted", 128, 30, paint);
1029 for (SkScalar textSize = 8; textSize < 30; textSize *= 1.22f) {
1030 paint.setTextSize(textSize);
1031 canvas->translate(0, textSize);
1032 canvas->drawString(testStr, 10, 0, paint);
1033 }
1034 }
1035 }
1036 ##
1037
1038 #SeeAlso setLinearText Hinting
1039##
1040
1041#Method void setLinearText(bool linearText)
1042
Cary Clark08895c42018-02-01 09:37:32 -05001043#Line # converts to Path before draw or measure ##
Cary Clarkab2621d2018-01-30 10:08:57 -05001044#In Linear_Text
Cary Clark8032b982017-07-28 11:04:54 -04001045 If true, text is converted to Path before drawing and measuring.
1046 By default, kLinearText_Flag is clear.
1047
1048 Sets kLinearText_Flag if linearText is true.
1049 Clears kLinearText_Flag if linearText is false.
1050
1051 #Param linearText setting for kLinearText_Flag ##
1052
1053 #Example
1054 #Height 128
1055 void draw(SkCanvas* canvas) {
1056 SkPaint paint;
1057 paint.setAntiAlias(true);
1058 const char testStr[] = "abcd efgh";
1059 for (int textSize : { 12, 24 } ) {
1060 paint.setTextSize(textSize);
1061 for (auto linearText : { false, true } ) {
1062 paint.setLinearText(linearText);
1063 SkString width;
1064 width.appendScalar(paint.measureText(testStr, SK_ARRAY_COUNT(testStr), nullptr));
1065 canvas->translate(0, textSize + 4);
1066 canvas->drawString(testStr, 10, 0, paint);
1067 canvas->drawString(width, 128, 0, paint);
1068 }
1069 }
1070 }
1071 ##
1072
1073 #SeeAlso isLinearText Hinting
1074##
1075
Cary Clark08895c42018-02-01 09:37:32 -05001076#Subtopic Linear_Text ##
Cary Clark8032b982017-07-28 11:04:54 -04001077
1078#Subtopic Subpixel_Text
Cary Clark08895c42018-02-01 09:37:32 -05001079#Alias Subpixel_Text
1080#Line # uses pixel transparency to represent fractional offset ##
Cary Clark8032b982017-07-28 11:04:54 -04001081
1082Flags kSubpixelText_Flag uses the pixel transparency to represent a fractional offset.
1083As the opaqueness
1084of the color increases, the edge of the glyph appears to move towards the outside of the pixel.
1085
1086#Method bool isSubpixelText() const
1087
Cary Clarkab2621d2018-01-30 10:08:57 -05001088#In Subpixel_Text
1089#Line # returns true if Subpixel_Text is set ##
Cary Clarkce101242017-09-01 15:51:02 -04001090 If true, Glyphs at different sub-pixel positions may differ on pixel edge coverage.
Cary Clark8032b982017-07-28 11:04:54 -04001091
1092 Equivalent to getFlags masked with kSubpixelText_Flag.
1093
1094 #Return kSubpixelText_Flag state ##
1095
1096 #Example
1097SkPaint paint;
1098SkDebugf("paint.isSubpixelText() %c= !!(paint.getFlags() & SkPaint::kSubpixelText_Flag)\n",
1099 paint.isSubpixelText() == !!(paint.getFlags() & SkPaint::kSubpixelText_Flag) ? '=' : '!');
1100paint.setSubpixelText(true);
1101SkDebugf("paint.isSubpixelText() %c= !!(paint.getFlags() & SkPaint::kSubpixelText_Flag)\n",
1102 paint.isSubpixelText() == !!(paint.getFlags() & SkPaint::kSubpixelText_Flag) ? '=' : '!');
1103
1104 #StdOut
1105 paint.isSubpixelText() == !!(paint.getFlags() & SkPaint::kSubpixelText_Flag)
1106 paint.isSubpixelText() == !!(paint.getFlags() & SkPaint::kSubpixelText_Flag)
1107 ##
1108 ##
1109
1110##
1111
1112#Method void setSubpixelText(bool subpixelText)
1113
Cary Clarkab2621d2018-01-30 10:08:57 -05001114#In Subpixel_Text
1115#Line # sets or clears Subpixel_Text ##
Cary Clarkce101242017-09-01 15:51:02 -04001116 Requests, but does not require, that Glyphs respect sub-pixel positioning.
Cary Clark8032b982017-07-28 11:04:54 -04001117
1118 Sets kSubpixelText_Flag if subpixelText is true.
1119 Clears kSubpixelText_Flag if subpixelText is false.
1120
1121 #Param subpixelText setting for kSubpixelText_Flag ##
1122
1123 #Example
1124 SkPaint paint1, paint2;
1125 paint1.setSubpixelText(true);
1126 paint2.setFlags(paint2.getFlags() | SkPaint::kSubpixelText_Flag);
1127 SkDebugf("paint1 %c= paint2\n", paint1 == paint2 ? '=' : '!');
1128
1129 #StdOut
1130 paint1 == paint2
1131 ##
1132 ##
1133
1134##
1135
Cary Clark08895c42018-02-01 09:37:32 -05001136#Subtopic Subpixel_Text ##
Cary Clark8032b982017-07-28 11:04:54 -04001137
1138#Subtopic LCD_Text
Cary Clarkc68ba1d2018-02-20 10:35:29 -05001139#Substitute LCD text
Cary Clark08895c42018-02-01 09:37:32 -05001140#Line # text relying on the order of Color_RGB stripes ##
Cary Clark8032b982017-07-28 11:04:54 -04001141#Alias LCD_Text # makes this a top level name, since it is under subtopic Device_Text
1142
1143When set, Flags kLCDRenderText_Flag takes advantage of the organization of Color_RGB stripes that
1144create a color, and relies
Cary Clarkce101242017-09-01 15:51:02 -04001145on the small size of the stripe and visual perception to make the color fringing imperceptible.
Cary Clark8032b982017-07-28 11:04:54 -04001146LCD_Text can be enabled on devices that orient stripes horizontally or vertically, and that order
1147the color components as Color_RGB or Color_RBG.
1148
1149#Method bool isLCDRenderText() const
1150
Cary Clarkab2621d2018-01-30 10:08:57 -05001151#In LCD_Text
1152#Line # returns true if LCD_Text is set ##
Cary Clarkce101242017-09-01 15:51:02 -04001153 If true, Glyphs may use LCD striping to improve glyph edges.
Cary Clark8032b982017-07-28 11:04:54 -04001154
1155 Returns true if Flags kLCDRenderText_Flag is set.
1156
1157 #Return kLCDRenderText_Flag state ##
1158
1159 #Example
1160SkPaint paint;
1161SkDebugf("paint.isLCDRenderText() %c= !!(paint.getFlags() & SkPaint::kLCDRenderText_Flag)\n",
1162 paint.isLCDRenderText() == !!(paint.getFlags() & SkPaint::kLCDRenderText_Flag) ? '=' : '!');
1163paint.setLCDRenderText(true);
1164SkDebugf("paint.isLCDRenderText() %c= !!(paint.getFlags() & SkPaint::kLCDRenderText_Flag)\n",
1165 paint.isLCDRenderText() == !!(paint.getFlags() & SkPaint::kLCDRenderText_Flag) ? '=' : '!');
1166
1167 #StdOut
1168 paint.isLCDRenderText() == !!(paint.getFlags() & SkPaint::kLCDRenderText_Flag)
1169 paint.isLCDRenderText() == !!(paint.getFlags() & SkPaint::kLCDRenderText_Flag)
1170 ##
1171 ##
1172
1173##
1174
1175#Method void setLCDRenderText(bool lcdText)
1176
Cary Clarkab2621d2018-01-30 10:08:57 -05001177#In LCD_Text
1178#Line # sets or clears LCD_Text ##
Cary Clarkce101242017-09-01 15:51:02 -04001179 Requests, but does not require, that Glyphs use LCD striping for glyph edges.
Cary Clark8032b982017-07-28 11:04:54 -04001180
1181 Sets kLCDRenderText_Flag if lcdText is true.
1182 Clears kLCDRenderText_Flag if lcdText is false.
1183
1184 #Param lcdText setting for kLCDRenderText_Flag ##
1185
1186 #Example
1187 SkPaint paint1, paint2;
1188 paint1.setLCDRenderText(true);
1189 paint2.setFlags(paint2.getFlags() | SkPaint::kLCDRenderText_Flag);
1190 SkDebugf("paint1 %c= paint2\n", paint1 == paint2 ? '=' : '!');
1191
1192 #StdOut
1193 paint1 == paint2
1194 ##
1195 ##
1196
1197
1198##
1199
Cary Clark08895c42018-02-01 09:37:32 -05001200#Subtopic LCD_Text ##
Cary Clark8032b982017-07-28 11:04:54 -04001201
Cary Clark8032b982017-07-28 11:04:54 -04001202# ------------------------------------------------------------------------------
Cary Clark08895c42018-02-01 09:37:32 -05001203#Subtopic Font_Embedded_Bitmaps
1204#Line # custom sized bitmap Glyphs ##
Cary Clark8032b982017-07-28 11:04:54 -04001205#Alias Font_Embedded_Bitmaps # long-winded enough, alias so I don't type Paint_Font_...
1206
Cary Clarkce101242017-09-01 15:51:02 -04001207Font_Embedded_Bitmaps allows selecting custom sized bitmap Glyphs.
Cary Clark8032b982017-07-28 11:04:54 -04001208Flags kEmbeddedBitmapText_Flag when set chooses an embedded bitmap glyph over an outline contained
1209in a font if the platform supports this option.
1210
1211FreeType selects the bitmap glyph if available when kEmbeddedBitmapText_Flag is set, and selects
1212the outline glyph if kEmbeddedBitmapText_Flag is clear.
1213Windows may select the bitmap glyph but is not required to do so.
1214OS_X and iOS do not support this option.
1215
1216Font_Embedded_Bitmaps is disabled by default.
1217Font_Embedded_Bitmaps can be enabled by default by setting SkPaintDefaults_Flags to
1218kEmbeddedBitmapText_Flag at compile time.
1219
1220#Example
1221 #ToDo image will only output on Ubuntu ... how to handle that in fiddle? ##
1222 #Platform !fiddle
1223 #Description
Cary Clarkce101242017-09-01 15:51:02 -04001224 The "hintgasp" TrueType font in the Skia resources/fonts directory
1225 includes an embedded bitmap Glyph at odd font sizes. This example works
1226 on platforms that use FreeType as their Font_Engine.
1227 Windows may, but is not required to, return a bitmap glyph if
1228 kEmbeddedBitmapText_Flag is set.
Cary Clark8032b982017-07-28 11:04:54 -04001229 ##
1230 #Image embeddedbitmap.png
1231
1232 SkBitmap bitmap;
1233 bitmap.allocN32Pixels(30, 15);
1234 bitmap.eraseColor(0);
1235 SkCanvas offscreen(bitmap);
1236 SkPaint paint;
1237 paint.setAntiAlias(true);
1238 paint.setTextSize(13);
Hal Canary53e5e7d2017-12-08 14:25:14 -05001239 paint.setTypeface(MakeResourceAsTypeface("fonts/hintgasp.ttf"));
Cary Clark8032b982017-07-28 11:04:54 -04001240 for (bool embedded : { false, true}) {
1241 paint.setEmbeddedBitmapText(embedded);
1242 offscreen.drawString("A", embedded ? 5 : 15, 15, paint);
1243 }
1244 canvas->drawBitmap(bitmap, 0, 0);
1245 canvas->scale(10, 10);
1246 canvas->drawBitmap(bitmap, -2, 1);
1247##
1248
1249#Method bool isEmbeddedBitmapText() const
1250
Cary Clarkab2621d2018-01-30 10:08:57 -05001251#In Font_Embedded_Bitmaps
1252#Line # returns true if Font_Embedded_Bitmaps is set ##
Cary Clarkce101242017-09-01 15:51:02 -04001253 If true, Font_Engine may return Glyphs from font bitmaps instead of from outlines.
Cary Clark8032b982017-07-28 11:04:54 -04001254
1255 Equivalent to getFlags masked with kEmbeddedBitmapText_Flag.
1256
1257 #Return kEmbeddedBitmapText_Flag state ##
1258
1259 #Example
1260 SkPaint paint;
1261 SkDebugf("paint.isEmbeddedBitmapText() %c="
1262 " !!(paint.getFlags() & SkPaint::kEmbeddedBitmapText_Flag)\n",
1263 paint.isEmbeddedBitmapText() ==
1264 !!(paint.getFlags() & SkPaint::kEmbeddedBitmapText_Flag) ? '=' : '!');
1265 paint.setEmbeddedBitmapText(true);
1266 SkDebugf("paint.isEmbeddedBitmapText() %c="
1267 " !!(paint.getFlags() & SkPaint::kEmbeddedBitmapText_Flag)\n",
1268 paint.isEmbeddedBitmapText() ==
1269 !!(paint.getFlags() & SkPaint::kEmbeddedBitmapText_Flag) ? '=' : '!');
1270
1271 #StdOut
1272 paint.isEmbeddedBitmapText() == !!(paint.getFlags() & SkPaint::kEmbeddedBitmapText_Flag)
1273 paint.isEmbeddedBitmapText() == !!(paint.getFlags() & SkPaint::kEmbeddedBitmapText_Flag)
1274 ##
1275 ##
1276
1277##
1278
1279#Method void setEmbeddedBitmapText(bool useEmbeddedBitmapText)
1280
Cary Clarkab2621d2018-01-30 10:08:57 -05001281#In Font_Embedded_Bitmaps
1282#Line # sets or clears Font_Embedded_Bitmaps ##
Cary Clark8032b982017-07-28 11:04:54 -04001283 Requests, but does not require, to use bitmaps in fonts instead of outlines.
1284
1285 Sets kEmbeddedBitmapText_Flag if useEmbeddedBitmapText is true.
1286 Clears kEmbeddedBitmapText_Flag if useEmbeddedBitmapText is false.
1287
1288 #Param useEmbeddedBitmapText setting for kEmbeddedBitmapText_Flag ##
1289
1290 #Example
1291 SkPaint paint1, paint2;
1292 paint1.setEmbeddedBitmapText(true);
1293 paint2.setFlags(paint2.getFlags() | SkPaint::kEmbeddedBitmapText_Flag);
1294 SkDebugf("paint1 %c= paint2\n", paint1 == paint2 ? '=' : '!');
1295
1296 #StdOut
1297 paint1 == paint2
1298 ##
1299 ##
1300
1301##
1302
Cary Clark08895c42018-02-01 09:37:32 -05001303#Subtopic Font_Embedded_Bitmaps ##
Cary Clark8032b982017-07-28 11:04:54 -04001304# ------------------------------------------------------------------------------
Cary Clark08895c42018-02-01 09:37:32 -05001305#Subtopic Automatic_Hinting
1306#Line # always adjust glyph paths ##
Cary Clark8032b982017-07-28 11:04:54 -04001307#Substitute auto-hinting
1308
1309If Hinting is set to kNormal_Hinting or kFull_Hinting, Automatic_Hinting
Cary Clarkce101242017-09-01 15:51:02 -04001310instructs the Font_Manager to always hint Glyphs.
Cary Clark8032b982017-07-28 11:04:54 -04001311Automatic_Hinting has no effect if Hinting is set to kNo_Hinting or
1312kSlight_Hinting.
1313
1314Automatic_Hinting only affects platforms that use FreeType as the Font_Manager.
1315
1316#Method bool isAutohinted() const
1317
Cary Clarkab2621d2018-01-30 10:08:57 -05001318#In Automatic_Hinting
1319#Line # returns true if Glyphs are always hinted ##
Cary Clark8032b982017-07-28 11:04:54 -04001320 If true, and if Hinting is set to kNormal_Hinting or kFull_Hinting, and if
1321 platform uses FreeType as the Font_Manager, instruct the Font_Manager to always hint
Cary Clarkce101242017-09-01 15:51:02 -04001322 Glyphs.
Cary Clark8032b982017-07-28 11:04:54 -04001323
1324 Equivalent to getFlags masked with kAutoHinting_Flag.
1325
1326 #Return kAutoHinting_Flag state ##
1327
1328 #Example
1329 SkPaint paint;
1330 for (auto forceAutoHinting : { false, true} ) {
1331 paint.setAutohinted(forceAutoHinting);
1332 SkDebugf("paint.isAutohinted() %c="
1333 " !!(paint.getFlags() & SkPaint::kAutoHinting_Flag)\n",
1334 paint.isAutohinted() ==
1335 !!(paint.getFlags() & SkPaint::kAutoHinting_Flag) ? '=' : '!');
1336 }
1337 #StdOut
1338 paint.isAutohinted() == !!(paint.getFlags() & SkPaint::kAutoHinting_Flag)
1339 paint.isAutohinted() == !!(paint.getFlags() & SkPaint::kAutoHinting_Flag)
1340 ##
1341 ##
1342
1343 #SeeAlso setAutohinted Hinting
1344
1345##
1346
1347#Method void setAutohinted(bool useAutohinter)
1348
Cary Clarkab2621d2018-01-30 10:08:57 -05001349#In Automatic_Hinting
1350#Line # sets Glyphs to always be hinted ##
Cary Clark8032b982017-07-28 11:04:54 -04001351 If Hinting is set to kNormal_Hinting or kFull_Hinting and useAutohinter is set,
Cary Clarkce101242017-09-01 15:51:02 -04001352 instruct the Font_Manager to always hint Glyphs.
Cary Clark8032b982017-07-28 11:04:54 -04001353 Automatic_Hinting has no effect if Hinting is set to kNo_Hinting or
1354 kSlight_Hinting.
1355
Cary Clark579985c2017-07-31 11:48:27 -04001356 Only affects platforms that use FreeType as the Font_Manager.
Cary Clark8032b982017-07-28 11:04:54 -04001357
1358 Sets kAutoHinting_Flag if useAutohinter is true.
1359 Clears kAutoHinting_Flag if useAutohinter is false.
1360
1361 #Param useAutohinter setting for kAutoHinting_Flag ##
1362
1363 #Example
1364 void draw(SkCanvas* canvas) {
1365 SkPaint paint;
1366 paint.setAntiAlias(true);
1367 const char testStr[] = "xxxx xxxx";
1368 for (auto forceAutoHinting : { false, true} ) {
1369 paint.setAutohinted(forceAutoHinting);
1370 paint.setTextSize(24);
1371 canvas->drawString(paint.isAutohinted() ? "auto-hinted" : "default", 108, 30, paint);
1372 for (SkScalar textSize = 8; textSize < 30; textSize *= 1.22f) {
1373 paint.setTextSize(textSize);
1374 canvas->translate(0, textSize);
1375 canvas->drawString(testStr, 10, 0, paint);
1376 }
1377 }
1378 }
1379 ##
1380
1381 #SeeAlso isAutohinted Hinting
1382
1383##
1384
Cary Clark08895c42018-02-01 09:37:32 -05001385#Subtopic Automatic_Hinting ##
Cary Clark8032b982017-07-28 11:04:54 -04001386# ------------------------------------------------------------------------------
Cary Clark08895c42018-02-01 09:37:32 -05001387#Subtopic Vertical_Text
1388#Line # orient text from top to bottom ##
Cary Clark8032b982017-07-28 11:04:54 -04001389
1390Text may be drawn by positioning each glyph, or by positioning the first glyph and
Cary Clarkce101242017-09-01 15:51:02 -04001391using Font_Advance to position subsequent Glyphs. By default, each successive glyph
1392is positioned to the right of the preceding glyph. Vertical_Text sets successive
1393Glyphs to position below the preceding glyph.
Cary Clark8032b982017-07-28 11:04:54 -04001394
Cary Clarkce101242017-09-01 15:51:02 -04001395Skia can translate text character codes as a series of Glyphs, but does not implement
Cary Clark8032b982017-07-28 11:04:54 -04001396font substitution,
Cary Clarkce101242017-09-01 15:51:02 -04001397textual substitution, line layout, or contextual spacing like Kerning pairs. Use
Cary Clark6fc50412017-09-21 12:31:06 -04001398a text shaping engine like
1399#A HarfBuzz # http://harfbuzz.org/ ##
1400 to translate text runs
Cary Clark8032b982017-07-28 11:04:54 -04001401into glyph series.
1402
1403Vertical_Text is clear if text is drawn left to right or set if drawn from top to bottom.
1404
1405Flags kVerticalText_Flag if clear draws text left to right.
1406Flags kVerticalText_Flag if set draws text top to bottom.
1407
1408Vertical_Text is clear by default.
1409Vertical_Text can be set by default by setting SkPaintDefaults_Flags to
1410kVerticalText_Flag at compile time.
1411
1412#Example
1413
1414void draw(SkCanvas* canvas) {
1415 SkPaint paint;
1416 paint.setAntiAlias(true);
1417 paint.setTextSize(50);
1418 for (bool vertical : { false, true } ) {
1419 paint.setVerticalText(vertical);
1420 canvas->drawString("aAlL", 25, 50, paint);
1421 }
1422}
1423
1424##
1425
1426#Method bool isVerticalText() const
1427
Cary Clarkab2621d2018-01-30 10:08:57 -05001428#In Vertical_Text
1429#Line # returns true if Vertical_Text is set ##
Cary Clarkce101242017-09-01 15:51:02 -04001430 If true, Glyphs are drawn top to bottom instead of left to right.
Cary Clark8032b982017-07-28 11:04:54 -04001431
1432 Equivalent to getFlags masked with kVerticalText_Flag.
1433
1434 #Return kVerticalText_Flag state ##
1435
1436 #Example
1437 SkPaint paint;
1438 SkDebugf("paint.isVerticalText() %c= !!(paint.getFlags() & SkPaint::kVerticalText_Flag)\n",
1439 paint.isVerticalText() == !!(paint.getFlags() & SkPaint::kVerticalText_Flag) ? '=' : '!');
1440 paint.setVerticalText(true);
1441 SkDebugf("paint.isVerticalText() %c= !!(paint.getFlags() & SkPaint::kVerticalText_Flag)\n",
1442 paint.isVerticalText() == !!(paint.getFlags() & SkPaint::kVerticalText_Flag) ? '=' : '!');
1443
1444 #StdOut
1445 paint.isVerticalText() == !!(paint.getFlags() & SkPaint::kVerticalText_Flag)
1446 paint.isVerticalText() == !!(paint.getFlags() & SkPaint::kVerticalText_Flag)
1447 ##
1448 ##
1449
1450##
1451
1452#Method void setVerticalText(bool verticalText)
1453
Cary Clarkab2621d2018-01-30 10:08:57 -05001454#In Vertical_Text
1455#Line # sets or clears Vertical_Text ##
Cary Clark8032b982017-07-28 11:04:54 -04001456 If true, text advance positions the next glyph below the previous glyph instead of to the
1457 right of previous glyph.
1458
1459 Sets kVerticalText_Flag if vertical is true.
1460 Clears kVerticalText_Flag if vertical is false.
1461
1462 #Param verticalText setting for kVerticalText_Flag ##
1463
1464 #Example
1465 SkPaint paint1, paint2;
1466 paint1.setVerticalText(true);
1467 paint2.setFlags(paint2.getFlags() | SkPaint::kVerticalText_Flag);
1468 SkDebugf("paint1 %c= paint2\n", paint1 == paint2 ? '=' : '!');
1469
1470 #StdOut
1471 paint1 == paint2
1472 ##
1473 ##
1474
1475##
1476
Cary Clark08895c42018-02-01 09:37:32 -05001477#Subtopic Vertical_Text ##
Cary Clark8032b982017-07-28 11:04:54 -04001478# ------------------------------------------------------------------------------
1479
Cary Clark08895c42018-02-01 09:37:32 -05001480#Subtopic Fake_Bold
1481#Line # approximate font styles ##
Cary Clark8032b982017-07-28 11:04:54 -04001482
1483Fake_Bold approximates the bold font style accompanying a normal font when a bold font face
1484is not available. Skia does not provide font substitution; it is up to the client to find the
Cary Clarkbc5697d2017-10-04 14:31:33 -04001485bold font face using the platform Font_Manager.
Cary Clark8032b982017-07-28 11:04:54 -04001486
1487Use Text_Skew_X to approximate an italic font style when the italic font face
1488is not available.
1489
Cary Clarkce101242017-09-01 15:51:02 -04001490A FreeType based port may define SK_USE_FREETYPE_EMBOLDEN at compile time to direct
1491the font engine to create the bold Glyphs. Otherwise, the extra bold is computed
Cary Clark8032b982017-07-28 11:04:54 -04001492by increasing the stroke width and setting the Style to kStrokeAndFill_Style as needed.
1493
1494Fake_Bold is disabled by default.
1495
1496#Example
1497#Height 128
1498void draw(SkCanvas* canvas) {
1499 SkPaint paint;
1500 paint.setAntiAlias(true);
1501 paint.setTextSize(40);
1502 canvas->drawString("OjYy_-", 10, 35, paint);
1503 paint.setFakeBoldText(true);
1504 canvas->drawString("OjYy_-", 10, 75, paint);
1505 // create a custom fake bold by varying the stroke width
1506 paint.setFakeBoldText(false);
1507 paint.setStyle(SkPaint::kStrokeAndFill_Style);
1508 paint.setStrokeWidth(40.f / 48);
1509 canvas->drawString("OjYy_-", 10, 115, paint);
1510}
1511##
1512
1513#Method bool isFakeBoldText() const
1514
Cary Clarkab2621d2018-01-30 10:08:57 -05001515#In Fake_Bold
1516#Line # returns true if Fake_Bold is set ##
Cary Clark8032b982017-07-28 11:04:54 -04001517 If true, approximate bold by increasing the stroke width when creating glyph bitmaps
1518 from outlines.
1519
1520 Equivalent to getFlags masked with kFakeBoldText_Flag.
1521
1522 #Return kFakeBoldText_Flag state ##
1523
1524 #Example
1525 SkPaint paint;
1526 SkDebugf("paint.isFakeBoldText() %c= !!(paint.getFlags() & SkPaint::kFakeBoldText_Flag)\n",
1527 paint.isFakeBoldText() == !!(paint.getFlags() & SkPaint::kFakeBoldText_Flag) ? '=' : '!');
1528 paint.setFakeBoldText(true);
1529 SkDebugf("paint.isFakeBoldText() %c= !!(paint.getFlags() & SkPaint::kFakeBoldText_Flag)\n",
1530 paint.isFakeBoldText() == !!(paint.getFlags() & SkPaint::kFakeBoldText_Flag) ? '=' : '!');
1531
1532 #StdOut
1533 paint.isFakeBoldText() == !!(paint.getFlags() & SkPaint::kFakeBoldText_Flag)
1534 paint.isFakeBoldText() == !!(paint.getFlags() & SkPaint::kFakeBoldText_Flag)
1535 ##
1536 ##
1537
1538##
1539
1540#Method void setFakeBoldText(bool fakeBoldText)
1541
Cary Clarkab2621d2018-01-30 10:08:57 -05001542#In Fake_Bold
1543#Line # sets or clears Fake_Bold ##
Cary Clarkce101242017-09-01 15:51:02 -04001544 Use increased stroke width when creating glyph bitmaps to approximate a bold typeface.
Cary Clark8032b982017-07-28 11:04:54 -04001545
1546 Sets kFakeBoldText_Flag if fakeBoldText is true.
1547 Clears kFakeBoldText_Flag if fakeBoldText is false.
1548
1549 #Param fakeBoldText setting for kFakeBoldText_Flag ##
1550
1551 #Example
1552 SkPaint paint1, paint2;
1553 paint1.setFakeBoldText(true);
1554 paint2.setFlags(paint2.getFlags() | SkPaint::kFakeBoldText_Flag);
1555 SkDebugf("paint1 %c= paint2\n", paint1 == paint2 ? '=' : '!');
1556
1557 #StdOut
1558 paint1 == paint2
1559 ##
1560 ##
1561
1562##
1563
Cary Clark08895c42018-02-01 09:37:32 -05001564#Subtopic Fake_Bold ##
Cary Clark8032b982017-07-28 11:04:54 -04001565
1566# ------------------------------------------------------------------------------
Cary Clark08895c42018-02-01 09:37:32 -05001567#Subtopic Full_Hinting_Spacing
1568#Line # glyph spacing affected by hinting ##
Cary Clark8032b982017-07-28 11:04:54 -04001569#Alias Full_Hinting_Spacing # long winded enough -- maybe things with two underscores auto-aliased?
1570
Cary Clarkce101242017-09-01 15:51:02 -04001571if Hinting is set to kFull_Hinting, Full_Hinting_Spacing adjusts the character
1572spacing by the difference of the hinted and Unhinted Left_Side_Bearing and
1573Right_Side_Bearing. Full_Hinting_Spacing only applies to platforms that use
1574FreeType as their Font_Engine.
Cary Clark8032b982017-07-28 11:04:54 -04001575
Cary Clarkce101242017-09-01 15:51:02 -04001576Full_Hinting_Spacing is not related to text Kerning, where the space between
Cary Clarkbc5697d2017-10-04 14:31:33 -04001577a specific pair of characters is adjusted using data in the font Kerning tables.
Cary Clark8032b982017-07-28 11:04:54 -04001578
1579#Method bool isDevKernText() const
1580
Cary Clarkab2621d2018-01-30 10:08:57 -05001581#In Full_Hinting_Spacing
1582#Line # returns true if Full_Hinting_Spacing is set ##
Cary Clark8032b982017-07-28 11:04:54 -04001583 Returns if character spacing may be adjusted by the hinting difference.
1584
1585 Equivalent to getFlags masked with kDevKernText_Flag.
1586
1587 #Return kDevKernText_Flag state ##
1588
1589 #Example
1590 SkPaint paint;
1591 SkDebugf("paint.isDevKernText() %c= !!(paint.getFlags() & SkPaint::kDevKernText_Flag)\n",
1592 paint.isDevKernText() == !!(paint.getFlags() & SkPaint::kDevKernText_Flag) ? '=' : '!');
1593 paint.setDevKernText(true);
1594 SkDebugf("paint.isDevKernText() %c= !!(paint.getFlags() & SkPaint::kDevKernText_Flag)\n",
1595 paint.isDevKernText() == !!(paint.getFlags() & SkPaint::kDevKernText_Flag) ? '=' : '!');
1596 ##
1597
1598##
1599
1600#Method void setDevKernText(bool devKernText)
1601
Cary Clarkab2621d2018-01-30 10:08:57 -05001602#In Full_Hinting_Spacing
1603#Line # sets or clears Full_Hinting_Spacing ##
Cary Clark8032b982017-07-28 11:04:54 -04001604 Requests, but does not require, to use hinting to adjust glyph spacing.
1605
1606 Sets kDevKernText_Flag if devKernText is true.
1607 Clears kDevKernText_Flag if devKernText is false.
1608
1609 #Param devKernText setting for devKernText ##
1610
1611 #Example
1612 SkPaint paint1, paint2;
1613 paint1.setDevKernText(true);
1614 paint2.setFlags(paint2.getFlags() | SkPaint::kDevKernText_Flag);
1615 SkDebugf("paint1 %c= paint2\n", paint1 == paint2 ? '=' : '!');
1616
1617 #StdOut
1618 paint1 == paint2
1619 ##
1620 ##
1621
1622##
1623
Cary Clark08895c42018-02-01 09:37:32 -05001624#Subtopic Full_Hinting_Spacing ##
Cary Clark8032b982017-07-28 11:04:54 -04001625# ------------------------------------------------------------------------------
Cary Clark08895c42018-02-01 09:37:32 -05001626#Subtopic Filter_Quality_Methods
1627#Line # get and set Filter_Quality ##
Cary Clark8032b982017-07-28 11:04:54 -04001628
1629Filter_Quality trades speed for image filtering when the image is scaled.
1630A lower Filter_Quality draws faster, but has less fidelity.
1631A higher Filter_Quality draws slower, but looks better.
Cary Clarkce101242017-09-01 15:51:02 -04001632If the image is drawn without scaling, the Filter_Quality choice will not result
1633in a noticeable difference.
Cary Clark8032b982017-07-28 11:04:54 -04001634
1635Filter_Quality is used in Paint passed as a parameter to
1636#List
1637# SkCanvas::drawBitmap ##
1638# SkCanvas::drawBitmapRect ##
1639# SkCanvas::drawImage ##
1640# SkCanvas::drawImageRect ##
1641 #ToDo probably more... ##
1642#List ##
1643and when Paint has a Shader specialization that uses Image or Bitmap.
1644
1645Filter_Quality is kNone_SkFilterQuality by default.
1646
1647#Example
1648#Image 3
1649void draw(SkCanvas* canvas) {
1650 SkPaint paint;
1651 canvas->scale(.2f, .2f);
1652 for (SkFilterQuality q : { kNone_SkFilterQuality, kLow_SkFilterQuality,
1653 kMedium_SkFilterQuality, kHigh_SkFilterQuality } ) {
1654 paint.setFilterQuality(q);
1655 canvas->drawImage(image.get(), 0, 0, &paint);
1656 canvas->translate(550, 0);
1657 if (kLow_SkFilterQuality == q) canvas->translate(-1100, 550);
1658 }
1659}
1660##
1661
1662#Method SkFilterQuality getFilterQuality() const
1663
Cary Clarkab2621d2018-01-30 10:08:57 -05001664#In Filter_Quality_Methods
1665#Line # returns Filter_Quality, image filtering level ##
Cary Clark8032b982017-07-28 11:04:54 -04001666Returns Filter_Quality, the image filtering level. A lower setting
1667draws faster; a higher setting looks better when the image is scaled.
1668
1669#Return one of: kNone_SkFilterQuality, kLow_SkFilterQuality,
1670 kMedium_SkFilterQuality, kHigh_SkFilterQuality
1671#Return ##
1672
1673#Example
1674 SkPaint paint;
1675 SkDebugf("kNone_SkFilterQuality %c= paint.getFilterQuality()\n",
1676 kNone_SkFilterQuality == paint.getFilterQuality() ? '=' : '!');
1677
1678 #StdOut
1679 kNone_SkFilterQuality == paint.getFilterQuality()
1680 ##
1681##
1682
1683##
1684
1685
1686#Method void setFilterQuality(SkFilterQuality quality)
1687
Cary Clarkab2621d2018-01-30 10:08:57 -05001688#In Filter_Quality_Methods
1689#Line # sets Filter_Quality, the image filtering level ##
Cary Clark8032b982017-07-28 11:04:54 -04001690Sets Filter_Quality, the image filtering level. A lower setting
1691draws faster; a higher setting looks better when the image is scaled.
Cary Clark579985c2017-07-31 11:48:27 -04001692Does not check to see if quality is valid.
Cary Clark8032b982017-07-28 11:04:54 -04001693
1694#Param quality one of: kNone_SkFilterQuality, kLow_SkFilterQuality,
1695 kMedium_SkFilterQuality, kHigh_SkFilterQuality
1696##
1697
1698#Example
1699 SkPaint paint;
1700 paint.setFilterQuality(kHigh_SkFilterQuality);
1701 SkDebugf("kHigh_SkFilterQuality %c= paint.getFilterQuality()\n",
1702 kHigh_SkFilterQuality == paint.getFilterQuality() ? '=' : '!');
1703
1704 #StdOut
1705 kHigh_SkFilterQuality == paint.getFilterQuality()
1706 ##
1707##
1708
1709#SeeAlso SkFilterQuality Image_Scaling
1710
1711##
1712
Cary Clark08895c42018-02-01 09:37:32 -05001713#Subtopic Filter_Quality_Methods ##
Cary Clark8032b982017-07-28 11:04:54 -04001714# ------------------------------------------------------------------------------
Cary Clark08895c42018-02-01 09:37:32 -05001715#Subtopic Color_Methods
1716#Line # get and set Color ##
Cary Clark8032b982017-07-28 11:04:54 -04001717
Cary Clarkab2621d2018-01-30 10:08:57 -05001718#Table
1719#Legend
1720# name # description ##
1721#Legend ##
1722# getColor # returns Color_Alpha and Color_RGB, one drawing color ##
1723# setColor # sets Color_Alpha and Color_RGB, one drawing color ##
1724#Table ##
Cary Clark8032b982017-07-28 11:04:54 -04001725
Cary Clarkab2621d2018-01-30 10:08:57 -05001726Color specifies the Color_RGB_Red, Color_RGB_Blue, Color_RGB_Green, and Color_Alpha
1727values used to draw a filled or stroked shape in a 32-bit value. Each component
1728occupies 8-bits, ranging from zero: no contribution; to 255: full intensity.
1729All values in any combination are valid.
Cary Clark8032b982017-07-28 11:04:54 -04001730
Cary Clarkab2621d2018-01-30 10:08:57 -05001731Color is not Premultiplied; Color_Alpha sets the transparency independent of
1732Color_RGB: Color_RGB_Red, Color_RGB_Blue, and Color_RGB_Green.
1733
1734The bit positions of Color_Alpha and Color_RGB are independent of the bit
1735positions on the output device, which may have more or fewer bits, and may have
1736a different arrangement.
Cary Clark8032b982017-07-28 11:04:54 -04001737
1738#Table
1739#Legend
1740# bit positions # Color_Alpha # Color_RGB_Red # Color_RGB_Blue # Color_RGB_Green ##
1741#Legend ##
1742# # 31 - 24 # 23 - 16 # 15 - 8 # 7 - 0 ##
1743#Table ##
1744
1745#Example
1746#Height 128
1747 void draw(SkCanvas* canvas) {
1748 SkPaint paint;
1749 paint.setColor(0x8000FF00); // transparent green
1750 canvas->drawCircle(50, 50, 40, paint);
1751 paint.setARGB(128, 255, 0, 0); // transparent red
1752 canvas->drawCircle(80, 50, 40, paint);
1753 paint.setColor(SK_ColorBLUE);
1754 paint.setAlpha(0x80);
1755 canvas->drawCircle(65, 65, 40, paint);
1756 }
1757##
1758
1759#Method SkColor getColor() const
1760
Cary Clarkab2621d2018-01-30 10:08:57 -05001761#In Color_Methods
1762#Line # returns Color_Alpha and Color_RGB, one drawing color ##
Cary Clarkce101242017-09-01 15:51:02 -04001763 Retrieves Alpha and Color_RGB, Unpremultiplied, packed into 32 bits.
Cary Clark8032b982017-07-28 11:04:54 -04001764 Use helpers SkColorGetA, SkColorGetR, SkColorGetG, and SkColorGetB to extract
1765 a color component.
1766
1767 #Return Unpremultiplied Color_ARGB ##
1768
1769 #Example
1770 SkPaint paint;
1771 paint.setColor(SK_ColorYELLOW);
1772 SkColor y = paint.getColor();
1773 SkDebugf("Yellow is %d%% red, %d%% green, and %d%% blue.\n", (int) (SkColorGetR(y) / 2.55f),
1774 (int) (SkColorGetG(y) / 2.55f), (int) (SkColorGetB(y) / 2.55f));
1775
1776 #StdOut
1777 Yellow is 100% red, 100% green, and 0% blue.
1778 ##
1779 ##
1780
1781 #SeeAlso SkColor
1782
1783##
1784
1785#Method void setColor(SkColor color)
1786
Cary Clarkab2621d2018-01-30 10:08:57 -05001787#In Color_Methods
1788#Line # sets Color_Alpha and Color_RGB, one drawing color ##
Cary Clarkce101242017-09-01 15:51:02 -04001789 Sets Alpha and Color_RGB used when stroking and filling. The color is a 32-bit value,
1790 Unpremultiplied, packing 8-bit components for Alpha, Red, Blue, and Green.
Cary Clark8032b982017-07-28 11:04:54 -04001791
1792 #Param color Unpremultiplied Color_ARGB ##
Cary Clark0c5f5462017-12-15 11:21:51 -05001793
1794 #Example
Cary Clark8032b982017-07-28 11:04:54 -04001795 SkPaint green1, green2;
1796 unsigned a = 255;
1797 unsigned r = 0;
1798 unsigned g = 255;
1799 unsigned b = 0;
1800 green1.setColor((a << 24) + (r << 16) + (g << 8) + (b << 0));
1801 green2.setColor(0xFF00FF00);
1802 SkDebugf("green1 %c= green2\n", green1 == green2 ? '=' : '!');
1803
1804 #StdOut
1805 green1 == green2
1806 ##
1807 ##
1808
1809 #SeeAlso SkColor setARGB SkColorSetARGB
1810
1811##
Cary Clark08895c42018-02-01 09:37:32 -05001812#Subtopic Color_Methods ##
Cary Clark8032b982017-07-28 11:04:54 -04001813
1814#Subtopic Alpha_Methods
Cary Clark08895c42018-02-01 09:37:32 -05001815#Line # get and set Alpha ##
Cary Clark8032b982017-07-28 11:04:54 -04001816
1817Color_Alpha sets the transparency independent of Color_RGB: Color_RGB_Red, Color_RGB_Blue, and Color_RGB_Green.
1818
1819#Method uint8_t getAlpha() const
1820
Cary Clarkab2621d2018-01-30 10:08:57 -05001821#In Alpha_Methods
1822#Line # returns Color_Alpha, color opacity ##
Cary Clarkce101242017-09-01 15:51:02 -04001823 Retrieves Alpha from the Color used when stroking and filling.
Cary Clark8032b982017-07-28 11:04:54 -04001824
Cary Clarkce101242017-09-01 15:51:02 -04001825 #Return Alpha ranging from zero, fully transparent, to 255, fully opaque ##
Cary Clark8032b982017-07-28 11:04:54 -04001826
1827 #Example
1828 SkPaint paint;
1829 SkDebugf("255 %c= paint.getAlpha()\n", 255 == paint.getAlpha() ? '=' : '!');
1830
1831 #StdOut
1832 255 == paint.getAlpha()
1833 ##
1834 ##
1835
1836##
1837
1838#Method void setAlpha(U8CPU a)
1839
Cary Clarkab2621d2018-01-30 10:08:57 -05001840#In Alpha_Methods
1841#Line # sets Color_Alpha, color opacity ##
Cary Clarkce101242017-09-01 15:51:02 -04001842 Replaces Alpha, leaving Color_RGB
Cary Clark8032b982017-07-28 11:04:54 -04001843 unchanged. An out of range value triggers an assert in the debug
1844 build. a is a value from zero to 255.
1845 a set to zero makes Color fully transparent; a set to 255 makes Color
1846 fully opaque.
1847
Cary Clarkce101242017-09-01 15:51:02 -04001848 #Param a Alpha component of Color ##
Cary Clark8032b982017-07-28 11:04:54 -04001849
1850 #Example
1851 SkPaint paint;
1852 paint.setColor(0x00112233);
1853 paint.setAlpha(0x44);
1854 SkDebugf("0x44112233 %c= paint.getColor()\n", 0x44112233 == paint.getColor() ? '=' : '!');
1855
1856 #StdOut
1857 0x44112233 == paint.getColor()
1858 ##
1859 ##
1860
1861##
1862
Cary Clark08895c42018-02-01 09:37:32 -05001863#Subtopic Alpha_Methods ##
Cary Clark8032b982017-07-28 11:04:54 -04001864
1865#Method void setARGB(U8CPU a, U8CPU r, U8CPU g, U8CPU b)
1866
Cary Clarkab2621d2018-01-30 10:08:57 -05001867#In Color_Methods
1868#Line # sets color by component ##
Cary Clark8032b982017-07-28 11:04:54 -04001869 Sets Color used when drawing solid fills. The color components range from 0 to 255.
Cary Clarkce101242017-09-01 15:51:02 -04001870 The color is Unpremultiplied; Alpha sets the transparency independent of Color_RGB.
Cary Clark8032b982017-07-28 11:04:54 -04001871
1872 #Param a amount of Color_Alpha, from fully transparent (0) to fully opaque (255) ##
1873 #Param r amount of Color_RGB_Red, from no red (0) to full red (255) ##
1874 #Param g amount of Color_RGB_Green, from no green (0) to full green (255) ##
1875 #Param b amount of Color_RGB_Blue, from no blue (0) to full blue (255) ##
1876
1877 #Example
1878 SkPaint transRed1, transRed2;
1879 transRed1.setARGB(255 / 2, 255, 0, 0);
1880 transRed2.setColor(SkColorSetARGB(255 / 2, 255, 0, 0));
1881 SkDebugf("transRed1 %c= transRed2", transRed1 == transRed2 ? '=' : '!');
1882
1883 #StdOut
1884 transRed1 == transRed2
1885 ##
1886 ##
1887
1888 #SeeAlso setColor SkColorSetARGB
1889
1890##
1891
Cary Clark8032b982017-07-28 11:04:54 -04001892# ------------------------------------------------------------------------------
Cary Clark08895c42018-02-01 09:37:32 -05001893#Subtopic Style
1894#Line # geometry filling, stroking ##
Cary Clark8032b982017-07-28 11:04:54 -04001895
1896Style specifies if the geometry is filled, stroked, or both filled and stroked.
1897Some shapes ignore Style and are always drawn filled or stroked.
1898
1899Set Style to kFill_Style to fill the shape.
1900The fill covers the area inside the geometry for most shapes.
1901
1902Set Style to kStroke_Style to stroke the shape.
1903
1904# ------------------------------------------------------------------------------
1905#Subtopic Fill
Cary Clark08895c42018-02-01 09:37:32 -05001906#Line # fill and stroke ##
Cary Clark8032b982017-07-28 11:04:54 -04001907#ToDo write up whatever generalities make sense to describe filling ##
1908
1909#SeeAlso Path_Fill_Type
Cary Clark08895c42018-02-01 09:37:32 -05001910#Subtopic Fill ##
Cary Clark8032b982017-07-28 11:04:54 -04001911
1912#Subtopic Stroke
Cary Clark08895c42018-02-01 09:37:32 -05001913#Line # lines and curves with width ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001914The stroke covers the area described by following the shape edge with a pen or brush of
Cary Clark8032b982017-07-28 11:04:54 -04001915Stroke_Width. The area covered where the shape starts and stops is described by Stroke_Cap.
1916The area covered where the shape turns a corner is described by Stroke_Join.
Cary Clarkbc5697d2017-10-04 14:31:33 -04001917The stroke is centered on the shape; it extends equally on either side of the shape edge.
Cary Clark8032b982017-07-28 11:04:54 -04001918
1919As Stroke_Width gets smaller, the drawn path frame is thinner. Stroke_Width less than one
1920may have gaps, and if kAntiAlias_Flag is set, Color_Alpha will increase to visually decrease coverage.
Cary Clark08895c42018-02-01 09:37:32 -05001921#Subtopic Stroke ##
Cary Clark8032b982017-07-28 11:04:54 -04001922
1923#Subtopic Hairline
Cary Clark08895c42018-02-01 09:37:32 -05001924#Line # lines and curves with minimal width ##
Cary Clark8032b982017-07-28 11:04:54 -04001925#Alias Hairline # maybe should be Stroke_Hairline ?
1926
1927Stroke_Width of zero has a special meaning and switches drawing to use Hairline.
1928Hairline draws the thinnest continuous frame. If kAntiAlias_Flag is clear, adjacent pixels
1929flow horizontally, vertically,or diagonally.
1930
Cary Clarkce101242017-09-01 15:51:02 -04001931#ToDo what is the description of Anti-aliased hairlines? ##
Cary Clark8032b982017-07-28 11:04:54 -04001932
1933Path drawing with Hairline may hit the same pixel more than once. For instance, Path containing
1934two lines in one Path_Contour will draw the corner point once, but may both lines may draw the adjacent
1935pixel. If kAntiAlias_Flag is set, transparency is applied twice, resulting in a darker pixel. Some
1936GPU-backed implementations apply transparency at a later drawing stage, avoiding double hit pixels
1937while stroking.
1938
Cary Clark08895c42018-02-01 09:37:32 -05001939#Subtopic Hairline ##
Cary Clark8032b982017-07-28 11:04:54 -04001940
1941#Enum Style
Cary Clark08895c42018-02-01 09:37:32 -05001942#Line # stroke, fill, or both ##
Cary Clark8032b982017-07-28 11:04:54 -04001943
1944#Code
1945 enum Style {
1946 kFill_Style,
1947 kStroke_Style,
1948 kStrokeAndFill_Style,
1949 };
1950##
1951
1952Set Style to fill, stroke, or both fill and stroke geometry.
1953The stroke and fill
1954share all paint attributes; for instance, they are drawn with the same color.
1955
1956Use kStrokeAndFill_Style to avoid hitting the same pixels twice with a stroke draw and
1957a fill draw.
1958
1959#Const kFill_Style 0
1960 Set to fill geometry.
Cary Clarkce101242017-09-01 15:51:02 -04001961 Applies to Rect, Region, Round_Rect, Circles, Ovals, Path, and Text.
1962 Bitmap, Image, Patches, Region, Sprites, and Vertices are painted as if
Cary Clark8032b982017-07-28 11:04:54 -04001963 kFill_Style is set, and ignore the set Style.
1964 The Path_Fill_Type specifies additional rules to fill the area outside the path edge,
1965 and to create an unfilled hole inside the shape.
1966 Style is set to kFill_Style by default.
1967##
1968
1969#Const kStroke_Style 1
1970 Set to stroke geometry.
Cary Clarkce101242017-09-01 15:51:02 -04001971 Applies to Rect, Region, Round_Rect, Arcs, Circles, Ovals, Path, and Text.
Cary Clark56356312018-02-08 14:45:18 -05001972 Arcs, Lines, and points, are always drawn as if kStroke_Style is set,
Cary Clark8032b982017-07-28 11:04:54 -04001973 and ignore the set Style.
1974 The stroke construction is unaffected by the Path_Fill_Type.
1975##
1976
1977#Const kStrokeAndFill_Style 2
1978 Set to stroke and fill geometry.
Cary Clarkce101242017-09-01 15:51:02 -04001979 Applies to Rect, Region, Round_Rect, Circles, Ovals, Path, and Text.
Cary Clark8032b982017-07-28 11:04:54 -04001980 Path is treated as if it is set to SkPath::kWinding_FillType,
1981 and the set Path_Fill_Type is ignored.
1982##
1983
Cary Clark08895c42018-02-01 09:37:32 -05001984#Enum Style ##
Cary Clark8032b982017-07-28 11:04:54 -04001985
1986#Enum
Cary Clark08895c42018-02-01 09:37:32 -05001987#Line # number of Style defines ##
Cary Clark8032b982017-07-28 11:04:54 -04001988#Code
1989 enum {
Cary Clarkbad5ad72017-08-03 17:14:08 -04001990 kStyleCount = kStrokeAndFill_Style + 1,
Cary Clark8032b982017-07-28 11:04:54 -04001991 };
1992##
1993
1994#Const kStyleCount 3
1995The number of different Style values defined.
1996May be used to verify that Style is a legal value.
1997##
1998
1999#Enum ##
2000
2001#Method Style getStyle() const
2002
Cary Clarkab2621d2018-01-30 10:08:57 -05002003#In Style
2004#Line # returns Style: stroke, fill, or both ##
Cary Clark8032b982017-07-28 11:04:54 -04002005 Whether the geometry is filled, stroked, or filled and stroked.
2006
2007 #Return one of:kFill_Style, kStroke_Style, kStrokeAndFill_Style ##
2008
2009 #Example
2010 SkPaint paint;
2011 SkDebugf("SkPaint::kFill_Style %c= paint.getStyle()\n",
2012 SkPaint::kFill_Style == paint.getStyle() ? '=' : '!');
2013
2014 #StdOut
2015 SkPaint::kFill_Style == paint.getStyle()
2016 ##
2017 ##
2018
2019#SeeAlso Style setStyle
2020##
2021
2022#Method void setStyle(Style style)
2023
Cary Clarkab2621d2018-01-30 10:08:57 -05002024#In Style
2025#Line # sets Style: stroke, fill, or both ##
Cary Clark8032b982017-07-28 11:04:54 -04002026 Sets whether the geometry is filled, stroked, or filled and stroked.
2027 Has no effect if style is not a legal Style value.
2028
2029 #Param style one of: kFill_Style, kStroke_Style, kStrokeAndFill_Style
2030 ##
2031
2032 #Example
2033 void draw(SkCanvas* canvas) {
2034 SkPaint paint;
2035 paint.setStrokeWidth(5);
2036 SkRegion region;
2037 region.op(140, 10, 160, 30, SkRegion::kUnion_Op);
2038 region.op(170, 40, 190, 60, SkRegion::kUnion_Op);
2039 SkBitmap bitmap;
2040 bitmap.setInfo(SkImageInfo::MakeA8(50, 50), 50);
2041 uint8_t pixels[50][50];
2042 for (int x = 0; x < 50; ++x) {
2043 for (int y = 0; y < 50; ++y) {
2044 pixels[y][x] = (x + y) % 5 ? 0xFF : 0x00;
2045 }
2046 }
2047 bitmap.setPixels(pixels);
2048 for (auto style : { SkPaint::kFill_Style,
2049 SkPaint::kStroke_Style,
2050 SkPaint::kStrokeAndFill_Style }) {
2051 paint.setStyle(style);
2052 canvas->drawLine(10, 10, 60, 60, paint);
2053 canvas->drawRect({80, 10, 130, 60}, paint);
2054 canvas->drawRegion(region, paint);
2055 canvas->drawBitmap(bitmap, 200, 10, &paint);
2056 canvas->translate(0, 80);
2057 }
2058 }
2059 ##
2060
2061#SeeAlso Style getStyle
2062##
2063
2064#SeeAlso Path_Fill_Type Path_Effect Style_Fill Style_Stroke
Cary Clark08895c42018-02-01 09:37:32 -05002065#Subtopic Style ##
Cary Clark8032b982017-07-28 11:04:54 -04002066
2067# ------------------------------------------------------------------------------
Cary Clark08895c42018-02-01 09:37:32 -05002068#Subtopic Stroke_Width
2069#Line # thickness perpendicular to geometry ##
Cary Clark8032b982017-07-28 11:04:54 -04002070
2071Stroke_Width sets the width for stroking. The width is the thickness
Cary Clarkbc5697d2017-10-04 14:31:33 -04002072of the stroke perpendicular to the path direction when the paint style is
Cary Clark8032b982017-07-28 11:04:54 -04002073set to kStroke_Style or kStrokeAndFill_Style.
2074
2075When width is greater than zero, the stroke encompasses as many pixels partially
2076or fully as needed. When the width equals zero, the paint enables hairlines;
2077the stroke is always one pixel wide.
2078
Cary Clarkbc5697d2017-10-04 14:31:33 -04002079The stroke dimensions are scaled by the canvas matrix, but Hairline stroke
Cary Clark8032b982017-07-28 11:04:54 -04002080remains one pixel wide regardless of scaling.
2081
2082The default width for the paint is zero.
2083
2084#Example
2085#Height 170
2086 #Platform raster gpu
2087 #Description
2088 The pixels hit to represent thin lines vary with the angle of the
Cary Clarkbc5697d2017-10-04 14:31:33 -04002089 line and the platform implementation.
Cary Clark8032b982017-07-28 11:04:54 -04002090 ##
2091 void draw(SkCanvas* canvas) {
2092 SkPaint paint;
2093 for (bool antialias : { false, true }) {
2094 paint.setAntiAlias(antialias);
2095 for (int width = 0; width <= 4; ++width) {
2096 SkScalar offset = antialias * 100 + width * 20;
2097 paint.setStrokeWidth(width * 0.25f);
2098 canvas->drawLine(10 + offset, 10, 20 + offset, 60, paint);
2099 canvas->drawLine(10 + offset, 110, 60 + offset, 160, paint);
2100 }
2101 }
2102 }
2103##
2104
2105#Method SkScalar getStrokeWidth() const
2106
Cary Clarkab2621d2018-01-30 10:08:57 -05002107#In Stroke_Width
2108#Line # returns thickness of the stroke ##
Cary Clark8032b982017-07-28 11:04:54 -04002109 Returns the thickness of the pen used by Paint to
2110 outline the shape.
2111
2112 #Return zero for Hairline, greater than zero for pen thickness ##
2113
2114 #Example
2115 SkPaint paint;
2116 SkDebugf("0 %c= paint.getStrokeWidth()\n", 0 == paint.getStrokeWidth() ? '=' : '!');
2117
2118 #StdOut
2119 0 == paint.getStrokeWidth()
2120 ##
2121 ##
2122
2123##
2124
2125#Method void setStrokeWidth(SkScalar width)
2126
Cary Clarkab2621d2018-01-30 10:08:57 -05002127#In Stroke_Width
2128#Line # sets thickness of the stroke ##
Cary Clark8032b982017-07-28 11:04:54 -04002129 Sets the thickness of the pen used by the paint to
2130 outline the shape.
2131 Has no effect if width is less than zero.
2132
2133 #Param width zero thickness for Hairline; greater than zero for pen thickness
2134 ##
2135
2136 #Example
2137 SkPaint paint;
2138 paint.setStrokeWidth(5);
2139 paint.setStrokeWidth(-1);
2140 SkDebugf("5 %c= paint.getStrokeWidth()\n", 5 == paint.getStrokeWidth() ? '=' : '!');
2141
2142 #StdOut
2143 5 == paint.getStrokeWidth()
2144 ##
2145 ##
2146
2147##
2148
Cary Clark08895c42018-02-01 09:37:32 -05002149#Subtopic Stroke_Width ##
Cary Clark8032b982017-07-28 11:04:54 -04002150# ------------------------------------------------------------------------------
Cary Clark08895c42018-02-01 09:37:32 -05002151#Subtopic Miter_Limit
2152#Line # maximum length of stroked corners ##
Cary Clark8032b982017-07-28 11:04:54 -04002153
2154Miter_Limit specifies the maximum miter length,
2155relative to the stroke width.
2156
2157Miter_Limit is used when the Stroke_Join
2158is set to kMiter_Join, and the Style is either kStroke_Style
2159or kStrokeAndFill_Style.
2160
2161If the miter at a corner exceeds this limit, kMiter_Join
2162is replaced with kBevel_Join.
2163
2164Miter_Limit can be computed from the corner angle:
2165
2166#Formula
2167 miter limit = 1 / sin ( angle / 2 )
2168#Formula ##
2169
2170Miter_Limit default value is 4.
2171The default may be changed at compile time by setting SkPaintDefaults_MiterLimit
Cary Clarkce101242017-09-01 15:51:02 -04002172in "SkUserConfig.h" or as a define supplied by the build environment.
Cary Clark8032b982017-07-28 11:04:54 -04002173
2174Here are some miter limits and the angles that triggers them.
2175#Table
2176#Legend
2177 # miter limit # angle in degrees ##
2178#Legend ##
2179 # 10 # 11.48 ##
2180 # 9 # 12.76 ##
2181 # 8 # 14.36 ##
2182 # 7 # 16.43 ##
2183 # 6 # 19.19 ##
2184 # 5 # 23.07 ##
2185 # 4 # 28.96 ##
2186 # 3 # 38.94 ##
2187 # 2 # 60 ##
2188 # 1 # 180 ##
2189#Table ##
2190
2191#Example
2192 #Height 170
2193 #Width 384
2194 #Description
2195 This example draws a stroked corner and the miter length beneath.
2196 When the miter limit is decreased slightly, the miter join is replaced
2197 by a bevel join.
2198 ##
2199 void draw(SkCanvas* canvas) {
2200 SkPoint pts[] = {{ 10, 50 }, { 110, 80 }, { 10, 110 }};
2201 SkVector v[] = { pts[0] - pts[1], pts[2] - pts[1] };
2202 SkScalar angle1 = SkScalarATan2(v[0].fY, v[0].fX);
2203 SkScalar angle2 = SkScalarATan2(v[1].fY, v[1].fX);
2204 const SkScalar strokeWidth = 20;
2205 SkScalar miterLimit = 1 / SkScalarSin((angle2 - angle1) / 2);
2206 SkScalar miterLength = strokeWidth * miterLimit;
2207 SkPath path;
2208 path.moveTo(pts[0]);
2209 path.lineTo(pts[1]);
2210 path.lineTo(pts[2]);
2211 SkPaint paint; // set to default kMiter_Join
2212 paint.setAntiAlias(true);
2213 paint.setStyle(SkPaint::kStroke_Style);
2214 paint.setStrokeMiter(miterLimit);
2215 paint.setStrokeWidth(strokeWidth);
2216 canvas->drawPath(path, paint);
2217 paint.setStrokeWidth(1);
2218 canvas->drawLine(pts[1].fX - miterLength / 2, pts[1].fY + 50,
2219 pts[1].fX + miterLength / 2, pts[1].fY + 50, paint);
2220 canvas->translate(200, 0);
2221 miterLimit *= 0.99f;
2222 paint.setStrokeMiter(miterLimit);
2223 paint.setStrokeWidth(strokeWidth);
2224 canvas->drawPath(path, paint);
2225 paint.setStrokeWidth(1);
2226 canvas->drawLine(pts[1].fX - miterLength / 2, pts[1].fY + 50,
2227 pts[1].fX + miterLength / 2, pts[1].fY + 50, paint);
2228 }
2229##
2230
2231#Method SkScalar getStrokeMiter() const
2232
Cary Clarkab2621d2018-01-30 10:08:57 -05002233#In Miter_Limit
2234#Line # returns Miter_Limit, angles with sharp corners ##
Cary Clark8032b982017-07-28 11:04:54 -04002235 The limit at which a sharp corner is drawn beveled.
2236
2237 #Return zero and greater Miter_Limit ##
2238
2239 #Example
2240 SkPaint paint;
2241 SkDebugf("default miter limit == %g\n", paint.getStrokeMiter());
2242
2243 #StdOut
2244 default miter limit == 4
2245 ##
2246 ##
2247
2248 #SeeAlso Miter_Limit setStrokeMiter Join
2249
2250##
2251
2252#Method void setStrokeMiter(SkScalar miter)
2253
Cary Clarkab2621d2018-01-30 10:08:57 -05002254#In Miter_Limit
2255#Line # sets Miter_Limit, angles with sharp corners ##
Cary Clark8032b982017-07-28 11:04:54 -04002256 The limit at which a sharp corner is drawn beveled.
2257 Valid values are zero and greater.
2258 Has no effect if miter is less than zero.
2259
2260 #Param miter zero and greater Miter_Limit
2261 ##
2262
2263 #Example
2264 SkPaint paint;
2265 paint.setStrokeMiter(8);
2266 paint.setStrokeMiter(-1);
2267 SkDebugf("default miter limit == %g\n", paint.getStrokeMiter());
2268
2269 #StdOut
2270 default miter limit == 8
2271 ##
2272 ##
2273
2274 #SeeAlso Miter_Limit getStrokeMiter Join
2275
2276##
2277
Cary Clark08895c42018-02-01 09:37:32 -05002278#Subtopic Miter_Limit ##
Cary Clark8032b982017-07-28 11:04:54 -04002279# ------------------------------------------------------------------------------
Cary Clark08895c42018-02-01 09:37:32 -05002280#Subtopic Stroke_Cap
2281#Line # decorations at ends of open strokes ##
Cary Clark8032b982017-07-28 11:04:54 -04002282
2283#Enum Cap
Cary Clark08895c42018-02-01 09:37:32 -05002284#Line # start and end geometry on stroked shapes ##
Cary Clark8032b982017-07-28 11:04:54 -04002285
2286#Code
2287 enum Cap {
2288 kButt_Cap,
2289 kRound_Cap,
2290 kSquare_Cap,
2291
2292 kLast_Cap = kSquare_Cap,
Cary Clarkbad5ad72017-08-03 17:14:08 -04002293 kDefault_Cap = kButt_Cap,
Cary Clark8032b982017-07-28 11:04:54 -04002294 };
Cary Clark6fc50412017-09-21 12:31:06 -04002295
Cary Clark8032b982017-07-28 11:04:54 -04002296 static constexpr int kCapCount = kLast_Cap + 1;
2297##
2298
2299Stroke_Cap draws at the beginning and end of an open Path_Contour.
2300
2301 #Const kButt_Cap 0
2302 Does not extend the stroke past the beginning or the end.
2303 ##
2304 #Const kRound_Cap 1
2305 Adds a circle with a diameter equal to Stroke_Width at the beginning
2306 and end.
2307 ##
2308 #Const kSquare_Cap 2
2309 Adds a square with sides equal to Stroke_Width at the beginning
2310 and end. The square sides are parallel to the initial and final direction
2311 of the stroke.
2312 ##
2313 #Const kLast_Cap 2
2314 Equivalent to the largest value for Stroke_Cap.
2315 ##
2316 #Const kDefault_Cap 0
2317 Equivalent to kButt_Cap.
2318 Stroke_Cap is set to kButt_Cap by default.
2319 ##
2320
2321 #Const kCapCount 3
2322 The number of different Stroke_Cap values defined.
2323 May be used to verify that Stroke_Cap is a legal value.
2324 ##
2325#Enum ##
2326
2327Stroke describes the area covered by a pen of Stroke_Width as it
Cary Clarkbc5697d2017-10-04 14:31:33 -04002328follows the Path_Contour, moving parallel to the contour direction.
Cary Clark8032b982017-07-28 11:04:54 -04002329
2330If the Path_Contour is not terminated by SkPath::kClose_Verb, the contour has a
2331visible beginning and end.
2332
2333Path_Contour may start and end at the same point; defining Zero_Length_Contour.
2334
2335kButt_Cap and Zero_Length_Contour is not drawn.
2336kRound_Cap and Zero_Length_Contour draws a circle of diameter Stroke_Width
2337at the contour point.
2338kSquare_Cap and Zero_Length_Contour draws an upright square with a side of
2339Stroke_Width at the contour point.
2340
2341Stroke_Cap is kButt_Cap by default.
2342
2343#Example
Cary Clark2ade9972017-11-02 17:49:34 -04002344#Height 200
Cary Clark8032b982017-07-28 11:04:54 -04002345 SkPaint paint;
2346 paint.setStyle(SkPaint::kStroke_Style);
2347 paint.setStrokeWidth(20);
2348 SkPath path;
2349 path.moveTo(30, 30);
2350 path.lineTo(30, 30);
2351 path.moveTo(70, 30);
2352 path.lineTo(90, 40);
2353 for (SkPaint::Cap c : { SkPaint::kButt_Cap, SkPaint::kRound_Cap, SkPaint::kSquare_Cap } ) {
2354 paint.setStrokeCap(c);
2355 canvas->drawPath(path, paint);
2356 canvas->translate(0, 70);
2357 }
2358##
2359
2360#Method Cap getStrokeCap() const
2361
Cary Clarkab2621d2018-01-30 10:08:57 -05002362#In Stroke_Cap
2363#Line # returns Cap, the area drawn at path ends ##
Cary Clark8032b982017-07-28 11:04:54 -04002364 The geometry drawn at the beginning and end of strokes.
2365
2366 #Return one of: kButt_Cap, kRound_Cap, kSquare_Cap ##
2367
2368 #Example
2369 SkPaint paint;
2370 SkDebugf("kButt_Cap %c= default stroke cap\n",
2371 SkPaint::kButt_Cap == paint.getStrokeCap() ? '=' : '!');
2372
2373 #StdOut
2374 kButt_Cap == default stroke cap
2375 ##
2376 ##
2377
2378 #SeeAlso Stroke_Cap setStrokeCap
2379##
2380
2381#Method void setStrokeCap(Cap cap)
2382
Cary Clarkab2621d2018-01-30 10:08:57 -05002383#In Stroke_Cap
2384#Line # sets Cap, the area drawn at path ends ##
Cary Clark8032b982017-07-28 11:04:54 -04002385 The geometry drawn at the beginning and end of strokes.
2386
2387 #Param cap one of: kButt_Cap, kRound_Cap, kSquare_Cap;
2388 has no effect if cap is not valid
2389 ##
2390
2391 #Example
2392 SkPaint paint;
2393 paint.setStrokeCap(SkPaint::kRound_Cap);
2394 paint.setStrokeCap((SkPaint::Cap) SkPaint::kCapCount);
2395 SkDebugf("kRound_Cap %c= paint.getStrokeCap()\n",
2396 SkPaint::kRound_Cap == paint.getStrokeCap() ? '=' : '!');
2397
2398 #StdOut
2399 kRound_Cap == paint.getStrokeCap()
2400 ##
2401 ##
2402
2403 #SeeAlso Stroke_Cap getStrokeCap
2404##
2405
Cary Clark08895c42018-02-01 09:37:32 -05002406#Subtopic Stroke_Cap ##
Cary Clark8032b982017-07-28 11:04:54 -04002407# ------------------------------------------------------------------------------
Cary Clark08895c42018-02-01 09:37:32 -05002408#Subtopic Stroke_Join
2409#Line # decoration at corners of strokes ##
Cary Clark8032b982017-07-28 11:04:54 -04002410
2411Stroke_Join draws at the sharp corners of an open or closed Path_Contour.
2412
2413Stroke describes the area covered by a pen of Stroke_Width as it
Cary Clarkbc5697d2017-10-04 14:31:33 -04002414follows the Path_Contour, moving parallel to the contour direction.
Cary Clark8032b982017-07-28 11:04:54 -04002415
2416If the contour direction changes abruptly, because the tangent direction leading
2417to the end of a curve within the contour does not match the tangent direction of
2418the following curve, the pair of curves meet at Stroke_Join.
2419
2420#Example
Cary Clark2ade9972017-11-02 17:49:34 -04002421#Height 200
Cary Clarka560c472017-11-27 10:44:06 -05002422 SkPaint paint;
2423 paint.setStyle(SkPaint::kStroke_Style);
2424 paint.setStrokeWidth(20);
2425 SkPath path;
2426 path.moveTo(30, 20);
2427 path.lineTo(40, 40);
2428 path.conicTo(70, 20, 100, 20, .707f);
2429 for (SkPaint::Join j : { SkPaint::kMiter_Join, SkPaint::kRound_Join, SkPaint::kBevel_Join } ) {
2430 paint.setStrokeJoin(j);
2431 canvas->drawPath(path, paint);
2432 canvas->translate(0, 70);
2433 }
Cary Clark8032b982017-07-28 11:04:54 -04002434##
2435
2436#Enum Join
Cary Clark08895c42018-02-01 09:37:32 -05002437#Line # corner geometry on stroked shapes ##
Cary Clark8032b982017-07-28 11:04:54 -04002438#Code
2439 enum Join {
2440 kMiter_Join,
2441 kRound_Join,
2442 kBevel_Join,
2443
2444 kLast_Join = kBevel_Join,
Cary Clarkbad5ad72017-08-03 17:14:08 -04002445 kDefault_Join = kMiter_Join,
Cary Clark8032b982017-07-28 11:04:54 -04002446 };
Cary Clark6fc50412017-09-21 12:31:06 -04002447
Cary Clark8032b982017-07-28 11:04:54 -04002448 static constexpr int kJoinCount = kLast_Join + 1;
2449##
2450
Cary Clark1eace2d2017-07-31 07:52:43 -04002451Join specifies how corners are drawn when a shape is stroked. Join
Cary Clark8032b982017-07-28 11:04:54 -04002452affects the four corners of a stroked rectangle, and the connected segments in a
2453stroked path.
2454
2455Choose miter join to draw sharp corners. Choose round join to draw a circle with a
2456radius equal to the stroke width on top of the corner. Choose bevel join to minimally
2457connect the thick strokes.
2458
2459The fill path constructed to describe the stroked path respects the join setting but may
2460not contain the actual join. For instance, a fill path constructed with round joins does
2461not necessarily include circles at each connected segment.
2462
2463#Const kMiter_Join 0
2464 Extends the outside corner to the extent allowed by Miter_Limit.
2465 If the extension exceeds Miter_Limit, kBevel_Join is used instead.
2466##
2467
2468#Const kRound_Join 1
2469 Adds a circle with a diameter of Stroke_Width at the sharp corner.
2470##
2471
2472#Const kBevel_Join 2
2473 Connects the outside edges of the sharp corner.
2474##
2475
2476#Const kLast_Join 2
2477 Equivalent to the largest value for Stroke_Join.
2478##
2479
2480#Const kDefault_Join 1
2481 Equivalent to kMiter_Join.
2482 Stroke_Join is set to kMiter_Join by default.
2483##
2484
2485#Const kJoinCount 3
2486 The number of different Stroke_Join values defined.
2487 May be used to verify that Stroke_Join is a legal value.
2488##
2489
2490#Example
2491#Width 462
2492void draw(SkCanvas* canvas) {
2493 SkPath path;
2494 path.moveTo(10, 50);
2495 path.quadTo(35, 110, 60, 210);
2496 path.quadTo(105, 110, 130, 10);
2497 SkPaint paint; // set to default kMiter_Join
2498 paint.setAntiAlias(true);
2499 paint.setStyle(SkPaint::kStroke_Style);
2500 paint.setStrokeWidth(20);
2501 canvas->drawPath(path, paint);
2502 canvas->translate(150, 0);
2503 paint.setStrokeJoin(SkPaint::kBevel_Join);
2504 canvas->drawPath(path, paint);
2505 canvas->translate(150, 0);
2506 paint.setStrokeJoin(SkPaint::kRound_Join);
2507 canvas->drawPath(path, paint);
2508}
2509##
2510
2511#SeeAlso setStrokeJoin getStrokeJoin setStrokeMiter getStrokeMiter
2512
2513#Enum ##
2514
2515#Method Join getStrokeJoin() const
2516
Cary Clarkab2621d2018-01-30 10:08:57 -05002517#In Stroke_Join
2518#Line # returns Join, geometry on path corners ##
Cary Clark0c5f5462017-12-15 11:21:51 -05002519 The geometry drawn at the corners of strokes.
Cary Clark8032b982017-07-28 11:04:54 -04002520
2521 #Return one of: kMiter_Join, kRound_Join, kBevel_Join ##
2522
2523 #Example
2524 SkPaint paint;
2525 SkDebugf("kMiter_Join %c= default stroke join\n",
2526 SkPaint::kMiter_Join == paint.getStrokeJoin() ? '=' : '!');
2527
2528 #StdOut
2529 kMiter_Join == default stroke join
2530 ##
2531 ##
2532
2533 #SeeAlso Stroke_Join setStrokeJoin
2534##
2535
2536#Method void setStrokeJoin(Join join)
2537
Cary Clarkab2621d2018-01-30 10:08:57 -05002538#In Stroke_Join
2539#Line # sets Join, geometry on path corners ##
Cary Clark0c5f5462017-12-15 11:21:51 -05002540 The geometry drawn at the corners of strokes.
Cary Clark8032b982017-07-28 11:04:54 -04002541
2542 #Param join one of: kMiter_Join, kRound_Join, kBevel_Join;
Cary Clark579985c2017-07-31 11:48:27 -04002543 otherwise, has no effect
Cary Clark8032b982017-07-28 11:04:54 -04002544 ##
2545
2546 #Example
2547 SkPaint paint;
2548 paint.setStrokeJoin(SkPaint::kMiter_Join);
2549 paint.setStrokeJoin((SkPaint::Join) SkPaint::kJoinCount);
2550 SkDebugf("kMiter_Join %c= paint.getStrokeJoin()\n",
2551 SkPaint::kMiter_Join == paint.getStrokeJoin() ? '=' : '!');
2552
2553 #StdOut
2554 kMiter_Join == paint.getStrokeJoin()
2555 ##
2556 ##
2557
2558 #SeeAlso Stroke_Join getStrokeJoin
2559##
2560
2561#SeeAlso Miter_Limit
2562
Cary Clark08895c42018-02-01 09:37:32 -05002563#Subtopic Stroke_Join ##
Cary Clark8032b982017-07-28 11:04:54 -04002564# ------------------------------------------------------------------------------
Cary Clark08895c42018-02-01 09:37:32 -05002565#Subtopic Fill_Path
2566#Line # make Path from Path_Effect, stroking ##
Cary Clark8032b982017-07-28 11:04:54 -04002567
2568Fill_Path creates a Path by applying the Path_Effect, followed by the Style_Stroke.
2569
2570If Paint contains Path_Effect, Path_Effect operates on the source Path; the result
2571replaces the destination Path. Otherwise, the source Path is replaces the
2572destination Path.
2573
2574Fill Path can request the Path_Effect to restrict to a culling rectangle, but
2575the Path_Effect is not required to do so.
2576
2577If Style is kStroke_Style or kStrokeAndFill_Style,
2578and Stroke_Width is greater than zero, the Stroke_Width, Stroke_Cap, Stroke_Join,
2579and Miter_Limit operate on the destination Path, replacing it.
2580
2581Fill Path can specify the precision used by Stroke_Width to approximate the stroke geometry.
2582
2583If the Style is kStroke_Style and the Stroke_Width is zero, getFillPath
2584returns false since Hairline has no filled equivalent.
2585
2586#Method bool getFillPath(const SkPath& src, SkPath* dst, const SkRect* cullRect,
2587 SkScalar resScale = 1) const
Cary Clarkab2621d2018-01-30 10:08:57 -05002588#In Fill_Path
2589#Line # returns fill path equivalent to stroke ##
Cary Clark8032b982017-07-28 11:04:54 -04002590
2591 The filled equivalent of the stroked path.
2592
2593 #Param src Path read to create a filled version ##
2594 #Param dst resulting Path; may be the same as src, but may not be nullptr ##
2595 #Param cullRect optional limit passed to Path_Effect ##
2596 #Param resScale if > 1, increase precision, else if (0 < res < 1) reduce precision
2597 to favor speed and size
2598 ##
2599 #Return true if the path represents Style_Fill, or false if it represents Hairline ##
2600
2601 #Example
2602 #Height 192
2603 #Description
Cary Clarkce101242017-09-01 15:51:02 -04002604 A very small Quad stroke is turned into a filled path with increasing levels of precision.
2605 At the lowest precision, the Quad stroke is approximated by a rectangle.
Cary Clark8032b982017-07-28 11:04:54 -04002606 At the highest precision, the filled path has high fidelity compared to the original stroke.
2607 ##
2608 void draw(SkCanvas* canvas) {
2609 SkPaint strokePaint;
2610 strokePaint.setAntiAlias(true);
2611 strokePaint.setStyle(SkPaint::kStroke_Style);
2612 strokePaint.setStrokeWidth(.1f);
2613 SkPath strokePath;
2614 strokePath.moveTo(.08f, .08f);
2615 strokePath.quadTo(.09f, .08f, .17f, .17f);
2616 SkPath fillPath;
2617 SkPaint outlinePaint(strokePaint);
2618 outlinePaint.setStrokeWidth(2);
2619 SkMatrix scale = SkMatrix::MakeScale(300, 300);
2620 for (SkScalar precision : { 0.01f, .1f, 1.f, 10.f, 100.f } ) {
2621 strokePaint.getFillPath(strokePath, &fillPath, nullptr, precision);
2622 fillPath.transform(scale);
2623 canvas->drawPath(fillPath, outlinePaint);
2624 canvas->translate(60, 0);
2625 if (1.f == precision) canvas->translate(-180, 100);
2626 }
2627 strokePath.transform(scale);
2628 strokePaint.setStrokeWidth(30);
2629 canvas->drawPath(strokePath, strokePaint);
2630 }
2631 ##
2632
2633##
2634
2635#Method bool getFillPath(const SkPath& src, SkPath* dst) const
2636
Cary Clarkab2621d2018-01-30 10:08:57 -05002637#In Fill_Path
Cary Clark8032b982017-07-28 11:04:54 -04002638 The filled equivalent of the stroked path.
2639
2640 Replaces dst with the src path modified by Path_Effect and Style_Stroke.
2641 Path_Effect, if any, is not culled. Stroke_Width is created with default precision.
2642
2643 #Param src Path read to create a filled version ##
2644 #Param dst resulting Path dst may be the same as src, but may not be nullptr ##
2645 #Return true if the path represents Style_Fill, or false if it represents Hairline ##
2646
2647 #Example
2648 #Height 128
2649 void draw(SkCanvas* canvas) {
2650 SkPaint paint;
2651 paint.setStyle(SkPaint::kStroke_Style);
2652 paint.setStrokeWidth(10);
2653 SkPath strokePath;
2654 strokePath.moveTo(20, 20);
2655 strokePath.lineTo(100, 100);
2656 canvas->drawPath(strokePath, paint);
2657 SkPath fillPath;
2658 paint.getFillPath(strokePath, &fillPath);
2659 paint.setStrokeWidth(2);
2660 canvas->translate(40, 0);
2661 canvas->drawPath(fillPath, paint);
2662 }
2663 ##
2664
2665##
2666
2667#SeeAlso Style_Stroke Stroke_Width Path_Effect
2668
Cary Clark08895c42018-02-01 09:37:32 -05002669#Subtopic Fill_Path ##
Cary Clark8032b982017-07-28 11:04:54 -04002670# ------------------------------------------------------------------------------
Cary Clark08895c42018-02-01 09:37:32 -05002671#Subtopic Shader_Methods
2672#Line # get and set Shader ##
Cary Clark8032b982017-07-28 11:04:54 -04002673
2674Shader defines the colors used when drawing a shape.
2675Shader may be an image, a gradient, or a computed fill.
2676If Paint has no Shader, then Color fills the shape.
2677
2678Shader is modulated by Color_Alpha component of Color.
2679If Shader object defines only Color_Alpha, then Color modulated by Color_Alpha describes
2680the fill.
2681
2682The drawn transparency can be modified without altering Shader, by changing Color_Alpha.
2683
2684#Example
2685void draw(SkCanvas* canvas) {
2686 SkPaint paint;
2687 SkPoint center = { 50, 50 };
2688 SkScalar radius = 50;
2689 const SkColor colors[] = { 0xFFFFFFFF, 0xFF000000 };
2690 paint.setShader(SkGradientShader::MakeRadial(center, radius, colors,
2691 nullptr, SK_ARRAY_COUNT(colors), SkShader::kClamp_TileMode));
2692 for (SkScalar a : { 0.3f, 0.6f, 1.0f } ) {
2693 paint.setAlpha((int) (a * 255));
2694 canvas->drawCircle(center.fX, center.fY, radius, paint);
2695 canvas->translate(70, 70);
2696 }
2697}
2698##
2699
2700If Shader generates only Color_Alpha then all components of Color modulate the output.
2701
2702#Example
2703void draw(SkCanvas* canvas) {
2704 SkPaint paint;
2705 SkBitmap bitmap;
2706 bitmap.setInfo(SkImageInfo::MakeA8(5, 1), 5); // bitmap only contains alpha
2707 uint8_t pixels[5] = { 0x22, 0x55, 0x88, 0xBB, 0xFF };
2708 bitmap.setPixels(pixels);
2709 paint.setShader(SkShader::MakeBitmapShader(bitmap,
2710 SkShader::kMirror_TileMode, SkShader::kMirror_TileMode));
2711 for (SkColor c : { SK_ColorRED, SK_ColorBLUE, SK_ColorGREEN } ) {
2712 paint.setColor(c); // all components in color affect shader
2713 canvas->drawCircle(50, 50, 50, paint);
2714 canvas->translate(70, 70);
2715 }
2716}
2717##
2718
2719#Method SkShader* getShader() const
2720
Cary Clarkab2621d2018-01-30 10:08:57 -05002721#In Shader_Methods
2722#Line # returns Shader, multiple drawing colors; gradients ##
Cary Clark8032b982017-07-28 11:04:54 -04002723 Optional colors used when filling a path, such as a gradient.
2724
2725 Does not alter Shader Reference_Count.
2726
2727 #Return Shader if previously set, nullptr otherwise ##
2728
2729 #Example
2730 void draw(SkCanvas* canvas) {
2731 SkPaint paint;
2732 SkDebugf("nullptr %c= shader\n", paint.getShader() ? '!' : '=');
2733 paint.setShader(SkShader::MakeEmptyShader());
2734 SkDebugf("nullptr %c= shader\n", paint.getShader() ? '!' : '=');
2735 }
2736
2737 #StdOut
2738 nullptr == shader
2739 nullptr != shader
2740 ##
2741 ##
2742
2743##
2744
2745#Method sk_sp<SkShader> refShader() const
2746
Cary Clarkab2621d2018-01-30 10:08:57 -05002747#In Shader_Methods
2748#Line # references Shader, multiple drawing colors; gradients ##
Cary Clark8032b982017-07-28 11:04:54 -04002749 Optional colors used when filling a path, such as a gradient.
2750
2751 Increases Shader Reference_Count by one.
2752
2753 #Return Shader if previously set, nullptr otherwise ##
2754
2755 #Example
2756 void draw(SkCanvas* canvas) {
2757 SkPaint paint1, paint2;
2758 paint1.setShader(SkShader::MakeEmptyShader());
2759 SkDebugf("shader unique: %s\n", paint1.getShader()->unique() ? "true" : "false");
2760 paint2.setShader(paint1.refShader());
2761 SkDebugf("shader unique: %s\n", paint1.getShader()->unique() ? "true" : "false");
2762 }
2763
2764 #StdOut
2765 shader unique: true
2766 shader unique: false
2767 ##
2768 ##
2769
2770##
2771
2772#Method void setShader(sk_sp<SkShader> shader)
2773
Cary Clarkab2621d2018-01-30 10:08:57 -05002774#In Shader_Methods
2775#Line # sets Shader, multiple drawing colors; gradients ##
Cary Clark8032b982017-07-28 11:04:54 -04002776 Optional colors used when filling a path, such as a gradient.
2777
Cary Clarkd0530ba2017-09-14 11:25:39 -04002778 Sets Shader to shader, decreasing Reference_Count of the previous Shader.
Cary Clark6fc50412017-09-21 12:31:06 -04002779 Increments shader Reference_Count by one.
Cary Clark8032b982017-07-28 11:04:54 -04002780
2781 #Param shader how geometry is filled with color; if nullptr, Color is used instead ##
2782
2783 #Example
2784 #Height 64
2785 void draw(SkCanvas* canvas) {
2786 SkPaint paint;
2787 paint.setColor(SK_ColorBLUE);
2788 paint.setShader(SkShader::MakeColorShader(SK_ColorRED));
2789 canvas->drawRect(SkRect::MakeWH(40, 40), paint);
2790 paint.setShader(nullptr);
2791 canvas->translate(50, 0);
2792 canvas->drawRect(SkRect::MakeWH(40, 40), paint);
2793 }
2794 ##
2795
2796##
2797
Cary Clark08895c42018-02-01 09:37:32 -05002798#Subtopic Shader_Methods ##
Cary Clark8032b982017-07-28 11:04:54 -04002799# ------------------------------------------------------------------------------
Cary Clark08895c42018-02-01 09:37:32 -05002800#Subtopic Color_Filter_Methods
2801#Line # get and set Color_Filter ##
Cary Clark8032b982017-07-28 11:04:54 -04002802
2803Color_Filter alters the color used when drawing a shape.
2804Color_Filter may apply Blend_Mode, transform the color through a matrix, or composite multiple filters.
2805If Paint has no Color_Filter, the color is unaltered.
2806
2807The drawn transparency can be modified without altering Color_Filter, by changing Color_Alpha.
2808
2809#Example
2810#Height 128
2811void draw(SkCanvas* canvas) {
2812 SkPaint paint;
2813 paint.setColorFilter(SkColorMatrixFilter::MakeLightingFilter(0xFFFFFF, 0xFF0000));
2814 for (SkColor c : { SK_ColorBLACK, SK_ColorGREEN } ) {
2815 paint.setColor(c);
2816 canvas->drawRect(SkRect::MakeXYWH(10, 10, 50, 50), paint);
2817 paint.setAlpha(0x80);
2818 canvas->drawRect(SkRect::MakeXYWH(60, 60, 50, 50), paint);
2819 canvas->translate(100, 0);
2820 }
2821}
2822##
2823
2824#Method SkColorFilter* getColorFilter() const
2825
Cary Clarkab2621d2018-01-30 10:08:57 -05002826#In Color_Filter_Methods
2827#Line # returns Color_Filter, how colors are altered ##
Cary Clark8032b982017-07-28 11:04:54 -04002828 Returns Color_Filter if set, or nullptr.
2829 Does not alter Color_Filter Reference_Count.
2830
2831 #Return Color_Filter if previously set, nullptr otherwise ##
2832
2833 #Example
2834 void draw(SkCanvas* canvas) {
2835 SkPaint paint;
2836 SkDebugf("nullptr %c= color filter\n", paint.getColorFilter() ? '!' : '=');
2837 paint.setColorFilter(SkColorFilter::MakeModeFilter(SK_ColorLTGRAY, SkBlendMode::kSrcIn));
2838 SkDebugf("nullptr %c= color filter\n", paint.getColorFilter() ? '!' : '=');
2839 }
2840
2841 #StdOut
2842 nullptr == color filter
2843 nullptr != color filter
2844 ##
2845 ##
2846##
2847
2848#Method sk_sp<SkColorFilter> refColorFilter() const
2849
Cary Clarkab2621d2018-01-30 10:08:57 -05002850#In Color_Filter_Methods
2851#Line # references Color_Filter, how colors are altered ##
Cary Clark8032b982017-07-28 11:04:54 -04002852 Returns Color_Filter if set, or nullptr.
2853 Increases Color_Filter Reference_Count by one.
2854
2855 #Return Color_Filter if set, or nullptr ##
2856
2857 #Example
2858 void draw(SkCanvas* canvas) {
2859 SkPaint paint1, paint2;
2860 paint1.setColorFilter(SkColorFilter::MakeModeFilter(0xFFFF0000, SkBlendMode::kSrcATop));
2861 SkDebugf("color filter unique: %s\n", paint1.getColorFilter()->unique() ? "true" : "false");
2862 paint2.setColorFilter(paint1.refColorFilter());
2863 SkDebugf("color filter unique: %s\n", paint1.getColorFilter()->unique() ? "true" : "false");
2864 }
2865
2866 #StdOut
2867 color filter unique: true
2868 color filter unique: false
2869 ##
2870 ##
2871##
2872
2873#Method void setColorFilter(sk_sp<SkColorFilter> colorFilter)
2874
Cary Clarkab2621d2018-01-30 10:08:57 -05002875#In Color_Filter_Methods
2876#Line # sets Color_Filter, alters color ##
Cary Clark6fc50412017-09-21 12:31:06 -04002877Sets Color_Filter to filter, decreasing Reference_Count of the previous
2878Color_Filter. Pass nullptr to clear Color_Filter.
2879
2880Increments filter Reference_Count by one.
Cary Clark8032b982017-07-28 11:04:54 -04002881
2882 #Param colorFilter Color_Filter to apply to subsequent draw ##
2883
2884 #Example
2885 #Height 64
2886 void draw(SkCanvas* canvas) {
2887 SkPaint paint;
2888 paint.setColorFilter(SkColorFilter::MakeModeFilter(SK_ColorLTGRAY, SkBlendMode::kSrcIn));
2889 canvas->drawRect(SkRect::MakeWH(50, 50), paint);
2890 paint.setColorFilter(nullptr);
2891 canvas->translate(70, 0);
2892 canvas->drawRect(SkRect::MakeWH(50, 50), paint);
2893 }
2894 ##
2895
2896##
2897
Cary Clark08895c42018-02-01 09:37:32 -05002898#Subtopic Color_Filter_Methods ##
Cary Clark8032b982017-07-28 11:04:54 -04002899# ------------------------------------------------------------------------------
Cary Clark08895c42018-02-01 09:37:32 -05002900#Subtopic Blend_Mode_Methods
2901#Line # get and set Blend_Mode ##
Cary Clark8032b982017-07-28 11:04:54 -04002902
2903Blend_Mode describes how Color combines with the destination color.
2904The default setting, SkBlendMode::kSrcOver, draws the source color
2905over the destination color.
2906
2907#Example
2908void draw(SkCanvas* canvas) {
2909 SkPaint normal, blender;
2910 normal.setColor(0xFF58a889);
2911 blender.setColor(0xFF8958a8);
2912 canvas->clear(0);
2913 for (SkBlendMode m : { SkBlendMode::kSrcOver, SkBlendMode::kSrcIn, SkBlendMode::kSrcOut } ) {
2914 normal.setBlendMode(SkBlendMode::kSrcOver);
2915 canvas->drawOval(SkRect::MakeXYWH(30, 30, 30, 80), normal);
2916 blender.setBlendMode(m);
2917 canvas->drawOval(SkRect::MakeXYWH(10, 50, 80, 30), blender);
2918 canvas->translate(70, 70);
2919 }
2920}
2921##
2922
2923#SeeAlso Blend_Mode
2924
2925#Method SkBlendMode getBlendMode() const
2926
Cary Clarkab2621d2018-01-30 10:08:57 -05002927#In Blend_Mode_Methods
2928#Line # returns Blend_Mode, how colors combine with Device ##
Cary Clark8032b982017-07-28 11:04:54 -04002929 Returns Blend_Mode.
Cary Clark579985c2017-07-31 11:48:27 -04002930 By default, returns SkBlendMode::kSrcOver.
Cary Clark8032b982017-07-28 11:04:54 -04002931
2932 #Return mode used to combine source color with destination color ##
2933
2934 #Example
2935 void draw(SkCanvas* canvas) {
2936 SkPaint paint;
2937 SkDebugf("kSrcOver %c= getBlendMode\n",
2938 SkBlendMode::kSrcOver == paint.getBlendMode() ? '=' : '!');
2939 paint.setBlendMode(SkBlendMode::kSrc);
2940 SkDebugf("kSrcOver %c= getBlendMode\n",
2941 SkBlendMode::kSrcOver == paint.getBlendMode() ? '=' : '!');
2942 }
2943
2944 #StdOut
2945 kSrcOver == getBlendMode
2946 kSrcOver != getBlendMode
2947 ##
2948 ##
2949
2950##
2951
2952#Method bool isSrcOver() const
2953
Cary Clarkab2621d2018-01-30 10:08:57 -05002954#In Blend_Mode_Methods
2955#Line # returns true if Blend_Mode is SkBlendMode::kSrcOver ##
Cary Clark8032b982017-07-28 11:04:54 -04002956 Returns true if Blend_Mode is SkBlendMode::kSrcOver, the default.
2957
2958 #Return true if Blend_Mode is SkBlendMode::kSrcOver ##
2959
2960 #Example
2961 void draw(SkCanvas* canvas) {
2962 SkPaint paint;
2963 SkDebugf("isSrcOver %c= true\n", paint.isSrcOver() ? '=' : '!');
2964 paint.setBlendMode(SkBlendMode::kSrc);
2965 SkDebugf("isSrcOver %c= true\n", paint.isSrcOver() ? '=' : '!');
2966 }
2967
2968 #StdOut
2969 isSrcOver == true
2970 isSrcOver != true
2971 ##
2972 ##
2973
2974##
2975
2976#Method void setBlendMode(SkBlendMode mode)
2977
Cary Clarkab2621d2018-01-30 10:08:57 -05002978#In Blend_Mode_Methods
2979#Line # sets Blend_Mode, how colors combine with destination ##
Cary Clark8032b982017-07-28 11:04:54 -04002980 Sets Blend_Mode to mode.
2981 Does not check for valid input.
2982
2983 #Param mode SkBlendMode used to combine source color and destination ##
2984
2985 #Example
2986 void draw(SkCanvas* canvas) {
2987 SkPaint paint;
2988 SkDebugf("isSrcOver %c= true\n", paint.isSrcOver() ? '=' : '!');
2989 paint.setBlendMode(SkBlendMode::kSrc);
2990 SkDebugf("isSrcOver %c= true\n", paint.isSrcOver() ? '=' : '!');
2991 }
2992
2993 #StdOut
2994 isSrcOver == true
2995 isSrcOver != true
2996 ##
2997 ##
2998
2999##
3000
Cary Clark08895c42018-02-01 09:37:32 -05003001#Subtopic Blend_Mode_Methods ##
Cary Clark8032b982017-07-28 11:04:54 -04003002# ------------------------------------------------------------------------------
Cary Clark08895c42018-02-01 09:37:32 -05003003#Subtopic Path_Effect_Methods
3004#Line # get and set Path_Effect ##
Cary Clark8032b982017-07-28 11:04:54 -04003005
3006Path_Effect modifies the path geometry before drawing it.
3007Path_Effect may implement dashing, custom fill effects and custom stroke effects.
3008If Paint has no Path_Effect, the path geometry is unaltered when filled or stroked.
3009
3010#Example
3011#Height 160
3012 void draw(SkCanvas* canvas) {
3013 SkPaint paint;
3014 paint.setStyle(SkPaint::kStroke_Style);
3015 paint.setStrokeWidth(16);
3016 SkScalar intervals[] = {30, 10};
3017 paint.setPathEffect(SkDashPathEffect::Make(intervals, SK_ARRAY_COUNT(intervals), 1));
3018 canvas->drawRoundRect({20, 20, 120, 120}, 20, 20, paint);
3019 }
3020##
3021
3022#SeeAlso Path_Effect
3023
3024#Method SkPathEffect* getPathEffect() const
3025
Cary Clarkab2621d2018-01-30 10:08:57 -05003026#In Path_Effect_Methods
3027#Line # returns Path_Effect, modifications to path geometry; dashing ##
Cary Clark8032b982017-07-28 11:04:54 -04003028 Returns Path_Effect if set, or nullptr.
3029 Does not alter Path_Effect Reference_Count.
3030
3031 #Return Path_Effect if previously set, nullptr otherwise ##
3032
3033 #Example
3034 void draw(SkCanvas* canvas) {
3035 SkPaint paint;
3036 SkDebugf("nullptr %c= path effect\n", paint.getPathEffect() ? '!' : '=');
3037 paint.setPathEffect(SkCornerPathEffect::Make(10));
3038 SkDebugf("nullptr %c= path effect\n", paint.getPathEffect() ? '!' : '=');
3039 }
3040
3041 #StdOut
3042 nullptr == path effect
3043 nullptr != path effect
3044 ##
3045 ##
3046
3047##
3048
3049
3050#Method sk_sp<SkPathEffect> refPathEffect() const
3051
Cary Clarkab2621d2018-01-30 10:08:57 -05003052#In Path_Effect_Methods
3053#Line # references Path_Effect, modifications to path geometry; dashing ##
Cary Clark8032b982017-07-28 11:04:54 -04003054 Returns Path_Effect if set, or nullptr.
3055 Increases Path_Effect Reference_Count by one.
3056
3057 #Return Path_Effect if previously set, nullptr otherwise ##
3058
3059 #Example
3060 void draw(SkCanvas* canvas) {
3061 SkPaint paint1, paint2;
Cary Clarka560c472017-11-27 10:44:06 -05003062 SkScalar intervals[] = {1, 2};
3063 paint1.setPathEffect(SkDashPathEffect::Make(intervals, SK_ARRAY_COUNT(intervals), 10));
Cary Clark8032b982017-07-28 11:04:54 -04003064 SkDebugf("path effect unique: %s\n", paint1.getPathEffect()->unique() ? "true" : "false");
3065 paint2.setPathEffect(paint1.refPathEffect());
3066 SkDebugf("path effect unique: %s\n", paint1.getPathEffect()->unique() ? "true" : "false");
3067 }
3068
3069 #StdOut
3070 path effect unique: true
3071 path effect unique: false
3072 ##
3073 ##
3074
3075##
3076
3077
3078#Method void setPathEffect(sk_sp<SkPathEffect> pathEffect)
3079
Cary Clarkab2621d2018-01-30 10:08:57 -05003080#In Path_Effect_Methods
3081#Line # sets Path_Effect, modifications to path geometry; dashing ##
Cary Clark6fc50412017-09-21 12:31:06 -04003082Sets Path_Effect to pathEffect, decreasing Reference_Count of the previous
3083Path_Effect. Pass nullptr to leave the path geometry unaltered.
3084
3085Increments pathEffect Reference_Count by one.
Cary Clark8032b982017-07-28 11:04:54 -04003086
3087 #Param pathEffect replace Path with a modification when drawn ##
3088
3089 #Example
3090 void draw(SkCanvas* canvas) {
3091 SkPaint paint;
3092 paint.setPathEffect(SkDiscretePathEffect::Make(3, 5));
3093 canvas->drawRect(SkRect::MakeXYWH(40, 40, 175, 175), paint);
3094 }
3095 ##
3096
3097##
3098
Cary Clark08895c42018-02-01 09:37:32 -05003099#Subtopic Path_Effect_Methods ##
Cary Clark8032b982017-07-28 11:04:54 -04003100# ------------------------------------------------------------------------------
Cary Clark08895c42018-02-01 09:37:32 -05003101#Subtopic Mask_Filter_Methods
3102#Line # get and set Mask_Filter ##
Cary Clark8032b982017-07-28 11:04:54 -04003103
Cary Clarkce101242017-09-01 15:51:02 -04003104Mask_Filter uses coverage of the shape drawn to create Mask_Alpha.
Mike Reed8ad91a92018-01-19 19:09:32 -05003105Mask_Filter takes a Mask, and returns a Mask.
Cary Clark6fc50412017-09-21 12:31:06 -04003106
3107Mask_Filter may change the geometry and transparency of the shape, such as
3108creating a blur effect. Set Mask_Filter to nullptr to prevent Mask_Filter from
3109modifying the draw.
Cary Clark8032b982017-07-28 11:04:54 -04003110
3111#Example
3112 void draw(SkCanvas* canvas) {
3113 SkPaint paint;
3114 paint.setMaskFilter(SkBlurMaskFilter::Make(kSolid_SkBlurStyle, 3));
3115 canvas->drawRect(SkRect::MakeXYWH(40, 40, 175, 175), paint);
3116 }
3117##
3118
3119#Method SkMaskFilter* getMaskFilter() const
3120
Cary Clarkab2621d2018-01-30 10:08:57 -05003121#In Mask_Filter_Methods
3122#Line # returns Mask_Filter, alterations to Mask_Alpha ##
Cary Clark8032b982017-07-28 11:04:54 -04003123 Returns Mask_Filter if set, or nullptr.
3124 Does not alter Mask_Filter Reference_Count.
3125
3126 #Return Mask_Filter if previously set, nullptr otherwise ##
3127
3128 #Example
3129 void draw(SkCanvas* canvas) {
3130 SkPaint paint;
3131 SkDebugf("nullptr %c= mask filter\n", paint.getMaskFilter() ? '!' : '=');
3132 paint.setMaskFilter(SkBlurMaskFilter::Make(kOuter_SkBlurStyle, 3));
3133 SkDebugf("nullptr %c= mask filter\n", paint.getMaskFilter() ? '!' : '=');
3134 }
3135
3136 #StdOut
3137 nullptr == mask filter
3138 nullptr != mask filter
3139 ##
3140 ##
3141
3142##
3143
3144#Method sk_sp<SkMaskFilter> refMaskFilter() const
3145
Cary Clarkab2621d2018-01-30 10:08:57 -05003146#In Mask_Filter_Methods
3147#Line # references Mask_Filter, alterations to Mask_Alpha ##
Cary Clark8032b982017-07-28 11:04:54 -04003148 Returns Mask_Filter if set, or nullptr.
Cary Clark6fc50412017-09-21 12:31:06 -04003149
Cary Clark8032b982017-07-28 11:04:54 -04003150 Increases Mask_Filter Reference_Count by one.
3151
3152 #Return Mask_Filter if previously set, nullptr otherwise ##
3153
3154 #Example
3155 void draw(SkCanvas* canvas) {
3156 SkPaint paint1, paint2;
3157 paint1.setMaskFilter(SkBlurMaskFilter::Make(kNormal_SkBlurStyle, 1));
3158 SkDebugf("mask filter unique: %s\n", paint1.getMaskFilter()->unique() ? "true" : "false");
3159 paint2.setMaskFilter(paint1.refMaskFilter());
3160 SkDebugf("mask filter unique: %s\n", paint1.getMaskFilter()->unique() ? "true" : "false");
3161 }
3162
3163 #StdOut
3164 mask filter unique: true
3165 mask filter unique: false
3166 ##
3167 ##
3168
3169##
3170
3171#Method void setMaskFilter(sk_sp<SkMaskFilter> maskFilter)
3172
Cary Clarkab2621d2018-01-30 10:08:57 -05003173#In Mask_Filter_Methods
3174#Line # sets Mask_Filter, alterations to Mask_Alpha ##
Cary Clark6fc50412017-09-21 12:31:06 -04003175Sets Mask_Filter to maskFilter, decreasing Reference_Count of the previous
3176Mask_Filter. Pass nullptr to clear Mask_Filter and leave Mask_Filter effect on
3177Mask_Alpha unaltered.
3178
Cary Clark6fc50412017-09-21 12:31:06 -04003179Increments maskFilter Reference_Count by one.
Cary Clark8032b982017-07-28 11:04:54 -04003180
3181 #Param maskFilter modifies clipping mask generated from drawn geometry ##
3182
3183 #Example
3184 void draw(SkCanvas* canvas) {
3185 SkPaint paint;
3186 paint.setStyle(SkPaint::kStroke_Style);
3187 paint.setStrokeWidth(10);
3188 paint.setMaskFilter(SkBlurMaskFilter::Make(kNormal_SkBlurStyle, 10));
3189 canvas->drawRect(SkRect::MakeXYWH(40, 40, 175, 175), paint);
3190 }
3191 ##
3192
3193##
3194
Cary Clark08895c42018-02-01 09:37:32 -05003195#Subtopic Mask_Filter_Methods ##
Cary Clark8032b982017-07-28 11:04:54 -04003196# ------------------------------------------------------------------------------
Cary Clark08895c42018-02-01 09:37:32 -05003197#Subtopic Typeface_Methods
3198#Line # get and set Typeface ##
Cary Clark8032b982017-07-28 11:04:54 -04003199
3200Typeface identifies the font used when drawing and measuring text.
3201Typeface may be specified by name, from a file, or from a data stream.
3202The default Typeface defers to the platform-specific default font
3203implementation.
3204
3205#Example
3206#Height 100
3207 void draw(SkCanvas* canvas) {
3208 SkPaint paint;
Ben Wagner700ff172017-11-08 15:37:22 -05003209 paint.setTypeface(SkTypeface::MakeFromName(nullptr, SkFontStyle()));
Cary Clark8032b982017-07-28 11:04:54 -04003210 paint.setAntiAlias(true);
3211 paint.setTextSize(36);
3212 canvas->drawString("A Big Hello!", 10, 40, paint);
3213 paint.setTypeface(nullptr);
3214 paint.setFakeBoldText(true);
3215 canvas->drawString("A Big Hello!", 10, 80, paint);
3216 }
3217##
3218
3219#Method SkTypeface* getTypeface() const
3220
Cary Clarkab2621d2018-01-30 10:08:57 -05003221#In Typeface_Methods
3222#Line # returns Typeface, font description ##
Cary Clark8032b982017-07-28 11:04:54 -04003223 Returns Typeface if set, or nullptr.
Cary Clark6fc50412017-09-21 12:31:06 -04003224 Increments Typeface Reference_Count by one.
Cary Clark8032b982017-07-28 11:04:54 -04003225
3226 #Return Typeface if previously set, nullptr otherwise ##
3227
3228 #Example
3229 void draw(SkCanvas* canvas) {
3230 SkPaint paint;
3231 SkDebugf("nullptr %c= typeface\n", paint.getTypeface() ? '!' : '=');
Cary Clark71961fb2018-01-05 14:21:59 -05003232 paint.setTypeface(SkTypeface::MakeFromName("monospace", SkFontStyle()));
Cary Clark8032b982017-07-28 11:04:54 -04003233 SkDebugf("nullptr %c= typeface\n", paint.getTypeface() ? '!' : '=');
3234 }
3235
3236 #StdOut
3237 nullptr == typeface
3238 nullptr != typeface
3239 ##
3240 ##
3241
3242##
3243
3244#Method sk_sp<SkTypeface> refTypeface() const
3245
Cary Clarkab2621d2018-01-30 10:08:57 -05003246#In Typeface_Methods
3247#Line # references Typeface, font description ##
Cary Clark8032b982017-07-28 11:04:54 -04003248 Increases Typeface Reference_Count by one.
3249
3250 #Return Typeface if previously set, nullptr otherwise ##
3251
3252 #Example
3253 void draw(SkCanvas* canvas) {
3254 SkPaint paint1, paint2;
Cary Clark71961fb2018-01-05 14:21:59 -05003255 paint1.setTypeface(SkTypeface::MakeFromName("monospace",
Cary Clark8032b982017-07-28 11:04:54 -04003256 SkFontStyle(SkFontStyle::kNormal_Weight, SkFontStyle::kNormal_Width,
3257 SkFontStyle::kItalic_Slant)));
3258 SkDebugf("typeface1 %c= typeface2\n",
3259 paint1.getTypeface() == paint2.getTypeface() ? '=' : '!');
3260 paint2.setTypeface(paint1.refTypeface());
3261 SkDebugf("typeface1 %c= typeface2\n",
3262 paint1.getTypeface() == paint2.getTypeface() ? '=' : '!');
3263 }
3264
3265 #StdOut
3266 typeface1 != typeface2
3267 typeface1 == typeface2
3268 ##
3269 ##
3270
3271##
3272
3273#Method void setTypeface(sk_sp<SkTypeface> typeface)
3274
Cary Clarkab2621d2018-01-30 10:08:57 -05003275#In Typeface_Methods
3276#Line # sets Typeface, font description ##
Cary Clark6fc50412017-09-21 12:31:06 -04003277Sets Typeface to typeface, decreasing Reference_Count of the previous Typeface.
3278Pass nullptr to clear Typeface and use the default typeface. Increments
3279typeface Reference_Count by one.
Cary Clark8032b982017-07-28 11:04:54 -04003280
3281 #Param typeface font and style used to draw text ##
3282
3283 #Example
3284 #Height 64
3285 void draw(SkCanvas* canvas) {
3286 SkPaint paint;
Cary Clark71961fb2018-01-05 14:21:59 -05003287 paint.setTypeface(SkTypeface::MakeFromName("monospace", SkFontStyle()));
3288 canvas->drawString("hamburgerfons", 10, 30, paint);
Cary Clark8032b982017-07-28 11:04:54 -04003289 paint.setTypeface(nullptr);
Cary Clark71961fb2018-01-05 14:21:59 -05003290 canvas->drawString("hamburgerfons", 10, 50, paint);
Cary Clark8032b982017-07-28 11:04:54 -04003291 }
3292 ##
3293
3294##
3295
Cary Clark08895c42018-02-01 09:37:32 -05003296#Subtopic Typeface_Methods ##
Cary Clark8032b982017-07-28 11:04:54 -04003297# ------------------------------------------------------------------------------
Cary Clark08895c42018-02-01 09:37:32 -05003298#Subtopic Image_Filter_Methods
3299#Line # get and set Image_Filter ##
Cary Clark8032b982017-07-28 11:04:54 -04003300
3301Image_Filter operates on the pixel representation of the shape, as modified by Paint
3302with Blend_Mode set to SkBlendMode::kSrcOver. Image_Filter creates a new bitmap,
3303which is drawn to the device using the set Blend_Mode.
Cary Clark6fc50412017-09-21 12:31:06 -04003304
Cary Clark8032b982017-07-28 11:04:54 -04003305Image_Filter is higher level than Mask_Filter; for instance, an Image_Filter
Cary Clarkce101242017-09-01 15:51:02 -04003306can operate on all channels of Color, while Mask_Filter generates Alpha only.
Cary Clark8032b982017-07-28 11:04:54 -04003307Image_Filter operates independently of and can be used in combination with
Mike Reed8ad91a92018-01-19 19:09:32 -05003308Mask_Filter.
Cary Clark8032b982017-07-28 11:04:54 -04003309
3310#Example
3311 #ToDo explain why the two draws are so different ##
3312 void draw(SkCanvas* canvas) {
3313 SkPaint paint;
3314 paint.setStyle(SkPaint::kStroke_Style);
3315 paint.setStrokeWidth(2);
3316 SkRegion region;
3317 region.op( 10, 10, 50, 50, SkRegion::kUnion_Op);
3318 region.op( 10, 50, 90, 90, SkRegion::kUnion_Op);
Cary Clarka560c472017-11-27 10:44:06 -05003319 paint.setImageFilter(SkBlurImageFilter::Make(5.0f, 5.0f, nullptr));
Cary Clark8032b982017-07-28 11:04:54 -04003320 canvas->drawRegion(region, paint);
3321 paint.setImageFilter(nullptr);
3322 paint.setMaskFilter(SkBlurMaskFilter::Make(kNormal_SkBlurStyle, 5));
3323 canvas->translate(100, 100);
3324 canvas->drawRegion(region, paint);
3325 }
3326##
3327
3328#Method SkImageFilter* getImageFilter() const
3329
Cary Clarkab2621d2018-01-30 10:08:57 -05003330#In Image_Filter_Methods
3331#Line # returns Image_Filter, alter pixels; blur ##
Cary Clark8032b982017-07-28 11:04:54 -04003332 Returns Image_Filter if set, or nullptr.
3333 Does not alter Image_Filter Reference_Count.
3334
3335 #Return Image_Filter if previously set, nullptr otherwise ##
3336
3337 #Example
3338 void draw(SkCanvas* canvas) {
3339 SkPaint paint;
3340 SkDebugf("nullptr %c= image filter\n", paint.getImageFilter() ? '!' : '=');
Cary Clarka560c472017-11-27 10:44:06 -05003341 paint.setImageFilter(SkBlurImageFilter::Make(kOuter_SkBlurStyle, 3, nullptr, nullptr));
Cary Clark8032b982017-07-28 11:04:54 -04003342 SkDebugf("nullptr %c= image filter\n", paint.getImageFilter() ? '!' : '=');
3343 }
3344
3345 #StdOut
3346 nullptr == image filter
3347 nullptr != image filter
3348 ##
3349 ##
3350
3351##
3352
3353#Method sk_sp<SkImageFilter> refImageFilter() const
3354
Cary Clarkab2621d2018-01-30 10:08:57 -05003355#In Image_Filter_Methods
3356#Line # references Image_Filter, alter pixels; blur ##
Cary Clark8032b982017-07-28 11:04:54 -04003357 Returns Image_Filter if set, or nullptr.
3358 Increases Image_Filter Reference_Count by one.
3359
3360 #Return Image_Filter if previously set, nullptr otherwise ##
3361
3362 #Example
3363 void draw(SkCanvas* canvas) {
3364 SkPaint paint1, paint2;
3365 paint1.setImageFilter(SkOffsetImageFilter::Make(25, 25, nullptr));
3366 SkDebugf("image filter unique: %s\n", paint1.getImageFilter()->unique() ? "true" : "false");
3367 paint2.setImageFilter(paint1.refImageFilter());
3368 SkDebugf("image filter unique: %s\n", paint1.getImageFilter()->unique() ? "true" : "false");
3369 }
3370
3371 #StdOut
3372 image filter unique: true
3373 image filter unique: false
3374 ##
3375 ##
3376
3377##
3378
3379#Method void setImageFilter(sk_sp<SkImageFilter> imageFilter)
3380
Cary Clarkab2621d2018-01-30 10:08:57 -05003381#In Image_Filter_Methods
3382#Line # sets Image_Filter, alter pixels; blur ##
Cary Clark6fc50412017-09-21 12:31:06 -04003383Sets Image_Filter to imageFilter, decreasing Reference_Count of the previous
3384Image_Filter. Pass nullptr to clear Image_Filter, and remove Image_Filter effect
3385on drawing.
3386
Cary Clark6fc50412017-09-21 12:31:06 -04003387Increments imageFilter Reference_Count by one.
Cary Clark8032b982017-07-28 11:04:54 -04003388
3389 #Param imageFilter how Image is sampled when transformed ##
3390
3391 #Example
3392 #Height 160
3393 void draw(SkCanvas* canvas) {
3394 SkBitmap bitmap;
3395 bitmap.allocN32Pixels(100, 100);
3396 SkCanvas offscreen(bitmap);
3397 SkPaint paint;
3398 paint.setAntiAlias(true);
3399 paint.setColor(SK_ColorWHITE);
3400 paint.setTextSize(96);
3401 offscreen.clear(0);
3402 offscreen.drawString("e", 20, 70, paint);
3403 paint.setImageFilter(
3404 SkLightingImageFilter::MakePointLitDiffuse(SkPoint3::Make(80, 100, 10),
3405 SK_ColorWHITE, 1, 2, nullptr, nullptr));
3406 canvas->drawBitmap(bitmap, 0, 0, &paint);
3407 }
3408 ##
3409
3410##
3411
Cary Clark08895c42018-02-01 09:37:32 -05003412#Subtopic Image_Filter_Methods ##
Cary Clark8032b982017-07-28 11:04:54 -04003413# ------------------------------------------------------------------------------
Cary Clark08895c42018-02-01 09:37:32 -05003414#Subtopic Draw_Looper_Methods
3415#Line # get and set Draw_Looper ##
Cary Clark8032b982017-07-28 11:04:54 -04003416
3417Draw_Looper sets a modifier that communicates state from one Draw_Layer
3418to another to construct the draw.
Cary Clark6fc50412017-09-21 12:31:06 -04003419
Cary Clark8032b982017-07-28 11:04:54 -04003420Draw_Looper draws one or more times, modifying the canvas and paint each time.
3421Draw_Looper may be used to draw multiple colors or create a colored shadow.
3422Set Draw_Looper to nullptr to prevent Draw_Looper from modifying the draw.
3423
3424#Example
3425#Height 128
3426 void draw(SkCanvas* canvas) {
3427 SkLayerDrawLooper::LayerInfo info;
3428 info.fPaintBits = (SkLayerDrawLooper::BitFlags) SkLayerDrawLooper::kColorFilter_Bit;
3429 info.fColorMode = SkBlendMode::kSrc;
3430 SkLayerDrawLooper::Builder looperBuilder;
3431 SkPaint* loopPaint = looperBuilder.addLayer(info);
3432 loopPaint->setColor(SK_ColorRED);
3433 info.fOffset.set(20, 20);
3434 loopPaint = looperBuilder.addLayer(info);
3435 loopPaint->setColor(SK_ColorBLUE);
3436 SkPaint paint;
3437 paint.setDrawLooper(looperBuilder.detach());
3438 canvas->drawCircle(50, 50, 50, paint);
3439 }
3440
3441##
3442
3443#Method SkDrawLooper* getDrawLooper() const
3444
Cary Clarkab2621d2018-01-30 10:08:57 -05003445#In Draw_Looper_Methods
3446#Line # returns Draw_Looper, multiple layers ##
Cary Clark8032b982017-07-28 11:04:54 -04003447 Returns Draw_Looper if set, or nullptr.
3448 Does not alter Draw_Looper Reference_Count.
3449
3450 #Return Draw_Looper if previously set, nullptr otherwise ##
3451
3452 #Example
3453 void draw(SkCanvas* canvas) {
3454 SkPaint paint;
3455 SkDebugf("nullptr %c= draw looper\n", paint.getDrawLooper() ? '!' : '=');
3456 SkLayerDrawLooper::Builder looperBuilder;
3457 paint.setDrawLooper(looperBuilder.detach());
3458 SkDebugf("nullptr %c= draw looper\n", paint.getDrawLooper() ? '!' : '=');
3459 }
3460
3461 #StdOut
3462 nullptr == draw looper
3463 nullptr != draw looper
3464 ##
3465 ##
3466
3467##
3468
3469#Method sk_sp<SkDrawLooper> refDrawLooper() const
3470
Cary Clarkab2621d2018-01-30 10:08:57 -05003471#In Draw_Looper_Methods
3472#Line # references Draw_Looper, multiple layers ##
Cary Clark8032b982017-07-28 11:04:54 -04003473 Returns Draw_Looper if set, or nullptr.
3474 Increases Draw_Looper Reference_Count by one.
3475
3476 #Return Draw_Looper if previously set, nullptr otherwise ##
3477
3478 #Example
3479 void draw(SkCanvas* canvas) {
3480 SkPaint paint1, paint2;
3481 SkLayerDrawLooper::Builder looperBuilder;
3482 paint1.setDrawLooper(looperBuilder.detach());
3483 SkDebugf("draw looper unique: %s\n", paint1.getDrawLooper()->unique() ? "true" : "false");
3484 paint2.setDrawLooper(paint1.refDrawLooper());
3485 SkDebugf("draw looper unique: %s\n", paint1.getDrawLooper()->unique() ? "true" : "false");
3486 }
3487
3488 #StdOut
3489 draw looper unique: true
3490 draw looper unique: false
3491 ##
3492 ##
3493
3494##
3495
3496#Method SkDrawLooper* getLooper() const
Cary Clark4855f782018-02-06 09:41:53 -05003497#Bug 6259
Cary Clark8032b982017-07-28 11:04:54 -04003498#Deprecated
Cary Clark8032b982017-07-28 11:04:54 -04003499##
3500
3501#Method void setDrawLooper(sk_sp<SkDrawLooper> drawLooper)
Cary Clarkab2621d2018-01-30 10:08:57 -05003502#In Draw_Looper_Methods
3503#Line # sets Draw_Looper, multiple layers ##
Cary Clark6fc50412017-09-21 12:31:06 -04003504Sets Draw_Looper to drawLooper, decreasing Reference_Count of the previous
3505drawLooper. Pass nullptr to clear Draw_Looper and leave Draw_Looper effect on
3506drawing unaltered.
3507
3508Increments drawLooper Reference_Count by one.
Cary Clark8032b982017-07-28 11:04:54 -04003509
Cary Clarka523d2d2017-08-30 08:58:10 -04003510 #Param drawLooper iterates through drawing one or more time, altering Paint ##
Cary Clark8032b982017-07-28 11:04:54 -04003511
3512 #Example
3513 #Height 128
3514 void draw(SkCanvas* canvas) {
3515 SkPaint paint;
3516 paint.setDrawLooper(SkBlurDrawLooper::Make(0x7FFF0000, 4, -5, -10));
3517 paint.setStyle(SkPaint::kStroke_Style);
3518 paint.setStrokeWidth(10);
3519 paint.setAntiAlias(true);
3520 paint.setColor(0x7f0000ff);
3521 canvas->drawCircle(70, 70, 50, paint);
3522 }
3523 ##
3524
3525##
3526
3527#Method void setLooper(sk_sp<SkDrawLooper> drawLooper)
Cary Clark4855f782018-02-06 09:41:53 -05003528#Bug 6259
Cary Clark8032b982017-07-28 11:04:54 -04003529#Deprecated
Cary Clark8032b982017-07-28 11:04:54 -04003530##
3531
Cary Clark08895c42018-02-01 09:37:32 -05003532#Subtopic Draw_Looper_Methods ##
Cary Clark4855f782018-02-06 09:41:53 -05003533
Cary Clark8032b982017-07-28 11:04:54 -04003534# ------------------------------------------------------------------------------
Cary Clark08895c42018-02-01 09:37:32 -05003535#Subtopic Text_Align
3536#Line # text placement relative to position ##
Cary Clark8032b982017-07-28 11:04:54 -04003537
3538#Enum Align
Cary Clark08895c42018-02-01 09:37:32 -05003539#Line # glyph locations relative to text position ##
Cary Clark8032b982017-07-28 11:04:54 -04003540#Code
3541 enum Align {
3542 kLeft_Align,
3543 kCenter_Align,
3544 kRight_Align,
3545 };
3546##
3547
3548Align adjusts the text relative to the text position.
Cary Clarkce101242017-09-01 15:51:02 -04003549Align affects Glyphs drawn with: SkCanvas::drawText, SkCanvas::drawPosText,
Cary Clark8032b982017-07-28 11:04:54 -04003550SkCanvas::drawPosTextH, SkCanvas::drawTextOnPath,
3551SkCanvas::drawTextOnPathHV, SkCanvas::drawTextRSXform, SkCanvas::drawTextBlob,
3552and SkCanvas::drawString;
Cary Clarkce101242017-09-01 15:51:02 -04003553as well as calls that place text Glyphs like getTextWidths and getTextPath.
Cary Clark8032b982017-07-28 11:04:54 -04003554
3555The text position is set by the font for both horizontal and vertical text.
3556Typically, for horizontal text, the position is to the left side of the glyph on the
3557base line; and for vertical text, the position is the horizontal center of the glyph
3558at the caps height.
3559
3560Align adjusts the glyph position to center it or move it to abut the position
3561using the metrics returned by the font.
3562
3563Align defaults to kLeft_Align.
3564
3565#Const kLeft_Align 0
3566 Leaves the glyph at the position computed by the font offset by the text position.
3567##
3568
3569#Const kCenter_Align 1
3570 Moves the glyph half its width if Flags has kVerticalText_Flag clear, and
3571 half its height if Flags has kVerticalText_Flag set.
3572##
3573
3574#Const kRight_Align 2
3575 Moves the glyph by its width if Flags has kVerticalText_Flag clear,
3576 and by its height if Flags has kVerticalText_Flag set.
3577##
3578
3579#Enum ##
3580
3581#Enum
Cary Clark08895c42018-02-01 09:37:32 -05003582#Line # number of Text_Align values ##
Cary Clark8032b982017-07-28 11:04:54 -04003583
3584#Code
3585 enum {
Cary Clarkbad5ad72017-08-03 17:14:08 -04003586 kAlignCount = 3,
Cary Clark8032b982017-07-28 11:04:54 -04003587 };
3588##
3589
3590#Const kAlignCount 3
3591 The number of different Text_Align values defined.
3592##
3593
3594#Enum ##
3595
3596#Example
3597 #Height 160
3598 #Description
3599 Each position separately moves the glyph in drawPosText.
3600 ##
3601 void draw(SkCanvas* canvas) {
3602 SkPaint paint;
3603 paint.setTextSize(40);
3604 SkPoint position[] = {{100, 50}, {150, 40}};
3605 for (SkPaint::Align a : { SkPaint::kLeft_Align,
3606 SkPaint::kCenter_Align,
3607 SkPaint::kRight_Align}) {
3608 paint.setTextAlign(a);
3609 canvas->drawPosText("Aa", 2, position, paint);
3610 canvas->translate(0, 50);
3611 }
3612 }
3613##
3614
3615#Example
3616 #Height 160
3617 #Description
3618 Vertical_Text treats kLeft_Align as top align, and kRight_Align as bottom align.
3619 ##
3620 void draw(SkCanvas* canvas) {
3621 SkPaint paint;
3622 paint.setTextSize(40);
3623 paint.setVerticalText(true);
3624 for (SkPaint::Align a : { SkPaint::kLeft_Align,
3625 SkPaint::kCenter_Align,
3626 SkPaint::kRight_Align }) {
3627 paint.setTextAlign(a);
3628 canvas->drawString("Aa", 50, 80, paint);
3629 canvas->translate(50, 0);
3630 }
3631 }
3632##
3633
3634#Method Align getTextAlign() const
3635
Cary Clarkab2621d2018-01-30 10:08:57 -05003636#In Text_Align
3637#Line # returns Align: left, center, or right ##
Cary Clark8032b982017-07-28 11:04:54 -04003638 Returns Text_Align.
3639 Returns kLeft_Align if Text_Align has not been set.
3640
3641 #Return text placement relative to position ##
3642
3643 #Example
3644 SkPaint paint;
3645 SkDebugf("kLeft_Align %c= default\n", SkPaint::kLeft_Align == paint.getTextAlign() ? '=' : '!');
3646
3647 #StdOut
3648 kLeft_Align == default
3649 ##
3650 ##
3651##
3652
3653#Method void setTextAlign(Align align)
3654
Cary Clarkab2621d2018-01-30 10:08:57 -05003655#In Text_Align
3656#Line # sets Align: left, center, or right ##
Cary Clark8032b982017-07-28 11:04:54 -04003657 Sets Text_Align to align.
3658 Has no effect if align is an invalid value.
3659
3660 #Param align text placement relative to position ##
3661
3662 #Example
3663 #Height 160
3664 #Description
3665 Text is left-aligned by default, and then set to center. Setting the
3666 alignment out of range has no effect.
3667 ##
3668 void draw(SkCanvas* canvas) {
3669 SkPaint paint;
3670 paint.setTextSize(40);
3671 canvas->drawString("Aa", 100, 50, paint);
3672 paint.setTextAlign(SkPaint::kCenter_Align);
3673 canvas->drawString("Aa", 100, 100, paint);
3674 paint.setTextAlign((SkPaint::Align) SkPaint::kAlignCount);
3675 canvas->drawString("Aa", 100, 150, paint);
3676 }
3677 ##
3678
3679##
3680
Cary Clark08895c42018-02-01 09:37:32 -05003681#Subtopic Text_Align ##
Cary Clark8032b982017-07-28 11:04:54 -04003682# ------------------------------------------------------------------------------
Cary Clark08895c42018-02-01 09:37:32 -05003683#Subtopic Text_Size
3684#Line # overall height in points ##
Cary Clark8032b982017-07-28 11:04:54 -04003685
3686Text_Size adjusts the overall text size in points.
3687Text_Size can be set to any positive value or zero.
3688Text_Size defaults to 12.
3689Set SkPaintDefaults_TextSize at compile time to change the default setting.
3690
3691#Example
3692#Height 135
3693 void draw(SkCanvas* canvas) {
3694 SkPaint paint;
3695 canvas->drawString("12 point", 10, 20, paint);
3696 paint.setTextSize(24);
3697 canvas->drawString("24 point", 10, 60, paint);
3698 paint.setTextSize(48);
3699 canvas->drawString("48 point", 10, 120, paint);
3700 }
3701##
3702
3703#Method SkScalar getTextSize() const
3704
Cary Clarkab2621d2018-01-30 10:08:57 -05003705#In Text_Size
3706#Line # returns text size in points ##
Cary Clark8032b982017-07-28 11:04:54 -04003707 Returns Text_Size in points.
3708
3709 #Return typographic height of text ##
3710
3711 #Example
3712 SkPaint paint;
3713 SkDebugf("12 %c= default text size\n", 12 == paint.getTextSize() ? '=' : '!');
3714 ##
3715
3716##
3717
3718#Method void setTextSize(SkScalar textSize)
3719
Cary Clarkab2621d2018-01-30 10:08:57 -05003720#In Text_Size
3721#Line # sets text size in points ##
Cary Clark8032b982017-07-28 11:04:54 -04003722 Sets Text_Size in points.
3723 Has no effect if textSize is not greater than or equal to zero.
3724
3725 #Param textSize typographic height of text ##
3726
3727 #Example
3728 SkPaint paint;
3729 SkDebugf("12 %c= text size\n", 12 == paint.getTextSize() ? '=' : '!');
3730 paint.setTextSize(-20);
3731 SkDebugf("12 %c= text size\n", 12 == paint.getTextSize() ? '=' : '!');
3732 ##
3733
3734##
3735
Cary Clark08895c42018-02-01 09:37:32 -05003736#Subtopic Text_Size ##
Cary Clark8032b982017-07-28 11:04:54 -04003737# ------------------------------------------------------------------------------
Cary Clark08895c42018-02-01 09:37:32 -05003738#Subtopic Text_Scale_X
3739#Line # text horizontal scale ##
Cary Clark8032b982017-07-28 11:04:54 -04003740
3741Text_Scale_X adjusts the text horizontal scale.
3742Text scaling approximates condensed and expanded type faces when the actual face
3743is not available.
3744Text_Scale_X can be set to any value.
3745Text_Scale_X defaults to 1.
3746
3747#Example
3748#Height 128
3749 void draw(SkCanvas* canvas) {
3750 SkPaint paint;
3751 paint.setAntiAlias(true);
3752 paint.setTextSize(24);
3753 paint.setTextScaleX(.8f);
3754 canvas->drawString("narrow", 10, 20, paint);
3755 paint.setTextScaleX(1);
3756 canvas->drawString("normal", 10, 60, paint);
3757 paint.setTextScaleX(1.2f);
3758 canvas->drawString("wide", 10, 100, paint);
3759 }
3760##
3761
3762#Method SkScalar getTextScaleX() const
3763
Cary Clarkab2621d2018-01-30 10:08:57 -05003764#In Text_Scale_X
3765#Line # returns the text horizontal scale; condensed text ##
Cary Clark8032b982017-07-28 11:04:54 -04003766 Returns Text_Scale_X.
3767 Default value is 1.
3768
3769 #Return text horizontal scale ##
3770
3771 #Example
3772 SkPaint paint;
3773 SkDebugf("1 %c= default text scale x\n", 1 == paint.getTextScaleX() ? '=' : '!');
3774 ##
3775
3776##
3777
3778
3779#Method void setTextScaleX(SkScalar scaleX)
3780
Cary Clarkab2621d2018-01-30 10:08:57 -05003781#In Text_Scale_X
3782#Line # sets the text horizontal scale; condensed text ##
Cary Clark8032b982017-07-28 11:04:54 -04003783 Sets Text_Scale_X.
3784 Default value is 1.
3785
3786 #Param scaleX text horizontal scale ##
3787
3788 #Example
3789 SkPaint paint;
3790 paint.setTextScaleX(0.f / 0.f);
3791 SkDebugf("text scale %s-a-number\n", SkScalarIsNaN(paint.getTextScaleX()) ? "not" : "is");
3792 ##
3793
3794##
3795
Cary Clark08895c42018-02-01 09:37:32 -05003796#Subtopic Text_Scale_X ##
Cary Clark8032b982017-07-28 11:04:54 -04003797
Cary Clark08895c42018-02-01 09:37:32 -05003798#Subtopic Text_Skew_X
3799#Line # text horizontal slant ##
Cary Clark8032b982017-07-28 11:04:54 -04003800
3801
3802Text_Skew_X adjusts the text horizontal slant.
3803Text skewing approximates italic and oblique type faces when the actual face
3804is not available.
3805Text_Skew_X can be set to any value.
3806Text_Skew_X defaults to 0.
3807
3808#Example
3809#Height 128
3810 void draw(SkCanvas* canvas) {
3811 SkPaint paint;
3812 paint.setAntiAlias(true);
3813 paint.setTextSize(24);
3814 paint.setTextSkewX(-.25f);
3815 canvas->drawString("right-leaning", 10, 100, paint);
3816 paint.setTextSkewX(0);
3817 canvas->drawString("normal", 10, 60, paint);
3818 paint.setTextSkewX(.25f);
3819 canvas->drawString("left-leaning", 10, 20, paint);
3820 }
3821##
3822
3823#Method SkScalar getTextSkewX() const
3824
Cary Clarkab2621d2018-01-30 10:08:57 -05003825#In Text_Skew_X
3826#Line # returns the text horizontal skew; oblique text ##
Cary Clark8032b982017-07-28 11:04:54 -04003827 Returns Text_Skew_X.
3828 Default value is zero.
3829
3830 #Return additional shear in x-axis relative to y-axis ##
3831
3832 #Example
3833 SkPaint paint;
3834 SkDebugf("0 %c= default text skew x\n", 0 == paint.getTextSkewX() ? '=' : '!');
3835 ##
3836
3837##
3838
3839#Method void setTextSkewX(SkScalar skewX)
3840
Cary Clarkab2621d2018-01-30 10:08:57 -05003841#In Text_Skew_X
3842#Line # sets the text horizontal skew; oblique text ##
Cary Clark8032b982017-07-28 11:04:54 -04003843 Sets Text_Skew_X.
3844 Default value is zero.
3845
3846 #Param skewX additional shear in x-axis relative to y-axis ##
3847
3848 #Example
3849 SkPaint paint;
3850 paint.setTextScaleX(1.f / 0.f);
3851 SkDebugf("text scale %s-finite\n", SkScalarIsFinite(paint.getTextScaleX()) ? "is" : "not");
3852 ##
3853
3854##
3855
Cary Clark08895c42018-02-01 09:37:32 -05003856#Subtopic Text_Skew_X ##
Cary Clark8032b982017-07-28 11:04:54 -04003857
3858# ------------------------------------------------------------------------------
Cary Clark08895c42018-02-01 09:37:32 -05003859#Subtopic Text_Encoding
3860#Line # text encoded as characters or Glyphs ##
Cary Clark8032b982017-07-28 11:04:54 -04003861
3862#Enum TextEncoding
Cary Clark08895c42018-02-01 09:37:32 -05003863#Line # character or glyph encoded size ##
Cary Clark8032b982017-07-28 11:04:54 -04003864
3865#Code
3866 enum TextEncoding {
3867 kUTF8_TextEncoding,
3868 kUTF16_TextEncoding,
3869 kUTF32_TextEncoding,
Cary Clarkbad5ad72017-08-03 17:14:08 -04003870 kGlyphID_TextEncoding,
Cary Clark8032b982017-07-28 11:04:54 -04003871 };
3872##
3873
Cary Clark6fc50412017-09-21 12:31:06 -04003874TextEncoding determines whether text specifies character codes and their encoded
Cary Clarkbc5697d2017-10-04 14:31:33 -04003875size, or glyph indices. Characters are encoded as specified by the
Cary Clark6fc50412017-09-21 12:31:06 -04003876#A Unicode standard # http://unicode.org/standard/standard.html ##
3877.
3878
Cary Clark8032b982017-07-28 11:04:54 -04003879Character codes encoded size are specified by UTF-8, UTF-16, or UTF-32.
Cary Clarkbc5697d2017-10-04 14:31:33 -04003880All character code formats are able to represent all of Unicode, differing only
Cary Clark8032b982017-07-28 11:04:54 -04003881in the total storage required.
3882
Cary Clark6fc50412017-09-21 12:31:06 -04003883#A UTF-8 (RFC 3629) # https://tools.ietf.org/html/rfc3629 ##
3884 encodes each character as one or more 8-bit bytes.
3885
3886#A UTF-16 (RFC 2781) # https://tools.ietf.org/html/rfc2781 ##
3887 encodes each character as one or two 16-bit words.
3888
3889#A UTF-32 # http://www.unicode.org/versions/Unicode5.0.0/ch03.pdf ##
3890 encodes each character as one 32-bit word.
Cary Clark8032b982017-07-28 11:04:54 -04003891
3892Font_Manager uses font data to convert character code points into glyph indices.
3893A glyph index is a 16-bit word.
3894
3895TextEncoding is set to kUTF8_TextEncoding by default.
3896
3897#Const kUTF8_TextEncoding 0
3898Uses bytes to represent UTF-8 or ASCII.
3899##
3900#Const kUTF16_TextEncoding 1
3901Uses two byte words to represent most of Unicode.
3902##
3903#Const kUTF32_TextEncoding 2
3904Uses four byte words to represent all of Unicode.
3905##
3906#Const kGlyphID_TextEncoding 3
3907Uses two byte words to represent glyph indices.
3908##
3909
3910#Enum ##
3911
3912#Example
3913#Height 128
3914#Description
Cary Clarkbc5697d2017-10-04 14:31:33 -04003915First line is encoded in UTF-8.
3916Second line is encoded in UTF-16.
3917Third line is encoded in UTF-32.
Cary Clark8032b982017-07-28 11:04:54 -04003918Fourth line has 16 bit glyph indices.
3919##
3920void draw(SkCanvas* canvas) {
3921 SkPaint paint;
3922 const char hello8[] = "Hello" "\xE2" "\x98" "\xBA";
3923 const uint16_t hello16[] = { 'H', 'e', 'l', 'l', 'o', 0x263A };
3924 const uint32_t hello32[] = { 'H', 'e', 'l', 'l', 'o', 0x263A };
3925 paint.setTextSize(24);
3926 canvas->drawText(hello8, sizeof(hello8) - 1, 10, 30, paint);
3927 paint.setTextEncoding(SkPaint::kUTF16_TextEncoding);
3928 canvas->drawText(hello16, sizeof(hello16), 10, 60, paint);
3929 paint.setTextEncoding(SkPaint::kUTF32_TextEncoding);
3930 canvas->drawText(hello32, sizeof(hello32), 10, 90, paint);
3931 uint16_t glyphs[SK_ARRAY_COUNT(hello32)];
3932 paint.textToGlyphs(hello32, sizeof(hello32), glyphs);
3933 paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
3934 canvas->drawText(glyphs, sizeof(glyphs), 10, 120, paint);
3935}
3936##
3937
3938#Method TextEncoding getTextEncoding() const
3939
Cary Clarkab2621d2018-01-30 10:08:57 -05003940#In Text_Encoding
3941#Line # returns character or glyph encoded size ##
Cary Clark8032b982017-07-28 11:04:54 -04003942 Returns Text_Encoding.
3943 Text_Encoding determines how character code points are mapped to font glyph indices.
3944
3945 #Return one of: kUTF8_TextEncoding, kUTF16_TextEncoding, kUTF32_TextEncoding, or
3946 kGlyphID_TextEncoding
3947 ##
3948
3949 #Example
3950 SkPaint paint;
3951 SkDebugf("kUTF8_TextEncoding %c= text encoding\n",
3952 SkPaint::kUTF8_TextEncoding == paint.getTextEncoding() ? '=' : '!');
3953 paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
3954 SkDebugf("kGlyphID_TextEncoding %c= text encoding\n",
3955 SkPaint::kGlyphID_TextEncoding == paint.getTextEncoding() ? '=' : '!');
3956
3957 #StdOut
3958 kUTF8_TextEncoding == text encoding
3959 kGlyphID_TextEncoding == text encoding
3960 ##
3961 ##
3962
3963##
3964
3965
3966#Method void setTextEncoding(TextEncoding encoding)
3967
Cary Clarkab2621d2018-01-30 10:08:57 -05003968#In Text_Encoding
3969#Line # sets character or glyph encoded size ##
Cary Clark8032b982017-07-28 11:04:54 -04003970 Sets Text_Encoding to encoding.
3971 Text_Encoding determines how character code points are mapped to font glyph indices.
3972 Invalid values for encoding are ignored.
3973
3974 #Param encoding one of: kUTF8_TextEncoding, kUTF16_TextEncoding, kUTF32_TextEncoding, or
Cary Clark579985c2017-07-31 11:48:27 -04003975 kGlyphID_TextEncoding
3976 #Param ##
Cary Clark8032b982017-07-28 11:04:54 -04003977
3978 #Example
3979 SkPaint paint;
3980 paint.setTextEncoding((SkPaint::TextEncoding) 4);
3981 SkDebugf("4 %c= text encoding\n", 4 == paint.getTextEncoding() ? '=' : '!');
3982
3983 #StdOut
3984 4 != text encoding
3985 ##
3986 ##
3987
3988##
3989
Cary Clark08895c42018-02-01 09:37:32 -05003990#Subtopic Text_Encoding ##
Cary Clark8032b982017-07-28 11:04:54 -04003991# ------------------------------------------------------------------------------
Cary Clark08895c42018-02-01 09:37:32 -05003992#Subtopic Font_Metrics
3993#Line # common glyph dimensions ##
Cary Clark8032b982017-07-28 11:04:54 -04003994
Cary Clarkce101242017-09-01 15:51:02 -04003995Font_Metrics describe dimensions common to the Glyphs in Typeface.
Cary Clark8032b982017-07-28 11:04:54 -04003996The dimensions are computed by Font_Manager from font data and do not take
3997Paint settings other than Text_Size into account.
3998
3999Font dimensions specify the anchor to the left of the glyph at baseline as the origin.
4000X-axis values to the left of the glyph are negative, and to the right of the left glyph edge
4001are positive.
4002Y-axis values above the baseline are negative, and below the baseline are positive.
Ben Wagnere5806492017-11-09 12:08:31 -05004003
Cary Clark8032b982017-07-28 11:04:54 -04004004#Example
4005#Width 512
4006void draw(SkCanvas* canvas) {
4007 SkPaint paint;
4008 paint.setAntiAlias(true);
4009 paint.setTextSize(120);
4010 SkPaint::FontMetrics fm;
4011 SkScalar lineHeight = paint.getFontMetrics(&fm);
4012 SkPoint pt = { 70, 180 };
4013 canvas->drawString("M", pt.fX, pt.fY, paint);
4014 canvas->drawLine(pt.fX, pt.fY, pt.fX, pt.fY + fm.fTop, paint);
4015 SkScalar ascent = pt.fY + fm.fAscent;
4016 canvas->drawLine(pt.fX - 25, ascent, pt.fX - 25, ascent + lineHeight, paint);
4017 canvas->drawLine(pt.fX - 50, pt.fY, pt.fX - 50, pt.fY + fm.fDescent, paint);
4018 canvas->drawLine(pt.fX + 100, pt.fY, pt.fX + 100, pt.fY + fm.fAscent, paint);
4019 canvas->drawLine(pt.fX + 125, pt.fY, pt.fX + 125, pt.fY - fm.fXHeight, paint);
4020 canvas->drawLine(pt.fX + 150, pt.fY, pt.fX + 150, pt.fY - fm.fCapHeight, paint);
4021 canvas->drawLine(pt.fX + 5, pt.fY, pt.fX + 5, pt.fY + fm.fBottom, paint);
4022 SkScalar xmin = pt.fX + fm.fXMin;
4023 canvas->drawLine(xmin, pt.fY + 60, xmin + fm.fMaxCharWidth, pt.fY + 60, paint);
4024 canvas->drawLine(xmin, pt.fY - 145, pt.fX, pt.fY - 145, paint);
4025 canvas->drawLine(pt.fX + fm.fXMax, pt.fY - 160, pt.fX, pt.fY - 160, paint);
4026 SkScalar upos = pt.fY + fm.fUnderlinePosition;
Ben Wagnere5806492017-11-09 12:08:31 -05004027 canvas->drawLine(pt.fX + 25, upos, pt.fX + 160, upos, paint);
4028 SkScalar ut = fm.fUnderlineThickness;
4029 canvas->drawLine(pt.fX + 130, upos + ut, pt.fX + 160, upos + ut, paint);
Cary Clark8032b982017-07-28 11:04:54 -04004030 paint.setTextSize(12);
4031 canvas->drawString("x-min", pt.fX - 50, pt.fY - 148, paint);
4032 canvas->drawString("x-max", pt.fX + 140, pt.fY - 150, paint);
4033 canvas->drawString("max char width", pt.fX + 120, pt.fY + 57, paint);
4034 canvas->drawString("underline position", pt.fX + 30, pt.fY + 22, paint);
4035 canvas->drawString("underline thickness", pt.fX + 162, pt.fY + 13, paint);
4036 canvas->rotate(-90);
4037 canvas->drawString("descent", -pt.fY - 30, pt.fX - 54, paint);
4038 canvas->drawString("line height", -pt.fY, pt.fX - 29, paint);
4039 canvas->drawString("top", -pt.fY + 30, pt.fX - 4, paint);
4040 canvas->drawString("ascent", -pt.fY, pt.fX + 110, paint);
4041 canvas->drawString("x-height", -pt.fY, pt.fX + 135, paint);
4042 canvas->drawString("cap-height", -pt.fY, pt.fX + 160, paint);
4043 canvas->drawString("bottom", -pt.fY - 50, pt.fX + 15, paint);
4044}
4045##
4046
4047#Struct FontMetrics
Cary Clark08895c42018-02-01 09:37:32 -05004048#Line # values computed by Font_Manager using Typeface ##
Cary Clark8032b982017-07-28 11:04:54 -04004049
4050#Code
4051 struct FontMetrics {
4052 enum FontMetricsFlags {
4053 kUnderlineThicknessIsValid_Flag = 1 << 0,
4054 kUnderlinePositionIsValid_Flag = 1 << 1,
4055 kStrikeoutThicknessIsValid_Flag = 1 << 2,
4056 kStrikeoutPositionIsValid_Flag = 1 << 3,
4057 };
4058
4059 uint32_t fFlags;
4060 SkScalar fTop;
4061 SkScalar fAscent;
4062 SkScalar fDescent;
4063 SkScalar fBottom;
4064 SkScalar fLeading;
4065 SkScalar fAvgCharWidth;
4066 SkScalar fMaxCharWidth;
4067 SkScalar fXMin;
4068 SkScalar fXMax;
4069 SkScalar fXHeight;
4070 SkScalar fCapHeight;
4071 SkScalar fUnderlineThickness;
4072 SkScalar fUnderlinePosition;
4073 SkScalar fStrikeoutThickness;
4074 SkScalar fStrikeoutPosition;
4075
4076 bool hasUnderlineThickness(SkScalar* thickness) const;
4077 bool hasUnderlinePosition(SkScalar* position) const;
4078 bool hasStrikeoutThickness(SkScalar* thickness) const;
4079 bool hasStrikeoutPosition(SkScalar* position) const;
4080 };
4081##
4082
Cary Clark154beea2017-10-26 07:58:48 -04004083 FontMetrics is filled out by getFontMetrics. FontMetrics contents reflect the values
4084 computed by Font_Manager using Typeface. Values are set to zero if they are
4085 not available.
Cary Clarke4aa3712017-09-15 02:56:12 -04004086
Ben Wagnere5806492017-11-09 12:08:31 -05004087 All vertical values relative to the baseline are given y-down. As such, zero is on the
4088 baseline, negative values are above the baseline, and positive values are below the
4089 baseline.
4090
Cary Clark154beea2017-10-26 07:58:48 -04004091 fUnderlineThickness and fUnderlinePosition have a bit set in fFlags if their values
4092 are valid, since their value may be zero.
Ben Wagnere5806492017-11-09 12:08:31 -05004093
Cary Clark154beea2017-10-26 07:58:48 -04004094 fStrikeoutThickness and fStrikeoutPosition have a bit set in fFlags if their values
4095 are valid, since their value may be zero.
4096
4097 #Enum FontMetricsFlags
Cary Clark08895c42018-02-01 09:37:32 -05004098#Line # valid Font_Metrics ##
Cary Clarke4aa3712017-09-15 02:56:12 -04004099
Cary Clark8032b982017-07-28 11:04:54 -04004100 #Code
4101 enum FontMetricsFlags {
4102 kUnderlineThicknessIsValid_Flag = 1 << 0,
4103 kUnderlinePositionIsValid_Flag = 1 << 1,
4104 kStrikeoutThicknessIsValid_Flag = 1 << 2,
4105 kStrikeoutPositionIsValid_Flag = 1 << 3,
4106 };
4107 ##
4108
Cary Clark154beea2017-10-26 07:58:48 -04004109 FontMetricsFlags are set in fFlags when underline and strikeout metrics are valid;
4110 the underline or strikeout metric may be valid and zero.
4111 Fonts with embedded bitmaps may not have valid underline or strikeout metrics.
4112
Cary Clark8032b982017-07-28 11:04:54 -04004113 #Const kUnderlineThicknessIsValid_Flag 0x0001
4114 Set if fUnderlineThickness is valid.
4115 ##
4116 #Const kUnderlinePositionIsValid_Flag 0x0002
4117 Set if fUnderlinePosition is valid.
4118 ##
4119 #Const kStrikeoutThicknessIsValid_Flag 0x0004
4120 Set if fStrikeoutThickness is valid.
4121 ##
4122 #Const kStrikeoutPositionIsValid_Flag 0x0008
4123 Set if fStrikeoutPosition is valid.
4124 ##
4125
4126 #Enum ##
4127
4128 #Member uint32_t fFlags
4129 fFlags is set when underline metrics are valid.
4130 ##
Ben Wagnere5806492017-11-09 12:08:31 -05004131
Cary Clark8032b982017-07-28 11:04:54 -04004132 #Member SkScalar fTop
Ben Wagnere5806492017-11-09 12:08:31 -05004133 Greatest extent above the baseline for any glyph.
4134 Typically less than zero.
Cary Clark8032b982017-07-28 11:04:54 -04004135 ##
Ben Wagnere5806492017-11-09 12:08:31 -05004136
Cary Clark8032b982017-07-28 11:04:54 -04004137 #Member SkScalar fAscent
4138 Recommended distance above the baseline to reserve for a line of text.
Ben Wagnere5806492017-11-09 12:08:31 -05004139 Typically less than zero.
Cary Clark8032b982017-07-28 11:04:54 -04004140 ##
Ben Wagnere5806492017-11-09 12:08:31 -05004141
Cary Clark8032b982017-07-28 11:04:54 -04004142 #Member SkScalar fDescent
4143 Recommended distance below the baseline to reserve for a line of text.
Ben Wagnere5806492017-11-09 12:08:31 -05004144 Typically greater than zero.
Cary Clark8032b982017-07-28 11:04:54 -04004145 ##
Ben Wagnere5806492017-11-09 12:08:31 -05004146
Cary Clark8032b982017-07-28 11:04:54 -04004147 #Member SkScalar fBottom
Ben Wagnere5806492017-11-09 12:08:31 -05004148 Greatest extent below the baseline for any glyph.
4149 Typically greater than zero.
Cary Clark8032b982017-07-28 11:04:54 -04004150 ##
Ben Wagnere5806492017-11-09 12:08:31 -05004151
Cary Clark8032b982017-07-28 11:04:54 -04004152 #Member SkScalar fLeading
4153 Recommended distance to add between lines of text.
Ben Wagnere5806492017-11-09 12:08:31 -05004154 Typically greater than or equal to zero.
Cary Clark8032b982017-07-28 11:04:54 -04004155 ##
Ben Wagnere5806492017-11-09 12:08:31 -05004156
Cary Clark8032b982017-07-28 11:04:54 -04004157 #Member SkScalar fAvgCharWidth
4158 Average character width, if it is available.
4159 Zero if no average width is stored in the font.
4160 ##
Ben Wagnere5806492017-11-09 12:08:31 -05004161
Cary Clark8032b982017-07-28 11:04:54 -04004162 #Member SkScalar fMaxCharWidth
4163 Maximum character width.
4164 ##
Ben Wagnere5806492017-11-09 12:08:31 -05004165
Cary Clark8032b982017-07-28 11:04:54 -04004166 #Member SkScalar fXMin
Ben Wagnere5806492017-11-09 12:08:31 -05004167 Minimum bounding box x value for all Glyphs.
Cary Clark8032b982017-07-28 11:04:54 -04004168 Typically less than zero.
4169 ##
Ben Wagnere5806492017-11-09 12:08:31 -05004170
Cary Clark8032b982017-07-28 11:04:54 -04004171 #Member SkScalar fXMax
Cary Clarkce101242017-09-01 15:51:02 -04004172 Maximum bounding box x value for all Glyphs.
Cary Clark8032b982017-07-28 11:04:54 -04004173 Typically greater than zero.
4174 ##
Ben Wagnere5806492017-11-09 12:08:31 -05004175
Cary Clark8032b982017-07-28 11:04:54 -04004176 #Member SkScalar fXHeight
4177 Height of a lower-case 'x'.
4178 May be zero if no lower-case height is stored in the font.
4179 ##
Ben Wagnere5806492017-11-09 12:08:31 -05004180
Cary Clark8032b982017-07-28 11:04:54 -04004181 #Member SkScalar fCapHeight
4182 Height of an upper-case letter.
4183 May be zero if no upper-case height is stored in the font.
4184 ##
Ben Wagnere5806492017-11-09 12:08:31 -05004185
Cary Clark8032b982017-07-28 11:04:54 -04004186 #Member SkScalar fUnderlineThickness
Ben Wagnere5806492017-11-09 12:08:31 -05004187 Underline thickness.
4188
4189 If the metric is valid, the kUnderlineThicknessIsValid_Flag is set in fFlags.
Cary Clark8032b982017-07-28 11:04:54 -04004190 If kUnderlineThicknessIsValid_Flag is clear, fUnderlineThickness is zero.
4191 ##
Ben Wagnere5806492017-11-09 12:08:31 -05004192
Cary Clark8032b982017-07-28 11:04:54 -04004193 #Member SkScalar fUnderlinePosition
Ben Wagnere5806492017-11-09 12:08:31 -05004194 Position of the top of the underline stroke relative to the baseline.
4195 Typically positive when valid.
Cary Clark8032b982017-07-28 11:04:54 -04004196
4197 If the metric is valid, the kUnderlinePositionIsValid_Flag is set in fFlags.
4198 If kUnderlinePositionIsValid_Flag is clear, fUnderlinePosition is zero.
4199 ##
4200
4201 #Member SkScalar fStrikeoutThickness
Ben Wagnere5806492017-11-09 12:08:31 -05004202 Strikeout thickness.
4203
4204 If the metric is valid, the kStrikeoutThicknessIsValid_Flag is set in fFlags.
Cary Clark8032b982017-07-28 11:04:54 -04004205 If kStrikeoutThicknessIsValid_Flag is clear, fStrikeoutThickness is zero.
4206 ##
4207
4208 #Member SkScalar fStrikeoutPosition
Ben Wagnere5806492017-11-09 12:08:31 -05004209 Position of the bottom of the strikeout stroke relative to the baseline.
4210 Typically negative when valid.
Cary Clark8032b982017-07-28 11:04:54 -04004211
Ben Wagnere5806492017-11-09 12:08:31 -05004212 If the metric is valid, the kStrikeoutPositionIsValid_Flag is set in fFlags.
4213 If kStrikeoutPositionIsValid_Flag is clear, fStrikeoutPosition is zero.
Cary Clark8032b982017-07-28 11:04:54 -04004214 ##
4215
4216 #Method bool hasUnderlineThickness(SkScalar* thickness) const
4217
Ben Wagnere5806492017-11-09 12:08:31 -05004218 If Font_Metrics has a valid underline thickness, return true, and set
Cary Clarkce101242017-09-01 15:51:02 -04004219 thickness to that value. If the underline thickness is not valid,
4220 return false, and ignore thickness.
Cary Clark8032b982017-07-28 11:04:54 -04004221
4222 #Param thickness storage for underline width ##
4223
4224 #Return true if font specifies underline width ##
4225
4226 #NoExample
4227 ##
4228 ##
4229
4230 #Method bool hasUnderlinePosition(SkScalar* position) const
4231
Ben Wagnere5806492017-11-09 12:08:31 -05004232 If Font_Metrics has a valid underline position, return true, and set
Cary Clarkce101242017-09-01 15:51:02 -04004233 position to that value. If the underline position is not valid,
4234 return false, and ignore position.
Cary Clark8032b982017-07-28 11:04:54 -04004235
4236 #Param position storage for underline position ##
4237
4238 #Return true if font specifies underline position ##
4239
4240 #NoExample
4241 ##
4242 ##
4243
4244 #Method bool hasStrikeoutThickness(SkScalar* thickness) const
4245
Ben Wagnere5806492017-11-09 12:08:31 -05004246 If Font_Metrics has a valid strikeout thickness, return true, and set
Cary Clarkce101242017-09-01 15:51:02 -04004247 thickness to that value. If the underline thickness is not valid,
4248 return false, and ignore thickness.
Cary Clark8032b982017-07-28 11:04:54 -04004249
4250 #Param thickness storage for strikeout width ##
4251
4252 #Return true if font specifies strikeout width ##
4253
4254 #NoExample
4255 ##
4256 ##
4257
4258 #Method bool hasStrikeoutPosition(SkScalar* position) const
4259
Ben Wagnere5806492017-11-09 12:08:31 -05004260 If Font_Metrics has a valid strikeout position, return true, and set
Cary Clarkce101242017-09-01 15:51:02 -04004261 position to that value. If the underline position is not valid,
4262 return false, and ignore position.
Cary Clark8032b982017-07-28 11:04:54 -04004263
4264 #Param position storage for strikeout position ##
4265
4266 #Return true if font specifies strikeout position ##
4267
4268 #NoExample
4269 ##
4270 ##
4271
4272#Struct ##
4273
4274#Method SkScalar getFontMetrics(FontMetrics* metrics, SkScalar scale = 0) const
4275
Cary Clarkab2621d2018-01-30 10:08:57 -05004276#In Font_Metrics
4277#Line # returns Typeface metrics scaled by text size ##
Cary Clark8032b982017-07-28 11:04:54 -04004278 Returns Font_Metrics associated with Typeface.
4279 The return value is the recommended spacing between lines: the sum of metrics
4280 descent, ascent, and leading.
4281 If metrics is not nullptr, Font_Metrics is copied to metrics.
4282 Results are scaled by Text_Size but does not take into account
4283 dimensions required by Text_Scale_X, Text_Skew_X, Fake_Bold,
4284 Style_Stroke, and Path_Effect.
4285 Results can be additionally scaled by scale; a scale of zero
4286 is ignored.
4287
4288 #Param metrics storage for Font_Metrics from Typeface; may be nullptr ##
4289 #Param scale additional multiplier for returned values ##
4290
4291 #Return recommended spacing between lines ##
4292
4293 #Example
4294 #Height 128
4295 void draw(SkCanvas* canvas) {
4296 SkPaint paint;
4297 paint.setTextSize(32);
4298 SkScalar lineHeight = paint.getFontMetrics(nullptr);
4299 canvas->drawString("line 1", 10, 40, paint);
4300 canvas->drawString("line 2", 10, 40 + lineHeight, paint);
4301 paint.setStyle(SkPaint::kStroke_Style);
4302 paint.setStrokeWidth(10);
4303 lineHeight = paint.getFontMetrics(nullptr, 1.10f); // account for stroke height
4304 canvas->drawString("line 3", 120, 40, paint);
4305 canvas->drawString("line 4", 120, 40 + lineHeight, paint);
4306 }
4307 ##
4308
4309 #SeeAlso Text_Size Typeface Typeface_Methods
4310
4311##
4312
4313
4314#Method SkScalar getFontSpacing() const
4315
Cary Clarkab2621d2018-01-30 10:08:57 -05004316#In Font_Metrics
4317#Line # returns recommended spacing between lines ##
Cary Clark8032b982017-07-28 11:04:54 -04004318 Returns the recommended spacing between lines: the sum of metrics
4319 descent, ascent, and leading.
4320 Result is scaled by Text_Size but does not take into account
4321 dimensions required by stroking and Path_Effect.
Cary Clark579985c2017-07-31 11:48:27 -04004322 Returns the same result as getFontMetrics.
Cary Clark8032b982017-07-28 11:04:54 -04004323
Cary Clark0c5f5462017-12-15 11:21:51 -05004324 #Return recommended spacing between lines ##
Cary Clark8032b982017-07-28 11:04:54 -04004325
4326 #Example
4327 SkPaint paint;
4328 for (SkScalar textSize : { 12, 18, 24, 32 } ) {
4329 paint.setTextSize(textSize);
4330 SkDebugf("textSize: %g fontSpacing: %g\n", textSize, paint.getFontSpacing());
4331 }
4332
4333 #StdOut
4334 textSize: 12 fontSpacing: 13.9688
4335 textSize: 18 fontSpacing: 20.9531
4336 textSize: 24 fontSpacing: 27.9375
4337 textSize: 32 fontSpacing: 37.25
4338 ##
4339 ##
4340
4341##
4342
4343
4344#Method SkRect getFontBounds() const
4345
Cary Clarkab2621d2018-01-30 10:08:57 -05004346#In Font_Metrics
4347#Line # returns union all glyph bounds ##
Cary Clarkce101242017-09-01 15:51:02 -04004348Returns the union of bounds of all Glyphs.
Cary Clark8032b982017-07-28 11:04:54 -04004349Returned dimensions are computed by Font_Manager from font data,
Cary Clark579985c2017-07-31 11:48:27 -04004350ignoring Hinting. Includes Text_Size, Text_Scale_X,
Cary Clark8032b982017-07-28 11:04:54 -04004351and Text_Skew_X, but not Fake_Bold or Path_Effect.
4352
4353If Text_Size is large, Text_Scale_X is one, and Text_Skew_X is zero,
Cary Clark579985c2017-07-31 11:48:27 -04004354returns the same bounds as Font_Metrics { FontMetrics::fXMin,
Cary Clark8032b982017-07-28 11:04:54 -04004355FontMetrics::fTop, FontMetrics::fXMax, FontMetrics::fBottom }.
4356
Cary Clarkce101242017-09-01 15:51:02 -04004357#Return union of bounds of all Glyphs ##
Cary Clark8032b982017-07-28 11:04:54 -04004358
4359#Example
4360 SkPaint paint;
4361 SkPaint::FontMetrics fm;
4362 paint.getFontMetrics(&fm);
4363 SkRect fb = paint.getFontBounds();
4364 SkDebugf("metrics bounds = { %g, %g, %g, %g }\n", fm.fXMin, fm.fTop, fm.fXMax, fm.fBottom );
4365 SkDebugf("font bounds = { %g, %g, %g, %g }\n", fb.fLeft, fb.fTop, fb.fRight, fm.fBottom );
4366
4367 #StdOut
4368 metrics bounds = { -12.2461, -14.7891, 21.5215, 5.55469 }
4369 font bounds = { -12.2461, -14.7891, 21.5215, 5.55469 }
4370 ##
4371##
4372
4373##
4374
Cary Clark08895c42018-02-01 09:37:32 -05004375#Subtopic Font_Metrics ##
Cary Clark8032b982017-07-28 11:04:54 -04004376# ------------------------------------------------------------------------------
4377
4378#Method int textToGlyphs(const void* text, size_t byteLength,
4379 SkGlyphID glyphs[]) const
Cary Clark78de7512018-02-07 07:27:09 -05004380#In Utility
Cary Clarkab2621d2018-01-30 10:08:57 -05004381#Line # converts text into glyph indices ##
Cary Clark8032b982017-07-28 11:04:54 -04004382
4383Converts text into glyph indices.
4384Returns the number of glyph indices represented by text.
4385Text_Encoding specifies how text represents characters or glyphs.
4386glyphs may be nullptr, to compute the glyph count.
4387
Cary Clarkbc5697d2017-10-04 14:31:33 -04004388Does not check text for valid character codes or valid glyph indices.
Cary Clark8032b982017-07-28 11:04:54 -04004389
Cary Clark579985c2017-07-31 11:48:27 -04004390If byteLength equals zero, returns zero.
Cary Clark8032b982017-07-28 11:04:54 -04004391If byteLength includes a partial character, the partial character is ignored.
4392
4393If Text_Encoding is kUTF8_TextEncoding and
4394text contains an invalid UTF-8 sequence, zero is returned.
4395
Cary Clarkce101242017-09-01 15:51:02 -04004396#Param text character storage encoded with Text_Encoding ##
Cary Clark8032b982017-07-28 11:04:54 -04004397#Param byteLength length of character storage in bytes ##
4398#Param glyphs storage for glyph indices; may be nullptr ##
4399
4400#Return number of glyphs represented by text of length byteLength ##
4401
4402 #Example
4403 #Height 64
4404 void draw(SkCanvas* canvas) {
4405 SkPaint paint;
4406 const uint8_t utf8[] = { 0x24, 0xC2, 0xA2, 0xE2, 0x82, 0xAC, 0xC2, 0xA5, 0xC2, 0xA3 };
4407 std::vector<SkGlyphID> glyphs;
4408 int count = paint.textToGlyphs(utf8, sizeof(utf8), nullptr);
4409 glyphs.resize(count);
4410 (void) paint.textToGlyphs(utf8, sizeof(utf8), &glyphs.front());
4411 paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
4412 paint.setTextSize(32);
4413 canvas->drawText(&glyphs.front(), glyphs.size() * sizeof(SkGlyphID), 10, 40, paint);
4414 }
4415 ##
4416
4417##
4418
4419#Method int countText(const void* text, size_t byteLength) const
Cary Clark78de7512018-02-07 07:27:09 -05004420#In Utility
Cary Clarkab2621d2018-01-30 10:08:57 -05004421#Line # returns number of Glyphs in text ##
Cary Clarkce101242017-09-01 15:51:02 -04004422 Returns the number of Glyphs in text.
4423 Uses Text_Encoding to count the Glyphs.
Cary Clark8032b982017-07-28 11:04:54 -04004424 Returns the same result as textToGlyphs.
4425
Cary Clarkce101242017-09-01 15:51:02 -04004426#Param text character storage encoded with Text_Encoding ##
Cary Clark8032b982017-07-28 11:04:54 -04004427#Param byteLength length of character storage in bytes ##
4428
Cary Clarkce101242017-09-01 15:51:02 -04004429#Return number of Glyphs represented by text of length byteLength ##
Cary Clark8032b982017-07-28 11:04:54 -04004430
4431 #Example
4432 SkPaint paint;
4433 const uint8_t utf8[] = { 0x24, 0xC2, 0xA2, 0xE2, 0x82, 0xAC, 0xC2, 0xA5, 0xC2, 0xA3 };
4434 SkDebugf("count = %d\n", paint.countText(utf8, sizeof(utf8)));
4435
4436 #StdOut
4437 count = 5
4438 ##
4439 ##
4440##
4441
4442# ------------------------------------------------------------------------------
4443
4444#Method bool containsText(const void* text, size_t byteLength) const
Cary Clark78de7512018-02-07 07:27:09 -05004445#In Utility
Cary Clarkab2621d2018-01-30 10:08:57 -05004446#Line # returns if all text corresponds to Glyphs ##
Cary Clark8032b982017-07-28 11:04:54 -04004447 Returns true if all text corresponds to a non-zero glyph index.
4448 Returns false if any characters in text are not supported in
4449 Typeface.
4450
Cary Clark579985c2017-07-31 11:48:27 -04004451 If Text_Encoding is kGlyphID_TextEncoding,
4452 returns true if all glyph indices in text are non-zero;
Cary Clark8032b982017-07-28 11:04:54 -04004453 does not check to see if text contains valid glyph indices for Typeface.
4454
Cary Clarkce101242017-09-01 15:51:02 -04004455 Returns true if byteLength is zero.
Cary Clark8032b982017-07-28 11:04:54 -04004456
Cary Clarkce101242017-09-01 15:51:02 -04004457 #Param text array of characters or Glyphs ##
Cary Clark8032b982017-07-28 11:04:54 -04004458 #Param byteLength number of bytes in text array ##
4459
4460 #Return true if all text corresponds to a non-zero glyph index ##
4461
4462 #Example
4463 #Description
4464 containsText succeeds for degree symbol, but cannot find a glyph index
4465 corresponding to the Unicode surrogate code point.
4466 ##
4467 SkPaint paint;
4468 const uint16_t goodChar = 0x00B0; // degree symbol
4469 const uint16_t badChar = 0xD800; // Unicode surrogate
4470 paint.setTextEncoding(SkPaint::kUTF16_TextEncoding);
4471 SkDebugf("0x%04x %c= has char\n", goodChar,
4472 paint.containsText(&goodChar, 2) ? '=' : '!');
4473 SkDebugf("0x%04x %c= has char\n", badChar,
4474 paint.containsText(&badChar, 2) ? '=' : '!');
4475
4476 #StdOut
4477 0x00b0 == has char
4478 0xd800 != has char
4479 ##
4480 ##
4481
4482 #Example
4483 #Description
4484 containsText returns true that glyph index is greater than zero, not
4485 that it corresponds to an entry in Typeface.
4486 ##
4487 SkPaint paint;
4488 const uint16_t goodGlyph = 511;
4489 const uint16_t zeroGlyph = 0;
4490 const uint16_t badGlyph = 65535; // larger than glyph count in font
4491 paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
4492 SkDebugf("0x%04x %c= has glyph\n", goodGlyph,
4493 paint.containsText(&goodGlyph, 2) ? '=' : '!');
4494 SkDebugf("0x%04x %c= has glyph\n", zeroGlyph,
4495 paint.containsText(&zeroGlyph, 2) ? '=' : '!');
4496 SkDebugf("0x%04x %c= has glyph\n", badGlyph,
4497 paint.containsText(&badGlyph, 2) ? '=' : '!');
4498
4499 #StdOut
4500 0x01ff == has glyph
4501 0x0000 != has glyph
4502 0xffff == has glyph
4503 ##
4504 ##
4505
4506#SeeAlso setTextEncoding Typeface
4507
4508##
4509
4510# ------------------------------------------------------------------------------
4511
4512#Method void glyphsToUnichars(const SkGlyphID glyphs[],
4513 int count, SkUnichar text[]) const
Cary Clark78de7512018-02-07 07:27:09 -05004514#In Utility
Cary Clarkab2621d2018-01-30 10:08:57 -05004515#Line # converts Glyphs into text ##
Cary Clark8032b982017-07-28 11:04:54 -04004516
4517 Converts glyphs into text if possible.
4518 Glyph values without direct Unicode equivalents are mapped to zero.
4519 Uses the Typeface, but is unaffected
4520 by Text_Encoding; the text values returned are equivalent to kUTF32_TextEncoding.
4521
4522 Only supported on platforms that use FreeType as the Font_Engine.
4523
4524 #Param glyphs array of indices into font ##
4525 #Param count length of glyph array ##
4526 #Param text storage for character codes, one per glyph ##
4527
4528 #Example
4529 #Height 64
4530 #Description
4531 Convert UTF-8 text to glyphs; then convert glyphs to Unichar code points.
4532 ##
4533 void draw(SkCanvas* canvas) {
4534 SkPaint paint;
4535 const char hello[] = "Hello!";
4536 const int count = sizeof(hello) - 1;
4537 SkGlyphID glyphs[count];
4538 if (count != paint.textToGlyphs(hello, count, glyphs)) {
4539 return;
4540 }
4541 SkUnichar unichars[count];
4542 paint.glyphsToUnichars(glyphs, count, unichars);
4543 paint.setTextEncoding(SkPaint::kUTF32_TextEncoding);
4544 canvas->drawText(unichars, sizeof(unichars), 10, 30, paint);
4545 }
4546 ##
4547
4548##
4549
4550# ------------------------------------------------------------------------------
Cary Clark08895c42018-02-01 09:37:32 -05004551#Subtopic Measure_Text
4552#Line # width, height, bounds of text ##
Cary Clark8032b982017-07-28 11:04:54 -04004553
4554#Method SkScalar measureText(const void* text, size_t length, SkRect* bounds) const
4555
Cary Clarkab2621d2018-01-30 10:08:57 -05004556#In Measure_Text
4557#Line # returns advance width and bounds of text ##
Cary Clark8032b982017-07-28 11:04:54 -04004558 Returns the advance width of text if kVerticalText_Flag is clear,
4559 and the height of text if kVerticalText_Flag is set.
4560 The advance is the normal distance to move before drawing additional text.
4561 Uses Text_Encoding to decode text, Typeface to get the font metrics,
4562 and Text_Size, Text_Scale_X, Text_Skew_X, Stroke_Width, and
4563 Path_Effect to scale the metrics and bounds.
4564 Returns the bounding box of text if bounds is not nullptr.
4565 The bounding box is computed as if the text was drawn at the origin.
4566
4567 #Param text character codes or glyph indices to be measured ##
4568 #Param length number of bytes of text to measure ##
4569 #Param bounds returns bounding box relative to (0, 0) if not nullptr ##
4570
4571 #Return advance width or height ##
4572
4573 #Example
4574 #Height 64
4575 void draw(SkCanvas* canvas) {
4576 SkPaint paint;
4577 paint.setAntiAlias(true);
4578 paint.setTextSize(50);
4579 const char str[] = "ay^jZ";
4580 const int count = sizeof(str) - 1;
4581 canvas->drawText(str, count, 25, 50, paint);
4582 SkRect bounds;
4583 paint.measureText(str, count, &bounds);
4584 canvas->translate(25, 50);
4585 paint.setStyle(SkPaint::kStroke_Style);
4586 canvas->drawRect(bounds, paint);
4587 }
4588 ##
4589
4590##
4591
4592#Method SkScalar measureText(const void* text, size_t length) const
4593
Cary Clarkab2621d2018-01-30 10:08:57 -05004594#In Measure_Text
Cary Clark8032b982017-07-28 11:04:54 -04004595 Returns the advance width of text if kVerticalText_Flag is clear,
4596 and the height of text if kVerticalText_Flag is set.
4597 The advance is the normal distance to move before drawing additional text.
4598 Uses Text_Encoding to decode text, Typeface to get the font metrics,
4599 and Text_Size to scale the metrics.
4600 Does not scale the advance or bounds by Fake_Bold or Path_Effect.
4601
4602 #Param text character codes or glyph indices to be measured ##
4603 #Param length number of bytes of text to measure ##
4604
4605 #Return advance width or height ##
4606
4607 #Example
4608 SkPaint paint;
4609 SkDebugf("default width = %g\n", paint.measureText("!", 1));
4610 paint.setTextSize(paint.getTextSize() * 2);
4611 SkDebugf("double width = %g\n", paint.measureText("!", 1));
4612
4613 #StdOut
4614 default width = 5
4615 double width = 10
4616 ##
4617 ##
4618
4619##
4620
4621#Method size_t breakText(const void* text, size_t length, SkScalar maxWidth,
Cary Clark73fa9722017-08-29 17:36:51 -04004622 SkScalar* measuredWidth = nullptr) const
Cary Clarkab2621d2018-01-30 10:08:57 -05004623#In Measure_Text
4624#Line # returns text that fits in a width ##
Cary Clark8032b982017-07-28 11:04:54 -04004625
4626 Returns the bytes of text that fit within maxWidth.
4627 If kVerticalText_Flag is clear, the text fragment fits if its advance width is less than or
4628 equal to maxWidth.
4629 If kVerticalText_Flag is set, the text fragment fits if its advance height is less than or
4630 equal to maxWidth.
4631 Measures only while the advance is less than or equal to maxWidth.
4632 Returns the advance or the text fragment in measuredWidth if it not nullptr.
4633 Uses Text_Encoding to decode text, Typeface to get the font metrics,
4634 and Text_Size to scale the metrics.
4635 Does not scale the advance or bounds by Fake_Bold or Path_Effect.
4636
4637 #Param text character codes or glyph indices to be measured ##
4638 #Param length number of bytes of text to measure ##
4639 #Param maxWidth advance limit; text is measured while advance is less than maxWidth ##
4640 #Param measuredWidth returns the width of the text less than or equal to maxWidth ##
4641 #Return bytes of text that fit, always less than or equal to length ##
4642
4643 #Example
4644 #Description
4645 Line under "Breakfast" shows desired width, shorter than available characters.
4646 Line under "Bre" shows measured width after breaking text.
4647 ##
4648 #Height 128
4649 #Width 280
4650 void draw(SkCanvas* canvas) {
4651 SkPaint paint;
4652 paint.setAntiAlias(true);
4653 paint.setTextSize(50);
4654 const char str[] = "Breakfast";
4655 const int count = sizeof(str) - 1;
4656 canvas->drawText(str, count, 25, 50, paint);
4657 SkScalar measuredWidth;
4658 int partialBytes = paint.breakText(str, count, 100, &measuredWidth);
4659 canvas->drawText(str, partialBytes, 25, 100, paint);
4660 canvas->drawLine(25, 60, 25 + 100, 60, paint);
4661 canvas->drawLine(25, 110, 25 + measuredWidth, 110, paint);
4662 }
4663 ##
4664
4665##
4666
4667#Method int getTextWidths(const void* text, size_t byteLength, SkScalar widths[],
Cary Clark73fa9722017-08-29 17:36:51 -04004668 SkRect bounds[] = nullptr) const
Cary Clarkab2621d2018-01-30 10:08:57 -05004669#In Measure_Text
4670#Line # returns advance and bounds for each glyph in text ##
Cary Clark8032b982017-07-28 11:04:54 -04004671
4672 Retrieves the advance and bounds for each glyph in text, and returns
4673 the glyph count in text.
4674 Both widths and bounds may be nullptr.
4675 If widths is not nullptr, widths must be an array of glyph count entries.
4676 if bounds is not nullptr, bounds must be an array of glyph count entries.
4677 If kVerticalText_Flag is clear, widths returns the horizontal advance.
4678 If kVerticalText_Flag is set, widths returns the vertical advance.
4679 Uses Text_Encoding to decode text, Typeface to get the font metrics,
4680 and Text_Size to scale the widths and bounds.
4681 Does not scale the advance by Fake_Bold or Path_Effect.
4682 Does include Fake_Bold and Path_Effect in the bounds.
4683
4684 #Param text character codes or glyph indices to be measured ##
4685 #Param byteLength number of bytes of text to measure ##
4686 #Param widths returns text advances for each glyph; may be nullptr ##
4687 #Param bounds returns bounds for each glyph relative to (0, 0); may be nullptr ##
4688
4689 #Return glyph count in text ##
4690
4691 #Example
4692 #Height 160
4693 #Description
Cary Clarkce101242017-09-01 15:51:02 -04004694 Bounds of Glyphs increase for stroked text, but text advance remains the same.
Cary Clark8032b982017-07-28 11:04:54 -04004695 The underlines show the text advance, spaced to keep them distinct.
4696 ##
4697 void draw(SkCanvas* canvas) {
4698 SkPaint paint;
4699 paint.setAntiAlias(true);
4700 paint.setTextSize(50);
4701 const char str[] = "abc";
4702 const int bytes = sizeof(str) - 1;
4703 int count = paint.getTextWidths(str, bytes, nullptr);
4704 std::vector<SkScalar> widths;
4705 std::vector<SkRect> bounds;
4706 widths.resize(count);
4707 bounds.resize(count);
4708 for (int loop = 0; loop < 2; ++loop) {
4709 (void) paint.getTextWidths(str, count, &widths.front(), &bounds.front());
4710 SkPoint loc = { 25, 50 };
4711 canvas->drawText(str, bytes, loc.fX, loc.fY, paint);
4712 paint.setStyle(SkPaint::kStroke_Style);
4713 paint.setStrokeWidth(0);
4714 SkScalar advanceY = loc.fY + 10;
4715 for (int index = 0; index < count; ++index) {
4716 bounds[index].offset(loc.fX, loc.fY);
4717 canvas->drawRect(bounds[index], paint);
4718 canvas->drawLine(loc.fX, advanceY, loc.fX + widths[index], advanceY, paint);
4719 loc.fX += widths[index];
4720 advanceY += 5;
4721 }
4722 canvas->translate(0, 80);
4723 paint.setStrokeWidth(3);
4724 }
4725 }
4726 ##
4727
4728##
4729
Cary Clark08895c42018-02-01 09:37:32 -05004730#Subtopic Measure_Text ##
Cary Clark8032b982017-07-28 11:04:54 -04004731# ------------------------------------------------------------------------------
Cary Clark08895c42018-02-01 09:37:32 -05004732#Subtopic Text_Path
4733#Line # geometry of Glyphs ##
Cary Clark8032b982017-07-28 11:04:54 -04004734
Cary Clarkce101242017-09-01 15:51:02 -04004735Text_Path describes the geometry of Glyphs used to draw text.
Cary Clark8032b982017-07-28 11:04:54 -04004736
4737#Method void getTextPath(const void* text, size_t length, SkScalar x, SkScalar y,
4738 SkPath* path) const
Cary Clarkab2621d2018-01-30 10:08:57 -05004739#In Text_Path
4740#Line # returns Path equivalent to text ##
Cary Clark8032b982017-07-28 11:04:54 -04004741
4742Returns the geometry as Path equivalent to the drawn text.
4743Uses Text_Encoding to decode text, Typeface to get the glyph paths,
4744and Text_Size, Fake_Bold, and Path_Effect to scale and modify the glyph paths.
4745All of the glyph paths are stored in path.
Cary Clark579985c2017-07-31 11:48:27 -04004746Uses x, y, and Text_Align to position path.
Cary Clark8032b982017-07-28 11:04:54 -04004747
4748 #Param text character codes or glyph indices ##
4749 #Param length number of bytes of text ##
4750 #Param x x-coordinate of the origin of the text ##
4751 #Param y y-coordinate of the origin of the text ##
Cary Clarkce101242017-09-01 15:51:02 -04004752 #Param path geometry of the Glyphs ##
Cary Clark8032b982017-07-28 11:04:54 -04004753
4754 #Example
4755 #Description
4756 Text is added to Path, offset, and subtracted from Path, then added at
4757 the offset location. The result is rendered with one draw call.
4758 ##
4759 #Height 128
4760 void draw(SkCanvas* canvas) {
4761 SkPaint paint;
4762 paint.setTextSize(80);
4763 SkPath path, path2;
4764 paint.getTextPath("ABC", 3, 20, 80, &path);
4765 path.offset(20, 20, &path2);
4766 Op(path, path2, SkPathOp::kDifference_SkPathOp, &path);
4767 path.addPath(path2);
4768 paint.setStyle(SkPaint::kStroke_Style);
4769 canvas->drawPath(path, paint);
4770 }
4771 ##
4772
4773##
4774
4775#Method void getPosTextPath(const void* text, size_t length,
4776 const SkPoint pos[], SkPath* path) const
Cary Clarkab2621d2018-01-30 10:08:57 -05004777#In Text_Path
4778#Line # returns Path equivalent to positioned text ##
Cary Clark8032b982017-07-28 11:04:54 -04004779
4780Returns the geometry as Path equivalent to the drawn text.
4781Uses Text_Encoding to decode text, Typeface to get the glyph paths,
4782and Text_Size, Fake_Bold, and Path_Effect to scale and modify the glyph paths.
4783All of the glyph paths are stored in path.
4784Uses pos array and Text_Align to position path.
4785pos contains a position for each glyph.
4786
4787 #Param text character codes or glyph indices ##
4788 #Param length number of bytes of text ##
4789 #Param pos positions of each glyph ##
Cary Clarkce101242017-09-01 15:51:02 -04004790 #Param path geometry of the Glyphs ##
Cary Clark8032b982017-07-28 11:04:54 -04004791
4792 #Example
4793 #Height 85
4794 #Description
Cary Clarkce101242017-09-01 15:51:02 -04004795 Simplifies three Glyphs to eliminate overlaps, and strokes the result.
Cary Clark8032b982017-07-28 11:04:54 -04004796 ##
4797 void draw(SkCanvas* canvas) {
4798 SkPaint paint;
4799 paint.setTextSize(80);
4800 SkPath path, path2;
4801 SkPoint pos[] = {{20, 60}, {30, 70}, {40, 80}};
4802 paint.getPosTextPath("ABC", 3, pos, &path);
4803 Simplify(path, &path);
4804 paint.setStyle(SkPaint::kStroke_Style);
4805 canvas->drawPath(path, paint);
4806 }
4807 ##
4808
4809##
4810
Cary Clark08895c42018-02-01 09:37:32 -05004811#Subtopic Text_Path ##
Cary Clark8032b982017-07-28 11:04:54 -04004812# ------------------------------------------------------------------------------
Cary Clark08895c42018-02-01 09:37:32 -05004813#Subtopic Text_Intercepts
4814#Line # advanced underline, strike through ##
Cary Clark8032b982017-07-28 11:04:54 -04004815
Cary Clarkce101242017-09-01 15:51:02 -04004816Text_Intercepts describe the intersection of drawn text Glyphs with a pair
Cary Clark8032b982017-07-28 11:04:54 -04004817of lines parallel to the text advance. Text_Intercepts permits creating a
Cary Clarkce101242017-09-01 15:51:02 -04004818underline that skips Descenders.
Cary Clark8032b982017-07-28 11:04:54 -04004819
4820#Method int getTextIntercepts(const void* text, size_t length, SkScalar x, SkScalar y,
4821 const SkScalar bounds[2], SkScalar* intervals) const
Cary Clarkab2621d2018-01-30 10:08:57 -05004822#In Text_Intercepts
4823#Line # returns where lines intersect text; underlines ##
Cary Clark8032b982017-07-28 11:04:54 -04004824
4825 Returns the number of intervals that intersect bounds.
4826 bounds describes a pair of lines parallel to the text advance.
Cary Clarkce101242017-09-01 15:51:02 -04004827 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 -04004828 the string.
4829 Uses Text_Encoding to decode text, Typeface to get the glyph paths,
4830 and Text_Size, Fake_Bold, and Path_Effect to scale and modify the glyph paths.
4831 Uses x, y, and Text_Align to position intervals.
4832
4833 Pass nullptr for intervals to determine the size of the interval array.
4834
4835 intervals are cached to improve performance for multiple calls.
4836
4837 #Param text character codes or glyph indices ##
4838 #Param length number of bytes of text ##
4839 #Param x x-coordinate of the origin of the text ##
4840 #Param y y-coordinate of the origin of the text ##
4841 #Param bounds lower and upper line parallel to the advance ##
4842 #Param intervals returned intersections; may be nullptr ##
4843
4844 #Return number of intersections; may be zero ##
4845
4846#Example
4847#Height 128
4848#Description
Cary Clarkce101242017-09-01 15:51:02 -04004849Underline uses intercepts to draw on either side of the glyph Descender.
Cary Clark8032b982017-07-28 11:04:54 -04004850##
4851void draw(SkCanvas* canvas) {
4852 SkPaint paint;
4853 paint.setTextSize(120);
4854 SkPoint textOrigin = { 20, 100 };
4855 SkScalar bounds[] = { 100, 108 };
4856 int count = paint.getTextIntercepts("y", 1, textOrigin.fX, textOrigin.fY, bounds, nullptr);
4857 std::vector<SkScalar> intervals;
4858 intervals.resize(count);
4859 (void) paint.getTextIntercepts("y", 1, textOrigin.fX, textOrigin.fY, bounds,
4860 &intervals.front());
4861 canvas->drawString("y", textOrigin.fX, textOrigin.fY, paint);
4862 paint.setColor(SK_ColorRED);
4863 SkScalar x = textOrigin.fX;
4864 for (int i = 0; i < count; i += 2) {
4865 canvas->drawRect({x, bounds[0], intervals[i], bounds[1]}, paint);
4866 x = intervals[i + 1];
4867 }
4868 canvas->drawRect({intervals[count - 1], bounds[0],
4869 textOrigin.fX + paint.measureText("y", 1), bounds[1]}, paint);
4870}
4871##
4872
4873##
4874
4875#Method int getPosTextIntercepts(const void* text, size_t length, const SkPoint pos[],
4876 const SkScalar bounds[2], SkScalar* intervals) const
Cary Clarkab2621d2018-01-30 10:08:57 -05004877#In Text_Intercepts
4878#Line # returns where lines intersect positioned text; underlines ##
Cary Clark8032b982017-07-28 11:04:54 -04004879
4880 Returns the number of intervals that intersect bounds.
4881 bounds describes a pair of lines parallel to the text advance.
Cary Clarkce101242017-09-01 15:51:02 -04004882 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 -04004883 the string.
4884 Uses Text_Encoding to decode text, Typeface to get the glyph paths,
4885 and Text_Size, Fake_Bold, and Path_Effect to scale and modify the glyph paths.
4886 Uses pos array and Text_Align to position intervals.
4887
4888 Pass nullptr for intervals to determine the size of the interval array.
4889
4890 intervals are cached to improve performance for multiple calls.
4891
4892 #Param text character codes or glyph indices ##
4893 #Param length number of bytes of text ##
4894 #Param pos positions of each glyph ##
4895 #Param bounds lower and upper line parallel to the advance ##
4896 #Param intervals returned intersections; may be nullptr ##
4897
Cary Clarka523d2d2017-08-30 08:58:10 -04004898 #Return number of intersections; may be zero ##
Cary Clark8032b982017-07-28 11:04:54 -04004899
4900 #Example
4901 #Description
Cary Clarkce101242017-09-01 15:51:02 -04004902 Text intercepts draw on either side of, but not inside, Glyphs in a run.
Cary Clark8032b982017-07-28 11:04:54 -04004903 ##
4904 void draw(SkCanvas* canvas) {
4905 SkPaint paint;
4906 paint.setTextSize(120);
4907 paint.setVerticalText(true);
4908 SkPoint textPos[] = {{ 60, 40 }, { 60, 140 }};
4909 SkScalar bounds[] = { 56, 64 };
4910 const char str[] = "A-";
4911 int len = sizeof(str) - 1;
4912 int count = paint.getPosTextIntercepts(str, len, textPos, bounds, nullptr);
4913 std::vector<SkScalar> intervals;
4914 intervals.resize(count);
4915 (void) paint.getPosTextIntercepts(str, len, textPos, bounds, &intervals.front());
4916 canvas->drawPosText(str, len, textPos, paint);
4917 paint.setColor(SK_ColorRED);
4918 SkScalar y = textPos[0].fY;
4919 for (int i = 0; i < count; i+= 2) {
4920 canvas->drawRect({bounds[0], y, bounds[1], intervals[i]}, paint);
4921 y = intervals[i + 1];
4922 }
4923 canvas->drawRect({bounds[0], intervals[count - 1], bounds[1], 240}, paint);
4924 }
4925 ##
4926
4927##
4928
4929#Method int getPosTextHIntercepts(const void* text, size_t length, const SkScalar xpos[],
4930 SkScalar constY, const SkScalar bounds[2],
4931 SkScalar* intervals) const
Cary Clarkab2621d2018-01-30 10:08:57 -05004932#In Text_Intercepts
4933#Line # returns where lines intersect horizontally positioned text; underlines ##
Cary Clark8032b982017-07-28 11:04:54 -04004934
4935 Returns the number of intervals that intersect bounds.
4936 bounds describes a pair of lines parallel to the text advance.
Cary Clarkce101242017-09-01 15:51:02 -04004937 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 -04004938 the string.
4939 Uses Text_Encoding to decode text, Typeface to get the glyph paths,
4940 and Text_Size, Fake_Bold, and Path_Effect to scale and modify the glyph paths.
4941 Uses xpos array, constY, and Text_Align to position intervals.
4942
4943 Pass nullptr for intervals to determine the size of the interval array.
4944
4945 intervals are cached to improve performance for multiple calls.
4946
4947 #Param text character codes or glyph indices ##
4948 #Param length number of bytes of text ##
4949 #Param xpos positions of each glyph in x ##
4950 #Param constY position of each glyph in y ##
4951 #Param bounds lower and upper line parallel to the advance ##
4952 #Param intervals returned intersections; may be nullptr ##
4953
4954 #Return number of intersections; may be zero ##
4955
4956 #Example
4957 #Height 128
4958 #Description
4959 Text intercepts do not take stroke thickness into consideration.
4960 ##
4961 void draw(SkCanvas* canvas) {
4962 SkPaint paint;
4963 paint.setTextSize(120);
4964 paint.setStyle(SkPaint::kStroke_Style);
4965 paint.setStrokeWidth(4);
4966 SkScalar textPosH[] = { 20, 80, 140 };
4967 SkScalar y = 100;
4968 SkScalar bounds[] = { 56, 78 };
4969 const char str[] = "\\-/";
4970 int len = sizeof(str) - 1;
4971 int count = paint.getPosTextHIntercepts(str, len, textPosH, y, bounds, nullptr);
4972 std::vector<SkScalar> intervals;
4973 intervals.resize(count);
4974 (void) paint.getPosTextHIntercepts(str, len, textPosH, y, bounds, &intervals.front());
4975 canvas->drawPosTextH(str, len, textPosH, y, paint);
4976 paint.setColor(0xFFFF7777);
4977 paint.setStyle(SkPaint::kFill_Style);
4978 SkScalar x = textPosH[0];
4979 for (int i = 0; i < count; i+= 2) {
4980 canvas->drawRect({x, bounds[0], intervals[i], bounds[1]}, paint);
4981 x = intervals[i + 1];
4982 }
4983 canvas->drawRect({intervals[count - 1], bounds[0], 180, bounds[1]}, paint);
4984 }
4985 ##
4986
4987##
4988
4989
4990#Method int getTextBlobIntercepts(const SkTextBlob* blob, const SkScalar bounds[2],
4991 SkScalar* intervals) const
Cary Clarkab2621d2018-01-30 10:08:57 -05004992#In Text_Intercepts
4993#Line # returns where lines intersect Text_Blob; underlines ##
Cary Clark8032b982017-07-28 11:04:54 -04004994
4995 Returns the number of intervals that intersect bounds.
4996 bounds describes a pair of lines parallel to the text advance.
Cary Clarkce101242017-09-01 15:51:02 -04004997 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 -04004998 the string.
Cary Clark3cd22cc2017-12-01 11:49:58 -05004999 Uses Typeface to get the glyph paths,
Cary Clark8032b982017-07-28 11:04:54 -04005000 and Text_Size, Fake_Bold, and Path_Effect to scale and modify the glyph paths.
Cary Clarkce101242017-09-01 15:51:02 -04005001 Uses run array and Text_Align to position intervals.
Cary Clark8032b982017-07-28 11:04:54 -04005002
Cary Clark3cd22cc2017-12-01 11:49:58 -05005003 Text_Encoding must be set to SkPaint::kGlyphID_TextEncoding.
5004
Cary Clark8032b982017-07-28 11:04:54 -04005005 Pass nullptr for intervals to determine the size of the interval array.
5006
5007 intervals are cached to improve performance for multiple calls.
5008
Cary Clarkce101242017-09-01 15:51:02 -04005009 #Param blob Glyphs, positions, and text paint attributes ##
Cary Clark8032b982017-07-28 11:04:54 -04005010 #Param bounds lower and upper line parallel to the advance ##
5011 #Param intervals returned intersections; may be nullptr ##
5012
5013 #Return number of intersections; may be zero ##
5014
5015 #Example
5016 #Height 143
5017 void draw(SkCanvas* canvas) {
5018 SkPaint paint;
Cary Clark3cd22cc2017-12-01 11:49:58 -05005019 paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
Cary Clark8032b982017-07-28 11:04:54 -04005020 paint.setTextSize(120);
5021 SkPoint textPos = { 20, 110 };
5022 int len = 3;
5023 SkTextBlobBuilder textBlobBuilder;
5024 const SkTextBlobBuilder::RunBuffer& run =
5025 textBlobBuilder.allocRun(paint, len, textPos.fX, textPos.fY);
5026 run.glyphs[0] = 10;
5027 run.glyphs[1] = 20;
5028 run.glyphs[2] = 30;
5029 sk_sp<const SkTextBlob> blob = textBlobBuilder.make();
5030 canvas->drawTextBlob(blob.get(), textPos.fX, textPos.fY, paint);
5031 SkScalar bounds[] = { 116, 134 };
5032 int count = paint.getTextBlobIntercepts(blob.get(), bounds, nullptr);
5033 std::vector<SkScalar> intervals;
5034 intervals.resize(count);
5035 (void) paint.getTextBlobIntercepts(blob.get(), bounds, &intervals.front());
5036 canvas->drawTextBlob(blob.get(), 0, 0, paint);
5037 paint.setColor(0xFFFF7777);
5038 SkScalar x = textPos.fX;
5039 for (int i = 0; i < count; i+= 2) {
5040 canvas->drawRect({x, bounds[0], intervals[i], bounds[1]}, paint);
5041 x = intervals[i + 1];
5042 }
5043 canvas->drawRect({intervals[count - 1], bounds[0], 180, bounds[1]}, paint);
5044 }
5045 ##
5046
5047##
5048
Cary Clark08895c42018-02-01 09:37:32 -05005049#Subtopic Text_Intercepts ##
Cary Clark8032b982017-07-28 11:04:54 -04005050# ------------------------------------------------------------------------------
5051
5052#Method bool nothingToDraw() const
Cary Clark78de7512018-02-07 07:27:09 -05005053#In Utility
Cary Clarkab2621d2018-01-30 10:08:57 -05005054#Line # returns true if Paint prevents all drawing ##
Cary Clark579985c2017-07-31 11:48:27 -04005055 Returns true if Paint prevents all drawing;
5056 otherwise, the Paint may or may not allow drawing.
Cary Clark8032b982017-07-28 11:04:54 -04005057
Cary Clarkce101242017-09-01 15:51:02 -04005058 Returns true if, for example, Blend_Mode combined with Color_Alpha computes a
5059 new Alpha of zero.
Cary Clark8032b982017-07-28 11:04:54 -04005060
5061 #Return true if Paint prevents all drawing ##
5062
5063 #Example
5064 void draw(SkCanvas* canvas) {
5065 auto debugster = [](const char* prefix, const SkPaint& p) -> void {
5066 SkDebugf("%s nothing to draw: %s\n", prefix,
5067 p.nothingToDraw() ? "true" : "false");
5068 };
5069 SkPaint paint;
5070 debugster("initial", paint);
5071 paint.setBlendMode(SkBlendMode::kDst);
5072 debugster("blend dst", paint);
5073 paint.setBlendMode(SkBlendMode::kSrcOver);
5074 debugster("blend src over", paint);
5075 paint.setAlpha(0);
5076 debugster("alpha 0", paint);
5077 }
5078
5079 #StdOut
5080 initial nothing to draw: false
5081 blend dst nothing to draw: true
5082 blend src over nothing to draw: false
5083 alpha 0 nothing to draw: true
5084 #StdOut ##
5085 ##
5086
5087##
5088
5089# ------------------------------------------------------------------------------
Cary Clark08895c42018-02-01 09:37:32 -05005090#Subtopic Fast_Bounds
5091#Line # approximate area required by Paint ##
Cary Clark8032b982017-07-28 11:04:54 -04005092 #Private
5093 To be made private.
5094 ##
5095
5096Fast_Bounds methods conservatively outset a drawing bounds by additional area
5097Paint may draw to.
5098
5099#Method bool canComputeFastBounds() const
Cary Clarkab2621d2018-01-30 10:08:57 -05005100
5101#In Fast_Bounds
5102#Line # returns true if settings allow for fast bounds computation ###Private
Cary Clark8032b982017-07-28 11:04:54 -04005103 (to be made private)
5104 ##
5105
5106 Returns true if Paint does not include elements requiring extensive computation
5107 to compute Device bounds of drawn geometry. For instance, Paint with Path_Effect
5108 always returns false.
5109
5110 #Return true if Paint allows for fast computation of bounds ##
5111##
5112
5113#Method const SkRect& computeFastBounds(const SkRect& orig, SkRect* storage) const
Cary Clarkab2621d2018-01-30 10:08:57 -05005114
5115#In Fast_Bounds
5116#Line # returns fill bounds for quick reject tests ###Private
Cary Clark8032b982017-07-28 11:04:54 -04005117 (to be made private)
5118 ##
5119
5120 Only call this if canComputeFastBounds returned true. This takes a
5121 raw rectangle (the raw bounds of a shape), and adjusts it for stylistic
5122 effects in the paint (e.g. stroking). If needed, it uses the storage
Cary Clarkce101242017-09-01 15:51:02 -04005123 parameter. It returns the adjusted bounds that can then be used
Cary Clark8032b982017-07-28 11:04:54 -04005124 for SkCanvas::quickReject tests.
5125
Cary Clarkce101242017-09-01 15:51:02 -04005126 The returned Rect will either be orig or storage, thus the caller
Cary Clark8032b982017-07-28 11:04:54 -04005127 should not rely on storage being set to the result, but should always
Cary Clarkce101242017-09-01 15:51:02 -04005128 use the returned value. It is legal for orig and storage to be the same
5129 Rect.
Cary Clark8032b982017-07-28 11:04:54 -04005130
5131 #Private
5132 e.g.
5133 if (paint.canComputeFastBounds()) {
5134 SkRect r, storage;
5135 path.computeBounds(&r, SkPath::kFast_BoundsType);
5136 const SkRect& fastR = paint.computeFastBounds(r, &storage);
5137 if (canvas->quickReject(fastR, ...)) {
5138 // don't draw the path
5139 }
5140 }
5141 ##
5142
5143 #Param orig geometry modified by Paint when drawn ##
5144 #Param storage computed bounds of geometry; may not be nullptr ##
5145
5146 #Return fast computed bounds ##
5147##
5148
5149#Method const SkRect& computeFastStrokeBounds(const SkRect& orig,
5150 SkRect* storage) const
Cary Clarkab2621d2018-01-30 10:08:57 -05005151#In Fast_Bounds
5152#Line # returns stroke bounds for quick reject tests ##
Cary Clark8032b982017-07-28 11:04:54 -04005153 #Private
5154 (to be made private)
5155 ##
5156
5157 #Param orig geometry modified by Paint when drawn ##
5158 #Param storage computed bounds of geometry ##
5159
5160 #Return fast computed bounds ##
5161##
5162
5163#Method const SkRect& doComputeFastBounds(const SkRect& orig, SkRect* storage,
5164 Style style) const
Cary Clarkab2621d2018-01-30 10:08:57 -05005165#In Fast_Bounds
5166#Line # returns bounds for quick reject tests ##
Cary Clark8032b982017-07-28 11:04:54 -04005167 #Private
5168 (to be made private)
5169 ##
5170
Cary Clarkce101242017-09-01 15:51:02 -04005171 Computes the bounds, overriding the Paint Style. This can be used to
5172 account for additional width required by stroking orig, without
5173 altering Style set to fill.
Cary Clark8032b982017-07-28 11:04:54 -04005174
5175 #Param orig geometry modified by Paint when drawn ##
5176 #Param storage computed bounds of geometry ##
5177 #Param style overrides Style ##
5178
5179 #Return fast computed bounds ##
5180##
5181
Cary Clark08895c42018-02-01 09:37:32 -05005182#Subtopic Fast_Bounds Fast_Bounds ##
Cary Clark8032b982017-07-28 11:04:54 -04005183
5184# ------------------------------------------------------------------------------
Cary Clark78de7512018-02-07 07:27:09 -05005185#Subtopic Utility
5186#Populate
5187#Line # rarely called management functions ##
5188##
Cary Clark8032b982017-07-28 11:04:54 -04005189
Cary Clark78de7512018-02-07 07:27:09 -05005190#Method void toString(SkString* str) const
5191#In Utility
Cary Clarkab2621d2018-01-30 10:08:57 -05005192#Line # converts Paint to machine readable form ##
Cary Clark8032b982017-07-28 11:04:54 -04005193#DefinedBy SK_TO_STRING_NONVIRT() ##
5194
5195#Private
5196macro expands to: void toString(SkString* str) const;
5197##
5198
Cary Clarkce101242017-09-01 15:51:02 -04005199Creates string representation of Paint. The representation is read by
5200internal debugging tools. The interface and implementation may be
5201suppressed by defining SK_IGNORE_TO_STRING.
Cary Clark8032b982017-07-28 11:04:54 -04005202
Cary Clarkce101242017-09-01 15:51:02 -04005203#Param str storage for string representation of Paint ##
Cary Clark8032b982017-07-28 11:04:54 -04005204
5205#Example
5206 SkPaint paint;
5207 SkString str;
5208 paint.toString(&str);
5209 const char textSize[] = "TextSize:";
5210 const int trailerSize = strlen("</dd><dt>");
5211 int textSizeLoc = str.find(textSize) + strlen(textSize) + trailerSize;
5212 const char* sizeStart = &str.c_str()[textSizeLoc];
5213 int textSizeEnd = SkStrFind(sizeStart, "</dd>");
5214 SkDebugf("text size = %.*s\n", textSizeEnd, sizeStart);
5215
5216 #StdOut
5217 text size = 12
5218 ##
5219
5220##
5221
Cary Clark2ade9972017-11-02 17:49:34 -04005222#SeeAlso SkPathEffect::toString SkMaskFilter::toString SkColorFilter::toString SkImageFilter::toString
Cary Clark8032b982017-07-28 11:04:54 -04005223
5224##
5225
5226# ------------------------------------------------------------------------------
5227
5228#Class SkPaint ##
5229
5230#Topic Paint ##
Cary Clark4855f782018-02-06 09:41:53 -05005231