blob: efbf41f57efda2bf20a38502b2d15dd2874f885f [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 Clarka560c472017-11-27 10:44:06 -0500112# 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
Cary Clarka560c472017-11-27 10:44:06 -0500171#Method static std::unique_ptr<SkCanvas> MakeRasterDirect(const SkImageInfo& info, void* pixels,
172 size_t rowBytes,
173 const SkSurfaceProps* props = nullptr)
Cary Clark8032b982017-07-28 11:04:54 -0400174
Cary Clarkbad5ad72017-08-03 17:14:08 -0400175Allocates raster Canvas that will draw directly into pixels.
Cary Clark8032b982017-07-28 11:04:54 -0400176
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 Clarka560c472017-11-27 10:44:06 -0500189Pixels are not initialized.
190To access pixels after drawing, call flush() or peekPixels.
Cary Clarkbad5ad72017-08-03 17:14:08 -0400191
192#Param info width, height, Image_Color_Type, Image_Alpha_Type, Color_Space, of Raster_Surface;
193 width, or height, or both, may be zero
Cary Clark8032b982017-07-28 11:04:54 -0400194##
Cary Clarkf05bdda2017-08-24 12:59:48 -0400195#Param pixels pointer to destination pixels buffer
Cary Clark8032b982017-07-28 11:04:54 -0400196##
Cary Clarkf05bdda2017-08-24 12:59:48 -0400197#Param rowBytes interval from one Surface row to the next, or zero
Cary Clark8032b982017-07-28 11:04:54 -0400198##
Cary Clarka560c472017-11-27 10:44:06 -0500199#Param props LCD striping orientation and setting for device independent fonts;
200 may be nullptr
201##
Cary Clark8032b982017-07-28 11:04:54 -0400202
Cary Clarkbad5ad72017-08-03 17:14:08 -0400203#Return Canvas if all parameters are valid; otherwise, nullptr ##
Cary Clark8032b982017-07-28 11:04:54 -0400204
205#Example
206 #Description
207 Allocates a three by three bitmap, clears it to white, and draws a black pixel
208 in the center.
209 ##
Cary Clarkbad5ad72017-08-03 17:14:08 -0400210void draw(SkCanvas* ) {
Cary Clarkce101242017-09-01 15:51:02 -0400211 SkImageInfo info = SkImageInfo::MakeN32Premul(3, 3); // device aligned, 32 bpp, Premultiplied
Cary Clarkbad5ad72017-08-03 17:14:08 -0400212 const size_t minRowBytes = info.minRowBytes(); // bytes used by one bitmap row
Cary Clarka560c472017-11-27 10:44:06 -0500213 const size_t size = info.computeMinByteSize(); // bytes used by all rows
Cary Clarkbad5ad72017-08-03 17:14:08 -0400214 SkAutoTMalloc<SkPMColor> storage(size); // allocate storage for pixels
215 SkPMColor* pixels = storage.get(); // get pointer to allocated storage
216 // create a SkCanvas backed by a raster device, and delete it when the
217 // function goes out of scope.
218 std::unique_ptr<SkCanvas> canvas = SkCanvas::MakeRasterDirect(info, pixels, minRowBytes);
Cary Clarkce101242017-09-01 15:51:02 -0400219 canvas->clear(SK_ColorWHITE); // white is Unpremultiplied, in ARGB order
Cary Clarkbad5ad72017-08-03 17:14:08 -0400220 canvas->flush(); // ensure that pixels are cleared
Cary Clarkce101242017-09-01 15:51:02 -0400221 SkPMColor pmWhite = pixels[0]; // the Premultiplied format may vary
Cary Clarkbad5ad72017-08-03 17:14:08 -0400222 SkPaint paint; // by default, draws black
223 canvas->drawPoint(1, 1, paint); // draw in the center
224 canvas->flush(); // ensure that point was drawn
225 for (int y = 0; y < info.height(); ++y) {
226 for (int x = 0; x < info.width(); ++x) {
227 SkDebugf("%c", *pixels++ == pmWhite ? '-' : 'x');
228 }
229 SkDebugf("\n");
230 }
Cary Clark8032b982017-07-28 11:04:54 -0400231}
232 #StdOut
233 ---
234 -x-
235 ---
236 ##
237##
238
Cary Clark8032b982017-07-28 11:04:54 -0400239#SeeAlso MakeRasterDirectN32 SkSurface::MakeRasterDirect
Cary Clark2ade9972017-11-02 17:49:34 -0400240
Cary Clark8032b982017-07-28 11:04:54 -0400241##
242
243# ------------------------------------------------------------------------------
244
245#Method static std::unique_ptr<SkCanvas> MakeRasterDirectN32(int width, int height, SkPMColor* pixels,
246 size_t rowBytes)
247
Cary Clarkbad5ad72017-08-03 17:14:08 -0400248Allocates raster Canvas specified by inline image specification. Subsequent Canvas
249calls draw into pixels.
Cary Clark8032b982017-07-28 11:04:54 -0400250Image_Color_Type is set to kN32_SkColorType.
251Image_Alpha_Type is set to kPremul_SkAlphaType.
252To access pixels after drawing, call flush() or peekPixels.
253
Cary Clarkbad5ad72017-08-03 17:14:08 -0400254Canvas is returned if all parameters are valid.
255Valid parameters include:
Cary Clarkf05bdda2017-08-24 12:59:48 -0400256width and height are zero or positive;
Cary Clarkbad5ad72017-08-03 17:14:08 -0400257pixels is not nullptr;
Cary Clarkf05bdda2017-08-24 12:59:48 -0400258rowBytes is zero or large enough to contain width pixels of kN32_SkColorType.
Cary Clarkbad5ad72017-08-03 17:14:08 -0400259
Cary Clarkce101242017-09-01 15:51:02 -0400260Pass zero for rowBytes to compute rowBytes from width and size of pixel.
Cary Clarkf05bdda2017-08-24 12:59:48 -0400261If rowBytes is greater than zero, it must be equal to or greater than
262width times bytes required for Image_Color_Type.
263
264Pixel buffer size should be height times rowBytes.
Cary Clarkbad5ad72017-08-03 17:14:08 -0400265
266#Param width pixel column count on Raster_Surface created; must be zero or greater ##
Cary Clarkbc5697d2017-10-04 14:31:33 -0400267#Param height pixel row count on Raster_Surface created; must be zero or greater ##
Cary Clarkbad5ad72017-08-03 17:14:08 -0400268#Param pixels pointer to destination pixels buffer; buffer size should be height
Cary Clarkf05bdda2017-08-24 12:59:48 -0400269 times rowBytes
Cary Clark8032b982017-07-28 11:04:54 -0400270##
Cary Clarkf05bdda2017-08-24 12:59:48 -0400271#Param rowBytes interval from one Surface row to the next, or zero
Cary Clark8032b982017-07-28 11:04:54 -0400272##
273
Cary Clarkbad5ad72017-08-03 17:14:08 -0400274#Return Canvas if all parameters are valid; otherwise, nullptr ##
Cary Clark8032b982017-07-28 11:04:54 -0400275
276#Example
277 #Description
278 Allocates a three by three bitmap, clears it to white, and draws a black pixel
279 in the center.
280 ##
281void draw(SkCanvas* ) {
282 const int width = 3;
283 const int height = 3;
Cary Clarkce101242017-09-01 15:51:02 -0400284 SkPMColor pixels[height][width]; // allocate a 3x3 Premultiplied bitmap on the stack
Cary Clark8032b982017-07-28 11:04:54 -0400285 // create a SkCanvas backed by a raster device, and delete it when the
286 // function goes out of scope.
287 std::unique_ptr<SkCanvas> canvas = SkCanvas::MakeRasterDirectN32(
288 width,
289 height,
Cary Clarkbc5697d2017-10-04 14:31:33 -0400290 pixels[0], // top-left of the bitmap
Cary Clark8032b982017-07-28 11:04:54 -0400291 sizeof(pixels[0])); // byte width of the each row
Cary Clarkce101242017-09-01 15:51:02 -0400292 // write a premultiplied value for white into all pixels in the bitmap
Cary Clark8032b982017-07-28 11:04:54 -0400293 canvas->clear(SK_ColorWHITE);
Cary Clarkce101242017-09-01 15:51:02 -0400294 SkPMColor pmWhite = pixels[0][0]; // the Premultiplied format may vary
Cary Clark8032b982017-07-28 11:04:54 -0400295 SkPaint paint; // by default, draws black
296 canvas->drawPoint(1, 1, paint); // draw in the center
297 canvas->flush(); // ensure that pixels is ready to be read
298 for (int y = 0; y < height; ++y) {
299 for (int x = 0; x < width; ++x) {
300 SkDebugf("%c", pixels[y][x] == pmWhite ? '-' : 'x');
301 }
302 SkDebugf("\n");
303 }
304}
305 #StdOut
306 ---
307 -x-
308 ---
309 ##
310##
311
Cary Clark2ade9972017-11-02 17:49:34 -0400312#SeeAlso MakeRasterDirect SkSurface::MakeRasterDirect SkImageInfo::MakeN32Premul
Cary Clark8032b982017-07-28 11:04:54 -0400313
314##
315
316# ------------------------------------------------------------------------------
317
318#Method SkCanvas()
319
Cary Clarkd0530ba2017-09-14 11:25:39 -0400320Creates an empty Canvas with no backing device or pixels, with
Cary Clarkf05bdda2017-08-24 12:59:48 -0400321a width and height of zero.
Cary Clark8032b982017-07-28 11:04:54 -0400322
Cary Clarkd0530ba2017-09-14 11:25:39 -0400323#Return empty Canvas ##
Cary Clark8032b982017-07-28 11:04:54 -0400324
325#Example
326
327#Description
328Passes a placeholder to a function that requires one.
329##
330
331#Function
Cary Clarkbad5ad72017-08-03 17:14:08 -0400332// Returns true if either the canvas rotates the text by 90 degrees, or the paint does.
333static void check_for_up_and_down_text(const SkCanvas* canvas, const SkPaint& paint) {
334 bool paintHasVertical = paint.isVerticalText();
335 const SkMatrix& matrix = canvas->getTotalMatrix();
336 bool matrixIsVertical = matrix.preservesRightAngles() && !matrix.isScaleTranslate();
337 SkDebugf("paint draws text %s\n", paintHasVertical != matrixIsVertical ?
338 "top to bottom" : "left to right");
339}
340
341static void check_for_up_and_down_text(const SkPaint& paint) {
342 SkCanvas canvas; // placeholder only, does not have an associated device
343 check_for_up_and_down_text(&canvas, paint);
344}
345
Cary Clark8032b982017-07-28 11:04:54 -0400346##
Cary Clarkbad5ad72017-08-03 17:14:08 -0400347void draw(SkCanvas* canvas) {
348 SkPaint paint;
349 check_for_up_and_down_text(paint); // paint draws text left to right
350 paint.setVerticalText(true);
351 check_for_up_and_down_text(paint); // paint draws text top to bottom
352 paint.setVerticalText(false);
353 canvas->rotate(90);
354 check_for_up_and_down_text(canvas, paint); // paint draws text top to bottom
355}
Cary Clark8032b982017-07-28 11:04:54 -0400356
357 #StdOut
358 paint draws text left to right
359 paint draws text top to bottom
360 paint draws text top to bottom
361 ##
362##
363
Cary Clark2ade9972017-11-02 17:49:34 -0400364#SeeAlso MakeRasterDirect SkRasterHandleAllocator::MakeCanvas SkSurface::getCanvas SkCreateColorSpaceXformCanvas
Cary Clark8032b982017-07-28 11:04:54 -0400365
366##
367
368# ------------------------------------------------------------------------------
369
Cary Clark73fa9722017-08-29 17:36:51 -0400370#Method SkCanvas(int width, int height, const SkSurfaceProps* props = nullptr)
Cary Clark8032b982017-07-28 11:04:54 -0400371
372Creates Canvas of the specified dimensions without a Surface.
Cary Clarkce101242017-09-01 15:51:02 -0400373Used by Subclasses with custom implementations for draw methods.
Cary Clark8032b982017-07-28 11:04:54 -0400374
Cary Clarkd0530ba2017-09-14 11:25:39 -0400375If props equals nullptr, Surface_Properties are created with
376Surface_Properties_Legacy_Font_Host settings, which choose the pixel striping
377direction and order. Since a platform may dynamically change its direction when
378the device is rotated, and since a platform may have multiple monitors with
379different characteristics, it is best not to rely on this legacy behavior.
Cary Clark8032b982017-07-28 11:04:54 -0400380
Cary Clarkbad5ad72017-08-03 17:14:08 -0400381#Param width zero or greater ##
382#Param height zero or greater ##
383#Param props LCD striping orientation and setting for device independent fonts;
384 may be nullptr
385##
386
387#Return Canvas placeholder with dimensions ##
Cary Clark8032b982017-07-28 11:04:54 -0400388
389#Example
390 SkCanvas canvas(10, 20); // 10 units wide, 20 units high
391 canvas.clipRect(SkRect::MakeXYWH(30, 40, 5, 10)); // clip is outside canvas' device
392 SkDebugf("canvas %s empty\n", canvas.getDeviceClipBounds().isEmpty() ? "is" : "is not");
393
394 #StdOut
395 canvas is empty
396 ##
397##
398
Cary Clark2ade9972017-11-02 17:49:34 -0400399#SeeAlso MakeRasterDirect SkSurfaceProps SkPixelGeometry SkCreateColorSpaceXformCanvas
Cary Clark8032b982017-07-28 11:04:54 -0400400
401##
402
403# ------------------------------------------------------------------------------
404
405#Method explicit SkCanvas(SkBaseDevice* device)
406
407Construct a canvas that draws into device.
408Used by child classes of SkCanvas.
409
410#ToDo Since SkBaseDevice is private, shouldn't this be private also? ##
411
Cary Clarkbad5ad72017-08-03 17:14:08 -0400412#Param device specifies a device for the canvas to draw into ##
Cary Clark8032b982017-07-28 11:04:54 -0400413
Cary Clarkbad5ad72017-08-03 17:14:08 -0400414#Return Canvas that can be used to draw into device ##
Cary Clark8032b982017-07-28 11:04:54 -0400415
416#Example
417#Error "Unsure how to create a meaningful example."
418 SkPDFCanvas::SkPDFCanvas(const sk_sp<SkPDFDevice>& dev)
419 : SkCanvas(dev.get()) {}
420##
421
Cary Clark2ade9972017-11-02 17:49:34 -0400422#ToDo either remove doc or figure out a way to fiddle it ##
423
424#SeeAlso MakeRasterDirect SkRasterHandleAllocator::MakeCanvas SkSurface::getCanvas SkCreateColorSpaceXformCanvas
Cary Clark8032b982017-07-28 11:04:54 -0400425
426##
427
428# ------------------------------------------------------------------------------
429
430#Method explicit SkCanvas(const SkBitmap& bitmap)
431
432Construct a canvas that draws into bitmap.
433Sets SkSurfaceProps::kLegacyFontHost_InitType in constructed Surface.
434
Cary Clarkbad5ad72017-08-03 17:14:08 -0400435Bitmap is copied so that subsequently editing bitmap will not affect
436constructed Canvas.
437
438May be deprecated in the future.
439
Cary Clark8032b982017-07-28 11:04:54 -0400440#ToDo Should be deprecated? ##
441
Cary Clarkbad5ad72017-08-03 17:14:08 -0400442#Param bitmap width, height, Image_Color_Type, Image_Alpha_Type, and pixel
443 storage of Raster_Surface
Cary Clark8032b982017-07-28 11:04:54 -0400444##
445
Cary Clarkbad5ad72017-08-03 17:14:08 -0400446#Return Canvas that can be used to draw into bitmap ##
Cary Clark8032b982017-07-28 11:04:54 -0400447
448#Example
449#Description
450The actual output depends on the installed fonts.
451##
452 SkBitmap bitmap;
453 // create a bitmap 5 wide and 11 high
454 bitmap.allocPixels(SkImageInfo::MakeN32Premul(5, 11));
455 SkCanvas canvas(bitmap);
Cary Clarkce101242017-09-01 15:51:02 -0400456 canvas.clear(SK_ColorWHITE); // white is Unpremultiplied, in ARGB order
Cary Clark8032b982017-07-28 11:04:54 -0400457 SkPixmap pixmap; // provides guaranteed access to the drawn pixels
458 if (!canvas.peekPixels(&pixmap)) {
459 SkDebugf("peekPixels should never fail.\n");
460 }
Cary Clarkbc5697d2017-10-04 14:31:33 -0400461 const SkPMColor* pixels = pixmap.addr32(); // points to top-left of bitmap
Cary Clarkce101242017-09-01 15:51:02 -0400462 SkPMColor pmWhite = pixels[0]; // the Premultiplied format may vary
Cary Clark8032b982017-07-28 11:04:54 -0400463 SkPaint paint; // by default, draws black, 12 point text
464 canvas.drawString("!", 1, 10, paint); // 1 char at baseline (1, 10)
465 for (int y = 0; y < bitmap.height(); ++y) {
466 for (int x = 0; x < bitmap.width(); ++x) {
467 SkDebugf("%c", *pixels++ == pmWhite ? '-' : 'x');
468 }
469 SkDebugf("\n");
470 }
471
472 #StdOut
Cary Clarkd0530ba2017-09-14 11:25:39 -0400473 -----
474 ---x-
475 ---x-
476 ---x-
477 ---x-
478 ---x-
479 ---x-
480 -----
481 ---x-
482 ---x-
Cary Clark8032b982017-07-28 11:04:54 -0400483 -----
484 #StdOut ##
485##
486
Cary Clark2ade9972017-11-02 17:49:34 -0400487#SeeAlso MakeRasterDirect SkRasterHandleAllocator::MakeCanvas SkSurface::getCanvas SkCreateColorSpaceXformCanvas
Cary Clark8032b982017-07-28 11:04:54 -0400488
489##
490
Cary Clarkbad5ad72017-08-03 17:14:08 -0400491#EnumClass ColorBehavior
Cary Clark8032b982017-07-28 11:04:54 -0400492
493#Private
494Android framework only.
495##
496
497#Code
498 enum class ColorBehavior {
499 kLegacy,
500 };
501##
502#Const kLegacy 0
Cary Clarkbad5ad72017-08-03 17:14:08 -0400503 Is a placeholder to allow specialized constructor; has no meaning.
Cary Clark8032b982017-07-28 11:04:54 -0400504##
505##
506
Cary Clarkbad5ad72017-08-03 17:14:08 -0400507#Method SkCanvas(const SkBitmap& bitmap, ColorBehavior behavior)
508
509#Private
510Android framework only.
511##
512
513#Param bitmap specifies a bitmap for the canvas to draw into ##
514#Param behavior specializes this constructor; value is unused ##
515#Return Canvas that can be used to draw into bitmap ##
516
517#NoExample
518##
519##
Cary Clark8032b982017-07-28 11:04:54 -0400520
521# ------------------------------------------------------------------------------
522
523#Method SkCanvas(const SkBitmap& bitmap, const SkSurfaceProps& props)
524
525Construct a canvas that draws into bitmap.
526Use props to match the device characteristics, like LCD striping.
527
Cary Clarkbad5ad72017-08-03 17:14:08 -0400528bitmap is copied so that subsequently editing bitmap will not affect
529constructed Canvas.
530
531#Param bitmap width, height, Image_Color_Type, Image_Alpha_Type,
532 and pixel storage of Raster_Surface
Cary Clark8032b982017-07-28 11:04:54 -0400533##
Cary Clarkbad5ad72017-08-03 17:14:08 -0400534#Param props order and orientation of RGB striping; and whether to use
535 device independent fonts
Cary Clark8032b982017-07-28 11:04:54 -0400536##
537
Cary Clarkbad5ad72017-08-03 17:14:08 -0400538#Return Canvas that can be used to draw into bitmap ##
Cary Clark8032b982017-07-28 11:04:54 -0400539
540#Example
541#Description
542The actual output depends on the installed fonts.
543##
544 SkBitmap bitmap;
545 // create a bitmap 5 wide and 11 high
546 bitmap.allocPixels(SkImageInfo::MakeN32Premul(5, 11));
547 SkCanvas canvas(bitmap, SkSurfaceProps(0, kUnknown_SkPixelGeometry));
Cary Clarkce101242017-09-01 15:51:02 -0400548 canvas.clear(SK_ColorWHITE); // white is Unpremultiplied, in ARGB order
Cary Clark8032b982017-07-28 11:04:54 -0400549 SkPixmap pixmap; // provides guaranteed access to the drawn pixels
550 if (!canvas.peekPixels(&pixmap)) {
551 SkDebugf("peekPixels should never fail.\n");
552 }
Cary Clarkbc5697d2017-10-04 14:31:33 -0400553 const SkPMColor* pixels = pixmap.addr32(); // points to top-left of bitmap
Cary Clarkce101242017-09-01 15:51:02 -0400554 SkPMColor pmWhite = pixels[0]; // the Premultiplied format may vary
Cary Clark8032b982017-07-28 11:04:54 -0400555 SkPaint paint; // by default, draws black, 12 point text
556 canvas.drawString("!", 1, 10, paint); // 1 char at baseline (1, 10)
557 for (int y = 0; y < bitmap.height(); ++y) {
558 for (int x = 0; x < bitmap.width(); ++x) {
559 SkDebugf("%c", *pixels++ == pmWhite ? '-' : 'x');
560 }
561 SkDebugf("\n");
562 }
563
564 #StdOut
565 -----
566 ---x-
567 ---x-
568 ---x-
569 ---x-
570 ---x-
571 ---x-
572 -----
573 ---x-
574 ---x-
575 -----
576 #StdOut ##
577##
578
Cary Clark2ade9972017-11-02 17:49:34 -0400579#SeeAlso MakeRasterDirect SkRasterHandleAllocator::MakeCanvas SkSurface::getCanvas SkCreateColorSpaceXformCanvas
Cary Clark8032b982017-07-28 11:04:54 -0400580
581##
582
583# ------------------------------------------------------------------------------
584
585#Method virtual ~SkCanvas()
586
Cary Clarkce101242017-09-01 15:51:02 -0400587Draw saved Layers, if any.
Cary Clark8032b982017-07-28 11:04:54 -0400588Free up resources used by Canvas.
589
590#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -0400591#Description
Cary Clarkce101242017-09-01 15:51:02 -0400592Canvas Layer draws into bitmap. saveLayerAlpha sets up an additional
593drawing surface that blends with the bitmap. When Layer goes out of
594scope, Layer Destructor is called. The saved Layer is restored, drawing
Cary Clarkbad5ad72017-08-03 17:14:08 -0400595transparent letters.
596##
Cary Clarkf05bdda2017-08-24 12:59:48 -0400597void draw(SkCanvas* canvas) {
598 SkBitmap bitmap;
599 bitmap.allocPixels(SkImageInfo::MakeN32Premul(200, 200));
600 {
601 SkCanvas offscreen(bitmap);
602 SkPaint paint;
603 paint.setTextSize(100);
604 offscreen.drawString("ABC", 20, 160, paint);
605 SkRect layerBounds = SkRect::MakeXYWH(32, 32, 192, 192);
606 offscreen.saveLayerAlpha(&layerBounds, 128);
607 offscreen.clear(SK_ColorWHITE);
608 offscreen.drawString("DEF", 20, 160, paint);
609 }
610 canvas->drawBitmap(bitmap, 0, 0, nullptr);
Cary Clarkbad5ad72017-08-03 17:14:08 -0400611}
Cary Clark8032b982017-07-28 11:04:54 -0400612##
613
Cary Clarkbad5ad72017-08-03 17:14:08 -0400614#SeeAlso State_Stack
Cary Clark8032b982017-07-28 11:04:54 -0400615
616##
617
618# ------------------------------------------------------------------------------
619
620#Method SkMetaData& getMetaData()
621
Cary Clarkf05bdda2017-08-24 12:59:48 -0400622Returns storage to associate additional data with the canvas.
Cary Clark8032b982017-07-28 11:04:54 -0400623The storage is freed when Canvas is deleted.
624
Cary Clarkbad5ad72017-08-03 17:14:08 -0400625#Return storage that can be read from and written to ##
Cary Clark8032b982017-07-28 11:04:54 -0400626
627#Example
628 const char* kHelloMetaData = "HelloMetaData";
629 SkCanvas canvas;
630 SkMetaData& metaData = canvas.getMetaData();
631 SkDebugf("before: %s\n", metaData.findString(kHelloMetaData));
632 metaData.setString(kHelloMetaData, "Hello!");
633 SkDebugf("during: %s\n", metaData.findString(kHelloMetaData));
634 metaData.removeString(kHelloMetaData);
635 SkDebugf("after: %s\n", metaData.findString(kHelloMetaData));
636
637 #StdOut
638 before: (null)
639 during: Hello!
640 after: (null)
641 #StdOut ##
642##
643
Cary Clark2ade9972017-11-02 17:49:34 -0400644#SeeAlso SkMetaData
Cary Clark8032b982017-07-28 11:04:54 -0400645
646##
647
648# ------------------------------------------------------------------------------
649
650#Method SkImageInfo imageInfo() const
651
652Returns Image_Info for Canvas. If Canvas is not associated with Raster_Surface or
Cary Clarkbad5ad72017-08-03 17:14:08 -0400653GPU_Surface, returned Image_Color_Type is set to kUnknown_SkColorType.
Cary Clark8032b982017-07-28 11:04:54 -0400654
Cary Clarkbad5ad72017-08-03 17:14:08 -0400655#Return dimensions and Image_Color_Type of Canvas ##
Cary Clark8032b982017-07-28 11:04:54 -0400656
657#Example
Cary Clarkf05bdda2017-08-24 12:59:48 -0400658 SkCanvas emptyCanvas;
659 SkImageInfo canvasInfo = emptyCanvas.imageInfo();
660 SkImageInfo emptyInfo;
661 SkDebugf("emptyInfo %c= canvasInfo\n", emptyInfo == canvasInfo ? '=' : '!');
662
663 #StdOut
664 emptyInfo == canvasInfo
665 ##
Cary Clark8032b982017-07-28 11:04:54 -0400666##
667
Cary Clark2ade9972017-11-02 17:49:34 -0400668#SeeAlso SkImageInfo MakeRasterDirect makeSurface
Cary Clark8032b982017-07-28 11:04:54 -0400669
670##
671
672# ------------------------------------------------------------------------------
673
674#Method bool getProps(SkSurfaceProps* props) const
675
676If Canvas is associated with Raster_Surface or
677GPU_Surface, copies Surface_Properties and returns true. Otherwise,
678return false and leave props unchanged.
679
Cary Clarkbad5ad72017-08-03 17:14:08 -0400680#Param props storage for writable SkSurfaceProps ##
Cary Clark8032b982017-07-28 11:04:54 -0400681
Cary Clarkbad5ad72017-08-03 17:14:08 -0400682#Return true if Surface_Properties was copied ##
Cary Clark8032b982017-07-28 11:04:54 -0400683
684#ToDo This seems old style. Deprecate? ##
685
686#Example
687 SkBitmap bitmap;
688 SkCanvas canvas(bitmap, SkSurfaceProps(0, kRGB_V_SkPixelGeometry));
689 SkSurfaceProps surfaceProps(0, kUnknown_SkPixelGeometry);
690 SkDebugf("isRGB:%d\n", SkPixelGeometryIsRGB(surfaceProps.pixelGeometry()));
691 if (!canvas.getProps(&surfaceProps)) {
692 SkDebugf("getProps failed unexpectedly.\n");
693 }
694 SkDebugf("isRGB:%d\n", SkPixelGeometryIsRGB(surfaceProps.pixelGeometry()));
695
696 #StdOut
697 isRGB:0
698 isRGB:1
699 #StdOut ##
700##
701
Cary Clark2ade9972017-11-02 17:49:34 -0400702#SeeAlso SkSurfaceProps makeSurface
Cary Clark8032b982017-07-28 11:04:54 -0400703
704##
705
706# ------------------------------------------------------------------------------
707
708#Method void flush()
709
710Triggers the immediate execution of all pending draw operations.
Cary Clarkbad5ad72017-08-03 17:14:08 -0400711If Canvas is associated with GPU_Surface, resolves all pending GPU operations.
Cary Clark2ade9972017-11-02 17:49:34 -0400712If Canvas is associated with Raster_Surface, has no effect; raster draw
713operations are never deferred.
714
715#ToDo
716In an overview section on managing the GPU, include:
717- flush should never change what is drawn
718- call to kick off gpu work
719- calling too much impacts performance
720- some calls (peekPixels, prepareForExternalIO) call it internally
721- canvas call is local, GrContext::flush is global
722- diffentiate between flush, flushAndSignalSemaphores
723- normally never needs to be called
724- call it when sharing gpu resources, feeling memory pressure, swapping out app, and before
725 abandoning context
726- also call to say "I'm finished drawing here", e.g., when drawing to a GPU-backed offscreen surface
727 (created with SkSurface::MakeRenderTarget)
728
729for posterity: this doesn't show a difference: fiddle.skia.org/c/@flushfail
730##
Cary Clark8032b982017-07-28 11:04:54 -0400731
732#Example
733#Error "haven't thought of a useful example to put here"
734##
735
Cary Clark2ade9972017-11-02 17:49:34 -0400736#SeeAlso peekPixels SkSurface::flush() GrContext::flush() SkSurface::prepareForExternalIO GrContext::abandonContext()
Cary Clark8032b982017-07-28 11:04:54 -0400737
738##
739
740# ------------------------------------------------------------------------------
741
742#Method virtual SkISize getBaseLayerSize() const
743
Cary Clarkce101242017-09-01 15:51:02 -0400744Gets the size of the base or root Layer in global canvas coordinates. The
745origin of the base Layer is always (0,0). The area available for drawing may be
Cary Clark8032b982017-07-28 11:04:54 -0400746smaller (due to clipping or saveLayer).
747
Cary Clarkce101242017-09-01 15:51:02 -0400748#Return integral width and height of base Layer ##
Cary Clark8032b982017-07-28 11:04:54 -0400749
750#Example
751 SkBitmap bitmap;
752 bitmap.allocPixels(SkImageInfo::MakeN32Premul(20, 30));
753 SkCanvas canvas(bitmap, SkSurfaceProps(0, kUnknown_SkPixelGeometry));
754 canvas.clipRect(SkRect::MakeWH(10, 40));
755 SkIRect clipDeviceBounds = canvas.getDeviceClipBounds();
756 if (clipDeviceBounds.isEmpty()) {
757 SkDebugf("Empty clip bounds is unexpected!\n");
758 }
759 SkDebugf("clip=%d,%d\n", clipDeviceBounds.width(), clipDeviceBounds.height());
760 SkISize baseLayerSize = canvas.getBaseLayerSize();
761 SkDebugf("size=%d,%d\n", baseLayerSize.width(), baseLayerSize.height());
762
763 #StdOut
764 clip=10,30
765 size=20,30
766 ##
767##
768
769#ToDo is this the same as the width and height of surface? ##
770
Cary Clark2ade9972017-11-02 17:49:34 -0400771#SeeAlso getDeviceClipBounds
772
Cary Clark8032b982017-07-28 11:04:54 -0400773##
774
775# ------------------------------------------------------------------------------
776
777#Method sk_sp<SkSurface> makeSurface(const SkImageInfo& info, const SkSurfaceProps* props = nullptr)
778
779Creates Surface matching info and props, and associates it with Canvas.
Cary Clarkbad5ad72017-08-03 17:14:08 -0400780Returns nullptr if no match found.
Cary Clark8032b982017-07-28 11:04:54 -0400781
Cary Clarkbad5ad72017-08-03 17:14:08 -0400782If props is nullptr, matches Surface_Properties in Canvas. If props is nullptr and Canvas
783does not have Surface_Properties, creates Surface with default Surface_Properties.
Cary Clark8032b982017-07-28 11:04:54 -0400784
Cary Clarkbad5ad72017-08-03 17:14:08 -0400785#Param info width, height, Image_Color_Type, Image_Alpha_Type, and Color_Space ##
786#Param props Surface_Properties to match; may be nullptr to match Canvas ##
787
788#Return Surface matching info and props, or nullptr if no match is available ##
Cary Clark8032b982017-07-28 11:04:54 -0400789
790#Example
791 sk_sp<SkSurface> surface = SkSurface::MakeRasterN32Premul(5, 6);
792 SkCanvas* smallCanvas = surface->getCanvas();
793 SkImageInfo imageInfo = SkImageInfo::MakeN32Premul(3, 4);
794 sk_sp<SkSurface> compatible = smallCanvas->makeSurface(imageInfo);
795 SkDebugf("compatible %c= nullptr\n", compatible == nullptr ? '=' : '!');
796 SkDebugf("size = %d, %d\n", compatible->width(), compatible->height());
797
798 #StdOut
Cary Clarkbad5ad72017-08-03 17:14:08 -0400799 compatible != nullptr
Cary Clark8032b982017-07-28 11:04:54 -0400800 size = 3, 4
801 ##
802##
803
Cary Clark2ade9972017-11-02 17:49:34 -0400804#SeeAlso SkSurface SkSurface::makeSurface SkImageInfo SkSurfaceProps
Cary Clark8032b982017-07-28 11:04:54 -0400805
806##
807
808# ------------------------------------------------------------------------------
809
810#Method virtual GrContext* getGrContext()
811
812Returns GPU_Context of the GPU_Surface associated with Canvas.
813
Cary Clarkbad5ad72017-08-03 17:14:08 -0400814#Return GPU_Context, if available; nullptr otherwise ##
Cary Clark8032b982017-07-28 11:04:54 -0400815
816#Example
817void draw(SkCanvas* canvas) {
818 if (canvas->getGrContext()) {
819 canvas->clear(SK_ColorRED);
820 } else {
821 canvas->clear(SK_ColorBLUE);
822 }
823}
824##
825
826#ToDo fiddle should show both CPU and GPU out ##
827
Cary Clark2ade9972017-11-02 17:49:34 -0400828#SeeAlso GrContext
829
Cary Clark8032b982017-07-28 11:04:54 -0400830##
831
832# ------------------------------------------------------------------------------
833
Cary Clark73fa9722017-08-29 17:36:51 -0400834#Method void* accessTopLayerPixels(SkImageInfo* info, size_t* rowBytes, SkIPoint* origin = nullptr)
Cary Clark8032b982017-07-28 11:04:54 -0400835
836Returns the pixel base address, Image_Info, rowBytes, and origin if the pixels
Cary Clarkbad5ad72017-08-03 17:14:08 -0400837can be read directly. The returned address is only valid
Cary Clark8032b982017-07-28 11:04:54 -0400838while Canvas is in scope and unchanged. Any Canvas call or Surface call
839may invalidate the returned address and other returned values.
840
841If pixels are inaccessible, info, rowBytes, and origin are unchanged.
842
Cary Clarkbad5ad72017-08-03 17:14:08 -0400843#Param info storage for writable pixels' Image_Info; may be nullptr ##
844#Param rowBytes storage for writable pixels' row bytes; may be nullptr ##
Cary Clarkbc5697d2017-10-04 14:31:33 -0400845#Param origin storage for Canvas top Layer origin, its top-left corner;
Cary Clarkbad5ad72017-08-03 17:14:08 -0400846 may be nullptr
847##
Cary Clark8032b982017-07-28 11:04:54 -0400848
Cary Clarka523d2d2017-08-30 08:58:10 -0400849#Return address of pixels, or nullptr if inaccessible ##
Cary Clark8032b982017-07-28 11:04:54 -0400850
851#Example
852void draw(SkCanvas* canvas) {
853 if (canvas->accessTopLayerPixels(nullptr, nullptr)) {
854 canvas->clear(SK_ColorRED);
855 } else {
856 canvas->clear(SK_ColorBLUE);
857 }
858}
859##
860
861#Example
862#Description
Cary Clarkce101242017-09-01 15:51:02 -0400863Draws "ABC" on the device. Then draws "DEF" in Layer, and reads
864Layer to add a large dotted "DEF". Finally blends Layer with the
Cary Clark8032b982017-07-28 11:04:54 -0400865device.
866
Cary Clarkce101242017-09-01 15:51:02 -0400867The Layer and blended result appear on the CPU and GPU but the large dotted
Cary Clark8032b982017-07-28 11:04:54 -0400868"DEF" appear only on the CPU.
869##
870void draw(SkCanvas* canvas) {
Cary Clarkbad5ad72017-08-03 17:14:08 -0400871 SkPaint paint;
872 paint.setTextSize(100);
873 canvas->drawString("ABC", 20, 160, paint);
874 SkRect layerBounds = SkRect::MakeXYWH(32, 32, 192, 192);
875 canvas->saveLayerAlpha(&layerBounds, 128);
876 canvas->clear(SK_ColorWHITE);
877 canvas->drawString("DEF", 20, 160, paint);
878 SkImageInfo imageInfo;
879 size_t rowBytes;
880 SkIPoint origin;
881 uint32_t* access = (uint32_t*) canvas->accessTopLayerPixels(&imageInfo, &rowBytes, &origin);
882 if (access) {
883 int h = imageInfo.height();
884 int v = imageInfo.width();
885 int rowWords = rowBytes / sizeof(uint32_t);
886 for (int y = 0; y < h; ++y) {
887 int newY = (y - h / 2) * 2 + h / 2;
888 if (newY < 0 || newY >= h) {
889 continue;
890 }
891 for (int x = 0; x < v; ++x) {
892 int newX = (x - v / 2) * 2 + v / 2;
893 if (newX < 0 || newX >= v) {
894 continue;
895 }
896 if (access[y * rowWords + x] == SK_ColorBLACK) {
897 access[newY * rowWords + newX] = SK_ColorGRAY;
898 }
899 }
900 }
901
902 }
Cary Clark8032b982017-07-28 11:04:54 -0400903 canvas->restore();
904}
905##
906
907#ToDo there are no callers of this that I can find. Deprecate? ##
908#ToDo fiddle should show both CPU and GPU out ##
909
Cary Clark2ade9972017-11-02 17:49:34 -0400910#SeeAlso SkImageInfo SkPixmap
911
Cary Clark8032b982017-07-28 11:04:54 -0400912##
913
914# ------------------------------------------------------------------------------
915
916#Method SkRasterHandleAllocator::Handle accessTopRasterHandle() const
917
918Returns custom context that tracks the Matrix and Clip.
919
920Use Raster_Handle_Allocator to blend Skia drawing with custom drawing, typically performed
Cary Clarkbc5697d2017-10-04 14:31:33 -0400921by the host platform user interface. The custom context returned is generated by
Cary Clarkbad5ad72017-08-03 17:14:08 -0400922SkRasterHandleAllocator::MakeCanvas, which creates a custom canvas with raster storage for
Cary Clark8032b982017-07-28 11:04:54 -0400923the drawing destination.
924
Cary Clarkce101242017-09-01 15:51:02 -0400925#Return context of custom allocation ##
Cary Clark8032b982017-07-28 11:04:54 -0400926
927#Example
928#Description
929#ToDo ##
930##
931#Function
932 static void DeleteCallback(void*, void* context) {
933 delete (char*) context;
934 }
935
936 class CustomAllocator : public SkRasterHandleAllocator {
937 public:
938 bool allocHandle(const SkImageInfo& info, Rec* rec) override {
939 char* context = new char[4]{'s', 'k', 'i', 'a'};
940 rec->fReleaseProc = DeleteCallback;
941 rec->fReleaseCtx = context;
942 rec->fHandle = context;
943 rec->fPixels = context;
944 rec->fRowBytes = 4;
945 return true;
946 }
947
948 void updateHandle(Handle handle, const SkMatrix& ctm, const SkIRect& clip_bounds) override {
949 // apply canvas matrix and clip to custom environment
950 }
951 };
952
953##
954 void draw(SkCanvas* canvas) {
955 const SkImageInfo info = SkImageInfo::MakeN32Premul(1, 1);
956 std::unique_ptr<SkCanvas> c2 =
957 SkRasterHandleAllocator::MakeCanvas(std::unique_ptr<CustomAllocator>(
958 new CustomAllocator()), info);
959 char* context = (char*) c2->accessTopRasterHandle();
960 SkDebugf("context = %.4s\n", context);
961
962 }
963 #StdOut
964 context = skia
965 ##
966 #ToDo skstd::make_unique could not be used because def is private -- note to fix in c++14? ##
967##
968
969#SeeAlso SkRasterHandleAllocator
970
971##
972
973# ------------------------------------------------------------------------------
974
975#Method bool peekPixels(SkPixmap* pixmap)
976
977Returns true if Canvas has direct access to its pixels.
978
Cary Clarkf05bdda2017-08-24 12:59:48 -0400979Pixels are readable when Device is raster. Pixels are not readable when Canvas
Cary Clarkbad5ad72017-08-03 17:14:08 -0400980is returned from GPU_Surface, returned by SkDocument::beginPage, returned by
Cary Clarkf05bdda2017-08-24 12:59:48 -0400981SkPictureRecorder::beginRecording, or Canvas is the base of a utility class
Cary Clarkbad5ad72017-08-03 17:14:08 -0400982like SkDumpCanvas.
Cary Clark8032b982017-07-28 11:04:54 -0400983
Cary Clarkf05bdda2017-08-24 12:59:48 -0400984pixmap is valid only while Canvas is in scope and unchanged. Any
Cary Clarkbad5ad72017-08-03 17:14:08 -0400985Canvas or Surface call may invalidate the pixmap values.
Cary Clark8032b982017-07-28 11:04:54 -0400986
Cary Clarkbc5697d2017-10-04 14:31:33 -0400987#Param pixmap storage for pixel state if pixels are readable; otherwise, ignored ##
Cary Clark8032b982017-07-28 11:04:54 -0400988
Cary Clarkbad5ad72017-08-03 17:14:08 -0400989#Return true if Canvas has direct access to pixels ##
Cary Clark8032b982017-07-28 11:04:54 -0400990
991#Example
992 SkPixmap pixmap;
993 if (canvas->peekPixels(&pixmap)) {
994 SkDebugf("width=%d height=%d\n", pixmap.bounds().width(), pixmap.bounds().height());
995 }
996 #StdOut
997 width=256 height=256
998 ##
999##
1000
Cary Clark2ade9972017-11-02 17:49:34 -04001001#SeeAlso readPixels SkBitmap::peekPixels SkImage::peekPixels SkSurface::peekPixels
1002
Cary Clark8032b982017-07-28 11:04:54 -04001003##
1004
1005# ------------------------------------------------------------------------------
1006
1007#Method bool readPixels(const SkImageInfo& dstInfo, void* dstPixels, size_t dstRowBytes,
1008 int srcX, int srcY)
1009
Cary Clark154beea2017-10-26 07:58:48 -04001010Copies Rect of pixels from Canvas into dstPixels. Matrix and Clip are
Cary Clarka560c472017-11-27 10:44:06 -05001011ignored.
Cary Clark6fc50412017-09-21 12:31:06 -04001012
Cary Clarka560c472017-11-27 10:44:06 -05001013Source Rect corners are (srcX, srcY) and (imageInfo().width(), imageInfo().height()).
1014Destination Rect corners are (0, 0) and (dstInfo.width(), dstInfo.height()).
Cary Clark6fc50412017-09-21 12:31:06 -04001015Copies each readable pixel intersecting both rectangles, without scaling,
Cary Clarkf05bdda2017-08-24 12:59:48 -04001016converting to dstInfo.colorType() and dstInfo.alphaType() if required.
Cary Clark8032b982017-07-28 11:04:54 -04001017
Cary Clarkf05bdda2017-08-24 12:59:48 -04001018Pixels are readable when Device is raster, or backed by a GPU.
1019Pixels are not readable when SkCanvas is returned by SkDocument::beginPage,
1020returned by SkPictureRecorder::beginRecording, or Canvas is the base of a utility
1021class like SkDumpCanvas.
Cary Clark8032b982017-07-28 11:04:54 -04001022
Cary Clarkf05bdda2017-08-24 12:59:48 -04001023The destination pixel storage must be allocated by the caller.
Cary Clark8032b982017-07-28 11:04:54 -04001024
Cary Clarkf05bdda2017-08-24 12:59:48 -04001025Pixel values are converted only if Image_Color_Type and Image_Alpha_Type
1026do not match. Only pixels within both source and destination rectangles
Cary Clark154beea2017-10-26 07:58:48 -04001027are copied. dstPixels contents outside Rect intersection are unchanged.
Cary Clarkf05bdda2017-08-24 12:59:48 -04001028
1029Pass negative values for srcX or srcY to offset pixels across or down destination.
Cary Clark8032b982017-07-28 11:04:54 -04001030
1031Does not copy, and returns false if:
1032
1033#List
Cary Clarkf05bdda2017-08-24 12:59:48 -04001034# Source and destination rectangles do not intersect. ##
1035# Canvas pixels could not be converted to dstInfo.colorType() or dstInfo.alphaType(). ##
1036# Canvas pixels are not readable; for instance, Canvas is document-based. ##
Cary Clark8032b982017-07-28 11:04:54 -04001037# dstRowBytes is too small to contain one row of pixels. ##
1038##
1039
Cary Clarkf05bdda2017-08-24 12:59:48 -04001040#Param dstInfo width, height, Image_Color_Type, and Image_Alpha_Type of dstPixels ##
1041#Param dstPixels storage for pixels; dstInfo.height() times dstRowBytes, or larger ##
1042#Param dstRowBytes size of one destination row; dstInfo.width() times pixel size, or larger ##
1043#Param srcX offset into readable pixels in x; may be negative ##
1044#Param srcY offset into readable pixels in y; may be negative ##
Cary Clark8032b982017-07-28 11:04:54 -04001045
Cary Clarkbad5ad72017-08-03 17:14:08 -04001046#Return true if pixels were copied ##
Cary Clark8032b982017-07-28 11:04:54 -04001047
1048#Example
Cary Clarkf05bdda2017-08-24 12:59:48 -04001049#Width 64
1050#Height 64
1051#Description
1052 A black circle drawn on a blue background provides an image to copy.
1053 readPixels copies one quarter of the canvas into each of the four corners.
Cary Clarka560c472017-11-27 10:44:06 -05001054 The copied quarter circles overdraw the original circle.
Cary Clarkf05bdda2017-08-24 12:59:48 -04001055##
1056 canvas->clear(SK_ColorBLUE);
1057 SkPaint paint;
1058 canvas->drawCircle(32, 32, 28, paint);
1059 SkImageInfo info = SkImageInfo::Make(64, 64, kBGRA_8888_SkColorType, kPremul_SkAlphaType);
1060 sk_sp<SkData> data(SkData::MakeUninitialized(info.minRowBytes() * info.height()));
1061 sk_bzero(data->writable_data(), info.minRowBytes() * info.height());
1062 for (int x : { 32, -32 } ) {
1063 for (int y : { 32, -32 } ) {
1064 canvas->readPixels(info, data->writable_data(), info.minRowBytes(), x, y);
1065 }
1066 }
1067 sk_sp<SkImage> image = SkImage::MakeRasterData(info, data, info.minRowBytes());
1068 canvas->drawImage(image, 0, 0);
1069##
1070
1071#Example
Cary Clark8032b982017-07-28 11:04:54 -04001072#Description
Cary Clarkce101242017-09-01 15:51:02 -04001073 Canvas returned by Raster_Surface has Premultiplied pixel values.
1074 clear() takes Unpremultiplied input with Color_Alpha equal 0x80
1075 and Color_RGB equal 0x55, 0xAA, 0xFF. Color_RGB is multiplied by Color_Alpha
1076 to generate Premultiplied value 0x802B5580. readPixels converts pixel back
1077 to Unpremultiplied value 0x8056A9FF, introducing error.
Cary Clark8032b982017-07-28 11:04:54 -04001078##
1079 canvas->clear(0x8055aaff);
1080 for (SkAlphaType alphaType : { kPremul_SkAlphaType, kUnpremul_SkAlphaType } ) {
1081 uint32_t pixel = 0;
1082 SkImageInfo info = SkImageInfo::Make(1, 1, kBGRA_8888_SkColorType, alphaType);
1083 if (canvas->readPixels(info, &pixel, 4, 0, 0)) {
1084 SkDebugf("pixel = %08x\n", pixel);
1085 }
1086 }
1087
1088 #StdOut
1089 pixel = 802b5580
1090 pixel = 8056a9ff
1091 ##
1092##
1093
Cary Clark2ade9972017-11-02 17:49:34 -04001094#SeeAlso peekPixels writePixels drawBitmap drawImage SkBitmap::readPixels SkPixmap::readPixels SkImage::readPixels SkSurface::readPixels
Cary Clark8032b982017-07-28 11:04:54 -04001095
1096##
1097
1098# ------------------------------------------------------------------------------
1099
1100#Method bool readPixels(const SkPixmap& pixmap, int srcX, int srcY)
1101
Cary Clark154beea2017-10-26 07:58:48 -04001102Copies Rect of pixels from Canvas into pixmap. Matrix and Clip are
Cary Clarka560c472017-11-27 10:44:06 -05001103ignored.
Cary Clark6fc50412017-09-21 12:31:06 -04001104
Cary Clarka560c472017-11-27 10:44:06 -05001105Source Rect corners are (srcX, srcY) and (imageInfo().width(), imageInfo().height()).
1106Destination Rect corners are (0, 0) and (pixmap.width(), pixmap.height()).
Cary Clark6fc50412017-09-21 12:31:06 -04001107Copies each readable pixel intersecting both rectangles, without scaling,
Cary Clarkf05bdda2017-08-24 12:59:48 -04001108converting to pixmap.colorType() and pixmap.alphaType() if required.
Cary Clark8032b982017-07-28 11:04:54 -04001109
Cary Clarkf05bdda2017-08-24 12:59:48 -04001110Pixels are readable when Device is raster, or backed by a GPU.
1111Pixels are not readable when SkCanvas is returned by SkDocument::beginPage,
1112returned by SkPictureRecorder::beginRecording, or Canvas is the base of a utility
1113class like SkDumpCanvas.
Cary Clark8032b982017-07-28 11:04:54 -04001114
Cary Clark6fc50412017-09-21 12:31:06 -04001115Caller must allocate pixel storage in pixmap if needed.
Cary Clark8032b982017-07-28 11:04:54 -04001116
Cary Clarkf05bdda2017-08-24 12:59:48 -04001117Pixel values are converted only if Image_Color_Type and Image_Alpha_Type
Cary Clark154beea2017-10-26 07:58:48 -04001118do not match. Only pixels within both source and destination Rects
1119are copied. pixmap pixels contents outside Rect intersection are unchanged.
Cary Clarkf05bdda2017-08-24 12:59:48 -04001120
1121Pass negative values for srcX or srcY to offset pixels across or down pixmap.
Cary Clark8032b982017-07-28 11:04:54 -04001122
1123Does not copy, and returns false if:
1124
1125#List
Cary Clarkf05bdda2017-08-24 12:59:48 -04001126# Source and destination rectangles do not intersect. ##
1127# Canvas pixels could not be converted to pixmap.colorType() or pixmap.alphaType(). ##
1128# Canvas pixels are not readable; for instance, Canvas is document-based. ##
1129# Pixmap pixels could not be allocated. ##
1130# pixmap.rowBytes() is too small to contain one row of pixels. ##
Cary Clark8032b982017-07-28 11:04:54 -04001131##
1132
Cary Clarkbad5ad72017-08-03 17:14:08 -04001133#Param pixmap storage for pixels copied from Canvas ##
Cary Clarkf05bdda2017-08-24 12:59:48 -04001134#Param srcX offset into readable pixels in x; may be negative ##
1135#Param srcY offset into readable pixels in y; may be negative ##
Cary Clark8032b982017-07-28 11:04:54 -04001136
Cary Clarkbad5ad72017-08-03 17:14:08 -04001137#Return true if pixels were copied ##
Cary Clark8032b982017-07-28 11:04:54 -04001138
1139#Example
Cary Clarkf05bdda2017-08-24 12:59:48 -04001140 #Description
Cary Clarkce101242017-09-01 15:51:02 -04001141 clear() takes Unpremultiplied input with Color_Alpha equal 0x80
1142 and Color_RGB equal 0x55, 0xAA, 0xFF. Color_RGB is multiplied by Color_Alpha
1143 to generate Premultiplied value 0x802B5580.
Cary Clarkf05bdda2017-08-24 12:59:48 -04001144 ##
1145 void draw(SkCanvas* canvas) {
1146 canvas->clear(0x8055aaff);
1147 uint32_t pixels[1] = { 0 };
1148 SkPixmap pixmap(SkImageInfo::MakeN32Premul(1, 1), pixels, 4);
1149 canvas->readPixels(pixmap, 0, 0);
1150 SkDebugf("pixel = %08x\n", pixels[0]);
1151 }
Cary Clark8032b982017-07-28 11:04:54 -04001152 #StdOut
1153 pixel = 802b5580
1154 ##
1155##
1156
Cary Clark2ade9972017-11-02 17:49:34 -04001157#SeeAlso peekPixels writePixels drawBitmap drawImage SkBitmap::readPixels SkPixmap::readPixels SkImage::readPixels SkSurface::readPixels
Cary Clark8032b982017-07-28 11:04:54 -04001158
1159##
1160
1161# ------------------------------------------------------------------------------
1162
1163#Method bool readPixels(const SkBitmap& bitmap, int srcX, int srcY)
1164
Cary Clark154beea2017-10-26 07:58:48 -04001165Copies Rect of pixels from Canvas into bitmap. Matrix and Clip are
Cary Clarka560c472017-11-27 10:44:06 -05001166ignored.
Cary Clark6fc50412017-09-21 12:31:06 -04001167
Cary Clarka560c472017-11-27 10:44:06 -05001168Source Rect corners are (srcX, srcY) and (imageInfo().width(), imageInfo().height()).
Cary Clark154beea2017-10-26 07:58:48 -04001169Destination Rect corners are (0, 0) and (bitmap.width(), bitmap.height()).
Cary Clarkf05bdda2017-08-24 12:59:48 -04001170Copies each readable pixel intersecting both rectangles, without scaling,
1171converting to bitmap.colorType() and bitmap.alphaType() if required.
Cary Clark8032b982017-07-28 11:04:54 -04001172
Cary Clarkf05bdda2017-08-24 12:59:48 -04001173Pixels are readable when Device is raster, or backed by a GPU.
1174Pixels are not readable when SkCanvas is returned by SkDocument::beginPage,
1175returned by SkPictureRecorder::beginRecording, or Canvas is the base of a utility
1176class like SkDumpCanvas.
Cary Clark8032b982017-07-28 11:04:54 -04001177
Cary Clark6fc50412017-09-21 12:31:06 -04001178Caller must allocate pixel storage in bitmap if needed.
Cary Clarkf05bdda2017-08-24 12:59:48 -04001179
1180Bitmap values are converted only if Image_Color_Type and Image_Alpha_Type
1181do not match. Only pixels within both source and destination rectangles
Cary Clark154beea2017-10-26 07:58:48 -04001182are copied. Bitmap pixels outside Rect intersection are unchanged.
Cary Clarkf05bdda2017-08-24 12:59:48 -04001183
1184Pass negative values for srcX or srcY to offset pixels across or down bitmap.
Cary Clark8032b982017-07-28 11:04:54 -04001185
1186Does not copy, and returns false if:
1187
1188#List
Cary Clarkf05bdda2017-08-24 12:59:48 -04001189# Source and destination rectangles do not intersect. ##
1190# Canvas pixels could not be converted to bitmap.colorType() or bitmap.alphaType(). ##
1191# Canvas pixels are not readable; for instance, Canvas is document-based. ##
Cary Clark8032b982017-07-28 11:04:54 -04001192# bitmap pixels could not be allocated. ##
Cary Clarkf05bdda2017-08-24 12:59:48 -04001193# bitmap.rowBytes() is too small to contain one row of pixels. ##
Cary Clark8032b982017-07-28 11:04:54 -04001194##
1195
Cary Clarkbad5ad72017-08-03 17:14:08 -04001196#Param bitmap storage for pixels copied from Canvas ##
Cary Clarkf05bdda2017-08-24 12:59:48 -04001197#Param srcX offset into readable pixels in x; may be negative ##
1198#Param srcY offset into readable pixels in y; may be negative ##
Cary Clark8032b982017-07-28 11:04:54 -04001199
Cary Clarkbad5ad72017-08-03 17:14:08 -04001200#Return true if pixels were copied ##
Cary Clark8032b982017-07-28 11:04:54 -04001201
1202#Example
Cary Clarkf05bdda2017-08-24 12:59:48 -04001203 #Description
Cary Clarkce101242017-09-01 15:51:02 -04001204 clear() takes Unpremultiplied input with Color_Alpha equal 0x80
1205 and Color_RGB equal 0x55, 0xAA, 0xFF. Color_RGB is multiplied by Color_Alpha
1206 to generate Premultiplied value 0x802B5580.
Cary Clarkf05bdda2017-08-24 12:59:48 -04001207 ##
Cary Clark8032b982017-07-28 11:04:54 -04001208void draw(SkCanvas* canvas) {
1209 canvas->clear(0x8055aaff);
1210 SkBitmap bitmap;
1211 bitmap.allocPixels(SkImageInfo::MakeN32Premul(1, 1));
1212 canvas->readPixels(bitmap, 0, 0);
1213 SkDebugf("pixel = %08x\n", bitmap.getAddr32(0, 0)[0]);
1214}
1215 #StdOut
1216 pixel = 802b5580
1217 ##
1218##
1219
Cary Clark2ade9972017-11-02 17:49:34 -04001220#SeeAlso peekPixels writePixels drawBitmap drawImage SkBitmap::readPixels SkPixmap::readPixels SkImage::readPixels SkSurface::readPixels
Cary Clark8032b982017-07-28 11:04:54 -04001221
1222##
1223
1224# ------------------------------------------------------------------------------
1225
1226#Method bool writePixels(const SkImageInfo& info, const void* pixels, size_t rowBytes, int x, int y)
1227
Cary Clark154beea2017-10-26 07:58:48 -04001228Copies Rect from pixels to Canvas. Matrix and Clip are ignored.
1229Source Rect corners are (0, 0) and (info.width(), info.height()).
1230Destination Rect corners are (x, y) and
1231(imageInfo().width(), imageInfo().height()).
Cary Clark6fc50412017-09-21 12:31:06 -04001232
1233Copies each readable pixel intersecting both rectangles, without scaling,
Cary Clark154beea2017-10-26 07:58:48 -04001234converting to imageInfo().colorType() and imageInfo().alphaType() if required.
Cary Clark8032b982017-07-28 11:04:54 -04001235
Cary Clarkf05bdda2017-08-24 12:59:48 -04001236Pixels are writable when Device is raster, or backed by a GPU.
1237Pixels are not writable when SkCanvas is returned by SkDocument::beginPage,
1238returned by SkPictureRecorder::beginRecording, or Canvas is the base of a utility
1239class like SkDumpCanvas.
Cary Clark8032b982017-07-28 11:04:54 -04001240
Cary Clarkf05bdda2017-08-24 12:59:48 -04001241Pixel values are converted only if Image_Color_Type and Image_Alpha_Type
1242do not match. Only pixels within both source and destination rectangles
Cary Clark154beea2017-10-26 07:58:48 -04001243are copied. Canvas pixels outside Rect intersection are unchanged.
Cary Clark8032b982017-07-28 11:04:54 -04001244
Cary Clarkf05bdda2017-08-24 12:59:48 -04001245Pass negative values for x or y to offset pixels to the left or
1246above Canvas pixels.
Cary Clark8032b982017-07-28 11:04:54 -04001247
1248Does not copy, and returns false if:
1249
1250#List
Cary Clarkf05bdda2017-08-24 12:59:48 -04001251# Source and destination rectangles do not intersect. ##
Cary Clark154beea2017-10-26 07:58:48 -04001252# pixels could not be converted to this->imageInfo().colorType() or
1253this->imageInfo().alphaType(). ##
Cary Clark8032b982017-07-28 11:04:54 -04001254# Canvas pixels are not writable; for instance, Canvas is document-based. ##
1255# rowBytes is too small to contain one row of pixels. ##
1256##
1257
Cary Clarkf05bdda2017-08-24 12:59:48 -04001258#Param info width, height, Image_Color_Type, and Image_Alpha_Type of pixels ##
1259#Param pixels pixels to copy, of size info.height() times rowBytes, or larger ##
Cary Clarkd0530ba2017-09-14 11:25:39 -04001260#Param rowBytes size of one row of pixels; info.width() times pixel size, or larger ##
Cary Clarkf05bdda2017-08-24 12:59:48 -04001261#Param x offset into Canvas writable pixels in x; may be negative ##
1262#Param y offset into Canvas writable pixels in y; may be negative ##
Cary Clark8032b982017-07-28 11:04:54 -04001263
Cary Clarkbad5ad72017-08-03 17:14:08 -04001264#Return true if pixels were written to Canvas ##
Cary Clark8032b982017-07-28 11:04:54 -04001265
1266#Example
1267 SkImageInfo imageInfo = SkImageInfo::MakeN32(256, 1, kPremul_SkAlphaType);
1268 for (int y = 0; y < 256; ++y) {
1269 uint32_t pixels[256];
1270 for (int x = 0; x < 256; ++x) {
1271 pixels[x] = SkColorSetARGB(x, x + y, x, x - y);
1272 }
1273 canvas->writePixels(imageInfo, &pixels, sizeof(pixels), 0, y);
1274 }
1275##
1276
Cary Clark2ade9972017-11-02 17:49:34 -04001277#SeeAlso readPixels drawBitmap drawImage SkBitmap::writePixels
Cary Clark8032b982017-07-28 11:04:54 -04001278
1279##
1280
1281# ------------------------------------------------------------------------------
1282
1283#Method bool writePixels(const SkBitmap& bitmap, int x, int y)
1284
Cary Clark154beea2017-10-26 07:58:48 -04001285Copies Rect from pixels to Canvas. Matrix and Clip are ignored.
1286Source Rect corners are (0, 0) and (bitmap.width(), bitmap.height()).
Cary Clark6fc50412017-09-21 12:31:06 -04001287
Cary Clark154beea2017-10-26 07:58:48 -04001288Destination Rect corners are (x, y) and
1289(imageInfo().width(), imageInfo().height()).
Cary Clark6fc50412017-09-21 12:31:06 -04001290
1291Copies each readable pixel intersecting both rectangles, without scaling,
Cary Clark154beea2017-10-26 07:58:48 -04001292converting to imageInfo().colorType() and imageInfo().alphaType() if required.
Cary Clark8032b982017-07-28 11:04:54 -04001293
Cary Clarkf05bdda2017-08-24 12:59:48 -04001294Pixels are writable when Device is raster, or backed by a GPU.
1295Pixels are not writable when SkCanvas is returned by SkDocument::beginPage,
1296returned by SkPictureRecorder::beginRecording, or Canvas is the base of a utility
1297class like SkDumpCanvas.
Cary Clark8032b982017-07-28 11:04:54 -04001298
Cary Clarkf05bdda2017-08-24 12:59:48 -04001299Pixel values are converted only if Image_Color_Type and Image_Alpha_Type
1300do not match. Only pixels within both source and destination rectangles
Cary Clark154beea2017-10-26 07:58:48 -04001301are copied. Canvas pixels outside Rect intersection are unchanged.
Cary Clark8032b982017-07-28 11:04:54 -04001302
Cary Clarkf05bdda2017-08-24 12:59:48 -04001303Pass negative values for x or y to offset pixels to the left or
1304above Canvas pixels.
Cary Clark8032b982017-07-28 11:04:54 -04001305
1306Does not copy, and returns false if:
1307
1308#List
Cary Clarkf05bdda2017-08-24 12:59:48 -04001309# Source and destination rectangles do not intersect. ##
Cary Clark8032b982017-07-28 11:04:54 -04001310# bitmap does not have allocated pixels. ##
Cary Clark154beea2017-10-26 07:58:48 -04001311# bitmap pixels could not be converted to this->imageInfo().colorType() or
1312this->imageInfo().alphaType(). ##
Cary Clarkce101242017-09-01 15:51:02 -04001313# Canvas pixels are not writable; for instance, Canvas is document based. ##
Cary Clark8032b982017-07-28 11:04:54 -04001314# bitmap pixels are inaccessible; for instance, bitmap wraps a texture. ##
1315##
1316
Cary Clarkbad5ad72017-08-03 17:14:08 -04001317#Param bitmap contains pixels copied to Canvas ##
Cary Clarkf05bdda2017-08-24 12:59:48 -04001318#Param x offset into Canvas writable pixels in x; may be negative ##
1319#Param y offset into Canvas writable pixels in y; may be negative ##
Cary Clark8032b982017-07-28 11:04:54 -04001320
Cary Clarkbad5ad72017-08-03 17:14:08 -04001321#Return true if pixels were written to Canvas ##
Cary Clark8032b982017-07-28 11:04:54 -04001322
1323#Example
1324void draw(SkCanvas* canvas) {
1325 SkImageInfo imageInfo = SkImageInfo::MakeN32Premul(2, 2);
1326 SkBitmap bitmap;
1327 bitmap.setInfo(imageInfo);
1328 uint32_t pixels[4];
1329 bitmap.setPixels(pixels);
1330 for (int y = 0; y < 256; y += 2) {
1331 for (int x = 0; x < 256; x += 2) {
1332 pixels[0] = SkColorSetRGB(x, y, x | y);
1333 pixels[1] = SkColorSetRGB(x ^ y, y, x);
1334 pixels[2] = SkColorSetRGB(x, x & y, y);
1335 pixels[3] = SkColorSetRGB(~x, ~y, x);
1336 canvas->writePixels(bitmap, x, y);
1337 }
1338 }
1339}
1340##
1341
Cary Clark2ade9972017-11-02 17:49:34 -04001342#SeeAlso readPixels drawBitmap drawImage SkBitmap::writePixels
Cary Clark8032b982017-07-28 11:04:54 -04001343
1344##
1345
1346# ------------------------------------------------------------------------------
1347#Topic State_Stack
1348
1349Canvas maintains a stack of state that allows hierarchical drawing, commonly used
Cary Clarkbad5ad72017-08-03 17:14:08 -04001350to implement windows and views. The initial state has an identity matrix and and
1351an infinite clip. Even with a wide-open clip, drawing is constrained by the
1352bounds of the Canvas Surface or Device.
Cary Clark8032b982017-07-28 11:04:54 -04001353
1354Canvas savable state consists of Clip, Matrix, and Draw_Filter.
1355Clip describes the area that may be drawn to.
1356Matrix transforms the geometry.
1357Draw_Filter (deprecated on most platforms) modifies the paint before drawing.
1358
1359save(), saveLayer, saveLayerPreserveLCDTextRequests, and saveLayerAlpha
1360save state and return the depth of the stack.
1361
Cary Clarkbad5ad72017-08-03 17:14:08 -04001362restore(), restoreToCount, and ~SkCanvas() revert state to its value when saved.
Cary Clark8032b982017-07-28 11:04:54 -04001363
1364Each state on the stack intersects Clip with the previous Clip,
1365and concatenates Matrix with the previous Matrix.
1366The intersected Clip makes the drawing area the same or smaller;
1367the concatenated Matrix may move the origin and potentially scale or rotate
1368the coordinate space.
1369
1370Canvas does not require balancing the state stack but it is a good idea
1371to do so. Calling save() without restore() will eventually cause Skia to fail;
1372mismatched save() and restore() create hard to find bugs.
1373
1374It is not possible to use state to draw outside of the clip defined by the
1375previous state.
1376
1377#Example
1378#Description
1379Draw to ever smaller clips; then restore drawing to full canvas.
1380Note that the second clipRect is not permitted to enlarge Clip.
1381##
1382#Height 160
Cary Clarkbad5ad72017-08-03 17:14:08 -04001383void draw(SkCanvas* canvas) {
1384 SkPaint paint;
1385 canvas->save(); // records stack depth to restore
1386 canvas->clipRect(SkRect::MakeWH(100, 100)); // constrains drawing to clip
1387 canvas->clear(SK_ColorRED); // draws to limit of clip
1388 canvas->save(); // records stack depth to restore
1389 canvas->clipRect(SkRect::MakeWH(50, 150)); // Rect below 100 is ignored
1390 canvas->clear(SK_ColorBLUE); // draws to smaller clip
1391 canvas->restore(); // enlarges clip
1392 canvas->drawLine(20, 20, 150, 150, paint); // line below 100 is not drawn
1393 canvas->restore(); // enlarges clip
1394 canvas->drawLine(150, 20, 50, 120, paint); // line below 100 is drawn
Cary Clark8032b982017-07-28 11:04:54 -04001395}
1396##
1397
1398Each Clip uses the current Matrix for its coordinates.
1399
1400#Example
1401#Description
1402While clipRect is given the same rectangle twice, Matrix makes the second
1403clipRect draw at half the size of the first.
1404##
1405#Height 128
Cary Clarkbad5ad72017-08-03 17:14:08 -04001406void draw(SkCanvas* canvas) {
1407 canvas->clipRect(SkRect::MakeWH(100, 100));
1408 canvas->clear(SK_ColorRED);
1409 canvas->scale(.5, .5);
1410 canvas->clipRect(SkRect::MakeWH(100, 100));
1411 canvas->clear(SK_ColorBLUE);
Cary Clark8032b982017-07-28 11:04:54 -04001412}
1413##
1414
1415#SeeAlso save() saveLayer saveLayerPreserveLCDTextRequests saveLayerAlpha restore() restoreToCount
1416
1417#Method int save()
1418
1419Saves Matrix, Clip, and Draw_Filter (Draw_Filter deprecated on most platforms).
1420Calling restore() discards changes to Matrix, Clip, and Draw_Filter,
1421restoring the Matrix, Clip, and Draw_Filter to their state when save() was called.
1422
Cary Clarkbad5ad72017-08-03 17:14:08 -04001423Matrix may be changed by translate(), scale(), rotate(), skew(), concat(), setMatrix,
1424and resetMatrix. Clip may be changed by clipRect, clipRRect, clipPath, clipRegion.
Cary Clark8032b982017-07-28 11:04:54 -04001425
Cary Clarkbad5ad72017-08-03 17:14:08 -04001426Saved Canvas state is put on a stack; multiple calls to save() should be balance
1427by an equal number of calls to restore().
Cary Clark8032b982017-07-28 11:04:54 -04001428
1429Call restoreToCount with result to restore this and subsequent saves.
1430
Cary Clarkbad5ad72017-08-03 17:14:08 -04001431#Return depth of saved stack ##
Cary Clark8032b982017-07-28 11:04:54 -04001432
1433#Example
1434#Description
1435The black square is translated 50 pixels down and to the right.
1436Restoring Canvas state removes translate() from Canvas stack;
1437the red square is not translated, and is drawn at the origin.
1438##
1439#Height 100
1440void draw(SkCanvas* canvas) {
1441 SkPaint paint;
1442 SkRect rect = { 0, 0, 25, 25 };
1443 canvas->drawRect(rect, paint);
1444 canvas->save();
1445 canvas->translate(50, 50);
1446 canvas->drawRect(rect, paint);
1447 canvas->restore();
1448 paint.setColor(SK_ColorRED);
1449 canvas->drawRect(rect, paint);
1450}
1451##
1452
Cary Clark2ade9972017-11-02 17:49:34 -04001453#SeeAlso saveLayer saveLayerPreserveLCDTextRequests saveLayerAlpha restore() restoreToCount
Cary Clark8032b982017-07-28 11:04:54 -04001454
1455##
1456
1457# ------------------------------------------------------------------------------
Cary Clark8032b982017-07-28 11:04:54 -04001458
1459#Method void restore()
1460
1461Removes changes to Matrix, Clip, and Draw_Filter since Canvas state was
1462last saved. The state is removed from the stack.
1463
1464Does nothing if the stack is empty.
1465
1466#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04001467void draw(SkCanvas* canvas) {
1468 SkCanvas simple;
1469 SkDebugf("depth = %d\n", simple.getSaveCount());
1470 simple.restore();
1471 SkDebugf("depth = %d\n", simple.getSaveCount());
Cary Clark8032b982017-07-28 11:04:54 -04001472}
1473##
1474
Cary Clark2ade9972017-11-02 17:49:34 -04001475#SeeAlso save() saveLayer saveLayerPreserveLCDTextRequests saveLayerAlpha restoreToCount
1476
Cary Clark8032b982017-07-28 11:04:54 -04001477##
1478
1479# ------------------------------------------------------------------------------
1480
1481#Method int getSaveCount() const
1482
1483Returns the number of saved states, each containing: Matrix, Clip, and Draw_Filter.
1484Equals the number of save() calls less the number of restore() calls plus one.
1485The save count of a new canvas is one.
1486
Cary Clarkbad5ad72017-08-03 17:14:08 -04001487#Return depth of save state stack ##
Cary Clark8032b982017-07-28 11:04:54 -04001488
1489#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04001490void draw(SkCanvas* canvas) {
1491 SkCanvas simple;
1492 SkDebugf("depth = %d\n", simple.getSaveCount());
1493 simple.save();
1494 SkDebugf("depth = %d\n", simple.getSaveCount());
1495 simple.restore();
1496 SkDebugf("depth = %d\n", simple.getSaveCount());
Cary Clark8032b982017-07-28 11:04:54 -04001497}
1498#StdOut
Cary Clarkbad5ad72017-08-03 17:14:08 -04001499depth = 1
1500depth = 2
Cary Clark8032b982017-07-28 11:04:54 -04001501depth = 1
1502##
1503##
1504
Cary Clark2ade9972017-11-02 17:49:34 -04001505#SeeAlso save() restore() restoreToCount
1506
Cary Clark8032b982017-07-28 11:04:54 -04001507##
1508
1509# ------------------------------------------------------------------------------
1510
1511#Method void restoreToCount(int saveCount)
1512
Cary Clarkbad5ad72017-08-03 17:14:08 -04001513Restores state to Matrix, Clip, and Draw_Filter values when save(), saveLayer,
1514saveLayerPreserveLCDTextRequests, or saveLayerAlpha returned saveCount.
Cary Clark8032b982017-07-28 11:04:54 -04001515
1516Does nothing if saveCount is greater than state stack count.
1517Restores state to initial values if saveCount is less than or equal to one.
1518
Cary Clarkbad5ad72017-08-03 17:14:08 -04001519#Param saveCount depth of state stack to restore ##
Cary Clark8032b982017-07-28 11:04:54 -04001520
1521#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04001522void draw(SkCanvas* canvas) {
1523 SkDebugf("depth = %d\n", canvas->getSaveCount());
1524 canvas->save();
1525 canvas->save();
1526 SkDebugf("depth = %d\n", canvas->getSaveCount());
1527 canvas->restoreToCount(0);
1528 SkDebugf("depth = %d\n", canvas->getSaveCount());
Cary Clark8032b982017-07-28 11:04:54 -04001529}
1530#StdOut
Cary Clarkbad5ad72017-08-03 17:14:08 -04001531depth = 1
1532depth = 3
Cary Clark8032b982017-07-28 11:04:54 -04001533depth = 1
1534##
1535##
1536
Cary Clark2ade9972017-11-02 17:49:34 -04001537#SeeAlso restore() getSaveCount save()
1538
Cary Clark8032b982017-07-28 11:04:54 -04001539##
1540
1541#Topic State_Stack ##
1542
1543# ------------------------------------------------------------------------------
Cary Clarkce101242017-09-01 15:51:02 -04001544
1545#Topic Layer
Cary Clarkd0530ba2017-09-14 11:25:39 -04001546#Substitute layer
Cary Clarkce101242017-09-01 15:51:02 -04001547#Alias Layers
1548
1549Layer allocates a temporary Bitmap to draw into. When the drawing is
1550complete, the Bitmap is drawn into the Canvas.
1551
1552Layer is saved in a stack along with other saved state. When state with a Layer
1553is restored, the Bitmap is drawn into the previous Layer.
1554
1555Layer may be initialized with the contents of the previous Layer. When Layer is
1556restored, its Bitmap can be modified by Paint passed to Layer to apply
1557Color_Alpha, Color_Filter, Image_Filter, and Blend_Mode.
1558
1559#Method int saveLayer(const SkRect* bounds, const SkPaint* paint)
1560
1561Saves Matrix, Clip, and Draw_Filter (Draw_Filter deprecated on most platforms),
1562and allocates a Bitmap for subsequent drawing.
1563Calling restore() discards changes to Matrix, Clip, and Draw_Filter,
1564and draws the Bitmap.
1565
1566Matrix may be changed by translate(), scale(), rotate(), skew(), concat(),
1567setMatrix, and resetMatrix. Clip may be changed by clipRect, clipRRect,
1568clipPath, clipRegion.
1569
1570Rect bounds suggests but does not define the Bitmap size. To clip drawing to
1571a specific rectangle, use clipRect.
1572
1573Optional Paint paint applies Color_Alpha, Color_Filter, Image_Filter, and
1574Blend_Mode when restore() is called.
1575
1576Call restoreToCount with returned value to restore this and subsequent saves.
1577
1578#Param bounds hint to limit the size of the Layer; may be nullptr ##
1579#Param paint graphics state for Layer; may be nullptr ##
1580
1581#Return depth of saved stack ##
1582
1583#Example
1584#Description
1585Rectangles are blurred by Image_Filter when restore() draws Layer to main
1586Canvas.
1587##
1588#Height 128
1589void draw(SkCanvas* canvas) {
1590 SkPaint paint, blur;
Cary Clarka560c472017-11-27 10:44:06 -05001591 blur.setImageFilter(SkBlurImageFilter::Make(3, 3, nullptr));
Cary Clarkce101242017-09-01 15:51:02 -04001592 canvas->saveLayer(nullptr, &blur);
1593 SkRect rect = { 25, 25, 50, 50};
1594 canvas->drawRect(rect, paint);
1595 canvas->translate(50, 50);
1596 paint.setColor(SK_ColorRED);
1597 canvas->drawRect(rect, paint);
1598 canvas->restore();
1599}
1600##
1601
Cary Clark2ade9972017-11-02 17:49:34 -04001602#SeeAlso save() restore() saveLayer saveLayerPreserveLCDTextRequests saveLayerAlpha SaveLayerRec
Cary Clarkce101242017-09-01 15:51:02 -04001603
1604##
1605
1606#Method int saveLayer(const SkRect& bounds, const SkPaint* paint)
1607
1608Saves Matrix, Clip, and Draw_Filter (Draw_Filter deprecated on most platforms),
1609and allocates a Bitmap for subsequent drawing.
1610Calling restore() discards changes to Matrix, Clip, and Draw_Filter,
1611and draws the Bitmap.
1612
1613Matrix may be changed by translate(), scale(), rotate(), skew(), concat(),
1614setMatrix, and resetMatrix. Clip may be changed by clipRect, clipRRect,
1615clipPath, clipRegion.
1616
1617Rect bounds suggests but does not define the Layer size. To clip drawing to
1618a specific rectangle, use clipRect.
1619
1620Optional Paint paint applies Color_Alpha, Color_Filter, Image_Filter, and
1621Blend_Mode when restore() is called.
1622
1623Call restoreToCount with returned value to restore this and subsequent saves.
1624
1625#Param bounds hint to limit the size of Layer; may be nullptr ##
1626#Param paint graphics state for Layer; may be nullptr ##
1627
1628#Return depth of saved stack ##
1629
1630#Example
1631#Description
1632Rectangles are blurred by Image_Filter when restore() draws Layer to main Canvas.
1633The red rectangle is clipped; it does not fully fit on Layer.
1634Image_Filter blurs past edge of Layer so red rectangle is blurred on all sides.
1635##
1636#Height 128
1637void draw(SkCanvas* canvas) {
1638 SkPaint paint, blur;
Cary Clarka560c472017-11-27 10:44:06 -05001639 blur.setImageFilter(SkBlurImageFilter::Make(3, 3, nullptr));
Cary Clarkce101242017-09-01 15:51:02 -04001640 canvas->saveLayer(SkRect::MakeWH(90, 90), &blur);
1641 SkRect rect = { 25, 25, 50, 50};
1642 canvas->drawRect(rect, paint);
1643 canvas->translate(50, 50);
1644 paint.setColor(SK_ColorRED);
1645 canvas->drawRect(rect, paint);
1646 canvas->restore();
1647}
1648##
1649
Cary Clark2ade9972017-11-02 17:49:34 -04001650#SeeAlso save() restore() saveLayerPreserveLCDTextRequests saveLayerAlpha SaveLayerRec
Cary Clarkce101242017-09-01 15:51:02 -04001651
1652##
1653
1654#Method int saveLayerPreserveLCDTextRequests(const SkRect* bounds, const SkPaint* paint)
1655
1656Saves Matrix, Clip, and Draw_Filter (Draw_Filter deprecated on most platforms),
1657and allocates a Bitmap for subsequent drawing.
1658LCD_Text is preserved when the Layer is drawn to the prior Layer.
1659
1660Calling restore() discards changes to Matrix, Clip, and Draw_Filter,
1661and draws Layer.
1662
1663Matrix may be changed by translate(), scale(), rotate(), skew(), concat(),
1664setMatrix, and resetMatrix. Clip may be changed by clipRect, clipRRect,
1665clipPath, clipRegion.
1666
1667Rect bounds suggests but does not define the Layer size. To clip drawing to
1668a specific rectangle, use clipRect.
1669
1670Optional Paint paint applies Color_Alpha, Color_Filter, Image_Filter, and
1671Blend_Mode when restore() is called.
1672
1673Call restoreToCount with returned value to restore this and subsequent saves.
1674
1675Draw text on an opaque background so that LCD_Text blends correctly with the
1676prior Layer. LCD_Text drawn on a background with transparency may result in
Cary Clark6fc50412017-09-21 12:31:06 -04001677incorrect blending.
Cary Clarkce101242017-09-01 15:51:02 -04001678
1679#Param bounds hint to limit the size of Layer; may be nullptr ##
1680#Param paint graphics state for Layer; may be nullptr ##
1681
1682#Return depth of saved stack ##
1683
1684#Example
1685 SkPaint paint;
1686 paint.setAntiAlias(true);
1687 paint.setLCDRenderText(true);
1688 paint.setTextSize(20);
1689 for (auto preserve : { false, true } ) {
1690 preserve ? canvas->saveLayerPreserveLCDTextRequests(nullptr, nullptr)
1691 : canvas->saveLayer(nullptr, nullptr);
1692 SkPaint p;
1693 p.setColor(SK_ColorWHITE);
1694 // Comment out the next line to draw on a non-opaque background.
1695 canvas->drawRect(SkRect::MakeLTRB(25, 40, 200, 70), p);
1696 canvas->drawString("Hamburgefons", 30, 60, paint);
1697
1698 p.setColor(0xFFCCCCCC);
1699 canvas->drawRect(SkRect::MakeLTRB(25, 70, 200, 100), p);
1700 canvas->drawString("Hamburgefons", 30, 90, paint);
1701
1702 canvas->restore();
1703 canvas->translate(0, 80);
1704 }
1705 ##
1706
Cary Clark2ade9972017-11-02 17:49:34 -04001707#SeeAlso save() restore() saveLayer saveLayerAlpha SaveLayerRec
Cary Clarkce101242017-09-01 15:51:02 -04001708
1709##
1710
1711#Method int saveLayerAlpha(const SkRect* bounds, U8CPU alpha)
1712
1713Saves Matrix, Clip, and Draw_Filter (Draw_Filter deprecated on most platforms),
1714and allocates Bitmap for subsequent drawing.
1715
1716Calling restore() discards changes to Matrix, Clip, and Draw_Filter,
1717and blends Layer with alpha opacity onto prior Layer.
1718
1719Matrix may be changed by translate(), scale(), rotate(), skew(), concat(),
1720setMatrix, and resetMatrix. Clip may be changed by clipRect, clipRRect,
1721clipPath, clipRegion.
1722
1723Rect bounds suggests but does not define Layer size. To clip drawing to
1724a specific rectangle, use clipRect.
1725
1726alpha of zero is fully transparent, 255 is fully opaque.
1727
1728Call restoreToCount with returned value to restore this and subsequent saves.
1729
1730#Param bounds hint to limit the size of Layer; may be nullptr ##
1731#Param alpha opacity of Layer ##
1732
1733#Return depth of saved stack ##
1734
1735#Example
1736 SkPaint paint;
1737 paint.setColor(SK_ColorRED);
1738 canvas->drawCircle(50, 50, 50, paint);
1739 canvas->saveLayerAlpha(nullptr, 128);
1740 paint.setColor(SK_ColorBLUE);
1741 canvas->drawCircle(100, 50, 50, paint);
1742 paint.setColor(SK_ColorGREEN);
1743 paint.setAlpha(128);
1744 canvas->drawCircle(75, 90, 50, paint);
1745 canvas->restore();
1746##
1747
Cary Clark2ade9972017-11-02 17:49:34 -04001748#SeeAlso save() restore() saveLayer saveLayerPreserveLCDTextRequests SaveLayerRec
Cary Clarkce101242017-09-01 15:51:02 -04001749
1750##
1751
1752#Enum
1753
1754#Code
1755 enum {
1756 kIsOpaque_SaveLayerFlag = 1 << 0,
1757 kPreserveLCDText_SaveLayerFlag = 1 << 1,
1758 kInitWithPrevious_SaveLayerFlag = 1 << 2,
1759 kDontClipToLayer_Legacy_SaveLayerFlag = kDontClipToLayer_PrivateSaveLayerFlag,
1760 };
Cary Clarkce101242017-09-01 15:51:02 -04001761##
1762
1763SaveLayerFlags provides options that may be used in any combination in SaveLayerRec,
1764defining how Layer allocated by saveLayer operates.
1765
1766#Const kIsOpaque_SaveLayerFlag 1
1767 Creates Layer without transparency. Flag is ignored if Layer Paint contains
1768 Image_Filter or Color_Filter.
1769##
1770
1771#Const kPreserveLCDText_SaveLayerFlag 2
1772 Creates Layer for LCD text. Flag is ignored if Layer Paint contains
1773 Image_Filter or Color_Filter.
1774##
1775
1776#Const kInitWithPrevious_SaveLayerFlag 4
1777 Initializes Layer with the contents of the previous Layer.
1778##
1779
1780#Const kDontClipToLayer_Legacy_SaveLayerFlag 0x80000000
1781#Private
1782 to be deprecated: bug.skia.org/2440
1783##
1784 Only present on Android.
1785 Skips setting a clip to the Layer bounds.
1786##
1787
1788#Example
1789#Height 160
1790#Description
1791Canvas Layer captures red and blue circles scaled up by four.
1792scalePaint blends Layer back with transparency.
1793##
1794void draw(SkCanvas* canvas) {
1795 SkPaint redPaint, bluePaint, scalePaint;
1796 redPaint.setColor(SK_ColorRED);
1797 canvas->drawCircle(21, 21, 8, redPaint);
1798 bluePaint.setColor(SK_ColorBLUE);
1799 canvas->drawCircle(31, 21, 8, bluePaint);
1800 SkMatrix matrix;
1801 matrix.setScale(4, 4);
1802 scalePaint.setAlpha(0x40);
1803 scalePaint.setImageFilter(
1804 SkImageFilter::MakeMatrixFilter(matrix, kNone_SkFilterQuality, nullptr));
1805 SkCanvas::SaveLayerRec saveLayerRec(nullptr, &scalePaint,
1806 SkCanvas::kInitWithPrevious_SaveLayerFlag);
1807 canvas->saveLayer(saveLayerRec);
1808 canvas->restore();
1809}
1810##
1811
Cary Clark2ade9972017-11-02 17:49:34 -04001812#SeeAlso save() restore() saveLayer saveLayerPreserveLCDTextRequests saveLayerAlpha SaveLayerRec
Cary Clarkce101242017-09-01 15:51:02 -04001813
1814#Enum ##
1815
Cary Clarka560c472017-11-27 10:44:06 -05001816#Typedef uint32_t SaveLayerFlags
1817
1818##
1819
Cary Clarkce101242017-09-01 15:51:02 -04001820#Struct SaveLayerRec
1821
1822#Code
1823 struct SaveLayerRec {
1824 SaveLayerRec*(...
1825
1826 const SkRect* fBounds;
1827 const SkPaint* fPaint;
1828 const SkImageFilter* fBackdrop;
1829 SaveLayerFlags fSaveLayerFlags;
1830 };
1831##
1832
1833SaveLayerRec contains the state used to create the Layer.
1834
1835#Member const SkRect* fBounds
1836 fBounds is used as a hint to limit the size of Layer; may be nullptr.
1837 fBounds suggests but does not define Layer size. To clip drawing to
1838 a specific rectangle, use clipRect.
1839##
1840
1841#Member const SkPaint* fPaint
1842 fPaint modifies how Layer overlays the prior Layer; may be nullptr.
1843 Color_Alpha, Blend_Mode, Color_Filter, Draw_Looper, Image_Filter, and
1844 Mask_Filter affect Layer draw.
1845##
1846
1847#Member const SkImageFilter* fBackdrop
1848 fBackdrop applies Image_Filter to the prior Layer when copying to the Layer;
1849 may be nullptr. Use kInitWithPrevious_SaveLayerFlag to copy the
1850 prior Layer without an Image_Filter.
1851##
1852
1853#Member const SkImage* fClipMask
1854 restore() clips Layer by the Color_Alpha channel of fClipMask when
1855 Layer is copied to Device. fClipMask may be nullptr. .
1856##
1857
1858#Member const SkMatrix* fClipMatrix
1859 fClipMatrix transforms fClipMask before it clips Layer. If
1860 fClipMask describes a translucent gradient, it may be scaled and rotated
1861 without introducing artifacts. fClipMatrix may be nullptr.
1862##
1863
1864#Member SaveLayerFlags fSaveLayerFlags
1865 fSaveLayerFlags are used to create Layer without transparency,
1866 create Layer for LCD text, and to create Layer with the
1867 contents of the previous Layer.
1868##
1869
1870#Example
1871#Height 160
1872#Description
1873Canvas Layer captures a red Anti-aliased circle and a blue Aliased circle scaled
1874up by four. After drawing another red circle without scaling on top, the Layer is
1875transferred to the main canvas.
1876##
1877void draw(SkCanvas* canvas) {
1878 SkPaint redPaint, bluePaint;
1879 redPaint.setAntiAlias(true);
1880 redPaint.setColor(SK_ColorRED);
1881 canvas->drawCircle(21, 21, 8, redPaint);
1882 bluePaint.setColor(SK_ColorBLUE);
1883 canvas->drawCircle(31, 21, 8, bluePaint);
1884 SkMatrix matrix;
1885 matrix.setScale(4, 4);
1886 auto scaler = SkImageFilter::MakeMatrixFilter(matrix, kNone_SkFilterQuality, nullptr);
1887 SkCanvas::SaveLayerRec saveLayerRec(nullptr, nullptr, scaler.get(), 0);
1888 canvas->saveLayer(saveLayerRec);
1889 canvas->drawCircle(125, 85, 8, redPaint);
1890 canvas->restore();
1891}
1892##
1893
1894#Method SaveLayerRec()
1895
1896Sets fBounds, fPaint, and fBackdrop to nullptr. Clears fSaveLayerFlags.
1897
1898#Return empty SaveLayerRec ##
1899
1900#Example
1901 SkCanvas::SaveLayerRec rec1;
1902 rec1.fSaveLayerFlags = SkCanvas::kIsOpaque_SaveLayerFlag;
1903 SkCanvas::SaveLayerRec rec2(nullptr, nullptr, SkCanvas::kIsOpaque_SaveLayerFlag);
1904 SkDebugf("rec1 %c= rec2\n", rec1.fBounds == rec2.fBounds
1905 && rec1.fPaint == rec2.fPaint
1906 && rec1.fBackdrop == rec2.fBackdrop
1907 && rec1.fSaveLayerFlags == rec2.fSaveLayerFlags ? '=' : '!');
1908 #StdOut
1909 rec1 == rec2
1910 ##
1911##
1912
Cary Clark2ade9972017-11-02 17:49:34 -04001913#SeeAlso save() restore() saveLayer saveLayerPreserveLCDTextRequests saveLayerAlpha
1914
Cary Clarkce101242017-09-01 15:51:02 -04001915##
1916
1917#Method SaveLayerRec(const SkRect* bounds, const SkPaint* paint, SaveLayerFlags saveLayerFlags = 0)
1918
1919Sets fBounds, fPaint, and fSaveLayerFlags; sets fBackdrop to nullptr.
1920
1921#Param bounds Layer dimensions; may be nullptr ##
1922#Param paint applied to Layer when overlaying prior Layer; may be nullptr ##
1923#Param saveLayerFlags SaveLayerRec options to modify Layer ##
1924
1925#Return SaveLayerRec with empty backdrop ##
1926
1927#Example
1928 SkCanvas::SaveLayerRec rec1;
1929 SkCanvas::SaveLayerRec rec2(nullptr, nullptr);
1930 SkDebugf("rec1 %c= rec2\n", rec1.fBounds == rec2.fBounds
1931 && rec1.fPaint == rec2.fPaint
1932 && rec1.fBackdrop == rec2.fBackdrop
1933 && rec1.fSaveLayerFlags == rec2.fSaveLayerFlags ? '=' : '!');
1934 #StdOut
1935 rec1 == rec2
1936 ##
1937##
1938
Cary Clark2ade9972017-11-02 17:49:34 -04001939#SeeAlso save() restore() saveLayer saveLayerPreserveLCDTextRequests saveLayerAlpha
1940
Cary Clarkce101242017-09-01 15:51:02 -04001941##
1942
1943#Method SaveLayerRec(const SkRect* bounds, const SkPaint* paint, const SkImageFilter* backdrop,
1944 SaveLayerFlags saveLayerFlags)
1945
1946Sets fBounds, fPaint, fBackdrop, and fSaveLayerFlags.
1947
1948#Param bounds Layer dimensions; may be nullptr ##
1949#Param paint applied to Layer when overlaying prior Layer;
1950 may be nullptr
1951##
1952#Param backdrop prior Layer copied with Image_Filter; may be nullptr
1953##
1954#Param saveLayerFlags SaveLayerRec options to modify Layer ##
1955
1956#Return SaveLayerRec fully specified ##
1957
1958#Example
1959 SkCanvas::SaveLayerRec rec1;
1960 SkCanvas::SaveLayerRec rec2(nullptr, nullptr, nullptr, 0);
1961 SkDebugf("rec1 %c= rec2\n", rec1.fBounds == rec2.fBounds
1962 && rec1.fPaint == rec2.fPaint
1963 && rec1.fBackdrop == rec2.fBackdrop
1964 && rec1.fSaveLayerFlags == rec2.fSaveLayerFlags ? '=' : '!');
1965 #StdOut
1966 rec1 == rec2
1967 ##
1968##
1969
Cary Clark2ade9972017-11-02 17:49:34 -04001970#SeeAlso save() restore() saveLayer saveLayerPreserveLCDTextRequests saveLayerAlpha
1971
Cary Clarkce101242017-09-01 15:51:02 -04001972##
1973
1974#Method SaveLayerRec(const SkRect* bounds, const SkPaint* paint, const SkImageFilter* backdrop,
1975 const SkImage* clipMask, const SkMatrix* clipMatrix,
1976 SaveLayerFlags saveLayerFlags)
1977
1978#Experimental
1979Not ready for general use.
1980##
1981
1982Sets fBounds, fPaint, fBackdrop, fClipMask, fClipMatrix, and fSaveLayerFlags.
1983clipMatrix uses Color_Alpha channel of image, transformed by clipMatrix, to clip
1984Layer when drawn to Canvas.
1985
Cary Clark2ade9972017-11-02 17:49:34 -04001986Implementation is not complete; has no effect if Device is GPU-backed.
Cary Clarkce101242017-09-01 15:51:02 -04001987
1988#Param bounds Layer dimensions; may be nullptr ##
1989#Param paint graphics state applied to Layer when overlaying prior
1990 Layer; may be nullptr
1991##
1992#Param backdrop prior Layer copied with Image_Filter;
1993 may be nullptr
1994##
1995#Param clipMask clip applied to Layer; may be nullptr ##
1996#Param clipMatrix matrix applied to clipMask; may be nullptr to use
1997 identity matrix
1998##
1999#Param saveLayerFlags SaveLayerRec options to modify Layer ##
2000
2001#Return SaveLayerRec fully specified ##
2002
Cary Clark2ade9972017-11-02 17:49:34 -04002003#SeeAlso save() restore() saveLayer saveLayerPreserveLCDTextRequests saveLayerAlpha
Cary Clarkce101242017-09-01 15:51:02 -04002004
2005##
2006
2007#Struct ##
2008
2009#Method int saveLayer(const SaveLayerRec& layerRec)
2010
2011Saves Matrix, Clip, and Draw_Filter (Draw_Filter deprecated on most platforms),
2012and allocates Bitmap for subsequent drawing.
2013
2014Calling restore() discards changes to Matrix, Clip, and Draw_Filter,
2015and blends Bitmap with Color_Alpha opacity onto the prior Layer.
2016
2017Matrix may be changed by translate(), scale(), rotate(), skew(), concat(),
2018setMatrix, and resetMatrix. Clip may be changed by clipRect, clipRRect,
2019clipPath, clipRegion.
2020
2021SaveLayerRec contains the state used to create the Layer.
2022
2023Call restoreToCount with returned value to restore this and subsequent saves.
2024
2025#Param layerRec Layer state ##
2026
2027#Return depth of save state stack ##
2028
2029#Example
2030#Description
2031The example draws an image, and saves it into a Layer with kInitWithPrevious_SaveLayerFlag.
2032Next it punches a hole in Layer and restore with SkBlendMode::kPlus.
2033Where Layer was cleared, the original image will draw unchanged.
2034Outside of the circle the mandrill is brightened.
2035##
2036 #Image 3
2037 // sk_sp<SkImage> image = GetResourceAsImage("mandrill_256.png");
2038 canvas->drawImage(image, 0, 0, nullptr);
2039 SkCanvas::SaveLayerRec rec;
2040 SkPaint paint;
2041 paint.setBlendMode(SkBlendMode::kPlus);
2042 rec.fSaveLayerFlags = SkCanvas::kInitWithPrevious_SaveLayerFlag;
2043 rec.fPaint = &paint;
2044 canvas->saveLayer(rec);
2045 paint.setBlendMode(SkBlendMode::kClear);
2046 canvas->drawCircle(128, 128, 96, paint);
2047 canvas->restore();
2048##
2049
2050#ToDo above example needs to replace GetResourceAsImage with way to select image in fiddle ##
2051
Cary Clark2ade9972017-11-02 17:49:34 -04002052#SeeAlso save() restore() saveLayer saveLayerPreserveLCDTextRequests saveLayerAlpha
2053
Cary Clarkce101242017-09-01 15:51:02 -04002054##
2055
2056#Topic Layer ##
2057
2058# ------------------------------------------------------------------------------
Cary Clark8032b982017-07-28 11:04:54 -04002059#Topic Matrix
2060
2061#Method void translate(SkScalar dx, SkScalar dy)
2062
2063Translate Matrix by dx along the x-axis and dy along the y-axis.
2064
2065Mathematically, replace Matrix with a translation matrix
Cary Clarkce101242017-09-01 15:51:02 -04002066Premultiplied with Matrix.
Cary Clark8032b982017-07-28 11:04:54 -04002067
2068This has the effect of moving the drawing by (dx, dy) before transforming
2069the result with Matrix.
2070
Cary Clarkbad5ad72017-08-03 17:14:08 -04002071#Param dx distance to translate in x ##
2072#Param dy distance to translate in y ##
Cary Clark8032b982017-07-28 11:04:54 -04002073
2074#Example
2075#Height 128
2076#Description
2077scale() followed by translate() produces different results from translate() followed
2078by scale().
2079
2080The blue stroke follows translate of (50, 50); a black
2081fill follows scale of (2, 1/2.f). After restoring the clip, which resets
2082Matrix, a red frame follows the same scale of (2, 1/2.f); a gray fill
2083follows translate of (50, 50).
2084##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002085void draw(SkCanvas* canvas) {
2086 SkPaint filledPaint;
2087 SkPaint outlinePaint;
2088 outlinePaint.setStyle(SkPaint::kStroke_Style);
2089 outlinePaint.setColor(SK_ColorBLUE);
2090 canvas->save();
2091 canvas->translate(50, 50);
2092 canvas->drawCircle(28, 28, 15, outlinePaint); // blue center: (50+28, 50+28)
2093 canvas->scale(2, 1/2.f);
2094 canvas->drawCircle(28, 28, 15, filledPaint); // black center: (50+(28*2), 50+(28/2))
2095 canvas->restore();
2096 filledPaint.setColor(SK_ColorGRAY);
2097 outlinePaint.setColor(SK_ColorRED);
2098 canvas->scale(2, 1/2.f);
2099 canvas->drawCircle(28, 28, 15, outlinePaint); // red center: (28*2, 28/2)
2100 canvas->translate(50, 50);
2101 canvas->drawCircle(28, 28, 15, filledPaint); // gray center: ((50+28)*2, (50+28)/2)
Cary Clark8032b982017-07-28 11:04:54 -04002102}
2103##
2104
Cary Clark2ade9972017-11-02 17:49:34 -04002105#SeeAlso concat() scale() skew() rotate() setMatrix
Cary Clark8032b982017-07-28 11:04:54 -04002106
2107##
2108
2109# ------------------------------------------------------------------------------
2110
2111#Method void scale(SkScalar sx, SkScalar sy)
2112
2113Scale Matrix by sx on the x-axis and sy on the y-axis.
2114
2115Mathematically, replace Matrix with a scale matrix
Cary Clarkce101242017-09-01 15:51:02 -04002116Premultiplied with Matrix.
Cary Clark8032b982017-07-28 11:04:54 -04002117
2118This has the effect of scaling the drawing by (sx, sy) before transforming
2119the result with Matrix.
2120
Cary Clarkbad5ad72017-08-03 17:14:08 -04002121#Param sx amount to scale in x ##
2122#Param sy amount to scale in y ##
Cary Clark8032b982017-07-28 11:04:54 -04002123
2124#Example
2125#Height 160
Cary Clarkbad5ad72017-08-03 17:14:08 -04002126void draw(SkCanvas* canvas) {
2127 SkPaint paint;
2128 SkRect rect = { 10, 20, 60, 120 };
2129 canvas->translate(20, 20);
2130 canvas->drawRect(rect, paint);
2131 canvas->scale(2, .5f);
2132 paint.setColor(SK_ColorGRAY);
2133 canvas->drawRect(rect, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002134}
2135##
2136
Cary Clark2ade9972017-11-02 17:49:34 -04002137#SeeAlso concat() translate() skew() rotate() setMatrix
Cary Clark8032b982017-07-28 11:04:54 -04002138
2139##
2140
2141# ------------------------------------------------------------------------------
2142
2143#Method void rotate(SkScalar degrees)
2144
2145Rotate Matrix by degrees. Positive degrees rotates clockwise.
2146
2147Mathematically, replace Matrix with a rotation matrix
Cary Clarkce101242017-09-01 15:51:02 -04002148Premultiplied with Matrix.
Cary Clark8032b982017-07-28 11:04:54 -04002149
2150This has the effect of rotating the drawing by degrees before transforming
2151the result with Matrix.
2152
Cary Clarkbad5ad72017-08-03 17:14:08 -04002153#Param degrees amount to rotate, in degrees ##
Cary Clark8032b982017-07-28 11:04:54 -04002154
2155#Example
2156#Description
2157Draw clock hands at time 5:10. The hour hand and minute hand point up and
2158are rotated clockwise.
2159##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002160void draw(SkCanvas* canvas) {
2161 SkPaint paint;
2162 paint.setStyle(SkPaint::kStroke_Style);
2163 canvas->translate(128, 128);
2164 canvas->drawCircle(0, 0, 60, paint);
2165 canvas->save();
2166 canvas->rotate(10 * 360 / 60); // 10 minutes of 60 scaled to 360 degrees
2167 canvas->drawLine(0, 0, 0, -50, paint);
2168 canvas->restore();
2169 canvas->rotate((5 + 10.f/60) * 360 / 12); // 5 and 10/60 hours of 12 scaled to 360 degrees
2170 canvas->drawLine(0, 0, 0, -30, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002171}
2172##
2173
Cary Clark2ade9972017-11-02 17:49:34 -04002174#SeeAlso concat() translate() skew() scale() setMatrix
Cary Clark8032b982017-07-28 11:04:54 -04002175
2176##
2177
2178# ------------------------------------------------------------------------------
2179
2180#Method void rotate(SkScalar degrees, SkScalar px, SkScalar py)
2181
Cary Clarkbad5ad72017-08-03 17:14:08 -04002182Rotate Matrix by degrees about a point at (px, py). Positive degrees rotates
2183clockwise.
Cary Clark8032b982017-07-28 11:04:54 -04002184
Cary Clarkce101242017-09-01 15:51:02 -04002185Mathematically, construct a rotation matrix. Premultiply the rotation matrix by
Cary Clark8032b982017-07-28 11:04:54 -04002186a translation matrix, then replace Matrix with the resulting matrix
Cary Clarkce101242017-09-01 15:51:02 -04002187Premultiplied with Matrix.
Cary Clark8032b982017-07-28 11:04:54 -04002188
Cary Clarkbad5ad72017-08-03 17:14:08 -04002189This has the effect of rotating the drawing about a given point before
2190transforming the result with Matrix.
Cary Clark8032b982017-07-28 11:04:54 -04002191
Cary Clarkbad5ad72017-08-03 17:14:08 -04002192#Param degrees amount to rotate, in degrees ##
2193#Param px x-coordinate of the point to rotate about ##
2194#Param py y-coordinate of the point to rotate about ##
Cary Clark8032b982017-07-28 11:04:54 -04002195
2196#Example
2197#Height 192
Cary Clarkbad5ad72017-08-03 17:14:08 -04002198void draw(SkCanvas* canvas) {
2199 SkPaint paint;
2200 paint.setTextSize(96);
2201 canvas->drawString("A1", 130, 100, paint);
2202 canvas->rotate(180, 130, 100);
2203 canvas->drawString("A1", 130, 100, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002204}
2205##
2206
Cary Clark2ade9972017-11-02 17:49:34 -04002207#SeeAlso concat() translate() skew() scale() setMatrix
Cary Clark8032b982017-07-28 11:04:54 -04002208
2209##
2210
2211# ------------------------------------------------------------------------------
2212
2213#Method void skew(SkScalar sx, SkScalar sy)
2214
Cary Clarkbad5ad72017-08-03 17:14:08 -04002215Skew Matrix by sx on the x-axis and sy on the y-axis. A positive value of sx
2216skews the drawing right as y increases; a positive value of sy skews the drawing
2217down as x increases.
Cary Clark8032b982017-07-28 11:04:54 -04002218
Cary Clarkce101242017-09-01 15:51:02 -04002219Mathematically, replace Matrix with a skew matrix Premultiplied with Matrix.
Cary Clark8032b982017-07-28 11:04:54 -04002220
Cary Clarkbad5ad72017-08-03 17:14:08 -04002221This has the effect of skewing the drawing by (sx, sy) before transforming
Cary Clark8032b982017-07-28 11:04:54 -04002222the result with Matrix.
2223
Cary Clarkbad5ad72017-08-03 17:14:08 -04002224#Param sx amount to skew in x ##
2225#Param sy amount to skew in y ##
2226
Cary Clark8032b982017-07-28 11:04:54 -04002227#Example
2228 #Description
2229 Black text mimics an oblique text style by using a negative skew in x that
2230 shifts the geometry to the right as the y values decrease.
2231 Red text uses a positive skew in y to shift the geometry down as the x values
2232 increase.
2233 Blue text combines x and y skew to rotate and scale.
2234 ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002235 SkPaint paint;
2236 paint.setTextSize(128);
2237 canvas->translate(30, 130);
2238 canvas->save();
2239 canvas->skew(-.5, 0);
2240 canvas->drawString("A1", 0, 0, paint);
2241 canvas->restore();
2242 canvas->save();
2243 canvas->skew(0, .5);
2244 paint.setColor(SK_ColorRED);
2245 canvas->drawString("A1", 0, 0, paint);
2246 canvas->restore();
2247 canvas->skew(-.5, .5);
2248 paint.setColor(SK_ColorBLUE);
Cary Clark8032b982017-07-28 11:04:54 -04002249 canvas->drawString("A1", 0, 0, paint);
2250##
2251
Cary Clark2ade9972017-11-02 17:49:34 -04002252#SeeAlso concat() translate() rotate() scale() setMatrix
Cary Clark8032b982017-07-28 11:04:54 -04002253
2254##
2255
2256# ------------------------------------------------------------------------------
2257
2258#Method void concat(const SkMatrix& matrix)
2259
Cary Clarkce101242017-09-01 15:51:02 -04002260Replace Matrix with matrix Premultiplied with existing Matrix.
Cary Clark8032b982017-07-28 11:04:54 -04002261
Cary Clarkbad5ad72017-08-03 17:14:08 -04002262This has the effect of transforming the drawn geometry by matrix, before
2263transforming the result with existing Matrix.
Cary Clark8032b982017-07-28 11:04:54 -04002264
Cary Clarkce101242017-09-01 15:51:02 -04002265#Param matrix matrix to Premultiply with existing Matrix ##
Cary Clark8032b982017-07-28 11:04:54 -04002266
2267#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04002268void draw(SkCanvas* canvas) {
2269 SkPaint paint;
2270 paint.setTextSize(80);
2271 paint.setTextScaleX(.3);
2272 SkMatrix matrix;
2273 SkRect rect[2] = {{ 10, 20, 90, 110 }, { 40, 130, 140, 180 }};
2274 matrix.setRectToRect(rect[0], rect[1], SkMatrix::kFill_ScaleToFit);
2275 canvas->drawRect(rect[0], paint);
2276 canvas->drawRect(rect[1], paint);
2277 paint.setColor(SK_ColorWHITE);
2278 canvas->drawString("Here", rect[0].fLeft + 10, rect[0].fBottom - 10, paint);
2279 canvas->concat(matrix);
2280 canvas->drawString("There", rect[0].fLeft + 10, rect[0].fBottom - 10, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002281}
2282##
2283
Cary Clark2ade9972017-11-02 17:49:34 -04002284#SeeAlso translate() rotate() scale() skew() setMatrix
Cary Clark8032b982017-07-28 11:04:54 -04002285
2286##
2287
2288# ------------------------------------------------------------------------------
2289
2290#Method void setMatrix(const SkMatrix& matrix)
2291
2292Replace Matrix with matrix.
2293Unlike concat(), any prior matrix state is overwritten.
2294
Cary Clarkbad5ad72017-08-03 17:14:08 -04002295#Param matrix matrix to copy, replacing existing Matrix ##
Cary Clark8032b982017-07-28 11:04:54 -04002296
2297#Example
2298#Height 128
Cary Clarkbad5ad72017-08-03 17:14:08 -04002299void draw(SkCanvas* canvas) {
2300 SkPaint paint;
2301 canvas->scale(4, 6);
2302 canvas->drawString("truth", 2, 10, paint);
2303 SkMatrix matrix;
2304 matrix.setScale(2.8f, 6);
2305 canvas->setMatrix(matrix);
2306 canvas->drawString("consequences", 2, 20, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002307}
2308##
2309
Cary Clark2ade9972017-11-02 17:49:34 -04002310#SeeAlso resetMatrix concat() translate() rotate() scale() skew()
Cary Clark8032b982017-07-28 11:04:54 -04002311
2312##
2313
2314# ------------------------------------------------------------------------------
2315
2316#Method void resetMatrix()
2317
2318Sets Matrix to the identity matrix.
2319Any prior matrix state is overwritten.
2320
2321#Example
2322#Height 128
Cary Clarkbad5ad72017-08-03 17:14:08 -04002323void draw(SkCanvas* canvas) {
2324 SkPaint paint;
2325 canvas->scale(4, 6);
2326 canvas->drawString("truth", 2, 10, paint);
2327 canvas->resetMatrix();
2328 canvas->scale(2.8f, 6);
2329 canvas->drawString("consequences", 2, 20, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002330}
2331##
2332
Cary Clark2ade9972017-11-02 17:49:34 -04002333#SeeAlso setMatrix concat() translate() rotate() scale() skew()
Cary Clark8032b982017-07-28 11:04:54 -04002334
2335##
2336
2337# ------------------------------------------------------------------------------
2338
2339#Method const SkMatrix& getTotalMatrix() const
2340
2341Returns Matrix.
2342This does not account for translation by Device or Surface.
2343
Cary Clarkbad5ad72017-08-03 17:14:08 -04002344#Return Matrix in Canvas ##
Cary Clark8032b982017-07-28 11:04:54 -04002345
2346#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04002347 SkDebugf("isIdentity %s\n", canvas->getTotalMatrix().isIdentity() ? "true" : "false");
2348 #StdOut
2349 isIdentity true
2350 ##
Cary Clark8032b982017-07-28 11:04:54 -04002351##
2352
Cary Clark2ade9972017-11-02 17:49:34 -04002353#SeeAlso setMatrix resetMatrix concat()
Cary Clark8032b982017-07-28 11:04:54 -04002354
2355##
2356
2357#Topic Matrix ##
2358
2359# ------------------------------------------------------------------------------
2360#Topic Clip
2361
2362Clip is built from a stack of clipping paths. Each Path in the
2363stack can be constructed from one or more Path_Contour elements. The
2364Path_Contour may be composed of any number of Path_Verb segments. Each
2365Path_Contour forms a closed area; Path_Fill_Type defines the area enclosed
2366by Path_Contour.
2367
2368Clip stack of Path elements successfully restrict the Path area. Each
2369Path is transformed by Matrix, then intersected with or subtracted from the
2370prior Clip to form the replacement Clip. Use SkClipOp::kDifference
2371to subtract Path from Clip; use SkClipOp::kIntersect to intersect Path
2372with Clip.
2373
Cary Clarkce101242017-09-01 15:51:02 -04002374A clipping Path may be Anti-aliased; if Path, after transformation, is
Cary Clark8032b982017-07-28 11:04:54 -04002375composed of horizontal and vertical lines, clearing Anti-alias allows whole pixels
Cary Clarkce101242017-09-01 15:51:02 -04002376to either be inside or outside the clip. The fastest drawing has a Aliased,
2377rectangular clip.
Cary Clark8032b982017-07-28 11:04:54 -04002378
2379If clipping Path has Anti-alias set, clip may partially clip a pixel, requiring
2380that drawing blend partially with the destination along the edge. A rotated
Cary Clarkce101242017-09-01 15:51:02 -04002381rectangular Anti-aliased clip looks smoother but draws slower.
Cary Clark8032b982017-07-28 11:04:54 -04002382
2383Clip can combine with Rect and Round_Rect primitives; like
2384Path, these are transformed by Matrix before they are combined with Clip.
2385
2386Clip can combine with Region. Region is assumed to be in Device coordinates
2387and is unaffected by Matrix.
2388
2389#Example
2390#Height 90
2391 #Description
Cary Clarkce101242017-09-01 15:51:02 -04002392 Draw a red circle with an Aliased clip and an Anti-aliased clip.
Cary Clark8032b982017-07-28 11:04:54 -04002393 Use an image filter to zoom into the pixels drawn.
Cary Clarkce101242017-09-01 15:51:02 -04002394 The edge of the Aliased clip fully draws pixels in the red circle.
2395 The edge of the Anti-aliased clip partially draws pixels in the red circle.
Cary Clark8032b982017-07-28 11:04:54 -04002396 ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002397 SkPaint redPaint, scalePaint;
2398 redPaint.setAntiAlias(true);
2399 redPaint.setColor(SK_ColorRED);
2400 canvas->save();
2401 for (bool antialias : { false, true } ) {
2402 canvas->save();
2403 canvas->clipRect(SkRect::MakeWH(19.5f, 11.5f), antialias);
2404 canvas->drawCircle(17, 11, 8, redPaint);
2405 canvas->restore();
2406 canvas->translate(16, 0);
2407 }
2408 canvas->restore();
2409 SkMatrix matrix;
2410 matrix.setScale(6, 6);
2411 scalePaint.setImageFilter(
2412 SkImageFilter::MakeMatrixFilter(matrix, kNone_SkFilterQuality, nullptr));
2413 SkCanvas::SaveLayerRec saveLayerRec(
2414 nullptr, &scalePaint, SkCanvas::kInitWithPrevious_SaveLayerFlag);
2415 canvas->saveLayer(saveLayerRec);
Cary Clark8032b982017-07-28 11:04:54 -04002416 canvas->restore();
2417##
2418
2419#Method void clipRect(const SkRect& rect, SkClipOp op, bool doAntiAlias)
2420
2421Replace Clip with the intersection or difference of Clip and rect,
Cary Clarkce101242017-09-01 15:51:02 -04002422with an Aliased or Anti-aliased clip edge. rect is transformed by Matrix
Cary Clark8032b982017-07-28 11:04:54 -04002423before it is combined with Clip.
2424
Cary Clarka523d2d2017-08-30 08:58:10 -04002425#Param rect Rect to combine with Clip ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002426#Param op Clip_Op to apply to Clip ##
Cary Clarkce101242017-09-01 15:51:02 -04002427#Param doAntiAlias true if Clip is to be Anti-aliased ##
Cary Clark8032b982017-07-28 11:04:54 -04002428
2429#Example
2430#Height 128
Cary Clarkbad5ad72017-08-03 17:14:08 -04002431void draw(SkCanvas* canvas) {
2432 canvas->rotate(10);
2433 SkPaint paint;
2434 paint.setAntiAlias(true);
2435 for (auto alias: { false, true } ) {
2436 canvas->save();
2437 canvas->clipRect(SkRect::MakeWH(90, 80), SkClipOp::kIntersect, alias);
2438 canvas->drawCircle(100, 60, 60, paint);
2439 canvas->restore();
2440 canvas->translate(80, 0);
2441 }
Cary Clark8032b982017-07-28 11:04:54 -04002442}
2443##
2444
Cary Clark2ade9972017-11-02 17:49:34 -04002445#SeeAlso clipRRect clipPath clipRegion
Cary Clark8032b982017-07-28 11:04:54 -04002446
2447##
2448
2449#Method void clipRect(const SkRect& rect, SkClipOp op)
2450
2451Replace Clip with the intersection or difference of Clip and rect.
Cary Clarkce101242017-09-01 15:51:02 -04002452Resulting Clip is Aliased; pixels are fully contained by the clip.
Cary Clarkbad5ad72017-08-03 17:14:08 -04002453rect is transformed by Matrix before it is combined with Clip.
Cary Clark8032b982017-07-28 11:04:54 -04002454
Cary Clarka523d2d2017-08-30 08:58:10 -04002455#Param rect Rect to combine with Clip ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002456#Param op Clip_Op to apply to Clip ##
Cary Clark8032b982017-07-28 11:04:54 -04002457
2458#Example
2459#Height 192
2460#Width 280
Cary Clarkbad5ad72017-08-03 17:14:08 -04002461void draw(SkCanvas* canvas) {
2462 SkPaint paint;
2463 for (SkClipOp op: { SkClipOp::kIntersect, SkClipOp::kDifference } ) {
2464 canvas->save();
2465 canvas->clipRect(SkRect::MakeWH(90, 120), op, false);
2466 canvas->drawCircle(100, 100, 60, paint);
2467 canvas->restore();
2468 canvas->translate(80, 0);
2469 }
Cary Clark8032b982017-07-28 11:04:54 -04002470}
2471##
2472
Cary Clark2ade9972017-11-02 17:49:34 -04002473#SeeAlso clipRRect clipPath clipRegion
Cary Clark8032b982017-07-28 11:04:54 -04002474
2475##
2476
2477#Method void clipRect(const SkRect& rect, bool doAntiAlias = false)
2478
2479Replace Clip with the intersection of Clip and rect.
Cary Clarkce101242017-09-01 15:51:02 -04002480Resulting Clip is Aliased; pixels are fully contained by the clip.
Cary Clark8032b982017-07-28 11:04:54 -04002481rect is transformed by Matrix
2482before it is combined with Clip.
2483
Cary Clarka523d2d2017-08-30 08:58:10 -04002484#Param rect Rect to combine with Clip ##
Cary Clarkce101242017-09-01 15:51:02 -04002485#Param doAntiAlias true if Clip is to be Anti-aliased ##
Cary Clark8032b982017-07-28 11:04:54 -04002486
2487#Example
2488#Height 133
2489 #Description
Cary Clarkce101242017-09-01 15:51:02 -04002490 A circle drawn in pieces looks uniform when drawn Aliased.
2491 The same circle pieces blend with pixels more than once when Anti-aliased,
Cary Clark8032b982017-07-28 11:04:54 -04002492 visible as a thin pair of lines through the right circle.
2493 ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002494void draw(SkCanvas* canvas) {
2495 canvas->clear(SK_ColorWHITE);
2496 SkPaint paint;
2497 paint.setAntiAlias(true);
2498 paint.setColor(0x8055aaff);
2499 SkRect clipRect = { 0, 0, 87.4f, 87.4f };
2500 for (auto alias: { false, true } ) {
2501 canvas->save();
2502 canvas->clipRect(clipRect, SkClipOp::kIntersect, alias);
2503 canvas->drawCircle(67, 67, 60, paint);
2504 canvas->restore();
2505 canvas->save();
2506 canvas->clipRect(clipRect, SkClipOp::kDifference, alias);
2507 canvas->drawCircle(67, 67, 60, paint);
2508 canvas->restore();
2509 canvas->translate(120, 0);
2510 }
Cary Clark8032b982017-07-28 11:04:54 -04002511}
2512##
2513
Cary Clark2ade9972017-11-02 17:49:34 -04002514#SeeAlso clipRRect clipPath clipRegion
Cary Clark8032b982017-07-28 11:04:54 -04002515
2516##
2517
2518#Method void androidFramework_setDeviceClipRestriction(const SkIRect& rect)
2519
Cary Clarkce101242017-09-01 15:51:02 -04002520Sets the maximum clip rectangle, which can be set by clipRect, clipRRect and
Cary Clark8032b982017-07-28 11:04:54 -04002521clipPath and intersect the current clip with the specified rect.
Cary Clarkce101242017-09-01 15:51:02 -04002522The maximum clip affects only future clipping operations; it is not retroactive.
Cary Clark8032b982017-07-28 11:04:54 -04002523The clip restriction is not recorded in pictures.
2524
Cary Clarkce101242017-09-01 15:51:02 -04002525Pass an empty rect to disable maximum clip.
Cary Clarkbad5ad72017-08-03 17:14:08 -04002526
Cary Clark8032b982017-07-28 11:04:54 -04002527#Private
2528This is private API to be used only by Android framework.
2529##
2530
Cary Clarkbad5ad72017-08-03 17:14:08 -04002531#Param rect maximum allowed clip in device coordinates
Cary Clark579985c2017-07-31 11:48:27 -04002532#Param ##
Cary Clark8032b982017-07-28 11:04:54 -04002533
2534##
2535
2536#Method void clipRRect(const SkRRect& rrect, SkClipOp op, bool doAntiAlias)
2537
2538Replace Clip with the intersection or difference of Clip and rrect,
Cary Clarkce101242017-09-01 15:51:02 -04002539with an Aliased or Anti-aliased clip edge.
Cary Clark8032b982017-07-28 11:04:54 -04002540rrect is transformed by Matrix
2541before it is combined with Clip.
2542
Cary Clarkbad5ad72017-08-03 17:14:08 -04002543#Param rrect Round_Rect to combine with Clip ##
2544#Param op Clip_Op to apply to Clip ##
Cary Clarkce101242017-09-01 15:51:02 -04002545#Param doAntiAlias true if Clip is to be Anti-aliased ##
Cary Clark8032b982017-07-28 11:04:54 -04002546
2547#Example
2548#Height 128
Cary Clarkbad5ad72017-08-03 17:14:08 -04002549void draw(SkCanvas* canvas) {
2550 canvas->clear(SK_ColorWHITE);
2551 SkPaint paint;
2552 paint.setAntiAlias(true);
2553 paint.setColor(0x8055aaff);
2554 SkRRect oval;
2555 oval.setOval({10, 20, 90, 100});
2556 canvas->clipRRect(oval, SkClipOp::kIntersect, true);
2557 canvas->drawCircle(70, 100, 60, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002558}
2559##
2560
Cary Clark2ade9972017-11-02 17:49:34 -04002561#SeeAlso clipRect clipPath clipRegion
Cary Clark8032b982017-07-28 11:04:54 -04002562
2563##
2564
2565#Method void clipRRect(const SkRRect& rrect, SkClipOp op)
2566
2567Replace Clip with the intersection or difference of Clip and rrect.
Cary Clarkce101242017-09-01 15:51:02 -04002568Resulting Clip is Aliased; pixels are fully contained by the clip.
Cary Clarkbad5ad72017-08-03 17:14:08 -04002569rrect is transformed by Matrix before it is combined with Clip.
Cary Clark8032b982017-07-28 11:04:54 -04002570
Cary Clarkbad5ad72017-08-03 17:14:08 -04002571#Param rrect Round_Rect to combine with Clip ##
2572#Param op Clip_Op to apply to Clip ##
Cary Clark8032b982017-07-28 11:04:54 -04002573
2574#Example
2575#Height 128
Cary Clarkbad5ad72017-08-03 17:14:08 -04002576void draw(SkCanvas* canvas) {
2577 SkPaint paint;
2578 paint.setColor(0x8055aaff);
2579 auto oval = SkRRect::MakeOval({10, 20, 90, 100});
2580 canvas->clipRRect(oval, SkClipOp::kIntersect);
2581 canvas->drawCircle(70, 100, 60, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002582}
2583##
2584
Cary Clark2ade9972017-11-02 17:49:34 -04002585#SeeAlso clipRect clipPath clipRegion
Cary Clark8032b982017-07-28 11:04:54 -04002586
2587##
2588
2589#Method void clipRRect(const SkRRect& rrect, bool doAntiAlias = false)
2590
2591Replace Clip with the intersection of Clip and rrect,
Cary Clarkce101242017-09-01 15:51:02 -04002592with an Aliased or Anti-aliased clip edge.
Cary Clarkbad5ad72017-08-03 17:14:08 -04002593rrect is transformed by Matrix before it is combined with Clip.
Cary Clark8032b982017-07-28 11:04:54 -04002594
Cary Clarkbad5ad72017-08-03 17:14:08 -04002595#Param rrect Round_Rect to combine with Clip ##
Cary Clarkce101242017-09-01 15:51:02 -04002596#Param doAntiAlias true if Clip is to be Anti-aliased ##
Cary Clark8032b982017-07-28 11:04:54 -04002597
2598#Example
2599#Height 128
Cary Clarkbad5ad72017-08-03 17:14:08 -04002600void draw(SkCanvas* canvas) {
2601 SkPaint paint;
2602 paint.setAntiAlias(true);
2603 auto oval = SkRRect::MakeRectXY({10, 20, 90, 100}, 9, 13);
2604 canvas->clipRRect(oval, true);
2605 canvas->drawCircle(70, 100, 60, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002606}
2607##
2608
Cary Clark2ade9972017-11-02 17:49:34 -04002609#SeeAlso clipRect clipPath clipRegion
Cary Clark8032b982017-07-28 11:04:54 -04002610
2611##
2612
2613#Method void clipPath(const SkPath& path, SkClipOp op, bool doAntiAlias)
2614
2615Replace Clip with the intersection or difference of Clip and path,
Cary Clarkce101242017-09-01 15:51:02 -04002616with an Aliased or Anti-aliased clip edge. Path_Fill_Type determines if path
Cary Clark8032b982017-07-28 11:04:54 -04002617describes the area inside or outside its contours; and if Path_Contour overlaps
2618itself or another Path_Contour, whether the overlaps form part of the area.
Cary Clarkbad5ad72017-08-03 17:14:08 -04002619path is transformed by Matrix before it is combined with Clip.
Cary Clark8032b982017-07-28 11:04:54 -04002620
Cary Clarkbad5ad72017-08-03 17:14:08 -04002621#Param path Path to combine with Clip ##
2622#Param op Clip_Op to apply to Clip ##
Cary Clarkce101242017-09-01 15:51:02 -04002623#Param doAntiAlias true if Clip is to be Anti-aliased ##
Cary Clark8032b982017-07-28 11:04:54 -04002624
2625#Example
2626#Description
2627Top figure uses SkPath::kInverseWinding_FillType and SkClipOp::kDifference;
2628area outside clip is subtracted from circle.
2629
2630Bottom figure uses SkPath::kWinding_FillType and SkClipOp::kIntersect;
2631area inside clip is intersected with circle.
2632##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002633void draw(SkCanvas* canvas) {
2634 SkPaint paint;
2635 paint.setAntiAlias(true);
2636 SkPath path;
2637 path.addRect({20, 30, 100, 110});
2638 path.setFillType(SkPath::kInverseWinding_FillType);
2639 canvas->save();
2640 canvas->clipPath(path, SkClipOp::kDifference, false);
2641 canvas->drawCircle(70, 100, 60, paint);
2642 canvas->restore();
2643 canvas->translate(100, 100);
2644 path.setFillType(SkPath::kWinding_FillType);
2645 canvas->clipPath(path, SkClipOp::kIntersect, false);
2646 canvas->drawCircle(70, 100, 60, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002647}
2648##
2649
Cary Clark2ade9972017-11-02 17:49:34 -04002650#SeeAlso clipRect clipRRect clipRegion
Cary Clark8032b982017-07-28 11:04:54 -04002651
2652##
2653
2654#Method void clipPath(const SkPath& path, SkClipOp op)
2655
2656Replace Clip with the intersection or difference of Clip and path.
Cary Clarkce101242017-09-01 15:51:02 -04002657Resulting Clip is Aliased; pixels are fully contained by the clip.
Cary Clark8032b982017-07-28 11:04:54 -04002658Path_Fill_Type determines if path
2659describes the area inside or outside its contours; and if Path_Contour overlaps
2660itself or another Path_Contour, whether the overlaps form part of the area.
2661path is transformed by Matrix
2662before it is combined with Clip.
2663
Cary Clarkbad5ad72017-08-03 17:14:08 -04002664#Param path Path to combine with Clip ##
2665#Param op Clip_Op to apply to Clip ##
Cary Clark8032b982017-07-28 11:04:54 -04002666
2667#Example
2668#Description
Cary Clarkbc5697d2017-10-04 14:31:33 -04002669Overlapping Rects form a clip. When clip Path_Fill_Type is set to
Cary Clark8032b982017-07-28 11:04:54 -04002670SkPath::kWinding_FillType, the overlap is included. Set to
2671SkPath::kEvenOdd_FillType, the overlap is excluded and forms a hole.
2672##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002673void draw(SkCanvas* canvas) {
2674 SkPaint paint;
2675 paint.setAntiAlias(true);
2676 SkPath path;
2677 path.addRect({20, 15, 100, 95});
2678 path.addRect({50, 65, 130, 135});
2679 path.setFillType(SkPath::kWinding_FillType);
2680 canvas->save();
2681 canvas->clipPath(path, SkClipOp::kIntersect);
2682 canvas->drawCircle(70, 85, 60, paint);
2683 canvas->restore();
2684 canvas->translate(100, 100);
2685 path.setFillType(SkPath::kEvenOdd_FillType);
2686 canvas->clipPath(path, SkClipOp::kIntersect);
2687 canvas->drawCircle(70, 85, 60, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002688}
2689##
2690
Cary Clark2ade9972017-11-02 17:49:34 -04002691#SeeAlso clipRect clipRRect clipRegion
Cary Clark8032b982017-07-28 11:04:54 -04002692
2693##
2694
2695#Method void clipPath(const SkPath& path, bool doAntiAlias = false)
2696
2697Replace Clip with the intersection of Clip and path.
Cary Clarkce101242017-09-01 15:51:02 -04002698Resulting Clip is Aliased; pixels are fully contained by the clip.
Cary Clark8032b982017-07-28 11:04:54 -04002699Path_Fill_Type determines if path
2700describes the area inside or outside its contours; and if Path_Contour overlaps
2701itself or another Path_Contour, whether the overlaps form part of the area.
Cary Clarkbad5ad72017-08-03 17:14:08 -04002702path is transformed by Matrix before it is combined with Clip.
Cary Clark8032b982017-07-28 11:04:54 -04002703
Cary Clarkbad5ad72017-08-03 17:14:08 -04002704#Param path Path to combine with Clip ##
Cary Clarkce101242017-09-01 15:51:02 -04002705#Param doAntiAlias true if Clip is to be Anti-aliased ##
Cary Clark8032b982017-07-28 11:04:54 -04002706
2707#Example
2708#Height 212
2709#Description
Cary Clarkbc5697d2017-10-04 14:31:33 -04002710Clip loops over itself covering its center twice. When clip Path_Fill_Type
Cary Clark8032b982017-07-28 11:04:54 -04002711is set to SkPath::kWinding_FillType, the overlap is included. Set to
2712SkPath::kEvenOdd_FillType, the overlap is excluded and forms a hole.
2713##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002714void draw(SkCanvas* canvas) {
2715 SkPaint paint;
2716 paint.setAntiAlias(true);
2717 SkPath path;
2718 SkPoint poly[] = {{20, 20}, { 80, 20}, { 80, 80}, {40, 80},
2719 {40, 40}, {100, 40}, {100, 100}, {20, 100}};
2720 path.addPoly(poly, SK_ARRAY_COUNT(poly), true);
2721 path.setFillType(SkPath::kWinding_FillType);
2722 canvas->save();
2723 canvas->clipPath(path, SkClipOp::kIntersect);
2724 canvas->drawCircle(50, 50, 45, paint);
2725 canvas->restore();
2726 canvas->translate(100, 100);
2727 path.setFillType(SkPath::kEvenOdd_FillType);
2728 canvas->clipPath(path, SkClipOp::kIntersect);
2729 canvas->drawCircle(50, 50, 45, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002730}
2731##
2732
Cary Clark2ade9972017-11-02 17:49:34 -04002733#SeeAlso clipRect clipRRect clipRegion
Cary Clark8032b982017-07-28 11:04:54 -04002734
2735##
2736
2737# ------------------------------------------------------------------------------
2738
2739#Method void setAllowSimplifyClip(bool allow)
2740
2741#Experimental
2742Only used for testing.
2743##
2744
Cary Clarkce101242017-09-01 15:51:02 -04002745Set to simplify clip stack using PathOps.
Cary Clark8032b982017-07-28 11:04:54 -04002746
2747##
2748
2749# ------------------------------------------------------------------------------
2750
2751#Method void clipRegion(const SkRegion& deviceRgn, SkClipOp op = SkClipOp::kIntersect)
2752
2753Replace Clip with the intersection or difference of Clip and Region deviceRgn.
Cary Clarkce101242017-09-01 15:51:02 -04002754Resulting Clip is Aliased; pixels are fully contained by the clip.
Cary Clark8032b982017-07-28 11:04:54 -04002755deviceRgn is unaffected by Matrix.
2756
Cary Clarkbad5ad72017-08-03 17:14:08 -04002757#Param deviceRgn Region to combine with Clip ##
2758#Param op Clip_Op to apply to Clip ##
Cary Clark8032b982017-07-28 11:04:54 -04002759
2760#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04002761#Description
Cary Clarkce101242017-09-01 15:51:02 -04002762 region is unaffected by canvas rotation; iRect is affected by canvas rotation.
2763 Both clips are Aliased; this is not noticeable on Region clip because it
Cary Clarkbad5ad72017-08-03 17:14:08 -04002764 aligns to pixel boundaries.
2765##
2766void draw(SkCanvas* canvas) {
2767 SkPaint paint;
2768 paint.setAntiAlias(true);
2769 SkIRect iRect = {30, 40, 120, 130 };
2770 SkRegion region(iRect);
2771 canvas->rotate(10);
2772 canvas->save();
2773 canvas->clipRegion(region, SkClipOp::kIntersect);
2774 canvas->drawCircle(50, 50, 45, paint);
2775 canvas->restore();
2776 canvas->translate(100, 100);
2777 canvas->clipRect(SkRect::Make(iRect), SkClipOp::kIntersect);
2778 canvas->drawCircle(50, 50, 45, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002779}
2780##
2781
Cary Clark2ade9972017-11-02 17:49:34 -04002782#SeeAlso clipRect clipRRect clipPath
Cary Clark8032b982017-07-28 11:04:54 -04002783
2784##
2785
2786#Method bool quickReject(const SkRect& rect) const
2787
2788Return true if Rect rect, transformed by Matrix, can be quickly determined to be
2789outside of Clip. May return false even though rect is outside of Clip.
2790
2791Use to check if an area to be drawn is clipped out, to skip subsequent draw calls.
2792
Cary Clarkbad5ad72017-08-03 17:14:08 -04002793#Param rect Rect to compare with Clip ##
Cary Clark8032b982017-07-28 11:04:54 -04002794
Cary Clarkbad5ad72017-08-03 17:14:08 -04002795#Return true if rect, transformed by Matrix, does not intersect Clip ##
Cary Clark8032b982017-07-28 11:04:54 -04002796
2797#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04002798void draw(SkCanvas* canvas) {
2799 SkRect testRect = {30, 30, 120, 129 };
2800 SkRect clipRect = {30, 130, 120, 230 };
2801 canvas->save();
2802 canvas->clipRect(clipRect);
2803 SkDebugf("quickReject %s\n", canvas->quickReject(testRect) ? "true" : "false");
2804 canvas->restore();
2805 canvas->rotate(10);
2806 canvas->clipRect(clipRect);
2807 SkDebugf("quickReject %s\n", canvas->quickReject(testRect) ? "true" : "false");
Cary Clark8032b982017-07-28 11:04:54 -04002808}
2809 #StdOut
Cary Clarkbad5ad72017-08-03 17:14:08 -04002810 quickReject true
Cary Clark8032b982017-07-28 11:04:54 -04002811 quickReject false
2812 ##
2813##
2814
Cary Clark2ade9972017-11-02 17:49:34 -04002815#SeeAlso getLocalClipBounds getTotalMatrix SkBitmap::drawsNothing
Cary Clark8032b982017-07-28 11:04:54 -04002816
2817##
2818
2819#Method bool quickReject(const SkPath& path) const
2820
2821Return true if path, transformed by Matrix, can be quickly determined to be
2822outside of Clip. May return false even though path is outside of Clip.
2823
2824Use to check if an area to be drawn is clipped out, to skip subsequent draw calls.
2825
Cary Clarkbad5ad72017-08-03 17:14:08 -04002826#Param path Path to compare with Clip ##
Cary Clark8032b982017-07-28 11:04:54 -04002827
Cary Clarkbad5ad72017-08-03 17:14:08 -04002828#Return true if path, transformed by Matrix, does not intersect Clip ##
Cary Clark8032b982017-07-28 11:04:54 -04002829
2830#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04002831void draw(SkCanvas* canvas) {
2832 SkPoint testPoints[] = {{30, 30}, {120, 30}, {120, 129} };
2833 SkPoint clipPoints[] = {{30, 130}, {120, 130}, {120, 230} };
2834 SkPath testPath, clipPath;
2835 testPath.addPoly(testPoints, SK_ARRAY_COUNT(testPoints), true);
2836 clipPath.addPoly(clipPoints, SK_ARRAY_COUNT(clipPoints), true);
2837 canvas->save();
2838 canvas->clipPath(clipPath);
2839 SkDebugf("quickReject %s\n", canvas->quickReject(testPath) ? "true" : "false");
2840 canvas->restore();
2841 canvas->rotate(10);
2842 canvas->clipPath(clipPath);
2843 SkDebugf("quickReject %s\n", canvas->quickReject(testPath) ? "true" : "false");
Cary Clark8032b982017-07-28 11:04:54 -04002844 #StdOut
Cary Clarkbad5ad72017-08-03 17:14:08 -04002845 quickReject true
Cary Clark8032b982017-07-28 11:04:54 -04002846 quickReject false
2847 ##
2848}
2849##
2850
Cary Clark2ade9972017-11-02 17:49:34 -04002851#SeeAlso getLocalClipBounds getTotalMatrix SkBitmap::drawsNothing
Cary Clark8032b982017-07-28 11:04:54 -04002852
2853##
2854
2855#Method SkRect getLocalClipBounds() const
2856
2857Return bounds of Clip, transformed by inverse of Matrix. If Clip is empty,
2858return SkRect::MakeEmpty, where all Rect sides equal zero.
2859
2860Rect returned is outset by one to account for partial pixel coverage if Clip
Cary Clarkce101242017-09-01 15:51:02 -04002861is Anti-aliased.
Cary Clark8032b982017-07-28 11:04:54 -04002862
Cary Clarkbad5ad72017-08-03 17:14:08 -04002863#Return bounds of Clip in local coordinates ##
Cary Clark8032b982017-07-28 11:04:54 -04002864
2865#Example
2866 #Description
2867 Initial bounds is device bounds outset by 1 on all sides.
2868 Clipped bounds is clipPath bounds outset by 1 on all sides.
2869 Scaling the canvas by two in x and y scales the local bounds by 1/2 in x and y.
2870 ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002871 SkCanvas local(256, 256);
2872 canvas = &local;
2873 SkRect bounds = canvas->getLocalClipBounds();
2874 SkDebugf("left:%g top:%g right:%g bottom:%g\n",
2875 bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom);
2876 SkPoint clipPoints[] = {{30, 130}, {120, 130}, {120, 230} };
2877 SkPath clipPath;
2878 clipPath.addPoly(clipPoints, SK_ARRAY_COUNT(clipPoints), true);
2879 canvas->clipPath(clipPath);
2880 bounds = canvas->getLocalClipBounds();
2881 SkDebugf("left:%g top:%g right:%g bottom:%g\n",
2882 bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom);
2883 canvas->scale(2, 2);
2884 bounds = canvas->getLocalClipBounds();
2885 SkDebugf("left:%g top:%g right:%g bottom:%g\n",
2886 bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom);
2887 #StdOut
2888 left:-1 top:-1 right:257 bottom:257
2889 left:29 top:129 right:121 bottom:231
2890 left:14.5 top:64.5 right:60.5 bottom:115.5
2891 ##
Cary Clark8032b982017-07-28 11:04:54 -04002892##
2893
2894# local canvas in example works around bug in fiddle ##
2895#Bug 6524 ##
Cary Clark2ade9972017-11-02 17:49:34 -04002896#SeeAlso getDeviceClipBounds getBaseLayerSize quickReject
Cary Clark8032b982017-07-28 11:04:54 -04002897
2898##
2899
2900#Method bool getLocalClipBounds(SkRect* bounds) const
2901
2902Return bounds of Clip, transformed by inverse of Matrix. If Clip is empty,
2903return false, and set bounds to SkRect::MakeEmpty, where all Rect sides equal zero.
2904
2905bounds is outset by one to account for partial pixel coverage if Clip
Cary Clarkce101242017-09-01 15:51:02 -04002906is Anti-aliased.
Cary Clark8032b982017-07-28 11:04:54 -04002907
Cary Clarkbad5ad72017-08-03 17:14:08 -04002908#Param bounds Rect of Clip in local coordinates ##
Cary Clark8032b982017-07-28 11:04:54 -04002909
Cary Clarkbad5ad72017-08-03 17:14:08 -04002910#Return true if Clip bounds is not empty ##
Cary Clark8032b982017-07-28 11:04:54 -04002911
2912#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04002913 void draw(SkCanvas* canvas) {
2914 SkCanvas local(256, 256);
2915 canvas = &local;
2916 SkRect bounds;
2917 SkDebugf("local bounds empty = %s\n", canvas->getLocalClipBounds(&bounds)
2918 ? "false" : "true");
2919 SkPath path;
2920 canvas->clipPath(path);
2921 SkDebugf("local bounds empty = %s\n", canvas->getLocalClipBounds(&bounds)
2922 ? "false" : "true");
Cary Clark8032b982017-07-28 11:04:54 -04002923 }
2924 #StdOut
Cary Clarkbad5ad72017-08-03 17:14:08 -04002925 local bounds empty = false
Cary Clark8032b982017-07-28 11:04:54 -04002926 local bounds empty = true
2927 ##
2928##
2929
2930# local canvas in example works around bug in fiddle ##
2931#Bug 6524 ##
Cary Clark2ade9972017-11-02 17:49:34 -04002932#SeeAlso getDeviceClipBounds getBaseLayerSize quickReject
Cary Clark8032b982017-07-28 11:04:54 -04002933
2934##
2935
2936#Method SkIRect getDeviceClipBounds() const
2937
2938Return IRect bounds of Clip, unaffected by Matrix. If Clip is empty,
2939return SkRect::MakeEmpty, where all Rect sides equal zero.
2940
2941Unlike getLocalClipBounds, returned IRect is not outset.
2942
Cary Clarkbad5ad72017-08-03 17:14:08 -04002943#Return bounds of Clip in Device coordinates ##
Cary Clark8032b982017-07-28 11:04:54 -04002944
2945#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04002946void draw(SkCanvas* canvas) {
2947 #Description
Cary Clark8032b982017-07-28 11:04:54 -04002948 Initial bounds is device bounds, not outset.
2949 Clipped bounds is clipPath bounds, not outset.
2950 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 -04002951 ##
2952 SkCanvas device(256, 256);
2953 canvas = &device;
2954 SkIRect bounds = canvas->getDeviceClipBounds();
2955 SkDebugf("left:%d top:%d right:%d bottom:%d\n",
2956 bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom);
2957 SkPoint clipPoints[] = {{30, 130}, {120, 130}, {120, 230} };
2958 SkPath clipPath;
2959 clipPath.addPoly(clipPoints, SK_ARRAY_COUNT(clipPoints), true);
2960 canvas->save();
2961 canvas->clipPath(clipPath);
2962 bounds = canvas->getDeviceClipBounds();
2963 SkDebugf("left:%d top:%d right:%d bottom:%d\n",
2964 bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom);
2965 canvas->restore();
2966 canvas->scale(1.f/2, 1.f/2);
2967 canvas->clipPath(clipPath);
2968 bounds = canvas->getDeviceClipBounds();
2969 SkDebugf("left:%d top:%d right:%d bottom:%d\n",
2970 bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom);
Cary Clark8032b982017-07-28 11:04:54 -04002971 #StdOut
Cary Clarkbad5ad72017-08-03 17:14:08 -04002972 left:0 top:0 right:256 bottom:256
2973 left:30 top:130 right:120 bottom:230
Cary Clark8032b982017-07-28 11:04:54 -04002974 left:15 top:65 right:60 bottom:115
2975 ##
2976}
2977##
2978
2979#ToDo some confusion on why with an identity Matrix local and device are different ##
Cary Clark2ade9972017-11-02 17:49:34 -04002980#SeeAlso getLocalClipBounds getBaseLayerSize quickReject
Cary Clark8032b982017-07-28 11:04:54 -04002981
2982# device canvas in example works around bug in fiddle ##
2983#Bug 6524 ##
2984
2985##
2986
2987#Method bool getDeviceClipBounds(SkIRect* bounds) const
2988
2989Return IRect bounds of Clip, unaffected by Matrix. If Clip is empty,
2990return false, and set bounds to SkRect::MakeEmpty, where all Rect sides equal zero.
2991
2992Unlike getLocalClipBounds, bounds is not outset.
2993
Cary Clarkbad5ad72017-08-03 17:14:08 -04002994#Param bounds Rect of Clip in device coordinates ##
Cary Clark8032b982017-07-28 11:04:54 -04002995
Cary Clarkbad5ad72017-08-03 17:14:08 -04002996#Return true if Clip bounds is not empty ##
Cary Clark8032b982017-07-28 11:04:54 -04002997
2998#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04002999 void draw(SkCanvas* canvas) {
3000 SkIRect bounds;
3001 SkDebugf("device bounds empty = %s\n", canvas->getDeviceClipBounds(&bounds)
3002 ? "false" : "true");
3003 SkPath path;
3004 canvas->clipPath(path);
3005 SkDebugf("device bounds empty = %s\n", canvas->getDeviceClipBounds(&bounds)
3006 ? "false" : "true");
Cary Clark8032b982017-07-28 11:04:54 -04003007 }
3008 #StdOut
Cary Clarkbad5ad72017-08-03 17:14:08 -04003009 device bounds empty = false
Cary Clark8032b982017-07-28 11:04:54 -04003010 device bounds empty = true
3011 ##
3012##
3013
Cary Clark2ade9972017-11-02 17:49:34 -04003014#SeeAlso getLocalClipBounds getBaseLayerSize quickReject
Cary Clark8032b982017-07-28 11:04:54 -04003015
3016##
3017
3018#Topic Clip ##
3019
3020# ------------------------------------------------------------------------------
3021
3022#Method void drawColor(SkColor color, SkBlendMode mode = SkBlendMode::kSrcOver)
3023
3024Fill Clip with Color color.
3025mode determines how Color_ARGB is combined with destination.
3026
Cary Clarkbad5ad72017-08-03 17:14:08 -04003027#Param color Unpremultiplied Color_ARGB ##
3028#Param mode SkBlendMode used to combine source color and destination ##
Cary Clark8032b982017-07-28 11:04:54 -04003029
3030#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003031 canvas->drawColor(SK_ColorRED);
3032 canvas->clipRect(SkRect::MakeWH(150, 150));
3033 canvas->drawColor(SkColorSetARGB(0x80, 0x00, 0xFF, 0x00), SkBlendMode::kPlus);
3034 canvas->clipRect(SkRect::MakeWH(75, 75));
3035 canvas->drawColor(SkColorSetARGB(0x80, 0x00, 0x00, 0xFF), SkBlendMode::kPlus);
Cary Clark8032b982017-07-28 11:04:54 -04003036##
3037
Cary Clark2ade9972017-11-02 17:49:34 -04003038#SeeAlso clear SkBitmap::erase drawPaint
Cary Clark8032b982017-07-28 11:04:54 -04003039
3040##
3041
3042# ------------------------------------------------------------------------------
3043
3044#Method void clear(SkColor color)
3045
3046Fill Clip with Color color using SkBlendMode::kSrc.
3047This has the effect of replacing all pixels contained by Clip with color.
3048
Cary Clarkbad5ad72017-08-03 17:14:08 -04003049#Param color Unpremultiplied Color_ARGB ##
Cary Clark8032b982017-07-28 11:04:54 -04003050
3051#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003052void draw(SkCanvas* canvas) {
3053 canvas->save();
3054 canvas->clipRect(SkRect::MakeWH(256, 128));
3055 canvas->clear(SkColorSetARGB(0x80, 0xFF, 0x00, 0x00));
3056 canvas->restore();
3057 canvas->save();
3058 canvas->clipRect(SkRect::MakeWH(150, 192));
3059 canvas->clear(SkColorSetARGB(0x80, 0x00, 0xFF, 0x00));
3060 canvas->restore();
3061 canvas->clipRect(SkRect::MakeWH(75, 256));
3062 canvas->clear(SkColorSetARGB(0x80, 0x00, 0x00, 0xFF));
Cary Clark8032b982017-07-28 11:04:54 -04003063}
3064##
3065
Cary Clark2ade9972017-11-02 17:49:34 -04003066#SeeAlso drawColor SkBitmap::erase drawPaint
Cary Clark8032b982017-07-28 11:04:54 -04003067
3068##
3069
3070# ------------------------------------------------------------------------------
3071
3072#Method void discard()
3073
3074Make Canvas contents undefined. Subsequent calls that read Canvas pixels,
3075such as drawing with SkBlendMode, return undefined results. discard() does
3076not change Clip or Matrix.
3077
3078discard() may do nothing, depending on the implementation of Surface or Device
3079that created Canvas.
3080
3081discard() allows optimized performance on subsequent draws by removing
3082cached data associated with Surface or Device.
3083It is not necessary to call discard() once done with Canvas;
3084any cached data is deleted when owning Surface or Device is deleted.
3085
3086#ToDo example? not sure how to make this meaningful w/o more implementation detail ##
Cary Clark2ade9972017-11-02 17:49:34 -04003087#SeeAlso flush() SkSurface::prepareForExternalIO GrContext::abandonContext
Cary Clark8032b982017-07-28 11:04:54 -04003088
3089#NoExample
3090##
3091
3092##
3093
3094# ------------------------------------------------------------------------------
3095
3096#Method void drawPaint(const SkPaint& paint)
3097
Cary Clarkbad5ad72017-08-03 17:14:08 -04003098Fill Clip with Paint paint. Paint components Rasterizer, Mask_Filter, Shader,
3099Color_Filter, Image_Filter, and Blend_Mode affect drawing;
3100Path_Effect in paint is ignored.
Cary Clark8032b982017-07-28 11:04:54 -04003101
3102# can Path_Effect in paint ever alter drawPaint?
3103
Cary Clarkbad5ad72017-08-03 17:14:08 -04003104#Param paint graphics state used to fill Canvas ##
Cary Clark8032b982017-07-28 11:04:54 -04003105
3106#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003107void draw(SkCanvas* canvas) {
3108 SkColor colors[] = { SK_ColorRED, SK_ColorGREEN, SK_ColorBLUE };
3109 SkScalar pos[] = { 0, SK_Scalar1/2, SK_Scalar1 };
3110 SkPaint paint;
3111 paint.setShader(SkGradientShader::MakeSweep(256, 256, colors, pos, SK_ARRAY_COUNT(colors)));
3112 canvas->drawPaint(paint);
Cary Clark8032b982017-07-28 11:04:54 -04003113}
3114##
3115
Cary Clark2ade9972017-11-02 17:49:34 -04003116#SeeAlso clear drawColor SkBitmap::erase
Cary Clark8032b982017-07-28 11:04:54 -04003117
3118##
3119
3120# ------------------------------------------------------------------------------
3121
3122#Enum PointMode
3123
3124#Code
3125 enum PointMode {
3126 kPoints_PointMode,
3127 kLines_PointMode,
Cary Clarkd0530ba2017-09-14 11:25:39 -04003128 kPolygon_PointMode,
Cary Clark8032b982017-07-28 11:04:54 -04003129 };
3130##
3131
3132Selects if an array of points are drawn as discrete points, as lines, or as
3133an open polygon.
3134
3135#Const kPoints_PointMode 0
3136 Draw each point separately.
3137##
3138
3139#Const kLines_PointMode 1
3140 Draw each pair of points as a line segment.
3141##
3142
3143#Const kPolygon_PointMode 2
3144 Draw the array of points as a open polygon.
3145##
3146
3147#Example
3148 #Description
3149 The upper left corner shows three squares when drawn as points.
3150 The upper right corner shows one line; when drawn as lines, two points are required per line.
3151 The lower right corner shows two lines; when draw as polygon, no miter is drawn at the corner.
3152 The lower left corner shows two lines with a miter when path contains polygon.
3153 ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003154void draw(SkCanvas* canvas) {
3155 SkPaint paint;
3156 paint.setStyle(SkPaint::kStroke_Style);
3157 paint.setStrokeWidth(10);
3158 SkPoint points[] = {{64, 32}, {96, 96}, {32, 96}};
3159 canvas->drawPoints(SkCanvas::kPoints_PointMode, 3, points, paint);
3160 canvas->translate(128, 0);
3161 canvas->drawPoints(SkCanvas::kLines_PointMode, 3, points, paint);
3162 canvas->translate(0, 128);
3163 canvas->drawPoints(SkCanvas::kPolygon_PointMode, 3, points, paint);
3164 SkPath path;
3165 path.addPoly(points, 3, false);
3166 canvas->translate(-128, 0);
3167 canvas->drawPath(path, paint);
Cary Clark8032b982017-07-28 11:04:54 -04003168}
3169##
3170
Cary Clark2ade9972017-11-02 17:49:34 -04003171#SeeAlso drawLine drawPoint drawPath
Cary Clark8032b982017-07-28 11:04:54 -04003172
3173##
3174
3175# ------------------------------------------------------------------------------
3176
3177#Method void drawPoints(PointMode mode, size_t count, const SkPoint pts[], const SkPaint& paint)
3178
3179Draw pts using Clip, Matrix and Paint paint.
Cary Clarkbad5ad72017-08-03 17:14:08 -04003180count is the number of points; if count is less than one, has no effect.
Cary Clark8032b982017-07-28 11:04:54 -04003181mode may be one of: kPoints_PointMode, kLines_PointMode, or kPolygon_PointMode.
3182
Cary Clarkbad5ad72017-08-03 17:14:08 -04003183If mode is kPoints_PointMode, the shape of point drawn depends on paint
3184Paint_Stroke_Cap. If paint is set to SkPaint::kRound_Cap, each point draws a
3185circle of diameter Paint_Stroke_Width. If paint is set to SkPaint::kSquare_Cap
3186or SkPaint::kButt_Cap, each point draws a square of width and height
3187Paint_Stroke_Width.
Cary Clark8032b982017-07-28 11:04:54 -04003188
3189If mode is kLines_PointMode, each pair of points draws a line segment.
3190One line is drawn for every two points; each point is used once. If count is odd,
3191the final point is ignored.
3192
3193If mode is kPolygon_PointMode, each adjacent pair of points draws a line segment.
3194count minus one lines are drawn; the first and last point are used once.
3195
3196Each line segment respects paint Paint_Stroke_Cap and Paint_Stroke_Width.
3197Paint_Style is ignored, as if were set to SkPaint::kStroke_Style.
3198
Cary Clarkbad5ad72017-08-03 17:14:08 -04003199Always draws each element one at a time; is not affected by
3200Paint_Stroke_Join, and unlike drawPath, does not create a mask from all points
3201and lines before drawing.
Cary Clark8032b982017-07-28 11:04:54 -04003202
Cary Clarka523d2d2017-08-30 08:58:10 -04003203#Param mode whether pts draws points or lines ##
3204#Param count number of points in the array ##
3205#Param pts array of points to draw ##
3206#Param paint stroke, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003207
3208#Example
3209#Height 200
3210 #Description
3211 #List
3212 # The first column draws points. ##
3213 # The second column draws points as lines. ##
3214 # The third column draws points as a polygon. ##
3215 # The fourth column draws points as a polygonal path. ##
3216 # The first row uses a round cap and round join. ##
3217 # The second row uses a square cap and a miter join. ##
3218 # The third row uses a butt cap and a bevel join. ##
3219 ##
3220 The transparent color makes multiple line draws visible;
3221 the path is drawn all at once.
3222 ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003223void draw(SkCanvas* canvas) {
3224 SkPaint paint;
3225 paint.setAntiAlias(true);
3226 paint.setStyle(SkPaint::kStroke_Style);
3227 paint.setStrokeWidth(10);
3228 paint.setColor(0x80349a45);
3229 const SkPoint points[] = {{32, 16}, {48, 48}, {16, 32}};
3230 const SkPaint::Join join[] = { SkPaint::kRound_Join,
3231 SkPaint::kMiter_Join,
3232 SkPaint::kBevel_Join };
3233 int joinIndex = 0;
3234 SkPath path;
3235 path.addPoly(points, 3, false);
3236 for (const auto cap : { SkPaint::kRound_Cap, SkPaint::kSquare_Cap, SkPaint::kButt_Cap } ) {
3237 paint.setStrokeCap(cap);
3238 paint.setStrokeJoin(join[joinIndex++]);
3239 for (const auto mode : { SkCanvas::kPoints_PointMode,
3240 SkCanvas::kLines_PointMode,
3241 SkCanvas::kPolygon_PointMode } ) {
3242 canvas->drawPoints(mode, 3, points, paint);
3243 canvas->translate(64, 0);
3244 }
3245 canvas->drawPath(path, paint);
3246 canvas->translate(-192, 64);
3247 }
Cary Clark8032b982017-07-28 11:04:54 -04003248}
3249##
3250
Cary Clark2ade9972017-11-02 17:49:34 -04003251#SeeAlso drawLine drawPoint drawPath
Cary Clark8032b982017-07-28 11:04:54 -04003252
3253##
3254
3255# ------------------------------------------------------------------------------
3256
3257#Method void drawPoint(SkScalar x, SkScalar y, const SkPaint& paint)
3258
3259Draw point at (x, y) using Clip, Matrix and Paint paint.
3260
3261The shape of point drawn depends on paint Paint_Stroke_Cap.
Cary Clarkbad5ad72017-08-03 17:14:08 -04003262If paint is set to SkPaint::kRound_Cap, draw a circle of diameter
3263Paint_Stroke_Width. If paint is set to SkPaint::kSquare_Cap or SkPaint::kButt_Cap,
Cary Clark8032b982017-07-28 11:04:54 -04003264draw a square of width and height Paint_Stroke_Width.
3265Paint_Style is ignored, as if were set to SkPaint::kStroke_Style.
3266
Cary Clarkbad5ad72017-08-03 17:14:08 -04003267#Param x left edge of circle or square ##
3268#Param y top edge of circle or square ##
3269#Param paint stroke, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003270
3271#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003272void draw(SkCanvas* canvas) {
3273 SkPaint paint;
3274 paint.setAntiAlias(true);
3275 paint.setColor(0x80349a45);
3276 paint.setStyle(SkPaint::kStroke_Style);
3277 paint.setStrokeWidth(100);
3278 paint.setStrokeCap(SkPaint::kRound_Cap);
3279 canvas->scale(1, 1.2f);
3280 canvas->drawPoint(64, 96, paint);
3281 canvas->scale(.6f, .8f);
3282 paint.setColor(SK_ColorWHITE);
3283 canvas->drawPoint(106, 120, paint);
Cary Clark8032b982017-07-28 11:04:54 -04003284}
3285##
3286
Cary Clark2ade9972017-11-02 17:49:34 -04003287#SeeAlso drawPoints drawCircle drawRect drawLine drawPath
Cary Clark8032b982017-07-28 11:04:54 -04003288
3289##
3290
Cary Clarkbad5ad72017-08-03 17:14:08 -04003291#Method void drawPoint(SkPoint p, const SkPaint& paint)
3292
3293Draw point p using Clip, Matrix and Paint paint.
3294
3295The shape of point drawn depends on paint Paint_Stroke_Cap.
3296If paint is set to SkPaint::kRound_Cap, draw a circle of diameter
3297Paint_Stroke_Width. If paint is set to SkPaint::kSquare_Cap or SkPaint::kButt_Cap,
3298draw a square of width and height Paint_Stroke_Width.
3299Paint_Style is ignored, as if were set to SkPaint::kStroke_Style.
3300
3301#Param p top-left edge of circle or square ##
3302#Param paint stroke, blend, color, and so on, used to draw ##
3303
3304#Example
3305void draw(SkCanvas* canvas) {
3306 SkPaint paint;
3307 paint.setAntiAlias(true);
3308 paint.setColor(0x80349a45);
3309 paint.setStyle(SkPaint::kStroke_Style);
3310 paint.setStrokeWidth(100);
3311 paint.setStrokeCap(SkPaint::kSquare_Cap);
3312 canvas->scale(1, 1.2f);
3313 canvas->drawPoint({64, 96}, paint);
3314 canvas->scale(.6f, .8f);
3315 paint.setColor(SK_ColorWHITE);
3316 canvas->drawPoint(106, 120, paint);
3317}
3318##
3319
Cary Clark2ade9972017-11-02 17:49:34 -04003320#SeeAlso drawPoints drawCircle drawRect drawLine drawPath
Cary Clarkbad5ad72017-08-03 17:14:08 -04003321
3322##
3323
Cary Clark8032b982017-07-28 11:04:54 -04003324# ------------------------------------------------------------------------------
3325
3326#Method void drawLine(SkScalar x0, SkScalar y0, SkScalar x1, SkScalar y1, const SkPaint& paint)
3327
Cary Clarkbad5ad72017-08-03 17:14:08 -04003328Draws line segment from (x0, y0) to (x1, y1) using Clip, Matrix, and Paint paint.
3329In paint: Paint_Stroke_Width describes the line thickness;
3330Paint_Stroke_Cap draws the end rounded or square;
Cary Clark8032b982017-07-28 11:04:54 -04003331Paint_Style is ignored, as if were set to SkPaint::kStroke_Style.
3332
Cary Clarkbad5ad72017-08-03 17:14:08 -04003333#Param x0 start of line segment on x-axis ##
3334#Param y0 start of line segment on y-axis ##
3335#Param x1 end of line segment on x-axis ##
3336#Param y1 end of line segment on y-axis ##
3337#Param paint stroke, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003338
3339#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003340 SkPaint paint;
3341 paint.setAntiAlias(true);
3342 paint.setColor(0xFF9a67be);
3343 paint.setStrokeWidth(20);
3344 canvas->skew(1, 0);
3345 canvas->drawLine(32, 96, 32, 160, paint);
3346 canvas->skew(-2, 0);
3347 canvas->drawLine(288, 96, 288, 160, paint);
3348##
3349
Cary Clark2ade9972017-11-02 17:49:34 -04003350#SeeAlso drawPoint drawCircle drawRect drawPath
Cary Clarkbad5ad72017-08-03 17:14:08 -04003351
3352##
3353
3354#Method void drawLine(SkPoint p0, SkPoint p1, const SkPaint& paint)
3355
3356Draws line segment from p0 to p1 using Clip, Matrix, and Paint paint.
3357In paint: Paint_Stroke_Width describes the line thickness;
3358Paint_Stroke_Cap draws the end rounded or square;
3359Paint_Style is ignored, as if were set to SkPaint::kStroke_Style.
3360
3361#Param p0 start of line segment ##
3362#Param p1 end of line segment ##
3363#Param paint stroke, blend, color, and so on, used to draw ##
3364
3365#Example
3366 SkPaint paint;
3367 paint.setAntiAlias(true);
3368 paint.setColor(0xFF9a67be);
3369 paint.setStrokeWidth(20);
3370 canvas->skew(1, 0);
3371 canvas->drawLine({32, 96}, {32, 160}, paint);
3372 canvas->skew(-2, 0);
3373 canvas->drawLine({288, 96}, {288, 160}, paint);
Cary Clark8032b982017-07-28 11:04:54 -04003374##
3375
Cary Clark2ade9972017-11-02 17:49:34 -04003376#SeeAlso drawPoint drawCircle drawRect drawPath
Cary Clark8032b982017-07-28 11:04:54 -04003377
3378##
3379
3380# ------------------------------------------------------------------------------
3381
3382#Method void drawRect(const SkRect& rect, const SkPaint& paint)
3383
3384Draw Rect rect using Clip, Matrix, and Paint paint.
3385In paint: Paint_Style determines if rectangle is stroked or filled;
3386if stroked, Paint_Stroke_Width describes the line thickness, and
3387Paint_Stroke_Join draws the corners rounded or square.
3388
Cary Clarkbc5697d2017-10-04 14:31:33 -04003389#Param rect rectangle to draw ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003390#Param paint stroke or fill, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003391
3392#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003393void draw(SkCanvas* canvas) {
3394 SkPoint rectPts[] = { {64, 48}, {192, 160} };
3395 SkPaint paint;
3396 paint.setAntiAlias(true);
3397 paint.setStyle(SkPaint::kStroke_Style);
3398 paint.setStrokeWidth(20);
3399 paint.setStrokeJoin(SkPaint::kRound_Join);
3400 SkMatrix rotator;
3401 rotator.setRotate(30, 128, 128);
3402 for (auto color : { SK_ColorRED, SK_ColorBLUE, SK_ColorYELLOW, SK_ColorMAGENTA } ) {
3403 paint.setColor(color);
3404 SkRect rect;
3405 rect.set(rectPts[0], rectPts[1]);
3406 canvas->drawRect(rect, paint);
3407 rotator.mapPoints(rectPts, 2);
3408 }
Cary Clark8032b982017-07-28 11:04:54 -04003409}
3410##
3411
Cary Clark2ade9972017-11-02 17:49:34 -04003412#SeeAlso drawIRect drawRRect drawRoundRect drawRegion drawPath drawLine
Cary Clark8032b982017-07-28 11:04:54 -04003413
3414##
3415
3416# ------------------------------------------------------------------------------
3417
3418#Method void drawIRect(const SkIRect& rect, const SkPaint& paint)
3419
3420Draw IRect rect using Clip, Matrix, and Paint paint.
3421In paint: Paint_Style determines if rectangle is stroked or filled;
3422if stroked, Paint_Stroke_Width describes the line thickness, and
3423Paint_Stroke_Join draws the corners rounded or square.
3424
Cary Clarkbc5697d2017-10-04 14:31:33 -04003425#Param rect rectangle to draw ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003426#Param paint stroke or fill, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003427
3428#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003429 SkIRect rect = { 64, 48, 192, 160 };
3430 SkPaint paint;
3431 paint.setAntiAlias(true);
3432 paint.setStyle(SkPaint::kStroke_Style);
3433 paint.setStrokeWidth(20);
3434 paint.setStrokeJoin(SkPaint::kRound_Join);
3435 for (auto color : { SK_ColorRED, SK_ColorBLUE, SK_ColorYELLOW, SK_ColorMAGENTA } ) {
3436 paint.setColor(color);
3437 canvas->drawIRect(rect, paint);
3438 canvas->rotate(30, 128, 128);
3439 }
Cary Clark8032b982017-07-28 11:04:54 -04003440##
3441
Cary Clark2ade9972017-11-02 17:49:34 -04003442#SeeAlso drawRect drawRRect drawRoundRect drawRegion drawPath drawLine
Cary Clark8032b982017-07-28 11:04:54 -04003443
3444##
3445
3446# ------------------------------------------------------------------------------
3447
3448#Method void drawRegion(const SkRegion& region, const SkPaint& paint)
3449
3450Draw Region region using Clip, Matrix, and Paint paint.
3451In paint: Paint_Style determines if rectangle is stroked or filled;
3452if stroked, Paint_Stroke_Width describes the line thickness, and
3453Paint_Stroke_Join draws the corners rounded or square.
3454
Cary Clarkbc5697d2017-10-04 14:31:33 -04003455#Param region region to draw ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003456#Param paint Paint stroke or fill, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003457
3458#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003459void draw(SkCanvas* canvas) {
3460 SkRegion region;
3461 region.op( 10, 10, 50, 50, SkRegion::kUnion_Op);
3462 region.op( 10, 50, 90, 90, SkRegion::kUnion_Op);
3463 SkPaint paint;
3464 paint.setAntiAlias(true);
3465 paint.setStyle(SkPaint::kStroke_Style);
3466 paint.setStrokeWidth(20);
3467 paint.setStrokeJoin(SkPaint::kRound_Join);
3468 canvas->drawRegion(region, paint);
Cary Clark8032b982017-07-28 11:04:54 -04003469}
3470##
3471
Cary Clark2ade9972017-11-02 17:49:34 -04003472#SeeAlso drawRect drawIRect drawPath
Cary Clark8032b982017-07-28 11:04:54 -04003473
3474##
3475
3476# ------------------------------------------------------------------------------
3477
3478#Method void drawOval(const SkRect& oval, const SkPaint& paint)
3479
3480Draw Oval oval using Clip, Matrix, and Paint.
3481In paint: Paint_Style determines if Oval is stroked or filled;
3482if stroked, Paint_Stroke_Width describes the line thickness.
3483
Cary Clarkbad5ad72017-08-03 17:14:08 -04003484#Param oval Rect bounds of Oval ##
3485#Param paint Paint stroke or fill, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003486
3487#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003488void draw(SkCanvas* canvas) {
3489 canvas->clear(0xFF3f5f9f);
3490 SkColor kColor1 = SkColorSetARGB(0xff, 0xff, 0x7f, 0);
3491 SkColor g1Colors[] = { kColor1, SkColorSetA(kColor1, 0x20) };
3492 SkPoint g1Points[] = { { 0, 0 }, { 0, 100 } };
3493 SkScalar pos[] = { 0.2f, 1.0f };
3494 SkRect bounds = SkRect::MakeWH(80, 70);
3495 SkPaint paint;
3496 paint.setAntiAlias(true);
3497 paint.setShader(SkGradientShader::MakeLinear(g1Points, g1Colors, pos, SK_ARRAY_COUNT(g1Colors),
3498 SkShader::kClamp_TileMode));
3499 canvas->drawOval(bounds , paint);
Cary Clark8032b982017-07-28 11:04:54 -04003500}
3501##
3502
Cary Clark2ade9972017-11-02 17:49:34 -04003503#SeeAlso drawCircle drawPoint drawPath drawRRect drawRoundRect
Cary Clark8032b982017-07-28 11:04:54 -04003504
3505##
3506
3507# ------------------------------------------------------------------------------
3508
3509#Method void drawRRect(const SkRRect& rrect, const SkPaint& paint)
3510
3511Draw Round_Rect rrect using Clip, Matrix, and Paint paint.
3512In paint: Paint_Style determines if rrect is stroked or filled;
3513if stroked, Paint_Stroke_Width describes the line thickness.
3514
Cary Clarkbad5ad72017-08-03 17:14:08 -04003515rrect may represent a rectangle, circle, oval, uniformly rounded rectangle, or
3516may have any combination of positive non-square radii for the four corners.
Cary Clark8032b982017-07-28 11:04:54 -04003517
Cary Clarkbad5ad72017-08-03 17:14:08 -04003518#Param rrect Round_Rect with up to eight corner radii to draw ##
3519#Param paint Paint stroke or fill, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003520
3521#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003522void draw(SkCanvas* canvas) {
3523 SkPaint paint;
3524 paint.setAntiAlias(true);
3525 SkRect outer = {30, 40, 210, 220};
3526 SkRect radii = {30, 50, 70, 90 };
3527 SkRRect rRect;
3528 rRect.setNinePatch(outer, radii.fLeft, radii.fTop, radii.fRight, radii.fBottom);
3529 canvas->drawRRect(rRect, paint);
3530 paint.setColor(SK_ColorWHITE);
3531 canvas->drawLine(outer.fLeft + radii.fLeft, outer.fTop,
3532 outer.fLeft + radii.fLeft, outer.fBottom, paint);
3533 canvas->drawLine(outer.fRight - radii.fRight, outer.fTop,
3534 outer.fRight - radii.fRight, outer.fBottom, paint);
3535 canvas->drawLine(outer.fLeft, outer.fTop + radii.fTop,
3536 outer.fRight, outer.fTop + radii.fTop, paint);
3537 canvas->drawLine(outer.fLeft, outer.fBottom - radii.fBottom,
3538 outer.fRight, outer.fBottom - radii.fBottom, paint);
3539}
Cary Clark8032b982017-07-28 11:04:54 -04003540##
3541
Cary Clark2ade9972017-11-02 17:49:34 -04003542#SeeAlso drawRect drawRoundRect drawDRRect drawCircle drawOval drawPath
Cary Clark8032b982017-07-28 11:04:54 -04003543
3544##
3545
3546# ------------------------------------------------------------------------------
3547
3548#Method void drawDRRect(const SkRRect& outer, const SkRRect& inner, const SkPaint& paint)
3549
3550Draw Round_Rect outer and inner
3551using Clip, Matrix, and Paint paint.
3552outer must contain inner or the drawing is undefined.
Cary Clarkce101242017-09-01 15:51:02 -04003553In paint: Paint_Style determines if Round_Rect is stroked or filled;
Cary Clark8032b982017-07-28 11:04:54 -04003554if stroked, Paint_Stroke_Width describes the line thickness.
Cary Clarkbad5ad72017-08-03 17:14:08 -04003555If stroked and Round_Rect corner has zero length radii, Paint_Stroke_Join can
3556draw corners rounded or square.
Cary Clark8032b982017-07-28 11:04:54 -04003557
Cary Clarkbad5ad72017-08-03 17:14:08 -04003558GPU-backed platforms optimize drawing when both outer and inner are
Cary Clark8032b982017-07-28 11:04:54 -04003559concave and outer contains inner. These platforms may not be able to draw
3560Path built with identical data as fast.
3561
Cary Clarkbad5ad72017-08-03 17:14:08 -04003562#Param outer Round_Rect outer bounds to draw ##
3563#Param inner Round_Rect inner bounds to draw ##
3564#Param paint Paint stroke or fill, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003565
3566#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003567void draw(SkCanvas* canvas) {
3568 SkRRect outer = SkRRect::MakeRect({20, 40, 210, 200});
3569 SkRRect inner = SkRRect::MakeOval({60, 70, 170, 160});
3570 SkPaint paint;
3571 canvas->drawDRRect(outer, inner, paint);
Cary Clark8032b982017-07-28 11:04:54 -04003572}
3573##
3574
3575#Example
3576#Description
3577 Outer Rect has no corner radii, but stroke join is rounded.
3578 Inner Round_Rect has corner radii; outset stroke increases radii of corners.
3579 Stroke join does not affect inner Round_Rect since it has no sharp corners.
3580##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003581void draw(SkCanvas* canvas) {
3582 SkRRect outer = SkRRect::MakeRect({20, 40, 210, 200});
3583 SkRRect inner = SkRRect::MakeRectXY({60, 70, 170, 160}, 10, 10);
3584 SkPaint paint;
3585 paint.setAntiAlias(true);
3586 paint.setStyle(SkPaint::kStroke_Style);
3587 paint.setStrokeWidth(20);
3588 paint.setStrokeJoin(SkPaint::kRound_Join);
3589 canvas->drawDRRect(outer, inner, paint);
3590 paint.setStrokeWidth(1);
3591 paint.setColor(SK_ColorWHITE);
3592 canvas->drawDRRect(outer, inner, paint);
Cary Clark8032b982017-07-28 11:04:54 -04003593}
3594##
3595
Cary Clark2ade9972017-11-02 17:49:34 -04003596#SeeAlso drawRect drawRoundRect drawRRect drawCircle drawOval drawPath
Cary Clark8032b982017-07-28 11:04:54 -04003597
3598##
3599
3600# ------------------------------------------------------------------------------
3601
3602#Method void drawCircle(SkScalar cx, SkScalar cy, SkScalar radius, const SkPaint& paint)
3603
3604Draw Circle at (cx, cy) with radius using Clip, Matrix, and Paint paint.
3605If radius is zero or less, nothing is drawn.
3606In paint: Paint_Style determines if Circle is stroked or filled;
3607if stroked, Paint_Stroke_Width describes the line thickness.
3608
Cary Clarkbad5ad72017-08-03 17:14:08 -04003609#Param cx Circle center on the x-axis ##
3610#Param cy Circle center on the y-axis ##
3611#Param radius half the diameter of Circle ##
3612#Param paint Paint stroke or fill, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003613
3614#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003615 void draw(SkCanvas* canvas) {
3616 SkPaint paint;
3617 paint.setAntiAlias(true);
3618 canvas->drawCircle(128, 128, 90, paint);
3619 paint.setColor(SK_ColorWHITE);
3620 canvas->drawCircle(86, 86, 20, paint);
3621 canvas->drawCircle(160, 76, 20, paint);
3622 canvas->drawCircle(140, 150, 35, paint);
3623 }
3624##
3625
Cary Clark2ade9972017-11-02 17:49:34 -04003626#SeeAlso drawOval drawRRect drawRoundRect drawPath drawArc drawPoint drawLine
Cary Clarkbad5ad72017-08-03 17:14:08 -04003627
3628##
3629
3630#Method void drawCircle(SkPoint center, SkScalar radius, const SkPaint& paint)
3631
Cary Clarkce101242017-09-01 15:51:02 -04003632Draw Circle at center with radius using Clip, Matrix, and Paint paint.
Cary Clarkbad5ad72017-08-03 17:14:08 -04003633If radius is zero or less, nothing is drawn.
3634In paint: Paint_Style determines if Circle is stroked or filled;
3635if stroked, Paint_Stroke_Width describes the line thickness.
3636
3637#Param center Circle center ##
3638#Param radius half the diameter of Circle ##
3639#Param paint Paint stroke or fill, blend, color, and so on, used to draw ##
3640
3641#Example
3642 void draw(SkCanvas* canvas) {
3643 SkPaint paint;
3644 paint.setAntiAlias(true);
3645 canvas->drawCircle(128, 128, 90, paint);
3646 paint.setColor(SK_ColorWHITE);
3647 canvas->drawCircle({86, 86}, 20, paint);
3648 canvas->drawCircle({160, 76}, 20, paint);
3649 canvas->drawCircle({140, 150}, 35, paint);
3650 }
Cary Clark8032b982017-07-28 11:04:54 -04003651##
3652
Cary Clark2ade9972017-11-02 17:49:34 -04003653#SeeAlso drawOval drawRRect drawRoundRect drawPath drawArc drawPoint drawLine
Cary Clark8032b982017-07-28 11:04:54 -04003654
3655##
3656
3657# ------------------------------------------------------------------------------
3658
3659#Method void drawArc(const SkRect& oval, SkScalar startAngle, SkScalar sweepAngle,
3660 bool useCenter, const SkPaint& paint)
3661
3662Draw Arc using Clip, Matrix, and Paint paint.
Cary Clarkbad5ad72017-08-03 17:14:08 -04003663
Cary Clark8032b982017-07-28 11:04:54 -04003664Arc is part of Oval bounded by oval, sweeping from startAngle to startAngle plus
3665sweepAngle. startAngle and sweepAngle are in degrees.
Cary Clarkbad5ad72017-08-03 17:14:08 -04003666
Cary Clark8032b982017-07-28 11:04:54 -04003667startAngle of zero places start point at the right middle edge of oval.
3668A positive sweepAngle places Arc end point clockwise from start point;
3669a negative sweepAngle places Arc end point counterclockwise from start point.
3670sweepAngle may exceed 360 degrees, a full circle.
3671If useCenter is true, draw a wedge that includes lines from oval
3672center to Arc end points. If useCenter is false, draw Arc between end points.
3673
3674If Rect oval is empty or sweepAngle is zero, nothing is drawn.
3675
Cary Clarkbad5ad72017-08-03 17:14:08 -04003676#Param oval Rect bounds of Oval containing Arc to draw ##
3677#Param startAngle angle in degrees where Arc begins ##
3678#Param sweepAngle sweep angle in degrees; positive is clockwise ##
3679#Param useCenter if true, include the center of the oval ##
3680#Param paint Paint stroke or fill, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003681
3682#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003683 void draw(SkCanvas* canvas) {
3684 SkPaint paint;
3685 paint.setAntiAlias(true);
3686 SkRect oval = { 4, 4, 60, 60};
3687 for (auto useCenter : { false, true } ) {
3688 for (auto style : { SkPaint::kFill_Style, SkPaint::kStroke_Style } ) {
3689 paint.setStyle(style);
3690 for (auto degrees : { 45, 90, 180, 360} ) {
3691 canvas->drawArc(oval, 0, degrees , useCenter, paint);
3692 canvas->translate(64, 0);
3693 }
3694 canvas->translate(-256, 64);
3695 }
3696 }
Cary Clark8032b982017-07-28 11:04:54 -04003697 }
3698##
3699
3700#Example
3701#Height 64
Cary Clarkbad5ad72017-08-03 17:14:08 -04003702 void draw(SkCanvas* canvas) {
3703 SkPaint paint;
3704 paint.setAntiAlias(true);
3705 paint.setStyle(SkPaint::kStroke_Style);
3706 paint.setStrokeWidth(4);
3707 SkRect oval = { 4, 4, 60, 60};
3708 float intervals[] = { 5, 5 };
3709 paint.setPathEffect(SkDashPathEffect::Make(intervals, 2, 2.5f));
3710 for (auto degrees : { 270, 360, 540, 720 } ) {
3711 canvas->drawArc(oval, 0, degrees, false, paint);
3712 canvas->translate(64, 0);
3713 }
Cary Clark8032b982017-07-28 11:04:54 -04003714 }
3715##
3716
Cary Clark2ade9972017-11-02 17:49:34 -04003717#SeeAlso SkPath::arcTo drawCircle drawOval drawPath
Cary Clark8032b982017-07-28 11:04:54 -04003718
3719##
3720
3721# ------------------------------------------------------------------------------
3722
3723#Method void drawRoundRect(const SkRect& rect, SkScalar rx, SkScalar ry, const SkPaint& paint)
3724
Cary Clarkbad5ad72017-08-03 17:14:08 -04003725Draw Round_Rect bounded by Rect rect, with corner radii (rx, ry) using Clip,
3726Matrix, and Paint paint.
3727
Cary Clark8032b982017-07-28 11:04:54 -04003728In paint: Paint_Style determines if Round_Rect is stroked or filled;
3729if stroked, Paint_Stroke_Width describes the line thickness.
3730If rx or ry are less than zero, they are treated as if they are zero.
3731If rx plus ry exceeds rect width or rect height, radii are scaled down to fit.
Cary Clarkbad5ad72017-08-03 17:14:08 -04003732If rx and ry are zero, Round_Rect is drawn as Rect and if stroked is affected by
3733Paint_Stroke_Join.
Cary Clark8032b982017-07-28 11:04:54 -04003734
Cary Clarkbad5ad72017-08-03 17:14:08 -04003735#Param rect Rect bounds of Round_Rect to draw ##
Cary Clarkce101242017-09-01 15:51:02 -04003736#Param rx axis length in x of oval describing rounded corners ##
3737#Param ry axis length in y of oval describing rounded corners ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003738#Param paint stroke, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003739
3740#Example
3741#Description
3742 Top row has a zero radius a generates a rectangle.
3743 Second row radii sum to less than sides.
3744 Third row radii sum equals sides.
3745 Fourth row radii sum exceeds sides; radii are scaled to fit.
3746##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003747 void draw(SkCanvas* canvas) {
3748 SkVector radii[] = { {0, 20}, {10, 10}, {10, 20}, {10, 40} };
3749 SkPaint paint;
3750 paint.setStrokeWidth(15);
3751 paint.setStrokeJoin(SkPaint::kRound_Join);
3752 paint.setAntiAlias(true);
3753 for (auto style : { SkPaint::kStroke_Style, SkPaint::kFill_Style } ) {
3754 paint.setStyle(style );
3755 for (size_t i = 0; i < SK_ARRAY_COUNT(radii); ++i) {
3756 canvas->drawRoundRect({10, 10, 60, 40}, radii[i].fX, radii[i].fY, paint);
3757 canvas->translate(0, 60);
3758 }
3759 canvas->translate(80, -240);
3760 }
Cary Clark8032b982017-07-28 11:04:54 -04003761 }
3762##
3763
Cary Clark2ade9972017-11-02 17:49:34 -04003764#SeeAlso DrawRRect drawRect drawDRRect drawPath drawCircle drawOval drawPoint
Cary Clark8032b982017-07-28 11:04:54 -04003765
3766##
3767
3768# ------------------------------------------------------------------------------
3769
3770#Method void drawPath(const SkPath& path, const SkPaint& paint)
3771
3772Draw Path path using Clip, Matrix, and Paint paint.
3773Path contains an array of Path_Contour, each of which may be open or closed.
3774
3775In paint: Paint_Style determines if Round_Rect is stroked or filled:
Cary Clarkbad5ad72017-08-03 17:14:08 -04003776if filled, Path_Fill_Type determines whether Path_Contour describes inside or
3777outside of fill; if stroked, Paint_Stroke_Width describes the line thickness,
3778Paint_Stroke_Cap describes line ends, and Paint_Stroke_Join describes how
3779corners are drawn.
Cary Clark8032b982017-07-28 11:04:54 -04003780
Cary Clarkbad5ad72017-08-03 17:14:08 -04003781#Param path Path to draw ##
3782#Param paint stroke, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003783
3784#Example
3785#Description
3786 Top rows draw stroked path with combinations of joins and caps. The open contour
3787 is affected by caps; the closed contour is affected by joins.
3788 Bottom row draws fill the same for open and closed contour.
3789 First bottom column shows winding fills overlap.
3790 Second bottom column shows even odd fills exclude overlap.
3791 Third bottom column shows inverse winding fills area outside both contours.
3792##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003793void draw(SkCanvas* canvas) {
3794 SkPath path;
3795 path.moveTo(20, 20);
3796 path.quadTo(60, 20, 60, 60);
3797 path.close();
3798 path.moveTo(60, 20);
3799 path.quadTo(60, 60, 20, 60);
3800 SkPaint paint;
3801 paint.setStrokeWidth(10);
3802 paint.setAntiAlias(true);
3803 paint.setStyle(SkPaint::kStroke_Style);
3804 for (auto join: { SkPaint::kBevel_Join, SkPaint::kRound_Join, SkPaint::kMiter_Join } ) {
3805 paint.setStrokeJoin(join);
3806 for (auto cap: { SkPaint::kButt_Cap, SkPaint::kSquare_Cap, SkPaint::kRound_Cap } ) {
3807 paint.setStrokeCap(cap);
3808 canvas->drawPath(path, paint);
3809 canvas->translate(80, 0);
3810 }
3811 canvas->translate(-240, 60);
3812 }
3813 paint.setStyle(SkPaint::kFill_Style);
3814 for (auto fill : { SkPath::kWinding_FillType,
3815 SkPath::kEvenOdd_FillType,
3816 SkPath::kInverseWinding_FillType } ) {
3817 path.setFillType(fill);
3818 canvas->save();
3819 canvas->clipRect({0, 10, 80, 70});
3820 canvas->drawPath(path, paint);
3821 canvas->restore();
3822 canvas->translate(80, 0);
3823 }
Cary Clark8032b982017-07-28 11:04:54 -04003824}
3825##
3826
Cary Clark2ade9972017-11-02 17:49:34 -04003827#SeeAlso SkPath drawLine drawArc drawRect drawPoints
Cary Clark8032b982017-07-28 11:04:54 -04003828
3829##
3830
3831# ------------------------------------------------------------------------------
3832#Topic Draw_Image
3833
Cary Clarkbad5ad72017-08-03 17:14:08 -04003834drawImage, drawImageRect, and drawImageNine can be called with a bare pointer or
3835a smart pointer as a convenience. The pairs of calls are otherwise identical.
Cary Clark8032b982017-07-28 11:04:54 -04003836
Cary Clark73fa9722017-08-29 17:36:51 -04003837#Method void drawImage(const SkImage* image, SkScalar left, SkScalar top, const SkPaint* paint = nullptr)
Cary Clark8032b982017-07-28 11:04:54 -04003838
3839Draw Image image, with its top-left corner at (left, top),
3840using Clip, Matrix, and optional Paint paint.
3841
Cary Clarkbad5ad72017-08-03 17:14:08 -04003842If paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter, Blend_Mode,
3843and Draw_Looper. If image is kAlpha_8_SkColorType, apply Shader.
3844If paint contains Mask_Filter, generate mask from image bounds. If generated
3845mask extends beyond image bounds, replicate image edge colors, just as Shader
3846made from SkImage::makeShader with SkShader::kClamp_TileMode set replicates the
Cary Clarkbc5697d2017-10-04 14:31:33 -04003847image edge color when it samples outside of its bounds.
Cary Clark8032b982017-07-28 11:04:54 -04003848
Cary Clarkbad5ad72017-08-03 17:14:08 -04003849#Param image uncompressed rectangular map of pixels ##
3850#Param left left side of image ##
3851#Param top top side of image ##
3852#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
3853 and so on; or nullptr
3854##
Cary Clark8032b982017-07-28 11:04:54 -04003855
3856#Example
3857#Height 64
3858#Image 4
Cary Clarkbad5ad72017-08-03 17:14:08 -04003859void draw(SkCanvas* canvas) {
3860 // sk_sp<SkImage> image;
3861 SkImage* imagePtr = image.get();
3862 canvas->drawImage(imagePtr, 0, 0);
3863 SkPaint paint;
3864 canvas->drawImage(imagePtr, 80, 0, &paint);
3865 paint.setAlpha(0x80);
3866 canvas->drawImage(imagePtr, 160, 0, &paint);
Cary Clark8032b982017-07-28 11:04:54 -04003867}
3868##
3869
Cary Clark2ade9972017-11-02 17:49:34 -04003870#SeeAlso drawBitmap drawImageLattice drawImageNine drawImageRect SkPaint::setImageFilter
Cary Clark8032b982017-07-28 11:04:54 -04003871
3872##
3873
3874# ------------------------------------------------------------------------------
3875
3876#Method void drawImage(const sk_sp<SkImage>& image, SkScalar left, SkScalar top,
Cary Clark73fa9722017-08-29 17:36:51 -04003877 const SkPaint* paint = nullptr)
Cary Clark8032b982017-07-28 11:04:54 -04003878
3879Draw Image image, with its top-left corner at (left, top),
3880using Clip, Matrix, and optional Paint paint.
3881
Cary Clarkbad5ad72017-08-03 17:14:08 -04003882If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
3883Blend_Mode, and Draw_Looper. If image is kAlpha_8_SkColorType, apply Shader.
3884If paint contains Mask_Filter, generate mask from image bounds. If generated
3885mask extends beyond image bounds, replicate image edge colors, just as Shader
3886made from SkImage::makeShader with SkShader::kClamp_TileMode set replicates the
Cary Clarkbc5697d2017-10-04 14:31:33 -04003887image edge color when it samples outside of its bounds.
Cary Clark8032b982017-07-28 11:04:54 -04003888
Cary Clarkbad5ad72017-08-03 17:14:08 -04003889#Param image uncompressed rectangular map of pixels ##
3890#Param left left side of image ##
3891#Param top pop side of image ##
3892#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
3893 and so on; or nullptr
3894##
Cary Clark8032b982017-07-28 11:04:54 -04003895
3896#Example
3897#Height 64
3898#Image 4
Cary Clarkbad5ad72017-08-03 17:14:08 -04003899void draw(SkCanvas* canvas) {
3900 // sk_sp<SkImage> image;
3901 canvas->drawImage(image, 0, 0);
3902 SkPaint paint;
3903 canvas->drawImage(image, 80, 0, &paint);
3904 paint.setAlpha(0x80);
3905 canvas->drawImage(image, 160, 0, &paint);
Cary Clark8032b982017-07-28 11:04:54 -04003906}
3907##
3908
Cary Clark2ade9972017-11-02 17:49:34 -04003909#SeeAlso drawBitmap drawImageLattice drawImageNine drawImageRect SkPaint::setImageFilter
Cary Clark8032b982017-07-28 11:04:54 -04003910
3911##
3912
3913# ------------------------------------------------------------------------------
3914
3915#Enum SrcRectConstraint
3916
3917#Code
3918 enum SrcRectConstraint {
3919 kStrict_SrcRectConstraint,
3920 kFast_SrcRectConstraint,
3921 };
3922##
3923
Cary Clarkce101242017-09-01 15:51:02 -04003924SrcRectConstraint controls the behavior at the edge of source Rect,
3925provided to drawImageRect, trading off speed for precision.
Cary Clark8032b982017-07-28 11:04:54 -04003926
Cary Clarkce101242017-09-01 15:51:02 -04003927Image_Filter in Paint may sample multiple pixels in the image. Source Rect
Cary Clarkbad5ad72017-08-03 17:14:08 -04003928restricts the bounds of pixels that may be read. Image_Filter may slow down if
Cary Clarkce101242017-09-01 15:51:02 -04003929it cannot read outside the bounds, when sampling near the edge of source Rect.
Cary Clark8032b982017-07-28 11:04:54 -04003930SrcRectConstraint specifies whether an Image_Filter is allowed to read pixels
Cary Clarkce101242017-09-01 15:51:02 -04003931outside source Rect.
Cary Clark8032b982017-07-28 11:04:54 -04003932
3933#Const kStrict_SrcRectConstraint
Cary Clarkce101242017-09-01 15:51:02 -04003934 Requires Image_Filter to respect source Rect,
Cary Clark8032b982017-07-28 11:04:54 -04003935 sampling only inside of its bounds, possibly with a performance penalty.
3936##
3937
3938#Const kFast_SrcRectConstraint
Cary Clarkce101242017-09-01 15:51:02 -04003939 Permits Image_Filter to sample outside of source Rect
Cary Clark8032b982017-07-28 11:04:54 -04003940 by half the width of Image_Filter, permitting it to run faster but with
3941 error at the image edges.
3942##
3943
3944#Example
3945#Height 64
3946#Description
3947 redBorder contains a black and white checkerboard bordered by red.
3948 redBorder is drawn scaled by 16 on the left.
Cary Clarkce101242017-09-01 15:51:02 -04003949 The middle and right bitmaps are filtered checkerboards.
Cary Clark8032b982017-07-28 11:04:54 -04003950 Drawing the checkerboard with kStrict_SrcRectConstraint shows only a blur of black and white.
3951 Drawing the checkerboard with kFast_SrcRectConstraint allows red to bleed in the corners.
3952##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003953void draw(SkCanvas* canvas) {
3954 SkBitmap redBorder;
3955 redBorder.allocPixels(SkImageInfo::MakeN32Premul(4, 4));
3956 SkCanvas checkRed(redBorder);
3957 checkRed.clear(SK_ColorRED);
3958 uint32_t checkers[][2] = { { SK_ColorBLACK, SK_ColorWHITE },
3959 { SK_ColorWHITE, SK_ColorBLACK } };
3960 checkRed.writePixels(
3961 SkImageInfo::MakeN32Premul(2, 2), (void*) checkers, sizeof(checkers[0]), 1, 1);
3962 canvas->scale(16, 16);
3963 canvas->drawBitmap(redBorder, 0, 0, nullptr);
3964 canvas->resetMatrix();
3965 sk_sp<SkImage> image = SkImage::MakeFromBitmap(redBorder);
3966 SkPaint lowPaint;
3967 lowPaint.setFilterQuality(kLow_SkFilterQuality);
3968 for (auto constraint : { SkCanvas::kStrict_SrcRectConstraint,
3969 SkCanvas::kFast_SrcRectConstraint } ) {
3970 canvas->translate(80, 0);
3971 canvas->drawImageRect(image.get(), SkRect::MakeLTRB(1, 1, 3, 3),
3972 SkRect::MakeLTRB(16, 16, 48, 48), &lowPaint, constraint);
3973 }
Cary Clark8032b982017-07-28 11:04:54 -04003974}
3975##
3976
Cary Clark2ade9972017-11-02 17:49:34 -04003977#SeeAlso drawImageRect drawImage SkPaint::setImageFilter
Cary Clark8032b982017-07-28 11:04:54 -04003978
3979##
3980
3981# ------------------------------------------------------------------------------
3982
3983#Method void drawImageRect(const SkImage* image, const SkRect& src, const SkRect& dst,
3984 const SkPaint* paint,
3985 SrcRectConstraint constraint = kStrict_SrcRectConstraint)
3986
3987Draw Rect src of Image image, scaled and translated to fill Rect dst.
3988Additionally transform draw using Clip, Matrix, and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04003989
Cary Clarkbad5ad72017-08-03 17:14:08 -04003990If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
3991Blend_Mode, and Draw_Looper. If image is kAlpha_8_SkColorType, apply Shader.
3992If paint contains Mask_Filter, generate mask from image bounds.
3993
3994If generated mask extends beyond image bounds, replicate image edge colors, just
3995as Shader made from SkImage::makeShader with SkShader::kClamp_TileMode set
Cary Clarkbc5697d2017-10-04 14:31:33 -04003996replicates the image edge color when it samples outside of its bounds.
Cary Clarkbad5ad72017-08-03 17:14:08 -04003997
3998constraint set to kStrict_SrcRectConstraint limits Paint Filter_Quality to
3999sample within src; set to kFast_SrcRectConstraint allows sampling outside to
4000improve performance.
4001
4002#Param image Image containing pixels, dimensions, and format ##
4003#Param src source Rect of image to draw from ##
4004#Param dst destination Rect of image to draw to ##
4005#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4006 and so on; or nullptr
4007##
4008#Param constraint filter strictly within src or draw faster ##
Cary Clark8032b982017-07-28 11:04:54 -04004009
4010#Example
4011#Height 64
4012#Description
4013 The left bitmap draws with Paint default kNone_SkFilterQuality, and stays within
Cary Clarkbc5697d2017-10-04 14:31:33 -04004014 its bounds; there is no bleeding with kFast_SrcRectConstraint.
Cary Clark8032b982017-07-28 11:04:54 -04004015 the middle and right bitmaps draw with kLow_SkFilterQuality; with
4016 kStrict_SrcRectConstraint, the filter remains within the checkerboard, and
4017 with kFast_SrcRectConstraint red bleeds on the edges.
4018##
Cary Clarkbad5ad72017-08-03 17:14:08 -04004019void draw(SkCanvas* canvas) {
4020 uint32_t pixels[][4] = {
4021 { 0xFFFF0000, 0xFFFF0000, 0xFFFF0000, 0xFFFF0000 },
4022 { 0xFFFF0000, 0xFF000000, 0xFFFFFFFF, 0xFFFF0000 },
4023 { 0xFFFF0000, 0xFFFFFFFF, 0xFF000000, 0xFFFF0000 },
4024 { 0xFFFF0000, 0xFFFF0000, 0xFFFF0000, 0xFFFF0000 } };
4025 SkBitmap redBorder;
4026 redBorder.installPixels(SkImageInfo::MakeN32Premul(4, 4),
4027 (void*) pixels, sizeof(pixels[0]));
4028 sk_sp<SkImage> image = SkImage::MakeFromBitmap(redBorder);
4029 SkPaint lowPaint;
4030 for (auto constraint : {
4031 SkCanvas::kFast_SrcRectConstraint,
4032 SkCanvas::kStrict_SrcRectConstraint,
4033 SkCanvas::kFast_SrcRectConstraint } ) {
4034 canvas->drawImageRect(image.get(), SkRect::MakeLTRB(1, 1, 3, 3),
4035 SkRect::MakeLTRB(16, 16, 48, 48), &lowPaint, constraint);
4036 lowPaint.setFilterQuality(kLow_SkFilterQuality);
4037 canvas->translate(80, 0);
4038 }
4039}
Cary Clark8032b982017-07-28 11:04:54 -04004040##
4041
Cary Clark2ade9972017-11-02 17:49:34 -04004042#SeeAlso SrcRectConstraint drawImage drawImageLattice drawImageNine
Cary Clark8032b982017-07-28 11:04:54 -04004043
4044##
4045
4046# ------------------------------------------------------------------------------
4047
4048#Method void drawImageRect(const SkImage* image, const SkIRect& isrc, const SkRect& dst,
4049 const SkPaint* paint, SrcRectConstraint constraint = kStrict_SrcRectConstraint)
4050
4051Draw IRect isrc of Image image, scaled and translated to fill Rect dst.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004052Note that isrc is on integer pixel boundaries; dst may include fractional
4053boundaries. Additionally transform draw using Clip, Matrix, and optional Paint
4054paint.
Cary Clark8032b982017-07-28 11:04:54 -04004055
Cary Clarkbad5ad72017-08-03 17:14:08 -04004056If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4057Blend_Mode, and Draw_Looper. If image is kAlpha_8_SkColorType, apply Shader.
4058If paint contains Mask_Filter, generate mask from image bounds.
4059
4060If generated mask extends beyond image bounds, replicate image edge colors, just
4061as Shader made from SkImage::makeShader with SkShader::kClamp_TileMode set
Cary Clarkbc5697d2017-10-04 14:31:33 -04004062replicates the image edge color when it samples outside of its bounds.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004063
4064constraint set to kStrict_SrcRectConstraint limits Paint Filter_Quality to
Cary Clarkce101242017-09-01 15:51:02 -04004065sample within isrc; set to kFast_SrcRectConstraint allows sampling outside to
Cary Clarkbad5ad72017-08-03 17:14:08 -04004066improve performance.
4067
4068#Param image Image containing pixels, dimensions, and format ##
4069#Param isrc source IRect of image to draw from ##
4070#Param dst destination Rect of image to draw to ##
4071#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4072 and so on; or nullptr
4073##
Cary Clarkce101242017-09-01 15:51:02 -04004074#Param constraint filter strictly within isrc or draw faster ##
Cary Clark8032b982017-07-28 11:04:54 -04004075
4076#Example
4077#Image 4
Cary Clarkbad5ad72017-08-03 17:14:08 -04004078void draw(SkCanvas* canvas) {
4079 // sk_sp<SkImage> image;
4080 for (auto i : { 1, 2, 4, 8 } ) {
4081 canvas->drawImageRect(image.get(), SkIRect::MakeLTRB(0, 0, 100, 100),
4082 SkRect::MakeXYWH(i * 20, i * 20, i * 20, i * 20), nullptr);
4083 }
Cary Clark8032b982017-07-28 11:04:54 -04004084}
4085##
4086
Cary Clark2ade9972017-11-02 17:49:34 -04004087#SeeAlso SrcRectConstraint drawImage drawImageLattice drawImageNine
Cary Clark8032b982017-07-28 11:04:54 -04004088
4089##
4090
4091# ------------------------------------------------------------------------------
4092
4093#Method void drawImageRect(const SkImage* image, const SkRect& dst, const SkPaint* paint,
4094 SrcRectConstraint constraint = kStrict_SrcRectConstraint)
4095
Cary Clarkbad5ad72017-08-03 17:14:08 -04004096Draw Image image, scaled and translated to fill Rect dst, using Clip, Matrix,
4097and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004098
Cary Clarkbad5ad72017-08-03 17:14:08 -04004099If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4100Blend_Mode, and Draw_Looper. If image is kAlpha_8_SkColorType, apply Shader.
4101If paint contains Mask_Filter, generate mask from image bounds.
4102
4103If generated mask extends beyond image bounds, replicate image edge colors, just
4104as Shader made from SkImage::makeShader with SkShader::kClamp_TileMode set
Cary Clarkbc5697d2017-10-04 14:31:33 -04004105replicates the image edge color when it samples outside of its bounds.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004106
4107constraint set to kStrict_SrcRectConstraint limits Paint Filter_Quality to
Cary Clarkce101242017-09-01 15:51:02 -04004108sample within image; set to kFast_SrcRectConstraint allows sampling outside to
Cary Clarkbad5ad72017-08-03 17:14:08 -04004109improve performance.
4110
4111#Param image Image containing pixels, dimensions, and format ##
4112#Param dst destination Rect of image to draw to ##
4113#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4114 and so on; or nullptr
4115##
Cary Clarkce101242017-09-01 15:51:02 -04004116#Param constraint filter strictly within image or draw faster ##
Cary Clark8032b982017-07-28 11:04:54 -04004117
4118#Example
4119#Image 4
Cary Clarkbad5ad72017-08-03 17:14:08 -04004120void draw(SkCanvas* canvas) {
4121 // sk_sp<SkImage> image;
4122 for (auto i : { 20, 40, 80, 160 } ) {
4123 canvas->drawImageRect(image.get(), SkRect::MakeXYWH(i, i, i, i), nullptr);
4124 }
Cary Clark8032b982017-07-28 11:04:54 -04004125}
4126##
4127
Cary Clark2ade9972017-11-02 17:49:34 -04004128#SeeAlso SrcRectConstraint drawImage drawImageLattice drawImageNine
Cary Clark8032b982017-07-28 11:04:54 -04004129
4130##
4131
4132# ------------------------------------------------------------------------------
4133
4134#Method void drawImageRect(const sk_sp<SkImage>& image, const SkRect& src, const SkRect& dst,
4135 const SkPaint* paint,
4136 SrcRectConstraint constraint = kStrict_SrcRectConstraint)
4137
4138Draw Rect src of Image image, scaled and translated to fill Rect dst.
4139Additionally transform draw using Clip, Matrix, and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004140
Cary Clarkbad5ad72017-08-03 17:14:08 -04004141If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4142Blend_Mode, and Draw_Looper. If image is kAlpha_8_SkColorType, apply Shader.
4143If paint contains Mask_Filter, generate mask from image bounds.
4144
4145If generated mask extends beyond image bounds, replicate image edge colors, just
4146as Shader made from SkImage::makeShader with SkShader::kClamp_TileMode set
Cary Clarkbc5697d2017-10-04 14:31:33 -04004147replicates the image edge color when it samples outside of its bounds.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004148
4149constraint set to kStrict_SrcRectConstraint limits Paint Filter_Quality to
4150sample within src; set to kFast_SrcRectConstraint allows sampling outside to
4151improve performance.
4152
4153#Param image Image containing pixels, dimensions, and format ##
4154#Param src source Rect of image to draw from ##
4155#Param dst destination Rect of image to draw to ##
4156#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4157 and so on; or nullptr
4158##
4159#Param constraint filter strictly within src or draw faster ##
Cary Clark8032b982017-07-28 11:04:54 -04004160
4161#Example
4162#Height 64
4163#Description
4164 Canvas scales and translates; transformation from src to dst also scales.
4165 The two matrices are concatenated to create the final transformation.
4166##
Cary Clarkbad5ad72017-08-03 17:14:08 -04004167void draw(SkCanvas* canvas) {
4168 uint32_t pixels[][2] = { { SK_ColorBLACK, SK_ColorWHITE },
4169 { SK_ColorWHITE, SK_ColorBLACK } };
4170 SkBitmap bitmap;
4171 bitmap.installPixels(SkImageInfo::MakeN32Premul(2, 2),
4172 (void*) pixels, sizeof(pixels[0]));
4173 sk_sp<SkImage> image = SkImage::MakeFromBitmap(bitmap);
4174 SkPaint paint;
4175 canvas->scale(4, 4);
4176 for (auto alpha : { 50, 100, 150, 255 } ) {
4177 paint.setAlpha(alpha);
4178 canvas->drawImageRect(image, SkRect::MakeWH(2, 2), SkRect::MakeWH(8, 8), &paint);
4179 canvas->translate(8, 0);
4180 }
4181}
Cary Clark8032b982017-07-28 11:04:54 -04004182##
4183
Cary Clark2ade9972017-11-02 17:49:34 -04004184#SeeAlso SrcRectConstraint drawImage drawImageLattice drawImageNine
Cary Clark8032b982017-07-28 11:04:54 -04004185
4186##
4187
4188# ------------------------------------------------------------------------------
4189
4190#Method void drawImageRect(const sk_sp<SkImage>& image, const SkIRect& isrc, const SkRect& dst,
4191 const SkPaint* paint, SrcRectConstraint constraint = kStrict_SrcRectConstraint)
4192
4193Draw IRect isrc of Image image, scaled and translated to fill Rect dst.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004194isrc is on integer pixel boundaries; dst may include fractional boundaries.
Cary Clark8032b982017-07-28 11:04:54 -04004195Additionally transform draw using Clip, Matrix, and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004196
Cary Clarkbad5ad72017-08-03 17:14:08 -04004197If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4198Blend_Mode, and Draw_Looper. If image is kAlpha_8_SkColorType, apply Shader.
4199If paint contains Mask_Filter, generate mask from image bounds.
4200
4201If generated mask extends beyond image bounds, replicate image edge colors, just
4202as Shader made from SkImage::makeShader with SkShader::kClamp_TileMode set
Cary Clarkbc5697d2017-10-04 14:31:33 -04004203replicates the image edge color when it samples outside of its bounds.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004204
4205constraint set to kStrict_SrcRectConstraint limits Paint Filter_Quality to
Cary Clarkce101242017-09-01 15:51:02 -04004206sample within image; set to kFast_SrcRectConstraint allows sampling outside to
Cary Clarkbad5ad72017-08-03 17:14:08 -04004207improve performance.
4208
4209#Param image Image containing pixels, dimensions, and format ##
4210#Param isrc source IRect of image to draw from ##
4211#Param dst destination Rect of image to draw to ##
4212#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4213 and so on; or nullptr
4214##
Cary Clarkce101242017-09-01 15:51:02 -04004215#Param constraint filter strictly within image or draw faster ##
Cary Clark8032b982017-07-28 11:04:54 -04004216
4217#Example
4218#Height 64
Cary Clarkbad5ad72017-08-03 17:14:08 -04004219void draw(SkCanvas* canvas) {
4220 uint32_t pixels[][2] = { { 0x00000000, 0x55555555},
4221 { 0xAAAAAAAA, 0xFFFFFFFF} };
4222 SkBitmap bitmap;
4223 bitmap.installPixels(SkImageInfo::MakeN32Premul(2, 2),
4224 (void*) pixels, sizeof(pixels[0]));
4225 sk_sp<SkImage> image = SkImage::MakeFromBitmap(bitmap);
4226 SkPaint paint;
4227 canvas->scale(4, 4);
4228 for (auto color : { SK_ColorRED, SK_ColorBLUE, SK_ColorGREEN } ) {
4229 paint.setColorFilter(SkColorFilter::MakeModeFilter(color, SkBlendMode::kPlus));
4230 canvas->drawImageRect(image, SkIRect::MakeWH(2, 2), SkRect::MakeWH(8, 8), &paint);
4231 canvas->translate(8, 0);
4232 }
Cary Clark8032b982017-07-28 11:04:54 -04004233}
4234##
4235
Cary Clark2ade9972017-11-02 17:49:34 -04004236#SeeAlso SrcRectConstraint drawImage drawImageLattice drawImageNine
4237
Cary Clark8032b982017-07-28 11:04:54 -04004238##
4239
4240# ------------------------------------------------------------------------------
4241
4242#Method void drawImageRect(const sk_sp<SkImage>& image, const SkRect& dst, const SkPaint* paint,
4243 SrcRectConstraint constraint = kStrict_SrcRectConstraint)
4244
4245Draw Image image, scaled and translated to fill Rect dst,
4246using Clip, Matrix, and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004247
Cary Clarkbad5ad72017-08-03 17:14:08 -04004248If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4249Blend_Mode, and Draw_Looper. If image is kAlpha_8_SkColorType, apply Shader.
4250If paint contains Mask_Filter, generate mask from image bounds.
4251
4252If generated mask extends beyond image bounds, replicate image edge colors, just
4253as Shader made from SkImage::makeShader with SkShader::kClamp_TileMode set
Cary Clarkbc5697d2017-10-04 14:31:33 -04004254replicates the image edge color when it samples outside of its bounds.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004255
4256constraint set to kStrict_SrcRectConstraint limits Paint Filter_Quality to
Cary Clarkce101242017-09-01 15:51:02 -04004257sample within image; set to kFast_SrcRectConstraint allows sampling outside to
Cary Clarkbad5ad72017-08-03 17:14:08 -04004258improve performance.
4259
4260#Param image Image containing pixels, dimensions, and format ##
4261#Param dst destination Rect of image to draw to ##
4262#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4263 and so on; or nullptr
4264##
Cary Clarkce101242017-09-01 15:51:02 -04004265#Param constraint filter strictly within image or draw faster ##
Cary Clark8032b982017-07-28 11:04:54 -04004266
4267#Example
4268#Height 64
Cary Clarkbad5ad72017-08-03 17:14:08 -04004269void draw(SkCanvas* canvas) {
4270 uint32_t pixels[][2] = { { 0x00000000, 0x55550000},
4271 { 0xAAAA0000, 0xFFFF0000} };
4272 SkBitmap bitmap;
4273 bitmap.installPixels(SkImageInfo::MakeN32Premul(2, 2),
4274 (void*) pixels, sizeof(pixels[0]));
4275 sk_sp<SkImage> image = SkImage::MakeFromBitmap(bitmap);
4276 SkPaint paint;
4277 canvas->scale(4, 4);
4278 for (auto color : { SK_ColorRED, SK_ColorBLUE, SK_ColorGREEN } ) {
4279 paint.setColorFilter(SkColorFilter::MakeModeFilter(color, SkBlendMode::kPlus));
4280 canvas->drawImageRect(image, SkRect::MakeWH(8, 8), &paint);
4281 canvas->translate(8, 0);
4282 }
Cary Clark8032b982017-07-28 11:04:54 -04004283}
4284##
4285
Cary Clark2ade9972017-11-02 17:49:34 -04004286#SeeAlso SrcRectConstraint drawImage drawImageLattice drawImageNine
Cary Clark8032b982017-07-28 11:04:54 -04004287
4288##
4289
4290# ------------------------------------------------------------------------------
4291
4292#Method void drawImageNine(const SkImage* image, const SkIRect& center, const SkRect& dst,
4293 const SkPaint* paint = nullptr)
4294
Cary Clarkd0530ba2017-09-14 11:25:39 -04004295Draw Image image stretched proportionally to fit into Rect dst.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004296IRect center divides the image into nine sections: four sides, four corners, and
Cary Clarkce101242017-09-01 15:51:02 -04004297the center. Corners are unmodified or scaled down proportionately if their sides
Cary Clarkbad5ad72017-08-03 17:14:08 -04004298are larger than dst; center and four sides are scaled to fit remaining space, if any.
Cary Clark8032b982017-07-28 11:04:54 -04004299
Cary Clarkbad5ad72017-08-03 17:14:08 -04004300Additionally transform draw using Clip, Matrix, and optional Paint paint.
4301
4302If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4303Blend_Mode, and Draw_Looper. If image is kAlpha_8_SkColorType, apply Shader.
4304If paint contains Mask_Filter, generate mask from image bounds.
4305
4306If generated mask extends beyond image bounds, replicate image edge colors, just
4307as Shader made from SkImage::makeShader with SkShader::kClamp_TileMode set
Cary Clarkbc5697d2017-10-04 14:31:33 -04004308replicates the image edge color when it samples outside of its bounds.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004309
4310#Param image Image containing pixels, dimensions, and format ##
4311#Param center IRect edge of image corners and sides ##
4312#Param dst destination Rect of image to draw to ##
4313#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4314 and so on; or nullptr
4315##
Cary Clark8032b982017-07-28 11:04:54 -04004316
4317#Example
4318#Height 128
4319#Description
4320 The leftmost image is smaller than center; only corners are drawn, all scaled to fit.
Cary Clarkce101242017-09-01 15:51:02 -04004321 The second image equals the size of center; only corners are drawn without scaling.
4322 The remaining images are larger than center. All corners draw without scaling.
4323 The sides and center are scaled if needed to take up the remaining space.
Cary Clark8032b982017-07-28 11:04:54 -04004324##
Cary Clarkbad5ad72017-08-03 17:14:08 -04004325void draw(SkCanvas* canvas) {
4326 SkIRect center = { 20, 10, 50, 40 };
4327 SkBitmap bitmap;
4328 bitmap.allocPixels(SkImageInfo::MakeN32Premul(60, 60));
4329 SkCanvas bitCanvas(bitmap);
4330 SkPaint paint;
4331 SkColor gray = 0xFF000000;
4332 int left = 0;
4333 for (auto right: { center.fLeft, center.fRight, bitmap.width() } ) {
4334 int top = 0;
4335 for (auto bottom: { center.fTop, center.fBottom, bitmap.height() } ) {
4336 paint.setColor(gray);
4337 bitCanvas.drawIRect(SkIRect::MakeLTRB(left, top, right, bottom), paint);
4338 gray += 0x001f1f1f;
4339 top = bottom;
4340 }
4341 left = right;
4342 }
4343 sk_sp<SkImage> image = SkImage::MakeFromBitmap(bitmap);
4344 SkImage* imagePtr = image.get();
4345 for (auto dest: { 20, 30, 40, 60, 90 } ) {
4346 canvas->drawImageNine(imagePtr, center, SkRect::MakeWH(dest, dest), nullptr);
4347 canvas->translate(dest + 4, 0);
4348 }
Cary Clark8032b982017-07-28 11:04:54 -04004349}
4350##
4351
Cary Clark2ade9972017-11-02 17:49:34 -04004352#SeeAlso drawImage drawBitmapNine drawImageLattice drawImageRect
Cary Clark8032b982017-07-28 11:04:54 -04004353
4354##
4355
4356# ------------------------------------------------------------------------------
4357
4358#Method void drawImageNine(const sk_sp<SkImage>& image, const SkIRect& center, const SkRect& dst,
4359 const SkPaint* paint = nullptr)
4360
Cary Clarkd0530ba2017-09-14 11:25:39 -04004361Draw Image image stretched proportionally to fit into Rect dst.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004362IRect center divides the image into nine sections: four sides, four corners, and
Cary Clarkce101242017-09-01 15:51:02 -04004363the center. Corners are not scaled, or scaled down proportionately if their sides
Cary Clarkbad5ad72017-08-03 17:14:08 -04004364are larger than dst; center and four sides are scaled to fit remaining space, if any.
Cary Clark8032b982017-07-28 11:04:54 -04004365
Cary Clarkbad5ad72017-08-03 17:14:08 -04004366Additionally transform draw using Clip, Matrix, and optional Paint paint.
4367
4368If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4369Blend_Mode, and Draw_Looper. If image is kAlpha_8_SkColorType, apply Shader.
4370If paint contains Mask_Filter, generate mask from image bounds.
4371
4372If generated mask extends beyond image bounds, replicate image edge colors, just
4373as Shader made from SkImage::makeShader with SkShader::kClamp_TileMode set
Cary Clarkbc5697d2017-10-04 14:31:33 -04004374replicates the image edge color when it samples outside of its bounds.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004375
4376#Param image Image containing pixels, dimensions, and format ##
4377#Param center IRect edge of image corners and sides ##
4378#Param dst destination Rect of image to draw to ##
4379#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4380 and so on; or nullptr
4381##
Cary Clark8032b982017-07-28 11:04:54 -04004382
4383#Example
4384#Height 128
4385#Description
4386 The two leftmost images has four corners and sides to the left and right of center.
4387 The leftmost image scales the width of corners proportionately to fit.
Cary Clarkce101242017-09-01 15:51:02 -04004388 The third and fourth image corners are not scaled; the sides and center are scaled to
Cary Clark8032b982017-07-28 11:04:54 -04004389 fill the remaining space.
4390 The rightmost image has four corners scaled vertically to fit, and uses sides above
4391 and below center to fill the remaining space.
4392##
Cary Clarkbad5ad72017-08-03 17:14:08 -04004393void draw(SkCanvas* canvas) {
4394 SkIRect center = { 20, 10, 50, 40 };
4395 SkBitmap bitmap;
4396 bitmap.allocPixels(SkImageInfo::MakeN32Premul(60, 60));
4397 SkCanvas bitCanvas(bitmap);
4398 SkPaint paint;
4399 SkColor gray = 0xFF000000;
4400 int left = 0;
4401 for (auto right: { center.fLeft, center.fRight, bitmap.width() } ) {
4402 int top = 0;
4403 for (auto bottom: { center.fTop, center.fBottom, bitmap.height() } ) {
4404 paint.setColor(gray);
4405 bitCanvas.drawIRect(SkIRect::MakeLTRB(left, top, right, bottom), paint);
4406 gray += 0x001f1f1f;
4407 top = bottom;
4408 }
4409 left = right;
4410 }
4411 sk_sp<SkImage> image = SkImage::MakeFromBitmap(bitmap);
4412 for (auto dest: { 20, 30, 40, 60, 90 } ) {
4413 canvas->drawImageNine(image, center, SkRect::MakeWH(dest, 110 - dest), nullptr);
4414 canvas->translate(dest + 4, 0);
4415 }
Cary Clark8032b982017-07-28 11:04:54 -04004416}
4417##
4418
Cary Clark2ade9972017-11-02 17:49:34 -04004419#SeeAlso drawImage drawBitmapNine drawImageLattice drawImageRect
Cary Clark8032b982017-07-28 11:04:54 -04004420
4421##
4422
4423# ------------------------------------------------------------------------------
4424
4425#Method void drawBitmap(const SkBitmap& bitmap, SkScalar left, SkScalar top,
Cary Clark73fa9722017-08-29 17:36:51 -04004426 const SkPaint* paint = nullptr)
Cary Clark8032b982017-07-28 11:04:54 -04004427
4428Draw Bitmap bitmap, with its top-left corner at (left, top),
4429using Clip, Matrix, and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004430
Cary Clarka560c472017-11-27 10:44:06 -05004431If Paint paint is not nullptr, apply Color_Filter, Color_Alpha, Image_Filter,
Cary Clarkbad5ad72017-08-03 17:14:08 -04004432Blend_Mode, and Draw_Looper. If bitmap is kAlpha_8_SkColorType, apply Shader.
4433If paint contains Mask_Filter, generate mask from bitmap bounds.
4434
4435If generated mask extends beyond bitmap bounds, replicate bitmap edge colors,
4436just as Shader made from SkShader::MakeBitmapShader with
Cary Clarkbc5697d2017-10-04 14:31:33 -04004437SkShader::kClamp_TileMode set replicates the bitmap edge color when it samples
Cary Clarkbad5ad72017-08-03 17:14:08 -04004438outside of its bounds.
4439
4440#Param bitmap Bitmap containing pixels, dimensions, and format ##
4441#Param left left side of bitmap ##
4442#Param top top side of bitmap ##
4443#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4444 and so on; or nullptr
4445##
Cary Clark8032b982017-07-28 11:04:54 -04004446
4447#Example
4448#Height 64
Cary Clarkbad5ad72017-08-03 17:14:08 -04004449void draw(SkCanvas* canvas) {
4450 uint8_t pixels[][8] = { { 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00},
4451 { 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00},
4452 { 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00},
4453 { 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF},
4454 { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
4455 { 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00},
4456 { 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0x00},
4457 { 0xFF, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0xFF} };
4458 SkBitmap bitmap;
4459 bitmap.installPixels(SkImageInfo::MakeA8(8, 8),
4460 (void*) pixels, sizeof(pixels[0]));
4461 SkPaint paint;
4462 canvas->scale(4, 4);
4463 for (auto color : { SK_ColorRED, SK_ColorBLUE, 0xFF007F00} ) {
4464 paint.setColor(color);
4465 canvas->drawBitmap(bitmap, 0, 0, &paint);
4466 canvas->translate(12, 0);
4467 }
Cary Clark8032b982017-07-28 11:04:54 -04004468}
4469##
4470
Cary Clark2ade9972017-11-02 17:49:34 -04004471#SeeAlso drawImage drawBitmapLattice drawBitmapNine drawBitmapRect SkBitmap::readPixels SkBitmap::writePixels
Cary Clark8032b982017-07-28 11:04:54 -04004472
4473##
4474
4475# ------------------------------------------------------------------------------
4476
4477#Method void drawBitmapRect(const SkBitmap& bitmap, const SkRect& src, const SkRect& dst,
4478 const SkPaint* paint, SrcRectConstraint constraint = kStrict_SrcRectConstraint)
4479
4480Draw Rect src of Bitmap bitmap, scaled and translated to fill Rect dst.
4481Additionally transform draw using Clip, Matrix, and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004482
Cary Clarkbad5ad72017-08-03 17:14:08 -04004483If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4484Blend_Mode, and Draw_Looper. If bitmap is kAlpha_8_SkColorType, apply Shader.
4485If paint contains Mask_Filter, generate mask from bitmap bounds.
4486
4487If generated mask extends beyond bitmap bounds, replicate bitmap edge colors,
4488just as Shader made from SkShader::MakeBitmapShader with
Cary Clarkbc5697d2017-10-04 14:31:33 -04004489SkShader::kClamp_TileMode set replicates the bitmap edge color when it samples
Cary Clarkbad5ad72017-08-03 17:14:08 -04004490outside of its bounds.
4491
4492constraint set to kStrict_SrcRectConstraint limits Paint Filter_Quality to
4493sample within src; set to kFast_SrcRectConstraint allows sampling outside to
4494improve performance.
4495
4496#Param bitmap Bitmap containing pixels, dimensions, and format ##
4497#Param src source Rect of image to draw from ##
4498#Param dst destination Rect of image to draw to ##
4499#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4500 and so on; or nullptr
4501##
4502#Param constraint filter strictly within src or draw faster ##
Cary Clark8032b982017-07-28 11:04:54 -04004503
4504#Example
4505#Height 64
Cary Clarkbad5ad72017-08-03 17:14:08 -04004506void draw(SkCanvas* canvas) {
4507 uint8_t pixels[][8] = { { 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00},
4508 { 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00},
4509 { 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00},
4510 { 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF},
4511 { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
4512 { 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00},
4513 { 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00},
4514 { 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00} };
4515 SkBitmap bitmap;
4516 bitmap.installPixels(SkImageInfo::MakeA8(8, 8),
4517 (void*) pixels, sizeof(pixels[0]));
4518 SkPaint paint;
4519 paint.setMaskFilter(SkBlurMaskFilter::Make(kSolid_SkBlurStyle, 6));
4520 for (auto color : { SK_ColorRED, SK_ColorBLUE, 0xFF007F00} ) {
4521 paint.setColor(color);
4522 canvas->drawBitmapRect(bitmap, SkRect::MakeWH(8, 8), SkRect::MakeWH(32, 32), &paint);
4523 canvas->translate(48, 0);
4524 }
Cary Clark8032b982017-07-28 11:04:54 -04004525}
4526##
4527
Cary Clark2ade9972017-11-02 17:49:34 -04004528#SeeAlso drawImageRect drawBitmap drawBitmapLattice drawBitmapNine
Cary Clark8032b982017-07-28 11:04:54 -04004529
4530##
4531
4532# ------------------------------------------------------------------------------
4533
4534#Method void drawBitmapRect(const SkBitmap& bitmap, const SkIRect& isrc, const SkRect& dst,
4535 const SkPaint* paint, SrcRectConstraint constraint = kStrict_SrcRectConstraint)
4536
4537Draw IRect isrc of Bitmap bitmap, scaled and translated to fill Rect dst.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004538isrc is on integer pixel boundaries; dst may include fractional boundaries.
Cary Clark8032b982017-07-28 11:04:54 -04004539Additionally transform draw using Clip, Matrix, and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004540
Cary Clarkbad5ad72017-08-03 17:14:08 -04004541If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4542Blend_Mode, and Draw_Looper. If bitmap is kAlpha_8_SkColorType, apply Shader.
4543If paint contains Mask_Filter, generate mask from bitmap bounds.
4544
4545If generated mask extends beyond bitmap bounds, replicate bitmap edge colors,
4546just as Shader made from SkShader::MakeBitmapShader with
Cary Clarkbc5697d2017-10-04 14:31:33 -04004547SkShader::kClamp_TileMode set replicates the bitmap edge color when it samples
Cary Clarkbad5ad72017-08-03 17:14:08 -04004548outside of its bounds.
4549
4550constraint set to kStrict_SrcRectConstraint limits Paint Filter_Quality to
Cary Clarkce101242017-09-01 15:51:02 -04004551sample within isrc; set to kFast_SrcRectConstraint allows sampling outside to
Cary Clarkbad5ad72017-08-03 17:14:08 -04004552improve performance.
4553
4554#Param bitmap Bitmap containing pixels, dimensions, and format ##
4555#Param isrc source IRect of image to draw from ##
4556#Param dst destination Rect of image to draw to ##
4557#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4558 and so on; or nullptr
4559##
Cary Clarkce101242017-09-01 15:51:02 -04004560#Param constraint sample strictly within isrc, or draw faster ##
Cary Clark8032b982017-07-28 11:04:54 -04004561
4562#Example
4563#Height 64
Cary Clarkbad5ad72017-08-03 17:14:08 -04004564void draw(SkCanvas* canvas) {
4565 uint8_t pixels[][8] = { { 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00},
4566 { 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00},
4567 { 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0xFF},
4568 { 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0xFF},
4569 { 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF},
4570 { 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF},
4571 { 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00},
4572 { 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00} };
4573 SkBitmap bitmap;
4574 bitmap.installPixels(SkImageInfo::MakeA8(8, 8),
4575 (void*) pixels, sizeof(pixels[0]));
4576 SkPaint paint;
4577 paint.setFilterQuality(kHigh_SkFilterQuality);
4578 for (auto color : { SK_ColorRED, SK_ColorBLUE, 0xFF007F00, 0xFF7f007f} ) {
4579 paint.setColor(color);
4580 canvas->drawBitmapRect(bitmap, SkIRect::MakeWH(8, 8), SkRect::MakeWH(32, 32), &paint);
4581 canvas->translate(48.25f, 0);
4582 }
Cary Clark8032b982017-07-28 11:04:54 -04004583}
4584##
4585
Cary Clark2ade9972017-11-02 17:49:34 -04004586#SeeAlso drawImageRect drawBitmap drawBitmapLattice drawBitmapNine
Cary Clark8032b982017-07-28 11:04:54 -04004587
4588##
4589
4590# ------------------------------------------------------------------------------
4591
4592#Method void drawBitmapRect(const SkBitmap& bitmap, const SkRect& dst, const SkPaint* paint,
4593 SrcRectConstraint constraint = kStrict_SrcRectConstraint)
4594
4595Draw Bitmap bitmap, scaled and translated to fill Rect dst.
Cary Clarkce101242017-09-01 15:51:02 -04004596bitmap bounds is on integer pixel boundaries; dst may include fractional boundaries.
Cary Clark8032b982017-07-28 11:04:54 -04004597Additionally transform draw using Clip, Matrix, and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004598
Cary Clarkbad5ad72017-08-03 17:14:08 -04004599If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4600Blend_Mode, and Draw_Looper. If bitmap is kAlpha_8_SkColorType, apply Shader.
4601If paint contains Mask_Filter, generate mask from bitmap bounds.
4602
4603If generated mask extends beyond bitmap bounds, replicate bitmap edge colors,
4604just as Shader made from SkShader::MakeBitmapShader with
Cary Clarkbc5697d2017-10-04 14:31:33 -04004605SkShader::kClamp_TileMode set replicates the bitmap edge color when it samples
Cary Clarkbad5ad72017-08-03 17:14:08 -04004606outside of its bounds.
4607
4608constraint set to kStrict_SrcRectConstraint limits Paint Filter_Quality to
Cary Clarkce101242017-09-01 15:51:02 -04004609sample within bitmap; set to kFast_SrcRectConstraint allows sampling outside to
Cary Clarkbad5ad72017-08-03 17:14:08 -04004610improve performance.
4611
4612#Param bitmap Bitmap containing pixels, dimensions, and format ##
4613#Param dst destination Rect of image to draw to ##
4614#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4615 and so on; or nullptr
4616##
Cary Clarkce101242017-09-01 15:51:02 -04004617#Param constraint filter strictly within bitmap or draw faster ##
Cary Clark8032b982017-07-28 11:04:54 -04004618
4619#Example
4620#Height 64
Cary Clarkbad5ad72017-08-03 17:14:08 -04004621void draw(SkCanvas* canvas) {
4622 uint32_t pixels[][2] = { { 0x00000000, 0x55550000},
4623 { 0xAAAA0000, 0xFFFF0000} };
4624 SkBitmap bitmap;
4625 bitmap.installPixels(SkImageInfo::MakeN32Premul(2, 2),
4626 (void*) pixels, sizeof(pixels[0]));
4627 SkPaint paint;
4628 canvas->scale(4, 4);
4629 for (auto color : { SK_ColorRED, SK_ColorBLUE, SK_ColorGREEN } ) {
4630 paint.setColorFilter(SkColorFilter::MakeModeFilter(color, SkBlendMode::kPlus));
4631 canvas->drawBitmapRect(bitmap, SkRect::MakeWH(8, 8), &paint);
4632 canvas->translate(8, 0);
4633 }
Cary Clark8032b982017-07-28 11:04:54 -04004634}
4635##
4636
Cary Clark2ade9972017-11-02 17:49:34 -04004637#SeeAlso drawImageRect drawBitmap drawBitmapLattice drawBitmapNine
Cary Clark8032b982017-07-28 11:04:54 -04004638
4639##
4640
4641# ------------------------------------------------------------------------------
4642
4643#Method void drawBitmapNine(const SkBitmap& bitmap, const SkIRect& center, const SkRect& dst,
Cary Clark73fa9722017-08-29 17:36:51 -04004644 const SkPaint* paint = nullptr)
Cary Clark8032b982017-07-28 11:04:54 -04004645
Cary Clarkd0530ba2017-09-14 11:25:39 -04004646Draw Bitmap bitmap stretched proportionally to fit into Rect dst.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004647IRect center divides the bitmap into nine sections: four sides, four corners,
Cary Clarkce101242017-09-01 15:51:02 -04004648and the center. Corners are not scaled, or scaled down proportionately if their
Cary Clarkbad5ad72017-08-03 17:14:08 -04004649sides are larger than dst; center and four sides are scaled to fit remaining
4650space, if any.
Cary Clark8032b982017-07-28 11:04:54 -04004651
Cary Clarkbad5ad72017-08-03 17:14:08 -04004652Additionally transform draw using Clip, Matrix, and optional Paint paint.
4653
4654If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4655Blend_Mode, and Draw_Looper. If bitmap is kAlpha_8_SkColorType, apply Shader.
4656If paint contains Mask_Filter, generate mask from bitmap bounds.
4657
4658If generated mask extends beyond bitmap bounds, replicate bitmap edge colors,
4659just as Shader made from SkShader::MakeBitmapShader with
Cary Clarkbc5697d2017-10-04 14:31:33 -04004660SkShader::kClamp_TileMode set replicates the bitmap edge color when it samples
Cary Clarkbad5ad72017-08-03 17:14:08 -04004661outside of its bounds.
4662
4663#Param bitmap Bitmap containing pixels, dimensions, and format ##
4664#Param center IRect edge of image corners and sides ##
4665#Param dst destination Rect of image to draw to ##
4666#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4667 and so on; or nullptr
4668##
Cary Clark8032b982017-07-28 11:04:54 -04004669
4670#Example
4671#Height 128
4672#Description
4673 The two leftmost bitmap draws has four corners and sides to the left and right of center.
4674 The leftmost bitmap draw scales the width of corners proportionately to fit.
Cary Clarkce101242017-09-01 15:51:02 -04004675 The third and fourth draw corners are not scaled; the sides and center are scaled to
Cary Clark8032b982017-07-28 11:04:54 -04004676 fill the remaining space.
4677 The rightmost bitmap draw has four corners scaled vertically to fit, and uses sides above
4678 and below center to fill the remaining space.
4679##
Cary Clarkbad5ad72017-08-03 17:14:08 -04004680void draw(SkCanvas* canvas) {
4681 SkIRect center = { 20, 10, 50, 40 };
4682 SkBitmap bitmap;
4683 bitmap.allocPixels(SkImageInfo::MakeN32Premul(60, 60));
4684 SkCanvas bitCanvas(bitmap);
4685 SkPaint paint;
4686 SkColor gray = 0xFF000000;
4687 int left = 0;
4688 for (auto right: { center.fLeft, center.fRight, bitmap.width() } ) {
4689 int top = 0;
4690 for (auto bottom: { center.fTop, center.fBottom, bitmap.height() } ) {
4691 paint.setColor(gray);
4692 bitCanvas.drawIRect(SkIRect::MakeLTRB(left, top, right, bottom), paint);
4693 gray += 0x001f1f1f;
4694 top = bottom;
4695 }
4696 left = right;
4697 }
4698 for (auto dest: { 20, 30, 40, 60, 90 } ) {
4699 canvas->drawBitmapNine(bitmap, center, SkRect::MakeWH(dest, 110 - dest), nullptr);
4700 canvas->translate(dest + 4, 0);
4701 }
Cary Clark8032b982017-07-28 11:04:54 -04004702}
4703##
4704
Cary Clark2ade9972017-11-02 17:49:34 -04004705#SeeAlso drawImageNine drawBitmap drawBitmapLattice drawBitmapRect
Cary Clark8032b982017-07-28 11:04:54 -04004706
4707##
4708
4709# ------------------------------------------------------------------------------
4710#Struct Lattice
4711
Cary Clark8032b982017-07-28 11:04:54 -04004712#Code
4713 struct Lattice {
4714 enum Flags {...
4715
4716 const int* fXDivs;
4717 const int* fYDivs;
4718 const Flags* fFlags;
4719 int fXCount;
4720 int fYCount;
4721 const SkIRect* fBounds;
4722 };
4723##
4724
Cary Clark154beea2017-10-26 07:58:48 -04004725 Lattice divides Bitmap or Image into a rectangular grid.
4726 Grid entries on even columns and even rows are fixed; these entries are
4727 always drawn at their original size if the destination is large enough.
4728 If the destination side is too small to hold the fixed entries, all fixed
4729 entries are proportionately scaled down to fit.
4730 The grid entries not on even columns and rows are scaled to fit the
4731 remaining space, if any.
4732
Cary Clark8032b982017-07-28 11:04:54 -04004733 #Enum Flags
4734 #Code
4735 enum Flags : uint8_t {
4736 kTransparent_Flags = 1 << 0,
4737 };
4738 ##
4739
4740 Optional setting per rectangular grid entry to make it transparent.
4741
4742 #Const kTransparent_Flags 1
4743 Set to skip lattice rectangle by making it transparent.
4744 ##
4745 ##
4746
4747 #Member const int* fXDivs
4748 Array of x-coordinates that divide the bitmap vertically.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004749 Array entries must be unique, increasing, greater than or equal to
4750 fBounds left edge, and less than fBounds right edge.
4751 Set the first element to fBounds left to collapse the left column of
4752 fixed grid entries.
Cary Clark8032b982017-07-28 11:04:54 -04004753 ##
4754
4755 #Member const int* fYDivs
4756 Array of y-coordinates that divide the bitmap horizontally.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004757 Array entries must be unique, increasing, greater than or equal to
4758 fBounds top edge, and less than fBounds bottom edge.
4759 Set the first element to fBounds top to collapse the top row of fixed
4760 grid entries.
Cary Clark8032b982017-07-28 11:04:54 -04004761 ##
4762
4763 #Member const Flags* fFlags
4764 Optional array of Flags, one per rectangular grid entry:
Cary Clarkbad5ad72017-08-03 17:14:08 -04004765 array length must be
4766 #Formula
4767 (fXCount + 1) * (fYCount + 1)
4768 ##
4769 .
Cary Clark6fc50412017-09-21 12:31:06 -04004770
Cary Clark8032b982017-07-28 11:04:54 -04004771 Array entries correspond to the rectangular grid entries, ascending
4772 left to right and then top to bottom.
4773 ##
4774
4775 #Member int fXCount
Cary Clarkbad5ad72017-08-03 17:14:08 -04004776 Number of entries in fXDivs array; one less than the number of
4777 horizontal divisions.
Cary Clark8032b982017-07-28 11:04:54 -04004778 ##
4779
4780 #Member int fYCount
Cary Clarkbad5ad72017-08-03 17:14:08 -04004781 Number of entries in fYDivs array; one less than the number of vertical
4782 divisions.
Cary Clark8032b982017-07-28 11:04:54 -04004783 ##
4784
4785 #Member const SkIRect* fBounds
4786 Optional subset IRect source to draw from.
4787 If nullptr, source bounds is dimensions of Bitmap or Image.
4788 ##
4789
4790#Struct Lattice ##
4791
4792#Method void drawBitmapLattice(const SkBitmap& bitmap, const Lattice& lattice, const SkRect& dst,
4793 const SkPaint* paint = nullptr)
4794
Cary Clarkd0530ba2017-09-14 11:25:39 -04004795Draw Bitmap bitmap stretched proportionally to fit into Rect dst.
Cary Clark8032b982017-07-28 11:04:54 -04004796
4797Lattice lattice divides bitmap into a rectangular grid.
4798Each intersection of an even-numbered row and column is fixed; like the corners
Cary Clarkbad5ad72017-08-03 17:14:08 -04004799of drawBitmapNine, fixed lattice elements never scale larger than their initial
Cary Clarkbc5697d2017-10-04 14:31:33 -04004800size and shrink proportionately when all fixed elements exceed the bitmap
Cary Clarkbad5ad72017-08-03 17:14:08 -04004801dimension. All other grid elements scale to fill the available space, if any.
Cary Clark8032b982017-07-28 11:04:54 -04004802
4803Additionally transform draw using Clip, Matrix, and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004804
Cary Clarkbad5ad72017-08-03 17:14:08 -04004805If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4806Blend_Mode, and Draw_Looper. If bitmap is kAlpha_8_SkColorType, apply Shader.
4807If paint contains Mask_Filter, generate mask from bitmap bounds.
4808
4809If generated mask extends beyond bitmap bounds, replicate bitmap edge colors,
4810just as Shader made from SkShader::MakeBitmapShader with
Cary Clarkbc5697d2017-10-04 14:31:33 -04004811SkShader::kClamp_TileMode set replicates the bitmap edge color when it samples
Cary Clarkbad5ad72017-08-03 17:14:08 -04004812outside of its bounds.
4813
4814#Param bitmap Bitmap containing pixels, dimensions, and format ##
4815#Param lattice division of bitmap into fixed and variable rectangles ##
4816#Param dst destination Rect of image to draw to ##
4817#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4818 and so on; or nullptr
4819##
Cary Clark8032b982017-07-28 11:04:54 -04004820
4821#Example
4822#Height 128
4823#Description
4824 The two leftmost bitmap draws has four corners and sides to the left and right of center.
4825 The leftmost bitmap draw scales the width of corners proportionately to fit.
Cary Clarkce101242017-09-01 15:51:02 -04004826 The third and fourth draw corners are not scaled; the sides are scaled to
Cary Clark8032b982017-07-28 11:04:54 -04004827 fill the remaining space; the center is transparent.
4828 The rightmost bitmap draw has four corners scaled vertically to fit, and uses sides above
4829 and below center to fill the remaining space.
4830##
Cary Clarkbad5ad72017-08-03 17:14:08 -04004831void draw(SkCanvas* canvas) {
4832 SkIRect center = { 20, 10, 50, 40 };
4833 SkBitmap bitmap;
4834 bitmap.allocPixels(SkImageInfo::MakeN32Premul(60, 60));
4835 SkCanvas bitCanvas(bitmap);
4836 SkPaint paint;
4837 SkColor gray = 0xFF000000;
4838 int left = 0;
4839 for (auto right: { center.fLeft, center.fRight, bitmap.width() } ) {
4840 int top = 0;
4841 for (auto bottom: { center.fTop, center.fBottom, bitmap.height() } ) {
4842 paint.setColor(gray);
4843 bitCanvas.drawIRect(SkIRect::MakeLTRB(left, top, right, bottom), paint);
4844 gray += 0x001f1f1f;
4845 top = bottom;
4846 }
4847 left = right;
4848 }
4849 const int xDivs[] = { center.fLeft, center.fRight };
4850 const int yDivs[] = { center.fTop, center.fBottom };
4851 SkCanvas::Lattice::Flags flags[3][3];
4852 memset(flags, 0, sizeof(flags));
4853 flags[1][1] = SkCanvas::Lattice::kTransparent_Flags;
4854 SkCanvas::Lattice lattice = { xDivs, yDivs, flags[0], SK_ARRAY_COUNT(xDivs),
4855 SK_ARRAY_COUNT(yDivs), nullptr };
4856 for (auto dest: { 20, 30, 40, 60, 90 } ) {
4857 canvas->drawBitmapLattice(bitmap, lattice , SkRect::MakeWH(dest, 110 - dest), nullptr);
4858 canvas->translate(dest + 4, 0);
4859 }
Cary Clark8032b982017-07-28 11:04:54 -04004860}
4861##
4862
Cary Clark2ade9972017-11-02 17:49:34 -04004863#SeeAlso drawImageLattice drawBitmap drawBitmapNine Lattice
Cary Clark8032b982017-07-28 11:04:54 -04004864
4865##
4866
4867# ------------------------------------------------------------------------------
4868
4869#Method void drawImageLattice(const SkImage* image, const Lattice& lattice, const SkRect& dst,
4870 const SkPaint* paint = nullptr)
4871
Cary Clarkd0530ba2017-09-14 11:25:39 -04004872Draw Image image stretched proportionally to fit into Rect dst.
Cary Clark8032b982017-07-28 11:04:54 -04004873
4874Lattice lattice divides image into a rectangular grid.
4875Each intersection of an even-numbered row and column is fixed; like the corners
Cary Clarkbad5ad72017-08-03 17:14:08 -04004876of drawBitmapNine, fixed lattice elements never scale larger than their initial
Cary Clarkbc5697d2017-10-04 14:31:33 -04004877size and shrink proportionately when all fixed elements exceed the bitmap
Cary Clarkbad5ad72017-08-03 17:14:08 -04004878dimension. All other grid elements scale to fill the available space, if any.
Cary Clark8032b982017-07-28 11:04:54 -04004879
4880Additionally transform draw using Clip, Matrix, and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004881
Cary Clarkbad5ad72017-08-03 17:14:08 -04004882If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4883Blend_Mode, and Draw_Looper. If bitmap is kAlpha_8_SkColorType, apply Shader.
4884If paint contains Mask_Filter, generate mask from bitmap bounds.
4885
4886If generated mask extends beyond bitmap bounds, replicate bitmap edge colors,
4887just as Shader made from SkShader::MakeBitmapShader with
Cary Clarkbc5697d2017-10-04 14:31:33 -04004888SkShader::kClamp_TileMode set replicates the bitmap edge color when it samples
Cary Clarkbad5ad72017-08-03 17:14:08 -04004889outside of its bounds.
4890
4891#Param image Image containing pixels, dimensions, and format ##
4892#Param lattice division of bitmap into fixed and variable rectangles ##
4893#Param dst destination Rect of image to draw to ##
4894#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4895 and so on; or nullptr
4896##
Cary Clark8032b982017-07-28 11:04:54 -04004897
4898#Example
4899#Height 128
4900#Description
4901 The leftmost image is smaller than center; only corners are drawn, all scaled to fit.
Cary Clarkce101242017-09-01 15:51:02 -04004902 The second image equals the size of center; only corners are drawn without scaling.
4903 The remaining images are larger than center. All corners draw without scaling. The sides
Cary Clark8032b982017-07-28 11:04:54 -04004904 are scaled if needed to take up the remaining space; the center is transparent.
4905##
Cary Clarkbad5ad72017-08-03 17:14:08 -04004906void draw(SkCanvas* canvas) {
4907 SkIRect center = { 20, 10, 50, 40 };
4908 SkBitmap bitmap;
4909 bitmap.allocPixels(SkImageInfo::MakeN32Premul(60, 60));
4910 SkCanvas bitCanvas(bitmap);
4911 SkPaint paint;
4912 SkColor gray = 0xFF000000;
4913 int left = 0;
4914 for (auto right: { center.fLeft, center.fRight, bitmap.width() } ) {
4915 int top = 0;
4916 for (auto bottom: { center.fTop, center.fBottom, bitmap.height() } ) {
4917 paint.setColor(gray);
4918 bitCanvas.drawIRect(SkIRect::MakeLTRB(left, top, right, bottom), paint);
4919 gray += 0x001f1f1f;
4920 top = bottom;
4921 }
4922 left = right;
4923 }
4924 const int xDivs[] = { center.fLeft, center.fRight };
4925 const int yDivs[] = { center.fTop, center.fBottom };
4926 SkCanvas::Lattice::Flags flags[3][3];
4927 memset(flags, 0, sizeof(flags));
4928 flags[1][1] = SkCanvas::Lattice::kTransparent_Flags;
4929 SkCanvas::Lattice lattice = { xDivs, yDivs, flags[0], SK_ARRAY_COUNT(xDivs),
4930 SK_ARRAY_COUNT(yDivs), nullptr };
4931 sk_sp<SkImage> image = SkImage::MakeFromBitmap(bitmap);
4932 SkImage* imagePtr = image.get();
4933 for (auto dest: { 20, 30, 40, 60, 90 } ) {
4934 canvas->drawImageNine(imagePtr, center, SkRect::MakeWH(dest, dest), nullptr);
4935 canvas->translate(dest + 4, 0);
4936 }
Cary Clark8032b982017-07-28 11:04:54 -04004937}
4938##
4939
Cary Clark2ade9972017-11-02 17:49:34 -04004940#SeeAlso drawBitmapLattice drawImage drawImageNine Lattice
Cary Clark8032b982017-07-28 11:04:54 -04004941
4942##
4943
4944#Topic Draw_Image ##
4945
4946# ------------------------------------------------------------------------------
4947
4948#Method void drawText(const void* text, size_t byteLength, SkScalar x, SkScalar y,
4949 const SkPaint& paint)
4950
4951Draw text, with origin at (x, y), using Clip, Matrix, and Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004952
Cary Clarkbc5697d2017-10-04 14:31:33 -04004953text meaning depends on Paint_Text_Encoding; by default, text is encoded as
Cary Clarkbad5ad72017-08-03 17:14:08 -04004954UTF-8.
Cary Clark8032b982017-07-28 11:04:54 -04004955
Cary Clarkbad5ad72017-08-03 17:14:08 -04004956x and y meaning depends on Paint_Text_Align and Paint_Vertical_Text; by default
Cary Clarkbc5697d2017-10-04 14:31:33 -04004957text draws left to right, positioning the first glyph left side bearing at x
Cary Clarkbad5ad72017-08-03 17:14:08 -04004958and its baseline at y. Text size is affected by Matrix and Paint_Text_Size.
4959
4960All elements of paint: Path_Effect, Rasterizer, Mask_Filter, Shader,
4961Color_Filter, Image_Filter, and Draw_Looper; apply to text. By default, draws
Cary Clarkce101242017-09-01 15:51:02 -04004962filled 12 point black Glyphs.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004963
Cary Clarkce101242017-09-01 15:51:02 -04004964#Param text character code points or Glyphs drawn ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04004965#Param byteLength byte length of text array ##
4966#Param x start of text on x-axis ##
4967#Param y start of text on y-axis ##
4968#Param paint text size, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04004969
4970#Example
4971#Height 200
4972#Description
4973 The same text is drawn varying Paint_Text_Size and varying
4974 Matrix.
4975##
Cary Clarkbad5ad72017-08-03 17:14:08 -04004976void draw(SkCanvas* canvas) {
4977 SkPaint paint;
4978 paint.setAntiAlias(true);
4979 float textSizes[] = { 12, 18, 24, 36 };
4980 for (auto size: textSizes ) {
4981 paint.setTextSize(size);
4982 canvas->drawText("Aa", 2, 10, 20, paint);
4983 canvas->translate(0, size * 2);
4984 }
4985 paint.reset();
4986 paint.setAntiAlias(true);
4987 float yPos = 20;
4988 for (auto size: textSizes ) {
4989 float scale = size / 12.f;
4990 canvas->resetMatrix();
4991 canvas->translate(100, 0);
4992 canvas->scale(scale, scale);
4993 canvas->drawText("Aa", 2, 10 / scale, yPos / scale, paint);
4994 yPos += size * 2;
4995 }
4996}
Cary Clark8032b982017-07-28 11:04:54 -04004997##
4998
Cary Clark2ade9972017-11-02 17:49:34 -04004999#SeeAlso drawString drawPosText drawPosTextH drawTextBlob drawTextOnPath drawTextRSXform
Cary Clark8032b982017-07-28 11:04:54 -04005000
5001##
5002
5003#Method void drawString(const char* string, SkScalar x, SkScalar y, const SkPaint& paint)
5004
Cary Clarkbad5ad72017-08-03 17:14:08 -04005005Draw null terminated string, with origin at (x, y), using Clip, Matrix, and
5006Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04005007
Cary Clarkbc5697d2017-10-04 14:31:33 -04005008string meaning depends on Paint_Text_Encoding; by default, strings are encoded
5009as UTF-8. Other values of Paint_Text_Encoding are unlikely to produce the desired
Cary Clarkbad5ad72017-08-03 17:14:08 -04005010results, since zero bytes may be embedded in the string.
Cary Clark8032b982017-07-28 11:04:54 -04005011
Cary Clarkbad5ad72017-08-03 17:14:08 -04005012x and y meaning depends on Paint_Text_Align and Paint_Vertical_Text; by default
Cary Clarkbc5697d2017-10-04 14:31:33 -04005013string draws left to right, positioning the first glyph left side bearing at x
Cary Clarkbad5ad72017-08-03 17:14:08 -04005014and its baseline at y. Text size is affected by Matrix and Paint_Text_Size.
5015
5016All elements of paint: Path_Effect, Rasterizer, Mask_Filter, Shader,
5017Color_Filter, Image_Filter, and Draw_Looper; apply to text. By default, draws
Cary Clarkce101242017-09-01 15:51:02 -04005018filled 12 point black Glyphs.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005019
Cary Clarkce101242017-09-01 15:51:02 -04005020#Param string character code points or Glyphs drawn,
Cary Clarkbad5ad72017-08-03 17:14:08 -04005021 ending with a char value of zero
5022##
5023#Param x start of string on x-axis ##
5024#Param y start of string on y-axis ##
5025#Param paint text size, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005026
5027#Example
5028 SkPaint paint;
5029 canvas->drawString("a small hello", 20, 20, paint);
5030##
5031
Cary Clark2ade9972017-11-02 17:49:34 -04005032#SeeAlso drawText drawPosText drawPosTextH drawTextBlob drawTextOnPath drawTextRSXform
Cary Clark8032b982017-07-28 11:04:54 -04005033
5034##
5035
5036#Method void drawString(const SkString& string, SkScalar x, SkScalar y, const SkPaint& paint)
5037
Cary Clarkbad5ad72017-08-03 17:14:08 -04005038Draw null terminated string, with origin at (x, y), using Clip, Matrix, and
5039Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04005040
Cary Clarkbc5697d2017-10-04 14:31:33 -04005041string meaning depends on Paint_Text_Encoding; by default, strings are encoded
5042as UTF-8. Other values of Paint_Text_Encoding are unlikely to produce the desired
Cary Clarkbad5ad72017-08-03 17:14:08 -04005043results, since zero bytes may be embedded in the string.
Cary Clark8032b982017-07-28 11:04:54 -04005044
Cary Clarkbad5ad72017-08-03 17:14:08 -04005045x and y meaning depends on Paint_Text_Align and Paint_Vertical_Text; by default
Cary Clarkbc5697d2017-10-04 14:31:33 -04005046string draws left to right, positioning the first glyph left side bearing at x
Cary Clarkbad5ad72017-08-03 17:14:08 -04005047and its baseline at y. Text size is affected by Matrix and Paint_Text_Size.
5048
5049All elements of paint: Path_Effect, Rasterizer, Mask_Filter, Shader,
5050Color_Filter, Image_Filter, and Draw_Looper; apply to text. By default, draws
Cary Clarkce101242017-09-01 15:51:02 -04005051filled 12 point black Glyphs.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005052
Cary Clarkce101242017-09-01 15:51:02 -04005053#Param string character code points or Glyphs drawn,
Cary Clarkbad5ad72017-08-03 17:14:08 -04005054 ending with a char value of zero
5055##
5056#Param x start of string on x-axis ##
5057#Param y start of string on y-axis ##
5058#Param paint text size, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005059
5060#Example
5061 SkPaint paint;
5062 SkString string("a small hello");
5063 canvas->drawString(string, 20, 20, paint);
5064##
5065
Cary Clark2ade9972017-11-02 17:49:34 -04005066#SeeAlso drawText drawPosText drawPosTextH drawTextBlob drawTextOnPath drawTextRSXform
Cary Clark8032b982017-07-28 11:04:54 -04005067
5068##
5069
5070# ------------------------------------------------------------------------------
5071
5072#Method void drawPosText(const void* text, size_t byteLength, const SkPoint pos[],
5073 const SkPaint& paint)
5074
Cary Clarkbad5ad72017-08-03 17:14:08 -04005075Draw each glyph in text with the origin in pos array, using Clip, Matrix, and
Cary Clarkce101242017-09-01 15:51:02 -04005076Paint paint. The number of entries in pos array must match the number of Glyphs
Cary Clarkbad5ad72017-08-03 17:14:08 -04005077described by byteLength of text.
Cary Clark8032b982017-07-28 11:04:54 -04005078
Cary Clarkbc5697d2017-10-04 14:31:33 -04005079text meaning depends on Paint_Text_Encoding; by default, text is encoded as
Cary Clarkbad5ad72017-08-03 17:14:08 -04005080UTF-8. pos elements' meaning depends on Paint_Text_Align and Paint_Vertical_Text;
Cary Clarkbc5697d2017-10-04 14:31:33 -04005081by default each glyph left side bearing is positioned at x and its
Cary Clarkbad5ad72017-08-03 17:14:08 -04005082baseline is positioned at y. Text size is affected by Matrix and
5083Paint_Text_Size.
Cary Clark8032b982017-07-28 11:04:54 -04005084
Cary Clarkbad5ad72017-08-03 17:14:08 -04005085All elements of paint: Path_Effect, Rasterizer, Mask_Filter, Shader,
5086Color_Filter, Image_Filter, and Draw_Looper; apply to text. By default, draws
Cary Clarkce101242017-09-01 15:51:02 -04005087filled 12 point black Glyphs.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005088
5089Layout engines such as Harfbuzz typically position each glyph
Cary Clarkbc5697d2017-10-04 14:31:33 -04005090rather than using the font advance widths.
Cary Clark8032b982017-07-28 11:04:54 -04005091
Cary Clarkce101242017-09-01 15:51:02 -04005092#Param text character code points or Glyphs drawn ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005093#Param byteLength byte length of text array ##
5094#Param pos array of glyph origins ##
5095#Param paint text size, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005096
5097#Example
5098#Height 120
Cary Clarkbad5ad72017-08-03 17:14:08 -04005099void draw(SkCanvas* canvas) {
5100 const char hello[] = "HeLLo!";
5101 const SkPoint pos[] = { {40, 100}, {82, 95}, {115, 110}, {130, 95}, {145, 85},
5102 {172, 100} };
5103 SkPaint paint;
5104 paint.setTextSize(60);
5105 canvas->drawPosText(hello, strlen(hello), pos, paint);
Cary Clark8032b982017-07-28 11:04:54 -04005106}
5107##
5108
Cary Clark2ade9972017-11-02 17:49:34 -04005109#SeeAlso drawText drawPosTextH drawTextBlob drawTextOnPath drawTextRSXform
Cary Clark8032b982017-07-28 11:04:54 -04005110
5111##
5112
5113# ------------------------------------------------------------------------------
5114
5115#Method void drawPosTextH(const void* text, size_t byteLength, const SkScalar xpos[], SkScalar constY,
5116 const SkPaint& paint)
5117
Cary Clarkbad5ad72017-08-03 17:14:08 -04005118Draw each glyph in text with its (x, y) origin composed from xpos array and
5119constY, using Clip, Matrix, and Paint paint. The number of entries in xpos array
Cary Clarkce101242017-09-01 15:51:02 -04005120must match the number of Glyphs described by byteLength of text.
Cary Clark8032b982017-07-28 11:04:54 -04005121
Cary Clarkbc5697d2017-10-04 14:31:33 -04005122text meaning depends on Paint_Text_Encoding; by default, text is encoded as
Cary Clarkce101242017-09-01 15:51:02 -04005123UTF-8. xpos elements' meaning depends on Paint_Text_Align and Paint_Vertical_Text;
Cary Clarkbc5697d2017-10-04 14:31:33 -04005124by default each glyph left side bearing is positioned at an xpos element and
Cary Clarkbad5ad72017-08-03 17:14:08 -04005125its baseline is positioned at constY. Text size is affected by Matrix and
5126Paint_Text_Size.
Cary Clark8032b982017-07-28 11:04:54 -04005127
Cary Clarkbad5ad72017-08-03 17:14:08 -04005128All elements of paint: Path_Effect, Rasterizer, Mask_Filter, Shader,
5129Color_Filter, Image_Filter, and Draw_Looper; apply to text. By default, draws
Cary Clarkce101242017-09-01 15:51:02 -04005130filled 12 point black Glyphs.
Cary Clark8032b982017-07-28 11:04:54 -04005131
Cary Clarkbad5ad72017-08-03 17:14:08 -04005132Layout engines such as Harfbuzz typically position each glyph
Cary Clarkbc5697d2017-10-04 14:31:33 -04005133rather than using the font advance widths if all Glyphs share the same
Cary Clarkbad5ad72017-08-03 17:14:08 -04005134baseline.
5135
Cary Clarkce101242017-09-01 15:51:02 -04005136#Param text character code points or Glyphs drawn ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005137#Param byteLength byte length of text array ##
5138#Param xpos array of x positions, used to position each glyph ##
5139#Param constY shared y coordinate for all of x positions ##
5140#Param paint text size, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005141
5142#Example
5143#Height 40
Cary Clarkbad5ad72017-08-03 17:14:08 -04005144 void draw(SkCanvas* canvas) {
5145 SkScalar xpos[] = { 20, 40, 80, 160 };
5146 SkPaint paint;
5147 canvas->drawPosTextH("XXXX", 4, xpos, 20, paint);
5148 }
Cary Clark8032b982017-07-28 11:04:54 -04005149##
5150
Cary Clark2ade9972017-11-02 17:49:34 -04005151#SeeAlso drawText drawPosText drawTextBlob drawTextOnPath drawTextRSXform
Cary Clark8032b982017-07-28 11:04:54 -04005152
5153##
5154
5155# ------------------------------------------------------------------------------
5156
5157#Method void drawTextOnPathHV(const void* text, size_t byteLength, const SkPath& path, SkScalar hOffset,
5158 SkScalar vOffset, const SkPaint& paint)
5159
5160Draw text on Path path, using Clip, Matrix, and Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04005161
Cary Clarkbad5ad72017-08-03 17:14:08 -04005162Origin of text is at distance hOffset along the path, offset by a perpendicular
5163vector of length vOffset. If the path section corresponding the glyph advance is
5164curved, the glyph is drawn curved to match; control points in the glyph are
Cary Clarkbc5697d2017-10-04 14:31:33 -04005165mapped to projected points parallel to the path. If the text advance is larger
Cary Clarkbad5ad72017-08-03 17:14:08 -04005166than the path length, the excess text is clipped.
5167
Cary Clarkbc5697d2017-10-04 14:31:33 -04005168text meaning depends on Paint_Text_Encoding; by default, text is encoded as
Cary Clarkbad5ad72017-08-03 17:14:08 -04005169UTF-8. Origin meaning depends on Paint_Text_Align and Paint_Vertical_Text; by
Cary Clarkbc5697d2017-10-04 14:31:33 -04005170default text positions the first glyph left side bearing at origin x and its
Cary Clark8032b982017-07-28 11:04:54 -04005171baseline at origin y. Text size is affected by Matrix and Paint_Text_Size.
5172
Cary Clarkbad5ad72017-08-03 17:14:08 -04005173All elements of paint: Path_Effect, Rasterizer, Mask_Filter, Shader,
5174Color_Filter, Image_Filter, and Draw_Looper; apply to text. By default, draws
Cary Clarkce101242017-09-01 15:51:02 -04005175filled 12 point black Glyphs.
Cary Clark8032b982017-07-28 11:04:54 -04005176
Cary Clarkce101242017-09-01 15:51:02 -04005177#Param text character code points or Glyphs drawn ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005178#Param byteLength byte length of text array ##
5179#Param path Path providing text baseline ##
5180#Param hOffset distance along path to offset origin ##
5181#Param vOffset offset of text above (if negative) or below (if positive) the path ##
5182#Param paint text size, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005183
5184#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04005185 void draw(SkCanvas* canvas) {
5186 const char aero[] = "correo a" "\xC3" "\xA9" "reo";
5187 const size_t len = sizeof(aero) - 1;
5188 SkPath path;
5189 path.addOval({43-26, 43-26, 43+26, 43+26}, SkPath::kCW_Direction, 3);
5190 SkPaint paint;
5191 paint.setTextSize(24);
5192 for (auto offset : { 0, 10, 20 } ) {
5193 canvas->drawTextOnPathHV(aero, len, path, 0, -offset, paint);
5194 canvas->translate(70 + offset, 70 + offset);
5195 }
5196 }
Cary Clark8032b982017-07-28 11:04:54 -04005197##
5198
Cary Clark2ade9972017-11-02 17:49:34 -04005199#SeeAlso drawTextOnPath drawText drawPosTextH drawTextBlob drawTextRSXform
Cary Clark8032b982017-07-28 11:04:54 -04005200
5201##
5202
5203# ------------------------------------------------------------------------------
5204
5205#Method void drawTextOnPath(const void* text, size_t byteLength, const SkPath& path,
5206 const SkMatrix* matrix, const SkPaint& paint)
5207
5208Draw text on Path path, using Clip, Matrix, and Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04005209
Cary Clarkbad5ad72017-08-03 17:14:08 -04005210Origin of text is at beginning of path offset by matrix, if provided, before it
5211is mapped to path. If the path section corresponding the glyph advance is
5212curved, the glyph is drawn curved to match; control points in the glyph are
Cary Clarkbc5697d2017-10-04 14:31:33 -04005213mapped to projected points parallel to the path. If the text advance is larger
Cary Clarkbad5ad72017-08-03 17:14:08 -04005214than the path length, the excess text is clipped.
5215
Cary Clarkbc5697d2017-10-04 14:31:33 -04005216text meaning depends on Paint_Text_Encoding; by default, text is encoded as
Cary Clarkbad5ad72017-08-03 17:14:08 -04005217UTF-8. Origin meaning depends on Paint_Text_Align and Paint_Vertical_Text; by
Cary Clarkbc5697d2017-10-04 14:31:33 -04005218default text positions the first glyph left side bearing at origin x and its
Cary Clark8032b982017-07-28 11:04:54 -04005219baseline at origin y. Text size is affected by Matrix and Paint_Text_Size.
5220
Cary Clarkbad5ad72017-08-03 17:14:08 -04005221All elements of paint: Path_Effect, Rasterizer, Mask_Filter, Shader,
5222Color_Filter, Image_Filter, and Draw_Looper; apply to text. By default, draws
Cary Clarkce101242017-09-01 15:51:02 -04005223filled 12 point black Glyphs.
Cary Clark8032b982017-07-28 11:04:54 -04005224
Cary Clarkce101242017-09-01 15:51:02 -04005225#Param text character code points or Glyphs drawn ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005226#Param byteLength byte length of text array ##
5227#Param path Path providing text baseline ##
Cary Clarkce101242017-09-01 15:51:02 -04005228#Param matrix transform of Glyphs before mapping to path; may be nullptr
Cary Clarka523d2d2017-08-30 08:58:10 -04005229 to use identity Matrix
Cary Clarkbad5ad72017-08-03 17:14:08 -04005230##
5231#Param paint text size, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005232
5233#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04005234 void draw(SkCanvas* canvas) {
5235 const char roller[] = "rollercoaster";
5236 const size_t len = sizeof(roller) - 1;
5237 SkPath path;
5238 path.cubicTo(40, -80, 120, 80, 160, -40);
5239 SkPaint paint;
5240 paint.setTextSize(32);
5241 paint.setStyle(SkPaint::kStroke_Style);
5242 SkMatrix matrix;
5243 matrix.setIdentity();
5244 for (int i = 0; i < 3; ++i) {
5245 canvas->translate(25, 60);
5246 canvas->drawPath(path, paint);
5247 canvas->drawTextOnPath(roller, len, path, &matrix, paint);
5248 matrix.preTranslate(0, 10);
5249 }
5250 }
Cary Clark8032b982017-07-28 11:04:54 -04005251##
5252
Cary Clark2ade9972017-11-02 17:49:34 -04005253#SeeAlso drawTextOnPathHV drawText drawPosTextH drawTextBlob drawTextRSXform
Cary Clark8032b982017-07-28 11:04:54 -04005254
5255##
5256
5257# ------------------------------------------------------------------------------
5258
5259#Method void drawTextRSXform(const void* text, size_t byteLength, const SkRSXform xform[],
5260 const SkRect* cullRect, const SkPaint& paint)
5261
5262Draw text, transforming each glyph by the corresponding SkRSXform,
5263using Clip, Matrix, and Paint paint.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005264
Cary Clark8032b982017-07-28 11:04:54 -04005265RSXform array specifies a separate square scale, rotation, and translation for
5266each glyph.
Cary Clark8032b982017-07-28 11:04:54 -04005267
Cary Clarkbad5ad72017-08-03 17:14:08 -04005268Optional Rect cullRect is a conservative bounds of text, taking into account
Cary Clarkce101242017-09-01 15:51:02 -04005269RSXform and paint. If cullRect is outside of Clip, canvas can skip drawing.
Cary Clark8032b982017-07-28 11:04:54 -04005270
Cary Clarkbad5ad72017-08-03 17:14:08 -04005271All elements of paint: Path_Effect, Rasterizer, Mask_Filter, Shader,
5272Color_Filter, Image_Filter, and Draw_Looper; apply to text. By default, draws
Cary Clarkce101242017-09-01 15:51:02 -04005273filled 12 point black Glyphs.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005274
Cary Clarkce101242017-09-01 15:51:02 -04005275#Param text character code points or Glyphs drawn ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005276#Param byteLength byte length of text array ##
5277#Param xform RSXform rotates, scales, and translates each glyph individually ##
5278#Param cullRect Rect bounds of text for efficient clipping; or nullptr ##
5279#Param paint text size, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005280
5281#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04005282void draw(SkCanvas* canvas) {
5283 const int iterations = 26;
5284 SkRSXform transforms[iterations];
5285 char alphabet[iterations];
5286 SkScalar angle = 0;
5287 SkScalar scale = 1;
5288 for (size_t i = 0; i < SK_ARRAY_COUNT(transforms); ++i) {
5289 const SkScalar s = SkScalarSin(angle) * scale;
5290 const SkScalar c = SkScalarCos(angle) * scale;
5291 transforms[i] = SkRSXform::Make(-c, -s, -s * 16, c * 16);
5292 angle += .45;
5293 scale += .2;
5294 alphabet[i] = 'A' + i;
5295 }
5296 SkPaint paint;
5297 paint.setTextAlign(SkPaint::kCenter_Align);
5298 canvas->translate(110, 138);
5299 canvas->drawTextRSXform(alphabet, sizeof(alphabet), transforms, nullptr, paint);
Cary Clark8032b982017-07-28 11:04:54 -04005300}
5301##
5302
Cary Clark2ade9972017-11-02 17:49:34 -04005303#SeeAlso drawTextOnPath drawTextOnPathHV drawText drawPosText drawTextBlob
Cary Clark8032b982017-07-28 11:04:54 -04005304
5305##
5306
5307# ------------------------------------------------------------------------------
5308
5309#Method void drawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y, const SkPaint& paint)
5310
5311Draw Text_Blob blob at (x, y), using Clip, Matrix, and Paint paint.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005312
Cary Clarkce101242017-09-01 15:51:02 -04005313blob contains Glyphs, their positions, and paint attributes specific to text:
Cary Clarkbad5ad72017-08-03 17:14:08 -04005314Typeface, Paint_Text_Size, Paint_Text_Scale_X, Paint_Text_Skew_X,
5315Paint_Text_Align, Paint_Hinting, Anti-alias, Paint_Fake_Bold,
5316Font_Embedded_Bitmaps, Full_Hinting_Spacing, LCD_Text, Linear_Text,
5317Subpixel_Text, and Paint_Vertical_Text.
Cary Clark8032b982017-07-28 11:04:54 -04005318
Cary Clark3cd22cc2017-12-01 11:49:58 -05005319Paint_Text_Encoding must be set to SkPaint::kGlyphID_TextEncoding.
5320
Cary Clark8032b982017-07-28 11:04:54 -04005321Elements of paint: Path_Effect, Rasterizer, Mask_Filter, Shader, Color_Filter,
5322Image_Filter, and Draw_Looper; apply to blob.
5323
Cary Clarkce101242017-09-01 15:51:02 -04005324#Param blob Glyphs, positions, and their paints' text size, typeface, and so on ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005325#Param x horizontal offset applied to blob ##
5326#Param y vertical offset applied to blob ##
5327#Param paint blend, color, stroking, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005328
5329#Example
5330#Height 120
Cary Clarkbad5ad72017-08-03 17:14:08 -04005331 void draw(SkCanvas* canvas) {
Cary Clark3cd22cc2017-12-01 11:49:58 -05005332 SkTextBlobBuilder textBlobBuilder;
5333 const char bunny[] = "/(^x^)\\";
5334 const int len = sizeof(bunny) - 1;
5335 uint16_t glyphs[len];
5336 SkPaint paint;
5337 paint.textToGlyphs(bunny, len, glyphs);
5338 paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
5339 int runs[] = { 3, 1, 3 };
5340 SkPoint textPos = { 20, 100 };
5341 int glyphIndex = 0;
5342 for (auto runLen : runs) {
5343 paint.setTextSize(1 == runLen ? 20 : 50);
5344 const SkTextBlobBuilder::RunBuffer& run =
5345 textBlobBuilder.allocRun(paint, runLen, textPos.fX, textPos.fY);
5346 memcpy(run.glyphs, &glyphs[glyphIndex], sizeof(glyphs[0]) * runLen);
5347 textPos.fX += paint.measureText(&glyphs[glyphIndex], sizeof(glyphs[0]) * runLen, nullptr);
5348 glyphIndex += runLen;
5349 }
5350 sk_sp<const SkTextBlob> blob = textBlobBuilder.make();
5351 paint.reset();
Cary Clarkbad5ad72017-08-03 17:14:08 -04005352 canvas->drawTextBlob(blob.get(), 0, 0, paint);
Cary Clark8032b982017-07-28 11:04:54 -04005353 }
5354##
5355
Cary Clark2ade9972017-11-02 17:49:34 -04005356#SeeAlso drawText drawPosText drawPosTextH
Cary Clark8032b982017-07-28 11:04:54 -04005357
5358##
5359
5360# ------------------------------------------------------------------------------
5361
5362#Method void drawTextBlob(const sk_sp<SkTextBlob>& blob, SkScalar x, SkScalar y, const SkPaint& paint)
5363
5364Draw Text_Blob blob at (x, y), using Clip, Matrix, and Paint paint.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005365
Cary Clarkce101242017-09-01 15:51:02 -04005366blob contains Glyphs, their positions, and paint attributes specific to text:
Cary Clarkbad5ad72017-08-03 17:14:08 -04005367Typeface, Paint_Text_Size, Paint_Text_Scale_X, Paint_Text_Skew_X,
5368Paint_Text_Align, Paint_Hinting, Anti-alias, Paint_Fake_Bold,
5369Font_Embedded_Bitmaps, Full_Hinting_Spacing, LCD_Text, Linear_Text,
5370Subpixel_Text, and Paint_Vertical_Text.
Cary Clark8032b982017-07-28 11:04:54 -04005371
Cary Clark3cd22cc2017-12-01 11:49:58 -05005372Paint_Text_Encoding must be set to SkPaint::kGlyphID_TextEncoding.
5373
Cary Clark8032b982017-07-28 11:04:54 -04005374Elements of paint: Path_Effect, Rasterizer, Mask_Filter, Shader, Color_Filter,
5375Image_Filter, and Draw_Looper; apply to blob.
5376
Cary Clarkce101242017-09-01 15:51:02 -04005377#Param blob Glyphs, positions, and their paints' text size, typeface, and so on ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005378#Param x horizontal offset applied to blob ##
5379#Param y vertical offset applied to blob ##
5380#Param paint blend, color, stroking, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005381
5382#Example
5383#Height 120
5384#Description
5385Paint attributes unrelated to text, like color, have no effect on paint in allocated Text_Blob.
5386Paint attributes related to text, like text size, have no effect on paint passed to drawTextBlob.
5387##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005388 void draw(SkCanvas* canvas) {
5389 SkTextBlobBuilder textBlobBuilder;
5390 SkPaint paint;
5391 paint.setTextSize(50);
5392 paint.setColor(SK_ColorRED);
Cary Clark3cd22cc2017-12-01 11:49:58 -05005393 paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
Cary Clarkbad5ad72017-08-03 17:14:08 -04005394 const SkTextBlobBuilder::RunBuffer& run =
5395 textBlobBuilder.allocRun(paint, 1, 20, 100);
5396 run.glyphs[0] = 20;
5397 sk_sp<const SkTextBlob> blob = textBlobBuilder.make();
5398 paint.setTextSize(10);
5399 paint.setColor(SK_ColorBLUE);
5400 canvas->drawTextBlob(blob.get(), 0, 0, paint);
5401 }
Cary Clark8032b982017-07-28 11:04:54 -04005402##
5403
Cary Clark2ade9972017-11-02 17:49:34 -04005404#SeeAlso drawText drawPosText drawPosTextH
Cary Clark8032b982017-07-28 11:04:54 -04005405
5406##
5407
5408# ------------------------------------------------------------------------------
5409
5410#Method void drawPicture(const SkPicture* picture)
5411
5412Draw Picture picture, using Clip and Matrix.
5413Clip and Matrix are unchanged by picture contents, as if
5414save() was called before and restore() was called after drawPicture.
5415
5416Picture records a series of draw commands for later playback.
5417
Cary Clarkbad5ad72017-08-03 17:14:08 -04005418#Param picture recorded drawing commands to play ##
Cary Clark8032b982017-07-28 11:04:54 -04005419
5420#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04005421void draw(SkCanvas* canvas) {
5422 SkPictureRecorder recorder;
5423 SkCanvas* recordingCanvas = recorder.beginRecording(50, 50);
5424 for (auto color : { SK_ColorRED, SK_ColorBLUE, 0xff007f00 } ) {
5425 SkPaint paint;
5426 paint.setColor(color);
5427 recordingCanvas->drawRect({10, 10, 30, 40}, paint);
5428 recordingCanvas->translate(10, 10);
5429 recordingCanvas->scale(1.2f, 1.4f);
5430 }
5431 sk_sp<SkPicture> playback = recorder.finishRecordingAsPicture();
5432 const SkPicture* playbackPtr = playback.get();
5433 canvas->drawPicture(playback);
5434 canvas->scale(2, 2);
5435 canvas->translate(50, 0);
5436 canvas->drawPicture(playback);
Cary Clark8032b982017-07-28 11:04:54 -04005437}
5438##
5439
Cary Clark2ade9972017-11-02 17:49:34 -04005440#SeeAlso drawDrawable SkPicture SkPicture::playback
Cary Clark8032b982017-07-28 11:04:54 -04005441
5442##
5443
5444# ------------------------------------------------------------------------------
5445
5446#Method void drawPicture(const sk_sp<SkPicture>& picture)
5447
5448Draw Picture picture, using Clip and Matrix.
5449Clip and Matrix are unchanged by picture contents, as if
5450save() was called before and restore() was called after drawPicture.
5451
5452Picture records a series of draw commands for later playback.
5453
Cary Clarkbad5ad72017-08-03 17:14:08 -04005454#Param picture recorded drawing commands to play ##
Cary Clark8032b982017-07-28 11:04:54 -04005455
5456#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04005457void draw(SkCanvas* canvas) {
5458 SkPictureRecorder recorder;
5459 SkCanvas* recordingCanvas = recorder.beginRecording(50, 50);
5460 for (auto color : { SK_ColorRED, SK_ColorBLUE, 0xff007f00 } ) {
5461 SkPaint paint;
5462 paint.setColor(color);
5463 recordingCanvas->drawRect({10, 10, 30, 40}, paint);
5464 recordingCanvas->translate(10, 10);
5465 recordingCanvas->scale(1.2f, 1.4f);
5466 }
5467 sk_sp<SkPicture> playback = recorder.finishRecordingAsPicture();
5468 canvas->drawPicture(playback);
5469 canvas->scale(2, 2);
5470 canvas->translate(50, 0);
5471 canvas->drawPicture(playback);
Cary Clark8032b982017-07-28 11:04:54 -04005472}
5473##
5474
Cary Clark2ade9972017-11-02 17:49:34 -04005475#SeeAlso drawDrawable SkPicture SkPicture::playback
Cary Clark8032b982017-07-28 11:04:54 -04005476
5477##
5478
5479# ------------------------------------------------------------------------------
5480
5481#Method void drawPicture(const SkPicture* picture, const SkMatrix* matrix, const SkPaint* paint)
5482
Cary Clarkbad5ad72017-08-03 17:14:08 -04005483Draw Picture picture, using Clip and Matrix; transforming picture with
5484Matrix matrix, if provided; and use Paint paint Color_Alpha, Color_Filter,
5485Image_Filter, and Blend_Mode, if provided.
Cary Clark8032b982017-07-28 11:04:54 -04005486
5487matrix transformation is equivalent to: save(), concat(), drawPicture, restore().
5488paint use is equivalent to: saveLayer, drawPicture, restore().
5489
Cary Clarkbad5ad72017-08-03 17:14:08 -04005490#Param picture recorded drawing commands to play ##
5491#Param matrix Matrix to rotate, scale, translate, and so on; may be nullptr ##
5492#Param paint Paint to apply transparency, filtering, and so on; may be nullptr ##
Cary Clark8032b982017-07-28 11:04:54 -04005493
5494#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04005495void draw(SkCanvas* canvas) {
5496 SkPaint paint;
5497 SkPictureRecorder recorder;
5498 SkCanvas* recordingCanvas = recorder.beginRecording(50, 50);
5499 for (auto color : { SK_ColorRED, SK_ColorBLUE, 0xff007f00 } ) {
5500 paint.setColor(color);
5501 recordingCanvas->drawRect({10, 10, 30, 40}, paint);
5502 recordingCanvas->translate(10, 10);
5503 recordingCanvas->scale(1.2f, 1.4f);
5504 }
5505 sk_sp<SkPicture> playback = recorder.finishRecordingAsPicture();
5506 const SkPicture* playbackPtr = playback.get();
5507 SkMatrix matrix;
5508 matrix.reset();
5509 for (auto alpha : { 70, 140, 210 } ) {
5510 paint.setAlpha(alpha);
5511 canvas->drawPicture(playbackPtr, &matrix, &paint);
5512 matrix.preTranslate(70, 70);
5513 }
Cary Clark8032b982017-07-28 11:04:54 -04005514}
5515##
5516
Cary Clark2ade9972017-11-02 17:49:34 -04005517#SeeAlso drawDrawable SkPicture SkPicture::playback
Cary Clark8032b982017-07-28 11:04:54 -04005518
5519##
5520
5521# ------------------------------------------------------------------------------
5522
5523#Method void drawPicture(const sk_sp<SkPicture>& picture, const SkMatrix* matrix, const SkPaint* paint)
5524
Cary Clarkbad5ad72017-08-03 17:14:08 -04005525Draw Picture picture, using Clip and Matrix; transforming picture with
5526Matrix matrix, if provided; and use Paint paint Color_Alpha, Color_Filter,
5527Image_Filter, and Blend_Mode, if provided.
Cary Clark8032b982017-07-28 11:04:54 -04005528
5529matrix transformation is equivalent to: save(), concat(), drawPicture, restore().
5530paint use is equivalent to: saveLayer, drawPicture, restore().
5531
Cary Clarkbad5ad72017-08-03 17:14:08 -04005532#Param picture recorded drawing commands to play ##
5533#Param matrix Matrix to rotate, scale, translate, and so on; may be nullptr ##
5534#Param paint Paint to apply transparency, filtering, and so on; may be nullptr ##
Cary Clark8032b982017-07-28 11:04:54 -04005535
5536#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04005537void draw(SkCanvas* canvas) {
5538 SkPaint paint;
5539 SkPictureRecorder recorder;
5540 SkCanvas* recordingCanvas = recorder.beginRecording(50, 50);
5541 for (auto color : { SK_ColorRED, SK_ColorBLUE, 0xff007f00 } ) {
5542 paint.setColor(color);
5543 recordingCanvas->drawRect({10, 10, 30, 40}, paint);
5544 recordingCanvas->translate(10, 10);
5545 recordingCanvas->scale(1.2f, 1.4f);
5546 }
5547 sk_sp<SkPicture> playback = recorder.finishRecordingAsPicture();
5548 SkMatrix matrix;
5549 matrix.reset();
5550 for (auto alpha : { 70, 140, 210 } ) {
5551 paint.setAlpha(alpha);
5552 canvas->drawPicture(playback, &matrix, &paint);
5553 matrix.preTranslate(70, 70);
5554 }
Cary Clark8032b982017-07-28 11:04:54 -04005555}
5556##
5557
Cary Clark2ade9972017-11-02 17:49:34 -04005558#SeeAlso drawDrawable SkPicture SkPicture::playback
Cary Clark8032b982017-07-28 11:04:54 -04005559
5560##
5561
5562# ------------------------------------------------------------------------------
5563
5564#Method void drawVertices(const SkVertices* vertices, SkBlendMode mode, const SkPaint& paint)
5565
5566Draw Vertices vertices, a triangle mesh, using Clip and Matrix.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005567If Vertices_Texs and Vertices_Colors are defined in vertices, and Paint paint
5568contains Shader, Blend_Mode mode combines Vertices_Colors with Shader.
Cary Clark8032b982017-07-28 11:04:54 -04005569
Cary Clarkbad5ad72017-08-03 17:14:08 -04005570#Param vertices triangle mesh to draw ##
5571#Param mode combines Vertices_Colors with Shader, if both are present ##
5572#Param paint specifies the Shader, used as Vertices texture; may be nullptr ##
Cary Clark8032b982017-07-28 11:04:54 -04005573
5574#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04005575void draw(SkCanvas* canvas) {
5576 SkPaint paint;
5577 SkPoint points[] = { { 0, 0 }, { 250, 0 }, { 100, 100 }, { 0, 250 } };
5578 SkColor colors[] = { SK_ColorRED, SK_ColorBLUE, SK_ColorYELLOW, SK_ColorCYAN };
5579 auto vertices = SkVertices::MakeCopy(SkVertices::kTriangleFan_VertexMode,
5580 SK_ARRAY_COUNT(points), points, nullptr, colors);
5581 canvas->drawVertices(vertices.get(), SkBlendMode::kSrc, paint);
5582}
Cary Clark8032b982017-07-28 11:04:54 -04005583##
5584
Cary Clark2ade9972017-11-02 17:49:34 -04005585#SeeAlso drawPatch drawPicture
Cary Clark8032b982017-07-28 11:04:54 -04005586
5587##
5588
5589# ------------------------------------------------------------------------------
5590
5591#Method void drawVertices(const sk_sp<SkVertices>& vertices, SkBlendMode mode, const SkPaint& paint)
5592
5593Draw Vertices vertices, a triangle mesh, using Clip and Matrix.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005594If Vertices_Texs and Vertices_Colors are defined in vertices, and Paint paint
5595contains Shader, Blend_Mode mode combines Vertices_Colors with Shader.
Cary Clark8032b982017-07-28 11:04:54 -04005596
Cary Clarkbad5ad72017-08-03 17:14:08 -04005597#Param vertices triangle mesh to draw ##
5598#Param mode combines Vertices_Colors with Shader, if both are present ##
5599#Param paint specifies the Shader, used as Vertices texture, may be nullptr ##
Cary Clark8032b982017-07-28 11:04:54 -04005600
5601#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04005602void draw(SkCanvas* canvas) {
5603 SkPaint paint;
5604 SkPoint points[] = { { 0, 0 }, { 250, 0 }, { 100, 100 }, { 0, 250 } };
5605 SkPoint texs[] = { { 0, 0 }, { 0, 250 }, { 250, 250 }, { 250, 0 } };
5606 SkColor colors[] = { SK_ColorRED, SK_ColorBLUE, SK_ColorYELLOW, SK_ColorCYAN };
5607 paint.setShader(SkGradientShader::MakeLinear(points, colors, nullptr, 4,
5608 SkShader::kClamp_TileMode));
5609 auto vertices = SkVertices::MakeCopy(SkVertices::kTriangleFan_VertexMode,
5610 SK_ARRAY_COUNT(points), points, texs, colors);
5611 canvas->drawVertices(vertices.get(), SkBlendMode::kDarken, paint);
Cary Clark8032b982017-07-28 11:04:54 -04005612}
5613##
5614
Cary Clark2ade9972017-11-02 17:49:34 -04005615#SeeAlso drawPatch drawPicture
Cary Clark8032b982017-07-28 11:04:54 -04005616
5617##
5618
5619# ------------------------------------------------------------------------------
5620
5621#Method void drawPatch(const SkPoint cubics[12], const SkColor colors[4],
5622 const SkPoint texCoords[4], SkBlendMode mode, const SkPaint& paint)
5623
Cary Clarka560c472017-11-27 10:44:06 -05005624Draws a Coons_Patch: the interpolation of four cubics with shared corners,
Cary Clark8032b982017-07-28 11:04:54 -04005625associating a color, and optionally a texture coordinate, with each corner.
5626
Cary Clarka560c472017-11-27 10:44:06 -05005627Coons_Patch uses Clip and Matrix, paint Shader, Color_Filter,
Cary Clarkbad5ad72017-08-03 17:14:08 -04005628Color_Alpha, Image_Filter, and Blend_Mode. If Shader is provided it is treated
Cary Clarka560c472017-11-27 10:44:06 -05005629as Coons_Patch texture; Blend_Mode mode combines Color colors and Shader if
Cary Clarkbad5ad72017-08-03 17:14:08 -04005630both are provided.
Cary Clark8032b982017-07-28 11:04:54 -04005631
Cary Clarkbc5697d2017-10-04 14:31:33 -04005632Point array cubics specifies four Cubics starting at the top-left corner,
Cary Clarkce101242017-09-01 15:51:02 -04005633in clockwise order, sharing every fourth point. The last Cubic ends at the
Cary Clarkbad5ad72017-08-03 17:14:08 -04005634first point.
Cary Clark8032b982017-07-28 11:04:54 -04005635
Cary Clarkbc5697d2017-10-04 14:31:33 -04005636Color array color associates colors with corners in top-left, top-right,
5637bottom-right, bottom-left order.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005638
5639If paint contains Shader, Point array texCoords maps Shader as texture to
Cary Clarkbc5697d2017-10-04 14:31:33 -04005640corners in top-left, top-right, bottom-right, bottom-left order.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005641
Cary Clarka523d2d2017-08-30 08:58:10 -04005642#Param cubics Path_Cubic array, sharing common points ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005643#Param colors Color array, one for each corner ##
Cary Clarkce101242017-09-01 15:51:02 -04005644#Param texCoords Point array of texture coordinates, mapping Shader to corners;
Cary Clarkbad5ad72017-08-03 17:14:08 -04005645 may be nullptr
Cary Clark579985c2017-07-31 11:48:27 -04005646#Param ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005647#Param mode Blend_Mode for colors, and for Shader if paint has one ##
5648#Param paint Shader, Color_Filter, Blend_Mode, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005649
5650#Example
5651#Image 5
Cary Clarkbad5ad72017-08-03 17:14:08 -04005652void draw(SkCanvas* canvas) {
5653 // SkBitmap source = cmbkygk;
5654 SkPaint paint;
5655 paint.setFilterQuality(kLow_SkFilterQuality);
5656 paint.setAntiAlias(true);
5657 SkPoint cubics[] = { { 3, 1 }, { 4, 2 }, { 5, 1 }, { 7, 3 },
5658 /* { 7, 3 }, */ { 6, 4 }, { 7, 5 }, { 5, 7 },
5659 /* { 5, 7 }, */ { 4, 6 }, { 3, 7 }, { 1, 5 },
5660 /* { 1, 5 }, */ { 2, 4 }, { 1, 3 }, /* { 3, 1 } */ };
5661 SkColor colors[] = { 0xbfff0000, 0xbf0000ff, 0xbfff00ff, 0xbf00ffff };
5662 SkPoint texCoords[] = { { -30, -30 }, { 162, -30}, { 162, 162}, { -30, 162} };
5663 paint.setShader(SkShader::MakeBitmapShader(source, SkShader::kClamp_TileMode,
5664 SkShader::kClamp_TileMode, nullptr));
5665 canvas->scale(15, 15);
5666 for (auto blend : { SkBlendMode::kSrcOver, SkBlendMode::kModulate, SkBlendMode::kXor } ) {
5667 canvas->drawPatch(cubics, colors, texCoords, blend, paint);
5668 canvas->translate(4, 4);
5669 }
Cary Clark8032b982017-07-28 11:04:54 -04005670}
5671##
5672
Cary Clark2ade9972017-11-02 17:49:34 -04005673#ToDo can patch use image filter? ##
5674#SeeAlso SeeAlso drawVertices drawPicture
Cary Clark8032b982017-07-28 11:04:54 -04005675
5676##
5677
5678# ------------------------------------------------------------------------------
5679
5680#Method void drawPatch(const SkPoint cubics[12], const SkColor colors[4],
5681 const SkPoint texCoords[4], const SkPaint& paint)
5682
Cary Clarka560c472017-11-27 10:44:06 -05005683Draws Cubic Coons_Patch: the interpolation of four cubics with shared corners,
Cary Clarkbad5ad72017-08-03 17:14:08 -04005684associating a color, and optionally a texture coordinate, with each corner.
Cary Clark8032b982017-07-28 11:04:54 -04005685
Cary Clarka560c472017-11-27 10:44:06 -05005686Coons_Patch uses Clip and Matrix, paint Shader, Color_Filter,
Cary Clarkbad5ad72017-08-03 17:14:08 -04005687Color_Alpha, Image_Filter, and Blend_Mode. If Shader is provided it is treated
Cary Clarka560c472017-11-27 10:44:06 -05005688as Coons_Patch texture; Blend_Mode mode combines Color colors and Shader if
Cary Clarkbad5ad72017-08-03 17:14:08 -04005689both are provided.
Cary Clark8032b982017-07-28 11:04:54 -04005690
Cary Clarkbc5697d2017-10-04 14:31:33 -04005691Point array cubics specifies four Cubics starting at the top-left corner,
Cary Clarkce101242017-09-01 15:51:02 -04005692in clockwise order, sharing every fourth point. The last Cubic ends at the
Cary Clarkbad5ad72017-08-03 17:14:08 -04005693first point.
5694
Cary Clarkbc5697d2017-10-04 14:31:33 -04005695Color array color associates colors with corners in top-left, top-right,
5696bottom-right, bottom-left order.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005697
5698If paint contains Shader, Point array texCoords maps Shader as texture to
Cary Clarkbc5697d2017-10-04 14:31:33 -04005699corners in top-left, top-right, bottom-right, bottom-left order.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005700
Cary Clarka523d2d2017-08-30 08:58:10 -04005701#Param cubics Path_Cubic array, sharing common points ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005702#Param colors Color array, one for each corner ##
Cary Clarkce101242017-09-01 15:51:02 -04005703#Param texCoords Point array of texture coordinates, mapping Shader to corners;
Cary Clarkbad5ad72017-08-03 17:14:08 -04005704 may be nullptr
Cary Clark579985c2017-07-31 11:48:27 -04005705#Param ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005706#Param paint Shader, Color_Filter, Blend_Mode, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005707
5708#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04005709void draw(SkCanvas* canvas) {
5710 SkPaint paint;
5711 paint.setAntiAlias(true);
5712 SkPoint cubics[] = { { 3, 1 }, { 4, 2 }, { 5, 1 }, { 7, 3 },
5713 /* { 7, 3 }, */ { 6, 4 }, { 7, 5 }, { 5, 7 },
5714 /* { 5, 7 }, */ { 4, 6 }, { 3, 7 }, { 1, 5 },
5715 /* { 1, 5 }, */ { 2, 4 }, { 1, 3 }, /* { 3, 1 } */ };
5716 SkColor colors[] = { SK_ColorRED, SK_ColorBLUE, SK_ColorYELLOW, SK_ColorCYAN };
5717 canvas->scale(30, 30);
5718 canvas->drawPatch(cubics, colors, nullptr, paint);
5719 SkPoint text[] = { {3,0.9f}, {4,2.5f}, {5,0.9f}, {7.5f,3.2f}, {5.5f,4.2f},
5720 {7.5f,5.2f}, {5,7.5f}, {4,5.9f}, {3,7.5f}, {0.5f,5.2f}, {2.5f,4.2f},
5721 {0.5f,3.2f} };
5722 paint.setTextSize(18.f / 30);
5723 paint.setTextAlign(SkPaint::kCenter_Align);
5724 for (int i = 0; i< 10; ++i) {
5725 char digit = '0' + i;
5726 canvas->drawText(&digit, 1, text[i].fX, text[i].fY, paint);
5727 }
5728 canvas->drawString("10", text[10].fX, text[10].fY, paint);
5729 canvas->drawString("11", text[11].fX, text[11].fY, paint);
5730 paint.setStyle(SkPaint::kStroke_Style);
5731 canvas->drawPoints(SkCanvas::kPolygon_PointMode, 12, cubics, paint);
5732 canvas->drawLine(cubics[11].fX, cubics[11].fY, cubics[0].fX, cubics[0].fY, paint);
Cary Clark8032b982017-07-28 11:04:54 -04005733}
5734##
5735
5736#Example
5737#Image 6
Cary Clarkbad5ad72017-08-03 17:14:08 -04005738void draw(SkCanvas* canvas) {
5739 // SkBitmap source = checkerboard;
5740 SkPaint paint;
5741 paint.setFilterQuality(kLow_SkFilterQuality);
5742 paint.setAntiAlias(true);
5743 SkPoint cubics[] = { { 3, 1 }, { 4, 2 }, { 5, 1 }, { 7, 3 },
5744 /* { 7, 3 }, */ { 6, 4 }, { 7, 5 }, { 5, 7 },
5745 /* { 5, 7 }, */ { 4, 6 }, { 3, 7 }, { 1, 5 },
5746 /* { 1, 5 }, */ { 2, 4 }, { 1, 3 }, /* { 3, 1 } */ };
5747 SkPoint texCoords[] = { { 0, 0 }, { 0, 62}, { 62, 62}, { 62, 0 } };
5748 paint.setShader(SkShader::MakeBitmapShader(source, SkShader::kClamp_TileMode,
5749 SkShader::kClamp_TileMode, nullptr));
5750 canvas->scale(30, 30);
5751 canvas->drawPatch(cubics, nullptr, texCoords, paint);
Cary Clark8032b982017-07-28 11:04:54 -04005752}
5753##
5754
Cary Clark2ade9972017-11-02 17:49:34 -04005755#ToDo can patch use image filter? ##
5756#SeeAlso SeeAlso drawVertices drawPicture
Cary Clark8032b982017-07-28 11:04:54 -04005757
5758##
5759
5760# ------------------------------------------------------------------------------
5761
5762#Method void drawAtlas(const SkImage* atlas, const SkRSXform xform[], const SkRect tex[],
5763 const SkColor colors[], int count, SkBlendMode mode, const SkRect* cullRect,
5764 const SkPaint* paint)
5765
5766Draw a set of sprites from atlas, using Clip, Matrix, and optional Paint paint.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005767paint uses Anti-alias, Color_Alpha, Color_Filter, Image_Filter, and Blend_Mode
5768to draw, if present. For each entry in the array, Rect tex locates sprite in
5769atlas, and RSXform xform transforms it into destination space.
5770
Cary Clark8032b982017-07-28 11:04:54 -04005771xform, text, and colors if present, must contain count entries.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005772Optional colors are applied for each sprite using Blend_Mode.
Cary Clark8032b982017-07-28 11:04:54 -04005773Optional cullRect is a conservative bounds of all transformed sprites.
Cary Clarkce101242017-09-01 15:51:02 -04005774If cullRect is outside of Clip, canvas can skip drawing.
Cary Clark8032b982017-07-28 11:04:54 -04005775
Cary Clarkbad5ad72017-08-03 17:14:08 -04005776#Param atlas Image containing sprites ##
5777#Param xform RSXform mappings for sprites in atlas ##
5778#Param tex Rect locations of sprites in atlas ##
Cary Clark6fc50412017-09-21 12:31:06 -04005779#Param colors one per sprite, blended with sprite using Blend_Mode; may be nullptr ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005780#Param count number of sprites to draw ##
5781#Param mode Blend_Mode combining colors and sprites ##
Cary Clark6fc50412017-09-21 12:31:06 -04005782#Param cullRect bounds of transformed sprites for efficient clipping; may be nullptr ##
5783#Param paint Color_Filter, Image_Filter, Blend_Mode, and so on; may be nullptr ##
Cary Clark8032b982017-07-28 11:04:54 -04005784
5785#Example
5786#Image 3
Cary Clarkbad5ad72017-08-03 17:14:08 -04005787void draw(SkCanvas* canvas) {
5788 // SkBitmap source = mandrill;
5789 SkRSXform xforms[] = { { .5f, 0, 0, 0 }, {0, .5f, 200, 100 } };
5790 SkRect tex[] = { { 0, 0, 250, 250 }, { 0, 0, 250, 250 } };
5791 SkColor colors[] = { 0x7f55aa00, 0x7f3333bf };
5792 const SkImage* imagePtr = image.get();
5793 canvas->drawAtlas(imagePtr, xforms, tex, colors, 2, SkBlendMode::kSrcOver, nullptr, nullptr);
Cary Clark8032b982017-07-28 11:04:54 -04005794}
5795##
5796
Cary Clark2ade9972017-11-02 17:49:34 -04005797#SeeAlso drawBitmap drawImage
Cary Clark8032b982017-07-28 11:04:54 -04005798
5799##
5800
5801# ------------------------------------------------------------------------------
5802
5803#Method void drawAtlas(const sk_sp<SkImage>& atlas, const SkRSXform xform[], const SkRect tex[],
5804 const SkColor colors[], int count, SkBlendMode mode, const SkRect* cullRect,
5805 const SkPaint* paint)
5806
5807Draw a set of sprites from atlas, using Clip, Matrix, and optional Paint paint.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005808paint uses Anti-alias, Color_Alpha, Color_Filter, Image_Filter, and Blend_Mode
5809to draw, if present. For each entry in the array, Rect tex locates sprite in
5810atlas, and RSXform xform transforms it into destination space.
5811
Cary Clark8032b982017-07-28 11:04:54 -04005812xform, text, and colors if present, must contain count entries.
5813Optional colors is applied for each sprite using Blend_Mode.
5814Optional cullRect is a conservative bounds of all transformed sprites.
Cary Clarkce101242017-09-01 15:51:02 -04005815If cullRect is outside of Clip, canvas can skip drawing.
Cary Clark8032b982017-07-28 11:04:54 -04005816
Cary Clarkbad5ad72017-08-03 17:14:08 -04005817#Param atlas Image containing sprites ##
5818#Param xform RSXform mappings for sprites in atlas ##
5819#Param tex Rect locations of sprites in atlas ##
Cary Clark6fc50412017-09-21 12:31:06 -04005820#Param colors one per sprite, blended with sprite using Blend_Mode; may be nullptr ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005821#Param count number of sprites to draw ##
5822#Param mode Blend_Mode combining colors and sprites ##
Cary Clark6fc50412017-09-21 12:31:06 -04005823#Param cullRect bounds of transformed sprites for efficient clipping; may be nullptr ##
5824#Param paint Color_Filter, Image_Filter, Blend_Mode, and so on; may be nullptr ##
Cary Clark8032b982017-07-28 11:04:54 -04005825
5826#Example
5827#Image 3
Cary Clarkbad5ad72017-08-03 17:14:08 -04005828void draw(SkCanvas* canvas) {
5829 // SkBitmap source = mandrill;
5830 SkRSXform xforms[] = { { .5f, 0, 0, 0 }, {0, .5f, 200, 100 } };
5831 SkRect tex[] = { { 0, 0, 250, 250 }, { 0, 0, 250, 250 } };
5832 SkColor colors[] = { 0x7f55aa00, 0x7f3333bf };
5833 SkPaint paint;
5834 paint.setAlpha(127);
5835 canvas->drawAtlas(image, xforms, tex, colors, 2, SkBlendMode::kPlus, nullptr, &paint);
Cary Clark8032b982017-07-28 11:04:54 -04005836}
5837##
5838
5839#ToDo bug in example on cpu side, gpu looks ok ##
5840
Cary Clark2ade9972017-11-02 17:49:34 -04005841#SeeAlso drawBitmap drawImage
5842
Cary Clark8032b982017-07-28 11:04:54 -04005843##
5844
5845# ------------------------------------------------------------------------------
5846
5847#Method void drawAtlas(const SkImage* atlas, const SkRSXform xform[], const SkRect tex[], int count,
5848 const SkRect* cullRect, const SkPaint* paint)
5849
5850Draw a set of sprites from atlas, using Clip, Matrix, and optional Paint paint.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005851paint uses Anti-alias, Color_Alpha, Color_Filter, Image_Filter, and Blend_Mode
5852to draw, if present. For each entry in the array, Rect tex locates sprite in
5853atlas, and RSXform xform transforms it into destination space.
5854
Cary Clark8032b982017-07-28 11:04:54 -04005855xform and text must contain count entries.
5856Optional cullRect is a conservative bounds of all transformed sprites.
Cary Clarkce101242017-09-01 15:51:02 -04005857If cullRect is outside of Clip, canvas can skip drawing.
Cary Clark8032b982017-07-28 11:04:54 -04005858
Cary Clarkbad5ad72017-08-03 17:14:08 -04005859#Param atlas Image containing sprites ##
5860#Param xform RSXform mappings for sprites in atlas ##
5861#Param tex Rect locations of sprites in atlas ##
5862#Param count number of sprites to draw ##
Cary Clark6fc50412017-09-21 12:31:06 -04005863#Param cullRect bounds of transformed sprites for efficient clipping; may be nullptr ##
5864#Param paint Color_Filter, Image_Filter, Blend_Mode, and so on; may be nullptr ##
Cary Clark8032b982017-07-28 11:04:54 -04005865
5866#Example
5867#Image 3
Cary Clarkbad5ad72017-08-03 17:14:08 -04005868void draw(SkCanvas* canvas) {
5869 // sk_sp<SkImage> image = mandrill;
5870 SkRSXform xforms[] = { { .5f, 0, 0, 0 }, {0, .5f, 200, 100 } };
5871 SkRect tex[] = { { 0, 0, 250, 250 }, { 0, 0, 250, 250 } };
5872 const SkImage* imagePtr = image.get();
5873 canvas->drawAtlas(imagePtr, xforms, tex, 2, nullptr, nullptr);
Cary Clark8032b982017-07-28 11:04:54 -04005874}
5875##
5876
Cary Clark2ade9972017-11-02 17:49:34 -04005877#SeeAlso drawBitmap drawImage
Cary Clark8032b982017-07-28 11:04:54 -04005878
5879##
5880
5881# ------------------------------------------------------------------------------
5882
5883#Method void drawAtlas(const sk_sp<SkImage>& atlas, const SkRSXform xform[], const SkRect tex[],
5884 int count, const SkRect* cullRect, const SkPaint* paint)
5885
5886Draw a set of sprites from atlas, using Clip, Matrix, and optional Paint paint.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005887paint uses Anti-alias, Color_Alpha, Color_Filter, Image_Filter, and Blend_Mode
5888to draw, if present. For each entry in the array, Rect tex locates sprite in
5889atlas, and RSXform xform transforms it into destination space.
5890
Cary Clark8032b982017-07-28 11:04:54 -04005891xform and text must contain count entries.
5892Optional cullRect is a conservative bounds of all transformed sprites.
Cary Clarkce101242017-09-01 15:51:02 -04005893If cullRect is outside of Clip, canvas can skip drawing.
Cary Clark8032b982017-07-28 11:04:54 -04005894
Cary Clarkbad5ad72017-08-03 17:14:08 -04005895#Param atlas Image containing sprites ##
5896#Param xform RSXform mappings for sprites in atlas ##
5897#Param tex Rect locations of sprites in atlas ##
5898#Param count number of sprites to draw ##
Cary Clark6fc50412017-09-21 12:31:06 -04005899#Param cullRect bounds of transformed sprites for efficient clipping; may be nullptr ##
5900#Param paint Color_Filter, Image_Filter, Blend_Mode, and so on; may be nullptr ##
Cary Clark8032b982017-07-28 11:04:54 -04005901
5902#Example
5903#Image 3
Cary Clarkbad5ad72017-08-03 17:14:08 -04005904void draw(SkCanvas* canvas) {
5905 // sk_sp<SkImage> image = mandrill;
5906 SkRSXform xforms[] = { { 1, 0, 0, 0 }, {0, 1, 300, 100 } };
5907 SkRect tex[] = { { 0, 0, 200, 200 }, { 200, 0, 400, 200 } };
5908 canvas->drawAtlas(image, xforms, tex, 2, nullptr, nullptr);
Cary Clark8032b982017-07-28 11:04:54 -04005909}
5910##
5911
Cary Clark2ade9972017-11-02 17:49:34 -04005912#SeeAlso drawBitmap drawImage
Cary Clark8032b982017-07-28 11:04:54 -04005913
5914##
5915
5916# ------------------------------------------------------------------------------
5917
Cary Clark73fa9722017-08-29 17:36:51 -04005918#Method void drawDrawable(SkDrawable* drawable, const SkMatrix* matrix = nullptr)
Cary Clark8032b982017-07-28 11:04:54 -04005919
5920Draw Drawable drawable using Clip and Matrix, concatenated with
5921optional matrix.
5922
5923If Canvas has an asynchronous implementation, as is the case
5924when it is recording into Picture, then drawable will be referenced,
5925so that SkDrawable::draw() can be called when the operation is finalized. To force
5926immediate drawing, call SkDrawable::draw() instead.
5927
Cary Clarkbad5ad72017-08-03 17:14:08 -04005928#Param drawable custom struct encapsulating drawing commands ##
5929#Param matrix transformation applied to drawing; may be nullptr ##
Cary Clark8032b982017-07-28 11:04:54 -04005930
5931#Example
5932#Height 100
5933#Function
Cary Clarkbad5ad72017-08-03 17:14:08 -04005934struct MyDrawable : public SkDrawable {
5935 SkRect onGetBounds() override { return SkRect::MakeWH(50, 100); }
5936
5937 void onDraw(SkCanvas* canvas) override {
5938 SkPath path;
5939 path.conicTo(10, 90, 50, 90, 0.9f);
5940 SkPaint paint;
5941 paint.setColor(SK_ColorBLUE);
5942 canvas->drawRect(path.getBounds(), paint);
5943 paint.setAntiAlias(true);
5944 paint.setColor(SK_ColorWHITE);
5945 canvas->drawPath(path, paint);
5946 }
5947};
5948
5949#Function ##
5950void draw(SkCanvas* canvas) {
5951 sk_sp<SkDrawable> drawable(new MyDrawable);
5952 SkMatrix matrix;
5953 matrix.setTranslate(10, 10);
5954 canvas->drawDrawable(drawable.get(), &matrix);
Cary Clark8032b982017-07-28 11:04:54 -04005955}
5956##
5957
Cary Clark2ade9972017-11-02 17:49:34 -04005958#SeeAlso SkDrawable drawPicture
Cary Clark8032b982017-07-28 11:04:54 -04005959
5960##
5961
5962# ------------------------------------------------------------------------------
5963
5964#Method void drawDrawable(SkDrawable* drawable, SkScalar x, SkScalar y)
5965
5966Draw Drawable drawable using Clip and Matrix, offset by (x, y).
5967
5968If Canvas has an asynchronous implementation, as is the case
5969when it is recording into Picture, then drawable will be referenced,
5970so that SkDrawable::draw() can be called when the operation is finalized. To force
5971immediate drawing, call SkDrawable::draw() instead.
5972
Cary Clarkbad5ad72017-08-03 17:14:08 -04005973#Param drawable custom struct encapsulating drawing commands ##
5974#Param x offset into Canvas writable pixels in x ##
5975#Param y offset into Canvas writable pixels in y ##
Cary Clark8032b982017-07-28 11:04:54 -04005976
5977#Example
5978#Height 100
5979#Function
Cary Clarkbad5ad72017-08-03 17:14:08 -04005980struct MyDrawable : public SkDrawable {
5981 SkRect onGetBounds() override { return SkRect::MakeWH(50, 100); }
5982
5983 void onDraw(SkCanvas* canvas) override {
5984 SkPath path;
5985 path.conicTo(10, 90, 50, 90, 0.9f);
5986 SkPaint paint;
5987 paint.setColor(SK_ColorBLUE);
5988 canvas->drawRect(path.getBounds(), paint);
5989 paint.setAntiAlias(true);
5990 paint.setColor(SK_ColorWHITE);
5991 canvas->drawPath(path, paint);
5992 }
5993};
5994
5995#Function ##
5996void draw(SkCanvas* canvas) {
5997 sk_sp<SkDrawable> drawable(new MyDrawable);
5998 canvas->drawDrawable(drawable.get(), 10, 10);
Cary Clark8032b982017-07-28 11:04:54 -04005999}
6000##
6001
Cary Clark2ade9972017-11-02 17:49:34 -04006002#SeeAlso SkDrawable drawPicture
Cary Clark8032b982017-07-28 11:04:54 -04006003
6004##
6005
6006# ------------------------------------------------------------------------------
6007
6008#Method void drawAnnotation(const SkRect& rect, const char key[], SkData* value)
6009
6010Associate Rect on Canvas when an annotation; a key-value pair, where the key is
6011a null-terminated utf8 string, and optional value is stored as Data.
6012
6013Only some canvas implementations, such as recording to Picture, or drawing to
6014Document_PDF, use annotations.
6015
Cary Clarkbad5ad72017-08-03 17:14:08 -04006016#Param rect Rect extent of canvas to annotate ##
6017#Param key string used for lookup ##
6018#Param value data holding value stored in annotation ##
Cary Clark8032b982017-07-28 11:04:54 -04006019
6020#Example
6021 #Height 1
6022 const char text[] = "Click this link!";
6023 SkRect bounds;
6024 SkPaint paint;
6025 paint.setTextSize(40);
6026 (void)paint.measureText(text, strlen(text), &bounds);
6027 const char url[] = "https://www.google.com/";
6028 sk_sp<SkData> urlData(SkData::MakeWithCString(url));
6029 canvas->drawAnnotation(bounds, "url_key", urlData.get());
6030##
6031
Cary Clark2ade9972017-11-02 17:49:34 -04006032#SeeAlso SkPicture SkDocument
Cary Clark8032b982017-07-28 11:04:54 -04006033
6034##
6035
6036# ------------------------------------------------------------------------------
6037
6038#Method void drawAnnotation(const SkRect& rect, const char key[], const sk_sp<SkData>& value)
6039
6040Associate Rect on Canvas when an annotation; a key-value pair, where the key is
6041a null-terminated utf8 string, and optional value is stored as Data.
6042
6043Only some canvas implementations, such as recording to Picture, or drawing to
6044Document_PDF, use annotations.
6045
Cary Clarkbad5ad72017-08-03 17:14:08 -04006046#Param rect Rect extent of canvas to annotate ##
6047#Param key string used for lookup ##
6048#Param value data holding value stored in annotation ##
Cary Clark8032b982017-07-28 11:04:54 -04006049
6050#Example
6051#Height 1
6052 const char text[] = "Click this link!";
6053 SkRect bounds;
6054 SkPaint paint;
6055 paint.setTextSize(40);
6056 (void)paint.measureText(text, strlen(text), &bounds);
6057 const char url[] = "https://www.google.com/";
6058 sk_sp<SkData> urlData(SkData::MakeWithCString(url));
6059 canvas->drawAnnotation(bounds, "url_key", urlData.get());
6060##
6061
Cary Clark2ade9972017-11-02 17:49:34 -04006062#SeeAlso SkPicture SkDocument
Cary Clark8032b982017-07-28 11:04:54 -04006063
6064##
6065
6066#Method SkDrawFilter* getDrawFilter() const
6067
6068Legacy call to be deprecated.
6069
6070#Deprecated
6071##
6072
6073##
6074
6075#Method virtual SkDrawFilter* setDrawFilter(SkDrawFilter* filter)
6076
6077Legacy call to be deprecated.
6078
6079#Deprecated
6080##
6081
6082##
6083
6084# ------------------------------------------------------------------------------
6085
6086#Method virtual bool isClipEmpty() const
6087
6088Returns true if Clip is empty; that is, nothing will draw.
6089
Cary Clarkbad5ad72017-08-03 17:14:08 -04006090May do work when called; it should not be called
Cary Clark8032b982017-07-28 11:04:54 -04006091more often than needed. However, once called, subsequent calls perform no
6092work until Clip changes.
6093
Cary Clarkbad5ad72017-08-03 17:14:08 -04006094#Return true if Clip is empty ##
Cary Clark8032b982017-07-28 11:04:54 -04006095
6096#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04006097 void draw(SkCanvas* canvas) {
6098 SkDebugf("clip is%s empty\n", canvas->isClipEmpty() ? "" : " not");
6099 SkPath path;
6100 canvas->clipPath(path);
6101 SkDebugf("clip is%s empty\n", canvas->isClipEmpty() ? "" : " not");
Cary Clark8032b982017-07-28 11:04:54 -04006102 }
6103 #StdOut
Cary Clarkbad5ad72017-08-03 17:14:08 -04006104 clip is not empty
Cary Clark8032b982017-07-28 11:04:54 -04006105 clip is empty
6106 ##
6107##
6108
Cary Clark2ade9972017-11-02 17:49:34 -04006109#SeeAlso isClipRect getLocalClipBounds getDeviceClipBounds
Cary Clark8032b982017-07-28 11:04:54 -04006110
6111##
6112
6113# ------------------------------------------------------------------------------
6114
6115#Method virtual bool isClipRect() const
6116
6117Returns true if Clip is Rect and not empty.
6118Returns false if the clip is empty, or if it is not Rect.
6119
Cary Clarkbad5ad72017-08-03 17:14:08 -04006120#Return true if Clip is Rect and not empty ##
Cary Clark8032b982017-07-28 11:04:54 -04006121
6122#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04006123 void draw(SkCanvas* canvas) {
6124 SkDebugf("clip is%s rect\n", canvas->isClipRect() ? "" : " not");
6125 canvas->clipRect({0, 0, 0, 0});
6126 SkDebugf("clip is%s rect\n", canvas->isClipRect() ? "" : " not");
Cary Clark8032b982017-07-28 11:04:54 -04006127 }
6128 #StdOut
Cary Clarkbad5ad72017-08-03 17:14:08 -04006129 clip is rect
Cary Clark8032b982017-07-28 11:04:54 -04006130 clip is not rect
6131 ##
6132##
6133
Cary Clark2ade9972017-11-02 17:49:34 -04006134#SeeAlso isClipEmpty getLocalClipBounds getDeviceClipBounds
Cary Clark8032b982017-07-28 11:04:54 -04006135
6136##
6137
6138#Class SkCanvas ##
Cary Clark884dd7d2017-10-11 10:37:52 -04006139
6140#Class SkAutoCanvasRestore
6141
6142Stack helper class calls SkCanvas::restoreToCount() when SkAutoCanvasRestore
6143goes out of scope. Use this to guarantee that the canvas is restored to a known
6144state.
6145
6146#Method SkAutoCanvasRestore(SkCanvas* canvas, bool doSave)
6147
6148Preserves Canvas save count. Optionally saves Canvas Clip and Matrix.
6149
6150#Param canvas Canvas to guard ##
6151#Param doSave call SkCanvas::save() ##
6152
6153#Return utility to restore Canvas state on destructor ##
6154
6155#Example
Cary Clark2ade9972017-11-02 17:49:34 -04006156#Height 128
Cary Clarka560c472017-11-27 10:44:06 -05006157 SkPaint p;
6158 p.setAntiAlias(true);
6159 p.setTextSize(64);
6160 for (SkScalar sx : { -1, 1 } ) {
6161 for (SkScalar sy : { -1, 1 } ) {
6162 SkAutoCanvasRestore autoRestore(canvas, true);
6163 SkMatrix m = SkMatrix::MakeAll(sx, 1, 96, 0, sy, 64, 0, 0, 1);
6164 canvas->concat(m);
6165 canvas->drawString("R", 0, 0, p);
6166 }
6167 }
Cary Clark884dd7d2017-10-11 10:37:52 -04006168##
6169
6170#SeeAlso SkCanvas::save SkCanvas::restore
6171
6172##
6173
6174#Method ~SkAutoCanvasRestore()
6175
Cary Clark2ade9972017-11-02 17:49:34 -04006176Restores Canvas to saved state. Destructor is called when container goes out of
6177scope.
Cary Clark884dd7d2017-10-11 10:37:52 -04006178
Cary Clark2ade9972017-11-02 17:49:34 -04006179#NoExample
Cary Clark884dd7d2017-10-11 10:37:52 -04006180##
6181
6182#SeeAlso SkCanvas::save SkCanvas::restore
6183
6184##
6185
6186#Method void restore()
6187
Cary Clark154beea2017-10-26 07:58:48 -04006188Restores Canvas to saved state immediately. Subsequent calls and
6189~SkAutoCanvasRestore have no effect.
Cary Clark884dd7d2017-10-11 10:37:52 -04006190
6191#Example
Cary Clarka560c472017-11-27 10:44:06 -05006192for (bool callRestore : { false, true } ) {
6193 for (bool saveCanvas : {false, true} ) {
6194 SkAutoCanvasRestore autoRestore(canvas, saveCanvas);
6195 if (!saveCanvas) {
6196 canvas->save();
6197 }
6198 SkDebugf("saveCanvas: %s before restore: %d\n",
6199 saveCanvas ? "true" : "false", canvas->getSaveCount());
6200 if (callRestore) autoRestore.restore();
6201 SkDebugf("saveCanvas: %s after restore: %d\n",
6202 saveCanvas ? "true" : "false", canvas->getSaveCount());
6203 }
6204}
6205SkDebugf("final count: %d\n", canvas->getSaveCount());
6206#StdOut
6207saveCanvas: false before restore: 2
6208saveCanvas: false after restore: 2
6209saveCanvas: true before restore: 2
6210saveCanvas: true after restore: 2
6211saveCanvas: false before restore: 2
6212saveCanvas: false after restore: 1
6213saveCanvas: true before restore: 2
6214saveCanvas: true after restore: 1
6215final count: 1
6216##
Cary Clark884dd7d2017-10-11 10:37:52 -04006217##
6218
6219#SeeAlso SkCanvas::save SkCanvas::restore
6220
6221##
6222
6223#Class SkAutoCanvasRestore ##
6224
Cary Clark8032b982017-07-28 11:04:54 -04006225#Topic Canvas ##