blob: 4463ea6b3a26ad6ee419dd23f1364b44b87cb886 [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 ##
38# Operators # operator overloading methods ##
Cary Clark8032b982017-07-28 11:04:54 -040039#Table ##
40#Subtopic ##
41
42#Subtopic Constants
43#Table
44#Legend
Cary Clark5081eed2018-01-22 07:55:48 -050045# name # description ##
Cary Clark8032b982017-07-28 11:04:54 -040046#Legend ##
Cary Clark5081eed2018-01-22 07:55:48 -050047# Lattice::Flags # controls Lattice transparency ##
48# PointMode # sets drawPoints options ##
49# SaveLayerFlags # sets SaveLayerRec options ##
50# SrcRectConstraint # sets drawImageRect options ##
Cary Clark8032b982017-07-28 11:04:54 -040051#Table ##
52#Subtopic ##
53
Cary Clark5081eed2018-01-22 07:55:48 -050054#Subtopic Classes_and_Structs
Cary Clark8032b982017-07-28 11:04:54 -040055#Table
56#Legend
Cary Clark5081eed2018-01-22 07:55:48 -050057# name # description ##
Cary Clark8032b982017-07-28 11:04:54 -040058#Legend ##
Cary Clark5081eed2018-01-22 07:55:48 -050059# Lattice # divides Bitmap, Image into a rectangular grid ##
60# SaveLayerRec # contains state to create Layer ##
Cary Clark8032b982017-07-28 11:04:54 -040061#Table ##
62#Subtopic ##
63
64#Subtopic Constructors
65
66Create the desired type of Surface to obtain its Canvas when possible. Constructors are useful
67when no Surface is required, and some helpers implicitly create Raster_Surface.
68
69#Table
70#Legend
Cary Clark5081eed2018-01-22 07:55:48 -050071# name # description ##
Cary Clark8032b982017-07-28 11:04:54 -040072#Legend ##
Cary Clark5081eed2018-01-22 07:55:48 -050073# MakeRasterDirect # creates from SkImageInfo and Pixel_Storage ##
74# MakeRasterDirectN32 # creates from image data and Pixel_Storage ##
75# SkCanvas() # creates with no Surface, no dimensions ##
76# SkCanvas(SkBaseDevice* device) # to be deprecated ##
77# SkCanvas(const SkBitmap& bitmap) # uses existing Bitmap ##
78# SkCanvas(const SkBitmap& bitmap, ColorBehavior behavior) # Android framework only ##
79# SkCanvas(const SkBitmap& bitmap, const SkSurfaceProps& props) # uses existing Bitmap and Surface_Properties ##
80# SkCanvas(int width, int height, const SkSurfaceProps* props = nullptr) # no Surface, set dimensions, Surface_Properties ##
81# ~SkCanvas() # draws saved Layers, frees resources ##
Cary Clark8032b982017-07-28 11:04:54 -040082#Table ##
83#Subtopic ##
84
85#Subtopic Member_Functions
86#Table
87#Legend
Cary Clark5081eed2018-01-22 07:55:48 -050088# name # description ##
Cary Clark8032b982017-07-28 11:04:54 -040089#Legend ##
Cary Clark5081eed2018-01-22 07:55:48 -050090# MakeRasterDirect # creates Canvas from SkImageInfo and pixel data ##
91# MakeRasterDirectN32 # creates Canvas from image specifications and pixel data ##
92# accessTopLayerPixels # returns writable pixel access if available ##
93# accessTopRasterHandle # returns context that tracks Clip and Matrix ##
94# clear() # fills Clip with Color ##
95# clipPath # combines Clip with Path ##
96# clipRRect # combines Clip with Round_Rect ##
97# clipRect # combines Clip with Rect ##
98# clipRegion # combines Clip with Region ##
99# concat() # multiplies Matrix by Matrix ##
100# discard() # makes Canvas contents undefined ##
101# drawAnnotation # associates a Rect with a key-value pair ##
102# drawArc # draws Arc using Clip, Matrix, and Paint ##
103# drawAtlas # draws sprites using Clip, Matrix, and Paint ##
104# drawBitmap # draws Bitmap at (x, y) position ##
105# drawBitmapLattice # draws proportionally stretched Bitmap ##
106# drawBitmapNine # draws Nine_Patch Bitmap ##
107# drawBitmapRect # draws Bitmap, source Rect to destination Rect ##
108# drawCircle # draws Circle using Clip, Matrix, and Paint ##
109# drawColor # fills Clip with Color and Blend_Mode ##
110# drawDRRect # draws double Round_Rect stroked or filled ##
111# drawDrawable # draws Drawable, encapsulated drawing commands ##
112# drawIRect # draws IRect using Clip, Matrix, and Paint ##
113# drawImage # draws Image at (x, y) position ##
114# drawImageLattice # draws proportionally stretched Image ##
115# drawImageNine # draws Nine_Patch Image ##
116# drawImageRect # draws Image, source Rect to destination Rect ##
117# drawLine # draws line segment between two points ##
118# drawOval # draws Oval using Clip, Matrix, and Paint ##
119# drawPaint # fills Clip with Paint ##
120# drawPatch # draws Coons_Patch ##
121# drawPath # draws Path using Clip, Matrix, and Paint ##
122# drawPicture # draws Picture using Clip and Matrix ##
123# drawPoint # draws point at (x, y) position ##
124# drawPoints # draws array as points, lines, polygon ##
125# drawPosText # draws text at array of (x, y) positions ##
126# drawPosTextH # draws text at x positions with common baseline ##
127# drawRRect # draws Round_Rect using Clip, Matrix, and Paint ##
128# drawRect # draws Rect using Clip, Matrix, and Paint ##
129# drawRegion # draws Region using Clip, Matrix, and Paint ##
130# drawRoundRect # draws Round_Rect using Clip, Matrix, and Paint ##
131# drawString # draws null terminated string at (x, y) using font advance ##
132# drawText # draws text at (x, y), using font advance ##
133# drawTextBlob # draws text with arrays of positions and Paint ##
134# drawTextOnPath # draws text following Path contour ##
135# drawTextOnPathHV # draws text following Path with offsets ##
136# drawTextRSXform # draws text with array of RSXform ##
137# drawVertices # draws Vertices, a triangle mesh ##
138# flush() # triggers execution of all pending draw operations ##
139# getBaseLayerSize # returns size of base Layer in global coordinates ##
140# getDeviceClipBounds # returns IRect bounds of Clip ##
141# getDrawFilter # legacy; to be deprecated ##
142# getGrContext # returns GPU_Context of the GPU_Surface ##
143# getLocalClipBounds # returns Clip bounds in source coordinates ##
144# getMetaData # associates additional data with the canvas ##
145# getProps # copies Surface_Properties if available ##
146# getSaveCount # returns depth of stack containing Clip and Matrix ##
147# getTotalMatrix # returns Matrix ##
148# imageInfo # returns Image_Info for Canvas ##
149# isClipEmpty # returns if Clip is empty ##
150# isClipRect # returns if Clip is Rect and not empty ##
151# makeSurface # creates Surface matching SkImageInfo and SkSurfaceProps ##
152# peekPixels # returns if Canvas has direct access to its pixels ##
153# quickReject # returns if Rect is outside Clip ##
154# readPixels # copies and converts rectangle of pixels from Canvas ##
155# resetMatrix # resets Matrix to identity ##
156# restore() # restores changes to Clip and Matrix, pops save stack ##
157# restoreToCount # restores changes to Clip and Matrix to given depth ##
158# rotate() # rotates Matrix ##
159# save() # saves Clip and Matrix on stack ##
160# saveLayer # saves Clip and Matrix on stack; creates Layer ##
161# saveLayerAlpha # saves Clip and Matrix on stack; creates Layer; sets opacity ##
162# saveLayerPreserveLCDTextRequests # saves Clip and Matrix on stack; creates Layer for LCD text ##
163# scale() # scales Matrix ##
164# setAllowSimplifyClip # experimental ##
165# setDrawFilter # legacy; to be deprecated ##
166# setMatrix # sets Matrix ##
167# skew() # skews Matrix. #
168# translate() # translates Matrix ##
169# writePixels # copies and converts rectangle of pixels to Canvas ##
Cary Clark8032b982017-07-28 11:04:54 -0400170#Table ##
171#Subtopic ##
172
173#Topic Overview ##
174
175# ------------------------------------------------------------------------------
176
Cary Clarka560c472017-11-27 10:44:06 -0500177#Method static std::unique_ptr<SkCanvas> MakeRasterDirect(const SkImageInfo& info, void* pixels,
178 size_t rowBytes,
179 const SkSurfaceProps* props = nullptr)
Cary Clark8032b982017-07-28 11:04:54 -0400180
Cary Clarkbad5ad72017-08-03 17:14:08 -0400181Allocates raster Canvas that will draw directly into pixels.
Cary Clark8032b982017-07-28 11:04:54 -0400182
Cary Clarkbad5ad72017-08-03 17:14:08 -0400183Canvas is returned if all parameters are valid.
184Valid parameters include:
185info dimensions are zero or positive;
186info contains Image_Color_Type and Image_Alpha_Type supported by Raster_Surface;
187pixels is not nullptr;
188rowBytes is zero or large enough to contain info width pixels of Image_Color_Type.
189
Cary Clarkf05bdda2017-08-24 12:59:48 -0400190Pass zero for rowBytes to compute rowBytes from info width and size of pixel.
191If rowBytes is greater than zero, it must be equal to or greater than
192info width times bytes required for Image_Color_Type.
193
194Pixel buffer size should be info height times computed rowBytes.
Cary Clarka560c472017-11-27 10:44:06 -0500195Pixels are not initialized.
196To access pixels after drawing, call flush() or peekPixels.
Cary Clarkbad5ad72017-08-03 17:14:08 -0400197
198#Param info width, height, Image_Color_Type, Image_Alpha_Type, Color_Space, of Raster_Surface;
199 width, or height, or both, may be zero
Cary Clark8032b982017-07-28 11:04:54 -0400200##
Cary Clarkf05bdda2017-08-24 12:59:48 -0400201#Param pixels pointer to destination pixels buffer
Cary Clark8032b982017-07-28 11:04:54 -0400202##
Cary Clarkf05bdda2017-08-24 12:59:48 -0400203#Param rowBytes interval from one Surface row to the next, or zero
Cary Clark8032b982017-07-28 11:04:54 -0400204##
Cary Clarka560c472017-11-27 10:44:06 -0500205#Param props LCD striping orientation and setting for device independent fonts;
206 may be nullptr
207##
Cary Clark8032b982017-07-28 11:04:54 -0400208
Cary Clarkbad5ad72017-08-03 17:14:08 -0400209#Return Canvas if all parameters are valid; otherwise, nullptr ##
Cary Clark8032b982017-07-28 11:04:54 -0400210
211#Example
212 #Description
213 Allocates a three by three bitmap, clears it to white, and draws a black pixel
214 in the center.
215 ##
Cary Clarkbad5ad72017-08-03 17:14:08 -0400216void draw(SkCanvas* ) {
Cary Clarkce101242017-09-01 15:51:02 -0400217 SkImageInfo info = SkImageInfo::MakeN32Premul(3, 3); // device aligned, 32 bpp, Premultiplied
Cary Clarkbad5ad72017-08-03 17:14:08 -0400218 const size_t minRowBytes = info.minRowBytes(); // bytes used by one bitmap row
Cary Clarka560c472017-11-27 10:44:06 -0500219 const size_t size = info.computeMinByteSize(); // bytes used by all rows
Cary Clarkbad5ad72017-08-03 17:14:08 -0400220 SkAutoTMalloc<SkPMColor> storage(size); // allocate storage for pixels
221 SkPMColor* pixels = storage.get(); // get pointer to allocated storage
222 // create a SkCanvas backed by a raster device, and delete it when the
223 // function goes out of scope.
224 std::unique_ptr<SkCanvas> canvas = SkCanvas::MakeRasterDirect(info, pixels, minRowBytes);
Cary Clarkce101242017-09-01 15:51:02 -0400225 canvas->clear(SK_ColorWHITE); // white is Unpremultiplied, in ARGB order
Cary Clarkbad5ad72017-08-03 17:14:08 -0400226 canvas->flush(); // ensure that pixels are cleared
Cary Clarkce101242017-09-01 15:51:02 -0400227 SkPMColor pmWhite = pixels[0]; // the Premultiplied format may vary
Cary Clarkbad5ad72017-08-03 17:14:08 -0400228 SkPaint paint; // by default, draws black
229 canvas->drawPoint(1, 1, paint); // draw in the center
230 canvas->flush(); // ensure that point was drawn
231 for (int y = 0; y < info.height(); ++y) {
232 for (int x = 0; x < info.width(); ++x) {
233 SkDebugf("%c", *pixels++ == pmWhite ? '-' : 'x');
234 }
235 SkDebugf("\n");
236 }
Cary Clark8032b982017-07-28 11:04:54 -0400237}
238 #StdOut
239 ---
240 -x-
241 ---
242 ##
243##
244
Cary Clark8032b982017-07-28 11:04:54 -0400245#SeeAlso MakeRasterDirectN32 SkSurface::MakeRasterDirect
Cary Clark2ade9972017-11-02 17:49:34 -0400246
Cary Clark8032b982017-07-28 11:04:54 -0400247##
248
249# ------------------------------------------------------------------------------
250
251#Method static std::unique_ptr<SkCanvas> MakeRasterDirectN32(int width, int height, SkPMColor* pixels,
252 size_t rowBytes)
253
Cary Clarkbad5ad72017-08-03 17:14:08 -0400254Allocates raster Canvas specified by inline image specification. Subsequent Canvas
255calls draw into pixels.
Cary Clark8032b982017-07-28 11:04:54 -0400256Image_Color_Type is set to kN32_SkColorType.
257Image_Alpha_Type is set to kPremul_SkAlphaType.
258To access pixels after drawing, call flush() or peekPixels.
259
Cary Clarkbad5ad72017-08-03 17:14:08 -0400260Canvas is returned if all parameters are valid.
261Valid parameters include:
Cary Clarkf05bdda2017-08-24 12:59:48 -0400262width and height are zero or positive;
Cary Clarkbad5ad72017-08-03 17:14:08 -0400263pixels is not nullptr;
Cary Clarkf05bdda2017-08-24 12:59:48 -0400264rowBytes is zero or large enough to contain width pixels of kN32_SkColorType.
Cary Clarkbad5ad72017-08-03 17:14:08 -0400265
Cary Clarkce101242017-09-01 15:51:02 -0400266Pass zero for rowBytes to compute rowBytes from width and size of pixel.
Cary Clarkf05bdda2017-08-24 12:59:48 -0400267If rowBytes is greater than zero, it must be equal to or greater than
268width times bytes required for Image_Color_Type.
269
270Pixel buffer size should be height times rowBytes.
Cary Clarkbad5ad72017-08-03 17:14:08 -0400271
272#Param width pixel column count on Raster_Surface created; must be zero or greater ##
Cary Clarkbc5697d2017-10-04 14:31:33 -0400273#Param height pixel row count on Raster_Surface created; must be zero or greater ##
Cary Clarkbad5ad72017-08-03 17:14:08 -0400274#Param pixels pointer to destination pixels buffer; buffer size should be height
Cary Clarkf05bdda2017-08-24 12:59:48 -0400275 times rowBytes
Cary Clark8032b982017-07-28 11:04:54 -0400276##
Cary Clarkf05bdda2017-08-24 12:59:48 -0400277#Param rowBytes interval from one Surface row to the next, or zero
Cary Clark8032b982017-07-28 11:04:54 -0400278##
279
Cary Clarkbad5ad72017-08-03 17:14:08 -0400280#Return Canvas if all parameters are valid; otherwise, nullptr ##
Cary Clark8032b982017-07-28 11:04:54 -0400281
282#Example
283 #Description
284 Allocates a three by three bitmap, clears it to white, and draws a black pixel
285 in the center.
286 ##
287void draw(SkCanvas* ) {
288 const int width = 3;
289 const int height = 3;
Cary Clarkce101242017-09-01 15:51:02 -0400290 SkPMColor pixels[height][width]; // allocate a 3x3 Premultiplied bitmap on the stack
Cary Clark8032b982017-07-28 11:04:54 -0400291 // create a SkCanvas backed by a raster device, and delete it when the
292 // function goes out of scope.
293 std::unique_ptr<SkCanvas> canvas = SkCanvas::MakeRasterDirectN32(
294 width,
295 height,
Cary Clarkbc5697d2017-10-04 14:31:33 -0400296 pixels[0], // top-left of the bitmap
Cary Clark8032b982017-07-28 11:04:54 -0400297 sizeof(pixels[0])); // byte width of the each row
Cary Clarkce101242017-09-01 15:51:02 -0400298 // write a premultiplied value for white into all pixels in the bitmap
Cary Clark8032b982017-07-28 11:04:54 -0400299 canvas->clear(SK_ColorWHITE);
Cary Clarkce101242017-09-01 15:51:02 -0400300 SkPMColor pmWhite = pixels[0][0]; // the Premultiplied format may vary
Cary Clark8032b982017-07-28 11:04:54 -0400301 SkPaint paint; // by default, draws black
302 canvas->drawPoint(1, 1, paint); // draw in the center
303 canvas->flush(); // ensure that pixels is ready to be read
304 for (int y = 0; y < height; ++y) {
305 for (int x = 0; x < width; ++x) {
306 SkDebugf("%c", pixels[y][x] == pmWhite ? '-' : 'x');
307 }
308 SkDebugf("\n");
309 }
310}
311 #StdOut
312 ---
313 -x-
314 ---
315 ##
316##
317
Cary Clark2ade9972017-11-02 17:49:34 -0400318#SeeAlso MakeRasterDirect SkSurface::MakeRasterDirect SkImageInfo::MakeN32Premul
Cary Clark8032b982017-07-28 11:04:54 -0400319
320##
321
322# ------------------------------------------------------------------------------
323
324#Method SkCanvas()
325
Cary Clarkd0530ba2017-09-14 11:25:39 -0400326Creates an empty Canvas with no backing device or pixels, with
Cary Clarkf05bdda2017-08-24 12:59:48 -0400327a width and height of zero.
Cary Clark8032b982017-07-28 11:04:54 -0400328
Cary Clarkd0530ba2017-09-14 11:25:39 -0400329#Return empty Canvas ##
Cary Clark8032b982017-07-28 11:04:54 -0400330
331#Example
332
333#Description
334Passes a placeholder to a function that requires one.
335##
336
337#Function
Cary Clarkbad5ad72017-08-03 17:14:08 -0400338// Returns true if either the canvas rotates the text by 90 degrees, or the paint does.
339static void check_for_up_and_down_text(const SkCanvas* canvas, const SkPaint& paint) {
340 bool paintHasVertical = paint.isVerticalText();
341 const SkMatrix& matrix = canvas->getTotalMatrix();
342 bool matrixIsVertical = matrix.preservesRightAngles() && !matrix.isScaleTranslate();
343 SkDebugf("paint draws text %s\n", paintHasVertical != matrixIsVertical ?
344 "top to bottom" : "left to right");
345}
346
347static void check_for_up_and_down_text(const SkPaint& paint) {
348 SkCanvas canvas; // placeholder only, does not have an associated device
349 check_for_up_and_down_text(&canvas, paint);
350}
351
Cary Clark8032b982017-07-28 11:04:54 -0400352##
Cary Clarkbad5ad72017-08-03 17:14:08 -0400353void draw(SkCanvas* canvas) {
354 SkPaint paint;
355 check_for_up_and_down_text(paint); // paint draws text left to right
356 paint.setVerticalText(true);
357 check_for_up_and_down_text(paint); // paint draws text top to bottom
358 paint.setVerticalText(false);
359 canvas->rotate(90);
360 check_for_up_and_down_text(canvas, paint); // paint draws text top to bottom
361}
Cary Clark8032b982017-07-28 11:04:54 -0400362
363 #StdOut
364 paint draws text left to right
365 paint draws text top to bottom
366 paint draws text top to bottom
367 ##
368##
369
Cary Clark2ade9972017-11-02 17:49:34 -0400370#SeeAlso MakeRasterDirect SkRasterHandleAllocator::MakeCanvas SkSurface::getCanvas SkCreateColorSpaceXformCanvas
Cary Clark8032b982017-07-28 11:04:54 -0400371
372##
373
374# ------------------------------------------------------------------------------
375
Cary Clark73fa9722017-08-29 17:36:51 -0400376#Method SkCanvas(int width, int height, const SkSurfaceProps* props = nullptr)
Cary Clark8032b982017-07-28 11:04:54 -0400377
378Creates Canvas of the specified dimensions without a Surface.
Cary Clarkce101242017-09-01 15:51:02 -0400379Used by Subclasses with custom implementations for draw methods.
Cary Clark8032b982017-07-28 11:04:54 -0400380
Cary Clarkd0530ba2017-09-14 11:25:39 -0400381If props equals nullptr, Surface_Properties are created with
382Surface_Properties_Legacy_Font_Host settings, which choose the pixel striping
383direction and order. Since a platform may dynamically change its direction when
384the device is rotated, and since a platform may have multiple monitors with
385different characteristics, it is best not to rely on this legacy behavior.
Cary Clark8032b982017-07-28 11:04:54 -0400386
Cary Clarkbad5ad72017-08-03 17:14:08 -0400387#Param width zero or greater ##
388#Param height zero or greater ##
389#Param props LCD striping orientation and setting for device independent fonts;
390 may be nullptr
391##
392
393#Return Canvas placeholder with dimensions ##
Cary Clark8032b982017-07-28 11:04:54 -0400394
395#Example
396 SkCanvas canvas(10, 20); // 10 units wide, 20 units high
397 canvas.clipRect(SkRect::MakeXYWH(30, 40, 5, 10)); // clip is outside canvas' device
398 SkDebugf("canvas %s empty\n", canvas.getDeviceClipBounds().isEmpty() ? "is" : "is not");
399
400 #StdOut
401 canvas is empty
402 ##
403##
404
Cary Clark2ade9972017-11-02 17:49:34 -0400405#SeeAlso MakeRasterDirect SkSurfaceProps SkPixelGeometry SkCreateColorSpaceXformCanvas
Cary Clark8032b982017-07-28 11:04:54 -0400406
407##
408
409# ------------------------------------------------------------------------------
410
411#Method explicit SkCanvas(SkBaseDevice* device)
412
413Construct a canvas that draws into device.
414Used by child classes of SkCanvas.
415
416#ToDo Since SkBaseDevice is private, shouldn't this be private also? ##
417
Cary Clarkbad5ad72017-08-03 17:14:08 -0400418#Param device specifies a device for the canvas to draw into ##
Cary Clark8032b982017-07-28 11:04:54 -0400419
Cary Clarkbad5ad72017-08-03 17:14:08 -0400420#Return Canvas that can be used to draw into device ##
Cary Clark8032b982017-07-28 11:04:54 -0400421
422#Example
423#Error "Unsure how to create a meaningful example."
424 SkPDFCanvas::SkPDFCanvas(const sk_sp<SkPDFDevice>& dev)
425 : SkCanvas(dev.get()) {}
426##
427
Cary Clark2ade9972017-11-02 17:49:34 -0400428#ToDo either remove doc or figure out a way to fiddle it ##
429
430#SeeAlso MakeRasterDirect SkRasterHandleAllocator::MakeCanvas SkSurface::getCanvas SkCreateColorSpaceXformCanvas
Cary Clark8032b982017-07-28 11:04:54 -0400431
432##
433
434# ------------------------------------------------------------------------------
435
436#Method explicit SkCanvas(const SkBitmap& bitmap)
437
438Construct a canvas that draws into bitmap.
439Sets SkSurfaceProps::kLegacyFontHost_InitType in constructed Surface.
440
Cary Clarkbad5ad72017-08-03 17:14:08 -0400441Bitmap is copied so that subsequently editing bitmap will not affect
442constructed Canvas.
443
444May be deprecated in the future.
445
Cary Clark8032b982017-07-28 11:04:54 -0400446#ToDo Should be deprecated? ##
447
Cary Clarkbad5ad72017-08-03 17:14:08 -0400448#Param bitmap width, height, Image_Color_Type, Image_Alpha_Type, and pixel
449 storage of Raster_Surface
Cary Clark8032b982017-07-28 11:04:54 -0400450##
451
Cary Clarkbad5ad72017-08-03 17:14:08 -0400452#Return Canvas that can be used to draw into bitmap ##
Cary Clark8032b982017-07-28 11:04:54 -0400453
454#Example
455#Description
456The actual output depends on the installed fonts.
457##
458 SkBitmap bitmap;
459 // create a bitmap 5 wide and 11 high
460 bitmap.allocPixels(SkImageInfo::MakeN32Premul(5, 11));
461 SkCanvas canvas(bitmap);
Cary Clarkce101242017-09-01 15:51:02 -0400462 canvas.clear(SK_ColorWHITE); // white is Unpremultiplied, in ARGB order
Cary Clark8032b982017-07-28 11:04:54 -0400463 SkPixmap pixmap; // provides guaranteed access to the drawn pixels
464 if (!canvas.peekPixels(&pixmap)) {
465 SkDebugf("peekPixels should never fail.\n");
466 }
Cary Clarkbc5697d2017-10-04 14:31:33 -0400467 const SkPMColor* pixels = pixmap.addr32(); // points to top-left of bitmap
Cary Clarkce101242017-09-01 15:51:02 -0400468 SkPMColor pmWhite = pixels[0]; // the Premultiplied format may vary
Cary Clark8032b982017-07-28 11:04:54 -0400469 SkPaint paint; // by default, draws black, 12 point text
470 canvas.drawString("!", 1, 10, paint); // 1 char at baseline (1, 10)
471 for (int y = 0; y < bitmap.height(); ++y) {
472 for (int x = 0; x < bitmap.width(); ++x) {
473 SkDebugf("%c", *pixels++ == pmWhite ? '-' : 'x');
474 }
475 SkDebugf("\n");
476 }
477
478 #StdOut
Cary Clarkd0530ba2017-09-14 11:25:39 -0400479 -----
480 ---x-
481 ---x-
482 ---x-
483 ---x-
484 ---x-
485 ---x-
486 -----
487 ---x-
488 ---x-
Cary Clark8032b982017-07-28 11:04:54 -0400489 -----
490 #StdOut ##
491##
492
Cary Clark2ade9972017-11-02 17:49:34 -0400493#SeeAlso MakeRasterDirect SkRasterHandleAllocator::MakeCanvas SkSurface::getCanvas SkCreateColorSpaceXformCanvas
Cary Clark8032b982017-07-28 11:04:54 -0400494
495##
496
Cary Clarkbad5ad72017-08-03 17:14:08 -0400497#EnumClass ColorBehavior
Cary Clark8032b982017-07-28 11:04:54 -0400498
499#Private
500Android framework only.
501##
502
503#Code
504 enum class ColorBehavior {
505 kLegacy,
506 };
507##
508#Const kLegacy 0
Cary Clarkbad5ad72017-08-03 17:14:08 -0400509 Is a placeholder to allow specialized constructor; has no meaning.
Cary Clark8032b982017-07-28 11:04:54 -0400510##
511##
512
Cary Clarkbad5ad72017-08-03 17:14:08 -0400513#Method SkCanvas(const SkBitmap& bitmap, ColorBehavior behavior)
514
515#Private
516Android framework only.
517##
518
519#Param bitmap specifies a bitmap for the canvas to draw into ##
520#Param behavior specializes this constructor; value is unused ##
521#Return Canvas that can be used to draw into bitmap ##
522
523#NoExample
524##
525##
Cary Clark8032b982017-07-28 11:04:54 -0400526
527# ------------------------------------------------------------------------------
528
529#Method SkCanvas(const SkBitmap& bitmap, const SkSurfaceProps& props)
530
531Construct a canvas that draws into bitmap.
532Use props to match the device characteristics, like LCD striping.
533
Cary Clarkbad5ad72017-08-03 17:14:08 -0400534bitmap is copied so that subsequently editing bitmap will not affect
535constructed Canvas.
536
537#Param bitmap width, height, Image_Color_Type, Image_Alpha_Type,
538 and pixel storage of Raster_Surface
Cary Clark8032b982017-07-28 11:04:54 -0400539##
Cary Clarkbad5ad72017-08-03 17:14:08 -0400540#Param props order and orientation of RGB striping; and whether to use
541 device independent fonts
Cary Clark8032b982017-07-28 11:04:54 -0400542##
543
Cary Clarkbad5ad72017-08-03 17:14:08 -0400544#Return Canvas that can be used to draw into bitmap ##
Cary Clark8032b982017-07-28 11:04:54 -0400545
546#Example
547#Description
548The actual output depends on the installed fonts.
549##
550 SkBitmap bitmap;
551 // create a bitmap 5 wide and 11 high
552 bitmap.allocPixels(SkImageInfo::MakeN32Premul(5, 11));
553 SkCanvas canvas(bitmap, SkSurfaceProps(0, kUnknown_SkPixelGeometry));
Cary Clarkce101242017-09-01 15:51:02 -0400554 canvas.clear(SK_ColorWHITE); // white is Unpremultiplied, in ARGB order
Cary Clark8032b982017-07-28 11:04:54 -0400555 SkPixmap pixmap; // provides guaranteed access to the drawn pixels
556 if (!canvas.peekPixels(&pixmap)) {
557 SkDebugf("peekPixels should never fail.\n");
558 }
Cary Clarkbc5697d2017-10-04 14:31:33 -0400559 const SkPMColor* pixels = pixmap.addr32(); // points to top-left of bitmap
Cary Clarkce101242017-09-01 15:51:02 -0400560 SkPMColor pmWhite = pixels[0]; // the Premultiplied format may vary
Cary Clark8032b982017-07-28 11:04:54 -0400561 SkPaint paint; // by default, draws black, 12 point text
562 canvas.drawString("!", 1, 10, paint); // 1 char at baseline (1, 10)
563 for (int y = 0; y < bitmap.height(); ++y) {
564 for (int x = 0; x < bitmap.width(); ++x) {
565 SkDebugf("%c", *pixels++ == pmWhite ? '-' : 'x');
566 }
567 SkDebugf("\n");
568 }
569
570 #StdOut
571 -----
572 ---x-
573 ---x-
574 ---x-
575 ---x-
576 ---x-
577 ---x-
578 -----
579 ---x-
580 ---x-
581 -----
582 #StdOut ##
583##
584
Cary Clark2ade9972017-11-02 17:49:34 -0400585#SeeAlso MakeRasterDirect SkRasterHandleAllocator::MakeCanvas SkSurface::getCanvas SkCreateColorSpaceXformCanvas
Cary Clark8032b982017-07-28 11:04:54 -0400586
587##
588
589# ------------------------------------------------------------------------------
590
591#Method virtual ~SkCanvas()
592
Cary Clark5081eed2018-01-22 07:55:48 -0500593Draws saved Layers, if any.
594Frees up resources used by Canvas.
Cary Clark8032b982017-07-28 11:04:54 -0400595
596#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -0400597#Description
Cary Clarkce101242017-09-01 15:51:02 -0400598Canvas Layer draws into bitmap. saveLayerAlpha sets up an additional
599drawing surface that blends with the bitmap. When Layer goes out of
600scope, Layer Destructor is called. The saved Layer is restored, drawing
Cary Clarkbad5ad72017-08-03 17:14:08 -0400601transparent letters.
602##
Cary Clarkf05bdda2017-08-24 12:59:48 -0400603void draw(SkCanvas* canvas) {
604 SkBitmap bitmap;
605 bitmap.allocPixels(SkImageInfo::MakeN32Premul(200, 200));
606 {
607 SkCanvas offscreen(bitmap);
608 SkPaint paint;
609 paint.setTextSize(100);
610 offscreen.drawString("ABC", 20, 160, paint);
611 SkRect layerBounds = SkRect::MakeXYWH(32, 32, 192, 192);
612 offscreen.saveLayerAlpha(&layerBounds, 128);
613 offscreen.clear(SK_ColorWHITE);
614 offscreen.drawString("DEF", 20, 160, paint);
615 }
616 canvas->drawBitmap(bitmap, 0, 0, nullptr);
Cary Clarkbad5ad72017-08-03 17:14:08 -0400617}
Cary Clark8032b982017-07-28 11:04:54 -0400618##
619
Cary Clarkbad5ad72017-08-03 17:14:08 -0400620#SeeAlso State_Stack
Cary Clark8032b982017-07-28 11:04:54 -0400621
622##
623
624# ------------------------------------------------------------------------------
625
626#Method SkMetaData& getMetaData()
627
Cary Clarkf05bdda2017-08-24 12:59:48 -0400628Returns storage to associate additional data with the canvas.
Cary Clark8032b982017-07-28 11:04:54 -0400629The storage is freed when Canvas is deleted.
630
Cary Clarkbad5ad72017-08-03 17:14:08 -0400631#Return storage that can be read from and written to ##
Cary Clark8032b982017-07-28 11:04:54 -0400632
633#Example
634 const char* kHelloMetaData = "HelloMetaData";
635 SkCanvas canvas;
636 SkMetaData& metaData = canvas.getMetaData();
637 SkDebugf("before: %s\n", metaData.findString(kHelloMetaData));
638 metaData.setString(kHelloMetaData, "Hello!");
639 SkDebugf("during: %s\n", metaData.findString(kHelloMetaData));
640 metaData.removeString(kHelloMetaData);
641 SkDebugf("after: %s\n", metaData.findString(kHelloMetaData));
642
643 #StdOut
644 before: (null)
645 during: Hello!
646 after: (null)
647 #StdOut ##
648##
649
Cary Clark2ade9972017-11-02 17:49:34 -0400650#SeeAlso SkMetaData
Cary Clark8032b982017-07-28 11:04:54 -0400651
652##
653
654# ------------------------------------------------------------------------------
655
656#Method SkImageInfo imageInfo() const
657
658Returns Image_Info for Canvas. If Canvas is not associated with Raster_Surface or
Cary Clarkbad5ad72017-08-03 17:14:08 -0400659GPU_Surface, returned Image_Color_Type is set to kUnknown_SkColorType.
Cary Clark8032b982017-07-28 11:04:54 -0400660
Cary Clarkbad5ad72017-08-03 17:14:08 -0400661#Return dimensions and Image_Color_Type of Canvas ##
Cary Clark8032b982017-07-28 11:04:54 -0400662
663#Example
Cary Clarkf05bdda2017-08-24 12:59:48 -0400664 SkCanvas emptyCanvas;
665 SkImageInfo canvasInfo = emptyCanvas.imageInfo();
666 SkImageInfo emptyInfo;
667 SkDebugf("emptyInfo %c= canvasInfo\n", emptyInfo == canvasInfo ? '=' : '!');
668
669 #StdOut
670 emptyInfo == canvasInfo
671 ##
Cary Clark8032b982017-07-28 11:04:54 -0400672##
673
Cary Clark2ade9972017-11-02 17:49:34 -0400674#SeeAlso SkImageInfo MakeRasterDirect makeSurface
Cary Clark8032b982017-07-28 11:04:54 -0400675
676##
677
678# ------------------------------------------------------------------------------
679
680#Method bool getProps(SkSurfaceProps* props) const
681
682If Canvas is associated with Raster_Surface or
683GPU_Surface, copies Surface_Properties and returns true. Otherwise,
684return false and leave props unchanged.
685
Cary Clarkbad5ad72017-08-03 17:14:08 -0400686#Param props storage for writable SkSurfaceProps ##
Cary Clark8032b982017-07-28 11:04:54 -0400687
Cary Clarkbad5ad72017-08-03 17:14:08 -0400688#Return true if Surface_Properties was copied ##
Cary Clark8032b982017-07-28 11:04:54 -0400689
690#ToDo This seems old style. Deprecate? ##
691
692#Example
693 SkBitmap bitmap;
694 SkCanvas canvas(bitmap, SkSurfaceProps(0, kRGB_V_SkPixelGeometry));
695 SkSurfaceProps surfaceProps(0, kUnknown_SkPixelGeometry);
696 SkDebugf("isRGB:%d\n", SkPixelGeometryIsRGB(surfaceProps.pixelGeometry()));
697 if (!canvas.getProps(&surfaceProps)) {
698 SkDebugf("getProps failed unexpectedly.\n");
699 }
700 SkDebugf("isRGB:%d\n", SkPixelGeometryIsRGB(surfaceProps.pixelGeometry()));
701
702 #StdOut
703 isRGB:0
704 isRGB:1
705 #StdOut ##
706##
707
Cary Clark2ade9972017-11-02 17:49:34 -0400708#SeeAlso SkSurfaceProps makeSurface
Cary Clark8032b982017-07-28 11:04:54 -0400709
710##
711
712# ------------------------------------------------------------------------------
713
714#Method void flush()
715
716Triggers the immediate execution of all pending draw operations.
Cary Clarkbad5ad72017-08-03 17:14:08 -0400717If Canvas is associated with GPU_Surface, resolves all pending GPU operations.
Cary Clark2ade9972017-11-02 17:49:34 -0400718If Canvas is associated with Raster_Surface, has no effect; raster draw
719operations are never deferred.
720
721#ToDo
722In an overview section on managing the GPU, include:
723- flush should never change what is drawn
724- call to kick off gpu work
725- calling too much impacts performance
726- some calls (peekPixels, prepareForExternalIO) call it internally
727- canvas call is local, GrContext::flush is global
728- diffentiate between flush, flushAndSignalSemaphores
729- normally never needs to be called
730- call it when sharing gpu resources, feeling memory pressure, swapping out app, and before
731 abandoning context
732- also call to say "I'm finished drawing here", e.g., when drawing to a GPU-backed offscreen surface
733 (created with SkSurface::MakeRenderTarget)
734
735for posterity: this doesn't show a difference: fiddle.skia.org/c/@flushfail
736##
Cary Clark8032b982017-07-28 11:04:54 -0400737
738#Example
739#Error "haven't thought of a useful example to put here"
740##
741
Cary Clark2ade9972017-11-02 17:49:34 -0400742#SeeAlso peekPixels SkSurface::flush() GrContext::flush() SkSurface::prepareForExternalIO GrContext::abandonContext()
Cary Clark8032b982017-07-28 11:04:54 -0400743
744##
745
746# ------------------------------------------------------------------------------
747
748#Method virtual SkISize getBaseLayerSize() const
749
Cary Clarkce101242017-09-01 15:51:02 -0400750Gets the size of the base or root Layer in global canvas coordinates. The
751origin of the base Layer is always (0,0). The area available for drawing may be
Cary Clark8032b982017-07-28 11:04:54 -0400752smaller (due to clipping or saveLayer).
753
Cary Clarkce101242017-09-01 15:51:02 -0400754#Return integral width and height of base Layer ##
Cary Clark8032b982017-07-28 11:04:54 -0400755
756#Example
757 SkBitmap bitmap;
758 bitmap.allocPixels(SkImageInfo::MakeN32Premul(20, 30));
759 SkCanvas canvas(bitmap, SkSurfaceProps(0, kUnknown_SkPixelGeometry));
760 canvas.clipRect(SkRect::MakeWH(10, 40));
761 SkIRect clipDeviceBounds = canvas.getDeviceClipBounds();
762 if (clipDeviceBounds.isEmpty()) {
763 SkDebugf("Empty clip bounds is unexpected!\n");
764 }
765 SkDebugf("clip=%d,%d\n", clipDeviceBounds.width(), clipDeviceBounds.height());
766 SkISize baseLayerSize = canvas.getBaseLayerSize();
767 SkDebugf("size=%d,%d\n", baseLayerSize.width(), baseLayerSize.height());
768
769 #StdOut
770 clip=10,30
771 size=20,30
772 ##
773##
774
775#ToDo is this the same as the width and height of surface? ##
776
Cary Clark2ade9972017-11-02 17:49:34 -0400777#SeeAlso getDeviceClipBounds
778
Cary Clark8032b982017-07-28 11:04:54 -0400779##
780
781# ------------------------------------------------------------------------------
782
783#Method sk_sp<SkSurface> makeSurface(const SkImageInfo& info, const SkSurfaceProps* props = nullptr)
784
785Creates Surface matching info and props, and associates it with Canvas.
Cary Clarkbad5ad72017-08-03 17:14:08 -0400786Returns nullptr if no match found.
Cary Clark8032b982017-07-28 11:04:54 -0400787
Cary Clarkbad5ad72017-08-03 17:14:08 -0400788If props is nullptr, matches Surface_Properties in Canvas. If props is nullptr and Canvas
789does not have Surface_Properties, creates Surface with default Surface_Properties.
Cary Clark8032b982017-07-28 11:04:54 -0400790
Cary Clarkbad5ad72017-08-03 17:14:08 -0400791#Param info width, height, Image_Color_Type, Image_Alpha_Type, and Color_Space ##
792#Param props Surface_Properties to match; may be nullptr to match Canvas ##
793
794#Return Surface matching info and props, or nullptr if no match is available ##
Cary Clark8032b982017-07-28 11:04:54 -0400795
796#Example
797 sk_sp<SkSurface> surface = SkSurface::MakeRasterN32Premul(5, 6);
798 SkCanvas* smallCanvas = surface->getCanvas();
799 SkImageInfo imageInfo = SkImageInfo::MakeN32Premul(3, 4);
800 sk_sp<SkSurface> compatible = smallCanvas->makeSurface(imageInfo);
801 SkDebugf("compatible %c= nullptr\n", compatible == nullptr ? '=' : '!');
802 SkDebugf("size = %d, %d\n", compatible->width(), compatible->height());
803
804 #StdOut
Cary Clarkbad5ad72017-08-03 17:14:08 -0400805 compatible != nullptr
Cary Clark8032b982017-07-28 11:04:54 -0400806 size = 3, 4
807 ##
808##
809
Cary Clark2ade9972017-11-02 17:49:34 -0400810#SeeAlso SkSurface SkSurface::makeSurface SkImageInfo SkSurfaceProps
Cary Clark8032b982017-07-28 11:04:54 -0400811
812##
813
814# ------------------------------------------------------------------------------
815
816#Method virtual GrContext* getGrContext()
817
818Returns GPU_Context of the GPU_Surface associated with Canvas.
819
Cary Clarkbad5ad72017-08-03 17:14:08 -0400820#Return GPU_Context, if available; nullptr otherwise ##
Cary Clark8032b982017-07-28 11:04:54 -0400821
822#Example
823void draw(SkCanvas* canvas) {
824 if (canvas->getGrContext()) {
825 canvas->clear(SK_ColorRED);
826 } else {
827 canvas->clear(SK_ColorBLUE);
828 }
829}
830##
831
832#ToDo fiddle should show both CPU and GPU out ##
833
Cary Clark2ade9972017-11-02 17:49:34 -0400834#SeeAlso GrContext
835
Cary Clark8032b982017-07-28 11:04:54 -0400836##
837
838# ------------------------------------------------------------------------------
839
Cary Clark73fa9722017-08-29 17:36:51 -0400840#Method void* accessTopLayerPixels(SkImageInfo* info, size_t* rowBytes, SkIPoint* origin = nullptr)
Cary Clark8032b982017-07-28 11:04:54 -0400841
842Returns the pixel base address, Image_Info, rowBytes, and origin if the pixels
Cary Clarkbad5ad72017-08-03 17:14:08 -0400843can be read directly. The returned address is only valid
Cary Clark8032b982017-07-28 11:04:54 -0400844while Canvas is in scope and unchanged. Any Canvas call or Surface call
845may invalidate the returned address and other returned values.
846
847If pixels are inaccessible, info, rowBytes, and origin are unchanged.
848
Cary Clarkbad5ad72017-08-03 17:14:08 -0400849#Param info storage for writable pixels' Image_Info; may be nullptr ##
850#Param rowBytes storage for writable pixels' row bytes; may be nullptr ##
Cary Clarkbc5697d2017-10-04 14:31:33 -0400851#Param origin storage for Canvas top Layer origin, its top-left corner;
Cary Clarkbad5ad72017-08-03 17:14:08 -0400852 may be nullptr
853##
Cary Clark8032b982017-07-28 11:04:54 -0400854
Cary Clarka523d2d2017-08-30 08:58:10 -0400855#Return address of pixels, or nullptr if inaccessible ##
Cary Clark8032b982017-07-28 11:04:54 -0400856
857#Example
858void draw(SkCanvas* canvas) {
859 if (canvas->accessTopLayerPixels(nullptr, nullptr)) {
860 canvas->clear(SK_ColorRED);
861 } else {
862 canvas->clear(SK_ColorBLUE);
863 }
864}
865##
866
867#Example
868#Description
Cary Clarkce101242017-09-01 15:51:02 -0400869Draws "ABC" on the device. Then draws "DEF" in Layer, and reads
870Layer to add a large dotted "DEF". Finally blends Layer with the
Cary Clark8032b982017-07-28 11:04:54 -0400871device.
872
Cary Clarkce101242017-09-01 15:51:02 -0400873The Layer and blended result appear on the CPU and GPU but the large dotted
Cary Clark8032b982017-07-28 11:04:54 -0400874"DEF" appear only on the CPU.
875##
876void draw(SkCanvas* canvas) {
Cary Clarkbad5ad72017-08-03 17:14:08 -0400877 SkPaint paint;
878 paint.setTextSize(100);
879 canvas->drawString("ABC", 20, 160, paint);
880 SkRect layerBounds = SkRect::MakeXYWH(32, 32, 192, 192);
881 canvas->saveLayerAlpha(&layerBounds, 128);
882 canvas->clear(SK_ColorWHITE);
883 canvas->drawString("DEF", 20, 160, paint);
884 SkImageInfo imageInfo;
885 size_t rowBytes;
886 SkIPoint origin;
887 uint32_t* access = (uint32_t*) canvas->accessTopLayerPixels(&imageInfo, &rowBytes, &origin);
888 if (access) {
889 int h = imageInfo.height();
890 int v = imageInfo.width();
891 int rowWords = rowBytes / sizeof(uint32_t);
892 for (int y = 0; y < h; ++y) {
893 int newY = (y - h / 2) * 2 + h / 2;
894 if (newY < 0 || newY >= h) {
895 continue;
896 }
897 for (int x = 0; x < v; ++x) {
898 int newX = (x - v / 2) * 2 + v / 2;
899 if (newX < 0 || newX >= v) {
900 continue;
901 }
902 if (access[y * rowWords + x] == SK_ColorBLACK) {
903 access[newY * rowWords + newX] = SK_ColorGRAY;
904 }
905 }
906 }
907
908 }
Cary Clark8032b982017-07-28 11:04:54 -0400909 canvas->restore();
910}
911##
912
913#ToDo there are no callers of this that I can find. Deprecate? ##
914#ToDo fiddle should show both CPU and GPU out ##
915
Cary Clark2ade9972017-11-02 17:49:34 -0400916#SeeAlso SkImageInfo SkPixmap
917
Cary Clark8032b982017-07-28 11:04:54 -0400918##
919
920# ------------------------------------------------------------------------------
921
922#Method SkRasterHandleAllocator::Handle accessTopRasterHandle() const
923
924Returns custom context that tracks the Matrix and Clip.
925
926Use Raster_Handle_Allocator to blend Skia drawing with custom drawing, typically performed
Cary Clarkbc5697d2017-10-04 14:31:33 -0400927by the host platform user interface. The custom context returned is generated by
Cary Clarkbad5ad72017-08-03 17:14:08 -0400928SkRasterHandleAllocator::MakeCanvas, which creates a custom canvas with raster storage for
Cary Clark8032b982017-07-28 11:04:54 -0400929the drawing destination.
930
Cary Clarkce101242017-09-01 15:51:02 -0400931#Return context of custom allocation ##
Cary Clark8032b982017-07-28 11:04:54 -0400932
933#Example
934#Description
935#ToDo ##
936##
937#Function
938 static void DeleteCallback(void*, void* context) {
939 delete (char*) context;
940 }
941
942 class CustomAllocator : public SkRasterHandleAllocator {
943 public:
944 bool allocHandle(const SkImageInfo& info, Rec* rec) override {
945 char* context = new char[4]{'s', 'k', 'i', 'a'};
946 rec->fReleaseProc = DeleteCallback;
947 rec->fReleaseCtx = context;
948 rec->fHandle = context;
949 rec->fPixels = context;
950 rec->fRowBytes = 4;
951 return true;
952 }
953
954 void updateHandle(Handle handle, const SkMatrix& ctm, const SkIRect& clip_bounds) override {
955 // apply canvas matrix and clip to custom environment
956 }
957 };
958
959##
960 void draw(SkCanvas* canvas) {
961 const SkImageInfo info = SkImageInfo::MakeN32Premul(1, 1);
962 std::unique_ptr<SkCanvas> c2 =
963 SkRasterHandleAllocator::MakeCanvas(std::unique_ptr<CustomAllocator>(
964 new CustomAllocator()), info);
965 char* context = (char*) c2->accessTopRasterHandle();
966 SkDebugf("context = %.4s\n", context);
967
968 }
969 #StdOut
970 context = skia
971 ##
972 #ToDo skstd::make_unique could not be used because def is private -- note to fix in c++14? ##
973##
974
975#SeeAlso SkRasterHandleAllocator
976
977##
978
979# ------------------------------------------------------------------------------
980
981#Method bool peekPixels(SkPixmap* pixmap)
982
983Returns true if Canvas has direct access to its pixels.
984
Cary Clarkf05bdda2017-08-24 12:59:48 -0400985Pixels are readable when Device is raster. Pixels are not readable when Canvas
Cary Clarkbad5ad72017-08-03 17:14:08 -0400986is returned from GPU_Surface, returned by SkDocument::beginPage, returned by
Cary Clarkf05bdda2017-08-24 12:59:48 -0400987SkPictureRecorder::beginRecording, or Canvas is the base of a utility class
Cary Clarkbad5ad72017-08-03 17:14:08 -0400988like SkDumpCanvas.
Cary Clark8032b982017-07-28 11:04:54 -0400989
Cary Clarkf05bdda2017-08-24 12:59:48 -0400990pixmap is valid only while Canvas is in scope and unchanged. Any
Cary Clarkbad5ad72017-08-03 17:14:08 -0400991Canvas or Surface call may invalidate the pixmap values.
Cary Clark8032b982017-07-28 11:04:54 -0400992
Cary Clarkbc5697d2017-10-04 14:31:33 -0400993#Param pixmap storage for pixel state if pixels are readable; otherwise, ignored ##
Cary Clark8032b982017-07-28 11:04:54 -0400994
Cary Clarkbad5ad72017-08-03 17:14:08 -0400995#Return true if Canvas has direct access to pixels ##
Cary Clark8032b982017-07-28 11:04:54 -0400996
997#Example
998 SkPixmap pixmap;
999 if (canvas->peekPixels(&pixmap)) {
1000 SkDebugf("width=%d height=%d\n", pixmap.bounds().width(), pixmap.bounds().height());
1001 }
1002 #StdOut
1003 width=256 height=256
1004 ##
1005##
1006
Cary Clark2ade9972017-11-02 17:49:34 -04001007#SeeAlso readPixels SkBitmap::peekPixels SkImage::peekPixels SkSurface::peekPixels
1008
Cary Clark8032b982017-07-28 11:04:54 -04001009##
1010
1011# ------------------------------------------------------------------------------
1012
1013#Method bool readPixels(const SkImageInfo& dstInfo, void* dstPixels, size_t dstRowBytes,
1014 int srcX, int srcY)
1015
Cary Clark154beea2017-10-26 07:58:48 -04001016Copies Rect of pixels from Canvas into dstPixels. Matrix and Clip are
Cary Clarka560c472017-11-27 10:44:06 -05001017ignored.
Cary Clark6fc50412017-09-21 12:31:06 -04001018
Cary Clarka560c472017-11-27 10:44:06 -05001019Source Rect corners are (srcX, srcY) and (imageInfo().width(), imageInfo().height()).
1020Destination Rect corners are (0, 0) and (dstInfo.width(), dstInfo.height()).
Cary Clark6fc50412017-09-21 12:31:06 -04001021Copies each readable pixel intersecting both rectangles, without scaling,
Cary Clarkf05bdda2017-08-24 12:59:48 -04001022converting to dstInfo.colorType() and dstInfo.alphaType() if required.
Cary Clark8032b982017-07-28 11:04:54 -04001023
Cary Clarkf05bdda2017-08-24 12:59:48 -04001024Pixels are readable when Device is raster, or backed by a GPU.
1025Pixels are not readable when SkCanvas is returned by SkDocument::beginPage,
1026returned by SkPictureRecorder::beginRecording, or Canvas is the base of a utility
1027class like SkDumpCanvas.
Cary Clark8032b982017-07-28 11:04:54 -04001028
Cary Clarkf05bdda2017-08-24 12:59:48 -04001029The destination pixel storage must be allocated by the caller.
Cary Clark8032b982017-07-28 11:04:54 -04001030
Cary Clarkf05bdda2017-08-24 12:59:48 -04001031Pixel values are converted only if Image_Color_Type and Image_Alpha_Type
1032do not match. Only pixels within both source and destination rectangles
Cary Clark154beea2017-10-26 07:58:48 -04001033are copied. dstPixels contents outside Rect intersection are unchanged.
Cary Clarkf05bdda2017-08-24 12:59:48 -04001034
1035Pass negative values for srcX or srcY to offset pixels across or down destination.
Cary Clark8032b982017-07-28 11:04:54 -04001036
1037Does not copy, and returns false if:
1038
1039#List
Cary Clarkf05bdda2017-08-24 12:59:48 -04001040# Source and destination rectangles do not intersect. ##
1041# Canvas pixels could not be converted to dstInfo.colorType() or dstInfo.alphaType(). ##
1042# Canvas pixels are not readable; for instance, Canvas is document-based. ##
Cary Clark8032b982017-07-28 11:04:54 -04001043# dstRowBytes is too small to contain one row of pixels. ##
1044##
1045
Cary Clarkf05bdda2017-08-24 12:59:48 -04001046#Param dstInfo width, height, Image_Color_Type, and Image_Alpha_Type of dstPixels ##
1047#Param dstPixels storage for pixels; dstInfo.height() times dstRowBytes, or larger ##
1048#Param dstRowBytes size of one destination row; dstInfo.width() times pixel size, or larger ##
1049#Param srcX offset into readable pixels in x; may be negative ##
1050#Param srcY offset into readable pixels in y; may be negative ##
Cary Clark8032b982017-07-28 11:04:54 -04001051
Cary Clarkbad5ad72017-08-03 17:14:08 -04001052#Return true if pixels were copied ##
Cary Clark8032b982017-07-28 11:04:54 -04001053
1054#Example
Cary Clarkf05bdda2017-08-24 12:59:48 -04001055#Width 64
1056#Height 64
1057#Description
1058 A black circle drawn on a blue background provides an image to copy.
1059 readPixels copies one quarter of the canvas into each of the four corners.
Cary Clarka560c472017-11-27 10:44:06 -05001060 The copied quarter circles overdraw the original circle.
Cary Clarkf05bdda2017-08-24 12:59:48 -04001061##
1062 canvas->clear(SK_ColorBLUE);
1063 SkPaint paint;
1064 canvas->drawCircle(32, 32, 28, paint);
1065 SkImageInfo info = SkImageInfo::Make(64, 64, kBGRA_8888_SkColorType, kPremul_SkAlphaType);
1066 sk_sp<SkData> data(SkData::MakeUninitialized(info.minRowBytes() * info.height()));
1067 sk_bzero(data->writable_data(), info.minRowBytes() * info.height());
1068 for (int x : { 32, -32 } ) {
1069 for (int y : { 32, -32 } ) {
1070 canvas->readPixels(info, data->writable_data(), info.minRowBytes(), x, y);
1071 }
1072 }
1073 sk_sp<SkImage> image = SkImage::MakeRasterData(info, data, info.minRowBytes());
1074 canvas->drawImage(image, 0, 0);
1075##
1076
1077#Example
Cary Clark8032b982017-07-28 11:04:54 -04001078#Description
Cary Clarkce101242017-09-01 15:51:02 -04001079 Canvas returned by Raster_Surface has Premultiplied pixel values.
1080 clear() takes Unpremultiplied input with Color_Alpha equal 0x80
1081 and Color_RGB equal 0x55, 0xAA, 0xFF. Color_RGB is multiplied by Color_Alpha
1082 to generate Premultiplied value 0x802B5580. readPixels converts pixel back
1083 to Unpremultiplied value 0x8056A9FF, introducing error.
Cary Clark8032b982017-07-28 11:04:54 -04001084##
1085 canvas->clear(0x8055aaff);
1086 for (SkAlphaType alphaType : { kPremul_SkAlphaType, kUnpremul_SkAlphaType } ) {
1087 uint32_t pixel = 0;
1088 SkImageInfo info = SkImageInfo::Make(1, 1, kBGRA_8888_SkColorType, alphaType);
1089 if (canvas->readPixels(info, &pixel, 4, 0, 0)) {
1090 SkDebugf("pixel = %08x\n", pixel);
1091 }
1092 }
1093
1094 #StdOut
1095 pixel = 802b5580
1096 pixel = 8056a9ff
1097 ##
1098##
1099
Cary Clark2ade9972017-11-02 17:49:34 -04001100#SeeAlso peekPixels writePixels drawBitmap drawImage SkBitmap::readPixels SkPixmap::readPixels SkImage::readPixels SkSurface::readPixels
Cary Clark8032b982017-07-28 11:04:54 -04001101
1102##
1103
1104# ------------------------------------------------------------------------------
1105
1106#Method bool readPixels(const SkPixmap& pixmap, int srcX, int srcY)
1107
Cary Clark154beea2017-10-26 07:58:48 -04001108Copies Rect of pixels from Canvas into pixmap. Matrix and Clip are
Cary Clarka560c472017-11-27 10:44:06 -05001109ignored.
Cary Clark6fc50412017-09-21 12:31:06 -04001110
Cary Clarka560c472017-11-27 10:44:06 -05001111Source Rect corners are (srcX, srcY) and (imageInfo().width(), imageInfo().height()).
1112Destination Rect corners are (0, 0) and (pixmap.width(), pixmap.height()).
Cary Clark6fc50412017-09-21 12:31:06 -04001113Copies each readable pixel intersecting both rectangles, without scaling,
Cary Clarkf05bdda2017-08-24 12:59:48 -04001114converting to pixmap.colorType() and pixmap.alphaType() if required.
Cary Clark8032b982017-07-28 11:04:54 -04001115
Cary Clarkf05bdda2017-08-24 12:59:48 -04001116Pixels are readable when Device is raster, or backed by a GPU.
1117Pixels are not readable when SkCanvas is returned by SkDocument::beginPage,
1118returned by SkPictureRecorder::beginRecording, or Canvas is the base of a utility
1119class like SkDumpCanvas.
Cary Clark8032b982017-07-28 11:04:54 -04001120
Cary Clark6fc50412017-09-21 12:31:06 -04001121Caller must allocate pixel storage in pixmap if needed.
Cary Clark8032b982017-07-28 11:04:54 -04001122
Cary Clarkf05bdda2017-08-24 12:59:48 -04001123Pixel values are converted only if Image_Color_Type and Image_Alpha_Type
Cary Clark154beea2017-10-26 07:58:48 -04001124do not match. Only pixels within both source and destination Rects
1125are copied. pixmap pixels contents outside Rect intersection are unchanged.
Cary Clarkf05bdda2017-08-24 12:59:48 -04001126
1127Pass negative values for srcX or srcY to offset pixels across or down pixmap.
Cary Clark8032b982017-07-28 11:04:54 -04001128
1129Does not copy, and returns false if:
1130
1131#List
Cary Clarkf05bdda2017-08-24 12:59:48 -04001132# Source and destination rectangles do not intersect. ##
1133# Canvas pixels could not be converted to pixmap.colorType() or pixmap.alphaType(). ##
1134# Canvas pixels are not readable; for instance, Canvas is document-based. ##
1135# Pixmap pixels could not be allocated. ##
1136# pixmap.rowBytes() is too small to contain one row of pixels. ##
Cary Clark8032b982017-07-28 11:04:54 -04001137##
1138
Cary Clarkbad5ad72017-08-03 17:14:08 -04001139#Param pixmap storage for pixels copied from Canvas ##
Cary Clarkf05bdda2017-08-24 12:59:48 -04001140#Param srcX offset into readable pixels in x; may be negative ##
1141#Param srcY offset into readable pixels in y; may be negative ##
Cary Clark8032b982017-07-28 11:04:54 -04001142
Cary Clarkbad5ad72017-08-03 17:14:08 -04001143#Return true if pixels were copied ##
Cary Clark8032b982017-07-28 11:04:54 -04001144
1145#Example
Cary Clarkf05bdda2017-08-24 12:59:48 -04001146 #Description
Cary Clarkce101242017-09-01 15:51:02 -04001147 clear() takes Unpremultiplied input with Color_Alpha equal 0x80
1148 and Color_RGB equal 0x55, 0xAA, 0xFF. Color_RGB is multiplied by Color_Alpha
1149 to generate Premultiplied value 0x802B5580.
Cary Clarkf05bdda2017-08-24 12:59:48 -04001150 ##
1151 void draw(SkCanvas* canvas) {
1152 canvas->clear(0x8055aaff);
1153 uint32_t pixels[1] = { 0 };
1154 SkPixmap pixmap(SkImageInfo::MakeN32Premul(1, 1), pixels, 4);
1155 canvas->readPixels(pixmap, 0, 0);
1156 SkDebugf("pixel = %08x\n", pixels[0]);
1157 }
Cary Clark8032b982017-07-28 11:04:54 -04001158 #StdOut
1159 pixel = 802b5580
1160 ##
1161##
1162
Cary Clark2ade9972017-11-02 17:49:34 -04001163#SeeAlso peekPixels writePixels drawBitmap drawImage SkBitmap::readPixels SkPixmap::readPixels SkImage::readPixels SkSurface::readPixels
Cary Clark8032b982017-07-28 11:04:54 -04001164
1165##
1166
1167# ------------------------------------------------------------------------------
1168
1169#Method bool readPixels(const SkBitmap& bitmap, int srcX, int srcY)
1170
Cary Clark154beea2017-10-26 07:58:48 -04001171Copies Rect of pixels from Canvas into bitmap. Matrix and Clip are
Cary Clarka560c472017-11-27 10:44:06 -05001172ignored.
Cary Clark6fc50412017-09-21 12:31:06 -04001173
Cary Clarka560c472017-11-27 10:44:06 -05001174Source Rect corners are (srcX, srcY) and (imageInfo().width(), imageInfo().height()).
Cary Clark154beea2017-10-26 07:58:48 -04001175Destination Rect corners are (0, 0) and (bitmap.width(), bitmap.height()).
Cary Clarkf05bdda2017-08-24 12:59:48 -04001176Copies each readable pixel intersecting both rectangles, without scaling,
1177converting to bitmap.colorType() and bitmap.alphaType() if required.
Cary Clark8032b982017-07-28 11:04:54 -04001178
Cary Clarkf05bdda2017-08-24 12:59:48 -04001179Pixels are readable when Device is raster, or backed by a GPU.
1180Pixels are not readable when SkCanvas is returned by SkDocument::beginPage,
1181returned by SkPictureRecorder::beginRecording, or Canvas is the base of a utility
1182class like SkDumpCanvas.
Cary Clark8032b982017-07-28 11:04:54 -04001183
Cary Clark6fc50412017-09-21 12:31:06 -04001184Caller must allocate pixel storage in bitmap if needed.
Cary Clarkf05bdda2017-08-24 12:59:48 -04001185
1186Bitmap values are converted only if Image_Color_Type and Image_Alpha_Type
1187do not match. Only pixels within both source and destination rectangles
Cary Clark154beea2017-10-26 07:58:48 -04001188are copied. Bitmap pixels outside Rect intersection are unchanged.
Cary Clarkf05bdda2017-08-24 12:59:48 -04001189
1190Pass negative values for srcX or srcY to offset pixels across or down bitmap.
Cary Clark8032b982017-07-28 11:04:54 -04001191
1192Does not copy, and returns false if:
1193
1194#List
Cary Clarkf05bdda2017-08-24 12:59:48 -04001195# Source and destination rectangles do not intersect. ##
1196# Canvas pixels could not be converted to bitmap.colorType() or bitmap.alphaType(). ##
1197# Canvas pixels are not readable; for instance, Canvas is document-based. ##
Cary Clark8032b982017-07-28 11:04:54 -04001198# bitmap pixels could not be allocated. ##
Cary Clarkf05bdda2017-08-24 12:59:48 -04001199# bitmap.rowBytes() is too small to contain one row of pixels. ##
Cary Clark8032b982017-07-28 11:04:54 -04001200##
1201
Cary Clarkbad5ad72017-08-03 17:14:08 -04001202#Param bitmap storage for pixels copied from Canvas ##
Cary Clarkf05bdda2017-08-24 12:59:48 -04001203#Param srcX offset into readable pixels in x; may be negative ##
1204#Param srcY offset into readable pixels in y; may be negative ##
Cary Clark8032b982017-07-28 11:04:54 -04001205
Cary Clarkbad5ad72017-08-03 17:14:08 -04001206#Return true if pixels were copied ##
Cary Clark8032b982017-07-28 11:04:54 -04001207
1208#Example
Cary Clarkf05bdda2017-08-24 12:59:48 -04001209 #Description
Cary Clarkce101242017-09-01 15:51:02 -04001210 clear() takes Unpremultiplied input with Color_Alpha equal 0x80
1211 and Color_RGB equal 0x55, 0xAA, 0xFF. Color_RGB is multiplied by Color_Alpha
1212 to generate Premultiplied value 0x802B5580.
Cary Clarkf05bdda2017-08-24 12:59:48 -04001213 ##
Cary Clark8032b982017-07-28 11:04:54 -04001214void draw(SkCanvas* canvas) {
1215 canvas->clear(0x8055aaff);
1216 SkBitmap bitmap;
1217 bitmap.allocPixels(SkImageInfo::MakeN32Premul(1, 1));
1218 canvas->readPixels(bitmap, 0, 0);
1219 SkDebugf("pixel = %08x\n", bitmap.getAddr32(0, 0)[0]);
1220}
1221 #StdOut
1222 pixel = 802b5580
1223 ##
1224##
1225
Cary Clark2ade9972017-11-02 17:49:34 -04001226#SeeAlso peekPixels writePixels drawBitmap drawImage SkBitmap::readPixels SkPixmap::readPixels SkImage::readPixels SkSurface::readPixels
Cary Clark8032b982017-07-28 11:04:54 -04001227
1228##
1229
1230# ------------------------------------------------------------------------------
1231
1232#Method bool writePixels(const SkImageInfo& info, const void* pixels, size_t rowBytes, int x, int y)
1233
Cary Clark154beea2017-10-26 07:58:48 -04001234Copies Rect from pixels to Canvas. Matrix and Clip are ignored.
1235Source Rect corners are (0, 0) and (info.width(), info.height()).
1236Destination Rect corners are (x, y) and
1237(imageInfo().width(), imageInfo().height()).
Cary Clark6fc50412017-09-21 12:31:06 -04001238
1239Copies each readable pixel intersecting both rectangles, without scaling,
Cary Clark154beea2017-10-26 07:58:48 -04001240converting to imageInfo().colorType() and imageInfo().alphaType() if required.
Cary Clark8032b982017-07-28 11:04:54 -04001241
Cary Clarkf05bdda2017-08-24 12:59:48 -04001242Pixels are writable when Device is raster, or backed by a GPU.
1243Pixels are not writable when SkCanvas is returned by SkDocument::beginPage,
1244returned by SkPictureRecorder::beginRecording, or Canvas is the base of a utility
1245class like SkDumpCanvas.
Cary Clark8032b982017-07-28 11:04:54 -04001246
Cary Clarkf05bdda2017-08-24 12:59:48 -04001247Pixel values are converted only if Image_Color_Type and Image_Alpha_Type
1248do not match. Only pixels within both source and destination rectangles
Cary Clark154beea2017-10-26 07:58:48 -04001249are copied. Canvas pixels outside Rect intersection are unchanged.
Cary Clark8032b982017-07-28 11:04:54 -04001250
Cary Clarkf05bdda2017-08-24 12:59:48 -04001251Pass negative values for x or y to offset pixels to the left or
1252above Canvas pixels.
Cary Clark8032b982017-07-28 11:04:54 -04001253
1254Does not copy, and returns false if:
1255
1256#List
Cary Clarkf05bdda2017-08-24 12:59:48 -04001257# Source and destination rectangles do not intersect. ##
Cary Clarkac47b882018-01-11 10:35:44 -05001258# pixels could not be converted to Canvas imageInfo().colorType() or
1259 imageInfo().alphaType(). ##
Cary Clark8032b982017-07-28 11:04:54 -04001260# Canvas pixels are not writable; for instance, Canvas is document-based. ##
1261# rowBytes is too small to contain one row of pixels. ##
1262##
1263
Cary Clarkf05bdda2017-08-24 12:59:48 -04001264#Param info width, height, Image_Color_Type, and Image_Alpha_Type of pixels ##
1265#Param pixels pixels to copy, of size info.height() times rowBytes, or larger ##
Cary Clarkd0530ba2017-09-14 11:25:39 -04001266#Param rowBytes size of one row of pixels; info.width() times pixel size, or larger ##
Cary Clarkf05bdda2017-08-24 12:59:48 -04001267#Param x offset into Canvas writable pixels in x; may be negative ##
1268#Param y offset into Canvas writable pixels in y; may be negative ##
Cary Clark8032b982017-07-28 11:04:54 -04001269
Cary Clarkbad5ad72017-08-03 17:14:08 -04001270#Return true if pixels were written to Canvas ##
Cary Clark8032b982017-07-28 11:04:54 -04001271
1272#Example
1273 SkImageInfo imageInfo = SkImageInfo::MakeN32(256, 1, kPremul_SkAlphaType);
1274 for (int y = 0; y < 256; ++y) {
1275 uint32_t pixels[256];
1276 for (int x = 0; x < 256; ++x) {
1277 pixels[x] = SkColorSetARGB(x, x + y, x, x - y);
1278 }
1279 canvas->writePixels(imageInfo, &pixels, sizeof(pixels), 0, y);
1280 }
1281##
1282
Cary Clark2ade9972017-11-02 17:49:34 -04001283#SeeAlso readPixels drawBitmap drawImage SkBitmap::writePixels
Cary Clark8032b982017-07-28 11:04:54 -04001284
1285##
1286
1287# ------------------------------------------------------------------------------
1288
1289#Method bool writePixels(const SkBitmap& bitmap, int x, int y)
1290
Cary Clark154beea2017-10-26 07:58:48 -04001291Copies Rect from pixels to Canvas. Matrix and Clip are ignored.
1292Source Rect corners are (0, 0) and (bitmap.width(), bitmap.height()).
Cary Clark6fc50412017-09-21 12:31:06 -04001293
Cary Clark154beea2017-10-26 07:58:48 -04001294Destination Rect corners are (x, y) and
1295(imageInfo().width(), imageInfo().height()).
Cary Clark6fc50412017-09-21 12:31:06 -04001296
1297Copies each readable pixel intersecting both rectangles, without scaling,
Cary Clark154beea2017-10-26 07:58:48 -04001298converting to imageInfo().colorType() and imageInfo().alphaType() if required.
Cary Clark8032b982017-07-28 11:04:54 -04001299
Cary Clarkf05bdda2017-08-24 12:59:48 -04001300Pixels are writable when Device is raster, or backed by a GPU.
1301Pixels are not writable when SkCanvas is returned by SkDocument::beginPage,
1302returned by SkPictureRecorder::beginRecording, or Canvas is the base of a utility
1303class like SkDumpCanvas.
Cary Clark8032b982017-07-28 11:04:54 -04001304
Cary Clarkf05bdda2017-08-24 12:59:48 -04001305Pixel values are converted only if Image_Color_Type and Image_Alpha_Type
1306do not match. Only pixels within both source and destination rectangles
Cary Clark154beea2017-10-26 07:58:48 -04001307are copied. Canvas pixels outside Rect intersection are unchanged.
Cary Clark8032b982017-07-28 11:04:54 -04001308
Cary Clarkf05bdda2017-08-24 12:59:48 -04001309Pass negative values for x or y to offset pixels to the left or
1310above Canvas pixels.
Cary Clark8032b982017-07-28 11:04:54 -04001311
1312Does not copy, and returns false if:
1313
1314#List
Cary Clarkf05bdda2017-08-24 12:59:48 -04001315# Source and destination rectangles do not intersect. ##
Cary Clark8032b982017-07-28 11:04:54 -04001316# bitmap does not have allocated pixels. ##
Cary Clarkac47b882018-01-11 10:35:44 -05001317# bitmap pixels could not be converted to Canvas imageInfo().colorType() or
1318 imageInfo().alphaType(). ##
Cary Clarkce101242017-09-01 15:51:02 -04001319# Canvas pixels are not writable; for instance, Canvas is document based. ##
Cary Clark8032b982017-07-28 11:04:54 -04001320# bitmap pixels are inaccessible; for instance, bitmap wraps a texture. ##
1321##
1322
Cary Clarkbad5ad72017-08-03 17:14:08 -04001323#Param bitmap contains pixels copied to Canvas ##
Cary Clarkf05bdda2017-08-24 12:59:48 -04001324#Param x offset into Canvas writable pixels in x; may be negative ##
1325#Param y offset into Canvas writable pixels in y; may be negative ##
Cary Clark8032b982017-07-28 11:04:54 -04001326
Cary Clarkbad5ad72017-08-03 17:14:08 -04001327#Return true if pixels were written to Canvas ##
Cary Clark8032b982017-07-28 11:04:54 -04001328
1329#Example
1330void draw(SkCanvas* canvas) {
1331 SkImageInfo imageInfo = SkImageInfo::MakeN32Premul(2, 2);
1332 SkBitmap bitmap;
1333 bitmap.setInfo(imageInfo);
1334 uint32_t pixels[4];
1335 bitmap.setPixels(pixels);
1336 for (int y = 0; y < 256; y += 2) {
1337 for (int x = 0; x < 256; x += 2) {
1338 pixels[0] = SkColorSetRGB(x, y, x | y);
1339 pixels[1] = SkColorSetRGB(x ^ y, y, x);
1340 pixels[2] = SkColorSetRGB(x, x & y, y);
1341 pixels[3] = SkColorSetRGB(~x, ~y, x);
1342 canvas->writePixels(bitmap, x, y);
1343 }
1344 }
1345}
1346##
1347
Cary Clark2ade9972017-11-02 17:49:34 -04001348#SeeAlso readPixels drawBitmap drawImage SkBitmap::writePixels
Cary Clark8032b982017-07-28 11:04:54 -04001349
1350##
1351
1352# ------------------------------------------------------------------------------
1353#Topic State_Stack
1354
1355Canvas maintains a stack of state that allows hierarchical drawing, commonly used
Cary Clarkbad5ad72017-08-03 17:14:08 -04001356to implement windows and views. The initial state has an identity matrix and and
1357an infinite clip. Even with a wide-open clip, drawing is constrained by the
1358bounds of the Canvas Surface or Device.
Cary Clark8032b982017-07-28 11:04:54 -04001359
1360Canvas savable state consists of Clip, Matrix, and Draw_Filter.
1361Clip describes the area that may be drawn to.
1362Matrix transforms the geometry.
1363Draw_Filter (deprecated on most platforms) modifies the paint before drawing.
1364
1365save(), saveLayer, saveLayerPreserveLCDTextRequests, and saveLayerAlpha
1366save state and return the depth of the stack.
1367
Cary Clarkbad5ad72017-08-03 17:14:08 -04001368restore(), restoreToCount, and ~SkCanvas() revert state to its value when saved.
Cary Clark8032b982017-07-28 11:04:54 -04001369
1370Each state on the stack intersects Clip with the previous Clip,
1371and concatenates Matrix with the previous Matrix.
1372The intersected Clip makes the drawing area the same or smaller;
1373the concatenated Matrix may move the origin and potentially scale or rotate
1374the coordinate space.
1375
1376Canvas does not require balancing the state stack but it is a good idea
1377to do so. Calling save() without restore() will eventually cause Skia to fail;
1378mismatched save() and restore() create hard to find bugs.
1379
1380It is not possible to use state to draw outside of the clip defined by the
1381previous state.
1382
1383#Example
1384#Description
1385Draw to ever smaller clips; then restore drawing to full canvas.
1386Note that the second clipRect is not permitted to enlarge Clip.
1387##
1388#Height 160
Cary Clarkbad5ad72017-08-03 17:14:08 -04001389void draw(SkCanvas* canvas) {
1390 SkPaint paint;
1391 canvas->save(); // records stack depth to restore
1392 canvas->clipRect(SkRect::MakeWH(100, 100)); // constrains drawing to clip
1393 canvas->clear(SK_ColorRED); // draws to limit of clip
1394 canvas->save(); // records stack depth to restore
1395 canvas->clipRect(SkRect::MakeWH(50, 150)); // Rect below 100 is ignored
1396 canvas->clear(SK_ColorBLUE); // draws to smaller clip
1397 canvas->restore(); // enlarges clip
1398 canvas->drawLine(20, 20, 150, 150, paint); // line below 100 is not drawn
1399 canvas->restore(); // enlarges clip
1400 canvas->drawLine(150, 20, 50, 120, paint); // line below 100 is drawn
Cary Clark8032b982017-07-28 11:04:54 -04001401}
1402##
1403
1404Each Clip uses the current Matrix for its coordinates.
1405
1406#Example
1407#Description
1408While clipRect is given the same rectangle twice, Matrix makes the second
1409clipRect draw at half the size of the first.
1410##
1411#Height 128
Cary Clarkbad5ad72017-08-03 17:14:08 -04001412void draw(SkCanvas* canvas) {
1413 canvas->clipRect(SkRect::MakeWH(100, 100));
1414 canvas->clear(SK_ColorRED);
1415 canvas->scale(.5, .5);
1416 canvas->clipRect(SkRect::MakeWH(100, 100));
1417 canvas->clear(SK_ColorBLUE);
Cary Clark8032b982017-07-28 11:04:54 -04001418}
1419##
1420
1421#SeeAlso save() saveLayer saveLayerPreserveLCDTextRequests saveLayerAlpha restore() restoreToCount
1422
1423#Method int save()
1424
1425Saves Matrix, Clip, and Draw_Filter (Draw_Filter deprecated on most platforms).
1426Calling restore() discards changes to Matrix, Clip, and Draw_Filter,
1427restoring the Matrix, Clip, and Draw_Filter to their state when save() was called.
1428
Cary Clarkbad5ad72017-08-03 17:14:08 -04001429Matrix may be changed by translate(), scale(), rotate(), skew(), concat(), setMatrix,
1430and resetMatrix. Clip may be changed by clipRect, clipRRect, clipPath, clipRegion.
Cary Clark8032b982017-07-28 11:04:54 -04001431
Cary Clarkbad5ad72017-08-03 17:14:08 -04001432Saved Canvas state is put on a stack; multiple calls to save() should be balance
1433by an equal number of calls to restore().
Cary Clark8032b982017-07-28 11:04:54 -04001434
1435Call restoreToCount with result to restore this and subsequent saves.
1436
Cary Clarkbad5ad72017-08-03 17:14:08 -04001437#Return depth of saved stack ##
Cary Clark8032b982017-07-28 11:04:54 -04001438
1439#Example
1440#Description
1441The black square is translated 50 pixels down and to the right.
1442Restoring Canvas state removes translate() from Canvas stack;
1443the red square is not translated, and is drawn at the origin.
1444##
1445#Height 100
1446void draw(SkCanvas* canvas) {
1447 SkPaint paint;
1448 SkRect rect = { 0, 0, 25, 25 };
1449 canvas->drawRect(rect, paint);
1450 canvas->save();
1451 canvas->translate(50, 50);
1452 canvas->drawRect(rect, paint);
1453 canvas->restore();
1454 paint.setColor(SK_ColorRED);
1455 canvas->drawRect(rect, paint);
1456}
1457##
1458
Cary Clark2ade9972017-11-02 17:49:34 -04001459#SeeAlso saveLayer saveLayerPreserveLCDTextRequests saveLayerAlpha restore() restoreToCount
Cary Clark8032b982017-07-28 11:04:54 -04001460
1461##
1462
1463# ------------------------------------------------------------------------------
Cary Clark8032b982017-07-28 11:04:54 -04001464
1465#Method void restore()
1466
1467Removes changes to Matrix, Clip, and Draw_Filter since Canvas state was
1468last saved. The state is removed from the stack.
1469
1470Does nothing if the stack is empty.
1471
1472#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04001473void draw(SkCanvas* canvas) {
1474 SkCanvas simple;
1475 SkDebugf("depth = %d\n", simple.getSaveCount());
1476 simple.restore();
1477 SkDebugf("depth = %d\n", simple.getSaveCount());
Cary Clark8032b982017-07-28 11:04:54 -04001478}
1479##
1480
Cary Clark2ade9972017-11-02 17:49:34 -04001481#SeeAlso save() saveLayer saveLayerPreserveLCDTextRequests saveLayerAlpha restoreToCount
1482
Cary Clark8032b982017-07-28 11:04:54 -04001483##
1484
1485# ------------------------------------------------------------------------------
1486
1487#Method int getSaveCount() const
1488
1489Returns the number of saved states, each containing: Matrix, Clip, and Draw_Filter.
1490Equals the number of save() calls less the number of restore() calls plus one.
1491The save count of a new canvas is one.
1492
Cary Clarkbad5ad72017-08-03 17:14:08 -04001493#Return depth of save state stack ##
Cary Clark8032b982017-07-28 11:04:54 -04001494
1495#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04001496void draw(SkCanvas* canvas) {
1497 SkCanvas simple;
1498 SkDebugf("depth = %d\n", simple.getSaveCount());
1499 simple.save();
1500 SkDebugf("depth = %d\n", simple.getSaveCount());
1501 simple.restore();
1502 SkDebugf("depth = %d\n", simple.getSaveCount());
Cary Clark8032b982017-07-28 11:04:54 -04001503}
1504#StdOut
Cary Clarkbad5ad72017-08-03 17:14:08 -04001505depth = 1
1506depth = 2
Cary Clark8032b982017-07-28 11:04:54 -04001507depth = 1
1508##
1509##
1510
Cary Clark2ade9972017-11-02 17:49:34 -04001511#SeeAlso save() restore() restoreToCount
1512
Cary Clark8032b982017-07-28 11:04:54 -04001513##
1514
1515# ------------------------------------------------------------------------------
1516
1517#Method void restoreToCount(int saveCount)
1518
Cary Clarkbad5ad72017-08-03 17:14:08 -04001519Restores state to Matrix, Clip, and Draw_Filter values when save(), saveLayer,
1520saveLayerPreserveLCDTextRequests, or saveLayerAlpha returned saveCount.
Cary Clark8032b982017-07-28 11:04:54 -04001521
1522Does nothing if saveCount is greater than state stack count.
1523Restores state to initial values if saveCount is less than or equal to one.
1524
Cary Clarkbad5ad72017-08-03 17:14:08 -04001525#Param saveCount depth of state stack to restore ##
Cary Clark8032b982017-07-28 11:04:54 -04001526
1527#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04001528void draw(SkCanvas* canvas) {
1529 SkDebugf("depth = %d\n", canvas->getSaveCount());
1530 canvas->save();
1531 canvas->save();
1532 SkDebugf("depth = %d\n", canvas->getSaveCount());
1533 canvas->restoreToCount(0);
1534 SkDebugf("depth = %d\n", canvas->getSaveCount());
Cary Clark8032b982017-07-28 11:04:54 -04001535}
1536#StdOut
Cary Clarkbad5ad72017-08-03 17:14:08 -04001537depth = 1
1538depth = 3
Cary Clark8032b982017-07-28 11:04:54 -04001539depth = 1
1540##
1541##
1542
Cary Clark2ade9972017-11-02 17:49:34 -04001543#SeeAlso restore() getSaveCount save()
1544
Cary Clark8032b982017-07-28 11:04:54 -04001545##
1546
1547#Topic State_Stack ##
1548
1549# ------------------------------------------------------------------------------
Cary Clarkce101242017-09-01 15:51:02 -04001550
1551#Topic Layer
Cary Clarkd0530ba2017-09-14 11:25:39 -04001552#Substitute layer
Cary Clarkce101242017-09-01 15:51:02 -04001553#Alias Layers
1554
1555Layer allocates a temporary Bitmap to draw into. When the drawing is
1556complete, the Bitmap is drawn into the Canvas.
1557
1558Layer is saved in a stack along with other saved state. When state with a Layer
1559is restored, the Bitmap is drawn into the previous Layer.
1560
1561Layer may be initialized with the contents of the previous Layer. When Layer is
1562restored, its Bitmap can be modified by Paint passed to Layer to apply
1563Color_Alpha, Color_Filter, Image_Filter, and Blend_Mode.
1564
1565#Method int saveLayer(const SkRect* bounds, const SkPaint* paint)
1566
1567Saves Matrix, Clip, and Draw_Filter (Draw_Filter deprecated on most platforms),
1568and allocates a Bitmap for subsequent drawing.
1569Calling restore() discards changes to Matrix, Clip, and Draw_Filter,
1570and draws the Bitmap.
1571
1572Matrix may be changed by translate(), scale(), rotate(), skew(), concat(),
1573setMatrix, and resetMatrix. Clip may be changed by clipRect, clipRRect,
1574clipPath, clipRegion.
1575
1576Rect bounds suggests but does not define the Bitmap size. To clip drawing to
1577a specific rectangle, use clipRect.
1578
1579Optional Paint paint applies Color_Alpha, Color_Filter, Image_Filter, and
1580Blend_Mode when restore() is called.
1581
1582Call restoreToCount with returned value to restore this and subsequent saves.
1583
1584#Param bounds hint to limit the size of the Layer; may be nullptr ##
1585#Param paint graphics state for Layer; may be nullptr ##
1586
1587#Return depth of saved stack ##
1588
1589#Example
1590#Description
1591Rectangles are blurred by Image_Filter when restore() draws Layer to main
1592Canvas.
1593##
1594#Height 128
1595void draw(SkCanvas* canvas) {
1596 SkPaint paint, blur;
Cary Clarka560c472017-11-27 10:44:06 -05001597 blur.setImageFilter(SkBlurImageFilter::Make(3, 3, nullptr));
Cary Clarkce101242017-09-01 15:51:02 -04001598 canvas->saveLayer(nullptr, &blur);
1599 SkRect rect = { 25, 25, 50, 50};
1600 canvas->drawRect(rect, paint);
1601 canvas->translate(50, 50);
1602 paint.setColor(SK_ColorRED);
1603 canvas->drawRect(rect, paint);
1604 canvas->restore();
1605}
1606##
1607
Cary Clark2ade9972017-11-02 17:49:34 -04001608#SeeAlso save() restore() saveLayer saveLayerPreserveLCDTextRequests saveLayerAlpha SaveLayerRec
Cary Clarkce101242017-09-01 15:51:02 -04001609
1610##
1611
1612#Method int saveLayer(const SkRect& bounds, const SkPaint* paint)
1613
1614Saves Matrix, Clip, and Draw_Filter (Draw_Filter deprecated on most platforms),
1615and allocates a Bitmap for subsequent drawing.
1616Calling restore() discards changes to Matrix, Clip, and Draw_Filter,
1617and draws the Bitmap.
1618
1619Matrix may be changed by translate(), scale(), rotate(), skew(), concat(),
1620setMatrix, and resetMatrix. Clip may be changed by clipRect, clipRRect,
1621clipPath, clipRegion.
1622
1623Rect bounds suggests but does not define the Layer size. To clip drawing to
1624a specific rectangle, use clipRect.
1625
1626Optional Paint paint applies Color_Alpha, Color_Filter, Image_Filter, and
1627Blend_Mode when restore() is called.
1628
1629Call restoreToCount with returned value to restore this and subsequent saves.
1630
1631#Param bounds hint to limit the size of Layer; may be nullptr ##
1632#Param paint graphics state for Layer; may be nullptr ##
1633
1634#Return depth of saved stack ##
1635
1636#Example
1637#Description
1638Rectangles are blurred by Image_Filter when restore() draws Layer to main Canvas.
1639The red rectangle is clipped; it does not fully fit on Layer.
1640Image_Filter blurs past edge of Layer so red rectangle is blurred on all sides.
1641##
1642#Height 128
1643void draw(SkCanvas* canvas) {
1644 SkPaint paint, blur;
Cary Clarka560c472017-11-27 10:44:06 -05001645 blur.setImageFilter(SkBlurImageFilter::Make(3, 3, nullptr));
Cary Clarkce101242017-09-01 15:51:02 -04001646 canvas->saveLayer(SkRect::MakeWH(90, 90), &blur);
1647 SkRect rect = { 25, 25, 50, 50};
1648 canvas->drawRect(rect, paint);
1649 canvas->translate(50, 50);
1650 paint.setColor(SK_ColorRED);
1651 canvas->drawRect(rect, paint);
1652 canvas->restore();
1653}
1654##
1655
Cary Clark2ade9972017-11-02 17:49:34 -04001656#SeeAlso save() restore() saveLayerPreserveLCDTextRequests saveLayerAlpha SaveLayerRec
Cary Clarkce101242017-09-01 15:51:02 -04001657
1658##
1659
1660#Method int saveLayerPreserveLCDTextRequests(const SkRect* bounds, const SkPaint* paint)
1661
1662Saves Matrix, Clip, and Draw_Filter (Draw_Filter deprecated on most platforms),
1663and allocates a Bitmap for subsequent drawing.
1664LCD_Text is preserved when the Layer is drawn to the prior Layer.
1665
1666Calling restore() discards changes to Matrix, Clip, and Draw_Filter,
1667and draws Layer.
1668
1669Matrix may be changed by translate(), scale(), rotate(), skew(), concat(),
1670setMatrix, and resetMatrix. Clip may be changed by clipRect, clipRRect,
1671clipPath, clipRegion.
1672
1673Rect bounds suggests but does not define the Layer size. To clip drawing to
1674a specific rectangle, use clipRect.
1675
1676Optional Paint paint applies Color_Alpha, Color_Filter, Image_Filter, and
1677Blend_Mode when restore() is called.
1678
1679Call restoreToCount with returned value to restore this and subsequent saves.
1680
1681Draw text on an opaque background so that LCD_Text blends correctly with the
1682prior Layer. LCD_Text drawn on a background with transparency may result in
Cary Clark6fc50412017-09-21 12:31:06 -04001683incorrect blending.
Cary Clarkce101242017-09-01 15:51:02 -04001684
1685#Param bounds hint to limit the size of Layer; may be nullptr ##
1686#Param paint graphics state for Layer; may be nullptr ##
1687
1688#Return depth of saved stack ##
1689
1690#Example
1691 SkPaint paint;
1692 paint.setAntiAlias(true);
1693 paint.setLCDRenderText(true);
1694 paint.setTextSize(20);
1695 for (auto preserve : { false, true } ) {
1696 preserve ? canvas->saveLayerPreserveLCDTextRequests(nullptr, nullptr)
1697 : canvas->saveLayer(nullptr, nullptr);
1698 SkPaint p;
1699 p.setColor(SK_ColorWHITE);
1700 // Comment out the next line to draw on a non-opaque background.
1701 canvas->drawRect(SkRect::MakeLTRB(25, 40, 200, 70), p);
1702 canvas->drawString("Hamburgefons", 30, 60, paint);
1703
1704 p.setColor(0xFFCCCCCC);
1705 canvas->drawRect(SkRect::MakeLTRB(25, 70, 200, 100), p);
1706 canvas->drawString("Hamburgefons", 30, 90, paint);
1707
1708 canvas->restore();
1709 canvas->translate(0, 80);
1710 }
1711 ##
1712
Cary Clark2ade9972017-11-02 17:49:34 -04001713#SeeAlso save() restore() saveLayer saveLayerAlpha SaveLayerRec
Cary Clarkce101242017-09-01 15:51:02 -04001714
1715##
1716
1717#Method int saveLayerAlpha(const SkRect* bounds, U8CPU alpha)
1718
1719Saves Matrix, Clip, and Draw_Filter (Draw_Filter deprecated on most platforms),
1720and allocates Bitmap for subsequent drawing.
1721
1722Calling restore() discards changes to Matrix, Clip, and Draw_Filter,
1723and blends Layer with alpha opacity onto prior Layer.
1724
1725Matrix may be changed by translate(), scale(), rotate(), skew(), concat(),
1726setMatrix, and resetMatrix. Clip may be changed by clipRect, clipRRect,
1727clipPath, clipRegion.
1728
1729Rect bounds suggests but does not define Layer size. To clip drawing to
1730a specific rectangle, use clipRect.
1731
1732alpha of zero is fully transparent, 255 is fully opaque.
1733
1734Call restoreToCount with returned value to restore this and subsequent saves.
1735
1736#Param bounds hint to limit the size of Layer; may be nullptr ##
1737#Param alpha opacity of Layer ##
1738
1739#Return depth of saved stack ##
1740
1741#Example
1742 SkPaint paint;
1743 paint.setColor(SK_ColorRED);
1744 canvas->drawCircle(50, 50, 50, paint);
1745 canvas->saveLayerAlpha(nullptr, 128);
1746 paint.setColor(SK_ColorBLUE);
1747 canvas->drawCircle(100, 50, 50, paint);
1748 paint.setColor(SK_ColorGREEN);
1749 paint.setAlpha(128);
1750 canvas->drawCircle(75, 90, 50, paint);
1751 canvas->restore();
1752##
1753
Cary Clark2ade9972017-11-02 17:49:34 -04001754#SeeAlso save() restore() saveLayer saveLayerPreserveLCDTextRequests SaveLayerRec
Cary Clarkce101242017-09-01 15:51:02 -04001755
1756##
1757
1758#Enum
1759
1760#Code
1761 enum {
1762 kIsOpaque_SaveLayerFlag = 1 << 0,
1763 kPreserveLCDText_SaveLayerFlag = 1 << 1,
1764 kInitWithPrevious_SaveLayerFlag = 1 << 2,
1765 kDontClipToLayer_Legacy_SaveLayerFlag = kDontClipToLayer_PrivateSaveLayerFlag,
1766 };
Cary Clarkce101242017-09-01 15:51:02 -04001767##
1768
1769SaveLayerFlags provides options that may be used in any combination in SaveLayerRec,
1770defining how Layer allocated by saveLayer operates.
1771
1772#Const kIsOpaque_SaveLayerFlag 1
1773 Creates Layer without transparency. Flag is ignored if Layer Paint contains
1774 Image_Filter or Color_Filter.
1775##
1776
1777#Const kPreserveLCDText_SaveLayerFlag 2
1778 Creates Layer for LCD text. Flag is ignored if Layer Paint contains
1779 Image_Filter or Color_Filter.
1780##
1781
1782#Const kInitWithPrevious_SaveLayerFlag 4
1783 Initializes Layer with the contents of the previous Layer.
1784##
1785
1786#Const kDontClipToLayer_Legacy_SaveLayerFlag 0x80000000
1787#Private
1788 to be deprecated: bug.skia.org/2440
1789##
1790 Only present on Android.
1791 Skips setting a clip to the Layer bounds.
1792##
1793
1794#Example
1795#Height 160
1796#Description
1797Canvas Layer captures red and blue circles scaled up by four.
1798scalePaint blends Layer back with transparency.
1799##
1800void draw(SkCanvas* canvas) {
1801 SkPaint redPaint, bluePaint, scalePaint;
1802 redPaint.setColor(SK_ColorRED);
1803 canvas->drawCircle(21, 21, 8, redPaint);
1804 bluePaint.setColor(SK_ColorBLUE);
1805 canvas->drawCircle(31, 21, 8, bluePaint);
1806 SkMatrix matrix;
1807 matrix.setScale(4, 4);
1808 scalePaint.setAlpha(0x40);
1809 scalePaint.setImageFilter(
1810 SkImageFilter::MakeMatrixFilter(matrix, kNone_SkFilterQuality, nullptr));
1811 SkCanvas::SaveLayerRec saveLayerRec(nullptr, &scalePaint,
1812 SkCanvas::kInitWithPrevious_SaveLayerFlag);
1813 canvas->saveLayer(saveLayerRec);
1814 canvas->restore();
1815}
1816##
1817
Cary Clark2ade9972017-11-02 17:49:34 -04001818#SeeAlso save() restore() saveLayer saveLayerPreserveLCDTextRequests saveLayerAlpha SaveLayerRec
Cary Clarkce101242017-09-01 15:51:02 -04001819
1820#Enum ##
1821
Cary Clarka560c472017-11-27 10:44:06 -05001822#Typedef uint32_t SaveLayerFlags
1823
1824##
1825
Cary Clarkce101242017-09-01 15:51:02 -04001826#Struct SaveLayerRec
1827
1828#Code
1829 struct SaveLayerRec {
1830 SaveLayerRec*(...
1831
1832 const SkRect* fBounds;
1833 const SkPaint* fPaint;
1834 const SkImageFilter* fBackdrop;
1835 SaveLayerFlags fSaveLayerFlags;
1836 };
1837##
1838
1839SaveLayerRec contains the state used to create the Layer.
1840
1841#Member const SkRect* fBounds
1842 fBounds is used as a hint to limit the size of Layer; may be nullptr.
1843 fBounds suggests but does not define Layer size. To clip drawing to
1844 a specific rectangle, use clipRect.
1845##
1846
1847#Member const SkPaint* fPaint
1848 fPaint modifies how Layer overlays the prior Layer; may be nullptr.
1849 Color_Alpha, Blend_Mode, Color_Filter, Draw_Looper, Image_Filter, and
1850 Mask_Filter affect Layer draw.
1851##
1852
1853#Member const SkImageFilter* fBackdrop
1854 fBackdrop applies Image_Filter to the prior Layer when copying to the Layer;
1855 may be nullptr. Use kInitWithPrevious_SaveLayerFlag to copy the
1856 prior Layer without an Image_Filter.
1857##
1858
1859#Member const SkImage* fClipMask
1860 restore() clips Layer by the Color_Alpha channel of fClipMask when
1861 Layer is copied to Device. fClipMask may be nullptr. .
1862##
1863
1864#Member const SkMatrix* fClipMatrix
1865 fClipMatrix transforms fClipMask before it clips Layer. If
1866 fClipMask describes a translucent gradient, it may be scaled and rotated
1867 without introducing artifacts. fClipMatrix may be nullptr.
1868##
1869
1870#Member SaveLayerFlags fSaveLayerFlags
1871 fSaveLayerFlags are used to create Layer without transparency,
1872 create Layer for LCD text, and to create Layer with the
1873 contents of the previous Layer.
1874##
1875
1876#Example
1877#Height 160
1878#Description
1879Canvas Layer captures a red Anti-aliased circle and a blue Aliased circle scaled
1880up by four. After drawing another red circle without scaling on top, the Layer is
1881transferred to the main canvas.
1882##
1883void draw(SkCanvas* canvas) {
1884 SkPaint redPaint, bluePaint;
1885 redPaint.setAntiAlias(true);
1886 redPaint.setColor(SK_ColorRED);
1887 canvas->drawCircle(21, 21, 8, redPaint);
1888 bluePaint.setColor(SK_ColorBLUE);
1889 canvas->drawCircle(31, 21, 8, bluePaint);
1890 SkMatrix matrix;
1891 matrix.setScale(4, 4);
1892 auto scaler = SkImageFilter::MakeMatrixFilter(matrix, kNone_SkFilterQuality, nullptr);
1893 SkCanvas::SaveLayerRec saveLayerRec(nullptr, nullptr, scaler.get(), 0);
1894 canvas->saveLayer(saveLayerRec);
1895 canvas->drawCircle(125, 85, 8, redPaint);
1896 canvas->restore();
1897}
1898##
1899
1900#Method SaveLayerRec()
1901
1902Sets fBounds, fPaint, and fBackdrop to nullptr. Clears fSaveLayerFlags.
1903
1904#Return empty SaveLayerRec ##
1905
1906#Example
1907 SkCanvas::SaveLayerRec rec1;
1908 rec1.fSaveLayerFlags = SkCanvas::kIsOpaque_SaveLayerFlag;
1909 SkCanvas::SaveLayerRec rec2(nullptr, nullptr, SkCanvas::kIsOpaque_SaveLayerFlag);
1910 SkDebugf("rec1 %c= rec2\n", rec1.fBounds == rec2.fBounds
1911 && rec1.fPaint == rec2.fPaint
1912 && rec1.fBackdrop == rec2.fBackdrop
1913 && rec1.fSaveLayerFlags == rec2.fSaveLayerFlags ? '=' : '!');
1914 #StdOut
1915 rec1 == rec2
1916 ##
1917##
1918
Cary Clark2ade9972017-11-02 17:49:34 -04001919#SeeAlso save() restore() saveLayer saveLayerPreserveLCDTextRequests saveLayerAlpha
1920
Cary Clarkce101242017-09-01 15:51:02 -04001921##
1922
1923#Method SaveLayerRec(const SkRect* bounds, const SkPaint* paint, SaveLayerFlags saveLayerFlags = 0)
1924
1925Sets fBounds, fPaint, and fSaveLayerFlags; sets fBackdrop to nullptr.
1926
1927#Param bounds Layer dimensions; may be nullptr ##
1928#Param paint applied to Layer when overlaying prior Layer; may be nullptr ##
1929#Param saveLayerFlags SaveLayerRec options to modify Layer ##
1930
1931#Return SaveLayerRec with empty backdrop ##
1932
1933#Example
1934 SkCanvas::SaveLayerRec rec1;
1935 SkCanvas::SaveLayerRec rec2(nullptr, nullptr);
1936 SkDebugf("rec1 %c= rec2\n", rec1.fBounds == rec2.fBounds
1937 && rec1.fPaint == rec2.fPaint
1938 && rec1.fBackdrop == rec2.fBackdrop
1939 && rec1.fSaveLayerFlags == rec2.fSaveLayerFlags ? '=' : '!');
1940 #StdOut
1941 rec1 == rec2
1942 ##
1943##
1944
Cary Clark2ade9972017-11-02 17:49:34 -04001945#SeeAlso save() restore() saveLayer saveLayerPreserveLCDTextRequests saveLayerAlpha
1946
Cary Clarkce101242017-09-01 15:51:02 -04001947##
1948
1949#Method SaveLayerRec(const SkRect* bounds, const SkPaint* paint, const SkImageFilter* backdrop,
1950 SaveLayerFlags saveLayerFlags)
1951
1952Sets fBounds, fPaint, fBackdrop, and fSaveLayerFlags.
1953
1954#Param bounds Layer dimensions; may be nullptr ##
1955#Param paint applied to Layer when overlaying prior Layer;
1956 may be nullptr
1957##
1958#Param backdrop prior Layer copied with Image_Filter; may be nullptr
1959##
1960#Param saveLayerFlags SaveLayerRec options to modify Layer ##
1961
1962#Return SaveLayerRec fully specified ##
1963
1964#Example
1965 SkCanvas::SaveLayerRec rec1;
1966 SkCanvas::SaveLayerRec rec2(nullptr, nullptr, nullptr, 0);
1967 SkDebugf("rec1 %c= rec2\n", rec1.fBounds == rec2.fBounds
1968 && rec1.fPaint == rec2.fPaint
1969 && rec1.fBackdrop == rec2.fBackdrop
1970 && rec1.fSaveLayerFlags == rec2.fSaveLayerFlags ? '=' : '!');
1971 #StdOut
1972 rec1 == rec2
1973 ##
1974##
1975
Cary Clark2ade9972017-11-02 17:49:34 -04001976#SeeAlso save() restore() saveLayer saveLayerPreserveLCDTextRequests saveLayerAlpha
1977
Cary Clarkce101242017-09-01 15:51:02 -04001978##
1979
1980#Method SaveLayerRec(const SkRect* bounds, const SkPaint* paint, const SkImageFilter* backdrop,
1981 const SkImage* clipMask, const SkMatrix* clipMatrix,
1982 SaveLayerFlags saveLayerFlags)
1983
1984#Experimental
1985Not ready for general use.
1986##
1987
1988Sets fBounds, fPaint, fBackdrop, fClipMask, fClipMatrix, and fSaveLayerFlags.
1989clipMatrix uses Color_Alpha channel of image, transformed by clipMatrix, to clip
1990Layer when drawn to Canvas.
1991
Cary Clark2ade9972017-11-02 17:49:34 -04001992Implementation is not complete; has no effect if Device is GPU-backed.
Cary Clarkce101242017-09-01 15:51:02 -04001993
1994#Param bounds Layer dimensions; may be nullptr ##
1995#Param paint graphics state applied to Layer when overlaying prior
1996 Layer; may be nullptr
1997##
1998#Param backdrop prior Layer copied with Image_Filter;
1999 may be nullptr
2000##
2001#Param clipMask clip applied to Layer; may be nullptr ##
2002#Param clipMatrix matrix applied to clipMask; may be nullptr to use
2003 identity matrix
2004##
2005#Param saveLayerFlags SaveLayerRec options to modify Layer ##
2006
2007#Return SaveLayerRec fully specified ##
2008
Cary Clark2ade9972017-11-02 17:49:34 -04002009#SeeAlso save() restore() saveLayer saveLayerPreserveLCDTextRequests saveLayerAlpha
Cary Clarkce101242017-09-01 15:51:02 -04002010
2011##
2012
2013#Struct ##
2014
2015#Method int saveLayer(const SaveLayerRec& layerRec)
2016
2017Saves Matrix, Clip, and Draw_Filter (Draw_Filter deprecated on most platforms),
2018and allocates Bitmap for subsequent drawing.
2019
2020Calling restore() discards changes to Matrix, Clip, and Draw_Filter,
2021and blends Bitmap with Color_Alpha opacity onto the prior Layer.
2022
2023Matrix may be changed by translate(), scale(), rotate(), skew(), concat(),
2024setMatrix, and resetMatrix. Clip may be changed by clipRect, clipRRect,
2025clipPath, clipRegion.
2026
2027SaveLayerRec contains the state used to create the Layer.
2028
2029Call restoreToCount with returned value to restore this and subsequent saves.
2030
2031#Param layerRec Layer state ##
2032
2033#Return depth of save state stack ##
2034
2035#Example
2036#Description
2037The example draws an image, and saves it into a Layer with kInitWithPrevious_SaveLayerFlag.
2038Next it punches a hole in Layer and restore with SkBlendMode::kPlus.
2039Where Layer was cleared, the original image will draw unchanged.
2040Outside of the circle the mandrill is brightened.
2041##
2042 #Image 3
Hal Canaryc465d132017-12-08 10:21:31 -05002043 // sk_sp<SkImage> image = GetResourceAsImage("images/mandrill_256.png");
Cary Clarkce101242017-09-01 15:51:02 -04002044 canvas->drawImage(image, 0, 0, nullptr);
2045 SkCanvas::SaveLayerRec rec;
2046 SkPaint paint;
2047 paint.setBlendMode(SkBlendMode::kPlus);
2048 rec.fSaveLayerFlags = SkCanvas::kInitWithPrevious_SaveLayerFlag;
2049 rec.fPaint = &paint;
2050 canvas->saveLayer(rec);
2051 paint.setBlendMode(SkBlendMode::kClear);
2052 canvas->drawCircle(128, 128, 96, paint);
2053 canvas->restore();
2054##
2055
2056#ToDo above example needs to replace GetResourceAsImage with way to select image in fiddle ##
2057
Cary Clark2ade9972017-11-02 17:49:34 -04002058#SeeAlso save() restore() saveLayer saveLayerPreserveLCDTextRequests saveLayerAlpha
2059
Cary Clarkce101242017-09-01 15:51:02 -04002060##
2061
2062#Topic Layer ##
2063
2064# ------------------------------------------------------------------------------
Cary Clark8032b982017-07-28 11:04:54 -04002065#Topic Matrix
2066
2067#Method void translate(SkScalar dx, SkScalar dy)
2068
2069Translate Matrix by dx along the x-axis and dy along the y-axis.
2070
2071Mathematically, replace Matrix with a translation matrix
Cary Clarkce101242017-09-01 15:51:02 -04002072Premultiplied with Matrix.
Cary Clark8032b982017-07-28 11:04:54 -04002073
2074This has the effect of moving the drawing by (dx, dy) before transforming
2075the result with Matrix.
2076
Cary Clarkbad5ad72017-08-03 17:14:08 -04002077#Param dx distance to translate in x ##
2078#Param dy distance to translate in y ##
Cary Clark8032b982017-07-28 11:04:54 -04002079
2080#Example
2081#Height 128
2082#Description
2083scale() followed by translate() produces different results from translate() followed
2084by scale().
2085
2086The blue stroke follows translate of (50, 50); a black
2087fill follows scale of (2, 1/2.f). After restoring the clip, which resets
2088Matrix, a red frame follows the same scale of (2, 1/2.f); a gray fill
2089follows translate of (50, 50).
2090##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002091void draw(SkCanvas* canvas) {
2092 SkPaint filledPaint;
2093 SkPaint outlinePaint;
2094 outlinePaint.setStyle(SkPaint::kStroke_Style);
2095 outlinePaint.setColor(SK_ColorBLUE);
2096 canvas->save();
2097 canvas->translate(50, 50);
2098 canvas->drawCircle(28, 28, 15, outlinePaint); // blue center: (50+28, 50+28)
2099 canvas->scale(2, 1/2.f);
2100 canvas->drawCircle(28, 28, 15, filledPaint); // black center: (50+(28*2), 50+(28/2))
2101 canvas->restore();
2102 filledPaint.setColor(SK_ColorGRAY);
2103 outlinePaint.setColor(SK_ColorRED);
2104 canvas->scale(2, 1/2.f);
2105 canvas->drawCircle(28, 28, 15, outlinePaint); // red center: (28*2, 28/2)
2106 canvas->translate(50, 50);
2107 canvas->drawCircle(28, 28, 15, filledPaint); // gray center: ((50+28)*2, (50+28)/2)
Cary Clark8032b982017-07-28 11:04:54 -04002108}
2109##
2110
Cary Clark2ade9972017-11-02 17:49:34 -04002111#SeeAlso concat() scale() skew() rotate() setMatrix
Cary Clark8032b982017-07-28 11:04:54 -04002112
2113##
2114
2115# ------------------------------------------------------------------------------
2116
2117#Method void scale(SkScalar sx, SkScalar sy)
2118
2119Scale Matrix by sx on the x-axis and sy on the y-axis.
2120
2121Mathematically, replace Matrix with a scale matrix
Cary Clarkce101242017-09-01 15:51:02 -04002122Premultiplied with Matrix.
Cary Clark8032b982017-07-28 11:04:54 -04002123
2124This has the effect of scaling the drawing by (sx, sy) before transforming
2125the result with Matrix.
2126
Cary Clarkbad5ad72017-08-03 17:14:08 -04002127#Param sx amount to scale in x ##
2128#Param sy amount to scale in y ##
Cary Clark8032b982017-07-28 11:04:54 -04002129
2130#Example
2131#Height 160
Cary Clarkbad5ad72017-08-03 17:14:08 -04002132void draw(SkCanvas* canvas) {
2133 SkPaint paint;
2134 SkRect rect = { 10, 20, 60, 120 };
2135 canvas->translate(20, 20);
2136 canvas->drawRect(rect, paint);
2137 canvas->scale(2, .5f);
2138 paint.setColor(SK_ColorGRAY);
2139 canvas->drawRect(rect, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002140}
2141##
2142
Cary Clark2ade9972017-11-02 17:49:34 -04002143#SeeAlso concat() translate() skew() rotate() setMatrix
Cary Clark8032b982017-07-28 11:04:54 -04002144
2145##
2146
2147# ------------------------------------------------------------------------------
2148
2149#Method void rotate(SkScalar degrees)
2150
2151Rotate Matrix by degrees. Positive degrees rotates clockwise.
2152
2153Mathematically, replace Matrix with a rotation matrix
Cary Clarkce101242017-09-01 15:51:02 -04002154Premultiplied with Matrix.
Cary Clark8032b982017-07-28 11:04:54 -04002155
2156This has the effect of rotating the drawing by degrees before transforming
2157the result with Matrix.
2158
Cary Clarkbad5ad72017-08-03 17:14:08 -04002159#Param degrees amount to rotate, in degrees ##
Cary Clark8032b982017-07-28 11:04:54 -04002160
2161#Example
2162#Description
2163Draw clock hands at time 5:10. The hour hand and minute hand point up and
2164are rotated clockwise.
2165##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002166void draw(SkCanvas* canvas) {
2167 SkPaint paint;
2168 paint.setStyle(SkPaint::kStroke_Style);
2169 canvas->translate(128, 128);
2170 canvas->drawCircle(0, 0, 60, paint);
2171 canvas->save();
2172 canvas->rotate(10 * 360 / 60); // 10 minutes of 60 scaled to 360 degrees
2173 canvas->drawLine(0, 0, 0, -50, paint);
2174 canvas->restore();
2175 canvas->rotate((5 + 10.f/60) * 360 / 12); // 5 and 10/60 hours of 12 scaled to 360 degrees
2176 canvas->drawLine(0, 0, 0, -30, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002177}
2178##
2179
Cary Clark2ade9972017-11-02 17:49:34 -04002180#SeeAlso concat() translate() skew() scale() setMatrix
Cary Clark8032b982017-07-28 11:04:54 -04002181
2182##
2183
2184# ------------------------------------------------------------------------------
2185
2186#Method void rotate(SkScalar degrees, SkScalar px, SkScalar py)
2187
Cary Clarkbad5ad72017-08-03 17:14:08 -04002188Rotate Matrix by degrees about a point at (px, py). Positive degrees rotates
2189clockwise.
Cary Clark8032b982017-07-28 11:04:54 -04002190
Cary Clarkce101242017-09-01 15:51:02 -04002191Mathematically, construct a rotation matrix. Premultiply the rotation matrix by
Cary Clark8032b982017-07-28 11:04:54 -04002192a translation matrix, then replace Matrix with the resulting matrix
Cary Clarkce101242017-09-01 15:51:02 -04002193Premultiplied with Matrix.
Cary Clark8032b982017-07-28 11:04:54 -04002194
Cary Clarkbad5ad72017-08-03 17:14:08 -04002195This has the effect of rotating the drawing about a given point before
2196transforming the result with Matrix.
Cary Clark8032b982017-07-28 11:04:54 -04002197
Cary Clarkbad5ad72017-08-03 17:14:08 -04002198#Param degrees amount to rotate, in degrees ##
2199#Param px x-coordinate of the point to rotate about ##
2200#Param py y-coordinate of the point to rotate about ##
Cary Clark8032b982017-07-28 11:04:54 -04002201
2202#Example
2203#Height 192
Cary Clarkbad5ad72017-08-03 17:14:08 -04002204void draw(SkCanvas* canvas) {
2205 SkPaint paint;
2206 paint.setTextSize(96);
2207 canvas->drawString("A1", 130, 100, paint);
2208 canvas->rotate(180, 130, 100);
2209 canvas->drawString("A1", 130, 100, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002210}
2211##
2212
Cary Clark2ade9972017-11-02 17:49:34 -04002213#SeeAlso concat() translate() skew() scale() setMatrix
Cary Clark8032b982017-07-28 11:04:54 -04002214
2215##
2216
2217# ------------------------------------------------------------------------------
2218
2219#Method void skew(SkScalar sx, SkScalar sy)
2220
Cary Clarkbad5ad72017-08-03 17:14:08 -04002221Skew Matrix by sx on the x-axis and sy on the y-axis. A positive value of sx
2222skews the drawing right as y increases; a positive value of sy skews the drawing
2223down as x increases.
Cary Clark8032b982017-07-28 11:04:54 -04002224
Cary Clarkce101242017-09-01 15:51:02 -04002225Mathematically, replace Matrix with a skew matrix Premultiplied with Matrix.
Cary Clark8032b982017-07-28 11:04:54 -04002226
Cary Clarkbad5ad72017-08-03 17:14:08 -04002227This has the effect of skewing the drawing by (sx, sy) before transforming
Cary Clark8032b982017-07-28 11:04:54 -04002228the result with Matrix.
2229
Cary Clarkbad5ad72017-08-03 17:14:08 -04002230#Param sx amount to skew in x ##
2231#Param sy amount to skew in y ##
2232
Cary Clark8032b982017-07-28 11:04:54 -04002233#Example
2234 #Description
2235 Black text mimics an oblique text style by using a negative skew in x that
2236 shifts the geometry to the right as the y values decrease.
2237 Red text uses a positive skew in y to shift the geometry down as the x values
2238 increase.
2239 Blue text combines x and y skew to rotate and scale.
2240 ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002241 SkPaint paint;
2242 paint.setTextSize(128);
2243 canvas->translate(30, 130);
2244 canvas->save();
2245 canvas->skew(-.5, 0);
2246 canvas->drawString("A1", 0, 0, paint);
2247 canvas->restore();
2248 canvas->save();
2249 canvas->skew(0, .5);
2250 paint.setColor(SK_ColorRED);
2251 canvas->drawString("A1", 0, 0, paint);
2252 canvas->restore();
2253 canvas->skew(-.5, .5);
2254 paint.setColor(SK_ColorBLUE);
Cary Clark8032b982017-07-28 11:04:54 -04002255 canvas->drawString("A1", 0, 0, paint);
2256##
2257
Cary Clark2ade9972017-11-02 17:49:34 -04002258#SeeAlso concat() translate() rotate() scale() setMatrix
Cary Clark8032b982017-07-28 11:04:54 -04002259
2260##
2261
2262# ------------------------------------------------------------------------------
2263
2264#Method void concat(const SkMatrix& matrix)
2265
Cary Clarkce101242017-09-01 15:51:02 -04002266Replace Matrix with matrix Premultiplied with existing Matrix.
Cary Clark8032b982017-07-28 11:04:54 -04002267
Cary Clarkbad5ad72017-08-03 17:14:08 -04002268This has the effect of transforming the drawn geometry by matrix, before
2269transforming the result with existing Matrix.
Cary Clark8032b982017-07-28 11:04:54 -04002270
Cary Clarkce101242017-09-01 15:51:02 -04002271#Param matrix matrix to Premultiply with existing Matrix ##
Cary Clark8032b982017-07-28 11:04:54 -04002272
2273#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04002274void draw(SkCanvas* canvas) {
2275 SkPaint paint;
2276 paint.setTextSize(80);
2277 paint.setTextScaleX(.3);
2278 SkMatrix matrix;
2279 SkRect rect[2] = {{ 10, 20, 90, 110 }, { 40, 130, 140, 180 }};
2280 matrix.setRectToRect(rect[0], rect[1], SkMatrix::kFill_ScaleToFit);
2281 canvas->drawRect(rect[0], paint);
2282 canvas->drawRect(rect[1], paint);
2283 paint.setColor(SK_ColorWHITE);
2284 canvas->drawString("Here", rect[0].fLeft + 10, rect[0].fBottom - 10, paint);
2285 canvas->concat(matrix);
2286 canvas->drawString("There", rect[0].fLeft + 10, rect[0].fBottom - 10, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002287}
2288##
2289
Cary Clark2ade9972017-11-02 17:49:34 -04002290#SeeAlso translate() rotate() scale() skew() setMatrix
Cary Clark8032b982017-07-28 11:04:54 -04002291
2292##
2293
2294# ------------------------------------------------------------------------------
2295
2296#Method void setMatrix(const SkMatrix& matrix)
2297
2298Replace Matrix with matrix.
2299Unlike concat(), any prior matrix state is overwritten.
2300
Cary Clarkbad5ad72017-08-03 17:14:08 -04002301#Param matrix matrix to copy, replacing existing Matrix ##
Cary Clark8032b982017-07-28 11:04:54 -04002302
2303#Example
2304#Height 128
Cary Clarkbad5ad72017-08-03 17:14:08 -04002305void draw(SkCanvas* canvas) {
2306 SkPaint paint;
2307 canvas->scale(4, 6);
2308 canvas->drawString("truth", 2, 10, paint);
2309 SkMatrix matrix;
2310 matrix.setScale(2.8f, 6);
2311 canvas->setMatrix(matrix);
2312 canvas->drawString("consequences", 2, 20, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002313}
2314##
2315
Cary Clark2ade9972017-11-02 17:49:34 -04002316#SeeAlso resetMatrix concat() translate() rotate() scale() skew()
Cary Clark8032b982017-07-28 11:04:54 -04002317
2318##
2319
2320# ------------------------------------------------------------------------------
2321
2322#Method void resetMatrix()
2323
2324Sets Matrix to the identity matrix.
2325Any prior matrix state is overwritten.
2326
2327#Example
2328#Height 128
Cary Clarkbad5ad72017-08-03 17:14:08 -04002329void draw(SkCanvas* canvas) {
2330 SkPaint paint;
2331 canvas->scale(4, 6);
2332 canvas->drawString("truth", 2, 10, paint);
2333 canvas->resetMatrix();
2334 canvas->scale(2.8f, 6);
2335 canvas->drawString("consequences", 2, 20, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002336}
2337##
2338
Cary Clark2ade9972017-11-02 17:49:34 -04002339#SeeAlso setMatrix concat() translate() rotate() scale() skew()
Cary Clark8032b982017-07-28 11:04:54 -04002340
2341##
2342
2343# ------------------------------------------------------------------------------
2344
2345#Method const SkMatrix& getTotalMatrix() const
2346
2347Returns Matrix.
2348This does not account for translation by Device or Surface.
2349
Cary Clarkbad5ad72017-08-03 17:14:08 -04002350#Return Matrix in Canvas ##
Cary Clark8032b982017-07-28 11:04:54 -04002351
2352#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04002353 SkDebugf("isIdentity %s\n", canvas->getTotalMatrix().isIdentity() ? "true" : "false");
2354 #StdOut
2355 isIdentity true
2356 ##
Cary Clark8032b982017-07-28 11:04:54 -04002357##
2358
Cary Clark2ade9972017-11-02 17:49:34 -04002359#SeeAlso setMatrix resetMatrix concat()
Cary Clark8032b982017-07-28 11:04:54 -04002360
2361##
2362
2363#Topic Matrix ##
2364
2365# ------------------------------------------------------------------------------
2366#Topic Clip
2367
2368Clip is built from a stack of clipping paths. Each Path in the
2369stack can be constructed from one or more Path_Contour elements. The
2370Path_Contour may be composed of any number of Path_Verb segments. Each
2371Path_Contour forms a closed area; Path_Fill_Type defines the area enclosed
2372by Path_Contour.
2373
2374Clip stack of Path elements successfully restrict the Path area. Each
2375Path is transformed by Matrix, then intersected with or subtracted from the
2376prior Clip to form the replacement Clip. Use SkClipOp::kDifference
2377to subtract Path from Clip; use SkClipOp::kIntersect to intersect Path
2378with Clip.
2379
Cary Clarkce101242017-09-01 15:51:02 -04002380A clipping Path may be Anti-aliased; if Path, after transformation, is
Cary Clark8032b982017-07-28 11:04:54 -04002381composed of horizontal and vertical lines, clearing Anti-alias allows whole pixels
Cary Clarkce101242017-09-01 15:51:02 -04002382to either be inside or outside the clip. The fastest drawing has a Aliased,
2383rectangular clip.
Cary Clark8032b982017-07-28 11:04:54 -04002384
2385If clipping Path has Anti-alias set, clip may partially clip a pixel, requiring
2386that drawing blend partially with the destination along the edge. A rotated
Cary Clarkce101242017-09-01 15:51:02 -04002387rectangular Anti-aliased clip looks smoother but draws slower.
Cary Clark8032b982017-07-28 11:04:54 -04002388
2389Clip can combine with Rect and Round_Rect primitives; like
2390Path, these are transformed by Matrix before they are combined with Clip.
2391
2392Clip can combine with Region. Region is assumed to be in Device coordinates
2393and is unaffected by Matrix.
2394
2395#Example
2396#Height 90
2397 #Description
Cary Clarkce101242017-09-01 15:51:02 -04002398 Draw a red circle with an Aliased clip and an Anti-aliased clip.
Cary Clark8032b982017-07-28 11:04:54 -04002399 Use an image filter to zoom into the pixels drawn.
Cary Clarkce101242017-09-01 15:51:02 -04002400 The edge of the Aliased clip fully draws pixels in the red circle.
2401 The edge of the Anti-aliased clip partially draws pixels in the red circle.
Cary Clark8032b982017-07-28 11:04:54 -04002402 ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002403 SkPaint redPaint, scalePaint;
2404 redPaint.setAntiAlias(true);
2405 redPaint.setColor(SK_ColorRED);
2406 canvas->save();
2407 for (bool antialias : { false, true } ) {
2408 canvas->save();
2409 canvas->clipRect(SkRect::MakeWH(19.5f, 11.5f), antialias);
2410 canvas->drawCircle(17, 11, 8, redPaint);
2411 canvas->restore();
2412 canvas->translate(16, 0);
2413 }
2414 canvas->restore();
2415 SkMatrix matrix;
2416 matrix.setScale(6, 6);
2417 scalePaint.setImageFilter(
2418 SkImageFilter::MakeMatrixFilter(matrix, kNone_SkFilterQuality, nullptr));
2419 SkCanvas::SaveLayerRec saveLayerRec(
2420 nullptr, &scalePaint, SkCanvas::kInitWithPrevious_SaveLayerFlag);
2421 canvas->saveLayer(saveLayerRec);
Cary Clark8032b982017-07-28 11:04:54 -04002422 canvas->restore();
2423##
2424
2425#Method void clipRect(const SkRect& rect, SkClipOp op, bool doAntiAlias)
2426
2427Replace Clip with the intersection or difference of Clip and rect,
Cary Clarkce101242017-09-01 15:51:02 -04002428with an Aliased or Anti-aliased clip edge. rect is transformed by Matrix
Cary Clark8032b982017-07-28 11:04:54 -04002429before it is combined with Clip.
2430
Cary Clarka523d2d2017-08-30 08:58:10 -04002431#Param rect Rect to combine with Clip ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002432#Param op Clip_Op to apply to Clip ##
Cary Clarkce101242017-09-01 15:51:02 -04002433#Param doAntiAlias true if Clip is to be Anti-aliased ##
Cary Clark8032b982017-07-28 11:04:54 -04002434
2435#Example
2436#Height 128
Cary Clarkbad5ad72017-08-03 17:14:08 -04002437void draw(SkCanvas* canvas) {
2438 canvas->rotate(10);
2439 SkPaint paint;
2440 paint.setAntiAlias(true);
2441 for (auto alias: { false, true } ) {
2442 canvas->save();
2443 canvas->clipRect(SkRect::MakeWH(90, 80), SkClipOp::kIntersect, alias);
2444 canvas->drawCircle(100, 60, 60, paint);
2445 canvas->restore();
2446 canvas->translate(80, 0);
2447 }
Cary Clark8032b982017-07-28 11:04:54 -04002448}
2449##
2450
Cary Clark2ade9972017-11-02 17:49:34 -04002451#SeeAlso clipRRect clipPath clipRegion
Cary Clark8032b982017-07-28 11:04:54 -04002452
2453##
2454
2455#Method void clipRect(const SkRect& rect, SkClipOp op)
2456
2457Replace Clip with the intersection or difference of Clip and rect.
Cary Clarkce101242017-09-01 15:51:02 -04002458Resulting Clip is Aliased; pixels are fully contained by the clip.
Cary Clarkbad5ad72017-08-03 17:14:08 -04002459rect is transformed by Matrix before it is combined with Clip.
Cary Clark8032b982017-07-28 11:04:54 -04002460
Cary Clarka523d2d2017-08-30 08:58:10 -04002461#Param rect Rect to combine with Clip ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002462#Param op Clip_Op to apply to Clip ##
Cary Clark8032b982017-07-28 11:04:54 -04002463
2464#Example
2465#Height 192
2466#Width 280
Cary Clarkbad5ad72017-08-03 17:14:08 -04002467void draw(SkCanvas* canvas) {
2468 SkPaint paint;
2469 for (SkClipOp op: { SkClipOp::kIntersect, SkClipOp::kDifference } ) {
2470 canvas->save();
2471 canvas->clipRect(SkRect::MakeWH(90, 120), op, false);
2472 canvas->drawCircle(100, 100, 60, paint);
2473 canvas->restore();
2474 canvas->translate(80, 0);
2475 }
Cary Clark8032b982017-07-28 11:04:54 -04002476}
2477##
2478
Cary Clark2ade9972017-11-02 17:49:34 -04002479#SeeAlso clipRRect clipPath clipRegion
Cary Clark8032b982017-07-28 11:04:54 -04002480
2481##
2482
2483#Method void clipRect(const SkRect& rect, bool doAntiAlias = false)
2484
2485Replace Clip with the intersection of Clip and rect.
Cary Clarkce101242017-09-01 15:51:02 -04002486Resulting Clip is Aliased; pixels are fully contained by the clip.
Cary Clark8032b982017-07-28 11:04:54 -04002487rect is transformed by Matrix
2488before it is combined with Clip.
2489
Cary Clarka523d2d2017-08-30 08:58:10 -04002490#Param rect Rect to combine with Clip ##
Cary Clarkce101242017-09-01 15:51:02 -04002491#Param doAntiAlias true if Clip is to be Anti-aliased ##
Cary Clark8032b982017-07-28 11:04:54 -04002492
2493#Example
2494#Height 133
2495 #Description
Cary Clarkce101242017-09-01 15:51:02 -04002496 A circle drawn in pieces looks uniform when drawn Aliased.
2497 The same circle pieces blend with pixels more than once when Anti-aliased,
Cary Clark8032b982017-07-28 11:04:54 -04002498 visible as a thin pair of lines through the right circle.
2499 ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002500void draw(SkCanvas* canvas) {
2501 canvas->clear(SK_ColorWHITE);
2502 SkPaint paint;
2503 paint.setAntiAlias(true);
2504 paint.setColor(0x8055aaff);
2505 SkRect clipRect = { 0, 0, 87.4f, 87.4f };
2506 for (auto alias: { false, true } ) {
2507 canvas->save();
2508 canvas->clipRect(clipRect, SkClipOp::kIntersect, alias);
2509 canvas->drawCircle(67, 67, 60, paint);
2510 canvas->restore();
2511 canvas->save();
2512 canvas->clipRect(clipRect, SkClipOp::kDifference, alias);
2513 canvas->drawCircle(67, 67, 60, paint);
2514 canvas->restore();
2515 canvas->translate(120, 0);
2516 }
Cary Clark8032b982017-07-28 11:04:54 -04002517}
2518##
2519
Cary Clark2ade9972017-11-02 17:49:34 -04002520#SeeAlso clipRRect clipPath clipRegion
Cary Clark8032b982017-07-28 11:04:54 -04002521
2522##
2523
2524#Method void androidFramework_setDeviceClipRestriction(const SkIRect& rect)
2525
Cary Clarkce101242017-09-01 15:51:02 -04002526Sets the maximum clip rectangle, which can be set by clipRect, clipRRect and
Cary Clark8032b982017-07-28 11:04:54 -04002527clipPath and intersect the current clip with the specified rect.
Cary Clarkce101242017-09-01 15:51:02 -04002528The maximum clip affects only future clipping operations; it is not retroactive.
Cary Clark8032b982017-07-28 11:04:54 -04002529The clip restriction is not recorded in pictures.
2530
Cary Clarkce101242017-09-01 15:51:02 -04002531Pass an empty rect to disable maximum clip.
Cary Clarkbad5ad72017-08-03 17:14:08 -04002532
Cary Clark8032b982017-07-28 11:04:54 -04002533#Private
2534This is private API to be used only by Android framework.
2535##
2536
Cary Clarkbad5ad72017-08-03 17:14:08 -04002537#Param rect maximum allowed clip in device coordinates
Cary Clark579985c2017-07-31 11:48:27 -04002538#Param ##
Cary Clark8032b982017-07-28 11:04:54 -04002539
2540##
2541
2542#Method void clipRRect(const SkRRect& rrect, SkClipOp op, bool doAntiAlias)
2543
2544Replace Clip with the intersection or difference of Clip and rrect,
Cary Clarkce101242017-09-01 15:51:02 -04002545with an Aliased or Anti-aliased clip edge.
Cary Clark8032b982017-07-28 11:04:54 -04002546rrect is transformed by Matrix
2547before it is combined with Clip.
2548
Cary Clarkbad5ad72017-08-03 17:14:08 -04002549#Param rrect Round_Rect to combine with Clip ##
2550#Param op Clip_Op to apply to Clip ##
Cary Clarkce101242017-09-01 15:51:02 -04002551#Param doAntiAlias true if Clip is to be Anti-aliased ##
Cary Clark8032b982017-07-28 11:04:54 -04002552
2553#Example
2554#Height 128
Cary Clarkbad5ad72017-08-03 17:14:08 -04002555void draw(SkCanvas* canvas) {
2556 canvas->clear(SK_ColorWHITE);
2557 SkPaint paint;
2558 paint.setAntiAlias(true);
2559 paint.setColor(0x8055aaff);
2560 SkRRect oval;
2561 oval.setOval({10, 20, 90, 100});
2562 canvas->clipRRect(oval, SkClipOp::kIntersect, true);
2563 canvas->drawCircle(70, 100, 60, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002564}
2565##
2566
Cary Clark2ade9972017-11-02 17:49:34 -04002567#SeeAlso clipRect clipPath clipRegion
Cary Clark8032b982017-07-28 11:04:54 -04002568
2569##
2570
2571#Method void clipRRect(const SkRRect& rrect, SkClipOp op)
2572
2573Replace Clip with the intersection or difference of Clip and rrect.
Cary Clarkce101242017-09-01 15:51:02 -04002574Resulting Clip is Aliased; pixels are fully contained by the clip.
Cary Clarkbad5ad72017-08-03 17:14:08 -04002575rrect is transformed by Matrix before it is combined with Clip.
Cary Clark8032b982017-07-28 11:04:54 -04002576
Cary Clarkbad5ad72017-08-03 17:14:08 -04002577#Param rrect Round_Rect to combine with Clip ##
2578#Param op Clip_Op to apply to Clip ##
Cary Clark8032b982017-07-28 11:04:54 -04002579
2580#Example
2581#Height 128
Cary Clarkbad5ad72017-08-03 17:14:08 -04002582void draw(SkCanvas* canvas) {
2583 SkPaint paint;
2584 paint.setColor(0x8055aaff);
2585 auto oval = SkRRect::MakeOval({10, 20, 90, 100});
2586 canvas->clipRRect(oval, SkClipOp::kIntersect);
2587 canvas->drawCircle(70, 100, 60, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002588}
2589##
2590
Cary Clark2ade9972017-11-02 17:49:34 -04002591#SeeAlso clipRect clipPath clipRegion
Cary Clark8032b982017-07-28 11:04:54 -04002592
2593##
2594
2595#Method void clipRRect(const SkRRect& rrect, bool doAntiAlias = false)
2596
2597Replace Clip with the intersection of Clip and rrect,
Cary Clarkce101242017-09-01 15:51:02 -04002598with an Aliased or Anti-aliased clip edge.
Cary Clarkbad5ad72017-08-03 17:14:08 -04002599rrect is transformed by Matrix before it is combined with Clip.
Cary Clark8032b982017-07-28 11:04:54 -04002600
Cary Clarkbad5ad72017-08-03 17:14:08 -04002601#Param rrect Round_Rect to combine with Clip ##
Cary Clarkce101242017-09-01 15:51:02 -04002602#Param doAntiAlias true if Clip is to be Anti-aliased ##
Cary Clark8032b982017-07-28 11:04:54 -04002603
2604#Example
2605#Height 128
Cary Clarkbad5ad72017-08-03 17:14:08 -04002606void draw(SkCanvas* canvas) {
2607 SkPaint paint;
2608 paint.setAntiAlias(true);
2609 auto oval = SkRRect::MakeRectXY({10, 20, 90, 100}, 9, 13);
2610 canvas->clipRRect(oval, true);
2611 canvas->drawCircle(70, 100, 60, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002612}
2613##
2614
Cary Clark2ade9972017-11-02 17:49:34 -04002615#SeeAlso clipRect clipPath clipRegion
Cary Clark8032b982017-07-28 11:04:54 -04002616
2617##
2618
2619#Method void clipPath(const SkPath& path, SkClipOp op, bool doAntiAlias)
2620
2621Replace Clip with the intersection or difference of Clip and path,
Cary Clarkce101242017-09-01 15:51:02 -04002622with an Aliased or Anti-aliased clip edge. Path_Fill_Type determines if path
Cary Clark8032b982017-07-28 11:04:54 -04002623describes the area inside or outside its contours; and if Path_Contour overlaps
2624itself or another Path_Contour, whether the overlaps form part of the area.
Cary Clarkbad5ad72017-08-03 17:14:08 -04002625path is transformed by Matrix before it is combined with Clip.
Cary Clark8032b982017-07-28 11:04:54 -04002626
Cary Clarkbad5ad72017-08-03 17:14:08 -04002627#Param path Path to combine with Clip ##
2628#Param op Clip_Op to apply to Clip ##
Cary Clarkce101242017-09-01 15:51:02 -04002629#Param doAntiAlias true if Clip is to be Anti-aliased ##
Cary Clark8032b982017-07-28 11:04:54 -04002630
2631#Example
2632#Description
2633Top figure uses SkPath::kInverseWinding_FillType and SkClipOp::kDifference;
2634area outside clip is subtracted from circle.
2635
2636Bottom figure uses SkPath::kWinding_FillType and SkClipOp::kIntersect;
2637area inside clip is intersected with circle.
2638##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002639void draw(SkCanvas* canvas) {
2640 SkPaint paint;
2641 paint.setAntiAlias(true);
2642 SkPath path;
2643 path.addRect({20, 30, 100, 110});
2644 path.setFillType(SkPath::kInverseWinding_FillType);
2645 canvas->save();
2646 canvas->clipPath(path, SkClipOp::kDifference, false);
2647 canvas->drawCircle(70, 100, 60, paint);
2648 canvas->restore();
2649 canvas->translate(100, 100);
2650 path.setFillType(SkPath::kWinding_FillType);
2651 canvas->clipPath(path, SkClipOp::kIntersect, false);
2652 canvas->drawCircle(70, 100, 60, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002653}
2654##
2655
Cary Clark2ade9972017-11-02 17:49:34 -04002656#SeeAlso clipRect clipRRect clipRegion
Cary Clark8032b982017-07-28 11:04:54 -04002657
2658##
2659
2660#Method void clipPath(const SkPath& path, SkClipOp op)
2661
2662Replace Clip with the intersection or difference of Clip and path.
Cary Clarkce101242017-09-01 15:51:02 -04002663Resulting Clip is Aliased; pixels are fully contained by the clip.
Cary Clark8032b982017-07-28 11:04:54 -04002664Path_Fill_Type determines if path
2665describes the area inside or outside its contours; and if Path_Contour overlaps
2666itself or another Path_Contour, whether the overlaps form part of the area.
2667path is transformed by Matrix
2668before it is combined with Clip.
2669
Cary Clarkbad5ad72017-08-03 17:14:08 -04002670#Param path Path to combine with Clip ##
2671#Param op Clip_Op to apply to Clip ##
Cary Clark8032b982017-07-28 11:04:54 -04002672
2673#Example
2674#Description
Cary Clarkbc5697d2017-10-04 14:31:33 -04002675Overlapping Rects form a clip. When clip Path_Fill_Type is set to
Cary Clark8032b982017-07-28 11:04:54 -04002676SkPath::kWinding_FillType, the overlap is included. Set to
2677SkPath::kEvenOdd_FillType, the overlap is excluded and forms a hole.
2678##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002679void draw(SkCanvas* canvas) {
2680 SkPaint paint;
2681 paint.setAntiAlias(true);
2682 SkPath path;
2683 path.addRect({20, 15, 100, 95});
2684 path.addRect({50, 65, 130, 135});
2685 path.setFillType(SkPath::kWinding_FillType);
2686 canvas->save();
2687 canvas->clipPath(path, SkClipOp::kIntersect);
2688 canvas->drawCircle(70, 85, 60, paint);
2689 canvas->restore();
2690 canvas->translate(100, 100);
2691 path.setFillType(SkPath::kEvenOdd_FillType);
2692 canvas->clipPath(path, SkClipOp::kIntersect);
2693 canvas->drawCircle(70, 85, 60, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002694}
2695##
2696
Cary Clark2ade9972017-11-02 17:49:34 -04002697#SeeAlso clipRect clipRRect clipRegion
Cary Clark8032b982017-07-28 11:04:54 -04002698
2699##
2700
2701#Method void clipPath(const SkPath& path, bool doAntiAlias = false)
2702
2703Replace Clip with the intersection of Clip and path.
Cary Clarkce101242017-09-01 15:51:02 -04002704Resulting Clip is Aliased; pixels are fully contained by the clip.
Cary Clark8032b982017-07-28 11:04:54 -04002705Path_Fill_Type determines if path
2706describes the area inside or outside its contours; and if Path_Contour overlaps
2707itself or another Path_Contour, whether the overlaps form part of the area.
Cary Clarkbad5ad72017-08-03 17:14:08 -04002708path is transformed by Matrix before it is combined with Clip.
Cary Clark8032b982017-07-28 11:04:54 -04002709
Cary Clarkbad5ad72017-08-03 17:14:08 -04002710#Param path Path to combine with Clip ##
Cary Clarkce101242017-09-01 15:51:02 -04002711#Param doAntiAlias true if Clip is to be Anti-aliased ##
Cary Clark8032b982017-07-28 11:04:54 -04002712
2713#Example
2714#Height 212
2715#Description
Cary Clarkbc5697d2017-10-04 14:31:33 -04002716Clip loops over itself covering its center twice. When clip Path_Fill_Type
Cary Clark8032b982017-07-28 11:04:54 -04002717is set to SkPath::kWinding_FillType, the overlap is included. Set to
2718SkPath::kEvenOdd_FillType, the overlap is excluded and forms a hole.
2719##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002720void draw(SkCanvas* canvas) {
2721 SkPaint paint;
2722 paint.setAntiAlias(true);
2723 SkPath path;
2724 SkPoint poly[] = {{20, 20}, { 80, 20}, { 80, 80}, {40, 80},
2725 {40, 40}, {100, 40}, {100, 100}, {20, 100}};
2726 path.addPoly(poly, SK_ARRAY_COUNT(poly), true);
2727 path.setFillType(SkPath::kWinding_FillType);
2728 canvas->save();
2729 canvas->clipPath(path, SkClipOp::kIntersect);
2730 canvas->drawCircle(50, 50, 45, paint);
2731 canvas->restore();
2732 canvas->translate(100, 100);
2733 path.setFillType(SkPath::kEvenOdd_FillType);
2734 canvas->clipPath(path, SkClipOp::kIntersect);
2735 canvas->drawCircle(50, 50, 45, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002736}
2737##
2738
Cary Clark2ade9972017-11-02 17:49:34 -04002739#SeeAlso clipRect clipRRect clipRegion
Cary Clark8032b982017-07-28 11:04:54 -04002740
2741##
2742
2743# ------------------------------------------------------------------------------
2744
2745#Method void setAllowSimplifyClip(bool allow)
2746
2747#Experimental
2748Only used for testing.
2749##
2750
Cary Clarkce101242017-09-01 15:51:02 -04002751Set to simplify clip stack using PathOps.
Cary Clark8032b982017-07-28 11:04:54 -04002752
2753##
2754
2755# ------------------------------------------------------------------------------
2756
2757#Method void clipRegion(const SkRegion& deviceRgn, SkClipOp op = SkClipOp::kIntersect)
2758
2759Replace Clip with the intersection or difference of Clip and Region deviceRgn.
Cary Clarkce101242017-09-01 15:51:02 -04002760Resulting Clip is Aliased; pixels are fully contained by the clip.
Cary Clark8032b982017-07-28 11:04:54 -04002761deviceRgn is unaffected by Matrix.
2762
Cary Clarkbad5ad72017-08-03 17:14:08 -04002763#Param deviceRgn Region to combine with Clip ##
2764#Param op Clip_Op to apply to Clip ##
Cary Clark8032b982017-07-28 11:04:54 -04002765
2766#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04002767#Description
Cary Clarkce101242017-09-01 15:51:02 -04002768 region is unaffected by canvas rotation; iRect is affected by canvas rotation.
2769 Both clips are Aliased; this is not noticeable on Region clip because it
Cary Clarkbad5ad72017-08-03 17:14:08 -04002770 aligns to pixel boundaries.
2771##
2772void draw(SkCanvas* canvas) {
2773 SkPaint paint;
2774 paint.setAntiAlias(true);
2775 SkIRect iRect = {30, 40, 120, 130 };
2776 SkRegion region(iRect);
2777 canvas->rotate(10);
2778 canvas->save();
2779 canvas->clipRegion(region, SkClipOp::kIntersect);
2780 canvas->drawCircle(50, 50, 45, paint);
2781 canvas->restore();
2782 canvas->translate(100, 100);
2783 canvas->clipRect(SkRect::Make(iRect), SkClipOp::kIntersect);
2784 canvas->drawCircle(50, 50, 45, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002785}
2786##
2787
Cary Clark2ade9972017-11-02 17:49:34 -04002788#SeeAlso clipRect clipRRect clipPath
Cary Clark8032b982017-07-28 11:04:54 -04002789
2790##
2791
2792#Method bool quickReject(const SkRect& rect) const
2793
2794Return true if Rect rect, transformed by Matrix, can be quickly determined to be
2795outside of Clip. May return false even though rect is outside of Clip.
2796
2797Use to check if an area to be drawn is clipped out, to skip subsequent draw calls.
2798
Cary Clarkbad5ad72017-08-03 17:14:08 -04002799#Param rect Rect to compare with Clip ##
Cary Clark8032b982017-07-28 11:04:54 -04002800
Cary Clarkbad5ad72017-08-03 17:14:08 -04002801#Return true if rect, transformed by Matrix, does not intersect Clip ##
Cary Clark8032b982017-07-28 11:04:54 -04002802
2803#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04002804void draw(SkCanvas* canvas) {
2805 SkRect testRect = {30, 30, 120, 129 };
2806 SkRect clipRect = {30, 130, 120, 230 };
2807 canvas->save();
2808 canvas->clipRect(clipRect);
2809 SkDebugf("quickReject %s\n", canvas->quickReject(testRect) ? "true" : "false");
2810 canvas->restore();
2811 canvas->rotate(10);
2812 canvas->clipRect(clipRect);
2813 SkDebugf("quickReject %s\n", canvas->quickReject(testRect) ? "true" : "false");
Cary Clark8032b982017-07-28 11:04:54 -04002814}
2815 #StdOut
Cary Clarkbad5ad72017-08-03 17:14:08 -04002816 quickReject true
Cary Clark8032b982017-07-28 11:04:54 -04002817 quickReject false
2818 ##
2819##
2820
Cary Clark2ade9972017-11-02 17:49:34 -04002821#SeeAlso getLocalClipBounds getTotalMatrix SkBitmap::drawsNothing
Cary Clark8032b982017-07-28 11:04:54 -04002822
2823##
2824
2825#Method bool quickReject(const SkPath& path) const
2826
2827Return true if path, transformed by Matrix, can be quickly determined to be
2828outside of Clip. May return false even though path is outside of Clip.
2829
2830Use to check if an area to be drawn is clipped out, to skip subsequent draw calls.
2831
Cary Clarkbad5ad72017-08-03 17:14:08 -04002832#Param path Path to compare with Clip ##
Cary Clark8032b982017-07-28 11:04:54 -04002833
Cary Clarkbad5ad72017-08-03 17:14:08 -04002834#Return true if path, transformed by Matrix, does not intersect Clip ##
Cary Clark8032b982017-07-28 11:04:54 -04002835
2836#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04002837void draw(SkCanvas* canvas) {
2838 SkPoint testPoints[] = {{30, 30}, {120, 30}, {120, 129} };
2839 SkPoint clipPoints[] = {{30, 130}, {120, 130}, {120, 230} };
2840 SkPath testPath, clipPath;
2841 testPath.addPoly(testPoints, SK_ARRAY_COUNT(testPoints), true);
2842 clipPath.addPoly(clipPoints, SK_ARRAY_COUNT(clipPoints), true);
2843 canvas->save();
2844 canvas->clipPath(clipPath);
2845 SkDebugf("quickReject %s\n", canvas->quickReject(testPath) ? "true" : "false");
2846 canvas->restore();
2847 canvas->rotate(10);
2848 canvas->clipPath(clipPath);
2849 SkDebugf("quickReject %s\n", canvas->quickReject(testPath) ? "true" : "false");
Cary Clark8032b982017-07-28 11:04:54 -04002850 #StdOut
Cary Clarkbad5ad72017-08-03 17:14:08 -04002851 quickReject true
Cary Clark8032b982017-07-28 11:04:54 -04002852 quickReject false
2853 ##
2854}
2855##
2856
Cary Clark2ade9972017-11-02 17:49:34 -04002857#SeeAlso getLocalClipBounds getTotalMatrix SkBitmap::drawsNothing
Cary Clark8032b982017-07-28 11:04:54 -04002858
2859##
2860
2861#Method SkRect getLocalClipBounds() const
2862
2863Return bounds of Clip, transformed by inverse of Matrix. If Clip is empty,
2864return SkRect::MakeEmpty, where all Rect sides equal zero.
2865
2866Rect returned is outset by one to account for partial pixel coverage if Clip
Cary Clarkce101242017-09-01 15:51:02 -04002867is Anti-aliased.
Cary Clark8032b982017-07-28 11:04:54 -04002868
Cary Clarkbad5ad72017-08-03 17:14:08 -04002869#Return bounds of Clip in local coordinates ##
Cary Clark8032b982017-07-28 11:04:54 -04002870
2871#Example
2872 #Description
2873 Initial bounds is device bounds outset by 1 on all sides.
2874 Clipped bounds is clipPath bounds outset by 1 on all sides.
2875 Scaling the canvas by two in x and y scales the local bounds by 1/2 in x and y.
2876 ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002877 SkCanvas local(256, 256);
2878 canvas = &local;
2879 SkRect bounds = canvas->getLocalClipBounds();
2880 SkDebugf("left:%g top:%g right:%g bottom:%g\n",
2881 bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom);
2882 SkPoint clipPoints[] = {{30, 130}, {120, 130}, {120, 230} };
2883 SkPath clipPath;
2884 clipPath.addPoly(clipPoints, SK_ARRAY_COUNT(clipPoints), true);
2885 canvas->clipPath(clipPath);
2886 bounds = canvas->getLocalClipBounds();
2887 SkDebugf("left:%g top:%g right:%g bottom:%g\n",
2888 bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom);
2889 canvas->scale(2, 2);
2890 bounds = canvas->getLocalClipBounds();
2891 SkDebugf("left:%g top:%g right:%g bottom:%g\n",
2892 bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom);
2893 #StdOut
2894 left:-1 top:-1 right:257 bottom:257
2895 left:29 top:129 right:121 bottom:231
2896 left:14.5 top:64.5 right:60.5 bottom:115.5
2897 ##
Cary Clark8032b982017-07-28 11:04:54 -04002898##
2899
2900# local canvas in example works around bug in fiddle ##
2901#Bug 6524 ##
Cary Clark2ade9972017-11-02 17:49:34 -04002902#SeeAlso getDeviceClipBounds getBaseLayerSize quickReject
Cary Clark8032b982017-07-28 11:04:54 -04002903
2904##
2905
2906#Method bool getLocalClipBounds(SkRect* bounds) const
2907
2908Return bounds of Clip, transformed by inverse of Matrix. If Clip is empty,
2909return false, and set bounds to SkRect::MakeEmpty, where all Rect sides equal zero.
2910
2911bounds is outset by one to account for partial pixel coverage if Clip
Cary Clarkce101242017-09-01 15:51:02 -04002912is Anti-aliased.
Cary Clark8032b982017-07-28 11:04:54 -04002913
Cary Clarkbad5ad72017-08-03 17:14:08 -04002914#Param bounds Rect of Clip in local coordinates ##
Cary Clark8032b982017-07-28 11:04:54 -04002915
Cary Clarkbad5ad72017-08-03 17:14:08 -04002916#Return true if Clip bounds is not empty ##
Cary Clark8032b982017-07-28 11:04:54 -04002917
2918#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04002919 void draw(SkCanvas* canvas) {
2920 SkCanvas local(256, 256);
2921 canvas = &local;
2922 SkRect bounds;
2923 SkDebugf("local bounds empty = %s\n", canvas->getLocalClipBounds(&bounds)
2924 ? "false" : "true");
2925 SkPath path;
2926 canvas->clipPath(path);
2927 SkDebugf("local bounds empty = %s\n", canvas->getLocalClipBounds(&bounds)
2928 ? "false" : "true");
Cary Clark8032b982017-07-28 11:04:54 -04002929 }
2930 #StdOut
Cary Clarkbad5ad72017-08-03 17:14:08 -04002931 local bounds empty = false
Cary Clark8032b982017-07-28 11:04:54 -04002932 local bounds empty = true
2933 ##
2934##
2935
2936# local canvas in example works around bug in fiddle ##
2937#Bug 6524 ##
Cary Clark2ade9972017-11-02 17:49:34 -04002938#SeeAlso getDeviceClipBounds getBaseLayerSize quickReject
Cary Clark8032b982017-07-28 11:04:54 -04002939
2940##
2941
2942#Method SkIRect getDeviceClipBounds() const
2943
2944Return IRect bounds of Clip, unaffected by Matrix. If Clip is empty,
2945return SkRect::MakeEmpty, where all Rect sides equal zero.
2946
2947Unlike getLocalClipBounds, returned IRect is not outset.
2948
Cary Clarkbad5ad72017-08-03 17:14:08 -04002949#Return bounds of Clip in Device coordinates ##
Cary Clark8032b982017-07-28 11:04:54 -04002950
2951#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04002952void draw(SkCanvas* canvas) {
2953 #Description
Cary Clark8032b982017-07-28 11:04:54 -04002954 Initial bounds is device bounds, not outset.
2955 Clipped bounds is clipPath bounds, not outset.
2956 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 -04002957 ##
2958 SkCanvas device(256, 256);
2959 canvas = &device;
2960 SkIRect bounds = canvas->getDeviceClipBounds();
2961 SkDebugf("left:%d top:%d right:%d bottom:%d\n",
2962 bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom);
2963 SkPoint clipPoints[] = {{30, 130}, {120, 130}, {120, 230} };
2964 SkPath clipPath;
2965 clipPath.addPoly(clipPoints, SK_ARRAY_COUNT(clipPoints), true);
2966 canvas->save();
2967 canvas->clipPath(clipPath);
2968 bounds = canvas->getDeviceClipBounds();
2969 SkDebugf("left:%d top:%d right:%d bottom:%d\n",
2970 bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom);
2971 canvas->restore();
2972 canvas->scale(1.f/2, 1.f/2);
2973 canvas->clipPath(clipPath);
2974 bounds = canvas->getDeviceClipBounds();
2975 SkDebugf("left:%d top:%d right:%d bottom:%d\n",
2976 bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom);
Cary Clark8032b982017-07-28 11:04:54 -04002977 #StdOut
Cary Clarkbad5ad72017-08-03 17:14:08 -04002978 left:0 top:0 right:256 bottom:256
2979 left:30 top:130 right:120 bottom:230
Cary Clark8032b982017-07-28 11:04:54 -04002980 left:15 top:65 right:60 bottom:115
2981 ##
2982}
2983##
2984
2985#ToDo some confusion on why with an identity Matrix local and device are different ##
Cary Clark2ade9972017-11-02 17:49:34 -04002986#SeeAlso getLocalClipBounds getBaseLayerSize quickReject
Cary Clark8032b982017-07-28 11:04:54 -04002987
2988# device canvas in example works around bug in fiddle ##
2989#Bug 6524 ##
2990
2991##
2992
2993#Method bool getDeviceClipBounds(SkIRect* bounds) const
2994
2995Return IRect bounds of Clip, unaffected by Matrix. If Clip is empty,
2996return false, and set bounds to SkRect::MakeEmpty, where all Rect sides equal zero.
2997
2998Unlike getLocalClipBounds, bounds is not outset.
2999
Cary Clarkbad5ad72017-08-03 17:14:08 -04003000#Param bounds Rect of Clip in device coordinates ##
Cary Clark8032b982017-07-28 11:04:54 -04003001
Cary Clarkbad5ad72017-08-03 17:14:08 -04003002#Return true if Clip bounds is not empty ##
Cary Clark8032b982017-07-28 11:04:54 -04003003
3004#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003005 void draw(SkCanvas* canvas) {
3006 SkIRect bounds;
3007 SkDebugf("device bounds empty = %s\n", canvas->getDeviceClipBounds(&bounds)
3008 ? "false" : "true");
3009 SkPath path;
3010 canvas->clipPath(path);
3011 SkDebugf("device bounds empty = %s\n", canvas->getDeviceClipBounds(&bounds)
3012 ? "false" : "true");
Cary Clark8032b982017-07-28 11:04:54 -04003013 }
3014 #StdOut
Cary Clarkbad5ad72017-08-03 17:14:08 -04003015 device bounds empty = false
Cary Clark8032b982017-07-28 11:04:54 -04003016 device bounds empty = true
3017 ##
3018##
3019
Cary Clark2ade9972017-11-02 17:49:34 -04003020#SeeAlso getLocalClipBounds getBaseLayerSize quickReject
Cary Clark8032b982017-07-28 11:04:54 -04003021
3022##
3023
3024#Topic Clip ##
3025
3026# ------------------------------------------------------------------------------
3027
3028#Method void drawColor(SkColor color, SkBlendMode mode = SkBlendMode::kSrcOver)
3029
3030Fill Clip with Color color.
3031mode determines how Color_ARGB is combined with destination.
3032
Cary Clarkbad5ad72017-08-03 17:14:08 -04003033#Param color Unpremultiplied Color_ARGB ##
3034#Param mode SkBlendMode used to combine source color and destination ##
Cary Clark8032b982017-07-28 11:04:54 -04003035
3036#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003037 canvas->drawColor(SK_ColorRED);
3038 canvas->clipRect(SkRect::MakeWH(150, 150));
3039 canvas->drawColor(SkColorSetARGB(0x80, 0x00, 0xFF, 0x00), SkBlendMode::kPlus);
3040 canvas->clipRect(SkRect::MakeWH(75, 75));
3041 canvas->drawColor(SkColorSetARGB(0x80, 0x00, 0x00, 0xFF), SkBlendMode::kPlus);
Cary Clark8032b982017-07-28 11:04:54 -04003042##
3043
Cary Clark2ade9972017-11-02 17:49:34 -04003044#SeeAlso clear SkBitmap::erase drawPaint
Cary Clark8032b982017-07-28 11:04:54 -04003045
3046##
3047
3048# ------------------------------------------------------------------------------
3049
3050#Method void clear(SkColor color)
3051
3052Fill Clip with Color color using SkBlendMode::kSrc.
3053This has the effect of replacing all pixels contained by Clip with color.
3054
Cary Clarkbad5ad72017-08-03 17:14:08 -04003055#Param color Unpremultiplied Color_ARGB ##
Cary Clark8032b982017-07-28 11:04:54 -04003056
3057#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003058void draw(SkCanvas* canvas) {
3059 canvas->save();
3060 canvas->clipRect(SkRect::MakeWH(256, 128));
3061 canvas->clear(SkColorSetARGB(0x80, 0xFF, 0x00, 0x00));
3062 canvas->restore();
3063 canvas->save();
3064 canvas->clipRect(SkRect::MakeWH(150, 192));
3065 canvas->clear(SkColorSetARGB(0x80, 0x00, 0xFF, 0x00));
3066 canvas->restore();
3067 canvas->clipRect(SkRect::MakeWH(75, 256));
3068 canvas->clear(SkColorSetARGB(0x80, 0x00, 0x00, 0xFF));
Cary Clark8032b982017-07-28 11:04:54 -04003069}
3070##
3071
Cary Clark2ade9972017-11-02 17:49:34 -04003072#SeeAlso drawColor SkBitmap::erase drawPaint
Cary Clark8032b982017-07-28 11:04:54 -04003073
3074##
3075
3076# ------------------------------------------------------------------------------
3077
3078#Method void discard()
3079
3080Make Canvas contents undefined. Subsequent calls that read Canvas pixels,
3081such as drawing with SkBlendMode, return undefined results. discard() does
3082not change Clip or Matrix.
3083
3084discard() may do nothing, depending on the implementation of Surface or Device
3085that created Canvas.
3086
3087discard() allows optimized performance on subsequent draws by removing
3088cached data associated with Surface or Device.
3089It is not necessary to call discard() once done with Canvas;
3090any cached data is deleted when owning Surface or Device is deleted.
3091
3092#ToDo example? not sure how to make this meaningful w/o more implementation detail ##
Cary Clark2ade9972017-11-02 17:49:34 -04003093#SeeAlso flush() SkSurface::prepareForExternalIO GrContext::abandonContext
Cary Clark8032b982017-07-28 11:04:54 -04003094
3095#NoExample
3096##
3097
3098##
3099
3100# ------------------------------------------------------------------------------
3101
3102#Method void drawPaint(const SkPaint& paint)
3103
Mike Reed8ad91a92018-01-19 19:09:32 -05003104Fill Clip with Paint paint. Paint components Mask_Filter, Shader,
Cary Clarkbad5ad72017-08-03 17:14:08 -04003105Color_Filter, Image_Filter, and Blend_Mode affect drawing;
3106Path_Effect in paint is ignored.
Cary Clark8032b982017-07-28 11:04:54 -04003107
3108# can Path_Effect in paint ever alter drawPaint?
3109
Cary Clarkbad5ad72017-08-03 17:14:08 -04003110#Param paint graphics state used to fill Canvas ##
Cary Clark8032b982017-07-28 11:04:54 -04003111
3112#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003113void draw(SkCanvas* canvas) {
3114 SkColor colors[] = { SK_ColorRED, SK_ColorGREEN, SK_ColorBLUE };
3115 SkScalar pos[] = { 0, SK_Scalar1/2, SK_Scalar1 };
3116 SkPaint paint;
3117 paint.setShader(SkGradientShader::MakeSweep(256, 256, colors, pos, SK_ARRAY_COUNT(colors)));
3118 canvas->drawPaint(paint);
Cary Clark8032b982017-07-28 11:04:54 -04003119}
3120##
3121
Cary Clark2ade9972017-11-02 17:49:34 -04003122#SeeAlso clear drawColor SkBitmap::erase
Cary Clark8032b982017-07-28 11:04:54 -04003123
3124##
3125
3126# ------------------------------------------------------------------------------
3127
3128#Enum PointMode
3129
3130#Code
3131 enum PointMode {
3132 kPoints_PointMode,
3133 kLines_PointMode,
Cary Clarkd0530ba2017-09-14 11:25:39 -04003134 kPolygon_PointMode,
Cary Clark8032b982017-07-28 11:04:54 -04003135 };
3136##
3137
3138Selects if an array of points are drawn as discrete points, as lines, or as
3139an open polygon.
3140
3141#Const kPoints_PointMode 0
3142 Draw each point separately.
3143##
3144
3145#Const kLines_PointMode 1
3146 Draw each pair of points as a line segment.
3147##
3148
3149#Const kPolygon_PointMode 2
3150 Draw the array of points as a open polygon.
3151##
3152
3153#Example
3154 #Description
3155 The upper left corner shows three squares when drawn as points.
3156 The upper right corner shows one line; when drawn as lines, two points are required per line.
3157 The lower right corner shows two lines; when draw as polygon, no miter is drawn at the corner.
3158 The lower left corner shows two lines with a miter when path contains polygon.
3159 ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003160void draw(SkCanvas* canvas) {
3161 SkPaint paint;
3162 paint.setStyle(SkPaint::kStroke_Style);
3163 paint.setStrokeWidth(10);
3164 SkPoint points[] = {{64, 32}, {96, 96}, {32, 96}};
3165 canvas->drawPoints(SkCanvas::kPoints_PointMode, 3, points, paint);
3166 canvas->translate(128, 0);
3167 canvas->drawPoints(SkCanvas::kLines_PointMode, 3, points, paint);
3168 canvas->translate(0, 128);
3169 canvas->drawPoints(SkCanvas::kPolygon_PointMode, 3, points, paint);
3170 SkPath path;
3171 path.addPoly(points, 3, false);
3172 canvas->translate(-128, 0);
3173 canvas->drawPath(path, paint);
Cary Clark8032b982017-07-28 11:04:54 -04003174}
3175##
3176
Cary Clark2ade9972017-11-02 17:49:34 -04003177#SeeAlso drawLine drawPoint drawPath
Cary Clark8032b982017-07-28 11:04:54 -04003178
3179##
3180
3181# ------------------------------------------------------------------------------
3182
3183#Method void drawPoints(PointMode mode, size_t count, const SkPoint pts[], const SkPaint& paint)
3184
3185Draw pts using Clip, Matrix and Paint paint.
Cary Clarkbad5ad72017-08-03 17:14:08 -04003186count is the number of points; if count is less than one, has no effect.
Cary Clark8032b982017-07-28 11:04:54 -04003187mode may be one of: kPoints_PointMode, kLines_PointMode, or kPolygon_PointMode.
3188
Cary Clarkbad5ad72017-08-03 17:14:08 -04003189If mode is kPoints_PointMode, the shape of point drawn depends on paint
3190Paint_Stroke_Cap. If paint is set to SkPaint::kRound_Cap, each point draws a
3191circle of diameter Paint_Stroke_Width. If paint is set to SkPaint::kSquare_Cap
3192or SkPaint::kButt_Cap, each point draws a square of width and height
3193Paint_Stroke_Width.
Cary Clark8032b982017-07-28 11:04:54 -04003194
3195If mode is kLines_PointMode, each pair of points draws a line segment.
3196One line is drawn for every two points; each point is used once. If count is odd,
3197the final point is ignored.
3198
3199If mode is kPolygon_PointMode, each adjacent pair of points draws a line segment.
3200count minus one lines are drawn; the first and last point are used once.
3201
3202Each line segment respects paint Paint_Stroke_Cap and Paint_Stroke_Width.
3203Paint_Style is ignored, as if were set to SkPaint::kStroke_Style.
3204
Cary Clarkbad5ad72017-08-03 17:14:08 -04003205Always draws each element one at a time; is not affected by
3206Paint_Stroke_Join, and unlike drawPath, does not create a mask from all points
3207and lines before drawing.
Cary Clark8032b982017-07-28 11:04:54 -04003208
Cary Clarka523d2d2017-08-30 08:58:10 -04003209#Param mode whether pts draws points or lines ##
3210#Param count number of points in the array ##
3211#Param pts array of points to draw ##
3212#Param paint stroke, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003213
3214#Example
3215#Height 200
3216 #Description
3217 #List
3218 # The first column draws points. ##
3219 # The second column draws points as lines. ##
3220 # The third column draws points as a polygon. ##
3221 # The fourth column draws points as a polygonal path. ##
3222 # The first row uses a round cap and round join. ##
3223 # The second row uses a square cap and a miter join. ##
3224 # The third row uses a butt cap and a bevel join. ##
3225 ##
3226 The transparent color makes multiple line draws visible;
3227 the path is drawn all at once.
3228 ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003229void draw(SkCanvas* canvas) {
3230 SkPaint paint;
3231 paint.setAntiAlias(true);
3232 paint.setStyle(SkPaint::kStroke_Style);
3233 paint.setStrokeWidth(10);
3234 paint.setColor(0x80349a45);
3235 const SkPoint points[] = {{32, 16}, {48, 48}, {16, 32}};
3236 const SkPaint::Join join[] = { SkPaint::kRound_Join,
3237 SkPaint::kMiter_Join,
3238 SkPaint::kBevel_Join };
3239 int joinIndex = 0;
3240 SkPath path;
3241 path.addPoly(points, 3, false);
3242 for (const auto cap : { SkPaint::kRound_Cap, SkPaint::kSquare_Cap, SkPaint::kButt_Cap } ) {
3243 paint.setStrokeCap(cap);
3244 paint.setStrokeJoin(join[joinIndex++]);
3245 for (const auto mode : { SkCanvas::kPoints_PointMode,
3246 SkCanvas::kLines_PointMode,
3247 SkCanvas::kPolygon_PointMode } ) {
3248 canvas->drawPoints(mode, 3, points, paint);
3249 canvas->translate(64, 0);
3250 }
3251 canvas->drawPath(path, paint);
3252 canvas->translate(-192, 64);
3253 }
Cary Clark8032b982017-07-28 11:04:54 -04003254}
3255##
3256
Cary Clark2ade9972017-11-02 17:49:34 -04003257#SeeAlso drawLine drawPoint drawPath
Cary Clark8032b982017-07-28 11:04:54 -04003258
3259##
3260
3261# ------------------------------------------------------------------------------
3262
3263#Method void drawPoint(SkScalar x, SkScalar y, const SkPaint& paint)
3264
3265Draw point at (x, y) using Clip, Matrix and Paint paint.
3266
3267The shape of point drawn depends on paint Paint_Stroke_Cap.
Cary Clarkbad5ad72017-08-03 17:14:08 -04003268If paint is set to SkPaint::kRound_Cap, draw a circle of diameter
3269Paint_Stroke_Width. If paint is set to SkPaint::kSquare_Cap or SkPaint::kButt_Cap,
Cary Clark8032b982017-07-28 11:04:54 -04003270draw a square of width and height Paint_Stroke_Width.
3271Paint_Style is ignored, as if were set to SkPaint::kStroke_Style.
3272
Cary Clarkbad5ad72017-08-03 17:14:08 -04003273#Param x left edge of circle or square ##
3274#Param y top edge of circle or square ##
3275#Param paint stroke, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003276
3277#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003278void draw(SkCanvas* canvas) {
3279 SkPaint paint;
3280 paint.setAntiAlias(true);
3281 paint.setColor(0x80349a45);
3282 paint.setStyle(SkPaint::kStroke_Style);
3283 paint.setStrokeWidth(100);
3284 paint.setStrokeCap(SkPaint::kRound_Cap);
3285 canvas->scale(1, 1.2f);
3286 canvas->drawPoint(64, 96, paint);
3287 canvas->scale(.6f, .8f);
3288 paint.setColor(SK_ColorWHITE);
3289 canvas->drawPoint(106, 120, paint);
Cary Clark8032b982017-07-28 11:04:54 -04003290}
3291##
3292
Cary Clark2ade9972017-11-02 17:49:34 -04003293#SeeAlso drawPoints drawCircle drawRect drawLine drawPath
Cary Clark8032b982017-07-28 11:04:54 -04003294
3295##
3296
Cary Clarkbad5ad72017-08-03 17:14:08 -04003297#Method void drawPoint(SkPoint p, const SkPaint& paint)
3298
3299Draw point p using Clip, Matrix and Paint paint.
3300
3301The shape of point drawn depends on paint Paint_Stroke_Cap.
3302If paint is set to SkPaint::kRound_Cap, draw a circle of diameter
3303Paint_Stroke_Width. If paint is set to SkPaint::kSquare_Cap or SkPaint::kButt_Cap,
3304draw a square of width and height Paint_Stroke_Width.
3305Paint_Style is ignored, as if were set to SkPaint::kStroke_Style.
3306
3307#Param p top-left edge of circle or square ##
3308#Param paint stroke, blend, color, and so on, used to draw ##
3309
3310#Example
3311void draw(SkCanvas* canvas) {
3312 SkPaint paint;
3313 paint.setAntiAlias(true);
3314 paint.setColor(0x80349a45);
3315 paint.setStyle(SkPaint::kStroke_Style);
3316 paint.setStrokeWidth(100);
3317 paint.setStrokeCap(SkPaint::kSquare_Cap);
3318 canvas->scale(1, 1.2f);
3319 canvas->drawPoint({64, 96}, paint);
3320 canvas->scale(.6f, .8f);
3321 paint.setColor(SK_ColorWHITE);
3322 canvas->drawPoint(106, 120, paint);
3323}
3324##
3325
Cary Clark2ade9972017-11-02 17:49:34 -04003326#SeeAlso drawPoints drawCircle drawRect drawLine drawPath
Cary Clarkbad5ad72017-08-03 17:14:08 -04003327
3328##
3329
Cary Clark8032b982017-07-28 11:04:54 -04003330# ------------------------------------------------------------------------------
3331
3332#Method void drawLine(SkScalar x0, SkScalar y0, SkScalar x1, SkScalar y1, const SkPaint& paint)
3333
Cary Clarkbad5ad72017-08-03 17:14:08 -04003334Draws line segment from (x0, y0) to (x1, y1) using Clip, Matrix, and Paint paint.
3335In paint: Paint_Stroke_Width describes the line thickness;
3336Paint_Stroke_Cap draws the end rounded or square;
Cary Clark8032b982017-07-28 11:04:54 -04003337Paint_Style is ignored, as if were set to SkPaint::kStroke_Style.
3338
Cary Clarkbad5ad72017-08-03 17:14:08 -04003339#Param x0 start of line segment on x-axis ##
3340#Param y0 start of line segment on y-axis ##
3341#Param x1 end of line segment on x-axis ##
3342#Param y1 end of line segment on y-axis ##
3343#Param paint stroke, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003344
3345#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003346 SkPaint paint;
3347 paint.setAntiAlias(true);
3348 paint.setColor(0xFF9a67be);
3349 paint.setStrokeWidth(20);
3350 canvas->skew(1, 0);
3351 canvas->drawLine(32, 96, 32, 160, paint);
3352 canvas->skew(-2, 0);
3353 canvas->drawLine(288, 96, 288, 160, paint);
3354##
3355
Cary Clark2ade9972017-11-02 17:49:34 -04003356#SeeAlso drawPoint drawCircle drawRect drawPath
Cary Clarkbad5ad72017-08-03 17:14:08 -04003357
3358##
3359
3360#Method void drawLine(SkPoint p0, SkPoint p1, const SkPaint& paint)
3361
3362Draws line segment from p0 to p1 using Clip, Matrix, and Paint paint.
3363In paint: Paint_Stroke_Width describes the line thickness;
3364Paint_Stroke_Cap draws the end rounded or square;
3365Paint_Style is ignored, as if were set to SkPaint::kStroke_Style.
3366
3367#Param p0 start of line segment ##
3368#Param p1 end of line segment ##
3369#Param paint stroke, blend, color, and so on, used to draw ##
3370
3371#Example
3372 SkPaint paint;
3373 paint.setAntiAlias(true);
3374 paint.setColor(0xFF9a67be);
3375 paint.setStrokeWidth(20);
3376 canvas->skew(1, 0);
3377 canvas->drawLine({32, 96}, {32, 160}, paint);
3378 canvas->skew(-2, 0);
3379 canvas->drawLine({288, 96}, {288, 160}, paint);
Cary Clark8032b982017-07-28 11:04:54 -04003380##
3381
Cary Clark2ade9972017-11-02 17:49:34 -04003382#SeeAlso drawPoint drawCircle drawRect drawPath
Cary Clark8032b982017-07-28 11:04:54 -04003383
3384##
3385
3386# ------------------------------------------------------------------------------
3387
3388#Method void drawRect(const SkRect& rect, const SkPaint& paint)
3389
3390Draw Rect rect using Clip, Matrix, and Paint paint.
3391In paint: Paint_Style determines if rectangle is stroked or filled;
3392if stroked, Paint_Stroke_Width describes the line thickness, and
3393Paint_Stroke_Join draws the corners rounded or square.
3394
Cary Clarkbc5697d2017-10-04 14:31:33 -04003395#Param rect rectangle to draw ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003396#Param paint stroke or fill, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003397
3398#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003399void draw(SkCanvas* canvas) {
3400 SkPoint rectPts[] = { {64, 48}, {192, 160} };
3401 SkPaint paint;
3402 paint.setAntiAlias(true);
3403 paint.setStyle(SkPaint::kStroke_Style);
3404 paint.setStrokeWidth(20);
3405 paint.setStrokeJoin(SkPaint::kRound_Join);
3406 SkMatrix rotator;
3407 rotator.setRotate(30, 128, 128);
3408 for (auto color : { SK_ColorRED, SK_ColorBLUE, SK_ColorYELLOW, SK_ColorMAGENTA } ) {
3409 paint.setColor(color);
3410 SkRect rect;
3411 rect.set(rectPts[0], rectPts[1]);
3412 canvas->drawRect(rect, paint);
3413 rotator.mapPoints(rectPts, 2);
3414 }
Cary Clark8032b982017-07-28 11:04:54 -04003415}
3416##
3417
Cary Clark2ade9972017-11-02 17:49:34 -04003418#SeeAlso drawIRect drawRRect drawRoundRect drawRegion drawPath drawLine
Cary Clark8032b982017-07-28 11:04:54 -04003419
3420##
3421
3422# ------------------------------------------------------------------------------
3423
3424#Method void drawIRect(const SkIRect& rect, const SkPaint& paint)
3425
3426Draw IRect rect using Clip, Matrix, and Paint paint.
3427In paint: Paint_Style determines if rectangle is stroked or filled;
3428if stroked, Paint_Stroke_Width describes the line thickness, and
3429Paint_Stroke_Join draws the corners rounded or square.
3430
Cary Clarkbc5697d2017-10-04 14:31:33 -04003431#Param rect rectangle to draw ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003432#Param paint stroke or fill, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003433
3434#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003435 SkIRect rect = { 64, 48, 192, 160 };
3436 SkPaint paint;
3437 paint.setAntiAlias(true);
3438 paint.setStyle(SkPaint::kStroke_Style);
3439 paint.setStrokeWidth(20);
3440 paint.setStrokeJoin(SkPaint::kRound_Join);
3441 for (auto color : { SK_ColorRED, SK_ColorBLUE, SK_ColorYELLOW, SK_ColorMAGENTA } ) {
3442 paint.setColor(color);
3443 canvas->drawIRect(rect, paint);
3444 canvas->rotate(30, 128, 128);
3445 }
Cary Clark8032b982017-07-28 11:04:54 -04003446##
3447
Cary Clark2ade9972017-11-02 17:49:34 -04003448#SeeAlso drawRect drawRRect drawRoundRect drawRegion drawPath drawLine
Cary Clark8032b982017-07-28 11:04:54 -04003449
3450##
3451
3452# ------------------------------------------------------------------------------
3453
3454#Method void drawRegion(const SkRegion& region, const SkPaint& paint)
3455
3456Draw Region region using Clip, Matrix, and Paint paint.
3457In paint: Paint_Style determines if rectangle is stroked or filled;
3458if stroked, Paint_Stroke_Width describes the line thickness, and
3459Paint_Stroke_Join draws the corners rounded or square.
3460
Cary Clarkbc5697d2017-10-04 14:31:33 -04003461#Param region region to draw ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003462#Param paint Paint stroke or fill, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003463
3464#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003465void draw(SkCanvas* canvas) {
3466 SkRegion region;
3467 region.op( 10, 10, 50, 50, SkRegion::kUnion_Op);
3468 region.op( 10, 50, 90, 90, SkRegion::kUnion_Op);
3469 SkPaint paint;
3470 paint.setAntiAlias(true);
3471 paint.setStyle(SkPaint::kStroke_Style);
3472 paint.setStrokeWidth(20);
3473 paint.setStrokeJoin(SkPaint::kRound_Join);
3474 canvas->drawRegion(region, paint);
Cary Clark8032b982017-07-28 11:04:54 -04003475}
3476##
3477
Cary Clark2ade9972017-11-02 17:49:34 -04003478#SeeAlso drawRect drawIRect drawPath
Cary Clark8032b982017-07-28 11:04:54 -04003479
3480##
3481
3482# ------------------------------------------------------------------------------
3483
3484#Method void drawOval(const SkRect& oval, const SkPaint& paint)
3485
3486Draw Oval oval using Clip, Matrix, and Paint.
3487In paint: Paint_Style determines if Oval is stroked or filled;
3488if stroked, Paint_Stroke_Width describes the line thickness.
3489
Cary Clarkbad5ad72017-08-03 17:14:08 -04003490#Param oval Rect bounds of Oval ##
3491#Param paint Paint stroke or fill, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003492
3493#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003494void draw(SkCanvas* canvas) {
3495 canvas->clear(0xFF3f5f9f);
3496 SkColor kColor1 = SkColorSetARGB(0xff, 0xff, 0x7f, 0);
3497 SkColor g1Colors[] = { kColor1, SkColorSetA(kColor1, 0x20) };
3498 SkPoint g1Points[] = { { 0, 0 }, { 0, 100 } };
3499 SkScalar pos[] = { 0.2f, 1.0f };
3500 SkRect bounds = SkRect::MakeWH(80, 70);
3501 SkPaint paint;
3502 paint.setAntiAlias(true);
3503 paint.setShader(SkGradientShader::MakeLinear(g1Points, g1Colors, pos, SK_ARRAY_COUNT(g1Colors),
3504 SkShader::kClamp_TileMode));
3505 canvas->drawOval(bounds , paint);
Cary Clark8032b982017-07-28 11:04:54 -04003506}
3507##
3508
Cary Clark2ade9972017-11-02 17:49:34 -04003509#SeeAlso drawCircle drawPoint drawPath drawRRect drawRoundRect
Cary Clark8032b982017-07-28 11:04:54 -04003510
3511##
3512
3513# ------------------------------------------------------------------------------
3514
3515#Method void drawRRect(const SkRRect& rrect, const SkPaint& paint)
3516
3517Draw Round_Rect rrect using Clip, Matrix, and Paint paint.
3518In paint: Paint_Style determines if rrect is stroked or filled;
3519if stroked, Paint_Stroke_Width describes the line thickness.
3520
Cary Clarkbad5ad72017-08-03 17:14:08 -04003521rrect may represent a rectangle, circle, oval, uniformly rounded rectangle, or
3522may have any combination of positive non-square radii for the four corners.
Cary Clark8032b982017-07-28 11:04:54 -04003523
Cary Clarkbad5ad72017-08-03 17:14:08 -04003524#Param rrect Round_Rect with up to eight corner radii to draw ##
3525#Param paint Paint stroke or fill, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003526
3527#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003528void draw(SkCanvas* canvas) {
3529 SkPaint paint;
3530 paint.setAntiAlias(true);
3531 SkRect outer = {30, 40, 210, 220};
3532 SkRect radii = {30, 50, 70, 90 };
3533 SkRRect rRect;
3534 rRect.setNinePatch(outer, radii.fLeft, radii.fTop, radii.fRight, radii.fBottom);
3535 canvas->drawRRect(rRect, paint);
3536 paint.setColor(SK_ColorWHITE);
3537 canvas->drawLine(outer.fLeft + radii.fLeft, outer.fTop,
3538 outer.fLeft + radii.fLeft, outer.fBottom, paint);
3539 canvas->drawLine(outer.fRight - radii.fRight, outer.fTop,
3540 outer.fRight - radii.fRight, outer.fBottom, paint);
3541 canvas->drawLine(outer.fLeft, outer.fTop + radii.fTop,
3542 outer.fRight, outer.fTop + radii.fTop, paint);
3543 canvas->drawLine(outer.fLeft, outer.fBottom - radii.fBottom,
3544 outer.fRight, outer.fBottom - radii.fBottom, paint);
3545}
Cary Clark8032b982017-07-28 11:04:54 -04003546##
3547
Cary Clark2ade9972017-11-02 17:49:34 -04003548#SeeAlso drawRect drawRoundRect drawDRRect drawCircle drawOval drawPath
Cary Clark8032b982017-07-28 11:04:54 -04003549
3550##
3551
3552# ------------------------------------------------------------------------------
3553
3554#Method void drawDRRect(const SkRRect& outer, const SkRRect& inner, const SkPaint& paint)
3555
3556Draw Round_Rect outer and inner
3557using Clip, Matrix, and Paint paint.
3558outer must contain inner or the drawing is undefined.
Cary Clarkce101242017-09-01 15:51:02 -04003559In paint: Paint_Style determines if Round_Rect is stroked or filled;
Cary Clark8032b982017-07-28 11:04:54 -04003560if stroked, Paint_Stroke_Width describes the line thickness.
Cary Clarkbad5ad72017-08-03 17:14:08 -04003561If stroked and Round_Rect corner has zero length radii, Paint_Stroke_Join can
3562draw corners rounded or square.
Cary Clark8032b982017-07-28 11:04:54 -04003563
Cary Clarkbad5ad72017-08-03 17:14:08 -04003564GPU-backed platforms optimize drawing when both outer and inner are
Cary Clark8032b982017-07-28 11:04:54 -04003565concave and outer contains inner. These platforms may not be able to draw
3566Path built with identical data as fast.
3567
Cary Clarkbad5ad72017-08-03 17:14:08 -04003568#Param outer Round_Rect outer bounds to draw ##
3569#Param inner Round_Rect inner bounds to draw ##
3570#Param paint Paint stroke or fill, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003571
3572#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003573void draw(SkCanvas* canvas) {
3574 SkRRect outer = SkRRect::MakeRect({20, 40, 210, 200});
3575 SkRRect inner = SkRRect::MakeOval({60, 70, 170, 160});
3576 SkPaint paint;
3577 canvas->drawDRRect(outer, inner, paint);
Cary Clark8032b982017-07-28 11:04:54 -04003578}
3579##
3580
3581#Example
3582#Description
3583 Outer Rect has no corner radii, but stroke join is rounded.
3584 Inner Round_Rect has corner radii; outset stroke increases radii of corners.
3585 Stroke join does not affect inner Round_Rect since it has no sharp corners.
3586##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003587void draw(SkCanvas* canvas) {
3588 SkRRect outer = SkRRect::MakeRect({20, 40, 210, 200});
3589 SkRRect inner = SkRRect::MakeRectXY({60, 70, 170, 160}, 10, 10);
3590 SkPaint paint;
3591 paint.setAntiAlias(true);
3592 paint.setStyle(SkPaint::kStroke_Style);
3593 paint.setStrokeWidth(20);
3594 paint.setStrokeJoin(SkPaint::kRound_Join);
3595 canvas->drawDRRect(outer, inner, paint);
3596 paint.setStrokeWidth(1);
3597 paint.setColor(SK_ColorWHITE);
3598 canvas->drawDRRect(outer, inner, paint);
Cary Clark8032b982017-07-28 11:04:54 -04003599}
3600##
3601
Cary Clark2ade9972017-11-02 17:49:34 -04003602#SeeAlso drawRect drawRoundRect drawRRect drawCircle drawOval drawPath
Cary Clark8032b982017-07-28 11:04:54 -04003603
3604##
3605
3606# ------------------------------------------------------------------------------
3607
3608#Method void drawCircle(SkScalar cx, SkScalar cy, SkScalar radius, const SkPaint& paint)
3609
3610Draw Circle at (cx, cy) with radius using Clip, Matrix, and Paint paint.
3611If radius is zero or less, nothing is drawn.
3612In paint: Paint_Style determines if Circle is stroked or filled;
3613if stroked, Paint_Stroke_Width describes the line thickness.
3614
Cary Clarkbad5ad72017-08-03 17:14:08 -04003615#Param cx Circle center on the x-axis ##
3616#Param cy Circle center on the y-axis ##
3617#Param radius half the diameter of Circle ##
3618#Param paint Paint stroke or fill, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003619
3620#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003621 void draw(SkCanvas* canvas) {
3622 SkPaint paint;
3623 paint.setAntiAlias(true);
3624 canvas->drawCircle(128, 128, 90, paint);
3625 paint.setColor(SK_ColorWHITE);
3626 canvas->drawCircle(86, 86, 20, paint);
3627 canvas->drawCircle(160, 76, 20, paint);
3628 canvas->drawCircle(140, 150, 35, paint);
3629 }
3630##
3631
Cary Clark2ade9972017-11-02 17:49:34 -04003632#SeeAlso drawOval drawRRect drawRoundRect drawPath drawArc drawPoint drawLine
Cary Clarkbad5ad72017-08-03 17:14:08 -04003633
3634##
3635
3636#Method void drawCircle(SkPoint center, SkScalar radius, const SkPaint& paint)
3637
Cary Clarkce101242017-09-01 15:51:02 -04003638Draw Circle at center with radius using Clip, Matrix, and Paint paint.
Cary Clarkbad5ad72017-08-03 17:14:08 -04003639If radius is zero or less, nothing is drawn.
3640In paint: Paint_Style determines if Circle is stroked or filled;
3641if stroked, Paint_Stroke_Width describes the line thickness.
3642
3643#Param center Circle center ##
3644#Param radius half the diameter of Circle ##
3645#Param paint Paint stroke or fill, blend, color, and so on, used to draw ##
3646
3647#Example
3648 void draw(SkCanvas* canvas) {
3649 SkPaint paint;
3650 paint.setAntiAlias(true);
3651 canvas->drawCircle(128, 128, 90, paint);
3652 paint.setColor(SK_ColorWHITE);
3653 canvas->drawCircle({86, 86}, 20, paint);
3654 canvas->drawCircle({160, 76}, 20, paint);
3655 canvas->drawCircle({140, 150}, 35, paint);
3656 }
Cary Clark8032b982017-07-28 11:04:54 -04003657##
3658
Cary Clark2ade9972017-11-02 17:49:34 -04003659#SeeAlso drawOval drawRRect drawRoundRect drawPath drawArc drawPoint drawLine
Cary Clark8032b982017-07-28 11:04:54 -04003660
3661##
3662
3663# ------------------------------------------------------------------------------
3664
3665#Method void drawArc(const SkRect& oval, SkScalar startAngle, SkScalar sweepAngle,
3666 bool useCenter, const SkPaint& paint)
3667
3668Draw Arc using Clip, Matrix, and Paint paint.
Cary Clarkbad5ad72017-08-03 17:14:08 -04003669
Cary Clark8032b982017-07-28 11:04:54 -04003670Arc is part of Oval bounded by oval, sweeping from startAngle to startAngle plus
3671sweepAngle. startAngle and sweepAngle are in degrees.
Cary Clarkbad5ad72017-08-03 17:14:08 -04003672
Cary Clark8032b982017-07-28 11:04:54 -04003673startAngle of zero places start point at the right middle edge of oval.
3674A positive sweepAngle places Arc end point clockwise from start point;
3675a negative sweepAngle places Arc end point counterclockwise from start point.
3676sweepAngle may exceed 360 degrees, a full circle.
3677If useCenter is true, draw a wedge that includes lines from oval
3678center to Arc end points. If useCenter is false, draw Arc between end points.
3679
3680If Rect oval is empty or sweepAngle is zero, nothing is drawn.
3681
Cary Clarkbad5ad72017-08-03 17:14:08 -04003682#Param oval Rect bounds of Oval containing Arc to draw ##
3683#Param startAngle angle in degrees where Arc begins ##
3684#Param sweepAngle sweep angle in degrees; positive is clockwise ##
3685#Param useCenter if true, include the center of the oval ##
3686#Param paint Paint stroke or fill, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003687
3688#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003689 void draw(SkCanvas* canvas) {
3690 SkPaint paint;
3691 paint.setAntiAlias(true);
3692 SkRect oval = { 4, 4, 60, 60};
3693 for (auto useCenter : { false, true } ) {
3694 for (auto style : { SkPaint::kFill_Style, SkPaint::kStroke_Style } ) {
3695 paint.setStyle(style);
3696 for (auto degrees : { 45, 90, 180, 360} ) {
3697 canvas->drawArc(oval, 0, degrees , useCenter, paint);
3698 canvas->translate(64, 0);
3699 }
3700 canvas->translate(-256, 64);
3701 }
3702 }
Cary Clark8032b982017-07-28 11:04:54 -04003703 }
3704##
3705
3706#Example
3707#Height 64
Cary Clarkbad5ad72017-08-03 17:14:08 -04003708 void draw(SkCanvas* canvas) {
3709 SkPaint paint;
3710 paint.setAntiAlias(true);
3711 paint.setStyle(SkPaint::kStroke_Style);
3712 paint.setStrokeWidth(4);
3713 SkRect oval = { 4, 4, 60, 60};
3714 float intervals[] = { 5, 5 };
3715 paint.setPathEffect(SkDashPathEffect::Make(intervals, 2, 2.5f));
3716 for (auto degrees : { 270, 360, 540, 720 } ) {
3717 canvas->drawArc(oval, 0, degrees, false, paint);
3718 canvas->translate(64, 0);
3719 }
Cary Clark8032b982017-07-28 11:04:54 -04003720 }
3721##
3722
Cary Clark2ade9972017-11-02 17:49:34 -04003723#SeeAlso SkPath::arcTo drawCircle drawOval drawPath
Cary Clark8032b982017-07-28 11:04:54 -04003724
3725##
3726
3727# ------------------------------------------------------------------------------
3728
3729#Method void drawRoundRect(const SkRect& rect, SkScalar rx, SkScalar ry, const SkPaint& paint)
3730
Cary Clarkbad5ad72017-08-03 17:14:08 -04003731Draw Round_Rect bounded by Rect rect, with corner radii (rx, ry) using Clip,
3732Matrix, and Paint paint.
3733
Cary Clark8032b982017-07-28 11:04:54 -04003734In paint: Paint_Style determines if Round_Rect is stroked or filled;
3735if stroked, Paint_Stroke_Width describes the line thickness.
3736If rx or ry are less than zero, they are treated as if they are zero.
3737If rx plus ry exceeds rect width or rect height, radii are scaled down to fit.
Cary Clarkbad5ad72017-08-03 17:14:08 -04003738If rx and ry are zero, Round_Rect is drawn as Rect and if stroked is affected by
3739Paint_Stroke_Join.
Cary Clark8032b982017-07-28 11:04:54 -04003740
Cary Clarkbad5ad72017-08-03 17:14:08 -04003741#Param rect Rect bounds of Round_Rect to draw ##
Cary Clarkce101242017-09-01 15:51:02 -04003742#Param rx axis length in x of oval describing rounded corners ##
3743#Param ry axis length in y of oval describing rounded corners ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003744#Param paint stroke, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003745
3746#Example
3747#Description
3748 Top row has a zero radius a generates a rectangle.
3749 Second row radii sum to less than sides.
3750 Third row radii sum equals sides.
3751 Fourth row radii sum exceeds sides; radii are scaled to fit.
3752##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003753 void draw(SkCanvas* canvas) {
3754 SkVector radii[] = { {0, 20}, {10, 10}, {10, 20}, {10, 40} };
3755 SkPaint paint;
3756 paint.setStrokeWidth(15);
3757 paint.setStrokeJoin(SkPaint::kRound_Join);
3758 paint.setAntiAlias(true);
3759 for (auto style : { SkPaint::kStroke_Style, SkPaint::kFill_Style } ) {
3760 paint.setStyle(style );
3761 for (size_t i = 0; i < SK_ARRAY_COUNT(radii); ++i) {
3762 canvas->drawRoundRect({10, 10, 60, 40}, radii[i].fX, radii[i].fY, paint);
3763 canvas->translate(0, 60);
3764 }
3765 canvas->translate(80, -240);
3766 }
Cary Clark8032b982017-07-28 11:04:54 -04003767 }
3768##
3769
Cary Clark2ade9972017-11-02 17:49:34 -04003770#SeeAlso DrawRRect drawRect drawDRRect drawPath drawCircle drawOval drawPoint
Cary Clark8032b982017-07-28 11:04:54 -04003771
3772##
3773
3774# ------------------------------------------------------------------------------
3775
3776#Method void drawPath(const SkPath& path, const SkPaint& paint)
3777
3778Draw Path path using Clip, Matrix, and Paint paint.
3779Path contains an array of Path_Contour, each of which may be open or closed.
3780
3781In paint: Paint_Style determines if Round_Rect is stroked or filled:
Cary Clarkbad5ad72017-08-03 17:14:08 -04003782if filled, Path_Fill_Type determines whether Path_Contour describes inside or
3783outside of fill; if stroked, Paint_Stroke_Width describes the line thickness,
3784Paint_Stroke_Cap describes line ends, and Paint_Stroke_Join describes how
3785corners are drawn.
Cary Clark8032b982017-07-28 11:04:54 -04003786
Cary Clarkbad5ad72017-08-03 17:14:08 -04003787#Param path Path to draw ##
3788#Param paint stroke, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003789
3790#Example
3791#Description
3792 Top rows draw stroked path with combinations of joins and caps. The open contour
3793 is affected by caps; the closed contour is affected by joins.
3794 Bottom row draws fill the same for open and closed contour.
3795 First bottom column shows winding fills overlap.
3796 Second bottom column shows even odd fills exclude overlap.
3797 Third bottom column shows inverse winding fills area outside both contours.
3798##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003799void draw(SkCanvas* canvas) {
3800 SkPath path;
3801 path.moveTo(20, 20);
3802 path.quadTo(60, 20, 60, 60);
3803 path.close();
3804 path.moveTo(60, 20);
3805 path.quadTo(60, 60, 20, 60);
3806 SkPaint paint;
3807 paint.setStrokeWidth(10);
3808 paint.setAntiAlias(true);
3809 paint.setStyle(SkPaint::kStroke_Style);
3810 for (auto join: { SkPaint::kBevel_Join, SkPaint::kRound_Join, SkPaint::kMiter_Join } ) {
3811 paint.setStrokeJoin(join);
3812 for (auto cap: { SkPaint::kButt_Cap, SkPaint::kSquare_Cap, SkPaint::kRound_Cap } ) {
3813 paint.setStrokeCap(cap);
3814 canvas->drawPath(path, paint);
3815 canvas->translate(80, 0);
3816 }
3817 canvas->translate(-240, 60);
3818 }
3819 paint.setStyle(SkPaint::kFill_Style);
3820 for (auto fill : { SkPath::kWinding_FillType,
3821 SkPath::kEvenOdd_FillType,
3822 SkPath::kInverseWinding_FillType } ) {
3823 path.setFillType(fill);
3824 canvas->save();
3825 canvas->clipRect({0, 10, 80, 70});
3826 canvas->drawPath(path, paint);
3827 canvas->restore();
3828 canvas->translate(80, 0);
3829 }
Cary Clark8032b982017-07-28 11:04:54 -04003830}
3831##
3832
Cary Clark2ade9972017-11-02 17:49:34 -04003833#SeeAlso SkPath drawLine drawArc drawRect drawPoints
Cary Clark8032b982017-07-28 11:04:54 -04003834
3835##
3836
3837# ------------------------------------------------------------------------------
3838#Topic Draw_Image
3839
Cary Clarkbad5ad72017-08-03 17:14:08 -04003840drawImage, drawImageRect, and drawImageNine can be called with a bare pointer or
3841a smart pointer as a convenience. The pairs of calls are otherwise identical.
Cary Clark8032b982017-07-28 11:04:54 -04003842
Cary Clark73fa9722017-08-29 17:36:51 -04003843#Method void drawImage(const SkImage* image, SkScalar left, SkScalar top, const SkPaint* paint = nullptr)
Cary Clark8032b982017-07-28 11:04:54 -04003844
3845Draw Image image, with its top-left corner at (left, top),
3846using Clip, Matrix, and optional Paint paint.
3847
Cary Clarkbad5ad72017-08-03 17:14:08 -04003848If paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter, Blend_Mode,
3849and Draw_Looper. If image is kAlpha_8_SkColorType, apply Shader.
3850If paint contains Mask_Filter, generate mask from image bounds. If generated
3851mask extends beyond image bounds, replicate image edge colors, just as Shader
3852made from SkImage::makeShader with SkShader::kClamp_TileMode set replicates the
Cary Clarkbc5697d2017-10-04 14:31:33 -04003853image edge color when it samples outside of its bounds.
Cary Clark8032b982017-07-28 11:04:54 -04003854
Cary Clarkbad5ad72017-08-03 17:14:08 -04003855#Param image uncompressed rectangular map of pixels ##
3856#Param left left side of image ##
3857#Param top top side of image ##
3858#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
3859 and so on; or nullptr
3860##
Cary Clark8032b982017-07-28 11:04:54 -04003861
3862#Example
3863#Height 64
3864#Image 4
Cary Clarkbad5ad72017-08-03 17:14:08 -04003865void draw(SkCanvas* canvas) {
3866 // sk_sp<SkImage> image;
3867 SkImage* imagePtr = image.get();
3868 canvas->drawImage(imagePtr, 0, 0);
3869 SkPaint paint;
3870 canvas->drawImage(imagePtr, 80, 0, &paint);
3871 paint.setAlpha(0x80);
3872 canvas->drawImage(imagePtr, 160, 0, &paint);
Cary Clark8032b982017-07-28 11:04:54 -04003873}
3874##
3875
Cary Clark2ade9972017-11-02 17:49:34 -04003876#SeeAlso drawBitmap drawImageLattice drawImageNine drawImageRect SkPaint::setImageFilter
Cary Clark8032b982017-07-28 11:04:54 -04003877
3878##
3879
3880# ------------------------------------------------------------------------------
3881
3882#Method void drawImage(const sk_sp<SkImage>& image, SkScalar left, SkScalar top,
Cary Clark73fa9722017-08-29 17:36:51 -04003883 const SkPaint* paint = nullptr)
Cary Clark8032b982017-07-28 11:04:54 -04003884
3885Draw Image image, with its top-left corner at (left, top),
3886using Clip, Matrix, and optional Paint paint.
3887
Cary Clarkbad5ad72017-08-03 17:14:08 -04003888If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
3889Blend_Mode, and Draw_Looper. If image is kAlpha_8_SkColorType, apply Shader.
3890If paint contains Mask_Filter, generate mask from image bounds. If generated
3891mask extends beyond image bounds, replicate image edge colors, just as Shader
3892made from SkImage::makeShader with SkShader::kClamp_TileMode set replicates the
Cary Clarkbc5697d2017-10-04 14:31:33 -04003893image edge color when it samples outside of its bounds.
Cary Clark8032b982017-07-28 11:04:54 -04003894
Cary Clarkbad5ad72017-08-03 17:14:08 -04003895#Param image uncompressed rectangular map of pixels ##
3896#Param left left side of image ##
3897#Param top pop side of image ##
3898#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
3899 and so on; or nullptr
3900##
Cary Clark8032b982017-07-28 11:04:54 -04003901
3902#Example
3903#Height 64
3904#Image 4
Cary Clarkbad5ad72017-08-03 17:14:08 -04003905void draw(SkCanvas* canvas) {
3906 // sk_sp<SkImage> image;
3907 canvas->drawImage(image, 0, 0);
3908 SkPaint paint;
3909 canvas->drawImage(image, 80, 0, &paint);
3910 paint.setAlpha(0x80);
3911 canvas->drawImage(image, 160, 0, &paint);
Cary Clark8032b982017-07-28 11:04:54 -04003912}
3913##
3914
Cary Clark2ade9972017-11-02 17:49:34 -04003915#SeeAlso drawBitmap drawImageLattice drawImageNine drawImageRect SkPaint::setImageFilter
Cary Clark8032b982017-07-28 11:04:54 -04003916
3917##
3918
3919# ------------------------------------------------------------------------------
3920
3921#Enum SrcRectConstraint
3922
3923#Code
3924 enum SrcRectConstraint {
3925 kStrict_SrcRectConstraint,
3926 kFast_SrcRectConstraint,
3927 };
3928##
3929
Cary Clarkce101242017-09-01 15:51:02 -04003930SrcRectConstraint controls the behavior at the edge of source Rect,
3931provided to drawImageRect, trading off speed for precision.
Cary Clark8032b982017-07-28 11:04:54 -04003932
Cary Clarkce101242017-09-01 15:51:02 -04003933Image_Filter in Paint may sample multiple pixels in the image. Source Rect
Cary Clarkbad5ad72017-08-03 17:14:08 -04003934restricts the bounds of pixels that may be read. Image_Filter may slow down if
Cary Clarkce101242017-09-01 15:51:02 -04003935it cannot read outside the bounds, when sampling near the edge of source Rect.
Cary Clark8032b982017-07-28 11:04:54 -04003936SrcRectConstraint specifies whether an Image_Filter is allowed to read pixels
Cary Clarkce101242017-09-01 15:51:02 -04003937outside source Rect.
Cary Clark8032b982017-07-28 11:04:54 -04003938
3939#Const kStrict_SrcRectConstraint
Cary Clarkce101242017-09-01 15:51:02 -04003940 Requires Image_Filter to respect source Rect,
Cary Clark8032b982017-07-28 11:04:54 -04003941 sampling only inside of its bounds, possibly with a performance penalty.
3942##
3943
3944#Const kFast_SrcRectConstraint
Cary Clarkce101242017-09-01 15:51:02 -04003945 Permits Image_Filter to sample outside of source Rect
Cary Clark8032b982017-07-28 11:04:54 -04003946 by half the width of Image_Filter, permitting it to run faster but with
3947 error at the image edges.
3948##
3949
3950#Example
3951#Height 64
3952#Description
3953 redBorder contains a black and white checkerboard bordered by red.
3954 redBorder is drawn scaled by 16 on the left.
Cary Clarkce101242017-09-01 15:51:02 -04003955 The middle and right bitmaps are filtered checkerboards.
Cary Clark8032b982017-07-28 11:04:54 -04003956 Drawing the checkerboard with kStrict_SrcRectConstraint shows only a blur of black and white.
3957 Drawing the checkerboard with kFast_SrcRectConstraint allows red to bleed in the corners.
3958##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003959void draw(SkCanvas* canvas) {
3960 SkBitmap redBorder;
3961 redBorder.allocPixels(SkImageInfo::MakeN32Premul(4, 4));
3962 SkCanvas checkRed(redBorder);
3963 checkRed.clear(SK_ColorRED);
3964 uint32_t checkers[][2] = { { SK_ColorBLACK, SK_ColorWHITE },
3965 { SK_ColorWHITE, SK_ColorBLACK } };
3966 checkRed.writePixels(
3967 SkImageInfo::MakeN32Premul(2, 2), (void*) checkers, sizeof(checkers[0]), 1, 1);
3968 canvas->scale(16, 16);
3969 canvas->drawBitmap(redBorder, 0, 0, nullptr);
3970 canvas->resetMatrix();
3971 sk_sp<SkImage> image = SkImage::MakeFromBitmap(redBorder);
3972 SkPaint lowPaint;
3973 lowPaint.setFilterQuality(kLow_SkFilterQuality);
3974 for (auto constraint : { SkCanvas::kStrict_SrcRectConstraint,
3975 SkCanvas::kFast_SrcRectConstraint } ) {
3976 canvas->translate(80, 0);
3977 canvas->drawImageRect(image.get(), SkRect::MakeLTRB(1, 1, 3, 3),
3978 SkRect::MakeLTRB(16, 16, 48, 48), &lowPaint, constraint);
3979 }
Cary Clark8032b982017-07-28 11:04:54 -04003980}
3981##
3982
Cary Clark2ade9972017-11-02 17:49:34 -04003983#SeeAlso drawImageRect drawImage SkPaint::setImageFilter
Cary Clark8032b982017-07-28 11:04:54 -04003984
3985##
3986
3987# ------------------------------------------------------------------------------
3988
3989#Method void drawImageRect(const SkImage* image, const SkRect& src, const SkRect& dst,
3990 const SkPaint* paint,
3991 SrcRectConstraint constraint = kStrict_SrcRectConstraint)
3992
3993Draw Rect src of Image image, scaled and translated to fill Rect dst.
3994Additionally transform draw using Clip, Matrix, and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04003995
Cary Clarkbad5ad72017-08-03 17:14:08 -04003996If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
3997Blend_Mode, and Draw_Looper. If image is kAlpha_8_SkColorType, apply Shader.
3998If paint contains Mask_Filter, generate mask from image bounds.
3999
4000If generated mask extends beyond image bounds, replicate image edge colors, just
4001as Shader made from SkImage::makeShader with SkShader::kClamp_TileMode set
Cary Clarkbc5697d2017-10-04 14:31:33 -04004002replicates the image edge color when it samples outside of its bounds.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004003
4004constraint set to kStrict_SrcRectConstraint limits Paint Filter_Quality to
4005sample within src; set to kFast_SrcRectConstraint allows sampling outside to
4006improve performance.
4007
4008#Param image Image containing pixels, dimensions, and format ##
4009#Param src source Rect of image to draw from ##
4010#Param dst destination Rect of image to draw to ##
4011#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4012 and so on; or nullptr
4013##
4014#Param constraint filter strictly within src or draw faster ##
Cary Clark8032b982017-07-28 11:04:54 -04004015
4016#Example
4017#Height 64
4018#Description
4019 The left bitmap draws with Paint default kNone_SkFilterQuality, and stays within
Cary Clarkbc5697d2017-10-04 14:31:33 -04004020 its bounds; there is no bleeding with kFast_SrcRectConstraint.
Cary Clark8032b982017-07-28 11:04:54 -04004021 the middle and right bitmaps draw with kLow_SkFilterQuality; with
4022 kStrict_SrcRectConstraint, the filter remains within the checkerboard, and
4023 with kFast_SrcRectConstraint red bleeds on the edges.
4024##
Cary Clarkbad5ad72017-08-03 17:14:08 -04004025void draw(SkCanvas* canvas) {
4026 uint32_t pixels[][4] = {
4027 { 0xFFFF0000, 0xFFFF0000, 0xFFFF0000, 0xFFFF0000 },
4028 { 0xFFFF0000, 0xFF000000, 0xFFFFFFFF, 0xFFFF0000 },
4029 { 0xFFFF0000, 0xFFFFFFFF, 0xFF000000, 0xFFFF0000 },
4030 { 0xFFFF0000, 0xFFFF0000, 0xFFFF0000, 0xFFFF0000 } };
4031 SkBitmap redBorder;
4032 redBorder.installPixels(SkImageInfo::MakeN32Premul(4, 4),
4033 (void*) pixels, sizeof(pixels[0]));
4034 sk_sp<SkImage> image = SkImage::MakeFromBitmap(redBorder);
4035 SkPaint lowPaint;
4036 for (auto constraint : {
4037 SkCanvas::kFast_SrcRectConstraint,
4038 SkCanvas::kStrict_SrcRectConstraint,
4039 SkCanvas::kFast_SrcRectConstraint } ) {
4040 canvas->drawImageRect(image.get(), SkRect::MakeLTRB(1, 1, 3, 3),
4041 SkRect::MakeLTRB(16, 16, 48, 48), &lowPaint, constraint);
4042 lowPaint.setFilterQuality(kLow_SkFilterQuality);
4043 canvas->translate(80, 0);
4044 }
4045}
Cary Clark8032b982017-07-28 11:04:54 -04004046##
4047
Cary Clark2ade9972017-11-02 17:49:34 -04004048#SeeAlso SrcRectConstraint drawImage drawImageLattice drawImageNine
Cary Clark8032b982017-07-28 11:04:54 -04004049
4050##
4051
4052# ------------------------------------------------------------------------------
4053
4054#Method void drawImageRect(const SkImage* image, const SkIRect& isrc, const SkRect& dst,
4055 const SkPaint* paint, SrcRectConstraint constraint = kStrict_SrcRectConstraint)
4056
4057Draw IRect isrc of Image image, scaled and translated to fill Rect dst.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004058Note that isrc is on integer pixel boundaries; dst may include fractional
4059boundaries. Additionally transform draw using Clip, Matrix, and optional Paint
4060paint.
Cary Clark8032b982017-07-28 11:04:54 -04004061
Cary Clarkbad5ad72017-08-03 17:14:08 -04004062If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4063Blend_Mode, and Draw_Looper. If image is kAlpha_8_SkColorType, apply Shader.
4064If paint contains Mask_Filter, generate mask from image bounds.
4065
4066If generated mask extends beyond image bounds, replicate image edge colors, just
4067as Shader made from SkImage::makeShader with SkShader::kClamp_TileMode set
Cary Clarkbc5697d2017-10-04 14:31:33 -04004068replicates the image edge color when it samples outside of its bounds.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004069
4070constraint set to kStrict_SrcRectConstraint limits Paint Filter_Quality to
Cary Clarkce101242017-09-01 15:51:02 -04004071sample within isrc; set to kFast_SrcRectConstraint allows sampling outside to
Cary Clarkbad5ad72017-08-03 17:14:08 -04004072improve performance.
4073
4074#Param image Image containing pixels, dimensions, and format ##
4075#Param isrc source IRect of image to draw from ##
4076#Param dst destination Rect of image to draw to ##
4077#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4078 and so on; or nullptr
4079##
Cary Clarkce101242017-09-01 15:51:02 -04004080#Param constraint filter strictly within isrc or draw faster ##
Cary Clark8032b982017-07-28 11:04:54 -04004081
4082#Example
4083#Image 4
Cary Clarkbad5ad72017-08-03 17:14:08 -04004084void draw(SkCanvas* canvas) {
4085 // sk_sp<SkImage> image;
4086 for (auto i : { 1, 2, 4, 8 } ) {
4087 canvas->drawImageRect(image.get(), SkIRect::MakeLTRB(0, 0, 100, 100),
4088 SkRect::MakeXYWH(i * 20, i * 20, i * 20, i * 20), nullptr);
4089 }
Cary Clark8032b982017-07-28 11:04:54 -04004090}
4091##
4092
Cary Clark2ade9972017-11-02 17:49:34 -04004093#SeeAlso SrcRectConstraint drawImage drawImageLattice drawImageNine
Cary Clark8032b982017-07-28 11:04:54 -04004094
4095##
4096
4097# ------------------------------------------------------------------------------
4098
4099#Method void drawImageRect(const SkImage* image, const SkRect& dst, const SkPaint* paint,
4100 SrcRectConstraint constraint = kStrict_SrcRectConstraint)
4101
Cary Clarkbad5ad72017-08-03 17:14:08 -04004102Draw Image image, scaled and translated to fill Rect dst, using Clip, Matrix,
4103and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004104
Cary Clarkbad5ad72017-08-03 17:14:08 -04004105If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4106Blend_Mode, and Draw_Looper. If image is kAlpha_8_SkColorType, apply Shader.
4107If paint contains Mask_Filter, generate mask from image bounds.
4108
4109If generated mask extends beyond image bounds, replicate image edge colors, just
4110as Shader made from SkImage::makeShader with SkShader::kClamp_TileMode set
Cary Clarkbc5697d2017-10-04 14:31:33 -04004111replicates the image edge color when it samples outside of its bounds.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004112
4113constraint set to kStrict_SrcRectConstraint limits Paint Filter_Quality to
Cary Clarkce101242017-09-01 15:51:02 -04004114sample within image; set to kFast_SrcRectConstraint allows sampling outside to
Cary Clarkbad5ad72017-08-03 17:14:08 -04004115improve performance.
4116
4117#Param image Image containing pixels, dimensions, and format ##
4118#Param dst destination Rect of image to draw to ##
4119#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4120 and so on; or nullptr
4121##
Cary Clarkce101242017-09-01 15:51:02 -04004122#Param constraint filter strictly within image or draw faster ##
Cary Clark8032b982017-07-28 11:04:54 -04004123
4124#Example
4125#Image 4
Cary Clarkbad5ad72017-08-03 17:14:08 -04004126void draw(SkCanvas* canvas) {
4127 // sk_sp<SkImage> image;
4128 for (auto i : { 20, 40, 80, 160 } ) {
4129 canvas->drawImageRect(image.get(), SkRect::MakeXYWH(i, i, i, i), nullptr);
4130 }
Cary Clark8032b982017-07-28 11:04:54 -04004131}
4132##
4133
Cary Clark2ade9972017-11-02 17:49:34 -04004134#SeeAlso SrcRectConstraint drawImage drawImageLattice drawImageNine
Cary Clark8032b982017-07-28 11:04:54 -04004135
4136##
4137
4138# ------------------------------------------------------------------------------
4139
4140#Method void drawImageRect(const sk_sp<SkImage>& image, const SkRect& src, const SkRect& dst,
4141 const SkPaint* paint,
4142 SrcRectConstraint constraint = kStrict_SrcRectConstraint)
4143
4144Draw Rect src of Image image, scaled and translated to fill Rect dst.
4145Additionally transform draw using Clip, Matrix, and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004146
Cary Clarkbad5ad72017-08-03 17:14:08 -04004147If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4148Blend_Mode, and Draw_Looper. If image is kAlpha_8_SkColorType, apply Shader.
4149If paint contains Mask_Filter, generate mask from image bounds.
4150
4151If generated mask extends beyond image bounds, replicate image edge colors, just
4152as Shader made from SkImage::makeShader with SkShader::kClamp_TileMode set
Cary Clarkbc5697d2017-10-04 14:31:33 -04004153replicates the image edge color when it samples outside of its bounds.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004154
4155constraint set to kStrict_SrcRectConstraint limits Paint Filter_Quality to
4156sample within src; set to kFast_SrcRectConstraint allows sampling outside to
4157improve performance.
4158
4159#Param image Image containing pixels, dimensions, and format ##
4160#Param src source Rect of image to draw from ##
4161#Param dst destination Rect of image to draw to ##
4162#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4163 and so on; or nullptr
4164##
4165#Param constraint filter strictly within src or draw faster ##
Cary Clark8032b982017-07-28 11:04:54 -04004166
4167#Example
4168#Height 64
4169#Description
4170 Canvas scales and translates; transformation from src to dst also scales.
4171 The two matrices are concatenated to create the final transformation.
4172##
Cary Clarkbad5ad72017-08-03 17:14:08 -04004173void draw(SkCanvas* canvas) {
4174 uint32_t pixels[][2] = { { SK_ColorBLACK, SK_ColorWHITE },
4175 { SK_ColorWHITE, SK_ColorBLACK } };
4176 SkBitmap bitmap;
4177 bitmap.installPixels(SkImageInfo::MakeN32Premul(2, 2),
4178 (void*) pixels, sizeof(pixels[0]));
4179 sk_sp<SkImage> image = SkImage::MakeFromBitmap(bitmap);
4180 SkPaint paint;
4181 canvas->scale(4, 4);
4182 for (auto alpha : { 50, 100, 150, 255 } ) {
4183 paint.setAlpha(alpha);
4184 canvas->drawImageRect(image, SkRect::MakeWH(2, 2), SkRect::MakeWH(8, 8), &paint);
4185 canvas->translate(8, 0);
4186 }
4187}
Cary Clark8032b982017-07-28 11:04:54 -04004188##
4189
Cary Clark2ade9972017-11-02 17:49:34 -04004190#SeeAlso SrcRectConstraint drawImage drawImageLattice drawImageNine
Cary Clark8032b982017-07-28 11:04:54 -04004191
4192##
4193
4194# ------------------------------------------------------------------------------
4195
4196#Method void drawImageRect(const sk_sp<SkImage>& image, const SkIRect& isrc, const SkRect& dst,
4197 const SkPaint* paint, SrcRectConstraint constraint = kStrict_SrcRectConstraint)
4198
4199Draw IRect isrc of Image image, scaled and translated to fill Rect dst.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004200isrc is on integer pixel boundaries; dst may include fractional boundaries.
Cary Clark8032b982017-07-28 11:04:54 -04004201Additionally transform draw using Clip, Matrix, and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004202
Cary Clarkbad5ad72017-08-03 17:14:08 -04004203If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4204Blend_Mode, and Draw_Looper. If image is kAlpha_8_SkColorType, apply Shader.
4205If paint contains Mask_Filter, generate mask from image bounds.
4206
4207If generated mask extends beyond image bounds, replicate image edge colors, just
4208as Shader made from SkImage::makeShader with SkShader::kClamp_TileMode set
Cary Clarkbc5697d2017-10-04 14:31:33 -04004209replicates the image edge color when it samples outside of its bounds.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004210
4211constraint set to kStrict_SrcRectConstraint limits Paint Filter_Quality to
Cary Clarkce101242017-09-01 15:51:02 -04004212sample within image; set to kFast_SrcRectConstraint allows sampling outside to
Cary Clarkbad5ad72017-08-03 17:14:08 -04004213improve performance.
4214
4215#Param image Image containing pixels, dimensions, and format ##
4216#Param isrc source IRect of image to draw from ##
4217#Param dst destination Rect of image to draw to ##
4218#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4219 and so on; or nullptr
4220##
Cary Clarkce101242017-09-01 15:51:02 -04004221#Param constraint filter strictly within image or draw faster ##
Cary Clark8032b982017-07-28 11:04:54 -04004222
4223#Example
4224#Height 64
Cary Clarkbad5ad72017-08-03 17:14:08 -04004225void draw(SkCanvas* canvas) {
4226 uint32_t pixels[][2] = { { 0x00000000, 0x55555555},
4227 { 0xAAAAAAAA, 0xFFFFFFFF} };
4228 SkBitmap bitmap;
4229 bitmap.installPixels(SkImageInfo::MakeN32Premul(2, 2),
4230 (void*) pixels, sizeof(pixels[0]));
4231 sk_sp<SkImage> image = SkImage::MakeFromBitmap(bitmap);
4232 SkPaint paint;
4233 canvas->scale(4, 4);
4234 for (auto color : { SK_ColorRED, SK_ColorBLUE, SK_ColorGREEN } ) {
4235 paint.setColorFilter(SkColorFilter::MakeModeFilter(color, SkBlendMode::kPlus));
4236 canvas->drawImageRect(image, SkIRect::MakeWH(2, 2), SkRect::MakeWH(8, 8), &paint);
4237 canvas->translate(8, 0);
4238 }
Cary Clark8032b982017-07-28 11:04:54 -04004239}
4240##
4241
Cary Clark2ade9972017-11-02 17:49:34 -04004242#SeeAlso SrcRectConstraint drawImage drawImageLattice drawImageNine
4243
Cary Clark8032b982017-07-28 11:04:54 -04004244##
4245
4246# ------------------------------------------------------------------------------
4247
4248#Method void drawImageRect(const sk_sp<SkImage>& image, const SkRect& dst, const SkPaint* paint,
4249 SrcRectConstraint constraint = kStrict_SrcRectConstraint)
4250
4251Draw Image image, scaled and translated to fill Rect dst,
4252using Clip, Matrix, and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004253
Cary Clarkbad5ad72017-08-03 17:14:08 -04004254If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4255Blend_Mode, and Draw_Looper. If image is kAlpha_8_SkColorType, apply Shader.
4256If paint contains Mask_Filter, generate mask from image bounds.
4257
4258If generated mask extends beyond image bounds, replicate image edge colors, just
4259as Shader made from SkImage::makeShader with SkShader::kClamp_TileMode set
Cary Clarkbc5697d2017-10-04 14:31:33 -04004260replicates the image edge color when it samples outside of its bounds.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004261
4262constraint set to kStrict_SrcRectConstraint limits Paint Filter_Quality to
Cary Clarkce101242017-09-01 15:51:02 -04004263sample within image; set to kFast_SrcRectConstraint allows sampling outside to
Cary Clarkbad5ad72017-08-03 17:14:08 -04004264improve performance.
4265
4266#Param image Image containing pixels, dimensions, and format ##
4267#Param dst destination Rect of image to draw to ##
4268#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4269 and so on; or nullptr
4270##
Cary Clarkce101242017-09-01 15:51:02 -04004271#Param constraint filter strictly within image or draw faster ##
Cary Clark8032b982017-07-28 11:04:54 -04004272
4273#Example
4274#Height 64
Cary Clarkbad5ad72017-08-03 17:14:08 -04004275void draw(SkCanvas* canvas) {
4276 uint32_t pixels[][2] = { { 0x00000000, 0x55550000},
4277 { 0xAAAA0000, 0xFFFF0000} };
4278 SkBitmap bitmap;
4279 bitmap.installPixels(SkImageInfo::MakeN32Premul(2, 2),
4280 (void*) pixels, sizeof(pixels[0]));
4281 sk_sp<SkImage> image = SkImage::MakeFromBitmap(bitmap);
4282 SkPaint paint;
4283 canvas->scale(4, 4);
4284 for (auto color : { SK_ColorRED, SK_ColorBLUE, SK_ColorGREEN } ) {
4285 paint.setColorFilter(SkColorFilter::MakeModeFilter(color, SkBlendMode::kPlus));
4286 canvas->drawImageRect(image, SkRect::MakeWH(8, 8), &paint);
4287 canvas->translate(8, 0);
4288 }
Cary Clark8032b982017-07-28 11:04:54 -04004289}
4290##
4291
Cary Clark2ade9972017-11-02 17:49:34 -04004292#SeeAlso SrcRectConstraint drawImage drawImageLattice drawImageNine
Cary Clark8032b982017-07-28 11:04:54 -04004293
4294##
4295
4296# ------------------------------------------------------------------------------
4297
4298#Method void drawImageNine(const SkImage* image, const SkIRect& center, const SkRect& dst,
4299 const SkPaint* paint = nullptr)
4300
Cary Clarkd0530ba2017-09-14 11:25:39 -04004301Draw Image image stretched proportionally to fit into Rect dst.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004302IRect center divides the image into nine sections: four sides, four corners, and
Cary Clarkce101242017-09-01 15:51:02 -04004303the center. Corners are unmodified or scaled down proportionately if their sides
Cary Clarkbad5ad72017-08-03 17:14:08 -04004304are larger than dst; center and four sides are scaled to fit remaining space, if any.
Cary Clark8032b982017-07-28 11:04:54 -04004305
Cary Clarkbad5ad72017-08-03 17:14:08 -04004306Additionally transform draw using Clip, Matrix, and optional Paint paint.
4307
4308If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4309Blend_Mode, and Draw_Looper. If image is kAlpha_8_SkColorType, apply Shader.
4310If paint contains Mask_Filter, generate mask from image bounds.
4311
4312If generated mask extends beyond image bounds, replicate image edge colors, just
4313as Shader made from SkImage::makeShader with SkShader::kClamp_TileMode set
Cary Clarkbc5697d2017-10-04 14:31:33 -04004314replicates the image edge color when it samples outside of its bounds.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004315
4316#Param image Image containing pixels, dimensions, and format ##
4317#Param center IRect edge of image corners and sides ##
4318#Param dst destination Rect of image to draw to ##
4319#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4320 and so on; or nullptr
4321##
Cary Clark8032b982017-07-28 11:04:54 -04004322
4323#Example
4324#Height 128
4325#Description
4326 The leftmost image is smaller than center; only corners are drawn, all scaled to fit.
Cary Clarkce101242017-09-01 15:51:02 -04004327 The second image equals the size of center; only corners are drawn without scaling.
4328 The remaining images are larger than center. All corners draw without scaling.
4329 The sides and center are scaled if needed to take up the remaining space.
Cary Clark8032b982017-07-28 11:04:54 -04004330##
Cary Clarkbad5ad72017-08-03 17:14:08 -04004331void draw(SkCanvas* canvas) {
4332 SkIRect center = { 20, 10, 50, 40 };
4333 SkBitmap bitmap;
4334 bitmap.allocPixels(SkImageInfo::MakeN32Premul(60, 60));
4335 SkCanvas bitCanvas(bitmap);
4336 SkPaint paint;
4337 SkColor gray = 0xFF000000;
4338 int left = 0;
4339 for (auto right: { center.fLeft, center.fRight, bitmap.width() } ) {
4340 int top = 0;
4341 for (auto bottom: { center.fTop, center.fBottom, bitmap.height() } ) {
4342 paint.setColor(gray);
4343 bitCanvas.drawIRect(SkIRect::MakeLTRB(left, top, right, bottom), paint);
4344 gray += 0x001f1f1f;
4345 top = bottom;
4346 }
4347 left = right;
4348 }
4349 sk_sp<SkImage> image = SkImage::MakeFromBitmap(bitmap);
4350 SkImage* imagePtr = image.get();
4351 for (auto dest: { 20, 30, 40, 60, 90 } ) {
4352 canvas->drawImageNine(imagePtr, center, SkRect::MakeWH(dest, dest), nullptr);
4353 canvas->translate(dest + 4, 0);
4354 }
Cary Clark8032b982017-07-28 11:04:54 -04004355}
4356##
4357
Cary Clark2ade9972017-11-02 17:49:34 -04004358#SeeAlso drawImage drawBitmapNine drawImageLattice drawImageRect
Cary Clark8032b982017-07-28 11:04:54 -04004359
4360##
4361
4362# ------------------------------------------------------------------------------
4363
4364#Method void drawImageNine(const sk_sp<SkImage>& image, const SkIRect& center, const SkRect& dst,
4365 const SkPaint* paint = nullptr)
4366
Cary Clarkd0530ba2017-09-14 11:25:39 -04004367Draw Image image stretched proportionally to fit into Rect dst.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004368IRect center divides the image into nine sections: four sides, four corners, and
Cary Clarkce101242017-09-01 15:51:02 -04004369the center. Corners are not scaled, or scaled down proportionately if their sides
Cary Clarkbad5ad72017-08-03 17:14:08 -04004370are larger than dst; center and four sides are scaled to fit remaining space, if any.
Cary Clark8032b982017-07-28 11:04:54 -04004371
Cary Clarkbad5ad72017-08-03 17:14:08 -04004372Additionally transform draw using Clip, Matrix, and optional Paint paint.
4373
4374If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4375Blend_Mode, and Draw_Looper. If image is kAlpha_8_SkColorType, apply Shader.
4376If paint contains Mask_Filter, generate mask from image bounds.
4377
4378If generated mask extends beyond image bounds, replicate image edge colors, just
4379as Shader made from SkImage::makeShader with SkShader::kClamp_TileMode set
Cary Clarkbc5697d2017-10-04 14:31:33 -04004380replicates the image edge color when it samples outside of its bounds.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004381
4382#Param image Image containing pixels, dimensions, and format ##
4383#Param center IRect edge of image corners and sides ##
4384#Param dst destination Rect of image to draw to ##
4385#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4386 and so on; or nullptr
4387##
Cary Clark8032b982017-07-28 11:04:54 -04004388
4389#Example
4390#Height 128
4391#Description
4392 The two leftmost images has four corners and sides to the left and right of center.
4393 The leftmost image scales the width of corners proportionately to fit.
Cary Clarkce101242017-09-01 15:51:02 -04004394 The third and fourth image corners are not scaled; the sides and center are scaled to
Cary Clark8032b982017-07-28 11:04:54 -04004395 fill the remaining space.
4396 The rightmost image has four corners scaled vertically to fit, and uses sides above
4397 and below center to fill the remaining space.
4398##
Cary Clarkbad5ad72017-08-03 17:14:08 -04004399void draw(SkCanvas* canvas) {
4400 SkIRect center = { 20, 10, 50, 40 };
4401 SkBitmap bitmap;
4402 bitmap.allocPixels(SkImageInfo::MakeN32Premul(60, 60));
4403 SkCanvas bitCanvas(bitmap);
4404 SkPaint paint;
4405 SkColor gray = 0xFF000000;
4406 int left = 0;
4407 for (auto right: { center.fLeft, center.fRight, bitmap.width() } ) {
4408 int top = 0;
4409 for (auto bottom: { center.fTop, center.fBottom, bitmap.height() } ) {
4410 paint.setColor(gray);
4411 bitCanvas.drawIRect(SkIRect::MakeLTRB(left, top, right, bottom), paint);
4412 gray += 0x001f1f1f;
4413 top = bottom;
4414 }
4415 left = right;
4416 }
4417 sk_sp<SkImage> image = SkImage::MakeFromBitmap(bitmap);
4418 for (auto dest: { 20, 30, 40, 60, 90 } ) {
4419 canvas->drawImageNine(image, center, SkRect::MakeWH(dest, 110 - dest), nullptr);
4420 canvas->translate(dest + 4, 0);
4421 }
Cary Clark8032b982017-07-28 11:04:54 -04004422}
4423##
4424
Cary Clark2ade9972017-11-02 17:49:34 -04004425#SeeAlso drawImage drawBitmapNine drawImageLattice drawImageRect
Cary Clark8032b982017-07-28 11:04:54 -04004426
4427##
4428
4429# ------------------------------------------------------------------------------
4430
4431#Method void drawBitmap(const SkBitmap& bitmap, SkScalar left, SkScalar top,
Cary Clark73fa9722017-08-29 17:36:51 -04004432 const SkPaint* paint = nullptr)
Cary Clark8032b982017-07-28 11:04:54 -04004433
4434Draw Bitmap bitmap, with its top-left corner at (left, top),
4435using Clip, Matrix, and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004436
Cary Clarka560c472017-11-27 10:44:06 -05004437If Paint paint is not nullptr, apply Color_Filter, Color_Alpha, Image_Filter,
Cary Clarkbad5ad72017-08-03 17:14:08 -04004438Blend_Mode, and Draw_Looper. If bitmap is kAlpha_8_SkColorType, apply Shader.
4439If paint contains Mask_Filter, generate mask from bitmap bounds.
4440
4441If generated mask extends beyond bitmap bounds, replicate bitmap edge colors,
4442just as Shader made from SkShader::MakeBitmapShader with
Cary Clarkbc5697d2017-10-04 14:31:33 -04004443SkShader::kClamp_TileMode set replicates the bitmap edge color when it samples
Cary Clarkbad5ad72017-08-03 17:14:08 -04004444outside of its bounds.
4445
4446#Param bitmap Bitmap containing pixels, dimensions, and format ##
4447#Param left left side of bitmap ##
4448#Param top top side of bitmap ##
4449#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4450 and so on; or nullptr
4451##
Cary Clark8032b982017-07-28 11:04:54 -04004452
4453#Example
4454#Height 64
Cary Clarkbad5ad72017-08-03 17:14:08 -04004455void draw(SkCanvas* canvas) {
4456 uint8_t pixels[][8] = { { 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00},
4457 { 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00},
4458 { 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00},
4459 { 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF},
4460 { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
4461 { 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00},
4462 { 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0x00},
4463 { 0xFF, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0xFF} };
4464 SkBitmap bitmap;
4465 bitmap.installPixels(SkImageInfo::MakeA8(8, 8),
4466 (void*) pixels, sizeof(pixels[0]));
4467 SkPaint paint;
4468 canvas->scale(4, 4);
4469 for (auto color : { SK_ColorRED, SK_ColorBLUE, 0xFF007F00} ) {
4470 paint.setColor(color);
4471 canvas->drawBitmap(bitmap, 0, 0, &paint);
4472 canvas->translate(12, 0);
4473 }
Cary Clark8032b982017-07-28 11:04:54 -04004474}
4475##
4476
Cary Clark2ade9972017-11-02 17:49:34 -04004477#SeeAlso drawImage drawBitmapLattice drawBitmapNine drawBitmapRect SkBitmap::readPixels SkBitmap::writePixels
Cary Clark8032b982017-07-28 11:04:54 -04004478
4479##
4480
4481# ------------------------------------------------------------------------------
4482
4483#Method void drawBitmapRect(const SkBitmap& bitmap, const SkRect& src, const SkRect& dst,
4484 const SkPaint* paint, SrcRectConstraint constraint = kStrict_SrcRectConstraint)
4485
4486Draw Rect src of Bitmap bitmap, scaled and translated to fill Rect dst.
4487Additionally transform draw using Clip, Matrix, and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004488
Cary Clarkbad5ad72017-08-03 17:14:08 -04004489If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4490Blend_Mode, and Draw_Looper. If bitmap is kAlpha_8_SkColorType, apply Shader.
4491If paint contains Mask_Filter, generate mask from bitmap bounds.
4492
4493If generated mask extends beyond bitmap bounds, replicate bitmap edge colors,
4494just as Shader made from SkShader::MakeBitmapShader with
Cary Clarkbc5697d2017-10-04 14:31:33 -04004495SkShader::kClamp_TileMode set replicates the bitmap edge color when it samples
Cary Clarkbad5ad72017-08-03 17:14:08 -04004496outside of its bounds.
4497
4498constraint set to kStrict_SrcRectConstraint limits Paint Filter_Quality to
4499sample within src; set to kFast_SrcRectConstraint allows sampling outside to
4500improve performance.
4501
4502#Param bitmap Bitmap containing pixels, dimensions, and format ##
4503#Param src source Rect of image to draw from ##
4504#Param dst destination Rect of image to draw to ##
4505#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4506 and so on; or nullptr
4507##
4508#Param constraint filter strictly within src or draw faster ##
Cary Clark8032b982017-07-28 11:04:54 -04004509
4510#Example
4511#Height 64
Cary Clarkbad5ad72017-08-03 17:14:08 -04004512void draw(SkCanvas* canvas) {
4513 uint8_t pixels[][8] = { { 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00},
4514 { 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00},
4515 { 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00},
4516 { 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF},
4517 { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
4518 { 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00},
4519 { 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00},
4520 { 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00} };
4521 SkBitmap bitmap;
4522 bitmap.installPixels(SkImageInfo::MakeA8(8, 8),
4523 (void*) pixels, sizeof(pixels[0]));
4524 SkPaint paint;
4525 paint.setMaskFilter(SkBlurMaskFilter::Make(kSolid_SkBlurStyle, 6));
4526 for (auto color : { SK_ColorRED, SK_ColorBLUE, 0xFF007F00} ) {
4527 paint.setColor(color);
4528 canvas->drawBitmapRect(bitmap, SkRect::MakeWH(8, 8), SkRect::MakeWH(32, 32), &paint);
4529 canvas->translate(48, 0);
4530 }
Cary Clark8032b982017-07-28 11:04:54 -04004531}
4532##
4533
Cary Clark2ade9972017-11-02 17:49:34 -04004534#SeeAlso drawImageRect drawBitmap drawBitmapLattice drawBitmapNine
Cary Clark8032b982017-07-28 11:04:54 -04004535
4536##
4537
4538# ------------------------------------------------------------------------------
4539
4540#Method void drawBitmapRect(const SkBitmap& bitmap, const SkIRect& isrc, const SkRect& dst,
4541 const SkPaint* paint, SrcRectConstraint constraint = kStrict_SrcRectConstraint)
4542
4543Draw IRect isrc of Bitmap bitmap, scaled and translated to fill Rect dst.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004544isrc is on integer pixel boundaries; dst may include fractional boundaries.
Cary Clark8032b982017-07-28 11:04:54 -04004545Additionally transform draw using Clip, Matrix, and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004546
Cary Clarkbad5ad72017-08-03 17:14:08 -04004547If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4548Blend_Mode, and Draw_Looper. If bitmap is kAlpha_8_SkColorType, apply Shader.
4549If paint contains Mask_Filter, generate mask from bitmap bounds.
4550
4551If generated mask extends beyond bitmap bounds, replicate bitmap edge colors,
4552just as Shader made from SkShader::MakeBitmapShader with
Cary Clarkbc5697d2017-10-04 14:31:33 -04004553SkShader::kClamp_TileMode set replicates the bitmap edge color when it samples
Cary Clarkbad5ad72017-08-03 17:14:08 -04004554outside of its bounds.
4555
4556constraint set to kStrict_SrcRectConstraint limits Paint Filter_Quality to
Cary Clarkce101242017-09-01 15:51:02 -04004557sample within isrc; set to kFast_SrcRectConstraint allows sampling outside to
Cary Clarkbad5ad72017-08-03 17:14:08 -04004558improve performance.
4559
4560#Param bitmap Bitmap containing pixels, dimensions, and format ##
4561#Param isrc source IRect of image to draw from ##
4562#Param dst destination Rect of image to draw to ##
4563#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4564 and so on; or nullptr
4565##
Cary Clarkce101242017-09-01 15:51:02 -04004566#Param constraint sample strictly within isrc, or draw faster ##
Cary Clark8032b982017-07-28 11:04:54 -04004567
4568#Example
4569#Height 64
Cary Clarkbad5ad72017-08-03 17:14:08 -04004570void draw(SkCanvas* canvas) {
4571 uint8_t pixels[][8] = { { 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00},
4572 { 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00},
4573 { 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0xFF},
4574 { 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0xFF},
4575 { 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF},
4576 { 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF},
4577 { 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00},
4578 { 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00} };
4579 SkBitmap bitmap;
4580 bitmap.installPixels(SkImageInfo::MakeA8(8, 8),
4581 (void*) pixels, sizeof(pixels[0]));
4582 SkPaint paint;
4583 paint.setFilterQuality(kHigh_SkFilterQuality);
4584 for (auto color : { SK_ColorRED, SK_ColorBLUE, 0xFF007F00, 0xFF7f007f} ) {
4585 paint.setColor(color);
4586 canvas->drawBitmapRect(bitmap, SkIRect::MakeWH(8, 8), SkRect::MakeWH(32, 32), &paint);
4587 canvas->translate(48.25f, 0);
4588 }
Cary Clark8032b982017-07-28 11:04:54 -04004589}
4590##
4591
Cary Clark2ade9972017-11-02 17:49:34 -04004592#SeeAlso drawImageRect drawBitmap drawBitmapLattice drawBitmapNine
Cary Clark8032b982017-07-28 11:04:54 -04004593
4594##
4595
4596# ------------------------------------------------------------------------------
4597
4598#Method void drawBitmapRect(const SkBitmap& bitmap, const SkRect& dst, const SkPaint* paint,
4599 SrcRectConstraint constraint = kStrict_SrcRectConstraint)
4600
4601Draw Bitmap bitmap, scaled and translated to fill Rect dst.
Cary Clarkce101242017-09-01 15:51:02 -04004602bitmap bounds is on integer pixel boundaries; dst may include fractional boundaries.
Cary Clark8032b982017-07-28 11:04:54 -04004603Additionally transform draw using Clip, Matrix, and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004604
Cary Clarkbad5ad72017-08-03 17:14:08 -04004605If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4606Blend_Mode, and Draw_Looper. If bitmap is kAlpha_8_SkColorType, apply Shader.
4607If paint contains Mask_Filter, generate mask from bitmap bounds.
4608
4609If generated mask extends beyond bitmap bounds, replicate bitmap edge colors,
4610just as Shader made from SkShader::MakeBitmapShader with
Cary Clarkbc5697d2017-10-04 14:31:33 -04004611SkShader::kClamp_TileMode set replicates the bitmap edge color when it samples
Cary Clarkbad5ad72017-08-03 17:14:08 -04004612outside of its bounds.
4613
4614constraint set to kStrict_SrcRectConstraint limits Paint Filter_Quality to
Cary Clarkce101242017-09-01 15:51:02 -04004615sample within bitmap; set to kFast_SrcRectConstraint allows sampling outside to
Cary Clarkbad5ad72017-08-03 17:14:08 -04004616improve performance.
4617
4618#Param bitmap Bitmap containing pixels, dimensions, and format ##
4619#Param dst destination Rect of image to draw to ##
4620#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4621 and so on; or nullptr
4622##
Cary Clarkce101242017-09-01 15:51:02 -04004623#Param constraint filter strictly within bitmap or draw faster ##
Cary Clark8032b982017-07-28 11:04:54 -04004624
4625#Example
4626#Height 64
Cary Clarkbad5ad72017-08-03 17:14:08 -04004627void draw(SkCanvas* canvas) {
4628 uint32_t pixels[][2] = { { 0x00000000, 0x55550000},
4629 { 0xAAAA0000, 0xFFFF0000} };
4630 SkBitmap bitmap;
4631 bitmap.installPixels(SkImageInfo::MakeN32Premul(2, 2),
4632 (void*) pixels, sizeof(pixels[0]));
4633 SkPaint paint;
4634 canvas->scale(4, 4);
4635 for (auto color : { SK_ColorRED, SK_ColorBLUE, SK_ColorGREEN } ) {
4636 paint.setColorFilter(SkColorFilter::MakeModeFilter(color, SkBlendMode::kPlus));
4637 canvas->drawBitmapRect(bitmap, SkRect::MakeWH(8, 8), &paint);
4638 canvas->translate(8, 0);
4639 }
Cary Clark8032b982017-07-28 11:04:54 -04004640}
4641##
4642
Cary Clark2ade9972017-11-02 17:49:34 -04004643#SeeAlso drawImageRect drawBitmap drawBitmapLattice drawBitmapNine
Cary Clark8032b982017-07-28 11:04:54 -04004644
4645##
4646
4647# ------------------------------------------------------------------------------
4648
4649#Method void drawBitmapNine(const SkBitmap& bitmap, const SkIRect& center, const SkRect& dst,
Cary Clark73fa9722017-08-29 17:36:51 -04004650 const SkPaint* paint = nullptr)
Cary Clark8032b982017-07-28 11:04:54 -04004651
Cary Clarkd0530ba2017-09-14 11:25:39 -04004652Draw Bitmap bitmap stretched proportionally to fit into Rect dst.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004653IRect center divides the bitmap into nine sections: four sides, four corners,
Cary Clarkce101242017-09-01 15:51:02 -04004654and the center. Corners are not scaled, or scaled down proportionately if their
Cary Clarkbad5ad72017-08-03 17:14:08 -04004655sides are larger than dst; center and four sides are scaled to fit remaining
4656space, if any.
Cary Clark8032b982017-07-28 11:04:54 -04004657
Cary Clarkbad5ad72017-08-03 17:14:08 -04004658Additionally transform draw using Clip, Matrix, and optional Paint paint.
4659
4660If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4661Blend_Mode, and Draw_Looper. If bitmap is kAlpha_8_SkColorType, apply Shader.
4662If paint contains Mask_Filter, generate mask from bitmap bounds.
4663
4664If generated mask extends beyond bitmap bounds, replicate bitmap edge colors,
4665just as Shader made from SkShader::MakeBitmapShader with
Cary Clarkbc5697d2017-10-04 14:31:33 -04004666SkShader::kClamp_TileMode set replicates the bitmap edge color when it samples
Cary Clarkbad5ad72017-08-03 17:14:08 -04004667outside of its bounds.
4668
4669#Param bitmap Bitmap containing pixels, dimensions, and format ##
4670#Param center IRect edge of image corners and sides ##
4671#Param dst destination Rect of image to draw to ##
4672#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4673 and so on; or nullptr
4674##
Cary Clark8032b982017-07-28 11:04:54 -04004675
4676#Example
4677#Height 128
4678#Description
4679 The two leftmost bitmap draws has four corners and sides to the left and right of center.
4680 The leftmost bitmap draw scales the width of corners proportionately to fit.
Cary Clarkce101242017-09-01 15:51:02 -04004681 The third and fourth draw corners are not scaled; the sides and center are scaled to
Cary Clark8032b982017-07-28 11:04:54 -04004682 fill the remaining space.
4683 The rightmost bitmap draw has four corners scaled vertically to fit, and uses sides above
4684 and below center to fill the remaining space.
4685##
Cary Clarkbad5ad72017-08-03 17:14:08 -04004686void draw(SkCanvas* canvas) {
4687 SkIRect center = { 20, 10, 50, 40 };
4688 SkBitmap bitmap;
4689 bitmap.allocPixels(SkImageInfo::MakeN32Premul(60, 60));
4690 SkCanvas bitCanvas(bitmap);
4691 SkPaint paint;
4692 SkColor gray = 0xFF000000;
4693 int left = 0;
4694 for (auto right: { center.fLeft, center.fRight, bitmap.width() } ) {
4695 int top = 0;
4696 for (auto bottom: { center.fTop, center.fBottom, bitmap.height() } ) {
4697 paint.setColor(gray);
4698 bitCanvas.drawIRect(SkIRect::MakeLTRB(left, top, right, bottom), paint);
4699 gray += 0x001f1f1f;
4700 top = bottom;
4701 }
4702 left = right;
4703 }
4704 for (auto dest: { 20, 30, 40, 60, 90 } ) {
4705 canvas->drawBitmapNine(bitmap, center, SkRect::MakeWH(dest, 110 - dest), nullptr);
4706 canvas->translate(dest + 4, 0);
4707 }
Cary Clark8032b982017-07-28 11:04:54 -04004708}
4709##
4710
Cary Clark2ade9972017-11-02 17:49:34 -04004711#SeeAlso drawImageNine drawBitmap drawBitmapLattice drawBitmapRect
Cary Clark8032b982017-07-28 11:04:54 -04004712
4713##
4714
4715# ------------------------------------------------------------------------------
4716#Struct Lattice
4717
Cary Clark8032b982017-07-28 11:04:54 -04004718#Code
4719 struct Lattice {
Cary Clark2f466242017-12-11 16:03:17 -05004720 enum RectType ...
Cary Clark8032b982017-07-28 11:04:54 -04004721
Cary Clark2f466242017-12-11 16:03:17 -05004722 const int* fXDivs;
4723 const int* fYDivs;
4724 const RectType* fRectTypes;
4725 int fXCount;
4726 int fYCount;
4727 const SkIRect* fBounds;
4728 const SkColor* fColors;
Cary Clark8032b982017-07-28 11:04:54 -04004729 };
4730##
4731
Cary Clark154beea2017-10-26 07:58:48 -04004732 Lattice divides Bitmap or Image into a rectangular grid.
4733 Grid entries on even columns and even rows are fixed; these entries are
4734 always drawn at their original size if the destination is large enough.
4735 If the destination side is too small to hold the fixed entries, all fixed
4736 entries are proportionately scaled down to fit.
4737 The grid entries not on even columns and rows are scaled to fit the
4738 remaining space, if any.
4739
Cary Clark2f466242017-12-11 16:03:17 -05004740 #Enum RectType
Cary Clark8032b982017-07-28 11:04:54 -04004741 #Code
Cary Clark2f466242017-12-11 16:03:17 -05004742 enum RectType : uint8_t {
4743 kDefault = 0,
4744 kTransparent,
4745 kFixedColor,
Cary Clark8032b982017-07-28 11:04:54 -04004746 };
4747 ##
4748
Cary Clark2f466242017-12-11 16:03:17 -05004749 Optional setting per rectangular grid entry to make it transparent,
4750 or to fill the grid entry with a color.
Cary Clark8032b982017-07-28 11:04:54 -04004751
Cary Clark2f466242017-12-11 16:03:17 -05004752 #Const kDefault 0
4753 Draws Bitmap into lattice rectangle.
4754 ##
4755
4756 #Const kTransparent 1
4757 Skips lattice rectangle by making it transparent.
4758 ##
4759
4760 #Const kFixedColor 2
4761 Draws one of fColors into lattice rectangle.
Cary Clark8032b982017-07-28 11:04:54 -04004762 ##
4763 ##
4764
4765 #Member const int* fXDivs
4766 Array of x-coordinates that divide the bitmap vertically.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004767 Array entries must be unique, increasing, greater than or equal to
4768 fBounds left edge, and less than fBounds right edge.
4769 Set the first element to fBounds left to collapse the left column of
4770 fixed grid entries.
Cary Clark8032b982017-07-28 11:04:54 -04004771 ##
4772
4773 #Member const int* fYDivs
4774 Array of y-coordinates that divide the bitmap horizontally.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004775 Array entries must be unique, increasing, greater than or equal to
4776 fBounds top edge, and less than fBounds bottom edge.
4777 Set the first element to fBounds top to collapse the top row of fixed
4778 grid entries.
Cary Clark8032b982017-07-28 11:04:54 -04004779 ##
4780
Cary Clark2f466242017-12-11 16:03:17 -05004781 #Member const RectType* fRectTypes
4782 Optional array of fill types, one per rectangular grid entry:
Cary Clarkbad5ad72017-08-03 17:14:08 -04004783 array length must be
4784 #Formula
4785 (fXCount + 1) * (fYCount + 1)
4786 ##
4787 .
Cary Clark6fc50412017-09-21 12:31:06 -04004788
Cary Clark2f466242017-12-11 16:03:17 -05004789 Each RectType is one of: kDefault, kTransparent, kFixedColor.
4790
Cary Clark8032b982017-07-28 11:04:54 -04004791 Array entries correspond to the rectangular grid entries, ascending
4792 left to right and then top to bottom.
4793 ##
4794
4795 #Member int fXCount
Cary Clarkbad5ad72017-08-03 17:14:08 -04004796 Number of entries in fXDivs array; one less than the number of
4797 horizontal divisions.
Cary Clark8032b982017-07-28 11:04:54 -04004798 ##
4799
4800 #Member int fYCount
Cary Clarkbad5ad72017-08-03 17:14:08 -04004801 Number of entries in fYDivs array; one less than the number of vertical
4802 divisions.
Cary Clark8032b982017-07-28 11:04:54 -04004803 ##
4804
4805 #Member const SkIRect* fBounds
4806 Optional subset IRect source to draw from.
4807 If nullptr, source bounds is dimensions of Bitmap or Image.
4808 ##
4809
Cary Clark2f466242017-12-11 16:03:17 -05004810 #Member const SkColor* fColors
4811 Optional array of colors, one per rectangular grid entry.
4812 Array length must be
4813 #Formula
4814 (fXCount + 1) * (fYCount + 1)
4815 ##
4816 .
4817
4818 Array entries correspond to the rectangular grid entries, ascending
4819 left to right, then top to bottom.
4820 ##
4821
Cary Clark8032b982017-07-28 11:04:54 -04004822#Struct Lattice ##
4823
4824#Method void drawBitmapLattice(const SkBitmap& bitmap, const Lattice& lattice, const SkRect& dst,
4825 const SkPaint* paint = nullptr)
4826
Cary Clarkd0530ba2017-09-14 11:25:39 -04004827Draw Bitmap bitmap stretched proportionally to fit into Rect dst.
Cary Clark8032b982017-07-28 11:04:54 -04004828
4829Lattice lattice divides bitmap into a rectangular grid.
4830Each intersection of an even-numbered row and column is fixed; like the corners
Cary Clarkbad5ad72017-08-03 17:14:08 -04004831of drawBitmapNine, fixed lattice elements never scale larger than their initial
Cary Clarkbc5697d2017-10-04 14:31:33 -04004832size and shrink proportionately when all fixed elements exceed the bitmap
Cary Clarkbad5ad72017-08-03 17:14:08 -04004833dimension. All other grid elements scale to fill the available space, if any.
Cary Clark8032b982017-07-28 11:04:54 -04004834
4835Additionally transform draw using Clip, Matrix, and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004836
Cary Clarkbad5ad72017-08-03 17:14:08 -04004837If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4838Blend_Mode, and Draw_Looper. If bitmap is kAlpha_8_SkColorType, apply Shader.
4839If paint contains Mask_Filter, generate mask from bitmap bounds.
4840
4841If generated mask extends beyond bitmap bounds, replicate bitmap edge colors,
4842just as Shader made from SkShader::MakeBitmapShader with
Cary Clarkbc5697d2017-10-04 14:31:33 -04004843SkShader::kClamp_TileMode set replicates the bitmap edge color when it samples
Cary Clarkbad5ad72017-08-03 17:14:08 -04004844outside of its bounds.
4845
4846#Param bitmap Bitmap containing pixels, dimensions, and format ##
4847#Param lattice division of bitmap into fixed and variable rectangles ##
4848#Param dst destination Rect of image to draw to ##
4849#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4850 and so on; or nullptr
4851##
Cary Clark8032b982017-07-28 11:04:54 -04004852
4853#Example
4854#Height 128
4855#Description
4856 The two leftmost bitmap draws has four corners and sides to the left and right of center.
4857 The leftmost bitmap draw scales the width of corners proportionately to fit.
Cary Clarkce101242017-09-01 15:51:02 -04004858 The third and fourth draw corners are not scaled; the sides are scaled to
Cary Clark8032b982017-07-28 11:04:54 -04004859 fill the remaining space; the center is transparent.
4860 The rightmost bitmap draw has four corners scaled vertically to fit, and uses sides above
4861 and below center to fill the remaining space.
4862##
Cary Clarkbad5ad72017-08-03 17:14:08 -04004863void draw(SkCanvas* canvas) {
4864 SkIRect center = { 20, 10, 50, 40 };
4865 SkBitmap bitmap;
4866 bitmap.allocPixels(SkImageInfo::MakeN32Premul(60, 60));
4867 SkCanvas bitCanvas(bitmap);
4868 SkPaint paint;
4869 SkColor gray = 0xFF000000;
4870 int left = 0;
4871 for (auto right: { center.fLeft, center.fRight, bitmap.width() } ) {
4872 int top = 0;
4873 for (auto bottom: { center.fTop, center.fBottom, bitmap.height() } ) {
4874 paint.setColor(gray);
4875 bitCanvas.drawIRect(SkIRect::MakeLTRB(left, top, right, bottom), paint);
4876 gray += 0x001f1f1f;
4877 top = bottom;
4878 }
4879 left = right;
4880 }
4881 const int xDivs[] = { center.fLeft, center.fRight };
4882 const int yDivs[] = { center.fTop, center.fBottom };
Cary Clarkca3ebcd2017-12-12 11:22:38 -05004883 SkCanvas::Lattice::RectType fillTypes[3][3];
4884 memset(fillTypes, 0, sizeof(fillTypes));
4885 fillTypes[1][1] = SkCanvas::Lattice::kTransparent;
4886 SkColor dummy[9]; // temporary pending bug fix
4887 SkCanvas::Lattice lattice = { xDivs, yDivs, fillTypes[0], SK_ARRAY_COUNT(xDivs),
4888 SK_ARRAY_COUNT(yDivs), nullptr, dummy };
Cary Clarkbad5ad72017-08-03 17:14:08 -04004889 for (auto dest: { 20, 30, 40, 60, 90 } ) {
Cary Clarkca3ebcd2017-12-12 11:22:38 -05004890 canvas->drawBitmapLattice(bitmap, lattice, SkRect::MakeWH(dest, 110 - dest), nullptr);
Cary Clarkbad5ad72017-08-03 17:14:08 -04004891 canvas->translate(dest + 4, 0);
4892 }
Cary Clark8032b982017-07-28 11:04:54 -04004893}
4894##
4895
Cary Clark2ade9972017-11-02 17:49:34 -04004896#SeeAlso drawImageLattice drawBitmap drawBitmapNine Lattice
Cary Clark8032b982017-07-28 11:04:54 -04004897
4898##
4899
4900# ------------------------------------------------------------------------------
4901
4902#Method void drawImageLattice(const SkImage* image, const Lattice& lattice, const SkRect& dst,
4903 const SkPaint* paint = nullptr)
4904
Cary Clarkd0530ba2017-09-14 11:25:39 -04004905Draw Image image stretched proportionally to fit into Rect dst.
Cary Clark8032b982017-07-28 11:04:54 -04004906
4907Lattice lattice divides image into a rectangular grid.
4908Each intersection of an even-numbered row and column is fixed; like the corners
Cary Clarkbad5ad72017-08-03 17:14:08 -04004909of drawBitmapNine, fixed lattice elements never scale larger than their initial
Cary Clarkbc5697d2017-10-04 14:31:33 -04004910size and shrink proportionately when all fixed elements exceed the bitmap
Cary Clarkbad5ad72017-08-03 17:14:08 -04004911dimension. All other grid elements scale to fill the available space, if any.
Cary Clark8032b982017-07-28 11:04:54 -04004912
4913Additionally transform draw using Clip, Matrix, and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004914
Cary Clarkbad5ad72017-08-03 17:14:08 -04004915If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4916Blend_Mode, and Draw_Looper. If bitmap is kAlpha_8_SkColorType, apply Shader.
4917If paint contains Mask_Filter, generate mask from bitmap bounds.
4918
4919If generated mask extends beyond bitmap bounds, replicate bitmap edge colors,
4920just as Shader made from SkShader::MakeBitmapShader with
Cary Clarkbc5697d2017-10-04 14:31:33 -04004921SkShader::kClamp_TileMode set replicates the bitmap edge color when it samples
Cary Clarkbad5ad72017-08-03 17:14:08 -04004922outside of its bounds.
4923
4924#Param image Image containing pixels, dimensions, and format ##
4925#Param lattice division of bitmap into fixed and variable rectangles ##
4926#Param dst destination Rect of image to draw to ##
4927#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4928 and so on; or nullptr
4929##
Cary Clark8032b982017-07-28 11:04:54 -04004930
4931#Example
4932#Height 128
4933#Description
4934 The leftmost image is smaller than center; only corners are drawn, all scaled to fit.
Cary Clarkce101242017-09-01 15:51:02 -04004935 The second image equals the size of center; only corners are drawn without scaling.
4936 The remaining images are larger than center. All corners draw without scaling. The sides
Cary Clark8032b982017-07-28 11:04:54 -04004937 are scaled if needed to take up the remaining space; the center is transparent.
4938##
Cary Clarkbad5ad72017-08-03 17:14:08 -04004939void draw(SkCanvas* canvas) {
4940 SkIRect center = { 20, 10, 50, 40 };
4941 SkBitmap bitmap;
4942 bitmap.allocPixels(SkImageInfo::MakeN32Premul(60, 60));
4943 SkCanvas bitCanvas(bitmap);
4944 SkPaint paint;
4945 SkColor gray = 0xFF000000;
4946 int left = 0;
4947 for (auto right: { center.fLeft, center.fRight, bitmap.width() } ) {
4948 int top = 0;
4949 for (auto bottom: { center.fTop, center.fBottom, bitmap.height() } ) {
4950 paint.setColor(gray);
4951 bitCanvas.drawIRect(SkIRect::MakeLTRB(left, top, right, bottom), paint);
4952 gray += 0x001f1f1f;
4953 top = bottom;
4954 }
4955 left = right;
4956 }
4957 const int xDivs[] = { center.fLeft, center.fRight };
4958 const int yDivs[] = { center.fTop, center.fBottom };
Cary Clarkca3ebcd2017-12-12 11:22:38 -05004959 SkCanvas::Lattice::RectType fillTypes[3][3];
4960 memset(fillTypes, 0, sizeof(fillTypes));
4961 fillTypes[1][1] = SkCanvas::Lattice::kTransparent;
4962 SkColor dummy[9]; // temporary pending bug fix
4963 SkCanvas::Lattice lattice = { xDivs, yDivs, fillTypes[0], SK_ARRAY_COUNT(xDivs),
4964 SK_ARRAY_COUNT(yDivs), nullptr, dummy };
Cary Clarkbad5ad72017-08-03 17:14:08 -04004965 sk_sp<SkImage> image = SkImage::MakeFromBitmap(bitmap);
4966 SkImage* imagePtr = image.get();
4967 for (auto dest: { 20, 30, 40, 60, 90 } ) {
4968 canvas->drawImageNine(imagePtr, center, SkRect::MakeWH(dest, dest), nullptr);
4969 canvas->translate(dest + 4, 0);
4970 }
Cary Clark8032b982017-07-28 11:04:54 -04004971}
4972##
4973
Cary Clark2ade9972017-11-02 17:49:34 -04004974#SeeAlso drawBitmapLattice drawImage drawImageNine Lattice
Cary Clark8032b982017-07-28 11:04:54 -04004975
4976##
4977
4978#Topic Draw_Image ##
4979
4980# ------------------------------------------------------------------------------
4981
4982#Method void drawText(const void* text, size_t byteLength, SkScalar x, SkScalar y,
4983 const SkPaint& paint)
4984
4985Draw text, with origin at (x, y), using Clip, Matrix, and Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004986
Cary Clarkbc5697d2017-10-04 14:31:33 -04004987text meaning depends on Paint_Text_Encoding; by default, text is encoded as
Cary Clarkbad5ad72017-08-03 17:14:08 -04004988UTF-8.
Cary Clark8032b982017-07-28 11:04:54 -04004989
Cary Clarkbad5ad72017-08-03 17:14:08 -04004990x and y meaning depends on Paint_Text_Align and Paint_Vertical_Text; by default
Cary Clarkbc5697d2017-10-04 14:31:33 -04004991text draws left to right, positioning the first glyph left side bearing at x
Cary Clarkbad5ad72017-08-03 17:14:08 -04004992and its baseline at y. Text size is affected by Matrix and Paint_Text_Size.
4993
Mike Reed8ad91a92018-01-19 19:09:32 -05004994All elements of paint: Path_Effect, Mask_Filter, Shader,
Cary Clarkbad5ad72017-08-03 17:14:08 -04004995Color_Filter, Image_Filter, and Draw_Looper; apply to text. By default, draws
Cary Clarkce101242017-09-01 15:51:02 -04004996filled 12 point black Glyphs.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004997
Cary Clarkce101242017-09-01 15:51:02 -04004998#Param text character code points or Glyphs drawn ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04004999#Param byteLength byte length of text array ##
5000#Param x start of text on x-axis ##
5001#Param y start of text on y-axis ##
5002#Param paint text size, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005003
5004#Example
5005#Height 200
5006#Description
5007 The same text is drawn varying Paint_Text_Size and varying
5008 Matrix.
5009##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005010void draw(SkCanvas* canvas) {
5011 SkPaint paint;
5012 paint.setAntiAlias(true);
5013 float textSizes[] = { 12, 18, 24, 36 };
5014 for (auto size: textSizes ) {
5015 paint.setTextSize(size);
5016 canvas->drawText("Aa", 2, 10, 20, paint);
5017 canvas->translate(0, size * 2);
5018 }
5019 paint.reset();
5020 paint.setAntiAlias(true);
5021 float yPos = 20;
5022 for (auto size: textSizes ) {
5023 float scale = size / 12.f;
5024 canvas->resetMatrix();
5025 canvas->translate(100, 0);
5026 canvas->scale(scale, scale);
5027 canvas->drawText("Aa", 2, 10 / scale, yPos / scale, paint);
5028 yPos += size * 2;
5029 }
5030}
Cary Clark8032b982017-07-28 11:04:54 -04005031##
5032
Cary Clark2ade9972017-11-02 17:49:34 -04005033#SeeAlso drawString drawPosText drawPosTextH drawTextBlob drawTextOnPath drawTextRSXform
Cary Clark8032b982017-07-28 11:04:54 -04005034
5035##
5036
5037#Method void drawString(const char* string, SkScalar x, SkScalar y, const SkPaint& paint)
5038
Cary Clarkbad5ad72017-08-03 17:14:08 -04005039Draw null terminated string, with origin at (x, y), using Clip, Matrix, and
5040Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04005041
Cary Clarkbc5697d2017-10-04 14:31:33 -04005042string meaning depends on Paint_Text_Encoding; by default, strings are encoded
5043as UTF-8. Other values of Paint_Text_Encoding are unlikely to produce the desired
Cary Clarkbad5ad72017-08-03 17:14:08 -04005044results, since zero bytes may be embedded in the string.
Cary Clark8032b982017-07-28 11:04:54 -04005045
Cary Clarkbad5ad72017-08-03 17:14:08 -04005046x and y meaning depends on Paint_Text_Align and Paint_Vertical_Text; by default
Cary Clarkbc5697d2017-10-04 14:31:33 -04005047string draws left to right, positioning the first glyph left side bearing at x
Cary Clarkbad5ad72017-08-03 17:14:08 -04005048and its baseline at y. Text size is affected by Matrix and Paint_Text_Size.
5049
Mike Reed8ad91a92018-01-19 19:09:32 -05005050All elements of paint: Path_Effect, Mask_Filter, Shader,
Cary Clarkbad5ad72017-08-03 17:14:08 -04005051Color_Filter, Image_Filter, and Draw_Looper; apply to text. By default, draws
Cary Clarkce101242017-09-01 15:51:02 -04005052filled 12 point black Glyphs.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005053
Cary Clarkce101242017-09-01 15:51:02 -04005054#Param string character code points or Glyphs drawn,
Cary Clarkbad5ad72017-08-03 17:14:08 -04005055 ending with a char value of zero
5056##
5057#Param x start of string on x-axis ##
5058#Param y start of string on y-axis ##
5059#Param paint text size, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005060
5061#Example
5062 SkPaint paint;
5063 canvas->drawString("a small hello", 20, 20, paint);
5064##
5065
Cary Clark2ade9972017-11-02 17:49:34 -04005066#SeeAlso drawText drawPosText drawPosTextH drawTextBlob drawTextOnPath drawTextRSXform
Cary Clark8032b982017-07-28 11:04:54 -04005067
5068##
5069
5070#Method void drawString(const SkString& string, SkScalar x, SkScalar y, const SkPaint& paint)
5071
Cary Clarkbad5ad72017-08-03 17:14:08 -04005072Draw null terminated string, with origin at (x, y), using Clip, Matrix, and
5073Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04005074
Cary Clarkbc5697d2017-10-04 14:31:33 -04005075string meaning depends on Paint_Text_Encoding; by default, strings are encoded
5076as UTF-8. Other values of Paint_Text_Encoding are unlikely to produce the desired
Cary Clarkbad5ad72017-08-03 17:14:08 -04005077results, since zero bytes may be embedded in the string.
Cary Clark8032b982017-07-28 11:04:54 -04005078
Cary Clarkbad5ad72017-08-03 17:14:08 -04005079x and y meaning depends on Paint_Text_Align and Paint_Vertical_Text; by default
Cary Clarkbc5697d2017-10-04 14:31:33 -04005080string draws left to right, positioning the first glyph left side bearing at x
Cary Clarkbad5ad72017-08-03 17:14:08 -04005081and its baseline at y. Text size is affected by Matrix and Paint_Text_Size.
5082
Mike Reed8ad91a92018-01-19 19:09:32 -05005083All elements of paint: Path_Effect, Mask_Filter, Shader,
Cary Clarkbad5ad72017-08-03 17:14:08 -04005084Color_Filter, Image_Filter, and Draw_Looper; apply to text. By default, draws
Cary Clarkce101242017-09-01 15:51:02 -04005085filled 12 point black Glyphs.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005086
Cary Clarkce101242017-09-01 15:51:02 -04005087#Param string character code points or Glyphs drawn,
Cary Clarkbad5ad72017-08-03 17:14:08 -04005088 ending with a char value of zero
5089##
5090#Param x start of string on x-axis ##
5091#Param y start of string on y-axis ##
5092#Param paint text size, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005093
5094#Example
5095 SkPaint paint;
5096 SkString string("a small hello");
5097 canvas->drawString(string, 20, 20, paint);
5098##
5099
Cary Clark2ade9972017-11-02 17:49:34 -04005100#SeeAlso drawText drawPosText drawPosTextH drawTextBlob drawTextOnPath drawTextRSXform
Cary Clark8032b982017-07-28 11:04:54 -04005101
5102##
5103
5104# ------------------------------------------------------------------------------
5105
5106#Method void drawPosText(const void* text, size_t byteLength, const SkPoint pos[],
5107 const SkPaint& paint)
5108
Cary Clarkbad5ad72017-08-03 17:14:08 -04005109Draw each glyph in text with the origin in pos array, using Clip, Matrix, and
Cary Clarkce101242017-09-01 15:51:02 -04005110Paint paint. The number of entries in pos array must match the number of Glyphs
Cary Clarkbad5ad72017-08-03 17:14:08 -04005111described by byteLength of text.
Cary Clark8032b982017-07-28 11:04:54 -04005112
Cary Clarkbc5697d2017-10-04 14:31:33 -04005113text meaning depends on Paint_Text_Encoding; by default, text is encoded as
Cary Clarkbad5ad72017-08-03 17:14:08 -04005114UTF-8. pos elements' meaning depends on Paint_Text_Align and Paint_Vertical_Text;
Cary Clarkbc5697d2017-10-04 14:31:33 -04005115by default each glyph left side bearing is positioned at x and its
Cary Clarkbad5ad72017-08-03 17:14:08 -04005116baseline is positioned at y. Text size is affected by Matrix and
5117Paint_Text_Size.
Cary Clark8032b982017-07-28 11:04:54 -04005118
Mike Reed8ad91a92018-01-19 19:09:32 -05005119All elements of paint: Path_Effect, Mask_Filter, Shader,
Cary Clarkbad5ad72017-08-03 17:14:08 -04005120Color_Filter, Image_Filter, and Draw_Looper; apply to text. By default, draws
Cary Clarkce101242017-09-01 15:51:02 -04005121filled 12 point black Glyphs.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005122
5123Layout engines such as Harfbuzz typically position each glyph
Cary Clarkbc5697d2017-10-04 14:31:33 -04005124rather than using the font advance widths.
Cary Clark8032b982017-07-28 11:04:54 -04005125
Cary Clarkce101242017-09-01 15:51:02 -04005126#Param text character code points or Glyphs drawn ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005127#Param byteLength byte length of text array ##
5128#Param pos array of glyph origins ##
5129#Param paint text size, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005130
5131#Example
5132#Height 120
Cary Clarkbad5ad72017-08-03 17:14:08 -04005133void draw(SkCanvas* canvas) {
5134 const char hello[] = "HeLLo!";
5135 const SkPoint pos[] = { {40, 100}, {82, 95}, {115, 110}, {130, 95}, {145, 85},
5136 {172, 100} };
5137 SkPaint paint;
5138 paint.setTextSize(60);
5139 canvas->drawPosText(hello, strlen(hello), pos, paint);
Cary Clark8032b982017-07-28 11:04:54 -04005140}
5141##
5142
Cary Clark2ade9972017-11-02 17:49:34 -04005143#SeeAlso drawText drawPosTextH drawTextBlob drawTextOnPath drawTextRSXform
Cary Clark8032b982017-07-28 11:04:54 -04005144
5145##
5146
5147# ------------------------------------------------------------------------------
5148
5149#Method void drawPosTextH(const void* text, size_t byteLength, const SkScalar xpos[], SkScalar constY,
5150 const SkPaint& paint)
5151
Cary Clarkbad5ad72017-08-03 17:14:08 -04005152Draw each glyph in text with its (x, y) origin composed from xpos array and
5153constY, using Clip, Matrix, and Paint paint. The number of entries in xpos array
Cary Clarkce101242017-09-01 15:51:02 -04005154must match the number of Glyphs described by byteLength of text.
Cary Clark8032b982017-07-28 11:04:54 -04005155
Cary Clarkbc5697d2017-10-04 14:31:33 -04005156text meaning depends on Paint_Text_Encoding; by default, text is encoded as
Cary Clarkce101242017-09-01 15:51:02 -04005157UTF-8. xpos elements' meaning depends on Paint_Text_Align and Paint_Vertical_Text;
Cary Clarkbc5697d2017-10-04 14:31:33 -04005158by default each glyph left side bearing is positioned at an xpos element and
Cary Clarkbad5ad72017-08-03 17:14:08 -04005159its baseline is positioned at constY. Text size is affected by Matrix and
5160Paint_Text_Size.
Cary Clark8032b982017-07-28 11:04:54 -04005161
Mike Reed8ad91a92018-01-19 19:09:32 -05005162All elements of paint: Path_Effect, Mask_Filter, Shader,
Cary Clarkbad5ad72017-08-03 17:14:08 -04005163Color_Filter, Image_Filter, and Draw_Looper; apply to text. By default, draws
Cary Clarkce101242017-09-01 15:51:02 -04005164filled 12 point black Glyphs.
Cary Clark8032b982017-07-28 11:04:54 -04005165
Cary Clarkbad5ad72017-08-03 17:14:08 -04005166Layout engines such as Harfbuzz typically position each glyph
Cary Clarkbc5697d2017-10-04 14:31:33 -04005167rather than using the font advance widths if all Glyphs share the same
Cary Clarkbad5ad72017-08-03 17:14:08 -04005168baseline.
5169
Cary Clarkce101242017-09-01 15:51:02 -04005170#Param text character code points or Glyphs drawn ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005171#Param byteLength byte length of text array ##
5172#Param xpos array of x positions, used to position each glyph ##
5173#Param constY shared y coordinate for all of x positions ##
5174#Param paint text size, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005175
5176#Example
5177#Height 40
Cary Clarkbad5ad72017-08-03 17:14:08 -04005178 void draw(SkCanvas* canvas) {
5179 SkScalar xpos[] = { 20, 40, 80, 160 };
5180 SkPaint paint;
5181 canvas->drawPosTextH("XXXX", 4, xpos, 20, paint);
5182 }
Cary Clark8032b982017-07-28 11:04:54 -04005183##
5184
Cary Clark2ade9972017-11-02 17:49:34 -04005185#SeeAlso drawText drawPosText drawTextBlob drawTextOnPath drawTextRSXform
Cary Clark8032b982017-07-28 11:04:54 -04005186
5187##
5188
5189# ------------------------------------------------------------------------------
5190
5191#Method void drawTextOnPathHV(const void* text, size_t byteLength, const SkPath& path, SkScalar hOffset,
5192 SkScalar vOffset, const SkPaint& paint)
5193
5194Draw text on Path path, using Clip, Matrix, and Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04005195
Cary Clarkbad5ad72017-08-03 17:14:08 -04005196Origin of text is at distance hOffset along the path, offset by a perpendicular
5197vector of length vOffset. If the path section corresponding the glyph advance is
5198curved, the glyph is drawn curved to match; control points in the glyph are
Cary Clarkbc5697d2017-10-04 14:31:33 -04005199mapped to projected points parallel to the path. If the text advance is larger
Cary Clarkbad5ad72017-08-03 17:14:08 -04005200than the path length, the excess text is clipped.
5201
Cary Clarkbc5697d2017-10-04 14:31:33 -04005202text meaning depends on Paint_Text_Encoding; by default, text is encoded as
Cary Clarkbad5ad72017-08-03 17:14:08 -04005203UTF-8. Origin meaning depends on Paint_Text_Align and Paint_Vertical_Text; by
Cary Clarkbc5697d2017-10-04 14:31:33 -04005204default text positions the first glyph left side bearing at origin x and its
Cary Clark8032b982017-07-28 11:04:54 -04005205baseline at origin y. Text size is affected by Matrix and Paint_Text_Size.
5206
Mike Reed8ad91a92018-01-19 19:09:32 -05005207All elements of paint: Path_Effect, Mask_Filter, Shader,
Cary Clarkbad5ad72017-08-03 17:14:08 -04005208Color_Filter, Image_Filter, and Draw_Looper; apply to text. By default, draws
Cary Clarkce101242017-09-01 15:51:02 -04005209filled 12 point black Glyphs.
Cary Clark8032b982017-07-28 11:04:54 -04005210
Cary Clarkce101242017-09-01 15:51:02 -04005211#Param text character code points or Glyphs drawn ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005212#Param byteLength byte length of text array ##
5213#Param path Path providing text baseline ##
5214#Param hOffset distance along path to offset origin ##
5215#Param vOffset offset of text above (if negative) or below (if positive) the path ##
5216#Param paint text size, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005217
5218#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04005219 void draw(SkCanvas* canvas) {
5220 const char aero[] = "correo a" "\xC3" "\xA9" "reo";
5221 const size_t len = sizeof(aero) - 1;
5222 SkPath path;
5223 path.addOval({43-26, 43-26, 43+26, 43+26}, SkPath::kCW_Direction, 3);
5224 SkPaint paint;
5225 paint.setTextSize(24);
5226 for (auto offset : { 0, 10, 20 } ) {
5227 canvas->drawTextOnPathHV(aero, len, path, 0, -offset, paint);
5228 canvas->translate(70 + offset, 70 + offset);
5229 }
5230 }
Cary Clark8032b982017-07-28 11:04:54 -04005231##
5232
Cary Clark2ade9972017-11-02 17:49:34 -04005233#SeeAlso drawTextOnPath drawText drawPosTextH drawTextBlob drawTextRSXform
Cary Clark8032b982017-07-28 11:04:54 -04005234
5235##
5236
5237# ------------------------------------------------------------------------------
5238
5239#Method void drawTextOnPath(const void* text, size_t byteLength, const SkPath& path,
5240 const SkMatrix* matrix, const SkPaint& paint)
5241
5242Draw text on Path path, using Clip, Matrix, and Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04005243
Cary Clarkbad5ad72017-08-03 17:14:08 -04005244Origin of text is at beginning of path offset by matrix, if provided, before it
5245is mapped to path. If the path section corresponding the glyph advance is
5246curved, the glyph is drawn curved to match; control points in the glyph are
Cary Clarkbc5697d2017-10-04 14:31:33 -04005247mapped to projected points parallel to the path. If the text advance is larger
Cary Clarkbad5ad72017-08-03 17:14:08 -04005248than the path length, the excess text is clipped.
5249
Cary Clarkbc5697d2017-10-04 14:31:33 -04005250text meaning depends on Paint_Text_Encoding; by default, text is encoded as
Cary Clarkbad5ad72017-08-03 17:14:08 -04005251UTF-8. Origin meaning depends on Paint_Text_Align and Paint_Vertical_Text; by
Cary Clarkbc5697d2017-10-04 14:31:33 -04005252default text positions the first glyph left side bearing at origin x and its
Cary Clark8032b982017-07-28 11:04:54 -04005253baseline at origin y. Text size is affected by Matrix and Paint_Text_Size.
5254
Mike Reed8ad91a92018-01-19 19:09:32 -05005255All elements of paint: Path_Effect, Mask_Filter, Shader,
Cary Clarkbad5ad72017-08-03 17:14:08 -04005256Color_Filter, Image_Filter, and Draw_Looper; apply to text. By default, draws
Cary Clarkce101242017-09-01 15:51:02 -04005257filled 12 point black Glyphs.
Cary Clark8032b982017-07-28 11:04:54 -04005258
Cary Clarkce101242017-09-01 15:51:02 -04005259#Param text character code points or Glyphs drawn ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005260#Param byteLength byte length of text array ##
5261#Param path Path providing text baseline ##
Cary Clarkce101242017-09-01 15:51:02 -04005262#Param matrix transform of Glyphs before mapping to path; may be nullptr
Cary Clarka523d2d2017-08-30 08:58:10 -04005263 to use identity Matrix
Cary Clarkbad5ad72017-08-03 17:14:08 -04005264##
5265#Param paint text size, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005266
5267#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04005268 void draw(SkCanvas* canvas) {
5269 const char roller[] = "rollercoaster";
5270 const size_t len = sizeof(roller) - 1;
5271 SkPath path;
5272 path.cubicTo(40, -80, 120, 80, 160, -40);
5273 SkPaint paint;
5274 paint.setTextSize(32);
5275 paint.setStyle(SkPaint::kStroke_Style);
5276 SkMatrix matrix;
5277 matrix.setIdentity();
5278 for (int i = 0; i < 3; ++i) {
5279 canvas->translate(25, 60);
5280 canvas->drawPath(path, paint);
5281 canvas->drawTextOnPath(roller, len, path, &matrix, paint);
5282 matrix.preTranslate(0, 10);
5283 }
5284 }
Cary Clark8032b982017-07-28 11:04:54 -04005285##
5286
Cary Clark2ade9972017-11-02 17:49:34 -04005287#SeeAlso drawTextOnPathHV drawText drawPosTextH drawTextBlob drawTextRSXform
Cary Clark8032b982017-07-28 11:04:54 -04005288
5289##
5290
5291# ------------------------------------------------------------------------------
5292
5293#Method void drawTextRSXform(const void* text, size_t byteLength, const SkRSXform xform[],
5294 const SkRect* cullRect, const SkPaint& paint)
5295
5296Draw text, transforming each glyph by the corresponding SkRSXform,
5297using Clip, Matrix, and Paint paint.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005298
Cary Clark8032b982017-07-28 11:04:54 -04005299RSXform array specifies a separate square scale, rotation, and translation for
5300each glyph.
Cary Clark8032b982017-07-28 11:04:54 -04005301
Cary Clarkbad5ad72017-08-03 17:14:08 -04005302Optional Rect cullRect is a conservative bounds of text, taking into account
Cary Clarkce101242017-09-01 15:51:02 -04005303RSXform and paint. If cullRect is outside of Clip, canvas can skip drawing.
Cary Clark8032b982017-07-28 11:04:54 -04005304
Mike Reed8ad91a92018-01-19 19:09:32 -05005305All elements of paint: Path_Effect, Mask_Filter, Shader,
Cary Clarkbad5ad72017-08-03 17:14:08 -04005306Color_Filter, Image_Filter, and Draw_Looper; apply to text. By default, draws
Cary Clarkce101242017-09-01 15:51:02 -04005307filled 12 point black Glyphs.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005308
Cary Clarkce101242017-09-01 15:51:02 -04005309#Param text character code points or Glyphs drawn ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005310#Param byteLength byte length of text array ##
5311#Param xform RSXform rotates, scales, and translates each glyph individually ##
5312#Param cullRect Rect bounds of text for efficient clipping; or nullptr ##
5313#Param paint text size, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005314
5315#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04005316void draw(SkCanvas* canvas) {
5317 const int iterations = 26;
5318 SkRSXform transforms[iterations];
5319 char alphabet[iterations];
5320 SkScalar angle = 0;
5321 SkScalar scale = 1;
5322 for (size_t i = 0; i < SK_ARRAY_COUNT(transforms); ++i) {
5323 const SkScalar s = SkScalarSin(angle) * scale;
5324 const SkScalar c = SkScalarCos(angle) * scale;
5325 transforms[i] = SkRSXform::Make(-c, -s, -s * 16, c * 16);
5326 angle += .45;
5327 scale += .2;
5328 alphabet[i] = 'A' + i;
5329 }
5330 SkPaint paint;
5331 paint.setTextAlign(SkPaint::kCenter_Align);
5332 canvas->translate(110, 138);
5333 canvas->drawTextRSXform(alphabet, sizeof(alphabet), transforms, nullptr, paint);
Cary Clark8032b982017-07-28 11:04:54 -04005334}
5335##
5336
Cary Clark2ade9972017-11-02 17:49:34 -04005337#SeeAlso drawTextOnPath drawTextOnPathHV drawText drawPosText drawTextBlob
Cary Clark8032b982017-07-28 11:04:54 -04005338
5339##
5340
5341# ------------------------------------------------------------------------------
5342
5343#Method void drawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y, const SkPaint& paint)
5344
5345Draw Text_Blob blob at (x, y), using Clip, Matrix, and Paint paint.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005346
Cary Clarkce101242017-09-01 15:51:02 -04005347blob contains Glyphs, their positions, and paint attributes specific to text:
Cary Clarkbad5ad72017-08-03 17:14:08 -04005348Typeface, Paint_Text_Size, Paint_Text_Scale_X, Paint_Text_Skew_X,
5349Paint_Text_Align, Paint_Hinting, Anti-alias, Paint_Fake_Bold,
5350Font_Embedded_Bitmaps, Full_Hinting_Spacing, LCD_Text, Linear_Text,
5351Subpixel_Text, and Paint_Vertical_Text.
Cary Clark8032b982017-07-28 11:04:54 -04005352
Cary Clark3cd22cc2017-12-01 11:49:58 -05005353Paint_Text_Encoding must be set to SkPaint::kGlyphID_TextEncoding.
5354
Mike Reed8ad91a92018-01-19 19:09:32 -05005355Elements of paint: Path_Effect, Mask_Filter, Shader, Color_Filter,
Cary Clark8032b982017-07-28 11:04:54 -04005356Image_Filter, and Draw_Looper; apply to blob.
5357
Cary Clarkce101242017-09-01 15:51:02 -04005358#Param blob Glyphs, positions, and their paints' text size, typeface, and so on ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005359#Param x horizontal offset applied to blob ##
5360#Param y vertical offset applied to blob ##
5361#Param paint blend, color, stroking, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005362
5363#Example
5364#Height 120
Cary Clarkbad5ad72017-08-03 17:14:08 -04005365 void draw(SkCanvas* canvas) {
Cary Clark2f466242017-12-11 16:03:17 -05005366 SkTextBlobBuilder textBlobBuilder;
5367 const char bunny[] = "/(^x^)\\";
5368 const int len = sizeof(bunny) - 1;
5369 uint16_t glyphs[len];
5370 SkPaint paint;
5371 paint.textToGlyphs(bunny, len, glyphs);
Cary Clark3cd22cc2017-12-01 11:49:58 -05005372 paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
Cary Clark2f466242017-12-11 16:03:17 -05005373 int runs[] = { 3, 1, 3 };
5374 SkPoint textPos = { 20, 100 };
5375 int glyphIndex = 0;
5376 for (auto runLen : runs) {
5377 paint.setTextSize(1 == runLen ? 20 : 50);
5378 const SkTextBlobBuilder::RunBuffer& run =
5379 textBlobBuilder.allocRun(paint, runLen, textPos.fX, textPos.fY);
5380 memcpy(run.glyphs, &glyphs[glyphIndex], sizeof(glyphs[0]) * runLen);
5381 textPos.fX += paint.measureText(&glyphs[glyphIndex], sizeof(glyphs[0]) * runLen, nullptr);
5382 glyphIndex += runLen;
5383 }
5384 sk_sp<const SkTextBlob> blob = textBlobBuilder.make();
5385 paint.reset();
Cary Clarkbad5ad72017-08-03 17:14:08 -04005386 canvas->drawTextBlob(blob.get(), 0, 0, paint);
Cary Clark8032b982017-07-28 11:04:54 -04005387 }
5388##
5389
Cary Clark2ade9972017-11-02 17:49:34 -04005390#SeeAlso drawText drawPosText drawPosTextH
Cary Clark8032b982017-07-28 11:04:54 -04005391
5392##
5393
5394# ------------------------------------------------------------------------------
5395
5396#Method void drawTextBlob(const sk_sp<SkTextBlob>& blob, SkScalar x, SkScalar y, const SkPaint& paint)
5397
5398Draw Text_Blob blob at (x, y), using Clip, Matrix, and Paint paint.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005399
Cary Clarkce101242017-09-01 15:51:02 -04005400blob contains Glyphs, their positions, and paint attributes specific to text:
Cary Clarkbad5ad72017-08-03 17:14:08 -04005401Typeface, Paint_Text_Size, Paint_Text_Scale_X, Paint_Text_Skew_X,
5402Paint_Text_Align, Paint_Hinting, Anti-alias, Paint_Fake_Bold,
5403Font_Embedded_Bitmaps, Full_Hinting_Spacing, LCD_Text, Linear_Text,
5404Subpixel_Text, and Paint_Vertical_Text.
Cary Clark8032b982017-07-28 11:04:54 -04005405
Cary Clark3cd22cc2017-12-01 11:49:58 -05005406Paint_Text_Encoding must be set to SkPaint::kGlyphID_TextEncoding.
5407
Mike Reed8ad91a92018-01-19 19:09:32 -05005408Elements of paint: Path_Effect, Mask_Filter, Shader, Color_Filter,
Cary Clark8032b982017-07-28 11:04:54 -04005409Image_Filter, and Draw_Looper; apply to blob.
5410
Cary Clarkce101242017-09-01 15:51:02 -04005411#Param blob Glyphs, positions, and their paints' text size, typeface, and so on ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005412#Param x horizontal offset applied to blob ##
5413#Param y vertical offset applied to blob ##
5414#Param paint blend, color, stroking, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005415
5416#Example
5417#Height 120
5418#Description
5419Paint attributes unrelated to text, like color, have no effect on paint in allocated Text_Blob.
5420Paint attributes related to text, like text size, have no effect on paint passed to drawTextBlob.
5421##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005422 void draw(SkCanvas* canvas) {
5423 SkTextBlobBuilder textBlobBuilder;
5424 SkPaint paint;
5425 paint.setTextSize(50);
5426 paint.setColor(SK_ColorRED);
Cary Clark2f466242017-12-11 16:03:17 -05005427 paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
Cary Clarkbad5ad72017-08-03 17:14:08 -04005428 const SkTextBlobBuilder::RunBuffer& run =
5429 textBlobBuilder.allocRun(paint, 1, 20, 100);
5430 run.glyphs[0] = 20;
5431 sk_sp<const SkTextBlob> blob = textBlobBuilder.make();
5432 paint.setTextSize(10);
5433 paint.setColor(SK_ColorBLUE);
5434 canvas->drawTextBlob(blob.get(), 0, 0, paint);
5435 }
Cary Clark8032b982017-07-28 11:04:54 -04005436##
5437
Cary Clark2ade9972017-11-02 17:49:34 -04005438#SeeAlso drawText drawPosText drawPosTextH
Cary Clark8032b982017-07-28 11:04:54 -04005439
5440##
5441
5442# ------------------------------------------------------------------------------
5443
5444#Method void drawPicture(const SkPicture* picture)
5445
5446Draw Picture picture, using Clip and Matrix.
5447Clip and Matrix are unchanged by picture contents, as if
5448save() was called before and restore() was called after drawPicture.
5449
5450Picture records a series of draw commands for later playback.
5451
Cary Clarkbad5ad72017-08-03 17:14:08 -04005452#Param picture recorded drawing commands to play ##
Cary Clark8032b982017-07-28 11:04:54 -04005453
5454#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04005455void draw(SkCanvas* canvas) {
5456 SkPictureRecorder recorder;
5457 SkCanvas* recordingCanvas = recorder.beginRecording(50, 50);
5458 for (auto color : { SK_ColorRED, SK_ColorBLUE, 0xff007f00 } ) {
5459 SkPaint paint;
5460 paint.setColor(color);
5461 recordingCanvas->drawRect({10, 10, 30, 40}, paint);
5462 recordingCanvas->translate(10, 10);
5463 recordingCanvas->scale(1.2f, 1.4f);
5464 }
5465 sk_sp<SkPicture> playback = recorder.finishRecordingAsPicture();
5466 const SkPicture* playbackPtr = playback.get();
5467 canvas->drawPicture(playback);
5468 canvas->scale(2, 2);
5469 canvas->translate(50, 0);
5470 canvas->drawPicture(playback);
Cary Clark8032b982017-07-28 11:04:54 -04005471}
5472##
5473
Cary Clark2ade9972017-11-02 17:49:34 -04005474#SeeAlso drawDrawable SkPicture SkPicture::playback
Cary Clark8032b982017-07-28 11:04:54 -04005475
5476##
5477
5478# ------------------------------------------------------------------------------
5479
5480#Method void drawPicture(const sk_sp<SkPicture>& picture)
5481
5482Draw Picture picture, using Clip and Matrix.
5483Clip and Matrix are unchanged by picture contents, as if
5484save() was called before and restore() was called after drawPicture.
5485
5486Picture records a series of draw commands for later playback.
5487
Cary Clarkbad5ad72017-08-03 17:14:08 -04005488#Param picture recorded drawing commands to play ##
Cary Clark8032b982017-07-28 11:04:54 -04005489
5490#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04005491void draw(SkCanvas* canvas) {
5492 SkPictureRecorder recorder;
5493 SkCanvas* recordingCanvas = recorder.beginRecording(50, 50);
5494 for (auto color : { SK_ColorRED, SK_ColorBLUE, 0xff007f00 } ) {
5495 SkPaint paint;
5496 paint.setColor(color);
5497 recordingCanvas->drawRect({10, 10, 30, 40}, paint);
5498 recordingCanvas->translate(10, 10);
5499 recordingCanvas->scale(1.2f, 1.4f);
5500 }
5501 sk_sp<SkPicture> playback = recorder.finishRecordingAsPicture();
5502 canvas->drawPicture(playback);
5503 canvas->scale(2, 2);
5504 canvas->translate(50, 0);
5505 canvas->drawPicture(playback);
Cary Clark8032b982017-07-28 11:04:54 -04005506}
5507##
5508
Cary Clark2ade9972017-11-02 17:49:34 -04005509#SeeAlso drawDrawable SkPicture SkPicture::playback
Cary Clark8032b982017-07-28 11:04:54 -04005510
5511##
5512
5513# ------------------------------------------------------------------------------
5514
5515#Method void drawPicture(const SkPicture* picture, const SkMatrix* matrix, const SkPaint* paint)
5516
Cary Clarkbad5ad72017-08-03 17:14:08 -04005517Draw Picture picture, using Clip and Matrix; transforming picture with
5518Matrix matrix, if provided; and use Paint paint Color_Alpha, Color_Filter,
5519Image_Filter, and Blend_Mode, if provided.
Cary Clark8032b982017-07-28 11:04:54 -04005520
5521matrix transformation is equivalent to: save(), concat(), drawPicture, restore().
5522paint use is equivalent to: saveLayer, drawPicture, restore().
5523
Cary Clarkbad5ad72017-08-03 17:14:08 -04005524#Param picture recorded drawing commands to play ##
5525#Param matrix Matrix to rotate, scale, translate, and so on; may be nullptr ##
5526#Param paint Paint to apply transparency, filtering, and so on; may be nullptr ##
Cary Clark8032b982017-07-28 11:04:54 -04005527
5528#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04005529void draw(SkCanvas* canvas) {
5530 SkPaint paint;
5531 SkPictureRecorder recorder;
5532 SkCanvas* recordingCanvas = recorder.beginRecording(50, 50);
5533 for (auto color : { SK_ColorRED, SK_ColorBLUE, 0xff007f00 } ) {
5534 paint.setColor(color);
5535 recordingCanvas->drawRect({10, 10, 30, 40}, paint);
5536 recordingCanvas->translate(10, 10);
5537 recordingCanvas->scale(1.2f, 1.4f);
5538 }
5539 sk_sp<SkPicture> playback = recorder.finishRecordingAsPicture();
5540 const SkPicture* playbackPtr = playback.get();
5541 SkMatrix matrix;
5542 matrix.reset();
5543 for (auto alpha : { 70, 140, 210 } ) {
5544 paint.setAlpha(alpha);
5545 canvas->drawPicture(playbackPtr, &matrix, &paint);
5546 matrix.preTranslate(70, 70);
5547 }
Cary Clark8032b982017-07-28 11:04:54 -04005548}
5549##
5550
Cary Clark2ade9972017-11-02 17:49:34 -04005551#SeeAlso drawDrawable SkPicture SkPicture::playback
Cary Clark8032b982017-07-28 11:04:54 -04005552
5553##
5554
5555# ------------------------------------------------------------------------------
5556
5557#Method void drawPicture(const sk_sp<SkPicture>& picture, const SkMatrix* matrix, const SkPaint* paint)
5558
Cary Clarkbad5ad72017-08-03 17:14:08 -04005559Draw Picture picture, using Clip and Matrix; transforming picture with
5560Matrix matrix, if provided; and use Paint paint Color_Alpha, Color_Filter,
5561Image_Filter, and Blend_Mode, if provided.
Cary Clark8032b982017-07-28 11:04:54 -04005562
5563matrix transformation is equivalent to: save(), concat(), drawPicture, restore().
5564paint use is equivalent to: saveLayer, drawPicture, restore().
5565
Cary Clarkbad5ad72017-08-03 17:14:08 -04005566#Param picture recorded drawing commands to play ##
5567#Param matrix Matrix to rotate, scale, translate, and so on; may be nullptr ##
5568#Param paint Paint to apply transparency, filtering, and so on; may be nullptr ##
Cary Clark8032b982017-07-28 11:04:54 -04005569
5570#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04005571void draw(SkCanvas* canvas) {
5572 SkPaint paint;
5573 SkPictureRecorder recorder;
5574 SkCanvas* recordingCanvas = recorder.beginRecording(50, 50);
5575 for (auto color : { SK_ColorRED, SK_ColorBLUE, 0xff007f00 } ) {
5576 paint.setColor(color);
5577 recordingCanvas->drawRect({10, 10, 30, 40}, paint);
5578 recordingCanvas->translate(10, 10);
5579 recordingCanvas->scale(1.2f, 1.4f);
5580 }
5581 sk_sp<SkPicture> playback = recorder.finishRecordingAsPicture();
5582 SkMatrix matrix;
5583 matrix.reset();
5584 for (auto alpha : { 70, 140, 210 } ) {
5585 paint.setAlpha(alpha);
5586 canvas->drawPicture(playback, &matrix, &paint);
5587 matrix.preTranslate(70, 70);
5588 }
Cary Clark8032b982017-07-28 11:04:54 -04005589}
5590##
5591
Cary Clark2ade9972017-11-02 17:49:34 -04005592#SeeAlso drawDrawable SkPicture SkPicture::playback
Cary Clark8032b982017-07-28 11:04:54 -04005593
5594##
5595
5596# ------------------------------------------------------------------------------
5597
5598#Method void drawVertices(const SkVertices* vertices, SkBlendMode mode, const SkPaint& paint)
5599
5600Draw Vertices vertices, a triangle mesh, using Clip and Matrix.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005601If Vertices_Texs and Vertices_Colors are defined in vertices, and Paint paint
5602contains Shader, Blend_Mode mode combines Vertices_Colors with Shader.
Cary Clark8032b982017-07-28 11:04:54 -04005603
Cary Clarkbad5ad72017-08-03 17:14:08 -04005604#Param vertices triangle mesh to draw ##
5605#Param mode combines Vertices_Colors with Shader, if both are present ##
5606#Param paint specifies the Shader, used as Vertices texture; may be nullptr ##
Cary Clark8032b982017-07-28 11:04:54 -04005607
5608#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04005609void draw(SkCanvas* canvas) {
5610 SkPaint paint;
5611 SkPoint points[] = { { 0, 0 }, { 250, 0 }, { 100, 100 }, { 0, 250 } };
5612 SkColor colors[] = { SK_ColorRED, SK_ColorBLUE, SK_ColorYELLOW, SK_ColorCYAN };
5613 auto vertices = SkVertices::MakeCopy(SkVertices::kTriangleFan_VertexMode,
5614 SK_ARRAY_COUNT(points), points, nullptr, colors);
5615 canvas->drawVertices(vertices.get(), SkBlendMode::kSrc, paint);
5616}
Cary Clark8032b982017-07-28 11:04:54 -04005617##
5618
Cary Clark2ade9972017-11-02 17:49:34 -04005619#SeeAlso drawPatch drawPicture
Cary Clark8032b982017-07-28 11:04:54 -04005620
5621##
5622
5623# ------------------------------------------------------------------------------
5624
5625#Method void drawVertices(const sk_sp<SkVertices>& vertices, SkBlendMode mode, const SkPaint& paint)
5626
5627Draw Vertices vertices, a triangle mesh, using Clip and Matrix.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005628If Vertices_Texs and Vertices_Colors are defined in vertices, and Paint paint
5629contains Shader, Blend_Mode mode combines Vertices_Colors with Shader.
Cary Clark8032b982017-07-28 11:04:54 -04005630
Cary Clarkbad5ad72017-08-03 17:14:08 -04005631#Param vertices triangle mesh to draw ##
5632#Param mode combines Vertices_Colors with Shader, if both are present ##
5633#Param paint specifies the Shader, used as Vertices texture, may be nullptr ##
Cary Clark8032b982017-07-28 11:04:54 -04005634
5635#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04005636void draw(SkCanvas* canvas) {
5637 SkPaint paint;
5638 SkPoint points[] = { { 0, 0 }, { 250, 0 }, { 100, 100 }, { 0, 250 } };
5639 SkPoint texs[] = { { 0, 0 }, { 0, 250 }, { 250, 250 }, { 250, 0 } };
5640 SkColor colors[] = { SK_ColorRED, SK_ColorBLUE, SK_ColorYELLOW, SK_ColorCYAN };
5641 paint.setShader(SkGradientShader::MakeLinear(points, colors, nullptr, 4,
5642 SkShader::kClamp_TileMode));
5643 auto vertices = SkVertices::MakeCopy(SkVertices::kTriangleFan_VertexMode,
5644 SK_ARRAY_COUNT(points), points, texs, colors);
5645 canvas->drawVertices(vertices.get(), SkBlendMode::kDarken, paint);
Cary Clark8032b982017-07-28 11:04:54 -04005646}
5647##
5648
Cary Clark2ade9972017-11-02 17:49:34 -04005649#SeeAlso drawPatch drawPicture
Cary Clark8032b982017-07-28 11:04:54 -04005650
5651##
5652
5653# ------------------------------------------------------------------------------
5654
5655#Method void drawPatch(const SkPoint cubics[12], const SkColor colors[4],
5656 const SkPoint texCoords[4], SkBlendMode mode, const SkPaint& paint)
5657
Cary Clarka560c472017-11-27 10:44:06 -05005658Draws a Coons_Patch: the interpolation of four cubics with shared corners,
Cary Clark8032b982017-07-28 11:04:54 -04005659associating a color, and optionally a texture coordinate, with each corner.
5660
Cary Clarka560c472017-11-27 10:44:06 -05005661Coons_Patch uses Clip and Matrix, paint Shader, Color_Filter,
Cary Clarkbad5ad72017-08-03 17:14:08 -04005662Color_Alpha, Image_Filter, and Blend_Mode. If Shader is provided it is treated
Cary Clarka560c472017-11-27 10:44:06 -05005663as Coons_Patch texture; Blend_Mode mode combines Color colors and Shader if
Cary Clarkbad5ad72017-08-03 17:14:08 -04005664both are provided.
Cary Clark8032b982017-07-28 11:04:54 -04005665
Cary Clarkbc5697d2017-10-04 14:31:33 -04005666Point array cubics specifies four Cubics starting at the top-left corner,
Cary Clarkce101242017-09-01 15:51:02 -04005667in clockwise order, sharing every fourth point. The last Cubic ends at the
Cary Clarkbad5ad72017-08-03 17:14:08 -04005668first point.
Cary Clark8032b982017-07-28 11:04:54 -04005669
Cary Clarkbc5697d2017-10-04 14:31:33 -04005670Color array color associates colors with corners in top-left, top-right,
5671bottom-right, bottom-left order.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005672
5673If paint contains Shader, Point array texCoords maps Shader as texture to
Cary Clarkbc5697d2017-10-04 14:31:33 -04005674corners in top-left, top-right, bottom-right, bottom-left order.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005675
Cary Clarka523d2d2017-08-30 08:58:10 -04005676#Param cubics Path_Cubic array, sharing common points ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005677#Param colors Color array, one for each corner ##
Cary Clarkce101242017-09-01 15:51:02 -04005678#Param texCoords Point array of texture coordinates, mapping Shader to corners;
Cary Clarkbad5ad72017-08-03 17:14:08 -04005679 may be nullptr
Cary Clark579985c2017-07-31 11:48:27 -04005680#Param ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005681#Param mode Blend_Mode for colors, and for Shader if paint has one ##
5682#Param paint Shader, Color_Filter, Blend_Mode, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005683
5684#Example
5685#Image 5
Cary Clarkbad5ad72017-08-03 17:14:08 -04005686void draw(SkCanvas* canvas) {
5687 // SkBitmap source = cmbkygk;
5688 SkPaint paint;
5689 paint.setFilterQuality(kLow_SkFilterQuality);
5690 paint.setAntiAlias(true);
5691 SkPoint cubics[] = { { 3, 1 }, { 4, 2 }, { 5, 1 }, { 7, 3 },
5692 /* { 7, 3 }, */ { 6, 4 }, { 7, 5 }, { 5, 7 },
5693 /* { 5, 7 }, */ { 4, 6 }, { 3, 7 }, { 1, 5 },
5694 /* { 1, 5 }, */ { 2, 4 }, { 1, 3 }, /* { 3, 1 } */ };
5695 SkColor colors[] = { 0xbfff0000, 0xbf0000ff, 0xbfff00ff, 0xbf00ffff };
5696 SkPoint texCoords[] = { { -30, -30 }, { 162, -30}, { 162, 162}, { -30, 162} };
5697 paint.setShader(SkShader::MakeBitmapShader(source, SkShader::kClamp_TileMode,
5698 SkShader::kClamp_TileMode, nullptr));
5699 canvas->scale(15, 15);
5700 for (auto blend : { SkBlendMode::kSrcOver, SkBlendMode::kModulate, SkBlendMode::kXor } ) {
5701 canvas->drawPatch(cubics, colors, texCoords, blend, paint);
5702 canvas->translate(4, 4);
5703 }
Cary Clark8032b982017-07-28 11:04:54 -04005704}
5705##
5706
Cary Clark2ade9972017-11-02 17:49:34 -04005707#ToDo can patch use image filter? ##
5708#SeeAlso SeeAlso drawVertices drawPicture
Cary Clark8032b982017-07-28 11:04:54 -04005709
5710##
5711
5712# ------------------------------------------------------------------------------
5713
5714#Method void drawPatch(const SkPoint cubics[12], const SkColor colors[4],
5715 const SkPoint texCoords[4], const SkPaint& paint)
5716
Cary Clarka560c472017-11-27 10:44:06 -05005717Draws Cubic Coons_Patch: the interpolation of four cubics with shared corners,
Cary Clarkbad5ad72017-08-03 17:14:08 -04005718associating a color, and optionally a texture coordinate, with each corner.
Cary Clark8032b982017-07-28 11:04:54 -04005719
Cary Clarka560c472017-11-27 10:44:06 -05005720Coons_Patch uses Clip and Matrix, paint Shader, Color_Filter,
Cary Clarkbad5ad72017-08-03 17:14:08 -04005721Color_Alpha, Image_Filter, and Blend_Mode. If Shader is provided it is treated
Cary Clarka560c472017-11-27 10:44:06 -05005722as Coons_Patch texture; Blend_Mode mode combines Color colors and Shader if
Cary Clarkbad5ad72017-08-03 17:14:08 -04005723both are provided.
Cary Clark8032b982017-07-28 11:04:54 -04005724
Cary Clarkbc5697d2017-10-04 14:31:33 -04005725Point array cubics specifies four Cubics starting at the top-left corner,
Cary Clarkce101242017-09-01 15:51:02 -04005726in clockwise order, sharing every fourth point. The last Cubic ends at the
Cary Clarkbad5ad72017-08-03 17:14:08 -04005727first point.
5728
Cary Clarkbc5697d2017-10-04 14:31:33 -04005729Color array color associates colors with corners in top-left, top-right,
5730bottom-right, bottom-left order.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005731
5732If paint contains Shader, Point array texCoords maps Shader as texture to
Cary Clarkbc5697d2017-10-04 14:31:33 -04005733corners in top-left, top-right, bottom-right, bottom-left order.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005734
Cary Clarka523d2d2017-08-30 08:58:10 -04005735#Param cubics Path_Cubic array, sharing common points ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005736#Param colors Color array, one for each corner ##
Cary Clarkce101242017-09-01 15:51:02 -04005737#Param texCoords Point array of texture coordinates, mapping Shader to corners;
Cary Clarkbad5ad72017-08-03 17:14:08 -04005738 may be nullptr
Cary Clark579985c2017-07-31 11:48:27 -04005739#Param ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005740#Param paint Shader, Color_Filter, Blend_Mode, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005741
5742#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04005743void draw(SkCanvas* canvas) {
5744 SkPaint paint;
5745 paint.setAntiAlias(true);
5746 SkPoint cubics[] = { { 3, 1 }, { 4, 2 }, { 5, 1 }, { 7, 3 },
5747 /* { 7, 3 }, */ { 6, 4 }, { 7, 5 }, { 5, 7 },
5748 /* { 5, 7 }, */ { 4, 6 }, { 3, 7 }, { 1, 5 },
5749 /* { 1, 5 }, */ { 2, 4 }, { 1, 3 }, /* { 3, 1 } */ };
5750 SkColor colors[] = { SK_ColorRED, SK_ColorBLUE, SK_ColorYELLOW, SK_ColorCYAN };
5751 canvas->scale(30, 30);
5752 canvas->drawPatch(cubics, colors, nullptr, paint);
5753 SkPoint text[] = { {3,0.9f}, {4,2.5f}, {5,0.9f}, {7.5f,3.2f}, {5.5f,4.2f},
5754 {7.5f,5.2f}, {5,7.5f}, {4,5.9f}, {3,7.5f}, {0.5f,5.2f}, {2.5f,4.2f},
5755 {0.5f,3.2f} };
5756 paint.setTextSize(18.f / 30);
5757 paint.setTextAlign(SkPaint::kCenter_Align);
5758 for (int i = 0; i< 10; ++i) {
5759 char digit = '0' + i;
5760 canvas->drawText(&digit, 1, text[i].fX, text[i].fY, paint);
5761 }
5762 canvas->drawString("10", text[10].fX, text[10].fY, paint);
5763 canvas->drawString("11", text[11].fX, text[11].fY, paint);
5764 paint.setStyle(SkPaint::kStroke_Style);
5765 canvas->drawPoints(SkCanvas::kPolygon_PointMode, 12, cubics, paint);
5766 canvas->drawLine(cubics[11].fX, cubics[11].fY, cubics[0].fX, cubics[0].fY, paint);
Cary Clark8032b982017-07-28 11:04:54 -04005767}
5768##
5769
5770#Example
5771#Image 6
Cary Clarkbad5ad72017-08-03 17:14:08 -04005772void draw(SkCanvas* canvas) {
5773 // SkBitmap source = checkerboard;
5774 SkPaint paint;
5775 paint.setFilterQuality(kLow_SkFilterQuality);
5776 paint.setAntiAlias(true);
5777 SkPoint cubics[] = { { 3, 1 }, { 4, 2 }, { 5, 1 }, { 7, 3 },
5778 /* { 7, 3 }, */ { 6, 4 }, { 7, 5 }, { 5, 7 },
5779 /* { 5, 7 }, */ { 4, 6 }, { 3, 7 }, { 1, 5 },
5780 /* { 1, 5 }, */ { 2, 4 }, { 1, 3 }, /* { 3, 1 } */ };
5781 SkPoint texCoords[] = { { 0, 0 }, { 0, 62}, { 62, 62}, { 62, 0 } };
5782 paint.setShader(SkShader::MakeBitmapShader(source, SkShader::kClamp_TileMode,
5783 SkShader::kClamp_TileMode, nullptr));
5784 canvas->scale(30, 30);
5785 canvas->drawPatch(cubics, nullptr, texCoords, paint);
Cary Clark8032b982017-07-28 11:04:54 -04005786}
5787##
5788
Cary Clark2ade9972017-11-02 17:49:34 -04005789#ToDo can patch use image filter? ##
5790#SeeAlso SeeAlso drawVertices drawPicture
Cary Clark8032b982017-07-28 11:04:54 -04005791
5792##
5793
5794# ------------------------------------------------------------------------------
5795
5796#Method void drawAtlas(const SkImage* atlas, const SkRSXform xform[], const SkRect tex[],
5797 const SkColor colors[], int count, SkBlendMode mode, const SkRect* cullRect,
5798 const SkPaint* paint)
5799
5800Draw a set of sprites from atlas, using Clip, Matrix, and optional Paint paint.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005801paint uses Anti-alias, Color_Alpha, Color_Filter, Image_Filter, and Blend_Mode
5802to draw, if present. For each entry in the array, Rect tex locates sprite in
5803atlas, and RSXform xform transforms it into destination space.
5804
Cary Clark8032b982017-07-28 11:04:54 -04005805xform, text, and colors if present, must contain count entries.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005806Optional colors are applied for each sprite using Blend_Mode.
Cary Clark8032b982017-07-28 11:04:54 -04005807Optional cullRect is a conservative bounds of all transformed sprites.
Cary Clarkce101242017-09-01 15:51:02 -04005808If cullRect is outside of Clip, canvas can skip drawing.
Cary Clark8032b982017-07-28 11:04:54 -04005809
Cary Clarkbad5ad72017-08-03 17:14:08 -04005810#Param atlas Image containing sprites ##
5811#Param xform RSXform mappings for sprites in atlas ##
5812#Param tex Rect locations of sprites in atlas ##
Cary Clark6fc50412017-09-21 12:31:06 -04005813#Param colors one per sprite, blended with sprite using Blend_Mode; may be nullptr ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005814#Param count number of sprites to draw ##
5815#Param mode Blend_Mode combining colors and sprites ##
Cary Clark6fc50412017-09-21 12:31:06 -04005816#Param cullRect bounds of transformed sprites for efficient clipping; may be nullptr ##
5817#Param paint Color_Filter, Image_Filter, Blend_Mode, and so on; may be nullptr ##
Cary Clark8032b982017-07-28 11:04:54 -04005818
5819#Example
5820#Image 3
Cary Clarkbad5ad72017-08-03 17:14:08 -04005821void draw(SkCanvas* canvas) {
5822 // SkBitmap source = mandrill;
5823 SkRSXform xforms[] = { { .5f, 0, 0, 0 }, {0, .5f, 200, 100 } };
5824 SkRect tex[] = { { 0, 0, 250, 250 }, { 0, 0, 250, 250 } };
5825 SkColor colors[] = { 0x7f55aa00, 0x7f3333bf };
5826 const SkImage* imagePtr = image.get();
5827 canvas->drawAtlas(imagePtr, xforms, tex, colors, 2, SkBlendMode::kSrcOver, nullptr, nullptr);
Cary Clark8032b982017-07-28 11:04:54 -04005828}
5829##
5830
Cary Clark2ade9972017-11-02 17:49:34 -04005831#SeeAlso drawBitmap drawImage
Cary Clark8032b982017-07-28 11:04:54 -04005832
5833##
5834
5835# ------------------------------------------------------------------------------
5836
5837#Method void drawAtlas(const sk_sp<SkImage>& atlas, const SkRSXform xform[], const SkRect tex[],
5838 const SkColor colors[], int count, SkBlendMode mode, const SkRect* cullRect,
5839 const SkPaint* paint)
5840
5841Draw a set of sprites from atlas, using Clip, Matrix, and optional Paint paint.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005842paint uses Anti-alias, Color_Alpha, Color_Filter, Image_Filter, and Blend_Mode
5843to draw, if present. For each entry in the array, Rect tex locates sprite in
5844atlas, and RSXform xform transforms it into destination space.
5845
Cary Clark8032b982017-07-28 11:04:54 -04005846xform, text, and colors if present, must contain count entries.
5847Optional colors is applied for each sprite using Blend_Mode.
5848Optional cullRect is a conservative bounds of all transformed sprites.
Cary Clarkce101242017-09-01 15:51:02 -04005849If cullRect is outside of Clip, canvas can skip drawing.
Cary Clark8032b982017-07-28 11:04:54 -04005850
Cary Clarkbad5ad72017-08-03 17:14:08 -04005851#Param atlas Image containing sprites ##
5852#Param xform RSXform mappings for sprites in atlas ##
5853#Param tex Rect locations of sprites in atlas ##
Cary Clark6fc50412017-09-21 12:31:06 -04005854#Param colors one per sprite, blended with sprite using Blend_Mode; may be nullptr ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005855#Param count number of sprites to draw ##
5856#Param mode Blend_Mode combining colors and sprites ##
Cary Clark6fc50412017-09-21 12:31:06 -04005857#Param cullRect bounds of transformed sprites for efficient clipping; may be nullptr ##
5858#Param paint Color_Filter, Image_Filter, Blend_Mode, and so on; may be nullptr ##
Cary Clark8032b982017-07-28 11:04:54 -04005859
5860#Example
5861#Image 3
Cary Clarkbad5ad72017-08-03 17:14:08 -04005862void draw(SkCanvas* canvas) {
5863 // SkBitmap source = mandrill;
5864 SkRSXform xforms[] = { { .5f, 0, 0, 0 }, {0, .5f, 200, 100 } };
5865 SkRect tex[] = { { 0, 0, 250, 250 }, { 0, 0, 250, 250 } };
5866 SkColor colors[] = { 0x7f55aa00, 0x7f3333bf };
5867 SkPaint paint;
5868 paint.setAlpha(127);
5869 canvas->drawAtlas(image, xforms, tex, colors, 2, SkBlendMode::kPlus, nullptr, &paint);
Cary Clark8032b982017-07-28 11:04:54 -04005870}
5871##
5872
5873#ToDo bug in example on cpu side, gpu looks ok ##
5874
Cary Clark2ade9972017-11-02 17:49:34 -04005875#SeeAlso drawBitmap drawImage
5876
Cary Clark8032b982017-07-28 11:04:54 -04005877##
5878
5879# ------------------------------------------------------------------------------
5880
5881#Method void drawAtlas(const SkImage* atlas, const SkRSXform xform[], const SkRect tex[], int count,
5882 const SkRect* cullRect, const SkPaint* paint)
5883
5884Draw a set of sprites from atlas, using Clip, Matrix, and optional Paint paint.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005885paint uses Anti-alias, Color_Alpha, Color_Filter, Image_Filter, and Blend_Mode
5886to draw, if present. For each entry in the array, Rect tex locates sprite in
5887atlas, and RSXform xform transforms it into destination space.
5888
Cary Clark8032b982017-07-28 11:04:54 -04005889xform and text must contain count entries.
5890Optional cullRect is a conservative bounds of all transformed sprites.
Cary Clarkce101242017-09-01 15:51:02 -04005891If cullRect is outside of Clip, canvas can skip drawing.
Cary Clark8032b982017-07-28 11:04:54 -04005892
Cary Clarkbad5ad72017-08-03 17:14:08 -04005893#Param atlas Image containing sprites ##
5894#Param xform RSXform mappings for sprites in atlas ##
5895#Param tex Rect locations of sprites in atlas ##
5896#Param count number of sprites to draw ##
Cary Clark6fc50412017-09-21 12:31:06 -04005897#Param cullRect bounds of transformed sprites for efficient clipping; may be nullptr ##
5898#Param paint Color_Filter, Image_Filter, Blend_Mode, and so on; may be nullptr ##
Cary Clark8032b982017-07-28 11:04:54 -04005899
5900#Example
5901#Image 3
Cary Clarkbad5ad72017-08-03 17:14:08 -04005902void draw(SkCanvas* canvas) {
5903 // sk_sp<SkImage> image = mandrill;
5904 SkRSXform xforms[] = { { .5f, 0, 0, 0 }, {0, .5f, 200, 100 } };
5905 SkRect tex[] = { { 0, 0, 250, 250 }, { 0, 0, 250, 250 } };
5906 const SkImage* imagePtr = image.get();
5907 canvas->drawAtlas(imagePtr, xforms, tex, 2, nullptr, nullptr);
Cary Clark8032b982017-07-28 11:04:54 -04005908}
5909##
5910
Cary Clark2ade9972017-11-02 17:49:34 -04005911#SeeAlso drawBitmap drawImage
Cary Clark8032b982017-07-28 11:04:54 -04005912
5913##
5914
5915# ------------------------------------------------------------------------------
5916
5917#Method void drawAtlas(const sk_sp<SkImage>& atlas, const SkRSXform xform[], const SkRect tex[],
5918 int count, const SkRect* cullRect, const SkPaint* paint)
5919
5920Draw a set of sprites from atlas, using Clip, Matrix, and optional Paint paint.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005921paint uses Anti-alias, Color_Alpha, Color_Filter, Image_Filter, and Blend_Mode
5922to draw, if present. For each entry in the array, Rect tex locates sprite in
5923atlas, and RSXform xform transforms it into destination space.
5924
Cary Clark8032b982017-07-28 11:04:54 -04005925xform and text must contain count entries.
5926Optional cullRect is a conservative bounds of all transformed sprites.
Cary Clarkce101242017-09-01 15:51:02 -04005927If cullRect is outside of Clip, canvas can skip drawing.
Cary Clark8032b982017-07-28 11:04:54 -04005928
Cary Clarkbad5ad72017-08-03 17:14:08 -04005929#Param atlas Image containing sprites ##
5930#Param xform RSXform mappings for sprites in atlas ##
5931#Param tex Rect locations of sprites in atlas ##
5932#Param count number of sprites to draw ##
Cary Clark6fc50412017-09-21 12:31:06 -04005933#Param cullRect bounds of transformed sprites for efficient clipping; may be nullptr ##
5934#Param paint Color_Filter, Image_Filter, Blend_Mode, and so on; may be nullptr ##
Cary Clark8032b982017-07-28 11:04:54 -04005935
5936#Example
5937#Image 3
Cary Clarkbad5ad72017-08-03 17:14:08 -04005938void draw(SkCanvas* canvas) {
5939 // sk_sp<SkImage> image = mandrill;
5940 SkRSXform xforms[] = { { 1, 0, 0, 0 }, {0, 1, 300, 100 } };
5941 SkRect tex[] = { { 0, 0, 200, 200 }, { 200, 0, 400, 200 } };
5942 canvas->drawAtlas(image, xforms, tex, 2, nullptr, nullptr);
Cary Clark8032b982017-07-28 11:04:54 -04005943}
5944##
5945
Cary Clark2ade9972017-11-02 17:49:34 -04005946#SeeAlso drawBitmap drawImage
Cary Clark8032b982017-07-28 11:04:54 -04005947
5948##
5949
5950# ------------------------------------------------------------------------------
5951
Cary Clark73fa9722017-08-29 17:36:51 -04005952#Method void drawDrawable(SkDrawable* drawable, const SkMatrix* matrix = nullptr)
Cary Clark8032b982017-07-28 11:04:54 -04005953
5954Draw Drawable drawable using Clip and Matrix, concatenated with
5955optional matrix.
5956
5957If Canvas has an asynchronous implementation, as is the case
5958when it is recording into Picture, then drawable will be referenced,
5959so that SkDrawable::draw() can be called when the operation is finalized. To force
5960immediate drawing, call SkDrawable::draw() instead.
5961
Cary Clarkbad5ad72017-08-03 17:14:08 -04005962#Param drawable custom struct encapsulating drawing commands ##
5963#Param matrix transformation applied to drawing; may be nullptr ##
Cary Clark8032b982017-07-28 11:04:54 -04005964
5965#Example
5966#Height 100
5967#Function
Cary Clarkbad5ad72017-08-03 17:14:08 -04005968struct MyDrawable : public SkDrawable {
5969 SkRect onGetBounds() override { return SkRect::MakeWH(50, 100); }
5970
5971 void onDraw(SkCanvas* canvas) override {
5972 SkPath path;
5973 path.conicTo(10, 90, 50, 90, 0.9f);
5974 SkPaint paint;
5975 paint.setColor(SK_ColorBLUE);
5976 canvas->drawRect(path.getBounds(), paint);
5977 paint.setAntiAlias(true);
5978 paint.setColor(SK_ColorWHITE);
5979 canvas->drawPath(path, paint);
5980 }
5981};
5982
5983#Function ##
5984void draw(SkCanvas* canvas) {
5985 sk_sp<SkDrawable> drawable(new MyDrawable);
5986 SkMatrix matrix;
5987 matrix.setTranslate(10, 10);
5988 canvas->drawDrawable(drawable.get(), &matrix);
Cary Clark8032b982017-07-28 11:04:54 -04005989}
5990##
5991
Cary Clark2ade9972017-11-02 17:49:34 -04005992#SeeAlso SkDrawable drawPicture
Cary Clark8032b982017-07-28 11:04:54 -04005993
5994##
5995
5996# ------------------------------------------------------------------------------
5997
5998#Method void drawDrawable(SkDrawable* drawable, SkScalar x, SkScalar y)
5999
6000Draw Drawable drawable using Clip and Matrix, offset by (x, y).
6001
6002If Canvas has an asynchronous implementation, as is the case
6003when it is recording into Picture, then drawable will be referenced,
6004so that SkDrawable::draw() can be called when the operation is finalized. To force
6005immediate drawing, call SkDrawable::draw() instead.
6006
Cary Clarkbad5ad72017-08-03 17:14:08 -04006007#Param drawable custom struct encapsulating drawing commands ##
6008#Param x offset into Canvas writable pixels in x ##
6009#Param y offset into Canvas writable pixels in y ##
Cary Clark8032b982017-07-28 11:04:54 -04006010
6011#Example
6012#Height 100
6013#Function
Cary Clarkbad5ad72017-08-03 17:14:08 -04006014struct MyDrawable : public SkDrawable {
6015 SkRect onGetBounds() override { return SkRect::MakeWH(50, 100); }
6016
6017 void onDraw(SkCanvas* canvas) override {
6018 SkPath path;
6019 path.conicTo(10, 90, 50, 90, 0.9f);
6020 SkPaint paint;
6021 paint.setColor(SK_ColorBLUE);
6022 canvas->drawRect(path.getBounds(), paint);
6023 paint.setAntiAlias(true);
6024 paint.setColor(SK_ColorWHITE);
6025 canvas->drawPath(path, paint);
6026 }
6027};
6028
6029#Function ##
6030void draw(SkCanvas* canvas) {
6031 sk_sp<SkDrawable> drawable(new MyDrawable);
6032 canvas->drawDrawable(drawable.get(), 10, 10);
Cary Clark8032b982017-07-28 11:04:54 -04006033}
6034##
6035
Cary Clark2ade9972017-11-02 17:49:34 -04006036#SeeAlso SkDrawable drawPicture
Cary Clark8032b982017-07-28 11:04:54 -04006037
6038##
6039
6040# ------------------------------------------------------------------------------
6041
6042#Method void drawAnnotation(const SkRect& rect, const char key[], SkData* value)
6043
6044Associate Rect on Canvas when an annotation; a key-value pair, where the key is
6045a null-terminated utf8 string, and optional value is stored as Data.
6046
6047Only some canvas implementations, such as recording to Picture, or drawing to
6048Document_PDF, use annotations.
6049
Cary Clarkbad5ad72017-08-03 17:14:08 -04006050#Param rect Rect extent of canvas to annotate ##
6051#Param key string used for lookup ##
6052#Param value data holding value stored in annotation ##
Cary Clark8032b982017-07-28 11:04:54 -04006053
6054#Example
6055 #Height 1
6056 const char text[] = "Click this link!";
6057 SkRect bounds;
6058 SkPaint paint;
6059 paint.setTextSize(40);
6060 (void)paint.measureText(text, strlen(text), &bounds);
6061 const char url[] = "https://www.google.com/";
6062 sk_sp<SkData> urlData(SkData::MakeWithCString(url));
6063 canvas->drawAnnotation(bounds, "url_key", urlData.get());
6064##
6065
Cary Clark2ade9972017-11-02 17:49:34 -04006066#SeeAlso SkPicture SkDocument
Cary Clark8032b982017-07-28 11:04:54 -04006067
6068##
6069
6070# ------------------------------------------------------------------------------
6071
6072#Method void drawAnnotation(const SkRect& rect, const char key[], const sk_sp<SkData>& value)
6073
6074Associate Rect on Canvas when an annotation; a key-value pair, where the key is
6075a null-terminated utf8 string, and optional value is stored as Data.
6076
6077Only some canvas implementations, such as recording to Picture, or drawing to
6078Document_PDF, use annotations.
6079
Cary Clarkbad5ad72017-08-03 17:14:08 -04006080#Param rect Rect extent of canvas to annotate ##
6081#Param key string used for lookup ##
6082#Param value data holding value stored in annotation ##
Cary Clark8032b982017-07-28 11:04:54 -04006083
6084#Example
6085#Height 1
6086 const char text[] = "Click this link!";
6087 SkRect bounds;
6088 SkPaint paint;
6089 paint.setTextSize(40);
6090 (void)paint.measureText(text, strlen(text), &bounds);
6091 const char url[] = "https://www.google.com/";
6092 sk_sp<SkData> urlData(SkData::MakeWithCString(url));
6093 canvas->drawAnnotation(bounds, "url_key", urlData.get());
6094##
6095
Cary Clark2ade9972017-11-02 17:49:34 -04006096#SeeAlso SkPicture SkDocument
Cary Clark8032b982017-07-28 11:04:54 -04006097
6098##
6099
6100#Method SkDrawFilter* getDrawFilter() const
6101
6102Legacy call to be deprecated.
6103
6104#Deprecated
6105##
6106
6107##
6108
6109#Method virtual SkDrawFilter* setDrawFilter(SkDrawFilter* filter)
6110
6111Legacy call to be deprecated.
6112
6113#Deprecated
6114##
6115
6116##
6117
6118# ------------------------------------------------------------------------------
6119
6120#Method virtual bool isClipEmpty() const
6121
6122Returns true if Clip is empty; that is, nothing will draw.
6123
Cary Clarkbad5ad72017-08-03 17:14:08 -04006124May do work when called; it should not be called
Cary Clark8032b982017-07-28 11:04:54 -04006125more often than needed. However, once called, subsequent calls perform no
6126work until Clip changes.
6127
Cary Clarkbad5ad72017-08-03 17:14:08 -04006128#Return true if Clip is empty ##
Cary Clark8032b982017-07-28 11:04:54 -04006129
6130#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04006131 void draw(SkCanvas* canvas) {
6132 SkDebugf("clip is%s empty\n", canvas->isClipEmpty() ? "" : " not");
6133 SkPath path;
6134 canvas->clipPath(path);
6135 SkDebugf("clip is%s empty\n", canvas->isClipEmpty() ? "" : " not");
Cary Clark8032b982017-07-28 11:04:54 -04006136 }
6137 #StdOut
Cary Clarkbad5ad72017-08-03 17:14:08 -04006138 clip is not empty
Cary Clark8032b982017-07-28 11:04:54 -04006139 clip is empty
6140 ##
6141##
6142
Cary Clark2ade9972017-11-02 17:49:34 -04006143#SeeAlso isClipRect getLocalClipBounds getDeviceClipBounds
Cary Clark8032b982017-07-28 11:04:54 -04006144
6145##
6146
6147# ------------------------------------------------------------------------------
6148
6149#Method virtual bool isClipRect() const
6150
6151Returns true if Clip is Rect and not empty.
6152Returns false if the clip is empty, or if it is not Rect.
6153
Cary Clarkbad5ad72017-08-03 17:14:08 -04006154#Return true if Clip is Rect and not empty ##
Cary Clark8032b982017-07-28 11:04:54 -04006155
6156#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04006157 void draw(SkCanvas* canvas) {
6158 SkDebugf("clip is%s rect\n", canvas->isClipRect() ? "" : " not");
6159 canvas->clipRect({0, 0, 0, 0});
6160 SkDebugf("clip is%s rect\n", canvas->isClipRect() ? "" : " not");
Cary Clark8032b982017-07-28 11:04:54 -04006161 }
6162 #StdOut
Cary Clarkbad5ad72017-08-03 17:14:08 -04006163 clip is rect
Cary Clark8032b982017-07-28 11:04:54 -04006164 clip is not rect
6165 ##
6166##
6167
Cary Clark2ade9972017-11-02 17:49:34 -04006168#SeeAlso isClipEmpty getLocalClipBounds getDeviceClipBounds
Cary Clark8032b982017-07-28 11:04:54 -04006169
6170##
6171
6172#Class SkCanvas ##
Cary Clark884dd7d2017-10-11 10:37:52 -04006173
Cary Clark8032b982017-07-28 11:04:54 -04006174#Topic Canvas ##