blob: ddf081cb1fec1527cd8caf491cdc9836cf8b01fd [file] [log] [blame]
Cary Clark8032b982017-07-28 11:04:54 -04001#Topic Canvas
Cary Clark137b8742018-05-30 09:21:49 -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
Herb Derbyefe39bc2018-05-01 17:06:20 -040015To 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.
Cary Clark8032b982017-07-28 11:04:54 -040018Canvas 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.
Herb Derbyefe39bc2018-05-01 17:06:20 -040025This approach may be deprecated in the future.
Cary Clark8032b982017-07-28 11:04:54 -040026
Cary Clark682c58d2018-05-16 07:07:07 -040027#Subtopic Overview
28#Populate
29##
30
Cary Clark4855f782018-02-06 09:41:53 -050031#Subtopic Related_Function
Cary Clark08895c42018-02-01 09:37:32 -050032#Populate
33##
Cary Clark8032b982017-07-28 11:04:54 -040034
Cary Clark4855f782018-02-06 09:41:53 -050035#Subtopic Constant
Cary Clark08895c42018-02-01 09:37:32 -050036#Populate
37##
Cary Clark8032b982017-07-28 11:04:54 -040038
Cary Clark682c58d2018-05-16 07:07:07 -040039#Subtopic Struct
40#Populate
41##
42
43#Subtopic Typedef
Cary Clark08895c42018-02-01 09:37:32 -050044#Populate
45##
Cary Clark8032b982017-07-28 11:04:54 -040046
Cary Clark4855f782018-02-06 09:41:53 -050047#Subtopic Constructor
Cary Clark8032b982017-07-28 11:04:54 -040048
Cary Clark4855f782018-02-06 09:41:53 -050049Create the desired type of Surface to obtain its Canvas when possible. Useful
Cary Clark8032b982017-07-28 11:04:54 -040050when no Surface is required, and some helpers implicitly create Raster_Surface.
51
Cary Clark08895c42018-02-01 09:37:32 -050052#Populate
53##
Cary Clark8032b982017-07-28 11:04:54 -040054
Cary Clark4855f782018-02-06 09:41:53 -050055#Subtopic Member_Function
Cary Clark08895c42018-02-01 09:37:32 -050056#Populate
57##
Cary Clark8032b982017-07-28 11:04:54 -040058
59# ------------------------------------------------------------------------------
60
Cary Clarka560c472017-11-27 10:44:06 -050061#Method static std::unique_ptr<SkCanvas> MakeRasterDirect(const SkImageInfo& info, void* pixels,
62 size_t rowBytes,
63 const SkSurfaceProps* props = nullptr)
Cary Clark78de7512018-02-07 07:27:09 -050064#In Constructor
Cary Clarkab2621d2018-01-30 10:08:57 -050065#Line # creates from SkImageInfo and Pixel_Storage ##
Cary Clark8032b982017-07-28 11:04:54 -040066
Cary Clarkbad5ad72017-08-03 17:14:08 -040067Allocates raster Canvas that will draw directly into pixels.
Cary Clark8032b982017-07-28 11:04:54 -040068
Cary Clarkbad5ad72017-08-03 17:14:08 -040069Canvas is returned if all parameters are valid.
70Valid parameters include:
71info dimensions are zero or positive;
Cary Clark2dc84ad2018-01-26 12:56:22 -050072info contains Color_Type and Alpha_Type supported by Raster_Surface;
Cary Clarkbad5ad72017-08-03 17:14:08 -040073pixels is not nullptr;
Cary Clark2dc84ad2018-01-26 12:56:22 -050074rowBytes is zero or large enough to contain info width pixels of Color_Type.
Cary Clarkbad5ad72017-08-03 17:14:08 -040075
Herb Derbyefe39bc2018-05-01 17:06:20 -040076Pass zero for rowBytes to compute rowBytes from info width and size of pixel.
Cary Clarkf05bdda2017-08-24 12:59:48 -040077If rowBytes is greater than zero, it must be equal to or greater than
Cary Clark2dc84ad2018-01-26 12:56:22 -050078info width times bytes required for Color_Type.
Cary Clarkf05bdda2017-08-24 12:59:48 -040079
80Pixel buffer size should be info height times computed rowBytes.
Cary Clarka560c472017-11-27 10:44:06 -050081Pixels are not initialized.
82To access pixels after drawing, call flush() or peekPixels.
Cary Clarkbad5ad72017-08-03 17:14:08 -040083
Cary Clark2dc84ad2018-01-26 12:56:22 -050084#Param info width, height, Color_Type, Alpha_Type, Color_Space, of Raster_Surface;
Cary Clarkbad5ad72017-08-03 17:14:08 -040085 width, or height, or both, may be zero
Cary Clark8032b982017-07-28 11:04:54 -040086##
Cary Clarkf05bdda2017-08-24 12:59:48 -040087#Param pixels pointer to destination pixels buffer
Cary Clark8032b982017-07-28 11:04:54 -040088##
Cary Clarkf05bdda2017-08-24 12:59:48 -040089#Param rowBytes interval from one Surface row to the next, or zero
Cary Clark8032b982017-07-28 11:04:54 -040090##
Cary Clarka560c472017-11-27 10:44:06 -050091#Param props LCD striping orientation and setting for device independent fonts;
92 may be nullptr
93##
Cary Clark8032b982017-07-28 11:04:54 -040094
Cary Clarkbad5ad72017-08-03 17:14:08 -040095#Return Canvas if all parameters are valid; otherwise, nullptr ##
Cary Clark8032b982017-07-28 11:04:54 -040096
97#Example
98 #Description
99 Allocates a three by three bitmap, clears it to white, and draws a black pixel
100 in the center.
101 ##
Cary Clarkbad5ad72017-08-03 17:14:08 -0400102void draw(SkCanvas* ) {
Cary Clarkce101242017-09-01 15:51:02 -0400103 SkImageInfo info = SkImageInfo::MakeN32Premul(3, 3); // device aligned, 32 bpp, Premultiplied
Cary Clarkbad5ad72017-08-03 17:14:08 -0400104 const size_t minRowBytes = info.minRowBytes(); // bytes used by one bitmap row
Cary Clarka560c472017-11-27 10:44:06 -0500105 const size_t size = info.computeMinByteSize(); // bytes used by all rows
Cary Clarkbad5ad72017-08-03 17:14:08 -0400106 SkAutoTMalloc<SkPMColor> storage(size); // allocate storage for pixels
107 SkPMColor* pixels = storage.get(); // get pointer to allocated storage
108 // create a SkCanvas backed by a raster device, and delete it when the
109 // function goes out of scope.
110 std::unique_ptr<SkCanvas> canvas = SkCanvas::MakeRasterDirect(info, pixels, minRowBytes);
Cary Clarkce101242017-09-01 15:51:02 -0400111 canvas->clear(SK_ColorWHITE); // white is Unpremultiplied, in ARGB order
Cary Clarkbad5ad72017-08-03 17:14:08 -0400112 canvas->flush(); // ensure that pixels are cleared
Cary Clarkce101242017-09-01 15:51:02 -0400113 SkPMColor pmWhite = pixels[0]; // the Premultiplied format may vary
Cary Clarkbad5ad72017-08-03 17:14:08 -0400114 SkPaint paint; // by default, draws black
115 canvas->drawPoint(1, 1, paint); // draw in the center
116 canvas->flush(); // ensure that point was drawn
117 for (int y = 0; y < info.height(); ++y) {
118 for (int x = 0; x < info.width(); ++x) {
119 SkDebugf("%c", *pixels++ == pmWhite ? '-' : 'x');
120 }
121 SkDebugf("\n");
122 }
Cary Clark8032b982017-07-28 11:04:54 -0400123}
124 #StdOut
125 ---
126 -x-
127 ---
128 ##
129##
130
Cary Clark8032b982017-07-28 11:04:54 -0400131#SeeAlso MakeRasterDirectN32 SkSurface::MakeRasterDirect
Cary Clark2ade9972017-11-02 17:49:34 -0400132
Cary Clark8032b982017-07-28 11:04:54 -0400133##
134
135# ------------------------------------------------------------------------------
136
137#Method static std::unique_ptr<SkCanvas> MakeRasterDirectN32(int width, int height, SkPMColor* pixels,
Herb Derbyefe39bc2018-05-01 17:06:20 -0400138 size_t rowBytes)
Cary Clark78de7512018-02-07 07:27:09 -0500139#In Constructor
Cary Clarkab2621d2018-01-30 10:08:57 -0500140#Line # creates from image data and Pixel_Storage ##
Cary Clark8032b982017-07-28 11:04:54 -0400141
Cary Clarkbad5ad72017-08-03 17:14:08 -0400142Allocates raster Canvas specified by inline image specification. Subsequent Canvas
143calls draw into pixels.
Cary Clark2dc84ad2018-01-26 12:56:22 -0500144Color_Type is set to kN32_SkColorType.
145Alpha_Type is set to kPremul_SkAlphaType.
Cary Clark8032b982017-07-28 11:04:54 -0400146To access pixels after drawing, call flush() or peekPixels.
147
Cary Clarkbad5ad72017-08-03 17:14:08 -0400148Canvas is returned if all parameters are valid.
149Valid parameters include:
Cary Clarkf05bdda2017-08-24 12:59:48 -0400150width and height are zero or positive;
Cary Clarkbad5ad72017-08-03 17:14:08 -0400151pixels is not nullptr;
Cary Clarkf05bdda2017-08-24 12:59:48 -0400152rowBytes is zero or large enough to contain width pixels of kN32_SkColorType.
Cary Clarkbad5ad72017-08-03 17:14:08 -0400153
Herb Derbyefe39bc2018-05-01 17:06:20 -0400154Pass zero for rowBytes to compute rowBytes from width and size of pixel.
Cary Clarkf05bdda2017-08-24 12:59:48 -0400155If rowBytes is greater than zero, it must be equal to or greater than
Cary Clark2dc84ad2018-01-26 12:56:22 -0500156width times bytes required for Color_Type.
Cary Clarkf05bdda2017-08-24 12:59:48 -0400157
158Pixel buffer size should be height times rowBytes.
Cary Clarkbad5ad72017-08-03 17:14:08 -0400159
160#Param width pixel column count on Raster_Surface created; must be zero or greater ##
Cary Clarkbc5697d2017-10-04 14:31:33 -0400161#Param height pixel row count on Raster_Surface created; must be zero or greater ##
Cary Clarkbad5ad72017-08-03 17:14:08 -0400162#Param pixels pointer to destination pixels buffer; buffer size should be height
Cary Clarkf05bdda2017-08-24 12:59:48 -0400163 times rowBytes
Cary Clark8032b982017-07-28 11:04:54 -0400164##
Cary Clarkf05bdda2017-08-24 12:59:48 -0400165#Param rowBytes interval from one Surface row to the next, or zero
Cary Clark8032b982017-07-28 11:04:54 -0400166##
167
Cary Clarkbad5ad72017-08-03 17:14:08 -0400168#Return Canvas if all parameters are valid; otherwise, nullptr ##
Cary Clark8032b982017-07-28 11:04:54 -0400169
170#Example
171 #Description
172 Allocates a three by three bitmap, clears it to white, and draws a black pixel
173 in the center.
174 ##
175void draw(SkCanvas* ) {
176 const int width = 3;
177 const int height = 3;
Cary Clarkce101242017-09-01 15:51:02 -0400178 SkPMColor pixels[height][width]; // allocate a 3x3 Premultiplied bitmap on the stack
Cary Clark8032b982017-07-28 11:04:54 -0400179 // create a SkCanvas backed by a raster device, and delete it when the
180 // function goes out of scope.
181 std::unique_ptr<SkCanvas> canvas = SkCanvas::MakeRasterDirectN32(
182 width,
183 height,
Cary Clarkbc5697d2017-10-04 14:31:33 -0400184 pixels[0], // top-left of the bitmap
Cary Clark8032b982017-07-28 11:04:54 -0400185 sizeof(pixels[0])); // byte width of the each row
Cary Clark682c58d2018-05-16 07:07:07 -0400186 // write a Premultiplied value for white into all pixels in the bitmap
Cary Clark8032b982017-07-28 11:04:54 -0400187 canvas->clear(SK_ColorWHITE);
Cary Clarkce101242017-09-01 15:51:02 -0400188 SkPMColor pmWhite = pixels[0][0]; // the Premultiplied format may vary
Cary Clark8032b982017-07-28 11:04:54 -0400189 SkPaint paint; // by default, draws black
190 canvas->drawPoint(1, 1, paint); // draw in the center
191 canvas->flush(); // ensure that pixels is ready to be read
192 for (int y = 0; y < height; ++y) {
193 for (int x = 0; x < width; ++x) {
194 SkDebugf("%c", pixels[y][x] == pmWhite ? '-' : 'x');
195 }
196 SkDebugf("\n");
197 }
198}
199 #StdOut
200 ---
201 -x-
202 ---
203 ##
204##
205
Cary Clark2ade9972017-11-02 17:49:34 -0400206#SeeAlso MakeRasterDirect SkSurface::MakeRasterDirect SkImageInfo::MakeN32Premul
Cary Clark8032b982017-07-28 11:04:54 -0400207
208##
209
210# ------------------------------------------------------------------------------
211
212#Method SkCanvas()
213
Cary Clarkab2621d2018-01-30 10:08:57 -0500214#Line # creates with no Surface, no dimensions ##
Herb Derbyefe39bc2018-05-01 17:06:20 -0400215Creates an empty Canvas with no backing device or pixels, with
Cary Clarkf05bdda2017-08-24 12:59:48 -0400216a width and height of zero.
Cary Clark8032b982017-07-28 11:04:54 -0400217
Cary Clarkd0530ba2017-09-14 11:25:39 -0400218#Return empty Canvas ##
Cary Clark8032b982017-07-28 11:04:54 -0400219
220#Example
221
222#Description
223Passes a placeholder to a function that requires one.
224##
225
226#Function
Cary Clarkbad5ad72017-08-03 17:14:08 -0400227// Returns true if either the canvas rotates the text by 90 degrees, or the paint does.
228static void check_for_up_and_down_text(const SkCanvas* canvas, const SkPaint& paint) {
229 bool paintHasVertical = paint.isVerticalText();
230 const SkMatrix& matrix = canvas->getTotalMatrix();
231 bool matrixIsVertical = matrix.preservesRightAngles() && !matrix.isScaleTranslate();
232 SkDebugf("paint draws text %s\n", paintHasVertical != matrixIsVertical ?
233 "top to bottom" : "left to right");
234}
235
236static void check_for_up_and_down_text(const SkPaint& paint) {
237 SkCanvas canvas; // placeholder only, does not have an associated device
238 check_for_up_and_down_text(&canvas, paint);
239}
240
Cary Clark8032b982017-07-28 11:04:54 -0400241##
Cary Clarkbad5ad72017-08-03 17:14:08 -0400242void draw(SkCanvas* canvas) {
243 SkPaint paint;
244 check_for_up_and_down_text(paint); // paint draws text left to right
245 paint.setVerticalText(true);
246 check_for_up_and_down_text(paint); // paint draws text top to bottom
247 paint.setVerticalText(false);
248 canvas->rotate(90);
249 check_for_up_and_down_text(canvas, paint); // paint draws text top to bottom
250}
Cary Clark8032b982017-07-28 11:04:54 -0400251
252 #StdOut
253 paint draws text left to right
254 paint draws text top to bottom
255 paint draws text top to bottom
256 ##
257##
258
Cary Clark2ade9972017-11-02 17:49:34 -0400259#SeeAlso MakeRasterDirect SkRasterHandleAllocator::MakeCanvas SkSurface::getCanvas SkCreateColorSpaceXformCanvas
Cary Clark8032b982017-07-28 11:04:54 -0400260
261##
262
263# ------------------------------------------------------------------------------
264
Cary Clark73fa9722017-08-29 17:36:51 -0400265#Method SkCanvas(int width, int height, const SkSurfaceProps* props = nullptr)
Cary Clark8032b982017-07-28 11:04:54 -0400266
Cary Clark682c58d2018-05-16 07:07:07 -0400267#Line # creates with no Surface, set dimensions, Surface_Properties ##
Cary Clark8032b982017-07-28 11:04:54 -0400268Creates Canvas of the specified dimensions without a Surface.
Cary Clark682c58d2018-05-16 07:07:07 -0400269Used by Subclasses with custom implementations for draw member functions.
Cary Clark8032b982017-07-28 11:04:54 -0400270
Cary Clarkd0530ba2017-09-14 11:25:39 -0400271If props equals nullptr, Surface_Properties are created with
Herb Derbyefe39bc2018-05-01 17:06:20 -0400272Surface_Properties_Legacy_Font_Host settings, which choose the pixel striping
Cary Clarkd0530ba2017-09-14 11:25:39 -0400273direction and order. Since a platform may dynamically change its direction when
274the device is rotated, and since a platform may have multiple monitors with
275different characteristics, it is best not to rely on this legacy behavior.
Cary Clark8032b982017-07-28 11:04:54 -0400276
Cary Clarkbad5ad72017-08-03 17:14:08 -0400277#Param width zero or greater ##
278#Param height zero or greater ##
279#Param props LCD striping orientation and setting for device independent fonts;
280 may be nullptr
281##
282
283#Return Canvas placeholder with dimensions ##
Cary Clark8032b982017-07-28 11:04:54 -0400284
285#Example
286 SkCanvas canvas(10, 20); // 10 units wide, 20 units high
287 canvas.clipRect(SkRect::MakeXYWH(30, 40, 5, 10)); // clip is outside canvas' device
288 SkDebugf("canvas %s empty\n", canvas.getDeviceClipBounds().isEmpty() ? "is" : "is not");
289
290 #StdOut
291 canvas is empty
292 ##
293##
294
Cary Clark2ade9972017-11-02 17:49:34 -0400295#SeeAlso MakeRasterDirect SkSurfaceProps SkPixelGeometry SkCreateColorSpaceXformCanvas
Cary Clark8032b982017-07-28 11:04:54 -0400296
297##
298
299# ------------------------------------------------------------------------------
300
Herb Derbyefe39bc2018-05-01 17:06:20 -0400301#Method explicit SkCanvas(sk_sp<SkBaseDevice> device)
Cary Clark4855f782018-02-06 09:41:53 -0500302#Deprecated soon
Cary Clark8032b982017-07-28 11:04:54 -0400303##
304
305# ------------------------------------------------------------------------------
306
307#Method explicit SkCanvas(const SkBitmap& bitmap)
308
Cary Clarkab2621d2018-01-30 10:08:57 -0500309#Line # uses existing Bitmap ##
Cary Clark8032b982017-07-28 11:04:54 -0400310Construct a canvas that draws into bitmap.
Herb Derbyefe39bc2018-05-01 17:06:20 -0400311Sets SkSurfaceProps::kLegacyFontHost_InitType in constructed Surface.
Cary Clark8032b982017-07-28 11:04:54 -0400312
Cary Clarkbad5ad72017-08-03 17:14:08 -0400313Bitmap is copied so that subsequently editing bitmap will not affect
314constructed Canvas.
315
316May be deprecated in the future.
317
Cary Clark8032b982017-07-28 11:04:54 -0400318#ToDo Should be deprecated? ##
319
Cary Clark2dc84ad2018-01-26 12:56:22 -0500320#Param bitmap width, height, Color_Type, Alpha_Type, and pixel
Cary Clarkbad5ad72017-08-03 17:14:08 -0400321 storage of Raster_Surface
Cary Clark8032b982017-07-28 11:04:54 -0400322##
323
Cary Clarkbad5ad72017-08-03 17:14:08 -0400324#Return Canvas that can be used to draw into bitmap ##
Cary Clark8032b982017-07-28 11:04:54 -0400325
326#Example
327#Description
328The actual output depends on the installed fonts.
329##
330 SkBitmap bitmap;
331 // create a bitmap 5 wide and 11 high
332 bitmap.allocPixels(SkImageInfo::MakeN32Premul(5, 11));
333 SkCanvas canvas(bitmap);
Cary Clarkce101242017-09-01 15:51:02 -0400334 canvas.clear(SK_ColorWHITE); // white is Unpremultiplied, in ARGB order
Cary Clark8032b982017-07-28 11:04:54 -0400335 SkPixmap pixmap; // provides guaranteed access to the drawn pixels
336 if (!canvas.peekPixels(&pixmap)) {
337 SkDebugf("peekPixels should never fail.\n");
338 }
Cary Clarkbc5697d2017-10-04 14:31:33 -0400339 const SkPMColor* pixels = pixmap.addr32(); // points to top-left of bitmap
Cary Clarkce101242017-09-01 15:51:02 -0400340 SkPMColor pmWhite = pixels[0]; // the Premultiplied format may vary
Cary Clark8032b982017-07-28 11:04:54 -0400341 SkPaint paint; // by default, draws black, 12 point text
342 canvas.drawString("!", 1, 10, paint); // 1 char at baseline (1, 10)
343 for (int y = 0; y < bitmap.height(); ++y) {
344 for (int x = 0; x < bitmap.width(); ++x) {
345 SkDebugf("%c", *pixels++ == pmWhite ? '-' : 'x');
346 }
347 SkDebugf("\n");
348 }
349
350 #StdOut
Cary Clarkd0530ba2017-09-14 11:25:39 -0400351 -----
352 ---x-
353 ---x-
354 ---x-
355 ---x-
356 ---x-
357 ---x-
358 -----
359 ---x-
360 ---x-
Cary Clark8032b982017-07-28 11:04:54 -0400361 -----
362 #StdOut ##
363##
364
Cary Clark2ade9972017-11-02 17:49:34 -0400365#SeeAlso MakeRasterDirect SkRasterHandleAllocator::MakeCanvas SkSurface::getCanvas SkCreateColorSpaceXformCanvas
Cary Clark8032b982017-07-28 11:04:54 -0400366
367##
368
Cary Clarkbad5ad72017-08-03 17:14:08 -0400369#EnumClass ColorBehavior
Cary Clark682c58d2018-05-16 07:07:07 -0400370#Line # exists for Android framework only ##
Cary Clark8032b982017-07-28 11:04:54 -0400371#Private
372Android framework only.
373##
374
375#Code
376 enum class ColorBehavior {
377 kLegacy,
378 };
379##
380#Const kLegacy 0
Cary Clark682c58d2018-05-16 07:07:07 -0400381#Line # placeholder ##
Cary Clarkbad5ad72017-08-03 17:14:08 -0400382 Is a placeholder to allow specialized constructor; has no meaning.
Cary Clark8032b982017-07-28 11:04:54 -0400383##
384##
385
Cary Clarkbad5ad72017-08-03 17:14:08 -0400386#Method SkCanvas(const SkBitmap& bitmap, ColorBehavior behavior)
387
Cary Clark682c58d2018-05-16 07:07:07 -0400388#Line # exists for Android framework only ##
389
Cary Clarkbad5ad72017-08-03 17:14:08 -0400390Android framework only.
Cary Clarkbad5ad72017-08-03 17:14:08 -0400391
392#Param bitmap specifies a bitmap for the canvas to draw into ##
393#Param behavior specializes this constructor; value is unused ##
394#Return Canvas that can be used to draw into bitmap ##
395
396#NoExample
397##
398##
Cary Clark8032b982017-07-28 11:04:54 -0400399
400# ------------------------------------------------------------------------------
401
402#Method SkCanvas(const SkBitmap& bitmap, const SkSurfaceProps& props)
403
Cary Clarkab2621d2018-01-30 10:08:57 -0500404#Line # uses existing Bitmap and Surface_Properties ##
Cary Clark8032b982017-07-28 11:04:54 -0400405Construct a canvas that draws into bitmap.
406Use props to match the device characteristics, like LCD striping.
407
Cary Clarkbad5ad72017-08-03 17:14:08 -0400408bitmap is copied so that subsequently editing bitmap will not affect
409constructed Canvas.
410
Cary Clark2dc84ad2018-01-26 12:56:22 -0500411#Param bitmap width, height, Color_Type, Alpha_Type,
Herb Derbyefe39bc2018-05-01 17:06:20 -0400412 and pixel storage of Raster_Surface
Cary Clark8032b982017-07-28 11:04:54 -0400413##
Cary Clarkbad5ad72017-08-03 17:14:08 -0400414#Param props order and orientation of RGB striping; and whether to use
415 device independent fonts
Cary Clark8032b982017-07-28 11:04:54 -0400416##
417
Cary Clarkbad5ad72017-08-03 17:14:08 -0400418#Return Canvas that can be used to draw into bitmap ##
Cary Clark8032b982017-07-28 11:04:54 -0400419
420#Example
421#Description
422The actual output depends on the installed fonts.
423##
424 SkBitmap bitmap;
425 // create a bitmap 5 wide and 11 high
426 bitmap.allocPixels(SkImageInfo::MakeN32Premul(5, 11));
427 SkCanvas canvas(bitmap, SkSurfaceProps(0, kUnknown_SkPixelGeometry));
Cary Clarkce101242017-09-01 15:51:02 -0400428 canvas.clear(SK_ColorWHITE); // white is Unpremultiplied, in ARGB order
Cary Clark8032b982017-07-28 11:04:54 -0400429 SkPixmap pixmap; // provides guaranteed access to the drawn pixels
430 if (!canvas.peekPixels(&pixmap)) {
431 SkDebugf("peekPixels should never fail.\n");
432 }
Cary Clarkbc5697d2017-10-04 14:31:33 -0400433 const SkPMColor* pixels = pixmap.addr32(); // points to top-left of bitmap
Cary Clarkce101242017-09-01 15:51:02 -0400434 SkPMColor pmWhite = pixels[0]; // the Premultiplied format may vary
Cary Clark8032b982017-07-28 11:04:54 -0400435 SkPaint paint; // by default, draws black, 12 point text
436 canvas.drawString("!", 1, 10, paint); // 1 char at baseline (1, 10)
437 for (int y = 0; y < bitmap.height(); ++y) {
438 for (int x = 0; x < bitmap.width(); ++x) {
439 SkDebugf("%c", *pixels++ == pmWhite ? '-' : 'x');
440 }
441 SkDebugf("\n");
442 }
443
444 #StdOut
445 -----
446 ---x-
447 ---x-
448 ---x-
449 ---x-
450 ---x-
451 ---x-
452 -----
453 ---x-
454 ---x-
455 -----
456 #StdOut ##
457##
458
Cary Clark2ade9972017-11-02 17:49:34 -0400459#SeeAlso MakeRasterDirect SkRasterHandleAllocator::MakeCanvas SkSurface::getCanvas SkCreateColorSpaceXformCanvas
Cary Clark8032b982017-07-28 11:04:54 -0400460
461##
462
463# ------------------------------------------------------------------------------
464
465#Method virtual ~SkCanvas()
466
Cary Clarkab2621d2018-01-30 10:08:57 -0500467#Line # draws saved Layers, frees resources ##
Cary Clark5081eed2018-01-22 07:55:48 -0500468Draws saved Layers, if any.
469Frees up resources used by Canvas.
Cary Clark8032b982017-07-28 11:04:54 -0400470
471#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -0400472#Description
Cary Clarkce101242017-09-01 15:51:02 -0400473Canvas Layer draws into bitmap. saveLayerAlpha sets up an additional
474drawing surface that blends with the bitmap. When Layer goes out of
475scope, Layer Destructor is called. The saved Layer is restored, drawing
Cary Clarkbad5ad72017-08-03 17:14:08 -0400476transparent letters.
477##
Cary Clarkf05bdda2017-08-24 12:59:48 -0400478void draw(SkCanvas* canvas) {
479 SkBitmap bitmap;
480 bitmap.allocPixels(SkImageInfo::MakeN32Premul(200, 200));
481 {
482 SkCanvas offscreen(bitmap);
483 SkPaint paint;
484 paint.setTextSize(100);
485 offscreen.drawString("ABC", 20, 160, paint);
486 SkRect layerBounds = SkRect::MakeXYWH(32, 32, 192, 192);
487 offscreen.saveLayerAlpha(&layerBounds, 128);
488 offscreen.clear(SK_ColorWHITE);
489 offscreen.drawString("DEF", 20, 160, paint);
490 }
491 canvas->drawBitmap(bitmap, 0, 0, nullptr);
Cary Clarkbad5ad72017-08-03 17:14:08 -0400492}
Cary Clark8032b982017-07-28 11:04:54 -0400493##
494
Cary Clarkbad5ad72017-08-03 17:14:08 -0400495#SeeAlso State_Stack
Cary Clark8032b982017-07-28 11:04:54 -0400496
497##
498
499# ------------------------------------------------------------------------------
Cary Clark78de7512018-02-07 07:27:09 -0500500#Subtopic Property
501#Populate
502#Line # metrics and attributes ##
503##
Cary Clark8032b982017-07-28 11:04:54 -0400504
505#Method SkMetaData& getMetaData()
Cary Clark78de7512018-02-07 07:27:09 -0500506#In Property
507#In Utility
Cary Clarkab2621d2018-01-30 10:08:57 -0500508#Line # associates additional data with the canvas ##
Cary Clarkf05bdda2017-08-24 12:59:48 -0400509Returns storage to associate additional data with the canvas.
Cary Clark8032b982017-07-28 11:04:54 -0400510The storage is freed when Canvas is deleted.
511
Cary Clarkbad5ad72017-08-03 17:14:08 -0400512#Return storage that can be read from and written to ##
Cary Clark8032b982017-07-28 11:04:54 -0400513
514#Example
515 const char* kHelloMetaData = "HelloMetaData";
516 SkCanvas canvas;
517 SkMetaData& metaData = canvas.getMetaData();
518 SkDebugf("before: %s\n", metaData.findString(kHelloMetaData));
519 metaData.setString(kHelloMetaData, "Hello!");
520 SkDebugf("during: %s\n", metaData.findString(kHelloMetaData));
521 metaData.removeString(kHelloMetaData);
522 SkDebugf("after: %s\n", metaData.findString(kHelloMetaData));
523
524 #StdOut
525 before: (null)
526 during: Hello!
527 after: (null)
528 #StdOut ##
529##
530
Cary Clark2ade9972017-11-02 17:49:34 -0400531#SeeAlso SkMetaData
Cary Clark8032b982017-07-28 11:04:54 -0400532
533##
534
535# ------------------------------------------------------------------------------
536
537#Method SkImageInfo imageInfo() const
Cary Clark78de7512018-02-07 07:27:09 -0500538#In Property
Cary Clarkab2621d2018-01-30 10:08:57 -0500539#Line # returns Image_Info for Canvas ##
Cary Clark8032b982017-07-28 11:04:54 -0400540Returns Image_Info for Canvas. If Canvas is not associated with Raster_Surface or
Cary Clark2dc84ad2018-01-26 12:56:22 -0500541GPU_Surface, returned Color_Type is set to kUnknown_SkColorType.
Cary Clark8032b982017-07-28 11:04:54 -0400542
Cary Clark2dc84ad2018-01-26 12:56:22 -0500543#Return dimensions and Color_Type of Canvas ##
Cary Clark8032b982017-07-28 11:04:54 -0400544
545#Example
Cary Clarkf05bdda2017-08-24 12:59:48 -0400546 SkCanvas emptyCanvas;
547 SkImageInfo canvasInfo = emptyCanvas.imageInfo();
548 SkImageInfo emptyInfo;
549 SkDebugf("emptyInfo %c= canvasInfo\n", emptyInfo == canvasInfo ? '=' : '!');
550
551 #StdOut
552 emptyInfo == canvasInfo
553 ##
Cary Clark8032b982017-07-28 11:04:54 -0400554##
555
Cary Clark2ade9972017-11-02 17:49:34 -0400556#SeeAlso SkImageInfo MakeRasterDirect makeSurface
Cary Clark8032b982017-07-28 11:04:54 -0400557
558##
559
560# ------------------------------------------------------------------------------
561
562#Method bool getProps(SkSurfaceProps* props) const
Cary Clark78de7512018-02-07 07:27:09 -0500563#In Property
Cary Clarkab2621d2018-01-30 10:08:57 -0500564#Line # copies Surface_Properties if available ##
Cary Clark8032b982017-07-28 11:04:54 -0400565If Canvas is associated with Raster_Surface or
566GPU_Surface, copies Surface_Properties and returns true. Otherwise,
567return false and leave props unchanged.
568
Cary Clarkbad5ad72017-08-03 17:14:08 -0400569#Param props storage for writable SkSurfaceProps ##
Cary Clark8032b982017-07-28 11:04:54 -0400570
Cary Clarkbad5ad72017-08-03 17:14:08 -0400571#Return true if Surface_Properties was copied ##
Cary Clark8032b982017-07-28 11:04:54 -0400572
573#ToDo This seems old style. Deprecate? ##
574
575#Example
576 SkBitmap bitmap;
577 SkCanvas canvas(bitmap, SkSurfaceProps(0, kRGB_V_SkPixelGeometry));
578 SkSurfaceProps surfaceProps(0, kUnknown_SkPixelGeometry);
579 SkDebugf("isRGB:%d\n", SkPixelGeometryIsRGB(surfaceProps.pixelGeometry()));
580 if (!canvas.getProps(&surfaceProps)) {
581 SkDebugf("getProps failed unexpectedly.\n");
582 }
583 SkDebugf("isRGB:%d\n", SkPixelGeometryIsRGB(surfaceProps.pixelGeometry()));
584
585 #StdOut
586 isRGB:0
587 isRGB:1
588 #StdOut ##
589##
590
Cary Clark2ade9972017-11-02 17:49:34 -0400591#SeeAlso SkSurfaceProps makeSurface
Cary Clark8032b982017-07-28 11:04:54 -0400592
593##
594
595# ------------------------------------------------------------------------------
Cary Clark78de7512018-02-07 07:27:09 -0500596#Subtopic Utility
597#Populate
598#Line # rarely called management functions ##
599##
Cary Clark8032b982017-07-28 11:04:54 -0400600
601#Method void flush()
Cary Clark78de7512018-02-07 07:27:09 -0500602#In Utility
Cary Clarkab2621d2018-01-30 10:08:57 -0500603#Line # triggers execution of all pending draw operations ##
Herb Derbyefe39bc2018-05-01 17:06:20 -0400604Triggers the immediate execution of all pending draw operations.
Cary Clarkbad5ad72017-08-03 17:14:08 -0400605If Canvas is associated with GPU_Surface, resolves all pending GPU operations.
Cary Clark2ade9972017-11-02 17:49:34 -0400606If Canvas is associated with Raster_Surface, has no effect; raster draw
607operations are never deferred.
608
609#ToDo
610In an overview section on managing the GPU, include:
611- flush should never change what is drawn
612- call to kick off gpu work
613- calling too much impacts performance
614- some calls (peekPixels, prepareForExternalIO) call it internally
615- canvas call is local, GrContext::flush is global
616- diffentiate between flush, flushAndSignalSemaphores
617- normally never needs to be called
618- call it when sharing gpu resources, feeling memory pressure, swapping out app, and before
619 abandoning context
620- also call to say "I'm finished drawing here", e.g., when drawing to a GPU-backed offscreen surface
621 (created with SkSurface::MakeRenderTarget)
622
623for posterity: this doesn't show a difference: fiddle.skia.org/c/@flushfail
624##
Cary Clark8032b982017-07-28 11:04:54 -0400625
Cary Clark08895c42018-02-01 09:37:32 -0500626#ToDo haven't thought of a useful example to put here ##
627#NoExample
Cary Clark8032b982017-07-28 11:04:54 -0400628##
629
Cary Clark2ade9972017-11-02 17:49:34 -0400630#SeeAlso peekPixels SkSurface::flush() GrContext::flush() SkSurface::prepareForExternalIO GrContext::abandonContext()
Cary Clark8032b982017-07-28 11:04:54 -0400631
632##
633
634# ------------------------------------------------------------------------------
635
636#Method virtual SkISize getBaseLayerSize() const
Cary Clark78de7512018-02-07 07:27:09 -0500637#In Property
Cary Clarkab2621d2018-01-30 10:08:57 -0500638#Line # returns size of base Layer in global coordinates ##
Cary Clarkce101242017-09-01 15:51:02 -0400639Gets the size of the base or root Layer in global canvas coordinates. The
640origin of the base Layer is always (0,0). The area available for drawing may be
Cary Clark8032b982017-07-28 11:04:54 -0400641smaller (due to clipping or saveLayer).
642
Cary Clarkce101242017-09-01 15:51:02 -0400643#Return integral width and height of base Layer ##
Cary Clark8032b982017-07-28 11:04:54 -0400644
645#Example
646 SkBitmap bitmap;
647 bitmap.allocPixels(SkImageInfo::MakeN32Premul(20, 30));
648 SkCanvas canvas(bitmap, SkSurfaceProps(0, kUnknown_SkPixelGeometry));
649 canvas.clipRect(SkRect::MakeWH(10, 40));
650 SkIRect clipDeviceBounds = canvas.getDeviceClipBounds();
651 if (clipDeviceBounds.isEmpty()) {
652 SkDebugf("Empty clip bounds is unexpected!\n");
653 }
654 SkDebugf("clip=%d,%d\n", clipDeviceBounds.width(), clipDeviceBounds.height());
655 SkISize baseLayerSize = canvas.getBaseLayerSize();
656 SkDebugf("size=%d,%d\n", baseLayerSize.width(), baseLayerSize.height());
657
658 #StdOut
659 clip=10,30
660 size=20,30
661 ##
662##
663
664#ToDo is this the same as the width and height of surface? ##
665
Cary Clark2ade9972017-11-02 17:49:34 -0400666#SeeAlso getDeviceClipBounds
667
Cary Clark8032b982017-07-28 11:04:54 -0400668##
669
670# ------------------------------------------------------------------------------
671
672#Method sk_sp<SkSurface> makeSurface(const SkImageInfo& info, const SkSurfaceProps* props = nullptr)
Cary Clark4855f782018-02-06 09:41:53 -0500673#In Constructor
Cary Clarkab2621d2018-01-30 10:08:57 -0500674#Line # creates Surface matching SkImageInfo and SkSurfaceProps ##
Cary Clark8032b982017-07-28 11:04:54 -0400675Creates Surface matching info and props, and associates it with Canvas.
Cary Clarkbad5ad72017-08-03 17:14:08 -0400676Returns nullptr if no match found.
Cary Clark8032b982017-07-28 11:04:54 -0400677
Cary Clarkbad5ad72017-08-03 17:14:08 -0400678If props is nullptr, matches Surface_Properties in Canvas. If props is nullptr and Canvas
679does not have Surface_Properties, creates Surface with default Surface_Properties.
Cary Clark8032b982017-07-28 11:04:54 -0400680
Cary Clark2dc84ad2018-01-26 12:56:22 -0500681#Param info width, height, Color_Type, Alpha_Type, and Color_Space ##
Cary Clarkbad5ad72017-08-03 17:14:08 -0400682#Param props Surface_Properties to match; may be nullptr to match Canvas ##
683
684#Return Surface matching info and props, or nullptr if no match is available ##
Cary Clark8032b982017-07-28 11:04:54 -0400685
686#Example
687 sk_sp<SkSurface> surface = SkSurface::MakeRasterN32Premul(5, 6);
688 SkCanvas* smallCanvas = surface->getCanvas();
689 SkImageInfo imageInfo = SkImageInfo::MakeN32Premul(3, 4);
690 sk_sp<SkSurface> compatible = smallCanvas->makeSurface(imageInfo);
691 SkDebugf("compatible %c= nullptr\n", compatible == nullptr ? '=' : '!');
692 SkDebugf("size = %d, %d\n", compatible->width(), compatible->height());
693
694 #StdOut
Cary Clarkbad5ad72017-08-03 17:14:08 -0400695 compatible != nullptr
Cary Clark8032b982017-07-28 11:04:54 -0400696 size = 3, 4
697 ##
698##
699
Cary Clark2ade9972017-11-02 17:49:34 -0400700#SeeAlso SkSurface SkSurface::makeSurface SkImageInfo SkSurfaceProps
Cary Clark8032b982017-07-28 11:04:54 -0400701
702##
703
704# ------------------------------------------------------------------------------
705
706#Method virtual GrContext* getGrContext()
Cary Clark78de7512018-02-07 07:27:09 -0500707#In Property
Cary Clarkab2621d2018-01-30 10:08:57 -0500708#Line # returns GPU_Context of the GPU_Surface ##
Cary Clark8032b982017-07-28 11:04:54 -0400709Returns GPU_Context of the GPU_Surface associated with Canvas.
710
Cary Clarkbad5ad72017-08-03 17:14:08 -0400711#Return GPU_Context, if available; nullptr otherwise ##
Cary Clark8032b982017-07-28 11:04:54 -0400712
713#Example
714void draw(SkCanvas* canvas) {
715 if (canvas->getGrContext()) {
716 canvas->clear(SK_ColorRED);
717 } else {
718 canvas->clear(SK_ColorBLUE);
719 }
720}
721##
722
723#ToDo fiddle should show both CPU and GPU out ##
724
Herb Derbyefe39bc2018-05-01 17:06:20 -0400725#SeeAlso GrContext
Cary Clark2ade9972017-11-02 17:49:34 -0400726
Cary Clark8032b982017-07-28 11:04:54 -0400727##
728
729# ------------------------------------------------------------------------------
730
Cary Clark73fa9722017-08-29 17:36:51 -0400731#Method void* accessTopLayerPixels(SkImageInfo* info, size_t* rowBytes, SkIPoint* origin = nullptr)
Cary Clark78de7512018-02-07 07:27:09 -0500732#In Utility
733#In Property
Cary Clarkab2621d2018-01-30 10:08:57 -0500734#Line # returns writable pixel access if available ##
Cary Clark8032b982017-07-28 11:04:54 -0400735Returns the pixel base address, Image_Info, rowBytes, and origin if the pixels
Cary Clarkbad5ad72017-08-03 17:14:08 -0400736can be read directly. The returned address is only valid
Cary Clark8032b982017-07-28 11:04:54 -0400737while Canvas is in scope and unchanged. Any Canvas call or Surface call
738may invalidate the returned address and other returned values.
739
740If pixels are inaccessible, info, rowBytes, and origin are unchanged.
741
Cary Clarkbad5ad72017-08-03 17:14:08 -0400742#Param info storage for writable pixels' Image_Info; may be nullptr ##
743#Param rowBytes storage for writable pixels' row bytes; may be nullptr ##
Cary Clarkbc5697d2017-10-04 14:31:33 -0400744#Param origin storage for Canvas top Layer origin, its top-left corner;
Cary Clarkbad5ad72017-08-03 17:14:08 -0400745 may be nullptr
746##
Cary Clark8032b982017-07-28 11:04:54 -0400747
Cary Clarka523d2d2017-08-30 08:58:10 -0400748#Return address of pixels, or nullptr if inaccessible ##
Cary Clark8032b982017-07-28 11:04:54 -0400749
750#Example
751void draw(SkCanvas* canvas) {
752 if (canvas->accessTopLayerPixels(nullptr, nullptr)) {
753 canvas->clear(SK_ColorRED);
754 } else {
755 canvas->clear(SK_ColorBLUE);
756 }
757}
758##
759
760#Example
761#Description
Cary Clarkce101242017-09-01 15:51:02 -0400762Draws "ABC" on the device. Then draws "DEF" in Layer, and reads
763Layer to add a large dotted "DEF". Finally blends Layer with the
Herb Derbyefe39bc2018-05-01 17:06:20 -0400764device.
Cary Clark8032b982017-07-28 11:04:54 -0400765
Cary Clarkce101242017-09-01 15:51:02 -0400766The Layer and blended result appear on the CPU and GPU but the large dotted
Cary Clark8032b982017-07-28 11:04:54 -0400767"DEF" appear only on the CPU.
768##
769void draw(SkCanvas* canvas) {
Cary Clarkbad5ad72017-08-03 17:14:08 -0400770 SkPaint paint;
771 paint.setTextSize(100);
772 canvas->drawString("ABC", 20, 160, paint);
773 SkRect layerBounds = SkRect::MakeXYWH(32, 32, 192, 192);
774 canvas->saveLayerAlpha(&layerBounds, 128);
775 canvas->clear(SK_ColorWHITE);
776 canvas->drawString("DEF", 20, 160, paint);
777 SkImageInfo imageInfo;
778 size_t rowBytes;
779 SkIPoint origin;
780 uint32_t* access = (uint32_t*) canvas->accessTopLayerPixels(&imageInfo, &rowBytes, &origin);
781 if (access) {
782 int h = imageInfo.height();
783 int v = imageInfo.width();
784 int rowWords = rowBytes / sizeof(uint32_t);
785 for (int y = 0; y < h; ++y) {
786 int newY = (y - h / 2) * 2 + h / 2;
787 if (newY < 0 || newY >= h) {
788 continue;
789 }
790 for (int x = 0; x < v; ++x) {
791 int newX = (x - v / 2) * 2 + v / 2;
792 if (newX < 0 || newX >= v) {
793 continue;
794 }
795 if (access[y * rowWords + x] == SK_ColorBLACK) {
796 access[newY * rowWords + newX] = SK_ColorGRAY;
797 }
798 }
799 }
800
801 }
Cary Clark8032b982017-07-28 11:04:54 -0400802 canvas->restore();
803}
804##
805
806#ToDo there are no callers of this that I can find. Deprecate? ##
807#ToDo fiddle should show both CPU and GPU out ##
808
Cary Clark2ade9972017-11-02 17:49:34 -0400809#SeeAlso SkImageInfo SkPixmap
810
Cary Clark8032b982017-07-28 11:04:54 -0400811##
812
813# ------------------------------------------------------------------------------
814
815#Method SkRasterHandleAllocator::Handle accessTopRasterHandle() const
Cary Clark78de7512018-02-07 07:27:09 -0500816#In Utility
817#In Property
Cary Clarkab2621d2018-01-30 10:08:57 -0500818#Line # returns context that tracks Clip and Matrix ##
Cary Clark8032b982017-07-28 11:04:54 -0400819Returns custom context that tracks the Matrix and Clip.
820
821Use Raster_Handle_Allocator to blend Skia drawing with custom drawing, typically performed
Cary Clarkbc5697d2017-10-04 14:31:33 -0400822by the host platform user interface. The custom context returned is generated by
Cary Clarkbad5ad72017-08-03 17:14:08 -0400823SkRasterHandleAllocator::MakeCanvas, which creates a custom canvas with raster storage for
Cary Clark8032b982017-07-28 11:04:54 -0400824the drawing destination.
825
Cary Clarkce101242017-09-01 15:51:02 -0400826#Return context of custom allocation ##
Cary Clark8032b982017-07-28 11:04:54 -0400827
828#Example
829#Description
830#ToDo ##
831##
832#Function
833 static void DeleteCallback(void*, void* context) {
834 delete (char*) context;
835 }
836
837 class CustomAllocator : public SkRasterHandleAllocator {
838 public:
839 bool allocHandle(const SkImageInfo& info, Rec* rec) override {
840 char* context = new char[4]{'s', 'k', 'i', 'a'};
841 rec->fReleaseProc = DeleteCallback;
842 rec->fReleaseCtx = context;
843 rec->fHandle = context;
844 rec->fPixels = context;
845 rec->fRowBytes = 4;
846 return true;
847 }
848
849 void updateHandle(Handle handle, const SkMatrix& ctm, const SkIRect& clip_bounds) override {
850 // apply canvas matrix and clip to custom environment
851 }
852 };
853
854##
855 void draw(SkCanvas* canvas) {
856 const SkImageInfo info = SkImageInfo::MakeN32Premul(1, 1);
857 std::unique_ptr<SkCanvas> c2 =
858 SkRasterHandleAllocator::MakeCanvas(std::unique_ptr<CustomAllocator>(
859 new CustomAllocator()), info);
860 char* context = (char*) c2->accessTopRasterHandle();
861 SkDebugf("context = %.4s\n", context);
862
863 }
864 #StdOut
865 context = skia
866 ##
867 #ToDo skstd::make_unique could not be used because def is private -- note to fix in c++14? ##
868##
869
870#SeeAlso SkRasterHandleAllocator
871
872##
873
874# ------------------------------------------------------------------------------
Cary Clark78de7512018-02-07 07:27:09 -0500875#Subtopic Pixels
876#Populate
877#Line # read and write pixel values ##
878##
Cary Clark8032b982017-07-28 11:04:54 -0400879
880#Method bool peekPixels(SkPixmap* pixmap)
Cary Clark78de7512018-02-07 07:27:09 -0500881#In Pixels
Cary Clarkab2621d2018-01-30 10:08:57 -0500882#Line # returns if Canvas has direct access to its pixels ##
Cary Clark8032b982017-07-28 11:04:54 -0400883Returns true if Canvas has direct access to its pixels.
884
Cary Clarkf05bdda2017-08-24 12:59:48 -0400885Pixels are readable when Device is raster. Pixels are not readable when Canvas
Cary Clarkbad5ad72017-08-03 17:14:08 -0400886is returned from GPU_Surface, returned by SkDocument::beginPage, returned by
Cary Clarkf05bdda2017-08-24 12:59:48 -0400887SkPictureRecorder::beginRecording, or Canvas is the base of a utility class
Brian Osman46fe9c72018-03-09 15:44:34 -0500888like SkDebugCanvas.
Cary Clark8032b982017-07-28 11:04:54 -0400889
Cary Clarkf05bdda2017-08-24 12:59:48 -0400890pixmap is valid only while Canvas is in scope and unchanged. Any
Cary Clarkbad5ad72017-08-03 17:14:08 -0400891Canvas or Surface call may invalidate the pixmap values.
Cary Clark8032b982017-07-28 11:04:54 -0400892
Cary Clarkbc5697d2017-10-04 14:31:33 -0400893#Param pixmap storage for pixel state if pixels are readable; otherwise, ignored ##
Cary Clark8032b982017-07-28 11:04:54 -0400894
Cary Clarkbad5ad72017-08-03 17:14:08 -0400895#Return true if Canvas has direct access to pixels ##
Cary Clark8032b982017-07-28 11:04:54 -0400896
897#Example
898 SkPixmap pixmap;
899 if (canvas->peekPixels(&pixmap)) {
900 SkDebugf("width=%d height=%d\n", pixmap.bounds().width(), pixmap.bounds().height());
901 }
902 #StdOut
903 width=256 height=256
904 ##
905##
906
Cary Clark2ade9972017-11-02 17:49:34 -0400907#SeeAlso readPixels SkBitmap::peekPixels SkImage::peekPixels SkSurface::peekPixels
908
Cary Clark8032b982017-07-28 11:04:54 -0400909##
910
911# ------------------------------------------------------------------------------
912
913#Method bool readPixels(const SkImageInfo& dstInfo, void* dstPixels, size_t dstRowBytes,
914 int srcX, int srcY)
Cary Clark78de7512018-02-07 07:27:09 -0500915#In Pixels
Cary Clarkab2621d2018-01-30 10:08:57 -0500916#Line # copies and converts rectangle of pixels from Canvas ##
Cary Clark8032b982017-07-28 11:04:54 -0400917
Cary Clark154beea2017-10-26 07:58:48 -0400918Copies Rect of pixels from Canvas into dstPixels. Matrix and Clip are
Herb Derbyefe39bc2018-05-01 17:06:20 -0400919ignored.
Cary Clark6fc50412017-09-21 12:31:06 -0400920
Cary Clarka560c472017-11-27 10:44:06 -0500921Source Rect corners are (srcX, srcY) and (imageInfo().width(), imageInfo().height()).
922Destination Rect corners are (0, 0) and (dstInfo.width(), dstInfo.height()).
Cary Clark6fc50412017-09-21 12:31:06 -0400923Copies each readable pixel intersecting both rectangles, without scaling,
Cary Clarkf05bdda2017-08-24 12:59:48 -0400924converting to dstInfo.colorType() and dstInfo.alphaType() if required.
Cary Clark8032b982017-07-28 11:04:54 -0400925
Cary Clarkf05bdda2017-08-24 12:59:48 -0400926Pixels are readable when Device is raster, or backed by a GPU.
927Pixels are not readable when SkCanvas is returned by SkDocument::beginPage,
928returned by SkPictureRecorder::beginRecording, or Canvas is the base of a utility
Brian Osman46fe9c72018-03-09 15:44:34 -0500929class like SkDebugCanvas.
Cary Clark8032b982017-07-28 11:04:54 -0400930
Cary Clarkf05bdda2017-08-24 12:59:48 -0400931The destination pixel storage must be allocated by the caller.
Cary Clark8032b982017-07-28 11:04:54 -0400932
Cary Clark2dc84ad2018-01-26 12:56:22 -0500933Pixel values are converted only if Color_Type and Alpha_Type
Cary Clarkf05bdda2017-08-24 12:59:48 -0400934do not match. Only pixels within both source and destination rectangles
Cary Clark154beea2017-10-26 07:58:48 -0400935are copied. dstPixels contents outside Rect intersection are unchanged.
Cary Clarkf05bdda2017-08-24 12:59:48 -0400936
937Pass negative values for srcX or srcY to offset pixels across or down destination.
Cary Clark8032b982017-07-28 11:04:54 -0400938
939Does not copy, and returns false if:
940
941#List
Cary Clarkf05bdda2017-08-24 12:59:48 -0400942# Source and destination rectangles do not intersect. ##
943# Canvas pixels could not be converted to dstInfo.colorType() or dstInfo.alphaType(). ##
944# Canvas pixels are not readable; for instance, Canvas is document-based. ##
Cary Clark8032b982017-07-28 11:04:54 -0400945# dstRowBytes is too small to contain one row of pixels. ##
946##
947
Cary Clark2dc84ad2018-01-26 12:56:22 -0500948#Param dstInfo width, height, Color_Type, and Alpha_Type of dstPixels ##
Cary Clarkf05bdda2017-08-24 12:59:48 -0400949#Param dstPixels storage for pixels; dstInfo.height() times dstRowBytes, or larger ##
950#Param dstRowBytes size of one destination row; dstInfo.width() times pixel size, or larger ##
951#Param srcX offset into readable pixels in x; may be negative ##
952#Param srcY offset into readable pixels in y; may be negative ##
Cary Clark8032b982017-07-28 11:04:54 -0400953
Cary Clarkbad5ad72017-08-03 17:14:08 -0400954#Return true if pixels were copied ##
Cary Clark8032b982017-07-28 11:04:54 -0400955
956#Example
Cary Clarkf05bdda2017-08-24 12:59:48 -0400957#Width 64
958#Height 64
959#Description
960 A black circle drawn on a blue background provides an image to copy.
961 readPixels copies one quarter of the canvas into each of the four corners.
Cary Clarka560c472017-11-27 10:44:06 -0500962 The copied quarter circles overdraw the original circle.
Cary Clarkf05bdda2017-08-24 12:59:48 -0400963##
964 canvas->clear(SK_ColorBLUE);
965 SkPaint paint;
966 canvas->drawCircle(32, 32, 28, paint);
967 SkImageInfo info = SkImageInfo::Make(64, 64, kBGRA_8888_SkColorType, kPremul_SkAlphaType);
968 sk_sp<SkData> data(SkData::MakeUninitialized(info.minRowBytes() * info.height()));
969 sk_bzero(data->writable_data(), info.minRowBytes() * info.height());
970 for (int x : { 32, -32 } ) {
971 for (int y : { 32, -32 } ) {
972 canvas->readPixels(info, data->writable_data(), info.minRowBytes(), x, y);
Herb Derbyefe39bc2018-05-01 17:06:20 -0400973 }
Cary Clarkf05bdda2017-08-24 12:59:48 -0400974 }
975 sk_sp<SkImage> image = SkImage::MakeRasterData(info, data, info.minRowBytes());
976 canvas->drawImage(image, 0, 0);
977##
978
979#Example
Cary Clark8032b982017-07-28 11:04:54 -0400980#Description
Cary Clarkce101242017-09-01 15:51:02 -0400981 Canvas returned by Raster_Surface has Premultiplied pixel values.
982 clear() takes Unpremultiplied input with Color_Alpha equal 0x80
Cary Clarkffb3d682018-05-17 12:17:28 -0400983 and RGB equal 0x55, 0xAA, 0xFF. RGB is multiplied by Color_Alpha
Cary Clarkce101242017-09-01 15:51:02 -0400984 to generate Premultiplied value 0x802B5580. readPixels converts pixel back
985 to Unpremultiplied value 0x8056A9FF, introducing error.
Cary Clark8032b982017-07-28 11:04:54 -0400986##
987 canvas->clear(0x8055aaff);
988 for (SkAlphaType alphaType : { kPremul_SkAlphaType, kUnpremul_SkAlphaType } ) {
989 uint32_t pixel = 0;
990 SkImageInfo info = SkImageInfo::Make(1, 1, kBGRA_8888_SkColorType, alphaType);
991 if (canvas->readPixels(info, &pixel, 4, 0, 0)) {
992 SkDebugf("pixel = %08x\n", pixel);
993 }
994 }
995
996 #StdOut
997 pixel = 802b5580
998 pixel = 8056a9ff
999 ##
1000##
1001
Cary Clark2ade9972017-11-02 17:49:34 -04001002#SeeAlso peekPixels writePixels drawBitmap drawImage SkBitmap::readPixels SkPixmap::readPixels SkImage::readPixels SkSurface::readPixels
Cary Clark8032b982017-07-28 11:04:54 -04001003
1004##
1005
1006# ------------------------------------------------------------------------------
1007
1008#Method bool readPixels(const SkPixmap& pixmap, int srcX, int srcY)
1009
Cary Clark154beea2017-10-26 07:58:48 -04001010Copies Rect of pixels from Canvas into pixmap. Matrix and Clip are
Cary Clarka560c472017-11-27 10:44:06 -05001011ignored.
Cary Clark6fc50412017-09-21 12:31:06 -04001012
Cary Clarka560c472017-11-27 10:44:06 -05001013Source Rect corners are (srcX, srcY) and (imageInfo().width(), imageInfo().height()).
1014Destination Rect corners are (0, 0) and (pixmap.width(), pixmap.height()).
Cary Clark6fc50412017-09-21 12:31:06 -04001015Copies each readable pixel intersecting both rectangles, without scaling,
Cary Clarkf05bdda2017-08-24 12:59:48 -04001016converting to pixmap.colorType() and pixmap.alphaType() if required.
Cary Clark8032b982017-07-28 11:04:54 -04001017
Cary Clarkf05bdda2017-08-24 12:59:48 -04001018Pixels are readable when Device is raster, or backed by a GPU.
1019Pixels are not readable when SkCanvas is returned by SkDocument::beginPage,
1020returned by SkPictureRecorder::beginRecording, or Canvas is the base of a utility
Brian Osman46fe9c72018-03-09 15:44:34 -05001021class like SkDebugCanvas.
Cary Clark8032b982017-07-28 11:04:54 -04001022
Cary Clark6fc50412017-09-21 12:31:06 -04001023Caller must allocate pixel storage in pixmap if needed.
Cary Clark8032b982017-07-28 11:04:54 -04001024
Cary Clark2dc84ad2018-01-26 12:56:22 -05001025Pixel values are converted only if Color_Type and Alpha_Type
Cary Clark154beea2017-10-26 07:58:48 -04001026do not match. Only pixels within both source and destination Rects
1027are copied. pixmap pixels contents outside Rect intersection are unchanged.
Cary Clarkf05bdda2017-08-24 12:59:48 -04001028
1029Pass negative values for srcX or srcY to offset pixels across or down pixmap.
Cary Clark8032b982017-07-28 11:04:54 -04001030
1031Does not copy, and returns false if:
1032
1033#List
Cary Clarkf05bdda2017-08-24 12:59:48 -04001034# Source and destination rectangles do not intersect. ##
1035# Canvas pixels could not be converted to pixmap.colorType() or pixmap.alphaType(). ##
1036# Canvas pixels are not readable; for instance, Canvas is document-based. ##
1037# Pixmap pixels could not be allocated. ##
1038# pixmap.rowBytes() is too small to contain one row of pixels. ##
Cary Clark8032b982017-07-28 11:04:54 -04001039##
1040
Cary Clarkbad5ad72017-08-03 17:14:08 -04001041#Param pixmap storage for pixels copied from Canvas ##
Cary Clarkf05bdda2017-08-24 12:59:48 -04001042#Param srcX offset into readable pixels in x; may be negative ##
1043#Param srcY offset into readable pixels in y; may be negative ##
Cary Clark8032b982017-07-28 11:04:54 -04001044
Cary Clarkbad5ad72017-08-03 17:14:08 -04001045#Return true if pixels were copied ##
Cary Clark8032b982017-07-28 11:04:54 -04001046
1047#Example
Cary Clarkf05bdda2017-08-24 12:59:48 -04001048 #Description
Cary Clarkce101242017-09-01 15:51:02 -04001049 clear() takes Unpremultiplied input with Color_Alpha equal 0x80
Cary Clarkffb3d682018-05-17 12:17:28 -04001050 and RGB equal 0x55, 0xAA, 0xFF. RGB is multiplied by Color_Alpha
Cary Clarkce101242017-09-01 15:51:02 -04001051 to generate Premultiplied value 0x802B5580.
Cary Clarkf05bdda2017-08-24 12:59:48 -04001052 ##
1053 void draw(SkCanvas* canvas) {
1054 canvas->clear(0x8055aaff);
1055 uint32_t pixels[1] = { 0 };
1056 SkPixmap pixmap(SkImageInfo::MakeN32Premul(1, 1), pixels, 4);
1057 canvas->readPixels(pixmap, 0, 0);
1058 SkDebugf("pixel = %08x\n", pixels[0]);
1059 }
Cary Clark8032b982017-07-28 11:04:54 -04001060 #StdOut
1061 pixel = 802b5580
1062 ##
1063##
1064
Cary Clark2ade9972017-11-02 17:49:34 -04001065#SeeAlso peekPixels writePixels drawBitmap drawImage SkBitmap::readPixels SkPixmap::readPixels SkImage::readPixels SkSurface::readPixels
Cary Clark8032b982017-07-28 11:04:54 -04001066
1067##
1068
1069# ------------------------------------------------------------------------------
1070
1071#Method bool readPixels(const SkBitmap& bitmap, int srcX, int srcY)
1072
Cary Clark154beea2017-10-26 07:58:48 -04001073Copies Rect of pixels from Canvas into bitmap. Matrix and Clip are
Cary Clarka560c472017-11-27 10:44:06 -05001074ignored.
Cary Clark6fc50412017-09-21 12:31:06 -04001075
Cary Clarka560c472017-11-27 10:44:06 -05001076Source Rect corners are (srcX, srcY) and (imageInfo().width(), imageInfo().height()).
Cary Clark154beea2017-10-26 07:58:48 -04001077Destination Rect corners are (0, 0) and (bitmap.width(), bitmap.height()).
Cary Clarkf05bdda2017-08-24 12:59:48 -04001078Copies each readable pixel intersecting both rectangles, without scaling,
1079converting to bitmap.colorType() and bitmap.alphaType() if required.
Cary Clark8032b982017-07-28 11:04:54 -04001080
Cary Clarkf05bdda2017-08-24 12:59:48 -04001081Pixels are readable when Device is raster, or backed by a GPU.
1082Pixels are not readable when SkCanvas is returned by SkDocument::beginPage,
1083returned by SkPictureRecorder::beginRecording, or Canvas is the base of a utility
Brian Osman46fe9c72018-03-09 15:44:34 -05001084class like SkDebugCanvas.
Cary Clark8032b982017-07-28 11:04:54 -04001085
Cary Clark6fc50412017-09-21 12:31:06 -04001086Caller must allocate pixel storage in bitmap if needed.
Cary Clarkf05bdda2017-08-24 12:59:48 -04001087
Cary Clark2dc84ad2018-01-26 12:56:22 -05001088Bitmap values are converted only if Color_Type and Alpha_Type
Cary Clarkf05bdda2017-08-24 12:59:48 -04001089do not match. Only pixels within both source and destination rectangles
Cary Clark154beea2017-10-26 07:58:48 -04001090are copied. Bitmap pixels outside Rect intersection are unchanged.
Cary Clarkf05bdda2017-08-24 12:59:48 -04001091
1092Pass negative values for srcX or srcY to offset pixels across or down bitmap.
Cary Clark8032b982017-07-28 11:04:54 -04001093
1094Does not copy, and returns false if:
1095
1096#List
Cary Clarkf05bdda2017-08-24 12:59:48 -04001097# Source and destination rectangles do not intersect. ##
1098# Canvas pixels could not be converted to bitmap.colorType() or bitmap.alphaType(). ##
1099# Canvas pixels are not readable; for instance, Canvas is document-based. ##
Cary Clark8032b982017-07-28 11:04:54 -04001100# bitmap pixels could not be allocated. ##
Cary Clarkf05bdda2017-08-24 12:59:48 -04001101# bitmap.rowBytes() is too small to contain one row of pixels. ##
Cary Clark8032b982017-07-28 11:04:54 -04001102##
1103
Cary Clarkbad5ad72017-08-03 17:14:08 -04001104#Param bitmap storage for pixels copied from Canvas ##
Cary Clarkf05bdda2017-08-24 12:59:48 -04001105#Param srcX offset into readable pixels in x; may be negative ##
1106#Param srcY offset into readable pixels in y; may be negative ##
Cary Clark8032b982017-07-28 11:04:54 -04001107
Cary Clarkbad5ad72017-08-03 17:14:08 -04001108#Return true if pixels were copied ##
Cary Clark8032b982017-07-28 11:04:54 -04001109
1110#Example
Cary Clarkf05bdda2017-08-24 12:59:48 -04001111 #Description
Cary Clarkce101242017-09-01 15:51:02 -04001112 clear() takes Unpremultiplied input with Color_Alpha equal 0x80
Cary Clarkffb3d682018-05-17 12:17:28 -04001113 and RGB equal 0x55, 0xAA, 0xFF. RGB is multiplied by Color_Alpha
Cary Clarkce101242017-09-01 15:51:02 -04001114 to generate Premultiplied value 0x802B5580.
Cary Clarkf05bdda2017-08-24 12:59:48 -04001115 ##
Cary Clark8032b982017-07-28 11:04:54 -04001116void draw(SkCanvas* canvas) {
1117 canvas->clear(0x8055aaff);
1118 SkBitmap bitmap;
1119 bitmap.allocPixels(SkImageInfo::MakeN32Premul(1, 1));
1120 canvas->readPixels(bitmap, 0, 0);
1121 SkDebugf("pixel = %08x\n", bitmap.getAddr32(0, 0)[0]);
1122}
1123 #StdOut
1124 pixel = 802b5580
1125 ##
1126##
1127
Cary Clark2ade9972017-11-02 17:49:34 -04001128#SeeAlso peekPixels writePixels drawBitmap drawImage SkBitmap::readPixels SkPixmap::readPixels SkImage::readPixels SkSurface::readPixels
Cary Clark8032b982017-07-28 11:04:54 -04001129
1130##
1131
1132# ------------------------------------------------------------------------------
1133
1134#Method bool writePixels(const SkImageInfo& info, const void* pixels, size_t rowBytes, int x, int y)
Cary Clark78de7512018-02-07 07:27:09 -05001135#In Pixels
Cary Clarkab2621d2018-01-30 10:08:57 -05001136#Line # copies and converts rectangle of pixels to Canvas ##
Cary Clark154beea2017-10-26 07:58:48 -04001137Copies Rect from pixels to Canvas. Matrix and Clip are ignored.
1138Source Rect corners are (0, 0) and (info.width(), info.height()).
1139Destination Rect corners are (x, y) and
1140(imageInfo().width(), imageInfo().height()).
Cary Clark6fc50412017-09-21 12:31:06 -04001141
1142Copies each readable pixel intersecting both rectangles, without scaling,
Cary Clark154beea2017-10-26 07:58:48 -04001143converting to imageInfo().colorType() and imageInfo().alphaType() if required.
Cary Clark8032b982017-07-28 11:04:54 -04001144
Cary Clarkf05bdda2017-08-24 12:59:48 -04001145Pixels are writable when Device is raster, or backed by a GPU.
1146Pixels are not writable when SkCanvas is returned by SkDocument::beginPage,
1147returned by SkPictureRecorder::beginRecording, or Canvas is the base of a utility
Brian Osman46fe9c72018-03-09 15:44:34 -05001148class like SkDebugCanvas.
Cary Clark8032b982017-07-28 11:04:54 -04001149
Cary Clark2dc84ad2018-01-26 12:56:22 -05001150Pixel values are converted only if Color_Type and Alpha_Type
Cary Clarkf05bdda2017-08-24 12:59:48 -04001151do not match. Only pixels within both source and destination rectangles
Cary Clark154beea2017-10-26 07:58:48 -04001152are copied. Canvas pixels outside Rect intersection are unchanged.
Cary Clark8032b982017-07-28 11:04:54 -04001153
Cary Clarkf05bdda2017-08-24 12:59:48 -04001154Pass negative values for x or y to offset pixels to the left or
1155above Canvas pixels.
Cary Clark8032b982017-07-28 11:04:54 -04001156
1157Does not copy, and returns false if:
1158
1159#List
Cary Clarkf05bdda2017-08-24 12:59:48 -04001160# Source and destination rectangles do not intersect. ##
Cary Clarkac47b882018-01-11 10:35:44 -05001161# pixels could not be converted to Canvas imageInfo().colorType() or
1162 imageInfo().alphaType(). ##
Cary Clark8032b982017-07-28 11:04:54 -04001163# Canvas pixels are not writable; for instance, Canvas is document-based. ##
1164# rowBytes is too small to contain one row of pixels. ##
1165##
1166
Cary Clark2dc84ad2018-01-26 12:56:22 -05001167#Param info width, height, Color_Type, and Alpha_Type of pixels ##
Cary Clarkf05bdda2017-08-24 12:59:48 -04001168#Param pixels pixels to copy, of size info.height() times rowBytes, or larger ##
Cary Clarkd0530ba2017-09-14 11:25:39 -04001169#Param rowBytes size of one row of pixels; info.width() times pixel size, or larger ##
Cary Clarkf05bdda2017-08-24 12:59:48 -04001170#Param x offset into Canvas writable pixels in x; may be negative ##
1171#Param y offset into Canvas writable pixels in y; may be negative ##
Cary Clark8032b982017-07-28 11:04:54 -04001172
Cary Clarkbad5ad72017-08-03 17:14:08 -04001173#Return true if pixels were written to Canvas ##
Cary Clark8032b982017-07-28 11:04:54 -04001174
1175#Example
1176 SkImageInfo imageInfo = SkImageInfo::MakeN32(256, 1, kPremul_SkAlphaType);
1177 for (int y = 0; y < 256; ++y) {
1178 uint32_t pixels[256];
1179 for (int x = 0; x < 256; ++x) {
1180 pixels[x] = SkColorSetARGB(x, x + y, x, x - y);
1181 }
1182 canvas->writePixels(imageInfo, &pixels, sizeof(pixels), 0, y);
1183 }
1184##
1185
Cary Clark2ade9972017-11-02 17:49:34 -04001186#SeeAlso readPixels drawBitmap drawImage SkBitmap::writePixels
Cary Clark8032b982017-07-28 11:04:54 -04001187
1188##
1189
1190# ------------------------------------------------------------------------------
1191
1192#Method bool writePixels(const SkBitmap& bitmap, int x, int y)
1193
Cary Clark154beea2017-10-26 07:58:48 -04001194Copies Rect from pixels to Canvas. Matrix and Clip are ignored.
1195Source Rect corners are (0, 0) and (bitmap.width(), bitmap.height()).
Cary Clark6fc50412017-09-21 12:31:06 -04001196
Cary Clark154beea2017-10-26 07:58:48 -04001197Destination Rect corners are (x, y) and
1198(imageInfo().width(), imageInfo().height()).
Cary Clark6fc50412017-09-21 12:31:06 -04001199
1200Copies each readable pixel intersecting both rectangles, without scaling,
Cary Clark154beea2017-10-26 07:58:48 -04001201converting to imageInfo().colorType() and imageInfo().alphaType() if required.
Cary Clark8032b982017-07-28 11:04:54 -04001202
Cary Clarkf05bdda2017-08-24 12:59:48 -04001203Pixels are writable when Device is raster, or backed by a GPU.
1204Pixels are not writable when SkCanvas is returned by SkDocument::beginPage,
1205returned by SkPictureRecorder::beginRecording, or Canvas is the base of a utility
Brian Osman46fe9c72018-03-09 15:44:34 -05001206class like SkDebugCanvas.
Cary Clark8032b982017-07-28 11:04:54 -04001207
Cary Clark2dc84ad2018-01-26 12:56:22 -05001208Pixel values are converted only if Color_Type and Alpha_Type
Cary Clarkf05bdda2017-08-24 12:59:48 -04001209do not match. Only pixels within both source and destination rectangles
Cary Clark154beea2017-10-26 07:58:48 -04001210are copied. Canvas pixels outside Rect intersection are unchanged.
Cary Clark8032b982017-07-28 11:04:54 -04001211
Cary Clarkf05bdda2017-08-24 12:59:48 -04001212Pass negative values for x or y to offset pixels to the left or
1213above Canvas pixels.
Cary Clark8032b982017-07-28 11:04:54 -04001214
1215Does not copy, and returns false if:
1216
1217#List
Cary Clarkf05bdda2017-08-24 12:59:48 -04001218# Source and destination rectangles do not intersect. ##
Cary Clark8032b982017-07-28 11:04:54 -04001219# bitmap does not have allocated pixels. ##
Cary Clarkac47b882018-01-11 10:35:44 -05001220# bitmap pixels could not be converted to Canvas imageInfo().colorType() or
1221 imageInfo().alphaType(). ##
Cary Clarkce101242017-09-01 15:51:02 -04001222# Canvas pixels are not writable; for instance, Canvas is document based. ##
Cary Clark8032b982017-07-28 11:04:54 -04001223# bitmap pixels are inaccessible; for instance, bitmap wraps a texture. ##
1224##
1225
Cary Clarkbad5ad72017-08-03 17:14:08 -04001226#Param bitmap contains pixels copied to Canvas ##
Cary Clarkf05bdda2017-08-24 12:59:48 -04001227#Param x offset into Canvas writable pixels in x; may be negative ##
1228#Param y offset into Canvas writable pixels in y; may be negative ##
Cary Clark8032b982017-07-28 11:04:54 -04001229
Cary Clarkbad5ad72017-08-03 17:14:08 -04001230#Return true if pixels were written to Canvas ##
Cary Clark8032b982017-07-28 11:04:54 -04001231
1232#Example
1233void draw(SkCanvas* canvas) {
1234 SkImageInfo imageInfo = SkImageInfo::MakeN32Premul(2, 2);
1235 SkBitmap bitmap;
1236 bitmap.setInfo(imageInfo);
1237 uint32_t pixels[4];
1238 bitmap.setPixels(pixels);
1239 for (int y = 0; y < 256; y += 2) {
1240 for (int x = 0; x < 256; x += 2) {
1241 pixels[0] = SkColorSetRGB(x, y, x | y);
1242 pixels[1] = SkColorSetRGB(x ^ y, y, x);
1243 pixels[2] = SkColorSetRGB(x, x & y, y);
1244 pixels[3] = SkColorSetRGB(~x, ~y, x);
1245 canvas->writePixels(bitmap, x, y);
1246 }
1247 }
1248}
1249##
1250
Cary Clark2ade9972017-11-02 17:49:34 -04001251#SeeAlso readPixels drawBitmap drawImage SkBitmap::writePixels
Cary Clark8032b982017-07-28 11:04:54 -04001252
1253##
1254
1255# ------------------------------------------------------------------------------
Cary Clark08895c42018-02-01 09:37:32 -05001256#Subtopic State_Stack
1257#Line # stack of state for hierarchical drawing ##
Cary Clark8032b982017-07-28 11:04:54 -04001258
1259Canvas maintains a stack of state that allows hierarchical drawing, commonly used
Cary Clarkbad5ad72017-08-03 17:14:08 -04001260to implement windows and views. The initial state has an identity matrix and and
1261an infinite clip. Even with a wide-open clip, drawing is constrained by the
1262bounds of the Canvas Surface or Device.
Cary Clark8032b982017-07-28 11:04:54 -04001263
1264Canvas savable state consists of Clip, Matrix, and Draw_Filter.
1265Clip describes the area that may be drawn to.
1266Matrix transforms the geometry.
1267Draw_Filter (deprecated on most platforms) modifies the paint before drawing.
1268
1269save(), saveLayer, saveLayerPreserveLCDTextRequests, and saveLayerAlpha
1270save state and return the depth of the stack.
1271
Cary Clarkbad5ad72017-08-03 17:14:08 -04001272restore(), restoreToCount, and ~SkCanvas() revert state to its value when saved.
Cary Clark8032b982017-07-28 11:04:54 -04001273
1274Each state on the stack intersects Clip with the previous Clip,
1275and concatenates Matrix with the previous Matrix.
1276The intersected Clip makes the drawing area the same or smaller;
1277the concatenated Matrix may move the origin and potentially scale or rotate
1278the coordinate space.
1279
1280Canvas does not require balancing the state stack but it is a good idea
1281to do so. Calling save() without restore() will eventually cause Skia to fail;
1282mismatched save() and restore() create hard to find bugs.
1283
1284It is not possible to use state to draw outside of the clip defined by the
1285previous state.
1286
1287#Example
1288#Description
1289Draw to ever smaller clips; then restore drawing to full canvas.
1290Note that the second clipRect is not permitted to enlarge Clip.
1291##
1292#Height 160
Cary Clarkbad5ad72017-08-03 17:14:08 -04001293void draw(SkCanvas* canvas) {
1294 SkPaint paint;
Herb Derbyefe39bc2018-05-01 17:06:20 -04001295 canvas->save(); // records stack depth to restore
Cary Clarkbad5ad72017-08-03 17:14:08 -04001296 canvas->clipRect(SkRect::MakeWH(100, 100)); // constrains drawing to clip
1297 canvas->clear(SK_ColorRED); // draws to limit of clip
Herb Derbyefe39bc2018-05-01 17:06:20 -04001298 canvas->save(); // records stack depth to restore
Cary Clarkbad5ad72017-08-03 17:14:08 -04001299 canvas->clipRect(SkRect::MakeWH(50, 150)); // Rect below 100 is ignored
1300 canvas->clear(SK_ColorBLUE); // draws to smaller clip
1301 canvas->restore(); // enlarges clip
1302 canvas->drawLine(20, 20, 150, 150, paint); // line below 100 is not drawn
1303 canvas->restore(); // enlarges clip
1304 canvas->drawLine(150, 20, 50, 120, paint); // line below 100 is drawn
Cary Clark8032b982017-07-28 11:04:54 -04001305}
Herb Derbyefe39bc2018-05-01 17:06:20 -04001306##
Cary Clark8032b982017-07-28 11:04:54 -04001307
1308Each Clip uses the current Matrix for its coordinates.
1309
1310#Example
1311#Description
1312While clipRect is given the same rectangle twice, Matrix makes the second
1313clipRect draw at half the size of the first.
1314##
1315#Height 128
Cary Clarkbad5ad72017-08-03 17:14:08 -04001316void draw(SkCanvas* canvas) {
1317 canvas->clipRect(SkRect::MakeWH(100, 100));
1318 canvas->clear(SK_ColorRED);
1319 canvas->scale(.5, .5);
1320 canvas->clipRect(SkRect::MakeWH(100, 100));
1321 canvas->clear(SK_ColorBLUE);
Cary Clark8032b982017-07-28 11:04:54 -04001322}
1323##
1324
1325#SeeAlso save() saveLayer saveLayerPreserveLCDTextRequests saveLayerAlpha restore() restoreToCount
1326
1327#Method int save()
1328
Cary Clarkab2621d2018-01-30 10:08:57 -05001329#In State_Stack
1330#Line # saves Clip and Matrix on stack ##
Cary Clark8032b982017-07-28 11:04:54 -04001331Saves Matrix, Clip, and Draw_Filter (Draw_Filter deprecated on most platforms).
1332Calling restore() discards changes to Matrix, Clip, and Draw_Filter,
1333restoring the Matrix, Clip, and Draw_Filter to their state when save() was called.
1334
Cary Clarkbad5ad72017-08-03 17:14:08 -04001335Matrix may be changed by translate(), scale(), rotate(), skew(), concat(), setMatrix,
1336and resetMatrix. Clip may be changed by clipRect, clipRRect, clipPath, clipRegion.
Cary Clark8032b982017-07-28 11:04:54 -04001337
Cary Clarkbad5ad72017-08-03 17:14:08 -04001338Saved Canvas state is put on a stack; multiple calls to save() should be balance
1339by an equal number of calls to restore().
Cary Clark8032b982017-07-28 11:04:54 -04001340
1341Call restoreToCount with result to restore this and subsequent saves.
1342
Cary Clarkbad5ad72017-08-03 17:14:08 -04001343#Return depth of saved stack ##
Cary Clark8032b982017-07-28 11:04:54 -04001344
1345#Example
Herb Derbyefe39bc2018-05-01 17:06:20 -04001346#Description
Cary Clark8032b982017-07-28 11:04:54 -04001347The black square is translated 50 pixels down and to the right.
1348Restoring Canvas state removes translate() from Canvas stack;
1349the red square is not translated, and is drawn at the origin.
1350##
1351#Height 100
1352void draw(SkCanvas* canvas) {
1353 SkPaint paint;
1354 SkRect rect = { 0, 0, 25, 25 };
1355 canvas->drawRect(rect, paint);
1356 canvas->save();
1357 canvas->translate(50, 50);
1358 canvas->drawRect(rect, paint);
1359 canvas->restore();
1360 paint.setColor(SK_ColorRED);
1361 canvas->drawRect(rect, paint);
1362}
1363##
1364
Cary Clark2ade9972017-11-02 17:49:34 -04001365#SeeAlso saveLayer saveLayerPreserveLCDTextRequests saveLayerAlpha restore() restoreToCount
Cary Clark8032b982017-07-28 11:04:54 -04001366
1367##
1368
1369# ------------------------------------------------------------------------------
Cary Clark8032b982017-07-28 11:04:54 -04001370
1371#Method void restore()
1372
Cary Clarkab2621d2018-01-30 10:08:57 -05001373#In State_Stack
1374#Line # restores changes to Clip and Matrix, pops save stack ##
Cary Clark8032b982017-07-28 11:04:54 -04001375Removes changes to Matrix, Clip, and Draw_Filter since Canvas state was
Herb Derbyefe39bc2018-05-01 17:06:20 -04001376last saved. The state is removed from the stack.
Cary Clark8032b982017-07-28 11:04:54 -04001377
Herb Derbyefe39bc2018-05-01 17:06:20 -04001378Does nothing if the stack is empty.
Cary Clark8032b982017-07-28 11:04:54 -04001379
1380#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04001381void draw(SkCanvas* canvas) {
1382 SkCanvas simple;
1383 SkDebugf("depth = %d\n", simple.getSaveCount());
1384 simple.restore();
1385 SkDebugf("depth = %d\n", simple.getSaveCount());
Cary Clark8032b982017-07-28 11:04:54 -04001386}
1387##
1388
Cary Clark2ade9972017-11-02 17:49:34 -04001389#SeeAlso save() saveLayer saveLayerPreserveLCDTextRequests saveLayerAlpha restoreToCount
1390
Cary Clark8032b982017-07-28 11:04:54 -04001391##
1392
1393# ------------------------------------------------------------------------------
1394
1395#Method int getSaveCount() const
1396
Cary Clarkab2621d2018-01-30 10:08:57 -05001397#In State_Stack
1398#Line # returns depth of stack containing Clip and Matrix ##
Cary Clark8032b982017-07-28 11:04:54 -04001399Returns the number of saved states, each containing: Matrix, Clip, and Draw_Filter.
Herb Derbyefe39bc2018-05-01 17:06:20 -04001400Equals the number of save() calls less the number of restore() calls plus one.
Cary Clark8032b982017-07-28 11:04:54 -04001401The save count of a new canvas is one.
1402
Cary Clarkbad5ad72017-08-03 17:14:08 -04001403#Return depth of save state stack ##
Cary Clark8032b982017-07-28 11:04:54 -04001404
1405#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04001406void draw(SkCanvas* canvas) {
1407 SkCanvas simple;
1408 SkDebugf("depth = %d\n", simple.getSaveCount());
1409 simple.save();
1410 SkDebugf("depth = %d\n", simple.getSaveCount());
1411 simple.restore();
1412 SkDebugf("depth = %d\n", simple.getSaveCount());
Cary Clark8032b982017-07-28 11:04:54 -04001413}
1414#StdOut
Cary Clarkbad5ad72017-08-03 17:14:08 -04001415depth = 1
1416depth = 2
Cary Clark8032b982017-07-28 11:04:54 -04001417depth = 1
1418##
1419##
1420
Cary Clark2ade9972017-11-02 17:49:34 -04001421#SeeAlso save() restore() restoreToCount
1422
Cary Clark8032b982017-07-28 11:04:54 -04001423##
1424
1425# ------------------------------------------------------------------------------
1426
1427#Method void restoreToCount(int saveCount)
1428
Cary Clarkab2621d2018-01-30 10:08:57 -05001429#In State_Stack
1430#Line # restores changes to Clip and Matrix to given depth ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04001431Restores state to Matrix, Clip, and Draw_Filter values when save(), saveLayer,
1432saveLayerPreserveLCDTextRequests, or saveLayerAlpha returned saveCount.
Cary Clark8032b982017-07-28 11:04:54 -04001433
Herb Derbyefe39bc2018-05-01 17:06:20 -04001434Does nothing if saveCount is greater than state stack count.
Cary Clark8032b982017-07-28 11:04:54 -04001435Restores state to initial values if saveCount is less than or equal to one.
1436
Cary Clarkbad5ad72017-08-03 17:14:08 -04001437#Param saveCount depth of state stack to restore ##
Cary Clark8032b982017-07-28 11:04:54 -04001438
1439#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04001440void draw(SkCanvas* canvas) {
1441 SkDebugf("depth = %d\n", canvas->getSaveCount());
1442 canvas->save();
1443 canvas->save();
1444 SkDebugf("depth = %d\n", canvas->getSaveCount());
1445 canvas->restoreToCount(0);
1446 SkDebugf("depth = %d\n", canvas->getSaveCount());
Cary Clark8032b982017-07-28 11:04:54 -04001447}
1448#StdOut
Cary Clarkbad5ad72017-08-03 17:14:08 -04001449depth = 1
1450depth = 3
Cary Clark8032b982017-07-28 11:04:54 -04001451depth = 1
1452##
1453##
1454
Herb Derbyefe39bc2018-05-01 17:06:20 -04001455#SeeAlso restore() getSaveCount save()
Cary Clark2ade9972017-11-02 17:49:34 -04001456
Cary Clark8032b982017-07-28 11:04:54 -04001457##
1458
Cary Clark08895c42018-02-01 09:37:32 -05001459#Subtopic State_Stack ##
Cary Clark8032b982017-07-28 11:04:54 -04001460
1461# ------------------------------------------------------------------------------
Cary Clarkce101242017-09-01 15:51:02 -04001462
Cary Clark08895c42018-02-01 09:37:32 -05001463#Subtopic Layer
Cary Clarkd0530ba2017-09-14 11:25:39 -04001464#Substitute layer
Cary Clarkce101242017-09-01 15:51:02 -04001465#Alias Layers
Cary Clark137b8742018-05-30 09:21:49 -04001466#Substitute layers
1467##
Cary Clark08895c42018-02-01 09:37:32 -05001468#Line # temporary Bitmap to draw into ##
Cary Clarkce101242017-09-01 15:51:02 -04001469
1470Layer allocates a temporary Bitmap to draw into. When the drawing is
Herb Derbyefe39bc2018-05-01 17:06:20 -04001471complete, the Bitmap is drawn into the Canvas.
Cary Clarkce101242017-09-01 15:51:02 -04001472
1473Layer is saved in a stack along with other saved state. When state with a Layer
1474is restored, the Bitmap is drawn into the previous Layer.
1475
1476Layer may be initialized with the contents of the previous Layer. When Layer is
1477restored, its Bitmap can be modified by Paint passed to Layer to apply
1478Color_Alpha, Color_Filter, Image_Filter, and Blend_Mode.
1479
1480#Method int saveLayer(const SkRect* bounds, const SkPaint* paint)
1481
Cary Clarkab2621d2018-01-30 10:08:57 -05001482#In Layer
1483#Line # saves Clip and Matrix on stack; creates Layer ##
Cary Clarkce101242017-09-01 15:51:02 -04001484Saves Matrix, Clip, and Draw_Filter (Draw_Filter deprecated on most platforms),
1485and allocates a Bitmap for subsequent drawing.
1486Calling restore() discards changes to Matrix, Clip, and Draw_Filter,
1487and draws the Bitmap.
1488
1489Matrix may be changed by translate(), scale(), rotate(), skew(), concat(),
Herb Derbyefe39bc2018-05-01 17:06:20 -04001490setMatrix, and resetMatrix. Clip may be changed by clipRect, clipRRect,
Cary Clarkce101242017-09-01 15:51:02 -04001491clipPath, clipRegion.
1492
1493Rect bounds suggests but does not define the Bitmap size. To clip drawing to
1494a specific rectangle, use clipRect.
1495
1496Optional Paint paint applies Color_Alpha, Color_Filter, Image_Filter, and
1497Blend_Mode when restore() is called.
1498
1499Call restoreToCount with returned value to restore this and subsequent saves.
1500
1501#Param bounds hint to limit the size of the Layer; may be nullptr ##
1502#Param paint graphics state for Layer; may be nullptr ##
1503
1504#Return depth of saved stack ##
1505
1506#Example
1507#Description
1508Rectangles are blurred by Image_Filter when restore() draws Layer to main
1509Canvas.
1510##
1511#Height 128
1512void draw(SkCanvas* canvas) {
1513 SkPaint paint, blur;
Cary Clarka560c472017-11-27 10:44:06 -05001514 blur.setImageFilter(SkBlurImageFilter::Make(3, 3, nullptr));
Cary Clarkce101242017-09-01 15:51:02 -04001515 canvas->saveLayer(nullptr, &blur);
1516 SkRect rect = { 25, 25, 50, 50};
1517 canvas->drawRect(rect, paint);
1518 canvas->translate(50, 50);
1519 paint.setColor(SK_ColorRED);
1520 canvas->drawRect(rect, paint);
1521 canvas->restore();
1522}
1523##
1524
Cary Clark2ade9972017-11-02 17:49:34 -04001525#SeeAlso save() restore() saveLayer saveLayerPreserveLCDTextRequests saveLayerAlpha SaveLayerRec
Cary Clarkce101242017-09-01 15:51:02 -04001526
1527##
1528
Herb Derbyefe39bc2018-05-01 17:06:20 -04001529#Method int saveLayer(const SkRect& bounds, const SkPaint* paint)
Cary Clarkce101242017-09-01 15:51:02 -04001530
Cary Clarkab2621d2018-01-30 10:08:57 -05001531#In Layer
Cary Clarkce101242017-09-01 15:51:02 -04001532Saves Matrix, Clip, and Draw_Filter (Draw_Filter deprecated on most platforms),
1533and allocates a Bitmap for subsequent drawing.
1534Calling restore() discards changes to Matrix, Clip, and Draw_Filter,
1535and draws the Bitmap.
1536
1537Matrix may be changed by translate(), scale(), rotate(), skew(), concat(),
1538setMatrix, and resetMatrix. Clip may be changed by clipRect, clipRRect,
1539clipPath, clipRegion.
1540
1541Rect bounds suggests but does not define the Layer size. To clip drawing to
1542a specific rectangle, use clipRect.
1543
1544Optional Paint paint applies Color_Alpha, Color_Filter, Image_Filter, and
1545Blend_Mode when restore() is called.
1546
1547Call restoreToCount with returned value to restore this and subsequent saves.
1548
1549#Param bounds hint to limit the size of Layer; may be nullptr ##
1550#Param paint graphics state for Layer; may be nullptr ##
1551
1552#Return depth of saved stack ##
1553
1554#Example
1555#Description
1556Rectangles are blurred by Image_Filter when restore() draws Layer to main Canvas.
Herb Derbyefe39bc2018-05-01 17:06:20 -04001557The red rectangle is clipped; it does not fully fit on Layer.
Cary Clarkce101242017-09-01 15:51:02 -04001558Image_Filter blurs past edge of Layer so red rectangle is blurred on all sides.
1559##
1560#Height 128
1561void draw(SkCanvas* canvas) {
1562 SkPaint paint, blur;
Cary Clarka560c472017-11-27 10:44:06 -05001563 blur.setImageFilter(SkBlurImageFilter::Make(3, 3, nullptr));
Cary Clarkce101242017-09-01 15:51:02 -04001564 canvas->saveLayer(SkRect::MakeWH(90, 90), &blur);
1565 SkRect rect = { 25, 25, 50, 50};
1566 canvas->drawRect(rect, paint);
1567 canvas->translate(50, 50);
1568 paint.setColor(SK_ColorRED);
1569 canvas->drawRect(rect, paint);
1570 canvas->restore();
1571}
1572##
1573
Cary Clark2ade9972017-11-02 17:49:34 -04001574#SeeAlso save() restore() saveLayerPreserveLCDTextRequests saveLayerAlpha SaveLayerRec
Cary Clarkce101242017-09-01 15:51:02 -04001575
1576##
1577
1578#Method int saveLayerPreserveLCDTextRequests(const SkRect* bounds, const SkPaint* paint)
1579
Cary Clarkab2621d2018-01-30 10:08:57 -05001580#In Layer
1581#Line # saves Clip and Matrix on stack; creates Layer for LCD text ##
Cary Clarkce101242017-09-01 15:51:02 -04001582Saves Matrix, Clip, and Draw_Filter (Draw_Filter deprecated on most platforms),
1583and allocates a Bitmap for subsequent drawing.
1584LCD_Text is preserved when the Layer is drawn to the prior Layer.
1585
1586Calling restore() discards changes to Matrix, Clip, and Draw_Filter,
1587and draws Layer.
1588
1589Matrix may be changed by translate(), scale(), rotate(), skew(), concat(),
1590setMatrix, and resetMatrix. Clip may be changed by clipRect, clipRRect,
1591clipPath, clipRegion.
Herb Derbyefe39bc2018-05-01 17:06:20 -04001592
Cary Clarkce101242017-09-01 15:51:02 -04001593Rect bounds suggests but does not define the Layer size. To clip drawing to
1594a specific rectangle, use clipRect.
1595
1596Optional Paint paint applies Color_Alpha, Color_Filter, Image_Filter, and
1597Blend_Mode when restore() is called.
1598
1599Call restoreToCount with returned value to restore this and subsequent saves.
1600
1601Draw text on an opaque background so that LCD_Text blends correctly with the
1602prior Layer. LCD_Text drawn on a background with transparency may result in
Cary Clark6fc50412017-09-21 12:31:06 -04001603incorrect blending.
Cary Clarkce101242017-09-01 15:51:02 -04001604
1605#Param bounds hint to limit the size of Layer; may be nullptr ##
1606#Param paint graphics state for Layer; may be nullptr ##
1607
1608#Return depth of saved stack ##
1609
1610#Example
1611 SkPaint paint;
1612 paint.setAntiAlias(true);
1613 paint.setLCDRenderText(true);
1614 paint.setTextSize(20);
1615 for (auto preserve : { false, true } ) {
1616 preserve ? canvas->saveLayerPreserveLCDTextRequests(nullptr, nullptr)
1617 : canvas->saveLayer(nullptr, nullptr);
1618 SkPaint p;
1619 p.setColor(SK_ColorWHITE);
1620 // Comment out the next line to draw on a non-opaque background.
1621 canvas->drawRect(SkRect::MakeLTRB(25, 40, 200, 70), p);
1622 canvas->drawString("Hamburgefons", 30, 60, paint);
1623
1624 p.setColor(0xFFCCCCCC);
1625 canvas->drawRect(SkRect::MakeLTRB(25, 70, 200, 100), p);
1626 canvas->drawString("Hamburgefons", 30, 90, paint);
1627
1628 canvas->restore();
1629 canvas->translate(0, 80);
1630 }
1631 ##
1632
Cary Clark2ade9972017-11-02 17:49:34 -04001633#SeeAlso save() restore() saveLayer saveLayerAlpha SaveLayerRec
Cary Clarkce101242017-09-01 15:51:02 -04001634
1635##
1636
1637#Method int saveLayerAlpha(const SkRect* bounds, U8CPU alpha)
1638
Cary Clarkab2621d2018-01-30 10:08:57 -05001639#In Layer
1640#Line # saves Clip and Matrix on stack; creates Layer; sets opacity ##
Cary Clarkce101242017-09-01 15:51:02 -04001641Saves Matrix, Clip, and Draw_Filter (Draw_Filter deprecated on most platforms),
1642and allocates Bitmap for subsequent drawing.
1643
1644Calling restore() discards changes to Matrix, Clip, and Draw_Filter,
1645and blends Layer with alpha opacity onto prior Layer.
1646
1647Matrix may be changed by translate(), scale(), rotate(), skew(), concat(),
1648setMatrix, and resetMatrix. Clip may be changed by clipRect, clipRRect,
1649clipPath, clipRegion.
1650
1651Rect bounds suggests but does not define Layer size. To clip drawing to
1652a specific rectangle, use clipRect.
1653
1654alpha of zero is fully transparent, 255 is fully opaque.
1655
1656Call restoreToCount with returned value to restore this and subsequent saves.
1657
1658#Param bounds hint to limit the size of Layer; may be nullptr ##
1659#Param alpha opacity of Layer ##
1660
1661#Return depth of saved stack ##
1662
1663#Example
1664 SkPaint paint;
1665 paint.setColor(SK_ColorRED);
1666 canvas->drawCircle(50, 50, 50, paint);
1667 canvas->saveLayerAlpha(nullptr, 128);
1668 paint.setColor(SK_ColorBLUE);
1669 canvas->drawCircle(100, 50, 50, paint);
1670 paint.setColor(SK_ColorGREEN);
1671 paint.setAlpha(128);
1672 canvas->drawCircle(75, 90, 50, paint);
1673 canvas->restore();
1674##
1675
Cary Clark2ade9972017-11-02 17:49:34 -04001676#SeeAlso save() restore() saveLayer saveLayerPreserveLCDTextRequests SaveLayerRec
Cary Clarkce101242017-09-01 15:51:02 -04001677
1678##
1679
Cary Clarkd98f78c2018-04-26 08:32:37 -04001680#Enum SaveLayerFlagsSet
Cary Clark08895c42018-02-01 09:37:32 -05001681#Line # sets SaveLayerRec options ##
Cary Clarkce101242017-09-01 15:51:02 -04001682#Code
Cary Clarkd98f78c2018-04-26 08:32:37 -04001683 enum SaveLayerFlagsSet {
Cary Clarkce101242017-09-01 15:51:02 -04001684 kPreserveLCDText_SaveLayerFlag = 1 << 1,
1685 kInitWithPrevious_SaveLayerFlag = 1 << 2,
Mike Reed910ca0f2018-04-25 13:04:05 -04001686 kMaskAgainstCoverage_EXPERIMENTAL_DONT_USE_SaveLayerFlag = 1 << 3,
Cary Clarkce101242017-09-01 15:51:02 -04001687 kDontClipToLayer_Legacy_SaveLayerFlag = kDontClipToLayer_PrivateSaveLayerFlag,
1688 };
Cary Clarkd98f78c2018-04-26 08:32:37 -04001689
1690 typedef uint32_t SaveLayerFlags;
Cary Clarkce101242017-09-01 15:51:02 -04001691##
1692
Cary Clark682c58d2018-05-16 07:07:07 -04001693
1694#Typedef uint32_t SaveLayerFlags
1695#Line # options for SaveLayerRec ##
Cary Clark137b8742018-05-30 09:21:49 -04001696##
Cary Clark682c58d2018-05-16 07:07:07 -04001697
Cary Clarkce101242017-09-01 15:51:02 -04001698SaveLayerFlags provides options that may be used in any combination in SaveLayerRec,
Cary Clark682c58d2018-05-16 07:07:07 -04001699defining how Layer allocated by saveLayer operates. It may be set to zero,
1700kPreserveLCDText_SaveLayerFlag, kInitWithPrevious_SaveLayerFlag, or both flags.
1701
Cary Clarkce101242017-09-01 15:51:02 -04001702#Const kPreserveLCDText_SaveLayerFlag 2
Cary Clark682c58d2018-05-16 07:07:07 -04001703#Line # creates Layer for LCD text ##
Cary Clarkce101242017-09-01 15:51:02 -04001704 Creates Layer for LCD text. Flag is ignored if Layer Paint contains
1705 Image_Filter or Color_Filter.
1706##
1707
1708#Const kInitWithPrevious_SaveLayerFlag 4
Cary Clark682c58d2018-05-16 07:07:07 -04001709#Line # initializes with previous contents ##
Cary Clarkce101242017-09-01 15:51:02 -04001710 Initializes Layer with the contents of the previous Layer.
1711##
1712
Mike Reed910ca0f2018-04-25 13:04:05 -04001713#Const kMaskAgainstCoverage_EXPERIMENTAL_DONT_USE_SaveLayerFlag 8
Cary Clark682c58d2018-05-16 07:07:07 -04001714#Experimental do not use
Mike Reed910ca0f2018-04-25 13:04:05 -04001715##
1716
Cary Clarkce101242017-09-01 15:51:02 -04001717#Const kDontClipToLayer_Legacy_SaveLayerFlag 0x80000000
Cary Clark4855f782018-02-06 09:41:53 -05001718#Deprecated soon
Cary Clarkce101242017-09-01 15:51:02 -04001719##
1720
1721#Example
1722#Height 160
1723#Description
1724Canvas Layer captures red and blue circles scaled up by four.
Herb Derbyefe39bc2018-05-01 17:06:20 -04001725scalePaint blends Layer back with transparency.
Cary Clarkce101242017-09-01 15:51:02 -04001726##
1727void draw(SkCanvas* canvas) {
1728 SkPaint redPaint, bluePaint, scalePaint;
1729 redPaint.setColor(SK_ColorRED);
1730 canvas->drawCircle(21, 21, 8, redPaint);
1731 bluePaint.setColor(SK_ColorBLUE);
1732 canvas->drawCircle(31, 21, 8, bluePaint);
1733 SkMatrix matrix;
1734 matrix.setScale(4, 4);
1735 scalePaint.setAlpha(0x40);
1736 scalePaint.setImageFilter(
1737 SkImageFilter::MakeMatrixFilter(matrix, kNone_SkFilterQuality, nullptr));
1738 SkCanvas::SaveLayerRec saveLayerRec(nullptr, &scalePaint,
Herb Derbyefe39bc2018-05-01 17:06:20 -04001739 SkCanvas::kInitWithPrevious_SaveLayerFlag);
Cary Clarkce101242017-09-01 15:51:02 -04001740 canvas->saveLayer(saveLayerRec);
1741 canvas->restore();
1742}
1743##
1744
Cary Clark2ade9972017-11-02 17:49:34 -04001745#SeeAlso save() restore() saveLayer saveLayerPreserveLCDTextRequests saveLayerAlpha SaveLayerRec
Cary Clarkce101242017-09-01 15:51:02 -04001746
1747#Enum ##
1748
Cary Clark682c58d2018-05-16 07:07:07 -04001749#Subtopic SaveLayerRec
1750#Line # contains the state used to create the Layer ##
Cary Clarka560c472017-11-27 10:44:06 -05001751
Cary Clarkce101242017-09-01 15:51:02 -04001752#Struct SaveLayerRec
Cary Clark08895c42018-02-01 09:37:32 -05001753#Line # contains the state used to create the Layer ##
Cary Clark682c58d2018-05-16 07:07:07 -04001754
Cary Clarkce101242017-09-01 15:51:02 -04001755#Code
1756 struct SaveLayerRec {
1757 SaveLayerRec*(...
1758
1759 const SkRect* fBounds;
1760 const SkPaint* fPaint;
1761 const SkImageFilter* fBackdrop;
1762 SaveLayerFlags fSaveLayerFlags;
1763 };
1764##
1765
Cary Clark137b8742018-05-30 09:21:49 -04001766SaveLayerRec contains the state used to create the Layer.
1767
Cary Clark682c58d2018-05-16 07:07:07 -04001768#Subtopic Overview
1769#Populate
1770##
1771
1772#Subtopic Member
1773#Populate
1774##
Cary Clarkce101242017-09-01 15:51:02 -04001775
1776#Member const SkRect* fBounds
Cary Clark682c58d2018-05-16 07:07:07 -04001777#Line # hints at Layer size limit ##
Cary Clarkce101242017-09-01 15:51:02 -04001778 fBounds is used as a hint to limit the size of Layer; may be nullptr.
1779 fBounds suggests but does not define Layer size. To clip drawing to
1780 a specific rectangle, use clipRect.
1781##
1782
1783#Member const SkPaint* fPaint
Cary Clark682c58d2018-05-16 07:07:07 -04001784#Line # modifies overlay ##
Cary Clarkce101242017-09-01 15:51:02 -04001785 fPaint modifies how Layer overlays the prior Layer; may be nullptr.
1786 Color_Alpha, Blend_Mode, Color_Filter, Draw_Looper, Image_Filter, and
1787 Mask_Filter affect Layer draw.
1788##
1789
1790#Member const SkImageFilter* fBackdrop
Cary Clark682c58d2018-05-16 07:07:07 -04001791#Line # applies Image_Filter to prior Layer ##
Cary Clarkce101242017-09-01 15:51:02 -04001792 fBackdrop applies Image_Filter to the prior Layer when copying to the Layer;
1793 may be nullptr. Use kInitWithPrevious_SaveLayerFlag to copy the
1794 prior Layer without an Image_Filter.
1795##
1796
1797#Member const SkImage* fClipMask
Cary Clark682c58d2018-05-16 07:07:07 -04001798#Line # clips Layer with Mask_Alpha ##
Cary Clarkce101242017-09-01 15:51:02 -04001799 restore() clips Layer by the Color_Alpha channel of fClipMask when
1800 Layer is copied to Device. fClipMask may be nullptr. .
1801##
1802
1803#Member const SkMatrix* fClipMatrix
Cary Clark682c58d2018-05-16 07:07:07 -04001804#Line # transforms Mask_Alpha used to clip ##
Herb Derbyefe39bc2018-05-01 17:06:20 -04001805 fClipMatrix transforms fClipMask before it clips Layer. If
Cary Clarkce101242017-09-01 15:51:02 -04001806 fClipMask describes a translucent gradient, it may be scaled and rotated
1807 without introducing artifacts. fClipMatrix may be nullptr.
1808##
1809
1810#Member SaveLayerFlags fSaveLayerFlags
Cary Clark682c58d2018-05-16 07:07:07 -04001811#Line # preserves LCD Text, creates with prior Layer contents ##
Cary Clarkce101242017-09-01 15:51:02 -04001812 fSaveLayerFlags are used to create Layer without transparency,
1813 create Layer for LCD text, and to create Layer with the
1814 contents of the previous Layer.
1815##
1816
1817#Example
1818#Height 160
1819#Description
Cary Clarkffb3d682018-05-17 12:17:28 -04001820Canvas Layer captures a red Anti_Aliased circle and a blue Aliased circle scaled
Cary Clarkce101242017-09-01 15:51:02 -04001821up by four. After drawing another red circle without scaling on top, the Layer is
Herb Derbyefe39bc2018-05-01 17:06:20 -04001822transferred to the main canvas.
Cary Clarkce101242017-09-01 15:51:02 -04001823##
1824void draw(SkCanvas* canvas) {
1825 SkPaint redPaint, bluePaint;
1826 redPaint.setAntiAlias(true);
1827 redPaint.setColor(SK_ColorRED);
1828 canvas->drawCircle(21, 21, 8, redPaint);
1829 bluePaint.setColor(SK_ColorBLUE);
1830 canvas->drawCircle(31, 21, 8, bluePaint);
1831 SkMatrix matrix;
1832 matrix.setScale(4, 4);
1833 auto scaler = SkImageFilter::MakeMatrixFilter(matrix, kNone_SkFilterQuality, nullptr);
Herb Derbyefe39bc2018-05-01 17:06:20 -04001834 SkCanvas::SaveLayerRec saveLayerRec(nullptr, nullptr, scaler.get(), 0);
Cary Clarkce101242017-09-01 15:51:02 -04001835 canvas->saveLayer(saveLayerRec);
1836 canvas->drawCircle(125, 85, 8, redPaint);
1837 canvas->restore();
1838}
1839##
1840
Cary Clark682c58d2018-05-16 07:07:07 -04001841#Subtopic Constructor
1842#Populate
1843##
Cary Clarkce101242017-09-01 15:51:02 -04001844
Cary Clark682c58d2018-05-16 07:07:07 -04001845#Method SaveLayerRec()
1846#Line # constructs SaveLayerRec ##
Cary Clarkce101242017-09-01 15:51:02 -04001847Sets fBounds, fPaint, and fBackdrop to nullptr. Clears fSaveLayerFlags.
1848
1849#Return empty SaveLayerRec ##
1850
1851#Example
1852 SkCanvas::SaveLayerRec rec1;
Mike Kleine083f7c2018-02-07 12:54:27 -05001853 rec1.fSaveLayerFlags = SkCanvas::kPreserveLCDText_SaveLayerFlag;
1854 SkCanvas::SaveLayerRec rec2(nullptr, nullptr, SkCanvas::kPreserveLCDText_SaveLayerFlag);
Cary Clarkce101242017-09-01 15:51:02 -04001855 SkDebugf("rec1 %c= rec2\n", rec1.fBounds == rec2.fBounds
1856 && rec1.fPaint == rec2.fPaint
1857 && rec1.fBackdrop == rec2.fBackdrop
1858 && rec1.fSaveLayerFlags == rec2.fSaveLayerFlags ? '=' : '!');
1859 #StdOut
1860 rec1 == rec2
1861 ##
1862##
1863
Cary Clark2ade9972017-11-02 17:49:34 -04001864#SeeAlso save() restore() saveLayer saveLayerPreserveLCDTextRequests saveLayerAlpha
1865
Cary Clarkce101242017-09-01 15:51:02 -04001866##
1867
Cary Clarkd98f78c2018-04-26 08:32:37 -04001868#Method SaveLayerRec(const SkRect* bounds, const SkPaint* paint,
1869 SaveLayerFlags saveLayerFlags = 0)
Cary Clarkce101242017-09-01 15:51:02 -04001870
1871Sets fBounds, fPaint, and fSaveLayerFlags; sets fBackdrop to nullptr.
1872
1873#Param bounds Layer dimensions; may be nullptr ##
1874#Param paint applied to Layer when overlaying prior Layer; may be nullptr ##
1875#Param saveLayerFlags SaveLayerRec options to modify Layer ##
1876
1877#Return SaveLayerRec with empty backdrop ##
1878
1879#Example
1880 SkCanvas::SaveLayerRec rec1;
1881 SkCanvas::SaveLayerRec rec2(nullptr, nullptr);
1882 SkDebugf("rec1 %c= rec2\n", rec1.fBounds == rec2.fBounds
1883 && rec1.fPaint == rec2.fPaint
1884 && rec1.fBackdrop == rec2.fBackdrop
1885 && rec1.fSaveLayerFlags == rec2.fSaveLayerFlags ? '=' : '!');
1886 #StdOut
1887 rec1 == rec2
1888 ##
1889##
1890
Cary Clark2ade9972017-11-02 17:49:34 -04001891#SeeAlso save() restore() saveLayer saveLayerPreserveLCDTextRequests saveLayerAlpha
1892
Cary Clarkce101242017-09-01 15:51:02 -04001893##
1894
1895#Method SaveLayerRec(const SkRect* bounds, const SkPaint* paint, const SkImageFilter* backdrop,
1896 SaveLayerFlags saveLayerFlags)
1897
1898Sets fBounds, fPaint, fBackdrop, and fSaveLayerFlags.
1899
1900#Param bounds Layer dimensions; may be nullptr ##
1901#Param paint applied to Layer when overlaying prior Layer;
1902 may be nullptr
1903##
1904#Param backdrop prior Layer copied with Image_Filter; may be nullptr
1905##
1906#Param saveLayerFlags SaveLayerRec options to modify Layer ##
1907
1908#Return SaveLayerRec fully specified ##
1909
1910#Example
1911 SkCanvas::SaveLayerRec rec1;
1912 SkCanvas::SaveLayerRec rec2(nullptr, nullptr, nullptr, 0);
1913 SkDebugf("rec1 %c= rec2\n", rec1.fBounds == rec2.fBounds
1914 && rec1.fPaint == rec2.fPaint
1915 && rec1.fBackdrop == rec2.fBackdrop
1916 && rec1.fSaveLayerFlags == rec2.fSaveLayerFlags ? '=' : '!');
1917 #StdOut
1918 rec1 == rec2
1919 ##
1920##
1921
Cary Clark2ade9972017-11-02 17:49:34 -04001922#SeeAlso save() restore() saveLayer saveLayerPreserveLCDTextRequests saveLayerAlpha
1923
Cary Clarkce101242017-09-01 15:51:02 -04001924##
1925
1926#Method SaveLayerRec(const SkRect* bounds, const SkPaint* paint, const SkImageFilter* backdrop,
1927 const SkImage* clipMask, const SkMatrix* clipMatrix,
1928 SaveLayerFlags saveLayerFlags)
1929
Cary Clark682c58d2018-05-16 07:07:07 -04001930#Experimental not ready
Cary Clarkce101242017-09-01 15:51:02 -04001931
1932Sets fBounds, fPaint, fBackdrop, fClipMask, fClipMatrix, and fSaveLayerFlags.
1933clipMatrix uses Color_Alpha channel of image, transformed by clipMatrix, to clip
1934Layer when drawn to Canvas.
1935
Cary Clark2ade9972017-11-02 17:49:34 -04001936Implementation is not complete; has no effect if Device is GPU-backed.
Cary Clarkce101242017-09-01 15:51:02 -04001937
1938#Param bounds Layer dimensions; may be nullptr ##
1939#Param paint graphics state applied to Layer when overlaying prior
1940 Layer; may be nullptr
1941##
1942#Param backdrop prior Layer copied with Image_Filter;
1943 may be nullptr
1944##
1945#Param clipMask clip applied to Layer; may be nullptr ##
1946#Param clipMatrix matrix applied to clipMask; may be nullptr to use
Herb Derbyefe39bc2018-05-01 17:06:20 -04001947 identity matrix
Cary Clarkce101242017-09-01 15:51:02 -04001948##
1949#Param saveLayerFlags SaveLayerRec options to modify Layer ##
1950
1951#Return SaveLayerRec fully specified ##
1952
Cary Clark2ade9972017-11-02 17:49:34 -04001953#SeeAlso save() restore() saveLayer saveLayerPreserveLCDTextRequests saveLayerAlpha
Cary Clarkce101242017-09-01 15:51:02 -04001954
1955##
1956
1957#Struct ##
1958
Cary Clark682c58d2018-05-16 07:07:07 -04001959#Subtopic ##
1960
Cary Clarkce101242017-09-01 15:51:02 -04001961#Method int saveLayer(const SaveLayerRec& layerRec)
1962
Cary Clarkab2621d2018-01-30 10:08:57 -05001963#In Layer
Cary Clarkce101242017-09-01 15:51:02 -04001964Saves Matrix, Clip, and Draw_Filter (Draw_Filter deprecated on most platforms),
1965and allocates Bitmap for subsequent drawing.
1966
1967Calling restore() discards changes to Matrix, Clip, and Draw_Filter,
1968and blends Bitmap with Color_Alpha opacity onto the prior Layer.
1969
1970Matrix may be changed by translate(), scale(), rotate(), skew(), concat(),
1971setMatrix, and resetMatrix. Clip may be changed by clipRect, clipRRect,
1972clipPath, clipRegion.
1973
1974SaveLayerRec contains the state used to create the Layer.
1975
1976Call restoreToCount with returned value to restore this and subsequent saves.
1977
1978#Param layerRec Layer state ##
1979
1980#Return depth of save state stack ##
1981
1982#Example
1983#Description
1984The example draws an image, and saves it into a Layer with kInitWithPrevious_SaveLayerFlag.
1985Next it punches a hole in Layer and restore with SkBlendMode::kPlus.
1986Where Layer was cleared, the original image will draw unchanged.
1987Outside of the circle the mandrill is brightened.
1988##
1989 #Image 3
Hal Canaryc465d132017-12-08 10:21:31 -05001990 // sk_sp<SkImage> image = GetResourceAsImage("images/mandrill_256.png");
Cary Clarkce101242017-09-01 15:51:02 -04001991 canvas->drawImage(image, 0, 0, nullptr);
1992 SkCanvas::SaveLayerRec rec;
1993 SkPaint paint;
1994 paint.setBlendMode(SkBlendMode::kPlus);
1995 rec.fSaveLayerFlags = SkCanvas::kInitWithPrevious_SaveLayerFlag;
1996 rec.fPaint = &paint;
1997 canvas->saveLayer(rec);
1998 paint.setBlendMode(SkBlendMode::kClear);
1999 canvas->drawCircle(128, 128, 96, paint);
2000 canvas->restore();
2001##
2002
2003#ToDo above example needs to replace GetResourceAsImage with way to select image in fiddle ##
2004
Cary Clark2ade9972017-11-02 17:49:34 -04002005#SeeAlso save() restore() saveLayer saveLayerPreserveLCDTextRequests saveLayerAlpha
2006
Cary Clarkce101242017-09-01 15:51:02 -04002007##
2008
Cary Clark08895c42018-02-01 09:37:32 -05002009#Subtopic Layer ##
Cary Clarkce101242017-09-01 15:51:02 -04002010
2011# ------------------------------------------------------------------------------
Cary Clark08895c42018-02-01 09:37:32 -05002012#Subtopic Matrix
2013#Line # coordinate transformation ##
Cary Clark8032b982017-07-28 11:04:54 -04002014
2015#Method void translate(SkScalar dx, SkScalar dy)
2016
Cary Clarkab2621d2018-01-30 10:08:57 -05002017#In Matrix
2018#Line # translates Matrix ##
Cary Clark8032b982017-07-28 11:04:54 -04002019Translate Matrix by dx along the x-axis and dy along the y-axis.
2020
2021Mathematically, replace Matrix with a translation matrix
Herb Derbyefe39bc2018-05-01 17:06:20 -04002022Premultiplied with Matrix.
Cary Clark8032b982017-07-28 11:04:54 -04002023
2024This has the effect of moving the drawing by (dx, dy) before transforming
2025the result with Matrix.
2026
Cary Clarkbad5ad72017-08-03 17:14:08 -04002027#Param dx distance to translate in x ##
2028#Param dy distance to translate in y ##
Cary Clark8032b982017-07-28 11:04:54 -04002029
2030#Example
2031#Height 128
2032#Description
2033scale() followed by translate() produces different results from translate() followed
Herb Derbyefe39bc2018-05-01 17:06:20 -04002034by scale().
Cary Clark8032b982017-07-28 11:04:54 -04002035
2036The blue stroke follows translate of (50, 50); a black
Herb Derbyefe39bc2018-05-01 17:06:20 -04002037fill follows scale of (2, 1/2.f). After restoring the clip, which resets
Cary Clark8032b982017-07-28 11:04:54 -04002038Matrix, a red frame follows the same scale of (2, 1/2.f); a gray fill
2039follows translate of (50, 50).
2040##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002041void draw(SkCanvas* canvas) {
2042 SkPaint filledPaint;
2043 SkPaint outlinePaint;
2044 outlinePaint.setStyle(SkPaint::kStroke_Style);
2045 outlinePaint.setColor(SK_ColorBLUE);
2046 canvas->save();
2047 canvas->translate(50, 50);
2048 canvas->drawCircle(28, 28, 15, outlinePaint); // blue center: (50+28, 50+28)
2049 canvas->scale(2, 1/2.f);
2050 canvas->drawCircle(28, 28, 15, filledPaint); // black center: (50+(28*2), 50+(28/2))
2051 canvas->restore();
2052 filledPaint.setColor(SK_ColorGRAY);
2053 outlinePaint.setColor(SK_ColorRED);
2054 canvas->scale(2, 1/2.f);
2055 canvas->drawCircle(28, 28, 15, outlinePaint); // red center: (28*2, 28/2)
2056 canvas->translate(50, 50);
2057 canvas->drawCircle(28, 28, 15, filledPaint); // gray center: ((50+28)*2, (50+28)/2)
Cary Clark8032b982017-07-28 11:04:54 -04002058}
2059##
2060
Cary Clark2ade9972017-11-02 17:49:34 -04002061#SeeAlso concat() scale() skew() rotate() setMatrix
Cary Clark8032b982017-07-28 11:04:54 -04002062
2063##
2064
2065# ------------------------------------------------------------------------------
2066
2067#Method void scale(SkScalar sx, SkScalar sy)
2068
Cary Clarkab2621d2018-01-30 10:08:57 -05002069#In Matrix
2070#Line # scales Matrix ##
Cary Clark8032b982017-07-28 11:04:54 -04002071Scale Matrix by sx on the x-axis and sy on the y-axis.
2072
2073Mathematically, replace Matrix with a scale matrix
Herb Derbyefe39bc2018-05-01 17:06:20 -04002074Premultiplied with Matrix.
Cary Clark8032b982017-07-28 11:04:54 -04002075
2076This has the effect of scaling the drawing by (sx, sy) before transforming
2077the result with Matrix.
2078
Cary Clarkbad5ad72017-08-03 17:14:08 -04002079#Param sx amount to scale in x ##
2080#Param sy amount to scale in y ##
Cary Clark8032b982017-07-28 11:04:54 -04002081
2082#Example
2083#Height 160
Cary Clarkbad5ad72017-08-03 17:14:08 -04002084void draw(SkCanvas* canvas) {
2085 SkPaint paint;
2086 SkRect rect = { 10, 20, 60, 120 };
2087 canvas->translate(20, 20);
2088 canvas->drawRect(rect, paint);
2089 canvas->scale(2, .5f);
2090 paint.setColor(SK_ColorGRAY);
2091 canvas->drawRect(rect, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002092}
2093##
2094
Cary Clark2ade9972017-11-02 17:49:34 -04002095#SeeAlso concat() translate() skew() rotate() setMatrix
Cary Clark8032b982017-07-28 11:04:54 -04002096
2097##
2098
2099# ------------------------------------------------------------------------------
2100
2101#Method void rotate(SkScalar degrees)
2102
Cary Clarkab2621d2018-01-30 10:08:57 -05002103#In Matrix
2104#Line # rotates Matrix ##
Cary Clark8032b982017-07-28 11:04:54 -04002105Rotate Matrix by degrees. Positive degrees rotates clockwise.
2106
2107Mathematically, replace Matrix with a rotation matrix
Herb Derbyefe39bc2018-05-01 17:06:20 -04002108Premultiplied with Matrix.
Cary Clark8032b982017-07-28 11:04:54 -04002109
2110This has the effect of rotating the drawing by degrees before transforming
2111the result with Matrix.
2112
Cary Clarkbad5ad72017-08-03 17:14:08 -04002113#Param degrees amount to rotate, in degrees ##
Cary Clark8032b982017-07-28 11:04:54 -04002114
2115#Example
2116#Description
2117Draw clock hands at time 5:10. The hour hand and minute hand point up and
2118are rotated clockwise.
2119##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002120void draw(SkCanvas* canvas) {
2121 SkPaint paint;
2122 paint.setStyle(SkPaint::kStroke_Style);
2123 canvas->translate(128, 128);
2124 canvas->drawCircle(0, 0, 60, paint);
2125 canvas->save();
2126 canvas->rotate(10 * 360 / 60); // 10 minutes of 60 scaled to 360 degrees
Herb Derbyefe39bc2018-05-01 17:06:20 -04002127 canvas->drawLine(0, 0, 0, -50, paint);
Cary Clarkbad5ad72017-08-03 17:14:08 -04002128 canvas->restore();
2129 canvas->rotate((5 + 10.f/60) * 360 / 12); // 5 and 10/60 hours of 12 scaled to 360 degrees
2130 canvas->drawLine(0, 0, 0, -30, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002131}
2132##
2133
Cary Clark2ade9972017-11-02 17:49:34 -04002134#SeeAlso concat() translate() skew() scale() setMatrix
Cary Clark8032b982017-07-28 11:04:54 -04002135
2136##
2137
2138# ------------------------------------------------------------------------------
2139
2140#Method void rotate(SkScalar degrees, SkScalar px, SkScalar py)
2141
Cary Clarkab2621d2018-01-30 10:08:57 -05002142#In Matrix
Cary Clarkbad5ad72017-08-03 17:14:08 -04002143Rotate Matrix by degrees about a point at (px, py). Positive degrees rotates
2144clockwise.
Cary Clark8032b982017-07-28 11:04:54 -04002145
Cary Clarkce101242017-09-01 15:51:02 -04002146Mathematically, construct a rotation matrix. Premultiply the rotation matrix by
Cary Clark8032b982017-07-28 11:04:54 -04002147a translation matrix, then replace Matrix with the resulting matrix
Herb Derbyefe39bc2018-05-01 17:06:20 -04002148Premultiplied with Matrix.
Cary Clark8032b982017-07-28 11:04:54 -04002149
Cary Clarkbad5ad72017-08-03 17:14:08 -04002150This has the effect of rotating the drawing about a given point before
2151transforming the result with Matrix.
Cary Clark8032b982017-07-28 11:04:54 -04002152
Cary Clarkbad5ad72017-08-03 17:14:08 -04002153#Param degrees amount to rotate, in degrees ##
2154#Param px x-coordinate of the point to rotate about ##
2155#Param py y-coordinate of the point to rotate about ##
Cary Clark8032b982017-07-28 11:04:54 -04002156
2157#Example
2158#Height 192
Cary Clarkbad5ad72017-08-03 17:14:08 -04002159void draw(SkCanvas* canvas) {
2160 SkPaint paint;
2161 paint.setTextSize(96);
2162 canvas->drawString("A1", 130, 100, paint);
2163 canvas->rotate(180, 130, 100);
2164 canvas->drawString("A1", 130, 100, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002165}
2166##
2167
Cary Clark2ade9972017-11-02 17:49:34 -04002168#SeeAlso concat() translate() skew() scale() setMatrix
Cary Clark8032b982017-07-28 11:04:54 -04002169
2170##
2171
2172# ------------------------------------------------------------------------------
2173
2174#Method void skew(SkScalar sx, SkScalar sy)
2175
Cary Clarkab2621d2018-01-30 10:08:57 -05002176#In Matrix
2177#Line # skews Matrix ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002178Skew Matrix by sx on the x-axis and sy on the y-axis. A positive value of sx
2179skews the drawing right as y increases; a positive value of sy skews the drawing
2180down as x increases.
Cary Clark8032b982017-07-28 11:04:54 -04002181
Herb Derbyefe39bc2018-05-01 17:06:20 -04002182Mathematically, replace Matrix with a skew matrix Premultiplied with Matrix.
Cary Clark8032b982017-07-28 11:04:54 -04002183
Cary Clarkbad5ad72017-08-03 17:14:08 -04002184This has the effect of skewing the drawing by (sx, sy) before transforming
Cary Clark8032b982017-07-28 11:04:54 -04002185the result with Matrix.
2186
Cary Clarkbad5ad72017-08-03 17:14:08 -04002187#Param sx amount to skew in x ##
2188#Param sy amount to skew in y ##
2189
Cary Clark8032b982017-07-28 11:04:54 -04002190#Example
Herb Derbyefe39bc2018-05-01 17:06:20 -04002191 #Description
Cary Clark8032b982017-07-28 11:04:54 -04002192 Black text mimics an oblique text style by using a negative skew in x that
2193 shifts the geometry to the right as the y values decrease.
2194 Red text uses a positive skew in y to shift the geometry down as the x values
2195 increase.
2196 Blue text combines x and y skew to rotate and scale.
2197 ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002198 SkPaint paint;
2199 paint.setTextSize(128);
2200 canvas->translate(30, 130);
2201 canvas->save();
2202 canvas->skew(-.5, 0);
2203 canvas->drawString("A1", 0, 0, paint);
2204 canvas->restore();
2205 canvas->save();
2206 canvas->skew(0, .5);
2207 paint.setColor(SK_ColorRED);
2208 canvas->drawString("A1", 0, 0, paint);
2209 canvas->restore();
2210 canvas->skew(-.5, .5);
2211 paint.setColor(SK_ColorBLUE);
Cary Clark8032b982017-07-28 11:04:54 -04002212 canvas->drawString("A1", 0, 0, paint);
2213##
2214
Cary Clark2ade9972017-11-02 17:49:34 -04002215#SeeAlso concat() translate() rotate() scale() setMatrix
Cary Clark8032b982017-07-28 11:04:54 -04002216
2217##
2218
2219# ------------------------------------------------------------------------------
2220
2221#Method void concat(const SkMatrix& matrix)
2222
Cary Clarkab2621d2018-01-30 10:08:57 -05002223#In Matrix
2224#Line # multiplies Matrix by Matrix ##
Cary Clarkce101242017-09-01 15:51:02 -04002225Replace Matrix with matrix Premultiplied with existing Matrix.
Cary Clark8032b982017-07-28 11:04:54 -04002226
Cary Clarkbad5ad72017-08-03 17:14:08 -04002227This has the effect of transforming the drawn geometry by matrix, before
2228transforming the result with existing Matrix.
Cary Clark8032b982017-07-28 11:04:54 -04002229
Cary Clarkce101242017-09-01 15:51:02 -04002230#Param matrix matrix to Premultiply with existing Matrix ##
Cary Clark8032b982017-07-28 11:04:54 -04002231
2232#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04002233void draw(SkCanvas* canvas) {
2234 SkPaint paint;
2235 paint.setTextSize(80);
2236 paint.setTextScaleX(.3);
2237 SkMatrix matrix;
2238 SkRect rect[2] = {{ 10, 20, 90, 110 }, { 40, 130, 140, 180 }};
2239 matrix.setRectToRect(rect[0], rect[1], SkMatrix::kFill_ScaleToFit);
2240 canvas->drawRect(rect[0], paint);
2241 canvas->drawRect(rect[1], paint);
2242 paint.setColor(SK_ColorWHITE);
2243 canvas->drawString("Here", rect[0].fLeft + 10, rect[0].fBottom - 10, paint);
2244 canvas->concat(matrix);
2245 canvas->drawString("There", rect[0].fLeft + 10, rect[0].fBottom - 10, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002246}
2247##
2248
Cary Clark2ade9972017-11-02 17:49:34 -04002249#SeeAlso translate() rotate() scale() skew() setMatrix
Cary Clark8032b982017-07-28 11:04:54 -04002250
2251##
2252
2253# ------------------------------------------------------------------------------
2254
2255#Method void setMatrix(const SkMatrix& matrix)
2256
Cary Clarkab2621d2018-01-30 10:08:57 -05002257#In Matrix
2258#Line # sets Matrix ##
Cary Clark8032b982017-07-28 11:04:54 -04002259Replace Matrix with matrix.
2260Unlike concat(), any prior matrix state is overwritten.
2261
Cary Clarkbad5ad72017-08-03 17:14:08 -04002262#Param matrix matrix to copy, replacing existing Matrix ##
Cary Clark8032b982017-07-28 11:04:54 -04002263
2264#Example
2265#Height 128
Cary Clarkbad5ad72017-08-03 17:14:08 -04002266void draw(SkCanvas* canvas) {
2267 SkPaint paint;
2268 canvas->scale(4, 6);
2269 canvas->drawString("truth", 2, 10, paint);
2270 SkMatrix matrix;
2271 matrix.setScale(2.8f, 6);
2272 canvas->setMatrix(matrix);
2273 canvas->drawString("consequences", 2, 20, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002274}
2275##
2276
Cary Clark2ade9972017-11-02 17:49:34 -04002277#SeeAlso resetMatrix concat() translate() rotate() scale() skew()
Cary Clark8032b982017-07-28 11:04:54 -04002278
2279##
2280
2281# ------------------------------------------------------------------------------
2282
2283#Method void resetMatrix()
2284
Cary Clarkab2621d2018-01-30 10:08:57 -05002285#In Matrix
2286#Line # resets Matrix to identity ##
Cary Clark8032b982017-07-28 11:04:54 -04002287Sets Matrix to the identity matrix.
2288Any prior matrix state is overwritten.
2289
2290#Example
2291#Height 128
Cary Clarkbad5ad72017-08-03 17:14:08 -04002292void draw(SkCanvas* canvas) {
2293 SkPaint paint;
2294 canvas->scale(4, 6);
2295 canvas->drawString("truth", 2, 10, paint);
2296 canvas->resetMatrix();
2297 canvas->scale(2.8f, 6);
2298 canvas->drawString("consequences", 2, 20, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002299}
2300##
2301
Cary Clark2ade9972017-11-02 17:49:34 -04002302#SeeAlso setMatrix concat() translate() rotate() scale() skew()
Cary Clark8032b982017-07-28 11:04:54 -04002303
2304##
2305
2306# ------------------------------------------------------------------------------
2307
2308#Method const SkMatrix& getTotalMatrix() const
2309
Cary Clarkab2621d2018-01-30 10:08:57 -05002310#In Matrix
2311#Line # returns Matrix ##
Cary Clark8032b982017-07-28 11:04:54 -04002312Returns Matrix.
2313This does not account for translation by Device or Surface.
2314
Cary Clarkbad5ad72017-08-03 17:14:08 -04002315#Return Matrix in Canvas ##
Cary Clark8032b982017-07-28 11:04:54 -04002316
2317#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04002318 SkDebugf("isIdentity %s\n", canvas->getTotalMatrix().isIdentity() ? "true" : "false");
2319 #StdOut
2320 isIdentity true
2321 ##
Cary Clark8032b982017-07-28 11:04:54 -04002322##
2323
Cary Clark2ade9972017-11-02 17:49:34 -04002324#SeeAlso setMatrix resetMatrix concat()
Cary Clark8032b982017-07-28 11:04:54 -04002325
2326##
2327
Cary Clark08895c42018-02-01 09:37:32 -05002328#Subtopic Matrix ##
Cary Clark8032b982017-07-28 11:04:54 -04002329
2330# ------------------------------------------------------------------------------
Cary Clark08895c42018-02-01 09:37:32 -05002331#Subtopic Clip
2332#Line # stack of clipping Paths ##
Cary Clark8032b982017-07-28 11:04:54 -04002333
2334Clip is built from a stack of clipping paths. Each Path in the
Herb Derbyefe39bc2018-05-01 17:06:20 -04002335stack can be constructed from one or more Path_Contour elements. The
Cary Clark8032b982017-07-28 11:04:54 -04002336Path_Contour may be composed of any number of Path_Verb segments. Each
2337Path_Contour forms a closed area; Path_Fill_Type defines the area enclosed
2338by Path_Contour.
2339
2340Clip stack of Path elements successfully restrict the Path area. Each
Herb Derbyefe39bc2018-05-01 17:06:20 -04002341Path is transformed by Matrix, then intersected with or subtracted from the
Cary Clark8032b982017-07-28 11:04:54 -04002342prior Clip to form the replacement Clip. Use SkClipOp::kDifference
2343to subtract Path from Clip; use SkClipOp::kIntersect to intersect Path
2344with Clip.
2345
Cary Clarkffb3d682018-05-17 12:17:28 -04002346A clipping Path may be Anti_Aliased; if Path, after transformation, is
2347composed of horizontal and vertical lines, clearing Anti_Alias allows whole pixels
Cary Clarkce101242017-09-01 15:51:02 -04002348to either be inside or outside the clip. The fastest drawing has a Aliased,
2349rectangular clip.
Cary Clark8032b982017-07-28 11:04:54 -04002350
Cary Clarkffb3d682018-05-17 12:17:28 -04002351If clipping Path has Anti_Alias set, clip may partially clip a pixel, requiring
Herb Derbyefe39bc2018-05-01 17:06:20 -04002352that drawing blend partially with the destination along the edge. A rotated
Cary Clarkffb3d682018-05-17 12:17:28 -04002353rectangular Anti_Aliased clip looks smoother but draws slower.
Cary Clark8032b982017-07-28 11:04:54 -04002354
2355Clip can combine with Rect and Round_Rect primitives; like
2356Path, these are transformed by Matrix before they are combined with Clip.
2357
2358Clip can combine with Region. Region is assumed to be in Device coordinates
2359and is unaffected by Matrix.
2360
2361#Example
2362#Height 90
2363 #Description
Cary Clarkffb3d682018-05-17 12:17:28 -04002364 Draw a red circle with an Aliased clip and an Anti_Aliased clip.
Cary Clark8032b982017-07-28 11:04:54 -04002365 Use an image filter to zoom into the pixels drawn.
Cary Clarkce101242017-09-01 15:51:02 -04002366 The edge of the Aliased clip fully draws pixels in the red circle.
Cary Clarkffb3d682018-05-17 12:17:28 -04002367 The edge of the Anti_Aliased clip partially draws pixels in the red circle.
Cary Clark8032b982017-07-28 11:04:54 -04002368 ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002369 SkPaint redPaint, scalePaint;
2370 redPaint.setAntiAlias(true);
2371 redPaint.setColor(SK_ColorRED);
2372 canvas->save();
2373 for (bool antialias : { false, true } ) {
2374 canvas->save();
2375 canvas->clipRect(SkRect::MakeWH(19.5f, 11.5f), antialias);
2376 canvas->drawCircle(17, 11, 8, redPaint);
2377 canvas->restore();
2378 canvas->translate(16, 0);
2379 }
2380 canvas->restore();
2381 SkMatrix matrix;
2382 matrix.setScale(6, 6);
2383 scalePaint.setImageFilter(
2384 SkImageFilter::MakeMatrixFilter(matrix, kNone_SkFilterQuality, nullptr));
2385 SkCanvas::SaveLayerRec saveLayerRec(
Herb Derbyefe39bc2018-05-01 17:06:20 -04002386 nullptr, &scalePaint, SkCanvas::kInitWithPrevious_SaveLayerFlag);
Cary Clarkbad5ad72017-08-03 17:14:08 -04002387 canvas->saveLayer(saveLayerRec);
Cary Clark8032b982017-07-28 11:04:54 -04002388 canvas->restore();
2389##
2390
2391#Method void clipRect(const SkRect& rect, SkClipOp op, bool doAntiAlias)
2392
Cary Clarkab2621d2018-01-30 10:08:57 -05002393#In Clip
2394#Line # combines Clip with Rect ##
Cary Clark8032b982017-07-28 11:04:54 -04002395Replace Clip with the intersection or difference of Clip and rect,
Cary Clarkffb3d682018-05-17 12:17:28 -04002396with an Aliased or Anti_Aliased clip edge. rect is transformed by Matrix
Cary Clark8032b982017-07-28 11:04:54 -04002397before it is combined with Clip.
2398
Cary Clarka523d2d2017-08-30 08:58:10 -04002399#Param rect Rect to combine with Clip ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002400#Param op Clip_Op to apply to Clip ##
Cary Clarkffb3d682018-05-17 12:17:28 -04002401#Param doAntiAlias true if Clip is to be Anti_Aliased ##
Cary Clark8032b982017-07-28 11:04:54 -04002402
2403#Example
2404#Height 128
Cary Clarkbad5ad72017-08-03 17:14:08 -04002405void draw(SkCanvas* canvas) {
2406 canvas->rotate(10);
2407 SkPaint paint;
2408 paint.setAntiAlias(true);
2409 for (auto alias: { false, true } ) {
2410 canvas->save();
2411 canvas->clipRect(SkRect::MakeWH(90, 80), SkClipOp::kIntersect, alias);
2412 canvas->drawCircle(100, 60, 60, paint);
2413 canvas->restore();
2414 canvas->translate(80, 0);
2415 }
Cary Clark8032b982017-07-28 11:04:54 -04002416}
2417##
2418
Cary Clark2ade9972017-11-02 17:49:34 -04002419#SeeAlso clipRRect clipPath clipRegion
Cary Clark8032b982017-07-28 11:04:54 -04002420
2421##
2422
Herb Derbyefe39bc2018-05-01 17:06:20 -04002423#Method void clipRect(const SkRect& rect, SkClipOp op)
Cary Clark8032b982017-07-28 11:04:54 -04002424
Cary Clarkab2621d2018-01-30 10:08:57 -05002425#In Clip
Cary Clark8032b982017-07-28 11:04:54 -04002426Replace Clip with the intersection or difference of Clip and rect.
Cary Clarkce101242017-09-01 15:51:02 -04002427Resulting Clip is Aliased; pixels are fully contained by the clip.
Cary Clarkbad5ad72017-08-03 17:14:08 -04002428rect is transformed by Matrix before it is combined with Clip.
Cary Clark8032b982017-07-28 11:04:54 -04002429
Cary Clarka523d2d2017-08-30 08:58:10 -04002430#Param rect Rect to combine with Clip ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002431#Param op Clip_Op to apply to Clip ##
Cary Clark8032b982017-07-28 11:04:54 -04002432
2433#Example
2434#Height 192
2435#Width 280
Cary Clarkbad5ad72017-08-03 17:14:08 -04002436void draw(SkCanvas* canvas) {
2437 SkPaint paint;
2438 for (SkClipOp op: { SkClipOp::kIntersect, SkClipOp::kDifference } ) {
2439 canvas->save();
2440 canvas->clipRect(SkRect::MakeWH(90, 120), op, false);
2441 canvas->drawCircle(100, 100, 60, paint);
2442 canvas->restore();
2443 canvas->translate(80, 0);
2444 }
Cary Clark8032b982017-07-28 11:04:54 -04002445}
2446##
2447
Cary Clark2ade9972017-11-02 17:49:34 -04002448#SeeAlso clipRRect clipPath clipRegion
Cary Clark8032b982017-07-28 11:04:54 -04002449
2450##
2451
Herb Derbyefe39bc2018-05-01 17:06:20 -04002452#Method void clipRect(const SkRect& rect, bool doAntiAlias = false)
Cary Clark8032b982017-07-28 11:04:54 -04002453
Cary Clarkab2621d2018-01-30 10:08:57 -05002454#In Clip
Cary Clark8032b982017-07-28 11:04:54 -04002455Replace Clip with the intersection of Clip and rect.
Cary Clarkce101242017-09-01 15:51:02 -04002456Resulting Clip is Aliased; pixels are fully contained by the clip.
Cary Clark8032b982017-07-28 11:04:54 -04002457rect is transformed by Matrix
2458before it is combined with Clip.
2459
Cary Clarka523d2d2017-08-30 08:58:10 -04002460#Param rect Rect to combine with Clip ##
Cary Clarkffb3d682018-05-17 12:17:28 -04002461#Param doAntiAlias true if Clip is to be Anti_Aliased ##
Cary Clark8032b982017-07-28 11:04:54 -04002462
2463#Example
2464#Height 133
2465 #Description
Cary Clarkce101242017-09-01 15:51:02 -04002466 A circle drawn in pieces looks uniform when drawn Aliased.
Cary Clarkffb3d682018-05-17 12:17:28 -04002467 The same circle pieces blend with pixels more than once when Anti_Aliased,
Cary Clark8032b982017-07-28 11:04:54 -04002468 visible as a thin pair of lines through the right circle.
2469 ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002470void draw(SkCanvas* canvas) {
2471 canvas->clear(SK_ColorWHITE);
2472 SkPaint paint;
2473 paint.setAntiAlias(true);
2474 paint.setColor(0x8055aaff);
2475 SkRect clipRect = { 0, 0, 87.4f, 87.4f };
2476 for (auto alias: { false, true } ) {
2477 canvas->save();
2478 canvas->clipRect(clipRect, SkClipOp::kIntersect, alias);
2479 canvas->drawCircle(67, 67, 60, paint);
2480 canvas->restore();
2481 canvas->save();
2482 canvas->clipRect(clipRect, SkClipOp::kDifference, alias);
2483 canvas->drawCircle(67, 67, 60, paint);
2484 canvas->restore();
2485 canvas->translate(120, 0);
2486 }
Cary Clark8032b982017-07-28 11:04:54 -04002487}
2488##
2489
Cary Clark2ade9972017-11-02 17:49:34 -04002490#SeeAlso clipRRect clipPath clipRegion
Cary Clark8032b982017-07-28 11:04:54 -04002491
2492##
2493
2494#Method void androidFramework_setDeviceClipRestriction(const SkIRect& rect)
2495
Cary Clarkab2621d2018-01-30 10:08:57 -05002496#In Clip
Cary Clark682c58d2018-05-16 07:07:07 -04002497#Line # exists for use by Android framework ##
Cary Clarkce101242017-09-01 15:51:02 -04002498Sets the maximum clip rectangle, which can be set by clipRect, clipRRect and
Cary Clark8032b982017-07-28 11:04:54 -04002499clipPath and intersect the current clip with the specified rect.
Cary Clarkce101242017-09-01 15:51:02 -04002500The maximum clip affects only future clipping operations; it is not retroactive.
Cary Clark8032b982017-07-28 11:04:54 -04002501The clip restriction is not recorded in pictures.
2502
Herb Derbyefe39bc2018-05-01 17:06:20 -04002503Pass an empty rect to disable maximum clip.
Cary Clarkbad5ad72017-08-03 17:14:08 -04002504
Cary Clark8032b982017-07-28 11:04:54 -04002505#Private
Cary Clark137b8742018-05-30 09:21:49 -04002506This private API is for use by Android framework only.
Cary Clark8032b982017-07-28 11:04:54 -04002507##
2508
Cary Clarkbad5ad72017-08-03 17:14:08 -04002509#Param rect maximum allowed clip in device coordinates
Cary Clark579985c2017-07-31 11:48:27 -04002510#Param ##
Cary Clark8032b982017-07-28 11:04:54 -04002511
2512##
2513
2514#Method void clipRRect(const SkRRect& rrect, SkClipOp op, bool doAntiAlias)
2515
Cary Clarkab2621d2018-01-30 10:08:57 -05002516#In Clip
2517#Line # combines Clip with Round_Rect ##
Cary Clark8032b982017-07-28 11:04:54 -04002518Replace Clip with the intersection or difference of Clip and rrect,
Cary Clarkffb3d682018-05-17 12:17:28 -04002519with an Aliased or Anti_Aliased clip edge.
Cary Clark8032b982017-07-28 11:04:54 -04002520rrect is transformed by Matrix
2521before it is combined with Clip.
2522
Cary Clarkbad5ad72017-08-03 17:14:08 -04002523#Param rrect Round_Rect to combine with Clip ##
2524#Param op Clip_Op to apply to Clip ##
Cary Clarkffb3d682018-05-17 12:17:28 -04002525#Param doAntiAlias true if Clip is to be Anti_Aliased ##
Cary Clark8032b982017-07-28 11:04:54 -04002526
2527#Example
2528#Height 128
Cary Clarkbad5ad72017-08-03 17:14:08 -04002529void draw(SkCanvas* canvas) {
2530 canvas->clear(SK_ColorWHITE);
2531 SkPaint paint;
2532 paint.setAntiAlias(true);
2533 paint.setColor(0x8055aaff);
2534 SkRRect oval;
2535 oval.setOval({10, 20, 90, 100});
2536 canvas->clipRRect(oval, SkClipOp::kIntersect, true);
2537 canvas->drawCircle(70, 100, 60, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002538}
2539##
2540
Cary Clark2ade9972017-11-02 17:49:34 -04002541#SeeAlso clipRect clipPath clipRegion
Cary Clark8032b982017-07-28 11:04:54 -04002542
2543##
2544
Herb Derbyefe39bc2018-05-01 17:06:20 -04002545#Method void clipRRect(const SkRRect& rrect, SkClipOp op)
Cary Clark8032b982017-07-28 11:04:54 -04002546
Cary Clarkab2621d2018-01-30 10:08:57 -05002547#In Clip
Cary Clark8032b982017-07-28 11:04:54 -04002548Replace Clip with the intersection or difference of Clip and rrect.
Cary Clarkce101242017-09-01 15:51:02 -04002549Resulting Clip is Aliased; pixels are fully contained by the clip.
Cary Clarkbad5ad72017-08-03 17:14:08 -04002550rrect is transformed by Matrix before it is combined with Clip.
Cary Clark8032b982017-07-28 11:04:54 -04002551
Cary Clarkbad5ad72017-08-03 17:14:08 -04002552#Param rrect Round_Rect to combine with Clip ##
2553#Param op Clip_Op to apply to Clip ##
Cary Clark8032b982017-07-28 11:04:54 -04002554
2555#Example
2556#Height 128
Cary Clarkbad5ad72017-08-03 17:14:08 -04002557void draw(SkCanvas* canvas) {
2558 SkPaint paint;
2559 paint.setColor(0x8055aaff);
2560 auto oval = SkRRect::MakeOval({10, 20, 90, 100});
2561 canvas->clipRRect(oval, SkClipOp::kIntersect);
2562 canvas->drawCircle(70, 100, 60, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002563}
2564##
2565
Cary Clark2ade9972017-11-02 17:49:34 -04002566#SeeAlso clipRect clipPath clipRegion
Cary Clark8032b982017-07-28 11:04:54 -04002567
2568##
2569
Herb Derbyefe39bc2018-05-01 17:06:20 -04002570#Method void clipRRect(const SkRRect& rrect, bool doAntiAlias = false)
Cary Clark8032b982017-07-28 11:04:54 -04002571
Cary Clarkab2621d2018-01-30 10:08:57 -05002572#In Clip
Cary Clark8032b982017-07-28 11:04:54 -04002573Replace Clip with the intersection of Clip and rrect,
Cary Clarkffb3d682018-05-17 12:17:28 -04002574with an Aliased or Anti_Aliased clip edge.
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 ##
Cary Clarkffb3d682018-05-17 12:17:28 -04002578#Param doAntiAlias true if Clip is to be Anti_Aliased ##
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.setAntiAlias(true);
2585 auto oval = SkRRect::MakeRectXY({10, 20, 90, 100}, 9, 13);
2586 canvas->clipRRect(oval, true);
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 clipPath(const SkPath& path, SkClipOp op, bool doAntiAlias)
2596
Cary Clarkab2621d2018-01-30 10:08:57 -05002597#In Clip
2598#Line # combines Clip with Path ##
Cary Clark8032b982017-07-28 11:04:54 -04002599Replace Clip with the intersection or difference of Clip and path,
Cary Clarkffb3d682018-05-17 12:17:28 -04002600with an Aliased or Anti_Aliased clip edge. Path_Fill_Type determines if path
Cary Clark8032b982017-07-28 11:04:54 -04002601describes the area inside or outside its contours; and if Path_Contour overlaps
2602itself or another Path_Contour, whether the overlaps form part of the area.
Cary Clarkbad5ad72017-08-03 17:14:08 -04002603path is transformed by Matrix before it is combined with Clip.
Cary Clark8032b982017-07-28 11:04:54 -04002604
Cary Clarkbad5ad72017-08-03 17:14:08 -04002605#Param path Path to combine with Clip ##
2606#Param op Clip_Op to apply to Clip ##
Cary Clarkffb3d682018-05-17 12:17:28 -04002607#Param doAntiAlias true if Clip is to be Anti_Aliased ##
Cary Clark8032b982017-07-28 11:04:54 -04002608
2609#Example
2610#Description
2611Top figure uses SkPath::kInverseWinding_FillType and SkClipOp::kDifference;
2612area outside clip is subtracted from circle.
2613
2614Bottom figure uses SkPath::kWinding_FillType and SkClipOp::kIntersect;
2615area inside clip is intersected with circle.
2616##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002617void draw(SkCanvas* canvas) {
2618 SkPaint paint;
2619 paint.setAntiAlias(true);
2620 SkPath path;
2621 path.addRect({20, 30, 100, 110});
2622 path.setFillType(SkPath::kInverseWinding_FillType);
2623 canvas->save();
2624 canvas->clipPath(path, SkClipOp::kDifference, false);
2625 canvas->drawCircle(70, 100, 60, paint);
2626 canvas->restore();
2627 canvas->translate(100, 100);
2628 path.setFillType(SkPath::kWinding_FillType);
2629 canvas->clipPath(path, SkClipOp::kIntersect, false);
2630 canvas->drawCircle(70, 100, 60, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002631}
2632##
2633
Cary Clark2ade9972017-11-02 17:49:34 -04002634#SeeAlso clipRect clipRRect clipRegion
Cary Clark8032b982017-07-28 11:04:54 -04002635
2636##
2637
Herb Derbyefe39bc2018-05-01 17:06:20 -04002638#Method void clipPath(const SkPath& path, SkClipOp op)
Cary Clark8032b982017-07-28 11:04:54 -04002639
Cary Clarkab2621d2018-01-30 10:08:57 -05002640#In Clip
Cary Clark8032b982017-07-28 11:04:54 -04002641Replace Clip with the intersection or difference of Clip and path.
Cary Clarkce101242017-09-01 15:51:02 -04002642Resulting Clip is Aliased; pixels are fully contained by the clip.
Cary Clark8032b982017-07-28 11:04:54 -04002643Path_Fill_Type determines if path
2644describes the area inside or outside its contours; and if Path_Contour overlaps
2645itself or another Path_Contour, whether the overlaps form part of the area.
2646path is transformed by Matrix
2647before it is combined with Clip.
2648
Cary Clarkbad5ad72017-08-03 17:14:08 -04002649#Param path Path to combine with Clip ##
2650#Param op Clip_Op to apply to Clip ##
Cary Clark8032b982017-07-28 11:04:54 -04002651
2652#Example
2653#Description
Cary Clarkbc5697d2017-10-04 14:31:33 -04002654Overlapping Rects form a clip. When clip Path_Fill_Type is set to
Herb Derbyefe39bc2018-05-01 17:06:20 -04002655SkPath::kWinding_FillType, the overlap is included. Set to
Cary Clark8032b982017-07-28 11:04:54 -04002656SkPath::kEvenOdd_FillType, the overlap is excluded and forms a hole.
2657##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002658void draw(SkCanvas* canvas) {
2659 SkPaint paint;
2660 paint.setAntiAlias(true);
2661 SkPath path;
2662 path.addRect({20, 15, 100, 95});
2663 path.addRect({50, 65, 130, 135});
2664 path.setFillType(SkPath::kWinding_FillType);
2665 canvas->save();
2666 canvas->clipPath(path, SkClipOp::kIntersect);
2667 canvas->drawCircle(70, 85, 60, paint);
2668 canvas->restore();
2669 canvas->translate(100, 100);
2670 path.setFillType(SkPath::kEvenOdd_FillType);
2671 canvas->clipPath(path, SkClipOp::kIntersect);
2672 canvas->drawCircle(70, 85, 60, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002673}
2674##
2675
Cary Clark2ade9972017-11-02 17:49:34 -04002676#SeeAlso clipRect clipRRect clipRegion
Cary Clark8032b982017-07-28 11:04:54 -04002677
2678##
2679
Herb Derbyefe39bc2018-05-01 17:06:20 -04002680#Method void clipPath(const SkPath& path, bool doAntiAlias = false)
Cary Clark8032b982017-07-28 11:04:54 -04002681
Cary Clarkab2621d2018-01-30 10:08:57 -05002682#In Clip
Cary Clark8032b982017-07-28 11:04:54 -04002683Replace Clip with the intersection of Clip and path.
Cary Clarkce101242017-09-01 15:51:02 -04002684Resulting Clip is Aliased; pixels are fully contained by the clip.
Cary Clark8032b982017-07-28 11:04:54 -04002685Path_Fill_Type determines if path
2686describes the area inside or outside its contours; and if Path_Contour overlaps
2687itself or another Path_Contour, whether the overlaps form part of the area.
Cary Clarkbad5ad72017-08-03 17:14:08 -04002688path is transformed by Matrix before it is combined with Clip.
Cary Clark8032b982017-07-28 11:04:54 -04002689
Cary Clarkbad5ad72017-08-03 17:14:08 -04002690#Param path Path to combine with Clip ##
Cary Clarkffb3d682018-05-17 12:17:28 -04002691#Param doAntiAlias true if Clip is to be Anti_Aliased ##
Cary Clark8032b982017-07-28 11:04:54 -04002692
2693#Example
2694#Height 212
2695#Description
Herb Derbyefe39bc2018-05-01 17:06:20 -04002696Clip loops over itself covering its center twice. When clip Path_Fill_Type
2697is set to SkPath::kWinding_FillType, the overlap is included. Set to
Cary Clark8032b982017-07-28 11:04:54 -04002698SkPath::kEvenOdd_FillType, the overlap is excluded and forms a hole.
2699##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002700void draw(SkCanvas* canvas) {
2701 SkPaint paint;
2702 paint.setAntiAlias(true);
2703 SkPath path;
2704 SkPoint poly[] = {{20, 20}, { 80, 20}, { 80, 80}, {40, 80},
2705 {40, 40}, {100, 40}, {100, 100}, {20, 100}};
2706 path.addPoly(poly, SK_ARRAY_COUNT(poly), true);
2707 path.setFillType(SkPath::kWinding_FillType);
2708 canvas->save();
2709 canvas->clipPath(path, SkClipOp::kIntersect);
2710 canvas->drawCircle(50, 50, 45, paint);
2711 canvas->restore();
2712 canvas->translate(100, 100);
2713 path.setFillType(SkPath::kEvenOdd_FillType);
2714 canvas->clipPath(path, SkClipOp::kIntersect);
2715 canvas->drawCircle(50, 50, 45, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002716}
2717##
2718
Cary Clark2ade9972017-11-02 17:49:34 -04002719#SeeAlso clipRect clipRRect clipRegion
Cary Clark8032b982017-07-28 11:04:54 -04002720
2721##
2722
2723# ------------------------------------------------------------------------------
2724
Herb Derbyefe39bc2018-05-01 17:06:20 -04002725#Method void setAllowSimplifyClip(bool allow)
Cary Clark8032b982017-07-28 11:04:54 -04002726
Cary Clarkab2621d2018-01-30 10:08:57 -05002727#In Clip
Cary Clark682c58d2018-05-16 07:07:07 -04002728#Experimental testing
Cary Clark8032b982017-07-28 11:04:54 -04002729
Cary Clarkce101242017-09-01 15:51:02 -04002730Set to simplify clip stack using PathOps.
Cary Clark8032b982017-07-28 11:04:54 -04002731
2732##
2733
2734# ------------------------------------------------------------------------------
2735
2736#Method void clipRegion(const SkRegion& deviceRgn, SkClipOp op = SkClipOp::kIntersect)
2737
Cary Clarkab2621d2018-01-30 10:08:57 -05002738#In Clip
2739#Line # combines Clip with Region ##
Cary Clark8032b982017-07-28 11:04:54 -04002740Replace Clip with the intersection or difference of Clip and Region deviceRgn.
Cary Clarkce101242017-09-01 15:51:02 -04002741Resulting Clip is Aliased; pixels are fully contained by the clip.
Cary Clark8032b982017-07-28 11:04:54 -04002742deviceRgn is unaffected by Matrix.
2743
Cary Clarkbad5ad72017-08-03 17:14:08 -04002744#Param deviceRgn Region to combine with Clip ##
2745#Param op Clip_Op to apply to Clip ##
Cary Clark8032b982017-07-28 11:04:54 -04002746
2747#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04002748#Description
Cary Clarkce101242017-09-01 15:51:02 -04002749 region is unaffected by canvas rotation; iRect is affected by canvas rotation.
2750 Both clips are Aliased; this is not noticeable on Region clip because it
Cary Clarkbad5ad72017-08-03 17:14:08 -04002751 aligns to pixel boundaries.
2752##
2753void draw(SkCanvas* canvas) {
2754 SkPaint paint;
2755 paint.setAntiAlias(true);
2756 SkIRect iRect = {30, 40, 120, 130 };
2757 SkRegion region(iRect);
2758 canvas->rotate(10);
2759 canvas->save();
2760 canvas->clipRegion(region, SkClipOp::kIntersect);
2761 canvas->drawCircle(50, 50, 45, paint);
2762 canvas->restore();
2763 canvas->translate(100, 100);
2764 canvas->clipRect(SkRect::Make(iRect), SkClipOp::kIntersect);
2765 canvas->drawCircle(50, 50, 45, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002766}
2767##
2768
Cary Clark2ade9972017-11-02 17:49:34 -04002769#SeeAlso clipRect clipRRect clipPath
Cary Clark8032b982017-07-28 11:04:54 -04002770
2771##
2772
2773#Method bool quickReject(const SkRect& rect) const
2774
Cary Clarkab2621d2018-01-30 10:08:57 -05002775#In Clip
2776#Line # returns if Rect is outside Clip ##
Cary Clark8032b982017-07-28 11:04:54 -04002777Return true if Rect rect, transformed by Matrix, can be quickly determined to be
2778outside of Clip. May return false even though rect is outside of Clip.
2779
2780Use to check if an area to be drawn is clipped out, to skip subsequent draw calls.
2781
Cary Clarkbad5ad72017-08-03 17:14:08 -04002782#Param rect Rect to compare with Clip ##
Cary Clark8032b982017-07-28 11:04:54 -04002783
Cary Clarkbad5ad72017-08-03 17:14:08 -04002784#Return true if rect, transformed by Matrix, does not intersect Clip ##
Cary Clark8032b982017-07-28 11:04:54 -04002785
2786#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04002787void draw(SkCanvas* canvas) {
Herb Derbyefe39bc2018-05-01 17:06:20 -04002788 SkRect testRect = {30, 30, 120, 129 };
2789 SkRect clipRect = {30, 130, 120, 230 };
Cary Clarkbad5ad72017-08-03 17:14:08 -04002790 canvas->save();
2791 canvas->clipRect(clipRect);
2792 SkDebugf("quickReject %s\n", canvas->quickReject(testRect) ? "true" : "false");
2793 canvas->restore();
2794 canvas->rotate(10);
2795 canvas->clipRect(clipRect);
2796 SkDebugf("quickReject %s\n", canvas->quickReject(testRect) ? "true" : "false");
Cary Clark8032b982017-07-28 11:04:54 -04002797}
2798 #StdOut
Cary Clarkbad5ad72017-08-03 17:14:08 -04002799 quickReject true
Cary Clark8032b982017-07-28 11:04:54 -04002800 quickReject false
2801 ##
2802##
2803
Cary Clark2ade9972017-11-02 17:49:34 -04002804#SeeAlso getLocalClipBounds getTotalMatrix SkBitmap::drawsNothing
Cary Clark8032b982017-07-28 11:04:54 -04002805
2806##
2807
2808#Method bool quickReject(const SkPath& path) const
2809
Cary Clarkab2621d2018-01-30 10:08:57 -05002810#In Clip
Cary Clark8032b982017-07-28 11:04:54 -04002811Return true if path, transformed by Matrix, can be quickly determined to be
2812outside of Clip. May return false even though path is outside of Clip.
2813
2814Use to check if an area to be drawn is clipped out, to skip subsequent draw calls.
2815
Cary Clarkbad5ad72017-08-03 17:14:08 -04002816#Param path Path to compare with Clip ##
Cary Clark8032b982017-07-28 11:04:54 -04002817
Cary Clarkbad5ad72017-08-03 17:14:08 -04002818#Return true if path, transformed by Matrix, does not intersect Clip ##
Cary Clark8032b982017-07-28 11:04:54 -04002819
2820#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04002821void draw(SkCanvas* canvas) {
Herb Derbyefe39bc2018-05-01 17:06:20 -04002822 SkPoint testPoints[] = {{30, 30}, {120, 30}, {120, 129} };
2823 SkPoint clipPoints[] = {{30, 130}, {120, 130}, {120, 230} };
Cary Clarkbad5ad72017-08-03 17:14:08 -04002824 SkPath testPath, clipPath;
2825 testPath.addPoly(testPoints, SK_ARRAY_COUNT(testPoints), true);
2826 clipPath.addPoly(clipPoints, SK_ARRAY_COUNT(clipPoints), true);
2827 canvas->save();
2828 canvas->clipPath(clipPath);
2829 SkDebugf("quickReject %s\n", canvas->quickReject(testPath) ? "true" : "false");
2830 canvas->restore();
2831 canvas->rotate(10);
2832 canvas->clipPath(clipPath);
2833 SkDebugf("quickReject %s\n", canvas->quickReject(testPath) ? "true" : "false");
Cary Clark8032b982017-07-28 11:04:54 -04002834 #StdOut
Cary Clarkbad5ad72017-08-03 17:14:08 -04002835 quickReject true
Cary Clark8032b982017-07-28 11:04:54 -04002836 quickReject false
2837 ##
2838}
2839##
2840
Cary Clark2ade9972017-11-02 17:49:34 -04002841#SeeAlso getLocalClipBounds getTotalMatrix SkBitmap::drawsNothing
Cary Clark8032b982017-07-28 11:04:54 -04002842
2843##
2844
Herb Derbyefe39bc2018-05-01 17:06:20 -04002845#Method SkRect getLocalClipBounds() const
Cary Clark8032b982017-07-28 11:04:54 -04002846
Cary Clarkab2621d2018-01-30 10:08:57 -05002847#In Clip
2848#Line # returns Clip bounds in source coordinates ##
Cary Clark8032b982017-07-28 11:04:54 -04002849Return bounds of Clip, transformed by inverse of Matrix. If Clip is empty,
2850return SkRect::MakeEmpty, where all Rect sides equal zero.
2851
2852Rect returned is outset by one to account for partial pixel coverage if Clip
Cary Clarkffb3d682018-05-17 12:17:28 -04002853is Anti_Aliased.
Cary Clark8032b982017-07-28 11:04:54 -04002854
Cary Clarkbad5ad72017-08-03 17:14:08 -04002855#Return bounds of Clip in local coordinates ##
Cary Clark8032b982017-07-28 11:04:54 -04002856
2857#Example
Herb Derbyefe39bc2018-05-01 17:06:20 -04002858 #Description
Cary Clark8032b982017-07-28 11:04:54 -04002859 Initial bounds is device bounds outset by 1 on all sides.
2860 Clipped bounds is clipPath bounds outset by 1 on all sides.
2861 Scaling the canvas by two in x and y scales the local bounds by 1/2 in x and y.
2862 ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002863 SkCanvas local(256, 256);
2864 canvas = &local;
2865 SkRect bounds = canvas->getLocalClipBounds();
2866 SkDebugf("left:%g top:%g right:%g bottom:%g\n",
2867 bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom);
Herb Derbyefe39bc2018-05-01 17:06:20 -04002868 SkPoint clipPoints[] = {{30, 130}, {120, 130}, {120, 230} };
Cary Clarkbad5ad72017-08-03 17:14:08 -04002869 SkPath clipPath;
2870 clipPath.addPoly(clipPoints, SK_ARRAY_COUNT(clipPoints), true);
2871 canvas->clipPath(clipPath);
2872 bounds = canvas->getLocalClipBounds();
2873 SkDebugf("left:%g top:%g right:%g bottom:%g\n",
2874 bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom);
2875 canvas->scale(2, 2);
2876 bounds = canvas->getLocalClipBounds();
2877 SkDebugf("left:%g top:%g right:%g bottom:%g\n",
2878 bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom);
2879 #StdOut
2880 left:-1 top:-1 right:257 bottom:257
2881 left:29 top:129 right:121 bottom:231
2882 left:14.5 top:64.5 right:60.5 bottom:115.5
2883 ##
Cary Clark8032b982017-07-28 11:04:54 -04002884##
2885
2886# local canvas in example works around bug in fiddle ##
Cary Clark4855f782018-02-06 09:41:53 -05002887#Bug 6524
Cary Clark2ade9972017-11-02 17:49:34 -04002888#SeeAlso getDeviceClipBounds getBaseLayerSize quickReject
Cary Clark8032b982017-07-28 11:04:54 -04002889
2890##
2891
Herb Derbyefe39bc2018-05-01 17:06:20 -04002892#Method bool getLocalClipBounds(SkRect* bounds) const
Cary Clark8032b982017-07-28 11:04:54 -04002893
Cary Clarkab2621d2018-01-30 10:08:57 -05002894#In Clip
Cary Clark8032b982017-07-28 11:04:54 -04002895Return bounds of Clip, transformed by inverse of Matrix. If Clip is empty,
2896return false, and set bounds to SkRect::MakeEmpty, where all Rect sides equal zero.
2897
2898bounds is outset by one to account for partial pixel coverage if Clip
Cary Clarkffb3d682018-05-17 12:17:28 -04002899is Anti_Aliased.
Cary Clark8032b982017-07-28 11:04:54 -04002900
Cary Clarkbad5ad72017-08-03 17:14:08 -04002901#Param bounds Rect of Clip in local coordinates ##
Cary Clark8032b982017-07-28 11:04:54 -04002902
Cary Clarkbad5ad72017-08-03 17:14:08 -04002903#Return true if Clip bounds is not empty ##
Cary Clark8032b982017-07-28 11:04:54 -04002904
2905#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04002906 void draw(SkCanvas* canvas) {
2907 SkCanvas local(256, 256);
2908 canvas = &local;
2909 SkRect bounds;
2910 SkDebugf("local bounds empty = %s\n", canvas->getLocalClipBounds(&bounds)
2911 ? "false" : "true");
2912 SkPath path;
2913 canvas->clipPath(path);
2914 SkDebugf("local bounds empty = %s\n", canvas->getLocalClipBounds(&bounds)
2915 ? "false" : "true");
Cary Clark8032b982017-07-28 11:04:54 -04002916 }
2917 #StdOut
Cary Clarkbad5ad72017-08-03 17:14:08 -04002918 local bounds empty = false
Cary Clark8032b982017-07-28 11:04:54 -04002919 local bounds empty = true
2920 ##
2921##
2922
2923# local canvas in example works around bug in fiddle ##
Cary Clark4855f782018-02-06 09:41:53 -05002924#Bug 6524
Cary Clark2ade9972017-11-02 17:49:34 -04002925#SeeAlso getDeviceClipBounds getBaseLayerSize quickReject
Cary Clark8032b982017-07-28 11:04:54 -04002926
2927##
2928
Herb Derbyefe39bc2018-05-01 17:06:20 -04002929#Method SkIRect getDeviceClipBounds() const
Cary Clark8032b982017-07-28 11:04:54 -04002930
Cary Clarkab2621d2018-01-30 10:08:57 -05002931#In Clip
2932#Line # returns IRect bounds of Clip ##
Cary Clark8032b982017-07-28 11:04:54 -04002933Return IRect bounds of Clip, unaffected by Matrix. If Clip is empty,
2934return SkRect::MakeEmpty, where all Rect sides equal zero.
2935
Herb Derbyefe39bc2018-05-01 17:06:20 -04002936Unlike getLocalClipBounds, returned IRect is not outset.
Cary Clark8032b982017-07-28 11:04:54 -04002937
Cary Clarkbad5ad72017-08-03 17:14:08 -04002938#Return bounds of Clip in Device coordinates ##
Cary Clark8032b982017-07-28 11:04:54 -04002939
2940#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04002941void draw(SkCanvas* canvas) {
2942 #Description
Cary Clark8032b982017-07-28 11:04:54 -04002943 Initial bounds is device bounds, not outset.
2944 Clipped bounds is clipPath bounds, not outset.
2945 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 -04002946 ##
2947 SkCanvas device(256, 256);
2948 canvas = &device;
2949 SkIRect bounds = canvas->getDeviceClipBounds();
2950 SkDebugf("left:%d top:%d right:%d bottom:%d\n",
2951 bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom);
Herb Derbyefe39bc2018-05-01 17:06:20 -04002952 SkPoint clipPoints[] = {{30, 130}, {120, 130}, {120, 230} };
Cary Clarkbad5ad72017-08-03 17:14:08 -04002953 SkPath clipPath;
2954 clipPath.addPoly(clipPoints, SK_ARRAY_COUNT(clipPoints), true);
2955 canvas->save();
2956 canvas->clipPath(clipPath);
2957 bounds = canvas->getDeviceClipBounds();
2958 SkDebugf("left:%d top:%d right:%d bottom:%d\n",
2959 bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom);
2960 canvas->restore();
2961 canvas->scale(1.f/2, 1.f/2);
2962 canvas->clipPath(clipPath);
2963 bounds = canvas->getDeviceClipBounds();
2964 SkDebugf("left:%d top:%d right:%d bottom:%d\n",
2965 bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom);
Cary Clark8032b982017-07-28 11:04:54 -04002966 #StdOut
Cary Clarkbad5ad72017-08-03 17:14:08 -04002967 left:0 top:0 right:256 bottom:256
2968 left:30 top:130 right:120 bottom:230
Cary Clark8032b982017-07-28 11:04:54 -04002969 left:15 top:65 right:60 bottom:115
2970 ##
2971}
2972##
2973
2974#ToDo some confusion on why with an identity Matrix local and device are different ##
Cary Clark2ade9972017-11-02 17:49:34 -04002975#SeeAlso getLocalClipBounds getBaseLayerSize quickReject
Cary Clark8032b982017-07-28 11:04:54 -04002976
2977# device canvas in example works around bug in fiddle ##
Cary Clark4855f782018-02-06 09:41:53 -05002978#Bug 6524
Cary Clark8032b982017-07-28 11:04:54 -04002979
2980##
2981
Herb Derbyefe39bc2018-05-01 17:06:20 -04002982#Method bool getDeviceClipBounds(SkIRect* bounds) const
Cary Clark8032b982017-07-28 11:04:54 -04002983
Cary Clarkab2621d2018-01-30 10:08:57 -05002984#In Clip
Cary Clark8032b982017-07-28 11:04:54 -04002985Return IRect bounds of Clip, unaffected by Matrix. If Clip is empty,
2986return false, and set bounds to SkRect::MakeEmpty, where all Rect sides equal zero.
2987
Herb Derbyefe39bc2018-05-01 17:06:20 -04002988Unlike getLocalClipBounds, bounds is not outset.
Cary Clark8032b982017-07-28 11:04:54 -04002989
Cary Clarkbad5ad72017-08-03 17:14:08 -04002990#Param bounds Rect of Clip in device coordinates ##
Cary Clark8032b982017-07-28 11:04:54 -04002991
Cary Clarkbad5ad72017-08-03 17:14:08 -04002992#Return true if Clip bounds is not empty ##
Cary Clark8032b982017-07-28 11:04:54 -04002993
2994#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04002995 void draw(SkCanvas* canvas) {
2996 SkIRect bounds;
2997 SkDebugf("device bounds empty = %s\n", canvas->getDeviceClipBounds(&bounds)
2998 ? "false" : "true");
2999 SkPath path;
3000 canvas->clipPath(path);
3001 SkDebugf("device bounds empty = %s\n", canvas->getDeviceClipBounds(&bounds)
3002 ? "false" : "true");
Cary Clark8032b982017-07-28 11:04:54 -04003003 }
3004 #StdOut
Cary Clarkbad5ad72017-08-03 17:14:08 -04003005 device bounds empty = false
Cary Clark8032b982017-07-28 11:04:54 -04003006 device bounds empty = true
3007 ##
3008##
3009
Cary Clark2ade9972017-11-02 17:49:34 -04003010#SeeAlso getLocalClipBounds getBaseLayerSize quickReject
Cary Clark8032b982017-07-28 11:04:54 -04003011
3012##
3013
Cary Clark08895c42018-02-01 09:37:32 -05003014#Subtopic Clip ##
Cary Clark8032b982017-07-28 11:04:54 -04003015
3016# ------------------------------------------------------------------------------
Cary Clark78de7512018-02-07 07:27:09 -05003017#Subtopic Draw
3018#Populate
3019#Line # draws into Canvas ##
3020##
Cary Clark8032b982017-07-28 11:04:54 -04003021
3022#Method void drawColor(SkColor color, SkBlendMode mode = SkBlendMode::kSrcOver)
Cary Clark78de7512018-02-07 07:27:09 -05003023#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05003024#Line # fills Clip with Color and Blend_Mode ##
Cary Clark8032b982017-07-28 11:04:54 -04003025Fill Clip with Color color.
Cary Clarkffb3d682018-05-17 12:17:28 -04003026mode determines how ARGB is combined with destination.
Cary Clark8032b982017-07-28 11:04:54 -04003027
Cary Clarkffb3d682018-05-17 12:17:28 -04003028#Param color Unpremultiplied ARGB ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003029#Param mode SkBlendMode used to combine source color and destination ##
Cary Clark8032b982017-07-28 11:04:54 -04003030
3031#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003032 canvas->drawColor(SK_ColorRED);
3033 canvas->clipRect(SkRect::MakeWH(150, 150));
3034 canvas->drawColor(SkColorSetARGB(0x80, 0x00, 0xFF, 0x00), SkBlendMode::kPlus);
3035 canvas->clipRect(SkRect::MakeWH(75, 75));
3036 canvas->drawColor(SkColorSetARGB(0x80, 0x00, 0x00, 0xFF), SkBlendMode::kPlus);
Cary Clark8032b982017-07-28 11:04:54 -04003037##
3038
Cary Clark2ade9972017-11-02 17:49:34 -04003039#SeeAlso clear SkBitmap::erase drawPaint
Cary Clark8032b982017-07-28 11:04:54 -04003040
3041##
3042
3043# ------------------------------------------------------------------------------
3044
Herb Derbyefe39bc2018-05-01 17:06:20 -04003045#Method void clear(SkColor color)
Cary Clark78de7512018-02-07 07:27:09 -05003046#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05003047#Line # fills Clip with Color ##
Herb Derbyefe39bc2018-05-01 17:06:20 -04003048Fill Clip with Color color using SkBlendMode::kSrc.
Cary Clark8032b982017-07-28 11:04:54 -04003049This has the effect of replacing all pixels contained by Clip with color.
3050
Cary Clarkffb3d682018-05-17 12:17:28 -04003051#Param color Unpremultiplied ARGB ##
Cary Clark8032b982017-07-28 11:04:54 -04003052
3053#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003054void draw(SkCanvas* canvas) {
3055 canvas->save();
3056 canvas->clipRect(SkRect::MakeWH(256, 128));
Herb Derbyefe39bc2018-05-01 17:06:20 -04003057 canvas->clear(SkColorSetARGB(0x80, 0xFF, 0x00, 0x00));
Cary Clarkbad5ad72017-08-03 17:14:08 -04003058 canvas->restore();
3059 canvas->save();
3060 canvas->clipRect(SkRect::MakeWH(150, 192));
3061 canvas->clear(SkColorSetARGB(0x80, 0x00, 0xFF, 0x00));
3062 canvas->restore();
3063 canvas->clipRect(SkRect::MakeWH(75, 256));
3064 canvas->clear(SkColorSetARGB(0x80, 0x00, 0x00, 0xFF));
Cary Clark8032b982017-07-28 11:04:54 -04003065}
3066##
3067
Cary Clark2ade9972017-11-02 17:49:34 -04003068#SeeAlso drawColor SkBitmap::erase drawPaint
Cary Clark8032b982017-07-28 11:04:54 -04003069
3070##
3071
3072# ------------------------------------------------------------------------------
3073
Herb Derbyefe39bc2018-05-01 17:06:20 -04003074#Method void discard()
Cary Clark78de7512018-02-07 07:27:09 -05003075#In Utility
Cary Clarkab2621d2018-01-30 10:08:57 -05003076#Line # makes Canvas contents undefined ##
Cary Clark8032b982017-07-28 11:04:54 -04003077Make Canvas contents undefined. Subsequent calls that read Canvas pixels,
3078such as drawing with SkBlendMode, return undefined results. discard() does
3079not change Clip or Matrix.
3080
3081discard() may do nothing, depending on the implementation of Surface or Device
3082that created Canvas.
3083
3084discard() allows optimized performance on subsequent draws by removing
3085cached data associated with Surface or Device.
3086It is not necessary to call discard() once done with Canvas;
3087any cached data is deleted when owning Surface or Device is deleted.
3088
3089#ToDo example? not sure how to make this meaningful w/o more implementation detail ##
Cary Clark2ade9972017-11-02 17:49:34 -04003090#SeeAlso flush() SkSurface::prepareForExternalIO GrContext::abandonContext
Cary Clark8032b982017-07-28 11:04:54 -04003091
Herb Derbyefe39bc2018-05-01 17:06:20 -04003092#NoExample
Cary Clark8032b982017-07-28 11:04:54 -04003093##
3094
3095##
3096
3097# ------------------------------------------------------------------------------
3098
3099#Method void drawPaint(const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05003100#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05003101#Line # fills Clip with Paint ##
Mike Reed8ad91a92018-01-19 19:09:32 -05003102Fill Clip with Paint paint. Paint components Mask_Filter, Shader,
Cary Clarkbad5ad72017-08-03 17:14:08 -04003103Color_Filter, Image_Filter, and Blend_Mode affect drawing;
3104Path_Effect in paint is ignored.
Cary Clark8032b982017-07-28 11:04:54 -04003105
3106# can Path_Effect in paint ever alter drawPaint?
3107
Cary Clarkbad5ad72017-08-03 17:14:08 -04003108#Param paint graphics state used to fill Canvas ##
Cary Clark8032b982017-07-28 11:04:54 -04003109
3110#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003111void draw(SkCanvas* canvas) {
3112 SkColor colors[] = { SK_ColorRED, SK_ColorGREEN, SK_ColorBLUE };
3113 SkScalar pos[] = { 0, SK_Scalar1/2, SK_Scalar1 };
3114 SkPaint paint;
3115 paint.setShader(SkGradientShader::MakeSweep(256, 256, colors, pos, SK_ARRAY_COUNT(colors)));
3116 canvas->drawPaint(paint);
Cary Clark8032b982017-07-28 11:04:54 -04003117}
3118##
3119
Cary Clark2ade9972017-11-02 17:49:34 -04003120#SeeAlso clear drawColor SkBitmap::erase
Cary Clark8032b982017-07-28 11:04:54 -04003121
3122##
3123
3124# ------------------------------------------------------------------------------
3125
3126#Enum PointMode
Cary Clark08895c42018-02-01 09:37:32 -05003127#Line # sets drawPoints options ##
Cary Clark8032b982017-07-28 11:04:54 -04003128
3129#Code
3130 enum PointMode {
3131 kPoints_PointMode,
3132 kLines_PointMode,
Cary Clarkd0530ba2017-09-14 11:25:39 -04003133 kPolygon_PointMode,
Cary Clark8032b982017-07-28 11:04:54 -04003134 };
3135##
3136
3137Selects if an array of points are drawn as discrete points, as lines, or as
3138an open polygon.
3139
3140#Const kPoints_PointMode 0
Cary Clark682c58d2018-05-16 07:07:07 -04003141#Line # draw each point separately ##
Cary Clark8032b982017-07-28 11:04:54 -04003142##
3143
3144#Const kLines_PointMode 1
Cary Clark682c58d2018-05-16 07:07:07 -04003145#Line # draw each pair of points as a line segment ##
Cary Clark8032b982017-07-28 11:04:54 -04003146##
3147
3148#Const kPolygon_PointMode 2
Cary Clark682c58d2018-05-16 07:07:07 -04003149#Line # draw the array of points as a open polygon ##
Cary Clark8032b982017-07-28 11:04:54 -04003150##
3151
3152#Example
Herb Derbyefe39bc2018-05-01 17:06:20 -04003153 #Description
Cary Clark8032b982017-07-28 11:04:54 -04003154 The upper left corner shows three squares when drawn as points.
3155 The upper right corner shows one line; when drawn as lines, two points are required per line.
3156 The lower right corner shows two lines; when draw as polygon, no miter is drawn at the corner.
3157 The lower left corner shows two lines with a miter when path contains polygon.
3158 ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003159void draw(SkCanvas* canvas) {
3160 SkPaint paint;
3161 paint.setStyle(SkPaint::kStroke_Style);
3162 paint.setStrokeWidth(10);
3163 SkPoint points[] = {{64, 32}, {96, 96}, {32, 96}};
3164 canvas->drawPoints(SkCanvas::kPoints_PointMode, 3, points, paint);
3165 canvas->translate(128, 0);
3166 canvas->drawPoints(SkCanvas::kLines_PointMode, 3, points, paint);
3167 canvas->translate(0, 128);
3168 canvas->drawPoints(SkCanvas::kPolygon_PointMode, 3, points, paint);
3169 SkPath path;
3170 path.addPoly(points, 3, false);
3171 canvas->translate(-128, 0);
3172 canvas->drawPath(path, paint);
Cary Clark8032b982017-07-28 11:04:54 -04003173}
3174##
3175
Cary Clark2ade9972017-11-02 17:49:34 -04003176#SeeAlso drawLine drawPoint drawPath
Cary Clark8032b982017-07-28 11:04:54 -04003177
3178##
3179
3180# ------------------------------------------------------------------------------
3181
3182#Method void drawPoints(PointMode mode, size_t count, const SkPoint pts[], const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05003183#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05003184#Line # draws array as points, lines, polygon ##
Cary Clark8032b982017-07-28 11:04:54 -04003185Draw 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,
Herb Derbyefe39bc2018-05-01 17:06:20 -04003197the final point is ignored.
Cary Clark8032b982017-07-28 11:04:54 -04003198
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
Herb Derbyefe39bc2018-05-01 17:06:20 -04003207and 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
Herb Derbyefe39bc2018-05-01 17:06:20 -04003216 #Description
Cary Clark8032b982017-07-28 11:04:54 -04003217 #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}};
Herb Derbyefe39bc2018-05-01 17:06:20 -04003236 const SkPaint::Join join[] = { SkPaint::kRound_Join,
Cary Clarkbad5ad72017-08-03 17:14:08 -04003237 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)
Cary Clark78de7512018-02-07 07:27:09 -05003264#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05003265#Line # draws point at (x, y) position ##
Cary Clark8032b982017-07-28 11:04:54 -04003266Draw point at (x, y) using Clip, Matrix and Paint paint.
3267
3268The shape of point drawn depends on paint Paint_Stroke_Cap.
Cary Clarkbad5ad72017-08-03 17:14:08 -04003269If paint is set to SkPaint::kRound_Cap, draw a circle of diameter
Herb Derbyefe39bc2018-05-01 17:06:20 -04003270Paint_Stroke_Width. If paint is set to SkPaint::kSquare_Cap or SkPaint::kButt_Cap,
Cary Clark8032b982017-07-28 11:04:54 -04003271draw a square of width and height Paint_Stroke_Width.
3272Paint_Style is ignored, as if were set to SkPaint::kStroke_Style.
3273
Cary Clarkbad5ad72017-08-03 17:14:08 -04003274#Param x left edge of circle or square ##
3275#Param y top edge of circle or square ##
3276#Param paint stroke, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003277
3278#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003279void draw(SkCanvas* canvas) {
3280 SkPaint paint;
3281 paint.setAntiAlias(true);
3282 paint.setColor(0x80349a45);
3283 paint.setStyle(SkPaint::kStroke_Style);
3284 paint.setStrokeWidth(100);
3285 paint.setStrokeCap(SkPaint::kRound_Cap);
3286 canvas->scale(1, 1.2f);
3287 canvas->drawPoint(64, 96, paint);
3288 canvas->scale(.6f, .8f);
3289 paint.setColor(SK_ColorWHITE);
3290 canvas->drawPoint(106, 120, paint);
Cary Clark8032b982017-07-28 11:04:54 -04003291}
3292##
3293
Cary Clark2ade9972017-11-02 17:49:34 -04003294#SeeAlso drawPoints drawCircle drawRect drawLine drawPath
Cary Clark8032b982017-07-28 11:04:54 -04003295
3296##
3297
Cary Clarkbad5ad72017-08-03 17:14:08 -04003298#Method void drawPoint(SkPoint p, const SkPaint& paint)
3299
3300Draw point p using Clip, Matrix and Paint paint.
3301
3302The shape of point drawn depends on paint Paint_Stroke_Cap.
3303If paint is set to SkPaint::kRound_Cap, draw a circle of diameter
Herb Derbyefe39bc2018-05-01 17:06:20 -04003304Paint_Stroke_Width. If paint is set to SkPaint::kSquare_Cap or SkPaint::kButt_Cap,
Cary Clarkbad5ad72017-08-03 17:14:08 -04003305draw a square of width and height Paint_Stroke_Width.
3306Paint_Style is ignored, as if were set to SkPaint::kStroke_Style.
3307
3308#Param p top-left edge of circle or square ##
3309#Param paint stroke, blend, color, and so on, used to draw ##
3310
3311#Example
3312void draw(SkCanvas* canvas) {
3313 SkPaint paint;
3314 paint.setAntiAlias(true);
3315 paint.setColor(0x80349a45);
3316 paint.setStyle(SkPaint::kStroke_Style);
3317 paint.setStrokeWidth(100);
3318 paint.setStrokeCap(SkPaint::kSquare_Cap);
3319 canvas->scale(1, 1.2f);
3320 canvas->drawPoint({64, 96}, paint);
3321 canvas->scale(.6f, .8f);
3322 paint.setColor(SK_ColorWHITE);
3323 canvas->drawPoint(106, 120, paint);
3324}
3325##
3326
Cary Clark2ade9972017-11-02 17:49:34 -04003327#SeeAlso drawPoints drawCircle drawRect drawLine drawPath
Cary Clarkbad5ad72017-08-03 17:14:08 -04003328
3329##
3330
Cary Clark8032b982017-07-28 11:04:54 -04003331# ------------------------------------------------------------------------------
3332
3333#Method void drawLine(SkScalar x0, SkScalar y0, SkScalar x1, SkScalar y1, const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05003334#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05003335#Line # draws line segment between two points ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003336Draws line segment from (x0, y0) to (x1, y1) using Clip, Matrix, and Paint paint.
3337In paint: Paint_Stroke_Width describes the line thickness;
3338Paint_Stroke_Cap draws the end rounded or square;
Cary Clark8032b982017-07-28 11:04:54 -04003339Paint_Style is ignored, as if were set to SkPaint::kStroke_Style.
3340
Cary Clarkbad5ad72017-08-03 17:14:08 -04003341#Param x0 start of line segment on x-axis ##
3342#Param y0 start of line segment on y-axis ##
3343#Param x1 end of line segment on x-axis ##
3344#Param y1 end of line segment on y-axis ##
3345#Param paint stroke, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003346
3347#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003348 SkPaint paint;
3349 paint.setAntiAlias(true);
3350 paint.setColor(0xFF9a67be);
3351 paint.setStrokeWidth(20);
3352 canvas->skew(1, 0);
3353 canvas->drawLine(32, 96, 32, 160, paint);
3354 canvas->skew(-2, 0);
3355 canvas->drawLine(288, 96, 288, 160, paint);
3356##
3357
Cary Clark2ade9972017-11-02 17:49:34 -04003358#SeeAlso drawPoint drawCircle drawRect drawPath
Cary Clarkbad5ad72017-08-03 17:14:08 -04003359
3360##
3361
3362#Method void drawLine(SkPoint p0, SkPoint p1, const SkPaint& paint)
3363
3364Draws line segment from p0 to p1 using Clip, Matrix, and Paint paint.
3365In paint: Paint_Stroke_Width describes the line thickness;
3366Paint_Stroke_Cap draws the end rounded or square;
3367Paint_Style is ignored, as if were set to SkPaint::kStroke_Style.
3368
3369#Param p0 start of line segment ##
3370#Param p1 end of line segment ##
3371#Param paint stroke, blend, color, and so on, used to draw ##
3372
3373#Example
3374 SkPaint paint;
3375 paint.setAntiAlias(true);
3376 paint.setColor(0xFF9a67be);
3377 paint.setStrokeWidth(20);
3378 canvas->skew(1, 0);
3379 canvas->drawLine({32, 96}, {32, 160}, paint);
3380 canvas->skew(-2, 0);
3381 canvas->drawLine({288, 96}, {288, 160}, paint);
Cary Clark8032b982017-07-28 11:04:54 -04003382##
3383
Cary Clark2ade9972017-11-02 17:49:34 -04003384#SeeAlso drawPoint drawCircle drawRect drawPath
Cary Clark8032b982017-07-28 11:04:54 -04003385
3386##
3387
3388# ------------------------------------------------------------------------------
3389
3390#Method void drawRect(const SkRect& rect, const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05003391#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05003392#Line # draws Rect using Clip, Matrix, and Paint ##
Cary Clark8032b982017-07-28 11:04:54 -04003393Draw Rect rect using Clip, Matrix, and Paint paint.
Herb Derbyefe39bc2018-05-01 17:06:20 -04003394In paint: Paint_Style determines if rectangle is stroked or filled;
Cary Clark8032b982017-07-28 11:04:54 -04003395if stroked, Paint_Stroke_Width describes the line thickness, and
3396Paint_Stroke_Join draws the corners rounded or square.
3397
Cary Clarkbc5697d2017-10-04 14:31:33 -04003398#Param rect rectangle to draw ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003399#Param paint stroke or fill, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003400
3401#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003402void draw(SkCanvas* canvas) {
3403 SkPoint rectPts[] = { {64, 48}, {192, 160} };
3404 SkPaint paint;
3405 paint.setAntiAlias(true);
3406 paint.setStyle(SkPaint::kStroke_Style);
3407 paint.setStrokeWidth(20);
3408 paint.setStrokeJoin(SkPaint::kRound_Join);
3409 SkMatrix rotator;
3410 rotator.setRotate(30, 128, 128);
3411 for (auto color : { SK_ColorRED, SK_ColorBLUE, SK_ColorYELLOW, SK_ColorMAGENTA } ) {
3412 paint.setColor(color);
3413 SkRect rect;
3414 rect.set(rectPts[0], rectPts[1]);
3415 canvas->drawRect(rect, paint);
3416 rotator.mapPoints(rectPts, 2);
3417 }
Cary Clark8032b982017-07-28 11:04:54 -04003418}
3419##
3420
Herb Derbyefe39bc2018-05-01 17:06:20 -04003421#SeeAlso drawIRect drawRRect drawRoundRect drawRegion drawPath drawLine
Cary Clark8032b982017-07-28 11:04:54 -04003422
3423##
3424
3425# ------------------------------------------------------------------------------
3426
Herb Derbyefe39bc2018-05-01 17:06:20 -04003427#Method void drawIRect(const SkIRect& rect, const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05003428#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05003429#Line # draws IRect using Clip, Matrix, and Paint ##
Cary Clark8032b982017-07-28 11:04:54 -04003430Draw IRect rect using Clip, Matrix, and Paint paint.
Herb Derbyefe39bc2018-05-01 17:06:20 -04003431In paint: Paint_Style determines if rectangle is stroked or filled;
Cary Clark8032b982017-07-28 11:04:54 -04003432if stroked, Paint_Stroke_Width describes the line thickness, and
3433Paint_Stroke_Join draws the corners rounded or square.
3434
Cary Clarkbc5697d2017-10-04 14:31:33 -04003435#Param rect rectangle to draw ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003436#Param paint stroke or fill, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003437
3438#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003439 SkIRect rect = { 64, 48, 192, 160 };
3440 SkPaint paint;
3441 paint.setAntiAlias(true);
3442 paint.setStyle(SkPaint::kStroke_Style);
3443 paint.setStrokeWidth(20);
3444 paint.setStrokeJoin(SkPaint::kRound_Join);
3445 for (auto color : { SK_ColorRED, SK_ColorBLUE, SK_ColorYELLOW, SK_ColorMAGENTA } ) {
3446 paint.setColor(color);
3447 canvas->drawIRect(rect, paint);
3448 canvas->rotate(30, 128, 128);
3449 }
Cary Clark8032b982017-07-28 11:04:54 -04003450##
3451
Cary Clark2ade9972017-11-02 17:49:34 -04003452#SeeAlso drawRect drawRRect drawRoundRect drawRegion drawPath drawLine
Cary Clark8032b982017-07-28 11:04:54 -04003453
3454##
3455
3456# ------------------------------------------------------------------------------
3457
3458#Method void drawRegion(const SkRegion& region, const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05003459#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05003460#Line # draws Region using Clip, Matrix, and Paint ##
Cary Clark8032b982017-07-28 11:04:54 -04003461Draw Region region using Clip, Matrix, and Paint paint.
Herb Derbyefe39bc2018-05-01 17:06:20 -04003462In paint: Paint_Style determines if rectangle is stroked or filled;
Cary Clark8032b982017-07-28 11:04:54 -04003463if stroked, Paint_Stroke_Width describes the line thickness, and
3464Paint_Stroke_Join draws the corners rounded or square.
3465
Cary Clarkbc5697d2017-10-04 14:31:33 -04003466#Param region region to draw ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003467#Param paint Paint stroke or fill, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003468
3469#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003470void draw(SkCanvas* canvas) {
3471 SkRegion region;
3472 region.op( 10, 10, 50, 50, SkRegion::kUnion_Op);
3473 region.op( 10, 50, 90, 90, SkRegion::kUnion_Op);
3474 SkPaint paint;
3475 paint.setAntiAlias(true);
3476 paint.setStyle(SkPaint::kStroke_Style);
3477 paint.setStrokeWidth(20);
3478 paint.setStrokeJoin(SkPaint::kRound_Join);
3479 canvas->drawRegion(region, paint);
Cary Clark8032b982017-07-28 11:04:54 -04003480}
3481##
3482
Cary Clark2ade9972017-11-02 17:49:34 -04003483#SeeAlso drawRect drawIRect drawPath
Cary Clark8032b982017-07-28 11:04:54 -04003484
3485##
3486
3487# ------------------------------------------------------------------------------
3488
3489#Method void drawOval(const SkRect& oval, const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05003490#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05003491#Line # draws Oval using Clip, Matrix, and Paint ##
Cary Clark8032b982017-07-28 11:04:54 -04003492Draw Oval oval using Clip, Matrix, and Paint.
Herb Derbyefe39bc2018-05-01 17:06:20 -04003493In paint: Paint_Style determines if Oval is stroked or filled;
Cary Clark8032b982017-07-28 11:04:54 -04003494if stroked, Paint_Stroke_Width describes the line thickness.
3495
Cary Clarkbad5ad72017-08-03 17:14:08 -04003496#Param oval Rect bounds of Oval ##
3497#Param paint Paint stroke or fill, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003498
3499#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003500void draw(SkCanvas* canvas) {
3501 canvas->clear(0xFF3f5f9f);
3502 SkColor kColor1 = SkColorSetARGB(0xff, 0xff, 0x7f, 0);
3503 SkColor g1Colors[] = { kColor1, SkColorSetA(kColor1, 0x20) };
3504 SkPoint g1Points[] = { { 0, 0 }, { 0, 100 } };
3505 SkScalar pos[] = { 0.2f, 1.0f };
3506 SkRect bounds = SkRect::MakeWH(80, 70);
3507 SkPaint paint;
3508 paint.setAntiAlias(true);
3509 paint.setShader(SkGradientShader::MakeLinear(g1Points, g1Colors, pos, SK_ARRAY_COUNT(g1Colors),
3510 SkShader::kClamp_TileMode));
3511 canvas->drawOval(bounds , paint);
Cary Clark8032b982017-07-28 11:04:54 -04003512}
3513##
3514
Cary Clark2ade9972017-11-02 17:49:34 -04003515#SeeAlso drawCircle drawPoint drawPath drawRRect drawRoundRect
Cary Clark8032b982017-07-28 11:04:54 -04003516
3517##
3518
3519# ------------------------------------------------------------------------------
3520
3521#Method void drawRRect(const SkRRect& rrect, const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05003522#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05003523#Line # draws Round_Rect using Clip, Matrix, and Paint ##
Cary Clark8032b982017-07-28 11:04:54 -04003524Draw Round_Rect rrect using Clip, Matrix, and Paint paint.
Herb Derbyefe39bc2018-05-01 17:06:20 -04003525In paint: Paint_Style determines if rrect is stroked or filled;
Cary Clark8032b982017-07-28 11:04:54 -04003526if stroked, Paint_Stroke_Width describes the line thickness.
3527
Cary Clarkbad5ad72017-08-03 17:14:08 -04003528rrect may represent a rectangle, circle, oval, uniformly rounded rectangle, or
3529may have any combination of positive non-square radii for the four corners.
Cary Clark8032b982017-07-28 11:04:54 -04003530
Cary Clarkbad5ad72017-08-03 17:14:08 -04003531#Param rrect Round_Rect with up to eight corner radii to draw ##
3532#Param paint Paint stroke or fill, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003533
3534#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003535void draw(SkCanvas* canvas) {
3536 SkPaint paint;
3537 paint.setAntiAlias(true);
3538 SkRect outer = {30, 40, 210, 220};
3539 SkRect radii = {30, 50, 70, 90 };
3540 SkRRect rRect;
3541 rRect.setNinePatch(outer, radii.fLeft, radii.fTop, radii.fRight, radii.fBottom);
3542 canvas->drawRRect(rRect, paint);
3543 paint.setColor(SK_ColorWHITE);
3544 canvas->drawLine(outer.fLeft + radii.fLeft, outer.fTop,
3545 outer.fLeft + radii.fLeft, outer.fBottom, paint);
Herb Derbyefe39bc2018-05-01 17:06:20 -04003546 canvas->drawLine(outer.fRight - radii.fRight, outer.fTop,
Cary Clarkbad5ad72017-08-03 17:14:08 -04003547 outer.fRight - radii.fRight, outer.fBottom, paint);
Herb Derbyefe39bc2018-05-01 17:06:20 -04003548 canvas->drawLine(outer.fLeft, outer.fTop + radii.fTop,
Cary Clarkbad5ad72017-08-03 17:14:08 -04003549 outer.fRight, outer.fTop + radii.fTop, paint);
Herb Derbyefe39bc2018-05-01 17:06:20 -04003550 canvas->drawLine(outer.fLeft, outer.fBottom - radii.fBottom,
Cary Clarkbad5ad72017-08-03 17:14:08 -04003551 outer.fRight, outer.fBottom - radii.fBottom, paint);
3552}
Cary Clark8032b982017-07-28 11:04:54 -04003553##
3554
Cary Clark2ade9972017-11-02 17:49:34 -04003555#SeeAlso drawRect drawRoundRect drawDRRect drawCircle drawOval drawPath
Cary Clark8032b982017-07-28 11:04:54 -04003556
3557##
3558
3559# ------------------------------------------------------------------------------
3560
3561#Method void drawDRRect(const SkRRect& outer, const SkRRect& inner, const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05003562#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05003563#Line # draws double Round_Rect stroked or filled ##
Cary Clark8032b982017-07-28 11:04:54 -04003564Draw Round_Rect outer and inner
Herb Derbyefe39bc2018-05-01 17:06:20 -04003565using Clip, Matrix, and Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04003566outer must contain inner or the drawing is undefined.
Herb Derbyefe39bc2018-05-01 17:06:20 -04003567In paint: Paint_Style determines if Round_Rect is stroked or filled;
Cary Clark8032b982017-07-28 11:04:54 -04003568if stroked, Paint_Stroke_Width describes the line thickness.
Cary Clarkbad5ad72017-08-03 17:14:08 -04003569If stroked and Round_Rect corner has zero length radii, Paint_Stroke_Join can
Herb Derbyefe39bc2018-05-01 17:06:20 -04003570draw corners rounded or square.
Cary Clark8032b982017-07-28 11:04:54 -04003571
Cary Clarkbad5ad72017-08-03 17:14:08 -04003572GPU-backed platforms optimize drawing when both outer and inner are
Cary Clark8032b982017-07-28 11:04:54 -04003573concave and outer contains inner. These platforms may not be able to draw
Herb Derbyefe39bc2018-05-01 17:06:20 -04003574Path built with identical data as fast.
Cary Clark8032b982017-07-28 11:04:54 -04003575
Cary Clarkbad5ad72017-08-03 17:14:08 -04003576#Param outer Round_Rect outer bounds to draw ##
3577#Param inner Round_Rect inner bounds to draw ##
3578#Param paint Paint stroke or fill, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003579
3580#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003581void draw(SkCanvas* canvas) {
3582 SkRRect outer = SkRRect::MakeRect({20, 40, 210, 200});
3583 SkRRect inner = SkRRect::MakeOval({60, 70, 170, 160});
3584 SkPaint paint;
3585 canvas->drawDRRect(outer, inner, paint);
Cary Clark8032b982017-07-28 11:04:54 -04003586}
3587##
3588
3589#Example
3590#Description
3591 Outer Rect has no corner radii, but stroke join is rounded.
3592 Inner Round_Rect has corner radii; outset stroke increases radii of corners.
3593 Stroke join does not affect inner Round_Rect since it has no sharp corners.
3594##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003595void draw(SkCanvas* canvas) {
3596 SkRRect outer = SkRRect::MakeRect({20, 40, 210, 200});
3597 SkRRect inner = SkRRect::MakeRectXY({60, 70, 170, 160}, 10, 10);
3598 SkPaint paint;
3599 paint.setAntiAlias(true);
3600 paint.setStyle(SkPaint::kStroke_Style);
3601 paint.setStrokeWidth(20);
3602 paint.setStrokeJoin(SkPaint::kRound_Join);
3603 canvas->drawDRRect(outer, inner, paint);
3604 paint.setStrokeWidth(1);
3605 paint.setColor(SK_ColorWHITE);
3606 canvas->drawDRRect(outer, inner, paint);
Cary Clark8032b982017-07-28 11:04:54 -04003607}
3608##
3609
Cary Clark2ade9972017-11-02 17:49:34 -04003610#SeeAlso drawRect drawRoundRect drawRRect drawCircle drawOval drawPath
Cary Clark8032b982017-07-28 11:04:54 -04003611
3612##
3613
3614# ------------------------------------------------------------------------------
3615
3616#Method void drawCircle(SkScalar cx, SkScalar cy, SkScalar radius, const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05003617#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05003618#Line # draws Circle using Clip, Matrix, and Paint ##
Cary Clark8032b982017-07-28 11:04:54 -04003619Draw Circle at (cx, cy) with radius using Clip, Matrix, and Paint paint.
3620If radius is zero or less, nothing is drawn.
Herb Derbyefe39bc2018-05-01 17:06:20 -04003621In paint: Paint_Style determines if Circle is stroked or filled;
Cary Clark8032b982017-07-28 11:04:54 -04003622if stroked, Paint_Stroke_Width describes the line thickness.
3623
Cary Clarkbad5ad72017-08-03 17:14:08 -04003624#Param cx Circle center on the x-axis ##
3625#Param cy Circle center on the y-axis ##
3626#Param radius half the diameter of Circle ##
3627#Param paint Paint stroke or fill, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003628
3629#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003630 void draw(SkCanvas* canvas) {
3631 SkPaint paint;
3632 paint.setAntiAlias(true);
3633 canvas->drawCircle(128, 128, 90, paint);
3634 paint.setColor(SK_ColorWHITE);
3635 canvas->drawCircle(86, 86, 20, paint);
3636 canvas->drawCircle(160, 76, 20, paint);
3637 canvas->drawCircle(140, 150, 35, paint);
3638 }
3639##
3640
Cary Clark2ade9972017-11-02 17:49:34 -04003641#SeeAlso drawOval drawRRect drawRoundRect drawPath drawArc drawPoint drawLine
Cary Clarkbad5ad72017-08-03 17:14:08 -04003642
3643##
3644
3645#Method void drawCircle(SkPoint center, SkScalar radius, const SkPaint& paint)
3646
Cary Clarkce101242017-09-01 15:51:02 -04003647Draw Circle at center with radius using Clip, Matrix, and Paint paint.
Cary Clarkbad5ad72017-08-03 17:14:08 -04003648If radius is zero or less, nothing is drawn.
Herb Derbyefe39bc2018-05-01 17:06:20 -04003649In paint: Paint_Style determines if Circle is stroked or filled;
Cary Clarkbad5ad72017-08-03 17:14:08 -04003650if stroked, Paint_Stroke_Width describes the line thickness.
3651
3652#Param center Circle center ##
3653#Param radius half the diameter of Circle ##
3654#Param paint Paint stroke or fill, blend, color, and so on, used to draw ##
3655
3656#Example
3657 void draw(SkCanvas* canvas) {
3658 SkPaint paint;
3659 paint.setAntiAlias(true);
3660 canvas->drawCircle(128, 128, 90, paint);
3661 paint.setColor(SK_ColorWHITE);
3662 canvas->drawCircle({86, 86}, 20, paint);
3663 canvas->drawCircle({160, 76}, 20, paint);
3664 canvas->drawCircle({140, 150}, 35, paint);
3665 }
Cary Clark8032b982017-07-28 11:04:54 -04003666##
3667
Cary Clark2ade9972017-11-02 17:49:34 -04003668#SeeAlso drawOval drawRRect drawRoundRect drawPath drawArc drawPoint drawLine
Cary Clark8032b982017-07-28 11:04:54 -04003669
3670##
3671
3672# ------------------------------------------------------------------------------
3673
3674#Method void drawArc(const SkRect& oval, SkScalar startAngle, SkScalar sweepAngle,
3675 bool useCenter, const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05003676#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05003677#Line # draws Arc using Clip, Matrix, and Paint ##
Cary Clark8032b982017-07-28 11:04:54 -04003678
3679Draw Arc using Clip, Matrix, and Paint paint.
Cary Clarkbad5ad72017-08-03 17:14:08 -04003680
Cary Clark8032b982017-07-28 11:04:54 -04003681Arc is part of Oval bounded by oval, sweeping from startAngle to startAngle plus
3682sweepAngle. startAngle and sweepAngle are in degrees.
Cary Clarkbad5ad72017-08-03 17:14:08 -04003683
Cary Clark8032b982017-07-28 11:04:54 -04003684startAngle of zero places start point at the right middle edge of oval.
3685A positive sweepAngle places Arc end point clockwise from start point;
3686a negative sweepAngle places Arc end point counterclockwise from start point.
3687sweepAngle may exceed 360 degrees, a full circle.
3688If useCenter is true, draw a wedge that includes lines from oval
3689center to Arc end points. If useCenter is false, draw Arc between end points.
3690
3691If Rect oval is empty or sweepAngle is zero, nothing is drawn.
3692
Cary Clarkbad5ad72017-08-03 17:14:08 -04003693#Param oval Rect bounds of Oval containing Arc to draw ##
3694#Param startAngle angle in degrees where Arc begins ##
3695#Param sweepAngle sweep angle in degrees; positive is clockwise ##
3696#Param useCenter if true, include the center of the oval ##
3697#Param paint Paint stroke or fill, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003698
3699#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003700 void draw(SkCanvas* canvas) {
3701 SkPaint paint;
3702 paint.setAntiAlias(true);
3703 SkRect oval = { 4, 4, 60, 60};
3704 for (auto useCenter : { false, true } ) {
3705 for (auto style : { SkPaint::kFill_Style, SkPaint::kStroke_Style } ) {
3706 paint.setStyle(style);
3707 for (auto degrees : { 45, 90, 180, 360} ) {
3708 canvas->drawArc(oval, 0, degrees , useCenter, paint);
3709 canvas->translate(64, 0);
3710 }
3711 canvas->translate(-256, 64);
3712 }
3713 }
Cary Clark8032b982017-07-28 11:04:54 -04003714 }
3715##
3716
3717#Example
3718#Height 64
Cary Clarkbad5ad72017-08-03 17:14:08 -04003719 void draw(SkCanvas* canvas) {
3720 SkPaint paint;
3721 paint.setAntiAlias(true);
3722 paint.setStyle(SkPaint::kStroke_Style);
3723 paint.setStrokeWidth(4);
3724 SkRect oval = { 4, 4, 60, 60};
3725 float intervals[] = { 5, 5 };
3726 paint.setPathEffect(SkDashPathEffect::Make(intervals, 2, 2.5f));
3727 for (auto degrees : { 270, 360, 540, 720 } ) {
3728 canvas->drawArc(oval, 0, degrees, false, paint);
3729 canvas->translate(64, 0);
3730 }
Cary Clark8032b982017-07-28 11:04:54 -04003731 }
3732##
3733
Cary Clark2ade9972017-11-02 17:49:34 -04003734#SeeAlso SkPath::arcTo drawCircle drawOval drawPath
Cary Clark8032b982017-07-28 11:04:54 -04003735
3736##
3737
3738# ------------------------------------------------------------------------------
3739
3740#Method void drawRoundRect(const SkRect& rect, SkScalar rx, SkScalar ry, const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05003741#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05003742#Line # draws Round_Rect using Clip, Matrix, and Paint ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003743Draw Round_Rect bounded by Rect rect, with corner radii (rx, ry) using Clip,
3744Matrix, and Paint paint.
3745
Herb Derbyefe39bc2018-05-01 17:06:20 -04003746In paint: Paint_Style determines if Round_Rect is stroked or filled;
Cary Clark8032b982017-07-28 11:04:54 -04003747if stroked, Paint_Stroke_Width describes the line thickness.
3748If rx or ry are less than zero, they are treated as if they are zero.
3749If rx plus ry exceeds rect width or rect height, radii are scaled down to fit.
Cary Clarkbad5ad72017-08-03 17:14:08 -04003750If rx and ry are zero, Round_Rect is drawn as Rect and if stroked is affected by
3751Paint_Stroke_Join.
Cary Clark8032b982017-07-28 11:04:54 -04003752
Cary Clarkbad5ad72017-08-03 17:14:08 -04003753#Param rect Rect bounds of Round_Rect to draw ##
Cary Clarkce101242017-09-01 15:51:02 -04003754#Param rx axis length in x of oval describing rounded corners ##
3755#Param ry axis length in y of oval describing rounded corners ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003756#Param paint stroke, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003757
3758#Example
3759#Description
3760 Top row has a zero radius a generates a rectangle.
3761 Second row radii sum to less than sides.
3762 Third row radii sum equals sides.
3763 Fourth row radii sum exceeds sides; radii are scaled to fit.
3764##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003765 void draw(SkCanvas* canvas) {
3766 SkVector radii[] = { {0, 20}, {10, 10}, {10, 20}, {10, 40} };
3767 SkPaint paint;
3768 paint.setStrokeWidth(15);
3769 paint.setStrokeJoin(SkPaint::kRound_Join);
3770 paint.setAntiAlias(true);
3771 for (auto style : { SkPaint::kStroke_Style, SkPaint::kFill_Style } ) {
3772 paint.setStyle(style );
3773 for (size_t i = 0; i < SK_ARRAY_COUNT(radii); ++i) {
3774 canvas->drawRoundRect({10, 10, 60, 40}, radii[i].fX, radii[i].fY, paint);
3775 canvas->translate(0, 60);
3776 }
3777 canvas->translate(80, -240);
3778 }
Cary Clark8032b982017-07-28 11:04:54 -04003779 }
3780##
3781
Cary Clark2ade9972017-11-02 17:49:34 -04003782#SeeAlso DrawRRect drawRect drawDRRect drawPath drawCircle drawOval drawPoint
Cary Clark8032b982017-07-28 11:04:54 -04003783
3784##
3785
3786# ------------------------------------------------------------------------------
3787
3788#Method void drawPath(const SkPath& path, const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05003789#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05003790#Line # draws Path using Clip, Matrix, and Paint ##
Cary Clark8032b982017-07-28 11:04:54 -04003791Draw Path path using Clip, Matrix, and Paint paint.
3792Path contains an array of Path_Contour, each of which may be open or closed.
3793
3794In paint: Paint_Style determines if Round_Rect is stroked or filled:
Cary Clarkbad5ad72017-08-03 17:14:08 -04003795if filled, Path_Fill_Type determines whether Path_Contour describes inside or
3796outside of fill; if stroked, Paint_Stroke_Width describes the line thickness,
3797Paint_Stroke_Cap describes line ends, and Paint_Stroke_Join describes how
3798corners are drawn.
Cary Clark8032b982017-07-28 11:04:54 -04003799
Cary Clarkbad5ad72017-08-03 17:14:08 -04003800#Param path Path to draw ##
3801#Param paint stroke, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003802
3803#Example
3804#Description
3805 Top rows draw stroked path with combinations of joins and caps. The open contour
3806 is affected by caps; the closed contour is affected by joins.
Herb Derbyefe39bc2018-05-01 17:06:20 -04003807 Bottom row draws fill the same for open and closed contour.
Cary Clark8032b982017-07-28 11:04:54 -04003808 First bottom column shows winding fills overlap.
3809 Second bottom column shows even odd fills exclude overlap.
3810 Third bottom column shows inverse winding fills area outside both contours.
3811##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003812void draw(SkCanvas* canvas) {
3813 SkPath path;
3814 path.moveTo(20, 20);
3815 path.quadTo(60, 20, 60, 60);
3816 path.close();
3817 path.moveTo(60, 20);
3818 path.quadTo(60, 60, 20, 60);
3819 SkPaint paint;
3820 paint.setStrokeWidth(10);
3821 paint.setAntiAlias(true);
3822 paint.setStyle(SkPaint::kStroke_Style);
3823 for (auto join: { SkPaint::kBevel_Join, SkPaint::kRound_Join, SkPaint::kMiter_Join } ) {
3824 paint.setStrokeJoin(join);
3825 for (auto cap: { SkPaint::kButt_Cap, SkPaint::kSquare_Cap, SkPaint::kRound_Cap } ) {
3826 paint.setStrokeCap(cap);
3827 canvas->drawPath(path, paint);
3828 canvas->translate(80, 0);
3829 }
3830 canvas->translate(-240, 60);
3831 }
3832 paint.setStyle(SkPaint::kFill_Style);
Herb Derbyefe39bc2018-05-01 17:06:20 -04003833 for (auto fill : { SkPath::kWinding_FillType,
3834 SkPath::kEvenOdd_FillType,
Cary Clarkbad5ad72017-08-03 17:14:08 -04003835 SkPath::kInverseWinding_FillType } ) {
3836 path.setFillType(fill);
3837 canvas->save();
3838 canvas->clipRect({0, 10, 80, 70});
3839 canvas->drawPath(path, paint);
3840 canvas->restore();
3841 canvas->translate(80, 0);
3842 }
Cary Clark8032b982017-07-28 11:04:54 -04003843}
3844##
3845
Cary Clark2ade9972017-11-02 17:49:34 -04003846#SeeAlso SkPath drawLine drawArc drawRect drawPoints
Cary Clark8032b982017-07-28 11:04:54 -04003847
3848##
3849
3850# ------------------------------------------------------------------------------
Cary Clark08895c42018-02-01 09:37:32 -05003851#Subtopic Draw_Image
3852#Line # draws Image to Canvas ##
Cary Clark8032b982017-07-28 11:04:54 -04003853
Cary Clarkbad5ad72017-08-03 17:14:08 -04003854drawImage, drawImageRect, and drawImageNine can be called with a bare pointer or
3855a smart pointer as a convenience. The pairs of calls are otherwise identical.
Cary Clark8032b982017-07-28 11:04:54 -04003856
Cary Clark73fa9722017-08-29 17:36:51 -04003857#Method void drawImage(const SkImage* image, SkScalar left, SkScalar top, const SkPaint* paint = nullptr)
Cary Clarkab2621d2018-01-30 10:08:57 -05003858#In Draw_Image
Cary Clark78de7512018-02-07 07:27:09 -05003859#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05003860#Line # draws Image at (x, y) position ##
Cary Clark8032b982017-07-28 11:04:54 -04003861Draw Image image, with its top-left corner at (left, top),
3862using Clip, Matrix, and optional Paint paint.
3863
Cary Clarkbad5ad72017-08-03 17:14:08 -04003864If paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter, Blend_Mode,
3865and Draw_Looper. If image is kAlpha_8_SkColorType, apply Shader.
3866If paint contains Mask_Filter, generate mask from image bounds. If generated
3867mask extends beyond image bounds, replicate image edge colors, just as Shader
3868made from SkImage::makeShader with SkShader::kClamp_TileMode set replicates the
Herb Derbyefe39bc2018-05-01 17:06:20 -04003869image edge color when it samples outside of its bounds.
Cary Clark8032b982017-07-28 11:04:54 -04003870
Cary Clarkbad5ad72017-08-03 17:14:08 -04003871#Param image uncompressed rectangular map of pixels ##
3872#Param left left side of image ##
3873#Param top top side of image ##
3874#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
3875 and so on; or nullptr
3876##
Cary Clark8032b982017-07-28 11:04:54 -04003877
3878#Example
3879#Height 64
3880#Image 4
Cary Clarkbad5ad72017-08-03 17:14:08 -04003881void draw(SkCanvas* canvas) {
3882 // sk_sp<SkImage> image;
3883 SkImage* imagePtr = image.get();
3884 canvas->drawImage(imagePtr, 0, 0);
3885 SkPaint paint;
3886 canvas->drawImage(imagePtr, 80, 0, &paint);
3887 paint.setAlpha(0x80);
3888 canvas->drawImage(imagePtr, 160, 0, &paint);
Cary Clark8032b982017-07-28 11:04:54 -04003889}
3890##
3891
Cary Clark2ade9972017-11-02 17:49:34 -04003892#SeeAlso drawBitmap drawImageLattice drawImageNine drawImageRect SkPaint::setImageFilter
Cary Clark8032b982017-07-28 11:04:54 -04003893
3894##
3895
3896# ------------------------------------------------------------------------------
3897
3898#Method void drawImage(const sk_sp<SkImage>& image, SkScalar left, SkScalar top,
Herb Derbyefe39bc2018-05-01 17:06:20 -04003899 const SkPaint* paint = nullptr)
Cary Clark8032b982017-07-28 11:04:54 -04003900
3901Draw Image image, with its top-left corner at (left, top),
3902using Clip, Matrix, and optional Paint paint.
3903
Cary Clarkbad5ad72017-08-03 17:14:08 -04003904If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
3905Blend_Mode, and Draw_Looper. If image is kAlpha_8_SkColorType, apply Shader.
3906If paint contains Mask_Filter, generate mask from image bounds. If generated
3907mask extends beyond image bounds, replicate image edge colors, just as Shader
3908made from SkImage::makeShader with SkShader::kClamp_TileMode set replicates the
Herb Derbyefe39bc2018-05-01 17:06:20 -04003909image edge color when it samples outside of its bounds.
Cary Clark8032b982017-07-28 11:04:54 -04003910
Cary Clarkbad5ad72017-08-03 17:14:08 -04003911#Param image uncompressed rectangular map of pixels ##
3912#Param left left side of image ##
3913#Param top pop side of image ##
3914#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
3915 and so on; or nullptr
3916##
Cary Clark8032b982017-07-28 11:04:54 -04003917
3918#Example
3919#Height 64
3920#Image 4
Cary Clarkbad5ad72017-08-03 17:14:08 -04003921void draw(SkCanvas* canvas) {
3922 // sk_sp<SkImage> image;
3923 canvas->drawImage(image, 0, 0);
3924 SkPaint paint;
3925 canvas->drawImage(image, 80, 0, &paint);
3926 paint.setAlpha(0x80);
3927 canvas->drawImage(image, 160, 0, &paint);
Cary Clark8032b982017-07-28 11:04:54 -04003928}
3929##
3930
Cary Clark2ade9972017-11-02 17:49:34 -04003931#SeeAlso drawBitmap drawImageLattice drawImageNine drawImageRect SkPaint::setImageFilter
Cary Clark8032b982017-07-28 11:04:54 -04003932
3933##
3934
3935# ------------------------------------------------------------------------------
3936
3937#Enum SrcRectConstraint
Cary Clark08895c42018-02-01 09:37:32 -05003938#Line # sets drawImageRect options ##
Cary Clark8032b982017-07-28 11:04:54 -04003939
3940#Code
3941 enum SrcRectConstraint {
Herb Derbyefe39bc2018-05-01 17:06:20 -04003942 kStrict_SrcRectConstraint,
3943 kFast_SrcRectConstraint,
Cary Clark8032b982017-07-28 11:04:54 -04003944 };
3945##
3946
Cary Clarkce101242017-09-01 15:51:02 -04003947SrcRectConstraint controls the behavior at the edge of source Rect,
3948provided to drawImageRect, trading off speed for precision.
Cary Clark8032b982017-07-28 11:04:54 -04003949
Cary Clarkce101242017-09-01 15:51:02 -04003950Image_Filter in Paint may sample multiple pixels in the image. Source Rect
Cary Clarkbad5ad72017-08-03 17:14:08 -04003951restricts the bounds of pixels that may be read. Image_Filter may slow down if
Herb Derbyefe39bc2018-05-01 17:06:20 -04003952it cannot read outside the bounds, when sampling near the edge of source Rect.
Cary Clark8032b982017-07-28 11:04:54 -04003953SrcRectConstraint specifies whether an Image_Filter is allowed to read pixels
Cary Clarkce101242017-09-01 15:51:02 -04003954outside source Rect.
Cary Clark8032b982017-07-28 11:04:54 -04003955
Cary Clark682c58d2018-05-16 07:07:07 -04003956#Const kStrict_SrcRectConstraint 0
3957#Line # sample only inside bounds; slower ##
Cary Clarkce101242017-09-01 15:51:02 -04003958 Requires Image_Filter to respect source Rect,
Cary Clark8032b982017-07-28 11:04:54 -04003959 sampling only inside of its bounds, possibly with a performance penalty.
3960##
3961
Cary Clark682c58d2018-05-16 07:07:07 -04003962#Const kFast_SrcRectConstraint 1
3963#Line # sample outside bounds; faster ##
Cary Clarkce101242017-09-01 15:51:02 -04003964 Permits Image_Filter to sample outside of source Rect
Cary Clark8032b982017-07-28 11:04:54 -04003965 by half the width of Image_Filter, permitting it to run faster but with
3966 error at the image edges.
3967##
3968
3969#Example
3970#Height 64
3971#Description
3972 redBorder contains a black and white checkerboard bordered by red.
3973 redBorder is drawn scaled by 16 on the left.
Cary Clarkce101242017-09-01 15:51:02 -04003974 The middle and right bitmaps are filtered checkerboards.
Cary Clark8032b982017-07-28 11:04:54 -04003975 Drawing the checkerboard with kStrict_SrcRectConstraint shows only a blur of black and white.
3976 Drawing the checkerboard with kFast_SrcRectConstraint allows red to bleed in the corners.
3977##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003978void draw(SkCanvas* canvas) {
3979 SkBitmap redBorder;
3980 redBorder.allocPixels(SkImageInfo::MakeN32Premul(4, 4));
3981 SkCanvas checkRed(redBorder);
3982 checkRed.clear(SK_ColorRED);
3983 uint32_t checkers[][2] = { { SK_ColorBLACK, SK_ColorWHITE },
3984 { SK_ColorWHITE, SK_ColorBLACK } };
3985 checkRed.writePixels(
3986 SkImageInfo::MakeN32Premul(2, 2), (void*) checkers, sizeof(checkers[0]), 1, 1);
3987 canvas->scale(16, 16);
3988 canvas->drawBitmap(redBorder, 0, 0, nullptr);
3989 canvas->resetMatrix();
3990 sk_sp<SkImage> image = SkImage::MakeFromBitmap(redBorder);
3991 SkPaint lowPaint;
3992 lowPaint.setFilterQuality(kLow_SkFilterQuality);
3993 for (auto constraint : { SkCanvas::kStrict_SrcRectConstraint,
3994 SkCanvas::kFast_SrcRectConstraint } ) {
3995 canvas->translate(80, 0);
3996 canvas->drawImageRect(image.get(), SkRect::MakeLTRB(1, 1, 3, 3),
3997 SkRect::MakeLTRB(16, 16, 48, 48), &lowPaint, constraint);
3998 }
Cary Clark8032b982017-07-28 11:04:54 -04003999}
4000##
4001
Cary Clark2ade9972017-11-02 17:49:34 -04004002#SeeAlso drawImageRect drawImage SkPaint::setImageFilter
Cary Clark8032b982017-07-28 11:04:54 -04004003
4004##
4005
4006# ------------------------------------------------------------------------------
4007
4008#Method void drawImageRect(const SkImage* image, const SkRect& src, const SkRect& dst,
4009 const SkPaint* paint,
4010 SrcRectConstraint constraint = kStrict_SrcRectConstraint)
Cary Clarkab2621d2018-01-30 10:08:57 -05004011#In Draw_Image
Cary Clark78de7512018-02-07 07:27:09 -05004012#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05004013#Line # draws Image, source Rect to destination Rect ##
Cary Clark8032b982017-07-28 11:04:54 -04004014
4015Draw Rect src of Image image, scaled and translated to fill Rect dst.
4016Additionally transform draw using Clip, Matrix, and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004017
Cary Clarkbad5ad72017-08-03 17:14:08 -04004018If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4019Blend_Mode, and Draw_Looper. If image is kAlpha_8_SkColorType, apply Shader.
4020If paint contains Mask_Filter, generate mask from image bounds.
4021
4022If generated mask extends beyond image bounds, replicate image edge colors, just
4023as Shader made from SkImage::makeShader with SkShader::kClamp_TileMode set
Cary Clarkbc5697d2017-10-04 14:31:33 -04004024replicates the image edge color when it samples outside of its bounds.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004025
4026constraint set to kStrict_SrcRectConstraint limits Paint Filter_Quality to
4027sample within src; set to kFast_SrcRectConstraint allows sampling outside to
4028improve performance.
4029
4030#Param image Image containing pixels, dimensions, and format ##
4031#Param src source Rect of image to draw from ##
4032#Param dst destination Rect of image to draw to ##
4033#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4034 and so on; or nullptr
4035##
4036#Param constraint filter strictly within src or draw faster ##
Cary Clark8032b982017-07-28 11:04:54 -04004037
4038#Example
4039#Height 64
4040#Description
4041 The left bitmap draws with Paint default kNone_SkFilterQuality, and stays within
Cary Clarkbc5697d2017-10-04 14:31:33 -04004042 its bounds; there is no bleeding with kFast_SrcRectConstraint.
Cary Clark8032b982017-07-28 11:04:54 -04004043 the middle and right bitmaps draw with kLow_SkFilterQuality; with
4044 kStrict_SrcRectConstraint, the filter remains within the checkerboard, and
4045 with kFast_SrcRectConstraint red bleeds on the edges.
4046##
Cary Clarkbad5ad72017-08-03 17:14:08 -04004047void draw(SkCanvas* canvas) {
Herb Derbyefe39bc2018-05-01 17:06:20 -04004048 uint32_t pixels[][4] = {
Cary Clarkbad5ad72017-08-03 17:14:08 -04004049 { 0xFFFF0000, 0xFFFF0000, 0xFFFF0000, 0xFFFF0000 },
4050 { 0xFFFF0000, 0xFF000000, 0xFFFFFFFF, 0xFFFF0000 },
4051 { 0xFFFF0000, 0xFFFFFFFF, 0xFF000000, 0xFFFF0000 },
4052 { 0xFFFF0000, 0xFFFF0000, 0xFFFF0000, 0xFFFF0000 } };
4053 SkBitmap redBorder;
Herb Derbyefe39bc2018-05-01 17:06:20 -04004054 redBorder.installPixels(SkImageInfo::MakeN32Premul(4, 4),
Cary Clarkbad5ad72017-08-03 17:14:08 -04004055 (void*) pixels, sizeof(pixels[0]));
4056 sk_sp<SkImage> image = SkImage::MakeFromBitmap(redBorder);
4057 SkPaint lowPaint;
4058 for (auto constraint : {
4059 SkCanvas::kFast_SrcRectConstraint,
4060 SkCanvas::kStrict_SrcRectConstraint,
4061 SkCanvas::kFast_SrcRectConstraint } ) {
4062 canvas->drawImageRect(image.get(), SkRect::MakeLTRB(1, 1, 3, 3),
4063 SkRect::MakeLTRB(16, 16, 48, 48), &lowPaint, constraint);
4064 lowPaint.setFilterQuality(kLow_SkFilterQuality);
4065 canvas->translate(80, 0);
4066 }
4067}
Cary Clark8032b982017-07-28 11:04:54 -04004068##
4069
Cary Clark2ade9972017-11-02 17:49:34 -04004070#SeeAlso SrcRectConstraint drawImage drawImageLattice drawImageNine
Cary Clark8032b982017-07-28 11:04:54 -04004071
4072##
4073
4074# ------------------------------------------------------------------------------
4075
4076#Method void drawImageRect(const SkImage* image, const SkIRect& isrc, const SkRect& dst,
4077 const SkPaint* paint, SrcRectConstraint constraint = kStrict_SrcRectConstraint)
Cary Clarkab2621d2018-01-30 10:08:57 -05004078#In Draw_Image
Cary Clark78de7512018-02-07 07:27:09 -05004079#In Draw
Cary Clark8032b982017-07-28 11:04:54 -04004080
4081Draw IRect isrc of Image image, scaled and translated to fill Rect dst.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004082Note that isrc is on integer pixel boundaries; dst may include fractional
4083boundaries. Additionally transform draw using Clip, Matrix, and optional Paint
Herb Derbyefe39bc2018-05-01 17:06:20 -04004084paint.
Cary Clark8032b982017-07-28 11:04:54 -04004085
Cary Clarkbad5ad72017-08-03 17:14:08 -04004086If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4087Blend_Mode, and Draw_Looper. If image is kAlpha_8_SkColorType, apply Shader.
4088If paint contains Mask_Filter, generate mask from image bounds.
4089
4090If generated mask extends beyond image bounds, replicate image edge colors, just
4091as Shader made from SkImage::makeShader with SkShader::kClamp_TileMode set
Cary Clarkbc5697d2017-10-04 14:31:33 -04004092replicates the image edge color when it samples outside of its bounds.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004093
4094constraint set to kStrict_SrcRectConstraint limits Paint Filter_Quality to
Cary Clarkce101242017-09-01 15:51:02 -04004095sample within isrc; set to kFast_SrcRectConstraint allows sampling outside to
Cary Clarkbad5ad72017-08-03 17:14:08 -04004096improve performance.
4097
4098#Param image Image containing pixels, dimensions, and format ##
4099#Param isrc source IRect of image to draw from ##
4100#Param dst destination Rect of image to draw to ##
4101#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4102 and so on; or nullptr
4103##
Cary Clarkce101242017-09-01 15:51:02 -04004104#Param constraint filter strictly within isrc or draw faster ##
Cary Clark8032b982017-07-28 11:04:54 -04004105
4106#Example
4107#Image 4
Cary Clarkbad5ad72017-08-03 17:14:08 -04004108void draw(SkCanvas* canvas) {
4109 // sk_sp<SkImage> image;
4110 for (auto i : { 1, 2, 4, 8 } ) {
Herb Derbyefe39bc2018-05-01 17:06:20 -04004111 canvas->drawImageRect(image.get(), SkIRect::MakeLTRB(0, 0, 100, 100),
Cary Clarkbad5ad72017-08-03 17:14:08 -04004112 SkRect::MakeXYWH(i * 20, i * 20, i * 20, i * 20), nullptr);
4113 }
Cary Clark8032b982017-07-28 11:04:54 -04004114}
4115##
4116
Cary Clark2ade9972017-11-02 17:49:34 -04004117#SeeAlso SrcRectConstraint drawImage drawImageLattice drawImageNine
Cary Clark8032b982017-07-28 11:04:54 -04004118
4119##
4120
4121# ------------------------------------------------------------------------------
4122
4123#Method void drawImageRect(const SkImage* image, const SkRect& dst, const SkPaint* paint,
4124 SrcRectConstraint constraint = kStrict_SrcRectConstraint)
Cary Clarkab2621d2018-01-30 10:08:57 -05004125#In Draw_Image
Cary Clark78de7512018-02-07 07:27:09 -05004126#In Draw
Cary Clark8032b982017-07-28 11:04:54 -04004127
Cary Clarkbad5ad72017-08-03 17:14:08 -04004128Draw Image image, scaled and translated to fill Rect dst, using Clip, Matrix,
4129and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004130
Cary Clarkbad5ad72017-08-03 17:14:08 -04004131If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4132Blend_Mode, and Draw_Looper. If image is kAlpha_8_SkColorType, apply Shader.
4133If paint contains Mask_Filter, generate mask from image bounds.
4134
4135If generated mask extends beyond image bounds, replicate image edge colors, just
4136as Shader made from SkImage::makeShader with SkShader::kClamp_TileMode set
Cary Clarkbc5697d2017-10-04 14:31:33 -04004137replicates the image edge color when it samples outside of its bounds.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004138
4139constraint set to kStrict_SrcRectConstraint limits Paint Filter_Quality to
Cary Clarkce101242017-09-01 15:51:02 -04004140sample within image; set to kFast_SrcRectConstraint allows sampling outside to
Cary Clarkbad5ad72017-08-03 17:14:08 -04004141improve performance.
4142
4143#Param image Image containing pixels, dimensions, and format ##
4144#Param dst destination Rect of image to draw to ##
4145#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4146 and so on; or nullptr
4147##
Cary Clarkce101242017-09-01 15:51:02 -04004148#Param constraint filter strictly within image or draw faster ##
Cary Clark8032b982017-07-28 11:04:54 -04004149
4150#Example
4151#Image 4
Cary Clarkbad5ad72017-08-03 17:14:08 -04004152void draw(SkCanvas* canvas) {
4153 // sk_sp<SkImage> image;
4154 for (auto i : { 20, 40, 80, 160 } ) {
4155 canvas->drawImageRect(image.get(), SkRect::MakeXYWH(i, i, i, i), nullptr);
4156 }
Cary Clark8032b982017-07-28 11:04:54 -04004157}
4158##
4159
Cary Clark2ade9972017-11-02 17:49:34 -04004160#SeeAlso SrcRectConstraint drawImage drawImageLattice drawImageNine
Cary Clark8032b982017-07-28 11:04:54 -04004161
4162##
4163
4164# ------------------------------------------------------------------------------
4165
4166#Method void drawImageRect(const sk_sp<SkImage>& image, const SkRect& src, const SkRect& dst,
4167 const SkPaint* paint,
Herb Derbyefe39bc2018-05-01 17:06:20 -04004168 SrcRectConstraint constraint = kStrict_SrcRectConstraint)
Cary Clarkab2621d2018-01-30 10:08:57 -05004169#In Draw_Image
Cary Clark78de7512018-02-07 07:27:09 -05004170#In Draw
Cary Clark8032b982017-07-28 11:04:54 -04004171Draw Rect src of Image image, scaled and translated to fill Rect dst.
4172Additionally transform draw using Clip, Matrix, and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004173
Cary Clarkbad5ad72017-08-03 17:14:08 -04004174If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4175Blend_Mode, and Draw_Looper. If image is kAlpha_8_SkColorType, apply Shader.
4176If paint contains Mask_Filter, generate mask from image bounds.
4177
4178If generated mask extends beyond image bounds, replicate image edge colors, just
4179as Shader made from SkImage::makeShader with SkShader::kClamp_TileMode set
Cary Clarkbc5697d2017-10-04 14:31:33 -04004180replicates the image edge color when it samples outside of its bounds.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004181
4182constraint set to kStrict_SrcRectConstraint limits Paint Filter_Quality to
4183sample within src; set to kFast_SrcRectConstraint allows sampling outside to
4184improve performance.
4185
4186#Param image Image containing pixels, dimensions, and format ##
4187#Param src source Rect of image to draw from ##
4188#Param dst destination Rect of image to draw to ##
4189#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4190 and so on; or nullptr
4191##
4192#Param constraint filter strictly within src or draw faster ##
Cary Clark8032b982017-07-28 11:04:54 -04004193
4194#Example
4195#Height 64
4196#Description
4197 Canvas scales and translates; transformation from src to dst also scales.
4198 The two matrices are concatenated to create the final transformation.
4199##
Cary Clarkbad5ad72017-08-03 17:14:08 -04004200void draw(SkCanvas* canvas) {
4201 uint32_t pixels[][2] = { { SK_ColorBLACK, SK_ColorWHITE },
4202 { SK_ColorWHITE, SK_ColorBLACK } };
4203 SkBitmap bitmap;
Herb Derbyefe39bc2018-05-01 17:06:20 -04004204 bitmap.installPixels(SkImageInfo::MakeN32Premul(2, 2),
Cary Clarkbad5ad72017-08-03 17:14:08 -04004205 (void*) pixels, sizeof(pixels[0]));
4206 sk_sp<SkImage> image = SkImage::MakeFromBitmap(bitmap);
4207 SkPaint paint;
4208 canvas->scale(4, 4);
4209 for (auto alpha : { 50, 100, 150, 255 } ) {
4210 paint.setAlpha(alpha);
4211 canvas->drawImageRect(image, SkRect::MakeWH(2, 2), SkRect::MakeWH(8, 8), &paint);
4212 canvas->translate(8, 0);
4213 }
4214}
Cary Clark8032b982017-07-28 11:04:54 -04004215##
4216
Cary Clark2ade9972017-11-02 17:49:34 -04004217#SeeAlso SrcRectConstraint drawImage drawImageLattice drawImageNine
Cary Clark8032b982017-07-28 11:04:54 -04004218
4219##
4220
4221# ------------------------------------------------------------------------------
4222
4223#Method void drawImageRect(const sk_sp<SkImage>& image, const SkIRect& isrc, const SkRect& dst,
Herb Derbyefe39bc2018-05-01 17:06:20 -04004224 const SkPaint* paint, SrcRectConstraint constraint = kStrict_SrcRectConstraint)
Cary Clarkab2621d2018-01-30 10:08:57 -05004225#In Draw_Image
Cary Clark78de7512018-02-07 07:27:09 -05004226#In Draw
Cary Clark8032b982017-07-28 11:04:54 -04004227Draw IRect isrc of Image image, scaled and translated to fill Rect dst.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004228isrc is on integer pixel boundaries; dst may include fractional boundaries.
Cary Clark8032b982017-07-28 11:04:54 -04004229Additionally transform draw using Clip, Matrix, and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004230
Cary Clarkbad5ad72017-08-03 17:14:08 -04004231If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4232Blend_Mode, and Draw_Looper. If image is kAlpha_8_SkColorType, apply Shader.
4233If paint contains Mask_Filter, generate mask from image bounds.
4234
4235If generated mask extends beyond image bounds, replicate image edge colors, just
4236as Shader made from SkImage::makeShader with SkShader::kClamp_TileMode set
Cary Clarkbc5697d2017-10-04 14:31:33 -04004237replicates the image edge color when it samples outside of its bounds.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004238
4239constraint set to kStrict_SrcRectConstraint limits Paint Filter_Quality to
Cary Clarkce101242017-09-01 15:51:02 -04004240sample within image; set to kFast_SrcRectConstraint allows sampling outside to
Cary Clarkbad5ad72017-08-03 17:14:08 -04004241improve performance.
4242
4243#Param image Image containing pixels, dimensions, and format ##
4244#Param isrc source IRect of image to draw from ##
4245#Param dst destination Rect of image to draw to ##
4246#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4247 and so on; or nullptr
4248##
Cary Clarkce101242017-09-01 15:51:02 -04004249#Param constraint filter strictly within image or draw faster ##
Cary Clark8032b982017-07-28 11:04:54 -04004250
4251#Example
4252#Height 64
Cary Clarkbad5ad72017-08-03 17:14:08 -04004253void draw(SkCanvas* canvas) {
4254 uint32_t pixels[][2] = { { 0x00000000, 0x55555555},
4255 { 0xAAAAAAAA, 0xFFFFFFFF} };
4256 SkBitmap bitmap;
Herb Derbyefe39bc2018-05-01 17:06:20 -04004257 bitmap.installPixels(SkImageInfo::MakeN32Premul(2, 2),
Cary Clarkbad5ad72017-08-03 17:14:08 -04004258 (void*) pixels, sizeof(pixels[0]));
4259 sk_sp<SkImage> image = SkImage::MakeFromBitmap(bitmap);
4260 SkPaint paint;
4261 canvas->scale(4, 4);
4262 for (auto color : { SK_ColorRED, SK_ColorBLUE, SK_ColorGREEN } ) {
4263 paint.setColorFilter(SkColorFilter::MakeModeFilter(color, SkBlendMode::kPlus));
4264 canvas->drawImageRect(image, SkIRect::MakeWH(2, 2), SkRect::MakeWH(8, 8), &paint);
4265 canvas->translate(8, 0);
4266 }
Cary Clark8032b982017-07-28 11:04:54 -04004267}
4268##
4269
Cary Clark2ade9972017-11-02 17:49:34 -04004270#SeeAlso SrcRectConstraint drawImage drawImageLattice drawImageNine
4271
Cary Clark8032b982017-07-28 11:04:54 -04004272##
4273
4274# ------------------------------------------------------------------------------
4275
4276#Method void drawImageRect(const sk_sp<SkImage>& image, const SkRect& dst, const SkPaint* paint,
Herb Derbyefe39bc2018-05-01 17:06:20 -04004277 SrcRectConstraint constraint = kStrict_SrcRectConstraint)
Cary Clarkab2621d2018-01-30 10:08:57 -05004278#In Draw_Image
Cary Clark78de7512018-02-07 07:27:09 -05004279#In Draw
Cary Clark8032b982017-07-28 11:04:54 -04004280Draw Image image, scaled and translated to fill Rect dst,
4281using Clip, Matrix, and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004282
Cary Clarkbad5ad72017-08-03 17:14:08 -04004283If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4284Blend_Mode, and Draw_Looper. If image is kAlpha_8_SkColorType, apply Shader.
4285If paint contains Mask_Filter, generate mask from image bounds.
4286
4287If generated mask extends beyond image bounds, replicate image edge colors, just
4288as Shader made from SkImage::makeShader with SkShader::kClamp_TileMode set
Cary Clarkbc5697d2017-10-04 14:31:33 -04004289replicates the image edge color when it samples outside of its bounds.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004290
4291constraint set to kStrict_SrcRectConstraint limits Paint Filter_Quality to
Cary Clarkce101242017-09-01 15:51:02 -04004292sample within image; set to kFast_SrcRectConstraint allows sampling outside to
Cary Clarkbad5ad72017-08-03 17:14:08 -04004293improve performance.
4294
4295#Param image Image containing pixels, dimensions, and format ##
4296#Param dst destination Rect of image to draw to ##
4297#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4298 and so on; or nullptr
4299##
Cary Clarkce101242017-09-01 15:51:02 -04004300#Param constraint filter strictly within image or draw faster ##
Cary Clark8032b982017-07-28 11:04:54 -04004301
4302#Example
4303#Height 64
Cary Clarkbad5ad72017-08-03 17:14:08 -04004304void draw(SkCanvas* canvas) {
4305 uint32_t pixels[][2] = { { 0x00000000, 0x55550000},
4306 { 0xAAAA0000, 0xFFFF0000} };
4307 SkBitmap bitmap;
Herb Derbyefe39bc2018-05-01 17:06:20 -04004308 bitmap.installPixels(SkImageInfo::MakeN32Premul(2, 2),
Cary Clarkbad5ad72017-08-03 17:14:08 -04004309 (void*) pixels, sizeof(pixels[0]));
4310 sk_sp<SkImage> image = SkImage::MakeFromBitmap(bitmap);
4311 SkPaint paint;
4312 canvas->scale(4, 4);
4313 for (auto color : { SK_ColorRED, SK_ColorBLUE, SK_ColorGREEN } ) {
4314 paint.setColorFilter(SkColorFilter::MakeModeFilter(color, SkBlendMode::kPlus));
4315 canvas->drawImageRect(image, SkRect::MakeWH(8, 8), &paint);
4316 canvas->translate(8, 0);
4317 }
Cary Clark8032b982017-07-28 11:04:54 -04004318}
4319##
4320
Cary Clark2ade9972017-11-02 17:49:34 -04004321#SeeAlso SrcRectConstraint drawImage drawImageLattice drawImageNine
Cary Clark8032b982017-07-28 11:04:54 -04004322
4323##
4324
4325# ------------------------------------------------------------------------------
4326
4327#Method void drawImageNine(const SkImage* image, const SkIRect& center, const SkRect& dst,
4328 const SkPaint* paint = nullptr)
Cary Clarkab2621d2018-01-30 10:08:57 -05004329#In Draw_Image
Cary Clark78de7512018-02-07 07:27:09 -05004330#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05004331#Line # draws Nine_Patch Image ##
Cary Clark8032b982017-07-28 11:04:54 -04004332
Cary Clarkd0530ba2017-09-14 11:25:39 -04004333Draw Image image stretched proportionally to fit into Rect dst.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004334IRect center divides the image into nine sections: four sides, four corners, and
Cary Clarkce101242017-09-01 15:51:02 -04004335the center. Corners are unmodified or scaled down proportionately if their sides
Cary Clarkbad5ad72017-08-03 17:14:08 -04004336are larger than dst; center and four sides are scaled to fit remaining space, if any.
Cary Clark8032b982017-07-28 11:04:54 -04004337
Cary Clarkbad5ad72017-08-03 17:14:08 -04004338Additionally transform draw using Clip, Matrix, and optional Paint paint.
4339
Cary Clark682c58d2018-05-16 07:07:07 -04004340#paint_as_used_by_draw_lattice_or_draw_nine(image)#
Cary Clarkbad5ad72017-08-03 17:14:08 -04004341
4342If generated mask extends beyond image bounds, replicate image edge colors, just
4343as Shader made from SkImage::makeShader with SkShader::kClamp_TileMode set
Cary Clarkbc5697d2017-10-04 14:31:33 -04004344replicates the image edge color when it samples outside of its bounds.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004345
4346#Param image Image containing pixels, dimensions, and format ##
4347#Param center IRect edge of image corners and sides ##
4348#Param dst destination Rect of image to draw to ##
4349#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4350 and so on; or nullptr
4351##
Cary Clark8032b982017-07-28 11:04:54 -04004352
4353#Example
4354#Height 128
4355#Description
4356 The leftmost image is smaller than center; only corners are drawn, all scaled to fit.
Cary Clarkce101242017-09-01 15:51:02 -04004357 The second image equals the size of center; only corners are drawn without scaling.
4358 The remaining images are larger than center. All corners draw without scaling.
4359 The sides and center are scaled if needed to take up the remaining space.
Cary Clark8032b982017-07-28 11:04:54 -04004360##
Cary Clarkbad5ad72017-08-03 17:14:08 -04004361void draw(SkCanvas* canvas) {
4362 SkIRect center = { 20, 10, 50, 40 };
4363 SkBitmap bitmap;
4364 bitmap.allocPixels(SkImageInfo::MakeN32Premul(60, 60));
4365 SkCanvas bitCanvas(bitmap);
4366 SkPaint paint;
4367 SkColor gray = 0xFF000000;
4368 int left = 0;
4369 for (auto right: { center.fLeft, center.fRight, bitmap.width() } ) {
4370 int top = 0;
4371 for (auto bottom: { center.fTop, center.fBottom, bitmap.height() } ) {
4372 paint.setColor(gray);
4373 bitCanvas.drawIRect(SkIRect::MakeLTRB(left, top, right, bottom), paint);
4374 gray += 0x001f1f1f;
4375 top = bottom;
4376 }
Herb Derbyefe39bc2018-05-01 17:06:20 -04004377 left = right;
Cary Clarkbad5ad72017-08-03 17:14:08 -04004378 }
4379 sk_sp<SkImage> image = SkImage::MakeFromBitmap(bitmap);
4380 SkImage* imagePtr = image.get();
4381 for (auto dest: { 20, 30, 40, 60, 90 } ) {
4382 canvas->drawImageNine(imagePtr, center, SkRect::MakeWH(dest, dest), nullptr);
4383 canvas->translate(dest + 4, 0);
4384 }
Cary Clark8032b982017-07-28 11:04:54 -04004385}
4386##
4387
Cary Clark2ade9972017-11-02 17:49:34 -04004388#SeeAlso drawImage drawBitmapNine drawImageLattice drawImageRect
Cary Clark8032b982017-07-28 11:04:54 -04004389
4390##
4391
4392# ------------------------------------------------------------------------------
4393
4394#Method void drawImageNine(const sk_sp<SkImage>& image, const SkIRect& center, const SkRect& dst,
Herb Derbyefe39bc2018-05-01 17:06:20 -04004395 const SkPaint* paint = nullptr)
Cary Clarkab2621d2018-01-30 10:08:57 -05004396#In Draw_Image
Cary Clark78de7512018-02-07 07:27:09 -05004397#In Draw
Cary Clarkd0530ba2017-09-14 11:25:39 -04004398Draw Image image stretched proportionally to fit into Rect dst.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004399IRect center divides the image into nine sections: four sides, four corners, and
Cary Clarkce101242017-09-01 15:51:02 -04004400the center. Corners are not scaled, or scaled down proportionately if their sides
Cary Clarkbad5ad72017-08-03 17:14:08 -04004401are larger than dst; center and four sides are scaled to fit remaining space, if any.
Cary Clark8032b982017-07-28 11:04:54 -04004402
Cary Clarkbad5ad72017-08-03 17:14:08 -04004403Additionally transform draw using Clip, Matrix, and optional Paint paint.
4404
Cary Clark137b8742018-05-30 09:21:49 -04004405#paint_as_used_by_draw_lattice_or_draw_nine(image)#
Cary Clarkbad5ad72017-08-03 17:14:08 -04004406
4407If generated mask extends beyond image bounds, replicate image edge colors, just
4408as Shader made from SkImage::makeShader with SkShader::kClamp_TileMode set
Cary Clarkbc5697d2017-10-04 14:31:33 -04004409replicates the image edge color when it samples outside of its bounds.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004410
4411#Param image Image containing pixels, dimensions, and format ##
4412#Param center IRect edge of image corners and sides ##
4413#Param dst destination Rect of image to draw to ##
4414#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4415 and so on; or nullptr
4416##
Cary Clark8032b982017-07-28 11:04:54 -04004417
4418#Example
4419#Height 128
4420#Description
4421 The two leftmost images has four corners and sides to the left and right of center.
4422 The leftmost image scales the width of corners proportionately to fit.
Herb Derbyefe39bc2018-05-01 17:06:20 -04004423 The third and fourth image corners are not scaled; the sides and center are scaled to
Cary Clark8032b982017-07-28 11:04:54 -04004424 fill the remaining space.
4425 The rightmost image has four corners scaled vertically to fit, and uses sides above
4426 and below center to fill the remaining space.
4427##
Cary Clarkbad5ad72017-08-03 17:14:08 -04004428void draw(SkCanvas* canvas) {
4429 SkIRect center = { 20, 10, 50, 40 };
4430 SkBitmap bitmap;
4431 bitmap.allocPixels(SkImageInfo::MakeN32Premul(60, 60));
4432 SkCanvas bitCanvas(bitmap);
4433 SkPaint paint;
4434 SkColor gray = 0xFF000000;
4435 int left = 0;
4436 for (auto right: { center.fLeft, center.fRight, bitmap.width() } ) {
4437 int top = 0;
4438 for (auto bottom: { center.fTop, center.fBottom, bitmap.height() } ) {
4439 paint.setColor(gray);
4440 bitCanvas.drawIRect(SkIRect::MakeLTRB(left, top, right, bottom), paint);
4441 gray += 0x001f1f1f;
4442 top = bottom;
4443 }
Herb Derbyefe39bc2018-05-01 17:06:20 -04004444 left = right;
Cary Clarkbad5ad72017-08-03 17:14:08 -04004445 }
4446 sk_sp<SkImage> image = SkImage::MakeFromBitmap(bitmap);
4447 for (auto dest: { 20, 30, 40, 60, 90 } ) {
4448 canvas->drawImageNine(image, center, SkRect::MakeWH(dest, 110 - dest), nullptr);
4449 canvas->translate(dest + 4, 0);
4450 }
Cary Clark8032b982017-07-28 11:04:54 -04004451}
4452##
4453
Cary Clark2ade9972017-11-02 17:49:34 -04004454#SeeAlso drawImage drawBitmapNine drawImageLattice drawImageRect
Cary Clark8032b982017-07-28 11:04:54 -04004455
4456##
4457
4458# ------------------------------------------------------------------------------
4459
4460#Method void drawBitmap(const SkBitmap& bitmap, SkScalar left, SkScalar top,
Cary Clark73fa9722017-08-29 17:36:51 -04004461 const SkPaint* paint = nullptr)
Cary Clarkab2621d2018-01-30 10:08:57 -05004462#In Draw_Image
Cary Clark78de7512018-02-07 07:27:09 -05004463#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05004464#Line # draws Bitmap at (x, y) position ##
Cary Clark8032b982017-07-28 11:04:54 -04004465
4466Draw Bitmap bitmap, with its top-left corner at (left, top),
4467using Clip, Matrix, and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004468
Cary Clarka560c472017-11-27 10:44:06 -05004469If Paint paint is not nullptr, apply Color_Filter, Color_Alpha, Image_Filter,
Cary Clarkbad5ad72017-08-03 17:14:08 -04004470Blend_Mode, and Draw_Looper. If bitmap is kAlpha_8_SkColorType, apply Shader.
4471If paint contains Mask_Filter, generate mask from bitmap bounds.
4472
4473If generated mask extends beyond bitmap bounds, replicate bitmap edge colors,
4474just as Shader made from SkShader::MakeBitmapShader with
Cary Clarkbc5697d2017-10-04 14:31:33 -04004475SkShader::kClamp_TileMode set replicates the bitmap edge color when it samples
Herb Derbyefe39bc2018-05-01 17:06:20 -04004476outside of its bounds.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004477
4478#Param bitmap Bitmap containing pixels, dimensions, and format ##
4479#Param left left side of bitmap ##
4480#Param top top side of bitmap ##
4481#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4482 and so on; or nullptr
4483##
Cary Clark8032b982017-07-28 11:04:54 -04004484
4485#Example
4486#Height 64
Cary Clarkbad5ad72017-08-03 17:14:08 -04004487void draw(SkCanvas* canvas) {
4488 uint8_t pixels[][8] = { { 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00},
4489 { 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00},
4490 { 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00},
4491 { 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF},
4492 { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
4493 { 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00},
4494 { 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0x00},
4495 { 0xFF, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0xFF} };
4496 SkBitmap bitmap;
Herb Derbyefe39bc2018-05-01 17:06:20 -04004497 bitmap.installPixels(SkImageInfo::MakeA8(8, 8),
Cary Clarkbad5ad72017-08-03 17:14:08 -04004498 (void*) pixels, sizeof(pixels[0]));
4499 SkPaint paint;
4500 canvas->scale(4, 4);
4501 for (auto color : { SK_ColorRED, SK_ColorBLUE, 0xFF007F00} ) {
4502 paint.setColor(color);
4503 canvas->drawBitmap(bitmap, 0, 0, &paint);
4504 canvas->translate(12, 0);
4505 }
Cary Clark8032b982017-07-28 11:04:54 -04004506}
4507##
4508
Cary Clark2ade9972017-11-02 17:49:34 -04004509#SeeAlso drawImage drawBitmapLattice drawBitmapNine drawBitmapRect SkBitmap::readPixels SkBitmap::writePixels
Cary Clark8032b982017-07-28 11:04:54 -04004510
4511##
4512
4513# ------------------------------------------------------------------------------
4514
4515#Method void drawBitmapRect(const SkBitmap& bitmap, const SkRect& src, const SkRect& dst,
4516 const SkPaint* paint, SrcRectConstraint constraint = kStrict_SrcRectConstraint)
Cary Clarkab2621d2018-01-30 10:08:57 -05004517#In Draw_Image
Cary Clark78de7512018-02-07 07:27:09 -05004518#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05004519#Line # draws Bitmap, source Rect to destination Rect ##
Cary Clark8032b982017-07-28 11:04:54 -04004520
4521Draw Rect src of Bitmap bitmap, scaled and translated to fill Rect dst.
4522Additionally transform draw using Clip, Matrix, and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004523
Cary Clarkbad5ad72017-08-03 17:14:08 -04004524If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4525Blend_Mode, and Draw_Looper. If bitmap is kAlpha_8_SkColorType, apply Shader.
4526If paint contains Mask_Filter, generate mask from bitmap bounds.
4527
4528If generated mask extends beyond bitmap bounds, replicate bitmap edge colors,
4529just as Shader made from SkShader::MakeBitmapShader with
Cary Clarkbc5697d2017-10-04 14:31:33 -04004530SkShader::kClamp_TileMode set replicates the bitmap edge color when it samples
Cary Clarkbad5ad72017-08-03 17:14:08 -04004531outside of its bounds.
4532
4533constraint set to kStrict_SrcRectConstraint limits Paint Filter_Quality to
4534sample within src; set to kFast_SrcRectConstraint allows sampling outside to
4535improve performance.
4536
4537#Param bitmap Bitmap containing pixels, dimensions, and format ##
4538#Param src source Rect of image to draw from ##
4539#Param dst destination Rect of image to draw to ##
4540#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4541 and so on; or nullptr
4542##
4543#Param constraint filter strictly within src or draw faster ##
Cary Clark8032b982017-07-28 11:04:54 -04004544
4545#Example
4546#Height 64
Cary Clarkbad5ad72017-08-03 17:14:08 -04004547void draw(SkCanvas* canvas) {
4548 uint8_t pixels[][8] = { { 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00},
4549 { 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00},
4550 { 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00},
4551 { 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF},
4552 { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
4553 { 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00},
4554 { 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00},
4555 { 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00} };
4556 SkBitmap bitmap;
Herb Derbyefe39bc2018-05-01 17:06:20 -04004557 bitmap.installPixels(SkImageInfo::MakeA8(8, 8),
Cary Clarkbad5ad72017-08-03 17:14:08 -04004558 (void*) pixels, sizeof(pixels[0]));
4559 SkPaint paint;
Cary Clark681287e2018-03-16 11:34:15 -04004560 paint.setMaskFilter(SkMaskFilter::MakeBlur(kSolid_SkBlurStyle, 6));
Cary Clarkbad5ad72017-08-03 17:14:08 -04004561 for (auto color : { SK_ColorRED, SK_ColorBLUE, 0xFF007F00} ) {
4562 paint.setColor(color);
4563 canvas->drawBitmapRect(bitmap, SkRect::MakeWH(8, 8), SkRect::MakeWH(32, 32), &paint);
4564 canvas->translate(48, 0);
4565 }
Cary Clark8032b982017-07-28 11:04:54 -04004566}
4567##
4568
Cary Clark2ade9972017-11-02 17:49:34 -04004569#SeeAlso drawImageRect drawBitmap drawBitmapLattice drawBitmapNine
Cary Clark8032b982017-07-28 11:04:54 -04004570
4571##
4572
4573# ------------------------------------------------------------------------------
4574
4575#Method void drawBitmapRect(const SkBitmap& bitmap, const SkIRect& isrc, const SkRect& dst,
4576 const SkPaint* paint, SrcRectConstraint constraint = kStrict_SrcRectConstraint)
Cary Clarkab2621d2018-01-30 10:08:57 -05004577#In Draw_Image
Cary Clark78de7512018-02-07 07:27:09 -05004578#In Draw
Cary Clark8032b982017-07-28 11:04:54 -04004579Draw IRect isrc of Bitmap bitmap, scaled and translated to fill Rect dst.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004580isrc is on integer pixel boundaries; dst may include fractional boundaries.
Cary Clark8032b982017-07-28 11:04:54 -04004581Additionally transform draw using Clip, Matrix, and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004582
Cary Clarkbad5ad72017-08-03 17:14:08 -04004583If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4584Blend_Mode, and Draw_Looper. If bitmap is kAlpha_8_SkColorType, apply Shader.
4585If paint contains Mask_Filter, generate mask from bitmap bounds.
4586
4587If generated mask extends beyond bitmap bounds, replicate bitmap edge colors,
4588just as Shader made from SkShader::MakeBitmapShader with
Cary Clarkbc5697d2017-10-04 14:31:33 -04004589SkShader::kClamp_TileMode set replicates the bitmap edge color when it samples
Cary Clarkbad5ad72017-08-03 17:14:08 -04004590outside of its bounds.
4591
4592constraint set to kStrict_SrcRectConstraint limits Paint Filter_Quality to
Cary Clarkce101242017-09-01 15:51:02 -04004593sample within isrc; set to kFast_SrcRectConstraint allows sampling outside to
Cary Clarkbad5ad72017-08-03 17:14:08 -04004594improve performance.
4595
4596#Param bitmap Bitmap containing pixels, dimensions, and format ##
4597#Param isrc source IRect of image to draw from ##
4598#Param dst destination Rect of image to draw to ##
4599#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4600 and so on; or nullptr
4601##
Cary Clarkce101242017-09-01 15:51:02 -04004602#Param constraint sample strictly within isrc, or draw faster ##
Cary Clark8032b982017-07-28 11:04:54 -04004603
4604#Example
4605#Height 64
Cary Clarkbad5ad72017-08-03 17:14:08 -04004606void draw(SkCanvas* canvas) {
4607 uint8_t pixels[][8] = { { 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00},
4608 { 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00},
4609 { 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0xFF},
4610 { 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0xFF},
4611 { 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF},
4612 { 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF},
4613 { 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00},
4614 { 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00} };
4615 SkBitmap bitmap;
Herb Derbyefe39bc2018-05-01 17:06:20 -04004616 bitmap.installPixels(SkImageInfo::MakeA8(8, 8),
Cary Clarkbad5ad72017-08-03 17:14:08 -04004617 (void*) pixels, sizeof(pixels[0]));
4618 SkPaint paint;
4619 paint.setFilterQuality(kHigh_SkFilterQuality);
4620 for (auto color : { SK_ColorRED, SK_ColorBLUE, 0xFF007F00, 0xFF7f007f} ) {
4621 paint.setColor(color);
4622 canvas->drawBitmapRect(bitmap, SkIRect::MakeWH(8, 8), SkRect::MakeWH(32, 32), &paint);
4623 canvas->translate(48.25f, 0);
4624 }
Cary Clark8032b982017-07-28 11:04:54 -04004625}
4626##
4627
Cary Clark2ade9972017-11-02 17:49:34 -04004628#SeeAlso drawImageRect drawBitmap drawBitmapLattice drawBitmapNine
Cary Clark8032b982017-07-28 11:04:54 -04004629
4630##
4631
4632# ------------------------------------------------------------------------------
4633
4634#Method void drawBitmapRect(const SkBitmap& bitmap, const SkRect& dst, const SkPaint* paint,
4635 SrcRectConstraint constraint = kStrict_SrcRectConstraint)
Cary Clarkab2621d2018-01-30 10:08:57 -05004636#In Draw_Image
Cary Clark78de7512018-02-07 07:27:09 -05004637#In Draw
Cary Clark8032b982017-07-28 11:04:54 -04004638Draw Bitmap bitmap, scaled and translated to fill Rect dst.
Cary Clarkce101242017-09-01 15:51:02 -04004639bitmap bounds is on integer pixel boundaries; dst may include fractional boundaries.
Cary Clark8032b982017-07-28 11:04:54 -04004640Additionally transform draw using Clip, Matrix, and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004641
Cary Clarkbad5ad72017-08-03 17:14:08 -04004642If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4643Blend_Mode, and Draw_Looper. If bitmap is kAlpha_8_SkColorType, apply Shader.
4644If paint contains Mask_Filter, generate mask from bitmap bounds.
4645
4646If generated mask extends beyond bitmap bounds, replicate bitmap edge colors,
4647just as Shader made from SkShader::MakeBitmapShader with
Cary Clarkbc5697d2017-10-04 14:31:33 -04004648SkShader::kClamp_TileMode set replicates the bitmap edge color when it samples
Cary Clarkbad5ad72017-08-03 17:14:08 -04004649outside of its bounds.
4650
4651constraint set to kStrict_SrcRectConstraint limits Paint Filter_Quality to
Cary Clarkce101242017-09-01 15:51:02 -04004652sample within bitmap; set to kFast_SrcRectConstraint allows sampling outside to
Cary Clarkbad5ad72017-08-03 17:14:08 -04004653improve performance.
4654
4655#Param bitmap Bitmap containing pixels, dimensions, and format ##
4656#Param dst destination Rect of image to draw to ##
4657#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4658 and so on; or nullptr
4659##
Cary Clarkce101242017-09-01 15:51:02 -04004660#Param constraint filter strictly within bitmap or draw faster ##
Cary Clark8032b982017-07-28 11:04:54 -04004661
4662#Example
4663#Height 64
Cary Clarkbad5ad72017-08-03 17:14:08 -04004664void draw(SkCanvas* canvas) {
4665 uint32_t pixels[][2] = { { 0x00000000, 0x55550000},
4666 { 0xAAAA0000, 0xFFFF0000} };
4667 SkBitmap bitmap;
Herb Derbyefe39bc2018-05-01 17:06:20 -04004668 bitmap.installPixels(SkImageInfo::MakeN32Premul(2, 2),
Cary Clarkbad5ad72017-08-03 17:14:08 -04004669 (void*) pixels, sizeof(pixels[0]));
4670 SkPaint paint;
4671 canvas->scale(4, 4);
4672 for (auto color : { SK_ColorRED, SK_ColorBLUE, SK_ColorGREEN } ) {
4673 paint.setColorFilter(SkColorFilter::MakeModeFilter(color, SkBlendMode::kPlus));
4674 canvas->drawBitmapRect(bitmap, SkRect::MakeWH(8, 8), &paint);
4675 canvas->translate(8, 0);
4676 }
Cary Clark8032b982017-07-28 11:04:54 -04004677}
4678##
4679
Cary Clark2ade9972017-11-02 17:49:34 -04004680#SeeAlso drawImageRect drawBitmap drawBitmapLattice drawBitmapNine
Cary Clark8032b982017-07-28 11:04:54 -04004681
4682##
4683
4684# ------------------------------------------------------------------------------
4685
Cary Clark682c58d2018-05-16 07:07:07 -04004686#PhraseDef paint_as_used_by_draw_lattice_or_draw_nine(bitmap_or_image)
4687If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4688Blend_Mode, and Draw_Looper. If #bitmap_or_image# is kAlpha_8_SkColorType, apply Shader.
4689If paint contains Mask_Filter, generate mask from #bitmap_or_image# bounds. If paint
4690Filter_Quality set to kNone_SkFilterQuality, disable pixel filtering. For all
4691other values of paint Filter_Quality, use kLow_SkFilterQuality to filter pixels.
Cary Clark137b8742018-05-30 09:21:49 -04004692Any SkMaskFilter on paint is ignored as is paint Anti_Aliasing state.
Cary Clark682c58d2018-05-16 07:07:07 -04004693##
4694
Cary Clark8032b982017-07-28 11:04:54 -04004695#Method void drawBitmapNine(const SkBitmap& bitmap, const SkIRect& center, const SkRect& dst,
Cary Clark73fa9722017-08-29 17:36:51 -04004696 const SkPaint* paint = nullptr)
Cary Clarkab2621d2018-01-30 10:08:57 -05004697#In Draw_Image
Cary Clark78de7512018-02-07 07:27:09 -05004698#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05004699#Line # draws Nine_Patch Bitmap ##
Cary Clark8032b982017-07-28 11:04:54 -04004700
Cary Clarkd0530ba2017-09-14 11:25:39 -04004701Draw Bitmap bitmap stretched proportionally to fit into Rect dst.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004702IRect center divides the bitmap into nine sections: four sides, four corners,
Cary Clarkce101242017-09-01 15:51:02 -04004703and the center. Corners are not scaled, or scaled down proportionately if their
Cary Clarkbad5ad72017-08-03 17:14:08 -04004704sides are larger than dst; center and four sides are scaled to fit remaining
4705space, if any.
Cary Clark8032b982017-07-28 11:04:54 -04004706
Cary Clarkbad5ad72017-08-03 17:14:08 -04004707Additionally transform draw using Clip, Matrix, and optional Paint paint.
4708
Cary Clark682c58d2018-05-16 07:07:07 -04004709#paint_as_used_by_draw_lattice_or_draw_nine(bitmap)#
Cary Clarkbad5ad72017-08-03 17:14:08 -04004710
4711If generated mask extends beyond bitmap bounds, replicate bitmap edge colors,
4712just as Shader made from SkShader::MakeBitmapShader with
Cary Clarkbc5697d2017-10-04 14:31:33 -04004713SkShader::kClamp_TileMode set replicates the bitmap edge color when it samples
Cary Clarkbad5ad72017-08-03 17:14:08 -04004714outside of its bounds.
4715
4716#Param bitmap Bitmap containing pixels, dimensions, and format ##
4717#Param center IRect edge of image corners and sides ##
4718#Param dst destination Rect of image to draw to ##
4719#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4720 and so on; or nullptr
4721##
Cary Clark8032b982017-07-28 11:04:54 -04004722
4723#Example
4724#Height 128
4725#Description
4726 The two leftmost bitmap draws has four corners and sides to the left and right of center.
4727 The leftmost bitmap draw scales the width of corners proportionately to fit.
Herb Derbyefe39bc2018-05-01 17:06:20 -04004728 The third and fourth draw corners are not scaled; the sides and center are scaled to
Cary Clark8032b982017-07-28 11:04:54 -04004729 fill the remaining space.
4730 The rightmost bitmap draw has four corners scaled vertically to fit, and uses sides above
4731 and below center to fill the remaining space.
4732##
Cary Clarkbad5ad72017-08-03 17:14:08 -04004733void draw(SkCanvas* canvas) {
4734 SkIRect center = { 20, 10, 50, 40 };
4735 SkBitmap bitmap;
4736 bitmap.allocPixels(SkImageInfo::MakeN32Premul(60, 60));
4737 SkCanvas bitCanvas(bitmap);
4738 SkPaint paint;
4739 SkColor gray = 0xFF000000;
4740 int left = 0;
4741 for (auto right: { center.fLeft, center.fRight, bitmap.width() } ) {
4742 int top = 0;
4743 for (auto bottom: { center.fTop, center.fBottom, bitmap.height() } ) {
4744 paint.setColor(gray);
4745 bitCanvas.drawIRect(SkIRect::MakeLTRB(left, top, right, bottom), paint);
4746 gray += 0x001f1f1f;
4747 top = bottom;
4748 }
Herb Derbyefe39bc2018-05-01 17:06:20 -04004749 left = right;
Cary Clarkbad5ad72017-08-03 17:14:08 -04004750 }
4751 for (auto dest: { 20, 30, 40, 60, 90 } ) {
4752 canvas->drawBitmapNine(bitmap, center, SkRect::MakeWH(dest, 110 - dest), nullptr);
4753 canvas->translate(dest + 4, 0);
4754 }
Cary Clark8032b982017-07-28 11:04:54 -04004755}
4756##
4757
Cary Clark2ade9972017-11-02 17:49:34 -04004758#SeeAlso drawImageNine drawBitmap drawBitmapLattice drawBitmapRect
Cary Clark8032b982017-07-28 11:04:54 -04004759
4760##
4761
4762# ------------------------------------------------------------------------------
Cary Clark682c58d2018-05-16 07:07:07 -04004763#Subtopic Lattice
4764#Line # divides Bitmap or Image into a rectangular grid ##
4765
Cary Clark8032b982017-07-28 11:04:54 -04004766#Struct Lattice
Cary Clark08895c42018-02-01 09:37:32 -05004767#Line # divides Bitmap or Image into a rectangular grid ##
Cary Clark682c58d2018-05-16 07:07:07 -04004768
Cary Clark8032b982017-07-28 11:04:54 -04004769#Code
4770 struct Lattice {
Cary Clark2f466242017-12-11 16:03:17 -05004771 enum RectType ...
Cary Clark8032b982017-07-28 11:04:54 -04004772
Cary Clark2f466242017-12-11 16:03:17 -05004773 const int* fXDivs;
4774 const int* fYDivs;
4775 const RectType* fRectTypes;
4776 int fXCount;
4777 int fYCount;
4778 const SkIRect* fBounds;
4779 const SkColor* fColors;
Cary Clark8032b982017-07-28 11:04:54 -04004780 };
4781##
4782
Cary Clark137b8742018-05-30 09:21:49 -04004783Lattice divides Bitmap or Image into a rectangular grid.
4784Grid entries on even columns and even rows are fixed; these entries are
4785always drawn at their original size if the destination is large enough.
4786If the destination side is too small to hold the fixed entries, all fixed
4787entries are proportionately scaled down to fit.
4788The grid entries not on even columns and rows are scaled to fit the
4789remaining space, if any.
4790
Cary Clark682c58d2018-05-16 07:07:07 -04004791#Subtopic Overview
4792#Populate
4793##
4794
4795#Subtopic Constant
4796#Populate
4797##
Cary Clark154beea2017-10-26 07:58:48 -04004798
Cary Clark2f466242017-12-11 16:03:17 -05004799 #Enum RectType
Cary Clark682c58d2018-05-16 07:07:07 -04004800 #Line # optional setting per rectangular grid entry ##
Cary Clark8032b982017-07-28 11:04:54 -04004801 #Code
Cary Clark2f466242017-12-11 16:03:17 -05004802 enum RectType : uint8_t {
4803 kDefault = 0,
4804 kTransparent,
4805 kFixedColor,
Cary Clark8032b982017-07-28 11:04:54 -04004806 };
4807 ##
4808
Cary Clark2f466242017-12-11 16:03:17 -05004809 Optional setting per rectangular grid entry to make it transparent,
4810 or to fill the grid entry with a color.
Cary Clark8032b982017-07-28 11:04:54 -04004811
Cary Clark2f466242017-12-11 16:03:17 -05004812 #Const kDefault 0
Cary Clark682c58d2018-05-16 07:07:07 -04004813 #Line # draws Bitmap into lattice rectangle ##
Cary Clark2f466242017-12-11 16:03:17 -05004814 ##
4815
4816 #Const kTransparent 1
Cary Clark682c58d2018-05-16 07:07:07 -04004817 #Line # skips lattice rectangle by making it transparent ##
Cary Clark2f466242017-12-11 16:03:17 -05004818 ##
4819
4820 #Const kFixedColor 2
Cary Clark682c58d2018-05-16 07:07:07 -04004821 #Line # draws one of fColors into lattice rectangle ##
Cary Clark8032b982017-07-28 11:04:54 -04004822 ##
4823 ##
4824
Cary Clark682c58d2018-05-16 07:07:07 -04004825#Subtopic Member
4826#Populate
4827##
4828
Cary Clark8032b982017-07-28 11:04:54 -04004829 #Member const int* fXDivs
Cary Clark682c58d2018-05-16 07:07:07 -04004830 #Line # x-coordinates dividing bitmap ##
Cary Clark8032b982017-07-28 11:04:54 -04004831 Array of x-coordinates that divide the bitmap vertically.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004832 Array entries must be unique, increasing, greater than or equal to
4833 fBounds left edge, and less than fBounds right edge.
4834 Set the first element to fBounds left to collapse the left column of
4835 fixed grid entries.
Cary Clark8032b982017-07-28 11:04:54 -04004836 ##
4837
4838 #Member const int* fYDivs
Cary Clark682c58d2018-05-16 07:07:07 -04004839 #Line # y-coordinates dividing bitmap ##
Cary Clark8032b982017-07-28 11:04:54 -04004840 Array of y-coordinates that divide the bitmap horizontally.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004841 Array entries must be unique, increasing, greater than or equal to
4842 fBounds top edge, and less than fBounds bottom edge.
4843 Set the first element to fBounds top to collapse the top row of fixed
4844 grid entries.
Cary Clark8032b982017-07-28 11:04:54 -04004845 ##
4846
Cary Clark2f466242017-12-11 16:03:17 -05004847 #Member const RectType* fRectTypes
Cary Clark682c58d2018-05-16 07:07:07 -04004848 #Line # array of fill types ##
Cary Clark2f466242017-12-11 16:03:17 -05004849 Optional array of fill types, one per rectangular grid entry:
Cary Clarkbad5ad72017-08-03 17:14:08 -04004850 array length must be
4851 #Formula
4852 (fXCount + 1) * (fYCount + 1)
4853 ##
4854 .
Cary Clark6fc50412017-09-21 12:31:06 -04004855
Cary Clark2f466242017-12-11 16:03:17 -05004856 Each RectType is one of: kDefault, kTransparent, kFixedColor.
4857
Cary Clark8032b982017-07-28 11:04:54 -04004858 Array entries correspond to the rectangular grid entries, ascending
4859 left to right and then top to bottom.
4860 ##
4861
4862 #Member int fXCount
Cary Clark682c58d2018-05-16 07:07:07 -04004863 #Line # number of x-coordinates ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04004864 Number of entries in fXDivs array; one less than the number of
4865 horizontal divisions.
Cary Clark8032b982017-07-28 11:04:54 -04004866 ##
4867
4868 #Member int fYCount
Cary Clark682c58d2018-05-16 07:07:07 -04004869 #Line # number of y-coordinates ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04004870 Number of entries in fYDivs array; one less than the number of vertical
4871 divisions.
Cary Clark8032b982017-07-28 11:04:54 -04004872 ##
4873
4874 #Member const SkIRect* fBounds
Cary Clark682c58d2018-05-16 07:07:07 -04004875 #Line # source bounds to draw from ##
Cary Clark8032b982017-07-28 11:04:54 -04004876 Optional subset IRect source to draw from.
4877 If nullptr, source bounds is dimensions of Bitmap or Image.
4878 ##
4879
Cary Clark2f466242017-12-11 16:03:17 -05004880 #Member const SkColor* fColors
Cary Clark682c58d2018-05-16 07:07:07 -04004881 #Line # array of colors ##
Cary Clark2f466242017-12-11 16:03:17 -05004882 Optional array of colors, one per rectangular grid entry.
4883 Array length must be
4884 #Formula
4885 (fXCount + 1) * (fYCount + 1)
4886 ##
4887 .
4888
4889 Array entries correspond to the rectangular grid entries, ascending
4890 left to right, then top to bottom.
4891 ##
4892
Cary Clark8032b982017-07-28 11:04:54 -04004893#Struct Lattice ##
4894
4895#Method void drawBitmapLattice(const SkBitmap& bitmap, const Lattice& lattice, const SkRect& dst,
4896 const SkPaint* paint = nullptr)
Cary Clarkab2621d2018-01-30 10:08:57 -05004897#In Draw_Image
Cary Clark78de7512018-02-07 07:27:09 -05004898#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05004899#Line # draws proportionally stretched Bitmap ##
Cary Clark8032b982017-07-28 11:04:54 -04004900
Cary Clarkd0530ba2017-09-14 11:25:39 -04004901Draw Bitmap bitmap stretched proportionally to fit into Rect dst.
Cary Clark8032b982017-07-28 11:04:54 -04004902
4903Lattice lattice divides bitmap into a rectangular grid.
4904Each intersection of an even-numbered row and column is fixed; like the corners
Cary Clarkbad5ad72017-08-03 17:14:08 -04004905of drawBitmapNine, fixed lattice elements never scale larger than their initial
Cary Clarkbc5697d2017-10-04 14:31:33 -04004906size and shrink proportionately when all fixed elements exceed the bitmap
Cary Clarkbad5ad72017-08-03 17:14:08 -04004907dimension. All other grid elements scale to fill the available space, if any.
Cary Clark8032b982017-07-28 11:04:54 -04004908
4909Additionally transform draw using Clip, Matrix, and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004910
Cary Clark682c58d2018-05-16 07:07:07 -04004911#paint_as_used_by_draw_lattice_or_draw_nine(bitmap)#
Cary Clarkbad5ad72017-08-03 17:14:08 -04004912
4913If generated mask extends beyond bitmap bounds, replicate bitmap edge colors,
4914just as Shader made from SkShader::MakeBitmapShader with
Cary Clarkbc5697d2017-10-04 14:31:33 -04004915SkShader::kClamp_TileMode set replicates the bitmap edge color when it samples
Cary Clarkbad5ad72017-08-03 17:14:08 -04004916outside of its bounds.
4917
4918#Param bitmap Bitmap containing pixels, dimensions, and format ##
4919#Param lattice division of bitmap into fixed and variable rectangles ##
4920#Param dst destination Rect of image to draw to ##
4921#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4922 and so on; or nullptr
4923##
Cary Clark8032b982017-07-28 11:04:54 -04004924
4925#Example
4926#Height 128
4927#Description
4928 The two leftmost bitmap draws has four corners and sides to the left and right of center.
4929 The leftmost bitmap draw scales the width of corners proportionately to fit.
Herb Derbyefe39bc2018-05-01 17:06:20 -04004930 The third and fourth draw corners are not scaled; the sides are scaled to
Cary Clark8032b982017-07-28 11:04:54 -04004931 fill the remaining space; the center is transparent.
4932 The rightmost bitmap draw has four corners scaled vertically to fit, and uses sides above
4933 and below center to fill the remaining space.
4934##
Cary Clarkbad5ad72017-08-03 17:14:08 -04004935void draw(SkCanvas* canvas) {
4936 SkIRect center = { 20, 10, 50, 40 };
4937 SkBitmap bitmap;
4938 bitmap.allocPixels(SkImageInfo::MakeN32Premul(60, 60));
4939 SkCanvas bitCanvas(bitmap);
4940 SkPaint paint;
4941 SkColor gray = 0xFF000000;
4942 int left = 0;
4943 for (auto right: { center.fLeft, center.fRight, bitmap.width() } ) {
4944 int top = 0;
4945 for (auto bottom: { center.fTop, center.fBottom, bitmap.height() } ) {
4946 paint.setColor(gray);
4947 bitCanvas.drawIRect(SkIRect::MakeLTRB(left, top, right, bottom), paint);
4948 gray += 0x001f1f1f;
4949 top = bottom;
4950 }
Herb Derbyefe39bc2018-05-01 17:06:20 -04004951 left = right;
Cary Clarkbad5ad72017-08-03 17:14:08 -04004952 }
4953 const int xDivs[] = { center.fLeft, center.fRight };
4954 const int yDivs[] = { center.fTop, center.fBottom };
Cary Clarkca3ebcd2017-12-12 11:22:38 -05004955 SkCanvas::Lattice::RectType fillTypes[3][3];
4956 memset(fillTypes, 0, sizeof(fillTypes));
4957 fillTypes[1][1] = SkCanvas::Lattice::kTransparent;
4958 SkColor dummy[9]; // temporary pending bug fix
4959 SkCanvas::Lattice lattice = { xDivs, yDivs, fillTypes[0], SK_ARRAY_COUNT(xDivs),
4960 SK_ARRAY_COUNT(yDivs), nullptr, dummy };
Cary Clarkbad5ad72017-08-03 17:14:08 -04004961 for (auto dest: { 20, 30, 40, 60, 90 } ) {
Cary Clarkca3ebcd2017-12-12 11:22:38 -05004962 canvas->drawBitmapLattice(bitmap, lattice, SkRect::MakeWH(dest, 110 - dest), nullptr);
Cary Clarkbad5ad72017-08-03 17:14:08 -04004963 canvas->translate(dest + 4, 0);
4964 }
Cary Clark8032b982017-07-28 11:04:54 -04004965}
4966##
4967
Cary Clark2ade9972017-11-02 17:49:34 -04004968#SeeAlso drawImageLattice drawBitmap drawBitmapNine Lattice
Cary Clark8032b982017-07-28 11:04:54 -04004969
4970##
4971
4972# ------------------------------------------------------------------------------
4973
4974#Method void drawImageLattice(const SkImage* image, const Lattice& lattice, const SkRect& dst,
4975 const SkPaint* paint = nullptr)
Cary Clarkab2621d2018-01-30 10:08:57 -05004976#In Draw_Image
Cary Clark78de7512018-02-07 07:27:09 -05004977#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05004978#Line # draws proportionally stretched Image ##
Cary Clark8032b982017-07-28 11:04:54 -04004979
Cary Clarkd0530ba2017-09-14 11:25:39 -04004980Draw Image image stretched proportionally to fit into Rect dst.
Cary Clark8032b982017-07-28 11:04:54 -04004981
4982Lattice lattice divides image into a rectangular grid.
4983Each intersection of an even-numbered row and column is fixed; like the corners
Cary Clarkbad5ad72017-08-03 17:14:08 -04004984of drawBitmapNine, fixed lattice elements never scale larger than their initial
Cary Clarkbc5697d2017-10-04 14:31:33 -04004985size and shrink proportionately when all fixed elements exceed the bitmap
Cary Clarkbad5ad72017-08-03 17:14:08 -04004986dimension. All other grid elements scale to fill the available space, if any.
Cary Clark8032b982017-07-28 11:04:54 -04004987
4988Additionally transform draw using Clip, Matrix, and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004989
Cary Clark682c58d2018-05-16 07:07:07 -04004990#paint_as_used_by_draw_lattice_or_draw_nine(image)#
Cary Clarkbad5ad72017-08-03 17:14:08 -04004991
4992If generated mask extends beyond bitmap bounds, replicate bitmap edge colors,
4993just as Shader made from SkShader::MakeBitmapShader with
Cary Clarkbc5697d2017-10-04 14:31:33 -04004994SkShader::kClamp_TileMode set replicates the bitmap edge color when it samples
Cary Clarkbad5ad72017-08-03 17:14:08 -04004995outside of its bounds.
4996
4997#Param image Image containing pixels, dimensions, and format ##
4998#Param lattice division of bitmap into fixed and variable rectangles ##
4999#Param dst destination Rect of image to draw to ##
5000#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
5001 and so on; or nullptr
5002##
Cary Clark8032b982017-07-28 11:04:54 -04005003
5004#Example
5005#Height 128
5006#Description
5007 The leftmost image is smaller than center; only corners are drawn, all scaled to fit.
Cary Clarkce101242017-09-01 15:51:02 -04005008 The second image equals the size of center; only corners are drawn without scaling.
5009 The remaining images are larger than center. All corners draw without scaling. The sides
Cary Clark8032b982017-07-28 11:04:54 -04005010 are scaled if needed to take up the remaining space; the center is transparent.
5011##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005012void draw(SkCanvas* canvas) {
5013 SkIRect center = { 20, 10, 50, 40 };
5014 SkBitmap bitmap;
5015 bitmap.allocPixels(SkImageInfo::MakeN32Premul(60, 60));
5016 SkCanvas bitCanvas(bitmap);
5017 SkPaint paint;
5018 SkColor gray = 0xFF000000;
5019 int left = 0;
5020 for (auto right: { center.fLeft, center.fRight, bitmap.width() } ) {
5021 int top = 0;
5022 for (auto bottom: { center.fTop, center.fBottom, bitmap.height() } ) {
5023 paint.setColor(gray);
5024 bitCanvas.drawIRect(SkIRect::MakeLTRB(left, top, right, bottom), paint);
5025 gray += 0x001f1f1f;
5026 top = bottom;
5027 }
Herb Derbyefe39bc2018-05-01 17:06:20 -04005028 left = right;
Cary Clarkbad5ad72017-08-03 17:14:08 -04005029 }
Cary Clarkbad5ad72017-08-03 17:14:08 -04005030 sk_sp<SkImage> image = SkImage::MakeFromBitmap(bitmap);
5031 SkImage* imagePtr = image.get();
5032 for (auto dest: { 20, 30, 40, 60, 90 } ) {
5033 canvas->drawImageNine(imagePtr, center, SkRect::MakeWH(dest, dest), nullptr);
5034 canvas->translate(dest + 4, 0);
5035 }
Cary Clark8032b982017-07-28 11:04:54 -04005036}
5037##
5038
Cary Clark2ade9972017-11-02 17:49:34 -04005039#SeeAlso drawBitmapLattice drawImage drawImageNine Lattice
Cary Clark8032b982017-07-28 11:04:54 -04005040
5041##
5042
Cary Clark682c58d2018-05-16 07:07:07 -04005043#Subtopic Lattice ##
5044
Cary Clark08895c42018-02-01 09:37:32 -05005045#Subtopic Draw_Image ##
Cary Clark8032b982017-07-28 11:04:54 -04005046
5047# ------------------------------------------------------------------------------
Cary Clark78de7512018-02-07 07:27:09 -05005048#Subtopic Draw_Text
5049#Populate
5050#Line # draws text into Canvas ##
5051##
Cary Clark8032b982017-07-28 11:04:54 -04005052
5053#Method void drawText(const void* text, size_t byteLength, SkScalar x, SkScalar y,
5054 const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05005055#In Draw_Text
5056#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05005057#Line # draws text at (x, y), using font advance ##
Cary Clark8032b982017-07-28 11:04:54 -04005058
5059Draw text, with origin at (x, y), using Clip, Matrix, and Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04005060
Cary Clarkbc5697d2017-10-04 14:31:33 -04005061text meaning depends on Paint_Text_Encoding; by default, text is encoded as
Cary Clarkbad5ad72017-08-03 17:14:08 -04005062UTF-8.
Cary Clark8032b982017-07-28 11:04:54 -04005063
Cary Clarkbad5ad72017-08-03 17:14:08 -04005064x and y meaning depends on Paint_Text_Align and Paint_Vertical_Text; by default
Cary Clarkbc5697d2017-10-04 14:31:33 -04005065text draws left to right, positioning the first glyph left side bearing at x
Herb Derbyefe39bc2018-05-01 17:06:20 -04005066and its baseline at y. Text size is affected by Matrix and Paint_Text_Size.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005067
Mike Reed8ad91a92018-01-19 19:09:32 -05005068All elements of paint: Path_Effect, Mask_Filter, Shader,
Cary Clarkbad5ad72017-08-03 17:14:08 -04005069Color_Filter, Image_Filter, and Draw_Looper; apply to text. By default, draws
Cary Clarkce101242017-09-01 15:51:02 -04005070filled 12 point black Glyphs.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005071
Cary Clarkce101242017-09-01 15:51:02 -04005072#Param text character code points or Glyphs drawn ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005073#Param byteLength byte length of text array ##
5074#Param x start of text on x-axis ##
5075#Param y start of text on y-axis ##
5076#Param paint text size, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005077
5078#Example
5079#Height 200
5080#Description
5081 The same text is drawn varying Paint_Text_Size and varying
Herb Derbyefe39bc2018-05-01 17:06:20 -04005082 Matrix.
Cary Clark8032b982017-07-28 11:04:54 -04005083##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005084void draw(SkCanvas* canvas) {
5085 SkPaint paint;
5086 paint.setAntiAlias(true);
5087 float textSizes[] = { 12, 18, 24, 36 };
5088 for (auto size: textSizes ) {
5089 paint.setTextSize(size);
5090 canvas->drawText("Aa", 2, 10, 20, paint);
5091 canvas->translate(0, size * 2);
5092 }
5093 paint.reset();
5094 paint.setAntiAlias(true);
5095 float yPos = 20;
5096 for (auto size: textSizes ) {
5097 float scale = size / 12.f;
5098 canvas->resetMatrix();
5099 canvas->translate(100, 0);
5100 canvas->scale(scale, scale);
5101 canvas->drawText("Aa", 2, 10 / scale, yPos / scale, paint);
Herb Derbyefe39bc2018-05-01 17:06:20 -04005102 yPos += size * 2;
Cary Clarkbad5ad72017-08-03 17:14:08 -04005103 }
5104}
Cary Clark8032b982017-07-28 11:04:54 -04005105##
5106
Cary Clark2ade9972017-11-02 17:49:34 -04005107#SeeAlso drawString drawPosText drawPosTextH drawTextBlob drawTextOnPath drawTextRSXform
Cary Clark8032b982017-07-28 11:04:54 -04005108
5109##
5110
5111#Method void drawString(const char* string, SkScalar x, SkScalar y, const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05005112#In Draw_Text
5113#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05005114#Line # draws null terminated string at (x, y) using font advance ##
Cary Clark682c58d2018-05-16 07:07:07 -04005115Draws null terminated string, with origin at (x, y), using Clip, Matrix, and
5116Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04005117
Cary Clarkbc5697d2017-10-04 14:31:33 -04005118string meaning depends on Paint_Text_Encoding; by default, strings are encoded
5119as UTF-8. Other values of Paint_Text_Encoding are unlikely to produce the desired
Cary Clarkbad5ad72017-08-03 17:14:08 -04005120results, since zero bytes may be embedded in the string.
Cary Clark8032b982017-07-28 11:04:54 -04005121
Cary Clarkbad5ad72017-08-03 17:14:08 -04005122x and y meaning depends on Paint_Text_Align and Paint_Vertical_Text; by default
Cary Clarkbc5697d2017-10-04 14:31:33 -04005123string draws left to right, positioning the first glyph left side bearing at x
Herb Derbyefe39bc2018-05-01 17:06:20 -04005124and its baseline at y. Text size is affected by Matrix and Paint_Text_Size.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005125
Mike Reed8ad91a92018-01-19 19:09:32 -05005126All elements of paint: Path_Effect, Mask_Filter, Shader,
Cary Clarkbad5ad72017-08-03 17:14:08 -04005127Color_Filter, Image_Filter, and Draw_Looper; apply to text. By default, draws
Cary Clarkce101242017-09-01 15:51:02 -04005128filled 12 point black Glyphs.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005129
Cary Clarkce101242017-09-01 15:51:02 -04005130#Param string character code points or Glyphs drawn,
Cary Clarkbad5ad72017-08-03 17:14:08 -04005131 ending with a char value of zero
5132##
5133#Param x start of string on x-axis ##
5134#Param y start of string on y-axis ##
5135#Param paint text size, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005136
5137#Example
Cary Clarkffb3d682018-05-17 12:17:28 -04005138#Height 48
Cary Clark8032b982017-07-28 11:04:54 -04005139 SkPaint paint;
5140 canvas->drawString("a small hello", 20, 20, paint);
5141##
5142
Cary Clark2ade9972017-11-02 17:49:34 -04005143#SeeAlso drawText drawPosText drawPosTextH drawTextBlob drawTextOnPath drawTextRSXform
Cary Clark8032b982017-07-28 11:04:54 -04005144
5145##
5146
5147#Method void drawString(const SkString& string, SkScalar x, SkScalar y, const SkPaint& paint)
5148
Cary Clarkbad5ad72017-08-03 17:14:08 -04005149Draw null terminated string, with origin at (x, y), using Clip, Matrix, and
5150Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04005151
Cary Clarkbc5697d2017-10-04 14:31:33 -04005152string meaning depends on Paint_Text_Encoding; by default, strings are encoded
5153as UTF-8. Other values of Paint_Text_Encoding are unlikely to produce the desired
Cary Clarkbad5ad72017-08-03 17:14:08 -04005154results, since zero bytes may be embedded in the string.
Cary Clark8032b982017-07-28 11:04:54 -04005155
Cary Clarkbad5ad72017-08-03 17:14:08 -04005156x and y meaning depends on Paint_Text_Align and Paint_Vertical_Text; by default
Cary Clarkbc5697d2017-10-04 14:31:33 -04005157string draws left to right, positioning the first glyph left side bearing at x
Herb Derbyefe39bc2018-05-01 17:06:20 -04005158and its baseline at y. Text size is affected by Matrix and Paint_Text_Size.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005159
Mike Reed8ad91a92018-01-19 19:09:32 -05005160All elements of paint: Path_Effect, Mask_Filter, Shader,
Cary Clarkbad5ad72017-08-03 17:14:08 -04005161Color_Filter, Image_Filter, and Draw_Looper; apply to text. By default, draws
Cary Clarkce101242017-09-01 15:51:02 -04005162filled 12 point black Glyphs.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005163
Cary Clarkce101242017-09-01 15:51:02 -04005164#Param string character code points or Glyphs drawn,
Cary Clarkbad5ad72017-08-03 17:14:08 -04005165 ending with a char value of zero
5166##
5167#Param x start of string on x-axis ##
5168#Param y start of string on y-axis ##
5169#Param paint text size, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005170
5171#Example
5172 SkPaint paint;
5173 SkString string("a small hello");
5174 canvas->drawString(string, 20, 20, paint);
5175##
5176
Cary Clark2ade9972017-11-02 17:49:34 -04005177#SeeAlso drawText drawPosText drawPosTextH drawTextBlob drawTextOnPath drawTextRSXform
Cary Clark8032b982017-07-28 11:04:54 -04005178
5179##
5180
5181# ------------------------------------------------------------------------------
5182
5183#Method void drawPosText(const void* text, size_t byteLength, const SkPoint pos[],
5184 const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05005185#In Draw_Text
5186#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05005187#Line # draws text at array of (x, y) positions ##
Cary Clark8032b982017-07-28 11:04:54 -04005188
Cary Clarkbad5ad72017-08-03 17:14:08 -04005189Draw each glyph in text with the origin in pos array, using Clip, Matrix, and
Cary Clarkce101242017-09-01 15:51:02 -04005190Paint paint. The number of entries in pos array must match the number of Glyphs
Cary Clarkbad5ad72017-08-03 17:14:08 -04005191described by byteLength of text.
Cary Clark8032b982017-07-28 11:04:54 -04005192
Cary Clarkbc5697d2017-10-04 14:31:33 -04005193text meaning depends on Paint_Text_Encoding; by default, text is encoded as
Cary Clark137b8742018-05-30 09:21:49 -04005194UTF-8. pos elements meaning depends on Paint_Vertical_Text;
Cary Clarkbc5697d2017-10-04 14:31:33 -04005195by default each glyph left side bearing is positioned at x and its
Cary Clarkbad5ad72017-08-03 17:14:08 -04005196baseline is positioned at y. Text size is affected by Matrix and
Herb Derbyefe39bc2018-05-01 17:06:20 -04005197Paint_Text_Size.
Cary Clark8032b982017-07-28 11:04:54 -04005198
Mike Reed8ad91a92018-01-19 19:09:32 -05005199All elements of paint: Path_Effect, Mask_Filter, Shader,
Cary Clarkbad5ad72017-08-03 17:14:08 -04005200Color_Filter, Image_Filter, and Draw_Looper; apply to text. By default, draws
Cary Clarkce101242017-09-01 15:51:02 -04005201filled 12 point black Glyphs.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005202
5203Layout engines such as Harfbuzz typically position each glyph
Cary Clarkbc5697d2017-10-04 14:31:33 -04005204rather than using the font advance widths.
Cary Clark8032b982017-07-28 11:04:54 -04005205
Cary Clarkce101242017-09-01 15:51:02 -04005206#Param text character code points or Glyphs drawn ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005207#Param byteLength byte length of text array ##
5208#Param pos array of glyph origins ##
5209#Param paint text size, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005210
5211#Example
5212#Height 120
Cary Clarkbad5ad72017-08-03 17:14:08 -04005213void draw(SkCanvas* canvas) {
5214 const char hello[] = "HeLLo!";
5215 const SkPoint pos[] = { {40, 100}, {82, 95}, {115, 110}, {130, 95}, {145, 85},
5216 {172, 100} };
5217 SkPaint paint;
5218 paint.setTextSize(60);
5219 canvas->drawPosText(hello, strlen(hello), pos, paint);
Cary Clark8032b982017-07-28 11:04:54 -04005220}
5221##
5222
Cary Clark2ade9972017-11-02 17:49:34 -04005223#SeeAlso drawText drawPosTextH drawTextBlob drawTextOnPath drawTextRSXform
Cary Clark8032b982017-07-28 11:04:54 -04005224
5225##
5226
5227# ------------------------------------------------------------------------------
5228
5229#Method void drawPosTextH(const void* text, size_t byteLength, const SkScalar xpos[], SkScalar constY,
5230 const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05005231#In Draw_Text
5232#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05005233#Line # draws text at x positions with common baseline ##
Cary Clark8032b982017-07-28 11:04:54 -04005234
Cary Clarkbad5ad72017-08-03 17:14:08 -04005235Draw each glyph in text with its (x, y) origin composed from xpos array and
5236constY, using Clip, Matrix, and Paint paint. The number of entries in xpos array
Cary Clarkce101242017-09-01 15:51:02 -04005237must match the number of Glyphs described by byteLength of text.
Cary Clark8032b982017-07-28 11:04:54 -04005238
Cary Clarkbc5697d2017-10-04 14:31:33 -04005239text meaning depends on Paint_Text_Encoding; by default, text is encoded as
Cary Clark137b8742018-05-30 09:21:49 -04005240UTF-8. xpos elements meaning depends on Paint_Vertical_Text;
Cary Clarkbc5697d2017-10-04 14:31:33 -04005241by default each glyph left side bearing is positioned at an xpos element and
Cary Clarkbad5ad72017-08-03 17:14:08 -04005242its baseline is positioned at constY. Text size is affected by Matrix and
Herb Derbyefe39bc2018-05-01 17:06:20 -04005243Paint_Text_Size.
Cary Clark8032b982017-07-28 11:04:54 -04005244
Mike Reed8ad91a92018-01-19 19:09:32 -05005245All elements of paint: Path_Effect, Mask_Filter, Shader,
Cary Clarkbad5ad72017-08-03 17:14:08 -04005246Color_Filter, Image_Filter, and Draw_Looper; apply to text. By default, draws
Cary Clarkce101242017-09-01 15:51:02 -04005247filled 12 point black Glyphs.
Cary Clark8032b982017-07-28 11:04:54 -04005248
Cary Clarkbad5ad72017-08-03 17:14:08 -04005249Layout engines such as Harfbuzz typically position each glyph
Cary Clarkbc5697d2017-10-04 14:31:33 -04005250rather than using the font advance widths if all Glyphs share the same
Cary Clarkbad5ad72017-08-03 17:14:08 -04005251baseline.
5252
Cary Clarkce101242017-09-01 15:51:02 -04005253#Param text character code points or Glyphs drawn ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005254#Param byteLength byte length of text array ##
5255#Param xpos array of x positions, used to position each glyph ##
5256#Param constY shared y coordinate for all of x positions ##
5257#Param paint text size, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005258
5259#Example
5260#Height 40
Cary Clarkbad5ad72017-08-03 17:14:08 -04005261 void draw(SkCanvas* canvas) {
5262 SkScalar xpos[] = { 20, 40, 80, 160 };
5263 SkPaint paint;
5264 canvas->drawPosTextH("XXXX", 4, xpos, 20, paint);
5265 }
Cary Clark8032b982017-07-28 11:04:54 -04005266##
5267
Cary Clark2ade9972017-11-02 17:49:34 -04005268#SeeAlso drawText drawPosText drawTextBlob drawTextOnPath drawTextRSXform
Cary Clark8032b982017-07-28 11:04:54 -04005269
5270##
5271
5272# ------------------------------------------------------------------------------
5273
5274#Method void drawTextOnPathHV(const void* text, size_t byteLength, const SkPath& path, SkScalar hOffset,
5275 SkScalar vOffset, const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05005276#In Draw_Text
5277#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05005278#Line # draws text following Path with offsets ##
Cary Clark8032b982017-07-28 11:04:54 -04005279
5280Draw text on Path path, using Clip, Matrix, and Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04005281
Cary Clarkbad5ad72017-08-03 17:14:08 -04005282Origin of text is at distance hOffset along the path, offset by a perpendicular
5283vector of length vOffset. If the path section corresponding the glyph advance is
5284curved, the glyph is drawn curved to match; control points in the glyph are
Cary Clarkbc5697d2017-10-04 14:31:33 -04005285mapped to projected points parallel to the path. If the text advance is larger
Cary Clarkbad5ad72017-08-03 17:14:08 -04005286than the path length, the excess text is clipped.
5287
Cary Clarkbc5697d2017-10-04 14:31:33 -04005288text meaning depends on Paint_Text_Encoding; by default, text is encoded as
Cary Clarkbad5ad72017-08-03 17:14:08 -04005289UTF-8. Origin meaning depends on Paint_Text_Align and Paint_Vertical_Text; by
Cary Clarkbc5697d2017-10-04 14:31:33 -04005290default text positions the first glyph left side bearing at origin x and its
Herb Derbyefe39bc2018-05-01 17:06:20 -04005291baseline at origin y. Text size is affected by Matrix and Paint_Text_Size.
Cary Clark8032b982017-07-28 11:04:54 -04005292
Mike Reed8ad91a92018-01-19 19:09:32 -05005293All elements of paint: Path_Effect, Mask_Filter, Shader,
Cary Clarkbad5ad72017-08-03 17:14:08 -04005294Color_Filter, Image_Filter, and Draw_Looper; apply to text. By default, draws
Cary Clarkce101242017-09-01 15:51:02 -04005295filled 12 point black Glyphs.
Cary Clark8032b982017-07-28 11:04:54 -04005296
Cary Clarkce101242017-09-01 15:51:02 -04005297#Param text character code points or Glyphs drawn ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005298#Param byteLength byte length of text array ##
5299#Param path Path providing text baseline ##
5300#Param hOffset distance along path to offset origin ##
5301#Param vOffset offset of text above (if negative) or below (if positive) the path ##
5302#Param paint text size, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005303
5304#Example
Herb Derbyefe39bc2018-05-01 17:06:20 -04005305 void draw(SkCanvas* canvas) {
Cary Clarkbad5ad72017-08-03 17:14:08 -04005306 const char aero[] = "correo a" "\xC3" "\xA9" "reo";
5307 const size_t len = sizeof(aero) - 1;
5308 SkPath path;
5309 path.addOval({43-26, 43-26, 43+26, 43+26}, SkPath::kCW_Direction, 3);
5310 SkPaint paint;
5311 paint.setTextSize(24);
5312 for (auto offset : { 0, 10, 20 } ) {
5313 canvas->drawTextOnPathHV(aero, len, path, 0, -offset, paint);
5314 canvas->translate(70 + offset, 70 + offset);
5315 }
5316 }
Cary Clark8032b982017-07-28 11:04:54 -04005317##
5318
Cary Clark2ade9972017-11-02 17:49:34 -04005319#SeeAlso drawTextOnPath drawText drawPosTextH drawTextBlob drawTextRSXform
Cary Clark8032b982017-07-28 11:04:54 -04005320
5321##
5322
5323# ------------------------------------------------------------------------------
5324
5325#Method void drawTextOnPath(const void* text, size_t byteLength, const SkPath& path,
5326 const SkMatrix* matrix, const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05005327#In Draw_Text
5328#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05005329#Line # draws text following Path contour ##
Cary Clark8032b982017-07-28 11:04:54 -04005330
5331Draw text on Path path, using Clip, Matrix, and Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04005332
Cary Clark682c58d2018-05-16 07:07:07 -04005333Origin of text is at beginning of path offset by matrix, if not nullptr.
Cary Clark137b8742018-05-30 09:21:49 -04005334matrix transforms text before text is mapped to path. If the path section
Cary Clark682c58d2018-05-16 07:07:07 -04005335corresponding the glyph advance is curved, the glyph is drawn curved to match;
5336control points in the glyph are mapped to projected points parallel to the path.
5337If the text advance is larger than the path length, the excess text is clipped.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005338
Cary Clark137b8742018-05-30 09:21:49 -04005339matrix does not effect paint Shader.
5340
Cary Clarkbc5697d2017-10-04 14:31:33 -04005341text meaning depends on Paint_Text_Encoding; by default, text is encoded as
Cary Clarkbad5ad72017-08-03 17:14:08 -04005342UTF-8. Origin meaning depends on Paint_Text_Align and Paint_Vertical_Text; by
Cary Clarkbc5697d2017-10-04 14:31:33 -04005343default text positions the first glyph left side bearing at origin x and its
Cary Clark137b8742018-05-30 09:21:49 -04005344baseline at origin y. Text size is affected by matrix parameter, Canvas Matrix,
Cary Clark682c58d2018-05-16 07:07:07 -04005345and Paint_Text_Size.
Cary Clark8032b982017-07-28 11:04:54 -04005346
Mike Reed8ad91a92018-01-19 19:09:32 -05005347All elements of paint: Path_Effect, Mask_Filter, Shader,
Cary Clarkbad5ad72017-08-03 17:14:08 -04005348Color_Filter, Image_Filter, and Draw_Looper; apply to text. By default, draws
Cary Clark137b8742018-05-30 09:21:49 -04005349filled 12 point black Glyphs.
Cary Clark8032b982017-07-28 11:04:54 -04005350
Cary Clarkce101242017-09-01 15:51:02 -04005351#Param text character code points or Glyphs drawn ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005352#Param byteLength byte length of text array ##
5353#Param path Path providing text baseline ##
Cary Clarkce101242017-09-01 15:51:02 -04005354#Param matrix transform of Glyphs before mapping to path; may be nullptr
Cary Clarka523d2d2017-08-30 08:58:10 -04005355 to use identity Matrix
Cary Clarkbad5ad72017-08-03 17:14:08 -04005356##
5357#Param paint text size, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005358
5359#Example
Herb Derbyefe39bc2018-05-01 17:06:20 -04005360 void draw(SkCanvas* canvas) {
Cary Clarkbad5ad72017-08-03 17:14:08 -04005361 const char roller[] = "rollercoaster";
5362 const size_t len = sizeof(roller) - 1;
5363 SkPath path;
5364 path.cubicTo(40, -80, 120, 80, 160, -40);
5365 SkPaint paint;
5366 paint.setTextSize(32);
5367 paint.setStyle(SkPaint::kStroke_Style);
5368 SkMatrix matrix;
5369 matrix.setIdentity();
5370 for (int i = 0; i < 3; ++i) {
5371 canvas->translate(25, 60);
5372 canvas->drawPath(path, paint);
5373 canvas->drawTextOnPath(roller, len, path, &matrix, paint);
5374 matrix.preTranslate(0, 10);
5375 }
5376 }
Cary Clark8032b982017-07-28 11:04:54 -04005377##
5378
Cary Clark2ade9972017-11-02 17:49:34 -04005379#SeeAlso drawTextOnPathHV drawText drawPosTextH drawTextBlob drawTextRSXform
Cary Clark8032b982017-07-28 11:04:54 -04005380
5381##
5382
5383# ------------------------------------------------------------------------------
5384
5385#Method void drawTextRSXform(const void* text, size_t byteLength, const SkRSXform xform[],
5386 const SkRect* cullRect, const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05005387#In Draw_Text
5388#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05005389#Line # draws text with array of RSXform ##
Cary Clark8032b982017-07-28 11:04:54 -04005390
5391Draw text, transforming each glyph by the corresponding SkRSXform,
5392using Clip, Matrix, and Paint paint.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005393
Cary Clark137b8742018-05-30 09:21:49 -04005394RSXform xform array specifies a separate square scale, rotation, and translation
5395for each glyph. xform does not affect paint Shader.
Cary Clark8032b982017-07-28 11:04:54 -04005396
Cary Clarkbad5ad72017-08-03 17:14:08 -04005397Optional Rect cullRect is a conservative bounds of text, taking into account
Cary Clarkce101242017-09-01 15:51:02 -04005398RSXform and paint. If cullRect is outside of Clip, canvas can skip drawing.
Cary Clark8032b982017-07-28 11:04:54 -04005399
Mike Reed8ad91a92018-01-19 19:09:32 -05005400All elements of paint: Path_Effect, Mask_Filter, Shader,
Cary Clarkbad5ad72017-08-03 17:14:08 -04005401Color_Filter, Image_Filter, and Draw_Looper; apply to text. By default, draws
Cary Clarkce101242017-09-01 15:51:02 -04005402filled 12 point black Glyphs.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005403
Cary Clarkce101242017-09-01 15:51:02 -04005404#Param text character code points or Glyphs drawn ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005405#Param byteLength byte length of text array ##
5406#Param xform RSXform rotates, scales, and translates each glyph individually ##
5407#Param cullRect Rect bounds of text for efficient clipping; or nullptr ##
5408#Param paint text size, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005409
5410#Example
Herb Derbyefe39bc2018-05-01 17:06:20 -04005411void draw(SkCanvas* canvas) {
Cary Clarkbad5ad72017-08-03 17:14:08 -04005412 const int iterations = 26;
5413 SkRSXform transforms[iterations];
5414 char alphabet[iterations];
5415 SkScalar angle = 0;
5416 SkScalar scale = 1;
5417 for (size_t i = 0; i < SK_ARRAY_COUNT(transforms); ++i) {
5418 const SkScalar s = SkScalarSin(angle) * scale;
5419 const SkScalar c = SkScalarCos(angle) * scale;
5420 transforms[i] = SkRSXform::Make(-c, -s, -s * 16, c * 16);
5421 angle += .45;
5422 scale += .2;
5423 alphabet[i] = 'A' + i;
5424 }
5425 SkPaint paint;
5426 paint.setTextAlign(SkPaint::kCenter_Align);
5427 canvas->translate(110, 138);
5428 canvas->drawTextRSXform(alphabet, sizeof(alphabet), transforms, nullptr, paint);
Cary Clark8032b982017-07-28 11:04:54 -04005429}
5430##
5431
Cary Clark2ade9972017-11-02 17:49:34 -04005432#SeeAlso drawTextOnPath drawTextOnPathHV drawText drawPosText drawTextBlob
Cary Clark8032b982017-07-28 11:04:54 -04005433
5434##
5435
5436# ------------------------------------------------------------------------------
5437
5438#Method void drawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y, const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05005439#In Draw_Text
5440#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05005441#Line # draws text with arrays of positions and Paint ##
Cary Clark8032b982017-07-28 11:04:54 -04005442Draw Text_Blob blob at (x, y), using Clip, Matrix, and Paint paint.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005443
Cary Clarkce101242017-09-01 15:51:02 -04005444blob contains Glyphs, their positions, and paint attributes specific to text:
Cary Clarkbad5ad72017-08-03 17:14:08 -04005445Typeface, Paint_Text_Size, Paint_Text_Scale_X, Paint_Text_Skew_X,
Cary Clarkffb3d682018-05-17 12:17:28 -04005446Paint_Text_Align, Paint_Hinting, Anti_Alias, Paint_Fake_Bold,
Cary Clarkbad5ad72017-08-03 17:14:08 -04005447Font_Embedded_Bitmaps, Full_Hinting_Spacing, LCD_Text, Linear_Text,
5448Subpixel_Text, and Paint_Vertical_Text.
Cary Clark8032b982017-07-28 11:04:54 -04005449
Cary Clark3cd22cc2017-12-01 11:49:58 -05005450Paint_Text_Encoding must be set to SkPaint::kGlyphID_TextEncoding.
5451
Mike Reed8ad91a92018-01-19 19:09:32 -05005452Elements of paint: Path_Effect, Mask_Filter, Shader, Color_Filter,
Cary Clark8032b982017-07-28 11:04:54 -04005453Image_Filter, and Draw_Looper; apply to blob.
5454
Cary Clarkce101242017-09-01 15:51:02 -04005455#Param blob Glyphs, positions, and their paints' text size, typeface, and so on ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005456#Param x horizontal offset applied to blob ##
5457#Param y vertical offset applied to blob ##
5458#Param paint blend, color, stroking, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005459
5460#Example
5461#Height 120
Cary Clarkbad5ad72017-08-03 17:14:08 -04005462 void draw(SkCanvas* canvas) {
Cary Clark2f466242017-12-11 16:03:17 -05005463 SkTextBlobBuilder textBlobBuilder;
5464 const char bunny[] = "/(^x^)\\";
5465 const int len = sizeof(bunny) - 1;
5466 uint16_t glyphs[len];
5467 SkPaint paint;
5468 paint.textToGlyphs(bunny, len, glyphs);
Cary Clark3cd22cc2017-12-01 11:49:58 -05005469 paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
Cary Clark2f466242017-12-11 16:03:17 -05005470 int runs[] = { 3, 1, 3 };
5471 SkPoint textPos = { 20, 100 };
5472 int glyphIndex = 0;
5473 for (auto runLen : runs) {
5474 paint.setTextSize(1 == runLen ? 20 : 50);
Herb Derbyefe39bc2018-05-01 17:06:20 -04005475 const SkTextBlobBuilder::RunBuffer& run =
Cary Clark2f466242017-12-11 16:03:17 -05005476 textBlobBuilder.allocRun(paint, runLen, textPos.fX, textPos.fY);
5477 memcpy(run.glyphs, &glyphs[glyphIndex], sizeof(glyphs[0]) * runLen);
5478 textPos.fX += paint.measureText(&glyphs[glyphIndex], sizeof(glyphs[0]) * runLen, nullptr);
5479 glyphIndex += runLen;
5480 }
5481 sk_sp<const SkTextBlob> blob = textBlobBuilder.make();
5482 paint.reset();
Cary Clarkbad5ad72017-08-03 17:14:08 -04005483 canvas->drawTextBlob(blob.get(), 0, 0, paint);
Cary Clark8032b982017-07-28 11:04:54 -04005484 }
5485##
5486
Cary Clark2ade9972017-11-02 17:49:34 -04005487#SeeAlso drawText drawPosText drawPosTextH
Cary Clark8032b982017-07-28 11:04:54 -04005488
5489##
5490
5491# ------------------------------------------------------------------------------
5492
Herb Derbyefe39bc2018-05-01 17:06:20 -04005493#Method void drawTextBlob(const sk_sp<SkTextBlob>& blob, SkScalar x, SkScalar y, const SkPaint& paint)
Cary Clark8032b982017-07-28 11:04:54 -04005494
5495Draw Text_Blob blob at (x, y), using Clip, Matrix, and Paint paint.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005496
Cary Clarkce101242017-09-01 15:51:02 -04005497blob contains Glyphs, their positions, and paint attributes specific to text:
Cary Clarkbad5ad72017-08-03 17:14:08 -04005498Typeface, Paint_Text_Size, Paint_Text_Scale_X, Paint_Text_Skew_X,
Cary Clarkffb3d682018-05-17 12:17:28 -04005499Paint_Text_Align, Paint_Hinting, Anti_Alias, Paint_Fake_Bold,
Cary Clarkbad5ad72017-08-03 17:14:08 -04005500Font_Embedded_Bitmaps, Full_Hinting_Spacing, LCD_Text, Linear_Text,
5501Subpixel_Text, and Paint_Vertical_Text.
Cary Clark8032b982017-07-28 11:04:54 -04005502
Cary Clark3cd22cc2017-12-01 11:49:58 -05005503Paint_Text_Encoding must be set to SkPaint::kGlyphID_TextEncoding.
5504
Herb Derbyefe39bc2018-05-01 17:06:20 -04005505Elements of paint: Path_Effect, Mask_Filter, Shader, Color_Filter,
Cary Clark8032b982017-07-28 11:04:54 -04005506Image_Filter, and Draw_Looper; apply to blob.
5507
Cary Clarkce101242017-09-01 15:51:02 -04005508#Param blob Glyphs, positions, and their paints' text size, typeface, and so on ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005509#Param x horizontal offset applied to blob ##
5510#Param y vertical offset applied to blob ##
5511#Param paint blend, color, stroking, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005512
5513#Example
5514#Height 120
5515#Description
5516Paint attributes unrelated to text, like color, have no effect on paint in allocated Text_Blob.
5517Paint attributes related to text, like text size, have no effect on paint passed to drawTextBlob.
5518##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005519 void draw(SkCanvas* canvas) {
5520 SkTextBlobBuilder textBlobBuilder;
5521 SkPaint paint;
5522 paint.setTextSize(50);
5523 paint.setColor(SK_ColorRED);
Cary Clark2f466242017-12-11 16:03:17 -05005524 paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
Herb Derbyefe39bc2018-05-01 17:06:20 -04005525 const SkTextBlobBuilder::RunBuffer& run =
Cary Clarkbad5ad72017-08-03 17:14:08 -04005526 textBlobBuilder.allocRun(paint, 1, 20, 100);
5527 run.glyphs[0] = 20;
5528 sk_sp<const SkTextBlob> blob = textBlobBuilder.make();
5529 paint.setTextSize(10);
5530 paint.setColor(SK_ColorBLUE);
5531 canvas->drawTextBlob(blob.get(), 0, 0, paint);
5532 }
Cary Clark8032b982017-07-28 11:04:54 -04005533##
5534
Cary Clark2ade9972017-11-02 17:49:34 -04005535#SeeAlso drawText drawPosText drawPosTextH
Cary Clark8032b982017-07-28 11:04:54 -04005536
5537##
5538
5539# ------------------------------------------------------------------------------
5540
Herb Derbyefe39bc2018-05-01 17:06:20 -04005541#Method void drawPicture(const SkPicture* picture)
Cary Clark78de7512018-02-07 07:27:09 -05005542#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05005543#Line # draws Picture using Clip and Matrix ##
Cary Clark8032b982017-07-28 11:04:54 -04005544Draw Picture picture, using Clip and Matrix.
5545Clip and Matrix are unchanged by picture contents, as if
5546save() was called before and restore() was called after drawPicture.
5547
5548Picture records a series of draw commands for later playback.
5549
Cary Clarkbad5ad72017-08-03 17:14:08 -04005550#Param picture recorded drawing commands to play ##
Cary Clark8032b982017-07-28 11:04:54 -04005551
5552#Example
Herb Derbyefe39bc2018-05-01 17:06:20 -04005553void draw(SkCanvas* canvas) {
Cary Clarkbad5ad72017-08-03 17:14:08 -04005554 SkPictureRecorder recorder;
5555 SkCanvas* recordingCanvas = recorder.beginRecording(50, 50);
5556 for (auto color : { SK_ColorRED, SK_ColorBLUE, 0xff007f00 } ) {
5557 SkPaint paint;
5558 paint.setColor(color);
5559 recordingCanvas->drawRect({10, 10, 30, 40}, paint);
5560 recordingCanvas->translate(10, 10);
5561 recordingCanvas->scale(1.2f, 1.4f);
5562 }
5563 sk_sp<SkPicture> playback = recorder.finishRecordingAsPicture();
Cary Clarkbad5ad72017-08-03 17:14:08 -04005564 canvas->drawPicture(playback);
5565 canvas->scale(2, 2);
5566 canvas->translate(50, 0);
5567 canvas->drawPicture(playback);
Cary Clark8032b982017-07-28 11:04:54 -04005568}
5569##
5570
Cary Clark2ade9972017-11-02 17:49:34 -04005571#SeeAlso drawDrawable SkPicture SkPicture::playback
Cary Clark8032b982017-07-28 11:04:54 -04005572
5573##
5574
5575# ------------------------------------------------------------------------------
5576
Herb Derbyefe39bc2018-05-01 17:06:20 -04005577#Method void drawPicture(const sk_sp<SkPicture>& picture)
Cary Clark8032b982017-07-28 11:04:54 -04005578
5579Draw Picture picture, using Clip and Matrix.
5580Clip and Matrix are unchanged by picture contents, as if
5581save() was called before and restore() was called after drawPicture.
5582
5583Picture records a series of draw commands for later playback.
5584
Cary Clarkbad5ad72017-08-03 17:14:08 -04005585#Param picture recorded drawing commands to play ##
Cary Clark8032b982017-07-28 11:04:54 -04005586
5587#Example
Herb Derbyefe39bc2018-05-01 17:06:20 -04005588void draw(SkCanvas* canvas) {
Cary Clarkbad5ad72017-08-03 17:14:08 -04005589 SkPictureRecorder recorder;
5590 SkCanvas* recordingCanvas = recorder.beginRecording(50, 50);
5591 for (auto color : { SK_ColorRED, SK_ColorBLUE, 0xff007f00 } ) {
5592 SkPaint paint;
5593 paint.setColor(color);
5594 recordingCanvas->drawRect({10, 10, 30, 40}, paint);
5595 recordingCanvas->translate(10, 10);
5596 recordingCanvas->scale(1.2f, 1.4f);
5597 }
5598 sk_sp<SkPicture> playback = recorder.finishRecordingAsPicture();
5599 canvas->drawPicture(playback);
5600 canvas->scale(2, 2);
5601 canvas->translate(50, 0);
5602 canvas->drawPicture(playback);
Cary Clark8032b982017-07-28 11:04:54 -04005603}
5604##
5605
Cary Clark2ade9972017-11-02 17:49:34 -04005606#SeeAlso drawDrawable SkPicture SkPicture::playback
Cary Clark8032b982017-07-28 11:04:54 -04005607
5608##
5609
5610# ------------------------------------------------------------------------------
5611
5612#Method void drawPicture(const SkPicture* picture, const SkMatrix* matrix, const SkPaint* paint)
5613
Cary Clarkbad5ad72017-08-03 17:14:08 -04005614Draw Picture picture, using Clip and Matrix; transforming picture with
5615Matrix matrix, if provided; and use Paint paint Color_Alpha, Color_Filter,
5616Image_Filter, and Blend_Mode, if provided.
Cary Clark8032b982017-07-28 11:04:54 -04005617
5618matrix transformation is equivalent to: save(), concat(), drawPicture, restore().
5619paint use is equivalent to: saveLayer, drawPicture, restore().
5620
Cary Clarkbad5ad72017-08-03 17:14:08 -04005621#Param picture recorded drawing commands to play ##
5622#Param matrix Matrix to rotate, scale, translate, and so on; may be nullptr ##
5623#Param paint Paint to apply transparency, filtering, and so on; may be nullptr ##
Cary Clark8032b982017-07-28 11:04:54 -04005624
5625#Example
Herb Derbyefe39bc2018-05-01 17:06:20 -04005626void draw(SkCanvas* canvas) {
Cary Clarkbad5ad72017-08-03 17:14:08 -04005627 SkPaint paint;
5628 SkPictureRecorder recorder;
5629 SkCanvas* recordingCanvas = recorder.beginRecording(50, 50);
5630 for (auto color : { SK_ColorRED, SK_ColorBLUE, 0xff007f00 } ) {
5631 paint.setColor(color);
5632 recordingCanvas->drawRect({10, 10, 30, 40}, paint);
5633 recordingCanvas->translate(10, 10);
5634 recordingCanvas->scale(1.2f, 1.4f);
5635 }
5636 sk_sp<SkPicture> playback = recorder.finishRecordingAsPicture();
5637 const SkPicture* playbackPtr = playback.get();
5638 SkMatrix matrix;
5639 matrix.reset();
5640 for (auto alpha : { 70, 140, 210 } ) {
5641 paint.setAlpha(alpha);
5642 canvas->drawPicture(playbackPtr, &matrix, &paint);
5643 matrix.preTranslate(70, 70);
5644 }
Cary Clark8032b982017-07-28 11:04:54 -04005645}
5646##
5647
Cary Clark2ade9972017-11-02 17:49:34 -04005648#SeeAlso drawDrawable SkPicture SkPicture::playback
Cary Clark8032b982017-07-28 11:04:54 -04005649
5650##
5651
5652# ------------------------------------------------------------------------------
5653
Herb Derbyefe39bc2018-05-01 17:06:20 -04005654#Method void drawPicture(const sk_sp<SkPicture>& picture, const SkMatrix* matrix, const SkPaint* paint)
Cary Clark8032b982017-07-28 11:04:54 -04005655
Cary Clarkbad5ad72017-08-03 17:14:08 -04005656Draw Picture picture, using Clip and Matrix; transforming picture with
5657Matrix matrix, if provided; and use Paint paint Color_Alpha, Color_Filter,
5658Image_Filter, and Blend_Mode, if provided.
Cary Clark8032b982017-07-28 11:04:54 -04005659
5660matrix transformation is equivalent to: save(), concat(), drawPicture, restore().
5661paint use is equivalent to: saveLayer, drawPicture, restore().
5662
Cary Clarkbad5ad72017-08-03 17:14:08 -04005663#Param picture recorded drawing commands to play ##
5664#Param matrix Matrix to rotate, scale, translate, and so on; may be nullptr ##
5665#Param paint Paint to apply transparency, filtering, and so on; may be nullptr ##
Cary Clark8032b982017-07-28 11:04:54 -04005666
5667#Example
Herb Derbyefe39bc2018-05-01 17:06:20 -04005668void draw(SkCanvas* canvas) {
Cary Clarkbad5ad72017-08-03 17:14:08 -04005669 SkPaint paint;
5670 SkPictureRecorder recorder;
5671 SkCanvas* recordingCanvas = recorder.beginRecording(50, 50);
5672 for (auto color : { SK_ColorRED, SK_ColorBLUE, 0xff007f00 } ) {
5673 paint.setColor(color);
5674 recordingCanvas->drawRect({10, 10, 30, 40}, paint);
5675 recordingCanvas->translate(10, 10);
5676 recordingCanvas->scale(1.2f, 1.4f);
5677 }
5678 sk_sp<SkPicture> playback = recorder.finishRecordingAsPicture();
5679 SkMatrix matrix;
5680 matrix.reset();
5681 for (auto alpha : { 70, 140, 210 } ) {
5682 paint.setAlpha(alpha);
5683 canvas->drawPicture(playback, &matrix, &paint);
5684 matrix.preTranslate(70, 70);
5685 }
Cary Clark8032b982017-07-28 11:04:54 -04005686}
5687##
5688
Cary Clark2ade9972017-11-02 17:49:34 -04005689#SeeAlso drawDrawable SkPicture SkPicture::playback
Cary Clark8032b982017-07-28 11:04:54 -04005690
5691##
5692
5693# ------------------------------------------------------------------------------
5694
5695#Method void drawVertices(const SkVertices* vertices, SkBlendMode mode, const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05005696#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05005697#Line # draws Vertices, a triangle mesh ##
Cary Clark8032b982017-07-28 11:04:54 -04005698Draw Vertices vertices, a triangle mesh, using Clip and Matrix.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005699If Vertices_Texs and Vertices_Colors are defined in vertices, and Paint paint
5700contains Shader, Blend_Mode mode combines Vertices_Colors with Shader.
Cary Clark8032b982017-07-28 11:04:54 -04005701
Cary Clarkbad5ad72017-08-03 17:14:08 -04005702#Param vertices triangle mesh to draw ##
5703#Param mode combines Vertices_Colors with Shader, if both are present ##
5704#Param paint specifies the Shader, used as Vertices texture; may be nullptr ##
Cary Clark8032b982017-07-28 11:04:54 -04005705
5706#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04005707void draw(SkCanvas* canvas) {
5708 SkPaint paint;
5709 SkPoint points[] = { { 0, 0 }, { 250, 0 }, { 100, 100 }, { 0, 250 } };
5710 SkColor colors[] = { SK_ColorRED, SK_ColorBLUE, SK_ColorYELLOW, SK_ColorCYAN };
5711 auto vertices = SkVertices::MakeCopy(SkVertices::kTriangleFan_VertexMode,
5712 SK_ARRAY_COUNT(points), points, nullptr, colors);
5713 canvas->drawVertices(vertices.get(), SkBlendMode::kSrc, paint);
5714}
Cary Clark8032b982017-07-28 11:04:54 -04005715##
5716
Cary Clark2ade9972017-11-02 17:49:34 -04005717#SeeAlso drawPatch drawPicture
Cary Clark8032b982017-07-28 11:04:54 -04005718
5719##
5720
5721# ------------------------------------------------------------------------------
5722
5723#Method void drawVertices(const sk_sp<SkVertices>& vertices, SkBlendMode mode, const SkPaint& paint)
5724
5725Draw Vertices vertices, a triangle mesh, using Clip and Matrix.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005726If Vertices_Texs and Vertices_Colors are defined in vertices, and Paint paint
5727contains Shader, Blend_Mode mode combines Vertices_Colors with Shader.
Cary Clark8032b982017-07-28 11:04:54 -04005728
Cary Clarkbad5ad72017-08-03 17:14:08 -04005729#Param vertices triangle mesh to draw ##
5730#Param mode combines Vertices_Colors with Shader, if both are present ##
5731#Param paint specifies the Shader, used as Vertices texture, may be nullptr ##
Cary Clark8032b982017-07-28 11:04:54 -04005732
5733#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04005734void draw(SkCanvas* canvas) {
5735 SkPaint paint;
5736 SkPoint points[] = { { 0, 0 }, { 250, 0 }, { 100, 100 }, { 0, 250 } };
5737 SkPoint texs[] = { { 0, 0 }, { 0, 250 }, { 250, 250 }, { 250, 0 } };
5738 SkColor colors[] = { SK_ColorRED, SK_ColorBLUE, SK_ColorYELLOW, SK_ColorCYAN };
5739 paint.setShader(SkGradientShader::MakeLinear(points, colors, nullptr, 4,
5740 SkShader::kClamp_TileMode));
5741 auto vertices = SkVertices::MakeCopy(SkVertices::kTriangleFan_VertexMode,
5742 SK_ARRAY_COUNT(points), points, texs, colors);
5743 canvas->drawVertices(vertices.get(), SkBlendMode::kDarken, paint);
Cary Clark8032b982017-07-28 11:04:54 -04005744}
5745##
5746
Cary Clark2ade9972017-11-02 17:49:34 -04005747#SeeAlso drawPatch drawPicture
Cary Clark8032b982017-07-28 11:04:54 -04005748
5749##
5750
5751# ------------------------------------------------------------------------------
5752
5753#Method void drawPatch(const SkPoint cubics[12], const SkColor colors[4],
5754 const SkPoint texCoords[4], SkBlendMode mode, const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05005755#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05005756#Line # draws Coons_Patch ##
Cary Clark8032b982017-07-28 11:04:54 -04005757
Herb Derbyefe39bc2018-05-01 17:06:20 -04005758Draws a Coons_Patch: the interpolation of four cubics with shared corners,
Cary Clark8032b982017-07-28 11:04:54 -04005759associating a color, and optionally a texture coordinate, with each corner.
5760
Cary Clarka560c472017-11-27 10:44:06 -05005761Coons_Patch uses Clip and Matrix, paint Shader, Color_Filter,
Cary Clarkbad5ad72017-08-03 17:14:08 -04005762Color_Alpha, Image_Filter, and Blend_Mode. If Shader is provided it is treated
Cary Clarka560c472017-11-27 10:44:06 -05005763as Coons_Patch texture; Blend_Mode mode combines Color colors and Shader if
Cary Clarkbad5ad72017-08-03 17:14:08 -04005764both are provided.
Cary Clark8032b982017-07-28 11:04:54 -04005765
Herb Derbyefe39bc2018-05-01 17:06:20 -04005766Point array cubics specifies four Cubics starting at the top-left corner,
Cary Clarkce101242017-09-01 15:51:02 -04005767in clockwise order, sharing every fourth point. The last Cubic ends at the
Cary Clarkbad5ad72017-08-03 17:14:08 -04005768first point.
Cary Clark8032b982017-07-28 11:04:54 -04005769
Cary Clarkbc5697d2017-10-04 14:31:33 -04005770Color array color associates colors with corners in top-left, top-right,
5771bottom-right, bottom-left order.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005772
5773If paint contains Shader, Point array texCoords maps Shader as texture to
Cary Clarkbc5697d2017-10-04 14:31:33 -04005774corners in top-left, top-right, bottom-right, bottom-left order.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005775
Cary Clarka523d2d2017-08-30 08:58:10 -04005776#Param cubics Path_Cubic array, sharing common points ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005777#Param colors Color array, one for each corner ##
Cary Clarkce101242017-09-01 15:51:02 -04005778#Param texCoords Point array of texture coordinates, mapping Shader to corners;
Herb Derbyefe39bc2018-05-01 17:06:20 -04005779 may be nullptr
Cary Clark579985c2017-07-31 11:48:27 -04005780#Param ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005781#Param mode Blend_Mode for colors, and for Shader if paint has one ##
5782#Param paint Shader, Color_Filter, Blend_Mode, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005783
5784#Example
5785#Image 5
Cary Clarkbad5ad72017-08-03 17:14:08 -04005786void draw(SkCanvas* canvas) {
5787 // SkBitmap source = cmbkygk;
5788 SkPaint paint;
5789 paint.setFilterQuality(kLow_SkFilterQuality);
5790 paint.setAntiAlias(true);
5791 SkPoint cubics[] = { { 3, 1 }, { 4, 2 }, { 5, 1 }, { 7, 3 },
5792 /* { 7, 3 }, */ { 6, 4 }, { 7, 5 }, { 5, 7 },
5793 /* { 5, 7 }, */ { 4, 6 }, { 3, 7 }, { 1, 5 },
5794 /* { 1, 5 }, */ { 2, 4 }, { 1, 3 }, /* { 3, 1 } */ };
5795 SkColor colors[] = { 0xbfff0000, 0xbf0000ff, 0xbfff00ff, 0xbf00ffff };
5796 SkPoint texCoords[] = { { -30, -30 }, { 162, -30}, { 162, 162}, { -30, 162} };
5797 paint.setShader(SkShader::MakeBitmapShader(source, SkShader::kClamp_TileMode,
5798 SkShader::kClamp_TileMode, nullptr));
5799 canvas->scale(15, 15);
5800 for (auto blend : { SkBlendMode::kSrcOver, SkBlendMode::kModulate, SkBlendMode::kXor } ) {
5801 canvas->drawPatch(cubics, colors, texCoords, blend, paint);
5802 canvas->translate(4, 4);
5803 }
Cary Clark8032b982017-07-28 11:04:54 -04005804}
5805##
5806
Cary Clark2ade9972017-11-02 17:49:34 -04005807#ToDo can patch use image filter? ##
5808#SeeAlso SeeAlso drawVertices drawPicture
Cary Clark8032b982017-07-28 11:04:54 -04005809
5810##
5811
5812# ------------------------------------------------------------------------------
5813
5814#Method void drawPatch(const SkPoint cubics[12], const SkColor colors[4],
Herb Derbyefe39bc2018-05-01 17:06:20 -04005815 const SkPoint texCoords[4], const SkPaint& paint)
Cary Clark8032b982017-07-28 11:04:54 -04005816
Herb Derbyefe39bc2018-05-01 17:06:20 -04005817Draws Cubic Coons_Patch: the interpolation of four cubics with shared corners,
Cary Clarkbad5ad72017-08-03 17:14:08 -04005818associating a color, and optionally a texture coordinate, with each corner.
Cary Clark8032b982017-07-28 11:04:54 -04005819
Cary Clarka560c472017-11-27 10:44:06 -05005820Coons_Patch uses Clip and Matrix, paint Shader, Color_Filter,
Cary Clarkbad5ad72017-08-03 17:14:08 -04005821Color_Alpha, Image_Filter, and Blend_Mode. If Shader is provided it is treated
Cary Clarka560c472017-11-27 10:44:06 -05005822as Coons_Patch texture; Blend_Mode mode combines Color colors and Shader if
Cary Clarkbad5ad72017-08-03 17:14:08 -04005823both are provided.
Cary Clark8032b982017-07-28 11:04:54 -04005824
Herb Derbyefe39bc2018-05-01 17:06:20 -04005825Point array cubics specifies four Cubics starting at the top-left corner,
Cary Clarkce101242017-09-01 15:51:02 -04005826in clockwise order, sharing every fourth point. The last Cubic ends at the
Cary Clarkbad5ad72017-08-03 17:14:08 -04005827first point.
5828
Cary Clarkbc5697d2017-10-04 14:31:33 -04005829Color array color associates colors with corners in top-left, top-right,
5830bottom-right, bottom-left order.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005831
5832If paint contains Shader, Point array texCoords maps Shader as texture to
Cary Clarkbc5697d2017-10-04 14:31:33 -04005833corners in top-left, top-right, bottom-right, bottom-left order.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005834
Cary Clarka523d2d2017-08-30 08:58:10 -04005835#Param cubics Path_Cubic array, sharing common points ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005836#Param colors Color array, one for each corner ##
Cary Clarkce101242017-09-01 15:51:02 -04005837#Param texCoords Point array of texture coordinates, mapping Shader to corners;
Herb Derbyefe39bc2018-05-01 17:06:20 -04005838 may be nullptr
Cary Clark579985c2017-07-31 11:48:27 -04005839#Param ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005840#Param paint Shader, Color_Filter, Blend_Mode, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005841
5842#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04005843void draw(SkCanvas* canvas) {
5844 SkPaint paint;
5845 paint.setAntiAlias(true);
5846 SkPoint cubics[] = { { 3, 1 }, { 4, 2 }, { 5, 1 }, { 7, 3 },
5847 /* { 7, 3 }, */ { 6, 4 }, { 7, 5 }, { 5, 7 },
5848 /* { 5, 7 }, */ { 4, 6 }, { 3, 7 }, { 1, 5 },
5849 /* { 1, 5 }, */ { 2, 4 }, { 1, 3 }, /* { 3, 1 } */ };
5850 SkColor colors[] = { SK_ColorRED, SK_ColorBLUE, SK_ColorYELLOW, SK_ColorCYAN };
5851 canvas->scale(30, 30);
5852 canvas->drawPatch(cubics, colors, nullptr, paint);
5853 SkPoint text[] = { {3,0.9f}, {4,2.5f}, {5,0.9f}, {7.5f,3.2f}, {5.5f,4.2f},
5854 {7.5f,5.2f}, {5,7.5f}, {4,5.9f}, {3,7.5f}, {0.5f,5.2f}, {2.5f,4.2f},
5855 {0.5f,3.2f} };
5856 paint.setTextSize(18.f / 30);
5857 paint.setTextAlign(SkPaint::kCenter_Align);
5858 for (int i = 0; i< 10; ++i) {
5859 char digit = '0' + i;
5860 canvas->drawText(&digit, 1, text[i].fX, text[i].fY, paint);
5861 }
5862 canvas->drawString("10", text[10].fX, text[10].fY, paint);
5863 canvas->drawString("11", text[11].fX, text[11].fY, paint);
5864 paint.setStyle(SkPaint::kStroke_Style);
5865 canvas->drawPoints(SkCanvas::kPolygon_PointMode, 12, cubics, paint);
5866 canvas->drawLine(cubics[11].fX, cubics[11].fY, cubics[0].fX, cubics[0].fY, paint);
Cary Clark8032b982017-07-28 11:04:54 -04005867}
5868##
5869
5870#Example
5871#Image 6
Cary Clarkbad5ad72017-08-03 17:14:08 -04005872void draw(SkCanvas* canvas) {
5873 // SkBitmap source = checkerboard;
5874 SkPaint paint;
5875 paint.setFilterQuality(kLow_SkFilterQuality);
5876 paint.setAntiAlias(true);
5877 SkPoint cubics[] = { { 3, 1 }, { 4, 2 }, { 5, 1 }, { 7, 3 },
5878 /* { 7, 3 }, */ { 6, 4 }, { 7, 5 }, { 5, 7 },
5879 /* { 5, 7 }, */ { 4, 6 }, { 3, 7 }, { 1, 5 },
5880 /* { 1, 5 }, */ { 2, 4 }, { 1, 3 }, /* { 3, 1 } */ };
5881 SkPoint texCoords[] = { { 0, 0 }, { 0, 62}, { 62, 62}, { 62, 0 } };
5882 paint.setShader(SkShader::MakeBitmapShader(source, SkShader::kClamp_TileMode,
5883 SkShader::kClamp_TileMode, nullptr));
5884 canvas->scale(30, 30);
5885 canvas->drawPatch(cubics, nullptr, texCoords, paint);
Cary Clark8032b982017-07-28 11:04:54 -04005886}
5887##
5888
Cary Clark2ade9972017-11-02 17:49:34 -04005889#ToDo can patch use image filter? ##
5890#SeeAlso SeeAlso drawVertices drawPicture
Cary Clark8032b982017-07-28 11:04:54 -04005891
5892##
5893
5894# ------------------------------------------------------------------------------
5895
5896#Method void drawAtlas(const SkImage* atlas, const SkRSXform xform[], const SkRect tex[],
5897 const SkColor colors[], int count, SkBlendMode mode, const SkRect* cullRect,
5898 const SkPaint* paint)
Cary Clark78de7512018-02-07 07:27:09 -05005899#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05005900#Line # draws sprites using Clip, Matrix, and Paint ##
Cary Clark8032b982017-07-28 11:04:54 -04005901
5902Draw a set of sprites from atlas, using Clip, Matrix, and optional Paint paint.
Cary Clarkffb3d682018-05-17 12:17:28 -04005903paint uses Anti_Alias, Color_Alpha, Color_Filter, Image_Filter, and Blend_Mode
Cary Clarkbad5ad72017-08-03 17:14:08 -04005904to draw, if present. For each entry in the array, Rect tex locates sprite in
5905atlas, and RSXform xform transforms it into destination space.
5906
Cary Clark8032b982017-07-28 11:04:54 -04005907xform, text, and colors if present, must contain count entries.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005908Optional colors are applied for each sprite using Blend_Mode.
Herb Derbyefe39bc2018-05-01 17:06:20 -04005909Optional cullRect is a conservative bounds of all transformed sprites.
Cary Clarkce101242017-09-01 15:51:02 -04005910If cullRect is outside of Clip, canvas can skip drawing.
Cary Clark8032b982017-07-28 11:04:54 -04005911
Cary Clarkbad5ad72017-08-03 17:14:08 -04005912#Param atlas Image containing sprites ##
5913#Param xform RSXform mappings for sprites in atlas ##
5914#Param tex Rect locations of sprites in atlas ##
Cary Clark6fc50412017-09-21 12:31:06 -04005915#Param colors one per sprite, blended with sprite using Blend_Mode; may be nullptr ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005916#Param count number of sprites to draw ##
5917#Param mode Blend_Mode combining colors and sprites ##
Cary Clark6fc50412017-09-21 12:31:06 -04005918#Param cullRect bounds of transformed sprites for efficient clipping; may be nullptr ##
5919#Param paint Color_Filter, Image_Filter, Blend_Mode, and so on; may be nullptr ##
Cary Clark8032b982017-07-28 11:04:54 -04005920
5921#Example
5922#Image 3
Cary Clarkbad5ad72017-08-03 17:14:08 -04005923void draw(SkCanvas* canvas) {
5924 // SkBitmap source = mandrill;
5925 SkRSXform xforms[] = { { .5f, 0, 0, 0 }, {0, .5f, 200, 100 } };
5926 SkRect tex[] = { { 0, 0, 250, 250 }, { 0, 0, 250, 250 } };
5927 SkColor colors[] = { 0x7f55aa00, 0x7f3333bf };
5928 const SkImage* imagePtr = image.get();
5929 canvas->drawAtlas(imagePtr, xforms, tex, colors, 2, SkBlendMode::kSrcOver, nullptr, nullptr);
Cary Clark8032b982017-07-28 11:04:54 -04005930}
5931##
5932
Cary Clark2ade9972017-11-02 17:49:34 -04005933#SeeAlso drawBitmap drawImage
Cary Clark8032b982017-07-28 11:04:54 -04005934
5935##
5936
5937# ------------------------------------------------------------------------------
5938
5939#Method void drawAtlas(const sk_sp<SkImage>& atlas, const SkRSXform xform[], const SkRect tex[],
5940 const SkColor colors[], int count, SkBlendMode mode, const SkRect* cullRect,
Herb Derbyefe39bc2018-05-01 17:06:20 -04005941 const SkPaint* paint)
Cary Clark8032b982017-07-28 11:04:54 -04005942
5943Draw a set of sprites from atlas, using Clip, Matrix, and optional Paint paint.
Cary Clarkffb3d682018-05-17 12:17:28 -04005944paint uses Anti_Alias, Color_Alpha, Color_Filter, Image_Filter, and Blend_Mode
Cary Clarkbad5ad72017-08-03 17:14:08 -04005945to draw, if present. For each entry in the array, Rect tex locates sprite in
5946atlas, and RSXform xform transforms it into destination space.
5947
Cary Clark8032b982017-07-28 11:04:54 -04005948xform, text, and colors if present, must contain count entries.
5949Optional colors is applied for each sprite using Blend_Mode.
Herb Derbyefe39bc2018-05-01 17:06:20 -04005950Optional cullRect is a conservative bounds of all transformed sprites.
Cary Clarkce101242017-09-01 15:51:02 -04005951If cullRect is outside of Clip, canvas can skip drawing.
Cary Clark8032b982017-07-28 11:04:54 -04005952
Cary Clarkbad5ad72017-08-03 17:14:08 -04005953#Param atlas Image containing sprites ##
5954#Param xform RSXform mappings for sprites in atlas ##
5955#Param tex Rect locations of sprites in atlas ##
Cary Clark6fc50412017-09-21 12:31:06 -04005956#Param colors one per sprite, blended with sprite using Blend_Mode; may be nullptr ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005957#Param count number of sprites to draw ##
5958#Param mode Blend_Mode combining colors and sprites ##
Cary Clark6fc50412017-09-21 12:31:06 -04005959#Param cullRect bounds of transformed sprites for efficient clipping; may be nullptr ##
5960#Param paint Color_Filter, Image_Filter, Blend_Mode, and so on; may be nullptr ##
Cary Clark8032b982017-07-28 11:04:54 -04005961
5962#Example
5963#Image 3
Cary Clarkbad5ad72017-08-03 17:14:08 -04005964void draw(SkCanvas* canvas) {
5965 // SkBitmap source = mandrill;
5966 SkRSXform xforms[] = { { .5f, 0, 0, 0 }, {0, .5f, 200, 100 } };
5967 SkRect tex[] = { { 0, 0, 250, 250 }, { 0, 0, 250, 250 } };
5968 SkColor colors[] = { 0x7f55aa00, 0x7f3333bf };
5969 SkPaint paint;
5970 paint.setAlpha(127);
5971 canvas->drawAtlas(image, xforms, tex, colors, 2, SkBlendMode::kPlus, nullptr, &paint);
Cary Clark8032b982017-07-28 11:04:54 -04005972}
5973##
5974
5975#ToDo bug in example on cpu side, gpu looks ok ##
5976
Cary Clark2ade9972017-11-02 17:49:34 -04005977#SeeAlso drawBitmap drawImage
5978
Cary Clark8032b982017-07-28 11:04:54 -04005979##
5980
5981# ------------------------------------------------------------------------------
5982
5983#Method void drawAtlas(const SkImage* atlas, const SkRSXform xform[], const SkRect tex[], int count,
Herb Derbyefe39bc2018-05-01 17:06:20 -04005984 const SkRect* cullRect, const SkPaint* paint)
Cary Clark8032b982017-07-28 11:04:54 -04005985
5986Draw a set of sprites from atlas, using Clip, Matrix, and optional Paint paint.
Cary Clarkffb3d682018-05-17 12:17:28 -04005987paint uses Anti_Alias, Color_Alpha, Color_Filter, Image_Filter, and Blend_Mode
Cary Clarkbad5ad72017-08-03 17:14:08 -04005988to draw, if present. For each entry in the array, Rect tex locates sprite in
5989atlas, and RSXform xform transforms it into destination space.
5990
Cary Clark8032b982017-07-28 11:04:54 -04005991xform and text must contain count entries.
Herb Derbyefe39bc2018-05-01 17:06:20 -04005992Optional cullRect is a conservative bounds of all transformed sprites.
Cary Clarkce101242017-09-01 15:51:02 -04005993If cullRect is outside of Clip, canvas can skip drawing.
Cary Clark8032b982017-07-28 11:04:54 -04005994
Cary Clarkbad5ad72017-08-03 17:14:08 -04005995#Param atlas Image containing sprites ##
5996#Param xform RSXform mappings for sprites in atlas ##
5997#Param tex Rect locations of sprites in atlas ##
5998#Param count number of sprites to draw ##
Cary Clark6fc50412017-09-21 12:31:06 -04005999#Param cullRect bounds of transformed sprites for efficient clipping; may be nullptr ##
6000#Param paint Color_Filter, Image_Filter, Blend_Mode, and so on; may be nullptr ##
Cary Clark8032b982017-07-28 11:04:54 -04006001
6002#Example
6003#Image 3
Cary Clarkbad5ad72017-08-03 17:14:08 -04006004void draw(SkCanvas* canvas) {
6005 // sk_sp<SkImage> image = mandrill;
6006 SkRSXform xforms[] = { { .5f, 0, 0, 0 }, {0, .5f, 200, 100 } };
6007 SkRect tex[] = { { 0, 0, 250, 250 }, { 0, 0, 250, 250 } };
6008 const SkImage* imagePtr = image.get();
6009 canvas->drawAtlas(imagePtr, xforms, tex, 2, nullptr, nullptr);
Cary Clark8032b982017-07-28 11:04:54 -04006010}
6011##
6012
Cary Clark2ade9972017-11-02 17:49:34 -04006013#SeeAlso drawBitmap drawImage
Cary Clark8032b982017-07-28 11:04:54 -04006014
6015##
6016
6017# ------------------------------------------------------------------------------
6018
6019#Method void drawAtlas(const sk_sp<SkImage>& atlas, const SkRSXform xform[], const SkRect tex[],
Herb Derbyefe39bc2018-05-01 17:06:20 -04006020 int count, const SkRect* cullRect, const SkPaint* paint)
Cary Clark8032b982017-07-28 11:04:54 -04006021
6022Draw a set of sprites from atlas, using Clip, Matrix, and optional Paint paint.
Cary Clarkffb3d682018-05-17 12:17:28 -04006023paint uses Anti_Alias, Color_Alpha, Color_Filter, Image_Filter, and Blend_Mode
Cary Clarkbad5ad72017-08-03 17:14:08 -04006024to draw, if present. For each entry in the array, Rect tex locates sprite in
6025atlas, and RSXform xform transforms it into destination space.
6026
Cary Clark8032b982017-07-28 11:04:54 -04006027xform and text must contain count entries.
Herb Derbyefe39bc2018-05-01 17:06:20 -04006028Optional cullRect is a conservative bounds of all transformed sprites.
Cary Clarkce101242017-09-01 15:51:02 -04006029If cullRect is outside of Clip, canvas can skip drawing.
Cary Clark8032b982017-07-28 11:04:54 -04006030
Cary Clarkbad5ad72017-08-03 17:14:08 -04006031#Param atlas Image containing sprites ##
6032#Param xform RSXform mappings for sprites in atlas ##
6033#Param tex Rect locations of sprites in atlas ##
6034#Param count number of sprites to draw ##
Cary Clark6fc50412017-09-21 12:31:06 -04006035#Param cullRect bounds of transformed sprites for efficient clipping; may be nullptr ##
6036#Param paint Color_Filter, Image_Filter, Blend_Mode, and so on; may be nullptr ##
Cary Clark8032b982017-07-28 11:04:54 -04006037
6038#Example
6039#Image 3
Cary Clarkbad5ad72017-08-03 17:14:08 -04006040void draw(SkCanvas* canvas) {
6041 // sk_sp<SkImage> image = mandrill;
6042 SkRSXform xforms[] = { { 1, 0, 0, 0 }, {0, 1, 300, 100 } };
6043 SkRect tex[] = { { 0, 0, 200, 200 }, { 200, 0, 400, 200 } };
6044 canvas->drawAtlas(image, xforms, tex, 2, nullptr, nullptr);
Cary Clark8032b982017-07-28 11:04:54 -04006045}
6046##
6047
Cary Clark2ade9972017-11-02 17:49:34 -04006048#SeeAlso drawBitmap drawImage
Cary Clark8032b982017-07-28 11:04:54 -04006049
6050##
6051
6052# ------------------------------------------------------------------------------
6053
Cary Clark73fa9722017-08-29 17:36:51 -04006054#Method void drawDrawable(SkDrawable* drawable, const SkMatrix* matrix = nullptr)
Cary Clark78de7512018-02-07 07:27:09 -05006055#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05006056#Line # draws Drawable, encapsulated drawing commands ##
Herb Derbyefe39bc2018-05-01 17:06:20 -04006057Draw Drawable drawable using Clip and Matrix, concatenated with
Cary Clark8032b982017-07-28 11:04:54 -04006058optional matrix.
6059
Herb Derbyefe39bc2018-05-01 17:06:20 -04006060If Canvas has an asynchronous implementation, as is the case
Cary Clark8032b982017-07-28 11:04:54 -04006061when it is recording into Picture, then drawable will be referenced,
6062so that SkDrawable::draw() can be called when the operation is finalized. To force
6063immediate drawing, call SkDrawable::draw() instead.
6064
Cary Clarkbad5ad72017-08-03 17:14:08 -04006065#Param drawable custom struct encapsulating drawing commands ##
6066#Param matrix transformation applied to drawing; may be nullptr ##
Cary Clark8032b982017-07-28 11:04:54 -04006067
6068#Example
6069#Height 100
6070#Function
Cary Clarkbad5ad72017-08-03 17:14:08 -04006071struct MyDrawable : public SkDrawable {
6072 SkRect onGetBounds() override { return SkRect::MakeWH(50, 100); }
6073
6074 void onDraw(SkCanvas* canvas) override {
6075 SkPath path;
6076 path.conicTo(10, 90, 50, 90, 0.9f);
6077 SkPaint paint;
6078 paint.setColor(SK_ColorBLUE);
6079 canvas->drawRect(path.getBounds(), paint);
6080 paint.setAntiAlias(true);
6081 paint.setColor(SK_ColorWHITE);
6082 canvas->drawPath(path, paint);
6083 }
6084};
6085
6086#Function ##
6087void draw(SkCanvas* canvas) {
6088 sk_sp<SkDrawable> drawable(new MyDrawable);
6089 SkMatrix matrix;
6090 matrix.setTranslate(10, 10);
6091 canvas->drawDrawable(drawable.get(), &matrix);
Cary Clark8032b982017-07-28 11:04:54 -04006092}
6093##
6094
Cary Clark2ade9972017-11-02 17:49:34 -04006095#SeeAlso SkDrawable drawPicture
Cary Clark8032b982017-07-28 11:04:54 -04006096
6097##
6098
6099# ------------------------------------------------------------------------------
6100
6101#Method void drawDrawable(SkDrawable* drawable, SkScalar x, SkScalar y)
6102
6103Draw Drawable drawable using Clip and Matrix, offset by (x, y).
6104
Herb Derbyefe39bc2018-05-01 17:06:20 -04006105If Canvas has an asynchronous implementation, as is the case
Cary Clark8032b982017-07-28 11:04:54 -04006106when it is recording into Picture, then drawable will be referenced,
6107so that SkDrawable::draw() can be called when the operation is finalized. To force
6108immediate drawing, call SkDrawable::draw() instead.
6109
Cary Clarkbad5ad72017-08-03 17:14:08 -04006110#Param drawable custom struct encapsulating drawing commands ##
6111#Param x offset into Canvas writable pixels in x ##
6112#Param y offset into Canvas writable pixels in y ##
Cary Clark8032b982017-07-28 11:04:54 -04006113
6114#Example
6115#Height 100
6116#Function
Cary Clarkbad5ad72017-08-03 17:14:08 -04006117struct MyDrawable : public SkDrawable {
6118 SkRect onGetBounds() override { return SkRect::MakeWH(50, 100); }
6119
6120 void onDraw(SkCanvas* canvas) override {
6121 SkPath path;
6122 path.conicTo(10, 90, 50, 90, 0.9f);
6123 SkPaint paint;
6124 paint.setColor(SK_ColorBLUE);
6125 canvas->drawRect(path.getBounds(), paint);
6126 paint.setAntiAlias(true);
6127 paint.setColor(SK_ColorWHITE);
6128 canvas->drawPath(path, paint);
6129 }
6130};
6131
6132#Function ##
6133void draw(SkCanvas* canvas) {
6134 sk_sp<SkDrawable> drawable(new MyDrawable);
6135 canvas->drawDrawable(drawable.get(), 10, 10);
Cary Clark8032b982017-07-28 11:04:54 -04006136}
6137##
6138
Cary Clark2ade9972017-11-02 17:49:34 -04006139#SeeAlso SkDrawable drawPicture
Cary Clark8032b982017-07-28 11:04:54 -04006140
6141##
6142
6143# ------------------------------------------------------------------------------
6144
6145#Method void drawAnnotation(const SkRect& rect, const char key[], SkData* value)
Cary Clark78de7512018-02-07 07:27:09 -05006146#In Draw
6147#In Utility
Cary Clarkab2621d2018-01-30 10:08:57 -05006148#Line # associates a Rect with a key-value pair ##
Cary Clark78de7512018-02-07 07:27:09 -05006149Associate Rect on Canvas with an annotation; a key-value pair, where the key is
Cary Clark8032b982017-07-28 11:04:54 -04006150a null-terminated utf8 string, and optional value is stored as Data.
6151
Herb Derbyefe39bc2018-05-01 17:06:20 -04006152Only some canvas implementations, such as recording to Picture, or drawing to
Cary Clark8032b982017-07-28 11:04:54 -04006153Document_PDF, use annotations.
6154
Cary Clarkbad5ad72017-08-03 17:14:08 -04006155#Param rect Rect extent of canvas to annotate ##
6156#Param key string used for lookup ##
6157#Param value data holding value stored in annotation ##
Cary Clark8032b982017-07-28 11:04:54 -04006158
6159#Example
6160 #Height 1
6161 const char text[] = "Click this link!";
6162 SkRect bounds;
6163 SkPaint paint;
6164 paint.setTextSize(40);
6165 (void)paint.measureText(text, strlen(text), &bounds);
6166 const char url[] = "https://www.google.com/";
6167 sk_sp<SkData> urlData(SkData::MakeWithCString(url));
6168 canvas->drawAnnotation(bounds, "url_key", urlData.get());
6169##
6170
Cary Clark2ade9972017-11-02 17:49:34 -04006171#SeeAlso SkPicture SkDocument
Cary Clark8032b982017-07-28 11:04:54 -04006172
6173##
6174
6175# ------------------------------------------------------------------------------
6176
Herb Derbyefe39bc2018-05-01 17:06:20 -04006177#Method void drawAnnotation(const SkRect& rect, const char key[], const sk_sp<SkData>& value)
Cary Clark8032b982017-07-28 11:04:54 -04006178
6179Associate Rect on Canvas when an annotation; a key-value pair, where the key is
6180a null-terminated utf8 string, and optional value is stored as Data.
6181
Herb Derbyefe39bc2018-05-01 17:06:20 -04006182Only some canvas implementations, such as recording to Picture, or drawing to
Cary Clark8032b982017-07-28 11:04:54 -04006183Document_PDF, use annotations.
6184
Cary Clarkbad5ad72017-08-03 17:14:08 -04006185#Param rect Rect extent of canvas to annotate ##
6186#Param key string used for lookup ##
6187#Param value data holding value stored in annotation ##
Cary Clark8032b982017-07-28 11:04:54 -04006188
6189#Example
6190#Height 1
6191 const char text[] = "Click this link!";
6192 SkRect bounds;
6193 SkPaint paint;
6194 paint.setTextSize(40);
6195 (void)paint.measureText(text, strlen(text), &bounds);
6196 const char url[] = "https://www.google.com/";
6197 sk_sp<SkData> urlData(SkData::MakeWithCString(url));
6198 canvas->drawAnnotation(bounds, "url_key", urlData.get());
6199##
6200
Cary Clark2ade9972017-11-02 17:49:34 -04006201#SeeAlso SkPicture SkDocument
Cary Clark8032b982017-07-28 11:04:54 -04006202
6203##
6204
6205#Method SkDrawFilter* getDrawFilter() const
Cary Clark4855f782018-02-06 09:41:53 -05006206#Deprecated soon
Cary Clark8032b982017-07-28 11:04:54 -04006207##
6208
6209#Method virtual SkDrawFilter* setDrawFilter(SkDrawFilter* filter)
Cary Clark4855f782018-02-06 09:41:53 -05006210#Deprecated soon
Cary Clark8032b982017-07-28 11:04:54 -04006211##
6212
6213# ------------------------------------------------------------------------------
6214
6215#Method virtual bool isClipEmpty() const
Cary Clark78de7512018-02-07 07:27:09 -05006216#In Property
Cary Clarkab2621d2018-01-30 10:08:57 -05006217#Line # returns if Clip is empty ##
Cary Clark8032b982017-07-28 11:04:54 -04006218Returns true if Clip is empty; that is, nothing will draw.
6219
Cary Clarkbad5ad72017-08-03 17:14:08 -04006220May do work when called; it should not be called
Cary Clark8032b982017-07-28 11:04:54 -04006221more often than needed. However, once called, subsequent calls perform no
6222work until Clip changes.
6223
Cary Clarkbad5ad72017-08-03 17:14:08 -04006224#Return true if Clip is empty ##
Cary Clark8032b982017-07-28 11:04:54 -04006225
6226#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04006227 void draw(SkCanvas* canvas) {
6228 SkDebugf("clip is%s empty\n", canvas->isClipEmpty() ? "" : " not");
6229 SkPath path;
6230 canvas->clipPath(path);
6231 SkDebugf("clip is%s empty\n", canvas->isClipEmpty() ? "" : " not");
Cary Clark8032b982017-07-28 11:04:54 -04006232 }
6233 #StdOut
Cary Clarkbad5ad72017-08-03 17:14:08 -04006234 clip is not empty
Cary Clark8032b982017-07-28 11:04:54 -04006235 clip is empty
6236 ##
6237##
6238
Cary Clark2ade9972017-11-02 17:49:34 -04006239#SeeAlso isClipRect getLocalClipBounds getDeviceClipBounds
Cary Clark8032b982017-07-28 11:04:54 -04006240
6241##
6242
6243# ------------------------------------------------------------------------------
6244
6245#Method virtual bool isClipRect() const
Cary Clark78de7512018-02-07 07:27:09 -05006246#In Property
Cary Clarkab2621d2018-01-30 10:08:57 -05006247#Line # returns if Clip is Rect and not empty ##
Cary Clark8032b982017-07-28 11:04:54 -04006248Returns true if Clip is Rect and not empty.
6249Returns false if the clip is empty, or if it is not Rect.
6250
Cary Clarkbad5ad72017-08-03 17:14:08 -04006251#Return true if Clip is Rect and not empty ##
Cary Clark8032b982017-07-28 11:04:54 -04006252
6253#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04006254 void draw(SkCanvas* canvas) {
6255 SkDebugf("clip is%s rect\n", canvas->isClipRect() ? "" : " not");
6256 canvas->clipRect({0, 0, 0, 0});
6257 SkDebugf("clip is%s rect\n", canvas->isClipRect() ? "" : " not");
Cary Clark8032b982017-07-28 11:04:54 -04006258 }
6259 #StdOut
Cary Clarkbad5ad72017-08-03 17:14:08 -04006260 clip is rect
Cary Clark8032b982017-07-28 11:04:54 -04006261 clip is not rect
6262 ##
6263##
6264
Cary Clark2ade9972017-11-02 17:49:34 -04006265#SeeAlso isClipEmpty getLocalClipBounds getDeviceClipBounds
Cary Clark8032b982017-07-28 11:04:54 -04006266
6267##
6268
6269#Class SkCanvas ##
Cary Clark884dd7d2017-10-11 10:37:52 -04006270
Cary Clark8032b982017-07-28 11:04:54 -04006271#Topic Canvas ##