blob: 85faecc82183e788a9515845d4dc6e753594a4e0 [file] [log] [blame]
Cary Clark8032b982017-07-28 11:04:54 -04001#Topic Canvas
Cary Clark137b8742018-05-30 09:21:49 -04002#Alias Canvas_Reference ##
Cary Clark8032b982017-07-28 11:04:54 -04003
Cary Clarke4aa3712017-09-15 02:56:12 -04004#Class SkCanvas
5
Cary Clark8032b982017-07-28 11:04:54 -04006Canvas provides an interface for drawing, and how the drawing is clipped and transformed.
7Canvas contains a stack of Matrix and Clip values.
8
9Canvas and Paint together provide the state to draw into Surface or Device.
Cary Clarkbad5ad72017-08-03 17:14:08 -040010Each Canvas draw call transforms the geometry of the object by the concatenation of all
11Matrix values in the stack. The transformed geometry is clipped by the intersection
12of all of Clip values in the stack. The Canvas draw calls use Paint to supply drawing
13state such as Color, Typeface, text size, stroke width, Shader and so on.
Cary Clark8032b982017-07-28 11:04:54 -040014
Herb Derbyefe39bc2018-05-01 17:06:20 -040015To draw to a pixel-based destination, create Raster_Surface or GPU_Surface.
16Request Canvas from Surface to obtain the interface to draw.
17Canvas generated by Raster_Surface draws to memory visible to the CPU.
Cary Clark8032b982017-07-28 11:04:54 -040018Canvas generated by GPU_Surface uses Vulkan or OpenGL to draw to the GPU.
19
Cary Clarkbad5ad72017-08-03 17:14:08 -040020To draw to a document, obtain Canvas from SVG_Canvas, Document_PDF, or Picture_Recorder.
Cary Clarkce101242017-09-01 15:51:02 -040021Document based Canvas and other Canvas Subclasses reference Device describing the
Cary Clarkbad5ad72017-08-03 17:14:08 -040022destination.
23
Cary Clark8032b982017-07-28 11:04:54 -040024Canvas can be constructed to draw to Bitmap without first creating Raster_Surface.
Herb Derbyefe39bc2018-05-01 17:06:20 -040025This approach may be deprecated in the future.
Cary Clark8032b982017-07-28 11:04:54 -040026
Cary Clark682c58d2018-05-16 07:07:07 -040027#Subtopic Overview
28#Populate
29##
30
Cary Clark4855f782018-02-06 09:41:53 -050031#Subtopic Related_Function
Cary Clark08895c42018-02-01 09:37:32 -050032#Populate
33##
Cary Clark8032b982017-07-28 11:04:54 -040034
Cary Clark4855f782018-02-06 09:41:53 -050035#Subtopic Constant
Cary Clark08895c42018-02-01 09:37:32 -050036#Populate
37##
Cary Clark8032b982017-07-28 11:04:54 -040038
Cary Clark682c58d2018-05-16 07:07:07 -040039#Subtopic Struct
40#Populate
41##
42
43#Subtopic Typedef
Cary Clark08895c42018-02-01 09:37:32 -050044#Populate
45##
Cary Clark8032b982017-07-28 11:04:54 -040046
Cary Clark4855f782018-02-06 09:41:53 -050047#Subtopic Constructor
Cary Clark8032b982017-07-28 11:04:54 -040048
Cary Clark4855f782018-02-06 09:41:53 -050049Create the desired type of Surface to obtain its Canvas when possible. Useful
Cary Clark8032b982017-07-28 11:04:54 -040050when no Surface is required, and some helpers implicitly create Raster_Surface.
51
Cary Clark08895c42018-02-01 09:37:32 -050052#Populate
53##
Cary Clark8032b982017-07-28 11:04:54 -040054
Cary Clark4855f782018-02-06 09:41:53 -050055#Subtopic Member_Function
Cary Clark08895c42018-02-01 09:37:32 -050056#Populate
57##
Cary Clark8032b982017-07-28 11:04:54 -040058
59# ------------------------------------------------------------------------------
60
Cary Clarka560c472017-11-27 10:44:06 -050061#Method static std::unique_ptr<SkCanvas> MakeRasterDirect(const SkImageInfo& info, void* pixels,
62 size_t rowBytes,
63 const SkSurfaceProps* props = nullptr)
Cary Clark78de7512018-02-07 07:27:09 -050064#In Constructor
Cary Clarkab2621d2018-01-30 10:08:57 -050065#Line # creates from SkImageInfo and Pixel_Storage ##
Cary Clark8032b982017-07-28 11:04:54 -040066
Cary Clarkbad5ad72017-08-03 17:14:08 -040067Allocates raster Canvas that will draw directly into pixels.
Cary Clark8032b982017-07-28 11:04:54 -040068
Cary Clarkbad5ad72017-08-03 17:14:08 -040069Canvas is returned if all parameters are valid.
70Valid parameters include:
71info dimensions are zero or positive;
Cary Clark2dc84ad2018-01-26 12:56:22 -050072info contains Color_Type and Alpha_Type supported by Raster_Surface;
Cary Clarkbad5ad72017-08-03 17:14:08 -040073pixels is not nullptr;
Cary Clark2dc84ad2018-01-26 12:56:22 -050074rowBytes is zero or large enough to contain info width pixels of Color_Type.
Cary Clarkbad5ad72017-08-03 17:14:08 -040075
Herb Derbyefe39bc2018-05-01 17:06:20 -040076Pass zero for rowBytes to compute rowBytes from info width and size of pixel.
Cary Clarkf05bdda2017-08-24 12:59:48 -040077If rowBytes is greater than zero, it must be equal to or greater than
Cary Clark2dc84ad2018-01-26 12:56:22 -050078info width times bytes required for Color_Type.
Cary Clarkf05bdda2017-08-24 12:59:48 -040079
80Pixel buffer size should be info height times computed rowBytes.
Cary Clarka560c472017-11-27 10:44:06 -050081Pixels are not initialized.
82To access pixels after drawing, call flush() or peekPixels.
Cary Clarkbad5ad72017-08-03 17:14:08 -040083
Cary Clark2dc84ad2018-01-26 12:56:22 -050084#Param info width, height, Color_Type, Alpha_Type, Color_Space, of Raster_Surface;
Cary Clarkbad5ad72017-08-03 17:14:08 -040085 width, or height, or both, may be zero
Cary Clark8032b982017-07-28 11:04:54 -040086##
Cary Clarkf05bdda2017-08-24 12:59:48 -040087#Param pixels pointer to destination pixels buffer
Cary Clark8032b982017-07-28 11:04:54 -040088##
Cary Clarkf05bdda2017-08-24 12:59:48 -040089#Param rowBytes interval from one Surface row to the next, or zero
Cary Clark8032b982017-07-28 11:04:54 -040090##
Cary Clarka560c472017-11-27 10:44:06 -050091#Param props LCD striping orientation and setting for device independent fonts;
92 may be nullptr
93##
Cary Clark8032b982017-07-28 11:04:54 -040094
Cary Clarkbad5ad72017-08-03 17:14:08 -040095#Return Canvas if all parameters are valid; otherwise, nullptr ##
Cary Clark8032b982017-07-28 11:04:54 -040096
97#Example
98 #Description
99 Allocates a three by three bitmap, clears it to white, and draws a black pixel
100 in the center.
101 ##
Cary Clarkbad5ad72017-08-03 17:14:08 -0400102void draw(SkCanvas* ) {
Cary Clarkce101242017-09-01 15:51:02 -0400103 SkImageInfo info = SkImageInfo::MakeN32Premul(3, 3); // device aligned, 32 bpp, Premultiplied
Cary Clarkbad5ad72017-08-03 17:14:08 -0400104 const size_t minRowBytes = info.minRowBytes(); // bytes used by one bitmap row
Cary Clarka560c472017-11-27 10:44:06 -0500105 const size_t size = info.computeMinByteSize(); // bytes used by all rows
Cary Clarkbad5ad72017-08-03 17:14:08 -0400106 SkAutoTMalloc<SkPMColor> storage(size); // allocate storage for pixels
107 SkPMColor* pixels = storage.get(); // get pointer to allocated storage
108 // create a SkCanvas backed by a raster device, and delete it when the
109 // function goes out of scope.
110 std::unique_ptr<SkCanvas> canvas = SkCanvas::MakeRasterDirect(info, pixels, minRowBytes);
Cary Clarkce101242017-09-01 15:51:02 -0400111 canvas->clear(SK_ColorWHITE); // white is Unpremultiplied, in ARGB order
Cary Clarkbad5ad72017-08-03 17:14:08 -0400112 canvas->flush(); // ensure that pixels are cleared
Cary Clarkce101242017-09-01 15:51:02 -0400113 SkPMColor pmWhite = pixels[0]; // the Premultiplied format may vary
Cary Clarkbad5ad72017-08-03 17:14:08 -0400114 SkPaint paint; // by default, draws black
115 canvas->drawPoint(1, 1, paint); // draw in the center
116 canvas->flush(); // ensure that point was drawn
117 for (int y = 0; y < info.height(); ++y) {
118 for (int x = 0; x < info.width(); ++x) {
119 SkDebugf("%c", *pixels++ == pmWhite ? '-' : 'x');
120 }
121 SkDebugf("\n");
122 }
Cary Clark8032b982017-07-28 11:04:54 -0400123}
124 #StdOut
125 ---
126 -x-
127 ---
128 ##
129##
130
Cary Clark8032b982017-07-28 11:04:54 -0400131#SeeAlso MakeRasterDirectN32 SkSurface::MakeRasterDirect
Cary Clark2ade9972017-11-02 17:49:34 -0400132
Cary Clark8032b982017-07-28 11:04:54 -0400133##
134
135# ------------------------------------------------------------------------------
136
137#Method static std::unique_ptr<SkCanvas> MakeRasterDirectN32(int width, int height, SkPMColor* pixels,
Herb Derbyefe39bc2018-05-01 17:06:20 -0400138 size_t rowBytes)
Cary Clark78de7512018-02-07 07:27:09 -0500139#In Constructor
Cary Clarkab2621d2018-01-30 10:08:57 -0500140#Line # creates from image data and Pixel_Storage ##
Cary Clark8032b982017-07-28 11:04:54 -0400141
Cary Clarkbad5ad72017-08-03 17:14:08 -0400142Allocates raster Canvas specified by inline image specification. Subsequent Canvas
143calls draw into pixels.
Cary Clark2dc84ad2018-01-26 12:56:22 -0500144Color_Type is set to kN32_SkColorType.
145Alpha_Type is set to kPremul_SkAlphaType.
Cary Clark8032b982017-07-28 11:04:54 -0400146To access pixels after drawing, call flush() or peekPixels.
147
Cary Clarkbad5ad72017-08-03 17:14:08 -0400148Canvas is returned if all parameters are valid.
149Valid parameters include:
Cary Clarkf05bdda2017-08-24 12:59:48 -0400150width and height are zero or positive;
Cary Clarkbad5ad72017-08-03 17:14:08 -0400151pixels is not nullptr;
Cary Clarkf05bdda2017-08-24 12:59:48 -0400152rowBytes is zero or large enough to contain width pixels of kN32_SkColorType.
Cary Clarkbad5ad72017-08-03 17:14:08 -0400153
Herb Derbyefe39bc2018-05-01 17:06:20 -0400154Pass zero for rowBytes to compute rowBytes from width and size of pixel.
Cary Clarkf05bdda2017-08-24 12:59:48 -0400155If rowBytes is greater than zero, it must be equal to or greater than
Cary Clark2dc84ad2018-01-26 12:56:22 -0500156width times bytes required for Color_Type.
Cary Clarkf05bdda2017-08-24 12:59:48 -0400157
158Pixel buffer size should be height times rowBytes.
Cary Clarkbad5ad72017-08-03 17:14:08 -0400159
160#Param width pixel column count on Raster_Surface created; must be zero or greater ##
Cary Clarkbc5697d2017-10-04 14:31:33 -0400161#Param height pixel row count on Raster_Surface created; must be zero or greater ##
Cary Clarkbad5ad72017-08-03 17:14:08 -0400162#Param pixels pointer to destination pixels buffer; buffer size should be height
Cary Clarkf05bdda2017-08-24 12:59:48 -0400163 times rowBytes
Cary Clark8032b982017-07-28 11:04:54 -0400164##
Cary Clarkf05bdda2017-08-24 12:59:48 -0400165#Param rowBytes interval from one Surface row to the next, or zero
Cary Clark8032b982017-07-28 11:04:54 -0400166##
167
Cary Clarkbad5ad72017-08-03 17:14:08 -0400168#Return Canvas if all parameters are valid; otherwise, nullptr ##
Cary Clark8032b982017-07-28 11:04:54 -0400169
170#Example
171 #Description
172 Allocates a three by three bitmap, clears it to white, and draws a black pixel
173 in the center.
174 ##
175void draw(SkCanvas* ) {
176 const int width = 3;
177 const int height = 3;
Cary Clarkce101242017-09-01 15:51:02 -0400178 SkPMColor pixels[height][width]; // allocate a 3x3 Premultiplied bitmap on the stack
Cary Clark8032b982017-07-28 11:04:54 -0400179 // create a SkCanvas backed by a raster device, and delete it when the
180 // function goes out of scope.
181 std::unique_ptr<SkCanvas> canvas = SkCanvas::MakeRasterDirectN32(
182 width,
183 height,
Cary Clarkbc5697d2017-10-04 14:31:33 -0400184 pixels[0], // top-left of the bitmap
Cary Clark8032b982017-07-28 11:04:54 -0400185 sizeof(pixels[0])); // byte width of the each row
Cary Clark682c58d2018-05-16 07:07:07 -0400186 // write a Premultiplied value for white into all pixels in the bitmap
Cary Clark8032b982017-07-28 11:04:54 -0400187 canvas->clear(SK_ColorWHITE);
Cary Clarkce101242017-09-01 15:51:02 -0400188 SkPMColor pmWhite = pixels[0][0]; // the Premultiplied format may vary
Cary Clark8032b982017-07-28 11:04:54 -0400189 SkPaint paint; // by default, draws black
190 canvas->drawPoint(1, 1, paint); // draw in the center
191 canvas->flush(); // ensure that pixels is ready to be read
192 for (int y = 0; y < height; ++y) {
193 for (int x = 0; x < width; ++x) {
194 SkDebugf("%c", pixels[y][x] == pmWhite ? '-' : 'x');
195 }
196 SkDebugf("\n");
197 }
198}
199 #StdOut
200 ---
201 -x-
202 ---
203 ##
204##
205
Cary Clark2ade9972017-11-02 17:49:34 -0400206#SeeAlso MakeRasterDirect SkSurface::MakeRasterDirect SkImageInfo::MakeN32Premul
Cary Clark8032b982017-07-28 11:04:54 -0400207
208##
209
210# ------------------------------------------------------------------------------
211
212#Method SkCanvas()
213
Cary Clarkab2621d2018-01-30 10:08:57 -0500214#Line # creates with no Surface, no dimensions ##
Herb Derbyefe39bc2018-05-01 17:06:20 -0400215Creates an empty Canvas with no backing device or pixels, with
Cary Clarkf05bdda2017-08-24 12:59:48 -0400216a width and height of zero.
Cary Clark8032b982017-07-28 11:04:54 -0400217
Cary Clarkd0530ba2017-09-14 11:25:39 -0400218#Return empty Canvas ##
Cary Clark8032b982017-07-28 11:04:54 -0400219
220#Example
221
222#Description
223Passes a placeholder to a function that requires one.
224##
225
226#Function
Cary Clarkbad5ad72017-08-03 17:14:08 -0400227// Returns true if either the canvas rotates the text by 90 degrees, or the paint does.
228static void check_for_up_and_down_text(const SkCanvas* canvas, const SkPaint& paint) {
229 bool paintHasVertical = paint.isVerticalText();
230 const SkMatrix& matrix = canvas->getTotalMatrix();
231 bool matrixIsVertical = matrix.preservesRightAngles() && !matrix.isScaleTranslate();
232 SkDebugf("paint draws text %s\n", paintHasVertical != matrixIsVertical ?
233 "top to bottom" : "left to right");
234}
235
236static void check_for_up_and_down_text(const SkPaint& paint) {
237 SkCanvas canvas; // placeholder only, does not have an associated device
238 check_for_up_and_down_text(&canvas, paint);
239}
240
Cary Clark8032b982017-07-28 11:04:54 -0400241##
Cary Clarkbad5ad72017-08-03 17:14:08 -0400242void draw(SkCanvas* canvas) {
243 SkPaint paint;
244 check_for_up_and_down_text(paint); // paint draws text left to right
245 paint.setVerticalText(true);
246 check_for_up_and_down_text(paint); // paint draws text top to bottom
247 paint.setVerticalText(false);
248 canvas->rotate(90);
249 check_for_up_and_down_text(canvas, paint); // paint draws text top to bottom
250}
Cary Clark8032b982017-07-28 11:04:54 -0400251
252 #StdOut
253 paint draws text left to right
254 paint draws text top to bottom
255 paint draws text top to bottom
256 ##
257##
258
Cary Clark2ade9972017-11-02 17:49:34 -0400259#SeeAlso MakeRasterDirect SkRasterHandleAllocator::MakeCanvas SkSurface::getCanvas SkCreateColorSpaceXformCanvas
Cary Clark8032b982017-07-28 11:04:54 -0400260
261##
262
263# ------------------------------------------------------------------------------
264
Cary Clark73fa9722017-08-29 17:36:51 -0400265#Method SkCanvas(int width, int height, const SkSurfaceProps* props = nullptr)
Cary Clark8032b982017-07-28 11:04:54 -0400266
Cary Clark682c58d2018-05-16 07:07:07 -0400267#Line # creates with no Surface, set dimensions, Surface_Properties ##
Cary Clark8032b982017-07-28 11:04:54 -0400268Creates Canvas of the specified dimensions without a Surface.
Cary Clark682c58d2018-05-16 07:07:07 -0400269Used by Subclasses with custom implementations for draw member functions.
Cary Clark8032b982017-07-28 11:04:54 -0400270
Cary Clarkd0530ba2017-09-14 11:25:39 -0400271If props equals nullptr, Surface_Properties are created with
Herb Derbyefe39bc2018-05-01 17:06:20 -0400272Surface_Properties_Legacy_Font_Host settings, which choose the pixel striping
Cary Clarkd0530ba2017-09-14 11:25:39 -0400273direction and order. Since a platform may dynamically change its direction when
274the device is rotated, and since a platform may have multiple monitors with
275different characteristics, it is best not to rely on this legacy behavior.
Cary Clark8032b982017-07-28 11:04:54 -0400276
Cary Clarkbad5ad72017-08-03 17:14:08 -0400277#Param width zero or greater ##
278#Param height zero or greater ##
279#Param props LCD striping orientation and setting for device independent fonts;
280 may be nullptr
281##
282
283#Return Canvas placeholder with dimensions ##
Cary Clark8032b982017-07-28 11:04:54 -0400284
285#Example
286 SkCanvas canvas(10, 20); // 10 units wide, 20 units high
287 canvas.clipRect(SkRect::MakeXYWH(30, 40, 5, 10)); // clip is outside canvas' device
288 SkDebugf("canvas %s empty\n", canvas.getDeviceClipBounds().isEmpty() ? "is" : "is not");
289
290 #StdOut
291 canvas is empty
292 ##
293##
294
Cary Clark2ade9972017-11-02 17:49:34 -0400295#SeeAlso MakeRasterDirect SkSurfaceProps SkPixelGeometry SkCreateColorSpaceXformCanvas
Cary Clark8032b982017-07-28 11:04:54 -0400296
297##
298
299# ------------------------------------------------------------------------------
300
Herb Derbyefe39bc2018-05-01 17:06:20 -0400301#Method explicit SkCanvas(sk_sp<SkBaseDevice> device)
Cary Clark4855f782018-02-06 09:41:53 -0500302#Deprecated soon
Cary Clark8032b982017-07-28 11:04:54 -0400303##
304
305# ------------------------------------------------------------------------------
306
307#Method explicit SkCanvas(const SkBitmap& bitmap)
308
Cary Clarkab2621d2018-01-30 10:08:57 -0500309#Line # uses existing Bitmap ##
Cary Clark80247e52018-07-11 16:18:41 -0400310Constructs 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 Clark80247e52018-07-11 16:18:41 -0400390For use by Android 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 Clark80247e52018-07-11 16:18:41 -0400405Constructs a canvas that draws into bitmap.
Cary Clark8032b982017-07-28 11:04:54 -0400406Use 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 Clark80247e52018-07-11 16:18:41 -0400565Copies Surface_Properties, if Canvas is associated with Raster_Surface or
566GPU_Surface, and returns true. Otherwise, returns false and leave props unchanged.
Cary Clark8032b982017-07-28 11:04:54 -0400567
Cary Clarkbad5ad72017-08-03 17:14:08 -0400568#Param props storage for writable SkSurfaceProps ##
Cary Clark8032b982017-07-28 11:04:54 -0400569
Cary Clarkbad5ad72017-08-03 17:14:08 -0400570#Return true if Surface_Properties was copied ##
Cary Clark8032b982017-07-28 11:04:54 -0400571
572#ToDo This seems old style. Deprecate? ##
573
574#Example
575 SkBitmap bitmap;
576 SkCanvas canvas(bitmap, SkSurfaceProps(0, kRGB_V_SkPixelGeometry));
577 SkSurfaceProps surfaceProps(0, kUnknown_SkPixelGeometry);
578 SkDebugf("isRGB:%d\n", SkPixelGeometryIsRGB(surfaceProps.pixelGeometry()));
579 if (!canvas.getProps(&surfaceProps)) {
580 SkDebugf("getProps failed unexpectedly.\n");
581 }
582 SkDebugf("isRGB:%d\n", SkPixelGeometryIsRGB(surfaceProps.pixelGeometry()));
583
584 #StdOut
585 isRGB:0
586 isRGB:1
587 #StdOut ##
588##
589
Cary Clark2ade9972017-11-02 17:49:34 -0400590#SeeAlso SkSurfaceProps makeSurface
Cary Clark8032b982017-07-28 11:04:54 -0400591
592##
593
594# ------------------------------------------------------------------------------
Cary Clark78de7512018-02-07 07:27:09 -0500595#Subtopic Utility
596#Populate
597#Line # rarely called management functions ##
598##
Cary Clark8032b982017-07-28 11:04:54 -0400599
600#Method void flush()
Cary Clark78de7512018-02-07 07:27:09 -0500601#In Utility
Cary Clarkab2621d2018-01-30 10:08:57 -0500602#Line # triggers execution of all pending draw operations ##
Herb Derbyefe39bc2018-05-01 17:06:20 -0400603Triggers the immediate execution of all pending draw operations.
Cary Clarkbad5ad72017-08-03 17:14:08 -0400604If Canvas is associated with GPU_Surface, resolves all pending GPU operations.
Cary Clark2ade9972017-11-02 17:49:34 -0400605If Canvas is associated with Raster_Surface, has no effect; raster draw
606operations are never deferred.
607
608#ToDo
609In an overview section on managing the GPU, include:
610- flush should never change what is drawn
611- call to kick off gpu work
612- calling too much impacts performance
613- some calls (peekPixels, prepareForExternalIO) call it internally
614- canvas call is local, GrContext::flush is global
615- diffentiate between flush, flushAndSignalSemaphores
616- normally never needs to be called
617- call it when sharing gpu resources, feeling memory pressure, swapping out app, and before
618 abandoning context
619- also call to say "I'm finished drawing here", e.g., when drawing to a GPU-backed offscreen surface
620 (created with SkSurface::MakeRenderTarget)
621
622for posterity: this doesn't show a difference: fiddle.skia.org/c/@flushfail
623##
Cary Clark8032b982017-07-28 11:04:54 -0400624
Cary Clark08895c42018-02-01 09:37:32 -0500625#ToDo haven't thought of a useful example to put here ##
626#NoExample
Cary Clark8032b982017-07-28 11:04:54 -0400627##
628
Cary Clark2ade9972017-11-02 17:49:34 -0400629#SeeAlso peekPixels SkSurface::flush() GrContext::flush() SkSurface::prepareForExternalIO GrContext::abandonContext()
Cary Clark8032b982017-07-28 11:04:54 -0400630
631##
632
633# ------------------------------------------------------------------------------
634
635#Method virtual SkISize getBaseLayerSize() const
Cary Clark78de7512018-02-07 07:27:09 -0500636#In Property
Cary Clarkab2621d2018-01-30 10:08:57 -0500637#Line # returns size of base Layer in global coordinates ##
Cary Clarkce101242017-09-01 15:51:02 -0400638Gets the size of the base or root Layer in global canvas coordinates. The
639origin of the base Layer is always (0,0). The area available for drawing may be
Cary Clark8032b982017-07-28 11:04:54 -0400640smaller (due to clipping or saveLayer).
641
Cary Clarkce101242017-09-01 15:51:02 -0400642#Return integral width and height of base Layer ##
Cary Clark8032b982017-07-28 11:04:54 -0400643
644#Example
645 SkBitmap bitmap;
646 bitmap.allocPixels(SkImageInfo::MakeN32Premul(20, 30));
647 SkCanvas canvas(bitmap, SkSurfaceProps(0, kUnknown_SkPixelGeometry));
648 canvas.clipRect(SkRect::MakeWH(10, 40));
649 SkIRect clipDeviceBounds = canvas.getDeviceClipBounds();
650 if (clipDeviceBounds.isEmpty()) {
651 SkDebugf("Empty clip bounds is unexpected!\n");
652 }
653 SkDebugf("clip=%d,%d\n", clipDeviceBounds.width(), clipDeviceBounds.height());
654 SkISize baseLayerSize = canvas.getBaseLayerSize();
655 SkDebugf("size=%d,%d\n", baseLayerSize.width(), baseLayerSize.height());
656
657 #StdOut
658 clip=10,30
659 size=20,30
660 ##
661##
662
663#ToDo is this the same as the width and height of surface? ##
664
Cary Clark2ade9972017-11-02 17:49:34 -0400665#SeeAlso getDeviceClipBounds
666
Cary Clark8032b982017-07-28 11:04:54 -0400667##
668
669# ------------------------------------------------------------------------------
670
671#Method sk_sp<SkSurface> makeSurface(const SkImageInfo& info, const SkSurfaceProps* props = nullptr)
Cary Clark4855f782018-02-06 09:41:53 -0500672#In Constructor
Cary Clarkab2621d2018-01-30 10:08:57 -0500673#Line # creates Surface matching SkImageInfo and SkSurfaceProps ##
Cary Clark8032b982017-07-28 11:04:54 -0400674Creates Surface matching info and props, and associates it with Canvas.
Cary Clarkbad5ad72017-08-03 17:14:08 -0400675Returns nullptr if no match found.
Cary Clark8032b982017-07-28 11:04:54 -0400676
Cary Clarkbad5ad72017-08-03 17:14:08 -0400677If props is nullptr, matches Surface_Properties in Canvas. If props is nullptr and Canvas
678does not have Surface_Properties, creates Surface with default Surface_Properties.
Cary Clark8032b982017-07-28 11:04:54 -0400679
Cary Clark2dc84ad2018-01-26 12:56:22 -0500680#Param info width, height, Color_Type, Alpha_Type, and Color_Space ##
Cary Clarkbad5ad72017-08-03 17:14:08 -0400681#Param props Surface_Properties to match; may be nullptr to match Canvas ##
682
683#Return Surface matching info and props, or nullptr if no match is available ##
Cary Clark8032b982017-07-28 11:04:54 -0400684
685#Example
686 sk_sp<SkSurface> surface = SkSurface::MakeRasterN32Premul(5, 6);
687 SkCanvas* smallCanvas = surface->getCanvas();
688 SkImageInfo imageInfo = SkImageInfo::MakeN32Premul(3, 4);
689 sk_sp<SkSurface> compatible = smallCanvas->makeSurface(imageInfo);
690 SkDebugf("compatible %c= nullptr\n", compatible == nullptr ? '=' : '!');
691 SkDebugf("size = %d, %d\n", compatible->width(), compatible->height());
692
693 #StdOut
Cary Clarkbad5ad72017-08-03 17:14:08 -0400694 compatible != nullptr
Cary Clark8032b982017-07-28 11:04:54 -0400695 size = 3, 4
696 ##
697##
698
Cary Clark2ade9972017-11-02 17:49:34 -0400699#SeeAlso SkSurface SkSurface::makeSurface SkImageInfo SkSurfaceProps
Cary Clark8032b982017-07-28 11:04:54 -0400700
701##
702
703# ------------------------------------------------------------------------------
704
705#Method virtual GrContext* getGrContext()
Cary Clark78de7512018-02-07 07:27:09 -0500706#In Property
Cary Clarkab2621d2018-01-30 10:08:57 -0500707#Line # returns GPU_Context of the GPU_Surface ##
Cary Clark8032b982017-07-28 11:04:54 -0400708Returns GPU_Context of the GPU_Surface associated with Canvas.
709
Cary Clarkbad5ad72017-08-03 17:14:08 -0400710#Return GPU_Context, if available; nullptr otherwise ##
Cary Clark8032b982017-07-28 11:04:54 -0400711
712#Example
713void draw(SkCanvas* canvas) {
714 if (canvas->getGrContext()) {
715 canvas->clear(SK_ColorRED);
716 } else {
717 canvas->clear(SK_ColorBLUE);
718 }
719}
720##
721
722#ToDo fiddle should show both CPU and GPU out ##
723
Herb Derbyefe39bc2018-05-01 17:06:20 -0400724#SeeAlso GrContext
Cary Clark2ade9972017-11-02 17:49:34 -0400725
Cary Clark8032b982017-07-28 11:04:54 -0400726##
727
728# ------------------------------------------------------------------------------
729
Cary Clark73fa9722017-08-29 17:36:51 -0400730#Method void* accessTopLayerPixels(SkImageInfo* info, size_t* rowBytes, SkIPoint* origin = nullptr)
Cary Clark78de7512018-02-07 07:27:09 -0500731#In Utility
732#In Property
Cary Clarkab2621d2018-01-30 10:08:57 -0500733#Line # returns writable pixel access if available ##
Cary Clark8032b982017-07-28 11:04:54 -0400734Returns the pixel base address, Image_Info, rowBytes, and origin if the pixels
Cary Clarkbad5ad72017-08-03 17:14:08 -0400735can be read directly. The returned address is only valid
Cary Clark8032b982017-07-28 11:04:54 -0400736while Canvas is in scope and unchanged. Any Canvas call or Surface call
737may invalidate the returned address and other returned values.
738
739If pixels are inaccessible, info, rowBytes, and origin are unchanged.
740
Cary Clarkbad5ad72017-08-03 17:14:08 -0400741#Param info storage for writable pixels' Image_Info; may be nullptr ##
742#Param rowBytes storage for writable pixels' row bytes; may be nullptr ##
Cary Clarkbc5697d2017-10-04 14:31:33 -0400743#Param origin storage for Canvas top Layer origin, its top-left corner;
Cary Clarkbad5ad72017-08-03 17:14:08 -0400744 may be nullptr
745##
Cary Clark8032b982017-07-28 11:04:54 -0400746
Cary Clarka523d2d2017-08-30 08:58:10 -0400747#Return address of pixels, or nullptr if inaccessible ##
Cary Clark8032b982017-07-28 11:04:54 -0400748
749#Example
750void draw(SkCanvas* canvas) {
751 if (canvas->accessTopLayerPixels(nullptr, nullptr)) {
752 canvas->clear(SK_ColorRED);
753 } else {
754 canvas->clear(SK_ColorBLUE);
755 }
756}
757##
758
759#Example
760#Description
Cary Clarkce101242017-09-01 15:51:02 -0400761Draws "ABC" on the device. Then draws "DEF" in Layer, and reads
762Layer to add a large dotted "DEF". Finally blends Layer with the
Herb Derbyefe39bc2018-05-01 17:06:20 -0400763device.
Cary Clark8032b982017-07-28 11:04:54 -0400764
Cary Clarkce101242017-09-01 15:51:02 -0400765The Layer and blended result appear on the CPU and GPU but the large dotted
Cary Clark8032b982017-07-28 11:04:54 -0400766"DEF" appear only on the CPU.
767##
768void draw(SkCanvas* canvas) {
Cary Clarkbad5ad72017-08-03 17:14:08 -0400769 SkPaint paint;
770 paint.setTextSize(100);
771 canvas->drawString("ABC", 20, 160, paint);
772 SkRect layerBounds = SkRect::MakeXYWH(32, 32, 192, 192);
773 canvas->saveLayerAlpha(&layerBounds, 128);
774 canvas->clear(SK_ColorWHITE);
775 canvas->drawString("DEF", 20, 160, paint);
776 SkImageInfo imageInfo;
777 size_t rowBytes;
778 SkIPoint origin;
779 uint32_t* access = (uint32_t*) canvas->accessTopLayerPixels(&imageInfo, &rowBytes, &origin);
780 if (access) {
781 int h = imageInfo.height();
782 int v = imageInfo.width();
783 int rowWords = rowBytes / sizeof(uint32_t);
784 for (int y = 0; y < h; ++y) {
785 int newY = (y - h / 2) * 2 + h / 2;
786 if (newY < 0 || newY >= h) {
787 continue;
788 }
789 for (int x = 0; x < v; ++x) {
790 int newX = (x - v / 2) * 2 + v / 2;
791 if (newX < 0 || newX >= v) {
792 continue;
793 }
794 if (access[y * rowWords + x] == SK_ColorBLACK) {
795 access[newY * rowWords + newX] = SK_ColorGRAY;
796 }
797 }
798 }
799
800 }
Cary Clark8032b982017-07-28 11:04:54 -0400801 canvas->restore();
802}
803##
804
805#ToDo there are no callers of this that I can find. Deprecate? ##
806#ToDo fiddle should show both CPU and GPU out ##
807
Cary Clark2ade9972017-11-02 17:49:34 -0400808#SeeAlso SkImageInfo SkPixmap
809
Cary Clark8032b982017-07-28 11:04:54 -0400810##
811
812# ------------------------------------------------------------------------------
813
814#Method SkRasterHandleAllocator::Handle accessTopRasterHandle() const
Cary Clark78de7512018-02-07 07:27:09 -0500815#In Utility
816#In Property
Cary Clarkab2621d2018-01-30 10:08:57 -0500817#Line # returns context that tracks Clip and Matrix ##
Cary Clark8032b982017-07-28 11:04:54 -0400818Returns custom context that tracks the Matrix and Clip.
819
820Use Raster_Handle_Allocator to blend Skia drawing with custom drawing, typically performed
Cary Clarkbc5697d2017-10-04 14:31:33 -0400821by the host platform user interface. The custom context returned is generated by
Cary Clarkbad5ad72017-08-03 17:14:08 -0400822SkRasterHandleAllocator::MakeCanvas, which creates a custom canvas with raster storage for
Cary Clark8032b982017-07-28 11:04:54 -0400823the drawing destination.
824
Cary Clarkce101242017-09-01 15:51:02 -0400825#Return context of custom allocation ##
Cary Clark8032b982017-07-28 11:04:54 -0400826
827#Example
828#Description
829#ToDo ##
830##
831#Function
832 static void DeleteCallback(void*, void* context) {
833 delete (char*) context;
834 }
835
836 class CustomAllocator : public SkRasterHandleAllocator {
837 public:
838 bool allocHandle(const SkImageInfo& info, Rec* rec) override {
839 char* context = new char[4]{'s', 'k', 'i', 'a'};
840 rec->fReleaseProc = DeleteCallback;
841 rec->fReleaseCtx = context;
842 rec->fHandle = context;
843 rec->fPixels = context;
844 rec->fRowBytes = 4;
845 return true;
846 }
847
848 void updateHandle(Handle handle, const SkMatrix& ctm, const SkIRect& clip_bounds) override {
849 // apply canvas matrix and clip to custom environment
850 }
851 };
852
853##
854 void draw(SkCanvas* canvas) {
855 const SkImageInfo info = SkImageInfo::MakeN32Premul(1, 1);
856 std::unique_ptr<SkCanvas> c2 =
857 SkRasterHandleAllocator::MakeCanvas(std::unique_ptr<CustomAllocator>(
858 new CustomAllocator()), info);
859 char* context = (char*) c2->accessTopRasterHandle();
860 SkDebugf("context = %.4s\n", context);
861
862 }
863 #StdOut
864 context = skia
865 ##
866 #ToDo skstd::make_unique could not be used because def is private -- note to fix in c++14? ##
867##
868
869#SeeAlso SkRasterHandleAllocator
870
871##
872
873# ------------------------------------------------------------------------------
Cary Clark78de7512018-02-07 07:27:09 -0500874#Subtopic Pixels
875#Populate
876#Line # read and write pixel values ##
877##
Cary Clark8032b982017-07-28 11:04:54 -0400878
879#Method bool peekPixels(SkPixmap* pixmap)
Cary Clark78de7512018-02-07 07:27:09 -0500880#In Pixels
Cary Clarkab2621d2018-01-30 10:08:57 -0500881#Line # returns if Canvas has direct access to its pixels ##
Cary Clark8032b982017-07-28 11:04:54 -0400882Returns true if Canvas has direct access to its pixels.
883
Cary Clarkf05bdda2017-08-24 12:59:48 -0400884Pixels are readable when Device is raster. Pixels are not readable when Canvas
Cary Clarkbad5ad72017-08-03 17:14:08 -0400885is returned from GPU_Surface, returned by SkDocument::beginPage, returned by
Cary Clarkf05bdda2017-08-24 12:59:48 -0400886SkPictureRecorder::beginRecording, or Canvas is the base of a utility class
Brian Osman46fe9c72018-03-09 15:44:34 -0500887like SkDebugCanvas.
Cary Clark8032b982017-07-28 11:04:54 -0400888
Cary Clarkf05bdda2017-08-24 12:59:48 -0400889pixmap is valid only while Canvas is in scope and unchanged. Any
Cary Clarkbad5ad72017-08-03 17:14:08 -0400890Canvas or Surface call may invalidate the pixmap values.
Cary Clark8032b982017-07-28 11:04:54 -0400891
Cary Clarkbc5697d2017-10-04 14:31:33 -0400892#Param pixmap storage for pixel state if pixels are readable; otherwise, ignored ##
Cary Clark8032b982017-07-28 11:04:54 -0400893
Cary Clarkbad5ad72017-08-03 17:14:08 -0400894#Return true if Canvas has direct access to pixels ##
Cary Clark8032b982017-07-28 11:04:54 -0400895
896#Example
897 SkPixmap pixmap;
898 if (canvas->peekPixels(&pixmap)) {
899 SkDebugf("width=%d height=%d\n", pixmap.bounds().width(), pixmap.bounds().height());
900 }
901 #StdOut
902 width=256 height=256
903 ##
904##
905
Cary Clark2ade9972017-11-02 17:49:34 -0400906#SeeAlso readPixels SkBitmap::peekPixels SkImage::peekPixels SkSurface::peekPixels
907
Cary Clark8032b982017-07-28 11:04:54 -0400908##
909
910# ------------------------------------------------------------------------------
911
912#Method bool readPixels(const SkImageInfo& dstInfo, void* dstPixels, size_t dstRowBytes,
913 int srcX, int srcY)
Cary Clark78de7512018-02-07 07:27:09 -0500914#In Pixels
Cary Clarkab2621d2018-01-30 10:08:57 -0500915#Line # copies and converts rectangle of pixels from Canvas ##
Cary Clark8032b982017-07-28 11:04:54 -0400916
Cary Clark154beea2017-10-26 07:58:48 -0400917Copies Rect of pixels from Canvas into dstPixels. Matrix and Clip are
Herb Derbyefe39bc2018-05-01 17:06:20 -0400918ignored.
Cary Clark6fc50412017-09-21 12:31:06 -0400919
Cary Clarka560c472017-11-27 10:44:06 -0500920Source Rect corners are (srcX, srcY) and (imageInfo().width(), imageInfo().height()).
921Destination Rect corners are (0, 0) and (dstInfo.width(), dstInfo.height()).
Cary Clark6fc50412017-09-21 12:31:06 -0400922Copies each readable pixel intersecting both rectangles, without scaling,
Cary Clarkf05bdda2017-08-24 12:59:48 -0400923converting to dstInfo.colorType() and dstInfo.alphaType() if required.
Cary Clark8032b982017-07-28 11:04:54 -0400924
Cary Clarkf05bdda2017-08-24 12:59:48 -0400925Pixels are readable when Device is raster, or backed by a GPU.
926Pixels are not readable when SkCanvas is returned by SkDocument::beginPage,
927returned by SkPictureRecorder::beginRecording, or Canvas is the base of a utility
Brian Osman46fe9c72018-03-09 15:44:34 -0500928class like SkDebugCanvas.
Cary Clark8032b982017-07-28 11:04:54 -0400929
Cary Clarkf05bdda2017-08-24 12:59:48 -0400930The destination pixel storage must be allocated by the caller.
Cary Clark8032b982017-07-28 11:04:54 -0400931
Cary Clark2dc84ad2018-01-26 12:56:22 -0500932Pixel values are converted only if Color_Type and Alpha_Type
Cary Clarkf05bdda2017-08-24 12:59:48 -0400933do not match. Only pixels within both source and destination rectangles
Cary Clark154beea2017-10-26 07:58:48 -0400934are copied. dstPixels contents outside Rect intersection are unchanged.
Cary Clarkf05bdda2017-08-24 12:59:48 -0400935
936Pass negative values for srcX or srcY to offset pixels across or down destination.
Cary Clark8032b982017-07-28 11:04:54 -0400937
938Does not copy, and returns false if:
939
940#List
Cary Clarkf05bdda2017-08-24 12:59:48 -0400941# Source and destination rectangles do not intersect. ##
942# Canvas pixels could not be converted to dstInfo.colorType() or dstInfo.alphaType(). ##
943# Canvas pixels are not readable; for instance, Canvas is document-based. ##
Cary Clark8032b982017-07-28 11:04:54 -0400944# dstRowBytes is too small to contain one row of pixels. ##
945##
946
Cary Clark2dc84ad2018-01-26 12:56:22 -0500947#Param dstInfo width, height, Color_Type, and Alpha_Type of dstPixels ##
Cary Clarkf05bdda2017-08-24 12:59:48 -0400948#Param dstPixels storage for pixels; dstInfo.height() times dstRowBytes, or larger ##
949#Param dstRowBytes size of one destination row; dstInfo.width() times pixel size, or larger ##
Cary Clark5538c132018-06-14 12:28:14 -0400950#Param srcX offset into readable pixels on x-axis; may be negative ##
951#Param srcY offset into readable pixels on y-axis; may be negative ##
Cary Clark8032b982017-07-28 11:04:54 -0400952
Cary Clarkbad5ad72017-08-03 17:14:08 -0400953#Return true if pixels were copied ##
Cary Clark8032b982017-07-28 11:04:54 -0400954
955#Example
Cary Clarkf05bdda2017-08-24 12:59:48 -0400956#Width 64
957#Height 64
958#Description
959 A black circle drawn on a blue background provides an image to copy.
960 readPixels copies one quarter of the canvas into each of the four corners.
Cary Clarka560c472017-11-27 10:44:06 -0500961 The copied quarter circles overdraw the original circle.
Cary Clarkf05bdda2017-08-24 12:59:48 -0400962##
963 canvas->clear(SK_ColorBLUE);
964 SkPaint paint;
965 canvas->drawCircle(32, 32, 28, paint);
966 SkImageInfo info = SkImageInfo::Make(64, 64, kBGRA_8888_SkColorType, kPremul_SkAlphaType);
967 sk_sp<SkData> data(SkData::MakeUninitialized(info.minRowBytes() * info.height()));
968 sk_bzero(data->writable_data(), info.minRowBytes() * info.height());
969 for (int x : { 32, -32 } ) {
970 for (int y : { 32, -32 } ) {
971 canvas->readPixels(info, data->writable_data(), info.minRowBytes(), x, y);
Herb Derbyefe39bc2018-05-01 17:06:20 -0400972 }
Cary Clarkf05bdda2017-08-24 12:59:48 -0400973 }
974 sk_sp<SkImage> image = SkImage::MakeRasterData(info, data, info.minRowBytes());
975 canvas->drawImage(image, 0, 0);
976##
977
978#Example
Cary Clark8032b982017-07-28 11:04:54 -0400979#Description
Cary Clarkce101242017-09-01 15:51:02 -0400980 Canvas returned by Raster_Surface has Premultiplied pixel values.
981 clear() takes Unpremultiplied input with Color_Alpha equal 0x80
Cary Clarkffb3d682018-05-17 12:17:28 -0400982 and RGB equal 0x55, 0xAA, 0xFF. RGB is multiplied by Color_Alpha
Cary Clarkce101242017-09-01 15:51:02 -0400983 to generate Premultiplied value 0x802B5580. readPixels converts pixel back
984 to Unpremultiplied value 0x8056A9FF, introducing error.
Cary Clark8032b982017-07-28 11:04:54 -0400985##
986 canvas->clear(0x8055aaff);
987 for (SkAlphaType alphaType : { kPremul_SkAlphaType, kUnpremul_SkAlphaType } ) {
988 uint32_t pixel = 0;
989 SkImageInfo info = SkImageInfo::Make(1, 1, kBGRA_8888_SkColorType, alphaType);
990 if (canvas->readPixels(info, &pixel, 4, 0, 0)) {
991 SkDebugf("pixel = %08x\n", pixel);
992 }
993 }
994
995 #StdOut
996 pixel = 802b5580
997 pixel = 8056a9ff
998 ##
999##
1000
Cary Clark2ade9972017-11-02 17:49:34 -04001001#SeeAlso peekPixels writePixels drawBitmap drawImage SkBitmap::readPixels SkPixmap::readPixels SkImage::readPixels SkSurface::readPixels
Cary Clark8032b982017-07-28 11:04:54 -04001002
1003##
1004
1005# ------------------------------------------------------------------------------
1006
1007#Method bool readPixels(const SkPixmap& pixmap, int srcX, int srcY)
1008
Cary Clark154beea2017-10-26 07:58:48 -04001009Copies Rect of pixels from Canvas into pixmap. Matrix and Clip are
Cary Clarka560c472017-11-27 10:44:06 -05001010ignored.
Cary Clark6fc50412017-09-21 12:31:06 -04001011
Cary Clarka560c472017-11-27 10:44:06 -05001012Source Rect corners are (srcX, srcY) and (imageInfo().width(), imageInfo().height()).
1013Destination Rect corners are (0, 0) and (pixmap.width(), pixmap.height()).
Cary Clark6fc50412017-09-21 12:31:06 -04001014Copies each readable pixel intersecting both rectangles, without scaling,
Cary Clarkf05bdda2017-08-24 12:59:48 -04001015converting to pixmap.colorType() and pixmap.alphaType() if required.
Cary Clark8032b982017-07-28 11:04:54 -04001016
Cary Clarkf05bdda2017-08-24 12:59:48 -04001017Pixels are readable when Device is raster, or backed by a GPU.
1018Pixels are not readable when SkCanvas is returned by SkDocument::beginPage,
1019returned by SkPictureRecorder::beginRecording, or Canvas is the base of a utility
Brian Osman46fe9c72018-03-09 15:44:34 -05001020class like SkDebugCanvas.
Cary Clark8032b982017-07-28 11:04:54 -04001021
Cary Clark6fc50412017-09-21 12:31:06 -04001022Caller must allocate pixel storage in pixmap if needed.
Cary Clark8032b982017-07-28 11:04:54 -04001023
Cary Clark2dc84ad2018-01-26 12:56:22 -05001024Pixel values are converted only if Color_Type and Alpha_Type
Cary Clark154beea2017-10-26 07:58:48 -04001025do not match. Only pixels within both source and destination Rects
1026are copied. pixmap pixels contents outside Rect intersection are unchanged.
Cary Clarkf05bdda2017-08-24 12:59:48 -04001027
1028Pass negative values for srcX or srcY to offset pixels across or down pixmap.
Cary Clark8032b982017-07-28 11:04:54 -04001029
1030Does not copy, and returns false if:
1031
1032#List
Cary Clarkf05bdda2017-08-24 12:59:48 -04001033# Source and destination rectangles do not intersect. ##
1034# Canvas pixels could not be converted to pixmap.colorType() or pixmap.alphaType(). ##
1035# Canvas pixels are not readable; for instance, Canvas is document-based. ##
1036# Pixmap pixels could not be allocated. ##
1037# pixmap.rowBytes() is too small to contain one row of pixels. ##
Cary Clark8032b982017-07-28 11:04:54 -04001038##
1039
Cary Clarkbad5ad72017-08-03 17:14:08 -04001040#Param pixmap storage for pixels copied from Canvas ##
Cary Clark5538c132018-06-14 12:28:14 -04001041#Param srcX offset into readable pixels on x-axis; may be negative ##
1042#Param srcY offset into readable pixels on y-axis; may be negative ##
Cary Clark8032b982017-07-28 11:04:54 -04001043
Cary Clarkbad5ad72017-08-03 17:14:08 -04001044#Return true if pixels were copied ##
Cary Clark8032b982017-07-28 11:04:54 -04001045
1046#Example
Cary Clarkf05bdda2017-08-24 12:59:48 -04001047 #Description
Cary Clarkce101242017-09-01 15:51:02 -04001048 clear() takes Unpremultiplied input with Color_Alpha equal 0x80
Cary Clarkffb3d682018-05-17 12:17:28 -04001049 and RGB equal 0x55, 0xAA, 0xFF. RGB is multiplied by Color_Alpha
Cary Clarkce101242017-09-01 15:51:02 -04001050 to generate Premultiplied value 0x802B5580.
Cary Clarkf05bdda2017-08-24 12:59:48 -04001051 ##
1052 void draw(SkCanvas* canvas) {
1053 canvas->clear(0x8055aaff);
1054 uint32_t pixels[1] = { 0 };
1055 SkPixmap pixmap(SkImageInfo::MakeN32Premul(1, 1), pixels, 4);
1056 canvas->readPixels(pixmap, 0, 0);
1057 SkDebugf("pixel = %08x\n", pixels[0]);
1058 }
Cary Clark8032b982017-07-28 11:04:54 -04001059 #StdOut
1060 pixel = 802b5580
1061 ##
1062##
1063
Cary Clark2ade9972017-11-02 17:49:34 -04001064#SeeAlso peekPixels writePixels drawBitmap drawImage SkBitmap::readPixels SkPixmap::readPixels SkImage::readPixels SkSurface::readPixels
Cary Clark8032b982017-07-28 11:04:54 -04001065
1066##
1067
1068# ------------------------------------------------------------------------------
1069
1070#Method bool readPixels(const SkBitmap& bitmap, int srcX, int srcY)
1071
Cary Clark154beea2017-10-26 07:58:48 -04001072Copies Rect of pixels from Canvas into bitmap. Matrix and Clip are
Cary Clarka560c472017-11-27 10:44:06 -05001073ignored.
Cary Clark6fc50412017-09-21 12:31:06 -04001074
Cary Clarka560c472017-11-27 10:44:06 -05001075Source Rect corners are (srcX, srcY) and (imageInfo().width(), imageInfo().height()).
Cary Clark154beea2017-10-26 07:58:48 -04001076Destination Rect corners are (0, 0) and (bitmap.width(), bitmap.height()).
Cary Clarkf05bdda2017-08-24 12:59:48 -04001077Copies each readable pixel intersecting both rectangles, without scaling,
1078converting to bitmap.colorType() and bitmap.alphaType() if required.
Cary Clark8032b982017-07-28 11:04:54 -04001079
Cary Clarkf05bdda2017-08-24 12:59:48 -04001080Pixels are readable when Device is raster, or backed by a GPU.
1081Pixels are not readable when SkCanvas is returned by SkDocument::beginPage,
1082returned by SkPictureRecorder::beginRecording, or Canvas is the base of a utility
Brian Osman46fe9c72018-03-09 15:44:34 -05001083class like SkDebugCanvas.
Cary Clark8032b982017-07-28 11:04:54 -04001084
Cary Clark6fc50412017-09-21 12:31:06 -04001085Caller must allocate pixel storage in bitmap if needed.
Cary Clarkf05bdda2017-08-24 12:59:48 -04001086
Cary Clark2dc84ad2018-01-26 12:56:22 -05001087Bitmap values are converted only if Color_Type and Alpha_Type
Cary Clarkf05bdda2017-08-24 12:59:48 -04001088do not match. Only pixels within both source and destination rectangles
Cary Clark154beea2017-10-26 07:58:48 -04001089are copied. Bitmap pixels outside Rect intersection are unchanged.
Cary Clarkf05bdda2017-08-24 12:59:48 -04001090
1091Pass negative values for srcX or srcY to offset pixels across or down bitmap.
Cary Clark8032b982017-07-28 11:04:54 -04001092
1093Does not copy, and returns false if:
1094
1095#List
Cary Clarkf05bdda2017-08-24 12:59:48 -04001096# Source and destination rectangles do not intersect. ##
1097# Canvas pixels could not be converted to bitmap.colorType() or bitmap.alphaType(). ##
1098# Canvas pixels are not readable; for instance, Canvas is document-based. ##
Cary Clark8032b982017-07-28 11:04:54 -04001099# bitmap pixels could not be allocated. ##
Cary Clarkf05bdda2017-08-24 12:59:48 -04001100# bitmap.rowBytes() is too small to contain one row of pixels. ##
Cary Clark8032b982017-07-28 11:04:54 -04001101##
1102
Cary Clarkbad5ad72017-08-03 17:14:08 -04001103#Param bitmap storage for pixels copied from Canvas ##
Cary Clark5538c132018-06-14 12:28:14 -04001104#Param srcX offset into readable pixels on x-axis; may be negative ##
1105#Param srcY offset into readable pixels on y-axis; may be negative ##
Cary Clark8032b982017-07-28 11:04:54 -04001106
Cary Clarkbad5ad72017-08-03 17:14:08 -04001107#Return true if pixels were copied ##
Cary Clark8032b982017-07-28 11:04:54 -04001108
1109#Example
Cary Clarkf05bdda2017-08-24 12:59:48 -04001110 #Description
Cary Clarkce101242017-09-01 15:51:02 -04001111 clear() takes Unpremultiplied input with Color_Alpha equal 0x80
Cary Clarkffb3d682018-05-17 12:17:28 -04001112 and RGB equal 0x55, 0xAA, 0xFF. RGB is multiplied by Color_Alpha
Cary Clarkce101242017-09-01 15:51:02 -04001113 to generate Premultiplied value 0x802B5580.
Cary Clarkf05bdda2017-08-24 12:59:48 -04001114 ##
Cary Clark8032b982017-07-28 11:04:54 -04001115void draw(SkCanvas* canvas) {
1116 canvas->clear(0x8055aaff);
1117 SkBitmap bitmap;
1118 bitmap.allocPixels(SkImageInfo::MakeN32Premul(1, 1));
1119 canvas->readPixels(bitmap, 0, 0);
1120 SkDebugf("pixel = %08x\n", bitmap.getAddr32(0, 0)[0]);
1121}
1122 #StdOut
1123 pixel = 802b5580
1124 ##
1125##
1126
Cary Clark2ade9972017-11-02 17:49:34 -04001127#SeeAlso peekPixels writePixels drawBitmap drawImage SkBitmap::readPixels SkPixmap::readPixels SkImage::readPixels SkSurface::readPixels
Cary Clark8032b982017-07-28 11:04:54 -04001128
1129##
1130
1131# ------------------------------------------------------------------------------
1132
1133#Method bool writePixels(const SkImageInfo& info, const void* pixels, size_t rowBytes, int x, int y)
Cary Clark78de7512018-02-07 07:27:09 -05001134#In Pixels
Cary Clarkab2621d2018-01-30 10:08:57 -05001135#Line # copies and converts rectangle of pixels to Canvas ##
Cary Clark154beea2017-10-26 07:58:48 -04001136Copies Rect from pixels to Canvas. Matrix and Clip are ignored.
1137Source Rect corners are (0, 0) and (info.width(), info.height()).
1138Destination Rect corners are (x, y) and
1139(imageInfo().width(), imageInfo().height()).
Cary Clark6fc50412017-09-21 12:31:06 -04001140
1141Copies each readable pixel intersecting both rectangles, without scaling,
Cary Clark154beea2017-10-26 07:58:48 -04001142converting to imageInfo().colorType() and imageInfo().alphaType() if required.
Cary Clark8032b982017-07-28 11:04:54 -04001143
Cary Clarkf05bdda2017-08-24 12:59:48 -04001144Pixels are writable when Device is raster, or backed by a GPU.
1145Pixels are not writable when SkCanvas is returned by SkDocument::beginPage,
1146returned by SkPictureRecorder::beginRecording, or Canvas is the base of a utility
Brian Osman46fe9c72018-03-09 15:44:34 -05001147class like SkDebugCanvas.
Cary Clark8032b982017-07-28 11:04:54 -04001148
Cary Clark2dc84ad2018-01-26 12:56:22 -05001149Pixel values are converted only if Color_Type and Alpha_Type
Cary Clarkf05bdda2017-08-24 12:59:48 -04001150do not match. Only pixels within both source and destination rectangles
Cary Clark154beea2017-10-26 07:58:48 -04001151are copied. Canvas pixels outside Rect intersection are unchanged.
Cary Clark8032b982017-07-28 11:04:54 -04001152
Cary Clarkf05bdda2017-08-24 12:59:48 -04001153Pass negative values for x or y to offset pixels to the left or
1154above Canvas pixels.
Cary Clark8032b982017-07-28 11:04:54 -04001155
1156Does not copy, and returns false if:
1157
1158#List
Cary Clarkf05bdda2017-08-24 12:59:48 -04001159# Source and destination rectangles do not intersect. ##
Cary Clarkac47b882018-01-11 10:35:44 -05001160# pixels could not be converted to Canvas imageInfo().colorType() or
1161 imageInfo().alphaType(). ##
Cary Clark8032b982017-07-28 11:04:54 -04001162# Canvas pixels are not writable; for instance, Canvas is document-based. ##
1163# rowBytes is too small to contain one row of pixels. ##
1164##
1165
Cary Clark2dc84ad2018-01-26 12:56:22 -05001166#Param info width, height, Color_Type, and Alpha_Type of pixels ##
Cary Clarkf05bdda2017-08-24 12:59:48 -04001167#Param pixels pixels to copy, of size info.height() times rowBytes, or larger ##
Cary Clarkd0530ba2017-09-14 11:25:39 -04001168#Param rowBytes size of one row of pixels; info.width() times pixel size, or larger ##
Cary Clark5538c132018-06-14 12:28:14 -04001169#Param x offset into Canvas writable pixels on x-axis; may be negative ##
1170#Param y offset into Canvas writable pixels on y-axis; may be negative ##
Cary Clark8032b982017-07-28 11:04:54 -04001171
Cary Clarkbad5ad72017-08-03 17:14:08 -04001172#Return true if pixels were written to Canvas ##
Cary Clark8032b982017-07-28 11:04:54 -04001173
1174#Example
1175 SkImageInfo imageInfo = SkImageInfo::MakeN32(256, 1, kPremul_SkAlphaType);
1176 for (int y = 0; y < 256; ++y) {
1177 uint32_t pixels[256];
1178 for (int x = 0; x < 256; ++x) {
1179 pixels[x] = SkColorSetARGB(x, x + y, x, x - y);
1180 }
1181 canvas->writePixels(imageInfo, &pixels, sizeof(pixels), 0, y);
1182 }
1183##
1184
Cary Clark2ade9972017-11-02 17:49:34 -04001185#SeeAlso readPixels drawBitmap drawImage SkBitmap::writePixels
Cary Clark8032b982017-07-28 11:04:54 -04001186
1187##
1188
1189# ------------------------------------------------------------------------------
1190
1191#Method bool writePixels(const SkBitmap& bitmap, int x, int y)
1192
Cary Clark154beea2017-10-26 07:58:48 -04001193Copies Rect from pixels to Canvas. Matrix and Clip are ignored.
1194Source Rect corners are (0, 0) and (bitmap.width(), bitmap.height()).
Cary Clark6fc50412017-09-21 12:31:06 -04001195
Cary Clark154beea2017-10-26 07:58:48 -04001196Destination Rect corners are (x, y) and
1197(imageInfo().width(), imageInfo().height()).
Cary Clark6fc50412017-09-21 12:31:06 -04001198
1199Copies each readable pixel intersecting both rectangles, without scaling,
Cary Clark154beea2017-10-26 07:58:48 -04001200converting to imageInfo().colorType() and imageInfo().alphaType() if required.
Cary Clark8032b982017-07-28 11:04:54 -04001201
Cary Clarkf05bdda2017-08-24 12:59:48 -04001202Pixels are writable when Device is raster, or backed by a GPU.
1203Pixels are not writable when SkCanvas is returned by SkDocument::beginPage,
1204returned by SkPictureRecorder::beginRecording, or Canvas is the base of a utility
Brian Osman46fe9c72018-03-09 15:44:34 -05001205class like SkDebugCanvas.
Cary Clark8032b982017-07-28 11:04:54 -04001206
Cary Clark2dc84ad2018-01-26 12:56:22 -05001207Pixel values are converted only if Color_Type and Alpha_Type
Cary Clarkf05bdda2017-08-24 12:59:48 -04001208do not match. Only pixels within both source and destination rectangles
Cary Clark154beea2017-10-26 07:58:48 -04001209are copied. Canvas pixels outside Rect intersection are unchanged.
Cary Clark8032b982017-07-28 11:04:54 -04001210
Cary Clarkf05bdda2017-08-24 12:59:48 -04001211Pass negative values for x or y to offset pixels to the left or
1212above Canvas pixels.
Cary Clark8032b982017-07-28 11:04:54 -04001213
1214Does not copy, and returns false if:
1215
1216#List
Cary Clarkf05bdda2017-08-24 12:59:48 -04001217# Source and destination rectangles do not intersect. ##
Cary Clark8032b982017-07-28 11:04:54 -04001218# bitmap does not have allocated pixels. ##
Cary Clarkac47b882018-01-11 10:35:44 -05001219# bitmap pixels could not be converted to Canvas imageInfo().colorType() or
1220 imageInfo().alphaType(). ##
Cary Clarkce101242017-09-01 15:51:02 -04001221# Canvas pixels are not writable; for instance, Canvas is document based. ##
Cary Clark8032b982017-07-28 11:04:54 -04001222# bitmap pixels are inaccessible; for instance, bitmap wraps a texture. ##
1223##
1224
Cary Clarkbad5ad72017-08-03 17:14:08 -04001225#Param bitmap contains pixels copied to Canvas ##
Cary Clarkf05bdda2017-08-24 12:59:48 -04001226#Param x offset into Canvas writable pixels in x; may be negative ##
1227#Param y offset into Canvas writable pixels in y; may be negative ##
Cary Clark8032b982017-07-28 11:04:54 -04001228
Cary Clarkbad5ad72017-08-03 17:14:08 -04001229#Return true if pixels were written to Canvas ##
Cary Clark8032b982017-07-28 11:04:54 -04001230
1231#Example
1232void draw(SkCanvas* canvas) {
1233 SkImageInfo imageInfo = SkImageInfo::MakeN32Premul(2, 2);
1234 SkBitmap bitmap;
1235 bitmap.setInfo(imageInfo);
1236 uint32_t pixels[4];
1237 bitmap.setPixels(pixels);
1238 for (int y = 0; y < 256; y += 2) {
1239 for (int x = 0; x < 256; x += 2) {
1240 pixels[0] = SkColorSetRGB(x, y, x | y);
1241 pixels[1] = SkColorSetRGB(x ^ y, y, x);
1242 pixels[2] = SkColorSetRGB(x, x & y, y);
1243 pixels[3] = SkColorSetRGB(~x, ~y, x);
1244 canvas->writePixels(bitmap, x, y);
1245 }
1246 }
1247}
1248##
1249
Cary Clark2ade9972017-11-02 17:49:34 -04001250#SeeAlso readPixels drawBitmap drawImage SkBitmap::writePixels
Cary Clark8032b982017-07-28 11:04:54 -04001251
1252##
1253
1254# ------------------------------------------------------------------------------
Cary Clark08895c42018-02-01 09:37:32 -05001255#Subtopic State_Stack
1256#Line # stack of state for hierarchical drawing ##
Cary Clark8032b982017-07-28 11:04:54 -04001257
1258Canvas maintains a stack of state that allows hierarchical drawing, commonly used
Cary Clarkbad5ad72017-08-03 17:14:08 -04001259to implement windows and views. The initial state has an identity matrix and and
1260an infinite clip. Even with a wide-open clip, drawing is constrained by the
1261bounds of the Canvas Surface or Device.
Cary Clark8032b982017-07-28 11:04:54 -04001262
Cary Clark939fd6c2018-07-12 08:40:13 -04001263Canvas savable state consists of Clip and Matrix.
Cary Clark8032b982017-07-28 11:04:54 -04001264Clip describes the area that may be drawn to.
1265Matrix transforms the geometry.
Cary Clark8032b982017-07-28 11:04:54 -04001266
1267save(), saveLayer, saveLayerPreserveLCDTextRequests, and saveLayerAlpha
1268save state and return the depth of the stack.
1269
Cary Clarkbad5ad72017-08-03 17:14:08 -04001270restore(), restoreToCount, and ~SkCanvas() revert state to its value when saved.
Cary Clark8032b982017-07-28 11:04:54 -04001271
1272Each state on the stack intersects Clip with the previous Clip,
1273and concatenates Matrix with the previous Matrix.
1274The intersected Clip makes the drawing area the same or smaller;
1275the concatenated Matrix may move the origin and potentially scale or rotate
1276the coordinate space.
1277
1278Canvas does not require balancing the state stack but it is a good idea
1279to do so. Calling save() without restore() will eventually cause Skia to fail;
1280mismatched save() and restore() create hard to find bugs.
1281
1282It is not possible to use state to draw outside of the clip defined by the
1283previous state.
1284
1285#Example
1286#Description
1287Draw to ever smaller clips; then restore drawing to full canvas.
1288Note that the second clipRect is not permitted to enlarge Clip.
1289##
1290#Height 160
Cary Clarkbad5ad72017-08-03 17:14:08 -04001291void draw(SkCanvas* canvas) {
1292 SkPaint paint;
Herb Derbyefe39bc2018-05-01 17:06:20 -04001293 canvas->save(); // records stack depth to restore
Cary Clarkbad5ad72017-08-03 17:14:08 -04001294 canvas->clipRect(SkRect::MakeWH(100, 100)); // constrains drawing to clip
1295 canvas->clear(SK_ColorRED); // draws to limit of clip
Herb Derbyefe39bc2018-05-01 17:06:20 -04001296 canvas->save(); // records stack depth to restore
Cary Clarkbad5ad72017-08-03 17:14:08 -04001297 canvas->clipRect(SkRect::MakeWH(50, 150)); // Rect below 100 is ignored
1298 canvas->clear(SK_ColorBLUE); // draws to smaller clip
1299 canvas->restore(); // enlarges clip
1300 canvas->drawLine(20, 20, 150, 150, paint); // line below 100 is not drawn
1301 canvas->restore(); // enlarges clip
1302 canvas->drawLine(150, 20, 50, 120, paint); // line below 100 is drawn
Cary Clark8032b982017-07-28 11:04:54 -04001303}
Herb Derbyefe39bc2018-05-01 17:06:20 -04001304##
Cary Clark8032b982017-07-28 11:04:54 -04001305
1306Each Clip uses the current Matrix for its coordinates.
1307
1308#Example
1309#Description
1310While clipRect is given the same rectangle twice, Matrix makes the second
1311clipRect draw at half the size of the first.
1312##
1313#Height 128
Cary Clarkbad5ad72017-08-03 17:14:08 -04001314void draw(SkCanvas* canvas) {
1315 canvas->clipRect(SkRect::MakeWH(100, 100));
1316 canvas->clear(SK_ColorRED);
1317 canvas->scale(.5, .5);
1318 canvas->clipRect(SkRect::MakeWH(100, 100));
1319 canvas->clear(SK_ColorBLUE);
Cary Clark8032b982017-07-28 11:04:54 -04001320}
1321##
1322
1323#SeeAlso save() saveLayer saveLayerPreserveLCDTextRequests saveLayerAlpha restore() restoreToCount
1324
1325#Method int save()
1326
Cary Clarkab2621d2018-01-30 10:08:57 -05001327#In State_Stack
1328#Line # saves Clip and Matrix on stack ##
Cary Clark939fd6c2018-07-12 08:40:13 -04001329Saves Matrix and Clip.
1330Calling restore() discards changes to Matrix and Clip,
1331restoring the Matrix and Clip to their state when save() was called.
Cary Clark8032b982017-07-28 11:04:54 -04001332
Cary Clarkbad5ad72017-08-03 17:14:08 -04001333Matrix may be changed by translate(), scale(), rotate(), skew(), concat(), setMatrix,
1334and resetMatrix. Clip may be changed by clipRect, clipRRect, clipPath, clipRegion.
Cary Clark8032b982017-07-28 11:04:54 -04001335
Cary Clarkbad5ad72017-08-03 17:14:08 -04001336Saved Canvas state is put on a stack; multiple calls to save() should be balance
1337by an equal number of calls to restore().
Cary Clark8032b982017-07-28 11:04:54 -04001338
1339Call restoreToCount with result to restore this and subsequent saves.
1340
Cary Clarkbad5ad72017-08-03 17:14:08 -04001341#Return depth of saved stack ##
Cary Clark8032b982017-07-28 11:04:54 -04001342
1343#Example
Herb Derbyefe39bc2018-05-01 17:06:20 -04001344#Description
Cary Clark8032b982017-07-28 11:04:54 -04001345The black square is translated 50 pixels down and to the right.
1346Restoring Canvas state removes translate() from Canvas stack;
1347the red square is not translated, and is drawn at the origin.
1348##
1349#Height 100
1350void draw(SkCanvas* canvas) {
1351 SkPaint paint;
1352 SkRect rect = { 0, 0, 25, 25 };
1353 canvas->drawRect(rect, paint);
1354 canvas->save();
1355 canvas->translate(50, 50);
1356 canvas->drawRect(rect, paint);
1357 canvas->restore();
1358 paint.setColor(SK_ColorRED);
1359 canvas->drawRect(rect, paint);
1360}
1361##
1362
Cary Clark2ade9972017-11-02 17:49:34 -04001363#SeeAlso saveLayer saveLayerPreserveLCDTextRequests saveLayerAlpha restore() restoreToCount
Cary Clark8032b982017-07-28 11:04:54 -04001364
1365##
1366
1367# ------------------------------------------------------------------------------
Cary Clark8032b982017-07-28 11:04:54 -04001368
1369#Method void restore()
1370
Cary Clarkab2621d2018-01-30 10:08:57 -05001371#In State_Stack
1372#Line # restores changes to Clip and Matrix, pops save stack ##
Cary Clark939fd6c2018-07-12 08:40:13 -04001373Removes changes to Matrix and Clip since Canvas state was
Herb Derbyefe39bc2018-05-01 17:06:20 -04001374last saved. The state is removed from the stack.
Cary Clark8032b982017-07-28 11:04:54 -04001375
Herb Derbyefe39bc2018-05-01 17:06:20 -04001376Does nothing if the stack is empty.
Cary Clark8032b982017-07-28 11:04:54 -04001377
1378#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04001379void draw(SkCanvas* canvas) {
1380 SkCanvas simple;
1381 SkDebugf("depth = %d\n", simple.getSaveCount());
1382 simple.restore();
1383 SkDebugf("depth = %d\n", simple.getSaveCount());
Cary Clark8032b982017-07-28 11:04:54 -04001384}
1385##
1386
Cary Clark2ade9972017-11-02 17:49:34 -04001387#SeeAlso save() saveLayer saveLayerPreserveLCDTextRequests saveLayerAlpha restoreToCount
1388
Cary Clark8032b982017-07-28 11:04:54 -04001389##
1390
1391# ------------------------------------------------------------------------------
1392
1393#Method int getSaveCount() const
1394
Cary Clarkab2621d2018-01-30 10:08:57 -05001395#In State_Stack
1396#Line # returns depth of stack containing Clip and Matrix ##
Cary Clark939fd6c2018-07-12 08:40:13 -04001397Returns the number of saved states, each containing: Matrix and Clip.
Herb Derbyefe39bc2018-05-01 17:06:20 -04001398Equals the number of save() calls less the number of restore() calls plus one.
Cary Clark8032b982017-07-28 11:04:54 -04001399The save count of a new canvas is one.
1400
Cary Clarkbad5ad72017-08-03 17:14:08 -04001401#Return depth of save state stack ##
Cary Clark8032b982017-07-28 11:04:54 -04001402
1403#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04001404void draw(SkCanvas* canvas) {
1405 SkCanvas simple;
1406 SkDebugf("depth = %d\n", simple.getSaveCount());
1407 simple.save();
1408 SkDebugf("depth = %d\n", simple.getSaveCount());
1409 simple.restore();
1410 SkDebugf("depth = %d\n", simple.getSaveCount());
Cary Clark8032b982017-07-28 11:04:54 -04001411}
1412#StdOut
Cary Clarkbad5ad72017-08-03 17:14:08 -04001413depth = 1
1414depth = 2
Cary Clark8032b982017-07-28 11:04:54 -04001415depth = 1
1416##
1417##
1418
Cary Clark2ade9972017-11-02 17:49:34 -04001419#SeeAlso save() restore() restoreToCount
1420
Cary Clark8032b982017-07-28 11:04:54 -04001421##
1422
1423# ------------------------------------------------------------------------------
1424
1425#Method void restoreToCount(int saveCount)
1426
Cary Clarkab2621d2018-01-30 10:08:57 -05001427#In State_Stack
1428#Line # restores changes to Clip and Matrix to given depth ##
Cary Clark939fd6c2018-07-12 08:40:13 -04001429Restores state to Matrix and Clip values when save(), saveLayer,
Cary Clarkbad5ad72017-08-03 17:14:08 -04001430saveLayerPreserveLCDTextRequests, or saveLayerAlpha returned saveCount.
Cary Clark8032b982017-07-28 11:04:54 -04001431
Herb Derbyefe39bc2018-05-01 17:06:20 -04001432Does nothing if saveCount is greater than state stack count.
Cary Clark8032b982017-07-28 11:04:54 -04001433Restores state to initial values if saveCount is less than or equal to one.
1434
Cary Clarkbad5ad72017-08-03 17:14:08 -04001435#Param saveCount depth of state stack to restore ##
Cary Clark8032b982017-07-28 11:04:54 -04001436
1437#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04001438void draw(SkCanvas* canvas) {
1439 SkDebugf("depth = %d\n", canvas->getSaveCount());
1440 canvas->save();
1441 canvas->save();
1442 SkDebugf("depth = %d\n", canvas->getSaveCount());
1443 canvas->restoreToCount(0);
1444 SkDebugf("depth = %d\n", canvas->getSaveCount());
Cary Clark8032b982017-07-28 11:04:54 -04001445}
1446#StdOut
Cary Clarkbad5ad72017-08-03 17:14:08 -04001447depth = 1
1448depth = 3
Cary Clark8032b982017-07-28 11:04:54 -04001449depth = 1
1450##
1451##
1452
Herb Derbyefe39bc2018-05-01 17:06:20 -04001453#SeeAlso restore() getSaveCount save()
Cary Clark2ade9972017-11-02 17:49:34 -04001454
Cary Clark8032b982017-07-28 11:04:54 -04001455##
1456
Cary Clark08895c42018-02-01 09:37:32 -05001457#Subtopic State_Stack ##
Cary Clark8032b982017-07-28 11:04:54 -04001458
1459# ------------------------------------------------------------------------------
Cary Clarkce101242017-09-01 15:51:02 -04001460
Cary Clark08895c42018-02-01 09:37:32 -05001461#Subtopic Layer
Cary Clarkd0530ba2017-09-14 11:25:39 -04001462#Substitute layer
Cary Clarkce101242017-09-01 15:51:02 -04001463#Alias Layers
Cary Clark137b8742018-05-30 09:21:49 -04001464#Substitute layers
1465##
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 Clark939fd6c2018-07-12 08:40:13 -04001482Saves Matrix and Clip, and allocates a Bitmap for subsequent drawing.
1483Calling restore() discards changes to Matrix and Clip, and draws the Bitmap.
Cary Clarkce101242017-09-01 15:51:02 -04001484
1485Matrix may be changed by translate(), scale(), rotate(), skew(), concat(),
Herb Derbyefe39bc2018-05-01 17:06:20 -04001486setMatrix, and resetMatrix. Clip may be changed by clipRect, clipRRect,
Cary Clarkce101242017-09-01 15:51:02 -04001487clipPath, clipRegion.
1488
1489Rect bounds suggests but does not define the Bitmap size. To clip drawing to
1490a specific rectangle, use clipRect.
1491
1492Optional Paint paint applies Color_Alpha, Color_Filter, Image_Filter, and
1493Blend_Mode when restore() is called.
1494
1495Call restoreToCount with returned value to restore this and subsequent saves.
1496
1497#Param bounds hint to limit the size of the Layer; may be nullptr ##
1498#Param paint graphics state for Layer; may be nullptr ##
1499
1500#Return depth of saved stack ##
1501
1502#Example
1503#Description
1504Rectangles are blurred by Image_Filter when restore() draws Layer to main
1505Canvas.
1506##
1507#Height 128
Cary Clark81abc432018-06-25 16:30:08 -04001508#Function
1509###$
1510#include "SkBlurImageFilter.h"
1511$$$#
1512##
1513
Cary Clarkce101242017-09-01 15:51:02 -04001514void draw(SkCanvas* canvas) {
1515 SkPaint paint, blur;
Cary Clarka560c472017-11-27 10:44:06 -05001516 blur.setImageFilter(SkBlurImageFilter::Make(3, 3, nullptr));
Cary Clarkce101242017-09-01 15:51:02 -04001517 canvas->saveLayer(nullptr, &blur);
1518 SkRect rect = { 25, 25, 50, 50};
1519 canvas->drawRect(rect, paint);
1520 canvas->translate(50, 50);
1521 paint.setColor(SK_ColorRED);
1522 canvas->drawRect(rect, paint);
1523 canvas->restore();
1524}
1525##
1526
Cary Clark2ade9972017-11-02 17:49:34 -04001527#SeeAlso save() restore() saveLayer saveLayerPreserveLCDTextRequests saveLayerAlpha SaveLayerRec
Cary Clarkce101242017-09-01 15:51:02 -04001528
1529##
1530
Herb Derbyefe39bc2018-05-01 17:06:20 -04001531#Method int saveLayer(const SkRect& bounds, const SkPaint* paint)
Cary Clarkce101242017-09-01 15:51:02 -04001532
Cary Clarkab2621d2018-01-30 10:08:57 -05001533#In Layer
Cary Clark939fd6c2018-07-12 08:40:13 -04001534Saves Matrix and Clip, and allocates a Bitmap for subsequent drawing.
1535Calling restore() discards changes to Matrix and Clip, and draws the Bitmap.
Cary Clarkce101242017-09-01 15:51:02 -04001536
1537Matrix may be changed by translate(), scale(), rotate(), skew(), concat(),
1538setMatrix, and resetMatrix. Clip may be changed by clipRect, clipRRect,
1539clipPath, clipRegion.
1540
1541Rect bounds suggests but does not define the Layer size. To clip drawing to
1542a specific rectangle, use clipRect.
1543
1544Optional Paint paint applies Color_Alpha, Color_Filter, Image_Filter, and
1545Blend_Mode when restore() is called.
1546
1547Call restoreToCount with returned value to restore this and subsequent saves.
1548
1549#Param bounds hint to limit the size of Layer; may be nullptr ##
1550#Param paint graphics state for Layer; may be nullptr ##
1551
1552#Return depth of saved stack ##
1553
1554#Example
1555#Description
1556Rectangles are blurred by Image_Filter when restore() draws Layer to main Canvas.
Herb Derbyefe39bc2018-05-01 17:06:20 -04001557The red rectangle is clipped; it does not fully fit on Layer.
Cary Clarkce101242017-09-01 15:51:02 -04001558Image_Filter blurs past edge of Layer so red rectangle is blurred on all sides.
1559##
1560#Height 128
Cary Clark81abc432018-06-25 16:30:08 -04001561#Function
1562###$
1563#include "SkBlurImageFilter.h"
1564$$$#
1565##
1566
Cary Clarkce101242017-09-01 15:51:02 -04001567void draw(SkCanvas* canvas) {
1568 SkPaint paint, blur;
Cary Clarka560c472017-11-27 10:44:06 -05001569 blur.setImageFilter(SkBlurImageFilter::Make(3, 3, nullptr));
Cary Clarkce101242017-09-01 15:51:02 -04001570 canvas->saveLayer(SkRect::MakeWH(90, 90), &blur);
1571 SkRect rect = { 25, 25, 50, 50};
1572 canvas->drawRect(rect, paint);
1573 canvas->translate(50, 50);
1574 paint.setColor(SK_ColorRED);
1575 canvas->drawRect(rect, paint);
1576 canvas->restore();
1577}
1578##
1579
Cary Clark2ade9972017-11-02 17:49:34 -04001580#SeeAlso save() restore() saveLayerPreserveLCDTextRequests saveLayerAlpha SaveLayerRec
Cary Clarkce101242017-09-01 15:51:02 -04001581
1582##
1583
1584#Method int saveLayerPreserveLCDTextRequests(const SkRect* bounds, const SkPaint* paint)
1585
Cary Clarkab2621d2018-01-30 10:08:57 -05001586#In Layer
1587#Line # saves Clip and Matrix on stack; creates Layer for LCD text ##
Cary Clark939fd6c2018-07-12 08:40:13 -04001588Saves Matrix and Clip, and allocates a Bitmap for subsequent drawing.
Cary Clarkce101242017-09-01 15:51:02 -04001589LCD_Text is preserved when the Layer is drawn to the prior Layer.
1590
Cary Clark939fd6c2018-07-12 08:40:13 -04001591Calling restore() discards changes to Matrix and Clip, and draws Layer.
Cary Clarkce101242017-09-01 15:51:02 -04001592
1593Matrix may be changed by translate(), scale(), rotate(), skew(), concat(),
1594setMatrix, and resetMatrix. Clip may be changed by clipRect, clipRRect,
1595clipPath, clipRegion.
Herb Derbyefe39bc2018-05-01 17:06:20 -04001596
Cary Clarkce101242017-09-01 15:51:02 -04001597Rect bounds suggests but does not define the Layer size. To clip drawing to
1598a specific rectangle, use clipRect.
1599
1600Optional Paint paint applies Color_Alpha, Color_Filter, Image_Filter, and
1601Blend_Mode when restore() is called.
1602
1603Call restoreToCount with returned value to restore this and subsequent saves.
1604
1605Draw text on an opaque background so that LCD_Text blends correctly with the
1606prior Layer. LCD_Text drawn on a background with transparency may result in
Cary Clark6fc50412017-09-21 12:31:06 -04001607incorrect blending.
Cary Clarkce101242017-09-01 15:51:02 -04001608
1609#Param bounds hint to limit the size of Layer; may be nullptr ##
1610#Param paint graphics state for Layer; may be nullptr ##
1611
1612#Return depth of saved stack ##
1613
1614#Example
1615 SkPaint paint;
1616 paint.setAntiAlias(true);
1617 paint.setLCDRenderText(true);
1618 paint.setTextSize(20);
1619 for (auto preserve : { false, true } ) {
1620 preserve ? canvas->saveLayerPreserveLCDTextRequests(nullptr, nullptr)
1621 : canvas->saveLayer(nullptr, nullptr);
1622 SkPaint p;
1623 p.setColor(SK_ColorWHITE);
1624 // Comment out the next line to draw on a non-opaque background.
1625 canvas->drawRect(SkRect::MakeLTRB(25, 40, 200, 70), p);
1626 canvas->drawString("Hamburgefons", 30, 60, paint);
1627
1628 p.setColor(0xFFCCCCCC);
1629 canvas->drawRect(SkRect::MakeLTRB(25, 70, 200, 100), p);
1630 canvas->drawString("Hamburgefons", 30, 90, paint);
1631
1632 canvas->restore();
1633 canvas->translate(0, 80);
1634 }
1635 ##
1636
Cary Clark2ade9972017-11-02 17:49:34 -04001637#SeeAlso save() restore() saveLayer saveLayerAlpha SaveLayerRec
Cary Clarkce101242017-09-01 15:51:02 -04001638
1639##
1640
1641#Method int saveLayerAlpha(const SkRect* bounds, U8CPU alpha)
1642
Cary Clarkab2621d2018-01-30 10:08:57 -05001643#In Layer
1644#Line # saves Clip and Matrix on stack; creates Layer; sets opacity ##
Cary Clark939fd6c2018-07-12 08:40:13 -04001645Saves Matrix and Clip, and allocates Bitmap for subsequent drawing.
Cary Clarkce101242017-09-01 15:51:02 -04001646
Cary Clark939fd6c2018-07-12 08:40:13 -04001647Calling restore() discards changes to Matrix and Clip,
Cary Clarkce101242017-09-01 15:51:02 -04001648and blends Layer with alpha opacity onto prior Layer.
1649
1650Matrix may be changed by translate(), scale(), rotate(), skew(), concat(),
1651setMatrix, and resetMatrix. Clip may be changed by clipRect, clipRRect,
1652clipPath, clipRegion.
1653
1654Rect bounds suggests but does not define Layer size. To clip drawing to
1655a specific rectangle, use clipRect.
1656
1657alpha of zero is fully transparent, 255 is fully opaque.
1658
1659Call restoreToCount with returned value to restore this and subsequent saves.
1660
1661#Param bounds hint to limit the size of Layer; may be nullptr ##
1662#Param alpha opacity of Layer ##
1663
1664#Return depth of saved stack ##
1665
1666#Example
1667 SkPaint paint;
1668 paint.setColor(SK_ColorRED);
1669 canvas->drawCircle(50, 50, 50, paint);
1670 canvas->saveLayerAlpha(nullptr, 128);
1671 paint.setColor(SK_ColorBLUE);
1672 canvas->drawCircle(100, 50, 50, paint);
1673 paint.setColor(SK_ColorGREEN);
1674 paint.setAlpha(128);
1675 canvas->drawCircle(75, 90, 50, paint);
1676 canvas->restore();
1677##
1678
Cary Clark2ade9972017-11-02 17:49:34 -04001679#SeeAlso save() restore() saveLayer saveLayerPreserveLCDTextRequests SaveLayerRec
Cary Clarkce101242017-09-01 15:51:02 -04001680
1681##
1682
Cary Clarkd98f78c2018-04-26 08:32:37 -04001683#Enum SaveLayerFlagsSet
Cary Clark08895c42018-02-01 09:37:32 -05001684#Line # sets SaveLayerRec options ##
Cary Clarkce101242017-09-01 15:51:02 -04001685#Code
Cary Clarkd98f78c2018-04-26 08:32:37 -04001686 enum SaveLayerFlagsSet {
Cary Clarkce101242017-09-01 15:51:02 -04001687 kPreserveLCDText_SaveLayerFlag = 1 << 1,
1688 kInitWithPrevious_SaveLayerFlag = 1 << 2,
Mike Reed910ca0f2018-04-25 13:04:05 -04001689 kMaskAgainstCoverage_EXPERIMENTAL_DONT_USE_SaveLayerFlag = 1 << 3,
Cary Clarkce101242017-09-01 15:51:02 -04001690 kDontClipToLayer_Legacy_SaveLayerFlag = kDontClipToLayer_PrivateSaveLayerFlag,
1691 };
Cary Clarkd98f78c2018-04-26 08:32:37 -04001692
1693 typedef uint32_t SaveLayerFlags;
Cary Clarkce101242017-09-01 15:51:02 -04001694##
1695
Cary Clark682c58d2018-05-16 07:07:07 -04001696
1697#Typedef uint32_t SaveLayerFlags
1698#Line # options for SaveLayerRec ##
Cary Clark137b8742018-05-30 09:21:49 -04001699##
Cary Clark682c58d2018-05-16 07:07:07 -04001700
Cary Clarkce101242017-09-01 15:51:02 -04001701SaveLayerFlags provides options that may be used in any combination in SaveLayerRec,
Cary Clark682c58d2018-05-16 07:07:07 -04001702defining how Layer allocated by saveLayer operates. It may be set to zero,
1703kPreserveLCDText_SaveLayerFlag, kInitWithPrevious_SaveLayerFlag, or both flags.
1704
Cary Clarkce101242017-09-01 15:51:02 -04001705#Const kPreserveLCDText_SaveLayerFlag 2
Cary Clark682c58d2018-05-16 07:07:07 -04001706#Line # creates Layer for LCD text ##
Cary Clarkce101242017-09-01 15:51:02 -04001707 Creates Layer for LCD text. Flag is ignored if Layer Paint contains
1708 Image_Filter or Color_Filter.
1709##
1710
1711#Const kInitWithPrevious_SaveLayerFlag 4
Cary Clark682c58d2018-05-16 07:07:07 -04001712#Line # initializes with previous contents ##
Cary Clarkce101242017-09-01 15:51:02 -04001713 Initializes Layer with the contents of the previous Layer.
1714##
1715
Mike Reed910ca0f2018-04-25 13:04:05 -04001716#Const kMaskAgainstCoverage_EXPERIMENTAL_DONT_USE_SaveLayerFlag 8
Cary Clark682c58d2018-05-16 07:07:07 -04001717#Experimental do not use
Mike Reed910ca0f2018-04-25 13:04:05 -04001718##
1719
Cary Clarkce101242017-09-01 15:51:02 -04001720#Const kDontClipToLayer_Legacy_SaveLayerFlag 0x80000000
Cary Clark4855f782018-02-06 09:41:53 -05001721#Deprecated soon
Cary Clarkce101242017-09-01 15:51:02 -04001722##
1723
1724#Example
1725#Height 160
1726#Description
1727Canvas Layer captures red and blue circles scaled up by four.
Herb Derbyefe39bc2018-05-01 17:06:20 -04001728scalePaint blends Layer back with transparency.
Cary Clarkce101242017-09-01 15:51:02 -04001729##
1730void draw(SkCanvas* canvas) {
1731 SkPaint redPaint, bluePaint, scalePaint;
1732 redPaint.setColor(SK_ColorRED);
1733 canvas->drawCircle(21, 21, 8, redPaint);
1734 bluePaint.setColor(SK_ColorBLUE);
1735 canvas->drawCircle(31, 21, 8, bluePaint);
1736 SkMatrix matrix;
1737 matrix.setScale(4, 4);
1738 scalePaint.setAlpha(0x40);
1739 scalePaint.setImageFilter(
1740 SkImageFilter::MakeMatrixFilter(matrix, kNone_SkFilterQuality, nullptr));
1741 SkCanvas::SaveLayerRec saveLayerRec(nullptr, &scalePaint,
Herb Derbyefe39bc2018-05-01 17:06:20 -04001742 SkCanvas::kInitWithPrevious_SaveLayerFlag);
Cary Clarkce101242017-09-01 15:51:02 -04001743 canvas->saveLayer(saveLayerRec);
1744 canvas->restore();
1745}
1746##
1747
Cary Clark2ade9972017-11-02 17:49:34 -04001748#SeeAlso save() restore() saveLayer saveLayerPreserveLCDTextRequests saveLayerAlpha SaveLayerRec
Cary Clarkce101242017-09-01 15:51:02 -04001749
1750#Enum ##
1751
Cary Clark682c58d2018-05-16 07:07:07 -04001752#Subtopic SaveLayerRec
1753#Line # contains the state used to create the Layer ##
Cary Clarka560c472017-11-27 10:44:06 -05001754
Cary Clarkce101242017-09-01 15:51:02 -04001755#Struct SaveLayerRec
Cary Clark08895c42018-02-01 09:37:32 -05001756#Line # contains the state used to create the Layer ##
Cary Clark682c58d2018-05-16 07:07:07 -04001757
Cary Clarkce101242017-09-01 15:51:02 -04001758#Code
1759 struct SaveLayerRec {
1760 SaveLayerRec*(...
1761
1762 const SkRect* fBounds;
1763 const SkPaint* fPaint;
1764 const SkImageFilter* fBackdrop;
1765 SaveLayerFlags fSaveLayerFlags;
1766 };
1767##
1768
Cary Clark137b8742018-05-30 09:21:49 -04001769SaveLayerRec contains the state used to create the Layer.
1770
Cary Clark682c58d2018-05-16 07:07:07 -04001771#Subtopic Overview
1772#Populate
1773##
1774
1775#Subtopic Member
1776#Populate
1777##
Cary Clarkce101242017-09-01 15:51:02 -04001778
1779#Member const SkRect* fBounds
Cary Clark682c58d2018-05-16 07:07:07 -04001780#Line # hints at Layer size limit ##
Cary Clarkce101242017-09-01 15:51:02 -04001781 fBounds is used as a hint to limit the size of Layer; may be nullptr.
1782 fBounds suggests but does not define Layer size. To clip drawing to
1783 a specific rectangle, use clipRect.
1784##
1785
1786#Member const SkPaint* fPaint
Cary Clark682c58d2018-05-16 07:07:07 -04001787#Line # modifies overlay ##
Cary Clarkce101242017-09-01 15:51:02 -04001788 fPaint modifies how Layer overlays the prior Layer; may be nullptr.
1789 Color_Alpha, Blend_Mode, Color_Filter, Draw_Looper, Image_Filter, and
1790 Mask_Filter affect Layer draw.
1791##
1792
1793#Member const SkImageFilter* fBackdrop
Cary Clark682c58d2018-05-16 07:07:07 -04001794#Line # applies Image_Filter to prior Layer ##
Cary Clarkce101242017-09-01 15:51:02 -04001795 fBackdrop applies Image_Filter to the prior Layer when copying to the Layer;
1796 may be nullptr. Use kInitWithPrevious_SaveLayerFlag to copy the
1797 prior Layer without an Image_Filter.
1798##
1799
1800#Member const SkImage* fClipMask
Cary Clark682c58d2018-05-16 07:07:07 -04001801#Line # clips Layer with Mask_Alpha ##
Cary Clarkce101242017-09-01 15:51:02 -04001802 restore() clips Layer by the Color_Alpha channel of fClipMask when
1803 Layer is copied to Device. fClipMask may be nullptr. .
1804##
1805
1806#Member const SkMatrix* fClipMatrix
Cary Clark682c58d2018-05-16 07:07:07 -04001807#Line # transforms Mask_Alpha used to clip ##
Herb Derbyefe39bc2018-05-01 17:06:20 -04001808 fClipMatrix transforms fClipMask before it clips Layer. If
Cary Clarkce101242017-09-01 15:51:02 -04001809 fClipMask describes a translucent gradient, it may be scaled and rotated
1810 without introducing artifacts. fClipMatrix may be nullptr.
1811##
1812
1813#Member SaveLayerFlags fSaveLayerFlags
Cary Clark682c58d2018-05-16 07:07:07 -04001814#Line # preserves LCD Text, creates with prior Layer contents ##
Cary Clarkce101242017-09-01 15:51:02 -04001815 fSaveLayerFlags are used to create Layer without transparency,
1816 create Layer for LCD text, and to create Layer with the
1817 contents of the previous Layer.
1818##
1819
1820#Example
1821#Height 160
1822#Description
Cary Clarkffb3d682018-05-17 12:17:28 -04001823Canvas Layer captures a red Anti_Aliased circle and a blue Aliased circle scaled
Cary Clarkce101242017-09-01 15:51:02 -04001824up by four. After drawing another red circle without scaling on top, the Layer is
Herb Derbyefe39bc2018-05-01 17:06:20 -04001825transferred to the main canvas.
Cary Clarkce101242017-09-01 15:51:02 -04001826##
1827void draw(SkCanvas* canvas) {
1828 SkPaint redPaint, bluePaint;
1829 redPaint.setAntiAlias(true);
1830 redPaint.setColor(SK_ColorRED);
1831 canvas->drawCircle(21, 21, 8, redPaint);
1832 bluePaint.setColor(SK_ColorBLUE);
1833 canvas->drawCircle(31, 21, 8, bluePaint);
1834 SkMatrix matrix;
1835 matrix.setScale(4, 4);
1836 auto scaler = SkImageFilter::MakeMatrixFilter(matrix, kNone_SkFilterQuality, nullptr);
Herb Derbyefe39bc2018-05-01 17:06:20 -04001837 SkCanvas::SaveLayerRec saveLayerRec(nullptr, nullptr, scaler.get(), 0);
Cary Clarkce101242017-09-01 15:51:02 -04001838 canvas->saveLayer(saveLayerRec);
1839 canvas->drawCircle(125, 85, 8, redPaint);
1840 canvas->restore();
1841}
1842##
1843
Cary Clark682c58d2018-05-16 07:07:07 -04001844#Subtopic Constructor
1845#Populate
1846##
Cary Clarkce101242017-09-01 15:51:02 -04001847
Cary Clark682c58d2018-05-16 07:07:07 -04001848#Method SaveLayerRec()
1849#Line # constructs SaveLayerRec ##
Cary Clarkce101242017-09-01 15:51:02 -04001850Sets fBounds, fPaint, and fBackdrop to nullptr. Clears fSaveLayerFlags.
1851
1852#Return empty SaveLayerRec ##
1853
1854#Example
1855 SkCanvas::SaveLayerRec rec1;
Mike Kleine083f7c2018-02-07 12:54:27 -05001856 rec1.fSaveLayerFlags = SkCanvas::kPreserveLCDText_SaveLayerFlag;
1857 SkCanvas::SaveLayerRec rec2(nullptr, nullptr, SkCanvas::kPreserveLCDText_SaveLayerFlag);
Cary Clarkce101242017-09-01 15:51:02 -04001858 SkDebugf("rec1 %c= rec2\n", rec1.fBounds == rec2.fBounds
1859 && rec1.fPaint == rec2.fPaint
1860 && rec1.fBackdrop == rec2.fBackdrop
1861 && rec1.fSaveLayerFlags == rec2.fSaveLayerFlags ? '=' : '!');
1862 #StdOut
1863 rec1 == rec2
1864 ##
1865##
1866
Cary Clark2ade9972017-11-02 17:49:34 -04001867#SeeAlso save() restore() saveLayer saveLayerPreserveLCDTextRequests saveLayerAlpha
1868
Cary Clarkce101242017-09-01 15:51:02 -04001869##
1870
Cary Clark224c7002018-06-27 11:00:21 -04001871#Method SaveLayerRec(const SkRect* bounds, const SkPaint* paint, SaveLayerFlags saveLayerFlags = 0)
Cary Clarkce101242017-09-01 15:51:02 -04001872
1873Sets fBounds, fPaint, and fSaveLayerFlags; sets fBackdrop to nullptr.
1874
1875#Param bounds Layer dimensions; may be nullptr ##
1876#Param paint applied to Layer when overlaying prior Layer; may be nullptr ##
1877#Param saveLayerFlags SaveLayerRec options to modify Layer ##
1878
1879#Return SaveLayerRec with empty backdrop ##
1880
1881#Example
1882 SkCanvas::SaveLayerRec rec1;
1883 SkCanvas::SaveLayerRec rec2(nullptr, nullptr);
1884 SkDebugf("rec1 %c= rec2\n", rec1.fBounds == rec2.fBounds
1885 && rec1.fPaint == rec2.fPaint
1886 && rec1.fBackdrop == rec2.fBackdrop
1887 && rec1.fSaveLayerFlags == rec2.fSaveLayerFlags ? '=' : '!');
1888 #StdOut
1889 rec1 == rec2
1890 ##
1891##
1892
Cary Clark2ade9972017-11-02 17:49:34 -04001893#SeeAlso save() restore() saveLayer saveLayerPreserveLCDTextRequests saveLayerAlpha
1894
Cary Clarkce101242017-09-01 15:51:02 -04001895##
1896
1897#Method SaveLayerRec(const SkRect* bounds, const SkPaint* paint, const SkImageFilter* backdrop,
1898 SaveLayerFlags saveLayerFlags)
1899
1900Sets fBounds, fPaint, fBackdrop, and fSaveLayerFlags.
1901
1902#Param bounds Layer dimensions; may be nullptr ##
1903#Param paint applied to Layer when overlaying prior Layer;
1904 may be nullptr
1905##
1906#Param backdrop prior Layer copied with Image_Filter; may be nullptr
1907##
1908#Param saveLayerFlags SaveLayerRec options to modify Layer ##
1909
1910#Return SaveLayerRec fully specified ##
1911
1912#Example
1913 SkCanvas::SaveLayerRec rec1;
1914 SkCanvas::SaveLayerRec rec2(nullptr, nullptr, nullptr, 0);
1915 SkDebugf("rec1 %c= rec2\n", rec1.fBounds == rec2.fBounds
1916 && rec1.fPaint == rec2.fPaint
1917 && rec1.fBackdrop == rec2.fBackdrop
1918 && rec1.fSaveLayerFlags == rec2.fSaveLayerFlags ? '=' : '!');
1919 #StdOut
1920 rec1 == rec2
1921 ##
1922##
1923
Cary Clark2ade9972017-11-02 17:49:34 -04001924#SeeAlso save() restore() saveLayer saveLayerPreserveLCDTextRequests saveLayerAlpha
1925
Cary Clarkce101242017-09-01 15:51:02 -04001926##
1927
1928#Method SaveLayerRec(const SkRect* bounds, const SkPaint* paint, const SkImageFilter* backdrop,
1929 const SkImage* clipMask, const SkMatrix* clipMatrix,
1930 SaveLayerFlags saveLayerFlags)
1931
Cary Clark682c58d2018-05-16 07:07:07 -04001932#Experimental not ready
Cary Clarkce101242017-09-01 15:51:02 -04001933
1934Sets fBounds, fPaint, fBackdrop, fClipMask, fClipMatrix, and fSaveLayerFlags.
1935clipMatrix uses Color_Alpha channel of image, transformed by clipMatrix, to clip
1936Layer when drawn to Canvas.
1937
Cary Clark2ade9972017-11-02 17:49:34 -04001938Implementation is not complete; has no effect if Device is GPU-backed.
Cary Clarkce101242017-09-01 15:51:02 -04001939
1940#Param bounds Layer dimensions; may be nullptr ##
1941#Param paint graphics state applied to Layer when overlaying prior
1942 Layer; may be nullptr
1943##
1944#Param backdrop prior Layer copied with Image_Filter;
1945 may be nullptr
1946##
1947#Param clipMask clip applied to Layer; may be nullptr ##
1948#Param clipMatrix matrix applied to clipMask; may be nullptr to use
Herb Derbyefe39bc2018-05-01 17:06:20 -04001949 identity matrix
Cary Clarkce101242017-09-01 15:51:02 -04001950##
1951#Param saveLayerFlags SaveLayerRec options to modify Layer ##
1952
1953#Return SaveLayerRec fully specified ##
1954
Cary Clark2ade9972017-11-02 17:49:34 -04001955#SeeAlso save() restore() saveLayer saveLayerPreserveLCDTextRequests saveLayerAlpha
Cary Clarkce101242017-09-01 15:51:02 -04001956
1957##
1958
1959#Struct ##
1960
Cary Clark682c58d2018-05-16 07:07:07 -04001961#Subtopic ##
1962
Cary Clarkce101242017-09-01 15:51:02 -04001963#Method int saveLayer(const SaveLayerRec& layerRec)
1964
Cary Clarkab2621d2018-01-30 10:08:57 -05001965#In Layer
Cary Clark939fd6c2018-07-12 08:40:13 -04001966Saves Matrix and Clip, and allocates Bitmap for subsequent drawing.
Cary Clarkce101242017-09-01 15:51:02 -04001967
Cary Clark939fd6c2018-07-12 08:40:13 -04001968Calling restore() discards changes to Matrix and Clip,
Cary Clarkce101242017-09-01 15:51:02 -04001969and blends Bitmap with Color_Alpha opacity onto the prior Layer.
1970
1971Matrix may be changed by translate(), scale(), rotate(), skew(), concat(),
1972setMatrix, and resetMatrix. Clip may be changed by clipRect, clipRRect,
1973clipPath, clipRegion.
1974
1975SaveLayerRec contains the state used to create the Layer.
1976
1977Call restoreToCount with returned value to restore this and subsequent saves.
1978
1979#Param layerRec Layer state ##
1980
1981#Return depth of save state stack ##
1982
1983#Example
1984#Description
1985The example draws an image, and saves it into a Layer with kInitWithPrevious_SaveLayerFlag.
1986Next it punches a hole in Layer and restore with SkBlendMode::kPlus.
1987Where Layer was cleared, the original image will draw unchanged.
1988Outside of the circle the mandrill is brightened.
1989##
1990 #Image 3
Hal Canaryc465d132017-12-08 10:21:31 -05001991 // sk_sp<SkImage> image = GetResourceAsImage("images/mandrill_256.png");
Cary Clarkce101242017-09-01 15:51:02 -04001992 canvas->drawImage(image, 0, 0, nullptr);
1993 SkCanvas::SaveLayerRec rec;
1994 SkPaint paint;
1995 paint.setBlendMode(SkBlendMode::kPlus);
1996 rec.fSaveLayerFlags = SkCanvas::kInitWithPrevious_SaveLayerFlag;
1997 rec.fPaint = &paint;
1998 canvas->saveLayer(rec);
1999 paint.setBlendMode(SkBlendMode::kClear);
2000 canvas->drawCircle(128, 128, 96, paint);
2001 canvas->restore();
2002##
2003
2004#ToDo above example needs to replace GetResourceAsImage with way to select image in fiddle ##
2005
Cary Clark2ade9972017-11-02 17:49:34 -04002006#SeeAlso save() restore() saveLayer saveLayerPreserveLCDTextRequests saveLayerAlpha
2007
Cary Clarkce101242017-09-01 15:51:02 -04002008##
2009
Cary Clark08895c42018-02-01 09:37:32 -05002010#Subtopic Layer ##
Cary Clarkce101242017-09-01 15:51:02 -04002011
2012# ------------------------------------------------------------------------------
Cary Clark08895c42018-02-01 09:37:32 -05002013#Subtopic Matrix
2014#Line # coordinate transformation ##
Cary Clark8032b982017-07-28 11:04:54 -04002015
2016#Method void translate(SkScalar dx, SkScalar dy)
2017
Cary Clarkab2621d2018-01-30 10:08:57 -05002018#In Matrix
2019#Line # translates Matrix ##
Cary Clark80247e52018-07-11 16:18:41 -04002020Translates Matrix by dx along the x-axis and dy along the y-axis.
Cary Clark8032b982017-07-28 11:04:54 -04002021
Cary Clark80247e52018-07-11 16:18:41 -04002022Mathematically, replaces Matrix with a translation matrix
Herb Derbyefe39bc2018-05-01 17:06:20 -04002023Premultiplied with Matrix.
Cary Clark8032b982017-07-28 11:04:54 -04002024
2025This has the effect of moving the drawing by (dx, dy) before transforming
2026the result with Matrix.
2027
Cary Clarkbad5ad72017-08-03 17:14:08 -04002028#Param dx distance to translate in x ##
2029#Param dy distance to translate in y ##
Cary Clark8032b982017-07-28 11:04:54 -04002030
2031#Example
2032#Height 128
2033#Description
2034scale() followed by translate() produces different results from translate() followed
Herb Derbyefe39bc2018-05-01 17:06:20 -04002035by scale().
Cary Clark8032b982017-07-28 11:04:54 -04002036
2037The blue stroke follows translate of (50, 50); a black
Herb Derbyefe39bc2018-05-01 17:06:20 -04002038fill follows scale of (2, 1/2.f). After restoring the clip, which resets
Cary Clark8032b982017-07-28 11:04:54 -04002039Matrix, a red frame follows the same scale of (2, 1/2.f); a gray fill
2040follows translate of (50, 50).
2041##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002042void draw(SkCanvas* canvas) {
2043 SkPaint filledPaint;
2044 SkPaint outlinePaint;
2045 outlinePaint.setStyle(SkPaint::kStroke_Style);
2046 outlinePaint.setColor(SK_ColorBLUE);
2047 canvas->save();
2048 canvas->translate(50, 50);
2049 canvas->drawCircle(28, 28, 15, outlinePaint); // blue center: (50+28, 50+28)
2050 canvas->scale(2, 1/2.f);
2051 canvas->drawCircle(28, 28, 15, filledPaint); // black center: (50+(28*2), 50+(28/2))
2052 canvas->restore();
2053 filledPaint.setColor(SK_ColorGRAY);
2054 outlinePaint.setColor(SK_ColorRED);
2055 canvas->scale(2, 1/2.f);
2056 canvas->drawCircle(28, 28, 15, outlinePaint); // red center: (28*2, 28/2)
2057 canvas->translate(50, 50);
2058 canvas->drawCircle(28, 28, 15, filledPaint); // gray center: ((50+28)*2, (50+28)/2)
Cary Clark8032b982017-07-28 11:04:54 -04002059}
2060##
2061
Cary Clark2ade9972017-11-02 17:49:34 -04002062#SeeAlso concat() scale() skew() rotate() setMatrix
Cary Clark8032b982017-07-28 11:04:54 -04002063
2064##
2065
2066# ------------------------------------------------------------------------------
2067
2068#Method void scale(SkScalar sx, SkScalar sy)
2069
Cary Clarkab2621d2018-01-30 10:08:57 -05002070#In Matrix
2071#Line # scales Matrix ##
Cary Clark80247e52018-07-11 16:18:41 -04002072Scales Matrix by sx on the x-axis and sy on the y-axis.
Cary Clark8032b982017-07-28 11:04:54 -04002073
Cary Clark80247e52018-07-11 16:18:41 -04002074Mathematically, replaces Matrix with a scale matrix
Herb Derbyefe39bc2018-05-01 17:06:20 -04002075Premultiplied with Matrix.
Cary Clark8032b982017-07-28 11:04:54 -04002076
2077This has the effect of scaling the drawing by (sx, sy) before transforming
2078the result with Matrix.
2079
Cary Clarkbad5ad72017-08-03 17:14:08 -04002080#Param sx amount to scale in x ##
2081#Param sy amount to scale in y ##
Cary Clark8032b982017-07-28 11:04:54 -04002082
2083#Example
2084#Height 160
Cary Clarkbad5ad72017-08-03 17:14:08 -04002085void draw(SkCanvas* canvas) {
2086 SkPaint paint;
2087 SkRect rect = { 10, 20, 60, 120 };
2088 canvas->translate(20, 20);
2089 canvas->drawRect(rect, paint);
2090 canvas->scale(2, .5f);
2091 paint.setColor(SK_ColorGRAY);
2092 canvas->drawRect(rect, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002093}
2094##
2095
Cary Clark2ade9972017-11-02 17:49:34 -04002096#SeeAlso concat() translate() skew() rotate() setMatrix
Cary Clark8032b982017-07-28 11:04:54 -04002097
2098##
2099
2100# ------------------------------------------------------------------------------
2101
2102#Method void rotate(SkScalar degrees)
2103
Cary Clarkab2621d2018-01-30 10:08:57 -05002104#In Matrix
2105#Line # rotates Matrix ##
Cary Clark80247e52018-07-11 16:18:41 -04002106Rotates Matrix by degrees. Positive degrees rotates clockwise.
Cary Clark8032b982017-07-28 11:04:54 -04002107
Cary Clark80247e52018-07-11 16:18:41 -04002108Mathematically, replaces Matrix with a rotation matrix
Herb Derbyefe39bc2018-05-01 17:06:20 -04002109Premultiplied with Matrix.
Cary Clark8032b982017-07-28 11:04:54 -04002110
2111This has the effect of rotating the drawing by degrees before transforming
2112the result with Matrix.
2113
Cary Clarkbad5ad72017-08-03 17:14:08 -04002114#Param degrees amount to rotate, in degrees ##
Cary Clark8032b982017-07-28 11:04:54 -04002115
2116#Example
2117#Description
2118Draw clock hands at time 5:10. The hour hand and minute hand point up and
2119are rotated clockwise.
2120##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002121void draw(SkCanvas* canvas) {
2122 SkPaint paint;
2123 paint.setStyle(SkPaint::kStroke_Style);
2124 canvas->translate(128, 128);
2125 canvas->drawCircle(0, 0, 60, paint);
2126 canvas->save();
2127 canvas->rotate(10 * 360 / 60); // 10 minutes of 60 scaled to 360 degrees
Herb Derbyefe39bc2018-05-01 17:06:20 -04002128 canvas->drawLine(0, 0, 0, -50, paint);
Cary Clarkbad5ad72017-08-03 17:14:08 -04002129 canvas->restore();
2130 canvas->rotate((5 + 10.f/60) * 360 / 12); // 5 and 10/60 hours of 12 scaled to 360 degrees
2131 canvas->drawLine(0, 0, 0, -30, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002132}
2133##
2134
Cary Clark2ade9972017-11-02 17:49:34 -04002135#SeeAlso concat() translate() skew() scale() setMatrix
Cary Clark8032b982017-07-28 11:04:54 -04002136
2137##
2138
2139# ------------------------------------------------------------------------------
2140
2141#Method void rotate(SkScalar degrees, SkScalar px, SkScalar py)
2142
Cary Clarkab2621d2018-01-30 10:08:57 -05002143#In Matrix
Cary Clark80247e52018-07-11 16:18:41 -04002144Rotates Matrix by degrees about a point at (px, py). Positive degrees rotates
Cary Clarkbad5ad72017-08-03 17:14:08 -04002145clockwise.
Cary Clark8032b982017-07-28 11:04:54 -04002146
Cary Clark80247e52018-07-11 16:18:41 -04002147Mathematically, constructs a rotation matrix; Premultiplies the rotation matrix by
2148a translation matrix; then replaces Matrix with the resulting matrix
Herb Derbyefe39bc2018-05-01 17:06:20 -04002149Premultiplied with Matrix.
Cary Clark8032b982017-07-28 11:04:54 -04002150
Cary Clarkbad5ad72017-08-03 17:14:08 -04002151This has the effect of rotating the drawing about a given point before
2152transforming the result with Matrix.
Cary Clark8032b982017-07-28 11:04:54 -04002153
Cary Clarkbad5ad72017-08-03 17:14:08 -04002154#Param degrees amount to rotate, in degrees ##
Cary Clark5538c132018-06-14 12:28:14 -04002155#Param px x-axis value of the point to rotate about ##
2156#Param py y-axis value of the point to rotate about ##
Cary Clark8032b982017-07-28 11:04:54 -04002157
2158#Example
2159#Height 192
Cary Clarkbad5ad72017-08-03 17:14:08 -04002160void draw(SkCanvas* canvas) {
2161 SkPaint paint;
2162 paint.setTextSize(96);
2163 canvas->drawString("A1", 130, 100, paint);
2164 canvas->rotate(180, 130, 100);
2165 canvas->drawString("A1", 130, 100, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002166}
2167##
2168
Cary Clark2ade9972017-11-02 17:49:34 -04002169#SeeAlso concat() translate() skew() scale() setMatrix
Cary Clark8032b982017-07-28 11:04:54 -04002170
2171##
2172
2173# ------------------------------------------------------------------------------
2174
2175#Method void skew(SkScalar sx, SkScalar sy)
2176
Cary Clarkab2621d2018-01-30 10:08:57 -05002177#In Matrix
2178#Line # skews Matrix ##
Cary Clark80247e52018-07-11 16:18:41 -04002179Skews Matrix by sx on the x-axis and sy on the y-axis. A positive value of sx
Cary Clark5538c132018-06-14 12:28:14 -04002180skews the drawing right as y-axis values increase; a positive value of sy skews
2181the drawing down as x-axis values increase.
Cary Clark8032b982017-07-28 11:04:54 -04002182
Cary Clark80247e52018-07-11 16:18:41 -04002183Mathematically, replaces Matrix with a skew matrix Premultiplied with Matrix.
Cary Clark8032b982017-07-28 11:04:54 -04002184
Cary Clarkbad5ad72017-08-03 17:14:08 -04002185This has the effect of skewing the drawing by (sx, sy) before transforming
Cary Clark8032b982017-07-28 11:04:54 -04002186the result with Matrix.
2187
Cary Clark5538c132018-06-14 12:28:14 -04002188#Param sx amount to skew on x-axis ##
2189#Param sy amount to skew on y-axis ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002190
Cary Clark8032b982017-07-28 11:04:54 -04002191#Example
Herb Derbyefe39bc2018-05-01 17:06:20 -04002192 #Description
Cary Clark5538c132018-06-14 12:28:14 -04002193 Black text mimics an oblique text style by using a negative skew on x-axis
2194 that shifts the geometry to the right as the y-axis values decrease.
2195 Red text uses a positive skew on y-axis to shift the geometry down
2196 as the x-axis values increase.
2197 Blue text combines sx and sy skew to rotate and scale.
Cary Clark8032b982017-07-28 11:04:54 -04002198 ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002199 SkPaint paint;
2200 paint.setTextSize(128);
2201 canvas->translate(30, 130);
2202 canvas->save();
2203 canvas->skew(-.5, 0);
2204 canvas->drawString("A1", 0, 0, paint);
2205 canvas->restore();
2206 canvas->save();
2207 canvas->skew(0, .5);
2208 paint.setColor(SK_ColorRED);
2209 canvas->drawString("A1", 0, 0, paint);
2210 canvas->restore();
2211 canvas->skew(-.5, .5);
2212 paint.setColor(SK_ColorBLUE);
Cary Clark8032b982017-07-28 11:04:54 -04002213 canvas->drawString("A1", 0, 0, paint);
2214##
2215
Cary Clark2ade9972017-11-02 17:49:34 -04002216#SeeAlso concat() translate() rotate() scale() setMatrix
Cary Clark8032b982017-07-28 11:04:54 -04002217
2218##
2219
2220# ------------------------------------------------------------------------------
2221
2222#Method void concat(const SkMatrix& matrix)
2223
Cary Clarkab2621d2018-01-30 10:08:57 -05002224#In Matrix
2225#Line # multiplies Matrix by Matrix ##
Cary Clark80247e52018-07-11 16:18:41 -04002226Replaces Matrix with matrix Premultiplied with existing Matrix.
Cary Clark8032b982017-07-28 11:04:54 -04002227
Cary Clarkbad5ad72017-08-03 17:14:08 -04002228This has the effect of transforming the drawn geometry by matrix, before
2229transforming the result with existing Matrix.
Cary Clark8032b982017-07-28 11:04:54 -04002230
Cary Clarkce101242017-09-01 15:51:02 -04002231#Param matrix matrix to Premultiply with existing Matrix ##
Cary Clark8032b982017-07-28 11:04:54 -04002232
2233#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04002234void draw(SkCanvas* canvas) {
2235 SkPaint paint;
2236 paint.setTextSize(80);
2237 paint.setTextScaleX(.3);
2238 SkMatrix matrix;
2239 SkRect rect[2] = {{ 10, 20, 90, 110 }, { 40, 130, 140, 180 }};
2240 matrix.setRectToRect(rect[0], rect[1], SkMatrix::kFill_ScaleToFit);
2241 canvas->drawRect(rect[0], paint);
2242 canvas->drawRect(rect[1], paint);
2243 paint.setColor(SK_ColorWHITE);
2244 canvas->drawString("Here", rect[0].fLeft + 10, rect[0].fBottom - 10, paint);
2245 canvas->concat(matrix);
2246 canvas->drawString("There", rect[0].fLeft + 10, rect[0].fBottom - 10, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002247}
2248##
2249
Cary Clark2ade9972017-11-02 17:49:34 -04002250#SeeAlso translate() rotate() scale() skew() setMatrix
Cary Clark8032b982017-07-28 11:04:54 -04002251
2252##
2253
2254# ------------------------------------------------------------------------------
2255
2256#Method void setMatrix(const SkMatrix& matrix)
2257
Cary Clarkab2621d2018-01-30 10:08:57 -05002258#In Matrix
2259#Line # sets Matrix ##
Cary Clark80247e52018-07-11 16:18:41 -04002260Replaces Matrix with matrix.
Cary Clark8032b982017-07-28 11:04:54 -04002261Unlike concat(), any prior matrix state is overwritten.
2262
Cary Clarkbad5ad72017-08-03 17:14:08 -04002263#Param matrix matrix to copy, replacing existing Matrix ##
Cary Clark8032b982017-07-28 11:04:54 -04002264
2265#Example
2266#Height 128
Cary Clarkbad5ad72017-08-03 17:14:08 -04002267void draw(SkCanvas* canvas) {
2268 SkPaint paint;
2269 canvas->scale(4, 6);
2270 canvas->drawString("truth", 2, 10, paint);
2271 SkMatrix matrix;
2272 matrix.setScale(2.8f, 6);
2273 canvas->setMatrix(matrix);
2274 canvas->drawString("consequences", 2, 20, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002275}
2276##
2277
Cary Clark2ade9972017-11-02 17:49:34 -04002278#SeeAlso resetMatrix concat() translate() rotate() scale() skew()
Cary Clark8032b982017-07-28 11:04:54 -04002279
2280##
2281
2282# ------------------------------------------------------------------------------
2283
2284#Method void resetMatrix()
2285
Cary Clarkab2621d2018-01-30 10:08:57 -05002286#In Matrix
2287#Line # resets Matrix to identity ##
Cary Clark8032b982017-07-28 11:04:54 -04002288Sets Matrix to the identity matrix.
2289Any prior matrix state is overwritten.
2290
2291#Example
2292#Height 128
Cary Clarkbad5ad72017-08-03 17:14:08 -04002293void draw(SkCanvas* canvas) {
2294 SkPaint paint;
2295 canvas->scale(4, 6);
2296 canvas->drawString("truth", 2, 10, paint);
2297 canvas->resetMatrix();
2298 canvas->scale(2.8f, 6);
2299 canvas->drawString("consequences", 2, 20, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002300}
2301##
2302
Cary Clark2ade9972017-11-02 17:49:34 -04002303#SeeAlso setMatrix concat() translate() rotate() scale() skew()
Cary Clark8032b982017-07-28 11:04:54 -04002304
2305##
2306
2307# ------------------------------------------------------------------------------
2308
2309#Method const SkMatrix& getTotalMatrix() const
2310
Cary Clarkab2621d2018-01-30 10:08:57 -05002311#In Matrix
2312#Line # returns Matrix ##
Cary Clark8032b982017-07-28 11:04:54 -04002313Returns Matrix.
2314This does not account for translation by Device or Surface.
2315
Cary Clarkbad5ad72017-08-03 17:14:08 -04002316#Return Matrix in Canvas ##
Cary Clark8032b982017-07-28 11:04:54 -04002317
2318#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04002319 SkDebugf("isIdentity %s\n", canvas->getTotalMatrix().isIdentity() ? "true" : "false");
2320 #StdOut
2321 isIdentity true
2322 ##
Cary Clark8032b982017-07-28 11:04:54 -04002323##
2324
Cary Clark2ade9972017-11-02 17:49:34 -04002325#SeeAlso setMatrix resetMatrix concat()
Cary Clark8032b982017-07-28 11:04:54 -04002326
2327##
2328
Cary Clark08895c42018-02-01 09:37:32 -05002329#Subtopic Matrix ##
Cary Clark8032b982017-07-28 11:04:54 -04002330
2331# ------------------------------------------------------------------------------
Cary Clark08895c42018-02-01 09:37:32 -05002332#Subtopic Clip
2333#Line # stack of clipping Paths ##
Cary Clark8032b982017-07-28 11:04:54 -04002334
2335Clip is built from a stack of clipping paths. Each Path in the
Herb Derbyefe39bc2018-05-01 17:06:20 -04002336stack can be constructed from one or more Path_Contour elements. The
Cary Clark8032b982017-07-28 11:04:54 -04002337Path_Contour may be composed of any number of Path_Verb segments. Each
2338Path_Contour forms a closed area; Path_Fill_Type defines the area enclosed
2339by Path_Contour.
2340
2341Clip stack of Path elements successfully restrict the Path area. Each
Herb Derbyefe39bc2018-05-01 17:06:20 -04002342Path is transformed by Matrix, then intersected with or subtracted from the
Cary Clark8032b982017-07-28 11:04:54 -04002343prior Clip to form the replacement Clip. Use SkClipOp::kDifference
2344to subtract Path from Clip; use SkClipOp::kIntersect to intersect Path
2345with Clip.
2346
Cary Clarkffb3d682018-05-17 12:17:28 -04002347A clipping Path may be Anti_Aliased; if Path, after transformation, is
2348composed of horizontal and vertical lines, clearing Anti_Alias allows whole pixels
Cary Clarkce101242017-09-01 15:51:02 -04002349to either be inside or outside the clip. The fastest drawing has a Aliased,
2350rectangular clip.
Cary Clark8032b982017-07-28 11:04:54 -04002351
Cary Clarkffb3d682018-05-17 12:17:28 -04002352If clipping Path has Anti_Alias set, clip may partially clip a pixel, requiring
Herb Derbyefe39bc2018-05-01 17:06:20 -04002353that drawing blend partially with the destination along the edge. A rotated
Cary Clarkffb3d682018-05-17 12:17:28 -04002354rectangular Anti_Aliased clip looks smoother but draws slower.
Cary Clark8032b982017-07-28 11:04:54 -04002355
2356Clip can combine with Rect and Round_Rect primitives; like
2357Path, these are transformed by Matrix before they are combined with Clip.
2358
2359Clip can combine with Region. Region is assumed to be in Device coordinates
2360and is unaffected by Matrix.
2361
2362#Example
2363#Height 90
2364 #Description
Cary Clarkffb3d682018-05-17 12:17:28 -04002365 Draw a red circle with an Aliased clip and an Anti_Aliased clip.
Cary Clark8032b982017-07-28 11:04:54 -04002366 Use an image filter to zoom into the pixels drawn.
Cary Clarkce101242017-09-01 15:51:02 -04002367 The edge of the Aliased clip fully draws pixels in the red circle.
Cary Clarkffb3d682018-05-17 12:17:28 -04002368 The edge of the Anti_Aliased clip partially draws pixels in the red circle.
Cary Clark8032b982017-07-28 11:04:54 -04002369 ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002370 SkPaint redPaint, scalePaint;
2371 redPaint.setAntiAlias(true);
2372 redPaint.setColor(SK_ColorRED);
2373 canvas->save();
2374 for (bool antialias : { false, true } ) {
2375 canvas->save();
2376 canvas->clipRect(SkRect::MakeWH(19.5f, 11.5f), antialias);
2377 canvas->drawCircle(17, 11, 8, redPaint);
2378 canvas->restore();
2379 canvas->translate(16, 0);
2380 }
2381 canvas->restore();
2382 SkMatrix matrix;
2383 matrix.setScale(6, 6);
2384 scalePaint.setImageFilter(
2385 SkImageFilter::MakeMatrixFilter(matrix, kNone_SkFilterQuality, nullptr));
2386 SkCanvas::SaveLayerRec saveLayerRec(
Herb Derbyefe39bc2018-05-01 17:06:20 -04002387 nullptr, &scalePaint, SkCanvas::kInitWithPrevious_SaveLayerFlag);
Cary Clarkbad5ad72017-08-03 17:14:08 -04002388 canvas->saveLayer(saveLayerRec);
Cary Clark8032b982017-07-28 11:04:54 -04002389 canvas->restore();
2390##
2391
2392#Method void clipRect(const SkRect& rect, SkClipOp op, bool doAntiAlias)
2393
Cary Clarkab2621d2018-01-30 10:08:57 -05002394#In Clip
2395#Line # combines Clip with Rect ##
Cary Clark80247e52018-07-11 16:18:41 -04002396Replaces Clip with the intersection or difference of Clip and rect,
Cary Clarkffb3d682018-05-17 12:17:28 -04002397with an Aliased or Anti_Aliased clip edge. rect is transformed by Matrix
Cary Clark8032b982017-07-28 11:04:54 -04002398before it is combined with Clip.
2399
Cary Clarka523d2d2017-08-30 08:58:10 -04002400#Param rect Rect to combine with Clip ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002401#Param op Clip_Op to apply to Clip ##
Cary Clarkffb3d682018-05-17 12:17:28 -04002402#Param doAntiAlias true if Clip is to be Anti_Aliased ##
Cary Clark8032b982017-07-28 11:04:54 -04002403
2404#Example
2405#Height 128
Cary Clarkbad5ad72017-08-03 17:14:08 -04002406void draw(SkCanvas* canvas) {
2407 canvas->rotate(10);
2408 SkPaint paint;
2409 paint.setAntiAlias(true);
2410 for (auto alias: { false, true } ) {
2411 canvas->save();
2412 canvas->clipRect(SkRect::MakeWH(90, 80), SkClipOp::kIntersect, alias);
2413 canvas->drawCircle(100, 60, 60, paint);
2414 canvas->restore();
2415 canvas->translate(80, 0);
2416 }
Cary Clark8032b982017-07-28 11:04:54 -04002417}
2418##
2419
Cary Clark2ade9972017-11-02 17:49:34 -04002420#SeeAlso clipRRect clipPath clipRegion
Cary Clark8032b982017-07-28 11:04:54 -04002421
2422##
2423
Herb Derbyefe39bc2018-05-01 17:06:20 -04002424#Method void clipRect(const SkRect& rect, SkClipOp op)
Cary Clark8032b982017-07-28 11:04:54 -04002425
Cary Clarkab2621d2018-01-30 10:08:57 -05002426#In Clip
Cary Clark80247e52018-07-11 16:18:41 -04002427Replaces Clip with the intersection or difference of Clip and rect.
Cary Clarkce101242017-09-01 15:51:02 -04002428Resulting Clip is Aliased; pixels are fully contained by the clip.
Cary Clarkbad5ad72017-08-03 17:14:08 -04002429rect is transformed by Matrix before it is combined with Clip.
Cary Clark8032b982017-07-28 11:04:54 -04002430
Cary Clarka523d2d2017-08-30 08:58:10 -04002431#Param rect Rect to combine with Clip ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002432#Param op Clip_Op to apply to Clip ##
Cary Clark8032b982017-07-28 11:04:54 -04002433
2434#Example
2435#Height 192
2436#Width 280
Cary Clarkbad5ad72017-08-03 17:14:08 -04002437void draw(SkCanvas* canvas) {
2438 SkPaint paint;
2439 for (SkClipOp op: { SkClipOp::kIntersect, SkClipOp::kDifference } ) {
2440 canvas->save();
2441 canvas->clipRect(SkRect::MakeWH(90, 120), op, false);
2442 canvas->drawCircle(100, 100, 60, paint);
2443 canvas->restore();
2444 canvas->translate(80, 0);
2445 }
Cary Clark8032b982017-07-28 11:04:54 -04002446}
2447##
2448
Cary Clark2ade9972017-11-02 17:49:34 -04002449#SeeAlso clipRRect clipPath clipRegion
Cary Clark8032b982017-07-28 11:04:54 -04002450
2451##
2452
Herb Derbyefe39bc2018-05-01 17:06:20 -04002453#Method void clipRect(const SkRect& rect, bool doAntiAlias = false)
Cary Clark8032b982017-07-28 11:04:54 -04002454
Cary Clarkab2621d2018-01-30 10:08:57 -05002455#In Clip
Cary Clark80247e52018-07-11 16:18:41 -04002456Replaces Clip with the intersection of Clip and rect.
Cary Clarkce101242017-09-01 15:51:02 -04002457Resulting Clip is Aliased; pixels are fully contained by the clip.
Cary Clark8032b982017-07-28 11:04:54 -04002458rect is transformed by Matrix
2459before it is combined with Clip.
2460
Cary Clarka523d2d2017-08-30 08:58:10 -04002461#Param rect Rect to combine with Clip ##
Cary Clarkffb3d682018-05-17 12:17:28 -04002462#Param doAntiAlias true if Clip is to be Anti_Aliased ##
Cary Clark8032b982017-07-28 11:04:54 -04002463
2464#Example
2465#Height 133
2466 #Description
Cary Clarkce101242017-09-01 15:51:02 -04002467 A circle drawn in pieces looks uniform when drawn Aliased.
Cary Clarkffb3d682018-05-17 12:17:28 -04002468 The same circle pieces blend with pixels more than once when Anti_Aliased,
Cary Clark8032b982017-07-28 11:04:54 -04002469 visible as a thin pair of lines through the right circle.
2470 ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002471void draw(SkCanvas* canvas) {
2472 canvas->clear(SK_ColorWHITE);
2473 SkPaint paint;
2474 paint.setAntiAlias(true);
2475 paint.setColor(0x8055aaff);
2476 SkRect clipRect = { 0, 0, 87.4f, 87.4f };
2477 for (auto alias: { false, true } ) {
2478 canvas->save();
2479 canvas->clipRect(clipRect, SkClipOp::kIntersect, alias);
2480 canvas->drawCircle(67, 67, 60, paint);
2481 canvas->restore();
2482 canvas->save();
2483 canvas->clipRect(clipRect, SkClipOp::kDifference, alias);
2484 canvas->drawCircle(67, 67, 60, paint);
2485 canvas->restore();
2486 canvas->translate(120, 0);
2487 }
Cary Clark8032b982017-07-28 11:04:54 -04002488}
2489##
2490
Cary Clark2ade9972017-11-02 17:49:34 -04002491#SeeAlso clipRRect clipPath clipRegion
Cary Clark8032b982017-07-28 11:04:54 -04002492
2493##
2494
2495#Method void androidFramework_setDeviceClipRestriction(const SkIRect& rect)
2496
Cary Clarkab2621d2018-01-30 10:08:57 -05002497#In Clip
Cary Clark682c58d2018-05-16 07:07:07 -04002498#Line # exists for use by Android framework ##
Cary Clarkce101242017-09-01 15:51:02 -04002499Sets the maximum clip rectangle, which can be set by clipRect, clipRRect and
Cary Clark8032b982017-07-28 11:04:54 -04002500clipPath and intersect the current clip with the specified rect.
Cary Clarkce101242017-09-01 15:51:02 -04002501The maximum clip affects only future clipping operations; it is not retroactive.
Cary Clark8032b982017-07-28 11:04:54 -04002502The clip restriction is not recorded in pictures.
2503
Herb Derbyefe39bc2018-05-01 17:06:20 -04002504Pass an empty rect to disable maximum clip.
Cary Clarkbad5ad72017-08-03 17:14:08 -04002505
Cary Clark8032b982017-07-28 11:04:54 -04002506#Private
Cary Clark137b8742018-05-30 09:21:49 -04002507This private API is for use by Android framework only.
Cary Clark8032b982017-07-28 11:04:54 -04002508##
2509
Cary Clarkbad5ad72017-08-03 17:14:08 -04002510#Param rect maximum allowed clip in device coordinates
Cary Clark579985c2017-07-31 11:48:27 -04002511#Param ##
Cary Clark8032b982017-07-28 11:04:54 -04002512
2513##
2514
2515#Method void clipRRect(const SkRRect& rrect, SkClipOp op, bool doAntiAlias)
2516
Cary Clarkab2621d2018-01-30 10:08:57 -05002517#In Clip
2518#Line # combines Clip with Round_Rect ##
Cary Clark80247e52018-07-11 16:18:41 -04002519Replaces Clip with the intersection or difference of Clip and rrect,
Cary Clarkffb3d682018-05-17 12:17:28 -04002520with an Aliased or Anti_Aliased clip edge.
Cary Clark8032b982017-07-28 11:04:54 -04002521rrect is transformed by Matrix
2522before it is combined with Clip.
2523
Cary Clarkbad5ad72017-08-03 17:14:08 -04002524#Param rrect Round_Rect to combine with Clip ##
2525#Param op Clip_Op to apply to Clip ##
Cary Clarkffb3d682018-05-17 12:17:28 -04002526#Param doAntiAlias true if Clip is to be Anti_Aliased ##
Cary Clark8032b982017-07-28 11:04:54 -04002527
2528#Example
2529#Height 128
Cary Clarkbad5ad72017-08-03 17:14:08 -04002530void draw(SkCanvas* canvas) {
2531 canvas->clear(SK_ColorWHITE);
2532 SkPaint paint;
2533 paint.setAntiAlias(true);
2534 paint.setColor(0x8055aaff);
2535 SkRRect oval;
2536 oval.setOval({10, 20, 90, 100});
2537 canvas->clipRRect(oval, SkClipOp::kIntersect, true);
2538 canvas->drawCircle(70, 100, 60, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002539}
2540##
2541
Cary Clark2ade9972017-11-02 17:49:34 -04002542#SeeAlso clipRect clipPath clipRegion
Cary Clark8032b982017-07-28 11:04:54 -04002543
2544##
2545
Herb Derbyefe39bc2018-05-01 17:06:20 -04002546#Method void clipRRect(const SkRRect& rrect, SkClipOp op)
Cary Clark8032b982017-07-28 11:04:54 -04002547
Cary Clarkab2621d2018-01-30 10:08:57 -05002548#In Clip
Cary Clark80247e52018-07-11 16:18:41 -04002549Replaces Clip with the intersection or difference of Clip and rrect.
Cary Clarkce101242017-09-01 15:51:02 -04002550Resulting Clip is Aliased; pixels are fully contained by the clip.
Cary Clarkbad5ad72017-08-03 17:14:08 -04002551rrect is transformed by Matrix before it is combined with Clip.
Cary Clark8032b982017-07-28 11:04:54 -04002552
Cary Clarkbad5ad72017-08-03 17:14:08 -04002553#Param rrect Round_Rect to combine with Clip ##
2554#Param op Clip_Op to apply to Clip ##
Cary Clark8032b982017-07-28 11:04:54 -04002555
2556#Example
2557#Height 128
Cary Clarkbad5ad72017-08-03 17:14:08 -04002558void draw(SkCanvas* canvas) {
2559 SkPaint paint;
2560 paint.setColor(0x8055aaff);
2561 auto oval = SkRRect::MakeOval({10, 20, 90, 100});
2562 canvas->clipRRect(oval, SkClipOp::kIntersect);
2563 canvas->drawCircle(70, 100, 60, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002564}
2565##
2566
Cary Clark2ade9972017-11-02 17:49:34 -04002567#SeeAlso clipRect clipPath clipRegion
Cary Clark8032b982017-07-28 11:04:54 -04002568
2569##
2570
Herb Derbyefe39bc2018-05-01 17:06:20 -04002571#Method void clipRRect(const SkRRect& rrect, bool doAntiAlias = false)
Cary Clark8032b982017-07-28 11:04:54 -04002572
Cary Clarkab2621d2018-01-30 10:08:57 -05002573#In Clip
Cary Clark80247e52018-07-11 16:18:41 -04002574Replaces Clip with the intersection of Clip and rrect,
Cary Clarkffb3d682018-05-17 12:17:28 -04002575with an Aliased or Anti_Aliased clip edge.
Cary Clarkbad5ad72017-08-03 17:14:08 -04002576rrect is transformed by Matrix before it is combined with Clip.
Cary Clark8032b982017-07-28 11:04:54 -04002577
Cary Clarkbad5ad72017-08-03 17:14:08 -04002578#Param rrect Round_Rect to combine with Clip ##
Cary Clarkffb3d682018-05-17 12:17:28 -04002579#Param doAntiAlias true if Clip is to be Anti_Aliased ##
Cary Clark8032b982017-07-28 11:04:54 -04002580
2581#Example
2582#Height 128
Cary Clarkbad5ad72017-08-03 17:14:08 -04002583void draw(SkCanvas* canvas) {
2584 SkPaint paint;
2585 paint.setAntiAlias(true);
2586 auto oval = SkRRect::MakeRectXY({10, 20, 90, 100}, 9, 13);
2587 canvas->clipRRect(oval, true);
2588 canvas->drawCircle(70, 100, 60, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002589}
2590##
2591
Cary Clark2ade9972017-11-02 17:49:34 -04002592#SeeAlso clipRect clipPath clipRegion
Cary Clark8032b982017-07-28 11:04:54 -04002593
2594##
2595
2596#Method void clipPath(const SkPath& path, SkClipOp op, bool doAntiAlias)
2597
Cary Clarkab2621d2018-01-30 10:08:57 -05002598#In Clip
2599#Line # combines Clip with Path ##
Cary Clark80247e52018-07-11 16:18:41 -04002600Replaces Clip with the intersection or difference of Clip and path,
Cary Clarkffb3d682018-05-17 12:17:28 -04002601with an Aliased or Anti_Aliased clip edge. Path_Fill_Type determines if path
Cary Clark8032b982017-07-28 11:04:54 -04002602describes the area inside or outside its contours; and if Path_Contour overlaps
2603itself or another Path_Contour, whether the overlaps form part of the area.
Cary Clarkbad5ad72017-08-03 17:14:08 -04002604path is transformed by Matrix before it is combined with Clip.
Cary Clark8032b982017-07-28 11:04:54 -04002605
Cary Clarkbad5ad72017-08-03 17:14:08 -04002606#Param path Path to combine with Clip ##
2607#Param op Clip_Op to apply to Clip ##
Cary Clarkffb3d682018-05-17 12:17:28 -04002608#Param doAntiAlias true if Clip is to be Anti_Aliased ##
Cary Clark8032b982017-07-28 11:04:54 -04002609
2610#Example
2611#Description
2612Top figure uses SkPath::kInverseWinding_FillType and SkClipOp::kDifference;
2613area outside clip is subtracted from circle.
2614
2615Bottom figure uses SkPath::kWinding_FillType and SkClipOp::kIntersect;
2616area inside clip is intersected with circle.
2617##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002618void draw(SkCanvas* canvas) {
2619 SkPaint paint;
2620 paint.setAntiAlias(true);
2621 SkPath path;
2622 path.addRect({20, 30, 100, 110});
2623 path.setFillType(SkPath::kInverseWinding_FillType);
2624 canvas->save();
2625 canvas->clipPath(path, SkClipOp::kDifference, false);
2626 canvas->drawCircle(70, 100, 60, paint);
2627 canvas->restore();
2628 canvas->translate(100, 100);
2629 path.setFillType(SkPath::kWinding_FillType);
2630 canvas->clipPath(path, SkClipOp::kIntersect, false);
2631 canvas->drawCircle(70, 100, 60, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002632}
2633##
2634
Cary Clark2ade9972017-11-02 17:49:34 -04002635#SeeAlso clipRect clipRRect clipRegion
Cary Clark8032b982017-07-28 11:04:54 -04002636
2637##
2638
Herb Derbyefe39bc2018-05-01 17:06:20 -04002639#Method void clipPath(const SkPath& path, SkClipOp op)
Cary Clark8032b982017-07-28 11:04:54 -04002640
Cary Clarkab2621d2018-01-30 10:08:57 -05002641#In Clip
Cary Clark80247e52018-07-11 16:18:41 -04002642Replaces Clip with the intersection or difference of Clip and path.
Cary Clarkce101242017-09-01 15:51:02 -04002643Resulting Clip is Aliased; pixels are fully contained by the clip.
Cary Clark8032b982017-07-28 11:04:54 -04002644Path_Fill_Type determines if path
2645describes the area inside or outside its contours; and if Path_Contour overlaps
2646itself or another Path_Contour, whether the overlaps form part of the area.
2647path is transformed by Matrix
2648before it is combined with Clip.
2649
Cary Clarkbad5ad72017-08-03 17:14:08 -04002650#Param path Path to combine with Clip ##
2651#Param op Clip_Op to apply to Clip ##
Cary Clark8032b982017-07-28 11:04:54 -04002652
2653#Example
2654#Description
Cary Clarkbc5697d2017-10-04 14:31:33 -04002655Overlapping Rects form a clip. When clip Path_Fill_Type is set to
Herb Derbyefe39bc2018-05-01 17:06:20 -04002656SkPath::kWinding_FillType, the overlap is included. Set to
Cary Clark8032b982017-07-28 11:04:54 -04002657SkPath::kEvenOdd_FillType, the overlap is excluded and forms a hole.
2658##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002659void draw(SkCanvas* canvas) {
2660 SkPaint paint;
2661 paint.setAntiAlias(true);
2662 SkPath path;
2663 path.addRect({20, 15, 100, 95});
2664 path.addRect({50, 65, 130, 135});
2665 path.setFillType(SkPath::kWinding_FillType);
2666 canvas->save();
2667 canvas->clipPath(path, SkClipOp::kIntersect);
2668 canvas->drawCircle(70, 85, 60, paint);
2669 canvas->restore();
2670 canvas->translate(100, 100);
2671 path.setFillType(SkPath::kEvenOdd_FillType);
2672 canvas->clipPath(path, SkClipOp::kIntersect);
2673 canvas->drawCircle(70, 85, 60, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002674}
2675##
2676
Cary Clark2ade9972017-11-02 17:49:34 -04002677#SeeAlso clipRect clipRRect clipRegion
Cary Clark8032b982017-07-28 11:04:54 -04002678
2679##
2680
Herb Derbyefe39bc2018-05-01 17:06:20 -04002681#Method void clipPath(const SkPath& path, bool doAntiAlias = false)
Cary Clark8032b982017-07-28 11:04:54 -04002682
Cary Clarkab2621d2018-01-30 10:08:57 -05002683#In Clip
Cary Clark80247e52018-07-11 16:18:41 -04002684Replaces Clip with the intersection of Clip and path.
Cary Clarkce101242017-09-01 15:51:02 -04002685Resulting Clip is Aliased; pixels are fully contained by the clip.
Cary Clark8032b982017-07-28 11:04:54 -04002686Path_Fill_Type determines if path
2687describes the area inside or outside its contours; and if Path_Contour overlaps
2688itself or another Path_Contour, whether the overlaps form part of the area.
Cary Clarkbad5ad72017-08-03 17:14:08 -04002689path is transformed by Matrix before it is combined with Clip.
Cary Clark8032b982017-07-28 11:04:54 -04002690
Cary Clarkbad5ad72017-08-03 17:14:08 -04002691#Param path Path to combine with Clip ##
Cary Clarkffb3d682018-05-17 12:17:28 -04002692#Param doAntiAlias true if Clip is to be Anti_Aliased ##
Cary Clark8032b982017-07-28 11:04:54 -04002693
2694#Example
2695#Height 212
2696#Description
Herb Derbyefe39bc2018-05-01 17:06:20 -04002697Clip loops over itself covering its center twice. When clip Path_Fill_Type
2698is set to SkPath::kWinding_FillType, the overlap is included. Set to
Cary Clark8032b982017-07-28 11:04:54 -04002699SkPath::kEvenOdd_FillType, the overlap is excluded and forms a hole.
2700##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002701void draw(SkCanvas* canvas) {
2702 SkPaint paint;
2703 paint.setAntiAlias(true);
2704 SkPath path;
2705 SkPoint poly[] = {{20, 20}, { 80, 20}, { 80, 80}, {40, 80},
2706 {40, 40}, {100, 40}, {100, 100}, {20, 100}};
2707 path.addPoly(poly, SK_ARRAY_COUNT(poly), true);
2708 path.setFillType(SkPath::kWinding_FillType);
2709 canvas->save();
2710 canvas->clipPath(path, SkClipOp::kIntersect);
2711 canvas->drawCircle(50, 50, 45, paint);
2712 canvas->restore();
2713 canvas->translate(100, 100);
2714 path.setFillType(SkPath::kEvenOdd_FillType);
2715 canvas->clipPath(path, SkClipOp::kIntersect);
2716 canvas->drawCircle(50, 50, 45, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002717}
2718##
2719
Cary Clark2ade9972017-11-02 17:49:34 -04002720#SeeAlso clipRect clipRRect clipRegion
Cary Clark8032b982017-07-28 11:04:54 -04002721
2722##
2723
2724# ------------------------------------------------------------------------------
2725
Herb Derbyefe39bc2018-05-01 17:06:20 -04002726#Method void setAllowSimplifyClip(bool allow)
Cary Clark8032b982017-07-28 11:04:54 -04002727
Cary Clarkab2621d2018-01-30 10:08:57 -05002728#In Clip
Cary Clark682c58d2018-05-16 07:07:07 -04002729#Experimental testing
Cary Clark8032b982017-07-28 11:04:54 -04002730
Cary Clarkce101242017-09-01 15:51:02 -04002731Set to simplify clip stack using PathOps.
Cary Clark8032b982017-07-28 11:04:54 -04002732
2733##
2734
2735# ------------------------------------------------------------------------------
2736
2737#Method void clipRegion(const SkRegion& deviceRgn, SkClipOp op = SkClipOp::kIntersect)
2738
Cary Clarkab2621d2018-01-30 10:08:57 -05002739#In Clip
2740#Line # combines Clip with Region ##
Cary Clark80247e52018-07-11 16:18:41 -04002741Replaces Clip with the intersection or difference of Clip and Region deviceRgn.
Cary Clarkce101242017-09-01 15:51:02 -04002742Resulting Clip is Aliased; pixels are fully contained by the clip.
Cary Clark8032b982017-07-28 11:04:54 -04002743deviceRgn is unaffected by Matrix.
2744
Cary Clarkbad5ad72017-08-03 17:14:08 -04002745#Param deviceRgn Region to combine with Clip ##
2746#Param op Clip_Op to apply to Clip ##
Cary Clark8032b982017-07-28 11:04:54 -04002747
2748#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04002749#Description
Cary Clarkce101242017-09-01 15:51:02 -04002750 region is unaffected by canvas rotation; iRect is affected by canvas rotation.
2751 Both clips are Aliased; this is not noticeable on Region clip because it
Cary Clarkbad5ad72017-08-03 17:14:08 -04002752 aligns to pixel boundaries.
2753##
2754void draw(SkCanvas* canvas) {
2755 SkPaint paint;
2756 paint.setAntiAlias(true);
2757 SkIRect iRect = {30, 40, 120, 130 };
2758 SkRegion region(iRect);
2759 canvas->rotate(10);
2760 canvas->save();
2761 canvas->clipRegion(region, SkClipOp::kIntersect);
2762 canvas->drawCircle(50, 50, 45, paint);
2763 canvas->restore();
2764 canvas->translate(100, 100);
2765 canvas->clipRect(SkRect::Make(iRect), SkClipOp::kIntersect);
2766 canvas->drawCircle(50, 50, 45, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002767}
2768##
2769
Cary Clark2ade9972017-11-02 17:49:34 -04002770#SeeAlso clipRect clipRRect clipPath
Cary Clark8032b982017-07-28 11:04:54 -04002771
2772##
2773
2774#Method bool quickReject(const SkRect& rect) const
2775
Cary Clarkab2621d2018-01-30 10:08:57 -05002776#In Clip
2777#Line # returns if Rect is outside Clip ##
Cary Clark80247e52018-07-11 16:18:41 -04002778Returns true if Rect rect, transformed by Matrix, can be quickly determined to be
Cary Clark8032b982017-07-28 11:04:54 -04002779outside of Clip. May return false even though rect is outside of Clip.
2780
2781Use to check if an area to be drawn is clipped out, to skip subsequent draw calls.
2782
Cary Clarkbad5ad72017-08-03 17:14:08 -04002783#Param rect Rect to compare with Clip ##
Cary Clark8032b982017-07-28 11:04:54 -04002784
Cary Clarkbad5ad72017-08-03 17:14:08 -04002785#Return true if rect, transformed by Matrix, does not intersect Clip ##
Cary Clark8032b982017-07-28 11:04:54 -04002786
2787#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04002788void draw(SkCanvas* canvas) {
Herb Derbyefe39bc2018-05-01 17:06:20 -04002789 SkRect testRect = {30, 30, 120, 129 };
2790 SkRect clipRect = {30, 130, 120, 230 };
Cary Clarkbad5ad72017-08-03 17:14:08 -04002791 canvas->save();
2792 canvas->clipRect(clipRect);
2793 SkDebugf("quickReject %s\n", canvas->quickReject(testRect) ? "true" : "false");
2794 canvas->restore();
2795 canvas->rotate(10);
2796 canvas->clipRect(clipRect);
2797 SkDebugf("quickReject %s\n", canvas->quickReject(testRect) ? "true" : "false");
Cary Clark8032b982017-07-28 11:04:54 -04002798}
2799 #StdOut
Cary Clarkbad5ad72017-08-03 17:14:08 -04002800 quickReject true
Cary Clark8032b982017-07-28 11:04:54 -04002801 quickReject false
2802 ##
2803##
2804
Cary Clark2ade9972017-11-02 17:49:34 -04002805#SeeAlso getLocalClipBounds getTotalMatrix SkBitmap::drawsNothing
Cary Clark8032b982017-07-28 11:04:54 -04002806
2807##
2808
2809#Method bool quickReject(const SkPath& path) const
2810
Cary Clarkab2621d2018-01-30 10:08:57 -05002811#In Clip
Cary Clark80247e52018-07-11 16:18:41 -04002812Returns true if path, transformed by Matrix, can be quickly determined to be
Cary Clark8032b982017-07-28 11:04:54 -04002813outside of Clip. May return false even though path is outside of Clip.
2814
2815Use to check if an area to be drawn is clipped out, to skip subsequent draw calls.
2816
Cary Clarkbad5ad72017-08-03 17:14:08 -04002817#Param path Path to compare with Clip ##
Cary Clark8032b982017-07-28 11:04:54 -04002818
Cary Clarkbad5ad72017-08-03 17:14:08 -04002819#Return true if path, transformed by Matrix, does not intersect Clip ##
Cary Clark8032b982017-07-28 11:04:54 -04002820
2821#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04002822void draw(SkCanvas* canvas) {
Herb Derbyefe39bc2018-05-01 17:06:20 -04002823 SkPoint testPoints[] = {{30, 30}, {120, 30}, {120, 129} };
2824 SkPoint clipPoints[] = {{30, 130}, {120, 130}, {120, 230} };
Cary Clarkbad5ad72017-08-03 17:14:08 -04002825 SkPath testPath, clipPath;
2826 testPath.addPoly(testPoints, SK_ARRAY_COUNT(testPoints), true);
2827 clipPath.addPoly(clipPoints, SK_ARRAY_COUNT(clipPoints), true);
2828 canvas->save();
2829 canvas->clipPath(clipPath);
2830 SkDebugf("quickReject %s\n", canvas->quickReject(testPath) ? "true" : "false");
2831 canvas->restore();
2832 canvas->rotate(10);
2833 canvas->clipPath(clipPath);
2834 SkDebugf("quickReject %s\n", canvas->quickReject(testPath) ? "true" : "false");
Cary Clark8032b982017-07-28 11:04:54 -04002835 #StdOut
Cary Clarkbad5ad72017-08-03 17:14:08 -04002836 quickReject true
Cary Clark8032b982017-07-28 11:04:54 -04002837 quickReject false
2838 ##
2839}
2840##
2841
Cary Clark2ade9972017-11-02 17:49:34 -04002842#SeeAlso getLocalClipBounds getTotalMatrix SkBitmap::drawsNothing
Cary Clark8032b982017-07-28 11:04:54 -04002843
2844##
2845
Herb Derbyefe39bc2018-05-01 17:06:20 -04002846#Method SkRect getLocalClipBounds() const
Cary Clark8032b982017-07-28 11:04:54 -04002847
Cary Clarkab2621d2018-01-30 10:08:57 -05002848#In Clip
2849#Line # returns Clip bounds in source coordinates ##
Cary Clark80247e52018-07-11 16:18:41 -04002850Returns bounds of Clip, transformed by inverse of Matrix. If Clip is empty,
Cary Clark8032b982017-07-28 11:04:54 -04002851return SkRect::MakeEmpty, where all Rect sides equal zero.
2852
2853Rect returned is outset by one to account for partial pixel coverage if Clip
Cary Clarkffb3d682018-05-17 12:17:28 -04002854is Anti_Aliased.
Cary Clark8032b982017-07-28 11:04:54 -04002855
Cary Clarkbad5ad72017-08-03 17:14:08 -04002856#Return bounds of Clip in local coordinates ##
Cary Clark8032b982017-07-28 11:04:54 -04002857
2858#Example
Herb Derbyefe39bc2018-05-01 17:06:20 -04002859 #Description
Cary Clark8032b982017-07-28 11:04:54 -04002860 Initial bounds is device bounds outset by 1 on all sides.
2861 Clipped bounds is clipPath bounds outset by 1 on all sides.
Cary Clark5538c132018-06-14 12:28:14 -04002862 Scaling the canvas by two on both axes scales the local bounds by 1/2
2863 on both axes.
Cary Clark8032b982017-07-28 11:04:54 -04002864 ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002865 SkCanvas local(256, 256);
2866 canvas = &local;
2867 SkRect bounds = canvas->getLocalClipBounds();
2868 SkDebugf("left:%g top:%g right:%g bottom:%g\n",
2869 bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom);
Herb Derbyefe39bc2018-05-01 17:06:20 -04002870 SkPoint clipPoints[] = {{30, 130}, {120, 130}, {120, 230} };
Cary Clarkbad5ad72017-08-03 17:14:08 -04002871 SkPath clipPath;
2872 clipPath.addPoly(clipPoints, SK_ARRAY_COUNT(clipPoints), true);
2873 canvas->clipPath(clipPath);
2874 bounds = canvas->getLocalClipBounds();
2875 SkDebugf("left:%g top:%g right:%g bottom:%g\n",
2876 bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom);
2877 canvas->scale(2, 2);
2878 bounds = canvas->getLocalClipBounds();
2879 SkDebugf("left:%g top:%g right:%g bottom:%g\n",
2880 bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom);
2881 #StdOut
2882 left:-1 top:-1 right:257 bottom:257
2883 left:29 top:129 right:121 bottom:231
2884 left:14.5 top:64.5 right:60.5 bottom:115.5
2885 ##
Cary Clark8032b982017-07-28 11:04:54 -04002886##
2887
2888# local canvas in example works around bug in fiddle ##
Cary Clark4855f782018-02-06 09:41:53 -05002889#Bug 6524
Cary Clark2ade9972017-11-02 17:49:34 -04002890#SeeAlso getDeviceClipBounds getBaseLayerSize quickReject
Cary Clark8032b982017-07-28 11:04:54 -04002891
2892##
2893
Herb Derbyefe39bc2018-05-01 17:06:20 -04002894#Method bool getLocalClipBounds(SkRect* bounds) const
Cary Clark8032b982017-07-28 11:04:54 -04002895
Cary Clarkab2621d2018-01-30 10:08:57 -05002896#In Clip
Cary Clark80247e52018-07-11 16:18:41 -04002897Returns bounds of Clip, transformed by inverse of Matrix. If Clip is empty,
Cary Clark8032b982017-07-28 11:04:54 -04002898return false, and set bounds to SkRect::MakeEmpty, where all Rect sides equal zero.
2899
2900bounds is outset by one to account for partial pixel coverage if Clip
Cary Clarkffb3d682018-05-17 12:17:28 -04002901is Anti_Aliased.
Cary Clark8032b982017-07-28 11:04:54 -04002902
Cary Clarkbad5ad72017-08-03 17:14:08 -04002903#Param bounds Rect of Clip in local coordinates ##
Cary Clark8032b982017-07-28 11:04:54 -04002904
Cary Clarkbad5ad72017-08-03 17:14:08 -04002905#Return true if Clip bounds is not empty ##
Cary Clark8032b982017-07-28 11:04:54 -04002906
2907#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04002908 void draw(SkCanvas* canvas) {
2909 SkCanvas local(256, 256);
2910 canvas = &local;
2911 SkRect bounds;
2912 SkDebugf("local bounds empty = %s\n", canvas->getLocalClipBounds(&bounds)
2913 ? "false" : "true");
2914 SkPath path;
2915 canvas->clipPath(path);
2916 SkDebugf("local bounds empty = %s\n", canvas->getLocalClipBounds(&bounds)
2917 ? "false" : "true");
Cary Clark8032b982017-07-28 11:04:54 -04002918 }
2919 #StdOut
Cary Clarkbad5ad72017-08-03 17:14:08 -04002920 local bounds empty = false
Cary Clark8032b982017-07-28 11:04:54 -04002921 local bounds empty = true
2922 ##
2923##
2924
2925# local canvas in example works around bug in fiddle ##
Cary Clark4855f782018-02-06 09:41:53 -05002926#Bug 6524
Cary Clark2ade9972017-11-02 17:49:34 -04002927#SeeAlso getDeviceClipBounds getBaseLayerSize quickReject
Cary Clark8032b982017-07-28 11:04:54 -04002928
2929##
2930
Herb Derbyefe39bc2018-05-01 17:06:20 -04002931#Method SkIRect getDeviceClipBounds() const
Cary Clark8032b982017-07-28 11:04:54 -04002932
Cary Clarkab2621d2018-01-30 10:08:57 -05002933#In Clip
2934#Line # returns IRect bounds of Clip ##
Cary Clark80247e52018-07-11 16:18:41 -04002935Returns IRect bounds of Clip, unaffected by Matrix. If Clip is empty,
Cary Clark8032b982017-07-28 11:04:54 -04002936return SkRect::MakeEmpty, where all Rect sides equal zero.
2937
Herb Derbyefe39bc2018-05-01 17:06:20 -04002938Unlike getLocalClipBounds, returned IRect is not outset.
Cary Clark8032b982017-07-28 11:04:54 -04002939
Cary Clarkbad5ad72017-08-03 17:14:08 -04002940#Return bounds of Clip in Device coordinates ##
Cary Clark8032b982017-07-28 11:04:54 -04002941
2942#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04002943void draw(SkCanvas* canvas) {
2944 #Description
Cary Clark8032b982017-07-28 11:04:54 -04002945 Initial bounds is device bounds, not outset.
2946 Clipped bounds is clipPath bounds, not outset.
Cary Clark5538c132018-06-14 12:28:14 -04002947 Scaling the canvas by 1/2 on both axes scales the device bounds by 1/2
2948 on both axes.
Cary Clarkbad5ad72017-08-03 17:14:08 -04002949 ##
2950 SkCanvas device(256, 256);
2951 canvas = &device;
2952 SkIRect bounds = canvas->getDeviceClipBounds();
2953 SkDebugf("left:%d top:%d right:%d bottom:%d\n",
2954 bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom);
Herb Derbyefe39bc2018-05-01 17:06:20 -04002955 SkPoint clipPoints[] = {{30, 130}, {120, 130}, {120, 230} };
Cary Clarkbad5ad72017-08-03 17:14:08 -04002956 SkPath clipPath;
2957 clipPath.addPoly(clipPoints, SK_ARRAY_COUNT(clipPoints), true);
2958 canvas->save();
2959 canvas->clipPath(clipPath);
2960 bounds = canvas->getDeviceClipBounds();
2961 SkDebugf("left:%d top:%d right:%d bottom:%d\n",
2962 bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom);
2963 canvas->restore();
2964 canvas->scale(1.f/2, 1.f/2);
2965 canvas->clipPath(clipPath);
2966 bounds = canvas->getDeviceClipBounds();
2967 SkDebugf("left:%d top:%d right:%d bottom:%d\n",
2968 bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom);
Cary Clark8032b982017-07-28 11:04:54 -04002969 #StdOut
Cary Clarkbad5ad72017-08-03 17:14:08 -04002970 left:0 top:0 right:256 bottom:256
2971 left:30 top:130 right:120 bottom:230
Cary Clark8032b982017-07-28 11:04:54 -04002972 left:15 top:65 right:60 bottom:115
2973 ##
2974}
2975##
2976
2977#ToDo some confusion on why with an identity Matrix local and device are different ##
Cary Clark2ade9972017-11-02 17:49:34 -04002978#SeeAlso getLocalClipBounds getBaseLayerSize quickReject
Cary Clark8032b982017-07-28 11:04:54 -04002979
2980# device canvas in example works around bug in fiddle ##
Cary Clark4855f782018-02-06 09:41:53 -05002981#Bug 6524
Cary Clark8032b982017-07-28 11:04:54 -04002982
2983##
2984
Herb Derbyefe39bc2018-05-01 17:06:20 -04002985#Method bool getDeviceClipBounds(SkIRect* bounds) const
Cary Clark8032b982017-07-28 11:04:54 -04002986
Cary Clarkab2621d2018-01-30 10:08:57 -05002987#In Clip
Cary Clark80247e52018-07-11 16:18:41 -04002988Returns IRect bounds of Clip, unaffected by Matrix. If Clip is empty,
Cary Clark8032b982017-07-28 11:04:54 -04002989return false, and set bounds to SkRect::MakeEmpty, where all Rect sides equal zero.
2990
Herb Derbyefe39bc2018-05-01 17:06:20 -04002991Unlike getLocalClipBounds, bounds is not outset.
Cary Clark8032b982017-07-28 11:04:54 -04002992
Cary Clarkbad5ad72017-08-03 17:14:08 -04002993#Param bounds Rect of Clip in device coordinates ##
Cary Clark8032b982017-07-28 11:04:54 -04002994
Cary Clarkbad5ad72017-08-03 17:14:08 -04002995#Return true if Clip bounds is not empty ##
Cary Clark8032b982017-07-28 11:04:54 -04002996
2997#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04002998 void draw(SkCanvas* canvas) {
2999 SkIRect bounds;
3000 SkDebugf("device bounds empty = %s\n", canvas->getDeviceClipBounds(&bounds)
3001 ? "false" : "true");
3002 SkPath path;
3003 canvas->clipPath(path);
3004 SkDebugf("device bounds empty = %s\n", canvas->getDeviceClipBounds(&bounds)
3005 ? "false" : "true");
Cary Clark8032b982017-07-28 11:04:54 -04003006 }
3007 #StdOut
Cary Clarkbad5ad72017-08-03 17:14:08 -04003008 device bounds empty = false
Cary Clark8032b982017-07-28 11:04:54 -04003009 device bounds empty = true
3010 ##
3011##
3012
Cary Clark2ade9972017-11-02 17:49:34 -04003013#SeeAlso getLocalClipBounds getBaseLayerSize quickReject
Cary Clark8032b982017-07-28 11:04:54 -04003014
3015##
3016
Cary Clark08895c42018-02-01 09:37:32 -05003017#Subtopic Clip ##
Cary Clark8032b982017-07-28 11:04:54 -04003018
3019# ------------------------------------------------------------------------------
Cary Clark78de7512018-02-07 07:27:09 -05003020#Subtopic Draw
3021#Populate
3022#Line # draws into Canvas ##
3023##
Cary Clark8032b982017-07-28 11:04:54 -04003024
3025#Method void drawColor(SkColor color, SkBlendMode mode = SkBlendMode::kSrcOver)
Cary Clark78de7512018-02-07 07:27:09 -05003026#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05003027#Line # fills Clip with Color and Blend_Mode ##
Cary Clark80247e52018-07-11 16:18:41 -04003028Fills Clip with Color color.
Cary Clarkffb3d682018-05-17 12:17:28 -04003029mode determines how ARGB is combined with destination.
Cary Clark8032b982017-07-28 11:04:54 -04003030
Cary Clarkffb3d682018-05-17 12:17:28 -04003031#Param color Unpremultiplied ARGB ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003032#Param mode SkBlendMode used to combine source color and destination ##
Cary Clark8032b982017-07-28 11:04:54 -04003033
3034#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003035 canvas->drawColor(SK_ColorRED);
3036 canvas->clipRect(SkRect::MakeWH(150, 150));
3037 canvas->drawColor(SkColorSetARGB(0x80, 0x00, 0xFF, 0x00), SkBlendMode::kPlus);
3038 canvas->clipRect(SkRect::MakeWH(75, 75));
3039 canvas->drawColor(SkColorSetARGB(0x80, 0x00, 0x00, 0xFF), SkBlendMode::kPlus);
Cary Clark8032b982017-07-28 11:04:54 -04003040##
3041
Cary Clark2ade9972017-11-02 17:49:34 -04003042#SeeAlso clear SkBitmap::erase drawPaint
Cary Clark8032b982017-07-28 11:04:54 -04003043
3044##
3045
3046# ------------------------------------------------------------------------------
3047
Herb Derbyefe39bc2018-05-01 17:06:20 -04003048#Method void clear(SkColor color)
Cary Clark78de7512018-02-07 07:27:09 -05003049#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05003050#Line # fills Clip with Color ##
Cary Clark80247e52018-07-11 16:18:41 -04003051Fills Clip with Color color using SkBlendMode::kSrc.
Cary Clark8032b982017-07-28 11:04:54 -04003052This has the effect of replacing all pixels contained by Clip with color.
3053
Cary Clarkffb3d682018-05-17 12:17:28 -04003054#Param color Unpremultiplied ARGB ##
Cary Clark8032b982017-07-28 11:04:54 -04003055
3056#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003057void draw(SkCanvas* canvas) {
3058 canvas->save();
3059 canvas->clipRect(SkRect::MakeWH(256, 128));
Herb Derbyefe39bc2018-05-01 17:06:20 -04003060 canvas->clear(SkColorSetARGB(0x80, 0xFF, 0x00, 0x00));
Cary Clarkbad5ad72017-08-03 17:14:08 -04003061 canvas->restore();
3062 canvas->save();
3063 canvas->clipRect(SkRect::MakeWH(150, 192));
3064 canvas->clear(SkColorSetARGB(0x80, 0x00, 0xFF, 0x00));
3065 canvas->restore();
3066 canvas->clipRect(SkRect::MakeWH(75, 256));
3067 canvas->clear(SkColorSetARGB(0x80, 0x00, 0x00, 0xFF));
Cary Clark8032b982017-07-28 11:04:54 -04003068}
3069##
3070
Cary Clark2ade9972017-11-02 17:49:34 -04003071#SeeAlso drawColor SkBitmap::erase drawPaint
Cary Clark8032b982017-07-28 11:04:54 -04003072
3073##
3074
3075# ------------------------------------------------------------------------------
3076
Herb Derbyefe39bc2018-05-01 17:06:20 -04003077#Method void discard()
Cary Clark78de7512018-02-07 07:27:09 -05003078#In Utility
Cary Clarkab2621d2018-01-30 10:08:57 -05003079#Line # makes Canvas contents undefined ##
Cary Clark80247e52018-07-11 16:18:41 -04003080Makes Canvas contents undefined. Subsequent calls that read Canvas pixels,
Cary Clark8032b982017-07-28 11:04:54 -04003081such as drawing with SkBlendMode, return undefined results. discard() does
3082not change Clip or Matrix.
3083
3084discard() may do nothing, depending on the implementation of Surface or Device
3085that created Canvas.
3086
3087discard() allows optimized performance on subsequent draws by removing
3088cached data associated with Surface or Device.
3089It is not necessary to call discard() once done with Canvas;
3090any cached data is deleted when owning Surface or Device is deleted.
3091
3092#ToDo example? not sure how to make this meaningful w/o more implementation detail ##
Cary Clark2ade9972017-11-02 17:49:34 -04003093#SeeAlso flush() SkSurface::prepareForExternalIO GrContext::abandonContext
Cary Clark8032b982017-07-28 11:04:54 -04003094
Herb Derbyefe39bc2018-05-01 17:06:20 -04003095#NoExample
Cary Clark8032b982017-07-28 11:04:54 -04003096##
3097
3098##
3099
3100# ------------------------------------------------------------------------------
3101
3102#Method void drawPaint(const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05003103#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05003104#Line # fills Clip with Paint ##
Cary Clark80247e52018-07-11 16:18:41 -04003105Fills Clip with Paint paint. Paint components Mask_Filter, Shader,
Cary Clarkbad5ad72017-08-03 17:14:08 -04003106Color_Filter, Image_Filter, and Blend_Mode affect drawing;
3107Path_Effect in paint is ignored.
Cary Clark8032b982017-07-28 11:04:54 -04003108
3109# can Path_Effect in paint ever alter drawPaint?
3110
Cary Clarkbad5ad72017-08-03 17:14:08 -04003111#Param paint graphics state used to fill Canvas ##
Cary Clark8032b982017-07-28 11:04:54 -04003112
3113#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003114void draw(SkCanvas* canvas) {
3115 SkColor colors[] = { SK_ColorRED, SK_ColorGREEN, SK_ColorBLUE };
3116 SkScalar pos[] = { 0, SK_Scalar1/2, SK_Scalar1 };
3117 SkPaint paint;
3118 paint.setShader(SkGradientShader::MakeSweep(256, 256, colors, pos, SK_ARRAY_COUNT(colors)));
3119 canvas->drawPaint(paint);
Cary Clark8032b982017-07-28 11:04:54 -04003120}
3121##
3122
Cary Clark2ade9972017-11-02 17:49:34 -04003123#SeeAlso clear drawColor SkBitmap::erase
Cary Clark8032b982017-07-28 11:04:54 -04003124
3125##
3126
3127# ------------------------------------------------------------------------------
3128
3129#Enum PointMode
Cary Clark08895c42018-02-01 09:37:32 -05003130#Line # sets drawPoints options ##
Cary Clark8032b982017-07-28 11:04:54 -04003131
3132#Code
3133 enum PointMode {
3134 kPoints_PointMode,
3135 kLines_PointMode,
Cary Clarkd0530ba2017-09-14 11:25:39 -04003136 kPolygon_PointMode,
Cary Clark8032b982017-07-28 11:04:54 -04003137 };
3138##
3139
3140Selects if an array of points are drawn as discrete points, as lines, or as
3141an open polygon.
3142
3143#Const kPoints_PointMode 0
Cary Clark682c58d2018-05-16 07:07:07 -04003144#Line # draw each point separately ##
Cary Clark8032b982017-07-28 11:04:54 -04003145##
3146
3147#Const kLines_PointMode 1
Cary Clark682c58d2018-05-16 07:07:07 -04003148#Line # draw each pair of points as a line segment ##
Cary Clark8032b982017-07-28 11:04:54 -04003149##
3150
3151#Const kPolygon_PointMode 2
Cary Clark682c58d2018-05-16 07:07:07 -04003152#Line # draw the array of points as a open polygon ##
Cary Clark8032b982017-07-28 11:04:54 -04003153##
3154
3155#Example
Herb Derbyefe39bc2018-05-01 17:06:20 -04003156 #Description
Cary Clark8032b982017-07-28 11:04:54 -04003157 The upper left corner shows three squares when drawn as points.
3158 The upper right corner shows one line; when drawn as lines, two points are required per line.
3159 The lower right corner shows two lines; when draw as polygon, no miter is drawn at the corner.
3160 The lower left corner shows two lines with a miter when path contains polygon.
3161 ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003162void draw(SkCanvas* canvas) {
3163 SkPaint paint;
3164 paint.setStyle(SkPaint::kStroke_Style);
3165 paint.setStrokeWidth(10);
3166 SkPoint points[] = {{64, 32}, {96, 96}, {32, 96}};
3167 canvas->drawPoints(SkCanvas::kPoints_PointMode, 3, points, paint);
3168 canvas->translate(128, 0);
3169 canvas->drawPoints(SkCanvas::kLines_PointMode, 3, points, paint);
3170 canvas->translate(0, 128);
3171 canvas->drawPoints(SkCanvas::kPolygon_PointMode, 3, points, paint);
3172 SkPath path;
3173 path.addPoly(points, 3, false);
3174 canvas->translate(-128, 0);
3175 canvas->drawPath(path, paint);
Cary Clark8032b982017-07-28 11:04:54 -04003176}
3177##
3178
Cary Clark2ade9972017-11-02 17:49:34 -04003179#SeeAlso drawLine drawPoint drawPath
Cary Clark8032b982017-07-28 11:04:54 -04003180
3181##
3182
3183# ------------------------------------------------------------------------------
3184
3185#Method void drawPoints(PointMode mode, size_t count, const SkPoint pts[], const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05003186#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05003187#Line # draws array as points, lines, polygon ##
Cary Clark80247e52018-07-11 16:18:41 -04003188Draws pts using Clip, Matrix and Paint paint.
Cary Clarkbad5ad72017-08-03 17:14:08 -04003189count is the number of points; if count is less than one, has no effect.
Cary Clark8032b982017-07-28 11:04:54 -04003190mode may be one of: kPoints_PointMode, kLines_PointMode, or kPolygon_PointMode.
3191
Cary Clarkbad5ad72017-08-03 17:14:08 -04003192If mode is kPoints_PointMode, the shape of point drawn depends on paint
3193Paint_Stroke_Cap. If paint is set to SkPaint::kRound_Cap, each point draws a
3194circle of diameter Paint_Stroke_Width. If paint is set to SkPaint::kSquare_Cap
3195or SkPaint::kButt_Cap, each point draws a square of width and height
3196Paint_Stroke_Width.
Cary Clark8032b982017-07-28 11:04:54 -04003197
3198If mode is kLines_PointMode, each pair of points draws a line segment.
3199One line is drawn for every two points; each point is used once. If count is odd,
Herb Derbyefe39bc2018-05-01 17:06:20 -04003200the final point is ignored.
Cary Clark8032b982017-07-28 11:04:54 -04003201
3202If mode is kPolygon_PointMode, each adjacent pair of points draws a line segment.
3203count minus one lines are drawn; the first and last point are used once.
3204
3205Each line segment respects paint Paint_Stroke_Cap and Paint_Stroke_Width.
3206Paint_Style is ignored, as if were set to SkPaint::kStroke_Style.
3207
Cary Clarkbad5ad72017-08-03 17:14:08 -04003208Always draws each element one at a time; is not affected by
3209Paint_Stroke_Join, and unlike drawPath, does not create a mask from all points
Herb Derbyefe39bc2018-05-01 17:06:20 -04003210and lines before drawing.
Cary Clark8032b982017-07-28 11:04:54 -04003211
Cary Clarka523d2d2017-08-30 08:58:10 -04003212#Param mode whether pts draws points or lines ##
3213#Param count number of points in the array ##
3214#Param pts array of points to draw ##
3215#Param paint stroke, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003216
3217#Example
3218#Height 200
Herb Derbyefe39bc2018-05-01 17:06:20 -04003219 #Description
Cary Clark8032b982017-07-28 11:04:54 -04003220 #List
3221 # The first column draws points. ##
3222 # The second column draws points as lines. ##
3223 # The third column draws points as a polygon. ##
3224 # The fourth column draws points as a polygonal path. ##
3225 # The first row uses a round cap and round join. ##
3226 # The second row uses a square cap and a miter join. ##
3227 # The third row uses a butt cap and a bevel join. ##
3228 ##
3229 The transparent color makes multiple line draws visible;
3230 the path is drawn all at once.
3231 ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003232void draw(SkCanvas* canvas) {
3233 SkPaint paint;
3234 paint.setAntiAlias(true);
3235 paint.setStyle(SkPaint::kStroke_Style);
3236 paint.setStrokeWidth(10);
3237 paint.setColor(0x80349a45);
3238 const SkPoint points[] = {{32, 16}, {48, 48}, {16, 32}};
Herb Derbyefe39bc2018-05-01 17:06:20 -04003239 const SkPaint::Join join[] = { SkPaint::kRound_Join,
Cary Clarkbad5ad72017-08-03 17:14:08 -04003240 SkPaint::kMiter_Join,
3241 SkPaint::kBevel_Join };
3242 int joinIndex = 0;
3243 SkPath path;
3244 path.addPoly(points, 3, false);
3245 for (const auto cap : { SkPaint::kRound_Cap, SkPaint::kSquare_Cap, SkPaint::kButt_Cap } ) {
3246 paint.setStrokeCap(cap);
3247 paint.setStrokeJoin(join[joinIndex++]);
3248 for (const auto mode : { SkCanvas::kPoints_PointMode,
3249 SkCanvas::kLines_PointMode,
3250 SkCanvas::kPolygon_PointMode } ) {
3251 canvas->drawPoints(mode, 3, points, paint);
3252 canvas->translate(64, 0);
3253 }
3254 canvas->drawPath(path, paint);
3255 canvas->translate(-192, 64);
3256 }
Cary Clark8032b982017-07-28 11:04:54 -04003257}
3258##
3259
Cary Clark2ade9972017-11-02 17:49:34 -04003260#SeeAlso drawLine drawPoint drawPath
Cary Clark8032b982017-07-28 11:04:54 -04003261
3262##
3263
3264# ------------------------------------------------------------------------------
3265
3266#Method void drawPoint(SkScalar x, SkScalar y, const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05003267#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05003268#Line # draws point at (x, y) position ##
Cary Clark80247e52018-07-11 16:18:41 -04003269Draws point at (x, y) using Clip, Matrix and Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04003270
3271The shape of point drawn depends on paint Paint_Stroke_Cap.
Cary Clarkbad5ad72017-08-03 17:14:08 -04003272If paint is set to SkPaint::kRound_Cap, draw a circle of diameter
Herb Derbyefe39bc2018-05-01 17:06:20 -04003273Paint_Stroke_Width. If paint is set to SkPaint::kSquare_Cap or SkPaint::kButt_Cap,
Cary Clark8032b982017-07-28 11:04:54 -04003274draw a square of width and height Paint_Stroke_Width.
3275Paint_Style is ignored, as if were set to SkPaint::kStroke_Style.
3276
Cary Clarkbad5ad72017-08-03 17:14:08 -04003277#Param x left edge of circle or square ##
3278#Param y top edge of circle or square ##
3279#Param paint stroke, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003280
3281#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003282void draw(SkCanvas* canvas) {
3283 SkPaint paint;
3284 paint.setAntiAlias(true);
3285 paint.setColor(0x80349a45);
3286 paint.setStyle(SkPaint::kStroke_Style);
3287 paint.setStrokeWidth(100);
3288 paint.setStrokeCap(SkPaint::kRound_Cap);
3289 canvas->scale(1, 1.2f);
3290 canvas->drawPoint(64, 96, paint);
3291 canvas->scale(.6f, .8f);
3292 paint.setColor(SK_ColorWHITE);
3293 canvas->drawPoint(106, 120, paint);
Cary Clark8032b982017-07-28 11:04:54 -04003294}
3295##
3296
Cary Clark2ade9972017-11-02 17:49:34 -04003297#SeeAlso drawPoints drawCircle drawRect drawLine drawPath
Cary Clark8032b982017-07-28 11:04:54 -04003298
3299##
3300
Cary Clarkbad5ad72017-08-03 17:14:08 -04003301#Method void drawPoint(SkPoint p, const SkPaint& paint)
3302
Cary Clark80247e52018-07-11 16:18:41 -04003303Draws point p using Clip, Matrix and Paint paint.
Cary Clarkbad5ad72017-08-03 17:14:08 -04003304
3305The shape of point drawn depends on paint Paint_Stroke_Cap.
3306If paint is set to SkPaint::kRound_Cap, draw a circle of diameter
Herb Derbyefe39bc2018-05-01 17:06:20 -04003307Paint_Stroke_Width. If paint is set to SkPaint::kSquare_Cap or SkPaint::kButt_Cap,
Cary Clarkbad5ad72017-08-03 17:14:08 -04003308draw a square of width and height Paint_Stroke_Width.
3309Paint_Style is ignored, as if were set to SkPaint::kStroke_Style.
3310
3311#Param p top-left edge of circle or square ##
3312#Param paint stroke, blend, color, and so on, used to draw ##
3313
3314#Example
3315void draw(SkCanvas* canvas) {
3316 SkPaint paint;
3317 paint.setAntiAlias(true);
3318 paint.setColor(0x80349a45);
3319 paint.setStyle(SkPaint::kStroke_Style);
3320 paint.setStrokeWidth(100);
3321 paint.setStrokeCap(SkPaint::kSquare_Cap);
3322 canvas->scale(1, 1.2f);
3323 canvas->drawPoint({64, 96}, paint);
3324 canvas->scale(.6f, .8f);
3325 paint.setColor(SK_ColorWHITE);
3326 canvas->drawPoint(106, 120, paint);
3327}
3328##
3329
Cary Clark2ade9972017-11-02 17:49:34 -04003330#SeeAlso drawPoints drawCircle drawRect drawLine drawPath
Cary Clarkbad5ad72017-08-03 17:14:08 -04003331
3332##
3333
Cary Clark8032b982017-07-28 11:04:54 -04003334# ------------------------------------------------------------------------------
3335
3336#Method void drawLine(SkScalar x0, SkScalar y0, SkScalar x1, SkScalar y1, const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05003337#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05003338#Line # draws line segment between two points ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003339Draws line segment from (x0, y0) to (x1, y1) using Clip, Matrix, and Paint paint.
3340In paint: Paint_Stroke_Width describes the line thickness;
3341Paint_Stroke_Cap draws the end rounded or square;
Cary Clark8032b982017-07-28 11:04:54 -04003342Paint_Style is ignored, as if were set to SkPaint::kStroke_Style.
3343
Cary Clarkbad5ad72017-08-03 17:14:08 -04003344#Param x0 start of line segment on x-axis ##
3345#Param y0 start of line segment on y-axis ##
3346#Param x1 end of line segment on x-axis ##
3347#Param y1 end of line segment on y-axis ##
3348#Param paint stroke, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003349
3350#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003351 SkPaint paint;
3352 paint.setAntiAlias(true);
3353 paint.setColor(0xFF9a67be);
3354 paint.setStrokeWidth(20);
3355 canvas->skew(1, 0);
3356 canvas->drawLine(32, 96, 32, 160, paint);
3357 canvas->skew(-2, 0);
3358 canvas->drawLine(288, 96, 288, 160, paint);
3359##
3360
Cary Clark2ade9972017-11-02 17:49:34 -04003361#SeeAlso drawPoint drawCircle drawRect drawPath
Cary Clarkbad5ad72017-08-03 17:14:08 -04003362
3363##
3364
3365#Method void drawLine(SkPoint p0, SkPoint p1, const SkPaint& paint)
3366
3367Draws line segment from p0 to p1 using Clip, Matrix, and Paint paint.
3368In paint: Paint_Stroke_Width describes the line thickness;
3369Paint_Stroke_Cap draws the end rounded or square;
3370Paint_Style is ignored, as if were set to SkPaint::kStroke_Style.
3371
3372#Param p0 start of line segment ##
3373#Param p1 end of line segment ##
3374#Param paint stroke, blend, color, and so on, used to draw ##
3375
3376#Example
3377 SkPaint paint;
3378 paint.setAntiAlias(true);
3379 paint.setColor(0xFF9a67be);
3380 paint.setStrokeWidth(20);
3381 canvas->skew(1, 0);
3382 canvas->drawLine({32, 96}, {32, 160}, paint);
3383 canvas->skew(-2, 0);
3384 canvas->drawLine({288, 96}, {288, 160}, paint);
Cary Clark8032b982017-07-28 11:04:54 -04003385##
3386
Cary Clark2ade9972017-11-02 17:49:34 -04003387#SeeAlso drawPoint drawCircle drawRect drawPath
Cary Clark8032b982017-07-28 11:04:54 -04003388
3389##
3390
3391# ------------------------------------------------------------------------------
3392
3393#Method void drawRect(const SkRect& rect, const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05003394#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05003395#Line # draws Rect using Clip, Matrix, and Paint ##
Cary Clark80247e52018-07-11 16:18:41 -04003396Draws Rect rect using Clip, Matrix, and Paint paint.
Herb Derbyefe39bc2018-05-01 17:06:20 -04003397In paint: Paint_Style determines if rectangle is stroked or filled;
Cary Clark8032b982017-07-28 11:04:54 -04003398if stroked, Paint_Stroke_Width describes the line thickness, and
3399Paint_Stroke_Join draws the corners rounded or square.
3400
Cary Clarkbc5697d2017-10-04 14:31:33 -04003401#Param rect rectangle to draw ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003402#Param paint stroke or fill, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003403
3404#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003405void draw(SkCanvas* canvas) {
3406 SkPoint rectPts[] = { {64, 48}, {192, 160} };
3407 SkPaint paint;
3408 paint.setAntiAlias(true);
3409 paint.setStyle(SkPaint::kStroke_Style);
3410 paint.setStrokeWidth(20);
3411 paint.setStrokeJoin(SkPaint::kRound_Join);
3412 SkMatrix rotator;
3413 rotator.setRotate(30, 128, 128);
3414 for (auto color : { SK_ColorRED, SK_ColorBLUE, SK_ColorYELLOW, SK_ColorMAGENTA } ) {
3415 paint.setColor(color);
3416 SkRect rect;
3417 rect.set(rectPts[0], rectPts[1]);
3418 canvas->drawRect(rect, paint);
3419 rotator.mapPoints(rectPts, 2);
3420 }
Cary Clark8032b982017-07-28 11:04:54 -04003421}
3422##
3423
Herb Derbyefe39bc2018-05-01 17:06:20 -04003424#SeeAlso drawIRect drawRRect drawRoundRect drawRegion drawPath drawLine
Cary Clark8032b982017-07-28 11:04:54 -04003425
3426##
3427
3428# ------------------------------------------------------------------------------
3429
Herb Derbyefe39bc2018-05-01 17:06:20 -04003430#Method void drawIRect(const SkIRect& rect, const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05003431#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05003432#Line # draws IRect using Clip, Matrix, and Paint ##
Cary Clark80247e52018-07-11 16:18:41 -04003433Draws IRect rect using Clip, Matrix, and Paint paint.
Herb Derbyefe39bc2018-05-01 17:06:20 -04003434In paint: Paint_Style determines if rectangle is stroked or filled;
Cary Clark8032b982017-07-28 11:04:54 -04003435if stroked, Paint_Stroke_Width describes the line thickness, and
3436Paint_Stroke_Join draws the corners rounded or square.
3437
Cary Clarkbc5697d2017-10-04 14:31:33 -04003438#Param rect rectangle to draw ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003439#Param paint stroke or fill, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003440
3441#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003442 SkIRect rect = { 64, 48, 192, 160 };
3443 SkPaint paint;
3444 paint.setAntiAlias(true);
3445 paint.setStyle(SkPaint::kStroke_Style);
3446 paint.setStrokeWidth(20);
3447 paint.setStrokeJoin(SkPaint::kRound_Join);
3448 for (auto color : { SK_ColorRED, SK_ColorBLUE, SK_ColorYELLOW, SK_ColorMAGENTA } ) {
3449 paint.setColor(color);
3450 canvas->drawIRect(rect, paint);
3451 canvas->rotate(30, 128, 128);
3452 }
Cary Clark8032b982017-07-28 11:04:54 -04003453##
3454
Cary Clark2ade9972017-11-02 17:49:34 -04003455#SeeAlso drawRect drawRRect drawRoundRect drawRegion drawPath drawLine
Cary Clark8032b982017-07-28 11:04:54 -04003456
3457##
3458
3459# ------------------------------------------------------------------------------
3460
3461#Method void drawRegion(const SkRegion& region, const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05003462#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05003463#Line # draws Region using Clip, Matrix, and Paint ##
Cary Clark80247e52018-07-11 16:18:41 -04003464Draws Region region using Clip, Matrix, and Paint paint.
Herb Derbyefe39bc2018-05-01 17:06:20 -04003465In paint: Paint_Style determines if rectangle is stroked or filled;
Cary Clark8032b982017-07-28 11:04:54 -04003466if stroked, Paint_Stroke_Width describes the line thickness, and
3467Paint_Stroke_Join draws the corners rounded or square.
3468
Cary Clarkbc5697d2017-10-04 14:31:33 -04003469#Param region region to draw ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003470#Param paint Paint stroke or fill, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003471
3472#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003473void draw(SkCanvas* canvas) {
3474 SkRegion region;
3475 region.op( 10, 10, 50, 50, SkRegion::kUnion_Op);
3476 region.op( 10, 50, 90, 90, SkRegion::kUnion_Op);
3477 SkPaint paint;
3478 paint.setAntiAlias(true);
3479 paint.setStyle(SkPaint::kStroke_Style);
3480 paint.setStrokeWidth(20);
3481 paint.setStrokeJoin(SkPaint::kRound_Join);
3482 canvas->drawRegion(region, paint);
Cary Clark8032b982017-07-28 11:04:54 -04003483}
3484##
3485
Cary Clark2ade9972017-11-02 17:49:34 -04003486#SeeAlso drawRect drawIRect drawPath
Cary Clark8032b982017-07-28 11:04:54 -04003487
3488##
3489
3490# ------------------------------------------------------------------------------
3491
3492#Method void drawOval(const SkRect& oval, const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05003493#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05003494#Line # draws Oval using Clip, Matrix, and Paint ##
Cary Clark80247e52018-07-11 16:18:41 -04003495Draws Oval oval using Clip, Matrix, and Paint.
Herb Derbyefe39bc2018-05-01 17:06:20 -04003496In paint: Paint_Style determines if Oval is stroked or filled;
Cary Clark8032b982017-07-28 11:04:54 -04003497if stroked, Paint_Stroke_Width describes the line thickness.
3498
Cary Clarkbad5ad72017-08-03 17:14:08 -04003499#Param oval Rect bounds of Oval ##
3500#Param paint Paint stroke or fill, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003501
3502#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003503void draw(SkCanvas* canvas) {
3504 canvas->clear(0xFF3f5f9f);
3505 SkColor kColor1 = SkColorSetARGB(0xff, 0xff, 0x7f, 0);
3506 SkColor g1Colors[] = { kColor1, SkColorSetA(kColor1, 0x20) };
3507 SkPoint g1Points[] = { { 0, 0 }, { 0, 100 } };
3508 SkScalar pos[] = { 0.2f, 1.0f };
3509 SkRect bounds = SkRect::MakeWH(80, 70);
3510 SkPaint paint;
3511 paint.setAntiAlias(true);
3512 paint.setShader(SkGradientShader::MakeLinear(g1Points, g1Colors, pos, SK_ARRAY_COUNT(g1Colors),
3513 SkShader::kClamp_TileMode));
3514 canvas->drawOval(bounds , paint);
Cary Clark8032b982017-07-28 11:04:54 -04003515}
3516##
3517
Cary Clark2ade9972017-11-02 17:49:34 -04003518#SeeAlso drawCircle drawPoint drawPath drawRRect drawRoundRect
Cary Clark8032b982017-07-28 11:04:54 -04003519
3520##
3521
3522# ------------------------------------------------------------------------------
3523
3524#Method void drawRRect(const SkRRect& rrect, const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05003525#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05003526#Line # draws Round_Rect using Clip, Matrix, and Paint ##
Cary Clark80247e52018-07-11 16:18:41 -04003527Draws Round_Rect rrect using Clip, Matrix, and Paint paint.
Herb Derbyefe39bc2018-05-01 17:06:20 -04003528In paint: Paint_Style determines if rrect is stroked or filled;
Cary Clark8032b982017-07-28 11:04:54 -04003529if stroked, Paint_Stroke_Width describes the line thickness.
3530
Cary Clarkbad5ad72017-08-03 17:14:08 -04003531rrect may represent a rectangle, circle, oval, uniformly rounded rectangle, or
3532may have any combination of positive non-square radii for the four corners.
Cary Clark8032b982017-07-28 11:04:54 -04003533
Cary Clarkbad5ad72017-08-03 17:14:08 -04003534#Param rrect Round_Rect with up to eight corner radii to draw ##
3535#Param paint Paint stroke or fill, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003536
3537#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003538void draw(SkCanvas* canvas) {
3539 SkPaint paint;
3540 paint.setAntiAlias(true);
3541 SkRect outer = {30, 40, 210, 220};
3542 SkRect radii = {30, 50, 70, 90 };
3543 SkRRect rRect;
3544 rRect.setNinePatch(outer, radii.fLeft, radii.fTop, radii.fRight, radii.fBottom);
3545 canvas->drawRRect(rRect, paint);
3546 paint.setColor(SK_ColorWHITE);
3547 canvas->drawLine(outer.fLeft + radii.fLeft, outer.fTop,
3548 outer.fLeft + radii.fLeft, outer.fBottom, paint);
Herb Derbyefe39bc2018-05-01 17:06:20 -04003549 canvas->drawLine(outer.fRight - radii.fRight, outer.fTop,
Cary Clarkbad5ad72017-08-03 17:14:08 -04003550 outer.fRight - radii.fRight, outer.fBottom, paint);
Herb Derbyefe39bc2018-05-01 17:06:20 -04003551 canvas->drawLine(outer.fLeft, outer.fTop + radii.fTop,
Cary Clarkbad5ad72017-08-03 17:14:08 -04003552 outer.fRight, outer.fTop + radii.fTop, paint);
Herb Derbyefe39bc2018-05-01 17:06:20 -04003553 canvas->drawLine(outer.fLeft, outer.fBottom - radii.fBottom,
Cary Clarkbad5ad72017-08-03 17:14:08 -04003554 outer.fRight, outer.fBottom - radii.fBottom, paint);
3555}
Cary Clark8032b982017-07-28 11:04:54 -04003556##
3557
Cary Clark2ade9972017-11-02 17:49:34 -04003558#SeeAlso drawRect drawRoundRect drawDRRect drawCircle drawOval drawPath
Cary Clark8032b982017-07-28 11:04:54 -04003559
3560##
3561
3562# ------------------------------------------------------------------------------
3563
3564#Method void drawDRRect(const SkRRect& outer, const SkRRect& inner, const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05003565#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05003566#Line # draws double Round_Rect stroked or filled ##
Cary Clark80247e52018-07-11 16:18:41 -04003567Draws Round_Rect outer and inner
Herb Derbyefe39bc2018-05-01 17:06:20 -04003568using Clip, Matrix, and Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04003569outer must contain inner or the drawing is undefined.
Herb Derbyefe39bc2018-05-01 17:06:20 -04003570In paint: Paint_Style determines if Round_Rect is stroked or filled;
Cary Clark8032b982017-07-28 11:04:54 -04003571if stroked, Paint_Stroke_Width describes the line thickness.
Cary Clarkbad5ad72017-08-03 17:14:08 -04003572If stroked and Round_Rect corner has zero length radii, Paint_Stroke_Join can
Herb Derbyefe39bc2018-05-01 17:06:20 -04003573draw corners rounded or square.
Cary Clark8032b982017-07-28 11:04:54 -04003574
Cary Clarkbad5ad72017-08-03 17:14:08 -04003575GPU-backed platforms optimize drawing when both outer and inner are
Cary Clark8032b982017-07-28 11:04:54 -04003576concave and outer contains inner. These platforms may not be able to draw
Herb Derbyefe39bc2018-05-01 17:06:20 -04003577Path built with identical data as fast.
Cary Clark8032b982017-07-28 11:04:54 -04003578
Cary Clarkbad5ad72017-08-03 17:14:08 -04003579#Param outer Round_Rect outer bounds to draw ##
3580#Param inner Round_Rect inner bounds to draw ##
3581#Param paint Paint stroke or fill, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003582
3583#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003584void draw(SkCanvas* canvas) {
3585 SkRRect outer = SkRRect::MakeRect({20, 40, 210, 200});
3586 SkRRect inner = SkRRect::MakeOval({60, 70, 170, 160});
3587 SkPaint paint;
3588 canvas->drawDRRect(outer, inner, paint);
Cary Clark8032b982017-07-28 11:04:54 -04003589}
3590##
3591
3592#Example
3593#Description
3594 Outer Rect has no corner radii, but stroke join is rounded.
3595 Inner Round_Rect has corner radii; outset stroke increases radii of corners.
3596 Stroke join does not affect inner Round_Rect since it has no sharp corners.
3597##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003598void draw(SkCanvas* canvas) {
3599 SkRRect outer = SkRRect::MakeRect({20, 40, 210, 200});
3600 SkRRect inner = SkRRect::MakeRectXY({60, 70, 170, 160}, 10, 10);
3601 SkPaint paint;
3602 paint.setAntiAlias(true);
3603 paint.setStyle(SkPaint::kStroke_Style);
3604 paint.setStrokeWidth(20);
3605 paint.setStrokeJoin(SkPaint::kRound_Join);
3606 canvas->drawDRRect(outer, inner, paint);
3607 paint.setStrokeWidth(1);
3608 paint.setColor(SK_ColorWHITE);
3609 canvas->drawDRRect(outer, inner, paint);
Cary Clark8032b982017-07-28 11:04:54 -04003610}
3611##
3612
Cary Clark2ade9972017-11-02 17:49:34 -04003613#SeeAlso drawRect drawRoundRect drawRRect drawCircle drawOval drawPath
Cary Clark8032b982017-07-28 11:04:54 -04003614
3615##
3616
3617# ------------------------------------------------------------------------------
3618
3619#Method void drawCircle(SkScalar cx, SkScalar cy, SkScalar radius, const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05003620#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05003621#Line # draws Circle using Clip, Matrix, and Paint ##
Cary Clark80247e52018-07-11 16:18:41 -04003622Draws Circle at (cx, cy) with radius using Clip, Matrix, and Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04003623If radius is zero or less, nothing is drawn.
Herb Derbyefe39bc2018-05-01 17:06:20 -04003624In paint: Paint_Style determines if Circle is stroked or filled;
Cary Clark8032b982017-07-28 11:04:54 -04003625if stroked, Paint_Stroke_Width describes the line thickness.
3626
Cary Clarkbad5ad72017-08-03 17:14:08 -04003627#Param cx Circle center on the x-axis ##
3628#Param cy Circle center on the y-axis ##
3629#Param radius half the diameter of Circle ##
3630#Param paint Paint stroke or fill, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003631
3632#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003633 void draw(SkCanvas* canvas) {
3634 SkPaint paint;
3635 paint.setAntiAlias(true);
3636 canvas->drawCircle(128, 128, 90, paint);
3637 paint.setColor(SK_ColorWHITE);
3638 canvas->drawCircle(86, 86, 20, paint);
3639 canvas->drawCircle(160, 76, 20, paint);
3640 canvas->drawCircle(140, 150, 35, paint);
3641 }
3642##
3643
Cary Clark2ade9972017-11-02 17:49:34 -04003644#SeeAlso drawOval drawRRect drawRoundRect drawPath drawArc drawPoint drawLine
Cary Clarkbad5ad72017-08-03 17:14:08 -04003645
3646##
3647
3648#Method void drawCircle(SkPoint center, SkScalar radius, const SkPaint& paint)
3649
Cary Clark80247e52018-07-11 16:18:41 -04003650Draws Circle at center with radius using Clip, Matrix, and Paint paint.
Cary Clarkbad5ad72017-08-03 17:14:08 -04003651If radius is zero or less, nothing is drawn.
Herb Derbyefe39bc2018-05-01 17:06:20 -04003652In paint: Paint_Style determines if Circle is stroked or filled;
Cary Clarkbad5ad72017-08-03 17:14:08 -04003653if stroked, Paint_Stroke_Width describes the line thickness.
3654
3655#Param center Circle center ##
3656#Param radius half the diameter of Circle ##
3657#Param paint Paint stroke or fill, blend, color, and so on, used to draw ##
3658
3659#Example
3660 void draw(SkCanvas* canvas) {
3661 SkPaint paint;
3662 paint.setAntiAlias(true);
3663 canvas->drawCircle(128, 128, 90, paint);
3664 paint.setColor(SK_ColorWHITE);
3665 canvas->drawCircle({86, 86}, 20, paint);
3666 canvas->drawCircle({160, 76}, 20, paint);
3667 canvas->drawCircle({140, 150}, 35, paint);
3668 }
Cary Clark8032b982017-07-28 11:04:54 -04003669##
3670
Cary Clark2ade9972017-11-02 17:49:34 -04003671#SeeAlso drawOval drawRRect drawRoundRect drawPath drawArc drawPoint drawLine
Cary Clark8032b982017-07-28 11:04:54 -04003672
3673##
3674
3675# ------------------------------------------------------------------------------
3676
3677#Method void drawArc(const SkRect& oval, SkScalar startAngle, SkScalar sweepAngle,
3678 bool useCenter, const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05003679#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05003680#Line # draws Arc using Clip, Matrix, and Paint ##
Cary Clark8032b982017-07-28 11:04:54 -04003681
Cary Clark80247e52018-07-11 16:18:41 -04003682Draws Arc using Clip, Matrix, and Paint paint.
Cary Clarkbad5ad72017-08-03 17:14:08 -04003683
Cary Clark8032b982017-07-28 11:04:54 -04003684Arc is part of Oval bounded by oval, sweeping from startAngle to startAngle plus
3685sweepAngle. startAngle and sweepAngle are in degrees.
Cary Clarkbad5ad72017-08-03 17:14:08 -04003686
Cary Clark8032b982017-07-28 11:04:54 -04003687startAngle of zero places start point at the right middle edge of oval.
3688A positive sweepAngle places Arc end point clockwise from start point;
3689a negative sweepAngle places Arc end point counterclockwise from start point.
3690sweepAngle may exceed 360 degrees, a full circle.
3691If useCenter is true, draw a wedge that includes lines from oval
3692center to Arc end points. If useCenter is false, draw Arc between end points.
3693
3694If Rect oval is empty or sweepAngle is zero, nothing is drawn.
3695
Cary Clarkbad5ad72017-08-03 17:14:08 -04003696#Param oval Rect bounds of Oval containing Arc to draw ##
3697#Param startAngle angle in degrees where Arc begins ##
3698#Param sweepAngle sweep angle in degrees; positive is clockwise ##
3699#Param useCenter if true, include the center of the oval ##
3700#Param paint Paint stroke or fill, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003701
3702#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003703 void draw(SkCanvas* canvas) {
3704 SkPaint paint;
3705 paint.setAntiAlias(true);
3706 SkRect oval = { 4, 4, 60, 60};
3707 for (auto useCenter : { false, true } ) {
3708 for (auto style : { SkPaint::kFill_Style, SkPaint::kStroke_Style } ) {
3709 paint.setStyle(style);
3710 for (auto degrees : { 45, 90, 180, 360} ) {
3711 canvas->drawArc(oval, 0, degrees , useCenter, paint);
3712 canvas->translate(64, 0);
3713 }
3714 canvas->translate(-256, 64);
3715 }
3716 }
Cary Clark8032b982017-07-28 11:04:54 -04003717 }
3718##
3719
3720#Example
3721#Height 64
Cary Clarkbad5ad72017-08-03 17:14:08 -04003722 void draw(SkCanvas* canvas) {
3723 SkPaint paint;
3724 paint.setAntiAlias(true);
3725 paint.setStyle(SkPaint::kStroke_Style);
3726 paint.setStrokeWidth(4);
3727 SkRect oval = { 4, 4, 60, 60};
3728 float intervals[] = { 5, 5 };
3729 paint.setPathEffect(SkDashPathEffect::Make(intervals, 2, 2.5f));
3730 for (auto degrees : { 270, 360, 540, 720 } ) {
3731 canvas->drawArc(oval, 0, degrees, false, paint);
3732 canvas->translate(64, 0);
3733 }
Cary Clark8032b982017-07-28 11:04:54 -04003734 }
3735##
3736
Cary Clark2ade9972017-11-02 17:49:34 -04003737#SeeAlso SkPath::arcTo drawCircle drawOval drawPath
Cary Clark8032b982017-07-28 11:04:54 -04003738
3739##
3740
3741# ------------------------------------------------------------------------------
3742
3743#Method void drawRoundRect(const SkRect& rect, SkScalar rx, SkScalar ry, const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05003744#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05003745#Line # draws Round_Rect using Clip, Matrix, and Paint ##
Cary Clark80247e52018-07-11 16:18:41 -04003746Draws Round_Rect bounded by Rect rect, with corner radii (rx, ry) using Clip,
Cary Clarkbad5ad72017-08-03 17:14:08 -04003747Matrix, and Paint paint.
3748
Herb Derbyefe39bc2018-05-01 17:06:20 -04003749In paint: Paint_Style determines if Round_Rect is stroked or filled;
Cary Clark8032b982017-07-28 11:04:54 -04003750if stroked, Paint_Stroke_Width describes the line thickness.
3751If rx or ry are less than zero, they are treated as if they are zero.
3752If rx plus ry exceeds rect width or rect height, radii are scaled down to fit.
Cary Clarkbad5ad72017-08-03 17:14:08 -04003753If rx and ry are zero, Round_Rect is drawn as Rect and if stroked is affected by
3754Paint_Stroke_Join.
Cary Clark8032b982017-07-28 11:04:54 -04003755
Cary Clarkbad5ad72017-08-03 17:14:08 -04003756#Param rect Rect bounds of Round_Rect to draw ##
Cary Clark5538c132018-06-14 12:28:14 -04003757#Param rx axis length on x-axis of oval describing rounded corners ##
3758#Param ry axis length on y-axis of oval describing rounded corners ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003759#Param paint stroke, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003760
3761#Example
3762#Description
3763 Top row has a zero radius a generates a rectangle.
3764 Second row radii sum to less than sides.
3765 Third row radii sum equals sides.
3766 Fourth row radii sum exceeds sides; radii are scaled to fit.
3767##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003768 void draw(SkCanvas* canvas) {
3769 SkVector radii[] = { {0, 20}, {10, 10}, {10, 20}, {10, 40} };
3770 SkPaint paint;
3771 paint.setStrokeWidth(15);
3772 paint.setStrokeJoin(SkPaint::kRound_Join);
3773 paint.setAntiAlias(true);
3774 for (auto style : { SkPaint::kStroke_Style, SkPaint::kFill_Style } ) {
3775 paint.setStyle(style );
3776 for (size_t i = 0; i < SK_ARRAY_COUNT(radii); ++i) {
3777 canvas->drawRoundRect({10, 10, 60, 40}, radii[i].fX, radii[i].fY, paint);
3778 canvas->translate(0, 60);
3779 }
3780 canvas->translate(80, -240);
3781 }
Cary Clark8032b982017-07-28 11:04:54 -04003782 }
3783##
3784
Cary Clark2ade9972017-11-02 17:49:34 -04003785#SeeAlso DrawRRect drawRect drawDRRect drawPath drawCircle drawOval drawPoint
Cary Clark8032b982017-07-28 11:04:54 -04003786
3787##
3788
3789# ------------------------------------------------------------------------------
3790
3791#Method void drawPath(const SkPath& path, const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05003792#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05003793#Line # draws Path using Clip, Matrix, and Paint ##
Cary Clark80247e52018-07-11 16:18:41 -04003794Draws Path path using Clip, Matrix, and Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04003795Path contains an array of Path_Contour, each of which may be open or closed.
3796
3797In paint: Paint_Style determines if Round_Rect is stroked or filled:
Cary Clarkbad5ad72017-08-03 17:14:08 -04003798if filled, Path_Fill_Type determines whether Path_Contour describes inside or
3799outside of fill; if stroked, Paint_Stroke_Width describes the line thickness,
3800Paint_Stroke_Cap describes line ends, and Paint_Stroke_Join describes how
3801corners are drawn.
Cary Clark8032b982017-07-28 11:04:54 -04003802
Cary Clarkbad5ad72017-08-03 17:14:08 -04003803#Param path Path to draw ##
3804#Param paint stroke, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003805
3806#Example
3807#Description
3808 Top rows draw stroked path with combinations of joins and caps. The open contour
3809 is affected by caps; the closed contour is affected by joins.
Herb Derbyefe39bc2018-05-01 17:06:20 -04003810 Bottom row draws fill the same for open and closed contour.
Cary Clark8032b982017-07-28 11:04:54 -04003811 First bottom column shows winding fills overlap.
3812 Second bottom column shows even odd fills exclude overlap.
3813 Third bottom column shows inverse winding fills area outside both contours.
3814##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003815void draw(SkCanvas* canvas) {
3816 SkPath path;
3817 path.moveTo(20, 20);
3818 path.quadTo(60, 20, 60, 60);
3819 path.close();
3820 path.moveTo(60, 20);
3821 path.quadTo(60, 60, 20, 60);
3822 SkPaint paint;
3823 paint.setStrokeWidth(10);
3824 paint.setAntiAlias(true);
3825 paint.setStyle(SkPaint::kStroke_Style);
3826 for (auto join: { SkPaint::kBevel_Join, SkPaint::kRound_Join, SkPaint::kMiter_Join } ) {
3827 paint.setStrokeJoin(join);
3828 for (auto cap: { SkPaint::kButt_Cap, SkPaint::kSquare_Cap, SkPaint::kRound_Cap } ) {
3829 paint.setStrokeCap(cap);
3830 canvas->drawPath(path, paint);
3831 canvas->translate(80, 0);
3832 }
3833 canvas->translate(-240, 60);
3834 }
3835 paint.setStyle(SkPaint::kFill_Style);
Herb Derbyefe39bc2018-05-01 17:06:20 -04003836 for (auto fill : { SkPath::kWinding_FillType,
3837 SkPath::kEvenOdd_FillType,
Cary Clarkbad5ad72017-08-03 17:14:08 -04003838 SkPath::kInverseWinding_FillType } ) {
3839 path.setFillType(fill);
3840 canvas->save();
3841 canvas->clipRect({0, 10, 80, 70});
3842 canvas->drawPath(path, paint);
3843 canvas->restore();
3844 canvas->translate(80, 0);
3845 }
Cary Clark8032b982017-07-28 11:04:54 -04003846}
3847##
3848
Cary Clark2ade9972017-11-02 17:49:34 -04003849#SeeAlso SkPath drawLine drawArc drawRect drawPoints
Cary Clark8032b982017-07-28 11:04:54 -04003850
3851##
3852
3853# ------------------------------------------------------------------------------
Cary Clark08895c42018-02-01 09:37:32 -05003854#Subtopic Draw_Image
3855#Line # draws Image to Canvas ##
Cary Clark8032b982017-07-28 11:04:54 -04003856
Cary Clarkbad5ad72017-08-03 17:14:08 -04003857drawImage, drawImageRect, and drawImageNine can be called with a bare pointer or
3858a smart pointer as a convenience. The pairs of calls are otherwise identical.
Cary Clark8032b982017-07-28 11:04:54 -04003859
Cary Clark73fa9722017-08-29 17:36:51 -04003860#Method void drawImage(const SkImage* image, SkScalar left, SkScalar top, const SkPaint* paint = nullptr)
Cary Clarkab2621d2018-01-30 10:08:57 -05003861#In Draw_Image
Cary Clark78de7512018-02-07 07:27:09 -05003862#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05003863#Line # draws Image at (x, y) position ##
Cary Clark80247e52018-07-11 16:18:41 -04003864Draws Image image, with its top-left corner at (left, top),
Cary Clark8032b982017-07-28 11:04:54 -04003865using Clip, Matrix, and optional Paint paint.
3866
Cary Clarkbad5ad72017-08-03 17:14:08 -04003867If paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter, Blend_Mode,
3868and Draw_Looper. If image is kAlpha_8_SkColorType, apply Shader.
3869If paint contains Mask_Filter, generate mask from image bounds. If generated
3870mask extends beyond image bounds, replicate image edge colors, just as Shader
3871made from SkImage::makeShader with SkShader::kClamp_TileMode set replicates the
Herb Derbyefe39bc2018-05-01 17:06:20 -04003872image edge color when it samples outside of its bounds.
Cary Clark8032b982017-07-28 11:04:54 -04003873
Cary Clarkbad5ad72017-08-03 17:14:08 -04003874#Param image uncompressed rectangular map of pixels ##
3875#Param left left side of image ##
3876#Param top top side of image ##
3877#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
3878 and so on; or nullptr
3879##
Cary Clark8032b982017-07-28 11:04:54 -04003880
3881#Example
3882#Height 64
3883#Image 4
Cary Clarkbad5ad72017-08-03 17:14:08 -04003884void draw(SkCanvas* canvas) {
3885 // sk_sp<SkImage> image;
3886 SkImage* imagePtr = image.get();
3887 canvas->drawImage(imagePtr, 0, 0);
3888 SkPaint paint;
3889 canvas->drawImage(imagePtr, 80, 0, &paint);
3890 paint.setAlpha(0x80);
3891 canvas->drawImage(imagePtr, 160, 0, &paint);
Cary Clark8032b982017-07-28 11:04:54 -04003892}
3893##
3894
Cary Clark2ade9972017-11-02 17:49:34 -04003895#SeeAlso drawBitmap drawImageLattice drawImageNine drawImageRect SkPaint::setImageFilter
Cary Clark8032b982017-07-28 11:04:54 -04003896
3897##
3898
3899# ------------------------------------------------------------------------------
3900
3901#Method void drawImage(const sk_sp<SkImage>& image, SkScalar left, SkScalar top,
Herb Derbyefe39bc2018-05-01 17:06:20 -04003902 const SkPaint* paint = nullptr)
Cary Clark8032b982017-07-28 11:04:54 -04003903
Cary Clark80247e52018-07-11 16:18:41 -04003904Draws Image image, with its top-left corner at (left, top),
Cary Clark8032b982017-07-28 11:04:54 -04003905using Clip, Matrix, and optional Paint paint.
3906
Cary Clarkbad5ad72017-08-03 17:14:08 -04003907If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
3908Blend_Mode, and Draw_Looper. If image is kAlpha_8_SkColorType, apply Shader.
3909If paint contains Mask_Filter, generate mask from image bounds. If generated
3910mask extends beyond image bounds, replicate image edge colors, just as Shader
3911made from SkImage::makeShader with SkShader::kClamp_TileMode set replicates the
Herb Derbyefe39bc2018-05-01 17:06:20 -04003912image edge color when it samples outside of its bounds.
Cary Clark8032b982017-07-28 11:04:54 -04003913
Cary Clarkbad5ad72017-08-03 17:14:08 -04003914#Param image uncompressed rectangular map of pixels ##
3915#Param left left side of image ##
3916#Param top pop side of image ##
3917#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
3918 and so on; or nullptr
3919##
Cary Clark8032b982017-07-28 11:04:54 -04003920
3921#Example
3922#Height 64
3923#Image 4
Cary Clarkbad5ad72017-08-03 17:14:08 -04003924void draw(SkCanvas* canvas) {
3925 // sk_sp<SkImage> image;
3926 canvas->drawImage(image, 0, 0);
3927 SkPaint paint;
3928 canvas->drawImage(image, 80, 0, &paint);
3929 paint.setAlpha(0x80);
3930 canvas->drawImage(image, 160, 0, &paint);
Cary Clark8032b982017-07-28 11:04:54 -04003931}
3932##
3933
Cary Clark2ade9972017-11-02 17:49:34 -04003934#SeeAlso drawBitmap drawImageLattice drawImageNine drawImageRect SkPaint::setImageFilter
Cary Clark8032b982017-07-28 11:04:54 -04003935
3936##
3937
3938# ------------------------------------------------------------------------------
3939
3940#Enum SrcRectConstraint
Cary Clark08895c42018-02-01 09:37:32 -05003941#Line # sets drawImageRect options ##
Cary Clark8032b982017-07-28 11:04:54 -04003942
3943#Code
3944 enum SrcRectConstraint {
Herb Derbyefe39bc2018-05-01 17:06:20 -04003945 kStrict_SrcRectConstraint,
3946 kFast_SrcRectConstraint,
Cary Clark8032b982017-07-28 11:04:54 -04003947 };
3948##
3949
Cary Clarkce101242017-09-01 15:51:02 -04003950SrcRectConstraint controls the behavior at the edge of source Rect,
3951provided to drawImageRect, trading off speed for precision.
Cary Clark8032b982017-07-28 11:04:54 -04003952
Cary Clarkce101242017-09-01 15:51:02 -04003953Image_Filter in Paint may sample multiple pixels in the image. Source Rect
Cary Clarkbad5ad72017-08-03 17:14:08 -04003954restricts the bounds of pixels that may be read. Image_Filter may slow down if
Herb Derbyefe39bc2018-05-01 17:06:20 -04003955it cannot read outside the bounds, when sampling near the edge of source Rect.
Cary Clark8032b982017-07-28 11:04:54 -04003956SrcRectConstraint specifies whether an Image_Filter is allowed to read pixels
Cary Clarkce101242017-09-01 15:51:02 -04003957outside source Rect.
Cary Clark8032b982017-07-28 11:04:54 -04003958
Cary Clark682c58d2018-05-16 07:07:07 -04003959#Const kStrict_SrcRectConstraint 0
3960#Line # sample only inside bounds; slower ##
Cary Clarkce101242017-09-01 15:51:02 -04003961 Requires Image_Filter to respect source Rect,
Cary Clark8032b982017-07-28 11:04:54 -04003962 sampling only inside of its bounds, possibly with a performance penalty.
3963##
3964
Cary Clark682c58d2018-05-16 07:07:07 -04003965#Const kFast_SrcRectConstraint 1
3966#Line # sample outside bounds; faster ##
Cary Clarkce101242017-09-01 15:51:02 -04003967 Permits Image_Filter to sample outside of source Rect
Cary Clark8032b982017-07-28 11:04:54 -04003968 by half the width of Image_Filter, permitting it to run faster but with
3969 error at the image edges.
3970##
3971
3972#Example
3973#Height 64
3974#Description
3975 redBorder contains a black and white checkerboard bordered by red.
3976 redBorder is drawn scaled by 16 on the left.
Cary Clarkce101242017-09-01 15:51:02 -04003977 The middle and right bitmaps are filtered checkerboards.
Cary Clark8032b982017-07-28 11:04:54 -04003978 Drawing the checkerboard with kStrict_SrcRectConstraint shows only a blur of black and white.
3979 Drawing the checkerboard with kFast_SrcRectConstraint allows red to bleed in the corners.
3980##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003981void draw(SkCanvas* canvas) {
3982 SkBitmap redBorder;
3983 redBorder.allocPixels(SkImageInfo::MakeN32Premul(4, 4));
3984 SkCanvas checkRed(redBorder);
3985 checkRed.clear(SK_ColorRED);
3986 uint32_t checkers[][2] = { { SK_ColorBLACK, SK_ColorWHITE },
3987 { SK_ColorWHITE, SK_ColorBLACK } };
3988 checkRed.writePixels(
3989 SkImageInfo::MakeN32Premul(2, 2), (void*) checkers, sizeof(checkers[0]), 1, 1);
3990 canvas->scale(16, 16);
3991 canvas->drawBitmap(redBorder, 0, 0, nullptr);
3992 canvas->resetMatrix();
3993 sk_sp<SkImage> image = SkImage::MakeFromBitmap(redBorder);
3994 SkPaint lowPaint;
3995 lowPaint.setFilterQuality(kLow_SkFilterQuality);
3996 for (auto constraint : { SkCanvas::kStrict_SrcRectConstraint,
3997 SkCanvas::kFast_SrcRectConstraint } ) {
3998 canvas->translate(80, 0);
3999 canvas->drawImageRect(image.get(), SkRect::MakeLTRB(1, 1, 3, 3),
4000 SkRect::MakeLTRB(16, 16, 48, 48), &lowPaint, constraint);
4001 }
Cary Clark8032b982017-07-28 11:04:54 -04004002}
4003##
4004
Cary Clark2ade9972017-11-02 17:49:34 -04004005#SeeAlso drawImageRect drawImage SkPaint::setImageFilter
Cary Clark8032b982017-07-28 11:04:54 -04004006
4007##
4008
4009# ------------------------------------------------------------------------------
4010
4011#Method void drawImageRect(const SkImage* image, const SkRect& src, const SkRect& dst,
4012 const SkPaint* paint,
4013 SrcRectConstraint constraint = kStrict_SrcRectConstraint)
Cary Clarkab2621d2018-01-30 10:08:57 -05004014#In Draw_Image
Cary Clark78de7512018-02-07 07:27:09 -05004015#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05004016#Line # draws Image, source Rect to destination Rect ##
Cary Clark8032b982017-07-28 11:04:54 -04004017
Cary Clark80247e52018-07-11 16:18:41 -04004018Draws Rect src of Image image, scaled and translated to fill Rect dst.
Cary Clark8032b982017-07-28 11:04:54 -04004019Additionally transform draw using Clip, Matrix, and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004020
Cary Clarkbad5ad72017-08-03 17:14:08 -04004021If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4022Blend_Mode, and Draw_Looper. If image is kAlpha_8_SkColorType, apply Shader.
4023If paint contains Mask_Filter, generate mask from image bounds.
4024
4025If generated mask extends beyond image bounds, replicate image edge colors, just
4026as Shader made from SkImage::makeShader with SkShader::kClamp_TileMode set
Cary Clarkbc5697d2017-10-04 14:31:33 -04004027replicates the image edge color when it samples outside of its bounds.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004028
4029constraint set to kStrict_SrcRectConstraint limits Paint Filter_Quality to
4030sample within src; set to kFast_SrcRectConstraint allows sampling outside to
4031improve performance.
4032
4033#Param image Image containing pixels, dimensions, and format ##
4034#Param src source Rect of image to draw from ##
4035#Param dst destination Rect of image to draw to ##
4036#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4037 and so on; or nullptr
4038##
4039#Param constraint filter strictly within src or draw faster ##
Cary Clark8032b982017-07-28 11:04:54 -04004040
4041#Example
4042#Height 64
4043#Description
4044 The left bitmap draws with Paint default kNone_SkFilterQuality, and stays within
Cary Clarkbc5697d2017-10-04 14:31:33 -04004045 its bounds; there is no bleeding with kFast_SrcRectConstraint.
Cary Clark8032b982017-07-28 11:04:54 -04004046 the middle and right bitmaps draw with kLow_SkFilterQuality; with
4047 kStrict_SrcRectConstraint, the filter remains within the checkerboard, and
4048 with kFast_SrcRectConstraint red bleeds on the edges.
4049##
Cary Clarkbad5ad72017-08-03 17:14:08 -04004050void draw(SkCanvas* canvas) {
Herb Derbyefe39bc2018-05-01 17:06:20 -04004051 uint32_t pixels[][4] = {
Cary Clarkbad5ad72017-08-03 17:14:08 -04004052 { 0xFFFF0000, 0xFFFF0000, 0xFFFF0000, 0xFFFF0000 },
4053 { 0xFFFF0000, 0xFF000000, 0xFFFFFFFF, 0xFFFF0000 },
4054 { 0xFFFF0000, 0xFFFFFFFF, 0xFF000000, 0xFFFF0000 },
4055 { 0xFFFF0000, 0xFFFF0000, 0xFFFF0000, 0xFFFF0000 } };
4056 SkBitmap redBorder;
Herb Derbyefe39bc2018-05-01 17:06:20 -04004057 redBorder.installPixels(SkImageInfo::MakeN32Premul(4, 4),
Cary Clarkbad5ad72017-08-03 17:14:08 -04004058 (void*) pixels, sizeof(pixels[0]));
4059 sk_sp<SkImage> image = SkImage::MakeFromBitmap(redBorder);
4060 SkPaint lowPaint;
4061 for (auto constraint : {
4062 SkCanvas::kFast_SrcRectConstraint,
4063 SkCanvas::kStrict_SrcRectConstraint,
4064 SkCanvas::kFast_SrcRectConstraint } ) {
4065 canvas->drawImageRect(image.get(), SkRect::MakeLTRB(1, 1, 3, 3),
4066 SkRect::MakeLTRB(16, 16, 48, 48), &lowPaint, constraint);
4067 lowPaint.setFilterQuality(kLow_SkFilterQuality);
4068 canvas->translate(80, 0);
4069 }
4070}
Cary Clark8032b982017-07-28 11:04:54 -04004071##
4072
Cary Clark2ade9972017-11-02 17:49:34 -04004073#SeeAlso SrcRectConstraint drawImage drawImageLattice drawImageNine
Cary Clark8032b982017-07-28 11:04:54 -04004074
4075##
4076
4077# ------------------------------------------------------------------------------
4078
4079#Method void drawImageRect(const SkImage* image, const SkIRect& isrc, const SkRect& dst,
4080 const SkPaint* paint, SrcRectConstraint constraint = kStrict_SrcRectConstraint)
Cary Clarkab2621d2018-01-30 10:08:57 -05004081#In Draw_Image
Cary Clark78de7512018-02-07 07:27:09 -05004082#In Draw
Cary Clark8032b982017-07-28 11:04:54 -04004083
Cary Clark80247e52018-07-11 16:18:41 -04004084Draws IRect isrc of Image image, scaled and translated to fill Rect dst.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004085Note that isrc is on integer pixel boundaries; dst may include fractional
4086boundaries. Additionally transform draw using Clip, Matrix, and optional Paint
Herb Derbyefe39bc2018-05-01 17:06:20 -04004087paint.
Cary Clark8032b982017-07-28 11:04:54 -04004088
Cary Clarkbad5ad72017-08-03 17:14:08 -04004089If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4090Blend_Mode, and Draw_Looper. If image is kAlpha_8_SkColorType, apply Shader.
4091If paint contains Mask_Filter, generate mask from image bounds.
4092
4093If generated mask extends beyond image bounds, replicate image edge colors, just
4094as Shader made from SkImage::makeShader with SkShader::kClamp_TileMode set
Cary Clarkbc5697d2017-10-04 14:31:33 -04004095replicates the image edge color when it samples outside of its bounds.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004096
4097constraint set to kStrict_SrcRectConstraint limits Paint Filter_Quality to
Cary Clarkce101242017-09-01 15:51:02 -04004098sample within isrc; set to kFast_SrcRectConstraint allows sampling outside to
Cary Clarkbad5ad72017-08-03 17:14:08 -04004099improve performance.
4100
4101#Param image Image containing pixels, dimensions, and format ##
4102#Param isrc source IRect of image to draw from ##
4103#Param dst destination Rect of image to draw to ##
4104#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4105 and so on; or nullptr
4106##
Cary Clarkce101242017-09-01 15:51:02 -04004107#Param constraint filter strictly within isrc or draw faster ##
Cary Clark8032b982017-07-28 11:04:54 -04004108
4109#Example
4110#Image 4
Cary Clarkbad5ad72017-08-03 17:14:08 -04004111void draw(SkCanvas* canvas) {
4112 // sk_sp<SkImage> image;
4113 for (auto i : { 1, 2, 4, 8 } ) {
Herb Derbyefe39bc2018-05-01 17:06:20 -04004114 canvas->drawImageRect(image.get(), SkIRect::MakeLTRB(0, 0, 100, 100),
Cary Clarkbad5ad72017-08-03 17:14:08 -04004115 SkRect::MakeXYWH(i * 20, i * 20, i * 20, i * 20), nullptr);
4116 }
Cary Clark8032b982017-07-28 11:04:54 -04004117}
4118##
4119
Cary Clark2ade9972017-11-02 17:49:34 -04004120#SeeAlso SrcRectConstraint drawImage drawImageLattice drawImageNine
Cary Clark8032b982017-07-28 11:04:54 -04004121
4122##
4123
4124# ------------------------------------------------------------------------------
4125
4126#Method void drawImageRect(const SkImage* image, const SkRect& dst, const SkPaint* paint,
4127 SrcRectConstraint constraint = kStrict_SrcRectConstraint)
Cary Clarkab2621d2018-01-30 10:08:57 -05004128#In Draw_Image
Cary Clark78de7512018-02-07 07:27:09 -05004129#In Draw
Cary Clark8032b982017-07-28 11:04:54 -04004130
Cary Clark80247e52018-07-11 16:18:41 -04004131Draws Image image, scaled and translated to fill Rect dst, using Clip, Matrix,
Cary Clarkbad5ad72017-08-03 17:14:08 -04004132and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004133
Cary Clarkbad5ad72017-08-03 17:14:08 -04004134If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4135Blend_Mode, and Draw_Looper. If image is kAlpha_8_SkColorType, apply Shader.
4136If paint contains Mask_Filter, generate mask from image bounds.
4137
4138If generated mask extends beyond image bounds, replicate image edge colors, just
4139as Shader made from SkImage::makeShader with SkShader::kClamp_TileMode set
Cary Clarkbc5697d2017-10-04 14:31:33 -04004140replicates the image edge color when it samples outside of its bounds.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004141
4142constraint set to kStrict_SrcRectConstraint limits Paint Filter_Quality to
Cary Clarkce101242017-09-01 15:51:02 -04004143sample within image; set to kFast_SrcRectConstraint allows sampling outside to
Cary Clarkbad5ad72017-08-03 17:14:08 -04004144improve performance.
4145
4146#Param image Image containing pixels, dimensions, and format ##
4147#Param dst destination Rect of image to draw to ##
4148#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4149 and so on; or nullptr
4150##
Cary Clarkce101242017-09-01 15:51:02 -04004151#Param constraint filter strictly within image or draw faster ##
Cary Clark8032b982017-07-28 11:04:54 -04004152
4153#Example
4154#Image 4
Cary Clarkbad5ad72017-08-03 17:14:08 -04004155void draw(SkCanvas* canvas) {
4156 // sk_sp<SkImage> image;
4157 for (auto i : { 20, 40, 80, 160 } ) {
4158 canvas->drawImageRect(image.get(), SkRect::MakeXYWH(i, i, i, i), nullptr);
4159 }
Cary Clark8032b982017-07-28 11:04:54 -04004160}
4161##
4162
Cary Clark2ade9972017-11-02 17:49:34 -04004163#SeeAlso SrcRectConstraint drawImage drawImageLattice drawImageNine
Cary Clark8032b982017-07-28 11:04:54 -04004164
4165##
4166
4167# ------------------------------------------------------------------------------
4168
4169#Method void drawImageRect(const sk_sp<SkImage>& image, const SkRect& src, const SkRect& dst,
4170 const SkPaint* paint,
Herb Derbyefe39bc2018-05-01 17:06:20 -04004171 SrcRectConstraint constraint = kStrict_SrcRectConstraint)
Cary Clarkab2621d2018-01-30 10:08:57 -05004172#In Draw_Image
Cary Clark78de7512018-02-07 07:27:09 -05004173#In Draw
Cary Clark80247e52018-07-11 16:18:41 -04004174Draws Rect src of Image image, scaled and translated to fill Rect dst.
Cary Clark8032b982017-07-28 11:04:54 -04004175Additionally transform draw using Clip, Matrix, and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004176
Cary Clarkbad5ad72017-08-03 17:14:08 -04004177If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4178Blend_Mode, and Draw_Looper. If image is kAlpha_8_SkColorType, apply Shader.
4179If paint contains Mask_Filter, generate mask from image bounds.
4180
4181If generated mask extends beyond image bounds, replicate image edge colors, just
4182as Shader made from SkImage::makeShader with SkShader::kClamp_TileMode set
Cary Clarkbc5697d2017-10-04 14:31:33 -04004183replicates the image edge color when it samples outside of its bounds.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004184
4185constraint set to kStrict_SrcRectConstraint limits Paint Filter_Quality to
4186sample within src; set to kFast_SrcRectConstraint allows sampling outside to
4187improve performance.
4188
4189#Param image Image containing pixels, dimensions, and format ##
4190#Param src source Rect of image to draw from ##
4191#Param dst destination Rect of image to draw to ##
4192#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4193 and so on; or nullptr
4194##
4195#Param constraint filter strictly within src or draw faster ##
Cary Clark8032b982017-07-28 11:04:54 -04004196
4197#Example
4198#Height 64
4199#Description
4200 Canvas scales and translates; transformation from src to dst also scales.
4201 The two matrices are concatenated to create the final transformation.
4202##
Cary Clarkbad5ad72017-08-03 17:14:08 -04004203void draw(SkCanvas* canvas) {
4204 uint32_t pixels[][2] = { { SK_ColorBLACK, SK_ColorWHITE },
4205 { SK_ColorWHITE, SK_ColorBLACK } };
4206 SkBitmap bitmap;
Herb Derbyefe39bc2018-05-01 17:06:20 -04004207 bitmap.installPixels(SkImageInfo::MakeN32Premul(2, 2),
Cary Clarkbad5ad72017-08-03 17:14:08 -04004208 (void*) pixels, sizeof(pixels[0]));
4209 sk_sp<SkImage> image = SkImage::MakeFromBitmap(bitmap);
4210 SkPaint paint;
4211 canvas->scale(4, 4);
4212 for (auto alpha : { 50, 100, 150, 255 } ) {
4213 paint.setAlpha(alpha);
4214 canvas->drawImageRect(image, SkRect::MakeWH(2, 2), SkRect::MakeWH(8, 8), &paint);
4215 canvas->translate(8, 0);
4216 }
4217}
Cary Clark8032b982017-07-28 11:04:54 -04004218##
4219
Cary Clark2ade9972017-11-02 17:49:34 -04004220#SeeAlso SrcRectConstraint drawImage drawImageLattice drawImageNine
Cary Clark8032b982017-07-28 11:04:54 -04004221
4222##
4223
4224# ------------------------------------------------------------------------------
4225
4226#Method void drawImageRect(const sk_sp<SkImage>& image, const SkIRect& isrc, const SkRect& dst,
Herb Derbyefe39bc2018-05-01 17:06:20 -04004227 const SkPaint* paint, SrcRectConstraint constraint = kStrict_SrcRectConstraint)
Cary Clarkab2621d2018-01-30 10:08:57 -05004228#In Draw_Image
Cary Clark78de7512018-02-07 07:27:09 -05004229#In Draw
Cary Clark80247e52018-07-11 16:18:41 -04004230Draws IRect isrc of Image image, scaled and translated to fill Rect dst.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004231isrc is on integer pixel boundaries; dst may include fractional boundaries.
Cary Clark8032b982017-07-28 11:04:54 -04004232Additionally transform draw using Clip, Matrix, and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004233
Cary Clarkbad5ad72017-08-03 17:14:08 -04004234If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4235Blend_Mode, and Draw_Looper. If image is kAlpha_8_SkColorType, apply Shader.
4236If paint contains Mask_Filter, generate mask from image bounds.
4237
4238If generated mask extends beyond image bounds, replicate image edge colors, just
4239as Shader made from SkImage::makeShader with SkShader::kClamp_TileMode set
Cary Clarkbc5697d2017-10-04 14:31:33 -04004240replicates the image edge color when it samples outside of its bounds.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004241
4242constraint set to kStrict_SrcRectConstraint limits Paint Filter_Quality to
Cary Clarkce101242017-09-01 15:51:02 -04004243sample within image; set to kFast_SrcRectConstraint allows sampling outside to
Cary Clarkbad5ad72017-08-03 17:14:08 -04004244improve performance.
4245
4246#Param image Image containing pixels, dimensions, and format ##
4247#Param isrc source IRect of image to draw from ##
4248#Param dst destination Rect of image to draw to ##
4249#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4250 and so on; or nullptr
4251##
Cary Clarkce101242017-09-01 15:51:02 -04004252#Param constraint filter strictly within image or draw faster ##
Cary Clark8032b982017-07-28 11:04:54 -04004253
4254#Example
4255#Height 64
Cary Clarkbad5ad72017-08-03 17:14:08 -04004256void draw(SkCanvas* canvas) {
4257 uint32_t pixels[][2] = { { 0x00000000, 0x55555555},
4258 { 0xAAAAAAAA, 0xFFFFFFFF} };
4259 SkBitmap bitmap;
Herb Derbyefe39bc2018-05-01 17:06:20 -04004260 bitmap.installPixels(SkImageInfo::MakeN32Premul(2, 2),
Cary Clarkbad5ad72017-08-03 17:14:08 -04004261 (void*) pixels, sizeof(pixels[0]));
4262 sk_sp<SkImage> image = SkImage::MakeFromBitmap(bitmap);
4263 SkPaint paint;
4264 canvas->scale(4, 4);
4265 for (auto color : { SK_ColorRED, SK_ColorBLUE, SK_ColorGREEN } ) {
4266 paint.setColorFilter(SkColorFilter::MakeModeFilter(color, SkBlendMode::kPlus));
4267 canvas->drawImageRect(image, SkIRect::MakeWH(2, 2), SkRect::MakeWH(8, 8), &paint);
4268 canvas->translate(8, 0);
4269 }
Cary Clark8032b982017-07-28 11:04:54 -04004270}
4271##
4272
Cary Clark2ade9972017-11-02 17:49:34 -04004273#SeeAlso SrcRectConstraint drawImage drawImageLattice drawImageNine
4274
Cary Clark8032b982017-07-28 11:04:54 -04004275##
4276
4277# ------------------------------------------------------------------------------
4278
4279#Method void drawImageRect(const sk_sp<SkImage>& image, const SkRect& dst, const SkPaint* paint,
Herb Derbyefe39bc2018-05-01 17:06:20 -04004280 SrcRectConstraint constraint = kStrict_SrcRectConstraint)
Cary Clarkab2621d2018-01-30 10:08:57 -05004281#In Draw_Image
Cary Clark78de7512018-02-07 07:27:09 -05004282#In Draw
Cary Clark80247e52018-07-11 16:18:41 -04004283Draws Image image, scaled and translated to fill Rect dst,
Cary Clark8032b982017-07-28 11:04:54 -04004284using Clip, Matrix, and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004285
Cary Clarkbad5ad72017-08-03 17:14:08 -04004286If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4287Blend_Mode, and Draw_Looper. If image is kAlpha_8_SkColorType, apply Shader.
4288If paint contains Mask_Filter, generate mask from image bounds.
4289
4290If generated mask extends beyond image bounds, replicate image edge colors, just
4291as Shader made from SkImage::makeShader with SkShader::kClamp_TileMode set
Cary Clarkbc5697d2017-10-04 14:31:33 -04004292replicates the image edge color when it samples outside of its bounds.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004293
4294constraint set to kStrict_SrcRectConstraint limits Paint Filter_Quality to
Cary Clarkce101242017-09-01 15:51:02 -04004295sample within image; set to kFast_SrcRectConstraint allows sampling outside to
Cary Clarkbad5ad72017-08-03 17:14:08 -04004296improve performance.
4297
4298#Param image Image containing pixels, dimensions, and format ##
4299#Param dst destination Rect of image to draw to ##
4300#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4301 and so on; or nullptr
4302##
Cary Clarkce101242017-09-01 15:51:02 -04004303#Param constraint filter strictly within image or draw faster ##
Cary Clark8032b982017-07-28 11:04:54 -04004304
4305#Example
4306#Height 64
Cary Clarkbad5ad72017-08-03 17:14:08 -04004307void draw(SkCanvas* canvas) {
4308 uint32_t pixels[][2] = { { 0x00000000, 0x55550000},
4309 { 0xAAAA0000, 0xFFFF0000} };
4310 SkBitmap bitmap;
Herb Derbyefe39bc2018-05-01 17:06:20 -04004311 bitmap.installPixels(SkImageInfo::MakeN32Premul(2, 2),
Cary Clarkbad5ad72017-08-03 17:14:08 -04004312 (void*) pixels, sizeof(pixels[0]));
4313 sk_sp<SkImage> image = SkImage::MakeFromBitmap(bitmap);
4314 SkPaint paint;
4315 canvas->scale(4, 4);
4316 for (auto color : { SK_ColorRED, SK_ColorBLUE, SK_ColorGREEN } ) {
4317 paint.setColorFilter(SkColorFilter::MakeModeFilter(color, SkBlendMode::kPlus));
4318 canvas->drawImageRect(image, SkRect::MakeWH(8, 8), &paint);
4319 canvas->translate(8, 0);
4320 }
Cary Clark8032b982017-07-28 11:04:54 -04004321}
4322##
4323
Cary Clark2ade9972017-11-02 17:49:34 -04004324#SeeAlso SrcRectConstraint drawImage drawImageLattice drawImageNine
Cary Clark8032b982017-07-28 11:04:54 -04004325
4326##
4327
4328# ------------------------------------------------------------------------------
4329
4330#Method void drawImageNine(const SkImage* image, const SkIRect& center, const SkRect& dst,
4331 const SkPaint* paint = nullptr)
Cary Clarkab2621d2018-01-30 10:08:57 -05004332#In Draw_Image
Cary Clark78de7512018-02-07 07:27:09 -05004333#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05004334#Line # draws Nine_Patch Image ##
Cary Clark8032b982017-07-28 11:04:54 -04004335
Cary Clark80247e52018-07-11 16:18:41 -04004336Draws Image image stretched proportionally to fit into Rect dst.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004337IRect center divides the image into nine sections: four sides, four corners, and
Cary Clarkce101242017-09-01 15:51:02 -04004338the center. Corners are unmodified or scaled down proportionately if their sides
Cary Clarkbad5ad72017-08-03 17:14:08 -04004339are larger than dst; center and four sides are scaled to fit remaining space, if any.
Cary Clark8032b982017-07-28 11:04:54 -04004340
Cary Clarkbad5ad72017-08-03 17:14:08 -04004341Additionally transform draw using Clip, Matrix, and optional Paint paint.
4342
Cary Clark682c58d2018-05-16 07:07:07 -04004343#paint_as_used_by_draw_lattice_or_draw_nine(image)#
Cary Clarkbad5ad72017-08-03 17:14:08 -04004344
4345If generated mask extends beyond image bounds, replicate image edge colors, just
4346as Shader made from SkImage::makeShader with SkShader::kClamp_TileMode set
Cary Clarkbc5697d2017-10-04 14:31:33 -04004347replicates the image edge color when it samples outside of its bounds.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004348
4349#Param image Image containing pixels, dimensions, and format ##
4350#Param center IRect edge of image corners and sides ##
4351#Param dst destination Rect of image to draw to ##
4352#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4353 and so on; or nullptr
4354##
Cary Clark8032b982017-07-28 11:04:54 -04004355
4356#Example
4357#Height 128
4358#Description
4359 The leftmost image is smaller than center; only corners are drawn, all scaled to fit.
Cary Clarkce101242017-09-01 15:51:02 -04004360 The second image equals the size of center; only corners are drawn without scaling.
4361 The remaining images are larger than center. All corners draw without scaling.
4362 The sides and center are scaled if needed to take up the remaining space.
Cary Clark8032b982017-07-28 11:04:54 -04004363##
Cary Clarkbad5ad72017-08-03 17:14:08 -04004364void draw(SkCanvas* canvas) {
4365 SkIRect center = { 20, 10, 50, 40 };
4366 SkBitmap bitmap;
4367 bitmap.allocPixels(SkImageInfo::MakeN32Premul(60, 60));
4368 SkCanvas bitCanvas(bitmap);
4369 SkPaint paint;
4370 SkColor gray = 0xFF000000;
4371 int left = 0;
4372 for (auto right: { center.fLeft, center.fRight, bitmap.width() } ) {
4373 int top = 0;
4374 for (auto bottom: { center.fTop, center.fBottom, bitmap.height() } ) {
4375 paint.setColor(gray);
4376 bitCanvas.drawIRect(SkIRect::MakeLTRB(left, top, right, bottom), paint);
4377 gray += 0x001f1f1f;
4378 top = bottom;
4379 }
Herb Derbyefe39bc2018-05-01 17:06:20 -04004380 left = right;
Cary Clarkbad5ad72017-08-03 17:14:08 -04004381 }
4382 sk_sp<SkImage> image = SkImage::MakeFromBitmap(bitmap);
4383 SkImage* imagePtr = image.get();
4384 for (auto dest: { 20, 30, 40, 60, 90 } ) {
4385 canvas->drawImageNine(imagePtr, center, SkRect::MakeWH(dest, dest), nullptr);
4386 canvas->translate(dest + 4, 0);
4387 }
Cary Clark8032b982017-07-28 11:04:54 -04004388}
4389##
4390
Cary Clark2ade9972017-11-02 17:49:34 -04004391#SeeAlso drawImage drawBitmapNine drawImageLattice drawImageRect
Cary Clark8032b982017-07-28 11:04:54 -04004392
4393##
4394
4395# ------------------------------------------------------------------------------
4396
4397#Method void drawImageNine(const sk_sp<SkImage>& image, const SkIRect& center, const SkRect& dst,
Herb Derbyefe39bc2018-05-01 17:06:20 -04004398 const SkPaint* paint = nullptr)
Cary Clarkab2621d2018-01-30 10:08:57 -05004399#In Draw_Image
Cary Clark78de7512018-02-07 07:27:09 -05004400#In Draw
Cary Clark80247e52018-07-11 16:18:41 -04004401Draws Image image stretched proportionally to fit into Rect dst.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004402IRect center divides the image into nine sections: four sides, four corners, and
Cary Clarkce101242017-09-01 15:51:02 -04004403the center. Corners are not scaled, or scaled down proportionately if their sides
Cary Clarkbad5ad72017-08-03 17:14:08 -04004404are larger than dst; center and four sides are scaled to fit remaining space, if any.
Cary Clark8032b982017-07-28 11:04:54 -04004405
Cary Clarkbad5ad72017-08-03 17:14:08 -04004406Additionally transform draw using Clip, Matrix, and optional Paint paint.
4407
Cary Clark137b8742018-05-30 09:21:49 -04004408#paint_as_used_by_draw_lattice_or_draw_nine(image)#
Cary Clarkbad5ad72017-08-03 17:14:08 -04004409
4410If generated mask extends beyond image bounds, replicate image edge colors, just
4411as Shader made from SkImage::makeShader with SkShader::kClamp_TileMode set
Cary Clarkbc5697d2017-10-04 14:31:33 -04004412replicates the image edge color when it samples outside of its bounds.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004413
4414#Param image Image containing pixels, dimensions, and format ##
4415#Param center IRect edge of image corners and sides ##
4416#Param dst destination Rect of image to draw to ##
4417#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4418 and so on; or nullptr
4419##
Cary Clark8032b982017-07-28 11:04:54 -04004420
4421#Example
4422#Height 128
4423#Description
4424 The two leftmost images has four corners and sides to the left and right of center.
4425 The leftmost image scales the width of corners proportionately to fit.
Herb Derbyefe39bc2018-05-01 17:06:20 -04004426 The third and fourth image corners are not scaled; the sides and center are scaled to
Cary Clark8032b982017-07-28 11:04:54 -04004427 fill the remaining space.
4428 The rightmost image has four corners scaled vertically to fit, and uses sides above
4429 and below center to fill the remaining space.
4430##
Cary Clarkbad5ad72017-08-03 17:14:08 -04004431void draw(SkCanvas* canvas) {
4432 SkIRect center = { 20, 10, 50, 40 };
4433 SkBitmap bitmap;
4434 bitmap.allocPixels(SkImageInfo::MakeN32Premul(60, 60));
4435 SkCanvas bitCanvas(bitmap);
4436 SkPaint paint;
4437 SkColor gray = 0xFF000000;
4438 int left = 0;
4439 for (auto right: { center.fLeft, center.fRight, bitmap.width() } ) {
4440 int top = 0;
4441 for (auto bottom: { center.fTop, center.fBottom, bitmap.height() } ) {
4442 paint.setColor(gray);
4443 bitCanvas.drawIRect(SkIRect::MakeLTRB(left, top, right, bottom), paint);
4444 gray += 0x001f1f1f;
4445 top = bottom;
4446 }
Herb Derbyefe39bc2018-05-01 17:06:20 -04004447 left = right;
Cary Clarkbad5ad72017-08-03 17:14:08 -04004448 }
4449 sk_sp<SkImage> image = SkImage::MakeFromBitmap(bitmap);
4450 for (auto dest: { 20, 30, 40, 60, 90 } ) {
4451 canvas->drawImageNine(image, center, SkRect::MakeWH(dest, 110 - dest), nullptr);
4452 canvas->translate(dest + 4, 0);
4453 }
Cary Clark8032b982017-07-28 11:04:54 -04004454}
4455##
4456
Cary Clark2ade9972017-11-02 17:49:34 -04004457#SeeAlso drawImage drawBitmapNine drawImageLattice drawImageRect
Cary Clark8032b982017-07-28 11:04:54 -04004458
4459##
4460
4461# ------------------------------------------------------------------------------
4462
4463#Method void drawBitmap(const SkBitmap& bitmap, SkScalar left, SkScalar top,
Cary Clark73fa9722017-08-29 17:36:51 -04004464 const SkPaint* paint = nullptr)
Cary Clarkab2621d2018-01-30 10:08:57 -05004465#In Draw_Image
Cary Clark78de7512018-02-07 07:27:09 -05004466#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05004467#Line # draws Bitmap at (x, y) position ##
Cary Clark8032b982017-07-28 11:04:54 -04004468
Cary Clark80247e52018-07-11 16:18:41 -04004469Draws Bitmap bitmap, with its top-left corner at (left, top),
Cary Clark8032b982017-07-28 11:04:54 -04004470using Clip, Matrix, and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004471
Cary Clarka560c472017-11-27 10:44:06 -05004472If Paint paint is not nullptr, apply Color_Filter, Color_Alpha, Image_Filter,
Cary Clarkbad5ad72017-08-03 17:14:08 -04004473Blend_Mode, and Draw_Looper. If bitmap is kAlpha_8_SkColorType, apply Shader.
4474If paint contains Mask_Filter, generate mask from bitmap bounds.
4475
4476If generated mask extends beyond bitmap bounds, replicate bitmap edge colors,
4477just as Shader made from SkShader::MakeBitmapShader with
Cary Clarkbc5697d2017-10-04 14:31:33 -04004478SkShader::kClamp_TileMode set replicates the bitmap edge color when it samples
Herb Derbyefe39bc2018-05-01 17:06:20 -04004479outside of its bounds.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004480
4481#Param bitmap Bitmap containing pixels, dimensions, and format ##
4482#Param left left side of bitmap ##
4483#Param top top side of bitmap ##
4484#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4485 and so on; or nullptr
4486##
Cary Clark8032b982017-07-28 11:04:54 -04004487
4488#Example
4489#Height 64
Cary Clarkbad5ad72017-08-03 17:14:08 -04004490void draw(SkCanvas* canvas) {
4491 uint8_t pixels[][8] = { { 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00},
4492 { 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00},
4493 { 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00},
4494 { 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF},
4495 { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
4496 { 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00},
4497 { 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0x00},
4498 { 0xFF, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0xFF} };
4499 SkBitmap bitmap;
Herb Derbyefe39bc2018-05-01 17:06:20 -04004500 bitmap.installPixels(SkImageInfo::MakeA8(8, 8),
Cary Clarkbad5ad72017-08-03 17:14:08 -04004501 (void*) pixels, sizeof(pixels[0]));
4502 SkPaint paint;
4503 canvas->scale(4, 4);
4504 for (auto color : { SK_ColorRED, SK_ColorBLUE, 0xFF007F00} ) {
4505 paint.setColor(color);
4506 canvas->drawBitmap(bitmap, 0, 0, &paint);
4507 canvas->translate(12, 0);
4508 }
Cary Clark8032b982017-07-28 11:04:54 -04004509}
4510##
4511
Cary Clark2ade9972017-11-02 17:49:34 -04004512#SeeAlso drawImage drawBitmapLattice drawBitmapNine drawBitmapRect SkBitmap::readPixels SkBitmap::writePixels
Cary Clark8032b982017-07-28 11:04:54 -04004513
4514##
4515
4516# ------------------------------------------------------------------------------
4517
4518#Method void drawBitmapRect(const SkBitmap& bitmap, const SkRect& src, const SkRect& dst,
4519 const SkPaint* paint, SrcRectConstraint constraint = kStrict_SrcRectConstraint)
Cary Clarkab2621d2018-01-30 10:08:57 -05004520#In Draw_Image
Cary Clark78de7512018-02-07 07:27:09 -05004521#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05004522#Line # draws Bitmap, source Rect to destination Rect ##
Cary Clark8032b982017-07-28 11:04:54 -04004523
Cary Clark80247e52018-07-11 16:18:41 -04004524Draws Rect src of Bitmap bitmap, scaled and translated to fill Rect dst.
Cary Clark8032b982017-07-28 11:04:54 -04004525Additionally transform draw using Clip, Matrix, and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004526
Cary Clarkbad5ad72017-08-03 17:14:08 -04004527If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4528Blend_Mode, and Draw_Looper. If bitmap is kAlpha_8_SkColorType, apply Shader.
4529If paint contains Mask_Filter, generate mask from bitmap bounds.
4530
4531If generated mask extends beyond bitmap bounds, replicate bitmap edge colors,
4532just as Shader made from SkShader::MakeBitmapShader with
Cary Clarkbc5697d2017-10-04 14:31:33 -04004533SkShader::kClamp_TileMode set replicates the bitmap edge color when it samples
Cary Clarkbad5ad72017-08-03 17:14:08 -04004534outside of its bounds.
4535
4536constraint set to kStrict_SrcRectConstraint limits Paint Filter_Quality to
4537sample within src; set to kFast_SrcRectConstraint allows sampling outside to
4538improve performance.
4539
4540#Param bitmap Bitmap containing pixels, dimensions, and format ##
4541#Param src source Rect of image to draw from ##
4542#Param dst destination Rect of image to draw to ##
4543#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4544 and so on; or nullptr
4545##
4546#Param constraint filter strictly within src or draw faster ##
Cary Clark8032b982017-07-28 11:04:54 -04004547
4548#Example
4549#Height 64
Cary Clarkbad5ad72017-08-03 17:14:08 -04004550void draw(SkCanvas* canvas) {
4551 uint8_t pixels[][8] = { { 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00},
4552 { 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00},
4553 { 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00},
4554 { 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF},
4555 { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
4556 { 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00},
4557 { 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00},
4558 { 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00} };
4559 SkBitmap bitmap;
Herb Derbyefe39bc2018-05-01 17:06:20 -04004560 bitmap.installPixels(SkImageInfo::MakeA8(8, 8),
Cary Clarkbad5ad72017-08-03 17:14:08 -04004561 (void*) pixels, sizeof(pixels[0]));
4562 SkPaint paint;
Cary Clark681287e2018-03-16 11:34:15 -04004563 paint.setMaskFilter(SkMaskFilter::MakeBlur(kSolid_SkBlurStyle, 6));
Cary Clarkbad5ad72017-08-03 17:14:08 -04004564 for (auto color : { SK_ColorRED, SK_ColorBLUE, 0xFF007F00} ) {
4565 paint.setColor(color);
4566 canvas->drawBitmapRect(bitmap, SkRect::MakeWH(8, 8), SkRect::MakeWH(32, 32), &paint);
4567 canvas->translate(48, 0);
4568 }
Cary Clark8032b982017-07-28 11:04:54 -04004569}
4570##
4571
Cary Clark2ade9972017-11-02 17:49:34 -04004572#SeeAlso drawImageRect drawBitmap drawBitmapLattice drawBitmapNine
Cary Clark8032b982017-07-28 11:04:54 -04004573
4574##
4575
4576# ------------------------------------------------------------------------------
4577
4578#Method void drawBitmapRect(const SkBitmap& bitmap, const SkIRect& isrc, const SkRect& dst,
4579 const SkPaint* paint, SrcRectConstraint constraint = kStrict_SrcRectConstraint)
Cary Clarkab2621d2018-01-30 10:08:57 -05004580#In Draw_Image
Cary Clark78de7512018-02-07 07:27:09 -05004581#In Draw
Cary Clark80247e52018-07-11 16:18:41 -04004582Draws IRect isrc of Bitmap bitmap, scaled and translated to fill Rect dst.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004583isrc is on integer pixel boundaries; dst may include fractional boundaries.
Cary Clark8032b982017-07-28 11:04:54 -04004584Additionally transform draw using Clip, Matrix, and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004585
Cary Clarkbad5ad72017-08-03 17:14:08 -04004586If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4587Blend_Mode, and Draw_Looper. If bitmap is kAlpha_8_SkColorType, apply Shader.
4588If paint contains Mask_Filter, generate mask from bitmap bounds.
4589
4590If generated mask extends beyond bitmap bounds, replicate bitmap edge colors,
4591just as Shader made from SkShader::MakeBitmapShader with
Cary Clarkbc5697d2017-10-04 14:31:33 -04004592SkShader::kClamp_TileMode set replicates the bitmap edge color when it samples
Cary Clarkbad5ad72017-08-03 17:14:08 -04004593outside of its bounds.
4594
4595constraint set to kStrict_SrcRectConstraint limits Paint Filter_Quality to
Cary Clarkce101242017-09-01 15:51:02 -04004596sample within isrc; set to kFast_SrcRectConstraint allows sampling outside to
Cary Clarkbad5ad72017-08-03 17:14:08 -04004597improve performance.
4598
4599#Param bitmap Bitmap containing pixels, dimensions, and format ##
4600#Param isrc source IRect of image to draw from ##
4601#Param dst destination Rect of image to draw to ##
4602#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4603 and so on; or nullptr
4604##
Cary Clarkce101242017-09-01 15:51:02 -04004605#Param constraint sample strictly within isrc, or draw faster ##
Cary Clark8032b982017-07-28 11:04:54 -04004606
4607#Example
4608#Height 64
Cary Clarkbad5ad72017-08-03 17:14:08 -04004609void draw(SkCanvas* canvas) {
4610 uint8_t pixels[][8] = { { 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00},
4611 { 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00},
4612 { 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0xFF},
4613 { 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0xFF},
4614 { 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF},
4615 { 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF},
4616 { 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00},
4617 { 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00} };
4618 SkBitmap bitmap;
Herb Derbyefe39bc2018-05-01 17:06:20 -04004619 bitmap.installPixels(SkImageInfo::MakeA8(8, 8),
Cary Clarkbad5ad72017-08-03 17:14:08 -04004620 (void*) pixels, sizeof(pixels[0]));
4621 SkPaint paint;
4622 paint.setFilterQuality(kHigh_SkFilterQuality);
4623 for (auto color : { SK_ColorRED, SK_ColorBLUE, 0xFF007F00, 0xFF7f007f} ) {
4624 paint.setColor(color);
4625 canvas->drawBitmapRect(bitmap, SkIRect::MakeWH(8, 8), SkRect::MakeWH(32, 32), &paint);
4626 canvas->translate(48.25f, 0);
4627 }
Cary Clark8032b982017-07-28 11:04:54 -04004628}
4629##
4630
Cary Clark2ade9972017-11-02 17:49:34 -04004631#SeeAlso drawImageRect drawBitmap drawBitmapLattice drawBitmapNine
Cary Clark8032b982017-07-28 11:04:54 -04004632
4633##
4634
4635# ------------------------------------------------------------------------------
4636
4637#Method void drawBitmapRect(const SkBitmap& bitmap, const SkRect& dst, const SkPaint* paint,
4638 SrcRectConstraint constraint = kStrict_SrcRectConstraint)
Cary Clarkab2621d2018-01-30 10:08:57 -05004639#In Draw_Image
Cary Clark78de7512018-02-07 07:27:09 -05004640#In Draw
Cary Clark80247e52018-07-11 16:18:41 -04004641Draws Bitmap bitmap, scaled and translated to fill Rect dst.
Cary Clarkce101242017-09-01 15:51:02 -04004642bitmap bounds is on integer pixel boundaries; dst may include fractional boundaries.
Cary Clark8032b982017-07-28 11:04:54 -04004643Additionally transform draw using Clip, Matrix, and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004644
Cary Clarkbad5ad72017-08-03 17:14:08 -04004645If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4646Blend_Mode, and Draw_Looper. If bitmap is kAlpha_8_SkColorType, apply Shader.
4647If paint contains Mask_Filter, generate mask from bitmap bounds.
4648
4649If generated mask extends beyond bitmap bounds, replicate bitmap edge colors,
4650just as Shader made from SkShader::MakeBitmapShader with
Cary Clarkbc5697d2017-10-04 14:31:33 -04004651SkShader::kClamp_TileMode set replicates the bitmap edge color when it samples
Cary Clarkbad5ad72017-08-03 17:14:08 -04004652outside of its bounds.
4653
4654constraint set to kStrict_SrcRectConstraint limits Paint Filter_Quality to
Cary Clarkce101242017-09-01 15:51:02 -04004655sample within bitmap; set to kFast_SrcRectConstraint allows sampling outside to
Cary Clarkbad5ad72017-08-03 17:14:08 -04004656improve performance.
4657
4658#Param bitmap Bitmap containing pixels, dimensions, and format ##
4659#Param dst destination Rect of image to draw to ##
4660#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4661 and so on; or nullptr
4662##
Cary Clarkce101242017-09-01 15:51:02 -04004663#Param constraint filter strictly within bitmap or draw faster ##
Cary Clark8032b982017-07-28 11:04:54 -04004664
4665#Example
4666#Height 64
Cary Clarkbad5ad72017-08-03 17:14:08 -04004667void draw(SkCanvas* canvas) {
4668 uint32_t pixels[][2] = { { 0x00000000, 0x55550000},
4669 { 0xAAAA0000, 0xFFFF0000} };
4670 SkBitmap bitmap;
Herb Derbyefe39bc2018-05-01 17:06:20 -04004671 bitmap.installPixels(SkImageInfo::MakeN32Premul(2, 2),
Cary Clarkbad5ad72017-08-03 17:14:08 -04004672 (void*) pixels, sizeof(pixels[0]));
4673 SkPaint paint;
4674 canvas->scale(4, 4);
4675 for (auto color : { SK_ColorRED, SK_ColorBLUE, SK_ColorGREEN } ) {
4676 paint.setColorFilter(SkColorFilter::MakeModeFilter(color, SkBlendMode::kPlus));
4677 canvas->drawBitmapRect(bitmap, SkRect::MakeWH(8, 8), &paint);
4678 canvas->translate(8, 0);
4679 }
Cary Clark8032b982017-07-28 11:04:54 -04004680}
4681##
4682
Cary Clark2ade9972017-11-02 17:49:34 -04004683#SeeAlso drawImageRect drawBitmap drawBitmapLattice drawBitmapNine
Cary Clark8032b982017-07-28 11:04:54 -04004684
4685##
4686
4687# ------------------------------------------------------------------------------
4688
Cary Clark682c58d2018-05-16 07:07:07 -04004689#PhraseDef paint_as_used_by_draw_lattice_or_draw_nine(bitmap_or_image)
4690If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4691Blend_Mode, and Draw_Looper. If #bitmap_or_image# is kAlpha_8_SkColorType, apply Shader.
4692If paint contains Mask_Filter, generate mask from #bitmap_or_image# bounds. If paint
4693Filter_Quality set to kNone_SkFilterQuality, disable pixel filtering. For all
4694other values of paint Filter_Quality, use kLow_SkFilterQuality to filter pixels.
Cary Clark137b8742018-05-30 09:21:49 -04004695Any SkMaskFilter on paint is ignored as is paint Anti_Aliasing state.
Cary Clark682c58d2018-05-16 07:07:07 -04004696##
4697
Cary Clark8032b982017-07-28 11:04:54 -04004698#Method void drawBitmapNine(const SkBitmap& bitmap, const SkIRect& center, const SkRect& dst,
Cary Clark73fa9722017-08-29 17:36:51 -04004699 const SkPaint* paint = nullptr)
Cary Clarkab2621d2018-01-30 10:08:57 -05004700#In Draw_Image
Cary Clark78de7512018-02-07 07:27:09 -05004701#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05004702#Line # draws Nine_Patch Bitmap ##
Cary Clark8032b982017-07-28 11:04:54 -04004703
Cary Clark80247e52018-07-11 16:18:41 -04004704Draws Bitmap bitmap stretched proportionally to fit into Rect dst.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004705IRect center divides the bitmap into nine sections: four sides, four corners,
Cary Clarkce101242017-09-01 15:51:02 -04004706and the center. Corners are not scaled, or scaled down proportionately if their
Cary Clarkbad5ad72017-08-03 17:14:08 -04004707sides are larger than dst; center and four sides are scaled to fit remaining
4708space, if any.
Cary Clark8032b982017-07-28 11:04:54 -04004709
Cary Clarkbad5ad72017-08-03 17:14:08 -04004710Additionally transform draw using Clip, Matrix, and optional Paint paint.
4711
Cary Clark682c58d2018-05-16 07:07:07 -04004712#paint_as_used_by_draw_lattice_or_draw_nine(bitmap)#
Cary Clarkbad5ad72017-08-03 17:14:08 -04004713
4714If generated mask extends beyond bitmap bounds, replicate bitmap edge colors,
4715just as Shader made from SkShader::MakeBitmapShader with
Cary Clarkbc5697d2017-10-04 14:31:33 -04004716SkShader::kClamp_TileMode set replicates the bitmap edge color when it samples
Cary Clarkbad5ad72017-08-03 17:14:08 -04004717outside of its bounds.
4718
4719#Param bitmap Bitmap containing pixels, dimensions, and format ##
4720#Param center IRect edge of image corners and sides ##
4721#Param dst destination Rect of image to draw to ##
4722#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4723 and so on; or nullptr
4724##
Cary Clark8032b982017-07-28 11:04:54 -04004725
4726#Example
4727#Height 128
4728#Description
4729 The two leftmost bitmap draws has four corners and sides to the left and right of center.
4730 The leftmost bitmap draw scales the width of corners proportionately to fit.
Herb Derbyefe39bc2018-05-01 17:06:20 -04004731 The third and fourth draw corners are not scaled; the sides and center are scaled to
Cary Clark8032b982017-07-28 11:04:54 -04004732 fill the remaining space.
4733 The rightmost bitmap draw has four corners scaled vertically to fit, and uses sides above
4734 and below center to fill the remaining space.
4735##
Cary Clarkbad5ad72017-08-03 17:14:08 -04004736void draw(SkCanvas* canvas) {
4737 SkIRect center = { 20, 10, 50, 40 };
4738 SkBitmap bitmap;
4739 bitmap.allocPixels(SkImageInfo::MakeN32Premul(60, 60));
4740 SkCanvas bitCanvas(bitmap);
4741 SkPaint paint;
4742 SkColor gray = 0xFF000000;
4743 int left = 0;
4744 for (auto right: { center.fLeft, center.fRight, bitmap.width() } ) {
4745 int top = 0;
4746 for (auto bottom: { center.fTop, center.fBottom, bitmap.height() } ) {
4747 paint.setColor(gray);
4748 bitCanvas.drawIRect(SkIRect::MakeLTRB(left, top, right, bottom), paint);
4749 gray += 0x001f1f1f;
4750 top = bottom;
4751 }
Herb Derbyefe39bc2018-05-01 17:06:20 -04004752 left = right;
Cary Clarkbad5ad72017-08-03 17:14:08 -04004753 }
4754 for (auto dest: { 20, 30, 40, 60, 90 } ) {
4755 canvas->drawBitmapNine(bitmap, center, SkRect::MakeWH(dest, 110 - dest), nullptr);
4756 canvas->translate(dest + 4, 0);
4757 }
Cary Clark8032b982017-07-28 11:04:54 -04004758}
4759##
4760
Cary Clark2ade9972017-11-02 17:49:34 -04004761#SeeAlso drawImageNine drawBitmap drawBitmapLattice drawBitmapRect
Cary Clark8032b982017-07-28 11:04:54 -04004762
4763##
4764
4765# ------------------------------------------------------------------------------
Cary Clark682c58d2018-05-16 07:07:07 -04004766#Subtopic Lattice
4767#Line # divides Bitmap or Image into a rectangular grid ##
4768
Cary Clark8032b982017-07-28 11:04:54 -04004769#Struct Lattice
Cary Clark08895c42018-02-01 09:37:32 -05004770#Line # divides Bitmap or Image into a rectangular grid ##
Cary Clark682c58d2018-05-16 07:07:07 -04004771
Cary Clark8032b982017-07-28 11:04:54 -04004772#Code
4773 struct Lattice {
Cary Clark2f466242017-12-11 16:03:17 -05004774 enum RectType ...
Cary Clark8032b982017-07-28 11:04:54 -04004775
Cary Clark2f466242017-12-11 16:03:17 -05004776 const int* fXDivs;
4777 const int* fYDivs;
4778 const RectType* fRectTypes;
4779 int fXCount;
4780 int fYCount;
4781 const SkIRect* fBounds;
4782 const SkColor* fColors;
Cary Clark8032b982017-07-28 11:04:54 -04004783 };
4784##
4785
Cary Clark137b8742018-05-30 09:21:49 -04004786Lattice divides Bitmap or Image into a rectangular grid.
4787Grid entries on even columns and even rows are fixed; these entries are
4788always drawn at their original size if the destination is large enough.
4789If the destination side is too small to hold the fixed entries, all fixed
4790entries are proportionately scaled down to fit.
4791The grid entries not on even columns and rows are scaled to fit the
4792remaining space, if any.
4793
Cary Clark682c58d2018-05-16 07:07:07 -04004794#Subtopic Overview
4795#Populate
4796##
4797
4798#Subtopic Constant
4799#Populate
4800##
Cary Clark154beea2017-10-26 07:58:48 -04004801
Cary Clark2f466242017-12-11 16:03:17 -05004802 #Enum RectType
Cary Clark682c58d2018-05-16 07:07:07 -04004803 #Line # optional setting per rectangular grid entry ##
Cary Clark8032b982017-07-28 11:04:54 -04004804 #Code
Cary Clark2f466242017-12-11 16:03:17 -05004805 enum RectType : uint8_t {
4806 kDefault = 0,
4807 kTransparent,
4808 kFixedColor,
Cary Clark8032b982017-07-28 11:04:54 -04004809 };
4810 ##
4811
Cary Clark2f466242017-12-11 16:03:17 -05004812 Optional setting per rectangular grid entry to make it transparent,
4813 or to fill the grid entry with a color.
Cary Clark8032b982017-07-28 11:04:54 -04004814
Cary Clark2f466242017-12-11 16:03:17 -05004815 #Const kDefault 0
Cary Clark682c58d2018-05-16 07:07:07 -04004816 #Line # draws Bitmap into lattice rectangle ##
Cary Clark2f466242017-12-11 16:03:17 -05004817 ##
4818
4819 #Const kTransparent 1
Cary Clark682c58d2018-05-16 07:07:07 -04004820 #Line # skips lattice rectangle by making it transparent ##
Cary Clark2f466242017-12-11 16:03:17 -05004821 ##
4822
4823 #Const kFixedColor 2
Cary Clark682c58d2018-05-16 07:07:07 -04004824 #Line # draws one of fColors into lattice rectangle ##
Cary Clark8032b982017-07-28 11:04:54 -04004825 ##
4826 ##
4827
Cary Clark682c58d2018-05-16 07:07:07 -04004828#Subtopic Member
4829#Populate
4830##
4831
Cary Clark8032b982017-07-28 11:04:54 -04004832 #Member const int* fXDivs
Cary Clark5538c132018-06-14 12:28:14 -04004833 #Line # x-axis values dividing bitmap ##
4834 Array of x-axis values that divide the bitmap vertically.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004835 Array entries must be unique, increasing, greater than or equal to
4836 fBounds left edge, and less than fBounds right edge.
4837 Set the first element to fBounds left to collapse the left column of
4838 fixed grid entries.
Cary Clark8032b982017-07-28 11:04:54 -04004839 ##
4840
4841 #Member const int* fYDivs
Cary Clark5538c132018-06-14 12:28:14 -04004842 #Line # y-axis values dividing bitmap ##
4843 Array of y-axis values that divide the bitmap horizontally.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004844 Array entries must be unique, increasing, greater than or equal to
4845 fBounds top edge, and less than fBounds bottom edge.
4846 Set the first element to fBounds top to collapse the top row of fixed
4847 grid entries.
Cary Clark8032b982017-07-28 11:04:54 -04004848 ##
4849
Cary Clark2f466242017-12-11 16:03:17 -05004850 #Member const RectType* fRectTypes
Cary Clark682c58d2018-05-16 07:07:07 -04004851 #Line # array of fill types ##
Cary Clark2f466242017-12-11 16:03:17 -05004852 Optional array of fill types, one per rectangular grid entry:
Cary Clarkbad5ad72017-08-03 17:14:08 -04004853 array length must be
4854 #Formula
4855 (fXCount + 1) * (fYCount + 1)
4856 ##
4857 .
Cary Clark6fc50412017-09-21 12:31:06 -04004858
Cary Clark2f466242017-12-11 16:03:17 -05004859 Each RectType is one of: kDefault, kTransparent, kFixedColor.
4860
Cary Clark8032b982017-07-28 11:04:54 -04004861 Array entries correspond to the rectangular grid entries, ascending
4862 left to right and then top to bottom.
4863 ##
4864
4865 #Member int fXCount
Cary Clark682c58d2018-05-16 07:07:07 -04004866 #Line # number of x-coordinates ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04004867 Number of entries in fXDivs array; one less than the number of
4868 horizontal divisions.
Cary Clark8032b982017-07-28 11:04:54 -04004869 ##
4870
4871 #Member int fYCount
Cary Clark682c58d2018-05-16 07:07:07 -04004872 #Line # number of y-coordinates ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04004873 Number of entries in fYDivs array; one less than the number of vertical
4874 divisions.
Cary Clark8032b982017-07-28 11:04:54 -04004875 ##
4876
4877 #Member const SkIRect* fBounds
Cary Clark682c58d2018-05-16 07:07:07 -04004878 #Line # source bounds to draw from ##
Cary Clark8032b982017-07-28 11:04:54 -04004879 Optional subset IRect source to draw from.
4880 If nullptr, source bounds is dimensions of Bitmap or Image.
4881 ##
4882
Cary Clark2f466242017-12-11 16:03:17 -05004883 #Member const SkColor* fColors
Cary Clark682c58d2018-05-16 07:07:07 -04004884 #Line # array of colors ##
Cary Clark2f466242017-12-11 16:03:17 -05004885 Optional array of colors, one per rectangular grid entry.
4886 Array length must be
4887 #Formula
4888 (fXCount + 1) * (fYCount + 1)
4889 ##
4890 .
4891
4892 Array entries correspond to the rectangular grid entries, ascending
4893 left to right, then top to bottom.
4894 ##
4895
Cary Clark8032b982017-07-28 11:04:54 -04004896#Struct Lattice ##
4897
4898#Method void drawBitmapLattice(const SkBitmap& bitmap, const Lattice& lattice, const SkRect& dst,
4899 const SkPaint* paint = nullptr)
Cary Clarkab2621d2018-01-30 10:08:57 -05004900#In Draw_Image
Cary Clark78de7512018-02-07 07:27:09 -05004901#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05004902#Line # draws proportionally stretched Bitmap ##
Cary Clark8032b982017-07-28 11:04:54 -04004903
Cary Clark80247e52018-07-11 16:18:41 -04004904Draws Bitmap bitmap stretched proportionally to fit into Rect dst.
Cary Clark8032b982017-07-28 11:04:54 -04004905
4906Lattice lattice divides bitmap into a rectangular grid.
4907Each intersection of an even-numbered row and column is fixed; like the corners
Cary Clarkbad5ad72017-08-03 17:14:08 -04004908of drawBitmapNine, fixed lattice elements never scale larger than their initial
Cary Clarkbc5697d2017-10-04 14:31:33 -04004909size and shrink proportionately when all fixed elements exceed the bitmap
Cary Clarkbad5ad72017-08-03 17:14:08 -04004910dimension. All other grid elements scale to fill the available space, if any.
Cary Clark8032b982017-07-28 11:04:54 -04004911
4912Additionally transform draw using Clip, Matrix, and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004913
Cary Clark682c58d2018-05-16 07:07:07 -04004914#paint_as_used_by_draw_lattice_or_draw_nine(bitmap)#
Cary Clarkbad5ad72017-08-03 17:14:08 -04004915
4916If generated mask extends beyond bitmap bounds, replicate bitmap edge colors,
4917just as Shader made from SkShader::MakeBitmapShader with
Cary Clarkbc5697d2017-10-04 14:31:33 -04004918SkShader::kClamp_TileMode set replicates the bitmap edge color when it samples
Cary Clarkbad5ad72017-08-03 17:14:08 -04004919outside of its bounds.
4920
4921#Param bitmap Bitmap containing pixels, dimensions, and format ##
4922#Param lattice division of bitmap into fixed and variable rectangles ##
4923#Param dst destination Rect of image to draw to ##
4924#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4925 and so on; or nullptr
4926##
Cary Clark8032b982017-07-28 11:04:54 -04004927
4928#Example
4929#Height 128
4930#Description
4931 The two leftmost bitmap draws has four corners and sides to the left and right of center.
4932 The leftmost bitmap draw scales the width of corners proportionately to fit.
Herb Derbyefe39bc2018-05-01 17:06:20 -04004933 The third and fourth draw corners are not scaled; the sides are scaled to
Cary Clark8032b982017-07-28 11:04:54 -04004934 fill the remaining space; the center is transparent.
4935 The rightmost bitmap draw has four corners scaled vertically to fit, and uses sides above
4936 and below center to fill the remaining space.
4937##
Cary Clarkbad5ad72017-08-03 17:14:08 -04004938void draw(SkCanvas* canvas) {
4939 SkIRect center = { 20, 10, 50, 40 };
4940 SkBitmap bitmap;
4941 bitmap.allocPixels(SkImageInfo::MakeN32Premul(60, 60));
4942 SkCanvas bitCanvas(bitmap);
4943 SkPaint paint;
4944 SkColor gray = 0xFF000000;
4945 int left = 0;
4946 for (auto right: { center.fLeft, center.fRight, bitmap.width() } ) {
4947 int top = 0;
4948 for (auto bottom: { center.fTop, center.fBottom, bitmap.height() } ) {
4949 paint.setColor(gray);
4950 bitCanvas.drawIRect(SkIRect::MakeLTRB(left, top, right, bottom), paint);
4951 gray += 0x001f1f1f;
4952 top = bottom;
4953 }
Herb Derbyefe39bc2018-05-01 17:06:20 -04004954 left = right;
Cary Clarkbad5ad72017-08-03 17:14:08 -04004955 }
4956 const int xDivs[] = { center.fLeft, center.fRight };
4957 const int yDivs[] = { center.fTop, center.fBottom };
Cary Clarkca3ebcd2017-12-12 11:22:38 -05004958 SkCanvas::Lattice::RectType fillTypes[3][3];
4959 memset(fillTypes, 0, sizeof(fillTypes));
4960 fillTypes[1][1] = SkCanvas::Lattice::kTransparent;
4961 SkColor dummy[9]; // temporary pending bug fix
4962 SkCanvas::Lattice lattice = { xDivs, yDivs, fillTypes[0], SK_ARRAY_COUNT(xDivs),
4963 SK_ARRAY_COUNT(yDivs), nullptr, dummy };
Cary Clarkbad5ad72017-08-03 17:14:08 -04004964 for (auto dest: { 20, 30, 40, 60, 90 } ) {
Cary Clarkca3ebcd2017-12-12 11:22:38 -05004965 canvas->drawBitmapLattice(bitmap, lattice, SkRect::MakeWH(dest, 110 - dest), nullptr);
Cary Clarkbad5ad72017-08-03 17:14:08 -04004966 canvas->translate(dest + 4, 0);
4967 }
Cary Clark8032b982017-07-28 11:04:54 -04004968}
4969##
4970
Cary Clark2ade9972017-11-02 17:49:34 -04004971#SeeAlso drawImageLattice drawBitmap drawBitmapNine Lattice
Cary Clark8032b982017-07-28 11:04:54 -04004972
4973##
4974
4975# ------------------------------------------------------------------------------
4976
4977#Method void drawImageLattice(const SkImage* image, const Lattice& lattice, const SkRect& dst,
4978 const SkPaint* paint = nullptr)
Cary Clarkab2621d2018-01-30 10:08:57 -05004979#In Draw_Image
Cary Clark78de7512018-02-07 07:27:09 -05004980#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05004981#Line # draws proportionally stretched Image ##
Cary Clark8032b982017-07-28 11:04:54 -04004982
Cary Clark80247e52018-07-11 16:18:41 -04004983Draws Image image stretched proportionally to fit into Rect dst.
Cary Clark8032b982017-07-28 11:04:54 -04004984
4985Lattice lattice divides image into a rectangular grid.
4986Each intersection of an even-numbered row and column is fixed; like the corners
Cary Clarkbad5ad72017-08-03 17:14:08 -04004987of drawBitmapNine, fixed lattice elements never scale larger than their initial
Cary Clarkbc5697d2017-10-04 14:31:33 -04004988size and shrink proportionately when all fixed elements exceed the bitmap
Cary Clarkbad5ad72017-08-03 17:14:08 -04004989dimension. All other grid elements scale to fill the available space, if any.
Cary Clark8032b982017-07-28 11:04:54 -04004990
4991Additionally transform draw using Clip, Matrix, and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004992
Cary Clark682c58d2018-05-16 07:07:07 -04004993#paint_as_used_by_draw_lattice_or_draw_nine(image)#
Cary Clarkbad5ad72017-08-03 17:14:08 -04004994
4995If generated mask extends beyond bitmap bounds, replicate bitmap edge colors,
4996just as Shader made from SkShader::MakeBitmapShader with
Cary Clarkbc5697d2017-10-04 14:31:33 -04004997SkShader::kClamp_TileMode set replicates the bitmap edge color when it samples
Cary Clarkbad5ad72017-08-03 17:14:08 -04004998outside of its bounds.
4999
5000#Param image Image containing pixels, dimensions, and format ##
5001#Param lattice division of bitmap into fixed and variable rectangles ##
5002#Param dst destination Rect of image to draw to ##
5003#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
5004 and so on; or nullptr
5005##
Cary Clark8032b982017-07-28 11:04:54 -04005006
5007#Example
5008#Height 128
5009#Description
5010 The leftmost image is smaller than center; only corners are drawn, all scaled to fit.
Cary Clarkce101242017-09-01 15:51:02 -04005011 The second image equals the size of center; only corners are drawn without scaling.
5012 The remaining images are larger than center. All corners draw without scaling. The sides
Cary Clark8032b982017-07-28 11:04:54 -04005013 are scaled if needed to take up the remaining space; the center is transparent.
5014##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005015void draw(SkCanvas* canvas) {
5016 SkIRect center = { 20, 10, 50, 40 };
5017 SkBitmap bitmap;
5018 bitmap.allocPixels(SkImageInfo::MakeN32Premul(60, 60));
5019 SkCanvas bitCanvas(bitmap);
5020 SkPaint paint;
5021 SkColor gray = 0xFF000000;
5022 int left = 0;
5023 for (auto right: { center.fLeft, center.fRight, bitmap.width() } ) {
5024 int top = 0;
5025 for (auto bottom: { center.fTop, center.fBottom, bitmap.height() } ) {
5026 paint.setColor(gray);
5027 bitCanvas.drawIRect(SkIRect::MakeLTRB(left, top, right, bottom), paint);
5028 gray += 0x001f1f1f;
5029 top = bottom;
5030 }
Herb Derbyefe39bc2018-05-01 17:06:20 -04005031 left = right;
Cary Clarkbad5ad72017-08-03 17:14:08 -04005032 }
Cary Clarkbad5ad72017-08-03 17:14:08 -04005033 sk_sp<SkImage> image = SkImage::MakeFromBitmap(bitmap);
5034 SkImage* imagePtr = image.get();
5035 for (auto dest: { 20, 30, 40, 60, 90 } ) {
5036 canvas->drawImageNine(imagePtr, center, SkRect::MakeWH(dest, dest), nullptr);
5037 canvas->translate(dest + 4, 0);
5038 }
Cary Clark8032b982017-07-28 11:04:54 -04005039}
5040##
5041
Cary Clark2ade9972017-11-02 17:49:34 -04005042#SeeAlso drawBitmapLattice drawImage drawImageNine Lattice
Cary Clark8032b982017-07-28 11:04:54 -04005043
5044##
5045
Cary Clark682c58d2018-05-16 07:07:07 -04005046#Subtopic Lattice ##
5047
Cary Clark08895c42018-02-01 09:37:32 -05005048#Subtopic Draw_Image ##
Cary Clark8032b982017-07-28 11:04:54 -04005049
5050# ------------------------------------------------------------------------------
Cary Clark78de7512018-02-07 07:27:09 -05005051#Subtopic Draw_Text
5052#Populate
5053#Line # draws text into Canvas ##
5054##
Cary Clark8032b982017-07-28 11:04:54 -04005055
5056#Method void drawText(const void* text, size_t byteLength, SkScalar x, SkScalar y,
5057 const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05005058#In Draw_Text
5059#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05005060#Line # draws text at (x, y), using font advance ##
Cary Clark8032b982017-07-28 11:04:54 -04005061
Cary Clark80247e52018-07-11 16:18:41 -04005062Draws text, with origin at (x, y), using Clip, Matrix, and Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04005063
Cary Clarkbc5697d2017-10-04 14:31:33 -04005064text meaning depends on Paint_Text_Encoding; by default, text is encoded as
Cary Clarkbad5ad72017-08-03 17:14:08 -04005065UTF-8.
Cary Clark8032b982017-07-28 11:04:54 -04005066
Cary Clarkbad5ad72017-08-03 17:14:08 -04005067x and y meaning depends on Paint_Text_Align and Paint_Vertical_Text; by default
Cary Clarkbc5697d2017-10-04 14:31:33 -04005068text draws left to right, positioning the first glyph left side bearing at x
Herb Derbyefe39bc2018-05-01 17:06:20 -04005069and its baseline at y. Text size is affected by Matrix and Paint_Text_Size.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005070
Mike Reed8ad91a92018-01-19 19:09:32 -05005071All elements of paint: Path_Effect, Mask_Filter, Shader,
Cary Clarkbad5ad72017-08-03 17:14:08 -04005072Color_Filter, Image_Filter, and Draw_Looper; apply to text. By default, draws
Cary Clarkce101242017-09-01 15:51:02 -04005073filled 12 point black Glyphs.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005074
Cary Clarkce101242017-09-01 15:51:02 -04005075#Param text character code points or Glyphs drawn ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005076#Param byteLength byte length of text array ##
5077#Param x start of text on x-axis ##
5078#Param y start of text on y-axis ##
5079#Param paint text size, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005080
5081#Example
5082#Height 200
5083#Description
5084 The same text is drawn varying Paint_Text_Size and varying
Herb Derbyefe39bc2018-05-01 17:06:20 -04005085 Matrix.
Cary Clark8032b982017-07-28 11:04:54 -04005086##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005087void draw(SkCanvas* canvas) {
5088 SkPaint paint;
5089 paint.setAntiAlias(true);
5090 float textSizes[] = { 12, 18, 24, 36 };
5091 for (auto size: textSizes ) {
5092 paint.setTextSize(size);
5093 canvas->drawText("Aa", 2, 10, 20, paint);
5094 canvas->translate(0, size * 2);
5095 }
5096 paint.reset();
5097 paint.setAntiAlias(true);
5098 float yPos = 20;
5099 for (auto size: textSizes ) {
5100 float scale = size / 12.f;
5101 canvas->resetMatrix();
5102 canvas->translate(100, 0);
5103 canvas->scale(scale, scale);
5104 canvas->drawText("Aa", 2, 10 / scale, yPos / scale, paint);
Herb Derbyefe39bc2018-05-01 17:06:20 -04005105 yPos += size * 2;
Cary Clarkbad5ad72017-08-03 17:14:08 -04005106 }
5107}
Cary Clark8032b982017-07-28 11:04:54 -04005108##
5109
Cary Clark153e76d2018-08-28 11:48:28 -04005110#SeeAlso drawString drawPosText drawPosTextH drawTextBlob drawTextRSXform
Cary Clark8032b982017-07-28 11:04:54 -04005111
5112##
5113
5114#Method void drawString(const char* string, SkScalar x, SkScalar y, const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05005115#In Draw_Text
5116#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05005117#Line # draws null terminated string at (x, y) using font advance ##
Cary Clark682c58d2018-05-16 07:07:07 -04005118Draws null terminated string, with origin at (x, y), using Clip, Matrix, and
5119Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04005120
Cary Clarkbc5697d2017-10-04 14:31:33 -04005121string meaning depends on Paint_Text_Encoding; by default, strings are encoded
5122as UTF-8. Other values of Paint_Text_Encoding are unlikely to produce the desired
Cary Clarkbad5ad72017-08-03 17:14:08 -04005123results, since zero bytes may be embedded in the string.
Cary Clark8032b982017-07-28 11:04:54 -04005124
Cary Clarkbad5ad72017-08-03 17:14:08 -04005125x and y meaning depends on Paint_Text_Align and Paint_Vertical_Text; by default
Cary Clarkbc5697d2017-10-04 14:31:33 -04005126string draws left to right, positioning the first glyph left side bearing at x
Herb Derbyefe39bc2018-05-01 17:06:20 -04005127and its baseline at y. Text size is affected by Matrix and Paint_Text_Size.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005128
Mike Reed8ad91a92018-01-19 19:09:32 -05005129All elements of paint: Path_Effect, Mask_Filter, Shader,
Cary Clarkbad5ad72017-08-03 17:14:08 -04005130Color_Filter, Image_Filter, and Draw_Looper; apply to text. By default, draws
Cary Clarkce101242017-09-01 15:51:02 -04005131filled 12 point black Glyphs.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005132
Cary Clarkce101242017-09-01 15:51:02 -04005133#Param string character code points or Glyphs drawn,
Cary Clarkbad5ad72017-08-03 17:14:08 -04005134 ending with a char value of zero
5135##
5136#Param x start of string on x-axis ##
5137#Param y start of string on y-axis ##
5138#Param paint text size, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005139
5140#Example
Cary Clarkffb3d682018-05-17 12:17:28 -04005141#Height 48
Cary Clark8032b982017-07-28 11:04:54 -04005142 SkPaint paint;
5143 canvas->drawString("a small hello", 20, 20, paint);
5144##
5145
Cary Clark153e76d2018-08-28 11:48:28 -04005146#SeeAlso drawText drawPosText drawPosTextH drawTextBlob drawTextRSXform
Cary Clark8032b982017-07-28 11:04:54 -04005147
5148##
5149
5150#Method void drawString(const SkString& string, SkScalar x, SkScalar y, const SkPaint& paint)
5151
Cary Clark80247e52018-07-11 16:18:41 -04005152Draws null terminated string, with origin at (x, y), using Clip, Matrix, and
Cary Clarkbad5ad72017-08-03 17:14:08 -04005153Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04005154
Cary Clarkbc5697d2017-10-04 14:31:33 -04005155string meaning depends on Paint_Text_Encoding; by default, strings are encoded
5156as UTF-8. Other values of Paint_Text_Encoding are unlikely to produce the desired
Cary Clarkbad5ad72017-08-03 17:14:08 -04005157results, since zero bytes may be embedded in the string.
Cary Clark8032b982017-07-28 11:04:54 -04005158
Cary Clarkbad5ad72017-08-03 17:14:08 -04005159x and y meaning depends on Paint_Text_Align and Paint_Vertical_Text; by default
Cary Clarkbc5697d2017-10-04 14:31:33 -04005160string draws left to right, positioning the first glyph left side bearing at x
Herb Derbyefe39bc2018-05-01 17:06:20 -04005161and its baseline at y. Text size is affected by Matrix and Paint_Text_Size.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005162
Mike Reed8ad91a92018-01-19 19:09:32 -05005163All elements of paint: Path_Effect, Mask_Filter, Shader,
Cary Clarkbad5ad72017-08-03 17:14:08 -04005164Color_Filter, Image_Filter, and Draw_Looper; apply to text. By default, draws
Cary Clarkce101242017-09-01 15:51:02 -04005165filled 12 point black Glyphs.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005166
Cary Clarkce101242017-09-01 15:51:02 -04005167#Param string character code points or Glyphs drawn,
Cary Clarkbad5ad72017-08-03 17:14:08 -04005168 ending with a char value of zero
5169##
5170#Param x start of string on x-axis ##
5171#Param y start of string on y-axis ##
5172#Param paint text size, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005173
5174#Example
5175 SkPaint paint;
5176 SkString string("a small hello");
5177 canvas->drawString(string, 20, 20, paint);
5178##
5179
Cary Clark153e76d2018-08-28 11:48:28 -04005180#SeeAlso drawText drawPosText drawPosTextH drawTextBlob drawTextRSXform
Cary Clark8032b982017-07-28 11:04:54 -04005181
5182##
5183
5184# ------------------------------------------------------------------------------
5185
5186#Method void drawPosText(const void* text, size_t byteLength, const SkPoint pos[],
5187 const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05005188#In Draw_Text
5189#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05005190#Line # draws text at array of (x, y) positions ##
Cary Clark8032b982017-07-28 11:04:54 -04005191
Cary Clark80247e52018-07-11 16:18:41 -04005192Draws each glyph in text with the origin in pos array, using Clip, Matrix, and
Cary Clarkce101242017-09-01 15:51:02 -04005193Paint paint. The number of entries in pos array must match the number of Glyphs
Cary Clarkbad5ad72017-08-03 17:14:08 -04005194described by byteLength of text.
Cary Clark8032b982017-07-28 11:04:54 -04005195
Cary Clarkbc5697d2017-10-04 14:31:33 -04005196text meaning depends on Paint_Text_Encoding; by default, text is encoded as
Cary Clark5538c132018-06-14 12:28:14 -04005197UTF-8. pos elements meaning depends on Paint_Vertical_Text; by default
5198glyph left side bearing and baseline are relative to Point in pos array.
5199Text size is affected by Matrix and Paint_Text_Size.
Cary Clark8032b982017-07-28 11:04:54 -04005200
Mike Reed8ad91a92018-01-19 19:09:32 -05005201All elements of paint: Path_Effect, Mask_Filter, Shader,
Cary Clarkbad5ad72017-08-03 17:14:08 -04005202Color_Filter, Image_Filter, and Draw_Looper; apply to text. By default, draws
Cary Clarkce101242017-09-01 15:51:02 -04005203filled 12 point black Glyphs.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005204
5205Layout engines such as Harfbuzz typically position each glyph
Cary Clarkbc5697d2017-10-04 14:31:33 -04005206rather than using the font advance widths.
Cary Clark8032b982017-07-28 11:04:54 -04005207
Cary Clarkce101242017-09-01 15:51:02 -04005208#Param text character code points or Glyphs drawn ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005209#Param byteLength byte length of text array ##
5210#Param pos array of glyph origins ##
5211#Param paint text size, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005212
5213#Example
5214#Height 120
Cary Clarkbad5ad72017-08-03 17:14:08 -04005215void draw(SkCanvas* canvas) {
5216 const char hello[] = "HeLLo!";
5217 const SkPoint pos[] = { {40, 100}, {82, 95}, {115, 110}, {130, 95}, {145, 85},
5218 {172, 100} };
5219 SkPaint paint;
5220 paint.setTextSize(60);
5221 canvas->drawPosText(hello, strlen(hello), pos, paint);
Cary Clark8032b982017-07-28 11:04:54 -04005222}
5223##
5224
Cary Clark153e76d2018-08-28 11:48:28 -04005225#SeeAlso drawText drawPosTextH drawTextBlob drawTextRSXform
Cary Clark8032b982017-07-28 11:04:54 -04005226
5227##
5228
5229# ------------------------------------------------------------------------------
5230
5231#Method void drawPosTextH(const void* text, size_t byteLength, const SkScalar xpos[], SkScalar constY,
5232 const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05005233#In Draw_Text
5234#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05005235#Line # draws text at x positions with common baseline ##
Cary Clark8032b982017-07-28 11:04:54 -04005236
Cary Clark80247e52018-07-11 16:18:41 -04005237Draws each glyph in text with its (x, y) origin composed from xpos array and
Cary Clarkbad5ad72017-08-03 17:14:08 -04005238constY, using Clip, Matrix, and Paint paint. The number of entries in xpos array
Cary Clarkce101242017-09-01 15:51:02 -04005239must match the number of Glyphs described by byteLength of text.
Cary Clark8032b982017-07-28 11:04:54 -04005240
Cary Clarkbc5697d2017-10-04 14:31:33 -04005241text meaning depends on Paint_Text_Encoding; by default, text is encoded as
Cary Clark137b8742018-05-30 09:21:49 -04005242UTF-8. xpos elements meaning depends on Paint_Vertical_Text;
Cary Clarkbc5697d2017-10-04 14:31:33 -04005243by default each glyph left side bearing is positioned at an xpos element and
Cary Clarkbad5ad72017-08-03 17:14:08 -04005244its baseline is positioned at constY. Text size is affected by Matrix and
Herb Derbyefe39bc2018-05-01 17:06:20 -04005245Paint_Text_Size.
Cary Clark8032b982017-07-28 11:04:54 -04005246
Mike Reed8ad91a92018-01-19 19:09:32 -05005247All elements of paint: Path_Effect, Mask_Filter, Shader,
Cary Clarkbad5ad72017-08-03 17:14:08 -04005248Color_Filter, Image_Filter, and Draw_Looper; apply to text. By default, draws
Cary Clarkce101242017-09-01 15:51:02 -04005249filled 12 point black Glyphs.
Cary Clark8032b982017-07-28 11:04:54 -04005250
Cary Clarkbad5ad72017-08-03 17:14:08 -04005251Layout engines such as Harfbuzz typically position each glyph
Cary Clarkbc5697d2017-10-04 14:31:33 -04005252rather than using the font advance widths if all Glyphs share the same
Cary Clarkbad5ad72017-08-03 17:14:08 -04005253baseline.
5254
Cary Clarkce101242017-09-01 15:51:02 -04005255#Param text character code points or Glyphs drawn ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005256#Param byteLength byte length of text array ##
Cary Clark5538c132018-06-14 12:28:14 -04005257#Param xpos array of x-axis positions, used to position each glyph ##
5258#Param constY shared y-axis value for all of x-axis positions ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005259#Param paint text size, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005260
5261#Example
5262#Height 40
Cary Clarkbad5ad72017-08-03 17:14:08 -04005263 void draw(SkCanvas* canvas) {
5264 SkScalar xpos[] = { 20, 40, 80, 160 };
5265 SkPaint paint;
5266 canvas->drawPosTextH("XXXX", 4, xpos, 20, paint);
5267 }
Cary Clark8032b982017-07-28 11:04:54 -04005268##
5269
Cary Clark153e76d2018-08-28 11:48:28 -04005270#SeeAlso drawText drawPosText drawTextBlob drawTextRSXform
Cary Clark8032b982017-07-28 11:04:54 -04005271
5272##
5273
5274# ------------------------------------------------------------------------------
5275
Cary Clark8032b982017-07-28 11:04:54 -04005276#Method void drawTextRSXform(const void* text, size_t byteLength, const SkRSXform xform[],
5277 const SkRect* cullRect, const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05005278#In Draw_Text
5279#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05005280#Line # draws text with array of RSXform ##
Cary Clark8032b982017-07-28 11:04:54 -04005281
Cary Clark80247e52018-07-11 16:18:41 -04005282Draws text, transforming each glyph by the corresponding SkRSXform,
Cary Clark8032b982017-07-28 11:04:54 -04005283using Clip, Matrix, and Paint paint.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005284
Cary Clark137b8742018-05-30 09:21:49 -04005285RSXform xform array specifies a separate square scale, rotation, and translation
5286for each glyph. xform does not affect paint Shader.
Cary Clark8032b982017-07-28 11:04:54 -04005287
Cary Clarkbad5ad72017-08-03 17:14:08 -04005288Optional Rect cullRect is a conservative bounds of text, taking into account
Cary Clarkce101242017-09-01 15:51:02 -04005289RSXform and paint. If cullRect is outside of Clip, canvas can skip drawing.
Cary Clark8032b982017-07-28 11:04:54 -04005290
Mike Reed8ad91a92018-01-19 19:09:32 -05005291All elements of paint: Path_Effect, Mask_Filter, Shader,
Cary Clarkbad5ad72017-08-03 17:14:08 -04005292Color_Filter, Image_Filter, and Draw_Looper; apply to text. By default, draws
Cary Clarkce101242017-09-01 15:51:02 -04005293filled 12 point black Glyphs.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005294
Cary Clarkce101242017-09-01 15:51:02 -04005295#Param text character code points or Glyphs drawn ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005296#Param byteLength byte length of text array ##
5297#Param xform RSXform rotates, scales, and translates each glyph individually ##
5298#Param cullRect Rect bounds of text for efficient clipping; or nullptr ##
5299#Param paint text size, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005300
5301#Example
Herb Derbyefe39bc2018-05-01 17:06:20 -04005302void draw(SkCanvas* canvas) {
Cary Clarkbad5ad72017-08-03 17:14:08 -04005303 const int iterations = 26;
5304 SkRSXform transforms[iterations];
5305 char alphabet[iterations];
5306 SkScalar angle = 0;
5307 SkScalar scale = 1;
5308 for (size_t i = 0; i < SK_ARRAY_COUNT(transforms); ++i) {
5309 const SkScalar s = SkScalarSin(angle) * scale;
5310 const SkScalar c = SkScalarCos(angle) * scale;
5311 transforms[i] = SkRSXform::Make(-c, -s, -s * 16, c * 16);
5312 angle += .45;
5313 scale += .2;
5314 alphabet[i] = 'A' + i;
5315 }
5316 SkPaint paint;
5317 paint.setTextAlign(SkPaint::kCenter_Align);
5318 canvas->translate(110, 138);
5319 canvas->drawTextRSXform(alphabet, sizeof(alphabet), transforms, nullptr, paint);
Cary Clark8032b982017-07-28 11:04:54 -04005320}
5321##
5322
Cary Clark153e76d2018-08-28 11:48:28 -04005323#SeeAlso drawText drawPosText drawTextBlob
Cary Clark8032b982017-07-28 11:04:54 -04005324
5325##
5326
5327# ------------------------------------------------------------------------------
5328
5329#Method void drawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y, const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05005330#In Draw_Text
5331#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05005332#Line # draws text with arrays of positions and Paint ##
Cary Clark80247e52018-07-11 16:18:41 -04005333Draws Text_Blob blob at (x, y), using Clip, Matrix, and Paint paint.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005334
Cary Clarkce101242017-09-01 15:51:02 -04005335blob contains Glyphs, their positions, and paint attributes specific to text:
Cary Clarkd2ca79c2018-08-10 13:09:13 -04005336#paint_font_metrics#.
Cary Clark8032b982017-07-28 11:04:54 -04005337
Cary Clark3cd22cc2017-12-01 11:49:58 -05005338Paint_Text_Encoding must be set to SkPaint::kGlyphID_TextEncoding.
5339
Cary Clarkd2ca79c2018-08-10 13:09:13 -04005340Elements of paint: Anti_Alias, Blend_Mode, Color including Color_Alpha,
5341Color_Filter, Paint_Dither, Draw_Looper, Mask_Filter, Path_Effect, Shader, and
5342Paint_Style; apply to blob. If Paint contains SkPaint::kStroke_Style:
5343Paint_Miter_Limit, Paint_Stroke_Cap, Paint_Stroke_Join, and Paint_Stroke_Width;
5344apply to Path created from blob.
Cary Clark8032b982017-07-28 11:04:54 -04005345
Cary Clarkce101242017-09-01 15:51:02 -04005346#Param blob Glyphs, positions, and their paints' text size, typeface, and so on ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005347#Param x horizontal offset applied to blob ##
5348#Param y vertical offset applied to blob ##
5349#Param paint blend, color, stroking, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005350
5351#Example
5352#Height 120
Cary Clarke80cd442018-07-17 13:19:56 -04005353void draw(SkCanvas* canvas) {
5354 SkTextBlobBuilder textBlobBuilder;
5355 const char bunny[] = "/(^x^)\\";
5356 const int len = sizeof(bunny) - 1;
5357 uint16_t glyphs[len];
5358 SkPaint paint;
5359 paint.textToGlyphs(bunny, len, glyphs);
5360 paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
5361 int runs[] = { 3, 1, 3 };
5362 SkPoint textPos = { 20, 100 };
5363 int glyphIndex = 0;
5364 for (auto runLen : runs) {
5365 paint.setTextSize(1 == runLen ? 20 : 50);
5366 const SkTextBlobBuilder::RunBuffer& run =
5367 textBlobBuilder.allocRun(paint, runLen, textPos.fX, textPos.fY);
5368 memcpy(run.glyphs, &glyphs[glyphIndex], sizeof(glyphs[0]) * runLen);
5369 textPos.fX += paint.measureText(&glyphs[glyphIndex], sizeof(glyphs[0]) * runLen, nullptr);
5370 glyphIndex += runLen;
Cary Clark8032b982017-07-28 11:04:54 -04005371 }
Cary Clarke80cd442018-07-17 13:19:56 -04005372 sk_sp<const SkTextBlob> blob = textBlobBuilder.make();
5373 paint.reset();
5374 canvas->drawTextBlob(blob.get(), 0, 0, paint);
5375}
Cary Clark8032b982017-07-28 11:04:54 -04005376##
5377
Cary Clark2ade9972017-11-02 17:49:34 -04005378#SeeAlso drawText drawPosText drawPosTextH
Cary Clark8032b982017-07-28 11:04:54 -04005379
5380##
5381
5382# ------------------------------------------------------------------------------
5383
Herb Derbyefe39bc2018-05-01 17:06:20 -04005384#Method void drawTextBlob(const sk_sp<SkTextBlob>& blob, SkScalar x, SkScalar y, const SkPaint& paint)
Cary Clark8032b982017-07-28 11:04:54 -04005385
Cary Clark80247e52018-07-11 16:18:41 -04005386Draws Text_Blob blob at (x, y), using Clip, Matrix, and Paint paint.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005387
Cary Clarkce101242017-09-01 15:51:02 -04005388blob contains Glyphs, their positions, and paint attributes specific to text:
Cary Clarkd2ca79c2018-08-10 13:09:13 -04005389#paint_font_metrics#.
Cary Clark8032b982017-07-28 11:04:54 -04005390
Cary Clark3cd22cc2017-12-01 11:49:58 -05005391Paint_Text_Encoding must be set to SkPaint::kGlyphID_TextEncoding.
5392
Herb Derbyefe39bc2018-05-01 17:06:20 -04005393Elements of paint: Path_Effect, Mask_Filter, Shader, Color_Filter,
Cary Clark8032b982017-07-28 11:04:54 -04005394Image_Filter, and Draw_Looper; apply to blob.
5395
Cary Clarkce101242017-09-01 15:51:02 -04005396#Param blob Glyphs, positions, and their paints' text size, typeface, and so on ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005397#Param x horizontal offset applied to blob ##
5398#Param y vertical offset applied to blob ##
5399#Param paint blend, color, stroking, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005400
5401#Example
5402#Height 120
5403#Description
5404Paint attributes unrelated to text, like color, have no effect on paint in allocated Text_Blob.
5405Paint attributes related to text, like text size, have no effect on paint passed to drawTextBlob.
5406##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005407 void draw(SkCanvas* canvas) {
5408 SkTextBlobBuilder textBlobBuilder;
5409 SkPaint paint;
5410 paint.setTextSize(50);
5411 paint.setColor(SK_ColorRED);
Cary Clark2f466242017-12-11 16:03:17 -05005412 paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
Herb Derbyefe39bc2018-05-01 17:06:20 -04005413 const SkTextBlobBuilder::RunBuffer& run =
Cary Clarkbad5ad72017-08-03 17:14:08 -04005414 textBlobBuilder.allocRun(paint, 1, 20, 100);
5415 run.glyphs[0] = 20;
5416 sk_sp<const SkTextBlob> blob = textBlobBuilder.make();
5417 paint.setTextSize(10);
5418 paint.setColor(SK_ColorBLUE);
5419 canvas->drawTextBlob(blob.get(), 0, 0, paint);
5420 }
Cary Clark8032b982017-07-28 11:04:54 -04005421##
5422
Cary Clark2ade9972017-11-02 17:49:34 -04005423#SeeAlso drawText drawPosText drawPosTextH
Cary Clark8032b982017-07-28 11:04:54 -04005424
5425##
5426
5427# ------------------------------------------------------------------------------
5428
Herb Derbyefe39bc2018-05-01 17:06:20 -04005429#Method void drawPicture(const SkPicture* picture)
Cary Clark78de7512018-02-07 07:27:09 -05005430#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05005431#Line # draws Picture using Clip and Matrix ##
Cary Clark80247e52018-07-11 16:18:41 -04005432Draws Picture picture, using Clip and Matrix.
Cary Clark8032b982017-07-28 11:04:54 -04005433Clip and Matrix are unchanged by picture contents, as if
5434save() was called before and restore() was called after drawPicture.
5435
5436Picture records a series of draw commands for later playback.
5437
Cary Clarkbad5ad72017-08-03 17:14:08 -04005438#Param picture recorded drawing commands to play ##
Cary Clark8032b982017-07-28 11:04:54 -04005439
5440#Example
Herb Derbyefe39bc2018-05-01 17:06:20 -04005441void draw(SkCanvas* canvas) {
Cary Clarkbad5ad72017-08-03 17:14:08 -04005442 SkPictureRecorder recorder;
5443 SkCanvas* recordingCanvas = recorder.beginRecording(50, 50);
5444 for (auto color : { SK_ColorRED, SK_ColorBLUE, 0xff007f00 } ) {
5445 SkPaint paint;
5446 paint.setColor(color);
5447 recordingCanvas->drawRect({10, 10, 30, 40}, paint);
5448 recordingCanvas->translate(10, 10);
5449 recordingCanvas->scale(1.2f, 1.4f);
5450 }
5451 sk_sp<SkPicture> playback = recorder.finishRecordingAsPicture();
Cary Clarkbad5ad72017-08-03 17:14:08 -04005452 canvas->drawPicture(playback);
5453 canvas->scale(2, 2);
5454 canvas->translate(50, 0);
5455 canvas->drawPicture(playback);
Cary Clark8032b982017-07-28 11:04:54 -04005456}
5457##
5458
Cary Clark2ade9972017-11-02 17:49:34 -04005459#SeeAlso drawDrawable SkPicture SkPicture::playback
Cary Clark8032b982017-07-28 11:04:54 -04005460
5461##
5462
5463# ------------------------------------------------------------------------------
5464
Herb Derbyefe39bc2018-05-01 17:06:20 -04005465#Method void drawPicture(const sk_sp<SkPicture>& picture)
Cary Clark8032b982017-07-28 11:04:54 -04005466
Cary Clark80247e52018-07-11 16:18:41 -04005467Draws Picture picture, using Clip and Matrix.
Cary Clark8032b982017-07-28 11:04:54 -04005468Clip and Matrix are unchanged by picture contents, as if
5469save() was called before and restore() was called after drawPicture.
5470
5471Picture records a series of draw commands for later playback.
5472
Cary Clarkbad5ad72017-08-03 17:14:08 -04005473#Param picture recorded drawing commands to play ##
Cary Clark8032b982017-07-28 11:04:54 -04005474
5475#Example
Herb Derbyefe39bc2018-05-01 17:06:20 -04005476void draw(SkCanvas* canvas) {
Cary Clarkbad5ad72017-08-03 17:14:08 -04005477 SkPictureRecorder recorder;
5478 SkCanvas* recordingCanvas = recorder.beginRecording(50, 50);
5479 for (auto color : { SK_ColorRED, SK_ColorBLUE, 0xff007f00 } ) {
5480 SkPaint paint;
5481 paint.setColor(color);
5482 recordingCanvas->drawRect({10, 10, 30, 40}, paint);
5483 recordingCanvas->translate(10, 10);
5484 recordingCanvas->scale(1.2f, 1.4f);
5485 }
5486 sk_sp<SkPicture> playback = recorder.finishRecordingAsPicture();
5487 canvas->drawPicture(playback);
5488 canvas->scale(2, 2);
5489 canvas->translate(50, 0);
5490 canvas->drawPicture(playback);
Cary Clark8032b982017-07-28 11:04:54 -04005491}
5492##
5493
Cary Clark2ade9972017-11-02 17:49:34 -04005494#SeeAlso drawDrawable SkPicture SkPicture::playback
Cary Clark8032b982017-07-28 11:04:54 -04005495
5496##
5497
5498# ------------------------------------------------------------------------------
5499
5500#Method void drawPicture(const SkPicture* picture, const SkMatrix* matrix, const SkPaint* paint)
5501
Cary Clark80247e52018-07-11 16:18:41 -04005502Draws Picture picture, using Clip and Matrix; transforming picture with
Cary Clarkbad5ad72017-08-03 17:14:08 -04005503Matrix matrix, if provided; and use Paint paint Color_Alpha, Color_Filter,
5504Image_Filter, and Blend_Mode, if provided.
Cary Clark8032b982017-07-28 11:04:54 -04005505
5506matrix transformation is equivalent to: save(), concat(), drawPicture, restore().
5507paint use is equivalent to: saveLayer, drawPicture, restore().
5508
Cary Clarkbad5ad72017-08-03 17:14:08 -04005509#Param picture recorded drawing commands to play ##
5510#Param matrix Matrix to rotate, scale, translate, and so on; may be nullptr ##
5511#Param paint Paint to apply transparency, filtering, and so on; may be nullptr ##
Cary Clark8032b982017-07-28 11:04:54 -04005512
5513#Example
Herb Derbyefe39bc2018-05-01 17:06:20 -04005514void draw(SkCanvas* canvas) {
Cary Clarkbad5ad72017-08-03 17:14:08 -04005515 SkPaint paint;
5516 SkPictureRecorder recorder;
5517 SkCanvas* recordingCanvas = recorder.beginRecording(50, 50);
5518 for (auto color : { SK_ColorRED, SK_ColorBLUE, 0xff007f00 } ) {
5519 paint.setColor(color);
5520 recordingCanvas->drawRect({10, 10, 30, 40}, paint);
5521 recordingCanvas->translate(10, 10);
5522 recordingCanvas->scale(1.2f, 1.4f);
5523 }
5524 sk_sp<SkPicture> playback = recorder.finishRecordingAsPicture();
5525 const SkPicture* playbackPtr = playback.get();
5526 SkMatrix matrix;
5527 matrix.reset();
5528 for (auto alpha : { 70, 140, 210 } ) {
5529 paint.setAlpha(alpha);
5530 canvas->drawPicture(playbackPtr, &matrix, &paint);
5531 matrix.preTranslate(70, 70);
5532 }
Cary Clark8032b982017-07-28 11:04:54 -04005533}
5534##
5535
Cary Clark2ade9972017-11-02 17:49:34 -04005536#SeeAlso drawDrawable SkPicture SkPicture::playback
Cary Clark8032b982017-07-28 11:04:54 -04005537
5538##
5539
5540# ------------------------------------------------------------------------------
5541
Herb Derbyefe39bc2018-05-01 17:06:20 -04005542#Method void drawPicture(const sk_sp<SkPicture>& picture, const SkMatrix* matrix, const SkPaint* paint)
Cary Clark8032b982017-07-28 11:04:54 -04005543
Cary Clark80247e52018-07-11 16:18:41 -04005544Draws Picture picture, using Clip and Matrix; transforming picture with
Cary Clarkbad5ad72017-08-03 17:14:08 -04005545Matrix matrix, if provided; and use Paint paint Color_Alpha, Color_Filter,
5546Image_Filter, and Blend_Mode, if provided.
Cary Clark8032b982017-07-28 11:04:54 -04005547
5548matrix transformation is equivalent to: save(), concat(), drawPicture, restore().
5549paint use is equivalent to: saveLayer, drawPicture, restore().
5550
Cary Clarkbad5ad72017-08-03 17:14:08 -04005551#Param picture recorded drawing commands to play ##
5552#Param matrix Matrix to rotate, scale, translate, and so on; may be nullptr ##
5553#Param paint Paint to apply transparency, filtering, and so on; may be nullptr ##
Cary Clark8032b982017-07-28 11:04:54 -04005554
5555#Example
Herb Derbyefe39bc2018-05-01 17:06:20 -04005556void draw(SkCanvas* canvas) {
Cary Clarkbad5ad72017-08-03 17:14:08 -04005557 SkPaint paint;
5558 SkPictureRecorder recorder;
5559 SkCanvas* recordingCanvas = recorder.beginRecording(50, 50);
5560 for (auto color : { SK_ColorRED, SK_ColorBLUE, 0xff007f00 } ) {
5561 paint.setColor(color);
5562 recordingCanvas->drawRect({10, 10, 30, 40}, paint);
5563 recordingCanvas->translate(10, 10);
5564 recordingCanvas->scale(1.2f, 1.4f);
5565 }
5566 sk_sp<SkPicture> playback = recorder.finishRecordingAsPicture();
5567 SkMatrix matrix;
5568 matrix.reset();
5569 for (auto alpha : { 70, 140, 210 } ) {
5570 paint.setAlpha(alpha);
5571 canvas->drawPicture(playback, &matrix, &paint);
5572 matrix.preTranslate(70, 70);
5573 }
Cary Clark8032b982017-07-28 11:04:54 -04005574}
5575##
5576
Cary Clark2ade9972017-11-02 17:49:34 -04005577#SeeAlso drawDrawable SkPicture SkPicture::playback
Cary Clark8032b982017-07-28 11:04:54 -04005578
5579##
5580
5581# ------------------------------------------------------------------------------
5582
5583#Method void drawVertices(const SkVertices* vertices, SkBlendMode mode, const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05005584#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05005585#Line # draws Vertices, a triangle mesh ##
Cary Clark80247e52018-07-11 16:18:41 -04005586Draws Vertices vertices, a triangle mesh, using Clip and Matrix.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005587If Vertices_Texs and Vertices_Colors are defined in vertices, and Paint paint
5588contains Shader, Blend_Mode mode combines Vertices_Colors with Shader.
Cary Clark8032b982017-07-28 11:04:54 -04005589
Cary Clarkbad5ad72017-08-03 17:14:08 -04005590#Param vertices triangle mesh to draw ##
5591#Param mode combines Vertices_Colors with Shader, if both are present ##
5592#Param paint specifies the Shader, used as Vertices texture; may be nullptr ##
Cary Clark8032b982017-07-28 11:04:54 -04005593
5594#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04005595void draw(SkCanvas* canvas) {
5596 SkPaint paint;
5597 SkPoint points[] = { { 0, 0 }, { 250, 0 }, { 100, 100 }, { 0, 250 } };
5598 SkColor colors[] = { SK_ColorRED, SK_ColorBLUE, SK_ColorYELLOW, SK_ColorCYAN };
5599 auto vertices = SkVertices::MakeCopy(SkVertices::kTriangleFan_VertexMode,
5600 SK_ARRAY_COUNT(points), points, nullptr, colors);
5601 canvas->drawVertices(vertices.get(), SkBlendMode::kSrc, paint);
5602}
Cary Clark8032b982017-07-28 11:04:54 -04005603##
5604
Cary Clark2ade9972017-11-02 17:49:34 -04005605#SeeAlso drawPatch drawPicture
Cary Clark8032b982017-07-28 11:04:54 -04005606
5607##
5608
5609# ------------------------------------------------------------------------------
5610
5611#Method void drawVertices(const sk_sp<SkVertices>& vertices, SkBlendMode mode, const SkPaint& paint)
5612
Cary Clark80247e52018-07-11 16:18:41 -04005613Draws Vertices vertices, a triangle mesh, using Clip and Matrix.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005614If Vertices_Texs and Vertices_Colors are defined in vertices, and Paint paint
5615contains Shader, Blend_Mode mode combines Vertices_Colors with Shader.
Cary Clark8032b982017-07-28 11:04:54 -04005616
Cary Clarkbad5ad72017-08-03 17:14:08 -04005617#Param vertices triangle mesh to draw ##
5618#Param mode combines Vertices_Colors with Shader, if both are present ##
5619#Param paint specifies the Shader, used as Vertices texture, may be nullptr ##
Cary Clark8032b982017-07-28 11:04:54 -04005620
5621#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04005622void draw(SkCanvas* canvas) {
5623 SkPaint paint;
5624 SkPoint points[] = { { 0, 0 }, { 250, 0 }, { 100, 100 }, { 0, 250 } };
5625 SkPoint texs[] = { { 0, 0 }, { 0, 250 }, { 250, 250 }, { 250, 0 } };
5626 SkColor colors[] = { SK_ColorRED, SK_ColorBLUE, SK_ColorYELLOW, SK_ColorCYAN };
5627 paint.setShader(SkGradientShader::MakeLinear(points, colors, nullptr, 4,
5628 SkShader::kClamp_TileMode));
5629 auto vertices = SkVertices::MakeCopy(SkVertices::kTriangleFan_VertexMode,
5630 SK_ARRAY_COUNT(points), points, texs, colors);
Ruiqi Mao94d57c42018-07-02 15:20:10 -04005631 canvas->drawVertices(vertices, SkBlendMode::kDarken, paint);
5632}
5633##
5634
5635#SeeAlso drawPatch drawPicture
5636
5637##
5638
5639# ------------------------------------------------------------------------------
5640
Ruiqi Maoc97a3392018-08-15 10:44:19 -04005641#Method void drawVertices(const SkVertices* vertices, const SkVertices::Bone bones[],
5642 int boneCount, SkBlendMode mode, const SkPaint& paint)
Ruiqi Mao94d57c42018-07-02 15:20:10 -04005643
Cary Clark80247e52018-07-11 16:18:41 -04005644Draws Vertices vertices, a triangle mesh, using Clip and Matrix. Bone data is used to
Ruiqi Mao94d57c42018-07-02 15:20:10 -04005645deform vertices with bone weights.
5646If Vertices_Texs and Vertices_Colors are defined in vertices, and Paint paint
5647contains Shader, Blend_Mode mode combines Vertices_Colors with Shader.
5648The first element of bones should be an object to world space transformation matrix that
5649will be applied before performing mesh deformations. If no such transformation is needed,
5650it should be the identity matrix.
Ruiqi Maoc97a3392018-08-15 10:44:19 -04005651boneCount must be at most 80, and thus the size of bones should be at most 80.
Ruiqi Mao94d57c42018-07-02 15:20:10 -04005652
5653#Param vertices triangle mesh to draw ##
5654#Param bones bone matrix data ##
5655#Param boneCount number of bone matrices ##
5656#Param mode combines Vertices_Colors with Shader, if both are present ##
5657#Param paint specifies the Shader, used as Vertices texture, may be nullptr ##
5658
Ruiqi Maoc97a3392018-08-15 10:44:19 -04005659#NoExample
Ruiqi Mao94d57c42018-07-02 15:20:10 -04005660void draw(SkCanvas* canvas) {
5661 SkPaint paint;
5662 SkPoint points[] = { { 0, 0 }, { 250, 0 }, { 100, 100 }, { 0, 250 } };
5663 SkPoint texs[] = { { 0, 0 }, { 0, 250 }, { 250, 250 }, { 250, 0 } };
5664 SkColor colors[] = { SK_ColorRED, SK_ColorBLUE, SK_ColorYELLOW, SK_ColorCYAN };
5665 SkVertices::BoneIndices boneIndices[] = { { 0, 0, 0, 0 },
5666 { 1, 0, 0, 0 },
5667 { 2, 0, 0, 0 },
5668 { 3, 0, 0, 0 } };
5669 SkVertices::BoneWeights boneWeights[] = { { 0.0f, 0.0f, 0.0f, 0.0f },
5670 { 1.0f, 0.0f, 0.0f, 0.0f },
5671 { 1.0f, 0.0f, 0.0f, 0.0f },
5672 { 1.0f, 0.0f, 0.0f, 0.0f } };
Ruiqi Maoc97a3392018-08-15 10:44:19 -04005673 SkVertices::Bone bones[] = { {{ 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f }},
5674 {{ 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 20.0f }},
5675 {{ 1.0f, 0.0f, 0.0f, 1.0f, 50.0f, 50.0f }},
5676 {{ 1.0f, 0.0f, 0.0f, 1.0f, 20.0f, 0.0f }} };
Ruiqi Mao94d57c42018-07-02 15:20:10 -04005677 paint.setShader(SkGradientShader::MakeLinear(points, colors, nullptr, 4,
5678 SkShader::kClamp_TileMode));
5679 auto vertices = SkVertices::MakeCopy(SkVertices::kTriangleFan_VertexMode,
5680 SK_ARRAY_COUNT(points), points, texs, colors, boneIndices, boneWeights);
5681 canvas->drawVertices(vertices.get(), bones, SK_ARRAY_COUNT(bones), SkBlendMode::kDarken, paint);
5682}
5683##
5684
5685#SeeAlso drawPatch drawPicture
5686
5687##
5688
5689# ------------------------------------------------------------------------------
5690
Ruiqi Maoc97a3392018-08-15 10:44:19 -04005691#Method void drawVertices(const sk_sp<SkVertices>& vertices, const SkVertices::Bone bones[],
5692 int boneCount, SkBlendMode mode, const SkPaint& paint)
Ruiqi Mao94d57c42018-07-02 15:20:10 -04005693
Cary Clark80247e52018-07-11 16:18:41 -04005694Draws Vertices vertices, a triangle mesh, using Clip and Matrix. Bone data is used to
Ruiqi Mao94d57c42018-07-02 15:20:10 -04005695deform vertices with bone weights.
5696If Vertices_Texs and Vertices_Colors are defined in vertices, and Paint paint
5697contains Shader, Blend_Mode mode combines Vertices_Colors with Shader.
5698The first element of bones should be an object to world space transformation matrix that
5699will be applied before performing mesh deformations. If no such transformation is needed,
5700it should be the identity matrix.
Ruiqi Maoc97a3392018-08-15 10:44:19 -04005701boneCount must be at most 80, and thus the size of bones should be at most 80.
Ruiqi Mao94d57c42018-07-02 15:20:10 -04005702
5703#Param vertices triangle mesh to draw ##
5704#Param bones bone matrix data ##
5705#Param boneCount number of bone matrices ##
5706#Param mode combines Vertices_Colors with Shader, if both are present ##
5707#Param paint specifies the Shader, used as Vertices texture, may be nullptr ##
5708
Ruiqi Maoc97a3392018-08-15 10:44:19 -04005709#NoExample
Ruiqi Mao94d57c42018-07-02 15:20:10 -04005710void draw(SkCanvas* canvas) {
5711 SkPaint paint;
5712 SkPoint points[] = { { 0, 0 }, { 250, 0 }, { 100, 100 }, { 0, 250 } };
5713 SkPoint texs[] = { { 0, 0 }, { 0, 250 }, { 250, 250 }, { 250, 0 } };
5714 SkColor colors[] = { SK_ColorRED, SK_ColorBLUE, SK_ColorYELLOW, SK_ColorCYAN };
5715 SkVertices::BoneIndices boneIndices[] = { { 0, 0, 0, 0 },
5716 { 1, 0, 0, 0 },
5717 { 2, 0, 0, 0 },
5718 { 3, 0, 0, 0 } };
5719 SkVertices::BoneWeights boneWeights[] = { { 0.0f, 0.0f, 0.0f, 0.0f },
5720 { 1.0f, 0.0f, 0.0f, 0.0f },
5721 { 1.0f, 0.0f, 0.0f, 0.0f },
5722 { 1.0f, 0.0f, 0.0f, 0.0f } };
Ruiqi Maoc97a3392018-08-15 10:44:19 -04005723 SkVertices::Bone bones[] = { {{ 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f }},
5724 {{ 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 20.0f }},
5725 {{ 1.0f, 0.0f, 0.0f, 1.0f, 50.0f, 50.0f }},
5726 {{ 1.0f, 0.0f, 0.0f, 1.0f, 20.0f, 0.0f }} };
Ruiqi Mao94d57c42018-07-02 15:20:10 -04005727 paint.setShader(SkGradientShader::MakeLinear(points, colors, nullptr, 4,
5728 SkShader::kClamp_TileMode));
5729 auto vertices = SkVertices::MakeCopy(SkVertices::kTriangleFan_VertexMode,
5730 SK_ARRAY_COUNT(points), points, texs, colors, boneIndices, boneWeights);
5731 canvas->drawVertices(vertices, bones, SK_ARRAY_COUNT(bones), SkBlendMode::kDarken, paint);
Cary Clark8032b982017-07-28 11:04:54 -04005732}
5733##
5734
Cary Clark2ade9972017-11-02 17:49:34 -04005735#SeeAlso drawPatch drawPicture
Cary Clark8032b982017-07-28 11:04:54 -04005736
5737##
5738
5739# ------------------------------------------------------------------------------
5740
5741#Method void drawPatch(const SkPoint cubics[12], const SkColor colors[4],
5742 const SkPoint texCoords[4], SkBlendMode mode, const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05005743#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05005744#Line # draws Coons_Patch ##
Cary Clark8032b982017-07-28 11:04:54 -04005745
Herb Derbyefe39bc2018-05-01 17:06:20 -04005746Draws a Coons_Patch: the interpolation of four cubics with shared corners,
Cary Clark5538c132018-06-14 12:28:14 -04005747associating a color, and optionally a texture Point, with each corner.
Cary Clark8032b982017-07-28 11:04:54 -04005748
Cary Clarka560c472017-11-27 10:44:06 -05005749Coons_Patch uses Clip and Matrix, paint Shader, Color_Filter,
Cary Clarkbad5ad72017-08-03 17:14:08 -04005750Color_Alpha, Image_Filter, and Blend_Mode. If Shader is provided it is treated
Cary Clarka560c472017-11-27 10:44:06 -05005751as Coons_Patch texture; Blend_Mode mode combines Color colors and Shader if
Cary Clarkbad5ad72017-08-03 17:14:08 -04005752both are provided.
Cary Clark8032b982017-07-28 11:04:54 -04005753
Herb Derbyefe39bc2018-05-01 17:06:20 -04005754Point array cubics specifies four Cubics starting at the top-left corner,
Cary Clarkce101242017-09-01 15:51:02 -04005755in clockwise order, sharing every fourth point. The last Cubic ends at the
Cary Clarkbad5ad72017-08-03 17:14:08 -04005756first point.
Cary Clark8032b982017-07-28 11:04:54 -04005757
Cary Clarkbc5697d2017-10-04 14:31:33 -04005758Color array color associates colors with corners in top-left, top-right,
5759bottom-right, bottom-left order.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005760
5761If paint contains Shader, Point array texCoords maps Shader as texture to
Cary Clarkbc5697d2017-10-04 14:31:33 -04005762corners in top-left, top-right, bottom-right, bottom-left order.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005763
Cary Clarka523d2d2017-08-30 08:58:10 -04005764#Param cubics Path_Cubic array, sharing common points ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005765#Param colors Color array, one for each corner ##
Cary Clarkce101242017-09-01 15:51:02 -04005766#Param texCoords Point array of texture coordinates, mapping Shader to corners;
Herb Derbyefe39bc2018-05-01 17:06:20 -04005767 may be nullptr
Cary Clark579985c2017-07-31 11:48:27 -04005768#Param ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005769#Param mode Blend_Mode for colors, and for Shader if paint has one ##
5770#Param paint Shader, Color_Filter, Blend_Mode, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005771
5772#Example
5773#Image 5
Cary Clarkbad5ad72017-08-03 17:14:08 -04005774void draw(SkCanvas* canvas) {
5775 // SkBitmap source = cmbkygk;
5776 SkPaint paint;
5777 paint.setFilterQuality(kLow_SkFilterQuality);
5778 paint.setAntiAlias(true);
5779 SkPoint cubics[] = { { 3, 1 }, { 4, 2 }, { 5, 1 }, { 7, 3 },
5780 /* { 7, 3 }, */ { 6, 4 }, { 7, 5 }, { 5, 7 },
5781 /* { 5, 7 }, */ { 4, 6 }, { 3, 7 }, { 1, 5 },
5782 /* { 1, 5 }, */ { 2, 4 }, { 1, 3 }, /* { 3, 1 } */ };
5783 SkColor colors[] = { 0xbfff0000, 0xbf0000ff, 0xbfff00ff, 0xbf00ffff };
5784 SkPoint texCoords[] = { { -30, -30 }, { 162, -30}, { 162, 162}, { -30, 162} };
5785 paint.setShader(SkShader::MakeBitmapShader(source, SkShader::kClamp_TileMode,
5786 SkShader::kClamp_TileMode, nullptr));
5787 canvas->scale(15, 15);
5788 for (auto blend : { SkBlendMode::kSrcOver, SkBlendMode::kModulate, SkBlendMode::kXor } ) {
5789 canvas->drawPatch(cubics, colors, texCoords, blend, paint);
5790 canvas->translate(4, 4);
5791 }
Cary Clark8032b982017-07-28 11:04:54 -04005792}
5793##
5794
Cary Clark2ade9972017-11-02 17:49:34 -04005795#ToDo can patch use image filter? ##
5796#SeeAlso SeeAlso drawVertices drawPicture
Cary Clark8032b982017-07-28 11:04:54 -04005797
5798##
5799
5800# ------------------------------------------------------------------------------
5801
5802#Method void drawPatch(const SkPoint cubics[12], const SkColor colors[4],
Herb Derbyefe39bc2018-05-01 17:06:20 -04005803 const SkPoint texCoords[4], const SkPaint& paint)
Cary Clark8032b982017-07-28 11:04:54 -04005804
Herb Derbyefe39bc2018-05-01 17:06:20 -04005805Draws Cubic Coons_Patch: the interpolation of four cubics with shared corners,
Cary Clark5538c132018-06-14 12:28:14 -04005806associating a color, and optionally a texture Point, with each corner.
Cary Clark8032b982017-07-28 11:04:54 -04005807
Cary Clarka560c472017-11-27 10:44:06 -05005808Coons_Patch uses Clip and Matrix, paint Shader, Color_Filter,
Cary Clarkbad5ad72017-08-03 17:14:08 -04005809Color_Alpha, Image_Filter, and Blend_Mode. If Shader is provided it is treated
Cary Clarka560c472017-11-27 10:44:06 -05005810as Coons_Patch texture; Blend_Mode mode combines Color colors and Shader if
Cary Clarkbad5ad72017-08-03 17:14:08 -04005811both are provided.
Cary Clark8032b982017-07-28 11:04:54 -04005812
Herb Derbyefe39bc2018-05-01 17:06:20 -04005813Point array cubics specifies four Cubics starting at the top-left corner,
Cary Clarkce101242017-09-01 15:51:02 -04005814in clockwise order, sharing every fourth point. The last Cubic ends at the
Cary Clarkbad5ad72017-08-03 17:14:08 -04005815first point.
5816
Cary Clarkbc5697d2017-10-04 14:31:33 -04005817Color array color associates colors with corners in top-left, top-right,
5818bottom-right, bottom-left order.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005819
5820If paint contains Shader, Point array texCoords maps Shader as texture to
Cary Clarkbc5697d2017-10-04 14:31:33 -04005821corners in top-left, top-right, bottom-right, bottom-left order.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005822
Cary Clarka523d2d2017-08-30 08:58:10 -04005823#Param cubics Path_Cubic array, sharing common points ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005824#Param colors Color array, one for each corner ##
Cary Clarkce101242017-09-01 15:51:02 -04005825#Param texCoords Point array of texture coordinates, mapping Shader to corners;
Herb Derbyefe39bc2018-05-01 17:06:20 -04005826 may be nullptr
Cary Clark579985c2017-07-31 11:48:27 -04005827#Param ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005828#Param paint Shader, Color_Filter, Blend_Mode, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005829
5830#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04005831void draw(SkCanvas* canvas) {
5832 SkPaint paint;
5833 paint.setAntiAlias(true);
5834 SkPoint cubics[] = { { 3, 1 }, { 4, 2 }, { 5, 1 }, { 7, 3 },
5835 /* { 7, 3 }, */ { 6, 4 }, { 7, 5 }, { 5, 7 },
5836 /* { 5, 7 }, */ { 4, 6 }, { 3, 7 }, { 1, 5 },
5837 /* { 1, 5 }, */ { 2, 4 }, { 1, 3 }, /* { 3, 1 } */ };
5838 SkColor colors[] = { SK_ColorRED, SK_ColorBLUE, SK_ColorYELLOW, SK_ColorCYAN };
5839 canvas->scale(30, 30);
5840 canvas->drawPatch(cubics, colors, nullptr, paint);
5841 SkPoint text[] = { {3,0.9f}, {4,2.5f}, {5,0.9f}, {7.5f,3.2f}, {5.5f,4.2f},
5842 {7.5f,5.2f}, {5,7.5f}, {4,5.9f}, {3,7.5f}, {0.5f,5.2f}, {2.5f,4.2f},
5843 {0.5f,3.2f} };
5844 paint.setTextSize(18.f / 30);
5845 paint.setTextAlign(SkPaint::kCenter_Align);
5846 for (int i = 0; i< 10; ++i) {
5847 char digit = '0' + i;
5848 canvas->drawText(&digit, 1, text[i].fX, text[i].fY, paint);
5849 }
5850 canvas->drawString("10", text[10].fX, text[10].fY, paint);
5851 canvas->drawString("11", text[11].fX, text[11].fY, paint);
5852 paint.setStyle(SkPaint::kStroke_Style);
5853 canvas->drawPoints(SkCanvas::kPolygon_PointMode, 12, cubics, paint);
5854 canvas->drawLine(cubics[11].fX, cubics[11].fY, cubics[0].fX, cubics[0].fY, paint);
Cary Clark8032b982017-07-28 11:04:54 -04005855}
5856##
5857
5858#Example
5859#Image 6
Cary Clarkbad5ad72017-08-03 17:14:08 -04005860void draw(SkCanvas* canvas) {
5861 // SkBitmap source = checkerboard;
5862 SkPaint paint;
5863 paint.setFilterQuality(kLow_SkFilterQuality);
5864 paint.setAntiAlias(true);
5865 SkPoint cubics[] = { { 3, 1 }, { 4, 2 }, { 5, 1 }, { 7, 3 },
5866 /* { 7, 3 }, */ { 6, 4 }, { 7, 5 }, { 5, 7 },
5867 /* { 5, 7 }, */ { 4, 6 }, { 3, 7 }, { 1, 5 },
5868 /* { 1, 5 }, */ { 2, 4 }, { 1, 3 }, /* { 3, 1 } */ };
5869 SkPoint texCoords[] = { { 0, 0 }, { 0, 62}, { 62, 62}, { 62, 0 } };
5870 paint.setShader(SkShader::MakeBitmapShader(source, SkShader::kClamp_TileMode,
5871 SkShader::kClamp_TileMode, nullptr));
5872 canvas->scale(30, 30);
5873 canvas->drawPatch(cubics, nullptr, texCoords, paint);
Cary Clark8032b982017-07-28 11:04:54 -04005874}
5875##
5876
Cary Clark2ade9972017-11-02 17:49:34 -04005877#ToDo can patch use image filter? ##
5878#SeeAlso SeeAlso drawVertices drawPicture
Cary Clark8032b982017-07-28 11:04:54 -04005879
5880##
5881
5882# ------------------------------------------------------------------------------
5883
5884#Method void drawAtlas(const SkImage* atlas, const SkRSXform xform[], const SkRect tex[],
5885 const SkColor colors[], int count, SkBlendMode mode, const SkRect* cullRect,
5886 const SkPaint* paint)
Cary Clark78de7512018-02-07 07:27:09 -05005887#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05005888#Line # draws sprites using Clip, Matrix, and Paint ##
Cary Clark8032b982017-07-28 11:04:54 -04005889
Cary Clark80247e52018-07-11 16:18:41 -04005890Draws a set of sprites from atlas, using Clip, Matrix, and optional Paint paint.
Cary Clarkffb3d682018-05-17 12:17:28 -04005891paint uses Anti_Alias, Color_Alpha, Color_Filter, Image_Filter, and Blend_Mode
Cary Clarkbad5ad72017-08-03 17:14:08 -04005892to draw, if present. For each entry in the array, Rect tex locates sprite in
5893atlas, and RSXform xform transforms it into destination space.
5894
Cary Clark8032b982017-07-28 11:04:54 -04005895xform, text, and colors if present, must contain count entries.
Cary Clark224c7002018-06-27 11:00:21 -04005896Optional colors are applied for each sprite using Blend_Mode mode, treating
5897sprite as source and colors as destination.
Herb Derbyefe39bc2018-05-01 17:06:20 -04005898Optional cullRect is a conservative bounds of all transformed sprites.
Cary Clarkce101242017-09-01 15:51:02 -04005899If cullRect is outside of Clip, canvas can skip drawing.
Cary Clark8032b982017-07-28 11:04:54 -04005900
Cary Clark224c7002018-06-27 11:00:21 -04005901
5902
Cary Clarkbad5ad72017-08-03 17:14:08 -04005903#Param atlas Image containing sprites ##
5904#Param xform RSXform mappings for sprites in atlas ##
5905#Param tex Rect locations of sprites in atlas ##
Cary Clark6fc50412017-09-21 12:31:06 -04005906#Param colors one per sprite, blended with sprite using Blend_Mode; may be nullptr ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005907#Param count number of sprites to draw ##
5908#Param mode Blend_Mode combining colors and sprites ##
Cary Clark6fc50412017-09-21 12:31:06 -04005909#Param cullRect bounds of transformed sprites for efficient clipping; may be nullptr ##
5910#Param paint Color_Filter, Image_Filter, Blend_Mode, and so on; may be nullptr ##
Cary Clark8032b982017-07-28 11:04:54 -04005911
5912#Example
5913#Image 3
Cary Clarkbad5ad72017-08-03 17:14:08 -04005914void draw(SkCanvas* canvas) {
5915 // SkBitmap source = mandrill;
5916 SkRSXform xforms[] = { { .5f, 0, 0, 0 }, {0, .5f, 200, 100 } };
5917 SkRect tex[] = { { 0, 0, 250, 250 }, { 0, 0, 250, 250 } };
5918 SkColor colors[] = { 0x7f55aa00, 0x7f3333bf };
5919 const SkImage* imagePtr = image.get();
5920 canvas->drawAtlas(imagePtr, xforms, tex, colors, 2, SkBlendMode::kSrcOver, nullptr, nullptr);
Cary Clark8032b982017-07-28 11:04:54 -04005921}
5922##
5923
Cary Clark2ade9972017-11-02 17:49:34 -04005924#SeeAlso drawBitmap drawImage
Cary Clark8032b982017-07-28 11:04:54 -04005925
5926##
5927
5928# ------------------------------------------------------------------------------
5929
5930#Method void drawAtlas(const sk_sp<SkImage>& atlas, const SkRSXform xform[], const SkRect tex[],
5931 const SkColor colors[], int count, SkBlendMode mode, const SkRect* cullRect,
Herb Derbyefe39bc2018-05-01 17:06:20 -04005932 const SkPaint* paint)
Cary Clark8032b982017-07-28 11:04:54 -04005933
Cary Clark80247e52018-07-11 16:18:41 -04005934Draws a set of sprites from atlas, using Clip, Matrix, and optional Paint paint.
Cary Clarkffb3d682018-05-17 12:17:28 -04005935paint uses Anti_Alias, Color_Alpha, Color_Filter, Image_Filter, and Blend_Mode
Cary Clarkbad5ad72017-08-03 17:14:08 -04005936to draw, if present. For each entry in the array, Rect tex locates sprite in
5937atlas, and RSXform xform transforms it into destination space.
5938
Cary Clark8032b982017-07-28 11:04:54 -04005939xform, text, and colors if present, must contain count entries.
5940Optional colors is applied for each sprite using Blend_Mode.
Herb Derbyefe39bc2018-05-01 17:06:20 -04005941Optional cullRect is a conservative bounds of all transformed sprites.
Cary Clarkce101242017-09-01 15:51:02 -04005942If cullRect is outside of Clip, canvas can skip drawing.
Cary Clark8032b982017-07-28 11:04:54 -04005943
Cary Clarkbad5ad72017-08-03 17:14:08 -04005944#Param atlas Image containing sprites ##
5945#Param xform RSXform mappings for sprites in atlas ##
5946#Param tex Rect locations of sprites in atlas ##
Cary Clark6fc50412017-09-21 12:31:06 -04005947#Param colors one per sprite, blended with sprite using Blend_Mode; may be nullptr ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005948#Param count number of sprites to draw ##
5949#Param mode Blend_Mode combining colors and sprites ##
Cary Clark6fc50412017-09-21 12:31:06 -04005950#Param cullRect bounds of transformed sprites for efficient clipping; may be nullptr ##
5951#Param paint Color_Filter, Image_Filter, Blend_Mode, and so on; may be nullptr ##
Cary Clark8032b982017-07-28 11:04:54 -04005952
5953#Example
5954#Image 3
Cary Clarkbad5ad72017-08-03 17:14:08 -04005955void draw(SkCanvas* canvas) {
5956 // SkBitmap source = mandrill;
5957 SkRSXform xforms[] = { { .5f, 0, 0, 0 }, {0, .5f, 200, 100 } };
5958 SkRect tex[] = { { 0, 0, 250, 250 }, { 0, 0, 250, 250 } };
5959 SkColor colors[] = { 0x7f55aa00, 0x7f3333bf };
5960 SkPaint paint;
5961 paint.setAlpha(127);
5962 canvas->drawAtlas(image, xforms, tex, colors, 2, SkBlendMode::kPlus, nullptr, &paint);
Cary Clark8032b982017-07-28 11:04:54 -04005963}
5964##
5965
5966#ToDo bug in example on cpu side, gpu looks ok ##
5967
Cary Clark2ade9972017-11-02 17:49:34 -04005968#SeeAlso drawBitmap drawImage
5969
Cary Clark8032b982017-07-28 11:04:54 -04005970##
5971
5972# ------------------------------------------------------------------------------
5973
5974#Method void drawAtlas(const SkImage* atlas, const SkRSXform xform[], const SkRect tex[], int count,
Herb Derbyefe39bc2018-05-01 17:06:20 -04005975 const SkRect* cullRect, const SkPaint* paint)
Cary Clark8032b982017-07-28 11:04:54 -04005976
Cary Clark80247e52018-07-11 16:18:41 -04005977Draws a set of sprites from atlas, using Clip, Matrix, and optional Paint paint.
Cary Clarkffb3d682018-05-17 12:17:28 -04005978paint uses Anti_Alias, Color_Alpha, Color_Filter, Image_Filter, and Blend_Mode
Cary Clarkbad5ad72017-08-03 17:14:08 -04005979to draw, if present. For each entry in the array, Rect tex locates sprite in
5980atlas, and RSXform xform transforms it into destination space.
5981
Cary Clark8032b982017-07-28 11:04:54 -04005982xform and text must contain count entries.
Herb Derbyefe39bc2018-05-01 17:06:20 -04005983Optional cullRect is a conservative bounds of all transformed sprites.
Cary Clarkce101242017-09-01 15:51:02 -04005984If cullRect is outside of Clip, canvas can skip drawing.
Cary Clark8032b982017-07-28 11:04:54 -04005985
Cary Clarkbad5ad72017-08-03 17:14:08 -04005986#Param atlas Image containing sprites ##
5987#Param xform RSXform mappings for sprites in atlas ##
5988#Param tex Rect locations of sprites in atlas ##
5989#Param count number of sprites to draw ##
Cary Clark6fc50412017-09-21 12:31:06 -04005990#Param cullRect bounds of transformed sprites for efficient clipping; may be nullptr ##
5991#Param paint Color_Filter, Image_Filter, Blend_Mode, and so on; may be nullptr ##
Cary Clark8032b982017-07-28 11:04:54 -04005992
5993#Example
5994#Image 3
Cary Clarkbad5ad72017-08-03 17:14:08 -04005995void draw(SkCanvas* canvas) {
5996 // sk_sp<SkImage> image = mandrill;
5997 SkRSXform xforms[] = { { .5f, 0, 0, 0 }, {0, .5f, 200, 100 } };
5998 SkRect tex[] = { { 0, 0, 250, 250 }, { 0, 0, 250, 250 } };
5999 const SkImage* imagePtr = image.get();
6000 canvas->drawAtlas(imagePtr, xforms, tex, 2, nullptr, nullptr);
Cary Clark8032b982017-07-28 11:04:54 -04006001}
6002##
6003
Cary Clark2ade9972017-11-02 17:49:34 -04006004#SeeAlso drawBitmap drawImage
Cary Clark8032b982017-07-28 11:04:54 -04006005
6006##
6007
6008# ------------------------------------------------------------------------------
6009
6010#Method void drawAtlas(const sk_sp<SkImage>& atlas, const SkRSXform xform[], const SkRect tex[],
Herb Derbyefe39bc2018-05-01 17:06:20 -04006011 int count, const SkRect* cullRect, const SkPaint* paint)
Cary Clark8032b982017-07-28 11:04:54 -04006012
Cary Clark80247e52018-07-11 16:18:41 -04006013Draws a set of sprites from atlas, using Clip, Matrix, and optional Paint paint.
Cary Clarkffb3d682018-05-17 12:17:28 -04006014paint uses Anti_Alias, Color_Alpha, Color_Filter, Image_Filter, and Blend_Mode
Cary Clarkbad5ad72017-08-03 17:14:08 -04006015to draw, if present. For each entry in the array, Rect tex locates sprite in
6016atlas, and RSXform xform transforms it into destination space.
6017
Cary Clark8032b982017-07-28 11:04:54 -04006018xform and text must contain count entries.
Herb Derbyefe39bc2018-05-01 17:06:20 -04006019Optional cullRect is a conservative bounds of all transformed sprites.
Cary Clarkce101242017-09-01 15:51:02 -04006020If cullRect is outside of Clip, canvas can skip drawing.
Cary Clark8032b982017-07-28 11:04:54 -04006021
Cary Clarkbad5ad72017-08-03 17:14:08 -04006022#Param atlas Image containing sprites ##
6023#Param xform RSXform mappings for sprites in atlas ##
6024#Param tex Rect locations of sprites in atlas ##
6025#Param count number of sprites to draw ##
Cary Clark6fc50412017-09-21 12:31:06 -04006026#Param cullRect bounds of transformed sprites for efficient clipping; may be nullptr ##
6027#Param paint Color_Filter, Image_Filter, Blend_Mode, and so on; may be nullptr ##
Cary Clark8032b982017-07-28 11:04:54 -04006028
6029#Example
6030#Image 3
Cary Clarkbad5ad72017-08-03 17:14:08 -04006031void draw(SkCanvas* canvas) {
6032 // sk_sp<SkImage> image = mandrill;
6033 SkRSXform xforms[] = { { 1, 0, 0, 0 }, {0, 1, 300, 100 } };
6034 SkRect tex[] = { { 0, 0, 200, 200 }, { 200, 0, 400, 200 } };
6035 canvas->drawAtlas(image, xforms, tex, 2, nullptr, nullptr);
Cary Clark8032b982017-07-28 11:04:54 -04006036}
6037##
6038
Cary Clark2ade9972017-11-02 17:49:34 -04006039#SeeAlso drawBitmap drawImage
Cary Clark8032b982017-07-28 11:04:54 -04006040
6041##
6042
6043# ------------------------------------------------------------------------------
6044
Cary Clark73fa9722017-08-29 17:36:51 -04006045#Method void drawDrawable(SkDrawable* drawable, const SkMatrix* matrix = nullptr)
Cary Clark78de7512018-02-07 07:27:09 -05006046#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05006047#Line # draws Drawable, encapsulated drawing commands ##
Cary Clark80247e52018-07-11 16:18:41 -04006048Draws Drawable drawable using Clip and Matrix, concatenated with
Cary Clark8032b982017-07-28 11:04:54 -04006049optional matrix.
6050
Herb Derbyefe39bc2018-05-01 17:06:20 -04006051If Canvas has an asynchronous implementation, as is the case
Cary Clark8032b982017-07-28 11:04:54 -04006052when it is recording into Picture, then drawable will be referenced,
6053so that SkDrawable::draw() can be called when the operation is finalized. To force
6054immediate drawing, call SkDrawable::draw() instead.
6055
Cary Clarkbad5ad72017-08-03 17:14:08 -04006056#Param drawable custom struct encapsulating drawing commands ##
6057#Param matrix transformation applied to drawing; may be nullptr ##
Cary Clark8032b982017-07-28 11:04:54 -04006058
6059#Example
6060#Height 100
6061#Function
Cary Clarkbad5ad72017-08-03 17:14:08 -04006062struct MyDrawable : public SkDrawable {
6063 SkRect onGetBounds() override { return SkRect::MakeWH(50, 100); }
6064
6065 void onDraw(SkCanvas* canvas) override {
6066 SkPath path;
6067 path.conicTo(10, 90, 50, 90, 0.9f);
6068 SkPaint paint;
6069 paint.setColor(SK_ColorBLUE);
6070 canvas->drawRect(path.getBounds(), paint);
6071 paint.setAntiAlias(true);
6072 paint.setColor(SK_ColorWHITE);
6073 canvas->drawPath(path, paint);
6074 }
6075};
6076
6077#Function ##
6078void draw(SkCanvas* canvas) {
6079 sk_sp<SkDrawable> drawable(new MyDrawable);
6080 SkMatrix matrix;
6081 matrix.setTranslate(10, 10);
6082 canvas->drawDrawable(drawable.get(), &matrix);
Cary Clark8032b982017-07-28 11:04:54 -04006083}
6084##
6085
Cary Clark2ade9972017-11-02 17:49:34 -04006086#SeeAlso SkDrawable drawPicture
Cary Clark8032b982017-07-28 11:04:54 -04006087
6088##
6089
6090# ------------------------------------------------------------------------------
6091
6092#Method void drawDrawable(SkDrawable* drawable, SkScalar x, SkScalar y)
6093
Cary Clark80247e52018-07-11 16:18:41 -04006094Draws Drawable drawable using Clip and Matrix, offset by (x, y).
Cary Clark8032b982017-07-28 11:04:54 -04006095
Herb Derbyefe39bc2018-05-01 17:06:20 -04006096If Canvas has an asynchronous implementation, as is the case
Cary Clark8032b982017-07-28 11:04:54 -04006097when it is recording into Picture, then drawable will be referenced,
6098so that SkDrawable::draw() can be called when the operation is finalized. To force
6099immediate drawing, call SkDrawable::draw() instead.
6100
Cary Clarkbad5ad72017-08-03 17:14:08 -04006101#Param drawable custom struct encapsulating drawing commands ##
Cary Clark5538c132018-06-14 12:28:14 -04006102#Param x offset into Canvas writable pixels on x-axis ##
6103#Param y offset into Canvas writable pixels on y-axis ##
Cary Clark8032b982017-07-28 11:04:54 -04006104
6105#Example
6106#Height 100
6107#Function
Cary Clarkbad5ad72017-08-03 17:14:08 -04006108struct MyDrawable : public SkDrawable {
6109 SkRect onGetBounds() override { return SkRect::MakeWH(50, 100); }
6110
6111 void onDraw(SkCanvas* canvas) override {
6112 SkPath path;
6113 path.conicTo(10, 90, 50, 90, 0.9f);
6114 SkPaint paint;
6115 paint.setColor(SK_ColorBLUE);
6116 canvas->drawRect(path.getBounds(), paint);
6117 paint.setAntiAlias(true);
6118 paint.setColor(SK_ColorWHITE);
6119 canvas->drawPath(path, paint);
6120 }
6121};
6122
6123#Function ##
6124void draw(SkCanvas* canvas) {
6125 sk_sp<SkDrawable> drawable(new MyDrawable);
6126 canvas->drawDrawable(drawable.get(), 10, 10);
Cary Clark8032b982017-07-28 11:04:54 -04006127}
6128##
6129
Cary Clark2ade9972017-11-02 17:49:34 -04006130#SeeAlso SkDrawable drawPicture
Cary Clark8032b982017-07-28 11:04:54 -04006131
6132##
6133
6134# ------------------------------------------------------------------------------
6135
6136#Method void drawAnnotation(const SkRect& rect, const char key[], SkData* value)
Cary Clark78de7512018-02-07 07:27:09 -05006137#In Draw
6138#In Utility
Cary Clarkab2621d2018-01-30 10:08:57 -05006139#Line # associates a Rect with a key-value pair ##
Cary Clark80247e52018-07-11 16:18:41 -04006140Associates Rect on Canvas with an annotation; a key-value pair, where the key is
Cary Clark8032b982017-07-28 11:04:54 -04006141a null-terminated utf8 string, and optional value is stored as Data.
6142
Herb Derbyefe39bc2018-05-01 17:06:20 -04006143Only some canvas implementations, such as recording to Picture, or drawing to
Cary Clark8032b982017-07-28 11:04:54 -04006144Document_PDF, use annotations.
6145
Cary Clarkbad5ad72017-08-03 17:14:08 -04006146#Param rect Rect extent of canvas to annotate ##
6147#Param key string used for lookup ##
6148#Param value data holding value stored in annotation ##
Cary Clark8032b982017-07-28 11:04:54 -04006149
6150#Example
6151 #Height 1
6152 const char text[] = "Click this link!";
6153 SkRect bounds;
6154 SkPaint paint;
6155 paint.setTextSize(40);
6156 (void)paint.measureText(text, strlen(text), &bounds);
6157 const char url[] = "https://www.google.com/";
6158 sk_sp<SkData> urlData(SkData::MakeWithCString(url));
6159 canvas->drawAnnotation(bounds, "url_key", urlData.get());
6160##
6161
Cary Clark2ade9972017-11-02 17:49:34 -04006162#SeeAlso SkPicture SkDocument
Cary Clark8032b982017-07-28 11:04:54 -04006163
6164##
6165
6166# ------------------------------------------------------------------------------
6167
Herb Derbyefe39bc2018-05-01 17:06:20 -04006168#Method void drawAnnotation(const SkRect& rect, const char key[], const sk_sp<SkData>& value)
Cary Clark8032b982017-07-28 11:04:54 -04006169
Cary Clark80247e52018-07-11 16:18:41 -04006170Associates Rect on Canvas when an annotation; a key-value pair, where the key is
Cary Clark8032b982017-07-28 11:04:54 -04006171a null-terminated utf8 string, and optional value is stored as Data.
6172
Herb Derbyefe39bc2018-05-01 17:06:20 -04006173Only some canvas implementations, such as recording to Picture, or drawing to
Cary Clark8032b982017-07-28 11:04:54 -04006174Document_PDF, use annotations.
6175
Cary Clarkbad5ad72017-08-03 17:14:08 -04006176#Param rect Rect extent of canvas to annotate ##
6177#Param key string used for lookup ##
6178#Param value data holding value stored in annotation ##
Cary Clark8032b982017-07-28 11:04:54 -04006179
6180#Example
6181#Height 1
6182 const char text[] = "Click this link!";
6183 SkRect bounds;
6184 SkPaint paint;
6185 paint.setTextSize(40);
6186 (void)paint.measureText(text, strlen(text), &bounds);
6187 const char url[] = "https://www.google.com/";
6188 sk_sp<SkData> urlData(SkData::MakeWithCString(url));
6189 canvas->drawAnnotation(bounds, "url_key", urlData.get());
6190##
6191
Cary Clark2ade9972017-11-02 17:49:34 -04006192#SeeAlso SkPicture SkDocument
Cary Clark8032b982017-07-28 11:04:54 -04006193
6194##
6195
Cary Clark8032b982017-07-28 11:04:54 -04006196# ------------------------------------------------------------------------------
6197
6198#Method virtual bool isClipEmpty() const
Cary Clark78de7512018-02-07 07:27:09 -05006199#In Property
Cary Clarkab2621d2018-01-30 10:08:57 -05006200#Line # returns if Clip is empty ##
Cary Clark8032b982017-07-28 11:04:54 -04006201Returns true if Clip is empty; that is, nothing will draw.
6202
Cary Clarkbad5ad72017-08-03 17:14:08 -04006203May do work when called; it should not be called
Cary Clark8032b982017-07-28 11:04:54 -04006204more often than needed. However, once called, subsequent calls perform no
6205work until Clip changes.
6206
Cary Clarkbad5ad72017-08-03 17:14:08 -04006207#Return true if Clip is empty ##
Cary Clark8032b982017-07-28 11:04:54 -04006208
6209#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04006210 void draw(SkCanvas* canvas) {
6211 SkDebugf("clip is%s empty\n", canvas->isClipEmpty() ? "" : " not");
6212 SkPath path;
6213 canvas->clipPath(path);
6214 SkDebugf("clip is%s empty\n", canvas->isClipEmpty() ? "" : " not");
Cary Clark8032b982017-07-28 11:04:54 -04006215 }
6216 #StdOut
Cary Clarkbad5ad72017-08-03 17:14:08 -04006217 clip is not empty
Cary Clark8032b982017-07-28 11:04:54 -04006218 clip is empty
6219 ##
6220##
6221
Cary Clark2ade9972017-11-02 17:49:34 -04006222#SeeAlso isClipRect getLocalClipBounds getDeviceClipBounds
Cary Clark8032b982017-07-28 11:04:54 -04006223
6224##
6225
6226# ------------------------------------------------------------------------------
6227
6228#Method virtual bool isClipRect() const
Cary Clark78de7512018-02-07 07:27:09 -05006229#In Property
Cary Clarkab2621d2018-01-30 10:08:57 -05006230#Line # returns if Clip is Rect and not empty ##
Cary Clark8032b982017-07-28 11:04:54 -04006231Returns true if Clip is Rect and not empty.
6232Returns false if the clip is empty, or if it is not Rect.
6233
Cary Clarkbad5ad72017-08-03 17:14:08 -04006234#Return true if Clip is Rect and not empty ##
Cary Clark8032b982017-07-28 11:04:54 -04006235
6236#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04006237 void draw(SkCanvas* canvas) {
6238 SkDebugf("clip is%s rect\n", canvas->isClipRect() ? "" : " not");
6239 canvas->clipRect({0, 0, 0, 0});
6240 SkDebugf("clip is%s rect\n", canvas->isClipRect() ? "" : " not");
Cary Clark8032b982017-07-28 11:04:54 -04006241 }
6242 #StdOut
Cary Clarkbad5ad72017-08-03 17:14:08 -04006243 clip is rect
Cary Clark8032b982017-07-28 11:04:54 -04006244 clip is not rect
6245 ##
6246##
6247
Cary Clark2ade9972017-11-02 17:49:34 -04006248#SeeAlso isClipEmpty getLocalClipBounds getDeviceClipBounds
Cary Clark8032b982017-07-28 11:04:54 -04006249
6250##
6251
6252#Class SkCanvas ##
Cary Clark884dd7d2017-10-11 10:37:52 -04006253
Cary Clark8032b982017-07-28 11:04:54 -04006254#Topic Canvas ##