blob: aec76107395920a89361db98595cda834b0205ba [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. ##
Cary Clark8032b982017-07-28 11:04:54 -040076#Table ##
77#Subtopic ##
78
79#Subtopic Member_Functions
80#Table
81#Legend
82# function # description ##
83#Legend ##
84# accessTopLayerPixels # Returns writable pixel access if available. ##
85# accessTopRasterHandle # Returns context that tracks Clip and Matrix. ##
86# clear() # Fills Clip with Color. ##
87# clipPath # Combines Clip with Path. ##
88# clipRRect # Combines Clip with Round_Rect. ##
89# clipRect # Combines Clip with Rect. ##
90# clipRegion # Combines Clip with Region. ##
91# concat() # Multiplies Matrix by Matrix. ##
92# discard() # Makes Canvas contents undefined. ##
93# drawAnnotation # Associates a Rect with a key-value pair.##
94# drawArc # Draws Arc using Clip, Matrix, and Paint.##
95# drawAtlas # Draws sprites using Clip, Matrix, and Paint.##
96# drawBitmap # Draws Bitmap at (x, y) position. ##
Cary Clarkd0530ba2017-09-14 11:25:39 -040097# drawBitmapLattice # Draws proportionally stretched Bitmap. ##
Cary Clark8032b982017-07-28 11:04:54 -040098# drawBitmapNine # Draws Nine_Patch Bitmap. ##
99# drawBitmapRect # Draws Bitmap, source Rect to destination Rect. ##
100# drawCircle # Draws Circle using Clip, Matrix, and Paint. ##
101# drawColor # Fills Clip with Color and Blend_Mode. ##
102# drawDRRect # Draws double Round_Rect stroked or filled. ##
103# drawDrawable # Draws Drawable, encapsulated drawing commands. ##
104# drawIRect # Draws IRect using Clip, Matrix, and Paint. ##
105# drawImage # Draws Image at (x, y) position. ##
Cary Clarkd0530ba2017-09-14 11:25:39 -0400106# drawImageLattice # Draws proportionally stretched Image. ##
Cary Clark8032b982017-07-28 11:04:54 -0400107# drawImageNine # Draws Nine_Patch Image. ##
108# drawImageRect # Draws Image, source Rect to destination Rect. ##
109# drawLine # Draws line segment between two points.##
110# drawOval # Draws Oval using Clip, Matrix, and Paint. ##
111# drawPaint # Fills Clip with Paint. ##
Cary Clarkce101242017-09-01 15:51:02 -0400112# drawPatch # Draws Coons patch. ##
Cary Clark8032b982017-07-28 11:04:54 -0400113# drawPath # Draws Path using Clip, Matrix, and Paint. ##
114# drawPicture # Draws Picture using Clip and Matrix. ##
115# drawPoint # Draws point at (x, y) position. ##
116# drawPoints # Draws array as points, lines, polygon. ##
117# drawPosText # Draws text at array of (x, y) positions. ##
118# drawPosTextH # Draws text at x positions with common baseline. ##
119# drawRRect # Draws Round_Rect using Clip, Matrix, and Paint. ##
120# drawRect # Draws Rect using Clip, Matrix, and Paint. ##
121# drawRegion # Draws Region using Clip, Matrix, and Paint. ##
122# drawRoundRect # Draws Round_Rect using Clip, Matrix, and Paint. ##
123# drawText # Draws text at (x, y), using font advance. ##
124# drawTextBlob # Draws text with arrays of positions and Paint. ##
125# drawTextOnPath # Draws text following Path contour. ##
126# drawTextOnPathHV # Draws text following Path with offsets. ##
127# drawTextRSXform # Draws text with array of RSXform. ##
128# drawString # Draws null terminated string at (x, y) using font advance. ##
129# drawVertices # Draws Vertices, a triangle mesh. ##
130# flush() # Triggers execution of all pending draw operations. ##
Cary Clarkce101242017-09-01 15:51:02 -0400131# getBaseLayerSize # Gets size of base Layer in global coordinates. ##
Cary Clark8032b982017-07-28 11:04:54 -0400132# getDeviceClipBounds # Returns IRect bounds of Clip. ##
133# getDrawFilter # Legacy; to be deprecated. ##
134# getGrContext # Returns GPU_Context of the GPU_Surface. ##
135# getLocalClipBounds # Returns Clip bounds in source coordinates. ##
136# getMetaData # Associates additional data with the canvas. ##
137# getProps # Copies Surface_Properties if available. ##
138# getSaveCount # Returns depth of stack containing Clip and Matrix. ##
139# getTotalMatrix # Returns Matrix. ##
140# imageInfo # Returns Image_Info for Canvas. ##
141# isClipEmpty # Returns if Clip is empty. ##
142# isClipRect # Returns if Clip is Rect and not empty. ##
143# MakeRasterDirect # Creates Canvas from SkImageInfo and pixel data. ##
144# MakeRasterDirectN32 # Creates Canvas from image specifications and pixel data. ##
145# makeSurface # Creates Surface matching SkImageInfo and SkSurfaceProps. ##
146# peekPixels # Returns if Canvas has direct access to its pixels. ##
147# quickReject # Returns if Rect is outside Clip. ##
148# readPixels # Copies and converts rectangle of pixels from Canvas. ##
149# resetMatrix # Resets Matrix to identity. ##
150# restore() # Restores changes to Clip and Matrix, pops save stack. ##
151# restoreToCount # Restores changes to Clip and Matrix to given depth. ##
152# rotate() # Rotates Matrix. ##
153# save() # Saves Clip and Matrix on stack. ##
Cary Clarkce101242017-09-01 15:51:02 -0400154# saveLayer # Saves Clip and Matrix on stack; creates Layer. ##
155# saveLayerAlpha # Saves Clip and Matrix on stack; creates Layer; sets opacity. ##
156# saveLayerPreserveLCDTextRequests # Saves Clip and Matrix on stack; creates Layer for LCD text. ##
Cary Clark8032b982017-07-28 11:04:54 -0400157# scale() # Scales Matrix. ##
158# setAllowSimplifyClip # Experimental. ##
159# setDrawFilter # Legacy; to be deprecated. ##
160# setMatrix # Sets Matrix. ##
161# skew() # Skews Matrix. #
162# translate() # Translates Matrix. ##
163# writePixels # Copies and converts rectangle of pixels to Canvas. ##
164#Table ##
165#Subtopic ##
166
167#Topic Overview ##
168
169# ------------------------------------------------------------------------------
170
171#Method static std::unique_ptr<SkCanvas> MakeRasterDirect(const SkImageInfo& info,
172 void* pixels, size_t rowBytes)
173
Cary Clarkbad5ad72017-08-03 17:14:08 -0400174Allocates raster Canvas that will draw directly into pixels.
Cary Clark8032b982017-07-28 11:04:54 -0400175To access pixels after drawing, call flush() or peekPixels.
176
Cary Clarkbad5ad72017-08-03 17:14:08 -0400177Canvas is returned if all parameters are valid.
178Valid parameters include:
179info dimensions are zero or positive;
180info contains Image_Color_Type and Image_Alpha_Type supported by Raster_Surface;
181pixels is not nullptr;
182rowBytes is zero or large enough to contain info width pixels of Image_Color_Type.
183
Cary Clarkf05bdda2017-08-24 12:59:48 -0400184Pass zero for rowBytes to compute rowBytes from info width and size of pixel.
185If rowBytes is greater than zero, it must be equal to or greater than
186info width times bytes required for Image_Color_Type.
187
188Pixel buffer size should be info height times computed rowBytes.
Cary Clarkbad5ad72017-08-03 17:14:08 -0400189
190#Param info width, height, Image_Color_Type, Image_Alpha_Type, Color_Space, of Raster_Surface;
191 width, or height, or both, may be zero
Cary Clark8032b982017-07-28 11:04:54 -0400192##
Cary Clarkf05bdda2017-08-24 12:59:48 -0400193#Param pixels pointer to destination pixels buffer
Cary Clark8032b982017-07-28 11:04:54 -0400194##
Cary Clarkf05bdda2017-08-24 12:59:48 -0400195#Param rowBytes interval from one Surface row to the next, or zero
Cary Clark8032b982017-07-28 11:04:54 -0400196##
197
Cary Clarkbad5ad72017-08-03 17:14:08 -0400198#Return Canvas if all parameters are valid; otherwise, nullptr ##
Cary Clark8032b982017-07-28 11:04:54 -0400199
200#Example
201 #Description
202 Allocates a three by three bitmap, clears it to white, and draws a black pixel
203 in the center.
204 ##
Cary Clarkbad5ad72017-08-03 17:14:08 -0400205void draw(SkCanvas* ) {
Cary Clarkce101242017-09-01 15:51:02 -0400206 SkImageInfo info = SkImageInfo::MakeN32Premul(3, 3); // device aligned, 32 bpp, Premultiplied
Cary Clarkbad5ad72017-08-03 17:14:08 -0400207 const size_t minRowBytes = info.minRowBytes(); // bytes used by one bitmap row
208 const size_t size = info.getSafeSize(minRowBytes); // bytes used by all rows
209 SkAutoTMalloc<SkPMColor> storage(size); // allocate storage for pixels
210 SkPMColor* pixels = storage.get(); // get pointer to allocated storage
211 // create a SkCanvas backed by a raster device, and delete it when the
212 // function goes out of scope.
213 std::unique_ptr<SkCanvas> canvas = SkCanvas::MakeRasterDirect(info, pixels, minRowBytes);
Cary Clarkce101242017-09-01 15:51:02 -0400214 canvas->clear(SK_ColorWHITE); // white is Unpremultiplied, in ARGB order
Cary Clarkbad5ad72017-08-03 17:14:08 -0400215 canvas->flush(); // ensure that pixels are cleared
Cary Clarkce101242017-09-01 15:51:02 -0400216 SkPMColor pmWhite = pixels[0]; // the Premultiplied format may vary
Cary Clarkbad5ad72017-08-03 17:14:08 -0400217 SkPaint paint; // by default, draws black
218 canvas->drawPoint(1, 1, paint); // draw in the center
219 canvas->flush(); // ensure that point was drawn
220 for (int y = 0; y < info.height(); ++y) {
221 for (int x = 0; x < info.width(); ++x) {
222 SkDebugf("%c", *pixels++ == pmWhite ? '-' : 'x');
223 }
224 SkDebugf("\n");
225 }
Cary Clark8032b982017-07-28 11:04:54 -0400226}
227 #StdOut
228 ---
229 -x-
230 ---
231 ##
232##
233
Cary Clark8032b982017-07-28 11:04:54 -0400234#SeeAlso MakeRasterDirectN32 SkSurface::MakeRasterDirect
Cary Clark2ade9972017-11-02 17:49:34 -0400235
Cary Clark8032b982017-07-28 11:04:54 -0400236##
237
238# ------------------------------------------------------------------------------
239
240#Method static std::unique_ptr<SkCanvas> MakeRasterDirectN32(int width, int height, SkPMColor* pixels,
241 size_t rowBytes)
242
Cary Clarkbad5ad72017-08-03 17:14:08 -0400243Allocates raster Canvas specified by inline image specification. Subsequent Canvas
244calls draw into pixels.
Cary Clark8032b982017-07-28 11:04:54 -0400245Image_Color_Type is set to kN32_SkColorType.
246Image_Alpha_Type is set to kPremul_SkAlphaType.
247To access pixels after drawing, call flush() or peekPixels.
248
Cary Clarkbad5ad72017-08-03 17:14:08 -0400249Canvas is returned if all parameters are valid.
250Valid parameters include:
Cary Clarkf05bdda2017-08-24 12:59:48 -0400251width and height are zero or positive;
Cary Clarkbad5ad72017-08-03 17:14:08 -0400252pixels is not nullptr;
Cary Clarkf05bdda2017-08-24 12:59:48 -0400253rowBytes is zero or large enough to contain width pixels of kN32_SkColorType.
Cary Clarkbad5ad72017-08-03 17:14:08 -0400254
Cary Clarkce101242017-09-01 15:51:02 -0400255Pass zero for rowBytes to compute rowBytes from width and size of pixel.
Cary Clarkf05bdda2017-08-24 12:59:48 -0400256If rowBytes is greater than zero, it must be equal to or greater than
257width times bytes required for Image_Color_Type.
258
259Pixel buffer size should be height times rowBytes.
Cary Clarkbad5ad72017-08-03 17:14:08 -0400260
261#Param width pixel column count on Raster_Surface created; must be zero or greater ##
Cary Clarkbc5697d2017-10-04 14:31:33 -0400262#Param height pixel row count on Raster_Surface created; must be zero or greater ##
Cary Clarkbad5ad72017-08-03 17:14:08 -0400263#Param pixels pointer to destination pixels buffer; buffer size should be height
Cary Clarkf05bdda2017-08-24 12:59:48 -0400264 times rowBytes
Cary Clark8032b982017-07-28 11:04:54 -0400265##
Cary Clarkf05bdda2017-08-24 12:59:48 -0400266#Param rowBytes interval from one Surface row to the next, or zero
Cary Clark8032b982017-07-28 11:04:54 -0400267##
268
Cary Clarkbad5ad72017-08-03 17:14:08 -0400269#Return Canvas if all parameters are valid; otherwise, nullptr ##
Cary Clark8032b982017-07-28 11:04:54 -0400270
271#Example
272 #Description
273 Allocates a three by three bitmap, clears it to white, and draws a black pixel
274 in the center.
275 ##
276void draw(SkCanvas* ) {
277 const int width = 3;
278 const int height = 3;
Cary Clarkce101242017-09-01 15:51:02 -0400279 SkPMColor pixels[height][width]; // allocate a 3x3 Premultiplied bitmap on the stack
Cary Clark8032b982017-07-28 11:04:54 -0400280 // create a SkCanvas backed by a raster device, and delete it when the
281 // function goes out of scope.
282 std::unique_ptr<SkCanvas> canvas = SkCanvas::MakeRasterDirectN32(
283 width,
284 height,
Cary Clarkbc5697d2017-10-04 14:31:33 -0400285 pixels[0], // top-left of the bitmap
Cary Clark8032b982017-07-28 11:04:54 -0400286 sizeof(pixels[0])); // byte width of the each row
Cary Clarkce101242017-09-01 15:51:02 -0400287 // write a premultiplied value for white into all pixels in the bitmap
Cary Clark8032b982017-07-28 11:04:54 -0400288 canvas->clear(SK_ColorWHITE);
Cary Clarkce101242017-09-01 15:51:02 -0400289 SkPMColor pmWhite = pixels[0][0]; // the Premultiplied format may vary
Cary Clark8032b982017-07-28 11:04:54 -0400290 SkPaint paint; // by default, draws black
291 canvas->drawPoint(1, 1, paint); // draw in the center
292 canvas->flush(); // ensure that pixels is ready to be read
293 for (int y = 0; y < height; ++y) {
294 for (int x = 0; x < width; ++x) {
295 SkDebugf("%c", pixels[y][x] == pmWhite ? '-' : 'x');
296 }
297 SkDebugf("\n");
298 }
299}
300 #StdOut
301 ---
302 -x-
303 ---
304 ##
305##
306
Cary Clark2ade9972017-11-02 17:49:34 -0400307#SeeAlso MakeRasterDirect SkSurface::MakeRasterDirect SkImageInfo::MakeN32Premul
Cary Clark8032b982017-07-28 11:04:54 -0400308
309##
310
311# ------------------------------------------------------------------------------
312
313#Method SkCanvas()
314
Cary Clarkd0530ba2017-09-14 11:25:39 -0400315Creates an empty Canvas with no backing device or pixels, with
Cary Clarkf05bdda2017-08-24 12:59:48 -0400316a width and height of zero.
Cary Clark8032b982017-07-28 11:04:54 -0400317
Cary Clarkd0530ba2017-09-14 11:25:39 -0400318#Return empty Canvas ##
Cary Clark8032b982017-07-28 11:04:54 -0400319
320#Example
321
322#Description
323Passes a placeholder to a function that requires one.
324##
325
326#Function
Cary Clarkbad5ad72017-08-03 17:14:08 -0400327// Returns true if either the canvas rotates the text by 90 degrees, or the paint does.
328static void check_for_up_and_down_text(const SkCanvas* canvas, const SkPaint& paint) {
329 bool paintHasVertical = paint.isVerticalText();
330 const SkMatrix& matrix = canvas->getTotalMatrix();
331 bool matrixIsVertical = matrix.preservesRightAngles() && !matrix.isScaleTranslate();
332 SkDebugf("paint draws text %s\n", paintHasVertical != matrixIsVertical ?
333 "top to bottom" : "left to right");
334}
335
336static void check_for_up_and_down_text(const SkPaint& paint) {
337 SkCanvas canvas; // placeholder only, does not have an associated device
338 check_for_up_and_down_text(&canvas, paint);
339}
340
Cary Clark8032b982017-07-28 11:04:54 -0400341##
Cary Clarkbad5ad72017-08-03 17:14:08 -0400342void draw(SkCanvas* canvas) {
343 SkPaint paint;
344 check_for_up_and_down_text(paint); // paint draws text left to right
345 paint.setVerticalText(true);
346 check_for_up_and_down_text(paint); // paint draws text top to bottom
347 paint.setVerticalText(false);
348 canvas->rotate(90);
349 check_for_up_and_down_text(canvas, paint); // paint draws text top to bottom
350}
Cary Clark8032b982017-07-28 11:04:54 -0400351
352 #StdOut
353 paint draws text left to right
354 paint draws text top to bottom
355 paint draws text top to bottom
356 ##
357##
358
Cary Clark2ade9972017-11-02 17:49:34 -0400359#SeeAlso MakeRasterDirect SkRasterHandleAllocator::MakeCanvas SkSurface::getCanvas SkCreateColorSpaceXformCanvas
Cary Clark8032b982017-07-28 11:04:54 -0400360
361##
362
363# ------------------------------------------------------------------------------
364
Cary Clark73fa9722017-08-29 17:36:51 -0400365#Method SkCanvas(int width, int height, const SkSurfaceProps* props = nullptr)
Cary Clark8032b982017-07-28 11:04:54 -0400366
367Creates Canvas of the specified dimensions without a Surface.
Cary Clarkce101242017-09-01 15:51:02 -0400368Used by Subclasses with custom implementations for draw methods.
Cary Clark8032b982017-07-28 11:04:54 -0400369
Cary Clarkd0530ba2017-09-14 11:25:39 -0400370If props equals nullptr, Surface_Properties are created with
371Surface_Properties_Legacy_Font_Host settings, which choose the pixel striping
372direction and order. Since a platform may dynamically change its direction when
373the device is rotated, and since a platform may have multiple monitors with
374different characteristics, it is best not to rely on this legacy behavior.
Cary Clark8032b982017-07-28 11:04:54 -0400375
Cary Clarkbad5ad72017-08-03 17:14:08 -0400376#Param width zero or greater ##
377#Param height zero or greater ##
378#Param props LCD striping orientation and setting for device independent fonts;
379 may be nullptr
380##
381
382#Return Canvas placeholder with dimensions ##
Cary Clark8032b982017-07-28 11:04:54 -0400383
384#Example
385 SkCanvas canvas(10, 20); // 10 units wide, 20 units high
386 canvas.clipRect(SkRect::MakeXYWH(30, 40, 5, 10)); // clip is outside canvas' device
387 SkDebugf("canvas %s empty\n", canvas.getDeviceClipBounds().isEmpty() ? "is" : "is not");
388
389 #StdOut
390 canvas is empty
391 ##
392##
393
Cary Clark2ade9972017-11-02 17:49:34 -0400394#SeeAlso MakeRasterDirect SkSurfaceProps SkPixelGeometry SkCreateColorSpaceXformCanvas
Cary Clark8032b982017-07-28 11:04:54 -0400395
396##
397
398# ------------------------------------------------------------------------------
399
400#Method explicit SkCanvas(SkBaseDevice* device)
401
402Construct a canvas that draws into device.
403Used by child classes of SkCanvas.
404
405#ToDo Since SkBaseDevice is private, shouldn't this be private also? ##
406
Cary Clarkbad5ad72017-08-03 17:14:08 -0400407#Param device specifies a device for the canvas to draw into ##
Cary Clark8032b982017-07-28 11:04:54 -0400408
Cary Clarkbad5ad72017-08-03 17:14:08 -0400409#Return Canvas that can be used to draw into device ##
Cary Clark8032b982017-07-28 11:04:54 -0400410
411#Example
412#Error "Unsure how to create a meaningful example."
413 SkPDFCanvas::SkPDFCanvas(const sk_sp<SkPDFDevice>& dev)
414 : SkCanvas(dev.get()) {}
415##
416
Cary Clark2ade9972017-11-02 17:49:34 -0400417#ToDo either remove doc or figure out a way to fiddle it ##
418
419#SeeAlso MakeRasterDirect SkRasterHandleAllocator::MakeCanvas SkSurface::getCanvas SkCreateColorSpaceXformCanvas
Cary Clark8032b982017-07-28 11:04:54 -0400420
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
Cary Clark2ade9972017-11-02 17:49:34 -0400482#SeeAlso MakeRasterDirect SkRasterHandleAllocator::MakeCanvas SkSurface::getCanvas SkCreateColorSpaceXformCanvas
Cary Clark8032b982017-07-28 11:04:54 -0400483
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
Cary Clark2ade9972017-11-02 17:49:34 -0400574#SeeAlso MakeRasterDirect SkRasterHandleAllocator::MakeCanvas SkSurface::getCanvas SkCreateColorSpaceXformCanvas
Cary Clark8032b982017-07-28 11:04:54 -0400575
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
Cary Clark2ade9972017-11-02 17:49:34 -0400639#SeeAlso SkMetaData
Cary Clark8032b982017-07-28 11:04:54 -0400640
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
Cary Clark2ade9972017-11-02 17:49:34 -0400663#SeeAlso SkImageInfo MakeRasterDirect makeSurface
Cary Clark8032b982017-07-28 11:04:54 -0400664
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
Cary Clark2ade9972017-11-02 17:49:34 -0400697#SeeAlso SkSurfaceProps makeSurface
Cary Clark8032b982017-07-28 11:04:54 -0400698
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 Clark2ade9972017-11-02 17:49:34 -0400707If Canvas is associated with Raster_Surface, has no effect; raster draw
708operations are never deferred.
709
710#ToDo
711In an overview section on managing the GPU, include:
712- flush should never change what is drawn
713- call to kick off gpu work
714- calling too much impacts performance
715- some calls (peekPixels, prepareForExternalIO) call it internally
716- canvas call is local, GrContext::flush is global
717- diffentiate between flush, flushAndSignalSemaphores
718- normally never needs to be called
719- call it when sharing gpu resources, feeling memory pressure, swapping out app, and before
720 abandoning context
721- also call to say "I'm finished drawing here", e.g., when drawing to a GPU-backed offscreen surface
722 (created with SkSurface::MakeRenderTarget)
723
724for posterity: this doesn't show a difference: fiddle.skia.org/c/@flushfail
725##
Cary Clark8032b982017-07-28 11:04:54 -0400726
727#Example
728#Error "haven't thought of a useful example to put here"
729##
730
Cary Clark2ade9972017-11-02 17:49:34 -0400731#SeeAlso peekPixels SkSurface::flush() GrContext::flush() SkSurface::prepareForExternalIO GrContext::abandonContext()
Cary Clark8032b982017-07-28 11:04:54 -0400732
733##
734
735# ------------------------------------------------------------------------------
736
737#Method virtual SkISize getBaseLayerSize() const
738
Cary Clarkce101242017-09-01 15:51:02 -0400739Gets the size of the base or root Layer in global canvas coordinates. The
740origin of the base Layer is always (0,0). The area available for drawing may be
Cary Clark8032b982017-07-28 11:04:54 -0400741smaller (due to clipping or saveLayer).
742
Cary Clarkce101242017-09-01 15:51:02 -0400743#Return integral width and height of base Layer ##
Cary Clark8032b982017-07-28 11:04:54 -0400744
745#Example
746 SkBitmap bitmap;
747 bitmap.allocPixels(SkImageInfo::MakeN32Premul(20, 30));
748 SkCanvas canvas(bitmap, SkSurfaceProps(0, kUnknown_SkPixelGeometry));
749 canvas.clipRect(SkRect::MakeWH(10, 40));
750 SkIRect clipDeviceBounds = canvas.getDeviceClipBounds();
751 if (clipDeviceBounds.isEmpty()) {
752 SkDebugf("Empty clip bounds is unexpected!\n");
753 }
754 SkDebugf("clip=%d,%d\n", clipDeviceBounds.width(), clipDeviceBounds.height());
755 SkISize baseLayerSize = canvas.getBaseLayerSize();
756 SkDebugf("size=%d,%d\n", baseLayerSize.width(), baseLayerSize.height());
757
758 #StdOut
759 clip=10,30
760 size=20,30
761 ##
762##
763
764#ToDo is this the same as the width and height of surface? ##
765
Cary Clark2ade9972017-11-02 17:49:34 -0400766#SeeAlso getDeviceClipBounds
767
Cary Clark8032b982017-07-28 11:04:54 -0400768##
769
770# ------------------------------------------------------------------------------
771
772#Method sk_sp<SkSurface> makeSurface(const SkImageInfo& info, const SkSurfaceProps* props = nullptr)
773
774Creates Surface matching info and props, and associates it with Canvas.
Cary Clarkbad5ad72017-08-03 17:14:08 -0400775Returns nullptr if no match found.
Cary Clark8032b982017-07-28 11:04:54 -0400776
Cary Clarkbad5ad72017-08-03 17:14:08 -0400777If props is nullptr, matches Surface_Properties in Canvas. If props is nullptr and Canvas
778does not have Surface_Properties, creates Surface with default Surface_Properties.
Cary Clark8032b982017-07-28 11:04:54 -0400779
Cary Clarkbad5ad72017-08-03 17:14:08 -0400780#Param info width, height, Image_Color_Type, Image_Alpha_Type, and Color_Space ##
781#Param props Surface_Properties to match; may be nullptr to match Canvas ##
782
783#Return Surface matching info and props, or nullptr if no match is available ##
Cary Clark8032b982017-07-28 11:04:54 -0400784
785#Example
786 sk_sp<SkSurface> surface = SkSurface::MakeRasterN32Premul(5, 6);
787 SkCanvas* smallCanvas = surface->getCanvas();
788 SkImageInfo imageInfo = SkImageInfo::MakeN32Premul(3, 4);
789 sk_sp<SkSurface> compatible = smallCanvas->makeSurface(imageInfo);
790 SkDebugf("compatible %c= nullptr\n", compatible == nullptr ? '=' : '!');
791 SkDebugf("size = %d, %d\n", compatible->width(), compatible->height());
792
793 #StdOut
Cary Clarkbad5ad72017-08-03 17:14:08 -0400794 compatible != nullptr
Cary Clark8032b982017-07-28 11:04:54 -0400795 size = 3, 4
796 ##
797##
798
Cary Clark2ade9972017-11-02 17:49:34 -0400799#SeeAlso SkSurface SkSurface::makeSurface SkImageInfo SkSurfaceProps
Cary Clark8032b982017-07-28 11:04:54 -0400800
801##
802
803# ------------------------------------------------------------------------------
804
805#Method virtual GrContext* getGrContext()
806
807Returns GPU_Context of the GPU_Surface associated with Canvas.
808
Cary Clarkbad5ad72017-08-03 17:14:08 -0400809#Return GPU_Context, if available; nullptr otherwise ##
Cary Clark8032b982017-07-28 11:04:54 -0400810
811#Example
812void draw(SkCanvas* canvas) {
813 if (canvas->getGrContext()) {
814 canvas->clear(SK_ColorRED);
815 } else {
816 canvas->clear(SK_ColorBLUE);
817 }
818}
819##
820
821#ToDo fiddle should show both CPU and GPU out ##
822
Cary Clark2ade9972017-11-02 17:49:34 -0400823#SeeAlso GrContext
824
Cary Clark8032b982017-07-28 11:04:54 -0400825##
826
827# ------------------------------------------------------------------------------
828
Cary Clark73fa9722017-08-29 17:36:51 -0400829#Method void* accessTopLayerPixels(SkImageInfo* info, size_t* rowBytes, SkIPoint* origin = nullptr)
Cary Clark8032b982017-07-28 11:04:54 -0400830
831Returns the pixel base address, Image_Info, rowBytes, and origin if the pixels
Cary Clarkbad5ad72017-08-03 17:14:08 -0400832can be read directly. The returned address is only valid
Cary Clark8032b982017-07-28 11:04:54 -0400833while Canvas is in scope and unchanged. Any Canvas call or Surface call
834may invalidate the returned address and other returned values.
835
836If pixels are inaccessible, info, rowBytes, and origin are unchanged.
837
Cary Clarkbad5ad72017-08-03 17:14:08 -0400838#Param info storage for writable pixels' Image_Info; may be nullptr ##
839#Param rowBytes storage for writable pixels' row bytes; may be nullptr ##
Cary Clarkbc5697d2017-10-04 14:31:33 -0400840#Param origin storage for Canvas top Layer origin, its top-left corner;
Cary Clarkbad5ad72017-08-03 17:14:08 -0400841 may be nullptr
842##
Cary Clark8032b982017-07-28 11:04:54 -0400843
Cary Clarka523d2d2017-08-30 08:58:10 -0400844#Return address of pixels, or nullptr if inaccessible ##
Cary Clark8032b982017-07-28 11:04:54 -0400845
846#Example
847void draw(SkCanvas* canvas) {
848 if (canvas->accessTopLayerPixels(nullptr, nullptr)) {
849 canvas->clear(SK_ColorRED);
850 } else {
851 canvas->clear(SK_ColorBLUE);
852 }
853}
854##
855
856#Example
857#Description
Cary Clarkce101242017-09-01 15:51:02 -0400858Draws "ABC" on the device. Then draws "DEF" in Layer, and reads
859Layer to add a large dotted "DEF". Finally blends Layer with the
Cary Clark8032b982017-07-28 11:04:54 -0400860device.
861
Cary Clarkce101242017-09-01 15:51:02 -0400862The Layer and blended result appear on the CPU and GPU but the large dotted
Cary Clark8032b982017-07-28 11:04:54 -0400863"DEF" appear only on the CPU.
864##
865void draw(SkCanvas* canvas) {
Cary Clarkbad5ad72017-08-03 17:14:08 -0400866 SkPaint paint;
867 paint.setTextSize(100);
868 canvas->drawString("ABC", 20, 160, paint);
869 SkRect layerBounds = SkRect::MakeXYWH(32, 32, 192, 192);
870 canvas->saveLayerAlpha(&layerBounds, 128);
871 canvas->clear(SK_ColorWHITE);
872 canvas->drawString("DEF", 20, 160, paint);
873 SkImageInfo imageInfo;
874 size_t rowBytes;
875 SkIPoint origin;
876 uint32_t* access = (uint32_t*) canvas->accessTopLayerPixels(&imageInfo, &rowBytes, &origin);
877 if (access) {
878 int h = imageInfo.height();
879 int v = imageInfo.width();
880 int rowWords = rowBytes / sizeof(uint32_t);
881 for (int y = 0; y < h; ++y) {
882 int newY = (y - h / 2) * 2 + h / 2;
883 if (newY < 0 || newY >= h) {
884 continue;
885 }
886 for (int x = 0; x < v; ++x) {
887 int newX = (x - v / 2) * 2 + v / 2;
888 if (newX < 0 || newX >= v) {
889 continue;
890 }
891 if (access[y * rowWords + x] == SK_ColorBLACK) {
892 access[newY * rowWords + newX] = SK_ColorGRAY;
893 }
894 }
895 }
896
897 }
Cary Clark8032b982017-07-28 11:04:54 -0400898 canvas->restore();
899}
900##
901
902#ToDo there are no callers of this that I can find. Deprecate? ##
903#ToDo fiddle should show both CPU and GPU out ##
904
Cary Clark2ade9972017-11-02 17:49:34 -0400905#SeeAlso SkImageInfo SkPixmap
906
Cary Clark8032b982017-07-28 11:04:54 -0400907##
908
909# ------------------------------------------------------------------------------
910
911#Method SkRasterHandleAllocator::Handle accessTopRasterHandle() const
912
913Returns custom context that tracks the Matrix and Clip.
914
915Use Raster_Handle_Allocator to blend Skia drawing with custom drawing, typically performed
Cary Clarkbc5697d2017-10-04 14:31:33 -0400916by the host platform user interface. The custom context returned is generated by
Cary Clarkbad5ad72017-08-03 17:14:08 -0400917SkRasterHandleAllocator::MakeCanvas, which creates a custom canvas with raster storage for
Cary Clark8032b982017-07-28 11:04:54 -0400918the drawing destination.
919
Cary Clarkce101242017-09-01 15:51:02 -0400920#Return context of custom allocation ##
Cary Clark8032b982017-07-28 11:04:54 -0400921
922#Example
923#Description
924#ToDo ##
925##
926#Function
927 static void DeleteCallback(void*, void* context) {
928 delete (char*) context;
929 }
930
931 class CustomAllocator : public SkRasterHandleAllocator {
932 public:
933 bool allocHandle(const SkImageInfo& info, Rec* rec) override {
934 char* context = new char[4]{'s', 'k', 'i', 'a'};
935 rec->fReleaseProc = DeleteCallback;
936 rec->fReleaseCtx = context;
937 rec->fHandle = context;
938 rec->fPixels = context;
939 rec->fRowBytes = 4;
940 return true;
941 }
942
943 void updateHandle(Handle handle, const SkMatrix& ctm, const SkIRect& clip_bounds) override {
944 // apply canvas matrix and clip to custom environment
945 }
946 };
947
948##
949 void draw(SkCanvas* canvas) {
950 const SkImageInfo info = SkImageInfo::MakeN32Premul(1, 1);
951 std::unique_ptr<SkCanvas> c2 =
952 SkRasterHandleAllocator::MakeCanvas(std::unique_ptr<CustomAllocator>(
953 new CustomAllocator()), info);
954 char* context = (char*) c2->accessTopRasterHandle();
955 SkDebugf("context = %.4s\n", context);
956
957 }
958 #StdOut
959 context = skia
960 ##
961 #ToDo skstd::make_unique could not be used because def is private -- note to fix in c++14? ##
962##
963
964#SeeAlso SkRasterHandleAllocator
965
966##
967
968# ------------------------------------------------------------------------------
969
970#Method bool peekPixels(SkPixmap* pixmap)
971
972Returns true if Canvas has direct access to its pixels.
973
Cary Clarkf05bdda2017-08-24 12:59:48 -0400974Pixels are readable when Device is raster. Pixels are not readable when Canvas
Cary Clarkbad5ad72017-08-03 17:14:08 -0400975is returned from GPU_Surface, returned by SkDocument::beginPage, returned by
Cary Clarkf05bdda2017-08-24 12:59:48 -0400976SkPictureRecorder::beginRecording, or Canvas is the base of a utility class
Cary Clarkbad5ad72017-08-03 17:14:08 -0400977like SkDumpCanvas.
Cary Clark8032b982017-07-28 11:04:54 -0400978
Cary Clarkf05bdda2017-08-24 12:59:48 -0400979pixmap is valid only while Canvas is in scope and unchanged. Any
Cary Clarkbad5ad72017-08-03 17:14:08 -0400980Canvas or Surface call may invalidate the pixmap values.
Cary Clark8032b982017-07-28 11:04:54 -0400981
Cary Clarkbc5697d2017-10-04 14:31:33 -0400982#Param pixmap storage for pixel state if pixels are readable; otherwise, ignored ##
Cary Clark8032b982017-07-28 11:04:54 -0400983
Cary Clarkbad5ad72017-08-03 17:14:08 -0400984#Return true if Canvas has direct access to pixels ##
Cary Clark8032b982017-07-28 11:04:54 -0400985
986#Example
987 SkPixmap pixmap;
988 if (canvas->peekPixels(&pixmap)) {
989 SkDebugf("width=%d height=%d\n", pixmap.bounds().width(), pixmap.bounds().height());
990 }
991 #StdOut
992 width=256 height=256
993 ##
994##
995
Cary Clark2ade9972017-11-02 17:49:34 -0400996#SeeAlso readPixels SkBitmap::peekPixels SkImage::peekPixels SkSurface::peekPixels
997
Cary Clark8032b982017-07-28 11:04:54 -0400998##
999
1000# ------------------------------------------------------------------------------
1001
1002#Method bool readPixels(const SkImageInfo& dstInfo, void* dstPixels, size_t dstRowBytes,
1003 int srcX, int srcY)
1004
Cary Clark154beea2017-10-26 07:58:48 -04001005Copies Rect of pixels from Canvas into dstPixels. Matrix and Clip are
1006ignored. Source Rect corners are (srcX, srcY) and
1007(imageInfo().width(), imageInfo().height()).
Cary Clark6fc50412017-09-21 12:31:06 -04001008
Cary Clark154beea2017-10-26 07:58:48 -04001009Destination Rect corners are (0, 0) and (bitmap.width(), bitmap.height()).
Cary Clark6fc50412017-09-21 12:31:06 -04001010Copies each readable pixel intersecting both rectangles, without scaling,
Cary Clarkf05bdda2017-08-24 12:59:48 -04001011converting to dstInfo.colorType() and dstInfo.alphaType() if required.
Cary Clark8032b982017-07-28 11:04:54 -04001012
Cary Clarkf05bdda2017-08-24 12:59:48 -04001013Pixels are readable when Device is raster, or backed by a GPU.
1014Pixels are not readable when SkCanvas is returned by SkDocument::beginPage,
1015returned by SkPictureRecorder::beginRecording, or Canvas is the base of a utility
1016class like SkDumpCanvas.
Cary Clark8032b982017-07-28 11:04:54 -04001017
Cary Clarkf05bdda2017-08-24 12:59:48 -04001018The destination pixel storage must be allocated by the caller.
Cary Clark8032b982017-07-28 11:04:54 -04001019
Cary Clarkf05bdda2017-08-24 12:59:48 -04001020Pixel values are converted only if Image_Color_Type and Image_Alpha_Type
1021do not match. Only pixels within both source and destination rectangles
Cary Clark154beea2017-10-26 07:58:48 -04001022are copied. dstPixels contents outside Rect intersection are unchanged.
Cary Clarkf05bdda2017-08-24 12:59:48 -04001023
1024Pass negative values for srcX or srcY to offset pixels across or down destination.
Cary Clark8032b982017-07-28 11:04:54 -04001025
1026Does not copy, and returns false if:
1027
1028#List
Cary Clarkf05bdda2017-08-24 12:59:48 -04001029# Source and destination rectangles do not intersect. ##
1030# Canvas pixels could not be converted to dstInfo.colorType() or dstInfo.alphaType(). ##
1031# Canvas pixels are not readable; for instance, Canvas is document-based. ##
Cary Clark8032b982017-07-28 11:04:54 -04001032# dstRowBytes is too small to contain one row of pixels. ##
1033##
1034
Cary Clarkf05bdda2017-08-24 12:59:48 -04001035#Param dstInfo width, height, Image_Color_Type, and Image_Alpha_Type of dstPixels ##
1036#Param dstPixels storage for pixels; dstInfo.height() times dstRowBytes, or larger ##
1037#Param dstRowBytes size of one destination row; dstInfo.width() times pixel size, or larger ##
1038#Param srcX offset into readable pixels in x; may be negative ##
1039#Param srcY offset into readable pixels in y; may be negative ##
Cary Clark8032b982017-07-28 11:04:54 -04001040
Cary Clarkbad5ad72017-08-03 17:14:08 -04001041#Return true if pixels were copied ##
Cary Clark8032b982017-07-28 11:04:54 -04001042
1043#Example
Cary Clarkf05bdda2017-08-24 12:59:48 -04001044#Width 64
1045#Height 64
1046#Description
1047 A black circle drawn on a blue background provides an image to copy.
1048 readPixels copies one quarter of the canvas into each of the four corners.
Cary Clarkce101242017-09-01 15:51:02 -04001049 The Layer draws over the image.
Cary Clarkf05bdda2017-08-24 12:59:48 -04001050##
1051 canvas->clear(SK_ColorBLUE);
1052 SkPaint paint;
1053 canvas->drawCircle(32, 32, 28, paint);
1054 SkImageInfo info = SkImageInfo::Make(64, 64, kBGRA_8888_SkColorType, kPremul_SkAlphaType);
1055 sk_sp<SkData> data(SkData::MakeUninitialized(info.minRowBytes() * info.height()));
1056 sk_bzero(data->writable_data(), info.minRowBytes() * info.height());
1057 for (int x : { 32, -32 } ) {
1058 for (int y : { 32, -32 } ) {
1059 canvas->readPixels(info, data->writable_data(), info.minRowBytes(), x, y);
1060 }
1061 }
1062 sk_sp<SkImage> image = SkImage::MakeRasterData(info, data, info.minRowBytes());
1063 canvas->drawImage(image, 0, 0);
1064##
1065
1066#Example
Cary Clark8032b982017-07-28 11:04:54 -04001067#Description
Cary Clarkce101242017-09-01 15:51:02 -04001068 Canvas returned by Raster_Surface has Premultiplied pixel values.
1069 clear() takes Unpremultiplied input with Color_Alpha equal 0x80
1070 and Color_RGB equal 0x55, 0xAA, 0xFF. Color_RGB is multiplied by Color_Alpha
1071 to generate Premultiplied value 0x802B5580. readPixels converts pixel back
1072 to Unpremultiplied value 0x8056A9FF, introducing error.
Cary Clark8032b982017-07-28 11:04:54 -04001073##
1074 canvas->clear(0x8055aaff);
1075 for (SkAlphaType alphaType : { kPremul_SkAlphaType, kUnpremul_SkAlphaType } ) {
1076 uint32_t pixel = 0;
1077 SkImageInfo info = SkImageInfo::Make(1, 1, kBGRA_8888_SkColorType, alphaType);
1078 if (canvas->readPixels(info, &pixel, 4, 0, 0)) {
1079 SkDebugf("pixel = %08x\n", pixel);
1080 }
1081 }
1082
1083 #StdOut
1084 pixel = 802b5580
1085 pixel = 8056a9ff
1086 ##
1087##
1088
Cary Clark2ade9972017-11-02 17:49:34 -04001089#SeeAlso peekPixels writePixels drawBitmap drawImage SkBitmap::readPixels SkPixmap::readPixels SkImage::readPixels SkSurface::readPixels
Cary Clark8032b982017-07-28 11:04:54 -04001090
1091##
1092
1093# ------------------------------------------------------------------------------
1094
1095#Method bool readPixels(const SkPixmap& pixmap, int srcX, int srcY)
1096
Cary Clark154beea2017-10-26 07:58:48 -04001097Copies Rect of pixels from Canvas into pixmap. Matrix and Clip are
1098ignored. Source Rect corners are (srcX, srcY) and
1099(imageInfo().width(), imageInfo().height()).
Cary Clark6fc50412017-09-21 12:31:06 -04001100
Cary Clark154beea2017-10-26 07:58:48 -04001101Destination Rect corners are (0, 0) and (bitmap.width(), bitmap.height()).
Cary Clark6fc50412017-09-21 12:31:06 -04001102Copies each readable pixel intersecting both rectangles, without scaling,
Cary Clarkf05bdda2017-08-24 12:59:48 -04001103converting to pixmap.colorType() and pixmap.alphaType() if required.
Cary Clark8032b982017-07-28 11:04:54 -04001104
Cary Clarkf05bdda2017-08-24 12:59:48 -04001105Pixels are readable when Device is raster, or backed by a GPU.
1106Pixels are not readable when SkCanvas is returned by SkDocument::beginPage,
1107returned by SkPictureRecorder::beginRecording, or Canvas is the base of a utility
1108class like SkDumpCanvas.
Cary Clark8032b982017-07-28 11:04:54 -04001109
Cary Clark6fc50412017-09-21 12:31:06 -04001110Caller must allocate pixel storage in pixmap if needed.
Cary Clark8032b982017-07-28 11:04:54 -04001111
Cary Clarkf05bdda2017-08-24 12:59:48 -04001112Pixel values are converted only if Image_Color_Type and Image_Alpha_Type
Cary Clark154beea2017-10-26 07:58:48 -04001113do not match. Only pixels within both source and destination Rects
1114are copied. pixmap pixels contents outside Rect intersection are unchanged.
Cary Clarkf05bdda2017-08-24 12:59:48 -04001115
1116Pass negative values for srcX or srcY to offset pixels across or down pixmap.
Cary Clark8032b982017-07-28 11:04:54 -04001117
1118Does not copy, and returns false if:
1119
1120#List
Cary Clarkf05bdda2017-08-24 12:59:48 -04001121# Source and destination rectangles do not intersect. ##
1122# Canvas pixels could not be converted to pixmap.colorType() or pixmap.alphaType(). ##
1123# Canvas pixels are not readable; for instance, Canvas is document-based. ##
1124# Pixmap pixels could not be allocated. ##
1125# pixmap.rowBytes() is too small to contain one row of pixels. ##
Cary Clark8032b982017-07-28 11:04:54 -04001126##
1127
Cary Clarkbad5ad72017-08-03 17:14:08 -04001128#Param pixmap storage for pixels copied from Canvas ##
Cary Clarkf05bdda2017-08-24 12:59:48 -04001129#Param srcX offset into readable pixels in x; may be negative ##
1130#Param srcY offset into readable pixels in y; may be negative ##
Cary Clark8032b982017-07-28 11:04:54 -04001131
Cary Clarkbad5ad72017-08-03 17:14:08 -04001132#Return true if pixels were copied ##
Cary Clark8032b982017-07-28 11:04:54 -04001133
1134#Example
Cary Clarkf05bdda2017-08-24 12:59:48 -04001135 #Description
Cary Clarkce101242017-09-01 15:51:02 -04001136 clear() takes Unpremultiplied input with Color_Alpha equal 0x80
1137 and Color_RGB equal 0x55, 0xAA, 0xFF. Color_RGB is multiplied by Color_Alpha
1138 to generate Premultiplied value 0x802B5580.
Cary Clarkf05bdda2017-08-24 12:59:48 -04001139 ##
1140 void draw(SkCanvas* canvas) {
1141 canvas->clear(0x8055aaff);
1142 uint32_t pixels[1] = { 0 };
1143 SkPixmap pixmap(SkImageInfo::MakeN32Premul(1, 1), pixels, 4);
1144 canvas->readPixels(pixmap, 0, 0);
1145 SkDebugf("pixel = %08x\n", pixels[0]);
1146 }
Cary Clark8032b982017-07-28 11:04:54 -04001147 #StdOut
1148 pixel = 802b5580
1149 ##
1150##
1151
Cary Clark2ade9972017-11-02 17:49:34 -04001152#SeeAlso peekPixels writePixels drawBitmap drawImage SkBitmap::readPixels SkPixmap::readPixels SkImage::readPixels SkSurface::readPixels
Cary Clark8032b982017-07-28 11:04:54 -04001153
1154##
1155
1156# ------------------------------------------------------------------------------
1157
1158#Method bool readPixels(const SkBitmap& bitmap, int srcX, int srcY)
1159
Cary Clark154beea2017-10-26 07:58:48 -04001160Copies Rect of pixels from Canvas into bitmap. Matrix and Clip are
1161ignored. Source Rect corners are (srcX, srcY) and
1162(imageInfo().width(), imageInfo().height()).
Cary Clark6fc50412017-09-21 12:31:06 -04001163
Cary Clark154beea2017-10-26 07:58:48 -04001164Destination Rect corners are (0, 0) and (bitmap.width(), bitmap.height()).
Cary Clarkf05bdda2017-08-24 12:59:48 -04001165Copies each readable pixel intersecting both rectangles, without scaling,
1166converting to bitmap.colorType() and bitmap.alphaType() if required.
Cary Clark8032b982017-07-28 11:04:54 -04001167
Cary Clarkf05bdda2017-08-24 12:59:48 -04001168Pixels are readable when Device is raster, or backed by a GPU.
1169Pixels are not readable when SkCanvas is returned by SkDocument::beginPage,
1170returned by SkPictureRecorder::beginRecording, or Canvas is the base of a utility
1171class like SkDumpCanvas.
Cary Clark8032b982017-07-28 11:04:54 -04001172
Cary Clark6fc50412017-09-21 12:31:06 -04001173Caller must allocate pixel storage in bitmap if needed.
Cary Clarkf05bdda2017-08-24 12:59:48 -04001174
1175Bitmap values are converted only if Image_Color_Type and Image_Alpha_Type
1176do not match. Only pixels within both source and destination rectangles
Cary Clark154beea2017-10-26 07:58:48 -04001177are copied. Bitmap pixels outside Rect intersection are unchanged.
Cary Clarkf05bdda2017-08-24 12:59:48 -04001178
1179Pass negative values for srcX or srcY to offset pixels across or down bitmap.
Cary Clark8032b982017-07-28 11:04:54 -04001180
1181Does not copy, and returns false if:
1182
1183#List
Cary Clarkf05bdda2017-08-24 12:59:48 -04001184# Source and destination rectangles do not intersect. ##
1185# Canvas pixels could not be converted to bitmap.colorType() or bitmap.alphaType(). ##
1186# Canvas pixels are not readable; for instance, Canvas is document-based. ##
Cary Clark8032b982017-07-28 11:04:54 -04001187# bitmap pixels could not be allocated. ##
Cary Clarkf05bdda2017-08-24 12:59:48 -04001188# bitmap.rowBytes() is too small to contain one row of pixels. ##
Cary Clark8032b982017-07-28 11:04:54 -04001189##
1190
Cary Clarkbad5ad72017-08-03 17:14:08 -04001191#Param bitmap storage for pixels copied from Canvas ##
Cary Clarkf05bdda2017-08-24 12:59:48 -04001192#Param srcX offset into readable pixels in x; may be negative ##
1193#Param srcY offset into readable pixels in y; may be negative ##
Cary Clark8032b982017-07-28 11:04:54 -04001194
Cary Clarkbad5ad72017-08-03 17:14:08 -04001195#Return true if pixels were copied ##
Cary Clark8032b982017-07-28 11:04:54 -04001196
1197#Example
Cary Clarkf05bdda2017-08-24 12:59:48 -04001198 #Description
Cary Clarkce101242017-09-01 15:51:02 -04001199 clear() takes Unpremultiplied input with Color_Alpha equal 0x80
1200 and Color_RGB equal 0x55, 0xAA, 0xFF. Color_RGB is multiplied by Color_Alpha
1201 to generate Premultiplied value 0x802B5580.
Cary Clarkf05bdda2017-08-24 12:59:48 -04001202 ##
Cary Clark8032b982017-07-28 11:04:54 -04001203void draw(SkCanvas* canvas) {
1204 canvas->clear(0x8055aaff);
1205 SkBitmap bitmap;
1206 bitmap.allocPixels(SkImageInfo::MakeN32Premul(1, 1));
1207 canvas->readPixels(bitmap, 0, 0);
1208 SkDebugf("pixel = %08x\n", bitmap.getAddr32(0, 0)[0]);
1209}
1210 #StdOut
1211 pixel = 802b5580
1212 ##
1213##
1214
Cary Clark2ade9972017-11-02 17:49:34 -04001215#SeeAlso peekPixels writePixels drawBitmap drawImage SkBitmap::readPixels SkPixmap::readPixels SkImage::readPixels SkSurface::readPixels
Cary Clark8032b982017-07-28 11:04:54 -04001216
1217##
1218
1219# ------------------------------------------------------------------------------
1220
1221#Method bool writePixels(const SkImageInfo& info, const void* pixels, size_t rowBytes, int x, int y)
1222
Cary Clark154beea2017-10-26 07:58:48 -04001223Copies Rect from pixels to Canvas. Matrix and Clip are ignored.
1224Source Rect corners are (0, 0) and (info.width(), info.height()).
1225Destination Rect corners are (x, y) and
1226(imageInfo().width(), imageInfo().height()).
Cary Clark6fc50412017-09-21 12:31:06 -04001227
1228Copies each readable pixel intersecting both rectangles, without scaling,
Cary Clark154beea2017-10-26 07:58:48 -04001229converting to imageInfo().colorType() and imageInfo().alphaType() if required.
Cary Clark8032b982017-07-28 11:04:54 -04001230
Cary Clarkf05bdda2017-08-24 12:59:48 -04001231Pixels are writable when Device is raster, or backed by a GPU.
1232Pixels are not writable when SkCanvas is returned by SkDocument::beginPage,
1233returned by SkPictureRecorder::beginRecording, or Canvas is the base of a utility
1234class like SkDumpCanvas.
Cary Clark8032b982017-07-28 11:04:54 -04001235
Cary Clarkf05bdda2017-08-24 12:59:48 -04001236Pixel values are converted only if Image_Color_Type and Image_Alpha_Type
1237do not match. Only pixels within both source and destination rectangles
Cary Clark154beea2017-10-26 07:58:48 -04001238are copied. Canvas pixels outside Rect intersection are unchanged.
Cary Clark8032b982017-07-28 11:04:54 -04001239
Cary Clarkf05bdda2017-08-24 12:59:48 -04001240Pass negative values for x or y to offset pixels to the left or
1241above Canvas pixels.
Cary Clark8032b982017-07-28 11:04:54 -04001242
1243Does not copy, and returns false if:
1244
1245#List
Cary Clarkf05bdda2017-08-24 12:59:48 -04001246# Source and destination rectangles do not intersect. ##
Cary Clark154beea2017-10-26 07:58:48 -04001247# pixels could not be converted to this->imageInfo().colorType() or
1248this->imageInfo().alphaType(). ##
Cary Clark8032b982017-07-28 11:04:54 -04001249# Canvas pixels are not writable; for instance, Canvas is document-based. ##
1250# rowBytes is too small to contain one row of pixels. ##
1251##
1252
Cary Clarkf05bdda2017-08-24 12:59:48 -04001253#Param info width, height, Image_Color_Type, and Image_Alpha_Type of pixels ##
1254#Param pixels pixels to copy, of size info.height() times rowBytes, or larger ##
Cary Clarkd0530ba2017-09-14 11:25:39 -04001255#Param rowBytes size of one row of pixels; info.width() times pixel size, or larger ##
Cary Clarkf05bdda2017-08-24 12:59:48 -04001256#Param x offset into Canvas writable pixels in x; may be negative ##
1257#Param y offset into Canvas writable pixels in y; may be negative ##
Cary Clark8032b982017-07-28 11:04:54 -04001258
Cary Clarkbad5ad72017-08-03 17:14:08 -04001259#Return true if pixels were written to Canvas ##
Cary Clark8032b982017-07-28 11:04:54 -04001260
1261#Example
1262 SkImageInfo imageInfo = SkImageInfo::MakeN32(256, 1, kPremul_SkAlphaType);
1263 for (int y = 0; y < 256; ++y) {
1264 uint32_t pixels[256];
1265 for (int x = 0; x < 256; ++x) {
1266 pixels[x] = SkColorSetARGB(x, x + y, x, x - y);
1267 }
1268 canvas->writePixels(imageInfo, &pixels, sizeof(pixels), 0, y);
1269 }
1270##
1271
Cary Clark2ade9972017-11-02 17:49:34 -04001272#SeeAlso readPixels drawBitmap drawImage SkBitmap::writePixels
Cary Clark8032b982017-07-28 11:04:54 -04001273
1274##
1275
1276# ------------------------------------------------------------------------------
1277
1278#Method bool writePixels(const SkBitmap& bitmap, int x, int y)
1279
Cary Clark154beea2017-10-26 07:58:48 -04001280Copies Rect from pixels to Canvas. Matrix and Clip are ignored.
1281Source Rect corners are (0, 0) and (bitmap.width(), bitmap.height()).
Cary Clark6fc50412017-09-21 12:31:06 -04001282
Cary Clark154beea2017-10-26 07:58:48 -04001283Destination Rect corners are (x, y) and
1284(imageInfo().width(), imageInfo().height()).
Cary Clark6fc50412017-09-21 12:31:06 -04001285
1286Copies each readable pixel intersecting both rectangles, without scaling,
Cary Clark154beea2017-10-26 07:58:48 -04001287converting to imageInfo().colorType() and imageInfo().alphaType() if required.
Cary Clark8032b982017-07-28 11:04:54 -04001288
Cary Clarkf05bdda2017-08-24 12:59:48 -04001289Pixels are writable when Device is raster, or backed by a GPU.
1290Pixels are not writable when SkCanvas is returned by SkDocument::beginPage,
1291returned by SkPictureRecorder::beginRecording, or Canvas is the base of a utility
1292class like SkDumpCanvas.
Cary Clark8032b982017-07-28 11:04:54 -04001293
Cary Clarkf05bdda2017-08-24 12:59:48 -04001294Pixel values are converted only if Image_Color_Type and Image_Alpha_Type
1295do not match. Only pixels within both source and destination rectangles
Cary Clark154beea2017-10-26 07:58:48 -04001296are copied. Canvas pixels outside Rect intersection are unchanged.
Cary Clark8032b982017-07-28 11:04:54 -04001297
Cary Clarkf05bdda2017-08-24 12:59:48 -04001298Pass negative values for x or y to offset pixels to the left or
1299above Canvas pixels.
Cary Clark8032b982017-07-28 11:04:54 -04001300
1301Does not copy, and returns false if:
1302
1303#List
Cary Clarkf05bdda2017-08-24 12:59:48 -04001304# Source and destination rectangles do not intersect. ##
Cary Clark8032b982017-07-28 11:04:54 -04001305# bitmap does not have allocated pixels. ##
Cary Clark154beea2017-10-26 07:58:48 -04001306# bitmap pixels could not be converted to this->imageInfo().colorType() or
1307this->imageInfo().alphaType(). ##
Cary Clarkce101242017-09-01 15:51:02 -04001308# Canvas pixels are not writable; for instance, Canvas is document based. ##
Cary Clark8032b982017-07-28 11:04:54 -04001309# bitmap pixels are inaccessible; for instance, bitmap wraps a texture. ##
1310##
1311
Cary Clarkbad5ad72017-08-03 17:14:08 -04001312#Param bitmap contains pixels copied to Canvas ##
Cary Clarkf05bdda2017-08-24 12:59:48 -04001313#Param x offset into Canvas writable pixels in x; may be negative ##
1314#Param y offset into Canvas writable pixels in y; may be negative ##
Cary Clark8032b982017-07-28 11:04:54 -04001315
Cary Clarkbad5ad72017-08-03 17:14:08 -04001316#Return true if pixels were written to Canvas ##
Cary Clark8032b982017-07-28 11:04:54 -04001317
1318#Example
1319void draw(SkCanvas* canvas) {
1320 SkImageInfo imageInfo = SkImageInfo::MakeN32Premul(2, 2);
1321 SkBitmap bitmap;
1322 bitmap.setInfo(imageInfo);
1323 uint32_t pixels[4];
1324 bitmap.setPixels(pixels);
1325 for (int y = 0; y < 256; y += 2) {
1326 for (int x = 0; x < 256; x += 2) {
1327 pixels[0] = SkColorSetRGB(x, y, x | y);
1328 pixels[1] = SkColorSetRGB(x ^ y, y, x);
1329 pixels[2] = SkColorSetRGB(x, x & y, y);
1330 pixels[3] = SkColorSetRGB(~x, ~y, x);
1331 canvas->writePixels(bitmap, x, y);
1332 }
1333 }
1334}
1335##
1336
Cary Clark2ade9972017-11-02 17:49:34 -04001337#SeeAlso readPixels drawBitmap drawImage SkBitmap::writePixels
Cary Clark8032b982017-07-28 11:04:54 -04001338
1339##
1340
1341# ------------------------------------------------------------------------------
1342#Topic State_Stack
1343
1344Canvas maintains a stack of state that allows hierarchical drawing, commonly used
Cary Clarkbad5ad72017-08-03 17:14:08 -04001345to implement windows and views. The initial state has an identity matrix and and
1346an infinite clip. Even with a wide-open clip, drawing is constrained by the
1347bounds of the Canvas Surface or Device.
Cary Clark8032b982017-07-28 11:04:54 -04001348
1349Canvas savable state consists of Clip, Matrix, and Draw_Filter.
1350Clip describes the area that may be drawn to.
1351Matrix transforms the geometry.
1352Draw_Filter (deprecated on most platforms) modifies the paint before drawing.
1353
1354save(), saveLayer, saveLayerPreserveLCDTextRequests, and saveLayerAlpha
1355save state and return the depth of the stack.
1356
Cary Clarkbad5ad72017-08-03 17:14:08 -04001357restore(), restoreToCount, and ~SkCanvas() revert state to its value when saved.
Cary Clark8032b982017-07-28 11:04:54 -04001358
1359Each state on the stack intersects Clip with the previous Clip,
1360and concatenates Matrix with the previous Matrix.
1361The intersected Clip makes the drawing area the same or smaller;
1362the concatenated Matrix may move the origin and potentially scale or rotate
1363the coordinate space.
1364
1365Canvas does not require balancing the state stack but it is a good idea
1366to do so. Calling save() without restore() will eventually cause Skia to fail;
1367mismatched save() and restore() create hard to find bugs.
1368
1369It is not possible to use state to draw outside of the clip defined by the
1370previous state.
1371
1372#Example
1373#Description
1374Draw to ever smaller clips; then restore drawing to full canvas.
1375Note that the second clipRect is not permitted to enlarge Clip.
1376##
1377#Height 160
Cary Clarkbad5ad72017-08-03 17:14:08 -04001378void draw(SkCanvas* canvas) {
1379 SkPaint paint;
1380 canvas->save(); // records stack depth to restore
1381 canvas->clipRect(SkRect::MakeWH(100, 100)); // constrains drawing to clip
1382 canvas->clear(SK_ColorRED); // draws to limit of clip
1383 canvas->save(); // records stack depth to restore
1384 canvas->clipRect(SkRect::MakeWH(50, 150)); // Rect below 100 is ignored
1385 canvas->clear(SK_ColorBLUE); // draws to smaller clip
1386 canvas->restore(); // enlarges clip
1387 canvas->drawLine(20, 20, 150, 150, paint); // line below 100 is not drawn
1388 canvas->restore(); // enlarges clip
1389 canvas->drawLine(150, 20, 50, 120, paint); // line below 100 is drawn
Cary Clark8032b982017-07-28 11:04:54 -04001390}
1391##
1392
1393Each Clip uses the current Matrix for its coordinates.
1394
1395#Example
1396#Description
1397While clipRect is given the same rectangle twice, Matrix makes the second
1398clipRect draw at half the size of the first.
1399##
1400#Height 128
Cary Clarkbad5ad72017-08-03 17:14:08 -04001401void draw(SkCanvas* canvas) {
1402 canvas->clipRect(SkRect::MakeWH(100, 100));
1403 canvas->clear(SK_ColorRED);
1404 canvas->scale(.5, .5);
1405 canvas->clipRect(SkRect::MakeWH(100, 100));
1406 canvas->clear(SK_ColorBLUE);
Cary Clark8032b982017-07-28 11:04:54 -04001407}
1408##
1409
1410#SeeAlso save() saveLayer saveLayerPreserveLCDTextRequests saveLayerAlpha restore() restoreToCount
1411
1412#Method int save()
1413
1414Saves Matrix, Clip, and Draw_Filter (Draw_Filter deprecated on most platforms).
1415Calling restore() discards changes to Matrix, Clip, and Draw_Filter,
1416restoring the Matrix, Clip, and Draw_Filter to their state when save() was called.
1417
Cary Clarkbad5ad72017-08-03 17:14:08 -04001418Matrix may be changed by translate(), scale(), rotate(), skew(), concat(), setMatrix,
1419and resetMatrix. Clip may be changed by clipRect, clipRRect, clipPath, clipRegion.
Cary Clark8032b982017-07-28 11:04:54 -04001420
Cary Clarkbad5ad72017-08-03 17:14:08 -04001421Saved Canvas state is put on a stack; multiple calls to save() should be balance
1422by an equal number of calls to restore().
Cary Clark8032b982017-07-28 11:04:54 -04001423
1424Call restoreToCount with result to restore this and subsequent saves.
1425
Cary Clarkbad5ad72017-08-03 17:14:08 -04001426#Return depth of saved stack ##
Cary Clark8032b982017-07-28 11:04:54 -04001427
1428#Example
1429#Description
1430The black square is translated 50 pixels down and to the right.
1431Restoring Canvas state removes translate() from Canvas stack;
1432the red square is not translated, and is drawn at the origin.
1433##
1434#Height 100
1435void draw(SkCanvas* canvas) {
1436 SkPaint paint;
1437 SkRect rect = { 0, 0, 25, 25 };
1438 canvas->drawRect(rect, paint);
1439 canvas->save();
1440 canvas->translate(50, 50);
1441 canvas->drawRect(rect, paint);
1442 canvas->restore();
1443 paint.setColor(SK_ColorRED);
1444 canvas->drawRect(rect, paint);
1445}
1446##
1447
Cary Clark2ade9972017-11-02 17:49:34 -04001448#SeeAlso saveLayer saveLayerPreserveLCDTextRequests saveLayerAlpha restore() restoreToCount
Cary Clark8032b982017-07-28 11:04:54 -04001449
1450##
1451
1452# ------------------------------------------------------------------------------
Cary Clark8032b982017-07-28 11:04:54 -04001453
1454#Method void restore()
1455
1456Removes changes to Matrix, Clip, and Draw_Filter since Canvas state was
1457last saved. The state is removed from the stack.
1458
1459Does nothing if the stack is empty.
1460
1461#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04001462void draw(SkCanvas* canvas) {
1463 SkCanvas simple;
1464 SkDebugf("depth = %d\n", simple.getSaveCount());
1465 simple.restore();
1466 SkDebugf("depth = %d\n", simple.getSaveCount());
Cary Clark8032b982017-07-28 11:04:54 -04001467}
1468##
1469
Cary Clark2ade9972017-11-02 17:49:34 -04001470#SeeAlso save() saveLayer saveLayerPreserveLCDTextRequests saveLayerAlpha restoreToCount
1471
Cary Clark8032b982017-07-28 11:04:54 -04001472##
1473
1474# ------------------------------------------------------------------------------
1475
1476#Method int getSaveCount() const
1477
1478Returns the number of saved states, each containing: Matrix, Clip, and Draw_Filter.
1479Equals the number of save() calls less the number of restore() calls plus one.
1480The save count of a new canvas is one.
1481
Cary Clarkbad5ad72017-08-03 17:14:08 -04001482#Return depth of save state stack ##
Cary Clark8032b982017-07-28 11:04:54 -04001483
1484#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04001485void draw(SkCanvas* canvas) {
1486 SkCanvas simple;
1487 SkDebugf("depth = %d\n", simple.getSaveCount());
1488 simple.save();
1489 SkDebugf("depth = %d\n", simple.getSaveCount());
1490 simple.restore();
1491 SkDebugf("depth = %d\n", simple.getSaveCount());
Cary Clark8032b982017-07-28 11:04:54 -04001492}
1493#StdOut
Cary Clarkbad5ad72017-08-03 17:14:08 -04001494depth = 1
1495depth = 2
Cary Clark8032b982017-07-28 11:04:54 -04001496depth = 1
1497##
1498##
1499
Cary Clark2ade9972017-11-02 17:49:34 -04001500#SeeAlso save() restore() restoreToCount
1501
Cary Clark8032b982017-07-28 11:04:54 -04001502##
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
Cary Clark2ade9972017-11-02 17:49:34 -04001532#SeeAlso restore() getSaveCount save()
1533
Cary Clark8032b982017-07-28 11:04:54 -04001534##
1535
1536#Topic State_Stack ##
1537
1538# ------------------------------------------------------------------------------
Cary Clarkce101242017-09-01 15:51:02 -04001539
1540#Topic Layer
Cary Clarkd0530ba2017-09-14 11:25:39 -04001541#Substitute layer
Cary Clarkce101242017-09-01 15:51:02 -04001542#Alias Layers
1543
1544Layer allocates a temporary Bitmap to draw into. When the drawing is
1545complete, the Bitmap is drawn into the Canvas.
1546
1547Layer is saved in a stack along with other saved state. When state with a Layer
1548is restored, the Bitmap is drawn into the previous Layer.
1549
1550Layer may be initialized with the contents of the previous Layer. When Layer is
1551restored, its Bitmap can be modified by Paint passed to Layer to apply
1552Color_Alpha, Color_Filter, Image_Filter, and Blend_Mode.
1553
1554#Method int saveLayer(const SkRect* bounds, const SkPaint* paint)
1555
1556Saves Matrix, Clip, and Draw_Filter (Draw_Filter deprecated on most platforms),
1557and allocates a Bitmap for subsequent drawing.
1558Calling restore() discards changes to Matrix, Clip, and Draw_Filter,
1559and draws the Bitmap.
1560
1561Matrix may be changed by translate(), scale(), rotate(), skew(), concat(),
1562setMatrix, and resetMatrix. Clip may be changed by clipRect, clipRRect,
1563clipPath, clipRegion.
1564
1565Rect bounds suggests but does not define the Bitmap size. To clip drawing to
1566a specific rectangle, use clipRect.
1567
1568Optional Paint paint applies Color_Alpha, Color_Filter, Image_Filter, and
1569Blend_Mode when restore() is called.
1570
1571Call restoreToCount with returned value to restore this and subsequent saves.
1572
1573#Param bounds hint to limit the size of the Layer; may be nullptr ##
1574#Param paint graphics state for Layer; may be nullptr ##
1575
1576#Return depth of saved stack ##
1577
1578#Example
1579#Description
1580Rectangles are blurred by Image_Filter when restore() draws Layer to main
1581Canvas.
1582##
1583#Height 128
1584void draw(SkCanvas* canvas) {
1585 SkPaint paint, blur;
1586 blur.setImageFilter(SkImageFilter::MakeBlur(3, 3, nullptr));
1587 canvas->saveLayer(nullptr, &blur);
1588 SkRect rect = { 25, 25, 50, 50};
1589 canvas->drawRect(rect, paint);
1590 canvas->translate(50, 50);
1591 paint.setColor(SK_ColorRED);
1592 canvas->drawRect(rect, paint);
1593 canvas->restore();
1594}
1595##
1596
Cary Clark2ade9972017-11-02 17:49:34 -04001597#SeeAlso save() restore() saveLayer saveLayerPreserveLCDTextRequests saveLayerAlpha SaveLayerRec
Cary Clarkce101242017-09-01 15:51:02 -04001598
1599##
1600
1601#Method int saveLayer(const SkRect& bounds, const SkPaint* paint)
1602
1603Saves Matrix, Clip, and Draw_Filter (Draw_Filter deprecated on most platforms),
1604and allocates a Bitmap for subsequent drawing.
1605Calling restore() discards changes to Matrix, Clip, and Draw_Filter,
1606and draws the Bitmap.
1607
1608Matrix may be changed by translate(), scale(), rotate(), skew(), concat(),
1609setMatrix, and resetMatrix. Clip may be changed by clipRect, clipRRect,
1610clipPath, clipRegion.
1611
1612Rect bounds suggests but does not define the Layer size. To clip drawing to
1613a specific rectangle, use clipRect.
1614
1615Optional Paint paint applies Color_Alpha, Color_Filter, Image_Filter, and
1616Blend_Mode when restore() is called.
1617
1618Call restoreToCount with returned value to restore this and subsequent saves.
1619
1620#Param bounds hint to limit the size of Layer; may be nullptr ##
1621#Param paint graphics state for Layer; may be nullptr ##
1622
1623#Return depth of saved stack ##
1624
1625#Example
1626#Description
1627Rectangles are blurred by Image_Filter when restore() draws Layer to main Canvas.
1628The red rectangle is clipped; it does not fully fit on Layer.
1629Image_Filter blurs past edge of Layer so red rectangle is blurred on all sides.
1630##
1631#Height 128
1632void draw(SkCanvas* canvas) {
1633 SkPaint paint, blur;
1634 blur.setImageFilter(SkImageFilter::MakeBlur(3, 3, nullptr));
1635 canvas->saveLayer(SkRect::MakeWH(90, 90), &blur);
1636 SkRect rect = { 25, 25, 50, 50};
1637 canvas->drawRect(rect, paint);
1638 canvas->translate(50, 50);
1639 paint.setColor(SK_ColorRED);
1640 canvas->drawRect(rect, paint);
1641 canvas->restore();
1642}
1643##
1644
Cary Clark2ade9972017-11-02 17:49:34 -04001645#SeeAlso save() restore() saveLayerPreserveLCDTextRequests saveLayerAlpha SaveLayerRec
Cary Clarkce101242017-09-01 15:51:02 -04001646
1647##
1648
1649#Method int saveLayerPreserveLCDTextRequests(const SkRect* bounds, const SkPaint* paint)
1650
1651Saves Matrix, Clip, and Draw_Filter (Draw_Filter deprecated on most platforms),
1652and allocates a Bitmap for subsequent drawing.
1653LCD_Text is preserved when the Layer is drawn to the prior Layer.
1654
1655Calling restore() discards changes to Matrix, Clip, and Draw_Filter,
1656and draws Layer.
1657
1658Matrix may be changed by translate(), scale(), rotate(), skew(), concat(),
1659setMatrix, and resetMatrix. Clip may be changed by clipRect, clipRRect,
1660clipPath, clipRegion.
1661
1662Rect bounds suggests but does not define the Layer size. To clip drawing to
1663a specific rectangle, use clipRect.
1664
1665Optional Paint paint applies Color_Alpha, Color_Filter, Image_Filter, and
1666Blend_Mode when restore() is called.
1667
1668Call restoreToCount with returned value to restore this and subsequent saves.
1669
1670Draw text on an opaque background so that LCD_Text blends correctly with the
1671prior Layer. LCD_Text drawn on a background with transparency may result in
Cary Clark6fc50412017-09-21 12:31:06 -04001672incorrect blending.
Cary Clarkce101242017-09-01 15:51:02 -04001673
1674#Param bounds hint to limit the size of Layer; may be nullptr ##
1675#Param paint graphics state for Layer; may be nullptr ##
1676
1677#Return depth of saved stack ##
1678
1679#Example
1680 SkPaint paint;
1681 paint.setAntiAlias(true);
1682 paint.setLCDRenderText(true);
1683 paint.setTextSize(20);
1684 for (auto preserve : { false, true } ) {
1685 preserve ? canvas->saveLayerPreserveLCDTextRequests(nullptr, nullptr)
1686 : canvas->saveLayer(nullptr, nullptr);
1687 SkPaint p;
1688 p.setColor(SK_ColorWHITE);
1689 // Comment out the next line to draw on a non-opaque background.
1690 canvas->drawRect(SkRect::MakeLTRB(25, 40, 200, 70), p);
1691 canvas->drawString("Hamburgefons", 30, 60, paint);
1692
1693 p.setColor(0xFFCCCCCC);
1694 canvas->drawRect(SkRect::MakeLTRB(25, 70, 200, 100), p);
1695 canvas->drawString("Hamburgefons", 30, 90, paint);
1696
1697 canvas->restore();
1698 canvas->translate(0, 80);
1699 }
1700 ##
1701
Cary Clark2ade9972017-11-02 17:49:34 -04001702#SeeAlso save() restore() saveLayer saveLayerAlpha SaveLayerRec
Cary Clarkce101242017-09-01 15:51:02 -04001703
1704##
1705
1706#Method int saveLayerAlpha(const SkRect* bounds, U8CPU alpha)
1707
1708Saves Matrix, Clip, and Draw_Filter (Draw_Filter deprecated on most platforms),
1709and allocates Bitmap for subsequent drawing.
1710
1711Calling restore() discards changes to Matrix, Clip, and Draw_Filter,
1712and blends Layer with alpha opacity onto prior Layer.
1713
1714Matrix may be changed by translate(), scale(), rotate(), skew(), concat(),
1715setMatrix, and resetMatrix. Clip may be changed by clipRect, clipRRect,
1716clipPath, clipRegion.
1717
1718Rect bounds suggests but does not define Layer size. To clip drawing to
1719a specific rectangle, use clipRect.
1720
1721alpha of zero is fully transparent, 255 is fully opaque.
1722
1723Call restoreToCount with returned value to restore this and subsequent saves.
1724
1725#Param bounds hint to limit the size of Layer; may be nullptr ##
1726#Param alpha opacity of Layer ##
1727
1728#Return depth of saved stack ##
1729
1730#Example
1731 SkPaint paint;
1732 paint.setColor(SK_ColorRED);
1733 canvas->drawCircle(50, 50, 50, paint);
1734 canvas->saveLayerAlpha(nullptr, 128);
1735 paint.setColor(SK_ColorBLUE);
1736 canvas->drawCircle(100, 50, 50, paint);
1737 paint.setColor(SK_ColorGREEN);
1738 paint.setAlpha(128);
1739 canvas->drawCircle(75, 90, 50, paint);
1740 canvas->restore();
1741##
1742
Cary Clark2ade9972017-11-02 17:49:34 -04001743#SeeAlso save() restore() saveLayer saveLayerPreserveLCDTextRequests SaveLayerRec
Cary Clarkce101242017-09-01 15:51:02 -04001744
1745##
1746
1747#Enum
1748
1749#Code
1750 enum {
1751 kIsOpaque_SaveLayerFlag = 1 << 0,
1752 kPreserveLCDText_SaveLayerFlag = 1 << 1,
1753 kInitWithPrevious_SaveLayerFlag = 1 << 2,
1754 kDontClipToLayer_Legacy_SaveLayerFlag = kDontClipToLayer_PrivateSaveLayerFlag,
1755 };
1756
1757 typedef uint32_t SaveLayerFlags;
1758##
1759
1760SaveLayerFlags provides options that may be used in any combination in SaveLayerRec,
1761defining how Layer allocated by saveLayer operates.
1762
1763#Const kIsOpaque_SaveLayerFlag 1
1764 Creates Layer without transparency. Flag is ignored if Layer Paint contains
1765 Image_Filter or Color_Filter.
1766##
1767
1768#Const kPreserveLCDText_SaveLayerFlag 2
1769 Creates Layer for LCD text. Flag is ignored if Layer Paint contains
1770 Image_Filter or Color_Filter.
1771##
1772
1773#Const kInitWithPrevious_SaveLayerFlag 4
1774 Initializes Layer with the contents of the previous Layer.
1775##
1776
1777#Const kDontClipToLayer_Legacy_SaveLayerFlag 0x80000000
1778#Private
1779 to be deprecated: bug.skia.org/2440
1780##
1781 Only present on Android.
1782 Skips setting a clip to the Layer bounds.
1783##
1784
1785#Example
1786#Height 160
1787#Description
1788Canvas Layer captures red and blue circles scaled up by four.
1789scalePaint blends Layer back with transparency.
1790##
1791void draw(SkCanvas* canvas) {
1792 SkPaint redPaint, bluePaint, scalePaint;
1793 redPaint.setColor(SK_ColorRED);
1794 canvas->drawCircle(21, 21, 8, redPaint);
1795 bluePaint.setColor(SK_ColorBLUE);
1796 canvas->drawCircle(31, 21, 8, bluePaint);
1797 SkMatrix matrix;
1798 matrix.setScale(4, 4);
1799 scalePaint.setAlpha(0x40);
1800 scalePaint.setImageFilter(
1801 SkImageFilter::MakeMatrixFilter(matrix, kNone_SkFilterQuality, nullptr));
1802 SkCanvas::SaveLayerRec saveLayerRec(nullptr, &scalePaint,
1803 SkCanvas::kInitWithPrevious_SaveLayerFlag);
1804 canvas->saveLayer(saveLayerRec);
1805 canvas->restore();
1806}
1807##
1808
Cary Clark2ade9972017-11-02 17:49:34 -04001809#SeeAlso save() restore() saveLayer saveLayerPreserveLCDTextRequests saveLayerAlpha SaveLayerRec
Cary Clarkce101242017-09-01 15:51:02 -04001810
1811#Enum ##
1812
1813#Struct SaveLayerRec
1814
1815#Code
1816 struct SaveLayerRec {
1817 SaveLayerRec*(...
1818
1819 const SkRect* fBounds;
1820 const SkPaint* fPaint;
1821 const SkImageFilter* fBackdrop;
1822 SaveLayerFlags fSaveLayerFlags;
1823 };
1824##
1825
1826SaveLayerRec contains the state used to create the Layer.
1827
1828#Member const SkRect* fBounds
1829 fBounds is used as a hint to limit the size of Layer; may be nullptr.
1830 fBounds suggests but does not define Layer size. To clip drawing to
1831 a specific rectangle, use clipRect.
1832##
1833
1834#Member const SkPaint* fPaint
1835 fPaint modifies how Layer overlays the prior Layer; may be nullptr.
1836 Color_Alpha, Blend_Mode, Color_Filter, Draw_Looper, Image_Filter, and
1837 Mask_Filter affect Layer draw.
1838##
1839
1840#Member const SkImageFilter* fBackdrop
1841 fBackdrop applies Image_Filter to the prior Layer when copying to the Layer;
1842 may be nullptr. Use kInitWithPrevious_SaveLayerFlag to copy the
1843 prior Layer without an Image_Filter.
1844##
1845
1846#Member const SkImage* fClipMask
1847 restore() clips Layer by the Color_Alpha channel of fClipMask when
1848 Layer is copied to Device. fClipMask may be nullptr. .
1849##
1850
1851#Member const SkMatrix* fClipMatrix
1852 fClipMatrix transforms fClipMask before it clips Layer. If
1853 fClipMask describes a translucent gradient, it may be scaled and rotated
1854 without introducing artifacts. fClipMatrix may be nullptr.
1855##
1856
1857#Member SaveLayerFlags fSaveLayerFlags
1858 fSaveLayerFlags are used to create Layer without transparency,
1859 create Layer for LCD text, and to create Layer with the
1860 contents of the previous Layer.
1861##
1862
1863#Example
1864#Height 160
1865#Description
1866Canvas Layer captures a red Anti-aliased circle and a blue Aliased circle scaled
1867up by four. After drawing another red circle without scaling on top, the Layer is
1868transferred to the main canvas.
1869##
1870void draw(SkCanvas* canvas) {
1871 SkPaint redPaint, bluePaint;
1872 redPaint.setAntiAlias(true);
1873 redPaint.setColor(SK_ColorRED);
1874 canvas->drawCircle(21, 21, 8, redPaint);
1875 bluePaint.setColor(SK_ColorBLUE);
1876 canvas->drawCircle(31, 21, 8, bluePaint);
1877 SkMatrix matrix;
1878 matrix.setScale(4, 4);
1879 auto scaler = SkImageFilter::MakeMatrixFilter(matrix, kNone_SkFilterQuality, nullptr);
1880 SkCanvas::SaveLayerRec saveLayerRec(nullptr, nullptr, scaler.get(), 0);
1881 canvas->saveLayer(saveLayerRec);
1882 canvas->drawCircle(125, 85, 8, redPaint);
1883 canvas->restore();
1884}
1885##
1886
1887#Method SaveLayerRec()
1888
1889Sets fBounds, fPaint, and fBackdrop to nullptr. Clears fSaveLayerFlags.
1890
1891#Return empty SaveLayerRec ##
1892
1893#Example
1894 SkCanvas::SaveLayerRec rec1;
1895 rec1.fSaveLayerFlags = SkCanvas::kIsOpaque_SaveLayerFlag;
1896 SkCanvas::SaveLayerRec rec2(nullptr, nullptr, SkCanvas::kIsOpaque_SaveLayerFlag);
1897 SkDebugf("rec1 %c= rec2\n", rec1.fBounds == rec2.fBounds
1898 && rec1.fPaint == rec2.fPaint
1899 && rec1.fBackdrop == rec2.fBackdrop
1900 && rec1.fSaveLayerFlags == rec2.fSaveLayerFlags ? '=' : '!');
1901 #StdOut
1902 rec1 == rec2
1903 ##
1904##
1905
Cary Clark2ade9972017-11-02 17:49:34 -04001906#SeeAlso save() restore() saveLayer saveLayerPreserveLCDTextRequests saveLayerAlpha
1907
Cary Clarkce101242017-09-01 15:51:02 -04001908##
1909
1910#Method SaveLayerRec(const SkRect* bounds, const SkPaint* paint, SaveLayerFlags saveLayerFlags = 0)
1911
1912Sets fBounds, fPaint, and fSaveLayerFlags; sets fBackdrop to nullptr.
1913
1914#Param bounds Layer dimensions; may be nullptr ##
1915#Param paint applied to Layer when overlaying prior Layer; may be nullptr ##
1916#Param saveLayerFlags SaveLayerRec options to modify Layer ##
1917
1918#Return SaveLayerRec with empty backdrop ##
1919
1920#Example
1921 SkCanvas::SaveLayerRec rec1;
1922 SkCanvas::SaveLayerRec rec2(nullptr, nullptr);
1923 SkDebugf("rec1 %c= rec2\n", rec1.fBounds == rec2.fBounds
1924 && rec1.fPaint == rec2.fPaint
1925 && rec1.fBackdrop == rec2.fBackdrop
1926 && rec1.fSaveLayerFlags == rec2.fSaveLayerFlags ? '=' : '!');
1927 #StdOut
1928 rec1 == rec2
1929 ##
1930##
1931
Cary Clark2ade9972017-11-02 17:49:34 -04001932#SeeAlso save() restore() saveLayer saveLayerPreserveLCDTextRequests saveLayerAlpha
1933
Cary Clarkce101242017-09-01 15:51:02 -04001934##
1935
1936#Method SaveLayerRec(const SkRect* bounds, const SkPaint* paint, const SkImageFilter* backdrop,
1937 SaveLayerFlags saveLayerFlags)
1938
1939Sets fBounds, fPaint, fBackdrop, and fSaveLayerFlags.
1940
1941#Param bounds Layer dimensions; may be nullptr ##
1942#Param paint applied to Layer when overlaying prior Layer;
1943 may be nullptr
1944##
1945#Param backdrop prior Layer copied with Image_Filter; may be nullptr
1946##
1947#Param saveLayerFlags SaveLayerRec options to modify Layer ##
1948
1949#Return SaveLayerRec fully specified ##
1950
1951#Example
1952 SkCanvas::SaveLayerRec rec1;
1953 SkCanvas::SaveLayerRec rec2(nullptr, nullptr, nullptr, 0);
1954 SkDebugf("rec1 %c= rec2\n", rec1.fBounds == rec2.fBounds
1955 && rec1.fPaint == rec2.fPaint
1956 && rec1.fBackdrop == rec2.fBackdrop
1957 && rec1.fSaveLayerFlags == rec2.fSaveLayerFlags ? '=' : '!');
1958 #StdOut
1959 rec1 == rec2
1960 ##
1961##
1962
Cary Clark2ade9972017-11-02 17:49:34 -04001963#SeeAlso save() restore() saveLayer saveLayerPreserveLCDTextRequests saveLayerAlpha
1964
Cary Clarkce101242017-09-01 15:51:02 -04001965##
1966
1967#Method SaveLayerRec(const SkRect* bounds, const SkPaint* paint, const SkImageFilter* backdrop,
1968 const SkImage* clipMask, const SkMatrix* clipMatrix,
1969 SaveLayerFlags saveLayerFlags)
1970
1971#Experimental
1972Not ready for general use.
1973##
1974
1975Sets fBounds, fPaint, fBackdrop, fClipMask, fClipMatrix, and fSaveLayerFlags.
1976clipMatrix uses Color_Alpha channel of image, transformed by clipMatrix, to clip
1977Layer when drawn to Canvas.
1978
Cary Clark2ade9972017-11-02 17:49:34 -04001979Implementation is not complete; has no effect if Device is GPU-backed.
Cary Clarkce101242017-09-01 15:51:02 -04001980
1981#Param bounds Layer dimensions; may be nullptr ##
1982#Param paint graphics state applied to Layer when overlaying prior
1983 Layer; may be nullptr
1984##
1985#Param backdrop prior Layer copied with Image_Filter;
1986 may be nullptr
1987##
1988#Param clipMask clip applied to Layer; may be nullptr ##
1989#Param clipMatrix matrix applied to clipMask; may be nullptr to use
1990 identity matrix
1991##
1992#Param saveLayerFlags SaveLayerRec options to modify Layer ##
1993
1994#Return SaveLayerRec fully specified ##
1995
Cary Clark2ade9972017-11-02 17:49:34 -04001996#SeeAlso save() restore() saveLayer saveLayerPreserveLCDTextRequests saveLayerAlpha
Cary Clarkce101242017-09-01 15:51:02 -04001997
1998##
1999
2000#Struct ##
2001
2002#Method int saveLayer(const SaveLayerRec& layerRec)
2003
2004Saves Matrix, Clip, and Draw_Filter (Draw_Filter deprecated on most platforms),
2005and allocates Bitmap for subsequent drawing.
2006
2007Calling restore() discards changes to Matrix, Clip, and Draw_Filter,
2008and blends Bitmap with Color_Alpha opacity onto the prior Layer.
2009
2010Matrix may be changed by translate(), scale(), rotate(), skew(), concat(),
2011setMatrix, and resetMatrix. Clip may be changed by clipRect, clipRRect,
2012clipPath, clipRegion.
2013
2014SaveLayerRec contains the state used to create the Layer.
2015
2016Call restoreToCount with returned value to restore this and subsequent saves.
2017
2018#Param layerRec Layer state ##
2019
2020#Return depth of save state stack ##
2021
2022#Example
2023#Description
2024The example draws an image, and saves it into a Layer with kInitWithPrevious_SaveLayerFlag.
2025Next it punches a hole in Layer and restore with SkBlendMode::kPlus.
2026Where Layer was cleared, the original image will draw unchanged.
2027Outside of the circle the mandrill is brightened.
2028##
2029 #Image 3
2030 // sk_sp<SkImage> image = GetResourceAsImage("mandrill_256.png");
2031 canvas->drawImage(image, 0, 0, nullptr);
2032 SkCanvas::SaveLayerRec rec;
2033 SkPaint paint;
2034 paint.setBlendMode(SkBlendMode::kPlus);
2035 rec.fSaveLayerFlags = SkCanvas::kInitWithPrevious_SaveLayerFlag;
2036 rec.fPaint = &paint;
2037 canvas->saveLayer(rec);
2038 paint.setBlendMode(SkBlendMode::kClear);
2039 canvas->drawCircle(128, 128, 96, paint);
2040 canvas->restore();
2041##
2042
2043#ToDo above example needs to replace GetResourceAsImage with way to select image in fiddle ##
2044
Cary Clark2ade9972017-11-02 17:49:34 -04002045#SeeAlso save() restore() saveLayer saveLayerPreserveLCDTextRequests saveLayerAlpha
2046
Cary Clarkce101242017-09-01 15:51:02 -04002047##
2048
2049#Topic Layer ##
2050
2051# ------------------------------------------------------------------------------
Cary Clark8032b982017-07-28 11:04:54 -04002052#Topic Matrix
2053
2054#Method void translate(SkScalar dx, SkScalar dy)
2055
2056Translate Matrix by dx along the x-axis and dy along the y-axis.
2057
2058Mathematically, replace Matrix with a translation matrix
Cary Clarkce101242017-09-01 15:51:02 -04002059Premultiplied with Matrix.
Cary Clark8032b982017-07-28 11:04:54 -04002060
2061This has the effect of moving the drawing by (dx, dy) before transforming
2062the result with Matrix.
2063
Cary Clarkbad5ad72017-08-03 17:14:08 -04002064#Param dx distance to translate in x ##
2065#Param dy distance to translate in y ##
Cary Clark8032b982017-07-28 11:04:54 -04002066
2067#Example
2068#Height 128
2069#Description
2070scale() followed by translate() produces different results from translate() followed
2071by scale().
2072
2073The blue stroke follows translate of (50, 50); a black
2074fill follows scale of (2, 1/2.f). After restoring the clip, which resets
2075Matrix, a red frame follows the same scale of (2, 1/2.f); a gray fill
2076follows translate of (50, 50).
2077##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002078void draw(SkCanvas* canvas) {
2079 SkPaint filledPaint;
2080 SkPaint outlinePaint;
2081 outlinePaint.setStyle(SkPaint::kStroke_Style);
2082 outlinePaint.setColor(SK_ColorBLUE);
2083 canvas->save();
2084 canvas->translate(50, 50);
2085 canvas->drawCircle(28, 28, 15, outlinePaint); // blue center: (50+28, 50+28)
2086 canvas->scale(2, 1/2.f);
2087 canvas->drawCircle(28, 28, 15, filledPaint); // black center: (50+(28*2), 50+(28/2))
2088 canvas->restore();
2089 filledPaint.setColor(SK_ColorGRAY);
2090 outlinePaint.setColor(SK_ColorRED);
2091 canvas->scale(2, 1/2.f);
2092 canvas->drawCircle(28, 28, 15, outlinePaint); // red center: (28*2, 28/2)
2093 canvas->translate(50, 50);
2094 canvas->drawCircle(28, 28, 15, filledPaint); // gray center: ((50+28)*2, (50+28)/2)
Cary Clark8032b982017-07-28 11:04:54 -04002095}
2096##
2097
Cary Clark2ade9972017-11-02 17:49:34 -04002098#SeeAlso concat() scale() skew() rotate() setMatrix
Cary Clark8032b982017-07-28 11:04:54 -04002099
2100##
2101
2102# ------------------------------------------------------------------------------
2103
2104#Method void scale(SkScalar sx, SkScalar sy)
2105
2106Scale Matrix by sx on the x-axis and sy on the y-axis.
2107
2108Mathematically, replace Matrix with a scale matrix
Cary Clarkce101242017-09-01 15:51:02 -04002109Premultiplied with Matrix.
Cary Clark8032b982017-07-28 11:04:54 -04002110
2111This has the effect of scaling the drawing by (sx, sy) before transforming
2112the result with Matrix.
2113
Cary Clarkbad5ad72017-08-03 17:14:08 -04002114#Param sx amount to scale in x ##
2115#Param sy amount to scale in y ##
Cary Clark8032b982017-07-28 11:04:54 -04002116
2117#Example
2118#Height 160
Cary Clarkbad5ad72017-08-03 17:14:08 -04002119void draw(SkCanvas* canvas) {
2120 SkPaint paint;
2121 SkRect rect = { 10, 20, 60, 120 };
2122 canvas->translate(20, 20);
2123 canvas->drawRect(rect, paint);
2124 canvas->scale(2, .5f);
2125 paint.setColor(SK_ColorGRAY);
2126 canvas->drawRect(rect, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002127}
2128##
2129
Cary Clark2ade9972017-11-02 17:49:34 -04002130#SeeAlso concat() translate() skew() rotate() setMatrix
Cary Clark8032b982017-07-28 11:04:54 -04002131
2132##
2133
2134# ------------------------------------------------------------------------------
2135
2136#Method void rotate(SkScalar degrees)
2137
2138Rotate Matrix by degrees. Positive degrees rotates clockwise.
2139
2140Mathematically, replace Matrix with a rotation matrix
Cary Clarkce101242017-09-01 15:51:02 -04002141Premultiplied with Matrix.
Cary Clark8032b982017-07-28 11:04:54 -04002142
2143This has the effect of rotating the drawing by degrees before transforming
2144the result with Matrix.
2145
Cary Clarkbad5ad72017-08-03 17:14:08 -04002146#Param degrees amount to rotate, in degrees ##
Cary Clark8032b982017-07-28 11:04:54 -04002147
2148#Example
2149#Description
2150Draw clock hands at time 5:10. The hour hand and minute hand point up and
2151are rotated clockwise.
2152##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002153void draw(SkCanvas* canvas) {
2154 SkPaint paint;
2155 paint.setStyle(SkPaint::kStroke_Style);
2156 canvas->translate(128, 128);
2157 canvas->drawCircle(0, 0, 60, paint);
2158 canvas->save();
2159 canvas->rotate(10 * 360 / 60); // 10 minutes of 60 scaled to 360 degrees
2160 canvas->drawLine(0, 0, 0, -50, paint);
2161 canvas->restore();
2162 canvas->rotate((5 + 10.f/60) * 360 / 12); // 5 and 10/60 hours of 12 scaled to 360 degrees
2163 canvas->drawLine(0, 0, 0, -30, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002164}
2165##
2166
Cary Clark2ade9972017-11-02 17:49:34 -04002167#SeeAlso concat() translate() skew() scale() setMatrix
Cary Clark8032b982017-07-28 11:04:54 -04002168
2169##
2170
2171# ------------------------------------------------------------------------------
2172
2173#Method void rotate(SkScalar degrees, SkScalar px, SkScalar py)
2174
Cary Clarkbad5ad72017-08-03 17:14:08 -04002175Rotate Matrix by degrees about a point at (px, py). Positive degrees rotates
2176clockwise.
Cary Clark8032b982017-07-28 11:04:54 -04002177
Cary Clarkce101242017-09-01 15:51:02 -04002178Mathematically, construct a rotation matrix. Premultiply the rotation matrix by
Cary Clark8032b982017-07-28 11:04:54 -04002179a translation matrix, then replace Matrix with the resulting matrix
Cary Clarkce101242017-09-01 15:51:02 -04002180Premultiplied with Matrix.
Cary Clark8032b982017-07-28 11:04:54 -04002181
Cary Clarkbad5ad72017-08-03 17:14:08 -04002182This has the effect of rotating the drawing about a given point before
2183transforming the result with Matrix.
Cary Clark8032b982017-07-28 11:04:54 -04002184
Cary Clarkbad5ad72017-08-03 17:14:08 -04002185#Param degrees amount to rotate, in degrees ##
2186#Param px x-coordinate of the point to rotate about ##
2187#Param py y-coordinate of the point to rotate about ##
Cary Clark8032b982017-07-28 11:04:54 -04002188
2189#Example
2190#Height 192
Cary Clarkbad5ad72017-08-03 17:14:08 -04002191void draw(SkCanvas* canvas) {
2192 SkPaint paint;
2193 paint.setTextSize(96);
2194 canvas->drawString("A1", 130, 100, paint);
2195 canvas->rotate(180, 130, 100);
2196 canvas->drawString("A1", 130, 100, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002197}
2198##
2199
Cary Clark2ade9972017-11-02 17:49:34 -04002200#SeeAlso concat() translate() skew() scale() setMatrix
Cary Clark8032b982017-07-28 11:04:54 -04002201
2202##
2203
2204# ------------------------------------------------------------------------------
2205
2206#Method void skew(SkScalar sx, SkScalar sy)
2207
Cary Clarkbad5ad72017-08-03 17:14:08 -04002208Skew Matrix by sx on the x-axis and sy on the y-axis. A positive value of sx
2209skews the drawing right as y increases; a positive value of sy skews the drawing
2210down as x increases.
Cary Clark8032b982017-07-28 11:04:54 -04002211
Cary Clarkce101242017-09-01 15:51:02 -04002212Mathematically, replace Matrix with a skew matrix Premultiplied with Matrix.
Cary Clark8032b982017-07-28 11:04:54 -04002213
Cary Clarkbad5ad72017-08-03 17:14:08 -04002214This has the effect of skewing the drawing by (sx, sy) before transforming
Cary Clark8032b982017-07-28 11:04:54 -04002215the result with Matrix.
2216
Cary Clarkbad5ad72017-08-03 17:14:08 -04002217#Param sx amount to skew in x ##
2218#Param sy amount to skew in y ##
2219
Cary Clark8032b982017-07-28 11:04:54 -04002220#Example
2221 #Description
2222 Black text mimics an oblique text style by using a negative skew in x that
2223 shifts the geometry to the right as the y values decrease.
2224 Red text uses a positive skew in y to shift the geometry down as the x values
2225 increase.
2226 Blue text combines x and y skew to rotate and scale.
2227 ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002228 SkPaint paint;
2229 paint.setTextSize(128);
2230 canvas->translate(30, 130);
2231 canvas->save();
2232 canvas->skew(-.5, 0);
2233 canvas->drawString("A1", 0, 0, paint);
2234 canvas->restore();
2235 canvas->save();
2236 canvas->skew(0, .5);
2237 paint.setColor(SK_ColorRED);
2238 canvas->drawString("A1", 0, 0, paint);
2239 canvas->restore();
2240 canvas->skew(-.5, .5);
2241 paint.setColor(SK_ColorBLUE);
Cary Clark8032b982017-07-28 11:04:54 -04002242 canvas->drawString("A1", 0, 0, paint);
2243##
2244
Cary Clark2ade9972017-11-02 17:49:34 -04002245#SeeAlso concat() translate() rotate() scale() setMatrix
Cary Clark8032b982017-07-28 11:04:54 -04002246
2247##
2248
2249# ------------------------------------------------------------------------------
2250
2251#Method void concat(const SkMatrix& matrix)
2252
Cary Clarkce101242017-09-01 15:51:02 -04002253Replace Matrix with matrix Premultiplied with existing Matrix.
Cary Clark8032b982017-07-28 11:04:54 -04002254
Cary Clarkbad5ad72017-08-03 17:14:08 -04002255This has the effect of transforming the drawn geometry by matrix, before
2256transforming the result with existing Matrix.
Cary Clark8032b982017-07-28 11:04:54 -04002257
Cary Clarkce101242017-09-01 15:51:02 -04002258#Param matrix matrix to Premultiply with existing Matrix ##
Cary Clark8032b982017-07-28 11:04:54 -04002259
2260#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04002261void draw(SkCanvas* canvas) {
2262 SkPaint paint;
2263 paint.setTextSize(80);
2264 paint.setTextScaleX(.3);
2265 SkMatrix matrix;
2266 SkRect rect[2] = {{ 10, 20, 90, 110 }, { 40, 130, 140, 180 }};
2267 matrix.setRectToRect(rect[0], rect[1], SkMatrix::kFill_ScaleToFit);
2268 canvas->drawRect(rect[0], paint);
2269 canvas->drawRect(rect[1], paint);
2270 paint.setColor(SK_ColorWHITE);
2271 canvas->drawString("Here", rect[0].fLeft + 10, rect[0].fBottom - 10, paint);
2272 canvas->concat(matrix);
2273 canvas->drawString("There", rect[0].fLeft + 10, rect[0].fBottom - 10, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002274}
2275##
2276
Cary Clark2ade9972017-11-02 17:49:34 -04002277#SeeAlso translate() rotate() scale() skew() setMatrix
Cary Clark8032b982017-07-28 11:04:54 -04002278
2279##
2280
2281# ------------------------------------------------------------------------------
2282
2283#Method void setMatrix(const SkMatrix& matrix)
2284
2285Replace Matrix with matrix.
2286Unlike concat(), any prior matrix state is overwritten.
2287
Cary Clarkbad5ad72017-08-03 17:14:08 -04002288#Param matrix matrix to copy, replacing existing Matrix ##
Cary Clark8032b982017-07-28 11:04:54 -04002289
2290#Example
2291#Height 128
Cary Clarkbad5ad72017-08-03 17:14:08 -04002292void draw(SkCanvas* canvas) {
2293 SkPaint paint;
2294 canvas->scale(4, 6);
2295 canvas->drawString("truth", 2, 10, paint);
2296 SkMatrix matrix;
2297 matrix.setScale(2.8f, 6);
2298 canvas->setMatrix(matrix);
2299 canvas->drawString("consequences", 2, 20, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002300}
2301##
2302
Cary Clark2ade9972017-11-02 17:49:34 -04002303#SeeAlso resetMatrix concat() translate() rotate() scale() skew()
Cary Clark8032b982017-07-28 11:04:54 -04002304
2305##
2306
2307# ------------------------------------------------------------------------------
2308
2309#Method void resetMatrix()
2310
2311Sets Matrix to the identity matrix.
2312Any prior matrix state is overwritten.
2313
2314#Example
2315#Height 128
Cary Clarkbad5ad72017-08-03 17:14:08 -04002316void draw(SkCanvas* canvas) {
2317 SkPaint paint;
2318 canvas->scale(4, 6);
2319 canvas->drawString("truth", 2, 10, paint);
2320 canvas->resetMatrix();
2321 canvas->scale(2.8f, 6);
2322 canvas->drawString("consequences", 2, 20, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002323}
2324##
2325
Cary Clark2ade9972017-11-02 17:49:34 -04002326#SeeAlso setMatrix concat() translate() rotate() scale() skew()
Cary Clark8032b982017-07-28 11:04:54 -04002327
2328##
2329
2330# ------------------------------------------------------------------------------
2331
2332#Method const SkMatrix& getTotalMatrix() const
2333
2334Returns Matrix.
2335This does not account for translation by Device or Surface.
2336
Cary Clarkbad5ad72017-08-03 17:14:08 -04002337#Return Matrix in Canvas ##
Cary Clark8032b982017-07-28 11:04:54 -04002338
2339#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04002340 SkDebugf("isIdentity %s\n", canvas->getTotalMatrix().isIdentity() ? "true" : "false");
2341 #StdOut
2342 isIdentity true
2343 ##
Cary Clark8032b982017-07-28 11:04:54 -04002344##
2345
Cary Clark2ade9972017-11-02 17:49:34 -04002346#SeeAlso setMatrix resetMatrix concat()
Cary Clark8032b982017-07-28 11:04:54 -04002347
2348##
2349
2350#Topic Matrix ##
2351
2352# ------------------------------------------------------------------------------
2353#Topic Clip
2354
2355Clip is built from a stack of clipping paths. Each Path in the
2356stack can be constructed from one or more Path_Contour elements. The
2357Path_Contour may be composed of any number of Path_Verb segments. Each
2358Path_Contour forms a closed area; Path_Fill_Type defines the area enclosed
2359by Path_Contour.
2360
2361Clip stack of Path elements successfully restrict the Path area. Each
2362Path is transformed by Matrix, then intersected with or subtracted from the
2363prior Clip to form the replacement Clip. Use SkClipOp::kDifference
2364to subtract Path from Clip; use SkClipOp::kIntersect to intersect Path
2365with Clip.
2366
Cary Clarkce101242017-09-01 15:51:02 -04002367A clipping Path may be Anti-aliased; if Path, after transformation, is
Cary Clark8032b982017-07-28 11:04:54 -04002368composed of horizontal and vertical lines, clearing Anti-alias allows whole pixels
Cary Clarkce101242017-09-01 15:51:02 -04002369to either be inside or outside the clip. The fastest drawing has a Aliased,
2370rectangular clip.
Cary Clark8032b982017-07-28 11:04:54 -04002371
2372If clipping Path has Anti-alias set, clip may partially clip a pixel, requiring
2373that drawing blend partially with the destination along the edge. A rotated
Cary Clarkce101242017-09-01 15:51:02 -04002374rectangular Anti-aliased clip looks smoother but draws slower.
Cary Clark8032b982017-07-28 11:04:54 -04002375
2376Clip can combine with Rect and Round_Rect primitives; like
2377Path, these are transformed by Matrix before they are combined with Clip.
2378
2379Clip can combine with Region. Region is assumed to be in Device coordinates
2380and is unaffected by Matrix.
2381
2382#Example
2383#Height 90
2384 #Description
Cary Clarkce101242017-09-01 15:51:02 -04002385 Draw a red circle with an Aliased clip and an Anti-aliased clip.
Cary Clark8032b982017-07-28 11:04:54 -04002386 Use an image filter to zoom into the pixels drawn.
Cary Clarkce101242017-09-01 15:51:02 -04002387 The edge of the Aliased clip fully draws pixels in the red circle.
2388 The edge of the Anti-aliased clip partially draws pixels in the red circle.
Cary Clark8032b982017-07-28 11:04:54 -04002389 ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002390 SkPaint redPaint, scalePaint;
2391 redPaint.setAntiAlias(true);
2392 redPaint.setColor(SK_ColorRED);
2393 canvas->save();
2394 for (bool antialias : { false, true } ) {
2395 canvas->save();
2396 canvas->clipRect(SkRect::MakeWH(19.5f, 11.5f), antialias);
2397 canvas->drawCircle(17, 11, 8, redPaint);
2398 canvas->restore();
2399 canvas->translate(16, 0);
2400 }
2401 canvas->restore();
2402 SkMatrix matrix;
2403 matrix.setScale(6, 6);
2404 scalePaint.setImageFilter(
2405 SkImageFilter::MakeMatrixFilter(matrix, kNone_SkFilterQuality, nullptr));
2406 SkCanvas::SaveLayerRec saveLayerRec(
2407 nullptr, &scalePaint, SkCanvas::kInitWithPrevious_SaveLayerFlag);
2408 canvas->saveLayer(saveLayerRec);
Cary Clark8032b982017-07-28 11:04:54 -04002409 canvas->restore();
2410##
2411
2412#Method void clipRect(const SkRect& rect, SkClipOp op, bool doAntiAlias)
2413
2414Replace Clip with the intersection or difference of Clip and rect,
Cary Clarkce101242017-09-01 15:51:02 -04002415with an Aliased or Anti-aliased clip edge. rect is transformed by Matrix
Cary Clark8032b982017-07-28 11:04:54 -04002416before it is combined with Clip.
2417
Cary Clarka523d2d2017-08-30 08:58:10 -04002418#Param rect Rect to combine with Clip ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002419#Param op Clip_Op to apply to Clip ##
Cary Clarkce101242017-09-01 15:51:02 -04002420#Param doAntiAlias true if Clip is to be Anti-aliased ##
Cary Clark8032b982017-07-28 11:04:54 -04002421
2422#Example
2423#Height 128
Cary Clarkbad5ad72017-08-03 17:14:08 -04002424void draw(SkCanvas* canvas) {
2425 canvas->rotate(10);
2426 SkPaint paint;
2427 paint.setAntiAlias(true);
2428 for (auto alias: { false, true } ) {
2429 canvas->save();
2430 canvas->clipRect(SkRect::MakeWH(90, 80), SkClipOp::kIntersect, alias);
2431 canvas->drawCircle(100, 60, 60, paint);
2432 canvas->restore();
2433 canvas->translate(80, 0);
2434 }
Cary Clark8032b982017-07-28 11:04:54 -04002435}
2436##
2437
Cary Clark2ade9972017-11-02 17:49:34 -04002438#SeeAlso clipRRect clipPath clipRegion
Cary Clark8032b982017-07-28 11:04:54 -04002439
2440##
2441
2442#Method void clipRect(const SkRect& rect, SkClipOp op)
2443
2444Replace Clip with the intersection or difference of Clip and rect.
Cary Clarkce101242017-09-01 15:51:02 -04002445Resulting Clip is Aliased; pixels are fully contained by the clip.
Cary Clarkbad5ad72017-08-03 17:14:08 -04002446rect is transformed by Matrix before it is combined with Clip.
Cary Clark8032b982017-07-28 11:04:54 -04002447
Cary Clarka523d2d2017-08-30 08:58:10 -04002448#Param rect Rect to combine with Clip ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002449#Param op Clip_Op to apply to Clip ##
Cary Clark8032b982017-07-28 11:04:54 -04002450
2451#Example
2452#Height 192
2453#Width 280
Cary Clarkbad5ad72017-08-03 17:14:08 -04002454void draw(SkCanvas* canvas) {
2455 SkPaint paint;
2456 for (SkClipOp op: { SkClipOp::kIntersect, SkClipOp::kDifference } ) {
2457 canvas->save();
2458 canvas->clipRect(SkRect::MakeWH(90, 120), op, false);
2459 canvas->drawCircle(100, 100, 60, paint);
2460 canvas->restore();
2461 canvas->translate(80, 0);
2462 }
Cary Clark8032b982017-07-28 11:04:54 -04002463}
2464##
2465
Cary Clark2ade9972017-11-02 17:49:34 -04002466#SeeAlso clipRRect clipPath clipRegion
Cary Clark8032b982017-07-28 11:04:54 -04002467
2468##
2469
2470#Method void clipRect(const SkRect& rect, bool doAntiAlias = false)
2471
2472Replace Clip with the intersection of Clip and rect.
Cary Clarkce101242017-09-01 15:51:02 -04002473Resulting Clip is Aliased; pixels are fully contained by the clip.
Cary Clark8032b982017-07-28 11:04:54 -04002474rect is transformed by Matrix
2475before it is combined with Clip.
2476
Cary Clarka523d2d2017-08-30 08:58:10 -04002477#Param rect Rect to combine with Clip ##
Cary Clarkce101242017-09-01 15:51:02 -04002478#Param doAntiAlias true if Clip is to be Anti-aliased ##
Cary Clark8032b982017-07-28 11:04:54 -04002479
2480#Example
2481#Height 133
2482 #Description
Cary Clarkce101242017-09-01 15:51:02 -04002483 A circle drawn in pieces looks uniform when drawn Aliased.
2484 The same circle pieces blend with pixels more than once when Anti-aliased,
Cary Clark8032b982017-07-28 11:04:54 -04002485 visible as a thin pair of lines through the right circle.
2486 ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002487void draw(SkCanvas* canvas) {
2488 canvas->clear(SK_ColorWHITE);
2489 SkPaint paint;
2490 paint.setAntiAlias(true);
2491 paint.setColor(0x8055aaff);
2492 SkRect clipRect = { 0, 0, 87.4f, 87.4f };
2493 for (auto alias: { false, true } ) {
2494 canvas->save();
2495 canvas->clipRect(clipRect, SkClipOp::kIntersect, alias);
2496 canvas->drawCircle(67, 67, 60, paint);
2497 canvas->restore();
2498 canvas->save();
2499 canvas->clipRect(clipRect, SkClipOp::kDifference, alias);
2500 canvas->drawCircle(67, 67, 60, paint);
2501 canvas->restore();
2502 canvas->translate(120, 0);
2503 }
Cary Clark8032b982017-07-28 11:04:54 -04002504}
2505##
2506
Cary Clark2ade9972017-11-02 17:49:34 -04002507#SeeAlso clipRRect clipPath clipRegion
Cary Clark8032b982017-07-28 11:04:54 -04002508
2509##
2510
2511#Method void androidFramework_setDeviceClipRestriction(const SkIRect& rect)
2512
Cary Clarkce101242017-09-01 15:51:02 -04002513Sets the maximum clip rectangle, which can be set by clipRect, clipRRect and
Cary Clark8032b982017-07-28 11:04:54 -04002514clipPath and intersect the current clip with the specified rect.
Cary Clarkce101242017-09-01 15:51:02 -04002515The maximum clip affects only future clipping operations; it is not retroactive.
Cary Clark8032b982017-07-28 11:04:54 -04002516The clip restriction is not recorded in pictures.
2517
Cary Clarkce101242017-09-01 15:51:02 -04002518Pass an empty rect to disable maximum clip.
Cary Clarkbad5ad72017-08-03 17:14:08 -04002519
Cary Clark8032b982017-07-28 11:04:54 -04002520#Private
2521This is private API to be used only by Android framework.
2522##
2523
Cary Clarkbad5ad72017-08-03 17:14:08 -04002524#Param rect maximum allowed clip in device coordinates
Cary Clark579985c2017-07-31 11:48:27 -04002525#Param ##
Cary Clark8032b982017-07-28 11:04:54 -04002526
2527##
2528
2529#Method void clipRRect(const SkRRect& rrect, SkClipOp op, bool doAntiAlias)
2530
2531Replace Clip with the intersection or difference of Clip and rrect,
Cary Clarkce101242017-09-01 15:51:02 -04002532with an Aliased or Anti-aliased clip edge.
Cary Clark8032b982017-07-28 11:04:54 -04002533rrect is transformed by Matrix
2534before it is combined with Clip.
2535
Cary Clarkbad5ad72017-08-03 17:14:08 -04002536#Param rrect Round_Rect to combine with Clip ##
2537#Param op Clip_Op to apply to Clip ##
Cary Clarkce101242017-09-01 15:51:02 -04002538#Param doAntiAlias true if Clip is to be Anti-aliased ##
Cary Clark8032b982017-07-28 11:04:54 -04002539
2540#Example
2541#Height 128
Cary Clarkbad5ad72017-08-03 17:14:08 -04002542void draw(SkCanvas* canvas) {
2543 canvas->clear(SK_ColorWHITE);
2544 SkPaint paint;
2545 paint.setAntiAlias(true);
2546 paint.setColor(0x8055aaff);
2547 SkRRect oval;
2548 oval.setOval({10, 20, 90, 100});
2549 canvas->clipRRect(oval, SkClipOp::kIntersect, true);
2550 canvas->drawCircle(70, 100, 60, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002551}
2552##
2553
Cary Clark2ade9972017-11-02 17:49:34 -04002554#SeeAlso clipRect clipPath clipRegion
Cary Clark8032b982017-07-28 11:04:54 -04002555
2556##
2557
2558#Method void clipRRect(const SkRRect& rrect, SkClipOp op)
2559
2560Replace Clip with the intersection or difference of Clip and rrect.
Cary Clarkce101242017-09-01 15:51:02 -04002561Resulting Clip is Aliased; pixels are fully contained by the clip.
Cary Clarkbad5ad72017-08-03 17:14:08 -04002562rrect is transformed by Matrix before it is combined with Clip.
Cary Clark8032b982017-07-28 11:04:54 -04002563
Cary Clarkbad5ad72017-08-03 17:14:08 -04002564#Param rrect Round_Rect to combine with Clip ##
2565#Param op Clip_Op to apply to Clip ##
Cary Clark8032b982017-07-28 11:04:54 -04002566
2567#Example
2568#Height 128
Cary Clarkbad5ad72017-08-03 17:14:08 -04002569void draw(SkCanvas* canvas) {
2570 SkPaint paint;
2571 paint.setColor(0x8055aaff);
2572 auto oval = SkRRect::MakeOval({10, 20, 90, 100});
2573 canvas->clipRRect(oval, SkClipOp::kIntersect);
2574 canvas->drawCircle(70, 100, 60, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002575}
2576##
2577
Cary Clark2ade9972017-11-02 17:49:34 -04002578#SeeAlso clipRect clipPath clipRegion
Cary Clark8032b982017-07-28 11:04:54 -04002579
2580##
2581
2582#Method void clipRRect(const SkRRect& rrect, bool doAntiAlias = false)
2583
2584Replace Clip with the intersection of Clip and rrect,
Cary Clarkce101242017-09-01 15:51:02 -04002585with an Aliased or Anti-aliased clip edge.
Cary Clarkbad5ad72017-08-03 17:14:08 -04002586rrect is transformed by Matrix before it is combined with Clip.
Cary Clark8032b982017-07-28 11:04:54 -04002587
Cary Clarkbad5ad72017-08-03 17:14:08 -04002588#Param rrect Round_Rect to combine with Clip ##
Cary Clarkce101242017-09-01 15:51:02 -04002589#Param doAntiAlias true if Clip is to be Anti-aliased ##
Cary Clark8032b982017-07-28 11:04:54 -04002590
2591#Example
2592#Height 128
Cary Clarkbad5ad72017-08-03 17:14:08 -04002593void draw(SkCanvas* canvas) {
2594 SkPaint paint;
2595 paint.setAntiAlias(true);
2596 auto oval = SkRRect::MakeRectXY({10, 20, 90, 100}, 9, 13);
2597 canvas->clipRRect(oval, true);
2598 canvas->drawCircle(70, 100, 60, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002599}
2600##
2601
Cary Clark2ade9972017-11-02 17:49:34 -04002602#SeeAlso clipRect clipPath clipRegion
Cary Clark8032b982017-07-28 11:04:54 -04002603
2604##
2605
2606#Method void clipPath(const SkPath& path, SkClipOp op, bool doAntiAlias)
2607
2608Replace Clip with the intersection or difference of Clip and path,
Cary Clarkce101242017-09-01 15:51:02 -04002609with an Aliased or Anti-aliased clip edge. Path_Fill_Type determines if path
Cary Clark8032b982017-07-28 11:04:54 -04002610describes the area inside or outside its contours; and if Path_Contour overlaps
2611itself or another Path_Contour, whether the overlaps form part of the area.
Cary Clarkbad5ad72017-08-03 17:14:08 -04002612path is transformed by Matrix before it is combined with Clip.
Cary Clark8032b982017-07-28 11:04:54 -04002613
Cary Clarkbad5ad72017-08-03 17:14:08 -04002614#Param path Path to combine with Clip ##
2615#Param op Clip_Op to apply to Clip ##
Cary Clarkce101242017-09-01 15:51:02 -04002616#Param doAntiAlias true if Clip is to be Anti-aliased ##
Cary Clark8032b982017-07-28 11:04:54 -04002617
2618#Example
2619#Description
2620Top figure uses SkPath::kInverseWinding_FillType and SkClipOp::kDifference;
2621area outside clip is subtracted from circle.
2622
2623Bottom figure uses SkPath::kWinding_FillType and SkClipOp::kIntersect;
2624area inside clip is intersected with circle.
2625##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002626void draw(SkCanvas* canvas) {
2627 SkPaint paint;
2628 paint.setAntiAlias(true);
2629 SkPath path;
2630 path.addRect({20, 30, 100, 110});
2631 path.setFillType(SkPath::kInverseWinding_FillType);
2632 canvas->save();
2633 canvas->clipPath(path, SkClipOp::kDifference, false);
2634 canvas->drawCircle(70, 100, 60, paint);
2635 canvas->restore();
2636 canvas->translate(100, 100);
2637 path.setFillType(SkPath::kWinding_FillType);
2638 canvas->clipPath(path, SkClipOp::kIntersect, false);
2639 canvas->drawCircle(70, 100, 60, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002640}
2641##
2642
Cary Clark2ade9972017-11-02 17:49:34 -04002643#SeeAlso clipRect clipRRect clipRegion
Cary Clark8032b982017-07-28 11:04:54 -04002644
2645##
2646
2647#Method void clipPath(const SkPath& path, SkClipOp op)
2648
2649Replace Clip with the intersection or difference of Clip and path.
Cary Clarkce101242017-09-01 15:51:02 -04002650Resulting Clip is Aliased; pixels are fully contained by the clip.
Cary Clark8032b982017-07-28 11:04:54 -04002651Path_Fill_Type determines if path
2652describes the area inside or outside its contours; and if Path_Contour overlaps
2653itself or another Path_Contour, whether the overlaps form part of the area.
2654path is transformed by Matrix
2655before it is combined with Clip.
2656
Cary Clarkbad5ad72017-08-03 17:14:08 -04002657#Param path Path to combine with Clip ##
2658#Param op Clip_Op to apply to Clip ##
Cary Clark8032b982017-07-28 11:04:54 -04002659
2660#Example
2661#Description
Cary Clarkbc5697d2017-10-04 14:31:33 -04002662Overlapping Rects form a clip. When clip Path_Fill_Type is set to
Cary Clark8032b982017-07-28 11:04:54 -04002663SkPath::kWinding_FillType, the overlap is included. Set to
2664SkPath::kEvenOdd_FillType, the overlap is excluded and forms a hole.
2665##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002666void draw(SkCanvas* canvas) {
2667 SkPaint paint;
2668 paint.setAntiAlias(true);
2669 SkPath path;
2670 path.addRect({20, 15, 100, 95});
2671 path.addRect({50, 65, 130, 135});
2672 path.setFillType(SkPath::kWinding_FillType);
2673 canvas->save();
2674 canvas->clipPath(path, SkClipOp::kIntersect);
2675 canvas->drawCircle(70, 85, 60, paint);
2676 canvas->restore();
2677 canvas->translate(100, 100);
2678 path.setFillType(SkPath::kEvenOdd_FillType);
2679 canvas->clipPath(path, SkClipOp::kIntersect);
2680 canvas->drawCircle(70, 85, 60, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002681}
2682##
2683
Cary Clark2ade9972017-11-02 17:49:34 -04002684#SeeAlso clipRect clipRRect clipRegion
Cary Clark8032b982017-07-28 11:04:54 -04002685
2686##
2687
2688#Method void clipPath(const SkPath& path, bool doAntiAlias = false)
2689
2690Replace Clip with the intersection of Clip and path.
Cary Clarkce101242017-09-01 15:51:02 -04002691Resulting Clip is Aliased; pixels are fully contained by the clip.
Cary Clark8032b982017-07-28 11:04:54 -04002692Path_Fill_Type determines if path
2693describes the area inside or outside its contours; and if Path_Contour overlaps
2694itself or another Path_Contour, whether the overlaps form part of the area.
Cary Clarkbad5ad72017-08-03 17:14:08 -04002695path is transformed by Matrix before it is combined with Clip.
Cary Clark8032b982017-07-28 11:04:54 -04002696
Cary Clarkbad5ad72017-08-03 17:14:08 -04002697#Param path Path to combine with Clip ##
Cary Clarkce101242017-09-01 15:51:02 -04002698#Param doAntiAlias true if Clip is to be Anti-aliased ##
Cary Clark8032b982017-07-28 11:04:54 -04002699
2700#Example
2701#Height 212
2702#Description
Cary Clarkbc5697d2017-10-04 14:31:33 -04002703Clip loops over itself covering its center twice. When clip Path_Fill_Type
Cary Clark8032b982017-07-28 11:04:54 -04002704is set to SkPath::kWinding_FillType, the overlap is included. Set to
2705SkPath::kEvenOdd_FillType, the overlap is excluded and forms a hole.
2706##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002707void draw(SkCanvas* canvas) {
2708 SkPaint paint;
2709 paint.setAntiAlias(true);
2710 SkPath path;
2711 SkPoint poly[] = {{20, 20}, { 80, 20}, { 80, 80}, {40, 80},
2712 {40, 40}, {100, 40}, {100, 100}, {20, 100}};
2713 path.addPoly(poly, SK_ARRAY_COUNT(poly), true);
2714 path.setFillType(SkPath::kWinding_FillType);
2715 canvas->save();
2716 canvas->clipPath(path, SkClipOp::kIntersect);
2717 canvas->drawCircle(50, 50, 45, paint);
2718 canvas->restore();
2719 canvas->translate(100, 100);
2720 path.setFillType(SkPath::kEvenOdd_FillType);
2721 canvas->clipPath(path, SkClipOp::kIntersect);
2722 canvas->drawCircle(50, 50, 45, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002723}
2724##
2725
Cary Clark2ade9972017-11-02 17:49:34 -04002726#SeeAlso clipRect clipRRect clipRegion
Cary Clark8032b982017-07-28 11:04:54 -04002727
2728##
2729
2730# ------------------------------------------------------------------------------
2731
2732#Method void setAllowSimplifyClip(bool allow)
2733
2734#Experimental
2735Only used for testing.
2736##
2737
Cary Clarkce101242017-09-01 15:51:02 -04002738Set to simplify clip stack using PathOps.
Cary Clark8032b982017-07-28 11:04:54 -04002739
2740##
2741
2742# ------------------------------------------------------------------------------
2743
2744#Method void clipRegion(const SkRegion& deviceRgn, SkClipOp op = SkClipOp::kIntersect)
2745
2746Replace Clip with the intersection or difference of Clip and Region deviceRgn.
Cary Clarkce101242017-09-01 15:51:02 -04002747Resulting Clip is Aliased; pixels are fully contained by the clip.
Cary Clark8032b982017-07-28 11:04:54 -04002748deviceRgn is unaffected by Matrix.
2749
Cary Clarkbad5ad72017-08-03 17:14:08 -04002750#Param deviceRgn Region to combine with Clip ##
2751#Param op Clip_Op to apply to Clip ##
Cary Clark8032b982017-07-28 11:04:54 -04002752
2753#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04002754#Description
Cary Clarkce101242017-09-01 15:51:02 -04002755 region is unaffected by canvas rotation; iRect is affected by canvas rotation.
2756 Both clips are Aliased; this is not noticeable on Region clip because it
Cary Clarkbad5ad72017-08-03 17:14:08 -04002757 aligns to pixel boundaries.
2758##
2759void draw(SkCanvas* canvas) {
2760 SkPaint paint;
2761 paint.setAntiAlias(true);
2762 SkIRect iRect = {30, 40, 120, 130 };
2763 SkRegion region(iRect);
2764 canvas->rotate(10);
2765 canvas->save();
2766 canvas->clipRegion(region, SkClipOp::kIntersect);
2767 canvas->drawCircle(50, 50, 45, paint);
2768 canvas->restore();
2769 canvas->translate(100, 100);
2770 canvas->clipRect(SkRect::Make(iRect), SkClipOp::kIntersect);
2771 canvas->drawCircle(50, 50, 45, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002772}
2773##
2774
Cary Clark2ade9972017-11-02 17:49:34 -04002775#SeeAlso clipRect clipRRect clipPath
Cary Clark8032b982017-07-28 11:04:54 -04002776
2777##
2778
2779#Method bool quickReject(const SkRect& rect) const
2780
2781Return true if Rect rect, transformed by Matrix, can be quickly determined to be
2782outside of Clip. May return false even though rect is outside of Clip.
2783
2784Use to check if an area to be drawn is clipped out, to skip subsequent draw calls.
2785
Cary Clarkbad5ad72017-08-03 17:14:08 -04002786#Param rect Rect to compare with Clip ##
Cary Clark8032b982017-07-28 11:04:54 -04002787
Cary Clarkbad5ad72017-08-03 17:14:08 -04002788#Return true if rect, transformed by Matrix, does not intersect Clip ##
Cary Clark8032b982017-07-28 11:04:54 -04002789
2790#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04002791void draw(SkCanvas* canvas) {
2792 SkRect testRect = {30, 30, 120, 129 };
2793 SkRect clipRect = {30, 130, 120, 230 };
2794 canvas->save();
2795 canvas->clipRect(clipRect);
2796 SkDebugf("quickReject %s\n", canvas->quickReject(testRect) ? "true" : "false");
2797 canvas->restore();
2798 canvas->rotate(10);
2799 canvas->clipRect(clipRect);
2800 SkDebugf("quickReject %s\n", canvas->quickReject(testRect) ? "true" : "false");
Cary Clark8032b982017-07-28 11:04:54 -04002801}
2802 #StdOut
Cary Clarkbad5ad72017-08-03 17:14:08 -04002803 quickReject true
Cary Clark8032b982017-07-28 11:04:54 -04002804 quickReject false
2805 ##
2806##
2807
Cary Clark2ade9972017-11-02 17:49:34 -04002808#SeeAlso getLocalClipBounds getTotalMatrix SkBitmap::drawsNothing
Cary Clark8032b982017-07-28 11:04:54 -04002809
2810##
2811
2812#Method bool quickReject(const SkPath& path) const
2813
2814Return true if path, transformed by Matrix, can be quickly determined to be
2815outside of Clip. May return false even though path is outside of Clip.
2816
2817Use to check if an area to be drawn is clipped out, to skip subsequent draw calls.
2818
Cary Clarkbad5ad72017-08-03 17:14:08 -04002819#Param path Path to compare with Clip ##
Cary Clark8032b982017-07-28 11:04:54 -04002820
Cary Clarkbad5ad72017-08-03 17:14:08 -04002821#Return true if path, transformed by Matrix, does not intersect Clip ##
Cary Clark8032b982017-07-28 11:04:54 -04002822
2823#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04002824void draw(SkCanvas* canvas) {
2825 SkPoint testPoints[] = {{30, 30}, {120, 30}, {120, 129} };
2826 SkPoint clipPoints[] = {{30, 130}, {120, 130}, {120, 230} };
2827 SkPath testPath, clipPath;
2828 testPath.addPoly(testPoints, SK_ARRAY_COUNT(testPoints), true);
2829 clipPath.addPoly(clipPoints, SK_ARRAY_COUNT(clipPoints), true);
2830 canvas->save();
2831 canvas->clipPath(clipPath);
2832 SkDebugf("quickReject %s\n", canvas->quickReject(testPath) ? "true" : "false");
2833 canvas->restore();
2834 canvas->rotate(10);
2835 canvas->clipPath(clipPath);
2836 SkDebugf("quickReject %s\n", canvas->quickReject(testPath) ? "true" : "false");
Cary Clark8032b982017-07-28 11:04:54 -04002837 #StdOut
Cary Clarkbad5ad72017-08-03 17:14:08 -04002838 quickReject true
Cary Clark8032b982017-07-28 11:04:54 -04002839 quickReject false
2840 ##
2841}
2842##
2843
Cary Clark2ade9972017-11-02 17:49:34 -04002844#SeeAlso getLocalClipBounds getTotalMatrix SkBitmap::drawsNothing
Cary Clark8032b982017-07-28 11:04:54 -04002845
2846##
2847
2848#Method SkRect getLocalClipBounds() const
2849
2850Return bounds of Clip, transformed by inverse of Matrix. If Clip is empty,
2851return SkRect::MakeEmpty, where all Rect sides equal zero.
2852
2853Rect returned is outset by one to account for partial pixel coverage if Clip
Cary Clarkce101242017-09-01 15:51:02 -04002854is Anti-aliased.
Cary Clark8032b982017-07-28 11:04:54 -04002855
Cary Clarkbad5ad72017-08-03 17:14:08 -04002856#Return bounds of Clip in local coordinates ##
Cary Clark8032b982017-07-28 11:04:54 -04002857
2858#Example
2859 #Description
2860 Initial bounds is device bounds outset by 1 on all sides.
2861 Clipped bounds is clipPath bounds outset by 1 on all sides.
2862 Scaling the canvas by two in x and y scales the local bounds by 1/2 in x and y.
2863 ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002864 SkCanvas local(256, 256);
2865 canvas = &local;
2866 SkRect bounds = canvas->getLocalClipBounds();
2867 SkDebugf("left:%g top:%g right:%g bottom:%g\n",
2868 bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom);
2869 SkPoint clipPoints[] = {{30, 130}, {120, 130}, {120, 230} };
2870 SkPath clipPath;
2871 clipPath.addPoly(clipPoints, SK_ARRAY_COUNT(clipPoints), true);
2872 canvas->clipPath(clipPath);
2873 bounds = canvas->getLocalClipBounds();
2874 SkDebugf("left:%g top:%g right:%g bottom:%g\n",
2875 bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom);
2876 canvas->scale(2, 2);
2877 bounds = canvas->getLocalClipBounds();
2878 SkDebugf("left:%g top:%g right:%g bottom:%g\n",
2879 bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom);
2880 #StdOut
2881 left:-1 top:-1 right:257 bottom:257
2882 left:29 top:129 right:121 bottom:231
2883 left:14.5 top:64.5 right:60.5 bottom:115.5
2884 ##
Cary Clark8032b982017-07-28 11:04:54 -04002885##
2886
2887# local canvas in example works around bug in fiddle ##
2888#Bug 6524 ##
Cary Clark2ade9972017-11-02 17:49:34 -04002889#SeeAlso getDeviceClipBounds getBaseLayerSize quickReject
Cary Clark8032b982017-07-28 11:04:54 -04002890
2891##
2892
2893#Method bool getLocalClipBounds(SkRect* bounds) const
2894
2895Return bounds of Clip, transformed by inverse of Matrix. If Clip is empty,
2896return false, and set bounds to SkRect::MakeEmpty, where all Rect sides equal zero.
2897
2898bounds is outset by one to account for partial pixel coverage if Clip
Cary Clarkce101242017-09-01 15:51:02 -04002899is Anti-aliased.
Cary Clark8032b982017-07-28 11:04:54 -04002900
Cary Clarkbad5ad72017-08-03 17:14:08 -04002901#Param bounds Rect of Clip in local coordinates ##
Cary Clark8032b982017-07-28 11:04:54 -04002902
Cary Clarkbad5ad72017-08-03 17:14:08 -04002903#Return true if Clip bounds is not empty ##
Cary Clark8032b982017-07-28 11:04:54 -04002904
2905#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04002906 void draw(SkCanvas* canvas) {
2907 SkCanvas local(256, 256);
2908 canvas = &local;
2909 SkRect bounds;
2910 SkDebugf("local bounds empty = %s\n", canvas->getLocalClipBounds(&bounds)
2911 ? "false" : "true");
2912 SkPath path;
2913 canvas->clipPath(path);
2914 SkDebugf("local bounds empty = %s\n", canvas->getLocalClipBounds(&bounds)
2915 ? "false" : "true");
Cary Clark8032b982017-07-28 11:04:54 -04002916 }
2917 #StdOut
Cary Clarkbad5ad72017-08-03 17:14:08 -04002918 local bounds empty = false
Cary Clark8032b982017-07-28 11:04:54 -04002919 local bounds empty = true
2920 ##
2921##
2922
2923# local canvas in example works around bug in fiddle ##
2924#Bug 6524 ##
Cary Clark2ade9972017-11-02 17:49:34 -04002925#SeeAlso getDeviceClipBounds getBaseLayerSize quickReject
Cary Clark8032b982017-07-28 11:04:54 -04002926
2927##
2928
2929#Method SkIRect getDeviceClipBounds() const
2930
2931Return IRect bounds of Clip, unaffected by Matrix. If Clip is empty,
2932return SkRect::MakeEmpty, where all Rect sides equal zero.
2933
2934Unlike getLocalClipBounds, returned IRect is not outset.
2935
Cary Clarkbad5ad72017-08-03 17:14:08 -04002936#Return bounds of Clip in Device coordinates ##
Cary Clark8032b982017-07-28 11:04:54 -04002937
2938#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04002939void draw(SkCanvas* canvas) {
2940 #Description
Cary Clark8032b982017-07-28 11:04:54 -04002941 Initial bounds is device bounds, not outset.
2942 Clipped bounds is clipPath bounds, not outset.
2943 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 -04002944 ##
2945 SkCanvas device(256, 256);
2946 canvas = &device;
2947 SkIRect bounds = canvas->getDeviceClipBounds();
2948 SkDebugf("left:%d top:%d right:%d bottom:%d\n",
2949 bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom);
2950 SkPoint clipPoints[] = {{30, 130}, {120, 130}, {120, 230} };
2951 SkPath clipPath;
2952 clipPath.addPoly(clipPoints, SK_ARRAY_COUNT(clipPoints), true);
2953 canvas->save();
2954 canvas->clipPath(clipPath);
2955 bounds = canvas->getDeviceClipBounds();
2956 SkDebugf("left:%d top:%d right:%d bottom:%d\n",
2957 bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom);
2958 canvas->restore();
2959 canvas->scale(1.f/2, 1.f/2);
2960 canvas->clipPath(clipPath);
2961 bounds = canvas->getDeviceClipBounds();
2962 SkDebugf("left:%d top:%d right:%d bottom:%d\n",
2963 bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom);
Cary Clark8032b982017-07-28 11:04:54 -04002964 #StdOut
Cary Clarkbad5ad72017-08-03 17:14:08 -04002965 left:0 top:0 right:256 bottom:256
2966 left:30 top:130 right:120 bottom:230
Cary Clark8032b982017-07-28 11:04:54 -04002967 left:15 top:65 right:60 bottom:115
2968 ##
2969}
2970##
2971
2972#ToDo some confusion on why with an identity Matrix local and device are different ##
Cary Clark2ade9972017-11-02 17:49:34 -04002973#SeeAlso getLocalClipBounds getBaseLayerSize quickReject
Cary Clark8032b982017-07-28 11:04:54 -04002974
2975# device canvas in example works around bug in fiddle ##
2976#Bug 6524 ##
2977
2978##
2979
2980#Method bool getDeviceClipBounds(SkIRect* bounds) const
2981
2982Return IRect bounds of Clip, unaffected by Matrix. If Clip is empty,
2983return false, and set bounds to SkRect::MakeEmpty, where all Rect sides equal zero.
2984
2985Unlike getLocalClipBounds, bounds is not outset.
2986
Cary Clarkbad5ad72017-08-03 17:14:08 -04002987#Param bounds Rect of Clip in device coordinates ##
Cary Clark8032b982017-07-28 11:04:54 -04002988
Cary Clarkbad5ad72017-08-03 17:14:08 -04002989#Return true if Clip bounds is not empty ##
Cary Clark8032b982017-07-28 11:04:54 -04002990
2991#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04002992 void draw(SkCanvas* canvas) {
2993 SkIRect bounds;
2994 SkDebugf("device bounds empty = %s\n", canvas->getDeviceClipBounds(&bounds)
2995 ? "false" : "true");
2996 SkPath path;
2997 canvas->clipPath(path);
2998 SkDebugf("device bounds empty = %s\n", canvas->getDeviceClipBounds(&bounds)
2999 ? "false" : "true");
Cary Clark8032b982017-07-28 11:04:54 -04003000 }
3001 #StdOut
Cary Clarkbad5ad72017-08-03 17:14:08 -04003002 device bounds empty = false
Cary Clark8032b982017-07-28 11:04:54 -04003003 device bounds empty = true
3004 ##
3005##
3006
Cary Clark2ade9972017-11-02 17:49:34 -04003007#SeeAlso getLocalClipBounds getBaseLayerSize quickReject
Cary Clark8032b982017-07-28 11:04:54 -04003008
3009##
3010
3011#Topic Clip ##
3012
3013# ------------------------------------------------------------------------------
3014
3015#Method void drawColor(SkColor color, SkBlendMode mode = SkBlendMode::kSrcOver)
3016
3017Fill Clip with Color color.
3018mode determines how Color_ARGB is combined with destination.
3019
Cary Clarkbad5ad72017-08-03 17:14:08 -04003020#Param color Unpremultiplied Color_ARGB ##
3021#Param mode SkBlendMode used to combine source color and destination ##
Cary Clark8032b982017-07-28 11:04:54 -04003022
3023#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003024 canvas->drawColor(SK_ColorRED);
3025 canvas->clipRect(SkRect::MakeWH(150, 150));
3026 canvas->drawColor(SkColorSetARGB(0x80, 0x00, 0xFF, 0x00), SkBlendMode::kPlus);
3027 canvas->clipRect(SkRect::MakeWH(75, 75));
3028 canvas->drawColor(SkColorSetARGB(0x80, 0x00, 0x00, 0xFF), SkBlendMode::kPlus);
Cary Clark8032b982017-07-28 11:04:54 -04003029##
3030
Cary Clark2ade9972017-11-02 17:49:34 -04003031#SeeAlso clear SkBitmap::erase drawPaint
Cary Clark8032b982017-07-28 11:04:54 -04003032
3033##
3034
3035# ------------------------------------------------------------------------------
3036
3037#Method void clear(SkColor color)
3038
3039Fill Clip with Color color using SkBlendMode::kSrc.
3040This has the effect of replacing all pixels contained by Clip with color.
3041
Cary Clarkbad5ad72017-08-03 17:14:08 -04003042#Param color Unpremultiplied Color_ARGB ##
Cary Clark8032b982017-07-28 11:04:54 -04003043
3044#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003045void draw(SkCanvas* canvas) {
3046 canvas->save();
3047 canvas->clipRect(SkRect::MakeWH(256, 128));
3048 canvas->clear(SkColorSetARGB(0x80, 0xFF, 0x00, 0x00));
3049 canvas->restore();
3050 canvas->save();
3051 canvas->clipRect(SkRect::MakeWH(150, 192));
3052 canvas->clear(SkColorSetARGB(0x80, 0x00, 0xFF, 0x00));
3053 canvas->restore();
3054 canvas->clipRect(SkRect::MakeWH(75, 256));
3055 canvas->clear(SkColorSetARGB(0x80, 0x00, 0x00, 0xFF));
Cary Clark8032b982017-07-28 11:04:54 -04003056}
3057##
3058
Cary Clark2ade9972017-11-02 17:49:34 -04003059#SeeAlso drawColor SkBitmap::erase drawPaint
Cary Clark8032b982017-07-28 11:04:54 -04003060
3061##
3062
3063# ------------------------------------------------------------------------------
3064
3065#Method void discard()
3066
3067Make Canvas contents undefined. Subsequent calls that read Canvas pixels,
3068such as drawing with SkBlendMode, return undefined results. discard() does
3069not change Clip or Matrix.
3070
3071discard() may do nothing, depending on the implementation of Surface or Device
3072that created Canvas.
3073
3074discard() allows optimized performance on subsequent draws by removing
3075cached data associated with Surface or Device.
3076It is not necessary to call discard() once done with Canvas;
3077any cached data is deleted when owning Surface or Device is deleted.
3078
3079#ToDo example? not sure how to make this meaningful w/o more implementation detail ##
Cary Clark2ade9972017-11-02 17:49:34 -04003080#SeeAlso flush() SkSurface::prepareForExternalIO GrContext::abandonContext
Cary Clark8032b982017-07-28 11:04:54 -04003081
3082#NoExample
3083##
3084
3085##
3086
3087# ------------------------------------------------------------------------------
3088
3089#Method void drawPaint(const SkPaint& paint)
3090
Cary Clarkbad5ad72017-08-03 17:14:08 -04003091Fill Clip with Paint paint. Paint components Rasterizer, Mask_Filter, Shader,
3092Color_Filter, Image_Filter, and Blend_Mode affect drawing;
3093Path_Effect in paint is ignored.
Cary Clark8032b982017-07-28 11:04:54 -04003094
3095# can Path_Effect in paint ever alter drawPaint?
3096
Cary Clarkbad5ad72017-08-03 17:14:08 -04003097#Param paint graphics state used to fill Canvas ##
Cary Clark8032b982017-07-28 11:04:54 -04003098
3099#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003100void draw(SkCanvas* canvas) {
3101 SkColor colors[] = { SK_ColorRED, SK_ColorGREEN, SK_ColorBLUE };
3102 SkScalar pos[] = { 0, SK_Scalar1/2, SK_Scalar1 };
3103 SkPaint paint;
3104 paint.setShader(SkGradientShader::MakeSweep(256, 256, colors, pos, SK_ARRAY_COUNT(colors)));
3105 canvas->drawPaint(paint);
Cary Clark8032b982017-07-28 11:04:54 -04003106}
3107##
3108
Cary Clark2ade9972017-11-02 17:49:34 -04003109#SeeAlso clear drawColor SkBitmap::erase
Cary Clark8032b982017-07-28 11:04:54 -04003110
3111##
3112
3113# ------------------------------------------------------------------------------
3114
3115#Enum PointMode
3116
3117#Code
3118 enum PointMode {
3119 kPoints_PointMode,
3120 kLines_PointMode,
Cary Clarkd0530ba2017-09-14 11:25:39 -04003121 kPolygon_PointMode,
Cary Clark8032b982017-07-28 11:04:54 -04003122 };
3123##
3124
3125Selects if an array of points are drawn as discrete points, as lines, or as
3126an open polygon.
3127
3128#Const kPoints_PointMode 0
3129 Draw each point separately.
3130##
3131
3132#Const kLines_PointMode 1
3133 Draw each pair of points as a line segment.
3134##
3135
3136#Const kPolygon_PointMode 2
3137 Draw the array of points as a open polygon.
3138##
3139
3140#Example
3141 #Description
3142 The upper left corner shows three squares when drawn as points.
3143 The upper right corner shows one line; when drawn as lines, two points are required per line.
3144 The lower right corner shows two lines; when draw as polygon, no miter is drawn at the corner.
3145 The lower left corner shows two lines with a miter when path contains polygon.
3146 ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003147void draw(SkCanvas* canvas) {
3148 SkPaint paint;
3149 paint.setStyle(SkPaint::kStroke_Style);
3150 paint.setStrokeWidth(10);
3151 SkPoint points[] = {{64, 32}, {96, 96}, {32, 96}};
3152 canvas->drawPoints(SkCanvas::kPoints_PointMode, 3, points, paint);
3153 canvas->translate(128, 0);
3154 canvas->drawPoints(SkCanvas::kLines_PointMode, 3, points, paint);
3155 canvas->translate(0, 128);
3156 canvas->drawPoints(SkCanvas::kPolygon_PointMode, 3, points, paint);
3157 SkPath path;
3158 path.addPoly(points, 3, false);
3159 canvas->translate(-128, 0);
3160 canvas->drawPath(path, paint);
Cary Clark8032b982017-07-28 11:04:54 -04003161}
3162##
3163
Cary Clark2ade9972017-11-02 17:49:34 -04003164#SeeAlso drawLine drawPoint drawPath
Cary Clark8032b982017-07-28 11:04:54 -04003165
3166##
3167
3168# ------------------------------------------------------------------------------
3169
3170#Method void drawPoints(PointMode mode, size_t count, const SkPoint pts[], const SkPaint& paint)
3171
3172Draw pts using Clip, Matrix and Paint paint.
Cary Clarkbad5ad72017-08-03 17:14:08 -04003173count is the number of points; if count is less than one, has no effect.
Cary Clark8032b982017-07-28 11:04:54 -04003174mode may be one of: kPoints_PointMode, kLines_PointMode, or kPolygon_PointMode.
3175
Cary Clarkbad5ad72017-08-03 17:14:08 -04003176If mode is kPoints_PointMode, the shape of point drawn depends on paint
3177Paint_Stroke_Cap. If paint is set to SkPaint::kRound_Cap, each point draws a
3178circle of diameter Paint_Stroke_Width. If paint is set to SkPaint::kSquare_Cap
3179or SkPaint::kButt_Cap, each point draws a square of width and height
3180Paint_Stroke_Width.
Cary Clark8032b982017-07-28 11:04:54 -04003181
3182If mode is kLines_PointMode, each pair of points draws a line segment.
3183One line is drawn for every two points; each point is used once. If count is odd,
3184the final point is ignored.
3185
3186If mode is kPolygon_PointMode, each adjacent pair of points draws a line segment.
3187count minus one lines are drawn; the first and last point are used once.
3188
3189Each line segment respects paint Paint_Stroke_Cap and Paint_Stroke_Width.
3190Paint_Style is ignored, as if were set to SkPaint::kStroke_Style.
3191
Cary Clarkbad5ad72017-08-03 17:14:08 -04003192Always draws each element one at a time; is not affected by
3193Paint_Stroke_Join, and unlike drawPath, does not create a mask from all points
3194and lines before drawing.
Cary Clark8032b982017-07-28 11:04:54 -04003195
Cary Clarka523d2d2017-08-30 08:58:10 -04003196#Param mode whether pts draws points or lines ##
3197#Param count number of points in the array ##
3198#Param pts array of points to draw ##
3199#Param paint stroke, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003200
3201#Example
3202#Height 200
3203 #Description
3204 #List
3205 # The first column draws points. ##
3206 # The second column draws points as lines. ##
3207 # The third column draws points as a polygon. ##
3208 # The fourth column draws points as a polygonal path. ##
3209 # The first row uses a round cap and round join. ##
3210 # The second row uses a square cap and a miter join. ##
3211 # The third row uses a butt cap and a bevel join. ##
3212 ##
3213 The transparent color makes multiple line draws visible;
3214 the path is drawn all at once.
3215 ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003216void draw(SkCanvas* canvas) {
3217 SkPaint paint;
3218 paint.setAntiAlias(true);
3219 paint.setStyle(SkPaint::kStroke_Style);
3220 paint.setStrokeWidth(10);
3221 paint.setColor(0x80349a45);
3222 const SkPoint points[] = {{32, 16}, {48, 48}, {16, 32}};
3223 const SkPaint::Join join[] = { SkPaint::kRound_Join,
3224 SkPaint::kMiter_Join,
3225 SkPaint::kBevel_Join };
3226 int joinIndex = 0;
3227 SkPath path;
3228 path.addPoly(points, 3, false);
3229 for (const auto cap : { SkPaint::kRound_Cap, SkPaint::kSquare_Cap, SkPaint::kButt_Cap } ) {
3230 paint.setStrokeCap(cap);
3231 paint.setStrokeJoin(join[joinIndex++]);
3232 for (const auto mode : { SkCanvas::kPoints_PointMode,
3233 SkCanvas::kLines_PointMode,
3234 SkCanvas::kPolygon_PointMode } ) {
3235 canvas->drawPoints(mode, 3, points, paint);
3236 canvas->translate(64, 0);
3237 }
3238 canvas->drawPath(path, paint);
3239 canvas->translate(-192, 64);
3240 }
Cary Clark8032b982017-07-28 11:04:54 -04003241}
3242##
3243
Cary Clark2ade9972017-11-02 17:49:34 -04003244#SeeAlso drawLine drawPoint drawPath
Cary Clark8032b982017-07-28 11:04:54 -04003245
3246##
3247
3248# ------------------------------------------------------------------------------
3249
3250#Method void drawPoint(SkScalar x, SkScalar y, const SkPaint& paint)
3251
3252Draw point at (x, y) using Clip, Matrix and Paint paint.
3253
3254The shape of point drawn depends on paint Paint_Stroke_Cap.
Cary Clarkbad5ad72017-08-03 17:14:08 -04003255If paint is set to SkPaint::kRound_Cap, draw a circle of diameter
3256Paint_Stroke_Width. If paint is set to SkPaint::kSquare_Cap or SkPaint::kButt_Cap,
Cary Clark8032b982017-07-28 11:04:54 -04003257draw a square of width and height Paint_Stroke_Width.
3258Paint_Style is ignored, as if were set to SkPaint::kStroke_Style.
3259
Cary Clarkbad5ad72017-08-03 17:14:08 -04003260#Param x left edge of circle or square ##
3261#Param y top edge of circle or square ##
3262#Param paint stroke, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003263
3264#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003265void draw(SkCanvas* canvas) {
3266 SkPaint paint;
3267 paint.setAntiAlias(true);
3268 paint.setColor(0x80349a45);
3269 paint.setStyle(SkPaint::kStroke_Style);
3270 paint.setStrokeWidth(100);
3271 paint.setStrokeCap(SkPaint::kRound_Cap);
3272 canvas->scale(1, 1.2f);
3273 canvas->drawPoint(64, 96, paint);
3274 canvas->scale(.6f, .8f);
3275 paint.setColor(SK_ColorWHITE);
3276 canvas->drawPoint(106, 120, paint);
Cary Clark8032b982017-07-28 11:04:54 -04003277}
3278##
3279
Cary Clark2ade9972017-11-02 17:49:34 -04003280#SeeAlso drawPoints drawCircle drawRect drawLine drawPath
Cary Clark8032b982017-07-28 11:04:54 -04003281
3282##
3283
Cary Clarkbad5ad72017-08-03 17:14:08 -04003284#Method void drawPoint(SkPoint p, const SkPaint& paint)
3285
3286Draw point p using Clip, Matrix and Paint paint.
3287
3288The shape of point drawn depends on paint Paint_Stroke_Cap.
3289If paint is set to SkPaint::kRound_Cap, draw a circle of diameter
3290Paint_Stroke_Width. If paint is set to SkPaint::kSquare_Cap or SkPaint::kButt_Cap,
3291draw a square of width and height Paint_Stroke_Width.
3292Paint_Style is ignored, as if were set to SkPaint::kStroke_Style.
3293
3294#Param p top-left edge of circle or square ##
3295#Param paint stroke, blend, color, and so on, used to draw ##
3296
3297#Example
3298void draw(SkCanvas* canvas) {
3299 SkPaint paint;
3300 paint.setAntiAlias(true);
3301 paint.setColor(0x80349a45);
3302 paint.setStyle(SkPaint::kStroke_Style);
3303 paint.setStrokeWidth(100);
3304 paint.setStrokeCap(SkPaint::kSquare_Cap);
3305 canvas->scale(1, 1.2f);
3306 canvas->drawPoint({64, 96}, paint);
3307 canvas->scale(.6f, .8f);
3308 paint.setColor(SK_ColorWHITE);
3309 canvas->drawPoint(106, 120, paint);
3310}
3311##
3312
Cary Clark2ade9972017-11-02 17:49:34 -04003313#SeeAlso drawPoints drawCircle drawRect drawLine drawPath
Cary Clarkbad5ad72017-08-03 17:14:08 -04003314
3315##
3316
Cary Clark8032b982017-07-28 11:04:54 -04003317# ------------------------------------------------------------------------------
3318
3319#Method void drawLine(SkScalar x0, SkScalar y0, SkScalar x1, SkScalar y1, const SkPaint& paint)
3320
Cary Clarkbad5ad72017-08-03 17:14:08 -04003321Draws line segment from (x0, y0) to (x1, y1) using Clip, Matrix, and Paint paint.
3322In paint: Paint_Stroke_Width describes the line thickness;
3323Paint_Stroke_Cap draws the end rounded or square;
Cary Clark8032b982017-07-28 11:04:54 -04003324Paint_Style is ignored, as if were set to SkPaint::kStroke_Style.
3325
Cary Clarkbad5ad72017-08-03 17:14:08 -04003326#Param x0 start of line segment on x-axis ##
3327#Param y0 start of line segment on y-axis ##
3328#Param x1 end of line segment on x-axis ##
3329#Param y1 end of line segment on y-axis ##
3330#Param paint stroke, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003331
3332#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003333 SkPaint paint;
3334 paint.setAntiAlias(true);
3335 paint.setColor(0xFF9a67be);
3336 paint.setStrokeWidth(20);
3337 canvas->skew(1, 0);
3338 canvas->drawLine(32, 96, 32, 160, paint);
3339 canvas->skew(-2, 0);
3340 canvas->drawLine(288, 96, 288, 160, paint);
3341##
3342
Cary Clark2ade9972017-11-02 17:49:34 -04003343#SeeAlso drawPoint drawCircle drawRect drawPath
Cary Clarkbad5ad72017-08-03 17:14:08 -04003344
3345##
3346
3347#Method void drawLine(SkPoint p0, SkPoint p1, const SkPaint& paint)
3348
3349Draws line segment from p0 to p1 using Clip, Matrix, and Paint paint.
3350In paint: Paint_Stroke_Width describes the line thickness;
3351Paint_Stroke_Cap draws the end rounded or square;
3352Paint_Style is ignored, as if were set to SkPaint::kStroke_Style.
3353
3354#Param p0 start of line segment ##
3355#Param p1 end of line segment ##
3356#Param paint stroke, blend, color, and so on, used to draw ##
3357
3358#Example
3359 SkPaint paint;
3360 paint.setAntiAlias(true);
3361 paint.setColor(0xFF9a67be);
3362 paint.setStrokeWidth(20);
3363 canvas->skew(1, 0);
3364 canvas->drawLine({32, 96}, {32, 160}, paint);
3365 canvas->skew(-2, 0);
3366 canvas->drawLine({288, 96}, {288, 160}, paint);
Cary Clark8032b982017-07-28 11:04:54 -04003367##
3368
Cary Clark2ade9972017-11-02 17:49:34 -04003369#SeeAlso drawPoint drawCircle drawRect drawPath
Cary Clark8032b982017-07-28 11:04:54 -04003370
3371##
3372
3373# ------------------------------------------------------------------------------
3374
3375#Method void drawRect(const SkRect& rect, const SkPaint& paint)
3376
3377Draw Rect rect using Clip, Matrix, and Paint paint.
3378In paint: Paint_Style determines if rectangle is stroked or filled;
3379if stroked, Paint_Stroke_Width describes the line thickness, and
3380Paint_Stroke_Join draws the corners rounded or square.
3381
Cary Clarkbc5697d2017-10-04 14:31:33 -04003382#Param rect rectangle to draw ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003383#Param paint stroke or fill, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003384
3385#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003386void draw(SkCanvas* canvas) {
3387 SkPoint rectPts[] = { {64, 48}, {192, 160} };
3388 SkPaint paint;
3389 paint.setAntiAlias(true);
3390 paint.setStyle(SkPaint::kStroke_Style);
3391 paint.setStrokeWidth(20);
3392 paint.setStrokeJoin(SkPaint::kRound_Join);
3393 SkMatrix rotator;
3394 rotator.setRotate(30, 128, 128);
3395 for (auto color : { SK_ColorRED, SK_ColorBLUE, SK_ColorYELLOW, SK_ColorMAGENTA } ) {
3396 paint.setColor(color);
3397 SkRect rect;
3398 rect.set(rectPts[0], rectPts[1]);
3399 canvas->drawRect(rect, paint);
3400 rotator.mapPoints(rectPts, 2);
3401 }
Cary Clark8032b982017-07-28 11:04:54 -04003402}
3403##
3404
Cary Clark2ade9972017-11-02 17:49:34 -04003405#SeeAlso drawIRect drawRRect drawRoundRect drawRegion drawPath drawLine
Cary Clark8032b982017-07-28 11:04:54 -04003406
3407##
3408
3409# ------------------------------------------------------------------------------
3410
3411#Method void drawIRect(const SkIRect& rect, const SkPaint& paint)
3412
3413Draw IRect rect using Clip, Matrix, and Paint paint.
3414In paint: Paint_Style determines if rectangle is stroked or filled;
3415if stroked, Paint_Stroke_Width describes the line thickness, and
3416Paint_Stroke_Join draws the corners rounded or square.
3417
Cary Clarkbc5697d2017-10-04 14:31:33 -04003418#Param rect rectangle to draw ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003419#Param paint stroke or fill, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003420
3421#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003422 SkIRect rect = { 64, 48, 192, 160 };
3423 SkPaint paint;
3424 paint.setAntiAlias(true);
3425 paint.setStyle(SkPaint::kStroke_Style);
3426 paint.setStrokeWidth(20);
3427 paint.setStrokeJoin(SkPaint::kRound_Join);
3428 for (auto color : { SK_ColorRED, SK_ColorBLUE, SK_ColorYELLOW, SK_ColorMAGENTA } ) {
3429 paint.setColor(color);
3430 canvas->drawIRect(rect, paint);
3431 canvas->rotate(30, 128, 128);
3432 }
Cary Clark8032b982017-07-28 11:04:54 -04003433##
3434
Cary Clark2ade9972017-11-02 17:49:34 -04003435#SeeAlso drawRect drawRRect drawRoundRect drawRegion drawPath drawLine
Cary Clark8032b982017-07-28 11:04:54 -04003436
3437##
3438
3439# ------------------------------------------------------------------------------
3440
3441#Method void drawRegion(const SkRegion& region, const SkPaint& paint)
3442
3443Draw Region region using Clip, Matrix, and Paint paint.
3444In paint: Paint_Style determines if rectangle is stroked or filled;
3445if stroked, Paint_Stroke_Width describes the line thickness, and
3446Paint_Stroke_Join draws the corners rounded or square.
3447
Cary Clarkbc5697d2017-10-04 14:31:33 -04003448#Param region region to draw ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003449#Param paint Paint stroke or fill, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003450
3451#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003452void draw(SkCanvas* canvas) {
3453 SkRegion region;
3454 region.op( 10, 10, 50, 50, SkRegion::kUnion_Op);
3455 region.op( 10, 50, 90, 90, SkRegion::kUnion_Op);
3456 SkPaint paint;
3457 paint.setAntiAlias(true);
3458 paint.setStyle(SkPaint::kStroke_Style);
3459 paint.setStrokeWidth(20);
3460 paint.setStrokeJoin(SkPaint::kRound_Join);
3461 canvas->drawRegion(region, paint);
Cary Clark8032b982017-07-28 11:04:54 -04003462}
3463##
3464
Cary Clark2ade9972017-11-02 17:49:34 -04003465#SeeAlso drawRect drawIRect drawPath
Cary Clark8032b982017-07-28 11:04:54 -04003466
3467##
3468
3469# ------------------------------------------------------------------------------
3470
3471#Method void drawOval(const SkRect& oval, const SkPaint& paint)
3472
3473Draw Oval oval using Clip, Matrix, and Paint.
3474In paint: Paint_Style determines if Oval is stroked or filled;
3475if stroked, Paint_Stroke_Width describes the line thickness.
3476
Cary Clarkbad5ad72017-08-03 17:14:08 -04003477#Param oval Rect bounds of Oval ##
3478#Param paint Paint stroke or fill, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003479
3480#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003481void draw(SkCanvas* canvas) {
3482 canvas->clear(0xFF3f5f9f);
3483 SkColor kColor1 = SkColorSetARGB(0xff, 0xff, 0x7f, 0);
3484 SkColor g1Colors[] = { kColor1, SkColorSetA(kColor1, 0x20) };
3485 SkPoint g1Points[] = { { 0, 0 }, { 0, 100 } };
3486 SkScalar pos[] = { 0.2f, 1.0f };
3487 SkRect bounds = SkRect::MakeWH(80, 70);
3488 SkPaint paint;
3489 paint.setAntiAlias(true);
3490 paint.setShader(SkGradientShader::MakeLinear(g1Points, g1Colors, pos, SK_ARRAY_COUNT(g1Colors),
3491 SkShader::kClamp_TileMode));
3492 canvas->drawOval(bounds , paint);
Cary Clark8032b982017-07-28 11:04:54 -04003493}
3494##
3495
Cary Clark2ade9972017-11-02 17:49:34 -04003496#SeeAlso drawCircle drawPoint drawPath drawRRect drawRoundRect
Cary Clark8032b982017-07-28 11:04:54 -04003497
3498##
3499
3500# ------------------------------------------------------------------------------
3501
3502#Method void drawRRect(const SkRRect& rrect, const SkPaint& paint)
3503
3504Draw Round_Rect rrect using Clip, Matrix, and Paint paint.
3505In paint: Paint_Style determines if rrect is stroked or filled;
3506if stroked, Paint_Stroke_Width describes the line thickness.
3507
Cary Clarkbad5ad72017-08-03 17:14:08 -04003508rrect may represent a rectangle, circle, oval, uniformly rounded rectangle, or
3509may have any combination of positive non-square radii for the four corners.
Cary Clark8032b982017-07-28 11:04:54 -04003510
Cary Clarkbad5ad72017-08-03 17:14:08 -04003511#Param rrect Round_Rect with up to eight corner radii to draw ##
3512#Param paint Paint stroke or fill, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003513
3514#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003515void draw(SkCanvas* canvas) {
3516 SkPaint paint;
3517 paint.setAntiAlias(true);
3518 SkRect outer = {30, 40, 210, 220};
3519 SkRect radii = {30, 50, 70, 90 };
3520 SkRRect rRect;
3521 rRect.setNinePatch(outer, radii.fLeft, radii.fTop, radii.fRight, radii.fBottom);
3522 canvas->drawRRect(rRect, paint);
3523 paint.setColor(SK_ColorWHITE);
3524 canvas->drawLine(outer.fLeft + radii.fLeft, outer.fTop,
3525 outer.fLeft + radii.fLeft, outer.fBottom, paint);
3526 canvas->drawLine(outer.fRight - radii.fRight, outer.fTop,
3527 outer.fRight - radii.fRight, outer.fBottom, paint);
3528 canvas->drawLine(outer.fLeft, outer.fTop + radii.fTop,
3529 outer.fRight, outer.fTop + radii.fTop, paint);
3530 canvas->drawLine(outer.fLeft, outer.fBottom - radii.fBottom,
3531 outer.fRight, outer.fBottom - radii.fBottom, paint);
3532}
Cary Clark8032b982017-07-28 11:04:54 -04003533##
3534
Cary Clark2ade9972017-11-02 17:49:34 -04003535#SeeAlso drawRect drawRoundRect drawDRRect drawCircle drawOval drawPath
Cary Clark8032b982017-07-28 11:04:54 -04003536
3537##
3538
3539# ------------------------------------------------------------------------------
3540
3541#Method void drawDRRect(const SkRRect& outer, const SkRRect& inner, const SkPaint& paint)
3542
3543Draw Round_Rect outer and inner
3544using Clip, Matrix, and Paint paint.
3545outer must contain inner or the drawing is undefined.
Cary Clarkce101242017-09-01 15:51:02 -04003546In paint: Paint_Style determines if Round_Rect is stroked or filled;
Cary Clark8032b982017-07-28 11:04:54 -04003547if stroked, Paint_Stroke_Width describes the line thickness.
Cary Clarkbad5ad72017-08-03 17:14:08 -04003548If stroked and Round_Rect corner has zero length radii, Paint_Stroke_Join can
3549draw corners rounded or square.
Cary Clark8032b982017-07-28 11:04:54 -04003550
Cary Clarkbad5ad72017-08-03 17:14:08 -04003551GPU-backed platforms optimize drawing when both outer and inner are
Cary Clark8032b982017-07-28 11:04:54 -04003552concave and outer contains inner. These platforms may not be able to draw
3553Path built with identical data as fast.
3554
Cary Clarkbad5ad72017-08-03 17:14:08 -04003555#Param outer Round_Rect outer bounds to draw ##
3556#Param inner Round_Rect inner bounds to draw ##
3557#Param paint Paint stroke or fill, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003558
3559#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003560void draw(SkCanvas* canvas) {
3561 SkRRect outer = SkRRect::MakeRect({20, 40, 210, 200});
3562 SkRRect inner = SkRRect::MakeOval({60, 70, 170, 160});
3563 SkPaint paint;
3564 canvas->drawDRRect(outer, inner, paint);
Cary Clark8032b982017-07-28 11:04:54 -04003565}
3566##
3567
3568#Example
3569#Description
3570 Outer Rect has no corner radii, but stroke join is rounded.
3571 Inner Round_Rect has corner radii; outset stroke increases radii of corners.
3572 Stroke join does not affect inner Round_Rect since it has no sharp corners.
3573##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003574void draw(SkCanvas* canvas) {
3575 SkRRect outer = SkRRect::MakeRect({20, 40, 210, 200});
3576 SkRRect inner = SkRRect::MakeRectXY({60, 70, 170, 160}, 10, 10);
3577 SkPaint paint;
3578 paint.setAntiAlias(true);
3579 paint.setStyle(SkPaint::kStroke_Style);
3580 paint.setStrokeWidth(20);
3581 paint.setStrokeJoin(SkPaint::kRound_Join);
3582 canvas->drawDRRect(outer, inner, paint);
3583 paint.setStrokeWidth(1);
3584 paint.setColor(SK_ColorWHITE);
3585 canvas->drawDRRect(outer, inner, paint);
Cary Clark8032b982017-07-28 11:04:54 -04003586}
3587##
3588
Cary Clark2ade9972017-11-02 17:49:34 -04003589#SeeAlso drawRect drawRoundRect drawRRect drawCircle drawOval drawPath
Cary Clark8032b982017-07-28 11:04:54 -04003590
3591##
3592
3593# ------------------------------------------------------------------------------
3594
3595#Method void drawCircle(SkScalar cx, SkScalar cy, SkScalar radius, const SkPaint& paint)
3596
3597Draw Circle at (cx, cy) with radius using Clip, Matrix, and Paint paint.
3598If radius is zero or less, nothing is drawn.
3599In paint: Paint_Style determines if Circle is stroked or filled;
3600if stroked, Paint_Stroke_Width describes the line thickness.
3601
Cary Clarkbad5ad72017-08-03 17:14:08 -04003602#Param cx Circle center on the x-axis ##
3603#Param cy Circle center on the y-axis ##
3604#Param radius half the diameter of Circle ##
3605#Param paint Paint stroke or fill, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003606
3607#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003608 void draw(SkCanvas* canvas) {
3609 SkPaint paint;
3610 paint.setAntiAlias(true);
3611 canvas->drawCircle(128, 128, 90, paint);
3612 paint.setColor(SK_ColorWHITE);
3613 canvas->drawCircle(86, 86, 20, paint);
3614 canvas->drawCircle(160, 76, 20, paint);
3615 canvas->drawCircle(140, 150, 35, paint);
3616 }
3617##
3618
Cary Clark2ade9972017-11-02 17:49:34 -04003619#SeeAlso drawOval drawRRect drawRoundRect drawPath drawArc drawPoint drawLine
Cary Clarkbad5ad72017-08-03 17:14:08 -04003620
3621##
3622
3623#Method void drawCircle(SkPoint center, SkScalar radius, const SkPaint& paint)
3624
Cary Clarkce101242017-09-01 15:51:02 -04003625Draw Circle at center with radius using Clip, Matrix, and Paint paint.
Cary Clarkbad5ad72017-08-03 17:14:08 -04003626If radius is zero or less, nothing is drawn.
3627In paint: Paint_Style determines if Circle is stroked or filled;
3628if stroked, Paint_Stroke_Width describes the line thickness.
3629
3630#Param center Circle center ##
3631#Param radius half the diameter of Circle ##
3632#Param paint Paint stroke or fill, blend, color, and so on, used to draw ##
3633
3634#Example
3635 void draw(SkCanvas* canvas) {
3636 SkPaint paint;
3637 paint.setAntiAlias(true);
3638 canvas->drawCircle(128, 128, 90, paint);
3639 paint.setColor(SK_ColorWHITE);
3640 canvas->drawCircle({86, 86}, 20, paint);
3641 canvas->drawCircle({160, 76}, 20, paint);
3642 canvas->drawCircle({140, 150}, 35, paint);
3643 }
Cary Clark8032b982017-07-28 11:04:54 -04003644##
3645
Cary Clark2ade9972017-11-02 17:49:34 -04003646#SeeAlso drawOval drawRRect drawRoundRect drawPath drawArc drawPoint drawLine
Cary Clark8032b982017-07-28 11:04:54 -04003647
3648##
3649
3650# ------------------------------------------------------------------------------
3651
3652#Method void drawArc(const SkRect& oval, SkScalar startAngle, SkScalar sweepAngle,
3653 bool useCenter, const SkPaint& paint)
3654
3655Draw Arc using Clip, Matrix, and Paint paint.
Cary Clarkbad5ad72017-08-03 17:14:08 -04003656
Cary Clark8032b982017-07-28 11:04:54 -04003657Arc is part of Oval bounded by oval, sweeping from startAngle to startAngle plus
3658sweepAngle. startAngle and sweepAngle are in degrees.
Cary Clarkbad5ad72017-08-03 17:14:08 -04003659
Cary Clark8032b982017-07-28 11:04:54 -04003660startAngle of zero places start point at the right middle edge of oval.
3661A positive sweepAngle places Arc end point clockwise from start point;
3662a negative sweepAngle places Arc end point counterclockwise from start point.
3663sweepAngle may exceed 360 degrees, a full circle.
3664If useCenter is true, draw a wedge that includes lines from oval
3665center to Arc end points. If useCenter is false, draw Arc between end points.
3666
3667If Rect oval is empty or sweepAngle is zero, nothing is drawn.
3668
Cary Clarkbad5ad72017-08-03 17:14:08 -04003669#Param oval Rect bounds of Oval containing Arc to draw ##
3670#Param startAngle angle in degrees where Arc begins ##
3671#Param sweepAngle sweep angle in degrees; positive is clockwise ##
3672#Param useCenter if true, include the center of the oval ##
3673#Param paint Paint stroke or fill, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003674
3675#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003676 void draw(SkCanvas* canvas) {
3677 SkPaint paint;
3678 paint.setAntiAlias(true);
3679 SkRect oval = { 4, 4, 60, 60};
3680 for (auto useCenter : { false, true } ) {
3681 for (auto style : { SkPaint::kFill_Style, SkPaint::kStroke_Style } ) {
3682 paint.setStyle(style);
3683 for (auto degrees : { 45, 90, 180, 360} ) {
3684 canvas->drawArc(oval, 0, degrees , useCenter, paint);
3685 canvas->translate(64, 0);
3686 }
3687 canvas->translate(-256, 64);
3688 }
3689 }
Cary Clark8032b982017-07-28 11:04:54 -04003690 }
3691##
3692
3693#Example
3694#Height 64
Cary Clarkbad5ad72017-08-03 17:14:08 -04003695 void draw(SkCanvas* canvas) {
3696 SkPaint paint;
3697 paint.setAntiAlias(true);
3698 paint.setStyle(SkPaint::kStroke_Style);
3699 paint.setStrokeWidth(4);
3700 SkRect oval = { 4, 4, 60, 60};
3701 float intervals[] = { 5, 5 };
3702 paint.setPathEffect(SkDashPathEffect::Make(intervals, 2, 2.5f));
3703 for (auto degrees : { 270, 360, 540, 720 } ) {
3704 canvas->drawArc(oval, 0, degrees, false, paint);
3705 canvas->translate(64, 0);
3706 }
Cary Clark8032b982017-07-28 11:04:54 -04003707 }
3708##
3709
Cary Clark2ade9972017-11-02 17:49:34 -04003710#SeeAlso SkPath::arcTo drawCircle drawOval drawPath
Cary Clark8032b982017-07-28 11:04:54 -04003711
3712##
3713
3714# ------------------------------------------------------------------------------
3715
3716#Method void drawRoundRect(const SkRect& rect, SkScalar rx, SkScalar ry, const SkPaint& paint)
3717
Cary Clarkbad5ad72017-08-03 17:14:08 -04003718Draw Round_Rect bounded by Rect rect, with corner radii (rx, ry) using Clip,
3719Matrix, and Paint paint.
3720
Cary Clark8032b982017-07-28 11:04:54 -04003721In paint: Paint_Style determines if Round_Rect is stroked or filled;
3722if stroked, Paint_Stroke_Width describes the line thickness.
3723If rx or ry are less than zero, they are treated as if they are zero.
3724If rx plus ry exceeds rect width or rect height, radii are scaled down to fit.
Cary Clarkbad5ad72017-08-03 17:14:08 -04003725If rx and ry are zero, Round_Rect is drawn as Rect and if stroked is affected by
3726Paint_Stroke_Join.
Cary Clark8032b982017-07-28 11:04:54 -04003727
Cary Clarkbad5ad72017-08-03 17:14:08 -04003728#Param rect Rect bounds of Round_Rect to draw ##
Cary Clarkce101242017-09-01 15:51:02 -04003729#Param rx axis length in x of oval describing rounded corners ##
3730#Param ry axis length in y of oval describing rounded corners ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003731#Param paint stroke, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003732
3733#Example
3734#Description
3735 Top row has a zero radius a generates a rectangle.
3736 Second row radii sum to less than sides.
3737 Third row radii sum equals sides.
3738 Fourth row radii sum exceeds sides; radii are scaled to fit.
3739##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003740 void draw(SkCanvas* canvas) {
3741 SkVector radii[] = { {0, 20}, {10, 10}, {10, 20}, {10, 40} };
3742 SkPaint paint;
3743 paint.setStrokeWidth(15);
3744 paint.setStrokeJoin(SkPaint::kRound_Join);
3745 paint.setAntiAlias(true);
3746 for (auto style : { SkPaint::kStroke_Style, SkPaint::kFill_Style } ) {
3747 paint.setStyle(style );
3748 for (size_t i = 0; i < SK_ARRAY_COUNT(radii); ++i) {
3749 canvas->drawRoundRect({10, 10, 60, 40}, radii[i].fX, radii[i].fY, paint);
3750 canvas->translate(0, 60);
3751 }
3752 canvas->translate(80, -240);
3753 }
Cary Clark8032b982017-07-28 11:04:54 -04003754 }
3755##
3756
Cary Clark2ade9972017-11-02 17:49:34 -04003757#SeeAlso DrawRRect drawRect drawDRRect drawPath drawCircle drawOval drawPoint
Cary Clark8032b982017-07-28 11:04:54 -04003758
3759##
3760
3761# ------------------------------------------------------------------------------
3762
3763#Method void drawPath(const SkPath& path, const SkPaint& paint)
3764
3765Draw Path path using Clip, Matrix, and Paint paint.
3766Path contains an array of Path_Contour, each of which may be open or closed.
3767
3768In paint: Paint_Style determines if Round_Rect is stroked or filled:
Cary Clarkbad5ad72017-08-03 17:14:08 -04003769if filled, Path_Fill_Type determines whether Path_Contour describes inside or
3770outside of fill; if stroked, Paint_Stroke_Width describes the line thickness,
3771Paint_Stroke_Cap describes line ends, and Paint_Stroke_Join describes how
3772corners are drawn.
Cary Clark8032b982017-07-28 11:04:54 -04003773
Cary Clarkbad5ad72017-08-03 17:14:08 -04003774#Param path Path to draw ##
3775#Param paint stroke, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003776
3777#Example
3778#Description
3779 Top rows draw stroked path with combinations of joins and caps. The open contour
3780 is affected by caps; the closed contour is affected by joins.
3781 Bottom row draws fill the same for open and closed contour.
3782 First bottom column shows winding fills overlap.
3783 Second bottom column shows even odd fills exclude overlap.
3784 Third bottom column shows inverse winding fills area outside both contours.
3785##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003786void draw(SkCanvas* canvas) {
3787 SkPath path;
3788 path.moveTo(20, 20);
3789 path.quadTo(60, 20, 60, 60);
3790 path.close();
3791 path.moveTo(60, 20);
3792 path.quadTo(60, 60, 20, 60);
3793 SkPaint paint;
3794 paint.setStrokeWidth(10);
3795 paint.setAntiAlias(true);
3796 paint.setStyle(SkPaint::kStroke_Style);
3797 for (auto join: { SkPaint::kBevel_Join, SkPaint::kRound_Join, SkPaint::kMiter_Join } ) {
3798 paint.setStrokeJoin(join);
3799 for (auto cap: { SkPaint::kButt_Cap, SkPaint::kSquare_Cap, SkPaint::kRound_Cap } ) {
3800 paint.setStrokeCap(cap);
3801 canvas->drawPath(path, paint);
3802 canvas->translate(80, 0);
3803 }
3804 canvas->translate(-240, 60);
3805 }
3806 paint.setStyle(SkPaint::kFill_Style);
3807 for (auto fill : { SkPath::kWinding_FillType,
3808 SkPath::kEvenOdd_FillType,
3809 SkPath::kInverseWinding_FillType } ) {
3810 path.setFillType(fill);
3811 canvas->save();
3812 canvas->clipRect({0, 10, 80, 70});
3813 canvas->drawPath(path, paint);
3814 canvas->restore();
3815 canvas->translate(80, 0);
3816 }
Cary Clark8032b982017-07-28 11:04:54 -04003817}
3818##
3819
Cary Clark2ade9972017-11-02 17:49:34 -04003820#SeeAlso SkPath drawLine drawArc drawRect drawPoints
Cary Clark8032b982017-07-28 11:04:54 -04003821
3822##
3823
3824# ------------------------------------------------------------------------------
3825#Topic Draw_Image
3826
Cary Clarkbad5ad72017-08-03 17:14:08 -04003827drawImage, drawImageRect, and drawImageNine can be called with a bare pointer or
3828a smart pointer as a convenience. The pairs of calls are otherwise identical.
Cary Clark8032b982017-07-28 11:04:54 -04003829
Cary Clark73fa9722017-08-29 17:36:51 -04003830#Method void drawImage(const SkImage* image, SkScalar left, SkScalar top, const SkPaint* paint = nullptr)
Cary Clark8032b982017-07-28 11:04:54 -04003831
3832Draw Image image, with its top-left corner at (left, top),
3833using Clip, Matrix, and optional Paint paint.
3834
Cary Clarkbad5ad72017-08-03 17:14:08 -04003835If paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter, Blend_Mode,
3836and Draw_Looper. If image is kAlpha_8_SkColorType, apply Shader.
3837If paint contains Mask_Filter, generate mask from image bounds. If generated
3838mask extends beyond image bounds, replicate image edge colors, just as Shader
3839made from SkImage::makeShader with SkShader::kClamp_TileMode set replicates the
Cary Clarkbc5697d2017-10-04 14:31:33 -04003840image edge color when it samples outside of its bounds.
Cary Clark8032b982017-07-28 11:04:54 -04003841
Cary Clarkbad5ad72017-08-03 17:14:08 -04003842#Param image uncompressed rectangular map of pixels ##
3843#Param left left side of image ##
3844#Param top top side of image ##
3845#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
3846 and so on; or nullptr
3847##
Cary Clark8032b982017-07-28 11:04:54 -04003848
3849#Example
3850#Height 64
3851#Image 4
Cary Clarkbad5ad72017-08-03 17:14:08 -04003852void draw(SkCanvas* canvas) {
3853 // sk_sp<SkImage> image;
3854 SkImage* imagePtr = image.get();
3855 canvas->drawImage(imagePtr, 0, 0);
3856 SkPaint paint;
3857 canvas->drawImage(imagePtr, 80, 0, &paint);
3858 paint.setAlpha(0x80);
3859 canvas->drawImage(imagePtr, 160, 0, &paint);
Cary Clark8032b982017-07-28 11:04:54 -04003860}
3861##
3862
Cary Clark2ade9972017-11-02 17:49:34 -04003863#SeeAlso drawBitmap drawImageLattice drawImageNine drawImageRect SkPaint::setImageFilter
Cary Clark8032b982017-07-28 11:04:54 -04003864
3865##
3866
3867# ------------------------------------------------------------------------------
3868
3869#Method void drawImage(const sk_sp<SkImage>& image, SkScalar left, SkScalar top,
Cary Clark73fa9722017-08-29 17:36:51 -04003870 const SkPaint* paint = nullptr)
Cary Clark8032b982017-07-28 11:04:54 -04003871
3872Draw Image image, with its top-left corner at (left, top),
3873using Clip, Matrix, and optional Paint paint.
3874
Cary Clarkbad5ad72017-08-03 17:14:08 -04003875If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
3876Blend_Mode, and Draw_Looper. If image is kAlpha_8_SkColorType, apply Shader.
3877If paint contains Mask_Filter, generate mask from image bounds. If generated
3878mask extends beyond image bounds, replicate image edge colors, just as Shader
3879made from SkImage::makeShader with SkShader::kClamp_TileMode set replicates the
Cary Clarkbc5697d2017-10-04 14:31:33 -04003880image edge color when it samples outside of its bounds.
Cary Clark8032b982017-07-28 11:04:54 -04003881
Cary Clarkbad5ad72017-08-03 17:14:08 -04003882#Param image uncompressed rectangular map of pixels ##
3883#Param left left side of image ##
3884#Param top pop side of image ##
3885#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
3886 and so on; or nullptr
3887##
Cary Clark8032b982017-07-28 11:04:54 -04003888
3889#Example
3890#Height 64
3891#Image 4
Cary Clarkbad5ad72017-08-03 17:14:08 -04003892void draw(SkCanvas* canvas) {
3893 // sk_sp<SkImage> image;
3894 canvas->drawImage(image, 0, 0);
3895 SkPaint paint;
3896 canvas->drawImage(image, 80, 0, &paint);
3897 paint.setAlpha(0x80);
3898 canvas->drawImage(image, 160, 0, &paint);
Cary Clark8032b982017-07-28 11:04:54 -04003899}
3900##
3901
Cary Clark2ade9972017-11-02 17:49:34 -04003902#SeeAlso drawBitmap drawImageLattice drawImageNine drawImageRect SkPaint::setImageFilter
Cary Clark8032b982017-07-28 11:04:54 -04003903
3904##
3905
3906# ------------------------------------------------------------------------------
3907
3908#Enum SrcRectConstraint
3909
3910#Code
3911 enum SrcRectConstraint {
3912 kStrict_SrcRectConstraint,
3913 kFast_SrcRectConstraint,
3914 };
3915##
3916
Cary Clarkce101242017-09-01 15:51:02 -04003917SrcRectConstraint controls the behavior at the edge of source Rect,
3918provided to drawImageRect, trading off speed for precision.
Cary Clark8032b982017-07-28 11:04:54 -04003919
Cary Clarkce101242017-09-01 15:51:02 -04003920Image_Filter in Paint may sample multiple pixels in the image. Source Rect
Cary Clarkbad5ad72017-08-03 17:14:08 -04003921restricts the bounds of pixels that may be read. Image_Filter may slow down if
Cary Clarkce101242017-09-01 15:51:02 -04003922it cannot read outside the bounds, when sampling near the edge of source Rect.
Cary Clark8032b982017-07-28 11:04:54 -04003923SrcRectConstraint specifies whether an Image_Filter is allowed to read pixels
Cary Clarkce101242017-09-01 15:51:02 -04003924outside source Rect.
Cary Clark8032b982017-07-28 11:04:54 -04003925
3926#Const kStrict_SrcRectConstraint
Cary Clarkce101242017-09-01 15:51:02 -04003927 Requires Image_Filter to respect source Rect,
Cary Clark8032b982017-07-28 11:04:54 -04003928 sampling only inside of its bounds, possibly with a performance penalty.
3929##
3930
3931#Const kFast_SrcRectConstraint
Cary Clarkce101242017-09-01 15:51:02 -04003932 Permits Image_Filter to sample outside of source Rect
Cary Clark8032b982017-07-28 11:04:54 -04003933 by half the width of Image_Filter, permitting it to run faster but with
3934 error at the image edges.
3935##
3936
3937#Example
3938#Height 64
3939#Description
3940 redBorder contains a black and white checkerboard bordered by red.
3941 redBorder is drawn scaled by 16 on the left.
Cary Clarkce101242017-09-01 15:51:02 -04003942 The middle and right bitmaps are filtered checkerboards.
Cary Clark8032b982017-07-28 11:04:54 -04003943 Drawing the checkerboard with kStrict_SrcRectConstraint shows only a blur of black and white.
3944 Drawing the checkerboard with kFast_SrcRectConstraint allows red to bleed in the corners.
3945##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003946void draw(SkCanvas* canvas) {
3947 SkBitmap redBorder;
3948 redBorder.allocPixels(SkImageInfo::MakeN32Premul(4, 4));
3949 SkCanvas checkRed(redBorder);
3950 checkRed.clear(SK_ColorRED);
3951 uint32_t checkers[][2] = { { SK_ColorBLACK, SK_ColorWHITE },
3952 { SK_ColorWHITE, SK_ColorBLACK } };
3953 checkRed.writePixels(
3954 SkImageInfo::MakeN32Premul(2, 2), (void*) checkers, sizeof(checkers[0]), 1, 1);
3955 canvas->scale(16, 16);
3956 canvas->drawBitmap(redBorder, 0, 0, nullptr);
3957 canvas->resetMatrix();
3958 sk_sp<SkImage> image = SkImage::MakeFromBitmap(redBorder);
3959 SkPaint lowPaint;
3960 lowPaint.setFilterQuality(kLow_SkFilterQuality);
3961 for (auto constraint : { SkCanvas::kStrict_SrcRectConstraint,
3962 SkCanvas::kFast_SrcRectConstraint } ) {
3963 canvas->translate(80, 0);
3964 canvas->drawImageRect(image.get(), SkRect::MakeLTRB(1, 1, 3, 3),
3965 SkRect::MakeLTRB(16, 16, 48, 48), &lowPaint, constraint);
3966 }
Cary Clark8032b982017-07-28 11:04:54 -04003967}
3968##
3969
Cary Clark2ade9972017-11-02 17:49:34 -04003970#SeeAlso drawImageRect drawImage SkPaint::setImageFilter
Cary Clark8032b982017-07-28 11:04:54 -04003971
3972##
3973
3974# ------------------------------------------------------------------------------
3975
3976#Method void drawImageRect(const SkImage* image, const SkRect& src, const SkRect& dst,
3977 const SkPaint* paint,
3978 SrcRectConstraint constraint = kStrict_SrcRectConstraint)
3979
3980Draw Rect src of Image image, scaled and translated to fill Rect dst.
3981Additionally transform draw using Clip, Matrix, and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04003982
Cary Clarkbad5ad72017-08-03 17:14:08 -04003983If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
3984Blend_Mode, and Draw_Looper. If image is kAlpha_8_SkColorType, apply Shader.
3985If paint contains Mask_Filter, generate mask from image bounds.
3986
3987If generated mask extends beyond image bounds, replicate image edge colors, just
3988as Shader made from SkImage::makeShader with SkShader::kClamp_TileMode set
Cary Clarkbc5697d2017-10-04 14:31:33 -04003989replicates the image edge color when it samples outside of its bounds.
Cary Clarkbad5ad72017-08-03 17:14:08 -04003990
3991constraint set to kStrict_SrcRectConstraint limits Paint Filter_Quality to
3992sample within src; set to kFast_SrcRectConstraint allows sampling outside to
3993improve performance.
3994
3995#Param image Image containing pixels, dimensions, and format ##
3996#Param src source Rect of image to draw from ##
3997#Param dst destination Rect of image to draw to ##
3998#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
3999 and so on; or nullptr
4000##
4001#Param constraint filter strictly within src or draw faster ##
Cary Clark8032b982017-07-28 11:04:54 -04004002
4003#Example
4004#Height 64
4005#Description
4006 The left bitmap draws with Paint default kNone_SkFilterQuality, and stays within
Cary Clarkbc5697d2017-10-04 14:31:33 -04004007 its bounds; there is no bleeding with kFast_SrcRectConstraint.
Cary Clark8032b982017-07-28 11:04:54 -04004008 the middle and right bitmaps draw with kLow_SkFilterQuality; with
4009 kStrict_SrcRectConstraint, the filter remains within the checkerboard, and
4010 with kFast_SrcRectConstraint red bleeds on the edges.
4011##
Cary Clarkbad5ad72017-08-03 17:14:08 -04004012void draw(SkCanvas* canvas) {
4013 uint32_t pixels[][4] = {
4014 { 0xFFFF0000, 0xFFFF0000, 0xFFFF0000, 0xFFFF0000 },
4015 { 0xFFFF0000, 0xFF000000, 0xFFFFFFFF, 0xFFFF0000 },
4016 { 0xFFFF0000, 0xFFFFFFFF, 0xFF000000, 0xFFFF0000 },
4017 { 0xFFFF0000, 0xFFFF0000, 0xFFFF0000, 0xFFFF0000 } };
4018 SkBitmap redBorder;
4019 redBorder.installPixels(SkImageInfo::MakeN32Premul(4, 4),
4020 (void*) pixels, sizeof(pixels[0]));
4021 sk_sp<SkImage> image = SkImage::MakeFromBitmap(redBorder);
4022 SkPaint lowPaint;
4023 for (auto constraint : {
4024 SkCanvas::kFast_SrcRectConstraint,
4025 SkCanvas::kStrict_SrcRectConstraint,
4026 SkCanvas::kFast_SrcRectConstraint } ) {
4027 canvas->drawImageRect(image.get(), SkRect::MakeLTRB(1, 1, 3, 3),
4028 SkRect::MakeLTRB(16, 16, 48, 48), &lowPaint, constraint);
4029 lowPaint.setFilterQuality(kLow_SkFilterQuality);
4030 canvas->translate(80, 0);
4031 }
4032}
Cary Clark8032b982017-07-28 11:04:54 -04004033##
4034
Cary Clark2ade9972017-11-02 17:49:34 -04004035#SeeAlso SrcRectConstraint drawImage drawImageLattice drawImageNine
Cary Clark8032b982017-07-28 11:04:54 -04004036
4037##
4038
4039# ------------------------------------------------------------------------------
4040
4041#Method void drawImageRect(const SkImage* image, const SkIRect& isrc, const SkRect& dst,
4042 const SkPaint* paint, SrcRectConstraint constraint = kStrict_SrcRectConstraint)
4043
4044Draw IRect isrc of Image image, scaled and translated to fill Rect dst.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004045Note that isrc is on integer pixel boundaries; dst may include fractional
4046boundaries. Additionally transform draw using Clip, Matrix, and optional Paint
4047paint.
Cary Clark8032b982017-07-28 11:04:54 -04004048
Cary Clarkbad5ad72017-08-03 17:14:08 -04004049If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4050Blend_Mode, and Draw_Looper. If image is kAlpha_8_SkColorType, apply Shader.
4051If paint contains Mask_Filter, generate mask from image bounds.
4052
4053If generated mask extends beyond image bounds, replicate image edge colors, just
4054as Shader made from SkImage::makeShader with SkShader::kClamp_TileMode set
Cary Clarkbc5697d2017-10-04 14:31:33 -04004055replicates the image edge color when it samples outside of its bounds.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004056
4057constraint set to kStrict_SrcRectConstraint limits Paint Filter_Quality to
Cary Clarkce101242017-09-01 15:51:02 -04004058sample within isrc; set to kFast_SrcRectConstraint allows sampling outside to
Cary Clarkbad5ad72017-08-03 17:14:08 -04004059improve performance.
4060
4061#Param image Image containing pixels, dimensions, and format ##
4062#Param isrc source IRect of image to draw from ##
4063#Param dst destination Rect of image to draw to ##
4064#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4065 and so on; or nullptr
4066##
Cary Clarkce101242017-09-01 15:51:02 -04004067#Param constraint filter strictly within isrc or draw faster ##
Cary Clark8032b982017-07-28 11:04:54 -04004068
4069#Example
4070#Image 4
Cary Clarkbad5ad72017-08-03 17:14:08 -04004071void draw(SkCanvas* canvas) {
4072 // sk_sp<SkImage> image;
4073 for (auto i : { 1, 2, 4, 8 } ) {
4074 canvas->drawImageRect(image.get(), SkIRect::MakeLTRB(0, 0, 100, 100),
4075 SkRect::MakeXYWH(i * 20, i * 20, i * 20, i * 20), nullptr);
4076 }
Cary Clark8032b982017-07-28 11:04:54 -04004077}
4078##
4079
Cary Clark2ade9972017-11-02 17:49:34 -04004080#SeeAlso SrcRectConstraint drawImage drawImageLattice drawImageNine
Cary Clark8032b982017-07-28 11:04:54 -04004081
4082##
4083
4084# ------------------------------------------------------------------------------
4085
4086#Method void drawImageRect(const SkImage* image, const SkRect& dst, const SkPaint* paint,
4087 SrcRectConstraint constraint = kStrict_SrcRectConstraint)
4088
Cary Clarkbad5ad72017-08-03 17:14:08 -04004089Draw Image image, scaled and translated to fill Rect dst, using Clip, Matrix,
4090and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004091
Cary Clarkbad5ad72017-08-03 17:14:08 -04004092If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4093Blend_Mode, and Draw_Looper. If image is kAlpha_8_SkColorType, apply Shader.
4094If paint contains Mask_Filter, generate mask from image bounds.
4095
4096If generated mask extends beyond image bounds, replicate image edge colors, just
4097as Shader made from SkImage::makeShader with SkShader::kClamp_TileMode set
Cary Clarkbc5697d2017-10-04 14:31:33 -04004098replicates the image edge color when it samples outside of its bounds.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004099
4100constraint set to kStrict_SrcRectConstraint limits Paint Filter_Quality to
Cary Clarkce101242017-09-01 15:51:02 -04004101sample within image; set to kFast_SrcRectConstraint allows sampling outside to
Cary Clarkbad5ad72017-08-03 17:14:08 -04004102improve performance.
4103
4104#Param image Image containing pixels, dimensions, and format ##
4105#Param dst destination Rect of image to draw to ##
4106#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4107 and so on; or nullptr
4108##
Cary Clarkce101242017-09-01 15:51:02 -04004109#Param constraint filter strictly within image or draw faster ##
Cary Clark8032b982017-07-28 11:04:54 -04004110
4111#Example
4112#Image 4
Cary Clarkbad5ad72017-08-03 17:14:08 -04004113void draw(SkCanvas* canvas) {
4114 // sk_sp<SkImage> image;
4115 for (auto i : { 20, 40, 80, 160 } ) {
4116 canvas->drawImageRect(image.get(), SkRect::MakeXYWH(i, i, i, i), nullptr);
4117 }
Cary Clark8032b982017-07-28 11:04:54 -04004118}
4119##
4120
Cary Clark2ade9972017-11-02 17:49:34 -04004121#SeeAlso SrcRectConstraint drawImage drawImageLattice drawImageNine
Cary Clark8032b982017-07-28 11:04:54 -04004122
4123##
4124
4125# ------------------------------------------------------------------------------
4126
4127#Method void drawImageRect(const sk_sp<SkImage>& image, const SkRect& src, const SkRect& dst,
4128 const SkPaint* paint,
4129 SrcRectConstraint constraint = kStrict_SrcRectConstraint)
4130
4131Draw Rect src of Image image, scaled and translated to fill Rect dst.
4132Additionally transform draw using Clip, Matrix, and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004133
Cary Clarkbad5ad72017-08-03 17:14:08 -04004134If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4135Blend_Mode, and Draw_Looper. If image is kAlpha_8_SkColorType, apply Shader.
4136If paint contains Mask_Filter, generate mask from image bounds.
4137
4138If generated mask extends beyond image bounds, replicate image edge colors, just
4139as Shader made from SkImage::makeShader with SkShader::kClamp_TileMode set
Cary Clarkbc5697d2017-10-04 14:31:33 -04004140replicates the image edge color when it samples outside of its bounds.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004141
4142constraint set to kStrict_SrcRectConstraint limits Paint Filter_Quality to
4143sample within src; set to kFast_SrcRectConstraint allows sampling outside to
4144improve performance.
4145
4146#Param image Image containing pixels, dimensions, and format ##
4147#Param src source Rect of image to draw from ##
4148#Param dst destination Rect of image to draw to ##
4149#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4150 and so on; or nullptr
4151##
4152#Param constraint filter strictly within src or draw faster ##
Cary Clark8032b982017-07-28 11:04:54 -04004153
4154#Example
4155#Height 64
4156#Description
4157 Canvas scales and translates; transformation from src to dst also scales.
4158 The two matrices are concatenated to create the final transformation.
4159##
Cary Clarkbad5ad72017-08-03 17:14:08 -04004160void draw(SkCanvas* canvas) {
4161 uint32_t pixels[][2] = { { SK_ColorBLACK, SK_ColorWHITE },
4162 { SK_ColorWHITE, SK_ColorBLACK } };
4163 SkBitmap bitmap;
4164 bitmap.installPixels(SkImageInfo::MakeN32Premul(2, 2),
4165 (void*) pixels, sizeof(pixels[0]));
4166 sk_sp<SkImage> image = SkImage::MakeFromBitmap(bitmap);
4167 SkPaint paint;
4168 canvas->scale(4, 4);
4169 for (auto alpha : { 50, 100, 150, 255 } ) {
4170 paint.setAlpha(alpha);
4171 canvas->drawImageRect(image, SkRect::MakeWH(2, 2), SkRect::MakeWH(8, 8), &paint);
4172 canvas->translate(8, 0);
4173 }
4174}
Cary Clark8032b982017-07-28 11:04:54 -04004175##
4176
Cary Clark2ade9972017-11-02 17:49:34 -04004177#SeeAlso SrcRectConstraint drawImage drawImageLattice drawImageNine
Cary Clark8032b982017-07-28 11:04:54 -04004178
4179##
4180
4181# ------------------------------------------------------------------------------
4182
4183#Method void drawImageRect(const sk_sp<SkImage>& image, const SkIRect& isrc, const SkRect& dst,
4184 const SkPaint* paint, SrcRectConstraint constraint = kStrict_SrcRectConstraint)
4185
4186Draw IRect isrc of Image image, scaled and translated to fill Rect dst.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004187isrc is on integer pixel boundaries; dst may include fractional boundaries.
Cary Clark8032b982017-07-28 11:04:54 -04004188Additionally transform draw using Clip, Matrix, and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004189
Cary Clarkbad5ad72017-08-03 17:14:08 -04004190If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4191Blend_Mode, and Draw_Looper. If image is kAlpha_8_SkColorType, apply Shader.
4192If paint contains Mask_Filter, generate mask from image bounds.
4193
4194If generated mask extends beyond image bounds, replicate image edge colors, just
4195as Shader made from SkImage::makeShader with SkShader::kClamp_TileMode set
Cary Clarkbc5697d2017-10-04 14:31:33 -04004196replicates the image edge color when it samples outside of its bounds.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004197
4198constraint set to kStrict_SrcRectConstraint limits Paint Filter_Quality to
Cary Clarkce101242017-09-01 15:51:02 -04004199sample within image; set to kFast_SrcRectConstraint allows sampling outside to
Cary Clarkbad5ad72017-08-03 17:14:08 -04004200improve performance.
4201
4202#Param image Image containing pixels, dimensions, and format ##
4203#Param isrc source IRect of image to draw from ##
4204#Param dst destination Rect of image to draw to ##
4205#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4206 and so on; or nullptr
4207##
Cary Clarkce101242017-09-01 15:51:02 -04004208#Param constraint filter strictly within image or draw faster ##
Cary Clark8032b982017-07-28 11:04:54 -04004209
4210#Example
4211#Height 64
Cary Clarkbad5ad72017-08-03 17:14:08 -04004212void draw(SkCanvas* canvas) {
4213 uint32_t pixels[][2] = { { 0x00000000, 0x55555555},
4214 { 0xAAAAAAAA, 0xFFFFFFFF} };
4215 SkBitmap bitmap;
4216 bitmap.installPixels(SkImageInfo::MakeN32Premul(2, 2),
4217 (void*) pixels, sizeof(pixels[0]));
4218 sk_sp<SkImage> image = SkImage::MakeFromBitmap(bitmap);
4219 SkPaint paint;
4220 canvas->scale(4, 4);
4221 for (auto color : { SK_ColorRED, SK_ColorBLUE, SK_ColorGREEN } ) {
4222 paint.setColorFilter(SkColorFilter::MakeModeFilter(color, SkBlendMode::kPlus));
4223 canvas->drawImageRect(image, SkIRect::MakeWH(2, 2), SkRect::MakeWH(8, 8), &paint);
4224 canvas->translate(8, 0);
4225 }
Cary Clark8032b982017-07-28 11:04:54 -04004226}
4227##
4228
Cary Clark2ade9972017-11-02 17:49:34 -04004229#SeeAlso SrcRectConstraint drawImage drawImageLattice drawImageNine
4230
Cary Clark8032b982017-07-28 11:04:54 -04004231##
4232
4233# ------------------------------------------------------------------------------
4234
4235#Method void drawImageRect(const sk_sp<SkImage>& image, const SkRect& dst, const SkPaint* paint,
4236 SrcRectConstraint constraint = kStrict_SrcRectConstraint)
4237
4238Draw Image image, scaled and translated to fill Rect dst,
4239using Clip, Matrix, and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004240
Cary Clarkbad5ad72017-08-03 17:14:08 -04004241If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4242Blend_Mode, and Draw_Looper. If image is kAlpha_8_SkColorType, apply Shader.
4243If paint contains Mask_Filter, generate mask from image bounds.
4244
4245If generated mask extends beyond image bounds, replicate image edge colors, just
4246as Shader made from SkImage::makeShader with SkShader::kClamp_TileMode set
Cary Clarkbc5697d2017-10-04 14:31:33 -04004247replicates the image edge color when it samples outside of its bounds.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004248
4249constraint set to kStrict_SrcRectConstraint limits Paint Filter_Quality to
Cary Clarkce101242017-09-01 15:51:02 -04004250sample within image; set to kFast_SrcRectConstraint allows sampling outside to
Cary Clarkbad5ad72017-08-03 17:14:08 -04004251improve performance.
4252
4253#Param image Image containing pixels, dimensions, and format ##
4254#Param dst destination Rect of image to draw to ##
4255#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4256 and so on; or nullptr
4257##
Cary Clarkce101242017-09-01 15:51:02 -04004258#Param constraint filter strictly within image or draw faster ##
Cary Clark8032b982017-07-28 11:04:54 -04004259
4260#Example
4261#Height 64
Cary Clarkbad5ad72017-08-03 17:14:08 -04004262void draw(SkCanvas* canvas) {
4263 uint32_t pixels[][2] = { { 0x00000000, 0x55550000},
4264 { 0xAAAA0000, 0xFFFF0000} };
4265 SkBitmap bitmap;
4266 bitmap.installPixels(SkImageInfo::MakeN32Premul(2, 2),
4267 (void*) pixels, sizeof(pixels[0]));
4268 sk_sp<SkImage> image = SkImage::MakeFromBitmap(bitmap);
4269 SkPaint paint;
4270 canvas->scale(4, 4);
4271 for (auto color : { SK_ColorRED, SK_ColorBLUE, SK_ColorGREEN } ) {
4272 paint.setColorFilter(SkColorFilter::MakeModeFilter(color, SkBlendMode::kPlus));
4273 canvas->drawImageRect(image, SkRect::MakeWH(8, 8), &paint);
4274 canvas->translate(8, 0);
4275 }
Cary Clark8032b982017-07-28 11:04:54 -04004276}
4277##
4278
Cary Clark2ade9972017-11-02 17:49:34 -04004279#SeeAlso SrcRectConstraint drawImage drawImageLattice drawImageNine
Cary Clark8032b982017-07-28 11:04:54 -04004280
4281##
4282
4283# ------------------------------------------------------------------------------
4284
4285#Method void drawImageNine(const SkImage* image, const SkIRect& center, const SkRect& dst,
4286 const SkPaint* paint = nullptr)
4287
Cary Clarkd0530ba2017-09-14 11:25:39 -04004288Draw Image image stretched proportionally to fit into Rect dst.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004289IRect center divides the image into nine sections: four sides, four corners, and
Cary Clarkce101242017-09-01 15:51:02 -04004290the center. Corners are unmodified or scaled down proportionately if their sides
Cary Clarkbad5ad72017-08-03 17:14:08 -04004291are larger than dst; center and four sides are scaled to fit remaining space, if any.
Cary Clark8032b982017-07-28 11:04:54 -04004292
Cary Clarkbad5ad72017-08-03 17:14:08 -04004293Additionally transform draw using Clip, Matrix, and optional Paint paint.
4294
4295If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4296Blend_Mode, and Draw_Looper. If image is kAlpha_8_SkColorType, apply Shader.
4297If paint contains Mask_Filter, generate mask from image bounds.
4298
4299If generated mask extends beyond image bounds, replicate image edge colors, just
4300as Shader made from SkImage::makeShader with SkShader::kClamp_TileMode set
Cary Clarkbc5697d2017-10-04 14:31:33 -04004301replicates the image edge color when it samples outside of its bounds.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004302
4303#Param image Image containing pixels, dimensions, and format ##
4304#Param center IRect edge of image corners and sides ##
4305#Param dst destination Rect of image to draw to ##
4306#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4307 and so on; or nullptr
4308##
Cary Clark8032b982017-07-28 11:04:54 -04004309
4310#Example
4311#Height 128
4312#Description
4313 The leftmost image is smaller than center; only corners are drawn, all scaled to fit.
Cary Clarkce101242017-09-01 15:51:02 -04004314 The second image equals the size of center; only corners are drawn without scaling.
4315 The remaining images are larger than center. All corners draw without scaling.
4316 The sides and center are scaled if needed to take up the remaining space.
Cary Clark8032b982017-07-28 11:04:54 -04004317##
Cary Clarkbad5ad72017-08-03 17:14:08 -04004318void draw(SkCanvas* canvas) {
4319 SkIRect center = { 20, 10, 50, 40 };
4320 SkBitmap bitmap;
4321 bitmap.allocPixels(SkImageInfo::MakeN32Premul(60, 60));
4322 SkCanvas bitCanvas(bitmap);
4323 SkPaint paint;
4324 SkColor gray = 0xFF000000;
4325 int left = 0;
4326 for (auto right: { center.fLeft, center.fRight, bitmap.width() } ) {
4327 int top = 0;
4328 for (auto bottom: { center.fTop, center.fBottom, bitmap.height() } ) {
4329 paint.setColor(gray);
4330 bitCanvas.drawIRect(SkIRect::MakeLTRB(left, top, right, bottom), paint);
4331 gray += 0x001f1f1f;
4332 top = bottom;
4333 }
4334 left = right;
4335 }
4336 sk_sp<SkImage> image = SkImage::MakeFromBitmap(bitmap);
4337 SkImage* imagePtr = image.get();
4338 for (auto dest: { 20, 30, 40, 60, 90 } ) {
4339 canvas->drawImageNine(imagePtr, center, SkRect::MakeWH(dest, dest), nullptr);
4340 canvas->translate(dest + 4, 0);
4341 }
Cary Clark8032b982017-07-28 11:04:54 -04004342}
4343##
4344
Cary Clark2ade9972017-11-02 17:49:34 -04004345#SeeAlso drawImage drawBitmapNine drawImageLattice drawImageRect
Cary Clark8032b982017-07-28 11:04:54 -04004346
4347##
4348
4349# ------------------------------------------------------------------------------
4350
4351#Method void drawImageNine(const sk_sp<SkImage>& image, const SkIRect& center, const SkRect& dst,
4352 const SkPaint* paint = nullptr)
4353
Cary Clarkd0530ba2017-09-14 11:25:39 -04004354Draw Image image stretched proportionally to fit into Rect dst.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004355IRect center divides the image into nine sections: four sides, four corners, and
Cary Clarkce101242017-09-01 15:51:02 -04004356the center. Corners are not scaled, or scaled down proportionately if their sides
Cary Clarkbad5ad72017-08-03 17:14:08 -04004357are larger than dst; center and four sides are scaled to fit remaining space, if any.
Cary Clark8032b982017-07-28 11:04:54 -04004358
Cary Clarkbad5ad72017-08-03 17:14:08 -04004359Additionally transform draw using Clip, Matrix, and optional Paint paint.
4360
4361If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4362Blend_Mode, and Draw_Looper. If image is kAlpha_8_SkColorType, apply Shader.
4363If paint contains Mask_Filter, generate mask from image bounds.
4364
4365If generated mask extends beyond image bounds, replicate image edge colors, just
4366as Shader made from SkImage::makeShader with SkShader::kClamp_TileMode set
Cary Clarkbc5697d2017-10-04 14:31:33 -04004367replicates the image edge color when it samples outside of its bounds.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004368
4369#Param image Image containing pixels, dimensions, and format ##
4370#Param center IRect edge of image corners and sides ##
4371#Param dst destination Rect of image to draw to ##
4372#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4373 and so on; or nullptr
4374##
Cary Clark8032b982017-07-28 11:04:54 -04004375
4376#Example
4377#Height 128
4378#Description
4379 The two leftmost images has four corners and sides to the left and right of center.
4380 The leftmost image scales the width of corners proportionately to fit.
Cary Clarkce101242017-09-01 15:51:02 -04004381 The third and fourth image corners are not scaled; the sides and center are scaled to
Cary Clark8032b982017-07-28 11:04:54 -04004382 fill the remaining space.
4383 The rightmost image has four corners scaled vertically to fit, and uses sides above
4384 and below center to fill the remaining space.
4385##
Cary Clarkbad5ad72017-08-03 17:14:08 -04004386void draw(SkCanvas* canvas) {
4387 SkIRect center = { 20, 10, 50, 40 };
4388 SkBitmap bitmap;
4389 bitmap.allocPixels(SkImageInfo::MakeN32Premul(60, 60));
4390 SkCanvas bitCanvas(bitmap);
4391 SkPaint paint;
4392 SkColor gray = 0xFF000000;
4393 int left = 0;
4394 for (auto right: { center.fLeft, center.fRight, bitmap.width() } ) {
4395 int top = 0;
4396 for (auto bottom: { center.fTop, center.fBottom, bitmap.height() } ) {
4397 paint.setColor(gray);
4398 bitCanvas.drawIRect(SkIRect::MakeLTRB(left, top, right, bottom), paint);
4399 gray += 0x001f1f1f;
4400 top = bottom;
4401 }
4402 left = right;
4403 }
4404 sk_sp<SkImage> image = SkImage::MakeFromBitmap(bitmap);
4405 for (auto dest: { 20, 30, 40, 60, 90 } ) {
4406 canvas->drawImageNine(image, center, SkRect::MakeWH(dest, 110 - dest), nullptr);
4407 canvas->translate(dest + 4, 0);
4408 }
Cary Clark8032b982017-07-28 11:04:54 -04004409}
4410##
4411
Cary Clark2ade9972017-11-02 17:49:34 -04004412#SeeAlso drawImage drawBitmapNine drawImageLattice drawImageRect
Cary Clark8032b982017-07-28 11:04:54 -04004413
4414##
4415
4416# ------------------------------------------------------------------------------
4417
4418#Method void drawBitmap(const SkBitmap& bitmap, SkScalar left, SkScalar top,
Cary Clark73fa9722017-08-29 17:36:51 -04004419 const SkPaint* paint = nullptr)
Cary Clark8032b982017-07-28 11:04:54 -04004420
4421Draw Bitmap bitmap, with its top-left corner at (left, top),
4422using Clip, Matrix, and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004423
Cary Clarkbad5ad72017-08-03 17:14:08 -04004424If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4425Blend_Mode, and Draw_Looper. If bitmap is kAlpha_8_SkColorType, apply Shader.
4426If paint contains Mask_Filter, generate mask from bitmap bounds.
4427
4428If generated mask extends beyond bitmap bounds, replicate bitmap edge colors,
4429just as Shader made from SkShader::MakeBitmapShader with
Cary Clarkbc5697d2017-10-04 14:31:33 -04004430SkShader::kClamp_TileMode set replicates the bitmap edge color when it samples
Cary Clarkbad5ad72017-08-03 17:14:08 -04004431outside of its bounds.
4432
4433#Param bitmap Bitmap containing pixels, dimensions, and format ##
4434#Param left left side of bitmap ##
4435#Param top top side of bitmap ##
4436#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4437 and so on; or nullptr
4438##
Cary Clark8032b982017-07-28 11:04:54 -04004439
4440#Example
4441#Height 64
Cary Clarkbad5ad72017-08-03 17:14:08 -04004442void draw(SkCanvas* canvas) {
4443 uint8_t pixels[][8] = { { 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00},
4444 { 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00},
4445 { 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00},
4446 { 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF},
4447 { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
4448 { 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00},
4449 { 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0x00},
4450 { 0xFF, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0xFF} };
4451 SkBitmap bitmap;
4452 bitmap.installPixels(SkImageInfo::MakeA8(8, 8),
4453 (void*) pixels, sizeof(pixels[0]));
4454 SkPaint paint;
4455 canvas->scale(4, 4);
4456 for (auto color : { SK_ColorRED, SK_ColorBLUE, 0xFF007F00} ) {
4457 paint.setColor(color);
4458 canvas->drawBitmap(bitmap, 0, 0, &paint);
4459 canvas->translate(12, 0);
4460 }
Cary Clark8032b982017-07-28 11:04:54 -04004461}
4462##
4463
Cary Clark2ade9972017-11-02 17:49:34 -04004464#SeeAlso drawImage drawBitmapLattice drawBitmapNine drawBitmapRect SkBitmap::readPixels SkBitmap::writePixels
Cary Clark8032b982017-07-28 11:04:54 -04004465
4466##
4467
4468# ------------------------------------------------------------------------------
4469
4470#Method void drawBitmapRect(const SkBitmap& bitmap, const SkRect& src, const SkRect& dst,
4471 const SkPaint* paint, SrcRectConstraint constraint = kStrict_SrcRectConstraint)
4472
4473Draw Rect src of Bitmap bitmap, scaled and translated to fill Rect dst.
4474Additionally transform draw using Clip, Matrix, and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004475
Cary Clarkbad5ad72017-08-03 17:14:08 -04004476If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4477Blend_Mode, and Draw_Looper. If bitmap is kAlpha_8_SkColorType, apply Shader.
4478If paint contains Mask_Filter, generate mask from bitmap bounds.
4479
4480If generated mask extends beyond bitmap bounds, replicate bitmap edge colors,
4481just as Shader made from SkShader::MakeBitmapShader with
Cary Clarkbc5697d2017-10-04 14:31:33 -04004482SkShader::kClamp_TileMode set replicates the bitmap edge color when it samples
Cary Clarkbad5ad72017-08-03 17:14:08 -04004483outside of its bounds.
4484
4485constraint set to kStrict_SrcRectConstraint limits Paint Filter_Quality to
4486sample within src; set to kFast_SrcRectConstraint allows sampling outside to
4487improve performance.
4488
4489#Param bitmap Bitmap containing pixels, dimensions, and format ##
4490#Param src source Rect of image to draw from ##
4491#Param dst destination Rect of image to draw to ##
4492#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4493 and so on; or nullptr
4494##
4495#Param constraint filter strictly within src or draw faster ##
Cary Clark8032b982017-07-28 11:04:54 -04004496
4497#Example
4498#Height 64
Cary Clarkbad5ad72017-08-03 17:14:08 -04004499void draw(SkCanvas* canvas) {
4500 uint8_t pixels[][8] = { { 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00},
4501 { 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00},
4502 { 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00},
4503 { 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF},
4504 { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
4505 { 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00},
4506 { 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00},
4507 { 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00} };
4508 SkBitmap bitmap;
4509 bitmap.installPixels(SkImageInfo::MakeA8(8, 8),
4510 (void*) pixels, sizeof(pixels[0]));
4511 SkPaint paint;
4512 paint.setMaskFilter(SkBlurMaskFilter::Make(kSolid_SkBlurStyle, 6));
4513 for (auto color : { SK_ColorRED, SK_ColorBLUE, 0xFF007F00} ) {
4514 paint.setColor(color);
4515 canvas->drawBitmapRect(bitmap, SkRect::MakeWH(8, 8), SkRect::MakeWH(32, 32), &paint);
4516 canvas->translate(48, 0);
4517 }
Cary Clark8032b982017-07-28 11:04:54 -04004518}
4519##
4520
Cary Clark2ade9972017-11-02 17:49:34 -04004521#SeeAlso drawImageRect drawBitmap drawBitmapLattice drawBitmapNine
Cary Clark8032b982017-07-28 11:04:54 -04004522
4523##
4524
4525# ------------------------------------------------------------------------------
4526
4527#Method void drawBitmapRect(const SkBitmap& bitmap, const SkIRect& isrc, const SkRect& dst,
4528 const SkPaint* paint, SrcRectConstraint constraint = kStrict_SrcRectConstraint)
4529
4530Draw IRect isrc of Bitmap bitmap, scaled and translated to fill Rect dst.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004531isrc is on integer pixel boundaries; dst may include fractional boundaries.
Cary Clark8032b982017-07-28 11:04:54 -04004532Additionally transform draw using Clip, Matrix, and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004533
Cary Clarkbad5ad72017-08-03 17:14:08 -04004534If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4535Blend_Mode, and Draw_Looper. If bitmap is kAlpha_8_SkColorType, apply Shader.
4536If paint contains Mask_Filter, generate mask from bitmap bounds.
4537
4538If generated mask extends beyond bitmap bounds, replicate bitmap edge colors,
4539just as Shader made from SkShader::MakeBitmapShader with
Cary Clarkbc5697d2017-10-04 14:31:33 -04004540SkShader::kClamp_TileMode set replicates the bitmap edge color when it samples
Cary Clarkbad5ad72017-08-03 17:14:08 -04004541outside of its bounds.
4542
4543constraint set to kStrict_SrcRectConstraint limits Paint Filter_Quality to
Cary Clarkce101242017-09-01 15:51:02 -04004544sample within isrc; set to kFast_SrcRectConstraint allows sampling outside to
Cary Clarkbad5ad72017-08-03 17:14:08 -04004545improve performance.
4546
4547#Param bitmap Bitmap containing pixels, dimensions, and format ##
4548#Param isrc source IRect of image to draw from ##
4549#Param dst destination Rect of image to draw to ##
4550#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4551 and so on; or nullptr
4552##
Cary Clarkce101242017-09-01 15:51:02 -04004553#Param constraint sample strictly within isrc, or draw faster ##
Cary Clark8032b982017-07-28 11:04:54 -04004554
4555#Example
4556#Height 64
Cary Clarkbad5ad72017-08-03 17:14:08 -04004557void draw(SkCanvas* canvas) {
4558 uint8_t pixels[][8] = { { 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00},
4559 { 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00},
4560 { 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0xFF},
4561 { 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0xFF},
4562 { 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF},
4563 { 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF},
4564 { 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00},
4565 { 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00} };
4566 SkBitmap bitmap;
4567 bitmap.installPixels(SkImageInfo::MakeA8(8, 8),
4568 (void*) pixels, sizeof(pixels[0]));
4569 SkPaint paint;
4570 paint.setFilterQuality(kHigh_SkFilterQuality);
4571 for (auto color : { SK_ColorRED, SK_ColorBLUE, 0xFF007F00, 0xFF7f007f} ) {
4572 paint.setColor(color);
4573 canvas->drawBitmapRect(bitmap, SkIRect::MakeWH(8, 8), SkRect::MakeWH(32, 32), &paint);
4574 canvas->translate(48.25f, 0);
4575 }
Cary Clark8032b982017-07-28 11:04:54 -04004576}
4577##
4578
Cary Clark2ade9972017-11-02 17:49:34 -04004579#SeeAlso drawImageRect drawBitmap drawBitmapLattice drawBitmapNine
Cary Clark8032b982017-07-28 11:04:54 -04004580
4581##
4582
4583# ------------------------------------------------------------------------------
4584
4585#Method void drawBitmapRect(const SkBitmap& bitmap, const SkRect& dst, const SkPaint* paint,
4586 SrcRectConstraint constraint = kStrict_SrcRectConstraint)
4587
4588Draw Bitmap bitmap, scaled and translated to fill Rect dst.
Cary Clarkce101242017-09-01 15:51:02 -04004589bitmap bounds is on integer pixel boundaries; dst may include fractional boundaries.
Cary Clark8032b982017-07-28 11:04:54 -04004590Additionally transform draw using Clip, Matrix, and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004591
Cary Clarkbad5ad72017-08-03 17:14:08 -04004592If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4593Blend_Mode, and Draw_Looper. If bitmap is kAlpha_8_SkColorType, apply Shader.
4594If paint contains Mask_Filter, generate mask from bitmap bounds.
4595
4596If generated mask extends beyond bitmap bounds, replicate bitmap edge colors,
4597just as Shader made from SkShader::MakeBitmapShader with
Cary Clarkbc5697d2017-10-04 14:31:33 -04004598SkShader::kClamp_TileMode set replicates the bitmap edge color when it samples
Cary Clarkbad5ad72017-08-03 17:14:08 -04004599outside of its bounds.
4600
4601constraint set to kStrict_SrcRectConstraint limits Paint Filter_Quality to
Cary Clarkce101242017-09-01 15:51:02 -04004602sample within bitmap; set to kFast_SrcRectConstraint allows sampling outside to
Cary Clarkbad5ad72017-08-03 17:14:08 -04004603improve performance.
4604
4605#Param bitmap Bitmap containing pixels, dimensions, and format ##
4606#Param dst destination Rect of image to draw to ##
4607#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4608 and so on; or nullptr
4609##
Cary Clarkce101242017-09-01 15:51:02 -04004610#Param constraint filter strictly within bitmap or draw faster ##
Cary Clark8032b982017-07-28 11:04:54 -04004611
4612#Example
4613#Height 64
Cary Clarkbad5ad72017-08-03 17:14:08 -04004614void draw(SkCanvas* canvas) {
4615 uint32_t pixels[][2] = { { 0x00000000, 0x55550000},
4616 { 0xAAAA0000, 0xFFFF0000} };
4617 SkBitmap bitmap;
4618 bitmap.installPixels(SkImageInfo::MakeN32Premul(2, 2),
4619 (void*) pixels, sizeof(pixels[0]));
4620 SkPaint paint;
4621 canvas->scale(4, 4);
4622 for (auto color : { SK_ColorRED, SK_ColorBLUE, SK_ColorGREEN } ) {
4623 paint.setColorFilter(SkColorFilter::MakeModeFilter(color, SkBlendMode::kPlus));
4624 canvas->drawBitmapRect(bitmap, SkRect::MakeWH(8, 8), &paint);
4625 canvas->translate(8, 0);
4626 }
Cary Clark8032b982017-07-28 11:04:54 -04004627}
4628##
4629
Cary Clark2ade9972017-11-02 17:49:34 -04004630#SeeAlso drawImageRect drawBitmap drawBitmapLattice drawBitmapNine
Cary Clark8032b982017-07-28 11:04:54 -04004631
4632##
4633
4634# ------------------------------------------------------------------------------
4635
4636#Method void drawBitmapNine(const SkBitmap& bitmap, const SkIRect& center, const SkRect& dst,
Cary Clark73fa9722017-08-29 17:36:51 -04004637 const SkPaint* paint = nullptr)
Cary Clark8032b982017-07-28 11:04:54 -04004638
Cary Clarkd0530ba2017-09-14 11:25:39 -04004639Draw Bitmap bitmap stretched proportionally to fit into Rect dst.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004640IRect center divides the bitmap into nine sections: four sides, four corners,
Cary Clarkce101242017-09-01 15:51:02 -04004641and the center. Corners are not scaled, or scaled down proportionately if their
Cary Clarkbad5ad72017-08-03 17:14:08 -04004642sides are larger than dst; center and four sides are scaled to fit remaining
4643space, if any.
Cary Clark8032b982017-07-28 11:04:54 -04004644
Cary Clarkbad5ad72017-08-03 17:14:08 -04004645Additionally transform draw using Clip, Matrix, and optional Paint paint.
4646
4647If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4648Blend_Mode, and Draw_Looper. If bitmap is kAlpha_8_SkColorType, apply Shader.
4649If paint contains Mask_Filter, generate mask from bitmap bounds.
4650
4651If generated mask extends beyond bitmap bounds, replicate bitmap edge colors,
4652just as Shader made from SkShader::MakeBitmapShader with
Cary Clarkbc5697d2017-10-04 14:31:33 -04004653SkShader::kClamp_TileMode set replicates the bitmap edge color when it samples
Cary Clarkbad5ad72017-08-03 17:14:08 -04004654outside of its bounds.
4655
4656#Param bitmap Bitmap containing pixels, dimensions, and format ##
4657#Param center IRect edge of image corners and sides ##
4658#Param dst destination Rect of image to draw to ##
4659#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4660 and so on; or nullptr
4661##
Cary Clark8032b982017-07-28 11:04:54 -04004662
4663#Example
4664#Height 128
4665#Description
4666 The two leftmost bitmap draws has four corners and sides to the left and right of center.
4667 The leftmost bitmap draw scales the width of corners proportionately to fit.
Cary Clarkce101242017-09-01 15:51:02 -04004668 The third and fourth draw corners are not scaled; the sides and center are scaled to
Cary Clark8032b982017-07-28 11:04:54 -04004669 fill the remaining space.
4670 The rightmost bitmap draw has four corners scaled vertically to fit, and uses sides above
4671 and below center to fill the remaining space.
4672##
Cary Clarkbad5ad72017-08-03 17:14:08 -04004673void draw(SkCanvas* canvas) {
4674 SkIRect center = { 20, 10, 50, 40 };
4675 SkBitmap bitmap;
4676 bitmap.allocPixels(SkImageInfo::MakeN32Premul(60, 60));
4677 SkCanvas bitCanvas(bitmap);
4678 SkPaint paint;
4679 SkColor gray = 0xFF000000;
4680 int left = 0;
4681 for (auto right: { center.fLeft, center.fRight, bitmap.width() } ) {
4682 int top = 0;
4683 for (auto bottom: { center.fTop, center.fBottom, bitmap.height() } ) {
4684 paint.setColor(gray);
4685 bitCanvas.drawIRect(SkIRect::MakeLTRB(left, top, right, bottom), paint);
4686 gray += 0x001f1f1f;
4687 top = bottom;
4688 }
4689 left = right;
4690 }
4691 for (auto dest: { 20, 30, 40, 60, 90 } ) {
4692 canvas->drawBitmapNine(bitmap, center, SkRect::MakeWH(dest, 110 - dest), nullptr);
4693 canvas->translate(dest + 4, 0);
4694 }
Cary Clark8032b982017-07-28 11:04:54 -04004695}
4696##
4697
Cary Clark2ade9972017-11-02 17:49:34 -04004698#SeeAlso drawImageNine drawBitmap drawBitmapLattice drawBitmapRect
Cary Clark8032b982017-07-28 11:04:54 -04004699
4700##
4701
4702# ------------------------------------------------------------------------------
4703#Struct Lattice
4704
Cary Clark8032b982017-07-28 11:04:54 -04004705#Code
4706 struct Lattice {
4707 enum Flags {...
4708
4709 const int* fXDivs;
4710 const int* fYDivs;
4711 const Flags* fFlags;
4712 int fXCount;
4713 int fYCount;
4714 const SkIRect* fBounds;
4715 };
4716##
4717
Cary Clark154beea2017-10-26 07:58:48 -04004718 Lattice divides Bitmap or Image into a rectangular grid.
4719 Grid entries on even columns and even rows are fixed; these entries are
4720 always drawn at their original size if the destination is large enough.
4721 If the destination side is too small to hold the fixed entries, all fixed
4722 entries are proportionately scaled down to fit.
4723 The grid entries not on even columns and rows are scaled to fit the
4724 remaining space, if any.
4725
Cary Clark8032b982017-07-28 11:04:54 -04004726 #Enum Flags
4727 #Code
4728 enum Flags : uint8_t {
4729 kTransparent_Flags = 1 << 0,
4730 };
4731 ##
4732
4733 Optional setting per rectangular grid entry to make it transparent.
4734
4735 #Const kTransparent_Flags 1
4736 Set to skip lattice rectangle by making it transparent.
4737 ##
4738 ##
4739
4740 #Member const int* fXDivs
4741 Array of x-coordinates that divide the bitmap vertically.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004742 Array entries must be unique, increasing, greater than or equal to
4743 fBounds left edge, and less than fBounds right edge.
4744 Set the first element to fBounds left to collapse the left column of
4745 fixed grid entries.
Cary Clark8032b982017-07-28 11:04:54 -04004746 ##
4747
4748 #Member const int* fYDivs
4749 Array of y-coordinates that divide the bitmap horizontally.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004750 Array entries must be unique, increasing, greater than or equal to
4751 fBounds top edge, and less than fBounds bottom edge.
4752 Set the first element to fBounds top to collapse the top row of fixed
4753 grid entries.
Cary Clark8032b982017-07-28 11:04:54 -04004754 ##
4755
4756 #Member const Flags* fFlags
4757 Optional array of Flags, one per rectangular grid entry:
Cary Clarkbad5ad72017-08-03 17:14:08 -04004758 array length must be
4759 #Formula
4760 (fXCount + 1) * (fYCount + 1)
4761 ##
4762 .
Cary Clark6fc50412017-09-21 12:31:06 -04004763
Cary Clark8032b982017-07-28 11:04:54 -04004764 Array entries correspond to the rectangular grid entries, ascending
4765 left to right and then top to bottom.
4766 ##
4767
4768 #Member int fXCount
Cary Clarkbad5ad72017-08-03 17:14:08 -04004769 Number of entries in fXDivs array; one less than the number of
4770 horizontal divisions.
Cary Clark8032b982017-07-28 11:04:54 -04004771 ##
4772
4773 #Member int fYCount
Cary Clarkbad5ad72017-08-03 17:14:08 -04004774 Number of entries in fYDivs array; one less than the number of vertical
4775 divisions.
Cary Clark8032b982017-07-28 11:04:54 -04004776 ##
4777
4778 #Member const SkIRect* fBounds
4779 Optional subset IRect source to draw from.
4780 If nullptr, source bounds is dimensions of Bitmap or Image.
4781 ##
4782
4783#Struct Lattice ##
4784
4785#Method void drawBitmapLattice(const SkBitmap& bitmap, const Lattice& lattice, const SkRect& dst,
4786 const SkPaint* paint = nullptr)
4787
Cary Clarkd0530ba2017-09-14 11:25:39 -04004788Draw Bitmap bitmap stretched proportionally to fit into Rect dst.
Cary Clark8032b982017-07-28 11:04:54 -04004789
4790Lattice lattice divides bitmap into a rectangular grid.
4791Each intersection of an even-numbered row and column is fixed; like the corners
Cary Clarkbad5ad72017-08-03 17:14:08 -04004792of drawBitmapNine, fixed lattice elements never scale larger than their initial
Cary Clarkbc5697d2017-10-04 14:31:33 -04004793size and shrink proportionately when all fixed elements exceed the bitmap
Cary Clarkbad5ad72017-08-03 17:14:08 -04004794dimension. All other grid elements scale to fill the available space, if any.
Cary Clark8032b982017-07-28 11:04:54 -04004795
4796Additionally transform draw using Clip, Matrix, and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004797
Cary Clarkbad5ad72017-08-03 17:14:08 -04004798If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4799Blend_Mode, and Draw_Looper. If bitmap is kAlpha_8_SkColorType, apply Shader.
4800If paint contains Mask_Filter, generate mask from bitmap bounds.
4801
4802If generated mask extends beyond bitmap bounds, replicate bitmap edge colors,
4803just as Shader made from SkShader::MakeBitmapShader with
Cary Clarkbc5697d2017-10-04 14:31:33 -04004804SkShader::kClamp_TileMode set replicates the bitmap edge color when it samples
Cary Clarkbad5ad72017-08-03 17:14:08 -04004805outside of its bounds.
4806
4807#Param bitmap Bitmap containing pixels, dimensions, and format ##
4808#Param lattice division of bitmap into fixed and variable rectangles ##
4809#Param dst destination Rect of image to draw to ##
4810#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4811 and so on; or nullptr
4812##
Cary Clark8032b982017-07-28 11:04:54 -04004813
4814#Example
4815#Height 128
4816#Description
4817 The two leftmost bitmap draws has four corners and sides to the left and right of center.
4818 The leftmost bitmap draw scales the width of corners proportionately to fit.
Cary Clarkce101242017-09-01 15:51:02 -04004819 The third and fourth draw corners are not scaled; the sides are scaled to
Cary Clark8032b982017-07-28 11:04:54 -04004820 fill the remaining space; the center is transparent.
4821 The rightmost bitmap draw has four corners scaled vertically to fit, and uses sides above
4822 and below center to fill the remaining space.
4823##
Cary Clarkbad5ad72017-08-03 17:14:08 -04004824void draw(SkCanvas* canvas) {
4825 SkIRect center = { 20, 10, 50, 40 };
4826 SkBitmap bitmap;
4827 bitmap.allocPixels(SkImageInfo::MakeN32Premul(60, 60));
4828 SkCanvas bitCanvas(bitmap);
4829 SkPaint paint;
4830 SkColor gray = 0xFF000000;
4831 int left = 0;
4832 for (auto right: { center.fLeft, center.fRight, bitmap.width() } ) {
4833 int top = 0;
4834 for (auto bottom: { center.fTop, center.fBottom, bitmap.height() } ) {
4835 paint.setColor(gray);
4836 bitCanvas.drawIRect(SkIRect::MakeLTRB(left, top, right, bottom), paint);
4837 gray += 0x001f1f1f;
4838 top = bottom;
4839 }
4840 left = right;
4841 }
4842 const int xDivs[] = { center.fLeft, center.fRight };
4843 const int yDivs[] = { center.fTop, center.fBottom };
4844 SkCanvas::Lattice::Flags flags[3][3];
4845 memset(flags, 0, sizeof(flags));
4846 flags[1][1] = SkCanvas::Lattice::kTransparent_Flags;
4847 SkCanvas::Lattice lattice = { xDivs, yDivs, flags[0], SK_ARRAY_COUNT(xDivs),
4848 SK_ARRAY_COUNT(yDivs), nullptr };
4849 for (auto dest: { 20, 30, 40, 60, 90 } ) {
4850 canvas->drawBitmapLattice(bitmap, lattice , SkRect::MakeWH(dest, 110 - dest), nullptr);
4851 canvas->translate(dest + 4, 0);
4852 }
Cary Clark8032b982017-07-28 11:04:54 -04004853}
4854##
4855
Cary Clark2ade9972017-11-02 17:49:34 -04004856#SeeAlso drawImageLattice drawBitmap drawBitmapNine Lattice
Cary Clark8032b982017-07-28 11:04:54 -04004857
4858##
4859
4860# ------------------------------------------------------------------------------
4861
4862#Method void drawImageLattice(const SkImage* image, const Lattice& lattice, const SkRect& dst,
4863 const SkPaint* paint = nullptr)
4864
Cary Clarkd0530ba2017-09-14 11:25:39 -04004865Draw Image image stretched proportionally to fit into Rect dst.
Cary Clark8032b982017-07-28 11:04:54 -04004866
4867Lattice lattice divides image into a rectangular grid.
4868Each intersection of an even-numbered row and column is fixed; like the corners
Cary Clarkbad5ad72017-08-03 17:14:08 -04004869of drawBitmapNine, fixed lattice elements never scale larger than their initial
Cary Clarkbc5697d2017-10-04 14:31:33 -04004870size and shrink proportionately when all fixed elements exceed the bitmap
Cary Clarkbad5ad72017-08-03 17:14:08 -04004871dimension. All other grid elements scale to fill the available space, if any.
Cary Clark8032b982017-07-28 11:04:54 -04004872
4873Additionally transform draw using Clip, Matrix, and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004874
Cary Clarkbad5ad72017-08-03 17:14:08 -04004875If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4876Blend_Mode, and Draw_Looper. If bitmap is kAlpha_8_SkColorType, apply Shader.
4877If paint contains Mask_Filter, generate mask from bitmap bounds.
4878
4879If generated mask extends beyond bitmap bounds, replicate bitmap edge colors,
4880just as Shader made from SkShader::MakeBitmapShader with
Cary Clarkbc5697d2017-10-04 14:31:33 -04004881SkShader::kClamp_TileMode set replicates the bitmap edge color when it samples
Cary Clarkbad5ad72017-08-03 17:14:08 -04004882outside of its bounds.
4883
4884#Param image Image containing pixels, dimensions, and format ##
4885#Param lattice division of bitmap into fixed and variable rectangles ##
4886#Param dst destination Rect of image to draw to ##
4887#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4888 and so on; or nullptr
4889##
Cary Clark8032b982017-07-28 11:04:54 -04004890
4891#Example
4892#Height 128
4893#Description
4894 The leftmost image is smaller than center; only corners are drawn, all scaled to fit.
Cary Clarkce101242017-09-01 15:51:02 -04004895 The second image equals the size of center; only corners are drawn without scaling.
4896 The remaining images are larger than center. All corners draw without scaling. The sides
Cary Clark8032b982017-07-28 11:04:54 -04004897 are scaled if needed to take up the remaining space; the center is transparent.
4898##
Cary Clarkbad5ad72017-08-03 17:14:08 -04004899void draw(SkCanvas* canvas) {
4900 SkIRect center = { 20, 10, 50, 40 };
4901 SkBitmap bitmap;
4902 bitmap.allocPixels(SkImageInfo::MakeN32Premul(60, 60));
4903 SkCanvas bitCanvas(bitmap);
4904 SkPaint paint;
4905 SkColor gray = 0xFF000000;
4906 int left = 0;
4907 for (auto right: { center.fLeft, center.fRight, bitmap.width() } ) {
4908 int top = 0;
4909 for (auto bottom: { center.fTop, center.fBottom, bitmap.height() } ) {
4910 paint.setColor(gray);
4911 bitCanvas.drawIRect(SkIRect::MakeLTRB(left, top, right, bottom), paint);
4912 gray += 0x001f1f1f;
4913 top = bottom;
4914 }
4915 left = right;
4916 }
4917 const int xDivs[] = { center.fLeft, center.fRight };
4918 const int yDivs[] = { center.fTop, center.fBottom };
4919 SkCanvas::Lattice::Flags flags[3][3];
4920 memset(flags, 0, sizeof(flags));
4921 flags[1][1] = SkCanvas::Lattice::kTransparent_Flags;
4922 SkCanvas::Lattice lattice = { xDivs, yDivs, flags[0], SK_ARRAY_COUNT(xDivs),
4923 SK_ARRAY_COUNT(yDivs), nullptr };
4924 sk_sp<SkImage> image = SkImage::MakeFromBitmap(bitmap);
4925 SkImage* imagePtr = image.get();
4926 for (auto dest: { 20, 30, 40, 60, 90 } ) {
4927 canvas->drawImageNine(imagePtr, center, SkRect::MakeWH(dest, dest), nullptr);
4928 canvas->translate(dest + 4, 0);
4929 }
Cary Clark8032b982017-07-28 11:04:54 -04004930}
4931##
4932
Cary Clark2ade9972017-11-02 17:49:34 -04004933#SeeAlso drawBitmapLattice drawImage drawImageNine Lattice
Cary Clark8032b982017-07-28 11:04:54 -04004934
4935##
4936
4937#Topic Draw_Image ##
4938
4939# ------------------------------------------------------------------------------
4940
4941#Method void drawText(const void* text, size_t byteLength, SkScalar x, SkScalar y,
4942 const SkPaint& paint)
4943
4944Draw text, with origin at (x, y), using Clip, Matrix, and Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004945
Cary Clarkbc5697d2017-10-04 14:31:33 -04004946text meaning depends on Paint_Text_Encoding; by default, text is encoded as
Cary Clarkbad5ad72017-08-03 17:14:08 -04004947UTF-8.
Cary Clark8032b982017-07-28 11:04:54 -04004948
Cary Clarkbad5ad72017-08-03 17:14:08 -04004949x and y meaning depends on Paint_Text_Align and Paint_Vertical_Text; by default
Cary Clarkbc5697d2017-10-04 14:31:33 -04004950text draws left to right, positioning the first glyph left side bearing at x
Cary Clarkbad5ad72017-08-03 17:14:08 -04004951and its baseline at y. Text size is affected by Matrix and Paint_Text_Size.
4952
4953All elements of paint: Path_Effect, Rasterizer, Mask_Filter, Shader,
4954Color_Filter, Image_Filter, and Draw_Looper; apply to text. By default, draws
Cary Clarkce101242017-09-01 15:51:02 -04004955filled 12 point black Glyphs.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004956
Cary Clarkce101242017-09-01 15:51:02 -04004957#Param text character code points or Glyphs drawn ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04004958#Param byteLength byte length of text array ##
4959#Param x start of text on x-axis ##
4960#Param y start of text on y-axis ##
4961#Param paint text size, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04004962
4963#Example
4964#Height 200
4965#Description
4966 The same text is drawn varying Paint_Text_Size and varying
4967 Matrix.
4968##
Cary Clarkbad5ad72017-08-03 17:14:08 -04004969void draw(SkCanvas* canvas) {
4970 SkPaint paint;
4971 paint.setAntiAlias(true);
4972 float textSizes[] = { 12, 18, 24, 36 };
4973 for (auto size: textSizes ) {
4974 paint.setTextSize(size);
4975 canvas->drawText("Aa", 2, 10, 20, paint);
4976 canvas->translate(0, size * 2);
4977 }
4978 paint.reset();
4979 paint.setAntiAlias(true);
4980 float yPos = 20;
4981 for (auto size: textSizes ) {
4982 float scale = size / 12.f;
4983 canvas->resetMatrix();
4984 canvas->translate(100, 0);
4985 canvas->scale(scale, scale);
4986 canvas->drawText("Aa", 2, 10 / scale, yPos / scale, paint);
4987 yPos += size * 2;
4988 }
4989}
Cary Clark8032b982017-07-28 11:04:54 -04004990##
4991
Cary Clark2ade9972017-11-02 17:49:34 -04004992#SeeAlso drawString drawPosText drawPosTextH drawTextBlob drawTextOnPath drawTextRSXform
Cary Clark8032b982017-07-28 11:04:54 -04004993
4994##
4995
4996#Method void drawString(const char* string, SkScalar x, SkScalar y, const SkPaint& paint)
4997
Cary Clarkbad5ad72017-08-03 17:14:08 -04004998Draw null terminated string, with origin at (x, y), using Clip, Matrix, and
4999Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04005000
Cary Clarkbc5697d2017-10-04 14:31:33 -04005001string meaning depends on Paint_Text_Encoding; by default, strings are encoded
5002as UTF-8. Other values of Paint_Text_Encoding are unlikely to produce the desired
Cary Clarkbad5ad72017-08-03 17:14:08 -04005003results, since zero bytes may be embedded in the string.
Cary Clark8032b982017-07-28 11:04:54 -04005004
Cary Clarkbad5ad72017-08-03 17:14:08 -04005005x and y meaning depends on Paint_Text_Align and Paint_Vertical_Text; by default
Cary Clarkbc5697d2017-10-04 14:31:33 -04005006string draws left to right, positioning the first glyph left side bearing at x
Cary Clarkbad5ad72017-08-03 17:14:08 -04005007and its baseline at y. Text size is affected by Matrix and Paint_Text_Size.
5008
5009All elements of paint: Path_Effect, Rasterizer, Mask_Filter, Shader,
5010Color_Filter, Image_Filter, and Draw_Looper; apply to text. By default, draws
Cary Clarkce101242017-09-01 15:51:02 -04005011filled 12 point black Glyphs.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005012
Cary Clarkce101242017-09-01 15:51:02 -04005013#Param string character code points or Glyphs drawn,
Cary Clarkbad5ad72017-08-03 17:14:08 -04005014 ending with a char value of zero
5015##
5016#Param x start of string on x-axis ##
5017#Param y start of string on y-axis ##
5018#Param paint text size, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005019
5020#Example
5021 SkPaint paint;
5022 canvas->drawString("a small hello", 20, 20, paint);
5023##
5024
Cary Clark2ade9972017-11-02 17:49:34 -04005025#SeeAlso drawText drawPosText drawPosTextH drawTextBlob drawTextOnPath drawTextRSXform
Cary Clark8032b982017-07-28 11:04:54 -04005026
5027##
5028
5029#Method void drawString(const SkString& string, SkScalar x, SkScalar y, const SkPaint& paint)
5030
Cary Clarkbad5ad72017-08-03 17:14:08 -04005031Draw null terminated string, with origin at (x, y), using Clip, Matrix, and
5032Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04005033
Cary Clarkbc5697d2017-10-04 14:31:33 -04005034string meaning depends on Paint_Text_Encoding; by default, strings are encoded
5035as UTF-8. Other values of Paint_Text_Encoding are unlikely to produce the desired
Cary Clarkbad5ad72017-08-03 17:14:08 -04005036results, since zero bytes may be embedded in the string.
Cary Clark8032b982017-07-28 11:04:54 -04005037
Cary Clarkbad5ad72017-08-03 17:14:08 -04005038x and y meaning depends on Paint_Text_Align and Paint_Vertical_Text; by default
Cary Clarkbc5697d2017-10-04 14:31:33 -04005039string draws left to right, positioning the first glyph left side bearing at x
Cary Clarkbad5ad72017-08-03 17:14:08 -04005040and its baseline at y. Text size is affected by Matrix and Paint_Text_Size.
5041
5042All elements of paint: Path_Effect, Rasterizer, Mask_Filter, Shader,
5043Color_Filter, Image_Filter, and Draw_Looper; apply to text. By default, draws
Cary Clarkce101242017-09-01 15:51:02 -04005044filled 12 point black Glyphs.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005045
Cary Clarkce101242017-09-01 15:51:02 -04005046#Param string character code points or Glyphs drawn,
Cary Clarkbad5ad72017-08-03 17:14:08 -04005047 ending with a char value of zero
5048##
5049#Param x start of string on x-axis ##
5050#Param y start of string on y-axis ##
5051#Param paint text size, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005052
5053#Example
5054 SkPaint paint;
5055 SkString string("a small hello");
5056 canvas->drawString(string, 20, 20, paint);
5057##
5058
Cary Clark2ade9972017-11-02 17:49:34 -04005059#SeeAlso drawText drawPosText drawPosTextH drawTextBlob drawTextOnPath drawTextRSXform
Cary Clark8032b982017-07-28 11:04:54 -04005060
5061##
5062
5063# ------------------------------------------------------------------------------
5064
5065#Method void drawPosText(const void* text, size_t byteLength, const SkPoint pos[],
5066 const SkPaint& paint)
5067
Cary Clarkbad5ad72017-08-03 17:14:08 -04005068Draw each glyph in text with the origin in pos array, using Clip, Matrix, and
Cary Clarkce101242017-09-01 15:51:02 -04005069Paint paint. The number of entries in pos array must match the number of Glyphs
Cary Clarkbad5ad72017-08-03 17:14:08 -04005070described by byteLength of text.
Cary Clark8032b982017-07-28 11:04:54 -04005071
Cary Clarkbc5697d2017-10-04 14:31:33 -04005072text meaning depends on Paint_Text_Encoding; by default, text is encoded as
Cary Clarkbad5ad72017-08-03 17:14:08 -04005073UTF-8. pos elements' meaning depends on Paint_Text_Align and Paint_Vertical_Text;
Cary Clarkbc5697d2017-10-04 14:31:33 -04005074by default each glyph left side bearing is positioned at x and its
Cary Clarkbad5ad72017-08-03 17:14:08 -04005075baseline is positioned at y. Text size is affected by Matrix and
5076Paint_Text_Size.
Cary Clark8032b982017-07-28 11:04:54 -04005077
Cary Clarkbad5ad72017-08-03 17:14:08 -04005078All elements of paint: Path_Effect, Rasterizer, Mask_Filter, Shader,
5079Color_Filter, Image_Filter, and Draw_Looper; apply to text. By default, draws
Cary Clarkce101242017-09-01 15:51:02 -04005080filled 12 point black Glyphs.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005081
5082Layout engines such as Harfbuzz typically position each glyph
Cary Clarkbc5697d2017-10-04 14:31:33 -04005083rather than using the font advance widths.
Cary Clark8032b982017-07-28 11:04:54 -04005084
Cary Clarkce101242017-09-01 15:51:02 -04005085#Param text character code points or Glyphs drawn ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005086#Param byteLength byte length of text array ##
5087#Param pos array of glyph origins ##
5088#Param paint text size, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005089
5090#Example
5091#Height 120
Cary Clarkbad5ad72017-08-03 17:14:08 -04005092void draw(SkCanvas* canvas) {
5093 const char hello[] = "HeLLo!";
5094 const SkPoint pos[] = { {40, 100}, {82, 95}, {115, 110}, {130, 95}, {145, 85},
5095 {172, 100} };
5096 SkPaint paint;
5097 paint.setTextSize(60);
5098 canvas->drawPosText(hello, strlen(hello), pos, paint);
Cary Clark8032b982017-07-28 11:04:54 -04005099}
5100##
5101
Cary Clark2ade9972017-11-02 17:49:34 -04005102#SeeAlso drawText drawPosTextH drawTextBlob drawTextOnPath drawTextRSXform
Cary Clark8032b982017-07-28 11:04:54 -04005103
5104##
5105
5106# ------------------------------------------------------------------------------
5107
5108#Method void drawPosTextH(const void* text, size_t byteLength, const SkScalar xpos[], SkScalar constY,
5109 const SkPaint& paint)
5110
Cary Clarkbad5ad72017-08-03 17:14:08 -04005111Draw each glyph in text with its (x, y) origin composed from xpos array and
5112constY, using Clip, Matrix, and Paint paint. The number of entries in xpos array
Cary Clarkce101242017-09-01 15:51:02 -04005113must match the number of Glyphs described by byteLength of text.
Cary Clark8032b982017-07-28 11:04:54 -04005114
Cary Clarkbc5697d2017-10-04 14:31:33 -04005115text meaning depends on Paint_Text_Encoding; by default, text is encoded as
Cary Clarkce101242017-09-01 15:51:02 -04005116UTF-8. xpos elements' meaning depends on Paint_Text_Align and Paint_Vertical_Text;
Cary Clarkbc5697d2017-10-04 14:31:33 -04005117by default each glyph left side bearing is positioned at an xpos element and
Cary Clarkbad5ad72017-08-03 17:14:08 -04005118its baseline is positioned at constY. Text size is affected by Matrix and
5119Paint_Text_Size.
Cary Clark8032b982017-07-28 11:04:54 -04005120
Cary Clarkbad5ad72017-08-03 17:14:08 -04005121All elements of paint: Path_Effect, Rasterizer, Mask_Filter, Shader,
5122Color_Filter, Image_Filter, and Draw_Looper; apply to text. By default, draws
Cary Clarkce101242017-09-01 15:51:02 -04005123filled 12 point black Glyphs.
Cary Clark8032b982017-07-28 11:04:54 -04005124
Cary Clarkbad5ad72017-08-03 17:14:08 -04005125Layout engines such as Harfbuzz typically position each glyph
Cary Clarkbc5697d2017-10-04 14:31:33 -04005126rather than using the font advance widths if all Glyphs share the same
Cary Clarkbad5ad72017-08-03 17:14:08 -04005127baseline.
5128
Cary Clarkce101242017-09-01 15:51:02 -04005129#Param text character code points or Glyphs drawn ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005130#Param byteLength byte length of text array ##
5131#Param xpos array of x positions, used to position each glyph ##
5132#Param constY shared y coordinate for all of x positions ##
5133#Param paint text size, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005134
5135#Example
5136#Height 40
Cary Clarkbad5ad72017-08-03 17:14:08 -04005137 void draw(SkCanvas* canvas) {
5138 SkScalar xpos[] = { 20, 40, 80, 160 };
5139 SkPaint paint;
5140 canvas->drawPosTextH("XXXX", 4, xpos, 20, paint);
5141 }
Cary Clark8032b982017-07-28 11:04:54 -04005142##
5143
Cary Clark2ade9972017-11-02 17:49:34 -04005144#SeeAlso drawText drawPosText drawTextBlob drawTextOnPath drawTextRSXform
Cary Clark8032b982017-07-28 11:04:54 -04005145
5146##
5147
5148# ------------------------------------------------------------------------------
5149
5150#Method void drawTextOnPathHV(const void* text, size_t byteLength, const SkPath& path, SkScalar hOffset,
5151 SkScalar vOffset, const SkPaint& paint)
5152
5153Draw text on Path path, using Clip, Matrix, and Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04005154
Cary Clarkbad5ad72017-08-03 17:14:08 -04005155Origin of text is at distance hOffset along the path, offset by a perpendicular
5156vector of length vOffset. If the path section corresponding the glyph advance is
5157curved, the glyph is drawn curved to match; control points in the glyph are
Cary Clarkbc5697d2017-10-04 14:31:33 -04005158mapped to projected points parallel to the path. If the text advance is larger
Cary Clarkbad5ad72017-08-03 17:14:08 -04005159than the path length, the excess text is clipped.
5160
Cary Clarkbc5697d2017-10-04 14:31:33 -04005161text meaning depends on Paint_Text_Encoding; by default, text is encoded as
Cary Clarkbad5ad72017-08-03 17:14:08 -04005162UTF-8. Origin meaning depends on Paint_Text_Align and Paint_Vertical_Text; by
Cary Clarkbc5697d2017-10-04 14:31:33 -04005163default text positions the first glyph left side bearing at origin x and its
Cary Clark8032b982017-07-28 11:04:54 -04005164baseline at origin y. Text size is affected by Matrix and Paint_Text_Size.
5165
Cary Clarkbad5ad72017-08-03 17:14:08 -04005166All elements of paint: Path_Effect, Rasterizer, Mask_Filter, Shader,
5167Color_Filter, Image_Filter, and Draw_Looper; apply to text. By default, draws
Cary Clarkce101242017-09-01 15:51:02 -04005168filled 12 point black Glyphs.
Cary Clark8032b982017-07-28 11:04:54 -04005169
Cary Clarkce101242017-09-01 15:51:02 -04005170#Param text character code points or Glyphs drawn ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005171#Param byteLength byte length of text array ##
5172#Param path Path providing text baseline ##
5173#Param hOffset distance along path to offset origin ##
5174#Param vOffset offset of text above (if negative) or below (if positive) the path ##
5175#Param paint text size, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005176
5177#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04005178 void draw(SkCanvas* canvas) {
5179 const char aero[] = "correo a" "\xC3" "\xA9" "reo";
5180 const size_t len = sizeof(aero) - 1;
5181 SkPath path;
5182 path.addOval({43-26, 43-26, 43+26, 43+26}, SkPath::kCW_Direction, 3);
5183 SkPaint paint;
5184 paint.setTextSize(24);
5185 for (auto offset : { 0, 10, 20 } ) {
5186 canvas->drawTextOnPathHV(aero, len, path, 0, -offset, paint);
5187 canvas->translate(70 + offset, 70 + offset);
5188 }
5189 }
Cary Clark8032b982017-07-28 11:04:54 -04005190##
5191
Cary Clark2ade9972017-11-02 17:49:34 -04005192#SeeAlso drawTextOnPath drawText drawPosTextH drawTextBlob drawTextRSXform
Cary Clark8032b982017-07-28 11:04:54 -04005193
5194##
5195
5196# ------------------------------------------------------------------------------
5197
5198#Method void drawTextOnPath(const void* text, size_t byteLength, const SkPath& path,
5199 const SkMatrix* matrix, const SkPaint& paint)
5200
5201Draw text on Path path, using Clip, Matrix, and Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04005202
Cary Clarkbad5ad72017-08-03 17:14:08 -04005203Origin of text is at beginning of path offset by matrix, if provided, before it
5204is mapped to path. If the path section corresponding the glyph advance is
5205curved, the glyph is drawn curved to match; control points in the glyph are
Cary Clarkbc5697d2017-10-04 14:31:33 -04005206mapped to projected points parallel to the path. If the text advance is larger
Cary Clarkbad5ad72017-08-03 17:14:08 -04005207than the path length, the excess text is clipped.
5208
Cary Clarkbc5697d2017-10-04 14:31:33 -04005209text meaning depends on Paint_Text_Encoding; by default, text is encoded as
Cary Clarkbad5ad72017-08-03 17:14:08 -04005210UTF-8. Origin meaning depends on Paint_Text_Align and Paint_Vertical_Text; by
Cary Clarkbc5697d2017-10-04 14:31:33 -04005211default text positions the first glyph left side bearing at origin x and its
Cary Clark8032b982017-07-28 11:04:54 -04005212baseline at origin y. Text size is affected by Matrix and Paint_Text_Size.
5213
Cary Clarkbad5ad72017-08-03 17:14:08 -04005214All elements of paint: Path_Effect, Rasterizer, Mask_Filter, Shader,
5215Color_Filter, Image_Filter, and Draw_Looper; apply to text. By default, draws
Cary Clarkce101242017-09-01 15:51:02 -04005216filled 12 point black Glyphs.
Cary Clark8032b982017-07-28 11:04:54 -04005217
Cary Clarkce101242017-09-01 15:51:02 -04005218#Param text character code points or Glyphs drawn ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005219#Param byteLength byte length of text array ##
5220#Param path Path providing text baseline ##
Cary Clarkce101242017-09-01 15:51:02 -04005221#Param matrix transform of Glyphs before mapping to path; may be nullptr
Cary Clarka523d2d2017-08-30 08:58:10 -04005222 to use identity Matrix
Cary Clarkbad5ad72017-08-03 17:14:08 -04005223##
5224#Param paint text size, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005225
5226#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04005227 void draw(SkCanvas* canvas) {
5228 const char roller[] = "rollercoaster";
5229 const size_t len = sizeof(roller) - 1;
5230 SkPath path;
5231 path.cubicTo(40, -80, 120, 80, 160, -40);
5232 SkPaint paint;
5233 paint.setTextSize(32);
5234 paint.setStyle(SkPaint::kStroke_Style);
5235 SkMatrix matrix;
5236 matrix.setIdentity();
5237 for (int i = 0; i < 3; ++i) {
5238 canvas->translate(25, 60);
5239 canvas->drawPath(path, paint);
5240 canvas->drawTextOnPath(roller, len, path, &matrix, paint);
5241 matrix.preTranslate(0, 10);
5242 }
5243 }
Cary Clark8032b982017-07-28 11:04:54 -04005244##
5245
Cary Clark2ade9972017-11-02 17:49:34 -04005246#SeeAlso drawTextOnPathHV drawText drawPosTextH drawTextBlob drawTextRSXform
Cary Clark8032b982017-07-28 11:04:54 -04005247
5248##
5249
5250# ------------------------------------------------------------------------------
5251
5252#Method void drawTextRSXform(const void* text, size_t byteLength, const SkRSXform xform[],
5253 const SkRect* cullRect, const SkPaint& paint)
5254
5255Draw text, transforming each glyph by the corresponding SkRSXform,
5256using Clip, Matrix, and Paint paint.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005257
Cary Clark8032b982017-07-28 11:04:54 -04005258RSXform array specifies a separate square scale, rotation, and translation for
5259each glyph.
Cary Clark8032b982017-07-28 11:04:54 -04005260
Cary Clarkbad5ad72017-08-03 17:14:08 -04005261Optional Rect cullRect is a conservative bounds of text, taking into account
Cary Clarkce101242017-09-01 15:51:02 -04005262RSXform and paint. If cullRect is outside of Clip, canvas can skip drawing.
Cary Clark8032b982017-07-28 11:04:54 -04005263
Cary Clarkbad5ad72017-08-03 17:14:08 -04005264All elements of paint: Path_Effect, Rasterizer, Mask_Filter, Shader,
5265Color_Filter, Image_Filter, and Draw_Looper; apply to text. By default, draws
Cary Clarkce101242017-09-01 15:51:02 -04005266filled 12 point black Glyphs.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005267
Cary Clarkce101242017-09-01 15:51:02 -04005268#Param text character code points or Glyphs drawn ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005269#Param byteLength byte length of text array ##
5270#Param xform RSXform rotates, scales, and translates each glyph individually ##
5271#Param cullRect Rect bounds of text for efficient clipping; or nullptr ##
5272#Param paint text size, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005273
5274#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04005275void draw(SkCanvas* canvas) {
5276 const int iterations = 26;
5277 SkRSXform transforms[iterations];
5278 char alphabet[iterations];
5279 SkScalar angle = 0;
5280 SkScalar scale = 1;
5281 for (size_t i = 0; i < SK_ARRAY_COUNT(transforms); ++i) {
5282 const SkScalar s = SkScalarSin(angle) * scale;
5283 const SkScalar c = SkScalarCos(angle) * scale;
5284 transforms[i] = SkRSXform::Make(-c, -s, -s * 16, c * 16);
5285 angle += .45;
5286 scale += .2;
5287 alphabet[i] = 'A' + i;
5288 }
5289 SkPaint paint;
5290 paint.setTextAlign(SkPaint::kCenter_Align);
5291 canvas->translate(110, 138);
5292 canvas->drawTextRSXform(alphabet, sizeof(alphabet), transforms, nullptr, paint);
Cary Clark8032b982017-07-28 11:04:54 -04005293}
5294##
5295
Cary Clark2ade9972017-11-02 17:49:34 -04005296#SeeAlso drawTextOnPath drawTextOnPathHV drawText drawPosText drawTextBlob
Cary Clark8032b982017-07-28 11:04:54 -04005297
5298##
5299
5300# ------------------------------------------------------------------------------
5301
5302#Method void drawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y, const SkPaint& paint)
5303
5304Draw Text_Blob blob at (x, y), using Clip, Matrix, and Paint paint.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005305
Cary Clarkce101242017-09-01 15:51:02 -04005306blob contains Glyphs, their positions, and paint attributes specific to text:
Cary Clarkbad5ad72017-08-03 17:14:08 -04005307Typeface, Paint_Text_Size, Paint_Text_Scale_X, Paint_Text_Skew_X,
5308Paint_Text_Align, Paint_Hinting, Anti-alias, Paint_Fake_Bold,
5309Font_Embedded_Bitmaps, Full_Hinting_Spacing, LCD_Text, Linear_Text,
5310Subpixel_Text, and Paint_Vertical_Text.
Cary Clark8032b982017-07-28 11:04:54 -04005311
5312Elements of paint: Path_Effect, Rasterizer, Mask_Filter, Shader, Color_Filter,
5313Image_Filter, and Draw_Looper; apply to blob.
5314
Cary Clarkce101242017-09-01 15:51:02 -04005315#Param blob Glyphs, positions, and their paints' text size, typeface, and so on ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005316#Param x horizontal offset applied to blob ##
5317#Param y vertical offset applied to blob ##
5318#Param paint blend, color, stroking, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005319
5320#Example
5321#Height 120
Cary Clarkbad5ad72017-08-03 17:14:08 -04005322 void draw(SkCanvas* canvas) {
5323 SkTextBlobBuilder textBlobBuilder;
5324 const char bunny[] = "/(^x^)\\";
5325 const int len = sizeof(bunny) - 1;
5326 uint16_t glyphs[len];
5327 SkPaint paint;
5328 paint.textToGlyphs(bunny, len, glyphs);
5329 int runs[] = { 3, 1, 3 };
5330 SkPoint textPos = { 20, 100 };
5331 int glyphIndex = 0;
5332 for (auto runLen : runs) {
5333 paint.setTextSize(1 == runLen ? 20 : 50);
5334 const SkTextBlobBuilder::RunBuffer& run =
5335 textBlobBuilder.allocRun(paint, runLen, textPos.fX, textPos.fY);
5336 memcpy(run.glyphs, &glyphs[glyphIndex], sizeof(glyphs[0]) * runLen);
5337 textPos.fX += paint.measureText(&bunny[glyphIndex], runLen, nullptr);
5338 glyphIndex += runLen;
5339 }
5340 sk_sp<const SkTextBlob> blob = textBlobBuilder.make();
5341 paint.reset();
5342 canvas->drawTextBlob(blob.get(), 0, 0, paint);
Cary Clark8032b982017-07-28 11:04:54 -04005343 }
5344##
5345
Cary Clark2ade9972017-11-02 17:49:34 -04005346#SeeAlso drawText drawPosText drawPosTextH
Cary Clark8032b982017-07-28 11:04:54 -04005347
5348##
5349
5350# ------------------------------------------------------------------------------
5351
5352#Method void drawTextBlob(const sk_sp<SkTextBlob>& blob, SkScalar x, SkScalar y, const SkPaint& paint)
5353
5354Draw Text_Blob blob at (x, y), using Clip, Matrix, and Paint paint.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005355
Cary Clarkce101242017-09-01 15:51:02 -04005356blob contains Glyphs, their positions, and paint attributes specific to text:
Cary Clarkbad5ad72017-08-03 17:14:08 -04005357Typeface, Paint_Text_Size, Paint_Text_Scale_X, Paint_Text_Skew_X,
5358Paint_Text_Align, Paint_Hinting, Anti-alias, Paint_Fake_Bold,
5359Font_Embedded_Bitmaps, Full_Hinting_Spacing, LCD_Text, Linear_Text,
5360Subpixel_Text, and Paint_Vertical_Text.
Cary Clark8032b982017-07-28 11:04:54 -04005361
5362Elements of paint: Path_Effect, Rasterizer, Mask_Filter, Shader, Color_Filter,
5363Image_Filter, and Draw_Looper; apply to blob.
5364
Cary Clarkce101242017-09-01 15:51:02 -04005365#Param blob Glyphs, positions, and their paints' text size, typeface, and so on ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005366#Param x horizontal offset applied to blob ##
5367#Param y vertical offset applied to blob ##
5368#Param paint blend, color, stroking, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005369
5370#Example
5371#Height 120
5372#Description
5373Paint attributes unrelated to text, like color, have no effect on paint in allocated Text_Blob.
5374Paint attributes related to text, like text size, have no effect on paint passed to drawTextBlob.
5375##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005376 void draw(SkCanvas* canvas) {
5377 SkTextBlobBuilder textBlobBuilder;
5378 SkPaint paint;
5379 paint.setTextSize(50);
5380 paint.setColor(SK_ColorRED);
5381 const SkTextBlobBuilder::RunBuffer& run =
5382 textBlobBuilder.allocRun(paint, 1, 20, 100);
5383 run.glyphs[0] = 20;
5384 sk_sp<const SkTextBlob> blob = textBlobBuilder.make();
5385 paint.setTextSize(10);
5386 paint.setColor(SK_ColorBLUE);
5387 canvas->drawTextBlob(blob.get(), 0, 0, paint);
5388 }
Cary Clark8032b982017-07-28 11:04:54 -04005389##
5390
Cary Clark2ade9972017-11-02 17:49:34 -04005391#SeeAlso drawText drawPosText drawPosTextH
Cary Clark8032b982017-07-28 11:04:54 -04005392
5393##
5394
5395# ------------------------------------------------------------------------------
5396
5397#Method void drawPicture(const SkPicture* picture)
5398
5399Draw Picture picture, using Clip and Matrix.
5400Clip and Matrix are unchanged by picture contents, as if
5401save() was called before and restore() was called after drawPicture.
5402
5403Picture records a series of draw commands for later playback.
5404
Cary Clarkbad5ad72017-08-03 17:14:08 -04005405#Param picture recorded drawing commands to play ##
Cary Clark8032b982017-07-28 11:04:54 -04005406
5407#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04005408void draw(SkCanvas* canvas) {
5409 SkPictureRecorder recorder;
5410 SkCanvas* recordingCanvas = recorder.beginRecording(50, 50);
5411 for (auto color : { SK_ColorRED, SK_ColorBLUE, 0xff007f00 } ) {
5412 SkPaint paint;
5413 paint.setColor(color);
5414 recordingCanvas->drawRect({10, 10, 30, 40}, paint);
5415 recordingCanvas->translate(10, 10);
5416 recordingCanvas->scale(1.2f, 1.4f);
5417 }
5418 sk_sp<SkPicture> playback = recorder.finishRecordingAsPicture();
5419 const SkPicture* playbackPtr = playback.get();
5420 canvas->drawPicture(playback);
5421 canvas->scale(2, 2);
5422 canvas->translate(50, 0);
5423 canvas->drawPicture(playback);
Cary Clark8032b982017-07-28 11:04:54 -04005424}
5425##
5426
Cary Clark2ade9972017-11-02 17:49:34 -04005427#SeeAlso drawDrawable SkPicture SkPicture::playback
Cary Clark8032b982017-07-28 11:04:54 -04005428
5429##
5430
5431# ------------------------------------------------------------------------------
5432
5433#Method void drawPicture(const sk_sp<SkPicture>& picture)
5434
5435Draw Picture picture, using Clip and Matrix.
5436Clip and Matrix are unchanged by picture contents, as if
5437save() was called before and restore() was called after drawPicture.
5438
5439Picture records a series of draw commands for later playback.
5440
Cary Clarkbad5ad72017-08-03 17:14:08 -04005441#Param picture recorded drawing commands to play ##
Cary Clark8032b982017-07-28 11:04:54 -04005442
5443#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04005444void draw(SkCanvas* canvas) {
5445 SkPictureRecorder recorder;
5446 SkCanvas* recordingCanvas = recorder.beginRecording(50, 50);
5447 for (auto color : { SK_ColorRED, SK_ColorBLUE, 0xff007f00 } ) {
5448 SkPaint paint;
5449 paint.setColor(color);
5450 recordingCanvas->drawRect({10, 10, 30, 40}, paint);
5451 recordingCanvas->translate(10, 10);
5452 recordingCanvas->scale(1.2f, 1.4f);
5453 }
5454 sk_sp<SkPicture> playback = recorder.finishRecordingAsPicture();
5455 canvas->drawPicture(playback);
5456 canvas->scale(2, 2);
5457 canvas->translate(50, 0);
5458 canvas->drawPicture(playback);
Cary Clark8032b982017-07-28 11:04:54 -04005459}
5460##
5461
Cary Clark2ade9972017-11-02 17:49:34 -04005462#SeeAlso drawDrawable SkPicture SkPicture::playback
Cary Clark8032b982017-07-28 11:04:54 -04005463
5464##
5465
5466# ------------------------------------------------------------------------------
5467
5468#Method void drawPicture(const SkPicture* picture, const SkMatrix* matrix, const SkPaint* paint)
5469
Cary Clarkbad5ad72017-08-03 17:14:08 -04005470Draw Picture picture, using Clip and Matrix; transforming picture with
5471Matrix matrix, if provided; and use Paint paint Color_Alpha, Color_Filter,
5472Image_Filter, and Blend_Mode, if provided.
Cary Clark8032b982017-07-28 11:04:54 -04005473
5474matrix transformation is equivalent to: save(), concat(), drawPicture, restore().
5475paint use is equivalent to: saveLayer, drawPicture, restore().
5476
Cary Clarkbad5ad72017-08-03 17:14:08 -04005477#Param picture recorded drawing commands to play ##
5478#Param matrix Matrix to rotate, scale, translate, and so on; may be nullptr ##
5479#Param paint Paint to apply transparency, filtering, and so on; may be nullptr ##
Cary Clark8032b982017-07-28 11:04:54 -04005480
5481#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04005482void draw(SkCanvas* canvas) {
5483 SkPaint paint;
5484 SkPictureRecorder recorder;
5485 SkCanvas* recordingCanvas = recorder.beginRecording(50, 50);
5486 for (auto color : { SK_ColorRED, SK_ColorBLUE, 0xff007f00 } ) {
5487 paint.setColor(color);
5488 recordingCanvas->drawRect({10, 10, 30, 40}, paint);
5489 recordingCanvas->translate(10, 10);
5490 recordingCanvas->scale(1.2f, 1.4f);
5491 }
5492 sk_sp<SkPicture> playback = recorder.finishRecordingAsPicture();
5493 const SkPicture* playbackPtr = playback.get();
5494 SkMatrix matrix;
5495 matrix.reset();
5496 for (auto alpha : { 70, 140, 210 } ) {
5497 paint.setAlpha(alpha);
5498 canvas->drawPicture(playbackPtr, &matrix, &paint);
5499 matrix.preTranslate(70, 70);
5500 }
Cary Clark8032b982017-07-28 11:04:54 -04005501}
5502##
5503
Cary Clark2ade9972017-11-02 17:49:34 -04005504#SeeAlso drawDrawable SkPicture SkPicture::playback
Cary Clark8032b982017-07-28 11:04:54 -04005505
5506##
5507
5508# ------------------------------------------------------------------------------
5509
5510#Method void drawPicture(const sk_sp<SkPicture>& picture, const SkMatrix* matrix, const SkPaint* paint)
5511
Cary Clarkbad5ad72017-08-03 17:14:08 -04005512Draw Picture picture, using Clip and Matrix; transforming picture with
5513Matrix matrix, if provided; and use Paint paint Color_Alpha, Color_Filter,
5514Image_Filter, and Blend_Mode, if provided.
Cary Clark8032b982017-07-28 11:04:54 -04005515
5516matrix transformation is equivalent to: save(), concat(), drawPicture, restore().
5517paint use is equivalent to: saveLayer, drawPicture, restore().
5518
Cary Clarkbad5ad72017-08-03 17:14:08 -04005519#Param picture recorded drawing commands to play ##
5520#Param matrix Matrix to rotate, scale, translate, and so on; may be nullptr ##
5521#Param paint Paint to apply transparency, filtering, and so on; may be nullptr ##
Cary Clark8032b982017-07-28 11:04:54 -04005522
5523#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04005524void draw(SkCanvas* canvas) {
5525 SkPaint paint;
5526 SkPictureRecorder recorder;
5527 SkCanvas* recordingCanvas = recorder.beginRecording(50, 50);
5528 for (auto color : { SK_ColorRED, SK_ColorBLUE, 0xff007f00 } ) {
5529 paint.setColor(color);
5530 recordingCanvas->drawRect({10, 10, 30, 40}, paint);
5531 recordingCanvas->translate(10, 10);
5532 recordingCanvas->scale(1.2f, 1.4f);
5533 }
5534 sk_sp<SkPicture> playback = recorder.finishRecordingAsPicture();
5535 SkMatrix matrix;
5536 matrix.reset();
5537 for (auto alpha : { 70, 140, 210 } ) {
5538 paint.setAlpha(alpha);
5539 canvas->drawPicture(playback, &matrix, &paint);
5540 matrix.preTranslate(70, 70);
5541 }
Cary Clark8032b982017-07-28 11:04:54 -04005542}
5543##
5544
Cary Clark2ade9972017-11-02 17:49:34 -04005545#SeeAlso drawDrawable SkPicture SkPicture::playback
Cary Clark8032b982017-07-28 11:04:54 -04005546
5547##
5548
5549# ------------------------------------------------------------------------------
5550
5551#Method void drawVertices(const SkVertices* vertices, SkBlendMode mode, const SkPaint& paint)
5552
5553Draw Vertices vertices, a triangle mesh, using Clip and Matrix.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005554If Vertices_Texs and Vertices_Colors are defined in vertices, and Paint paint
5555contains Shader, Blend_Mode mode combines Vertices_Colors with Shader.
Cary Clark8032b982017-07-28 11:04:54 -04005556
Cary Clarkbad5ad72017-08-03 17:14:08 -04005557#Param vertices triangle mesh to draw ##
5558#Param mode combines Vertices_Colors with Shader, if both are present ##
5559#Param paint specifies the Shader, used as Vertices texture; may be nullptr ##
Cary Clark8032b982017-07-28 11:04:54 -04005560
5561#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04005562void draw(SkCanvas* canvas) {
5563 SkPaint paint;
5564 SkPoint points[] = { { 0, 0 }, { 250, 0 }, { 100, 100 }, { 0, 250 } };
5565 SkColor colors[] = { SK_ColorRED, SK_ColorBLUE, SK_ColorYELLOW, SK_ColorCYAN };
5566 auto vertices = SkVertices::MakeCopy(SkVertices::kTriangleFan_VertexMode,
5567 SK_ARRAY_COUNT(points), points, nullptr, colors);
5568 canvas->drawVertices(vertices.get(), SkBlendMode::kSrc, paint);
5569}
Cary Clark8032b982017-07-28 11:04:54 -04005570##
5571
Cary Clark2ade9972017-11-02 17:49:34 -04005572#SeeAlso drawPatch drawPicture
Cary Clark8032b982017-07-28 11:04:54 -04005573
5574##
5575
5576# ------------------------------------------------------------------------------
5577
5578#Method void drawVertices(const sk_sp<SkVertices>& vertices, SkBlendMode mode, const SkPaint& paint)
5579
5580Draw Vertices vertices, a triangle mesh, using Clip and Matrix.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005581If Vertices_Texs and Vertices_Colors are defined in vertices, and Paint paint
5582contains Shader, Blend_Mode mode combines Vertices_Colors with Shader.
Cary Clark8032b982017-07-28 11:04:54 -04005583
Cary Clarkbad5ad72017-08-03 17:14:08 -04005584#Param vertices triangle mesh to draw ##
5585#Param mode combines Vertices_Colors with Shader, if both are present ##
5586#Param paint specifies the Shader, used as Vertices texture, may be nullptr ##
Cary Clark8032b982017-07-28 11:04:54 -04005587
5588#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04005589void draw(SkCanvas* canvas) {
5590 SkPaint paint;
5591 SkPoint points[] = { { 0, 0 }, { 250, 0 }, { 100, 100 }, { 0, 250 } };
5592 SkPoint texs[] = { { 0, 0 }, { 0, 250 }, { 250, 250 }, { 250, 0 } };
5593 SkColor colors[] = { SK_ColorRED, SK_ColorBLUE, SK_ColorYELLOW, SK_ColorCYAN };
5594 paint.setShader(SkGradientShader::MakeLinear(points, colors, nullptr, 4,
5595 SkShader::kClamp_TileMode));
5596 auto vertices = SkVertices::MakeCopy(SkVertices::kTriangleFan_VertexMode,
5597 SK_ARRAY_COUNT(points), points, texs, colors);
5598 canvas->drawVertices(vertices.get(), SkBlendMode::kDarken, paint);
Cary Clark8032b982017-07-28 11:04:54 -04005599}
5600##
5601
Cary Clark2ade9972017-11-02 17:49:34 -04005602#SeeAlso drawPatch drawPicture
Cary Clark8032b982017-07-28 11:04:54 -04005603
5604##
5605
5606# ------------------------------------------------------------------------------
5607
5608#Method void drawPatch(const SkPoint cubics[12], const SkColor colors[4],
5609 const SkPoint texCoords[4], SkBlendMode mode, const SkPaint& paint)
5610
Cary Clarkce101242017-09-01 15:51:02 -04005611Draws a Coons patch: the interpolation of four cubics with shared corners,
Cary Clark8032b982017-07-28 11:04:54 -04005612associating a color, and optionally a texture coordinate, with each corner.
5613
Cary Clarkbc5697d2017-10-04 14:31:33 -04005614The Coons patch uses Clip and Matrix, paint Shader, Color_Filter,
Cary Clarkbad5ad72017-08-03 17:14:08 -04005615Color_Alpha, Image_Filter, and Blend_Mode. If Shader is provided it is treated
5616as the Coons patch texture; Blend_Mode mode combines Color colors and Shader if
5617both are provided.
Cary Clark8032b982017-07-28 11:04:54 -04005618
Cary Clarkbc5697d2017-10-04 14:31:33 -04005619Point array cubics specifies four Cubics starting at the top-left corner,
Cary Clarkce101242017-09-01 15:51:02 -04005620in clockwise order, sharing every fourth point. The last Cubic ends at the
Cary Clarkbad5ad72017-08-03 17:14:08 -04005621first point.
Cary Clark8032b982017-07-28 11:04:54 -04005622
Cary Clarkbc5697d2017-10-04 14:31:33 -04005623Color array color associates colors with corners in top-left, top-right,
5624bottom-right, bottom-left order.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005625
5626If paint contains Shader, Point array texCoords maps Shader as texture to
Cary Clarkbc5697d2017-10-04 14:31:33 -04005627corners in top-left, top-right, bottom-right, bottom-left order.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005628
Cary Clarka523d2d2017-08-30 08:58:10 -04005629#Param cubics Path_Cubic array, sharing common points ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005630#Param colors Color array, one for each corner ##
Cary Clarkce101242017-09-01 15:51:02 -04005631#Param texCoords Point array of texture coordinates, mapping Shader to corners;
Cary Clarkbad5ad72017-08-03 17:14:08 -04005632 may be nullptr
Cary Clark579985c2017-07-31 11:48:27 -04005633#Param ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005634#Param mode Blend_Mode for colors, and for Shader if paint has one ##
5635#Param paint Shader, Color_Filter, Blend_Mode, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005636
5637#Example
5638#Image 5
Cary Clarkbad5ad72017-08-03 17:14:08 -04005639void draw(SkCanvas* canvas) {
5640 // SkBitmap source = cmbkygk;
5641 SkPaint paint;
5642 paint.setFilterQuality(kLow_SkFilterQuality);
5643 paint.setAntiAlias(true);
5644 SkPoint cubics[] = { { 3, 1 }, { 4, 2 }, { 5, 1 }, { 7, 3 },
5645 /* { 7, 3 }, */ { 6, 4 }, { 7, 5 }, { 5, 7 },
5646 /* { 5, 7 }, */ { 4, 6 }, { 3, 7 }, { 1, 5 },
5647 /* { 1, 5 }, */ { 2, 4 }, { 1, 3 }, /* { 3, 1 } */ };
5648 SkColor colors[] = { 0xbfff0000, 0xbf0000ff, 0xbfff00ff, 0xbf00ffff };
5649 SkPoint texCoords[] = { { -30, -30 }, { 162, -30}, { 162, 162}, { -30, 162} };
5650 paint.setShader(SkShader::MakeBitmapShader(source, SkShader::kClamp_TileMode,
5651 SkShader::kClamp_TileMode, nullptr));
5652 canvas->scale(15, 15);
5653 for (auto blend : { SkBlendMode::kSrcOver, SkBlendMode::kModulate, SkBlendMode::kXor } ) {
5654 canvas->drawPatch(cubics, colors, texCoords, blend, paint);
5655 canvas->translate(4, 4);
5656 }
Cary Clark8032b982017-07-28 11:04:54 -04005657}
5658##
5659
Cary Clark2ade9972017-11-02 17:49:34 -04005660#ToDo can patch use image filter? ##
5661#SeeAlso SeeAlso drawVertices drawPicture
Cary Clark8032b982017-07-28 11:04:54 -04005662
5663##
5664
5665# ------------------------------------------------------------------------------
5666
5667#Method void drawPatch(const SkPoint cubics[12], const SkColor colors[4],
5668 const SkPoint texCoords[4], const SkPaint& paint)
5669
Cary Clarkce101242017-09-01 15:51:02 -04005670Draws Cubic Coons patch: the interpolation of four cubics with shared corners,
Cary Clarkbad5ad72017-08-03 17:14:08 -04005671associating a color, and optionally a texture coordinate, with each corner.
Cary Clark8032b982017-07-28 11:04:54 -04005672
Cary Clarkbc5697d2017-10-04 14:31:33 -04005673The Coons patch uses Clip and Matrix, paint Shader, Color_Filter,
Cary Clarkbad5ad72017-08-03 17:14:08 -04005674Color_Alpha, Image_Filter, and Blend_Mode. If Shader is provided it is treated
5675as the Coons patch texture; Blend_Mode mode combines Color colors and Shader if
5676both are provided.
Cary Clark8032b982017-07-28 11:04:54 -04005677
Cary Clarkbc5697d2017-10-04 14:31:33 -04005678Point array cubics specifies four Cubics starting at the top-left corner,
Cary Clarkce101242017-09-01 15:51:02 -04005679in clockwise order, sharing every fourth point. The last Cubic ends at the
Cary Clarkbad5ad72017-08-03 17:14:08 -04005680first point.
5681
Cary Clarkbc5697d2017-10-04 14:31:33 -04005682Color array color associates colors with corners in top-left, top-right,
5683bottom-right, bottom-left order.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005684
5685If paint contains Shader, Point array texCoords maps Shader as texture to
Cary Clarkbc5697d2017-10-04 14:31:33 -04005686corners in top-left, top-right, bottom-right, bottom-left order.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005687
Cary Clarka523d2d2017-08-30 08:58:10 -04005688#Param cubics Path_Cubic array, sharing common points ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005689#Param colors Color array, one for each corner ##
Cary Clarkce101242017-09-01 15:51:02 -04005690#Param texCoords Point array of texture coordinates, mapping Shader to corners;
Cary Clarkbad5ad72017-08-03 17:14:08 -04005691 may be nullptr
Cary Clark579985c2017-07-31 11:48:27 -04005692#Param ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005693#Param paint Shader, Color_Filter, Blend_Mode, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005694
5695#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04005696void draw(SkCanvas* canvas) {
5697 SkPaint paint;
5698 paint.setAntiAlias(true);
5699 SkPoint cubics[] = { { 3, 1 }, { 4, 2 }, { 5, 1 }, { 7, 3 },
5700 /* { 7, 3 }, */ { 6, 4 }, { 7, 5 }, { 5, 7 },
5701 /* { 5, 7 }, */ { 4, 6 }, { 3, 7 }, { 1, 5 },
5702 /* { 1, 5 }, */ { 2, 4 }, { 1, 3 }, /* { 3, 1 } */ };
5703 SkColor colors[] = { SK_ColorRED, SK_ColorBLUE, SK_ColorYELLOW, SK_ColorCYAN };
5704 canvas->scale(30, 30);
5705 canvas->drawPatch(cubics, colors, nullptr, paint);
5706 SkPoint text[] = { {3,0.9f}, {4,2.5f}, {5,0.9f}, {7.5f,3.2f}, {5.5f,4.2f},
5707 {7.5f,5.2f}, {5,7.5f}, {4,5.9f}, {3,7.5f}, {0.5f,5.2f}, {2.5f,4.2f},
5708 {0.5f,3.2f} };
5709 paint.setTextSize(18.f / 30);
5710 paint.setTextAlign(SkPaint::kCenter_Align);
5711 for (int i = 0; i< 10; ++i) {
5712 char digit = '0' + i;
5713 canvas->drawText(&digit, 1, text[i].fX, text[i].fY, paint);
5714 }
5715 canvas->drawString("10", text[10].fX, text[10].fY, paint);
5716 canvas->drawString("11", text[11].fX, text[11].fY, paint);
5717 paint.setStyle(SkPaint::kStroke_Style);
5718 canvas->drawPoints(SkCanvas::kPolygon_PointMode, 12, cubics, paint);
5719 canvas->drawLine(cubics[11].fX, cubics[11].fY, cubics[0].fX, cubics[0].fY, paint);
Cary Clark8032b982017-07-28 11:04:54 -04005720}
5721##
5722
5723#Example
5724#Image 6
Cary Clarkbad5ad72017-08-03 17:14:08 -04005725void draw(SkCanvas* canvas) {
5726 // SkBitmap source = checkerboard;
5727 SkPaint paint;
5728 paint.setFilterQuality(kLow_SkFilterQuality);
5729 paint.setAntiAlias(true);
5730 SkPoint cubics[] = { { 3, 1 }, { 4, 2 }, { 5, 1 }, { 7, 3 },
5731 /* { 7, 3 }, */ { 6, 4 }, { 7, 5 }, { 5, 7 },
5732 /* { 5, 7 }, */ { 4, 6 }, { 3, 7 }, { 1, 5 },
5733 /* { 1, 5 }, */ { 2, 4 }, { 1, 3 }, /* { 3, 1 } */ };
5734 SkPoint texCoords[] = { { 0, 0 }, { 0, 62}, { 62, 62}, { 62, 0 } };
5735 paint.setShader(SkShader::MakeBitmapShader(source, SkShader::kClamp_TileMode,
5736 SkShader::kClamp_TileMode, nullptr));
5737 canvas->scale(30, 30);
5738 canvas->drawPatch(cubics, nullptr, texCoords, paint);
Cary Clark8032b982017-07-28 11:04:54 -04005739}
5740##
5741
Cary Clark2ade9972017-11-02 17:49:34 -04005742#ToDo can patch use image filter? ##
5743#SeeAlso SeeAlso drawVertices drawPicture
Cary Clark8032b982017-07-28 11:04:54 -04005744
5745##
5746
5747# ------------------------------------------------------------------------------
5748
5749#Method void drawAtlas(const SkImage* atlas, const SkRSXform xform[], const SkRect tex[],
5750 const SkColor colors[], int count, SkBlendMode mode, const SkRect* cullRect,
5751 const SkPaint* paint)
5752
5753Draw a set of sprites from atlas, using Clip, Matrix, and optional Paint paint.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005754paint uses Anti-alias, Color_Alpha, Color_Filter, Image_Filter, and Blend_Mode
5755to draw, if present. For each entry in the array, Rect tex locates sprite in
5756atlas, and RSXform xform transforms it into destination space.
5757
Cary Clark8032b982017-07-28 11:04:54 -04005758xform, text, and colors if present, must contain count entries.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005759Optional colors are applied for each sprite using Blend_Mode.
Cary Clark8032b982017-07-28 11:04:54 -04005760Optional cullRect is a conservative bounds of all transformed sprites.
Cary Clarkce101242017-09-01 15:51:02 -04005761If cullRect is outside of Clip, canvas can skip drawing.
Cary Clark8032b982017-07-28 11:04:54 -04005762
Cary Clarkbad5ad72017-08-03 17:14:08 -04005763#Param atlas Image containing sprites ##
5764#Param xform RSXform mappings for sprites in atlas ##
5765#Param tex Rect locations of sprites in atlas ##
Cary Clark6fc50412017-09-21 12:31:06 -04005766#Param colors one per sprite, blended with sprite using Blend_Mode; may be nullptr ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005767#Param count number of sprites to draw ##
5768#Param mode Blend_Mode combining colors and sprites ##
Cary Clark6fc50412017-09-21 12:31:06 -04005769#Param cullRect bounds of transformed sprites for efficient clipping; may be nullptr ##
5770#Param paint Color_Filter, Image_Filter, Blend_Mode, and so on; may be nullptr ##
Cary Clark8032b982017-07-28 11:04:54 -04005771
5772#Example
5773#Image 3
Cary Clarkbad5ad72017-08-03 17:14:08 -04005774void draw(SkCanvas* canvas) {
5775 // SkBitmap source = mandrill;
5776 SkRSXform xforms[] = { { .5f, 0, 0, 0 }, {0, .5f, 200, 100 } };
5777 SkRect tex[] = { { 0, 0, 250, 250 }, { 0, 0, 250, 250 } };
5778 SkColor colors[] = { 0x7f55aa00, 0x7f3333bf };
5779 const SkImage* imagePtr = image.get();
5780 canvas->drawAtlas(imagePtr, xforms, tex, colors, 2, SkBlendMode::kSrcOver, nullptr, nullptr);
Cary Clark8032b982017-07-28 11:04:54 -04005781}
5782##
5783
Cary Clark2ade9972017-11-02 17:49:34 -04005784#SeeAlso drawBitmap drawImage
Cary Clark8032b982017-07-28 11:04:54 -04005785
5786##
5787
5788# ------------------------------------------------------------------------------
5789
5790#Method void drawAtlas(const sk_sp<SkImage>& atlas, const SkRSXform xform[], const SkRect tex[],
5791 const SkColor colors[], int count, SkBlendMode mode, const SkRect* cullRect,
5792 const SkPaint* paint)
5793
5794Draw a set of sprites from atlas, using Clip, Matrix, and optional Paint paint.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005795paint uses Anti-alias, Color_Alpha, Color_Filter, Image_Filter, and Blend_Mode
5796to draw, if present. For each entry in the array, Rect tex locates sprite in
5797atlas, and RSXform xform transforms it into destination space.
5798
Cary Clark8032b982017-07-28 11:04:54 -04005799xform, text, and colors if present, must contain count entries.
5800Optional colors is applied for each sprite using Blend_Mode.
5801Optional cullRect is a conservative bounds of all transformed sprites.
Cary Clarkce101242017-09-01 15:51:02 -04005802If cullRect is outside of Clip, canvas can skip drawing.
Cary Clark8032b982017-07-28 11:04:54 -04005803
Cary Clarkbad5ad72017-08-03 17:14:08 -04005804#Param atlas Image containing sprites ##
5805#Param xform RSXform mappings for sprites in atlas ##
5806#Param tex Rect locations of sprites in atlas ##
Cary Clark6fc50412017-09-21 12:31:06 -04005807#Param colors one per sprite, blended with sprite using Blend_Mode; may be nullptr ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005808#Param count number of sprites to draw ##
5809#Param mode Blend_Mode combining colors and sprites ##
Cary Clark6fc50412017-09-21 12:31:06 -04005810#Param cullRect bounds of transformed sprites for efficient clipping; may be nullptr ##
5811#Param paint Color_Filter, Image_Filter, Blend_Mode, and so on; may be nullptr ##
Cary Clark8032b982017-07-28 11:04:54 -04005812
5813#Example
5814#Image 3
Cary Clarkbad5ad72017-08-03 17:14:08 -04005815void draw(SkCanvas* canvas) {
5816 // SkBitmap source = mandrill;
5817 SkRSXform xforms[] = { { .5f, 0, 0, 0 }, {0, .5f, 200, 100 } };
5818 SkRect tex[] = { { 0, 0, 250, 250 }, { 0, 0, 250, 250 } };
5819 SkColor colors[] = { 0x7f55aa00, 0x7f3333bf };
5820 SkPaint paint;
5821 paint.setAlpha(127);
5822 canvas->drawAtlas(image, xforms, tex, colors, 2, SkBlendMode::kPlus, nullptr, &paint);
Cary Clark8032b982017-07-28 11:04:54 -04005823}
5824##
5825
5826#ToDo bug in example on cpu side, gpu looks ok ##
5827
Cary Clark2ade9972017-11-02 17:49:34 -04005828#SeeAlso drawBitmap drawImage
5829
Cary Clark8032b982017-07-28 11:04:54 -04005830##
5831
5832# ------------------------------------------------------------------------------
5833
5834#Method void drawAtlas(const SkImage* atlas, const SkRSXform xform[], const SkRect tex[], int count,
5835 const SkRect* cullRect, const SkPaint* paint)
5836
5837Draw a set of sprites from atlas, using Clip, Matrix, and optional Paint paint.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005838paint uses Anti-alias, Color_Alpha, Color_Filter, Image_Filter, and Blend_Mode
5839to draw, if present. For each entry in the array, Rect tex locates sprite in
5840atlas, and RSXform xform transforms it into destination space.
5841
Cary Clark8032b982017-07-28 11:04:54 -04005842xform and text must contain count entries.
5843Optional cullRect is a conservative bounds of all transformed sprites.
Cary Clarkce101242017-09-01 15:51:02 -04005844If cullRect is outside of Clip, canvas can skip drawing.
Cary Clark8032b982017-07-28 11:04:54 -04005845
Cary Clarkbad5ad72017-08-03 17:14:08 -04005846#Param atlas Image containing sprites ##
5847#Param xform RSXform mappings for sprites in atlas ##
5848#Param tex Rect locations of sprites in atlas ##
5849#Param count number of sprites to draw ##
Cary Clark6fc50412017-09-21 12:31:06 -04005850#Param cullRect bounds of transformed sprites for efficient clipping; may be nullptr ##
5851#Param paint Color_Filter, Image_Filter, Blend_Mode, and so on; may be nullptr ##
Cary Clark8032b982017-07-28 11:04:54 -04005852
5853#Example
5854#Image 3
Cary Clarkbad5ad72017-08-03 17:14:08 -04005855void draw(SkCanvas* canvas) {
5856 // sk_sp<SkImage> image = mandrill;
5857 SkRSXform xforms[] = { { .5f, 0, 0, 0 }, {0, .5f, 200, 100 } };
5858 SkRect tex[] = { { 0, 0, 250, 250 }, { 0, 0, 250, 250 } };
5859 const SkImage* imagePtr = image.get();
5860 canvas->drawAtlas(imagePtr, xforms, tex, 2, nullptr, nullptr);
Cary Clark8032b982017-07-28 11:04:54 -04005861}
5862##
5863
Cary Clark2ade9972017-11-02 17:49:34 -04005864#SeeAlso drawBitmap drawImage
Cary Clark8032b982017-07-28 11:04:54 -04005865
5866##
5867
5868# ------------------------------------------------------------------------------
5869
5870#Method void drawAtlas(const sk_sp<SkImage>& atlas, const SkRSXform xform[], const SkRect tex[],
5871 int count, const SkRect* cullRect, const SkPaint* paint)
5872
5873Draw a set of sprites from atlas, using Clip, Matrix, and optional Paint paint.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005874paint uses Anti-alias, Color_Alpha, Color_Filter, Image_Filter, and Blend_Mode
5875to draw, if present. For each entry in the array, Rect tex locates sprite in
5876atlas, and RSXform xform transforms it into destination space.
5877
Cary Clark8032b982017-07-28 11:04:54 -04005878xform and text must contain count entries.
5879Optional cullRect is a conservative bounds of all transformed sprites.
Cary Clarkce101242017-09-01 15:51:02 -04005880If cullRect is outside of Clip, canvas can skip drawing.
Cary Clark8032b982017-07-28 11:04:54 -04005881
Cary Clarkbad5ad72017-08-03 17:14:08 -04005882#Param atlas Image containing sprites ##
5883#Param xform RSXform mappings for sprites in atlas ##
5884#Param tex Rect locations of sprites in atlas ##
5885#Param count number of sprites to draw ##
Cary Clark6fc50412017-09-21 12:31:06 -04005886#Param cullRect bounds of transformed sprites for efficient clipping; may be nullptr ##
5887#Param paint Color_Filter, Image_Filter, Blend_Mode, and so on; may be nullptr ##
Cary Clark8032b982017-07-28 11:04:54 -04005888
5889#Example
5890#Image 3
Cary Clarkbad5ad72017-08-03 17:14:08 -04005891void draw(SkCanvas* canvas) {
5892 // sk_sp<SkImage> image = mandrill;
5893 SkRSXform xforms[] = { { 1, 0, 0, 0 }, {0, 1, 300, 100 } };
5894 SkRect tex[] = { { 0, 0, 200, 200 }, { 200, 0, 400, 200 } };
5895 canvas->drawAtlas(image, xforms, tex, 2, nullptr, nullptr);
Cary Clark8032b982017-07-28 11:04:54 -04005896}
5897##
5898
Cary Clark2ade9972017-11-02 17:49:34 -04005899#SeeAlso drawBitmap drawImage
Cary Clark8032b982017-07-28 11:04:54 -04005900
5901##
5902
5903# ------------------------------------------------------------------------------
5904
Cary Clark73fa9722017-08-29 17:36:51 -04005905#Method void drawDrawable(SkDrawable* drawable, const SkMatrix* matrix = nullptr)
Cary Clark8032b982017-07-28 11:04:54 -04005906
5907Draw Drawable drawable using Clip and Matrix, concatenated with
5908optional matrix.
5909
5910If Canvas has an asynchronous implementation, as is the case
5911when it is recording into Picture, then drawable will be referenced,
5912so that SkDrawable::draw() can be called when the operation is finalized. To force
5913immediate drawing, call SkDrawable::draw() instead.
5914
Cary Clarkbad5ad72017-08-03 17:14:08 -04005915#Param drawable custom struct encapsulating drawing commands ##
5916#Param matrix transformation applied to drawing; may be nullptr ##
Cary Clark8032b982017-07-28 11:04:54 -04005917
5918#Example
5919#Height 100
5920#Function
Cary Clarkbad5ad72017-08-03 17:14:08 -04005921struct MyDrawable : public SkDrawable {
5922 SkRect onGetBounds() override { return SkRect::MakeWH(50, 100); }
5923
5924 void onDraw(SkCanvas* canvas) override {
5925 SkPath path;
5926 path.conicTo(10, 90, 50, 90, 0.9f);
5927 SkPaint paint;
5928 paint.setColor(SK_ColorBLUE);
5929 canvas->drawRect(path.getBounds(), paint);
5930 paint.setAntiAlias(true);
5931 paint.setColor(SK_ColorWHITE);
5932 canvas->drawPath(path, paint);
5933 }
5934};
5935
5936#Function ##
5937void draw(SkCanvas* canvas) {
5938 sk_sp<SkDrawable> drawable(new MyDrawable);
5939 SkMatrix matrix;
5940 matrix.setTranslate(10, 10);
5941 canvas->drawDrawable(drawable.get(), &matrix);
Cary Clark8032b982017-07-28 11:04:54 -04005942}
5943##
5944
Cary Clark2ade9972017-11-02 17:49:34 -04005945#SeeAlso SkDrawable drawPicture
Cary Clark8032b982017-07-28 11:04:54 -04005946
5947##
5948
5949# ------------------------------------------------------------------------------
5950
5951#Method void drawDrawable(SkDrawable* drawable, SkScalar x, SkScalar y)
5952
5953Draw Drawable drawable using Clip and Matrix, offset by (x, y).
5954
5955If Canvas has an asynchronous implementation, as is the case
5956when it is recording into Picture, then drawable will be referenced,
5957so that SkDrawable::draw() can be called when the operation is finalized. To force
5958immediate drawing, call SkDrawable::draw() instead.
5959
Cary Clarkbad5ad72017-08-03 17:14:08 -04005960#Param drawable custom struct encapsulating drawing commands ##
5961#Param x offset into Canvas writable pixels in x ##
5962#Param y offset into Canvas writable pixels in y ##
Cary Clark8032b982017-07-28 11:04:54 -04005963
5964#Example
5965#Height 100
5966#Function
Cary Clarkbad5ad72017-08-03 17:14:08 -04005967struct MyDrawable : public SkDrawable {
5968 SkRect onGetBounds() override { return SkRect::MakeWH(50, 100); }
5969
5970 void onDraw(SkCanvas* canvas) override {
5971 SkPath path;
5972 path.conicTo(10, 90, 50, 90, 0.9f);
5973 SkPaint paint;
5974 paint.setColor(SK_ColorBLUE);
5975 canvas->drawRect(path.getBounds(), paint);
5976 paint.setAntiAlias(true);
5977 paint.setColor(SK_ColorWHITE);
5978 canvas->drawPath(path, paint);
5979 }
5980};
5981
5982#Function ##
5983void draw(SkCanvas* canvas) {
5984 sk_sp<SkDrawable> drawable(new MyDrawable);
5985 canvas->drawDrawable(drawable.get(), 10, 10);
Cary Clark8032b982017-07-28 11:04:54 -04005986}
5987##
5988
Cary Clark2ade9972017-11-02 17:49:34 -04005989#SeeAlso SkDrawable drawPicture
Cary Clark8032b982017-07-28 11:04:54 -04005990
5991##
5992
5993# ------------------------------------------------------------------------------
5994
5995#Method void drawAnnotation(const SkRect& rect, const char key[], SkData* value)
5996
5997Associate Rect on Canvas when an annotation; a key-value pair, where the key is
5998a null-terminated utf8 string, and optional value is stored as Data.
5999
6000Only some canvas implementations, such as recording to Picture, or drawing to
6001Document_PDF, use annotations.
6002
Cary Clarkbad5ad72017-08-03 17:14:08 -04006003#Param rect Rect extent of canvas to annotate ##
6004#Param key string used for lookup ##
6005#Param value data holding value stored in annotation ##
Cary Clark8032b982017-07-28 11:04:54 -04006006
6007#Example
6008 #Height 1
6009 const char text[] = "Click this link!";
6010 SkRect bounds;
6011 SkPaint paint;
6012 paint.setTextSize(40);
6013 (void)paint.measureText(text, strlen(text), &bounds);
6014 const char url[] = "https://www.google.com/";
6015 sk_sp<SkData> urlData(SkData::MakeWithCString(url));
6016 canvas->drawAnnotation(bounds, "url_key", urlData.get());
6017##
6018
Cary Clark2ade9972017-11-02 17:49:34 -04006019#SeeAlso SkPicture SkDocument
Cary Clark8032b982017-07-28 11:04:54 -04006020
6021##
6022
6023# ------------------------------------------------------------------------------
6024
6025#Method void drawAnnotation(const SkRect& rect, const char key[], const sk_sp<SkData>& value)
6026
6027Associate Rect on Canvas when an annotation; a key-value pair, where the key is
6028a null-terminated utf8 string, and optional value is stored as Data.
6029
6030Only some canvas implementations, such as recording to Picture, or drawing to
6031Document_PDF, use annotations.
6032
Cary Clarkbad5ad72017-08-03 17:14:08 -04006033#Param rect Rect extent of canvas to annotate ##
6034#Param key string used for lookup ##
6035#Param value data holding value stored in annotation ##
Cary Clark8032b982017-07-28 11:04:54 -04006036
6037#Example
6038#Height 1
6039 const char text[] = "Click this link!";
6040 SkRect bounds;
6041 SkPaint paint;
6042 paint.setTextSize(40);
6043 (void)paint.measureText(text, strlen(text), &bounds);
6044 const char url[] = "https://www.google.com/";
6045 sk_sp<SkData> urlData(SkData::MakeWithCString(url));
6046 canvas->drawAnnotation(bounds, "url_key", urlData.get());
6047##
6048
Cary Clark2ade9972017-11-02 17:49:34 -04006049#SeeAlso SkPicture SkDocument
Cary Clark8032b982017-07-28 11:04:54 -04006050
6051##
6052
6053#Method SkDrawFilter* getDrawFilter() const
6054
6055Legacy call to be deprecated.
6056
6057#Deprecated
6058##
6059
6060##
6061
6062#Method virtual SkDrawFilter* setDrawFilter(SkDrawFilter* filter)
6063
6064Legacy call to be deprecated.
6065
6066#Deprecated
6067##
6068
6069##
6070
6071# ------------------------------------------------------------------------------
6072
6073#Method virtual bool isClipEmpty() const
6074
6075Returns true if Clip is empty; that is, nothing will draw.
6076
Cary Clarkbad5ad72017-08-03 17:14:08 -04006077May do work when called; it should not be called
Cary Clark8032b982017-07-28 11:04:54 -04006078more often than needed. However, once called, subsequent calls perform no
6079work until Clip changes.
6080
Cary Clarkbad5ad72017-08-03 17:14:08 -04006081#Return true if Clip is empty ##
Cary Clark8032b982017-07-28 11:04:54 -04006082
6083#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04006084 void draw(SkCanvas* canvas) {
6085 SkDebugf("clip is%s empty\n", canvas->isClipEmpty() ? "" : " not");
6086 SkPath path;
6087 canvas->clipPath(path);
6088 SkDebugf("clip is%s empty\n", canvas->isClipEmpty() ? "" : " not");
Cary Clark8032b982017-07-28 11:04:54 -04006089 }
6090 #StdOut
Cary Clarkbad5ad72017-08-03 17:14:08 -04006091 clip is not empty
Cary Clark8032b982017-07-28 11:04:54 -04006092 clip is empty
6093 ##
6094##
6095
Cary Clark2ade9972017-11-02 17:49:34 -04006096#SeeAlso isClipRect getLocalClipBounds getDeviceClipBounds
Cary Clark8032b982017-07-28 11:04:54 -04006097
6098##
6099
6100# ------------------------------------------------------------------------------
6101
6102#Method virtual bool isClipRect() const
6103
6104Returns true if Clip is Rect and not empty.
6105Returns false if the clip is empty, or if it is not Rect.
6106
Cary Clarkbad5ad72017-08-03 17:14:08 -04006107#Return true if Clip is Rect and not empty ##
Cary Clark8032b982017-07-28 11:04:54 -04006108
6109#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04006110 void draw(SkCanvas* canvas) {
6111 SkDebugf("clip is%s rect\n", canvas->isClipRect() ? "" : " not");
6112 canvas->clipRect({0, 0, 0, 0});
6113 SkDebugf("clip is%s rect\n", canvas->isClipRect() ? "" : " not");
Cary Clark8032b982017-07-28 11:04:54 -04006114 }
6115 #StdOut
Cary Clarkbad5ad72017-08-03 17:14:08 -04006116 clip is rect
Cary Clark8032b982017-07-28 11:04:54 -04006117 clip is not rect
6118 ##
6119##
6120
Cary Clark2ade9972017-11-02 17:49:34 -04006121#SeeAlso isClipEmpty getLocalClipBounds getDeviceClipBounds
Cary Clark8032b982017-07-28 11:04:54 -04006122
6123##
6124
6125#Class SkCanvas ##
Cary Clark884dd7d2017-10-11 10:37:52 -04006126
6127#Class SkAutoCanvasRestore
6128
6129Stack helper class calls SkCanvas::restoreToCount() when SkAutoCanvasRestore
6130goes out of scope. Use this to guarantee that the canvas is restored to a known
6131state.
6132
6133#Method SkAutoCanvasRestore(SkCanvas* canvas, bool doSave)
6134
6135Preserves Canvas save count. Optionally saves Canvas Clip and Matrix.
6136
6137#Param canvas Canvas to guard ##
6138#Param doSave call SkCanvas::save() ##
6139
6140#Return utility to restore Canvas state on destructor ##
6141
6142#Example
Cary Clark2ade9972017-11-02 17:49:34 -04006143#Height 128
6144 SkPaint p;
6145 p.setAntiAlias(true);
6146 p.setTextSize(64);
6147 for (SkScalar sx : { -1, 1 } ) {
6148 for (SkScalar sy : { -1, 1 } ) {
6149 SkAutoCanvasRestore autoRestore(canvas, true);
6150 SkMatrix m = SkMatrix::MakeAll(sx, 1, 96, 0, sy, 64, 0, 0, 1);
6151 canvas->concat(m);
6152 canvas->drawString("R", 0, 0, p);
6153 }
6154 }
Cary Clark884dd7d2017-10-11 10:37:52 -04006155##
6156
6157#SeeAlso SkCanvas::save SkCanvas::restore
6158
6159##
6160
6161#Method ~SkAutoCanvasRestore()
6162
Cary Clark2ade9972017-11-02 17:49:34 -04006163Restores Canvas to saved state. Destructor is called when container goes out of
6164scope.
Cary Clark884dd7d2017-10-11 10:37:52 -04006165
Cary Clark2ade9972017-11-02 17:49:34 -04006166#NoExample
Cary Clark884dd7d2017-10-11 10:37:52 -04006167##
6168
6169#SeeAlso SkCanvas::save SkCanvas::restore
6170
6171##
6172
6173#Method void restore()
6174
Cary Clark154beea2017-10-26 07:58:48 -04006175Restores Canvas to saved state immediately. Subsequent calls and
6176~SkAutoCanvasRestore have no effect.
Cary Clark884dd7d2017-10-11 10:37:52 -04006177
6178#Example
Cary Clark2ade9972017-11-02 17:49:34 -04006179for (bool callRestore : { false, true } ) {
6180 for (bool saveCanvas : {false, true} ) {
6181 SkAutoCanvasRestore autoRestore(canvas, saveCanvas);
6182 if (!saveCanvas) {
6183 canvas->save();
6184 }
6185 SkDebugf("saveCanvas: %s before restore: %d\n",
6186 saveCanvas ? "true" : "false", canvas->getSaveCount());
6187 if (callRestore) autoRestore.restore();
6188 SkDebugf("saveCanvas: %s after restore: %d\n",
6189 saveCanvas ? "true" : "false", canvas->getSaveCount());
6190 }
6191}
6192SkDebugf("final count: %d\n", canvas->getSaveCount());
6193#StdOut
6194saveCanvas: false before restore: 2
6195saveCanvas: false after restore: 2
6196saveCanvas: true before restore: 2
6197saveCanvas: true after restore: 2
6198saveCanvas: false before restore: 2
6199saveCanvas: false after restore: 1
6200saveCanvas: true before restore: 2
6201saveCanvas: true after restore: 1
6202final count: 1
6203##
Cary Clark884dd7d2017-10-11 10:37:52 -04006204##
6205
6206#SeeAlso SkCanvas::save SkCanvas::restore
6207
6208##
6209
6210#Class SkAutoCanvasRestore ##
6211
Cary Clark8032b982017-07-28 11:04:54 -04006212#Topic Canvas ##