blob: 3c836b41d32f5fba64fe9b989eca04dfdc3d70aa [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
Cary Clarke4aa3712017-09-15 02:56:12 -04004#Class SkCanvas
5
Cary Clark8032b982017-07-28 11:04:54 -04006Canvas provides an interface for drawing, and how the drawing is clipped and transformed.
7Canvas contains a stack of Matrix and Clip values.
8
9Canvas and Paint together provide the state to draw into Surface or Device.
Cary Clarkbad5ad72017-08-03 17:14:08 -040010Each Canvas draw call transforms the geometry of the object by the concatenation of all
11Matrix values in the stack. The transformed geometry is clipped by the intersection
12of all of Clip values in the stack. The Canvas draw calls use Paint to supply drawing
13state such as Color, Typeface, text size, stroke width, Shader and so on.
Cary Clark8032b982017-07-28 11:04:54 -040014
15To draw to a pixel-based destination, create Raster_Surface or GPU_Surface.
16Request Canvas from Surface to obtain the interface to draw.
17Canvas generated by Raster_Surface draws to memory visible to the CPU.
18Canvas generated by GPU_Surface uses Vulkan or OpenGL to draw to the GPU.
19
Cary Clarkbad5ad72017-08-03 17:14:08 -040020To draw to a document, obtain Canvas from SVG_Canvas, Document_PDF, or Picture_Recorder.
Cary Clarkce101242017-09-01 15:51:02 -040021Document based Canvas and other Canvas Subclasses reference Device describing the
Cary Clarkbad5ad72017-08-03 17:14:08 -040022destination.
23
Cary Clark8032b982017-07-28 11:04:54 -040024Canvas can be constructed to draw to Bitmap without first creating Raster_Surface.
25This approach may be deprecated in the future.
26
Cary Clark8032b982017-07-28 11:04:54 -040027#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. ##
Cary Clarkce101242017-09-01 15:51:02 -040056# SaveLayerRec # Contains state to create Layer. ##
Cary Clark8032b982017-07-28 11:04:54 -040057#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. ##
Cary Clark73fa9722017-08-29 17:36:51 -040070# SkCanvas(int width, int height, const SkSurfaceProps* props = nullptr) # No Surface, set dimensions, Surface_Properties. ##
Cary Clark8032b982017-07-28 11:04:54 -040071# 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. ##
Cary Clarkd0530ba2017-09-14 11:25:39 -040098# drawBitmapLattice # Draws proportionally stretched Bitmap. ##
Cary Clark8032b982017-07-28 11:04:54 -040099# 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. ##
Cary Clarkd0530ba2017-09-14 11:25:39 -0400107# drawImageLattice # Draws proportionally stretched Image. ##
Cary Clark8032b982017-07-28 11:04:54 -0400108# 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. ##
Cary Clarkce101242017-09-01 15:51:02 -0400113# drawPatch # Draws Coons patch. ##
Cary Clark8032b982017-07-28 11:04:54 -0400114# 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. ##
Cary Clarkce101242017-09-01 15:51:02 -0400132# getBaseLayerSize # Gets size of base Layer in global coordinates. ##
Cary Clark8032b982017-07-28 11:04:54 -0400133# 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. ##
Cary Clarkce101242017-09-01 15:51:02 -0400155# saveLayer # Saves Clip and Matrix on stack; creates Layer. ##
156# saveLayerAlpha # Saves Clip and Matrix on stack; creates Layer; sets opacity. ##
157# saveLayerPreserveLCDTextRequests # Saves Clip and Matrix on stack; creates Layer for LCD text. ##
Cary Clark8032b982017-07-28 11:04:54 -0400158# 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
Cary Clarkf05bdda2017-08-24 12:59:48 -0400185Pass zero for rowBytes to compute rowBytes from info width and size of pixel.
186If rowBytes is greater than zero, it must be equal to or greater than
187info width times bytes required for Image_Color_Type.
188
189Pixel buffer size should be info height times computed rowBytes.
Cary Clarkbad5ad72017-08-03 17:14:08 -0400190
191#Param info width, height, Image_Color_Type, Image_Alpha_Type, Color_Space, of Raster_Surface;
192 width, or height, or both, may be zero
Cary Clark8032b982017-07-28 11:04:54 -0400193##
Cary Clarkf05bdda2017-08-24 12:59:48 -0400194#Param pixels pointer to destination pixels buffer
Cary Clark8032b982017-07-28 11:04:54 -0400195##
Cary Clarkf05bdda2017-08-24 12:59:48 -0400196#Param rowBytes interval from one Surface row to the next, or zero
Cary Clark8032b982017-07-28 11:04:54 -0400197##
198
Cary Clarkbad5ad72017-08-03 17:14:08 -0400199#Return Canvas if all parameters are valid; otherwise, nullptr ##
Cary Clark8032b982017-07-28 11:04:54 -0400200
201#Example
202 #Description
203 Allocates a three by three bitmap, clears it to white, and draws a black pixel
204 in the center.
205 ##
Cary Clarkbad5ad72017-08-03 17:14:08 -0400206void draw(SkCanvas* ) {
Cary Clarkce101242017-09-01 15:51:02 -0400207 SkImageInfo info = SkImageInfo::MakeN32Premul(3, 3); // device aligned, 32 bpp, Premultiplied
Cary Clarkbad5ad72017-08-03 17:14:08 -0400208 const size_t minRowBytes = info.minRowBytes(); // bytes used by one bitmap row
209 const size_t size = info.getSafeSize(minRowBytes); // bytes used by all rows
210 SkAutoTMalloc<SkPMColor> storage(size); // allocate storage for pixels
211 SkPMColor* pixels = storage.get(); // get pointer to allocated storage
212 // create a SkCanvas backed by a raster device, and delete it when the
213 // function goes out of scope.
214 std::unique_ptr<SkCanvas> canvas = SkCanvas::MakeRasterDirect(info, pixels, minRowBytes);
Cary Clarkce101242017-09-01 15:51:02 -0400215 canvas->clear(SK_ColorWHITE); // white is Unpremultiplied, in ARGB order
Cary Clarkbad5ad72017-08-03 17:14:08 -0400216 canvas->flush(); // ensure that pixels are cleared
Cary Clarkce101242017-09-01 15:51:02 -0400217 SkPMColor pmWhite = pixels[0]; // the Premultiplied format may vary
Cary Clarkbad5ad72017-08-03 17:14:08 -0400218 SkPaint paint; // by default, draws black
219 canvas->drawPoint(1, 1, paint); // draw in the center
220 canvas->flush(); // ensure that point was drawn
221 for (int y = 0; y < info.height(); ++y) {
222 for (int x = 0; x < info.width(); ++x) {
223 SkDebugf("%c", *pixels++ == pmWhite ? '-' : 'x');
224 }
225 SkDebugf("\n");
226 }
Cary Clark8032b982017-07-28 11:04:54 -0400227}
228 #StdOut
229 ---
230 -x-
231 ---
232 ##
233##
234
235#ToDo incomplete ##
236
237#SeeAlso MakeRasterDirectN32 SkSurface::MakeRasterDirect
238##
239
240# ------------------------------------------------------------------------------
241
242#Method static std::unique_ptr<SkCanvas> MakeRasterDirectN32(int width, int height, SkPMColor* pixels,
243 size_t rowBytes)
244
Cary Clarkbad5ad72017-08-03 17:14:08 -0400245Allocates raster Canvas specified by inline image specification. Subsequent Canvas
246calls draw into pixels.
Cary Clark8032b982017-07-28 11:04:54 -0400247Image_Color_Type is set to kN32_SkColorType.
248Image_Alpha_Type is set to kPremul_SkAlphaType.
249To access pixels after drawing, call flush() or peekPixels.
250
Cary Clarkbad5ad72017-08-03 17:14:08 -0400251Canvas is returned if all parameters are valid.
252Valid parameters include:
Cary Clarkf05bdda2017-08-24 12:59:48 -0400253width and height are zero or positive;
Cary Clarkbad5ad72017-08-03 17:14:08 -0400254pixels is not nullptr;
Cary Clarkf05bdda2017-08-24 12:59:48 -0400255rowBytes is zero or large enough to contain width pixels of kN32_SkColorType.
Cary Clarkbad5ad72017-08-03 17:14:08 -0400256
Cary Clarkce101242017-09-01 15:51:02 -0400257Pass zero for rowBytes to compute rowBytes from width and size of pixel.
Cary Clarkf05bdda2017-08-24 12:59:48 -0400258If rowBytes is greater than zero, it must be equal to or greater than
259width times bytes required for Image_Color_Type.
260
261Pixel buffer size should be height times rowBytes.
Cary Clarkbad5ad72017-08-03 17:14:08 -0400262
263#Param width pixel column count on Raster_Surface created; must be zero or greater ##
Cary Clarkbc5697d2017-10-04 14:31:33 -0400264#Param height pixel row count on Raster_Surface created; must be zero or greater ##
Cary Clarkbad5ad72017-08-03 17:14:08 -0400265#Param pixels pointer to destination pixels buffer; buffer size should be height
Cary Clarkf05bdda2017-08-24 12:59:48 -0400266 times rowBytes
Cary Clark8032b982017-07-28 11:04:54 -0400267##
Cary Clarkf05bdda2017-08-24 12:59:48 -0400268#Param rowBytes interval from one Surface row to the next, or zero
Cary Clark8032b982017-07-28 11:04:54 -0400269##
270
Cary Clarkbad5ad72017-08-03 17:14:08 -0400271#Return Canvas if all parameters are valid; otherwise, nullptr ##
Cary Clark8032b982017-07-28 11:04:54 -0400272
273#Example
274 #Description
275 Allocates a three by three bitmap, clears it to white, and draws a black pixel
276 in the center.
277 ##
278void draw(SkCanvas* ) {
279 const int width = 3;
280 const int height = 3;
Cary Clarkce101242017-09-01 15:51:02 -0400281 SkPMColor pixels[height][width]; // allocate a 3x3 Premultiplied bitmap on the stack
Cary Clark8032b982017-07-28 11:04:54 -0400282 // create a SkCanvas backed by a raster device, and delete it when the
283 // function goes out of scope.
284 std::unique_ptr<SkCanvas> canvas = SkCanvas::MakeRasterDirectN32(
285 width,
286 height,
Cary Clarkbc5697d2017-10-04 14:31:33 -0400287 pixels[0], // top-left of the bitmap
Cary Clark8032b982017-07-28 11:04:54 -0400288 sizeof(pixels[0])); // byte width of the each row
Cary Clarkce101242017-09-01 15:51:02 -0400289 // write a premultiplied value for white into all pixels in the bitmap
Cary Clark8032b982017-07-28 11:04:54 -0400290 canvas->clear(SK_ColorWHITE);
Cary Clarkce101242017-09-01 15:51:02 -0400291 SkPMColor pmWhite = pixels[0][0]; // the Premultiplied format may vary
Cary Clark8032b982017-07-28 11:04:54 -0400292 SkPaint paint; // by default, draws black
293 canvas->drawPoint(1, 1, paint); // draw in the center
294 canvas->flush(); // ensure that pixels is ready to be read
295 for (int y = 0; y < height; ++y) {
296 for (int x = 0; x < width; ++x) {
297 SkDebugf("%c", pixels[y][x] == pmWhite ? '-' : 'x');
298 }
299 SkDebugf("\n");
300 }
301}
302 #StdOut
303 ---
304 -x-
305 ---
306 ##
307##
308
309#ToDo incomplete ##
310
311##
312
313# ------------------------------------------------------------------------------
314
315#Method SkCanvas()
316
Cary Clarkd0530ba2017-09-14 11:25:39 -0400317Creates an empty Canvas with no backing device or pixels, with
Cary Clarkf05bdda2017-08-24 12:59:48 -0400318a width and height of zero.
Cary Clark8032b982017-07-28 11:04:54 -0400319
Cary Clarkd0530ba2017-09-14 11:25:39 -0400320#Return empty Canvas ##
Cary Clark8032b982017-07-28 11:04:54 -0400321
322#Example
323
324#Description
325Passes a placeholder to a function that requires one.
326##
327
328#Function
Cary Clarkbad5ad72017-08-03 17:14:08 -0400329// Returns true if either the canvas rotates the text by 90 degrees, or the paint does.
330static void check_for_up_and_down_text(const SkCanvas* canvas, const SkPaint& paint) {
331 bool paintHasVertical = paint.isVerticalText();
332 const SkMatrix& matrix = canvas->getTotalMatrix();
333 bool matrixIsVertical = matrix.preservesRightAngles() && !matrix.isScaleTranslate();
334 SkDebugf("paint draws text %s\n", paintHasVertical != matrixIsVertical ?
335 "top to bottom" : "left to right");
336}
337
338static void check_for_up_and_down_text(const SkPaint& paint) {
339 SkCanvas canvas; // placeholder only, does not have an associated device
340 check_for_up_and_down_text(&canvas, paint);
341}
342
Cary Clark8032b982017-07-28 11:04:54 -0400343##
Cary Clarkbad5ad72017-08-03 17:14:08 -0400344void draw(SkCanvas* canvas) {
345 SkPaint paint;
346 check_for_up_and_down_text(paint); // paint draws text left to right
347 paint.setVerticalText(true);
348 check_for_up_and_down_text(paint); // paint draws text top to bottom
349 paint.setVerticalText(false);
350 canvas->rotate(90);
351 check_for_up_and_down_text(canvas, paint); // paint draws text top to bottom
352}
Cary Clark8032b982017-07-28 11:04:54 -0400353
354 #StdOut
355 paint draws text left to right
356 paint draws text top to bottom
357 paint draws text top to bottom
358 ##
359##
360
361#ToDo incomplete ##
362
363##
364
365# ------------------------------------------------------------------------------
366
Cary Clark73fa9722017-08-29 17:36:51 -0400367#Method SkCanvas(int width, int height, const SkSurfaceProps* props = nullptr)
Cary Clark8032b982017-07-28 11:04:54 -0400368
369Creates Canvas of the specified dimensions without a Surface.
Cary Clarkce101242017-09-01 15:51:02 -0400370Used by Subclasses with custom implementations for draw methods.
Cary Clark8032b982017-07-28 11:04:54 -0400371
Cary Clarkd0530ba2017-09-14 11:25:39 -0400372If props equals nullptr, Surface_Properties are created with
373Surface_Properties_Legacy_Font_Host settings, which choose the pixel striping
374direction and order. Since a platform may dynamically change its direction when
375the device is rotated, and since a platform may have multiple monitors with
376different characteristics, it is best not to rely on this legacy behavior.
Cary Clark8032b982017-07-28 11:04:54 -0400377
Cary Clarkbad5ad72017-08-03 17:14:08 -0400378#Param width zero or greater ##
379#Param height zero or greater ##
380#Param props LCD striping orientation and setting for device independent fonts;
381 may be nullptr
382##
383
384#Return Canvas placeholder with dimensions ##
Cary Clark8032b982017-07-28 11:04:54 -0400385
386#Example
387 SkCanvas canvas(10, 20); // 10 units wide, 20 units high
388 canvas.clipRect(SkRect::MakeXYWH(30, 40, 5, 10)); // clip is outside canvas' device
389 SkDebugf("canvas %s empty\n", canvas.getDeviceClipBounds().isEmpty() ? "is" : "is not");
390
391 #StdOut
392 canvas is empty
393 ##
394##
395
Cary Clarkbad5ad72017-08-03 17:14:08 -0400396#SeeAlso SkSurfaceProps SkPixelGeometry
Cary Clark8032b982017-07-28 11:04:54 -0400397
398##
399
400# ------------------------------------------------------------------------------
401
402#Method explicit SkCanvas(SkBaseDevice* device)
403
404Construct a canvas that draws into device.
405Used by child classes of SkCanvas.
406
407#ToDo Since SkBaseDevice is private, shouldn't this be private also? ##
408
Cary Clarkbad5ad72017-08-03 17:14:08 -0400409#Param device specifies a device for the canvas to draw into ##
Cary Clark8032b982017-07-28 11:04:54 -0400410
Cary Clarkbad5ad72017-08-03 17:14:08 -0400411#Return Canvas that can be used to draw into device ##
Cary Clark8032b982017-07-28 11:04:54 -0400412
413#Example
414#Error "Unsure how to create a meaningful example."
415 SkPDFCanvas::SkPDFCanvas(const sk_sp<SkPDFDevice>& dev)
416 : SkCanvas(dev.get()) {}
417##
418
419#ToDo either remove doc of figure out a way to fiddle it ##
420
421##
422
423# ------------------------------------------------------------------------------
424
425#Method explicit SkCanvas(const SkBitmap& bitmap)
426
427Construct a canvas that draws into bitmap.
428Sets SkSurfaceProps::kLegacyFontHost_InitType in constructed Surface.
429
Cary Clarkbad5ad72017-08-03 17:14:08 -0400430Bitmap is copied so that subsequently editing bitmap will not affect
431constructed Canvas.
432
433May be deprecated in the future.
434
Cary Clark8032b982017-07-28 11:04:54 -0400435#ToDo Should be deprecated? ##
436
Cary Clarkbad5ad72017-08-03 17:14:08 -0400437#Param bitmap width, height, Image_Color_Type, Image_Alpha_Type, and pixel
438 storage of Raster_Surface
Cary Clark8032b982017-07-28 11:04:54 -0400439##
440
Cary Clarkbad5ad72017-08-03 17:14:08 -0400441#Return Canvas that can be used to draw into bitmap ##
Cary Clark8032b982017-07-28 11:04:54 -0400442
443#Example
444#Description
445The actual output depends on the installed fonts.
446##
447 SkBitmap bitmap;
448 // create a bitmap 5 wide and 11 high
449 bitmap.allocPixels(SkImageInfo::MakeN32Premul(5, 11));
450 SkCanvas canvas(bitmap);
Cary Clarkce101242017-09-01 15:51:02 -0400451 canvas.clear(SK_ColorWHITE); // white is Unpremultiplied, in ARGB order
Cary Clark8032b982017-07-28 11:04:54 -0400452 SkPixmap pixmap; // provides guaranteed access to the drawn pixels
453 if (!canvas.peekPixels(&pixmap)) {
454 SkDebugf("peekPixels should never fail.\n");
455 }
Cary Clarkbc5697d2017-10-04 14:31:33 -0400456 const SkPMColor* pixels = pixmap.addr32(); // points to top-left of bitmap
Cary Clarkce101242017-09-01 15:51:02 -0400457 SkPMColor pmWhite = pixels[0]; // the Premultiplied format may vary
Cary Clark8032b982017-07-28 11:04:54 -0400458 SkPaint paint; // by default, draws black, 12 point text
459 canvas.drawString("!", 1, 10, paint); // 1 char at baseline (1, 10)
460 for (int y = 0; y < bitmap.height(); ++y) {
461 for (int x = 0; x < bitmap.width(); ++x) {
462 SkDebugf("%c", *pixels++ == pmWhite ? '-' : 'x');
463 }
464 SkDebugf("\n");
465 }
466
467 #StdOut
Cary Clarkd0530ba2017-09-14 11:25:39 -0400468 -----
469 ---x-
470 ---x-
471 ---x-
472 ---x-
473 ---x-
474 ---x-
475 -----
476 ---x-
477 ---x-
Cary Clark8032b982017-07-28 11:04:54 -0400478 -----
479 #StdOut ##
480##
481
482#ToDo incomplete ##
483
484##
485
Cary Clarkbad5ad72017-08-03 17:14:08 -0400486#EnumClass ColorBehavior
Cary Clark8032b982017-07-28 11:04:54 -0400487
488#Private
489Android framework only.
490##
491
492#Code
493 enum class ColorBehavior {
494 kLegacy,
495 };
496##
497#Const kLegacy 0
Cary Clarkbad5ad72017-08-03 17:14:08 -0400498 Is a placeholder to allow specialized constructor; has no meaning.
Cary Clark8032b982017-07-28 11:04:54 -0400499##
500##
501
Cary Clarkbad5ad72017-08-03 17:14:08 -0400502#Method SkCanvas(const SkBitmap& bitmap, ColorBehavior behavior)
503
504#Private
505Android framework only.
506##
507
508#Param bitmap specifies a bitmap for the canvas to draw into ##
509#Param behavior specializes this constructor; value is unused ##
510#Return Canvas that can be used to draw into bitmap ##
511
512#NoExample
513##
514##
Cary Clark8032b982017-07-28 11:04:54 -0400515
516# ------------------------------------------------------------------------------
517
518#Method SkCanvas(const SkBitmap& bitmap, const SkSurfaceProps& props)
519
520Construct a canvas that draws into bitmap.
521Use props to match the device characteristics, like LCD striping.
522
Cary Clarkbad5ad72017-08-03 17:14:08 -0400523bitmap is copied so that subsequently editing bitmap will not affect
524constructed Canvas.
525
526#Param bitmap width, height, Image_Color_Type, Image_Alpha_Type,
527 and pixel storage of Raster_Surface
Cary Clark8032b982017-07-28 11:04:54 -0400528##
Cary Clarkbad5ad72017-08-03 17:14:08 -0400529#Param props order and orientation of RGB striping; and whether to use
530 device independent fonts
Cary Clark8032b982017-07-28 11:04:54 -0400531##
532
Cary Clarkbad5ad72017-08-03 17:14:08 -0400533#Return Canvas that can be used to draw into bitmap ##
Cary Clark8032b982017-07-28 11:04:54 -0400534
535#Example
536#Description
537The actual output depends on the installed fonts.
538##
539 SkBitmap bitmap;
540 // create a bitmap 5 wide and 11 high
541 bitmap.allocPixels(SkImageInfo::MakeN32Premul(5, 11));
542 SkCanvas canvas(bitmap, SkSurfaceProps(0, kUnknown_SkPixelGeometry));
Cary Clarkce101242017-09-01 15:51:02 -0400543 canvas.clear(SK_ColorWHITE); // white is Unpremultiplied, in ARGB order
Cary Clark8032b982017-07-28 11:04:54 -0400544 SkPixmap pixmap; // provides guaranteed access to the drawn pixels
545 if (!canvas.peekPixels(&pixmap)) {
546 SkDebugf("peekPixels should never fail.\n");
547 }
Cary Clarkbc5697d2017-10-04 14:31:33 -0400548 const SkPMColor* pixels = pixmap.addr32(); // points to top-left of bitmap
Cary Clarkce101242017-09-01 15:51:02 -0400549 SkPMColor pmWhite = pixels[0]; // the Premultiplied format may vary
Cary Clark8032b982017-07-28 11:04:54 -0400550 SkPaint paint; // by default, draws black, 12 point text
551 canvas.drawString("!", 1, 10, paint); // 1 char at baseline (1, 10)
552 for (int y = 0; y < bitmap.height(); ++y) {
553 for (int x = 0; x < bitmap.width(); ++x) {
554 SkDebugf("%c", *pixels++ == pmWhite ? '-' : 'x');
555 }
556 SkDebugf("\n");
557 }
558
559 #StdOut
560 -----
561 ---x-
562 ---x-
563 ---x-
564 ---x-
565 ---x-
566 ---x-
567 -----
568 ---x-
569 ---x-
570 -----
571 #StdOut ##
572##
573
574#ToDo incomplete ##
575
576##
577
578# ------------------------------------------------------------------------------
579
580#Method virtual ~SkCanvas()
581
Cary Clarkce101242017-09-01 15:51:02 -0400582Draw saved Layers, if any.
Cary Clark8032b982017-07-28 11:04:54 -0400583Free up resources used by Canvas.
584
585#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -0400586#Description
Cary Clarkce101242017-09-01 15:51:02 -0400587Canvas Layer draws into bitmap. saveLayerAlpha sets up an additional
588drawing surface that blends with the bitmap. When Layer goes out of
589scope, Layer Destructor is called. The saved Layer is restored, drawing
Cary Clarkbad5ad72017-08-03 17:14:08 -0400590transparent letters.
591##
Cary Clarkf05bdda2017-08-24 12:59:48 -0400592void draw(SkCanvas* canvas) {
593 SkBitmap bitmap;
594 bitmap.allocPixels(SkImageInfo::MakeN32Premul(200, 200));
595 {
596 SkCanvas offscreen(bitmap);
597 SkPaint paint;
598 paint.setTextSize(100);
599 offscreen.drawString("ABC", 20, 160, paint);
600 SkRect layerBounds = SkRect::MakeXYWH(32, 32, 192, 192);
601 offscreen.saveLayerAlpha(&layerBounds, 128);
602 offscreen.clear(SK_ColorWHITE);
603 offscreen.drawString("DEF", 20, 160, paint);
604 }
605 canvas->drawBitmap(bitmap, 0, 0, nullptr);
Cary Clarkbad5ad72017-08-03 17:14:08 -0400606}
Cary Clark8032b982017-07-28 11:04:54 -0400607##
608
Cary Clarkbad5ad72017-08-03 17:14:08 -0400609#SeeAlso State_Stack
Cary Clark8032b982017-07-28 11:04:54 -0400610
611##
612
613# ------------------------------------------------------------------------------
614
615#Method SkMetaData& getMetaData()
616
Cary Clarkf05bdda2017-08-24 12:59:48 -0400617Returns storage to associate additional data with the canvas.
Cary Clark8032b982017-07-28 11:04:54 -0400618The storage is freed when Canvas is deleted.
619
Cary Clarkbad5ad72017-08-03 17:14:08 -0400620#Return storage that can be read from and written to ##
Cary Clark8032b982017-07-28 11:04:54 -0400621
622#Example
623 const char* kHelloMetaData = "HelloMetaData";
624 SkCanvas canvas;
625 SkMetaData& metaData = canvas.getMetaData();
626 SkDebugf("before: %s\n", metaData.findString(kHelloMetaData));
627 metaData.setString(kHelloMetaData, "Hello!");
628 SkDebugf("during: %s\n", metaData.findString(kHelloMetaData));
629 metaData.removeString(kHelloMetaData);
630 SkDebugf("after: %s\n", metaData.findString(kHelloMetaData));
631
632 #StdOut
633 before: (null)
634 during: Hello!
635 after: (null)
636 #StdOut ##
637##
638
639#ToDo incomplete ##
640
641##
642
643# ------------------------------------------------------------------------------
644
645#Method SkImageInfo imageInfo() const
646
647Returns Image_Info for Canvas. If Canvas is not associated with Raster_Surface or
Cary Clarkbad5ad72017-08-03 17:14:08 -0400648GPU_Surface, returned Image_Color_Type is set to kUnknown_SkColorType.
Cary Clark8032b982017-07-28 11:04:54 -0400649
Cary Clarkbad5ad72017-08-03 17:14:08 -0400650#Return dimensions and Image_Color_Type of Canvas ##
Cary Clark8032b982017-07-28 11:04:54 -0400651
652#Example
Cary Clarkf05bdda2017-08-24 12:59:48 -0400653 SkCanvas emptyCanvas;
654 SkImageInfo canvasInfo = emptyCanvas.imageInfo();
655 SkImageInfo emptyInfo;
656 SkDebugf("emptyInfo %c= canvasInfo\n", emptyInfo == canvasInfo ? '=' : '!');
657
658 #StdOut
659 emptyInfo == canvasInfo
660 ##
Cary Clark8032b982017-07-28 11:04:54 -0400661##
662
663#ToDo incomplete ##
664
665##
666
667# ------------------------------------------------------------------------------
668
669#Method bool getProps(SkSurfaceProps* props) const
670
671If Canvas is associated with Raster_Surface or
672GPU_Surface, copies Surface_Properties and returns true. Otherwise,
673return false and leave props unchanged.
674
Cary Clarkbad5ad72017-08-03 17:14:08 -0400675#Param props storage for writable SkSurfaceProps ##
Cary Clark8032b982017-07-28 11:04:54 -0400676
Cary Clarkbad5ad72017-08-03 17:14:08 -0400677#Return true if Surface_Properties was copied ##
Cary Clark8032b982017-07-28 11:04:54 -0400678
679#ToDo This seems old style. Deprecate? ##
680
681#Example
682 SkBitmap bitmap;
683 SkCanvas canvas(bitmap, SkSurfaceProps(0, kRGB_V_SkPixelGeometry));
684 SkSurfaceProps surfaceProps(0, kUnknown_SkPixelGeometry);
685 SkDebugf("isRGB:%d\n", SkPixelGeometryIsRGB(surfaceProps.pixelGeometry()));
686 if (!canvas.getProps(&surfaceProps)) {
687 SkDebugf("getProps failed unexpectedly.\n");
688 }
689 SkDebugf("isRGB:%d\n", SkPixelGeometryIsRGB(surfaceProps.pixelGeometry()));
690
691 #StdOut
692 isRGB:0
693 isRGB:1
694 #StdOut ##
695##
696
697#ToDo incomplete ##
698
699##
700
701# ------------------------------------------------------------------------------
702
703#Method void flush()
704
705Triggers the immediate execution of all pending draw operations.
Cary Clarkbad5ad72017-08-03 17:14:08 -0400706If Canvas is associated with GPU_Surface, resolves all pending GPU operations.
Cary Clark8032b982017-07-28 11:04:54 -0400707
708#Example
709#Error "haven't thought of a useful example to put here"
710##
711
712#ToDo incomplete ##
713
714##
715
716# ------------------------------------------------------------------------------
717
718#Method virtual SkISize getBaseLayerSize() const
719
Cary Clarkce101242017-09-01 15:51:02 -0400720Gets the size of the base or root Layer in global canvas coordinates. The
721origin of the base Layer is always (0,0). The area available for drawing may be
Cary Clark8032b982017-07-28 11:04:54 -0400722smaller (due to clipping or saveLayer).
723
Cary Clarkce101242017-09-01 15:51:02 -0400724#Return integral width and height of base Layer ##
Cary Clark8032b982017-07-28 11:04:54 -0400725
726#Example
727 SkBitmap bitmap;
728 bitmap.allocPixels(SkImageInfo::MakeN32Premul(20, 30));
729 SkCanvas canvas(bitmap, SkSurfaceProps(0, kUnknown_SkPixelGeometry));
730 canvas.clipRect(SkRect::MakeWH(10, 40));
731 SkIRect clipDeviceBounds = canvas.getDeviceClipBounds();
732 if (clipDeviceBounds.isEmpty()) {
733 SkDebugf("Empty clip bounds is unexpected!\n");
734 }
735 SkDebugf("clip=%d,%d\n", clipDeviceBounds.width(), clipDeviceBounds.height());
736 SkISize baseLayerSize = canvas.getBaseLayerSize();
737 SkDebugf("size=%d,%d\n", baseLayerSize.width(), baseLayerSize.height());
738
739 #StdOut
740 clip=10,30
741 size=20,30
742 ##
743##
744
745#ToDo is this the same as the width and height of surface? ##
746
747##
748
749# ------------------------------------------------------------------------------
750
751#Method sk_sp<SkSurface> makeSurface(const SkImageInfo& info, const SkSurfaceProps* props = nullptr)
752
753Creates Surface matching info and props, and associates it with Canvas.
Cary Clarkbad5ad72017-08-03 17:14:08 -0400754Returns nullptr if no match found.
Cary Clark8032b982017-07-28 11:04:54 -0400755
Cary Clarkbad5ad72017-08-03 17:14:08 -0400756If props is nullptr, matches Surface_Properties in Canvas. If props is nullptr and Canvas
757does not have Surface_Properties, creates Surface with default Surface_Properties.
Cary Clark8032b982017-07-28 11:04:54 -0400758
Cary Clarkbad5ad72017-08-03 17:14:08 -0400759#Param info width, height, Image_Color_Type, Image_Alpha_Type, and Color_Space ##
760#Param props Surface_Properties to match; may be nullptr to match Canvas ##
761
762#Return Surface matching info and props, or nullptr if no match is available ##
Cary Clark8032b982017-07-28 11:04:54 -0400763
764#Example
765 sk_sp<SkSurface> surface = SkSurface::MakeRasterN32Premul(5, 6);
766 SkCanvas* smallCanvas = surface->getCanvas();
767 SkImageInfo imageInfo = SkImageInfo::MakeN32Premul(3, 4);
768 sk_sp<SkSurface> compatible = smallCanvas->makeSurface(imageInfo);
769 SkDebugf("compatible %c= nullptr\n", compatible == nullptr ? '=' : '!');
770 SkDebugf("size = %d, %d\n", compatible->width(), compatible->height());
771
772 #StdOut
Cary Clarkbad5ad72017-08-03 17:14:08 -0400773 compatible != nullptr
Cary Clark8032b982017-07-28 11:04:54 -0400774 size = 3, 4
775 ##
776##
777
778#ToDo incomplete ##
779
780##
781
782# ------------------------------------------------------------------------------
783
784#Method virtual GrContext* getGrContext()
785
786Returns GPU_Context of the GPU_Surface associated with Canvas.
787
Cary Clarkbad5ad72017-08-03 17:14:08 -0400788#Return GPU_Context, if available; nullptr otherwise ##
Cary Clark8032b982017-07-28 11:04:54 -0400789
790#Example
791void draw(SkCanvas* canvas) {
792 if (canvas->getGrContext()) {
793 canvas->clear(SK_ColorRED);
794 } else {
795 canvas->clear(SK_ColorBLUE);
796 }
797}
798##
799
800#ToDo fiddle should show both CPU and GPU out ##
801
802##
803
804# ------------------------------------------------------------------------------
805
Cary Clark73fa9722017-08-29 17:36:51 -0400806#Method void* accessTopLayerPixels(SkImageInfo* info, size_t* rowBytes, SkIPoint* origin = nullptr)
Cary Clark8032b982017-07-28 11:04:54 -0400807
808Returns the pixel base address, Image_Info, rowBytes, and origin if the pixels
Cary Clarkbad5ad72017-08-03 17:14:08 -0400809can be read directly. The returned address is only valid
Cary Clark8032b982017-07-28 11:04:54 -0400810while Canvas is in scope and unchanged. Any Canvas call or Surface call
811may invalidate the returned address and other returned values.
812
813If pixels are inaccessible, info, rowBytes, and origin are unchanged.
814
Cary Clarkbad5ad72017-08-03 17:14:08 -0400815#Param info storage for writable pixels' Image_Info; may be nullptr ##
816#Param rowBytes storage for writable pixels' row bytes; may be nullptr ##
Cary Clarkbc5697d2017-10-04 14:31:33 -0400817#Param origin storage for Canvas top Layer origin, its top-left corner;
Cary Clarkbad5ad72017-08-03 17:14:08 -0400818 may be nullptr
819##
Cary Clark8032b982017-07-28 11:04:54 -0400820
Cary Clarka523d2d2017-08-30 08:58:10 -0400821#Return address of pixels, or nullptr if inaccessible ##
Cary Clark8032b982017-07-28 11:04:54 -0400822
823#Example
824void draw(SkCanvas* canvas) {
825 if (canvas->accessTopLayerPixels(nullptr, nullptr)) {
826 canvas->clear(SK_ColorRED);
827 } else {
828 canvas->clear(SK_ColorBLUE);
829 }
830}
831##
832
833#Example
834#Description
Cary Clarkce101242017-09-01 15:51:02 -0400835Draws "ABC" on the device. Then draws "DEF" in Layer, and reads
836Layer to add a large dotted "DEF". Finally blends Layer with the
Cary Clark8032b982017-07-28 11:04:54 -0400837device.
838
Cary Clarkce101242017-09-01 15:51:02 -0400839The Layer and blended result appear on the CPU and GPU but the large dotted
Cary Clark8032b982017-07-28 11:04:54 -0400840"DEF" appear only on the CPU.
841##
842void draw(SkCanvas* canvas) {
Cary Clarkbad5ad72017-08-03 17:14:08 -0400843 SkPaint paint;
844 paint.setTextSize(100);
845 canvas->drawString("ABC", 20, 160, paint);
846 SkRect layerBounds = SkRect::MakeXYWH(32, 32, 192, 192);
847 canvas->saveLayerAlpha(&layerBounds, 128);
848 canvas->clear(SK_ColorWHITE);
849 canvas->drawString("DEF", 20, 160, paint);
850 SkImageInfo imageInfo;
851 size_t rowBytes;
852 SkIPoint origin;
853 uint32_t* access = (uint32_t*) canvas->accessTopLayerPixels(&imageInfo, &rowBytes, &origin);
854 if (access) {
855 int h = imageInfo.height();
856 int v = imageInfo.width();
857 int rowWords = rowBytes / sizeof(uint32_t);
858 for (int y = 0; y < h; ++y) {
859 int newY = (y - h / 2) * 2 + h / 2;
860 if (newY < 0 || newY >= h) {
861 continue;
862 }
863 for (int x = 0; x < v; ++x) {
864 int newX = (x - v / 2) * 2 + v / 2;
865 if (newX < 0 || newX >= v) {
866 continue;
867 }
868 if (access[y * rowWords + x] == SK_ColorBLACK) {
869 access[newY * rowWords + newX] = SK_ColorGRAY;
870 }
871 }
872 }
873
874 }
Cary Clark8032b982017-07-28 11:04:54 -0400875 canvas->restore();
876}
877##
878
879#ToDo there are no callers of this that I can find. Deprecate? ##
880#ToDo fiddle should show both CPU and GPU out ##
881
882##
883
884# ------------------------------------------------------------------------------
885
886#Method SkRasterHandleAllocator::Handle accessTopRasterHandle() const
887
888Returns custom context that tracks the Matrix and Clip.
889
890Use Raster_Handle_Allocator to blend Skia drawing with custom drawing, typically performed
Cary Clarkbc5697d2017-10-04 14:31:33 -0400891by the host platform user interface. The custom context returned is generated by
Cary Clarkbad5ad72017-08-03 17:14:08 -0400892SkRasterHandleAllocator::MakeCanvas, which creates a custom canvas with raster storage for
Cary Clark8032b982017-07-28 11:04:54 -0400893the drawing destination.
894
Cary Clarkce101242017-09-01 15:51:02 -0400895#Return context of custom allocation ##
Cary Clark8032b982017-07-28 11:04:54 -0400896
897#Example
898#Description
899#ToDo ##
900##
901#Function
902 static void DeleteCallback(void*, void* context) {
903 delete (char*) context;
904 }
905
906 class CustomAllocator : public SkRasterHandleAllocator {
907 public:
908 bool allocHandle(const SkImageInfo& info, Rec* rec) override {
909 char* context = new char[4]{'s', 'k', 'i', 'a'};
910 rec->fReleaseProc = DeleteCallback;
911 rec->fReleaseCtx = context;
912 rec->fHandle = context;
913 rec->fPixels = context;
914 rec->fRowBytes = 4;
915 return true;
916 }
917
918 void updateHandle(Handle handle, const SkMatrix& ctm, const SkIRect& clip_bounds) override {
919 // apply canvas matrix and clip to custom environment
920 }
921 };
922
923##
924 void draw(SkCanvas* canvas) {
925 const SkImageInfo info = SkImageInfo::MakeN32Premul(1, 1);
926 std::unique_ptr<SkCanvas> c2 =
927 SkRasterHandleAllocator::MakeCanvas(std::unique_ptr<CustomAllocator>(
928 new CustomAllocator()), info);
929 char* context = (char*) c2->accessTopRasterHandle();
930 SkDebugf("context = %.4s\n", context);
931
932 }
933 #StdOut
934 context = skia
935 ##
936 #ToDo skstd::make_unique could not be used because def is private -- note to fix in c++14? ##
937##
938
939#SeeAlso SkRasterHandleAllocator
940
941##
942
943# ------------------------------------------------------------------------------
944
945#Method bool peekPixels(SkPixmap* pixmap)
946
947Returns true if Canvas has direct access to its pixels.
948
Cary Clarkf05bdda2017-08-24 12:59:48 -0400949Pixels are readable when Device is raster. Pixels are not readable when Canvas
Cary Clarkbad5ad72017-08-03 17:14:08 -0400950is returned from GPU_Surface, returned by SkDocument::beginPage, returned by
Cary Clarkf05bdda2017-08-24 12:59:48 -0400951SkPictureRecorder::beginRecording, or Canvas is the base of a utility class
Cary Clarkbad5ad72017-08-03 17:14:08 -0400952like SkDumpCanvas.
Cary Clark8032b982017-07-28 11:04:54 -0400953
Cary Clarkf05bdda2017-08-24 12:59:48 -0400954pixmap is valid only while Canvas is in scope and unchanged. Any
Cary Clarkbad5ad72017-08-03 17:14:08 -0400955Canvas or Surface call may invalidate the pixmap values.
Cary Clark8032b982017-07-28 11:04:54 -0400956
Cary Clarkbc5697d2017-10-04 14:31:33 -0400957#Param pixmap storage for pixel state if pixels are readable; otherwise, ignored ##
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 Clark154beea2017-10-26 07:58:48 -0400978Copies Rect of pixels from Canvas into dstPixels. Matrix and Clip are
979ignored. Source Rect corners are (srcX, srcY) and
980(imageInfo().width(), imageInfo().height()).
Cary Clark6fc50412017-09-21 12:31:06 -0400981
Cary Clark154beea2017-10-26 07:58:48 -0400982Destination Rect corners are (0, 0) and (bitmap.width(), bitmap.height()).
Cary Clark6fc50412017-09-21 12:31:06 -0400983Copies each readable pixel intersecting both rectangles, without scaling,
Cary Clarkf05bdda2017-08-24 12:59:48 -0400984converting to dstInfo.colorType() and dstInfo.alphaType() if required.
Cary Clark8032b982017-07-28 11:04:54 -0400985
Cary Clarkf05bdda2017-08-24 12:59:48 -0400986Pixels are readable when Device is raster, or backed by a GPU.
987Pixels are not readable when SkCanvas is returned by SkDocument::beginPage,
988returned by SkPictureRecorder::beginRecording, or Canvas is the base of a utility
989class like SkDumpCanvas.
Cary Clark8032b982017-07-28 11:04:54 -0400990
Cary Clarkf05bdda2017-08-24 12:59:48 -0400991The destination pixel storage must be allocated by the caller.
Cary Clark8032b982017-07-28 11:04:54 -0400992
Cary Clarkf05bdda2017-08-24 12:59:48 -0400993Pixel values are converted only if Image_Color_Type and Image_Alpha_Type
994do not match. Only pixels within both source and destination rectangles
Cary Clark154beea2017-10-26 07:58:48 -0400995are copied. dstPixels contents outside Rect intersection are unchanged.
Cary Clarkf05bdda2017-08-24 12:59:48 -0400996
997Pass negative values for srcX or srcY to offset pixels across or down destination.
Cary Clark8032b982017-07-28 11:04:54 -0400998
999Does not copy, and returns false if:
1000
1001#List
Cary Clarkf05bdda2017-08-24 12:59:48 -04001002# Source and destination rectangles do not intersect. ##
1003# Canvas pixels could not be converted to dstInfo.colorType() or dstInfo.alphaType(). ##
1004# Canvas pixels are not readable; for instance, Canvas is document-based. ##
Cary Clark8032b982017-07-28 11:04:54 -04001005# dstRowBytes is too small to contain one row of pixels. ##
1006##
1007
Cary Clarkf05bdda2017-08-24 12:59:48 -04001008#Param dstInfo width, height, Image_Color_Type, and Image_Alpha_Type of dstPixels ##
1009#Param dstPixels storage for pixels; dstInfo.height() times dstRowBytes, or larger ##
1010#Param dstRowBytes size of one destination row; dstInfo.width() times pixel size, or larger ##
1011#Param srcX offset into readable pixels in x; may be negative ##
1012#Param srcY offset into readable pixels in y; may be negative ##
Cary Clark8032b982017-07-28 11:04:54 -04001013
Cary Clarkbad5ad72017-08-03 17:14:08 -04001014#Return true if pixels were copied ##
Cary Clark8032b982017-07-28 11:04:54 -04001015
1016#Example
Cary Clarkf05bdda2017-08-24 12:59:48 -04001017#Width 64
1018#Height 64
1019#Description
1020 A black circle drawn on a blue background provides an image to copy.
1021 readPixels copies one quarter of the canvas into each of the four corners.
Cary Clarkce101242017-09-01 15:51:02 -04001022 The Layer draws over the image.
Cary Clarkf05bdda2017-08-24 12:59:48 -04001023##
1024 canvas->clear(SK_ColorBLUE);
1025 SkPaint paint;
1026 canvas->drawCircle(32, 32, 28, paint);
1027 SkImageInfo info = SkImageInfo::Make(64, 64, kBGRA_8888_SkColorType, kPremul_SkAlphaType);
1028 sk_sp<SkData> data(SkData::MakeUninitialized(info.minRowBytes() * info.height()));
1029 sk_bzero(data->writable_data(), info.minRowBytes() * info.height());
1030 for (int x : { 32, -32 } ) {
1031 for (int y : { 32, -32 } ) {
1032 canvas->readPixels(info, data->writable_data(), info.minRowBytes(), x, y);
1033 }
1034 }
1035 sk_sp<SkImage> image = SkImage::MakeRasterData(info, data, info.minRowBytes());
1036 canvas->drawImage(image, 0, 0);
1037##
1038
1039#Example
Cary Clark8032b982017-07-28 11:04:54 -04001040#Description
Cary Clarkce101242017-09-01 15:51:02 -04001041 Canvas returned by Raster_Surface has Premultiplied pixel values.
1042 clear() takes Unpremultiplied input with Color_Alpha equal 0x80
1043 and Color_RGB equal 0x55, 0xAA, 0xFF. Color_RGB is multiplied by Color_Alpha
1044 to generate Premultiplied value 0x802B5580. readPixels converts pixel back
1045 to Unpremultiplied value 0x8056A9FF, introducing error.
Cary Clark8032b982017-07-28 11:04:54 -04001046##
1047 canvas->clear(0x8055aaff);
1048 for (SkAlphaType alphaType : { kPremul_SkAlphaType, kUnpremul_SkAlphaType } ) {
1049 uint32_t pixel = 0;
1050 SkImageInfo info = SkImageInfo::Make(1, 1, kBGRA_8888_SkColorType, alphaType);
1051 if (canvas->readPixels(info, &pixel, 4, 0, 0)) {
1052 SkDebugf("pixel = %08x\n", pixel);
1053 }
1054 }
1055
1056 #StdOut
1057 pixel = 802b5580
1058 pixel = 8056a9ff
1059 ##
1060##
1061
Cary Clarkf05bdda2017-08-24 12:59:48 -04001062#SeeAlso peekPixels writePixels drawBitmap drawImage
Cary Clark8032b982017-07-28 11:04:54 -04001063
1064##
1065
1066# ------------------------------------------------------------------------------
1067
1068#Method bool readPixels(const SkPixmap& pixmap, int srcX, int srcY)
1069
Cary Clark154beea2017-10-26 07:58:48 -04001070Copies Rect of pixels from Canvas into pixmap. Matrix and Clip are
1071ignored. Source Rect corners are (srcX, srcY) and
1072(imageInfo().width(), imageInfo().height()).
Cary Clark6fc50412017-09-21 12:31:06 -04001073
Cary Clark154beea2017-10-26 07:58:48 -04001074Destination Rect corners are (0, 0) and (bitmap.width(), bitmap.height()).
Cary Clark6fc50412017-09-21 12:31:06 -04001075Copies each readable pixel intersecting both rectangles, without scaling,
Cary Clarkf05bdda2017-08-24 12:59:48 -04001076converting to pixmap.colorType() and pixmap.alphaType() if required.
Cary Clark8032b982017-07-28 11:04:54 -04001077
Cary Clarkf05bdda2017-08-24 12:59:48 -04001078Pixels are readable when Device is raster, or backed by a GPU.
1079Pixels are not readable when SkCanvas is returned by SkDocument::beginPage,
1080returned by SkPictureRecorder::beginRecording, or Canvas is the base of a utility
1081class like SkDumpCanvas.
Cary Clark8032b982017-07-28 11:04:54 -04001082
Cary Clark6fc50412017-09-21 12:31:06 -04001083Caller must allocate pixel storage in pixmap if needed.
Cary Clark8032b982017-07-28 11:04:54 -04001084
Cary Clarkf05bdda2017-08-24 12:59:48 -04001085Pixel values are converted only if Image_Color_Type and Image_Alpha_Type
Cary Clark154beea2017-10-26 07:58:48 -04001086do not match. Only pixels within both source and destination Rects
1087are copied. pixmap pixels contents outside Rect intersection are unchanged.
Cary Clarkf05bdda2017-08-24 12:59:48 -04001088
1089Pass negative values for srcX or srcY to offset pixels across or down pixmap.
Cary Clark8032b982017-07-28 11:04:54 -04001090
1091Does not copy, and returns false if:
1092
1093#List
Cary Clarkf05bdda2017-08-24 12:59:48 -04001094# Source and destination rectangles do not intersect. ##
1095# Canvas pixels could not be converted to pixmap.colorType() or pixmap.alphaType(). ##
1096# Canvas pixels are not readable; for instance, Canvas is document-based. ##
1097# Pixmap pixels could not be allocated. ##
1098# pixmap.rowBytes() is too small to contain one row of pixels. ##
Cary Clark8032b982017-07-28 11:04:54 -04001099##
1100
Cary Clarkbad5ad72017-08-03 17:14:08 -04001101#Param pixmap storage for pixels copied from Canvas ##
Cary Clarkf05bdda2017-08-24 12:59:48 -04001102#Param srcX offset into readable pixels in x; may be negative ##
1103#Param srcY offset into readable pixels in y; may be negative ##
Cary Clark8032b982017-07-28 11:04:54 -04001104
Cary Clarkbad5ad72017-08-03 17:14:08 -04001105#Return true if pixels were copied ##
Cary Clark8032b982017-07-28 11:04:54 -04001106
1107#Example
Cary Clarkf05bdda2017-08-24 12:59:48 -04001108 #Description
Cary Clarkce101242017-09-01 15:51:02 -04001109 clear() takes Unpremultiplied input with Color_Alpha equal 0x80
1110 and Color_RGB equal 0x55, 0xAA, 0xFF. Color_RGB is multiplied by Color_Alpha
1111 to generate Premultiplied value 0x802B5580.
Cary Clarkf05bdda2017-08-24 12:59:48 -04001112 ##
1113 void draw(SkCanvas* canvas) {
1114 canvas->clear(0x8055aaff);
1115 uint32_t pixels[1] = { 0 };
1116 SkPixmap pixmap(SkImageInfo::MakeN32Premul(1, 1), pixels, 4);
1117 canvas->readPixels(pixmap, 0, 0);
1118 SkDebugf("pixel = %08x\n", pixels[0]);
1119 }
Cary Clark8032b982017-07-28 11:04:54 -04001120 #StdOut
1121 pixel = 802b5580
1122 ##
1123##
1124
Cary Clarkf05bdda2017-08-24 12:59:48 -04001125#SeeAlso peekPixels writePixels drawBitmap drawImage
Cary Clark8032b982017-07-28 11:04:54 -04001126
1127##
1128
1129# ------------------------------------------------------------------------------
1130
1131#Method bool readPixels(const SkBitmap& bitmap, int srcX, int srcY)
1132
Cary Clark154beea2017-10-26 07:58:48 -04001133Copies Rect of pixels from Canvas into bitmap. Matrix and Clip are
1134ignored. Source Rect corners are (srcX, srcY) and
1135(imageInfo().width(), imageInfo().height()).
Cary Clark6fc50412017-09-21 12:31:06 -04001136
Cary Clark154beea2017-10-26 07:58:48 -04001137Destination Rect corners are (0, 0) and (bitmap.width(), bitmap.height()).
Cary Clarkf05bdda2017-08-24 12:59:48 -04001138Copies each readable pixel intersecting both rectangles, without scaling,
1139converting to bitmap.colorType() and bitmap.alphaType() if required.
Cary Clark8032b982017-07-28 11:04:54 -04001140
Cary Clarkf05bdda2017-08-24 12:59:48 -04001141Pixels are readable when Device is raster, or backed by a GPU.
1142Pixels are not readable when SkCanvas is returned by SkDocument::beginPage,
1143returned by SkPictureRecorder::beginRecording, or Canvas is the base of a utility
1144class like SkDumpCanvas.
Cary Clark8032b982017-07-28 11:04:54 -04001145
Cary Clark6fc50412017-09-21 12:31:06 -04001146Caller must allocate pixel storage in bitmap if needed.
Cary Clarkf05bdda2017-08-24 12:59:48 -04001147
1148Bitmap values are converted only if Image_Color_Type and Image_Alpha_Type
1149do not match. Only pixels within both source and destination rectangles
Cary Clark154beea2017-10-26 07:58:48 -04001150are copied. Bitmap pixels outside Rect intersection are unchanged.
Cary Clarkf05bdda2017-08-24 12:59:48 -04001151
1152Pass negative values for srcX or srcY to offset pixels across or down bitmap.
Cary Clark8032b982017-07-28 11:04:54 -04001153
1154Does not copy, and returns false if:
1155
1156#List
Cary Clarkf05bdda2017-08-24 12:59:48 -04001157# Source and destination rectangles do not intersect. ##
1158# Canvas pixels could not be converted to bitmap.colorType() or bitmap.alphaType(). ##
1159# Canvas pixels are not readable; for instance, Canvas is document-based. ##
Cary Clark8032b982017-07-28 11:04:54 -04001160# bitmap pixels could not be allocated. ##
Cary Clarkf05bdda2017-08-24 12:59:48 -04001161# bitmap.rowBytes() is too small to contain one row of pixels. ##
Cary Clark8032b982017-07-28 11:04:54 -04001162##
1163
Cary Clarkbad5ad72017-08-03 17:14:08 -04001164#Param bitmap storage for pixels copied from Canvas ##
Cary Clarkf05bdda2017-08-24 12:59:48 -04001165#Param srcX offset into readable pixels in x; may be negative ##
1166#Param srcY offset into readable pixels in y; may be negative ##
Cary Clark8032b982017-07-28 11:04:54 -04001167
Cary Clarkbad5ad72017-08-03 17:14:08 -04001168#Return true if pixels were copied ##
Cary Clark8032b982017-07-28 11:04:54 -04001169
1170#Example
Cary Clarkf05bdda2017-08-24 12:59:48 -04001171 #Description
Cary Clarkce101242017-09-01 15:51:02 -04001172 clear() takes Unpremultiplied input with Color_Alpha equal 0x80
1173 and Color_RGB equal 0x55, 0xAA, 0xFF. Color_RGB is multiplied by Color_Alpha
1174 to generate Premultiplied value 0x802B5580.
Cary Clarkf05bdda2017-08-24 12:59:48 -04001175 ##
Cary Clark8032b982017-07-28 11:04:54 -04001176void draw(SkCanvas* canvas) {
1177 canvas->clear(0x8055aaff);
1178 SkBitmap bitmap;
1179 bitmap.allocPixels(SkImageInfo::MakeN32Premul(1, 1));
1180 canvas->readPixels(bitmap, 0, 0);
1181 SkDebugf("pixel = %08x\n", bitmap.getAddr32(0, 0)[0]);
1182}
1183 #StdOut
1184 pixel = 802b5580
1185 ##
1186##
1187
Cary Clarkf05bdda2017-08-24 12:59:48 -04001188#SeeAlso peekPixels writePixels drawBitmap drawImage
Cary Clark8032b982017-07-28 11:04:54 -04001189
1190##
1191
1192# ------------------------------------------------------------------------------
1193
1194#Method bool writePixels(const SkImageInfo& info, const void* pixels, size_t rowBytes, int x, int y)
1195
Cary Clark154beea2017-10-26 07:58:48 -04001196Copies Rect from pixels to Canvas. Matrix and Clip are ignored.
1197Source Rect corners are (0, 0) and (info.width(), info.height()).
1198Destination Rect corners are (x, y) and
1199(imageInfo().width(), imageInfo().height()).
Cary Clark6fc50412017-09-21 12:31:06 -04001200
1201Copies each readable pixel intersecting both rectangles, without scaling,
Cary Clark154beea2017-10-26 07:58:48 -04001202converting to imageInfo().colorType() and imageInfo().alphaType() if required.
Cary Clark8032b982017-07-28 11:04:54 -04001203
Cary Clarkf05bdda2017-08-24 12:59:48 -04001204Pixels are writable when Device is raster, or backed by a GPU.
1205Pixels are not writable when SkCanvas is returned by SkDocument::beginPage,
1206returned by SkPictureRecorder::beginRecording, or Canvas is the base of a utility
1207class like SkDumpCanvas.
Cary Clark8032b982017-07-28 11:04:54 -04001208
Cary Clarkf05bdda2017-08-24 12:59:48 -04001209Pixel values are converted only if Image_Color_Type and Image_Alpha_Type
1210do not match. Only pixels within both source and destination rectangles
Cary Clark154beea2017-10-26 07:58:48 -04001211are copied. Canvas pixels outside Rect intersection are unchanged.
Cary Clark8032b982017-07-28 11:04:54 -04001212
Cary Clarkf05bdda2017-08-24 12:59:48 -04001213Pass negative values for x or y to offset pixels to the left or
1214above Canvas pixels.
Cary Clark8032b982017-07-28 11:04:54 -04001215
1216Does not copy, and returns false if:
1217
1218#List
Cary Clarkf05bdda2017-08-24 12:59:48 -04001219# Source and destination rectangles do not intersect. ##
Cary Clark154beea2017-10-26 07:58:48 -04001220# pixels could not be converted to this->imageInfo().colorType() or
1221this->imageInfo().alphaType(). ##
Cary Clark8032b982017-07-28 11:04:54 -04001222# Canvas pixels are not writable; for instance, Canvas is document-based. ##
1223# rowBytes is too small to contain one row of pixels. ##
1224##
1225
Cary Clarkf05bdda2017-08-24 12:59:48 -04001226#Param info width, height, Image_Color_Type, and Image_Alpha_Type of pixels ##
1227#Param pixels pixels to copy, of size info.height() times rowBytes, or larger ##
Cary Clarkd0530ba2017-09-14 11:25:39 -04001228#Param rowBytes size of one row of pixels; info.width() times pixel size, or larger ##
Cary Clarkf05bdda2017-08-24 12:59:48 -04001229#Param x offset into Canvas writable pixels in x; may be negative ##
1230#Param y offset into Canvas writable pixels in y; may be negative ##
Cary Clark8032b982017-07-28 11:04:54 -04001231
Cary Clarkbad5ad72017-08-03 17:14:08 -04001232#Return true if pixels were written to Canvas ##
Cary Clark8032b982017-07-28 11:04:54 -04001233
1234#Example
1235 SkImageInfo imageInfo = SkImageInfo::MakeN32(256, 1, kPremul_SkAlphaType);
1236 for (int y = 0; y < 256; ++y) {
1237 uint32_t pixels[256];
1238 for (int x = 0; x < 256; ++x) {
1239 pixels[x] = SkColorSetARGB(x, x + y, x, x - y);
1240 }
1241 canvas->writePixels(imageInfo, &pixels, sizeof(pixels), 0, y);
1242 }
1243##
1244
Cary Clarkf05bdda2017-08-24 12:59:48 -04001245#SeeAlso readPixels drawBitmap drawImage
Cary Clark8032b982017-07-28 11:04:54 -04001246
1247##
1248
1249# ------------------------------------------------------------------------------
1250
1251#Method bool writePixels(const SkBitmap& bitmap, int x, int y)
1252
Cary Clark154beea2017-10-26 07:58:48 -04001253Copies Rect from pixels to Canvas. Matrix and Clip are ignored.
1254Source Rect corners are (0, 0) and (bitmap.width(), bitmap.height()).
Cary Clark6fc50412017-09-21 12:31:06 -04001255
Cary Clark154beea2017-10-26 07:58:48 -04001256Destination Rect corners are (x, y) and
1257(imageInfo().width(), imageInfo().height()).
Cary Clark6fc50412017-09-21 12:31:06 -04001258
1259Copies each readable pixel intersecting both rectangles, without scaling,
Cary Clark154beea2017-10-26 07:58:48 -04001260converting to imageInfo().colorType() and imageInfo().alphaType() if required.
Cary Clark8032b982017-07-28 11:04:54 -04001261
Cary Clarkf05bdda2017-08-24 12:59:48 -04001262Pixels are writable when Device is raster, or backed by a GPU.
1263Pixels are not writable when SkCanvas is returned by SkDocument::beginPage,
1264returned by SkPictureRecorder::beginRecording, or Canvas is the base of a utility
1265class like SkDumpCanvas.
Cary Clark8032b982017-07-28 11:04:54 -04001266
Cary Clarkf05bdda2017-08-24 12:59:48 -04001267Pixel values are converted only if Image_Color_Type and Image_Alpha_Type
1268do not match. Only pixels within both source and destination rectangles
Cary Clark154beea2017-10-26 07:58:48 -04001269are copied. Canvas pixels outside Rect intersection are unchanged.
Cary Clark8032b982017-07-28 11:04:54 -04001270
Cary Clarkf05bdda2017-08-24 12:59:48 -04001271Pass negative values for x or y to offset pixels to the left or
1272above Canvas pixels.
Cary Clark8032b982017-07-28 11:04:54 -04001273
1274Does not copy, and returns false if:
1275
1276#List
Cary Clarkf05bdda2017-08-24 12:59:48 -04001277# Source and destination rectangles do not intersect. ##
Cary Clark8032b982017-07-28 11:04:54 -04001278# bitmap does not have allocated pixels. ##
Cary Clark154beea2017-10-26 07:58:48 -04001279# bitmap pixels could not be converted to this->imageInfo().colorType() or
1280this->imageInfo().alphaType(). ##
Cary Clarkce101242017-09-01 15:51:02 -04001281# Canvas pixels are not writable; for instance, Canvas is document based. ##
Cary Clark8032b982017-07-28 11:04:54 -04001282# 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 ##
Cary Clarkf05bdda2017-08-24 12:59:48 -04001286#Param x offset into Canvas writable pixels in x; may be negative ##
1287#Param y offset into Canvas writable pixels in y; may be negative ##
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
Cary Clarkf05bdda2017-08-24 12:59:48 -04001310#SeeAlso readPixels drawBitmap drawImage
Cary Clark8032b982017-07-28 11:04:54 -04001311
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# ------------------------------------------------------------------------------
Cary Clark8032b982017-07-28 11:04:54 -04001426
1427#Method void restore()
1428
1429Removes changes to Matrix, Clip, and Draw_Filter since Canvas state was
1430last saved. The state is removed from the stack.
1431
1432Does nothing if the stack is empty.
1433
1434#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04001435void draw(SkCanvas* canvas) {
1436 SkCanvas simple;
1437 SkDebugf("depth = %d\n", simple.getSaveCount());
1438 simple.restore();
1439 SkDebugf("depth = %d\n", simple.getSaveCount());
Cary Clark8032b982017-07-28 11:04:54 -04001440}
1441##
1442
1443##
1444
1445# ------------------------------------------------------------------------------
1446
1447#Method int getSaveCount() const
1448
1449Returns the number of saved states, each containing: Matrix, Clip, and Draw_Filter.
1450Equals the number of save() calls less the number of restore() calls plus one.
1451The save count of a new canvas is one.
1452
Cary Clarkbad5ad72017-08-03 17:14:08 -04001453#Return depth of save state stack ##
Cary Clark8032b982017-07-28 11:04:54 -04001454
1455#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04001456void draw(SkCanvas* canvas) {
1457 SkCanvas simple;
1458 SkDebugf("depth = %d\n", simple.getSaveCount());
1459 simple.save();
1460 SkDebugf("depth = %d\n", simple.getSaveCount());
1461 simple.restore();
1462 SkDebugf("depth = %d\n", simple.getSaveCount());
Cary Clark8032b982017-07-28 11:04:54 -04001463}
1464#StdOut
Cary Clarkbad5ad72017-08-03 17:14:08 -04001465depth = 1
1466depth = 2
Cary Clark8032b982017-07-28 11:04:54 -04001467depth = 1
1468##
1469##
1470
1471##
1472
1473# ------------------------------------------------------------------------------
1474
1475#Method void restoreToCount(int saveCount)
1476
Cary Clarkbad5ad72017-08-03 17:14:08 -04001477Restores state to Matrix, Clip, and Draw_Filter values when save(), saveLayer,
1478saveLayerPreserveLCDTextRequests, or saveLayerAlpha returned saveCount.
Cary Clark8032b982017-07-28 11:04:54 -04001479
1480Does nothing if saveCount is greater than state stack count.
1481Restores state to initial values if saveCount is less than or equal to one.
1482
Cary Clarkbad5ad72017-08-03 17:14:08 -04001483#Param saveCount depth of state stack to restore ##
Cary Clark8032b982017-07-28 11:04:54 -04001484
1485#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04001486void draw(SkCanvas* canvas) {
1487 SkDebugf("depth = %d\n", canvas->getSaveCount());
1488 canvas->save();
1489 canvas->save();
1490 SkDebugf("depth = %d\n", canvas->getSaveCount());
1491 canvas->restoreToCount(0);
1492 SkDebugf("depth = %d\n", canvas->getSaveCount());
Cary Clark8032b982017-07-28 11:04:54 -04001493}
1494#StdOut
Cary Clarkbad5ad72017-08-03 17:14:08 -04001495depth = 1
1496depth = 3
Cary Clark8032b982017-07-28 11:04:54 -04001497depth = 1
1498##
1499##
1500
1501##
1502
1503#Topic State_Stack ##
1504
1505# ------------------------------------------------------------------------------
Cary Clarkce101242017-09-01 15:51:02 -04001506
1507#Topic Layer
Cary Clarkd0530ba2017-09-14 11:25:39 -04001508#Substitute layer
Cary Clarkce101242017-09-01 15:51:02 -04001509#Alias Layers
1510
1511Layer allocates a temporary Bitmap to draw into. When the drawing is
1512complete, the Bitmap is drawn into the Canvas.
1513
1514Layer is saved in a stack along with other saved state. When state with a Layer
1515is restored, the Bitmap is drawn into the previous Layer.
1516
1517Layer may be initialized with the contents of the previous Layer. When Layer is
1518restored, its Bitmap can be modified by Paint passed to Layer to apply
1519Color_Alpha, Color_Filter, Image_Filter, and Blend_Mode.
1520
1521#Method int saveLayer(const SkRect* bounds, const SkPaint* paint)
1522
1523Saves Matrix, Clip, and Draw_Filter (Draw_Filter deprecated on most platforms),
1524and allocates a Bitmap for subsequent drawing.
1525Calling restore() discards changes to Matrix, Clip, and Draw_Filter,
1526and draws the Bitmap.
1527
1528Matrix may be changed by translate(), scale(), rotate(), skew(), concat(),
1529setMatrix, and resetMatrix. Clip may be changed by clipRect, clipRRect,
1530clipPath, clipRegion.
1531
1532Rect bounds suggests but does not define the Bitmap size. To clip drawing to
1533a specific rectangle, use clipRect.
1534
1535Optional Paint paint applies Color_Alpha, Color_Filter, Image_Filter, and
1536Blend_Mode when restore() is called.
1537
1538Call restoreToCount with returned value to restore this and subsequent saves.
1539
1540#Param bounds hint to limit the size of the Layer; may be nullptr ##
1541#Param paint graphics state for Layer; may be nullptr ##
1542
1543#Return depth of saved stack ##
1544
1545#Example
1546#Description
1547Rectangles are blurred by Image_Filter when restore() draws Layer to main
1548Canvas.
1549##
1550#Height 128
1551void draw(SkCanvas* canvas) {
1552 SkPaint paint, blur;
1553 blur.setImageFilter(SkImageFilter::MakeBlur(3, 3, nullptr));
1554 canvas->saveLayer(nullptr, &blur);
1555 SkRect rect = { 25, 25, 50, 50};
1556 canvas->drawRect(rect, paint);
1557 canvas->translate(50, 50);
1558 paint.setColor(SK_ColorRED);
1559 canvas->drawRect(rect, paint);
1560 canvas->restore();
1561}
1562##
1563
1564#ToDo incomplete ##
1565
1566##
1567
1568#Method int saveLayer(const SkRect& bounds, const SkPaint* paint)
1569
1570Saves Matrix, Clip, and Draw_Filter (Draw_Filter deprecated on most platforms),
1571and allocates a Bitmap for subsequent drawing.
1572Calling restore() discards changes to Matrix, Clip, and Draw_Filter,
1573and draws the Bitmap.
1574
1575Matrix may be changed by translate(), scale(), rotate(), skew(), concat(),
1576setMatrix, and resetMatrix. Clip may be changed by clipRect, clipRRect,
1577clipPath, clipRegion.
1578
1579Rect bounds suggests but does not define the Layer size. To clip drawing to
1580a specific rectangle, use clipRect.
1581
1582Optional Paint paint applies Color_Alpha, Color_Filter, Image_Filter, and
1583Blend_Mode when restore() is called.
1584
1585Call restoreToCount with returned value to restore this and subsequent saves.
1586
1587#Param bounds hint to limit the size of Layer; may be nullptr ##
1588#Param paint graphics state for Layer; may be nullptr ##
1589
1590#Return depth of saved stack ##
1591
1592#Example
1593#Description
1594Rectangles are blurred by Image_Filter when restore() draws Layer to main Canvas.
1595The red rectangle is clipped; it does not fully fit on Layer.
1596Image_Filter blurs past edge of Layer so red rectangle is blurred on all sides.
1597##
1598#Height 128
1599void draw(SkCanvas* canvas) {
1600 SkPaint paint, blur;
1601 blur.setImageFilter(SkImageFilter::MakeBlur(3, 3, nullptr));
1602 canvas->saveLayer(SkRect::MakeWH(90, 90), &blur);
1603 SkRect rect = { 25, 25, 50, 50};
1604 canvas->drawRect(rect, paint);
1605 canvas->translate(50, 50);
1606 paint.setColor(SK_ColorRED);
1607 canvas->drawRect(rect, paint);
1608 canvas->restore();
1609}
1610##
1611
1612#ToDo incomplete ##
1613
1614##
1615
1616#Method int saveLayerPreserveLCDTextRequests(const SkRect* bounds, const SkPaint* paint)
1617
1618Saves Matrix, Clip, and Draw_Filter (Draw_Filter deprecated on most platforms),
1619and allocates a Bitmap for subsequent drawing.
1620LCD_Text is preserved when the Layer is drawn to the prior Layer.
1621
1622Calling restore() discards changes to Matrix, Clip, and Draw_Filter,
1623and draws Layer.
1624
1625Matrix may be changed by translate(), scale(), rotate(), skew(), concat(),
1626setMatrix, and resetMatrix. Clip may be changed by clipRect, clipRRect,
1627clipPath, clipRegion.
1628
1629Rect bounds suggests but does not define the Layer size. To clip drawing to
1630a specific rectangle, use clipRect.
1631
1632Optional Paint paint applies Color_Alpha, Color_Filter, Image_Filter, and
1633Blend_Mode when restore() is called.
1634
1635Call restoreToCount with returned value to restore this and subsequent saves.
1636
1637Draw text on an opaque background so that LCD_Text blends correctly with the
1638prior Layer. LCD_Text drawn on a background with transparency may result in
Cary Clark6fc50412017-09-21 12:31:06 -04001639incorrect blending.
Cary Clarkce101242017-09-01 15:51:02 -04001640
1641#Param bounds hint to limit the size of Layer; may be nullptr ##
1642#Param paint graphics state for Layer; may be nullptr ##
1643
1644#Return depth of saved stack ##
1645
1646#Example
1647 SkPaint paint;
1648 paint.setAntiAlias(true);
1649 paint.setLCDRenderText(true);
1650 paint.setTextSize(20);
1651 for (auto preserve : { false, true } ) {
1652 preserve ? canvas->saveLayerPreserveLCDTextRequests(nullptr, nullptr)
1653 : canvas->saveLayer(nullptr, nullptr);
1654 SkPaint p;
1655 p.setColor(SK_ColorWHITE);
1656 // Comment out the next line to draw on a non-opaque background.
1657 canvas->drawRect(SkRect::MakeLTRB(25, 40, 200, 70), p);
1658 canvas->drawString("Hamburgefons", 30, 60, paint);
1659
1660 p.setColor(0xFFCCCCCC);
1661 canvas->drawRect(SkRect::MakeLTRB(25, 70, 200, 100), p);
1662 canvas->drawString("Hamburgefons", 30, 90, paint);
1663
1664 canvas->restore();
1665 canvas->translate(0, 80);
1666 }
1667 ##
1668
1669#ToDo incomplete ##
1670
1671##
1672
1673#Method int saveLayerAlpha(const SkRect* bounds, U8CPU alpha)
1674
1675Saves Matrix, Clip, and Draw_Filter (Draw_Filter deprecated on most platforms),
1676and allocates Bitmap for subsequent drawing.
1677
1678Calling restore() discards changes to Matrix, Clip, and Draw_Filter,
1679and blends Layer with alpha opacity onto prior Layer.
1680
1681Matrix may be changed by translate(), scale(), rotate(), skew(), concat(),
1682setMatrix, and resetMatrix. Clip may be changed by clipRect, clipRRect,
1683clipPath, clipRegion.
1684
1685Rect bounds suggests but does not define Layer size. To clip drawing to
1686a specific rectangle, use clipRect.
1687
1688alpha of zero is fully transparent, 255 is fully opaque.
1689
1690Call restoreToCount with returned value to restore this and subsequent saves.
1691
1692#Param bounds hint to limit the size of Layer; may be nullptr ##
1693#Param alpha opacity of Layer ##
1694
1695#Return depth of saved stack ##
1696
1697#Example
1698 SkPaint paint;
1699 paint.setColor(SK_ColorRED);
1700 canvas->drawCircle(50, 50, 50, paint);
1701 canvas->saveLayerAlpha(nullptr, 128);
1702 paint.setColor(SK_ColorBLUE);
1703 canvas->drawCircle(100, 50, 50, paint);
1704 paint.setColor(SK_ColorGREEN);
1705 paint.setAlpha(128);
1706 canvas->drawCircle(75, 90, 50, paint);
1707 canvas->restore();
1708##
1709
1710#ToDo incomplete ##
1711
1712##
1713
1714#Enum
1715
1716#Code
1717 enum {
1718 kIsOpaque_SaveLayerFlag = 1 << 0,
1719 kPreserveLCDText_SaveLayerFlag = 1 << 1,
1720 kInitWithPrevious_SaveLayerFlag = 1 << 2,
1721 kDontClipToLayer_Legacy_SaveLayerFlag = kDontClipToLayer_PrivateSaveLayerFlag,
1722 };
1723
1724 typedef uint32_t SaveLayerFlags;
1725##
1726
1727SaveLayerFlags provides options that may be used in any combination in SaveLayerRec,
1728defining how Layer allocated by saveLayer operates.
1729
1730#Const kIsOpaque_SaveLayerFlag 1
1731 Creates Layer without transparency. Flag is ignored if Layer Paint contains
1732 Image_Filter or Color_Filter.
1733##
1734
1735#Const kPreserveLCDText_SaveLayerFlag 2
1736 Creates Layer for LCD text. Flag is ignored if Layer Paint contains
1737 Image_Filter or Color_Filter.
1738##
1739
1740#Const kInitWithPrevious_SaveLayerFlag 4
1741 Initializes Layer with the contents of the previous Layer.
1742##
1743
1744#Const kDontClipToLayer_Legacy_SaveLayerFlag 0x80000000
1745#Private
1746 to be deprecated: bug.skia.org/2440
1747##
1748 Only present on Android.
1749 Skips setting a clip to the Layer bounds.
1750##
1751
1752#Example
1753#Height 160
1754#Description
1755Canvas Layer captures red and blue circles scaled up by four.
1756scalePaint blends Layer back with transparency.
1757##
1758void draw(SkCanvas* canvas) {
1759 SkPaint redPaint, bluePaint, scalePaint;
1760 redPaint.setColor(SK_ColorRED);
1761 canvas->drawCircle(21, 21, 8, redPaint);
1762 bluePaint.setColor(SK_ColorBLUE);
1763 canvas->drawCircle(31, 21, 8, bluePaint);
1764 SkMatrix matrix;
1765 matrix.setScale(4, 4);
1766 scalePaint.setAlpha(0x40);
1767 scalePaint.setImageFilter(
1768 SkImageFilter::MakeMatrixFilter(matrix, kNone_SkFilterQuality, nullptr));
1769 SkCanvas::SaveLayerRec saveLayerRec(nullptr, &scalePaint,
1770 SkCanvas::kInitWithPrevious_SaveLayerFlag);
1771 canvas->saveLayer(saveLayerRec);
1772 canvas->restore();
1773}
1774##
1775
1776#ToDo incomplete ##
1777
1778#Enum ##
1779
1780#Struct SaveLayerRec
1781
1782#Code
1783 struct SaveLayerRec {
1784 SaveLayerRec*(...
1785
1786 const SkRect* fBounds;
1787 const SkPaint* fPaint;
1788 const SkImageFilter* fBackdrop;
1789 SaveLayerFlags fSaveLayerFlags;
1790 };
1791##
1792
1793SaveLayerRec contains the state used to create the Layer.
1794
1795#Member const SkRect* fBounds
1796 fBounds is used as a hint to limit the size of Layer; may be nullptr.
1797 fBounds suggests but does not define Layer size. To clip drawing to
1798 a specific rectangle, use clipRect.
1799##
1800
1801#Member const SkPaint* fPaint
1802 fPaint modifies how Layer overlays the prior Layer; may be nullptr.
1803 Color_Alpha, Blend_Mode, Color_Filter, Draw_Looper, Image_Filter, and
1804 Mask_Filter affect Layer draw.
1805##
1806
1807#Member const SkImageFilter* fBackdrop
1808 fBackdrop applies Image_Filter to the prior Layer when copying to the Layer;
1809 may be nullptr. Use kInitWithPrevious_SaveLayerFlag to copy the
1810 prior Layer without an Image_Filter.
1811##
1812
1813#Member const SkImage* fClipMask
1814 restore() clips Layer by the Color_Alpha channel of fClipMask when
1815 Layer is copied to Device. fClipMask may be nullptr. .
1816##
1817
1818#Member const SkMatrix* fClipMatrix
1819 fClipMatrix transforms fClipMask before it clips Layer. If
1820 fClipMask describes a translucent gradient, it may be scaled and rotated
1821 without introducing artifacts. fClipMatrix may be nullptr.
1822##
1823
1824#Member SaveLayerFlags fSaveLayerFlags
1825 fSaveLayerFlags are used to create Layer without transparency,
1826 create Layer for LCD text, and to create Layer with the
1827 contents of the previous Layer.
1828##
1829
1830#Example
1831#Height 160
1832#Description
1833Canvas Layer captures a red Anti-aliased circle and a blue Aliased circle scaled
1834up by four. After drawing another red circle without scaling on top, the Layer is
1835transferred to the main canvas.
1836##
1837void draw(SkCanvas* canvas) {
1838 SkPaint redPaint, bluePaint;
1839 redPaint.setAntiAlias(true);
1840 redPaint.setColor(SK_ColorRED);
1841 canvas->drawCircle(21, 21, 8, redPaint);
1842 bluePaint.setColor(SK_ColorBLUE);
1843 canvas->drawCircle(31, 21, 8, bluePaint);
1844 SkMatrix matrix;
1845 matrix.setScale(4, 4);
1846 auto scaler = SkImageFilter::MakeMatrixFilter(matrix, kNone_SkFilterQuality, nullptr);
1847 SkCanvas::SaveLayerRec saveLayerRec(nullptr, nullptr, scaler.get(), 0);
1848 canvas->saveLayer(saveLayerRec);
1849 canvas->drawCircle(125, 85, 8, redPaint);
1850 canvas->restore();
1851}
1852##
1853
1854#Method SaveLayerRec()
1855
1856Sets fBounds, fPaint, and fBackdrop to nullptr. Clears fSaveLayerFlags.
1857
1858#Return empty SaveLayerRec ##
1859
1860#Example
1861 SkCanvas::SaveLayerRec rec1;
1862 rec1.fSaveLayerFlags = SkCanvas::kIsOpaque_SaveLayerFlag;
1863 SkCanvas::SaveLayerRec rec2(nullptr, nullptr, SkCanvas::kIsOpaque_SaveLayerFlag);
1864 SkDebugf("rec1 %c= rec2\n", rec1.fBounds == rec2.fBounds
1865 && rec1.fPaint == rec2.fPaint
1866 && rec1.fBackdrop == rec2.fBackdrop
1867 && rec1.fSaveLayerFlags == rec2.fSaveLayerFlags ? '=' : '!');
1868 #StdOut
1869 rec1 == rec2
1870 ##
1871##
1872
1873##
1874
1875#Method SaveLayerRec(const SkRect* bounds, const SkPaint* paint, SaveLayerFlags saveLayerFlags = 0)
1876
1877Sets fBounds, fPaint, and fSaveLayerFlags; sets fBackdrop to nullptr.
1878
1879#Param bounds Layer dimensions; may be nullptr ##
1880#Param paint applied to Layer when overlaying prior Layer; may be nullptr ##
1881#Param saveLayerFlags SaveLayerRec options to modify Layer ##
1882
1883#Return SaveLayerRec with empty backdrop ##
1884
1885#Example
1886 SkCanvas::SaveLayerRec rec1;
1887 SkCanvas::SaveLayerRec rec2(nullptr, nullptr);
1888 SkDebugf("rec1 %c= rec2\n", rec1.fBounds == rec2.fBounds
1889 && rec1.fPaint == rec2.fPaint
1890 && rec1.fBackdrop == rec2.fBackdrop
1891 && rec1.fSaveLayerFlags == rec2.fSaveLayerFlags ? '=' : '!');
1892 #StdOut
1893 rec1 == rec2
1894 ##
1895##
1896
1897##
1898
1899#Method SaveLayerRec(const SkRect* bounds, const SkPaint* paint, const SkImageFilter* backdrop,
1900 SaveLayerFlags saveLayerFlags)
1901
1902Sets fBounds, fPaint, fBackdrop, and fSaveLayerFlags.
1903
1904#Param bounds Layer dimensions; may be nullptr ##
1905#Param paint applied to Layer when overlaying prior Layer;
1906 may be nullptr
1907##
1908#Param backdrop prior Layer copied with Image_Filter; may be nullptr
1909##
1910#Param saveLayerFlags SaveLayerRec options to modify Layer ##
1911
1912#Return SaveLayerRec fully specified ##
1913
1914#Example
1915 SkCanvas::SaveLayerRec rec1;
1916 SkCanvas::SaveLayerRec rec2(nullptr, nullptr, nullptr, 0);
1917 SkDebugf("rec1 %c= rec2\n", rec1.fBounds == rec2.fBounds
1918 && rec1.fPaint == rec2.fPaint
1919 && rec1.fBackdrop == rec2.fBackdrop
1920 && rec1.fSaveLayerFlags == rec2.fSaveLayerFlags ? '=' : '!');
1921 #StdOut
1922 rec1 == rec2
1923 ##
1924##
1925
1926##
1927
1928#Method SaveLayerRec(const SkRect* bounds, const SkPaint* paint, const SkImageFilter* backdrop,
1929 const SkImage* clipMask, const SkMatrix* clipMatrix,
1930 SaveLayerFlags saveLayerFlags)
1931
1932#Experimental
1933Not ready for general use.
1934##
1935
1936Sets fBounds, fPaint, fBackdrop, fClipMask, fClipMatrix, and fSaveLayerFlags.
1937clipMatrix uses Color_Alpha channel of image, transformed by clipMatrix, to clip
1938Layer when drawn to Canvas.
1939
1940Implementation is incomplete; has no effect if Device is GPU-backed.
1941
1942#Param bounds Layer dimensions; may be nullptr ##
1943#Param paint graphics state applied to Layer when overlaying prior
1944 Layer; may be nullptr
1945##
1946#Param backdrop prior Layer copied with Image_Filter;
1947 may be nullptr
1948##
1949#Param clipMask clip applied to Layer; may be nullptr ##
1950#Param clipMatrix matrix applied to clipMask; may be nullptr to use
1951 identity matrix
1952##
1953#Param saveLayerFlags SaveLayerRec options to modify Layer ##
1954
1955#Return SaveLayerRec fully specified ##
1956
1957#ToDo incomplete ##
1958
1959##
1960
1961#Struct ##
1962
1963#Method int saveLayer(const SaveLayerRec& layerRec)
1964
1965Saves Matrix, Clip, and Draw_Filter (Draw_Filter deprecated on most platforms),
1966and allocates Bitmap for subsequent drawing.
1967
1968Calling restore() discards changes to Matrix, Clip, and Draw_Filter,
1969and blends Bitmap with Color_Alpha opacity onto the prior Layer.
1970
1971Matrix may be changed by translate(), scale(), rotate(), skew(), concat(),
1972setMatrix, and resetMatrix. Clip may be changed by clipRect, clipRRect,
1973clipPath, clipRegion.
1974
1975SaveLayerRec contains the state used to create the Layer.
1976
1977Call restoreToCount with returned value to restore this and subsequent saves.
1978
1979#Param layerRec Layer state ##
1980
1981#Return depth of save state stack ##
1982
1983#Example
1984#Description
1985The example draws an image, and saves it into a Layer with kInitWithPrevious_SaveLayerFlag.
1986Next it punches a hole in Layer and restore with SkBlendMode::kPlus.
1987Where Layer was cleared, the original image will draw unchanged.
1988Outside of the circle the mandrill is brightened.
1989##
1990 #Image 3
1991 // sk_sp<SkImage> image = GetResourceAsImage("mandrill_256.png");
1992 canvas->drawImage(image, 0, 0, nullptr);
1993 SkCanvas::SaveLayerRec rec;
1994 SkPaint paint;
1995 paint.setBlendMode(SkBlendMode::kPlus);
1996 rec.fSaveLayerFlags = SkCanvas::kInitWithPrevious_SaveLayerFlag;
1997 rec.fPaint = &paint;
1998 canvas->saveLayer(rec);
1999 paint.setBlendMode(SkBlendMode::kClear);
2000 canvas->drawCircle(128, 128, 96, paint);
2001 canvas->restore();
2002##
2003
2004#ToDo above example needs to replace GetResourceAsImage with way to select image in fiddle ##
2005
2006##
2007
2008#Topic Layer ##
2009
2010# ------------------------------------------------------------------------------
Cary Clark8032b982017-07-28 11:04:54 -04002011#Topic Matrix
2012
2013#Method void translate(SkScalar dx, SkScalar dy)
2014
2015Translate Matrix by dx along the x-axis and dy along the y-axis.
2016
2017Mathematically, replace Matrix with a translation matrix
Cary Clarkce101242017-09-01 15:51:02 -04002018Premultiplied with Matrix.
Cary Clark8032b982017-07-28 11:04:54 -04002019
2020This has the effect of moving the drawing by (dx, dy) before transforming
2021the result with Matrix.
2022
Cary Clarkbad5ad72017-08-03 17:14:08 -04002023#Param dx distance to translate in x ##
2024#Param dy distance to translate in y ##
Cary Clark8032b982017-07-28 11:04:54 -04002025
2026#Example
2027#Height 128
2028#Description
2029scale() followed by translate() produces different results from translate() followed
2030by scale().
2031
2032The blue stroke follows translate of (50, 50); a black
2033fill follows scale of (2, 1/2.f). After restoring the clip, which resets
2034Matrix, a red frame follows the same scale of (2, 1/2.f); a gray fill
2035follows translate of (50, 50).
2036##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002037void draw(SkCanvas* canvas) {
2038 SkPaint filledPaint;
2039 SkPaint outlinePaint;
2040 outlinePaint.setStyle(SkPaint::kStroke_Style);
2041 outlinePaint.setColor(SK_ColorBLUE);
2042 canvas->save();
2043 canvas->translate(50, 50);
2044 canvas->drawCircle(28, 28, 15, outlinePaint); // blue center: (50+28, 50+28)
2045 canvas->scale(2, 1/2.f);
2046 canvas->drawCircle(28, 28, 15, filledPaint); // black center: (50+(28*2), 50+(28/2))
2047 canvas->restore();
2048 filledPaint.setColor(SK_ColorGRAY);
2049 outlinePaint.setColor(SK_ColorRED);
2050 canvas->scale(2, 1/2.f);
2051 canvas->drawCircle(28, 28, 15, outlinePaint); // red center: (28*2, 28/2)
2052 canvas->translate(50, 50);
2053 canvas->drawCircle(28, 28, 15, filledPaint); // gray center: ((50+28)*2, (50+28)/2)
Cary Clark8032b982017-07-28 11:04:54 -04002054}
2055##
2056
2057#ToDo incomplete ##
2058
2059##
2060
2061# ------------------------------------------------------------------------------
2062
2063#Method void scale(SkScalar sx, SkScalar sy)
2064
2065Scale Matrix by sx on the x-axis and sy on the y-axis.
2066
2067Mathematically, replace Matrix with a scale matrix
Cary Clarkce101242017-09-01 15:51:02 -04002068Premultiplied with Matrix.
Cary Clark8032b982017-07-28 11:04:54 -04002069
2070This has the effect of scaling the drawing by (sx, sy) before transforming
2071the result with Matrix.
2072
Cary Clarkbad5ad72017-08-03 17:14:08 -04002073#Param sx amount to scale in x ##
2074#Param sy amount to scale in y ##
Cary Clark8032b982017-07-28 11:04:54 -04002075
2076#Example
2077#Height 160
Cary Clarkbad5ad72017-08-03 17:14:08 -04002078void draw(SkCanvas* canvas) {
2079 SkPaint paint;
2080 SkRect rect = { 10, 20, 60, 120 };
2081 canvas->translate(20, 20);
2082 canvas->drawRect(rect, paint);
2083 canvas->scale(2, .5f);
2084 paint.setColor(SK_ColorGRAY);
2085 canvas->drawRect(rect, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002086}
2087##
2088
2089#ToDo incomplete ##
2090
2091##
2092
2093# ------------------------------------------------------------------------------
2094
2095#Method void rotate(SkScalar degrees)
2096
2097Rotate Matrix by degrees. Positive degrees rotates clockwise.
2098
2099Mathematically, replace Matrix with a rotation matrix
Cary Clarkce101242017-09-01 15:51:02 -04002100Premultiplied with Matrix.
Cary Clark8032b982017-07-28 11:04:54 -04002101
2102This has the effect of rotating the drawing by degrees before transforming
2103the result with Matrix.
2104
Cary Clarkbad5ad72017-08-03 17:14:08 -04002105#Param degrees amount to rotate, in degrees ##
Cary Clark8032b982017-07-28 11:04:54 -04002106
2107#Example
2108#Description
2109Draw clock hands at time 5:10. The hour hand and minute hand point up and
2110are rotated clockwise.
2111##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002112void draw(SkCanvas* canvas) {
2113 SkPaint paint;
2114 paint.setStyle(SkPaint::kStroke_Style);
2115 canvas->translate(128, 128);
2116 canvas->drawCircle(0, 0, 60, paint);
2117 canvas->save();
2118 canvas->rotate(10 * 360 / 60); // 10 minutes of 60 scaled to 360 degrees
2119 canvas->drawLine(0, 0, 0, -50, paint);
2120 canvas->restore();
2121 canvas->rotate((5 + 10.f/60) * 360 / 12); // 5 and 10/60 hours of 12 scaled to 360 degrees
2122 canvas->drawLine(0, 0, 0, -30, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002123}
2124##
2125
2126#ToDo incomplete ##
2127
2128##
2129
2130# ------------------------------------------------------------------------------
2131
2132#Method void rotate(SkScalar degrees, SkScalar px, SkScalar py)
2133
Cary Clarkbad5ad72017-08-03 17:14:08 -04002134Rotate Matrix by degrees about a point at (px, py). Positive degrees rotates
2135clockwise.
Cary Clark8032b982017-07-28 11:04:54 -04002136
Cary Clarkce101242017-09-01 15:51:02 -04002137Mathematically, construct a rotation matrix. Premultiply the rotation matrix by
Cary Clark8032b982017-07-28 11:04:54 -04002138a translation matrix, then replace Matrix with the resulting matrix
Cary Clarkce101242017-09-01 15:51:02 -04002139Premultiplied with Matrix.
Cary Clark8032b982017-07-28 11:04:54 -04002140
Cary Clarkbad5ad72017-08-03 17:14:08 -04002141This has the effect of rotating the drawing about a given point before
2142transforming the result with Matrix.
Cary Clark8032b982017-07-28 11:04:54 -04002143
Cary Clarkbad5ad72017-08-03 17:14:08 -04002144#Param degrees amount to rotate, in degrees ##
2145#Param px x-coordinate of the point to rotate about ##
2146#Param py y-coordinate of the point to rotate about ##
Cary Clark8032b982017-07-28 11:04:54 -04002147
2148#Example
2149#Height 192
Cary Clarkbad5ad72017-08-03 17:14:08 -04002150void draw(SkCanvas* canvas) {
2151 SkPaint paint;
2152 paint.setTextSize(96);
2153 canvas->drawString("A1", 130, 100, paint);
2154 canvas->rotate(180, 130, 100);
2155 canvas->drawString("A1", 130, 100, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002156}
2157##
2158
2159#ToDo incomplete ##
2160
2161##
2162
2163# ------------------------------------------------------------------------------
2164
2165#Method void skew(SkScalar sx, SkScalar sy)
2166
Cary Clarkbad5ad72017-08-03 17:14:08 -04002167Skew Matrix by sx on the x-axis and sy on the y-axis. A positive value of sx
2168skews the drawing right as y increases; a positive value of sy skews the drawing
2169down as x increases.
Cary Clark8032b982017-07-28 11:04:54 -04002170
Cary Clarkce101242017-09-01 15:51:02 -04002171Mathematically, replace Matrix with a skew matrix Premultiplied with Matrix.
Cary Clark8032b982017-07-28 11:04:54 -04002172
Cary Clarkbad5ad72017-08-03 17:14:08 -04002173This has the effect of skewing the drawing by (sx, sy) before transforming
Cary Clark8032b982017-07-28 11:04:54 -04002174the result with Matrix.
2175
Cary Clarkbad5ad72017-08-03 17:14:08 -04002176#Param sx amount to skew in x ##
2177#Param sy amount to skew in y ##
2178
Cary Clark8032b982017-07-28 11:04:54 -04002179#Example
2180 #Description
2181 Black text mimics an oblique text style by using a negative skew in x that
2182 shifts the geometry to the right as the y values decrease.
2183 Red text uses a positive skew in y to shift the geometry down as the x values
2184 increase.
2185 Blue text combines x and y skew to rotate and scale.
2186 ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002187 SkPaint paint;
2188 paint.setTextSize(128);
2189 canvas->translate(30, 130);
2190 canvas->save();
2191 canvas->skew(-.5, 0);
2192 canvas->drawString("A1", 0, 0, paint);
2193 canvas->restore();
2194 canvas->save();
2195 canvas->skew(0, .5);
2196 paint.setColor(SK_ColorRED);
2197 canvas->drawString("A1", 0, 0, paint);
2198 canvas->restore();
2199 canvas->skew(-.5, .5);
2200 paint.setColor(SK_ColorBLUE);
Cary Clark8032b982017-07-28 11:04:54 -04002201 canvas->drawString("A1", 0, 0, paint);
2202##
2203
2204#ToDo incomplete ##
2205
2206##
2207
2208# ------------------------------------------------------------------------------
2209
2210#Method void concat(const SkMatrix& matrix)
2211
Cary Clarkce101242017-09-01 15:51:02 -04002212Replace Matrix with matrix Premultiplied with existing Matrix.
Cary Clark8032b982017-07-28 11:04:54 -04002213
Cary Clarkbad5ad72017-08-03 17:14:08 -04002214This has the effect of transforming the drawn geometry by matrix, before
2215transforming the result with existing Matrix.
Cary Clark8032b982017-07-28 11:04:54 -04002216
Cary Clarkce101242017-09-01 15:51:02 -04002217#Param matrix matrix to Premultiply with existing Matrix ##
Cary Clark8032b982017-07-28 11:04:54 -04002218
2219#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04002220void draw(SkCanvas* canvas) {
2221 SkPaint paint;
2222 paint.setTextSize(80);
2223 paint.setTextScaleX(.3);
2224 SkMatrix matrix;
2225 SkRect rect[2] = {{ 10, 20, 90, 110 }, { 40, 130, 140, 180 }};
2226 matrix.setRectToRect(rect[0], rect[1], SkMatrix::kFill_ScaleToFit);
2227 canvas->drawRect(rect[0], paint);
2228 canvas->drawRect(rect[1], paint);
2229 paint.setColor(SK_ColorWHITE);
2230 canvas->drawString("Here", rect[0].fLeft + 10, rect[0].fBottom - 10, paint);
2231 canvas->concat(matrix);
2232 canvas->drawString("There", rect[0].fLeft + 10, rect[0].fBottom - 10, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002233}
2234##
2235
2236#ToDo incomplete ##
2237
2238##
2239
2240# ------------------------------------------------------------------------------
2241
2242#Method void setMatrix(const SkMatrix& matrix)
2243
2244Replace Matrix with matrix.
2245Unlike concat(), any prior matrix state is overwritten.
2246
Cary Clarkbad5ad72017-08-03 17:14:08 -04002247#Param matrix matrix to copy, replacing existing Matrix ##
Cary Clark8032b982017-07-28 11:04:54 -04002248
2249#Example
2250#Height 128
Cary Clarkbad5ad72017-08-03 17:14:08 -04002251void draw(SkCanvas* canvas) {
2252 SkPaint paint;
2253 canvas->scale(4, 6);
2254 canvas->drawString("truth", 2, 10, paint);
2255 SkMatrix matrix;
2256 matrix.setScale(2.8f, 6);
2257 canvas->setMatrix(matrix);
2258 canvas->drawString("consequences", 2, 20, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002259}
2260##
2261
2262#ToDo incomplete ##
2263
2264##
2265
2266# ------------------------------------------------------------------------------
2267
2268#Method void resetMatrix()
2269
2270Sets Matrix to the identity matrix.
2271Any prior matrix state is overwritten.
2272
2273#Example
2274#Height 128
Cary Clarkbad5ad72017-08-03 17:14:08 -04002275void draw(SkCanvas* canvas) {
2276 SkPaint paint;
2277 canvas->scale(4, 6);
2278 canvas->drawString("truth", 2, 10, paint);
2279 canvas->resetMatrix();
2280 canvas->scale(2.8f, 6);
2281 canvas->drawString("consequences", 2, 20, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002282}
2283##
2284
2285#ToDo incomplete ##
2286
2287##
2288
2289# ------------------------------------------------------------------------------
2290
2291#Method const SkMatrix& getTotalMatrix() const
2292
2293Returns Matrix.
2294This does not account for translation by Device or Surface.
2295
Cary Clarkbad5ad72017-08-03 17:14:08 -04002296#Return Matrix in Canvas ##
Cary Clark8032b982017-07-28 11:04:54 -04002297
2298#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04002299 SkDebugf("isIdentity %s\n", canvas->getTotalMatrix().isIdentity() ? "true" : "false");
2300 #StdOut
2301 isIdentity true
2302 ##
Cary Clark8032b982017-07-28 11:04:54 -04002303##
2304
2305#ToDo incomplete ##
2306
2307##
2308
2309#Topic Matrix ##
2310
2311# ------------------------------------------------------------------------------
2312#Topic Clip
2313
2314Clip is built from a stack of clipping paths. Each Path in the
2315stack can be constructed from one or more Path_Contour elements. The
2316Path_Contour may be composed of any number of Path_Verb segments. Each
2317Path_Contour forms a closed area; Path_Fill_Type defines the area enclosed
2318by Path_Contour.
2319
2320Clip stack of Path elements successfully restrict the Path area. Each
2321Path is transformed by Matrix, then intersected with or subtracted from the
2322prior Clip to form the replacement Clip. Use SkClipOp::kDifference
2323to subtract Path from Clip; use SkClipOp::kIntersect to intersect Path
2324with Clip.
2325
Cary Clarkce101242017-09-01 15:51:02 -04002326A clipping Path may be Anti-aliased; if Path, after transformation, is
Cary Clark8032b982017-07-28 11:04:54 -04002327composed of horizontal and vertical lines, clearing Anti-alias allows whole pixels
Cary Clarkce101242017-09-01 15:51:02 -04002328to either be inside or outside the clip. The fastest drawing has a Aliased,
2329rectangular clip.
Cary Clark8032b982017-07-28 11:04:54 -04002330
2331If clipping Path has Anti-alias set, clip may partially clip a pixel, requiring
2332that drawing blend partially with the destination along the edge. A rotated
Cary Clarkce101242017-09-01 15:51:02 -04002333rectangular Anti-aliased clip looks smoother but draws slower.
Cary Clark8032b982017-07-28 11:04:54 -04002334
2335Clip can combine with Rect and Round_Rect primitives; like
2336Path, these are transformed by Matrix before they are combined with Clip.
2337
2338Clip can combine with Region. Region is assumed to be in Device coordinates
2339and is unaffected by Matrix.
2340
2341#Example
2342#Height 90
2343 #Description
Cary Clarkce101242017-09-01 15:51:02 -04002344 Draw a red circle with an Aliased clip and an Anti-aliased clip.
Cary Clark8032b982017-07-28 11:04:54 -04002345 Use an image filter to zoom into the pixels drawn.
Cary Clarkce101242017-09-01 15:51:02 -04002346 The edge of the Aliased clip fully draws pixels in the red circle.
2347 The edge of the Anti-aliased clip partially draws pixels in the red circle.
Cary Clark8032b982017-07-28 11:04:54 -04002348 ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002349 SkPaint redPaint, scalePaint;
2350 redPaint.setAntiAlias(true);
2351 redPaint.setColor(SK_ColorRED);
2352 canvas->save();
2353 for (bool antialias : { false, true } ) {
2354 canvas->save();
2355 canvas->clipRect(SkRect::MakeWH(19.5f, 11.5f), antialias);
2356 canvas->drawCircle(17, 11, 8, redPaint);
2357 canvas->restore();
2358 canvas->translate(16, 0);
2359 }
2360 canvas->restore();
2361 SkMatrix matrix;
2362 matrix.setScale(6, 6);
2363 scalePaint.setImageFilter(
2364 SkImageFilter::MakeMatrixFilter(matrix, kNone_SkFilterQuality, nullptr));
2365 SkCanvas::SaveLayerRec saveLayerRec(
2366 nullptr, &scalePaint, SkCanvas::kInitWithPrevious_SaveLayerFlag);
2367 canvas->saveLayer(saveLayerRec);
Cary Clark8032b982017-07-28 11:04:54 -04002368 canvas->restore();
2369##
2370
2371#Method void clipRect(const SkRect& rect, SkClipOp op, bool doAntiAlias)
2372
2373Replace Clip with the intersection or difference of Clip and rect,
Cary Clarkce101242017-09-01 15:51:02 -04002374with an Aliased or Anti-aliased clip edge. rect is transformed by Matrix
Cary Clark8032b982017-07-28 11:04:54 -04002375before it is combined with Clip.
2376
Cary Clarka523d2d2017-08-30 08:58:10 -04002377#Param rect Rect to combine with Clip ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002378#Param op Clip_Op to apply to Clip ##
Cary Clarkce101242017-09-01 15:51:02 -04002379#Param doAntiAlias true if Clip is to be Anti-aliased ##
Cary Clark8032b982017-07-28 11:04:54 -04002380
2381#Example
2382#Height 128
Cary Clarkbad5ad72017-08-03 17:14:08 -04002383void draw(SkCanvas* canvas) {
2384 canvas->rotate(10);
2385 SkPaint paint;
2386 paint.setAntiAlias(true);
2387 for (auto alias: { false, true } ) {
2388 canvas->save();
2389 canvas->clipRect(SkRect::MakeWH(90, 80), SkClipOp::kIntersect, alias);
2390 canvas->drawCircle(100, 60, 60, paint);
2391 canvas->restore();
2392 canvas->translate(80, 0);
2393 }
Cary Clark8032b982017-07-28 11:04:54 -04002394}
2395##
2396
2397#ToDo incomplete ##
2398
2399##
2400
2401#Method void clipRect(const SkRect& rect, SkClipOp op)
2402
2403Replace Clip with the intersection or difference of Clip and rect.
Cary Clarkce101242017-09-01 15:51:02 -04002404Resulting Clip is Aliased; pixels are fully contained by the clip.
Cary Clarkbad5ad72017-08-03 17:14:08 -04002405rect is transformed by Matrix before it is combined with Clip.
Cary Clark8032b982017-07-28 11:04:54 -04002406
Cary Clarka523d2d2017-08-30 08:58:10 -04002407#Param rect Rect to combine with Clip ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002408#Param op Clip_Op to apply to Clip ##
Cary Clark8032b982017-07-28 11:04:54 -04002409
2410#Example
2411#Height 192
2412#Width 280
Cary Clarkbad5ad72017-08-03 17:14:08 -04002413void draw(SkCanvas* canvas) {
2414 SkPaint paint;
2415 for (SkClipOp op: { SkClipOp::kIntersect, SkClipOp::kDifference } ) {
2416 canvas->save();
2417 canvas->clipRect(SkRect::MakeWH(90, 120), op, false);
2418 canvas->drawCircle(100, 100, 60, paint);
2419 canvas->restore();
2420 canvas->translate(80, 0);
2421 }
Cary Clark8032b982017-07-28 11:04:54 -04002422}
2423##
2424
2425#ToDo incomplete ##
2426
2427##
2428
2429#Method void clipRect(const SkRect& rect, bool doAntiAlias = false)
2430
2431Replace Clip with the intersection of Clip and rect.
Cary Clarkce101242017-09-01 15:51:02 -04002432Resulting Clip is Aliased; pixels are fully contained by the clip.
Cary Clark8032b982017-07-28 11:04:54 -04002433rect is transformed by Matrix
2434before it is combined with Clip.
2435
Cary Clarka523d2d2017-08-30 08:58:10 -04002436#Param rect Rect to combine with Clip ##
Cary Clarkce101242017-09-01 15:51:02 -04002437#Param doAntiAlias true if Clip is to be Anti-aliased ##
Cary Clark8032b982017-07-28 11:04:54 -04002438
2439#Example
2440#Height 133
2441 #Description
Cary Clarkce101242017-09-01 15:51:02 -04002442 A circle drawn in pieces looks uniform when drawn Aliased.
2443 The same circle pieces blend with pixels more than once when Anti-aliased,
Cary Clark8032b982017-07-28 11:04:54 -04002444 visible as a thin pair of lines through the right circle.
2445 ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002446void draw(SkCanvas* canvas) {
2447 canvas->clear(SK_ColorWHITE);
2448 SkPaint paint;
2449 paint.setAntiAlias(true);
2450 paint.setColor(0x8055aaff);
2451 SkRect clipRect = { 0, 0, 87.4f, 87.4f };
2452 for (auto alias: { false, true } ) {
2453 canvas->save();
2454 canvas->clipRect(clipRect, SkClipOp::kIntersect, alias);
2455 canvas->drawCircle(67, 67, 60, paint);
2456 canvas->restore();
2457 canvas->save();
2458 canvas->clipRect(clipRect, SkClipOp::kDifference, alias);
2459 canvas->drawCircle(67, 67, 60, paint);
2460 canvas->restore();
2461 canvas->translate(120, 0);
2462 }
Cary Clark8032b982017-07-28 11:04:54 -04002463}
2464##
2465
2466#ToDo incomplete ##
2467
2468##
2469
2470#Method void androidFramework_setDeviceClipRestriction(const SkIRect& rect)
2471
Cary Clarkce101242017-09-01 15:51:02 -04002472Sets the maximum clip rectangle, which can be set by clipRect, clipRRect and
Cary Clark8032b982017-07-28 11:04:54 -04002473clipPath and intersect the current clip with the specified rect.
Cary Clarkce101242017-09-01 15:51:02 -04002474The maximum clip affects only future clipping operations; it is not retroactive.
Cary Clark8032b982017-07-28 11:04:54 -04002475The clip restriction is not recorded in pictures.
2476
Cary Clarkce101242017-09-01 15:51:02 -04002477Pass an empty rect to disable maximum clip.
Cary Clarkbad5ad72017-08-03 17:14:08 -04002478
Cary Clark8032b982017-07-28 11:04:54 -04002479#Private
2480This is private API to be used only by Android framework.
2481##
2482
Cary Clarkbad5ad72017-08-03 17:14:08 -04002483#Param rect maximum allowed clip in device coordinates
Cary Clark579985c2017-07-31 11:48:27 -04002484#Param ##
Cary Clark8032b982017-07-28 11:04:54 -04002485
2486##
2487
2488#Method void clipRRect(const SkRRect& rrect, SkClipOp op, bool doAntiAlias)
2489
2490Replace Clip with the intersection or difference of Clip and rrect,
Cary Clarkce101242017-09-01 15:51:02 -04002491with an Aliased or Anti-aliased clip edge.
Cary Clark8032b982017-07-28 11:04:54 -04002492rrect is transformed by Matrix
2493before it is combined with Clip.
2494
Cary Clarkbad5ad72017-08-03 17:14:08 -04002495#Param rrect Round_Rect to combine with Clip ##
2496#Param op Clip_Op to apply to Clip ##
Cary Clarkce101242017-09-01 15:51:02 -04002497#Param doAntiAlias true if Clip is to be Anti-aliased ##
Cary Clark8032b982017-07-28 11:04:54 -04002498
2499#Example
2500#Height 128
Cary Clarkbad5ad72017-08-03 17:14:08 -04002501void draw(SkCanvas* canvas) {
2502 canvas->clear(SK_ColorWHITE);
2503 SkPaint paint;
2504 paint.setAntiAlias(true);
2505 paint.setColor(0x8055aaff);
2506 SkRRect oval;
2507 oval.setOval({10, 20, 90, 100});
2508 canvas->clipRRect(oval, SkClipOp::kIntersect, true);
2509 canvas->drawCircle(70, 100, 60, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002510}
2511##
2512
2513#ToDo incomplete ##
2514
2515##
2516
2517#Method void clipRRect(const SkRRect& rrect, SkClipOp op)
2518
2519Replace Clip with the intersection or difference of Clip and rrect.
Cary Clarkce101242017-09-01 15:51:02 -04002520Resulting Clip is Aliased; pixels are fully contained by the clip.
Cary Clarkbad5ad72017-08-03 17:14:08 -04002521rrect is transformed by Matrix before it is combined with Clip.
Cary Clark8032b982017-07-28 11:04:54 -04002522
Cary Clarkbad5ad72017-08-03 17:14:08 -04002523#Param rrect Round_Rect to combine with Clip ##
2524#Param op Clip_Op to apply to Clip ##
Cary Clark8032b982017-07-28 11:04:54 -04002525
2526#Example
2527#Height 128
Cary Clarkbad5ad72017-08-03 17:14:08 -04002528void draw(SkCanvas* canvas) {
2529 SkPaint paint;
2530 paint.setColor(0x8055aaff);
2531 auto oval = SkRRect::MakeOval({10, 20, 90, 100});
2532 canvas->clipRRect(oval, SkClipOp::kIntersect);
2533 canvas->drawCircle(70, 100, 60, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002534}
2535##
2536
2537#ToDo incomplete ##
2538
2539##
2540
2541#Method void clipRRect(const SkRRect& rrect, bool doAntiAlias = false)
2542
2543Replace Clip with the intersection of Clip and rrect,
Cary Clarkce101242017-09-01 15:51:02 -04002544with an Aliased or Anti-aliased clip edge.
Cary Clarkbad5ad72017-08-03 17:14:08 -04002545rrect is transformed by Matrix before it is combined with Clip.
Cary Clark8032b982017-07-28 11:04:54 -04002546
Cary Clarkbad5ad72017-08-03 17:14:08 -04002547#Param rrect Round_Rect to combine with Clip ##
Cary Clarkce101242017-09-01 15:51:02 -04002548#Param doAntiAlias true if Clip is to be Anti-aliased ##
Cary Clark8032b982017-07-28 11:04:54 -04002549
2550#Example
2551#Height 128
Cary Clarkbad5ad72017-08-03 17:14:08 -04002552void draw(SkCanvas* canvas) {
2553 SkPaint paint;
2554 paint.setAntiAlias(true);
2555 auto oval = SkRRect::MakeRectXY({10, 20, 90, 100}, 9, 13);
2556 canvas->clipRRect(oval, true);
2557 canvas->drawCircle(70, 100, 60, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002558}
2559##
2560
2561#ToDo incomplete ##
2562
2563##
2564
2565#Method void clipPath(const SkPath& path, SkClipOp op, bool doAntiAlias)
2566
2567Replace Clip with the intersection or difference of Clip and path,
Cary Clarkce101242017-09-01 15:51:02 -04002568with an Aliased or Anti-aliased clip edge. Path_Fill_Type determines if path
Cary Clark8032b982017-07-28 11:04:54 -04002569describes the area inside or outside its contours; and if Path_Contour overlaps
2570itself or another Path_Contour, whether the overlaps form part of the area.
Cary Clarkbad5ad72017-08-03 17:14:08 -04002571path is transformed by Matrix before it is combined with Clip.
Cary Clark8032b982017-07-28 11:04:54 -04002572
Cary Clarkbad5ad72017-08-03 17:14:08 -04002573#Param path Path to combine with Clip ##
2574#Param op Clip_Op to apply to Clip ##
Cary Clarkce101242017-09-01 15:51:02 -04002575#Param doAntiAlias true if Clip is to be Anti-aliased ##
Cary Clark8032b982017-07-28 11:04:54 -04002576
2577#Example
2578#Description
2579Top figure uses SkPath::kInverseWinding_FillType and SkClipOp::kDifference;
2580area outside clip is subtracted from circle.
2581
2582Bottom figure uses SkPath::kWinding_FillType and SkClipOp::kIntersect;
2583area inside clip is intersected with circle.
2584##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002585void draw(SkCanvas* canvas) {
2586 SkPaint paint;
2587 paint.setAntiAlias(true);
2588 SkPath path;
2589 path.addRect({20, 30, 100, 110});
2590 path.setFillType(SkPath::kInverseWinding_FillType);
2591 canvas->save();
2592 canvas->clipPath(path, SkClipOp::kDifference, false);
2593 canvas->drawCircle(70, 100, 60, paint);
2594 canvas->restore();
2595 canvas->translate(100, 100);
2596 path.setFillType(SkPath::kWinding_FillType);
2597 canvas->clipPath(path, SkClipOp::kIntersect, false);
2598 canvas->drawCircle(70, 100, 60, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002599}
2600##
2601
2602#ToDo incomplete ##
2603
2604##
2605
2606#Method void clipPath(const SkPath& path, SkClipOp op)
2607
2608Replace Clip with the intersection or difference of Clip and path.
Cary Clarkce101242017-09-01 15:51:02 -04002609Resulting Clip is Aliased; pixels are fully contained by the clip.
Cary Clark8032b982017-07-28 11:04:54 -04002610Path_Fill_Type determines if path
2611describes the area inside or outside its contours; and if Path_Contour overlaps
2612itself or another Path_Contour, whether the overlaps form part of the area.
2613path is transformed by Matrix
2614before it is combined with Clip.
2615
Cary Clarkbad5ad72017-08-03 17:14:08 -04002616#Param path Path to combine with Clip ##
2617#Param op Clip_Op to apply to Clip ##
Cary Clark8032b982017-07-28 11:04:54 -04002618
2619#Example
2620#Description
Cary Clarkbc5697d2017-10-04 14:31:33 -04002621Overlapping Rects form a clip. When clip Path_Fill_Type is set to
Cary Clark8032b982017-07-28 11:04:54 -04002622SkPath::kWinding_FillType, the overlap is included. Set to
2623SkPath::kEvenOdd_FillType, the overlap is excluded and forms a hole.
2624##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002625void draw(SkCanvas* canvas) {
2626 SkPaint paint;
2627 paint.setAntiAlias(true);
2628 SkPath path;
2629 path.addRect({20, 15, 100, 95});
2630 path.addRect({50, 65, 130, 135});
2631 path.setFillType(SkPath::kWinding_FillType);
2632 canvas->save();
2633 canvas->clipPath(path, SkClipOp::kIntersect);
2634 canvas->drawCircle(70, 85, 60, paint);
2635 canvas->restore();
2636 canvas->translate(100, 100);
2637 path.setFillType(SkPath::kEvenOdd_FillType);
2638 canvas->clipPath(path, SkClipOp::kIntersect);
2639 canvas->drawCircle(70, 85, 60, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002640}
2641##
2642
2643#ToDo incomplete ##
2644
2645##
2646
2647#Method void clipPath(const SkPath& path, bool doAntiAlias = false)
2648
2649Replace Clip with the intersection of Clip and path.
Cary Clarkce101242017-09-01 15:51:02 -04002650Resulting Clip is Aliased; pixels are fully contained by the clip.
Cary Clark8032b982017-07-28 11:04:54 -04002651Path_Fill_Type determines if path
2652describes the area inside or outside its contours; and if Path_Contour overlaps
2653itself or another Path_Contour, whether the overlaps form part of the area.
Cary Clarkbad5ad72017-08-03 17:14:08 -04002654path is transformed by Matrix before it is combined with Clip.
Cary Clark8032b982017-07-28 11:04:54 -04002655
Cary Clarkbad5ad72017-08-03 17:14:08 -04002656#Param path Path to combine with Clip ##
Cary Clarkce101242017-09-01 15:51:02 -04002657#Param doAntiAlias true if Clip is to be Anti-aliased ##
Cary Clark8032b982017-07-28 11:04:54 -04002658
2659#Example
2660#Height 212
2661#Description
Cary Clarkbc5697d2017-10-04 14:31:33 -04002662Clip loops over itself covering its center twice. When clip Path_Fill_Type
Cary Clark8032b982017-07-28 11:04:54 -04002663is set to SkPath::kWinding_FillType, the overlap is included. Set to
2664SkPath::kEvenOdd_FillType, the overlap is excluded and forms a hole.
2665##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002666void draw(SkCanvas* canvas) {
2667 SkPaint paint;
2668 paint.setAntiAlias(true);
2669 SkPath path;
2670 SkPoint poly[] = {{20, 20}, { 80, 20}, { 80, 80}, {40, 80},
2671 {40, 40}, {100, 40}, {100, 100}, {20, 100}};
2672 path.addPoly(poly, SK_ARRAY_COUNT(poly), true);
2673 path.setFillType(SkPath::kWinding_FillType);
2674 canvas->save();
2675 canvas->clipPath(path, SkClipOp::kIntersect);
2676 canvas->drawCircle(50, 50, 45, paint);
2677 canvas->restore();
2678 canvas->translate(100, 100);
2679 path.setFillType(SkPath::kEvenOdd_FillType);
2680 canvas->clipPath(path, SkClipOp::kIntersect);
2681 canvas->drawCircle(50, 50, 45, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002682}
2683##
2684
2685#ToDo incomplete ##
2686
2687##
2688
2689# ------------------------------------------------------------------------------
2690
2691#Method void setAllowSimplifyClip(bool allow)
2692
2693#Experimental
2694Only used for testing.
2695##
2696
Cary Clarkce101242017-09-01 15:51:02 -04002697Set to simplify clip stack using PathOps.
Cary Clark8032b982017-07-28 11:04:54 -04002698
2699##
2700
2701# ------------------------------------------------------------------------------
2702
2703#Method void clipRegion(const SkRegion& deviceRgn, SkClipOp op = SkClipOp::kIntersect)
2704
2705Replace Clip with the intersection or difference of Clip and Region deviceRgn.
Cary Clarkce101242017-09-01 15:51:02 -04002706Resulting Clip is Aliased; pixels are fully contained by the clip.
Cary Clark8032b982017-07-28 11:04:54 -04002707deviceRgn is unaffected by Matrix.
2708
Cary Clarkbad5ad72017-08-03 17:14:08 -04002709#Param deviceRgn Region to combine with Clip ##
2710#Param op Clip_Op to apply to Clip ##
Cary Clark8032b982017-07-28 11:04:54 -04002711
2712#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04002713#Description
Cary Clarkce101242017-09-01 15:51:02 -04002714 region is unaffected by canvas rotation; iRect is affected by canvas rotation.
2715 Both clips are Aliased; this is not noticeable on Region clip because it
Cary Clarkbad5ad72017-08-03 17:14:08 -04002716 aligns to pixel boundaries.
2717##
2718void draw(SkCanvas* canvas) {
2719 SkPaint paint;
2720 paint.setAntiAlias(true);
2721 SkIRect iRect = {30, 40, 120, 130 };
2722 SkRegion region(iRect);
2723 canvas->rotate(10);
2724 canvas->save();
2725 canvas->clipRegion(region, SkClipOp::kIntersect);
2726 canvas->drawCircle(50, 50, 45, paint);
2727 canvas->restore();
2728 canvas->translate(100, 100);
2729 canvas->clipRect(SkRect::Make(iRect), SkClipOp::kIntersect);
2730 canvas->drawCircle(50, 50, 45, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002731}
2732##
2733
2734#ToDo incomplete ##
2735
2736##
2737
2738#Method bool quickReject(const SkRect& rect) const
2739
2740Return true if Rect rect, transformed by Matrix, can be quickly determined to be
2741outside of Clip. May return false even though rect is outside of Clip.
2742
2743Use to check if an area to be drawn is clipped out, to skip subsequent draw calls.
2744
Cary Clarkbad5ad72017-08-03 17:14:08 -04002745#Param rect Rect to compare with Clip ##
Cary Clark8032b982017-07-28 11:04:54 -04002746
Cary Clarkbad5ad72017-08-03 17:14:08 -04002747#Return true if rect, transformed by Matrix, does not intersect Clip ##
Cary Clark8032b982017-07-28 11:04:54 -04002748
2749#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04002750void draw(SkCanvas* canvas) {
2751 SkRect testRect = {30, 30, 120, 129 };
2752 SkRect clipRect = {30, 130, 120, 230 };
2753 canvas->save();
2754 canvas->clipRect(clipRect);
2755 SkDebugf("quickReject %s\n", canvas->quickReject(testRect) ? "true" : "false");
2756 canvas->restore();
2757 canvas->rotate(10);
2758 canvas->clipRect(clipRect);
2759 SkDebugf("quickReject %s\n", canvas->quickReject(testRect) ? "true" : "false");
Cary Clark8032b982017-07-28 11:04:54 -04002760}
2761 #StdOut
Cary Clarkbad5ad72017-08-03 17:14:08 -04002762 quickReject true
Cary Clark8032b982017-07-28 11:04:54 -04002763 quickReject false
2764 ##
2765##
2766
2767#ToDo incomplete ##
2768
2769##
2770
2771#Method bool quickReject(const SkPath& path) const
2772
2773Return true if path, transformed by Matrix, can be quickly determined to be
2774outside of Clip. May return false even though path is outside of Clip.
2775
2776Use to check if an area to be drawn is clipped out, to skip subsequent draw calls.
2777
Cary Clarkbad5ad72017-08-03 17:14:08 -04002778#Param path Path to compare with Clip ##
Cary Clark8032b982017-07-28 11:04:54 -04002779
Cary Clarkbad5ad72017-08-03 17:14:08 -04002780#Return true if path, transformed by Matrix, does not intersect Clip ##
Cary Clark8032b982017-07-28 11:04:54 -04002781
2782#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04002783void draw(SkCanvas* canvas) {
2784 SkPoint testPoints[] = {{30, 30}, {120, 30}, {120, 129} };
2785 SkPoint clipPoints[] = {{30, 130}, {120, 130}, {120, 230} };
2786 SkPath testPath, clipPath;
2787 testPath.addPoly(testPoints, SK_ARRAY_COUNT(testPoints), true);
2788 clipPath.addPoly(clipPoints, SK_ARRAY_COUNT(clipPoints), true);
2789 canvas->save();
2790 canvas->clipPath(clipPath);
2791 SkDebugf("quickReject %s\n", canvas->quickReject(testPath) ? "true" : "false");
2792 canvas->restore();
2793 canvas->rotate(10);
2794 canvas->clipPath(clipPath);
2795 SkDebugf("quickReject %s\n", canvas->quickReject(testPath) ? "true" : "false");
Cary Clark8032b982017-07-28 11:04:54 -04002796 #StdOut
Cary Clarkbad5ad72017-08-03 17:14:08 -04002797 quickReject true
Cary Clark8032b982017-07-28 11:04:54 -04002798 quickReject false
2799 ##
2800}
2801##
2802
2803#ToDo incomplete ##
2804
2805##
2806
2807#Method SkRect getLocalClipBounds() const
2808
2809Return bounds of Clip, transformed by inverse of Matrix. If Clip is empty,
2810return SkRect::MakeEmpty, where all Rect sides equal zero.
2811
2812Rect returned is outset by one to account for partial pixel coverage if Clip
Cary Clarkce101242017-09-01 15:51:02 -04002813is Anti-aliased.
Cary Clark8032b982017-07-28 11:04:54 -04002814
Cary Clarkbad5ad72017-08-03 17:14:08 -04002815#Return bounds of Clip in local coordinates ##
Cary Clark8032b982017-07-28 11:04:54 -04002816
2817#Example
2818 #Description
2819 Initial bounds is device bounds outset by 1 on all sides.
2820 Clipped bounds is clipPath bounds outset by 1 on all sides.
2821 Scaling the canvas by two in x and y scales the local bounds by 1/2 in x and y.
2822 ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002823 SkCanvas local(256, 256);
2824 canvas = &local;
2825 SkRect bounds = canvas->getLocalClipBounds();
2826 SkDebugf("left:%g top:%g right:%g bottom:%g\n",
2827 bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom);
2828 SkPoint clipPoints[] = {{30, 130}, {120, 130}, {120, 230} };
2829 SkPath clipPath;
2830 clipPath.addPoly(clipPoints, SK_ARRAY_COUNT(clipPoints), true);
2831 canvas->clipPath(clipPath);
2832 bounds = canvas->getLocalClipBounds();
2833 SkDebugf("left:%g top:%g right:%g bottom:%g\n",
2834 bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom);
2835 canvas->scale(2, 2);
2836 bounds = canvas->getLocalClipBounds();
2837 SkDebugf("left:%g top:%g right:%g bottom:%g\n",
2838 bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom);
2839 #StdOut
2840 left:-1 top:-1 right:257 bottom:257
2841 left:29 top:129 right:121 bottom:231
2842 left:14.5 top:64.5 right:60.5 bottom:115.5
2843 ##
Cary Clark8032b982017-07-28 11:04:54 -04002844##
2845
2846# local canvas in example works around bug in fiddle ##
2847#Bug 6524 ##
2848
2849##
2850
2851#Method bool getLocalClipBounds(SkRect* bounds) const
2852
2853Return bounds of Clip, transformed by inverse of Matrix. If Clip is empty,
2854return false, and set bounds to SkRect::MakeEmpty, where all Rect sides equal zero.
2855
2856bounds is outset by one to account for partial pixel coverage if Clip
Cary Clarkce101242017-09-01 15:51:02 -04002857is Anti-aliased.
Cary Clark8032b982017-07-28 11:04:54 -04002858
Cary Clarkbad5ad72017-08-03 17:14:08 -04002859#Param bounds Rect of Clip in local coordinates ##
Cary Clark8032b982017-07-28 11:04:54 -04002860
Cary Clarkbad5ad72017-08-03 17:14:08 -04002861#Return true if Clip bounds is not empty ##
Cary Clark8032b982017-07-28 11:04:54 -04002862
2863#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04002864 void draw(SkCanvas* canvas) {
2865 SkCanvas local(256, 256);
2866 canvas = &local;
2867 SkRect bounds;
2868 SkDebugf("local bounds empty = %s\n", canvas->getLocalClipBounds(&bounds)
2869 ? "false" : "true");
2870 SkPath path;
2871 canvas->clipPath(path);
2872 SkDebugf("local bounds empty = %s\n", canvas->getLocalClipBounds(&bounds)
2873 ? "false" : "true");
Cary Clark8032b982017-07-28 11:04:54 -04002874 }
2875 #StdOut
Cary Clarkbad5ad72017-08-03 17:14:08 -04002876 local bounds empty = false
Cary Clark8032b982017-07-28 11:04:54 -04002877 local bounds empty = true
2878 ##
2879##
2880
2881# local canvas in example works around bug in fiddle ##
2882#Bug 6524 ##
2883
2884##
2885
2886#Method SkIRect getDeviceClipBounds() const
2887
2888Return IRect bounds of Clip, unaffected by Matrix. If Clip is empty,
2889return SkRect::MakeEmpty, where all Rect sides equal zero.
2890
2891Unlike getLocalClipBounds, returned IRect is not outset.
2892
Cary Clarkbad5ad72017-08-03 17:14:08 -04002893#Return bounds of Clip in Device coordinates ##
Cary Clark8032b982017-07-28 11:04:54 -04002894
2895#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04002896void draw(SkCanvas* canvas) {
2897 #Description
Cary Clark8032b982017-07-28 11:04:54 -04002898 Initial bounds is device bounds, not outset.
2899 Clipped bounds is clipPath bounds, not outset.
2900 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 -04002901 ##
2902 SkCanvas device(256, 256);
2903 canvas = &device;
2904 SkIRect bounds = canvas->getDeviceClipBounds();
2905 SkDebugf("left:%d top:%d right:%d bottom:%d\n",
2906 bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom);
2907 SkPoint clipPoints[] = {{30, 130}, {120, 130}, {120, 230} };
2908 SkPath clipPath;
2909 clipPath.addPoly(clipPoints, SK_ARRAY_COUNT(clipPoints), true);
2910 canvas->save();
2911 canvas->clipPath(clipPath);
2912 bounds = canvas->getDeviceClipBounds();
2913 SkDebugf("left:%d top:%d right:%d bottom:%d\n",
2914 bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom);
2915 canvas->restore();
2916 canvas->scale(1.f/2, 1.f/2);
2917 canvas->clipPath(clipPath);
2918 bounds = canvas->getDeviceClipBounds();
2919 SkDebugf("left:%d top:%d right:%d bottom:%d\n",
2920 bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom);
Cary Clark8032b982017-07-28 11:04:54 -04002921 #StdOut
Cary Clarkbad5ad72017-08-03 17:14:08 -04002922 left:0 top:0 right:256 bottom:256
2923 left:30 top:130 right:120 bottom:230
Cary Clark8032b982017-07-28 11:04:54 -04002924 left:15 top:65 right:60 bottom:115
2925 ##
2926}
2927##
2928
2929#ToDo some confusion on why with an identity Matrix local and device are different ##
2930
2931# device canvas in example works around bug in fiddle ##
2932#Bug 6524 ##
2933
2934##
2935
2936#Method bool getDeviceClipBounds(SkIRect* bounds) const
2937
2938Return IRect bounds of Clip, unaffected by Matrix. If Clip is empty,
2939return false, and set bounds to SkRect::MakeEmpty, where all Rect sides equal zero.
2940
2941Unlike getLocalClipBounds, bounds is not outset.
2942
Cary Clarkbad5ad72017-08-03 17:14:08 -04002943#Param bounds Rect of Clip in device coordinates ##
Cary Clark8032b982017-07-28 11:04:54 -04002944
Cary Clarkbad5ad72017-08-03 17:14:08 -04002945#Return true if Clip bounds is not empty ##
Cary Clark8032b982017-07-28 11:04:54 -04002946
2947#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04002948 void draw(SkCanvas* canvas) {
2949 SkIRect bounds;
2950 SkDebugf("device bounds empty = %s\n", canvas->getDeviceClipBounds(&bounds)
2951 ? "false" : "true");
2952 SkPath path;
2953 canvas->clipPath(path);
2954 SkDebugf("device bounds empty = %s\n", canvas->getDeviceClipBounds(&bounds)
2955 ? "false" : "true");
Cary Clark8032b982017-07-28 11:04:54 -04002956 }
2957 #StdOut
Cary Clarkbad5ad72017-08-03 17:14:08 -04002958 device bounds empty = false
Cary Clark8032b982017-07-28 11:04:54 -04002959 device bounds empty = true
2960 ##
2961##
2962
2963#ToDo incomplete ##
2964
2965##
2966
2967#Topic Clip ##
2968
2969# ------------------------------------------------------------------------------
2970
2971#Method void drawColor(SkColor color, SkBlendMode mode = SkBlendMode::kSrcOver)
2972
2973Fill Clip with Color color.
2974mode determines how Color_ARGB is combined with destination.
2975
Cary Clarkbad5ad72017-08-03 17:14:08 -04002976#Param color Unpremultiplied Color_ARGB ##
2977#Param mode SkBlendMode used to combine source color and destination ##
Cary Clark8032b982017-07-28 11:04:54 -04002978
2979#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04002980 canvas->drawColor(SK_ColorRED);
2981 canvas->clipRect(SkRect::MakeWH(150, 150));
2982 canvas->drawColor(SkColorSetARGB(0x80, 0x00, 0xFF, 0x00), SkBlendMode::kPlus);
2983 canvas->clipRect(SkRect::MakeWH(75, 75));
2984 canvas->drawColor(SkColorSetARGB(0x80, 0x00, 0x00, 0xFF), SkBlendMode::kPlus);
Cary Clark8032b982017-07-28 11:04:54 -04002985##
2986
2987#ToDo incomplete ##
2988
2989##
2990
2991# ------------------------------------------------------------------------------
2992
2993#Method void clear(SkColor color)
2994
2995Fill Clip with Color color using SkBlendMode::kSrc.
2996This has the effect of replacing all pixels contained by Clip with color.
2997
Cary Clarkbad5ad72017-08-03 17:14:08 -04002998#Param color Unpremultiplied Color_ARGB ##
Cary Clark8032b982017-07-28 11:04:54 -04002999
3000#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003001void draw(SkCanvas* canvas) {
3002 canvas->save();
3003 canvas->clipRect(SkRect::MakeWH(256, 128));
3004 canvas->clear(SkColorSetARGB(0x80, 0xFF, 0x00, 0x00));
3005 canvas->restore();
3006 canvas->save();
3007 canvas->clipRect(SkRect::MakeWH(150, 192));
3008 canvas->clear(SkColorSetARGB(0x80, 0x00, 0xFF, 0x00));
3009 canvas->restore();
3010 canvas->clipRect(SkRect::MakeWH(75, 256));
3011 canvas->clear(SkColorSetARGB(0x80, 0x00, 0x00, 0xFF));
Cary Clark8032b982017-07-28 11:04:54 -04003012}
3013##
3014
3015#ToDo incomplete ##
3016
3017##
3018
3019# ------------------------------------------------------------------------------
3020
3021#Method void discard()
3022
3023Make Canvas contents undefined. Subsequent calls that read Canvas pixels,
3024such as drawing with SkBlendMode, return undefined results. discard() does
3025not change Clip or Matrix.
3026
3027discard() may do nothing, depending on the implementation of Surface or Device
3028that created Canvas.
3029
3030discard() allows optimized performance on subsequent draws by removing
3031cached data associated with Surface or Device.
3032It is not necessary to call discard() once done with Canvas;
3033any cached data is deleted when owning Surface or Device is deleted.
3034
3035#ToDo example? not sure how to make this meaningful w/o more implementation detail ##
3036
3037#NoExample
3038##
3039
3040##
3041
3042# ------------------------------------------------------------------------------
3043
3044#Method void drawPaint(const SkPaint& paint)
3045
Cary Clarkbad5ad72017-08-03 17:14:08 -04003046Fill Clip with Paint paint. Paint components Rasterizer, Mask_Filter, Shader,
3047Color_Filter, Image_Filter, and Blend_Mode affect drawing;
3048Path_Effect in paint is ignored.
Cary Clark8032b982017-07-28 11:04:54 -04003049
3050# can Path_Effect in paint ever alter drawPaint?
3051
Cary Clarkbad5ad72017-08-03 17:14:08 -04003052#Param paint graphics state used to fill Canvas ##
Cary Clark8032b982017-07-28 11:04:54 -04003053
3054#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003055void draw(SkCanvas* canvas) {
3056 SkColor colors[] = { SK_ColorRED, SK_ColorGREEN, SK_ColorBLUE };
3057 SkScalar pos[] = { 0, SK_Scalar1/2, SK_Scalar1 };
3058 SkPaint paint;
3059 paint.setShader(SkGradientShader::MakeSweep(256, 256, colors, pos, SK_ARRAY_COUNT(colors)));
3060 canvas->drawPaint(paint);
Cary Clark8032b982017-07-28 11:04:54 -04003061}
3062##
3063
3064#ToDo incomplete ##
3065
3066##
3067
3068# ------------------------------------------------------------------------------
3069
3070#Enum PointMode
3071
3072#Code
3073 enum PointMode {
3074 kPoints_PointMode,
3075 kLines_PointMode,
Cary Clarkd0530ba2017-09-14 11:25:39 -04003076 kPolygon_PointMode,
Cary Clark8032b982017-07-28 11:04:54 -04003077 };
3078##
3079
3080Selects if an array of points are drawn as discrete points, as lines, or as
3081an open polygon.
3082
3083#Const kPoints_PointMode 0
3084 Draw each point separately.
3085##
3086
3087#Const kLines_PointMode 1
3088 Draw each pair of points as a line segment.
3089##
3090
3091#Const kPolygon_PointMode 2
3092 Draw the array of points as a open polygon.
3093##
3094
3095#Example
3096 #Description
3097 The upper left corner shows three squares when drawn as points.
3098 The upper right corner shows one line; when drawn as lines, two points are required per line.
3099 The lower right corner shows two lines; when draw as polygon, no miter is drawn at the corner.
3100 The lower left corner shows two lines with a miter when path contains polygon.
3101 ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003102void draw(SkCanvas* canvas) {
3103 SkPaint paint;
3104 paint.setStyle(SkPaint::kStroke_Style);
3105 paint.setStrokeWidth(10);
3106 SkPoint points[] = {{64, 32}, {96, 96}, {32, 96}};
3107 canvas->drawPoints(SkCanvas::kPoints_PointMode, 3, points, paint);
3108 canvas->translate(128, 0);
3109 canvas->drawPoints(SkCanvas::kLines_PointMode, 3, points, paint);
3110 canvas->translate(0, 128);
3111 canvas->drawPoints(SkCanvas::kPolygon_PointMode, 3, points, paint);
3112 SkPath path;
3113 path.addPoly(points, 3, false);
3114 canvas->translate(-128, 0);
3115 canvas->drawPath(path, paint);
Cary Clark8032b982017-07-28 11:04:54 -04003116}
3117##
3118
3119#ToDo incomplete ##
3120
3121##
3122
3123# ------------------------------------------------------------------------------
3124
3125#Method void drawPoints(PointMode mode, size_t count, const SkPoint pts[], const SkPaint& paint)
3126
3127Draw pts using Clip, Matrix and Paint paint.
Cary Clarkbad5ad72017-08-03 17:14:08 -04003128count is the number of points; if count is less than one, has no effect.
Cary Clark8032b982017-07-28 11:04:54 -04003129mode may be one of: kPoints_PointMode, kLines_PointMode, or kPolygon_PointMode.
3130
Cary Clarkbad5ad72017-08-03 17:14:08 -04003131If mode is kPoints_PointMode, the shape of point drawn depends on paint
3132Paint_Stroke_Cap. If paint is set to SkPaint::kRound_Cap, each point draws a
3133circle of diameter Paint_Stroke_Width. If paint is set to SkPaint::kSquare_Cap
3134or SkPaint::kButt_Cap, each point draws a square of width and height
3135Paint_Stroke_Width.
Cary Clark8032b982017-07-28 11:04:54 -04003136
3137If mode is kLines_PointMode, each pair of points draws a line segment.
3138One line is drawn for every two points; each point is used once. If count is odd,
3139the final point is ignored.
3140
3141If mode is kPolygon_PointMode, each adjacent pair of points draws a line segment.
3142count minus one lines are drawn; the first and last point are used once.
3143
3144Each line segment respects paint Paint_Stroke_Cap and Paint_Stroke_Width.
3145Paint_Style is ignored, as if were set to SkPaint::kStroke_Style.
3146
Cary Clarkbad5ad72017-08-03 17:14:08 -04003147Always draws each element one at a time; is not affected by
3148Paint_Stroke_Join, and unlike drawPath, does not create a mask from all points
3149and lines before drawing.
Cary Clark8032b982017-07-28 11:04:54 -04003150
Cary Clarka523d2d2017-08-30 08:58:10 -04003151#Param mode whether pts draws points or lines ##
3152#Param count number of points in the array ##
3153#Param pts array of points to draw ##
3154#Param paint stroke, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003155
3156#Example
3157#Height 200
3158 #Description
3159 #List
3160 # The first column draws points. ##
3161 # The second column draws points as lines. ##
3162 # The third column draws points as a polygon. ##
3163 # The fourth column draws points as a polygonal path. ##
3164 # The first row uses a round cap and round join. ##
3165 # The second row uses a square cap and a miter join. ##
3166 # The third row uses a butt cap and a bevel join. ##
3167 ##
3168 The transparent color makes multiple line draws visible;
3169 the path is drawn all at once.
3170 ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003171void draw(SkCanvas* canvas) {
3172 SkPaint paint;
3173 paint.setAntiAlias(true);
3174 paint.setStyle(SkPaint::kStroke_Style);
3175 paint.setStrokeWidth(10);
3176 paint.setColor(0x80349a45);
3177 const SkPoint points[] = {{32, 16}, {48, 48}, {16, 32}};
3178 const SkPaint::Join join[] = { SkPaint::kRound_Join,
3179 SkPaint::kMiter_Join,
3180 SkPaint::kBevel_Join };
3181 int joinIndex = 0;
3182 SkPath path;
3183 path.addPoly(points, 3, false);
3184 for (const auto cap : { SkPaint::kRound_Cap, SkPaint::kSquare_Cap, SkPaint::kButt_Cap } ) {
3185 paint.setStrokeCap(cap);
3186 paint.setStrokeJoin(join[joinIndex++]);
3187 for (const auto mode : { SkCanvas::kPoints_PointMode,
3188 SkCanvas::kLines_PointMode,
3189 SkCanvas::kPolygon_PointMode } ) {
3190 canvas->drawPoints(mode, 3, points, paint);
3191 canvas->translate(64, 0);
3192 }
3193 canvas->drawPath(path, paint);
3194 canvas->translate(-192, 64);
3195 }
Cary Clark8032b982017-07-28 11:04:54 -04003196}
3197##
3198
3199#ToDo incomplete ##
3200
3201##
3202
3203# ------------------------------------------------------------------------------
3204
3205#Method void drawPoint(SkScalar x, SkScalar y, const SkPaint& paint)
3206
3207Draw point at (x, y) using Clip, Matrix and Paint paint.
3208
3209The shape of point drawn depends on paint Paint_Stroke_Cap.
Cary Clarkbad5ad72017-08-03 17:14:08 -04003210If paint is set to SkPaint::kRound_Cap, draw a circle of diameter
3211Paint_Stroke_Width. If paint is set to SkPaint::kSquare_Cap or SkPaint::kButt_Cap,
Cary Clark8032b982017-07-28 11:04:54 -04003212draw a square of width and height Paint_Stroke_Width.
3213Paint_Style is ignored, as if were set to SkPaint::kStroke_Style.
3214
Cary Clarkbad5ad72017-08-03 17:14:08 -04003215#Param x left edge of circle or square ##
3216#Param y top edge of circle or square ##
3217#Param paint stroke, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003218
3219#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003220void draw(SkCanvas* canvas) {
3221 SkPaint paint;
3222 paint.setAntiAlias(true);
3223 paint.setColor(0x80349a45);
3224 paint.setStyle(SkPaint::kStroke_Style);
3225 paint.setStrokeWidth(100);
3226 paint.setStrokeCap(SkPaint::kRound_Cap);
3227 canvas->scale(1, 1.2f);
3228 canvas->drawPoint(64, 96, paint);
3229 canvas->scale(.6f, .8f);
3230 paint.setColor(SK_ColorWHITE);
3231 canvas->drawPoint(106, 120, paint);
Cary Clark8032b982017-07-28 11:04:54 -04003232}
3233##
3234
3235#ToDo incomplete ##
3236
3237##
3238
Cary Clarkbad5ad72017-08-03 17:14:08 -04003239#Method void drawPoint(SkPoint p, const SkPaint& paint)
3240
3241Draw point p using Clip, Matrix and Paint paint.
3242
3243The shape of point drawn depends on paint Paint_Stroke_Cap.
3244If paint is set to SkPaint::kRound_Cap, draw a circle of diameter
3245Paint_Stroke_Width. If paint is set to SkPaint::kSquare_Cap or SkPaint::kButt_Cap,
3246draw a square of width and height Paint_Stroke_Width.
3247Paint_Style is ignored, as if were set to SkPaint::kStroke_Style.
3248
3249#Param p top-left edge of circle or square ##
3250#Param paint stroke, blend, color, and so on, used to draw ##
3251
3252#Example
3253void draw(SkCanvas* canvas) {
3254 SkPaint paint;
3255 paint.setAntiAlias(true);
3256 paint.setColor(0x80349a45);
3257 paint.setStyle(SkPaint::kStroke_Style);
3258 paint.setStrokeWidth(100);
3259 paint.setStrokeCap(SkPaint::kSquare_Cap);
3260 canvas->scale(1, 1.2f);
3261 canvas->drawPoint({64, 96}, paint);
3262 canvas->scale(.6f, .8f);
3263 paint.setColor(SK_ColorWHITE);
3264 canvas->drawPoint(106, 120, paint);
3265}
3266##
3267
3268#SeeAlso drawPoints drawCircle drawRect
3269
3270##
3271
Cary Clark8032b982017-07-28 11:04:54 -04003272# ------------------------------------------------------------------------------
3273
3274#Method void drawLine(SkScalar x0, SkScalar y0, SkScalar x1, SkScalar y1, const SkPaint& paint)
3275
Cary Clarkbad5ad72017-08-03 17:14:08 -04003276Draws line segment from (x0, y0) to (x1, y1) using Clip, Matrix, and Paint paint.
3277In paint: Paint_Stroke_Width describes the line thickness;
3278Paint_Stroke_Cap draws the end rounded or square;
Cary Clark8032b982017-07-28 11:04:54 -04003279Paint_Style is ignored, as if were set to SkPaint::kStroke_Style.
3280
Cary Clarkbad5ad72017-08-03 17:14:08 -04003281#Param x0 start of line segment on x-axis ##
3282#Param y0 start of line segment on y-axis ##
3283#Param x1 end of line segment on x-axis ##
3284#Param y1 end of line segment on y-axis ##
3285#Param paint stroke, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003286
3287#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003288 SkPaint paint;
3289 paint.setAntiAlias(true);
3290 paint.setColor(0xFF9a67be);
3291 paint.setStrokeWidth(20);
3292 canvas->skew(1, 0);
3293 canvas->drawLine(32, 96, 32, 160, paint);
3294 canvas->skew(-2, 0);
3295 canvas->drawLine(288, 96, 288, 160, paint);
3296##
3297
3298#ToDo incomplete ##
3299
3300##
3301
3302#Method void drawLine(SkPoint p0, SkPoint p1, const SkPaint& paint)
3303
3304Draws line segment from p0 to p1 using Clip, Matrix, and Paint paint.
3305In paint: Paint_Stroke_Width describes the line thickness;
3306Paint_Stroke_Cap draws the end rounded or square;
3307Paint_Style is ignored, as if were set to SkPaint::kStroke_Style.
3308
3309#Param p0 start of line segment ##
3310#Param p1 end of line segment ##
3311#Param paint stroke, blend, color, and so on, used to draw ##
3312
3313#Example
3314 SkPaint paint;
3315 paint.setAntiAlias(true);
3316 paint.setColor(0xFF9a67be);
3317 paint.setStrokeWidth(20);
3318 canvas->skew(1, 0);
3319 canvas->drawLine({32, 96}, {32, 160}, paint);
3320 canvas->skew(-2, 0);
3321 canvas->drawLine({288, 96}, {288, 160}, paint);
Cary Clark8032b982017-07-28 11:04:54 -04003322##
3323
3324#ToDo incomplete ##
3325
3326##
3327
3328# ------------------------------------------------------------------------------
3329
3330#Method void drawRect(const SkRect& rect, const SkPaint& paint)
3331
3332Draw Rect rect using Clip, Matrix, and Paint paint.
3333In paint: Paint_Style determines if rectangle is stroked or filled;
3334if stroked, Paint_Stroke_Width describes the line thickness, and
3335Paint_Stroke_Join draws the corners rounded or square.
3336
Cary Clarkbc5697d2017-10-04 14:31:33 -04003337#Param rect rectangle to draw ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003338#Param paint stroke or fill, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003339
3340#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003341void draw(SkCanvas* canvas) {
3342 SkPoint rectPts[] = { {64, 48}, {192, 160} };
3343 SkPaint paint;
3344 paint.setAntiAlias(true);
3345 paint.setStyle(SkPaint::kStroke_Style);
3346 paint.setStrokeWidth(20);
3347 paint.setStrokeJoin(SkPaint::kRound_Join);
3348 SkMatrix rotator;
3349 rotator.setRotate(30, 128, 128);
3350 for (auto color : { SK_ColorRED, SK_ColorBLUE, SK_ColorYELLOW, SK_ColorMAGENTA } ) {
3351 paint.setColor(color);
3352 SkRect rect;
3353 rect.set(rectPts[0], rectPts[1]);
3354 canvas->drawRect(rect, paint);
3355 rotator.mapPoints(rectPts, 2);
3356 }
Cary Clark8032b982017-07-28 11:04:54 -04003357}
3358##
3359
3360#ToDo incomplete ##
3361
3362##
3363
3364# ------------------------------------------------------------------------------
3365
3366#Method void drawIRect(const SkIRect& rect, const SkPaint& paint)
3367
3368Draw IRect rect using Clip, Matrix, and Paint paint.
3369In paint: Paint_Style determines if rectangle is stroked or filled;
3370if stroked, Paint_Stroke_Width describes the line thickness, and
3371Paint_Stroke_Join draws the corners rounded or square.
3372
Cary Clarkbc5697d2017-10-04 14:31:33 -04003373#Param rect rectangle to draw ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003374#Param paint stroke or fill, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003375
3376#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003377 SkIRect rect = { 64, 48, 192, 160 };
3378 SkPaint paint;
3379 paint.setAntiAlias(true);
3380 paint.setStyle(SkPaint::kStroke_Style);
3381 paint.setStrokeWidth(20);
3382 paint.setStrokeJoin(SkPaint::kRound_Join);
3383 for (auto color : { SK_ColorRED, SK_ColorBLUE, SK_ColorYELLOW, SK_ColorMAGENTA } ) {
3384 paint.setColor(color);
3385 canvas->drawIRect(rect, paint);
3386 canvas->rotate(30, 128, 128);
3387 }
Cary Clark8032b982017-07-28 11:04:54 -04003388##
3389
3390#ToDo incomplete ##
3391
3392##
3393
3394# ------------------------------------------------------------------------------
3395
3396#Method void drawRegion(const SkRegion& region, const SkPaint& paint)
3397
3398Draw Region region using Clip, Matrix, and Paint paint.
3399In paint: Paint_Style determines if rectangle is stroked or filled;
3400if stroked, Paint_Stroke_Width describes the line thickness, and
3401Paint_Stroke_Join draws the corners rounded or square.
3402
Cary Clarkbc5697d2017-10-04 14:31:33 -04003403#Param region region to draw ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003404#Param paint Paint stroke or fill, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003405
3406#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003407void draw(SkCanvas* canvas) {
3408 SkRegion region;
3409 region.op( 10, 10, 50, 50, SkRegion::kUnion_Op);
3410 region.op( 10, 50, 90, 90, SkRegion::kUnion_Op);
3411 SkPaint paint;
3412 paint.setAntiAlias(true);
3413 paint.setStyle(SkPaint::kStroke_Style);
3414 paint.setStrokeWidth(20);
3415 paint.setStrokeJoin(SkPaint::kRound_Join);
3416 canvas->drawRegion(region, paint);
Cary Clark8032b982017-07-28 11:04:54 -04003417}
3418##
3419
3420#ToDo incomplete ##
3421
3422##
3423
3424# ------------------------------------------------------------------------------
3425
3426#Method void drawOval(const SkRect& oval, const SkPaint& paint)
3427
3428Draw Oval oval using Clip, Matrix, and Paint.
3429In paint: Paint_Style determines if Oval is stroked or filled;
3430if stroked, Paint_Stroke_Width describes the line thickness.
3431
Cary Clarkbad5ad72017-08-03 17:14:08 -04003432#Param oval Rect bounds of Oval ##
3433#Param paint Paint stroke or fill, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003434
3435#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003436void draw(SkCanvas* canvas) {
3437 canvas->clear(0xFF3f5f9f);
3438 SkColor kColor1 = SkColorSetARGB(0xff, 0xff, 0x7f, 0);
3439 SkColor g1Colors[] = { kColor1, SkColorSetA(kColor1, 0x20) };
3440 SkPoint g1Points[] = { { 0, 0 }, { 0, 100 } };
3441 SkScalar pos[] = { 0.2f, 1.0f };
3442 SkRect bounds = SkRect::MakeWH(80, 70);
3443 SkPaint paint;
3444 paint.setAntiAlias(true);
3445 paint.setShader(SkGradientShader::MakeLinear(g1Points, g1Colors, pos, SK_ARRAY_COUNT(g1Colors),
3446 SkShader::kClamp_TileMode));
3447 canvas->drawOval(bounds , paint);
Cary Clark8032b982017-07-28 11:04:54 -04003448}
3449##
3450
3451#ToDo incomplete ##
3452
3453##
3454
3455# ------------------------------------------------------------------------------
3456
3457#Method void drawRRect(const SkRRect& rrect, const SkPaint& paint)
3458
3459Draw Round_Rect rrect using Clip, Matrix, and Paint paint.
3460In paint: Paint_Style determines if rrect is stroked or filled;
3461if stroked, Paint_Stroke_Width describes the line thickness.
3462
Cary Clarkbad5ad72017-08-03 17:14:08 -04003463rrect may represent a rectangle, circle, oval, uniformly rounded rectangle, or
3464may have any combination of positive non-square radii for the four corners.
Cary Clark8032b982017-07-28 11:04:54 -04003465
Cary Clarkbad5ad72017-08-03 17:14:08 -04003466#Param rrect Round_Rect with up to eight corner radii to draw ##
3467#Param paint Paint stroke or fill, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003468
3469#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003470void draw(SkCanvas* canvas) {
3471 SkPaint paint;
3472 paint.setAntiAlias(true);
3473 SkRect outer = {30, 40, 210, 220};
3474 SkRect radii = {30, 50, 70, 90 };
3475 SkRRect rRect;
3476 rRect.setNinePatch(outer, radii.fLeft, radii.fTop, radii.fRight, radii.fBottom);
3477 canvas->drawRRect(rRect, paint);
3478 paint.setColor(SK_ColorWHITE);
3479 canvas->drawLine(outer.fLeft + radii.fLeft, outer.fTop,
3480 outer.fLeft + radii.fLeft, outer.fBottom, paint);
3481 canvas->drawLine(outer.fRight - radii.fRight, outer.fTop,
3482 outer.fRight - radii.fRight, outer.fBottom, paint);
3483 canvas->drawLine(outer.fLeft, outer.fTop + radii.fTop,
3484 outer.fRight, outer.fTop + radii.fTop, paint);
3485 canvas->drawLine(outer.fLeft, outer.fBottom - radii.fBottom,
3486 outer.fRight, outer.fBottom - radii.fBottom, paint);
3487}
Cary Clark8032b982017-07-28 11:04:54 -04003488##
3489
3490#ToDo incomplete ##
3491
3492##
3493
3494# ------------------------------------------------------------------------------
3495
3496#Method void drawDRRect(const SkRRect& outer, const SkRRect& inner, const SkPaint& paint)
3497
3498Draw Round_Rect outer and inner
3499using Clip, Matrix, and Paint paint.
3500outer must contain inner or the drawing is undefined.
Cary Clarkce101242017-09-01 15:51:02 -04003501In paint: Paint_Style determines if Round_Rect is stroked or filled;
Cary Clark8032b982017-07-28 11:04:54 -04003502if stroked, Paint_Stroke_Width describes the line thickness.
Cary Clarkbad5ad72017-08-03 17:14:08 -04003503If stroked and Round_Rect corner has zero length radii, Paint_Stroke_Join can
3504draw corners rounded or square.
Cary Clark8032b982017-07-28 11:04:54 -04003505
Cary Clarkbad5ad72017-08-03 17:14:08 -04003506GPU-backed platforms optimize drawing when both outer and inner are
Cary Clark8032b982017-07-28 11:04:54 -04003507concave and outer contains inner. These platforms may not be able to draw
3508Path built with identical data as fast.
3509
Cary Clarkbad5ad72017-08-03 17:14:08 -04003510#Param outer Round_Rect outer bounds to draw ##
3511#Param inner Round_Rect inner bounds to draw ##
3512#Param paint Paint stroke or fill, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003513
3514#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003515void draw(SkCanvas* canvas) {
3516 SkRRect outer = SkRRect::MakeRect({20, 40, 210, 200});
3517 SkRRect inner = SkRRect::MakeOval({60, 70, 170, 160});
3518 SkPaint paint;
3519 canvas->drawDRRect(outer, inner, paint);
Cary Clark8032b982017-07-28 11:04:54 -04003520}
3521##
3522
3523#Example
3524#Description
3525 Outer Rect has no corner radii, but stroke join is rounded.
3526 Inner Round_Rect has corner radii; outset stroke increases radii of corners.
3527 Stroke join does not affect inner Round_Rect since it has no sharp corners.
3528##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003529void draw(SkCanvas* canvas) {
3530 SkRRect outer = SkRRect::MakeRect({20, 40, 210, 200});
3531 SkRRect inner = SkRRect::MakeRectXY({60, 70, 170, 160}, 10, 10);
3532 SkPaint paint;
3533 paint.setAntiAlias(true);
3534 paint.setStyle(SkPaint::kStroke_Style);
3535 paint.setStrokeWidth(20);
3536 paint.setStrokeJoin(SkPaint::kRound_Join);
3537 canvas->drawDRRect(outer, inner, paint);
3538 paint.setStrokeWidth(1);
3539 paint.setColor(SK_ColorWHITE);
3540 canvas->drawDRRect(outer, inner, paint);
Cary Clark8032b982017-07-28 11:04:54 -04003541}
3542##
3543
3544#ToDo incomplete ##
3545
3546##
3547
3548# ------------------------------------------------------------------------------
3549
3550#Method void drawCircle(SkScalar cx, SkScalar cy, SkScalar radius, const SkPaint& paint)
3551
3552Draw Circle at (cx, cy) with radius using Clip, Matrix, and Paint paint.
3553If radius is zero or less, nothing is drawn.
3554In paint: Paint_Style determines if Circle is stroked or filled;
3555if stroked, Paint_Stroke_Width describes the line thickness.
3556
Cary Clarkbad5ad72017-08-03 17:14:08 -04003557#Param cx Circle center on the x-axis ##
3558#Param cy Circle center on the y-axis ##
3559#Param radius half the diameter of Circle ##
3560#Param paint Paint stroke or fill, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003561
3562#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003563 void draw(SkCanvas* canvas) {
3564 SkPaint paint;
3565 paint.setAntiAlias(true);
3566 canvas->drawCircle(128, 128, 90, paint);
3567 paint.setColor(SK_ColorWHITE);
3568 canvas->drawCircle(86, 86, 20, paint);
3569 canvas->drawCircle(160, 76, 20, paint);
3570 canvas->drawCircle(140, 150, 35, paint);
3571 }
3572##
3573
3574#ToDo incomplete ##
3575
3576##
3577
3578#Method void drawCircle(SkPoint center, SkScalar radius, const SkPaint& paint)
3579
Cary Clarkce101242017-09-01 15:51:02 -04003580Draw Circle at center with radius using Clip, Matrix, and Paint paint.
Cary Clarkbad5ad72017-08-03 17:14:08 -04003581If radius is zero or less, nothing is drawn.
3582In paint: Paint_Style determines if Circle is stroked or filled;
3583if stroked, Paint_Stroke_Width describes the line thickness.
3584
3585#Param center Circle center ##
3586#Param radius half the diameter of Circle ##
3587#Param paint Paint stroke or fill, blend, color, and so on, used to draw ##
3588
3589#Example
3590 void draw(SkCanvas* canvas) {
3591 SkPaint paint;
3592 paint.setAntiAlias(true);
3593 canvas->drawCircle(128, 128, 90, paint);
3594 paint.setColor(SK_ColorWHITE);
3595 canvas->drawCircle({86, 86}, 20, paint);
3596 canvas->drawCircle({160, 76}, 20, paint);
3597 canvas->drawCircle({140, 150}, 35, paint);
3598 }
Cary Clark8032b982017-07-28 11:04:54 -04003599##
3600
3601#ToDo incomplete ##
3602
3603##
3604
3605# ------------------------------------------------------------------------------
3606
3607#Method void drawArc(const SkRect& oval, SkScalar startAngle, SkScalar sweepAngle,
3608 bool useCenter, const SkPaint& paint)
3609
3610Draw Arc using Clip, Matrix, and Paint paint.
Cary Clarkbad5ad72017-08-03 17:14:08 -04003611
Cary Clark8032b982017-07-28 11:04:54 -04003612Arc is part of Oval bounded by oval, sweeping from startAngle to startAngle plus
3613sweepAngle. startAngle and sweepAngle are in degrees.
Cary Clarkbad5ad72017-08-03 17:14:08 -04003614
Cary Clark8032b982017-07-28 11:04:54 -04003615startAngle of zero places start point at the right middle edge of oval.
3616A positive sweepAngle places Arc end point clockwise from start point;
3617a negative sweepAngle places Arc end point counterclockwise from start point.
3618sweepAngle may exceed 360 degrees, a full circle.
3619If useCenter is true, draw a wedge that includes lines from oval
3620center to Arc end points. If useCenter is false, draw Arc between end points.
3621
3622If Rect oval is empty or sweepAngle is zero, nothing is drawn.
3623
Cary Clarkbad5ad72017-08-03 17:14:08 -04003624#Param oval Rect bounds of Oval containing Arc to draw ##
3625#Param startAngle angle in degrees where Arc begins ##
3626#Param sweepAngle sweep angle in degrees; positive is clockwise ##
3627#Param useCenter if true, include the center of the oval ##
3628#Param paint Paint stroke or fill, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003629
3630#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003631 void draw(SkCanvas* canvas) {
3632 SkPaint paint;
3633 paint.setAntiAlias(true);
3634 SkRect oval = { 4, 4, 60, 60};
3635 for (auto useCenter : { false, true } ) {
3636 for (auto style : { SkPaint::kFill_Style, SkPaint::kStroke_Style } ) {
3637 paint.setStyle(style);
3638 for (auto degrees : { 45, 90, 180, 360} ) {
3639 canvas->drawArc(oval, 0, degrees , useCenter, paint);
3640 canvas->translate(64, 0);
3641 }
3642 canvas->translate(-256, 64);
3643 }
3644 }
Cary Clark8032b982017-07-28 11:04:54 -04003645 }
3646##
3647
3648#Example
3649#Height 64
Cary Clarkbad5ad72017-08-03 17:14:08 -04003650 void draw(SkCanvas* canvas) {
3651 SkPaint paint;
3652 paint.setAntiAlias(true);
3653 paint.setStyle(SkPaint::kStroke_Style);
3654 paint.setStrokeWidth(4);
3655 SkRect oval = { 4, 4, 60, 60};
3656 float intervals[] = { 5, 5 };
3657 paint.setPathEffect(SkDashPathEffect::Make(intervals, 2, 2.5f));
3658 for (auto degrees : { 270, 360, 540, 720 } ) {
3659 canvas->drawArc(oval, 0, degrees, false, paint);
3660 canvas->translate(64, 0);
3661 }
Cary Clark8032b982017-07-28 11:04:54 -04003662 }
3663##
3664
3665#ToDo incomplete ##
3666
3667##
3668
3669# ------------------------------------------------------------------------------
3670
3671#Method void drawRoundRect(const SkRect& rect, SkScalar rx, SkScalar ry, const SkPaint& paint)
3672
Cary Clarkbad5ad72017-08-03 17:14:08 -04003673Draw Round_Rect bounded by Rect rect, with corner radii (rx, ry) using Clip,
3674Matrix, and Paint paint.
3675
Cary Clark8032b982017-07-28 11:04:54 -04003676In paint: Paint_Style determines if Round_Rect is stroked or filled;
3677if stroked, Paint_Stroke_Width describes the line thickness.
3678If rx or ry are less than zero, they are treated as if they are zero.
3679If rx plus ry exceeds rect width or rect height, radii are scaled down to fit.
Cary Clarkbad5ad72017-08-03 17:14:08 -04003680If rx and ry are zero, Round_Rect is drawn as Rect and if stroked is affected by
3681Paint_Stroke_Join.
Cary Clark8032b982017-07-28 11:04:54 -04003682
Cary Clarkbad5ad72017-08-03 17:14:08 -04003683#Param rect Rect bounds of Round_Rect to draw ##
Cary Clarkce101242017-09-01 15:51:02 -04003684#Param rx axis length in x of oval describing rounded corners ##
3685#Param ry axis length in y of oval describing rounded corners ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003686#Param paint stroke, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003687
3688#Example
3689#Description
3690 Top row has a zero radius a generates a rectangle.
3691 Second row radii sum to less than sides.
3692 Third row radii sum equals sides.
3693 Fourth row radii sum exceeds sides; radii are scaled to fit.
3694##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003695 void draw(SkCanvas* canvas) {
3696 SkVector radii[] = { {0, 20}, {10, 10}, {10, 20}, {10, 40} };
3697 SkPaint paint;
3698 paint.setStrokeWidth(15);
3699 paint.setStrokeJoin(SkPaint::kRound_Join);
3700 paint.setAntiAlias(true);
3701 for (auto style : { SkPaint::kStroke_Style, SkPaint::kFill_Style } ) {
3702 paint.setStyle(style );
3703 for (size_t i = 0; i < SK_ARRAY_COUNT(radii); ++i) {
3704 canvas->drawRoundRect({10, 10, 60, 40}, radii[i].fX, radii[i].fY, paint);
3705 canvas->translate(0, 60);
3706 }
3707 canvas->translate(80, -240);
3708 }
Cary Clark8032b982017-07-28 11:04:54 -04003709 }
3710##
3711
3712#ToDo incomplete ##
3713
3714##
3715
3716# ------------------------------------------------------------------------------
3717
3718#Method void drawPath(const SkPath& path, const SkPaint& paint)
3719
3720Draw Path path using Clip, Matrix, and Paint paint.
3721Path contains an array of Path_Contour, each of which may be open or closed.
3722
3723In paint: Paint_Style determines if Round_Rect is stroked or filled:
Cary Clarkbad5ad72017-08-03 17:14:08 -04003724if filled, Path_Fill_Type determines whether Path_Contour describes inside or
3725outside of fill; if stroked, Paint_Stroke_Width describes the line thickness,
3726Paint_Stroke_Cap describes line ends, and Paint_Stroke_Join describes how
3727corners are drawn.
Cary Clark8032b982017-07-28 11:04:54 -04003728
Cary Clarkbad5ad72017-08-03 17:14:08 -04003729#Param path Path to draw ##
3730#Param paint stroke, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003731
3732#Example
3733#Description
3734 Top rows draw stroked path with combinations of joins and caps. The open contour
3735 is affected by caps; the closed contour is affected by joins.
3736 Bottom row draws fill the same for open and closed contour.
3737 First bottom column shows winding fills overlap.
3738 Second bottom column shows even odd fills exclude overlap.
3739 Third bottom column shows inverse winding fills area outside both contours.
3740##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003741void draw(SkCanvas* canvas) {
3742 SkPath path;
3743 path.moveTo(20, 20);
3744 path.quadTo(60, 20, 60, 60);
3745 path.close();
3746 path.moveTo(60, 20);
3747 path.quadTo(60, 60, 20, 60);
3748 SkPaint paint;
3749 paint.setStrokeWidth(10);
3750 paint.setAntiAlias(true);
3751 paint.setStyle(SkPaint::kStroke_Style);
3752 for (auto join: { SkPaint::kBevel_Join, SkPaint::kRound_Join, SkPaint::kMiter_Join } ) {
3753 paint.setStrokeJoin(join);
3754 for (auto cap: { SkPaint::kButt_Cap, SkPaint::kSquare_Cap, SkPaint::kRound_Cap } ) {
3755 paint.setStrokeCap(cap);
3756 canvas->drawPath(path, paint);
3757 canvas->translate(80, 0);
3758 }
3759 canvas->translate(-240, 60);
3760 }
3761 paint.setStyle(SkPaint::kFill_Style);
3762 for (auto fill : { SkPath::kWinding_FillType,
3763 SkPath::kEvenOdd_FillType,
3764 SkPath::kInverseWinding_FillType } ) {
3765 path.setFillType(fill);
3766 canvas->save();
3767 canvas->clipRect({0, 10, 80, 70});
3768 canvas->drawPath(path, paint);
3769 canvas->restore();
3770 canvas->translate(80, 0);
3771 }
Cary Clark8032b982017-07-28 11:04:54 -04003772}
3773##
3774
3775#ToDo incomplete ##
3776
3777##
3778
3779# ------------------------------------------------------------------------------
3780#Topic Draw_Image
3781
Cary Clarkbad5ad72017-08-03 17:14:08 -04003782drawImage, drawImageRect, and drawImageNine can be called with a bare pointer or
3783a smart pointer as a convenience. The pairs of calls are otherwise identical.
Cary Clark8032b982017-07-28 11:04:54 -04003784
Cary Clark73fa9722017-08-29 17:36:51 -04003785#Method void drawImage(const SkImage* image, SkScalar left, SkScalar top, const SkPaint* paint = nullptr)
Cary Clark8032b982017-07-28 11:04:54 -04003786
3787Draw Image image, with its top-left corner at (left, top),
3788using Clip, Matrix, and optional Paint paint.
3789
Cary Clarkbad5ad72017-08-03 17:14:08 -04003790If paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter, Blend_Mode,
3791and Draw_Looper. If image is kAlpha_8_SkColorType, apply Shader.
3792If paint contains Mask_Filter, generate mask from image bounds. If generated
3793mask extends beyond image bounds, replicate image edge colors, just as Shader
3794made from SkImage::makeShader with SkShader::kClamp_TileMode set replicates the
Cary Clarkbc5697d2017-10-04 14:31:33 -04003795image edge color when it samples outside of its bounds.
Cary Clark8032b982017-07-28 11:04:54 -04003796
Cary Clarkbad5ad72017-08-03 17:14:08 -04003797#Param image uncompressed rectangular map of pixels ##
3798#Param left left side of image ##
3799#Param top top side of image ##
3800#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
3801 and so on; or nullptr
3802##
Cary Clark8032b982017-07-28 11:04:54 -04003803
3804#Example
3805#Height 64
3806#Image 4
Cary Clarkbad5ad72017-08-03 17:14:08 -04003807void draw(SkCanvas* canvas) {
3808 // sk_sp<SkImage> image;
3809 SkImage* imagePtr = image.get();
3810 canvas->drawImage(imagePtr, 0, 0);
3811 SkPaint paint;
3812 canvas->drawImage(imagePtr, 80, 0, &paint);
3813 paint.setAlpha(0x80);
3814 canvas->drawImage(imagePtr, 160, 0, &paint);
Cary Clark8032b982017-07-28 11:04:54 -04003815}
3816##
3817
3818#ToDo incomplete ##
3819
3820##
3821
3822# ------------------------------------------------------------------------------
3823
3824#Method void drawImage(const sk_sp<SkImage>& image, SkScalar left, SkScalar top,
Cary Clark73fa9722017-08-29 17:36:51 -04003825 const SkPaint* paint = nullptr)
Cary Clark8032b982017-07-28 11:04:54 -04003826
3827Draw Image image, with its top-left corner at (left, top),
3828using Clip, Matrix, and optional Paint paint.
3829
Cary Clarkbad5ad72017-08-03 17:14:08 -04003830If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
3831Blend_Mode, and Draw_Looper. If image is kAlpha_8_SkColorType, apply Shader.
3832If paint contains Mask_Filter, generate mask from image bounds. If generated
3833mask extends beyond image bounds, replicate image edge colors, just as Shader
3834made from SkImage::makeShader with SkShader::kClamp_TileMode set replicates the
Cary Clarkbc5697d2017-10-04 14:31:33 -04003835image edge color when it samples outside of its bounds.
Cary Clark8032b982017-07-28 11:04:54 -04003836
Cary Clarkbad5ad72017-08-03 17:14:08 -04003837#Param image uncompressed rectangular map of pixels ##
3838#Param left left side of image ##
3839#Param top pop side of image ##
3840#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
3841 and so on; or nullptr
3842##
Cary Clark8032b982017-07-28 11:04:54 -04003843
3844#Example
3845#Height 64
3846#Image 4
Cary Clarkbad5ad72017-08-03 17:14:08 -04003847void draw(SkCanvas* canvas) {
3848 // sk_sp<SkImage> image;
3849 canvas->drawImage(image, 0, 0);
3850 SkPaint paint;
3851 canvas->drawImage(image, 80, 0, &paint);
3852 paint.setAlpha(0x80);
3853 canvas->drawImage(image, 160, 0, &paint);
Cary Clark8032b982017-07-28 11:04:54 -04003854}
3855##
3856
3857#ToDo incomplete ##
3858
3859##
3860
3861# ------------------------------------------------------------------------------
3862
3863#Enum SrcRectConstraint
3864
3865#Code
3866 enum SrcRectConstraint {
3867 kStrict_SrcRectConstraint,
3868 kFast_SrcRectConstraint,
3869 };
3870##
3871
Cary Clarkce101242017-09-01 15:51:02 -04003872SrcRectConstraint controls the behavior at the edge of source Rect,
3873provided to drawImageRect, trading off speed for precision.
Cary Clark8032b982017-07-28 11:04:54 -04003874
Cary Clarkce101242017-09-01 15:51:02 -04003875Image_Filter in Paint may sample multiple pixels in the image. Source Rect
Cary Clarkbad5ad72017-08-03 17:14:08 -04003876restricts the bounds of pixels that may be read. Image_Filter may slow down if
Cary Clarkce101242017-09-01 15:51:02 -04003877it cannot read outside the bounds, when sampling near the edge of source Rect.
Cary Clark8032b982017-07-28 11:04:54 -04003878SrcRectConstraint specifies whether an Image_Filter is allowed to read pixels
Cary Clarkce101242017-09-01 15:51:02 -04003879outside source Rect.
Cary Clark8032b982017-07-28 11:04:54 -04003880
3881#Const kStrict_SrcRectConstraint
Cary Clarkce101242017-09-01 15:51:02 -04003882 Requires Image_Filter to respect source Rect,
Cary Clark8032b982017-07-28 11:04:54 -04003883 sampling only inside of its bounds, possibly with a performance penalty.
3884##
3885
3886#Const kFast_SrcRectConstraint
Cary Clarkce101242017-09-01 15:51:02 -04003887 Permits Image_Filter to sample outside of source Rect
Cary Clark8032b982017-07-28 11:04:54 -04003888 by half the width of Image_Filter, permitting it to run faster but with
3889 error at the image edges.
3890##
3891
3892#Example
3893#Height 64
3894#Description
3895 redBorder contains a black and white checkerboard bordered by red.
3896 redBorder is drawn scaled by 16 on the left.
Cary Clarkce101242017-09-01 15:51:02 -04003897 The middle and right bitmaps are filtered checkerboards.
Cary Clark8032b982017-07-28 11:04:54 -04003898 Drawing the checkerboard with kStrict_SrcRectConstraint shows only a blur of black and white.
3899 Drawing the checkerboard with kFast_SrcRectConstraint allows red to bleed in the corners.
3900##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003901void draw(SkCanvas* canvas) {
3902 SkBitmap redBorder;
3903 redBorder.allocPixels(SkImageInfo::MakeN32Premul(4, 4));
3904 SkCanvas checkRed(redBorder);
3905 checkRed.clear(SK_ColorRED);
3906 uint32_t checkers[][2] = { { SK_ColorBLACK, SK_ColorWHITE },
3907 { SK_ColorWHITE, SK_ColorBLACK } };
3908 checkRed.writePixels(
3909 SkImageInfo::MakeN32Premul(2, 2), (void*) checkers, sizeof(checkers[0]), 1, 1);
3910 canvas->scale(16, 16);
3911 canvas->drawBitmap(redBorder, 0, 0, nullptr);
3912 canvas->resetMatrix();
3913 sk_sp<SkImage> image = SkImage::MakeFromBitmap(redBorder);
3914 SkPaint lowPaint;
3915 lowPaint.setFilterQuality(kLow_SkFilterQuality);
3916 for (auto constraint : { SkCanvas::kStrict_SrcRectConstraint,
3917 SkCanvas::kFast_SrcRectConstraint } ) {
3918 canvas->translate(80, 0);
3919 canvas->drawImageRect(image.get(), SkRect::MakeLTRB(1, 1, 3, 3),
3920 SkRect::MakeLTRB(16, 16, 48, 48), &lowPaint, constraint);
3921 }
Cary Clark8032b982017-07-28 11:04:54 -04003922}
3923##
3924
3925#ToDo incomplete ##
3926
3927##
3928
3929# ------------------------------------------------------------------------------
3930
3931#Method void drawImageRect(const SkImage* image, const SkRect& src, const SkRect& dst,
3932 const SkPaint* paint,
3933 SrcRectConstraint constraint = kStrict_SrcRectConstraint)
3934
3935Draw Rect src of Image image, scaled and translated to fill Rect dst.
3936Additionally transform draw using Clip, Matrix, and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04003937
Cary Clarkbad5ad72017-08-03 17:14:08 -04003938If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
3939Blend_Mode, and Draw_Looper. If image is kAlpha_8_SkColorType, apply Shader.
3940If paint contains Mask_Filter, generate mask from image bounds.
3941
3942If generated mask extends beyond image bounds, replicate image edge colors, just
3943as Shader made from SkImage::makeShader with SkShader::kClamp_TileMode set
Cary Clarkbc5697d2017-10-04 14:31:33 -04003944replicates the image edge color when it samples outside of its bounds.
Cary Clarkbad5ad72017-08-03 17:14:08 -04003945
3946constraint set to kStrict_SrcRectConstraint limits Paint Filter_Quality to
3947sample within src; set to kFast_SrcRectConstraint allows sampling outside to
3948improve performance.
3949
3950#Param image Image containing pixels, dimensions, and format ##
3951#Param src source Rect of image to draw from ##
3952#Param dst destination Rect of image to draw to ##
3953#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
3954 and so on; or nullptr
3955##
3956#Param constraint filter strictly within src or draw faster ##
Cary Clark8032b982017-07-28 11:04:54 -04003957
3958#Example
3959#Height 64
3960#Description
3961 The left bitmap draws with Paint default kNone_SkFilterQuality, and stays within
Cary Clarkbc5697d2017-10-04 14:31:33 -04003962 its bounds; there is no bleeding with kFast_SrcRectConstraint.
Cary Clark8032b982017-07-28 11:04:54 -04003963 the middle and right bitmaps draw with kLow_SkFilterQuality; with
3964 kStrict_SrcRectConstraint, the filter remains within the checkerboard, and
3965 with kFast_SrcRectConstraint red bleeds on the edges.
3966##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003967void draw(SkCanvas* canvas) {
3968 uint32_t pixels[][4] = {
3969 { 0xFFFF0000, 0xFFFF0000, 0xFFFF0000, 0xFFFF0000 },
3970 { 0xFFFF0000, 0xFF000000, 0xFFFFFFFF, 0xFFFF0000 },
3971 { 0xFFFF0000, 0xFFFFFFFF, 0xFF000000, 0xFFFF0000 },
3972 { 0xFFFF0000, 0xFFFF0000, 0xFFFF0000, 0xFFFF0000 } };
3973 SkBitmap redBorder;
3974 redBorder.installPixels(SkImageInfo::MakeN32Premul(4, 4),
3975 (void*) pixels, sizeof(pixels[0]));
3976 sk_sp<SkImage> image = SkImage::MakeFromBitmap(redBorder);
3977 SkPaint lowPaint;
3978 for (auto constraint : {
3979 SkCanvas::kFast_SrcRectConstraint,
3980 SkCanvas::kStrict_SrcRectConstraint,
3981 SkCanvas::kFast_SrcRectConstraint } ) {
3982 canvas->drawImageRect(image.get(), SkRect::MakeLTRB(1, 1, 3, 3),
3983 SkRect::MakeLTRB(16, 16, 48, 48), &lowPaint, constraint);
3984 lowPaint.setFilterQuality(kLow_SkFilterQuality);
3985 canvas->translate(80, 0);
3986 }
3987}
Cary Clark8032b982017-07-28 11:04:54 -04003988##
3989
3990#ToDo incomplete ##
3991
3992##
3993
3994# ------------------------------------------------------------------------------
3995
3996#Method void drawImageRect(const SkImage* image, const SkIRect& isrc, const SkRect& dst,
3997 const SkPaint* paint, SrcRectConstraint constraint = kStrict_SrcRectConstraint)
3998
3999Draw IRect isrc of Image image, scaled and translated to fill Rect dst.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004000Note that isrc is on integer pixel boundaries; dst may include fractional
4001boundaries. Additionally transform draw using Clip, Matrix, and optional Paint
4002paint.
Cary Clark8032b982017-07-28 11:04:54 -04004003
Cary Clarkbad5ad72017-08-03 17:14:08 -04004004If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4005Blend_Mode, and Draw_Looper. If image is kAlpha_8_SkColorType, apply Shader.
4006If paint contains Mask_Filter, generate mask from image bounds.
4007
4008If generated mask extends beyond image bounds, replicate image edge colors, just
4009as Shader made from SkImage::makeShader with SkShader::kClamp_TileMode set
Cary Clarkbc5697d2017-10-04 14:31:33 -04004010replicates the image edge color when it samples outside of its bounds.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004011
4012constraint set to kStrict_SrcRectConstraint limits Paint Filter_Quality to
Cary Clarkce101242017-09-01 15:51:02 -04004013sample within isrc; set to kFast_SrcRectConstraint allows sampling outside to
Cary Clarkbad5ad72017-08-03 17:14:08 -04004014improve performance.
4015
4016#Param image Image containing pixels, dimensions, and format ##
4017#Param isrc source IRect of image to draw from ##
4018#Param dst destination Rect of image to draw to ##
4019#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4020 and so on; or nullptr
4021##
Cary Clarkce101242017-09-01 15:51:02 -04004022#Param constraint filter strictly within isrc or draw faster ##
Cary Clark8032b982017-07-28 11:04:54 -04004023
4024#Example
4025#Image 4
Cary Clarkbad5ad72017-08-03 17:14:08 -04004026void draw(SkCanvas* canvas) {
4027 // sk_sp<SkImage> image;
4028 for (auto i : { 1, 2, 4, 8 } ) {
4029 canvas->drawImageRect(image.get(), SkIRect::MakeLTRB(0, 0, 100, 100),
4030 SkRect::MakeXYWH(i * 20, i * 20, i * 20, i * 20), nullptr);
4031 }
Cary Clark8032b982017-07-28 11:04:54 -04004032}
4033##
4034
4035#ToDo incomplete ##
4036
4037##
4038
4039# ------------------------------------------------------------------------------
4040
4041#Method void drawImageRect(const SkImage* image, const SkRect& dst, const SkPaint* paint,
4042 SrcRectConstraint constraint = kStrict_SrcRectConstraint)
4043
Cary Clarkbad5ad72017-08-03 17:14:08 -04004044Draw Image image, scaled and translated to fill Rect dst, using Clip, Matrix,
4045and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004046
Cary Clarkbad5ad72017-08-03 17:14:08 -04004047If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4048Blend_Mode, and Draw_Looper. If image is kAlpha_8_SkColorType, apply Shader.
4049If paint contains Mask_Filter, generate mask from image bounds.
4050
4051If generated mask extends beyond image bounds, replicate image edge colors, just
4052as Shader made from SkImage::makeShader with SkShader::kClamp_TileMode set
Cary Clarkbc5697d2017-10-04 14:31:33 -04004053replicates the image edge color when it samples outside of its bounds.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004054
4055constraint set to kStrict_SrcRectConstraint limits Paint Filter_Quality to
Cary Clarkce101242017-09-01 15:51:02 -04004056sample within image; set to kFast_SrcRectConstraint allows sampling outside to
Cary Clarkbad5ad72017-08-03 17:14:08 -04004057improve performance.
4058
4059#Param image Image containing pixels, dimensions, and format ##
4060#Param dst destination Rect of image to draw to ##
4061#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4062 and so on; or nullptr
4063##
Cary Clarkce101242017-09-01 15:51:02 -04004064#Param constraint filter strictly within image or draw faster ##
Cary Clark8032b982017-07-28 11:04:54 -04004065
4066#Example
4067#Image 4
Cary Clarkbad5ad72017-08-03 17:14:08 -04004068void draw(SkCanvas* canvas) {
4069 // sk_sp<SkImage> image;
4070 for (auto i : { 20, 40, 80, 160 } ) {
4071 canvas->drawImageRect(image.get(), SkRect::MakeXYWH(i, i, i, i), nullptr);
4072 }
Cary Clark8032b982017-07-28 11:04:54 -04004073}
4074##
4075
4076#ToDo incomplete ##
4077
4078##
4079
4080# ------------------------------------------------------------------------------
4081
4082#Method void drawImageRect(const sk_sp<SkImage>& image, const SkRect& src, const SkRect& dst,
4083 const SkPaint* paint,
4084 SrcRectConstraint constraint = kStrict_SrcRectConstraint)
4085
4086Draw Rect src of Image image, scaled and translated to fill Rect dst.
4087Additionally transform draw using Clip, Matrix, and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004088
Cary Clarkbad5ad72017-08-03 17:14:08 -04004089If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4090Blend_Mode, and Draw_Looper. If image is kAlpha_8_SkColorType, apply Shader.
4091If paint contains Mask_Filter, generate mask from image bounds.
4092
4093If generated mask extends beyond image bounds, replicate image edge colors, just
4094as Shader made from SkImage::makeShader with SkShader::kClamp_TileMode set
Cary Clarkbc5697d2017-10-04 14:31:33 -04004095replicates the image edge color when it samples outside of its bounds.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004096
4097constraint set to kStrict_SrcRectConstraint limits Paint Filter_Quality to
4098sample within src; set to kFast_SrcRectConstraint allows sampling outside to
4099improve performance.
4100
4101#Param image Image containing pixels, dimensions, and format ##
4102#Param src source Rect of image to draw from ##
4103#Param dst destination Rect of image to draw to ##
4104#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4105 and so on; or nullptr
4106##
4107#Param constraint filter strictly within src or draw faster ##
Cary Clark8032b982017-07-28 11:04:54 -04004108
4109#Example
4110#Height 64
4111#Description
4112 Canvas scales and translates; transformation from src to dst also scales.
4113 The two matrices are concatenated to create the final transformation.
4114##
Cary Clarkbad5ad72017-08-03 17:14:08 -04004115void draw(SkCanvas* canvas) {
4116 uint32_t pixels[][2] = { { SK_ColorBLACK, SK_ColorWHITE },
4117 { SK_ColorWHITE, SK_ColorBLACK } };
4118 SkBitmap bitmap;
4119 bitmap.installPixels(SkImageInfo::MakeN32Premul(2, 2),
4120 (void*) pixels, sizeof(pixels[0]));
4121 sk_sp<SkImage> image = SkImage::MakeFromBitmap(bitmap);
4122 SkPaint paint;
4123 canvas->scale(4, 4);
4124 for (auto alpha : { 50, 100, 150, 255 } ) {
4125 paint.setAlpha(alpha);
4126 canvas->drawImageRect(image, SkRect::MakeWH(2, 2), SkRect::MakeWH(8, 8), &paint);
4127 canvas->translate(8, 0);
4128 }
4129}
Cary Clark8032b982017-07-28 11:04:54 -04004130##
4131
4132#ToDo incomplete ##
4133
4134##
4135
4136# ------------------------------------------------------------------------------
4137
4138#Method void drawImageRect(const sk_sp<SkImage>& image, const SkIRect& isrc, const SkRect& dst,
4139 const SkPaint* paint, SrcRectConstraint constraint = kStrict_SrcRectConstraint)
4140
4141Draw IRect isrc of Image image, scaled and translated to fill Rect dst.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004142isrc is on integer pixel boundaries; dst may include fractional boundaries.
Cary Clark8032b982017-07-28 11:04:54 -04004143Additionally transform draw using Clip, Matrix, and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004144
Cary Clarkbad5ad72017-08-03 17:14:08 -04004145If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4146Blend_Mode, and Draw_Looper. If image is kAlpha_8_SkColorType, apply Shader.
4147If paint contains Mask_Filter, generate mask from image bounds.
4148
4149If generated mask extends beyond image bounds, replicate image edge colors, just
4150as Shader made from SkImage::makeShader with SkShader::kClamp_TileMode set
Cary Clarkbc5697d2017-10-04 14:31:33 -04004151replicates the image edge color when it samples outside of its bounds.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004152
4153constraint set to kStrict_SrcRectConstraint limits Paint Filter_Quality to
Cary Clarkce101242017-09-01 15:51:02 -04004154sample within image; set to kFast_SrcRectConstraint allows sampling outside to
Cary Clarkbad5ad72017-08-03 17:14:08 -04004155improve performance.
4156
4157#Param image Image containing pixels, dimensions, and format ##
4158#Param isrc source IRect of image to draw from ##
4159#Param dst destination Rect of image to draw to ##
4160#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4161 and so on; or nullptr
4162##
Cary Clarkce101242017-09-01 15:51:02 -04004163#Param constraint filter strictly within image or draw faster ##
Cary Clark8032b982017-07-28 11:04:54 -04004164
4165#Example
4166#Height 64
Cary Clarkbad5ad72017-08-03 17:14:08 -04004167void draw(SkCanvas* canvas) {
4168 uint32_t pixels[][2] = { { 0x00000000, 0x55555555},
4169 { 0xAAAAAAAA, 0xFFFFFFFF} };
4170 SkBitmap bitmap;
4171 bitmap.installPixels(SkImageInfo::MakeN32Premul(2, 2),
4172 (void*) pixels, sizeof(pixels[0]));
4173 sk_sp<SkImage> image = SkImage::MakeFromBitmap(bitmap);
4174 SkPaint paint;
4175 canvas->scale(4, 4);
4176 for (auto color : { SK_ColorRED, SK_ColorBLUE, SK_ColorGREEN } ) {
4177 paint.setColorFilter(SkColorFilter::MakeModeFilter(color, SkBlendMode::kPlus));
4178 canvas->drawImageRect(image, SkIRect::MakeWH(2, 2), SkRect::MakeWH(8, 8), &paint);
4179 canvas->translate(8, 0);
4180 }
Cary Clark8032b982017-07-28 11:04:54 -04004181}
4182##
4183
4184#ToDo incomplete ##
4185##
4186
4187# ------------------------------------------------------------------------------
4188
4189#Method void drawImageRect(const sk_sp<SkImage>& image, const SkRect& dst, const SkPaint* paint,
4190 SrcRectConstraint constraint = kStrict_SrcRectConstraint)
4191
4192Draw Image image, scaled and translated to fill Rect dst,
4193using Clip, Matrix, and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004194
Cary Clarkbad5ad72017-08-03 17:14:08 -04004195If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4196Blend_Mode, and Draw_Looper. If image is kAlpha_8_SkColorType, apply Shader.
4197If paint contains Mask_Filter, generate mask from image bounds.
4198
4199If generated mask extends beyond image bounds, replicate image edge colors, just
4200as Shader made from SkImage::makeShader with SkShader::kClamp_TileMode set
Cary Clarkbc5697d2017-10-04 14:31:33 -04004201replicates the image edge color when it samples outside of its bounds.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004202
4203constraint set to kStrict_SrcRectConstraint limits Paint Filter_Quality to
Cary Clarkce101242017-09-01 15:51:02 -04004204sample within image; set to kFast_SrcRectConstraint allows sampling outside to
Cary Clarkbad5ad72017-08-03 17:14:08 -04004205improve performance.
4206
4207#Param image Image containing pixels, dimensions, and format ##
4208#Param dst destination Rect of image to draw to ##
4209#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4210 and so on; or nullptr
4211##
Cary Clarkce101242017-09-01 15:51:02 -04004212#Param constraint filter strictly within image or draw faster ##
Cary Clark8032b982017-07-28 11:04:54 -04004213
4214#Example
4215#Height 64
Cary Clarkbad5ad72017-08-03 17:14:08 -04004216void draw(SkCanvas* canvas) {
4217 uint32_t pixels[][2] = { { 0x00000000, 0x55550000},
4218 { 0xAAAA0000, 0xFFFF0000} };
4219 SkBitmap bitmap;
4220 bitmap.installPixels(SkImageInfo::MakeN32Premul(2, 2),
4221 (void*) pixels, sizeof(pixels[0]));
4222 sk_sp<SkImage> image = SkImage::MakeFromBitmap(bitmap);
4223 SkPaint paint;
4224 canvas->scale(4, 4);
4225 for (auto color : { SK_ColorRED, SK_ColorBLUE, SK_ColorGREEN } ) {
4226 paint.setColorFilter(SkColorFilter::MakeModeFilter(color, SkBlendMode::kPlus));
4227 canvas->drawImageRect(image, SkRect::MakeWH(8, 8), &paint);
4228 canvas->translate(8, 0);
4229 }
Cary Clark8032b982017-07-28 11:04:54 -04004230}
4231##
4232
4233#ToDo incomplete ##
4234
4235##
4236
4237# ------------------------------------------------------------------------------
4238
4239#Method void drawImageNine(const SkImage* image, const SkIRect& center, const SkRect& dst,
4240 const SkPaint* paint = nullptr)
4241
Cary Clarkd0530ba2017-09-14 11:25:39 -04004242Draw Image image stretched proportionally to fit into Rect dst.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004243IRect center divides the image into nine sections: four sides, four corners, and
Cary Clarkce101242017-09-01 15:51:02 -04004244the center. Corners are unmodified or scaled down proportionately if their sides
Cary Clarkbad5ad72017-08-03 17:14:08 -04004245are larger than dst; center and four sides are scaled to fit remaining space, if any.
Cary Clark8032b982017-07-28 11:04:54 -04004246
Cary Clarkbad5ad72017-08-03 17:14:08 -04004247Additionally transform draw using Clip, Matrix, and optional Paint paint.
4248
4249If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4250Blend_Mode, and Draw_Looper. If image is kAlpha_8_SkColorType, apply Shader.
4251If paint contains Mask_Filter, generate mask from image bounds.
4252
4253If generated mask extends beyond image bounds, replicate image edge colors, just
4254as Shader made from SkImage::makeShader with SkShader::kClamp_TileMode set
Cary Clarkbc5697d2017-10-04 14:31:33 -04004255replicates the image edge color when it samples outside of its bounds.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004256
4257#Param image Image containing pixels, dimensions, and format ##
4258#Param center IRect edge of image corners and sides ##
4259#Param dst destination Rect of image to draw to ##
4260#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4261 and so on; or nullptr
4262##
Cary Clark8032b982017-07-28 11:04:54 -04004263
4264#Example
4265#Height 128
4266#Description
4267 The leftmost image is smaller than center; only corners are drawn, all scaled to fit.
Cary Clarkce101242017-09-01 15:51:02 -04004268 The second image equals the size of center; only corners are drawn without scaling.
4269 The remaining images are larger than center. All corners draw without scaling.
4270 The sides and center are scaled if needed to take up the remaining space.
Cary Clark8032b982017-07-28 11:04:54 -04004271##
Cary Clarkbad5ad72017-08-03 17:14:08 -04004272void draw(SkCanvas* canvas) {
4273 SkIRect center = { 20, 10, 50, 40 };
4274 SkBitmap bitmap;
4275 bitmap.allocPixels(SkImageInfo::MakeN32Premul(60, 60));
4276 SkCanvas bitCanvas(bitmap);
4277 SkPaint paint;
4278 SkColor gray = 0xFF000000;
4279 int left = 0;
4280 for (auto right: { center.fLeft, center.fRight, bitmap.width() } ) {
4281 int top = 0;
4282 for (auto bottom: { center.fTop, center.fBottom, bitmap.height() } ) {
4283 paint.setColor(gray);
4284 bitCanvas.drawIRect(SkIRect::MakeLTRB(left, top, right, bottom), paint);
4285 gray += 0x001f1f1f;
4286 top = bottom;
4287 }
4288 left = right;
4289 }
4290 sk_sp<SkImage> image = SkImage::MakeFromBitmap(bitmap);
4291 SkImage* imagePtr = image.get();
4292 for (auto dest: { 20, 30, 40, 60, 90 } ) {
4293 canvas->drawImageNine(imagePtr, center, SkRect::MakeWH(dest, dest), nullptr);
4294 canvas->translate(dest + 4, 0);
4295 }
Cary Clark8032b982017-07-28 11:04:54 -04004296}
4297##
4298
4299#ToDo incomplete ##
4300
4301##
4302
4303# ------------------------------------------------------------------------------
4304
4305#Method void drawImageNine(const sk_sp<SkImage>& image, const SkIRect& center, const SkRect& dst,
4306 const SkPaint* paint = nullptr)
4307
Cary Clarkd0530ba2017-09-14 11:25:39 -04004308Draw Image image stretched proportionally to fit into Rect dst.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004309IRect center divides the image into nine sections: four sides, four corners, and
Cary Clarkce101242017-09-01 15:51:02 -04004310the center. Corners are not scaled, or scaled down proportionately if their sides
Cary Clarkbad5ad72017-08-03 17:14:08 -04004311are larger than dst; center and four sides are scaled to fit remaining space, if any.
Cary Clark8032b982017-07-28 11:04:54 -04004312
Cary Clarkbad5ad72017-08-03 17:14:08 -04004313Additionally transform draw using Clip, Matrix, and optional Paint paint.
4314
4315If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4316Blend_Mode, and Draw_Looper. If image is kAlpha_8_SkColorType, apply Shader.
4317If paint contains Mask_Filter, generate mask from image bounds.
4318
4319If generated mask extends beyond image bounds, replicate image edge colors, just
4320as Shader made from SkImage::makeShader with SkShader::kClamp_TileMode set
Cary Clarkbc5697d2017-10-04 14:31:33 -04004321replicates the image edge color when it samples outside of its bounds.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004322
4323#Param image Image containing pixels, dimensions, and format ##
4324#Param center IRect edge of image corners and sides ##
4325#Param dst destination Rect of image to draw to ##
4326#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4327 and so on; or nullptr
4328##
Cary Clark8032b982017-07-28 11:04:54 -04004329
4330#Example
4331#Height 128
4332#Description
4333 The two leftmost images has four corners and sides to the left and right of center.
4334 The leftmost image scales the width of corners proportionately to fit.
Cary Clarkce101242017-09-01 15:51:02 -04004335 The third and fourth image corners are not scaled; the sides and center are scaled to
Cary Clark8032b982017-07-28 11:04:54 -04004336 fill the remaining space.
4337 The rightmost image has four corners scaled vertically to fit, and uses sides above
4338 and below center to fill the remaining space.
4339##
Cary Clarkbad5ad72017-08-03 17:14:08 -04004340void draw(SkCanvas* canvas) {
4341 SkIRect center = { 20, 10, 50, 40 };
4342 SkBitmap bitmap;
4343 bitmap.allocPixels(SkImageInfo::MakeN32Premul(60, 60));
4344 SkCanvas bitCanvas(bitmap);
4345 SkPaint paint;
4346 SkColor gray = 0xFF000000;
4347 int left = 0;
4348 for (auto right: { center.fLeft, center.fRight, bitmap.width() } ) {
4349 int top = 0;
4350 for (auto bottom: { center.fTop, center.fBottom, bitmap.height() } ) {
4351 paint.setColor(gray);
4352 bitCanvas.drawIRect(SkIRect::MakeLTRB(left, top, right, bottom), paint);
4353 gray += 0x001f1f1f;
4354 top = bottom;
4355 }
4356 left = right;
4357 }
4358 sk_sp<SkImage> image = SkImage::MakeFromBitmap(bitmap);
4359 for (auto dest: { 20, 30, 40, 60, 90 } ) {
4360 canvas->drawImageNine(image, center, SkRect::MakeWH(dest, 110 - dest), nullptr);
4361 canvas->translate(dest + 4, 0);
4362 }
Cary Clark8032b982017-07-28 11:04:54 -04004363}
4364##
4365
4366#ToDo incomplete ##
4367
4368##
4369
4370# ------------------------------------------------------------------------------
4371
4372#Method void drawBitmap(const SkBitmap& bitmap, SkScalar left, SkScalar top,
Cary Clark73fa9722017-08-29 17:36:51 -04004373 const SkPaint* paint = nullptr)
Cary Clark8032b982017-07-28 11:04:54 -04004374
4375Draw Bitmap bitmap, with its top-left corner at (left, top),
4376using Clip, Matrix, and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004377
Cary Clarkbad5ad72017-08-03 17:14:08 -04004378If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4379Blend_Mode, and Draw_Looper. If bitmap is kAlpha_8_SkColorType, apply Shader.
4380If paint contains Mask_Filter, generate mask from bitmap bounds.
4381
4382If generated mask extends beyond bitmap bounds, replicate bitmap edge colors,
4383just as Shader made from SkShader::MakeBitmapShader with
Cary Clarkbc5697d2017-10-04 14:31:33 -04004384SkShader::kClamp_TileMode set replicates the bitmap edge color when it samples
Cary Clarkbad5ad72017-08-03 17:14:08 -04004385outside of its bounds.
4386
4387#Param bitmap Bitmap containing pixels, dimensions, and format ##
4388#Param left left side of bitmap ##
4389#Param top top side of bitmap ##
4390#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4391 and so on; or nullptr
4392##
Cary Clark8032b982017-07-28 11:04:54 -04004393
4394#Example
4395#Height 64
Cary Clarkbad5ad72017-08-03 17:14:08 -04004396void draw(SkCanvas* canvas) {
4397 uint8_t pixels[][8] = { { 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00},
4398 { 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00},
4399 { 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00},
4400 { 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF},
4401 { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
4402 { 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00},
4403 { 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0x00},
4404 { 0xFF, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0xFF} };
4405 SkBitmap bitmap;
4406 bitmap.installPixels(SkImageInfo::MakeA8(8, 8),
4407 (void*) pixels, sizeof(pixels[0]));
4408 SkPaint paint;
4409 canvas->scale(4, 4);
4410 for (auto color : { SK_ColorRED, SK_ColorBLUE, 0xFF007F00} ) {
4411 paint.setColor(color);
4412 canvas->drawBitmap(bitmap, 0, 0, &paint);
4413 canvas->translate(12, 0);
4414 }
Cary Clark8032b982017-07-28 11:04:54 -04004415}
4416##
4417
4418#ToDo incomplete ##
4419
4420##
4421
4422# ------------------------------------------------------------------------------
4423
4424#Method void drawBitmapRect(const SkBitmap& bitmap, const SkRect& src, const SkRect& dst,
4425 const SkPaint* paint, SrcRectConstraint constraint = kStrict_SrcRectConstraint)
4426
4427Draw Rect src of Bitmap bitmap, scaled and translated to fill Rect dst.
4428Additionally transform draw using Clip, Matrix, and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004429
Cary Clarkbad5ad72017-08-03 17:14:08 -04004430If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4431Blend_Mode, and Draw_Looper. If bitmap is kAlpha_8_SkColorType, apply Shader.
4432If paint contains Mask_Filter, generate mask from bitmap bounds.
4433
4434If generated mask extends beyond bitmap bounds, replicate bitmap edge colors,
4435just as Shader made from SkShader::MakeBitmapShader with
Cary Clarkbc5697d2017-10-04 14:31:33 -04004436SkShader::kClamp_TileMode set replicates the bitmap edge color when it samples
Cary Clarkbad5ad72017-08-03 17:14:08 -04004437outside of its bounds.
4438
4439constraint set to kStrict_SrcRectConstraint limits Paint Filter_Quality to
4440sample within src; set to kFast_SrcRectConstraint allows sampling outside to
4441improve performance.
4442
4443#Param bitmap Bitmap containing pixels, dimensions, and format ##
4444#Param src source Rect of image to draw from ##
4445#Param dst destination Rect of image to draw to ##
4446#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4447 and so on; or nullptr
4448##
4449#Param constraint filter strictly within src or draw faster ##
Cary Clark8032b982017-07-28 11:04:54 -04004450
4451#Example
4452#Height 64
Cary Clarkbad5ad72017-08-03 17:14:08 -04004453void draw(SkCanvas* canvas) {
4454 uint8_t pixels[][8] = { { 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00},
4455 { 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00},
4456 { 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00},
4457 { 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF},
4458 { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
4459 { 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00},
4460 { 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00},
4461 { 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00} };
4462 SkBitmap bitmap;
4463 bitmap.installPixels(SkImageInfo::MakeA8(8, 8),
4464 (void*) pixels, sizeof(pixels[0]));
4465 SkPaint paint;
4466 paint.setMaskFilter(SkBlurMaskFilter::Make(kSolid_SkBlurStyle, 6));
4467 for (auto color : { SK_ColorRED, SK_ColorBLUE, 0xFF007F00} ) {
4468 paint.setColor(color);
4469 canvas->drawBitmapRect(bitmap, SkRect::MakeWH(8, 8), SkRect::MakeWH(32, 32), &paint);
4470 canvas->translate(48, 0);
4471 }
Cary Clark8032b982017-07-28 11:04:54 -04004472}
4473##
4474
4475#ToDo incomplete ##
4476
4477##
4478
4479# ------------------------------------------------------------------------------
4480
4481#Method void drawBitmapRect(const SkBitmap& bitmap, const SkIRect& isrc, const SkRect& dst,
4482 const SkPaint* paint, SrcRectConstraint constraint = kStrict_SrcRectConstraint)
4483
4484Draw IRect isrc of Bitmap bitmap, scaled and translated to fill Rect dst.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004485isrc is on integer pixel boundaries; dst may include fractional boundaries.
Cary Clark8032b982017-07-28 11:04:54 -04004486Additionally transform draw using Clip, Matrix, and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004487
Cary Clarkbad5ad72017-08-03 17:14:08 -04004488If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4489Blend_Mode, and Draw_Looper. If bitmap is kAlpha_8_SkColorType, apply Shader.
4490If paint contains Mask_Filter, generate mask from bitmap bounds.
4491
4492If generated mask extends beyond bitmap bounds, replicate bitmap edge colors,
4493just as Shader made from SkShader::MakeBitmapShader with
Cary Clarkbc5697d2017-10-04 14:31:33 -04004494SkShader::kClamp_TileMode set replicates the bitmap edge color when it samples
Cary Clarkbad5ad72017-08-03 17:14:08 -04004495outside of its bounds.
4496
4497constraint set to kStrict_SrcRectConstraint limits Paint Filter_Quality to
Cary Clarkce101242017-09-01 15:51:02 -04004498sample within isrc; set to kFast_SrcRectConstraint allows sampling outside to
Cary Clarkbad5ad72017-08-03 17:14:08 -04004499improve performance.
4500
4501#Param bitmap Bitmap containing pixels, dimensions, and format ##
4502#Param isrc source IRect of image to draw from ##
4503#Param dst destination Rect of image to draw to ##
4504#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4505 and so on; or nullptr
4506##
Cary Clarkce101242017-09-01 15:51:02 -04004507#Param constraint sample strictly within isrc, or draw faster ##
Cary Clark8032b982017-07-28 11:04:54 -04004508
4509#Example
4510#Height 64
Cary Clarkbad5ad72017-08-03 17:14:08 -04004511void draw(SkCanvas* canvas) {
4512 uint8_t pixels[][8] = { { 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00},
4513 { 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00},
4514 { 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0xFF},
4515 { 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0xFF},
4516 { 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF},
4517 { 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF},
4518 { 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00},
4519 { 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00} };
4520 SkBitmap bitmap;
4521 bitmap.installPixels(SkImageInfo::MakeA8(8, 8),
4522 (void*) pixels, sizeof(pixels[0]));
4523 SkPaint paint;
4524 paint.setFilterQuality(kHigh_SkFilterQuality);
4525 for (auto color : { SK_ColorRED, SK_ColorBLUE, 0xFF007F00, 0xFF7f007f} ) {
4526 paint.setColor(color);
4527 canvas->drawBitmapRect(bitmap, SkIRect::MakeWH(8, 8), SkRect::MakeWH(32, 32), &paint);
4528 canvas->translate(48.25f, 0);
4529 }
Cary Clark8032b982017-07-28 11:04:54 -04004530}
4531##
4532
4533#ToDo incomplete ##
4534
4535##
4536
4537# ------------------------------------------------------------------------------
4538
4539#Method void drawBitmapRect(const SkBitmap& bitmap, const SkRect& dst, const SkPaint* paint,
4540 SrcRectConstraint constraint = kStrict_SrcRectConstraint)
4541
4542Draw Bitmap bitmap, scaled and translated to fill Rect dst.
Cary Clarkce101242017-09-01 15:51:02 -04004543bitmap bounds is on integer pixel boundaries; dst may include fractional boundaries.
Cary Clark8032b982017-07-28 11:04:54 -04004544Additionally transform draw using Clip, Matrix, and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004545
Cary Clarkbad5ad72017-08-03 17:14:08 -04004546If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4547Blend_Mode, and Draw_Looper. If bitmap is kAlpha_8_SkColorType, apply Shader.
4548If paint contains Mask_Filter, generate mask from bitmap bounds.
4549
4550If generated mask extends beyond bitmap bounds, replicate bitmap edge colors,
4551just as Shader made from SkShader::MakeBitmapShader with
Cary Clarkbc5697d2017-10-04 14:31:33 -04004552SkShader::kClamp_TileMode set replicates the bitmap edge color when it samples
Cary Clarkbad5ad72017-08-03 17:14:08 -04004553outside of its bounds.
4554
4555constraint set to kStrict_SrcRectConstraint limits Paint Filter_Quality to
Cary Clarkce101242017-09-01 15:51:02 -04004556sample within bitmap; set to kFast_SrcRectConstraint allows sampling outside to
Cary Clarkbad5ad72017-08-03 17:14:08 -04004557improve performance.
4558
4559#Param bitmap Bitmap containing pixels, dimensions, and format ##
4560#Param dst destination Rect of image to draw to ##
4561#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4562 and so on; or nullptr
4563##
Cary Clarkce101242017-09-01 15:51:02 -04004564#Param constraint filter strictly within bitmap or draw faster ##
Cary Clark8032b982017-07-28 11:04:54 -04004565
4566#Example
4567#Height 64
Cary Clarkbad5ad72017-08-03 17:14:08 -04004568void draw(SkCanvas* canvas) {
4569 uint32_t pixels[][2] = { { 0x00000000, 0x55550000},
4570 { 0xAAAA0000, 0xFFFF0000} };
4571 SkBitmap bitmap;
4572 bitmap.installPixels(SkImageInfo::MakeN32Premul(2, 2),
4573 (void*) pixels, sizeof(pixels[0]));
4574 SkPaint paint;
4575 canvas->scale(4, 4);
4576 for (auto color : { SK_ColorRED, SK_ColorBLUE, SK_ColorGREEN } ) {
4577 paint.setColorFilter(SkColorFilter::MakeModeFilter(color, SkBlendMode::kPlus));
4578 canvas->drawBitmapRect(bitmap, SkRect::MakeWH(8, 8), &paint);
4579 canvas->translate(8, 0);
4580 }
Cary Clark8032b982017-07-28 11:04:54 -04004581}
4582##
4583
4584#ToDo incomplete ##
4585
4586##
4587
4588# ------------------------------------------------------------------------------
4589
4590#Method void drawBitmapNine(const SkBitmap& bitmap, const SkIRect& center, const SkRect& dst,
Cary Clark73fa9722017-08-29 17:36:51 -04004591 const SkPaint* paint = nullptr)
Cary Clark8032b982017-07-28 11:04:54 -04004592
Cary Clarkd0530ba2017-09-14 11:25:39 -04004593Draw Bitmap bitmap stretched proportionally to fit into Rect dst.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004594IRect center divides the bitmap into nine sections: four sides, four corners,
Cary Clarkce101242017-09-01 15:51:02 -04004595and the center. Corners are not scaled, or scaled down proportionately if their
Cary Clarkbad5ad72017-08-03 17:14:08 -04004596sides are larger than dst; center and four sides are scaled to fit remaining
4597space, if any.
Cary Clark8032b982017-07-28 11:04:54 -04004598
Cary Clarkbad5ad72017-08-03 17:14:08 -04004599Additionally transform draw using Clip, Matrix, and optional Paint paint.
4600
4601If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4602Blend_Mode, and Draw_Looper. If bitmap is kAlpha_8_SkColorType, apply Shader.
4603If paint contains Mask_Filter, generate mask from bitmap bounds.
4604
4605If generated mask extends beyond bitmap bounds, replicate bitmap edge colors,
4606just as Shader made from SkShader::MakeBitmapShader with
Cary Clarkbc5697d2017-10-04 14:31:33 -04004607SkShader::kClamp_TileMode set replicates the bitmap edge color when it samples
Cary Clarkbad5ad72017-08-03 17:14:08 -04004608outside of its bounds.
4609
4610#Param bitmap Bitmap containing pixels, dimensions, and format ##
4611#Param center IRect edge of image corners and sides ##
4612#Param dst destination Rect of image to draw to ##
4613#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4614 and so on; or nullptr
4615##
Cary Clark8032b982017-07-28 11:04:54 -04004616
4617#Example
4618#Height 128
4619#Description
4620 The two leftmost bitmap draws has four corners and sides to the left and right of center.
4621 The leftmost bitmap draw scales the width of corners proportionately to fit.
Cary Clarkce101242017-09-01 15:51:02 -04004622 The third and fourth draw corners are not scaled; the sides and center are scaled to
Cary Clark8032b982017-07-28 11:04:54 -04004623 fill the remaining space.
4624 The rightmost bitmap draw has four corners scaled vertically to fit, and uses sides above
4625 and below center to fill the remaining space.
4626##
Cary Clarkbad5ad72017-08-03 17:14:08 -04004627void draw(SkCanvas* canvas) {
4628 SkIRect center = { 20, 10, 50, 40 };
4629 SkBitmap bitmap;
4630 bitmap.allocPixels(SkImageInfo::MakeN32Premul(60, 60));
4631 SkCanvas bitCanvas(bitmap);
4632 SkPaint paint;
4633 SkColor gray = 0xFF000000;
4634 int left = 0;
4635 for (auto right: { center.fLeft, center.fRight, bitmap.width() } ) {
4636 int top = 0;
4637 for (auto bottom: { center.fTop, center.fBottom, bitmap.height() } ) {
4638 paint.setColor(gray);
4639 bitCanvas.drawIRect(SkIRect::MakeLTRB(left, top, right, bottom), paint);
4640 gray += 0x001f1f1f;
4641 top = bottom;
4642 }
4643 left = right;
4644 }
4645 for (auto dest: { 20, 30, 40, 60, 90 } ) {
4646 canvas->drawBitmapNine(bitmap, center, SkRect::MakeWH(dest, 110 - dest), nullptr);
4647 canvas->translate(dest + 4, 0);
4648 }
Cary Clark8032b982017-07-28 11:04:54 -04004649}
4650##
4651
4652#ToDo incomplete ##
4653
4654##
4655
4656# ------------------------------------------------------------------------------
4657#Struct Lattice
4658
Cary Clark8032b982017-07-28 11:04:54 -04004659#Code
4660 struct Lattice {
4661 enum Flags {...
4662
4663 const int* fXDivs;
4664 const int* fYDivs;
4665 const Flags* fFlags;
4666 int fXCount;
4667 int fYCount;
4668 const SkIRect* fBounds;
4669 };
4670##
4671
Cary Clark154beea2017-10-26 07:58:48 -04004672 Lattice divides Bitmap or Image into a rectangular grid.
4673 Grid entries on even columns and even rows are fixed; these entries are
4674 always drawn at their original size if the destination is large enough.
4675 If the destination side is too small to hold the fixed entries, all fixed
4676 entries are proportionately scaled down to fit.
4677 The grid entries not on even columns and rows are scaled to fit the
4678 remaining space, if any.
4679
Cary Clark8032b982017-07-28 11:04:54 -04004680 #Enum Flags
4681 #Code
4682 enum Flags : uint8_t {
4683 kTransparent_Flags = 1 << 0,
4684 };
4685 ##
4686
4687 Optional setting per rectangular grid entry to make it transparent.
4688
4689 #Const kTransparent_Flags 1
4690 Set to skip lattice rectangle by making it transparent.
4691 ##
4692 ##
4693
4694 #Member const int* fXDivs
4695 Array of x-coordinates that divide the bitmap vertically.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004696 Array entries must be unique, increasing, greater than or equal to
4697 fBounds left edge, and less than fBounds right edge.
4698 Set the first element to fBounds left to collapse the left column of
4699 fixed grid entries.
Cary Clark8032b982017-07-28 11:04:54 -04004700 ##
4701
4702 #Member const int* fYDivs
4703 Array of y-coordinates that divide the bitmap horizontally.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004704 Array entries must be unique, increasing, greater than or equal to
4705 fBounds top edge, and less than fBounds bottom edge.
4706 Set the first element to fBounds top to collapse the top row of fixed
4707 grid entries.
Cary Clark8032b982017-07-28 11:04:54 -04004708 ##
4709
4710 #Member const Flags* fFlags
4711 Optional array of Flags, one per rectangular grid entry:
Cary Clarkbad5ad72017-08-03 17:14:08 -04004712 array length must be
4713 #Formula
4714 (fXCount + 1) * (fYCount + 1)
4715 ##
4716 .
Cary Clark6fc50412017-09-21 12:31:06 -04004717
Cary Clark8032b982017-07-28 11:04:54 -04004718 Array entries correspond to the rectangular grid entries, ascending
4719 left to right and then top to bottom.
4720 ##
4721
4722 #Member int fXCount
Cary Clarkbad5ad72017-08-03 17:14:08 -04004723 Number of entries in fXDivs array; one less than the number of
4724 horizontal divisions.
Cary Clark8032b982017-07-28 11:04:54 -04004725 ##
4726
4727 #Member int fYCount
Cary Clarkbad5ad72017-08-03 17:14:08 -04004728 Number of entries in fYDivs array; one less than the number of vertical
4729 divisions.
Cary Clark8032b982017-07-28 11:04:54 -04004730 ##
4731
4732 #Member const SkIRect* fBounds
4733 Optional subset IRect source to draw from.
4734 If nullptr, source bounds is dimensions of Bitmap or Image.
4735 ##
4736
4737#Struct Lattice ##
4738
4739#Method void drawBitmapLattice(const SkBitmap& bitmap, const Lattice& lattice, const SkRect& dst,
4740 const SkPaint* paint = nullptr)
4741
Cary Clarkd0530ba2017-09-14 11:25:39 -04004742Draw Bitmap bitmap stretched proportionally to fit into Rect dst.
Cary Clark8032b982017-07-28 11:04:54 -04004743
4744Lattice lattice divides bitmap into a rectangular grid.
4745Each intersection of an even-numbered row and column is fixed; like the corners
Cary Clarkbad5ad72017-08-03 17:14:08 -04004746of drawBitmapNine, fixed lattice elements never scale larger than their initial
Cary Clarkbc5697d2017-10-04 14:31:33 -04004747size and shrink proportionately when all fixed elements exceed the bitmap
Cary Clarkbad5ad72017-08-03 17:14:08 -04004748dimension. All other grid elements scale to fill the available space, if any.
Cary Clark8032b982017-07-28 11:04:54 -04004749
4750Additionally transform draw using Clip, Matrix, and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004751
Cary Clarkbad5ad72017-08-03 17:14:08 -04004752If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4753Blend_Mode, and Draw_Looper. If bitmap is kAlpha_8_SkColorType, apply Shader.
4754If paint contains Mask_Filter, generate mask from bitmap bounds.
4755
4756If generated mask extends beyond bitmap bounds, replicate bitmap edge colors,
4757just as Shader made from SkShader::MakeBitmapShader with
Cary Clarkbc5697d2017-10-04 14:31:33 -04004758SkShader::kClamp_TileMode set replicates the bitmap edge color when it samples
Cary Clarkbad5ad72017-08-03 17:14:08 -04004759outside of its bounds.
4760
4761#Param bitmap Bitmap containing pixels, dimensions, and format ##
4762#Param lattice division of bitmap into fixed and variable rectangles ##
4763#Param dst destination Rect of image to draw to ##
4764#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4765 and so on; or nullptr
4766##
Cary Clark8032b982017-07-28 11:04:54 -04004767
4768#Example
4769#Height 128
4770#Description
4771 The two leftmost bitmap draws has four corners and sides to the left and right of center.
4772 The leftmost bitmap draw scales the width of corners proportionately to fit.
Cary Clarkce101242017-09-01 15:51:02 -04004773 The third and fourth draw corners are not scaled; the sides are scaled to
Cary Clark8032b982017-07-28 11:04:54 -04004774 fill the remaining space; the center is transparent.
4775 The rightmost bitmap draw has four corners scaled vertically to fit, and uses sides above
4776 and below center to fill the remaining space.
4777##
Cary Clarkbad5ad72017-08-03 17:14:08 -04004778void draw(SkCanvas* canvas) {
4779 SkIRect center = { 20, 10, 50, 40 };
4780 SkBitmap bitmap;
4781 bitmap.allocPixels(SkImageInfo::MakeN32Premul(60, 60));
4782 SkCanvas bitCanvas(bitmap);
4783 SkPaint paint;
4784 SkColor gray = 0xFF000000;
4785 int left = 0;
4786 for (auto right: { center.fLeft, center.fRight, bitmap.width() } ) {
4787 int top = 0;
4788 for (auto bottom: { center.fTop, center.fBottom, bitmap.height() } ) {
4789 paint.setColor(gray);
4790 bitCanvas.drawIRect(SkIRect::MakeLTRB(left, top, right, bottom), paint);
4791 gray += 0x001f1f1f;
4792 top = bottom;
4793 }
4794 left = right;
4795 }
4796 const int xDivs[] = { center.fLeft, center.fRight };
4797 const int yDivs[] = { center.fTop, center.fBottom };
4798 SkCanvas::Lattice::Flags flags[3][3];
4799 memset(flags, 0, sizeof(flags));
4800 flags[1][1] = SkCanvas::Lattice::kTransparent_Flags;
4801 SkCanvas::Lattice lattice = { xDivs, yDivs, flags[0], SK_ARRAY_COUNT(xDivs),
4802 SK_ARRAY_COUNT(yDivs), nullptr };
4803 for (auto dest: { 20, 30, 40, 60, 90 } ) {
4804 canvas->drawBitmapLattice(bitmap, lattice , SkRect::MakeWH(dest, 110 - dest), nullptr);
4805 canvas->translate(dest + 4, 0);
4806 }
Cary Clark8032b982017-07-28 11:04:54 -04004807}
4808##
4809
4810#ToDo incomplete ##
4811
4812##
4813
4814# ------------------------------------------------------------------------------
4815
4816#Method void drawImageLattice(const SkImage* image, const Lattice& lattice, const SkRect& dst,
4817 const SkPaint* paint = nullptr)
4818
Cary Clarkd0530ba2017-09-14 11:25:39 -04004819Draw Image image stretched proportionally to fit into Rect dst.
Cary Clark8032b982017-07-28 11:04:54 -04004820
4821Lattice lattice divides image into a rectangular grid.
4822Each intersection of an even-numbered row and column is fixed; like the corners
Cary Clarkbad5ad72017-08-03 17:14:08 -04004823of drawBitmapNine, fixed lattice elements never scale larger than their initial
Cary Clarkbc5697d2017-10-04 14:31:33 -04004824size and shrink proportionately when all fixed elements exceed the bitmap
Cary Clarkbad5ad72017-08-03 17:14:08 -04004825dimension. All other grid elements scale to fill the available space, if any.
Cary Clark8032b982017-07-28 11:04:54 -04004826
4827Additionally transform draw using Clip, Matrix, and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004828
Cary Clarkbad5ad72017-08-03 17:14:08 -04004829If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4830Blend_Mode, and Draw_Looper. If bitmap is kAlpha_8_SkColorType, apply Shader.
4831If paint contains Mask_Filter, generate mask from bitmap bounds.
4832
4833If generated mask extends beyond bitmap bounds, replicate bitmap edge colors,
4834just as Shader made from SkShader::MakeBitmapShader with
Cary Clarkbc5697d2017-10-04 14:31:33 -04004835SkShader::kClamp_TileMode set replicates the bitmap edge color when it samples
Cary Clarkbad5ad72017-08-03 17:14:08 -04004836outside of its bounds.
4837
4838#Param image Image containing pixels, dimensions, and format ##
4839#Param lattice division of bitmap into fixed and variable rectangles ##
4840#Param dst destination Rect of image to draw to ##
4841#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4842 and so on; or nullptr
4843##
Cary Clark8032b982017-07-28 11:04:54 -04004844
4845#Example
4846#Height 128
4847#Description
4848 The leftmost image is smaller than center; only corners are drawn, all scaled to fit.
Cary Clarkce101242017-09-01 15:51:02 -04004849 The second image equals the size of center; only corners are drawn without scaling.
4850 The remaining images are larger than center. All corners draw without scaling. The sides
Cary Clark8032b982017-07-28 11:04:54 -04004851 are scaled if needed to take up the remaining space; the center is transparent.
4852##
Cary Clarkbad5ad72017-08-03 17:14:08 -04004853void draw(SkCanvas* canvas) {
4854 SkIRect center = { 20, 10, 50, 40 };
4855 SkBitmap bitmap;
4856 bitmap.allocPixels(SkImageInfo::MakeN32Premul(60, 60));
4857 SkCanvas bitCanvas(bitmap);
4858 SkPaint paint;
4859 SkColor gray = 0xFF000000;
4860 int left = 0;
4861 for (auto right: { center.fLeft, center.fRight, bitmap.width() } ) {
4862 int top = 0;
4863 for (auto bottom: { center.fTop, center.fBottom, bitmap.height() } ) {
4864 paint.setColor(gray);
4865 bitCanvas.drawIRect(SkIRect::MakeLTRB(left, top, right, bottom), paint);
4866 gray += 0x001f1f1f;
4867 top = bottom;
4868 }
4869 left = right;
4870 }
4871 const int xDivs[] = { center.fLeft, center.fRight };
4872 const int yDivs[] = { center.fTop, center.fBottom };
4873 SkCanvas::Lattice::Flags flags[3][3];
4874 memset(flags, 0, sizeof(flags));
4875 flags[1][1] = SkCanvas::Lattice::kTransparent_Flags;
4876 SkCanvas::Lattice lattice = { xDivs, yDivs, flags[0], SK_ARRAY_COUNT(xDivs),
4877 SK_ARRAY_COUNT(yDivs), nullptr };
4878 sk_sp<SkImage> image = SkImage::MakeFromBitmap(bitmap);
4879 SkImage* imagePtr = image.get();
4880 for (auto dest: { 20, 30, 40, 60, 90 } ) {
4881 canvas->drawImageNine(imagePtr, center, SkRect::MakeWH(dest, dest), nullptr);
4882 canvas->translate(dest + 4, 0);
4883 }
Cary Clark8032b982017-07-28 11:04:54 -04004884}
4885##
4886
4887#ToDo incomplete ##
4888
4889##
4890
4891#Topic Draw_Image ##
4892
4893# ------------------------------------------------------------------------------
4894
4895#Method void drawText(const void* text, size_t byteLength, SkScalar x, SkScalar y,
4896 const SkPaint& paint)
4897
4898Draw text, with origin at (x, y), using Clip, Matrix, and Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004899
Cary Clarkbc5697d2017-10-04 14:31:33 -04004900text meaning depends on Paint_Text_Encoding; by default, text is encoded as
Cary Clarkbad5ad72017-08-03 17:14:08 -04004901UTF-8.
Cary Clark8032b982017-07-28 11:04:54 -04004902
Cary Clarkbad5ad72017-08-03 17:14:08 -04004903x and y meaning depends on Paint_Text_Align and Paint_Vertical_Text; by default
Cary Clarkbc5697d2017-10-04 14:31:33 -04004904text draws left to right, positioning the first glyph left side bearing at x
Cary Clarkbad5ad72017-08-03 17:14:08 -04004905and its baseline at y. Text size is affected by Matrix and Paint_Text_Size.
4906
4907All elements of paint: Path_Effect, Rasterizer, Mask_Filter, Shader,
4908Color_Filter, Image_Filter, and Draw_Looper; apply to text. By default, draws
Cary Clarkce101242017-09-01 15:51:02 -04004909filled 12 point black Glyphs.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004910
Cary Clarkce101242017-09-01 15:51:02 -04004911#Param text character code points or Glyphs drawn ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04004912#Param byteLength byte length of text array ##
4913#Param x start of text on x-axis ##
4914#Param y start of text on y-axis ##
4915#Param paint text size, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04004916
4917#Example
4918#Height 200
4919#Description
4920 The same text is drawn varying Paint_Text_Size and varying
4921 Matrix.
4922##
Cary Clarkbad5ad72017-08-03 17:14:08 -04004923void draw(SkCanvas* canvas) {
4924 SkPaint paint;
4925 paint.setAntiAlias(true);
4926 float textSizes[] = { 12, 18, 24, 36 };
4927 for (auto size: textSizes ) {
4928 paint.setTextSize(size);
4929 canvas->drawText("Aa", 2, 10, 20, paint);
4930 canvas->translate(0, size * 2);
4931 }
4932 paint.reset();
4933 paint.setAntiAlias(true);
4934 float yPos = 20;
4935 for (auto size: textSizes ) {
4936 float scale = size / 12.f;
4937 canvas->resetMatrix();
4938 canvas->translate(100, 0);
4939 canvas->scale(scale, scale);
4940 canvas->drawText("Aa", 2, 10 / scale, yPos / scale, paint);
4941 yPos += size * 2;
4942 }
4943}
Cary Clark8032b982017-07-28 11:04:54 -04004944##
4945
4946#ToDo incomplete ##
4947
4948##
4949
4950#Method void drawString(const char* string, SkScalar x, SkScalar y, const SkPaint& paint)
4951
Cary Clarkbad5ad72017-08-03 17:14:08 -04004952Draw null terminated string, with origin at (x, y), using Clip, Matrix, and
4953Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004954
Cary Clarkbc5697d2017-10-04 14:31:33 -04004955string meaning depends on Paint_Text_Encoding; by default, strings are encoded
4956as UTF-8. Other values of Paint_Text_Encoding are unlikely to produce the desired
Cary Clarkbad5ad72017-08-03 17:14:08 -04004957results, since zero bytes may be embedded in the string.
Cary Clark8032b982017-07-28 11:04:54 -04004958
Cary Clarkbad5ad72017-08-03 17:14:08 -04004959x and y meaning depends on Paint_Text_Align and Paint_Vertical_Text; by default
Cary Clarkbc5697d2017-10-04 14:31:33 -04004960string draws left to right, positioning the first glyph left side bearing at x
Cary Clarkbad5ad72017-08-03 17:14:08 -04004961and its baseline at y. Text size is affected by Matrix and Paint_Text_Size.
4962
4963All elements of paint: Path_Effect, Rasterizer, Mask_Filter, Shader,
4964Color_Filter, Image_Filter, and Draw_Looper; apply to text. By default, draws
Cary Clarkce101242017-09-01 15:51:02 -04004965filled 12 point black Glyphs.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004966
Cary Clarkce101242017-09-01 15:51:02 -04004967#Param string character code points or Glyphs drawn,
Cary Clarkbad5ad72017-08-03 17:14:08 -04004968 ending with a char value of zero
4969##
4970#Param x start of string on x-axis ##
4971#Param y start of string on y-axis ##
4972#Param paint text size, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04004973
4974#Example
4975 SkPaint paint;
4976 canvas->drawString("a small hello", 20, 20, paint);
4977##
4978
4979#SeeAlso drawText
4980
4981##
4982
4983#Method void drawString(const SkString& string, SkScalar x, SkScalar y, const SkPaint& paint)
4984
Cary Clarkbad5ad72017-08-03 17:14:08 -04004985Draw null terminated string, with origin at (x, y), using Clip, Matrix, and
4986Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004987
Cary Clarkbc5697d2017-10-04 14:31:33 -04004988string meaning depends on Paint_Text_Encoding; by default, strings are encoded
4989as UTF-8. Other values of Paint_Text_Encoding are unlikely to produce the desired
Cary Clarkbad5ad72017-08-03 17:14:08 -04004990results, since zero bytes may be embedded in the string.
Cary Clark8032b982017-07-28 11:04:54 -04004991
Cary Clarkbad5ad72017-08-03 17:14:08 -04004992x and y meaning depends on Paint_Text_Align and Paint_Vertical_Text; by default
Cary Clarkbc5697d2017-10-04 14:31:33 -04004993string draws left to right, positioning the first glyph left side bearing at x
Cary Clarkbad5ad72017-08-03 17:14:08 -04004994and its baseline at y. Text size is affected by Matrix and Paint_Text_Size.
4995
4996All elements of paint: Path_Effect, Rasterizer, Mask_Filter, Shader,
4997Color_Filter, Image_Filter, and Draw_Looper; apply to text. By default, draws
Cary Clarkce101242017-09-01 15:51:02 -04004998filled 12 point black Glyphs.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004999
Cary Clarkce101242017-09-01 15:51:02 -04005000#Param string character code points or Glyphs drawn,
Cary Clarkbad5ad72017-08-03 17:14:08 -04005001 ending with a char value of zero
5002##
5003#Param x start of string on x-axis ##
5004#Param y start of string on y-axis ##
5005#Param paint text size, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005006
5007#Example
5008 SkPaint paint;
5009 SkString string("a small hello");
5010 canvas->drawString(string, 20, 20, paint);
5011##
5012
5013#SeeAlso drawText
5014
5015##
5016
5017# ------------------------------------------------------------------------------
5018
5019#Method void drawPosText(const void* text, size_t byteLength, const SkPoint pos[],
5020 const SkPaint& paint)
5021
Cary Clarkbad5ad72017-08-03 17:14:08 -04005022Draw each glyph in text with the origin in pos array, using Clip, Matrix, and
Cary Clarkce101242017-09-01 15:51:02 -04005023Paint paint. The number of entries in pos array must match the number of Glyphs
Cary Clarkbad5ad72017-08-03 17:14:08 -04005024described by byteLength of text.
Cary Clark8032b982017-07-28 11:04:54 -04005025
Cary Clarkbc5697d2017-10-04 14:31:33 -04005026text meaning depends on Paint_Text_Encoding; by default, text is encoded as
Cary Clarkbad5ad72017-08-03 17:14:08 -04005027UTF-8. pos elements' meaning depends on Paint_Text_Align and Paint_Vertical_Text;
Cary Clarkbc5697d2017-10-04 14:31:33 -04005028by default each glyph left side bearing is positioned at x and its
Cary Clarkbad5ad72017-08-03 17:14:08 -04005029baseline is positioned at y. Text size is affected by Matrix and
5030Paint_Text_Size.
Cary Clark8032b982017-07-28 11:04:54 -04005031
Cary Clarkbad5ad72017-08-03 17:14:08 -04005032All elements of paint: Path_Effect, Rasterizer, Mask_Filter, Shader,
5033Color_Filter, Image_Filter, and Draw_Looper; apply to text. By default, draws
Cary Clarkce101242017-09-01 15:51:02 -04005034filled 12 point black Glyphs.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005035
5036Layout engines such as Harfbuzz typically position each glyph
Cary Clarkbc5697d2017-10-04 14:31:33 -04005037rather than using the font advance widths.
Cary Clark8032b982017-07-28 11:04:54 -04005038
Cary Clarkce101242017-09-01 15:51:02 -04005039#Param text character code points or Glyphs drawn ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005040#Param byteLength byte length of text array ##
5041#Param pos array of glyph origins ##
5042#Param paint text size, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005043
5044#Example
5045#Height 120
Cary Clarkbad5ad72017-08-03 17:14:08 -04005046void draw(SkCanvas* canvas) {
5047 const char hello[] = "HeLLo!";
5048 const SkPoint pos[] = { {40, 100}, {82, 95}, {115, 110}, {130, 95}, {145, 85},
5049 {172, 100} };
5050 SkPaint paint;
5051 paint.setTextSize(60);
5052 canvas->drawPosText(hello, strlen(hello), pos, paint);
Cary Clark8032b982017-07-28 11:04:54 -04005053}
5054##
5055
5056#ToDo incomplete ##
5057
5058##
5059
5060# ------------------------------------------------------------------------------
5061
5062#Method void drawPosTextH(const void* text, size_t byteLength, const SkScalar xpos[], SkScalar constY,
5063 const SkPaint& paint)
5064
Cary Clarkbad5ad72017-08-03 17:14:08 -04005065Draw each glyph in text with its (x, y) origin composed from xpos array and
5066constY, using Clip, Matrix, and Paint paint. The number of entries in xpos array
Cary Clarkce101242017-09-01 15:51:02 -04005067must match the number of Glyphs described by byteLength of text.
Cary Clark8032b982017-07-28 11:04:54 -04005068
Cary Clarkbc5697d2017-10-04 14:31:33 -04005069text meaning depends on Paint_Text_Encoding; by default, text is encoded as
Cary Clarkce101242017-09-01 15:51:02 -04005070UTF-8. xpos elements' meaning depends on Paint_Text_Align and Paint_Vertical_Text;
Cary Clarkbc5697d2017-10-04 14:31:33 -04005071by default each glyph left side bearing is positioned at an xpos element and
Cary Clarkbad5ad72017-08-03 17:14:08 -04005072its baseline is positioned at constY. Text size is affected by Matrix and
5073Paint_Text_Size.
Cary Clark8032b982017-07-28 11:04:54 -04005074
Cary Clarkbad5ad72017-08-03 17:14:08 -04005075All elements of paint: Path_Effect, Rasterizer, Mask_Filter, Shader,
5076Color_Filter, Image_Filter, and Draw_Looper; apply to text. By default, draws
Cary Clarkce101242017-09-01 15:51:02 -04005077filled 12 point black Glyphs.
Cary Clark8032b982017-07-28 11:04:54 -04005078
Cary Clarkbad5ad72017-08-03 17:14:08 -04005079Layout engines such as Harfbuzz typically position each glyph
Cary Clarkbc5697d2017-10-04 14:31:33 -04005080rather than using the font advance widths if all Glyphs share the same
Cary Clarkbad5ad72017-08-03 17:14:08 -04005081baseline.
5082
Cary Clarkce101242017-09-01 15:51:02 -04005083#Param text character code points or Glyphs drawn ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005084#Param byteLength byte length of text array ##
5085#Param xpos array of x positions, used to position each glyph ##
5086#Param constY shared y coordinate for all of x positions ##
5087#Param paint text size, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005088
5089#Example
5090#Height 40
Cary Clarkbad5ad72017-08-03 17:14:08 -04005091 void draw(SkCanvas* canvas) {
5092 SkScalar xpos[] = { 20, 40, 80, 160 };
5093 SkPaint paint;
5094 canvas->drawPosTextH("XXXX", 4, xpos, 20, paint);
5095 }
Cary Clark8032b982017-07-28 11:04:54 -04005096##
5097
5098#ToDo incomplete ##
5099
5100##
5101
5102# ------------------------------------------------------------------------------
5103
5104#Method void drawTextOnPathHV(const void* text, size_t byteLength, const SkPath& path, SkScalar hOffset,
5105 SkScalar vOffset, const SkPaint& paint)
5106
5107Draw text on Path path, using Clip, Matrix, and Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04005108
Cary Clarkbad5ad72017-08-03 17:14:08 -04005109Origin of text is at distance hOffset along the path, offset by a perpendicular
5110vector of length vOffset. If the path section corresponding the glyph advance is
5111curved, the glyph is drawn curved to match; control points in the glyph are
Cary Clarkbc5697d2017-10-04 14:31:33 -04005112mapped to projected points parallel to the path. If the text advance is larger
Cary Clarkbad5ad72017-08-03 17:14:08 -04005113than the path length, the excess text is clipped.
5114
Cary Clarkbc5697d2017-10-04 14:31:33 -04005115text meaning depends on Paint_Text_Encoding; by default, text is encoded as
Cary Clarkbad5ad72017-08-03 17:14:08 -04005116UTF-8. Origin meaning depends on Paint_Text_Align and Paint_Vertical_Text; by
Cary Clarkbc5697d2017-10-04 14:31:33 -04005117default text positions the first glyph left side bearing at origin x and its
Cary Clark8032b982017-07-28 11:04:54 -04005118baseline at origin y. Text size is affected by Matrix and Paint_Text_Size.
5119
Cary Clarkbad5ad72017-08-03 17:14:08 -04005120All elements of paint: Path_Effect, Rasterizer, Mask_Filter, Shader,
5121Color_Filter, Image_Filter, and Draw_Looper; apply to text. By default, draws
Cary Clarkce101242017-09-01 15:51:02 -04005122filled 12 point black Glyphs.
Cary Clark8032b982017-07-28 11:04:54 -04005123
Cary Clarkce101242017-09-01 15:51:02 -04005124#Param text character code points or Glyphs drawn ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005125#Param byteLength byte length of text array ##
5126#Param path Path providing text baseline ##
5127#Param hOffset distance along path to offset origin ##
5128#Param vOffset offset of text above (if negative) or below (if positive) the path ##
5129#Param paint text size, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005130
5131#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04005132 void draw(SkCanvas* canvas) {
5133 const char aero[] = "correo a" "\xC3" "\xA9" "reo";
5134 const size_t len = sizeof(aero) - 1;
5135 SkPath path;
5136 path.addOval({43-26, 43-26, 43+26, 43+26}, SkPath::kCW_Direction, 3);
5137 SkPaint paint;
5138 paint.setTextSize(24);
5139 for (auto offset : { 0, 10, 20 } ) {
5140 canvas->drawTextOnPathHV(aero, len, path, 0, -offset, paint);
5141 canvas->translate(70 + offset, 70 + offset);
5142 }
5143 }
Cary Clark8032b982017-07-28 11:04:54 -04005144##
5145
5146#ToDo incomplete ##
5147
5148##
5149
5150# ------------------------------------------------------------------------------
5151
5152#Method void drawTextOnPath(const void* text, size_t byteLength, const SkPath& path,
5153 const SkMatrix* matrix, const SkPaint& paint)
5154
5155Draw text on Path path, using Clip, Matrix, and Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04005156
Cary Clarkbad5ad72017-08-03 17:14:08 -04005157Origin of text is at beginning of path offset by matrix, if provided, before it
5158is mapped to path. If the path section corresponding the glyph advance is
5159curved, the glyph is drawn curved to match; control points in the glyph are
Cary Clarkbc5697d2017-10-04 14:31:33 -04005160mapped to projected points parallel to the path. If the text advance is larger
Cary Clarkbad5ad72017-08-03 17:14:08 -04005161than the path length, the excess text is clipped.
5162
Cary Clarkbc5697d2017-10-04 14:31:33 -04005163text meaning depends on Paint_Text_Encoding; by default, text is encoded as
Cary Clarkbad5ad72017-08-03 17:14:08 -04005164UTF-8. Origin meaning depends on Paint_Text_Align and Paint_Vertical_Text; by
Cary Clarkbc5697d2017-10-04 14:31:33 -04005165default text positions the first glyph left side bearing at origin x and its
Cary Clark8032b982017-07-28 11:04:54 -04005166baseline at origin y. Text size is affected by Matrix and Paint_Text_Size.
5167
Cary Clarkbad5ad72017-08-03 17:14:08 -04005168All elements of paint: Path_Effect, Rasterizer, Mask_Filter, Shader,
5169Color_Filter, Image_Filter, and Draw_Looper; apply to text. By default, draws
Cary Clarkce101242017-09-01 15:51:02 -04005170filled 12 point black Glyphs.
Cary Clark8032b982017-07-28 11:04:54 -04005171
Cary Clarkce101242017-09-01 15:51:02 -04005172#Param text character code points or Glyphs drawn ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005173#Param byteLength byte length of text array ##
5174#Param path Path providing text baseline ##
Cary Clarkce101242017-09-01 15:51:02 -04005175#Param matrix transform of Glyphs before mapping to path; may be nullptr
Cary Clarka523d2d2017-08-30 08:58:10 -04005176 to use identity Matrix
Cary Clarkbad5ad72017-08-03 17:14:08 -04005177##
5178#Param paint text size, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005179
5180#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04005181 void draw(SkCanvas* canvas) {
5182 const char roller[] = "rollercoaster";
5183 const size_t len = sizeof(roller) - 1;
5184 SkPath path;
5185 path.cubicTo(40, -80, 120, 80, 160, -40);
5186 SkPaint paint;
5187 paint.setTextSize(32);
5188 paint.setStyle(SkPaint::kStroke_Style);
5189 SkMatrix matrix;
5190 matrix.setIdentity();
5191 for (int i = 0; i < 3; ++i) {
5192 canvas->translate(25, 60);
5193 canvas->drawPath(path, paint);
5194 canvas->drawTextOnPath(roller, len, path, &matrix, paint);
5195 matrix.preTranslate(0, 10);
5196 }
5197 }
Cary Clark8032b982017-07-28 11:04:54 -04005198##
5199
5200#ToDo incomplete ##
5201
5202##
5203
5204# ------------------------------------------------------------------------------
5205
5206#Method void drawTextRSXform(const void* text, size_t byteLength, const SkRSXform xform[],
5207 const SkRect* cullRect, const SkPaint& paint)
5208
5209Draw text, transforming each glyph by the corresponding SkRSXform,
5210using Clip, Matrix, and Paint paint.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005211
Cary Clark8032b982017-07-28 11:04:54 -04005212RSXform array specifies a separate square scale, rotation, and translation for
5213each glyph.
Cary Clark8032b982017-07-28 11:04:54 -04005214
Cary Clarkbad5ad72017-08-03 17:14:08 -04005215Optional Rect cullRect is a conservative bounds of text, taking into account
Cary Clarkce101242017-09-01 15:51:02 -04005216RSXform and paint. If cullRect is outside of Clip, canvas can skip drawing.
Cary Clark8032b982017-07-28 11:04:54 -04005217
Cary Clarkbad5ad72017-08-03 17:14:08 -04005218All elements of paint: Path_Effect, Rasterizer, Mask_Filter, Shader,
5219Color_Filter, Image_Filter, and Draw_Looper; apply to text. By default, draws
Cary Clarkce101242017-09-01 15:51:02 -04005220filled 12 point black Glyphs.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005221
Cary Clarkce101242017-09-01 15:51:02 -04005222#Param text character code points or Glyphs drawn ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005223#Param byteLength byte length of text array ##
5224#Param xform RSXform rotates, scales, and translates each glyph individually ##
5225#Param cullRect Rect bounds of text for efficient clipping; or nullptr ##
5226#Param paint text size, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005227
5228#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04005229void draw(SkCanvas* canvas) {
5230 const int iterations = 26;
5231 SkRSXform transforms[iterations];
5232 char alphabet[iterations];
5233 SkScalar angle = 0;
5234 SkScalar scale = 1;
5235 for (size_t i = 0; i < SK_ARRAY_COUNT(transforms); ++i) {
5236 const SkScalar s = SkScalarSin(angle) * scale;
5237 const SkScalar c = SkScalarCos(angle) * scale;
5238 transforms[i] = SkRSXform::Make(-c, -s, -s * 16, c * 16);
5239 angle += .45;
5240 scale += .2;
5241 alphabet[i] = 'A' + i;
5242 }
5243 SkPaint paint;
5244 paint.setTextAlign(SkPaint::kCenter_Align);
5245 canvas->translate(110, 138);
5246 canvas->drawTextRSXform(alphabet, sizeof(alphabet), transforms, nullptr, paint);
Cary Clark8032b982017-07-28 11:04:54 -04005247}
5248##
5249
5250#ToDo incomplete ##
5251
5252##
5253
5254# ------------------------------------------------------------------------------
5255
5256#Method void drawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y, const SkPaint& paint)
5257
5258Draw Text_Blob blob at (x, y), using Clip, Matrix, and Paint paint.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005259
Cary Clarkce101242017-09-01 15:51:02 -04005260blob contains Glyphs, their positions, and paint attributes specific to text:
Cary Clarkbad5ad72017-08-03 17:14:08 -04005261Typeface, Paint_Text_Size, Paint_Text_Scale_X, Paint_Text_Skew_X,
5262Paint_Text_Align, Paint_Hinting, Anti-alias, Paint_Fake_Bold,
5263Font_Embedded_Bitmaps, Full_Hinting_Spacing, LCD_Text, Linear_Text,
5264Subpixel_Text, and Paint_Vertical_Text.
Cary Clark8032b982017-07-28 11:04:54 -04005265
5266Elements of paint: Path_Effect, Rasterizer, Mask_Filter, Shader, Color_Filter,
5267Image_Filter, and Draw_Looper; apply to blob.
5268
Cary Clarkce101242017-09-01 15:51:02 -04005269#Param blob Glyphs, positions, and their paints' text size, typeface, and so on ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005270#Param x horizontal offset applied to blob ##
5271#Param y vertical offset applied to blob ##
5272#Param paint blend, color, stroking, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005273
5274#Example
5275#Height 120
Cary Clarkbad5ad72017-08-03 17:14:08 -04005276 void draw(SkCanvas* canvas) {
5277 SkTextBlobBuilder textBlobBuilder;
5278 const char bunny[] = "/(^x^)\\";
5279 const int len = sizeof(bunny) - 1;
5280 uint16_t glyphs[len];
5281 SkPaint paint;
5282 paint.textToGlyphs(bunny, len, glyphs);
5283 int runs[] = { 3, 1, 3 };
5284 SkPoint textPos = { 20, 100 };
5285 int glyphIndex = 0;
5286 for (auto runLen : runs) {
5287 paint.setTextSize(1 == runLen ? 20 : 50);
5288 const SkTextBlobBuilder::RunBuffer& run =
5289 textBlobBuilder.allocRun(paint, runLen, textPos.fX, textPos.fY);
5290 memcpy(run.glyphs, &glyphs[glyphIndex], sizeof(glyphs[0]) * runLen);
5291 textPos.fX += paint.measureText(&bunny[glyphIndex], runLen, nullptr);
5292 glyphIndex += runLen;
5293 }
5294 sk_sp<const SkTextBlob> blob = textBlobBuilder.make();
5295 paint.reset();
5296 canvas->drawTextBlob(blob.get(), 0, 0, paint);
Cary Clark8032b982017-07-28 11:04:54 -04005297 }
5298##
5299
5300#ToDo incomplete ##
5301
5302##
5303
5304# ------------------------------------------------------------------------------
5305
5306#Method void drawTextBlob(const sk_sp<SkTextBlob>& blob, SkScalar x, SkScalar y, const SkPaint& paint)
5307
5308Draw Text_Blob blob at (x, y), using Clip, Matrix, and Paint paint.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005309
Cary Clarkce101242017-09-01 15:51:02 -04005310blob contains Glyphs, their positions, and paint attributes specific to text:
Cary Clarkbad5ad72017-08-03 17:14:08 -04005311Typeface, Paint_Text_Size, Paint_Text_Scale_X, Paint_Text_Skew_X,
5312Paint_Text_Align, Paint_Hinting, Anti-alias, Paint_Fake_Bold,
5313Font_Embedded_Bitmaps, Full_Hinting_Spacing, LCD_Text, Linear_Text,
5314Subpixel_Text, and Paint_Vertical_Text.
Cary Clark8032b982017-07-28 11:04:54 -04005315
5316Elements of paint: Path_Effect, Rasterizer, Mask_Filter, Shader, Color_Filter,
5317Image_Filter, and Draw_Looper; apply to blob.
5318
Cary Clarkce101242017-09-01 15:51:02 -04005319#Param blob Glyphs, positions, and their paints' text size, typeface, and so on ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005320#Param x horizontal offset applied to blob ##
5321#Param y vertical offset applied to blob ##
5322#Param paint blend, color, stroking, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005323
5324#Example
5325#Height 120
5326#Description
5327Paint attributes unrelated to text, like color, have no effect on paint in allocated Text_Blob.
5328Paint attributes related to text, like text size, have no effect on paint passed to drawTextBlob.
5329##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005330 void draw(SkCanvas* canvas) {
5331 SkTextBlobBuilder textBlobBuilder;
5332 SkPaint paint;
5333 paint.setTextSize(50);
5334 paint.setColor(SK_ColorRED);
5335 const SkTextBlobBuilder::RunBuffer& run =
5336 textBlobBuilder.allocRun(paint, 1, 20, 100);
5337 run.glyphs[0] = 20;
5338 sk_sp<const SkTextBlob> blob = textBlobBuilder.make();
5339 paint.setTextSize(10);
5340 paint.setColor(SK_ColorBLUE);
5341 canvas->drawTextBlob(blob.get(), 0, 0, paint);
5342 }
Cary Clark8032b982017-07-28 11:04:54 -04005343##
5344
5345#ToDo incomplete ##
5346
5347##
5348
5349# ------------------------------------------------------------------------------
5350
5351#Method void drawPicture(const SkPicture* picture)
5352
5353Draw Picture picture, using Clip and Matrix.
5354Clip and Matrix are unchanged by picture contents, as if
5355save() was called before and restore() was called after drawPicture.
5356
5357Picture records a series of draw commands for later playback.
5358
Cary Clarkbad5ad72017-08-03 17:14:08 -04005359#Param picture recorded drawing commands to play ##
Cary Clark8032b982017-07-28 11:04:54 -04005360
5361#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04005362void draw(SkCanvas* canvas) {
5363 SkPictureRecorder recorder;
5364 SkCanvas* recordingCanvas = recorder.beginRecording(50, 50);
5365 for (auto color : { SK_ColorRED, SK_ColorBLUE, 0xff007f00 } ) {
5366 SkPaint paint;
5367 paint.setColor(color);
5368 recordingCanvas->drawRect({10, 10, 30, 40}, paint);
5369 recordingCanvas->translate(10, 10);
5370 recordingCanvas->scale(1.2f, 1.4f);
5371 }
5372 sk_sp<SkPicture> playback = recorder.finishRecordingAsPicture();
5373 const SkPicture* playbackPtr = playback.get();
5374 canvas->drawPicture(playback);
5375 canvas->scale(2, 2);
5376 canvas->translate(50, 0);
5377 canvas->drawPicture(playback);
Cary Clark8032b982017-07-28 11:04:54 -04005378}
5379##
5380
5381#ToDo incomplete ##
5382
5383##
5384
5385# ------------------------------------------------------------------------------
5386
5387#Method void drawPicture(const sk_sp<SkPicture>& picture)
5388
5389Draw Picture picture, using Clip and Matrix.
5390Clip and Matrix are unchanged by picture contents, as if
5391save() was called before and restore() was called after drawPicture.
5392
5393Picture records a series of draw commands for later playback.
5394
Cary Clarkbad5ad72017-08-03 17:14:08 -04005395#Param picture recorded drawing commands to play ##
Cary Clark8032b982017-07-28 11:04:54 -04005396
5397#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04005398void draw(SkCanvas* canvas) {
5399 SkPictureRecorder recorder;
5400 SkCanvas* recordingCanvas = recorder.beginRecording(50, 50);
5401 for (auto color : { SK_ColorRED, SK_ColorBLUE, 0xff007f00 } ) {
5402 SkPaint paint;
5403 paint.setColor(color);
5404 recordingCanvas->drawRect({10, 10, 30, 40}, paint);
5405 recordingCanvas->translate(10, 10);
5406 recordingCanvas->scale(1.2f, 1.4f);
5407 }
5408 sk_sp<SkPicture> playback = recorder.finishRecordingAsPicture();
5409 canvas->drawPicture(playback);
5410 canvas->scale(2, 2);
5411 canvas->translate(50, 0);
5412 canvas->drawPicture(playback);
Cary Clark8032b982017-07-28 11:04:54 -04005413}
5414##
5415
5416#ToDo incomplete ##
5417
5418##
5419
5420# ------------------------------------------------------------------------------
5421
5422#Method void drawPicture(const SkPicture* picture, const SkMatrix* matrix, const SkPaint* paint)
5423
Cary Clarkbad5ad72017-08-03 17:14:08 -04005424Draw Picture picture, using Clip and Matrix; transforming picture with
5425Matrix matrix, if provided; and use Paint paint Color_Alpha, Color_Filter,
5426Image_Filter, and Blend_Mode, if provided.
Cary Clark8032b982017-07-28 11:04:54 -04005427
5428matrix transformation is equivalent to: save(), concat(), drawPicture, restore().
5429paint use is equivalent to: saveLayer, drawPicture, restore().
5430
Cary Clarkbad5ad72017-08-03 17:14:08 -04005431#Param picture recorded drawing commands to play ##
5432#Param matrix Matrix to rotate, scale, translate, and so on; may be nullptr ##
5433#Param paint Paint to apply transparency, filtering, and so on; may be nullptr ##
Cary Clark8032b982017-07-28 11:04:54 -04005434
5435#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04005436void draw(SkCanvas* canvas) {
5437 SkPaint paint;
5438 SkPictureRecorder recorder;
5439 SkCanvas* recordingCanvas = recorder.beginRecording(50, 50);
5440 for (auto color : { SK_ColorRED, SK_ColorBLUE, 0xff007f00 } ) {
5441 paint.setColor(color);
5442 recordingCanvas->drawRect({10, 10, 30, 40}, paint);
5443 recordingCanvas->translate(10, 10);
5444 recordingCanvas->scale(1.2f, 1.4f);
5445 }
5446 sk_sp<SkPicture> playback = recorder.finishRecordingAsPicture();
5447 const SkPicture* playbackPtr = playback.get();
5448 SkMatrix matrix;
5449 matrix.reset();
5450 for (auto alpha : { 70, 140, 210 } ) {
5451 paint.setAlpha(alpha);
5452 canvas->drawPicture(playbackPtr, &matrix, &paint);
5453 matrix.preTranslate(70, 70);
5454 }
Cary Clark8032b982017-07-28 11:04:54 -04005455}
5456##
5457
5458#ToDo incomplete ##
5459
5460##
5461
5462# ------------------------------------------------------------------------------
5463
5464#Method void drawPicture(const sk_sp<SkPicture>& picture, const SkMatrix* matrix, const SkPaint* paint)
5465
Cary Clarkbad5ad72017-08-03 17:14:08 -04005466Draw Picture picture, using Clip and Matrix; transforming picture with
5467Matrix matrix, if provided; and use Paint paint Color_Alpha, Color_Filter,
5468Image_Filter, and Blend_Mode, if provided.
Cary Clark8032b982017-07-28 11:04:54 -04005469
5470matrix transformation is equivalent to: save(), concat(), drawPicture, restore().
5471paint use is equivalent to: saveLayer, drawPicture, restore().
5472
Cary Clarkbad5ad72017-08-03 17:14:08 -04005473#Param picture recorded drawing commands to play ##
5474#Param matrix Matrix to rotate, scale, translate, and so on; may be nullptr ##
5475#Param paint Paint to apply transparency, filtering, and so on; may be nullptr ##
Cary Clark8032b982017-07-28 11:04:54 -04005476
5477#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04005478void draw(SkCanvas* canvas) {
5479 SkPaint paint;
5480 SkPictureRecorder recorder;
5481 SkCanvas* recordingCanvas = recorder.beginRecording(50, 50);
5482 for (auto color : { SK_ColorRED, SK_ColorBLUE, 0xff007f00 } ) {
5483 paint.setColor(color);
5484 recordingCanvas->drawRect({10, 10, 30, 40}, paint);
5485 recordingCanvas->translate(10, 10);
5486 recordingCanvas->scale(1.2f, 1.4f);
5487 }
5488 sk_sp<SkPicture> playback = recorder.finishRecordingAsPicture();
5489 SkMatrix matrix;
5490 matrix.reset();
5491 for (auto alpha : { 70, 140, 210 } ) {
5492 paint.setAlpha(alpha);
5493 canvas->drawPicture(playback, &matrix, &paint);
5494 matrix.preTranslate(70, 70);
5495 }
Cary Clark8032b982017-07-28 11:04:54 -04005496}
5497##
5498
5499#ToDo incomplete ##
5500
5501##
5502
5503# ------------------------------------------------------------------------------
5504
5505#Method void drawVertices(const SkVertices* vertices, SkBlendMode mode, const SkPaint& paint)
5506
5507Draw Vertices vertices, a triangle mesh, using Clip and Matrix.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005508If Vertices_Texs and Vertices_Colors are defined in vertices, and Paint paint
5509contains Shader, Blend_Mode mode combines Vertices_Colors with Shader.
Cary Clark8032b982017-07-28 11:04:54 -04005510
Cary Clarkbad5ad72017-08-03 17:14:08 -04005511#Param vertices triangle mesh to draw ##
5512#Param mode combines Vertices_Colors with Shader, if both are present ##
5513#Param paint specifies the Shader, used as Vertices texture; may be nullptr ##
Cary Clark8032b982017-07-28 11:04:54 -04005514
5515#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04005516void draw(SkCanvas* canvas) {
5517 SkPaint paint;
5518 SkPoint points[] = { { 0, 0 }, { 250, 0 }, { 100, 100 }, { 0, 250 } };
5519 SkColor colors[] = { SK_ColorRED, SK_ColorBLUE, SK_ColorYELLOW, SK_ColorCYAN };
5520 auto vertices = SkVertices::MakeCopy(SkVertices::kTriangleFan_VertexMode,
5521 SK_ARRAY_COUNT(points), points, nullptr, colors);
5522 canvas->drawVertices(vertices.get(), SkBlendMode::kSrc, paint);
5523}
Cary Clark8032b982017-07-28 11:04:54 -04005524##
5525
5526#ToDo incomplete ##
5527
5528##
5529
5530# ------------------------------------------------------------------------------
5531
5532#Method void drawVertices(const sk_sp<SkVertices>& vertices, SkBlendMode mode, const SkPaint& paint)
5533
5534Draw Vertices vertices, a triangle mesh, using Clip and Matrix.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005535If Vertices_Texs and Vertices_Colors are defined in vertices, and Paint paint
5536contains Shader, Blend_Mode mode combines Vertices_Colors with Shader.
Cary Clark8032b982017-07-28 11:04:54 -04005537
Cary Clarkbad5ad72017-08-03 17:14:08 -04005538#Param vertices triangle mesh to draw ##
5539#Param mode combines Vertices_Colors with Shader, if both are present ##
5540#Param paint specifies the Shader, used as Vertices texture, may be nullptr ##
Cary Clark8032b982017-07-28 11:04:54 -04005541
5542#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04005543void draw(SkCanvas* canvas) {
5544 SkPaint paint;
5545 SkPoint points[] = { { 0, 0 }, { 250, 0 }, { 100, 100 }, { 0, 250 } };
5546 SkPoint texs[] = { { 0, 0 }, { 0, 250 }, { 250, 250 }, { 250, 0 } };
5547 SkColor colors[] = { SK_ColorRED, SK_ColorBLUE, SK_ColorYELLOW, SK_ColorCYAN };
5548 paint.setShader(SkGradientShader::MakeLinear(points, colors, nullptr, 4,
5549 SkShader::kClamp_TileMode));
5550 auto vertices = SkVertices::MakeCopy(SkVertices::kTriangleFan_VertexMode,
5551 SK_ARRAY_COUNT(points), points, texs, colors);
5552 canvas->drawVertices(vertices.get(), SkBlendMode::kDarken, paint);
Cary Clark8032b982017-07-28 11:04:54 -04005553}
5554##
5555
5556#ToDo incomplete ##
5557
5558##
5559
5560# ------------------------------------------------------------------------------
5561
5562#Method void drawPatch(const SkPoint cubics[12], const SkColor colors[4],
5563 const SkPoint texCoords[4], SkBlendMode mode, const SkPaint& paint)
5564
Cary Clarkce101242017-09-01 15:51:02 -04005565Draws a Coons patch: the interpolation of four cubics with shared corners,
Cary Clark8032b982017-07-28 11:04:54 -04005566associating a color, and optionally a texture coordinate, with each corner.
5567
Cary Clarkbc5697d2017-10-04 14:31:33 -04005568The Coons patch uses Clip and Matrix, paint Shader, Color_Filter,
Cary Clarkbad5ad72017-08-03 17:14:08 -04005569Color_Alpha, Image_Filter, and Blend_Mode. If Shader is provided it is treated
5570as the Coons patch texture; Blend_Mode mode combines Color colors and Shader if
5571both are provided.
Cary Clark8032b982017-07-28 11:04:54 -04005572
Cary Clarkbc5697d2017-10-04 14:31:33 -04005573Point array cubics specifies four Cubics starting at the top-left corner,
Cary Clarkce101242017-09-01 15:51:02 -04005574in clockwise order, sharing every fourth point. The last Cubic ends at the
Cary Clarkbad5ad72017-08-03 17:14:08 -04005575first point.
Cary Clark8032b982017-07-28 11:04:54 -04005576
Cary Clarkbc5697d2017-10-04 14:31:33 -04005577Color array color associates colors with corners in top-left, top-right,
5578bottom-right, bottom-left order.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005579
5580If paint contains Shader, Point array texCoords maps Shader as texture to
Cary Clarkbc5697d2017-10-04 14:31:33 -04005581corners in top-left, top-right, bottom-right, bottom-left order.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005582
Cary Clarka523d2d2017-08-30 08:58:10 -04005583#Param cubics Path_Cubic array, sharing common points ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005584#Param colors Color array, one for each corner ##
Cary Clarkce101242017-09-01 15:51:02 -04005585#Param texCoords Point array of texture coordinates, mapping Shader to corners;
Cary Clarkbad5ad72017-08-03 17:14:08 -04005586 may be nullptr
Cary Clark579985c2017-07-31 11:48:27 -04005587#Param ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005588#Param mode Blend_Mode for colors, and for Shader if paint has one ##
5589#Param paint Shader, Color_Filter, Blend_Mode, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005590
5591#Example
5592#Image 5
Cary Clarkbad5ad72017-08-03 17:14:08 -04005593void draw(SkCanvas* canvas) {
5594 // SkBitmap source = cmbkygk;
5595 SkPaint paint;
5596 paint.setFilterQuality(kLow_SkFilterQuality);
5597 paint.setAntiAlias(true);
5598 SkPoint cubics[] = { { 3, 1 }, { 4, 2 }, { 5, 1 }, { 7, 3 },
5599 /* { 7, 3 }, */ { 6, 4 }, { 7, 5 }, { 5, 7 },
5600 /* { 5, 7 }, */ { 4, 6 }, { 3, 7 }, { 1, 5 },
5601 /* { 1, 5 }, */ { 2, 4 }, { 1, 3 }, /* { 3, 1 } */ };
5602 SkColor colors[] = { 0xbfff0000, 0xbf0000ff, 0xbfff00ff, 0xbf00ffff };
5603 SkPoint texCoords[] = { { -30, -30 }, { 162, -30}, { 162, 162}, { -30, 162} };
5604 paint.setShader(SkShader::MakeBitmapShader(source, SkShader::kClamp_TileMode,
5605 SkShader::kClamp_TileMode, nullptr));
5606 canvas->scale(15, 15);
5607 for (auto blend : { SkBlendMode::kSrcOver, SkBlendMode::kModulate, SkBlendMode::kXor } ) {
5608 canvas->drawPatch(cubics, colors, texCoords, blend, paint);
5609 canvas->translate(4, 4);
5610 }
Cary Clark8032b982017-07-28 11:04:54 -04005611}
5612##
5613
Cary Clarkbad5ad72017-08-03 17:14:08 -04005614#ToDo incomplete; can patch use image filter? ##
Cary Clark8032b982017-07-28 11:04:54 -04005615
5616##
5617
5618# ------------------------------------------------------------------------------
5619
5620#Method void drawPatch(const SkPoint cubics[12], const SkColor colors[4],
5621 const SkPoint texCoords[4], const SkPaint& paint)
5622
Cary Clarkce101242017-09-01 15:51:02 -04005623Draws Cubic Coons patch: the interpolation of four cubics with shared corners,
Cary Clarkbad5ad72017-08-03 17:14:08 -04005624associating a color, and optionally a texture coordinate, with each corner.
Cary Clark8032b982017-07-28 11:04:54 -04005625
Cary Clarkbc5697d2017-10-04 14:31:33 -04005626The Coons patch uses Clip and Matrix, paint Shader, Color_Filter,
Cary Clarkbad5ad72017-08-03 17:14:08 -04005627Color_Alpha, Image_Filter, and Blend_Mode. If Shader is provided it is treated
5628as the Coons patch texture; Blend_Mode mode combines Color colors and Shader if
5629both are provided.
Cary Clark8032b982017-07-28 11:04:54 -04005630
Cary Clarkbc5697d2017-10-04 14:31:33 -04005631Point array cubics specifies four Cubics starting at the top-left corner,
Cary Clarkce101242017-09-01 15:51:02 -04005632in clockwise order, sharing every fourth point. The last Cubic ends at the
Cary Clarkbad5ad72017-08-03 17:14:08 -04005633first point.
5634
Cary Clarkbc5697d2017-10-04 14:31:33 -04005635Color array color associates colors with corners in top-left, top-right,
5636bottom-right, bottom-left order.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005637
5638If paint contains Shader, Point array texCoords maps Shader as texture to
Cary Clarkbc5697d2017-10-04 14:31:33 -04005639corners in top-left, top-right, bottom-right, bottom-left order.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005640
Cary Clarka523d2d2017-08-30 08:58:10 -04005641#Param cubics Path_Cubic array, sharing common points ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005642#Param colors Color array, one for each corner ##
Cary Clarkce101242017-09-01 15:51:02 -04005643#Param texCoords Point array of texture coordinates, mapping Shader to corners;
Cary Clarkbad5ad72017-08-03 17:14:08 -04005644 may be nullptr
Cary Clark579985c2017-07-31 11:48:27 -04005645#Param ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005646#Param paint Shader, Color_Filter, Blend_Mode, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005647
5648#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04005649void draw(SkCanvas* canvas) {
5650 SkPaint paint;
5651 paint.setAntiAlias(true);
5652 SkPoint cubics[] = { { 3, 1 }, { 4, 2 }, { 5, 1 }, { 7, 3 },
5653 /* { 7, 3 }, */ { 6, 4 }, { 7, 5 }, { 5, 7 },
5654 /* { 5, 7 }, */ { 4, 6 }, { 3, 7 }, { 1, 5 },
5655 /* { 1, 5 }, */ { 2, 4 }, { 1, 3 }, /* { 3, 1 } */ };
5656 SkColor colors[] = { SK_ColorRED, SK_ColorBLUE, SK_ColorYELLOW, SK_ColorCYAN };
5657 canvas->scale(30, 30);
5658 canvas->drawPatch(cubics, colors, nullptr, paint);
5659 SkPoint text[] = { {3,0.9f}, {4,2.5f}, {5,0.9f}, {7.5f,3.2f}, {5.5f,4.2f},
5660 {7.5f,5.2f}, {5,7.5f}, {4,5.9f}, {3,7.5f}, {0.5f,5.2f}, {2.5f,4.2f},
5661 {0.5f,3.2f} };
5662 paint.setTextSize(18.f / 30);
5663 paint.setTextAlign(SkPaint::kCenter_Align);
5664 for (int i = 0; i< 10; ++i) {
5665 char digit = '0' + i;
5666 canvas->drawText(&digit, 1, text[i].fX, text[i].fY, paint);
5667 }
5668 canvas->drawString("10", text[10].fX, text[10].fY, paint);
5669 canvas->drawString("11", text[11].fX, text[11].fY, paint);
5670 paint.setStyle(SkPaint::kStroke_Style);
5671 canvas->drawPoints(SkCanvas::kPolygon_PointMode, 12, cubics, paint);
5672 canvas->drawLine(cubics[11].fX, cubics[11].fY, cubics[0].fX, cubics[0].fY, paint);
Cary Clark8032b982017-07-28 11:04:54 -04005673}
5674##
5675
5676#Example
5677#Image 6
Cary Clarkbad5ad72017-08-03 17:14:08 -04005678void draw(SkCanvas* canvas) {
5679 // SkBitmap source = checkerboard;
5680 SkPaint paint;
5681 paint.setFilterQuality(kLow_SkFilterQuality);
5682 paint.setAntiAlias(true);
5683 SkPoint cubics[] = { { 3, 1 }, { 4, 2 }, { 5, 1 }, { 7, 3 },
5684 /* { 7, 3 }, */ { 6, 4 }, { 7, 5 }, { 5, 7 },
5685 /* { 5, 7 }, */ { 4, 6 }, { 3, 7 }, { 1, 5 },
5686 /* { 1, 5 }, */ { 2, 4 }, { 1, 3 }, /* { 3, 1 } */ };
5687 SkPoint texCoords[] = { { 0, 0 }, { 0, 62}, { 62, 62}, { 62, 0 } };
5688 paint.setShader(SkShader::MakeBitmapShader(source, SkShader::kClamp_TileMode,
5689 SkShader::kClamp_TileMode, nullptr));
5690 canvas->scale(30, 30);
5691 canvas->drawPatch(cubics, nullptr, texCoords, paint);
Cary Clark8032b982017-07-28 11:04:54 -04005692}
5693##
5694
Cary Clarkbad5ad72017-08-03 17:14:08 -04005695#ToDo incomplete; can patch use image filter? ##
Cary Clark8032b982017-07-28 11:04:54 -04005696
5697##
5698
5699# ------------------------------------------------------------------------------
5700
5701#Method void drawAtlas(const SkImage* atlas, const SkRSXform xform[], const SkRect tex[],
5702 const SkColor colors[], int count, SkBlendMode mode, const SkRect* cullRect,
5703 const SkPaint* paint)
5704
5705Draw a set of sprites from atlas, using Clip, Matrix, and optional Paint paint.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005706paint uses Anti-alias, Color_Alpha, Color_Filter, Image_Filter, and Blend_Mode
5707to draw, if present. For each entry in the array, Rect tex locates sprite in
5708atlas, and RSXform xform transforms it into destination space.
5709
Cary Clark8032b982017-07-28 11:04:54 -04005710xform, text, and colors if present, must contain count entries.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005711Optional colors are applied for each sprite using Blend_Mode.
Cary Clark8032b982017-07-28 11:04:54 -04005712Optional cullRect is a conservative bounds of all transformed sprites.
Cary Clarkce101242017-09-01 15:51:02 -04005713If cullRect is outside of Clip, canvas can skip drawing.
Cary Clark8032b982017-07-28 11:04:54 -04005714
Cary Clarkbad5ad72017-08-03 17:14:08 -04005715#Param atlas Image containing sprites ##
5716#Param xform RSXform mappings for sprites in atlas ##
5717#Param tex Rect locations of sprites in atlas ##
Cary Clark6fc50412017-09-21 12:31:06 -04005718#Param colors one per sprite, blended with sprite using Blend_Mode; may be nullptr ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005719#Param count number of sprites to draw ##
5720#Param mode Blend_Mode combining colors and sprites ##
Cary Clark6fc50412017-09-21 12:31:06 -04005721#Param cullRect bounds of transformed sprites for efficient clipping; may be nullptr ##
5722#Param paint Color_Filter, Image_Filter, Blend_Mode, and so on; may be nullptr ##
Cary Clark8032b982017-07-28 11:04:54 -04005723
5724#Example
5725#Image 3
Cary Clarkbad5ad72017-08-03 17:14:08 -04005726void draw(SkCanvas* canvas) {
5727 // SkBitmap source = mandrill;
5728 SkRSXform xforms[] = { { .5f, 0, 0, 0 }, {0, .5f, 200, 100 } };
5729 SkRect tex[] = { { 0, 0, 250, 250 }, { 0, 0, 250, 250 } };
5730 SkColor colors[] = { 0x7f55aa00, 0x7f3333bf };
5731 const SkImage* imagePtr = image.get();
5732 canvas->drawAtlas(imagePtr, xforms, tex, colors, 2, SkBlendMode::kSrcOver, nullptr, nullptr);
Cary Clark8032b982017-07-28 11:04:54 -04005733}
5734##
5735
5736#ToDo incomplete ##
5737
5738##
5739
5740# ------------------------------------------------------------------------------
5741
5742#Method void drawAtlas(const sk_sp<SkImage>& atlas, const SkRSXform xform[], const SkRect tex[],
5743 const SkColor colors[], int count, SkBlendMode mode, const SkRect* cullRect,
5744 const SkPaint* paint)
5745
5746Draw a set of sprites from atlas, using Clip, Matrix, and optional Paint paint.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005747paint uses Anti-alias, Color_Alpha, Color_Filter, Image_Filter, and Blend_Mode
5748to draw, if present. For each entry in the array, Rect tex locates sprite in
5749atlas, and RSXform xform transforms it into destination space.
5750
Cary Clark8032b982017-07-28 11:04:54 -04005751xform, text, and colors if present, must contain count entries.
5752Optional colors is applied for each sprite using Blend_Mode.
5753Optional cullRect is a conservative bounds of all transformed sprites.
Cary Clarkce101242017-09-01 15:51:02 -04005754If cullRect is outside of Clip, canvas can skip drawing.
Cary Clark8032b982017-07-28 11:04:54 -04005755
Cary Clarkbad5ad72017-08-03 17:14:08 -04005756#Param atlas Image containing sprites ##
5757#Param xform RSXform mappings for sprites in atlas ##
5758#Param tex Rect locations of sprites in atlas ##
Cary Clark6fc50412017-09-21 12:31:06 -04005759#Param colors one per sprite, blended with sprite using Blend_Mode; may be nullptr ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005760#Param count number of sprites to draw ##
5761#Param mode Blend_Mode combining colors and sprites ##
Cary Clark6fc50412017-09-21 12:31:06 -04005762#Param cullRect bounds of transformed sprites for efficient clipping; may be nullptr ##
5763#Param paint Color_Filter, Image_Filter, Blend_Mode, and so on; may be nullptr ##
Cary Clark8032b982017-07-28 11:04:54 -04005764
5765#Example
5766#Image 3
Cary Clarkbad5ad72017-08-03 17:14:08 -04005767void draw(SkCanvas* canvas) {
5768 // SkBitmap source = mandrill;
5769 SkRSXform xforms[] = { { .5f, 0, 0, 0 }, {0, .5f, 200, 100 } };
5770 SkRect tex[] = { { 0, 0, 250, 250 }, { 0, 0, 250, 250 } };
5771 SkColor colors[] = { 0x7f55aa00, 0x7f3333bf };
5772 SkPaint paint;
5773 paint.setAlpha(127);
5774 canvas->drawAtlas(image, xforms, tex, colors, 2, SkBlendMode::kPlus, nullptr, &paint);
Cary Clark8032b982017-07-28 11:04:54 -04005775}
5776##
5777
5778#ToDo bug in example on cpu side, gpu looks ok ##
5779
5780##
5781
5782# ------------------------------------------------------------------------------
5783
5784#Method void drawAtlas(const SkImage* atlas, const SkRSXform xform[], const SkRect tex[], int count,
5785 const SkRect* cullRect, const SkPaint* paint)
5786
5787Draw a set of sprites from atlas, using Clip, Matrix, and optional Paint paint.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005788paint uses Anti-alias, Color_Alpha, Color_Filter, Image_Filter, and Blend_Mode
5789to draw, if present. For each entry in the array, Rect tex locates sprite in
5790atlas, and RSXform xform transforms it into destination space.
5791
Cary Clark8032b982017-07-28 11:04:54 -04005792xform and text must contain count entries.
5793Optional cullRect is a conservative bounds of all transformed sprites.
Cary Clarkce101242017-09-01 15:51:02 -04005794If cullRect is outside of Clip, canvas can skip drawing.
Cary Clark8032b982017-07-28 11:04:54 -04005795
Cary Clarkbad5ad72017-08-03 17:14:08 -04005796#Param atlas Image containing sprites ##
5797#Param xform RSXform mappings for sprites in atlas ##
5798#Param tex Rect locations of sprites in atlas ##
5799#Param count number of sprites to draw ##
Cary Clark6fc50412017-09-21 12:31:06 -04005800#Param cullRect bounds of transformed sprites for efficient clipping; may be nullptr ##
5801#Param paint Color_Filter, Image_Filter, Blend_Mode, and so on; may be nullptr ##
Cary Clark8032b982017-07-28 11:04:54 -04005802
5803#Example
5804#Image 3
Cary Clarkbad5ad72017-08-03 17:14:08 -04005805void draw(SkCanvas* canvas) {
5806 // sk_sp<SkImage> image = mandrill;
5807 SkRSXform xforms[] = { { .5f, 0, 0, 0 }, {0, .5f, 200, 100 } };
5808 SkRect tex[] = { { 0, 0, 250, 250 }, { 0, 0, 250, 250 } };
5809 const SkImage* imagePtr = image.get();
5810 canvas->drawAtlas(imagePtr, xforms, tex, 2, nullptr, nullptr);
Cary Clark8032b982017-07-28 11:04:54 -04005811}
5812##
5813
5814#ToDo incomplete ##
5815
5816##
5817
5818# ------------------------------------------------------------------------------
5819
5820#Method void drawAtlas(const sk_sp<SkImage>& atlas, const SkRSXform xform[], const SkRect tex[],
5821 int count, const SkRect* cullRect, const SkPaint* paint)
5822
5823Draw a set of sprites from atlas, using Clip, Matrix, and optional Paint paint.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005824paint uses Anti-alias, Color_Alpha, Color_Filter, Image_Filter, and Blend_Mode
5825to draw, if present. For each entry in the array, Rect tex locates sprite in
5826atlas, and RSXform xform transforms it into destination space.
5827
Cary Clark8032b982017-07-28 11:04:54 -04005828xform and text must contain count entries.
5829Optional cullRect is a conservative bounds of all transformed sprites.
Cary Clarkce101242017-09-01 15:51:02 -04005830If cullRect is outside of Clip, canvas can skip drawing.
Cary Clark8032b982017-07-28 11:04:54 -04005831
Cary Clarkbad5ad72017-08-03 17:14:08 -04005832#Param atlas Image containing sprites ##
5833#Param xform RSXform mappings for sprites in atlas ##
5834#Param tex Rect locations of sprites in atlas ##
5835#Param count number of sprites to draw ##
Cary Clark6fc50412017-09-21 12:31:06 -04005836#Param cullRect bounds of transformed sprites for efficient clipping; may be nullptr ##
5837#Param paint Color_Filter, Image_Filter, Blend_Mode, and so on; may be nullptr ##
Cary Clark8032b982017-07-28 11:04:54 -04005838
5839#Example
5840#Image 3
Cary Clarkbad5ad72017-08-03 17:14:08 -04005841void draw(SkCanvas* canvas) {
5842 // sk_sp<SkImage> image = mandrill;
5843 SkRSXform xforms[] = { { 1, 0, 0, 0 }, {0, 1, 300, 100 } };
5844 SkRect tex[] = { { 0, 0, 200, 200 }, { 200, 0, 400, 200 } };
5845 canvas->drawAtlas(image, xforms, tex, 2, nullptr, nullptr);
Cary Clark8032b982017-07-28 11:04:54 -04005846}
5847##
5848
5849#ToDo incomplete ##
5850
5851##
5852
5853# ------------------------------------------------------------------------------
5854
Cary Clark73fa9722017-08-29 17:36:51 -04005855#Method void drawDrawable(SkDrawable* drawable, const SkMatrix* matrix = nullptr)
Cary Clark8032b982017-07-28 11:04:54 -04005856
5857Draw Drawable drawable using Clip and Matrix, concatenated with
5858optional matrix.
5859
5860If Canvas has an asynchronous implementation, as is the case
5861when it is recording into Picture, then drawable will be referenced,
5862so that SkDrawable::draw() can be called when the operation is finalized. To force
5863immediate drawing, call SkDrawable::draw() instead.
5864
Cary Clarkbad5ad72017-08-03 17:14:08 -04005865#Param drawable custom struct encapsulating drawing commands ##
5866#Param matrix transformation applied to drawing; may be nullptr ##
Cary Clark8032b982017-07-28 11:04:54 -04005867
5868#Example
5869#Height 100
5870#Function
Cary Clarkbad5ad72017-08-03 17:14:08 -04005871struct MyDrawable : public SkDrawable {
5872 SkRect onGetBounds() override { return SkRect::MakeWH(50, 100); }
5873
5874 void onDraw(SkCanvas* canvas) override {
5875 SkPath path;
5876 path.conicTo(10, 90, 50, 90, 0.9f);
5877 SkPaint paint;
5878 paint.setColor(SK_ColorBLUE);
5879 canvas->drawRect(path.getBounds(), paint);
5880 paint.setAntiAlias(true);
5881 paint.setColor(SK_ColorWHITE);
5882 canvas->drawPath(path, paint);
5883 }
5884};
5885
5886#Function ##
5887void draw(SkCanvas* canvas) {
5888 sk_sp<SkDrawable> drawable(new MyDrawable);
5889 SkMatrix matrix;
5890 matrix.setTranslate(10, 10);
5891 canvas->drawDrawable(drawable.get(), &matrix);
Cary Clark8032b982017-07-28 11:04:54 -04005892}
5893##
5894
5895#ToDo incomplete ##
5896
5897##
5898
5899# ------------------------------------------------------------------------------
5900
5901#Method void drawDrawable(SkDrawable* drawable, SkScalar x, SkScalar y)
5902
5903Draw Drawable drawable using Clip and Matrix, offset by (x, y).
5904
5905If Canvas has an asynchronous implementation, as is the case
5906when it is recording into Picture, then drawable will be referenced,
5907so that SkDrawable::draw() can be called when the operation is finalized. To force
5908immediate drawing, call SkDrawable::draw() instead.
5909
Cary Clarkbad5ad72017-08-03 17:14:08 -04005910#Param drawable custom struct encapsulating drawing commands ##
5911#Param x offset into Canvas writable pixels in x ##
5912#Param y offset into Canvas writable pixels in y ##
Cary Clark8032b982017-07-28 11:04:54 -04005913
5914#Example
5915#Height 100
5916#Function
Cary Clarkbad5ad72017-08-03 17:14:08 -04005917struct MyDrawable : public SkDrawable {
5918 SkRect onGetBounds() override { return SkRect::MakeWH(50, 100); }
5919
5920 void onDraw(SkCanvas* canvas) override {
5921 SkPath path;
5922 path.conicTo(10, 90, 50, 90, 0.9f);
5923 SkPaint paint;
5924 paint.setColor(SK_ColorBLUE);
5925 canvas->drawRect(path.getBounds(), paint);
5926 paint.setAntiAlias(true);
5927 paint.setColor(SK_ColorWHITE);
5928 canvas->drawPath(path, paint);
5929 }
5930};
5931
5932#Function ##
5933void draw(SkCanvas* canvas) {
5934 sk_sp<SkDrawable> drawable(new MyDrawable);
5935 canvas->drawDrawable(drawable.get(), 10, 10);
Cary Clark8032b982017-07-28 11:04:54 -04005936}
5937##
5938
5939#ToDo incomplete ##
5940
5941##
5942
5943# ------------------------------------------------------------------------------
5944
5945#Method void drawAnnotation(const SkRect& rect, const char key[], SkData* value)
5946
5947Associate Rect on Canvas when an annotation; a key-value pair, where the key is
5948a null-terminated utf8 string, and optional value is stored as Data.
5949
5950Only some canvas implementations, such as recording to Picture, or drawing to
5951Document_PDF, use annotations.
5952
Cary Clarkbad5ad72017-08-03 17:14:08 -04005953#Param rect Rect extent of canvas to annotate ##
5954#Param key string used for lookup ##
5955#Param value data holding value stored in annotation ##
Cary Clark8032b982017-07-28 11:04:54 -04005956
5957#Example
5958 #Height 1
5959 const char text[] = "Click this link!";
5960 SkRect bounds;
5961 SkPaint paint;
5962 paint.setTextSize(40);
5963 (void)paint.measureText(text, strlen(text), &bounds);
5964 const char url[] = "https://www.google.com/";
5965 sk_sp<SkData> urlData(SkData::MakeWithCString(url));
5966 canvas->drawAnnotation(bounds, "url_key", urlData.get());
5967##
5968
5969#ToDo incomplete ##
5970
5971##
5972
5973# ------------------------------------------------------------------------------
5974
5975#Method void drawAnnotation(const SkRect& rect, const char key[], const sk_sp<SkData>& value)
5976
5977Associate Rect on Canvas when an annotation; a key-value pair, where the key is
5978a null-terminated utf8 string, and optional value is stored as Data.
5979
5980Only some canvas implementations, such as recording to Picture, or drawing to
5981Document_PDF, use annotations.
5982
Cary Clarkbad5ad72017-08-03 17:14:08 -04005983#Param rect Rect extent of canvas to annotate ##
5984#Param key string used for lookup ##
5985#Param value data holding value stored in annotation ##
Cary Clark8032b982017-07-28 11:04:54 -04005986
5987#Example
5988#Height 1
5989 const char text[] = "Click this link!";
5990 SkRect bounds;
5991 SkPaint paint;
5992 paint.setTextSize(40);
5993 (void)paint.measureText(text, strlen(text), &bounds);
5994 const char url[] = "https://www.google.com/";
5995 sk_sp<SkData> urlData(SkData::MakeWithCString(url));
5996 canvas->drawAnnotation(bounds, "url_key", urlData.get());
5997##
5998
5999#ToDo incomplete ##
6000
6001##
6002
6003#Method SkDrawFilter* getDrawFilter() const
6004
6005Legacy call to be deprecated.
6006
6007#Deprecated
6008##
6009
6010##
6011
6012#Method virtual SkDrawFilter* setDrawFilter(SkDrawFilter* filter)
6013
6014Legacy call to be deprecated.
6015
6016#Deprecated
6017##
6018
6019##
6020
6021# ------------------------------------------------------------------------------
6022
6023#Method virtual bool isClipEmpty() const
6024
6025Returns true if Clip is empty; that is, nothing will draw.
6026
Cary Clarkbad5ad72017-08-03 17:14:08 -04006027May do work when called; it should not be called
Cary Clark8032b982017-07-28 11:04:54 -04006028more often than needed. However, once called, subsequent calls perform no
6029work until Clip changes.
6030
Cary Clarkbad5ad72017-08-03 17:14:08 -04006031#Return true if Clip is empty ##
Cary Clark8032b982017-07-28 11:04:54 -04006032
6033#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04006034 void draw(SkCanvas* canvas) {
6035 SkDebugf("clip is%s empty\n", canvas->isClipEmpty() ? "" : " not");
6036 SkPath path;
6037 canvas->clipPath(path);
6038 SkDebugf("clip is%s empty\n", canvas->isClipEmpty() ? "" : " not");
Cary Clark8032b982017-07-28 11:04:54 -04006039 }
6040 #StdOut
Cary Clarkbad5ad72017-08-03 17:14:08 -04006041 clip is not empty
Cary Clark8032b982017-07-28 11:04:54 -04006042 clip is empty
6043 ##
6044##
6045
6046#ToDo incomplete ##
6047
6048##
6049
6050# ------------------------------------------------------------------------------
6051
6052#Method virtual bool isClipRect() const
6053
6054Returns true if Clip is Rect and not empty.
6055Returns false if the clip is empty, or if it is not Rect.
6056
Cary Clarkbad5ad72017-08-03 17:14:08 -04006057#Return true if Clip is Rect and not empty ##
Cary Clark8032b982017-07-28 11:04:54 -04006058
6059#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04006060 void draw(SkCanvas* canvas) {
6061 SkDebugf("clip is%s rect\n", canvas->isClipRect() ? "" : " not");
6062 canvas->clipRect({0, 0, 0, 0});
6063 SkDebugf("clip is%s rect\n", canvas->isClipRect() ? "" : " not");
Cary Clark8032b982017-07-28 11:04:54 -04006064 }
6065 #StdOut
Cary Clarkbad5ad72017-08-03 17:14:08 -04006066 clip is rect
Cary Clark8032b982017-07-28 11:04:54 -04006067 clip is not rect
6068 ##
6069##
6070
6071#ToDo incomplete ##
6072
6073##
6074
6075#Class SkCanvas ##
Cary Clark884dd7d2017-10-11 10:37:52 -04006076
6077#Class SkAutoCanvasRestore
6078
6079Stack helper class calls SkCanvas::restoreToCount() when SkAutoCanvasRestore
6080goes out of scope. Use this to guarantee that the canvas is restored to a known
6081state.
6082
6083#Method SkAutoCanvasRestore(SkCanvas* canvas, bool doSave)
6084
6085Preserves Canvas save count. Optionally saves Canvas Clip and Matrix.
6086
6087#Param canvas Canvas to guard ##
6088#Param doSave call SkCanvas::save() ##
6089
6090#Return utility to restore Canvas state on destructor ##
6091
6092#Example
6093// incomplete
6094##
6095
6096#SeeAlso SkCanvas::save SkCanvas::restore
6097
6098##
6099
6100#Method ~SkAutoCanvasRestore()
6101
6102Restores Canvas to saved state.
6103
6104#Example
6105// incomplete
6106##
6107
6108#SeeAlso SkCanvas::save SkCanvas::restore
6109
6110##
6111
6112#Method void restore()
6113
Cary Clark154beea2017-10-26 07:58:48 -04006114Restores Canvas to saved state immediately. Subsequent calls and
6115~SkAutoCanvasRestore have no effect.
Cary Clark884dd7d2017-10-11 10:37:52 -04006116
6117#Example
6118// incomplete
6119##
6120
6121#SeeAlso SkCanvas::save SkCanvas::restore
6122
6123##
6124
6125#Class SkAutoCanvasRestore ##
6126
Cary Clark8032b982017-07-28 11:04:54 -04006127#Topic Canvas ##