blob: 486fe46d715c9bf9c2695c0e3e2b7bc2a56ec39c [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 Clarkf05bdda2017-08-24 12:59:48 -0400978Copies rectangle of pixels from Canvas into dstPixels. Matrix and Clip are
979ignored. Source rectangle corners are (srcX, srcY) and
Cary Clarkce101242017-09-01 15:51:02 -0400980#Formula
981(this->imageInfo.width(), this->imageInfo.height())
982##
Cary Clark6fc50412017-09-21 12:31:06 -0400983.
984
985Destination rectangle corners are (0, 0) and (bitmap.width(), bitmap.height()).
986Copies each readable pixel intersecting both rectangles, without scaling,
Cary Clarkf05bdda2017-08-24 12:59:48 -0400987converting to dstInfo.colorType() and dstInfo.alphaType() if required.
Cary Clark8032b982017-07-28 11:04:54 -0400988
Cary Clarkf05bdda2017-08-24 12:59:48 -0400989Pixels are readable when Device is raster, or backed by a GPU.
990Pixels are not readable when SkCanvas is returned by SkDocument::beginPage,
991returned by SkPictureRecorder::beginRecording, or Canvas is the base of a utility
992class like SkDumpCanvas.
Cary Clark8032b982017-07-28 11:04:54 -0400993
Cary Clarkf05bdda2017-08-24 12:59:48 -0400994The destination pixel storage must be allocated by the caller.
Cary Clark8032b982017-07-28 11:04:54 -0400995
Cary Clarkf05bdda2017-08-24 12:59:48 -0400996Pixel values are converted only if Image_Color_Type and Image_Alpha_Type
997do not match. Only pixels within both source and destination rectangles
998are copied. dstPixels contents outside the rectangle intersection are unchanged.
999
1000Pass negative values for srcX or srcY to offset pixels across or down destination.
Cary Clark8032b982017-07-28 11:04:54 -04001001
1002Does not copy, and returns false if:
1003
1004#List
Cary Clarkf05bdda2017-08-24 12:59:48 -04001005# Source and destination rectangles do not intersect. ##
1006# Canvas pixels could not be converted to dstInfo.colorType() or dstInfo.alphaType(). ##
1007# Canvas pixels are not readable; for instance, Canvas is document-based. ##
Cary Clark8032b982017-07-28 11:04:54 -04001008# dstRowBytes is too small to contain one row of pixels. ##
1009##
1010
Cary Clarkf05bdda2017-08-24 12:59:48 -04001011#Param dstInfo width, height, Image_Color_Type, and Image_Alpha_Type of dstPixels ##
1012#Param dstPixels storage for pixels; dstInfo.height() times dstRowBytes, or larger ##
1013#Param dstRowBytes size of one destination row; dstInfo.width() times pixel size, or larger ##
1014#Param srcX offset into readable pixels in x; may be negative ##
1015#Param srcY offset into readable pixels in y; may be negative ##
Cary Clark8032b982017-07-28 11:04:54 -04001016
Cary Clarkbad5ad72017-08-03 17:14:08 -04001017#Return true if pixels were copied ##
Cary Clark8032b982017-07-28 11:04:54 -04001018
1019#Example
Cary Clarkf05bdda2017-08-24 12:59:48 -04001020#Width 64
1021#Height 64
1022#Description
1023 A black circle drawn on a blue background provides an image to copy.
1024 readPixels copies one quarter of the canvas into each of the four corners.
Cary Clarkce101242017-09-01 15:51:02 -04001025 The Layer draws over the image.
Cary Clarkf05bdda2017-08-24 12:59:48 -04001026##
1027 canvas->clear(SK_ColorBLUE);
1028 SkPaint paint;
1029 canvas->drawCircle(32, 32, 28, paint);
1030 SkImageInfo info = SkImageInfo::Make(64, 64, kBGRA_8888_SkColorType, kPremul_SkAlphaType);
1031 sk_sp<SkData> data(SkData::MakeUninitialized(info.minRowBytes() * info.height()));
1032 sk_bzero(data->writable_data(), info.minRowBytes() * info.height());
1033 for (int x : { 32, -32 } ) {
1034 for (int y : { 32, -32 } ) {
1035 canvas->readPixels(info, data->writable_data(), info.minRowBytes(), x, y);
1036 }
1037 }
1038 sk_sp<SkImage> image = SkImage::MakeRasterData(info, data, info.minRowBytes());
1039 canvas->drawImage(image, 0, 0);
1040##
1041
1042#Example
Cary Clark8032b982017-07-28 11:04:54 -04001043#Description
Cary Clarkce101242017-09-01 15:51:02 -04001044 Canvas returned by Raster_Surface has Premultiplied pixel values.
1045 clear() takes Unpremultiplied input with Color_Alpha equal 0x80
1046 and Color_RGB equal 0x55, 0xAA, 0xFF. Color_RGB is multiplied by Color_Alpha
1047 to generate Premultiplied value 0x802B5580. readPixels converts pixel back
1048 to Unpremultiplied value 0x8056A9FF, introducing error.
Cary Clark8032b982017-07-28 11:04:54 -04001049##
1050 canvas->clear(0x8055aaff);
1051 for (SkAlphaType alphaType : { kPremul_SkAlphaType, kUnpremul_SkAlphaType } ) {
1052 uint32_t pixel = 0;
1053 SkImageInfo info = SkImageInfo::Make(1, 1, kBGRA_8888_SkColorType, alphaType);
1054 if (canvas->readPixels(info, &pixel, 4, 0, 0)) {
1055 SkDebugf("pixel = %08x\n", pixel);
1056 }
1057 }
1058
1059 #StdOut
1060 pixel = 802b5580
1061 pixel = 8056a9ff
1062 ##
1063##
1064
Cary Clarkf05bdda2017-08-24 12:59:48 -04001065#SeeAlso peekPixels writePixels drawBitmap drawImage
Cary Clark8032b982017-07-28 11:04:54 -04001066
1067##
1068
1069# ------------------------------------------------------------------------------
1070
1071#Method bool readPixels(const SkPixmap& pixmap, int srcX, int srcY)
1072
Cary Clarkf05bdda2017-08-24 12:59:48 -04001073Copies rectangle of pixels from Canvas into pixmap. Matrix and Clip are
1074ignored. Source rectangle corners are (srcX, srcY) and
Cary Clarkce101242017-09-01 15:51:02 -04001075#Formula
1076(this->imageInfo.width(), this->imageInfo.height())
1077##
Cary Clark6fc50412017-09-21 12:31:06 -04001078.
1079
1080Destination rectangle corners are (0, 0) and (bitmap.width(), bitmap.height()).
1081Copies each readable pixel intersecting both rectangles, without scaling,
Cary Clarkf05bdda2017-08-24 12:59:48 -04001082converting to pixmap.colorType() and pixmap.alphaType() if required.
Cary Clark8032b982017-07-28 11:04:54 -04001083
Cary Clarkf05bdda2017-08-24 12:59:48 -04001084Pixels are readable when Device is raster, or backed by a GPU.
1085Pixels are not readable when SkCanvas is returned by SkDocument::beginPage,
1086returned by SkPictureRecorder::beginRecording, or Canvas is the base of a utility
1087class like SkDumpCanvas.
Cary Clark8032b982017-07-28 11:04:54 -04001088
Cary Clark6fc50412017-09-21 12:31:06 -04001089Caller must allocate pixel storage in pixmap if needed.
Cary Clark8032b982017-07-28 11:04:54 -04001090
Cary Clarkf05bdda2017-08-24 12:59:48 -04001091Pixel values are converted only if Image_Color_Type and Image_Alpha_Type
1092do not match. Only pixels within both source and destination rectangles
1093are copied. pixmap pixels contents outside the rectangle intersection are unchanged.
1094
1095Pass negative values for srcX or srcY to offset pixels across or down pixmap.
Cary Clark8032b982017-07-28 11:04:54 -04001096
1097Does not copy, and returns false if:
1098
1099#List
Cary Clarkf05bdda2017-08-24 12:59:48 -04001100# Source and destination rectangles do not intersect. ##
1101# Canvas pixels could not be converted to pixmap.colorType() or pixmap.alphaType(). ##
1102# Canvas pixels are not readable; for instance, Canvas is document-based. ##
1103# Pixmap pixels could not be allocated. ##
1104# pixmap.rowBytes() is too small to contain one row of pixels. ##
Cary Clark8032b982017-07-28 11:04:54 -04001105##
1106
Cary Clarkbad5ad72017-08-03 17:14:08 -04001107#Param pixmap storage for pixels copied from Canvas ##
Cary Clarkf05bdda2017-08-24 12:59:48 -04001108#Param srcX offset into readable pixels in x; may be negative ##
1109#Param srcY offset into readable pixels in y; may be negative ##
Cary Clark8032b982017-07-28 11:04:54 -04001110
Cary Clarkbad5ad72017-08-03 17:14:08 -04001111#Return true if pixels were copied ##
Cary Clark8032b982017-07-28 11:04:54 -04001112
1113#Example
Cary Clarkf05bdda2017-08-24 12:59:48 -04001114 #Description
Cary Clarkce101242017-09-01 15:51:02 -04001115 clear() takes Unpremultiplied input with Color_Alpha equal 0x80
1116 and Color_RGB equal 0x55, 0xAA, 0xFF. Color_RGB is multiplied by Color_Alpha
1117 to generate Premultiplied value 0x802B5580.
Cary Clarkf05bdda2017-08-24 12:59:48 -04001118 ##
1119 void draw(SkCanvas* canvas) {
1120 canvas->clear(0x8055aaff);
1121 uint32_t pixels[1] = { 0 };
1122 SkPixmap pixmap(SkImageInfo::MakeN32Premul(1, 1), pixels, 4);
1123 canvas->readPixels(pixmap, 0, 0);
1124 SkDebugf("pixel = %08x\n", pixels[0]);
1125 }
Cary Clark8032b982017-07-28 11:04:54 -04001126 #StdOut
1127 pixel = 802b5580
1128 ##
1129##
1130
Cary Clarkf05bdda2017-08-24 12:59:48 -04001131#SeeAlso peekPixels writePixels drawBitmap drawImage
Cary Clark8032b982017-07-28 11:04:54 -04001132
1133##
1134
1135# ------------------------------------------------------------------------------
1136
1137#Method bool readPixels(const SkBitmap& bitmap, int srcX, int srcY)
1138
Cary Clarkf05bdda2017-08-24 12:59:48 -04001139Copies rectangle of pixels from Canvas into bitmap. Matrix and Clip are
1140ignored. Source rectangle corners are (srcX, srcY) and
Cary Clarkce101242017-09-01 15:51:02 -04001141#Formula
1142(this->imageInfo.width(), this->imageInfo.height())
1143##
Cary Clark6fc50412017-09-21 12:31:06 -04001144.
1145
1146Destination rectangle corners are (0, 0) and (bitmap.width(), bitmap.height()).
Cary Clarkf05bdda2017-08-24 12:59:48 -04001147Copies each readable pixel intersecting both rectangles, without scaling,
1148converting to bitmap.colorType() and bitmap.alphaType() if required.
Cary Clark8032b982017-07-28 11:04:54 -04001149
Cary Clarkf05bdda2017-08-24 12:59:48 -04001150Pixels are readable when Device is raster, or backed by a GPU.
1151Pixels are not readable when SkCanvas is returned by SkDocument::beginPage,
1152returned by SkPictureRecorder::beginRecording, or Canvas is the base of a utility
1153class like SkDumpCanvas.
Cary Clark8032b982017-07-28 11:04:54 -04001154
Cary Clark6fc50412017-09-21 12:31:06 -04001155Caller must allocate pixel storage in bitmap if needed.
Cary Clarkf05bdda2017-08-24 12:59:48 -04001156
1157Bitmap values are converted only if Image_Color_Type and Image_Alpha_Type
1158do not match. Only pixels within both source and destination rectangles
1159are copied. Bitmap pixels outside the rectangle intersection are unchanged.
1160
1161Pass negative values for srcX or srcY to offset pixels across or down bitmap.
Cary Clark8032b982017-07-28 11:04:54 -04001162
1163Does not copy, and returns false if:
1164
1165#List
Cary Clarkf05bdda2017-08-24 12:59:48 -04001166# Source and destination rectangles do not intersect. ##
1167# Canvas pixels could not be converted to bitmap.colorType() or bitmap.alphaType(). ##
1168# Canvas pixels are not readable; for instance, Canvas is document-based. ##
Cary Clark8032b982017-07-28 11:04:54 -04001169# bitmap pixels could not be allocated. ##
Cary Clarkf05bdda2017-08-24 12:59:48 -04001170# bitmap.rowBytes() is too small to contain one row of pixels. ##
Cary Clark8032b982017-07-28 11:04:54 -04001171##
1172
Cary Clarkbad5ad72017-08-03 17:14:08 -04001173#Param bitmap storage for pixels copied from Canvas ##
Cary Clarkf05bdda2017-08-24 12:59:48 -04001174#Param srcX offset into readable pixels in x; may be negative ##
1175#Param srcY offset into readable pixels in y; may be negative ##
Cary Clark8032b982017-07-28 11:04:54 -04001176
Cary Clarkbad5ad72017-08-03 17:14:08 -04001177#Return true if pixels were copied ##
Cary Clark8032b982017-07-28 11:04:54 -04001178
1179#Example
Cary Clarkf05bdda2017-08-24 12:59:48 -04001180 #Description
Cary Clarkce101242017-09-01 15:51:02 -04001181 clear() takes Unpremultiplied input with Color_Alpha equal 0x80
1182 and Color_RGB equal 0x55, 0xAA, 0xFF. Color_RGB is multiplied by Color_Alpha
1183 to generate Premultiplied value 0x802B5580.
Cary Clarkf05bdda2017-08-24 12:59:48 -04001184 ##
Cary Clark8032b982017-07-28 11:04:54 -04001185void draw(SkCanvas* canvas) {
1186 canvas->clear(0x8055aaff);
1187 SkBitmap bitmap;
1188 bitmap.allocPixels(SkImageInfo::MakeN32Premul(1, 1));
1189 canvas->readPixels(bitmap, 0, 0);
1190 SkDebugf("pixel = %08x\n", bitmap.getAddr32(0, 0)[0]);
1191}
1192 #StdOut
1193 pixel = 802b5580
1194 ##
1195##
1196
Cary Clarkf05bdda2017-08-24 12:59:48 -04001197#SeeAlso peekPixels writePixels drawBitmap drawImage
Cary Clark8032b982017-07-28 11:04:54 -04001198
1199##
1200
1201# ------------------------------------------------------------------------------
1202
1203#Method bool writePixels(const SkImageInfo& info, const void* pixels, size_t rowBytes, int x, int y)
1204
Cary Clarkf05bdda2017-08-24 12:59:48 -04001205Copies rectangle from pixels to Canvas. Matrix and Clip are ignored.
1206Source rectangle corners are (0, 0) and (info.width(), info.height()).
1207Destination rectangle corners are (x, y) and
Cary Clarkce101242017-09-01 15:51:02 -04001208#Formula
1209(this->imageInfo.width(), this->imageInfo.height())
1210##
Cary Clark6fc50412017-09-21 12:31:06 -04001211.
1212
1213Copies each readable pixel intersecting both rectangles, without scaling,
1214converting to
Cary Clarkce101242017-09-01 15:51:02 -04001215#Formula
1216this->imageInfo.colorType()
1217##
1218and
1219#Formula
1220this->imageInfo.alphaType()
1221##
1222if required.
Cary Clark8032b982017-07-28 11:04:54 -04001223
Cary Clarkf05bdda2017-08-24 12:59:48 -04001224Pixels are writable when Device is raster, or backed by a GPU.
1225Pixels are not writable when SkCanvas is returned by SkDocument::beginPage,
1226returned by SkPictureRecorder::beginRecording, or Canvas is the base of a utility
1227class like SkDumpCanvas.
Cary Clark8032b982017-07-28 11:04:54 -04001228
Cary Clarkf05bdda2017-08-24 12:59:48 -04001229Pixel values are converted only if Image_Color_Type and Image_Alpha_Type
1230do not match. Only pixels within both source and destination rectangles
1231are copied. Canvas pixels outside the rectangle intersection are unchanged.
Cary Clark8032b982017-07-28 11:04:54 -04001232
Cary Clarkf05bdda2017-08-24 12:59:48 -04001233Pass negative values for x or y to offset pixels to the left or
1234above Canvas pixels.
Cary Clark8032b982017-07-28 11:04:54 -04001235
1236Does not copy, and returns false if:
1237
1238#List
Cary Clarkf05bdda2017-08-24 12:59:48 -04001239# Source and destination rectangles do not intersect. ##
Cary Clark6fc50412017-09-21 12:31:06 -04001240# pixels could not be converted to this->imageInfo.colorType() or
1241this->imageInfo.alphaType(). ##
Cary Clark8032b982017-07-28 11:04:54 -04001242# Canvas pixels are not writable; for instance, Canvas is document-based. ##
1243# rowBytes is too small to contain one row of pixels. ##
1244##
1245
Cary Clarkf05bdda2017-08-24 12:59:48 -04001246#Param info width, height, Image_Color_Type, and Image_Alpha_Type of pixels ##
1247#Param pixels pixels to copy, of size info.height() times rowBytes, or larger ##
Cary Clarkd0530ba2017-09-14 11:25:39 -04001248#Param rowBytes size of one row of pixels; info.width() times pixel size, or larger ##
Cary Clarkf05bdda2017-08-24 12:59:48 -04001249#Param x offset into Canvas writable pixels in x; may be negative ##
1250#Param y offset into Canvas writable pixels in y; may be negative ##
Cary Clark8032b982017-07-28 11:04:54 -04001251
Cary Clarkbad5ad72017-08-03 17:14:08 -04001252#Return true if pixels were written to Canvas ##
Cary Clark8032b982017-07-28 11:04:54 -04001253
1254#Example
1255 SkImageInfo imageInfo = SkImageInfo::MakeN32(256, 1, kPremul_SkAlphaType);
1256 for (int y = 0; y < 256; ++y) {
1257 uint32_t pixels[256];
1258 for (int x = 0; x < 256; ++x) {
1259 pixels[x] = SkColorSetARGB(x, x + y, x, x - y);
1260 }
1261 canvas->writePixels(imageInfo, &pixels, sizeof(pixels), 0, y);
1262 }
1263##
1264
Cary Clarkf05bdda2017-08-24 12:59:48 -04001265#SeeAlso readPixels drawBitmap drawImage
Cary Clark8032b982017-07-28 11:04:54 -04001266
1267##
1268
1269# ------------------------------------------------------------------------------
1270
1271#Method bool writePixels(const SkBitmap& bitmap, int x, int y)
1272
Cary Clarkf05bdda2017-08-24 12:59:48 -04001273Copies rectangle from pixels to Canvas. Matrix and Clip are ignored.
Cary Clark6fc50412017-09-21 12:31:06 -04001274Source rectangle corners are (0, 0) and (bitmap.width(), bitmap.height()).
1275
Cary Clarkf05bdda2017-08-24 12:59:48 -04001276Destination rectangle corners are (x, y) and
Cary Clarkce101242017-09-01 15:51:02 -04001277#Formula
1278(this->imageInfo.width(), this->imageInfo.height())
1279##
Cary Clark6fc50412017-09-21 12:31:06 -04001280.
1281
1282Copies each readable pixel intersecting both rectangles, without scaling,
1283converting to
Cary Clarkce101242017-09-01 15:51:02 -04001284#Formula
1285this->imageInfo.colorType()
1286##
1287and
1288#Formula
1289this->imageInfo.alphaType()
1290##
1291if required.
Cary Clark8032b982017-07-28 11:04:54 -04001292
Cary Clarkf05bdda2017-08-24 12:59:48 -04001293Pixels are writable when Device is raster, or backed by a GPU.
1294Pixels are not writable when SkCanvas is returned by SkDocument::beginPage,
1295returned by SkPictureRecorder::beginRecording, or Canvas is the base of a utility
1296class like SkDumpCanvas.
Cary Clark8032b982017-07-28 11:04:54 -04001297
Cary Clarkf05bdda2017-08-24 12:59:48 -04001298Pixel values are converted only if Image_Color_Type and Image_Alpha_Type
1299do not match. Only pixels within both source and destination rectangles
1300are copied. Canvas pixels outside the rectangle intersection are unchanged.
Cary Clark8032b982017-07-28 11:04:54 -04001301
Cary Clarkf05bdda2017-08-24 12:59:48 -04001302Pass negative values for x or y to offset pixels to the left or
1303above Canvas pixels.
Cary Clark8032b982017-07-28 11:04:54 -04001304
1305Does not copy, and returns false if:
1306
1307#List
Cary Clarkf05bdda2017-08-24 12:59:48 -04001308# Source and destination rectangles do not intersect. ##
Cary Clark8032b982017-07-28 11:04:54 -04001309# bitmap does not have allocated pixels. ##
Cary Clark6fc50412017-09-21 12:31:06 -04001310# bitmap pixels could not be converted to this->imageInfo.colorType() or
1311this->imageInfo.alphaType(). ##
Cary Clarkce101242017-09-01 15:51:02 -04001312# Canvas pixels are not writable; for instance, Canvas is document based. ##
Cary Clark8032b982017-07-28 11:04:54 -04001313# bitmap pixels are inaccessible; for instance, bitmap wraps a texture. ##
1314##
1315
Cary Clarkbad5ad72017-08-03 17:14:08 -04001316#Param bitmap contains pixels copied to Canvas ##
Cary Clarkf05bdda2017-08-24 12:59:48 -04001317#Param x offset into Canvas writable pixels in x; may be negative ##
1318#Param y offset into Canvas writable pixels in y; may be negative ##
Cary Clark8032b982017-07-28 11:04:54 -04001319
Cary Clarkbad5ad72017-08-03 17:14:08 -04001320#Return true if pixels were written to Canvas ##
Cary Clark8032b982017-07-28 11:04:54 -04001321
1322#Example
1323void draw(SkCanvas* canvas) {
1324 SkImageInfo imageInfo = SkImageInfo::MakeN32Premul(2, 2);
1325 SkBitmap bitmap;
1326 bitmap.setInfo(imageInfo);
1327 uint32_t pixels[4];
1328 bitmap.setPixels(pixels);
1329 for (int y = 0; y < 256; y += 2) {
1330 for (int x = 0; x < 256; x += 2) {
1331 pixels[0] = SkColorSetRGB(x, y, x | y);
1332 pixels[1] = SkColorSetRGB(x ^ y, y, x);
1333 pixels[2] = SkColorSetRGB(x, x & y, y);
1334 pixels[3] = SkColorSetRGB(~x, ~y, x);
1335 canvas->writePixels(bitmap, x, y);
1336 }
1337 }
1338}
1339##
1340
Cary Clarkf05bdda2017-08-24 12:59:48 -04001341#SeeAlso readPixels drawBitmap drawImage
Cary Clark8032b982017-07-28 11:04:54 -04001342
1343##
1344
1345# ------------------------------------------------------------------------------
1346#Topic State_Stack
1347
1348Canvas maintains a stack of state that allows hierarchical drawing, commonly used
Cary Clarkbad5ad72017-08-03 17:14:08 -04001349to implement windows and views. The initial state has an identity matrix and and
1350an infinite clip. Even with a wide-open clip, drawing is constrained by the
1351bounds of the Canvas Surface or Device.
Cary Clark8032b982017-07-28 11:04:54 -04001352
1353Canvas savable state consists of Clip, Matrix, and Draw_Filter.
1354Clip describes the area that may be drawn to.
1355Matrix transforms the geometry.
1356Draw_Filter (deprecated on most platforms) modifies the paint before drawing.
1357
1358save(), saveLayer, saveLayerPreserveLCDTextRequests, and saveLayerAlpha
1359save state and return the depth of the stack.
1360
Cary Clarkbad5ad72017-08-03 17:14:08 -04001361restore(), restoreToCount, and ~SkCanvas() revert state to its value when saved.
Cary Clark8032b982017-07-28 11:04:54 -04001362
1363Each state on the stack intersects Clip with the previous Clip,
1364and concatenates Matrix with the previous Matrix.
1365The intersected Clip makes the drawing area the same or smaller;
1366the concatenated Matrix may move the origin and potentially scale or rotate
1367the coordinate space.
1368
1369Canvas does not require balancing the state stack but it is a good idea
1370to do so. Calling save() without restore() will eventually cause Skia to fail;
1371mismatched save() and restore() create hard to find bugs.
1372
1373It is not possible to use state to draw outside of the clip defined by the
1374previous state.
1375
1376#Example
1377#Description
1378Draw to ever smaller clips; then restore drawing to full canvas.
1379Note that the second clipRect is not permitted to enlarge Clip.
1380##
1381#Height 160
Cary Clarkbad5ad72017-08-03 17:14:08 -04001382void draw(SkCanvas* canvas) {
1383 SkPaint paint;
1384 canvas->save(); // records stack depth to restore
1385 canvas->clipRect(SkRect::MakeWH(100, 100)); // constrains drawing to clip
1386 canvas->clear(SK_ColorRED); // draws to limit of clip
1387 canvas->save(); // records stack depth to restore
1388 canvas->clipRect(SkRect::MakeWH(50, 150)); // Rect below 100 is ignored
1389 canvas->clear(SK_ColorBLUE); // draws to smaller clip
1390 canvas->restore(); // enlarges clip
1391 canvas->drawLine(20, 20, 150, 150, paint); // line below 100 is not drawn
1392 canvas->restore(); // enlarges clip
1393 canvas->drawLine(150, 20, 50, 120, paint); // line below 100 is drawn
Cary Clark8032b982017-07-28 11:04:54 -04001394}
1395##
1396
1397Each Clip uses the current Matrix for its coordinates.
1398
1399#Example
1400#Description
1401While clipRect is given the same rectangle twice, Matrix makes the second
1402clipRect draw at half the size of the first.
1403##
1404#Height 128
Cary Clarkbad5ad72017-08-03 17:14:08 -04001405void draw(SkCanvas* canvas) {
1406 canvas->clipRect(SkRect::MakeWH(100, 100));
1407 canvas->clear(SK_ColorRED);
1408 canvas->scale(.5, .5);
1409 canvas->clipRect(SkRect::MakeWH(100, 100));
1410 canvas->clear(SK_ColorBLUE);
Cary Clark8032b982017-07-28 11:04:54 -04001411}
1412##
1413
1414#SeeAlso save() saveLayer saveLayerPreserveLCDTextRequests saveLayerAlpha restore() restoreToCount
1415
1416#Method int save()
1417
1418Saves Matrix, Clip, and Draw_Filter (Draw_Filter deprecated on most platforms).
1419Calling restore() discards changes to Matrix, Clip, and Draw_Filter,
1420restoring the Matrix, Clip, and Draw_Filter to their state when save() was called.
1421
Cary Clarkbad5ad72017-08-03 17:14:08 -04001422Matrix may be changed by translate(), scale(), rotate(), skew(), concat(), setMatrix,
1423and resetMatrix. Clip may be changed by clipRect, clipRRect, clipPath, clipRegion.
Cary Clark8032b982017-07-28 11:04:54 -04001424
Cary Clarkbad5ad72017-08-03 17:14:08 -04001425Saved Canvas state is put on a stack; multiple calls to save() should be balance
1426by an equal number of calls to restore().
Cary Clark8032b982017-07-28 11:04:54 -04001427
1428Call restoreToCount with result to restore this and subsequent saves.
1429
Cary Clarkbad5ad72017-08-03 17:14:08 -04001430#Return depth of saved stack ##
Cary Clark8032b982017-07-28 11:04:54 -04001431
1432#Example
1433#Description
1434The black square is translated 50 pixels down and to the right.
1435Restoring Canvas state removes translate() from Canvas stack;
1436the red square is not translated, and is drawn at the origin.
1437##
1438#Height 100
1439void draw(SkCanvas* canvas) {
1440 SkPaint paint;
1441 SkRect rect = { 0, 0, 25, 25 };
1442 canvas->drawRect(rect, paint);
1443 canvas->save();
1444 canvas->translate(50, 50);
1445 canvas->drawRect(rect, paint);
1446 canvas->restore();
1447 paint.setColor(SK_ColorRED);
1448 canvas->drawRect(rect, paint);
1449}
1450##
1451
1452#ToDo incomplete ##
1453
1454##
1455
1456# ------------------------------------------------------------------------------
Cary Clark8032b982017-07-28 11:04:54 -04001457
1458#Method void restore()
1459
1460Removes changes to Matrix, Clip, and Draw_Filter since Canvas state was
1461last saved. The state is removed from the stack.
1462
1463Does nothing if the stack is empty.
1464
1465#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04001466void draw(SkCanvas* canvas) {
1467 SkCanvas simple;
1468 SkDebugf("depth = %d\n", simple.getSaveCount());
1469 simple.restore();
1470 SkDebugf("depth = %d\n", simple.getSaveCount());
Cary Clark8032b982017-07-28 11:04:54 -04001471}
1472##
1473
1474##
1475
1476# ------------------------------------------------------------------------------
1477
1478#Method int getSaveCount() const
1479
1480Returns the number of saved states, each containing: Matrix, Clip, and Draw_Filter.
1481Equals the number of save() calls less the number of restore() calls plus one.
1482The save count of a new canvas is one.
1483
Cary Clarkbad5ad72017-08-03 17:14:08 -04001484#Return depth of save state stack ##
Cary Clark8032b982017-07-28 11:04:54 -04001485
1486#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04001487void draw(SkCanvas* canvas) {
1488 SkCanvas simple;
1489 SkDebugf("depth = %d\n", simple.getSaveCount());
1490 simple.save();
1491 SkDebugf("depth = %d\n", simple.getSaveCount());
1492 simple.restore();
1493 SkDebugf("depth = %d\n", simple.getSaveCount());
Cary Clark8032b982017-07-28 11:04:54 -04001494}
1495#StdOut
Cary Clarkbad5ad72017-08-03 17:14:08 -04001496depth = 1
1497depth = 2
Cary Clark8032b982017-07-28 11:04:54 -04001498depth = 1
1499##
1500##
1501
1502##
1503
1504# ------------------------------------------------------------------------------
1505
1506#Method void restoreToCount(int saveCount)
1507
Cary Clarkbad5ad72017-08-03 17:14:08 -04001508Restores state to Matrix, Clip, and Draw_Filter values when save(), saveLayer,
1509saveLayerPreserveLCDTextRequests, or saveLayerAlpha returned saveCount.
Cary Clark8032b982017-07-28 11:04:54 -04001510
1511Does nothing if saveCount is greater than state stack count.
1512Restores state to initial values if saveCount is less than or equal to one.
1513
Cary Clarkbad5ad72017-08-03 17:14:08 -04001514#Param saveCount depth of state stack to restore ##
Cary Clark8032b982017-07-28 11:04:54 -04001515
1516#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04001517void draw(SkCanvas* canvas) {
1518 SkDebugf("depth = %d\n", canvas->getSaveCount());
1519 canvas->save();
1520 canvas->save();
1521 SkDebugf("depth = %d\n", canvas->getSaveCount());
1522 canvas->restoreToCount(0);
1523 SkDebugf("depth = %d\n", canvas->getSaveCount());
Cary Clark8032b982017-07-28 11:04:54 -04001524}
1525#StdOut
Cary Clarkbad5ad72017-08-03 17:14:08 -04001526depth = 1
1527depth = 3
Cary Clark8032b982017-07-28 11:04:54 -04001528depth = 1
1529##
1530##
1531
1532##
1533
1534#Topic State_Stack ##
1535
1536# ------------------------------------------------------------------------------
Cary Clarkce101242017-09-01 15:51:02 -04001537
1538#Topic Layer
Cary Clarkd0530ba2017-09-14 11:25:39 -04001539#Substitute layer
Cary Clarkce101242017-09-01 15:51:02 -04001540#Alias Layers
1541
1542Layer allocates a temporary Bitmap to draw into. When the drawing is
1543complete, the Bitmap is drawn into the Canvas.
1544
1545Layer is saved in a stack along with other saved state. When state with a Layer
1546is restored, the Bitmap is drawn into the previous Layer.
1547
1548Layer may be initialized with the contents of the previous Layer. When Layer is
1549restored, its Bitmap can be modified by Paint passed to Layer to apply
1550Color_Alpha, Color_Filter, Image_Filter, and Blend_Mode.
1551
1552#Method int saveLayer(const SkRect* bounds, const SkPaint* paint)
1553
1554Saves Matrix, Clip, and Draw_Filter (Draw_Filter deprecated on most platforms),
1555and allocates a Bitmap for subsequent drawing.
1556Calling restore() discards changes to Matrix, Clip, and Draw_Filter,
1557and draws the Bitmap.
1558
1559Matrix may be changed by translate(), scale(), rotate(), skew(), concat(),
1560setMatrix, and resetMatrix. Clip may be changed by clipRect, clipRRect,
1561clipPath, clipRegion.
1562
1563Rect bounds suggests but does not define the Bitmap size. To clip drawing to
1564a specific rectangle, use clipRect.
1565
1566Optional Paint paint applies Color_Alpha, Color_Filter, Image_Filter, and
1567Blend_Mode when restore() is called.
1568
1569Call restoreToCount with returned value to restore this and subsequent saves.
1570
1571#Param bounds hint to limit the size of the Layer; may be nullptr ##
1572#Param paint graphics state for Layer; may be nullptr ##
1573
1574#Return depth of saved stack ##
1575
1576#Example
1577#Description
1578Rectangles are blurred by Image_Filter when restore() draws Layer to main
1579Canvas.
1580##
1581#Height 128
1582void draw(SkCanvas* canvas) {
1583 SkPaint paint, blur;
1584 blur.setImageFilter(SkImageFilter::MakeBlur(3, 3, nullptr));
1585 canvas->saveLayer(nullptr, &blur);
1586 SkRect rect = { 25, 25, 50, 50};
1587 canvas->drawRect(rect, paint);
1588 canvas->translate(50, 50);
1589 paint.setColor(SK_ColorRED);
1590 canvas->drawRect(rect, paint);
1591 canvas->restore();
1592}
1593##
1594
1595#ToDo incomplete ##
1596
1597##
1598
1599#Method int saveLayer(const SkRect& bounds, const SkPaint* paint)
1600
1601Saves Matrix, Clip, and Draw_Filter (Draw_Filter deprecated on most platforms),
1602and allocates a Bitmap for subsequent drawing.
1603Calling restore() discards changes to Matrix, Clip, and Draw_Filter,
1604and draws the Bitmap.
1605
1606Matrix may be changed by translate(), scale(), rotate(), skew(), concat(),
1607setMatrix, and resetMatrix. Clip may be changed by clipRect, clipRRect,
1608clipPath, clipRegion.
1609
1610Rect bounds suggests but does not define the Layer size. To clip drawing to
1611a specific rectangle, use clipRect.
1612
1613Optional Paint paint applies Color_Alpha, Color_Filter, Image_Filter, and
1614Blend_Mode when restore() is called.
1615
1616Call restoreToCount with returned value to restore this and subsequent saves.
1617
1618#Param bounds hint to limit the size of Layer; may be nullptr ##
1619#Param paint graphics state for Layer; may be nullptr ##
1620
1621#Return depth of saved stack ##
1622
1623#Example
1624#Description
1625Rectangles are blurred by Image_Filter when restore() draws Layer to main Canvas.
1626The red rectangle is clipped; it does not fully fit on Layer.
1627Image_Filter blurs past edge of Layer so red rectangle is blurred on all sides.
1628##
1629#Height 128
1630void draw(SkCanvas* canvas) {
1631 SkPaint paint, blur;
1632 blur.setImageFilter(SkImageFilter::MakeBlur(3, 3, nullptr));
1633 canvas->saveLayer(SkRect::MakeWH(90, 90), &blur);
1634 SkRect rect = { 25, 25, 50, 50};
1635 canvas->drawRect(rect, paint);
1636 canvas->translate(50, 50);
1637 paint.setColor(SK_ColorRED);
1638 canvas->drawRect(rect, paint);
1639 canvas->restore();
1640}
1641##
1642
1643#ToDo incomplete ##
1644
1645##
1646
1647#Method int saveLayerPreserveLCDTextRequests(const SkRect* bounds, const SkPaint* paint)
1648
1649Saves Matrix, Clip, and Draw_Filter (Draw_Filter deprecated on most platforms),
1650and allocates a Bitmap for subsequent drawing.
1651LCD_Text is preserved when the Layer is drawn to the prior Layer.
1652
1653Calling restore() discards changes to Matrix, Clip, and Draw_Filter,
1654and draws Layer.
1655
1656Matrix may be changed by translate(), scale(), rotate(), skew(), concat(),
1657setMatrix, and resetMatrix. Clip may be changed by clipRect, clipRRect,
1658clipPath, clipRegion.
1659
1660Rect bounds suggests but does not define the Layer size. To clip drawing to
1661a specific rectangle, use clipRect.
1662
1663Optional Paint paint applies Color_Alpha, Color_Filter, Image_Filter, and
1664Blend_Mode when restore() is called.
1665
1666Call restoreToCount with returned value to restore this and subsequent saves.
1667
1668Draw text on an opaque background so that LCD_Text blends correctly with the
1669prior Layer. LCD_Text drawn on a background with transparency may result in
Cary Clark6fc50412017-09-21 12:31:06 -04001670incorrect blending.
Cary Clarkce101242017-09-01 15:51:02 -04001671
1672#Param bounds hint to limit the size of Layer; may be nullptr ##
1673#Param paint graphics state for Layer; may be nullptr ##
1674
1675#Return depth of saved stack ##
1676
1677#Example
1678 SkPaint paint;
1679 paint.setAntiAlias(true);
1680 paint.setLCDRenderText(true);
1681 paint.setTextSize(20);
1682 for (auto preserve : { false, true } ) {
1683 preserve ? canvas->saveLayerPreserveLCDTextRequests(nullptr, nullptr)
1684 : canvas->saveLayer(nullptr, nullptr);
1685 SkPaint p;
1686 p.setColor(SK_ColorWHITE);
1687 // Comment out the next line to draw on a non-opaque background.
1688 canvas->drawRect(SkRect::MakeLTRB(25, 40, 200, 70), p);
1689 canvas->drawString("Hamburgefons", 30, 60, paint);
1690
1691 p.setColor(0xFFCCCCCC);
1692 canvas->drawRect(SkRect::MakeLTRB(25, 70, 200, 100), p);
1693 canvas->drawString("Hamburgefons", 30, 90, paint);
1694
1695 canvas->restore();
1696 canvas->translate(0, 80);
1697 }
1698 ##
1699
1700#ToDo incomplete ##
1701
1702##
1703
1704#Method int saveLayerAlpha(const SkRect* bounds, U8CPU alpha)
1705
1706Saves Matrix, Clip, and Draw_Filter (Draw_Filter deprecated on most platforms),
1707and allocates Bitmap for subsequent drawing.
1708
1709Calling restore() discards changes to Matrix, Clip, and Draw_Filter,
1710and blends Layer with alpha opacity onto prior Layer.
1711
1712Matrix may be changed by translate(), scale(), rotate(), skew(), concat(),
1713setMatrix, and resetMatrix. Clip may be changed by clipRect, clipRRect,
1714clipPath, clipRegion.
1715
1716Rect bounds suggests but does not define Layer size. To clip drawing to
1717a specific rectangle, use clipRect.
1718
1719alpha of zero is fully transparent, 255 is fully opaque.
1720
1721Call restoreToCount with returned value to restore this and subsequent saves.
1722
1723#Param bounds hint to limit the size of Layer; may be nullptr ##
1724#Param alpha opacity of Layer ##
1725
1726#Return depth of saved stack ##
1727
1728#Example
1729 SkPaint paint;
1730 paint.setColor(SK_ColorRED);
1731 canvas->drawCircle(50, 50, 50, paint);
1732 canvas->saveLayerAlpha(nullptr, 128);
1733 paint.setColor(SK_ColorBLUE);
1734 canvas->drawCircle(100, 50, 50, paint);
1735 paint.setColor(SK_ColorGREEN);
1736 paint.setAlpha(128);
1737 canvas->drawCircle(75, 90, 50, paint);
1738 canvas->restore();
1739##
1740
1741#ToDo incomplete ##
1742
1743##
1744
1745#Enum
1746
1747#Code
1748 enum {
1749 kIsOpaque_SaveLayerFlag = 1 << 0,
1750 kPreserveLCDText_SaveLayerFlag = 1 << 1,
1751 kInitWithPrevious_SaveLayerFlag = 1 << 2,
1752 kDontClipToLayer_Legacy_SaveLayerFlag = kDontClipToLayer_PrivateSaveLayerFlag,
1753 };
1754
1755 typedef uint32_t SaveLayerFlags;
1756##
1757
1758SaveLayerFlags provides options that may be used in any combination in SaveLayerRec,
1759defining how Layer allocated by saveLayer operates.
1760
1761#Const kIsOpaque_SaveLayerFlag 1
1762 Creates Layer without transparency. Flag is ignored if Layer Paint contains
1763 Image_Filter or Color_Filter.
1764##
1765
1766#Const kPreserveLCDText_SaveLayerFlag 2
1767 Creates Layer for LCD text. Flag is ignored if Layer Paint contains
1768 Image_Filter or Color_Filter.
1769##
1770
1771#Const kInitWithPrevious_SaveLayerFlag 4
1772 Initializes Layer with the contents of the previous Layer.
1773##
1774
1775#Const kDontClipToLayer_Legacy_SaveLayerFlag 0x80000000
1776#Private
1777 to be deprecated: bug.skia.org/2440
1778##
1779 Only present on Android.
1780 Skips setting a clip to the Layer bounds.
1781##
1782
1783#Example
1784#Height 160
1785#Description
1786Canvas Layer captures red and blue circles scaled up by four.
1787scalePaint blends Layer back with transparency.
1788##
1789void draw(SkCanvas* canvas) {
1790 SkPaint redPaint, bluePaint, scalePaint;
1791 redPaint.setColor(SK_ColorRED);
1792 canvas->drawCircle(21, 21, 8, redPaint);
1793 bluePaint.setColor(SK_ColorBLUE);
1794 canvas->drawCircle(31, 21, 8, bluePaint);
1795 SkMatrix matrix;
1796 matrix.setScale(4, 4);
1797 scalePaint.setAlpha(0x40);
1798 scalePaint.setImageFilter(
1799 SkImageFilter::MakeMatrixFilter(matrix, kNone_SkFilterQuality, nullptr));
1800 SkCanvas::SaveLayerRec saveLayerRec(nullptr, &scalePaint,
1801 SkCanvas::kInitWithPrevious_SaveLayerFlag);
1802 canvas->saveLayer(saveLayerRec);
1803 canvas->restore();
1804}
1805##
1806
1807#ToDo incomplete ##
1808
1809#Enum ##
1810
1811#Struct SaveLayerRec
1812
1813#Code
1814 struct SaveLayerRec {
1815 SaveLayerRec*(...
1816
1817 const SkRect* fBounds;
1818 const SkPaint* fPaint;
1819 const SkImageFilter* fBackdrop;
1820 SaveLayerFlags fSaveLayerFlags;
1821 };
1822##
1823
1824SaveLayerRec contains the state used to create the Layer.
1825
1826#Member const SkRect* fBounds
1827 fBounds is used as a hint to limit the size of Layer; may be nullptr.
1828 fBounds suggests but does not define Layer size. To clip drawing to
1829 a specific rectangle, use clipRect.
1830##
1831
1832#Member const SkPaint* fPaint
1833 fPaint modifies how Layer overlays the prior Layer; may be nullptr.
1834 Color_Alpha, Blend_Mode, Color_Filter, Draw_Looper, Image_Filter, and
1835 Mask_Filter affect Layer draw.
1836##
1837
1838#Member const SkImageFilter* fBackdrop
1839 fBackdrop applies Image_Filter to the prior Layer when copying to the Layer;
1840 may be nullptr. Use kInitWithPrevious_SaveLayerFlag to copy the
1841 prior Layer without an Image_Filter.
1842##
1843
1844#Member const SkImage* fClipMask
1845 restore() clips Layer by the Color_Alpha channel of fClipMask when
1846 Layer is copied to Device. fClipMask may be nullptr. .
1847##
1848
1849#Member const SkMatrix* fClipMatrix
1850 fClipMatrix transforms fClipMask before it clips Layer. If
1851 fClipMask describes a translucent gradient, it may be scaled and rotated
1852 without introducing artifacts. fClipMatrix may be nullptr.
1853##
1854
1855#Member SaveLayerFlags fSaveLayerFlags
1856 fSaveLayerFlags are used to create Layer without transparency,
1857 create Layer for LCD text, and to create Layer with the
1858 contents of the previous Layer.
1859##
1860
1861#Example
1862#Height 160
1863#Description
1864Canvas Layer captures a red Anti-aliased circle and a blue Aliased circle scaled
1865up by four. After drawing another red circle without scaling on top, the Layer is
1866transferred to the main canvas.
1867##
1868void draw(SkCanvas* canvas) {
1869 SkPaint redPaint, bluePaint;
1870 redPaint.setAntiAlias(true);
1871 redPaint.setColor(SK_ColorRED);
1872 canvas->drawCircle(21, 21, 8, redPaint);
1873 bluePaint.setColor(SK_ColorBLUE);
1874 canvas->drawCircle(31, 21, 8, bluePaint);
1875 SkMatrix matrix;
1876 matrix.setScale(4, 4);
1877 auto scaler = SkImageFilter::MakeMatrixFilter(matrix, kNone_SkFilterQuality, nullptr);
1878 SkCanvas::SaveLayerRec saveLayerRec(nullptr, nullptr, scaler.get(), 0);
1879 canvas->saveLayer(saveLayerRec);
1880 canvas->drawCircle(125, 85, 8, redPaint);
1881 canvas->restore();
1882}
1883##
1884
1885#Method SaveLayerRec()
1886
1887Sets fBounds, fPaint, and fBackdrop to nullptr. Clears fSaveLayerFlags.
1888
1889#Return empty SaveLayerRec ##
1890
1891#Example
1892 SkCanvas::SaveLayerRec rec1;
1893 rec1.fSaveLayerFlags = SkCanvas::kIsOpaque_SaveLayerFlag;
1894 SkCanvas::SaveLayerRec rec2(nullptr, nullptr, SkCanvas::kIsOpaque_SaveLayerFlag);
1895 SkDebugf("rec1 %c= rec2\n", rec1.fBounds == rec2.fBounds
1896 && rec1.fPaint == rec2.fPaint
1897 && rec1.fBackdrop == rec2.fBackdrop
1898 && rec1.fSaveLayerFlags == rec2.fSaveLayerFlags ? '=' : '!');
1899 #StdOut
1900 rec1 == rec2
1901 ##
1902##
1903
1904##
1905
1906#Method SaveLayerRec(const SkRect* bounds, const SkPaint* paint, SaveLayerFlags saveLayerFlags = 0)
1907
1908Sets fBounds, fPaint, and fSaveLayerFlags; sets fBackdrop to nullptr.
1909
1910#Param bounds Layer dimensions; may be nullptr ##
1911#Param paint applied to Layer when overlaying prior Layer; may be nullptr ##
1912#Param saveLayerFlags SaveLayerRec options to modify Layer ##
1913
1914#Return SaveLayerRec with empty backdrop ##
1915
1916#Example
1917 SkCanvas::SaveLayerRec rec1;
1918 SkCanvas::SaveLayerRec rec2(nullptr, nullptr);
1919 SkDebugf("rec1 %c= rec2\n", rec1.fBounds == rec2.fBounds
1920 && rec1.fPaint == rec2.fPaint
1921 && rec1.fBackdrop == rec2.fBackdrop
1922 && rec1.fSaveLayerFlags == rec2.fSaveLayerFlags ? '=' : '!');
1923 #StdOut
1924 rec1 == rec2
1925 ##
1926##
1927
1928##
1929
1930#Method SaveLayerRec(const SkRect* bounds, const SkPaint* paint, const SkImageFilter* backdrop,
1931 SaveLayerFlags saveLayerFlags)
1932
1933Sets fBounds, fPaint, fBackdrop, and fSaveLayerFlags.
1934
1935#Param bounds Layer dimensions; may be nullptr ##
1936#Param paint applied to Layer when overlaying prior Layer;
1937 may be nullptr
1938##
1939#Param backdrop prior Layer copied with Image_Filter; may be nullptr
1940##
1941#Param saveLayerFlags SaveLayerRec options to modify Layer ##
1942
1943#Return SaveLayerRec fully specified ##
1944
1945#Example
1946 SkCanvas::SaveLayerRec rec1;
1947 SkCanvas::SaveLayerRec rec2(nullptr, nullptr, nullptr, 0);
1948 SkDebugf("rec1 %c= rec2\n", rec1.fBounds == rec2.fBounds
1949 && rec1.fPaint == rec2.fPaint
1950 && rec1.fBackdrop == rec2.fBackdrop
1951 && rec1.fSaveLayerFlags == rec2.fSaveLayerFlags ? '=' : '!');
1952 #StdOut
1953 rec1 == rec2
1954 ##
1955##
1956
1957##
1958
1959#Method SaveLayerRec(const SkRect* bounds, const SkPaint* paint, const SkImageFilter* backdrop,
1960 const SkImage* clipMask, const SkMatrix* clipMatrix,
1961 SaveLayerFlags saveLayerFlags)
1962
1963#Experimental
1964Not ready for general use.
1965##
1966
1967Sets fBounds, fPaint, fBackdrop, fClipMask, fClipMatrix, and fSaveLayerFlags.
1968clipMatrix uses Color_Alpha channel of image, transformed by clipMatrix, to clip
1969Layer when drawn to Canvas.
1970
1971Implementation is incomplete; has no effect if Device is GPU-backed.
1972
1973#Param bounds Layer dimensions; may be nullptr ##
1974#Param paint graphics state applied to Layer when overlaying prior
1975 Layer; may be nullptr
1976##
1977#Param backdrop prior Layer copied with Image_Filter;
1978 may be nullptr
1979##
1980#Param clipMask clip applied to Layer; may be nullptr ##
1981#Param clipMatrix matrix applied to clipMask; may be nullptr to use
1982 identity matrix
1983##
1984#Param saveLayerFlags SaveLayerRec options to modify Layer ##
1985
1986#Return SaveLayerRec fully specified ##
1987
1988#ToDo incomplete ##
1989
1990##
1991
1992#Struct ##
1993
1994#Method int saveLayer(const SaveLayerRec& layerRec)
1995
1996Saves Matrix, Clip, and Draw_Filter (Draw_Filter deprecated on most platforms),
1997and allocates Bitmap for subsequent drawing.
1998
1999Calling restore() discards changes to Matrix, Clip, and Draw_Filter,
2000and blends Bitmap with Color_Alpha opacity onto the prior Layer.
2001
2002Matrix may be changed by translate(), scale(), rotate(), skew(), concat(),
2003setMatrix, and resetMatrix. Clip may be changed by clipRect, clipRRect,
2004clipPath, clipRegion.
2005
2006SaveLayerRec contains the state used to create the Layer.
2007
2008Call restoreToCount with returned value to restore this and subsequent saves.
2009
2010#Param layerRec Layer state ##
2011
2012#Return depth of save state stack ##
2013
2014#Example
2015#Description
2016The example draws an image, and saves it into a Layer with kInitWithPrevious_SaveLayerFlag.
2017Next it punches a hole in Layer and restore with SkBlendMode::kPlus.
2018Where Layer was cleared, the original image will draw unchanged.
2019Outside of the circle the mandrill is brightened.
2020##
2021 #Image 3
2022 // sk_sp<SkImage> image = GetResourceAsImage("mandrill_256.png");
2023 canvas->drawImage(image, 0, 0, nullptr);
2024 SkCanvas::SaveLayerRec rec;
2025 SkPaint paint;
2026 paint.setBlendMode(SkBlendMode::kPlus);
2027 rec.fSaveLayerFlags = SkCanvas::kInitWithPrevious_SaveLayerFlag;
2028 rec.fPaint = &paint;
2029 canvas->saveLayer(rec);
2030 paint.setBlendMode(SkBlendMode::kClear);
2031 canvas->drawCircle(128, 128, 96, paint);
2032 canvas->restore();
2033##
2034
2035#ToDo above example needs to replace GetResourceAsImage with way to select image in fiddle ##
2036
2037##
2038
2039#Topic Layer ##
2040
2041# ------------------------------------------------------------------------------
Cary Clark8032b982017-07-28 11:04:54 -04002042#Topic Matrix
2043
2044#Method void translate(SkScalar dx, SkScalar dy)
2045
2046Translate Matrix by dx along the x-axis and dy along the y-axis.
2047
2048Mathematically, replace Matrix with a translation matrix
Cary Clarkce101242017-09-01 15:51:02 -04002049Premultiplied with Matrix.
Cary Clark8032b982017-07-28 11:04:54 -04002050
2051This has the effect of moving the drawing by (dx, dy) before transforming
2052the result with Matrix.
2053
Cary Clarkbad5ad72017-08-03 17:14:08 -04002054#Param dx distance to translate in x ##
2055#Param dy distance to translate in y ##
Cary Clark8032b982017-07-28 11:04:54 -04002056
2057#Example
2058#Height 128
2059#Description
2060scale() followed by translate() produces different results from translate() followed
2061by scale().
2062
2063The blue stroke follows translate of (50, 50); a black
2064fill follows scale of (2, 1/2.f). After restoring the clip, which resets
2065Matrix, a red frame follows the same scale of (2, 1/2.f); a gray fill
2066follows translate of (50, 50).
2067##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002068void draw(SkCanvas* canvas) {
2069 SkPaint filledPaint;
2070 SkPaint outlinePaint;
2071 outlinePaint.setStyle(SkPaint::kStroke_Style);
2072 outlinePaint.setColor(SK_ColorBLUE);
2073 canvas->save();
2074 canvas->translate(50, 50);
2075 canvas->drawCircle(28, 28, 15, outlinePaint); // blue center: (50+28, 50+28)
2076 canvas->scale(2, 1/2.f);
2077 canvas->drawCircle(28, 28, 15, filledPaint); // black center: (50+(28*2), 50+(28/2))
2078 canvas->restore();
2079 filledPaint.setColor(SK_ColorGRAY);
2080 outlinePaint.setColor(SK_ColorRED);
2081 canvas->scale(2, 1/2.f);
2082 canvas->drawCircle(28, 28, 15, outlinePaint); // red center: (28*2, 28/2)
2083 canvas->translate(50, 50);
2084 canvas->drawCircle(28, 28, 15, filledPaint); // gray center: ((50+28)*2, (50+28)/2)
Cary Clark8032b982017-07-28 11:04:54 -04002085}
2086##
2087
2088#ToDo incomplete ##
2089
2090##
2091
2092# ------------------------------------------------------------------------------
2093
2094#Method void scale(SkScalar sx, SkScalar sy)
2095
2096Scale Matrix by sx on the x-axis and sy on the y-axis.
2097
2098Mathematically, replace Matrix with a scale matrix
Cary Clarkce101242017-09-01 15:51:02 -04002099Premultiplied with Matrix.
Cary Clark8032b982017-07-28 11:04:54 -04002100
2101This has the effect of scaling the drawing by (sx, sy) before transforming
2102the result with Matrix.
2103
Cary Clarkbad5ad72017-08-03 17:14:08 -04002104#Param sx amount to scale in x ##
2105#Param sy amount to scale in y ##
Cary Clark8032b982017-07-28 11:04:54 -04002106
2107#Example
2108#Height 160
Cary Clarkbad5ad72017-08-03 17:14:08 -04002109void draw(SkCanvas* canvas) {
2110 SkPaint paint;
2111 SkRect rect = { 10, 20, 60, 120 };
2112 canvas->translate(20, 20);
2113 canvas->drawRect(rect, paint);
2114 canvas->scale(2, .5f);
2115 paint.setColor(SK_ColorGRAY);
2116 canvas->drawRect(rect, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002117}
2118##
2119
2120#ToDo incomplete ##
2121
2122##
2123
2124# ------------------------------------------------------------------------------
2125
2126#Method void rotate(SkScalar degrees)
2127
2128Rotate Matrix by degrees. Positive degrees rotates clockwise.
2129
2130Mathematically, replace Matrix with a rotation matrix
Cary Clarkce101242017-09-01 15:51:02 -04002131Premultiplied with Matrix.
Cary Clark8032b982017-07-28 11:04:54 -04002132
2133This has the effect of rotating the drawing by degrees before transforming
2134the result with Matrix.
2135
Cary Clarkbad5ad72017-08-03 17:14:08 -04002136#Param degrees amount to rotate, in degrees ##
Cary Clark8032b982017-07-28 11:04:54 -04002137
2138#Example
2139#Description
2140Draw clock hands at time 5:10. The hour hand and minute hand point up and
2141are rotated clockwise.
2142##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002143void draw(SkCanvas* canvas) {
2144 SkPaint paint;
2145 paint.setStyle(SkPaint::kStroke_Style);
2146 canvas->translate(128, 128);
2147 canvas->drawCircle(0, 0, 60, paint);
2148 canvas->save();
2149 canvas->rotate(10 * 360 / 60); // 10 minutes of 60 scaled to 360 degrees
2150 canvas->drawLine(0, 0, 0, -50, paint);
2151 canvas->restore();
2152 canvas->rotate((5 + 10.f/60) * 360 / 12); // 5 and 10/60 hours of 12 scaled to 360 degrees
2153 canvas->drawLine(0, 0, 0, -30, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002154}
2155##
2156
2157#ToDo incomplete ##
2158
2159##
2160
2161# ------------------------------------------------------------------------------
2162
2163#Method void rotate(SkScalar degrees, SkScalar px, SkScalar py)
2164
Cary Clarkbad5ad72017-08-03 17:14:08 -04002165Rotate Matrix by degrees about a point at (px, py). Positive degrees rotates
2166clockwise.
Cary Clark8032b982017-07-28 11:04:54 -04002167
Cary Clarkce101242017-09-01 15:51:02 -04002168Mathematically, construct a rotation matrix. Premultiply the rotation matrix by
Cary Clark8032b982017-07-28 11:04:54 -04002169a translation matrix, then replace Matrix with the resulting matrix
Cary Clarkce101242017-09-01 15:51:02 -04002170Premultiplied with Matrix.
Cary Clark8032b982017-07-28 11:04:54 -04002171
Cary Clarkbad5ad72017-08-03 17:14:08 -04002172This has the effect of rotating the drawing about a given point before
2173transforming the result with Matrix.
Cary Clark8032b982017-07-28 11:04:54 -04002174
Cary Clarkbad5ad72017-08-03 17:14:08 -04002175#Param degrees amount to rotate, in degrees ##
2176#Param px x-coordinate of the point to rotate about ##
2177#Param py y-coordinate of the point to rotate about ##
Cary Clark8032b982017-07-28 11:04:54 -04002178
2179#Example
2180#Height 192
Cary Clarkbad5ad72017-08-03 17:14:08 -04002181void draw(SkCanvas* canvas) {
2182 SkPaint paint;
2183 paint.setTextSize(96);
2184 canvas->drawString("A1", 130, 100, paint);
2185 canvas->rotate(180, 130, 100);
2186 canvas->drawString("A1", 130, 100, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002187}
2188##
2189
2190#ToDo incomplete ##
2191
2192##
2193
2194# ------------------------------------------------------------------------------
2195
2196#Method void skew(SkScalar sx, SkScalar sy)
2197
Cary Clarkbad5ad72017-08-03 17:14:08 -04002198Skew Matrix by sx on the x-axis and sy on the y-axis. A positive value of sx
2199skews the drawing right as y increases; a positive value of sy skews the drawing
2200down as x increases.
Cary Clark8032b982017-07-28 11:04:54 -04002201
Cary Clarkce101242017-09-01 15:51:02 -04002202Mathematically, replace Matrix with a skew matrix Premultiplied with Matrix.
Cary Clark8032b982017-07-28 11:04:54 -04002203
Cary Clarkbad5ad72017-08-03 17:14:08 -04002204This has the effect of skewing the drawing by (sx, sy) before transforming
Cary Clark8032b982017-07-28 11:04:54 -04002205the result with Matrix.
2206
Cary Clarkbad5ad72017-08-03 17:14:08 -04002207#Param sx amount to skew in x ##
2208#Param sy amount to skew in y ##
2209
Cary Clark8032b982017-07-28 11:04:54 -04002210#Example
2211 #Description
2212 Black text mimics an oblique text style by using a negative skew in x that
2213 shifts the geometry to the right as the y values decrease.
2214 Red text uses a positive skew in y to shift the geometry down as the x values
2215 increase.
2216 Blue text combines x and y skew to rotate and scale.
2217 ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002218 SkPaint paint;
2219 paint.setTextSize(128);
2220 canvas->translate(30, 130);
2221 canvas->save();
2222 canvas->skew(-.5, 0);
2223 canvas->drawString("A1", 0, 0, paint);
2224 canvas->restore();
2225 canvas->save();
2226 canvas->skew(0, .5);
2227 paint.setColor(SK_ColorRED);
2228 canvas->drawString("A1", 0, 0, paint);
2229 canvas->restore();
2230 canvas->skew(-.5, .5);
2231 paint.setColor(SK_ColorBLUE);
Cary Clark8032b982017-07-28 11:04:54 -04002232 canvas->drawString("A1", 0, 0, paint);
2233##
2234
2235#ToDo incomplete ##
2236
2237##
2238
2239# ------------------------------------------------------------------------------
2240
2241#Method void concat(const SkMatrix& matrix)
2242
Cary Clarkce101242017-09-01 15:51:02 -04002243Replace Matrix with matrix Premultiplied with existing Matrix.
Cary Clark8032b982017-07-28 11:04:54 -04002244
Cary Clarkbad5ad72017-08-03 17:14:08 -04002245This has the effect of transforming the drawn geometry by matrix, before
2246transforming the result with existing Matrix.
Cary Clark8032b982017-07-28 11:04:54 -04002247
Cary Clarkce101242017-09-01 15:51:02 -04002248#Param matrix matrix to Premultiply with existing Matrix ##
Cary Clark8032b982017-07-28 11:04:54 -04002249
2250#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04002251void draw(SkCanvas* canvas) {
2252 SkPaint paint;
2253 paint.setTextSize(80);
2254 paint.setTextScaleX(.3);
2255 SkMatrix matrix;
2256 SkRect rect[2] = {{ 10, 20, 90, 110 }, { 40, 130, 140, 180 }};
2257 matrix.setRectToRect(rect[0], rect[1], SkMatrix::kFill_ScaleToFit);
2258 canvas->drawRect(rect[0], paint);
2259 canvas->drawRect(rect[1], paint);
2260 paint.setColor(SK_ColorWHITE);
2261 canvas->drawString("Here", rect[0].fLeft + 10, rect[0].fBottom - 10, paint);
2262 canvas->concat(matrix);
2263 canvas->drawString("There", rect[0].fLeft + 10, rect[0].fBottom - 10, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002264}
2265##
2266
2267#ToDo incomplete ##
2268
2269##
2270
2271# ------------------------------------------------------------------------------
2272
2273#Method void setMatrix(const SkMatrix& matrix)
2274
2275Replace Matrix with matrix.
2276Unlike concat(), any prior matrix state is overwritten.
2277
Cary Clarkbad5ad72017-08-03 17:14:08 -04002278#Param matrix matrix to copy, replacing existing Matrix ##
Cary Clark8032b982017-07-28 11:04:54 -04002279
2280#Example
2281#Height 128
Cary Clarkbad5ad72017-08-03 17:14:08 -04002282void draw(SkCanvas* canvas) {
2283 SkPaint paint;
2284 canvas->scale(4, 6);
2285 canvas->drawString("truth", 2, 10, paint);
2286 SkMatrix matrix;
2287 matrix.setScale(2.8f, 6);
2288 canvas->setMatrix(matrix);
2289 canvas->drawString("consequences", 2, 20, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002290}
2291##
2292
2293#ToDo incomplete ##
2294
2295##
2296
2297# ------------------------------------------------------------------------------
2298
2299#Method void resetMatrix()
2300
2301Sets Matrix to the identity matrix.
2302Any prior matrix state is overwritten.
2303
2304#Example
2305#Height 128
Cary Clarkbad5ad72017-08-03 17:14:08 -04002306void draw(SkCanvas* canvas) {
2307 SkPaint paint;
2308 canvas->scale(4, 6);
2309 canvas->drawString("truth", 2, 10, paint);
2310 canvas->resetMatrix();
2311 canvas->scale(2.8f, 6);
2312 canvas->drawString("consequences", 2, 20, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002313}
2314##
2315
2316#ToDo incomplete ##
2317
2318##
2319
2320# ------------------------------------------------------------------------------
2321
2322#Method const SkMatrix& getTotalMatrix() const
2323
2324Returns Matrix.
2325This does not account for translation by Device or Surface.
2326
Cary Clarkbad5ad72017-08-03 17:14:08 -04002327#Return Matrix in Canvas ##
Cary Clark8032b982017-07-28 11:04:54 -04002328
2329#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04002330 SkDebugf("isIdentity %s\n", canvas->getTotalMatrix().isIdentity() ? "true" : "false");
2331 #StdOut
2332 isIdentity true
2333 ##
Cary Clark8032b982017-07-28 11:04:54 -04002334##
2335
2336#ToDo incomplete ##
2337
2338##
2339
2340#Topic Matrix ##
2341
2342# ------------------------------------------------------------------------------
2343#Topic Clip
2344
2345Clip is built from a stack of clipping paths. Each Path in the
2346stack can be constructed from one or more Path_Contour elements. The
2347Path_Contour may be composed of any number of Path_Verb segments. Each
2348Path_Contour forms a closed area; Path_Fill_Type defines the area enclosed
2349by Path_Contour.
2350
2351Clip stack of Path elements successfully restrict the Path area. Each
2352Path is transformed by Matrix, then intersected with or subtracted from the
2353prior Clip to form the replacement Clip. Use SkClipOp::kDifference
2354to subtract Path from Clip; use SkClipOp::kIntersect to intersect Path
2355with Clip.
2356
Cary Clarkce101242017-09-01 15:51:02 -04002357A clipping Path may be Anti-aliased; if Path, after transformation, is
Cary Clark8032b982017-07-28 11:04:54 -04002358composed of horizontal and vertical lines, clearing Anti-alias allows whole pixels
Cary Clarkce101242017-09-01 15:51:02 -04002359to either be inside or outside the clip. The fastest drawing has a Aliased,
2360rectangular clip.
Cary Clark8032b982017-07-28 11:04:54 -04002361
2362If clipping Path has Anti-alias set, clip may partially clip a pixel, requiring
2363that drawing blend partially with the destination along the edge. A rotated
Cary Clarkce101242017-09-01 15:51:02 -04002364rectangular Anti-aliased clip looks smoother but draws slower.
Cary Clark8032b982017-07-28 11:04:54 -04002365
2366Clip can combine with Rect and Round_Rect primitives; like
2367Path, these are transformed by Matrix before they are combined with Clip.
2368
2369Clip can combine with Region. Region is assumed to be in Device coordinates
2370and is unaffected by Matrix.
2371
2372#Example
2373#Height 90
2374 #Description
Cary Clarkce101242017-09-01 15:51:02 -04002375 Draw a red circle with an Aliased clip and an Anti-aliased clip.
Cary Clark8032b982017-07-28 11:04:54 -04002376 Use an image filter to zoom into the pixels drawn.
Cary Clarkce101242017-09-01 15:51:02 -04002377 The edge of the Aliased clip fully draws pixels in the red circle.
2378 The edge of the Anti-aliased clip partially draws pixels in the red circle.
Cary Clark8032b982017-07-28 11:04:54 -04002379 ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002380 SkPaint redPaint, scalePaint;
2381 redPaint.setAntiAlias(true);
2382 redPaint.setColor(SK_ColorRED);
2383 canvas->save();
2384 for (bool antialias : { false, true } ) {
2385 canvas->save();
2386 canvas->clipRect(SkRect::MakeWH(19.5f, 11.5f), antialias);
2387 canvas->drawCircle(17, 11, 8, redPaint);
2388 canvas->restore();
2389 canvas->translate(16, 0);
2390 }
2391 canvas->restore();
2392 SkMatrix matrix;
2393 matrix.setScale(6, 6);
2394 scalePaint.setImageFilter(
2395 SkImageFilter::MakeMatrixFilter(matrix, kNone_SkFilterQuality, nullptr));
2396 SkCanvas::SaveLayerRec saveLayerRec(
2397 nullptr, &scalePaint, SkCanvas::kInitWithPrevious_SaveLayerFlag);
2398 canvas->saveLayer(saveLayerRec);
Cary Clark8032b982017-07-28 11:04:54 -04002399 canvas->restore();
2400##
2401
2402#Method void clipRect(const SkRect& rect, SkClipOp op, bool doAntiAlias)
2403
2404Replace Clip with the intersection or difference of Clip and rect,
Cary Clarkce101242017-09-01 15:51:02 -04002405with an Aliased or Anti-aliased clip edge. rect is transformed by Matrix
Cary Clark8032b982017-07-28 11:04:54 -04002406before it is combined with Clip.
2407
Cary Clarka523d2d2017-08-30 08:58:10 -04002408#Param rect Rect to combine with Clip ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002409#Param op Clip_Op to apply to Clip ##
Cary Clarkce101242017-09-01 15:51:02 -04002410#Param doAntiAlias true if Clip is to be Anti-aliased ##
Cary Clark8032b982017-07-28 11:04:54 -04002411
2412#Example
2413#Height 128
Cary Clarkbad5ad72017-08-03 17:14:08 -04002414void draw(SkCanvas* canvas) {
2415 canvas->rotate(10);
2416 SkPaint paint;
2417 paint.setAntiAlias(true);
2418 for (auto alias: { false, true } ) {
2419 canvas->save();
2420 canvas->clipRect(SkRect::MakeWH(90, 80), SkClipOp::kIntersect, alias);
2421 canvas->drawCircle(100, 60, 60, paint);
2422 canvas->restore();
2423 canvas->translate(80, 0);
2424 }
Cary Clark8032b982017-07-28 11:04:54 -04002425}
2426##
2427
2428#ToDo incomplete ##
2429
2430##
2431
2432#Method void clipRect(const SkRect& rect, SkClipOp op)
2433
2434Replace Clip with the intersection or difference of Clip and rect.
Cary Clarkce101242017-09-01 15:51:02 -04002435Resulting Clip is Aliased; pixels are fully contained by the clip.
Cary Clarkbad5ad72017-08-03 17:14:08 -04002436rect is transformed by Matrix before it is combined with Clip.
Cary Clark8032b982017-07-28 11:04:54 -04002437
Cary Clarka523d2d2017-08-30 08:58:10 -04002438#Param rect Rect to combine with Clip ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002439#Param op Clip_Op to apply to Clip ##
Cary Clark8032b982017-07-28 11:04:54 -04002440
2441#Example
2442#Height 192
2443#Width 280
Cary Clarkbad5ad72017-08-03 17:14:08 -04002444void draw(SkCanvas* canvas) {
2445 SkPaint paint;
2446 for (SkClipOp op: { SkClipOp::kIntersect, SkClipOp::kDifference } ) {
2447 canvas->save();
2448 canvas->clipRect(SkRect::MakeWH(90, 120), op, false);
2449 canvas->drawCircle(100, 100, 60, paint);
2450 canvas->restore();
2451 canvas->translate(80, 0);
2452 }
Cary Clark8032b982017-07-28 11:04:54 -04002453}
2454##
2455
2456#ToDo incomplete ##
2457
2458##
2459
2460#Method void clipRect(const SkRect& rect, bool doAntiAlias = false)
2461
2462Replace Clip with the intersection of Clip and rect.
Cary Clarkce101242017-09-01 15:51:02 -04002463Resulting Clip is Aliased; pixels are fully contained by the clip.
Cary Clark8032b982017-07-28 11:04:54 -04002464rect is transformed by Matrix
2465before it is combined with Clip.
2466
Cary Clarka523d2d2017-08-30 08:58:10 -04002467#Param rect Rect to combine with Clip ##
Cary Clarkce101242017-09-01 15:51:02 -04002468#Param doAntiAlias true if Clip is to be Anti-aliased ##
Cary Clark8032b982017-07-28 11:04:54 -04002469
2470#Example
2471#Height 133
2472 #Description
Cary Clarkce101242017-09-01 15:51:02 -04002473 A circle drawn in pieces looks uniform when drawn Aliased.
2474 The same circle pieces blend with pixels more than once when Anti-aliased,
Cary Clark8032b982017-07-28 11:04:54 -04002475 visible as a thin pair of lines through the right circle.
2476 ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002477void draw(SkCanvas* canvas) {
2478 canvas->clear(SK_ColorWHITE);
2479 SkPaint paint;
2480 paint.setAntiAlias(true);
2481 paint.setColor(0x8055aaff);
2482 SkRect clipRect = { 0, 0, 87.4f, 87.4f };
2483 for (auto alias: { false, true } ) {
2484 canvas->save();
2485 canvas->clipRect(clipRect, SkClipOp::kIntersect, alias);
2486 canvas->drawCircle(67, 67, 60, paint);
2487 canvas->restore();
2488 canvas->save();
2489 canvas->clipRect(clipRect, SkClipOp::kDifference, alias);
2490 canvas->drawCircle(67, 67, 60, paint);
2491 canvas->restore();
2492 canvas->translate(120, 0);
2493 }
Cary Clark8032b982017-07-28 11:04:54 -04002494}
2495##
2496
2497#ToDo incomplete ##
2498
2499##
2500
2501#Method void androidFramework_setDeviceClipRestriction(const SkIRect& rect)
2502
Cary Clarkce101242017-09-01 15:51:02 -04002503Sets the maximum clip rectangle, which can be set by clipRect, clipRRect and
Cary Clark8032b982017-07-28 11:04:54 -04002504clipPath and intersect the current clip with the specified rect.
Cary Clarkce101242017-09-01 15:51:02 -04002505The maximum clip affects only future clipping operations; it is not retroactive.
Cary Clark8032b982017-07-28 11:04:54 -04002506The clip restriction is not recorded in pictures.
2507
Cary Clarkce101242017-09-01 15:51:02 -04002508Pass an empty rect to disable maximum clip.
Cary Clarkbad5ad72017-08-03 17:14:08 -04002509
Cary Clark8032b982017-07-28 11:04:54 -04002510#Private
2511This is private API to be used only by Android framework.
2512##
2513
Cary Clarkbad5ad72017-08-03 17:14:08 -04002514#Param rect maximum allowed clip in device coordinates
Cary Clark579985c2017-07-31 11:48:27 -04002515#Param ##
Cary Clark8032b982017-07-28 11:04:54 -04002516
2517##
2518
2519#Method void clipRRect(const SkRRect& rrect, SkClipOp op, bool doAntiAlias)
2520
2521Replace Clip with the intersection or difference of Clip and rrect,
Cary Clarkce101242017-09-01 15:51:02 -04002522with an Aliased or Anti-aliased clip edge.
Cary Clark8032b982017-07-28 11:04:54 -04002523rrect is transformed by Matrix
2524before it is combined with Clip.
2525
Cary Clarkbad5ad72017-08-03 17:14:08 -04002526#Param rrect Round_Rect to combine with Clip ##
2527#Param op Clip_Op to apply to Clip ##
Cary Clarkce101242017-09-01 15:51:02 -04002528#Param doAntiAlias true if Clip is to be Anti-aliased ##
Cary Clark8032b982017-07-28 11:04:54 -04002529
2530#Example
2531#Height 128
Cary Clarkbad5ad72017-08-03 17:14:08 -04002532void draw(SkCanvas* canvas) {
2533 canvas->clear(SK_ColorWHITE);
2534 SkPaint paint;
2535 paint.setAntiAlias(true);
2536 paint.setColor(0x8055aaff);
2537 SkRRect oval;
2538 oval.setOval({10, 20, 90, 100});
2539 canvas->clipRRect(oval, SkClipOp::kIntersect, true);
2540 canvas->drawCircle(70, 100, 60, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002541}
2542##
2543
2544#ToDo incomplete ##
2545
2546##
2547
2548#Method void clipRRect(const SkRRect& rrect, SkClipOp op)
2549
2550Replace Clip with the intersection or difference of Clip and rrect.
Cary Clarkce101242017-09-01 15:51:02 -04002551Resulting Clip is Aliased; pixels are fully contained by the clip.
Cary Clarkbad5ad72017-08-03 17:14:08 -04002552rrect is transformed by Matrix before it is combined with Clip.
Cary Clark8032b982017-07-28 11:04:54 -04002553
Cary Clarkbad5ad72017-08-03 17:14:08 -04002554#Param rrect Round_Rect to combine with Clip ##
2555#Param op Clip_Op to apply to Clip ##
Cary Clark8032b982017-07-28 11:04:54 -04002556
2557#Example
2558#Height 128
Cary Clarkbad5ad72017-08-03 17:14:08 -04002559void draw(SkCanvas* canvas) {
2560 SkPaint paint;
2561 paint.setColor(0x8055aaff);
2562 auto oval = SkRRect::MakeOval({10, 20, 90, 100});
2563 canvas->clipRRect(oval, SkClipOp::kIntersect);
2564 canvas->drawCircle(70, 100, 60, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002565}
2566##
2567
2568#ToDo incomplete ##
2569
2570##
2571
2572#Method void clipRRect(const SkRRect& rrect, bool doAntiAlias = false)
2573
2574Replace Clip with the intersection of Clip and rrect,
Cary Clarkce101242017-09-01 15:51:02 -04002575with an Aliased or Anti-aliased clip edge.
Cary Clarkbad5ad72017-08-03 17:14:08 -04002576rrect is transformed by Matrix before it is combined with Clip.
Cary Clark8032b982017-07-28 11:04:54 -04002577
Cary Clarkbad5ad72017-08-03 17:14:08 -04002578#Param rrect Round_Rect to combine with Clip ##
Cary Clarkce101242017-09-01 15:51:02 -04002579#Param doAntiAlias true if Clip is to be Anti-aliased ##
Cary Clark8032b982017-07-28 11:04:54 -04002580
2581#Example
2582#Height 128
Cary Clarkbad5ad72017-08-03 17:14:08 -04002583void draw(SkCanvas* canvas) {
2584 SkPaint paint;
2585 paint.setAntiAlias(true);
2586 auto oval = SkRRect::MakeRectXY({10, 20, 90, 100}, 9, 13);
2587 canvas->clipRRect(oval, true);
2588 canvas->drawCircle(70, 100, 60, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002589}
2590##
2591
2592#ToDo incomplete ##
2593
2594##
2595
2596#Method void clipPath(const SkPath& path, SkClipOp op, bool doAntiAlias)
2597
2598Replace Clip with the intersection or difference of Clip and path,
Cary Clarkce101242017-09-01 15:51:02 -04002599with an Aliased or Anti-aliased clip edge. Path_Fill_Type determines if path
Cary Clark8032b982017-07-28 11:04:54 -04002600describes the area inside or outside its contours; and if Path_Contour overlaps
2601itself or another Path_Contour, whether the overlaps form part of the area.
Cary Clarkbad5ad72017-08-03 17:14:08 -04002602path is transformed by Matrix before it is combined with Clip.
Cary Clark8032b982017-07-28 11:04:54 -04002603
Cary Clarkbad5ad72017-08-03 17:14:08 -04002604#Param path Path to combine with Clip ##
2605#Param op Clip_Op to apply to Clip ##
Cary Clarkce101242017-09-01 15:51:02 -04002606#Param doAntiAlias true if Clip is to be Anti-aliased ##
Cary Clark8032b982017-07-28 11:04:54 -04002607
2608#Example
2609#Description
2610Top figure uses SkPath::kInverseWinding_FillType and SkClipOp::kDifference;
2611area outside clip is subtracted from circle.
2612
2613Bottom figure uses SkPath::kWinding_FillType and SkClipOp::kIntersect;
2614area inside clip is intersected with circle.
2615##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002616void draw(SkCanvas* canvas) {
2617 SkPaint paint;
2618 paint.setAntiAlias(true);
2619 SkPath path;
2620 path.addRect({20, 30, 100, 110});
2621 path.setFillType(SkPath::kInverseWinding_FillType);
2622 canvas->save();
2623 canvas->clipPath(path, SkClipOp::kDifference, false);
2624 canvas->drawCircle(70, 100, 60, paint);
2625 canvas->restore();
2626 canvas->translate(100, 100);
2627 path.setFillType(SkPath::kWinding_FillType);
2628 canvas->clipPath(path, SkClipOp::kIntersect, false);
2629 canvas->drawCircle(70, 100, 60, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002630}
2631##
2632
2633#ToDo incomplete ##
2634
2635##
2636
2637#Method void clipPath(const SkPath& path, SkClipOp op)
2638
2639Replace Clip with the intersection or difference of Clip and path.
Cary Clarkce101242017-09-01 15:51:02 -04002640Resulting Clip is Aliased; pixels are fully contained by the clip.
Cary Clark8032b982017-07-28 11:04:54 -04002641Path_Fill_Type determines if path
2642describes the area inside or outside its contours; and if Path_Contour overlaps
2643itself or another Path_Contour, whether the overlaps form part of the area.
2644path is transformed by Matrix
2645before it is combined with Clip.
2646
Cary Clarkbad5ad72017-08-03 17:14:08 -04002647#Param path Path to combine with Clip ##
2648#Param op Clip_Op to apply to Clip ##
Cary Clark8032b982017-07-28 11:04:54 -04002649
2650#Example
2651#Description
Cary Clarkbc5697d2017-10-04 14:31:33 -04002652Overlapping Rects form a clip. When clip Path_Fill_Type is set to
Cary Clark8032b982017-07-28 11:04:54 -04002653SkPath::kWinding_FillType, the overlap is included. Set to
2654SkPath::kEvenOdd_FillType, the overlap is excluded and forms a hole.
2655##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002656void draw(SkCanvas* canvas) {
2657 SkPaint paint;
2658 paint.setAntiAlias(true);
2659 SkPath path;
2660 path.addRect({20, 15, 100, 95});
2661 path.addRect({50, 65, 130, 135});
2662 path.setFillType(SkPath::kWinding_FillType);
2663 canvas->save();
2664 canvas->clipPath(path, SkClipOp::kIntersect);
2665 canvas->drawCircle(70, 85, 60, paint);
2666 canvas->restore();
2667 canvas->translate(100, 100);
2668 path.setFillType(SkPath::kEvenOdd_FillType);
2669 canvas->clipPath(path, SkClipOp::kIntersect);
2670 canvas->drawCircle(70, 85, 60, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002671}
2672##
2673
2674#ToDo incomplete ##
2675
2676##
2677
2678#Method void clipPath(const SkPath& path, bool doAntiAlias = false)
2679
2680Replace Clip with the intersection of Clip and path.
Cary Clarkce101242017-09-01 15:51:02 -04002681Resulting Clip is Aliased; pixels are fully contained by the clip.
Cary Clark8032b982017-07-28 11:04:54 -04002682Path_Fill_Type determines if path
2683describes the area inside or outside its contours; and if Path_Contour overlaps
2684itself or another Path_Contour, whether the overlaps form part of the area.
Cary Clarkbad5ad72017-08-03 17:14:08 -04002685path is transformed by Matrix before it is combined with Clip.
Cary Clark8032b982017-07-28 11:04:54 -04002686
Cary Clarkbad5ad72017-08-03 17:14:08 -04002687#Param path Path to combine with Clip ##
Cary Clarkce101242017-09-01 15:51:02 -04002688#Param doAntiAlias true if Clip is to be Anti-aliased ##
Cary Clark8032b982017-07-28 11:04:54 -04002689
2690#Example
2691#Height 212
2692#Description
Cary Clarkbc5697d2017-10-04 14:31:33 -04002693Clip loops over itself covering its center twice. When clip Path_Fill_Type
Cary Clark8032b982017-07-28 11:04:54 -04002694is set to SkPath::kWinding_FillType, the overlap is included. Set to
2695SkPath::kEvenOdd_FillType, the overlap is excluded and forms a hole.
2696##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002697void draw(SkCanvas* canvas) {
2698 SkPaint paint;
2699 paint.setAntiAlias(true);
2700 SkPath path;
2701 SkPoint poly[] = {{20, 20}, { 80, 20}, { 80, 80}, {40, 80},
2702 {40, 40}, {100, 40}, {100, 100}, {20, 100}};
2703 path.addPoly(poly, SK_ARRAY_COUNT(poly), true);
2704 path.setFillType(SkPath::kWinding_FillType);
2705 canvas->save();
2706 canvas->clipPath(path, SkClipOp::kIntersect);
2707 canvas->drawCircle(50, 50, 45, paint);
2708 canvas->restore();
2709 canvas->translate(100, 100);
2710 path.setFillType(SkPath::kEvenOdd_FillType);
2711 canvas->clipPath(path, SkClipOp::kIntersect);
2712 canvas->drawCircle(50, 50, 45, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002713}
2714##
2715
2716#ToDo incomplete ##
2717
2718##
2719
2720# ------------------------------------------------------------------------------
2721
2722#Method void setAllowSimplifyClip(bool allow)
2723
2724#Experimental
2725Only used for testing.
2726##
2727
Cary Clarkce101242017-09-01 15:51:02 -04002728Set to simplify clip stack using PathOps.
Cary Clark8032b982017-07-28 11:04:54 -04002729
2730##
2731
2732# ------------------------------------------------------------------------------
2733
2734#Method void clipRegion(const SkRegion& deviceRgn, SkClipOp op = SkClipOp::kIntersect)
2735
2736Replace Clip with the intersection or difference of Clip and Region deviceRgn.
Cary Clarkce101242017-09-01 15:51:02 -04002737Resulting Clip is Aliased; pixels are fully contained by the clip.
Cary Clark8032b982017-07-28 11:04:54 -04002738deviceRgn is unaffected by Matrix.
2739
Cary Clarkbad5ad72017-08-03 17:14:08 -04002740#Param deviceRgn Region to combine with Clip ##
2741#Param op Clip_Op to apply to Clip ##
Cary Clark8032b982017-07-28 11:04:54 -04002742
2743#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04002744#Description
Cary Clarkce101242017-09-01 15:51:02 -04002745 region is unaffected by canvas rotation; iRect is affected by canvas rotation.
2746 Both clips are Aliased; this is not noticeable on Region clip because it
Cary Clarkbad5ad72017-08-03 17:14:08 -04002747 aligns to pixel boundaries.
2748##
2749void draw(SkCanvas* canvas) {
2750 SkPaint paint;
2751 paint.setAntiAlias(true);
2752 SkIRect iRect = {30, 40, 120, 130 };
2753 SkRegion region(iRect);
2754 canvas->rotate(10);
2755 canvas->save();
2756 canvas->clipRegion(region, SkClipOp::kIntersect);
2757 canvas->drawCircle(50, 50, 45, paint);
2758 canvas->restore();
2759 canvas->translate(100, 100);
2760 canvas->clipRect(SkRect::Make(iRect), SkClipOp::kIntersect);
2761 canvas->drawCircle(50, 50, 45, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002762}
2763##
2764
2765#ToDo incomplete ##
2766
2767##
2768
2769#Method bool quickReject(const SkRect& rect) const
2770
2771Return true if Rect rect, transformed by Matrix, can be quickly determined to be
2772outside of Clip. May return false even though rect is outside of Clip.
2773
2774Use to check if an area to be drawn is clipped out, to skip subsequent draw calls.
2775
Cary Clarkbad5ad72017-08-03 17:14:08 -04002776#Param rect Rect to compare with Clip ##
Cary Clark8032b982017-07-28 11:04:54 -04002777
Cary Clarkbad5ad72017-08-03 17:14:08 -04002778#Return true if rect, transformed by Matrix, does not intersect Clip ##
Cary Clark8032b982017-07-28 11:04:54 -04002779
2780#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04002781void draw(SkCanvas* canvas) {
2782 SkRect testRect = {30, 30, 120, 129 };
2783 SkRect clipRect = {30, 130, 120, 230 };
2784 canvas->save();
2785 canvas->clipRect(clipRect);
2786 SkDebugf("quickReject %s\n", canvas->quickReject(testRect) ? "true" : "false");
2787 canvas->restore();
2788 canvas->rotate(10);
2789 canvas->clipRect(clipRect);
2790 SkDebugf("quickReject %s\n", canvas->quickReject(testRect) ? "true" : "false");
Cary Clark8032b982017-07-28 11:04:54 -04002791}
2792 #StdOut
Cary Clarkbad5ad72017-08-03 17:14:08 -04002793 quickReject true
Cary Clark8032b982017-07-28 11:04:54 -04002794 quickReject false
2795 ##
2796##
2797
2798#ToDo incomplete ##
2799
2800##
2801
2802#Method bool quickReject(const SkPath& path) const
2803
2804Return true if path, transformed by Matrix, can be quickly determined to be
2805outside of Clip. May return false even though path is outside of Clip.
2806
2807Use to check if an area to be drawn is clipped out, to skip subsequent draw calls.
2808
Cary Clarkbad5ad72017-08-03 17:14:08 -04002809#Param path Path to compare with Clip ##
Cary Clark8032b982017-07-28 11:04:54 -04002810
Cary Clarkbad5ad72017-08-03 17:14:08 -04002811#Return true if path, transformed by Matrix, does not intersect Clip ##
Cary Clark8032b982017-07-28 11:04:54 -04002812
2813#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04002814void draw(SkCanvas* canvas) {
2815 SkPoint testPoints[] = {{30, 30}, {120, 30}, {120, 129} };
2816 SkPoint clipPoints[] = {{30, 130}, {120, 130}, {120, 230} };
2817 SkPath testPath, clipPath;
2818 testPath.addPoly(testPoints, SK_ARRAY_COUNT(testPoints), true);
2819 clipPath.addPoly(clipPoints, SK_ARRAY_COUNT(clipPoints), true);
2820 canvas->save();
2821 canvas->clipPath(clipPath);
2822 SkDebugf("quickReject %s\n", canvas->quickReject(testPath) ? "true" : "false");
2823 canvas->restore();
2824 canvas->rotate(10);
2825 canvas->clipPath(clipPath);
2826 SkDebugf("quickReject %s\n", canvas->quickReject(testPath) ? "true" : "false");
Cary Clark8032b982017-07-28 11:04:54 -04002827 #StdOut
Cary Clarkbad5ad72017-08-03 17:14:08 -04002828 quickReject true
Cary Clark8032b982017-07-28 11:04:54 -04002829 quickReject false
2830 ##
2831}
2832##
2833
2834#ToDo incomplete ##
2835
2836##
2837
2838#Method SkRect getLocalClipBounds() const
2839
2840Return bounds of Clip, transformed by inverse of Matrix. If Clip is empty,
2841return SkRect::MakeEmpty, where all Rect sides equal zero.
2842
2843Rect returned is outset by one to account for partial pixel coverage if Clip
Cary Clarkce101242017-09-01 15:51:02 -04002844is Anti-aliased.
Cary Clark8032b982017-07-28 11:04:54 -04002845
Cary Clarkbad5ad72017-08-03 17:14:08 -04002846#Return bounds of Clip in local coordinates ##
Cary Clark8032b982017-07-28 11:04:54 -04002847
2848#Example
2849 #Description
2850 Initial bounds is device bounds outset by 1 on all sides.
2851 Clipped bounds is clipPath bounds outset by 1 on all sides.
2852 Scaling the canvas by two in x and y scales the local bounds by 1/2 in x and y.
2853 ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002854 SkCanvas local(256, 256);
2855 canvas = &local;
2856 SkRect bounds = canvas->getLocalClipBounds();
2857 SkDebugf("left:%g top:%g right:%g bottom:%g\n",
2858 bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom);
2859 SkPoint clipPoints[] = {{30, 130}, {120, 130}, {120, 230} };
2860 SkPath clipPath;
2861 clipPath.addPoly(clipPoints, SK_ARRAY_COUNT(clipPoints), true);
2862 canvas->clipPath(clipPath);
2863 bounds = canvas->getLocalClipBounds();
2864 SkDebugf("left:%g top:%g right:%g bottom:%g\n",
2865 bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom);
2866 canvas->scale(2, 2);
2867 bounds = canvas->getLocalClipBounds();
2868 SkDebugf("left:%g top:%g right:%g bottom:%g\n",
2869 bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom);
2870 #StdOut
2871 left:-1 top:-1 right:257 bottom:257
2872 left:29 top:129 right:121 bottom:231
2873 left:14.5 top:64.5 right:60.5 bottom:115.5
2874 ##
Cary Clark8032b982017-07-28 11:04:54 -04002875##
2876
2877# local canvas in example works around bug in fiddle ##
2878#Bug 6524 ##
2879
2880##
2881
2882#Method bool getLocalClipBounds(SkRect* bounds) const
2883
2884Return bounds of Clip, transformed by inverse of Matrix. If Clip is empty,
2885return false, and set bounds to SkRect::MakeEmpty, where all Rect sides equal zero.
2886
2887bounds is outset by one to account for partial pixel coverage if Clip
Cary Clarkce101242017-09-01 15:51:02 -04002888is Anti-aliased.
Cary Clark8032b982017-07-28 11:04:54 -04002889
Cary Clarkbad5ad72017-08-03 17:14:08 -04002890#Param bounds Rect of Clip in local coordinates ##
Cary Clark8032b982017-07-28 11:04:54 -04002891
Cary Clarkbad5ad72017-08-03 17:14:08 -04002892#Return true if Clip bounds is not empty ##
Cary Clark8032b982017-07-28 11:04:54 -04002893
2894#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04002895 void draw(SkCanvas* canvas) {
2896 SkCanvas local(256, 256);
2897 canvas = &local;
2898 SkRect bounds;
2899 SkDebugf("local bounds empty = %s\n", canvas->getLocalClipBounds(&bounds)
2900 ? "false" : "true");
2901 SkPath path;
2902 canvas->clipPath(path);
2903 SkDebugf("local bounds empty = %s\n", canvas->getLocalClipBounds(&bounds)
2904 ? "false" : "true");
Cary Clark8032b982017-07-28 11:04:54 -04002905 }
2906 #StdOut
Cary Clarkbad5ad72017-08-03 17:14:08 -04002907 local bounds empty = false
Cary Clark8032b982017-07-28 11:04:54 -04002908 local bounds empty = true
2909 ##
2910##
2911
2912# local canvas in example works around bug in fiddle ##
2913#Bug 6524 ##
2914
2915##
2916
2917#Method SkIRect getDeviceClipBounds() const
2918
2919Return IRect bounds of Clip, unaffected by Matrix. If Clip is empty,
2920return SkRect::MakeEmpty, where all Rect sides equal zero.
2921
2922Unlike getLocalClipBounds, returned IRect is not outset.
2923
Cary Clarkbad5ad72017-08-03 17:14:08 -04002924#Return bounds of Clip in Device coordinates ##
Cary Clark8032b982017-07-28 11:04:54 -04002925
2926#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04002927void draw(SkCanvas* canvas) {
2928 #Description
Cary Clark8032b982017-07-28 11:04:54 -04002929 Initial bounds is device bounds, not outset.
2930 Clipped bounds is clipPath bounds, not outset.
2931 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 -04002932 ##
2933 SkCanvas device(256, 256);
2934 canvas = &device;
2935 SkIRect bounds = canvas->getDeviceClipBounds();
2936 SkDebugf("left:%d top:%d right:%d bottom:%d\n",
2937 bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom);
2938 SkPoint clipPoints[] = {{30, 130}, {120, 130}, {120, 230} };
2939 SkPath clipPath;
2940 clipPath.addPoly(clipPoints, SK_ARRAY_COUNT(clipPoints), true);
2941 canvas->save();
2942 canvas->clipPath(clipPath);
2943 bounds = canvas->getDeviceClipBounds();
2944 SkDebugf("left:%d top:%d right:%d bottom:%d\n",
2945 bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom);
2946 canvas->restore();
2947 canvas->scale(1.f/2, 1.f/2);
2948 canvas->clipPath(clipPath);
2949 bounds = canvas->getDeviceClipBounds();
2950 SkDebugf("left:%d top:%d right:%d bottom:%d\n",
2951 bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom);
Cary Clark8032b982017-07-28 11:04:54 -04002952 #StdOut
Cary Clarkbad5ad72017-08-03 17:14:08 -04002953 left:0 top:0 right:256 bottom:256
2954 left:30 top:130 right:120 bottom:230
Cary Clark8032b982017-07-28 11:04:54 -04002955 left:15 top:65 right:60 bottom:115
2956 ##
2957}
2958##
2959
2960#ToDo some confusion on why with an identity Matrix local and device are different ##
2961
2962# device canvas in example works around bug in fiddle ##
2963#Bug 6524 ##
2964
2965##
2966
2967#Method bool getDeviceClipBounds(SkIRect* bounds) const
2968
2969Return IRect bounds of Clip, unaffected by Matrix. If Clip is empty,
2970return false, and set bounds to SkRect::MakeEmpty, where all Rect sides equal zero.
2971
2972Unlike getLocalClipBounds, bounds is not outset.
2973
Cary Clarkbad5ad72017-08-03 17:14:08 -04002974#Param bounds Rect of Clip in device coordinates ##
Cary Clark8032b982017-07-28 11:04:54 -04002975
Cary Clarkbad5ad72017-08-03 17:14:08 -04002976#Return true if Clip bounds is not empty ##
Cary Clark8032b982017-07-28 11:04:54 -04002977
2978#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04002979 void draw(SkCanvas* canvas) {
2980 SkIRect bounds;
2981 SkDebugf("device bounds empty = %s\n", canvas->getDeviceClipBounds(&bounds)
2982 ? "false" : "true");
2983 SkPath path;
2984 canvas->clipPath(path);
2985 SkDebugf("device bounds empty = %s\n", canvas->getDeviceClipBounds(&bounds)
2986 ? "false" : "true");
Cary Clark8032b982017-07-28 11:04:54 -04002987 }
2988 #StdOut
Cary Clarkbad5ad72017-08-03 17:14:08 -04002989 device bounds empty = false
Cary Clark8032b982017-07-28 11:04:54 -04002990 device bounds empty = true
2991 ##
2992##
2993
2994#ToDo incomplete ##
2995
2996##
2997
2998#Topic Clip ##
2999
3000# ------------------------------------------------------------------------------
3001
3002#Method void drawColor(SkColor color, SkBlendMode mode = SkBlendMode::kSrcOver)
3003
3004Fill Clip with Color color.
3005mode determines how Color_ARGB is combined with destination.
3006
Cary Clarkbad5ad72017-08-03 17:14:08 -04003007#Param color Unpremultiplied Color_ARGB ##
3008#Param mode SkBlendMode used to combine source color and destination ##
Cary Clark8032b982017-07-28 11:04:54 -04003009
3010#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003011 canvas->drawColor(SK_ColorRED);
3012 canvas->clipRect(SkRect::MakeWH(150, 150));
3013 canvas->drawColor(SkColorSetARGB(0x80, 0x00, 0xFF, 0x00), SkBlendMode::kPlus);
3014 canvas->clipRect(SkRect::MakeWH(75, 75));
3015 canvas->drawColor(SkColorSetARGB(0x80, 0x00, 0x00, 0xFF), SkBlendMode::kPlus);
Cary Clark8032b982017-07-28 11:04:54 -04003016##
3017
3018#ToDo incomplete ##
3019
3020##
3021
3022# ------------------------------------------------------------------------------
3023
3024#Method void clear(SkColor color)
3025
3026Fill Clip with Color color using SkBlendMode::kSrc.
3027This has the effect of replacing all pixels contained by Clip with color.
3028
Cary Clarkbad5ad72017-08-03 17:14:08 -04003029#Param color Unpremultiplied Color_ARGB ##
Cary Clark8032b982017-07-28 11:04:54 -04003030
3031#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003032void draw(SkCanvas* canvas) {
3033 canvas->save();
3034 canvas->clipRect(SkRect::MakeWH(256, 128));
3035 canvas->clear(SkColorSetARGB(0x80, 0xFF, 0x00, 0x00));
3036 canvas->restore();
3037 canvas->save();
3038 canvas->clipRect(SkRect::MakeWH(150, 192));
3039 canvas->clear(SkColorSetARGB(0x80, 0x00, 0xFF, 0x00));
3040 canvas->restore();
3041 canvas->clipRect(SkRect::MakeWH(75, 256));
3042 canvas->clear(SkColorSetARGB(0x80, 0x00, 0x00, 0xFF));
Cary Clark8032b982017-07-28 11:04:54 -04003043}
3044##
3045
3046#ToDo incomplete ##
3047
3048##
3049
3050# ------------------------------------------------------------------------------
3051
3052#Method void discard()
3053
3054Make Canvas contents undefined. Subsequent calls that read Canvas pixels,
3055such as drawing with SkBlendMode, return undefined results. discard() does
3056not change Clip or Matrix.
3057
3058discard() may do nothing, depending on the implementation of Surface or Device
3059that created Canvas.
3060
3061discard() allows optimized performance on subsequent draws by removing
3062cached data associated with Surface or Device.
3063It is not necessary to call discard() once done with Canvas;
3064any cached data is deleted when owning Surface or Device is deleted.
3065
3066#ToDo example? not sure how to make this meaningful w/o more implementation detail ##
3067
3068#NoExample
3069##
3070
3071##
3072
3073# ------------------------------------------------------------------------------
3074
3075#Method void drawPaint(const SkPaint& paint)
3076
Cary Clarkbad5ad72017-08-03 17:14:08 -04003077Fill Clip with Paint paint. Paint components Rasterizer, Mask_Filter, Shader,
3078Color_Filter, Image_Filter, and Blend_Mode affect drawing;
3079Path_Effect in paint is ignored.
Cary Clark8032b982017-07-28 11:04:54 -04003080
3081# can Path_Effect in paint ever alter drawPaint?
3082
Cary Clarkbad5ad72017-08-03 17:14:08 -04003083#Param paint graphics state used to fill Canvas ##
Cary Clark8032b982017-07-28 11:04:54 -04003084
3085#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003086void draw(SkCanvas* canvas) {
3087 SkColor colors[] = { SK_ColorRED, SK_ColorGREEN, SK_ColorBLUE };
3088 SkScalar pos[] = { 0, SK_Scalar1/2, SK_Scalar1 };
3089 SkPaint paint;
3090 paint.setShader(SkGradientShader::MakeSweep(256, 256, colors, pos, SK_ARRAY_COUNT(colors)));
3091 canvas->drawPaint(paint);
Cary Clark8032b982017-07-28 11:04:54 -04003092}
3093##
3094
3095#ToDo incomplete ##
3096
3097##
3098
3099# ------------------------------------------------------------------------------
3100
3101#Enum PointMode
3102
3103#Code
3104 enum PointMode {
3105 kPoints_PointMode,
3106 kLines_PointMode,
Cary Clarkd0530ba2017-09-14 11:25:39 -04003107 kPolygon_PointMode,
Cary Clark8032b982017-07-28 11:04:54 -04003108 };
3109##
3110
3111Selects if an array of points are drawn as discrete points, as lines, or as
3112an open polygon.
3113
3114#Const kPoints_PointMode 0
3115 Draw each point separately.
3116##
3117
3118#Const kLines_PointMode 1
3119 Draw each pair of points as a line segment.
3120##
3121
3122#Const kPolygon_PointMode 2
3123 Draw the array of points as a open polygon.
3124##
3125
3126#Example
3127 #Description
3128 The upper left corner shows three squares when drawn as points.
3129 The upper right corner shows one line; when drawn as lines, two points are required per line.
3130 The lower right corner shows two lines; when draw as polygon, no miter is drawn at the corner.
3131 The lower left corner shows two lines with a miter when path contains polygon.
3132 ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003133void draw(SkCanvas* canvas) {
3134 SkPaint paint;
3135 paint.setStyle(SkPaint::kStroke_Style);
3136 paint.setStrokeWidth(10);
3137 SkPoint points[] = {{64, 32}, {96, 96}, {32, 96}};
3138 canvas->drawPoints(SkCanvas::kPoints_PointMode, 3, points, paint);
3139 canvas->translate(128, 0);
3140 canvas->drawPoints(SkCanvas::kLines_PointMode, 3, points, paint);
3141 canvas->translate(0, 128);
3142 canvas->drawPoints(SkCanvas::kPolygon_PointMode, 3, points, paint);
3143 SkPath path;
3144 path.addPoly(points, 3, false);
3145 canvas->translate(-128, 0);
3146 canvas->drawPath(path, paint);
Cary Clark8032b982017-07-28 11:04:54 -04003147}
3148##
3149
3150#ToDo incomplete ##
3151
3152##
3153
3154# ------------------------------------------------------------------------------
3155
3156#Method void drawPoints(PointMode mode, size_t count, const SkPoint pts[], const SkPaint& paint)
3157
3158Draw pts using Clip, Matrix and Paint paint.
Cary Clarkbad5ad72017-08-03 17:14:08 -04003159count is the number of points; if count is less than one, has no effect.
Cary Clark8032b982017-07-28 11:04:54 -04003160mode may be one of: kPoints_PointMode, kLines_PointMode, or kPolygon_PointMode.
3161
Cary Clarkbad5ad72017-08-03 17:14:08 -04003162If mode is kPoints_PointMode, the shape of point drawn depends on paint
3163Paint_Stroke_Cap. If paint is set to SkPaint::kRound_Cap, each point draws a
3164circle of diameter Paint_Stroke_Width. If paint is set to SkPaint::kSquare_Cap
3165or SkPaint::kButt_Cap, each point draws a square of width and height
3166Paint_Stroke_Width.
Cary Clark8032b982017-07-28 11:04:54 -04003167
3168If mode is kLines_PointMode, each pair of points draws a line segment.
3169One line is drawn for every two points; each point is used once. If count is odd,
3170the final point is ignored.
3171
3172If mode is kPolygon_PointMode, each adjacent pair of points draws a line segment.
3173count minus one lines are drawn; the first and last point are used once.
3174
3175Each line segment respects paint Paint_Stroke_Cap and Paint_Stroke_Width.
3176Paint_Style is ignored, as if were set to SkPaint::kStroke_Style.
3177
Cary Clarkbad5ad72017-08-03 17:14:08 -04003178Always draws each element one at a time; is not affected by
3179Paint_Stroke_Join, and unlike drawPath, does not create a mask from all points
3180and lines before drawing.
Cary Clark8032b982017-07-28 11:04:54 -04003181
Cary Clarka523d2d2017-08-30 08:58:10 -04003182#Param mode whether pts draws points or lines ##
3183#Param count number of points in the array ##
3184#Param pts array of points to draw ##
3185#Param paint stroke, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003186
3187#Example
3188#Height 200
3189 #Description
3190 #List
3191 # The first column draws points. ##
3192 # The second column draws points as lines. ##
3193 # The third column draws points as a polygon. ##
3194 # The fourth column draws points as a polygonal path. ##
3195 # The first row uses a round cap and round join. ##
3196 # The second row uses a square cap and a miter join. ##
3197 # The third row uses a butt cap and a bevel join. ##
3198 ##
3199 The transparent color makes multiple line draws visible;
3200 the path is drawn all at once.
3201 ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003202void draw(SkCanvas* canvas) {
3203 SkPaint paint;
3204 paint.setAntiAlias(true);
3205 paint.setStyle(SkPaint::kStroke_Style);
3206 paint.setStrokeWidth(10);
3207 paint.setColor(0x80349a45);
3208 const SkPoint points[] = {{32, 16}, {48, 48}, {16, 32}};
3209 const SkPaint::Join join[] = { SkPaint::kRound_Join,
3210 SkPaint::kMiter_Join,
3211 SkPaint::kBevel_Join };
3212 int joinIndex = 0;
3213 SkPath path;
3214 path.addPoly(points, 3, false);
3215 for (const auto cap : { SkPaint::kRound_Cap, SkPaint::kSquare_Cap, SkPaint::kButt_Cap } ) {
3216 paint.setStrokeCap(cap);
3217 paint.setStrokeJoin(join[joinIndex++]);
3218 for (const auto mode : { SkCanvas::kPoints_PointMode,
3219 SkCanvas::kLines_PointMode,
3220 SkCanvas::kPolygon_PointMode } ) {
3221 canvas->drawPoints(mode, 3, points, paint);
3222 canvas->translate(64, 0);
3223 }
3224 canvas->drawPath(path, paint);
3225 canvas->translate(-192, 64);
3226 }
Cary Clark8032b982017-07-28 11:04:54 -04003227}
3228##
3229
3230#ToDo incomplete ##
3231
3232##
3233
3234# ------------------------------------------------------------------------------
3235
3236#Method void drawPoint(SkScalar x, SkScalar y, const SkPaint& paint)
3237
3238Draw point at (x, y) using Clip, Matrix and Paint paint.
3239
3240The shape of point drawn depends on paint Paint_Stroke_Cap.
Cary Clarkbad5ad72017-08-03 17:14:08 -04003241If paint is set to SkPaint::kRound_Cap, draw a circle of diameter
3242Paint_Stroke_Width. If paint is set to SkPaint::kSquare_Cap or SkPaint::kButt_Cap,
Cary Clark8032b982017-07-28 11:04:54 -04003243draw a square of width and height Paint_Stroke_Width.
3244Paint_Style is ignored, as if were set to SkPaint::kStroke_Style.
3245
Cary Clarkbad5ad72017-08-03 17:14:08 -04003246#Param x left edge of circle or square ##
3247#Param y top edge of circle or square ##
3248#Param paint stroke, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003249
3250#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003251void draw(SkCanvas* canvas) {
3252 SkPaint paint;
3253 paint.setAntiAlias(true);
3254 paint.setColor(0x80349a45);
3255 paint.setStyle(SkPaint::kStroke_Style);
3256 paint.setStrokeWidth(100);
3257 paint.setStrokeCap(SkPaint::kRound_Cap);
3258 canvas->scale(1, 1.2f);
3259 canvas->drawPoint(64, 96, paint);
3260 canvas->scale(.6f, .8f);
3261 paint.setColor(SK_ColorWHITE);
3262 canvas->drawPoint(106, 120, paint);
Cary Clark8032b982017-07-28 11:04:54 -04003263}
3264##
3265
3266#ToDo incomplete ##
3267
3268##
3269
Cary Clarkbad5ad72017-08-03 17:14:08 -04003270#Method void drawPoint(SkPoint p, const SkPaint& paint)
3271
3272Draw point p using Clip, Matrix and Paint paint.
3273
3274The shape of point drawn depends on paint Paint_Stroke_Cap.
3275If paint is set to SkPaint::kRound_Cap, draw a circle of diameter
3276Paint_Stroke_Width. If paint is set to SkPaint::kSquare_Cap or SkPaint::kButt_Cap,
3277draw a square of width and height Paint_Stroke_Width.
3278Paint_Style is ignored, as if were set to SkPaint::kStroke_Style.
3279
3280#Param p top-left edge of circle or square ##
3281#Param paint stroke, blend, color, and so on, used to draw ##
3282
3283#Example
3284void draw(SkCanvas* canvas) {
3285 SkPaint paint;
3286 paint.setAntiAlias(true);
3287 paint.setColor(0x80349a45);
3288 paint.setStyle(SkPaint::kStroke_Style);
3289 paint.setStrokeWidth(100);
3290 paint.setStrokeCap(SkPaint::kSquare_Cap);
3291 canvas->scale(1, 1.2f);
3292 canvas->drawPoint({64, 96}, paint);
3293 canvas->scale(.6f, .8f);
3294 paint.setColor(SK_ColorWHITE);
3295 canvas->drawPoint(106, 120, paint);
3296}
3297##
3298
3299#SeeAlso drawPoints drawCircle drawRect
3300
3301##
3302
Cary Clark8032b982017-07-28 11:04:54 -04003303# ------------------------------------------------------------------------------
3304
3305#Method void drawLine(SkScalar x0, SkScalar y0, SkScalar x1, SkScalar y1, const SkPaint& paint)
3306
Cary Clarkbad5ad72017-08-03 17:14:08 -04003307Draws line segment from (x0, y0) to (x1, y1) using Clip, Matrix, and Paint paint.
3308In paint: Paint_Stroke_Width describes the line thickness;
3309Paint_Stroke_Cap draws the end rounded or square;
Cary Clark8032b982017-07-28 11:04:54 -04003310Paint_Style is ignored, as if were set to SkPaint::kStroke_Style.
3311
Cary Clarkbad5ad72017-08-03 17:14:08 -04003312#Param x0 start of line segment on x-axis ##
3313#Param y0 start of line segment on y-axis ##
3314#Param x1 end of line segment on x-axis ##
3315#Param y1 end of line segment on y-axis ##
3316#Param paint stroke, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003317
3318#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003319 SkPaint paint;
3320 paint.setAntiAlias(true);
3321 paint.setColor(0xFF9a67be);
3322 paint.setStrokeWidth(20);
3323 canvas->skew(1, 0);
3324 canvas->drawLine(32, 96, 32, 160, paint);
3325 canvas->skew(-2, 0);
3326 canvas->drawLine(288, 96, 288, 160, paint);
3327##
3328
3329#ToDo incomplete ##
3330
3331##
3332
3333#Method void drawLine(SkPoint p0, SkPoint p1, const SkPaint& paint)
3334
3335Draws line segment from p0 to p1 using Clip, Matrix, and Paint paint.
3336In paint: Paint_Stroke_Width describes the line thickness;
3337Paint_Stroke_Cap draws the end rounded or square;
3338Paint_Style is ignored, as if were set to SkPaint::kStroke_Style.
3339
3340#Param p0 start of line segment ##
3341#Param p1 end of line segment ##
3342#Param paint stroke, blend, color, and so on, used to draw ##
3343
3344#Example
3345 SkPaint paint;
3346 paint.setAntiAlias(true);
3347 paint.setColor(0xFF9a67be);
3348 paint.setStrokeWidth(20);
3349 canvas->skew(1, 0);
3350 canvas->drawLine({32, 96}, {32, 160}, paint);
3351 canvas->skew(-2, 0);
3352 canvas->drawLine({288, 96}, {288, 160}, paint);
Cary Clark8032b982017-07-28 11:04:54 -04003353##
3354
3355#ToDo incomplete ##
3356
3357##
3358
3359# ------------------------------------------------------------------------------
3360
3361#Method void drawRect(const SkRect& rect, const SkPaint& paint)
3362
3363Draw Rect rect using Clip, Matrix, and Paint paint.
3364In paint: Paint_Style determines if rectangle is stroked or filled;
3365if stroked, Paint_Stroke_Width describes the line thickness, and
3366Paint_Stroke_Join draws the corners rounded or square.
3367
Cary Clarkbc5697d2017-10-04 14:31:33 -04003368#Param rect rectangle to draw ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003369#Param paint stroke or fill, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003370
3371#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003372void draw(SkCanvas* canvas) {
3373 SkPoint rectPts[] = { {64, 48}, {192, 160} };
3374 SkPaint paint;
3375 paint.setAntiAlias(true);
3376 paint.setStyle(SkPaint::kStroke_Style);
3377 paint.setStrokeWidth(20);
3378 paint.setStrokeJoin(SkPaint::kRound_Join);
3379 SkMatrix rotator;
3380 rotator.setRotate(30, 128, 128);
3381 for (auto color : { SK_ColorRED, SK_ColorBLUE, SK_ColorYELLOW, SK_ColorMAGENTA } ) {
3382 paint.setColor(color);
3383 SkRect rect;
3384 rect.set(rectPts[0], rectPts[1]);
3385 canvas->drawRect(rect, paint);
3386 rotator.mapPoints(rectPts, 2);
3387 }
Cary Clark8032b982017-07-28 11:04:54 -04003388}
3389##
3390
3391#ToDo incomplete ##
3392
3393##
3394
3395# ------------------------------------------------------------------------------
3396
3397#Method void drawIRect(const SkIRect& rect, const SkPaint& paint)
3398
3399Draw IRect rect using Clip, Matrix, and Paint paint.
3400In paint: Paint_Style determines if rectangle is stroked or filled;
3401if stroked, Paint_Stroke_Width describes the line thickness, and
3402Paint_Stroke_Join draws the corners rounded or square.
3403
Cary Clarkbc5697d2017-10-04 14:31:33 -04003404#Param rect rectangle to draw ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003405#Param paint stroke or fill, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003406
3407#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003408 SkIRect rect = { 64, 48, 192, 160 };
3409 SkPaint paint;
3410 paint.setAntiAlias(true);
3411 paint.setStyle(SkPaint::kStroke_Style);
3412 paint.setStrokeWidth(20);
3413 paint.setStrokeJoin(SkPaint::kRound_Join);
3414 for (auto color : { SK_ColorRED, SK_ColorBLUE, SK_ColorYELLOW, SK_ColorMAGENTA } ) {
3415 paint.setColor(color);
3416 canvas->drawIRect(rect, paint);
3417 canvas->rotate(30, 128, 128);
3418 }
Cary Clark8032b982017-07-28 11:04:54 -04003419##
3420
3421#ToDo incomplete ##
3422
3423##
3424
3425# ------------------------------------------------------------------------------
3426
3427#Method void drawRegion(const SkRegion& region, const SkPaint& paint)
3428
3429Draw Region region using Clip, Matrix, and Paint paint.
3430In paint: Paint_Style determines if rectangle is stroked or filled;
3431if stroked, Paint_Stroke_Width describes the line thickness, and
3432Paint_Stroke_Join draws the corners rounded or square.
3433
Cary Clarkbc5697d2017-10-04 14:31:33 -04003434#Param region region to draw ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003435#Param paint Paint stroke or fill, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003436
3437#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003438void draw(SkCanvas* canvas) {
3439 SkRegion region;
3440 region.op( 10, 10, 50, 50, SkRegion::kUnion_Op);
3441 region.op( 10, 50, 90, 90, SkRegion::kUnion_Op);
3442 SkPaint paint;
3443 paint.setAntiAlias(true);
3444 paint.setStyle(SkPaint::kStroke_Style);
3445 paint.setStrokeWidth(20);
3446 paint.setStrokeJoin(SkPaint::kRound_Join);
3447 canvas->drawRegion(region, paint);
Cary Clark8032b982017-07-28 11:04:54 -04003448}
3449##
3450
3451#ToDo incomplete ##
3452
3453##
3454
3455# ------------------------------------------------------------------------------
3456
3457#Method void drawOval(const SkRect& oval, const SkPaint& paint)
3458
3459Draw Oval oval using Clip, Matrix, and Paint.
3460In paint: Paint_Style determines if Oval is stroked or filled;
3461if stroked, Paint_Stroke_Width describes the line thickness.
3462
Cary Clarkbad5ad72017-08-03 17:14:08 -04003463#Param oval Rect bounds of Oval ##
3464#Param paint Paint stroke or fill, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003465
3466#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003467void draw(SkCanvas* canvas) {
3468 canvas->clear(0xFF3f5f9f);
3469 SkColor kColor1 = SkColorSetARGB(0xff, 0xff, 0x7f, 0);
3470 SkColor g1Colors[] = { kColor1, SkColorSetA(kColor1, 0x20) };
3471 SkPoint g1Points[] = { { 0, 0 }, { 0, 100 } };
3472 SkScalar pos[] = { 0.2f, 1.0f };
3473 SkRect bounds = SkRect::MakeWH(80, 70);
3474 SkPaint paint;
3475 paint.setAntiAlias(true);
3476 paint.setShader(SkGradientShader::MakeLinear(g1Points, g1Colors, pos, SK_ARRAY_COUNT(g1Colors),
3477 SkShader::kClamp_TileMode));
3478 canvas->drawOval(bounds , paint);
Cary Clark8032b982017-07-28 11:04:54 -04003479}
3480##
3481
3482#ToDo incomplete ##
3483
3484##
3485
3486# ------------------------------------------------------------------------------
3487
3488#Method void drawRRect(const SkRRect& rrect, const SkPaint& paint)
3489
3490Draw Round_Rect rrect using Clip, Matrix, and Paint paint.
3491In paint: Paint_Style determines if rrect is stroked or filled;
3492if stroked, Paint_Stroke_Width describes the line thickness.
3493
Cary Clarkbad5ad72017-08-03 17:14:08 -04003494rrect may represent a rectangle, circle, oval, uniformly rounded rectangle, or
3495may have any combination of positive non-square radii for the four corners.
Cary Clark8032b982017-07-28 11:04:54 -04003496
Cary Clarkbad5ad72017-08-03 17:14:08 -04003497#Param rrect Round_Rect with up to eight corner radii to draw ##
3498#Param paint Paint stroke or fill, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003499
3500#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003501void draw(SkCanvas* canvas) {
3502 SkPaint paint;
3503 paint.setAntiAlias(true);
3504 SkRect outer = {30, 40, 210, 220};
3505 SkRect radii = {30, 50, 70, 90 };
3506 SkRRect rRect;
3507 rRect.setNinePatch(outer, radii.fLeft, radii.fTop, radii.fRight, radii.fBottom);
3508 canvas->drawRRect(rRect, paint);
3509 paint.setColor(SK_ColorWHITE);
3510 canvas->drawLine(outer.fLeft + radii.fLeft, outer.fTop,
3511 outer.fLeft + radii.fLeft, outer.fBottom, paint);
3512 canvas->drawLine(outer.fRight - radii.fRight, outer.fTop,
3513 outer.fRight - radii.fRight, outer.fBottom, paint);
3514 canvas->drawLine(outer.fLeft, outer.fTop + radii.fTop,
3515 outer.fRight, outer.fTop + radii.fTop, paint);
3516 canvas->drawLine(outer.fLeft, outer.fBottom - radii.fBottom,
3517 outer.fRight, outer.fBottom - radii.fBottom, paint);
3518}
Cary Clark8032b982017-07-28 11:04:54 -04003519##
3520
3521#ToDo incomplete ##
3522
3523##
3524
3525# ------------------------------------------------------------------------------
3526
3527#Method void drawDRRect(const SkRRect& outer, const SkRRect& inner, const SkPaint& paint)
3528
3529Draw Round_Rect outer and inner
3530using Clip, Matrix, and Paint paint.
3531outer must contain inner or the drawing is undefined.
Cary Clarkce101242017-09-01 15:51:02 -04003532In paint: Paint_Style determines if Round_Rect is stroked or filled;
Cary Clark8032b982017-07-28 11:04:54 -04003533if stroked, Paint_Stroke_Width describes the line thickness.
Cary Clarkbad5ad72017-08-03 17:14:08 -04003534If stroked and Round_Rect corner has zero length radii, Paint_Stroke_Join can
3535draw corners rounded or square.
Cary Clark8032b982017-07-28 11:04:54 -04003536
Cary Clarkbad5ad72017-08-03 17:14:08 -04003537GPU-backed platforms optimize drawing when both outer and inner are
Cary Clark8032b982017-07-28 11:04:54 -04003538concave and outer contains inner. These platforms may not be able to draw
3539Path built with identical data as fast.
3540
Cary Clarkbad5ad72017-08-03 17:14:08 -04003541#Param outer Round_Rect outer bounds to draw ##
3542#Param inner Round_Rect inner bounds to draw ##
3543#Param paint Paint stroke or fill, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003544
3545#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003546void draw(SkCanvas* canvas) {
3547 SkRRect outer = SkRRect::MakeRect({20, 40, 210, 200});
3548 SkRRect inner = SkRRect::MakeOval({60, 70, 170, 160});
3549 SkPaint paint;
3550 canvas->drawDRRect(outer, inner, paint);
Cary Clark8032b982017-07-28 11:04:54 -04003551}
3552##
3553
3554#Example
3555#Description
3556 Outer Rect has no corner radii, but stroke join is rounded.
3557 Inner Round_Rect has corner radii; outset stroke increases radii of corners.
3558 Stroke join does not affect inner Round_Rect since it has no sharp corners.
3559##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003560void draw(SkCanvas* canvas) {
3561 SkRRect outer = SkRRect::MakeRect({20, 40, 210, 200});
3562 SkRRect inner = SkRRect::MakeRectXY({60, 70, 170, 160}, 10, 10);
3563 SkPaint paint;
3564 paint.setAntiAlias(true);
3565 paint.setStyle(SkPaint::kStroke_Style);
3566 paint.setStrokeWidth(20);
3567 paint.setStrokeJoin(SkPaint::kRound_Join);
3568 canvas->drawDRRect(outer, inner, paint);
3569 paint.setStrokeWidth(1);
3570 paint.setColor(SK_ColorWHITE);
3571 canvas->drawDRRect(outer, inner, paint);
Cary Clark8032b982017-07-28 11:04:54 -04003572}
3573##
3574
3575#ToDo incomplete ##
3576
3577##
3578
3579# ------------------------------------------------------------------------------
3580
3581#Method void drawCircle(SkScalar cx, SkScalar cy, SkScalar radius, const SkPaint& paint)
3582
3583Draw Circle at (cx, cy) with radius using Clip, Matrix, and Paint paint.
3584If radius is zero or less, nothing is drawn.
3585In paint: Paint_Style determines if Circle is stroked or filled;
3586if stroked, Paint_Stroke_Width describes the line thickness.
3587
Cary Clarkbad5ad72017-08-03 17:14:08 -04003588#Param cx Circle center on the x-axis ##
3589#Param cy Circle center on the y-axis ##
3590#Param radius half the diameter of Circle ##
3591#Param paint Paint stroke or fill, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003592
3593#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003594 void draw(SkCanvas* canvas) {
3595 SkPaint paint;
3596 paint.setAntiAlias(true);
3597 canvas->drawCircle(128, 128, 90, paint);
3598 paint.setColor(SK_ColorWHITE);
3599 canvas->drawCircle(86, 86, 20, paint);
3600 canvas->drawCircle(160, 76, 20, paint);
3601 canvas->drawCircle(140, 150, 35, paint);
3602 }
3603##
3604
3605#ToDo incomplete ##
3606
3607##
3608
3609#Method void drawCircle(SkPoint center, SkScalar radius, const SkPaint& paint)
3610
Cary Clarkce101242017-09-01 15:51:02 -04003611Draw Circle at center with radius using Clip, Matrix, and Paint paint.
Cary Clarkbad5ad72017-08-03 17:14:08 -04003612If radius is zero or less, nothing is drawn.
3613In paint: Paint_Style determines if Circle is stroked or filled;
3614if stroked, Paint_Stroke_Width describes the line thickness.
3615
3616#Param center Circle center ##
3617#Param radius half the diameter of Circle ##
3618#Param paint Paint stroke or fill, blend, color, and so on, used to draw ##
3619
3620#Example
3621 void draw(SkCanvas* canvas) {
3622 SkPaint paint;
3623 paint.setAntiAlias(true);
3624 canvas->drawCircle(128, 128, 90, paint);
3625 paint.setColor(SK_ColorWHITE);
3626 canvas->drawCircle({86, 86}, 20, paint);
3627 canvas->drawCircle({160, 76}, 20, paint);
3628 canvas->drawCircle({140, 150}, 35, paint);
3629 }
Cary Clark8032b982017-07-28 11:04:54 -04003630##
3631
3632#ToDo incomplete ##
3633
3634##
3635
3636# ------------------------------------------------------------------------------
3637
3638#Method void drawArc(const SkRect& oval, SkScalar startAngle, SkScalar sweepAngle,
3639 bool useCenter, const SkPaint& paint)
3640
3641Draw Arc using Clip, Matrix, and Paint paint.
Cary Clarkbad5ad72017-08-03 17:14:08 -04003642
Cary Clark8032b982017-07-28 11:04:54 -04003643Arc is part of Oval bounded by oval, sweeping from startAngle to startAngle plus
3644sweepAngle. startAngle and sweepAngle are in degrees.
Cary Clarkbad5ad72017-08-03 17:14:08 -04003645
Cary Clark8032b982017-07-28 11:04:54 -04003646startAngle of zero places start point at the right middle edge of oval.
3647A positive sweepAngle places Arc end point clockwise from start point;
3648a negative sweepAngle places Arc end point counterclockwise from start point.
3649sweepAngle may exceed 360 degrees, a full circle.
3650If useCenter is true, draw a wedge that includes lines from oval
3651center to Arc end points. If useCenter is false, draw Arc between end points.
3652
3653If Rect oval is empty or sweepAngle is zero, nothing is drawn.
3654
Cary Clarkbad5ad72017-08-03 17:14:08 -04003655#Param oval Rect bounds of Oval containing Arc to draw ##
3656#Param startAngle angle in degrees where Arc begins ##
3657#Param sweepAngle sweep angle in degrees; positive is clockwise ##
3658#Param useCenter if true, include the center of the oval ##
3659#Param paint Paint stroke or fill, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003660
3661#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003662 void draw(SkCanvas* canvas) {
3663 SkPaint paint;
3664 paint.setAntiAlias(true);
3665 SkRect oval = { 4, 4, 60, 60};
3666 for (auto useCenter : { false, true } ) {
3667 for (auto style : { SkPaint::kFill_Style, SkPaint::kStroke_Style } ) {
3668 paint.setStyle(style);
3669 for (auto degrees : { 45, 90, 180, 360} ) {
3670 canvas->drawArc(oval, 0, degrees , useCenter, paint);
3671 canvas->translate(64, 0);
3672 }
3673 canvas->translate(-256, 64);
3674 }
3675 }
Cary Clark8032b982017-07-28 11:04:54 -04003676 }
3677##
3678
3679#Example
3680#Height 64
Cary Clarkbad5ad72017-08-03 17:14:08 -04003681 void draw(SkCanvas* canvas) {
3682 SkPaint paint;
3683 paint.setAntiAlias(true);
3684 paint.setStyle(SkPaint::kStroke_Style);
3685 paint.setStrokeWidth(4);
3686 SkRect oval = { 4, 4, 60, 60};
3687 float intervals[] = { 5, 5 };
3688 paint.setPathEffect(SkDashPathEffect::Make(intervals, 2, 2.5f));
3689 for (auto degrees : { 270, 360, 540, 720 } ) {
3690 canvas->drawArc(oval, 0, degrees, false, paint);
3691 canvas->translate(64, 0);
3692 }
Cary Clark8032b982017-07-28 11:04:54 -04003693 }
3694##
3695
3696#ToDo incomplete ##
3697
3698##
3699
3700# ------------------------------------------------------------------------------
3701
3702#Method void drawRoundRect(const SkRect& rect, SkScalar rx, SkScalar ry, const SkPaint& paint)
3703
Cary Clarkbad5ad72017-08-03 17:14:08 -04003704Draw Round_Rect bounded by Rect rect, with corner radii (rx, ry) using Clip,
3705Matrix, and Paint paint.
3706
Cary Clark8032b982017-07-28 11:04:54 -04003707In paint: Paint_Style determines if Round_Rect is stroked or filled;
3708if stroked, Paint_Stroke_Width describes the line thickness.
3709If rx or ry are less than zero, they are treated as if they are zero.
3710If rx plus ry exceeds rect width or rect height, radii are scaled down to fit.
Cary Clarkbad5ad72017-08-03 17:14:08 -04003711If rx and ry are zero, Round_Rect is drawn as Rect and if stroked is affected by
3712Paint_Stroke_Join.
Cary Clark8032b982017-07-28 11:04:54 -04003713
Cary Clarkbad5ad72017-08-03 17:14:08 -04003714#Param rect Rect bounds of Round_Rect to draw ##
Cary Clarkce101242017-09-01 15:51:02 -04003715#Param rx axis length in x of oval describing rounded corners ##
3716#Param ry axis length in y of oval describing rounded corners ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003717#Param paint stroke, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003718
3719#Example
3720#Description
3721 Top row has a zero radius a generates a rectangle.
3722 Second row radii sum to less than sides.
3723 Third row radii sum equals sides.
3724 Fourth row radii sum exceeds sides; radii are scaled to fit.
3725##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003726 void draw(SkCanvas* canvas) {
3727 SkVector radii[] = { {0, 20}, {10, 10}, {10, 20}, {10, 40} };
3728 SkPaint paint;
3729 paint.setStrokeWidth(15);
3730 paint.setStrokeJoin(SkPaint::kRound_Join);
3731 paint.setAntiAlias(true);
3732 for (auto style : { SkPaint::kStroke_Style, SkPaint::kFill_Style } ) {
3733 paint.setStyle(style );
3734 for (size_t i = 0; i < SK_ARRAY_COUNT(radii); ++i) {
3735 canvas->drawRoundRect({10, 10, 60, 40}, radii[i].fX, radii[i].fY, paint);
3736 canvas->translate(0, 60);
3737 }
3738 canvas->translate(80, -240);
3739 }
Cary Clark8032b982017-07-28 11:04:54 -04003740 }
3741##
3742
3743#ToDo incomplete ##
3744
3745##
3746
3747# ------------------------------------------------------------------------------
3748
3749#Method void drawPath(const SkPath& path, const SkPaint& paint)
3750
3751Draw Path path using Clip, Matrix, and Paint paint.
3752Path contains an array of Path_Contour, each of which may be open or closed.
3753
3754In paint: Paint_Style determines if Round_Rect is stroked or filled:
Cary Clarkbad5ad72017-08-03 17:14:08 -04003755if filled, Path_Fill_Type determines whether Path_Contour describes inside or
3756outside of fill; if stroked, Paint_Stroke_Width describes the line thickness,
3757Paint_Stroke_Cap describes line ends, and Paint_Stroke_Join describes how
3758corners are drawn.
Cary Clark8032b982017-07-28 11:04:54 -04003759
Cary Clarkbad5ad72017-08-03 17:14:08 -04003760#Param path Path to draw ##
3761#Param paint stroke, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003762
3763#Example
3764#Description
3765 Top rows draw stroked path with combinations of joins and caps. The open contour
3766 is affected by caps; the closed contour is affected by joins.
3767 Bottom row draws fill the same for open and closed contour.
3768 First bottom column shows winding fills overlap.
3769 Second bottom column shows even odd fills exclude overlap.
3770 Third bottom column shows inverse winding fills area outside both contours.
3771##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003772void draw(SkCanvas* canvas) {
3773 SkPath path;
3774 path.moveTo(20, 20);
3775 path.quadTo(60, 20, 60, 60);
3776 path.close();
3777 path.moveTo(60, 20);
3778 path.quadTo(60, 60, 20, 60);
3779 SkPaint paint;
3780 paint.setStrokeWidth(10);
3781 paint.setAntiAlias(true);
3782 paint.setStyle(SkPaint::kStroke_Style);
3783 for (auto join: { SkPaint::kBevel_Join, SkPaint::kRound_Join, SkPaint::kMiter_Join } ) {
3784 paint.setStrokeJoin(join);
3785 for (auto cap: { SkPaint::kButt_Cap, SkPaint::kSquare_Cap, SkPaint::kRound_Cap } ) {
3786 paint.setStrokeCap(cap);
3787 canvas->drawPath(path, paint);
3788 canvas->translate(80, 0);
3789 }
3790 canvas->translate(-240, 60);
3791 }
3792 paint.setStyle(SkPaint::kFill_Style);
3793 for (auto fill : { SkPath::kWinding_FillType,
3794 SkPath::kEvenOdd_FillType,
3795 SkPath::kInverseWinding_FillType } ) {
3796 path.setFillType(fill);
3797 canvas->save();
3798 canvas->clipRect({0, 10, 80, 70});
3799 canvas->drawPath(path, paint);
3800 canvas->restore();
3801 canvas->translate(80, 0);
3802 }
Cary Clark8032b982017-07-28 11:04:54 -04003803}
3804##
3805
3806#ToDo incomplete ##
3807
3808##
3809
3810# ------------------------------------------------------------------------------
3811#Topic Draw_Image
3812
Cary Clarkbad5ad72017-08-03 17:14:08 -04003813drawImage, drawImageRect, and drawImageNine can be called with a bare pointer or
3814a smart pointer as a convenience. The pairs of calls are otherwise identical.
Cary Clark8032b982017-07-28 11:04:54 -04003815
Cary Clark73fa9722017-08-29 17:36:51 -04003816#Method void drawImage(const SkImage* image, SkScalar left, SkScalar top, const SkPaint* paint = nullptr)
Cary Clark8032b982017-07-28 11:04:54 -04003817
3818Draw Image image, with its top-left corner at (left, top),
3819using Clip, Matrix, and optional Paint paint.
3820
Cary Clarkbad5ad72017-08-03 17:14:08 -04003821If paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter, Blend_Mode,
3822and Draw_Looper. If image is kAlpha_8_SkColorType, apply Shader.
3823If paint contains Mask_Filter, generate mask from image bounds. If generated
3824mask extends beyond image bounds, replicate image edge colors, just as Shader
3825made from SkImage::makeShader with SkShader::kClamp_TileMode set replicates the
Cary Clarkbc5697d2017-10-04 14:31:33 -04003826image edge color when it samples outside of its bounds.
Cary Clark8032b982017-07-28 11:04:54 -04003827
Cary Clarkbad5ad72017-08-03 17:14:08 -04003828#Param image uncompressed rectangular map of pixels ##
3829#Param left left side of image ##
3830#Param top top side of image ##
3831#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
3832 and so on; or nullptr
3833##
Cary Clark8032b982017-07-28 11:04:54 -04003834
3835#Example
3836#Height 64
3837#Image 4
Cary Clarkbad5ad72017-08-03 17:14:08 -04003838void draw(SkCanvas* canvas) {
3839 // sk_sp<SkImage> image;
3840 SkImage* imagePtr = image.get();
3841 canvas->drawImage(imagePtr, 0, 0);
3842 SkPaint paint;
3843 canvas->drawImage(imagePtr, 80, 0, &paint);
3844 paint.setAlpha(0x80);
3845 canvas->drawImage(imagePtr, 160, 0, &paint);
Cary Clark8032b982017-07-28 11:04:54 -04003846}
3847##
3848
3849#ToDo incomplete ##
3850
3851##
3852
3853# ------------------------------------------------------------------------------
3854
3855#Method void drawImage(const sk_sp<SkImage>& image, SkScalar left, SkScalar top,
Cary Clark73fa9722017-08-29 17:36:51 -04003856 const SkPaint* paint = nullptr)
Cary Clark8032b982017-07-28 11:04:54 -04003857
3858Draw Image image, with its top-left corner at (left, top),
3859using Clip, Matrix, and optional Paint paint.
3860
Cary Clarkbad5ad72017-08-03 17:14:08 -04003861If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
3862Blend_Mode, and Draw_Looper. If image is kAlpha_8_SkColorType, apply Shader.
3863If paint contains Mask_Filter, generate mask from image bounds. If generated
3864mask extends beyond image bounds, replicate image edge colors, just as Shader
3865made from SkImage::makeShader with SkShader::kClamp_TileMode set replicates the
Cary Clarkbc5697d2017-10-04 14:31:33 -04003866image edge color when it samples outside of its bounds.
Cary Clark8032b982017-07-28 11:04:54 -04003867
Cary Clarkbad5ad72017-08-03 17:14:08 -04003868#Param image uncompressed rectangular map of pixels ##
3869#Param left left side of image ##
3870#Param top pop side of image ##
3871#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
3872 and so on; or nullptr
3873##
Cary Clark8032b982017-07-28 11:04:54 -04003874
3875#Example
3876#Height 64
3877#Image 4
Cary Clarkbad5ad72017-08-03 17:14:08 -04003878void draw(SkCanvas* canvas) {
3879 // sk_sp<SkImage> image;
3880 canvas->drawImage(image, 0, 0);
3881 SkPaint paint;
3882 canvas->drawImage(image, 80, 0, &paint);
3883 paint.setAlpha(0x80);
3884 canvas->drawImage(image, 160, 0, &paint);
Cary Clark8032b982017-07-28 11:04:54 -04003885}
3886##
3887
3888#ToDo incomplete ##
3889
3890##
3891
3892# ------------------------------------------------------------------------------
3893
3894#Enum SrcRectConstraint
3895
3896#Code
3897 enum SrcRectConstraint {
3898 kStrict_SrcRectConstraint,
3899 kFast_SrcRectConstraint,
3900 };
3901##
3902
Cary Clarkce101242017-09-01 15:51:02 -04003903SrcRectConstraint controls the behavior at the edge of source Rect,
3904provided to drawImageRect, trading off speed for precision.
Cary Clark8032b982017-07-28 11:04:54 -04003905
Cary Clarkce101242017-09-01 15:51:02 -04003906Image_Filter in Paint may sample multiple pixels in the image. Source Rect
Cary Clarkbad5ad72017-08-03 17:14:08 -04003907restricts the bounds of pixels that may be read. Image_Filter may slow down if
Cary Clarkce101242017-09-01 15:51:02 -04003908it cannot read outside the bounds, when sampling near the edge of source Rect.
Cary Clark8032b982017-07-28 11:04:54 -04003909SrcRectConstraint specifies whether an Image_Filter is allowed to read pixels
Cary Clarkce101242017-09-01 15:51:02 -04003910outside source Rect.
Cary Clark8032b982017-07-28 11:04:54 -04003911
3912#Const kStrict_SrcRectConstraint
Cary Clarkce101242017-09-01 15:51:02 -04003913 Requires Image_Filter to respect source Rect,
Cary Clark8032b982017-07-28 11:04:54 -04003914 sampling only inside of its bounds, possibly with a performance penalty.
3915##
3916
3917#Const kFast_SrcRectConstraint
Cary Clarkce101242017-09-01 15:51:02 -04003918 Permits Image_Filter to sample outside of source Rect
Cary Clark8032b982017-07-28 11:04:54 -04003919 by half the width of Image_Filter, permitting it to run faster but with
3920 error at the image edges.
3921##
3922
3923#Example
3924#Height 64
3925#Description
3926 redBorder contains a black and white checkerboard bordered by red.
3927 redBorder is drawn scaled by 16 on the left.
Cary Clarkce101242017-09-01 15:51:02 -04003928 The middle and right bitmaps are filtered checkerboards.
Cary Clark8032b982017-07-28 11:04:54 -04003929 Drawing the checkerboard with kStrict_SrcRectConstraint shows only a blur of black and white.
3930 Drawing the checkerboard with kFast_SrcRectConstraint allows red to bleed in the corners.
3931##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003932void draw(SkCanvas* canvas) {
3933 SkBitmap redBorder;
3934 redBorder.allocPixels(SkImageInfo::MakeN32Premul(4, 4));
3935 SkCanvas checkRed(redBorder);
3936 checkRed.clear(SK_ColorRED);
3937 uint32_t checkers[][2] = { { SK_ColorBLACK, SK_ColorWHITE },
3938 { SK_ColorWHITE, SK_ColorBLACK } };
3939 checkRed.writePixels(
3940 SkImageInfo::MakeN32Premul(2, 2), (void*) checkers, sizeof(checkers[0]), 1, 1);
3941 canvas->scale(16, 16);
3942 canvas->drawBitmap(redBorder, 0, 0, nullptr);
3943 canvas->resetMatrix();
3944 sk_sp<SkImage> image = SkImage::MakeFromBitmap(redBorder);
3945 SkPaint lowPaint;
3946 lowPaint.setFilterQuality(kLow_SkFilterQuality);
3947 for (auto constraint : { SkCanvas::kStrict_SrcRectConstraint,
3948 SkCanvas::kFast_SrcRectConstraint } ) {
3949 canvas->translate(80, 0);
3950 canvas->drawImageRect(image.get(), SkRect::MakeLTRB(1, 1, 3, 3),
3951 SkRect::MakeLTRB(16, 16, 48, 48), &lowPaint, constraint);
3952 }
Cary Clark8032b982017-07-28 11:04:54 -04003953}
3954##
3955
3956#ToDo incomplete ##
3957
3958##
3959
3960# ------------------------------------------------------------------------------
3961
3962#Method void drawImageRect(const SkImage* image, const SkRect& src, const SkRect& dst,
3963 const SkPaint* paint,
3964 SrcRectConstraint constraint = kStrict_SrcRectConstraint)
3965
3966Draw Rect src of Image image, scaled and translated to fill Rect dst.
3967Additionally transform draw using Clip, Matrix, and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04003968
Cary Clarkbad5ad72017-08-03 17:14:08 -04003969If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
3970Blend_Mode, and Draw_Looper. If image is kAlpha_8_SkColorType, apply Shader.
3971If paint contains Mask_Filter, generate mask from image bounds.
3972
3973If generated mask extends beyond image bounds, replicate image edge colors, just
3974as Shader made from SkImage::makeShader with SkShader::kClamp_TileMode set
Cary Clarkbc5697d2017-10-04 14:31:33 -04003975replicates the image edge color when it samples outside of its bounds.
Cary Clarkbad5ad72017-08-03 17:14:08 -04003976
3977constraint set to kStrict_SrcRectConstraint limits Paint Filter_Quality to
3978sample within src; set to kFast_SrcRectConstraint allows sampling outside to
3979improve performance.
3980
3981#Param image Image containing pixels, dimensions, and format ##
3982#Param src source Rect of image to draw from ##
3983#Param dst destination Rect of image to draw to ##
3984#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
3985 and so on; or nullptr
3986##
3987#Param constraint filter strictly within src or draw faster ##
Cary Clark8032b982017-07-28 11:04:54 -04003988
3989#Example
3990#Height 64
3991#Description
3992 The left bitmap draws with Paint default kNone_SkFilterQuality, and stays within
Cary Clarkbc5697d2017-10-04 14:31:33 -04003993 its bounds; there is no bleeding with kFast_SrcRectConstraint.
Cary Clark8032b982017-07-28 11:04:54 -04003994 the middle and right bitmaps draw with kLow_SkFilterQuality; with
3995 kStrict_SrcRectConstraint, the filter remains within the checkerboard, and
3996 with kFast_SrcRectConstraint red bleeds on the edges.
3997##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003998void draw(SkCanvas* canvas) {
3999 uint32_t pixels[][4] = {
4000 { 0xFFFF0000, 0xFFFF0000, 0xFFFF0000, 0xFFFF0000 },
4001 { 0xFFFF0000, 0xFF000000, 0xFFFFFFFF, 0xFFFF0000 },
4002 { 0xFFFF0000, 0xFFFFFFFF, 0xFF000000, 0xFFFF0000 },
4003 { 0xFFFF0000, 0xFFFF0000, 0xFFFF0000, 0xFFFF0000 } };
4004 SkBitmap redBorder;
4005 redBorder.installPixels(SkImageInfo::MakeN32Premul(4, 4),
4006 (void*) pixels, sizeof(pixels[0]));
4007 sk_sp<SkImage> image = SkImage::MakeFromBitmap(redBorder);
4008 SkPaint lowPaint;
4009 for (auto constraint : {
4010 SkCanvas::kFast_SrcRectConstraint,
4011 SkCanvas::kStrict_SrcRectConstraint,
4012 SkCanvas::kFast_SrcRectConstraint } ) {
4013 canvas->drawImageRect(image.get(), SkRect::MakeLTRB(1, 1, 3, 3),
4014 SkRect::MakeLTRB(16, 16, 48, 48), &lowPaint, constraint);
4015 lowPaint.setFilterQuality(kLow_SkFilterQuality);
4016 canvas->translate(80, 0);
4017 }
4018}
Cary Clark8032b982017-07-28 11:04:54 -04004019##
4020
4021#ToDo incomplete ##
4022
4023##
4024
4025# ------------------------------------------------------------------------------
4026
4027#Method void drawImageRect(const SkImage* image, const SkIRect& isrc, const SkRect& dst,
4028 const SkPaint* paint, SrcRectConstraint constraint = kStrict_SrcRectConstraint)
4029
4030Draw IRect isrc of Image image, scaled and translated to fill Rect dst.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004031Note that isrc is on integer pixel boundaries; dst may include fractional
4032boundaries. Additionally transform draw using Clip, Matrix, and optional Paint
4033paint.
Cary Clark8032b982017-07-28 11:04:54 -04004034
Cary Clarkbad5ad72017-08-03 17:14:08 -04004035If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4036Blend_Mode, and Draw_Looper. If image is kAlpha_8_SkColorType, apply Shader.
4037If paint contains Mask_Filter, generate mask from image bounds.
4038
4039If generated mask extends beyond image bounds, replicate image edge colors, just
4040as Shader made from SkImage::makeShader with SkShader::kClamp_TileMode set
Cary Clarkbc5697d2017-10-04 14:31:33 -04004041replicates the image edge color when it samples outside of its bounds.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004042
4043constraint set to kStrict_SrcRectConstraint limits Paint Filter_Quality to
Cary Clarkce101242017-09-01 15:51:02 -04004044sample within isrc; set to kFast_SrcRectConstraint allows sampling outside to
Cary Clarkbad5ad72017-08-03 17:14:08 -04004045improve performance.
4046
4047#Param image Image containing pixels, dimensions, and format ##
4048#Param isrc source IRect of image to draw from ##
4049#Param dst destination Rect of image to draw to ##
4050#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4051 and so on; or nullptr
4052##
Cary Clarkce101242017-09-01 15:51:02 -04004053#Param constraint filter strictly within isrc or draw faster ##
Cary Clark8032b982017-07-28 11:04:54 -04004054
4055#Example
4056#Image 4
Cary Clarkbad5ad72017-08-03 17:14:08 -04004057void draw(SkCanvas* canvas) {
4058 // sk_sp<SkImage> image;
4059 for (auto i : { 1, 2, 4, 8 } ) {
4060 canvas->drawImageRect(image.get(), SkIRect::MakeLTRB(0, 0, 100, 100),
4061 SkRect::MakeXYWH(i * 20, i * 20, i * 20, i * 20), nullptr);
4062 }
Cary Clark8032b982017-07-28 11:04:54 -04004063}
4064##
4065
4066#ToDo incomplete ##
4067
4068##
4069
4070# ------------------------------------------------------------------------------
4071
4072#Method void drawImageRect(const SkImage* image, const SkRect& dst, const SkPaint* paint,
4073 SrcRectConstraint constraint = kStrict_SrcRectConstraint)
4074
Cary Clarkbad5ad72017-08-03 17:14:08 -04004075Draw Image image, scaled and translated to fill Rect dst, using Clip, Matrix,
4076and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004077
Cary Clarkbad5ad72017-08-03 17:14:08 -04004078If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4079Blend_Mode, and Draw_Looper. If image is kAlpha_8_SkColorType, apply Shader.
4080If paint contains Mask_Filter, generate mask from image bounds.
4081
4082If generated mask extends beyond image bounds, replicate image edge colors, just
4083as Shader made from SkImage::makeShader with SkShader::kClamp_TileMode set
Cary Clarkbc5697d2017-10-04 14:31:33 -04004084replicates the image edge color when it samples outside of its bounds.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004085
4086constraint set to kStrict_SrcRectConstraint limits Paint Filter_Quality to
Cary Clarkce101242017-09-01 15:51:02 -04004087sample within image; set to kFast_SrcRectConstraint allows sampling outside to
Cary Clarkbad5ad72017-08-03 17:14:08 -04004088improve performance.
4089
4090#Param image Image containing pixels, dimensions, and format ##
4091#Param dst destination Rect of image to draw to ##
4092#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4093 and so on; or nullptr
4094##
Cary Clarkce101242017-09-01 15:51:02 -04004095#Param constraint filter strictly within image or draw faster ##
Cary Clark8032b982017-07-28 11:04:54 -04004096
4097#Example
4098#Image 4
Cary Clarkbad5ad72017-08-03 17:14:08 -04004099void draw(SkCanvas* canvas) {
4100 // sk_sp<SkImage> image;
4101 for (auto i : { 20, 40, 80, 160 } ) {
4102 canvas->drawImageRect(image.get(), SkRect::MakeXYWH(i, i, i, i), nullptr);
4103 }
Cary Clark8032b982017-07-28 11:04:54 -04004104}
4105##
4106
4107#ToDo incomplete ##
4108
4109##
4110
4111# ------------------------------------------------------------------------------
4112
4113#Method void drawImageRect(const sk_sp<SkImage>& image, const SkRect& src, const SkRect& dst,
4114 const SkPaint* paint,
4115 SrcRectConstraint constraint = kStrict_SrcRectConstraint)
4116
4117Draw Rect src of Image image, scaled and translated to fill Rect dst.
4118Additionally transform draw using Clip, Matrix, and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004119
Cary Clarkbad5ad72017-08-03 17:14:08 -04004120If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4121Blend_Mode, and Draw_Looper. If image is kAlpha_8_SkColorType, apply Shader.
4122If paint contains Mask_Filter, generate mask from image bounds.
4123
4124If generated mask extends beyond image bounds, replicate image edge colors, just
4125as Shader made from SkImage::makeShader with SkShader::kClamp_TileMode set
Cary Clarkbc5697d2017-10-04 14:31:33 -04004126replicates the image edge color when it samples outside of its bounds.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004127
4128constraint set to kStrict_SrcRectConstraint limits Paint Filter_Quality to
4129sample within src; set to kFast_SrcRectConstraint allows sampling outside to
4130improve performance.
4131
4132#Param image Image containing pixels, dimensions, and format ##
4133#Param src source Rect of image to draw from ##
4134#Param dst destination Rect of image to draw to ##
4135#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4136 and so on; or nullptr
4137##
4138#Param constraint filter strictly within src or draw faster ##
Cary Clark8032b982017-07-28 11:04:54 -04004139
4140#Example
4141#Height 64
4142#Description
4143 Canvas scales and translates; transformation from src to dst also scales.
4144 The two matrices are concatenated to create the final transformation.
4145##
Cary Clarkbad5ad72017-08-03 17:14:08 -04004146void draw(SkCanvas* canvas) {
4147 uint32_t pixels[][2] = { { SK_ColorBLACK, SK_ColorWHITE },
4148 { SK_ColorWHITE, SK_ColorBLACK } };
4149 SkBitmap bitmap;
4150 bitmap.installPixels(SkImageInfo::MakeN32Premul(2, 2),
4151 (void*) pixels, sizeof(pixels[0]));
4152 sk_sp<SkImage> image = SkImage::MakeFromBitmap(bitmap);
4153 SkPaint paint;
4154 canvas->scale(4, 4);
4155 for (auto alpha : { 50, 100, 150, 255 } ) {
4156 paint.setAlpha(alpha);
4157 canvas->drawImageRect(image, SkRect::MakeWH(2, 2), SkRect::MakeWH(8, 8), &paint);
4158 canvas->translate(8, 0);
4159 }
4160}
Cary Clark8032b982017-07-28 11:04:54 -04004161##
4162
4163#ToDo incomplete ##
4164
4165##
4166
4167# ------------------------------------------------------------------------------
4168
4169#Method void drawImageRect(const sk_sp<SkImage>& image, const SkIRect& isrc, const SkRect& dst,
4170 const SkPaint* paint, SrcRectConstraint constraint = kStrict_SrcRectConstraint)
4171
4172Draw IRect isrc of Image image, scaled and translated to fill Rect dst.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004173isrc is on integer pixel boundaries; dst may include fractional boundaries.
Cary Clark8032b982017-07-28 11:04:54 -04004174Additionally transform draw using Clip, Matrix, and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004175
Cary Clarkbad5ad72017-08-03 17:14:08 -04004176If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4177Blend_Mode, and Draw_Looper. If image is kAlpha_8_SkColorType, apply Shader.
4178If paint contains Mask_Filter, generate mask from image bounds.
4179
4180If generated mask extends beyond image bounds, replicate image edge colors, just
4181as Shader made from SkImage::makeShader with SkShader::kClamp_TileMode set
Cary Clarkbc5697d2017-10-04 14:31:33 -04004182replicates the image edge color when it samples outside of its bounds.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004183
4184constraint set to kStrict_SrcRectConstraint limits Paint Filter_Quality to
Cary Clarkce101242017-09-01 15:51:02 -04004185sample within image; set to kFast_SrcRectConstraint allows sampling outside to
Cary Clarkbad5ad72017-08-03 17:14:08 -04004186improve performance.
4187
4188#Param image Image containing pixels, dimensions, and format ##
4189#Param isrc source IRect of image to draw from ##
4190#Param dst destination Rect of image to draw to ##
4191#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4192 and so on; or nullptr
4193##
Cary Clarkce101242017-09-01 15:51:02 -04004194#Param constraint filter strictly within image or draw faster ##
Cary Clark8032b982017-07-28 11:04:54 -04004195
4196#Example
4197#Height 64
Cary Clarkbad5ad72017-08-03 17:14:08 -04004198void draw(SkCanvas* canvas) {
4199 uint32_t pixels[][2] = { { 0x00000000, 0x55555555},
4200 { 0xAAAAAAAA, 0xFFFFFFFF} };
4201 SkBitmap bitmap;
4202 bitmap.installPixels(SkImageInfo::MakeN32Premul(2, 2),
4203 (void*) pixels, sizeof(pixels[0]));
4204 sk_sp<SkImage> image = SkImage::MakeFromBitmap(bitmap);
4205 SkPaint paint;
4206 canvas->scale(4, 4);
4207 for (auto color : { SK_ColorRED, SK_ColorBLUE, SK_ColorGREEN } ) {
4208 paint.setColorFilter(SkColorFilter::MakeModeFilter(color, SkBlendMode::kPlus));
4209 canvas->drawImageRect(image, SkIRect::MakeWH(2, 2), SkRect::MakeWH(8, 8), &paint);
4210 canvas->translate(8, 0);
4211 }
Cary Clark8032b982017-07-28 11:04:54 -04004212}
4213##
4214
4215#ToDo incomplete ##
4216##
4217
4218# ------------------------------------------------------------------------------
4219
4220#Method void drawImageRect(const sk_sp<SkImage>& image, const SkRect& dst, const SkPaint* paint,
4221 SrcRectConstraint constraint = kStrict_SrcRectConstraint)
4222
4223Draw Image image, scaled and translated to fill Rect dst,
4224using Clip, Matrix, and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004225
Cary Clarkbad5ad72017-08-03 17:14:08 -04004226If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4227Blend_Mode, and Draw_Looper. If image is kAlpha_8_SkColorType, apply Shader.
4228If paint contains Mask_Filter, generate mask from image bounds.
4229
4230If generated mask extends beyond image bounds, replicate image edge colors, just
4231as Shader made from SkImage::makeShader with SkShader::kClamp_TileMode set
Cary Clarkbc5697d2017-10-04 14:31:33 -04004232replicates the image edge color when it samples outside of its bounds.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004233
4234constraint set to kStrict_SrcRectConstraint limits Paint Filter_Quality to
Cary Clarkce101242017-09-01 15:51:02 -04004235sample within image; set to kFast_SrcRectConstraint allows sampling outside to
Cary Clarkbad5ad72017-08-03 17:14:08 -04004236improve performance.
4237
4238#Param image Image containing pixels, dimensions, and format ##
4239#Param dst destination Rect of image to draw to ##
4240#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4241 and so on; or nullptr
4242##
Cary Clarkce101242017-09-01 15:51:02 -04004243#Param constraint filter strictly within image or draw faster ##
Cary Clark8032b982017-07-28 11:04:54 -04004244
4245#Example
4246#Height 64
Cary Clarkbad5ad72017-08-03 17:14:08 -04004247void draw(SkCanvas* canvas) {
4248 uint32_t pixels[][2] = { { 0x00000000, 0x55550000},
4249 { 0xAAAA0000, 0xFFFF0000} };
4250 SkBitmap bitmap;
4251 bitmap.installPixels(SkImageInfo::MakeN32Premul(2, 2),
4252 (void*) pixels, sizeof(pixels[0]));
4253 sk_sp<SkImage> image = SkImage::MakeFromBitmap(bitmap);
4254 SkPaint paint;
4255 canvas->scale(4, 4);
4256 for (auto color : { SK_ColorRED, SK_ColorBLUE, SK_ColorGREEN } ) {
4257 paint.setColorFilter(SkColorFilter::MakeModeFilter(color, SkBlendMode::kPlus));
4258 canvas->drawImageRect(image, SkRect::MakeWH(8, 8), &paint);
4259 canvas->translate(8, 0);
4260 }
Cary Clark8032b982017-07-28 11:04:54 -04004261}
4262##
4263
4264#ToDo incomplete ##
4265
4266##
4267
4268# ------------------------------------------------------------------------------
4269
4270#Method void drawImageNine(const SkImage* image, const SkIRect& center, const SkRect& dst,
4271 const SkPaint* paint = nullptr)
4272
Cary Clarkd0530ba2017-09-14 11:25:39 -04004273Draw Image image stretched proportionally to fit into Rect dst.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004274IRect center divides the image into nine sections: four sides, four corners, and
Cary Clarkce101242017-09-01 15:51:02 -04004275the center. Corners are unmodified or scaled down proportionately if their sides
Cary Clarkbad5ad72017-08-03 17:14:08 -04004276are larger than dst; center and four sides are scaled to fit remaining space, if any.
Cary Clark8032b982017-07-28 11:04:54 -04004277
Cary Clarkbad5ad72017-08-03 17:14:08 -04004278Additionally transform draw using Clip, Matrix, and optional Paint paint.
4279
4280If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4281Blend_Mode, and Draw_Looper. If image is kAlpha_8_SkColorType, apply Shader.
4282If paint contains Mask_Filter, generate mask from image bounds.
4283
4284If generated mask extends beyond image bounds, replicate image edge colors, just
4285as Shader made from SkImage::makeShader with SkShader::kClamp_TileMode set
Cary Clarkbc5697d2017-10-04 14:31:33 -04004286replicates the image edge color when it samples outside of its bounds.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004287
4288#Param image Image containing pixels, dimensions, and format ##
4289#Param center IRect edge of image corners and sides ##
4290#Param dst destination Rect of image to draw to ##
4291#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4292 and so on; or nullptr
4293##
Cary Clark8032b982017-07-28 11:04:54 -04004294
4295#Example
4296#Height 128
4297#Description
4298 The leftmost image is smaller than center; only corners are drawn, all scaled to fit.
Cary Clarkce101242017-09-01 15:51:02 -04004299 The second image equals the size of center; only corners are drawn without scaling.
4300 The remaining images are larger than center. All corners draw without scaling.
4301 The sides and center are scaled if needed to take up the remaining space.
Cary Clark8032b982017-07-28 11:04:54 -04004302##
Cary Clarkbad5ad72017-08-03 17:14:08 -04004303void draw(SkCanvas* canvas) {
4304 SkIRect center = { 20, 10, 50, 40 };
4305 SkBitmap bitmap;
4306 bitmap.allocPixels(SkImageInfo::MakeN32Premul(60, 60));
4307 SkCanvas bitCanvas(bitmap);
4308 SkPaint paint;
4309 SkColor gray = 0xFF000000;
4310 int left = 0;
4311 for (auto right: { center.fLeft, center.fRight, bitmap.width() } ) {
4312 int top = 0;
4313 for (auto bottom: { center.fTop, center.fBottom, bitmap.height() } ) {
4314 paint.setColor(gray);
4315 bitCanvas.drawIRect(SkIRect::MakeLTRB(left, top, right, bottom), paint);
4316 gray += 0x001f1f1f;
4317 top = bottom;
4318 }
4319 left = right;
4320 }
4321 sk_sp<SkImage> image = SkImage::MakeFromBitmap(bitmap);
4322 SkImage* imagePtr = image.get();
4323 for (auto dest: { 20, 30, 40, 60, 90 } ) {
4324 canvas->drawImageNine(imagePtr, center, SkRect::MakeWH(dest, dest), nullptr);
4325 canvas->translate(dest + 4, 0);
4326 }
Cary Clark8032b982017-07-28 11:04:54 -04004327}
4328##
4329
4330#ToDo incomplete ##
4331
4332##
4333
4334# ------------------------------------------------------------------------------
4335
4336#Method void drawImageNine(const sk_sp<SkImage>& image, const SkIRect& center, const SkRect& dst,
4337 const SkPaint* paint = nullptr)
4338
Cary Clarkd0530ba2017-09-14 11:25:39 -04004339Draw Image image stretched proportionally to fit into Rect dst.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004340IRect center divides the image into nine sections: four sides, four corners, and
Cary Clarkce101242017-09-01 15:51:02 -04004341the center. Corners are not scaled, or scaled down proportionately if their sides
Cary Clarkbad5ad72017-08-03 17:14:08 -04004342are larger than dst; center and four sides are scaled to fit remaining space, if any.
Cary Clark8032b982017-07-28 11:04:54 -04004343
Cary Clarkbad5ad72017-08-03 17:14:08 -04004344Additionally transform draw using Clip, Matrix, and optional Paint paint.
4345
4346If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4347Blend_Mode, and Draw_Looper. If image is kAlpha_8_SkColorType, apply Shader.
4348If paint contains Mask_Filter, generate mask from image bounds.
4349
4350If generated mask extends beyond image bounds, replicate image edge colors, just
4351as Shader made from SkImage::makeShader with SkShader::kClamp_TileMode set
Cary Clarkbc5697d2017-10-04 14:31:33 -04004352replicates the image edge color when it samples outside of its bounds.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004353
4354#Param image Image containing pixels, dimensions, and format ##
4355#Param center IRect edge of image corners and sides ##
4356#Param dst destination Rect of image to draw to ##
4357#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4358 and so on; or nullptr
4359##
Cary Clark8032b982017-07-28 11:04:54 -04004360
4361#Example
4362#Height 128
4363#Description
4364 The two leftmost images has four corners and sides to the left and right of center.
4365 The leftmost image scales the width of corners proportionately to fit.
Cary Clarkce101242017-09-01 15:51:02 -04004366 The third and fourth image corners are not scaled; the sides and center are scaled to
Cary Clark8032b982017-07-28 11:04:54 -04004367 fill the remaining space.
4368 The rightmost image has four corners scaled vertically to fit, and uses sides above
4369 and below center to fill the remaining space.
4370##
Cary Clarkbad5ad72017-08-03 17:14:08 -04004371void draw(SkCanvas* canvas) {
4372 SkIRect center = { 20, 10, 50, 40 };
4373 SkBitmap bitmap;
4374 bitmap.allocPixels(SkImageInfo::MakeN32Premul(60, 60));
4375 SkCanvas bitCanvas(bitmap);
4376 SkPaint paint;
4377 SkColor gray = 0xFF000000;
4378 int left = 0;
4379 for (auto right: { center.fLeft, center.fRight, bitmap.width() } ) {
4380 int top = 0;
4381 for (auto bottom: { center.fTop, center.fBottom, bitmap.height() } ) {
4382 paint.setColor(gray);
4383 bitCanvas.drawIRect(SkIRect::MakeLTRB(left, top, right, bottom), paint);
4384 gray += 0x001f1f1f;
4385 top = bottom;
4386 }
4387 left = right;
4388 }
4389 sk_sp<SkImage> image = SkImage::MakeFromBitmap(bitmap);
4390 for (auto dest: { 20, 30, 40, 60, 90 } ) {
4391 canvas->drawImageNine(image, center, SkRect::MakeWH(dest, 110 - dest), nullptr);
4392 canvas->translate(dest + 4, 0);
4393 }
Cary Clark8032b982017-07-28 11:04:54 -04004394}
4395##
4396
4397#ToDo incomplete ##
4398
4399##
4400
4401# ------------------------------------------------------------------------------
4402
4403#Method void drawBitmap(const SkBitmap& bitmap, SkScalar left, SkScalar top,
Cary Clark73fa9722017-08-29 17:36:51 -04004404 const SkPaint* paint = nullptr)
Cary Clark8032b982017-07-28 11:04:54 -04004405
4406Draw Bitmap bitmap, with its top-left corner at (left, top),
4407using Clip, Matrix, and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004408
Cary Clarkbad5ad72017-08-03 17:14:08 -04004409If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4410Blend_Mode, and Draw_Looper. If bitmap is kAlpha_8_SkColorType, apply Shader.
4411If paint contains Mask_Filter, generate mask from bitmap bounds.
4412
4413If generated mask extends beyond bitmap bounds, replicate bitmap edge colors,
4414just as Shader made from SkShader::MakeBitmapShader with
Cary Clarkbc5697d2017-10-04 14:31:33 -04004415SkShader::kClamp_TileMode set replicates the bitmap edge color when it samples
Cary Clarkbad5ad72017-08-03 17:14:08 -04004416outside of its bounds.
4417
4418#Param bitmap Bitmap containing pixels, dimensions, and format ##
4419#Param left left side of bitmap ##
4420#Param top top side of bitmap ##
4421#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4422 and so on; or nullptr
4423##
Cary Clark8032b982017-07-28 11:04:54 -04004424
4425#Example
4426#Height 64
Cary Clarkbad5ad72017-08-03 17:14:08 -04004427void draw(SkCanvas* canvas) {
4428 uint8_t pixels[][8] = { { 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00},
4429 { 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00},
4430 { 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00},
4431 { 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF},
4432 { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
4433 { 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00},
4434 { 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0x00},
4435 { 0xFF, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0xFF} };
4436 SkBitmap bitmap;
4437 bitmap.installPixels(SkImageInfo::MakeA8(8, 8),
4438 (void*) pixels, sizeof(pixels[0]));
4439 SkPaint paint;
4440 canvas->scale(4, 4);
4441 for (auto color : { SK_ColorRED, SK_ColorBLUE, 0xFF007F00} ) {
4442 paint.setColor(color);
4443 canvas->drawBitmap(bitmap, 0, 0, &paint);
4444 canvas->translate(12, 0);
4445 }
Cary Clark8032b982017-07-28 11:04:54 -04004446}
4447##
4448
4449#ToDo incomplete ##
4450
4451##
4452
4453# ------------------------------------------------------------------------------
4454
4455#Method void drawBitmapRect(const SkBitmap& bitmap, const SkRect& src, const SkRect& dst,
4456 const SkPaint* paint, SrcRectConstraint constraint = kStrict_SrcRectConstraint)
4457
4458Draw Rect src of Bitmap bitmap, scaled and translated to fill Rect dst.
4459Additionally transform draw using Clip, Matrix, and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004460
Cary Clarkbad5ad72017-08-03 17:14:08 -04004461If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4462Blend_Mode, and Draw_Looper. If bitmap is kAlpha_8_SkColorType, apply Shader.
4463If paint contains Mask_Filter, generate mask from bitmap bounds.
4464
4465If generated mask extends beyond bitmap bounds, replicate bitmap edge colors,
4466just as Shader made from SkShader::MakeBitmapShader with
Cary Clarkbc5697d2017-10-04 14:31:33 -04004467SkShader::kClamp_TileMode set replicates the bitmap edge color when it samples
Cary Clarkbad5ad72017-08-03 17:14:08 -04004468outside of its bounds.
4469
4470constraint set to kStrict_SrcRectConstraint limits Paint Filter_Quality to
4471sample within src; set to kFast_SrcRectConstraint allows sampling outside to
4472improve performance.
4473
4474#Param bitmap Bitmap containing pixels, dimensions, and format ##
4475#Param src source Rect of image to draw from ##
4476#Param dst destination Rect of image to draw to ##
4477#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4478 and so on; or nullptr
4479##
4480#Param constraint filter strictly within src or draw faster ##
Cary Clark8032b982017-07-28 11:04:54 -04004481
4482#Example
4483#Height 64
Cary Clarkbad5ad72017-08-03 17:14:08 -04004484void draw(SkCanvas* canvas) {
4485 uint8_t pixels[][8] = { { 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00},
4486 { 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00},
4487 { 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00},
4488 { 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF},
4489 { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
4490 { 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00},
4491 { 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00},
4492 { 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00} };
4493 SkBitmap bitmap;
4494 bitmap.installPixels(SkImageInfo::MakeA8(8, 8),
4495 (void*) pixels, sizeof(pixels[0]));
4496 SkPaint paint;
4497 paint.setMaskFilter(SkBlurMaskFilter::Make(kSolid_SkBlurStyle, 6));
4498 for (auto color : { SK_ColorRED, SK_ColorBLUE, 0xFF007F00} ) {
4499 paint.setColor(color);
4500 canvas->drawBitmapRect(bitmap, SkRect::MakeWH(8, 8), SkRect::MakeWH(32, 32), &paint);
4501 canvas->translate(48, 0);
4502 }
Cary Clark8032b982017-07-28 11:04:54 -04004503}
4504##
4505
4506#ToDo incomplete ##
4507
4508##
4509
4510# ------------------------------------------------------------------------------
4511
4512#Method void drawBitmapRect(const SkBitmap& bitmap, const SkIRect& isrc, const SkRect& dst,
4513 const SkPaint* paint, SrcRectConstraint constraint = kStrict_SrcRectConstraint)
4514
4515Draw IRect isrc of Bitmap bitmap, scaled and translated to fill Rect dst.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004516isrc is on integer pixel boundaries; dst may include fractional boundaries.
Cary Clark8032b982017-07-28 11:04:54 -04004517Additionally transform draw using Clip, Matrix, and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004518
Cary Clarkbad5ad72017-08-03 17:14:08 -04004519If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4520Blend_Mode, and Draw_Looper. If bitmap is kAlpha_8_SkColorType, apply Shader.
4521If paint contains Mask_Filter, generate mask from bitmap bounds.
4522
4523If generated mask extends beyond bitmap bounds, replicate bitmap edge colors,
4524just as Shader made from SkShader::MakeBitmapShader with
Cary Clarkbc5697d2017-10-04 14:31:33 -04004525SkShader::kClamp_TileMode set replicates the bitmap edge color when it samples
Cary Clarkbad5ad72017-08-03 17:14:08 -04004526outside of its bounds.
4527
4528constraint set to kStrict_SrcRectConstraint limits Paint Filter_Quality to
Cary Clarkce101242017-09-01 15:51:02 -04004529sample within isrc; set to kFast_SrcRectConstraint allows sampling outside to
Cary Clarkbad5ad72017-08-03 17:14:08 -04004530improve performance.
4531
4532#Param bitmap Bitmap containing pixels, dimensions, and format ##
4533#Param isrc source IRect of image to draw from ##
4534#Param dst destination Rect of image to draw to ##
4535#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4536 and so on; or nullptr
4537##
Cary Clarkce101242017-09-01 15:51:02 -04004538#Param constraint sample strictly within isrc, or draw faster ##
Cary Clark8032b982017-07-28 11:04:54 -04004539
4540#Example
4541#Height 64
Cary Clarkbad5ad72017-08-03 17:14:08 -04004542void draw(SkCanvas* canvas) {
4543 uint8_t pixels[][8] = { { 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00},
4544 { 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00},
4545 { 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0xFF},
4546 { 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0xFF},
4547 { 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF},
4548 { 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF},
4549 { 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00},
4550 { 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00} };
4551 SkBitmap bitmap;
4552 bitmap.installPixels(SkImageInfo::MakeA8(8, 8),
4553 (void*) pixels, sizeof(pixels[0]));
4554 SkPaint paint;
4555 paint.setFilterQuality(kHigh_SkFilterQuality);
4556 for (auto color : { SK_ColorRED, SK_ColorBLUE, 0xFF007F00, 0xFF7f007f} ) {
4557 paint.setColor(color);
4558 canvas->drawBitmapRect(bitmap, SkIRect::MakeWH(8, 8), SkRect::MakeWH(32, 32), &paint);
4559 canvas->translate(48.25f, 0);
4560 }
Cary Clark8032b982017-07-28 11:04:54 -04004561}
4562##
4563
4564#ToDo incomplete ##
4565
4566##
4567
4568# ------------------------------------------------------------------------------
4569
4570#Method void drawBitmapRect(const SkBitmap& bitmap, const SkRect& dst, const SkPaint* paint,
4571 SrcRectConstraint constraint = kStrict_SrcRectConstraint)
4572
4573Draw Bitmap bitmap, scaled and translated to fill Rect dst.
Cary Clarkce101242017-09-01 15:51:02 -04004574bitmap bounds is on integer pixel boundaries; dst may include fractional boundaries.
Cary Clark8032b982017-07-28 11:04:54 -04004575Additionally transform draw using Clip, Matrix, and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004576
Cary Clarkbad5ad72017-08-03 17:14:08 -04004577If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4578Blend_Mode, and Draw_Looper. If bitmap is kAlpha_8_SkColorType, apply Shader.
4579If paint contains Mask_Filter, generate mask from bitmap bounds.
4580
4581If generated mask extends beyond bitmap bounds, replicate bitmap edge colors,
4582just as Shader made from SkShader::MakeBitmapShader with
Cary Clarkbc5697d2017-10-04 14:31:33 -04004583SkShader::kClamp_TileMode set replicates the bitmap edge color when it samples
Cary Clarkbad5ad72017-08-03 17:14:08 -04004584outside of its bounds.
4585
4586constraint set to kStrict_SrcRectConstraint limits Paint Filter_Quality to
Cary Clarkce101242017-09-01 15:51:02 -04004587sample within bitmap; set to kFast_SrcRectConstraint allows sampling outside to
Cary Clarkbad5ad72017-08-03 17:14:08 -04004588improve performance.
4589
4590#Param bitmap Bitmap containing pixels, dimensions, and format ##
4591#Param dst destination Rect of image to draw to ##
4592#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4593 and so on; or nullptr
4594##
Cary Clarkce101242017-09-01 15:51:02 -04004595#Param constraint filter strictly within bitmap or draw faster ##
Cary Clark8032b982017-07-28 11:04:54 -04004596
4597#Example
4598#Height 64
Cary Clarkbad5ad72017-08-03 17:14:08 -04004599void draw(SkCanvas* canvas) {
4600 uint32_t pixels[][2] = { { 0x00000000, 0x55550000},
4601 { 0xAAAA0000, 0xFFFF0000} };
4602 SkBitmap bitmap;
4603 bitmap.installPixels(SkImageInfo::MakeN32Premul(2, 2),
4604 (void*) pixels, sizeof(pixels[0]));
4605 SkPaint paint;
4606 canvas->scale(4, 4);
4607 for (auto color : { SK_ColorRED, SK_ColorBLUE, SK_ColorGREEN } ) {
4608 paint.setColorFilter(SkColorFilter::MakeModeFilter(color, SkBlendMode::kPlus));
4609 canvas->drawBitmapRect(bitmap, SkRect::MakeWH(8, 8), &paint);
4610 canvas->translate(8, 0);
4611 }
Cary Clark8032b982017-07-28 11:04:54 -04004612}
4613##
4614
4615#ToDo incomplete ##
4616
4617##
4618
4619# ------------------------------------------------------------------------------
4620
4621#Method void drawBitmapNine(const SkBitmap& bitmap, const SkIRect& center, const SkRect& dst,
Cary Clark73fa9722017-08-29 17:36:51 -04004622 const SkPaint* paint = nullptr)
Cary Clark8032b982017-07-28 11:04:54 -04004623
Cary Clarkd0530ba2017-09-14 11:25:39 -04004624Draw Bitmap bitmap stretched proportionally to fit into Rect dst.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004625IRect center divides the bitmap into nine sections: four sides, four corners,
Cary Clarkce101242017-09-01 15:51:02 -04004626and the center. Corners are not scaled, or scaled down proportionately if their
Cary Clarkbad5ad72017-08-03 17:14:08 -04004627sides are larger than dst; center and four sides are scaled to fit remaining
4628space, if any.
Cary Clark8032b982017-07-28 11:04:54 -04004629
Cary Clarkbad5ad72017-08-03 17:14:08 -04004630Additionally transform draw using Clip, Matrix, and optional Paint paint.
4631
4632If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4633Blend_Mode, and Draw_Looper. If bitmap is kAlpha_8_SkColorType, apply Shader.
4634If paint contains Mask_Filter, generate mask from bitmap bounds.
4635
4636If generated mask extends beyond bitmap bounds, replicate bitmap edge colors,
4637just as Shader made from SkShader::MakeBitmapShader with
Cary Clarkbc5697d2017-10-04 14:31:33 -04004638SkShader::kClamp_TileMode set replicates the bitmap edge color when it samples
Cary Clarkbad5ad72017-08-03 17:14:08 -04004639outside of its bounds.
4640
4641#Param bitmap Bitmap containing pixels, dimensions, and format ##
4642#Param center IRect edge of image corners and sides ##
4643#Param dst destination Rect of image to draw to ##
4644#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4645 and so on; or nullptr
4646##
Cary Clark8032b982017-07-28 11:04:54 -04004647
4648#Example
4649#Height 128
4650#Description
4651 The two leftmost bitmap draws has four corners and sides to the left and right of center.
4652 The leftmost bitmap draw scales the width of corners proportionately to fit.
Cary Clarkce101242017-09-01 15:51:02 -04004653 The third and fourth draw corners are not scaled; the sides and center are scaled to
Cary Clark8032b982017-07-28 11:04:54 -04004654 fill the remaining space.
4655 The rightmost bitmap draw has four corners scaled vertically to fit, and uses sides above
4656 and below center to fill the remaining space.
4657##
Cary Clarkbad5ad72017-08-03 17:14:08 -04004658void draw(SkCanvas* canvas) {
4659 SkIRect center = { 20, 10, 50, 40 };
4660 SkBitmap bitmap;
4661 bitmap.allocPixels(SkImageInfo::MakeN32Premul(60, 60));
4662 SkCanvas bitCanvas(bitmap);
4663 SkPaint paint;
4664 SkColor gray = 0xFF000000;
4665 int left = 0;
4666 for (auto right: { center.fLeft, center.fRight, bitmap.width() } ) {
4667 int top = 0;
4668 for (auto bottom: { center.fTop, center.fBottom, bitmap.height() } ) {
4669 paint.setColor(gray);
4670 bitCanvas.drawIRect(SkIRect::MakeLTRB(left, top, right, bottom), paint);
4671 gray += 0x001f1f1f;
4672 top = bottom;
4673 }
4674 left = right;
4675 }
4676 for (auto dest: { 20, 30, 40, 60, 90 } ) {
4677 canvas->drawBitmapNine(bitmap, center, SkRect::MakeWH(dest, 110 - dest), nullptr);
4678 canvas->translate(dest + 4, 0);
4679 }
Cary Clark8032b982017-07-28 11:04:54 -04004680}
4681##
4682
4683#ToDo incomplete ##
4684
4685##
4686
4687# ------------------------------------------------------------------------------
4688#Struct Lattice
4689
4690 Lattice divides Bitmap or Image into a rectangular grid.
4691 Grid entries on even columns and even rows are fixed; these entries are
4692 always drawn at their original size if the destination is large enough.
4693 If the destination side is too small to hold the fixed entries, all fixed
4694 entries are proportionately scaled down to fit.
4695 The grid entries not on even columns and rows are scaled to fit the
4696 remaining space, if any.
4697
4698#Code
4699 struct Lattice {
4700 enum Flags {...
4701
4702 const int* fXDivs;
4703 const int* fYDivs;
4704 const Flags* fFlags;
4705 int fXCount;
4706 int fYCount;
4707 const SkIRect* fBounds;
4708 };
4709##
4710
4711 #Enum Flags
4712 #Code
4713 enum Flags : uint8_t {
4714 kTransparent_Flags = 1 << 0,
4715 };
4716 ##
4717
4718 Optional setting per rectangular grid entry to make it transparent.
4719
4720 #Const kTransparent_Flags 1
4721 Set to skip lattice rectangle by making it transparent.
4722 ##
4723 ##
4724
4725 #Member const int* fXDivs
4726 Array of x-coordinates that divide the bitmap vertically.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004727 Array entries must be unique, increasing, greater than or equal to
4728 fBounds left edge, and less than fBounds right edge.
4729 Set the first element to fBounds left to collapse the left column of
4730 fixed grid entries.
Cary Clark8032b982017-07-28 11:04:54 -04004731 ##
4732
4733 #Member const int* fYDivs
4734 Array of y-coordinates that divide the bitmap horizontally.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004735 Array entries must be unique, increasing, greater than or equal to
4736 fBounds top edge, and less than fBounds bottom edge.
4737 Set the first element to fBounds top to collapse the top row of fixed
4738 grid entries.
Cary Clark8032b982017-07-28 11:04:54 -04004739 ##
4740
4741 #Member const Flags* fFlags
4742 Optional array of Flags, one per rectangular grid entry:
Cary Clarkbad5ad72017-08-03 17:14:08 -04004743 array length must be
4744 #Formula
4745 (fXCount + 1) * (fYCount + 1)
4746 ##
4747 .
Cary Clark6fc50412017-09-21 12:31:06 -04004748
Cary Clark8032b982017-07-28 11:04:54 -04004749 Array entries correspond to the rectangular grid entries, ascending
4750 left to right and then top to bottom.
4751 ##
4752
4753 #Member int fXCount
Cary Clarkbad5ad72017-08-03 17:14:08 -04004754 Number of entries in fXDivs array; one less than the number of
4755 horizontal divisions.
Cary Clark8032b982017-07-28 11:04:54 -04004756 ##
4757
4758 #Member int fYCount
Cary Clarkbad5ad72017-08-03 17:14:08 -04004759 Number of entries in fYDivs array; one less than the number of vertical
4760 divisions.
Cary Clark8032b982017-07-28 11:04:54 -04004761 ##
4762
4763 #Member const SkIRect* fBounds
4764 Optional subset IRect source to draw from.
4765 If nullptr, source bounds is dimensions of Bitmap or Image.
4766 ##
4767
4768#Struct Lattice ##
4769
4770#Method void drawBitmapLattice(const SkBitmap& bitmap, const Lattice& lattice, const SkRect& dst,
4771 const SkPaint* paint = nullptr)
4772
Cary Clarkd0530ba2017-09-14 11:25:39 -04004773Draw Bitmap bitmap stretched proportionally to fit into Rect dst.
Cary Clark8032b982017-07-28 11:04:54 -04004774
4775Lattice lattice divides bitmap into a rectangular grid.
4776Each intersection of an even-numbered row and column is fixed; like the corners
Cary Clarkbad5ad72017-08-03 17:14:08 -04004777of drawBitmapNine, fixed lattice elements never scale larger than their initial
Cary Clarkbc5697d2017-10-04 14:31:33 -04004778size and shrink proportionately when all fixed elements exceed the bitmap
Cary Clarkbad5ad72017-08-03 17:14:08 -04004779dimension. All other grid elements scale to fill the available space, if any.
Cary Clark8032b982017-07-28 11:04:54 -04004780
4781Additionally transform draw using Clip, Matrix, and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004782
Cary Clarkbad5ad72017-08-03 17:14:08 -04004783If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4784Blend_Mode, and Draw_Looper. If bitmap is kAlpha_8_SkColorType, apply Shader.
4785If paint contains Mask_Filter, generate mask from bitmap bounds.
4786
4787If generated mask extends beyond bitmap bounds, replicate bitmap edge colors,
4788just as Shader made from SkShader::MakeBitmapShader with
Cary Clarkbc5697d2017-10-04 14:31:33 -04004789SkShader::kClamp_TileMode set replicates the bitmap edge color when it samples
Cary Clarkbad5ad72017-08-03 17:14:08 -04004790outside of its bounds.
4791
4792#Param bitmap Bitmap containing pixels, dimensions, and format ##
4793#Param lattice division of bitmap into fixed and variable rectangles ##
4794#Param dst destination Rect of image to draw to ##
4795#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4796 and so on; or nullptr
4797##
Cary Clark8032b982017-07-28 11:04:54 -04004798
4799#Example
4800#Height 128
4801#Description
4802 The two leftmost bitmap draws has four corners and sides to the left and right of center.
4803 The leftmost bitmap draw scales the width of corners proportionately to fit.
Cary Clarkce101242017-09-01 15:51:02 -04004804 The third and fourth draw corners are not scaled; the sides are scaled to
Cary Clark8032b982017-07-28 11:04:54 -04004805 fill the remaining space; the center is transparent.
4806 The rightmost bitmap draw has four corners scaled vertically to fit, and uses sides above
4807 and below center to fill the remaining space.
4808##
Cary Clarkbad5ad72017-08-03 17:14:08 -04004809void draw(SkCanvas* canvas) {
4810 SkIRect center = { 20, 10, 50, 40 };
4811 SkBitmap bitmap;
4812 bitmap.allocPixels(SkImageInfo::MakeN32Premul(60, 60));
4813 SkCanvas bitCanvas(bitmap);
4814 SkPaint paint;
4815 SkColor gray = 0xFF000000;
4816 int left = 0;
4817 for (auto right: { center.fLeft, center.fRight, bitmap.width() } ) {
4818 int top = 0;
4819 for (auto bottom: { center.fTop, center.fBottom, bitmap.height() } ) {
4820 paint.setColor(gray);
4821 bitCanvas.drawIRect(SkIRect::MakeLTRB(left, top, right, bottom), paint);
4822 gray += 0x001f1f1f;
4823 top = bottom;
4824 }
4825 left = right;
4826 }
4827 const int xDivs[] = { center.fLeft, center.fRight };
4828 const int yDivs[] = { center.fTop, center.fBottom };
4829 SkCanvas::Lattice::Flags flags[3][3];
4830 memset(flags, 0, sizeof(flags));
4831 flags[1][1] = SkCanvas::Lattice::kTransparent_Flags;
4832 SkCanvas::Lattice lattice = { xDivs, yDivs, flags[0], SK_ARRAY_COUNT(xDivs),
4833 SK_ARRAY_COUNT(yDivs), nullptr };
4834 for (auto dest: { 20, 30, 40, 60, 90 } ) {
4835 canvas->drawBitmapLattice(bitmap, lattice , SkRect::MakeWH(dest, 110 - dest), nullptr);
4836 canvas->translate(dest + 4, 0);
4837 }
Cary Clark8032b982017-07-28 11:04:54 -04004838}
4839##
4840
4841#ToDo incomplete ##
4842
4843##
4844
4845# ------------------------------------------------------------------------------
4846
4847#Method void drawImageLattice(const SkImage* image, const Lattice& lattice, const SkRect& dst,
4848 const SkPaint* paint = nullptr)
4849
Cary Clarkd0530ba2017-09-14 11:25:39 -04004850Draw Image image stretched proportionally to fit into Rect dst.
Cary Clark8032b982017-07-28 11:04:54 -04004851
4852Lattice lattice divides image into a rectangular grid.
4853Each intersection of an even-numbered row and column is fixed; like the corners
Cary Clarkbad5ad72017-08-03 17:14:08 -04004854of drawBitmapNine, fixed lattice elements never scale larger than their initial
Cary Clarkbc5697d2017-10-04 14:31:33 -04004855size and shrink proportionately when all fixed elements exceed the bitmap
Cary Clarkbad5ad72017-08-03 17:14:08 -04004856dimension. All other grid elements scale to fill the available space, if any.
Cary Clark8032b982017-07-28 11:04:54 -04004857
4858Additionally transform draw using Clip, Matrix, and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004859
Cary Clarkbad5ad72017-08-03 17:14:08 -04004860If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4861Blend_Mode, and Draw_Looper. If bitmap is kAlpha_8_SkColorType, apply Shader.
4862If paint contains Mask_Filter, generate mask from bitmap bounds.
4863
4864If generated mask extends beyond bitmap bounds, replicate bitmap edge colors,
4865just as Shader made from SkShader::MakeBitmapShader with
Cary Clarkbc5697d2017-10-04 14:31:33 -04004866SkShader::kClamp_TileMode set replicates the bitmap edge color when it samples
Cary Clarkbad5ad72017-08-03 17:14:08 -04004867outside of its bounds.
4868
4869#Param image Image containing pixels, dimensions, and format ##
4870#Param lattice division of bitmap into fixed and variable rectangles ##
4871#Param dst destination Rect of image to draw to ##
4872#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4873 and so on; or nullptr
4874##
Cary Clark8032b982017-07-28 11:04:54 -04004875
4876#Example
4877#Height 128
4878#Description
4879 The leftmost image is smaller than center; only corners are drawn, all scaled to fit.
Cary Clarkce101242017-09-01 15:51:02 -04004880 The second image equals the size of center; only corners are drawn without scaling.
4881 The remaining images are larger than center. All corners draw without scaling. The sides
Cary Clark8032b982017-07-28 11:04:54 -04004882 are scaled if needed to take up the remaining space; the center is transparent.
4883##
Cary Clarkbad5ad72017-08-03 17:14:08 -04004884void draw(SkCanvas* canvas) {
4885 SkIRect center = { 20, 10, 50, 40 };
4886 SkBitmap bitmap;
4887 bitmap.allocPixels(SkImageInfo::MakeN32Premul(60, 60));
4888 SkCanvas bitCanvas(bitmap);
4889 SkPaint paint;
4890 SkColor gray = 0xFF000000;
4891 int left = 0;
4892 for (auto right: { center.fLeft, center.fRight, bitmap.width() } ) {
4893 int top = 0;
4894 for (auto bottom: { center.fTop, center.fBottom, bitmap.height() } ) {
4895 paint.setColor(gray);
4896 bitCanvas.drawIRect(SkIRect::MakeLTRB(left, top, right, bottom), paint);
4897 gray += 0x001f1f1f;
4898 top = bottom;
4899 }
4900 left = right;
4901 }
4902 const int xDivs[] = { center.fLeft, center.fRight };
4903 const int yDivs[] = { center.fTop, center.fBottom };
4904 SkCanvas::Lattice::Flags flags[3][3];
4905 memset(flags, 0, sizeof(flags));
4906 flags[1][1] = SkCanvas::Lattice::kTransparent_Flags;
4907 SkCanvas::Lattice lattice = { xDivs, yDivs, flags[0], SK_ARRAY_COUNT(xDivs),
4908 SK_ARRAY_COUNT(yDivs), nullptr };
4909 sk_sp<SkImage> image = SkImage::MakeFromBitmap(bitmap);
4910 SkImage* imagePtr = image.get();
4911 for (auto dest: { 20, 30, 40, 60, 90 } ) {
4912 canvas->drawImageNine(imagePtr, center, SkRect::MakeWH(dest, dest), nullptr);
4913 canvas->translate(dest + 4, 0);
4914 }
Cary Clark8032b982017-07-28 11:04:54 -04004915}
4916##
4917
4918#ToDo incomplete ##
4919
4920##
4921
4922#Topic Draw_Image ##
4923
4924# ------------------------------------------------------------------------------
4925
4926#Method void drawText(const void* text, size_t byteLength, SkScalar x, SkScalar y,
4927 const SkPaint& paint)
4928
4929Draw text, with origin at (x, y), using Clip, Matrix, and Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004930
Cary Clarkbc5697d2017-10-04 14:31:33 -04004931text meaning depends on Paint_Text_Encoding; by default, text is encoded as
Cary Clarkbad5ad72017-08-03 17:14:08 -04004932UTF-8.
Cary Clark8032b982017-07-28 11:04:54 -04004933
Cary Clarkbad5ad72017-08-03 17:14:08 -04004934x and y meaning depends on Paint_Text_Align and Paint_Vertical_Text; by default
Cary Clarkbc5697d2017-10-04 14:31:33 -04004935text draws left to right, positioning the first glyph left side bearing at x
Cary Clarkbad5ad72017-08-03 17:14:08 -04004936and its baseline at y. Text size is affected by Matrix and Paint_Text_Size.
4937
4938All elements of paint: Path_Effect, Rasterizer, Mask_Filter, Shader,
4939Color_Filter, Image_Filter, and Draw_Looper; apply to text. By default, draws
Cary Clarkce101242017-09-01 15:51:02 -04004940filled 12 point black Glyphs.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004941
Cary Clarkce101242017-09-01 15:51:02 -04004942#Param text character code points or Glyphs drawn ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04004943#Param byteLength byte length of text array ##
4944#Param x start of text on x-axis ##
4945#Param y start of text on y-axis ##
4946#Param paint text size, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04004947
4948#Example
4949#Height 200
4950#Description
4951 The same text is drawn varying Paint_Text_Size and varying
4952 Matrix.
4953##
Cary Clarkbad5ad72017-08-03 17:14:08 -04004954void draw(SkCanvas* canvas) {
4955 SkPaint paint;
4956 paint.setAntiAlias(true);
4957 float textSizes[] = { 12, 18, 24, 36 };
4958 for (auto size: textSizes ) {
4959 paint.setTextSize(size);
4960 canvas->drawText("Aa", 2, 10, 20, paint);
4961 canvas->translate(0, size * 2);
4962 }
4963 paint.reset();
4964 paint.setAntiAlias(true);
4965 float yPos = 20;
4966 for (auto size: textSizes ) {
4967 float scale = size / 12.f;
4968 canvas->resetMatrix();
4969 canvas->translate(100, 0);
4970 canvas->scale(scale, scale);
4971 canvas->drawText("Aa", 2, 10 / scale, yPos / scale, paint);
4972 yPos += size * 2;
4973 }
4974}
Cary Clark8032b982017-07-28 11:04:54 -04004975##
4976
4977#ToDo incomplete ##
4978
4979##
4980
4981#Method void drawString(const char* string, SkScalar x, SkScalar y, const SkPaint& paint)
4982
Cary Clarkbad5ad72017-08-03 17:14:08 -04004983Draw null terminated string, with origin at (x, y), using Clip, Matrix, and
4984Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004985
Cary Clarkbc5697d2017-10-04 14:31:33 -04004986string meaning depends on Paint_Text_Encoding; by default, strings are encoded
4987as UTF-8. Other values of Paint_Text_Encoding are unlikely to produce the desired
Cary Clarkbad5ad72017-08-03 17:14:08 -04004988results, since zero bytes may be embedded in the string.
Cary Clark8032b982017-07-28 11:04:54 -04004989
Cary Clarkbad5ad72017-08-03 17:14:08 -04004990x and y meaning depends on Paint_Text_Align and Paint_Vertical_Text; by default
Cary Clarkbc5697d2017-10-04 14:31:33 -04004991string draws left to right, positioning the first glyph left side bearing at x
Cary Clarkbad5ad72017-08-03 17:14:08 -04004992and its baseline at y. Text size is affected by Matrix and Paint_Text_Size.
4993
4994All elements of paint: Path_Effect, Rasterizer, Mask_Filter, Shader,
4995Color_Filter, Image_Filter, and Draw_Looper; apply to text. By default, draws
Cary Clarkce101242017-09-01 15:51:02 -04004996filled 12 point black Glyphs.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004997
Cary Clarkce101242017-09-01 15:51:02 -04004998#Param string character code points or Glyphs drawn,
Cary Clarkbad5ad72017-08-03 17:14:08 -04004999 ending with a char value of zero
5000##
5001#Param x start of string on x-axis ##
5002#Param y start of string on y-axis ##
5003#Param paint text size, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005004
5005#Example
5006 SkPaint paint;
5007 canvas->drawString("a small hello", 20, 20, paint);
5008##
5009
5010#SeeAlso drawText
5011
5012##
5013
5014#Method void drawString(const SkString& string, SkScalar x, SkScalar y, const SkPaint& paint)
5015
Cary Clarkbad5ad72017-08-03 17:14:08 -04005016Draw null terminated string, with origin at (x, y), using Clip, Matrix, and
5017Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04005018
Cary Clarkbc5697d2017-10-04 14:31:33 -04005019string meaning depends on Paint_Text_Encoding; by default, strings are encoded
5020as UTF-8. Other values of Paint_Text_Encoding are unlikely to produce the desired
Cary Clarkbad5ad72017-08-03 17:14:08 -04005021results, since zero bytes may be embedded in the string.
Cary Clark8032b982017-07-28 11:04:54 -04005022
Cary Clarkbad5ad72017-08-03 17:14:08 -04005023x and y meaning depends on Paint_Text_Align and Paint_Vertical_Text; by default
Cary Clarkbc5697d2017-10-04 14:31:33 -04005024string draws left to right, positioning the first glyph left side bearing at x
Cary Clarkbad5ad72017-08-03 17:14:08 -04005025and its baseline at y. Text size is affected by Matrix and Paint_Text_Size.
5026
5027All elements of paint: Path_Effect, Rasterizer, Mask_Filter, Shader,
5028Color_Filter, Image_Filter, and Draw_Looper; apply to text. By default, draws
Cary Clarkce101242017-09-01 15:51:02 -04005029filled 12 point black Glyphs.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005030
Cary Clarkce101242017-09-01 15:51:02 -04005031#Param string character code points or Glyphs drawn,
Cary Clarkbad5ad72017-08-03 17:14:08 -04005032 ending with a char value of zero
5033##
5034#Param x start of string on x-axis ##
5035#Param y start of string on y-axis ##
5036#Param paint text size, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005037
5038#Example
5039 SkPaint paint;
5040 SkString string("a small hello");
5041 canvas->drawString(string, 20, 20, paint);
5042##
5043
5044#SeeAlso drawText
5045
5046##
5047
5048# ------------------------------------------------------------------------------
5049
5050#Method void drawPosText(const void* text, size_t byteLength, const SkPoint pos[],
5051 const SkPaint& paint)
5052
Cary Clarkbad5ad72017-08-03 17:14:08 -04005053Draw each glyph in text with the origin in pos array, using Clip, Matrix, and
Cary Clarkce101242017-09-01 15:51:02 -04005054Paint paint. The number of entries in pos array must match the number of Glyphs
Cary Clarkbad5ad72017-08-03 17:14:08 -04005055described by byteLength of text.
Cary Clark8032b982017-07-28 11:04:54 -04005056
Cary Clarkbc5697d2017-10-04 14:31:33 -04005057text meaning depends on Paint_Text_Encoding; by default, text is encoded as
Cary Clarkbad5ad72017-08-03 17:14:08 -04005058UTF-8. pos elements' meaning depends on Paint_Text_Align and Paint_Vertical_Text;
Cary Clarkbc5697d2017-10-04 14:31:33 -04005059by default each glyph left side bearing is positioned at x and its
Cary Clarkbad5ad72017-08-03 17:14:08 -04005060baseline is positioned at y. Text size is affected by Matrix and
5061Paint_Text_Size.
Cary Clark8032b982017-07-28 11:04:54 -04005062
Cary Clarkbad5ad72017-08-03 17:14:08 -04005063All elements of paint: Path_Effect, Rasterizer, Mask_Filter, Shader,
5064Color_Filter, Image_Filter, and Draw_Looper; apply to text. By default, draws
Cary Clarkce101242017-09-01 15:51:02 -04005065filled 12 point black Glyphs.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005066
5067Layout engines such as Harfbuzz typically position each glyph
Cary Clarkbc5697d2017-10-04 14:31:33 -04005068rather than using the font advance widths.
Cary Clark8032b982017-07-28 11:04:54 -04005069
Cary Clarkce101242017-09-01 15:51:02 -04005070#Param text character code points or Glyphs drawn ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005071#Param byteLength byte length of text array ##
5072#Param pos array of glyph origins ##
5073#Param paint text size, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005074
5075#Example
5076#Height 120
Cary Clarkbad5ad72017-08-03 17:14:08 -04005077void draw(SkCanvas* canvas) {
5078 const char hello[] = "HeLLo!";
5079 const SkPoint pos[] = { {40, 100}, {82, 95}, {115, 110}, {130, 95}, {145, 85},
5080 {172, 100} };
5081 SkPaint paint;
5082 paint.setTextSize(60);
5083 canvas->drawPosText(hello, strlen(hello), pos, paint);
Cary Clark8032b982017-07-28 11:04:54 -04005084}
5085##
5086
5087#ToDo incomplete ##
5088
5089##
5090
5091# ------------------------------------------------------------------------------
5092
5093#Method void drawPosTextH(const void* text, size_t byteLength, const SkScalar xpos[], SkScalar constY,
5094 const SkPaint& paint)
5095
Cary Clarkbad5ad72017-08-03 17:14:08 -04005096Draw each glyph in text with its (x, y) origin composed from xpos array and
5097constY, using Clip, Matrix, and Paint paint. The number of entries in xpos array
Cary Clarkce101242017-09-01 15:51:02 -04005098must match the number of Glyphs described by byteLength of text.
Cary Clark8032b982017-07-28 11:04:54 -04005099
Cary Clarkbc5697d2017-10-04 14:31:33 -04005100text meaning depends on Paint_Text_Encoding; by default, text is encoded as
Cary Clarkce101242017-09-01 15:51:02 -04005101UTF-8. xpos elements' meaning depends on Paint_Text_Align and Paint_Vertical_Text;
Cary Clarkbc5697d2017-10-04 14:31:33 -04005102by default each glyph left side bearing is positioned at an xpos element and
Cary Clarkbad5ad72017-08-03 17:14:08 -04005103its baseline is positioned at constY. Text size is affected by Matrix and
5104Paint_Text_Size.
Cary Clark8032b982017-07-28 11:04:54 -04005105
Cary Clarkbad5ad72017-08-03 17:14:08 -04005106All elements of paint: Path_Effect, Rasterizer, Mask_Filter, Shader,
5107Color_Filter, Image_Filter, and Draw_Looper; apply to text. By default, draws
Cary Clarkce101242017-09-01 15:51:02 -04005108filled 12 point black Glyphs.
Cary Clark8032b982017-07-28 11:04:54 -04005109
Cary Clarkbad5ad72017-08-03 17:14:08 -04005110Layout engines such as Harfbuzz typically position each glyph
Cary Clarkbc5697d2017-10-04 14:31:33 -04005111rather than using the font advance widths if all Glyphs share the same
Cary Clarkbad5ad72017-08-03 17:14:08 -04005112baseline.
5113
Cary Clarkce101242017-09-01 15:51:02 -04005114#Param text character code points or Glyphs drawn ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005115#Param byteLength byte length of text array ##
5116#Param xpos array of x positions, used to position each glyph ##
5117#Param constY shared y coordinate for all of x positions ##
5118#Param paint text size, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005119
5120#Example
5121#Height 40
Cary Clarkbad5ad72017-08-03 17:14:08 -04005122 void draw(SkCanvas* canvas) {
5123 SkScalar xpos[] = { 20, 40, 80, 160 };
5124 SkPaint paint;
5125 canvas->drawPosTextH("XXXX", 4, xpos, 20, paint);
5126 }
Cary Clark8032b982017-07-28 11:04:54 -04005127##
5128
5129#ToDo incomplete ##
5130
5131##
5132
5133# ------------------------------------------------------------------------------
5134
5135#Method void drawTextOnPathHV(const void* text, size_t byteLength, const SkPath& path, SkScalar hOffset,
5136 SkScalar vOffset, const SkPaint& paint)
5137
5138Draw text on Path path, using Clip, Matrix, and Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04005139
Cary Clarkbad5ad72017-08-03 17:14:08 -04005140Origin of text is at distance hOffset along the path, offset by a perpendicular
5141vector of length vOffset. If the path section corresponding the glyph advance is
5142curved, the glyph is drawn curved to match; control points in the glyph are
Cary Clarkbc5697d2017-10-04 14:31:33 -04005143mapped to projected points parallel to the path. If the text advance is larger
Cary Clarkbad5ad72017-08-03 17:14:08 -04005144than the path length, the excess text is clipped.
5145
Cary Clarkbc5697d2017-10-04 14:31:33 -04005146text meaning depends on Paint_Text_Encoding; by default, text is encoded as
Cary Clarkbad5ad72017-08-03 17:14:08 -04005147UTF-8. Origin meaning depends on Paint_Text_Align and Paint_Vertical_Text; by
Cary Clarkbc5697d2017-10-04 14:31:33 -04005148default text positions the first glyph left side bearing at origin x and its
Cary Clark8032b982017-07-28 11:04:54 -04005149baseline at origin y. Text size is affected by Matrix and Paint_Text_Size.
5150
Cary Clarkbad5ad72017-08-03 17:14:08 -04005151All elements of paint: Path_Effect, Rasterizer, Mask_Filter, Shader,
5152Color_Filter, Image_Filter, and Draw_Looper; apply to text. By default, draws
Cary Clarkce101242017-09-01 15:51:02 -04005153filled 12 point black Glyphs.
Cary Clark8032b982017-07-28 11:04:54 -04005154
Cary Clarkce101242017-09-01 15:51:02 -04005155#Param text character code points or Glyphs drawn ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005156#Param byteLength byte length of text array ##
5157#Param path Path providing text baseline ##
5158#Param hOffset distance along path to offset origin ##
5159#Param vOffset offset of text above (if negative) or below (if positive) the path ##
5160#Param paint text size, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005161
5162#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04005163 void draw(SkCanvas* canvas) {
5164 const char aero[] = "correo a" "\xC3" "\xA9" "reo";
5165 const size_t len = sizeof(aero) - 1;
5166 SkPath path;
5167 path.addOval({43-26, 43-26, 43+26, 43+26}, SkPath::kCW_Direction, 3);
5168 SkPaint paint;
5169 paint.setTextSize(24);
5170 for (auto offset : { 0, 10, 20 } ) {
5171 canvas->drawTextOnPathHV(aero, len, path, 0, -offset, paint);
5172 canvas->translate(70 + offset, 70 + offset);
5173 }
5174 }
Cary Clark8032b982017-07-28 11:04:54 -04005175##
5176
5177#ToDo incomplete ##
5178
5179##
5180
5181# ------------------------------------------------------------------------------
5182
5183#Method void drawTextOnPath(const void* text, size_t byteLength, const SkPath& path,
5184 const SkMatrix* matrix, const SkPaint& paint)
5185
5186Draw text on Path path, using Clip, Matrix, and Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04005187
Cary Clarkbad5ad72017-08-03 17:14:08 -04005188Origin of text is at beginning of path offset by matrix, if provided, before it
5189is mapped to path. If the path section corresponding the glyph advance is
5190curved, the glyph is drawn curved to match; control points in the glyph are
Cary Clarkbc5697d2017-10-04 14:31:33 -04005191mapped to projected points parallel to the path. If the text advance is larger
Cary Clarkbad5ad72017-08-03 17:14:08 -04005192than the path length, the excess text is clipped.
5193
Cary Clarkbc5697d2017-10-04 14:31:33 -04005194text meaning depends on Paint_Text_Encoding; by default, text is encoded as
Cary Clarkbad5ad72017-08-03 17:14:08 -04005195UTF-8. Origin meaning depends on Paint_Text_Align and Paint_Vertical_Text; by
Cary Clarkbc5697d2017-10-04 14:31:33 -04005196default text positions the first glyph left side bearing at origin x and its
Cary Clark8032b982017-07-28 11:04:54 -04005197baseline at origin y. Text size is affected by Matrix and Paint_Text_Size.
5198
Cary Clarkbad5ad72017-08-03 17:14:08 -04005199All elements of paint: Path_Effect, Rasterizer, Mask_Filter, Shader,
5200Color_Filter, Image_Filter, and Draw_Looper; apply to text. By default, draws
Cary Clarkce101242017-09-01 15:51:02 -04005201filled 12 point black Glyphs.
Cary Clark8032b982017-07-28 11:04:54 -04005202
Cary Clarkce101242017-09-01 15:51:02 -04005203#Param text character code points or Glyphs drawn ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005204#Param byteLength byte length of text array ##
5205#Param path Path providing text baseline ##
Cary Clarkce101242017-09-01 15:51:02 -04005206#Param matrix transform of Glyphs before mapping to path; may be nullptr
Cary Clarka523d2d2017-08-30 08:58:10 -04005207 to use identity Matrix
Cary Clarkbad5ad72017-08-03 17:14:08 -04005208##
5209#Param paint text size, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005210
5211#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04005212 void draw(SkCanvas* canvas) {
5213 const char roller[] = "rollercoaster";
5214 const size_t len = sizeof(roller) - 1;
5215 SkPath path;
5216 path.cubicTo(40, -80, 120, 80, 160, -40);
5217 SkPaint paint;
5218 paint.setTextSize(32);
5219 paint.setStyle(SkPaint::kStroke_Style);
5220 SkMatrix matrix;
5221 matrix.setIdentity();
5222 for (int i = 0; i < 3; ++i) {
5223 canvas->translate(25, 60);
5224 canvas->drawPath(path, paint);
5225 canvas->drawTextOnPath(roller, len, path, &matrix, paint);
5226 matrix.preTranslate(0, 10);
5227 }
5228 }
Cary Clark8032b982017-07-28 11:04:54 -04005229##
5230
5231#ToDo incomplete ##
5232
5233##
5234
5235# ------------------------------------------------------------------------------
5236
5237#Method void drawTextRSXform(const void* text, size_t byteLength, const SkRSXform xform[],
5238 const SkRect* cullRect, const SkPaint& paint)
5239
5240Draw text, transforming each glyph by the corresponding SkRSXform,
5241using Clip, Matrix, and Paint paint.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005242
Cary Clark8032b982017-07-28 11:04:54 -04005243RSXform array specifies a separate square scale, rotation, and translation for
5244each glyph.
Cary Clark8032b982017-07-28 11:04:54 -04005245
Cary Clarkbad5ad72017-08-03 17:14:08 -04005246Optional Rect cullRect is a conservative bounds of text, taking into account
Cary Clarkce101242017-09-01 15:51:02 -04005247RSXform and paint. If cullRect is outside of Clip, canvas can skip drawing.
Cary Clark8032b982017-07-28 11:04:54 -04005248
Cary Clarkbad5ad72017-08-03 17:14:08 -04005249All elements of paint: Path_Effect, Rasterizer, Mask_Filter, Shader,
5250Color_Filter, Image_Filter, and Draw_Looper; apply to text. By default, draws
Cary Clarkce101242017-09-01 15:51:02 -04005251filled 12 point black Glyphs.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005252
Cary Clarkce101242017-09-01 15:51:02 -04005253#Param text character code points or Glyphs drawn ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005254#Param byteLength byte length of text array ##
5255#Param xform RSXform rotates, scales, and translates each glyph individually ##
5256#Param cullRect Rect bounds of text for efficient clipping; or nullptr ##
5257#Param paint text size, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005258
5259#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04005260void draw(SkCanvas* canvas) {
5261 const int iterations = 26;
5262 SkRSXform transforms[iterations];
5263 char alphabet[iterations];
5264 SkScalar angle = 0;
5265 SkScalar scale = 1;
5266 for (size_t i = 0; i < SK_ARRAY_COUNT(transforms); ++i) {
5267 const SkScalar s = SkScalarSin(angle) * scale;
5268 const SkScalar c = SkScalarCos(angle) * scale;
5269 transforms[i] = SkRSXform::Make(-c, -s, -s * 16, c * 16);
5270 angle += .45;
5271 scale += .2;
5272 alphabet[i] = 'A' + i;
5273 }
5274 SkPaint paint;
5275 paint.setTextAlign(SkPaint::kCenter_Align);
5276 canvas->translate(110, 138);
5277 canvas->drawTextRSXform(alphabet, sizeof(alphabet), transforms, nullptr, paint);
Cary Clark8032b982017-07-28 11:04:54 -04005278}
5279##
5280
5281#ToDo incomplete ##
5282
5283##
5284
5285# ------------------------------------------------------------------------------
5286
5287#Method void drawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y, const SkPaint& paint)
5288
5289Draw Text_Blob blob at (x, y), using Clip, Matrix, and Paint paint.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005290
Cary Clarkce101242017-09-01 15:51:02 -04005291blob contains Glyphs, their positions, and paint attributes specific to text:
Cary Clarkbad5ad72017-08-03 17:14:08 -04005292Typeface, Paint_Text_Size, Paint_Text_Scale_X, Paint_Text_Skew_X,
5293Paint_Text_Align, Paint_Hinting, Anti-alias, Paint_Fake_Bold,
5294Font_Embedded_Bitmaps, Full_Hinting_Spacing, LCD_Text, Linear_Text,
5295Subpixel_Text, and Paint_Vertical_Text.
Cary Clark8032b982017-07-28 11:04:54 -04005296
5297Elements of paint: Path_Effect, Rasterizer, Mask_Filter, Shader, Color_Filter,
5298Image_Filter, and Draw_Looper; apply to blob.
5299
Cary Clarkce101242017-09-01 15:51:02 -04005300#Param blob Glyphs, positions, and their paints' text size, typeface, and so on ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005301#Param x horizontal offset applied to blob ##
5302#Param y vertical offset applied to blob ##
5303#Param paint blend, color, stroking, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005304
5305#Example
5306#Height 120
Cary Clarkbad5ad72017-08-03 17:14:08 -04005307 void draw(SkCanvas* canvas) {
5308 SkTextBlobBuilder textBlobBuilder;
5309 const char bunny[] = "/(^x^)\\";
5310 const int len = sizeof(bunny) - 1;
5311 uint16_t glyphs[len];
5312 SkPaint paint;
5313 paint.textToGlyphs(bunny, len, glyphs);
5314 int runs[] = { 3, 1, 3 };
5315 SkPoint textPos = { 20, 100 };
5316 int glyphIndex = 0;
5317 for (auto runLen : runs) {
5318 paint.setTextSize(1 == runLen ? 20 : 50);
5319 const SkTextBlobBuilder::RunBuffer& run =
5320 textBlobBuilder.allocRun(paint, runLen, textPos.fX, textPos.fY);
5321 memcpy(run.glyphs, &glyphs[glyphIndex], sizeof(glyphs[0]) * runLen);
5322 textPos.fX += paint.measureText(&bunny[glyphIndex], runLen, nullptr);
5323 glyphIndex += runLen;
5324 }
5325 sk_sp<const SkTextBlob> blob = textBlobBuilder.make();
5326 paint.reset();
5327 canvas->drawTextBlob(blob.get(), 0, 0, paint);
Cary Clark8032b982017-07-28 11:04:54 -04005328 }
5329##
5330
5331#ToDo incomplete ##
5332
5333##
5334
5335# ------------------------------------------------------------------------------
5336
5337#Method void drawTextBlob(const sk_sp<SkTextBlob>& blob, SkScalar x, SkScalar y, const SkPaint& paint)
5338
5339Draw Text_Blob blob at (x, y), using Clip, Matrix, and Paint paint.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005340
Cary Clarkce101242017-09-01 15:51:02 -04005341blob contains Glyphs, their positions, and paint attributes specific to text:
Cary Clarkbad5ad72017-08-03 17:14:08 -04005342Typeface, Paint_Text_Size, Paint_Text_Scale_X, Paint_Text_Skew_X,
5343Paint_Text_Align, Paint_Hinting, Anti-alias, Paint_Fake_Bold,
5344Font_Embedded_Bitmaps, Full_Hinting_Spacing, LCD_Text, Linear_Text,
5345Subpixel_Text, and Paint_Vertical_Text.
Cary Clark8032b982017-07-28 11:04:54 -04005346
5347Elements of paint: Path_Effect, Rasterizer, Mask_Filter, Shader, Color_Filter,
5348Image_Filter, and Draw_Looper; apply to blob.
5349
Cary Clarkce101242017-09-01 15:51:02 -04005350#Param blob Glyphs, positions, and their paints' text size, typeface, and so on ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005351#Param x horizontal offset applied to blob ##
5352#Param y vertical offset applied to blob ##
5353#Param paint blend, color, stroking, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005354
5355#Example
5356#Height 120
5357#Description
5358Paint attributes unrelated to text, like color, have no effect on paint in allocated Text_Blob.
5359Paint attributes related to text, like text size, have no effect on paint passed to drawTextBlob.
5360##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005361 void draw(SkCanvas* canvas) {
5362 SkTextBlobBuilder textBlobBuilder;
5363 SkPaint paint;
5364 paint.setTextSize(50);
5365 paint.setColor(SK_ColorRED);
5366 const SkTextBlobBuilder::RunBuffer& run =
5367 textBlobBuilder.allocRun(paint, 1, 20, 100);
5368 run.glyphs[0] = 20;
5369 sk_sp<const SkTextBlob> blob = textBlobBuilder.make();
5370 paint.setTextSize(10);
5371 paint.setColor(SK_ColorBLUE);
5372 canvas->drawTextBlob(blob.get(), 0, 0, paint);
5373 }
Cary Clark8032b982017-07-28 11:04:54 -04005374##
5375
5376#ToDo incomplete ##
5377
5378##
5379
5380# ------------------------------------------------------------------------------
5381
5382#Method void drawPicture(const SkPicture* picture)
5383
5384Draw Picture picture, using Clip and Matrix.
5385Clip and Matrix are unchanged by picture contents, as if
5386save() was called before and restore() was called after drawPicture.
5387
5388Picture records a series of draw commands for later playback.
5389
Cary Clarkbad5ad72017-08-03 17:14:08 -04005390#Param picture recorded drawing commands to play ##
Cary Clark8032b982017-07-28 11:04:54 -04005391
5392#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04005393void draw(SkCanvas* canvas) {
5394 SkPictureRecorder recorder;
5395 SkCanvas* recordingCanvas = recorder.beginRecording(50, 50);
5396 for (auto color : { SK_ColorRED, SK_ColorBLUE, 0xff007f00 } ) {
5397 SkPaint paint;
5398 paint.setColor(color);
5399 recordingCanvas->drawRect({10, 10, 30, 40}, paint);
5400 recordingCanvas->translate(10, 10);
5401 recordingCanvas->scale(1.2f, 1.4f);
5402 }
5403 sk_sp<SkPicture> playback = recorder.finishRecordingAsPicture();
5404 const SkPicture* playbackPtr = playback.get();
5405 canvas->drawPicture(playback);
5406 canvas->scale(2, 2);
5407 canvas->translate(50, 0);
5408 canvas->drawPicture(playback);
Cary Clark8032b982017-07-28 11:04:54 -04005409}
5410##
5411
5412#ToDo incomplete ##
5413
5414##
5415
5416# ------------------------------------------------------------------------------
5417
5418#Method void drawPicture(const sk_sp<SkPicture>& picture)
5419
5420Draw Picture picture, using Clip and Matrix.
5421Clip and Matrix are unchanged by picture contents, as if
5422save() was called before and restore() was called after drawPicture.
5423
5424Picture records a series of draw commands for later playback.
5425
Cary Clarkbad5ad72017-08-03 17:14:08 -04005426#Param picture recorded drawing commands to play ##
Cary Clark8032b982017-07-28 11:04:54 -04005427
5428#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04005429void draw(SkCanvas* canvas) {
5430 SkPictureRecorder recorder;
5431 SkCanvas* recordingCanvas = recorder.beginRecording(50, 50);
5432 for (auto color : { SK_ColorRED, SK_ColorBLUE, 0xff007f00 } ) {
5433 SkPaint paint;
5434 paint.setColor(color);
5435 recordingCanvas->drawRect({10, 10, 30, 40}, paint);
5436 recordingCanvas->translate(10, 10);
5437 recordingCanvas->scale(1.2f, 1.4f);
5438 }
5439 sk_sp<SkPicture> playback = recorder.finishRecordingAsPicture();
5440 canvas->drawPicture(playback);
5441 canvas->scale(2, 2);
5442 canvas->translate(50, 0);
5443 canvas->drawPicture(playback);
Cary Clark8032b982017-07-28 11:04:54 -04005444}
5445##
5446
5447#ToDo incomplete ##
5448
5449##
5450
5451# ------------------------------------------------------------------------------
5452
5453#Method void drawPicture(const SkPicture* picture, const SkMatrix* matrix, const SkPaint* paint)
5454
Cary Clarkbad5ad72017-08-03 17:14:08 -04005455Draw Picture picture, using Clip and Matrix; transforming picture with
5456Matrix matrix, if provided; and use Paint paint Color_Alpha, Color_Filter,
5457Image_Filter, and Blend_Mode, if provided.
Cary Clark8032b982017-07-28 11:04:54 -04005458
5459matrix transformation is equivalent to: save(), concat(), drawPicture, restore().
5460paint use is equivalent to: saveLayer, drawPicture, restore().
5461
Cary Clarkbad5ad72017-08-03 17:14:08 -04005462#Param picture recorded drawing commands to play ##
5463#Param matrix Matrix to rotate, scale, translate, and so on; may be nullptr ##
5464#Param paint Paint to apply transparency, filtering, and so on; may be nullptr ##
Cary Clark8032b982017-07-28 11:04:54 -04005465
5466#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04005467void draw(SkCanvas* canvas) {
5468 SkPaint paint;
5469 SkPictureRecorder recorder;
5470 SkCanvas* recordingCanvas = recorder.beginRecording(50, 50);
5471 for (auto color : { SK_ColorRED, SK_ColorBLUE, 0xff007f00 } ) {
5472 paint.setColor(color);
5473 recordingCanvas->drawRect({10, 10, 30, 40}, paint);
5474 recordingCanvas->translate(10, 10);
5475 recordingCanvas->scale(1.2f, 1.4f);
5476 }
5477 sk_sp<SkPicture> playback = recorder.finishRecordingAsPicture();
5478 const SkPicture* playbackPtr = playback.get();
5479 SkMatrix matrix;
5480 matrix.reset();
5481 for (auto alpha : { 70, 140, 210 } ) {
5482 paint.setAlpha(alpha);
5483 canvas->drawPicture(playbackPtr, &matrix, &paint);
5484 matrix.preTranslate(70, 70);
5485 }
Cary Clark8032b982017-07-28 11:04:54 -04005486}
5487##
5488
5489#ToDo incomplete ##
5490
5491##
5492
5493# ------------------------------------------------------------------------------
5494
5495#Method void drawPicture(const sk_sp<SkPicture>& picture, const SkMatrix* matrix, const SkPaint* paint)
5496
Cary Clarkbad5ad72017-08-03 17:14:08 -04005497Draw Picture picture, using Clip and Matrix; transforming picture with
5498Matrix matrix, if provided; and use Paint paint Color_Alpha, Color_Filter,
5499Image_Filter, and Blend_Mode, if provided.
Cary Clark8032b982017-07-28 11:04:54 -04005500
5501matrix transformation is equivalent to: save(), concat(), drawPicture, restore().
5502paint use is equivalent to: saveLayer, drawPicture, restore().
5503
Cary Clarkbad5ad72017-08-03 17:14:08 -04005504#Param picture recorded drawing commands to play ##
5505#Param matrix Matrix to rotate, scale, translate, and so on; may be nullptr ##
5506#Param paint Paint to apply transparency, filtering, and so on; may be nullptr ##
Cary Clark8032b982017-07-28 11:04:54 -04005507
5508#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04005509void draw(SkCanvas* canvas) {
5510 SkPaint paint;
5511 SkPictureRecorder recorder;
5512 SkCanvas* recordingCanvas = recorder.beginRecording(50, 50);
5513 for (auto color : { SK_ColorRED, SK_ColorBLUE, 0xff007f00 } ) {
5514 paint.setColor(color);
5515 recordingCanvas->drawRect({10, 10, 30, 40}, paint);
5516 recordingCanvas->translate(10, 10);
5517 recordingCanvas->scale(1.2f, 1.4f);
5518 }
5519 sk_sp<SkPicture> playback = recorder.finishRecordingAsPicture();
5520 SkMatrix matrix;
5521 matrix.reset();
5522 for (auto alpha : { 70, 140, 210 } ) {
5523 paint.setAlpha(alpha);
5524 canvas->drawPicture(playback, &matrix, &paint);
5525 matrix.preTranslate(70, 70);
5526 }
Cary Clark8032b982017-07-28 11:04:54 -04005527}
5528##
5529
5530#ToDo incomplete ##
5531
5532##
5533
5534# ------------------------------------------------------------------------------
5535
5536#Method void drawVertices(const SkVertices* vertices, SkBlendMode mode, const SkPaint& paint)
5537
5538Draw Vertices vertices, a triangle mesh, using Clip and Matrix.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005539If Vertices_Texs and Vertices_Colors are defined in vertices, and Paint paint
5540contains Shader, Blend_Mode mode combines Vertices_Colors with Shader.
Cary Clark8032b982017-07-28 11:04:54 -04005541
Cary Clarkbad5ad72017-08-03 17:14:08 -04005542#Param vertices triangle mesh to draw ##
5543#Param mode combines Vertices_Colors with Shader, if both are present ##
5544#Param paint specifies the Shader, used as Vertices texture; may be nullptr ##
Cary Clark8032b982017-07-28 11:04:54 -04005545
5546#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04005547void draw(SkCanvas* canvas) {
5548 SkPaint paint;
5549 SkPoint points[] = { { 0, 0 }, { 250, 0 }, { 100, 100 }, { 0, 250 } };
5550 SkColor colors[] = { SK_ColorRED, SK_ColorBLUE, SK_ColorYELLOW, SK_ColorCYAN };
5551 auto vertices = SkVertices::MakeCopy(SkVertices::kTriangleFan_VertexMode,
5552 SK_ARRAY_COUNT(points), points, nullptr, colors);
5553 canvas->drawVertices(vertices.get(), SkBlendMode::kSrc, paint);
5554}
Cary Clark8032b982017-07-28 11:04:54 -04005555##
5556
5557#ToDo incomplete ##
5558
5559##
5560
5561# ------------------------------------------------------------------------------
5562
5563#Method void drawVertices(const sk_sp<SkVertices>& vertices, SkBlendMode mode, const SkPaint& paint)
5564
5565Draw Vertices vertices, a triangle mesh, using Clip and Matrix.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005566If Vertices_Texs and Vertices_Colors are defined in vertices, and Paint paint
5567contains Shader, Blend_Mode mode combines Vertices_Colors with Shader.
Cary Clark8032b982017-07-28 11:04:54 -04005568
Cary Clarkbad5ad72017-08-03 17:14:08 -04005569#Param vertices triangle mesh to draw ##
5570#Param mode combines Vertices_Colors with Shader, if both are present ##
5571#Param paint specifies the Shader, used as Vertices texture, may be nullptr ##
Cary Clark8032b982017-07-28 11:04:54 -04005572
5573#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04005574void draw(SkCanvas* canvas) {
5575 SkPaint paint;
5576 SkPoint points[] = { { 0, 0 }, { 250, 0 }, { 100, 100 }, { 0, 250 } };
5577 SkPoint texs[] = { { 0, 0 }, { 0, 250 }, { 250, 250 }, { 250, 0 } };
5578 SkColor colors[] = { SK_ColorRED, SK_ColorBLUE, SK_ColorYELLOW, SK_ColorCYAN };
5579 paint.setShader(SkGradientShader::MakeLinear(points, colors, nullptr, 4,
5580 SkShader::kClamp_TileMode));
5581 auto vertices = SkVertices::MakeCopy(SkVertices::kTriangleFan_VertexMode,
5582 SK_ARRAY_COUNT(points), points, texs, colors);
5583 canvas->drawVertices(vertices.get(), SkBlendMode::kDarken, paint);
Cary Clark8032b982017-07-28 11:04:54 -04005584}
5585##
5586
5587#ToDo incomplete ##
5588
5589##
5590
5591# ------------------------------------------------------------------------------
5592
5593#Method void drawPatch(const SkPoint cubics[12], const SkColor colors[4],
5594 const SkPoint texCoords[4], SkBlendMode mode, const SkPaint& paint)
5595
Cary Clarkce101242017-09-01 15:51:02 -04005596Draws a Coons patch: the interpolation of four cubics with shared corners,
Cary Clark8032b982017-07-28 11:04:54 -04005597associating a color, and optionally a texture coordinate, with each corner.
5598
Cary Clarkbc5697d2017-10-04 14:31:33 -04005599The Coons patch uses Clip and Matrix, paint Shader, Color_Filter,
Cary Clarkbad5ad72017-08-03 17:14:08 -04005600Color_Alpha, Image_Filter, and Blend_Mode. If Shader is provided it is treated
5601as the Coons patch texture; Blend_Mode mode combines Color colors and Shader if
5602both are provided.
Cary Clark8032b982017-07-28 11:04:54 -04005603
Cary Clarkbc5697d2017-10-04 14:31:33 -04005604Point array cubics specifies four Cubics starting at the top-left corner,
Cary Clarkce101242017-09-01 15:51:02 -04005605in clockwise order, sharing every fourth point. The last Cubic ends at the
Cary Clarkbad5ad72017-08-03 17:14:08 -04005606first point.
Cary Clark8032b982017-07-28 11:04:54 -04005607
Cary Clarkbc5697d2017-10-04 14:31:33 -04005608Color array color associates colors with corners in top-left, top-right,
5609bottom-right, bottom-left order.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005610
5611If paint contains Shader, Point array texCoords maps Shader as texture to
Cary Clarkbc5697d2017-10-04 14:31:33 -04005612corners in top-left, top-right, bottom-right, bottom-left order.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005613
Cary Clarka523d2d2017-08-30 08:58:10 -04005614#Param cubics Path_Cubic array, sharing common points ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005615#Param colors Color array, one for each corner ##
Cary Clarkce101242017-09-01 15:51:02 -04005616#Param texCoords Point array of texture coordinates, mapping Shader to corners;
Cary Clarkbad5ad72017-08-03 17:14:08 -04005617 may be nullptr
Cary Clark579985c2017-07-31 11:48:27 -04005618#Param ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005619#Param mode Blend_Mode for colors, and for Shader if paint has one ##
5620#Param paint Shader, Color_Filter, Blend_Mode, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005621
5622#Example
5623#Image 5
Cary Clarkbad5ad72017-08-03 17:14:08 -04005624void draw(SkCanvas* canvas) {
5625 // SkBitmap source = cmbkygk;
5626 SkPaint paint;
5627 paint.setFilterQuality(kLow_SkFilterQuality);
5628 paint.setAntiAlias(true);
5629 SkPoint cubics[] = { { 3, 1 }, { 4, 2 }, { 5, 1 }, { 7, 3 },
5630 /* { 7, 3 }, */ { 6, 4 }, { 7, 5 }, { 5, 7 },
5631 /* { 5, 7 }, */ { 4, 6 }, { 3, 7 }, { 1, 5 },
5632 /* { 1, 5 }, */ { 2, 4 }, { 1, 3 }, /* { 3, 1 } */ };
5633 SkColor colors[] = { 0xbfff0000, 0xbf0000ff, 0xbfff00ff, 0xbf00ffff };
5634 SkPoint texCoords[] = { { -30, -30 }, { 162, -30}, { 162, 162}, { -30, 162} };
5635 paint.setShader(SkShader::MakeBitmapShader(source, SkShader::kClamp_TileMode,
5636 SkShader::kClamp_TileMode, nullptr));
5637 canvas->scale(15, 15);
5638 for (auto blend : { SkBlendMode::kSrcOver, SkBlendMode::kModulate, SkBlendMode::kXor } ) {
5639 canvas->drawPatch(cubics, colors, texCoords, blend, paint);
5640 canvas->translate(4, 4);
5641 }
Cary Clark8032b982017-07-28 11:04:54 -04005642}
5643##
5644
Cary Clarkbad5ad72017-08-03 17:14:08 -04005645#ToDo incomplete; can patch use image filter? ##
Cary Clark8032b982017-07-28 11:04:54 -04005646
5647##
5648
5649# ------------------------------------------------------------------------------
5650
5651#Method void drawPatch(const SkPoint cubics[12], const SkColor colors[4],
5652 const SkPoint texCoords[4], const SkPaint& paint)
5653
Cary Clarkce101242017-09-01 15:51:02 -04005654Draws Cubic Coons patch: the interpolation of four cubics with shared corners,
Cary Clarkbad5ad72017-08-03 17:14:08 -04005655associating a color, and optionally a texture coordinate, with each corner.
Cary Clark8032b982017-07-28 11:04:54 -04005656
Cary Clarkbc5697d2017-10-04 14:31:33 -04005657The Coons patch uses Clip and Matrix, paint Shader, Color_Filter,
Cary Clarkbad5ad72017-08-03 17:14:08 -04005658Color_Alpha, Image_Filter, and Blend_Mode. If Shader is provided it is treated
5659as the Coons patch texture; Blend_Mode mode combines Color colors and Shader if
5660both are provided.
Cary Clark8032b982017-07-28 11:04:54 -04005661
Cary Clarkbc5697d2017-10-04 14:31:33 -04005662Point array cubics specifies four Cubics starting at the top-left corner,
Cary Clarkce101242017-09-01 15:51:02 -04005663in clockwise order, sharing every fourth point. The last Cubic ends at the
Cary Clarkbad5ad72017-08-03 17:14:08 -04005664first point.
5665
Cary Clarkbc5697d2017-10-04 14:31:33 -04005666Color array color associates colors with corners in top-left, top-right,
5667bottom-right, bottom-left order.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005668
5669If paint contains Shader, Point array texCoords maps Shader as texture to
Cary Clarkbc5697d2017-10-04 14:31:33 -04005670corners in top-left, top-right, bottom-right, bottom-left order.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005671
Cary Clarka523d2d2017-08-30 08:58:10 -04005672#Param cubics Path_Cubic array, sharing common points ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005673#Param colors Color array, one for each corner ##
Cary Clarkce101242017-09-01 15:51:02 -04005674#Param texCoords Point array of texture coordinates, mapping Shader to corners;
Cary Clarkbad5ad72017-08-03 17:14:08 -04005675 may be nullptr
Cary Clark579985c2017-07-31 11:48:27 -04005676#Param ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005677#Param paint Shader, Color_Filter, Blend_Mode, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005678
5679#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04005680void draw(SkCanvas* canvas) {
5681 SkPaint paint;
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 SkColor colors[] = { SK_ColorRED, SK_ColorBLUE, SK_ColorYELLOW, SK_ColorCYAN };
5688 canvas->scale(30, 30);
5689 canvas->drawPatch(cubics, colors, nullptr, paint);
5690 SkPoint text[] = { {3,0.9f}, {4,2.5f}, {5,0.9f}, {7.5f,3.2f}, {5.5f,4.2f},
5691 {7.5f,5.2f}, {5,7.5f}, {4,5.9f}, {3,7.5f}, {0.5f,5.2f}, {2.5f,4.2f},
5692 {0.5f,3.2f} };
5693 paint.setTextSize(18.f / 30);
5694 paint.setTextAlign(SkPaint::kCenter_Align);
5695 for (int i = 0; i< 10; ++i) {
5696 char digit = '0' + i;
5697 canvas->drawText(&digit, 1, text[i].fX, text[i].fY, paint);
5698 }
5699 canvas->drawString("10", text[10].fX, text[10].fY, paint);
5700 canvas->drawString("11", text[11].fX, text[11].fY, paint);
5701 paint.setStyle(SkPaint::kStroke_Style);
5702 canvas->drawPoints(SkCanvas::kPolygon_PointMode, 12, cubics, paint);
5703 canvas->drawLine(cubics[11].fX, cubics[11].fY, cubics[0].fX, cubics[0].fY, paint);
Cary Clark8032b982017-07-28 11:04:54 -04005704}
5705##
5706
5707#Example
5708#Image 6
Cary Clarkbad5ad72017-08-03 17:14:08 -04005709void draw(SkCanvas* canvas) {
5710 // SkBitmap source = checkerboard;
5711 SkPaint paint;
5712 paint.setFilterQuality(kLow_SkFilterQuality);
5713 paint.setAntiAlias(true);
5714 SkPoint cubics[] = { { 3, 1 }, { 4, 2 }, { 5, 1 }, { 7, 3 },
5715 /* { 7, 3 }, */ { 6, 4 }, { 7, 5 }, { 5, 7 },
5716 /* { 5, 7 }, */ { 4, 6 }, { 3, 7 }, { 1, 5 },
5717 /* { 1, 5 }, */ { 2, 4 }, { 1, 3 }, /* { 3, 1 } */ };
5718 SkPoint texCoords[] = { { 0, 0 }, { 0, 62}, { 62, 62}, { 62, 0 } };
5719 paint.setShader(SkShader::MakeBitmapShader(source, SkShader::kClamp_TileMode,
5720 SkShader::kClamp_TileMode, nullptr));
5721 canvas->scale(30, 30);
5722 canvas->drawPatch(cubics, nullptr, texCoords, paint);
Cary Clark8032b982017-07-28 11:04:54 -04005723}
5724##
5725
Cary Clarkbad5ad72017-08-03 17:14:08 -04005726#ToDo incomplete; can patch use image filter? ##
Cary Clark8032b982017-07-28 11:04:54 -04005727
5728##
5729
5730# ------------------------------------------------------------------------------
5731
5732#Method void drawAtlas(const SkImage* atlas, const SkRSXform xform[], const SkRect tex[],
5733 const SkColor colors[], int count, SkBlendMode mode, const SkRect* cullRect,
5734 const SkPaint* paint)
5735
5736Draw a set of sprites from atlas, using Clip, Matrix, and optional Paint paint.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005737paint uses Anti-alias, Color_Alpha, Color_Filter, Image_Filter, and Blend_Mode
5738to draw, if present. For each entry in the array, Rect tex locates sprite in
5739atlas, and RSXform xform transforms it into destination space.
5740
Cary Clark8032b982017-07-28 11:04:54 -04005741xform, text, and colors if present, must contain count entries.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005742Optional colors are applied for each sprite using Blend_Mode.
Cary Clark8032b982017-07-28 11:04:54 -04005743Optional cullRect is a conservative bounds of all transformed sprites.
Cary Clarkce101242017-09-01 15:51:02 -04005744If cullRect is outside of Clip, canvas can skip drawing.
Cary Clark8032b982017-07-28 11:04:54 -04005745
Cary Clarkbad5ad72017-08-03 17:14:08 -04005746#Param atlas Image containing sprites ##
5747#Param xform RSXform mappings for sprites in atlas ##
5748#Param tex Rect locations of sprites in atlas ##
Cary Clark6fc50412017-09-21 12:31:06 -04005749#Param colors one per sprite, blended with sprite using Blend_Mode; may be nullptr ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005750#Param count number of sprites to draw ##
5751#Param mode Blend_Mode combining colors and sprites ##
Cary Clark6fc50412017-09-21 12:31:06 -04005752#Param cullRect bounds of transformed sprites for efficient clipping; may be nullptr ##
5753#Param paint Color_Filter, Image_Filter, Blend_Mode, and so on; may be nullptr ##
Cary Clark8032b982017-07-28 11:04:54 -04005754
5755#Example
5756#Image 3
Cary Clarkbad5ad72017-08-03 17:14:08 -04005757void draw(SkCanvas* canvas) {
5758 // SkBitmap source = mandrill;
5759 SkRSXform xforms[] = { { .5f, 0, 0, 0 }, {0, .5f, 200, 100 } };
5760 SkRect tex[] = { { 0, 0, 250, 250 }, { 0, 0, 250, 250 } };
5761 SkColor colors[] = { 0x7f55aa00, 0x7f3333bf };
5762 const SkImage* imagePtr = image.get();
5763 canvas->drawAtlas(imagePtr, xforms, tex, colors, 2, SkBlendMode::kSrcOver, nullptr, nullptr);
Cary Clark8032b982017-07-28 11:04:54 -04005764}
5765##
5766
5767#ToDo incomplete ##
5768
5769##
5770
5771# ------------------------------------------------------------------------------
5772
5773#Method void drawAtlas(const sk_sp<SkImage>& atlas, const SkRSXform xform[], const SkRect tex[],
5774 const SkColor colors[], int count, SkBlendMode mode, const SkRect* cullRect,
5775 const SkPaint* paint)
5776
5777Draw a set of sprites from atlas, using Clip, Matrix, and optional Paint paint.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005778paint uses Anti-alias, Color_Alpha, Color_Filter, Image_Filter, and Blend_Mode
5779to draw, if present. For each entry in the array, Rect tex locates sprite in
5780atlas, and RSXform xform transforms it into destination space.
5781
Cary Clark8032b982017-07-28 11:04:54 -04005782xform, text, and colors if present, must contain count entries.
5783Optional colors is applied for each sprite using Blend_Mode.
5784Optional cullRect is a conservative bounds of all transformed sprites.
Cary Clarkce101242017-09-01 15:51:02 -04005785If cullRect is outside of Clip, canvas can skip drawing.
Cary Clark8032b982017-07-28 11:04:54 -04005786
Cary Clarkbad5ad72017-08-03 17:14:08 -04005787#Param atlas Image containing sprites ##
5788#Param xform RSXform mappings for sprites in atlas ##
5789#Param tex Rect locations of sprites in atlas ##
Cary Clark6fc50412017-09-21 12:31:06 -04005790#Param colors one per sprite, blended with sprite using Blend_Mode; may be nullptr ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005791#Param count number of sprites to draw ##
5792#Param mode Blend_Mode combining colors and sprites ##
Cary Clark6fc50412017-09-21 12:31:06 -04005793#Param cullRect bounds of transformed sprites for efficient clipping; may be nullptr ##
5794#Param paint Color_Filter, Image_Filter, Blend_Mode, and so on; may be nullptr ##
Cary Clark8032b982017-07-28 11:04:54 -04005795
5796#Example
5797#Image 3
Cary Clarkbad5ad72017-08-03 17:14:08 -04005798void draw(SkCanvas* canvas) {
5799 // SkBitmap source = mandrill;
5800 SkRSXform xforms[] = { { .5f, 0, 0, 0 }, {0, .5f, 200, 100 } };
5801 SkRect tex[] = { { 0, 0, 250, 250 }, { 0, 0, 250, 250 } };
5802 SkColor colors[] = { 0x7f55aa00, 0x7f3333bf };
5803 SkPaint paint;
5804 paint.setAlpha(127);
5805 canvas->drawAtlas(image, xforms, tex, colors, 2, SkBlendMode::kPlus, nullptr, &paint);
Cary Clark8032b982017-07-28 11:04:54 -04005806}
5807##
5808
5809#ToDo bug in example on cpu side, gpu looks ok ##
5810
5811##
5812
5813# ------------------------------------------------------------------------------
5814
5815#Method void drawAtlas(const SkImage* atlas, const SkRSXform xform[], const SkRect tex[], int count,
5816 const SkRect* cullRect, const SkPaint* paint)
5817
5818Draw a set of sprites from atlas, using Clip, Matrix, and optional Paint paint.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005819paint uses Anti-alias, Color_Alpha, Color_Filter, Image_Filter, and Blend_Mode
5820to draw, if present. For each entry in the array, Rect tex locates sprite in
5821atlas, and RSXform xform transforms it into destination space.
5822
Cary Clark8032b982017-07-28 11:04:54 -04005823xform and text must contain count entries.
5824Optional cullRect is a conservative bounds of all transformed sprites.
Cary Clarkce101242017-09-01 15:51:02 -04005825If cullRect is outside of Clip, canvas can skip drawing.
Cary Clark8032b982017-07-28 11:04:54 -04005826
Cary Clarkbad5ad72017-08-03 17:14:08 -04005827#Param atlas Image containing sprites ##
5828#Param xform RSXform mappings for sprites in atlas ##
5829#Param tex Rect locations of sprites in atlas ##
5830#Param count number of sprites to draw ##
Cary Clark6fc50412017-09-21 12:31:06 -04005831#Param cullRect bounds of transformed sprites for efficient clipping; may be nullptr ##
5832#Param paint Color_Filter, Image_Filter, Blend_Mode, and so on; may be nullptr ##
Cary Clark8032b982017-07-28 11:04:54 -04005833
5834#Example
5835#Image 3
Cary Clarkbad5ad72017-08-03 17:14:08 -04005836void draw(SkCanvas* canvas) {
5837 // sk_sp<SkImage> image = mandrill;
5838 SkRSXform xforms[] = { { .5f, 0, 0, 0 }, {0, .5f, 200, 100 } };
5839 SkRect tex[] = { { 0, 0, 250, 250 }, { 0, 0, 250, 250 } };
5840 const SkImage* imagePtr = image.get();
5841 canvas->drawAtlas(imagePtr, xforms, tex, 2, nullptr, nullptr);
Cary Clark8032b982017-07-28 11:04:54 -04005842}
5843##
5844
5845#ToDo incomplete ##
5846
5847##
5848
5849# ------------------------------------------------------------------------------
5850
5851#Method void drawAtlas(const sk_sp<SkImage>& atlas, const SkRSXform xform[], const SkRect tex[],
5852 int count, const SkRect* cullRect, const SkPaint* paint)
5853
5854Draw a set of sprites from atlas, using Clip, Matrix, and optional Paint paint.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005855paint uses Anti-alias, Color_Alpha, Color_Filter, Image_Filter, and Blend_Mode
5856to draw, if present. For each entry in the array, Rect tex locates sprite in
5857atlas, and RSXform xform transforms it into destination space.
5858
Cary Clark8032b982017-07-28 11:04:54 -04005859xform and text must contain count entries.
5860Optional cullRect is a conservative bounds of all transformed sprites.
Cary Clarkce101242017-09-01 15:51:02 -04005861If cullRect is outside of Clip, canvas can skip drawing.
Cary Clark8032b982017-07-28 11:04:54 -04005862
Cary Clarkbad5ad72017-08-03 17:14:08 -04005863#Param atlas Image containing sprites ##
5864#Param xform RSXform mappings for sprites in atlas ##
5865#Param tex Rect locations of sprites in atlas ##
5866#Param count number of sprites to draw ##
Cary Clark6fc50412017-09-21 12:31:06 -04005867#Param cullRect bounds of transformed sprites for efficient clipping; may be nullptr ##
5868#Param paint Color_Filter, Image_Filter, Blend_Mode, and so on; may be nullptr ##
Cary Clark8032b982017-07-28 11:04:54 -04005869
5870#Example
5871#Image 3
Cary Clarkbad5ad72017-08-03 17:14:08 -04005872void draw(SkCanvas* canvas) {
5873 // sk_sp<SkImage> image = mandrill;
5874 SkRSXform xforms[] = { { 1, 0, 0, 0 }, {0, 1, 300, 100 } };
5875 SkRect tex[] = { { 0, 0, 200, 200 }, { 200, 0, 400, 200 } };
5876 canvas->drawAtlas(image, xforms, tex, 2, nullptr, nullptr);
Cary Clark8032b982017-07-28 11:04:54 -04005877}
5878##
5879
5880#ToDo incomplete ##
5881
5882##
5883
5884# ------------------------------------------------------------------------------
5885
Cary Clark73fa9722017-08-29 17:36:51 -04005886#Method void drawDrawable(SkDrawable* drawable, const SkMatrix* matrix = nullptr)
Cary Clark8032b982017-07-28 11:04:54 -04005887
5888Draw Drawable drawable using Clip and Matrix, concatenated with
5889optional matrix.
5890
5891If Canvas has an asynchronous implementation, as is the case
5892when it is recording into Picture, then drawable will be referenced,
5893so that SkDrawable::draw() can be called when the operation is finalized. To force
5894immediate drawing, call SkDrawable::draw() instead.
5895
Cary Clarkbad5ad72017-08-03 17:14:08 -04005896#Param drawable custom struct encapsulating drawing commands ##
5897#Param matrix transformation applied to drawing; may be nullptr ##
Cary Clark8032b982017-07-28 11:04:54 -04005898
5899#Example
5900#Height 100
5901#Function
Cary Clarkbad5ad72017-08-03 17:14:08 -04005902struct MyDrawable : public SkDrawable {
5903 SkRect onGetBounds() override { return SkRect::MakeWH(50, 100); }
5904
5905 void onDraw(SkCanvas* canvas) override {
5906 SkPath path;
5907 path.conicTo(10, 90, 50, 90, 0.9f);
5908 SkPaint paint;
5909 paint.setColor(SK_ColorBLUE);
5910 canvas->drawRect(path.getBounds(), paint);
5911 paint.setAntiAlias(true);
5912 paint.setColor(SK_ColorWHITE);
5913 canvas->drawPath(path, paint);
5914 }
5915};
5916
5917#Function ##
5918void draw(SkCanvas* canvas) {
5919 sk_sp<SkDrawable> drawable(new MyDrawable);
5920 SkMatrix matrix;
5921 matrix.setTranslate(10, 10);
5922 canvas->drawDrawable(drawable.get(), &matrix);
Cary Clark8032b982017-07-28 11:04:54 -04005923}
5924##
5925
5926#ToDo incomplete ##
5927
5928##
5929
5930# ------------------------------------------------------------------------------
5931
5932#Method void drawDrawable(SkDrawable* drawable, SkScalar x, SkScalar y)
5933
5934Draw Drawable drawable using Clip and Matrix, offset by (x, y).
5935
5936If Canvas has an asynchronous implementation, as is the case
5937when it is recording into Picture, then drawable will be referenced,
5938so that SkDrawable::draw() can be called when the operation is finalized. To force
5939immediate drawing, call SkDrawable::draw() instead.
5940
Cary Clarkbad5ad72017-08-03 17:14:08 -04005941#Param drawable custom struct encapsulating drawing commands ##
5942#Param x offset into Canvas writable pixels in x ##
5943#Param y offset into Canvas writable pixels in y ##
Cary Clark8032b982017-07-28 11:04:54 -04005944
5945#Example
5946#Height 100
5947#Function
Cary Clarkbad5ad72017-08-03 17:14:08 -04005948struct MyDrawable : public SkDrawable {
5949 SkRect onGetBounds() override { return SkRect::MakeWH(50, 100); }
5950
5951 void onDraw(SkCanvas* canvas) override {
5952 SkPath path;
5953 path.conicTo(10, 90, 50, 90, 0.9f);
5954 SkPaint paint;
5955 paint.setColor(SK_ColorBLUE);
5956 canvas->drawRect(path.getBounds(), paint);
5957 paint.setAntiAlias(true);
5958 paint.setColor(SK_ColorWHITE);
5959 canvas->drawPath(path, paint);
5960 }
5961};
5962
5963#Function ##
5964void draw(SkCanvas* canvas) {
5965 sk_sp<SkDrawable> drawable(new MyDrawable);
5966 canvas->drawDrawable(drawable.get(), 10, 10);
Cary Clark8032b982017-07-28 11:04:54 -04005967}
5968##
5969
5970#ToDo incomplete ##
5971
5972##
5973
5974# ------------------------------------------------------------------------------
5975
5976#Method void drawAnnotation(const SkRect& rect, const char key[], SkData* value)
5977
5978Associate Rect on Canvas when an annotation; a key-value pair, where the key is
5979a null-terminated utf8 string, and optional value is stored as Data.
5980
5981Only some canvas implementations, such as recording to Picture, or drawing to
5982Document_PDF, use annotations.
5983
Cary Clarkbad5ad72017-08-03 17:14:08 -04005984#Param rect Rect extent of canvas to annotate ##
5985#Param key string used for lookup ##
5986#Param value data holding value stored in annotation ##
Cary Clark8032b982017-07-28 11:04:54 -04005987
5988#Example
5989 #Height 1
5990 const char text[] = "Click this link!";
5991 SkRect bounds;
5992 SkPaint paint;
5993 paint.setTextSize(40);
5994 (void)paint.measureText(text, strlen(text), &bounds);
5995 const char url[] = "https://www.google.com/";
5996 sk_sp<SkData> urlData(SkData::MakeWithCString(url));
5997 canvas->drawAnnotation(bounds, "url_key", urlData.get());
5998##
5999
6000#ToDo incomplete ##
6001
6002##
6003
6004# ------------------------------------------------------------------------------
6005
6006#Method void drawAnnotation(const SkRect& rect, const char key[], const sk_sp<SkData>& value)
6007
6008Associate Rect on Canvas when an annotation; a key-value pair, where the key is
6009a null-terminated utf8 string, and optional value is stored as Data.
6010
6011Only some canvas implementations, such as recording to Picture, or drawing to
6012Document_PDF, use annotations.
6013
Cary Clarkbad5ad72017-08-03 17:14:08 -04006014#Param rect Rect extent of canvas to annotate ##
6015#Param key string used for lookup ##
6016#Param value data holding value stored in annotation ##
Cary Clark8032b982017-07-28 11:04:54 -04006017
6018#Example
6019#Height 1
6020 const char text[] = "Click this link!";
6021 SkRect bounds;
6022 SkPaint paint;
6023 paint.setTextSize(40);
6024 (void)paint.measureText(text, strlen(text), &bounds);
6025 const char url[] = "https://www.google.com/";
6026 sk_sp<SkData> urlData(SkData::MakeWithCString(url));
6027 canvas->drawAnnotation(bounds, "url_key", urlData.get());
6028##
6029
6030#ToDo incomplete ##
6031
6032##
6033
6034#Method SkDrawFilter* getDrawFilter() const
6035
6036Legacy call to be deprecated.
6037
6038#Deprecated
6039##
6040
6041##
6042
6043#Method virtual SkDrawFilter* setDrawFilter(SkDrawFilter* filter)
6044
6045Legacy call to be deprecated.
6046
6047#Deprecated
6048##
6049
6050##
6051
6052# ------------------------------------------------------------------------------
6053
6054#Method virtual bool isClipEmpty() const
6055
6056Returns true if Clip is empty; that is, nothing will draw.
6057
Cary Clarkbad5ad72017-08-03 17:14:08 -04006058May do work when called; it should not be called
Cary Clark8032b982017-07-28 11:04:54 -04006059more often than needed. However, once called, subsequent calls perform no
6060work until Clip changes.
6061
Cary Clarkbad5ad72017-08-03 17:14:08 -04006062#Return true if Clip is empty ##
Cary Clark8032b982017-07-28 11:04:54 -04006063
6064#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04006065 void draw(SkCanvas* canvas) {
6066 SkDebugf("clip is%s empty\n", canvas->isClipEmpty() ? "" : " not");
6067 SkPath path;
6068 canvas->clipPath(path);
6069 SkDebugf("clip is%s empty\n", canvas->isClipEmpty() ? "" : " not");
Cary Clark8032b982017-07-28 11:04:54 -04006070 }
6071 #StdOut
Cary Clarkbad5ad72017-08-03 17:14:08 -04006072 clip is not empty
Cary Clark8032b982017-07-28 11:04:54 -04006073 clip is empty
6074 ##
6075##
6076
6077#ToDo incomplete ##
6078
6079##
6080
6081# ------------------------------------------------------------------------------
6082
6083#Method virtual bool isClipRect() const
6084
6085Returns true if Clip is Rect and not empty.
6086Returns false if the clip is empty, or if it is not Rect.
6087
Cary Clarkbad5ad72017-08-03 17:14:08 -04006088#Return true if Clip is Rect and not empty ##
Cary Clark8032b982017-07-28 11:04:54 -04006089
6090#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04006091 void draw(SkCanvas* canvas) {
6092 SkDebugf("clip is%s rect\n", canvas->isClipRect() ? "" : " not");
6093 canvas->clipRect({0, 0, 0, 0});
6094 SkDebugf("clip is%s rect\n", canvas->isClipRect() ? "" : " not");
Cary Clark8032b982017-07-28 11:04:54 -04006095 }
6096 #StdOut
Cary Clarkbad5ad72017-08-03 17:14:08 -04006097 clip is rect
Cary Clark8032b982017-07-28 11:04:54 -04006098 clip is not rect
6099 ##
6100##
6101
6102#ToDo incomplete ##
6103
6104##
6105
6106#Class SkCanvas ##
Cary Clark884dd7d2017-10-11 10:37:52 -04006107
6108#Class SkAutoCanvasRestore
6109
6110Stack helper class calls SkCanvas::restoreToCount() when SkAutoCanvasRestore
6111goes out of scope. Use this to guarantee that the canvas is restored to a known
6112state.
6113
6114#Method SkAutoCanvasRestore(SkCanvas* canvas, bool doSave)
6115
6116Preserves Canvas save count. Optionally saves Canvas Clip and Matrix.
6117
6118#Param canvas Canvas to guard ##
6119#Param doSave call SkCanvas::save() ##
6120
6121#Return utility to restore Canvas state on destructor ##
6122
6123#Example
6124// incomplete
6125##
6126
6127#SeeAlso SkCanvas::save SkCanvas::restore
6128
6129##
6130
6131#Method ~SkAutoCanvasRestore()
6132
6133Restores Canvas to saved state.
6134
6135#Example
6136// incomplete
6137##
6138
6139#SeeAlso SkCanvas::save SkCanvas::restore
6140
6141##
6142
6143#Method void restore()
6144
6145Restores Canvas to saved state immediately. Subsequent calls and class
6146destructor have no effect.
6147
6148#Example
6149// incomplete
6150##
6151
6152#SeeAlso SkCanvas::save SkCanvas::restore
6153
6154##
6155
6156#Class SkAutoCanvasRestore ##
6157
Cary Clark8032b982017-07-28 11:04:54 -04006158#Topic Canvas ##