blob: 9387450922ca2de6652521192396628febfedec6 [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
Cary Clark5081eed2018-01-22 07:55:48 -050032# name # description ##
Cary Clark8032b982017-07-28 11:04:54 -040033#Legend ##
Cary Clark5081eed2018-01-22 07:55:48 -050034# Classes_and_Structs # embedded struct and class members ##
35# Constants # enum and enum class, const values ##
36# Constructors # functions that construct SkPath ##
37# Member_Functions # static functions and member methods ##
Cary Clark8032b982017-07-28 11:04:54 -040038#Table ##
39#Subtopic ##
40
41#Subtopic Constants
42#Table
43#Legend
Cary Clark5081eed2018-01-22 07:55:48 -050044# name # description ##
Cary Clark8032b982017-07-28 11:04:54 -040045#Legend ##
Cary Clark5081eed2018-01-22 07:55:48 -050046# Lattice::Flags # controls Lattice transparency ##
47# PointMode # sets drawPoints options ##
48# SaveLayerFlags # sets SaveLayerRec options ##
49# SrcRectConstraint # sets drawImageRect options ##
Cary Clark8032b982017-07-28 11:04:54 -040050#Table ##
51#Subtopic ##
52
Cary Clark5081eed2018-01-22 07:55:48 -050053#Subtopic Classes_and_Structs
Cary Clark8032b982017-07-28 11:04:54 -040054#Table
55#Legend
Cary Clark5081eed2018-01-22 07:55:48 -050056# name # description ##
Cary Clark8032b982017-07-28 11:04:54 -040057#Legend ##
Cary Clark5081eed2018-01-22 07:55:48 -050058# Lattice # divides Bitmap, Image into a rectangular grid ##
59# SaveLayerRec # contains state to create Layer ##
Cary Clark8032b982017-07-28 11:04:54 -040060#Table ##
61#Subtopic ##
62
63#Subtopic Constructors
64
65Create the desired type of Surface to obtain its Canvas when possible. Constructors are useful
66when no Surface is required, and some helpers implicitly create Raster_Surface.
67
68#Table
69#Legend
Cary Clark5081eed2018-01-22 07:55:48 -050070# name # description ##
Cary Clark8032b982017-07-28 11:04:54 -040071#Legend ##
Cary Clark5081eed2018-01-22 07:55:48 -050072# MakeRasterDirect # creates from SkImageInfo and Pixel_Storage ##
73# MakeRasterDirectN32 # creates from image data and Pixel_Storage ##
74# SkCanvas() # creates with no Surface, no dimensions ##
75# SkCanvas(SkBaseDevice* device) # to be deprecated ##
76# SkCanvas(const SkBitmap& bitmap) # uses existing Bitmap ##
77# SkCanvas(const SkBitmap& bitmap, ColorBehavior behavior) # Android framework only ##
78# SkCanvas(const SkBitmap& bitmap, const SkSurfaceProps& props) # uses existing Bitmap and Surface_Properties ##
79# SkCanvas(int width, int height, const SkSurfaceProps* props = nullptr) # no Surface, set dimensions, Surface_Properties ##
80# ~SkCanvas() # draws saved Layers, frees resources ##
Cary Clark8032b982017-07-28 11:04:54 -040081#Table ##
82#Subtopic ##
83
84#Subtopic Member_Functions
85#Table
86#Legend
Cary Clark5081eed2018-01-22 07:55:48 -050087# name # description ##
Cary Clark8032b982017-07-28 11:04:54 -040088#Legend ##
Cary Clark5081eed2018-01-22 07:55:48 -050089# MakeRasterDirect # creates Canvas from SkImageInfo and pixel data ##
90# MakeRasterDirectN32 # creates Canvas from image specifications and pixel data ##
91# accessTopLayerPixels # returns writable pixel access if available ##
92# accessTopRasterHandle # returns context that tracks Clip and Matrix ##
93# clear() # fills Clip with Color ##
94# clipPath # combines Clip with Path ##
95# clipRRect # combines Clip with Round_Rect ##
96# clipRect # combines Clip with Rect ##
97# clipRegion # combines Clip with Region ##
98# concat() # multiplies Matrix by Matrix ##
99# discard() # makes Canvas contents undefined ##
100# drawAnnotation # associates a Rect with a key-value pair ##
101# drawArc # draws Arc using Clip, Matrix, and Paint ##
102# drawAtlas # draws sprites using Clip, Matrix, and Paint ##
103# drawBitmap # draws Bitmap at (x, y) position ##
104# drawBitmapLattice # draws proportionally stretched Bitmap ##
105# drawBitmapNine # draws Nine_Patch Bitmap ##
106# drawBitmapRect # draws Bitmap, source Rect to destination Rect ##
107# drawCircle # draws Circle using Clip, Matrix, and Paint ##
108# drawColor # fills Clip with Color and Blend_Mode ##
109# drawDRRect # draws double Round_Rect stroked or filled ##
110# drawDrawable # draws Drawable, encapsulated drawing commands ##
111# drawIRect # draws IRect using Clip, Matrix, and Paint ##
112# drawImage # draws Image at (x, y) position ##
113# drawImageLattice # draws proportionally stretched Image ##
114# drawImageNine # draws Nine_Patch Image ##
115# drawImageRect # draws Image, source Rect to destination Rect ##
116# drawLine # draws line segment between two points ##
117# drawOval # draws Oval using Clip, Matrix, and Paint ##
118# drawPaint # fills Clip with Paint ##
119# drawPatch # draws Coons_Patch ##
120# drawPath # draws Path using Clip, Matrix, and Paint ##
121# drawPicture # draws Picture using Clip and Matrix ##
122# drawPoint # draws point at (x, y) position ##
123# drawPoints # draws array as points, lines, polygon ##
124# drawPosText # draws text at array of (x, y) positions ##
125# drawPosTextH # draws text at x positions with common baseline ##
126# drawRRect # draws Round_Rect using Clip, Matrix, and Paint ##
127# drawRect # draws Rect using Clip, Matrix, and Paint ##
128# drawRegion # draws Region using Clip, Matrix, and Paint ##
129# drawRoundRect # draws Round_Rect using Clip, Matrix, and Paint ##
130# drawString # draws null terminated string at (x, y) using font advance ##
131# drawText # draws text at (x, y), using font advance ##
132# drawTextBlob # draws text with arrays of positions and Paint ##
133# drawTextOnPath # draws text following Path contour ##
134# drawTextOnPathHV # draws text following Path with offsets ##
135# drawTextRSXform # draws text with array of RSXform ##
136# drawVertices # draws Vertices, a triangle mesh ##
137# flush() # triggers execution of all pending draw operations ##
138# getBaseLayerSize # returns size of base Layer in global coordinates ##
139# getDeviceClipBounds # returns IRect bounds of Clip ##
140# getDrawFilter # legacy; to be deprecated ##
141# getGrContext # returns GPU_Context of the GPU_Surface ##
142# getLocalClipBounds # returns Clip bounds in source coordinates ##
143# getMetaData # associates additional data with the canvas ##
144# getProps # copies Surface_Properties if available ##
145# getSaveCount # returns depth of stack containing Clip and Matrix ##
146# getTotalMatrix # returns Matrix ##
147# imageInfo # returns Image_Info for Canvas ##
148# isClipEmpty # returns if Clip is empty ##
149# isClipRect # returns if Clip is Rect and not empty ##
150# makeSurface # creates Surface matching SkImageInfo and SkSurfaceProps ##
151# peekPixels # returns if Canvas has direct access to its pixels ##
152# quickReject # returns if Rect is outside Clip ##
153# readPixels # copies and converts rectangle of pixels from Canvas ##
154# resetMatrix # resets Matrix to identity ##
155# restore() # restores changes to Clip and Matrix, pops save stack ##
156# restoreToCount # restores changes to Clip and Matrix to given depth ##
157# rotate() # rotates Matrix ##
158# save() # saves Clip and Matrix on stack ##
159# saveLayer # saves Clip and Matrix on stack; creates Layer ##
160# saveLayerAlpha # saves Clip and Matrix on stack; creates Layer; sets opacity ##
161# saveLayerPreserveLCDTextRequests # saves Clip and Matrix on stack; creates Layer for LCD text ##
162# scale() # scales Matrix ##
163# setAllowSimplifyClip # experimental ##
164# setDrawFilter # legacy; to be deprecated ##
165# setMatrix # sets Matrix ##
166# skew() # skews Matrix. #
167# translate() # translates Matrix ##
168# writePixels # copies and converts rectangle of pixels to Canvas ##
Cary Clark8032b982017-07-28 11:04:54 -0400169#Table ##
170#Subtopic ##
171
172#Topic Overview ##
173
174# ------------------------------------------------------------------------------
175
Cary Clarka560c472017-11-27 10:44:06 -0500176#Method static std::unique_ptr<SkCanvas> MakeRasterDirect(const SkImageInfo& info, void* pixels,
177 size_t rowBytes,
178 const SkSurfaceProps* props = nullptr)
Cary Clark8032b982017-07-28 11:04:54 -0400179
Cary Clarkbad5ad72017-08-03 17:14:08 -0400180Allocates raster Canvas that will draw directly into pixels.
Cary Clark8032b982017-07-28 11:04:54 -0400181
Cary Clarkbad5ad72017-08-03 17:14:08 -0400182Canvas is returned if all parameters are valid.
183Valid parameters include:
184info dimensions are zero or positive;
Cary Clark2dc84ad2018-01-26 12:56:22 -0500185info contains Color_Type and Alpha_Type supported by Raster_Surface;
Cary Clarkbad5ad72017-08-03 17:14:08 -0400186pixels is not nullptr;
Cary Clark2dc84ad2018-01-26 12:56:22 -0500187rowBytes is zero or large enough to contain info width pixels of Color_Type.
Cary Clarkbad5ad72017-08-03 17:14:08 -0400188
Cary Clarkf05bdda2017-08-24 12:59:48 -0400189Pass zero for rowBytes to compute rowBytes from info width and size of pixel.
190If rowBytes is greater than zero, it must be equal to or greater than
Cary Clark2dc84ad2018-01-26 12:56:22 -0500191info width times bytes required for Color_Type.
Cary Clarkf05bdda2017-08-24 12:59:48 -0400192
193Pixel buffer size should be info height times computed rowBytes.
Cary Clarka560c472017-11-27 10:44:06 -0500194Pixels are not initialized.
195To access pixels after drawing, call flush() or peekPixels.
Cary Clarkbad5ad72017-08-03 17:14:08 -0400196
Cary Clark2dc84ad2018-01-26 12:56:22 -0500197#Param info width, height, Color_Type, Alpha_Type, Color_Space, of Raster_Surface;
Cary Clarkbad5ad72017-08-03 17:14:08 -0400198 width, or height, or both, may be zero
Cary Clark8032b982017-07-28 11:04:54 -0400199##
Cary Clarkf05bdda2017-08-24 12:59:48 -0400200#Param pixels pointer to destination pixels buffer
Cary Clark8032b982017-07-28 11:04:54 -0400201##
Cary Clarkf05bdda2017-08-24 12:59:48 -0400202#Param rowBytes interval from one Surface row to the next, or zero
Cary Clark8032b982017-07-28 11:04:54 -0400203##
Cary Clarka560c472017-11-27 10:44:06 -0500204#Param props LCD striping orientation and setting for device independent fonts;
205 may be nullptr
206##
Cary Clark8032b982017-07-28 11:04:54 -0400207
Cary Clarkbad5ad72017-08-03 17:14:08 -0400208#Return Canvas if all parameters are valid; otherwise, nullptr ##
Cary Clark8032b982017-07-28 11:04:54 -0400209
210#Example
211 #Description
212 Allocates a three by three bitmap, clears it to white, and draws a black pixel
213 in the center.
214 ##
Cary Clarkbad5ad72017-08-03 17:14:08 -0400215void draw(SkCanvas* ) {
Cary Clarkce101242017-09-01 15:51:02 -0400216 SkImageInfo info = SkImageInfo::MakeN32Premul(3, 3); // device aligned, 32 bpp, Premultiplied
Cary Clarkbad5ad72017-08-03 17:14:08 -0400217 const size_t minRowBytes = info.minRowBytes(); // bytes used by one bitmap row
Cary Clarka560c472017-11-27 10:44:06 -0500218 const size_t size = info.computeMinByteSize(); // bytes used by all rows
Cary Clarkbad5ad72017-08-03 17:14:08 -0400219 SkAutoTMalloc<SkPMColor> storage(size); // allocate storage for pixels
220 SkPMColor* pixels = storage.get(); // get pointer to allocated storage
221 // create a SkCanvas backed by a raster device, and delete it when the
222 // function goes out of scope.
223 std::unique_ptr<SkCanvas> canvas = SkCanvas::MakeRasterDirect(info, pixels, minRowBytes);
Cary Clarkce101242017-09-01 15:51:02 -0400224 canvas->clear(SK_ColorWHITE); // white is Unpremultiplied, in ARGB order
Cary Clarkbad5ad72017-08-03 17:14:08 -0400225 canvas->flush(); // ensure that pixels are cleared
Cary Clarkce101242017-09-01 15:51:02 -0400226 SkPMColor pmWhite = pixels[0]; // the Premultiplied format may vary
Cary Clarkbad5ad72017-08-03 17:14:08 -0400227 SkPaint paint; // by default, draws black
228 canvas->drawPoint(1, 1, paint); // draw in the center
229 canvas->flush(); // ensure that point was drawn
230 for (int y = 0; y < info.height(); ++y) {
231 for (int x = 0; x < info.width(); ++x) {
232 SkDebugf("%c", *pixels++ == pmWhite ? '-' : 'x');
233 }
234 SkDebugf("\n");
235 }
Cary Clark8032b982017-07-28 11:04:54 -0400236}
237 #StdOut
238 ---
239 -x-
240 ---
241 ##
242##
243
Cary Clark8032b982017-07-28 11:04:54 -0400244#SeeAlso MakeRasterDirectN32 SkSurface::MakeRasterDirect
Cary Clark2ade9972017-11-02 17:49:34 -0400245
Cary Clark8032b982017-07-28 11:04:54 -0400246##
247
248# ------------------------------------------------------------------------------
249
250#Method static std::unique_ptr<SkCanvas> MakeRasterDirectN32(int width, int height, SkPMColor* pixels,
251 size_t rowBytes)
252
Cary Clarkbad5ad72017-08-03 17:14:08 -0400253Allocates raster Canvas specified by inline image specification. Subsequent Canvas
254calls draw into pixels.
Cary Clark2dc84ad2018-01-26 12:56:22 -0500255Color_Type is set to kN32_SkColorType.
256Alpha_Type is set to kPremul_SkAlphaType.
Cary Clark8032b982017-07-28 11:04:54 -0400257To access pixels after drawing, call flush() or peekPixels.
258
Cary Clarkbad5ad72017-08-03 17:14:08 -0400259Canvas is returned if all parameters are valid.
260Valid parameters include:
Cary Clarkf05bdda2017-08-24 12:59:48 -0400261width and height are zero or positive;
Cary Clarkbad5ad72017-08-03 17:14:08 -0400262pixels is not nullptr;
Cary Clarkf05bdda2017-08-24 12:59:48 -0400263rowBytes is zero or large enough to contain width pixels of kN32_SkColorType.
Cary Clarkbad5ad72017-08-03 17:14:08 -0400264
Cary Clarkce101242017-09-01 15:51:02 -0400265Pass zero for rowBytes to compute rowBytes from width and size of pixel.
Cary Clarkf05bdda2017-08-24 12:59:48 -0400266If rowBytes is greater than zero, it must be equal to or greater than
Cary Clark2dc84ad2018-01-26 12:56:22 -0500267width times bytes required for Color_Type.
Cary Clarkf05bdda2017-08-24 12:59:48 -0400268
269Pixel buffer size should be height times rowBytes.
Cary Clarkbad5ad72017-08-03 17:14:08 -0400270
271#Param width pixel column count on Raster_Surface created; must be zero or greater ##
Cary Clarkbc5697d2017-10-04 14:31:33 -0400272#Param height pixel row count on Raster_Surface created; must be zero or greater ##
Cary Clarkbad5ad72017-08-03 17:14:08 -0400273#Param pixels pointer to destination pixels buffer; buffer size should be height
Cary Clarkf05bdda2017-08-24 12:59:48 -0400274 times rowBytes
Cary Clark8032b982017-07-28 11:04:54 -0400275##
Cary Clarkf05bdda2017-08-24 12:59:48 -0400276#Param rowBytes interval from one Surface row to the next, or zero
Cary Clark8032b982017-07-28 11:04:54 -0400277##
278
Cary Clarkbad5ad72017-08-03 17:14:08 -0400279#Return Canvas if all parameters are valid; otherwise, nullptr ##
Cary Clark8032b982017-07-28 11:04:54 -0400280
281#Example
282 #Description
283 Allocates a three by three bitmap, clears it to white, and draws a black pixel
284 in the center.
285 ##
286void draw(SkCanvas* ) {
287 const int width = 3;
288 const int height = 3;
Cary Clarkce101242017-09-01 15:51:02 -0400289 SkPMColor pixels[height][width]; // allocate a 3x3 Premultiplied bitmap on the stack
Cary Clark8032b982017-07-28 11:04:54 -0400290 // create a SkCanvas backed by a raster device, and delete it when the
291 // function goes out of scope.
292 std::unique_ptr<SkCanvas> canvas = SkCanvas::MakeRasterDirectN32(
293 width,
294 height,
Cary Clarkbc5697d2017-10-04 14:31:33 -0400295 pixels[0], // top-left of the bitmap
Cary Clark8032b982017-07-28 11:04:54 -0400296 sizeof(pixels[0])); // byte width of the each row
Cary Clarkce101242017-09-01 15:51:02 -0400297 // write a premultiplied value for white into all pixels in the bitmap
Cary Clark8032b982017-07-28 11:04:54 -0400298 canvas->clear(SK_ColorWHITE);
Cary Clarkce101242017-09-01 15:51:02 -0400299 SkPMColor pmWhite = pixels[0][0]; // the Premultiplied format may vary
Cary Clark8032b982017-07-28 11:04:54 -0400300 SkPaint paint; // by default, draws black
301 canvas->drawPoint(1, 1, paint); // draw in the center
302 canvas->flush(); // ensure that pixels is ready to be read
303 for (int y = 0; y < height; ++y) {
304 for (int x = 0; x < width; ++x) {
305 SkDebugf("%c", pixels[y][x] == pmWhite ? '-' : 'x');
306 }
307 SkDebugf("\n");
308 }
309}
310 #StdOut
311 ---
312 -x-
313 ---
314 ##
315##
316
Cary Clark2ade9972017-11-02 17:49:34 -0400317#SeeAlso MakeRasterDirect SkSurface::MakeRasterDirect SkImageInfo::MakeN32Premul
Cary Clark8032b982017-07-28 11:04:54 -0400318
319##
320
321# ------------------------------------------------------------------------------
322
323#Method SkCanvas()
324
Cary Clarkd0530ba2017-09-14 11:25:39 -0400325Creates an empty Canvas with no backing device or pixels, with
Cary Clarkf05bdda2017-08-24 12:59:48 -0400326a width and height of zero.
Cary Clark8032b982017-07-28 11:04:54 -0400327
Cary Clarkd0530ba2017-09-14 11:25:39 -0400328#Return empty Canvas ##
Cary Clark8032b982017-07-28 11:04:54 -0400329
330#Example
331
332#Description
333Passes a placeholder to a function that requires one.
334##
335
336#Function
Cary Clarkbad5ad72017-08-03 17:14:08 -0400337// Returns true if either the canvas rotates the text by 90 degrees, or the paint does.
338static void check_for_up_and_down_text(const SkCanvas* canvas, const SkPaint& paint) {
339 bool paintHasVertical = paint.isVerticalText();
340 const SkMatrix& matrix = canvas->getTotalMatrix();
341 bool matrixIsVertical = matrix.preservesRightAngles() && !matrix.isScaleTranslate();
342 SkDebugf("paint draws text %s\n", paintHasVertical != matrixIsVertical ?
343 "top to bottom" : "left to right");
344}
345
346static void check_for_up_and_down_text(const SkPaint& paint) {
347 SkCanvas canvas; // placeholder only, does not have an associated device
348 check_for_up_and_down_text(&canvas, paint);
349}
350
Cary Clark8032b982017-07-28 11:04:54 -0400351##
Cary Clarkbad5ad72017-08-03 17:14:08 -0400352void draw(SkCanvas* canvas) {
353 SkPaint paint;
354 check_for_up_and_down_text(paint); // paint draws text left to right
355 paint.setVerticalText(true);
356 check_for_up_and_down_text(paint); // paint draws text top to bottom
357 paint.setVerticalText(false);
358 canvas->rotate(90);
359 check_for_up_and_down_text(canvas, paint); // paint draws text top to bottom
360}
Cary Clark8032b982017-07-28 11:04:54 -0400361
362 #StdOut
363 paint draws text left to right
364 paint draws text top to bottom
365 paint draws text top to bottom
366 ##
367##
368
Cary Clark2ade9972017-11-02 17:49:34 -0400369#SeeAlso MakeRasterDirect SkRasterHandleAllocator::MakeCanvas SkSurface::getCanvas SkCreateColorSpaceXformCanvas
Cary Clark8032b982017-07-28 11:04:54 -0400370
371##
372
373# ------------------------------------------------------------------------------
374
Cary Clark73fa9722017-08-29 17:36:51 -0400375#Method SkCanvas(int width, int height, const SkSurfaceProps* props = nullptr)
Cary Clark8032b982017-07-28 11:04:54 -0400376
377Creates Canvas of the specified dimensions without a Surface.
Cary Clarkce101242017-09-01 15:51:02 -0400378Used by Subclasses with custom implementations for draw methods.
Cary Clark8032b982017-07-28 11:04:54 -0400379
Cary Clarkd0530ba2017-09-14 11:25:39 -0400380If props equals nullptr, Surface_Properties are created with
381Surface_Properties_Legacy_Font_Host settings, which choose the pixel striping
382direction and order. Since a platform may dynamically change its direction when
383the device is rotated, and since a platform may have multiple monitors with
384different characteristics, it is best not to rely on this legacy behavior.
Cary Clark8032b982017-07-28 11:04:54 -0400385
Cary Clarkbad5ad72017-08-03 17:14:08 -0400386#Param width zero or greater ##
387#Param height zero or greater ##
388#Param props LCD striping orientation and setting for device independent fonts;
389 may be nullptr
390##
391
392#Return Canvas placeholder with dimensions ##
Cary Clark8032b982017-07-28 11:04:54 -0400393
394#Example
395 SkCanvas canvas(10, 20); // 10 units wide, 20 units high
396 canvas.clipRect(SkRect::MakeXYWH(30, 40, 5, 10)); // clip is outside canvas' device
397 SkDebugf("canvas %s empty\n", canvas.getDeviceClipBounds().isEmpty() ? "is" : "is not");
398
399 #StdOut
400 canvas is empty
401 ##
402##
403
Cary Clark2ade9972017-11-02 17:49:34 -0400404#SeeAlso MakeRasterDirect SkSurfaceProps SkPixelGeometry SkCreateColorSpaceXformCanvas
Cary Clark8032b982017-07-28 11:04:54 -0400405
406##
407
408# ------------------------------------------------------------------------------
409
410#Method explicit SkCanvas(SkBaseDevice* device)
411
412Construct a canvas that draws into device.
413Used by child classes of SkCanvas.
414
415#ToDo Since SkBaseDevice is private, shouldn't this be private also? ##
416
Cary Clarkbad5ad72017-08-03 17:14:08 -0400417#Param device specifies a device for the canvas to draw into ##
Cary Clark8032b982017-07-28 11:04:54 -0400418
Cary Clarkbad5ad72017-08-03 17:14:08 -0400419#Return Canvas that can be used to draw into device ##
Cary Clark8032b982017-07-28 11:04:54 -0400420
421#Example
422#Error "Unsure how to create a meaningful example."
423 SkPDFCanvas::SkPDFCanvas(const sk_sp<SkPDFDevice>& dev)
424 : SkCanvas(dev.get()) {}
425##
426
Cary Clark2ade9972017-11-02 17:49:34 -0400427#ToDo either remove doc or figure out a way to fiddle it ##
428
429#SeeAlso MakeRasterDirect SkRasterHandleAllocator::MakeCanvas SkSurface::getCanvas SkCreateColorSpaceXformCanvas
Cary Clark8032b982017-07-28 11:04:54 -0400430
431##
432
433# ------------------------------------------------------------------------------
434
435#Method explicit SkCanvas(const SkBitmap& bitmap)
436
437Construct a canvas that draws into bitmap.
438Sets SkSurfaceProps::kLegacyFontHost_InitType in constructed Surface.
439
Cary Clarkbad5ad72017-08-03 17:14:08 -0400440Bitmap is copied so that subsequently editing bitmap will not affect
441constructed Canvas.
442
443May be deprecated in the future.
444
Cary Clark8032b982017-07-28 11:04:54 -0400445#ToDo Should be deprecated? ##
446
Cary Clark2dc84ad2018-01-26 12:56:22 -0500447#Param bitmap width, height, Color_Type, Alpha_Type, and pixel
Cary Clarkbad5ad72017-08-03 17:14:08 -0400448 storage of Raster_Surface
Cary Clark8032b982017-07-28 11:04:54 -0400449##
450
Cary Clarkbad5ad72017-08-03 17:14:08 -0400451#Return Canvas that can be used to draw into bitmap ##
Cary Clark8032b982017-07-28 11:04:54 -0400452
453#Example
454#Description
455The actual output depends on the installed fonts.
456##
457 SkBitmap bitmap;
458 // create a bitmap 5 wide and 11 high
459 bitmap.allocPixels(SkImageInfo::MakeN32Premul(5, 11));
460 SkCanvas canvas(bitmap);
Cary Clarkce101242017-09-01 15:51:02 -0400461 canvas.clear(SK_ColorWHITE); // white is Unpremultiplied, in ARGB order
Cary Clark8032b982017-07-28 11:04:54 -0400462 SkPixmap pixmap; // provides guaranteed access to the drawn pixels
463 if (!canvas.peekPixels(&pixmap)) {
464 SkDebugf("peekPixels should never fail.\n");
465 }
Cary Clarkbc5697d2017-10-04 14:31:33 -0400466 const SkPMColor* pixels = pixmap.addr32(); // points to top-left of bitmap
Cary Clarkce101242017-09-01 15:51:02 -0400467 SkPMColor pmWhite = pixels[0]; // the Premultiplied format may vary
Cary Clark8032b982017-07-28 11:04:54 -0400468 SkPaint paint; // by default, draws black, 12 point text
469 canvas.drawString("!", 1, 10, paint); // 1 char at baseline (1, 10)
470 for (int y = 0; y < bitmap.height(); ++y) {
471 for (int x = 0; x < bitmap.width(); ++x) {
472 SkDebugf("%c", *pixels++ == pmWhite ? '-' : 'x');
473 }
474 SkDebugf("\n");
475 }
476
477 #StdOut
Cary Clarkd0530ba2017-09-14 11:25:39 -0400478 -----
479 ---x-
480 ---x-
481 ---x-
482 ---x-
483 ---x-
484 ---x-
485 -----
486 ---x-
487 ---x-
Cary Clark8032b982017-07-28 11:04:54 -0400488 -----
489 #StdOut ##
490##
491
Cary Clark2ade9972017-11-02 17:49:34 -0400492#SeeAlso MakeRasterDirect SkRasterHandleAllocator::MakeCanvas SkSurface::getCanvas SkCreateColorSpaceXformCanvas
Cary Clark8032b982017-07-28 11:04:54 -0400493
494##
495
Cary Clarkbad5ad72017-08-03 17:14:08 -0400496#EnumClass ColorBehavior
Cary Clark8032b982017-07-28 11:04:54 -0400497
498#Private
499Android framework only.
500##
501
502#Code
503 enum class ColorBehavior {
504 kLegacy,
505 };
506##
507#Const kLegacy 0
Cary Clarkbad5ad72017-08-03 17:14:08 -0400508 Is a placeholder to allow specialized constructor; has no meaning.
Cary Clark8032b982017-07-28 11:04:54 -0400509##
510##
511
Cary Clarkbad5ad72017-08-03 17:14:08 -0400512#Method SkCanvas(const SkBitmap& bitmap, ColorBehavior behavior)
513
514#Private
515Android framework only.
516##
517
518#Param bitmap specifies a bitmap for the canvas to draw into ##
519#Param behavior specializes this constructor; value is unused ##
520#Return Canvas that can be used to draw into bitmap ##
521
522#NoExample
523##
524##
Cary Clark8032b982017-07-28 11:04:54 -0400525
526# ------------------------------------------------------------------------------
527
528#Method SkCanvas(const SkBitmap& bitmap, const SkSurfaceProps& props)
529
530Construct a canvas that draws into bitmap.
531Use props to match the device characteristics, like LCD striping.
532
Cary Clarkbad5ad72017-08-03 17:14:08 -0400533bitmap is copied so that subsequently editing bitmap will not affect
534constructed Canvas.
535
Cary Clark2dc84ad2018-01-26 12:56:22 -0500536#Param bitmap width, height, Color_Type, Alpha_Type,
Cary Clarkbad5ad72017-08-03 17:14:08 -0400537 and pixel storage of Raster_Surface
Cary Clark8032b982017-07-28 11:04:54 -0400538##
Cary Clarkbad5ad72017-08-03 17:14:08 -0400539#Param props order and orientation of RGB striping; and whether to use
540 device independent fonts
Cary Clark8032b982017-07-28 11:04:54 -0400541##
542
Cary Clarkbad5ad72017-08-03 17:14:08 -0400543#Return Canvas that can be used to draw into bitmap ##
Cary Clark8032b982017-07-28 11:04:54 -0400544
545#Example
546#Description
547The actual output depends on the installed fonts.
548##
549 SkBitmap bitmap;
550 // create a bitmap 5 wide and 11 high
551 bitmap.allocPixels(SkImageInfo::MakeN32Premul(5, 11));
552 SkCanvas canvas(bitmap, SkSurfaceProps(0, kUnknown_SkPixelGeometry));
Cary Clarkce101242017-09-01 15:51:02 -0400553 canvas.clear(SK_ColorWHITE); // white is Unpremultiplied, in ARGB order
Cary Clark8032b982017-07-28 11:04:54 -0400554 SkPixmap pixmap; // provides guaranteed access to the drawn pixels
555 if (!canvas.peekPixels(&pixmap)) {
556 SkDebugf("peekPixels should never fail.\n");
557 }
Cary Clarkbc5697d2017-10-04 14:31:33 -0400558 const SkPMColor* pixels = pixmap.addr32(); // points to top-left of bitmap
Cary Clarkce101242017-09-01 15:51:02 -0400559 SkPMColor pmWhite = pixels[0]; // the Premultiplied format may vary
Cary Clark8032b982017-07-28 11:04:54 -0400560 SkPaint paint; // by default, draws black, 12 point text
561 canvas.drawString("!", 1, 10, paint); // 1 char at baseline (1, 10)
562 for (int y = 0; y < bitmap.height(); ++y) {
563 for (int x = 0; x < bitmap.width(); ++x) {
564 SkDebugf("%c", *pixels++ == pmWhite ? '-' : 'x');
565 }
566 SkDebugf("\n");
567 }
568
569 #StdOut
570 -----
571 ---x-
572 ---x-
573 ---x-
574 ---x-
575 ---x-
576 ---x-
577 -----
578 ---x-
579 ---x-
580 -----
581 #StdOut ##
582##
583
Cary Clark2ade9972017-11-02 17:49:34 -0400584#SeeAlso MakeRasterDirect SkRasterHandleAllocator::MakeCanvas SkSurface::getCanvas SkCreateColorSpaceXformCanvas
Cary Clark8032b982017-07-28 11:04:54 -0400585
586##
587
588# ------------------------------------------------------------------------------
589
590#Method virtual ~SkCanvas()
591
Cary Clark5081eed2018-01-22 07:55:48 -0500592Draws saved Layers, if any.
593Frees up resources used by Canvas.
Cary Clark8032b982017-07-28 11:04:54 -0400594
595#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -0400596#Description
Cary Clarkce101242017-09-01 15:51:02 -0400597Canvas Layer draws into bitmap. saveLayerAlpha sets up an additional
598drawing surface that blends with the bitmap. When Layer goes out of
599scope, Layer Destructor is called. The saved Layer is restored, drawing
Cary Clarkbad5ad72017-08-03 17:14:08 -0400600transparent letters.
601##
Cary Clarkf05bdda2017-08-24 12:59:48 -0400602void draw(SkCanvas* canvas) {
603 SkBitmap bitmap;
604 bitmap.allocPixels(SkImageInfo::MakeN32Premul(200, 200));
605 {
606 SkCanvas offscreen(bitmap);
607 SkPaint paint;
608 paint.setTextSize(100);
609 offscreen.drawString("ABC", 20, 160, paint);
610 SkRect layerBounds = SkRect::MakeXYWH(32, 32, 192, 192);
611 offscreen.saveLayerAlpha(&layerBounds, 128);
612 offscreen.clear(SK_ColorWHITE);
613 offscreen.drawString("DEF", 20, 160, paint);
614 }
615 canvas->drawBitmap(bitmap, 0, 0, nullptr);
Cary Clarkbad5ad72017-08-03 17:14:08 -0400616}
Cary Clark8032b982017-07-28 11:04:54 -0400617##
618
Cary Clarkbad5ad72017-08-03 17:14:08 -0400619#SeeAlso State_Stack
Cary Clark8032b982017-07-28 11:04:54 -0400620
621##
622
623# ------------------------------------------------------------------------------
624
625#Method SkMetaData& getMetaData()
626
Cary Clarkf05bdda2017-08-24 12:59:48 -0400627Returns storage to associate additional data with the canvas.
Cary Clark8032b982017-07-28 11:04:54 -0400628The storage is freed when Canvas is deleted.
629
Cary Clarkbad5ad72017-08-03 17:14:08 -0400630#Return storage that can be read from and written to ##
Cary Clark8032b982017-07-28 11:04:54 -0400631
632#Example
633 const char* kHelloMetaData = "HelloMetaData";
634 SkCanvas canvas;
635 SkMetaData& metaData = canvas.getMetaData();
636 SkDebugf("before: %s\n", metaData.findString(kHelloMetaData));
637 metaData.setString(kHelloMetaData, "Hello!");
638 SkDebugf("during: %s\n", metaData.findString(kHelloMetaData));
639 metaData.removeString(kHelloMetaData);
640 SkDebugf("after: %s\n", metaData.findString(kHelloMetaData));
641
642 #StdOut
643 before: (null)
644 during: Hello!
645 after: (null)
646 #StdOut ##
647##
648
Cary Clark2ade9972017-11-02 17:49:34 -0400649#SeeAlso SkMetaData
Cary Clark8032b982017-07-28 11:04:54 -0400650
651##
652
653# ------------------------------------------------------------------------------
654
655#Method SkImageInfo imageInfo() const
656
657Returns Image_Info for Canvas. If Canvas is not associated with Raster_Surface or
Cary Clark2dc84ad2018-01-26 12:56:22 -0500658GPU_Surface, returned Color_Type is set to kUnknown_SkColorType.
Cary Clark8032b982017-07-28 11:04:54 -0400659
Cary Clark2dc84ad2018-01-26 12:56:22 -0500660#Return dimensions and Color_Type of Canvas ##
Cary Clark8032b982017-07-28 11:04:54 -0400661
662#Example
Cary Clarkf05bdda2017-08-24 12:59:48 -0400663 SkCanvas emptyCanvas;
664 SkImageInfo canvasInfo = emptyCanvas.imageInfo();
665 SkImageInfo emptyInfo;
666 SkDebugf("emptyInfo %c= canvasInfo\n", emptyInfo == canvasInfo ? '=' : '!');
667
668 #StdOut
669 emptyInfo == canvasInfo
670 ##
Cary Clark8032b982017-07-28 11:04:54 -0400671##
672
Cary Clark2ade9972017-11-02 17:49:34 -0400673#SeeAlso SkImageInfo MakeRasterDirect makeSurface
Cary Clark8032b982017-07-28 11:04:54 -0400674
675##
676
677# ------------------------------------------------------------------------------
678
679#Method bool getProps(SkSurfaceProps* props) const
680
681If Canvas is associated with Raster_Surface or
682GPU_Surface, copies Surface_Properties and returns true. Otherwise,
683return false and leave props unchanged.
684
Cary Clarkbad5ad72017-08-03 17:14:08 -0400685#Param props storage for writable SkSurfaceProps ##
Cary Clark8032b982017-07-28 11:04:54 -0400686
Cary Clarkbad5ad72017-08-03 17:14:08 -0400687#Return true if Surface_Properties was copied ##
Cary Clark8032b982017-07-28 11:04:54 -0400688
689#ToDo This seems old style. Deprecate? ##
690
691#Example
692 SkBitmap bitmap;
693 SkCanvas canvas(bitmap, SkSurfaceProps(0, kRGB_V_SkPixelGeometry));
694 SkSurfaceProps surfaceProps(0, kUnknown_SkPixelGeometry);
695 SkDebugf("isRGB:%d\n", SkPixelGeometryIsRGB(surfaceProps.pixelGeometry()));
696 if (!canvas.getProps(&surfaceProps)) {
697 SkDebugf("getProps failed unexpectedly.\n");
698 }
699 SkDebugf("isRGB:%d\n", SkPixelGeometryIsRGB(surfaceProps.pixelGeometry()));
700
701 #StdOut
702 isRGB:0
703 isRGB:1
704 #StdOut ##
705##
706
Cary Clark2ade9972017-11-02 17:49:34 -0400707#SeeAlso SkSurfaceProps makeSurface
Cary Clark8032b982017-07-28 11:04:54 -0400708
709##
710
711# ------------------------------------------------------------------------------
712
713#Method void flush()
714
715Triggers the immediate execution of all pending draw operations.
Cary Clarkbad5ad72017-08-03 17:14:08 -0400716If Canvas is associated with GPU_Surface, resolves all pending GPU operations.
Cary Clark2ade9972017-11-02 17:49:34 -0400717If Canvas is associated with Raster_Surface, has no effect; raster draw
718operations are never deferred.
719
720#ToDo
721In an overview section on managing the GPU, include:
722- flush should never change what is drawn
723- call to kick off gpu work
724- calling too much impacts performance
725- some calls (peekPixels, prepareForExternalIO) call it internally
726- canvas call is local, GrContext::flush is global
727- diffentiate between flush, flushAndSignalSemaphores
728- normally never needs to be called
729- call it when sharing gpu resources, feeling memory pressure, swapping out app, and before
730 abandoning context
731- also call to say "I'm finished drawing here", e.g., when drawing to a GPU-backed offscreen surface
732 (created with SkSurface::MakeRenderTarget)
733
734for posterity: this doesn't show a difference: fiddle.skia.org/c/@flushfail
735##
Cary Clark8032b982017-07-28 11:04:54 -0400736
737#Example
738#Error "haven't thought of a useful example to put here"
739##
740
Cary Clark2ade9972017-11-02 17:49:34 -0400741#SeeAlso peekPixels SkSurface::flush() GrContext::flush() SkSurface::prepareForExternalIO GrContext::abandonContext()
Cary Clark8032b982017-07-28 11:04:54 -0400742
743##
744
745# ------------------------------------------------------------------------------
746
747#Method virtual SkISize getBaseLayerSize() const
748
Cary Clarkce101242017-09-01 15:51:02 -0400749Gets the size of the base or root Layer in global canvas coordinates. The
750origin of the base Layer is always (0,0). The area available for drawing may be
Cary Clark8032b982017-07-28 11:04:54 -0400751smaller (due to clipping or saveLayer).
752
Cary Clarkce101242017-09-01 15:51:02 -0400753#Return integral width and height of base Layer ##
Cary Clark8032b982017-07-28 11:04:54 -0400754
755#Example
756 SkBitmap bitmap;
757 bitmap.allocPixels(SkImageInfo::MakeN32Premul(20, 30));
758 SkCanvas canvas(bitmap, SkSurfaceProps(0, kUnknown_SkPixelGeometry));
759 canvas.clipRect(SkRect::MakeWH(10, 40));
760 SkIRect clipDeviceBounds = canvas.getDeviceClipBounds();
761 if (clipDeviceBounds.isEmpty()) {
762 SkDebugf("Empty clip bounds is unexpected!\n");
763 }
764 SkDebugf("clip=%d,%d\n", clipDeviceBounds.width(), clipDeviceBounds.height());
765 SkISize baseLayerSize = canvas.getBaseLayerSize();
766 SkDebugf("size=%d,%d\n", baseLayerSize.width(), baseLayerSize.height());
767
768 #StdOut
769 clip=10,30
770 size=20,30
771 ##
772##
773
774#ToDo is this the same as the width and height of surface? ##
775
Cary Clark2ade9972017-11-02 17:49:34 -0400776#SeeAlso getDeviceClipBounds
777
Cary Clark8032b982017-07-28 11:04:54 -0400778##
779
780# ------------------------------------------------------------------------------
781
782#Method sk_sp<SkSurface> makeSurface(const SkImageInfo& info, const SkSurfaceProps* props = nullptr)
783
784Creates Surface matching info and props, and associates it with Canvas.
Cary Clarkbad5ad72017-08-03 17:14:08 -0400785Returns nullptr if no match found.
Cary Clark8032b982017-07-28 11:04:54 -0400786
Cary Clarkbad5ad72017-08-03 17:14:08 -0400787If props is nullptr, matches Surface_Properties in Canvas. If props is nullptr and Canvas
788does not have Surface_Properties, creates Surface with default Surface_Properties.
Cary Clark8032b982017-07-28 11:04:54 -0400789
Cary Clark2dc84ad2018-01-26 12:56:22 -0500790#Param info width, height, Color_Type, Alpha_Type, and Color_Space ##
Cary Clarkbad5ad72017-08-03 17:14:08 -0400791#Param props Surface_Properties to match; may be nullptr to match Canvas ##
792
793#Return Surface matching info and props, or nullptr if no match is available ##
Cary Clark8032b982017-07-28 11:04:54 -0400794
795#Example
796 sk_sp<SkSurface> surface = SkSurface::MakeRasterN32Premul(5, 6);
797 SkCanvas* smallCanvas = surface->getCanvas();
798 SkImageInfo imageInfo = SkImageInfo::MakeN32Premul(3, 4);
799 sk_sp<SkSurface> compatible = smallCanvas->makeSurface(imageInfo);
800 SkDebugf("compatible %c= nullptr\n", compatible == nullptr ? '=' : '!');
801 SkDebugf("size = %d, %d\n", compatible->width(), compatible->height());
802
803 #StdOut
Cary Clarkbad5ad72017-08-03 17:14:08 -0400804 compatible != nullptr
Cary Clark8032b982017-07-28 11:04:54 -0400805 size = 3, 4
806 ##
807##
808
Cary Clark2ade9972017-11-02 17:49:34 -0400809#SeeAlso SkSurface SkSurface::makeSurface SkImageInfo SkSurfaceProps
Cary Clark8032b982017-07-28 11:04:54 -0400810
811##
812
813# ------------------------------------------------------------------------------
814
815#Method virtual GrContext* getGrContext()
816
817Returns GPU_Context of the GPU_Surface associated with Canvas.
818
Cary Clarkbad5ad72017-08-03 17:14:08 -0400819#Return GPU_Context, if available; nullptr otherwise ##
Cary Clark8032b982017-07-28 11:04:54 -0400820
821#Example
822void draw(SkCanvas* canvas) {
823 if (canvas->getGrContext()) {
824 canvas->clear(SK_ColorRED);
825 } else {
826 canvas->clear(SK_ColorBLUE);
827 }
828}
829##
830
831#ToDo fiddle should show both CPU and GPU out ##
832
Cary Clark2ade9972017-11-02 17:49:34 -0400833#SeeAlso GrContext
834
Cary Clark8032b982017-07-28 11:04:54 -0400835##
836
837# ------------------------------------------------------------------------------
838
Cary Clark73fa9722017-08-29 17:36:51 -0400839#Method void* accessTopLayerPixels(SkImageInfo* info, size_t* rowBytes, SkIPoint* origin = nullptr)
Cary Clark8032b982017-07-28 11:04:54 -0400840
841Returns the pixel base address, Image_Info, rowBytes, and origin if the pixels
Cary Clarkbad5ad72017-08-03 17:14:08 -0400842can be read directly. The returned address is only valid
Cary Clark8032b982017-07-28 11:04:54 -0400843while Canvas is in scope and unchanged. Any Canvas call or Surface call
844may invalidate the returned address and other returned values.
845
846If pixels are inaccessible, info, rowBytes, and origin are unchanged.
847
Cary Clarkbad5ad72017-08-03 17:14:08 -0400848#Param info storage for writable pixels' Image_Info; may be nullptr ##
849#Param rowBytes storage for writable pixels' row bytes; may be nullptr ##
Cary Clarkbc5697d2017-10-04 14:31:33 -0400850#Param origin storage for Canvas top Layer origin, its top-left corner;
Cary Clarkbad5ad72017-08-03 17:14:08 -0400851 may be nullptr
852##
Cary Clark8032b982017-07-28 11:04:54 -0400853
Cary Clarka523d2d2017-08-30 08:58:10 -0400854#Return address of pixels, or nullptr if inaccessible ##
Cary Clark8032b982017-07-28 11:04:54 -0400855
856#Example
857void draw(SkCanvas* canvas) {
858 if (canvas->accessTopLayerPixels(nullptr, nullptr)) {
859 canvas->clear(SK_ColorRED);
860 } else {
861 canvas->clear(SK_ColorBLUE);
862 }
863}
864##
865
866#Example
867#Description
Cary Clarkce101242017-09-01 15:51:02 -0400868Draws "ABC" on the device. Then draws "DEF" in Layer, and reads
869Layer to add a large dotted "DEF". Finally blends Layer with the
Cary Clark8032b982017-07-28 11:04:54 -0400870device.
871
Cary Clarkce101242017-09-01 15:51:02 -0400872The Layer and blended result appear on the CPU and GPU but the large dotted
Cary Clark8032b982017-07-28 11:04:54 -0400873"DEF" appear only on the CPU.
874##
875void draw(SkCanvas* canvas) {
Cary Clarkbad5ad72017-08-03 17:14:08 -0400876 SkPaint paint;
877 paint.setTextSize(100);
878 canvas->drawString("ABC", 20, 160, paint);
879 SkRect layerBounds = SkRect::MakeXYWH(32, 32, 192, 192);
880 canvas->saveLayerAlpha(&layerBounds, 128);
881 canvas->clear(SK_ColorWHITE);
882 canvas->drawString("DEF", 20, 160, paint);
883 SkImageInfo imageInfo;
884 size_t rowBytes;
885 SkIPoint origin;
886 uint32_t* access = (uint32_t*) canvas->accessTopLayerPixels(&imageInfo, &rowBytes, &origin);
887 if (access) {
888 int h = imageInfo.height();
889 int v = imageInfo.width();
890 int rowWords = rowBytes / sizeof(uint32_t);
891 for (int y = 0; y < h; ++y) {
892 int newY = (y - h / 2) * 2 + h / 2;
893 if (newY < 0 || newY >= h) {
894 continue;
895 }
896 for (int x = 0; x < v; ++x) {
897 int newX = (x - v / 2) * 2 + v / 2;
898 if (newX < 0 || newX >= v) {
899 continue;
900 }
901 if (access[y * rowWords + x] == SK_ColorBLACK) {
902 access[newY * rowWords + newX] = SK_ColorGRAY;
903 }
904 }
905 }
906
907 }
Cary Clark8032b982017-07-28 11:04:54 -0400908 canvas->restore();
909}
910##
911
912#ToDo there are no callers of this that I can find. Deprecate? ##
913#ToDo fiddle should show both CPU and GPU out ##
914
Cary Clark2ade9972017-11-02 17:49:34 -0400915#SeeAlso SkImageInfo SkPixmap
916
Cary Clark8032b982017-07-28 11:04:54 -0400917##
918
919# ------------------------------------------------------------------------------
920
921#Method SkRasterHandleAllocator::Handle accessTopRasterHandle() const
922
923Returns custom context that tracks the Matrix and Clip.
924
925Use Raster_Handle_Allocator to blend Skia drawing with custom drawing, typically performed
Cary Clarkbc5697d2017-10-04 14:31:33 -0400926by the host platform user interface. The custom context returned is generated by
Cary Clarkbad5ad72017-08-03 17:14:08 -0400927SkRasterHandleAllocator::MakeCanvas, which creates a custom canvas with raster storage for
Cary Clark8032b982017-07-28 11:04:54 -0400928the drawing destination.
929
Cary Clarkce101242017-09-01 15:51:02 -0400930#Return context of custom allocation ##
Cary Clark8032b982017-07-28 11:04:54 -0400931
932#Example
933#Description
934#ToDo ##
935##
936#Function
937 static void DeleteCallback(void*, void* context) {
938 delete (char*) context;
939 }
940
941 class CustomAllocator : public SkRasterHandleAllocator {
942 public:
943 bool allocHandle(const SkImageInfo& info, Rec* rec) override {
944 char* context = new char[4]{'s', 'k', 'i', 'a'};
945 rec->fReleaseProc = DeleteCallback;
946 rec->fReleaseCtx = context;
947 rec->fHandle = context;
948 rec->fPixels = context;
949 rec->fRowBytes = 4;
950 return true;
951 }
952
953 void updateHandle(Handle handle, const SkMatrix& ctm, const SkIRect& clip_bounds) override {
954 // apply canvas matrix and clip to custom environment
955 }
956 };
957
958##
959 void draw(SkCanvas* canvas) {
960 const SkImageInfo info = SkImageInfo::MakeN32Premul(1, 1);
961 std::unique_ptr<SkCanvas> c2 =
962 SkRasterHandleAllocator::MakeCanvas(std::unique_ptr<CustomAllocator>(
963 new CustomAllocator()), info);
964 char* context = (char*) c2->accessTopRasterHandle();
965 SkDebugf("context = %.4s\n", context);
966
967 }
968 #StdOut
969 context = skia
970 ##
971 #ToDo skstd::make_unique could not be used because def is private -- note to fix in c++14? ##
972##
973
974#SeeAlso SkRasterHandleAllocator
975
976##
977
978# ------------------------------------------------------------------------------
979
980#Method bool peekPixels(SkPixmap* pixmap)
981
982Returns true if Canvas has direct access to its pixels.
983
Cary Clarkf05bdda2017-08-24 12:59:48 -0400984Pixels are readable when Device is raster. Pixels are not readable when Canvas
Cary Clarkbad5ad72017-08-03 17:14:08 -0400985is returned from GPU_Surface, returned by SkDocument::beginPage, returned by
Cary Clarkf05bdda2017-08-24 12:59:48 -0400986SkPictureRecorder::beginRecording, or Canvas is the base of a utility class
Cary Clarkbad5ad72017-08-03 17:14:08 -0400987like SkDumpCanvas.
Cary Clark8032b982017-07-28 11:04:54 -0400988
Cary Clarkf05bdda2017-08-24 12:59:48 -0400989pixmap is valid only while Canvas is in scope and unchanged. Any
Cary Clarkbad5ad72017-08-03 17:14:08 -0400990Canvas or Surface call may invalidate the pixmap values.
Cary Clark8032b982017-07-28 11:04:54 -0400991
Cary Clarkbc5697d2017-10-04 14:31:33 -0400992#Param pixmap storage for pixel state if pixels are readable; otherwise, ignored ##
Cary Clark8032b982017-07-28 11:04:54 -0400993
Cary Clarkbad5ad72017-08-03 17:14:08 -0400994#Return true if Canvas has direct access to pixels ##
Cary Clark8032b982017-07-28 11:04:54 -0400995
996#Example
997 SkPixmap pixmap;
998 if (canvas->peekPixels(&pixmap)) {
999 SkDebugf("width=%d height=%d\n", pixmap.bounds().width(), pixmap.bounds().height());
1000 }
1001 #StdOut
1002 width=256 height=256
1003 ##
1004##
1005
Cary Clark2ade9972017-11-02 17:49:34 -04001006#SeeAlso readPixels SkBitmap::peekPixels SkImage::peekPixels SkSurface::peekPixels
1007
Cary Clark8032b982017-07-28 11:04:54 -04001008##
1009
1010# ------------------------------------------------------------------------------
1011
1012#Method bool readPixels(const SkImageInfo& dstInfo, void* dstPixels, size_t dstRowBytes,
1013 int srcX, int srcY)
1014
Cary Clark154beea2017-10-26 07:58:48 -04001015Copies Rect of pixels from Canvas into dstPixels. Matrix and Clip are
Cary Clarka560c472017-11-27 10:44:06 -05001016ignored.
Cary Clark6fc50412017-09-21 12:31:06 -04001017
Cary Clarka560c472017-11-27 10:44:06 -05001018Source Rect corners are (srcX, srcY) and (imageInfo().width(), imageInfo().height()).
1019Destination Rect corners are (0, 0) and (dstInfo.width(), dstInfo.height()).
Cary Clark6fc50412017-09-21 12:31:06 -04001020Copies each readable pixel intersecting both rectangles, without scaling,
Cary Clarkf05bdda2017-08-24 12:59:48 -04001021converting to dstInfo.colorType() and dstInfo.alphaType() if required.
Cary Clark8032b982017-07-28 11:04:54 -04001022
Cary Clarkf05bdda2017-08-24 12:59:48 -04001023Pixels are readable when Device is raster, or backed by a GPU.
1024Pixels are not readable when SkCanvas is returned by SkDocument::beginPage,
1025returned by SkPictureRecorder::beginRecording, or Canvas is the base of a utility
1026class like SkDumpCanvas.
Cary Clark8032b982017-07-28 11:04:54 -04001027
Cary Clarkf05bdda2017-08-24 12:59:48 -04001028The destination pixel storage must be allocated by the caller.
Cary Clark8032b982017-07-28 11:04:54 -04001029
Cary Clark2dc84ad2018-01-26 12:56:22 -05001030Pixel values are converted only if Color_Type and Alpha_Type
Cary Clarkf05bdda2017-08-24 12:59:48 -04001031do not match. Only pixels within both source and destination rectangles
Cary Clark154beea2017-10-26 07:58:48 -04001032are copied. dstPixels contents outside Rect intersection are unchanged.
Cary Clarkf05bdda2017-08-24 12:59:48 -04001033
1034Pass negative values for srcX or srcY to offset pixels across or down destination.
Cary Clark8032b982017-07-28 11:04:54 -04001035
1036Does not copy, and returns false if:
1037
1038#List
Cary Clarkf05bdda2017-08-24 12:59:48 -04001039# Source and destination rectangles do not intersect. ##
1040# Canvas pixels could not be converted to dstInfo.colorType() or dstInfo.alphaType(). ##
1041# Canvas pixels are not readable; for instance, Canvas is document-based. ##
Cary Clark8032b982017-07-28 11:04:54 -04001042# dstRowBytes is too small to contain one row of pixels. ##
1043##
1044
Cary Clark2dc84ad2018-01-26 12:56:22 -05001045#Param dstInfo width, height, Color_Type, and Alpha_Type of dstPixels ##
Cary Clarkf05bdda2017-08-24 12:59:48 -04001046#Param dstPixels storage for pixels; dstInfo.height() times dstRowBytes, or larger ##
1047#Param dstRowBytes size of one destination row; dstInfo.width() times pixel size, or larger ##
1048#Param srcX offset into readable pixels in x; may be negative ##
1049#Param srcY offset into readable pixels in y; may be negative ##
Cary Clark8032b982017-07-28 11:04:54 -04001050
Cary Clarkbad5ad72017-08-03 17:14:08 -04001051#Return true if pixels were copied ##
Cary Clark8032b982017-07-28 11:04:54 -04001052
1053#Example
Cary Clarkf05bdda2017-08-24 12:59:48 -04001054#Width 64
1055#Height 64
1056#Description
1057 A black circle drawn on a blue background provides an image to copy.
1058 readPixels copies one quarter of the canvas into each of the four corners.
Cary Clarka560c472017-11-27 10:44:06 -05001059 The copied quarter circles overdraw the original circle.
Cary Clarkf05bdda2017-08-24 12:59:48 -04001060##
1061 canvas->clear(SK_ColorBLUE);
1062 SkPaint paint;
1063 canvas->drawCircle(32, 32, 28, paint);
1064 SkImageInfo info = SkImageInfo::Make(64, 64, kBGRA_8888_SkColorType, kPremul_SkAlphaType);
1065 sk_sp<SkData> data(SkData::MakeUninitialized(info.minRowBytes() * info.height()));
1066 sk_bzero(data->writable_data(), info.minRowBytes() * info.height());
1067 for (int x : { 32, -32 } ) {
1068 for (int y : { 32, -32 } ) {
1069 canvas->readPixels(info, data->writable_data(), info.minRowBytes(), x, y);
1070 }
1071 }
1072 sk_sp<SkImage> image = SkImage::MakeRasterData(info, data, info.minRowBytes());
1073 canvas->drawImage(image, 0, 0);
1074##
1075
1076#Example
Cary Clark8032b982017-07-28 11:04:54 -04001077#Description
Cary Clarkce101242017-09-01 15:51:02 -04001078 Canvas returned by Raster_Surface has Premultiplied pixel values.
1079 clear() takes Unpremultiplied input with Color_Alpha equal 0x80
1080 and Color_RGB equal 0x55, 0xAA, 0xFF. Color_RGB is multiplied by Color_Alpha
1081 to generate Premultiplied value 0x802B5580. readPixels converts pixel back
1082 to Unpremultiplied value 0x8056A9FF, introducing error.
Cary Clark8032b982017-07-28 11:04:54 -04001083##
1084 canvas->clear(0x8055aaff);
1085 for (SkAlphaType alphaType : { kPremul_SkAlphaType, kUnpremul_SkAlphaType } ) {
1086 uint32_t pixel = 0;
1087 SkImageInfo info = SkImageInfo::Make(1, 1, kBGRA_8888_SkColorType, alphaType);
1088 if (canvas->readPixels(info, &pixel, 4, 0, 0)) {
1089 SkDebugf("pixel = %08x\n", pixel);
1090 }
1091 }
1092
1093 #StdOut
1094 pixel = 802b5580
1095 pixel = 8056a9ff
1096 ##
1097##
1098
Cary Clark2ade9972017-11-02 17:49:34 -04001099#SeeAlso peekPixels writePixels drawBitmap drawImage SkBitmap::readPixels SkPixmap::readPixels SkImage::readPixels SkSurface::readPixels
Cary Clark8032b982017-07-28 11:04:54 -04001100
1101##
1102
1103# ------------------------------------------------------------------------------
1104
1105#Method bool readPixels(const SkPixmap& pixmap, int srcX, int srcY)
1106
Cary Clark154beea2017-10-26 07:58:48 -04001107Copies Rect of pixels from Canvas into pixmap. Matrix and Clip are
Cary Clarka560c472017-11-27 10:44:06 -05001108ignored.
Cary Clark6fc50412017-09-21 12:31:06 -04001109
Cary Clarka560c472017-11-27 10:44:06 -05001110Source Rect corners are (srcX, srcY) and (imageInfo().width(), imageInfo().height()).
1111Destination Rect corners are (0, 0) and (pixmap.width(), pixmap.height()).
Cary Clark6fc50412017-09-21 12:31:06 -04001112Copies each readable pixel intersecting both rectangles, without scaling,
Cary Clarkf05bdda2017-08-24 12:59:48 -04001113converting to pixmap.colorType() and pixmap.alphaType() if required.
Cary Clark8032b982017-07-28 11:04:54 -04001114
Cary Clarkf05bdda2017-08-24 12:59:48 -04001115Pixels are readable when Device is raster, or backed by a GPU.
1116Pixels are not readable when SkCanvas is returned by SkDocument::beginPage,
1117returned by SkPictureRecorder::beginRecording, or Canvas is the base of a utility
1118class like SkDumpCanvas.
Cary Clark8032b982017-07-28 11:04:54 -04001119
Cary Clark6fc50412017-09-21 12:31:06 -04001120Caller must allocate pixel storage in pixmap if needed.
Cary Clark8032b982017-07-28 11:04:54 -04001121
Cary Clark2dc84ad2018-01-26 12:56:22 -05001122Pixel values are converted only if Color_Type and Alpha_Type
Cary Clark154beea2017-10-26 07:58:48 -04001123do not match. Only pixels within both source and destination Rects
1124are copied. pixmap pixels contents outside Rect intersection are unchanged.
Cary Clarkf05bdda2017-08-24 12:59:48 -04001125
1126Pass negative values for srcX or srcY to offset pixels across or down pixmap.
Cary Clark8032b982017-07-28 11:04:54 -04001127
1128Does not copy, and returns false if:
1129
1130#List
Cary Clarkf05bdda2017-08-24 12:59:48 -04001131# Source and destination rectangles do not intersect. ##
1132# Canvas pixels could not be converted to pixmap.colorType() or pixmap.alphaType(). ##
1133# Canvas pixels are not readable; for instance, Canvas is document-based. ##
1134# Pixmap pixels could not be allocated. ##
1135# pixmap.rowBytes() is too small to contain one row of pixels. ##
Cary Clark8032b982017-07-28 11:04:54 -04001136##
1137
Cary Clarkbad5ad72017-08-03 17:14:08 -04001138#Param pixmap storage for pixels copied from Canvas ##
Cary Clarkf05bdda2017-08-24 12:59:48 -04001139#Param srcX offset into readable pixels in x; may be negative ##
1140#Param srcY offset into readable pixels in y; may be negative ##
Cary Clark8032b982017-07-28 11:04:54 -04001141
Cary Clarkbad5ad72017-08-03 17:14:08 -04001142#Return true if pixels were copied ##
Cary Clark8032b982017-07-28 11:04:54 -04001143
1144#Example
Cary Clarkf05bdda2017-08-24 12:59:48 -04001145 #Description
Cary Clarkce101242017-09-01 15:51:02 -04001146 clear() takes Unpremultiplied input with Color_Alpha equal 0x80
1147 and Color_RGB equal 0x55, 0xAA, 0xFF. Color_RGB is multiplied by Color_Alpha
1148 to generate Premultiplied value 0x802B5580.
Cary Clarkf05bdda2017-08-24 12:59:48 -04001149 ##
1150 void draw(SkCanvas* canvas) {
1151 canvas->clear(0x8055aaff);
1152 uint32_t pixels[1] = { 0 };
1153 SkPixmap pixmap(SkImageInfo::MakeN32Premul(1, 1), pixels, 4);
1154 canvas->readPixels(pixmap, 0, 0);
1155 SkDebugf("pixel = %08x\n", pixels[0]);
1156 }
Cary Clark8032b982017-07-28 11:04:54 -04001157 #StdOut
1158 pixel = 802b5580
1159 ##
1160##
1161
Cary Clark2ade9972017-11-02 17:49:34 -04001162#SeeAlso peekPixels writePixels drawBitmap drawImage SkBitmap::readPixels SkPixmap::readPixels SkImage::readPixels SkSurface::readPixels
Cary Clark8032b982017-07-28 11:04:54 -04001163
1164##
1165
1166# ------------------------------------------------------------------------------
1167
1168#Method bool readPixels(const SkBitmap& bitmap, int srcX, int srcY)
1169
Cary Clark154beea2017-10-26 07:58:48 -04001170Copies Rect of pixels from Canvas into bitmap. Matrix and Clip are
Cary Clarka560c472017-11-27 10:44:06 -05001171ignored.
Cary Clark6fc50412017-09-21 12:31:06 -04001172
Cary Clarka560c472017-11-27 10:44:06 -05001173Source Rect corners are (srcX, srcY) and (imageInfo().width(), imageInfo().height()).
Cary Clark154beea2017-10-26 07:58:48 -04001174Destination Rect corners are (0, 0) and (bitmap.width(), bitmap.height()).
Cary Clarkf05bdda2017-08-24 12:59:48 -04001175Copies each readable pixel intersecting both rectangles, without scaling,
1176converting to bitmap.colorType() and bitmap.alphaType() if required.
Cary Clark8032b982017-07-28 11:04:54 -04001177
Cary Clarkf05bdda2017-08-24 12:59:48 -04001178Pixels are readable when Device is raster, or backed by a GPU.
1179Pixels are not readable when SkCanvas is returned by SkDocument::beginPage,
1180returned by SkPictureRecorder::beginRecording, or Canvas is the base of a utility
1181class like SkDumpCanvas.
Cary Clark8032b982017-07-28 11:04:54 -04001182
Cary Clark6fc50412017-09-21 12:31:06 -04001183Caller must allocate pixel storage in bitmap if needed.
Cary Clarkf05bdda2017-08-24 12:59:48 -04001184
Cary Clark2dc84ad2018-01-26 12:56:22 -05001185Bitmap values are converted only if Color_Type and Alpha_Type
Cary Clarkf05bdda2017-08-24 12:59:48 -04001186do not match. Only pixels within both source and destination rectangles
Cary Clark154beea2017-10-26 07:58:48 -04001187are copied. Bitmap pixels outside Rect intersection are unchanged.
Cary Clarkf05bdda2017-08-24 12:59:48 -04001188
1189Pass negative values for srcX or srcY to offset pixels across or down bitmap.
Cary Clark8032b982017-07-28 11:04:54 -04001190
1191Does not copy, and returns false if:
1192
1193#List
Cary Clarkf05bdda2017-08-24 12:59:48 -04001194# Source and destination rectangles do not intersect. ##
1195# Canvas pixels could not be converted to bitmap.colorType() or bitmap.alphaType(). ##
1196# Canvas pixels are not readable; for instance, Canvas is document-based. ##
Cary Clark8032b982017-07-28 11:04:54 -04001197# bitmap pixels could not be allocated. ##
Cary Clarkf05bdda2017-08-24 12:59:48 -04001198# bitmap.rowBytes() is too small to contain one row of pixels. ##
Cary Clark8032b982017-07-28 11:04:54 -04001199##
1200
Cary Clarkbad5ad72017-08-03 17:14:08 -04001201#Param bitmap storage for pixels copied from Canvas ##
Cary Clarkf05bdda2017-08-24 12:59:48 -04001202#Param srcX offset into readable pixels in x; may be negative ##
1203#Param srcY offset into readable pixels in y; may be negative ##
Cary Clark8032b982017-07-28 11:04:54 -04001204
Cary Clarkbad5ad72017-08-03 17:14:08 -04001205#Return true if pixels were copied ##
Cary Clark8032b982017-07-28 11:04:54 -04001206
1207#Example
Cary Clarkf05bdda2017-08-24 12:59:48 -04001208 #Description
Cary Clarkce101242017-09-01 15:51:02 -04001209 clear() takes Unpremultiplied input with Color_Alpha equal 0x80
1210 and Color_RGB equal 0x55, 0xAA, 0xFF. Color_RGB is multiplied by Color_Alpha
1211 to generate Premultiplied value 0x802B5580.
Cary Clarkf05bdda2017-08-24 12:59:48 -04001212 ##
Cary Clark8032b982017-07-28 11:04:54 -04001213void draw(SkCanvas* canvas) {
1214 canvas->clear(0x8055aaff);
1215 SkBitmap bitmap;
1216 bitmap.allocPixels(SkImageInfo::MakeN32Premul(1, 1));
1217 canvas->readPixels(bitmap, 0, 0);
1218 SkDebugf("pixel = %08x\n", bitmap.getAddr32(0, 0)[0]);
1219}
1220 #StdOut
1221 pixel = 802b5580
1222 ##
1223##
1224
Cary Clark2ade9972017-11-02 17:49:34 -04001225#SeeAlso peekPixels writePixels drawBitmap drawImage SkBitmap::readPixels SkPixmap::readPixels SkImage::readPixels SkSurface::readPixels
Cary Clark8032b982017-07-28 11:04:54 -04001226
1227##
1228
1229# ------------------------------------------------------------------------------
1230
1231#Method bool writePixels(const SkImageInfo& info, const void* pixels, size_t rowBytes, int x, int y)
1232
Cary Clark154beea2017-10-26 07:58:48 -04001233Copies Rect from pixels to Canvas. Matrix and Clip are ignored.
1234Source Rect corners are (0, 0) and (info.width(), info.height()).
1235Destination Rect corners are (x, y) and
1236(imageInfo().width(), imageInfo().height()).
Cary Clark6fc50412017-09-21 12:31:06 -04001237
1238Copies each readable pixel intersecting both rectangles, without scaling,
Cary Clark154beea2017-10-26 07:58:48 -04001239converting to imageInfo().colorType() and imageInfo().alphaType() if required.
Cary Clark8032b982017-07-28 11:04:54 -04001240
Cary Clarkf05bdda2017-08-24 12:59:48 -04001241Pixels are writable when Device is raster, or backed by a GPU.
1242Pixels are not writable when SkCanvas is returned by SkDocument::beginPage,
1243returned by SkPictureRecorder::beginRecording, or Canvas is the base of a utility
1244class like SkDumpCanvas.
Cary Clark8032b982017-07-28 11:04:54 -04001245
Cary Clark2dc84ad2018-01-26 12:56:22 -05001246Pixel values are converted only if Color_Type and Alpha_Type
Cary Clarkf05bdda2017-08-24 12:59:48 -04001247do not match. Only pixels within both source and destination rectangles
Cary Clark154beea2017-10-26 07:58:48 -04001248are copied. Canvas pixels outside Rect intersection are unchanged.
Cary Clark8032b982017-07-28 11:04:54 -04001249
Cary Clarkf05bdda2017-08-24 12:59:48 -04001250Pass negative values for x or y to offset pixels to the left or
1251above Canvas pixels.
Cary Clark8032b982017-07-28 11:04:54 -04001252
1253Does not copy, and returns false if:
1254
1255#List
Cary Clarkf05bdda2017-08-24 12:59:48 -04001256# Source and destination rectangles do not intersect. ##
Cary Clarkac47b882018-01-11 10:35:44 -05001257# pixels could not be converted to Canvas imageInfo().colorType() or
1258 imageInfo().alphaType(). ##
Cary Clark8032b982017-07-28 11:04:54 -04001259# Canvas pixels are not writable; for instance, Canvas is document-based. ##
1260# rowBytes is too small to contain one row of pixels. ##
1261##
1262
Cary Clark2dc84ad2018-01-26 12:56:22 -05001263#Param info width, height, Color_Type, and Alpha_Type of pixels ##
Cary Clarkf05bdda2017-08-24 12:59:48 -04001264#Param pixels pixels to copy, of size info.height() times rowBytes, or larger ##
Cary Clarkd0530ba2017-09-14 11:25:39 -04001265#Param rowBytes size of one row of pixels; info.width() times pixel size, or larger ##
Cary Clarkf05bdda2017-08-24 12:59:48 -04001266#Param x offset into Canvas writable pixels in x; may be negative ##
1267#Param y offset into Canvas writable pixels in y; may be negative ##
Cary Clark8032b982017-07-28 11:04:54 -04001268
Cary Clarkbad5ad72017-08-03 17:14:08 -04001269#Return true if pixels were written to Canvas ##
Cary Clark8032b982017-07-28 11:04:54 -04001270
1271#Example
1272 SkImageInfo imageInfo = SkImageInfo::MakeN32(256, 1, kPremul_SkAlphaType);
1273 for (int y = 0; y < 256; ++y) {
1274 uint32_t pixels[256];
1275 for (int x = 0; x < 256; ++x) {
1276 pixels[x] = SkColorSetARGB(x, x + y, x, x - y);
1277 }
1278 canvas->writePixels(imageInfo, &pixels, sizeof(pixels), 0, y);
1279 }
1280##
1281
Cary Clark2ade9972017-11-02 17:49:34 -04001282#SeeAlso readPixels drawBitmap drawImage SkBitmap::writePixels
Cary Clark8032b982017-07-28 11:04:54 -04001283
1284##
1285
1286# ------------------------------------------------------------------------------
1287
1288#Method bool writePixels(const SkBitmap& bitmap, int x, int y)
1289
Cary Clark154beea2017-10-26 07:58:48 -04001290Copies Rect from pixels to Canvas. Matrix and Clip are ignored.
1291Source Rect corners are (0, 0) and (bitmap.width(), bitmap.height()).
Cary Clark6fc50412017-09-21 12:31:06 -04001292
Cary Clark154beea2017-10-26 07:58:48 -04001293Destination Rect corners are (x, y) and
1294(imageInfo().width(), imageInfo().height()).
Cary Clark6fc50412017-09-21 12:31:06 -04001295
1296Copies each readable pixel intersecting both rectangles, without scaling,
Cary Clark154beea2017-10-26 07:58:48 -04001297converting to imageInfo().colorType() and imageInfo().alphaType() if required.
Cary Clark8032b982017-07-28 11:04:54 -04001298
Cary Clarkf05bdda2017-08-24 12:59:48 -04001299Pixels are writable when Device is raster, or backed by a GPU.
1300Pixels are not writable when SkCanvas is returned by SkDocument::beginPage,
1301returned by SkPictureRecorder::beginRecording, or Canvas is the base of a utility
1302class like SkDumpCanvas.
Cary Clark8032b982017-07-28 11:04:54 -04001303
Cary Clark2dc84ad2018-01-26 12:56:22 -05001304Pixel values are converted only if Color_Type and Alpha_Type
Cary Clarkf05bdda2017-08-24 12:59:48 -04001305do not match. Only pixels within both source and destination rectangles
Cary Clark154beea2017-10-26 07:58:48 -04001306are copied. Canvas pixels outside Rect intersection are unchanged.
Cary Clark8032b982017-07-28 11:04:54 -04001307
Cary Clarkf05bdda2017-08-24 12:59:48 -04001308Pass negative values for x or y to offset pixels to the left or
1309above Canvas pixels.
Cary Clark8032b982017-07-28 11:04:54 -04001310
1311Does not copy, and returns false if:
1312
1313#List
Cary Clarkf05bdda2017-08-24 12:59:48 -04001314# Source and destination rectangles do not intersect. ##
Cary Clark8032b982017-07-28 11:04:54 -04001315# bitmap does not have allocated pixels. ##
Cary Clarkac47b882018-01-11 10:35:44 -05001316# bitmap pixels could not be converted to Canvas imageInfo().colorType() or
1317 imageInfo().alphaType(). ##
Cary Clarkce101242017-09-01 15:51:02 -04001318# Canvas pixels are not writable; for instance, Canvas is document based. ##
Cary Clark8032b982017-07-28 11:04:54 -04001319# bitmap pixels are inaccessible; for instance, bitmap wraps a texture. ##
1320##
1321
Cary Clarkbad5ad72017-08-03 17:14:08 -04001322#Param bitmap contains pixels copied to Canvas ##
Cary Clarkf05bdda2017-08-24 12:59:48 -04001323#Param x offset into Canvas writable pixels in x; may be negative ##
1324#Param y offset into Canvas writable pixels in y; may be negative ##
Cary Clark8032b982017-07-28 11:04:54 -04001325
Cary Clarkbad5ad72017-08-03 17:14:08 -04001326#Return true if pixels were written to Canvas ##
Cary Clark8032b982017-07-28 11:04:54 -04001327
1328#Example
1329void draw(SkCanvas* canvas) {
1330 SkImageInfo imageInfo = SkImageInfo::MakeN32Premul(2, 2);
1331 SkBitmap bitmap;
1332 bitmap.setInfo(imageInfo);
1333 uint32_t pixels[4];
1334 bitmap.setPixels(pixels);
1335 for (int y = 0; y < 256; y += 2) {
1336 for (int x = 0; x < 256; x += 2) {
1337 pixels[0] = SkColorSetRGB(x, y, x | y);
1338 pixels[1] = SkColorSetRGB(x ^ y, y, x);
1339 pixels[2] = SkColorSetRGB(x, x & y, y);
1340 pixels[3] = SkColorSetRGB(~x, ~y, x);
1341 canvas->writePixels(bitmap, x, y);
1342 }
1343 }
1344}
1345##
1346
Cary Clark2ade9972017-11-02 17:49:34 -04001347#SeeAlso readPixels drawBitmap drawImage SkBitmap::writePixels
Cary Clark8032b982017-07-28 11:04:54 -04001348
1349##
1350
1351# ------------------------------------------------------------------------------
1352#Topic State_Stack
1353
1354Canvas maintains a stack of state that allows hierarchical drawing, commonly used
Cary Clarkbad5ad72017-08-03 17:14:08 -04001355to implement windows and views. The initial state has an identity matrix and and
1356an infinite clip. Even with a wide-open clip, drawing is constrained by the
1357bounds of the Canvas Surface or Device.
Cary Clark8032b982017-07-28 11:04:54 -04001358
1359Canvas savable state consists of Clip, Matrix, and Draw_Filter.
1360Clip describes the area that may be drawn to.
1361Matrix transforms the geometry.
1362Draw_Filter (deprecated on most platforms) modifies the paint before drawing.
1363
1364save(), saveLayer, saveLayerPreserveLCDTextRequests, and saveLayerAlpha
1365save state and return the depth of the stack.
1366
Cary Clarkbad5ad72017-08-03 17:14:08 -04001367restore(), restoreToCount, and ~SkCanvas() revert state to its value when saved.
Cary Clark8032b982017-07-28 11:04:54 -04001368
1369Each state on the stack intersects Clip with the previous Clip,
1370and concatenates Matrix with the previous Matrix.
1371The intersected Clip makes the drawing area the same or smaller;
1372the concatenated Matrix may move the origin and potentially scale or rotate
1373the coordinate space.
1374
1375Canvas does not require balancing the state stack but it is a good idea
1376to do so. Calling save() without restore() will eventually cause Skia to fail;
1377mismatched save() and restore() create hard to find bugs.
1378
1379It is not possible to use state to draw outside of the clip defined by the
1380previous state.
1381
1382#Example
1383#Description
1384Draw to ever smaller clips; then restore drawing to full canvas.
1385Note that the second clipRect is not permitted to enlarge Clip.
1386##
1387#Height 160
Cary Clarkbad5ad72017-08-03 17:14:08 -04001388void draw(SkCanvas* canvas) {
1389 SkPaint paint;
1390 canvas->save(); // records stack depth to restore
1391 canvas->clipRect(SkRect::MakeWH(100, 100)); // constrains drawing to clip
1392 canvas->clear(SK_ColorRED); // draws to limit of clip
1393 canvas->save(); // records stack depth to restore
1394 canvas->clipRect(SkRect::MakeWH(50, 150)); // Rect below 100 is ignored
1395 canvas->clear(SK_ColorBLUE); // draws to smaller clip
1396 canvas->restore(); // enlarges clip
1397 canvas->drawLine(20, 20, 150, 150, paint); // line below 100 is not drawn
1398 canvas->restore(); // enlarges clip
1399 canvas->drawLine(150, 20, 50, 120, paint); // line below 100 is drawn
Cary Clark8032b982017-07-28 11:04:54 -04001400}
1401##
1402
1403Each Clip uses the current Matrix for its coordinates.
1404
1405#Example
1406#Description
1407While clipRect is given the same rectangle twice, Matrix makes the second
1408clipRect draw at half the size of the first.
1409##
1410#Height 128
Cary Clarkbad5ad72017-08-03 17:14:08 -04001411void draw(SkCanvas* canvas) {
1412 canvas->clipRect(SkRect::MakeWH(100, 100));
1413 canvas->clear(SK_ColorRED);
1414 canvas->scale(.5, .5);
1415 canvas->clipRect(SkRect::MakeWH(100, 100));
1416 canvas->clear(SK_ColorBLUE);
Cary Clark8032b982017-07-28 11:04:54 -04001417}
1418##
1419
1420#SeeAlso save() saveLayer saveLayerPreserveLCDTextRequests saveLayerAlpha restore() restoreToCount
1421
1422#Method int save()
1423
1424Saves Matrix, Clip, and Draw_Filter (Draw_Filter deprecated on most platforms).
1425Calling restore() discards changes to Matrix, Clip, and Draw_Filter,
1426restoring the Matrix, Clip, and Draw_Filter to their state when save() was called.
1427
Cary Clarkbad5ad72017-08-03 17:14:08 -04001428Matrix may be changed by translate(), scale(), rotate(), skew(), concat(), setMatrix,
1429and resetMatrix. Clip may be changed by clipRect, clipRRect, clipPath, clipRegion.
Cary Clark8032b982017-07-28 11:04:54 -04001430
Cary Clarkbad5ad72017-08-03 17:14:08 -04001431Saved Canvas state is put on a stack; multiple calls to save() should be balance
1432by an equal number of calls to restore().
Cary Clark8032b982017-07-28 11:04:54 -04001433
1434Call restoreToCount with result to restore this and subsequent saves.
1435
Cary Clarkbad5ad72017-08-03 17:14:08 -04001436#Return depth of saved stack ##
Cary Clark8032b982017-07-28 11:04:54 -04001437
1438#Example
1439#Description
1440The black square is translated 50 pixels down and to the right.
1441Restoring Canvas state removes translate() from Canvas stack;
1442the red square is not translated, and is drawn at the origin.
1443##
1444#Height 100
1445void draw(SkCanvas* canvas) {
1446 SkPaint paint;
1447 SkRect rect = { 0, 0, 25, 25 };
1448 canvas->drawRect(rect, paint);
1449 canvas->save();
1450 canvas->translate(50, 50);
1451 canvas->drawRect(rect, paint);
1452 canvas->restore();
1453 paint.setColor(SK_ColorRED);
1454 canvas->drawRect(rect, paint);
1455}
1456##
1457
Cary Clark2ade9972017-11-02 17:49:34 -04001458#SeeAlso saveLayer saveLayerPreserveLCDTextRequests saveLayerAlpha restore() restoreToCount
Cary Clark8032b982017-07-28 11:04:54 -04001459
1460##
1461
1462# ------------------------------------------------------------------------------
Cary Clark8032b982017-07-28 11:04:54 -04001463
1464#Method void restore()
1465
1466Removes changes to Matrix, Clip, and Draw_Filter since Canvas state was
1467last saved. The state is removed from the stack.
1468
1469Does nothing if the stack is empty.
1470
1471#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04001472void draw(SkCanvas* canvas) {
1473 SkCanvas simple;
1474 SkDebugf("depth = %d\n", simple.getSaveCount());
1475 simple.restore();
1476 SkDebugf("depth = %d\n", simple.getSaveCount());
Cary Clark8032b982017-07-28 11:04:54 -04001477}
1478##
1479
Cary Clark2ade9972017-11-02 17:49:34 -04001480#SeeAlso save() saveLayer saveLayerPreserveLCDTextRequests saveLayerAlpha restoreToCount
1481
Cary Clark8032b982017-07-28 11:04:54 -04001482##
1483
1484# ------------------------------------------------------------------------------
1485
1486#Method int getSaveCount() const
1487
1488Returns the number of saved states, each containing: Matrix, Clip, and Draw_Filter.
1489Equals the number of save() calls less the number of restore() calls plus one.
1490The save count of a new canvas is one.
1491
Cary Clarkbad5ad72017-08-03 17:14:08 -04001492#Return depth of save state stack ##
Cary Clark8032b982017-07-28 11:04:54 -04001493
1494#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04001495void draw(SkCanvas* canvas) {
1496 SkCanvas simple;
1497 SkDebugf("depth = %d\n", simple.getSaveCount());
1498 simple.save();
1499 SkDebugf("depth = %d\n", simple.getSaveCount());
1500 simple.restore();
1501 SkDebugf("depth = %d\n", simple.getSaveCount());
Cary Clark8032b982017-07-28 11:04:54 -04001502}
1503#StdOut
Cary Clarkbad5ad72017-08-03 17:14:08 -04001504depth = 1
1505depth = 2
Cary Clark8032b982017-07-28 11:04:54 -04001506depth = 1
1507##
1508##
1509
Cary Clark2ade9972017-11-02 17:49:34 -04001510#SeeAlso save() restore() restoreToCount
1511
Cary Clark8032b982017-07-28 11:04:54 -04001512##
1513
1514# ------------------------------------------------------------------------------
1515
1516#Method void restoreToCount(int saveCount)
1517
Cary Clarkbad5ad72017-08-03 17:14:08 -04001518Restores state to Matrix, Clip, and Draw_Filter values when save(), saveLayer,
1519saveLayerPreserveLCDTextRequests, or saveLayerAlpha returned saveCount.
Cary Clark8032b982017-07-28 11:04:54 -04001520
1521Does nothing if saveCount is greater than state stack count.
1522Restores state to initial values if saveCount is less than or equal to one.
1523
Cary Clarkbad5ad72017-08-03 17:14:08 -04001524#Param saveCount depth of state stack to restore ##
Cary Clark8032b982017-07-28 11:04:54 -04001525
1526#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04001527void draw(SkCanvas* canvas) {
1528 SkDebugf("depth = %d\n", canvas->getSaveCount());
1529 canvas->save();
1530 canvas->save();
1531 SkDebugf("depth = %d\n", canvas->getSaveCount());
1532 canvas->restoreToCount(0);
1533 SkDebugf("depth = %d\n", canvas->getSaveCount());
Cary Clark8032b982017-07-28 11:04:54 -04001534}
1535#StdOut
Cary Clarkbad5ad72017-08-03 17:14:08 -04001536depth = 1
1537depth = 3
Cary Clark8032b982017-07-28 11:04:54 -04001538depth = 1
1539##
1540##
1541
Cary Clark2ade9972017-11-02 17:49:34 -04001542#SeeAlso restore() getSaveCount save()
1543
Cary Clark8032b982017-07-28 11:04:54 -04001544##
1545
1546#Topic State_Stack ##
1547
1548# ------------------------------------------------------------------------------
Cary Clarkce101242017-09-01 15:51:02 -04001549
1550#Topic Layer
Cary Clarkd0530ba2017-09-14 11:25:39 -04001551#Substitute layer
Cary Clarkce101242017-09-01 15:51:02 -04001552#Alias Layers
1553
1554Layer allocates a temporary Bitmap to draw into. When the drawing is
1555complete, the Bitmap is drawn into the Canvas.
1556
1557Layer is saved in a stack along with other saved state. When state with a Layer
1558is restored, the Bitmap is drawn into the previous Layer.
1559
1560Layer may be initialized with the contents of the previous Layer. When Layer is
1561restored, its Bitmap can be modified by Paint passed to Layer to apply
1562Color_Alpha, Color_Filter, Image_Filter, and Blend_Mode.
1563
1564#Method int saveLayer(const SkRect* bounds, const SkPaint* paint)
1565
1566Saves Matrix, Clip, and Draw_Filter (Draw_Filter deprecated on most platforms),
1567and allocates a Bitmap for subsequent drawing.
1568Calling restore() discards changes to Matrix, Clip, and Draw_Filter,
1569and draws the Bitmap.
1570
1571Matrix may be changed by translate(), scale(), rotate(), skew(), concat(),
1572setMatrix, and resetMatrix. Clip may be changed by clipRect, clipRRect,
1573clipPath, clipRegion.
1574
1575Rect bounds suggests but does not define the Bitmap size. To clip drawing to
1576a specific rectangle, use clipRect.
1577
1578Optional Paint paint applies Color_Alpha, Color_Filter, Image_Filter, and
1579Blend_Mode when restore() is called.
1580
1581Call restoreToCount with returned value to restore this and subsequent saves.
1582
1583#Param bounds hint to limit the size of the Layer; may be nullptr ##
1584#Param paint graphics state for Layer; may be nullptr ##
1585
1586#Return depth of saved stack ##
1587
1588#Example
1589#Description
1590Rectangles are blurred by Image_Filter when restore() draws Layer to main
1591Canvas.
1592##
1593#Height 128
1594void draw(SkCanvas* canvas) {
1595 SkPaint paint, blur;
Cary Clarka560c472017-11-27 10:44:06 -05001596 blur.setImageFilter(SkBlurImageFilter::Make(3, 3, nullptr));
Cary Clarkce101242017-09-01 15:51:02 -04001597 canvas->saveLayer(nullptr, &blur);
1598 SkRect rect = { 25, 25, 50, 50};
1599 canvas->drawRect(rect, paint);
1600 canvas->translate(50, 50);
1601 paint.setColor(SK_ColorRED);
1602 canvas->drawRect(rect, paint);
1603 canvas->restore();
1604}
1605##
1606
Cary Clark2ade9972017-11-02 17:49:34 -04001607#SeeAlso save() restore() saveLayer saveLayerPreserveLCDTextRequests saveLayerAlpha SaveLayerRec
Cary Clarkce101242017-09-01 15:51:02 -04001608
1609##
1610
1611#Method int saveLayer(const SkRect& bounds, const SkPaint* paint)
1612
1613Saves Matrix, Clip, and Draw_Filter (Draw_Filter deprecated on most platforms),
1614and allocates a Bitmap for subsequent drawing.
1615Calling restore() discards changes to Matrix, Clip, and Draw_Filter,
1616and draws the Bitmap.
1617
1618Matrix may be changed by translate(), scale(), rotate(), skew(), concat(),
1619setMatrix, and resetMatrix. Clip may be changed by clipRect, clipRRect,
1620clipPath, clipRegion.
1621
1622Rect bounds suggests but does not define the Layer size. To clip drawing to
1623a specific rectangle, use clipRect.
1624
1625Optional Paint paint applies Color_Alpha, Color_Filter, Image_Filter, and
1626Blend_Mode when restore() is called.
1627
1628Call restoreToCount with returned value to restore this and subsequent saves.
1629
1630#Param bounds hint to limit the size of Layer; may be nullptr ##
1631#Param paint graphics state for Layer; may be nullptr ##
1632
1633#Return depth of saved stack ##
1634
1635#Example
1636#Description
1637Rectangles are blurred by Image_Filter when restore() draws Layer to main Canvas.
1638The red rectangle is clipped; it does not fully fit on Layer.
1639Image_Filter blurs past edge of Layer so red rectangle is blurred on all sides.
1640##
1641#Height 128
1642void draw(SkCanvas* canvas) {
1643 SkPaint paint, blur;
Cary Clarka560c472017-11-27 10:44:06 -05001644 blur.setImageFilter(SkBlurImageFilter::Make(3, 3, nullptr));
Cary Clarkce101242017-09-01 15:51:02 -04001645 canvas->saveLayer(SkRect::MakeWH(90, 90), &blur);
1646 SkRect rect = { 25, 25, 50, 50};
1647 canvas->drawRect(rect, paint);
1648 canvas->translate(50, 50);
1649 paint.setColor(SK_ColorRED);
1650 canvas->drawRect(rect, paint);
1651 canvas->restore();
1652}
1653##
1654
Cary Clark2ade9972017-11-02 17:49:34 -04001655#SeeAlso save() restore() saveLayerPreserveLCDTextRequests saveLayerAlpha SaveLayerRec
Cary Clarkce101242017-09-01 15:51:02 -04001656
1657##
1658
1659#Method int saveLayerPreserveLCDTextRequests(const SkRect* bounds, const SkPaint* paint)
1660
1661Saves Matrix, Clip, and Draw_Filter (Draw_Filter deprecated on most platforms),
1662and allocates a Bitmap for subsequent drawing.
1663LCD_Text is preserved when the Layer is drawn to the prior Layer.
1664
1665Calling restore() discards changes to Matrix, Clip, and Draw_Filter,
1666and draws Layer.
1667
1668Matrix may be changed by translate(), scale(), rotate(), skew(), concat(),
1669setMatrix, and resetMatrix. Clip may be changed by clipRect, clipRRect,
1670clipPath, clipRegion.
1671
1672Rect bounds suggests but does not define the Layer size. To clip drawing to
1673a specific rectangle, use clipRect.
1674
1675Optional Paint paint applies Color_Alpha, Color_Filter, Image_Filter, and
1676Blend_Mode when restore() is called.
1677
1678Call restoreToCount with returned value to restore this and subsequent saves.
1679
1680Draw text on an opaque background so that LCD_Text blends correctly with the
1681prior Layer. LCD_Text drawn on a background with transparency may result in
Cary Clark6fc50412017-09-21 12:31:06 -04001682incorrect blending.
Cary Clarkce101242017-09-01 15:51:02 -04001683
1684#Param bounds hint to limit the size of Layer; may be nullptr ##
1685#Param paint graphics state for Layer; may be nullptr ##
1686
1687#Return depth of saved stack ##
1688
1689#Example
1690 SkPaint paint;
1691 paint.setAntiAlias(true);
1692 paint.setLCDRenderText(true);
1693 paint.setTextSize(20);
1694 for (auto preserve : { false, true } ) {
1695 preserve ? canvas->saveLayerPreserveLCDTextRequests(nullptr, nullptr)
1696 : canvas->saveLayer(nullptr, nullptr);
1697 SkPaint p;
1698 p.setColor(SK_ColorWHITE);
1699 // Comment out the next line to draw on a non-opaque background.
1700 canvas->drawRect(SkRect::MakeLTRB(25, 40, 200, 70), p);
1701 canvas->drawString("Hamburgefons", 30, 60, paint);
1702
1703 p.setColor(0xFFCCCCCC);
1704 canvas->drawRect(SkRect::MakeLTRB(25, 70, 200, 100), p);
1705 canvas->drawString("Hamburgefons", 30, 90, paint);
1706
1707 canvas->restore();
1708 canvas->translate(0, 80);
1709 }
1710 ##
1711
Cary Clark2ade9972017-11-02 17:49:34 -04001712#SeeAlso save() restore() saveLayer saveLayerAlpha SaveLayerRec
Cary Clarkce101242017-09-01 15:51:02 -04001713
1714##
1715
1716#Method int saveLayerAlpha(const SkRect* bounds, U8CPU alpha)
1717
1718Saves Matrix, Clip, and Draw_Filter (Draw_Filter deprecated on most platforms),
1719and allocates Bitmap for subsequent drawing.
1720
1721Calling restore() discards changes to Matrix, Clip, and Draw_Filter,
1722and blends Layer with alpha opacity onto prior Layer.
1723
1724Matrix may be changed by translate(), scale(), rotate(), skew(), concat(),
1725setMatrix, and resetMatrix. Clip may be changed by clipRect, clipRRect,
1726clipPath, clipRegion.
1727
1728Rect bounds suggests but does not define Layer size. To clip drawing to
1729a specific rectangle, use clipRect.
1730
1731alpha of zero is fully transparent, 255 is fully opaque.
1732
1733Call restoreToCount with returned value to restore this and subsequent saves.
1734
1735#Param bounds hint to limit the size of Layer; may be nullptr ##
1736#Param alpha opacity of Layer ##
1737
1738#Return depth of saved stack ##
1739
1740#Example
1741 SkPaint paint;
1742 paint.setColor(SK_ColorRED);
1743 canvas->drawCircle(50, 50, 50, paint);
1744 canvas->saveLayerAlpha(nullptr, 128);
1745 paint.setColor(SK_ColorBLUE);
1746 canvas->drawCircle(100, 50, 50, paint);
1747 paint.setColor(SK_ColorGREEN);
1748 paint.setAlpha(128);
1749 canvas->drawCircle(75, 90, 50, paint);
1750 canvas->restore();
1751##
1752
Cary Clark2ade9972017-11-02 17:49:34 -04001753#SeeAlso save() restore() saveLayer saveLayerPreserveLCDTextRequests SaveLayerRec
Cary Clarkce101242017-09-01 15:51:02 -04001754
1755##
1756
1757#Enum
1758
1759#Code
1760 enum {
1761 kIsOpaque_SaveLayerFlag = 1 << 0,
1762 kPreserveLCDText_SaveLayerFlag = 1 << 1,
1763 kInitWithPrevious_SaveLayerFlag = 1 << 2,
1764 kDontClipToLayer_Legacy_SaveLayerFlag = kDontClipToLayer_PrivateSaveLayerFlag,
1765 };
Cary Clarkce101242017-09-01 15:51:02 -04001766##
1767
1768SaveLayerFlags provides options that may be used in any combination in SaveLayerRec,
1769defining how Layer allocated by saveLayer operates.
1770
1771#Const kIsOpaque_SaveLayerFlag 1
1772 Creates Layer without transparency. Flag is ignored if Layer Paint contains
1773 Image_Filter or Color_Filter.
1774##
1775
1776#Const kPreserveLCDText_SaveLayerFlag 2
1777 Creates Layer for LCD text. Flag is ignored if Layer Paint contains
1778 Image_Filter or Color_Filter.
1779##
1780
1781#Const kInitWithPrevious_SaveLayerFlag 4
1782 Initializes Layer with the contents of the previous Layer.
1783##
1784
1785#Const kDontClipToLayer_Legacy_SaveLayerFlag 0x80000000
1786#Private
1787 to be deprecated: bug.skia.org/2440
1788##
1789 Only present on Android.
1790 Skips setting a clip to the Layer bounds.
1791##
1792
1793#Example
1794#Height 160
1795#Description
1796Canvas Layer captures red and blue circles scaled up by four.
1797scalePaint blends Layer back with transparency.
1798##
1799void draw(SkCanvas* canvas) {
1800 SkPaint redPaint, bluePaint, scalePaint;
1801 redPaint.setColor(SK_ColorRED);
1802 canvas->drawCircle(21, 21, 8, redPaint);
1803 bluePaint.setColor(SK_ColorBLUE);
1804 canvas->drawCircle(31, 21, 8, bluePaint);
1805 SkMatrix matrix;
1806 matrix.setScale(4, 4);
1807 scalePaint.setAlpha(0x40);
1808 scalePaint.setImageFilter(
1809 SkImageFilter::MakeMatrixFilter(matrix, kNone_SkFilterQuality, nullptr));
1810 SkCanvas::SaveLayerRec saveLayerRec(nullptr, &scalePaint,
1811 SkCanvas::kInitWithPrevious_SaveLayerFlag);
1812 canvas->saveLayer(saveLayerRec);
1813 canvas->restore();
1814}
1815##
1816
Cary Clark2ade9972017-11-02 17:49:34 -04001817#SeeAlso save() restore() saveLayer saveLayerPreserveLCDTextRequests saveLayerAlpha SaveLayerRec
Cary Clarkce101242017-09-01 15:51:02 -04001818
1819#Enum ##
1820
Cary Clarka560c472017-11-27 10:44:06 -05001821#Typedef uint32_t SaveLayerFlags
1822
1823##
1824
Cary Clarkce101242017-09-01 15:51:02 -04001825#Struct SaveLayerRec
1826
1827#Code
1828 struct SaveLayerRec {
1829 SaveLayerRec*(...
1830
1831 const SkRect* fBounds;
1832 const SkPaint* fPaint;
1833 const SkImageFilter* fBackdrop;
1834 SaveLayerFlags fSaveLayerFlags;
1835 };
1836##
1837
1838SaveLayerRec contains the state used to create the Layer.
1839
1840#Member const SkRect* fBounds
1841 fBounds is used as a hint to limit the size of Layer; may be nullptr.
1842 fBounds suggests but does not define Layer size. To clip drawing to
1843 a specific rectangle, use clipRect.
1844##
1845
1846#Member const SkPaint* fPaint
1847 fPaint modifies how Layer overlays the prior Layer; may be nullptr.
1848 Color_Alpha, Blend_Mode, Color_Filter, Draw_Looper, Image_Filter, and
1849 Mask_Filter affect Layer draw.
1850##
1851
1852#Member const SkImageFilter* fBackdrop
1853 fBackdrop applies Image_Filter to the prior Layer when copying to the Layer;
1854 may be nullptr. Use kInitWithPrevious_SaveLayerFlag to copy the
1855 prior Layer without an Image_Filter.
1856##
1857
1858#Member const SkImage* fClipMask
1859 restore() clips Layer by the Color_Alpha channel of fClipMask when
1860 Layer is copied to Device. fClipMask may be nullptr. .
1861##
1862
1863#Member const SkMatrix* fClipMatrix
1864 fClipMatrix transforms fClipMask before it clips Layer. If
1865 fClipMask describes a translucent gradient, it may be scaled and rotated
1866 without introducing artifacts. fClipMatrix may be nullptr.
1867##
1868
1869#Member SaveLayerFlags fSaveLayerFlags
1870 fSaveLayerFlags are used to create Layer without transparency,
1871 create Layer for LCD text, and to create Layer with the
1872 contents of the previous Layer.
1873##
1874
1875#Example
1876#Height 160
1877#Description
1878Canvas Layer captures a red Anti-aliased circle and a blue Aliased circle scaled
1879up by four. After drawing another red circle without scaling on top, the Layer is
1880transferred to the main canvas.
1881##
1882void draw(SkCanvas* canvas) {
1883 SkPaint redPaint, bluePaint;
1884 redPaint.setAntiAlias(true);
1885 redPaint.setColor(SK_ColorRED);
1886 canvas->drawCircle(21, 21, 8, redPaint);
1887 bluePaint.setColor(SK_ColorBLUE);
1888 canvas->drawCircle(31, 21, 8, bluePaint);
1889 SkMatrix matrix;
1890 matrix.setScale(4, 4);
1891 auto scaler = SkImageFilter::MakeMatrixFilter(matrix, kNone_SkFilterQuality, nullptr);
1892 SkCanvas::SaveLayerRec saveLayerRec(nullptr, nullptr, scaler.get(), 0);
1893 canvas->saveLayer(saveLayerRec);
1894 canvas->drawCircle(125, 85, 8, redPaint);
1895 canvas->restore();
1896}
1897##
1898
1899#Method SaveLayerRec()
1900
1901Sets fBounds, fPaint, and fBackdrop to nullptr. Clears fSaveLayerFlags.
1902
1903#Return empty SaveLayerRec ##
1904
1905#Example
1906 SkCanvas::SaveLayerRec rec1;
1907 rec1.fSaveLayerFlags = SkCanvas::kIsOpaque_SaveLayerFlag;
1908 SkCanvas::SaveLayerRec rec2(nullptr, nullptr, SkCanvas::kIsOpaque_SaveLayerFlag);
1909 SkDebugf("rec1 %c= rec2\n", rec1.fBounds == rec2.fBounds
1910 && rec1.fPaint == rec2.fPaint
1911 && rec1.fBackdrop == rec2.fBackdrop
1912 && rec1.fSaveLayerFlags == rec2.fSaveLayerFlags ? '=' : '!');
1913 #StdOut
1914 rec1 == rec2
1915 ##
1916##
1917
Cary Clark2ade9972017-11-02 17:49:34 -04001918#SeeAlso save() restore() saveLayer saveLayerPreserveLCDTextRequests saveLayerAlpha
1919
Cary Clarkce101242017-09-01 15:51:02 -04001920##
1921
1922#Method SaveLayerRec(const SkRect* bounds, const SkPaint* paint, SaveLayerFlags saveLayerFlags = 0)
1923
1924Sets fBounds, fPaint, and fSaveLayerFlags; sets fBackdrop to nullptr.
1925
1926#Param bounds Layer dimensions; may be nullptr ##
1927#Param paint applied to Layer when overlaying prior Layer; may be nullptr ##
1928#Param saveLayerFlags SaveLayerRec options to modify Layer ##
1929
1930#Return SaveLayerRec with empty backdrop ##
1931
1932#Example
1933 SkCanvas::SaveLayerRec rec1;
1934 SkCanvas::SaveLayerRec rec2(nullptr, nullptr);
1935 SkDebugf("rec1 %c= rec2\n", rec1.fBounds == rec2.fBounds
1936 && rec1.fPaint == rec2.fPaint
1937 && rec1.fBackdrop == rec2.fBackdrop
1938 && rec1.fSaveLayerFlags == rec2.fSaveLayerFlags ? '=' : '!');
1939 #StdOut
1940 rec1 == rec2
1941 ##
1942##
1943
Cary Clark2ade9972017-11-02 17:49:34 -04001944#SeeAlso save() restore() saveLayer saveLayerPreserveLCDTextRequests saveLayerAlpha
1945
Cary Clarkce101242017-09-01 15:51:02 -04001946##
1947
1948#Method SaveLayerRec(const SkRect* bounds, const SkPaint* paint, const SkImageFilter* backdrop,
1949 SaveLayerFlags saveLayerFlags)
1950
1951Sets fBounds, fPaint, fBackdrop, and fSaveLayerFlags.
1952
1953#Param bounds Layer dimensions; may be nullptr ##
1954#Param paint applied to Layer when overlaying prior Layer;
1955 may be nullptr
1956##
1957#Param backdrop prior Layer copied with Image_Filter; may be nullptr
1958##
1959#Param saveLayerFlags SaveLayerRec options to modify Layer ##
1960
1961#Return SaveLayerRec fully specified ##
1962
1963#Example
1964 SkCanvas::SaveLayerRec rec1;
1965 SkCanvas::SaveLayerRec rec2(nullptr, nullptr, nullptr, 0);
1966 SkDebugf("rec1 %c= rec2\n", rec1.fBounds == rec2.fBounds
1967 && rec1.fPaint == rec2.fPaint
1968 && rec1.fBackdrop == rec2.fBackdrop
1969 && rec1.fSaveLayerFlags == rec2.fSaveLayerFlags ? '=' : '!');
1970 #StdOut
1971 rec1 == rec2
1972 ##
1973##
1974
Cary Clark2ade9972017-11-02 17:49:34 -04001975#SeeAlso save() restore() saveLayer saveLayerPreserveLCDTextRequests saveLayerAlpha
1976
Cary Clarkce101242017-09-01 15:51:02 -04001977##
1978
1979#Method SaveLayerRec(const SkRect* bounds, const SkPaint* paint, const SkImageFilter* backdrop,
1980 const SkImage* clipMask, const SkMatrix* clipMatrix,
1981 SaveLayerFlags saveLayerFlags)
1982
1983#Experimental
1984Not ready for general use.
1985##
1986
1987Sets fBounds, fPaint, fBackdrop, fClipMask, fClipMatrix, and fSaveLayerFlags.
1988clipMatrix uses Color_Alpha channel of image, transformed by clipMatrix, to clip
1989Layer when drawn to Canvas.
1990
Cary Clark2ade9972017-11-02 17:49:34 -04001991Implementation is not complete; has no effect if Device is GPU-backed.
Cary Clarkce101242017-09-01 15:51:02 -04001992
1993#Param bounds Layer dimensions; may be nullptr ##
1994#Param paint graphics state applied to Layer when overlaying prior
1995 Layer; may be nullptr
1996##
1997#Param backdrop prior Layer copied with Image_Filter;
1998 may be nullptr
1999##
2000#Param clipMask clip applied to Layer; may be nullptr ##
2001#Param clipMatrix matrix applied to clipMask; may be nullptr to use
2002 identity matrix
2003##
2004#Param saveLayerFlags SaveLayerRec options to modify Layer ##
2005
2006#Return SaveLayerRec fully specified ##
2007
Cary Clark2ade9972017-11-02 17:49:34 -04002008#SeeAlso save() restore() saveLayer saveLayerPreserveLCDTextRequests saveLayerAlpha
Cary Clarkce101242017-09-01 15:51:02 -04002009
2010##
2011
2012#Struct ##
2013
2014#Method int saveLayer(const SaveLayerRec& layerRec)
2015
2016Saves Matrix, Clip, and Draw_Filter (Draw_Filter deprecated on most platforms),
2017and allocates Bitmap for subsequent drawing.
2018
2019Calling restore() discards changes to Matrix, Clip, and Draw_Filter,
2020and blends Bitmap with Color_Alpha opacity onto the prior Layer.
2021
2022Matrix may be changed by translate(), scale(), rotate(), skew(), concat(),
2023setMatrix, and resetMatrix. Clip may be changed by clipRect, clipRRect,
2024clipPath, clipRegion.
2025
2026SaveLayerRec contains the state used to create the Layer.
2027
2028Call restoreToCount with returned value to restore this and subsequent saves.
2029
2030#Param layerRec Layer state ##
2031
2032#Return depth of save state stack ##
2033
2034#Example
2035#Description
2036The example draws an image, and saves it into a Layer with kInitWithPrevious_SaveLayerFlag.
2037Next it punches a hole in Layer and restore with SkBlendMode::kPlus.
2038Where Layer was cleared, the original image will draw unchanged.
2039Outside of the circle the mandrill is brightened.
2040##
2041 #Image 3
Hal Canaryc465d132017-12-08 10:21:31 -05002042 // sk_sp<SkImage> image = GetResourceAsImage("images/mandrill_256.png");
Cary Clarkce101242017-09-01 15:51:02 -04002043 canvas->drawImage(image, 0, 0, nullptr);
2044 SkCanvas::SaveLayerRec rec;
2045 SkPaint paint;
2046 paint.setBlendMode(SkBlendMode::kPlus);
2047 rec.fSaveLayerFlags = SkCanvas::kInitWithPrevious_SaveLayerFlag;
2048 rec.fPaint = &paint;
2049 canvas->saveLayer(rec);
2050 paint.setBlendMode(SkBlendMode::kClear);
2051 canvas->drawCircle(128, 128, 96, paint);
2052 canvas->restore();
2053##
2054
2055#ToDo above example needs to replace GetResourceAsImage with way to select image in fiddle ##
2056
Cary Clark2ade9972017-11-02 17:49:34 -04002057#SeeAlso save() restore() saveLayer saveLayerPreserveLCDTextRequests saveLayerAlpha
2058
Cary Clarkce101242017-09-01 15:51:02 -04002059##
2060
2061#Topic Layer ##
2062
2063# ------------------------------------------------------------------------------
Cary Clark8032b982017-07-28 11:04:54 -04002064#Topic Matrix
2065
2066#Method void translate(SkScalar dx, SkScalar dy)
2067
2068Translate Matrix by dx along the x-axis and dy along the y-axis.
2069
2070Mathematically, replace Matrix with a translation matrix
Cary Clarkce101242017-09-01 15:51:02 -04002071Premultiplied with Matrix.
Cary Clark8032b982017-07-28 11:04:54 -04002072
2073This has the effect of moving the drawing by (dx, dy) before transforming
2074the result with Matrix.
2075
Cary Clarkbad5ad72017-08-03 17:14:08 -04002076#Param dx distance to translate in x ##
2077#Param dy distance to translate in y ##
Cary Clark8032b982017-07-28 11:04:54 -04002078
2079#Example
2080#Height 128
2081#Description
2082scale() followed by translate() produces different results from translate() followed
2083by scale().
2084
2085The blue stroke follows translate of (50, 50); a black
2086fill follows scale of (2, 1/2.f). After restoring the clip, which resets
2087Matrix, a red frame follows the same scale of (2, 1/2.f); a gray fill
2088follows translate of (50, 50).
2089##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002090void draw(SkCanvas* canvas) {
2091 SkPaint filledPaint;
2092 SkPaint outlinePaint;
2093 outlinePaint.setStyle(SkPaint::kStroke_Style);
2094 outlinePaint.setColor(SK_ColorBLUE);
2095 canvas->save();
2096 canvas->translate(50, 50);
2097 canvas->drawCircle(28, 28, 15, outlinePaint); // blue center: (50+28, 50+28)
2098 canvas->scale(2, 1/2.f);
2099 canvas->drawCircle(28, 28, 15, filledPaint); // black center: (50+(28*2), 50+(28/2))
2100 canvas->restore();
2101 filledPaint.setColor(SK_ColorGRAY);
2102 outlinePaint.setColor(SK_ColorRED);
2103 canvas->scale(2, 1/2.f);
2104 canvas->drawCircle(28, 28, 15, outlinePaint); // red center: (28*2, 28/2)
2105 canvas->translate(50, 50);
2106 canvas->drawCircle(28, 28, 15, filledPaint); // gray center: ((50+28)*2, (50+28)/2)
Cary Clark8032b982017-07-28 11:04:54 -04002107}
2108##
2109
Cary Clark2ade9972017-11-02 17:49:34 -04002110#SeeAlso concat() scale() skew() rotate() setMatrix
Cary Clark8032b982017-07-28 11:04:54 -04002111
2112##
2113
2114# ------------------------------------------------------------------------------
2115
2116#Method void scale(SkScalar sx, SkScalar sy)
2117
2118Scale Matrix by sx on the x-axis and sy on the y-axis.
2119
2120Mathematically, replace Matrix with a scale matrix
Cary Clarkce101242017-09-01 15:51:02 -04002121Premultiplied with Matrix.
Cary Clark8032b982017-07-28 11:04:54 -04002122
2123This has the effect of scaling the drawing by (sx, sy) before transforming
2124the result with Matrix.
2125
Cary Clarkbad5ad72017-08-03 17:14:08 -04002126#Param sx amount to scale in x ##
2127#Param sy amount to scale in y ##
Cary Clark8032b982017-07-28 11:04:54 -04002128
2129#Example
2130#Height 160
Cary Clarkbad5ad72017-08-03 17:14:08 -04002131void draw(SkCanvas* canvas) {
2132 SkPaint paint;
2133 SkRect rect = { 10, 20, 60, 120 };
2134 canvas->translate(20, 20);
2135 canvas->drawRect(rect, paint);
2136 canvas->scale(2, .5f);
2137 paint.setColor(SK_ColorGRAY);
2138 canvas->drawRect(rect, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002139}
2140##
2141
Cary Clark2ade9972017-11-02 17:49:34 -04002142#SeeAlso concat() translate() skew() rotate() setMatrix
Cary Clark8032b982017-07-28 11:04:54 -04002143
2144##
2145
2146# ------------------------------------------------------------------------------
2147
2148#Method void rotate(SkScalar degrees)
2149
2150Rotate Matrix by degrees. Positive degrees rotates clockwise.
2151
2152Mathematically, replace Matrix with a rotation matrix
Cary Clarkce101242017-09-01 15:51:02 -04002153Premultiplied with Matrix.
Cary Clark8032b982017-07-28 11:04:54 -04002154
2155This has the effect of rotating the drawing by degrees before transforming
2156the result with Matrix.
2157
Cary Clarkbad5ad72017-08-03 17:14:08 -04002158#Param degrees amount to rotate, in degrees ##
Cary Clark8032b982017-07-28 11:04:54 -04002159
2160#Example
2161#Description
2162Draw clock hands at time 5:10. The hour hand and minute hand point up and
2163are rotated clockwise.
2164##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002165void draw(SkCanvas* canvas) {
2166 SkPaint paint;
2167 paint.setStyle(SkPaint::kStroke_Style);
2168 canvas->translate(128, 128);
2169 canvas->drawCircle(0, 0, 60, paint);
2170 canvas->save();
2171 canvas->rotate(10 * 360 / 60); // 10 minutes of 60 scaled to 360 degrees
2172 canvas->drawLine(0, 0, 0, -50, paint);
2173 canvas->restore();
2174 canvas->rotate((5 + 10.f/60) * 360 / 12); // 5 and 10/60 hours of 12 scaled to 360 degrees
2175 canvas->drawLine(0, 0, 0, -30, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002176}
2177##
2178
Cary Clark2ade9972017-11-02 17:49:34 -04002179#SeeAlso concat() translate() skew() scale() setMatrix
Cary Clark8032b982017-07-28 11:04:54 -04002180
2181##
2182
2183# ------------------------------------------------------------------------------
2184
2185#Method void rotate(SkScalar degrees, SkScalar px, SkScalar py)
2186
Cary Clarkbad5ad72017-08-03 17:14:08 -04002187Rotate Matrix by degrees about a point at (px, py). Positive degrees rotates
2188clockwise.
Cary Clark8032b982017-07-28 11:04:54 -04002189
Cary Clarkce101242017-09-01 15:51:02 -04002190Mathematically, construct a rotation matrix. Premultiply the rotation matrix by
Cary Clark8032b982017-07-28 11:04:54 -04002191a translation matrix, then replace Matrix with the resulting matrix
Cary Clarkce101242017-09-01 15:51:02 -04002192Premultiplied with Matrix.
Cary Clark8032b982017-07-28 11:04:54 -04002193
Cary Clarkbad5ad72017-08-03 17:14:08 -04002194This has the effect of rotating the drawing about a given point before
2195transforming the result with Matrix.
Cary Clark8032b982017-07-28 11:04:54 -04002196
Cary Clarkbad5ad72017-08-03 17:14:08 -04002197#Param degrees amount to rotate, in degrees ##
2198#Param px x-coordinate of the point to rotate about ##
2199#Param py y-coordinate of the point to rotate about ##
Cary Clark8032b982017-07-28 11:04:54 -04002200
2201#Example
2202#Height 192
Cary Clarkbad5ad72017-08-03 17:14:08 -04002203void draw(SkCanvas* canvas) {
2204 SkPaint paint;
2205 paint.setTextSize(96);
2206 canvas->drawString("A1", 130, 100, paint);
2207 canvas->rotate(180, 130, 100);
2208 canvas->drawString("A1", 130, 100, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002209}
2210##
2211
Cary Clark2ade9972017-11-02 17:49:34 -04002212#SeeAlso concat() translate() skew() scale() setMatrix
Cary Clark8032b982017-07-28 11:04:54 -04002213
2214##
2215
2216# ------------------------------------------------------------------------------
2217
2218#Method void skew(SkScalar sx, SkScalar sy)
2219
Cary Clarkbad5ad72017-08-03 17:14:08 -04002220Skew Matrix by sx on the x-axis and sy on the y-axis. A positive value of sx
2221skews the drawing right as y increases; a positive value of sy skews the drawing
2222down as x increases.
Cary Clark8032b982017-07-28 11:04:54 -04002223
Cary Clarkce101242017-09-01 15:51:02 -04002224Mathematically, replace Matrix with a skew matrix Premultiplied with Matrix.
Cary Clark8032b982017-07-28 11:04:54 -04002225
Cary Clarkbad5ad72017-08-03 17:14:08 -04002226This has the effect of skewing the drawing by (sx, sy) before transforming
Cary Clark8032b982017-07-28 11:04:54 -04002227the result with Matrix.
2228
Cary Clarkbad5ad72017-08-03 17:14:08 -04002229#Param sx amount to skew in x ##
2230#Param sy amount to skew in y ##
2231
Cary Clark8032b982017-07-28 11:04:54 -04002232#Example
2233 #Description
2234 Black text mimics an oblique text style by using a negative skew in x that
2235 shifts the geometry to the right as the y values decrease.
2236 Red text uses a positive skew in y to shift the geometry down as the x values
2237 increase.
2238 Blue text combines x and y skew to rotate and scale.
2239 ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002240 SkPaint paint;
2241 paint.setTextSize(128);
2242 canvas->translate(30, 130);
2243 canvas->save();
2244 canvas->skew(-.5, 0);
2245 canvas->drawString("A1", 0, 0, paint);
2246 canvas->restore();
2247 canvas->save();
2248 canvas->skew(0, .5);
2249 paint.setColor(SK_ColorRED);
2250 canvas->drawString("A1", 0, 0, paint);
2251 canvas->restore();
2252 canvas->skew(-.5, .5);
2253 paint.setColor(SK_ColorBLUE);
Cary Clark8032b982017-07-28 11:04:54 -04002254 canvas->drawString("A1", 0, 0, paint);
2255##
2256
Cary Clark2ade9972017-11-02 17:49:34 -04002257#SeeAlso concat() translate() rotate() scale() setMatrix
Cary Clark8032b982017-07-28 11:04:54 -04002258
2259##
2260
2261# ------------------------------------------------------------------------------
2262
2263#Method void concat(const SkMatrix& matrix)
2264
Cary Clarkce101242017-09-01 15:51:02 -04002265Replace Matrix with matrix Premultiplied with existing Matrix.
Cary Clark8032b982017-07-28 11:04:54 -04002266
Cary Clarkbad5ad72017-08-03 17:14:08 -04002267This has the effect of transforming the drawn geometry by matrix, before
2268transforming the result with existing Matrix.
Cary Clark8032b982017-07-28 11:04:54 -04002269
Cary Clarkce101242017-09-01 15:51:02 -04002270#Param matrix matrix to Premultiply with existing Matrix ##
Cary Clark8032b982017-07-28 11:04:54 -04002271
2272#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04002273void draw(SkCanvas* canvas) {
2274 SkPaint paint;
2275 paint.setTextSize(80);
2276 paint.setTextScaleX(.3);
2277 SkMatrix matrix;
2278 SkRect rect[2] = {{ 10, 20, 90, 110 }, { 40, 130, 140, 180 }};
2279 matrix.setRectToRect(rect[0], rect[1], SkMatrix::kFill_ScaleToFit);
2280 canvas->drawRect(rect[0], paint);
2281 canvas->drawRect(rect[1], paint);
2282 paint.setColor(SK_ColorWHITE);
2283 canvas->drawString("Here", rect[0].fLeft + 10, rect[0].fBottom - 10, paint);
2284 canvas->concat(matrix);
2285 canvas->drawString("There", rect[0].fLeft + 10, rect[0].fBottom - 10, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002286}
2287##
2288
Cary Clark2ade9972017-11-02 17:49:34 -04002289#SeeAlso translate() rotate() scale() skew() setMatrix
Cary Clark8032b982017-07-28 11:04:54 -04002290
2291##
2292
2293# ------------------------------------------------------------------------------
2294
2295#Method void setMatrix(const SkMatrix& matrix)
2296
2297Replace Matrix with matrix.
2298Unlike concat(), any prior matrix state is overwritten.
2299
Cary Clarkbad5ad72017-08-03 17:14:08 -04002300#Param matrix matrix to copy, replacing existing Matrix ##
Cary Clark8032b982017-07-28 11:04:54 -04002301
2302#Example
2303#Height 128
Cary Clarkbad5ad72017-08-03 17:14:08 -04002304void draw(SkCanvas* canvas) {
2305 SkPaint paint;
2306 canvas->scale(4, 6);
2307 canvas->drawString("truth", 2, 10, paint);
2308 SkMatrix matrix;
2309 matrix.setScale(2.8f, 6);
2310 canvas->setMatrix(matrix);
2311 canvas->drawString("consequences", 2, 20, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002312}
2313##
2314
Cary Clark2ade9972017-11-02 17:49:34 -04002315#SeeAlso resetMatrix concat() translate() rotate() scale() skew()
Cary Clark8032b982017-07-28 11:04:54 -04002316
2317##
2318
2319# ------------------------------------------------------------------------------
2320
2321#Method void resetMatrix()
2322
2323Sets Matrix to the identity matrix.
2324Any prior matrix state is overwritten.
2325
2326#Example
2327#Height 128
Cary Clarkbad5ad72017-08-03 17:14:08 -04002328void draw(SkCanvas* canvas) {
2329 SkPaint paint;
2330 canvas->scale(4, 6);
2331 canvas->drawString("truth", 2, 10, paint);
2332 canvas->resetMatrix();
2333 canvas->scale(2.8f, 6);
2334 canvas->drawString("consequences", 2, 20, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002335}
2336##
2337
Cary Clark2ade9972017-11-02 17:49:34 -04002338#SeeAlso setMatrix concat() translate() rotate() scale() skew()
Cary Clark8032b982017-07-28 11:04:54 -04002339
2340##
2341
2342# ------------------------------------------------------------------------------
2343
2344#Method const SkMatrix& getTotalMatrix() const
2345
2346Returns Matrix.
2347This does not account for translation by Device or Surface.
2348
Cary Clarkbad5ad72017-08-03 17:14:08 -04002349#Return Matrix in Canvas ##
Cary Clark8032b982017-07-28 11:04:54 -04002350
2351#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04002352 SkDebugf("isIdentity %s\n", canvas->getTotalMatrix().isIdentity() ? "true" : "false");
2353 #StdOut
2354 isIdentity true
2355 ##
Cary Clark8032b982017-07-28 11:04:54 -04002356##
2357
Cary Clark2ade9972017-11-02 17:49:34 -04002358#SeeAlso setMatrix resetMatrix concat()
Cary Clark8032b982017-07-28 11:04:54 -04002359
2360##
2361
2362#Topic Matrix ##
2363
2364# ------------------------------------------------------------------------------
2365#Topic Clip
2366
2367Clip is built from a stack of clipping paths. Each Path in the
2368stack can be constructed from one or more Path_Contour elements. The
2369Path_Contour may be composed of any number of Path_Verb segments. Each
2370Path_Contour forms a closed area; Path_Fill_Type defines the area enclosed
2371by Path_Contour.
2372
2373Clip stack of Path elements successfully restrict the Path area. Each
2374Path is transformed by Matrix, then intersected with or subtracted from the
2375prior Clip to form the replacement Clip. Use SkClipOp::kDifference
2376to subtract Path from Clip; use SkClipOp::kIntersect to intersect Path
2377with Clip.
2378
Cary Clarkce101242017-09-01 15:51:02 -04002379A clipping Path may be Anti-aliased; if Path, after transformation, is
Cary Clark8032b982017-07-28 11:04:54 -04002380composed of horizontal and vertical lines, clearing Anti-alias allows whole pixels
Cary Clarkce101242017-09-01 15:51:02 -04002381to either be inside or outside the clip. The fastest drawing has a Aliased,
2382rectangular clip.
Cary Clark8032b982017-07-28 11:04:54 -04002383
2384If clipping Path has Anti-alias set, clip may partially clip a pixel, requiring
2385that drawing blend partially with the destination along the edge. A rotated
Cary Clarkce101242017-09-01 15:51:02 -04002386rectangular Anti-aliased clip looks smoother but draws slower.
Cary Clark8032b982017-07-28 11:04:54 -04002387
2388Clip can combine with Rect and Round_Rect primitives; like
2389Path, these are transformed by Matrix before they are combined with Clip.
2390
2391Clip can combine with Region. Region is assumed to be in Device coordinates
2392and is unaffected by Matrix.
2393
2394#Example
2395#Height 90
2396 #Description
Cary Clarkce101242017-09-01 15:51:02 -04002397 Draw a red circle with an Aliased clip and an Anti-aliased clip.
Cary Clark8032b982017-07-28 11:04:54 -04002398 Use an image filter to zoom into the pixels drawn.
Cary Clarkce101242017-09-01 15:51:02 -04002399 The edge of the Aliased clip fully draws pixels in the red circle.
2400 The edge of the Anti-aliased clip partially draws pixels in the red circle.
Cary Clark8032b982017-07-28 11:04:54 -04002401 ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002402 SkPaint redPaint, scalePaint;
2403 redPaint.setAntiAlias(true);
2404 redPaint.setColor(SK_ColorRED);
2405 canvas->save();
2406 for (bool antialias : { false, true } ) {
2407 canvas->save();
2408 canvas->clipRect(SkRect::MakeWH(19.5f, 11.5f), antialias);
2409 canvas->drawCircle(17, 11, 8, redPaint);
2410 canvas->restore();
2411 canvas->translate(16, 0);
2412 }
2413 canvas->restore();
2414 SkMatrix matrix;
2415 matrix.setScale(6, 6);
2416 scalePaint.setImageFilter(
2417 SkImageFilter::MakeMatrixFilter(matrix, kNone_SkFilterQuality, nullptr));
2418 SkCanvas::SaveLayerRec saveLayerRec(
2419 nullptr, &scalePaint, SkCanvas::kInitWithPrevious_SaveLayerFlag);
2420 canvas->saveLayer(saveLayerRec);
Cary Clark8032b982017-07-28 11:04:54 -04002421 canvas->restore();
2422##
2423
2424#Method void clipRect(const SkRect& rect, SkClipOp op, bool doAntiAlias)
2425
2426Replace Clip with the intersection or difference of Clip and rect,
Cary Clarkce101242017-09-01 15:51:02 -04002427with an Aliased or Anti-aliased clip edge. rect is transformed by Matrix
Cary Clark8032b982017-07-28 11:04:54 -04002428before it is combined with Clip.
2429
Cary Clarka523d2d2017-08-30 08:58:10 -04002430#Param rect Rect to combine with Clip ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002431#Param op Clip_Op to apply to Clip ##
Cary Clarkce101242017-09-01 15:51:02 -04002432#Param doAntiAlias true if Clip is to be Anti-aliased ##
Cary Clark8032b982017-07-28 11:04:54 -04002433
2434#Example
2435#Height 128
Cary Clarkbad5ad72017-08-03 17:14:08 -04002436void draw(SkCanvas* canvas) {
2437 canvas->rotate(10);
2438 SkPaint paint;
2439 paint.setAntiAlias(true);
2440 for (auto alias: { false, true } ) {
2441 canvas->save();
2442 canvas->clipRect(SkRect::MakeWH(90, 80), SkClipOp::kIntersect, alias);
2443 canvas->drawCircle(100, 60, 60, paint);
2444 canvas->restore();
2445 canvas->translate(80, 0);
2446 }
Cary Clark8032b982017-07-28 11:04:54 -04002447}
2448##
2449
Cary Clark2ade9972017-11-02 17:49:34 -04002450#SeeAlso clipRRect clipPath clipRegion
Cary Clark8032b982017-07-28 11:04:54 -04002451
2452##
2453
2454#Method void clipRect(const SkRect& rect, SkClipOp op)
2455
2456Replace Clip with the intersection or difference of Clip and rect.
Cary Clarkce101242017-09-01 15:51:02 -04002457Resulting Clip is Aliased; pixels are fully contained by the clip.
Cary Clarkbad5ad72017-08-03 17:14:08 -04002458rect is transformed by Matrix before it is combined with Clip.
Cary Clark8032b982017-07-28 11:04:54 -04002459
Cary Clarka523d2d2017-08-30 08:58:10 -04002460#Param rect Rect to combine with Clip ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002461#Param op Clip_Op to apply to Clip ##
Cary Clark8032b982017-07-28 11:04:54 -04002462
2463#Example
2464#Height 192
2465#Width 280
Cary Clarkbad5ad72017-08-03 17:14:08 -04002466void draw(SkCanvas* canvas) {
2467 SkPaint paint;
2468 for (SkClipOp op: { SkClipOp::kIntersect, SkClipOp::kDifference } ) {
2469 canvas->save();
2470 canvas->clipRect(SkRect::MakeWH(90, 120), op, false);
2471 canvas->drawCircle(100, 100, 60, paint);
2472 canvas->restore();
2473 canvas->translate(80, 0);
2474 }
Cary Clark8032b982017-07-28 11:04:54 -04002475}
2476##
2477
Cary Clark2ade9972017-11-02 17:49:34 -04002478#SeeAlso clipRRect clipPath clipRegion
Cary Clark8032b982017-07-28 11:04:54 -04002479
2480##
2481
2482#Method void clipRect(const SkRect& rect, bool doAntiAlias = false)
2483
2484Replace Clip with the intersection of Clip and rect.
Cary Clarkce101242017-09-01 15:51:02 -04002485Resulting Clip is Aliased; pixels are fully contained by the clip.
Cary Clark8032b982017-07-28 11:04:54 -04002486rect is transformed by Matrix
2487before it is combined with Clip.
2488
Cary Clarka523d2d2017-08-30 08:58:10 -04002489#Param rect Rect to combine with Clip ##
Cary Clarkce101242017-09-01 15:51:02 -04002490#Param doAntiAlias true if Clip is to be Anti-aliased ##
Cary Clark8032b982017-07-28 11:04:54 -04002491
2492#Example
2493#Height 133
2494 #Description
Cary Clarkce101242017-09-01 15:51:02 -04002495 A circle drawn in pieces looks uniform when drawn Aliased.
2496 The same circle pieces blend with pixels more than once when Anti-aliased,
Cary Clark8032b982017-07-28 11:04:54 -04002497 visible as a thin pair of lines through the right circle.
2498 ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002499void draw(SkCanvas* canvas) {
2500 canvas->clear(SK_ColorWHITE);
2501 SkPaint paint;
2502 paint.setAntiAlias(true);
2503 paint.setColor(0x8055aaff);
2504 SkRect clipRect = { 0, 0, 87.4f, 87.4f };
2505 for (auto alias: { false, true } ) {
2506 canvas->save();
2507 canvas->clipRect(clipRect, SkClipOp::kIntersect, alias);
2508 canvas->drawCircle(67, 67, 60, paint);
2509 canvas->restore();
2510 canvas->save();
2511 canvas->clipRect(clipRect, SkClipOp::kDifference, alias);
2512 canvas->drawCircle(67, 67, 60, paint);
2513 canvas->restore();
2514 canvas->translate(120, 0);
2515 }
Cary Clark8032b982017-07-28 11:04:54 -04002516}
2517##
2518
Cary Clark2ade9972017-11-02 17:49:34 -04002519#SeeAlso clipRRect clipPath clipRegion
Cary Clark8032b982017-07-28 11:04:54 -04002520
2521##
2522
2523#Method void androidFramework_setDeviceClipRestriction(const SkIRect& rect)
2524
Cary Clarkce101242017-09-01 15:51:02 -04002525Sets the maximum clip rectangle, which can be set by clipRect, clipRRect and
Cary Clark8032b982017-07-28 11:04:54 -04002526clipPath and intersect the current clip with the specified rect.
Cary Clarkce101242017-09-01 15:51:02 -04002527The maximum clip affects only future clipping operations; it is not retroactive.
Cary Clark8032b982017-07-28 11:04:54 -04002528The clip restriction is not recorded in pictures.
2529
Cary Clarkce101242017-09-01 15:51:02 -04002530Pass an empty rect to disable maximum clip.
Cary Clarkbad5ad72017-08-03 17:14:08 -04002531
Cary Clark8032b982017-07-28 11:04:54 -04002532#Private
2533This is private API to be used only by Android framework.
2534##
2535
Cary Clarkbad5ad72017-08-03 17:14:08 -04002536#Param rect maximum allowed clip in device coordinates
Cary Clark579985c2017-07-31 11:48:27 -04002537#Param ##
Cary Clark8032b982017-07-28 11:04:54 -04002538
2539##
2540
2541#Method void clipRRect(const SkRRect& rrect, SkClipOp op, bool doAntiAlias)
2542
2543Replace Clip with the intersection or difference of Clip and rrect,
Cary Clarkce101242017-09-01 15:51:02 -04002544with an Aliased or Anti-aliased clip edge.
Cary Clark8032b982017-07-28 11:04:54 -04002545rrect is transformed by Matrix
2546before it is combined with Clip.
2547
Cary Clarkbad5ad72017-08-03 17:14:08 -04002548#Param rrect Round_Rect to combine with Clip ##
2549#Param op Clip_Op to apply to Clip ##
Cary Clarkce101242017-09-01 15:51:02 -04002550#Param doAntiAlias true if Clip is to be Anti-aliased ##
Cary Clark8032b982017-07-28 11:04:54 -04002551
2552#Example
2553#Height 128
Cary Clarkbad5ad72017-08-03 17:14:08 -04002554void draw(SkCanvas* canvas) {
2555 canvas->clear(SK_ColorWHITE);
2556 SkPaint paint;
2557 paint.setAntiAlias(true);
2558 paint.setColor(0x8055aaff);
2559 SkRRect oval;
2560 oval.setOval({10, 20, 90, 100});
2561 canvas->clipRRect(oval, SkClipOp::kIntersect, true);
2562 canvas->drawCircle(70, 100, 60, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002563}
2564##
2565
Cary Clark2ade9972017-11-02 17:49:34 -04002566#SeeAlso clipRect clipPath clipRegion
Cary Clark8032b982017-07-28 11:04:54 -04002567
2568##
2569
2570#Method void clipRRect(const SkRRect& rrect, SkClipOp op)
2571
2572Replace Clip with the intersection or difference of Clip and rrect.
Cary Clarkce101242017-09-01 15:51:02 -04002573Resulting Clip is Aliased; pixels are fully contained by the clip.
Cary Clarkbad5ad72017-08-03 17:14:08 -04002574rrect is transformed by Matrix before it is combined with Clip.
Cary Clark8032b982017-07-28 11:04:54 -04002575
Cary Clarkbad5ad72017-08-03 17:14:08 -04002576#Param rrect Round_Rect to combine with Clip ##
2577#Param op Clip_Op to apply to Clip ##
Cary Clark8032b982017-07-28 11:04:54 -04002578
2579#Example
2580#Height 128
Cary Clarkbad5ad72017-08-03 17:14:08 -04002581void draw(SkCanvas* canvas) {
2582 SkPaint paint;
2583 paint.setColor(0x8055aaff);
2584 auto oval = SkRRect::MakeOval({10, 20, 90, 100});
2585 canvas->clipRRect(oval, SkClipOp::kIntersect);
2586 canvas->drawCircle(70, 100, 60, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002587}
2588##
2589
Cary Clark2ade9972017-11-02 17:49:34 -04002590#SeeAlso clipRect clipPath clipRegion
Cary Clark8032b982017-07-28 11:04:54 -04002591
2592##
2593
2594#Method void clipRRect(const SkRRect& rrect, bool doAntiAlias = false)
2595
2596Replace Clip with the intersection of Clip and rrect,
Cary Clarkce101242017-09-01 15:51:02 -04002597with an Aliased or Anti-aliased clip edge.
Cary Clarkbad5ad72017-08-03 17:14:08 -04002598rrect is transformed by Matrix before it is combined with Clip.
Cary Clark8032b982017-07-28 11:04:54 -04002599
Cary Clarkbad5ad72017-08-03 17:14:08 -04002600#Param rrect Round_Rect to combine with Clip ##
Cary Clarkce101242017-09-01 15:51:02 -04002601#Param doAntiAlias true if Clip is to be Anti-aliased ##
Cary Clark8032b982017-07-28 11:04:54 -04002602
2603#Example
2604#Height 128
Cary Clarkbad5ad72017-08-03 17:14:08 -04002605void draw(SkCanvas* canvas) {
2606 SkPaint paint;
2607 paint.setAntiAlias(true);
2608 auto oval = SkRRect::MakeRectXY({10, 20, 90, 100}, 9, 13);
2609 canvas->clipRRect(oval, true);
2610 canvas->drawCircle(70, 100, 60, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002611}
2612##
2613
Cary Clark2ade9972017-11-02 17:49:34 -04002614#SeeAlso clipRect clipPath clipRegion
Cary Clark8032b982017-07-28 11:04:54 -04002615
2616##
2617
2618#Method void clipPath(const SkPath& path, SkClipOp op, bool doAntiAlias)
2619
2620Replace Clip with the intersection or difference of Clip and path,
Cary Clarkce101242017-09-01 15:51:02 -04002621with an Aliased or Anti-aliased clip edge. Path_Fill_Type determines if path
Cary Clark8032b982017-07-28 11:04:54 -04002622describes the area inside or outside its contours; and if Path_Contour overlaps
2623itself or another Path_Contour, whether the overlaps form part of the area.
Cary Clarkbad5ad72017-08-03 17:14:08 -04002624path is transformed by Matrix before it is combined with Clip.
Cary Clark8032b982017-07-28 11:04:54 -04002625
Cary Clarkbad5ad72017-08-03 17:14:08 -04002626#Param path Path to combine with Clip ##
2627#Param op Clip_Op to apply to Clip ##
Cary Clarkce101242017-09-01 15:51:02 -04002628#Param doAntiAlias true if Clip is to be Anti-aliased ##
Cary Clark8032b982017-07-28 11:04:54 -04002629
2630#Example
2631#Description
2632Top figure uses SkPath::kInverseWinding_FillType and SkClipOp::kDifference;
2633area outside clip is subtracted from circle.
2634
2635Bottom figure uses SkPath::kWinding_FillType and SkClipOp::kIntersect;
2636area inside clip is intersected with circle.
2637##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002638void draw(SkCanvas* canvas) {
2639 SkPaint paint;
2640 paint.setAntiAlias(true);
2641 SkPath path;
2642 path.addRect({20, 30, 100, 110});
2643 path.setFillType(SkPath::kInverseWinding_FillType);
2644 canvas->save();
2645 canvas->clipPath(path, SkClipOp::kDifference, false);
2646 canvas->drawCircle(70, 100, 60, paint);
2647 canvas->restore();
2648 canvas->translate(100, 100);
2649 path.setFillType(SkPath::kWinding_FillType);
2650 canvas->clipPath(path, SkClipOp::kIntersect, false);
2651 canvas->drawCircle(70, 100, 60, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002652}
2653##
2654
Cary Clark2ade9972017-11-02 17:49:34 -04002655#SeeAlso clipRect clipRRect clipRegion
Cary Clark8032b982017-07-28 11:04:54 -04002656
2657##
2658
2659#Method void clipPath(const SkPath& path, SkClipOp op)
2660
2661Replace Clip with the intersection or difference of Clip and path.
Cary Clarkce101242017-09-01 15:51:02 -04002662Resulting Clip is Aliased; pixels are fully contained by the clip.
Cary Clark8032b982017-07-28 11:04:54 -04002663Path_Fill_Type determines if path
2664describes the area inside or outside its contours; and if Path_Contour overlaps
2665itself or another Path_Contour, whether the overlaps form part of the area.
2666path is transformed by Matrix
2667before it is combined with Clip.
2668
Cary Clarkbad5ad72017-08-03 17:14:08 -04002669#Param path Path to combine with Clip ##
2670#Param op Clip_Op to apply to Clip ##
Cary Clark8032b982017-07-28 11:04:54 -04002671
2672#Example
2673#Description
Cary Clarkbc5697d2017-10-04 14:31:33 -04002674Overlapping Rects form a clip. When clip Path_Fill_Type is set to
Cary Clark8032b982017-07-28 11:04:54 -04002675SkPath::kWinding_FillType, the overlap is included. Set to
2676SkPath::kEvenOdd_FillType, the overlap is excluded and forms a hole.
2677##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002678void draw(SkCanvas* canvas) {
2679 SkPaint paint;
2680 paint.setAntiAlias(true);
2681 SkPath path;
2682 path.addRect({20, 15, 100, 95});
2683 path.addRect({50, 65, 130, 135});
2684 path.setFillType(SkPath::kWinding_FillType);
2685 canvas->save();
2686 canvas->clipPath(path, SkClipOp::kIntersect);
2687 canvas->drawCircle(70, 85, 60, paint);
2688 canvas->restore();
2689 canvas->translate(100, 100);
2690 path.setFillType(SkPath::kEvenOdd_FillType);
2691 canvas->clipPath(path, SkClipOp::kIntersect);
2692 canvas->drawCircle(70, 85, 60, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002693}
2694##
2695
Cary Clark2ade9972017-11-02 17:49:34 -04002696#SeeAlso clipRect clipRRect clipRegion
Cary Clark8032b982017-07-28 11:04:54 -04002697
2698##
2699
2700#Method void clipPath(const SkPath& path, bool doAntiAlias = false)
2701
2702Replace Clip with the intersection of Clip and path.
Cary Clarkce101242017-09-01 15:51:02 -04002703Resulting Clip is Aliased; pixels are fully contained by the clip.
Cary Clark8032b982017-07-28 11:04:54 -04002704Path_Fill_Type determines if path
2705describes the area inside or outside its contours; and if Path_Contour overlaps
2706itself or another Path_Contour, whether the overlaps form part of the area.
Cary Clarkbad5ad72017-08-03 17:14:08 -04002707path is transformed by Matrix before it is combined with Clip.
Cary Clark8032b982017-07-28 11:04:54 -04002708
Cary Clarkbad5ad72017-08-03 17:14:08 -04002709#Param path Path to combine with Clip ##
Cary Clarkce101242017-09-01 15:51:02 -04002710#Param doAntiAlias true if Clip is to be Anti-aliased ##
Cary Clark8032b982017-07-28 11:04:54 -04002711
2712#Example
2713#Height 212
2714#Description
Cary Clarkbc5697d2017-10-04 14:31:33 -04002715Clip loops over itself covering its center twice. When clip Path_Fill_Type
Cary Clark8032b982017-07-28 11:04:54 -04002716is set to SkPath::kWinding_FillType, the overlap is included. Set to
2717SkPath::kEvenOdd_FillType, the overlap is excluded and forms a hole.
2718##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002719void draw(SkCanvas* canvas) {
2720 SkPaint paint;
2721 paint.setAntiAlias(true);
2722 SkPath path;
2723 SkPoint poly[] = {{20, 20}, { 80, 20}, { 80, 80}, {40, 80},
2724 {40, 40}, {100, 40}, {100, 100}, {20, 100}};
2725 path.addPoly(poly, SK_ARRAY_COUNT(poly), true);
2726 path.setFillType(SkPath::kWinding_FillType);
2727 canvas->save();
2728 canvas->clipPath(path, SkClipOp::kIntersect);
2729 canvas->drawCircle(50, 50, 45, paint);
2730 canvas->restore();
2731 canvas->translate(100, 100);
2732 path.setFillType(SkPath::kEvenOdd_FillType);
2733 canvas->clipPath(path, SkClipOp::kIntersect);
2734 canvas->drawCircle(50, 50, 45, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002735}
2736##
2737
Cary Clark2ade9972017-11-02 17:49:34 -04002738#SeeAlso clipRect clipRRect clipRegion
Cary Clark8032b982017-07-28 11:04:54 -04002739
2740##
2741
2742# ------------------------------------------------------------------------------
2743
2744#Method void setAllowSimplifyClip(bool allow)
2745
2746#Experimental
2747Only used for testing.
2748##
2749
Cary Clarkce101242017-09-01 15:51:02 -04002750Set to simplify clip stack using PathOps.
Cary Clark8032b982017-07-28 11:04:54 -04002751
2752##
2753
2754# ------------------------------------------------------------------------------
2755
2756#Method void clipRegion(const SkRegion& deviceRgn, SkClipOp op = SkClipOp::kIntersect)
2757
2758Replace Clip with the intersection or difference of Clip and Region deviceRgn.
Cary Clarkce101242017-09-01 15:51:02 -04002759Resulting Clip is Aliased; pixels are fully contained by the clip.
Cary Clark8032b982017-07-28 11:04:54 -04002760deviceRgn is unaffected by Matrix.
2761
Cary Clarkbad5ad72017-08-03 17:14:08 -04002762#Param deviceRgn Region to combine with Clip ##
2763#Param op Clip_Op to apply to Clip ##
Cary Clark8032b982017-07-28 11:04:54 -04002764
2765#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04002766#Description
Cary Clarkce101242017-09-01 15:51:02 -04002767 region is unaffected by canvas rotation; iRect is affected by canvas rotation.
2768 Both clips are Aliased; this is not noticeable on Region clip because it
Cary Clarkbad5ad72017-08-03 17:14:08 -04002769 aligns to pixel boundaries.
2770##
2771void draw(SkCanvas* canvas) {
2772 SkPaint paint;
2773 paint.setAntiAlias(true);
2774 SkIRect iRect = {30, 40, 120, 130 };
2775 SkRegion region(iRect);
2776 canvas->rotate(10);
2777 canvas->save();
2778 canvas->clipRegion(region, SkClipOp::kIntersect);
2779 canvas->drawCircle(50, 50, 45, paint);
2780 canvas->restore();
2781 canvas->translate(100, 100);
2782 canvas->clipRect(SkRect::Make(iRect), SkClipOp::kIntersect);
2783 canvas->drawCircle(50, 50, 45, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002784}
2785##
2786
Cary Clark2ade9972017-11-02 17:49:34 -04002787#SeeAlso clipRect clipRRect clipPath
Cary Clark8032b982017-07-28 11:04:54 -04002788
2789##
2790
2791#Method bool quickReject(const SkRect& rect) const
2792
2793Return true if Rect rect, transformed by Matrix, can be quickly determined to be
2794outside of Clip. May return false even though rect is outside of Clip.
2795
2796Use to check if an area to be drawn is clipped out, to skip subsequent draw calls.
2797
Cary Clarkbad5ad72017-08-03 17:14:08 -04002798#Param rect Rect to compare with Clip ##
Cary Clark8032b982017-07-28 11:04:54 -04002799
Cary Clarkbad5ad72017-08-03 17:14:08 -04002800#Return true if rect, transformed by Matrix, does not intersect Clip ##
Cary Clark8032b982017-07-28 11:04:54 -04002801
2802#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04002803void draw(SkCanvas* canvas) {
2804 SkRect testRect = {30, 30, 120, 129 };
2805 SkRect clipRect = {30, 130, 120, 230 };
2806 canvas->save();
2807 canvas->clipRect(clipRect);
2808 SkDebugf("quickReject %s\n", canvas->quickReject(testRect) ? "true" : "false");
2809 canvas->restore();
2810 canvas->rotate(10);
2811 canvas->clipRect(clipRect);
2812 SkDebugf("quickReject %s\n", canvas->quickReject(testRect) ? "true" : "false");
Cary Clark8032b982017-07-28 11:04:54 -04002813}
2814 #StdOut
Cary Clarkbad5ad72017-08-03 17:14:08 -04002815 quickReject true
Cary Clark8032b982017-07-28 11:04:54 -04002816 quickReject false
2817 ##
2818##
2819
Cary Clark2ade9972017-11-02 17:49:34 -04002820#SeeAlso getLocalClipBounds getTotalMatrix SkBitmap::drawsNothing
Cary Clark8032b982017-07-28 11:04:54 -04002821
2822##
2823
2824#Method bool quickReject(const SkPath& path) const
2825
2826Return true if path, transformed by Matrix, can be quickly determined to be
2827outside of Clip. May return false even though path is outside of Clip.
2828
2829Use to check if an area to be drawn is clipped out, to skip subsequent draw calls.
2830
Cary Clarkbad5ad72017-08-03 17:14:08 -04002831#Param path Path to compare with Clip ##
Cary Clark8032b982017-07-28 11:04:54 -04002832
Cary Clarkbad5ad72017-08-03 17:14:08 -04002833#Return true if path, transformed by Matrix, does not intersect Clip ##
Cary Clark8032b982017-07-28 11:04:54 -04002834
2835#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04002836void draw(SkCanvas* canvas) {
2837 SkPoint testPoints[] = {{30, 30}, {120, 30}, {120, 129} };
2838 SkPoint clipPoints[] = {{30, 130}, {120, 130}, {120, 230} };
2839 SkPath testPath, clipPath;
2840 testPath.addPoly(testPoints, SK_ARRAY_COUNT(testPoints), true);
2841 clipPath.addPoly(clipPoints, SK_ARRAY_COUNT(clipPoints), true);
2842 canvas->save();
2843 canvas->clipPath(clipPath);
2844 SkDebugf("quickReject %s\n", canvas->quickReject(testPath) ? "true" : "false");
2845 canvas->restore();
2846 canvas->rotate(10);
2847 canvas->clipPath(clipPath);
2848 SkDebugf("quickReject %s\n", canvas->quickReject(testPath) ? "true" : "false");
Cary Clark8032b982017-07-28 11:04:54 -04002849 #StdOut
Cary Clarkbad5ad72017-08-03 17:14:08 -04002850 quickReject true
Cary Clark8032b982017-07-28 11:04:54 -04002851 quickReject false
2852 ##
2853}
2854##
2855
Cary Clark2ade9972017-11-02 17:49:34 -04002856#SeeAlso getLocalClipBounds getTotalMatrix SkBitmap::drawsNothing
Cary Clark8032b982017-07-28 11:04:54 -04002857
2858##
2859
2860#Method SkRect getLocalClipBounds() const
2861
2862Return bounds of Clip, transformed by inverse of Matrix. If Clip is empty,
2863return SkRect::MakeEmpty, where all Rect sides equal zero.
2864
2865Rect returned is outset by one to account for partial pixel coverage if Clip
Cary Clarkce101242017-09-01 15:51:02 -04002866is Anti-aliased.
Cary Clark8032b982017-07-28 11:04:54 -04002867
Cary Clarkbad5ad72017-08-03 17:14:08 -04002868#Return bounds of Clip in local coordinates ##
Cary Clark8032b982017-07-28 11:04:54 -04002869
2870#Example
2871 #Description
2872 Initial bounds is device bounds outset by 1 on all sides.
2873 Clipped bounds is clipPath bounds outset by 1 on all sides.
2874 Scaling the canvas by two in x and y scales the local bounds by 1/2 in x and y.
2875 ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002876 SkCanvas local(256, 256);
2877 canvas = &local;
2878 SkRect bounds = canvas->getLocalClipBounds();
2879 SkDebugf("left:%g top:%g right:%g bottom:%g\n",
2880 bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom);
2881 SkPoint clipPoints[] = {{30, 130}, {120, 130}, {120, 230} };
2882 SkPath clipPath;
2883 clipPath.addPoly(clipPoints, SK_ARRAY_COUNT(clipPoints), true);
2884 canvas->clipPath(clipPath);
2885 bounds = canvas->getLocalClipBounds();
2886 SkDebugf("left:%g top:%g right:%g bottom:%g\n",
2887 bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom);
2888 canvas->scale(2, 2);
2889 bounds = canvas->getLocalClipBounds();
2890 SkDebugf("left:%g top:%g right:%g bottom:%g\n",
2891 bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom);
2892 #StdOut
2893 left:-1 top:-1 right:257 bottom:257
2894 left:29 top:129 right:121 bottom:231
2895 left:14.5 top:64.5 right:60.5 bottom:115.5
2896 ##
Cary Clark8032b982017-07-28 11:04:54 -04002897##
2898
2899# local canvas in example works around bug in fiddle ##
2900#Bug 6524 ##
Cary Clark2ade9972017-11-02 17:49:34 -04002901#SeeAlso getDeviceClipBounds getBaseLayerSize quickReject
Cary Clark8032b982017-07-28 11:04:54 -04002902
2903##
2904
2905#Method bool getLocalClipBounds(SkRect* bounds) const
2906
2907Return bounds of Clip, transformed by inverse of Matrix. If Clip is empty,
2908return false, and set bounds to SkRect::MakeEmpty, where all Rect sides equal zero.
2909
2910bounds is outset by one to account for partial pixel coverage if Clip
Cary Clarkce101242017-09-01 15:51:02 -04002911is Anti-aliased.
Cary Clark8032b982017-07-28 11:04:54 -04002912
Cary Clarkbad5ad72017-08-03 17:14:08 -04002913#Param bounds Rect of Clip in local coordinates ##
Cary Clark8032b982017-07-28 11:04:54 -04002914
Cary Clarkbad5ad72017-08-03 17:14:08 -04002915#Return true if Clip bounds is not empty ##
Cary Clark8032b982017-07-28 11:04:54 -04002916
2917#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04002918 void draw(SkCanvas* canvas) {
2919 SkCanvas local(256, 256);
2920 canvas = &local;
2921 SkRect bounds;
2922 SkDebugf("local bounds empty = %s\n", canvas->getLocalClipBounds(&bounds)
2923 ? "false" : "true");
2924 SkPath path;
2925 canvas->clipPath(path);
2926 SkDebugf("local bounds empty = %s\n", canvas->getLocalClipBounds(&bounds)
2927 ? "false" : "true");
Cary Clark8032b982017-07-28 11:04:54 -04002928 }
2929 #StdOut
Cary Clarkbad5ad72017-08-03 17:14:08 -04002930 local bounds empty = false
Cary Clark8032b982017-07-28 11:04:54 -04002931 local bounds empty = true
2932 ##
2933##
2934
2935# local canvas in example works around bug in fiddle ##
2936#Bug 6524 ##
Cary Clark2ade9972017-11-02 17:49:34 -04002937#SeeAlso getDeviceClipBounds getBaseLayerSize quickReject
Cary Clark8032b982017-07-28 11:04:54 -04002938
2939##
2940
2941#Method SkIRect getDeviceClipBounds() const
2942
2943Return IRect bounds of Clip, unaffected by Matrix. If Clip is empty,
2944return SkRect::MakeEmpty, where all Rect sides equal zero.
2945
2946Unlike getLocalClipBounds, returned IRect is not outset.
2947
Cary Clarkbad5ad72017-08-03 17:14:08 -04002948#Return bounds of Clip in Device coordinates ##
Cary Clark8032b982017-07-28 11:04:54 -04002949
2950#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04002951void draw(SkCanvas* canvas) {
2952 #Description
Cary Clark8032b982017-07-28 11:04:54 -04002953 Initial bounds is device bounds, not outset.
2954 Clipped bounds is clipPath bounds, not outset.
2955 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 -04002956 ##
2957 SkCanvas device(256, 256);
2958 canvas = &device;
2959 SkIRect bounds = canvas->getDeviceClipBounds();
2960 SkDebugf("left:%d top:%d right:%d bottom:%d\n",
2961 bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom);
2962 SkPoint clipPoints[] = {{30, 130}, {120, 130}, {120, 230} };
2963 SkPath clipPath;
2964 clipPath.addPoly(clipPoints, SK_ARRAY_COUNT(clipPoints), true);
2965 canvas->save();
2966 canvas->clipPath(clipPath);
2967 bounds = canvas->getDeviceClipBounds();
2968 SkDebugf("left:%d top:%d right:%d bottom:%d\n",
2969 bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom);
2970 canvas->restore();
2971 canvas->scale(1.f/2, 1.f/2);
2972 canvas->clipPath(clipPath);
2973 bounds = canvas->getDeviceClipBounds();
2974 SkDebugf("left:%d top:%d right:%d bottom:%d\n",
2975 bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom);
Cary Clark8032b982017-07-28 11:04:54 -04002976 #StdOut
Cary Clarkbad5ad72017-08-03 17:14:08 -04002977 left:0 top:0 right:256 bottom:256
2978 left:30 top:130 right:120 bottom:230
Cary Clark8032b982017-07-28 11:04:54 -04002979 left:15 top:65 right:60 bottom:115
2980 ##
2981}
2982##
2983
2984#ToDo some confusion on why with an identity Matrix local and device are different ##
Cary Clark2ade9972017-11-02 17:49:34 -04002985#SeeAlso getLocalClipBounds getBaseLayerSize quickReject
Cary Clark8032b982017-07-28 11:04:54 -04002986
2987# device canvas in example works around bug in fiddle ##
2988#Bug 6524 ##
2989
2990##
2991
2992#Method bool getDeviceClipBounds(SkIRect* bounds) const
2993
2994Return IRect bounds of Clip, unaffected by Matrix. If Clip is empty,
2995return false, and set bounds to SkRect::MakeEmpty, where all Rect sides equal zero.
2996
2997Unlike getLocalClipBounds, bounds is not outset.
2998
Cary Clarkbad5ad72017-08-03 17:14:08 -04002999#Param bounds Rect of Clip in device coordinates ##
Cary Clark8032b982017-07-28 11:04:54 -04003000
Cary Clarkbad5ad72017-08-03 17:14:08 -04003001#Return true if Clip bounds is not empty ##
Cary Clark8032b982017-07-28 11:04:54 -04003002
3003#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003004 void draw(SkCanvas* canvas) {
3005 SkIRect bounds;
3006 SkDebugf("device bounds empty = %s\n", canvas->getDeviceClipBounds(&bounds)
3007 ? "false" : "true");
3008 SkPath path;
3009 canvas->clipPath(path);
3010 SkDebugf("device bounds empty = %s\n", canvas->getDeviceClipBounds(&bounds)
3011 ? "false" : "true");
Cary Clark8032b982017-07-28 11:04:54 -04003012 }
3013 #StdOut
Cary Clarkbad5ad72017-08-03 17:14:08 -04003014 device bounds empty = false
Cary Clark8032b982017-07-28 11:04:54 -04003015 device bounds empty = true
3016 ##
3017##
3018
Cary Clark2ade9972017-11-02 17:49:34 -04003019#SeeAlso getLocalClipBounds getBaseLayerSize quickReject
Cary Clark8032b982017-07-28 11:04:54 -04003020
3021##
3022
3023#Topic Clip ##
3024
3025# ------------------------------------------------------------------------------
3026
3027#Method void drawColor(SkColor color, SkBlendMode mode = SkBlendMode::kSrcOver)
3028
3029Fill Clip with Color color.
3030mode determines how Color_ARGB is combined with destination.
3031
Cary Clarkbad5ad72017-08-03 17:14:08 -04003032#Param color Unpremultiplied Color_ARGB ##
3033#Param mode SkBlendMode used to combine source color and destination ##
Cary Clark8032b982017-07-28 11:04:54 -04003034
3035#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003036 canvas->drawColor(SK_ColorRED);
3037 canvas->clipRect(SkRect::MakeWH(150, 150));
3038 canvas->drawColor(SkColorSetARGB(0x80, 0x00, 0xFF, 0x00), SkBlendMode::kPlus);
3039 canvas->clipRect(SkRect::MakeWH(75, 75));
3040 canvas->drawColor(SkColorSetARGB(0x80, 0x00, 0x00, 0xFF), SkBlendMode::kPlus);
Cary Clark8032b982017-07-28 11:04:54 -04003041##
3042
Cary Clark2ade9972017-11-02 17:49:34 -04003043#SeeAlso clear SkBitmap::erase drawPaint
Cary Clark8032b982017-07-28 11:04:54 -04003044
3045##
3046
3047# ------------------------------------------------------------------------------
3048
3049#Method void clear(SkColor color)
3050
3051Fill Clip with Color color using SkBlendMode::kSrc.
3052This has the effect of replacing all pixels contained by Clip with color.
3053
Cary Clarkbad5ad72017-08-03 17:14:08 -04003054#Param color Unpremultiplied Color_ARGB ##
Cary Clark8032b982017-07-28 11:04:54 -04003055
3056#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003057void draw(SkCanvas* canvas) {
3058 canvas->save();
3059 canvas->clipRect(SkRect::MakeWH(256, 128));
3060 canvas->clear(SkColorSetARGB(0x80, 0xFF, 0x00, 0x00));
3061 canvas->restore();
3062 canvas->save();
3063 canvas->clipRect(SkRect::MakeWH(150, 192));
3064 canvas->clear(SkColorSetARGB(0x80, 0x00, 0xFF, 0x00));
3065 canvas->restore();
3066 canvas->clipRect(SkRect::MakeWH(75, 256));
3067 canvas->clear(SkColorSetARGB(0x80, 0x00, 0x00, 0xFF));
Cary Clark8032b982017-07-28 11:04:54 -04003068}
3069##
3070
Cary Clark2ade9972017-11-02 17:49:34 -04003071#SeeAlso drawColor SkBitmap::erase drawPaint
Cary Clark8032b982017-07-28 11:04:54 -04003072
3073##
3074
3075# ------------------------------------------------------------------------------
3076
3077#Method void discard()
3078
3079Make Canvas contents undefined. Subsequent calls that read Canvas pixels,
3080such as drawing with SkBlendMode, return undefined results. discard() does
3081not change Clip or Matrix.
3082
3083discard() may do nothing, depending on the implementation of Surface or Device
3084that created Canvas.
3085
3086discard() allows optimized performance on subsequent draws by removing
3087cached data associated with Surface or Device.
3088It is not necessary to call discard() once done with Canvas;
3089any cached data is deleted when owning Surface or Device is deleted.
3090
3091#ToDo example? not sure how to make this meaningful w/o more implementation detail ##
Cary Clark2ade9972017-11-02 17:49:34 -04003092#SeeAlso flush() SkSurface::prepareForExternalIO GrContext::abandonContext
Cary Clark8032b982017-07-28 11:04:54 -04003093
3094#NoExample
3095##
3096
3097##
3098
3099# ------------------------------------------------------------------------------
3100
3101#Method void drawPaint(const SkPaint& paint)
3102
Mike Reed8ad91a92018-01-19 19:09:32 -05003103Fill Clip with Paint paint. Paint components Mask_Filter, Shader,
Cary Clarkbad5ad72017-08-03 17:14:08 -04003104Color_Filter, Image_Filter, and Blend_Mode affect drawing;
3105Path_Effect in paint is ignored.
Cary Clark8032b982017-07-28 11:04:54 -04003106
3107# can Path_Effect in paint ever alter drawPaint?
3108
Cary Clarkbad5ad72017-08-03 17:14:08 -04003109#Param paint graphics state used to fill Canvas ##
Cary Clark8032b982017-07-28 11:04:54 -04003110
3111#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003112void draw(SkCanvas* canvas) {
3113 SkColor colors[] = { SK_ColorRED, SK_ColorGREEN, SK_ColorBLUE };
3114 SkScalar pos[] = { 0, SK_Scalar1/2, SK_Scalar1 };
3115 SkPaint paint;
3116 paint.setShader(SkGradientShader::MakeSweep(256, 256, colors, pos, SK_ARRAY_COUNT(colors)));
3117 canvas->drawPaint(paint);
Cary Clark8032b982017-07-28 11:04:54 -04003118}
3119##
3120
Cary Clark2ade9972017-11-02 17:49:34 -04003121#SeeAlso clear drawColor SkBitmap::erase
Cary Clark8032b982017-07-28 11:04:54 -04003122
3123##
3124
3125# ------------------------------------------------------------------------------
3126
3127#Enum PointMode
3128
3129#Code
3130 enum PointMode {
3131 kPoints_PointMode,
3132 kLines_PointMode,
Cary Clarkd0530ba2017-09-14 11:25:39 -04003133 kPolygon_PointMode,
Cary Clark8032b982017-07-28 11:04:54 -04003134 };
3135##
3136
3137Selects if an array of points are drawn as discrete points, as lines, or as
3138an open polygon.
3139
3140#Const kPoints_PointMode 0
3141 Draw each point separately.
3142##
3143
3144#Const kLines_PointMode 1
3145 Draw each pair of points as a line segment.
3146##
3147
3148#Const kPolygon_PointMode 2
3149 Draw the array of points as a open polygon.
3150##
3151
3152#Example
3153 #Description
3154 The upper left corner shows three squares when drawn as points.
3155 The upper right corner shows one line; when drawn as lines, two points are required per line.
3156 The lower right corner shows two lines; when draw as polygon, no miter is drawn at the corner.
3157 The lower left corner shows two lines with a miter when path contains polygon.
3158 ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003159void draw(SkCanvas* canvas) {
3160 SkPaint paint;
3161 paint.setStyle(SkPaint::kStroke_Style);
3162 paint.setStrokeWidth(10);
3163 SkPoint points[] = {{64, 32}, {96, 96}, {32, 96}};
3164 canvas->drawPoints(SkCanvas::kPoints_PointMode, 3, points, paint);
3165 canvas->translate(128, 0);
3166 canvas->drawPoints(SkCanvas::kLines_PointMode, 3, points, paint);
3167 canvas->translate(0, 128);
3168 canvas->drawPoints(SkCanvas::kPolygon_PointMode, 3, points, paint);
3169 SkPath path;
3170 path.addPoly(points, 3, false);
3171 canvas->translate(-128, 0);
3172 canvas->drawPath(path, paint);
Cary Clark8032b982017-07-28 11:04:54 -04003173}
3174##
3175
Cary Clark2ade9972017-11-02 17:49:34 -04003176#SeeAlso drawLine drawPoint drawPath
Cary Clark8032b982017-07-28 11:04:54 -04003177
3178##
3179
3180# ------------------------------------------------------------------------------
3181
3182#Method void drawPoints(PointMode mode, size_t count, const SkPoint pts[], const SkPaint& paint)
3183
3184Draw pts using Clip, Matrix and Paint paint.
Cary Clarkbad5ad72017-08-03 17:14:08 -04003185count is the number of points; if count is less than one, has no effect.
Cary Clark8032b982017-07-28 11:04:54 -04003186mode may be one of: kPoints_PointMode, kLines_PointMode, or kPolygon_PointMode.
3187
Cary Clarkbad5ad72017-08-03 17:14:08 -04003188If mode is kPoints_PointMode, the shape of point drawn depends on paint
3189Paint_Stroke_Cap. If paint is set to SkPaint::kRound_Cap, each point draws a
3190circle of diameter Paint_Stroke_Width. If paint is set to SkPaint::kSquare_Cap
3191or SkPaint::kButt_Cap, each point draws a square of width and height
3192Paint_Stroke_Width.
Cary Clark8032b982017-07-28 11:04:54 -04003193
3194If mode is kLines_PointMode, each pair of points draws a line segment.
3195One line is drawn for every two points; each point is used once. If count is odd,
3196the final point is ignored.
3197
3198If mode is kPolygon_PointMode, each adjacent pair of points draws a line segment.
3199count minus one lines are drawn; the first and last point are used once.
3200
3201Each line segment respects paint Paint_Stroke_Cap and Paint_Stroke_Width.
3202Paint_Style is ignored, as if were set to SkPaint::kStroke_Style.
3203
Cary Clarkbad5ad72017-08-03 17:14:08 -04003204Always draws each element one at a time; is not affected by
3205Paint_Stroke_Join, and unlike drawPath, does not create a mask from all points
3206and lines before drawing.
Cary Clark8032b982017-07-28 11:04:54 -04003207
Cary Clarka523d2d2017-08-30 08:58:10 -04003208#Param mode whether pts draws points or lines ##
3209#Param count number of points in the array ##
3210#Param pts array of points to draw ##
3211#Param paint stroke, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003212
3213#Example
3214#Height 200
3215 #Description
3216 #List
3217 # The first column draws points. ##
3218 # The second column draws points as lines. ##
3219 # The third column draws points as a polygon. ##
3220 # The fourth column draws points as a polygonal path. ##
3221 # The first row uses a round cap and round join. ##
3222 # The second row uses a square cap and a miter join. ##
3223 # The third row uses a butt cap and a bevel join. ##
3224 ##
3225 The transparent color makes multiple line draws visible;
3226 the path is drawn all at once.
3227 ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003228void draw(SkCanvas* canvas) {
3229 SkPaint paint;
3230 paint.setAntiAlias(true);
3231 paint.setStyle(SkPaint::kStroke_Style);
3232 paint.setStrokeWidth(10);
3233 paint.setColor(0x80349a45);
3234 const SkPoint points[] = {{32, 16}, {48, 48}, {16, 32}};
3235 const SkPaint::Join join[] = { SkPaint::kRound_Join,
3236 SkPaint::kMiter_Join,
3237 SkPaint::kBevel_Join };
3238 int joinIndex = 0;
3239 SkPath path;
3240 path.addPoly(points, 3, false);
3241 for (const auto cap : { SkPaint::kRound_Cap, SkPaint::kSquare_Cap, SkPaint::kButt_Cap } ) {
3242 paint.setStrokeCap(cap);
3243 paint.setStrokeJoin(join[joinIndex++]);
3244 for (const auto mode : { SkCanvas::kPoints_PointMode,
3245 SkCanvas::kLines_PointMode,
3246 SkCanvas::kPolygon_PointMode } ) {
3247 canvas->drawPoints(mode, 3, points, paint);
3248 canvas->translate(64, 0);
3249 }
3250 canvas->drawPath(path, paint);
3251 canvas->translate(-192, 64);
3252 }
Cary Clark8032b982017-07-28 11:04:54 -04003253}
3254##
3255
Cary Clark2ade9972017-11-02 17:49:34 -04003256#SeeAlso drawLine drawPoint drawPath
Cary Clark8032b982017-07-28 11:04:54 -04003257
3258##
3259
3260# ------------------------------------------------------------------------------
3261
3262#Method void drawPoint(SkScalar x, SkScalar y, const SkPaint& paint)
3263
3264Draw point at (x, y) using Clip, Matrix and Paint paint.
3265
3266The shape of point drawn depends on paint Paint_Stroke_Cap.
Cary Clarkbad5ad72017-08-03 17:14:08 -04003267If paint is set to SkPaint::kRound_Cap, draw a circle of diameter
3268Paint_Stroke_Width. If paint is set to SkPaint::kSquare_Cap or SkPaint::kButt_Cap,
Cary Clark8032b982017-07-28 11:04:54 -04003269draw a square of width and height Paint_Stroke_Width.
3270Paint_Style is ignored, as if were set to SkPaint::kStroke_Style.
3271
Cary Clarkbad5ad72017-08-03 17:14:08 -04003272#Param x left edge of circle or square ##
3273#Param y top edge of circle or square ##
3274#Param paint stroke, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003275
3276#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003277void draw(SkCanvas* canvas) {
3278 SkPaint paint;
3279 paint.setAntiAlias(true);
3280 paint.setColor(0x80349a45);
3281 paint.setStyle(SkPaint::kStroke_Style);
3282 paint.setStrokeWidth(100);
3283 paint.setStrokeCap(SkPaint::kRound_Cap);
3284 canvas->scale(1, 1.2f);
3285 canvas->drawPoint(64, 96, paint);
3286 canvas->scale(.6f, .8f);
3287 paint.setColor(SK_ColorWHITE);
3288 canvas->drawPoint(106, 120, paint);
Cary Clark8032b982017-07-28 11:04:54 -04003289}
3290##
3291
Cary Clark2ade9972017-11-02 17:49:34 -04003292#SeeAlso drawPoints drawCircle drawRect drawLine drawPath
Cary Clark8032b982017-07-28 11:04:54 -04003293
3294##
3295
Cary Clarkbad5ad72017-08-03 17:14:08 -04003296#Method void drawPoint(SkPoint p, const SkPaint& paint)
3297
3298Draw point p using Clip, Matrix and Paint paint.
3299
3300The shape of point drawn depends on paint Paint_Stroke_Cap.
3301If paint is set to SkPaint::kRound_Cap, draw a circle of diameter
3302Paint_Stroke_Width. If paint is set to SkPaint::kSquare_Cap or SkPaint::kButt_Cap,
3303draw a square of width and height Paint_Stroke_Width.
3304Paint_Style is ignored, as if were set to SkPaint::kStroke_Style.
3305
3306#Param p top-left edge of circle or square ##
3307#Param paint stroke, blend, color, and so on, used to draw ##
3308
3309#Example
3310void draw(SkCanvas* canvas) {
3311 SkPaint paint;
3312 paint.setAntiAlias(true);
3313 paint.setColor(0x80349a45);
3314 paint.setStyle(SkPaint::kStroke_Style);
3315 paint.setStrokeWidth(100);
3316 paint.setStrokeCap(SkPaint::kSquare_Cap);
3317 canvas->scale(1, 1.2f);
3318 canvas->drawPoint({64, 96}, paint);
3319 canvas->scale(.6f, .8f);
3320 paint.setColor(SK_ColorWHITE);
3321 canvas->drawPoint(106, 120, paint);
3322}
3323##
3324
Cary Clark2ade9972017-11-02 17:49:34 -04003325#SeeAlso drawPoints drawCircle drawRect drawLine drawPath
Cary Clarkbad5ad72017-08-03 17:14:08 -04003326
3327##
3328
Cary Clark8032b982017-07-28 11:04:54 -04003329# ------------------------------------------------------------------------------
3330
3331#Method void drawLine(SkScalar x0, SkScalar y0, SkScalar x1, SkScalar y1, const SkPaint& paint)
3332
Cary Clarkbad5ad72017-08-03 17:14:08 -04003333Draws line segment from (x0, y0) to (x1, y1) using Clip, Matrix, and Paint paint.
3334In paint: Paint_Stroke_Width describes the line thickness;
3335Paint_Stroke_Cap draws the end rounded or square;
Cary Clark8032b982017-07-28 11:04:54 -04003336Paint_Style is ignored, as if were set to SkPaint::kStroke_Style.
3337
Cary Clarkbad5ad72017-08-03 17:14:08 -04003338#Param x0 start of line segment on x-axis ##
3339#Param y0 start of line segment on y-axis ##
3340#Param x1 end of line segment on x-axis ##
3341#Param y1 end of line segment on y-axis ##
3342#Param paint stroke, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003343
3344#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003345 SkPaint paint;
3346 paint.setAntiAlias(true);
3347 paint.setColor(0xFF9a67be);
3348 paint.setStrokeWidth(20);
3349 canvas->skew(1, 0);
3350 canvas->drawLine(32, 96, 32, 160, paint);
3351 canvas->skew(-2, 0);
3352 canvas->drawLine(288, 96, 288, 160, paint);
3353##
3354
Cary Clark2ade9972017-11-02 17:49:34 -04003355#SeeAlso drawPoint drawCircle drawRect drawPath
Cary Clarkbad5ad72017-08-03 17:14:08 -04003356
3357##
3358
3359#Method void drawLine(SkPoint p0, SkPoint p1, const SkPaint& paint)
3360
3361Draws line segment from p0 to p1 using Clip, Matrix, and Paint paint.
3362In paint: Paint_Stroke_Width describes the line thickness;
3363Paint_Stroke_Cap draws the end rounded or square;
3364Paint_Style is ignored, as if were set to SkPaint::kStroke_Style.
3365
3366#Param p0 start of line segment ##
3367#Param p1 end of line segment ##
3368#Param paint stroke, blend, color, and so on, used to draw ##
3369
3370#Example
3371 SkPaint paint;
3372 paint.setAntiAlias(true);
3373 paint.setColor(0xFF9a67be);
3374 paint.setStrokeWidth(20);
3375 canvas->skew(1, 0);
3376 canvas->drawLine({32, 96}, {32, 160}, paint);
3377 canvas->skew(-2, 0);
3378 canvas->drawLine({288, 96}, {288, 160}, paint);
Cary Clark8032b982017-07-28 11:04:54 -04003379##
3380
Cary Clark2ade9972017-11-02 17:49:34 -04003381#SeeAlso drawPoint drawCircle drawRect drawPath
Cary Clark8032b982017-07-28 11:04:54 -04003382
3383##
3384
3385# ------------------------------------------------------------------------------
3386
3387#Method void drawRect(const SkRect& rect, const SkPaint& paint)
3388
3389Draw Rect rect using Clip, Matrix, and Paint paint.
3390In paint: Paint_Style determines if rectangle is stroked or filled;
3391if stroked, Paint_Stroke_Width describes the line thickness, and
3392Paint_Stroke_Join draws the corners rounded or square.
3393
Cary Clarkbc5697d2017-10-04 14:31:33 -04003394#Param rect rectangle to draw ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003395#Param paint stroke or fill, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003396
3397#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003398void draw(SkCanvas* canvas) {
3399 SkPoint rectPts[] = { {64, 48}, {192, 160} };
3400 SkPaint paint;
3401 paint.setAntiAlias(true);
3402 paint.setStyle(SkPaint::kStroke_Style);
3403 paint.setStrokeWidth(20);
3404 paint.setStrokeJoin(SkPaint::kRound_Join);
3405 SkMatrix rotator;
3406 rotator.setRotate(30, 128, 128);
3407 for (auto color : { SK_ColorRED, SK_ColorBLUE, SK_ColorYELLOW, SK_ColorMAGENTA } ) {
3408 paint.setColor(color);
3409 SkRect rect;
3410 rect.set(rectPts[0], rectPts[1]);
3411 canvas->drawRect(rect, paint);
3412 rotator.mapPoints(rectPts, 2);
3413 }
Cary Clark8032b982017-07-28 11:04:54 -04003414}
3415##
3416
Cary Clark2ade9972017-11-02 17:49:34 -04003417#SeeAlso drawIRect drawRRect drawRoundRect drawRegion drawPath drawLine
Cary Clark8032b982017-07-28 11:04:54 -04003418
3419##
3420
3421# ------------------------------------------------------------------------------
3422
3423#Method void drawIRect(const SkIRect& rect, const SkPaint& paint)
3424
3425Draw IRect rect using Clip, Matrix, and Paint paint.
3426In paint: Paint_Style determines if rectangle is stroked or filled;
3427if stroked, Paint_Stroke_Width describes the line thickness, and
3428Paint_Stroke_Join draws the corners rounded or square.
3429
Cary Clarkbc5697d2017-10-04 14:31:33 -04003430#Param rect rectangle to draw ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003431#Param paint stroke or fill, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003432
3433#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003434 SkIRect rect = { 64, 48, 192, 160 };
3435 SkPaint paint;
3436 paint.setAntiAlias(true);
3437 paint.setStyle(SkPaint::kStroke_Style);
3438 paint.setStrokeWidth(20);
3439 paint.setStrokeJoin(SkPaint::kRound_Join);
3440 for (auto color : { SK_ColorRED, SK_ColorBLUE, SK_ColorYELLOW, SK_ColorMAGENTA } ) {
3441 paint.setColor(color);
3442 canvas->drawIRect(rect, paint);
3443 canvas->rotate(30, 128, 128);
3444 }
Cary Clark8032b982017-07-28 11:04:54 -04003445##
3446
Cary Clark2ade9972017-11-02 17:49:34 -04003447#SeeAlso drawRect drawRRect drawRoundRect drawRegion drawPath drawLine
Cary Clark8032b982017-07-28 11:04:54 -04003448
3449##
3450
3451# ------------------------------------------------------------------------------
3452
3453#Method void drawRegion(const SkRegion& region, const SkPaint& paint)
3454
3455Draw Region region using Clip, Matrix, and Paint paint.
3456In paint: Paint_Style determines if rectangle is stroked or filled;
3457if stroked, Paint_Stroke_Width describes the line thickness, and
3458Paint_Stroke_Join draws the corners rounded or square.
3459
Cary Clarkbc5697d2017-10-04 14:31:33 -04003460#Param region region to draw ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003461#Param paint Paint stroke or fill, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003462
3463#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003464void draw(SkCanvas* canvas) {
3465 SkRegion region;
3466 region.op( 10, 10, 50, 50, SkRegion::kUnion_Op);
3467 region.op( 10, 50, 90, 90, SkRegion::kUnion_Op);
3468 SkPaint paint;
3469 paint.setAntiAlias(true);
3470 paint.setStyle(SkPaint::kStroke_Style);
3471 paint.setStrokeWidth(20);
3472 paint.setStrokeJoin(SkPaint::kRound_Join);
3473 canvas->drawRegion(region, paint);
Cary Clark8032b982017-07-28 11:04:54 -04003474}
3475##
3476
Cary Clark2ade9972017-11-02 17:49:34 -04003477#SeeAlso drawRect drawIRect drawPath
Cary Clark8032b982017-07-28 11:04:54 -04003478
3479##
3480
3481# ------------------------------------------------------------------------------
3482
3483#Method void drawOval(const SkRect& oval, const SkPaint& paint)
3484
3485Draw Oval oval using Clip, Matrix, and Paint.
3486In paint: Paint_Style determines if Oval is stroked or filled;
3487if stroked, Paint_Stroke_Width describes the line thickness.
3488
Cary Clarkbad5ad72017-08-03 17:14:08 -04003489#Param oval Rect bounds of Oval ##
3490#Param paint Paint stroke or fill, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003491
3492#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003493void draw(SkCanvas* canvas) {
3494 canvas->clear(0xFF3f5f9f);
3495 SkColor kColor1 = SkColorSetARGB(0xff, 0xff, 0x7f, 0);
3496 SkColor g1Colors[] = { kColor1, SkColorSetA(kColor1, 0x20) };
3497 SkPoint g1Points[] = { { 0, 0 }, { 0, 100 } };
3498 SkScalar pos[] = { 0.2f, 1.0f };
3499 SkRect bounds = SkRect::MakeWH(80, 70);
3500 SkPaint paint;
3501 paint.setAntiAlias(true);
3502 paint.setShader(SkGradientShader::MakeLinear(g1Points, g1Colors, pos, SK_ARRAY_COUNT(g1Colors),
3503 SkShader::kClamp_TileMode));
3504 canvas->drawOval(bounds , paint);
Cary Clark8032b982017-07-28 11:04:54 -04003505}
3506##
3507
Cary Clark2ade9972017-11-02 17:49:34 -04003508#SeeAlso drawCircle drawPoint drawPath drawRRect drawRoundRect
Cary Clark8032b982017-07-28 11:04:54 -04003509
3510##
3511
3512# ------------------------------------------------------------------------------
3513
3514#Method void drawRRect(const SkRRect& rrect, const SkPaint& paint)
3515
3516Draw Round_Rect rrect using Clip, Matrix, and Paint paint.
3517In paint: Paint_Style determines if rrect is stroked or filled;
3518if stroked, Paint_Stroke_Width describes the line thickness.
3519
Cary Clarkbad5ad72017-08-03 17:14:08 -04003520rrect may represent a rectangle, circle, oval, uniformly rounded rectangle, or
3521may have any combination of positive non-square radii for the four corners.
Cary Clark8032b982017-07-28 11:04:54 -04003522
Cary Clarkbad5ad72017-08-03 17:14:08 -04003523#Param rrect Round_Rect with up to eight corner radii to draw ##
3524#Param paint Paint stroke or fill, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003525
3526#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003527void draw(SkCanvas* canvas) {
3528 SkPaint paint;
3529 paint.setAntiAlias(true);
3530 SkRect outer = {30, 40, 210, 220};
3531 SkRect radii = {30, 50, 70, 90 };
3532 SkRRect rRect;
3533 rRect.setNinePatch(outer, radii.fLeft, radii.fTop, radii.fRight, radii.fBottom);
3534 canvas->drawRRect(rRect, paint);
3535 paint.setColor(SK_ColorWHITE);
3536 canvas->drawLine(outer.fLeft + radii.fLeft, outer.fTop,
3537 outer.fLeft + radii.fLeft, outer.fBottom, paint);
3538 canvas->drawLine(outer.fRight - radii.fRight, outer.fTop,
3539 outer.fRight - radii.fRight, outer.fBottom, paint);
3540 canvas->drawLine(outer.fLeft, outer.fTop + radii.fTop,
3541 outer.fRight, outer.fTop + radii.fTop, paint);
3542 canvas->drawLine(outer.fLeft, outer.fBottom - radii.fBottom,
3543 outer.fRight, outer.fBottom - radii.fBottom, paint);
3544}
Cary Clark8032b982017-07-28 11:04:54 -04003545##
3546
Cary Clark2ade9972017-11-02 17:49:34 -04003547#SeeAlso drawRect drawRoundRect drawDRRect drawCircle drawOval drawPath
Cary Clark8032b982017-07-28 11:04:54 -04003548
3549##
3550
3551# ------------------------------------------------------------------------------
3552
3553#Method void drawDRRect(const SkRRect& outer, const SkRRect& inner, const SkPaint& paint)
3554
3555Draw Round_Rect outer and inner
3556using Clip, Matrix, and Paint paint.
3557outer must contain inner or the drawing is undefined.
Cary Clarkce101242017-09-01 15:51:02 -04003558In paint: Paint_Style determines if Round_Rect is stroked or filled;
Cary Clark8032b982017-07-28 11:04:54 -04003559if stroked, Paint_Stroke_Width describes the line thickness.
Cary Clarkbad5ad72017-08-03 17:14:08 -04003560If stroked and Round_Rect corner has zero length radii, Paint_Stroke_Join can
3561draw corners rounded or square.
Cary Clark8032b982017-07-28 11:04:54 -04003562
Cary Clarkbad5ad72017-08-03 17:14:08 -04003563GPU-backed platforms optimize drawing when both outer and inner are
Cary Clark8032b982017-07-28 11:04:54 -04003564concave and outer contains inner. These platforms may not be able to draw
3565Path built with identical data as fast.
3566
Cary Clarkbad5ad72017-08-03 17:14:08 -04003567#Param outer Round_Rect outer bounds to draw ##
3568#Param inner Round_Rect inner bounds to draw ##
3569#Param paint Paint stroke or fill, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003570
3571#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003572void draw(SkCanvas* canvas) {
3573 SkRRect outer = SkRRect::MakeRect({20, 40, 210, 200});
3574 SkRRect inner = SkRRect::MakeOval({60, 70, 170, 160});
3575 SkPaint paint;
3576 canvas->drawDRRect(outer, inner, paint);
Cary Clark8032b982017-07-28 11:04:54 -04003577}
3578##
3579
3580#Example
3581#Description
3582 Outer Rect has no corner radii, but stroke join is rounded.
3583 Inner Round_Rect has corner radii; outset stroke increases radii of corners.
3584 Stroke join does not affect inner Round_Rect since it has no sharp corners.
3585##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003586void draw(SkCanvas* canvas) {
3587 SkRRect outer = SkRRect::MakeRect({20, 40, 210, 200});
3588 SkRRect inner = SkRRect::MakeRectXY({60, 70, 170, 160}, 10, 10);
3589 SkPaint paint;
3590 paint.setAntiAlias(true);
3591 paint.setStyle(SkPaint::kStroke_Style);
3592 paint.setStrokeWidth(20);
3593 paint.setStrokeJoin(SkPaint::kRound_Join);
3594 canvas->drawDRRect(outer, inner, paint);
3595 paint.setStrokeWidth(1);
3596 paint.setColor(SK_ColorWHITE);
3597 canvas->drawDRRect(outer, inner, paint);
Cary Clark8032b982017-07-28 11:04:54 -04003598}
3599##
3600
Cary Clark2ade9972017-11-02 17:49:34 -04003601#SeeAlso drawRect drawRoundRect drawRRect drawCircle drawOval drawPath
Cary Clark8032b982017-07-28 11:04:54 -04003602
3603##
3604
3605# ------------------------------------------------------------------------------
3606
3607#Method void drawCircle(SkScalar cx, SkScalar cy, SkScalar radius, const SkPaint& paint)
3608
3609Draw Circle at (cx, cy) with radius using Clip, Matrix, and Paint paint.
3610If radius is zero or less, nothing is drawn.
3611In paint: Paint_Style determines if Circle is stroked or filled;
3612if stroked, Paint_Stroke_Width describes the line thickness.
3613
Cary Clarkbad5ad72017-08-03 17:14:08 -04003614#Param cx Circle center on the x-axis ##
3615#Param cy Circle center on the y-axis ##
3616#Param radius half the diameter of Circle ##
3617#Param paint Paint stroke or fill, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003618
3619#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003620 void draw(SkCanvas* canvas) {
3621 SkPaint paint;
3622 paint.setAntiAlias(true);
3623 canvas->drawCircle(128, 128, 90, paint);
3624 paint.setColor(SK_ColorWHITE);
3625 canvas->drawCircle(86, 86, 20, paint);
3626 canvas->drawCircle(160, 76, 20, paint);
3627 canvas->drawCircle(140, 150, 35, paint);
3628 }
3629##
3630
Cary Clark2ade9972017-11-02 17:49:34 -04003631#SeeAlso drawOval drawRRect drawRoundRect drawPath drawArc drawPoint drawLine
Cary Clarkbad5ad72017-08-03 17:14:08 -04003632
3633##
3634
3635#Method void drawCircle(SkPoint center, SkScalar radius, const SkPaint& paint)
3636
Cary Clarkce101242017-09-01 15:51:02 -04003637Draw Circle at center with radius using Clip, Matrix, and Paint paint.
Cary Clarkbad5ad72017-08-03 17:14:08 -04003638If radius is zero or less, nothing is drawn.
3639In paint: Paint_Style determines if Circle is stroked or filled;
3640if stroked, Paint_Stroke_Width describes the line thickness.
3641
3642#Param center Circle center ##
3643#Param radius half the diameter of Circle ##
3644#Param paint Paint stroke or fill, blend, color, and so on, used to draw ##
3645
3646#Example
3647 void draw(SkCanvas* canvas) {
3648 SkPaint paint;
3649 paint.setAntiAlias(true);
3650 canvas->drawCircle(128, 128, 90, paint);
3651 paint.setColor(SK_ColorWHITE);
3652 canvas->drawCircle({86, 86}, 20, paint);
3653 canvas->drawCircle({160, 76}, 20, paint);
3654 canvas->drawCircle({140, 150}, 35, paint);
3655 }
Cary Clark8032b982017-07-28 11:04:54 -04003656##
3657
Cary Clark2ade9972017-11-02 17:49:34 -04003658#SeeAlso drawOval drawRRect drawRoundRect drawPath drawArc drawPoint drawLine
Cary Clark8032b982017-07-28 11:04:54 -04003659
3660##
3661
3662# ------------------------------------------------------------------------------
3663
3664#Method void drawArc(const SkRect& oval, SkScalar startAngle, SkScalar sweepAngle,
3665 bool useCenter, const SkPaint& paint)
3666
3667Draw Arc using Clip, Matrix, and Paint paint.
Cary Clarkbad5ad72017-08-03 17:14:08 -04003668
Cary Clark8032b982017-07-28 11:04:54 -04003669Arc is part of Oval bounded by oval, sweeping from startAngle to startAngle plus
3670sweepAngle. startAngle and sweepAngle are in degrees.
Cary Clarkbad5ad72017-08-03 17:14:08 -04003671
Cary Clark8032b982017-07-28 11:04:54 -04003672startAngle of zero places start point at the right middle edge of oval.
3673A positive sweepAngle places Arc end point clockwise from start point;
3674a negative sweepAngle places Arc end point counterclockwise from start point.
3675sweepAngle may exceed 360 degrees, a full circle.
3676If useCenter is true, draw a wedge that includes lines from oval
3677center to Arc end points. If useCenter is false, draw Arc between end points.
3678
3679If Rect oval is empty or sweepAngle is zero, nothing is drawn.
3680
Cary Clarkbad5ad72017-08-03 17:14:08 -04003681#Param oval Rect bounds of Oval containing Arc to draw ##
3682#Param startAngle angle in degrees where Arc begins ##
3683#Param sweepAngle sweep angle in degrees; positive is clockwise ##
3684#Param useCenter if true, include the center of the oval ##
3685#Param paint Paint stroke or fill, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003686
3687#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003688 void draw(SkCanvas* canvas) {
3689 SkPaint paint;
3690 paint.setAntiAlias(true);
3691 SkRect oval = { 4, 4, 60, 60};
3692 for (auto useCenter : { false, true } ) {
3693 for (auto style : { SkPaint::kFill_Style, SkPaint::kStroke_Style } ) {
3694 paint.setStyle(style);
3695 for (auto degrees : { 45, 90, 180, 360} ) {
3696 canvas->drawArc(oval, 0, degrees , useCenter, paint);
3697 canvas->translate(64, 0);
3698 }
3699 canvas->translate(-256, 64);
3700 }
3701 }
Cary Clark8032b982017-07-28 11:04:54 -04003702 }
3703##
3704
3705#Example
3706#Height 64
Cary Clarkbad5ad72017-08-03 17:14:08 -04003707 void draw(SkCanvas* canvas) {
3708 SkPaint paint;
3709 paint.setAntiAlias(true);
3710 paint.setStyle(SkPaint::kStroke_Style);
3711 paint.setStrokeWidth(4);
3712 SkRect oval = { 4, 4, 60, 60};
3713 float intervals[] = { 5, 5 };
3714 paint.setPathEffect(SkDashPathEffect::Make(intervals, 2, 2.5f));
3715 for (auto degrees : { 270, 360, 540, 720 } ) {
3716 canvas->drawArc(oval, 0, degrees, false, paint);
3717 canvas->translate(64, 0);
3718 }
Cary Clark8032b982017-07-28 11:04:54 -04003719 }
3720##
3721
Cary Clark2ade9972017-11-02 17:49:34 -04003722#SeeAlso SkPath::arcTo drawCircle drawOval drawPath
Cary Clark8032b982017-07-28 11:04:54 -04003723
3724##
3725
3726# ------------------------------------------------------------------------------
3727
3728#Method void drawRoundRect(const SkRect& rect, SkScalar rx, SkScalar ry, const SkPaint& paint)
3729
Cary Clarkbad5ad72017-08-03 17:14:08 -04003730Draw Round_Rect bounded by Rect rect, with corner radii (rx, ry) using Clip,
3731Matrix, and Paint paint.
3732
Cary Clark8032b982017-07-28 11:04:54 -04003733In paint: Paint_Style determines if Round_Rect is stroked or filled;
3734if stroked, Paint_Stroke_Width describes the line thickness.
3735If rx or ry are less than zero, they are treated as if they are zero.
3736If rx plus ry exceeds rect width or rect height, radii are scaled down to fit.
Cary Clarkbad5ad72017-08-03 17:14:08 -04003737If rx and ry are zero, Round_Rect is drawn as Rect and if stroked is affected by
3738Paint_Stroke_Join.
Cary Clark8032b982017-07-28 11:04:54 -04003739
Cary Clarkbad5ad72017-08-03 17:14:08 -04003740#Param rect Rect bounds of Round_Rect to draw ##
Cary Clarkce101242017-09-01 15:51:02 -04003741#Param rx axis length in x of oval describing rounded corners ##
3742#Param ry axis length in y of oval describing rounded corners ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003743#Param paint stroke, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003744
3745#Example
3746#Description
3747 Top row has a zero radius a generates a rectangle.
3748 Second row radii sum to less than sides.
3749 Third row radii sum equals sides.
3750 Fourth row radii sum exceeds sides; radii are scaled to fit.
3751##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003752 void draw(SkCanvas* canvas) {
3753 SkVector radii[] = { {0, 20}, {10, 10}, {10, 20}, {10, 40} };
3754 SkPaint paint;
3755 paint.setStrokeWidth(15);
3756 paint.setStrokeJoin(SkPaint::kRound_Join);
3757 paint.setAntiAlias(true);
3758 for (auto style : { SkPaint::kStroke_Style, SkPaint::kFill_Style } ) {
3759 paint.setStyle(style );
3760 for (size_t i = 0; i < SK_ARRAY_COUNT(radii); ++i) {
3761 canvas->drawRoundRect({10, 10, 60, 40}, radii[i].fX, radii[i].fY, paint);
3762 canvas->translate(0, 60);
3763 }
3764 canvas->translate(80, -240);
3765 }
Cary Clark8032b982017-07-28 11:04:54 -04003766 }
3767##
3768
Cary Clark2ade9972017-11-02 17:49:34 -04003769#SeeAlso DrawRRect drawRect drawDRRect drawPath drawCircle drawOval drawPoint
Cary Clark8032b982017-07-28 11:04:54 -04003770
3771##
3772
3773# ------------------------------------------------------------------------------
3774
3775#Method void drawPath(const SkPath& path, const SkPaint& paint)
3776
3777Draw Path path using Clip, Matrix, and Paint paint.
3778Path contains an array of Path_Contour, each of which may be open or closed.
3779
3780In paint: Paint_Style determines if Round_Rect is stroked or filled:
Cary Clarkbad5ad72017-08-03 17:14:08 -04003781if filled, Path_Fill_Type determines whether Path_Contour describes inside or
3782outside of fill; if stroked, Paint_Stroke_Width describes the line thickness,
3783Paint_Stroke_Cap describes line ends, and Paint_Stroke_Join describes how
3784corners are drawn.
Cary Clark8032b982017-07-28 11:04:54 -04003785
Cary Clarkbad5ad72017-08-03 17:14:08 -04003786#Param path Path to draw ##
3787#Param paint stroke, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003788
3789#Example
3790#Description
3791 Top rows draw stroked path with combinations of joins and caps. The open contour
3792 is affected by caps; the closed contour is affected by joins.
3793 Bottom row draws fill the same for open and closed contour.
3794 First bottom column shows winding fills overlap.
3795 Second bottom column shows even odd fills exclude overlap.
3796 Third bottom column shows inverse winding fills area outside both contours.
3797##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003798void draw(SkCanvas* canvas) {
3799 SkPath path;
3800 path.moveTo(20, 20);
3801 path.quadTo(60, 20, 60, 60);
3802 path.close();
3803 path.moveTo(60, 20);
3804 path.quadTo(60, 60, 20, 60);
3805 SkPaint paint;
3806 paint.setStrokeWidth(10);
3807 paint.setAntiAlias(true);
3808 paint.setStyle(SkPaint::kStroke_Style);
3809 for (auto join: { SkPaint::kBevel_Join, SkPaint::kRound_Join, SkPaint::kMiter_Join } ) {
3810 paint.setStrokeJoin(join);
3811 for (auto cap: { SkPaint::kButt_Cap, SkPaint::kSquare_Cap, SkPaint::kRound_Cap } ) {
3812 paint.setStrokeCap(cap);
3813 canvas->drawPath(path, paint);
3814 canvas->translate(80, 0);
3815 }
3816 canvas->translate(-240, 60);
3817 }
3818 paint.setStyle(SkPaint::kFill_Style);
3819 for (auto fill : { SkPath::kWinding_FillType,
3820 SkPath::kEvenOdd_FillType,
3821 SkPath::kInverseWinding_FillType } ) {
3822 path.setFillType(fill);
3823 canvas->save();
3824 canvas->clipRect({0, 10, 80, 70});
3825 canvas->drawPath(path, paint);
3826 canvas->restore();
3827 canvas->translate(80, 0);
3828 }
Cary Clark8032b982017-07-28 11:04:54 -04003829}
3830##
3831
Cary Clark2ade9972017-11-02 17:49:34 -04003832#SeeAlso SkPath drawLine drawArc drawRect drawPoints
Cary Clark8032b982017-07-28 11:04:54 -04003833
3834##
3835
3836# ------------------------------------------------------------------------------
3837#Topic Draw_Image
3838
Cary Clarkbad5ad72017-08-03 17:14:08 -04003839drawImage, drawImageRect, and drawImageNine can be called with a bare pointer or
3840a smart pointer as a convenience. The pairs of calls are otherwise identical.
Cary Clark8032b982017-07-28 11:04:54 -04003841
Cary Clark73fa9722017-08-29 17:36:51 -04003842#Method void drawImage(const SkImage* image, SkScalar left, SkScalar top, const SkPaint* paint = nullptr)
Cary Clark8032b982017-07-28 11:04:54 -04003843
3844Draw Image image, with its top-left corner at (left, top),
3845using Clip, Matrix, and optional Paint paint.
3846
Cary Clarkbad5ad72017-08-03 17:14:08 -04003847If paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter, Blend_Mode,
3848and Draw_Looper. If image is kAlpha_8_SkColorType, apply Shader.
3849If paint contains Mask_Filter, generate mask from image bounds. If generated
3850mask extends beyond image bounds, replicate image edge colors, just as Shader
3851made from SkImage::makeShader with SkShader::kClamp_TileMode set replicates the
Cary Clarkbc5697d2017-10-04 14:31:33 -04003852image edge color when it samples outside of its bounds.
Cary Clark8032b982017-07-28 11:04:54 -04003853
Cary Clarkbad5ad72017-08-03 17:14:08 -04003854#Param image uncompressed rectangular map of pixels ##
3855#Param left left side of image ##
3856#Param top top side of image ##
3857#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
3858 and so on; or nullptr
3859##
Cary Clark8032b982017-07-28 11:04:54 -04003860
3861#Example
3862#Height 64
3863#Image 4
Cary Clarkbad5ad72017-08-03 17:14:08 -04003864void draw(SkCanvas* canvas) {
3865 // sk_sp<SkImage> image;
3866 SkImage* imagePtr = image.get();
3867 canvas->drawImage(imagePtr, 0, 0);
3868 SkPaint paint;
3869 canvas->drawImage(imagePtr, 80, 0, &paint);
3870 paint.setAlpha(0x80);
3871 canvas->drawImage(imagePtr, 160, 0, &paint);
Cary Clark8032b982017-07-28 11:04:54 -04003872}
3873##
3874
Cary Clark2ade9972017-11-02 17:49:34 -04003875#SeeAlso drawBitmap drawImageLattice drawImageNine drawImageRect SkPaint::setImageFilter
Cary Clark8032b982017-07-28 11:04:54 -04003876
3877##
3878
3879# ------------------------------------------------------------------------------
3880
3881#Method void drawImage(const sk_sp<SkImage>& image, SkScalar left, SkScalar top,
Cary Clark73fa9722017-08-29 17:36:51 -04003882 const SkPaint* paint = nullptr)
Cary Clark8032b982017-07-28 11:04:54 -04003883
3884Draw Image image, with its top-left corner at (left, top),
3885using Clip, Matrix, and optional Paint paint.
3886
Cary Clarkbad5ad72017-08-03 17:14:08 -04003887If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
3888Blend_Mode, and Draw_Looper. If image is kAlpha_8_SkColorType, apply Shader.
3889If paint contains Mask_Filter, generate mask from image bounds. If generated
3890mask extends beyond image bounds, replicate image edge colors, just as Shader
3891made from SkImage::makeShader with SkShader::kClamp_TileMode set replicates the
Cary Clarkbc5697d2017-10-04 14:31:33 -04003892image edge color when it samples outside of its bounds.
Cary Clark8032b982017-07-28 11:04:54 -04003893
Cary Clarkbad5ad72017-08-03 17:14:08 -04003894#Param image uncompressed rectangular map of pixels ##
3895#Param left left side of image ##
3896#Param top pop side of image ##
3897#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
3898 and so on; or nullptr
3899##
Cary Clark8032b982017-07-28 11:04:54 -04003900
3901#Example
3902#Height 64
3903#Image 4
Cary Clarkbad5ad72017-08-03 17:14:08 -04003904void draw(SkCanvas* canvas) {
3905 // sk_sp<SkImage> image;
3906 canvas->drawImage(image, 0, 0);
3907 SkPaint paint;
3908 canvas->drawImage(image, 80, 0, &paint);
3909 paint.setAlpha(0x80);
3910 canvas->drawImage(image, 160, 0, &paint);
Cary Clark8032b982017-07-28 11:04:54 -04003911}
3912##
3913
Cary Clark2ade9972017-11-02 17:49:34 -04003914#SeeAlso drawBitmap drawImageLattice drawImageNine drawImageRect SkPaint::setImageFilter
Cary Clark8032b982017-07-28 11:04:54 -04003915
3916##
3917
3918# ------------------------------------------------------------------------------
3919
3920#Enum SrcRectConstraint
3921
3922#Code
3923 enum SrcRectConstraint {
3924 kStrict_SrcRectConstraint,
3925 kFast_SrcRectConstraint,
3926 };
3927##
3928
Cary Clarkce101242017-09-01 15:51:02 -04003929SrcRectConstraint controls the behavior at the edge of source Rect,
3930provided to drawImageRect, trading off speed for precision.
Cary Clark8032b982017-07-28 11:04:54 -04003931
Cary Clarkce101242017-09-01 15:51:02 -04003932Image_Filter in Paint may sample multiple pixels in the image. Source Rect
Cary Clarkbad5ad72017-08-03 17:14:08 -04003933restricts the bounds of pixels that may be read. Image_Filter may slow down if
Cary Clarkce101242017-09-01 15:51:02 -04003934it cannot read outside the bounds, when sampling near the edge of source Rect.
Cary Clark8032b982017-07-28 11:04:54 -04003935SrcRectConstraint specifies whether an Image_Filter is allowed to read pixels
Cary Clarkce101242017-09-01 15:51:02 -04003936outside source Rect.
Cary Clark8032b982017-07-28 11:04:54 -04003937
3938#Const kStrict_SrcRectConstraint
Cary Clarkce101242017-09-01 15:51:02 -04003939 Requires Image_Filter to respect source Rect,
Cary Clark8032b982017-07-28 11:04:54 -04003940 sampling only inside of its bounds, possibly with a performance penalty.
3941##
3942
3943#Const kFast_SrcRectConstraint
Cary Clarkce101242017-09-01 15:51:02 -04003944 Permits Image_Filter to sample outside of source Rect
Cary Clark8032b982017-07-28 11:04:54 -04003945 by half the width of Image_Filter, permitting it to run faster but with
3946 error at the image edges.
3947##
3948
3949#Example
3950#Height 64
3951#Description
3952 redBorder contains a black and white checkerboard bordered by red.
3953 redBorder is drawn scaled by 16 on the left.
Cary Clarkce101242017-09-01 15:51:02 -04003954 The middle and right bitmaps are filtered checkerboards.
Cary Clark8032b982017-07-28 11:04:54 -04003955 Drawing the checkerboard with kStrict_SrcRectConstraint shows only a blur of black and white.
3956 Drawing the checkerboard with kFast_SrcRectConstraint allows red to bleed in the corners.
3957##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003958void draw(SkCanvas* canvas) {
3959 SkBitmap redBorder;
3960 redBorder.allocPixels(SkImageInfo::MakeN32Premul(4, 4));
3961 SkCanvas checkRed(redBorder);
3962 checkRed.clear(SK_ColorRED);
3963 uint32_t checkers[][2] = { { SK_ColorBLACK, SK_ColorWHITE },
3964 { SK_ColorWHITE, SK_ColorBLACK } };
3965 checkRed.writePixels(
3966 SkImageInfo::MakeN32Premul(2, 2), (void*) checkers, sizeof(checkers[0]), 1, 1);
3967 canvas->scale(16, 16);
3968 canvas->drawBitmap(redBorder, 0, 0, nullptr);
3969 canvas->resetMatrix();
3970 sk_sp<SkImage> image = SkImage::MakeFromBitmap(redBorder);
3971 SkPaint lowPaint;
3972 lowPaint.setFilterQuality(kLow_SkFilterQuality);
3973 for (auto constraint : { SkCanvas::kStrict_SrcRectConstraint,
3974 SkCanvas::kFast_SrcRectConstraint } ) {
3975 canvas->translate(80, 0);
3976 canvas->drawImageRect(image.get(), SkRect::MakeLTRB(1, 1, 3, 3),
3977 SkRect::MakeLTRB(16, 16, 48, 48), &lowPaint, constraint);
3978 }
Cary Clark8032b982017-07-28 11:04:54 -04003979}
3980##
3981
Cary Clark2ade9972017-11-02 17:49:34 -04003982#SeeAlso drawImageRect drawImage SkPaint::setImageFilter
Cary Clark8032b982017-07-28 11:04:54 -04003983
3984##
3985
3986# ------------------------------------------------------------------------------
3987
3988#Method void drawImageRect(const SkImage* image, const SkRect& src, const SkRect& dst,
3989 const SkPaint* paint,
3990 SrcRectConstraint constraint = kStrict_SrcRectConstraint)
3991
3992Draw Rect src of Image image, scaled and translated to fill Rect dst.
3993Additionally transform draw using Clip, Matrix, and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04003994
Cary Clarkbad5ad72017-08-03 17:14:08 -04003995If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
3996Blend_Mode, and Draw_Looper. If image is kAlpha_8_SkColorType, apply Shader.
3997If paint contains Mask_Filter, generate mask from image bounds.
3998
3999If generated mask extends beyond image bounds, replicate image edge colors, just
4000as Shader made from SkImage::makeShader with SkShader::kClamp_TileMode set
Cary Clarkbc5697d2017-10-04 14:31:33 -04004001replicates the image edge color when it samples outside of its bounds.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004002
4003constraint set to kStrict_SrcRectConstraint limits Paint Filter_Quality to
4004sample within src; set to kFast_SrcRectConstraint allows sampling outside to
4005improve performance.
4006
4007#Param image Image containing pixels, dimensions, and format ##
4008#Param src source Rect of image to draw from ##
4009#Param dst destination Rect of image to draw to ##
4010#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4011 and so on; or nullptr
4012##
4013#Param constraint filter strictly within src or draw faster ##
Cary Clark8032b982017-07-28 11:04:54 -04004014
4015#Example
4016#Height 64
4017#Description
4018 The left bitmap draws with Paint default kNone_SkFilterQuality, and stays within
Cary Clarkbc5697d2017-10-04 14:31:33 -04004019 its bounds; there is no bleeding with kFast_SrcRectConstraint.
Cary Clark8032b982017-07-28 11:04:54 -04004020 the middle and right bitmaps draw with kLow_SkFilterQuality; with
4021 kStrict_SrcRectConstraint, the filter remains within the checkerboard, and
4022 with kFast_SrcRectConstraint red bleeds on the edges.
4023##
Cary Clarkbad5ad72017-08-03 17:14:08 -04004024void draw(SkCanvas* canvas) {
4025 uint32_t pixels[][4] = {
4026 { 0xFFFF0000, 0xFFFF0000, 0xFFFF0000, 0xFFFF0000 },
4027 { 0xFFFF0000, 0xFF000000, 0xFFFFFFFF, 0xFFFF0000 },
4028 { 0xFFFF0000, 0xFFFFFFFF, 0xFF000000, 0xFFFF0000 },
4029 { 0xFFFF0000, 0xFFFF0000, 0xFFFF0000, 0xFFFF0000 } };
4030 SkBitmap redBorder;
4031 redBorder.installPixels(SkImageInfo::MakeN32Premul(4, 4),
4032 (void*) pixels, sizeof(pixels[0]));
4033 sk_sp<SkImage> image = SkImage::MakeFromBitmap(redBorder);
4034 SkPaint lowPaint;
4035 for (auto constraint : {
4036 SkCanvas::kFast_SrcRectConstraint,
4037 SkCanvas::kStrict_SrcRectConstraint,
4038 SkCanvas::kFast_SrcRectConstraint } ) {
4039 canvas->drawImageRect(image.get(), SkRect::MakeLTRB(1, 1, 3, 3),
4040 SkRect::MakeLTRB(16, 16, 48, 48), &lowPaint, constraint);
4041 lowPaint.setFilterQuality(kLow_SkFilterQuality);
4042 canvas->translate(80, 0);
4043 }
4044}
Cary Clark8032b982017-07-28 11:04:54 -04004045##
4046
Cary Clark2ade9972017-11-02 17:49:34 -04004047#SeeAlso SrcRectConstraint drawImage drawImageLattice drawImageNine
Cary Clark8032b982017-07-28 11:04:54 -04004048
4049##
4050
4051# ------------------------------------------------------------------------------
4052
4053#Method void drawImageRect(const SkImage* image, const SkIRect& isrc, const SkRect& dst,
4054 const SkPaint* paint, SrcRectConstraint constraint = kStrict_SrcRectConstraint)
4055
4056Draw IRect isrc of Image image, scaled and translated to fill Rect dst.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004057Note that isrc is on integer pixel boundaries; dst may include fractional
4058boundaries. Additionally transform draw using Clip, Matrix, and optional Paint
4059paint.
Cary Clark8032b982017-07-28 11:04:54 -04004060
Cary Clarkbad5ad72017-08-03 17:14:08 -04004061If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4062Blend_Mode, and Draw_Looper. If image is kAlpha_8_SkColorType, apply Shader.
4063If paint contains Mask_Filter, generate mask from image bounds.
4064
4065If generated mask extends beyond image bounds, replicate image edge colors, just
4066as Shader made from SkImage::makeShader with SkShader::kClamp_TileMode set
Cary Clarkbc5697d2017-10-04 14:31:33 -04004067replicates the image edge color when it samples outside of its bounds.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004068
4069constraint set to kStrict_SrcRectConstraint limits Paint Filter_Quality to
Cary Clarkce101242017-09-01 15:51:02 -04004070sample within isrc; set to kFast_SrcRectConstraint allows sampling outside to
Cary Clarkbad5ad72017-08-03 17:14:08 -04004071improve performance.
4072
4073#Param image Image containing pixels, dimensions, and format ##
4074#Param isrc source IRect of image to draw from ##
4075#Param dst destination Rect of image to draw to ##
4076#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4077 and so on; or nullptr
4078##
Cary Clarkce101242017-09-01 15:51:02 -04004079#Param constraint filter strictly within isrc or draw faster ##
Cary Clark8032b982017-07-28 11:04:54 -04004080
4081#Example
4082#Image 4
Cary Clarkbad5ad72017-08-03 17:14:08 -04004083void draw(SkCanvas* canvas) {
4084 // sk_sp<SkImage> image;
4085 for (auto i : { 1, 2, 4, 8 } ) {
4086 canvas->drawImageRect(image.get(), SkIRect::MakeLTRB(0, 0, 100, 100),
4087 SkRect::MakeXYWH(i * 20, i * 20, i * 20, i * 20), nullptr);
4088 }
Cary Clark8032b982017-07-28 11:04:54 -04004089}
4090##
4091
Cary Clark2ade9972017-11-02 17:49:34 -04004092#SeeAlso SrcRectConstraint drawImage drawImageLattice drawImageNine
Cary Clark8032b982017-07-28 11:04:54 -04004093
4094##
4095
4096# ------------------------------------------------------------------------------
4097
4098#Method void drawImageRect(const SkImage* image, const SkRect& dst, const SkPaint* paint,
4099 SrcRectConstraint constraint = kStrict_SrcRectConstraint)
4100
Cary Clarkbad5ad72017-08-03 17:14:08 -04004101Draw Image image, scaled and translated to fill Rect dst, using Clip, Matrix,
4102and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004103
Cary Clarkbad5ad72017-08-03 17:14:08 -04004104If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4105Blend_Mode, and Draw_Looper. If image is kAlpha_8_SkColorType, apply Shader.
4106If paint contains Mask_Filter, generate mask from image bounds.
4107
4108If generated mask extends beyond image bounds, replicate image edge colors, just
4109as Shader made from SkImage::makeShader with SkShader::kClamp_TileMode set
Cary Clarkbc5697d2017-10-04 14:31:33 -04004110replicates the image edge color when it samples outside of its bounds.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004111
4112constraint set to kStrict_SrcRectConstraint limits Paint Filter_Quality to
Cary Clarkce101242017-09-01 15:51:02 -04004113sample within image; set to kFast_SrcRectConstraint allows sampling outside to
Cary Clarkbad5ad72017-08-03 17:14:08 -04004114improve performance.
4115
4116#Param image Image containing pixels, dimensions, and format ##
4117#Param dst destination Rect of image to draw to ##
4118#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4119 and so on; or nullptr
4120##
Cary Clarkce101242017-09-01 15:51:02 -04004121#Param constraint filter strictly within image or draw faster ##
Cary Clark8032b982017-07-28 11:04:54 -04004122
4123#Example
4124#Image 4
Cary Clarkbad5ad72017-08-03 17:14:08 -04004125void draw(SkCanvas* canvas) {
4126 // sk_sp<SkImage> image;
4127 for (auto i : { 20, 40, 80, 160 } ) {
4128 canvas->drawImageRect(image.get(), SkRect::MakeXYWH(i, i, i, i), nullptr);
4129 }
Cary Clark8032b982017-07-28 11:04:54 -04004130}
4131##
4132
Cary Clark2ade9972017-11-02 17:49:34 -04004133#SeeAlso SrcRectConstraint drawImage drawImageLattice drawImageNine
Cary Clark8032b982017-07-28 11:04:54 -04004134
4135##
4136
4137# ------------------------------------------------------------------------------
4138
4139#Method void drawImageRect(const sk_sp<SkImage>& image, const SkRect& src, const SkRect& dst,
4140 const SkPaint* paint,
4141 SrcRectConstraint constraint = kStrict_SrcRectConstraint)
4142
4143Draw Rect src of Image image, scaled and translated to fill Rect dst.
4144Additionally transform draw using Clip, Matrix, and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004145
Cary Clarkbad5ad72017-08-03 17:14:08 -04004146If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4147Blend_Mode, and Draw_Looper. If image is kAlpha_8_SkColorType, apply Shader.
4148If paint contains Mask_Filter, generate mask from image bounds.
4149
4150If generated mask extends beyond image bounds, replicate image edge colors, just
4151as Shader made from SkImage::makeShader with SkShader::kClamp_TileMode set
Cary Clarkbc5697d2017-10-04 14:31:33 -04004152replicates the image edge color when it samples outside of its bounds.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004153
4154constraint set to kStrict_SrcRectConstraint limits Paint Filter_Quality to
4155sample within src; set to kFast_SrcRectConstraint allows sampling outside to
4156improve performance.
4157
4158#Param image Image containing pixels, dimensions, and format ##
4159#Param src source Rect of image to draw from ##
4160#Param dst destination Rect of image to draw to ##
4161#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4162 and so on; or nullptr
4163##
4164#Param constraint filter strictly within src or draw faster ##
Cary Clark8032b982017-07-28 11:04:54 -04004165
4166#Example
4167#Height 64
4168#Description
4169 Canvas scales and translates; transformation from src to dst also scales.
4170 The two matrices are concatenated to create the final transformation.
4171##
Cary Clarkbad5ad72017-08-03 17:14:08 -04004172void draw(SkCanvas* canvas) {
4173 uint32_t pixels[][2] = { { SK_ColorBLACK, SK_ColorWHITE },
4174 { SK_ColorWHITE, SK_ColorBLACK } };
4175 SkBitmap bitmap;
4176 bitmap.installPixels(SkImageInfo::MakeN32Premul(2, 2),
4177 (void*) pixels, sizeof(pixels[0]));
4178 sk_sp<SkImage> image = SkImage::MakeFromBitmap(bitmap);
4179 SkPaint paint;
4180 canvas->scale(4, 4);
4181 for (auto alpha : { 50, 100, 150, 255 } ) {
4182 paint.setAlpha(alpha);
4183 canvas->drawImageRect(image, SkRect::MakeWH(2, 2), SkRect::MakeWH(8, 8), &paint);
4184 canvas->translate(8, 0);
4185 }
4186}
Cary Clark8032b982017-07-28 11:04:54 -04004187##
4188
Cary Clark2ade9972017-11-02 17:49:34 -04004189#SeeAlso SrcRectConstraint drawImage drawImageLattice drawImageNine
Cary Clark8032b982017-07-28 11:04:54 -04004190
4191##
4192
4193# ------------------------------------------------------------------------------
4194
4195#Method void drawImageRect(const sk_sp<SkImage>& image, const SkIRect& isrc, const SkRect& dst,
4196 const SkPaint* paint, SrcRectConstraint constraint = kStrict_SrcRectConstraint)
4197
4198Draw IRect isrc of Image image, scaled and translated to fill Rect dst.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004199isrc is on integer pixel boundaries; dst may include fractional boundaries.
Cary Clark8032b982017-07-28 11:04:54 -04004200Additionally transform draw using Clip, Matrix, and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004201
Cary Clarkbad5ad72017-08-03 17:14:08 -04004202If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4203Blend_Mode, and Draw_Looper. If image is kAlpha_8_SkColorType, apply Shader.
4204If paint contains Mask_Filter, generate mask from image bounds.
4205
4206If generated mask extends beyond image bounds, replicate image edge colors, just
4207as Shader made from SkImage::makeShader with SkShader::kClamp_TileMode set
Cary Clarkbc5697d2017-10-04 14:31:33 -04004208replicates the image edge color when it samples outside of its bounds.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004209
4210constraint set to kStrict_SrcRectConstraint limits Paint Filter_Quality to
Cary Clarkce101242017-09-01 15:51:02 -04004211sample within image; set to kFast_SrcRectConstraint allows sampling outside to
Cary Clarkbad5ad72017-08-03 17:14:08 -04004212improve performance.
4213
4214#Param image Image containing pixels, dimensions, and format ##
4215#Param isrc source IRect of image to draw from ##
4216#Param dst destination Rect of image to draw to ##
4217#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4218 and so on; or nullptr
4219##
Cary Clarkce101242017-09-01 15:51:02 -04004220#Param constraint filter strictly within image or draw faster ##
Cary Clark8032b982017-07-28 11:04:54 -04004221
4222#Example
4223#Height 64
Cary Clarkbad5ad72017-08-03 17:14:08 -04004224void draw(SkCanvas* canvas) {
4225 uint32_t pixels[][2] = { { 0x00000000, 0x55555555},
4226 { 0xAAAAAAAA, 0xFFFFFFFF} };
4227 SkBitmap bitmap;
4228 bitmap.installPixels(SkImageInfo::MakeN32Premul(2, 2),
4229 (void*) pixels, sizeof(pixels[0]));
4230 sk_sp<SkImage> image = SkImage::MakeFromBitmap(bitmap);
4231 SkPaint paint;
4232 canvas->scale(4, 4);
4233 for (auto color : { SK_ColorRED, SK_ColorBLUE, SK_ColorGREEN } ) {
4234 paint.setColorFilter(SkColorFilter::MakeModeFilter(color, SkBlendMode::kPlus));
4235 canvas->drawImageRect(image, SkIRect::MakeWH(2, 2), SkRect::MakeWH(8, 8), &paint);
4236 canvas->translate(8, 0);
4237 }
Cary Clark8032b982017-07-28 11:04:54 -04004238}
4239##
4240
Cary Clark2ade9972017-11-02 17:49:34 -04004241#SeeAlso SrcRectConstraint drawImage drawImageLattice drawImageNine
4242
Cary Clark8032b982017-07-28 11:04:54 -04004243##
4244
4245# ------------------------------------------------------------------------------
4246
4247#Method void drawImageRect(const sk_sp<SkImage>& image, const SkRect& dst, const SkPaint* paint,
4248 SrcRectConstraint constraint = kStrict_SrcRectConstraint)
4249
4250Draw Image image, scaled and translated to fill Rect dst,
4251using Clip, Matrix, and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004252
Cary Clarkbad5ad72017-08-03 17:14:08 -04004253If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4254Blend_Mode, and Draw_Looper. If image is kAlpha_8_SkColorType, apply Shader.
4255If paint contains Mask_Filter, generate mask from image bounds.
4256
4257If generated mask extends beyond image bounds, replicate image edge colors, just
4258as Shader made from SkImage::makeShader with SkShader::kClamp_TileMode set
Cary Clarkbc5697d2017-10-04 14:31:33 -04004259replicates the image edge color when it samples outside of its bounds.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004260
4261constraint set to kStrict_SrcRectConstraint limits Paint Filter_Quality to
Cary Clarkce101242017-09-01 15:51:02 -04004262sample within image; set to kFast_SrcRectConstraint allows sampling outside to
Cary Clarkbad5ad72017-08-03 17:14:08 -04004263improve performance.
4264
4265#Param image Image containing pixels, dimensions, and format ##
4266#Param dst destination Rect of image to draw to ##
4267#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4268 and so on; or nullptr
4269##
Cary Clarkce101242017-09-01 15:51:02 -04004270#Param constraint filter strictly within image or draw faster ##
Cary Clark8032b982017-07-28 11:04:54 -04004271
4272#Example
4273#Height 64
Cary Clarkbad5ad72017-08-03 17:14:08 -04004274void draw(SkCanvas* canvas) {
4275 uint32_t pixels[][2] = { { 0x00000000, 0x55550000},
4276 { 0xAAAA0000, 0xFFFF0000} };
4277 SkBitmap bitmap;
4278 bitmap.installPixels(SkImageInfo::MakeN32Premul(2, 2),
4279 (void*) pixels, sizeof(pixels[0]));
4280 sk_sp<SkImage> image = SkImage::MakeFromBitmap(bitmap);
4281 SkPaint paint;
4282 canvas->scale(4, 4);
4283 for (auto color : { SK_ColorRED, SK_ColorBLUE, SK_ColorGREEN } ) {
4284 paint.setColorFilter(SkColorFilter::MakeModeFilter(color, SkBlendMode::kPlus));
4285 canvas->drawImageRect(image, SkRect::MakeWH(8, 8), &paint);
4286 canvas->translate(8, 0);
4287 }
Cary Clark8032b982017-07-28 11:04:54 -04004288}
4289##
4290
Cary Clark2ade9972017-11-02 17:49:34 -04004291#SeeAlso SrcRectConstraint drawImage drawImageLattice drawImageNine
Cary Clark8032b982017-07-28 11:04:54 -04004292
4293##
4294
4295# ------------------------------------------------------------------------------
4296
4297#Method void drawImageNine(const SkImage* image, const SkIRect& center, const SkRect& dst,
4298 const SkPaint* paint = nullptr)
4299
Cary Clarkd0530ba2017-09-14 11:25:39 -04004300Draw Image image stretched proportionally to fit into Rect dst.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004301IRect center divides the image into nine sections: four sides, four corners, and
Cary Clarkce101242017-09-01 15:51:02 -04004302the center. Corners are unmodified or scaled down proportionately if their sides
Cary Clarkbad5ad72017-08-03 17:14:08 -04004303are larger than dst; center and four sides are scaled to fit remaining space, if any.
Cary Clark8032b982017-07-28 11:04:54 -04004304
Cary Clarkbad5ad72017-08-03 17:14:08 -04004305Additionally transform draw using Clip, Matrix, and optional Paint paint.
4306
4307If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4308Blend_Mode, and Draw_Looper. If image is kAlpha_8_SkColorType, apply Shader.
4309If paint contains Mask_Filter, generate mask from image bounds.
4310
4311If generated mask extends beyond image bounds, replicate image edge colors, just
4312as Shader made from SkImage::makeShader with SkShader::kClamp_TileMode set
Cary Clarkbc5697d2017-10-04 14:31:33 -04004313replicates the image edge color when it samples outside of its bounds.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004314
4315#Param image Image containing pixels, dimensions, and format ##
4316#Param center IRect edge of image corners and sides ##
4317#Param dst destination Rect of image to draw to ##
4318#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4319 and so on; or nullptr
4320##
Cary Clark8032b982017-07-28 11:04:54 -04004321
4322#Example
4323#Height 128
4324#Description
4325 The leftmost image is smaller than center; only corners are drawn, all scaled to fit.
Cary Clarkce101242017-09-01 15:51:02 -04004326 The second image equals the size of center; only corners are drawn without scaling.
4327 The remaining images are larger than center. All corners draw without scaling.
4328 The sides and center are scaled if needed to take up the remaining space.
Cary Clark8032b982017-07-28 11:04:54 -04004329##
Cary Clarkbad5ad72017-08-03 17:14:08 -04004330void draw(SkCanvas* canvas) {
4331 SkIRect center = { 20, 10, 50, 40 };
4332 SkBitmap bitmap;
4333 bitmap.allocPixels(SkImageInfo::MakeN32Premul(60, 60));
4334 SkCanvas bitCanvas(bitmap);
4335 SkPaint paint;
4336 SkColor gray = 0xFF000000;
4337 int left = 0;
4338 for (auto right: { center.fLeft, center.fRight, bitmap.width() } ) {
4339 int top = 0;
4340 for (auto bottom: { center.fTop, center.fBottom, bitmap.height() } ) {
4341 paint.setColor(gray);
4342 bitCanvas.drawIRect(SkIRect::MakeLTRB(left, top, right, bottom), paint);
4343 gray += 0x001f1f1f;
4344 top = bottom;
4345 }
4346 left = right;
4347 }
4348 sk_sp<SkImage> image = SkImage::MakeFromBitmap(bitmap);
4349 SkImage* imagePtr = image.get();
4350 for (auto dest: { 20, 30, 40, 60, 90 } ) {
4351 canvas->drawImageNine(imagePtr, center, SkRect::MakeWH(dest, dest), nullptr);
4352 canvas->translate(dest + 4, 0);
4353 }
Cary Clark8032b982017-07-28 11:04:54 -04004354}
4355##
4356
Cary Clark2ade9972017-11-02 17:49:34 -04004357#SeeAlso drawImage drawBitmapNine drawImageLattice drawImageRect
Cary Clark8032b982017-07-28 11:04:54 -04004358
4359##
4360
4361# ------------------------------------------------------------------------------
4362
4363#Method void drawImageNine(const sk_sp<SkImage>& image, const SkIRect& center, const SkRect& dst,
4364 const SkPaint* paint = nullptr)
4365
Cary Clarkd0530ba2017-09-14 11:25:39 -04004366Draw Image image stretched proportionally to fit into Rect dst.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004367IRect center divides the image into nine sections: four sides, four corners, and
Cary Clarkce101242017-09-01 15:51:02 -04004368the center. Corners are not scaled, or scaled down proportionately if their sides
Cary Clarkbad5ad72017-08-03 17:14:08 -04004369are larger than dst; center and four sides are scaled to fit remaining space, if any.
Cary Clark8032b982017-07-28 11:04:54 -04004370
Cary Clarkbad5ad72017-08-03 17:14:08 -04004371Additionally transform draw using Clip, Matrix, and optional Paint paint.
4372
4373If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4374Blend_Mode, and Draw_Looper. If image is kAlpha_8_SkColorType, apply Shader.
4375If paint contains Mask_Filter, generate mask from image bounds.
4376
4377If generated mask extends beyond image bounds, replicate image edge colors, just
4378as Shader made from SkImage::makeShader with SkShader::kClamp_TileMode set
Cary Clarkbc5697d2017-10-04 14:31:33 -04004379replicates the image edge color when it samples outside of its bounds.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004380
4381#Param image Image containing pixels, dimensions, and format ##
4382#Param center IRect edge of image corners and sides ##
4383#Param dst destination Rect of image to draw to ##
4384#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4385 and so on; or nullptr
4386##
Cary Clark8032b982017-07-28 11:04:54 -04004387
4388#Example
4389#Height 128
4390#Description
4391 The two leftmost images has four corners and sides to the left and right of center.
4392 The leftmost image scales the width of corners proportionately to fit.
Cary Clarkce101242017-09-01 15:51:02 -04004393 The third and fourth image corners are not scaled; the sides and center are scaled to
Cary Clark8032b982017-07-28 11:04:54 -04004394 fill the remaining space.
4395 The rightmost image has four corners scaled vertically to fit, and uses sides above
4396 and below center to fill the remaining space.
4397##
Cary Clarkbad5ad72017-08-03 17:14:08 -04004398void draw(SkCanvas* canvas) {
4399 SkIRect center = { 20, 10, 50, 40 };
4400 SkBitmap bitmap;
4401 bitmap.allocPixels(SkImageInfo::MakeN32Premul(60, 60));
4402 SkCanvas bitCanvas(bitmap);
4403 SkPaint paint;
4404 SkColor gray = 0xFF000000;
4405 int left = 0;
4406 for (auto right: { center.fLeft, center.fRight, bitmap.width() } ) {
4407 int top = 0;
4408 for (auto bottom: { center.fTop, center.fBottom, bitmap.height() } ) {
4409 paint.setColor(gray);
4410 bitCanvas.drawIRect(SkIRect::MakeLTRB(left, top, right, bottom), paint);
4411 gray += 0x001f1f1f;
4412 top = bottom;
4413 }
4414 left = right;
4415 }
4416 sk_sp<SkImage> image = SkImage::MakeFromBitmap(bitmap);
4417 for (auto dest: { 20, 30, 40, 60, 90 } ) {
4418 canvas->drawImageNine(image, center, SkRect::MakeWH(dest, 110 - dest), nullptr);
4419 canvas->translate(dest + 4, 0);
4420 }
Cary Clark8032b982017-07-28 11:04:54 -04004421}
4422##
4423
Cary Clark2ade9972017-11-02 17:49:34 -04004424#SeeAlso drawImage drawBitmapNine drawImageLattice drawImageRect
Cary Clark8032b982017-07-28 11:04:54 -04004425
4426##
4427
4428# ------------------------------------------------------------------------------
4429
4430#Method void drawBitmap(const SkBitmap& bitmap, SkScalar left, SkScalar top,
Cary Clark73fa9722017-08-29 17:36:51 -04004431 const SkPaint* paint = nullptr)
Cary Clark8032b982017-07-28 11:04:54 -04004432
4433Draw Bitmap bitmap, with its top-left corner at (left, top),
4434using Clip, Matrix, and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004435
Cary Clarka560c472017-11-27 10:44:06 -05004436If Paint paint is not nullptr, apply Color_Filter, Color_Alpha, Image_Filter,
Cary Clarkbad5ad72017-08-03 17:14:08 -04004437Blend_Mode, and Draw_Looper. If bitmap is kAlpha_8_SkColorType, apply Shader.
4438If paint contains Mask_Filter, generate mask from bitmap bounds.
4439
4440If generated mask extends beyond bitmap bounds, replicate bitmap edge colors,
4441just as Shader made from SkShader::MakeBitmapShader with
Cary Clarkbc5697d2017-10-04 14:31:33 -04004442SkShader::kClamp_TileMode set replicates the bitmap edge color when it samples
Cary Clarkbad5ad72017-08-03 17:14:08 -04004443outside of its bounds.
4444
4445#Param bitmap Bitmap containing pixels, dimensions, and format ##
4446#Param left left side of bitmap ##
4447#Param top top side of bitmap ##
4448#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4449 and so on; or nullptr
4450##
Cary Clark8032b982017-07-28 11:04:54 -04004451
4452#Example
4453#Height 64
Cary Clarkbad5ad72017-08-03 17:14:08 -04004454void draw(SkCanvas* canvas) {
4455 uint8_t pixels[][8] = { { 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00},
4456 { 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00},
4457 { 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00},
4458 { 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF},
4459 { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
4460 { 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00},
4461 { 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0x00},
4462 { 0xFF, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0xFF} };
4463 SkBitmap bitmap;
4464 bitmap.installPixels(SkImageInfo::MakeA8(8, 8),
4465 (void*) pixels, sizeof(pixels[0]));
4466 SkPaint paint;
4467 canvas->scale(4, 4);
4468 for (auto color : { SK_ColorRED, SK_ColorBLUE, 0xFF007F00} ) {
4469 paint.setColor(color);
4470 canvas->drawBitmap(bitmap, 0, 0, &paint);
4471 canvas->translate(12, 0);
4472 }
Cary Clark8032b982017-07-28 11:04:54 -04004473}
4474##
4475
Cary Clark2ade9972017-11-02 17:49:34 -04004476#SeeAlso drawImage drawBitmapLattice drawBitmapNine drawBitmapRect SkBitmap::readPixels SkBitmap::writePixels
Cary Clark8032b982017-07-28 11:04:54 -04004477
4478##
4479
4480# ------------------------------------------------------------------------------
4481
4482#Method void drawBitmapRect(const SkBitmap& bitmap, const SkRect& src, const SkRect& dst,
4483 const SkPaint* paint, SrcRectConstraint constraint = kStrict_SrcRectConstraint)
4484
4485Draw Rect src of Bitmap bitmap, scaled and translated to fill Rect dst.
4486Additionally transform draw using Clip, Matrix, and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004487
Cary Clarkbad5ad72017-08-03 17:14:08 -04004488If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4489Blend_Mode, and Draw_Looper. If bitmap is kAlpha_8_SkColorType, apply Shader.
4490If paint contains Mask_Filter, generate mask from bitmap bounds.
4491
4492If generated mask extends beyond bitmap bounds, replicate bitmap edge colors,
4493just as Shader made from SkShader::MakeBitmapShader with
Cary Clarkbc5697d2017-10-04 14:31:33 -04004494SkShader::kClamp_TileMode set replicates the bitmap edge color when it samples
Cary Clarkbad5ad72017-08-03 17:14:08 -04004495outside of its bounds.
4496
4497constraint set to kStrict_SrcRectConstraint limits Paint Filter_Quality to
4498sample within src; set to kFast_SrcRectConstraint allows sampling outside to
4499improve performance.
4500
4501#Param bitmap Bitmap containing pixels, dimensions, and format ##
4502#Param src source Rect of image to draw from ##
4503#Param dst destination Rect of image to draw to ##
4504#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4505 and so on; or nullptr
4506##
4507#Param constraint filter strictly within src or draw faster ##
Cary Clark8032b982017-07-28 11:04:54 -04004508
4509#Example
4510#Height 64
Cary Clarkbad5ad72017-08-03 17:14:08 -04004511void draw(SkCanvas* canvas) {
4512 uint8_t pixels[][8] = { { 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00},
4513 { 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00},
4514 { 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00},
4515 { 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF},
4516 { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
4517 { 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00},
4518 { 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00},
4519 { 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00} };
4520 SkBitmap bitmap;
4521 bitmap.installPixels(SkImageInfo::MakeA8(8, 8),
4522 (void*) pixels, sizeof(pixels[0]));
4523 SkPaint paint;
4524 paint.setMaskFilter(SkBlurMaskFilter::Make(kSolid_SkBlurStyle, 6));
4525 for (auto color : { SK_ColorRED, SK_ColorBLUE, 0xFF007F00} ) {
4526 paint.setColor(color);
4527 canvas->drawBitmapRect(bitmap, SkRect::MakeWH(8, 8), SkRect::MakeWH(32, 32), &paint);
4528 canvas->translate(48, 0);
4529 }
Cary Clark8032b982017-07-28 11:04:54 -04004530}
4531##
4532
Cary Clark2ade9972017-11-02 17:49:34 -04004533#SeeAlso drawImageRect drawBitmap drawBitmapLattice drawBitmapNine
Cary Clark8032b982017-07-28 11:04:54 -04004534
4535##
4536
4537# ------------------------------------------------------------------------------
4538
4539#Method void drawBitmapRect(const SkBitmap& bitmap, const SkIRect& isrc, const SkRect& dst,
4540 const SkPaint* paint, SrcRectConstraint constraint = kStrict_SrcRectConstraint)
4541
4542Draw IRect isrc of Bitmap bitmap, scaled and translated to fill Rect dst.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004543isrc is on integer pixel boundaries; dst may include fractional boundaries.
Cary Clark8032b982017-07-28 11:04:54 -04004544Additionally transform draw using Clip, Matrix, and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004545
Cary Clarkbad5ad72017-08-03 17:14:08 -04004546If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4547Blend_Mode, and Draw_Looper. If bitmap is kAlpha_8_SkColorType, apply Shader.
4548If paint contains Mask_Filter, generate mask from bitmap bounds.
4549
4550If generated mask extends beyond bitmap bounds, replicate bitmap edge colors,
4551just as Shader made from SkShader::MakeBitmapShader with
Cary Clarkbc5697d2017-10-04 14:31:33 -04004552SkShader::kClamp_TileMode set replicates the bitmap edge color when it samples
Cary Clarkbad5ad72017-08-03 17:14:08 -04004553outside of its bounds.
4554
4555constraint set to kStrict_SrcRectConstraint limits Paint Filter_Quality to
Cary Clarkce101242017-09-01 15:51:02 -04004556sample within isrc; set to kFast_SrcRectConstraint allows sampling outside to
Cary Clarkbad5ad72017-08-03 17:14:08 -04004557improve performance.
4558
4559#Param bitmap Bitmap containing pixels, dimensions, and format ##
4560#Param isrc source IRect of image to draw from ##
4561#Param dst destination Rect of image to draw to ##
4562#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4563 and so on; or nullptr
4564##
Cary Clarkce101242017-09-01 15:51:02 -04004565#Param constraint sample strictly within isrc, or draw faster ##
Cary Clark8032b982017-07-28 11:04:54 -04004566
4567#Example
4568#Height 64
Cary Clarkbad5ad72017-08-03 17:14:08 -04004569void draw(SkCanvas* canvas) {
4570 uint8_t pixels[][8] = { { 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00},
4571 { 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00},
4572 { 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0xFF},
4573 { 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0xFF},
4574 { 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF},
4575 { 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF},
4576 { 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00},
4577 { 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00} };
4578 SkBitmap bitmap;
4579 bitmap.installPixels(SkImageInfo::MakeA8(8, 8),
4580 (void*) pixels, sizeof(pixels[0]));
4581 SkPaint paint;
4582 paint.setFilterQuality(kHigh_SkFilterQuality);
4583 for (auto color : { SK_ColorRED, SK_ColorBLUE, 0xFF007F00, 0xFF7f007f} ) {
4584 paint.setColor(color);
4585 canvas->drawBitmapRect(bitmap, SkIRect::MakeWH(8, 8), SkRect::MakeWH(32, 32), &paint);
4586 canvas->translate(48.25f, 0);
4587 }
Cary Clark8032b982017-07-28 11:04:54 -04004588}
4589##
4590
Cary Clark2ade9972017-11-02 17:49:34 -04004591#SeeAlso drawImageRect drawBitmap drawBitmapLattice drawBitmapNine
Cary Clark8032b982017-07-28 11:04:54 -04004592
4593##
4594
4595# ------------------------------------------------------------------------------
4596
4597#Method void drawBitmapRect(const SkBitmap& bitmap, const SkRect& dst, const SkPaint* paint,
4598 SrcRectConstraint constraint = kStrict_SrcRectConstraint)
4599
4600Draw Bitmap bitmap, scaled and translated to fill Rect dst.
Cary Clarkce101242017-09-01 15:51:02 -04004601bitmap bounds is on integer pixel boundaries; dst may include fractional boundaries.
Cary Clark8032b982017-07-28 11:04:54 -04004602Additionally transform draw using Clip, Matrix, and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004603
Cary Clarkbad5ad72017-08-03 17:14:08 -04004604If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4605Blend_Mode, and Draw_Looper. If bitmap is kAlpha_8_SkColorType, apply Shader.
4606If paint contains Mask_Filter, generate mask from bitmap bounds.
4607
4608If generated mask extends beyond bitmap bounds, replicate bitmap edge colors,
4609just as Shader made from SkShader::MakeBitmapShader with
Cary Clarkbc5697d2017-10-04 14:31:33 -04004610SkShader::kClamp_TileMode set replicates the bitmap edge color when it samples
Cary Clarkbad5ad72017-08-03 17:14:08 -04004611outside of its bounds.
4612
4613constraint set to kStrict_SrcRectConstraint limits Paint Filter_Quality to
Cary Clarkce101242017-09-01 15:51:02 -04004614sample within bitmap; set to kFast_SrcRectConstraint allows sampling outside to
Cary Clarkbad5ad72017-08-03 17:14:08 -04004615improve performance.
4616
4617#Param bitmap Bitmap containing pixels, dimensions, and format ##
4618#Param dst destination Rect of image to draw to ##
4619#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4620 and so on; or nullptr
4621##
Cary Clarkce101242017-09-01 15:51:02 -04004622#Param constraint filter strictly within bitmap or draw faster ##
Cary Clark8032b982017-07-28 11:04:54 -04004623
4624#Example
4625#Height 64
Cary Clarkbad5ad72017-08-03 17:14:08 -04004626void draw(SkCanvas* canvas) {
4627 uint32_t pixels[][2] = { { 0x00000000, 0x55550000},
4628 { 0xAAAA0000, 0xFFFF0000} };
4629 SkBitmap bitmap;
4630 bitmap.installPixels(SkImageInfo::MakeN32Premul(2, 2),
4631 (void*) pixels, sizeof(pixels[0]));
4632 SkPaint paint;
4633 canvas->scale(4, 4);
4634 for (auto color : { SK_ColorRED, SK_ColorBLUE, SK_ColorGREEN } ) {
4635 paint.setColorFilter(SkColorFilter::MakeModeFilter(color, SkBlendMode::kPlus));
4636 canvas->drawBitmapRect(bitmap, SkRect::MakeWH(8, 8), &paint);
4637 canvas->translate(8, 0);
4638 }
Cary Clark8032b982017-07-28 11:04:54 -04004639}
4640##
4641
Cary Clark2ade9972017-11-02 17:49:34 -04004642#SeeAlso drawImageRect drawBitmap drawBitmapLattice drawBitmapNine
Cary Clark8032b982017-07-28 11:04:54 -04004643
4644##
4645
4646# ------------------------------------------------------------------------------
4647
4648#Method void drawBitmapNine(const SkBitmap& bitmap, const SkIRect& center, const SkRect& dst,
Cary Clark73fa9722017-08-29 17:36:51 -04004649 const SkPaint* paint = nullptr)
Cary Clark8032b982017-07-28 11:04:54 -04004650
Cary Clarkd0530ba2017-09-14 11:25:39 -04004651Draw Bitmap bitmap stretched proportionally to fit into Rect dst.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004652IRect center divides the bitmap into nine sections: four sides, four corners,
Cary Clarkce101242017-09-01 15:51:02 -04004653and the center. Corners are not scaled, or scaled down proportionately if their
Cary Clarkbad5ad72017-08-03 17:14:08 -04004654sides are larger than dst; center and four sides are scaled to fit remaining
4655space, if any.
Cary Clark8032b982017-07-28 11:04:54 -04004656
Cary Clarkbad5ad72017-08-03 17:14:08 -04004657Additionally transform draw using Clip, Matrix, and optional Paint paint.
4658
4659If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4660Blend_Mode, and Draw_Looper. If bitmap is kAlpha_8_SkColorType, apply Shader.
4661If paint contains Mask_Filter, generate mask from bitmap bounds.
4662
4663If generated mask extends beyond bitmap bounds, replicate bitmap edge colors,
4664just as Shader made from SkShader::MakeBitmapShader with
Cary Clarkbc5697d2017-10-04 14:31:33 -04004665SkShader::kClamp_TileMode set replicates the bitmap edge color when it samples
Cary Clarkbad5ad72017-08-03 17:14:08 -04004666outside of its bounds.
4667
4668#Param bitmap Bitmap containing pixels, dimensions, and format ##
4669#Param center IRect edge of image corners and sides ##
4670#Param dst destination Rect of image to draw to ##
4671#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4672 and so on; or nullptr
4673##
Cary Clark8032b982017-07-28 11:04:54 -04004674
4675#Example
4676#Height 128
4677#Description
4678 The two leftmost bitmap draws has four corners and sides to the left and right of center.
4679 The leftmost bitmap draw scales the width of corners proportionately to fit.
Cary Clarkce101242017-09-01 15:51:02 -04004680 The third and fourth draw corners are not scaled; the sides and center are scaled to
Cary Clark8032b982017-07-28 11:04:54 -04004681 fill the remaining space.
4682 The rightmost bitmap draw has four corners scaled vertically to fit, and uses sides above
4683 and below center to fill the remaining space.
4684##
Cary Clarkbad5ad72017-08-03 17:14:08 -04004685void draw(SkCanvas* canvas) {
4686 SkIRect center = { 20, 10, 50, 40 };
4687 SkBitmap bitmap;
4688 bitmap.allocPixels(SkImageInfo::MakeN32Premul(60, 60));
4689 SkCanvas bitCanvas(bitmap);
4690 SkPaint paint;
4691 SkColor gray = 0xFF000000;
4692 int left = 0;
4693 for (auto right: { center.fLeft, center.fRight, bitmap.width() } ) {
4694 int top = 0;
4695 for (auto bottom: { center.fTop, center.fBottom, bitmap.height() } ) {
4696 paint.setColor(gray);
4697 bitCanvas.drawIRect(SkIRect::MakeLTRB(left, top, right, bottom), paint);
4698 gray += 0x001f1f1f;
4699 top = bottom;
4700 }
4701 left = right;
4702 }
4703 for (auto dest: { 20, 30, 40, 60, 90 } ) {
4704 canvas->drawBitmapNine(bitmap, center, SkRect::MakeWH(dest, 110 - dest), nullptr);
4705 canvas->translate(dest + 4, 0);
4706 }
Cary Clark8032b982017-07-28 11:04:54 -04004707}
4708##
4709
Cary Clark2ade9972017-11-02 17:49:34 -04004710#SeeAlso drawImageNine drawBitmap drawBitmapLattice drawBitmapRect
Cary Clark8032b982017-07-28 11:04:54 -04004711
4712##
4713
4714# ------------------------------------------------------------------------------
4715#Struct Lattice
4716
Cary Clark8032b982017-07-28 11:04:54 -04004717#Code
4718 struct Lattice {
Cary Clark2f466242017-12-11 16:03:17 -05004719 enum RectType ...
Cary Clark8032b982017-07-28 11:04:54 -04004720
Cary Clark2f466242017-12-11 16:03:17 -05004721 const int* fXDivs;
4722 const int* fYDivs;
4723 const RectType* fRectTypes;
4724 int fXCount;
4725 int fYCount;
4726 const SkIRect* fBounds;
4727 const SkColor* fColors;
Cary Clark8032b982017-07-28 11:04:54 -04004728 };
4729##
4730
Cary Clark154beea2017-10-26 07:58:48 -04004731 Lattice divides Bitmap or Image into a rectangular grid.
4732 Grid entries on even columns and even rows are fixed; these entries are
4733 always drawn at their original size if the destination is large enough.
4734 If the destination side is too small to hold the fixed entries, all fixed
4735 entries are proportionately scaled down to fit.
4736 The grid entries not on even columns and rows are scaled to fit the
4737 remaining space, if any.
4738
Cary Clark2f466242017-12-11 16:03:17 -05004739 #Enum RectType
Cary Clark8032b982017-07-28 11:04:54 -04004740 #Code
Cary Clark2f466242017-12-11 16:03:17 -05004741 enum RectType : uint8_t {
4742 kDefault = 0,
4743 kTransparent,
4744 kFixedColor,
Cary Clark8032b982017-07-28 11:04:54 -04004745 };
4746 ##
4747
Cary Clark2f466242017-12-11 16:03:17 -05004748 Optional setting per rectangular grid entry to make it transparent,
4749 or to fill the grid entry with a color.
Cary Clark8032b982017-07-28 11:04:54 -04004750
Cary Clark2f466242017-12-11 16:03:17 -05004751 #Const kDefault 0
4752 Draws Bitmap into lattice rectangle.
4753 ##
4754
4755 #Const kTransparent 1
4756 Skips lattice rectangle by making it transparent.
4757 ##
4758
4759 #Const kFixedColor 2
4760 Draws one of fColors into lattice rectangle.
Cary Clark8032b982017-07-28 11:04:54 -04004761 ##
4762 ##
4763
4764 #Member const int* fXDivs
4765 Array of x-coordinates that divide the bitmap vertically.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004766 Array entries must be unique, increasing, greater than or equal to
4767 fBounds left edge, and less than fBounds right edge.
4768 Set the first element to fBounds left to collapse the left column of
4769 fixed grid entries.
Cary Clark8032b982017-07-28 11:04:54 -04004770 ##
4771
4772 #Member const int* fYDivs
4773 Array of y-coordinates that divide the bitmap horizontally.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004774 Array entries must be unique, increasing, greater than or equal to
4775 fBounds top edge, and less than fBounds bottom edge.
4776 Set the first element to fBounds top to collapse the top row of fixed
4777 grid entries.
Cary Clark8032b982017-07-28 11:04:54 -04004778 ##
4779
Cary Clark2f466242017-12-11 16:03:17 -05004780 #Member const RectType* fRectTypes
4781 Optional array of fill types, one per rectangular grid entry:
Cary Clarkbad5ad72017-08-03 17:14:08 -04004782 array length must be
4783 #Formula
4784 (fXCount + 1) * (fYCount + 1)
4785 ##
4786 .
Cary Clark6fc50412017-09-21 12:31:06 -04004787
Cary Clark2f466242017-12-11 16:03:17 -05004788 Each RectType is one of: kDefault, kTransparent, kFixedColor.
4789
Cary Clark8032b982017-07-28 11:04:54 -04004790 Array entries correspond to the rectangular grid entries, ascending
4791 left to right and then top to bottom.
4792 ##
4793
4794 #Member int fXCount
Cary Clarkbad5ad72017-08-03 17:14:08 -04004795 Number of entries in fXDivs array; one less than the number of
4796 horizontal divisions.
Cary Clark8032b982017-07-28 11:04:54 -04004797 ##
4798
4799 #Member int fYCount
Cary Clarkbad5ad72017-08-03 17:14:08 -04004800 Number of entries in fYDivs array; one less than the number of vertical
4801 divisions.
Cary Clark8032b982017-07-28 11:04:54 -04004802 ##
4803
4804 #Member const SkIRect* fBounds
4805 Optional subset IRect source to draw from.
4806 If nullptr, source bounds is dimensions of Bitmap or Image.
4807 ##
4808
Cary Clark2f466242017-12-11 16:03:17 -05004809 #Member const SkColor* fColors
4810 Optional array of colors, one per rectangular grid entry.
4811 Array length must be
4812 #Formula
4813 (fXCount + 1) * (fYCount + 1)
4814 ##
4815 .
4816
4817 Array entries correspond to the rectangular grid entries, ascending
4818 left to right, then top to bottom.
4819 ##
4820
Cary Clark8032b982017-07-28 11:04:54 -04004821#Struct Lattice ##
4822
4823#Method void drawBitmapLattice(const SkBitmap& bitmap, const Lattice& lattice, const SkRect& dst,
4824 const SkPaint* paint = nullptr)
4825
Cary Clarkd0530ba2017-09-14 11:25:39 -04004826Draw Bitmap bitmap stretched proportionally to fit into Rect dst.
Cary Clark8032b982017-07-28 11:04:54 -04004827
4828Lattice lattice divides bitmap into a rectangular grid.
4829Each intersection of an even-numbered row and column is fixed; like the corners
Cary Clarkbad5ad72017-08-03 17:14:08 -04004830of drawBitmapNine, fixed lattice elements never scale larger than their initial
Cary Clarkbc5697d2017-10-04 14:31:33 -04004831size and shrink proportionately when all fixed elements exceed the bitmap
Cary Clarkbad5ad72017-08-03 17:14:08 -04004832dimension. All other grid elements scale to fill the available space, if any.
Cary Clark8032b982017-07-28 11:04:54 -04004833
4834Additionally transform draw using Clip, Matrix, and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004835
Cary Clarkbad5ad72017-08-03 17:14:08 -04004836If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4837Blend_Mode, and Draw_Looper. If bitmap is kAlpha_8_SkColorType, apply Shader.
4838If paint contains Mask_Filter, generate mask from bitmap bounds.
4839
4840If generated mask extends beyond bitmap bounds, replicate bitmap edge colors,
4841just as Shader made from SkShader::MakeBitmapShader with
Cary Clarkbc5697d2017-10-04 14:31:33 -04004842SkShader::kClamp_TileMode set replicates the bitmap edge color when it samples
Cary Clarkbad5ad72017-08-03 17:14:08 -04004843outside of its bounds.
4844
4845#Param bitmap Bitmap containing pixels, dimensions, and format ##
4846#Param lattice division of bitmap into fixed and variable rectangles ##
4847#Param dst destination Rect of image to draw to ##
4848#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4849 and so on; or nullptr
4850##
Cary Clark8032b982017-07-28 11:04:54 -04004851
4852#Example
4853#Height 128
4854#Description
4855 The two leftmost bitmap draws has four corners and sides to the left and right of center.
4856 The leftmost bitmap draw scales the width of corners proportionately to fit.
Cary Clarkce101242017-09-01 15:51:02 -04004857 The third and fourth draw corners are not scaled; the sides are scaled to
Cary Clark8032b982017-07-28 11:04:54 -04004858 fill the remaining space; the center is transparent.
4859 The rightmost bitmap draw has four corners scaled vertically to fit, and uses sides above
4860 and below center to fill the remaining space.
4861##
Cary Clarkbad5ad72017-08-03 17:14:08 -04004862void draw(SkCanvas* canvas) {
4863 SkIRect center = { 20, 10, 50, 40 };
4864 SkBitmap bitmap;
4865 bitmap.allocPixels(SkImageInfo::MakeN32Premul(60, 60));
4866 SkCanvas bitCanvas(bitmap);
4867 SkPaint paint;
4868 SkColor gray = 0xFF000000;
4869 int left = 0;
4870 for (auto right: { center.fLeft, center.fRight, bitmap.width() } ) {
4871 int top = 0;
4872 for (auto bottom: { center.fTop, center.fBottom, bitmap.height() } ) {
4873 paint.setColor(gray);
4874 bitCanvas.drawIRect(SkIRect::MakeLTRB(left, top, right, bottom), paint);
4875 gray += 0x001f1f1f;
4876 top = bottom;
4877 }
4878 left = right;
4879 }
4880 const int xDivs[] = { center.fLeft, center.fRight };
4881 const int yDivs[] = { center.fTop, center.fBottom };
Cary Clarkca3ebcd2017-12-12 11:22:38 -05004882 SkCanvas::Lattice::RectType fillTypes[3][3];
4883 memset(fillTypes, 0, sizeof(fillTypes));
4884 fillTypes[1][1] = SkCanvas::Lattice::kTransparent;
4885 SkColor dummy[9]; // temporary pending bug fix
4886 SkCanvas::Lattice lattice = { xDivs, yDivs, fillTypes[0], SK_ARRAY_COUNT(xDivs),
4887 SK_ARRAY_COUNT(yDivs), nullptr, dummy };
Cary Clarkbad5ad72017-08-03 17:14:08 -04004888 for (auto dest: { 20, 30, 40, 60, 90 } ) {
Cary Clarkca3ebcd2017-12-12 11:22:38 -05004889 canvas->drawBitmapLattice(bitmap, lattice, SkRect::MakeWH(dest, 110 - dest), nullptr);
Cary Clarkbad5ad72017-08-03 17:14:08 -04004890 canvas->translate(dest + 4, 0);
4891 }
Cary Clark8032b982017-07-28 11:04:54 -04004892}
4893##
4894
Cary Clark2ade9972017-11-02 17:49:34 -04004895#SeeAlso drawImageLattice drawBitmap drawBitmapNine Lattice
Cary Clark8032b982017-07-28 11:04:54 -04004896
4897##
4898
4899# ------------------------------------------------------------------------------
4900
4901#Method void drawImageLattice(const SkImage* image, const Lattice& lattice, const SkRect& dst,
4902 const SkPaint* paint = nullptr)
4903
Cary Clarkd0530ba2017-09-14 11:25:39 -04004904Draw Image image stretched proportionally to fit into Rect dst.
Cary Clark8032b982017-07-28 11:04:54 -04004905
4906Lattice lattice divides image into a rectangular grid.
4907Each intersection of an even-numbered row and column is fixed; like the corners
Cary Clarkbad5ad72017-08-03 17:14:08 -04004908of drawBitmapNine, fixed lattice elements never scale larger than their initial
Cary Clarkbc5697d2017-10-04 14:31:33 -04004909size and shrink proportionately when all fixed elements exceed the bitmap
Cary Clarkbad5ad72017-08-03 17:14:08 -04004910dimension. All other grid elements scale to fill the available space, if any.
Cary Clark8032b982017-07-28 11:04:54 -04004911
4912Additionally transform draw using Clip, Matrix, and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004913
Cary Clarkbad5ad72017-08-03 17:14:08 -04004914If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4915Blend_Mode, and Draw_Looper. If bitmap is kAlpha_8_SkColorType, apply Shader.
4916If paint contains Mask_Filter, generate mask from bitmap bounds.
4917
4918If generated mask extends beyond bitmap bounds, replicate bitmap edge colors,
4919just as Shader made from SkShader::MakeBitmapShader with
Cary Clarkbc5697d2017-10-04 14:31:33 -04004920SkShader::kClamp_TileMode set replicates the bitmap edge color when it samples
Cary Clarkbad5ad72017-08-03 17:14:08 -04004921outside of its bounds.
4922
4923#Param image Image containing pixels, dimensions, and format ##
4924#Param lattice division of bitmap into fixed and variable rectangles ##
4925#Param dst destination Rect of image to draw to ##
4926#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4927 and so on; or nullptr
4928##
Cary Clark8032b982017-07-28 11:04:54 -04004929
4930#Example
4931#Height 128
4932#Description
4933 The leftmost image is smaller than center; only corners are drawn, all scaled to fit.
Cary Clarkce101242017-09-01 15:51:02 -04004934 The second image equals the size of center; only corners are drawn without scaling.
4935 The remaining images are larger than center. All corners draw without scaling. The sides
Cary Clark8032b982017-07-28 11:04:54 -04004936 are scaled if needed to take up the remaining space; the center is transparent.
4937##
Cary Clarkbad5ad72017-08-03 17:14:08 -04004938void draw(SkCanvas* canvas) {
4939 SkIRect center = { 20, 10, 50, 40 };
4940 SkBitmap bitmap;
4941 bitmap.allocPixels(SkImageInfo::MakeN32Premul(60, 60));
4942 SkCanvas bitCanvas(bitmap);
4943 SkPaint paint;
4944 SkColor gray = 0xFF000000;
4945 int left = 0;
4946 for (auto right: { center.fLeft, center.fRight, bitmap.width() } ) {
4947 int top = 0;
4948 for (auto bottom: { center.fTop, center.fBottom, bitmap.height() } ) {
4949 paint.setColor(gray);
4950 bitCanvas.drawIRect(SkIRect::MakeLTRB(left, top, right, bottom), paint);
4951 gray += 0x001f1f1f;
4952 top = bottom;
4953 }
4954 left = right;
4955 }
4956 const int xDivs[] = { center.fLeft, center.fRight };
4957 const int yDivs[] = { center.fTop, center.fBottom };
Cary Clarkca3ebcd2017-12-12 11:22:38 -05004958 SkCanvas::Lattice::RectType fillTypes[3][3];
4959 memset(fillTypes, 0, sizeof(fillTypes));
4960 fillTypes[1][1] = SkCanvas::Lattice::kTransparent;
4961 SkColor dummy[9]; // temporary pending bug fix
4962 SkCanvas::Lattice lattice = { xDivs, yDivs, fillTypes[0], SK_ARRAY_COUNT(xDivs),
4963 SK_ARRAY_COUNT(yDivs), nullptr, dummy };
Cary Clarkbad5ad72017-08-03 17:14:08 -04004964 sk_sp<SkImage> image = SkImage::MakeFromBitmap(bitmap);
4965 SkImage* imagePtr = image.get();
4966 for (auto dest: { 20, 30, 40, 60, 90 } ) {
4967 canvas->drawImageNine(imagePtr, center, SkRect::MakeWH(dest, dest), nullptr);
4968 canvas->translate(dest + 4, 0);
4969 }
Cary Clark8032b982017-07-28 11:04:54 -04004970}
4971##
4972
Cary Clark2ade9972017-11-02 17:49:34 -04004973#SeeAlso drawBitmapLattice drawImage drawImageNine Lattice
Cary Clark8032b982017-07-28 11:04:54 -04004974
4975##
4976
4977#Topic Draw_Image ##
4978
4979# ------------------------------------------------------------------------------
4980
4981#Method void drawText(const void* text, size_t byteLength, SkScalar x, SkScalar y,
4982 const SkPaint& paint)
4983
4984Draw text, with origin at (x, y), using Clip, Matrix, and Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004985
Cary Clarkbc5697d2017-10-04 14:31:33 -04004986text meaning depends on Paint_Text_Encoding; by default, text is encoded as
Cary Clarkbad5ad72017-08-03 17:14:08 -04004987UTF-8.
Cary Clark8032b982017-07-28 11:04:54 -04004988
Cary Clarkbad5ad72017-08-03 17:14:08 -04004989x and y meaning depends on Paint_Text_Align and Paint_Vertical_Text; by default
Cary Clarkbc5697d2017-10-04 14:31:33 -04004990text draws left to right, positioning the first glyph left side bearing at x
Cary Clarkbad5ad72017-08-03 17:14:08 -04004991and its baseline at y. Text size is affected by Matrix and Paint_Text_Size.
4992
Mike Reed8ad91a92018-01-19 19:09:32 -05004993All elements of paint: Path_Effect, Mask_Filter, Shader,
Cary Clarkbad5ad72017-08-03 17:14:08 -04004994Color_Filter, Image_Filter, and Draw_Looper; apply to text. By default, draws
Cary Clarkce101242017-09-01 15:51:02 -04004995filled 12 point black Glyphs.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004996
Cary Clarkce101242017-09-01 15:51:02 -04004997#Param text character code points or Glyphs drawn ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04004998#Param byteLength byte length of text array ##
4999#Param x start of text on x-axis ##
5000#Param y start of text on y-axis ##
5001#Param paint text size, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005002
5003#Example
5004#Height 200
5005#Description
5006 The same text is drawn varying Paint_Text_Size and varying
5007 Matrix.
5008##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005009void draw(SkCanvas* canvas) {
5010 SkPaint paint;
5011 paint.setAntiAlias(true);
5012 float textSizes[] = { 12, 18, 24, 36 };
5013 for (auto size: textSizes ) {
5014 paint.setTextSize(size);
5015 canvas->drawText("Aa", 2, 10, 20, paint);
5016 canvas->translate(0, size * 2);
5017 }
5018 paint.reset();
5019 paint.setAntiAlias(true);
5020 float yPos = 20;
5021 for (auto size: textSizes ) {
5022 float scale = size / 12.f;
5023 canvas->resetMatrix();
5024 canvas->translate(100, 0);
5025 canvas->scale(scale, scale);
5026 canvas->drawText("Aa", 2, 10 / scale, yPos / scale, paint);
5027 yPos += size * 2;
5028 }
5029}
Cary Clark8032b982017-07-28 11:04:54 -04005030##
5031
Cary Clark2ade9972017-11-02 17:49:34 -04005032#SeeAlso drawString drawPosText drawPosTextH drawTextBlob drawTextOnPath drawTextRSXform
Cary Clark8032b982017-07-28 11:04:54 -04005033
5034##
5035
5036#Method void drawString(const char* 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
Mike Reed8ad91a92018-01-19 19:09:32 -05005049All elements of paint: Path_Effect, Mask_Filter, Shader,
Cary Clarkbad5ad72017-08-03 17:14:08 -04005050Color_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 canvas->drawString("a small hello", 20, 20, paint);
5063##
5064
Cary Clark2ade9972017-11-02 17:49:34 -04005065#SeeAlso drawText drawPosText drawPosTextH drawTextBlob drawTextOnPath drawTextRSXform
Cary Clark8032b982017-07-28 11:04:54 -04005066
5067##
5068
5069#Method void drawString(const SkString& string, SkScalar x, SkScalar y, const SkPaint& paint)
5070
Cary Clarkbad5ad72017-08-03 17:14:08 -04005071Draw null terminated string, with origin at (x, y), using Clip, Matrix, and
5072Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04005073
Cary Clarkbc5697d2017-10-04 14:31:33 -04005074string meaning depends on Paint_Text_Encoding; by default, strings are encoded
5075as UTF-8. Other values of Paint_Text_Encoding are unlikely to produce the desired
Cary Clarkbad5ad72017-08-03 17:14:08 -04005076results, since zero bytes may be embedded in the string.
Cary Clark8032b982017-07-28 11:04:54 -04005077
Cary Clarkbad5ad72017-08-03 17:14:08 -04005078x and y meaning depends on Paint_Text_Align and Paint_Vertical_Text; by default
Cary Clarkbc5697d2017-10-04 14:31:33 -04005079string draws left to right, positioning the first glyph left side bearing at x
Cary Clarkbad5ad72017-08-03 17:14:08 -04005080and its baseline at y. Text size is affected by Matrix and Paint_Text_Size.
5081
Mike Reed8ad91a92018-01-19 19:09:32 -05005082All elements of paint: Path_Effect, Mask_Filter, Shader,
Cary Clarkbad5ad72017-08-03 17:14:08 -04005083Color_Filter, Image_Filter, and Draw_Looper; apply to text. By default, draws
Cary Clarkce101242017-09-01 15:51:02 -04005084filled 12 point black Glyphs.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005085
Cary Clarkce101242017-09-01 15:51:02 -04005086#Param string character code points or Glyphs drawn,
Cary Clarkbad5ad72017-08-03 17:14:08 -04005087 ending with a char value of zero
5088##
5089#Param x start of string on x-axis ##
5090#Param y start of string on y-axis ##
5091#Param paint text size, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005092
5093#Example
5094 SkPaint paint;
5095 SkString string("a small hello");
5096 canvas->drawString(string, 20, 20, paint);
5097##
5098
Cary Clark2ade9972017-11-02 17:49:34 -04005099#SeeAlso drawText drawPosText drawPosTextH drawTextBlob drawTextOnPath drawTextRSXform
Cary Clark8032b982017-07-28 11:04:54 -04005100
5101##
5102
5103# ------------------------------------------------------------------------------
5104
5105#Method void drawPosText(const void* text, size_t byteLength, const SkPoint pos[],
5106 const SkPaint& paint)
5107
Cary Clarkbad5ad72017-08-03 17:14:08 -04005108Draw each glyph in text with the origin in pos array, using Clip, Matrix, and
Cary Clarkce101242017-09-01 15:51:02 -04005109Paint paint. The number of entries in pos array must match the number of Glyphs
Cary Clarkbad5ad72017-08-03 17:14:08 -04005110described by byteLength of text.
Cary Clark8032b982017-07-28 11:04:54 -04005111
Cary Clarkbc5697d2017-10-04 14:31:33 -04005112text meaning depends on Paint_Text_Encoding; by default, text is encoded as
Cary Clarkbad5ad72017-08-03 17:14:08 -04005113UTF-8. pos elements' meaning depends on Paint_Text_Align and Paint_Vertical_Text;
Cary Clarkbc5697d2017-10-04 14:31:33 -04005114by default each glyph left side bearing is positioned at x and its
Cary Clarkbad5ad72017-08-03 17:14:08 -04005115baseline is positioned at y. Text size is affected by Matrix and
5116Paint_Text_Size.
Cary Clark8032b982017-07-28 11:04:54 -04005117
Mike Reed8ad91a92018-01-19 19:09:32 -05005118All elements of paint: Path_Effect, Mask_Filter, Shader,
Cary Clarkbad5ad72017-08-03 17:14:08 -04005119Color_Filter, Image_Filter, and Draw_Looper; apply to text. By default, draws
Cary Clarkce101242017-09-01 15:51:02 -04005120filled 12 point black Glyphs.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005121
5122Layout engines such as Harfbuzz typically position each glyph
Cary Clarkbc5697d2017-10-04 14:31:33 -04005123rather than using the font advance widths.
Cary Clark8032b982017-07-28 11:04:54 -04005124
Cary Clarkce101242017-09-01 15:51:02 -04005125#Param text character code points or Glyphs drawn ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005126#Param byteLength byte length of text array ##
5127#Param pos array of glyph origins ##
5128#Param paint text size, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005129
5130#Example
5131#Height 120
Cary Clarkbad5ad72017-08-03 17:14:08 -04005132void draw(SkCanvas* canvas) {
5133 const char hello[] = "HeLLo!";
5134 const SkPoint pos[] = { {40, 100}, {82, 95}, {115, 110}, {130, 95}, {145, 85},
5135 {172, 100} };
5136 SkPaint paint;
5137 paint.setTextSize(60);
5138 canvas->drawPosText(hello, strlen(hello), pos, paint);
Cary Clark8032b982017-07-28 11:04:54 -04005139}
5140##
5141
Cary Clark2ade9972017-11-02 17:49:34 -04005142#SeeAlso drawText drawPosTextH drawTextBlob drawTextOnPath drawTextRSXform
Cary Clark8032b982017-07-28 11:04:54 -04005143
5144##
5145
5146# ------------------------------------------------------------------------------
5147
5148#Method void drawPosTextH(const void* text, size_t byteLength, const SkScalar xpos[], SkScalar constY,
5149 const SkPaint& paint)
5150
Cary Clarkbad5ad72017-08-03 17:14:08 -04005151Draw each glyph in text with its (x, y) origin composed from xpos array and
5152constY, using Clip, Matrix, and Paint paint. The number of entries in xpos array
Cary Clarkce101242017-09-01 15:51:02 -04005153must match the number of Glyphs described by byteLength of text.
Cary Clark8032b982017-07-28 11:04:54 -04005154
Cary Clarkbc5697d2017-10-04 14:31:33 -04005155text meaning depends on Paint_Text_Encoding; by default, text is encoded as
Cary Clarkce101242017-09-01 15:51:02 -04005156UTF-8. xpos elements' meaning depends on Paint_Text_Align and Paint_Vertical_Text;
Cary Clarkbc5697d2017-10-04 14:31:33 -04005157by default each glyph left side bearing is positioned at an xpos element and
Cary Clarkbad5ad72017-08-03 17:14:08 -04005158its baseline is positioned at constY. Text size is affected by Matrix and
5159Paint_Text_Size.
Cary Clark8032b982017-07-28 11:04:54 -04005160
Mike Reed8ad91a92018-01-19 19:09:32 -05005161All elements of paint: Path_Effect, Mask_Filter, Shader,
Cary Clarkbad5ad72017-08-03 17:14:08 -04005162Color_Filter, Image_Filter, and Draw_Looper; apply to text. By default, draws
Cary Clarkce101242017-09-01 15:51:02 -04005163filled 12 point black Glyphs.
Cary Clark8032b982017-07-28 11:04:54 -04005164
Cary Clarkbad5ad72017-08-03 17:14:08 -04005165Layout engines such as Harfbuzz typically position each glyph
Cary Clarkbc5697d2017-10-04 14:31:33 -04005166rather than using the font advance widths if all Glyphs share the same
Cary Clarkbad5ad72017-08-03 17:14:08 -04005167baseline.
5168
Cary Clarkce101242017-09-01 15:51:02 -04005169#Param text character code points or Glyphs drawn ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005170#Param byteLength byte length of text array ##
5171#Param xpos array of x positions, used to position each glyph ##
5172#Param constY shared y coordinate for all of x positions ##
5173#Param paint text size, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005174
5175#Example
5176#Height 40
Cary Clarkbad5ad72017-08-03 17:14:08 -04005177 void draw(SkCanvas* canvas) {
5178 SkScalar xpos[] = { 20, 40, 80, 160 };
5179 SkPaint paint;
5180 canvas->drawPosTextH("XXXX", 4, xpos, 20, paint);
5181 }
Cary Clark8032b982017-07-28 11:04:54 -04005182##
5183
Cary Clark2ade9972017-11-02 17:49:34 -04005184#SeeAlso drawText drawPosText drawTextBlob drawTextOnPath drawTextRSXform
Cary Clark8032b982017-07-28 11:04:54 -04005185
5186##
5187
5188# ------------------------------------------------------------------------------
5189
5190#Method void drawTextOnPathHV(const void* text, size_t byteLength, const SkPath& path, SkScalar hOffset,
5191 SkScalar vOffset, const SkPaint& paint)
5192
5193Draw text on Path path, using Clip, Matrix, and Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04005194
Cary Clarkbad5ad72017-08-03 17:14:08 -04005195Origin of text is at distance hOffset along the path, offset by a perpendicular
5196vector of length vOffset. If the path section corresponding the glyph advance is
5197curved, the glyph is drawn curved to match; control points in the glyph are
Cary Clarkbc5697d2017-10-04 14:31:33 -04005198mapped to projected points parallel to the path. If the text advance is larger
Cary Clarkbad5ad72017-08-03 17:14:08 -04005199than the path length, the excess text is clipped.
5200
Cary Clarkbc5697d2017-10-04 14:31:33 -04005201text meaning depends on Paint_Text_Encoding; by default, text is encoded as
Cary Clarkbad5ad72017-08-03 17:14:08 -04005202UTF-8. Origin meaning depends on Paint_Text_Align and Paint_Vertical_Text; by
Cary Clarkbc5697d2017-10-04 14:31:33 -04005203default text positions the first glyph left side bearing at origin x and its
Cary Clark8032b982017-07-28 11:04:54 -04005204baseline at origin y. Text size is affected by Matrix and Paint_Text_Size.
5205
Mike Reed8ad91a92018-01-19 19:09:32 -05005206All elements of paint: Path_Effect, Mask_Filter, Shader,
Cary Clarkbad5ad72017-08-03 17:14:08 -04005207Color_Filter, Image_Filter, and Draw_Looper; apply to text. By default, draws
Cary Clarkce101242017-09-01 15:51:02 -04005208filled 12 point black Glyphs.
Cary Clark8032b982017-07-28 11:04:54 -04005209
Cary Clarkce101242017-09-01 15:51:02 -04005210#Param text character code points or Glyphs drawn ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005211#Param byteLength byte length of text array ##
5212#Param path Path providing text baseline ##
5213#Param hOffset distance along path to offset origin ##
5214#Param vOffset offset of text above (if negative) or below (if positive) the path ##
5215#Param paint text size, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005216
5217#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04005218 void draw(SkCanvas* canvas) {
5219 const char aero[] = "correo a" "\xC3" "\xA9" "reo";
5220 const size_t len = sizeof(aero) - 1;
5221 SkPath path;
5222 path.addOval({43-26, 43-26, 43+26, 43+26}, SkPath::kCW_Direction, 3);
5223 SkPaint paint;
5224 paint.setTextSize(24);
5225 for (auto offset : { 0, 10, 20 } ) {
5226 canvas->drawTextOnPathHV(aero, len, path, 0, -offset, paint);
5227 canvas->translate(70 + offset, 70 + offset);
5228 }
5229 }
Cary Clark8032b982017-07-28 11:04:54 -04005230##
5231
Cary Clark2ade9972017-11-02 17:49:34 -04005232#SeeAlso drawTextOnPath drawText drawPosTextH drawTextBlob drawTextRSXform
Cary Clark8032b982017-07-28 11:04:54 -04005233
5234##
5235
5236# ------------------------------------------------------------------------------
5237
5238#Method void drawTextOnPath(const void* text, size_t byteLength, const SkPath& path,
5239 const SkMatrix* matrix, const SkPaint& paint)
5240
5241Draw text on Path path, using Clip, Matrix, and Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04005242
Cary Clarkbad5ad72017-08-03 17:14:08 -04005243Origin of text is at beginning of path offset by matrix, if provided, before it
5244is mapped to path. If the path section corresponding the glyph advance is
5245curved, the glyph is drawn curved to match; control points in the glyph are
Cary Clarkbc5697d2017-10-04 14:31:33 -04005246mapped to projected points parallel to the path. If the text advance is larger
Cary Clarkbad5ad72017-08-03 17:14:08 -04005247than the path length, the excess text is clipped.
5248
Cary Clarkbc5697d2017-10-04 14:31:33 -04005249text meaning depends on Paint_Text_Encoding; by default, text is encoded as
Cary Clarkbad5ad72017-08-03 17:14:08 -04005250UTF-8. Origin meaning depends on Paint_Text_Align and Paint_Vertical_Text; by
Cary Clarkbc5697d2017-10-04 14:31:33 -04005251default text positions the first glyph left side bearing at origin x and its
Cary Clark8032b982017-07-28 11:04:54 -04005252baseline at origin y. Text size is affected by Matrix and Paint_Text_Size.
5253
Mike Reed8ad91a92018-01-19 19:09:32 -05005254All elements of paint: Path_Effect, Mask_Filter, Shader,
Cary Clarkbad5ad72017-08-03 17:14:08 -04005255Color_Filter, Image_Filter, and Draw_Looper; apply to text. By default, draws
Cary Clarkce101242017-09-01 15:51:02 -04005256filled 12 point black Glyphs.
Cary Clark8032b982017-07-28 11:04:54 -04005257
Cary Clarkce101242017-09-01 15:51:02 -04005258#Param text character code points or Glyphs drawn ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005259#Param byteLength byte length of text array ##
5260#Param path Path providing text baseline ##
Cary Clarkce101242017-09-01 15:51:02 -04005261#Param matrix transform of Glyphs before mapping to path; may be nullptr
Cary Clarka523d2d2017-08-30 08:58:10 -04005262 to use identity Matrix
Cary Clarkbad5ad72017-08-03 17:14:08 -04005263##
5264#Param paint text size, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005265
5266#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04005267 void draw(SkCanvas* canvas) {
5268 const char roller[] = "rollercoaster";
5269 const size_t len = sizeof(roller) - 1;
5270 SkPath path;
5271 path.cubicTo(40, -80, 120, 80, 160, -40);
5272 SkPaint paint;
5273 paint.setTextSize(32);
5274 paint.setStyle(SkPaint::kStroke_Style);
5275 SkMatrix matrix;
5276 matrix.setIdentity();
5277 for (int i = 0; i < 3; ++i) {
5278 canvas->translate(25, 60);
5279 canvas->drawPath(path, paint);
5280 canvas->drawTextOnPath(roller, len, path, &matrix, paint);
5281 matrix.preTranslate(0, 10);
5282 }
5283 }
Cary Clark8032b982017-07-28 11:04:54 -04005284##
5285
Cary Clark2ade9972017-11-02 17:49:34 -04005286#SeeAlso drawTextOnPathHV drawText drawPosTextH drawTextBlob drawTextRSXform
Cary Clark8032b982017-07-28 11:04:54 -04005287
5288##
5289
5290# ------------------------------------------------------------------------------
5291
5292#Method void drawTextRSXform(const void* text, size_t byteLength, const SkRSXform xform[],
5293 const SkRect* cullRect, const SkPaint& paint)
5294
5295Draw text, transforming each glyph by the corresponding SkRSXform,
5296using Clip, Matrix, and Paint paint.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005297
Cary Clark8032b982017-07-28 11:04:54 -04005298RSXform array specifies a separate square scale, rotation, and translation for
5299each glyph.
Cary Clark8032b982017-07-28 11:04:54 -04005300
Cary Clarkbad5ad72017-08-03 17:14:08 -04005301Optional Rect cullRect is a conservative bounds of text, taking into account
Cary Clarkce101242017-09-01 15:51:02 -04005302RSXform and paint. If cullRect is outside of Clip, canvas can skip drawing.
Cary Clark8032b982017-07-28 11:04:54 -04005303
Mike Reed8ad91a92018-01-19 19:09:32 -05005304All elements of paint: Path_Effect, Mask_Filter, Shader,
Cary Clarkbad5ad72017-08-03 17:14:08 -04005305Color_Filter, Image_Filter, and Draw_Looper; apply to text. By default, draws
Cary Clarkce101242017-09-01 15:51:02 -04005306filled 12 point black Glyphs.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005307
Cary Clarkce101242017-09-01 15:51:02 -04005308#Param text character code points or Glyphs drawn ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005309#Param byteLength byte length of text array ##
5310#Param xform RSXform rotates, scales, and translates each glyph individually ##
5311#Param cullRect Rect bounds of text for efficient clipping; or nullptr ##
5312#Param paint text size, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005313
5314#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04005315void draw(SkCanvas* canvas) {
5316 const int iterations = 26;
5317 SkRSXform transforms[iterations];
5318 char alphabet[iterations];
5319 SkScalar angle = 0;
5320 SkScalar scale = 1;
5321 for (size_t i = 0; i < SK_ARRAY_COUNT(transforms); ++i) {
5322 const SkScalar s = SkScalarSin(angle) * scale;
5323 const SkScalar c = SkScalarCos(angle) * scale;
5324 transforms[i] = SkRSXform::Make(-c, -s, -s * 16, c * 16);
5325 angle += .45;
5326 scale += .2;
5327 alphabet[i] = 'A' + i;
5328 }
5329 SkPaint paint;
5330 paint.setTextAlign(SkPaint::kCenter_Align);
5331 canvas->translate(110, 138);
5332 canvas->drawTextRSXform(alphabet, sizeof(alphabet), transforms, nullptr, paint);
Cary Clark8032b982017-07-28 11:04:54 -04005333}
5334##
5335
Cary Clark2ade9972017-11-02 17:49:34 -04005336#SeeAlso drawTextOnPath drawTextOnPathHV drawText drawPosText drawTextBlob
Cary Clark8032b982017-07-28 11:04:54 -04005337
5338##
5339
5340# ------------------------------------------------------------------------------
5341
5342#Method void drawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y, const SkPaint& paint)
5343
5344Draw Text_Blob blob at (x, y), using Clip, Matrix, and Paint paint.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005345
Cary Clarkce101242017-09-01 15:51:02 -04005346blob contains Glyphs, their positions, and paint attributes specific to text:
Cary Clarkbad5ad72017-08-03 17:14:08 -04005347Typeface, Paint_Text_Size, Paint_Text_Scale_X, Paint_Text_Skew_X,
5348Paint_Text_Align, Paint_Hinting, Anti-alias, Paint_Fake_Bold,
5349Font_Embedded_Bitmaps, Full_Hinting_Spacing, LCD_Text, Linear_Text,
5350Subpixel_Text, and Paint_Vertical_Text.
Cary Clark8032b982017-07-28 11:04:54 -04005351
Cary Clark3cd22cc2017-12-01 11:49:58 -05005352Paint_Text_Encoding must be set to SkPaint::kGlyphID_TextEncoding.
5353
Mike Reed8ad91a92018-01-19 19:09:32 -05005354Elements of paint: Path_Effect, Mask_Filter, Shader, Color_Filter,
Cary Clark8032b982017-07-28 11:04:54 -04005355Image_Filter, and Draw_Looper; apply to blob.
5356
Cary Clarkce101242017-09-01 15:51:02 -04005357#Param blob Glyphs, positions, and their paints' text size, typeface, and so on ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005358#Param x horizontal offset applied to blob ##
5359#Param y vertical offset applied to blob ##
5360#Param paint blend, color, stroking, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005361
5362#Example
5363#Height 120
Cary Clarkbad5ad72017-08-03 17:14:08 -04005364 void draw(SkCanvas* canvas) {
Cary Clark2f466242017-12-11 16:03:17 -05005365 SkTextBlobBuilder textBlobBuilder;
5366 const char bunny[] = "/(^x^)\\";
5367 const int len = sizeof(bunny) - 1;
5368 uint16_t glyphs[len];
5369 SkPaint paint;
5370 paint.textToGlyphs(bunny, len, glyphs);
Cary Clark3cd22cc2017-12-01 11:49:58 -05005371 paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
Cary Clark2f466242017-12-11 16:03:17 -05005372 int runs[] = { 3, 1, 3 };
5373 SkPoint textPos = { 20, 100 };
5374 int glyphIndex = 0;
5375 for (auto runLen : runs) {
5376 paint.setTextSize(1 == runLen ? 20 : 50);
5377 const SkTextBlobBuilder::RunBuffer& run =
5378 textBlobBuilder.allocRun(paint, runLen, textPos.fX, textPos.fY);
5379 memcpy(run.glyphs, &glyphs[glyphIndex], sizeof(glyphs[0]) * runLen);
5380 textPos.fX += paint.measureText(&glyphs[glyphIndex], sizeof(glyphs[0]) * runLen, nullptr);
5381 glyphIndex += runLen;
5382 }
5383 sk_sp<const SkTextBlob> blob = textBlobBuilder.make();
5384 paint.reset();
Cary Clarkbad5ad72017-08-03 17:14:08 -04005385 canvas->drawTextBlob(blob.get(), 0, 0, paint);
Cary Clark8032b982017-07-28 11:04:54 -04005386 }
5387##
5388
Cary Clark2ade9972017-11-02 17:49:34 -04005389#SeeAlso drawText drawPosText drawPosTextH
Cary Clark8032b982017-07-28 11:04:54 -04005390
5391##
5392
5393# ------------------------------------------------------------------------------
5394
5395#Method void drawTextBlob(const sk_sp<SkTextBlob>& blob, SkScalar x, SkScalar y, const SkPaint& paint)
5396
5397Draw Text_Blob blob at (x, y), using Clip, Matrix, and Paint paint.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005398
Cary Clarkce101242017-09-01 15:51:02 -04005399blob contains Glyphs, their positions, and paint attributes specific to text:
Cary Clarkbad5ad72017-08-03 17:14:08 -04005400Typeface, Paint_Text_Size, Paint_Text_Scale_X, Paint_Text_Skew_X,
5401Paint_Text_Align, Paint_Hinting, Anti-alias, Paint_Fake_Bold,
5402Font_Embedded_Bitmaps, Full_Hinting_Spacing, LCD_Text, Linear_Text,
5403Subpixel_Text, and Paint_Vertical_Text.
Cary Clark8032b982017-07-28 11:04:54 -04005404
Cary Clark3cd22cc2017-12-01 11:49:58 -05005405Paint_Text_Encoding must be set to SkPaint::kGlyphID_TextEncoding.
5406
Mike Reed8ad91a92018-01-19 19:09:32 -05005407Elements of paint: Path_Effect, Mask_Filter, Shader, Color_Filter,
Cary Clark8032b982017-07-28 11:04:54 -04005408Image_Filter, and Draw_Looper; apply to blob.
5409
Cary Clarkce101242017-09-01 15:51:02 -04005410#Param blob Glyphs, positions, and their paints' text size, typeface, and so on ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005411#Param x horizontal offset applied to blob ##
5412#Param y vertical offset applied to blob ##
5413#Param paint blend, color, stroking, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005414
5415#Example
5416#Height 120
5417#Description
5418Paint attributes unrelated to text, like color, have no effect on paint in allocated Text_Blob.
5419Paint attributes related to text, like text size, have no effect on paint passed to drawTextBlob.
5420##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005421 void draw(SkCanvas* canvas) {
5422 SkTextBlobBuilder textBlobBuilder;
5423 SkPaint paint;
5424 paint.setTextSize(50);
5425 paint.setColor(SK_ColorRED);
Cary Clark2f466242017-12-11 16:03:17 -05005426 paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
Cary Clarkbad5ad72017-08-03 17:14:08 -04005427 const SkTextBlobBuilder::RunBuffer& run =
5428 textBlobBuilder.allocRun(paint, 1, 20, 100);
5429 run.glyphs[0] = 20;
5430 sk_sp<const SkTextBlob> blob = textBlobBuilder.make();
5431 paint.setTextSize(10);
5432 paint.setColor(SK_ColorBLUE);
5433 canvas->drawTextBlob(blob.get(), 0, 0, paint);
5434 }
Cary Clark8032b982017-07-28 11:04:54 -04005435##
5436
Cary Clark2ade9972017-11-02 17:49:34 -04005437#SeeAlso drawText drawPosText drawPosTextH
Cary Clark8032b982017-07-28 11:04:54 -04005438
5439##
5440
5441# ------------------------------------------------------------------------------
5442
5443#Method void drawPicture(const SkPicture* picture)
5444
5445Draw Picture picture, using Clip and Matrix.
5446Clip and Matrix are unchanged by picture contents, as if
5447save() was called before and restore() was called after drawPicture.
5448
5449Picture records a series of draw commands for later playback.
5450
Cary Clarkbad5ad72017-08-03 17:14:08 -04005451#Param picture recorded drawing commands to play ##
Cary Clark8032b982017-07-28 11:04:54 -04005452
5453#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04005454void draw(SkCanvas* canvas) {
5455 SkPictureRecorder recorder;
5456 SkCanvas* recordingCanvas = recorder.beginRecording(50, 50);
5457 for (auto color : { SK_ColorRED, SK_ColorBLUE, 0xff007f00 } ) {
5458 SkPaint paint;
5459 paint.setColor(color);
5460 recordingCanvas->drawRect({10, 10, 30, 40}, paint);
5461 recordingCanvas->translate(10, 10);
5462 recordingCanvas->scale(1.2f, 1.4f);
5463 }
5464 sk_sp<SkPicture> playback = recorder.finishRecordingAsPicture();
5465 const SkPicture* playbackPtr = playback.get();
5466 canvas->drawPicture(playback);
5467 canvas->scale(2, 2);
5468 canvas->translate(50, 0);
5469 canvas->drawPicture(playback);
Cary Clark8032b982017-07-28 11:04:54 -04005470}
5471##
5472
Cary Clark2ade9972017-11-02 17:49:34 -04005473#SeeAlso drawDrawable SkPicture SkPicture::playback
Cary Clark8032b982017-07-28 11:04:54 -04005474
5475##
5476
5477# ------------------------------------------------------------------------------
5478
5479#Method void drawPicture(const sk_sp<SkPicture>& picture)
5480
5481Draw Picture picture, using Clip and Matrix.
5482Clip and Matrix are unchanged by picture contents, as if
5483save() was called before and restore() was called after drawPicture.
5484
5485Picture records a series of draw commands for later playback.
5486
Cary Clarkbad5ad72017-08-03 17:14:08 -04005487#Param picture recorded drawing commands to play ##
Cary Clark8032b982017-07-28 11:04:54 -04005488
5489#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04005490void draw(SkCanvas* canvas) {
5491 SkPictureRecorder recorder;
5492 SkCanvas* recordingCanvas = recorder.beginRecording(50, 50);
5493 for (auto color : { SK_ColorRED, SK_ColorBLUE, 0xff007f00 } ) {
5494 SkPaint paint;
5495 paint.setColor(color);
5496 recordingCanvas->drawRect({10, 10, 30, 40}, paint);
5497 recordingCanvas->translate(10, 10);
5498 recordingCanvas->scale(1.2f, 1.4f);
5499 }
5500 sk_sp<SkPicture> playback = recorder.finishRecordingAsPicture();
5501 canvas->drawPicture(playback);
5502 canvas->scale(2, 2);
5503 canvas->translate(50, 0);
5504 canvas->drawPicture(playback);
Cary Clark8032b982017-07-28 11:04:54 -04005505}
5506##
5507
Cary Clark2ade9972017-11-02 17:49:34 -04005508#SeeAlso drawDrawable SkPicture SkPicture::playback
Cary Clark8032b982017-07-28 11:04:54 -04005509
5510##
5511
5512# ------------------------------------------------------------------------------
5513
5514#Method void drawPicture(const SkPicture* picture, const SkMatrix* matrix, const SkPaint* paint)
5515
Cary Clarkbad5ad72017-08-03 17:14:08 -04005516Draw Picture picture, using Clip and Matrix; transforming picture with
5517Matrix matrix, if provided; and use Paint paint Color_Alpha, Color_Filter,
5518Image_Filter, and Blend_Mode, if provided.
Cary Clark8032b982017-07-28 11:04:54 -04005519
5520matrix transformation is equivalent to: save(), concat(), drawPicture, restore().
5521paint use is equivalent to: saveLayer, drawPicture, restore().
5522
Cary Clarkbad5ad72017-08-03 17:14:08 -04005523#Param picture recorded drawing commands to play ##
5524#Param matrix Matrix to rotate, scale, translate, and so on; may be nullptr ##
5525#Param paint Paint to apply transparency, filtering, and so on; may be nullptr ##
Cary Clark8032b982017-07-28 11:04:54 -04005526
5527#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04005528void draw(SkCanvas* canvas) {
5529 SkPaint paint;
5530 SkPictureRecorder recorder;
5531 SkCanvas* recordingCanvas = recorder.beginRecording(50, 50);
5532 for (auto color : { SK_ColorRED, SK_ColorBLUE, 0xff007f00 } ) {
5533 paint.setColor(color);
5534 recordingCanvas->drawRect({10, 10, 30, 40}, paint);
5535 recordingCanvas->translate(10, 10);
5536 recordingCanvas->scale(1.2f, 1.4f);
5537 }
5538 sk_sp<SkPicture> playback = recorder.finishRecordingAsPicture();
5539 const SkPicture* playbackPtr = playback.get();
5540 SkMatrix matrix;
5541 matrix.reset();
5542 for (auto alpha : { 70, 140, 210 } ) {
5543 paint.setAlpha(alpha);
5544 canvas->drawPicture(playbackPtr, &matrix, &paint);
5545 matrix.preTranslate(70, 70);
5546 }
Cary Clark8032b982017-07-28 11:04:54 -04005547}
5548##
5549
Cary Clark2ade9972017-11-02 17:49:34 -04005550#SeeAlso drawDrawable SkPicture SkPicture::playback
Cary Clark8032b982017-07-28 11:04:54 -04005551
5552##
5553
5554# ------------------------------------------------------------------------------
5555
5556#Method void drawPicture(const sk_sp<SkPicture>& picture, const SkMatrix* matrix, const SkPaint* paint)
5557
Cary Clarkbad5ad72017-08-03 17:14:08 -04005558Draw Picture picture, using Clip and Matrix; transforming picture with
5559Matrix matrix, if provided; and use Paint paint Color_Alpha, Color_Filter,
5560Image_Filter, and Blend_Mode, if provided.
Cary Clark8032b982017-07-28 11:04:54 -04005561
5562matrix transformation is equivalent to: save(), concat(), drawPicture, restore().
5563paint use is equivalent to: saveLayer, drawPicture, restore().
5564
Cary Clarkbad5ad72017-08-03 17:14:08 -04005565#Param picture recorded drawing commands to play ##
5566#Param matrix Matrix to rotate, scale, translate, and so on; may be nullptr ##
5567#Param paint Paint to apply transparency, filtering, and so on; may be nullptr ##
Cary Clark8032b982017-07-28 11:04:54 -04005568
5569#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04005570void draw(SkCanvas* canvas) {
5571 SkPaint paint;
5572 SkPictureRecorder recorder;
5573 SkCanvas* recordingCanvas = recorder.beginRecording(50, 50);
5574 for (auto color : { SK_ColorRED, SK_ColorBLUE, 0xff007f00 } ) {
5575 paint.setColor(color);
5576 recordingCanvas->drawRect({10, 10, 30, 40}, paint);
5577 recordingCanvas->translate(10, 10);
5578 recordingCanvas->scale(1.2f, 1.4f);
5579 }
5580 sk_sp<SkPicture> playback = recorder.finishRecordingAsPicture();
5581 SkMatrix matrix;
5582 matrix.reset();
5583 for (auto alpha : { 70, 140, 210 } ) {
5584 paint.setAlpha(alpha);
5585 canvas->drawPicture(playback, &matrix, &paint);
5586 matrix.preTranslate(70, 70);
5587 }
Cary Clark8032b982017-07-28 11:04:54 -04005588}
5589##
5590
Cary Clark2ade9972017-11-02 17:49:34 -04005591#SeeAlso drawDrawable SkPicture SkPicture::playback
Cary Clark8032b982017-07-28 11:04:54 -04005592
5593##
5594
5595# ------------------------------------------------------------------------------
5596
5597#Method void drawVertices(const SkVertices* vertices, SkBlendMode mode, const SkPaint& paint)
5598
5599Draw Vertices vertices, a triangle mesh, using Clip and Matrix.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005600If Vertices_Texs and Vertices_Colors are defined in vertices, and Paint paint
5601contains Shader, Blend_Mode mode combines Vertices_Colors with Shader.
Cary Clark8032b982017-07-28 11:04:54 -04005602
Cary Clarkbad5ad72017-08-03 17:14:08 -04005603#Param vertices triangle mesh to draw ##
5604#Param mode combines Vertices_Colors with Shader, if both are present ##
5605#Param paint specifies the Shader, used as Vertices texture; may be nullptr ##
Cary Clark8032b982017-07-28 11:04:54 -04005606
5607#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04005608void draw(SkCanvas* canvas) {
5609 SkPaint paint;
5610 SkPoint points[] = { { 0, 0 }, { 250, 0 }, { 100, 100 }, { 0, 250 } };
5611 SkColor colors[] = { SK_ColorRED, SK_ColorBLUE, SK_ColorYELLOW, SK_ColorCYAN };
5612 auto vertices = SkVertices::MakeCopy(SkVertices::kTriangleFan_VertexMode,
5613 SK_ARRAY_COUNT(points), points, nullptr, colors);
5614 canvas->drawVertices(vertices.get(), SkBlendMode::kSrc, paint);
5615}
Cary Clark8032b982017-07-28 11:04:54 -04005616##
5617
Cary Clark2ade9972017-11-02 17:49:34 -04005618#SeeAlso drawPatch drawPicture
Cary Clark8032b982017-07-28 11:04:54 -04005619
5620##
5621
5622# ------------------------------------------------------------------------------
5623
5624#Method void drawVertices(const sk_sp<SkVertices>& vertices, SkBlendMode mode, const SkPaint& paint)
5625
5626Draw Vertices vertices, a triangle mesh, using Clip and Matrix.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005627If Vertices_Texs and Vertices_Colors are defined in vertices, and Paint paint
5628contains Shader, Blend_Mode mode combines Vertices_Colors with Shader.
Cary Clark8032b982017-07-28 11:04:54 -04005629
Cary Clarkbad5ad72017-08-03 17:14:08 -04005630#Param vertices triangle mesh to draw ##
5631#Param mode combines Vertices_Colors with Shader, if both are present ##
5632#Param paint specifies the Shader, used as Vertices texture, may be nullptr ##
Cary Clark8032b982017-07-28 11:04:54 -04005633
5634#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04005635void draw(SkCanvas* canvas) {
5636 SkPaint paint;
5637 SkPoint points[] = { { 0, 0 }, { 250, 0 }, { 100, 100 }, { 0, 250 } };
5638 SkPoint texs[] = { { 0, 0 }, { 0, 250 }, { 250, 250 }, { 250, 0 } };
5639 SkColor colors[] = { SK_ColorRED, SK_ColorBLUE, SK_ColorYELLOW, SK_ColorCYAN };
5640 paint.setShader(SkGradientShader::MakeLinear(points, colors, nullptr, 4,
5641 SkShader::kClamp_TileMode));
5642 auto vertices = SkVertices::MakeCopy(SkVertices::kTriangleFan_VertexMode,
5643 SK_ARRAY_COUNT(points), points, texs, colors);
5644 canvas->drawVertices(vertices.get(), SkBlendMode::kDarken, paint);
Cary Clark8032b982017-07-28 11:04:54 -04005645}
5646##
5647
Cary Clark2ade9972017-11-02 17:49:34 -04005648#SeeAlso drawPatch drawPicture
Cary Clark8032b982017-07-28 11:04:54 -04005649
5650##
5651
5652# ------------------------------------------------------------------------------
5653
5654#Method void drawPatch(const SkPoint cubics[12], const SkColor colors[4],
5655 const SkPoint texCoords[4], SkBlendMode mode, const SkPaint& paint)
5656
Cary Clarka560c472017-11-27 10:44:06 -05005657Draws a Coons_Patch: the interpolation of four cubics with shared corners,
Cary Clark8032b982017-07-28 11:04:54 -04005658associating a color, and optionally a texture coordinate, with each corner.
5659
Cary Clarka560c472017-11-27 10:44:06 -05005660Coons_Patch uses Clip and Matrix, paint Shader, Color_Filter,
Cary Clarkbad5ad72017-08-03 17:14:08 -04005661Color_Alpha, Image_Filter, and Blend_Mode. If Shader is provided it is treated
Cary Clarka560c472017-11-27 10:44:06 -05005662as Coons_Patch texture; Blend_Mode mode combines Color colors and Shader if
Cary Clarkbad5ad72017-08-03 17:14:08 -04005663both are provided.
Cary Clark8032b982017-07-28 11:04:54 -04005664
Cary Clarkbc5697d2017-10-04 14:31:33 -04005665Point array cubics specifies four Cubics starting at the top-left corner,
Cary Clarkce101242017-09-01 15:51:02 -04005666in clockwise order, sharing every fourth point. The last Cubic ends at the
Cary Clarkbad5ad72017-08-03 17:14:08 -04005667first point.
Cary Clark8032b982017-07-28 11:04:54 -04005668
Cary Clarkbc5697d2017-10-04 14:31:33 -04005669Color array color associates colors with corners in top-left, top-right,
5670bottom-right, bottom-left order.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005671
5672If paint contains Shader, Point array texCoords maps Shader as texture to
Cary Clarkbc5697d2017-10-04 14:31:33 -04005673corners in top-left, top-right, bottom-right, bottom-left order.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005674
Cary Clarka523d2d2017-08-30 08:58:10 -04005675#Param cubics Path_Cubic array, sharing common points ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005676#Param colors Color array, one for each corner ##
Cary Clarkce101242017-09-01 15:51:02 -04005677#Param texCoords Point array of texture coordinates, mapping Shader to corners;
Cary Clarkbad5ad72017-08-03 17:14:08 -04005678 may be nullptr
Cary Clark579985c2017-07-31 11:48:27 -04005679#Param ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005680#Param mode Blend_Mode for colors, and for Shader if paint has one ##
5681#Param paint Shader, Color_Filter, Blend_Mode, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005682
5683#Example
5684#Image 5
Cary Clarkbad5ad72017-08-03 17:14:08 -04005685void draw(SkCanvas* canvas) {
5686 // SkBitmap source = cmbkygk;
5687 SkPaint paint;
5688 paint.setFilterQuality(kLow_SkFilterQuality);
5689 paint.setAntiAlias(true);
5690 SkPoint cubics[] = { { 3, 1 }, { 4, 2 }, { 5, 1 }, { 7, 3 },
5691 /* { 7, 3 }, */ { 6, 4 }, { 7, 5 }, { 5, 7 },
5692 /* { 5, 7 }, */ { 4, 6 }, { 3, 7 }, { 1, 5 },
5693 /* { 1, 5 }, */ { 2, 4 }, { 1, 3 }, /* { 3, 1 } */ };
5694 SkColor colors[] = { 0xbfff0000, 0xbf0000ff, 0xbfff00ff, 0xbf00ffff };
5695 SkPoint texCoords[] = { { -30, -30 }, { 162, -30}, { 162, 162}, { -30, 162} };
5696 paint.setShader(SkShader::MakeBitmapShader(source, SkShader::kClamp_TileMode,
5697 SkShader::kClamp_TileMode, nullptr));
5698 canvas->scale(15, 15);
5699 for (auto blend : { SkBlendMode::kSrcOver, SkBlendMode::kModulate, SkBlendMode::kXor } ) {
5700 canvas->drawPatch(cubics, colors, texCoords, blend, paint);
5701 canvas->translate(4, 4);
5702 }
Cary Clark8032b982017-07-28 11:04:54 -04005703}
5704##
5705
Cary Clark2ade9972017-11-02 17:49:34 -04005706#ToDo can patch use image filter? ##
5707#SeeAlso SeeAlso drawVertices drawPicture
Cary Clark8032b982017-07-28 11:04:54 -04005708
5709##
5710
5711# ------------------------------------------------------------------------------
5712
5713#Method void drawPatch(const SkPoint cubics[12], const SkColor colors[4],
5714 const SkPoint texCoords[4], const SkPaint& paint)
5715
Cary Clarka560c472017-11-27 10:44:06 -05005716Draws Cubic Coons_Patch: the interpolation of four cubics with shared corners,
Cary Clarkbad5ad72017-08-03 17:14:08 -04005717associating a color, and optionally a texture coordinate, with each corner.
Cary Clark8032b982017-07-28 11:04:54 -04005718
Cary Clarka560c472017-11-27 10:44:06 -05005719Coons_Patch uses Clip and Matrix, paint Shader, Color_Filter,
Cary Clarkbad5ad72017-08-03 17:14:08 -04005720Color_Alpha, Image_Filter, and Blend_Mode. If Shader is provided it is treated
Cary Clarka560c472017-11-27 10:44:06 -05005721as Coons_Patch texture; Blend_Mode mode combines Color colors and Shader if
Cary Clarkbad5ad72017-08-03 17:14:08 -04005722both are provided.
Cary Clark8032b982017-07-28 11:04:54 -04005723
Cary Clarkbc5697d2017-10-04 14:31:33 -04005724Point array cubics specifies four Cubics starting at the top-left corner,
Cary Clarkce101242017-09-01 15:51:02 -04005725in clockwise order, sharing every fourth point. The last Cubic ends at the
Cary Clarkbad5ad72017-08-03 17:14:08 -04005726first point.
5727
Cary Clarkbc5697d2017-10-04 14:31:33 -04005728Color array color associates colors with corners in top-left, top-right,
5729bottom-right, bottom-left order.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005730
5731If paint contains Shader, Point array texCoords maps Shader as texture to
Cary Clarkbc5697d2017-10-04 14:31:33 -04005732corners in top-left, top-right, bottom-right, bottom-left order.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005733
Cary Clarka523d2d2017-08-30 08:58:10 -04005734#Param cubics Path_Cubic array, sharing common points ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005735#Param colors Color array, one for each corner ##
Cary Clarkce101242017-09-01 15:51:02 -04005736#Param texCoords Point array of texture coordinates, mapping Shader to corners;
Cary Clarkbad5ad72017-08-03 17:14:08 -04005737 may be nullptr
Cary Clark579985c2017-07-31 11:48:27 -04005738#Param ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005739#Param paint Shader, Color_Filter, Blend_Mode, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005740
5741#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04005742void draw(SkCanvas* canvas) {
5743 SkPaint paint;
5744 paint.setAntiAlias(true);
5745 SkPoint cubics[] = { { 3, 1 }, { 4, 2 }, { 5, 1 }, { 7, 3 },
5746 /* { 7, 3 }, */ { 6, 4 }, { 7, 5 }, { 5, 7 },
5747 /* { 5, 7 }, */ { 4, 6 }, { 3, 7 }, { 1, 5 },
5748 /* { 1, 5 }, */ { 2, 4 }, { 1, 3 }, /* { 3, 1 } */ };
5749 SkColor colors[] = { SK_ColorRED, SK_ColorBLUE, SK_ColorYELLOW, SK_ColorCYAN };
5750 canvas->scale(30, 30);
5751 canvas->drawPatch(cubics, colors, nullptr, paint);
5752 SkPoint text[] = { {3,0.9f}, {4,2.5f}, {5,0.9f}, {7.5f,3.2f}, {5.5f,4.2f},
5753 {7.5f,5.2f}, {5,7.5f}, {4,5.9f}, {3,7.5f}, {0.5f,5.2f}, {2.5f,4.2f},
5754 {0.5f,3.2f} };
5755 paint.setTextSize(18.f / 30);
5756 paint.setTextAlign(SkPaint::kCenter_Align);
5757 for (int i = 0; i< 10; ++i) {
5758 char digit = '0' + i;
5759 canvas->drawText(&digit, 1, text[i].fX, text[i].fY, paint);
5760 }
5761 canvas->drawString("10", text[10].fX, text[10].fY, paint);
5762 canvas->drawString("11", text[11].fX, text[11].fY, paint);
5763 paint.setStyle(SkPaint::kStroke_Style);
5764 canvas->drawPoints(SkCanvas::kPolygon_PointMode, 12, cubics, paint);
5765 canvas->drawLine(cubics[11].fX, cubics[11].fY, cubics[0].fX, cubics[0].fY, paint);
Cary Clark8032b982017-07-28 11:04:54 -04005766}
5767##
5768
5769#Example
5770#Image 6
Cary Clarkbad5ad72017-08-03 17:14:08 -04005771void draw(SkCanvas* canvas) {
5772 // SkBitmap source = checkerboard;
5773 SkPaint paint;
5774 paint.setFilterQuality(kLow_SkFilterQuality);
5775 paint.setAntiAlias(true);
5776 SkPoint cubics[] = { { 3, 1 }, { 4, 2 }, { 5, 1 }, { 7, 3 },
5777 /* { 7, 3 }, */ { 6, 4 }, { 7, 5 }, { 5, 7 },
5778 /* { 5, 7 }, */ { 4, 6 }, { 3, 7 }, { 1, 5 },
5779 /* { 1, 5 }, */ { 2, 4 }, { 1, 3 }, /* { 3, 1 } */ };
5780 SkPoint texCoords[] = { { 0, 0 }, { 0, 62}, { 62, 62}, { 62, 0 } };
5781 paint.setShader(SkShader::MakeBitmapShader(source, SkShader::kClamp_TileMode,
5782 SkShader::kClamp_TileMode, nullptr));
5783 canvas->scale(30, 30);
5784 canvas->drawPatch(cubics, nullptr, texCoords, paint);
Cary Clark8032b982017-07-28 11:04:54 -04005785}
5786##
5787
Cary Clark2ade9972017-11-02 17:49:34 -04005788#ToDo can patch use image filter? ##
5789#SeeAlso SeeAlso drawVertices drawPicture
Cary Clark8032b982017-07-28 11:04:54 -04005790
5791##
5792
5793# ------------------------------------------------------------------------------
5794
5795#Method void drawAtlas(const SkImage* atlas, const SkRSXform xform[], const SkRect tex[],
5796 const SkColor colors[], int count, SkBlendMode mode, const SkRect* cullRect,
5797 const SkPaint* paint)
5798
5799Draw a set of sprites from atlas, using Clip, Matrix, and optional Paint paint.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005800paint uses Anti-alias, Color_Alpha, Color_Filter, Image_Filter, and Blend_Mode
5801to draw, if present. For each entry in the array, Rect tex locates sprite in
5802atlas, and RSXform xform transforms it into destination space.
5803
Cary Clark8032b982017-07-28 11:04:54 -04005804xform, text, and colors if present, must contain count entries.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005805Optional colors are applied for each sprite using Blend_Mode.
Cary Clark8032b982017-07-28 11:04:54 -04005806Optional cullRect is a conservative bounds of all transformed sprites.
Cary Clarkce101242017-09-01 15:51:02 -04005807If cullRect is outside of Clip, canvas can skip drawing.
Cary Clark8032b982017-07-28 11:04:54 -04005808
Cary Clarkbad5ad72017-08-03 17:14:08 -04005809#Param atlas Image containing sprites ##
5810#Param xform RSXform mappings for sprites in atlas ##
5811#Param tex Rect locations of sprites in atlas ##
Cary Clark6fc50412017-09-21 12:31:06 -04005812#Param colors one per sprite, blended with sprite using Blend_Mode; may be nullptr ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005813#Param count number of sprites to draw ##
5814#Param mode Blend_Mode combining colors and sprites ##
Cary Clark6fc50412017-09-21 12:31:06 -04005815#Param cullRect bounds of transformed sprites for efficient clipping; may be nullptr ##
5816#Param paint Color_Filter, Image_Filter, Blend_Mode, and so on; may be nullptr ##
Cary Clark8032b982017-07-28 11:04:54 -04005817
5818#Example
5819#Image 3
Cary Clarkbad5ad72017-08-03 17:14:08 -04005820void draw(SkCanvas* canvas) {
5821 // SkBitmap source = mandrill;
5822 SkRSXform xforms[] = { { .5f, 0, 0, 0 }, {0, .5f, 200, 100 } };
5823 SkRect tex[] = { { 0, 0, 250, 250 }, { 0, 0, 250, 250 } };
5824 SkColor colors[] = { 0x7f55aa00, 0x7f3333bf };
5825 const SkImage* imagePtr = image.get();
5826 canvas->drawAtlas(imagePtr, xforms, tex, colors, 2, SkBlendMode::kSrcOver, nullptr, nullptr);
Cary Clark8032b982017-07-28 11:04:54 -04005827}
5828##
5829
Cary Clark2ade9972017-11-02 17:49:34 -04005830#SeeAlso drawBitmap drawImage
Cary Clark8032b982017-07-28 11:04:54 -04005831
5832##
5833
5834# ------------------------------------------------------------------------------
5835
5836#Method void drawAtlas(const sk_sp<SkImage>& atlas, const SkRSXform xform[], const SkRect tex[],
5837 const SkColor colors[], int count, SkBlendMode mode, const SkRect* cullRect,
5838 const SkPaint* paint)
5839
5840Draw a set of sprites from atlas, using Clip, Matrix, and optional Paint paint.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005841paint uses Anti-alias, Color_Alpha, Color_Filter, Image_Filter, and Blend_Mode
5842to draw, if present. For each entry in the array, Rect tex locates sprite in
5843atlas, and RSXform xform transforms it into destination space.
5844
Cary Clark8032b982017-07-28 11:04:54 -04005845xform, text, and colors if present, must contain count entries.
5846Optional colors is applied for each sprite using Blend_Mode.
5847Optional cullRect is a conservative bounds of all transformed sprites.
Cary Clarkce101242017-09-01 15:51:02 -04005848If cullRect is outside of Clip, canvas can skip drawing.
Cary Clark8032b982017-07-28 11:04:54 -04005849
Cary Clarkbad5ad72017-08-03 17:14:08 -04005850#Param atlas Image containing sprites ##
5851#Param xform RSXform mappings for sprites in atlas ##
5852#Param tex Rect locations of sprites in atlas ##
Cary Clark6fc50412017-09-21 12:31:06 -04005853#Param colors one per sprite, blended with sprite using Blend_Mode; may be nullptr ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005854#Param count number of sprites to draw ##
5855#Param mode Blend_Mode combining colors and sprites ##
Cary Clark6fc50412017-09-21 12:31:06 -04005856#Param cullRect bounds of transformed sprites for efficient clipping; may be nullptr ##
5857#Param paint Color_Filter, Image_Filter, Blend_Mode, and so on; may be nullptr ##
Cary Clark8032b982017-07-28 11:04:54 -04005858
5859#Example
5860#Image 3
Cary Clarkbad5ad72017-08-03 17:14:08 -04005861void draw(SkCanvas* canvas) {
5862 // SkBitmap source = mandrill;
5863 SkRSXform xforms[] = { { .5f, 0, 0, 0 }, {0, .5f, 200, 100 } };
5864 SkRect tex[] = { { 0, 0, 250, 250 }, { 0, 0, 250, 250 } };
5865 SkColor colors[] = { 0x7f55aa00, 0x7f3333bf };
5866 SkPaint paint;
5867 paint.setAlpha(127);
5868 canvas->drawAtlas(image, xforms, tex, colors, 2, SkBlendMode::kPlus, nullptr, &paint);
Cary Clark8032b982017-07-28 11:04:54 -04005869}
5870##
5871
5872#ToDo bug in example on cpu side, gpu looks ok ##
5873
Cary Clark2ade9972017-11-02 17:49:34 -04005874#SeeAlso drawBitmap drawImage
5875
Cary Clark8032b982017-07-28 11:04:54 -04005876##
5877
5878# ------------------------------------------------------------------------------
5879
5880#Method void drawAtlas(const SkImage* atlas, const SkRSXform xform[], const SkRect tex[], int count,
5881 const SkRect* cullRect, const SkPaint* paint)
5882
5883Draw a set of sprites from atlas, using Clip, Matrix, and optional Paint paint.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005884paint uses Anti-alias, Color_Alpha, Color_Filter, Image_Filter, and Blend_Mode
5885to draw, if present. For each entry in the array, Rect tex locates sprite in
5886atlas, and RSXform xform transforms it into destination space.
5887
Cary Clark8032b982017-07-28 11:04:54 -04005888xform and text must contain count entries.
5889Optional cullRect is a conservative bounds of all transformed sprites.
Cary Clarkce101242017-09-01 15:51:02 -04005890If cullRect is outside of Clip, canvas can skip drawing.
Cary Clark8032b982017-07-28 11:04:54 -04005891
Cary Clarkbad5ad72017-08-03 17:14:08 -04005892#Param atlas Image containing sprites ##
5893#Param xform RSXform mappings for sprites in atlas ##
5894#Param tex Rect locations of sprites in atlas ##
5895#Param count number of sprites to draw ##
Cary Clark6fc50412017-09-21 12:31:06 -04005896#Param cullRect bounds of transformed sprites for efficient clipping; may be nullptr ##
5897#Param paint Color_Filter, Image_Filter, Blend_Mode, and so on; may be nullptr ##
Cary Clark8032b982017-07-28 11:04:54 -04005898
5899#Example
5900#Image 3
Cary Clarkbad5ad72017-08-03 17:14:08 -04005901void draw(SkCanvas* canvas) {
5902 // sk_sp<SkImage> image = mandrill;
5903 SkRSXform xforms[] = { { .5f, 0, 0, 0 }, {0, .5f, 200, 100 } };
5904 SkRect tex[] = { { 0, 0, 250, 250 }, { 0, 0, 250, 250 } };
5905 const SkImage* imagePtr = image.get();
5906 canvas->drawAtlas(imagePtr, xforms, tex, 2, nullptr, nullptr);
Cary Clark8032b982017-07-28 11:04:54 -04005907}
5908##
5909
Cary Clark2ade9972017-11-02 17:49:34 -04005910#SeeAlso drawBitmap drawImage
Cary Clark8032b982017-07-28 11:04:54 -04005911
5912##
5913
5914# ------------------------------------------------------------------------------
5915
5916#Method void drawAtlas(const sk_sp<SkImage>& atlas, const SkRSXform xform[], const SkRect tex[],
5917 int count, const SkRect* cullRect, const SkPaint* paint)
5918
5919Draw a set of sprites from atlas, using Clip, Matrix, and optional Paint paint.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005920paint uses Anti-alias, Color_Alpha, Color_Filter, Image_Filter, and Blend_Mode
5921to draw, if present. For each entry in the array, Rect tex locates sprite in
5922atlas, and RSXform xform transforms it into destination space.
5923
Cary Clark8032b982017-07-28 11:04:54 -04005924xform and text must contain count entries.
5925Optional cullRect is a conservative bounds of all transformed sprites.
Cary Clarkce101242017-09-01 15:51:02 -04005926If cullRect is outside of Clip, canvas can skip drawing.
Cary Clark8032b982017-07-28 11:04:54 -04005927
Cary Clarkbad5ad72017-08-03 17:14:08 -04005928#Param atlas Image containing sprites ##
5929#Param xform RSXform mappings for sprites in atlas ##
5930#Param tex Rect locations of sprites in atlas ##
5931#Param count number of sprites to draw ##
Cary Clark6fc50412017-09-21 12:31:06 -04005932#Param cullRect bounds of transformed sprites for efficient clipping; may be nullptr ##
5933#Param paint Color_Filter, Image_Filter, Blend_Mode, and so on; may be nullptr ##
Cary Clark8032b982017-07-28 11:04:54 -04005934
5935#Example
5936#Image 3
Cary Clarkbad5ad72017-08-03 17:14:08 -04005937void draw(SkCanvas* canvas) {
5938 // sk_sp<SkImage> image = mandrill;
5939 SkRSXform xforms[] = { { 1, 0, 0, 0 }, {0, 1, 300, 100 } };
5940 SkRect tex[] = { { 0, 0, 200, 200 }, { 200, 0, 400, 200 } };
5941 canvas->drawAtlas(image, xforms, tex, 2, nullptr, nullptr);
Cary Clark8032b982017-07-28 11:04:54 -04005942}
5943##
5944
Cary Clark2ade9972017-11-02 17:49:34 -04005945#SeeAlso drawBitmap drawImage
Cary Clark8032b982017-07-28 11:04:54 -04005946
5947##
5948
5949# ------------------------------------------------------------------------------
5950
Cary Clark73fa9722017-08-29 17:36:51 -04005951#Method void drawDrawable(SkDrawable* drawable, const SkMatrix* matrix = nullptr)
Cary Clark8032b982017-07-28 11:04:54 -04005952
5953Draw Drawable drawable using Clip and Matrix, concatenated with
5954optional matrix.
5955
5956If Canvas has an asynchronous implementation, as is the case
5957when it is recording into Picture, then drawable will be referenced,
5958so that SkDrawable::draw() can be called when the operation is finalized. To force
5959immediate drawing, call SkDrawable::draw() instead.
5960
Cary Clarkbad5ad72017-08-03 17:14:08 -04005961#Param drawable custom struct encapsulating drawing commands ##
5962#Param matrix transformation applied to drawing; may be nullptr ##
Cary Clark8032b982017-07-28 11:04:54 -04005963
5964#Example
5965#Height 100
5966#Function
Cary Clarkbad5ad72017-08-03 17:14:08 -04005967struct MyDrawable : public SkDrawable {
5968 SkRect onGetBounds() override { return SkRect::MakeWH(50, 100); }
5969
5970 void onDraw(SkCanvas* canvas) override {
5971 SkPath path;
5972 path.conicTo(10, 90, 50, 90, 0.9f);
5973 SkPaint paint;
5974 paint.setColor(SK_ColorBLUE);
5975 canvas->drawRect(path.getBounds(), paint);
5976 paint.setAntiAlias(true);
5977 paint.setColor(SK_ColorWHITE);
5978 canvas->drawPath(path, paint);
5979 }
5980};
5981
5982#Function ##
5983void draw(SkCanvas* canvas) {
5984 sk_sp<SkDrawable> drawable(new MyDrawable);
5985 SkMatrix matrix;
5986 matrix.setTranslate(10, 10);
5987 canvas->drawDrawable(drawable.get(), &matrix);
Cary Clark8032b982017-07-28 11:04:54 -04005988}
5989##
5990
Cary Clark2ade9972017-11-02 17:49:34 -04005991#SeeAlso SkDrawable drawPicture
Cary Clark8032b982017-07-28 11:04:54 -04005992
5993##
5994
5995# ------------------------------------------------------------------------------
5996
5997#Method void drawDrawable(SkDrawable* drawable, SkScalar x, SkScalar y)
5998
5999Draw Drawable drawable using Clip and Matrix, offset by (x, y).
6000
6001If Canvas has an asynchronous implementation, as is the case
6002when it is recording into Picture, then drawable will be referenced,
6003so that SkDrawable::draw() can be called when the operation is finalized. To force
6004immediate drawing, call SkDrawable::draw() instead.
6005
Cary Clarkbad5ad72017-08-03 17:14:08 -04006006#Param drawable custom struct encapsulating drawing commands ##
6007#Param x offset into Canvas writable pixels in x ##
6008#Param y offset into Canvas writable pixels in y ##
Cary Clark8032b982017-07-28 11:04:54 -04006009
6010#Example
6011#Height 100
6012#Function
Cary Clarkbad5ad72017-08-03 17:14:08 -04006013struct MyDrawable : public SkDrawable {
6014 SkRect onGetBounds() override { return SkRect::MakeWH(50, 100); }
6015
6016 void onDraw(SkCanvas* canvas) override {
6017 SkPath path;
6018 path.conicTo(10, 90, 50, 90, 0.9f);
6019 SkPaint paint;
6020 paint.setColor(SK_ColorBLUE);
6021 canvas->drawRect(path.getBounds(), paint);
6022 paint.setAntiAlias(true);
6023 paint.setColor(SK_ColorWHITE);
6024 canvas->drawPath(path, paint);
6025 }
6026};
6027
6028#Function ##
6029void draw(SkCanvas* canvas) {
6030 sk_sp<SkDrawable> drawable(new MyDrawable);
6031 canvas->drawDrawable(drawable.get(), 10, 10);
Cary Clark8032b982017-07-28 11:04:54 -04006032}
6033##
6034
Cary Clark2ade9972017-11-02 17:49:34 -04006035#SeeAlso SkDrawable drawPicture
Cary Clark8032b982017-07-28 11:04:54 -04006036
6037##
6038
6039# ------------------------------------------------------------------------------
6040
6041#Method void drawAnnotation(const SkRect& rect, const char key[], SkData* value)
6042
6043Associate Rect on Canvas when an annotation; a key-value pair, where the key is
6044a null-terminated utf8 string, and optional value is stored as Data.
6045
6046Only some canvas implementations, such as recording to Picture, or drawing to
6047Document_PDF, use annotations.
6048
Cary Clarkbad5ad72017-08-03 17:14:08 -04006049#Param rect Rect extent of canvas to annotate ##
6050#Param key string used for lookup ##
6051#Param value data holding value stored in annotation ##
Cary Clark8032b982017-07-28 11:04:54 -04006052
6053#Example
6054 #Height 1
6055 const char text[] = "Click this link!";
6056 SkRect bounds;
6057 SkPaint paint;
6058 paint.setTextSize(40);
6059 (void)paint.measureText(text, strlen(text), &bounds);
6060 const char url[] = "https://www.google.com/";
6061 sk_sp<SkData> urlData(SkData::MakeWithCString(url));
6062 canvas->drawAnnotation(bounds, "url_key", urlData.get());
6063##
6064
Cary Clark2ade9972017-11-02 17:49:34 -04006065#SeeAlso SkPicture SkDocument
Cary Clark8032b982017-07-28 11:04:54 -04006066
6067##
6068
6069# ------------------------------------------------------------------------------
6070
6071#Method void drawAnnotation(const SkRect& rect, const char key[], const sk_sp<SkData>& value)
6072
6073Associate Rect on Canvas when an annotation; a key-value pair, where the key is
6074a null-terminated utf8 string, and optional value is stored as Data.
6075
6076Only some canvas implementations, such as recording to Picture, or drawing to
6077Document_PDF, use annotations.
6078
Cary Clarkbad5ad72017-08-03 17:14:08 -04006079#Param rect Rect extent of canvas to annotate ##
6080#Param key string used for lookup ##
6081#Param value data holding value stored in annotation ##
Cary Clark8032b982017-07-28 11:04:54 -04006082
6083#Example
6084#Height 1
6085 const char text[] = "Click this link!";
6086 SkRect bounds;
6087 SkPaint paint;
6088 paint.setTextSize(40);
6089 (void)paint.measureText(text, strlen(text), &bounds);
6090 const char url[] = "https://www.google.com/";
6091 sk_sp<SkData> urlData(SkData::MakeWithCString(url));
6092 canvas->drawAnnotation(bounds, "url_key", urlData.get());
6093##
6094
Cary Clark2ade9972017-11-02 17:49:34 -04006095#SeeAlso SkPicture SkDocument
Cary Clark8032b982017-07-28 11:04:54 -04006096
6097##
6098
6099#Method SkDrawFilter* getDrawFilter() const
6100
6101Legacy call to be deprecated.
6102
6103#Deprecated
6104##
6105
6106##
6107
6108#Method virtual SkDrawFilter* setDrawFilter(SkDrawFilter* filter)
6109
6110Legacy call to be deprecated.
6111
6112#Deprecated
6113##
6114
6115##
6116
6117# ------------------------------------------------------------------------------
6118
6119#Method virtual bool isClipEmpty() const
6120
6121Returns true if Clip is empty; that is, nothing will draw.
6122
Cary Clarkbad5ad72017-08-03 17:14:08 -04006123May do work when called; it should not be called
Cary Clark8032b982017-07-28 11:04:54 -04006124more often than needed. However, once called, subsequent calls perform no
6125work until Clip changes.
6126
Cary Clarkbad5ad72017-08-03 17:14:08 -04006127#Return true if Clip is empty ##
Cary Clark8032b982017-07-28 11:04:54 -04006128
6129#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04006130 void draw(SkCanvas* canvas) {
6131 SkDebugf("clip is%s empty\n", canvas->isClipEmpty() ? "" : " not");
6132 SkPath path;
6133 canvas->clipPath(path);
6134 SkDebugf("clip is%s empty\n", canvas->isClipEmpty() ? "" : " not");
Cary Clark8032b982017-07-28 11:04:54 -04006135 }
6136 #StdOut
Cary Clarkbad5ad72017-08-03 17:14:08 -04006137 clip is not empty
Cary Clark8032b982017-07-28 11:04:54 -04006138 clip is empty
6139 ##
6140##
6141
Cary Clark2ade9972017-11-02 17:49:34 -04006142#SeeAlso isClipRect getLocalClipBounds getDeviceClipBounds
Cary Clark8032b982017-07-28 11:04:54 -04006143
6144##
6145
6146# ------------------------------------------------------------------------------
6147
6148#Method virtual bool isClipRect() const
6149
6150Returns true if Clip is Rect and not empty.
6151Returns false if the clip is empty, or if it is not Rect.
6152
Cary Clarkbad5ad72017-08-03 17:14:08 -04006153#Return true if Clip is Rect and not empty ##
Cary Clark8032b982017-07-28 11:04:54 -04006154
6155#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04006156 void draw(SkCanvas* canvas) {
6157 SkDebugf("clip is%s rect\n", canvas->isClipRect() ? "" : " not");
6158 canvas->clipRect({0, 0, 0, 0});
6159 SkDebugf("clip is%s rect\n", canvas->isClipRect() ? "" : " not");
Cary Clark8032b982017-07-28 11:04:54 -04006160 }
6161 #StdOut
Cary Clarkbad5ad72017-08-03 17:14:08 -04006162 clip is rect
Cary Clark8032b982017-07-28 11:04:54 -04006163 clip is not rect
6164 ##
6165##
6166
Cary Clark2ade9972017-11-02 17:49:34 -04006167#SeeAlso isClipEmpty getLocalClipBounds getDeviceClipBounds
Cary Clark8032b982017-07-28 11:04:54 -04006168
6169##
6170
6171#Class SkCanvas ##
Cary Clark884dd7d2017-10-11 10:37:52 -04006172
Cary Clark8032b982017-07-28 11:04:54 -04006173#Topic Canvas ##