blob: 2990a8c48cecc6820643c78f5bf609f7d758d82c [file] [log] [blame]
Cary Clark8032b982017-07-28 11:04:54 -04001#Topic Canvas
Cary Clark12799e12017-07-28 15:18:29 -04002#Alias Canvas_Reference
Cary Clark8032b982017-07-28 11:04:54 -04003
Cary Clarke4aa3712017-09-15 02:56:12 -04004#Class SkCanvas
5
Cary Clark8032b982017-07-28 11:04:54 -04006Canvas provides an interface for drawing, and how the drawing is clipped and transformed.
7Canvas contains a stack of Matrix and Clip values.
8
9Canvas and Paint together provide the state to draw into Surface or Device.
Cary Clarkbad5ad72017-08-03 17:14:08 -040010Each Canvas draw call transforms the geometry of the object by the concatenation of all
11Matrix values in the stack. The transformed geometry is clipped by the intersection
12of all of Clip values in the stack. The Canvas draw calls use Paint to supply drawing
13state such as Color, Typeface, text size, stroke width, Shader and so on.
Cary Clark8032b982017-07-28 11:04:54 -040014
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 Clark08895c42018-02-01 09:37:32 -05001466#Line # temporary Bitmap to draw into ##
Cary Clarkce101242017-09-01 15:51:02 -04001467
1468Layer allocates a temporary Bitmap to draw into. When the drawing is
Herb Derbyefe39bc2018-05-01 17:06:20 -04001469complete, the Bitmap is drawn into the Canvas.
Cary Clarkce101242017-09-01 15:51:02 -04001470
1471Layer is saved in a stack along with other saved state. When state with a Layer
1472is restored, the Bitmap is drawn into the previous Layer.
1473
1474Layer may be initialized with the contents of the previous Layer. When Layer is
1475restored, its Bitmap can be modified by Paint passed to Layer to apply
1476Color_Alpha, Color_Filter, Image_Filter, and Blend_Mode.
1477
1478#Method int saveLayer(const SkRect* bounds, const SkPaint* paint)
1479
Cary Clarkab2621d2018-01-30 10:08:57 -05001480#In Layer
1481#Line # saves Clip and Matrix on stack; creates Layer ##
Cary Clarkce101242017-09-01 15:51:02 -04001482Saves Matrix, Clip, and Draw_Filter (Draw_Filter deprecated on most platforms),
1483and allocates a Bitmap for subsequent drawing.
1484Calling restore() discards changes to Matrix, Clip, and Draw_Filter,
1485and draws the Bitmap.
1486
1487Matrix may be changed by translate(), scale(), rotate(), skew(), concat(),
Herb Derbyefe39bc2018-05-01 17:06:20 -04001488setMatrix, and resetMatrix. Clip may be changed by clipRect, clipRRect,
Cary Clarkce101242017-09-01 15:51:02 -04001489clipPath, clipRegion.
1490
1491Rect bounds suggests but does not define the Bitmap size. To clip drawing to
1492a specific rectangle, use clipRect.
1493
1494Optional Paint paint applies Color_Alpha, Color_Filter, Image_Filter, and
1495Blend_Mode when restore() is called.
1496
1497Call restoreToCount with returned value to restore this and subsequent saves.
1498
1499#Param bounds hint to limit the size of the Layer; may be nullptr ##
1500#Param paint graphics state for Layer; may be nullptr ##
1501
1502#Return depth of saved stack ##
1503
1504#Example
1505#Description
1506Rectangles are blurred by Image_Filter when restore() draws Layer to main
1507Canvas.
1508##
1509#Height 128
1510void draw(SkCanvas* canvas) {
1511 SkPaint paint, blur;
Cary Clarka560c472017-11-27 10:44:06 -05001512 blur.setImageFilter(SkBlurImageFilter::Make(3, 3, nullptr));
Cary Clarkce101242017-09-01 15:51:02 -04001513 canvas->saveLayer(nullptr, &blur);
1514 SkRect rect = { 25, 25, 50, 50};
1515 canvas->drawRect(rect, paint);
1516 canvas->translate(50, 50);
1517 paint.setColor(SK_ColorRED);
1518 canvas->drawRect(rect, paint);
1519 canvas->restore();
1520}
1521##
1522
Cary Clark2ade9972017-11-02 17:49:34 -04001523#SeeAlso save() restore() saveLayer saveLayerPreserveLCDTextRequests saveLayerAlpha SaveLayerRec
Cary Clarkce101242017-09-01 15:51:02 -04001524
1525##
1526
Herb Derbyefe39bc2018-05-01 17:06:20 -04001527#Method int saveLayer(const SkRect& bounds, const SkPaint* paint)
Cary Clarkce101242017-09-01 15:51:02 -04001528
Cary Clarkab2621d2018-01-30 10:08:57 -05001529#In Layer
Cary Clarkce101242017-09-01 15:51:02 -04001530Saves Matrix, Clip, and Draw_Filter (Draw_Filter deprecated on most platforms),
1531and allocates a Bitmap for subsequent drawing.
1532Calling restore() discards changes to Matrix, Clip, and Draw_Filter,
1533and draws the Bitmap.
1534
1535Matrix may be changed by translate(), scale(), rotate(), skew(), concat(),
1536setMatrix, and resetMatrix. Clip may be changed by clipRect, clipRRect,
1537clipPath, clipRegion.
1538
1539Rect bounds suggests but does not define the Layer size. To clip drawing to
1540a specific rectangle, use clipRect.
1541
1542Optional Paint paint applies Color_Alpha, Color_Filter, Image_Filter, and
1543Blend_Mode when restore() is called.
1544
1545Call restoreToCount with returned value to restore this and subsequent saves.
1546
1547#Param bounds hint to limit the size of Layer; may be nullptr ##
1548#Param paint graphics state for Layer; may be nullptr ##
1549
1550#Return depth of saved stack ##
1551
1552#Example
1553#Description
1554Rectangles are blurred by Image_Filter when restore() draws Layer to main Canvas.
Herb Derbyefe39bc2018-05-01 17:06:20 -04001555The red rectangle is clipped; it does not fully fit on Layer.
Cary Clarkce101242017-09-01 15:51:02 -04001556Image_Filter blurs past edge of Layer so red rectangle is blurred on all sides.
1557##
1558#Height 128
1559void draw(SkCanvas* canvas) {
1560 SkPaint paint, blur;
Cary Clarka560c472017-11-27 10:44:06 -05001561 blur.setImageFilter(SkBlurImageFilter::Make(3, 3, nullptr));
Cary Clarkce101242017-09-01 15:51:02 -04001562 canvas->saveLayer(SkRect::MakeWH(90, 90), &blur);
1563 SkRect rect = { 25, 25, 50, 50};
1564 canvas->drawRect(rect, paint);
1565 canvas->translate(50, 50);
1566 paint.setColor(SK_ColorRED);
1567 canvas->drawRect(rect, paint);
1568 canvas->restore();
1569}
1570##
1571
Cary Clark2ade9972017-11-02 17:49:34 -04001572#SeeAlso save() restore() saveLayerPreserveLCDTextRequests saveLayerAlpha SaveLayerRec
Cary Clarkce101242017-09-01 15:51:02 -04001573
1574##
1575
1576#Method int saveLayerPreserveLCDTextRequests(const SkRect* bounds, const SkPaint* paint)
1577
Cary Clarkab2621d2018-01-30 10:08:57 -05001578#In Layer
1579#Line # saves Clip and Matrix on stack; creates Layer for LCD text ##
Cary Clarkce101242017-09-01 15:51:02 -04001580Saves Matrix, Clip, and Draw_Filter (Draw_Filter deprecated on most platforms),
1581and allocates a Bitmap for subsequent drawing.
1582LCD_Text is preserved when the Layer is drawn to the prior Layer.
1583
1584Calling restore() discards changes to Matrix, Clip, and Draw_Filter,
1585and draws Layer.
1586
1587Matrix may be changed by translate(), scale(), rotate(), skew(), concat(),
1588setMatrix, and resetMatrix. Clip may be changed by clipRect, clipRRect,
1589clipPath, clipRegion.
Herb Derbyefe39bc2018-05-01 17:06:20 -04001590
Cary Clarkce101242017-09-01 15:51:02 -04001591Rect bounds suggests but does not define the Layer size. To clip drawing to
1592a specific rectangle, use clipRect.
1593
1594Optional Paint paint applies Color_Alpha, Color_Filter, Image_Filter, and
1595Blend_Mode when restore() is called.
1596
1597Call restoreToCount with returned value to restore this and subsequent saves.
1598
1599Draw text on an opaque background so that LCD_Text blends correctly with the
1600prior Layer. LCD_Text drawn on a background with transparency may result in
Cary Clark6fc50412017-09-21 12:31:06 -04001601incorrect blending.
Cary Clarkce101242017-09-01 15:51:02 -04001602
1603#Param bounds hint to limit the size of Layer; may be nullptr ##
1604#Param paint graphics state for Layer; may be nullptr ##
1605
1606#Return depth of saved stack ##
1607
1608#Example
1609 SkPaint paint;
1610 paint.setAntiAlias(true);
1611 paint.setLCDRenderText(true);
1612 paint.setTextSize(20);
1613 for (auto preserve : { false, true } ) {
1614 preserve ? canvas->saveLayerPreserveLCDTextRequests(nullptr, nullptr)
1615 : canvas->saveLayer(nullptr, nullptr);
1616 SkPaint p;
1617 p.setColor(SK_ColorWHITE);
1618 // Comment out the next line to draw on a non-opaque background.
1619 canvas->drawRect(SkRect::MakeLTRB(25, 40, 200, 70), p);
1620 canvas->drawString("Hamburgefons", 30, 60, paint);
1621
1622 p.setColor(0xFFCCCCCC);
1623 canvas->drawRect(SkRect::MakeLTRB(25, 70, 200, 100), p);
1624 canvas->drawString("Hamburgefons", 30, 90, paint);
1625
1626 canvas->restore();
1627 canvas->translate(0, 80);
1628 }
1629 ##
1630
Cary Clark2ade9972017-11-02 17:49:34 -04001631#SeeAlso save() restore() saveLayer saveLayerAlpha SaveLayerRec
Cary Clarkce101242017-09-01 15:51:02 -04001632
1633##
1634
1635#Method int saveLayerAlpha(const SkRect* bounds, U8CPU alpha)
1636
Cary Clarkab2621d2018-01-30 10:08:57 -05001637#In Layer
1638#Line # saves Clip and Matrix on stack; creates Layer; sets opacity ##
Cary Clarkce101242017-09-01 15:51:02 -04001639Saves Matrix, Clip, and Draw_Filter (Draw_Filter deprecated on most platforms),
1640and allocates Bitmap for subsequent drawing.
1641
1642Calling restore() discards changes to Matrix, Clip, and Draw_Filter,
1643and blends Layer with alpha opacity onto prior Layer.
1644
1645Matrix may be changed by translate(), scale(), rotate(), skew(), concat(),
1646setMatrix, and resetMatrix. Clip may be changed by clipRect, clipRRect,
1647clipPath, clipRegion.
1648
1649Rect bounds suggests but does not define Layer size. To clip drawing to
1650a specific rectangle, use clipRect.
1651
1652alpha of zero is fully transparent, 255 is fully opaque.
1653
1654Call restoreToCount with returned value to restore this and subsequent saves.
1655
1656#Param bounds hint to limit the size of Layer; may be nullptr ##
1657#Param alpha opacity of Layer ##
1658
1659#Return depth of saved stack ##
1660
1661#Example
1662 SkPaint paint;
1663 paint.setColor(SK_ColorRED);
1664 canvas->drawCircle(50, 50, 50, paint);
1665 canvas->saveLayerAlpha(nullptr, 128);
1666 paint.setColor(SK_ColorBLUE);
1667 canvas->drawCircle(100, 50, 50, paint);
1668 paint.setColor(SK_ColorGREEN);
1669 paint.setAlpha(128);
1670 canvas->drawCircle(75, 90, 50, paint);
1671 canvas->restore();
1672##
1673
Cary Clark2ade9972017-11-02 17:49:34 -04001674#SeeAlso save() restore() saveLayer saveLayerPreserveLCDTextRequests SaveLayerRec
Cary Clarkce101242017-09-01 15:51:02 -04001675
1676##
1677
Cary Clarkd98f78c2018-04-26 08:32:37 -04001678#Enum SaveLayerFlagsSet
Cary Clark08895c42018-02-01 09:37:32 -05001679#Line # sets SaveLayerRec options ##
Cary Clarkce101242017-09-01 15:51:02 -04001680#Code
Cary Clarkd98f78c2018-04-26 08:32:37 -04001681 enum SaveLayerFlagsSet {
Cary Clarkce101242017-09-01 15:51:02 -04001682 kPreserveLCDText_SaveLayerFlag = 1 << 1,
1683 kInitWithPrevious_SaveLayerFlag = 1 << 2,
Mike Reed910ca0f2018-04-25 13:04:05 -04001684 kMaskAgainstCoverage_EXPERIMENTAL_DONT_USE_SaveLayerFlag = 1 << 3,
Cary Clarkce101242017-09-01 15:51:02 -04001685 kDontClipToLayer_Legacy_SaveLayerFlag = kDontClipToLayer_PrivateSaveLayerFlag,
1686 };
Cary Clarkd98f78c2018-04-26 08:32:37 -04001687
1688 typedef uint32_t SaveLayerFlags;
Cary Clarkce101242017-09-01 15:51:02 -04001689##
1690
Cary Clark682c58d2018-05-16 07:07:07 -04001691
1692#Typedef uint32_t SaveLayerFlags
1693#Line # options for SaveLayerRec ##
1694
Cary Clarkce101242017-09-01 15:51:02 -04001695SaveLayerFlags provides options that may be used in any combination in SaveLayerRec,
Cary Clark682c58d2018-05-16 07:07:07 -04001696defining how Layer allocated by saveLayer operates. It may be set to zero,
1697kPreserveLCDText_SaveLayerFlag, kInitWithPrevious_SaveLayerFlag, or both flags.
1698
1699##
Cary Clarkce101242017-09-01 15:51:02 -04001700
Cary Clarkce101242017-09-01 15:51:02 -04001701#Const kPreserveLCDText_SaveLayerFlag 2
Cary Clark682c58d2018-05-16 07:07:07 -04001702#Line # creates Layer for LCD text ##
Cary Clarkce101242017-09-01 15:51:02 -04001703 Creates Layer for LCD text. Flag is ignored if Layer Paint contains
1704 Image_Filter or Color_Filter.
1705##
1706
1707#Const kInitWithPrevious_SaveLayerFlag 4
Cary Clark682c58d2018-05-16 07:07:07 -04001708#Line # initializes with previous contents ##
Cary Clarkce101242017-09-01 15:51:02 -04001709 Initializes Layer with the contents of the previous Layer.
1710##
1711
Mike Reed910ca0f2018-04-25 13:04:05 -04001712#Const kMaskAgainstCoverage_EXPERIMENTAL_DONT_USE_SaveLayerFlag 8
Cary Clark682c58d2018-05-16 07:07:07 -04001713#Experimental do not use
Mike Reed910ca0f2018-04-25 13:04:05 -04001714##
1715
Cary Clarkce101242017-09-01 15:51:02 -04001716#Const kDontClipToLayer_Legacy_SaveLayerFlag 0x80000000
Cary Clark4855f782018-02-06 09:41:53 -05001717#Deprecated soon
Cary Clarkce101242017-09-01 15:51:02 -04001718##
1719
1720#Example
1721#Height 160
1722#Description
1723Canvas Layer captures red and blue circles scaled up by four.
Herb Derbyefe39bc2018-05-01 17:06:20 -04001724scalePaint blends Layer back with transparency.
Cary Clarkce101242017-09-01 15:51:02 -04001725##
1726void draw(SkCanvas* canvas) {
1727 SkPaint redPaint, bluePaint, scalePaint;
1728 redPaint.setColor(SK_ColorRED);
1729 canvas->drawCircle(21, 21, 8, redPaint);
1730 bluePaint.setColor(SK_ColorBLUE);
1731 canvas->drawCircle(31, 21, 8, bluePaint);
1732 SkMatrix matrix;
1733 matrix.setScale(4, 4);
1734 scalePaint.setAlpha(0x40);
1735 scalePaint.setImageFilter(
1736 SkImageFilter::MakeMatrixFilter(matrix, kNone_SkFilterQuality, nullptr));
1737 SkCanvas::SaveLayerRec saveLayerRec(nullptr, &scalePaint,
Herb Derbyefe39bc2018-05-01 17:06:20 -04001738 SkCanvas::kInitWithPrevious_SaveLayerFlag);
Cary Clarkce101242017-09-01 15:51:02 -04001739 canvas->saveLayer(saveLayerRec);
1740 canvas->restore();
1741}
1742##
1743
Cary Clark2ade9972017-11-02 17:49:34 -04001744#SeeAlso save() restore() saveLayer saveLayerPreserveLCDTextRequests saveLayerAlpha SaveLayerRec
Cary Clarkce101242017-09-01 15:51:02 -04001745
1746#Enum ##
1747
Cary Clark682c58d2018-05-16 07:07:07 -04001748#Subtopic SaveLayerRec
1749#Line # contains the state used to create the Layer ##
Cary Clarka560c472017-11-27 10:44:06 -05001750
Cary Clarkce101242017-09-01 15:51:02 -04001751#Struct SaveLayerRec
Cary Clark08895c42018-02-01 09:37:32 -05001752#Line # contains the state used to create the Layer ##
Cary Clark682c58d2018-05-16 07:07:07 -04001753
1754SaveLayerRec contains the state used to create the Layer.
1755
Cary Clarkce101242017-09-01 15:51:02 -04001756#Code
1757 struct SaveLayerRec {
1758 SaveLayerRec*(...
1759
1760 const SkRect* fBounds;
1761 const SkPaint* fPaint;
1762 const SkImageFilter* fBackdrop;
1763 SaveLayerFlags fSaveLayerFlags;
1764 };
1765##
1766
Cary Clark682c58d2018-05-16 07:07:07 -04001767#Subtopic Overview
1768#Populate
1769##
1770
1771#Subtopic Member
1772#Populate
1773##
Cary Clarkce101242017-09-01 15:51:02 -04001774
1775#Member const SkRect* fBounds
Cary Clark682c58d2018-05-16 07:07:07 -04001776#Line # hints at Layer size limit ##
Cary Clarkce101242017-09-01 15:51:02 -04001777 fBounds is used as a hint to limit the size of Layer; may be nullptr.
1778 fBounds suggests but does not define Layer size. To clip drawing to
1779 a specific rectangle, use clipRect.
1780##
1781
1782#Member const SkPaint* fPaint
Cary Clark682c58d2018-05-16 07:07:07 -04001783#Line # modifies overlay ##
Cary Clarkce101242017-09-01 15:51:02 -04001784 fPaint modifies how Layer overlays the prior Layer; may be nullptr.
1785 Color_Alpha, Blend_Mode, Color_Filter, Draw_Looper, Image_Filter, and
1786 Mask_Filter affect Layer draw.
1787##
1788
1789#Member const SkImageFilter* fBackdrop
Cary Clark682c58d2018-05-16 07:07:07 -04001790#Line # applies Image_Filter to prior Layer ##
Cary Clarkce101242017-09-01 15:51:02 -04001791 fBackdrop applies Image_Filter to the prior Layer when copying to the Layer;
1792 may be nullptr. Use kInitWithPrevious_SaveLayerFlag to copy the
1793 prior Layer without an Image_Filter.
1794##
1795
1796#Member const SkImage* fClipMask
Cary Clark682c58d2018-05-16 07:07:07 -04001797#Line # clips Layer with Mask_Alpha ##
Cary Clarkce101242017-09-01 15:51:02 -04001798 restore() clips Layer by the Color_Alpha channel of fClipMask when
1799 Layer is copied to Device. fClipMask may be nullptr. .
1800##
1801
1802#Member const SkMatrix* fClipMatrix
Cary Clark682c58d2018-05-16 07:07:07 -04001803#Line # transforms Mask_Alpha used to clip ##
Herb Derbyefe39bc2018-05-01 17:06:20 -04001804 fClipMatrix transforms fClipMask before it clips Layer. If
Cary Clarkce101242017-09-01 15:51:02 -04001805 fClipMask describes a translucent gradient, it may be scaled and rotated
1806 without introducing artifacts. fClipMatrix may be nullptr.
1807##
1808
1809#Member SaveLayerFlags fSaveLayerFlags
Cary Clark682c58d2018-05-16 07:07:07 -04001810#Line # preserves LCD Text, creates with prior Layer contents ##
Cary Clarkce101242017-09-01 15:51:02 -04001811 fSaveLayerFlags are used to create Layer without transparency,
1812 create Layer for LCD text, and to create Layer with the
1813 contents of the previous Layer.
1814##
1815
1816#Example
1817#Height 160
1818#Description
Cary Clarkffb3d682018-05-17 12:17:28 -04001819Canvas Layer captures a red Anti_Aliased circle and a blue Aliased circle scaled
Cary Clarkce101242017-09-01 15:51:02 -04001820up by four. After drawing another red circle without scaling on top, the Layer is
Herb Derbyefe39bc2018-05-01 17:06:20 -04001821transferred to the main canvas.
Cary Clarkce101242017-09-01 15:51:02 -04001822##
1823void draw(SkCanvas* canvas) {
1824 SkPaint redPaint, bluePaint;
1825 redPaint.setAntiAlias(true);
1826 redPaint.setColor(SK_ColorRED);
1827 canvas->drawCircle(21, 21, 8, redPaint);
1828 bluePaint.setColor(SK_ColorBLUE);
1829 canvas->drawCircle(31, 21, 8, bluePaint);
1830 SkMatrix matrix;
1831 matrix.setScale(4, 4);
1832 auto scaler = SkImageFilter::MakeMatrixFilter(matrix, kNone_SkFilterQuality, nullptr);
Herb Derbyefe39bc2018-05-01 17:06:20 -04001833 SkCanvas::SaveLayerRec saveLayerRec(nullptr, nullptr, scaler.get(), 0);
Cary Clarkce101242017-09-01 15:51:02 -04001834 canvas->saveLayer(saveLayerRec);
1835 canvas->drawCircle(125, 85, 8, redPaint);
1836 canvas->restore();
1837}
1838##
1839
Cary Clark682c58d2018-05-16 07:07:07 -04001840#Subtopic Constructor
1841#Populate
1842##
Cary Clarkce101242017-09-01 15:51:02 -04001843
Cary Clark682c58d2018-05-16 07:07:07 -04001844#Method SaveLayerRec()
1845#Line # constructs SaveLayerRec ##
Cary Clarkce101242017-09-01 15:51:02 -04001846Sets fBounds, fPaint, and fBackdrop to nullptr. Clears fSaveLayerFlags.
1847
1848#Return empty SaveLayerRec ##
1849
1850#Example
1851 SkCanvas::SaveLayerRec rec1;
Mike Kleine083f7c2018-02-07 12:54:27 -05001852 rec1.fSaveLayerFlags = SkCanvas::kPreserveLCDText_SaveLayerFlag;
1853 SkCanvas::SaveLayerRec rec2(nullptr, nullptr, SkCanvas::kPreserveLCDText_SaveLayerFlag);
Cary Clarkce101242017-09-01 15:51:02 -04001854 SkDebugf("rec1 %c= rec2\n", rec1.fBounds == rec2.fBounds
1855 && rec1.fPaint == rec2.fPaint
1856 && rec1.fBackdrop == rec2.fBackdrop
1857 && rec1.fSaveLayerFlags == rec2.fSaveLayerFlags ? '=' : '!');
1858 #StdOut
1859 rec1 == rec2
1860 ##
1861##
1862
Cary Clark2ade9972017-11-02 17:49:34 -04001863#SeeAlso save() restore() saveLayer saveLayerPreserveLCDTextRequests saveLayerAlpha
1864
Cary Clarkce101242017-09-01 15:51:02 -04001865##
1866
Cary Clarkd98f78c2018-04-26 08:32:37 -04001867#Method SaveLayerRec(const SkRect* bounds, const SkPaint* paint,
1868 SaveLayerFlags saveLayerFlags = 0)
Cary Clarkce101242017-09-01 15:51:02 -04001869
1870Sets fBounds, fPaint, and fSaveLayerFlags; sets fBackdrop to nullptr.
1871
1872#Param bounds Layer dimensions; may be nullptr ##
1873#Param paint applied to Layer when overlaying prior Layer; may be nullptr ##
1874#Param saveLayerFlags SaveLayerRec options to modify Layer ##
1875
1876#Return SaveLayerRec with empty backdrop ##
1877
1878#Example
1879 SkCanvas::SaveLayerRec rec1;
1880 SkCanvas::SaveLayerRec rec2(nullptr, nullptr);
1881 SkDebugf("rec1 %c= rec2\n", rec1.fBounds == rec2.fBounds
1882 && rec1.fPaint == rec2.fPaint
1883 && rec1.fBackdrop == rec2.fBackdrop
1884 && rec1.fSaveLayerFlags == rec2.fSaveLayerFlags ? '=' : '!');
1885 #StdOut
1886 rec1 == rec2
1887 ##
1888##
1889
Cary Clark2ade9972017-11-02 17:49:34 -04001890#SeeAlso save() restore() saveLayer saveLayerPreserveLCDTextRequests saveLayerAlpha
1891
Cary Clarkce101242017-09-01 15:51:02 -04001892##
1893
1894#Method SaveLayerRec(const SkRect* bounds, const SkPaint* paint, const SkImageFilter* backdrop,
1895 SaveLayerFlags saveLayerFlags)
1896
1897Sets fBounds, fPaint, fBackdrop, and fSaveLayerFlags.
1898
1899#Param bounds Layer dimensions; may be nullptr ##
1900#Param paint applied to Layer when overlaying prior Layer;
1901 may be nullptr
1902##
1903#Param backdrop prior Layer copied with Image_Filter; may be nullptr
1904##
1905#Param saveLayerFlags SaveLayerRec options to modify Layer ##
1906
1907#Return SaveLayerRec fully specified ##
1908
1909#Example
1910 SkCanvas::SaveLayerRec rec1;
1911 SkCanvas::SaveLayerRec rec2(nullptr, nullptr, nullptr, 0);
1912 SkDebugf("rec1 %c= rec2\n", rec1.fBounds == rec2.fBounds
1913 && rec1.fPaint == rec2.fPaint
1914 && rec1.fBackdrop == rec2.fBackdrop
1915 && rec1.fSaveLayerFlags == rec2.fSaveLayerFlags ? '=' : '!');
1916 #StdOut
1917 rec1 == rec2
1918 ##
1919##
1920
Cary Clark2ade9972017-11-02 17:49:34 -04001921#SeeAlso save() restore() saveLayer saveLayerPreserveLCDTextRequests saveLayerAlpha
1922
Cary Clarkce101242017-09-01 15:51:02 -04001923##
1924
1925#Method SaveLayerRec(const SkRect* bounds, const SkPaint* paint, const SkImageFilter* backdrop,
1926 const SkImage* clipMask, const SkMatrix* clipMatrix,
1927 SaveLayerFlags saveLayerFlags)
1928
Cary Clark682c58d2018-05-16 07:07:07 -04001929#Experimental not ready
Cary Clarkce101242017-09-01 15:51:02 -04001930
1931Sets fBounds, fPaint, fBackdrop, fClipMask, fClipMatrix, and fSaveLayerFlags.
1932clipMatrix uses Color_Alpha channel of image, transformed by clipMatrix, to clip
1933Layer when drawn to Canvas.
1934
Cary Clark2ade9972017-11-02 17:49:34 -04001935Implementation is not complete; has no effect if Device is GPU-backed.
Cary Clarkce101242017-09-01 15:51:02 -04001936
1937#Param bounds Layer dimensions; may be nullptr ##
1938#Param paint graphics state applied to Layer when overlaying prior
1939 Layer; may be nullptr
1940##
1941#Param backdrop prior Layer copied with Image_Filter;
1942 may be nullptr
1943##
1944#Param clipMask clip applied to Layer; may be nullptr ##
1945#Param clipMatrix matrix applied to clipMask; may be nullptr to use
Herb Derbyefe39bc2018-05-01 17:06:20 -04001946 identity matrix
Cary Clarkce101242017-09-01 15:51:02 -04001947##
1948#Param saveLayerFlags SaveLayerRec options to modify Layer ##
1949
1950#Return SaveLayerRec fully specified ##
1951
Cary Clark2ade9972017-11-02 17:49:34 -04001952#SeeAlso save() restore() saveLayer saveLayerPreserveLCDTextRequests saveLayerAlpha
Cary Clarkce101242017-09-01 15:51:02 -04001953
1954##
1955
1956#Struct ##
1957
Cary Clark682c58d2018-05-16 07:07:07 -04001958#Subtopic ##
1959
Cary Clarkce101242017-09-01 15:51:02 -04001960#Method int saveLayer(const SaveLayerRec& layerRec)
1961
Cary Clarkab2621d2018-01-30 10:08:57 -05001962#In Layer
Cary Clarkce101242017-09-01 15:51:02 -04001963Saves Matrix, Clip, and Draw_Filter (Draw_Filter deprecated on most platforms),
1964and allocates Bitmap for subsequent drawing.
1965
1966Calling restore() discards changes to Matrix, Clip, and Draw_Filter,
1967and blends Bitmap with Color_Alpha opacity onto the prior Layer.
1968
1969Matrix may be changed by translate(), scale(), rotate(), skew(), concat(),
1970setMatrix, and resetMatrix. Clip may be changed by clipRect, clipRRect,
1971clipPath, clipRegion.
1972
1973SaveLayerRec contains the state used to create the Layer.
1974
1975Call restoreToCount with returned value to restore this and subsequent saves.
1976
1977#Param layerRec Layer state ##
1978
1979#Return depth of save state stack ##
1980
1981#Example
1982#Description
1983The example draws an image, and saves it into a Layer with kInitWithPrevious_SaveLayerFlag.
1984Next it punches a hole in Layer and restore with SkBlendMode::kPlus.
1985Where Layer was cleared, the original image will draw unchanged.
1986Outside of the circle the mandrill is brightened.
1987##
1988 #Image 3
Hal Canaryc465d132017-12-08 10:21:31 -05001989 // sk_sp<SkImage> image = GetResourceAsImage("images/mandrill_256.png");
Cary Clarkce101242017-09-01 15:51:02 -04001990 canvas->drawImage(image, 0, 0, nullptr);
1991 SkCanvas::SaveLayerRec rec;
1992 SkPaint paint;
1993 paint.setBlendMode(SkBlendMode::kPlus);
1994 rec.fSaveLayerFlags = SkCanvas::kInitWithPrevious_SaveLayerFlag;
1995 rec.fPaint = &paint;
1996 canvas->saveLayer(rec);
1997 paint.setBlendMode(SkBlendMode::kClear);
1998 canvas->drawCircle(128, 128, 96, paint);
1999 canvas->restore();
2000##
2001
2002#ToDo above example needs to replace GetResourceAsImage with way to select image in fiddle ##
2003
Cary Clark2ade9972017-11-02 17:49:34 -04002004#SeeAlso save() restore() saveLayer saveLayerPreserveLCDTextRequests saveLayerAlpha
2005
Cary Clarkce101242017-09-01 15:51:02 -04002006##
2007
Cary Clark08895c42018-02-01 09:37:32 -05002008#Subtopic Layer ##
Cary Clarkce101242017-09-01 15:51:02 -04002009
2010# ------------------------------------------------------------------------------
Cary Clark08895c42018-02-01 09:37:32 -05002011#Subtopic Matrix
2012#Line # coordinate transformation ##
Cary Clark8032b982017-07-28 11:04:54 -04002013
2014#Method void translate(SkScalar dx, SkScalar dy)
2015
Cary Clarkab2621d2018-01-30 10:08:57 -05002016#In Matrix
2017#Line # translates Matrix ##
Cary Clark8032b982017-07-28 11:04:54 -04002018Translate Matrix by dx along the x-axis and dy along the y-axis.
2019
2020Mathematically, replace Matrix with a translation matrix
Herb Derbyefe39bc2018-05-01 17:06:20 -04002021Premultiplied with Matrix.
Cary Clark8032b982017-07-28 11:04:54 -04002022
2023This has the effect of moving the drawing by (dx, dy) before transforming
2024the result with Matrix.
2025
Cary Clarkbad5ad72017-08-03 17:14:08 -04002026#Param dx distance to translate in x ##
2027#Param dy distance to translate in y ##
Cary Clark8032b982017-07-28 11:04:54 -04002028
2029#Example
2030#Height 128
2031#Description
2032scale() followed by translate() produces different results from translate() followed
Herb Derbyefe39bc2018-05-01 17:06:20 -04002033by scale().
Cary Clark8032b982017-07-28 11:04:54 -04002034
2035The blue stroke follows translate of (50, 50); a black
Herb Derbyefe39bc2018-05-01 17:06:20 -04002036fill follows scale of (2, 1/2.f). After restoring the clip, which resets
Cary Clark8032b982017-07-28 11:04:54 -04002037Matrix, a red frame follows the same scale of (2, 1/2.f); a gray fill
2038follows translate of (50, 50).
2039##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002040void draw(SkCanvas* canvas) {
2041 SkPaint filledPaint;
2042 SkPaint outlinePaint;
2043 outlinePaint.setStyle(SkPaint::kStroke_Style);
2044 outlinePaint.setColor(SK_ColorBLUE);
2045 canvas->save();
2046 canvas->translate(50, 50);
2047 canvas->drawCircle(28, 28, 15, outlinePaint); // blue center: (50+28, 50+28)
2048 canvas->scale(2, 1/2.f);
2049 canvas->drawCircle(28, 28, 15, filledPaint); // black center: (50+(28*2), 50+(28/2))
2050 canvas->restore();
2051 filledPaint.setColor(SK_ColorGRAY);
2052 outlinePaint.setColor(SK_ColorRED);
2053 canvas->scale(2, 1/2.f);
2054 canvas->drawCircle(28, 28, 15, outlinePaint); // red center: (28*2, 28/2)
2055 canvas->translate(50, 50);
2056 canvas->drawCircle(28, 28, 15, filledPaint); // gray center: ((50+28)*2, (50+28)/2)
Cary Clark8032b982017-07-28 11:04:54 -04002057}
2058##
2059
Cary Clark2ade9972017-11-02 17:49:34 -04002060#SeeAlso concat() scale() skew() rotate() setMatrix
Cary Clark8032b982017-07-28 11:04:54 -04002061
2062##
2063
2064# ------------------------------------------------------------------------------
2065
2066#Method void scale(SkScalar sx, SkScalar sy)
2067
Cary Clarkab2621d2018-01-30 10:08:57 -05002068#In Matrix
2069#Line # scales Matrix ##
Cary Clark8032b982017-07-28 11:04:54 -04002070Scale Matrix by sx on the x-axis and sy on the y-axis.
2071
2072Mathematically, replace Matrix with a scale matrix
Herb Derbyefe39bc2018-05-01 17:06:20 -04002073Premultiplied with Matrix.
Cary Clark8032b982017-07-28 11:04:54 -04002074
2075This has the effect of scaling the drawing by (sx, sy) before transforming
2076the result with Matrix.
2077
Cary Clarkbad5ad72017-08-03 17:14:08 -04002078#Param sx amount to scale in x ##
2079#Param sy amount to scale in y ##
Cary Clark8032b982017-07-28 11:04:54 -04002080
2081#Example
2082#Height 160
Cary Clarkbad5ad72017-08-03 17:14:08 -04002083void draw(SkCanvas* canvas) {
2084 SkPaint paint;
2085 SkRect rect = { 10, 20, 60, 120 };
2086 canvas->translate(20, 20);
2087 canvas->drawRect(rect, paint);
2088 canvas->scale(2, .5f);
2089 paint.setColor(SK_ColorGRAY);
2090 canvas->drawRect(rect, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002091}
2092##
2093
Cary Clark2ade9972017-11-02 17:49:34 -04002094#SeeAlso concat() translate() skew() rotate() setMatrix
Cary Clark8032b982017-07-28 11:04:54 -04002095
2096##
2097
2098# ------------------------------------------------------------------------------
2099
2100#Method void rotate(SkScalar degrees)
2101
Cary Clarkab2621d2018-01-30 10:08:57 -05002102#In Matrix
2103#Line # rotates Matrix ##
Cary Clark8032b982017-07-28 11:04:54 -04002104Rotate Matrix by degrees. Positive degrees rotates clockwise.
2105
2106Mathematically, replace Matrix with a rotation matrix
Herb Derbyefe39bc2018-05-01 17:06:20 -04002107Premultiplied with Matrix.
Cary Clark8032b982017-07-28 11:04:54 -04002108
2109This has the effect of rotating the drawing by degrees before transforming
2110the result with Matrix.
2111
Cary Clarkbad5ad72017-08-03 17:14:08 -04002112#Param degrees amount to rotate, in degrees ##
Cary Clark8032b982017-07-28 11:04:54 -04002113
2114#Example
2115#Description
2116Draw clock hands at time 5:10. The hour hand and minute hand point up and
2117are rotated clockwise.
2118##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002119void draw(SkCanvas* canvas) {
2120 SkPaint paint;
2121 paint.setStyle(SkPaint::kStroke_Style);
2122 canvas->translate(128, 128);
2123 canvas->drawCircle(0, 0, 60, paint);
2124 canvas->save();
2125 canvas->rotate(10 * 360 / 60); // 10 minutes of 60 scaled to 360 degrees
Herb Derbyefe39bc2018-05-01 17:06:20 -04002126 canvas->drawLine(0, 0, 0, -50, paint);
Cary Clarkbad5ad72017-08-03 17:14:08 -04002127 canvas->restore();
2128 canvas->rotate((5 + 10.f/60) * 360 / 12); // 5 and 10/60 hours of 12 scaled to 360 degrees
2129 canvas->drawLine(0, 0, 0, -30, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002130}
2131##
2132
Cary Clark2ade9972017-11-02 17:49:34 -04002133#SeeAlso concat() translate() skew() scale() setMatrix
Cary Clark8032b982017-07-28 11:04:54 -04002134
2135##
2136
2137# ------------------------------------------------------------------------------
2138
2139#Method void rotate(SkScalar degrees, SkScalar px, SkScalar py)
2140
Cary Clarkab2621d2018-01-30 10:08:57 -05002141#In Matrix
Cary Clarkbad5ad72017-08-03 17:14:08 -04002142Rotate Matrix by degrees about a point at (px, py). Positive degrees rotates
2143clockwise.
Cary Clark8032b982017-07-28 11:04:54 -04002144
Cary Clarkce101242017-09-01 15:51:02 -04002145Mathematically, construct a rotation matrix. Premultiply the rotation matrix by
Cary Clark8032b982017-07-28 11:04:54 -04002146a translation matrix, then replace Matrix with the resulting matrix
Herb Derbyefe39bc2018-05-01 17:06:20 -04002147Premultiplied with Matrix.
Cary Clark8032b982017-07-28 11:04:54 -04002148
Cary Clarkbad5ad72017-08-03 17:14:08 -04002149This has the effect of rotating the drawing about a given point before
2150transforming the result with Matrix.
Cary Clark8032b982017-07-28 11:04:54 -04002151
Cary Clarkbad5ad72017-08-03 17:14:08 -04002152#Param degrees amount to rotate, in degrees ##
2153#Param px x-coordinate of the point to rotate about ##
2154#Param py y-coordinate of the point to rotate about ##
Cary Clark8032b982017-07-28 11:04:54 -04002155
2156#Example
2157#Height 192
Cary Clarkbad5ad72017-08-03 17:14:08 -04002158void draw(SkCanvas* canvas) {
2159 SkPaint paint;
2160 paint.setTextSize(96);
2161 canvas->drawString("A1", 130, 100, paint);
2162 canvas->rotate(180, 130, 100);
2163 canvas->drawString("A1", 130, 100, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002164}
2165##
2166
Cary Clark2ade9972017-11-02 17:49:34 -04002167#SeeAlso concat() translate() skew() scale() setMatrix
Cary Clark8032b982017-07-28 11:04:54 -04002168
2169##
2170
2171# ------------------------------------------------------------------------------
2172
2173#Method void skew(SkScalar sx, SkScalar sy)
2174
Cary Clarkab2621d2018-01-30 10:08:57 -05002175#In Matrix
2176#Line # skews Matrix ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002177Skew Matrix by sx on the x-axis and sy on the y-axis. A positive value of sx
2178skews the drawing right as y increases; a positive value of sy skews the drawing
2179down as x increases.
Cary Clark8032b982017-07-28 11:04:54 -04002180
Herb Derbyefe39bc2018-05-01 17:06:20 -04002181Mathematically, replace Matrix with a skew matrix Premultiplied with Matrix.
Cary Clark8032b982017-07-28 11:04:54 -04002182
Cary Clarkbad5ad72017-08-03 17:14:08 -04002183This has the effect of skewing the drawing by (sx, sy) before transforming
Cary Clark8032b982017-07-28 11:04:54 -04002184the result with Matrix.
2185
Cary Clarkbad5ad72017-08-03 17:14:08 -04002186#Param sx amount to skew in x ##
2187#Param sy amount to skew in y ##
2188
Cary Clark8032b982017-07-28 11:04:54 -04002189#Example
Herb Derbyefe39bc2018-05-01 17:06:20 -04002190 #Description
Cary Clark8032b982017-07-28 11:04:54 -04002191 Black text mimics an oblique text style by using a negative skew in x that
2192 shifts the geometry to the right as the y values decrease.
2193 Red text uses a positive skew in y to shift the geometry down as the x values
2194 increase.
2195 Blue text combines x and y skew to rotate and scale.
2196 ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002197 SkPaint paint;
2198 paint.setTextSize(128);
2199 canvas->translate(30, 130);
2200 canvas->save();
2201 canvas->skew(-.5, 0);
2202 canvas->drawString("A1", 0, 0, paint);
2203 canvas->restore();
2204 canvas->save();
2205 canvas->skew(0, .5);
2206 paint.setColor(SK_ColorRED);
2207 canvas->drawString("A1", 0, 0, paint);
2208 canvas->restore();
2209 canvas->skew(-.5, .5);
2210 paint.setColor(SK_ColorBLUE);
Cary Clark8032b982017-07-28 11:04:54 -04002211 canvas->drawString("A1", 0, 0, paint);
2212##
2213
Cary Clark2ade9972017-11-02 17:49:34 -04002214#SeeAlso concat() translate() rotate() scale() setMatrix
Cary Clark8032b982017-07-28 11:04:54 -04002215
2216##
2217
2218# ------------------------------------------------------------------------------
2219
2220#Method void concat(const SkMatrix& matrix)
2221
Cary Clarkab2621d2018-01-30 10:08:57 -05002222#In Matrix
2223#Line # multiplies Matrix by Matrix ##
Cary Clarkce101242017-09-01 15:51:02 -04002224Replace Matrix with matrix Premultiplied with existing Matrix.
Cary Clark8032b982017-07-28 11:04:54 -04002225
Cary Clarkbad5ad72017-08-03 17:14:08 -04002226This has the effect of transforming the drawn geometry by matrix, before
2227transforming the result with existing Matrix.
Cary Clark8032b982017-07-28 11:04:54 -04002228
Cary Clarkce101242017-09-01 15:51:02 -04002229#Param matrix matrix to Premultiply with existing Matrix ##
Cary Clark8032b982017-07-28 11:04:54 -04002230
2231#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04002232void draw(SkCanvas* canvas) {
2233 SkPaint paint;
2234 paint.setTextSize(80);
2235 paint.setTextScaleX(.3);
2236 SkMatrix matrix;
2237 SkRect rect[2] = {{ 10, 20, 90, 110 }, { 40, 130, 140, 180 }};
2238 matrix.setRectToRect(rect[0], rect[1], SkMatrix::kFill_ScaleToFit);
2239 canvas->drawRect(rect[0], paint);
2240 canvas->drawRect(rect[1], paint);
2241 paint.setColor(SK_ColorWHITE);
2242 canvas->drawString("Here", rect[0].fLeft + 10, rect[0].fBottom - 10, paint);
2243 canvas->concat(matrix);
2244 canvas->drawString("There", rect[0].fLeft + 10, rect[0].fBottom - 10, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002245}
2246##
2247
Cary Clark2ade9972017-11-02 17:49:34 -04002248#SeeAlso translate() rotate() scale() skew() setMatrix
Cary Clark8032b982017-07-28 11:04:54 -04002249
2250##
2251
2252# ------------------------------------------------------------------------------
2253
2254#Method void setMatrix(const SkMatrix& matrix)
2255
Cary Clarkab2621d2018-01-30 10:08:57 -05002256#In Matrix
2257#Line # sets Matrix ##
Cary Clark8032b982017-07-28 11:04:54 -04002258Replace Matrix with matrix.
2259Unlike concat(), any prior matrix state is overwritten.
2260
Cary Clarkbad5ad72017-08-03 17:14:08 -04002261#Param matrix matrix to copy, replacing existing Matrix ##
Cary Clark8032b982017-07-28 11:04:54 -04002262
2263#Example
2264#Height 128
Cary Clarkbad5ad72017-08-03 17:14:08 -04002265void draw(SkCanvas* canvas) {
2266 SkPaint paint;
2267 canvas->scale(4, 6);
2268 canvas->drawString("truth", 2, 10, paint);
2269 SkMatrix matrix;
2270 matrix.setScale(2.8f, 6);
2271 canvas->setMatrix(matrix);
2272 canvas->drawString("consequences", 2, 20, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002273}
2274##
2275
Cary Clark2ade9972017-11-02 17:49:34 -04002276#SeeAlso resetMatrix concat() translate() rotate() scale() skew()
Cary Clark8032b982017-07-28 11:04:54 -04002277
2278##
2279
2280# ------------------------------------------------------------------------------
2281
2282#Method void resetMatrix()
2283
Cary Clarkab2621d2018-01-30 10:08:57 -05002284#In Matrix
2285#Line # resets Matrix to identity ##
Cary Clark8032b982017-07-28 11:04:54 -04002286Sets Matrix to the identity matrix.
2287Any prior matrix state is overwritten.
2288
2289#Example
2290#Height 128
Cary Clarkbad5ad72017-08-03 17:14:08 -04002291void draw(SkCanvas* canvas) {
2292 SkPaint paint;
2293 canvas->scale(4, 6);
2294 canvas->drawString("truth", 2, 10, paint);
2295 canvas->resetMatrix();
2296 canvas->scale(2.8f, 6);
2297 canvas->drawString("consequences", 2, 20, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002298}
2299##
2300
Cary Clark2ade9972017-11-02 17:49:34 -04002301#SeeAlso setMatrix concat() translate() rotate() scale() skew()
Cary Clark8032b982017-07-28 11:04:54 -04002302
2303##
2304
2305# ------------------------------------------------------------------------------
2306
2307#Method const SkMatrix& getTotalMatrix() const
2308
Cary Clarkab2621d2018-01-30 10:08:57 -05002309#In Matrix
2310#Line # returns Matrix ##
Cary Clark8032b982017-07-28 11:04:54 -04002311Returns Matrix.
2312This does not account for translation by Device or Surface.
2313
Cary Clarkbad5ad72017-08-03 17:14:08 -04002314#Return Matrix in Canvas ##
Cary Clark8032b982017-07-28 11:04:54 -04002315
2316#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04002317 SkDebugf("isIdentity %s\n", canvas->getTotalMatrix().isIdentity() ? "true" : "false");
2318 #StdOut
2319 isIdentity true
2320 ##
Cary Clark8032b982017-07-28 11:04:54 -04002321##
2322
Cary Clark2ade9972017-11-02 17:49:34 -04002323#SeeAlso setMatrix resetMatrix concat()
Cary Clark8032b982017-07-28 11:04:54 -04002324
2325##
2326
Cary Clark08895c42018-02-01 09:37:32 -05002327#Subtopic Matrix ##
Cary Clark8032b982017-07-28 11:04:54 -04002328
2329# ------------------------------------------------------------------------------
Cary Clark08895c42018-02-01 09:37:32 -05002330#Subtopic Clip
2331#Line # stack of clipping Paths ##
Cary Clark8032b982017-07-28 11:04:54 -04002332
2333Clip is built from a stack of clipping paths. Each Path in the
Herb Derbyefe39bc2018-05-01 17:06:20 -04002334stack can be constructed from one or more Path_Contour elements. The
Cary Clark8032b982017-07-28 11:04:54 -04002335Path_Contour may be composed of any number of Path_Verb segments. Each
2336Path_Contour forms a closed area; Path_Fill_Type defines the area enclosed
2337by Path_Contour.
2338
2339Clip stack of Path elements successfully restrict the Path area. Each
Herb Derbyefe39bc2018-05-01 17:06:20 -04002340Path is transformed by Matrix, then intersected with or subtracted from the
Cary Clark8032b982017-07-28 11:04:54 -04002341prior Clip to form the replacement Clip. Use SkClipOp::kDifference
2342to subtract Path from Clip; use SkClipOp::kIntersect to intersect Path
2343with Clip.
2344
Cary Clarkffb3d682018-05-17 12:17:28 -04002345A clipping Path may be Anti_Aliased; if Path, after transformation, is
2346composed of horizontal and vertical lines, clearing Anti_Alias allows whole pixels
Cary Clarkce101242017-09-01 15:51:02 -04002347to either be inside or outside the clip. The fastest drawing has a Aliased,
2348rectangular clip.
Cary Clark8032b982017-07-28 11:04:54 -04002349
Cary Clarkffb3d682018-05-17 12:17:28 -04002350If clipping Path has Anti_Alias set, clip may partially clip a pixel, requiring
Herb Derbyefe39bc2018-05-01 17:06:20 -04002351that drawing blend partially with the destination along the edge. A rotated
Cary Clarkffb3d682018-05-17 12:17:28 -04002352rectangular Anti_Aliased clip looks smoother but draws slower.
Cary Clark8032b982017-07-28 11:04:54 -04002353
2354Clip can combine with Rect and Round_Rect primitives; like
2355Path, these are transformed by Matrix before they are combined with Clip.
2356
2357Clip can combine with Region. Region is assumed to be in Device coordinates
2358and is unaffected by Matrix.
2359
2360#Example
2361#Height 90
2362 #Description
Cary Clarkffb3d682018-05-17 12:17:28 -04002363 Draw a red circle with an Aliased clip and an Anti_Aliased clip.
Cary Clark8032b982017-07-28 11:04:54 -04002364 Use an image filter to zoom into the pixels drawn.
Cary Clarkce101242017-09-01 15:51:02 -04002365 The edge of the Aliased clip fully draws pixels in the red circle.
Cary Clarkffb3d682018-05-17 12:17:28 -04002366 The edge of the Anti_Aliased clip partially draws pixels in the red circle.
Cary Clark8032b982017-07-28 11:04:54 -04002367 ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002368 SkPaint redPaint, scalePaint;
2369 redPaint.setAntiAlias(true);
2370 redPaint.setColor(SK_ColorRED);
2371 canvas->save();
2372 for (bool antialias : { false, true } ) {
2373 canvas->save();
2374 canvas->clipRect(SkRect::MakeWH(19.5f, 11.5f), antialias);
2375 canvas->drawCircle(17, 11, 8, redPaint);
2376 canvas->restore();
2377 canvas->translate(16, 0);
2378 }
2379 canvas->restore();
2380 SkMatrix matrix;
2381 matrix.setScale(6, 6);
2382 scalePaint.setImageFilter(
2383 SkImageFilter::MakeMatrixFilter(matrix, kNone_SkFilterQuality, nullptr));
2384 SkCanvas::SaveLayerRec saveLayerRec(
Herb Derbyefe39bc2018-05-01 17:06:20 -04002385 nullptr, &scalePaint, SkCanvas::kInitWithPrevious_SaveLayerFlag);
Cary Clarkbad5ad72017-08-03 17:14:08 -04002386 canvas->saveLayer(saveLayerRec);
Cary Clark8032b982017-07-28 11:04:54 -04002387 canvas->restore();
2388##
2389
2390#Method void clipRect(const SkRect& rect, SkClipOp op, bool doAntiAlias)
2391
Cary Clarkab2621d2018-01-30 10:08:57 -05002392#In Clip
2393#Line # combines Clip with Rect ##
Cary Clark8032b982017-07-28 11:04:54 -04002394Replace Clip with the intersection or difference of Clip and rect,
Cary Clarkffb3d682018-05-17 12:17:28 -04002395with an Aliased or Anti_Aliased clip edge. rect is transformed by Matrix
Cary Clark8032b982017-07-28 11:04:54 -04002396before it is combined with Clip.
2397
Cary Clarka523d2d2017-08-30 08:58:10 -04002398#Param rect Rect to combine with Clip ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002399#Param op Clip_Op to apply to Clip ##
Cary Clarkffb3d682018-05-17 12:17:28 -04002400#Param doAntiAlias true if Clip is to be Anti_Aliased ##
Cary Clark8032b982017-07-28 11:04:54 -04002401
2402#Example
2403#Height 128
Cary Clarkbad5ad72017-08-03 17:14:08 -04002404void draw(SkCanvas* canvas) {
2405 canvas->rotate(10);
2406 SkPaint paint;
2407 paint.setAntiAlias(true);
2408 for (auto alias: { false, true } ) {
2409 canvas->save();
2410 canvas->clipRect(SkRect::MakeWH(90, 80), SkClipOp::kIntersect, alias);
2411 canvas->drawCircle(100, 60, 60, paint);
2412 canvas->restore();
2413 canvas->translate(80, 0);
2414 }
Cary Clark8032b982017-07-28 11:04:54 -04002415}
2416##
2417
Cary Clark2ade9972017-11-02 17:49:34 -04002418#SeeAlso clipRRect clipPath clipRegion
Cary Clark8032b982017-07-28 11:04:54 -04002419
2420##
2421
Herb Derbyefe39bc2018-05-01 17:06:20 -04002422#Method void clipRect(const SkRect& rect, SkClipOp op)
Cary Clark8032b982017-07-28 11:04:54 -04002423
Cary Clarkab2621d2018-01-30 10:08:57 -05002424#In Clip
Cary Clark8032b982017-07-28 11:04:54 -04002425Replace Clip with the intersection or difference of Clip and rect.
Cary Clarkce101242017-09-01 15:51:02 -04002426Resulting Clip is Aliased; pixels are fully contained by the clip.
Cary Clarkbad5ad72017-08-03 17:14:08 -04002427rect is transformed by Matrix before it is combined with Clip.
Cary Clark8032b982017-07-28 11:04:54 -04002428
Cary Clarka523d2d2017-08-30 08:58:10 -04002429#Param rect Rect to combine with Clip ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002430#Param op Clip_Op to apply to Clip ##
Cary Clark8032b982017-07-28 11:04:54 -04002431
2432#Example
2433#Height 192
2434#Width 280
Cary Clarkbad5ad72017-08-03 17:14:08 -04002435void draw(SkCanvas* canvas) {
2436 SkPaint paint;
2437 for (SkClipOp op: { SkClipOp::kIntersect, SkClipOp::kDifference } ) {
2438 canvas->save();
2439 canvas->clipRect(SkRect::MakeWH(90, 120), op, false);
2440 canvas->drawCircle(100, 100, 60, paint);
2441 canvas->restore();
2442 canvas->translate(80, 0);
2443 }
Cary Clark8032b982017-07-28 11:04:54 -04002444}
2445##
2446
Cary Clark2ade9972017-11-02 17:49:34 -04002447#SeeAlso clipRRect clipPath clipRegion
Cary Clark8032b982017-07-28 11:04:54 -04002448
2449##
2450
Herb Derbyefe39bc2018-05-01 17:06:20 -04002451#Method void clipRect(const SkRect& rect, bool doAntiAlias = false)
Cary Clark8032b982017-07-28 11:04:54 -04002452
Cary Clarkab2621d2018-01-30 10:08:57 -05002453#In Clip
Cary Clark8032b982017-07-28 11:04:54 -04002454Replace Clip with the intersection of Clip and rect.
Cary Clarkce101242017-09-01 15:51:02 -04002455Resulting Clip is Aliased; pixels are fully contained by the clip.
Cary Clark8032b982017-07-28 11:04:54 -04002456rect is transformed by Matrix
2457before it is combined with Clip.
2458
Cary Clarka523d2d2017-08-30 08:58:10 -04002459#Param rect Rect to combine with Clip ##
Cary Clarkffb3d682018-05-17 12:17:28 -04002460#Param doAntiAlias true if Clip is to be Anti_Aliased ##
Cary Clark8032b982017-07-28 11:04:54 -04002461
2462#Example
2463#Height 133
2464 #Description
Cary Clarkce101242017-09-01 15:51:02 -04002465 A circle drawn in pieces looks uniform when drawn Aliased.
Cary Clarkffb3d682018-05-17 12:17:28 -04002466 The same circle pieces blend with pixels more than once when Anti_Aliased,
Cary Clark8032b982017-07-28 11:04:54 -04002467 visible as a thin pair of lines through the right circle.
2468 ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002469void draw(SkCanvas* canvas) {
2470 canvas->clear(SK_ColorWHITE);
2471 SkPaint paint;
2472 paint.setAntiAlias(true);
2473 paint.setColor(0x8055aaff);
2474 SkRect clipRect = { 0, 0, 87.4f, 87.4f };
2475 for (auto alias: { false, true } ) {
2476 canvas->save();
2477 canvas->clipRect(clipRect, SkClipOp::kIntersect, alias);
2478 canvas->drawCircle(67, 67, 60, paint);
2479 canvas->restore();
2480 canvas->save();
2481 canvas->clipRect(clipRect, SkClipOp::kDifference, alias);
2482 canvas->drawCircle(67, 67, 60, paint);
2483 canvas->restore();
2484 canvas->translate(120, 0);
2485 }
Cary Clark8032b982017-07-28 11:04:54 -04002486}
2487##
2488
Cary Clark2ade9972017-11-02 17:49:34 -04002489#SeeAlso clipRRect clipPath clipRegion
Cary Clark8032b982017-07-28 11:04:54 -04002490
2491##
2492
2493#Method void androidFramework_setDeviceClipRestriction(const SkIRect& rect)
2494
Cary Clarkab2621d2018-01-30 10:08:57 -05002495#In Clip
Cary Clark682c58d2018-05-16 07:07:07 -04002496#Line # exists for use by Android framework ##
Cary Clarkce101242017-09-01 15:51:02 -04002497Sets the maximum clip rectangle, which can be set by clipRect, clipRRect and
Cary Clark8032b982017-07-28 11:04:54 -04002498clipPath and intersect the current clip with the specified rect.
Cary Clarkce101242017-09-01 15:51:02 -04002499The maximum clip affects only future clipping operations; it is not retroactive.
Cary Clark8032b982017-07-28 11:04:54 -04002500The clip restriction is not recorded in pictures.
2501
Herb Derbyefe39bc2018-05-01 17:06:20 -04002502Pass an empty rect to disable maximum clip.
Cary Clarkbad5ad72017-08-03 17:14:08 -04002503
Cary Clark8032b982017-07-28 11:04:54 -04002504#Private
2505This is private API to be used only by Android framework.
2506##
2507
Cary Clarkbad5ad72017-08-03 17:14:08 -04002508#Param rect maximum allowed clip in device coordinates
Cary Clark579985c2017-07-31 11:48:27 -04002509#Param ##
Cary Clark8032b982017-07-28 11:04:54 -04002510
2511##
2512
2513#Method void clipRRect(const SkRRect& rrect, SkClipOp op, bool doAntiAlias)
2514
Cary Clarkab2621d2018-01-30 10:08:57 -05002515#In Clip
2516#Line # combines Clip with Round_Rect ##
Cary Clark8032b982017-07-28 11:04:54 -04002517Replace Clip with the intersection or difference of Clip and rrect,
Cary Clarkffb3d682018-05-17 12:17:28 -04002518with an Aliased or Anti_Aliased clip edge.
Cary Clark8032b982017-07-28 11:04:54 -04002519rrect is transformed by Matrix
2520before it is combined with Clip.
2521
Cary Clarkbad5ad72017-08-03 17:14:08 -04002522#Param rrect Round_Rect to combine with Clip ##
2523#Param op Clip_Op to apply to Clip ##
Cary Clarkffb3d682018-05-17 12:17:28 -04002524#Param doAntiAlias true if Clip is to be Anti_Aliased ##
Cary Clark8032b982017-07-28 11:04:54 -04002525
2526#Example
2527#Height 128
Cary Clarkbad5ad72017-08-03 17:14:08 -04002528void draw(SkCanvas* canvas) {
2529 canvas->clear(SK_ColorWHITE);
2530 SkPaint paint;
2531 paint.setAntiAlias(true);
2532 paint.setColor(0x8055aaff);
2533 SkRRect oval;
2534 oval.setOval({10, 20, 90, 100});
2535 canvas->clipRRect(oval, SkClipOp::kIntersect, true);
2536 canvas->drawCircle(70, 100, 60, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002537}
2538##
2539
Cary Clark2ade9972017-11-02 17:49:34 -04002540#SeeAlso clipRect clipPath clipRegion
Cary Clark8032b982017-07-28 11:04:54 -04002541
2542##
2543
Herb Derbyefe39bc2018-05-01 17:06:20 -04002544#Method void clipRRect(const SkRRect& rrect, SkClipOp op)
Cary Clark8032b982017-07-28 11:04:54 -04002545
Cary Clarkab2621d2018-01-30 10:08:57 -05002546#In Clip
Cary Clark8032b982017-07-28 11:04:54 -04002547Replace Clip with the intersection or difference of Clip and rrect.
Cary Clarkce101242017-09-01 15:51:02 -04002548Resulting Clip is Aliased; pixels are fully contained by the clip.
Cary Clarkbad5ad72017-08-03 17:14:08 -04002549rrect is transformed by Matrix before it is combined with Clip.
Cary Clark8032b982017-07-28 11:04:54 -04002550
Cary Clarkbad5ad72017-08-03 17:14:08 -04002551#Param rrect Round_Rect to combine with Clip ##
2552#Param op Clip_Op to apply to Clip ##
Cary Clark8032b982017-07-28 11:04:54 -04002553
2554#Example
2555#Height 128
Cary Clarkbad5ad72017-08-03 17:14:08 -04002556void draw(SkCanvas* canvas) {
2557 SkPaint paint;
2558 paint.setColor(0x8055aaff);
2559 auto oval = SkRRect::MakeOval({10, 20, 90, 100});
2560 canvas->clipRRect(oval, SkClipOp::kIntersect);
2561 canvas->drawCircle(70, 100, 60, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002562}
2563##
2564
Cary Clark2ade9972017-11-02 17:49:34 -04002565#SeeAlso clipRect clipPath clipRegion
Cary Clark8032b982017-07-28 11:04:54 -04002566
2567##
2568
Herb Derbyefe39bc2018-05-01 17:06:20 -04002569#Method void clipRRect(const SkRRect& rrect, bool doAntiAlias = false)
Cary Clark8032b982017-07-28 11:04:54 -04002570
Cary Clarkab2621d2018-01-30 10:08:57 -05002571#In Clip
Cary Clark8032b982017-07-28 11:04:54 -04002572Replace Clip with the intersection of Clip and rrect,
Cary Clarkffb3d682018-05-17 12:17:28 -04002573with an Aliased or Anti_Aliased clip edge.
Cary Clarkbad5ad72017-08-03 17:14:08 -04002574rrect is transformed by Matrix before it is combined with Clip.
Cary Clark8032b982017-07-28 11:04:54 -04002575
Cary Clarkbad5ad72017-08-03 17:14:08 -04002576#Param rrect Round_Rect to combine with Clip ##
Cary Clarkffb3d682018-05-17 12:17:28 -04002577#Param doAntiAlias true if Clip is to be Anti_Aliased ##
Cary Clark8032b982017-07-28 11:04:54 -04002578
2579#Example
2580#Height 128
Cary Clarkbad5ad72017-08-03 17:14:08 -04002581void draw(SkCanvas* canvas) {
2582 SkPaint paint;
2583 paint.setAntiAlias(true);
2584 auto oval = SkRRect::MakeRectXY({10, 20, 90, 100}, 9, 13);
2585 canvas->clipRRect(oval, true);
2586 canvas->drawCircle(70, 100, 60, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002587}
2588##
2589
Cary Clark2ade9972017-11-02 17:49:34 -04002590#SeeAlso clipRect clipPath clipRegion
Cary Clark8032b982017-07-28 11:04:54 -04002591
2592##
2593
2594#Method void clipPath(const SkPath& path, SkClipOp op, bool doAntiAlias)
2595
Cary Clarkab2621d2018-01-30 10:08:57 -05002596#In Clip
2597#Line # combines Clip with Path ##
Cary Clark8032b982017-07-28 11:04:54 -04002598Replace Clip with the intersection or difference of Clip and path,
Cary Clarkffb3d682018-05-17 12:17:28 -04002599with an Aliased or Anti_Aliased clip edge. Path_Fill_Type determines if path
Cary Clark8032b982017-07-28 11:04:54 -04002600describes the area inside or outside its contours; and if Path_Contour overlaps
2601itself or another Path_Contour, whether the overlaps form part of the area.
Cary Clarkbad5ad72017-08-03 17:14:08 -04002602path is transformed by Matrix before it is combined with Clip.
Cary Clark8032b982017-07-28 11:04:54 -04002603
Cary Clarkbad5ad72017-08-03 17:14:08 -04002604#Param path Path to combine with Clip ##
2605#Param op Clip_Op to apply to Clip ##
Cary Clarkffb3d682018-05-17 12:17:28 -04002606#Param doAntiAlias true if Clip is to be Anti_Aliased ##
Cary Clark8032b982017-07-28 11:04:54 -04002607
2608#Example
2609#Description
2610Top figure uses SkPath::kInverseWinding_FillType and SkClipOp::kDifference;
2611area outside clip is subtracted from circle.
2612
2613Bottom figure uses SkPath::kWinding_FillType and SkClipOp::kIntersect;
2614area inside clip is intersected with circle.
2615##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002616void draw(SkCanvas* canvas) {
2617 SkPaint paint;
2618 paint.setAntiAlias(true);
2619 SkPath path;
2620 path.addRect({20, 30, 100, 110});
2621 path.setFillType(SkPath::kInverseWinding_FillType);
2622 canvas->save();
2623 canvas->clipPath(path, SkClipOp::kDifference, false);
2624 canvas->drawCircle(70, 100, 60, paint);
2625 canvas->restore();
2626 canvas->translate(100, 100);
2627 path.setFillType(SkPath::kWinding_FillType);
2628 canvas->clipPath(path, SkClipOp::kIntersect, false);
2629 canvas->drawCircle(70, 100, 60, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002630}
2631##
2632
Cary Clark2ade9972017-11-02 17:49:34 -04002633#SeeAlso clipRect clipRRect clipRegion
Cary Clark8032b982017-07-28 11:04:54 -04002634
2635##
2636
Herb Derbyefe39bc2018-05-01 17:06:20 -04002637#Method void clipPath(const SkPath& path, SkClipOp op)
Cary Clark8032b982017-07-28 11:04:54 -04002638
Cary Clarkab2621d2018-01-30 10:08:57 -05002639#In Clip
Cary Clark8032b982017-07-28 11:04:54 -04002640Replace Clip with the intersection or difference of Clip and path.
Cary Clarkce101242017-09-01 15:51:02 -04002641Resulting Clip is Aliased; pixels are fully contained by the clip.
Cary Clark8032b982017-07-28 11:04:54 -04002642Path_Fill_Type determines if path
2643describes the area inside or outside its contours; and if Path_Contour overlaps
2644itself or another Path_Contour, whether the overlaps form part of the area.
2645path is transformed by Matrix
2646before it is combined with Clip.
2647
Cary Clarkbad5ad72017-08-03 17:14:08 -04002648#Param path Path to combine with Clip ##
2649#Param op Clip_Op to apply to Clip ##
Cary Clark8032b982017-07-28 11:04:54 -04002650
2651#Example
2652#Description
Cary Clarkbc5697d2017-10-04 14:31:33 -04002653Overlapping Rects form a clip. When clip Path_Fill_Type is set to
Herb Derbyefe39bc2018-05-01 17:06:20 -04002654SkPath::kWinding_FillType, the overlap is included. Set to
Cary Clark8032b982017-07-28 11:04:54 -04002655SkPath::kEvenOdd_FillType, the overlap is excluded and forms a hole.
2656##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002657void draw(SkCanvas* canvas) {
2658 SkPaint paint;
2659 paint.setAntiAlias(true);
2660 SkPath path;
2661 path.addRect({20, 15, 100, 95});
2662 path.addRect({50, 65, 130, 135});
2663 path.setFillType(SkPath::kWinding_FillType);
2664 canvas->save();
2665 canvas->clipPath(path, SkClipOp::kIntersect);
2666 canvas->drawCircle(70, 85, 60, paint);
2667 canvas->restore();
2668 canvas->translate(100, 100);
2669 path.setFillType(SkPath::kEvenOdd_FillType);
2670 canvas->clipPath(path, SkClipOp::kIntersect);
2671 canvas->drawCircle(70, 85, 60, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002672}
2673##
2674
Cary Clark2ade9972017-11-02 17:49:34 -04002675#SeeAlso clipRect clipRRect clipRegion
Cary Clark8032b982017-07-28 11:04:54 -04002676
2677##
2678
Herb Derbyefe39bc2018-05-01 17:06:20 -04002679#Method void clipPath(const SkPath& path, bool doAntiAlias = false)
Cary Clark8032b982017-07-28 11:04:54 -04002680
Cary Clarkab2621d2018-01-30 10:08:57 -05002681#In Clip
Cary Clark8032b982017-07-28 11:04:54 -04002682Replace Clip with the intersection of Clip and path.
Cary Clarkce101242017-09-01 15:51:02 -04002683Resulting Clip is Aliased; pixels are fully contained by the clip.
Cary Clark8032b982017-07-28 11:04:54 -04002684Path_Fill_Type determines if path
2685describes the area inside or outside its contours; and if Path_Contour overlaps
2686itself or another Path_Contour, whether the overlaps form part of the area.
Cary Clarkbad5ad72017-08-03 17:14:08 -04002687path is transformed by Matrix before it is combined with Clip.
Cary Clark8032b982017-07-28 11:04:54 -04002688
Cary Clarkbad5ad72017-08-03 17:14:08 -04002689#Param path Path to combine with Clip ##
Cary Clarkffb3d682018-05-17 12:17:28 -04002690#Param doAntiAlias true if Clip is to be Anti_Aliased ##
Cary Clark8032b982017-07-28 11:04:54 -04002691
2692#Example
2693#Height 212
2694#Description
Herb Derbyefe39bc2018-05-01 17:06:20 -04002695Clip loops over itself covering its center twice. When clip Path_Fill_Type
2696is set to SkPath::kWinding_FillType, the overlap is included. Set to
Cary Clark8032b982017-07-28 11:04:54 -04002697SkPath::kEvenOdd_FillType, the overlap is excluded and forms a hole.
2698##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002699void draw(SkCanvas* canvas) {
2700 SkPaint paint;
2701 paint.setAntiAlias(true);
2702 SkPath path;
2703 SkPoint poly[] = {{20, 20}, { 80, 20}, { 80, 80}, {40, 80},
2704 {40, 40}, {100, 40}, {100, 100}, {20, 100}};
2705 path.addPoly(poly, SK_ARRAY_COUNT(poly), true);
2706 path.setFillType(SkPath::kWinding_FillType);
2707 canvas->save();
2708 canvas->clipPath(path, SkClipOp::kIntersect);
2709 canvas->drawCircle(50, 50, 45, paint);
2710 canvas->restore();
2711 canvas->translate(100, 100);
2712 path.setFillType(SkPath::kEvenOdd_FillType);
2713 canvas->clipPath(path, SkClipOp::kIntersect);
2714 canvas->drawCircle(50, 50, 45, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002715}
2716##
2717
Cary Clark2ade9972017-11-02 17:49:34 -04002718#SeeAlso clipRect clipRRect clipRegion
Cary Clark8032b982017-07-28 11:04:54 -04002719
2720##
2721
2722# ------------------------------------------------------------------------------
2723
Herb Derbyefe39bc2018-05-01 17:06:20 -04002724#Method void setAllowSimplifyClip(bool allow)
Cary Clark8032b982017-07-28 11:04:54 -04002725
Cary Clarkab2621d2018-01-30 10:08:57 -05002726#In Clip
Cary Clark682c58d2018-05-16 07:07:07 -04002727#Experimental testing
Cary Clark8032b982017-07-28 11:04:54 -04002728
Cary Clarkce101242017-09-01 15:51:02 -04002729Set to simplify clip stack using PathOps.
Cary Clark8032b982017-07-28 11:04:54 -04002730
2731##
2732
2733# ------------------------------------------------------------------------------
2734
2735#Method void clipRegion(const SkRegion& deviceRgn, SkClipOp op = SkClipOp::kIntersect)
2736
Cary Clarkab2621d2018-01-30 10:08:57 -05002737#In Clip
2738#Line # combines Clip with Region ##
Cary Clark8032b982017-07-28 11:04:54 -04002739Replace Clip with the intersection or difference of Clip and Region deviceRgn.
Cary Clarkce101242017-09-01 15:51:02 -04002740Resulting Clip is Aliased; pixels are fully contained by the clip.
Cary Clark8032b982017-07-28 11:04:54 -04002741deviceRgn is unaffected by Matrix.
2742
Cary Clarkbad5ad72017-08-03 17:14:08 -04002743#Param deviceRgn Region to combine with Clip ##
2744#Param op Clip_Op to apply to Clip ##
Cary Clark8032b982017-07-28 11:04:54 -04002745
2746#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04002747#Description
Cary Clarkce101242017-09-01 15:51:02 -04002748 region is unaffected by canvas rotation; iRect is affected by canvas rotation.
2749 Both clips are Aliased; this is not noticeable on Region clip because it
Cary Clarkbad5ad72017-08-03 17:14:08 -04002750 aligns to pixel boundaries.
2751##
2752void draw(SkCanvas* canvas) {
2753 SkPaint paint;
2754 paint.setAntiAlias(true);
2755 SkIRect iRect = {30, 40, 120, 130 };
2756 SkRegion region(iRect);
2757 canvas->rotate(10);
2758 canvas->save();
2759 canvas->clipRegion(region, SkClipOp::kIntersect);
2760 canvas->drawCircle(50, 50, 45, paint);
2761 canvas->restore();
2762 canvas->translate(100, 100);
2763 canvas->clipRect(SkRect::Make(iRect), SkClipOp::kIntersect);
2764 canvas->drawCircle(50, 50, 45, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002765}
2766##
2767
Cary Clark2ade9972017-11-02 17:49:34 -04002768#SeeAlso clipRect clipRRect clipPath
Cary Clark8032b982017-07-28 11:04:54 -04002769
2770##
2771
2772#Method bool quickReject(const SkRect& rect) const
2773
Cary Clarkab2621d2018-01-30 10:08:57 -05002774#In Clip
2775#Line # returns if Rect is outside Clip ##
Cary Clark8032b982017-07-28 11:04:54 -04002776Return true if Rect rect, transformed by Matrix, can be quickly determined to be
2777outside of Clip. May return false even though rect is outside of Clip.
2778
2779Use to check if an area to be drawn is clipped out, to skip subsequent draw calls.
2780
Cary Clarkbad5ad72017-08-03 17:14:08 -04002781#Param rect Rect to compare with Clip ##
Cary Clark8032b982017-07-28 11:04:54 -04002782
Cary Clarkbad5ad72017-08-03 17:14:08 -04002783#Return true if rect, transformed by Matrix, does not intersect Clip ##
Cary Clark8032b982017-07-28 11:04:54 -04002784
2785#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04002786void draw(SkCanvas* canvas) {
Herb Derbyefe39bc2018-05-01 17:06:20 -04002787 SkRect testRect = {30, 30, 120, 129 };
2788 SkRect clipRect = {30, 130, 120, 230 };
Cary Clarkbad5ad72017-08-03 17:14:08 -04002789 canvas->save();
2790 canvas->clipRect(clipRect);
2791 SkDebugf("quickReject %s\n", canvas->quickReject(testRect) ? "true" : "false");
2792 canvas->restore();
2793 canvas->rotate(10);
2794 canvas->clipRect(clipRect);
2795 SkDebugf("quickReject %s\n", canvas->quickReject(testRect) ? "true" : "false");
Cary Clark8032b982017-07-28 11:04:54 -04002796}
2797 #StdOut
Cary Clarkbad5ad72017-08-03 17:14:08 -04002798 quickReject true
Cary Clark8032b982017-07-28 11:04:54 -04002799 quickReject false
2800 ##
2801##
2802
Cary Clark2ade9972017-11-02 17:49:34 -04002803#SeeAlso getLocalClipBounds getTotalMatrix SkBitmap::drawsNothing
Cary Clark8032b982017-07-28 11:04:54 -04002804
2805##
2806
2807#Method bool quickReject(const SkPath& path) const
2808
Cary Clarkab2621d2018-01-30 10:08:57 -05002809#In Clip
Cary Clark8032b982017-07-28 11:04:54 -04002810Return true if path, transformed by Matrix, can be quickly determined to be
2811outside of Clip. May return false even though path is outside of Clip.
2812
2813Use to check if an area to be drawn is clipped out, to skip subsequent draw calls.
2814
Cary Clarkbad5ad72017-08-03 17:14:08 -04002815#Param path Path to compare with Clip ##
Cary Clark8032b982017-07-28 11:04:54 -04002816
Cary Clarkbad5ad72017-08-03 17:14:08 -04002817#Return true if path, transformed by Matrix, does not intersect Clip ##
Cary Clark8032b982017-07-28 11:04:54 -04002818
2819#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04002820void draw(SkCanvas* canvas) {
Herb Derbyefe39bc2018-05-01 17:06:20 -04002821 SkPoint testPoints[] = {{30, 30}, {120, 30}, {120, 129} };
2822 SkPoint clipPoints[] = {{30, 130}, {120, 130}, {120, 230} };
Cary Clarkbad5ad72017-08-03 17:14:08 -04002823 SkPath testPath, clipPath;
2824 testPath.addPoly(testPoints, SK_ARRAY_COUNT(testPoints), true);
2825 clipPath.addPoly(clipPoints, SK_ARRAY_COUNT(clipPoints), true);
2826 canvas->save();
2827 canvas->clipPath(clipPath);
2828 SkDebugf("quickReject %s\n", canvas->quickReject(testPath) ? "true" : "false");
2829 canvas->restore();
2830 canvas->rotate(10);
2831 canvas->clipPath(clipPath);
2832 SkDebugf("quickReject %s\n", canvas->quickReject(testPath) ? "true" : "false");
Cary Clark8032b982017-07-28 11:04:54 -04002833 #StdOut
Cary Clarkbad5ad72017-08-03 17:14:08 -04002834 quickReject true
Cary Clark8032b982017-07-28 11:04:54 -04002835 quickReject false
2836 ##
2837}
2838##
2839
Cary Clark2ade9972017-11-02 17:49:34 -04002840#SeeAlso getLocalClipBounds getTotalMatrix SkBitmap::drawsNothing
Cary Clark8032b982017-07-28 11:04:54 -04002841
2842##
2843
Herb Derbyefe39bc2018-05-01 17:06:20 -04002844#Method SkRect getLocalClipBounds() const
Cary Clark8032b982017-07-28 11:04:54 -04002845
Cary Clarkab2621d2018-01-30 10:08:57 -05002846#In Clip
2847#Line # returns Clip bounds in source coordinates ##
Cary Clark8032b982017-07-28 11:04:54 -04002848Return bounds of Clip, transformed by inverse of Matrix. If Clip is empty,
2849return SkRect::MakeEmpty, where all Rect sides equal zero.
2850
2851Rect returned is outset by one to account for partial pixel coverage if Clip
Cary Clarkffb3d682018-05-17 12:17:28 -04002852is Anti_Aliased.
Cary Clark8032b982017-07-28 11:04:54 -04002853
Cary Clarkbad5ad72017-08-03 17:14:08 -04002854#Return bounds of Clip in local coordinates ##
Cary Clark8032b982017-07-28 11:04:54 -04002855
2856#Example
Herb Derbyefe39bc2018-05-01 17:06:20 -04002857 #Description
Cary Clark8032b982017-07-28 11:04:54 -04002858 Initial bounds is device bounds outset by 1 on all sides.
2859 Clipped bounds is clipPath bounds outset by 1 on all sides.
2860 Scaling the canvas by two in x and y scales the local bounds by 1/2 in x and y.
2861 ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002862 SkCanvas local(256, 256);
2863 canvas = &local;
2864 SkRect bounds = canvas->getLocalClipBounds();
2865 SkDebugf("left:%g top:%g right:%g bottom:%g\n",
2866 bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom);
Herb Derbyefe39bc2018-05-01 17:06:20 -04002867 SkPoint clipPoints[] = {{30, 130}, {120, 130}, {120, 230} };
Cary Clarkbad5ad72017-08-03 17:14:08 -04002868 SkPath clipPath;
2869 clipPath.addPoly(clipPoints, SK_ARRAY_COUNT(clipPoints), true);
2870 canvas->clipPath(clipPath);
2871 bounds = canvas->getLocalClipBounds();
2872 SkDebugf("left:%g top:%g right:%g bottom:%g\n",
2873 bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom);
2874 canvas->scale(2, 2);
2875 bounds = canvas->getLocalClipBounds();
2876 SkDebugf("left:%g top:%g right:%g bottom:%g\n",
2877 bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom);
2878 #StdOut
2879 left:-1 top:-1 right:257 bottom:257
2880 left:29 top:129 right:121 bottom:231
2881 left:14.5 top:64.5 right:60.5 bottom:115.5
2882 ##
Cary Clark8032b982017-07-28 11:04:54 -04002883##
2884
2885# local canvas in example works around bug in fiddle ##
Cary Clark4855f782018-02-06 09:41:53 -05002886#Bug 6524
Cary Clark2ade9972017-11-02 17:49:34 -04002887#SeeAlso getDeviceClipBounds getBaseLayerSize quickReject
Cary Clark8032b982017-07-28 11:04:54 -04002888
2889##
2890
Herb Derbyefe39bc2018-05-01 17:06:20 -04002891#Method bool getLocalClipBounds(SkRect* bounds) const
Cary Clark8032b982017-07-28 11:04:54 -04002892
Cary Clarkab2621d2018-01-30 10:08:57 -05002893#In Clip
Cary Clark8032b982017-07-28 11:04:54 -04002894Return bounds of Clip, transformed by inverse of Matrix. If Clip is empty,
2895return false, and set bounds to SkRect::MakeEmpty, where all Rect sides equal zero.
2896
2897bounds is outset by one to account for partial pixel coverage if Clip
Cary Clarkffb3d682018-05-17 12:17:28 -04002898is Anti_Aliased.
Cary Clark8032b982017-07-28 11:04:54 -04002899
Cary Clarkbad5ad72017-08-03 17:14:08 -04002900#Param bounds Rect of Clip in local coordinates ##
Cary Clark8032b982017-07-28 11:04:54 -04002901
Cary Clarkbad5ad72017-08-03 17:14:08 -04002902#Return true if Clip bounds is not empty ##
Cary Clark8032b982017-07-28 11:04:54 -04002903
2904#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04002905 void draw(SkCanvas* canvas) {
2906 SkCanvas local(256, 256);
2907 canvas = &local;
2908 SkRect bounds;
2909 SkDebugf("local bounds empty = %s\n", canvas->getLocalClipBounds(&bounds)
2910 ? "false" : "true");
2911 SkPath path;
2912 canvas->clipPath(path);
2913 SkDebugf("local bounds empty = %s\n", canvas->getLocalClipBounds(&bounds)
2914 ? "false" : "true");
Cary Clark8032b982017-07-28 11:04:54 -04002915 }
2916 #StdOut
Cary Clarkbad5ad72017-08-03 17:14:08 -04002917 local bounds empty = false
Cary Clark8032b982017-07-28 11:04:54 -04002918 local bounds empty = true
2919 ##
2920##
2921
2922# local canvas in example works around bug in fiddle ##
Cary Clark4855f782018-02-06 09:41:53 -05002923#Bug 6524
Cary Clark2ade9972017-11-02 17:49:34 -04002924#SeeAlso getDeviceClipBounds getBaseLayerSize quickReject
Cary Clark8032b982017-07-28 11:04:54 -04002925
2926##
2927
Herb Derbyefe39bc2018-05-01 17:06:20 -04002928#Method SkIRect getDeviceClipBounds() const
Cary Clark8032b982017-07-28 11:04:54 -04002929
Cary Clarkab2621d2018-01-30 10:08:57 -05002930#In Clip
2931#Line # returns IRect bounds of Clip ##
Cary Clark8032b982017-07-28 11:04:54 -04002932Return IRect bounds of Clip, unaffected by Matrix. If Clip is empty,
2933return SkRect::MakeEmpty, where all Rect sides equal zero.
2934
Herb Derbyefe39bc2018-05-01 17:06:20 -04002935Unlike getLocalClipBounds, returned IRect is not outset.
Cary Clark8032b982017-07-28 11:04:54 -04002936
Cary Clarkbad5ad72017-08-03 17:14:08 -04002937#Return bounds of Clip in Device coordinates ##
Cary Clark8032b982017-07-28 11:04:54 -04002938
2939#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04002940void draw(SkCanvas* canvas) {
2941 #Description
Cary Clark8032b982017-07-28 11:04:54 -04002942 Initial bounds is device bounds, not outset.
2943 Clipped bounds is clipPath bounds, not outset.
2944 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 -04002945 ##
2946 SkCanvas device(256, 256);
2947 canvas = &device;
2948 SkIRect bounds = canvas->getDeviceClipBounds();
2949 SkDebugf("left:%d top:%d right:%d bottom:%d\n",
2950 bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom);
Herb Derbyefe39bc2018-05-01 17:06:20 -04002951 SkPoint clipPoints[] = {{30, 130}, {120, 130}, {120, 230} };
Cary Clarkbad5ad72017-08-03 17:14:08 -04002952 SkPath clipPath;
2953 clipPath.addPoly(clipPoints, SK_ARRAY_COUNT(clipPoints), true);
2954 canvas->save();
2955 canvas->clipPath(clipPath);
2956 bounds = canvas->getDeviceClipBounds();
2957 SkDebugf("left:%d top:%d right:%d bottom:%d\n",
2958 bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom);
2959 canvas->restore();
2960 canvas->scale(1.f/2, 1.f/2);
2961 canvas->clipPath(clipPath);
2962 bounds = canvas->getDeviceClipBounds();
2963 SkDebugf("left:%d top:%d right:%d bottom:%d\n",
2964 bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom);
Cary Clark8032b982017-07-28 11:04:54 -04002965 #StdOut
Cary Clarkbad5ad72017-08-03 17:14:08 -04002966 left:0 top:0 right:256 bottom:256
2967 left:30 top:130 right:120 bottom:230
Cary Clark8032b982017-07-28 11:04:54 -04002968 left:15 top:65 right:60 bottom:115
2969 ##
2970}
2971##
2972
2973#ToDo some confusion on why with an identity Matrix local and device are different ##
Cary Clark2ade9972017-11-02 17:49:34 -04002974#SeeAlso getLocalClipBounds getBaseLayerSize quickReject
Cary Clark8032b982017-07-28 11:04:54 -04002975
2976# device canvas in example works around bug in fiddle ##
Cary Clark4855f782018-02-06 09:41:53 -05002977#Bug 6524
Cary Clark8032b982017-07-28 11:04:54 -04002978
2979##
2980
Herb Derbyefe39bc2018-05-01 17:06:20 -04002981#Method bool getDeviceClipBounds(SkIRect* bounds) const
Cary Clark8032b982017-07-28 11:04:54 -04002982
Cary Clarkab2621d2018-01-30 10:08:57 -05002983#In Clip
Cary Clark8032b982017-07-28 11:04:54 -04002984Return IRect bounds of Clip, unaffected by Matrix. If Clip is empty,
2985return false, and set bounds to SkRect::MakeEmpty, where all Rect sides equal zero.
2986
Herb Derbyefe39bc2018-05-01 17:06:20 -04002987Unlike getLocalClipBounds, bounds is not outset.
Cary Clark8032b982017-07-28 11:04:54 -04002988
Cary Clarkbad5ad72017-08-03 17:14:08 -04002989#Param bounds Rect of Clip in device coordinates ##
Cary Clark8032b982017-07-28 11:04:54 -04002990
Cary Clarkbad5ad72017-08-03 17:14:08 -04002991#Return true if Clip bounds is not empty ##
Cary Clark8032b982017-07-28 11:04:54 -04002992
2993#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04002994 void draw(SkCanvas* canvas) {
2995 SkIRect bounds;
2996 SkDebugf("device bounds empty = %s\n", canvas->getDeviceClipBounds(&bounds)
2997 ? "false" : "true");
2998 SkPath path;
2999 canvas->clipPath(path);
3000 SkDebugf("device bounds empty = %s\n", canvas->getDeviceClipBounds(&bounds)
3001 ? "false" : "true");
Cary Clark8032b982017-07-28 11:04:54 -04003002 }
3003 #StdOut
Cary Clarkbad5ad72017-08-03 17:14:08 -04003004 device bounds empty = false
Cary Clark8032b982017-07-28 11:04:54 -04003005 device bounds empty = true
3006 ##
3007##
3008
Cary Clark2ade9972017-11-02 17:49:34 -04003009#SeeAlso getLocalClipBounds getBaseLayerSize quickReject
Cary Clark8032b982017-07-28 11:04:54 -04003010
3011##
3012
Cary Clark08895c42018-02-01 09:37:32 -05003013#Subtopic Clip ##
Cary Clark8032b982017-07-28 11:04:54 -04003014
3015# ------------------------------------------------------------------------------
Cary Clark78de7512018-02-07 07:27:09 -05003016#Subtopic Draw
3017#Populate
3018#Line # draws into Canvas ##
3019##
Cary Clark8032b982017-07-28 11:04:54 -04003020
3021#Method void drawColor(SkColor color, SkBlendMode mode = SkBlendMode::kSrcOver)
Cary Clark78de7512018-02-07 07:27:09 -05003022#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05003023#Line # fills Clip with Color and Blend_Mode ##
Cary Clark8032b982017-07-28 11:04:54 -04003024Fill Clip with Color color.
Cary Clarkffb3d682018-05-17 12:17:28 -04003025mode determines how ARGB is combined with destination.
Cary Clark8032b982017-07-28 11:04:54 -04003026
Cary Clarkffb3d682018-05-17 12:17:28 -04003027#Param color Unpremultiplied ARGB ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003028#Param mode SkBlendMode used to combine source color and destination ##
Cary Clark8032b982017-07-28 11:04:54 -04003029
3030#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003031 canvas->drawColor(SK_ColorRED);
3032 canvas->clipRect(SkRect::MakeWH(150, 150));
3033 canvas->drawColor(SkColorSetARGB(0x80, 0x00, 0xFF, 0x00), SkBlendMode::kPlus);
3034 canvas->clipRect(SkRect::MakeWH(75, 75));
3035 canvas->drawColor(SkColorSetARGB(0x80, 0x00, 0x00, 0xFF), SkBlendMode::kPlus);
Cary Clark8032b982017-07-28 11:04:54 -04003036##
3037
Cary Clark2ade9972017-11-02 17:49:34 -04003038#SeeAlso clear SkBitmap::erase drawPaint
Cary Clark8032b982017-07-28 11:04:54 -04003039
3040##
3041
3042# ------------------------------------------------------------------------------
3043
Herb Derbyefe39bc2018-05-01 17:06:20 -04003044#Method void clear(SkColor color)
Cary Clark78de7512018-02-07 07:27:09 -05003045#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05003046#Line # fills Clip with Color ##
Herb Derbyefe39bc2018-05-01 17:06:20 -04003047Fill Clip with Color color using SkBlendMode::kSrc.
Cary Clark8032b982017-07-28 11:04:54 -04003048This has the effect of replacing all pixels contained by Clip with color.
3049
Cary Clarkffb3d682018-05-17 12:17:28 -04003050#Param color Unpremultiplied ARGB ##
Cary Clark8032b982017-07-28 11:04:54 -04003051
3052#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003053void draw(SkCanvas* canvas) {
3054 canvas->save();
3055 canvas->clipRect(SkRect::MakeWH(256, 128));
Herb Derbyefe39bc2018-05-01 17:06:20 -04003056 canvas->clear(SkColorSetARGB(0x80, 0xFF, 0x00, 0x00));
Cary Clarkbad5ad72017-08-03 17:14:08 -04003057 canvas->restore();
3058 canvas->save();
3059 canvas->clipRect(SkRect::MakeWH(150, 192));
3060 canvas->clear(SkColorSetARGB(0x80, 0x00, 0xFF, 0x00));
3061 canvas->restore();
3062 canvas->clipRect(SkRect::MakeWH(75, 256));
3063 canvas->clear(SkColorSetARGB(0x80, 0x00, 0x00, 0xFF));
Cary Clark8032b982017-07-28 11:04:54 -04003064}
3065##
3066
Cary Clark2ade9972017-11-02 17:49:34 -04003067#SeeAlso drawColor SkBitmap::erase drawPaint
Cary Clark8032b982017-07-28 11:04:54 -04003068
3069##
3070
3071# ------------------------------------------------------------------------------
3072
Herb Derbyefe39bc2018-05-01 17:06:20 -04003073#Method void discard()
Cary Clark78de7512018-02-07 07:27:09 -05003074#In Utility
Cary Clarkab2621d2018-01-30 10:08:57 -05003075#Line # makes Canvas contents undefined ##
Cary Clark8032b982017-07-28 11:04:54 -04003076Make Canvas contents undefined. Subsequent calls that read Canvas pixels,
3077such as drawing with SkBlendMode, return undefined results. discard() does
3078not change Clip or Matrix.
3079
3080discard() may do nothing, depending on the implementation of Surface or Device
3081that created Canvas.
3082
3083discard() allows optimized performance on subsequent draws by removing
3084cached data associated with Surface or Device.
3085It is not necessary to call discard() once done with Canvas;
3086any cached data is deleted when owning Surface or Device is deleted.
3087
3088#ToDo example? not sure how to make this meaningful w/o more implementation detail ##
Cary Clark2ade9972017-11-02 17:49:34 -04003089#SeeAlso flush() SkSurface::prepareForExternalIO GrContext::abandonContext
Cary Clark8032b982017-07-28 11:04:54 -04003090
Herb Derbyefe39bc2018-05-01 17:06:20 -04003091#NoExample
Cary Clark8032b982017-07-28 11:04:54 -04003092##
3093
3094##
3095
3096# ------------------------------------------------------------------------------
3097
3098#Method void drawPaint(const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05003099#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05003100#Line # fills Clip with Paint ##
Mike Reed8ad91a92018-01-19 19:09:32 -05003101Fill Clip with Paint paint. Paint components Mask_Filter, Shader,
Cary Clarkbad5ad72017-08-03 17:14:08 -04003102Color_Filter, Image_Filter, and Blend_Mode affect drawing;
3103Path_Effect in paint is ignored.
Cary Clark8032b982017-07-28 11:04:54 -04003104
3105# can Path_Effect in paint ever alter drawPaint?
3106
Cary Clarkbad5ad72017-08-03 17:14:08 -04003107#Param paint graphics state used to fill Canvas ##
Cary Clark8032b982017-07-28 11:04:54 -04003108
3109#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003110void draw(SkCanvas* canvas) {
3111 SkColor colors[] = { SK_ColorRED, SK_ColorGREEN, SK_ColorBLUE };
3112 SkScalar pos[] = { 0, SK_Scalar1/2, SK_Scalar1 };
3113 SkPaint paint;
3114 paint.setShader(SkGradientShader::MakeSweep(256, 256, colors, pos, SK_ARRAY_COUNT(colors)));
3115 canvas->drawPaint(paint);
Cary Clark8032b982017-07-28 11:04:54 -04003116}
3117##
3118
Cary Clark2ade9972017-11-02 17:49:34 -04003119#SeeAlso clear drawColor SkBitmap::erase
Cary Clark8032b982017-07-28 11:04:54 -04003120
3121##
3122
3123# ------------------------------------------------------------------------------
3124
3125#Enum PointMode
Cary Clark08895c42018-02-01 09:37:32 -05003126#Line # sets drawPoints options ##
Cary Clark8032b982017-07-28 11:04:54 -04003127
3128#Code
3129 enum PointMode {
3130 kPoints_PointMode,
3131 kLines_PointMode,
Cary Clarkd0530ba2017-09-14 11:25:39 -04003132 kPolygon_PointMode,
Cary Clark8032b982017-07-28 11:04:54 -04003133 };
3134##
3135
3136Selects if an array of points are drawn as discrete points, as lines, or as
3137an open polygon.
3138
3139#Const kPoints_PointMode 0
Cary Clark682c58d2018-05-16 07:07:07 -04003140#Line # draw each point separately ##
Cary Clark8032b982017-07-28 11:04:54 -04003141##
3142
3143#Const kLines_PointMode 1
Cary Clark682c58d2018-05-16 07:07:07 -04003144#Line # draw each pair of points as a line segment ##
Cary Clark8032b982017-07-28 11:04:54 -04003145##
3146
3147#Const kPolygon_PointMode 2
Cary Clark682c58d2018-05-16 07:07:07 -04003148#Line # draw the array of points as a open polygon ##
Cary Clark8032b982017-07-28 11:04:54 -04003149##
3150
3151#Example
Herb Derbyefe39bc2018-05-01 17:06:20 -04003152 #Description
Cary Clark8032b982017-07-28 11:04:54 -04003153 The upper left corner shows three squares when drawn as points.
3154 The upper right corner shows one line; when drawn as lines, two points are required per line.
3155 The lower right corner shows two lines; when draw as polygon, no miter is drawn at the corner.
3156 The lower left corner shows two lines with a miter when path contains polygon.
3157 ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003158void draw(SkCanvas* canvas) {
3159 SkPaint paint;
3160 paint.setStyle(SkPaint::kStroke_Style);
3161 paint.setStrokeWidth(10);
3162 SkPoint points[] = {{64, 32}, {96, 96}, {32, 96}};
3163 canvas->drawPoints(SkCanvas::kPoints_PointMode, 3, points, paint);
3164 canvas->translate(128, 0);
3165 canvas->drawPoints(SkCanvas::kLines_PointMode, 3, points, paint);
3166 canvas->translate(0, 128);
3167 canvas->drawPoints(SkCanvas::kPolygon_PointMode, 3, points, paint);
3168 SkPath path;
3169 path.addPoly(points, 3, false);
3170 canvas->translate(-128, 0);
3171 canvas->drawPath(path, paint);
Cary Clark8032b982017-07-28 11:04:54 -04003172}
3173##
3174
Cary Clark2ade9972017-11-02 17:49:34 -04003175#SeeAlso drawLine drawPoint drawPath
Cary Clark8032b982017-07-28 11:04:54 -04003176
3177##
3178
3179# ------------------------------------------------------------------------------
3180
3181#Method void drawPoints(PointMode mode, size_t count, const SkPoint pts[], const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05003182#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05003183#Line # draws array as points, lines, polygon ##
Cary Clark8032b982017-07-28 11:04:54 -04003184Draw pts using Clip, Matrix and Paint paint.
Cary Clarkbad5ad72017-08-03 17:14:08 -04003185count is the number of points; if count is less than one, has no effect.
Cary Clark8032b982017-07-28 11:04:54 -04003186mode may be one of: kPoints_PointMode, kLines_PointMode, or kPolygon_PointMode.
3187
Cary Clarkbad5ad72017-08-03 17:14:08 -04003188If mode is kPoints_PointMode, the shape of point drawn depends on paint
3189Paint_Stroke_Cap. If paint is set to SkPaint::kRound_Cap, each point draws a
3190circle of diameter Paint_Stroke_Width. If paint is set to SkPaint::kSquare_Cap
3191or SkPaint::kButt_Cap, each point draws a square of width and height
3192Paint_Stroke_Width.
Cary Clark8032b982017-07-28 11:04:54 -04003193
3194If mode is kLines_PointMode, each pair of points draws a line segment.
3195One line is drawn for every two points; each point is used once. If count is odd,
Herb Derbyefe39bc2018-05-01 17:06:20 -04003196the final point is ignored.
Cary Clark8032b982017-07-28 11:04:54 -04003197
3198If mode is kPolygon_PointMode, each adjacent pair of points draws a line segment.
3199count minus one lines are drawn; the first and last point are used once.
3200
3201Each line segment respects paint Paint_Stroke_Cap and Paint_Stroke_Width.
3202Paint_Style is ignored, as if were set to SkPaint::kStroke_Style.
3203
Cary Clarkbad5ad72017-08-03 17:14:08 -04003204Always draws each element one at a time; is not affected by
3205Paint_Stroke_Join, and unlike drawPath, does not create a mask from all points
Herb Derbyefe39bc2018-05-01 17:06:20 -04003206and lines before drawing.
Cary Clark8032b982017-07-28 11:04:54 -04003207
Cary Clarka523d2d2017-08-30 08:58:10 -04003208#Param mode whether pts draws points or lines ##
3209#Param count number of points in the array ##
3210#Param pts array of points to draw ##
3211#Param paint stroke, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003212
3213#Example
3214#Height 200
Herb Derbyefe39bc2018-05-01 17:06:20 -04003215 #Description
Cary Clark8032b982017-07-28 11:04:54 -04003216 #List
3217 # The first column draws points. ##
3218 # The second column draws points as lines. ##
3219 # The third column draws points as a polygon. ##
3220 # The fourth column draws points as a polygonal path. ##
3221 # The first row uses a round cap and round join. ##
3222 # The second row uses a square cap and a miter join. ##
3223 # The third row uses a butt cap and a bevel join. ##
3224 ##
3225 The transparent color makes multiple line draws visible;
3226 the path is drawn all at once.
3227 ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003228void draw(SkCanvas* canvas) {
3229 SkPaint paint;
3230 paint.setAntiAlias(true);
3231 paint.setStyle(SkPaint::kStroke_Style);
3232 paint.setStrokeWidth(10);
3233 paint.setColor(0x80349a45);
3234 const SkPoint points[] = {{32, 16}, {48, 48}, {16, 32}};
Herb Derbyefe39bc2018-05-01 17:06:20 -04003235 const SkPaint::Join join[] = { SkPaint::kRound_Join,
Cary Clarkbad5ad72017-08-03 17:14:08 -04003236 SkPaint::kMiter_Join,
3237 SkPaint::kBevel_Join };
3238 int joinIndex = 0;
3239 SkPath path;
3240 path.addPoly(points, 3, false);
3241 for (const auto cap : { SkPaint::kRound_Cap, SkPaint::kSquare_Cap, SkPaint::kButt_Cap } ) {
3242 paint.setStrokeCap(cap);
3243 paint.setStrokeJoin(join[joinIndex++]);
3244 for (const auto mode : { SkCanvas::kPoints_PointMode,
3245 SkCanvas::kLines_PointMode,
3246 SkCanvas::kPolygon_PointMode } ) {
3247 canvas->drawPoints(mode, 3, points, paint);
3248 canvas->translate(64, 0);
3249 }
3250 canvas->drawPath(path, paint);
3251 canvas->translate(-192, 64);
3252 }
Cary Clark8032b982017-07-28 11:04:54 -04003253}
3254##
3255
Cary Clark2ade9972017-11-02 17:49:34 -04003256#SeeAlso drawLine drawPoint drawPath
Cary Clark8032b982017-07-28 11:04:54 -04003257
3258##
3259
3260# ------------------------------------------------------------------------------
3261
3262#Method void drawPoint(SkScalar x, SkScalar y, const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05003263#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05003264#Line # draws point at (x, y) position ##
Cary Clark8032b982017-07-28 11:04:54 -04003265Draw point at (x, y) using Clip, Matrix and Paint paint.
3266
3267The shape of point drawn depends on paint Paint_Stroke_Cap.
Cary Clarkbad5ad72017-08-03 17:14:08 -04003268If paint is set to SkPaint::kRound_Cap, draw a circle of diameter
Herb Derbyefe39bc2018-05-01 17:06:20 -04003269Paint_Stroke_Width. If paint is set to SkPaint::kSquare_Cap or SkPaint::kButt_Cap,
Cary Clark8032b982017-07-28 11:04:54 -04003270draw a square of width and height Paint_Stroke_Width.
3271Paint_Style is ignored, as if were set to SkPaint::kStroke_Style.
3272
Cary Clarkbad5ad72017-08-03 17:14:08 -04003273#Param x left edge of circle or square ##
3274#Param y top edge of circle or square ##
3275#Param paint stroke, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003276
3277#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003278void draw(SkCanvas* canvas) {
3279 SkPaint paint;
3280 paint.setAntiAlias(true);
3281 paint.setColor(0x80349a45);
3282 paint.setStyle(SkPaint::kStroke_Style);
3283 paint.setStrokeWidth(100);
3284 paint.setStrokeCap(SkPaint::kRound_Cap);
3285 canvas->scale(1, 1.2f);
3286 canvas->drawPoint(64, 96, paint);
3287 canvas->scale(.6f, .8f);
3288 paint.setColor(SK_ColorWHITE);
3289 canvas->drawPoint(106, 120, paint);
Cary Clark8032b982017-07-28 11:04:54 -04003290}
3291##
3292
Cary Clark2ade9972017-11-02 17:49:34 -04003293#SeeAlso drawPoints drawCircle drawRect drawLine drawPath
Cary Clark8032b982017-07-28 11:04:54 -04003294
3295##
3296
Cary Clarkbad5ad72017-08-03 17:14:08 -04003297#Method void drawPoint(SkPoint p, const SkPaint& paint)
3298
3299Draw point p using Clip, Matrix and Paint paint.
3300
3301The shape of point drawn depends on paint Paint_Stroke_Cap.
3302If paint is set to SkPaint::kRound_Cap, draw a circle of diameter
Herb Derbyefe39bc2018-05-01 17:06:20 -04003303Paint_Stroke_Width. If paint is set to SkPaint::kSquare_Cap or SkPaint::kButt_Cap,
Cary Clarkbad5ad72017-08-03 17:14:08 -04003304draw a square of width and height Paint_Stroke_Width.
3305Paint_Style is ignored, as if were set to SkPaint::kStroke_Style.
3306
3307#Param p top-left edge of circle or square ##
3308#Param paint stroke, blend, color, and so on, used to draw ##
3309
3310#Example
3311void draw(SkCanvas* canvas) {
3312 SkPaint paint;
3313 paint.setAntiAlias(true);
3314 paint.setColor(0x80349a45);
3315 paint.setStyle(SkPaint::kStroke_Style);
3316 paint.setStrokeWidth(100);
3317 paint.setStrokeCap(SkPaint::kSquare_Cap);
3318 canvas->scale(1, 1.2f);
3319 canvas->drawPoint({64, 96}, paint);
3320 canvas->scale(.6f, .8f);
3321 paint.setColor(SK_ColorWHITE);
3322 canvas->drawPoint(106, 120, paint);
3323}
3324##
3325
Cary Clark2ade9972017-11-02 17:49:34 -04003326#SeeAlso drawPoints drawCircle drawRect drawLine drawPath
Cary Clarkbad5ad72017-08-03 17:14:08 -04003327
3328##
3329
Cary Clark8032b982017-07-28 11:04:54 -04003330# ------------------------------------------------------------------------------
3331
3332#Method void drawLine(SkScalar x0, SkScalar y0, SkScalar x1, SkScalar y1, const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05003333#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05003334#Line # draws line segment between two points ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003335Draws line segment from (x0, y0) to (x1, y1) using Clip, Matrix, and Paint paint.
3336In paint: Paint_Stroke_Width describes the line thickness;
3337Paint_Stroke_Cap draws the end rounded or square;
Cary Clark8032b982017-07-28 11:04:54 -04003338Paint_Style is ignored, as if were set to SkPaint::kStroke_Style.
3339
Cary Clarkbad5ad72017-08-03 17:14:08 -04003340#Param x0 start of line segment on x-axis ##
3341#Param y0 start of line segment on y-axis ##
3342#Param x1 end of line segment on x-axis ##
3343#Param y1 end of line segment on y-axis ##
3344#Param paint stroke, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003345
3346#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003347 SkPaint paint;
3348 paint.setAntiAlias(true);
3349 paint.setColor(0xFF9a67be);
3350 paint.setStrokeWidth(20);
3351 canvas->skew(1, 0);
3352 canvas->drawLine(32, 96, 32, 160, paint);
3353 canvas->skew(-2, 0);
3354 canvas->drawLine(288, 96, 288, 160, paint);
3355##
3356
Cary Clark2ade9972017-11-02 17:49:34 -04003357#SeeAlso drawPoint drawCircle drawRect drawPath
Cary Clarkbad5ad72017-08-03 17:14:08 -04003358
3359##
3360
3361#Method void drawLine(SkPoint p0, SkPoint p1, const SkPaint& paint)
3362
3363Draws line segment from p0 to p1 using Clip, Matrix, and Paint paint.
3364In paint: Paint_Stroke_Width describes the line thickness;
3365Paint_Stroke_Cap draws the end rounded or square;
3366Paint_Style is ignored, as if were set to SkPaint::kStroke_Style.
3367
3368#Param p0 start of line segment ##
3369#Param p1 end of line segment ##
3370#Param paint stroke, blend, color, and so on, used to draw ##
3371
3372#Example
3373 SkPaint paint;
3374 paint.setAntiAlias(true);
3375 paint.setColor(0xFF9a67be);
3376 paint.setStrokeWidth(20);
3377 canvas->skew(1, 0);
3378 canvas->drawLine({32, 96}, {32, 160}, paint);
3379 canvas->skew(-2, 0);
3380 canvas->drawLine({288, 96}, {288, 160}, paint);
Cary Clark8032b982017-07-28 11:04:54 -04003381##
3382
Cary Clark2ade9972017-11-02 17:49:34 -04003383#SeeAlso drawPoint drawCircle drawRect drawPath
Cary Clark8032b982017-07-28 11:04:54 -04003384
3385##
3386
3387# ------------------------------------------------------------------------------
3388
3389#Method void drawRect(const SkRect& rect, const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05003390#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05003391#Line # draws Rect using Clip, Matrix, and Paint ##
Cary Clark8032b982017-07-28 11:04:54 -04003392Draw Rect rect using Clip, Matrix, and Paint paint.
Herb Derbyefe39bc2018-05-01 17:06:20 -04003393In paint: Paint_Style determines if rectangle is stroked or filled;
Cary Clark8032b982017-07-28 11:04:54 -04003394if stroked, Paint_Stroke_Width describes the line thickness, and
3395Paint_Stroke_Join draws the corners rounded or square.
3396
Cary Clarkbc5697d2017-10-04 14:31:33 -04003397#Param rect rectangle to draw ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003398#Param paint stroke or fill, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003399
3400#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003401void draw(SkCanvas* canvas) {
3402 SkPoint rectPts[] = { {64, 48}, {192, 160} };
3403 SkPaint paint;
3404 paint.setAntiAlias(true);
3405 paint.setStyle(SkPaint::kStroke_Style);
3406 paint.setStrokeWidth(20);
3407 paint.setStrokeJoin(SkPaint::kRound_Join);
3408 SkMatrix rotator;
3409 rotator.setRotate(30, 128, 128);
3410 for (auto color : { SK_ColorRED, SK_ColorBLUE, SK_ColorYELLOW, SK_ColorMAGENTA } ) {
3411 paint.setColor(color);
3412 SkRect rect;
3413 rect.set(rectPts[0], rectPts[1]);
3414 canvas->drawRect(rect, paint);
3415 rotator.mapPoints(rectPts, 2);
3416 }
Cary Clark8032b982017-07-28 11:04:54 -04003417}
3418##
3419
Herb Derbyefe39bc2018-05-01 17:06:20 -04003420#SeeAlso drawIRect drawRRect drawRoundRect drawRegion drawPath drawLine
Cary Clark8032b982017-07-28 11:04:54 -04003421
3422##
3423
3424# ------------------------------------------------------------------------------
3425
Herb Derbyefe39bc2018-05-01 17:06:20 -04003426#Method void drawIRect(const SkIRect& rect, const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05003427#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05003428#Line # draws IRect using Clip, Matrix, and Paint ##
Cary Clark8032b982017-07-28 11:04:54 -04003429Draw IRect rect using Clip, Matrix, and Paint paint.
Herb Derbyefe39bc2018-05-01 17:06:20 -04003430In paint: Paint_Style determines if rectangle is stroked or filled;
Cary Clark8032b982017-07-28 11:04:54 -04003431if stroked, Paint_Stroke_Width describes the line thickness, and
3432Paint_Stroke_Join draws the corners rounded or square.
3433
Cary Clarkbc5697d2017-10-04 14:31:33 -04003434#Param rect rectangle to draw ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003435#Param paint stroke or fill, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003436
3437#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003438 SkIRect rect = { 64, 48, 192, 160 };
3439 SkPaint paint;
3440 paint.setAntiAlias(true);
3441 paint.setStyle(SkPaint::kStroke_Style);
3442 paint.setStrokeWidth(20);
3443 paint.setStrokeJoin(SkPaint::kRound_Join);
3444 for (auto color : { SK_ColorRED, SK_ColorBLUE, SK_ColorYELLOW, SK_ColorMAGENTA } ) {
3445 paint.setColor(color);
3446 canvas->drawIRect(rect, paint);
3447 canvas->rotate(30, 128, 128);
3448 }
Cary Clark8032b982017-07-28 11:04:54 -04003449##
3450
Cary Clark2ade9972017-11-02 17:49:34 -04003451#SeeAlso drawRect drawRRect drawRoundRect drawRegion drawPath drawLine
Cary Clark8032b982017-07-28 11:04:54 -04003452
3453##
3454
3455# ------------------------------------------------------------------------------
3456
3457#Method void drawRegion(const SkRegion& region, const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05003458#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05003459#Line # draws Region using Clip, Matrix, and Paint ##
Cary Clark8032b982017-07-28 11:04:54 -04003460Draw Region region using Clip, Matrix, and Paint paint.
Herb Derbyefe39bc2018-05-01 17:06:20 -04003461In paint: Paint_Style determines if rectangle is stroked or filled;
Cary Clark8032b982017-07-28 11:04:54 -04003462if stroked, Paint_Stroke_Width describes the line thickness, and
3463Paint_Stroke_Join draws the corners rounded or square.
3464
Cary Clarkbc5697d2017-10-04 14:31:33 -04003465#Param region region to draw ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003466#Param paint Paint stroke or fill, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003467
3468#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003469void draw(SkCanvas* canvas) {
3470 SkRegion region;
3471 region.op( 10, 10, 50, 50, SkRegion::kUnion_Op);
3472 region.op( 10, 50, 90, 90, SkRegion::kUnion_Op);
3473 SkPaint paint;
3474 paint.setAntiAlias(true);
3475 paint.setStyle(SkPaint::kStroke_Style);
3476 paint.setStrokeWidth(20);
3477 paint.setStrokeJoin(SkPaint::kRound_Join);
3478 canvas->drawRegion(region, paint);
Cary Clark8032b982017-07-28 11:04:54 -04003479}
3480##
3481
Cary Clark2ade9972017-11-02 17:49:34 -04003482#SeeAlso drawRect drawIRect drawPath
Cary Clark8032b982017-07-28 11:04:54 -04003483
3484##
3485
3486# ------------------------------------------------------------------------------
3487
3488#Method void drawOval(const SkRect& oval, const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05003489#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05003490#Line # draws Oval using Clip, Matrix, and Paint ##
Cary Clark8032b982017-07-28 11:04:54 -04003491Draw Oval oval using Clip, Matrix, and Paint.
Herb Derbyefe39bc2018-05-01 17:06:20 -04003492In paint: Paint_Style determines if Oval is stroked or filled;
Cary Clark8032b982017-07-28 11:04:54 -04003493if stroked, Paint_Stroke_Width describes the line thickness.
3494
Cary Clarkbad5ad72017-08-03 17:14:08 -04003495#Param oval Rect bounds of Oval ##
3496#Param paint Paint stroke or fill, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003497
3498#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003499void draw(SkCanvas* canvas) {
3500 canvas->clear(0xFF3f5f9f);
3501 SkColor kColor1 = SkColorSetARGB(0xff, 0xff, 0x7f, 0);
3502 SkColor g1Colors[] = { kColor1, SkColorSetA(kColor1, 0x20) };
3503 SkPoint g1Points[] = { { 0, 0 }, { 0, 100 } };
3504 SkScalar pos[] = { 0.2f, 1.0f };
3505 SkRect bounds = SkRect::MakeWH(80, 70);
3506 SkPaint paint;
3507 paint.setAntiAlias(true);
3508 paint.setShader(SkGradientShader::MakeLinear(g1Points, g1Colors, pos, SK_ARRAY_COUNT(g1Colors),
3509 SkShader::kClamp_TileMode));
3510 canvas->drawOval(bounds , paint);
Cary Clark8032b982017-07-28 11:04:54 -04003511}
3512##
3513
Cary Clark2ade9972017-11-02 17:49:34 -04003514#SeeAlso drawCircle drawPoint drawPath drawRRect drawRoundRect
Cary Clark8032b982017-07-28 11:04:54 -04003515
3516##
3517
3518# ------------------------------------------------------------------------------
3519
3520#Method void drawRRect(const SkRRect& rrect, const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05003521#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05003522#Line # draws Round_Rect using Clip, Matrix, and Paint ##
Cary Clark8032b982017-07-28 11:04:54 -04003523Draw Round_Rect rrect using Clip, Matrix, and Paint paint.
Herb Derbyefe39bc2018-05-01 17:06:20 -04003524In paint: Paint_Style determines if rrect is stroked or filled;
Cary Clark8032b982017-07-28 11:04:54 -04003525if stroked, Paint_Stroke_Width describes the line thickness.
3526
Cary Clarkbad5ad72017-08-03 17:14:08 -04003527rrect may represent a rectangle, circle, oval, uniformly rounded rectangle, or
3528may have any combination of positive non-square radii for the four corners.
Cary Clark8032b982017-07-28 11:04:54 -04003529
Cary Clarkbad5ad72017-08-03 17:14:08 -04003530#Param rrect Round_Rect with up to eight corner radii to draw ##
3531#Param paint Paint stroke or fill, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003532
3533#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003534void draw(SkCanvas* canvas) {
3535 SkPaint paint;
3536 paint.setAntiAlias(true);
3537 SkRect outer = {30, 40, 210, 220};
3538 SkRect radii = {30, 50, 70, 90 };
3539 SkRRect rRect;
3540 rRect.setNinePatch(outer, radii.fLeft, radii.fTop, radii.fRight, radii.fBottom);
3541 canvas->drawRRect(rRect, paint);
3542 paint.setColor(SK_ColorWHITE);
3543 canvas->drawLine(outer.fLeft + radii.fLeft, outer.fTop,
3544 outer.fLeft + radii.fLeft, outer.fBottom, paint);
Herb Derbyefe39bc2018-05-01 17:06:20 -04003545 canvas->drawLine(outer.fRight - radii.fRight, outer.fTop,
Cary Clarkbad5ad72017-08-03 17:14:08 -04003546 outer.fRight - radii.fRight, outer.fBottom, paint);
Herb Derbyefe39bc2018-05-01 17:06:20 -04003547 canvas->drawLine(outer.fLeft, outer.fTop + radii.fTop,
Cary Clarkbad5ad72017-08-03 17:14:08 -04003548 outer.fRight, outer.fTop + radii.fTop, paint);
Herb Derbyefe39bc2018-05-01 17:06:20 -04003549 canvas->drawLine(outer.fLeft, outer.fBottom - radii.fBottom,
Cary Clarkbad5ad72017-08-03 17:14:08 -04003550 outer.fRight, outer.fBottom - radii.fBottom, paint);
3551}
Cary Clark8032b982017-07-28 11:04:54 -04003552##
3553
Cary Clark2ade9972017-11-02 17:49:34 -04003554#SeeAlso drawRect drawRoundRect drawDRRect drawCircle drawOval drawPath
Cary Clark8032b982017-07-28 11:04:54 -04003555
3556##
3557
3558# ------------------------------------------------------------------------------
3559
3560#Method void drawDRRect(const SkRRect& outer, const SkRRect& inner, const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05003561#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05003562#Line # draws double Round_Rect stroked or filled ##
Cary Clark8032b982017-07-28 11:04:54 -04003563Draw Round_Rect outer and inner
Herb Derbyefe39bc2018-05-01 17:06:20 -04003564using Clip, Matrix, and Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04003565outer must contain inner or the drawing is undefined.
Herb Derbyefe39bc2018-05-01 17:06:20 -04003566In paint: Paint_Style determines if Round_Rect is stroked or filled;
Cary Clark8032b982017-07-28 11:04:54 -04003567if stroked, Paint_Stroke_Width describes the line thickness.
Cary Clarkbad5ad72017-08-03 17:14:08 -04003568If stroked and Round_Rect corner has zero length radii, Paint_Stroke_Join can
Herb Derbyefe39bc2018-05-01 17:06:20 -04003569draw corners rounded or square.
Cary Clark8032b982017-07-28 11:04:54 -04003570
Cary Clarkbad5ad72017-08-03 17:14:08 -04003571GPU-backed platforms optimize drawing when both outer and inner are
Cary Clark8032b982017-07-28 11:04:54 -04003572concave and outer contains inner. These platforms may not be able to draw
Herb Derbyefe39bc2018-05-01 17:06:20 -04003573Path built with identical data as fast.
Cary Clark8032b982017-07-28 11:04:54 -04003574
Cary Clarkbad5ad72017-08-03 17:14:08 -04003575#Param outer Round_Rect outer bounds to draw ##
3576#Param inner Round_Rect inner bounds to draw ##
3577#Param paint Paint stroke or fill, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003578
3579#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003580void draw(SkCanvas* canvas) {
3581 SkRRect outer = SkRRect::MakeRect({20, 40, 210, 200});
3582 SkRRect inner = SkRRect::MakeOval({60, 70, 170, 160});
3583 SkPaint paint;
3584 canvas->drawDRRect(outer, inner, paint);
Cary Clark8032b982017-07-28 11:04:54 -04003585}
3586##
3587
3588#Example
3589#Description
3590 Outer Rect has no corner radii, but stroke join is rounded.
3591 Inner Round_Rect has corner radii; outset stroke increases radii of corners.
3592 Stroke join does not affect inner Round_Rect since it has no sharp corners.
3593##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003594void draw(SkCanvas* canvas) {
3595 SkRRect outer = SkRRect::MakeRect({20, 40, 210, 200});
3596 SkRRect inner = SkRRect::MakeRectXY({60, 70, 170, 160}, 10, 10);
3597 SkPaint paint;
3598 paint.setAntiAlias(true);
3599 paint.setStyle(SkPaint::kStroke_Style);
3600 paint.setStrokeWidth(20);
3601 paint.setStrokeJoin(SkPaint::kRound_Join);
3602 canvas->drawDRRect(outer, inner, paint);
3603 paint.setStrokeWidth(1);
3604 paint.setColor(SK_ColorWHITE);
3605 canvas->drawDRRect(outer, inner, paint);
Cary Clark8032b982017-07-28 11:04:54 -04003606}
3607##
3608
Cary Clark2ade9972017-11-02 17:49:34 -04003609#SeeAlso drawRect drawRoundRect drawRRect drawCircle drawOval drawPath
Cary Clark8032b982017-07-28 11:04:54 -04003610
3611##
3612
3613# ------------------------------------------------------------------------------
3614
3615#Method void drawCircle(SkScalar cx, SkScalar cy, SkScalar radius, const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05003616#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05003617#Line # draws Circle using Clip, Matrix, and Paint ##
Cary Clark8032b982017-07-28 11:04:54 -04003618Draw Circle at (cx, cy) with radius using Clip, Matrix, and Paint paint.
3619If radius is zero or less, nothing is drawn.
Herb Derbyefe39bc2018-05-01 17:06:20 -04003620In paint: Paint_Style determines if Circle is stroked or filled;
Cary Clark8032b982017-07-28 11:04:54 -04003621if stroked, Paint_Stroke_Width describes the line thickness.
3622
Cary Clarkbad5ad72017-08-03 17:14:08 -04003623#Param cx Circle center on the x-axis ##
3624#Param cy Circle center on the y-axis ##
3625#Param radius half the diameter of Circle ##
3626#Param paint Paint stroke or fill, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003627
3628#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003629 void draw(SkCanvas* canvas) {
3630 SkPaint paint;
3631 paint.setAntiAlias(true);
3632 canvas->drawCircle(128, 128, 90, paint);
3633 paint.setColor(SK_ColorWHITE);
3634 canvas->drawCircle(86, 86, 20, paint);
3635 canvas->drawCircle(160, 76, 20, paint);
3636 canvas->drawCircle(140, 150, 35, paint);
3637 }
3638##
3639
Cary Clark2ade9972017-11-02 17:49:34 -04003640#SeeAlso drawOval drawRRect drawRoundRect drawPath drawArc drawPoint drawLine
Cary Clarkbad5ad72017-08-03 17:14:08 -04003641
3642##
3643
3644#Method void drawCircle(SkPoint center, SkScalar radius, const SkPaint& paint)
3645
Cary Clarkce101242017-09-01 15:51:02 -04003646Draw Circle at center with radius using Clip, Matrix, and Paint paint.
Cary Clarkbad5ad72017-08-03 17:14:08 -04003647If radius is zero or less, nothing is drawn.
Herb Derbyefe39bc2018-05-01 17:06:20 -04003648In paint: Paint_Style determines if Circle is stroked or filled;
Cary Clarkbad5ad72017-08-03 17:14:08 -04003649if stroked, Paint_Stroke_Width describes the line thickness.
3650
3651#Param center Circle center ##
3652#Param radius half the diameter of Circle ##
3653#Param paint Paint stroke or fill, blend, color, and so on, used to draw ##
3654
3655#Example
3656 void draw(SkCanvas* canvas) {
3657 SkPaint paint;
3658 paint.setAntiAlias(true);
3659 canvas->drawCircle(128, 128, 90, paint);
3660 paint.setColor(SK_ColorWHITE);
3661 canvas->drawCircle({86, 86}, 20, paint);
3662 canvas->drawCircle({160, 76}, 20, paint);
3663 canvas->drawCircle({140, 150}, 35, paint);
3664 }
Cary Clark8032b982017-07-28 11:04:54 -04003665##
3666
Cary Clark2ade9972017-11-02 17:49:34 -04003667#SeeAlso drawOval drawRRect drawRoundRect drawPath drawArc drawPoint drawLine
Cary Clark8032b982017-07-28 11:04:54 -04003668
3669##
3670
3671# ------------------------------------------------------------------------------
3672
3673#Method void drawArc(const SkRect& oval, SkScalar startAngle, SkScalar sweepAngle,
3674 bool useCenter, const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05003675#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05003676#Line # draws Arc using Clip, Matrix, and Paint ##
Cary Clark8032b982017-07-28 11:04:54 -04003677
3678Draw Arc using Clip, Matrix, and Paint paint.
Cary Clarkbad5ad72017-08-03 17:14:08 -04003679
Cary Clark8032b982017-07-28 11:04:54 -04003680Arc is part of Oval bounded by oval, sweeping from startAngle to startAngle plus
3681sweepAngle. startAngle and sweepAngle are in degrees.
Cary Clarkbad5ad72017-08-03 17:14:08 -04003682
Cary Clark8032b982017-07-28 11:04:54 -04003683startAngle of zero places start point at the right middle edge of oval.
3684A positive sweepAngle places Arc end point clockwise from start point;
3685a negative sweepAngle places Arc end point counterclockwise from start point.
3686sweepAngle may exceed 360 degrees, a full circle.
3687If useCenter is true, draw a wedge that includes lines from oval
3688center to Arc end points. If useCenter is false, draw Arc between end points.
3689
3690If Rect oval is empty or sweepAngle is zero, nothing is drawn.
3691
Cary Clarkbad5ad72017-08-03 17:14:08 -04003692#Param oval Rect bounds of Oval containing Arc to draw ##
3693#Param startAngle angle in degrees where Arc begins ##
3694#Param sweepAngle sweep angle in degrees; positive is clockwise ##
3695#Param useCenter if true, include the center of the oval ##
3696#Param paint Paint stroke or fill, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003697
3698#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003699 void draw(SkCanvas* canvas) {
3700 SkPaint paint;
3701 paint.setAntiAlias(true);
3702 SkRect oval = { 4, 4, 60, 60};
3703 for (auto useCenter : { false, true } ) {
3704 for (auto style : { SkPaint::kFill_Style, SkPaint::kStroke_Style } ) {
3705 paint.setStyle(style);
3706 for (auto degrees : { 45, 90, 180, 360} ) {
3707 canvas->drawArc(oval, 0, degrees , useCenter, paint);
3708 canvas->translate(64, 0);
3709 }
3710 canvas->translate(-256, 64);
3711 }
3712 }
Cary Clark8032b982017-07-28 11:04:54 -04003713 }
3714##
3715
3716#Example
3717#Height 64
Cary Clarkbad5ad72017-08-03 17:14:08 -04003718 void draw(SkCanvas* canvas) {
3719 SkPaint paint;
3720 paint.setAntiAlias(true);
3721 paint.setStyle(SkPaint::kStroke_Style);
3722 paint.setStrokeWidth(4);
3723 SkRect oval = { 4, 4, 60, 60};
3724 float intervals[] = { 5, 5 };
3725 paint.setPathEffect(SkDashPathEffect::Make(intervals, 2, 2.5f));
3726 for (auto degrees : { 270, 360, 540, 720 } ) {
3727 canvas->drawArc(oval, 0, degrees, false, paint);
3728 canvas->translate(64, 0);
3729 }
Cary Clark8032b982017-07-28 11:04:54 -04003730 }
3731##
3732
Cary Clark2ade9972017-11-02 17:49:34 -04003733#SeeAlso SkPath::arcTo drawCircle drawOval drawPath
Cary Clark8032b982017-07-28 11:04:54 -04003734
3735##
3736
3737# ------------------------------------------------------------------------------
3738
3739#Method void drawRoundRect(const SkRect& rect, SkScalar rx, SkScalar ry, const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05003740#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05003741#Line # draws Round_Rect using Clip, Matrix, and Paint ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003742Draw Round_Rect bounded by Rect rect, with corner radii (rx, ry) using Clip,
3743Matrix, and Paint paint.
3744
Herb Derbyefe39bc2018-05-01 17:06:20 -04003745In paint: Paint_Style determines if Round_Rect is stroked or filled;
Cary Clark8032b982017-07-28 11:04:54 -04003746if stroked, Paint_Stroke_Width describes the line thickness.
3747If rx or ry are less than zero, they are treated as if they are zero.
3748If rx plus ry exceeds rect width or rect height, radii are scaled down to fit.
Cary Clarkbad5ad72017-08-03 17:14:08 -04003749If rx and ry are zero, Round_Rect is drawn as Rect and if stroked is affected by
3750Paint_Stroke_Join.
Cary Clark8032b982017-07-28 11:04:54 -04003751
Cary Clarkbad5ad72017-08-03 17:14:08 -04003752#Param rect Rect bounds of Round_Rect to draw ##
Cary Clarkce101242017-09-01 15:51:02 -04003753#Param rx axis length in x of oval describing rounded corners ##
3754#Param ry axis length in y of oval describing rounded corners ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003755#Param paint stroke, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003756
3757#Example
3758#Description
3759 Top row has a zero radius a generates a rectangle.
3760 Second row radii sum to less than sides.
3761 Third row radii sum equals sides.
3762 Fourth row radii sum exceeds sides; radii are scaled to fit.
3763##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003764 void draw(SkCanvas* canvas) {
3765 SkVector radii[] = { {0, 20}, {10, 10}, {10, 20}, {10, 40} };
3766 SkPaint paint;
3767 paint.setStrokeWidth(15);
3768 paint.setStrokeJoin(SkPaint::kRound_Join);
3769 paint.setAntiAlias(true);
3770 for (auto style : { SkPaint::kStroke_Style, SkPaint::kFill_Style } ) {
3771 paint.setStyle(style );
3772 for (size_t i = 0; i < SK_ARRAY_COUNT(radii); ++i) {
3773 canvas->drawRoundRect({10, 10, 60, 40}, radii[i].fX, radii[i].fY, paint);
3774 canvas->translate(0, 60);
3775 }
3776 canvas->translate(80, -240);
3777 }
Cary Clark8032b982017-07-28 11:04:54 -04003778 }
3779##
3780
Cary Clark2ade9972017-11-02 17:49:34 -04003781#SeeAlso DrawRRect drawRect drawDRRect drawPath drawCircle drawOval drawPoint
Cary Clark8032b982017-07-28 11:04:54 -04003782
3783##
3784
3785# ------------------------------------------------------------------------------
3786
3787#Method void drawPath(const SkPath& path, const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05003788#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05003789#Line # draws Path using Clip, Matrix, and Paint ##
Cary Clark8032b982017-07-28 11:04:54 -04003790Draw Path path using Clip, Matrix, and Paint paint.
3791Path contains an array of Path_Contour, each of which may be open or closed.
3792
3793In paint: Paint_Style determines if Round_Rect is stroked or filled:
Cary Clarkbad5ad72017-08-03 17:14:08 -04003794if filled, Path_Fill_Type determines whether Path_Contour describes inside or
3795outside of fill; if stroked, Paint_Stroke_Width describes the line thickness,
3796Paint_Stroke_Cap describes line ends, and Paint_Stroke_Join describes how
3797corners are drawn.
Cary Clark8032b982017-07-28 11:04:54 -04003798
Cary Clarkbad5ad72017-08-03 17:14:08 -04003799#Param path Path to draw ##
3800#Param paint stroke, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003801
3802#Example
3803#Description
3804 Top rows draw stroked path with combinations of joins and caps. The open contour
3805 is affected by caps; the closed contour is affected by joins.
Herb Derbyefe39bc2018-05-01 17:06:20 -04003806 Bottom row draws fill the same for open and closed contour.
Cary Clark8032b982017-07-28 11:04:54 -04003807 First bottom column shows winding fills overlap.
3808 Second bottom column shows even odd fills exclude overlap.
3809 Third bottom column shows inverse winding fills area outside both contours.
3810##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003811void draw(SkCanvas* canvas) {
3812 SkPath path;
3813 path.moveTo(20, 20);
3814 path.quadTo(60, 20, 60, 60);
3815 path.close();
3816 path.moveTo(60, 20);
3817 path.quadTo(60, 60, 20, 60);
3818 SkPaint paint;
3819 paint.setStrokeWidth(10);
3820 paint.setAntiAlias(true);
3821 paint.setStyle(SkPaint::kStroke_Style);
3822 for (auto join: { SkPaint::kBevel_Join, SkPaint::kRound_Join, SkPaint::kMiter_Join } ) {
3823 paint.setStrokeJoin(join);
3824 for (auto cap: { SkPaint::kButt_Cap, SkPaint::kSquare_Cap, SkPaint::kRound_Cap } ) {
3825 paint.setStrokeCap(cap);
3826 canvas->drawPath(path, paint);
3827 canvas->translate(80, 0);
3828 }
3829 canvas->translate(-240, 60);
3830 }
3831 paint.setStyle(SkPaint::kFill_Style);
Herb Derbyefe39bc2018-05-01 17:06:20 -04003832 for (auto fill : { SkPath::kWinding_FillType,
3833 SkPath::kEvenOdd_FillType,
Cary Clarkbad5ad72017-08-03 17:14:08 -04003834 SkPath::kInverseWinding_FillType } ) {
3835 path.setFillType(fill);
3836 canvas->save();
3837 canvas->clipRect({0, 10, 80, 70});
3838 canvas->drawPath(path, paint);
3839 canvas->restore();
3840 canvas->translate(80, 0);
3841 }
Cary Clark8032b982017-07-28 11:04:54 -04003842}
3843##
3844
Cary Clark2ade9972017-11-02 17:49:34 -04003845#SeeAlso SkPath drawLine drawArc drawRect drawPoints
Cary Clark8032b982017-07-28 11:04:54 -04003846
3847##
3848
3849# ------------------------------------------------------------------------------
Cary Clark08895c42018-02-01 09:37:32 -05003850#Subtopic Draw_Image
3851#Line # draws Image to Canvas ##
Cary Clark8032b982017-07-28 11:04:54 -04003852
Cary Clarkbad5ad72017-08-03 17:14:08 -04003853drawImage, drawImageRect, and drawImageNine can be called with a bare pointer or
3854a smart pointer as a convenience. The pairs of calls are otherwise identical.
Cary Clark8032b982017-07-28 11:04:54 -04003855
Cary Clark73fa9722017-08-29 17:36:51 -04003856#Method void drawImage(const SkImage* image, SkScalar left, SkScalar top, const SkPaint* paint = nullptr)
Cary Clarkab2621d2018-01-30 10:08:57 -05003857#In Draw_Image
Cary Clark78de7512018-02-07 07:27:09 -05003858#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05003859#Line # draws Image at (x, y) position ##
Cary Clark8032b982017-07-28 11:04:54 -04003860Draw Image image, with its top-left corner at (left, top),
3861using Clip, Matrix, and optional Paint paint.
3862
Cary Clarkbad5ad72017-08-03 17:14:08 -04003863If paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter, Blend_Mode,
3864and Draw_Looper. If image is kAlpha_8_SkColorType, apply Shader.
3865If paint contains Mask_Filter, generate mask from image bounds. If generated
3866mask extends beyond image bounds, replicate image edge colors, just as Shader
3867made from SkImage::makeShader with SkShader::kClamp_TileMode set replicates the
Herb Derbyefe39bc2018-05-01 17:06:20 -04003868image edge color when it samples outside of its bounds.
Cary Clark8032b982017-07-28 11:04:54 -04003869
Cary Clarkbad5ad72017-08-03 17:14:08 -04003870#Param image uncompressed rectangular map of pixels ##
3871#Param left left side of image ##
3872#Param top top side of image ##
3873#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
3874 and so on; or nullptr
3875##
Cary Clark8032b982017-07-28 11:04:54 -04003876
3877#Example
3878#Height 64
3879#Image 4
Cary Clarkbad5ad72017-08-03 17:14:08 -04003880void draw(SkCanvas* canvas) {
3881 // sk_sp<SkImage> image;
3882 SkImage* imagePtr = image.get();
3883 canvas->drawImage(imagePtr, 0, 0);
3884 SkPaint paint;
3885 canvas->drawImage(imagePtr, 80, 0, &paint);
3886 paint.setAlpha(0x80);
3887 canvas->drawImage(imagePtr, 160, 0, &paint);
Cary Clark8032b982017-07-28 11:04:54 -04003888}
3889##
3890
Cary Clark2ade9972017-11-02 17:49:34 -04003891#SeeAlso drawBitmap drawImageLattice drawImageNine drawImageRect SkPaint::setImageFilter
Cary Clark8032b982017-07-28 11:04:54 -04003892
3893##
3894
3895# ------------------------------------------------------------------------------
3896
3897#Method void drawImage(const sk_sp<SkImage>& image, SkScalar left, SkScalar top,
Herb Derbyefe39bc2018-05-01 17:06:20 -04003898 const SkPaint* paint = nullptr)
Cary Clark8032b982017-07-28 11:04:54 -04003899
3900Draw Image image, with its top-left corner at (left, top),
3901using Clip, Matrix, and optional Paint paint.
3902
Cary Clarkbad5ad72017-08-03 17:14:08 -04003903If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
3904Blend_Mode, and Draw_Looper. If image is kAlpha_8_SkColorType, apply Shader.
3905If paint contains Mask_Filter, generate mask from image bounds. If generated
3906mask extends beyond image bounds, replicate image edge colors, just as Shader
3907made from SkImage::makeShader with SkShader::kClamp_TileMode set replicates the
Herb Derbyefe39bc2018-05-01 17:06:20 -04003908image edge color when it samples outside of its bounds.
Cary Clark8032b982017-07-28 11:04:54 -04003909
Cary Clarkbad5ad72017-08-03 17:14:08 -04003910#Param image uncompressed rectangular map of pixels ##
3911#Param left left side of image ##
3912#Param top pop side of image ##
3913#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
3914 and so on; or nullptr
3915##
Cary Clark8032b982017-07-28 11:04:54 -04003916
3917#Example
3918#Height 64
3919#Image 4
Cary Clarkbad5ad72017-08-03 17:14:08 -04003920void draw(SkCanvas* canvas) {
3921 // sk_sp<SkImage> image;
3922 canvas->drawImage(image, 0, 0);
3923 SkPaint paint;
3924 canvas->drawImage(image, 80, 0, &paint);
3925 paint.setAlpha(0x80);
3926 canvas->drawImage(image, 160, 0, &paint);
Cary Clark8032b982017-07-28 11:04:54 -04003927}
3928##
3929
Cary Clark2ade9972017-11-02 17:49:34 -04003930#SeeAlso drawBitmap drawImageLattice drawImageNine drawImageRect SkPaint::setImageFilter
Cary Clark8032b982017-07-28 11:04:54 -04003931
3932##
3933
3934# ------------------------------------------------------------------------------
3935
3936#Enum SrcRectConstraint
Cary Clark08895c42018-02-01 09:37:32 -05003937#Line # sets drawImageRect options ##
Cary Clark8032b982017-07-28 11:04:54 -04003938
3939#Code
3940 enum SrcRectConstraint {
Herb Derbyefe39bc2018-05-01 17:06:20 -04003941 kStrict_SrcRectConstraint,
3942 kFast_SrcRectConstraint,
Cary Clark8032b982017-07-28 11:04:54 -04003943 };
3944##
3945
Cary Clarkce101242017-09-01 15:51:02 -04003946SrcRectConstraint controls the behavior at the edge of source Rect,
3947provided to drawImageRect, trading off speed for precision.
Cary Clark8032b982017-07-28 11:04:54 -04003948
Cary Clarkce101242017-09-01 15:51:02 -04003949Image_Filter in Paint may sample multiple pixels in the image. Source Rect
Cary Clarkbad5ad72017-08-03 17:14:08 -04003950restricts the bounds of pixels that may be read. Image_Filter may slow down if
Herb Derbyefe39bc2018-05-01 17:06:20 -04003951it cannot read outside the bounds, when sampling near the edge of source Rect.
Cary Clark8032b982017-07-28 11:04:54 -04003952SrcRectConstraint specifies whether an Image_Filter is allowed to read pixels
Cary Clarkce101242017-09-01 15:51:02 -04003953outside source Rect.
Cary Clark8032b982017-07-28 11:04:54 -04003954
Cary Clark682c58d2018-05-16 07:07:07 -04003955#Const kStrict_SrcRectConstraint 0
3956#Line # sample only inside bounds; slower ##
Cary Clarkce101242017-09-01 15:51:02 -04003957 Requires Image_Filter to respect source Rect,
Cary Clark8032b982017-07-28 11:04:54 -04003958 sampling only inside of its bounds, possibly with a performance penalty.
3959##
3960
Cary Clark682c58d2018-05-16 07:07:07 -04003961#Const kFast_SrcRectConstraint 1
3962#Line # sample outside bounds; faster ##
Cary Clarkce101242017-09-01 15:51:02 -04003963 Permits Image_Filter to sample outside of source Rect
Cary Clark8032b982017-07-28 11:04:54 -04003964 by half the width of Image_Filter, permitting it to run faster but with
3965 error at the image edges.
3966##
3967
3968#Example
3969#Height 64
3970#Description
3971 redBorder contains a black and white checkerboard bordered by red.
3972 redBorder is drawn scaled by 16 on the left.
Cary Clarkce101242017-09-01 15:51:02 -04003973 The middle and right bitmaps are filtered checkerboards.
Cary Clark8032b982017-07-28 11:04:54 -04003974 Drawing the checkerboard with kStrict_SrcRectConstraint shows only a blur of black and white.
3975 Drawing the checkerboard with kFast_SrcRectConstraint allows red to bleed in the corners.
3976##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003977void draw(SkCanvas* canvas) {
3978 SkBitmap redBorder;
3979 redBorder.allocPixels(SkImageInfo::MakeN32Premul(4, 4));
3980 SkCanvas checkRed(redBorder);
3981 checkRed.clear(SK_ColorRED);
3982 uint32_t checkers[][2] = { { SK_ColorBLACK, SK_ColorWHITE },
3983 { SK_ColorWHITE, SK_ColorBLACK } };
3984 checkRed.writePixels(
3985 SkImageInfo::MakeN32Premul(2, 2), (void*) checkers, sizeof(checkers[0]), 1, 1);
3986 canvas->scale(16, 16);
3987 canvas->drawBitmap(redBorder, 0, 0, nullptr);
3988 canvas->resetMatrix();
3989 sk_sp<SkImage> image = SkImage::MakeFromBitmap(redBorder);
3990 SkPaint lowPaint;
3991 lowPaint.setFilterQuality(kLow_SkFilterQuality);
3992 for (auto constraint : { SkCanvas::kStrict_SrcRectConstraint,
3993 SkCanvas::kFast_SrcRectConstraint } ) {
3994 canvas->translate(80, 0);
3995 canvas->drawImageRect(image.get(), SkRect::MakeLTRB(1, 1, 3, 3),
3996 SkRect::MakeLTRB(16, 16, 48, 48), &lowPaint, constraint);
3997 }
Cary Clark8032b982017-07-28 11:04:54 -04003998}
3999##
4000
Cary Clark2ade9972017-11-02 17:49:34 -04004001#SeeAlso drawImageRect drawImage SkPaint::setImageFilter
Cary Clark8032b982017-07-28 11:04:54 -04004002
4003##
4004
4005# ------------------------------------------------------------------------------
4006
4007#Method void drawImageRect(const SkImage* image, const SkRect& src, const SkRect& dst,
4008 const SkPaint* paint,
4009 SrcRectConstraint constraint = kStrict_SrcRectConstraint)
Cary Clarkab2621d2018-01-30 10:08:57 -05004010#In Draw_Image
Cary Clark78de7512018-02-07 07:27:09 -05004011#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05004012#Line # draws Image, source Rect to destination Rect ##
Cary Clark8032b982017-07-28 11:04:54 -04004013
4014Draw Rect src of Image image, scaled and translated to fill Rect dst.
4015Additionally transform draw using Clip, Matrix, and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004016
Cary Clarkbad5ad72017-08-03 17:14:08 -04004017If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4018Blend_Mode, and Draw_Looper. If image is kAlpha_8_SkColorType, apply Shader.
4019If paint contains Mask_Filter, generate mask from image bounds.
4020
4021If generated mask extends beyond image bounds, replicate image edge colors, just
4022as Shader made from SkImage::makeShader with SkShader::kClamp_TileMode set
Cary Clarkbc5697d2017-10-04 14:31:33 -04004023replicates the image edge color when it samples outside of its bounds.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004024
4025constraint set to kStrict_SrcRectConstraint limits Paint Filter_Quality to
4026sample within src; set to kFast_SrcRectConstraint allows sampling outside to
4027improve performance.
4028
4029#Param image Image containing pixels, dimensions, and format ##
4030#Param src source Rect of image to draw from ##
4031#Param dst destination Rect of image to draw to ##
4032#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4033 and so on; or nullptr
4034##
4035#Param constraint filter strictly within src or draw faster ##
Cary Clark8032b982017-07-28 11:04:54 -04004036
4037#Example
4038#Height 64
4039#Description
4040 The left bitmap draws with Paint default kNone_SkFilterQuality, and stays within
Cary Clarkbc5697d2017-10-04 14:31:33 -04004041 its bounds; there is no bleeding with kFast_SrcRectConstraint.
Cary Clark8032b982017-07-28 11:04:54 -04004042 the middle and right bitmaps draw with kLow_SkFilterQuality; with
4043 kStrict_SrcRectConstraint, the filter remains within the checkerboard, and
4044 with kFast_SrcRectConstraint red bleeds on the edges.
4045##
Cary Clarkbad5ad72017-08-03 17:14:08 -04004046void draw(SkCanvas* canvas) {
Herb Derbyefe39bc2018-05-01 17:06:20 -04004047 uint32_t pixels[][4] = {
Cary Clarkbad5ad72017-08-03 17:14:08 -04004048 { 0xFFFF0000, 0xFFFF0000, 0xFFFF0000, 0xFFFF0000 },
4049 { 0xFFFF0000, 0xFF000000, 0xFFFFFFFF, 0xFFFF0000 },
4050 { 0xFFFF0000, 0xFFFFFFFF, 0xFF000000, 0xFFFF0000 },
4051 { 0xFFFF0000, 0xFFFF0000, 0xFFFF0000, 0xFFFF0000 } };
4052 SkBitmap redBorder;
Herb Derbyefe39bc2018-05-01 17:06:20 -04004053 redBorder.installPixels(SkImageInfo::MakeN32Premul(4, 4),
Cary Clarkbad5ad72017-08-03 17:14:08 -04004054 (void*) pixels, sizeof(pixels[0]));
4055 sk_sp<SkImage> image = SkImage::MakeFromBitmap(redBorder);
4056 SkPaint lowPaint;
4057 for (auto constraint : {
4058 SkCanvas::kFast_SrcRectConstraint,
4059 SkCanvas::kStrict_SrcRectConstraint,
4060 SkCanvas::kFast_SrcRectConstraint } ) {
4061 canvas->drawImageRect(image.get(), SkRect::MakeLTRB(1, 1, 3, 3),
4062 SkRect::MakeLTRB(16, 16, 48, 48), &lowPaint, constraint);
4063 lowPaint.setFilterQuality(kLow_SkFilterQuality);
4064 canvas->translate(80, 0);
4065 }
4066}
Cary Clark8032b982017-07-28 11:04:54 -04004067##
4068
Cary Clark2ade9972017-11-02 17:49:34 -04004069#SeeAlso SrcRectConstraint drawImage drawImageLattice drawImageNine
Cary Clark8032b982017-07-28 11:04:54 -04004070
4071##
4072
4073# ------------------------------------------------------------------------------
4074
4075#Method void drawImageRect(const SkImage* image, const SkIRect& isrc, const SkRect& dst,
4076 const SkPaint* paint, SrcRectConstraint constraint = kStrict_SrcRectConstraint)
Cary Clarkab2621d2018-01-30 10:08:57 -05004077#In Draw_Image
Cary Clark78de7512018-02-07 07:27:09 -05004078#In Draw
Cary Clark8032b982017-07-28 11:04:54 -04004079
4080Draw IRect isrc of Image image, scaled and translated to fill Rect dst.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004081Note that isrc is on integer pixel boundaries; dst may include fractional
4082boundaries. Additionally transform draw using Clip, Matrix, and optional Paint
Herb Derbyefe39bc2018-05-01 17:06:20 -04004083paint.
Cary Clark8032b982017-07-28 11:04:54 -04004084
Cary Clarkbad5ad72017-08-03 17:14:08 -04004085If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4086Blend_Mode, and Draw_Looper. If image is kAlpha_8_SkColorType, apply Shader.
4087If paint contains Mask_Filter, generate mask from image bounds.
4088
4089If generated mask extends beyond image bounds, replicate image edge colors, just
4090as Shader made from SkImage::makeShader with SkShader::kClamp_TileMode set
Cary Clarkbc5697d2017-10-04 14:31:33 -04004091replicates the image edge color when it samples outside of its bounds.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004092
4093constraint set to kStrict_SrcRectConstraint limits Paint Filter_Quality to
Cary Clarkce101242017-09-01 15:51:02 -04004094sample within isrc; set to kFast_SrcRectConstraint allows sampling outside to
Cary Clarkbad5ad72017-08-03 17:14:08 -04004095improve performance.
4096
4097#Param image Image containing pixels, dimensions, and format ##
4098#Param isrc source IRect of image to draw from ##
4099#Param dst destination Rect of image to draw to ##
4100#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4101 and so on; or nullptr
4102##
Cary Clarkce101242017-09-01 15:51:02 -04004103#Param constraint filter strictly within isrc or draw faster ##
Cary Clark8032b982017-07-28 11:04:54 -04004104
4105#Example
4106#Image 4
Cary Clarkbad5ad72017-08-03 17:14:08 -04004107void draw(SkCanvas* canvas) {
4108 // sk_sp<SkImage> image;
4109 for (auto i : { 1, 2, 4, 8 } ) {
Herb Derbyefe39bc2018-05-01 17:06:20 -04004110 canvas->drawImageRect(image.get(), SkIRect::MakeLTRB(0, 0, 100, 100),
Cary Clarkbad5ad72017-08-03 17:14:08 -04004111 SkRect::MakeXYWH(i * 20, i * 20, i * 20, i * 20), nullptr);
4112 }
Cary Clark8032b982017-07-28 11:04:54 -04004113}
4114##
4115
Cary Clark2ade9972017-11-02 17:49:34 -04004116#SeeAlso SrcRectConstraint drawImage drawImageLattice drawImageNine
Cary Clark8032b982017-07-28 11:04:54 -04004117
4118##
4119
4120# ------------------------------------------------------------------------------
4121
4122#Method void drawImageRect(const SkImage* image, const SkRect& dst, const SkPaint* paint,
4123 SrcRectConstraint constraint = kStrict_SrcRectConstraint)
Cary Clarkab2621d2018-01-30 10:08:57 -05004124#In Draw_Image
Cary Clark78de7512018-02-07 07:27:09 -05004125#In Draw
Cary Clark8032b982017-07-28 11:04:54 -04004126
Cary Clarkbad5ad72017-08-03 17:14:08 -04004127Draw Image image, scaled and translated to fill Rect dst, using Clip, Matrix,
4128and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004129
Cary Clarkbad5ad72017-08-03 17:14:08 -04004130If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4131Blend_Mode, and Draw_Looper. If image is kAlpha_8_SkColorType, apply Shader.
4132If paint contains Mask_Filter, generate mask from image bounds.
4133
4134If generated mask extends beyond image bounds, replicate image edge colors, just
4135as Shader made from SkImage::makeShader with SkShader::kClamp_TileMode set
Cary Clarkbc5697d2017-10-04 14:31:33 -04004136replicates the image edge color when it samples outside of its bounds.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004137
4138constraint set to kStrict_SrcRectConstraint limits Paint Filter_Quality to
Cary Clarkce101242017-09-01 15:51:02 -04004139sample within image; set to kFast_SrcRectConstraint allows sampling outside to
Cary Clarkbad5ad72017-08-03 17:14:08 -04004140improve performance.
4141
4142#Param image Image containing pixels, dimensions, and format ##
4143#Param dst destination Rect of image to draw to ##
4144#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4145 and so on; or nullptr
4146##
Cary Clarkce101242017-09-01 15:51:02 -04004147#Param constraint filter strictly within image or draw faster ##
Cary Clark8032b982017-07-28 11:04:54 -04004148
4149#Example
4150#Image 4
Cary Clarkbad5ad72017-08-03 17:14:08 -04004151void draw(SkCanvas* canvas) {
4152 // sk_sp<SkImage> image;
4153 for (auto i : { 20, 40, 80, 160 } ) {
4154 canvas->drawImageRect(image.get(), SkRect::MakeXYWH(i, i, i, i), nullptr);
4155 }
Cary Clark8032b982017-07-28 11:04:54 -04004156}
4157##
4158
Cary Clark2ade9972017-11-02 17:49:34 -04004159#SeeAlso SrcRectConstraint drawImage drawImageLattice drawImageNine
Cary Clark8032b982017-07-28 11:04:54 -04004160
4161##
4162
4163# ------------------------------------------------------------------------------
4164
4165#Method void drawImageRect(const sk_sp<SkImage>& image, const SkRect& src, const SkRect& dst,
4166 const SkPaint* paint,
Herb Derbyefe39bc2018-05-01 17:06:20 -04004167 SrcRectConstraint constraint = kStrict_SrcRectConstraint)
Cary Clarkab2621d2018-01-30 10:08:57 -05004168#In Draw_Image
Cary Clark78de7512018-02-07 07:27:09 -05004169#In Draw
Cary Clark8032b982017-07-28 11:04:54 -04004170Draw Rect src of Image image, scaled and translated to fill Rect dst.
4171Additionally transform draw using Clip, Matrix, and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004172
Cary Clarkbad5ad72017-08-03 17:14:08 -04004173If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4174Blend_Mode, and Draw_Looper. If image is kAlpha_8_SkColorType, apply Shader.
4175If paint contains Mask_Filter, generate mask from image bounds.
4176
4177If generated mask extends beyond image bounds, replicate image edge colors, just
4178as Shader made from SkImage::makeShader with SkShader::kClamp_TileMode set
Cary Clarkbc5697d2017-10-04 14:31:33 -04004179replicates the image edge color when it samples outside of its bounds.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004180
4181constraint set to kStrict_SrcRectConstraint limits Paint Filter_Quality to
4182sample within src; set to kFast_SrcRectConstraint allows sampling outside to
4183improve performance.
4184
4185#Param image Image containing pixels, dimensions, and format ##
4186#Param src source Rect of image to draw from ##
4187#Param dst destination Rect of image to draw to ##
4188#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4189 and so on; or nullptr
4190##
4191#Param constraint filter strictly within src or draw faster ##
Cary Clark8032b982017-07-28 11:04:54 -04004192
4193#Example
4194#Height 64
4195#Description
4196 Canvas scales and translates; transformation from src to dst also scales.
4197 The two matrices are concatenated to create the final transformation.
4198##
Cary Clarkbad5ad72017-08-03 17:14:08 -04004199void draw(SkCanvas* canvas) {
4200 uint32_t pixels[][2] = { { SK_ColorBLACK, SK_ColorWHITE },
4201 { SK_ColorWHITE, SK_ColorBLACK } };
4202 SkBitmap bitmap;
Herb Derbyefe39bc2018-05-01 17:06:20 -04004203 bitmap.installPixels(SkImageInfo::MakeN32Premul(2, 2),
Cary Clarkbad5ad72017-08-03 17:14:08 -04004204 (void*) pixels, sizeof(pixels[0]));
4205 sk_sp<SkImage> image = SkImage::MakeFromBitmap(bitmap);
4206 SkPaint paint;
4207 canvas->scale(4, 4);
4208 for (auto alpha : { 50, 100, 150, 255 } ) {
4209 paint.setAlpha(alpha);
4210 canvas->drawImageRect(image, SkRect::MakeWH(2, 2), SkRect::MakeWH(8, 8), &paint);
4211 canvas->translate(8, 0);
4212 }
4213}
Cary Clark8032b982017-07-28 11:04:54 -04004214##
4215
Cary Clark2ade9972017-11-02 17:49:34 -04004216#SeeAlso SrcRectConstraint drawImage drawImageLattice drawImageNine
Cary Clark8032b982017-07-28 11:04:54 -04004217
4218##
4219
4220# ------------------------------------------------------------------------------
4221
4222#Method void drawImageRect(const sk_sp<SkImage>& image, const SkIRect& isrc, const SkRect& dst,
Herb Derbyefe39bc2018-05-01 17:06:20 -04004223 const SkPaint* paint, SrcRectConstraint constraint = kStrict_SrcRectConstraint)
Cary Clarkab2621d2018-01-30 10:08:57 -05004224#In Draw_Image
Cary Clark78de7512018-02-07 07:27:09 -05004225#In Draw
Cary Clark8032b982017-07-28 11:04:54 -04004226Draw IRect isrc of Image image, scaled and translated to fill Rect dst.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004227isrc is on integer pixel boundaries; dst may include fractional boundaries.
Cary Clark8032b982017-07-28 11:04:54 -04004228Additionally transform draw using Clip, Matrix, and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004229
Cary Clarkbad5ad72017-08-03 17:14:08 -04004230If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4231Blend_Mode, and Draw_Looper. If image is kAlpha_8_SkColorType, apply Shader.
4232If paint contains Mask_Filter, generate mask from image bounds.
4233
4234If generated mask extends beyond image bounds, replicate image edge colors, just
4235as Shader made from SkImage::makeShader with SkShader::kClamp_TileMode set
Cary Clarkbc5697d2017-10-04 14:31:33 -04004236replicates the image edge color when it samples outside of its bounds.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004237
4238constraint set to kStrict_SrcRectConstraint limits Paint Filter_Quality to
Cary Clarkce101242017-09-01 15:51:02 -04004239sample within image; set to kFast_SrcRectConstraint allows sampling outside to
Cary Clarkbad5ad72017-08-03 17:14:08 -04004240improve performance.
4241
4242#Param image Image containing pixels, dimensions, and format ##
4243#Param isrc source IRect of image to draw from ##
4244#Param dst destination Rect of image to draw to ##
4245#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4246 and so on; or nullptr
4247##
Cary Clarkce101242017-09-01 15:51:02 -04004248#Param constraint filter strictly within image or draw faster ##
Cary Clark8032b982017-07-28 11:04:54 -04004249
4250#Example
4251#Height 64
Cary Clarkbad5ad72017-08-03 17:14:08 -04004252void draw(SkCanvas* canvas) {
4253 uint32_t pixels[][2] = { { 0x00000000, 0x55555555},
4254 { 0xAAAAAAAA, 0xFFFFFFFF} };
4255 SkBitmap bitmap;
Herb Derbyefe39bc2018-05-01 17:06:20 -04004256 bitmap.installPixels(SkImageInfo::MakeN32Premul(2, 2),
Cary Clarkbad5ad72017-08-03 17:14:08 -04004257 (void*) pixels, sizeof(pixels[0]));
4258 sk_sp<SkImage> image = SkImage::MakeFromBitmap(bitmap);
4259 SkPaint paint;
4260 canvas->scale(4, 4);
4261 for (auto color : { SK_ColorRED, SK_ColorBLUE, SK_ColorGREEN } ) {
4262 paint.setColorFilter(SkColorFilter::MakeModeFilter(color, SkBlendMode::kPlus));
4263 canvas->drawImageRect(image, SkIRect::MakeWH(2, 2), SkRect::MakeWH(8, 8), &paint);
4264 canvas->translate(8, 0);
4265 }
Cary Clark8032b982017-07-28 11:04:54 -04004266}
4267##
4268
Cary Clark2ade9972017-11-02 17:49:34 -04004269#SeeAlso SrcRectConstraint drawImage drawImageLattice drawImageNine
4270
Cary Clark8032b982017-07-28 11:04:54 -04004271##
4272
4273# ------------------------------------------------------------------------------
4274
4275#Method void drawImageRect(const sk_sp<SkImage>& image, const SkRect& dst, const SkPaint* paint,
Herb Derbyefe39bc2018-05-01 17:06:20 -04004276 SrcRectConstraint constraint = kStrict_SrcRectConstraint)
Cary Clarkab2621d2018-01-30 10:08:57 -05004277#In Draw_Image
Cary Clark78de7512018-02-07 07:27:09 -05004278#In Draw
Cary Clark8032b982017-07-28 11:04:54 -04004279Draw Image image, scaled and translated to fill Rect dst,
4280using Clip, Matrix, and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004281
Cary Clarkbad5ad72017-08-03 17:14:08 -04004282If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4283Blend_Mode, and Draw_Looper. If image is kAlpha_8_SkColorType, apply Shader.
4284If paint contains Mask_Filter, generate mask from image bounds.
4285
4286If generated mask extends beyond image bounds, replicate image edge colors, just
4287as Shader made from SkImage::makeShader with SkShader::kClamp_TileMode set
Cary Clarkbc5697d2017-10-04 14:31:33 -04004288replicates the image edge color when it samples outside of its bounds.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004289
4290constraint set to kStrict_SrcRectConstraint limits Paint Filter_Quality to
Cary Clarkce101242017-09-01 15:51:02 -04004291sample within image; set to kFast_SrcRectConstraint allows sampling outside to
Cary Clarkbad5ad72017-08-03 17:14:08 -04004292improve performance.
4293
4294#Param image Image containing pixels, dimensions, and format ##
4295#Param dst destination Rect of image to draw to ##
4296#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4297 and so on; or nullptr
4298##
Cary Clarkce101242017-09-01 15:51:02 -04004299#Param constraint filter strictly within image or draw faster ##
Cary Clark8032b982017-07-28 11:04:54 -04004300
4301#Example
4302#Height 64
Cary Clarkbad5ad72017-08-03 17:14:08 -04004303void draw(SkCanvas* canvas) {
4304 uint32_t pixels[][2] = { { 0x00000000, 0x55550000},
4305 { 0xAAAA0000, 0xFFFF0000} };
4306 SkBitmap bitmap;
Herb Derbyefe39bc2018-05-01 17:06:20 -04004307 bitmap.installPixels(SkImageInfo::MakeN32Premul(2, 2),
Cary Clarkbad5ad72017-08-03 17:14:08 -04004308 (void*) pixels, sizeof(pixels[0]));
4309 sk_sp<SkImage> image = SkImage::MakeFromBitmap(bitmap);
4310 SkPaint paint;
4311 canvas->scale(4, 4);
4312 for (auto color : { SK_ColorRED, SK_ColorBLUE, SK_ColorGREEN } ) {
4313 paint.setColorFilter(SkColorFilter::MakeModeFilter(color, SkBlendMode::kPlus));
4314 canvas->drawImageRect(image, SkRect::MakeWH(8, 8), &paint);
4315 canvas->translate(8, 0);
4316 }
Cary Clark8032b982017-07-28 11:04:54 -04004317}
4318##
4319
Cary Clark2ade9972017-11-02 17:49:34 -04004320#SeeAlso SrcRectConstraint drawImage drawImageLattice drawImageNine
Cary Clark8032b982017-07-28 11:04:54 -04004321
4322##
4323
4324# ------------------------------------------------------------------------------
4325
4326#Method void drawImageNine(const SkImage* image, const SkIRect& center, const SkRect& dst,
4327 const SkPaint* paint = nullptr)
Cary Clarkab2621d2018-01-30 10:08:57 -05004328#In Draw_Image
Cary Clark78de7512018-02-07 07:27:09 -05004329#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05004330#Line # draws Nine_Patch Image ##
Cary Clark8032b982017-07-28 11:04:54 -04004331
Cary Clarkd0530ba2017-09-14 11:25:39 -04004332Draw Image image stretched proportionally to fit into Rect dst.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004333IRect center divides the image into nine sections: four sides, four corners, and
Cary Clarkce101242017-09-01 15:51:02 -04004334the center. Corners are unmodified or scaled down proportionately if their sides
Cary Clarkbad5ad72017-08-03 17:14:08 -04004335are larger than dst; center and four sides are scaled to fit remaining space, if any.
Cary Clark8032b982017-07-28 11:04:54 -04004336
Cary Clarkbad5ad72017-08-03 17:14:08 -04004337Additionally transform draw using Clip, Matrix, and optional Paint paint.
4338
Cary Clark682c58d2018-05-16 07:07:07 -04004339#paint_as_used_by_draw_lattice_or_draw_nine(image)#
Cary Clarkbad5ad72017-08-03 17:14:08 -04004340
4341If generated mask extends beyond image bounds, replicate image edge colors, just
4342as Shader made from SkImage::makeShader with SkShader::kClamp_TileMode set
Cary Clarkbc5697d2017-10-04 14:31:33 -04004343replicates the image edge color when it samples outside of its bounds.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004344
4345#Param image Image containing pixels, dimensions, and format ##
4346#Param center IRect edge of image corners and sides ##
4347#Param dst destination Rect of image to draw to ##
4348#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4349 and so on; or nullptr
4350##
Cary Clark8032b982017-07-28 11:04:54 -04004351
4352#Example
4353#Height 128
4354#Description
4355 The leftmost image is smaller than center; only corners are drawn, all scaled to fit.
Cary Clarkce101242017-09-01 15:51:02 -04004356 The second image equals the size of center; only corners are drawn without scaling.
4357 The remaining images are larger than center. All corners draw without scaling.
4358 The sides and center are scaled if needed to take up the remaining space.
Cary Clark8032b982017-07-28 11:04:54 -04004359##
Cary Clarkbad5ad72017-08-03 17:14:08 -04004360void draw(SkCanvas* canvas) {
4361 SkIRect center = { 20, 10, 50, 40 };
4362 SkBitmap bitmap;
4363 bitmap.allocPixels(SkImageInfo::MakeN32Premul(60, 60));
4364 SkCanvas bitCanvas(bitmap);
4365 SkPaint paint;
4366 SkColor gray = 0xFF000000;
4367 int left = 0;
4368 for (auto right: { center.fLeft, center.fRight, bitmap.width() } ) {
4369 int top = 0;
4370 for (auto bottom: { center.fTop, center.fBottom, bitmap.height() } ) {
4371 paint.setColor(gray);
4372 bitCanvas.drawIRect(SkIRect::MakeLTRB(left, top, right, bottom), paint);
4373 gray += 0x001f1f1f;
4374 top = bottom;
4375 }
Herb Derbyefe39bc2018-05-01 17:06:20 -04004376 left = right;
Cary Clarkbad5ad72017-08-03 17:14:08 -04004377 }
4378 sk_sp<SkImage> image = SkImage::MakeFromBitmap(bitmap);
4379 SkImage* imagePtr = image.get();
4380 for (auto dest: { 20, 30, 40, 60, 90 } ) {
4381 canvas->drawImageNine(imagePtr, center, SkRect::MakeWH(dest, dest), nullptr);
4382 canvas->translate(dest + 4, 0);
4383 }
Cary Clark8032b982017-07-28 11:04:54 -04004384}
4385##
4386
Cary Clark2ade9972017-11-02 17:49:34 -04004387#SeeAlso drawImage drawBitmapNine drawImageLattice drawImageRect
Cary Clark8032b982017-07-28 11:04:54 -04004388
4389##
4390
4391# ------------------------------------------------------------------------------
4392
4393#Method void drawImageNine(const sk_sp<SkImage>& image, const SkIRect& center, const SkRect& dst,
Herb Derbyefe39bc2018-05-01 17:06:20 -04004394 const SkPaint* paint = nullptr)
Cary Clarkab2621d2018-01-30 10:08:57 -05004395#In Draw_Image
Cary Clark78de7512018-02-07 07:27:09 -05004396#In Draw
Cary Clarkd0530ba2017-09-14 11:25:39 -04004397Draw Image image stretched proportionally to fit into Rect dst.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004398IRect center divides the image into nine sections: four sides, four corners, and
Cary Clarkce101242017-09-01 15:51:02 -04004399the center. Corners are not scaled, or scaled down proportionately if their sides
Cary Clarkbad5ad72017-08-03 17:14:08 -04004400are larger than dst; center and four sides are scaled to fit remaining space, if any.
Cary Clark8032b982017-07-28 11:04:54 -04004401
Cary Clarkbad5ad72017-08-03 17:14:08 -04004402Additionally transform draw using Clip, Matrix, and optional Paint paint.
4403
4404If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4405Blend_Mode, and Draw_Looper. If image is kAlpha_8_SkColorType, apply Shader.
4406If paint contains Mask_Filter, generate mask from image bounds.
4407
4408If generated mask extends beyond image bounds, replicate image edge colors, just
4409as Shader made from SkImage::makeShader with SkShader::kClamp_TileMode set
Cary Clarkbc5697d2017-10-04 14:31:33 -04004410replicates the image edge color when it samples outside of its bounds.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004411
4412#Param image Image containing pixels, dimensions, and format ##
4413#Param center IRect edge of image corners and sides ##
4414#Param dst destination Rect of image to draw to ##
4415#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4416 and so on; or nullptr
4417##
Cary Clark8032b982017-07-28 11:04:54 -04004418
4419#Example
4420#Height 128
4421#Description
4422 The two leftmost images has four corners and sides to the left and right of center.
4423 The leftmost image scales the width of corners proportionately to fit.
Herb Derbyefe39bc2018-05-01 17:06:20 -04004424 The third and fourth image corners are not scaled; the sides and center are scaled to
Cary Clark8032b982017-07-28 11:04:54 -04004425 fill the remaining space.
4426 The rightmost image has four corners scaled vertically to fit, and uses sides above
4427 and below center to fill the remaining space.
4428##
Cary Clarkbad5ad72017-08-03 17:14:08 -04004429void draw(SkCanvas* canvas) {
4430 SkIRect center = { 20, 10, 50, 40 };
4431 SkBitmap bitmap;
4432 bitmap.allocPixels(SkImageInfo::MakeN32Premul(60, 60));
4433 SkCanvas bitCanvas(bitmap);
4434 SkPaint paint;
4435 SkColor gray = 0xFF000000;
4436 int left = 0;
4437 for (auto right: { center.fLeft, center.fRight, bitmap.width() } ) {
4438 int top = 0;
4439 for (auto bottom: { center.fTop, center.fBottom, bitmap.height() } ) {
4440 paint.setColor(gray);
4441 bitCanvas.drawIRect(SkIRect::MakeLTRB(left, top, right, bottom), paint);
4442 gray += 0x001f1f1f;
4443 top = bottom;
4444 }
Herb Derbyefe39bc2018-05-01 17:06:20 -04004445 left = right;
Cary Clarkbad5ad72017-08-03 17:14:08 -04004446 }
4447 sk_sp<SkImage> image = SkImage::MakeFromBitmap(bitmap);
4448 for (auto dest: { 20, 30, 40, 60, 90 } ) {
4449 canvas->drawImageNine(image, center, SkRect::MakeWH(dest, 110 - dest), nullptr);
4450 canvas->translate(dest + 4, 0);
4451 }
Cary Clark8032b982017-07-28 11:04:54 -04004452}
4453##
4454
Cary Clark2ade9972017-11-02 17:49:34 -04004455#SeeAlso drawImage drawBitmapNine drawImageLattice drawImageRect
Cary Clark8032b982017-07-28 11:04:54 -04004456
4457##
4458
4459# ------------------------------------------------------------------------------
4460
4461#Method void drawBitmap(const SkBitmap& bitmap, SkScalar left, SkScalar top,
Cary Clark73fa9722017-08-29 17:36:51 -04004462 const SkPaint* paint = nullptr)
Cary Clarkab2621d2018-01-30 10:08:57 -05004463#In Draw_Image
Cary Clark78de7512018-02-07 07:27:09 -05004464#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05004465#Line # draws Bitmap at (x, y) position ##
Cary Clark8032b982017-07-28 11:04:54 -04004466
4467Draw Bitmap bitmap, with its top-left corner at (left, top),
4468using Clip, Matrix, and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004469
Cary Clarka560c472017-11-27 10:44:06 -05004470If Paint paint is not nullptr, apply Color_Filter, Color_Alpha, Image_Filter,
Cary Clarkbad5ad72017-08-03 17:14:08 -04004471Blend_Mode, and Draw_Looper. If bitmap is kAlpha_8_SkColorType, apply Shader.
4472If paint contains Mask_Filter, generate mask from bitmap bounds.
4473
4474If generated mask extends beyond bitmap bounds, replicate bitmap edge colors,
4475just as Shader made from SkShader::MakeBitmapShader with
Cary Clarkbc5697d2017-10-04 14:31:33 -04004476SkShader::kClamp_TileMode set replicates the bitmap edge color when it samples
Herb Derbyefe39bc2018-05-01 17:06:20 -04004477outside of its bounds.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004478
4479#Param bitmap Bitmap containing pixels, dimensions, and format ##
4480#Param left left side of bitmap ##
4481#Param top top side of bitmap ##
4482#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4483 and so on; or nullptr
4484##
Cary Clark8032b982017-07-28 11:04:54 -04004485
4486#Example
4487#Height 64
Cary Clarkbad5ad72017-08-03 17:14:08 -04004488void draw(SkCanvas* canvas) {
4489 uint8_t pixels[][8] = { { 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00},
4490 { 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00},
4491 { 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00},
4492 { 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF},
4493 { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
4494 { 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00},
4495 { 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0x00},
4496 { 0xFF, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0xFF} };
4497 SkBitmap bitmap;
Herb Derbyefe39bc2018-05-01 17:06:20 -04004498 bitmap.installPixels(SkImageInfo::MakeA8(8, 8),
Cary Clarkbad5ad72017-08-03 17:14:08 -04004499 (void*) pixels, sizeof(pixels[0]));
4500 SkPaint paint;
4501 canvas->scale(4, 4);
4502 for (auto color : { SK_ColorRED, SK_ColorBLUE, 0xFF007F00} ) {
4503 paint.setColor(color);
4504 canvas->drawBitmap(bitmap, 0, 0, &paint);
4505 canvas->translate(12, 0);
4506 }
Cary Clark8032b982017-07-28 11:04:54 -04004507}
4508##
4509
Cary Clark2ade9972017-11-02 17:49:34 -04004510#SeeAlso drawImage drawBitmapLattice drawBitmapNine drawBitmapRect SkBitmap::readPixels SkBitmap::writePixels
Cary Clark8032b982017-07-28 11:04:54 -04004511
4512##
4513
4514# ------------------------------------------------------------------------------
4515
4516#Method void drawBitmapRect(const SkBitmap& bitmap, const SkRect& src, const SkRect& dst,
4517 const SkPaint* paint, SrcRectConstraint constraint = kStrict_SrcRectConstraint)
Cary Clarkab2621d2018-01-30 10:08:57 -05004518#In Draw_Image
Cary Clark78de7512018-02-07 07:27:09 -05004519#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05004520#Line # draws Bitmap, source Rect to destination Rect ##
Cary Clark8032b982017-07-28 11:04:54 -04004521
4522Draw Rect src of Bitmap bitmap, scaled and translated to fill Rect dst.
4523Additionally transform draw using Clip, Matrix, and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004524
Cary Clarkbad5ad72017-08-03 17:14:08 -04004525If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4526Blend_Mode, and Draw_Looper. If bitmap is kAlpha_8_SkColorType, apply Shader.
4527If paint contains Mask_Filter, generate mask from bitmap bounds.
4528
4529If generated mask extends beyond bitmap bounds, replicate bitmap edge colors,
4530just as Shader made from SkShader::MakeBitmapShader with
Cary Clarkbc5697d2017-10-04 14:31:33 -04004531SkShader::kClamp_TileMode set replicates the bitmap edge color when it samples
Cary Clarkbad5ad72017-08-03 17:14:08 -04004532outside of its bounds.
4533
4534constraint set to kStrict_SrcRectConstraint limits Paint Filter_Quality to
4535sample within src; set to kFast_SrcRectConstraint allows sampling outside to
4536improve performance.
4537
4538#Param bitmap Bitmap containing pixels, dimensions, and format ##
4539#Param src source Rect of image to draw from ##
4540#Param dst destination Rect of image to draw to ##
4541#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4542 and so on; or nullptr
4543##
4544#Param constraint filter strictly within src or draw faster ##
Cary Clark8032b982017-07-28 11:04:54 -04004545
4546#Example
4547#Height 64
Cary Clarkbad5ad72017-08-03 17:14:08 -04004548void draw(SkCanvas* canvas) {
4549 uint8_t pixels[][8] = { { 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00},
4550 { 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00},
4551 { 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00},
4552 { 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF},
4553 { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
4554 { 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00},
4555 { 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00},
4556 { 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00} };
4557 SkBitmap bitmap;
Herb Derbyefe39bc2018-05-01 17:06:20 -04004558 bitmap.installPixels(SkImageInfo::MakeA8(8, 8),
Cary Clarkbad5ad72017-08-03 17:14:08 -04004559 (void*) pixels, sizeof(pixels[0]));
4560 SkPaint paint;
Cary Clark681287e2018-03-16 11:34:15 -04004561 paint.setMaskFilter(SkMaskFilter::MakeBlur(kSolid_SkBlurStyle, 6));
Cary Clarkbad5ad72017-08-03 17:14:08 -04004562 for (auto color : { SK_ColorRED, SK_ColorBLUE, 0xFF007F00} ) {
4563 paint.setColor(color);
4564 canvas->drawBitmapRect(bitmap, SkRect::MakeWH(8, 8), SkRect::MakeWH(32, 32), &paint);
4565 canvas->translate(48, 0);
4566 }
Cary Clark8032b982017-07-28 11:04:54 -04004567}
4568##
4569
Cary Clark2ade9972017-11-02 17:49:34 -04004570#SeeAlso drawImageRect drawBitmap drawBitmapLattice drawBitmapNine
Cary Clark8032b982017-07-28 11:04:54 -04004571
4572##
4573
4574# ------------------------------------------------------------------------------
4575
4576#Method void drawBitmapRect(const SkBitmap& bitmap, const SkIRect& isrc, const SkRect& dst,
4577 const SkPaint* paint, SrcRectConstraint constraint = kStrict_SrcRectConstraint)
Cary Clarkab2621d2018-01-30 10:08:57 -05004578#In Draw_Image
Cary Clark78de7512018-02-07 07:27:09 -05004579#In Draw
Cary Clark8032b982017-07-28 11:04:54 -04004580Draw IRect isrc of Bitmap bitmap, scaled and translated to fill Rect dst.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004581isrc is on integer pixel boundaries; dst may include fractional boundaries.
Cary Clark8032b982017-07-28 11:04:54 -04004582Additionally transform draw using Clip, Matrix, and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004583
Cary Clarkbad5ad72017-08-03 17:14:08 -04004584If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4585Blend_Mode, and Draw_Looper. If bitmap is kAlpha_8_SkColorType, apply Shader.
4586If paint contains Mask_Filter, generate mask from bitmap bounds.
4587
4588If generated mask extends beyond bitmap bounds, replicate bitmap edge colors,
4589just as Shader made from SkShader::MakeBitmapShader with
Cary Clarkbc5697d2017-10-04 14:31:33 -04004590SkShader::kClamp_TileMode set replicates the bitmap edge color when it samples
Cary Clarkbad5ad72017-08-03 17:14:08 -04004591outside of its bounds.
4592
4593constraint set to kStrict_SrcRectConstraint limits Paint Filter_Quality to
Cary Clarkce101242017-09-01 15:51:02 -04004594sample within isrc; set to kFast_SrcRectConstraint allows sampling outside to
Cary Clarkbad5ad72017-08-03 17:14:08 -04004595improve performance.
4596
4597#Param bitmap Bitmap containing pixels, dimensions, and format ##
4598#Param isrc source IRect of image to draw from ##
4599#Param dst destination Rect of image to draw to ##
4600#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4601 and so on; or nullptr
4602##
Cary Clarkce101242017-09-01 15:51:02 -04004603#Param constraint sample strictly within isrc, or draw faster ##
Cary Clark8032b982017-07-28 11:04:54 -04004604
4605#Example
4606#Height 64
Cary Clarkbad5ad72017-08-03 17:14:08 -04004607void draw(SkCanvas* canvas) {
4608 uint8_t pixels[][8] = { { 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00},
4609 { 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00},
4610 { 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0xFF},
4611 { 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0xFF},
4612 { 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF},
4613 { 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF},
4614 { 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00},
4615 { 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00} };
4616 SkBitmap bitmap;
Herb Derbyefe39bc2018-05-01 17:06:20 -04004617 bitmap.installPixels(SkImageInfo::MakeA8(8, 8),
Cary Clarkbad5ad72017-08-03 17:14:08 -04004618 (void*) pixels, sizeof(pixels[0]));
4619 SkPaint paint;
4620 paint.setFilterQuality(kHigh_SkFilterQuality);
4621 for (auto color : { SK_ColorRED, SK_ColorBLUE, 0xFF007F00, 0xFF7f007f} ) {
4622 paint.setColor(color);
4623 canvas->drawBitmapRect(bitmap, SkIRect::MakeWH(8, 8), SkRect::MakeWH(32, 32), &paint);
4624 canvas->translate(48.25f, 0);
4625 }
Cary Clark8032b982017-07-28 11:04:54 -04004626}
4627##
4628
Cary Clark2ade9972017-11-02 17:49:34 -04004629#SeeAlso drawImageRect drawBitmap drawBitmapLattice drawBitmapNine
Cary Clark8032b982017-07-28 11:04:54 -04004630
4631##
4632
4633# ------------------------------------------------------------------------------
4634
4635#Method void drawBitmapRect(const SkBitmap& bitmap, const SkRect& dst, const SkPaint* paint,
4636 SrcRectConstraint constraint = kStrict_SrcRectConstraint)
Cary Clarkab2621d2018-01-30 10:08:57 -05004637#In Draw_Image
Cary Clark78de7512018-02-07 07:27:09 -05004638#In Draw
Cary Clark8032b982017-07-28 11:04:54 -04004639Draw Bitmap bitmap, scaled and translated to fill Rect dst.
Cary Clarkce101242017-09-01 15:51:02 -04004640bitmap bounds is on integer pixel boundaries; dst may include fractional boundaries.
Cary Clark8032b982017-07-28 11:04:54 -04004641Additionally transform draw using Clip, Matrix, and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004642
Cary Clarkbad5ad72017-08-03 17:14:08 -04004643If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4644Blend_Mode, and Draw_Looper. If bitmap is kAlpha_8_SkColorType, apply Shader.
4645If paint contains Mask_Filter, generate mask from bitmap bounds.
4646
4647If generated mask extends beyond bitmap bounds, replicate bitmap edge colors,
4648just as Shader made from SkShader::MakeBitmapShader with
Cary Clarkbc5697d2017-10-04 14:31:33 -04004649SkShader::kClamp_TileMode set replicates the bitmap edge color when it samples
Cary Clarkbad5ad72017-08-03 17:14:08 -04004650outside of its bounds.
4651
4652constraint set to kStrict_SrcRectConstraint limits Paint Filter_Quality to
Cary Clarkce101242017-09-01 15:51:02 -04004653sample within bitmap; set to kFast_SrcRectConstraint allows sampling outside to
Cary Clarkbad5ad72017-08-03 17:14:08 -04004654improve performance.
4655
4656#Param bitmap Bitmap containing pixels, dimensions, and format ##
4657#Param dst destination Rect of image to draw to ##
4658#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4659 and so on; or nullptr
4660##
Cary Clarkce101242017-09-01 15:51:02 -04004661#Param constraint filter strictly within bitmap or draw faster ##
Cary Clark8032b982017-07-28 11:04:54 -04004662
4663#Example
4664#Height 64
Cary Clarkbad5ad72017-08-03 17:14:08 -04004665void draw(SkCanvas* canvas) {
4666 uint32_t pixels[][2] = { { 0x00000000, 0x55550000},
4667 { 0xAAAA0000, 0xFFFF0000} };
4668 SkBitmap bitmap;
Herb Derbyefe39bc2018-05-01 17:06:20 -04004669 bitmap.installPixels(SkImageInfo::MakeN32Premul(2, 2),
Cary Clarkbad5ad72017-08-03 17:14:08 -04004670 (void*) pixels, sizeof(pixels[0]));
4671 SkPaint paint;
4672 canvas->scale(4, 4);
4673 for (auto color : { SK_ColorRED, SK_ColorBLUE, SK_ColorGREEN } ) {
4674 paint.setColorFilter(SkColorFilter::MakeModeFilter(color, SkBlendMode::kPlus));
4675 canvas->drawBitmapRect(bitmap, SkRect::MakeWH(8, 8), &paint);
4676 canvas->translate(8, 0);
4677 }
Cary Clark8032b982017-07-28 11:04:54 -04004678}
4679##
4680
Cary Clark2ade9972017-11-02 17:49:34 -04004681#SeeAlso drawImageRect drawBitmap drawBitmapLattice drawBitmapNine
Cary Clark8032b982017-07-28 11:04:54 -04004682
4683##
4684
4685# ------------------------------------------------------------------------------
4686
Cary Clark682c58d2018-05-16 07:07:07 -04004687#PhraseDef paint_as_used_by_draw_lattice_or_draw_nine(bitmap_or_image)
4688If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4689Blend_Mode, and Draw_Looper. If #bitmap_or_image# is kAlpha_8_SkColorType, apply Shader.
4690If paint contains Mask_Filter, generate mask from #bitmap_or_image# bounds. If paint
4691Filter_Quality set to kNone_SkFilterQuality, disable pixel filtering. For all
4692other values of paint Filter_Quality, use kLow_SkFilterQuality to filter pixels.
Brian Salomon969be1c2018-05-21 14:37:49 -04004693Any SkMaskFilter on the paint is ignored as is the paint's antialiasing state.
Cary Clark682c58d2018-05-16 07:07:07 -04004694##
4695
Cary Clark8032b982017-07-28 11:04:54 -04004696#Method void drawBitmapNine(const SkBitmap& bitmap, const SkIRect& center, const SkRect& dst,
Cary Clark73fa9722017-08-29 17:36:51 -04004697 const SkPaint* paint = nullptr)
Cary Clarkab2621d2018-01-30 10:08:57 -05004698#In Draw_Image
Cary Clark78de7512018-02-07 07:27:09 -05004699#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05004700#Line # draws Nine_Patch Bitmap ##
Cary Clark8032b982017-07-28 11:04:54 -04004701
Cary Clarkd0530ba2017-09-14 11:25:39 -04004702Draw Bitmap bitmap stretched proportionally to fit into Rect dst.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004703IRect center divides the bitmap into nine sections: four sides, four corners,
Cary Clarkce101242017-09-01 15:51:02 -04004704and the center. Corners are not scaled, or scaled down proportionately if their
Cary Clarkbad5ad72017-08-03 17:14:08 -04004705sides are larger than dst; center and four sides are scaled to fit remaining
4706space, if any.
Cary Clark8032b982017-07-28 11:04:54 -04004707
Cary Clarkbad5ad72017-08-03 17:14:08 -04004708Additionally transform draw using Clip, Matrix, and optional Paint paint.
4709
Cary Clark682c58d2018-05-16 07:07:07 -04004710#paint_as_used_by_draw_lattice_or_draw_nine(bitmap)#
Cary Clarkbad5ad72017-08-03 17:14:08 -04004711
4712If generated mask extends beyond bitmap bounds, replicate bitmap edge colors,
4713just as Shader made from SkShader::MakeBitmapShader with
Cary Clarkbc5697d2017-10-04 14:31:33 -04004714SkShader::kClamp_TileMode set replicates the bitmap edge color when it samples
Cary Clarkbad5ad72017-08-03 17:14:08 -04004715outside of its bounds.
4716
4717#Param bitmap Bitmap containing pixels, dimensions, and format ##
4718#Param center IRect edge of image corners and sides ##
4719#Param dst destination Rect of image to draw to ##
4720#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4721 and so on; or nullptr
4722##
Cary Clark8032b982017-07-28 11:04:54 -04004723
4724#Example
4725#Height 128
4726#Description
4727 The two leftmost bitmap draws has four corners and sides to the left and right of center.
4728 The leftmost bitmap draw scales the width of corners proportionately to fit.
Herb Derbyefe39bc2018-05-01 17:06:20 -04004729 The third and fourth draw corners are not scaled; the sides and center are scaled to
Cary Clark8032b982017-07-28 11:04:54 -04004730 fill the remaining space.
4731 The rightmost bitmap draw has four corners scaled vertically to fit, and uses sides above
4732 and below center to fill the remaining space.
4733##
Cary Clarkbad5ad72017-08-03 17:14:08 -04004734void draw(SkCanvas* canvas) {
4735 SkIRect center = { 20, 10, 50, 40 };
4736 SkBitmap bitmap;
4737 bitmap.allocPixels(SkImageInfo::MakeN32Premul(60, 60));
4738 SkCanvas bitCanvas(bitmap);
4739 SkPaint paint;
4740 SkColor gray = 0xFF000000;
4741 int left = 0;
4742 for (auto right: { center.fLeft, center.fRight, bitmap.width() } ) {
4743 int top = 0;
4744 for (auto bottom: { center.fTop, center.fBottom, bitmap.height() } ) {
4745 paint.setColor(gray);
4746 bitCanvas.drawIRect(SkIRect::MakeLTRB(left, top, right, bottom), paint);
4747 gray += 0x001f1f1f;
4748 top = bottom;
4749 }
Herb Derbyefe39bc2018-05-01 17:06:20 -04004750 left = right;
Cary Clarkbad5ad72017-08-03 17:14:08 -04004751 }
4752 for (auto dest: { 20, 30, 40, 60, 90 } ) {
4753 canvas->drawBitmapNine(bitmap, center, SkRect::MakeWH(dest, 110 - dest), nullptr);
4754 canvas->translate(dest + 4, 0);
4755 }
Cary Clark8032b982017-07-28 11:04:54 -04004756}
4757##
4758
Cary Clark2ade9972017-11-02 17:49:34 -04004759#SeeAlso drawImageNine drawBitmap drawBitmapLattice drawBitmapRect
Cary Clark8032b982017-07-28 11:04:54 -04004760
4761##
4762
4763# ------------------------------------------------------------------------------
Cary Clark682c58d2018-05-16 07:07:07 -04004764#Subtopic Lattice
4765#Line # divides Bitmap or Image into a rectangular grid ##
4766
Cary Clark8032b982017-07-28 11:04:54 -04004767#Struct Lattice
Cary Clark08895c42018-02-01 09:37:32 -05004768#Line # divides Bitmap or Image into a rectangular grid ##
Cary Clark682c58d2018-05-16 07:07:07 -04004769
4770Lattice divides Bitmap or Image into a rectangular grid.
4771Grid entries on even columns and even rows are fixed; these entries are
4772always drawn at their original size if the destination is large enough.
4773If the destination side is too small to hold the fixed entries, all fixed
4774entries are proportionately scaled down to fit.
4775The grid entries not on even columns and rows are scaled to fit the
4776remaining space, if any.
4777
Cary Clark8032b982017-07-28 11:04:54 -04004778#Code
4779 struct Lattice {
Cary Clark2f466242017-12-11 16:03:17 -05004780 enum RectType ...
Cary Clark8032b982017-07-28 11:04:54 -04004781
Cary Clark2f466242017-12-11 16:03:17 -05004782 const int* fXDivs;
4783 const int* fYDivs;
4784 const RectType* fRectTypes;
4785 int fXCount;
4786 int fYCount;
4787 const SkIRect* fBounds;
4788 const SkColor* fColors;
Cary Clark8032b982017-07-28 11:04:54 -04004789 };
4790##
4791
Cary Clark682c58d2018-05-16 07:07:07 -04004792#Subtopic Overview
4793#Populate
4794##
4795
4796#Subtopic Constant
4797#Populate
4798##
Cary Clark154beea2017-10-26 07:58:48 -04004799
Cary Clark2f466242017-12-11 16:03:17 -05004800 #Enum RectType
Cary Clark682c58d2018-05-16 07:07:07 -04004801 #Line # optional setting per rectangular grid entry ##
Cary Clark8032b982017-07-28 11:04:54 -04004802 #Code
Cary Clark2f466242017-12-11 16:03:17 -05004803 enum RectType : uint8_t {
4804 kDefault = 0,
4805 kTransparent,
4806 kFixedColor,
Cary Clark8032b982017-07-28 11:04:54 -04004807 };
4808 ##
4809
Cary Clark2f466242017-12-11 16:03:17 -05004810 Optional setting per rectangular grid entry to make it transparent,
4811 or to fill the grid entry with a color.
Cary Clark8032b982017-07-28 11:04:54 -04004812
Cary Clark2f466242017-12-11 16:03:17 -05004813 #Const kDefault 0
Cary Clark682c58d2018-05-16 07:07:07 -04004814 #Line # draws Bitmap into lattice rectangle ##
Cary Clark2f466242017-12-11 16:03:17 -05004815 ##
4816
4817 #Const kTransparent 1
Cary Clark682c58d2018-05-16 07:07:07 -04004818 #Line # skips lattice rectangle by making it transparent ##
Cary Clark2f466242017-12-11 16:03:17 -05004819 ##
4820
4821 #Const kFixedColor 2
Cary Clark682c58d2018-05-16 07:07:07 -04004822 #Line # draws one of fColors into lattice rectangle ##
Cary Clark8032b982017-07-28 11:04:54 -04004823 ##
4824 ##
4825
Cary Clark682c58d2018-05-16 07:07:07 -04004826#Subtopic Member
4827#Populate
4828##
4829
Cary Clark8032b982017-07-28 11:04:54 -04004830 #Member const int* fXDivs
Cary Clark682c58d2018-05-16 07:07:07 -04004831 #Line # x-coordinates dividing bitmap ##
Cary Clark8032b982017-07-28 11:04:54 -04004832 Array of x-coordinates that divide the bitmap vertically.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004833 Array entries must be unique, increasing, greater than or equal to
4834 fBounds left edge, and less than fBounds right edge.
4835 Set the first element to fBounds left to collapse the left column of
4836 fixed grid entries.
Cary Clark8032b982017-07-28 11:04:54 -04004837 ##
4838
4839 #Member const int* fYDivs
Cary Clark682c58d2018-05-16 07:07:07 -04004840 #Line # y-coordinates dividing bitmap ##
Cary Clark8032b982017-07-28 11:04:54 -04004841 Array of y-coordinates that divide the bitmap horizontally.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004842 Array entries must be unique, increasing, greater than or equal to
4843 fBounds top edge, and less than fBounds bottom edge.
4844 Set the first element to fBounds top to collapse the top row of fixed
4845 grid entries.
Cary Clark8032b982017-07-28 11:04:54 -04004846 ##
4847
Cary Clark2f466242017-12-11 16:03:17 -05004848 #Member const RectType* fRectTypes
Cary Clark682c58d2018-05-16 07:07:07 -04004849 #Line # array of fill types ##
Cary Clark2f466242017-12-11 16:03:17 -05004850 Optional array of fill types, one per rectangular grid entry:
Cary Clarkbad5ad72017-08-03 17:14:08 -04004851 array length must be
4852 #Formula
4853 (fXCount + 1) * (fYCount + 1)
4854 ##
4855 .
Cary Clark6fc50412017-09-21 12:31:06 -04004856
Cary Clark2f466242017-12-11 16:03:17 -05004857 Each RectType is one of: kDefault, kTransparent, kFixedColor.
4858
Cary Clark8032b982017-07-28 11:04:54 -04004859 Array entries correspond to the rectangular grid entries, ascending
4860 left to right and then top to bottom.
4861 ##
4862
4863 #Member int fXCount
Cary Clark682c58d2018-05-16 07:07:07 -04004864 #Line # number of x-coordinates ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04004865 Number of entries in fXDivs array; one less than the number of
4866 horizontal divisions.
Cary Clark8032b982017-07-28 11:04:54 -04004867 ##
4868
4869 #Member int fYCount
Cary Clark682c58d2018-05-16 07:07:07 -04004870 #Line # number of y-coordinates ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04004871 Number of entries in fYDivs array; one less than the number of vertical
4872 divisions.
Cary Clark8032b982017-07-28 11:04:54 -04004873 ##
4874
4875 #Member const SkIRect* fBounds
Cary Clark682c58d2018-05-16 07:07:07 -04004876 #Line # source bounds to draw from ##
Cary Clark8032b982017-07-28 11:04:54 -04004877 Optional subset IRect source to draw from.
4878 If nullptr, source bounds is dimensions of Bitmap or Image.
4879 ##
4880
Cary Clark2f466242017-12-11 16:03:17 -05004881 #Member const SkColor* fColors
Cary Clark682c58d2018-05-16 07:07:07 -04004882 #Line # array of colors ##
Cary Clark2f466242017-12-11 16:03:17 -05004883 Optional array of colors, one per rectangular grid entry.
4884 Array length must be
4885 #Formula
4886 (fXCount + 1) * (fYCount + 1)
4887 ##
4888 .
4889
4890 Array entries correspond to the rectangular grid entries, ascending
4891 left to right, then top to bottom.
4892 ##
4893
Cary Clark8032b982017-07-28 11:04:54 -04004894#Struct Lattice ##
4895
4896#Method void drawBitmapLattice(const SkBitmap& bitmap, const Lattice& lattice, const SkRect& dst,
4897 const SkPaint* paint = nullptr)
Cary Clarkab2621d2018-01-30 10:08:57 -05004898#In Draw_Image
Cary Clark78de7512018-02-07 07:27:09 -05004899#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05004900#Line # draws proportionally stretched Bitmap ##
Cary Clark8032b982017-07-28 11:04:54 -04004901
Cary Clarkd0530ba2017-09-14 11:25:39 -04004902Draw Bitmap bitmap stretched proportionally to fit into Rect dst.
Cary Clark8032b982017-07-28 11:04:54 -04004903
4904Lattice lattice divides bitmap into a rectangular grid.
4905Each intersection of an even-numbered row and column is fixed; like the corners
Cary Clarkbad5ad72017-08-03 17:14:08 -04004906of drawBitmapNine, fixed lattice elements never scale larger than their initial
Cary Clarkbc5697d2017-10-04 14:31:33 -04004907size and shrink proportionately when all fixed elements exceed the bitmap
Cary Clarkbad5ad72017-08-03 17:14:08 -04004908dimension. All other grid elements scale to fill the available space, if any.
Cary Clark8032b982017-07-28 11:04:54 -04004909
4910Additionally transform draw using Clip, Matrix, and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004911
Cary Clark682c58d2018-05-16 07:07:07 -04004912#paint_as_used_by_draw_lattice_or_draw_nine(bitmap)#
Cary Clarkbad5ad72017-08-03 17:14:08 -04004913
4914If generated mask extends beyond bitmap bounds, replicate bitmap edge colors,
4915just as Shader made from SkShader::MakeBitmapShader with
Cary Clarkbc5697d2017-10-04 14:31:33 -04004916SkShader::kClamp_TileMode set replicates the bitmap edge color when it samples
Cary Clarkbad5ad72017-08-03 17:14:08 -04004917outside of its bounds.
4918
4919#Param bitmap Bitmap containing pixels, dimensions, and format ##
4920#Param lattice division of bitmap into fixed and variable rectangles ##
4921#Param dst destination Rect of image to draw to ##
4922#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4923 and so on; or nullptr
4924##
Cary Clark8032b982017-07-28 11:04:54 -04004925
4926#Example
4927#Height 128
4928#Description
4929 The two leftmost bitmap draws has four corners and sides to the left and right of center.
4930 The leftmost bitmap draw scales the width of corners proportionately to fit.
Herb Derbyefe39bc2018-05-01 17:06:20 -04004931 The third and fourth draw corners are not scaled; the sides are scaled to
Cary Clark8032b982017-07-28 11:04:54 -04004932 fill the remaining space; the center is transparent.
4933 The rightmost bitmap draw has four corners scaled vertically to fit, and uses sides above
4934 and below center to fill the remaining space.
4935##
Cary Clarkbad5ad72017-08-03 17:14:08 -04004936void draw(SkCanvas* canvas) {
4937 SkIRect center = { 20, 10, 50, 40 };
4938 SkBitmap bitmap;
4939 bitmap.allocPixels(SkImageInfo::MakeN32Premul(60, 60));
4940 SkCanvas bitCanvas(bitmap);
4941 SkPaint paint;
4942 SkColor gray = 0xFF000000;
4943 int left = 0;
4944 for (auto right: { center.fLeft, center.fRight, bitmap.width() } ) {
4945 int top = 0;
4946 for (auto bottom: { center.fTop, center.fBottom, bitmap.height() } ) {
4947 paint.setColor(gray);
4948 bitCanvas.drawIRect(SkIRect::MakeLTRB(left, top, right, bottom), paint);
4949 gray += 0x001f1f1f;
4950 top = bottom;
4951 }
Herb Derbyefe39bc2018-05-01 17:06:20 -04004952 left = right;
Cary Clarkbad5ad72017-08-03 17:14:08 -04004953 }
4954 const int xDivs[] = { center.fLeft, center.fRight };
4955 const int yDivs[] = { center.fTop, center.fBottom };
Cary Clarkca3ebcd2017-12-12 11:22:38 -05004956 SkCanvas::Lattice::RectType fillTypes[3][3];
4957 memset(fillTypes, 0, sizeof(fillTypes));
4958 fillTypes[1][1] = SkCanvas::Lattice::kTransparent;
4959 SkColor dummy[9]; // temporary pending bug fix
4960 SkCanvas::Lattice lattice = { xDivs, yDivs, fillTypes[0], SK_ARRAY_COUNT(xDivs),
4961 SK_ARRAY_COUNT(yDivs), nullptr, dummy };
Cary Clarkbad5ad72017-08-03 17:14:08 -04004962 for (auto dest: { 20, 30, 40, 60, 90 } ) {
Cary Clarkca3ebcd2017-12-12 11:22:38 -05004963 canvas->drawBitmapLattice(bitmap, lattice, SkRect::MakeWH(dest, 110 - dest), nullptr);
Cary Clarkbad5ad72017-08-03 17:14:08 -04004964 canvas->translate(dest + 4, 0);
4965 }
Cary Clark8032b982017-07-28 11:04:54 -04004966}
4967##
4968
Cary Clark2ade9972017-11-02 17:49:34 -04004969#SeeAlso drawImageLattice drawBitmap drawBitmapNine Lattice
Cary Clark8032b982017-07-28 11:04:54 -04004970
4971##
4972
4973# ------------------------------------------------------------------------------
4974
4975#Method void drawImageLattice(const SkImage* image, const Lattice& lattice, const SkRect& dst,
4976 const SkPaint* paint = nullptr)
Cary Clarkab2621d2018-01-30 10:08:57 -05004977#In Draw_Image
Cary Clark78de7512018-02-07 07:27:09 -05004978#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05004979#Line # draws proportionally stretched Image ##
Cary Clark8032b982017-07-28 11:04:54 -04004980
Cary Clarkd0530ba2017-09-14 11:25:39 -04004981Draw Image image stretched proportionally to fit into Rect dst.
Cary Clark8032b982017-07-28 11:04:54 -04004982
4983Lattice lattice divides image into a rectangular grid.
4984Each intersection of an even-numbered row and column is fixed; like the corners
Cary Clarkbad5ad72017-08-03 17:14:08 -04004985of drawBitmapNine, fixed lattice elements never scale larger than their initial
Cary Clarkbc5697d2017-10-04 14:31:33 -04004986size and shrink proportionately when all fixed elements exceed the bitmap
Cary Clarkbad5ad72017-08-03 17:14:08 -04004987dimension. All other grid elements scale to fill the available space, if any.
Cary Clark8032b982017-07-28 11:04:54 -04004988
4989Additionally transform draw using Clip, Matrix, and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004990
Cary Clark682c58d2018-05-16 07:07:07 -04004991#paint_as_used_by_draw_lattice_or_draw_nine(image)#
Cary Clarkbad5ad72017-08-03 17:14:08 -04004992
4993If generated mask extends beyond bitmap bounds, replicate bitmap edge colors,
4994just as Shader made from SkShader::MakeBitmapShader with
Cary Clarkbc5697d2017-10-04 14:31:33 -04004995SkShader::kClamp_TileMode set replicates the bitmap edge color when it samples
Cary Clarkbad5ad72017-08-03 17:14:08 -04004996outside of its bounds.
4997
4998#Param image Image containing pixels, dimensions, and format ##
4999#Param lattice division of bitmap into fixed and variable rectangles ##
5000#Param dst destination Rect of image to draw to ##
5001#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
5002 and so on; or nullptr
5003##
Cary Clark8032b982017-07-28 11:04:54 -04005004
5005#Example
5006#Height 128
5007#Description
5008 The leftmost image is smaller than center; only corners are drawn, all scaled to fit.
Cary Clarkce101242017-09-01 15:51:02 -04005009 The second image equals the size of center; only corners are drawn without scaling.
5010 The remaining images are larger than center. All corners draw without scaling. The sides
Cary Clark8032b982017-07-28 11:04:54 -04005011 are scaled if needed to take up the remaining space; the center is transparent.
5012##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005013void draw(SkCanvas* canvas) {
5014 SkIRect center = { 20, 10, 50, 40 };
5015 SkBitmap bitmap;
5016 bitmap.allocPixels(SkImageInfo::MakeN32Premul(60, 60));
5017 SkCanvas bitCanvas(bitmap);
5018 SkPaint paint;
5019 SkColor gray = 0xFF000000;
5020 int left = 0;
5021 for (auto right: { center.fLeft, center.fRight, bitmap.width() } ) {
5022 int top = 0;
5023 for (auto bottom: { center.fTop, center.fBottom, bitmap.height() } ) {
5024 paint.setColor(gray);
5025 bitCanvas.drawIRect(SkIRect::MakeLTRB(left, top, right, bottom), paint);
5026 gray += 0x001f1f1f;
5027 top = bottom;
5028 }
Herb Derbyefe39bc2018-05-01 17:06:20 -04005029 left = right;
Cary Clarkbad5ad72017-08-03 17:14:08 -04005030 }
Cary Clarkbad5ad72017-08-03 17:14:08 -04005031 sk_sp<SkImage> image = SkImage::MakeFromBitmap(bitmap);
5032 SkImage* imagePtr = image.get();
5033 for (auto dest: { 20, 30, 40, 60, 90 } ) {
5034 canvas->drawImageNine(imagePtr, center, SkRect::MakeWH(dest, dest), nullptr);
5035 canvas->translate(dest + 4, 0);
5036 }
Cary Clark8032b982017-07-28 11:04:54 -04005037}
5038##
5039
Cary Clark2ade9972017-11-02 17:49:34 -04005040#SeeAlso drawBitmapLattice drawImage drawImageNine Lattice
Cary Clark8032b982017-07-28 11:04:54 -04005041
5042##
5043
Cary Clark682c58d2018-05-16 07:07:07 -04005044#Subtopic Lattice ##
5045
Cary Clark08895c42018-02-01 09:37:32 -05005046#Subtopic Draw_Image ##
Cary Clark8032b982017-07-28 11:04:54 -04005047
5048# ------------------------------------------------------------------------------
Cary Clark78de7512018-02-07 07:27:09 -05005049#Subtopic Draw_Text
5050#Populate
5051#Line # draws text into Canvas ##
5052##
Cary Clark8032b982017-07-28 11:04:54 -04005053
5054#Method void drawText(const void* text, size_t byteLength, SkScalar x, SkScalar y,
5055 const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05005056#In Draw_Text
5057#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05005058#Line # draws text at (x, y), using font advance ##
Cary Clark8032b982017-07-28 11:04:54 -04005059
5060Draw text, with origin at (x, y), using Clip, Matrix, and Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04005061
Cary Clarkbc5697d2017-10-04 14:31:33 -04005062text meaning depends on Paint_Text_Encoding; by default, text is encoded as
Cary Clarkbad5ad72017-08-03 17:14:08 -04005063UTF-8.
Cary Clark8032b982017-07-28 11:04:54 -04005064
Cary Clarkbad5ad72017-08-03 17:14:08 -04005065x and y meaning depends on Paint_Text_Align and Paint_Vertical_Text; by default
Cary Clarkbc5697d2017-10-04 14:31:33 -04005066text draws left to right, positioning the first glyph left side bearing at x
Herb Derbyefe39bc2018-05-01 17:06:20 -04005067and its baseline at y. Text size is affected by Matrix and Paint_Text_Size.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005068
Mike Reed8ad91a92018-01-19 19:09:32 -05005069All elements of paint: Path_Effect, Mask_Filter, Shader,
Cary Clarkbad5ad72017-08-03 17:14:08 -04005070Color_Filter, Image_Filter, and Draw_Looper; apply to text. By default, draws
Cary Clarkce101242017-09-01 15:51:02 -04005071filled 12 point black Glyphs.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005072
Cary Clarkce101242017-09-01 15:51:02 -04005073#Param text character code points or Glyphs drawn ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005074#Param byteLength byte length of text array ##
5075#Param x start of text on x-axis ##
5076#Param y start of text on y-axis ##
5077#Param paint text size, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005078
5079#Example
5080#Height 200
5081#Description
5082 The same text is drawn varying Paint_Text_Size and varying
Herb Derbyefe39bc2018-05-01 17:06:20 -04005083 Matrix.
Cary Clark8032b982017-07-28 11:04:54 -04005084##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005085void draw(SkCanvas* canvas) {
5086 SkPaint paint;
5087 paint.setAntiAlias(true);
5088 float textSizes[] = { 12, 18, 24, 36 };
5089 for (auto size: textSizes ) {
5090 paint.setTextSize(size);
5091 canvas->drawText("Aa", 2, 10, 20, paint);
5092 canvas->translate(0, size * 2);
5093 }
5094 paint.reset();
5095 paint.setAntiAlias(true);
5096 float yPos = 20;
5097 for (auto size: textSizes ) {
5098 float scale = size / 12.f;
5099 canvas->resetMatrix();
5100 canvas->translate(100, 0);
5101 canvas->scale(scale, scale);
5102 canvas->drawText("Aa", 2, 10 / scale, yPos / scale, paint);
Herb Derbyefe39bc2018-05-01 17:06:20 -04005103 yPos += size * 2;
Cary Clarkbad5ad72017-08-03 17:14:08 -04005104 }
5105}
Cary Clark8032b982017-07-28 11:04:54 -04005106##
5107
Cary Clark2ade9972017-11-02 17:49:34 -04005108#SeeAlso drawString drawPosText drawPosTextH drawTextBlob drawTextOnPath drawTextRSXform
Cary Clark8032b982017-07-28 11:04:54 -04005109
5110##
5111
5112#Method void drawString(const char* string, SkScalar x, SkScalar y, const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05005113#In Draw_Text
5114#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05005115#Line # draws null terminated string at (x, y) using font advance ##
Cary Clark682c58d2018-05-16 07:07:07 -04005116Draws null terminated string, with origin at (x, y), using Clip, Matrix, and
5117Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04005118
Cary Clarkbc5697d2017-10-04 14:31:33 -04005119string meaning depends on Paint_Text_Encoding; by default, strings are encoded
5120as UTF-8. Other values of Paint_Text_Encoding are unlikely to produce the desired
Cary Clarkbad5ad72017-08-03 17:14:08 -04005121results, since zero bytes may be embedded in the string.
Cary Clark8032b982017-07-28 11:04:54 -04005122
Cary Clarkbad5ad72017-08-03 17:14:08 -04005123x and y meaning depends on Paint_Text_Align and Paint_Vertical_Text; by default
Cary Clarkbc5697d2017-10-04 14:31:33 -04005124string draws left to right, positioning the first glyph left side bearing at x
Herb Derbyefe39bc2018-05-01 17:06:20 -04005125and its baseline at y. Text size is affected by Matrix and Paint_Text_Size.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005126
Mike Reed8ad91a92018-01-19 19:09:32 -05005127All elements of paint: Path_Effect, Mask_Filter, Shader,
Cary Clarkbad5ad72017-08-03 17:14:08 -04005128Color_Filter, Image_Filter, and Draw_Looper; apply to text. By default, draws
Cary Clarkce101242017-09-01 15:51:02 -04005129filled 12 point black Glyphs.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005130
Cary Clarkce101242017-09-01 15:51:02 -04005131#Param string character code points or Glyphs drawn,
Cary Clarkbad5ad72017-08-03 17:14:08 -04005132 ending with a char value of zero
5133##
5134#Param x start of string on x-axis ##
5135#Param y start of string on y-axis ##
5136#Param paint text size, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005137
5138#Example
Cary Clarkffb3d682018-05-17 12:17:28 -04005139#Height 48
Cary Clark8032b982017-07-28 11:04:54 -04005140 SkPaint paint;
5141 canvas->drawString("a small hello", 20, 20, paint);
5142##
5143
Cary Clark2ade9972017-11-02 17:49:34 -04005144#SeeAlso drawText drawPosText drawPosTextH drawTextBlob drawTextOnPath drawTextRSXform
Cary Clark8032b982017-07-28 11:04:54 -04005145
5146##
5147
5148#Method void drawString(const SkString& string, SkScalar x, SkScalar y, const SkPaint& paint)
5149
Cary Clarkbad5ad72017-08-03 17:14:08 -04005150Draw null terminated string, with origin at (x, y), using Clip, Matrix, and
5151Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04005152
Cary Clarkbc5697d2017-10-04 14:31:33 -04005153string meaning depends on Paint_Text_Encoding; by default, strings are encoded
5154as UTF-8. Other values of Paint_Text_Encoding are unlikely to produce the desired
Cary Clarkbad5ad72017-08-03 17:14:08 -04005155results, since zero bytes may be embedded in the string.
Cary Clark8032b982017-07-28 11:04:54 -04005156
Cary Clarkbad5ad72017-08-03 17:14:08 -04005157x and y meaning depends on Paint_Text_Align and Paint_Vertical_Text; by default
Cary Clarkbc5697d2017-10-04 14:31:33 -04005158string draws left to right, positioning the first glyph left side bearing at x
Herb Derbyefe39bc2018-05-01 17:06:20 -04005159and its baseline at y. Text size is affected by Matrix and Paint_Text_Size.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005160
Mike Reed8ad91a92018-01-19 19:09:32 -05005161All elements of paint: Path_Effect, Mask_Filter, Shader,
Cary Clarkbad5ad72017-08-03 17:14:08 -04005162Color_Filter, Image_Filter, and Draw_Looper; apply to text. By default, draws
Cary Clarkce101242017-09-01 15:51:02 -04005163filled 12 point black Glyphs.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005164
Cary Clarkce101242017-09-01 15:51:02 -04005165#Param string character code points or Glyphs drawn,
Cary Clarkbad5ad72017-08-03 17:14:08 -04005166 ending with a char value of zero
5167##
5168#Param x start of string on x-axis ##
5169#Param y start of string on y-axis ##
5170#Param paint text size, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005171
5172#Example
5173 SkPaint paint;
5174 SkString string("a small hello");
5175 canvas->drawString(string, 20, 20, paint);
5176##
5177
Cary Clark2ade9972017-11-02 17:49:34 -04005178#SeeAlso drawText drawPosText drawPosTextH drawTextBlob drawTextOnPath drawTextRSXform
Cary Clark8032b982017-07-28 11:04:54 -04005179
5180##
5181
5182# ------------------------------------------------------------------------------
5183
5184#Method void drawPosText(const void* text, size_t byteLength, const SkPoint pos[],
5185 const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05005186#In Draw_Text
5187#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05005188#Line # draws text at array of (x, y) positions ##
Cary Clark8032b982017-07-28 11:04:54 -04005189
Cary Clarkbad5ad72017-08-03 17:14:08 -04005190Draw each glyph in text with the origin in pos array, using Clip, Matrix, and
Cary Clarkce101242017-09-01 15:51:02 -04005191Paint paint. The number of entries in pos array must match the number of Glyphs
Cary Clarkbad5ad72017-08-03 17:14:08 -04005192described by byteLength of text.
Cary Clark8032b982017-07-28 11:04:54 -04005193
Cary Clarkbc5697d2017-10-04 14:31:33 -04005194text meaning depends on Paint_Text_Encoding; by default, text is encoded as
Cary Clarkbad5ad72017-08-03 17:14:08 -04005195UTF-8. pos elements' meaning depends on Paint_Text_Align and Paint_Vertical_Text;
Cary Clarkbc5697d2017-10-04 14:31:33 -04005196by default each glyph left side bearing is positioned at x and its
Cary Clarkbad5ad72017-08-03 17:14:08 -04005197baseline is positioned at y. Text size is affected by Matrix and
Herb Derbyefe39bc2018-05-01 17:06:20 -04005198Paint_Text_Size.
Cary Clark8032b982017-07-28 11:04:54 -04005199
Mike Reed8ad91a92018-01-19 19:09:32 -05005200All elements of paint: Path_Effect, Mask_Filter, Shader,
Cary Clarkbad5ad72017-08-03 17:14:08 -04005201Color_Filter, Image_Filter, and Draw_Looper; apply to text. By default, draws
Cary Clarkce101242017-09-01 15:51:02 -04005202filled 12 point black Glyphs.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005203
5204Layout engines such as Harfbuzz typically position each glyph
Cary Clarkbc5697d2017-10-04 14:31:33 -04005205rather than using the font advance widths.
Cary Clark8032b982017-07-28 11:04:54 -04005206
Cary Clarkce101242017-09-01 15:51:02 -04005207#Param text character code points or Glyphs drawn ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005208#Param byteLength byte length of text array ##
5209#Param pos array of glyph origins ##
5210#Param paint text size, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005211
5212#Example
5213#Height 120
Cary Clarkbad5ad72017-08-03 17:14:08 -04005214void draw(SkCanvas* canvas) {
5215 const char hello[] = "HeLLo!";
5216 const SkPoint pos[] = { {40, 100}, {82, 95}, {115, 110}, {130, 95}, {145, 85},
5217 {172, 100} };
5218 SkPaint paint;
5219 paint.setTextSize(60);
5220 canvas->drawPosText(hello, strlen(hello), pos, paint);
Cary Clark8032b982017-07-28 11:04:54 -04005221}
5222##
5223
Cary Clark2ade9972017-11-02 17:49:34 -04005224#SeeAlso drawText drawPosTextH drawTextBlob drawTextOnPath drawTextRSXform
Cary Clark8032b982017-07-28 11:04:54 -04005225
5226##
5227
5228# ------------------------------------------------------------------------------
5229
5230#Method void drawPosTextH(const void* text, size_t byteLength, const SkScalar xpos[], SkScalar constY,
5231 const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05005232#In Draw_Text
5233#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05005234#Line # draws text at x positions with common baseline ##
Cary Clark8032b982017-07-28 11:04:54 -04005235
Cary Clarkbad5ad72017-08-03 17:14:08 -04005236Draw each glyph in text with its (x, y) origin composed from xpos array and
5237constY, using Clip, Matrix, and Paint paint. The number of entries in xpos array
Cary Clarkce101242017-09-01 15:51:02 -04005238must match the number of Glyphs described by byteLength of text.
Cary Clark8032b982017-07-28 11:04:54 -04005239
Cary Clarkbc5697d2017-10-04 14:31:33 -04005240text meaning depends on Paint_Text_Encoding; by default, text is encoded as
Cary Clarkce101242017-09-01 15:51:02 -04005241UTF-8. xpos elements' meaning depends on Paint_Text_Align and Paint_Vertical_Text;
Cary Clarkbc5697d2017-10-04 14:31:33 -04005242by default each glyph left side bearing is positioned at an xpos element and
Cary Clarkbad5ad72017-08-03 17:14:08 -04005243its baseline is positioned at constY. Text size is affected by Matrix and
Herb Derbyefe39bc2018-05-01 17:06:20 -04005244Paint_Text_Size.
Cary Clark8032b982017-07-28 11:04:54 -04005245
Mike Reed8ad91a92018-01-19 19:09:32 -05005246All elements of paint: Path_Effect, Mask_Filter, Shader,
Cary Clarkbad5ad72017-08-03 17:14:08 -04005247Color_Filter, Image_Filter, and Draw_Looper; apply to text. By default, draws
Cary Clarkce101242017-09-01 15:51:02 -04005248filled 12 point black Glyphs.
Cary Clark8032b982017-07-28 11:04:54 -04005249
Cary Clarkbad5ad72017-08-03 17:14:08 -04005250Layout engines such as Harfbuzz typically position each glyph
Cary Clarkbc5697d2017-10-04 14:31:33 -04005251rather than using the font advance widths if all Glyphs share the same
Cary Clarkbad5ad72017-08-03 17:14:08 -04005252baseline.
5253
Cary Clarkce101242017-09-01 15:51:02 -04005254#Param text character code points or Glyphs drawn ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005255#Param byteLength byte length of text array ##
5256#Param xpos array of x positions, used to position each glyph ##
5257#Param constY shared y coordinate for all of x positions ##
5258#Param paint text size, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005259
5260#Example
5261#Height 40
Cary Clarkbad5ad72017-08-03 17:14:08 -04005262 void draw(SkCanvas* canvas) {
5263 SkScalar xpos[] = { 20, 40, 80, 160 };
5264 SkPaint paint;
5265 canvas->drawPosTextH("XXXX", 4, xpos, 20, paint);
5266 }
Cary Clark8032b982017-07-28 11:04:54 -04005267##
5268
Cary Clark2ade9972017-11-02 17:49:34 -04005269#SeeAlso drawText drawPosText drawTextBlob drawTextOnPath drawTextRSXform
Cary Clark8032b982017-07-28 11:04:54 -04005270
5271##
5272
5273# ------------------------------------------------------------------------------
5274
5275#Method void drawTextOnPathHV(const void* text, size_t byteLength, const SkPath& path, SkScalar hOffset,
5276 SkScalar vOffset, const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05005277#In Draw_Text
5278#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05005279#Line # draws text following Path with offsets ##
Cary Clark8032b982017-07-28 11:04:54 -04005280
5281Draw text on Path path, using Clip, Matrix, and Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04005282
Cary Clarkbad5ad72017-08-03 17:14:08 -04005283Origin of text is at distance hOffset along the path, offset by a perpendicular
5284vector of length vOffset. If the path section corresponding the glyph advance is
5285curved, the glyph is drawn curved to match; control points in the glyph are
Cary Clarkbc5697d2017-10-04 14:31:33 -04005286mapped to projected points parallel to the path. If the text advance is larger
Cary Clarkbad5ad72017-08-03 17:14:08 -04005287than the path length, the excess text is clipped.
5288
Cary Clarkbc5697d2017-10-04 14:31:33 -04005289text meaning depends on Paint_Text_Encoding; by default, text is encoded as
Cary Clarkbad5ad72017-08-03 17:14:08 -04005290UTF-8. Origin meaning depends on Paint_Text_Align and Paint_Vertical_Text; by
Cary Clarkbc5697d2017-10-04 14:31:33 -04005291default text positions the first glyph left side bearing at origin x and its
Herb Derbyefe39bc2018-05-01 17:06:20 -04005292baseline at origin y. Text size is affected by Matrix and Paint_Text_Size.
Cary Clark8032b982017-07-28 11:04:54 -04005293
Mike Reed8ad91a92018-01-19 19:09:32 -05005294All elements of paint: Path_Effect, Mask_Filter, Shader,
Cary Clarkbad5ad72017-08-03 17:14:08 -04005295Color_Filter, Image_Filter, and Draw_Looper; apply to text. By default, draws
Cary Clarkce101242017-09-01 15:51:02 -04005296filled 12 point black Glyphs.
Cary Clark8032b982017-07-28 11:04:54 -04005297
Cary Clarkce101242017-09-01 15:51:02 -04005298#Param text character code points or Glyphs drawn ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005299#Param byteLength byte length of text array ##
5300#Param path Path providing text baseline ##
5301#Param hOffset distance along path to offset origin ##
5302#Param vOffset offset of text above (if negative) or below (if positive) the path ##
5303#Param paint text size, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005304
5305#Example
Herb Derbyefe39bc2018-05-01 17:06:20 -04005306 void draw(SkCanvas* canvas) {
Cary Clarkbad5ad72017-08-03 17:14:08 -04005307 const char aero[] = "correo a" "\xC3" "\xA9" "reo";
5308 const size_t len = sizeof(aero) - 1;
5309 SkPath path;
5310 path.addOval({43-26, 43-26, 43+26, 43+26}, SkPath::kCW_Direction, 3);
5311 SkPaint paint;
5312 paint.setTextSize(24);
5313 for (auto offset : { 0, 10, 20 } ) {
5314 canvas->drawTextOnPathHV(aero, len, path, 0, -offset, paint);
5315 canvas->translate(70 + offset, 70 + offset);
5316 }
5317 }
Cary Clark8032b982017-07-28 11:04:54 -04005318##
5319
Cary Clark2ade9972017-11-02 17:49:34 -04005320#SeeAlso drawTextOnPath drawText drawPosTextH drawTextBlob drawTextRSXform
Cary Clark8032b982017-07-28 11:04:54 -04005321
5322##
5323
5324# ------------------------------------------------------------------------------
5325
5326#Method void drawTextOnPath(const void* text, size_t byteLength, const SkPath& path,
5327 const SkMatrix* matrix, const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05005328#In Draw_Text
5329#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05005330#Line # draws text following Path contour ##
Cary Clark8032b982017-07-28 11:04:54 -04005331
5332Draw text on Path path, using Clip, Matrix, and Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04005333
Cary Clark682c58d2018-05-16 07:07:07 -04005334Origin of text is at beginning of path offset by matrix, if not nullptr.
5335matrix also transforms text before text is mapped to path. If the path section
5336corresponding the glyph advance is curved, the glyph is drawn curved to match;
5337control points in the glyph are mapped to projected points parallel to the path.
5338If the text advance is larger than the path length, the excess text is clipped.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005339
Cary Clarkbc5697d2017-10-04 14:31:33 -04005340text meaning depends on Paint_Text_Encoding; by default, text is encoded as
Cary Clarkbad5ad72017-08-03 17:14:08 -04005341UTF-8. Origin meaning depends on Paint_Text_Align and Paint_Vertical_Text; by
Cary Clarkbc5697d2017-10-04 14:31:33 -04005342default text positions the first glyph left side bearing at origin x and its
Cary Clark682c58d2018-05-16 07:07:07 -04005343baseline at origin y. Text size is affected by matrix parameter, Canvas_Matrix,
5344and Paint_Text_Size.
Cary Clark8032b982017-07-28 11:04:54 -04005345
Mike Reed8ad91a92018-01-19 19:09:32 -05005346All elements of paint: Path_Effect, Mask_Filter, Shader,
Cary Clarkbad5ad72017-08-03 17:14:08 -04005347Color_Filter, Image_Filter, and Draw_Looper; apply to text. By default, draws
Cary Clark682c58d2018-05-16 07:07:07 -04005348filled 12 point black Glyphs. Canvas Matrix does effect paint Shader, but
5349matrix parameter does not.
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
Herb Derbyefe39bc2018-05-01 17:06:20 -04005394RSXform array specifies a separate square scale, rotation, and translation for
Cary Clark8032b982017-07-28 11:04:54 -04005395each glyph.
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 ##