blob: f5bd893563a6987cdfb6d44711905a341af2d0c2 [file] [log] [blame]
Cary Clark8032b982017-07-28 11:04:54 -04001#Topic Canvas
Cary Clark12799e12017-07-28 15:18:29 -04002#Alias Canvas_Reference
Cary Clark8032b982017-07-28 11:04:54 -04003
4Canvas provides an interface for drawing, and how the drawing is clipped and transformed.
5Canvas contains a stack of Matrix and Clip values.
6
7Canvas and Paint together provide the state to draw into Surface or Device.
Cary Clarkbad5ad72017-08-03 17:14:08 -04008Each Canvas draw call transforms the geometry of the object by the concatenation of all
9Matrix values in the stack. The transformed geometry is clipped by the intersection
10of all of Clip values in the stack. The Canvas draw calls use Paint to supply drawing
11state such as Color, Typeface, text size, stroke width, Shader and so on.
Cary Clark8032b982017-07-28 11:04:54 -040012
13To draw to a pixel-based destination, create Raster_Surface or GPU_Surface.
14Request Canvas from Surface to obtain the interface to draw.
15Canvas generated by Raster_Surface draws to memory visible to the CPU.
16Canvas generated by GPU_Surface uses Vulkan or OpenGL to draw to the GPU.
17
Cary Clarkbad5ad72017-08-03 17:14:08 -040018To draw to a document, obtain Canvas from SVG_Canvas, Document_PDF, or Picture_Recorder.
19Document-based Canvas and other Canvas subclasses reference Device describing the
20destination.
21
Cary Clark8032b982017-07-28 11:04:54 -040022Canvas can be constructed to draw to Bitmap without first creating Raster_Surface.
23This approach may be deprecated in the future.
24
Cary Clark8032b982017-07-28 11:04:54 -040025#Class SkCanvas
26
27#Topic Overview
28
29#Subtopic Subtopics
30#Table
31#Legend
32# topics # description ##
33#Legend ##
34#ToDo generate a TOC here ##
35#Table ##
36#Subtopic ##
37
38#Subtopic Constants
39#Table
40#Legend
41# constants # description ##
42#Legend ##
43# Lattice::Flags # Controls Lattice transparency. ##
44# PointMode # Sets drawPoints options. ##
45# SaveLayerFlags # Sets SaveLayerRec options. ##
46# SrcRectConstraint # Sets drawImageRect options. ##
47#Table ##
48#Subtopic ##
49
50#Subtopic Structs
51#Table
52#Legend
53# struct # description ##
54#Legend ##
55# Lattice # Divides Bitmap, Image into a rectangular grid. ##
56# SaveLayerRec # Contains state to create the layer offscreen. ##
57#Table ##
58#Subtopic ##
59
60#Subtopic Constructors
61
62Create the desired type of Surface to obtain its Canvas when possible. Constructors are useful
63when no Surface is required, and some helpers implicitly create Raster_Surface.
64
65#Table
66#Legend
67# # description ##
68#Legend ##
69# SkCanvas() # No Surface, no dimensions. ##
70# SkCanvas(int width, int height, const SkSurfaceProps* = NULL) # No Surface, set dimensions, Surface_Properties. ##
71# SkCanvas(SkBaseDevice* device) # Existing Device. (SkBaseDevice is private.) ##
72# SkCanvas(const SkBitmap& bitmap) # Uses existing Bitmap. ##
73# SkCanvas(const SkBitmap& bitmap, const SkSurfaceProps& props) # Uses existing Bitmap and Surface_Properties. ##
74# MakeRasterDirect # Creates from SkImageInfo and Pixel_Storage. ##
75# MakeRasterDirectN32 # Creates from image data and Pixel_Storage. ##
76#ToDo incomplete ##
77#Table ##
78#Subtopic ##
79
80#Subtopic Member_Functions
81#Table
82#Legend
83# function # description ##
84#Legend ##
85# accessTopLayerPixels # Returns writable pixel access if available. ##
86# accessTopRasterHandle # Returns context that tracks Clip and Matrix. ##
87# clear() # Fills Clip with Color. ##
88# clipPath # Combines Clip with Path. ##
89# clipRRect # Combines Clip with Round_Rect. ##
90# clipRect # Combines Clip with Rect. ##
91# clipRegion # Combines Clip with Region. ##
92# concat() # Multiplies Matrix by Matrix. ##
93# discard() # Makes Canvas contents undefined. ##
94# drawAnnotation # Associates a Rect with a key-value pair.##
95# drawArc # Draws Arc using Clip, Matrix, and Paint.##
96# drawAtlas # Draws sprites using Clip, Matrix, and Paint.##
97# drawBitmap # Draws Bitmap at (x, y) position. ##
98# drawBitmapLattice # Draws differentially stretched Bitmap. ##
99# drawBitmapNine # Draws Nine_Patch Bitmap. ##
100# drawBitmapRect # Draws Bitmap, source Rect to destination Rect. ##
101# drawCircle # Draws Circle using Clip, Matrix, and Paint. ##
102# drawColor # Fills Clip with Color and Blend_Mode. ##
103# drawDRRect # Draws double Round_Rect stroked or filled. ##
104# drawDrawable # Draws Drawable, encapsulated drawing commands. ##
105# drawIRect # Draws IRect using Clip, Matrix, and Paint. ##
106# drawImage # Draws Image at (x, y) position. ##
107# drawImageLattice # Draws differentially stretched Image. ##
108# drawImageNine # Draws Nine_Patch Image. ##
109# drawImageRect # Draws Image, source Rect to destination Rect. ##
110# drawLine # Draws line segment between two points.##
111# drawOval # Draws Oval using Clip, Matrix, and Paint. ##
112# drawPaint # Fills Clip with Paint. ##
113# drawPatch # Draws cubic Coons patch. ##
114# drawPath # Draws Path using Clip, Matrix, and Paint. ##
115# drawPicture # Draws Picture using Clip and Matrix. ##
116# drawPoint # Draws point at (x, y) position. ##
117# drawPoints # Draws array as points, lines, polygon. ##
118# drawPosText # Draws text at array of (x, y) positions. ##
119# drawPosTextH # Draws text at x positions with common baseline. ##
120# drawRRect # Draws Round_Rect using Clip, Matrix, and Paint. ##
121# drawRect # Draws Rect using Clip, Matrix, and Paint. ##
122# drawRegion # Draws Region using Clip, Matrix, and Paint. ##
123# drawRoundRect # Draws Round_Rect using Clip, Matrix, and Paint. ##
124# drawText # Draws text at (x, y), using font advance. ##
125# drawTextBlob # Draws text with arrays of positions and Paint. ##
126# drawTextOnPath # Draws text following Path contour. ##
127# drawTextOnPathHV # Draws text following Path with offsets. ##
128# drawTextRSXform # Draws text with array of RSXform. ##
129# drawString # Draws null terminated string at (x, y) using font advance. ##
130# drawVertices # Draws Vertices, a triangle mesh. ##
131# flush() # Triggers execution of all pending draw operations. ##
132# getBaseLayerSize # Gets size of base layer in global coordinates. ##
133# getDeviceClipBounds # Returns IRect bounds of Clip. ##
134# getDrawFilter # Legacy; to be deprecated. ##
135# getGrContext # Returns GPU_Context of the GPU_Surface. ##
136# getLocalClipBounds # Returns Clip bounds in source coordinates. ##
137# getMetaData # Associates additional data with the canvas. ##
138# getProps # Copies Surface_Properties if available. ##
139# getSaveCount # Returns depth of stack containing Clip and Matrix. ##
140# getTotalMatrix # Returns Matrix. ##
141# imageInfo # Returns Image_Info for Canvas. ##
142# isClipEmpty # Returns if Clip is empty. ##
143# isClipRect # Returns if Clip is Rect and not empty. ##
144# MakeRasterDirect # Creates Canvas from SkImageInfo and pixel data. ##
145# MakeRasterDirectN32 # Creates Canvas from image specifications and pixel data. ##
146# makeSurface # Creates Surface matching SkImageInfo and SkSurfaceProps. ##
147# peekPixels # Returns if Canvas has direct access to its pixels. ##
148# quickReject # Returns if Rect is outside Clip. ##
149# readPixels # Copies and converts rectangle of pixels from Canvas. ##
150# resetMatrix # Resets Matrix to identity. ##
151# restore() # Restores changes to Clip and Matrix, pops save stack. ##
152# restoreToCount # Restores changes to Clip and Matrix to given depth. ##
153# rotate() # Rotates Matrix. ##
154# save() # Saves Clip and Matrix on stack. ##
155# saveLayer # Saves Clip and Matrix on stack; creates offscreen. ##
156# saveLayerAlpha # Saves Clip and Matrix on stack; creates offscreen; sets opacity. ##
157# saveLayerPreserveLCDTextRequests # Saves Clip and Matrix on stack; creates offscreen for LCD text. ##
158# scale() # Scales Matrix. ##
159# setAllowSimplifyClip # Experimental. ##
160# setDrawFilter # Legacy; to be deprecated. ##
161# setMatrix # Sets Matrix. ##
162# skew() # Skews Matrix. #
163# translate() # Translates Matrix. ##
164# writePixels # Copies and converts rectangle of pixels to Canvas. ##
165#Table ##
166#Subtopic ##
167
168#Topic Overview ##
169
170# ------------------------------------------------------------------------------
171
172#Method static std::unique_ptr<SkCanvas> MakeRasterDirect(const SkImageInfo& info,
173 void* pixels, size_t rowBytes)
174
Cary Clarkbad5ad72017-08-03 17:14:08 -0400175Allocates raster Canvas that will draw directly into pixels.
Cary Clark8032b982017-07-28 11:04:54 -0400176To access pixels after drawing, call flush() or peekPixels.
177
Cary Clarkbad5ad72017-08-03 17:14:08 -0400178Canvas is returned if all parameters are valid.
179Valid parameters include:
180info dimensions are zero or positive;
181info contains Image_Color_Type and Image_Alpha_Type supported by Raster_Surface;
182pixels is not nullptr;
183rowBytes is zero or large enough to contain info width pixels of Image_Color_Type.
184
185pixel buffer size should be info height times rowBytes times bytes required for
186Image_Color_Type.
187
188#Param info width, height, Image_Color_Type, Image_Alpha_Type, Color_Space, of Raster_Surface;
189 width, or height, or both, may be zero
Cary Clark8032b982017-07-28 11:04:54 -0400190##
Cary Clarkbad5ad72017-08-03 17:14:08 -0400191#Param pixels pointer to destination pixels buffer; buffer size should be height
192 times rowBytes times four
Cary Clark8032b982017-07-28 11:04:54 -0400193##
Cary Clarkbad5ad72017-08-03 17:14:08 -0400194#Param rowBytes interval from one Surface row to the next; equal to or greater than
195 info width times bytes required for Image_Color_Type
Cary Clark8032b982017-07-28 11:04:54 -0400196##
197
Cary Clarkbad5ad72017-08-03 17:14:08 -0400198#Return Canvas if all parameters are valid; otherwise, nullptr ##
Cary Clark8032b982017-07-28 11:04:54 -0400199
200#Example
201 #Description
202 Allocates a three by three bitmap, clears it to white, and draws a black pixel
203 in the center.
204 ##
Cary Clarkbad5ad72017-08-03 17:14:08 -0400205void draw(SkCanvas* ) {
206 SkImageInfo info = SkImageInfo::MakeN32Premul(3, 3); // device aligned, 32 bpp, premultipled
207 const size_t minRowBytes = info.minRowBytes(); // bytes used by one bitmap row
208 const size_t size = info.getSafeSize(minRowBytes); // bytes used by all rows
209 SkAutoTMalloc<SkPMColor> storage(size); // allocate storage for pixels
210 SkPMColor* pixels = storage.get(); // get pointer to allocated storage
211 // create a SkCanvas backed by a raster device, and delete it when the
212 // function goes out of scope.
213 std::unique_ptr<SkCanvas> canvas = SkCanvas::MakeRasterDirect(info, pixels, minRowBytes);
214 canvas->clear(SK_ColorWHITE); // white is unpremultiplied, in ARGB order
215 canvas->flush(); // ensure that pixels are cleared
216 SkPMColor pmWhite = pixels[0]; // the premultiplied format may vary
217 SkPaint paint; // by default, draws black
218 canvas->drawPoint(1, 1, paint); // draw in the center
219 canvas->flush(); // ensure that point was drawn
220 for (int y = 0; y < info.height(); ++y) {
221 for (int x = 0; x < info.width(); ++x) {
222 SkDebugf("%c", *pixels++ == pmWhite ? '-' : 'x');
223 }
224 SkDebugf("\n");
225 }
Cary Clark8032b982017-07-28 11:04:54 -0400226}
227 #StdOut
228 ---
229 -x-
230 ---
231 ##
232##
233
234#ToDo incomplete ##
235
236#SeeAlso MakeRasterDirectN32 SkSurface::MakeRasterDirect
237##
238
239# ------------------------------------------------------------------------------
240
241#Method static std::unique_ptr<SkCanvas> MakeRasterDirectN32(int width, int height, SkPMColor* pixels,
242 size_t rowBytes)
243
Cary Clarkbad5ad72017-08-03 17:14:08 -0400244Allocates raster Canvas specified by inline image specification. Subsequent Canvas
245calls draw into pixels.
Cary Clark8032b982017-07-28 11:04:54 -0400246Image_Color_Type is set to kN32_SkColorType.
247Image_Alpha_Type is set to kPremul_SkAlphaType.
248To access pixels after drawing, call flush() or peekPixels.
249
Cary Clarkbad5ad72017-08-03 17:14:08 -0400250Canvas is returned if all parameters are valid.
251Valid parameters include:
252info dimensions are zero or positive;
253info contains Image_Color_Type and Image_Alpha_Type supported by Raster_Surface;
254pixels is not nullptr;
255rowBytes is zero or large enough to contain width pixels of Image_Color_Type.
256
257pixel buffer size should be info height times rowBytes times bytes required for
258Image_Color_Type.
259
260#Param width pixel column count on Raster_Surface created; must be zero or greater ##
261#Param height pixel row count on Raster_Surface created.; must be zero or greater ##
262#Param pixels pointer to destination pixels buffer; buffer size should be height
263 times rowBytes times four
Cary Clark8032b982017-07-28 11:04:54 -0400264##
Cary Clarkbad5ad72017-08-03 17:14:08 -0400265#Param rowBytes interval from one Surface row to the next; equal to or greater than
266 width times four
Cary Clark8032b982017-07-28 11:04:54 -0400267##
268
Cary Clarkbad5ad72017-08-03 17:14:08 -0400269#Return Canvas if all parameters are valid; otherwise, nullptr ##
Cary Clark8032b982017-07-28 11:04:54 -0400270
271#Example
272 #Description
273 Allocates a three by three bitmap, clears it to white, and draws a black pixel
274 in the center.
275 ##
276void draw(SkCanvas* ) {
277 const int width = 3;
278 const int height = 3;
279 SkPMColor pixels[height][width]; // allocate a 3x3 premultiplied bitmap on the stack
280 // create a SkCanvas backed by a raster device, and delete it when the
281 // function goes out of scope.
282 std::unique_ptr<SkCanvas> canvas = SkCanvas::MakeRasterDirectN32(
283 width,
284 height,
285 pixels[0], // top left of the bitmap
286 sizeof(pixels[0])); // byte width of the each row
287 // write a pre-multiplied value for white into all pixels in the bitmap
288 canvas->clear(SK_ColorWHITE);
289 SkPMColor pmWhite = pixels[0][0]; // the premultiplied format may vary
290 SkPaint paint; // by default, draws black
291 canvas->drawPoint(1, 1, paint); // draw in the center
292 canvas->flush(); // ensure that pixels is ready to be read
293 for (int y = 0; y < height; ++y) {
294 for (int x = 0; x < width; ++x) {
295 SkDebugf("%c", pixels[y][x] == pmWhite ? '-' : 'x');
296 }
297 SkDebugf("\n");
298 }
299}
300 #StdOut
301 ---
302 -x-
303 ---
304 ##
305##
306
307#ToDo incomplete ##
308
309##
310
311# ------------------------------------------------------------------------------
312
313#Method SkCanvas()
314
315Creates an empty canvas with no backing device/pixels, and zero
316dimensions.
317
Cary Clarkbad5ad72017-08-03 17:14:08 -0400318#Return empty canvas ##
Cary Clark8032b982017-07-28 11:04:54 -0400319
320#Example
321
322#Description
323Passes a placeholder to a function that requires one.
324##
325
326#Function
Cary Clarkbad5ad72017-08-03 17:14:08 -0400327// Returns true if either the canvas rotates the text by 90 degrees, or the paint does.
328static void check_for_up_and_down_text(const SkCanvas* canvas, const SkPaint& paint) {
329 bool paintHasVertical = paint.isVerticalText();
330 const SkMatrix& matrix = canvas->getTotalMatrix();
331 bool matrixIsVertical = matrix.preservesRightAngles() && !matrix.isScaleTranslate();
332 SkDebugf("paint draws text %s\n", paintHasVertical != matrixIsVertical ?
333 "top to bottom" : "left to right");
334}
335
336static void check_for_up_and_down_text(const SkPaint& paint) {
337 SkCanvas canvas; // placeholder only, does not have an associated device
338 check_for_up_and_down_text(&canvas, paint);
339}
340
Cary Clark8032b982017-07-28 11:04:54 -0400341##
Cary Clarkbad5ad72017-08-03 17:14:08 -0400342void draw(SkCanvas* canvas) {
343 SkPaint paint;
344 check_for_up_and_down_text(paint); // paint draws text left to right
345 paint.setVerticalText(true);
346 check_for_up_and_down_text(paint); // paint draws text top to bottom
347 paint.setVerticalText(false);
348 canvas->rotate(90);
349 check_for_up_and_down_text(canvas, paint); // paint draws text top to bottom
350}
Cary Clark8032b982017-07-28 11:04:54 -0400351
352 #StdOut
353 paint draws text left to right
354 paint draws text top to bottom
355 paint draws text top to bottom
356 ##
357##
358
359#ToDo incomplete ##
360
361##
362
363# ------------------------------------------------------------------------------
364
365#Method SkCanvas(int width, int height, const SkSurfaceProps* props = NULL)
366
367Creates Canvas of the specified dimensions without a Surface.
368Used by subclasses with custom implementations for draw methods.
369
Cary Clarkbad5ad72017-08-03 17:14:08 -0400370If props equals nullptr, Surface_Properties are created with Surface_Properties_Legacy_Font_Host settings,
371which choose the pixel striping direction and order. Since a platform may dynamically
372change its direction when the device is rotated, and since a platform may have
373multiple monitors with different characteristics, it's best not to rely on this
374legacy behavior.
Cary Clark8032b982017-07-28 11:04:54 -0400375
Cary Clarkbad5ad72017-08-03 17:14:08 -0400376#Param width zero or greater ##
377#Param height zero or greater ##
378#Param props LCD striping orientation and setting for device independent fonts;
379 may be nullptr
380##
381
382#Return Canvas placeholder with dimensions ##
Cary Clark8032b982017-07-28 11:04:54 -0400383
384#Example
385 SkCanvas canvas(10, 20); // 10 units wide, 20 units high
386 canvas.clipRect(SkRect::MakeXYWH(30, 40, 5, 10)); // clip is outside canvas' device
387 SkDebugf("canvas %s empty\n", canvas.getDeviceClipBounds().isEmpty() ? "is" : "is not");
388
389 #StdOut
390 canvas is empty
391 ##
392##
393
Cary Clarkbad5ad72017-08-03 17:14:08 -0400394#SeeAlso SkSurfaceProps SkPixelGeometry
Cary Clark8032b982017-07-28 11:04:54 -0400395
396##
397
398# ------------------------------------------------------------------------------
399
400#Method explicit SkCanvas(SkBaseDevice* device)
401
402Construct a canvas that draws into device.
403Used by child classes of SkCanvas.
404
405#ToDo Since SkBaseDevice is private, shouldn't this be private also? ##
406
Cary Clarkbad5ad72017-08-03 17:14:08 -0400407#Param device specifies a device for the canvas to draw into ##
Cary Clark8032b982017-07-28 11:04:54 -0400408
Cary Clarkbad5ad72017-08-03 17:14:08 -0400409#Return Canvas that can be used to draw into device ##
Cary Clark8032b982017-07-28 11:04:54 -0400410
411#Example
412#Error "Unsure how to create a meaningful example."
413 SkPDFCanvas::SkPDFCanvas(const sk_sp<SkPDFDevice>& dev)
414 : SkCanvas(dev.get()) {}
415##
416
417#ToDo either remove doc of figure out a way to fiddle it ##
418
419##
420
421# ------------------------------------------------------------------------------
422
423#Method explicit SkCanvas(const SkBitmap& bitmap)
424
425Construct a canvas that draws into bitmap.
426Sets SkSurfaceProps::kLegacyFontHost_InitType in constructed Surface.
427
Cary Clarkbad5ad72017-08-03 17:14:08 -0400428Bitmap is copied so that subsequently editing bitmap will not affect
429constructed Canvas.
430
431May be deprecated in the future.
432
Cary Clark8032b982017-07-28 11:04:54 -0400433#ToDo Should be deprecated? ##
434
Cary Clarkbad5ad72017-08-03 17:14:08 -0400435#Param bitmap width, height, Image_Color_Type, Image_Alpha_Type, and pixel
436 storage of Raster_Surface
Cary Clark8032b982017-07-28 11:04:54 -0400437##
438
Cary Clarkbad5ad72017-08-03 17:14:08 -0400439#Return Canvas that can be used to draw into bitmap ##
Cary Clark8032b982017-07-28 11:04:54 -0400440
441#Example
442#Description
443The actual output depends on the installed fonts.
444##
445 SkBitmap bitmap;
446 // create a bitmap 5 wide and 11 high
447 bitmap.allocPixels(SkImageInfo::MakeN32Premul(5, 11));
448 SkCanvas canvas(bitmap);
449 canvas.clear(SK_ColorWHITE); // white is unpremultiplied, in ARGB order
450 SkPixmap pixmap; // provides guaranteed access to the drawn pixels
451 if (!canvas.peekPixels(&pixmap)) {
452 SkDebugf("peekPixels should never fail.\n");
453 }
454 const SkPMColor* pixels = pixmap.addr32(); // points to top left of bitmap
455 SkPMColor pmWhite = pixels[0]; // the premultiplied format may vary
456 SkPaint paint; // by default, draws black, 12 point text
457 canvas.drawString("!", 1, 10, paint); // 1 char at baseline (1, 10)
458 for (int y = 0; y < bitmap.height(); ++y) {
459 for (int x = 0; x < bitmap.width(); ++x) {
460 SkDebugf("%c", *pixels++ == pmWhite ? '-' : 'x');
461 }
462 SkDebugf("\n");
463 }
464
465 #StdOut
466 -----
467 --x--
468 --x--
469 --x--
470 --x--
471 --x--
472 --x--
473 -----
474 --x--
475 --x--
476 -----
477 #StdOut ##
478##
479
480#ToDo incomplete ##
481
482##
483
Cary Clarkbad5ad72017-08-03 17:14:08 -0400484#EnumClass ColorBehavior
Cary Clark8032b982017-07-28 11:04:54 -0400485
486#Private
487Android framework only.
488##
489
490#Code
491 enum class ColorBehavior {
492 kLegacy,
493 };
494##
495#Const kLegacy 0
Cary Clarkbad5ad72017-08-03 17:14:08 -0400496 Is a placeholder to allow specialized constructor; has no meaning.
Cary Clark8032b982017-07-28 11:04:54 -0400497##
498##
499
Cary Clarkbad5ad72017-08-03 17:14:08 -0400500#Method SkCanvas(const SkBitmap& bitmap, ColorBehavior behavior)
501
502#Private
503Android framework only.
504##
505
506#Param bitmap specifies a bitmap for the canvas to draw into ##
507#Param behavior specializes this constructor; value is unused ##
508#Return Canvas that can be used to draw into bitmap ##
509
510#NoExample
511##
512##
Cary Clark8032b982017-07-28 11:04:54 -0400513
514# ------------------------------------------------------------------------------
515
516#Method SkCanvas(const SkBitmap& bitmap, const SkSurfaceProps& props)
517
518Construct a canvas that draws into bitmap.
519Use props to match the device characteristics, like LCD striping.
520
Cary Clarkbad5ad72017-08-03 17:14:08 -0400521bitmap is copied so that subsequently editing bitmap will not affect
522constructed Canvas.
523
524#Param bitmap width, height, Image_Color_Type, Image_Alpha_Type,
525 and pixel storage of Raster_Surface
Cary Clark8032b982017-07-28 11:04:54 -0400526##
Cary Clarkbad5ad72017-08-03 17:14:08 -0400527#Param props order and orientation of RGB striping; and whether to use
528 device independent fonts
Cary Clark8032b982017-07-28 11:04:54 -0400529##
530
Cary Clarkbad5ad72017-08-03 17:14:08 -0400531#Return Canvas that can be used to draw into bitmap ##
Cary Clark8032b982017-07-28 11:04:54 -0400532
533#Example
534#Description
535The actual output depends on the installed fonts.
536##
537 SkBitmap bitmap;
538 // create a bitmap 5 wide and 11 high
539 bitmap.allocPixels(SkImageInfo::MakeN32Premul(5, 11));
540 SkCanvas canvas(bitmap, SkSurfaceProps(0, kUnknown_SkPixelGeometry));
541 canvas.clear(SK_ColorWHITE); // white is unpremultiplied, in ARGB order
542 SkPixmap pixmap; // provides guaranteed access to the drawn pixels
543 if (!canvas.peekPixels(&pixmap)) {
544 SkDebugf("peekPixels should never fail.\n");
545 }
546 const SkPMColor* pixels = pixmap.addr32(); // points to top left of bitmap
547 SkPMColor pmWhite = pixels[0]; // the premultiplied format may vary
548 SkPaint paint; // by default, draws black, 12 point text
549 canvas.drawString("!", 1, 10, paint); // 1 char at baseline (1, 10)
550 for (int y = 0; y < bitmap.height(); ++y) {
551 for (int x = 0; x < bitmap.width(); ++x) {
552 SkDebugf("%c", *pixels++ == pmWhite ? '-' : 'x');
553 }
554 SkDebugf("\n");
555 }
556
557 #StdOut
558 -----
559 ---x-
560 ---x-
561 ---x-
562 ---x-
563 ---x-
564 ---x-
565 -----
566 ---x-
567 ---x-
568 -----
569 #StdOut ##
570##
571
572#ToDo incomplete ##
573
574##
575
576# ------------------------------------------------------------------------------
577
578#Method virtual ~SkCanvas()
579
Cary Clarkbad5ad72017-08-03 17:14:08 -0400580Draw saved layers, if any.
Cary Clark8032b982017-07-28 11:04:54 -0400581Free up resources used by Canvas.
582
583#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -0400584#Description
585Canvas offscreen draws into bitmap. saveLayerAlpha sets up an additional
586drawing surface that blends with the bitmap. When offscreen goes out of
587scope, offscreen destructor is called. The saved layer is restored, drawing
588transparent letters.
589##
590void draw(SkCanvas* canvas) {
591 SkBitmap bitmap;
592 bitmap.allocPixels(SkImageInfo::MakeN32Premul(200, 200));
593 {
594 SkCanvas offscreen(bitmap);
595 SkPaint paint;
596 paint.setTextSize(100);
597 offscreen.drawString("ABC", 20, 160, paint);
598 SkRect layerBounds = SkRect::MakeXYWH(32, 32, 192, 192);
599 offscreen.saveLayerAlpha(&layerBounds, 128);
600 offscreen.clear(SK_ColorWHITE);
601 offscreen.drawString("DEF", 20, 160, paint);
602 }
603 canvas->drawBitmap(bitmap, 0, 0, nullptr);
604}
Cary Clark8032b982017-07-28 11:04:54 -0400605##
606
Cary Clarkbad5ad72017-08-03 17:14:08 -0400607#SeeAlso State_Stack
Cary Clark8032b982017-07-28 11:04:54 -0400608
609##
610
611# ------------------------------------------------------------------------------
612
613#Method SkMetaData& getMetaData()
614
615Associates additional data with the canvas.
616The storage is freed when Canvas is deleted.
617
Cary Clarkbad5ad72017-08-03 17:14:08 -0400618#Return storage that can be read from and written to ##
Cary Clark8032b982017-07-28 11:04:54 -0400619
620#Example
621 const char* kHelloMetaData = "HelloMetaData";
622 SkCanvas canvas;
623 SkMetaData& metaData = canvas.getMetaData();
624 SkDebugf("before: %s\n", metaData.findString(kHelloMetaData));
625 metaData.setString(kHelloMetaData, "Hello!");
626 SkDebugf("during: %s\n", metaData.findString(kHelloMetaData));
627 metaData.removeString(kHelloMetaData);
628 SkDebugf("after: %s\n", metaData.findString(kHelloMetaData));
629
630 #StdOut
631 before: (null)
632 during: Hello!
633 after: (null)
634 #StdOut ##
635##
636
637#ToDo incomplete ##
638
639##
640
641# ------------------------------------------------------------------------------
642
643#Method SkImageInfo imageInfo() const
644
645Returns Image_Info for Canvas. If Canvas is not associated with Raster_Surface or
Cary Clarkbad5ad72017-08-03 17:14:08 -0400646GPU_Surface, returned Image_Color_Type is set to kUnknown_SkColorType.
Cary Clark8032b982017-07-28 11:04:54 -0400647
Cary Clarkbad5ad72017-08-03 17:14:08 -0400648#Return dimensions and Image_Color_Type of Canvas ##
Cary Clark8032b982017-07-28 11:04:54 -0400649
650#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -0400651 SkCanvas emptyCanvas;
652 SkImageInfo canvasInfo = emptyCanvas.imageInfo();
653 SkImageInfo emptyInfo;
654 SkDebugf("emptyInfo %c= canvasInfo\n", emptyInfo == canvasInfo ? '=' : '!');
655
656 #StdOut
657 emptyInfo == canvasInfo
658 ##
Cary Clark8032b982017-07-28 11:04:54 -0400659##
660
661#ToDo incomplete ##
662
663##
664
665# ------------------------------------------------------------------------------
666
667#Method bool getProps(SkSurfaceProps* props) const
668
669If Canvas is associated with Raster_Surface or
670GPU_Surface, copies Surface_Properties and returns true. Otherwise,
671return false and leave props unchanged.
672
Cary Clarkbad5ad72017-08-03 17:14:08 -0400673#Param props storage for writable SkSurfaceProps ##
Cary Clark8032b982017-07-28 11:04:54 -0400674
Cary Clarkbad5ad72017-08-03 17:14:08 -0400675#Return true if Surface_Properties was copied ##
Cary Clark8032b982017-07-28 11:04:54 -0400676
677#ToDo This seems old style. Deprecate? ##
678
679#Example
680 SkBitmap bitmap;
681 SkCanvas canvas(bitmap, SkSurfaceProps(0, kRGB_V_SkPixelGeometry));
682 SkSurfaceProps surfaceProps(0, kUnknown_SkPixelGeometry);
683 SkDebugf("isRGB:%d\n", SkPixelGeometryIsRGB(surfaceProps.pixelGeometry()));
684 if (!canvas.getProps(&surfaceProps)) {
685 SkDebugf("getProps failed unexpectedly.\n");
686 }
687 SkDebugf("isRGB:%d\n", SkPixelGeometryIsRGB(surfaceProps.pixelGeometry()));
688
689 #StdOut
690 isRGB:0
691 isRGB:1
692 #StdOut ##
693##
694
695#ToDo incomplete ##
696
697##
698
699# ------------------------------------------------------------------------------
700
701#Method void flush()
702
703Triggers the immediate execution of all pending draw operations.
Cary Clarkbad5ad72017-08-03 17:14:08 -0400704If Canvas is associated with GPU_Surface, resolves all pending GPU operations.
Cary Clark8032b982017-07-28 11:04:54 -0400705
706#Example
707#Error "haven't thought of a useful example to put here"
708##
709
710#ToDo incomplete ##
711
712##
713
714# ------------------------------------------------------------------------------
715
716#Method virtual SkISize getBaseLayerSize() const
717
718Gets the size of the base or root layer in global canvas coordinates. The
719origin of the base layer is always (0,0). The current drawable area may be
720smaller (due to clipping or saveLayer).
721
Cary Clarkbad5ad72017-08-03 17:14:08 -0400722#Return integral width and height of base layer ##
Cary Clark8032b982017-07-28 11:04:54 -0400723
724#Example
725 SkBitmap bitmap;
726 bitmap.allocPixels(SkImageInfo::MakeN32Premul(20, 30));
727 SkCanvas canvas(bitmap, SkSurfaceProps(0, kUnknown_SkPixelGeometry));
728 canvas.clipRect(SkRect::MakeWH(10, 40));
729 SkIRect clipDeviceBounds = canvas.getDeviceClipBounds();
730 if (clipDeviceBounds.isEmpty()) {
731 SkDebugf("Empty clip bounds is unexpected!\n");
732 }
733 SkDebugf("clip=%d,%d\n", clipDeviceBounds.width(), clipDeviceBounds.height());
734 SkISize baseLayerSize = canvas.getBaseLayerSize();
735 SkDebugf("size=%d,%d\n", baseLayerSize.width(), baseLayerSize.height());
736
737 #StdOut
738 clip=10,30
739 size=20,30
740 ##
741##
742
743#ToDo is this the same as the width and height of surface? ##
744
745##
746
747# ------------------------------------------------------------------------------
748
749#Method sk_sp<SkSurface> makeSurface(const SkImageInfo& info, const SkSurfaceProps* props = nullptr)
750
751Creates Surface matching info and props, and associates it with Canvas.
Cary Clarkbad5ad72017-08-03 17:14:08 -0400752Returns nullptr if no match found.
Cary Clark8032b982017-07-28 11:04:54 -0400753
Cary Clarkbad5ad72017-08-03 17:14:08 -0400754If props is nullptr, matches Surface_Properties in Canvas. If props is nullptr and Canvas
755does not have Surface_Properties, creates Surface with default Surface_Properties.
Cary Clark8032b982017-07-28 11:04:54 -0400756
Cary Clarkbad5ad72017-08-03 17:14:08 -0400757#Param info width, height, Image_Color_Type, Image_Alpha_Type, and Color_Space ##
758#Param props Surface_Properties to match; may be nullptr to match Canvas ##
759
760#Return Surface matching info and props, or nullptr if no match is available ##
Cary Clark8032b982017-07-28 11:04:54 -0400761
762#Example
763 sk_sp<SkSurface> surface = SkSurface::MakeRasterN32Premul(5, 6);
764 SkCanvas* smallCanvas = surface->getCanvas();
765 SkImageInfo imageInfo = SkImageInfo::MakeN32Premul(3, 4);
766 sk_sp<SkSurface> compatible = smallCanvas->makeSurface(imageInfo);
767 SkDebugf("compatible %c= nullptr\n", compatible == nullptr ? '=' : '!');
768 SkDebugf("size = %d, %d\n", compatible->width(), compatible->height());
769
770 #StdOut
Cary Clarkbad5ad72017-08-03 17:14:08 -0400771 compatible != nullptr
Cary Clark8032b982017-07-28 11:04:54 -0400772 size = 3, 4
773 ##
774##
775
776#ToDo incomplete ##
777
778##
779
780# ------------------------------------------------------------------------------
781
782#Method virtual GrContext* getGrContext()
783
784Returns GPU_Context of the GPU_Surface associated with Canvas.
785
Cary Clarkbad5ad72017-08-03 17:14:08 -0400786#Return GPU_Context, if available; nullptr otherwise ##
Cary Clark8032b982017-07-28 11:04:54 -0400787
788#Example
789void draw(SkCanvas* canvas) {
790 if (canvas->getGrContext()) {
791 canvas->clear(SK_ColorRED);
792 } else {
793 canvas->clear(SK_ColorBLUE);
794 }
795}
796##
797
798#ToDo fiddle should show both CPU and GPU out ##
799
800##
801
802# ------------------------------------------------------------------------------
803
804#Method void* accessTopLayerPixels(SkImageInfo* info, size_t* rowBytes, SkIPoint* origin = NULL)
805
806Returns the pixel base address, Image_Info, rowBytes, and origin if the pixels
Cary Clarkbad5ad72017-08-03 17:14:08 -0400807can be read directly. The returned address is only valid
Cary Clark8032b982017-07-28 11:04:54 -0400808while Canvas is in scope and unchanged. Any Canvas call or Surface call
809may invalidate the returned address and other returned values.
810
811If pixels are inaccessible, info, rowBytes, and origin are unchanged.
812
Cary Clarkbad5ad72017-08-03 17:14:08 -0400813#Param info storage for writable pixels' Image_Info; may be nullptr ##
814#Param rowBytes storage for writable pixels' row bytes; may be nullptr ##
815#Param origin storage for Canvas top layer origin, its top left corner;
816 may be nullptr
817##
Cary Clark8032b982017-07-28 11:04:54 -0400818
Cary Clarkbad5ad72017-08-03 17:14:08 -0400819#Return Address of pixels, or nullptr if inaccessible ##
Cary Clark8032b982017-07-28 11:04:54 -0400820
821#Example
822void draw(SkCanvas* canvas) {
823 if (canvas->accessTopLayerPixels(nullptr, nullptr)) {
824 canvas->clear(SK_ColorRED);
825 } else {
826 canvas->clear(SK_ColorBLUE);
827 }
828}
829##
830
831#Example
832#Description
833Draws "ABC" on the device. Then draws "DEF" in an offscreen layer, and reads the
834offscreen to add a large dotted "DEF". Finally blends the offscreen with the
835device.
836
837The offscreen and blended result appear on the CPU and GPU but the large dotted
838"DEF" appear only on the CPU.
839##
840void draw(SkCanvas* canvas) {
Cary Clarkbad5ad72017-08-03 17:14:08 -0400841 SkPaint paint;
842 paint.setTextSize(100);
843 canvas->drawString("ABC", 20, 160, paint);
844 SkRect layerBounds = SkRect::MakeXYWH(32, 32, 192, 192);
845 canvas->saveLayerAlpha(&layerBounds, 128);
846 canvas->clear(SK_ColorWHITE);
847 canvas->drawString("DEF", 20, 160, paint);
848 SkImageInfo imageInfo;
849 size_t rowBytes;
850 SkIPoint origin;
851 uint32_t* access = (uint32_t*) canvas->accessTopLayerPixels(&imageInfo, &rowBytes, &origin);
852 if (access) {
853 int h = imageInfo.height();
854 int v = imageInfo.width();
855 int rowWords = rowBytes / sizeof(uint32_t);
856 for (int y = 0; y < h; ++y) {
857 int newY = (y - h / 2) * 2 + h / 2;
858 if (newY < 0 || newY >= h) {
859 continue;
860 }
861 for (int x = 0; x < v; ++x) {
862 int newX = (x - v / 2) * 2 + v / 2;
863 if (newX < 0 || newX >= v) {
864 continue;
865 }
866 if (access[y * rowWords + x] == SK_ColorBLACK) {
867 access[newY * rowWords + newX] = SK_ColorGRAY;
868 }
869 }
870 }
871
872 }
Cary Clark8032b982017-07-28 11:04:54 -0400873 canvas->restore();
874}
875##
876
877#ToDo there are no callers of this that I can find. Deprecate? ##
878#ToDo fiddle should show both CPU and GPU out ##
879
880##
881
882# ------------------------------------------------------------------------------
883
884#Method SkRasterHandleAllocator::Handle accessTopRasterHandle() const
885
886Returns custom context that tracks the Matrix and Clip.
887
888Use Raster_Handle_Allocator to blend Skia drawing with custom drawing, typically performed
Cary Clarkbad5ad72017-08-03 17:14:08 -0400889by the host platform's user interface. This accessor returns the custom context generated by
890SkRasterHandleAllocator::MakeCanvas, which creates a custom canvas with raster storage for
Cary Clark8032b982017-07-28 11:04:54 -0400891the drawing destination.
892
Cary Clarkbad5ad72017-08-03 17:14:08 -0400893#Return context of custom allocator ##
Cary Clark8032b982017-07-28 11:04:54 -0400894
895#Example
896#Description
897#ToDo ##
898##
899#Function
900 static void DeleteCallback(void*, void* context) {
901 delete (char*) context;
902 }
903
904 class CustomAllocator : public SkRasterHandleAllocator {
905 public:
906 bool allocHandle(const SkImageInfo& info, Rec* rec) override {
907 char* context = new char[4]{'s', 'k', 'i', 'a'};
908 rec->fReleaseProc = DeleteCallback;
909 rec->fReleaseCtx = context;
910 rec->fHandle = context;
911 rec->fPixels = context;
912 rec->fRowBytes = 4;
913 return true;
914 }
915
916 void updateHandle(Handle handle, const SkMatrix& ctm, const SkIRect& clip_bounds) override {
917 // apply canvas matrix and clip to custom environment
918 }
919 };
920
921##
922 void draw(SkCanvas* canvas) {
923 const SkImageInfo info = SkImageInfo::MakeN32Premul(1, 1);
924 std::unique_ptr<SkCanvas> c2 =
925 SkRasterHandleAllocator::MakeCanvas(std::unique_ptr<CustomAllocator>(
926 new CustomAllocator()), info);
927 char* context = (char*) c2->accessTopRasterHandle();
928 SkDebugf("context = %.4s\n", context);
929
930 }
931 #StdOut
932 context = skia
933 ##
934 #ToDo skstd::make_unique could not be used because def is private -- note to fix in c++14? ##
935##
936
937#SeeAlso SkRasterHandleAllocator
938
939##
940
941# ------------------------------------------------------------------------------
942
943#Method bool peekPixels(SkPixmap* pixmap)
944
945Returns true if Canvas has direct access to its pixels.
946
Cary Clarkbad5ad72017-08-03 17:14:08 -0400947Pixels are readable when Device is raster. Pixels are not readable when SkCanvas
948is returned from GPU_Surface, returned by SkDocument::beginPage, returned by
949SkPictureRecorder::beginRecording, or SkCanvas is the base of a utility class
950like SkDumpCanvas.
Cary Clark8032b982017-07-28 11:04:54 -0400951
Cary Clarkbad5ad72017-08-03 17:14:08 -0400952pixmap pixel address is only valid while Canvas is in scope and unchanged. Any
953Canvas or Surface call may invalidate the pixmap values.
Cary Clark8032b982017-07-28 11:04:54 -0400954
Cary Clarkbad5ad72017-08-03 17:14:08 -0400955#Param pixmap storage for Canvas pixel state if Canvas pixels are readable;
956 otherwise, ignored
957##
Cary Clark8032b982017-07-28 11:04:54 -0400958
Cary Clarkbad5ad72017-08-03 17:14:08 -0400959#Return true if Canvas has direct access to pixels ##
Cary Clark8032b982017-07-28 11:04:54 -0400960
961#Example
962 SkPixmap pixmap;
963 if (canvas->peekPixels(&pixmap)) {
964 SkDebugf("width=%d height=%d\n", pixmap.bounds().width(), pixmap.bounds().height());
965 }
966 #StdOut
967 width=256 height=256
968 ##
969##
970
971##
972
973# ------------------------------------------------------------------------------
974
975#Method bool readPixels(const SkImageInfo& dstInfo, void* dstPixels, size_t dstRowBytes,
976 int srcX, int srcY)
977
Cary Clarkbad5ad72017-08-03 17:14:08 -0400978Copies rectangle of pixels from Canvas into dstPixels, converting their
979Image_Color_Type and Image_Alpha_Type. Pixels are readable when Device is
980raster. Pixels are not readable when SkCanvas is returned from GPU_Surface,
981returned by SkDocument::beginPage, returned by SkPictureRecorder::beginRecording,
Cary Clark8032b982017-07-28 11:04:54 -0400982or SkCanvas is the base of a utility class like SkDumpCanvas.
983
Cary Clarkbad5ad72017-08-03 17:14:08 -0400984Pixel values are converted only if Canvas Image_Color_Type and Image_Alpha_Type
985does not match dstInfo. Only pixels within the rectangle that intersect Canvas
986pixels are copied. dstPixels outside the rectangle intersection are unchanged.
Cary Clark8032b982017-07-28 11:04:54 -0400987
988#Table
989#Legend
990# source rectangle # value ##
991##
992# left # srcX ##
993# top # srcY ##
994# width # dstInfo.width() ##
995# height # dstInfo.height() ##
996##
997
998 #Table
999#Legend
1000# canvas pixel bounds # value ##
1001##
1002# left # 0 ##
1003# top # 0 ##
1004# width # imageInfo().width() ##
1005# height # imageInfo().height() ##
1006##
1007
1008Does not copy, and returns false if:
1009
1010#List
1011# Source rectangle and canvas pixel bounds do not intersect. ##
1012# Canvas pixels could not be converted to dstInfo Image_Color_Type or dstInfo Image_Alpha_Type. ##
1013# Canvas pixels are not readable; for instance, Canvas is not raster, or is document-based. ##
1014# dstRowBytes is too small to contain one row of pixels. ##
1015##
1016
Cary Clarkbad5ad72017-08-03 17:14:08 -04001017#Param dstInfo dimensions, Image_Color_Type, and Image_Alpha_Type of dstPixels ##
1018#Param dstPixels storage for pixels, of size dstInfo.height() times dstRowBytes ##
1019#Param dstRowBytes size of one destination row, dstInfo.width() times pixel size ##
1020#Param srcX offset into readable pixels in x ##
1021#Param srcY offset into readable pixels in y ##
Cary Clark8032b982017-07-28 11:04:54 -04001022
Cary Clarkbad5ad72017-08-03 17:14:08 -04001023#Return true if pixels were copied ##
Cary Clark8032b982017-07-28 11:04:54 -04001024
1025#Example
1026#Description
1027 Canvas returned by Raster_Surface has premultiplied pixel values.
1028 clear() takes unpremultiplied input with Color_Alpha equal 0x80
1029 and Color_RGB equal 0x55, 0xAA, 0xFF. Color_RGB is multipled by Color_Alpha
1030 to generate premultipled value 0x802B5580. readPixels converts pixel back
1031 to unpremultipled value 0x8056A9FF, introducing error.
1032##
1033 canvas->clear(0x8055aaff);
1034 for (SkAlphaType alphaType : { kPremul_SkAlphaType, kUnpremul_SkAlphaType } ) {
1035 uint32_t pixel = 0;
1036 SkImageInfo info = SkImageInfo::Make(1, 1, kBGRA_8888_SkColorType, alphaType);
1037 if (canvas->readPixels(info, &pixel, 4, 0, 0)) {
1038 SkDebugf("pixel = %08x\n", pixel);
1039 }
1040 }
1041
1042 #StdOut
1043 pixel = 802b5580
1044 pixel = 8056a9ff
1045 ##
1046##
1047
1048#ToDo incomplete ##
1049
1050##
1051
1052# ------------------------------------------------------------------------------
1053
1054#Method bool readPixels(const SkPixmap& pixmap, int srcX, int srcY)
1055
Cary Clarkbad5ad72017-08-03 17:14:08 -04001056Copies rectangle of pixels from Canvas into Pixmap, converting their
1057Image_Color_Type and Image_Alpha_Type. Pixels are readable when Device is raster.
1058Pixels are not readable when SkCanvas is returned from GPU_Surface, returned by
1059SkDocument::beginPage, returned by SkPictureRecorder::beginRecording,
Cary Clark8032b982017-07-28 11:04:54 -04001060or SkCanvas is the base of a utility class like SkDumpCanvas.
1061
Cary Clarkbad5ad72017-08-03 17:14:08 -04001062Pixel values are converted only if Canvas Image_Color_Type and Image_Alpha_Type
1063does not match bitmap Image_Info. Only Pixmap pixels within the rectangle that
1064intersect Canvas pixels are copied. Pixmap pixels outside the rectangle
1065intersection are unchanged.
Cary Clark8032b982017-07-28 11:04:54 -04001066
1067#Table
1068#Legend
1069# source rectangle # value ##
1070##
1071# left # srcX ##
1072# top # srcY ##
1073# width # bitmap.width() ##
1074# height # bitmap.height() ##
1075##
1076
1077 #Table
1078#Legend
1079# canvas pixel bounds # value ##
1080##
1081# left # 0 ##
1082# top # 0 ##
1083# width # imageInfo().width() ##
1084# height # imageInfo().height() ##
1085##
1086
1087Does not copy, and returns false if:
1088
1089#List
1090# Source rectangle and canvas pixel bounds do not intersect. ##
1091# Canvas pixels could not be converted to bitmap Image_Color_Type or bitmap Image_Alpha_Type. ##
1092# Canvas pixels are not readable; for instance, Canvas is not raster, or is document-based. ##
1093# bitmap pixels could not be allocated. ##
1094# Bitmap_Row_Bytes is too small to contain one row of pixels. ##
1095##
1096
Cary Clarkbad5ad72017-08-03 17:14:08 -04001097#Param pixmap storage for pixels copied from Canvas ##
1098#Param srcX offset into readable pixels in x ##
1099#Param srcY offset into readable pixels in y ##
Cary Clark8032b982017-07-28 11:04:54 -04001100
Cary Clarkbad5ad72017-08-03 17:14:08 -04001101#Return true if pixels were copied ##
Cary Clark8032b982017-07-28 11:04:54 -04001102
1103#Example
1104void draw(SkCanvas* canvas) {
1105 canvas->clear(0x8055aaff);
1106 uint32_t pixels[1] = { 0 };
Cary Clarkbad5ad72017-08-03 17:14:08 -04001107 SkPixmap pixmap(SkImageInfo::MakeN32Premul(1, 1), pixels, 4);
Cary Clark8032b982017-07-28 11:04:54 -04001108 canvas->readPixels(pixmap, 0, 0);
1109 SkDebugf("pixel = %08x\n", pixels[0]);
1110}
1111 #StdOut
1112 pixel = 802b5580
1113 ##
1114##
1115
1116#ToDo incomplete ##
1117
1118##
1119
1120# ------------------------------------------------------------------------------
1121
1122#Method bool readPixels(const SkBitmap& bitmap, int srcX, int srcY)
1123
Cary Clarkbad5ad72017-08-03 17:14:08 -04001124Copies pixels enclosed by bitmap offset to (x, y) from Canvas into bitmap,
1125converting their Image_Color_Type and Image_Alpha_Type.
1126Pixels are readable when Device is raster. Pixels are not readable when SkCanvas
1127is returned from GPU_Surface, returned by SkDocument::beginPage, returned by
1128SkPictureRecorder::beginRecording, or SkCanvas is the base of a utility class
1129like SkDumpCanvas. Allocates pixel storage in bitmap if needed.
Cary Clark8032b982017-07-28 11:04:54 -04001130
Cary Clarkbad5ad72017-08-03 17:14:08 -04001131Pixel values are converted only if Canvas Image_Color_Type and Image_Alpha_Type
1132does not match bitmap Image_Info. Only pixels within the rectangle that intersect
1133Canvas pixels are copied. Bitamp pixels outside the rectangle intersection are
1134unchanged.
Cary Clark8032b982017-07-28 11:04:54 -04001135
Cary Clarkbad5ad72017-08-03 17:14:08 -04001136#Table
Cary Clark8032b982017-07-28 11:04:54 -04001137#Legend
1138# canvas pixel bounds # value ##
1139##
1140# left # 0 ##
1141# top # 0 ##
1142# width # imageInfo().width() ##
1143# height # imageInfo().height() ##
1144##
1145
1146Does not copy, and returns false if:
1147
1148#List
1149# Bounds formed by (x, y) and bitmap (width, height) and canvas pixel bounds do not intersect. ##
1150# Canvas pixels could not be converted to bitmap Image_Color_Type or bitmap Image_Alpha_Type. ##
1151# Canvas pixels are not readable; for instance, Canvas is not raster, or is document-based. ##
1152# bitmap pixels could not be allocated. ##
1153# Bitmap_Row_Bytes is too small to contain one row of pixels. ##
1154##
1155
Cary Clarkbad5ad72017-08-03 17:14:08 -04001156#Param bitmap storage for pixels copied from Canvas ##
1157#Param srcX offset into readable pixels in x ##
1158#Param srcY offset into readable pixels in y ##
Cary Clark8032b982017-07-28 11:04:54 -04001159
Cary Clarkbad5ad72017-08-03 17:14:08 -04001160#Return true if pixels were copied ##
Cary Clark8032b982017-07-28 11:04:54 -04001161
1162#Example
1163void draw(SkCanvas* canvas) {
1164 canvas->clear(0x8055aaff);
1165 SkBitmap bitmap;
1166 bitmap.allocPixels(SkImageInfo::MakeN32Premul(1, 1));
1167 canvas->readPixels(bitmap, 0, 0);
1168 SkDebugf("pixel = %08x\n", bitmap.getAddr32(0, 0)[0]);
1169}
1170 #StdOut
1171 pixel = 802b5580
1172 ##
1173##
1174
1175#ToDo incomplete ##
1176
1177##
1178
1179# ------------------------------------------------------------------------------
1180
1181#Method bool writePixels(const SkImageInfo& info, const void* pixels, size_t rowBytes, int x, int y)
1182
1183Copies to Canvas pixels, ignoring the Matrix and Clip, converting to match
1184info Image_Color_Type and info Image_Alpha_Type.
1185
Cary Clarkbad5ad72017-08-03 17:14:08 -04001186Pixel values are converted only if Canvas Image_Color_Type and Image_Alpha_Type
1187does not match info. Only pixels within the source rectangle that intersect
1188Canvas pixel bounds are copied. Canvas pixels outside the rectangle intersection
1189are unchanged.
Cary Clark8032b982017-07-28 11:04:54 -04001190
1191#Table
1192#Legend
1193# source rectangle # value ##
1194##
1195# left # x ##
1196# top # y ##
1197# width # info.width() ##
1198# height # info.height() ##
1199##
1200
1201 #Table
1202#Legend
1203# canvas pixel bounds # value ##
1204##
1205# left # 0 ##
1206# top # 0 ##
1207# width # imageInfo().width() ##
1208# height # imageInfo().height() ##
1209##
1210
1211Does not copy, and returns false if:
1212
1213#List
1214# Source rectangle and canvas pixel bounds do not intersect. ##
1215# pixels could not be converted to Canvas Image_Color_Type or Canvas Image_Alpha_Type. ##
1216# Canvas pixels are not writable; for instance, Canvas is document-based. ##
1217# rowBytes is too small to contain one row of pixels. ##
1218##
1219
Cary Clarkbad5ad72017-08-03 17:14:08 -04001220#Param info dimensions, Image_Color_Type, and Image_Alpha_Type of pixels ##
1221#Param pixels pixels to copy, of size info.height() times rowBytes ##
1222#Param rowBytes offset from one row to the next, usually info.width() times pixel size ##
1223#Param x offset into Canvas writable pixels in x ##
1224#Param y offset into Canvas writable pixels in y ##
Cary Clark8032b982017-07-28 11:04:54 -04001225
Cary Clarkbad5ad72017-08-03 17:14:08 -04001226#Return true if pixels were written to Canvas ##
Cary Clark8032b982017-07-28 11:04:54 -04001227
1228#Example
1229 SkImageInfo imageInfo = SkImageInfo::MakeN32(256, 1, kPremul_SkAlphaType);
1230 for (int y = 0; y < 256; ++y) {
1231 uint32_t pixels[256];
1232 for (int x = 0; x < 256; ++x) {
1233 pixels[x] = SkColorSetARGB(x, x + y, x, x - y);
1234 }
1235 canvas->writePixels(imageInfo, &pixels, sizeof(pixels), 0, y);
1236 }
1237##
1238
1239#ToDo incomplete ##
1240
1241##
1242
1243# ------------------------------------------------------------------------------
1244
1245#Method bool writePixels(const SkBitmap& bitmap, int x, int y)
1246
1247Writes to Canvas pixels, ignoring the Matrix and Clip, converting to match
1248bitmap Image_Color_Type and bitmap Image_Alpha_Type.
1249
Cary Clarkbad5ad72017-08-03 17:14:08 -04001250Pixel values are converted only if Canvas Image_Color_Type and Image_Alpha_Type
1251does not match bitmap. Only pixels within the source rectangle that intersect
1252Canvas pixel bounds are copied. Canvas pixels outside the rectangle intersection
1253are unchanged.
Cary Clark8032b982017-07-28 11:04:54 -04001254
1255#Table
1256#Legend
1257# source rectangle # value ##
1258##
1259# left # x ##
1260# top # y ##
1261# width # bitmap.width() ##
1262# height # bitmap.height() ##
1263##
1264
1265 #Table
1266#Legend
1267# canvas pixel bounds # value ##
1268##
1269# left # 0 ##
1270# top # 0 ##
1271# width # imageInfo().width() ##
1272# height # imageInfo().height() ##
1273##
1274
1275Does not copy, and returns false if:
1276
1277#List
1278# Source rectangle and Canvas pixel bounds do not intersect. ##
1279# bitmap does not have allocated pixels. ##
1280# bitmap pixels could not be converted to Canvas Image_Color_Type or Canvas Image_Alpha_Type. ##
1281# Canvas pixels are not writable; for instance, Canvas is document-based. ##
1282# bitmap pixels are inaccessible; for instance, bitmap wraps a texture. ##
1283##
1284
Cary Clarkbad5ad72017-08-03 17:14:08 -04001285#Param bitmap contains pixels copied to Canvas ##
1286#Param x offset into Canvas writable pixels in x ##
1287#Param y offset into Canvas writable pixels in y ##
Cary Clark8032b982017-07-28 11:04:54 -04001288
Cary Clarkbad5ad72017-08-03 17:14:08 -04001289#Return true if pixels were written to Canvas ##
Cary Clark8032b982017-07-28 11:04:54 -04001290
1291#Example
1292void draw(SkCanvas* canvas) {
1293 SkImageInfo imageInfo = SkImageInfo::MakeN32Premul(2, 2);
1294 SkBitmap bitmap;
1295 bitmap.setInfo(imageInfo);
1296 uint32_t pixels[4];
1297 bitmap.setPixels(pixels);
1298 for (int y = 0; y < 256; y += 2) {
1299 for (int x = 0; x < 256; x += 2) {
1300 pixels[0] = SkColorSetRGB(x, y, x | y);
1301 pixels[1] = SkColorSetRGB(x ^ y, y, x);
1302 pixels[2] = SkColorSetRGB(x, x & y, y);
1303 pixels[3] = SkColorSetRGB(~x, ~y, x);
1304 canvas->writePixels(bitmap, x, y);
1305 }
1306 }
1307}
1308##
1309
1310#ToDo incomplete ##
1311
1312##
1313
1314# ------------------------------------------------------------------------------
1315#Topic State_Stack
1316
1317Canvas maintains a stack of state that allows hierarchical drawing, commonly used
Cary Clarkbad5ad72017-08-03 17:14:08 -04001318to implement windows and views. The initial state has an identity matrix and and
1319an infinite clip. Even with a wide-open clip, drawing is constrained by the
1320bounds of the Canvas Surface or Device.
Cary Clark8032b982017-07-28 11:04:54 -04001321
1322Canvas savable state consists of Clip, Matrix, and Draw_Filter.
1323Clip describes the area that may be drawn to.
1324Matrix transforms the geometry.
1325Draw_Filter (deprecated on most platforms) modifies the paint before drawing.
1326
1327save(), saveLayer, saveLayerPreserveLCDTextRequests, and saveLayerAlpha
1328save state and return the depth of the stack.
1329
Cary Clarkbad5ad72017-08-03 17:14:08 -04001330restore(), restoreToCount, and ~SkCanvas() revert state to its value when saved.
Cary Clark8032b982017-07-28 11:04:54 -04001331
1332Each state on the stack intersects Clip with the previous Clip,
1333and concatenates Matrix with the previous Matrix.
1334The intersected Clip makes the drawing area the same or smaller;
1335the concatenated Matrix may move the origin and potentially scale or rotate
1336the coordinate space.
1337
1338Canvas does not require balancing the state stack but it is a good idea
1339to do so. Calling save() without restore() will eventually cause Skia to fail;
1340mismatched save() and restore() create hard to find bugs.
1341
1342It is not possible to use state to draw outside of the clip defined by the
1343previous state.
1344
1345#Example
1346#Description
1347Draw to ever smaller clips; then restore drawing to full canvas.
1348Note that the second clipRect is not permitted to enlarge Clip.
1349##
1350#Height 160
Cary Clarkbad5ad72017-08-03 17:14:08 -04001351void draw(SkCanvas* canvas) {
1352 SkPaint paint;
1353 canvas->save(); // records stack depth to restore
1354 canvas->clipRect(SkRect::MakeWH(100, 100)); // constrains drawing to clip
1355 canvas->clear(SK_ColorRED); // draws to limit of clip
1356 canvas->save(); // records stack depth to restore
1357 canvas->clipRect(SkRect::MakeWH(50, 150)); // Rect below 100 is ignored
1358 canvas->clear(SK_ColorBLUE); // draws to smaller clip
1359 canvas->restore(); // enlarges clip
1360 canvas->drawLine(20, 20, 150, 150, paint); // line below 100 is not drawn
1361 canvas->restore(); // enlarges clip
1362 canvas->drawLine(150, 20, 50, 120, paint); // line below 100 is drawn
Cary Clark8032b982017-07-28 11:04:54 -04001363}
1364##
1365
1366Each Clip uses the current Matrix for its coordinates.
1367
1368#Example
1369#Description
1370While clipRect is given the same rectangle twice, Matrix makes the second
1371clipRect draw at half the size of the first.
1372##
1373#Height 128
Cary Clarkbad5ad72017-08-03 17:14:08 -04001374void draw(SkCanvas* canvas) {
1375 canvas->clipRect(SkRect::MakeWH(100, 100));
1376 canvas->clear(SK_ColorRED);
1377 canvas->scale(.5, .5);
1378 canvas->clipRect(SkRect::MakeWH(100, 100));
1379 canvas->clear(SK_ColorBLUE);
Cary Clark8032b982017-07-28 11:04:54 -04001380}
1381##
1382
1383#SeeAlso save() saveLayer saveLayerPreserveLCDTextRequests saveLayerAlpha restore() restoreToCount
1384
1385#Method int save()
1386
1387Saves Matrix, Clip, and Draw_Filter (Draw_Filter deprecated on most platforms).
1388Calling restore() discards changes to Matrix, Clip, and Draw_Filter,
1389restoring the Matrix, Clip, and Draw_Filter to their state when save() was called.
1390
Cary Clarkbad5ad72017-08-03 17:14:08 -04001391Matrix may be changed by translate(), scale(), rotate(), skew(), concat(), setMatrix,
1392and resetMatrix. Clip may be changed by clipRect, clipRRect, clipPath, clipRegion.
Cary Clark8032b982017-07-28 11:04:54 -04001393
Cary Clarkbad5ad72017-08-03 17:14:08 -04001394Saved Canvas state is put on a stack; multiple calls to save() should be balance
1395by an equal number of calls to restore().
Cary Clark8032b982017-07-28 11:04:54 -04001396
1397Call restoreToCount with result to restore this and subsequent saves.
1398
Cary Clarkbad5ad72017-08-03 17:14:08 -04001399#Return depth of saved stack ##
Cary Clark8032b982017-07-28 11:04:54 -04001400
1401#Example
1402#Description
1403The black square is translated 50 pixels down and to the right.
1404Restoring Canvas state removes translate() from Canvas stack;
1405the red square is not translated, and is drawn at the origin.
1406##
1407#Height 100
1408void draw(SkCanvas* canvas) {
1409 SkPaint paint;
1410 SkRect rect = { 0, 0, 25, 25 };
1411 canvas->drawRect(rect, paint);
1412 canvas->save();
1413 canvas->translate(50, 50);
1414 canvas->drawRect(rect, paint);
1415 canvas->restore();
1416 paint.setColor(SK_ColorRED);
1417 canvas->drawRect(rect, paint);
1418}
1419##
1420
1421#ToDo incomplete ##
1422
1423##
1424
1425# ------------------------------------------------------------------------------
1426#Subtopic Layer
1427
Cary Clarkbad5ad72017-08-03 17:14:08 -04001428Layer allocates a temporary offscreen Bitmap to draw into. When the drawing is
1429complete, the Bitmap is drawn into the Canvas.
Cary Clark8032b982017-07-28 11:04:54 -04001430
1431Layer is saved in a stack along with other saved state. When state with a Layer
1432is restored, the offscreen Bitmap is drawn into the previous layer.
1433
1434Layer may be initialized with the contents of the previous layer. When Layer is
Cary Clarkbad5ad72017-08-03 17:14:08 -04001435restored, its Bitmap can be modified by Paint passed to Layer to apply
1436Color_Alpha, Color_Filter, Image_Filter, and Blend_Mode.
Cary Clark8032b982017-07-28 11:04:54 -04001437
1438#Method int saveLayer(const SkRect* bounds, const SkPaint* paint)
1439
1440Saves Matrix, Clip, and Draw_Filter (Draw_Filter deprecated on most platforms),
1441and allocates an offscreen Bitmap for subsequent drawing.
1442Calling restore() discards changes to Matrix, Clip, and Draw_Filter,
1443and draws the offscreen bitmap.
Cary Clark8032b982017-07-28 11:04:54 -04001444
Cary Clarkbad5ad72017-08-03 17:14:08 -04001445Matrix may be changed by translate(), scale(), rotate(), skew(), concat(),
1446setMatrix, and resetMatrix. Clip may be changed by clipRect, clipRRect,
1447clipPath, clipRegion.
Cary Clark8032b982017-07-28 11:04:54 -04001448
Cary Clarkbad5ad72017-08-03 17:14:08 -04001449Rect bounds suggests but does not define the offscreen size. To clip drawing to
1450a specific rectangle, use clipRect.
Cary Clark8032b982017-07-28 11:04:54 -04001451
Cary Clarkbad5ad72017-08-03 17:14:08 -04001452Optional Paint paint applies Color_Alpha, Color_Filter, Image_Filter, and
1453Blend_Mode when restore() is called.
Cary Clark8032b982017-07-28 11:04:54 -04001454
Cary Clarkbad5ad72017-08-03 17:14:08 -04001455Call restoreToCount with returned value to restore this and subsequent saves.
Cary Clark8032b982017-07-28 11:04:54 -04001456
Cary Clarkbad5ad72017-08-03 17:14:08 -04001457#Param bounds hint to limit the size of the offscreen; may be nullptr ##
1458#Param paint graphics state for offscreen; may be nullptr ##
Cary Clark8032b982017-07-28 11:04:54 -04001459
Cary Clarkbad5ad72017-08-03 17:14:08 -04001460#Return depth of saved stack ##
Cary Clark8032b982017-07-28 11:04:54 -04001461
1462#Example
1463#Description
Cary Clarkbad5ad72017-08-03 17:14:08 -04001464Rectangles are blurred by Image_Filter when restore() draws offscreen to main
1465Canvas.
Cary Clark8032b982017-07-28 11:04:54 -04001466##
1467#Height 128
1468void draw(SkCanvas* canvas) {
1469 SkPaint paint, blur;
1470 blur.setImageFilter(SkImageFilter::MakeBlur(3, 3, nullptr));
1471 canvas->saveLayer(nullptr, &blur);
1472 SkRect rect = { 25, 25, 50, 50};
1473 canvas->drawRect(rect, paint);
1474 canvas->translate(50, 50);
1475 paint.setColor(SK_ColorRED);
1476 canvas->drawRect(rect, paint);
1477 canvas->restore();
1478}
1479##
1480
1481#ToDo incomplete ##
1482
1483##
1484
1485#Method int saveLayer(const SkRect& bounds, const SkPaint* paint)
1486
1487Saves Matrix, Clip, and Draw_Filter (Draw_Filter deprecated on most platforms),
1488and allocates an offscreen Bitmap for subsequent drawing.
1489Calling restore() discards changes to Matrix, Clip, and Draw_Filter,
1490and draws the offscreen Bitmap.
Cary Clark8032b982017-07-28 11:04:54 -04001491
Cary Clarkbad5ad72017-08-03 17:14:08 -04001492Matrix may be changed by translate(), scale(), rotate(), skew(), concat(),
1493setMatrix, and resetMatrix. Clip may be changed by clipRect, clipRRect,
1494clipPath, clipRegion.
Cary Clark8032b982017-07-28 11:04:54 -04001495
Cary Clarkbad5ad72017-08-03 17:14:08 -04001496Rect bounds suggests but does not define the offscreen size. To clip drawing to
1497a specific rectangle, use clipRect.
Cary Clark8032b982017-07-28 11:04:54 -04001498
Cary Clarkbad5ad72017-08-03 17:14:08 -04001499Optional Paint paint applies Color_Alpha, Color_Filter, Image_Filter, and
1500Blend_Mode when restore() is called.
Cary Clark8032b982017-07-28 11:04:54 -04001501
Cary Clarkbad5ad72017-08-03 17:14:08 -04001502Call restoreToCount with returned value to restore this and subsequent saves.
Cary Clark8032b982017-07-28 11:04:54 -04001503
Cary Clarkbad5ad72017-08-03 17:14:08 -04001504#Param bounds hint to limit the size of the offscreen; may be nullptr ##
1505#Param paint graphics state for offscreen; may be nullptr ##
Cary Clark8032b982017-07-28 11:04:54 -04001506
Cary Clarkbad5ad72017-08-03 17:14:08 -04001507#Return depth of saved stack ##
Cary Clark8032b982017-07-28 11:04:54 -04001508
1509#Example
1510#Description
1511Rectangles are blurred by Image_Filter when restore() draws offscreen to main Canvas.
1512The red rectangle is clipped; it does not fully fit on the offscreen Canvas.
1513Image_Filter blurs past edge of offscreen so red rectangle is blurred on all sides.
1514##
1515#Height 128
1516void draw(SkCanvas* canvas) {
1517 SkPaint paint, blur;
1518 blur.setImageFilter(SkImageFilter::MakeBlur(3, 3, nullptr));
1519 canvas->saveLayer(SkRect::MakeWH(90, 90), &blur);
1520 SkRect rect = { 25, 25, 50, 50};
1521 canvas->drawRect(rect, paint);
1522 canvas->translate(50, 50);
1523 paint.setColor(SK_ColorRED);
1524 canvas->drawRect(rect, paint);
1525 canvas->restore();
1526}
1527##
1528
1529#ToDo incomplete ##
1530
1531##
1532
1533#Method int saveLayerPreserveLCDTextRequests(const SkRect* bounds, const SkPaint* paint)
1534
1535Saves Matrix, Clip, and Draw_Filter (Draw_Filter deprecated on most platforms),
1536and allocates an offscreen bitmap for subsequent drawing.
1537LCD_Text is preserved when the offscreen is drawn to the prior layer.
1538
Cary Clark8032b982017-07-28 11:04:54 -04001539Calling restore() discards changes to Matrix, Clip, and Draw_Filter,
1540and draws the offscreen bitmap.
Cary Clark8032b982017-07-28 11:04:54 -04001541
Cary Clarkbad5ad72017-08-03 17:14:08 -04001542Matrix may be changed by translate(), scale(), rotate(), skew(), concat(),
1543setMatrix, and resetMatrix. Clip may be changed by clipRect, clipRRect,
1544clipPath, clipRegion.
Cary Clark8032b982017-07-28 11:04:54 -04001545
Cary Clarkbad5ad72017-08-03 17:14:08 -04001546Rect bounds suggests but does not define the offscreen size. To clip drawing to
1547a specific rectangle, use clipRect.
Cary Clark8032b982017-07-28 11:04:54 -04001548
Cary Clarkbad5ad72017-08-03 17:14:08 -04001549Optional Paint paint applies Color_Alpha, Color_Filter, Image_Filter, and
1550Blend_Mode when restore() is called.
Cary Clark8032b982017-07-28 11:04:54 -04001551
Cary Clarkbad5ad72017-08-03 17:14:08 -04001552Call restoreToCount with returned value to restore this and subsequent saves.
Cary Clark8032b982017-07-28 11:04:54 -04001553
Cary Clarkbad5ad72017-08-03 17:14:08 -04001554Draw text on an opaque background so that LCD_Text blends correctly with the
1555prior layer. LCD_Text drawn on a background with transparency may result in
1556incorrect banding.
Cary Clark8032b982017-07-28 11:04:54 -04001557
Cary Clarkbad5ad72017-08-03 17:14:08 -04001558#Param bounds hint to limit the size of the offscreen; may be nullptr ##
1559#Param paint graphics state for offscreen; may be nullptr ##
Cary Clark8032b982017-07-28 11:04:54 -04001560
Cary Clarkbad5ad72017-08-03 17:14:08 -04001561#Return depth of saved stack ##
Cary Clark8032b982017-07-28 11:04:54 -04001562
1563#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04001564 SkPaint paint;
1565 paint.setAntiAlias(true);
1566 paint.setLCDRenderText(true);
1567 paint.setTextSize(20);
1568 for (auto preserve : { false, true } ) {
1569 preserve ? canvas->saveLayerPreserveLCDTextRequests(nullptr, nullptr)
1570 : canvas->saveLayer(nullptr, nullptr);
1571 SkPaint p;
1572 p.setColor(SK_ColorWHITE);
1573 // Comment out the next line to draw on a non-opaque background.
1574 canvas->drawRect(SkRect::MakeLTRB(25, 40, 200, 70), p);
1575 canvas->drawString("Hamburgefons", 30, 60, paint);
1576
1577 p.setColor(0xFFCCCCCC);
1578 canvas->drawRect(SkRect::MakeLTRB(25, 70, 200, 100), p);
1579 canvas->drawString("Hamburgefons", 30, 90, paint);
1580
1581 canvas->restore();
1582 canvas->translate(0, 80);
Cary Clark8032b982017-07-28 11:04:54 -04001583 }
1584 ##
1585
1586#ToDo incomplete ##
1587
1588##
1589
1590#Method int saveLayerAlpha(const SkRect* bounds, U8CPU alpha)
1591
1592Saves Matrix, Clip, and Draw_Filter (Draw_Filter deprecated on most platforms),
1593and allocates an offscreen bitmap for subsequent drawing.
1594
1595Calling restore() discards changes to Matrix, Clip, and Draw_Filter,
1596and blends the offscreen bitmap with alpha opacity onto the prior layer.
Cary Clark8032b982017-07-28 11:04:54 -04001597
Cary Clarkbad5ad72017-08-03 17:14:08 -04001598Matrix may be changed by translate(), scale(), rotate(), skew(), concat(),
1599setMatrix, and resetMatrix. Clip may be changed by clipRect, clipRRect,
1600clipPath, clipRegion.
Cary Clark8032b982017-07-28 11:04:54 -04001601
Cary Clarkbad5ad72017-08-03 17:14:08 -04001602Rect bounds suggests but does not define the offscreen size. To clip drawing to
1603a specific rectangle, use clipRect.
Cary Clark8032b982017-07-28 11:04:54 -04001604
Cary Clarkbad5ad72017-08-03 17:14:08 -04001605alpha of zero is fully transparent, 255 is fully opaque.
Cary Clark8032b982017-07-28 11:04:54 -04001606
Cary Clarkbad5ad72017-08-03 17:14:08 -04001607Call restoreToCount with returned value to restore this and subsequent saves.
Cary Clark8032b982017-07-28 11:04:54 -04001608
Cary Clarkbad5ad72017-08-03 17:14:08 -04001609#Param bounds hint to limit the size of the offscreen; may be nullptr ##
1610#Param alpha opacity of the offscreen ##
1611
1612#Return depth of saved stack ##
Cary Clark8032b982017-07-28 11:04:54 -04001613
1614#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04001615 SkPaint paint;
1616 paint.setColor(SK_ColorRED);
1617 canvas->drawCircle(50, 50, 50, paint);
1618 canvas->saveLayerAlpha(nullptr, 128);
1619 paint.setColor(SK_ColorBLUE);
1620 canvas->drawCircle(100, 50, 50, paint);
1621 paint.setColor(SK_ColorGREEN);
1622 paint.setAlpha(128);
1623 canvas->drawCircle(75, 90, 50, paint);
Cary Clark8032b982017-07-28 11:04:54 -04001624 canvas->restore();
1625##
1626
1627#ToDo incomplete ##
1628
1629##
1630
Cary Clarkbad5ad72017-08-03 17:14:08 -04001631#Enum
Cary Clark8032b982017-07-28 11:04:54 -04001632
1633#Code
1634 enum {
1635 kIsOpaque_SaveLayerFlag = 1 << 0,
1636 kPreserveLCDText_SaveLayerFlag = 1 << 1,
1637 kInitWithPrevious_SaveLayerFlag = 1 << 2,
Cary Clarkbad5ad72017-08-03 17:14:08 -04001638 kDontClipToLayer_Legacy_SaveLayerFlag = kDontClipToLayer_PrivateSaveLayerFlag,
Cary Clark8032b982017-07-28 11:04:54 -04001639 };
1640
1641 typedef uint32_t SaveLayerFlags;
1642##
1643
1644SaveLayerFlags provides options that may be used in any combination in SaveLayerRec,
1645defining how the offscreen allocated by saveLayer operates.
1646
1647#Const kIsOpaque_SaveLayerFlag 1
1648 Creates offscreen without transparency. Flag is ignored if layer Paint contains
1649 Image_Filter or Color_Filter.
1650##
1651
1652#Const kPreserveLCDText_SaveLayerFlag 2
1653 Creates offscreen for LCD text. Flag is ignored if layer Paint contains
1654 Image_Filter or Color_Filter.
1655##
1656
1657#Const kInitWithPrevious_SaveLayerFlag 4
1658 Initializes offscreen with the contents of the previous layer.
1659##
1660
Cary Clarkbad5ad72017-08-03 17:14:08 -04001661#Const kDontClipToLayer_Legacy_SaveLayerFlag 0x80000000
1662#Private
1663 to be deprecated: bug.skia.org/2440
1664##
1665 Only present on Android.
1666 Skips setting a clip to the layer bounds.
1667##
1668
Cary Clark8032b982017-07-28 11:04:54 -04001669#Example
1670#Height 160
1671#Description
1672Canvas layer captures red and blue circles scaled up by four.
1673scalePaint blends offscreen back with transparency.
1674##
Cary Clarkbad5ad72017-08-03 17:14:08 -04001675void draw(SkCanvas* canvas) {
1676 SkPaint redPaint, bluePaint, scalePaint;
1677 redPaint.setColor(SK_ColorRED);
1678 canvas->drawCircle(21, 21, 8, redPaint);
1679 bluePaint.setColor(SK_ColorBLUE);
1680 canvas->drawCircle(31, 21, 8, bluePaint);
1681 SkMatrix matrix;
1682 matrix.setScale(4, 4);
1683 scalePaint.setAlpha(0x40);
1684 scalePaint.setImageFilter(
1685 SkImageFilter::MakeMatrixFilter(matrix, kNone_SkFilterQuality, nullptr));
1686 SkCanvas::SaveLayerRec saveLayerRec(nullptr, &scalePaint,
1687 SkCanvas::kInitWithPrevious_SaveLayerFlag);
1688 canvas->saveLayer(saveLayerRec);
1689 canvas->restore();
Cary Clark8032b982017-07-28 11:04:54 -04001690}
1691##
1692
1693#ToDo incomplete ##
1694
1695#Enum ##
1696
1697#Struct SaveLayerRec
1698
1699#Code
1700 struct SaveLayerRec {
1701 SaveLayerRec*(...
1702
1703 const SkRect* fBounds;
1704 const SkPaint* fPaint;
1705 const SkImageFilter* fBackdrop;
1706 SaveLayerFlags fSaveLayerFlags;
1707 };
1708##
1709
1710SaveLayerRec contains the state used to create the layer offscreen.
1711
1712#Member const SkRect* fBounds
1713 fBounds is used as a hint to limit the size of the offscreen; may be nullptr.
Cary Clarkbad5ad72017-08-03 17:14:08 -04001714 fBounds suggests but does not define the offscreen size. To clip drawing to
1715 a specific rectangle, use clipRect.
Cary Clark8032b982017-07-28 11:04:54 -04001716##
1717
1718#Member const SkPaint* fPaint
Cary Clarkbad5ad72017-08-03 17:14:08 -04001719 fPaint modifies how the offscreen overlays the prior layer; may be nullptr.
1720 Color_Alpha, Blend_Mode, Color_Filter, Draw_Looper, Image_Filter, and
1721 Mask_Filter affect the offscreen draw.
Cary Clark8032b982017-07-28 11:04:54 -04001722##
1723
1724#Member const SkImageFilter* fBackdrop
Cary Clarkbad5ad72017-08-03 17:14:08 -04001725 fBackdrop applies Image_Filter to the prior layer when copying to the layer
1726 offscreen; may be nullptr. Use kInitWithPrevious_SaveLayerFlag to copy the
1727 prior layer without an Image_Filter.
Cary Clark8032b982017-07-28 11:04:54 -04001728##
1729
1730#Member const SkImage* fClipMask
Cary Clarkbad5ad72017-08-03 17:14:08 -04001731 restore() clips the layer offscreen by the alpha channel of fClipMask when
1732 the offscreen is copied to Device. fClipMask may be nullptr. .
Cary Clark8032b982017-07-28 11:04:54 -04001733##
1734
1735#Member const SkMatrix* fClipMatrix
Cary Clarkbad5ad72017-08-03 17:14:08 -04001736 fClipMatrix transforms fClipMask before it clips the layer offscreen. If
1737 fClipMask describes a translucent gradient, it may be scaled and rotated
1738 without introducing artifacts. fClipMatrix may be nullptr.
Cary Clark8032b982017-07-28 11:04:54 -04001739##
1740
1741#Member SaveLayerFlags fSaveLayerFlags
Cary Clarkbad5ad72017-08-03 17:14:08 -04001742 fSaveLayerFlags are used to create layer offscreen without transparency,
1743 create layer offscreen for LCD text, and to create layer offscreen with the
1744 contents of the previous layer.
Cary Clark8032b982017-07-28 11:04:54 -04001745##
1746
1747#Example
1748#Height 160
1749#Description
Cary Clarkbad5ad72017-08-03 17:14:08 -04001750Canvas layer captures a red anti-aliased circle and a blue aliased circle scaled
1751up by four. After drawing another unscaled red circle on top, the offscreen is
1752transferred to the main canvas.
Cary Clark8032b982017-07-28 11:04:54 -04001753##
Cary Clarkbad5ad72017-08-03 17:14:08 -04001754void draw(SkCanvas* canvas) {
1755 SkPaint redPaint, bluePaint;
1756 redPaint.setAntiAlias(true);
1757 redPaint.setColor(SK_ColorRED);
1758 canvas->drawCircle(21, 21, 8, redPaint);
1759 bluePaint.setColor(SK_ColorBLUE);
1760 canvas->drawCircle(31, 21, 8, bluePaint);
1761 SkMatrix matrix;
1762 matrix.setScale(4, 4);
1763 auto scaler = SkImageFilter::MakeMatrixFilter(matrix, kNone_SkFilterQuality, nullptr);
1764 SkCanvas::SaveLayerRec saveLayerRec(nullptr, nullptr, scaler.get(), 0);
1765 canvas->saveLayer(saveLayerRec);
1766 canvas->drawCircle(125, 85, 8, redPaint);
1767 canvas->restore();
Cary Clark8032b982017-07-28 11:04:54 -04001768}
1769##
1770
1771#Method SaveLayerRec()
1772
1773Sets fBounds, fPaint, and fBackdrop to nullptr. Clears fSaveLayerFlags.
1774
Cary Clarkbad5ad72017-08-03 17:14:08 -04001775#Return empty SaveLayerRec ##
Cary Clark8032b982017-07-28 11:04:54 -04001776
1777#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04001778 SkCanvas::SaveLayerRec rec1;
1779 rec1.fSaveLayerFlags = SkCanvas::kIsOpaque_SaveLayerFlag;
1780 SkCanvas::SaveLayerRec rec2(nullptr, nullptr, SkCanvas::kIsOpaque_SaveLayerFlag);
1781 SkDebugf("rec1 %c= rec2\n", rec1.fBounds == rec2.fBounds
1782 && rec1.fPaint == rec2.fPaint
1783 && rec1.fBackdrop == rec2.fBackdrop
Cary Clark8032b982017-07-28 11:04:54 -04001784 && rec1.fSaveLayerFlags == rec2.fSaveLayerFlags ? '=' : '!');
1785 #StdOut
1786 rec1 == rec2
1787 ##
1788##
1789
1790##
1791
1792#Method SaveLayerRec(const SkRect* bounds, const SkPaint* paint, SaveLayerFlags saveLayerFlags = 0)
1793
1794Sets fBounds, fPaint, and fSaveLayerFlags; sets fBackdrop to nullptr.
1795
Cary Clarkbad5ad72017-08-03 17:14:08 -04001796#Param bounds offscreen dimensions; may be nullptr ##
1797#Param paint applied to offscreen when overlaying prior layer; may be nullptr ##
1798#Param saveLayerFlags SaveLayerRec options to modify offscreen ##
Cary Clark8032b982017-07-28 11:04:54 -04001799
Cary Clarkbad5ad72017-08-03 17:14:08 -04001800#Return SaveLayerRec with empty backdrop ##
Cary Clark8032b982017-07-28 11:04:54 -04001801
1802#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04001803 SkCanvas::SaveLayerRec rec1;
1804 SkCanvas::SaveLayerRec rec2(nullptr, nullptr);
1805 SkDebugf("rec1 %c= rec2\n", rec1.fBounds == rec2.fBounds
1806 && rec1.fPaint == rec2.fPaint
1807 && rec1.fBackdrop == rec2.fBackdrop
Cary Clark8032b982017-07-28 11:04:54 -04001808 && rec1.fSaveLayerFlags == rec2.fSaveLayerFlags ? '=' : '!');
1809 #StdOut
1810 rec1 == rec2
1811 ##
1812##
1813
1814##
1815
1816#Method SaveLayerRec(const SkRect* bounds, const SkPaint* paint, const SkImageFilter* backdrop,
1817 SaveLayerFlags saveLayerFlags)
1818
1819Sets fBounds, fPaint, fBackdrop, and fSaveLayerFlags.
1820
Cary Clarkbad5ad72017-08-03 17:14:08 -04001821#Param bounds offscreen dimensions; may be nullptr ##
1822#Param paint applied to offscreen when overlaying prior layer;
1823 may be nullptr
1824##
1825#Param backdrop prior layer copied to offscreen with Image_Filter;
1826 may be nullptr
1827##
1828#Param saveLayerFlags SaveLayerRec options to modify offscreen ##
Cary Clark8032b982017-07-28 11:04:54 -04001829
Cary Clarkbad5ad72017-08-03 17:14:08 -04001830#Return SaveLayerRec fully specified ##
Cary Clark8032b982017-07-28 11:04:54 -04001831
1832#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04001833 SkCanvas::SaveLayerRec rec1;
1834 SkCanvas::SaveLayerRec rec2(nullptr, nullptr, nullptr, 0);
1835 SkDebugf("rec1 %c= rec2\n", rec1.fBounds == rec2.fBounds
1836 && rec1.fPaint == rec2.fPaint
1837 && rec1.fBackdrop == rec2.fBackdrop
Cary Clark8032b982017-07-28 11:04:54 -04001838 && rec1.fSaveLayerFlags == rec2.fSaveLayerFlags ? '=' : '!');
1839 #StdOut
1840 rec1 == rec2
1841 ##
1842##
1843
1844##
1845
1846#Method SaveLayerRec(const SkRect* bounds, const SkPaint* paint, const SkImageFilter* backdrop,
1847 const SkImage* clipMask, const SkMatrix* clipMatrix,
1848 SaveLayerFlags saveLayerFlags)
1849
1850#Experimental
1851Not ready for general use.
1852##
1853
Cary Clarkbad5ad72017-08-03 17:14:08 -04001854Sets fBounds, fPaint, fBackdrop, fClipMask, fClipMatrix, and fSaveLayerFlags.
1855clipMatrix uses alpha channel of image, transformed by clipMatrix, to clip layer
1856when drawn to Canvas.
Cary Clark8032b982017-07-28 11:04:54 -04001857
Cary Clarkbad5ad72017-08-03 17:14:08 -04001858Implementation is incomplete; has no effect if Device is GPU-backed.
1859
1860#Param bounds offscreen dimensions; may be nullptr ##
1861#Param paint graphics state applied to offscreen when overlaying prior
1862 layer; may be nullptr
1863##
1864#Param backdrop prior layer copied to offscreen with Image_Filter;
1865 may be nullptr
1866##
1867#Param clipMask clip applied to layer; may be nullptr ##
1868#Param clipMatrix matrix applied to clipMask; may be nullptr to use
1869 identity matrix
1870##
1871#Param saveLayerFlags SaveLayerRec options to modify offscreen ##
1872
1873#Return SaveLayerRec fully specified ##
Cary Clark8032b982017-07-28 11:04:54 -04001874
1875#ToDo incomplete ##
1876
1877##
1878
1879#Struct ##
1880
1881#Method int saveLayer(const SaveLayerRec& layerRec)
1882
1883Saves Matrix, Clip, and Draw_Filter (Draw_Filter deprecated on most platforms),
1884and allocates an offscreen bitmap for subsequent drawing.
1885
1886Calling restore() discards changes to Matrix, Clip, and Draw_Filter,
1887and blends the offscreen bitmap with alpha opacity onto the prior layer.
Cary Clark8032b982017-07-28 11:04:54 -04001888
Cary Clarkbad5ad72017-08-03 17:14:08 -04001889Matrix may be changed by translate(), scale(), rotate(), skew(), concat(),
1890setMatrix, and resetMatrix. Clip may be changed by clipRect, clipRRect,
1891clipPath, clipRegion.
Cary Clark8032b982017-07-28 11:04:54 -04001892
1893SaveLayerRec contains the state used to create the layer offscreen.
1894
Cary Clarkbad5ad72017-08-03 17:14:08 -04001895Call restoreToCount with returned value to restore this and subsequent saves.
Cary Clark8032b982017-07-28 11:04:54 -04001896
Cary Clarkbad5ad72017-08-03 17:14:08 -04001897#Param layerRec offscreen state ##
Cary Clark8032b982017-07-28 11:04:54 -04001898
Cary Clarkbad5ad72017-08-03 17:14:08 -04001899#Return depth of save state stack ##
Cary Clark8032b982017-07-28 11:04:54 -04001900
1901#Example
1902#Description
1903The example draws an image, and saves it into a layer with kInitWithPrevious_SaveLayerFlag.
1904Next it punches a hole in the layer and restore with SkBlendMode::kPlus.
1905Where the layer was cleared, the original image will draw unchanged.
1906Outside of the circle the mandrill is brightened.
1907##
1908 #Image 3
1909 // sk_sp<SkImage> image = GetResourceAsImage("mandrill_256.png");
1910 canvas->drawImage(image, 0, 0, nullptr);
1911 SkCanvas::SaveLayerRec rec;
1912 SkPaint paint;
1913 paint.setBlendMode(SkBlendMode::kPlus);
1914 rec.fSaveLayerFlags = SkCanvas::kInitWithPrevious_SaveLayerFlag;
1915 rec.fPaint = &paint;
1916 canvas->saveLayer(rec);
1917 paint.setBlendMode(SkBlendMode::kClear);
1918 canvas->drawCircle(128, 128, 96, paint);
1919 canvas->restore();
1920##
1921
1922#ToDo above example needs to replace GetResourceAsImage with way to select image in fiddle ##
1923
1924##
1925
1926#Subtopic Layer ##
1927
1928# ------------------------------------------------------------------------------
1929
1930#Method void restore()
1931
1932Removes changes to Matrix, Clip, and Draw_Filter since Canvas state was
1933last saved. The state is removed from the stack.
1934
1935Does nothing if the stack is empty.
1936
1937#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04001938void draw(SkCanvas* canvas) {
1939 SkCanvas simple;
1940 SkDebugf("depth = %d\n", simple.getSaveCount());
1941 simple.restore();
1942 SkDebugf("depth = %d\n", simple.getSaveCount());
Cary Clark8032b982017-07-28 11:04:54 -04001943}
1944##
1945
1946##
1947
1948# ------------------------------------------------------------------------------
1949
1950#Method int getSaveCount() const
1951
1952Returns the number of saved states, each containing: Matrix, Clip, and Draw_Filter.
1953Equals the number of save() calls less the number of restore() calls plus one.
1954The save count of a new canvas is one.
1955
Cary Clarkbad5ad72017-08-03 17:14:08 -04001956#Return depth of save state stack ##
Cary Clark8032b982017-07-28 11:04:54 -04001957
1958#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04001959void draw(SkCanvas* canvas) {
1960 SkCanvas simple;
1961 SkDebugf("depth = %d\n", simple.getSaveCount());
1962 simple.save();
1963 SkDebugf("depth = %d\n", simple.getSaveCount());
1964 simple.restore();
1965 SkDebugf("depth = %d\n", simple.getSaveCount());
Cary Clark8032b982017-07-28 11:04:54 -04001966}
1967#StdOut
Cary Clarkbad5ad72017-08-03 17:14:08 -04001968depth = 1
1969depth = 2
Cary Clark8032b982017-07-28 11:04:54 -04001970depth = 1
1971##
1972##
1973
1974##
1975
1976# ------------------------------------------------------------------------------
1977
1978#Method void restoreToCount(int saveCount)
1979
Cary Clarkbad5ad72017-08-03 17:14:08 -04001980Restores state to Matrix, Clip, and Draw_Filter values when save(), saveLayer,
1981saveLayerPreserveLCDTextRequests, or saveLayerAlpha returned saveCount.
Cary Clark8032b982017-07-28 11:04:54 -04001982
1983Does nothing if saveCount is greater than state stack count.
1984Restores state to initial values if saveCount is less than or equal to one.
1985
Cary Clarkbad5ad72017-08-03 17:14:08 -04001986#Param saveCount depth of state stack to restore ##
Cary Clark8032b982017-07-28 11:04:54 -04001987
1988#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04001989void draw(SkCanvas* canvas) {
1990 SkDebugf("depth = %d\n", canvas->getSaveCount());
1991 canvas->save();
1992 canvas->save();
1993 SkDebugf("depth = %d\n", canvas->getSaveCount());
1994 canvas->restoreToCount(0);
1995 SkDebugf("depth = %d\n", canvas->getSaveCount());
Cary Clark8032b982017-07-28 11:04:54 -04001996}
1997#StdOut
Cary Clarkbad5ad72017-08-03 17:14:08 -04001998depth = 1
1999depth = 3
Cary Clark8032b982017-07-28 11:04:54 -04002000depth = 1
2001##
2002##
2003
2004##
2005
2006#Topic State_Stack ##
2007
2008# ------------------------------------------------------------------------------
2009#Topic Matrix
2010
2011#Method void translate(SkScalar dx, SkScalar dy)
2012
2013Translate Matrix by dx along the x-axis and dy along the y-axis.
2014
2015Mathematically, replace Matrix with a translation matrix
2016pre-multiplied with Matrix.
2017
2018This has the effect of moving the drawing by (dx, dy) before transforming
2019the result with Matrix.
2020
Cary Clarkbad5ad72017-08-03 17:14:08 -04002021#Param dx distance to translate in x ##
2022#Param dy distance to translate in y ##
Cary Clark8032b982017-07-28 11:04:54 -04002023
2024#Example
2025#Height 128
2026#Description
2027scale() followed by translate() produces different results from translate() followed
2028by scale().
2029
2030The blue stroke follows translate of (50, 50); a black
2031fill follows scale of (2, 1/2.f). After restoring the clip, which resets
2032Matrix, a red frame follows the same scale of (2, 1/2.f); a gray fill
2033follows translate of (50, 50).
2034##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002035void draw(SkCanvas* canvas) {
2036 SkPaint filledPaint;
2037 SkPaint outlinePaint;
2038 outlinePaint.setStyle(SkPaint::kStroke_Style);
2039 outlinePaint.setColor(SK_ColorBLUE);
2040 canvas->save();
2041 canvas->translate(50, 50);
2042 canvas->drawCircle(28, 28, 15, outlinePaint); // blue center: (50+28, 50+28)
2043 canvas->scale(2, 1/2.f);
2044 canvas->drawCircle(28, 28, 15, filledPaint); // black center: (50+(28*2), 50+(28/2))
2045 canvas->restore();
2046 filledPaint.setColor(SK_ColorGRAY);
2047 outlinePaint.setColor(SK_ColorRED);
2048 canvas->scale(2, 1/2.f);
2049 canvas->drawCircle(28, 28, 15, outlinePaint); // red center: (28*2, 28/2)
2050 canvas->translate(50, 50);
2051 canvas->drawCircle(28, 28, 15, filledPaint); // gray center: ((50+28)*2, (50+28)/2)
Cary Clark8032b982017-07-28 11:04:54 -04002052}
2053##
2054
2055#ToDo incomplete ##
2056
2057##
2058
2059# ------------------------------------------------------------------------------
2060
2061#Method void scale(SkScalar sx, SkScalar sy)
2062
2063Scale Matrix by sx on the x-axis and sy on the y-axis.
2064
2065Mathematically, replace Matrix with a scale matrix
2066pre-multiplied with Matrix.
2067
2068This has the effect of scaling the drawing by (sx, sy) before transforming
2069the result with Matrix.
2070
Cary Clarkbad5ad72017-08-03 17:14:08 -04002071#Param sx amount to scale in x ##
2072#Param sy amount to scale in y ##
Cary Clark8032b982017-07-28 11:04:54 -04002073
2074#Example
2075#Height 160
Cary Clarkbad5ad72017-08-03 17:14:08 -04002076void draw(SkCanvas* canvas) {
2077 SkPaint paint;
2078 SkRect rect = { 10, 20, 60, 120 };
2079 canvas->translate(20, 20);
2080 canvas->drawRect(rect, paint);
2081 canvas->scale(2, .5f);
2082 paint.setColor(SK_ColorGRAY);
2083 canvas->drawRect(rect, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002084}
2085##
2086
2087#ToDo incomplete ##
2088
2089##
2090
2091# ------------------------------------------------------------------------------
2092
2093#Method void rotate(SkScalar degrees)
2094
2095Rotate Matrix by degrees. Positive degrees rotates clockwise.
2096
2097Mathematically, replace Matrix with a rotation matrix
2098pre-multiplied with Matrix.
2099
2100This has the effect of rotating the drawing by degrees before transforming
2101the result with Matrix.
2102
Cary Clarkbad5ad72017-08-03 17:14:08 -04002103#Param degrees amount to rotate, in degrees ##
Cary Clark8032b982017-07-28 11:04:54 -04002104
2105#Example
2106#Description
2107Draw clock hands at time 5:10. The hour hand and minute hand point up and
2108are rotated clockwise.
2109##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002110void draw(SkCanvas* canvas) {
2111 SkPaint paint;
2112 paint.setStyle(SkPaint::kStroke_Style);
2113 canvas->translate(128, 128);
2114 canvas->drawCircle(0, 0, 60, paint);
2115 canvas->save();
2116 canvas->rotate(10 * 360 / 60); // 10 minutes of 60 scaled to 360 degrees
2117 canvas->drawLine(0, 0, 0, -50, paint);
2118 canvas->restore();
2119 canvas->rotate((5 + 10.f/60) * 360 / 12); // 5 and 10/60 hours of 12 scaled to 360 degrees
2120 canvas->drawLine(0, 0, 0, -30, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002121}
2122##
2123
2124#ToDo incomplete ##
2125
2126##
2127
2128# ------------------------------------------------------------------------------
2129
2130#Method void rotate(SkScalar degrees, SkScalar px, SkScalar py)
2131
Cary Clarkbad5ad72017-08-03 17:14:08 -04002132Rotate Matrix by degrees about a point at (px, py). Positive degrees rotates
2133clockwise.
Cary Clark8032b982017-07-28 11:04:54 -04002134
2135Mathematically, construct a rotation matrix. Pre-multiply the rotation matrix by
2136a translation matrix, then replace Matrix with the resulting matrix
2137pre-multiplied with Matrix.
2138
Cary Clarkbad5ad72017-08-03 17:14:08 -04002139This has the effect of rotating the drawing about a given point before
2140transforming the result with Matrix.
Cary Clark8032b982017-07-28 11:04:54 -04002141
Cary Clarkbad5ad72017-08-03 17:14:08 -04002142#Param degrees amount to rotate, in degrees ##
2143#Param px x-coordinate of the point to rotate about ##
2144#Param py y-coordinate of the point to rotate about ##
Cary Clark8032b982017-07-28 11:04:54 -04002145
2146#Example
2147#Height 192
Cary Clarkbad5ad72017-08-03 17:14:08 -04002148void draw(SkCanvas* canvas) {
2149 SkPaint paint;
2150 paint.setTextSize(96);
2151 canvas->drawString("A1", 130, 100, paint);
2152 canvas->rotate(180, 130, 100);
2153 canvas->drawString("A1", 130, 100, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002154}
2155##
2156
2157#ToDo incomplete ##
2158
2159##
2160
2161# ------------------------------------------------------------------------------
2162
2163#Method void skew(SkScalar sx, SkScalar sy)
2164
Cary Clarkbad5ad72017-08-03 17:14:08 -04002165Skew Matrix by sx on the x-axis and sy on the y-axis. A positive value of sx
2166skews the drawing right as y increases; a positive value of sy skews the drawing
2167down as x increases.
Cary Clark8032b982017-07-28 11:04:54 -04002168
Cary Clarkbad5ad72017-08-03 17:14:08 -04002169Mathematically, replace Matrix with a skew matrix pre-multiplied with Matrix.
Cary Clark8032b982017-07-28 11:04:54 -04002170
Cary Clarkbad5ad72017-08-03 17:14:08 -04002171This has the effect of skewing the drawing by (sx, sy) before transforming
Cary Clark8032b982017-07-28 11:04:54 -04002172the result with Matrix.
2173
Cary Clarkbad5ad72017-08-03 17:14:08 -04002174#Param sx amount to skew in x ##
2175#Param sy amount to skew in y ##
2176
Cary Clark8032b982017-07-28 11:04:54 -04002177#Example
2178 #Description
2179 Black text mimics an oblique text style by using a negative skew in x that
2180 shifts the geometry to the right as the y values decrease.
2181 Red text uses a positive skew in y to shift the geometry down as the x values
2182 increase.
2183 Blue text combines x and y skew to rotate and scale.
2184 ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002185 SkPaint paint;
2186 paint.setTextSize(128);
2187 canvas->translate(30, 130);
2188 canvas->save();
2189 canvas->skew(-.5, 0);
2190 canvas->drawString("A1", 0, 0, paint);
2191 canvas->restore();
2192 canvas->save();
2193 canvas->skew(0, .5);
2194 paint.setColor(SK_ColorRED);
2195 canvas->drawString("A1", 0, 0, paint);
2196 canvas->restore();
2197 canvas->skew(-.5, .5);
2198 paint.setColor(SK_ColorBLUE);
Cary Clark8032b982017-07-28 11:04:54 -04002199 canvas->drawString("A1", 0, 0, paint);
2200##
2201
2202#ToDo incomplete ##
2203
2204##
2205
2206# ------------------------------------------------------------------------------
2207
2208#Method void concat(const SkMatrix& matrix)
2209
Cary Clarkbad5ad72017-08-03 17:14:08 -04002210Replace Matrix with matrix pre-multiplied with existing Matrix.
Cary Clark8032b982017-07-28 11:04:54 -04002211
Cary Clarkbad5ad72017-08-03 17:14:08 -04002212This has the effect of transforming the drawn geometry by matrix, before
2213transforming the result with existing Matrix.
Cary Clark8032b982017-07-28 11:04:54 -04002214
Cary Clarkbad5ad72017-08-03 17:14:08 -04002215#Param matrix matrix to pre-multiply with existing Matrix ##
Cary Clark8032b982017-07-28 11:04:54 -04002216
2217#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04002218void draw(SkCanvas* canvas) {
2219 SkPaint paint;
2220 paint.setTextSize(80);
2221 paint.setTextScaleX(.3);
2222 SkMatrix matrix;
2223 SkRect rect[2] = {{ 10, 20, 90, 110 }, { 40, 130, 140, 180 }};
2224 matrix.setRectToRect(rect[0], rect[1], SkMatrix::kFill_ScaleToFit);
2225 canvas->drawRect(rect[0], paint);
2226 canvas->drawRect(rect[1], paint);
2227 paint.setColor(SK_ColorWHITE);
2228 canvas->drawString("Here", rect[0].fLeft + 10, rect[0].fBottom - 10, paint);
2229 canvas->concat(matrix);
2230 canvas->drawString("There", rect[0].fLeft + 10, rect[0].fBottom - 10, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002231}
2232##
2233
2234#ToDo incomplete ##
2235
2236##
2237
2238# ------------------------------------------------------------------------------
2239
2240#Method void setMatrix(const SkMatrix& matrix)
2241
2242Replace Matrix with matrix.
2243Unlike concat(), any prior matrix state is overwritten.
2244
Cary Clarkbad5ad72017-08-03 17:14:08 -04002245#Param matrix matrix to copy, replacing existing Matrix ##
Cary Clark8032b982017-07-28 11:04:54 -04002246
2247#Example
2248#Height 128
Cary Clarkbad5ad72017-08-03 17:14:08 -04002249void draw(SkCanvas* canvas) {
2250 SkPaint paint;
2251 canvas->scale(4, 6);
2252 canvas->drawString("truth", 2, 10, paint);
2253 SkMatrix matrix;
2254 matrix.setScale(2.8f, 6);
2255 canvas->setMatrix(matrix);
2256 canvas->drawString("consequences", 2, 20, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002257}
2258##
2259
2260#ToDo incomplete ##
2261
2262##
2263
2264# ------------------------------------------------------------------------------
2265
2266#Method void resetMatrix()
2267
2268Sets Matrix to the identity matrix.
2269Any prior matrix state is overwritten.
2270
2271#Example
2272#Height 128
Cary Clarkbad5ad72017-08-03 17:14:08 -04002273void draw(SkCanvas* canvas) {
2274 SkPaint paint;
2275 canvas->scale(4, 6);
2276 canvas->drawString("truth", 2, 10, paint);
2277 canvas->resetMatrix();
2278 canvas->scale(2.8f, 6);
2279 canvas->drawString("consequences", 2, 20, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002280}
2281##
2282
2283#ToDo incomplete ##
2284
2285##
2286
2287# ------------------------------------------------------------------------------
2288
2289#Method const SkMatrix& getTotalMatrix() const
2290
2291Returns Matrix.
2292This does not account for translation by Device or Surface.
2293
Cary Clarkbad5ad72017-08-03 17:14:08 -04002294#Return Matrix in Canvas ##
Cary Clark8032b982017-07-28 11:04:54 -04002295
2296#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04002297 SkDebugf("isIdentity %s\n", canvas->getTotalMatrix().isIdentity() ? "true" : "false");
2298 #StdOut
2299 isIdentity true
2300 ##
Cary Clark8032b982017-07-28 11:04:54 -04002301##
2302
2303#ToDo incomplete ##
2304
2305##
2306
2307#Topic Matrix ##
2308
2309# ------------------------------------------------------------------------------
2310#Topic Clip
2311
2312Clip is built from a stack of clipping paths. Each Path in the
2313stack can be constructed from one or more Path_Contour elements. The
2314Path_Contour may be composed of any number of Path_Verb segments. Each
2315Path_Contour forms a closed area; Path_Fill_Type defines the area enclosed
2316by Path_Contour.
2317
2318Clip stack of Path elements successfully restrict the Path area. Each
2319Path is transformed by Matrix, then intersected with or subtracted from the
2320prior Clip to form the replacement Clip. Use SkClipOp::kDifference
2321to subtract Path from Clip; use SkClipOp::kIntersect to intersect Path
2322with Clip.
2323
2324A clipping Path may be anti-aliased; if Path, after transformation, is
2325composed of horizontal and vertical lines, clearing Anti-alias allows whole pixels
2326to either be inside or outside the clip. The fastest drawing has a aliased,
2327rectanglar clip.
2328
2329If clipping Path has Anti-alias set, clip may partially clip a pixel, requiring
2330that drawing blend partially with the destination along the edge. A rotated
2331rectangular anti-aliased clip looks smoother but draws slower.
2332
2333Clip can combine with Rect and Round_Rect primitives; like
2334Path, these are transformed by Matrix before they are combined with Clip.
2335
2336Clip can combine with Region. Region is assumed to be in Device coordinates
2337and is unaffected by Matrix.
2338
2339#Example
2340#Height 90
2341 #Description
2342 Draw a red circle with an aliased clip and an anti-aliased clip.
2343 Use an image filter to zoom into the pixels drawn.
2344 The edge of the aliased clip fully draws pixels in the red circle.
2345 The edge of the anti-aliased clip partially draws pixels in the red circle.
2346 ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002347 SkPaint redPaint, scalePaint;
2348 redPaint.setAntiAlias(true);
2349 redPaint.setColor(SK_ColorRED);
2350 canvas->save();
2351 for (bool antialias : { false, true } ) {
2352 canvas->save();
2353 canvas->clipRect(SkRect::MakeWH(19.5f, 11.5f), antialias);
2354 canvas->drawCircle(17, 11, 8, redPaint);
2355 canvas->restore();
2356 canvas->translate(16, 0);
2357 }
2358 canvas->restore();
2359 SkMatrix matrix;
2360 matrix.setScale(6, 6);
2361 scalePaint.setImageFilter(
2362 SkImageFilter::MakeMatrixFilter(matrix, kNone_SkFilterQuality, nullptr));
2363 SkCanvas::SaveLayerRec saveLayerRec(
2364 nullptr, &scalePaint, SkCanvas::kInitWithPrevious_SaveLayerFlag);
2365 canvas->saveLayer(saveLayerRec);
Cary Clark8032b982017-07-28 11:04:54 -04002366 canvas->restore();
2367##
2368
2369#Method void clipRect(const SkRect& rect, SkClipOp op, bool doAntiAlias)
2370
2371Replace Clip with the intersection or difference of Clip and rect,
2372with an aliased or anti-aliased clip edge. rect is transformed by Matrix
2373before it is combined with Clip.
2374
Cary Clarkbad5ad72017-08-03 17:14:08 -04002375#Param rect Rectangle to combine with Clip ##
2376#Param op Clip_Op to apply to Clip ##
2377#Param doAntiAlias true if Clip is to be anti-aliased ##
Cary Clark8032b982017-07-28 11:04:54 -04002378
2379#Example
2380#Height 128
Cary Clarkbad5ad72017-08-03 17:14:08 -04002381void draw(SkCanvas* canvas) {
2382 canvas->rotate(10);
2383 SkPaint paint;
2384 paint.setAntiAlias(true);
2385 for (auto alias: { false, true } ) {
2386 canvas->save();
2387 canvas->clipRect(SkRect::MakeWH(90, 80), SkClipOp::kIntersect, alias);
2388 canvas->drawCircle(100, 60, 60, paint);
2389 canvas->restore();
2390 canvas->translate(80, 0);
2391 }
Cary Clark8032b982017-07-28 11:04:54 -04002392}
2393##
2394
2395#ToDo incomplete ##
2396
2397##
2398
2399#Method void clipRect(const SkRect& rect, SkClipOp op)
2400
2401Replace Clip with the intersection or difference of Clip and rect.
2402Resulting Clip is aliased; pixels are fully contained by the clip.
Cary Clarkbad5ad72017-08-03 17:14:08 -04002403rect is transformed by Matrix before it is combined with Clip.
Cary Clark8032b982017-07-28 11:04:54 -04002404
Cary Clarkbad5ad72017-08-03 17:14:08 -04002405#Param rect Rectangle to combine with Clip ##
2406#Param op Clip_Op to apply to Clip ##
Cary Clark8032b982017-07-28 11:04:54 -04002407
2408#Example
2409#Height 192
2410#Width 280
Cary Clarkbad5ad72017-08-03 17:14:08 -04002411void draw(SkCanvas* canvas) {
2412 SkPaint paint;
2413 for (SkClipOp op: { SkClipOp::kIntersect, SkClipOp::kDifference } ) {
2414 canvas->save();
2415 canvas->clipRect(SkRect::MakeWH(90, 120), op, false);
2416 canvas->drawCircle(100, 100, 60, paint);
2417 canvas->restore();
2418 canvas->translate(80, 0);
2419 }
Cary Clark8032b982017-07-28 11:04:54 -04002420}
2421##
2422
2423#ToDo incomplete ##
2424
2425##
2426
2427#Method void clipRect(const SkRect& rect, bool doAntiAlias = false)
2428
2429Replace Clip with the intersection of Clip and rect.
2430Resulting Clip is aliased; pixels are fully contained by the clip.
2431rect is transformed by Matrix
2432before it is combined with Clip.
2433
Cary Clarkbad5ad72017-08-03 17:14:08 -04002434#Param rect Rectangle to combine with Clip ##
2435#Param doAntiAlias true if Clip is to be anti-aliased ##
Cary Clark8032b982017-07-28 11:04:54 -04002436
2437#Example
2438#Height 133
2439 #Description
2440 A circle drawn in pieces looks uniform when drawn aliased.
2441 The same circle pieces blend with pixels more than once when anti-aliased,
2442 visible as a thin pair of lines through the right circle.
2443 ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002444void draw(SkCanvas* canvas) {
2445 canvas->clear(SK_ColorWHITE);
2446 SkPaint paint;
2447 paint.setAntiAlias(true);
2448 paint.setColor(0x8055aaff);
2449 SkRect clipRect = { 0, 0, 87.4f, 87.4f };
2450 for (auto alias: { false, true } ) {
2451 canvas->save();
2452 canvas->clipRect(clipRect, SkClipOp::kIntersect, alias);
2453 canvas->drawCircle(67, 67, 60, paint);
2454 canvas->restore();
2455 canvas->save();
2456 canvas->clipRect(clipRect, SkClipOp::kDifference, alias);
2457 canvas->drawCircle(67, 67, 60, paint);
2458 canvas->restore();
2459 canvas->translate(120, 0);
2460 }
Cary Clark8032b982017-07-28 11:04:54 -04002461}
2462##
2463
2464#ToDo incomplete ##
2465
2466##
2467
2468#Method void androidFramework_setDeviceClipRestriction(const SkIRect& rect)
2469
2470Sets the max clip rectangle, which can be set by clipRect, clipRRect and
2471clipPath and intersect the current clip with the specified rect.
2472The max clip affects only future ops (it is not retroactive).
2473The clip restriction is not recorded in pictures.
2474
Cary Clarkbad5ad72017-08-03 17:14:08 -04002475Pass an empty rect to disable max clip.
2476
Cary Clark8032b982017-07-28 11:04:54 -04002477#Private
2478This is private API to be used only by Android framework.
2479##
2480
Cary Clarkbad5ad72017-08-03 17:14:08 -04002481#Param rect maximum allowed clip in device coordinates
Cary Clark579985c2017-07-31 11:48:27 -04002482#Param ##
Cary Clark8032b982017-07-28 11:04:54 -04002483
2484##
2485
2486#Method void clipRRect(const SkRRect& rrect, SkClipOp op, bool doAntiAlias)
2487
2488Replace Clip with the intersection or difference of Clip and rrect,
2489with an aliased or anti-aliased clip edge.
2490rrect is transformed by Matrix
2491before it is combined with Clip.
2492
Cary Clarkbad5ad72017-08-03 17:14:08 -04002493#Param rrect Round_Rect to combine with Clip ##
2494#Param op Clip_Op to apply to Clip ##
2495#Param doAntiAlias true if Clip is to be antialiased ##
Cary Clark8032b982017-07-28 11:04:54 -04002496
2497#Example
2498#Height 128
Cary Clarkbad5ad72017-08-03 17:14:08 -04002499void draw(SkCanvas* canvas) {
2500 canvas->clear(SK_ColorWHITE);
2501 SkPaint paint;
2502 paint.setAntiAlias(true);
2503 paint.setColor(0x8055aaff);
2504 SkRRect oval;
2505 oval.setOval({10, 20, 90, 100});
2506 canvas->clipRRect(oval, SkClipOp::kIntersect, true);
2507 canvas->drawCircle(70, 100, 60, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002508}
2509##
2510
2511#ToDo incomplete ##
2512
2513##
2514
2515#Method void clipRRect(const SkRRect& rrect, SkClipOp op)
2516
2517Replace Clip with the intersection or difference of Clip and rrect.
2518Resulting Clip is aliased; pixels are fully contained by the clip.
Cary Clarkbad5ad72017-08-03 17:14:08 -04002519rrect is transformed by Matrix before it is combined with Clip.
Cary Clark8032b982017-07-28 11:04:54 -04002520
Cary Clarkbad5ad72017-08-03 17:14:08 -04002521#Param rrect Round_Rect to combine with Clip ##
2522#Param op Clip_Op to apply to Clip ##
Cary Clark8032b982017-07-28 11:04:54 -04002523
2524#Example
2525#Height 128
Cary Clarkbad5ad72017-08-03 17:14:08 -04002526void draw(SkCanvas* canvas) {
2527 SkPaint paint;
2528 paint.setColor(0x8055aaff);
2529 auto oval = SkRRect::MakeOval({10, 20, 90, 100});
2530 canvas->clipRRect(oval, SkClipOp::kIntersect);
2531 canvas->drawCircle(70, 100, 60, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002532}
2533##
2534
2535#ToDo incomplete ##
2536
2537##
2538
2539#Method void clipRRect(const SkRRect& rrect, bool doAntiAlias = false)
2540
2541Replace Clip with the intersection of Clip and rrect,
2542with an aliased or anti-aliased clip edge.
Cary Clarkbad5ad72017-08-03 17:14:08 -04002543rrect is transformed by Matrix before it is combined with Clip.
Cary Clark8032b982017-07-28 11:04:54 -04002544
Cary Clarkbad5ad72017-08-03 17:14:08 -04002545#Param rrect Round_Rect to combine with Clip ##
2546#Param doAntiAlias true if Clip is to be antialiased ##
Cary Clark8032b982017-07-28 11:04:54 -04002547
2548#Example
2549#Height 128
Cary Clarkbad5ad72017-08-03 17:14:08 -04002550void draw(SkCanvas* canvas) {
2551 SkPaint paint;
2552 paint.setAntiAlias(true);
2553 auto oval = SkRRect::MakeRectXY({10, 20, 90, 100}, 9, 13);
2554 canvas->clipRRect(oval, true);
2555 canvas->drawCircle(70, 100, 60, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002556}
2557##
2558
2559#ToDo incomplete ##
2560
2561##
2562
2563#Method void clipPath(const SkPath& path, SkClipOp op, bool doAntiAlias)
2564
2565Replace Clip with the intersection or difference of Clip and path,
2566with an aliased or anti-aliased clip edge. Path_Fill_Type determines if path
2567describes the area inside or outside its contours; and if Path_Contour overlaps
2568itself or another Path_Contour, whether the overlaps form part of the area.
Cary Clarkbad5ad72017-08-03 17:14:08 -04002569path is transformed by Matrix before it is combined with Clip.
Cary Clark8032b982017-07-28 11:04:54 -04002570
Cary Clarkbad5ad72017-08-03 17:14:08 -04002571#Param path Path to combine with Clip ##
2572#Param op Clip_Op to apply to Clip ##
2573#Param doAntiAlias true if Clip is to be antialiased ##
Cary Clark8032b982017-07-28 11:04:54 -04002574
2575#Example
2576#Description
2577Top figure uses SkPath::kInverseWinding_FillType and SkClipOp::kDifference;
2578area outside clip is subtracted from circle.
2579
2580Bottom figure uses SkPath::kWinding_FillType and SkClipOp::kIntersect;
2581area inside clip is intersected with circle.
2582##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002583void draw(SkCanvas* canvas) {
2584 SkPaint paint;
2585 paint.setAntiAlias(true);
2586 SkPath path;
2587 path.addRect({20, 30, 100, 110});
2588 path.setFillType(SkPath::kInverseWinding_FillType);
2589 canvas->save();
2590 canvas->clipPath(path, SkClipOp::kDifference, false);
2591 canvas->drawCircle(70, 100, 60, paint);
2592 canvas->restore();
2593 canvas->translate(100, 100);
2594 path.setFillType(SkPath::kWinding_FillType);
2595 canvas->clipPath(path, SkClipOp::kIntersect, false);
2596 canvas->drawCircle(70, 100, 60, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002597}
2598##
2599
2600#ToDo incomplete ##
2601
2602##
2603
2604#Method void clipPath(const SkPath& path, SkClipOp op)
2605
2606Replace Clip with the intersection or difference of Clip and path.
2607Resulting Clip is aliased; pixels are fully contained by the clip.
2608Path_Fill_Type determines if path
2609describes the area inside or outside its contours; and if Path_Contour overlaps
2610itself or another Path_Contour, whether the overlaps form part of the area.
2611path is transformed by Matrix
2612before it is combined with Clip.
2613
Cary Clarkbad5ad72017-08-03 17:14:08 -04002614#Param path Path to combine with Clip ##
2615#Param op Clip_Op to apply to Clip ##
Cary Clark8032b982017-07-28 11:04:54 -04002616
2617#Example
2618#Description
2619Overlapping Rects form a clip. When clip's Path_Fill_Type is set to
2620SkPath::kWinding_FillType, the overlap is included. Set to
2621SkPath::kEvenOdd_FillType, the overlap is excluded and forms a hole.
2622##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002623void draw(SkCanvas* canvas) {
2624 SkPaint paint;
2625 paint.setAntiAlias(true);
2626 SkPath path;
2627 path.addRect({20, 15, 100, 95});
2628 path.addRect({50, 65, 130, 135});
2629 path.setFillType(SkPath::kWinding_FillType);
2630 canvas->save();
2631 canvas->clipPath(path, SkClipOp::kIntersect);
2632 canvas->drawCircle(70, 85, 60, paint);
2633 canvas->restore();
2634 canvas->translate(100, 100);
2635 path.setFillType(SkPath::kEvenOdd_FillType);
2636 canvas->clipPath(path, SkClipOp::kIntersect);
2637 canvas->drawCircle(70, 85, 60, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002638}
2639##
2640
2641#ToDo incomplete ##
2642
2643##
2644
2645#Method void clipPath(const SkPath& path, bool doAntiAlias = false)
2646
2647Replace Clip with the intersection of Clip and path.
2648Resulting Clip is aliased; pixels are fully contained by the clip.
2649Path_Fill_Type determines if path
2650describes the area inside or outside its contours; and if Path_Contour overlaps
2651itself or another Path_Contour, whether the overlaps form part of the area.
Cary Clarkbad5ad72017-08-03 17:14:08 -04002652path is transformed by Matrix before it is combined with Clip.
Cary Clark8032b982017-07-28 11:04:54 -04002653
Cary Clarkbad5ad72017-08-03 17:14:08 -04002654#Param path Path to combine with Clip ##
2655#Param doAntiAlias true if Clip is to be antialiased ##
Cary Clark8032b982017-07-28 11:04:54 -04002656
2657#Example
2658#Height 212
2659#Description
2660Clip loops over itself covering its center twice. When clip's Path_Fill_Type
2661is set to SkPath::kWinding_FillType, the overlap is included. Set to
2662SkPath::kEvenOdd_FillType, the overlap is excluded and forms a hole.
2663##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002664void draw(SkCanvas* canvas) {
2665 SkPaint paint;
2666 paint.setAntiAlias(true);
2667 SkPath path;
2668 SkPoint poly[] = {{20, 20}, { 80, 20}, { 80, 80}, {40, 80},
2669 {40, 40}, {100, 40}, {100, 100}, {20, 100}};
2670 path.addPoly(poly, SK_ARRAY_COUNT(poly), true);
2671 path.setFillType(SkPath::kWinding_FillType);
2672 canvas->save();
2673 canvas->clipPath(path, SkClipOp::kIntersect);
2674 canvas->drawCircle(50, 50, 45, paint);
2675 canvas->restore();
2676 canvas->translate(100, 100);
2677 path.setFillType(SkPath::kEvenOdd_FillType);
2678 canvas->clipPath(path, SkClipOp::kIntersect);
2679 canvas->drawCircle(50, 50, 45, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002680}
2681##
2682
2683#ToDo incomplete ##
2684
2685##
2686
2687# ------------------------------------------------------------------------------
2688
2689#Method void setAllowSimplifyClip(bool allow)
2690
2691#Experimental
2692Only used for testing.
2693##
2694
2695Set to simplify clip stack using path ops.
2696
2697##
2698
2699# ------------------------------------------------------------------------------
2700
2701#Method void clipRegion(const SkRegion& deviceRgn, SkClipOp op = SkClipOp::kIntersect)
2702
2703Replace Clip with the intersection or difference of Clip and Region deviceRgn.
2704Resulting Clip is aliased; pixels are fully contained by the clip.
2705deviceRgn is unaffected by Matrix.
2706
Cary Clarkbad5ad72017-08-03 17:14:08 -04002707#Param deviceRgn Region to combine with Clip ##
2708#Param op Clip_Op to apply to Clip ##
Cary Clark8032b982017-07-28 11:04:54 -04002709
2710#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04002711#Description
2712 region is unaffected by canvas rotation; rect is affected by canvas rotation.
2713 Both clips are aliased; this is unnoticable on Region clip because it
2714 aligns to pixel boundaries.
2715##
2716void draw(SkCanvas* canvas) {
2717 SkPaint paint;
2718 paint.setAntiAlias(true);
2719 SkIRect iRect = {30, 40, 120, 130 };
2720 SkRegion region(iRect);
2721 canvas->rotate(10);
2722 canvas->save();
2723 canvas->clipRegion(region, SkClipOp::kIntersect);
2724 canvas->drawCircle(50, 50, 45, paint);
2725 canvas->restore();
2726 canvas->translate(100, 100);
2727 canvas->clipRect(SkRect::Make(iRect), SkClipOp::kIntersect);
2728 canvas->drawCircle(50, 50, 45, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002729}
2730##
2731
2732#ToDo incomplete ##
2733
2734##
2735
2736#Method bool quickReject(const SkRect& rect) const
2737
2738Return true if Rect rect, transformed by Matrix, can be quickly determined to be
2739outside of Clip. May return false even though rect is outside of Clip.
2740
2741Use to check if an area to be drawn is clipped out, to skip subsequent draw calls.
2742
Cary Clarkbad5ad72017-08-03 17:14:08 -04002743#Param rect Rect to compare with Clip ##
Cary Clark8032b982017-07-28 11:04:54 -04002744
Cary Clarkbad5ad72017-08-03 17:14:08 -04002745#Return true if rect, transformed by Matrix, does not intersect Clip ##
Cary Clark8032b982017-07-28 11:04:54 -04002746
2747#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04002748void draw(SkCanvas* canvas) {
2749 SkRect testRect = {30, 30, 120, 129 };
2750 SkRect clipRect = {30, 130, 120, 230 };
2751 canvas->save();
2752 canvas->clipRect(clipRect);
2753 SkDebugf("quickReject %s\n", canvas->quickReject(testRect) ? "true" : "false");
2754 canvas->restore();
2755 canvas->rotate(10);
2756 canvas->clipRect(clipRect);
2757 SkDebugf("quickReject %s\n", canvas->quickReject(testRect) ? "true" : "false");
Cary Clark8032b982017-07-28 11:04:54 -04002758}
2759 #StdOut
Cary Clarkbad5ad72017-08-03 17:14:08 -04002760 quickReject true
Cary Clark8032b982017-07-28 11:04:54 -04002761 quickReject false
2762 ##
2763##
2764
2765#ToDo incomplete ##
2766
2767##
2768
2769#Method bool quickReject(const SkPath& path) const
2770
2771Return true if path, transformed by Matrix, can be quickly determined to be
2772outside of Clip. May return false even though path is outside of Clip.
2773
2774Use to check if an area to be drawn is clipped out, to skip subsequent draw calls.
2775
Cary Clarkbad5ad72017-08-03 17:14:08 -04002776#Param path Path to compare with Clip ##
Cary Clark8032b982017-07-28 11:04:54 -04002777
Cary Clarkbad5ad72017-08-03 17:14:08 -04002778#Return true if path, transformed by Matrix, does not intersect Clip ##
Cary Clark8032b982017-07-28 11:04:54 -04002779
2780#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04002781void draw(SkCanvas* canvas) {
2782 SkPoint testPoints[] = {{30, 30}, {120, 30}, {120, 129} };
2783 SkPoint clipPoints[] = {{30, 130}, {120, 130}, {120, 230} };
2784 SkPath testPath, clipPath;
2785 testPath.addPoly(testPoints, SK_ARRAY_COUNT(testPoints), true);
2786 clipPath.addPoly(clipPoints, SK_ARRAY_COUNT(clipPoints), true);
2787 canvas->save();
2788 canvas->clipPath(clipPath);
2789 SkDebugf("quickReject %s\n", canvas->quickReject(testPath) ? "true" : "false");
2790 canvas->restore();
2791 canvas->rotate(10);
2792 canvas->clipPath(clipPath);
2793 SkDebugf("quickReject %s\n", canvas->quickReject(testPath) ? "true" : "false");
Cary Clark8032b982017-07-28 11:04:54 -04002794 #StdOut
Cary Clarkbad5ad72017-08-03 17:14:08 -04002795 quickReject true
Cary Clark8032b982017-07-28 11:04:54 -04002796 quickReject false
2797 ##
2798}
2799##
2800
2801#ToDo incomplete ##
2802
2803##
2804
2805#Method SkRect getLocalClipBounds() const
2806
2807Return bounds of Clip, transformed by inverse of Matrix. If Clip is empty,
2808return SkRect::MakeEmpty, where all Rect sides equal zero.
2809
2810Rect returned is outset by one to account for partial pixel coverage if Clip
2811is anti-aliased.
2812
Cary Clarkbad5ad72017-08-03 17:14:08 -04002813#Return bounds of Clip in local coordinates ##
Cary Clark8032b982017-07-28 11:04:54 -04002814
2815#Example
2816 #Description
2817 Initial bounds is device bounds outset by 1 on all sides.
2818 Clipped bounds is clipPath bounds outset by 1 on all sides.
2819 Scaling the canvas by two in x and y scales the local bounds by 1/2 in x and y.
2820 ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002821 SkCanvas local(256, 256);
2822 canvas = &local;
2823 SkRect bounds = canvas->getLocalClipBounds();
2824 SkDebugf("left:%g top:%g right:%g bottom:%g\n",
2825 bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom);
2826 SkPoint clipPoints[] = {{30, 130}, {120, 130}, {120, 230} };
2827 SkPath clipPath;
2828 clipPath.addPoly(clipPoints, SK_ARRAY_COUNT(clipPoints), true);
2829 canvas->clipPath(clipPath);
2830 bounds = canvas->getLocalClipBounds();
2831 SkDebugf("left:%g top:%g right:%g bottom:%g\n",
2832 bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom);
2833 canvas->scale(2, 2);
2834 bounds = canvas->getLocalClipBounds();
2835 SkDebugf("left:%g top:%g right:%g bottom:%g\n",
2836 bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom);
2837 #StdOut
2838 left:-1 top:-1 right:257 bottom:257
2839 left:29 top:129 right:121 bottom:231
2840 left:14.5 top:64.5 right:60.5 bottom:115.5
2841 ##
Cary Clark8032b982017-07-28 11:04:54 -04002842##
2843
2844# local canvas in example works around bug in fiddle ##
2845#Bug 6524 ##
2846
2847##
2848
2849#Method bool getLocalClipBounds(SkRect* bounds) const
2850
2851Return bounds of Clip, transformed by inverse of Matrix. If Clip is empty,
2852return false, and set bounds to SkRect::MakeEmpty, where all Rect sides equal zero.
2853
2854bounds is outset by one to account for partial pixel coverage if Clip
2855is anti-aliased.
2856
Cary Clarkbad5ad72017-08-03 17:14:08 -04002857#Param bounds Rect of Clip in local coordinates ##
Cary Clark8032b982017-07-28 11:04:54 -04002858
Cary Clarkbad5ad72017-08-03 17:14:08 -04002859#Return true if Clip bounds is not empty ##
Cary Clark8032b982017-07-28 11:04:54 -04002860
2861#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04002862 void draw(SkCanvas* canvas) {
2863 SkCanvas local(256, 256);
2864 canvas = &local;
2865 SkRect bounds;
2866 SkDebugf("local bounds empty = %s\n", canvas->getLocalClipBounds(&bounds)
2867 ? "false" : "true");
2868 SkPath path;
2869 canvas->clipPath(path);
2870 SkDebugf("local bounds empty = %s\n", canvas->getLocalClipBounds(&bounds)
2871 ? "false" : "true");
Cary Clark8032b982017-07-28 11:04:54 -04002872 }
2873 #StdOut
Cary Clarkbad5ad72017-08-03 17:14:08 -04002874 local bounds empty = false
Cary Clark8032b982017-07-28 11:04:54 -04002875 local bounds empty = true
2876 ##
2877##
2878
2879# local canvas in example works around bug in fiddle ##
2880#Bug 6524 ##
2881
2882##
2883
2884#Method SkIRect getDeviceClipBounds() const
2885
2886Return IRect bounds of Clip, unaffected by Matrix. If Clip is empty,
2887return SkRect::MakeEmpty, where all Rect sides equal zero.
2888
2889Unlike getLocalClipBounds, returned IRect is not outset.
2890
Cary Clarkbad5ad72017-08-03 17:14:08 -04002891#Return bounds of Clip in Device coordinates ##
Cary Clark8032b982017-07-28 11:04:54 -04002892
2893#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04002894void draw(SkCanvas* canvas) {
2895 #Description
Cary Clark8032b982017-07-28 11:04:54 -04002896 Initial bounds is device bounds, not outset.
2897 Clipped bounds is clipPath bounds, not outset.
2898 Scaling the canvas by 1/2 in x and y scales the device bounds by 1/2 in x and y.
Cary Clarkbad5ad72017-08-03 17:14:08 -04002899 ##
2900 SkCanvas device(256, 256);
2901 canvas = &device;
2902 SkIRect bounds = canvas->getDeviceClipBounds();
2903 SkDebugf("left:%d top:%d right:%d bottom:%d\n",
2904 bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom);
2905 SkPoint clipPoints[] = {{30, 130}, {120, 130}, {120, 230} };
2906 SkPath clipPath;
2907 clipPath.addPoly(clipPoints, SK_ARRAY_COUNT(clipPoints), true);
2908 canvas->save();
2909 canvas->clipPath(clipPath);
2910 bounds = canvas->getDeviceClipBounds();
2911 SkDebugf("left:%d top:%d right:%d bottom:%d\n",
2912 bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom);
2913 canvas->restore();
2914 canvas->scale(1.f/2, 1.f/2);
2915 canvas->clipPath(clipPath);
2916 bounds = canvas->getDeviceClipBounds();
2917 SkDebugf("left:%d top:%d right:%d bottom:%d\n",
2918 bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom);
Cary Clark8032b982017-07-28 11:04:54 -04002919 #StdOut
Cary Clarkbad5ad72017-08-03 17:14:08 -04002920 left:0 top:0 right:256 bottom:256
2921 left:30 top:130 right:120 bottom:230
Cary Clark8032b982017-07-28 11:04:54 -04002922 left:15 top:65 right:60 bottom:115
2923 ##
2924}
2925##
2926
2927#ToDo some confusion on why with an identity Matrix local and device are different ##
2928
2929# device canvas in example works around bug in fiddle ##
2930#Bug 6524 ##
2931
2932##
2933
2934#Method bool getDeviceClipBounds(SkIRect* bounds) const
2935
2936Return IRect bounds of Clip, unaffected by Matrix. If Clip is empty,
2937return false, and set bounds to SkRect::MakeEmpty, where all Rect sides equal zero.
2938
2939Unlike getLocalClipBounds, bounds is not outset.
2940
Cary Clarkbad5ad72017-08-03 17:14:08 -04002941#Param bounds Rect of Clip in device coordinates ##
Cary Clark8032b982017-07-28 11:04:54 -04002942
Cary Clarkbad5ad72017-08-03 17:14:08 -04002943#Return true if Clip bounds is not empty ##
Cary Clark8032b982017-07-28 11:04:54 -04002944
2945#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04002946 void draw(SkCanvas* canvas) {
2947 SkIRect bounds;
2948 SkDebugf("device bounds empty = %s\n", canvas->getDeviceClipBounds(&bounds)
2949 ? "false" : "true");
2950 SkPath path;
2951 canvas->clipPath(path);
2952 SkDebugf("device bounds empty = %s\n", canvas->getDeviceClipBounds(&bounds)
2953 ? "false" : "true");
Cary Clark8032b982017-07-28 11:04:54 -04002954 }
2955 #StdOut
Cary Clarkbad5ad72017-08-03 17:14:08 -04002956 device bounds empty = false
Cary Clark8032b982017-07-28 11:04:54 -04002957 device bounds empty = true
2958 ##
2959##
2960
2961#ToDo incomplete ##
2962
2963##
2964
2965#Topic Clip ##
2966
2967# ------------------------------------------------------------------------------
2968
2969#Method void drawColor(SkColor color, SkBlendMode mode = SkBlendMode::kSrcOver)
2970
2971Fill Clip with Color color.
2972mode determines how Color_ARGB is combined with destination.
2973
Cary Clarkbad5ad72017-08-03 17:14:08 -04002974#Param color Unpremultiplied Color_ARGB ##
2975#Param mode SkBlendMode used to combine source color and destination ##
Cary Clark8032b982017-07-28 11:04:54 -04002976
2977#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04002978 canvas->drawColor(SK_ColorRED);
2979 canvas->clipRect(SkRect::MakeWH(150, 150));
2980 canvas->drawColor(SkColorSetARGB(0x80, 0x00, 0xFF, 0x00), SkBlendMode::kPlus);
2981 canvas->clipRect(SkRect::MakeWH(75, 75));
2982 canvas->drawColor(SkColorSetARGB(0x80, 0x00, 0x00, 0xFF), SkBlendMode::kPlus);
Cary Clark8032b982017-07-28 11:04:54 -04002983##
2984
2985#ToDo incomplete ##
2986
2987##
2988
2989# ------------------------------------------------------------------------------
2990
2991#Method void clear(SkColor color)
2992
2993Fill Clip with Color color using SkBlendMode::kSrc.
2994This has the effect of replacing all pixels contained by Clip with color.
2995
Cary Clarkbad5ad72017-08-03 17:14:08 -04002996#Param color Unpremultiplied Color_ARGB ##
Cary Clark8032b982017-07-28 11:04:54 -04002997
2998#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04002999void draw(SkCanvas* canvas) {
3000 canvas->save();
3001 canvas->clipRect(SkRect::MakeWH(256, 128));
3002 canvas->clear(SkColorSetARGB(0x80, 0xFF, 0x00, 0x00));
3003 canvas->restore();
3004 canvas->save();
3005 canvas->clipRect(SkRect::MakeWH(150, 192));
3006 canvas->clear(SkColorSetARGB(0x80, 0x00, 0xFF, 0x00));
3007 canvas->restore();
3008 canvas->clipRect(SkRect::MakeWH(75, 256));
3009 canvas->clear(SkColorSetARGB(0x80, 0x00, 0x00, 0xFF));
Cary Clark8032b982017-07-28 11:04:54 -04003010}
3011##
3012
3013#ToDo incomplete ##
3014
3015##
3016
3017# ------------------------------------------------------------------------------
3018
3019#Method void discard()
3020
3021Make Canvas contents undefined. Subsequent calls that read Canvas pixels,
3022such as drawing with SkBlendMode, return undefined results. discard() does
3023not change Clip or Matrix.
3024
3025discard() may do nothing, depending on the implementation of Surface or Device
3026that created Canvas.
3027
3028discard() allows optimized performance on subsequent draws by removing
3029cached data associated with Surface or Device.
3030It is not necessary to call discard() once done with Canvas;
3031any cached data is deleted when owning Surface or Device is deleted.
3032
3033#ToDo example? not sure how to make this meaningful w/o more implementation detail ##
3034
3035#NoExample
3036##
3037
3038##
3039
3040# ------------------------------------------------------------------------------
3041
3042#Method void drawPaint(const SkPaint& paint)
3043
Cary Clarkbad5ad72017-08-03 17:14:08 -04003044Fill Clip with Paint paint. Paint components Rasterizer, Mask_Filter, Shader,
3045Color_Filter, Image_Filter, and Blend_Mode affect drawing;
3046Path_Effect in paint is ignored.
Cary Clark8032b982017-07-28 11:04:54 -04003047
3048# can Path_Effect in paint ever alter drawPaint?
3049
Cary Clarkbad5ad72017-08-03 17:14:08 -04003050#Param paint graphics state used to fill Canvas ##
Cary Clark8032b982017-07-28 11:04:54 -04003051
3052#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003053void draw(SkCanvas* canvas) {
3054 SkColor colors[] = { SK_ColorRED, SK_ColorGREEN, SK_ColorBLUE };
3055 SkScalar pos[] = { 0, SK_Scalar1/2, SK_Scalar1 };
3056 SkPaint paint;
3057 paint.setShader(SkGradientShader::MakeSweep(256, 256, colors, pos, SK_ARRAY_COUNT(colors)));
3058 canvas->drawPaint(paint);
Cary Clark8032b982017-07-28 11:04:54 -04003059}
3060##
3061
3062#ToDo incomplete ##
3063
3064##
3065
3066# ------------------------------------------------------------------------------
3067
3068#Enum PointMode
3069
3070#Code
3071 enum PointMode {
3072 kPoints_PointMode,
3073 kLines_PointMode,
3074 kPolygon_PointMode
3075 };
3076##
3077
3078Selects if an array of points are drawn as discrete points, as lines, or as
3079an open polygon.
3080
3081#Const kPoints_PointMode 0
3082 Draw each point separately.
3083##
3084
3085#Const kLines_PointMode 1
3086 Draw each pair of points as a line segment.
3087##
3088
3089#Const kPolygon_PointMode 2
3090 Draw the array of points as a open polygon.
3091##
3092
3093#Example
3094 #Description
3095 The upper left corner shows three squares when drawn as points.
3096 The upper right corner shows one line; when drawn as lines, two points are required per line.
3097 The lower right corner shows two lines; when draw as polygon, no miter is drawn at the corner.
3098 The lower left corner shows two lines with a miter when path contains polygon.
3099 ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003100void draw(SkCanvas* canvas) {
3101 SkPaint paint;
3102 paint.setStyle(SkPaint::kStroke_Style);
3103 paint.setStrokeWidth(10);
3104 SkPoint points[] = {{64, 32}, {96, 96}, {32, 96}};
3105 canvas->drawPoints(SkCanvas::kPoints_PointMode, 3, points, paint);
3106 canvas->translate(128, 0);
3107 canvas->drawPoints(SkCanvas::kLines_PointMode, 3, points, paint);
3108 canvas->translate(0, 128);
3109 canvas->drawPoints(SkCanvas::kPolygon_PointMode, 3, points, paint);
3110 SkPath path;
3111 path.addPoly(points, 3, false);
3112 canvas->translate(-128, 0);
3113 canvas->drawPath(path, paint);
Cary Clark8032b982017-07-28 11:04:54 -04003114}
3115##
3116
3117#ToDo incomplete ##
3118
3119##
3120
3121# ------------------------------------------------------------------------------
3122
3123#Method void drawPoints(PointMode mode, size_t count, const SkPoint pts[], const SkPaint& paint)
3124
3125Draw pts using Clip, Matrix and Paint paint.
Cary Clarkbad5ad72017-08-03 17:14:08 -04003126count is the number of points; if count is less than one, has no effect.
Cary Clark8032b982017-07-28 11:04:54 -04003127mode may be one of: kPoints_PointMode, kLines_PointMode, or kPolygon_PointMode.
3128
Cary Clarkbad5ad72017-08-03 17:14:08 -04003129If mode is kPoints_PointMode, the shape of point drawn depends on paint
3130Paint_Stroke_Cap. If paint is set to SkPaint::kRound_Cap, each point draws a
3131circle of diameter Paint_Stroke_Width. If paint is set to SkPaint::kSquare_Cap
3132or SkPaint::kButt_Cap, each point draws a square of width and height
3133Paint_Stroke_Width.
Cary Clark8032b982017-07-28 11:04:54 -04003134
3135If mode is kLines_PointMode, each pair of points draws a line segment.
3136One line is drawn for every two points; each point is used once. If count is odd,
3137the final point is ignored.
3138
3139If mode is kPolygon_PointMode, each adjacent pair of points draws a line segment.
3140count minus one lines are drawn; the first and last point are used once.
3141
3142Each line segment respects paint Paint_Stroke_Cap and Paint_Stroke_Width.
3143Paint_Style is ignored, as if were set to SkPaint::kStroke_Style.
3144
Cary Clarkbad5ad72017-08-03 17:14:08 -04003145Always draws each element one at a time; is not affected by
3146Paint_Stroke_Join, and unlike drawPath, does not create a mask from all points
3147and lines before drawing.
Cary Clark8032b982017-07-28 11:04:54 -04003148
Cary Clarkbad5ad72017-08-03 17:14:08 -04003149#Param mode Whether pts draws points or lines ##
3150#Param count The number of points in the array ##
3151#Param pts Array of points to draw ##
3152#Param paint Stroke, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003153
3154#Example
3155#Height 200
3156 #Description
3157 #List
3158 # The first column draws points. ##
3159 # The second column draws points as lines. ##
3160 # The third column draws points as a polygon. ##
3161 # The fourth column draws points as a polygonal path. ##
3162 # The first row uses a round cap and round join. ##
3163 # The second row uses a square cap and a miter join. ##
3164 # The third row uses a butt cap and a bevel join. ##
3165 ##
3166 The transparent color makes multiple line draws visible;
3167 the path is drawn all at once.
3168 ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003169void draw(SkCanvas* canvas) {
3170 SkPaint paint;
3171 paint.setAntiAlias(true);
3172 paint.setStyle(SkPaint::kStroke_Style);
3173 paint.setStrokeWidth(10);
3174 paint.setColor(0x80349a45);
3175 const SkPoint points[] = {{32, 16}, {48, 48}, {16, 32}};
3176 const SkPaint::Join join[] = { SkPaint::kRound_Join,
3177 SkPaint::kMiter_Join,
3178 SkPaint::kBevel_Join };
3179 int joinIndex = 0;
3180 SkPath path;
3181 path.addPoly(points, 3, false);
3182 for (const auto cap : { SkPaint::kRound_Cap, SkPaint::kSquare_Cap, SkPaint::kButt_Cap } ) {
3183 paint.setStrokeCap(cap);
3184 paint.setStrokeJoin(join[joinIndex++]);
3185 for (const auto mode : { SkCanvas::kPoints_PointMode,
3186 SkCanvas::kLines_PointMode,
3187 SkCanvas::kPolygon_PointMode } ) {
3188 canvas->drawPoints(mode, 3, points, paint);
3189 canvas->translate(64, 0);
3190 }
3191 canvas->drawPath(path, paint);
3192 canvas->translate(-192, 64);
3193 }
Cary Clark8032b982017-07-28 11:04:54 -04003194}
3195##
3196
3197#ToDo incomplete ##
3198
3199##
3200
3201# ------------------------------------------------------------------------------
3202
3203#Method void drawPoint(SkScalar x, SkScalar y, const SkPaint& paint)
3204
3205Draw point at (x, y) using Clip, Matrix and Paint paint.
3206
3207The shape of point drawn depends on paint Paint_Stroke_Cap.
Cary Clarkbad5ad72017-08-03 17:14:08 -04003208If paint is set to SkPaint::kRound_Cap, draw a circle of diameter
3209Paint_Stroke_Width. If paint is set to SkPaint::kSquare_Cap or SkPaint::kButt_Cap,
Cary Clark8032b982017-07-28 11:04:54 -04003210draw a square of width and height Paint_Stroke_Width.
3211Paint_Style is ignored, as if were set to SkPaint::kStroke_Style.
3212
Cary Clarkbad5ad72017-08-03 17:14:08 -04003213#Param x left edge of circle or square ##
3214#Param y top edge of circle or square ##
3215#Param paint stroke, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003216
3217#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003218void draw(SkCanvas* canvas) {
3219 SkPaint paint;
3220 paint.setAntiAlias(true);
3221 paint.setColor(0x80349a45);
3222 paint.setStyle(SkPaint::kStroke_Style);
3223 paint.setStrokeWidth(100);
3224 paint.setStrokeCap(SkPaint::kRound_Cap);
3225 canvas->scale(1, 1.2f);
3226 canvas->drawPoint(64, 96, paint);
3227 canvas->scale(.6f, .8f);
3228 paint.setColor(SK_ColorWHITE);
3229 canvas->drawPoint(106, 120, paint);
Cary Clark8032b982017-07-28 11:04:54 -04003230}
3231##
3232
3233#ToDo incomplete ##
3234
3235##
3236
Cary Clarkbad5ad72017-08-03 17:14:08 -04003237#Method void drawPoint(SkPoint p, const SkPaint& paint)
3238
3239Draw point p using Clip, Matrix and Paint paint.
3240
3241The shape of point drawn depends on paint Paint_Stroke_Cap.
3242If paint is set to SkPaint::kRound_Cap, draw a circle of diameter
3243Paint_Stroke_Width. If paint is set to SkPaint::kSquare_Cap or SkPaint::kButt_Cap,
3244draw a square of width and height Paint_Stroke_Width.
3245Paint_Style is ignored, as if were set to SkPaint::kStroke_Style.
3246
3247#Param p top-left edge of circle or square ##
3248#Param paint stroke, blend, color, and so on, used to draw ##
3249
3250#Example
3251void draw(SkCanvas* canvas) {
3252 SkPaint paint;
3253 paint.setAntiAlias(true);
3254 paint.setColor(0x80349a45);
3255 paint.setStyle(SkPaint::kStroke_Style);
3256 paint.setStrokeWidth(100);
3257 paint.setStrokeCap(SkPaint::kSquare_Cap);
3258 canvas->scale(1, 1.2f);
3259 canvas->drawPoint({64, 96}, paint);
3260 canvas->scale(.6f, .8f);
3261 paint.setColor(SK_ColorWHITE);
3262 canvas->drawPoint(106, 120, paint);
3263}
3264##
3265
3266#SeeAlso drawPoints drawCircle drawRect
3267
3268##
3269
Cary Clark8032b982017-07-28 11:04:54 -04003270# ------------------------------------------------------------------------------
3271
3272#Method void drawLine(SkScalar x0, SkScalar y0, SkScalar x1, SkScalar y1, const SkPaint& paint)
3273
Cary Clarkbad5ad72017-08-03 17:14:08 -04003274Draws line segment from (x0, y0) to (x1, y1) using Clip, Matrix, and Paint paint.
3275In paint: Paint_Stroke_Width describes the line thickness;
3276Paint_Stroke_Cap draws the end rounded or square;
Cary Clark8032b982017-07-28 11:04:54 -04003277Paint_Style is ignored, as if were set to SkPaint::kStroke_Style.
3278
Cary Clarkbad5ad72017-08-03 17:14:08 -04003279#Param x0 start of line segment on x-axis ##
3280#Param y0 start of line segment on y-axis ##
3281#Param x1 end of line segment on x-axis ##
3282#Param y1 end of line segment on y-axis ##
3283#Param paint stroke, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003284
3285#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003286 SkPaint paint;
3287 paint.setAntiAlias(true);
3288 paint.setColor(0xFF9a67be);
3289 paint.setStrokeWidth(20);
3290 canvas->skew(1, 0);
3291 canvas->drawLine(32, 96, 32, 160, paint);
3292 canvas->skew(-2, 0);
3293 canvas->drawLine(288, 96, 288, 160, paint);
3294##
3295
3296#ToDo incomplete ##
3297
3298##
3299
3300#Method void drawLine(SkPoint p0, SkPoint p1, const SkPaint& paint)
3301
3302Draws line segment from p0 to p1 using Clip, Matrix, and Paint paint.
3303In paint: Paint_Stroke_Width describes the line thickness;
3304Paint_Stroke_Cap draws the end rounded or square;
3305Paint_Style is ignored, as if were set to SkPaint::kStroke_Style.
3306
3307#Param p0 start of line segment ##
3308#Param p1 end of line segment ##
3309#Param paint stroke, blend, color, and so on, used to draw ##
3310
3311#Example
3312 SkPaint paint;
3313 paint.setAntiAlias(true);
3314 paint.setColor(0xFF9a67be);
3315 paint.setStrokeWidth(20);
3316 canvas->skew(1, 0);
3317 canvas->drawLine({32, 96}, {32, 160}, paint);
3318 canvas->skew(-2, 0);
3319 canvas->drawLine({288, 96}, {288, 160}, paint);
Cary Clark8032b982017-07-28 11:04:54 -04003320##
3321
3322#ToDo incomplete ##
3323
3324##
3325
3326# ------------------------------------------------------------------------------
3327
3328#Method void drawRect(const SkRect& rect, const SkPaint& paint)
3329
3330Draw Rect rect using Clip, Matrix, and Paint paint.
3331In paint: Paint_Style determines if rectangle is stroked or filled;
3332if stroked, Paint_Stroke_Width describes the line thickness, and
3333Paint_Stroke_Join draws the corners rounded or square.
3334
Cary Clarkbad5ad72017-08-03 17:14:08 -04003335#Param rect rectangle to be drawn ##
3336#Param paint stroke or fill, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003337
3338#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003339void draw(SkCanvas* canvas) {
3340 SkPoint rectPts[] = { {64, 48}, {192, 160} };
3341 SkPaint paint;
3342 paint.setAntiAlias(true);
3343 paint.setStyle(SkPaint::kStroke_Style);
3344 paint.setStrokeWidth(20);
3345 paint.setStrokeJoin(SkPaint::kRound_Join);
3346 SkMatrix rotator;
3347 rotator.setRotate(30, 128, 128);
3348 for (auto color : { SK_ColorRED, SK_ColorBLUE, SK_ColorYELLOW, SK_ColorMAGENTA } ) {
3349 paint.setColor(color);
3350 SkRect rect;
3351 rect.set(rectPts[0], rectPts[1]);
3352 canvas->drawRect(rect, paint);
3353 rotator.mapPoints(rectPts, 2);
3354 }
Cary Clark8032b982017-07-28 11:04:54 -04003355}
3356##
3357
3358#ToDo incomplete ##
3359
3360##
3361
3362# ------------------------------------------------------------------------------
3363
3364#Method void drawIRect(const SkIRect& rect, const SkPaint& paint)
3365
3366Draw IRect rect using Clip, Matrix, and Paint paint.
3367In paint: Paint_Style determines if rectangle is stroked or filled;
3368if stroked, Paint_Stroke_Width describes the line thickness, and
3369Paint_Stroke_Join draws the corners rounded or square.
3370
Cary Clarkbad5ad72017-08-03 17:14:08 -04003371#Param rect rectangle to be drawn ##
3372#Param paint stroke or fill, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003373
3374#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003375 SkIRect rect = { 64, 48, 192, 160 };
3376 SkPaint paint;
3377 paint.setAntiAlias(true);
3378 paint.setStyle(SkPaint::kStroke_Style);
3379 paint.setStrokeWidth(20);
3380 paint.setStrokeJoin(SkPaint::kRound_Join);
3381 for (auto color : { SK_ColorRED, SK_ColorBLUE, SK_ColorYELLOW, SK_ColorMAGENTA } ) {
3382 paint.setColor(color);
3383 canvas->drawIRect(rect, paint);
3384 canvas->rotate(30, 128, 128);
3385 }
Cary Clark8032b982017-07-28 11:04:54 -04003386##
3387
3388#ToDo incomplete ##
3389
3390##
3391
3392# ------------------------------------------------------------------------------
3393
3394#Method void drawRegion(const SkRegion& region, const SkPaint& paint)
3395
3396Draw Region region using Clip, Matrix, and Paint paint.
3397In paint: Paint_Style determines if rectangle is stroked or filled;
3398if stroked, Paint_Stroke_Width describes the line thickness, and
3399Paint_Stroke_Join draws the corners rounded or square.
3400
Cary Clarkbad5ad72017-08-03 17:14:08 -04003401#Param region region to be drawn ##
3402#Param paint Paint stroke or fill, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003403
3404#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003405void draw(SkCanvas* canvas) {
3406 SkRegion region;
3407 region.op( 10, 10, 50, 50, SkRegion::kUnion_Op);
3408 region.op( 10, 50, 90, 90, SkRegion::kUnion_Op);
3409 SkPaint paint;
3410 paint.setAntiAlias(true);
3411 paint.setStyle(SkPaint::kStroke_Style);
3412 paint.setStrokeWidth(20);
3413 paint.setStrokeJoin(SkPaint::kRound_Join);
3414 canvas->drawRegion(region, paint);
Cary Clark8032b982017-07-28 11:04:54 -04003415}
3416##
3417
3418#ToDo incomplete ##
3419
3420##
3421
3422# ------------------------------------------------------------------------------
3423
3424#Method void drawOval(const SkRect& oval, const SkPaint& paint)
3425
3426Draw Oval oval using Clip, Matrix, and Paint.
3427In paint: Paint_Style determines if Oval is stroked or filled;
3428if stroked, Paint_Stroke_Width describes the line thickness.
3429
Cary Clarkbad5ad72017-08-03 17:14:08 -04003430#Param oval Rect bounds of Oval ##
3431#Param paint Paint stroke or fill, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003432
3433#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003434void draw(SkCanvas* canvas) {
3435 canvas->clear(0xFF3f5f9f);
3436 SkColor kColor1 = SkColorSetARGB(0xff, 0xff, 0x7f, 0);
3437 SkColor g1Colors[] = { kColor1, SkColorSetA(kColor1, 0x20) };
3438 SkPoint g1Points[] = { { 0, 0 }, { 0, 100 } };
3439 SkScalar pos[] = { 0.2f, 1.0f };
3440 SkRect bounds = SkRect::MakeWH(80, 70);
3441 SkPaint paint;
3442 paint.setAntiAlias(true);
3443 paint.setShader(SkGradientShader::MakeLinear(g1Points, g1Colors, pos, SK_ARRAY_COUNT(g1Colors),
3444 SkShader::kClamp_TileMode));
3445 canvas->drawOval(bounds , paint);
Cary Clark8032b982017-07-28 11:04:54 -04003446}
3447##
3448
3449#ToDo incomplete ##
3450
3451##
3452
3453# ------------------------------------------------------------------------------
3454
3455#Method void drawRRect(const SkRRect& rrect, const SkPaint& paint)
3456
3457Draw Round_Rect rrect using Clip, Matrix, and Paint paint.
3458In paint: Paint_Style determines if rrect is stroked or filled;
3459if stroked, Paint_Stroke_Width describes the line thickness.
3460
Cary Clarkbad5ad72017-08-03 17:14:08 -04003461rrect may represent a rectangle, circle, oval, uniformly rounded rectangle, or
3462may have any combination of positive non-square radii for the four corners.
Cary Clark8032b982017-07-28 11:04:54 -04003463
Cary Clarkbad5ad72017-08-03 17:14:08 -04003464#Param rrect Round_Rect with up to eight corner radii to draw ##
3465#Param paint Paint stroke or fill, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003466
3467#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003468void draw(SkCanvas* canvas) {
3469 SkPaint paint;
3470 paint.setAntiAlias(true);
3471 SkRect outer = {30, 40, 210, 220};
3472 SkRect radii = {30, 50, 70, 90 };
3473 SkRRect rRect;
3474 rRect.setNinePatch(outer, radii.fLeft, radii.fTop, radii.fRight, radii.fBottom);
3475 canvas->drawRRect(rRect, paint);
3476 paint.setColor(SK_ColorWHITE);
3477 canvas->drawLine(outer.fLeft + radii.fLeft, outer.fTop,
3478 outer.fLeft + radii.fLeft, outer.fBottom, paint);
3479 canvas->drawLine(outer.fRight - radii.fRight, outer.fTop,
3480 outer.fRight - radii.fRight, outer.fBottom, paint);
3481 canvas->drawLine(outer.fLeft, outer.fTop + radii.fTop,
3482 outer.fRight, outer.fTop + radii.fTop, paint);
3483 canvas->drawLine(outer.fLeft, outer.fBottom - radii.fBottom,
3484 outer.fRight, outer.fBottom - radii.fBottom, paint);
3485}
Cary Clark8032b982017-07-28 11:04:54 -04003486##
3487
3488#ToDo incomplete ##
3489
3490##
3491
3492# ------------------------------------------------------------------------------
3493
3494#Method void drawDRRect(const SkRRect& outer, const SkRRect& inner, const SkPaint& paint)
3495
3496Draw Round_Rect outer and inner
3497using Clip, Matrix, and Paint paint.
3498outer must contain inner or the drawing is undefined.
3499In paint: Paint_Style determines if rrect is stroked or filled;
3500if stroked, Paint_Stroke_Width describes the line thickness.
Cary Clarkbad5ad72017-08-03 17:14:08 -04003501If stroked and Round_Rect corner has zero length radii, Paint_Stroke_Join can
3502draw corners rounded or square.
Cary Clark8032b982017-07-28 11:04:54 -04003503
Cary Clarkbad5ad72017-08-03 17:14:08 -04003504GPU-backed platforms optimize drawing when both outer and inner are
Cary Clark8032b982017-07-28 11:04:54 -04003505concave and outer contains inner. These platforms may not be able to draw
3506Path built with identical data as fast.
3507
Cary Clarkbad5ad72017-08-03 17:14:08 -04003508#Param outer Round_Rect outer bounds to draw ##
3509#Param inner Round_Rect inner bounds to draw ##
3510#Param paint Paint stroke or fill, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003511
3512#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003513void draw(SkCanvas* canvas) {
3514 SkRRect outer = SkRRect::MakeRect({20, 40, 210, 200});
3515 SkRRect inner = SkRRect::MakeOval({60, 70, 170, 160});
3516 SkPaint paint;
3517 canvas->drawDRRect(outer, inner, paint);
Cary Clark8032b982017-07-28 11:04:54 -04003518}
3519##
3520
3521#Example
3522#Description
3523 Outer Rect has no corner radii, but stroke join is rounded.
3524 Inner Round_Rect has corner radii; outset stroke increases radii of corners.
3525 Stroke join does not affect inner Round_Rect since it has no sharp corners.
3526##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003527void draw(SkCanvas* canvas) {
3528 SkRRect outer = SkRRect::MakeRect({20, 40, 210, 200});
3529 SkRRect inner = SkRRect::MakeRectXY({60, 70, 170, 160}, 10, 10);
3530 SkPaint paint;
3531 paint.setAntiAlias(true);
3532 paint.setStyle(SkPaint::kStroke_Style);
3533 paint.setStrokeWidth(20);
3534 paint.setStrokeJoin(SkPaint::kRound_Join);
3535 canvas->drawDRRect(outer, inner, paint);
3536 paint.setStrokeWidth(1);
3537 paint.setColor(SK_ColorWHITE);
3538 canvas->drawDRRect(outer, inner, paint);
Cary Clark8032b982017-07-28 11:04:54 -04003539}
3540##
3541
3542#ToDo incomplete ##
3543
3544##
3545
3546# ------------------------------------------------------------------------------
3547
3548#Method void drawCircle(SkScalar cx, SkScalar cy, SkScalar radius, const SkPaint& paint)
3549
3550Draw Circle at (cx, cy) with radius using Clip, Matrix, and Paint paint.
3551If radius is zero or less, nothing is drawn.
3552In paint: Paint_Style determines if Circle is stroked or filled;
3553if stroked, Paint_Stroke_Width describes the line thickness.
3554
Cary Clarkbad5ad72017-08-03 17:14:08 -04003555#Param cx Circle center on the x-axis ##
3556#Param cy Circle center on the y-axis ##
3557#Param radius half the diameter of Circle ##
3558#Param paint Paint stroke or fill, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003559
3560#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003561 void draw(SkCanvas* canvas) {
3562 SkPaint paint;
3563 paint.setAntiAlias(true);
3564 canvas->drawCircle(128, 128, 90, paint);
3565 paint.setColor(SK_ColorWHITE);
3566 canvas->drawCircle(86, 86, 20, paint);
3567 canvas->drawCircle(160, 76, 20, paint);
3568 canvas->drawCircle(140, 150, 35, paint);
3569 }
3570##
3571
3572#ToDo incomplete ##
3573
3574##
3575
3576#Method void drawCircle(SkPoint center, SkScalar radius, const SkPaint& paint)
3577
3578Draw Circle at (cx, cy) with radius using Clip, Matrix, and Paint paint.
3579If radius is zero or less, nothing is drawn.
3580In paint: Paint_Style determines if Circle is stroked or filled;
3581if stroked, Paint_Stroke_Width describes the line thickness.
3582
3583#Param center Circle center ##
3584#Param radius half the diameter of Circle ##
3585#Param paint Paint stroke or fill, blend, color, and so on, used to draw ##
3586
3587#Example
3588 void draw(SkCanvas* canvas) {
3589 SkPaint paint;
3590 paint.setAntiAlias(true);
3591 canvas->drawCircle(128, 128, 90, paint);
3592 paint.setColor(SK_ColorWHITE);
3593 canvas->drawCircle({86, 86}, 20, paint);
3594 canvas->drawCircle({160, 76}, 20, paint);
3595 canvas->drawCircle({140, 150}, 35, paint);
3596 }
Cary Clark8032b982017-07-28 11:04:54 -04003597##
3598
3599#ToDo incomplete ##
3600
3601##
3602
3603# ------------------------------------------------------------------------------
3604
3605#Method void drawArc(const SkRect& oval, SkScalar startAngle, SkScalar sweepAngle,
3606 bool useCenter, const SkPaint& paint)
3607
3608Draw Arc using Clip, Matrix, and Paint paint.
Cary Clarkbad5ad72017-08-03 17:14:08 -04003609
Cary Clark8032b982017-07-28 11:04:54 -04003610Arc is part of Oval bounded by oval, sweeping from startAngle to startAngle plus
3611sweepAngle. startAngle and sweepAngle are in degrees.
Cary Clarkbad5ad72017-08-03 17:14:08 -04003612
Cary Clark8032b982017-07-28 11:04:54 -04003613startAngle of zero places start point at the right middle edge of oval.
3614A positive sweepAngle places Arc end point clockwise from start point;
3615a negative sweepAngle places Arc end point counterclockwise from start point.
3616sweepAngle may exceed 360 degrees, a full circle.
3617If useCenter is true, draw a wedge that includes lines from oval
3618center to Arc end points. If useCenter is false, draw Arc between end points.
3619
3620If Rect oval is empty or sweepAngle is zero, nothing is drawn.
3621
Cary Clarkbad5ad72017-08-03 17:14:08 -04003622#Param oval Rect bounds of Oval containing Arc to draw ##
3623#Param startAngle angle in degrees where Arc begins ##
3624#Param sweepAngle sweep angle in degrees; positive is clockwise ##
3625#Param useCenter if true, include the center of the oval ##
3626#Param paint Paint stroke or fill, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003627
3628#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003629 void draw(SkCanvas* canvas) {
3630 SkPaint paint;
3631 paint.setAntiAlias(true);
3632 SkRect oval = { 4, 4, 60, 60};
3633 for (auto useCenter : { false, true } ) {
3634 for (auto style : { SkPaint::kFill_Style, SkPaint::kStroke_Style } ) {
3635 paint.setStyle(style);
3636 for (auto degrees : { 45, 90, 180, 360} ) {
3637 canvas->drawArc(oval, 0, degrees , useCenter, paint);
3638 canvas->translate(64, 0);
3639 }
3640 canvas->translate(-256, 64);
3641 }
3642 }
Cary Clark8032b982017-07-28 11:04:54 -04003643 }
3644##
3645
3646#Example
3647#Height 64
Cary Clarkbad5ad72017-08-03 17:14:08 -04003648 void draw(SkCanvas* canvas) {
3649 SkPaint paint;
3650 paint.setAntiAlias(true);
3651 paint.setStyle(SkPaint::kStroke_Style);
3652 paint.setStrokeWidth(4);
3653 SkRect oval = { 4, 4, 60, 60};
3654 float intervals[] = { 5, 5 };
3655 paint.setPathEffect(SkDashPathEffect::Make(intervals, 2, 2.5f));
3656 for (auto degrees : { 270, 360, 540, 720 } ) {
3657 canvas->drawArc(oval, 0, degrees, false, paint);
3658 canvas->translate(64, 0);
3659 }
Cary Clark8032b982017-07-28 11:04:54 -04003660 }
3661##
3662
3663#ToDo incomplete ##
3664
3665##
3666
3667# ------------------------------------------------------------------------------
3668
3669#Method void drawRoundRect(const SkRect& rect, SkScalar rx, SkScalar ry, const SkPaint& paint)
3670
Cary Clarkbad5ad72017-08-03 17:14:08 -04003671Draw Round_Rect bounded by Rect rect, with corner radii (rx, ry) using Clip,
3672Matrix, and Paint paint.
3673
Cary Clark8032b982017-07-28 11:04:54 -04003674In paint: Paint_Style determines if Round_Rect is stroked or filled;
3675if stroked, Paint_Stroke_Width describes the line thickness.
3676If rx or ry are less than zero, they are treated as if they are zero.
3677If rx plus ry exceeds rect width or rect height, radii are scaled down to fit.
Cary Clarkbad5ad72017-08-03 17:14:08 -04003678If rx and ry are zero, Round_Rect is drawn as Rect and if stroked is affected by
3679Paint_Stroke_Join.
Cary Clark8032b982017-07-28 11:04:54 -04003680
Cary Clarkbad5ad72017-08-03 17:14:08 -04003681#Param rect Rect bounds of Round_Rect to draw ##
3682#Param rx semiaxis length in x of oval describing rounded corners ##
3683#Param ry semiaxis length in y of oval describing rounded corners ##
3684#Param paint stroke, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003685
3686#Example
3687#Description
3688 Top row has a zero radius a generates a rectangle.
3689 Second row radii sum to less than sides.
3690 Third row radii sum equals sides.
3691 Fourth row radii sum exceeds sides; radii are scaled to fit.
3692##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003693 void draw(SkCanvas* canvas) {
3694 SkVector radii[] = { {0, 20}, {10, 10}, {10, 20}, {10, 40} };
3695 SkPaint paint;
3696 paint.setStrokeWidth(15);
3697 paint.setStrokeJoin(SkPaint::kRound_Join);
3698 paint.setAntiAlias(true);
3699 for (auto style : { SkPaint::kStroke_Style, SkPaint::kFill_Style } ) {
3700 paint.setStyle(style );
3701 for (size_t i = 0; i < SK_ARRAY_COUNT(radii); ++i) {
3702 canvas->drawRoundRect({10, 10, 60, 40}, radii[i].fX, radii[i].fY, paint);
3703 canvas->translate(0, 60);
3704 }
3705 canvas->translate(80, -240);
3706 }
Cary Clark8032b982017-07-28 11:04:54 -04003707 }
3708##
3709
3710#ToDo incomplete ##
3711
3712##
3713
3714# ------------------------------------------------------------------------------
3715
3716#Method void drawPath(const SkPath& path, const SkPaint& paint)
3717
3718Draw Path path using Clip, Matrix, and Paint paint.
3719Path contains an array of Path_Contour, each of which may be open or closed.
3720
3721In paint: Paint_Style determines if Round_Rect is stroked or filled:
Cary Clarkbad5ad72017-08-03 17:14:08 -04003722if filled, Path_Fill_Type determines whether Path_Contour describes inside or
3723outside of fill; if stroked, Paint_Stroke_Width describes the line thickness,
3724Paint_Stroke_Cap describes line ends, and Paint_Stroke_Join describes how
3725corners are drawn.
Cary Clark8032b982017-07-28 11:04:54 -04003726
Cary Clarkbad5ad72017-08-03 17:14:08 -04003727#Param path Path to draw ##
3728#Param paint stroke, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003729
3730#Example
3731#Description
3732 Top rows draw stroked path with combinations of joins and caps. The open contour
3733 is affected by caps; the closed contour is affected by joins.
3734 Bottom row draws fill the same for open and closed contour.
3735 First bottom column shows winding fills overlap.
3736 Second bottom column shows even odd fills exclude overlap.
3737 Third bottom column shows inverse winding fills area outside both contours.
3738##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003739void draw(SkCanvas* canvas) {
3740 SkPath path;
3741 path.moveTo(20, 20);
3742 path.quadTo(60, 20, 60, 60);
3743 path.close();
3744 path.moveTo(60, 20);
3745 path.quadTo(60, 60, 20, 60);
3746 SkPaint paint;
3747 paint.setStrokeWidth(10);
3748 paint.setAntiAlias(true);
3749 paint.setStyle(SkPaint::kStroke_Style);
3750 for (auto join: { SkPaint::kBevel_Join, SkPaint::kRound_Join, SkPaint::kMiter_Join } ) {
3751 paint.setStrokeJoin(join);
3752 for (auto cap: { SkPaint::kButt_Cap, SkPaint::kSquare_Cap, SkPaint::kRound_Cap } ) {
3753 paint.setStrokeCap(cap);
3754 canvas->drawPath(path, paint);
3755 canvas->translate(80, 0);
3756 }
3757 canvas->translate(-240, 60);
3758 }
3759 paint.setStyle(SkPaint::kFill_Style);
3760 for (auto fill : { SkPath::kWinding_FillType,
3761 SkPath::kEvenOdd_FillType,
3762 SkPath::kInverseWinding_FillType } ) {
3763 path.setFillType(fill);
3764 canvas->save();
3765 canvas->clipRect({0, 10, 80, 70});
3766 canvas->drawPath(path, paint);
3767 canvas->restore();
3768 canvas->translate(80, 0);
3769 }
Cary Clark8032b982017-07-28 11:04:54 -04003770}
3771##
3772
3773#ToDo incomplete ##
3774
3775##
3776
3777# ------------------------------------------------------------------------------
3778#Topic Draw_Image
3779
Cary Clarkbad5ad72017-08-03 17:14:08 -04003780drawImage, drawImageRect, and drawImageNine can be called with a bare pointer or
3781a smart pointer as a convenience. The pairs of calls are otherwise identical.
Cary Clark8032b982017-07-28 11:04:54 -04003782
3783#Method void drawImage(const SkImage* image, SkScalar left, SkScalar top, const SkPaint* paint = NULL)
3784
3785Draw Image image, with its top-left corner at (left, top),
3786using Clip, Matrix, and optional Paint paint.
3787
Cary Clarkbad5ad72017-08-03 17:14:08 -04003788If paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter, Blend_Mode,
3789and Draw_Looper. If image is kAlpha_8_SkColorType, apply Shader.
3790If paint contains Mask_Filter, generate mask from image bounds. If generated
3791mask extends beyond image bounds, replicate image edge colors, just as Shader
3792made from SkImage::makeShader with SkShader::kClamp_TileMode set replicates the
3793image's edge color when it samples outside of its bounds.
Cary Clark8032b982017-07-28 11:04:54 -04003794
Cary Clarkbad5ad72017-08-03 17:14:08 -04003795#Param image uncompressed rectangular map of pixels ##
3796#Param left left side of image ##
3797#Param top top side of image ##
3798#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
3799 and so on; or nullptr
3800##
Cary Clark8032b982017-07-28 11:04:54 -04003801
3802#Example
3803#Height 64
3804#Image 4
Cary Clarkbad5ad72017-08-03 17:14:08 -04003805void draw(SkCanvas* canvas) {
3806 // sk_sp<SkImage> image;
3807 SkImage* imagePtr = image.get();
3808 canvas->drawImage(imagePtr, 0, 0);
3809 SkPaint paint;
3810 canvas->drawImage(imagePtr, 80, 0, &paint);
3811 paint.setAlpha(0x80);
3812 canvas->drawImage(imagePtr, 160, 0, &paint);
Cary Clark8032b982017-07-28 11:04:54 -04003813}
3814##
3815
3816#ToDo incomplete ##
3817
3818##
3819
3820# ------------------------------------------------------------------------------
3821
3822#Method void drawImage(const sk_sp<SkImage>& image, SkScalar left, SkScalar top,
3823 const SkPaint* paint = NULL)
3824
3825Draw Image image, with its top-left corner at (left, top),
3826using Clip, Matrix, and optional Paint paint.
3827
Cary Clarkbad5ad72017-08-03 17:14:08 -04003828If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
3829Blend_Mode, and Draw_Looper. If image is kAlpha_8_SkColorType, apply Shader.
3830If paint contains Mask_Filter, generate mask from image bounds. If generated
3831mask extends beyond image bounds, replicate image edge colors, just as Shader
3832made from SkImage::makeShader with SkShader::kClamp_TileMode set replicates the
3833image's edge color when it samples outside of its bounds.
Cary Clark8032b982017-07-28 11:04:54 -04003834
Cary Clarkbad5ad72017-08-03 17:14:08 -04003835#Param image uncompressed rectangular map of pixels ##
3836#Param left left side of image ##
3837#Param top pop side of image ##
3838#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
3839 and so on; or nullptr
3840##
Cary Clark8032b982017-07-28 11:04:54 -04003841
3842#Example
3843#Height 64
3844#Image 4
Cary Clarkbad5ad72017-08-03 17:14:08 -04003845void draw(SkCanvas* canvas) {
3846 // sk_sp<SkImage> image;
3847 canvas->drawImage(image, 0, 0);
3848 SkPaint paint;
3849 canvas->drawImage(image, 80, 0, &paint);
3850 paint.setAlpha(0x80);
3851 canvas->drawImage(image, 160, 0, &paint);
Cary Clark8032b982017-07-28 11:04:54 -04003852}
3853##
3854
3855#ToDo incomplete ##
3856
3857##
3858
3859# ------------------------------------------------------------------------------
3860
3861#Enum SrcRectConstraint
3862
3863#Code
3864 enum SrcRectConstraint {
3865 kStrict_SrcRectConstraint,
3866 kFast_SrcRectConstraint,
3867 };
3868##
3869
Cary Clarkbad5ad72017-08-03 17:14:08 -04003870SrcRectConstraint controls the behavior at the edge of the Rect src, provided to
3871drawImageRect, trading off speed for precision.
Cary Clark8032b982017-07-28 11:04:54 -04003872
Cary Clarkbad5ad72017-08-03 17:14:08 -04003873Image_Filter in Paint may sample multiple pixels in the image. Rect src
3874restricts the bounds of pixels that may be read. Image_Filter may slow down if
3875it cannot read outside the bounds, when sampling near the edge of Rect src.
Cary Clark8032b982017-07-28 11:04:54 -04003876SrcRectConstraint specifies whether an Image_Filter is allowed to read pixels
3877outside Rect src.
3878
3879#Const kStrict_SrcRectConstraint
3880 Requires Image_Filter to respect Rect src,
3881 sampling only inside of its bounds, possibly with a performance penalty.
3882##
3883
3884#Const kFast_SrcRectConstraint
3885 Permits Image_Filter to sample outside of Rect src
3886 by half the width of Image_Filter, permitting it to run faster but with
3887 error at the image edges.
3888##
3889
3890#Example
3891#Height 64
3892#Description
3893 redBorder contains a black and white checkerboard bordered by red.
3894 redBorder is drawn scaled by 16 on the left.
3895 The middle and right bitmaps are filtered checkboards.
3896 Drawing the checkerboard with kStrict_SrcRectConstraint shows only a blur of black and white.
3897 Drawing the checkerboard with kFast_SrcRectConstraint allows red to bleed in the corners.
3898##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003899void draw(SkCanvas* canvas) {
3900 SkBitmap redBorder;
3901 redBorder.allocPixels(SkImageInfo::MakeN32Premul(4, 4));
3902 SkCanvas checkRed(redBorder);
3903 checkRed.clear(SK_ColorRED);
3904 uint32_t checkers[][2] = { { SK_ColorBLACK, SK_ColorWHITE },
3905 { SK_ColorWHITE, SK_ColorBLACK } };
3906 checkRed.writePixels(
3907 SkImageInfo::MakeN32Premul(2, 2), (void*) checkers, sizeof(checkers[0]), 1, 1);
3908 canvas->scale(16, 16);
3909 canvas->drawBitmap(redBorder, 0, 0, nullptr);
3910 canvas->resetMatrix();
3911 sk_sp<SkImage> image = SkImage::MakeFromBitmap(redBorder);
3912 SkPaint lowPaint;
3913 lowPaint.setFilterQuality(kLow_SkFilterQuality);
3914 for (auto constraint : { SkCanvas::kStrict_SrcRectConstraint,
3915 SkCanvas::kFast_SrcRectConstraint } ) {
3916 canvas->translate(80, 0);
3917 canvas->drawImageRect(image.get(), SkRect::MakeLTRB(1, 1, 3, 3),
3918 SkRect::MakeLTRB(16, 16, 48, 48), &lowPaint, constraint);
3919 }
Cary Clark8032b982017-07-28 11:04:54 -04003920}
3921##
3922
3923#ToDo incomplete ##
3924
3925##
3926
3927# ------------------------------------------------------------------------------
3928
3929#Method void drawImageRect(const SkImage* image, const SkRect& src, const SkRect& dst,
3930 const SkPaint* paint,
3931 SrcRectConstraint constraint = kStrict_SrcRectConstraint)
3932
3933Draw Rect src of Image image, scaled and translated to fill Rect dst.
3934Additionally transform draw using Clip, Matrix, and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04003935
Cary Clarkbad5ad72017-08-03 17:14:08 -04003936If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
3937Blend_Mode, and Draw_Looper. If image is kAlpha_8_SkColorType, apply Shader.
3938If paint contains Mask_Filter, generate mask from image bounds.
3939
3940If generated mask extends beyond image bounds, replicate image edge colors, just
3941as Shader made from SkImage::makeShader with SkShader::kClamp_TileMode set
3942replicates the image's edge color when it samples outside of its bounds.
3943
3944constraint set to kStrict_SrcRectConstraint limits Paint Filter_Quality to
3945sample within src; set to kFast_SrcRectConstraint allows sampling outside to
3946improve performance.
3947
3948#Param image Image containing pixels, dimensions, and format ##
3949#Param src source Rect of image to draw from ##
3950#Param dst destination Rect of image to draw to ##
3951#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
3952 and so on; or nullptr
3953##
3954#Param constraint filter strictly within src or draw faster ##
Cary Clark8032b982017-07-28 11:04:54 -04003955
3956#Example
3957#Height 64
3958#Description
3959 The left bitmap draws with Paint default kNone_SkFilterQuality, and stays within
3960 its bounds; there's no bleeding with kFast_SrcRectConstraint.
3961 the middle and right bitmaps draw with kLow_SkFilterQuality; with
3962 kStrict_SrcRectConstraint, the filter remains within the checkerboard, and
3963 with kFast_SrcRectConstraint red bleeds on the edges.
3964##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003965void draw(SkCanvas* canvas) {
3966 uint32_t pixels[][4] = {
3967 { 0xFFFF0000, 0xFFFF0000, 0xFFFF0000, 0xFFFF0000 },
3968 { 0xFFFF0000, 0xFF000000, 0xFFFFFFFF, 0xFFFF0000 },
3969 { 0xFFFF0000, 0xFFFFFFFF, 0xFF000000, 0xFFFF0000 },
3970 { 0xFFFF0000, 0xFFFF0000, 0xFFFF0000, 0xFFFF0000 } };
3971 SkBitmap redBorder;
3972 redBorder.installPixels(SkImageInfo::MakeN32Premul(4, 4),
3973 (void*) pixels, sizeof(pixels[0]));
3974 sk_sp<SkImage> image = SkImage::MakeFromBitmap(redBorder);
3975 SkPaint lowPaint;
3976 for (auto constraint : {
3977 SkCanvas::kFast_SrcRectConstraint,
3978 SkCanvas::kStrict_SrcRectConstraint,
3979 SkCanvas::kFast_SrcRectConstraint } ) {
3980 canvas->drawImageRect(image.get(), SkRect::MakeLTRB(1, 1, 3, 3),
3981 SkRect::MakeLTRB(16, 16, 48, 48), &lowPaint, constraint);
3982 lowPaint.setFilterQuality(kLow_SkFilterQuality);
3983 canvas->translate(80, 0);
3984 }
3985}
Cary Clark8032b982017-07-28 11:04:54 -04003986##
3987
3988#ToDo incomplete ##
3989
3990##
3991
3992# ------------------------------------------------------------------------------
3993
3994#Method void drawImageRect(const SkImage* image, const SkIRect& isrc, const SkRect& dst,
3995 const SkPaint* paint, SrcRectConstraint constraint = kStrict_SrcRectConstraint)
3996
3997Draw IRect isrc of Image image, scaled and translated to fill Rect dst.
Cary Clarkbad5ad72017-08-03 17:14:08 -04003998Note that isrc is on integer pixel boundaries; dst may include fractional
3999boundaries. Additionally transform draw using Clip, Matrix, and optional Paint
4000paint.
Cary Clark8032b982017-07-28 11:04:54 -04004001
Cary Clarkbad5ad72017-08-03 17:14:08 -04004002If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4003Blend_Mode, and Draw_Looper. If image is kAlpha_8_SkColorType, apply Shader.
4004If paint contains Mask_Filter, generate mask from image bounds.
4005
4006If generated mask extends beyond image bounds, replicate image edge colors, just
4007as Shader made from SkImage::makeShader with SkShader::kClamp_TileMode set
4008replicates the image's edge color when it samples outside of its bounds.
4009
4010constraint set to kStrict_SrcRectConstraint limits Paint Filter_Quality to
4011sample within src; set to kFast_SrcRectConstraint allows sampling outside to
4012improve performance.
4013
4014#Param image Image containing pixels, dimensions, and format ##
4015#Param isrc source IRect of image to draw from ##
4016#Param dst destination Rect of image to draw to ##
4017#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4018 and so on; or nullptr
4019##
4020#Param constraint filter strictly within src or draw faster ##
Cary Clark8032b982017-07-28 11:04:54 -04004021
4022#Example
4023#Image 4
Cary Clarkbad5ad72017-08-03 17:14:08 -04004024void draw(SkCanvas* canvas) {
4025 // sk_sp<SkImage> image;
4026 for (auto i : { 1, 2, 4, 8 } ) {
4027 canvas->drawImageRect(image.get(), SkIRect::MakeLTRB(0, 0, 100, 100),
4028 SkRect::MakeXYWH(i * 20, i * 20, i * 20, i * 20), nullptr);
4029 }
Cary Clark8032b982017-07-28 11:04:54 -04004030}
4031##
4032
4033#ToDo incomplete ##
4034
4035##
4036
4037# ------------------------------------------------------------------------------
4038
4039#Method void drawImageRect(const SkImage* image, const SkRect& dst, const SkPaint* paint,
4040 SrcRectConstraint constraint = kStrict_SrcRectConstraint)
4041
Cary Clarkbad5ad72017-08-03 17:14:08 -04004042Draw Image image, scaled and translated to fill Rect dst, using Clip, Matrix,
4043and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004044
Cary Clarkbad5ad72017-08-03 17:14:08 -04004045If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4046Blend_Mode, and Draw_Looper. If image is kAlpha_8_SkColorType, apply Shader.
4047If paint contains Mask_Filter, generate mask from image bounds.
4048
4049If generated mask extends beyond image bounds, replicate image edge colors, just
4050as Shader made from SkImage::makeShader with SkShader::kClamp_TileMode set
4051replicates the image's edge color when it samples outside of its bounds.
4052
4053constraint set to kStrict_SrcRectConstraint limits Paint Filter_Quality to
4054sample within src; set to kFast_SrcRectConstraint allows sampling outside to
4055improve performance.
4056
4057#Param image Image containing pixels, dimensions, and format ##
4058#Param dst destination Rect of image to draw to ##
4059#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4060 and so on; or nullptr
4061##
4062#Param constraint filter strictly within src or draw faster ##
Cary Clark8032b982017-07-28 11:04:54 -04004063
4064#Example
4065#Image 4
Cary Clarkbad5ad72017-08-03 17:14:08 -04004066void draw(SkCanvas* canvas) {
4067 // sk_sp<SkImage> image;
4068 for (auto i : { 20, 40, 80, 160 } ) {
4069 canvas->drawImageRect(image.get(), SkRect::MakeXYWH(i, i, i, i), nullptr);
4070 }
Cary Clark8032b982017-07-28 11:04:54 -04004071}
4072##
4073
4074#ToDo incomplete ##
4075
4076##
4077
4078# ------------------------------------------------------------------------------
4079
4080#Method void drawImageRect(const sk_sp<SkImage>& image, const SkRect& src, const SkRect& dst,
4081 const SkPaint* paint,
4082 SrcRectConstraint constraint = kStrict_SrcRectConstraint)
4083
4084Draw Rect src of Image image, scaled and translated to fill Rect dst.
4085Additionally transform draw using Clip, Matrix, and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004086
Cary Clarkbad5ad72017-08-03 17:14:08 -04004087If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4088Blend_Mode, and Draw_Looper. If image is kAlpha_8_SkColorType, apply Shader.
4089If paint contains Mask_Filter, generate mask from image bounds.
4090
4091If generated mask extends beyond image bounds, replicate image edge colors, just
4092as Shader made from SkImage::makeShader with SkShader::kClamp_TileMode set
4093replicates the image's edge color when it samples outside of its bounds.
4094
4095constraint set to kStrict_SrcRectConstraint limits Paint Filter_Quality to
4096sample within src; set to kFast_SrcRectConstraint allows sampling outside to
4097improve performance.
4098
4099#Param image Image containing pixels, dimensions, and format ##
4100#Param src source Rect of image to draw from ##
4101#Param dst destination Rect of image to draw to ##
4102#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4103 and so on; or nullptr
4104##
4105#Param constraint filter strictly within src or draw faster ##
Cary Clark8032b982017-07-28 11:04:54 -04004106
4107#Example
4108#Height 64
4109#Description
4110 Canvas scales and translates; transformation from src to dst also scales.
4111 The two matrices are concatenated to create the final transformation.
4112##
Cary Clarkbad5ad72017-08-03 17:14:08 -04004113void draw(SkCanvas* canvas) {
4114 uint32_t pixels[][2] = { { SK_ColorBLACK, SK_ColorWHITE },
4115 { SK_ColorWHITE, SK_ColorBLACK } };
4116 SkBitmap bitmap;
4117 bitmap.installPixels(SkImageInfo::MakeN32Premul(2, 2),
4118 (void*) pixels, sizeof(pixels[0]));
4119 sk_sp<SkImage> image = SkImage::MakeFromBitmap(bitmap);
4120 SkPaint paint;
4121 canvas->scale(4, 4);
4122 for (auto alpha : { 50, 100, 150, 255 } ) {
4123 paint.setAlpha(alpha);
4124 canvas->drawImageRect(image, SkRect::MakeWH(2, 2), SkRect::MakeWH(8, 8), &paint);
4125 canvas->translate(8, 0);
4126 }
4127}
Cary Clark8032b982017-07-28 11:04:54 -04004128##
4129
4130#ToDo incomplete ##
4131
4132##
4133
4134# ------------------------------------------------------------------------------
4135
4136#Method void drawImageRect(const sk_sp<SkImage>& image, const SkIRect& isrc, const SkRect& dst,
4137 const SkPaint* paint, SrcRectConstraint constraint = kStrict_SrcRectConstraint)
4138
4139Draw IRect isrc of Image image, scaled and translated to fill Rect dst.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004140isrc is on integer pixel boundaries; dst may include fractional boundaries.
Cary Clark8032b982017-07-28 11:04:54 -04004141Additionally transform draw using Clip, Matrix, and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004142
Cary Clarkbad5ad72017-08-03 17:14:08 -04004143If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4144Blend_Mode, and Draw_Looper. If image is kAlpha_8_SkColorType, apply Shader.
4145If paint contains Mask_Filter, generate mask from image bounds.
4146
4147If generated mask extends beyond image bounds, replicate image edge colors, just
4148as Shader made from SkImage::makeShader with SkShader::kClamp_TileMode set
4149replicates the image's edge color when it samples outside of its bounds.
4150
4151constraint set to kStrict_SrcRectConstraint limits Paint Filter_Quality to
4152sample within src; set to kFast_SrcRectConstraint allows sampling outside to
4153improve performance.
4154
4155#Param image Image containing pixels, dimensions, and format ##
4156#Param isrc source IRect of image to draw from ##
4157#Param dst destination Rect of image to draw to ##
4158#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4159 and so on; or nullptr
4160##
4161#Param constraint filter strictly within src or draw faster ##
Cary Clark8032b982017-07-28 11:04:54 -04004162
4163#Example
4164#Height 64
Cary Clarkbad5ad72017-08-03 17:14:08 -04004165void draw(SkCanvas* canvas) {
4166 uint32_t pixels[][2] = { { 0x00000000, 0x55555555},
4167 { 0xAAAAAAAA, 0xFFFFFFFF} };
4168 SkBitmap bitmap;
4169 bitmap.installPixels(SkImageInfo::MakeN32Premul(2, 2),
4170 (void*) pixels, sizeof(pixels[0]));
4171 sk_sp<SkImage> image = SkImage::MakeFromBitmap(bitmap);
4172 SkPaint paint;
4173 canvas->scale(4, 4);
4174 for (auto color : { SK_ColorRED, SK_ColorBLUE, SK_ColorGREEN } ) {
4175 paint.setColorFilter(SkColorFilter::MakeModeFilter(color, SkBlendMode::kPlus));
4176 canvas->drawImageRect(image, SkIRect::MakeWH(2, 2), SkRect::MakeWH(8, 8), &paint);
4177 canvas->translate(8, 0);
4178 }
Cary Clark8032b982017-07-28 11:04:54 -04004179}
4180##
4181
4182#ToDo incomplete ##
4183##
4184
4185# ------------------------------------------------------------------------------
4186
4187#Method void drawImageRect(const sk_sp<SkImage>& image, const SkRect& dst, const SkPaint* paint,
4188 SrcRectConstraint constraint = kStrict_SrcRectConstraint)
4189
4190Draw Image image, scaled and translated to fill Rect dst,
4191using Clip, Matrix, and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004192
Cary Clarkbad5ad72017-08-03 17:14:08 -04004193If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4194Blend_Mode, and Draw_Looper. If image is kAlpha_8_SkColorType, apply Shader.
4195If paint contains Mask_Filter, generate mask from image bounds.
4196
4197If generated mask extends beyond image bounds, replicate image edge colors, just
4198as Shader made from SkImage::makeShader with SkShader::kClamp_TileMode set
4199replicates the image's edge color when it samples outside of its bounds.
4200
4201constraint set to kStrict_SrcRectConstraint limits Paint Filter_Quality to
4202sample within src; set to kFast_SrcRectConstraint allows sampling outside to
4203improve performance.
4204
4205#Param image Image containing pixels, dimensions, and format ##
4206#Param dst destination Rect of image to draw to ##
4207#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4208 and so on; or nullptr
4209##
4210#Param constraint filter strictly within src or draw faster ##
Cary Clark8032b982017-07-28 11:04:54 -04004211
4212#Example
4213#Height 64
Cary Clarkbad5ad72017-08-03 17:14:08 -04004214void draw(SkCanvas* canvas) {
4215 uint32_t pixels[][2] = { { 0x00000000, 0x55550000},
4216 { 0xAAAA0000, 0xFFFF0000} };
4217 SkBitmap bitmap;
4218 bitmap.installPixels(SkImageInfo::MakeN32Premul(2, 2),
4219 (void*) pixels, sizeof(pixels[0]));
4220 sk_sp<SkImage> image = SkImage::MakeFromBitmap(bitmap);
4221 SkPaint paint;
4222 canvas->scale(4, 4);
4223 for (auto color : { SK_ColorRED, SK_ColorBLUE, SK_ColorGREEN } ) {
4224 paint.setColorFilter(SkColorFilter::MakeModeFilter(color, SkBlendMode::kPlus));
4225 canvas->drawImageRect(image, SkRect::MakeWH(8, 8), &paint);
4226 canvas->translate(8, 0);
4227 }
Cary Clark8032b982017-07-28 11:04:54 -04004228}
4229##
4230
4231#ToDo incomplete ##
4232
4233##
4234
4235# ------------------------------------------------------------------------------
4236
4237#Method void drawImageNine(const SkImage* image, const SkIRect& center, const SkRect& dst,
4238 const SkPaint* paint = nullptr)
4239
4240Draw Image image stretched differentially to fit into Rect dst.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004241IRect center divides the image into nine sections: four sides, four corners, and
4242the center. Corners are unscaled or scaled down proportionately if their sides
4243are larger than dst; center and four sides are scaled to fit remaining space, if any.
Cary Clark8032b982017-07-28 11:04:54 -04004244
Cary Clarkbad5ad72017-08-03 17:14:08 -04004245Additionally transform draw using Clip, Matrix, and optional Paint paint.
4246
4247If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4248Blend_Mode, and Draw_Looper. If image is kAlpha_8_SkColorType, apply Shader.
4249If paint contains Mask_Filter, generate mask from image bounds.
4250
4251If generated mask extends beyond image bounds, replicate image edge colors, just
4252as Shader made from SkImage::makeShader with SkShader::kClamp_TileMode set
4253replicates the image's edge color when it samples outside of its bounds.
4254
4255#Param image Image containing pixels, dimensions, and format ##
4256#Param center IRect edge of image corners and sides ##
4257#Param dst destination Rect of image to draw to ##
4258#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4259 and so on; or nullptr
4260##
Cary Clark8032b982017-07-28 11:04:54 -04004261
4262#Example
4263#Height 128
4264#Description
4265 The leftmost image is smaller than center; only corners are drawn, all scaled to fit.
4266 The second image equals the size of center; only corners are drawn, unscaled.
4267 The remaining images are larger than center. All corners draw unscaled. The sides
4268 and center are scaled if needed to take up the remaining space.
4269##
Cary Clarkbad5ad72017-08-03 17:14:08 -04004270void draw(SkCanvas* canvas) {
4271 SkIRect center = { 20, 10, 50, 40 };
4272 SkBitmap bitmap;
4273 bitmap.allocPixels(SkImageInfo::MakeN32Premul(60, 60));
4274 SkCanvas bitCanvas(bitmap);
4275 SkPaint paint;
4276 SkColor gray = 0xFF000000;
4277 int left = 0;
4278 for (auto right: { center.fLeft, center.fRight, bitmap.width() } ) {
4279 int top = 0;
4280 for (auto bottom: { center.fTop, center.fBottom, bitmap.height() } ) {
4281 paint.setColor(gray);
4282 bitCanvas.drawIRect(SkIRect::MakeLTRB(left, top, right, bottom), paint);
4283 gray += 0x001f1f1f;
4284 top = bottom;
4285 }
4286 left = right;
4287 }
4288 sk_sp<SkImage> image = SkImage::MakeFromBitmap(bitmap);
4289 SkImage* imagePtr = image.get();
4290 for (auto dest: { 20, 30, 40, 60, 90 } ) {
4291 canvas->drawImageNine(imagePtr, center, SkRect::MakeWH(dest, dest), nullptr);
4292 canvas->translate(dest + 4, 0);
4293 }
Cary Clark8032b982017-07-28 11:04:54 -04004294}
4295##
4296
4297#ToDo incomplete ##
4298
4299##
4300
4301# ------------------------------------------------------------------------------
4302
4303#Method void drawImageNine(const sk_sp<SkImage>& image, const SkIRect& center, const SkRect& dst,
4304 const SkPaint* paint = nullptr)
4305
4306Draw Image image stretched differentially to fit into Rect dst.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004307IRect center divides the image into nine sections: four sides, four corners, and
4308the center. Corners are unscaled or scaled down proportionately if their sides
4309are larger than dst; center and four sides are scaled to fit remaining space, if any.
Cary Clark8032b982017-07-28 11:04:54 -04004310
Cary Clarkbad5ad72017-08-03 17:14:08 -04004311Additionally transform draw using Clip, Matrix, and optional Paint paint.
4312
4313If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4314Blend_Mode, and Draw_Looper. If image is kAlpha_8_SkColorType, apply Shader.
4315If paint contains Mask_Filter, generate mask from image bounds.
4316
4317If generated mask extends beyond image bounds, replicate image edge colors, just
4318as Shader made from SkImage::makeShader with SkShader::kClamp_TileMode set
4319replicates the image's edge color when it samples outside of its bounds.
4320
4321#Param image Image containing pixels, dimensions, and format ##
4322#Param center IRect edge of image corners and sides ##
4323#Param dst destination Rect of image to draw to ##
4324#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4325 and so on; or nullptr
4326##
Cary Clark8032b982017-07-28 11:04:54 -04004327
4328#Example
4329#Height 128
4330#Description
4331 The two leftmost images has four corners and sides to the left and right of center.
4332 The leftmost image scales the width of corners proportionately to fit.
4333 The third and fourth image corners are unscaled; the sides and center are scaled to
4334 fill the remaining space.
4335 The rightmost image has four corners scaled vertically to fit, and uses sides above
4336 and below center to fill the remaining space.
4337##
Cary Clarkbad5ad72017-08-03 17:14:08 -04004338void draw(SkCanvas* canvas) {
4339 SkIRect center = { 20, 10, 50, 40 };
4340 SkBitmap bitmap;
4341 bitmap.allocPixels(SkImageInfo::MakeN32Premul(60, 60));
4342 SkCanvas bitCanvas(bitmap);
4343 SkPaint paint;
4344 SkColor gray = 0xFF000000;
4345 int left = 0;
4346 for (auto right: { center.fLeft, center.fRight, bitmap.width() } ) {
4347 int top = 0;
4348 for (auto bottom: { center.fTop, center.fBottom, bitmap.height() } ) {
4349 paint.setColor(gray);
4350 bitCanvas.drawIRect(SkIRect::MakeLTRB(left, top, right, bottom), paint);
4351 gray += 0x001f1f1f;
4352 top = bottom;
4353 }
4354 left = right;
4355 }
4356 sk_sp<SkImage> image = SkImage::MakeFromBitmap(bitmap);
4357 for (auto dest: { 20, 30, 40, 60, 90 } ) {
4358 canvas->drawImageNine(image, center, SkRect::MakeWH(dest, 110 - dest), nullptr);
4359 canvas->translate(dest + 4, 0);
4360 }
Cary Clark8032b982017-07-28 11:04:54 -04004361}
4362##
4363
4364#ToDo incomplete ##
4365
4366##
4367
4368# ------------------------------------------------------------------------------
4369
4370#Method void drawBitmap(const SkBitmap& bitmap, SkScalar left, SkScalar top,
4371 const SkPaint* paint = NULL)
4372
4373Draw Bitmap bitmap, with its top-left corner at (left, top),
4374using Clip, Matrix, and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004375
Cary Clarkbad5ad72017-08-03 17:14:08 -04004376If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4377Blend_Mode, and Draw_Looper. If bitmap is kAlpha_8_SkColorType, apply Shader.
4378If paint contains Mask_Filter, generate mask from bitmap bounds.
4379
4380If generated mask extends beyond bitmap bounds, replicate bitmap edge colors,
4381just as Shader made from SkShader::MakeBitmapShader with
4382SkShader::kClamp_TileMode set replicates the bitmap's edge color when it samples
4383outside of its bounds.
4384
4385#Param bitmap Bitmap containing pixels, dimensions, and format ##
4386#Param left left side of bitmap ##
4387#Param top top side of bitmap ##
4388#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4389 and so on; or nullptr
4390##
Cary Clark8032b982017-07-28 11:04:54 -04004391
4392#Example
4393#Height 64
Cary Clarkbad5ad72017-08-03 17:14:08 -04004394void draw(SkCanvas* canvas) {
4395 uint8_t pixels[][8] = { { 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00},
4396 { 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00},
4397 { 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00},
4398 { 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF},
4399 { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
4400 { 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00},
4401 { 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0x00},
4402 { 0xFF, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0xFF} };
4403 SkBitmap bitmap;
4404 bitmap.installPixels(SkImageInfo::MakeA8(8, 8),
4405 (void*) pixels, sizeof(pixels[0]));
4406 SkPaint paint;
4407 canvas->scale(4, 4);
4408 for (auto color : { SK_ColorRED, SK_ColorBLUE, 0xFF007F00} ) {
4409 paint.setColor(color);
4410 canvas->drawBitmap(bitmap, 0, 0, &paint);
4411 canvas->translate(12, 0);
4412 }
Cary Clark8032b982017-07-28 11:04:54 -04004413}
4414##
4415
4416#ToDo incomplete ##
4417
4418##
4419
4420# ------------------------------------------------------------------------------
4421
4422#Method void drawBitmapRect(const SkBitmap& bitmap, const SkRect& src, const SkRect& dst,
4423 const SkPaint* paint, SrcRectConstraint constraint = kStrict_SrcRectConstraint)
4424
4425Draw Rect src of Bitmap bitmap, scaled and translated to fill Rect dst.
4426Additionally transform draw using Clip, Matrix, and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004427
Cary Clarkbad5ad72017-08-03 17:14:08 -04004428If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4429Blend_Mode, and Draw_Looper. If bitmap is kAlpha_8_SkColorType, apply Shader.
4430If paint contains Mask_Filter, generate mask from bitmap bounds.
4431
4432If generated mask extends beyond bitmap bounds, replicate bitmap edge colors,
4433just as Shader made from SkShader::MakeBitmapShader with
4434SkShader::kClamp_TileMode set replicates the bitmap's edge color when it samples
4435outside of its bounds.
4436
4437constraint set to kStrict_SrcRectConstraint limits Paint Filter_Quality to
4438sample within src; set to kFast_SrcRectConstraint allows sampling outside to
4439improve performance.
4440
4441#Param bitmap Bitmap containing pixels, dimensions, and format ##
4442#Param src source Rect of image to draw from ##
4443#Param dst destination Rect of image to draw to ##
4444#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4445 and so on; or nullptr
4446##
4447#Param constraint filter strictly within src or draw faster ##
Cary Clark8032b982017-07-28 11:04:54 -04004448
4449#Example
4450#Height 64
Cary Clarkbad5ad72017-08-03 17:14:08 -04004451void draw(SkCanvas* canvas) {
4452 uint8_t pixels[][8] = { { 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00},
4453 { 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00},
4454 { 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00},
4455 { 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF},
4456 { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
4457 { 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00},
4458 { 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00},
4459 { 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00} };
4460 SkBitmap bitmap;
4461 bitmap.installPixels(SkImageInfo::MakeA8(8, 8),
4462 (void*) pixels, sizeof(pixels[0]));
4463 SkPaint paint;
4464 paint.setMaskFilter(SkBlurMaskFilter::Make(kSolid_SkBlurStyle, 6));
4465 for (auto color : { SK_ColorRED, SK_ColorBLUE, 0xFF007F00} ) {
4466 paint.setColor(color);
4467 canvas->drawBitmapRect(bitmap, SkRect::MakeWH(8, 8), SkRect::MakeWH(32, 32), &paint);
4468 canvas->translate(48, 0);
4469 }
Cary Clark8032b982017-07-28 11:04:54 -04004470}
4471##
4472
4473#ToDo incomplete ##
4474
4475##
4476
4477# ------------------------------------------------------------------------------
4478
4479#Method void drawBitmapRect(const SkBitmap& bitmap, const SkIRect& isrc, const SkRect& dst,
4480 const SkPaint* paint, SrcRectConstraint constraint = kStrict_SrcRectConstraint)
4481
4482Draw IRect isrc of Bitmap bitmap, scaled and translated to fill Rect dst.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004483isrc is on integer pixel boundaries; dst may include fractional boundaries.
Cary Clark8032b982017-07-28 11:04:54 -04004484Additionally transform draw using Clip, Matrix, and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004485
Cary Clarkbad5ad72017-08-03 17:14:08 -04004486If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4487Blend_Mode, and Draw_Looper. If bitmap is kAlpha_8_SkColorType, apply Shader.
4488If paint contains Mask_Filter, generate mask from bitmap bounds.
4489
4490If generated mask extends beyond bitmap bounds, replicate bitmap edge colors,
4491just as Shader made from SkShader::MakeBitmapShader with
4492SkShader::kClamp_TileMode set replicates the bitmap's edge color when it samples
4493outside of its bounds.
4494
4495constraint set to kStrict_SrcRectConstraint limits Paint Filter_Quality to
4496sample within src; set to kFast_SrcRectConstraint allows sampling outside to
4497improve performance.
4498
4499#Param bitmap Bitmap containing pixels, dimensions, and format ##
4500#Param isrc source IRect of image to draw from ##
4501#Param dst destination Rect of image to draw to ##
4502#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4503 and so on; or nullptr
4504##
4505#Param constraint Filter strictly within src or draw faster ##
Cary Clark8032b982017-07-28 11:04:54 -04004506
4507#Example
4508#Height 64
Cary Clarkbad5ad72017-08-03 17:14:08 -04004509void draw(SkCanvas* canvas) {
4510 uint8_t pixels[][8] = { { 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00},
4511 { 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00},
4512 { 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0xFF},
4513 { 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0xFF},
4514 { 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF},
4515 { 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF},
4516 { 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00},
4517 { 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00} };
4518 SkBitmap bitmap;
4519 bitmap.installPixels(SkImageInfo::MakeA8(8, 8),
4520 (void*) pixels, sizeof(pixels[0]));
4521 SkPaint paint;
4522 paint.setFilterQuality(kHigh_SkFilterQuality);
4523 for (auto color : { SK_ColorRED, SK_ColorBLUE, 0xFF007F00, 0xFF7f007f} ) {
4524 paint.setColor(color);
4525 canvas->drawBitmapRect(bitmap, SkIRect::MakeWH(8, 8), SkRect::MakeWH(32, 32), &paint);
4526 canvas->translate(48.25f, 0);
4527 }
Cary Clark8032b982017-07-28 11:04:54 -04004528}
4529##
4530
4531#ToDo incomplete ##
4532
4533##
4534
4535# ------------------------------------------------------------------------------
4536
4537#Method void drawBitmapRect(const SkBitmap& bitmap, const SkRect& dst, const SkPaint* paint,
4538 SrcRectConstraint constraint = kStrict_SrcRectConstraint)
4539
4540Draw Bitmap bitmap, scaled and translated to fill Rect dst.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004541isrc is on integer pixel boundaries; dst may include fractional boundaries.
Cary Clark8032b982017-07-28 11:04:54 -04004542Additionally transform draw using Clip, Matrix, and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004543
Cary Clarkbad5ad72017-08-03 17:14:08 -04004544If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4545Blend_Mode, and Draw_Looper. If bitmap is kAlpha_8_SkColorType, apply Shader.
4546If paint contains Mask_Filter, generate mask from bitmap bounds.
4547
4548If generated mask extends beyond bitmap bounds, replicate bitmap edge colors,
4549just as Shader made from SkShader::MakeBitmapShader with
4550SkShader::kClamp_TileMode set replicates the bitmap's edge color when it samples
4551outside of its bounds.
4552
4553constraint set to kStrict_SrcRectConstraint limits Paint Filter_Quality to
4554sample within src; set to kFast_SrcRectConstraint allows sampling outside to
4555improve performance.
4556
4557#Param bitmap Bitmap containing pixels, dimensions, and format ##
4558#Param dst destination Rect of image to draw to ##
4559#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4560 and so on; or nullptr
4561##
4562#Param constraint filter strictly within src or draw faster ##
Cary Clark8032b982017-07-28 11:04:54 -04004563
4564#Example
4565#Height 64
Cary Clarkbad5ad72017-08-03 17:14:08 -04004566void draw(SkCanvas* canvas) {
4567 uint32_t pixels[][2] = { { 0x00000000, 0x55550000},
4568 { 0xAAAA0000, 0xFFFF0000} };
4569 SkBitmap bitmap;
4570 bitmap.installPixels(SkImageInfo::MakeN32Premul(2, 2),
4571 (void*) pixels, sizeof(pixels[0]));
4572 SkPaint paint;
4573 canvas->scale(4, 4);
4574 for (auto color : { SK_ColorRED, SK_ColorBLUE, SK_ColorGREEN } ) {
4575 paint.setColorFilter(SkColorFilter::MakeModeFilter(color, SkBlendMode::kPlus));
4576 canvas->drawBitmapRect(bitmap, SkRect::MakeWH(8, 8), &paint);
4577 canvas->translate(8, 0);
4578 }
Cary Clark8032b982017-07-28 11:04:54 -04004579}
4580##
4581
4582#ToDo incomplete ##
4583
4584##
4585
4586# ------------------------------------------------------------------------------
4587
4588#Method void drawBitmapNine(const SkBitmap& bitmap, const SkIRect& center, const SkRect& dst,
4589 const SkPaint* paint = NULL)
4590
4591Draw Bitmap bitmap stretched differentially to fit into Rect dst.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004592IRect center divides the bitmap into nine sections: four sides, four corners,
4593and the center. Corners are unscaled or scaled down proportionately if their
4594sides are larger than dst; center and four sides are scaled to fit remaining
4595space, if any.
Cary Clark8032b982017-07-28 11:04:54 -04004596
Cary Clarkbad5ad72017-08-03 17:14:08 -04004597Additionally transform draw using Clip, Matrix, and optional Paint paint.
4598
4599If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4600Blend_Mode, and Draw_Looper. If bitmap is kAlpha_8_SkColorType, apply Shader.
4601If paint contains Mask_Filter, generate mask from bitmap bounds.
4602
4603If generated mask extends beyond bitmap bounds, replicate bitmap edge colors,
4604just as Shader made from SkShader::MakeBitmapShader with
4605SkShader::kClamp_TileMode set replicates the bitmap's edge color when it samples
4606outside of its bounds.
4607
4608#Param bitmap Bitmap containing pixels, dimensions, and format ##
4609#Param center IRect edge of image corners and sides ##
4610#Param dst destination Rect of image to draw to ##
4611#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4612 and so on; or nullptr
4613##
Cary Clark8032b982017-07-28 11:04:54 -04004614
4615#Example
4616#Height 128
4617#Description
4618 The two leftmost bitmap draws has four corners and sides to the left and right of center.
4619 The leftmost bitmap draw scales the width of corners proportionately to fit.
4620 The third and fourth draw corners are unscaled; the sides and center are scaled to
4621 fill the remaining space.
4622 The rightmost bitmap draw has four corners scaled vertically to fit, and uses sides above
4623 and below center to fill the remaining space.
4624##
Cary Clarkbad5ad72017-08-03 17:14:08 -04004625void draw(SkCanvas* canvas) {
4626 SkIRect center = { 20, 10, 50, 40 };
4627 SkBitmap bitmap;
4628 bitmap.allocPixels(SkImageInfo::MakeN32Premul(60, 60));
4629 SkCanvas bitCanvas(bitmap);
4630 SkPaint paint;
4631 SkColor gray = 0xFF000000;
4632 int left = 0;
4633 for (auto right: { center.fLeft, center.fRight, bitmap.width() } ) {
4634 int top = 0;
4635 for (auto bottom: { center.fTop, center.fBottom, bitmap.height() } ) {
4636 paint.setColor(gray);
4637 bitCanvas.drawIRect(SkIRect::MakeLTRB(left, top, right, bottom), paint);
4638 gray += 0x001f1f1f;
4639 top = bottom;
4640 }
4641 left = right;
4642 }
4643 for (auto dest: { 20, 30, 40, 60, 90 } ) {
4644 canvas->drawBitmapNine(bitmap, center, SkRect::MakeWH(dest, 110 - dest), nullptr);
4645 canvas->translate(dest + 4, 0);
4646 }
Cary Clark8032b982017-07-28 11:04:54 -04004647}
4648##
4649
4650#ToDo incomplete ##
4651
4652##
4653
4654# ------------------------------------------------------------------------------
4655#Struct Lattice
4656
4657 Lattice divides Bitmap or Image into a rectangular grid.
4658 Grid entries on even columns and even rows are fixed; these entries are
4659 always drawn at their original size if the destination is large enough.
4660 If the destination side is too small to hold the fixed entries, all fixed
4661 entries are proportionately scaled down to fit.
4662 The grid entries not on even columns and rows are scaled to fit the
4663 remaining space, if any.
4664
4665#Code
4666 struct Lattice {
4667 enum Flags {...
4668
4669 const int* fXDivs;
4670 const int* fYDivs;
4671 const Flags* fFlags;
4672 int fXCount;
4673 int fYCount;
4674 const SkIRect* fBounds;
4675 };
4676##
4677
4678 #Enum Flags
4679 #Code
4680 enum Flags : uint8_t {
4681 kTransparent_Flags = 1 << 0,
4682 };
4683 ##
4684
4685 Optional setting per rectangular grid entry to make it transparent.
4686
4687 #Const kTransparent_Flags 1
4688 Set to skip lattice rectangle by making it transparent.
4689 ##
4690 ##
4691
4692 #Member const int* fXDivs
4693 Array of x-coordinates that divide the bitmap vertically.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004694 Array entries must be unique, increasing, greater than or equal to
4695 fBounds left edge, and less than fBounds right edge.
4696 Set the first element to fBounds left to collapse the left column of
4697 fixed grid entries.
Cary Clark8032b982017-07-28 11:04:54 -04004698 ##
4699
4700 #Member const int* fYDivs
4701 Array of y-coordinates that divide the bitmap horizontally.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004702 Array entries must be unique, increasing, greater than or equal to
4703 fBounds top edge, and less than fBounds bottom edge.
4704 Set the first element to fBounds top to collapse the top row of fixed
4705 grid entries.
Cary Clark8032b982017-07-28 11:04:54 -04004706 ##
4707
4708 #Member const Flags* fFlags
4709 Optional array of Flags, one per rectangular grid entry:
Cary Clarkbad5ad72017-08-03 17:14:08 -04004710 array length must be
4711 #Formula
4712 (fXCount + 1) * (fYCount + 1)
4713 ##
4714 .
Cary Clark8032b982017-07-28 11:04:54 -04004715 Array entries correspond to the rectangular grid entries, ascending
4716 left to right and then top to bottom.
4717 ##
4718
4719 #Member int fXCount
Cary Clarkbad5ad72017-08-03 17:14:08 -04004720 Number of entries in fXDivs array; one less than the number of
4721 horizontal divisions.
Cary Clark8032b982017-07-28 11:04:54 -04004722 ##
4723
4724 #Member int fYCount
Cary Clarkbad5ad72017-08-03 17:14:08 -04004725 Number of entries in fYDivs array; one less than the number of vertical
4726 divisions.
Cary Clark8032b982017-07-28 11:04:54 -04004727 ##
4728
4729 #Member const SkIRect* fBounds
4730 Optional subset IRect source to draw from.
4731 If nullptr, source bounds is dimensions of Bitmap or Image.
4732 ##
4733
4734#Struct Lattice ##
4735
4736#Method void drawBitmapLattice(const SkBitmap& bitmap, const Lattice& lattice, const SkRect& dst,
4737 const SkPaint* paint = nullptr)
4738
4739Draw Bitmap bitmap stretched differentially to fit into Rect dst.
4740
4741Lattice lattice divides bitmap into a rectangular grid.
4742Each intersection of an even-numbered row and column is fixed; like the corners
Cary Clarkbad5ad72017-08-03 17:14:08 -04004743of drawBitmapNine, fixed lattice elements never scale larger than their initial
4744size and shrink proportionately when all fixed elements exceed the bitmap's
4745dimension. All other grid elements scale to fill the available space, if any.
Cary Clark8032b982017-07-28 11:04:54 -04004746
4747Additionally transform draw using Clip, Matrix, and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004748
Cary Clarkbad5ad72017-08-03 17:14:08 -04004749If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4750Blend_Mode, and Draw_Looper. If bitmap is kAlpha_8_SkColorType, apply Shader.
4751If paint contains Mask_Filter, generate mask from bitmap bounds.
4752
4753If generated mask extends beyond bitmap bounds, replicate bitmap edge colors,
4754just as Shader made from SkShader::MakeBitmapShader with
4755SkShader::kClamp_TileMode set replicates the bitmap's edge color when it samples
4756outside of its bounds.
4757
4758#Param bitmap Bitmap containing pixels, dimensions, and format ##
4759#Param lattice division of bitmap into fixed and variable rectangles ##
4760#Param dst destination Rect of image to draw to ##
4761#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4762 and so on; or nullptr
4763##
Cary Clark8032b982017-07-28 11:04:54 -04004764
4765#Example
4766#Height 128
4767#Description
4768 The two leftmost bitmap draws has four corners and sides to the left and right of center.
4769 The leftmost bitmap draw scales the width of corners proportionately to fit.
4770 The third and fourth draw corners are unscaled; the sides are scaled to
4771 fill the remaining space; the center is transparent.
4772 The rightmost bitmap draw has four corners scaled vertically to fit, and uses sides above
4773 and below center to fill the remaining space.
4774##
Cary Clarkbad5ad72017-08-03 17:14:08 -04004775void draw(SkCanvas* canvas) {
4776 SkIRect center = { 20, 10, 50, 40 };
4777 SkBitmap bitmap;
4778 bitmap.allocPixels(SkImageInfo::MakeN32Premul(60, 60));
4779 SkCanvas bitCanvas(bitmap);
4780 SkPaint paint;
4781 SkColor gray = 0xFF000000;
4782 int left = 0;
4783 for (auto right: { center.fLeft, center.fRight, bitmap.width() } ) {
4784 int top = 0;
4785 for (auto bottom: { center.fTop, center.fBottom, bitmap.height() } ) {
4786 paint.setColor(gray);
4787 bitCanvas.drawIRect(SkIRect::MakeLTRB(left, top, right, bottom), paint);
4788 gray += 0x001f1f1f;
4789 top = bottom;
4790 }
4791 left = right;
4792 }
4793 const int xDivs[] = { center.fLeft, center.fRight };
4794 const int yDivs[] = { center.fTop, center.fBottom };
4795 SkCanvas::Lattice::Flags flags[3][3];
4796 memset(flags, 0, sizeof(flags));
4797 flags[1][1] = SkCanvas::Lattice::kTransparent_Flags;
4798 SkCanvas::Lattice lattice = { xDivs, yDivs, flags[0], SK_ARRAY_COUNT(xDivs),
4799 SK_ARRAY_COUNT(yDivs), nullptr };
4800 for (auto dest: { 20, 30, 40, 60, 90 } ) {
4801 canvas->drawBitmapLattice(bitmap, lattice , SkRect::MakeWH(dest, 110 - dest), nullptr);
4802 canvas->translate(dest + 4, 0);
4803 }
Cary Clark8032b982017-07-28 11:04:54 -04004804}
4805##
4806
4807#ToDo incomplete ##
4808
4809##
4810
4811# ------------------------------------------------------------------------------
4812
4813#Method void drawImageLattice(const SkImage* image, const Lattice& lattice, const SkRect& dst,
4814 const SkPaint* paint = nullptr)
4815
4816Draw Image image stretched differentially to fit into Rect dst.
4817
4818Lattice lattice divides image into a rectangular grid.
4819Each intersection of an even-numbered row and column is fixed; like the corners
Cary Clarkbad5ad72017-08-03 17:14:08 -04004820of drawBitmapNine, fixed lattice elements never scale larger than their initial
4821size and shrink proportionately when all fixed elements exceed the bitmap's
4822dimension. All other grid elements scale to fill the available space, if any.
Cary Clark8032b982017-07-28 11:04:54 -04004823
4824Additionally transform draw using Clip, Matrix, and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004825
Cary Clarkbad5ad72017-08-03 17:14:08 -04004826If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4827Blend_Mode, and Draw_Looper. If bitmap is kAlpha_8_SkColorType, apply Shader.
4828If paint contains Mask_Filter, generate mask from bitmap bounds.
4829
4830If generated mask extends beyond bitmap bounds, replicate bitmap edge colors,
4831just as Shader made from SkShader::MakeBitmapShader with
4832SkShader::kClamp_TileMode set replicates the bitmap's edge color when it samples
4833outside of its bounds.
4834
4835#Param image Image containing pixels, dimensions, and format ##
4836#Param lattice division of bitmap into fixed and variable rectangles ##
4837#Param dst destination Rect of image to draw to ##
4838#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4839 and so on; or nullptr
4840##
Cary Clark8032b982017-07-28 11:04:54 -04004841
4842#Example
4843#Height 128
4844#Description
4845 The leftmost image is smaller than center; only corners are drawn, all scaled to fit.
4846 The second image equals the size of center; only corners are drawn, unscaled.
4847 The remaining images are larger than center. All corners draw unscaled. The sides
4848 are scaled if needed to take up the remaining space; the center is transparent.
4849##
Cary Clarkbad5ad72017-08-03 17:14:08 -04004850void draw(SkCanvas* canvas) {
4851 SkIRect center = { 20, 10, 50, 40 };
4852 SkBitmap bitmap;
4853 bitmap.allocPixels(SkImageInfo::MakeN32Premul(60, 60));
4854 SkCanvas bitCanvas(bitmap);
4855 SkPaint paint;
4856 SkColor gray = 0xFF000000;
4857 int left = 0;
4858 for (auto right: { center.fLeft, center.fRight, bitmap.width() } ) {
4859 int top = 0;
4860 for (auto bottom: { center.fTop, center.fBottom, bitmap.height() } ) {
4861 paint.setColor(gray);
4862 bitCanvas.drawIRect(SkIRect::MakeLTRB(left, top, right, bottom), paint);
4863 gray += 0x001f1f1f;
4864 top = bottom;
4865 }
4866 left = right;
4867 }
4868 const int xDivs[] = { center.fLeft, center.fRight };
4869 const int yDivs[] = { center.fTop, center.fBottom };
4870 SkCanvas::Lattice::Flags flags[3][3];
4871 memset(flags, 0, sizeof(flags));
4872 flags[1][1] = SkCanvas::Lattice::kTransparent_Flags;
4873 SkCanvas::Lattice lattice = { xDivs, yDivs, flags[0], SK_ARRAY_COUNT(xDivs),
4874 SK_ARRAY_COUNT(yDivs), nullptr };
4875 sk_sp<SkImage> image = SkImage::MakeFromBitmap(bitmap);
4876 SkImage* imagePtr = image.get();
4877 for (auto dest: { 20, 30, 40, 60, 90 } ) {
4878 canvas->drawImageNine(imagePtr, center, SkRect::MakeWH(dest, dest), nullptr);
4879 canvas->translate(dest + 4, 0);
4880 }
Cary Clark8032b982017-07-28 11:04:54 -04004881}
4882##
4883
4884#ToDo incomplete ##
4885
4886##
4887
4888#Topic Draw_Image ##
4889
4890# ------------------------------------------------------------------------------
4891
4892#Method void drawText(const void* text, size_t byteLength, SkScalar x, SkScalar y,
4893 const SkPaint& paint)
4894
4895Draw text, with origin at (x, y), using Clip, Matrix, and Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004896
Cary Clarkbad5ad72017-08-03 17:14:08 -04004897text's meaning depends on Paint_Text_Encoding; by default, text encoding is
4898UTF-8.
Cary Clark8032b982017-07-28 11:04:54 -04004899
Cary Clarkbad5ad72017-08-03 17:14:08 -04004900x and y meaning depends on Paint_Text_Align and Paint_Vertical_Text; by default
4901text draws left to right, positioning the first glyph's left side bearing at x
4902and its baseline at y. Text size is affected by Matrix and Paint_Text_Size.
4903
4904All elements of paint: Path_Effect, Rasterizer, Mask_Filter, Shader,
4905Color_Filter, Image_Filter, and Draw_Looper; apply to text. By default, draws
4906filled 12 point black glyphs.
4907
4908#Param text character code points or glyphs drawn ##
4909#Param byteLength byte length of text array ##
4910#Param x start of text on x-axis ##
4911#Param y start of text on y-axis ##
4912#Param paint text size, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04004913
4914#Example
4915#Height 200
4916#Description
4917 The same text is drawn varying Paint_Text_Size and varying
4918 Matrix.
4919##
Cary Clarkbad5ad72017-08-03 17:14:08 -04004920void draw(SkCanvas* canvas) {
4921 SkPaint paint;
4922 paint.setAntiAlias(true);
4923 float textSizes[] = { 12, 18, 24, 36 };
4924 for (auto size: textSizes ) {
4925 paint.setTextSize(size);
4926 canvas->drawText("Aa", 2, 10, 20, paint);
4927 canvas->translate(0, size * 2);
4928 }
4929 paint.reset();
4930 paint.setAntiAlias(true);
4931 float yPos = 20;
4932 for (auto size: textSizes ) {
4933 float scale = size / 12.f;
4934 canvas->resetMatrix();
4935 canvas->translate(100, 0);
4936 canvas->scale(scale, scale);
4937 canvas->drawText("Aa", 2, 10 / scale, yPos / scale, paint);
4938 yPos += size * 2;
4939 }
4940}
Cary Clark8032b982017-07-28 11:04:54 -04004941##
4942
4943#ToDo incomplete ##
4944
4945##
4946
4947#Method void drawString(const char* string, SkScalar x, SkScalar y, const SkPaint& paint)
4948
Cary Clarkbad5ad72017-08-03 17:14:08 -04004949Draw null terminated string, with origin at (x, y), using Clip, Matrix, and
4950Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004951
Cary Clarkbad5ad72017-08-03 17:14:08 -04004952string's meaning depends on Paint_Text_Encoding; by default, string encoding is
4953UTF-8. Other values of Paint_Text_Encoding are unlikely to produce the desired
4954results, since zero bytes may be embedded in the string.
Cary Clark8032b982017-07-28 11:04:54 -04004955
Cary Clarkbad5ad72017-08-03 17:14:08 -04004956x and y meaning depends on Paint_Text_Align and Paint_Vertical_Text; by default
4957string draws left to right, positioning the first glyph's left side bearing at x
4958and its baseline at y. Text size is affected by Matrix and Paint_Text_Size.
4959
4960All elements of paint: Path_Effect, Rasterizer, Mask_Filter, Shader,
4961Color_Filter, Image_Filter, and Draw_Looper; apply to text. By default, draws
4962filled 12 point black glyphs.
4963
4964#Param string character code points or glyphs drawn,
4965 ending with a char value of zero
4966##
4967#Param x start of string on x-axis ##
4968#Param y start of string on y-axis ##
4969#Param paint text size, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04004970
4971#Example
4972 SkPaint paint;
4973 canvas->drawString("a small hello", 20, 20, paint);
4974##
4975
4976#SeeAlso drawText
4977
4978##
4979
4980#Method void drawString(const SkString& string, SkScalar x, SkScalar y, const SkPaint& paint)
4981
Cary Clarkbad5ad72017-08-03 17:14:08 -04004982Draw null terminated string, with origin at (x, y), using Clip, Matrix, and
4983Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004984
Cary Clarkbad5ad72017-08-03 17:14:08 -04004985string's meaning depends on Paint_Text_Encoding; by default, string encoding is
4986UTF-8. Other values of Paint_Text_Encoding are unlikely to produce the desired
4987results, since zero bytes may be embedded in the string.
Cary Clark8032b982017-07-28 11:04:54 -04004988
Cary Clarkbad5ad72017-08-03 17:14:08 -04004989x and y meaning depends on Paint_Text_Align and Paint_Vertical_Text; by default
4990string draws left to right, positioning the first glyph's left side bearing at x
4991and its baseline at y. Text size is affected by Matrix and Paint_Text_Size.
4992
4993All elements of paint: Path_Effect, Rasterizer, Mask_Filter, Shader,
4994Color_Filter, Image_Filter, and Draw_Looper; apply to text. By default, draws
4995filled 12 point black glyphs.
4996
4997#Param string character code points or glyphs drawn,
4998 ending with a char value of zero
4999##
5000#Param x start of string on x-axis ##
5001#Param y start of string on y-axis ##
5002#Param paint text size, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005003
5004#Example
5005 SkPaint paint;
5006 SkString string("a small hello");
5007 canvas->drawString(string, 20, 20, paint);
5008##
5009
5010#SeeAlso drawText
5011
5012##
5013
5014# ------------------------------------------------------------------------------
5015
5016#Method void drawPosText(const void* text, size_t byteLength, const SkPoint pos[],
5017 const SkPaint& paint)
5018
Cary Clarkbad5ad72017-08-03 17:14:08 -04005019Draw each glyph in text with the origin in pos array, using Clip, Matrix, and
5020Paint paint. The number of entries in pos array must match the number of glyphs
5021described by byteLength of text.
Cary Clark8032b982017-07-28 11:04:54 -04005022
Cary Clarkbad5ad72017-08-03 17:14:08 -04005023text's meaning depends on Paint_Text_Encoding; by default, text encoding is
5024UTF-8. pos elements' meaning depends on Paint_Text_Align and Paint_Vertical_Text;
5025by default each glyph's left side bearing is positioned at x and its
5026baseline is positioned at y. Text size is affected by Matrix and
5027Paint_Text_Size.
Cary Clark8032b982017-07-28 11:04:54 -04005028
Cary Clarkbad5ad72017-08-03 17:14:08 -04005029All elements of paint: Path_Effect, Rasterizer, Mask_Filter, Shader,
5030Color_Filter, Image_Filter, and Draw_Looper; apply to text. By default, draws
5031filled 12 point black glyphs.
5032
5033Layout engines such as Harfbuzz typically position each glyph
Cary Clark8032b982017-07-28 11:04:54 -04005034rather than using the font's advance widths.
5035
Cary Clarkbad5ad72017-08-03 17:14:08 -04005036#Param text character code points or glyphs drawn ##
5037#Param byteLength byte length of text array ##
5038#Param pos array of glyph origins ##
5039#Param paint text size, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005040
5041#Example
5042#Height 120
Cary Clarkbad5ad72017-08-03 17:14:08 -04005043void draw(SkCanvas* canvas) {
5044 const char hello[] = "HeLLo!";
5045 const SkPoint pos[] = { {40, 100}, {82, 95}, {115, 110}, {130, 95}, {145, 85},
5046 {172, 100} };
5047 SkPaint paint;
5048 paint.setTextSize(60);
5049 canvas->drawPosText(hello, strlen(hello), pos, paint);
Cary Clark8032b982017-07-28 11:04:54 -04005050}
5051##
5052
5053#ToDo incomplete ##
5054
5055##
5056
5057# ------------------------------------------------------------------------------
5058
5059#Method void drawPosTextH(const void* text, size_t byteLength, const SkScalar xpos[], SkScalar constY,
5060 const SkPaint& paint)
5061
Cary Clarkbad5ad72017-08-03 17:14:08 -04005062Draw each glyph in text with its (x, y) origin composed from xpos array and
5063constY, using Clip, Matrix, and Paint paint. The number of entries in xpos array
5064must match the number of glyphs described by byteLength of text.
Cary Clark8032b982017-07-28 11:04:54 -04005065
Cary Clarkbad5ad72017-08-03 17:14:08 -04005066text's meaning depends on Paint_Text_Encoding; by default, text encoding is
5067UTF-8. pos elements' meaning depends on Paint_Text_Align and Paint_Vertical_Text;
5068by default each glyph's left side bearing is positioned at an xpos element and
5069its baseline is positioned at constY. Text size is affected by Matrix and
5070Paint_Text_Size.
Cary Clark8032b982017-07-28 11:04:54 -04005071
Cary Clarkbad5ad72017-08-03 17:14:08 -04005072All elements of paint: Path_Effect, Rasterizer, Mask_Filter, Shader,
5073Color_Filter, Image_Filter, and Draw_Looper; apply to text. By default, draws
5074filled 12 point black glyphs.
Cary Clark8032b982017-07-28 11:04:54 -04005075
Cary Clarkbad5ad72017-08-03 17:14:08 -04005076Layout engines such as Harfbuzz typically position each glyph
5077rather than using the font's advance widths if all glyphs share the same
5078baseline.
5079
5080#Param text character code points or glyphs drawn ##
5081#Param byteLength byte length of text array ##
5082#Param xpos array of x positions, used to position each glyph ##
5083#Param constY shared y coordinate for all of x positions ##
5084#Param paint text size, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005085
5086#Example
5087#Height 40
Cary Clarkbad5ad72017-08-03 17:14:08 -04005088 void draw(SkCanvas* canvas) {
5089 SkScalar xpos[] = { 20, 40, 80, 160 };
5090 SkPaint paint;
5091 canvas->drawPosTextH("XXXX", 4, xpos, 20, paint);
5092 }
Cary Clark8032b982017-07-28 11:04:54 -04005093##
5094
5095#ToDo incomplete ##
5096
5097##
5098
5099# ------------------------------------------------------------------------------
5100
5101#Method void drawTextOnPathHV(const void* text, size_t byteLength, const SkPath& path, SkScalar hOffset,
5102 SkScalar vOffset, const SkPaint& paint)
5103
5104Draw text on Path path, using Clip, Matrix, and Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04005105
Cary Clarkbad5ad72017-08-03 17:14:08 -04005106Origin of text is at distance hOffset along the path, offset by a perpendicular
5107vector of length vOffset. If the path section corresponding the glyph advance is
5108curved, the glyph is drawn curved to match; control points in the glyph are
5109mapped to projected points parallel to the path. If the text's advance is larger
5110than the path length, the excess text is clipped.
5111
5112text's meaning depends on Paint_Text_Encoding; by default, text encoding is
5113UTF-8. Origin meaning depends on Paint_Text_Align and Paint_Vertical_Text; by
5114default text positions the first glyph's left side bearing at origin x and its
Cary Clark8032b982017-07-28 11:04:54 -04005115baseline at origin y. Text size is affected by Matrix and Paint_Text_Size.
5116
Cary Clarkbad5ad72017-08-03 17:14:08 -04005117All elements of paint: Path_Effect, Rasterizer, Mask_Filter, Shader,
5118Color_Filter, Image_Filter, and Draw_Looper; apply to text. By default, draws
5119filled 12 point black glyphs.
Cary Clark8032b982017-07-28 11:04:54 -04005120
Cary Clarkbad5ad72017-08-03 17:14:08 -04005121#Param text character code points or glyphs drawn ##
5122#Param byteLength byte length of text array ##
5123#Param path Path providing text baseline ##
5124#Param hOffset distance along path to offset origin ##
5125#Param vOffset offset of text above (if negative) or below (if positive) the path ##
5126#Param paint text size, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005127
5128#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04005129 void draw(SkCanvas* canvas) {
5130 const char aero[] = "correo a" "\xC3" "\xA9" "reo";
5131 const size_t len = sizeof(aero) - 1;
5132 SkPath path;
5133 path.addOval({43-26, 43-26, 43+26, 43+26}, SkPath::kCW_Direction, 3);
5134 SkPaint paint;
5135 paint.setTextSize(24);
5136 for (auto offset : { 0, 10, 20 } ) {
5137 canvas->drawTextOnPathHV(aero, len, path, 0, -offset, paint);
5138 canvas->translate(70 + offset, 70 + offset);
5139 }
5140 }
Cary Clark8032b982017-07-28 11:04:54 -04005141##
5142
5143#ToDo incomplete ##
5144
5145##
5146
5147# ------------------------------------------------------------------------------
5148
5149#Method void drawTextOnPath(const void* text, size_t byteLength, const SkPath& path,
5150 const SkMatrix* matrix, const SkPaint& paint)
5151
5152Draw text on Path path, using Clip, Matrix, and Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04005153
Cary Clarkbad5ad72017-08-03 17:14:08 -04005154Origin of text is at beginning of path offset by matrix, if provided, before it
5155is mapped to path. If the path section corresponding the glyph advance is
5156curved, the glyph is drawn curved to match; control points in the glyph are
5157mapped to projected points parallel to the path. If the text's advance is larger
5158than the path length, the excess text is clipped.
5159
5160text's meaning depends on Paint_Text_Encoding; by default, text encoding is
5161UTF-8. Origin meaning depends on Paint_Text_Align and Paint_Vertical_Text; by
5162default text positions the first glyph's left side bearing at origin x and its
Cary Clark8032b982017-07-28 11:04:54 -04005163baseline at origin y. Text size is affected by Matrix and Paint_Text_Size.
5164
Cary Clarkbad5ad72017-08-03 17:14:08 -04005165All elements of paint: Path_Effect, Rasterizer, Mask_Filter, Shader,
5166Color_Filter, Image_Filter, and Draw_Looper; apply to text. By default, draws
5167filled 12 point black glyphs.
Cary Clark8032b982017-07-28 11:04:54 -04005168
Cary Clarkbad5ad72017-08-03 17:14:08 -04005169#Param text character code points or glyphs drawn ##
5170#Param byteLength byte length of text array ##
5171#Param path Path providing text baseline ##
5172#Param matrix transform of glyphs before mapping to path; may be nullptr
5173 to use identity Matrix.
5174##
5175#Param paint text size, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005176
5177#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04005178 void draw(SkCanvas* canvas) {
5179 const char roller[] = "rollercoaster";
5180 const size_t len = sizeof(roller) - 1;
5181 SkPath path;
5182 path.cubicTo(40, -80, 120, 80, 160, -40);
5183 SkPaint paint;
5184 paint.setTextSize(32);
5185 paint.setStyle(SkPaint::kStroke_Style);
5186 SkMatrix matrix;
5187 matrix.setIdentity();
5188 for (int i = 0; i < 3; ++i) {
5189 canvas->translate(25, 60);
5190 canvas->drawPath(path, paint);
5191 canvas->drawTextOnPath(roller, len, path, &matrix, paint);
5192 matrix.preTranslate(0, 10);
5193 }
5194 }
Cary Clark8032b982017-07-28 11:04:54 -04005195##
5196
5197#ToDo incomplete ##
5198
5199##
5200
5201# ------------------------------------------------------------------------------
5202
5203#Method void drawTextRSXform(const void* text, size_t byteLength, const SkRSXform xform[],
5204 const SkRect* cullRect, const SkPaint& paint)
5205
5206Draw text, transforming each glyph by the corresponding SkRSXform,
5207using Clip, Matrix, and Paint paint.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005208
Cary Clark8032b982017-07-28 11:04:54 -04005209RSXform array specifies a separate square scale, rotation, and translation for
5210each glyph.
Cary Clark8032b982017-07-28 11:04:54 -04005211
Cary Clarkbad5ad72017-08-03 17:14:08 -04005212Optional Rect cullRect is a conservative bounds of text, taking into account
5213RSXform and paint. If cullrect is outside of Clip, canvas can skip drawing.
Cary Clark8032b982017-07-28 11:04:54 -04005214
Cary Clarkbad5ad72017-08-03 17:14:08 -04005215All elements of paint: Path_Effect, Rasterizer, Mask_Filter, Shader,
5216Color_Filter, Image_Filter, and Draw_Looper; apply to text. By default, draws
5217filled 12 point black glyphs.
5218
5219#Param text character code points or glyphs drawn ##
5220#Param byteLength byte length of text array ##
5221#Param xform RSXform rotates, scales, and translates each glyph individually ##
5222#Param cullRect Rect bounds of text for efficient clipping; or nullptr ##
5223#Param paint text size, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005224
5225#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04005226void draw(SkCanvas* canvas) {
5227 const int iterations = 26;
5228 SkRSXform transforms[iterations];
5229 char alphabet[iterations];
5230 SkScalar angle = 0;
5231 SkScalar scale = 1;
5232 for (size_t i = 0; i < SK_ARRAY_COUNT(transforms); ++i) {
5233 const SkScalar s = SkScalarSin(angle) * scale;
5234 const SkScalar c = SkScalarCos(angle) * scale;
5235 transforms[i] = SkRSXform::Make(-c, -s, -s * 16, c * 16);
5236 angle += .45;
5237 scale += .2;
5238 alphabet[i] = 'A' + i;
5239 }
5240 SkPaint paint;
5241 paint.setTextAlign(SkPaint::kCenter_Align);
5242 canvas->translate(110, 138);
5243 canvas->drawTextRSXform(alphabet, sizeof(alphabet), transforms, nullptr, paint);
Cary Clark8032b982017-07-28 11:04:54 -04005244}
5245##
5246
5247#ToDo incomplete ##
5248
5249##
5250
5251# ------------------------------------------------------------------------------
5252
5253#Method void drawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y, const SkPaint& paint)
5254
5255Draw Text_Blob blob at (x, y), using Clip, Matrix, and Paint paint.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005256
Cary Clark8032b982017-07-28 11:04:54 -04005257blob contains glyphs, their positions, and paint attributes specific to text:
Cary Clarkbad5ad72017-08-03 17:14:08 -04005258Typeface, Paint_Text_Size, Paint_Text_Scale_X, Paint_Text_Skew_X,
5259Paint_Text_Align, Paint_Hinting, Anti-alias, Paint_Fake_Bold,
5260Font_Embedded_Bitmaps, Full_Hinting_Spacing, LCD_Text, Linear_Text,
5261Subpixel_Text, and Paint_Vertical_Text.
Cary Clark8032b982017-07-28 11:04:54 -04005262
5263Elements of paint: Path_Effect, Rasterizer, Mask_Filter, Shader, Color_Filter,
5264Image_Filter, and Draw_Looper; apply to blob.
5265
Cary Clarkbad5ad72017-08-03 17:14:08 -04005266#Param blob glyphs, positions, and their paints' text size, typeface, and so on ##
5267#Param x horizontal offset applied to blob ##
5268#Param y vertical offset applied to blob ##
5269#Param paint blend, color, stroking, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005270
5271#Example
5272#Height 120
Cary Clarkbad5ad72017-08-03 17:14:08 -04005273 void draw(SkCanvas* canvas) {
5274 SkTextBlobBuilder textBlobBuilder;
5275 const char bunny[] = "/(^x^)\\";
5276 const int len = sizeof(bunny) - 1;
5277 uint16_t glyphs[len];
5278 SkPaint paint;
5279 paint.textToGlyphs(bunny, len, glyphs);
5280 int runs[] = { 3, 1, 3 };
5281 SkPoint textPos = { 20, 100 };
5282 int glyphIndex = 0;
5283 for (auto runLen : runs) {
5284 paint.setTextSize(1 == runLen ? 20 : 50);
5285 const SkTextBlobBuilder::RunBuffer& run =
5286 textBlobBuilder.allocRun(paint, runLen, textPos.fX, textPos.fY);
5287 memcpy(run.glyphs, &glyphs[glyphIndex], sizeof(glyphs[0]) * runLen);
5288 textPos.fX += paint.measureText(&bunny[glyphIndex], runLen, nullptr);
5289 glyphIndex += runLen;
5290 }
5291 sk_sp<const SkTextBlob> blob = textBlobBuilder.make();
5292 paint.reset();
5293 canvas->drawTextBlob(blob.get(), 0, 0, paint);
Cary Clark8032b982017-07-28 11:04:54 -04005294 }
5295##
5296
5297#ToDo incomplete ##
5298
5299##
5300
5301# ------------------------------------------------------------------------------
5302
5303#Method void drawTextBlob(const sk_sp<SkTextBlob>& blob, SkScalar x, SkScalar y, const SkPaint& paint)
5304
5305Draw Text_Blob blob at (x, y), using Clip, Matrix, and Paint paint.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005306
Cary Clark8032b982017-07-28 11:04:54 -04005307blob contains glyphs, their positions, and paint attributes specific to text:
Cary Clarkbad5ad72017-08-03 17:14:08 -04005308Typeface, Paint_Text_Size, Paint_Text_Scale_X, Paint_Text_Skew_X,
5309Paint_Text_Align, Paint_Hinting, Anti-alias, Paint_Fake_Bold,
5310Font_Embedded_Bitmaps, Full_Hinting_Spacing, LCD_Text, Linear_Text,
5311Subpixel_Text, and Paint_Vertical_Text.
Cary Clark8032b982017-07-28 11:04:54 -04005312
5313Elements of paint: Path_Effect, Rasterizer, Mask_Filter, Shader, Color_Filter,
5314Image_Filter, and Draw_Looper; apply to blob.
5315
Cary Clarkbad5ad72017-08-03 17:14:08 -04005316#Param blob glyphs, positions, and their paints' text size, typeface, and so on ##
5317#Param x horizontal offset applied to blob ##
5318#Param y vertical offset applied to blob ##
5319#Param paint blend, color, stroking, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005320
5321#Example
5322#Height 120
5323#Description
5324Paint attributes unrelated to text, like color, have no effect on paint in allocated Text_Blob.
5325Paint attributes related to text, like text size, have no effect on paint passed to drawTextBlob.
5326##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005327 void draw(SkCanvas* canvas) {
5328 SkTextBlobBuilder textBlobBuilder;
5329 SkPaint paint;
5330 paint.setTextSize(50);
5331 paint.setColor(SK_ColorRED);
5332 const SkTextBlobBuilder::RunBuffer& run =
5333 textBlobBuilder.allocRun(paint, 1, 20, 100);
5334 run.glyphs[0] = 20;
5335 sk_sp<const SkTextBlob> blob = textBlobBuilder.make();
5336 paint.setTextSize(10);
5337 paint.setColor(SK_ColorBLUE);
5338 canvas->drawTextBlob(blob.get(), 0, 0, paint);
5339 }
Cary Clark8032b982017-07-28 11:04:54 -04005340##
5341
5342#ToDo incomplete ##
5343
5344##
5345
5346# ------------------------------------------------------------------------------
5347
5348#Method void drawPicture(const SkPicture* picture)
5349
5350Draw Picture picture, using Clip and Matrix.
5351Clip and Matrix are unchanged by picture contents, as if
5352save() was called before and restore() was called after drawPicture.
5353
5354Picture records a series of draw commands for later playback.
5355
Cary Clarkbad5ad72017-08-03 17:14:08 -04005356#Param picture recorded drawing commands to play ##
Cary Clark8032b982017-07-28 11:04:54 -04005357
5358#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04005359void draw(SkCanvas* canvas) {
5360 SkPictureRecorder recorder;
5361 SkCanvas* recordingCanvas = recorder.beginRecording(50, 50);
5362 for (auto color : { SK_ColorRED, SK_ColorBLUE, 0xff007f00 } ) {
5363 SkPaint paint;
5364 paint.setColor(color);
5365 recordingCanvas->drawRect({10, 10, 30, 40}, paint);
5366 recordingCanvas->translate(10, 10);
5367 recordingCanvas->scale(1.2f, 1.4f);
5368 }
5369 sk_sp<SkPicture> playback = recorder.finishRecordingAsPicture();
5370 const SkPicture* playbackPtr = playback.get();
5371 canvas->drawPicture(playback);
5372 canvas->scale(2, 2);
5373 canvas->translate(50, 0);
5374 canvas->drawPicture(playback);
Cary Clark8032b982017-07-28 11:04:54 -04005375}
5376##
5377
5378#ToDo incomplete ##
5379
5380##
5381
5382# ------------------------------------------------------------------------------
5383
5384#Method void drawPicture(const sk_sp<SkPicture>& picture)
5385
5386Draw Picture picture, using Clip and Matrix.
5387Clip and Matrix are unchanged by picture contents, as if
5388save() was called before and restore() was called after drawPicture.
5389
5390Picture records a series of draw commands for later playback.
5391
Cary Clarkbad5ad72017-08-03 17:14:08 -04005392#Param picture recorded drawing commands to play ##
Cary Clark8032b982017-07-28 11:04:54 -04005393
5394#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04005395void draw(SkCanvas* canvas) {
5396 SkPictureRecorder recorder;
5397 SkCanvas* recordingCanvas = recorder.beginRecording(50, 50);
5398 for (auto color : { SK_ColorRED, SK_ColorBLUE, 0xff007f00 } ) {
5399 SkPaint paint;
5400 paint.setColor(color);
5401 recordingCanvas->drawRect({10, 10, 30, 40}, paint);
5402 recordingCanvas->translate(10, 10);
5403 recordingCanvas->scale(1.2f, 1.4f);
5404 }
5405 sk_sp<SkPicture> playback = recorder.finishRecordingAsPicture();
5406 canvas->drawPicture(playback);
5407 canvas->scale(2, 2);
5408 canvas->translate(50, 0);
5409 canvas->drawPicture(playback);
Cary Clark8032b982017-07-28 11:04:54 -04005410}
5411##
5412
5413#ToDo incomplete ##
5414
5415##
5416
5417# ------------------------------------------------------------------------------
5418
5419#Method void drawPicture(const SkPicture* picture, const SkMatrix* matrix, const SkPaint* paint)
5420
Cary Clarkbad5ad72017-08-03 17:14:08 -04005421Draw Picture picture, using Clip and Matrix; transforming picture with
5422Matrix matrix, if provided; and use Paint paint Color_Alpha, Color_Filter,
5423Image_Filter, and Blend_Mode, if provided.
Cary Clark8032b982017-07-28 11:04:54 -04005424
5425matrix transformation is equivalent to: save(), concat(), drawPicture, restore().
5426paint use is equivalent to: saveLayer, drawPicture, restore().
5427
Cary Clarkbad5ad72017-08-03 17:14:08 -04005428#Param picture recorded drawing commands to play ##
5429#Param matrix Matrix to rotate, scale, translate, and so on; may be nullptr ##
5430#Param paint Paint to apply transparency, filtering, and so on; may be nullptr ##
Cary Clark8032b982017-07-28 11:04:54 -04005431
5432#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04005433void draw(SkCanvas* canvas) {
5434 SkPaint paint;
5435 SkPictureRecorder recorder;
5436 SkCanvas* recordingCanvas = recorder.beginRecording(50, 50);
5437 for (auto color : { SK_ColorRED, SK_ColorBLUE, 0xff007f00 } ) {
5438 paint.setColor(color);
5439 recordingCanvas->drawRect({10, 10, 30, 40}, paint);
5440 recordingCanvas->translate(10, 10);
5441 recordingCanvas->scale(1.2f, 1.4f);
5442 }
5443 sk_sp<SkPicture> playback = recorder.finishRecordingAsPicture();
5444 const SkPicture* playbackPtr = playback.get();
5445 SkMatrix matrix;
5446 matrix.reset();
5447 for (auto alpha : { 70, 140, 210 } ) {
5448 paint.setAlpha(alpha);
5449 canvas->drawPicture(playbackPtr, &matrix, &paint);
5450 matrix.preTranslate(70, 70);
5451 }
Cary Clark8032b982017-07-28 11:04:54 -04005452}
5453##
5454
5455#ToDo incomplete ##
5456
5457##
5458
5459# ------------------------------------------------------------------------------
5460
5461#Method void drawPicture(const sk_sp<SkPicture>& picture, const SkMatrix* matrix, const SkPaint* paint)
5462
Cary Clarkbad5ad72017-08-03 17:14:08 -04005463Draw Picture picture, using Clip and Matrix; transforming picture with
5464Matrix matrix, if provided; and use Paint paint Color_Alpha, Color_Filter,
5465Image_Filter, and Blend_Mode, if provided.
Cary Clark8032b982017-07-28 11:04:54 -04005466
5467matrix transformation is equivalent to: save(), concat(), drawPicture, restore().
5468paint use is equivalent to: saveLayer, drawPicture, restore().
5469
Cary Clarkbad5ad72017-08-03 17:14:08 -04005470#Param picture recorded drawing commands to play ##
5471#Param matrix Matrix to rotate, scale, translate, and so on; may be nullptr ##
5472#Param paint Paint to apply transparency, filtering, and so on; may be nullptr ##
Cary Clark8032b982017-07-28 11:04:54 -04005473
5474#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04005475void draw(SkCanvas* canvas) {
5476 SkPaint paint;
5477 SkPictureRecorder recorder;
5478 SkCanvas* recordingCanvas = recorder.beginRecording(50, 50);
5479 for (auto color : { SK_ColorRED, SK_ColorBLUE, 0xff007f00 } ) {
5480 paint.setColor(color);
5481 recordingCanvas->drawRect({10, 10, 30, 40}, paint);
5482 recordingCanvas->translate(10, 10);
5483 recordingCanvas->scale(1.2f, 1.4f);
5484 }
5485 sk_sp<SkPicture> playback = recorder.finishRecordingAsPicture();
5486 SkMatrix matrix;
5487 matrix.reset();
5488 for (auto alpha : { 70, 140, 210 } ) {
5489 paint.setAlpha(alpha);
5490 canvas->drawPicture(playback, &matrix, &paint);
5491 matrix.preTranslate(70, 70);
5492 }
Cary Clark8032b982017-07-28 11:04:54 -04005493}
5494##
5495
5496#ToDo incomplete ##
5497
5498##
5499
5500# ------------------------------------------------------------------------------
5501
5502#Method void drawVertices(const SkVertices* vertices, SkBlendMode mode, const SkPaint& paint)
5503
5504Draw Vertices vertices, a triangle mesh, using Clip and Matrix.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005505If Vertices_Texs and Vertices_Colors are defined in vertices, and Paint paint
5506contains Shader, Blend_Mode mode combines Vertices_Colors with Shader.
Cary Clark8032b982017-07-28 11:04:54 -04005507
Cary Clarkbad5ad72017-08-03 17:14:08 -04005508#Param vertices triangle mesh to draw ##
5509#Param mode combines Vertices_Colors with Shader, if both are present ##
5510#Param paint specifies the Shader, used as Vertices texture; may be nullptr ##
Cary Clark8032b982017-07-28 11:04:54 -04005511
5512#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04005513void draw(SkCanvas* canvas) {
5514 SkPaint paint;
5515 SkPoint points[] = { { 0, 0 }, { 250, 0 }, { 100, 100 }, { 0, 250 } };
5516 SkColor colors[] = { SK_ColorRED, SK_ColorBLUE, SK_ColorYELLOW, SK_ColorCYAN };
5517 auto vertices = SkVertices::MakeCopy(SkVertices::kTriangleFan_VertexMode,
5518 SK_ARRAY_COUNT(points), points, nullptr, colors);
5519 canvas->drawVertices(vertices.get(), SkBlendMode::kSrc, paint);
5520}
Cary Clark8032b982017-07-28 11:04:54 -04005521##
5522
5523#ToDo incomplete ##
5524
5525##
5526
5527# ------------------------------------------------------------------------------
5528
5529#Method void drawVertices(const sk_sp<SkVertices>& vertices, SkBlendMode mode, const SkPaint& paint)
5530
5531Draw Vertices vertices, a triangle mesh, using Clip and Matrix.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005532If Vertices_Texs and Vertices_Colors are defined in vertices, and Paint paint
5533contains Shader, Blend_Mode mode combines Vertices_Colors with Shader.
Cary Clark8032b982017-07-28 11:04:54 -04005534
Cary Clarkbad5ad72017-08-03 17:14:08 -04005535#Param vertices triangle mesh to draw ##
5536#Param mode combines Vertices_Colors with Shader, if both are present ##
5537#Param paint specifies the Shader, used as Vertices texture, may be nullptr ##
Cary Clark8032b982017-07-28 11:04:54 -04005538
5539#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04005540void draw(SkCanvas* canvas) {
5541 SkPaint paint;
5542 SkPoint points[] = { { 0, 0 }, { 250, 0 }, { 100, 100 }, { 0, 250 } };
5543 SkPoint texs[] = { { 0, 0 }, { 0, 250 }, { 250, 250 }, { 250, 0 } };
5544 SkColor colors[] = { SK_ColorRED, SK_ColorBLUE, SK_ColorYELLOW, SK_ColorCYAN };
5545 paint.setShader(SkGradientShader::MakeLinear(points, colors, nullptr, 4,
5546 SkShader::kClamp_TileMode));
5547 auto vertices = SkVertices::MakeCopy(SkVertices::kTriangleFan_VertexMode,
5548 SK_ARRAY_COUNT(points), points, texs, colors);
5549 canvas->drawVertices(vertices.get(), SkBlendMode::kDarken, paint);
Cary Clark8032b982017-07-28 11:04:54 -04005550}
5551##
5552
5553#ToDo incomplete ##
5554
5555##
5556
5557# ------------------------------------------------------------------------------
5558
5559#Method void drawPatch(const SkPoint cubics[12], const SkColor colors[4],
5560 const SkPoint texCoords[4], SkBlendMode mode, const SkPaint& paint)
5561
5562Draw a cubic Coons patch: the interpolation of four cubics with shared corners,
5563associating a color, and optionally a texture coordinate, with each corner.
5564
Cary Clarkbad5ad72017-08-03 17:14:08 -04005565The Coons patch uses Clip and Matrix, Paint paint's Shader, Color_Filter,
5566Color_Alpha, Image_Filter, and Blend_Mode. If Shader is provided it is treated
5567as the Coons patch texture; Blend_Mode mode combines Color colors and Shader if
5568both are provided.
Cary Clark8032b982017-07-28 11:04:54 -04005569
Cary Clarkbad5ad72017-08-03 17:14:08 -04005570Point array cubics specifies four cubics starting at the top left corner,
5571in clockwise order, sharing every fourth point. The last cubic ends at the
5572first point.
Cary Clark8032b982017-07-28 11:04:54 -04005573
Cary Clarkbad5ad72017-08-03 17:14:08 -04005574Color array color associates colors with corners in top left, top right,
5575bottom right, bottom left order.
5576
5577If paint contains Shader, Point array texCoords maps Shader as texture to
5578corners in top left, top right, bottom right, bottom left order.
5579
5580#Param cubics Cubic array, sharing common points ##
5581#Param colors Color array, one for each corner ##
5582#Param texCoords Point array of texure coordinates, mapping Shader to corners;
5583 may be nullptr
Cary Clark579985c2017-07-31 11:48:27 -04005584#Param ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005585#Param mode Blend_Mode for colors, and for Shader if paint has one ##
5586#Param paint Shader, Color_Filter, Blend_Mode, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005587
5588#Example
5589#Image 5
Cary Clarkbad5ad72017-08-03 17:14:08 -04005590void draw(SkCanvas* canvas) {
5591 // SkBitmap source = cmbkygk;
5592 SkPaint paint;
5593 paint.setFilterQuality(kLow_SkFilterQuality);
5594 paint.setAntiAlias(true);
5595 SkPoint cubics[] = { { 3, 1 }, { 4, 2 }, { 5, 1 }, { 7, 3 },
5596 /* { 7, 3 }, */ { 6, 4 }, { 7, 5 }, { 5, 7 },
5597 /* { 5, 7 }, */ { 4, 6 }, { 3, 7 }, { 1, 5 },
5598 /* { 1, 5 }, */ { 2, 4 }, { 1, 3 }, /* { 3, 1 } */ };
5599 SkColor colors[] = { 0xbfff0000, 0xbf0000ff, 0xbfff00ff, 0xbf00ffff };
5600 SkPoint texCoords[] = { { -30, -30 }, { 162, -30}, { 162, 162}, { -30, 162} };
5601 paint.setShader(SkShader::MakeBitmapShader(source, SkShader::kClamp_TileMode,
5602 SkShader::kClamp_TileMode, nullptr));
5603 canvas->scale(15, 15);
5604 for (auto blend : { SkBlendMode::kSrcOver, SkBlendMode::kModulate, SkBlendMode::kXor } ) {
5605 canvas->drawPatch(cubics, colors, texCoords, blend, paint);
5606 canvas->translate(4, 4);
5607 }
Cary Clark8032b982017-07-28 11:04:54 -04005608}
5609##
5610
Cary Clarkbad5ad72017-08-03 17:14:08 -04005611#ToDo incomplete; can patch use image filter? ##
Cary Clark8032b982017-07-28 11:04:54 -04005612
5613##
5614
5615# ------------------------------------------------------------------------------
5616
5617#Method void drawPatch(const SkPoint cubics[12], const SkColor colors[4],
5618 const SkPoint texCoords[4], const SkPaint& paint)
5619
5620Draw a cubic Coons patch: the interpolation of four cubics with shared corners,
Cary Clarkbad5ad72017-08-03 17:14:08 -04005621associating a color, and optionally a texture coordinate, with each corner.
Cary Clark8032b982017-07-28 11:04:54 -04005622
Cary Clarkbad5ad72017-08-03 17:14:08 -04005623The Coons patch uses Clip and Matrix, Paint paint's Shader, Color_Filter,
5624Color_Alpha, Image_Filter, and Blend_Mode. If Shader is provided it is treated
5625as the Coons patch texture; Blend_Mode mode combines Color colors and Shader if
5626both are provided.
Cary Clark8032b982017-07-28 11:04:54 -04005627
Cary Clarkbad5ad72017-08-03 17:14:08 -04005628Point array cubics specifies four cubics starting at the top left corner,
5629in clockwise order, sharing every fourth point. The last cubic ends at the
5630first point.
5631
5632Color array color associates colors with corners in top left, top right,
5633bottom right, bottom left order.
5634
5635If paint contains Shader, Point array texCoords maps Shader as texture to
5636corners in top left, top right, bottom right, bottom left order.
5637
5638#Param cubics Cubic array, sharing common points ##
5639#Param colors Color array, one for each corner ##
5640#Param texCoords Point array of texure coordinates, mapping Shader to corners;
5641 may be nullptr
Cary Clark579985c2017-07-31 11:48:27 -04005642#Param ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005643#Param paint Shader, Color_Filter, Blend_Mode, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005644
5645#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04005646void draw(SkCanvas* canvas) {
5647 SkPaint paint;
5648 paint.setAntiAlias(true);
5649 SkPoint cubics[] = { { 3, 1 }, { 4, 2 }, { 5, 1 }, { 7, 3 },
5650 /* { 7, 3 }, */ { 6, 4 }, { 7, 5 }, { 5, 7 },
5651 /* { 5, 7 }, */ { 4, 6 }, { 3, 7 }, { 1, 5 },
5652 /* { 1, 5 }, */ { 2, 4 }, { 1, 3 }, /* { 3, 1 } */ };
5653 SkColor colors[] = { SK_ColorRED, SK_ColorBLUE, SK_ColorYELLOW, SK_ColorCYAN };
5654 canvas->scale(30, 30);
5655 canvas->drawPatch(cubics, colors, nullptr, paint);
5656 SkPoint text[] = { {3,0.9f}, {4,2.5f}, {5,0.9f}, {7.5f,3.2f}, {5.5f,4.2f},
5657 {7.5f,5.2f}, {5,7.5f}, {4,5.9f}, {3,7.5f}, {0.5f,5.2f}, {2.5f,4.2f},
5658 {0.5f,3.2f} };
5659 paint.setTextSize(18.f / 30);
5660 paint.setTextAlign(SkPaint::kCenter_Align);
5661 for (int i = 0; i< 10; ++i) {
5662 char digit = '0' + i;
5663 canvas->drawText(&digit, 1, text[i].fX, text[i].fY, paint);
5664 }
5665 canvas->drawString("10", text[10].fX, text[10].fY, paint);
5666 canvas->drawString("11", text[11].fX, text[11].fY, paint);
5667 paint.setStyle(SkPaint::kStroke_Style);
5668 canvas->drawPoints(SkCanvas::kPolygon_PointMode, 12, cubics, paint);
5669 canvas->drawLine(cubics[11].fX, cubics[11].fY, cubics[0].fX, cubics[0].fY, paint);
Cary Clark8032b982017-07-28 11:04:54 -04005670}
5671##
5672
5673#Example
5674#Image 6
Cary Clarkbad5ad72017-08-03 17:14:08 -04005675void draw(SkCanvas* canvas) {
5676 // SkBitmap source = checkerboard;
5677 SkPaint paint;
5678 paint.setFilterQuality(kLow_SkFilterQuality);
5679 paint.setAntiAlias(true);
5680 SkPoint cubics[] = { { 3, 1 }, { 4, 2 }, { 5, 1 }, { 7, 3 },
5681 /* { 7, 3 }, */ { 6, 4 }, { 7, 5 }, { 5, 7 },
5682 /* { 5, 7 }, */ { 4, 6 }, { 3, 7 }, { 1, 5 },
5683 /* { 1, 5 }, */ { 2, 4 }, { 1, 3 }, /* { 3, 1 } */ };
5684 SkPoint texCoords[] = { { 0, 0 }, { 0, 62}, { 62, 62}, { 62, 0 } };
5685 paint.setShader(SkShader::MakeBitmapShader(source, SkShader::kClamp_TileMode,
5686 SkShader::kClamp_TileMode, nullptr));
5687 canvas->scale(30, 30);
5688 canvas->drawPatch(cubics, nullptr, texCoords, paint);
Cary Clark8032b982017-07-28 11:04:54 -04005689}
5690##
5691
Cary Clarkbad5ad72017-08-03 17:14:08 -04005692#ToDo incomplete; can patch use image filter? ##
Cary Clark8032b982017-07-28 11:04:54 -04005693
5694##
5695
5696# ------------------------------------------------------------------------------
5697
5698#Method void drawAtlas(const SkImage* atlas, const SkRSXform xform[], const SkRect tex[],
5699 const SkColor colors[], int count, SkBlendMode mode, const SkRect* cullRect,
5700 const SkPaint* paint)
5701
5702Draw a set of sprites from atlas, using Clip, Matrix, and optional Paint paint.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005703paint uses Anti-alias, Color_Alpha, Color_Filter, Image_Filter, and Blend_Mode
5704to draw, if present. For each entry in the array, Rect tex locates sprite in
5705atlas, and RSXform xform transforms it into destination space.
5706
Cary Clark8032b982017-07-28 11:04:54 -04005707xform, text, and colors if present, must contain count entries.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005708Optional colors are applied for each sprite using Blend_Mode.
Cary Clark8032b982017-07-28 11:04:54 -04005709Optional cullRect is a conservative bounds of all transformed sprites.
5710If cullrect is outside of Clip, canvas can skip drawing.
5711
Cary Clarkbad5ad72017-08-03 17:14:08 -04005712#Param atlas Image containing sprites ##
5713#Param xform RSXform mappings for sprites in atlas ##
5714#Param tex Rect locations of sprites in atlas ##
5715#Param colors Color, one per sprite, blended with sprite using Blend_Mode; may be nullptr ##
5716#Param count number of sprites to draw ##
5717#Param mode Blend_Mode combining colors and sprites ##
5718#Param cullRect Rect bounds of transformed sprites for efficient clipping; may be nullptr ##
5719#Param paint Paint Color_Filter, Image_Filter, Blend_Mode, and so on; may be nullptr ##
Cary Clark8032b982017-07-28 11:04:54 -04005720
5721#Example
5722#Image 3
Cary Clarkbad5ad72017-08-03 17:14:08 -04005723void draw(SkCanvas* canvas) {
5724 // SkBitmap source = mandrill;
5725 SkRSXform xforms[] = { { .5f, 0, 0, 0 }, {0, .5f, 200, 100 } };
5726 SkRect tex[] = { { 0, 0, 250, 250 }, { 0, 0, 250, 250 } };
5727 SkColor colors[] = { 0x7f55aa00, 0x7f3333bf };
5728 const SkImage* imagePtr = image.get();
5729 canvas->drawAtlas(imagePtr, xforms, tex, colors, 2, SkBlendMode::kSrcOver, nullptr, nullptr);
Cary Clark8032b982017-07-28 11:04:54 -04005730}
5731##
5732
5733#ToDo incomplete ##
5734
5735##
5736
5737# ------------------------------------------------------------------------------
5738
5739#Method void drawAtlas(const sk_sp<SkImage>& atlas, const SkRSXform xform[], const SkRect tex[],
5740 const SkColor colors[], int count, SkBlendMode mode, const SkRect* cullRect,
5741 const SkPaint* paint)
5742
5743Draw a set of sprites from atlas, using Clip, Matrix, and optional Paint paint.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005744paint uses Anti-alias, Color_Alpha, Color_Filter, Image_Filter, and Blend_Mode
5745to draw, if present. For each entry in the array, Rect tex locates sprite in
5746atlas, and RSXform xform transforms it into destination space.
5747
Cary Clark8032b982017-07-28 11:04:54 -04005748xform, text, and colors if present, must contain count entries.
5749Optional colors is applied for each sprite using Blend_Mode.
5750Optional cullRect is a conservative bounds of all transformed sprites.
5751If cullrect is outside of Clip, canvas can skip drawing.
5752
Cary Clarkbad5ad72017-08-03 17:14:08 -04005753#Param atlas Image containing sprites ##
5754#Param xform RSXform mappings for sprites in atlas ##
5755#Param tex Rect locations of sprites in atlas ##
5756#Param colors Color, one per sprite, blended with sprite using Blend_Mode; may be nullptr ##
5757#Param count number of sprites to draw ##
5758#Param mode Blend_Mode combining colors and sprites ##
5759#Param cullRect Rect bounds of transformed sprites for efficient clipping; may be nullptr ##
5760#Param paint Paint Color_Filter, Image_Filter, Blend_Mode, and so on; may be nullptr ##
Cary Clark8032b982017-07-28 11:04:54 -04005761
5762#Example
5763#Image 3
Cary Clarkbad5ad72017-08-03 17:14:08 -04005764void draw(SkCanvas* canvas) {
5765 // SkBitmap source = mandrill;
5766 SkRSXform xforms[] = { { .5f, 0, 0, 0 }, {0, .5f, 200, 100 } };
5767 SkRect tex[] = { { 0, 0, 250, 250 }, { 0, 0, 250, 250 } };
5768 SkColor colors[] = { 0x7f55aa00, 0x7f3333bf };
5769 SkPaint paint;
5770 paint.setAlpha(127);
5771 canvas->drawAtlas(image, xforms, tex, colors, 2, SkBlendMode::kPlus, nullptr, &paint);
Cary Clark8032b982017-07-28 11:04:54 -04005772}
5773##
5774
5775#ToDo bug in example on cpu side, gpu looks ok ##
5776
5777##
5778
5779# ------------------------------------------------------------------------------
5780
5781#Method void drawAtlas(const SkImage* atlas, const SkRSXform xform[], const SkRect tex[], int count,
5782 const SkRect* cullRect, const SkPaint* paint)
5783
5784Draw a set of sprites from atlas, using Clip, Matrix, and optional Paint paint.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005785paint uses Anti-alias, Color_Alpha, Color_Filter, Image_Filter, and Blend_Mode
5786to draw, if present. For each entry in the array, Rect tex locates sprite in
5787atlas, and RSXform xform transforms it into destination space.
5788
Cary Clark8032b982017-07-28 11:04:54 -04005789xform and text must contain count entries.
5790Optional cullRect is a conservative bounds of all transformed sprites.
5791If cullrect is outside of Clip, canvas can skip drawing.
5792
Cary Clarkbad5ad72017-08-03 17:14:08 -04005793#Param atlas Image containing sprites ##
5794#Param xform RSXform mappings for sprites in atlas ##
5795#Param tex Rect locations of sprites in atlas ##
5796#Param count number of sprites to draw ##
5797#Param cullRect Rect bounds of transformed sprites for efficient clipping; may be nullptr ##
5798#Param paint Paint Color_Filter, Image_Filter, Blend_Mode, and so on; may be nullptr ##
Cary Clark8032b982017-07-28 11:04:54 -04005799
5800#Example
5801#Image 3
Cary Clarkbad5ad72017-08-03 17:14:08 -04005802void draw(SkCanvas* canvas) {
5803 // sk_sp<SkImage> image = mandrill;
5804 SkRSXform xforms[] = { { .5f, 0, 0, 0 }, {0, .5f, 200, 100 } };
5805 SkRect tex[] = { { 0, 0, 250, 250 }, { 0, 0, 250, 250 } };
5806 const SkImage* imagePtr = image.get();
5807 canvas->drawAtlas(imagePtr, xforms, tex, 2, nullptr, nullptr);
Cary Clark8032b982017-07-28 11:04:54 -04005808}
5809##
5810
5811#ToDo incomplete ##
5812
5813##
5814
5815# ------------------------------------------------------------------------------
5816
5817#Method void drawAtlas(const sk_sp<SkImage>& atlas, const SkRSXform xform[], const SkRect tex[],
5818 int count, const SkRect* cullRect, const SkPaint* paint)
5819
5820Draw a set of sprites from atlas, using Clip, Matrix, and optional Paint paint.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005821paint uses Anti-alias, Color_Alpha, Color_Filter, Image_Filter, and Blend_Mode
5822to draw, if present. For each entry in the array, Rect tex locates sprite in
5823atlas, and RSXform xform transforms it into destination space.
5824
Cary Clark8032b982017-07-28 11:04:54 -04005825xform and text must contain count entries.
5826Optional cullRect is a conservative bounds of all transformed sprites.
5827If cullrect is outside of Clip, canvas can skip drawing.
5828
Cary Clarkbad5ad72017-08-03 17:14:08 -04005829#Param atlas Image containing sprites ##
5830#Param xform RSXform mappings for sprites in atlas ##
5831#Param tex Rect locations of sprites in atlas ##
5832#Param count number of sprites to draw ##
5833#Param cullRect Rect bounds of transformed sprites for efficient clipping; may be nullptr ##
5834#Param paint Paint Color_Filter, Image_Filter, Blend_Mode, and so on; may be nullptr ##
Cary Clark8032b982017-07-28 11:04:54 -04005835
5836#Example
5837#Image 3
Cary Clarkbad5ad72017-08-03 17:14:08 -04005838void draw(SkCanvas* canvas) {
5839 // sk_sp<SkImage> image = mandrill;
5840 SkRSXform xforms[] = { { 1, 0, 0, 0 }, {0, 1, 300, 100 } };
5841 SkRect tex[] = { { 0, 0, 200, 200 }, { 200, 0, 400, 200 } };
5842 canvas->drawAtlas(image, xforms, tex, 2, nullptr, nullptr);
Cary Clark8032b982017-07-28 11:04:54 -04005843}
5844##
5845
5846#ToDo incomplete ##
5847
5848##
5849
5850# ------------------------------------------------------------------------------
5851
5852#Method void drawDrawable(SkDrawable* drawable, const SkMatrix* matrix = NULL)
5853
5854Draw Drawable drawable using Clip and Matrix, concatenated with
5855optional matrix.
5856
5857If Canvas has an asynchronous implementation, as is the case
5858when it is recording into Picture, then drawable will be referenced,
5859so that SkDrawable::draw() can be called when the operation is finalized. To force
5860immediate drawing, call SkDrawable::draw() instead.
5861
Cary Clarkbad5ad72017-08-03 17:14:08 -04005862#Param drawable custom struct encapsulating drawing commands ##
5863#Param matrix transformation applied to drawing; may be nullptr ##
Cary Clark8032b982017-07-28 11:04:54 -04005864
5865#Example
5866#Height 100
5867#Function
Cary Clarkbad5ad72017-08-03 17:14:08 -04005868struct MyDrawable : public SkDrawable {
5869 SkRect onGetBounds() override { return SkRect::MakeWH(50, 100); }
5870
5871 void onDraw(SkCanvas* canvas) override {
5872 SkPath path;
5873 path.conicTo(10, 90, 50, 90, 0.9f);
5874 SkPaint paint;
5875 paint.setColor(SK_ColorBLUE);
5876 canvas->drawRect(path.getBounds(), paint);
5877 paint.setAntiAlias(true);
5878 paint.setColor(SK_ColorWHITE);
5879 canvas->drawPath(path, paint);
5880 }
5881};
5882
5883#Function ##
5884void draw(SkCanvas* canvas) {
5885 sk_sp<SkDrawable> drawable(new MyDrawable);
5886 SkMatrix matrix;
5887 matrix.setTranslate(10, 10);
5888 canvas->drawDrawable(drawable.get(), &matrix);
Cary Clark8032b982017-07-28 11:04:54 -04005889}
5890##
5891
5892#ToDo incomplete ##
5893
5894##
5895
5896# ------------------------------------------------------------------------------
5897
5898#Method void drawDrawable(SkDrawable* drawable, SkScalar x, SkScalar y)
5899
5900Draw Drawable drawable using Clip and Matrix, offset by (x, y).
5901
5902If Canvas has an asynchronous implementation, as is the case
5903when it is recording into Picture, then drawable will be referenced,
5904so that SkDrawable::draw() can be called when the operation is finalized. To force
5905immediate drawing, call SkDrawable::draw() instead.
5906
Cary Clarkbad5ad72017-08-03 17:14:08 -04005907#Param drawable custom struct encapsulating drawing commands ##
5908#Param x offset into Canvas writable pixels in x ##
5909#Param y offset into Canvas writable pixels in y ##
Cary Clark8032b982017-07-28 11:04:54 -04005910
5911#Example
5912#Height 100
5913#Function
Cary Clarkbad5ad72017-08-03 17:14:08 -04005914struct MyDrawable : public SkDrawable {
5915 SkRect onGetBounds() override { return SkRect::MakeWH(50, 100); }
5916
5917 void onDraw(SkCanvas* canvas) override {
5918 SkPath path;
5919 path.conicTo(10, 90, 50, 90, 0.9f);
5920 SkPaint paint;
5921 paint.setColor(SK_ColorBLUE);
5922 canvas->drawRect(path.getBounds(), paint);
5923 paint.setAntiAlias(true);
5924 paint.setColor(SK_ColorWHITE);
5925 canvas->drawPath(path, paint);
5926 }
5927};
5928
5929#Function ##
5930void draw(SkCanvas* canvas) {
5931 sk_sp<SkDrawable> drawable(new MyDrawable);
5932 canvas->drawDrawable(drawable.get(), 10, 10);
Cary Clark8032b982017-07-28 11:04:54 -04005933}
5934##
5935
5936#ToDo incomplete ##
5937
5938##
5939
5940# ------------------------------------------------------------------------------
5941
5942#Method void drawAnnotation(const SkRect& rect, const char key[], SkData* value)
5943
5944Associate Rect on Canvas when an annotation; a key-value pair, where the key is
5945a null-terminated utf8 string, and optional value is stored as Data.
5946
5947Only some canvas implementations, such as recording to Picture, or drawing to
5948Document_PDF, use annotations.
5949
Cary Clarkbad5ad72017-08-03 17:14:08 -04005950#Param rect Rect extent of canvas to annotate ##
5951#Param key string used for lookup ##
5952#Param value data holding value stored in annotation ##
Cary Clark8032b982017-07-28 11:04:54 -04005953
5954#Example
5955 #Height 1
5956 const char text[] = "Click this link!";
5957 SkRect bounds;
5958 SkPaint paint;
5959 paint.setTextSize(40);
5960 (void)paint.measureText(text, strlen(text), &bounds);
5961 const char url[] = "https://www.google.com/";
5962 sk_sp<SkData> urlData(SkData::MakeWithCString(url));
5963 canvas->drawAnnotation(bounds, "url_key", urlData.get());
5964##
5965
5966#ToDo incomplete ##
5967
5968##
5969
5970# ------------------------------------------------------------------------------
5971
5972#Method void drawAnnotation(const SkRect& rect, const char key[], const sk_sp<SkData>& value)
5973
5974Associate Rect on Canvas when an annotation; a key-value pair, where the key is
5975a null-terminated utf8 string, and optional value is stored as Data.
5976
5977Only some canvas implementations, such as recording to Picture, or drawing to
5978Document_PDF, use annotations.
5979
Cary Clarkbad5ad72017-08-03 17:14:08 -04005980#Param rect Rect extent of canvas to annotate ##
5981#Param key string used for lookup ##
5982#Param value data holding value stored in annotation ##
Cary Clark8032b982017-07-28 11:04:54 -04005983
5984#Example
5985#Height 1
5986 const char text[] = "Click this link!";
5987 SkRect bounds;
5988 SkPaint paint;
5989 paint.setTextSize(40);
5990 (void)paint.measureText(text, strlen(text), &bounds);
5991 const char url[] = "https://www.google.com/";
5992 sk_sp<SkData> urlData(SkData::MakeWithCString(url));
5993 canvas->drawAnnotation(bounds, "url_key", urlData.get());
5994##
5995
5996#ToDo incomplete ##
5997
5998##
5999
6000#Method SkDrawFilter* getDrawFilter() const
6001
6002Legacy call to be deprecated.
6003
6004#Deprecated
6005##
6006
6007##
6008
6009#Method virtual SkDrawFilter* setDrawFilter(SkDrawFilter* filter)
6010
6011Legacy call to be deprecated.
6012
6013#Deprecated
6014##
6015
6016##
6017
6018# ------------------------------------------------------------------------------
6019
6020#Method virtual bool isClipEmpty() const
6021
6022Returns true if Clip is empty; that is, nothing will draw.
6023
Cary Clarkbad5ad72017-08-03 17:14:08 -04006024May do work when called; it should not be called
Cary Clark8032b982017-07-28 11:04:54 -04006025more often than needed. However, once called, subsequent calls perform no
6026work until Clip changes.
6027
Cary Clarkbad5ad72017-08-03 17:14:08 -04006028#Return true if Clip is empty ##
Cary Clark8032b982017-07-28 11:04:54 -04006029
6030#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04006031 void draw(SkCanvas* canvas) {
6032 SkDebugf("clip is%s empty\n", canvas->isClipEmpty() ? "" : " not");
6033 SkPath path;
6034 canvas->clipPath(path);
6035 SkDebugf("clip is%s empty\n", canvas->isClipEmpty() ? "" : " not");
Cary Clark8032b982017-07-28 11:04:54 -04006036 }
6037 #StdOut
Cary Clarkbad5ad72017-08-03 17:14:08 -04006038 clip is not empty
Cary Clark8032b982017-07-28 11:04:54 -04006039 clip is empty
6040 ##
6041##
6042
6043#ToDo incomplete ##
6044
6045##
6046
6047# ------------------------------------------------------------------------------
6048
6049#Method virtual bool isClipRect() const
6050
6051Returns true if Clip is Rect and not empty.
6052Returns false if the clip is empty, or if it is not Rect.
6053
Cary Clarkbad5ad72017-08-03 17:14:08 -04006054#Return true if Clip is Rect and not empty ##
Cary Clark8032b982017-07-28 11:04:54 -04006055
6056#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04006057 void draw(SkCanvas* canvas) {
6058 SkDebugf("clip is%s rect\n", canvas->isClipRect() ? "" : " not");
6059 canvas->clipRect({0, 0, 0, 0});
6060 SkDebugf("clip is%s rect\n", canvas->isClipRect() ? "" : " not");
Cary Clark8032b982017-07-28 11:04:54 -04006061 }
6062 #StdOut
Cary Clarkbad5ad72017-08-03 17:14:08 -04006063 clip is rect
Cary Clark8032b982017-07-28 11:04:54 -04006064 clip is not rect
6065 ##
6066##
6067
6068#ToDo incomplete ##
6069
6070##
6071
6072#Class SkCanvas ##
6073#Topic Canvas ##