blob: fc6093cf7a48b1223588cb9500c67f05ca4615b7 [file] [log] [blame]
Cary Clark8032b982017-07-28 11:04:54 -04001#Topic Canvas
Cary Clark137b8742018-05-30 09:21:49 -04002#Alias Canvas_Reference ##
Cary Clark8032b982017-07-28 11:04:54 -04003
Cary Clarke4aa3712017-09-15 02:56:12 -04004#Class SkCanvas
5
Cary Clark8032b982017-07-28 11:04:54 -04006Canvas provides an interface for drawing, and how the drawing is clipped and transformed.
7Canvas contains a stack of Matrix and Clip values.
8
9Canvas and Paint together provide the state to draw into Surface or Device.
Cary Clarkbad5ad72017-08-03 17:14:08 -040010Each Canvas draw call transforms the geometry of the object by the concatenation of all
11Matrix values in the stack. The transformed geometry is clipped by the intersection
12of all of Clip values in the stack. The Canvas draw calls use Paint to supply drawing
13state such as Color, Typeface, text size, stroke width, Shader and so on.
Cary Clark8032b982017-07-28 11:04:54 -040014
Herb Derbyefe39bc2018-05-01 17:06:20 -040015To draw to a pixel-based destination, create Raster_Surface or GPU_Surface.
16Request Canvas from Surface to obtain the interface to draw.
17Canvas generated by Raster_Surface draws to memory visible to the CPU.
Cary Clark8032b982017-07-28 11:04:54 -040018Canvas generated by GPU_Surface uses Vulkan or OpenGL to draw to the GPU.
19
Cary Clarkbad5ad72017-08-03 17:14:08 -040020To draw to a document, obtain Canvas from SVG_Canvas, Document_PDF, or Picture_Recorder.
Cary Clarkce101242017-09-01 15:51:02 -040021Document based Canvas and other Canvas Subclasses reference Device describing the
Cary Clarkbad5ad72017-08-03 17:14:08 -040022destination.
23
Cary Clark8032b982017-07-28 11:04:54 -040024Canvas can be constructed to draw to Bitmap without first creating Raster_Surface.
Herb Derbyefe39bc2018-05-01 17:06:20 -040025This approach may be deprecated in the future.
Cary Clark8032b982017-07-28 11:04:54 -040026
Cary Clark682c58d2018-05-16 07:07:07 -040027#Subtopic Overview
28#Populate
29##
30
Cary Clark4855f782018-02-06 09:41:53 -050031#Subtopic Related_Function
Cary Clark08895c42018-02-01 09:37:32 -050032#Populate
33##
Cary Clark8032b982017-07-28 11:04:54 -040034
Cary Clark4855f782018-02-06 09:41:53 -050035#Subtopic Constant
Cary Clark08895c42018-02-01 09:37:32 -050036#Populate
37##
Cary Clark8032b982017-07-28 11:04:54 -040038
Cary Clark682c58d2018-05-16 07:07:07 -040039#Subtopic Struct
40#Populate
41##
42
43#Subtopic Typedef
Cary Clark08895c42018-02-01 09:37:32 -050044#Populate
45##
Cary Clark8032b982017-07-28 11:04:54 -040046
Cary Clark4855f782018-02-06 09:41:53 -050047#Subtopic Constructor
Cary Clark8032b982017-07-28 11:04:54 -040048
Cary Clark4855f782018-02-06 09:41:53 -050049Create the desired type of Surface to obtain its Canvas when possible. Useful
Cary Clark8032b982017-07-28 11:04:54 -040050when no Surface is required, and some helpers implicitly create Raster_Surface.
51
Cary Clark08895c42018-02-01 09:37:32 -050052#Populate
53##
Cary Clark8032b982017-07-28 11:04:54 -040054
Cary Clark4855f782018-02-06 09:41:53 -050055#Subtopic Member_Function
Cary Clark08895c42018-02-01 09:37:32 -050056#Populate
57##
Cary Clark8032b982017-07-28 11:04:54 -040058
59# ------------------------------------------------------------------------------
60
Cary Clarka560c472017-11-27 10:44:06 -050061#Method static std::unique_ptr<SkCanvas> MakeRasterDirect(const SkImageInfo& info, void* pixels,
62 size_t rowBytes,
63 const SkSurfaceProps* props = nullptr)
Cary Clark78de7512018-02-07 07:27:09 -050064#In Constructor
Cary Clarkab2621d2018-01-30 10:08:57 -050065#Line # creates from SkImageInfo and Pixel_Storage ##
Cary Clark8032b982017-07-28 11:04:54 -040066
Cary Clarkbad5ad72017-08-03 17:14:08 -040067Allocates raster Canvas that will draw directly into pixels.
Cary Clark8032b982017-07-28 11:04:54 -040068
Cary Clarkbad5ad72017-08-03 17:14:08 -040069Canvas is returned if all parameters are valid.
70Valid parameters include:
71info dimensions are zero or positive;
Cary Clark2dc84ad2018-01-26 12:56:22 -050072info contains Color_Type and Alpha_Type supported by Raster_Surface;
Cary Clarkbad5ad72017-08-03 17:14:08 -040073pixels is not nullptr;
Cary Clark2dc84ad2018-01-26 12:56:22 -050074rowBytes is zero or large enough to contain info width pixels of Color_Type.
Cary Clarkbad5ad72017-08-03 17:14:08 -040075
Herb Derbyefe39bc2018-05-01 17:06:20 -040076Pass zero for rowBytes to compute rowBytes from info width and size of pixel.
Cary Clarkf05bdda2017-08-24 12:59:48 -040077If rowBytes is greater than zero, it must be equal to or greater than
Cary Clark2dc84ad2018-01-26 12:56:22 -050078info width times bytes required for Color_Type.
Cary Clarkf05bdda2017-08-24 12:59:48 -040079
80Pixel buffer size should be info height times computed rowBytes.
Cary Clarka560c472017-11-27 10:44:06 -050081Pixels are not initialized.
82To access pixels after drawing, call flush() or peekPixels.
Cary Clarkbad5ad72017-08-03 17:14:08 -040083
Cary Clark2dc84ad2018-01-26 12:56:22 -050084#Param info width, height, Color_Type, Alpha_Type, Color_Space, of Raster_Surface;
Cary Clarkbad5ad72017-08-03 17:14:08 -040085 width, or height, or both, may be zero
Cary Clark8032b982017-07-28 11:04:54 -040086##
Cary Clarkf05bdda2017-08-24 12:59:48 -040087#Param pixels pointer to destination pixels buffer
Cary Clark8032b982017-07-28 11:04:54 -040088##
Cary Clarkf05bdda2017-08-24 12:59:48 -040089#Param rowBytes interval from one Surface row to the next, or zero
Cary Clark8032b982017-07-28 11:04:54 -040090##
Cary Clarka560c472017-11-27 10:44:06 -050091#Param props LCD striping orientation and setting for device independent fonts;
92 may be nullptr
93##
Cary Clark8032b982017-07-28 11:04:54 -040094
Cary Clarkbad5ad72017-08-03 17:14:08 -040095#Return Canvas if all parameters are valid; otherwise, nullptr ##
Cary Clark8032b982017-07-28 11:04:54 -040096
97#Example
98 #Description
99 Allocates a three by three bitmap, clears it to white, and draws a black pixel
100 in the center.
101 ##
Cary Clarkbad5ad72017-08-03 17:14:08 -0400102void draw(SkCanvas* ) {
Cary Clarkce101242017-09-01 15:51:02 -0400103 SkImageInfo info = SkImageInfo::MakeN32Premul(3, 3); // device aligned, 32 bpp, Premultiplied
Cary Clarkbad5ad72017-08-03 17:14:08 -0400104 const size_t minRowBytes = info.minRowBytes(); // bytes used by one bitmap row
Cary Clarka560c472017-11-27 10:44:06 -0500105 const size_t size = info.computeMinByteSize(); // bytes used by all rows
Cary Clarkbad5ad72017-08-03 17:14:08 -0400106 SkAutoTMalloc<SkPMColor> storage(size); // allocate storage for pixels
107 SkPMColor* pixels = storage.get(); // get pointer to allocated storage
108 // create a SkCanvas backed by a raster device, and delete it when the
109 // function goes out of scope.
110 std::unique_ptr<SkCanvas> canvas = SkCanvas::MakeRasterDirect(info, pixels, minRowBytes);
Cary Clarkce101242017-09-01 15:51:02 -0400111 canvas->clear(SK_ColorWHITE); // white is Unpremultiplied, in ARGB order
Cary Clarkbad5ad72017-08-03 17:14:08 -0400112 canvas->flush(); // ensure that pixels are cleared
Cary Clarkce101242017-09-01 15:51:02 -0400113 SkPMColor pmWhite = pixels[0]; // the Premultiplied format may vary
Cary Clarkbad5ad72017-08-03 17:14:08 -0400114 SkPaint paint; // by default, draws black
115 canvas->drawPoint(1, 1, paint); // draw in the center
116 canvas->flush(); // ensure that point was drawn
117 for (int y = 0; y < info.height(); ++y) {
118 for (int x = 0; x < info.width(); ++x) {
119 SkDebugf("%c", *pixels++ == pmWhite ? '-' : 'x');
120 }
121 SkDebugf("\n");
122 }
Cary Clark8032b982017-07-28 11:04:54 -0400123}
124 #StdOut
125 ---
126 -x-
127 ---
128 ##
129##
130
Cary Clark8032b982017-07-28 11:04:54 -0400131#SeeAlso MakeRasterDirectN32 SkSurface::MakeRasterDirect
Cary Clark2ade9972017-11-02 17:49:34 -0400132
Cary Clark8032b982017-07-28 11:04:54 -0400133##
134
135# ------------------------------------------------------------------------------
136
137#Method static std::unique_ptr<SkCanvas> MakeRasterDirectN32(int width, int height, SkPMColor* pixels,
Herb Derbyefe39bc2018-05-01 17:06:20 -0400138 size_t rowBytes)
Cary Clark78de7512018-02-07 07:27:09 -0500139#In Constructor
Cary Clarkab2621d2018-01-30 10:08:57 -0500140#Line # creates from image data and Pixel_Storage ##
Cary Clark8032b982017-07-28 11:04:54 -0400141
Cary Clarkbad5ad72017-08-03 17:14:08 -0400142Allocates raster Canvas specified by inline image specification. Subsequent Canvas
143calls draw into pixels.
Cary Clark2dc84ad2018-01-26 12:56:22 -0500144Color_Type is set to kN32_SkColorType.
145Alpha_Type is set to kPremul_SkAlphaType.
Cary Clark8032b982017-07-28 11:04:54 -0400146To access pixels after drawing, call flush() or peekPixels.
147
Cary Clarkbad5ad72017-08-03 17:14:08 -0400148Canvas is returned if all parameters are valid.
149Valid parameters include:
Cary Clarkf05bdda2017-08-24 12:59:48 -0400150width and height are zero or positive;
Cary Clarkbad5ad72017-08-03 17:14:08 -0400151pixels is not nullptr;
Cary Clarkf05bdda2017-08-24 12:59:48 -0400152rowBytes is zero or large enough to contain width pixels of kN32_SkColorType.
Cary Clarkbad5ad72017-08-03 17:14:08 -0400153
Herb Derbyefe39bc2018-05-01 17:06:20 -0400154Pass zero for rowBytes to compute rowBytes from width and size of pixel.
Cary Clarkf05bdda2017-08-24 12:59:48 -0400155If rowBytes is greater than zero, it must be equal to or greater than
Cary Clark2dc84ad2018-01-26 12:56:22 -0500156width times bytes required for Color_Type.
Cary Clarkf05bdda2017-08-24 12:59:48 -0400157
158Pixel buffer size should be height times rowBytes.
Cary Clarkbad5ad72017-08-03 17:14:08 -0400159
160#Param width pixel column count on Raster_Surface created; must be zero or greater ##
Cary Clarkbc5697d2017-10-04 14:31:33 -0400161#Param height pixel row count on Raster_Surface created; must be zero or greater ##
Cary Clarkbad5ad72017-08-03 17:14:08 -0400162#Param pixels pointer to destination pixels buffer; buffer size should be height
Cary Clarkf05bdda2017-08-24 12:59:48 -0400163 times rowBytes
Cary Clark8032b982017-07-28 11:04:54 -0400164##
Cary Clarkf05bdda2017-08-24 12:59:48 -0400165#Param rowBytes interval from one Surface row to the next, or zero
Cary Clark8032b982017-07-28 11:04:54 -0400166##
167
Cary Clarkbad5ad72017-08-03 17:14:08 -0400168#Return Canvas if all parameters are valid; otherwise, nullptr ##
Cary Clark8032b982017-07-28 11:04:54 -0400169
170#Example
171 #Description
172 Allocates a three by three bitmap, clears it to white, and draws a black pixel
173 in the center.
174 ##
175void draw(SkCanvas* ) {
176 const int width = 3;
177 const int height = 3;
Cary Clarkce101242017-09-01 15:51:02 -0400178 SkPMColor pixels[height][width]; // allocate a 3x3 Premultiplied bitmap on the stack
Cary Clark8032b982017-07-28 11:04:54 -0400179 // create a SkCanvas backed by a raster device, and delete it when the
180 // function goes out of scope.
181 std::unique_ptr<SkCanvas> canvas = SkCanvas::MakeRasterDirectN32(
182 width,
183 height,
Cary Clarkbc5697d2017-10-04 14:31:33 -0400184 pixels[0], // top-left of the bitmap
Cary Clark8032b982017-07-28 11:04:54 -0400185 sizeof(pixels[0])); // byte width of the each row
Cary Clark682c58d2018-05-16 07:07:07 -0400186 // write a Premultiplied value for white into all pixels in the bitmap
Cary Clark8032b982017-07-28 11:04:54 -0400187 canvas->clear(SK_ColorWHITE);
Cary Clarkce101242017-09-01 15:51:02 -0400188 SkPMColor pmWhite = pixels[0][0]; // the Premultiplied format may vary
Cary Clark8032b982017-07-28 11:04:54 -0400189 SkPaint paint; // by default, draws black
190 canvas->drawPoint(1, 1, paint); // draw in the center
191 canvas->flush(); // ensure that pixels is ready to be read
192 for (int y = 0; y < height; ++y) {
193 for (int x = 0; x < width; ++x) {
194 SkDebugf("%c", pixels[y][x] == pmWhite ? '-' : 'x');
195 }
196 SkDebugf("\n");
197 }
198}
199 #StdOut
200 ---
201 -x-
202 ---
203 ##
204##
205
Cary Clark2ade9972017-11-02 17:49:34 -0400206#SeeAlso MakeRasterDirect SkSurface::MakeRasterDirect SkImageInfo::MakeN32Premul
Cary Clark8032b982017-07-28 11:04:54 -0400207
208##
209
210# ------------------------------------------------------------------------------
211
212#Method SkCanvas()
213
Cary Clarkab2621d2018-01-30 10:08:57 -0500214#Line # creates with no Surface, no dimensions ##
Herb Derbyefe39bc2018-05-01 17:06:20 -0400215Creates an empty Canvas with no backing device or pixels, with
Cary Clarkf05bdda2017-08-24 12:59:48 -0400216a width and height of zero.
Cary Clark8032b982017-07-28 11:04:54 -0400217
Cary Clarkd0530ba2017-09-14 11:25:39 -0400218#Return empty Canvas ##
Cary Clark8032b982017-07-28 11:04:54 -0400219
220#Example
221
222#Description
223Passes a placeholder to a function that requires one.
224##
225
226#Function
Cary Clarkbad5ad72017-08-03 17:14:08 -0400227// Returns true if either the canvas rotates the text by 90 degrees, or the paint does.
228static void check_for_up_and_down_text(const SkCanvas* canvas, const SkPaint& paint) {
229 bool paintHasVertical = paint.isVerticalText();
230 const SkMatrix& matrix = canvas->getTotalMatrix();
231 bool matrixIsVertical = matrix.preservesRightAngles() && !matrix.isScaleTranslate();
232 SkDebugf("paint draws text %s\n", paintHasVertical != matrixIsVertical ?
233 "top to bottom" : "left to right");
234}
235
236static void check_for_up_and_down_text(const SkPaint& paint) {
237 SkCanvas canvas; // placeholder only, does not have an associated device
238 check_for_up_and_down_text(&canvas, paint);
239}
240
Cary Clark8032b982017-07-28 11:04:54 -0400241##
Cary Clarkbad5ad72017-08-03 17:14:08 -0400242void draw(SkCanvas* canvas) {
243 SkPaint paint;
244 check_for_up_and_down_text(paint); // paint draws text left to right
245 paint.setVerticalText(true);
246 check_for_up_and_down_text(paint); // paint draws text top to bottom
247 paint.setVerticalText(false);
248 canvas->rotate(90);
249 check_for_up_and_down_text(canvas, paint); // paint draws text top to bottom
250}
Cary Clark8032b982017-07-28 11:04:54 -0400251
252 #StdOut
253 paint draws text left to right
254 paint draws text top to bottom
255 paint draws text top to bottom
256 ##
257##
258
Cary Clark2ade9972017-11-02 17:49:34 -0400259#SeeAlso MakeRasterDirect SkRasterHandleAllocator::MakeCanvas SkSurface::getCanvas SkCreateColorSpaceXformCanvas
Cary Clark8032b982017-07-28 11:04:54 -0400260
261##
262
263# ------------------------------------------------------------------------------
264
Cary Clark73fa9722017-08-29 17:36:51 -0400265#Method SkCanvas(int width, int height, const SkSurfaceProps* props = nullptr)
Cary Clark8032b982017-07-28 11:04:54 -0400266
Cary Clark682c58d2018-05-16 07:07:07 -0400267#Line # creates with no Surface, set dimensions, Surface_Properties ##
Cary Clark8032b982017-07-28 11:04:54 -0400268Creates Canvas of the specified dimensions without a Surface.
Cary Clark682c58d2018-05-16 07:07:07 -0400269Used by Subclasses with custom implementations for draw member functions.
Cary Clark8032b982017-07-28 11:04:54 -0400270
Cary Clarkd0530ba2017-09-14 11:25:39 -0400271If props equals nullptr, Surface_Properties are created with
Herb Derbyefe39bc2018-05-01 17:06:20 -0400272Surface_Properties_Legacy_Font_Host settings, which choose the pixel striping
Cary Clarkd0530ba2017-09-14 11:25:39 -0400273direction and order. Since a platform may dynamically change its direction when
274the device is rotated, and since a platform may have multiple monitors with
275different characteristics, it is best not to rely on this legacy behavior.
Cary Clark8032b982017-07-28 11:04:54 -0400276
Cary Clarkbad5ad72017-08-03 17:14:08 -0400277#Param width zero or greater ##
278#Param height zero or greater ##
279#Param props LCD striping orientation and setting for device independent fonts;
280 may be nullptr
281##
282
283#Return Canvas placeholder with dimensions ##
Cary Clark8032b982017-07-28 11:04:54 -0400284
285#Example
286 SkCanvas canvas(10, 20); // 10 units wide, 20 units high
287 canvas.clipRect(SkRect::MakeXYWH(30, 40, 5, 10)); // clip is outside canvas' device
288 SkDebugf("canvas %s empty\n", canvas.getDeviceClipBounds().isEmpty() ? "is" : "is not");
289
290 #StdOut
291 canvas is empty
292 ##
293##
294
Cary Clark2ade9972017-11-02 17:49:34 -0400295#SeeAlso MakeRasterDirect SkSurfaceProps SkPixelGeometry SkCreateColorSpaceXformCanvas
Cary Clark8032b982017-07-28 11:04:54 -0400296
297##
298
299# ------------------------------------------------------------------------------
300
Herb Derbyefe39bc2018-05-01 17:06:20 -0400301#Method explicit SkCanvas(sk_sp<SkBaseDevice> device)
Cary Clark4855f782018-02-06 09:41:53 -0500302#Deprecated soon
Cary Clark8032b982017-07-28 11:04:54 -0400303##
304
305# ------------------------------------------------------------------------------
306
307#Method explicit SkCanvas(const SkBitmap& bitmap)
308
Cary Clarkab2621d2018-01-30 10:08:57 -0500309#Line # uses existing Bitmap ##
Cary Clark8032b982017-07-28 11:04:54 -0400310Construct a canvas that draws into bitmap.
Herb Derbyefe39bc2018-05-01 17:06:20 -0400311Sets SkSurfaceProps::kLegacyFontHost_InitType in constructed Surface.
Cary Clark8032b982017-07-28 11:04:54 -0400312
Cary Clarkbad5ad72017-08-03 17:14:08 -0400313Bitmap is copied so that subsequently editing bitmap will not affect
314constructed Canvas.
315
316May be deprecated in the future.
317
Cary Clark8032b982017-07-28 11:04:54 -0400318#ToDo Should be deprecated? ##
319
Cary Clark2dc84ad2018-01-26 12:56:22 -0500320#Param bitmap width, height, Color_Type, Alpha_Type, and pixel
Cary Clarkbad5ad72017-08-03 17:14:08 -0400321 storage of Raster_Surface
Cary Clark8032b982017-07-28 11:04:54 -0400322##
323
Cary Clarkbad5ad72017-08-03 17:14:08 -0400324#Return Canvas that can be used to draw into bitmap ##
Cary Clark8032b982017-07-28 11:04:54 -0400325
326#Example
327#Description
328The actual output depends on the installed fonts.
329##
330 SkBitmap bitmap;
331 // create a bitmap 5 wide and 11 high
332 bitmap.allocPixels(SkImageInfo::MakeN32Premul(5, 11));
333 SkCanvas canvas(bitmap);
Cary Clarkce101242017-09-01 15:51:02 -0400334 canvas.clear(SK_ColorWHITE); // white is Unpremultiplied, in ARGB order
Cary Clark8032b982017-07-28 11:04:54 -0400335 SkPixmap pixmap; // provides guaranteed access to the drawn pixels
336 if (!canvas.peekPixels(&pixmap)) {
337 SkDebugf("peekPixels should never fail.\n");
338 }
Cary Clarkbc5697d2017-10-04 14:31:33 -0400339 const SkPMColor* pixels = pixmap.addr32(); // points to top-left of bitmap
Cary Clarkce101242017-09-01 15:51:02 -0400340 SkPMColor pmWhite = pixels[0]; // the Premultiplied format may vary
Cary Clark8032b982017-07-28 11:04:54 -0400341 SkPaint paint; // by default, draws black, 12 point text
342 canvas.drawString("!", 1, 10, paint); // 1 char at baseline (1, 10)
343 for (int y = 0; y < bitmap.height(); ++y) {
344 for (int x = 0; x < bitmap.width(); ++x) {
345 SkDebugf("%c", *pixels++ == pmWhite ? '-' : 'x');
346 }
347 SkDebugf("\n");
348 }
349
350 #StdOut
Cary Clarkd0530ba2017-09-14 11:25:39 -0400351 -----
352 ---x-
353 ---x-
354 ---x-
355 ---x-
356 ---x-
357 ---x-
358 -----
359 ---x-
360 ---x-
Cary Clark8032b982017-07-28 11:04:54 -0400361 -----
362 #StdOut ##
363##
364
Cary Clark2ade9972017-11-02 17:49:34 -0400365#SeeAlso MakeRasterDirect SkRasterHandleAllocator::MakeCanvas SkSurface::getCanvas SkCreateColorSpaceXformCanvas
Cary Clark8032b982017-07-28 11:04:54 -0400366
367##
368
Cary Clarkbad5ad72017-08-03 17:14:08 -0400369#EnumClass ColorBehavior
Cary Clark682c58d2018-05-16 07:07:07 -0400370#Line # exists for Android framework only ##
Cary Clark8032b982017-07-28 11:04:54 -0400371#Private
372Android framework only.
373##
374
375#Code
376 enum class ColorBehavior {
377 kLegacy,
378 };
379##
380#Const kLegacy 0
Cary Clark682c58d2018-05-16 07:07:07 -0400381#Line # placeholder ##
Cary Clarkbad5ad72017-08-03 17:14:08 -0400382 Is a placeholder to allow specialized constructor; has no meaning.
Cary Clark8032b982017-07-28 11:04:54 -0400383##
384##
385
Cary Clarkbad5ad72017-08-03 17:14:08 -0400386#Method SkCanvas(const SkBitmap& bitmap, ColorBehavior behavior)
387
Cary Clark682c58d2018-05-16 07:07:07 -0400388#Line # exists for Android framework only ##
389
Cary Clarkbad5ad72017-08-03 17:14:08 -0400390Android framework only.
Cary Clarkbad5ad72017-08-03 17:14:08 -0400391
392#Param bitmap specifies a bitmap for the canvas to draw into ##
393#Param behavior specializes this constructor; value is unused ##
394#Return Canvas that can be used to draw into bitmap ##
395
396#NoExample
397##
398##
Cary Clark8032b982017-07-28 11:04:54 -0400399
400# ------------------------------------------------------------------------------
401
402#Method SkCanvas(const SkBitmap& bitmap, const SkSurfaceProps& props)
403
Cary Clarkab2621d2018-01-30 10:08:57 -0500404#Line # uses existing Bitmap and Surface_Properties ##
Cary Clark8032b982017-07-28 11:04:54 -0400405Construct a canvas that draws into bitmap.
406Use props to match the device characteristics, like LCD striping.
407
Cary Clarkbad5ad72017-08-03 17:14:08 -0400408bitmap is copied so that subsequently editing bitmap will not affect
409constructed Canvas.
410
Cary Clark2dc84ad2018-01-26 12:56:22 -0500411#Param bitmap width, height, Color_Type, Alpha_Type,
Herb Derbyefe39bc2018-05-01 17:06:20 -0400412 and pixel storage of Raster_Surface
Cary Clark8032b982017-07-28 11:04:54 -0400413##
Cary Clarkbad5ad72017-08-03 17:14:08 -0400414#Param props order and orientation of RGB striping; and whether to use
415 device independent fonts
Cary Clark8032b982017-07-28 11:04:54 -0400416##
417
Cary Clarkbad5ad72017-08-03 17:14:08 -0400418#Return Canvas that can be used to draw into bitmap ##
Cary Clark8032b982017-07-28 11:04:54 -0400419
420#Example
421#Description
422The actual output depends on the installed fonts.
423##
424 SkBitmap bitmap;
425 // create a bitmap 5 wide and 11 high
426 bitmap.allocPixels(SkImageInfo::MakeN32Premul(5, 11));
427 SkCanvas canvas(bitmap, SkSurfaceProps(0, kUnknown_SkPixelGeometry));
Cary Clarkce101242017-09-01 15:51:02 -0400428 canvas.clear(SK_ColorWHITE); // white is Unpremultiplied, in ARGB order
Cary Clark8032b982017-07-28 11:04:54 -0400429 SkPixmap pixmap; // provides guaranteed access to the drawn pixels
430 if (!canvas.peekPixels(&pixmap)) {
431 SkDebugf("peekPixels should never fail.\n");
432 }
Cary Clarkbc5697d2017-10-04 14:31:33 -0400433 const SkPMColor* pixels = pixmap.addr32(); // points to top-left of bitmap
Cary Clarkce101242017-09-01 15:51:02 -0400434 SkPMColor pmWhite = pixels[0]; // the Premultiplied format may vary
Cary Clark8032b982017-07-28 11:04:54 -0400435 SkPaint paint; // by default, draws black, 12 point text
436 canvas.drawString("!", 1, 10, paint); // 1 char at baseline (1, 10)
437 for (int y = 0; y < bitmap.height(); ++y) {
438 for (int x = 0; x < bitmap.width(); ++x) {
439 SkDebugf("%c", *pixels++ == pmWhite ? '-' : 'x');
440 }
441 SkDebugf("\n");
442 }
443
444 #StdOut
445 -----
446 ---x-
447 ---x-
448 ---x-
449 ---x-
450 ---x-
451 ---x-
452 -----
453 ---x-
454 ---x-
455 -----
456 #StdOut ##
457##
458
Cary Clark2ade9972017-11-02 17:49:34 -0400459#SeeAlso MakeRasterDirect SkRasterHandleAllocator::MakeCanvas SkSurface::getCanvas SkCreateColorSpaceXformCanvas
Cary Clark8032b982017-07-28 11:04:54 -0400460
461##
462
463# ------------------------------------------------------------------------------
464
465#Method virtual ~SkCanvas()
466
Cary Clarkab2621d2018-01-30 10:08:57 -0500467#Line # draws saved Layers, frees resources ##
Cary Clark5081eed2018-01-22 07:55:48 -0500468Draws saved Layers, if any.
469Frees up resources used by Canvas.
Cary Clark8032b982017-07-28 11:04:54 -0400470
471#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -0400472#Description
Cary Clarkce101242017-09-01 15:51:02 -0400473Canvas Layer draws into bitmap. saveLayerAlpha sets up an additional
474drawing surface that blends with the bitmap. When Layer goes out of
475scope, Layer Destructor is called. The saved Layer is restored, drawing
Cary Clarkbad5ad72017-08-03 17:14:08 -0400476transparent letters.
477##
Cary Clarkf05bdda2017-08-24 12:59:48 -0400478void draw(SkCanvas* canvas) {
479 SkBitmap bitmap;
480 bitmap.allocPixels(SkImageInfo::MakeN32Premul(200, 200));
481 {
482 SkCanvas offscreen(bitmap);
483 SkPaint paint;
484 paint.setTextSize(100);
485 offscreen.drawString("ABC", 20, 160, paint);
486 SkRect layerBounds = SkRect::MakeXYWH(32, 32, 192, 192);
487 offscreen.saveLayerAlpha(&layerBounds, 128);
488 offscreen.clear(SK_ColorWHITE);
489 offscreen.drawString("DEF", 20, 160, paint);
490 }
491 canvas->drawBitmap(bitmap, 0, 0, nullptr);
Cary Clarkbad5ad72017-08-03 17:14:08 -0400492}
Cary Clark8032b982017-07-28 11:04:54 -0400493##
494
Cary Clarkbad5ad72017-08-03 17:14:08 -0400495#SeeAlso State_Stack
Cary Clark8032b982017-07-28 11:04:54 -0400496
497##
498
499# ------------------------------------------------------------------------------
Cary Clark78de7512018-02-07 07:27:09 -0500500#Subtopic Property
501#Populate
502#Line # metrics and attributes ##
503##
Cary Clark8032b982017-07-28 11:04:54 -0400504
505#Method SkMetaData& getMetaData()
Cary Clark78de7512018-02-07 07:27:09 -0500506#In Property
507#In Utility
Cary Clarkab2621d2018-01-30 10:08:57 -0500508#Line # associates additional data with the canvas ##
Cary Clarkf05bdda2017-08-24 12:59:48 -0400509Returns storage to associate additional data with the canvas.
Cary Clark8032b982017-07-28 11:04:54 -0400510The storage is freed when Canvas is deleted.
511
Cary Clarkbad5ad72017-08-03 17:14:08 -0400512#Return storage that can be read from and written to ##
Cary Clark8032b982017-07-28 11:04:54 -0400513
514#Example
515 const char* kHelloMetaData = "HelloMetaData";
516 SkCanvas canvas;
517 SkMetaData& metaData = canvas.getMetaData();
518 SkDebugf("before: %s\n", metaData.findString(kHelloMetaData));
519 metaData.setString(kHelloMetaData, "Hello!");
520 SkDebugf("during: %s\n", metaData.findString(kHelloMetaData));
521 metaData.removeString(kHelloMetaData);
522 SkDebugf("after: %s\n", metaData.findString(kHelloMetaData));
523
524 #StdOut
525 before: (null)
526 during: Hello!
527 after: (null)
528 #StdOut ##
529##
530
Cary Clark2ade9972017-11-02 17:49:34 -0400531#SeeAlso SkMetaData
Cary Clark8032b982017-07-28 11:04:54 -0400532
533##
534
535# ------------------------------------------------------------------------------
536
537#Method SkImageInfo imageInfo() const
Cary Clark78de7512018-02-07 07:27:09 -0500538#In Property
Cary Clarkab2621d2018-01-30 10:08:57 -0500539#Line # returns Image_Info for Canvas ##
Cary Clark8032b982017-07-28 11:04:54 -0400540Returns Image_Info for Canvas. If Canvas is not associated with Raster_Surface or
Cary Clark2dc84ad2018-01-26 12:56:22 -0500541GPU_Surface, returned Color_Type is set to kUnknown_SkColorType.
Cary Clark8032b982017-07-28 11:04:54 -0400542
Cary Clark2dc84ad2018-01-26 12:56:22 -0500543#Return dimensions and Color_Type of Canvas ##
Cary Clark8032b982017-07-28 11:04:54 -0400544
545#Example
Cary Clarkf05bdda2017-08-24 12:59:48 -0400546 SkCanvas emptyCanvas;
547 SkImageInfo canvasInfo = emptyCanvas.imageInfo();
548 SkImageInfo emptyInfo;
549 SkDebugf("emptyInfo %c= canvasInfo\n", emptyInfo == canvasInfo ? '=' : '!');
550
551 #StdOut
552 emptyInfo == canvasInfo
553 ##
Cary Clark8032b982017-07-28 11:04:54 -0400554##
555
Cary Clark2ade9972017-11-02 17:49:34 -0400556#SeeAlso SkImageInfo MakeRasterDirect makeSurface
Cary Clark8032b982017-07-28 11:04:54 -0400557
558##
559
560# ------------------------------------------------------------------------------
561
562#Method bool getProps(SkSurfaceProps* props) const
Cary Clark78de7512018-02-07 07:27:09 -0500563#In Property
Cary Clarkab2621d2018-01-30 10:08:57 -0500564#Line # copies Surface_Properties if available ##
Cary Clark8032b982017-07-28 11:04:54 -0400565If Canvas is associated with Raster_Surface or
566GPU_Surface, copies Surface_Properties and returns true. Otherwise,
567return false and leave props unchanged.
568
Cary Clarkbad5ad72017-08-03 17:14:08 -0400569#Param props storage for writable SkSurfaceProps ##
Cary Clark8032b982017-07-28 11:04:54 -0400570
Cary Clarkbad5ad72017-08-03 17:14:08 -0400571#Return true if Surface_Properties was copied ##
Cary Clark8032b982017-07-28 11:04:54 -0400572
573#ToDo This seems old style. Deprecate? ##
574
575#Example
576 SkBitmap bitmap;
577 SkCanvas canvas(bitmap, SkSurfaceProps(0, kRGB_V_SkPixelGeometry));
578 SkSurfaceProps surfaceProps(0, kUnknown_SkPixelGeometry);
579 SkDebugf("isRGB:%d\n", SkPixelGeometryIsRGB(surfaceProps.pixelGeometry()));
580 if (!canvas.getProps(&surfaceProps)) {
581 SkDebugf("getProps failed unexpectedly.\n");
582 }
583 SkDebugf("isRGB:%d\n", SkPixelGeometryIsRGB(surfaceProps.pixelGeometry()));
584
585 #StdOut
586 isRGB:0
587 isRGB:1
588 #StdOut ##
589##
590
Cary Clark2ade9972017-11-02 17:49:34 -0400591#SeeAlso SkSurfaceProps makeSurface
Cary Clark8032b982017-07-28 11:04:54 -0400592
593##
594
595# ------------------------------------------------------------------------------
Cary Clark78de7512018-02-07 07:27:09 -0500596#Subtopic Utility
597#Populate
598#Line # rarely called management functions ##
599##
Cary Clark8032b982017-07-28 11:04:54 -0400600
601#Method void flush()
Cary Clark78de7512018-02-07 07:27:09 -0500602#In Utility
Cary Clarkab2621d2018-01-30 10:08:57 -0500603#Line # triggers execution of all pending draw operations ##
Herb Derbyefe39bc2018-05-01 17:06:20 -0400604Triggers the immediate execution of all pending draw operations.
Cary Clarkbad5ad72017-08-03 17:14:08 -0400605If Canvas is associated with GPU_Surface, resolves all pending GPU operations.
Cary Clark2ade9972017-11-02 17:49:34 -0400606If Canvas is associated with Raster_Surface, has no effect; raster draw
607operations are never deferred.
608
609#ToDo
610In an overview section on managing the GPU, include:
611- flush should never change what is drawn
612- call to kick off gpu work
613- calling too much impacts performance
614- some calls (peekPixels, prepareForExternalIO) call it internally
615- canvas call is local, GrContext::flush is global
616- diffentiate between flush, flushAndSignalSemaphores
617- normally never needs to be called
618- call it when sharing gpu resources, feeling memory pressure, swapping out app, and before
619 abandoning context
620- also call to say "I'm finished drawing here", e.g., when drawing to a GPU-backed offscreen surface
621 (created with SkSurface::MakeRenderTarget)
622
623for posterity: this doesn't show a difference: fiddle.skia.org/c/@flushfail
624##
Cary Clark8032b982017-07-28 11:04:54 -0400625
Cary Clark08895c42018-02-01 09:37:32 -0500626#ToDo haven't thought of a useful example to put here ##
627#NoExample
Cary Clark8032b982017-07-28 11:04:54 -0400628##
629
Cary Clark2ade9972017-11-02 17:49:34 -0400630#SeeAlso peekPixels SkSurface::flush() GrContext::flush() SkSurface::prepareForExternalIO GrContext::abandonContext()
Cary Clark8032b982017-07-28 11:04:54 -0400631
632##
633
634# ------------------------------------------------------------------------------
635
636#Method virtual SkISize getBaseLayerSize() const
Cary Clark78de7512018-02-07 07:27:09 -0500637#In Property
Cary Clarkab2621d2018-01-30 10:08:57 -0500638#Line # returns size of base Layer in global coordinates ##
Cary Clarkce101242017-09-01 15:51:02 -0400639Gets the size of the base or root Layer in global canvas coordinates. The
640origin of the base Layer is always (0,0). The area available for drawing may be
Cary Clark8032b982017-07-28 11:04:54 -0400641smaller (due to clipping or saveLayer).
642
Cary Clarkce101242017-09-01 15:51:02 -0400643#Return integral width and height of base Layer ##
Cary Clark8032b982017-07-28 11:04:54 -0400644
645#Example
646 SkBitmap bitmap;
647 bitmap.allocPixels(SkImageInfo::MakeN32Premul(20, 30));
648 SkCanvas canvas(bitmap, SkSurfaceProps(0, kUnknown_SkPixelGeometry));
649 canvas.clipRect(SkRect::MakeWH(10, 40));
650 SkIRect clipDeviceBounds = canvas.getDeviceClipBounds();
651 if (clipDeviceBounds.isEmpty()) {
652 SkDebugf("Empty clip bounds is unexpected!\n");
653 }
654 SkDebugf("clip=%d,%d\n", clipDeviceBounds.width(), clipDeviceBounds.height());
655 SkISize baseLayerSize = canvas.getBaseLayerSize();
656 SkDebugf("size=%d,%d\n", baseLayerSize.width(), baseLayerSize.height());
657
658 #StdOut
659 clip=10,30
660 size=20,30
661 ##
662##
663
664#ToDo is this the same as the width and height of surface? ##
665
Cary Clark2ade9972017-11-02 17:49:34 -0400666#SeeAlso getDeviceClipBounds
667
Cary Clark8032b982017-07-28 11:04:54 -0400668##
669
670# ------------------------------------------------------------------------------
671
672#Method sk_sp<SkSurface> makeSurface(const SkImageInfo& info, const SkSurfaceProps* props = nullptr)
Cary Clark4855f782018-02-06 09:41:53 -0500673#In Constructor
Cary Clarkab2621d2018-01-30 10:08:57 -0500674#Line # creates Surface matching SkImageInfo and SkSurfaceProps ##
Cary Clark8032b982017-07-28 11:04:54 -0400675Creates Surface matching info and props, and associates it with Canvas.
Cary Clarkbad5ad72017-08-03 17:14:08 -0400676Returns nullptr if no match found.
Cary Clark8032b982017-07-28 11:04:54 -0400677
Cary Clarkbad5ad72017-08-03 17:14:08 -0400678If props is nullptr, matches Surface_Properties in Canvas. If props is nullptr and Canvas
679does not have Surface_Properties, creates Surface with default Surface_Properties.
Cary Clark8032b982017-07-28 11:04:54 -0400680
Cary Clark2dc84ad2018-01-26 12:56:22 -0500681#Param info width, height, Color_Type, Alpha_Type, and Color_Space ##
Cary Clarkbad5ad72017-08-03 17:14:08 -0400682#Param props Surface_Properties to match; may be nullptr to match Canvas ##
683
684#Return Surface matching info and props, or nullptr if no match is available ##
Cary Clark8032b982017-07-28 11:04:54 -0400685
686#Example
687 sk_sp<SkSurface> surface = SkSurface::MakeRasterN32Premul(5, 6);
688 SkCanvas* smallCanvas = surface->getCanvas();
689 SkImageInfo imageInfo = SkImageInfo::MakeN32Premul(3, 4);
690 sk_sp<SkSurface> compatible = smallCanvas->makeSurface(imageInfo);
691 SkDebugf("compatible %c= nullptr\n", compatible == nullptr ? '=' : '!');
692 SkDebugf("size = %d, %d\n", compatible->width(), compatible->height());
693
694 #StdOut
Cary Clarkbad5ad72017-08-03 17:14:08 -0400695 compatible != nullptr
Cary Clark8032b982017-07-28 11:04:54 -0400696 size = 3, 4
697 ##
698##
699
Cary Clark2ade9972017-11-02 17:49:34 -0400700#SeeAlso SkSurface SkSurface::makeSurface SkImageInfo SkSurfaceProps
Cary Clark8032b982017-07-28 11:04:54 -0400701
702##
703
704# ------------------------------------------------------------------------------
705
706#Method virtual GrContext* getGrContext()
Cary Clark78de7512018-02-07 07:27:09 -0500707#In Property
Cary Clarkab2621d2018-01-30 10:08:57 -0500708#Line # returns GPU_Context of the GPU_Surface ##
Cary Clark8032b982017-07-28 11:04:54 -0400709Returns GPU_Context of the GPU_Surface associated with Canvas.
710
Cary Clarkbad5ad72017-08-03 17:14:08 -0400711#Return GPU_Context, if available; nullptr otherwise ##
Cary Clark8032b982017-07-28 11:04:54 -0400712
713#Example
714void draw(SkCanvas* canvas) {
715 if (canvas->getGrContext()) {
716 canvas->clear(SK_ColorRED);
717 } else {
718 canvas->clear(SK_ColorBLUE);
719 }
720}
721##
722
723#ToDo fiddle should show both CPU and GPU out ##
724
Herb Derbyefe39bc2018-05-01 17:06:20 -0400725#SeeAlso GrContext
Cary Clark2ade9972017-11-02 17:49:34 -0400726
Cary Clark8032b982017-07-28 11:04:54 -0400727##
728
729# ------------------------------------------------------------------------------
730
Cary Clark73fa9722017-08-29 17:36:51 -0400731#Method void* accessTopLayerPixels(SkImageInfo* info, size_t* rowBytes, SkIPoint* origin = nullptr)
Cary Clark78de7512018-02-07 07:27:09 -0500732#In Utility
733#In Property
Cary Clarkab2621d2018-01-30 10:08:57 -0500734#Line # returns writable pixel access if available ##
Cary Clark8032b982017-07-28 11:04:54 -0400735Returns the pixel base address, Image_Info, rowBytes, and origin if the pixels
Cary Clarkbad5ad72017-08-03 17:14:08 -0400736can be read directly. The returned address is only valid
Cary Clark8032b982017-07-28 11:04:54 -0400737while Canvas is in scope and unchanged. Any Canvas call or Surface call
738may invalidate the returned address and other returned values.
739
740If pixels are inaccessible, info, rowBytes, and origin are unchanged.
741
Cary Clarkbad5ad72017-08-03 17:14:08 -0400742#Param info storage for writable pixels' Image_Info; may be nullptr ##
743#Param rowBytes storage for writable pixels' row bytes; may be nullptr ##
Cary Clarkbc5697d2017-10-04 14:31:33 -0400744#Param origin storage for Canvas top Layer origin, its top-left corner;
Cary Clarkbad5ad72017-08-03 17:14:08 -0400745 may be nullptr
746##
Cary Clark8032b982017-07-28 11:04:54 -0400747
Cary Clarka523d2d2017-08-30 08:58:10 -0400748#Return address of pixels, or nullptr if inaccessible ##
Cary Clark8032b982017-07-28 11:04:54 -0400749
750#Example
751void draw(SkCanvas* canvas) {
752 if (canvas->accessTopLayerPixels(nullptr, nullptr)) {
753 canvas->clear(SK_ColorRED);
754 } else {
755 canvas->clear(SK_ColorBLUE);
756 }
757}
758##
759
760#Example
761#Description
Cary Clarkce101242017-09-01 15:51:02 -0400762Draws "ABC" on the device. Then draws "DEF" in Layer, and reads
763Layer to add a large dotted "DEF". Finally blends Layer with the
Herb Derbyefe39bc2018-05-01 17:06:20 -0400764device.
Cary Clark8032b982017-07-28 11:04:54 -0400765
Cary Clarkce101242017-09-01 15:51:02 -0400766The Layer and blended result appear on the CPU and GPU but the large dotted
Cary Clark8032b982017-07-28 11:04:54 -0400767"DEF" appear only on the CPU.
768##
769void draw(SkCanvas* canvas) {
Cary Clarkbad5ad72017-08-03 17:14:08 -0400770 SkPaint paint;
771 paint.setTextSize(100);
772 canvas->drawString("ABC", 20, 160, paint);
773 SkRect layerBounds = SkRect::MakeXYWH(32, 32, 192, 192);
774 canvas->saveLayerAlpha(&layerBounds, 128);
775 canvas->clear(SK_ColorWHITE);
776 canvas->drawString("DEF", 20, 160, paint);
777 SkImageInfo imageInfo;
778 size_t rowBytes;
779 SkIPoint origin;
780 uint32_t* access = (uint32_t*) canvas->accessTopLayerPixels(&imageInfo, &rowBytes, &origin);
781 if (access) {
782 int h = imageInfo.height();
783 int v = imageInfo.width();
784 int rowWords = rowBytes / sizeof(uint32_t);
785 for (int y = 0; y < h; ++y) {
786 int newY = (y - h / 2) * 2 + h / 2;
787 if (newY < 0 || newY >= h) {
788 continue;
789 }
790 for (int x = 0; x < v; ++x) {
791 int newX = (x - v / 2) * 2 + v / 2;
792 if (newX < 0 || newX >= v) {
793 continue;
794 }
795 if (access[y * rowWords + x] == SK_ColorBLACK) {
796 access[newY * rowWords + newX] = SK_ColorGRAY;
797 }
798 }
799 }
800
801 }
Cary Clark8032b982017-07-28 11:04:54 -0400802 canvas->restore();
803}
804##
805
806#ToDo there are no callers of this that I can find. Deprecate? ##
807#ToDo fiddle should show both CPU and GPU out ##
808
Cary Clark2ade9972017-11-02 17:49:34 -0400809#SeeAlso SkImageInfo SkPixmap
810
Cary Clark8032b982017-07-28 11:04:54 -0400811##
812
813# ------------------------------------------------------------------------------
814
815#Method SkRasterHandleAllocator::Handle accessTopRasterHandle() const
Cary Clark78de7512018-02-07 07:27:09 -0500816#In Utility
817#In Property
Cary Clarkab2621d2018-01-30 10:08:57 -0500818#Line # returns context that tracks Clip and Matrix ##
Cary Clark8032b982017-07-28 11:04:54 -0400819Returns custom context that tracks the Matrix and Clip.
820
821Use Raster_Handle_Allocator to blend Skia drawing with custom drawing, typically performed
Cary Clarkbc5697d2017-10-04 14:31:33 -0400822by the host platform user interface. The custom context returned is generated by
Cary Clarkbad5ad72017-08-03 17:14:08 -0400823SkRasterHandleAllocator::MakeCanvas, which creates a custom canvas with raster storage for
Cary Clark8032b982017-07-28 11:04:54 -0400824the drawing destination.
825
Cary Clarkce101242017-09-01 15:51:02 -0400826#Return context of custom allocation ##
Cary Clark8032b982017-07-28 11:04:54 -0400827
828#Example
829#Description
830#ToDo ##
831##
832#Function
833 static void DeleteCallback(void*, void* context) {
834 delete (char*) context;
835 }
836
837 class CustomAllocator : public SkRasterHandleAllocator {
838 public:
839 bool allocHandle(const SkImageInfo& info, Rec* rec) override {
840 char* context = new char[4]{'s', 'k', 'i', 'a'};
841 rec->fReleaseProc = DeleteCallback;
842 rec->fReleaseCtx = context;
843 rec->fHandle = context;
844 rec->fPixels = context;
845 rec->fRowBytes = 4;
846 return true;
847 }
848
849 void updateHandle(Handle handle, const SkMatrix& ctm, const SkIRect& clip_bounds) override {
850 // apply canvas matrix and clip to custom environment
851 }
852 };
853
854##
855 void draw(SkCanvas* canvas) {
856 const SkImageInfo info = SkImageInfo::MakeN32Premul(1, 1);
857 std::unique_ptr<SkCanvas> c2 =
858 SkRasterHandleAllocator::MakeCanvas(std::unique_ptr<CustomAllocator>(
859 new CustomAllocator()), info);
860 char* context = (char*) c2->accessTopRasterHandle();
861 SkDebugf("context = %.4s\n", context);
862
863 }
864 #StdOut
865 context = skia
866 ##
867 #ToDo skstd::make_unique could not be used because def is private -- note to fix in c++14? ##
868##
869
870#SeeAlso SkRasterHandleAllocator
871
872##
873
874# ------------------------------------------------------------------------------
Cary Clark78de7512018-02-07 07:27:09 -0500875#Subtopic Pixels
876#Populate
877#Line # read and write pixel values ##
878##
Cary Clark8032b982017-07-28 11:04:54 -0400879
880#Method bool peekPixels(SkPixmap* pixmap)
Cary Clark78de7512018-02-07 07:27:09 -0500881#In Pixels
Cary Clarkab2621d2018-01-30 10:08:57 -0500882#Line # returns if Canvas has direct access to its pixels ##
Cary Clark8032b982017-07-28 11:04:54 -0400883Returns true if Canvas has direct access to its pixels.
884
Cary Clarkf05bdda2017-08-24 12:59:48 -0400885Pixels are readable when Device is raster. Pixels are not readable when Canvas
Cary Clarkbad5ad72017-08-03 17:14:08 -0400886is returned from GPU_Surface, returned by SkDocument::beginPage, returned by
Cary Clarkf05bdda2017-08-24 12:59:48 -0400887SkPictureRecorder::beginRecording, or Canvas is the base of a utility class
Brian Osman46fe9c72018-03-09 15:44:34 -0500888like SkDebugCanvas.
Cary Clark8032b982017-07-28 11:04:54 -0400889
Cary Clarkf05bdda2017-08-24 12:59:48 -0400890pixmap is valid only while Canvas is in scope and unchanged. Any
Cary Clarkbad5ad72017-08-03 17:14:08 -0400891Canvas or Surface call may invalidate the pixmap values.
Cary Clark8032b982017-07-28 11:04:54 -0400892
Cary Clarkbc5697d2017-10-04 14:31:33 -0400893#Param pixmap storage for pixel state if pixels are readable; otherwise, ignored ##
Cary Clark8032b982017-07-28 11:04:54 -0400894
Cary Clarkbad5ad72017-08-03 17:14:08 -0400895#Return true if Canvas has direct access to pixels ##
Cary Clark8032b982017-07-28 11:04:54 -0400896
897#Example
898 SkPixmap pixmap;
899 if (canvas->peekPixels(&pixmap)) {
900 SkDebugf("width=%d height=%d\n", pixmap.bounds().width(), pixmap.bounds().height());
901 }
902 #StdOut
903 width=256 height=256
904 ##
905##
906
Cary Clark2ade9972017-11-02 17:49:34 -0400907#SeeAlso readPixels SkBitmap::peekPixels SkImage::peekPixels SkSurface::peekPixels
908
Cary Clark8032b982017-07-28 11:04:54 -0400909##
910
911# ------------------------------------------------------------------------------
912
913#Method bool readPixels(const SkImageInfo& dstInfo, void* dstPixels, size_t dstRowBytes,
914 int srcX, int srcY)
Cary Clark78de7512018-02-07 07:27:09 -0500915#In Pixels
Cary Clarkab2621d2018-01-30 10:08:57 -0500916#Line # copies and converts rectangle of pixels from Canvas ##
Cary Clark8032b982017-07-28 11:04:54 -0400917
Cary Clark154beea2017-10-26 07:58:48 -0400918Copies Rect of pixels from Canvas into dstPixels. Matrix and Clip are
Herb Derbyefe39bc2018-05-01 17:06:20 -0400919ignored.
Cary Clark6fc50412017-09-21 12:31:06 -0400920
Cary Clarka560c472017-11-27 10:44:06 -0500921Source Rect corners are (srcX, srcY) and (imageInfo().width(), imageInfo().height()).
922Destination Rect corners are (0, 0) and (dstInfo.width(), dstInfo.height()).
Cary Clark6fc50412017-09-21 12:31:06 -0400923Copies each readable pixel intersecting both rectangles, without scaling,
Cary Clarkf05bdda2017-08-24 12:59:48 -0400924converting to dstInfo.colorType() and dstInfo.alphaType() if required.
Cary Clark8032b982017-07-28 11:04:54 -0400925
Cary Clarkf05bdda2017-08-24 12:59:48 -0400926Pixels are readable when Device is raster, or backed by a GPU.
927Pixels are not readable when SkCanvas is returned by SkDocument::beginPage,
928returned by SkPictureRecorder::beginRecording, or Canvas is the base of a utility
Brian Osman46fe9c72018-03-09 15:44:34 -0500929class like SkDebugCanvas.
Cary Clark8032b982017-07-28 11:04:54 -0400930
Cary Clarkf05bdda2017-08-24 12:59:48 -0400931The destination pixel storage must be allocated by the caller.
Cary Clark8032b982017-07-28 11:04:54 -0400932
Cary Clark2dc84ad2018-01-26 12:56:22 -0500933Pixel values are converted only if Color_Type and Alpha_Type
Cary Clarkf05bdda2017-08-24 12:59:48 -0400934do not match. Only pixels within both source and destination rectangles
Cary Clark154beea2017-10-26 07:58:48 -0400935are copied. dstPixels contents outside Rect intersection are unchanged.
Cary Clarkf05bdda2017-08-24 12:59:48 -0400936
937Pass negative values for srcX or srcY to offset pixels across or down destination.
Cary Clark8032b982017-07-28 11:04:54 -0400938
939Does not copy, and returns false if:
940
941#List
Cary Clarkf05bdda2017-08-24 12:59:48 -0400942# Source and destination rectangles do not intersect. ##
943# Canvas pixels could not be converted to dstInfo.colorType() or dstInfo.alphaType(). ##
944# Canvas pixels are not readable; for instance, Canvas is document-based. ##
Cary Clark8032b982017-07-28 11:04:54 -0400945# dstRowBytes is too small to contain one row of pixels. ##
946##
947
Cary Clark2dc84ad2018-01-26 12:56:22 -0500948#Param dstInfo width, height, Color_Type, and Alpha_Type of dstPixels ##
Cary Clarkf05bdda2017-08-24 12:59:48 -0400949#Param dstPixels storage for pixels; dstInfo.height() times dstRowBytes, or larger ##
950#Param dstRowBytes size of one destination row; dstInfo.width() times pixel size, or larger ##
Cary Clark5538c132018-06-14 12:28:14 -0400951#Param srcX offset into readable pixels on x-axis; may be negative ##
952#Param srcY offset into readable pixels on y-axis; may be negative ##
Cary Clark8032b982017-07-28 11:04:54 -0400953
Cary Clarkbad5ad72017-08-03 17:14:08 -0400954#Return true if pixels were copied ##
Cary Clark8032b982017-07-28 11:04:54 -0400955
956#Example
Cary Clarkf05bdda2017-08-24 12:59:48 -0400957#Width 64
958#Height 64
959#Description
960 A black circle drawn on a blue background provides an image to copy.
961 readPixels copies one quarter of the canvas into each of the four corners.
Cary Clarka560c472017-11-27 10:44:06 -0500962 The copied quarter circles overdraw the original circle.
Cary Clarkf05bdda2017-08-24 12:59:48 -0400963##
964 canvas->clear(SK_ColorBLUE);
965 SkPaint paint;
966 canvas->drawCircle(32, 32, 28, paint);
967 SkImageInfo info = SkImageInfo::Make(64, 64, kBGRA_8888_SkColorType, kPremul_SkAlphaType);
968 sk_sp<SkData> data(SkData::MakeUninitialized(info.minRowBytes() * info.height()));
969 sk_bzero(data->writable_data(), info.minRowBytes() * info.height());
970 for (int x : { 32, -32 } ) {
971 for (int y : { 32, -32 } ) {
972 canvas->readPixels(info, data->writable_data(), info.minRowBytes(), x, y);
Herb Derbyefe39bc2018-05-01 17:06:20 -0400973 }
Cary Clarkf05bdda2017-08-24 12:59:48 -0400974 }
975 sk_sp<SkImage> image = SkImage::MakeRasterData(info, data, info.minRowBytes());
976 canvas->drawImage(image, 0, 0);
977##
978
979#Example
Cary Clark8032b982017-07-28 11:04:54 -0400980#Description
Cary Clarkce101242017-09-01 15:51:02 -0400981 Canvas returned by Raster_Surface has Premultiplied pixel values.
982 clear() takes Unpremultiplied input with Color_Alpha equal 0x80
Cary Clarkffb3d682018-05-17 12:17:28 -0400983 and RGB equal 0x55, 0xAA, 0xFF. RGB is multiplied by Color_Alpha
Cary Clarkce101242017-09-01 15:51:02 -0400984 to generate Premultiplied value 0x802B5580. readPixels converts pixel back
985 to Unpremultiplied value 0x8056A9FF, introducing error.
Cary Clark8032b982017-07-28 11:04:54 -0400986##
987 canvas->clear(0x8055aaff);
988 for (SkAlphaType alphaType : { kPremul_SkAlphaType, kUnpremul_SkAlphaType } ) {
989 uint32_t pixel = 0;
990 SkImageInfo info = SkImageInfo::Make(1, 1, kBGRA_8888_SkColorType, alphaType);
991 if (canvas->readPixels(info, &pixel, 4, 0, 0)) {
992 SkDebugf("pixel = %08x\n", pixel);
993 }
994 }
995
996 #StdOut
997 pixel = 802b5580
998 pixel = 8056a9ff
999 ##
1000##
1001
Cary Clark2ade9972017-11-02 17:49:34 -04001002#SeeAlso peekPixels writePixels drawBitmap drawImage SkBitmap::readPixels SkPixmap::readPixels SkImage::readPixels SkSurface::readPixels
Cary Clark8032b982017-07-28 11:04:54 -04001003
1004##
1005
1006# ------------------------------------------------------------------------------
1007
1008#Method bool readPixels(const SkPixmap& pixmap, int srcX, int srcY)
1009
Cary Clark154beea2017-10-26 07:58:48 -04001010Copies Rect of pixels from Canvas into pixmap. Matrix and Clip are
Cary Clarka560c472017-11-27 10:44:06 -05001011ignored.
Cary Clark6fc50412017-09-21 12:31:06 -04001012
Cary Clarka560c472017-11-27 10:44:06 -05001013Source Rect corners are (srcX, srcY) and (imageInfo().width(), imageInfo().height()).
1014Destination Rect corners are (0, 0) and (pixmap.width(), pixmap.height()).
Cary Clark6fc50412017-09-21 12:31:06 -04001015Copies each readable pixel intersecting both rectangles, without scaling,
Cary Clarkf05bdda2017-08-24 12:59:48 -04001016converting to pixmap.colorType() and pixmap.alphaType() if required.
Cary Clark8032b982017-07-28 11:04:54 -04001017
Cary Clarkf05bdda2017-08-24 12:59:48 -04001018Pixels are readable when Device is raster, or backed by a GPU.
1019Pixels are not readable when SkCanvas is returned by SkDocument::beginPage,
1020returned by SkPictureRecorder::beginRecording, or Canvas is the base of a utility
Brian Osman46fe9c72018-03-09 15:44:34 -05001021class like SkDebugCanvas.
Cary Clark8032b982017-07-28 11:04:54 -04001022
Cary Clark6fc50412017-09-21 12:31:06 -04001023Caller must allocate pixel storage in pixmap if needed.
Cary Clark8032b982017-07-28 11:04:54 -04001024
Cary Clark2dc84ad2018-01-26 12:56:22 -05001025Pixel values are converted only if Color_Type and Alpha_Type
Cary Clark154beea2017-10-26 07:58:48 -04001026do not match. Only pixels within both source and destination Rects
1027are copied. pixmap pixels contents outside Rect intersection are unchanged.
Cary Clarkf05bdda2017-08-24 12:59:48 -04001028
1029Pass negative values for srcX or srcY to offset pixels across or down pixmap.
Cary Clark8032b982017-07-28 11:04:54 -04001030
1031Does not copy, and returns false if:
1032
1033#List
Cary Clarkf05bdda2017-08-24 12:59:48 -04001034# Source and destination rectangles do not intersect. ##
1035# Canvas pixels could not be converted to pixmap.colorType() or pixmap.alphaType(). ##
1036# Canvas pixels are not readable; for instance, Canvas is document-based. ##
1037# Pixmap pixels could not be allocated. ##
1038# pixmap.rowBytes() is too small to contain one row of pixels. ##
Cary Clark8032b982017-07-28 11:04:54 -04001039##
1040
Cary Clarkbad5ad72017-08-03 17:14:08 -04001041#Param pixmap storage for pixels copied from Canvas ##
Cary Clark5538c132018-06-14 12:28:14 -04001042#Param srcX offset into readable pixels on x-axis; may be negative ##
1043#Param srcY offset into readable pixels on y-axis; may be negative ##
Cary Clark8032b982017-07-28 11:04:54 -04001044
Cary Clarkbad5ad72017-08-03 17:14:08 -04001045#Return true if pixels were copied ##
Cary Clark8032b982017-07-28 11:04:54 -04001046
1047#Example
Cary Clarkf05bdda2017-08-24 12:59:48 -04001048 #Description
Cary Clarkce101242017-09-01 15:51:02 -04001049 clear() takes Unpremultiplied input with Color_Alpha equal 0x80
Cary Clarkffb3d682018-05-17 12:17:28 -04001050 and RGB equal 0x55, 0xAA, 0xFF. RGB is multiplied by Color_Alpha
Cary Clarkce101242017-09-01 15:51:02 -04001051 to generate Premultiplied value 0x802B5580.
Cary Clarkf05bdda2017-08-24 12:59:48 -04001052 ##
1053 void draw(SkCanvas* canvas) {
1054 canvas->clear(0x8055aaff);
1055 uint32_t pixels[1] = { 0 };
1056 SkPixmap pixmap(SkImageInfo::MakeN32Premul(1, 1), pixels, 4);
1057 canvas->readPixels(pixmap, 0, 0);
1058 SkDebugf("pixel = %08x\n", pixels[0]);
1059 }
Cary Clark8032b982017-07-28 11:04:54 -04001060 #StdOut
1061 pixel = 802b5580
1062 ##
1063##
1064
Cary Clark2ade9972017-11-02 17:49:34 -04001065#SeeAlso peekPixels writePixels drawBitmap drawImage SkBitmap::readPixels SkPixmap::readPixels SkImage::readPixels SkSurface::readPixels
Cary Clark8032b982017-07-28 11:04:54 -04001066
1067##
1068
1069# ------------------------------------------------------------------------------
1070
1071#Method bool readPixels(const SkBitmap& bitmap, int srcX, int srcY)
1072
Cary Clark154beea2017-10-26 07:58:48 -04001073Copies Rect of pixels from Canvas into bitmap. Matrix and Clip are
Cary Clarka560c472017-11-27 10:44:06 -05001074ignored.
Cary Clark6fc50412017-09-21 12:31:06 -04001075
Cary Clarka560c472017-11-27 10:44:06 -05001076Source Rect corners are (srcX, srcY) and (imageInfo().width(), imageInfo().height()).
Cary Clark154beea2017-10-26 07:58:48 -04001077Destination Rect corners are (0, 0) and (bitmap.width(), bitmap.height()).
Cary Clarkf05bdda2017-08-24 12:59:48 -04001078Copies each readable pixel intersecting both rectangles, without scaling,
1079converting to bitmap.colorType() and bitmap.alphaType() if required.
Cary Clark8032b982017-07-28 11:04:54 -04001080
Cary Clarkf05bdda2017-08-24 12:59:48 -04001081Pixels are readable when Device is raster, or backed by a GPU.
1082Pixels are not readable when SkCanvas is returned by SkDocument::beginPage,
1083returned by SkPictureRecorder::beginRecording, or Canvas is the base of a utility
Brian Osman46fe9c72018-03-09 15:44:34 -05001084class like SkDebugCanvas.
Cary Clark8032b982017-07-28 11:04:54 -04001085
Cary Clark6fc50412017-09-21 12:31:06 -04001086Caller must allocate pixel storage in bitmap if needed.
Cary Clarkf05bdda2017-08-24 12:59:48 -04001087
Cary Clark2dc84ad2018-01-26 12:56:22 -05001088Bitmap values are converted only if Color_Type and Alpha_Type
Cary Clarkf05bdda2017-08-24 12:59:48 -04001089do not match. Only pixels within both source and destination rectangles
Cary Clark154beea2017-10-26 07:58:48 -04001090are copied. Bitmap pixels outside Rect intersection are unchanged.
Cary Clarkf05bdda2017-08-24 12:59:48 -04001091
1092Pass negative values for srcX or srcY to offset pixels across or down bitmap.
Cary Clark8032b982017-07-28 11:04:54 -04001093
1094Does not copy, and returns false if:
1095
1096#List
Cary Clarkf05bdda2017-08-24 12:59:48 -04001097# Source and destination rectangles do not intersect. ##
1098# Canvas pixels could not be converted to bitmap.colorType() or bitmap.alphaType(). ##
1099# Canvas pixels are not readable; for instance, Canvas is document-based. ##
Cary Clark8032b982017-07-28 11:04:54 -04001100# bitmap pixels could not be allocated. ##
Cary Clarkf05bdda2017-08-24 12:59:48 -04001101# bitmap.rowBytes() is too small to contain one row of pixels. ##
Cary Clark8032b982017-07-28 11:04:54 -04001102##
1103
Cary Clarkbad5ad72017-08-03 17:14:08 -04001104#Param bitmap storage for pixels copied from Canvas ##
Cary Clark5538c132018-06-14 12:28:14 -04001105#Param srcX offset into readable pixels on x-axis; may be negative ##
1106#Param srcY offset into readable pixels on y-axis; may be negative ##
Cary Clark8032b982017-07-28 11:04:54 -04001107
Cary Clarkbad5ad72017-08-03 17:14:08 -04001108#Return true if pixels were copied ##
Cary Clark8032b982017-07-28 11:04:54 -04001109
1110#Example
Cary Clarkf05bdda2017-08-24 12:59:48 -04001111 #Description
Cary Clarkce101242017-09-01 15:51:02 -04001112 clear() takes Unpremultiplied input with Color_Alpha equal 0x80
Cary Clarkffb3d682018-05-17 12:17:28 -04001113 and RGB equal 0x55, 0xAA, 0xFF. RGB is multiplied by Color_Alpha
Cary Clarkce101242017-09-01 15:51:02 -04001114 to generate Premultiplied value 0x802B5580.
Cary Clarkf05bdda2017-08-24 12:59:48 -04001115 ##
Cary Clark8032b982017-07-28 11:04:54 -04001116void draw(SkCanvas* canvas) {
1117 canvas->clear(0x8055aaff);
1118 SkBitmap bitmap;
1119 bitmap.allocPixels(SkImageInfo::MakeN32Premul(1, 1));
1120 canvas->readPixels(bitmap, 0, 0);
1121 SkDebugf("pixel = %08x\n", bitmap.getAddr32(0, 0)[0]);
1122}
1123 #StdOut
1124 pixel = 802b5580
1125 ##
1126##
1127
Cary Clark2ade9972017-11-02 17:49:34 -04001128#SeeAlso peekPixels writePixels drawBitmap drawImage SkBitmap::readPixels SkPixmap::readPixels SkImage::readPixels SkSurface::readPixels
Cary Clark8032b982017-07-28 11:04:54 -04001129
1130##
1131
1132# ------------------------------------------------------------------------------
1133
1134#Method bool writePixels(const SkImageInfo& info, const void* pixels, size_t rowBytes, int x, int y)
Cary Clark78de7512018-02-07 07:27:09 -05001135#In Pixels
Cary Clarkab2621d2018-01-30 10:08:57 -05001136#Line # copies and converts rectangle of pixels to Canvas ##
Cary Clark154beea2017-10-26 07:58:48 -04001137Copies Rect from pixels to Canvas. Matrix and Clip are ignored.
1138Source Rect corners are (0, 0) and (info.width(), info.height()).
1139Destination Rect corners are (x, y) and
1140(imageInfo().width(), imageInfo().height()).
Cary Clark6fc50412017-09-21 12:31:06 -04001141
1142Copies each readable pixel intersecting both rectangles, without scaling,
Cary Clark154beea2017-10-26 07:58:48 -04001143converting to imageInfo().colorType() and imageInfo().alphaType() if required.
Cary Clark8032b982017-07-28 11:04:54 -04001144
Cary Clarkf05bdda2017-08-24 12:59:48 -04001145Pixels are writable when Device is raster, or backed by a GPU.
1146Pixels are not writable when SkCanvas is returned by SkDocument::beginPage,
1147returned by SkPictureRecorder::beginRecording, or Canvas is the base of a utility
Brian Osman46fe9c72018-03-09 15:44:34 -05001148class like SkDebugCanvas.
Cary Clark8032b982017-07-28 11:04:54 -04001149
Cary Clark2dc84ad2018-01-26 12:56:22 -05001150Pixel values are converted only if Color_Type and Alpha_Type
Cary Clarkf05bdda2017-08-24 12:59:48 -04001151do not match. Only pixels within both source and destination rectangles
Cary Clark154beea2017-10-26 07:58:48 -04001152are copied. Canvas pixels outside Rect intersection are unchanged.
Cary Clark8032b982017-07-28 11:04:54 -04001153
Cary Clarkf05bdda2017-08-24 12:59:48 -04001154Pass negative values for x or y to offset pixels to the left or
1155above Canvas pixels.
Cary Clark8032b982017-07-28 11:04:54 -04001156
1157Does not copy, and returns false if:
1158
1159#List
Cary Clarkf05bdda2017-08-24 12:59:48 -04001160# Source and destination rectangles do not intersect. ##
Cary Clarkac47b882018-01-11 10:35:44 -05001161# pixels could not be converted to Canvas imageInfo().colorType() or
1162 imageInfo().alphaType(). ##
Cary Clark8032b982017-07-28 11:04:54 -04001163# Canvas pixels are not writable; for instance, Canvas is document-based. ##
1164# rowBytes is too small to contain one row of pixels. ##
1165##
1166
Cary Clark2dc84ad2018-01-26 12:56:22 -05001167#Param info width, height, Color_Type, and Alpha_Type of pixels ##
Cary Clarkf05bdda2017-08-24 12:59:48 -04001168#Param pixels pixels to copy, of size info.height() times rowBytes, or larger ##
Cary Clarkd0530ba2017-09-14 11:25:39 -04001169#Param rowBytes size of one row of pixels; info.width() times pixel size, or larger ##
Cary Clark5538c132018-06-14 12:28:14 -04001170#Param x offset into Canvas writable pixels on x-axis; may be negative ##
1171#Param y offset into Canvas writable pixels on y-axis; may be negative ##
Cary Clark8032b982017-07-28 11:04:54 -04001172
Cary Clarkbad5ad72017-08-03 17:14:08 -04001173#Return true if pixels were written to Canvas ##
Cary Clark8032b982017-07-28 11:04:54 -04001174
1175#Example
1176 SkImageInfo imageInfo = SkImageInfo::MakeN32(256, 1, kPremul_SkAlphaType);
1177 for (int y = 0; y < 256; ++y) {
1178 uint32_t pixels[256];
1179 for (int x = 0; x < 256; ++x) {
1180 pixels[x] = SkColorSetARGB(x, x + y, x, x - y);
1181 }
1182 canvas->writePixels(imageInfo, &pixels, sizeof(pixels), 0, y);
1183 }
1184##
1185
Cary Clark2ade9972017-11-02 17:49:34 -04001186#SeeAlso readPixels drawBitmap drawImage SkBitmap::writePixels
Cary Clark8032b982017-07-28 11:04:54 -04001187
1188##
1189
1190# ------------------------------------------------------------------------------
1191
1192#Method bool writePixels(const SkBitmap& bitmap, int x, int y)
1193
Cary Clark154beea2017-10-26 07:58:48 -04001194Copies Rect from pixels to Canvas. Matrix and Clip are ignored.
1195Source Rect corners are (0, 0) and (bitmap.width(), bitmap.height()).
Cary Clark6fc50412017-09-21 12:31:06 -04001196
Cary Clark154beea2017-10-26 07:58:48 -04001197Destination Rect corners are (x, y) and
1198(imageInfo().width(), imageInfo().height()).
Cary Clark6fc50412017-09-21 12:31:06 -04001199
1200Copies each readable pixel intersecting both rectangles, without scaling,
Cary Clark154beea2017-10-26 07:58:48 -04001201converting to imageInfo().colorType() and imageInfo().alphaType() if required.
Cary Clark8032b982017-07-28 11:04:54 -04001202
Cary Clarkf05bdda2017-08-24 12:59:48 -04001203Pixels are writable when Device is raster, or backed by a GPU.
1204Pixels are not writable when SkCanvas is returned by SkDocument::beginPage,
1205returned by SkPictureRecorder::beginRecording, or Canvas is the base of a utility
Brian Osman46fe9c72018-03-09 15:44:34 -05001206class like SkDebugCanvas.
Cary Clark8032b982017-07-28 11:04:54 -04001207
Cary Clark2dc84ad2018-01-26 12:56:22 -05001208Pixel values are converted only if Color_Type and Alpha_Type
Cary Clarkf05bdda2017-08-24 12:59:48 -04001209do not match. Only pixels within both source and destination rectangles
Cary Clark154beea2017-10-26 07:58:48 -04001210are copied. Canvas pixels outside Rect intersection are unchanged.
Cary Clark8032b982017-07-28 11:04:54 -04001211
Cary Clarkf05bdda2017-08-24 12:59:48 -04001212Pass negative values for x or y to offset pixels to the left or
1213above Canvas pixels.
Cary Clark8032b982017-07-28 11:04:54 -04001214
1215Does not copy, and returns false if:
1216
1217#List
Cary Clarkf05bdda2017-08-24 12:59:48 -04001218# Source and destination rectangles do not intersect. ##
Cary Clark8032b982017-07-28 11:04:54 -04001219# bitmap does not have allocated pixels. ##
Cary Clarkac47b882018-01-11 10:35:44 -05001220# bitmap pixels could not be converted to Canvas imageInfo().colorType() or
1221 imageInfo().alphaType(). ##
Cary Clarkce101242017-09-01 15:51:02 -04001222# Canvas pixels are not writable; for instance, Canvas is document based. ##
Cary Clark8032b982017-07-28 11:04:54 -04001223# bitmap pixels are inaccessible; for instance, bitmap wraps a texture. ##
1224##
1225
Cary Clarkbad5ad72017-08-03 17:14:08 -04001226#Param bitmap contains pixels copied to Canvas ##
Cary Clarkf05bdda2017-08-24 12:59:48 -04001227#Param x offset into Canvas writable pixels in x; may be negative ##
1228#Param y offset into Canvas writable pixels in y; may be negative ##
Cary Clark8032b982017-07-28 11:04:54 -04001229
Cary Clarkbad5ad72017-08-03 17:14:08 -04001230#Return true if pixels were written to Canvas ##
Cary Clark8032b982017-07-28 11:04:54 -04001231
1232#Example
1233void draw(SkCanvas* canvas) {
1234 SkImageInfo imageInfo = SkImageInfo::MakeN32Premul(2, 2);
1235 SkBitmap bitmap;
1236 bitmap.setInfo(imageInfo);
1237 uint32_t pixels[4];
1238 bitmap.setPixels(pixels);
1239 for (int y = 0; y < 256; y += 2) {
1240 for (int x = 0; x < 256; x += 2) {
1241 pixels[0] = SkColorSetRGB(x, y, x | y);
1242 pixels[1] = SkColorSetRGB(x ^ y, y, x);
1243 pixels[2] = SkColorSetRGB(x, x & y, y);
1244 pixels[3] = SkColorSetRGB(~x, ~y, x);
1245 canvas->writePixels(bitmap, x, y);
1246 }
1247 }
1248}
1249##
1250
Cary Clark2ade9972017-11-02 17:49:34 -04001251#SeeAlso readPixels drawBitmap drawImage SkBitmap::writePixels
Cary Clark8032b982017-07-28 11:04:54 -04001252
1253##
1254
1255# ------------------------------------------------------------------------------
Cary Clark08895c42018-02-01 09:37:32 -05001256#Subtopic State_Stack
1257#Line # stack of state for hierarchical drawing ##
Cary Clark8032b982017-07-28 11:04:54 -04001258
1259Canvas maintains a stack of state that allows hierarchical drawing, commonly used
Cary Clarkbad5ad72017-08-03 17:14:08 -04001260to implement windows and views. The initial state has an identity matrix and and
1261an infinite clip. Even with a wide-open clip, drawing is constrained by the
1262bounds of the Canvas Surface or Device.
Cary Clark8032b982017-07-28 11:04:54 -04001263
1264Canvas savable state consists of Clip, Matrix, and Draw_Filter.
1265Clip describes the area that may be drawn to.
1266Matrix transforms the geometry.
1267Draw_Filter (deprecated on most platforms) modifies the paint before drawing.
1268
1269save(), saveLayer, saveLayerPreserveLCDTextRequests, and saveLayerAlpha
1270save state and return the depth of the stack.
1271
Cary Clarkbad5ad72017-08-03 17:14:08 -04001272restore(), restoreToCount, and ~SkCanvas() revert state to its value when saved.
Cary Clark8032b982017-07-28 11:04:54 -04001273
1274Each state on the stack intersects Clip with the previous Clip,
1275and concatenates Matrix with the previous Matrix.
1276The intersected Clip makes the drawing area the same or smaller;
1277the concatenated Matrix may move the origin and potentially scale or rotate
1278the coordinate space.
1279
1280Canvas does not require balancing the state stack but it is a good idea
1281to do so. Calling save() without restore() will eventually cause Skia to fail;
1282mismatched save() and restore() create hard to find bugs.
1283
1284It is not possible to use state to draw outside of the clip defined by the
1285previous state.
1286
1287#Example
1288#Description
1289Draw to ever smaller clips; then restore drawing to full canvas.
1290Note that the second clipRect is not permitted to enlarge Clip.
1291##
1292#Height 160
Cary Clarkbad5ad72017-08-03 17:14:08 -04001293void draw(SkCanvas* canvas) {
1294 SkPaint paint;
Herb Derbyefe39bc2018-05-01 17:06:20 -04001295 canvas->save(); // records stack depth to restore
Cary Clarkbad5ad72017-08-03 17:14:08 -04001296 canvas->clipRect(SkRect::MakeWH(100, 100)); // constrains drawing to clip
1297 canvas->clear(SK_ColorRED); // draws to limit of clip
Herb Derbyefe39bc2018-05-01 17:06:20 -04001298 canvas->save(); // records stack depth to restore
Cary Clarkbad5ad72017-08-03 17:14:08 -04001299 canvas->clipRect(SkRect::MakeWH(50, 150)); // Rect below 100 is ignored
1300 canvas->clear(SK_ColorBLUE); // draws to smaller clip
1301 canvas->restore(); // enlarges clip
1302 canvas->drawLine(20, 20, 150, 150, paint); // line below 100 is not drawn
1303 canvas->restore(); // enlarges clip
1304 canvas->drawLine(150, 20, 50, 120, paint); // line below 100 is drawn
Cary Clark8032b982017-07-28 11:04:54 -04001305}
Herb Derbyefe39bc2018-05-01 17:06:20 -04001306##
Cary Clark8032b982017-07-28 11:04:54 -04001307
1308Each Clip uses the current Matrix for its coordinates.
1309
1310#Example
1311#Description
1312While clipRect is given the same rectangle twice, Matrix makes the second
1313clipRect draw at half the size of the first.
1314##
1315#Height 128
Cary Clarkbad5ad72017-08-03 17:14:08 -04001316void draw(SkCanvas* canvas) {
1317 canvas->clipRect(SkRect::MakeWH(100, 100));
1318 canvas->clear(SK_ColorRED);
1319 canvas->scale(.5, .5);
1320 canvas->clipRect(SkRect::MakeWH(100, 100));
1321 canvas->clear(SK_ColorBLUE);
Cary Clark8032b982017-07-28 11:04:54 -04001322}
1323##
1324
1325#SeeAlso save() saveLayer saveLayerPreserveLCDTextRequests saveLayerAlpha restore() restoreToCount
1326
1327#Method int save()
1328
Cary Clarkab2621d2018-01-30 10:08:57 -05001329#In State_Stack
1330#Line # saves Clip and Matrix on stack ##
Cary Clark8032b982017-07-28 11:04:54 -04001331Saves Matrix, Clip, and Draw_Filter (Draw_Filter deprecated on most platforms).
1332Calling restore() discards changes to Matrix, Clip, and Draw_Filter,
1333restoring the Matrix, Clip, and Draw_Filter to their state when save() was called.
1334
Cary Clarkbad5ad72017-08-03 17:14:08 -04001335Matrix may be changed by translate(), scale(), rotate(), skew(), concat(), setMatrix,
1336and resetMatrix. Clip may be changed by clipRect, clipRRect, clipPath, clipRegion.
Cary Clark8032b982017-07-28 11:04:54 -04001337
Cary Clarkbad5ad72017-08-03 17:14:08 -04001338Saved Canvas state is put on a stack; multiple calls to save() should be balance
1339by an equal number of calls to restore().
Cary Clark8032b982017-07-28 11:04:54 -04001340
1341Call restoreToCount with result to restore this and subsequent saves.
1342
Cary Clarkbad5ad72017-08-03 17:14:08 -04001343#Return depth of saved stack ##
Cary Clark8032b982017-07-28 11:04:54 -04001344
1345#Example
Herb Derbyefe39bc2018-05-01 17:06:20 -04001346#Description
Cary Clark8032b982017-07-28 11:04:54 -04001347The black square is translated 50 pixels down and to the right.
1348Restoring Canvas state removes translate() from Canvas stack;
1349the red square is not translated, and is drawn at the origin.
1350##
1351#Height 100
1352void draw(SkCanvas* canvas) {
1353 SkPaint paint;
1354 SkRect rect = { 0, 0, 25, 25 };
1355 canvas->drawRect(rect, paint);
1356 canvas->save();
1357 canvas->translate(50, 50);
1358 canvas->drawRect(rect, paint);
1359 canvas->restore();
1360 paint.setColor(SK_ColorRED);
1361 canvas->drawRect(rect, paint);
1362}
1363##
1364
Cary Clark2ade9972017-11-02 17:49:34 -04001365#SeeAlso saveLayer saveLayerPreserveLCDTextRequests saveLayerAlpha restore() restoreToCount
Cary Clark8032b982017-07-28 11:04:54 -04001366
1367##
1368
1369# ------------------------------------------------------------------------------
Cary Clark8032b982017-07-28 11:04:54 -04001370
1371#Method void restore()
1372
Cary Clarkab2621d2018-01-30 10:08:57 -05001373#In State_Stack
1374#Line # restores changes to Clip and Matrix, pops save stack ##
Cary Clark8032b982017-07-28 11:04:54 -04001375Removes changes to Matrix, Clip, and Draw_Filter since Canvas state was
Herb Derbyefe39bc2018-05-01 17:06:20 -04001376last saved. The state is removed from the stack.
Cary Clark8032b982017-07-28 11:04:54 -04001377
Herb Derbyefe39bc2018-05-01 17:06:20 -04001378Does nothing if the stack is empty.
Cary Clark8032b982017-07-28 11:04:54 -04001379
1380#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04001381void draw(SkCanvas* canvas) {
1382 SkCanvas simple;
1383 SkDebugf("depth = %d\n", simple.getSaveCount());
1384 simple.restore();
1385 SkDebugf("depth = %d\n", simple.getSaveCount());
Cary Clark8032b982017-07-28 11:04:54 -04001386}
1387##
1388
Cary Clark2ade9972017-11-02 17:49:34 -04001389#SeeAlso save() saveLayer saveLayerPreserveLCDTextRequests saveLayerAlpha restoreToCount
1390
Cary Clark8032b982017-07-28 11:04:54 -04001391##
1392
1393# ------------------------------------------------------------------------------
1394
1395#Method int getSaveCount() const
1396
Cary Clarkab2621d2018-01-30 10:08:57 -05001397#In State_Stack
1398#Line # returns depth of stack containing Clip and Matrix ##
Cary Clark8032b982017-07-28 11:04:54 -04001399Returns the number of saved states, each containing: Matrix, Clip, and Draw_Filter.
Herb Derbyefe39bc2018-05-01 17:06:20 -04001400Equals the number of save() calls less the number of restore() calls plus one.
Cary Clark8032b982017-07-28 11:04:54 -04001401The save count of a new canvas is one.
1402
Cary Clarkbad5ad72017-08-03 17:14:08 -04001403#Return depth of save state stack ##
Cary Clark8032b982017-07-28 11:04:54 -04001404
1405#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04001406void draw(SkCanvas* canvas) {
1407 SkCanvas simple;
1408 SkDebugf("depth = %d\n", simple.getSaveCount());
1409 simple.save();
1410 SkDebugf("depth = %d\n", simple.getSaveCount());
1411 simple.restore();
1412 SkDebugf("depth = %d\n", simple.getSaveCount());
Cary Clark8032b982017-07-28 11:04:54 -04001413}
1414#StdOut
Cary Clarkbad5ad72017-08-03 17:14:08 -04001415depth = 1
1416depth = 2
Cary Clark8032b982017-07-28 11:04:54 -04001417depth = 1
1418##
1419##
1420
Cary Clark2ade9972017-11-02 17:49:34 -04001421#SeeAlso save() restore() restoreToCount
1422
Cary Clark8032b982017-07-28 11:04:54 -04001423##
1424
1425# ------------------------------------------------------------------------------
1426
1427#Method void restoreToCount(int saveCount)
1428
Cary Clarkab2621d2018-01-30 10:08:57 -05001429#In State_Stack
1430#Line # restores changes to Clip and Matrix to given depth ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04001431Restores state to Matrix, Clip, and Draw_Filter values when save(), saveLayer,
1432saveLayerPreserveLCDTextRequests, or saveLayerAlpha returned saveCount.
Cary Clark8032b982017-07-28 11:04:54 -04001433
Herb Derbyefe39bc2018-05-01 17:06:20 -04001434Does nothing if saveCount is greater than state stack count.
Cary Clark8032b982017-07-28 11:04:54 -04001435Restores state to initial values if saveCount is less than or equal to one.
1436
Cary Clarkbad5ad72017-08-03 17:14:08 -04001437#Param saveCount depth of state stack to restore ##
Cary Clark8032b982017-07-28 11:04:54 -04001438
1439#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04001440void draw(SkCanvas* canvas) {
1441 SkDebugf("depth = %d\n", canvas->getSaveCount());
1442 canvas->save();
1443 canvas->save();
1444 SkDebugf("depth = %d\n", canvas->getSaveCount());
1445 canvas->restoreToCount(0);
1446 SkDebugf("depth = %d\n", canvas->getSaveCount());
Cary Clark8032b982017-07-28 11:04:54 -04001447}
1448#StdOut
Cary Clarkbad5ad72017-08-03 17:14:08 -04001449depth = 1
1450depth = 3
Cary Clark8032b982017-07-28 11:04:54 -04001451depth = 1
1452##
1453##
1454
Herb Derbyefe39bc2018-05-01 17:06:20 -04001455#SeeAlso restore() getSaveCount save()
Cary Clark2ade9972017-11-02 17:49:34 -04001456
Cary Clark8032b982017-07-28 11:04:54 -04001457##
1458
Cary Clark08895c42018-02-01 09:37:32 -05001459#Subtopic State_Stack ##
Cary Clark8032b982017-07-28 11:04:54 -04001460
1461# ------------------------------------------------------------------------------
Cary Clarkce101242017-09-01 15:51:02 -04001462
Cary Clark08895c42018-02-01 09:37:32 -05001463#Subtopic Layer
Cary Clarkd0530ba2017-09-14 11:25:39 -04001464#Substitute layer
Cary Clarkce101242017-09-01 15:51:02 -04001465#Alias Layers
Cary Clark137b8742018-05-30 09:21:49 -04001466#Substitute layers
1467##
Cary Clark08895c42018-02-01 09:37:32 -05001468#Line # temporary Bitmap to draw into ##
Cary Clarkce101242017-09-01 15:51:02 -04001469
1470Layer allocates a temporary Bitmap to draw into. When the drawing is
Herb Derbyefe39bc2018-05-01 17:06:20 -04001471complete, the Bitmap is drawn into the Canvas.
Cary Clarkce101242017-09-01 15:51:02 -04001472
1473Layer is saved in a stack along with other saved state. When state with a Layer
1474is restored, the Bitmap is drawn into the previous Layer.
1475
1476Layer may be initialized with the contents of the previous Layer. When Layer is
1477restored, its Bitmap can be modified by Paint passed to Layer to apply
1478Color_Alpha, Color_Filter, Image_Filter, and Blend_Mode.
1479
1480#Method int saveLayer(const SkRect* bounds, const SkPaint* paint)
1481
Cary Clarkab2621d2018-01-30 10:08:57 -05001482#In Layer
1483#Line # saves Clip and Matrix on stack; creates Layer ##
Cary Clarkce101242017-09-01 15:51:02 -04001484Saves Matrix, Clip, and Draw_Filter (Draw_Filter deprecated on most platforms),
1485and allocates a Bitmap for subsequent drawing.
1486Calling restore() discards changes to Matrix, Clip, and Draw_Filter,
1487and draws the Bitmap.
1488
1489Matrix may be changed by translate(), scale(), rotate(), skew(), concat(),
Herb Derbyefe39bc2018-05-01 17:06:20 -04001490setMatrix, and resetMatrix. Clip may be changed by clipRect, clipRRect,
Cary Clarkce101242017-09-01 15:51:02 -04001491clipPath, clipRegion.
1492
1493Rect bounds suggests but does not define the Bitmap size. To clip drawing to
1494a specific rectangle, use clipRect.
1495
1496Optional Paint paint applies Color_Alpha, Color_Filter, Image_Filter, and
1497Blend_Mode when restore() is called.
1498
1499Call restoreToCount with returned value to restore this and subsequent saves.
1500
1501#Param bounds hint to limit the size of the Layer; may be nullptr ##
1502#Param paint graphics state for Layer; may be nullptr ##
1503
1504#Return depth of saved stack ##
1505
1506#Example
1507#Description
1508Rectangles are blurred by Image_Filter when restore() draws Layer to main
1509Canvas.
1510##
1511#Height 128
Cary Clark81abc432018-06-25 16:30:08 -04001512#Function
1513###$
1514#include "SkBlurImageFilter.h"
1515$$$#
1516##
1517
Cary Clarkce101242017-09-01 15:51:02 -04001518void draw(SkCanvas* canvas) {
1519 SkPaint paint, blur;
Cary Clarka560c472017-11-27 10:44:06 -05001520 blur.setImageFilter(SkBlurImageFilter::Make(3, 3, nullptr));
Cary Clarkce101242017-09-01 15:51:02 -04001521 canvas->saveLayer(nullptr, &blur);
1522 SkRect rect = { 25, 25, 50, 50};
1523 canvas->drawRect(rect, paint);
1524 canvas->translate(50, 50);
1525 paint.setColor(SK_ColorRED);
1526 canvas->drawRect(rect, paint);
1527 canvas->restore();
1528}
1529##
1530
Cary Clark2ade9972017-11-02 17:49:34 -04001531#SeeAlso save() restore() saveLayer saveLayerPreserveLCDTextRequests saveLayerAlpha SaveLayerRec
Cary Clarkce101242017-09-01 15:51:02 -04001532
1533##
1534
Herb Derbyefe39bc2018-05-01 17:06:20 -04001535#Method int saveLayer(const SkRect& bounds, const SkPaint* paint)
Cary Clarkce101242017-09-01 15:51:02 -04001536
Cary Clarkab2621d2018-01-30 10:08:57 -05001537#In Layer
Cary Clarkce101242017-09-01 15:51:02 -04001538Saves Matrix, Clip, and Draw_Filter (Draw_Filter deprecated on most platforms),
1539and allocates a Bitmap for subsequent drawing.
1540Calling restore() discards changes to Matrix, Clip, and Draw_Filter,
1541and draws the Bitmap.
1542
1543Matrix may be changed by translate(), scale(), rotate(), skew(), concat(),
1544setMatrix, and resetMatrix. Clip may be changed by clipRect, clipRRect,
1545clipPath, clipRegion.
1546
1547Rect bounds suggests but does not define the Layer size. To clip drawing to
1548a specific rectangle, use clipRect.
1549
1550Optional Paint paint applies Color_Alpha, Color_Filter, Image_Filter, and
1551Blend_Mode when restore() is called.
1552
1553Call restoreToCount with returned value to restore this and subsequent saves.
1554
1555#Param bounds hint to limit the size of Layer; may be nullptr ##
1556#Param paint graphics state for Layer; may be nullptr ##
1557
1558#Return depth of saved stack ##
1559
1560#Example
1561#Description
1562Rectangles are blurred by Image_Filter when restore() draws Layer to main Canvas.
Herb Derbyefe39bc2018-05-01 17:06:20 -04001563The red rectangle is clipped; it does not fully fit on Layer.
Cary Clarkce101242017-09-01 15:51:02 -04001564Image_Filter blurs past edge of Layer so red rectangle is blurred on all sides.
1565##
1566#Height 128
Cary Clark81abc432018-06-25 16:30:08 -04001567#Function
1568###$
1569#include "SkBlurImageFilter.h"
1570$$$#
1571##
1572
Cary Clarkce101242017-09-01 15:51:02 -04001573void draw(SkCanvas* canvas) {
1574 SkPaint paint, blur;
Cary Clarka560c472017-11-27 10:44:06 -05001575 blur.setImageFilter(SkBlurImageFilter::Make(3, 3, nullptr));
Cary Clarkce101242017-09-01 15:51:02 -04001576 canvas->saveLayer(SkRect::MakeWH(90, 90), &blur);
1577 SkRect rect = { 25, 25, 50, 50};
1578 canvas->drawRect(rect, paint);
1579 canvas->translate(50, 50);
1580 paint.setColor(SK_ColorRED);
1581 canvas->drawRect(rect, paint);
1582 canvas->restore();
1583}
1584##
1585
Cary Clark2ade9972017-11-02 17:49:34 -04001586#SeeAlso save() restore() saveLayerPreserveLCDTextRequests saveLayerAlpha SaveLayerRec
Cary Clarkce101242017-09-01 15:51:02 -04001587
1588##
1589
1590#Method int saveLayerPreserveLCDTextRequests(const SkRect* bounds, const SkPaint* paint)
1591
Cary Clarkab2621d2018-01-30 10:08:57 -05001592#In Layer
1593#Line # saves Clip and Matrix on stack; creates Layer for LCD text ##
Cary Clarkce101242017-09-01 15:51:02 -04001594Saves Matrix, Clip, and Draw_Filter (Draw_Filter deprecated on most platforms),
1595and allocates a Bitmap for subsequent drawing.
1596LCD_Text is preserved when the Layer is drawn to the prior Layer.
1597
1598Calling restore() discards changes to Matrix, Clip, and Draw_Filter,
1599and draws Layer.
1600
1601Matrix may be changed by translate(), scale(), rotate(), skew(), concat(),
1602setMatrix, and resetMatrix. Clip may be changed by clipRect, clipRRect,
1603clipPath, clipRegion.
Herb Derbyefe39bc2018-05-01 17:06:20 -04001604
Cary Clarkce101242017-09-01 15:51:02 -04001605Rect bounds suggests but does not define the Layer size. To clip drawing to
1606a specific rectangle, use clipRect.
1607
1608Optional Paint paint applies Color_Alpha, Color_Filter, Image_Filter, and
1609Blend_Mode when restore() is called.
1610
1611Call restoreToCount with returned value to restore this and subsequent saves.
1612
1613Draw text on an opaque background so that LCD_Text blends correctly with the
1614prior Layer. LCD_Text drawn on a background with transparency may result in
Cary Clark6fc50412017-09-21 12:31:06 -04001615incorrect blending.
Cary Clarkce101242017-09-01 15:51:02 -04001616
1617#Param bounds hint to limit the size of Layer; may be nullptr ##
1618#Param paint graphics state for Layer; may be nullptr ##
1619
1620#Return depth of saved stack ##
1621
1622#Example
1623 SkPaint paint;
1624 paint.setAntiAlias(true);
1625 paint.setLCDRenderText(true);
1626 paint.setTextSize(20);
1627 for (auto preserve : { false, true } ) {
1628 preserve ? canvas->saveLayerPreserveLCDTextRequests(nullptr, nullptr)
1629 : canvas->saveLayer(nullptr, nullptr);
1630 SkPaint p;
1631 p.setColor(SK_ColorWHITE);
1632 // Comment out the next line to draw on a non-opaque background.
1633 canvas->drawRect(SkRect::MakeLTRB(25, 40, 200, 70), p);
1634 canvas->drawString("Hamburgefons", 30, 60, paint);
1635
1636 p.setColor(0xFFCCCCCC);
1637 canvas->drawRect(SkRect::MakeLTRB(25, 70, 200, 100), p);
1638 canvas->drawString("Hamburgefons", 30, 90, paint);
1639
1640 canvas->restore();
1641 canvas->translate(0, 80);
1642 }
1643 ##
1644
Cary Clark2ade9972017-11-02 17:49:34 -04001645#SeeAlso save() restore() saveLayer saveLayerAlpha SaveLayerRec
Cary Clarkce101242017-09-01 15:51:02 -04001646
1647##
1648
1649#Method int saveLayerAlpha(const SkRect* bounds, U8CPU alpha)
1650
Cary Clarkab2621d2018-01-30 10:08:57 -05001651#In Layer
1652#Line # saves Clip and Matrix on stack; creates Layer; sets opacity ##
Cary Clarkce101242017-09-01 15:51:02 -04001653Saves Matrix, Clip, and Draw_Filter (Draw_Filter deprecated on most platforms),
1654and allocates Bitmap for subsequent drawing.
1655
1656Calling restore() discards changes to Matrix, Clip, and Draw_Filter,
1657and blends Layer with alpha opacity onto prior Layer.
1658
1659Matrix may be changed by translate(), scale(), rotate(), skew(), concat(),
1660setMatrix, and resetMatrix. Clip may be changed by clipRect, clipRRect,
1661clipPath, clipRegion.
1662
1663Rect bounds suggests but does not define Layer size. To clip drawing to
1664a specific rectangle, use clipRect.
1665
1666alpha of zero is fully transparent, 255 is fully opaque.
1667
1668Call restoreToCount with returned value to restore this and subsequent saves.
1669
1670#Param bounds hint to limit the size of Layer; may be nullptr ##
1671#Param alpha opacity of Layer ##
1672
1673#Return depth of saved stack ##
1674
1675#Example
1676 SkPaint paint;
1677 paint.setColor(SK_ColorRED);
1678 canvas->drawCircle(50, 50, 50, paint);
1679 canvas->saveLayerAlpha(nullptr, 128);
1680 paint.setColor(SK_ColorBLUE);
1681 canvas->drawCircle(100, 50, 50, paint);
1682 paint.setColor(SK_ColorGREEN);
1683 paint.setAlpha(128);
1684 canvas->drawCircle(75, 90, 50, paint);
1685 canvas->restore();
1686##
1687
Cary Clark2ade9972017-11-02 17:49:34 -04001688#SeeAlso save() restore() saveLayer saveLayerPreserveLCDTextRequests SaveLayerRec
Cary Clarkce101242017-09-01 15:51:02 -04001689
1690##
1691
Cary Clarkd98f78c2018-04-26 08:32:37 -04001692#Enum SaveLayerFlagsSet
Cary Clark08895c42018-02-01 09:37:32 -05001693#Line # sets SaveLayerRec options ##
Cary Clarkce101242017-09-01 15:51:02 -04001694#Code
Cary Clarkd98f78c2018-04-26 08:32:37 -04001695 enum SaveLayerFlagsSet {
Cary Clarkce101242017-09-01 15:51:02 -04001696 kPreserveLCDText_SaveLayerFlag = 1 << 1,
1697 kInitWithPrevious_SaveLayerFlag = 1 << 2,
Mike Reed910ca0f2018-04-25 13:04:05 -04001698 kMaskAgainstCoverage_EXPERIMENTAL_DONT_USE_SaveLayerFlag = 1 << 3,
Cary Clarkce101242017-09-01 15:51:02 -04001699 kDontClipToLayer_Legacy_SaveLayerFlag = kDontClipToLayer_PrivateSaveLayerFlag,
1700 };
Cary Clarkd98f78c2018-04-26 08:32:37 -04001701
1702 typedef uint32_t SaveLayerFlags;
Cary Clarkce101242017-09-01 15:51:02 -04001703##
1704
Cary Clark682c58d2018-05-16 07:07:07 -04001705
1706#Typedef uint32_t SaveLayerFlags
1707#Line # options for SaveLayerRec ##
Cary Clark137b8742018-05-30 09:21:49 -04001708##
Cary Clark682c58d2018-05-16 07:07:07 -04001709
Cary Clarkce101242017-09-01 15:51:02 -04001710SaveLayerFlags provides options that may be used in any combination in SaveLayerRec,
Cary Clark682c58d2018-05-16 07:07:07 -04001711defining how Layer allocated by saveLayer operates. It may be set to zero,
1712kPreserveLCDText_SaveLayerFlag, kInitWithPrevious_SaveLayerFlag, or both flags.
1713
Cary Clarkce101242017-09-01 15:51:02 -04001714#Const kPreserveLCDText_SaveLayerFlag 2
Cary Clark682c58d2018-05-16 07:07:07 -04001715#Line # creates Layer for LCD text ##
Cary Clarkce101242017-09-01 15:51:02 -04001716 Creates Layer for LCD text. Flag is ignored if Layer Paint contains
1717 Image_Filter or Color_Filter.
1718##
1719
1720#Const kInitWithPrevious_SaveLayerFlag 4
Cary Clark682c58d2018-05-16 07:07:07 -04001721#Line # initializes with previous contents ##
Cary Clarkce101242017-09-01 15:51:02 -04001722 Initializes Layer with the contents of the previous Layer.
1723##
1724
Mike Reed910ca0f2018-04-25 13:04:05 -04001725#Const kMaskAgainstCoverage_EXPERIMENTAL_DONT_USE_SaveLayerFlag 8
Cary Clark682c58d2018-05-16 07:07:07 -04001726#Experimental do not use
Mike Reed910ca0f2018-04-25 13:04:05 -04001727##
1728
Cary Clarkce101242017-09-01 15:51:02 -04001729#Const kDontClipToLayer_Legacy_SaveLayerFlag 0x80000000
Cary Clark4855f782018-02-06 09:41:53 -05001730#Deprecated soon
Cary Clarkce101242017-09-01 15:51:02 -04001731##
1732
1733#Example
1734#Height 160
1735#Description
1736Canvas Layer captures red and blue circles scaled up by four.
Herb Derbyefe39bc2018-05-01 17:06:20 -04001737scalePaint blends Layer back with transparency.
Cary Clarkce101242017-09-01 15:51:02 -04001738##
1739void draw(SkCanvas* canvas) {
1740 SkPaint redPaint, bluePaint, scalePaint;
1741 redPaint.setColor(SK_ColorRED);
1742 canvas->drawCircle(21, 21, 8, redPaint);
1743 bluePaint.setColor(SK_ColorBLUE);
1744 canvas->drawCircle(31, 21, 8, bluePaint);
1745 SkMatrix matrix;
1746 matrix.setScale(4, 4);
1747 scalePaint.setAlpha(0x40);
1748 scalePaint.setImageFilter(
1749 SkImageFilter::MakeMatrixFilter(matrix, kNone_SkFilterQuality, nullptr));
1750 SkCanvas::SaveLayerRec saveLayerRec(nullptr, &scalePaint,
Herb Derbyefe39bc2018-05-01 17:06:20 -04001751 SkCanvas::kInitWithPrevious_SaveLayerFlag);
Cary Clarkce101242017-09-01 15:51:02 -04001752 canvas->saveLayer(saveLayerRec);
1753 canvas->restore();
1754}
1755##
1756
Cary Clark2ade9972017-11-02 17:49:34 -04001757#SeeAlso save() restore() saveLayer saveLayerPreserveLCDTextRequests saveLayerAlpha SaveLayerRec
Cary Clarkce101242017-09-01 15:51:02 -04001758
1759#Enum ##
1760
Cary Clark682c58d2018-05-16 07:07:07 -04001761#Subtopic SaveLayerRec
1762#Line # contains the state used to create the Layer ##
Cary Clarka560c472017-11-27 10:44:06 -05001763
Cary Clarkce101242017-09-01 15:51:02 -04001764#Struct SaveLayerRec
Cary Clark08895c42018-02-01 09:37:32 -05001765#Line # contains the state used to create the Layer ##
Cary Clark682c58d2018-05-16 07:07:07 -04001766
Cary Clarkce101242017-09-01 15:51:02 -04001767#Code
1768 struct SaveLayerRec {
1769 SaveLayerRec*(...
1770
1771 const SkRect* fBounds;
1772 const SkPaint* fPaint;
1773 const SkImageFilter* fBackdrop;
1774 SaveLayerFlags fSaveLayerFlags;
1775 };
1776##
1777
Cary Clark137b8742018-05-30 09:21:49 -04001778SaveLayerRec contains the state used to create the Layer.
1779
Cary Clark682c58d2018-05-16 07:07:07 -04001780#Subtopic Overview
1781#Populate
1782##
1783
1784#Subtopic Member
1785#Populate
1786##
Cary Clarkce101242017-09-01 15:51:02 -04001787
1788#Member const SkRect* fBounds
Cary Clark682c58d2018-05-16 07:07:07 -04001789#Line # hints at Layer size limit ##
Cary Clarkce101242017-09-01 15:51:02 -04001790 fBounds is used as a hint to limit the size of Layer; may be nullptr.
1791 fBounds suggests but does not define Layer size. To clip drawing to
1792 a specific rectangle, use clipRect.
1793##
1794
1795#Member const SkPaint* fPaint
Cary Clark682c58d2018-05-16 07:07:07 -04001796#Line # modifies overlay ##
Cary Clarkce101242017-09-01 15:51:02 -04001797 fPaint modifies how Layer overlays the prior Layer; may be nullptr.
1798 Color_Alpha, Blend_Mode, Color_Filter, Draw_Looper, Image_Filter, and
1799 Mask_Filter affect Layer draw.
1800##
1801
1802#Member const SkImageFilter* fBackdrop
Cary Clark682c58d2018-05-16 07:07:07 -04001803#Line # applies Image_Filter to prior Layer ##
Cary Clarkce101242017-09-01 15:51:02 -04001804 fBackdrop applies Image_Filter to the prior Layer when copying to the Layer;
1805 may be nullptr. Use kInitWithPrevious_SaveLayerFlag to copy the
1806 prior Layer without an Image_Filter.
1807##
1808
1809#Member const SkImage* fClipMask
Cary Clark682c58d2018-05-16 07:07:07 -04001810#Line # clips Layer with Mask_Alpha ##
Cary Clarkce101242017-09-01 15:51:02 -04001811 restore() clips Layer by the Color_Alpha channel of fClipMask when
1812 Layer is copied to Device. fClipMask may be nullptr. .
1813##
1814
1815#Member const SkMatrix* fClipMatrix
Cary Clark682c58d2018-05-16 07:07:07 -04001816#Line # transforms Mask_Alpha used to clip ##
Herb Derbyefe39bc2018-05-01 17:06:20 -04001817 fClipMatrix transforms fClipMask before it clips Layer. If
Cary Clarkce101242017-09-01 15:51:02 -04001818 fClipMask describes a translucent gradient, it may be scaled and rotated
1819 without introducing artifacts. fClipMatrix may be nullptr.
1820##
1821
1822#Member SaveLayerFlags fSaveLayerFlags
Cary Clark682c58d2018-05-16 07:07:07 -04001823#Line # preserves LCD Text, creates with prior Layer contents ##
Cary Clarkce101242017-09-01 15:51:02 -04001824 fSaveLayerFlags are used to create Layer without transparency,
1825 create Layer for LCD text, and to create Layer with the
1826 contents of the previous Layer.
1827##
1828
1829#Example
1830#Height 160
1831#Description
Cary Clarkffb3d682018-05-17 12:17:28 -04001832Canvas Layer captures a red Anti_Aliased circle and a blue Aliased circle scaled
Cary Clarkce101242017-09-01 15:51:02 -04001833up by four. After drawing another red circle without scaling on top, the Layer is
Herb Derbyefe39bc2018-05-01 17:06:20 -04001834transferred to the main canvas.
Cary Clarkce101242017-09-01 15:51:02 -04001835##
1836void draw(SkCanvas* canvas) {
1837 SkPaint redPaint, bluePaint;
1838 redPaint.setAntiAlias(true);
1839 redPaint.setColor(SK_ColorRED);
1840 canvas->drawCircle(21, 21, 8, redPaint);
1841 bluePaint.setColor(SK_ColorBLUE);
1842 canvas->drawCircle(31, 21, 8, bluePaint);
1843 SkMatrix matrix;
1844 matrix.setScale(4, 4);
1845 auto scaler = SkImageFilter::MakeMatrixFilter(matrix, kNone_SkFilterQuality, nullptr);
Herb Derbyefe39bc2018-05-01 17:06:20 -04001846 SkCanvas::SaveLayerRec saveLayerRec(nullptr, nullptr, scaler.get(), 0);
Cary Clarkce101242017-09-01 15:51:02 -04001847 canvas->saveLayer(saveLayerRec);
1848 canvas->drawCircle(125, 85, 8, redPaint);
1849 canvas->restore();
1850}
1851##
1852
Cary Clark682c58d2018-05-16 07:07:07 -04001853#Subtopic Constructor
1854#Populate
1855##
Cary Clarkce101242017-09-01 15:51:02 -04001856
Cary Clark682c58d2018-05-16 07:07:07 -04001857#Method SaveLayerRec()
1858#Line # constructs SaveLayerRec ##
Cary Clarkce101242017-09-01 15:51:02 -04001859Sets fBounds, fPaint, and fBackdrop to nullptr. Clears fSaveLayerFlags.
1860
1861#Return empty SaveLayerRec ##
1862
1863#Example
1864 SkCanvas::SaveLayerRec rec1;
Mike Kleine083f7c2018-02-07 12:54:27 -05001865 rec1.fSaveLayerFlags = SkCanvas::kPreserveLCDText_SaveLayerFlag;
1866 SkCanvas::SaveLayerRec rec2(nullptr, nullptr, SkCanvas::kPreserveLCDText_SaveLayerFlag);
Cary Clarkce101242017-09-01 15:51:02 -04001867 SkDebugf("rec1 %c= rec2\n", rec1.fBounds == rec2.fBounds
1868 && rec1.fPaint == rec2.fPaint
1869 && rec1.fBackdrop == rec2.fBackdrop
1870 && rec1.fSaveLayerFlags == rec2.fSaveLayerFlags ? '=' : '!');
1871 #StdOut
1872 rec1 == rec2
1873 ##
1874##
1875
Cary Clark2ade9972017-11-02 17:49:34 -04001876#SeeAlso save() restore() saveLayer saveLayerPreserveLCDTextRequests saveLayerAlpha
1877
Cary Clarkce101242017-09-01 15:51:02 -04001878##
1879
Cary Clark224c7002018-06-27 11:00:21 -04001880#Method SaveLayerRec(const SkRect* bounds, const SkPaint* paint, SaveLayerFlags saveLayerFlags = 0)
Cary Clarkce101242017-09-01 15:51:02 -04001881
1882Sets fBounds, fPaint, and fSaveLayerFlags; sets fBackdrop to nullptr.
1883
1884#Param bounds Layer dimensions; may be nullptr ##
1885#Param paint applied to Layer when overlaying prior Layer; may be nullptr ##
1886#Param saveLayerFlags SaveLayerRec options to modify Layer ##
1887
1888#Return SaveLayerRec with empty backdrop ##
1889
1890#Example
1891 SkCanvas::SaveLayerRec rec1;
1892 SkCanvas::SaveLayerRec rec2(nullptr, nullptr);
1893 SkDebugf("rec1 %c= rec2\n", rec1.fBounds == rec2.fBounds
1894 && rec1.fPaint == rec2.fPaint
1895 && rec1.fBackdrop == rec2.fBackdrop
1896 && rec1.fSaveLayerFlags == rec2.fSaveLayerFlags ? '=' : '!');
1897 #StdOut
1898 rec1 == rec2
1899 ##
1900##
1901
Cary Clark2ade9972017-11-02 17:49:34 -04001902#SeeAlso save() restore() saveLayer saveLayerPreserveLCDTextRequests saveLayerAlpha
1903
Cary Clarkce101242017-09-01 15:51:02 -04001904##
1905
1906#Method SaveLayerRec(const SkRect* bounds, const SkPaint* paint, const SkImageFilter* backdrop,
1907 SaveLayerFlags saveLayerFlags)
1908
1909Sets fBounds, fPaint, fBackdrop, and fSaveLayerFlags.
1910
1911#Param bounds Layer dimensions; may be nullptr ##
1912#Param paint applied to Layer when overlaying prior Layer;
1913 may be nullptr
1914##
1915#Param backdrop prior Layer copied with Image_Filter; may be nullptr
1916##
1917#Param saveLayerFlags SaveLayerRec options to modify Layer ##
1918
1919#Return SaveLayerRec fully specified ##
1920
1921#Example
1922 SkCanvas::SaveLayerRec rec1;
1923 SkCanvas::SaveLayerRec rec2(nullptr, nullptr, nullptr, 0);
1924 SkDebugf("rec1 %c= rec2\n", rec1.fBounds == rec2.fBounds
1925 && rec1.fPaint == rec2.fPaint
1926 && rec1.fBackdrop == rec2.fBackdrop
1927 && rec1.fSaveLayerFlags == rec2.fSaveLayerFlags ? '=' : '!');
1928 #StdOut
1929 rec1 == rec2
1930 ##
1931##
1932
Cary Clark2ade9972017-11-02 17:49:34 -04001933#SeeAlso save() restore() saveLayer saveLayerPreserveLCDTextRequests saveLayerAlpha
1934
Cary Clarkce101242017-09-01 15:51:02 -04001935##
1936
1937#Method SaveLayerRec(const SkRect* bounds, const SkPaint* paint, const SkImageFilter* backdrop,
1938 const SkImage* clipMask, const SkMatrix* clipMatrix,
1939 SaveLayerFlags saveLayerFlags)
1940
Cary Clark682c58d2018-05-16 07:07:07 -04001941#Experimental not ready
Cary Clarkce101242017-09-01 15:51:02 -04001942
1943Sets fBounds, fPaint, fBackdrop, fClipMask, fClipMatrix, and fSaveLayerFlags.
1944clipMatrix uses Color_Alpha channel of image, transformed by clipMatrix, to clip
1945Layer when drawn to Canvas.
1946
Cary Clark2ade9972017-11-02 17:49:34 -04001947Implementation is not complete; has no effect if Device is GPU-backed.
Cary Clarkce101242017-09-01 15:51:02 -04001948
1949#Param bounds Layer dimensions; may be nullptr ##
1950#Param paint graphics state applied to Layer when overlaying prior
1951 Layer; may be nullptr
1952##
1953#Param backdrop prior Layer copied with Image_Filter;
1954 may be nullptr
1955##
1956#Param clipMask clip applied to Layer; may be nullptr ##
1957#Param clipMatrix matrix applied to clipMask; may be nullptr to use
Herb Derbyefe39bc2018-05-01 17:06:20 -04001958 identity matrix
Cary Clarkce101242017-09-01 15:51:02 -04001959##
1960#Param saveLayerFlags SaveLayerRec options to modify Layer ##
1961
1962#Return SaveLayerRec fully specified ##
1963
Cary Clark2ade9972017-11-02 17:49:34 -04001964#SeeAlso save() restore() saveLayer saveLayerPreserveLCDTextRequests saveLayerAlpha
Cary Clarkce101242017-09-01 15:51:02 -04001965
1966##
1967
1968#Struct ##
1969
Cary Clark682c58d2018-05-16 07:07:07 -04001970#Subtopic ##
1971
Cary Clarkce101242017-09-01 15:51:02 -04001972#Method int saveLayer(const SaveLayerRec& layerRec)
1973
Cary Clarkab2621d2018-01-30 10:08:57 -05001974#In Layer
Cary Clarkce101242017-09-01 15:51:02 -04001975Saves Matrix, Clip, and Draw_Filter (Draw_Filter deprecated on most platforms),
1976and allocates Bitmap for subsequent drawing.
1977
1978Calling restore() discards changes to Matrix, Clip, and Draw_Filter,
1979and blends Bitmap with Color_Alpha opacity onto the prior Layer.
1980
1981Matrix may be changed by translate(), scale(), rotate(), skew(), concat(),
1982setMatrix, and resetMatrix. Clip may be changed by clipRect, clipRRect,
1983clipPath, clipRegion.
1984
1985SaveLayerRec contains the state used to create the Layer.
1986
1987Call restoreToCount with returned value to restore this and subsequent saves.
1988
1989#Param layerRec Layer state ##
1990
1991#Return depth of save state stack ##
1992
1993#Example
1994#Description
1995The example draws an image, and saves it into a Layer with kInitWithPrevious_SaveLayerFlag.
1996Next it punches a hole in Layer and restore with SkBlendMode::kPlus.
1997Where Layer was cleared, the original image will draw unchanged.
1998Outside of the circle the mandrill is brightened.
1999##
2000 #Image 3
Hal Canaryc465d132017-12-08 10:21:31 -05002001 // sk_sp<SkImage> image = GetResourceAsImage("images/mandrill_256.png");
Cary Clarkce101242017-09-01 15:51:02 -04002002 canvas->drawImage(image, 0, 0, nullptr);
2003 SkCanvas::SaveLayerRec rec;
2004 SkPaint paint;
2005 paint.setBlendMode(SkBlendMode::kPlus);
2006 rec.fSaveLayerFlags = SkCanvas::kInitWithPrevious_SaveLayerFlag;
2007 rec.fPaint = &paint;
2008 canvas->saveLayer(rec);
2009 paint.setBlendMode(SkBlendMode::kClear);
2010 canvas->drawCircle(128, 128, 96, paint);
2011 canvas->restore();
2012##
2013
2014#ToDo above example needs to replace GetResourceAsImage with way to select image in fiddle ##
2015
Cary Clark2ade9972017-11-02 17:49:34 -04002016#SeeAlso save() restore() saveLayer saveLayerPreserveLCDTextRequests saveLayerAlpha
2017
Cary Clarkce101242017-09-01 15:51:02 -04002018##
2019
Cary Clark08895c42018-02-01 09:37:32 -05002020#Subtopic Layer ##
Cary Clarkce101242017-09-01 15:51:02 -04002021
2022# ------------------------------------------------------------------------------
Cary Clark08895c42018-02-01 09:37:32 -05002023#Subtopic Matrix
2024#Line # coordinate transformation ##
Cary Clark8032b982017-07-28 11:04:54 -04002025
2026#Method void translate(SkScalar dx, SkScalar dy)
2027
Cary Clarkab2621d2018-01-30 10:08:57 -05002028#In Matrix
2029#Line # translates Matrix ##
Cary Clark8032b982017-07-28 11:04:54 -04002030Translate Matrix by dx along the x-axis and dy along the y-axis.
2031
2032Mathematically, replace Matrix with a translation matrix
Herb Derbyefe39bc2018-05-01 17:06:20 -04002033Premultiplied with Matrix.
Cary Clark8032b982017-07-28 11:04:54 -04002034
2035This has the effect of moving the drawing by (dx, dy) before transforming
2036the result with Matrix.
2037
Cary Clarkbad5ad72017-08-03 17:14:08 -04002038#Param dx distance to translate in x ##
2039#Param dy distance to translate in y ##
Cary Clark8032b982017-07-28 11:04:54 -04002040
2041#Example
2042#Height 128
2043#Description
2044scale() followed by translate() produces different results from translate() followed
Herb Derbyefe39bc2018-05-01 17:06:20 -04002045by scale().
Cary Clark8032b982017-07-28 11:04:54 -04002046
2047The blue stroke follows translate of (50, 50); a black
Herb Derbyefe39bc2018-05-01 17:06:20 -04002048fill follows scale of (2, 1/2.f). After restoring the clip, which resets
Cary Clark8032b982017-07-28 11:04:54 -04002049Matrix, a red frame follows the same scale of (2, 1/2.f); a gray fill
2050follows translate of (50, 50).
2051##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002052void draw(SkCanvas* canvas) {
2053 SkPaint filledPaint;
2054 SkPaint outlinePaint;
2055 outlinePaint.setStyle(SkPaint::kStroke_Style);
2056 outlinePaint.setColor(SK_ColorBLUE);
2057 canvas->save();
2058 canvas->translate(50, 50);
2059 canvas->drawCircle(28, 28, 15, outlinePaint); // blue center: (50+28, 50+28)
2060 canvas->scale(2, 1/2.f);
2061 canvas->drawCircle(28, 28, 15, filledPaint); // black center: (50+(28*2), 50+(28/2))
2062 canvas->restore();
2063 filledPaint.setColor(SK_ColorGRAY);
2064 outlinePaint.setColor(SK_ColorRED);
2065 canvas->scale(2, 1/2.f);
2066 canvas->drawCircle(28, 28, 15, outlinePaint); // red center: (28*2, 28/2)
2067 canvas->translate(50, 50);
2068 canvas->drawCircle(28, 28, 15, filledPaint); // gray center: ((50+28)*2, (50+28)/2)
Cary Clark8032b982017-07-28 11:04:54 -04002069}
2070##
2071
Cary Clark2ade9972017-11-02 17:49:34 -04002072#SeeAlso concat() scale() skew() rotate() setMatrix
Cary Clark8032b982017-07-28 11:04:54 -04002073
2074##
2075
2076# ------------------------------------------------------------------------------
2077
2078#Method void scale(SkScalar sx, SkScalar sy)
2079
Cary Clarkab2621d2018-01-30 10:08:57 -05002080#In Matrix
2081#Line # scales Matrix ##
Cary Clark8032b982017-07-28 11:04:54 -04002082Scale Matrix by sx on the x-axis and sy on the y-axis.
2083
2084Mathematically, replace Matrix with a scale matrix
Herb Derbyefe39bc2018-05-01 17:06:20 -04002085Premultiplied with Matrix.
Cary Clark8032b982017-07-28 11:04:54 -04002086
2087This has the effect of scaling the drawing by (sx, sy) before transforming
2088the result with Matrix.
2089
Cary Clarkbad5ad72017-08-03 17:14:08 -04002090#Param sx amount to scale in x ##
2091#Param sy amount to scale in y ##
Cary Clark8032b982017-07-28 11:04:54 -04002092
2093#Example
2094#Height 160
Cary Clarkbad5ad72017-08-03 17:14:08 -04002095void draw(SkCanvas* canvas) {
2096 SkPaint paint;
2097 SkRect rect = { 10, 20, 60, 120 };
2098 canvas->translate(20, 20);
2099 canvas->drawRect(rect, paint);
2100 canvas->scale(2, .5f);
2101 paint.setColor(SK_ColorGRAY);
2102 canvas->drawRect(rect, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002103}
2104##
2105
Cary Clark2ade9972017-11-02 17:49:34 -04002106#SeeAlso concat() translate() skew() rotate() setMatrix
Cary Clark8032b982017-07-28 11:04:54 -04002107
2108##
2109
2110# ------------------------------------------------------------------------------
2111
2112#Method void rotate(SkScalar degrees)
2113
Cary Clarkab2621d2018-01-30 10:08:57 -05002114#In Matrix
2115#Line # rotates Matrix ##
Cary Clark8032b982017-07-28 11:04:54 -04002116Rotate Matrix by degrees. Positive degrees rotates clockwise.
2117
2118Mathematically, replace Matrix with a rotation matrix
Herb Derbyefe39bc2018-05-01 17:06:20 -04002119Premultiplied with Matrix.
Cary Clark8032b982017-07-28 11:04:54 -04002120
2121This has the effect of rotating the drawing by degrees before transforming
2122the result with Matrix.
2123
Cary Clarkbad5ad72017-08-03 17:14:08 -04002124#Param degrees amount to rotate, in degrees ##
Cary Clark8032b982017-07-28 11:04:54 -04002125
2126#Example
2127#Description
2128Draw clock hands at time 5:10. The hour hand and minute hand point up and
2129are rotated clockwise.
2130##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002131void draw(SkCanvas* canvas) {
2132 SkPaint paint;
2133 paint.setStyle(SkPaint::kStroke_Style);
2134 canvas->translate(128, 128);
2135 canvas->drawCircle(0, 0, 60, paint);
2136 canvas->save();
2137 canvas->rotate(10 * 360 / 60); // 10 minutes of 60 scaled to 360 degrees
Herb Derbyefe39bc2018-05-01 17:06:20 -04002138 canvas->drawLine(0, 0, 0, -50, paint);
Cary Clarkbad5ad72017-08-03 17:14:08 -04002139 canvas->restore();
2140 canvas->rotate((5 + 10.f/60) * 360 / 12); // 5 and 10/60 hours of 12 scaled to 360 degrees
2141 canvas->drawLine(0, 0, 0, -30, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002142}
2143##
2144
Cary Clark2ade9972017-11-02 17:49:34 -04002145#SeeAlso concat() translate() skew() scale() setMatrix
Cary Clark8032b982017-07-28 11:04:54 -04002146
2147##
2148
2149# ------------------------------------------------------------------------------
2150
2151#Method void rotate(SkScalar degrees, SkScalar px, SkScalar py)
2152
Cary Clarkab2621d2018-01-30 10:08:57 -05002153#In Matrix
Cary Clarkbad5ad72017-08-03 17:14:08 -04002154Rotate Matrix by degrees about a point at (px, py). Positive degrees rotates
2155clockwise.
Cary Clark8032b982017-07-28 11:04:54 -04002156
Cary Clarkce101242017-09-01 15:51:02 -04002157Mathematically, construct a rotation matrix. Premultiply the rotation matrix by
Cary Clark8032b982017-07-28 11:04:54 -04002158a translation matrix, then replace Matrix with the resulting matrix
Herb Derbyefe39bc2018-05-01 17:06:20 -04002159Premultiplied with Matrix.
Cary Clark8032b982017-07-28 11:04:54 -04002160
Cary Clarkbad5ad72017-08-03 17:14:08 -04002161This has the effect of rotating the drawing about a given point before
2162transforming the result with Matrix.
Cary Clark8032b982017-07-28 11:04:54 -04002163
Cary Clarkbad5ad72017-08-03 17:14:08 -04002164#Param degrees amount to rotate, in degrees ##
Cary Clark5538c132018-06-14 12:28:14 -04002165#Param px x-axis value of the point to rotate about ##
2166#Param py y-axis value of the point to rotate about ##
Cary Clark8032b982017-07-28 11:04:54 -04002167
2168#Example
2169#Height 192
Cary Clarkbad5ad72017-08-03 17:14:08 -04002170void draw(SkCanvas* canvas) {
2171 SkPaint paint;
2172 paint.setTextSize(96);
2173 canvas->drawString("A1", 130, 100, paint);
2174 canvas->rotate(180, 130, 100);
2175 canvas->drawString("A1", 130, 100, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002176}
2177##
2178
Cary Clark2ade9972017-11-02 17:49:34 -04002179#SeeAlso concat() translate() skew() scale() setMatrix
Cary Clark8032b982017-07-28 11:04:54 -04002180
2181##
2182
2183# ------------------------------------------------------------------------------
2184
2185#Method void skew(SkScalar sx, SkScalar sy)
2186
Cary Clarkab2621d2018-01-30 10:08:57 -05002187#In Matrix
2188#Line # skews Matrix ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002189Skew 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 -04002190skews the drawing right as y-axis values increase; a positive value of sy skews
2191the drawing down as x-axis values increase.
Cary Clark8032b982017-07-28 11:04:54 -04002192
Herb Derbyefe39bc2018-05-01 17:06:20 -04002193Mathematically, replace Matrix with a skew matrix Premultiplied with Matrix.
Cary Clark8032b982017-07-28 11:04:54 -04002194
Cary Clarkbad5ad72017-08-03 17:14:08 -04002195This has the effect of skewing the drawing by (sx, sy) before transforming
Cary Clark8032b982017-07-28 11:04:54 -04002196the result with Matrix.
2197
Cary Clark5538c132018-06-14 12:28:14 -04002198#Param sx amount to skew on x-axis ##
2199#Param sy amount to skew on y-axis ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002200
Cary Clark8032b982017-07-28 11:04:54 -04002201#Example
Herb Derbyefe39bc2018-05-01 17:06:20 -04002202 #Description
Cary Clark5538c132018-06-14 12:28:14 -04002203 Black text mimics an oblique text style by using a negative skew on x-axis
2204 that shifts the geometry to the right as the y-axis values decrease.
2205 Red text uses a positive skew on y-axis to shift the geometry down
2206 as the x-axis values increase.
2207 Blue text combines sx and sy skew to rotate and scale.
Cary Clark8032b982017-07-28 11:04:54 -04002208 ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002209 SkPaint paint;
2210 paint.setTextSize(128);
2211 canvas->translate(30, 130);
2212 canvas->save();
2213 canvas->skew(-.5, 0);
2214 canvas->drawString("A1", 0, 0, paint);
2215 canvas->restore();
2216 canvas->save();
2217 canvas->skew(0, .5);
2218 paint.setColor(SK_ColorRED);
2219 canvas->drawString("A1", 0, 0, paint);
2220 canvas->restore();
2221 canvas->skew(-.5, .5);
2222 paint.setColor(SK_ColorBLUE);
Cary Clark8032b982017-07-28 11:04:54 -04002223 canvas->drawString("A1", 0, 0, paint);
2224##
2225
Cary Clark2ade9972017-11-02 17:49:34 -04002226#SeeAlso concat() translate() rotate() scale() setMatrix
Cary Clark8032b982017-07-28 11:04:54 -04002227
2228##
2229
2230# ------------------------------------------------------------------------------
2231
2232#Method void concat(const SkMatrix& matrix)
2233
Cary Clarkab2621d2018-01-30 10:08:57 -05002234#In Matrix
2235#Line # multiplies Matrix by Matrix ##
Cary Clarkce101242017-09-01 15:51:02 -04002236Replace Matrix with matrix Premultiplied with existing Matrix.
Cary Clark8032b982017-07-28 11:04:54 -04002237
Cary Clarkbad5ad72017-08-03 17:14:08 -04002238This has the effect of transforming the drawn geometry by matrix, before
2239transforming the result with existing Matrix.
Cary Clark8032b982017-07-28 11:04:54 -04002240
Cary Clarkce101242017-09-01 15:51:02 -04002241#Param matrix matrix to Premultiply with existing Matrix ##
Cary Clark8032b982017-07-28 11:04:54 -04002242
2243#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04002244void draw(SkCanvas* canvas) {
2245 SkPaint paint;
2246 paint.setTextSize(80);
2247 paint.setTextScaleX(.3);
2248 SkMatrix matrix;
2249 SkRect rect[2] = {{ 10, 20, 90, 110 }, { 40, 130, 140, 180 }};
2250 matrix.setRectToRect(rect[0], rect[1], SkMatrix::kFill_ScaleToFit);
2251 canvas->drawRect(rect[0], paint);
2252 canvas->drawRect(rect[1], paint);
2253 paint.setColor(SK_ColorWHITE);
2254 canvas->drawString("Here", rect[0].fLeft + 10, rect[0].fBottom - 10, paint);
2255 canvas->concat(matrix);
2256 canvas->drawString("There", rect[0].fLeft + 10, rect[0].fBottom - 10, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002257}
2258##
2259
Cary Clark2ade9972017-11-02 17:49:34 -04002260#SeeAlso translate() rotate() scale() skew() setMatrix
Cary Clark8032b982017-07-28 11:04:54 -04002261
2262##
2263
2264# ------------------------------------------------------------------------------
2265
2266#Method void setMatrix(const SkMatrix& matrix)
2267
Cary Clarkab2621d2018-01-30 10:08:57 -05002268#In Matrix
2269#Line # sets Matrix ##
Cary Clark8032b982017-07-28 11:04:54 -04002270Replace Matrix with matrix.
2271Unlike concat(), any prior matrix state is overwritten.
2272
Cary Clarkbad5ad72017-08-03 17:14:08 -04002273#Param matrix matrix to copy, replacing existing Matrix ##
Cary Clark8032b982017-07-28 11:04:54 -04002274
2275#Example
2276#Height 128
Cary Clarkbad5ad72017-08-03 17:14:08 -04002277void draw(SkCanvas* canvas) {
2278 SkPaint paint;
2279 canvas->scale(4, 6);
2280 canvas->drawString("truth", 2, 10, paint);
2281 SkMatrix matrix;
2282 matrix.setScale(2.8f, 6);
2283 canvas->setMatrix(matrix);
2284 canvas->drawString("consequences", 2, 20, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002285}
2286##
2287
Cary Clark2ade9972017-11-02 17:49:34 -04002288#SeeAlso resetMatrix concat() translate() rotate() scale() skew()
Cary Clark8032b982017-07-28 11:04:54 -04002289
2290##
2291
2292# ------------------------------------------------------------------------------
2293
2294#Method void resetMatrix()
2295
Cary Clarkab2621d2018-01-30 10:08:57 -05002296#In Matrix
2297#Line # resets Matrix to identity ##
Cary Clark8032b982017-07-28 11:04:54 -04002298Sets Matrix to the identity matrix.
2299Any prior matrix state is overwritten.
2300
2301#Example
2302#Height 128
Cary Clarkbad5ad72017-08-03 17:14:08 -04002303void draw(SkCanvas* canvas) {
2304 SkPaint paint;
2305 canvas->scale(4, 6);
2306 canvas->drawString("truth", 2, 10, paint);
2307 canvas->resetMatrix();
2308 canvas->scale(2.8f, 6);
2309 canvas->drawString("consequences", 2, 20, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002310}
2311##
2312
Cary Clark2ade9972017-11-02 17:49:34 -04002313#SeeAlso setMatrix concat() translate() rotate() scale() skew()
Cary Clark8032b982017-07-28 11:04:54 -04002314
2315##
2316
2317# ------------------------------------------------------------------------------
2318
2319#Method const SkMatrix& getTotalMatrix() const
2320
Cary Clarkab2621d2018-01-30 10:08:57 -05002321#In Matrix
2322#Line # returns Matrix ##
Cary Clark8032b982017-07-28 11:04:54 -04002323Returns Matrix.
2324This does not account for translation by Device or Surface.
2325
Cary Clarkbad5ad72017-08-03 17:14:08 -04002326#Return Matrix in Canvas ##
Cary Clark8032b982017-07-28 11:04:54 -04002327
2328#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04002329 SkDebugf("isIdentity %s\n", canvas->getTotalMatrix().isIdentity() ? "true" : "false");
2330 #StdOut
2331 isIdentity true
2332 ##
Cary Clark8032b982017-07-28 11:04:54 -04002333##
2334
Cary Clark2ade9972017-11-02 17:49:34 -04002335#SeeAlso setMatrix resetMatrix concat()
Cary Clark8032b982017-07-28 11:04:54 -04002336
2337##
2338
Cary Clark08895c42018-02-01 09:37:32 -05002339#Subtopic Matrix ##
Cary Clark8032b982017-07-28 11:04:54 -04002340
2341# ------------------------------------------------------------------------------
Cary Clark08895c42018-02-01 09:37:32 -05002342#Subtopic Clip
2343#Line # stack of clipping Paths ##
Cary Clark8032b982017-07-28 11:04:54 -04002344
2345Clip is built from a stack of clipping paths. Each Path in the
Herb Derbyefe39bc2018-05-01 17:06:20 -04002346stack can be constructed from one or more Path_Contour elements. The
Cary Clark8032b982017-07-28 11:04:54 -04002347Path_Contour may be composed of any number of Path_Verb segments. Each
2348Path_Contour forms a closed area; Path_Fill_Type defines the area enclosed
2349by Path_Contour.
2350
2351Clip stack of Path elements successfully restrict the Path area. Each
Herb Derbyefe39bc2018-05-01 17:06:20 -04002352Path is transformed by Matrix, then intersected with or subtracted from the
Cary Clark8032b982017-07-28 11:04:54 -04002353prior Clip to form the replacement Clip. Use SkClipOp::kDifference
2354to subtract Path from Clip; use SkClipOp::kIntersect to intersect Path
2355with Clip.
2356
Cary Clarkffb3d682018-05-17 12:17:28 -04002357A clipping Path may be Anti_Aliased; if Path, after transformation, is
2358composed of horizontal and vertical lines, clearing Anti_Alias allows whole pixels
Cary Clarkce101242017-09-01 15:51:02 -04002359to either be inside or outside the clip. The fastest drawing has a Aliased,
2360rectangular clip.
Cary Clark8032b982017-07-28 11:04:54 -04002361
Cary Clarkffb3d682018-05-17 12:17:28 -04002362If clipping Path has Anti_Alias set, clip may partially clip a pixel, requiring
Herb Derbyefe39bc2018-05-01 17:06:20 -04002363that drawing blend partially with the destination along the edge. A rotated
Cary Clarkffb3d682018-05-17 12:17:28 -04002364rectangular Anti_Aliased clip looks smoother but draws slower.
Cary Clark8032b982017-07-28 11:04:54 -04002365
2366Clip can combine with Rect and Round_Rect primitives; like
2367Path, these are transformed by Matrix before they are combined with Clip.
2368
2369Clip can combine with Region. Region is assumed to be in Device coordinates
2370and is unaffected by Matrix.
2371
2372#Example
2373#Height 90
2374 #Description
Cary Clarkffb3d682018-05-17 12:17:28 -04002375 Draw a red circle with an Aliased clip and an Anti_Aliased clip.
Cary Clark8032b982017-07-28 11:04:54 -04002376 Use an image filter to zoom into the pixels drawn.
Cary Clarkce101242017-09-01 15:51:02 -04002377 The edge of the Aliased clip fully draws pixels in the red circle.
Cary Clarkffb3d682018-05-17 12:17:28 -04002378 The edge of the Anti_Aliased clip partially draws pixels in the red circle.
Cary Clark8032b982017-07-28 11:04:54 -04002379 ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002380 SkPaint redPaint, scalePaint;
2381 redPaint.setAntiAlias(true);
2382 redPaint.setColor(SK_ColorRED);
2383 canvas->save();
2384 for (bool antialias : { false, true } ) {
2385 canvas->save();
2386 canvas->clipRect(SkRect::MakeWH(19.5f, 11.5f), antialias);
2387 canvas->drawCircle(17, 11, 8, redPaint);
2388 canvas->restore();
2389 canvas->translate(16, 0);
2390 }
2391 canvas->restore();
2392 SkMatrix matrix;
2393 matrix.setScale(6, 6);
2394 scalePaint.setImageFilter(
2395 SkImageFilter::MakeMatrixFilter(matrix, kNone_SkFilterQuality, nullptr));
2396 SkCanvas::SaveLayerRec saveLayerRec(
Herb Derbyefe39bc2018-05-01 17:06:20 -04002397 nullptr, &scalePaint, SkCanvas::kInitWithPrevious_SaveLayerFlag);
Cary Clarkbad5ad72017-08-03 17:14:08 -04002398 canvas->saveLayer(saveLayerRec);
Cary Clark8032b982017-07-28 11:04:54 -04002399 canvas->restore();
2400##
2401
2402#Method void clipRect(const SkRect& rect, SkClipOp op, bool doAntiAlias)
2403
Cary Clarkab2621d2018-01-30 10:08:57 -05002404#In Clip
2405#Line # combines Clip with Rect ##
Cary Clark8032b982017-07-28 11:04:54 -04002406Replace Clip with the intersection or difference of Clip and rect,
Cary Clarkffb3d682018-05-17 12:17:28 -04002407with an Aliased or Anti_Aliased clip edge. rect is transformed by Matrix
Cary Clark8032b982017-07-28 11:04:54 -04002408before it is combined with Clip.
2409
Cary Clarka523d2d2017-08-30 08:58:10 -04002410#Param rect Rect to combine with Clip ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002411#Param op Clip_Op to apply to Clip ##
Cary Clarkffb3d682018-05-17 12:17:28 -04002412#Param doAntiAlias true if Clip is to be Anti_Aliased ##
Cary Clark8032b982017-07-28 11:04:54 -04002413
2414#Example
2415#Height 128
Cary Clarkbad5ad72017-08-03 17:14:08 -04002416void draw(SkCanvas* canvas) {
2417 canvas->rotate(10);
2418 SkPaint paint;
2419 paint.setAntiAlias(true);
2420 for (auto alias: { false, true } ) {
2421 canvas->save();
2422 canvas->clipRect(SkRect::MakeWH(90, 80), SkClipOp::kIntersect, alias);
2423 canvas->drawCircle(100, 60, 60, paint);
2424 canvas->restore();
2425 canvas->translate(80, 0);
2426 }
Cary Clark8032b982017-07-28 11:04:54 -04002427}
2428##
2429
Cary Clark2ade9972017-11-02 17:49:34 -04002430#SeeAlso clipRRect clipPath clipRegion
Cary Clark8032b982017-07-28 11:04:54 -04002431
2432##
2433
Herb Derbyefe39bc2018-05-01 17:06:20 -04002434#Method void clipRect(const SkRect& rect, SkClipOp op)
Cary Clark8032b982017-07-28 11:04:54 -04002435
Cary Clarkab2621d2018-01-30 10:08:57 -05002436#In Clip
Cary Clark8032b982017-07-28 11:04:54 -04002437Replace Clip with the intersection or difference of Clip and rect.
Cary Clarkce101242017-09-01 15:51:02 -04002438Resulting Clip is Aliased; pixels are fully contained by the clip.
Cary Clarkbad5ad72017-08-03 17:14:08 -04002439rect is transformed by Matrix before it is combined with Clip.
Cary Clark8032b982017-07-28 11:04:54 -04002440
Cary Clarka523d2d2017-08-30 08:58:10 -04002441#Param rect Rect to combine with Clip ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002442#Param op Clip_Op to apply to Clip ##
Cary Clark8032b982017-07-28 11:04:54 -04002443
2444#Example
2445#Height 192
2446#Width 280
Cary Clarkbad5ad72017-08-03 17:14:08 -04002447void draw(SkCanvas* canvas) {
2448 SkPaint paint;
2449 for (SkClipOp op: { SkClipOp::kIntersect, SkClipOp::kDifference } ) {
2450 canvas->save();
2451 canvas->clipRect(SkRect::MakeWH(90, 120), op, false);
2452 canvas->drawCircle(100, 100, 60, paint);
2453 canvas->restore();
2454 canvas->translate(80, 0);
2455 }
Cary Clark8032b982017-07-28 11:04:54 -04002456}
2457##
2458
Cary Clark2ade9972017-11-02 17:49:34 -04002459#SeeAlso clipRRect clipPath clipRegion
Cary Clark8032b982017-07-28 11:04:54 -04002460
2461##
2462
Herb Derbyefe39bc2018-05-01 17:06:20 -04002463#Method void clipRect(const SkRect& rect, bool doAntiAlias = false)
Cary Clark8032b982017-07-28 11:04:54 -04002464
Cary Clarkab2621d2018-01-30 10:08:57 -05002465#In Clip
Cary Clark8032b982017-07-28 11:04:54 -04002466Replace Clip with the intersection of Clip and rect.
Cary Clarkce101242017-09-01 15:51:02 -04002467Resulting Clip is Aliased; pixels are fully contained by the clip.
Cary Clark8032b982017-07-28 11:04:54 -04002468rect is transformed by Matrix
2469before it is combined with Clip.
2470
Cary Clarka523d2d2017-08-30 08:58:10 -04002471#Param rect Rect to combine with Clip ##
Cary Clarkffb3d682018-05-17 12:17:28 -04002472#Param doAntiAlias true if Clip is to be Anti_Aliased ##
Cary Clark8032b982017-07-28 11:04:54 -04002473
2474#Example
2475#Height 133
2476 #Description
Cary Clarkce101242017-09-01 15:51:02 -04002477 A circle drawn in pieces looks uniform when drawn Aliased.
Cary Clarkffb3d682018-05-17 12:17:28 -04002478 The same circle pieces blend with pixels more than once when Anti_Aliased,
Cary Clark8032b982017-07-28 11:04:54 -04002479 visible as a thin pair of lines through the right circle.
2480 ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002481void draw(SkCanvas* canvas) {
2482 canvas->clear(SK_ColorWHITE);
2483 SkPaint paint;
2484 paint.setAntiAlias(true);
2485 paint.setColor(0x8055aaff);
2486 SkRect clipRect = { 0, 0, 87.4f, 87.4f };
2487 for (auto alias: { false, true } ) {
2488 canvas->save();
2489 canvas->clipRect(clipRect, SkClipOp::kIntersect, alias);
2490 canvas->drawCircle(67, 67, 60, paint);
2491 canvas->restore();
2492 canvas->save();
2493 canvas->clipRect(clipRect, SkClipOp::kDifference, alias);
2494 canvas->drawCircle(67, 67, 60, paint);
2495 canvas->restore();
2496 canvas->translate(120, 0);
2497 }
Cary Clark8032b982017-07-28 11:04:54 -04002498}
2499##
2500
Cary Clark2ade9972017-11-02 17:49:34 -04002501#SeeAlso clipRRect clipPath clipRegion
Cary Clark8032b982017-07-28 11:04:54 -04002502
2503##
2504
2505#Method void androidFramework_setDeviceClipRestriction(const SkIRect& rect)
2506
Cary Clarkab2621d2018-01-30 10:08:57 -05002507#In Clip
Cary Clark682c58d2018-05-16 07:07:07 -04002508#Line # exists for use by Android framework ##
Cary Clarkce101242017-09-01 15:51:02 -04002509Sets the maximum clip rectangle, which can be set by clipRect, clipRRect and
Cary Clark8032b982017-07-28 11:04:54 -04002510clipPath and intersect the current clip with the specified rect.
Cary Clarkce101242017-09-01 15:51:02 -04002511The maximum clip affects only future clipping operations; it is not retroactive.
Cary Clark8032b982017-07-28 11:04:54 -04002512The clip restriction is not recorded in pictures.
2513
Herb Derbyefe39bc2018-05-01 17:06:20 -04002514Pass an empty rect to disable maximum clip.
Cary Clarkbad5ad72017-08-03 17:14:08 -04002515
Cary Clark8032b982017-07-28 11:04:54 -04002516#Private
Cary Clark137b8742018-05-30 09:21:49 -04002517This private API is for use by Android framework only.
Cary Clark8032b982017-07-28 11:04:54 -04002518##
2519
Cary Clarkbad5ad72017-08-03 17:14:08 -04002520#Param rect maximum allowed clip in device coordinates
Cary Clark579985c2017-07-31 11:48:27 -04002521#Param ##
Cary Clark8032b982017-07-28 11:04:54 -04002522
2523##
2524
2525#Method void clipRRect(const SkRRect& rrect, SkClipOp op, bool doAntiAlias)
2526
Cary Clarkab2621d2018-01-30 10:08:57 -05002527#In Clip
2528#Line # combines Clip with Round_Rect ##
Cary Clark8032b982017-07-28 11:04:54 -04002529Replace Clip with the intersection or difference of Clip and rrect,
Cary Clarkffb3d682018-05-17 12:17:28 -04002530with an Aliased or Anti_Aliased clip edge.
Cary Clark8032b982017-07-28 11:04:54 -04002531rrect is transformed by Matrix
2532before it is combined with Clip.
2533
Cary Clarkbad5ad72017-08-03 17:14:08 -04002534#Param rrect Round_Rect to combine with Clip ##
2535#Param op Clip_Op to apply to Clip ##
Cary Clarkffb3d682018-05-17 12:17:28 -04002536#Param doAntiAlias true if Clip is to be Anti_Aliased ##
Cary Clark8032b982017-07-28 11:04:54 -04002537
2538#Example
2539#Height 128
Cary Clarkbad5ad72017-08-03 17:14:08 -04002540void draw(SkCanvas* canvas) {
2541 canvas->clear(SK_ColorWHITE);
2542 SkPaint paint;
2543 paint.setAntiAlias(true);
2544 paint.setColor(0x8055aaff);
2545 SkRRect oval;
2546 oval.setOval({10, 20, 90, 100});
2547 canvas->clipRRect(oval, SkClipOp::kIntersect, true);
2548 canvas->drawCircle(70, 100, 60, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002549}
2550##
2551
Cary Clark2ade9972017-11-02 17:49:34 -04002552#SeeAlso clipRect clipPath clipRegion
Cary Clark8032b982017-07-28 11:04:54 -04002553
2554##
2555
Herb Derbyefe39bc2018-05-01 17:06:20 -04002556#Method void clipRRect(const SkRRect& rrect, SkClipOp op)
Cary Clark8032b982017-07-28 11:04:54 -04002557
Cary Clarkab2621d2018-01-30 10:08:57 -05002558#In Clip
Cary Clark8032b982017-07-28 11:04:54 -04002559Replace Clip with the intersection or difference of Clip and rrect.
Cary Clarkce101242017-09-01 15:51:02 -04002560Resulting Clip is Aliased; pixels are fully contained by the clip.
Cary Clarkbad5ad72017-08-03 17:14:08 -04002561rrect is transformed by Matrix before it is combined with Clip.
Cary Clark8032b982017-07-28 11:04:54 -04002562
Cary Clarkbad5ad72017-08-03 17:14:08 -04002563#Param rrect Round_Rect to combine with Clip ##
2564#Param op Clip_Op to apply to Clip ##
Cary Clark8032b982017-07-28 11:04:54 -04002565
2566#Example
2567#Height 128
Cary Clarkbad5ad72017-08-03 17:14:08 -04002568void draw(SkCanvas* canvas) {
2569 SkPaint paint;
2570 paint.setColor(0x8055aaff);
2571 auto oval = SkRRect::MakeOval({10, 20, 90, 100});
2572 canvas->clipRRect(oval, SkClipOp::kIntersect);
2573 canvas->drawCircle(70, 100, 60, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002574}
2575##
2576
Cary Clark2ade9972017-11-02 17:49:34 -04002577#SeeAlso clipRect clipPath clipRegion
Cary Clark8032b982017-07-28 11:04:54 -04002578
2579##
2580
Herb Derbyefe39bc2018-05-01 17:06:20 -04002581#Method void clipRRect(const SkRRect& rrect, bool doAntiAlias = false)
Cary Clark8032b982017-07-28 11:04:54 -04002582
Cary Clarkab2621d2018-01-30 10:08:57 -05002583#In Clip
Cary Clark8032b982017-07-28 11:04:54 -04002584Replace Clip with the intersection of Clip and rrect,
Cary Clarkffb3d682018-05-17 12:17:28 -04002585with an Aliased or Anti_Aliased clip edge.
Cary Clarkbad5ad72017-08-03 17:14:08 -04002586rrect is transformed by Matrix before it is combined with Clip.
Cary Clark8032b982017-07-28 11:04:54 -04002587
Cary Clarkbad5ad72017-08-03 17:14:08 -04002588#Param rrect Round_Rect to combine with Clip ##
Cary Clarkffb3d682018-05-17 12:17:28 -04002589#Param doAntiAlias true if Clip is to be Anti_Aliased ##
Cary Clark8032b982017-07-28 11:04:54 -04002590
2591#Example
2592#Height 128
Cary Clarkbad5ad72017-08-03 17:14:08 -04002593void draw(SkCanvas* canvas) {
2594 SkPaint paint;
2595 paint.setAntiAlias(true);
2596 auto oval = SkRRect::MakeRectXY({10, 20, 90, 100}, 9, 13);
2597 canvas->clipRRect(oval, true);
2598 canvas->drawCircle(70, 100, 60, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002599}
2600##
2601
Cary Clark2ade9972017-11-02 17:49:34 -04002602#SeeAlso clipRect clipPath clipRegion
Cary Clark8032b982017-07-28 11:04:54 -04002603
2604##
2605
2606#Method void clipPath(const SkPath& path, SkClipOp op, bool doAntiAlias)
2607
Cary Clarkab2621d2018-01-30 10:08:57 -05002608#In Clip
2609#Line # combines Clip with Path ##
Cary Clark8032b982017-07-28 11:04:54 -04002610Replace Clip with the intersection or difference of Clip and path,
Cary Clarkffb3d682018-05-17 12:17:28 -04002611with an Aliased or Anti_Aliased clip edge. Path_Fill_Type determines if path
Cary Clark8032b982017-07-28 11:04:54 -04002612describes the area inside or outside its contours; and if Path_Contour overlaps
2613itself or another Path_Contour, whether the overlaps form part of the area.
Cary Clarkbad5ad72017-08-03 17:14:08 -04002614path is transformed by Matrix before it is combined with Clip.
Cary Clark8032b982017-07-28 11:04:54 -04002615
Cary Clarkbad5ad72017-08-03 17:14:08 -04002616#Param path Path to combine with Clip ##
2617#Param op Clip_Op to apply to Clip ##
Cary Clarkffb3d682018-05-17 12:17:28 -04002618#Param doAntiAlias true if Clip is to be Anti_Aliased ##
Cary Clark8032b982017-07-28 11:04:54 -04002619
2620#Example
2621#Description
2622Top figure uses SkPath::kInverseWinding_FillType and SkClipOp::kDifference;
2623area outside clip is subtracted from circle.
2624
2625Bottom figure uses SkPath::kWinding_FillType and SkClipOp::kIntersect;
2626area inside clip is intersected with circle.
2627##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002628void draw(SkCanvas* canvas) {
2629 SkPaint paint;
2630 paint.setAntiAlias(true);
2631 SkPath path;
2632 path.addRect({20, 30, 100, 110});
2633 path.setFillType(SkPath::kInverseWinding_FillType);
2634 canvas->save();
2635 canvas->clipPath(path, SkClipOp::kDifference, false);
2636 canvas->drawCircle(70, 100, 60, paint);
2637 canvas->restore();
2638 canvas->translate(100, 100);
2639 path.setFillType(SkPath::kWinding_FillType);
2640 canvas->clipPath(path, SkClipOp::kIntersect, false);
2641 canvas->drawCircle(70, 100, 60, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002642}
2643##
2644
Cary Clark2ade9972017-11-02 17:49:34 -04002645#SeeAlso clipRect clipRRect clipRegion
Cary Clark8032b982017-07-28 11:04:54 -04002646
2647##
2648
Herb Derbyefe39bc2018-05-01 17:06:20 -04002649#Method void clipPath(const SkPath& path, SkClipOp op)
Cary Clark8032b982017-07-28 11:04:54 -04002650
Cary Clarkab2621d2018-01-30 10:08:57 -05002651#In Clip
Cary Clark8032b982017-07-28 11:04:54 -04002652Replace Clip with the intersection or difference of Clip and path.
Cary Clarkce101242017-09-01 15:51:02 -04002653Resulting Clip is Aliased; pixels are fully contained by the clip.
Cary Clark8032b982017-07-28 11:04:54 -04002654Path_Fill_Type determines if path
2655describes the area inside or outside its contours; and if Path_Contour overlaps
2656itself or another Path_Contour, whether the overlaps form part of the area.
2657path is transformed by Matrix
2658before it is combined with Clip.
2659
Cary Clarkbad5ad72017-08-03 17:14:08 -04002660#Param path Path to combine with Clip ##
2661#Param op Clip_Op to apply to Clip ##
Cary Clark8032b982017-07-28 11:04:54 -04002662
2663#Example
2664#Description
Cary Clarkbc5697d2017-10-04 14:31:33 -04002665Overlapping Rects form a clip. When clip Path_Fill_Type is set to
Herb Derbyefe39bc2018-05-01 17:06:20 -04002666SkPath::kWinding_FillType, the overlap is included. Set to
Cary Clark8032b982017-07-28 11:04:54 -04002667SkPath::kEvenOdd_FillType, the overlap is excluded and forms a hole.
2668##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002669void draw(SkCanvas* canvas) {
2670 SkPaint paint;
2671 paint.setAntiAlias(true);
2672 SkPath path;
2673 path.addRect({20, 15, 100, 95});
2674 path.addRect({50, 65, 130, 135});
2675 path.setFillType(SkPath::kWinding_FillType);
2676 canvas->save();
2677 canvas->clipPath(path, SkClipOp::kIntersect);
2678 canvas->drawCircle(70, 85, 60, paint);
2679 canvas->restore();
2680 canvas->translate(100, 100);
2681 path.setFillType(SkPath::kEvenOdd_FillType);
2682 canvas->clipPath(path, SkClipOp::kIntersect);
2683 canvas->drawCircle(70, 85, 60, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002684}
2685##
2686
Cary Clark2ade9972017-11-02 17:49:34 -04002687#SeeAlso clipRect clipRRect clipRegion
Cary Clark8032b982017-07-28 11:04:54 -04002688
2689##
2690
Herb Derbyefe39bc2018-05-01 17:06:20 -04002691#Method void clipPath(const SkPath& path, bool doAntiAlias = false)
Cary Clark8032b982017-07-28 11:04:54 -04002692
Cary Clarkab2621d2018-01-30 10:08:57 -05002693#In Clip
Cary Clark8032b982017-07-28 11:04:54 -04002694Replace Clip with the intersection of Clip and path.
Cary Clarkce101242017-09-01 15:51:02 -04002695Resulting Clip is Aliased; pixels are fully contained by the clip.
Cary Clark8032b982017-07-28 11:04:54 -04002696Path_Fill_Type determines if path
2697describes the area inside or outside its contours; and if Path_Contour overlaps
2698itself or another Path_Contour, whether the overlaps form part of the area.
Cary Clarkbad5ad72017-08-03 17:14:08 -04002699path is transformed by Matrix before it is combined with Clip.
Cary Clark8032b982017-07-28 11:04:54 -04002700
Cary Clarkbad5ad72017-08-03 17:14:08 -04002701#Param path Path to combine with Clip ##
Cary Clarkffb3d682018-05-17 12:17:28 -04002702#Param doAntiAlias true if Clip is to be Anti_Aliased ##
Cary Clark8032b982017-07-28 11:04:54 -04002703
2704#Example
2705#Height 212
2706#Description
Herb Derbyefe39bc2018-05-01 17:06:20 -04002707Clip loops over itself covering its center twice. When clip Path_Fill_Type
2708is set to SkPath::kWinding_FillType, the overlap is included. Set to
Cary Clark8032b982017-07-28 11:04:54 -04002709SkPath::kEvenOdd_FillType, the overlap is excluded and forms a hole.
2710##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002711void draw(SkCanvas* canvas) {
2712 SkPaint paint;
2713 paint.setAntiAlias(true);
2714 SkPath path;
2715 SkPoint poly[] = {{20, 20}, { 80, 20}, { 80, 80}, {40, 80},
2716 {40, 40}, {100, 40}, {100, 100}, {20, 100}};
2717 path.addPoly(poly, SK_ARRAY_COUNT(poly), true);
2718 path.setFillType(SkPath::kWinding_FillType);
2719 canvas->save();
2720 canvas->clipPath(path, SkClipOp::kIntersect);
2721 canvas->drawCircle(50, 50, 45, paint);
2722 canvas->restore();
2723 canvas->translate(100, 100);
2724 path.setFillType(SkPath::kEvenOdd_FillType);
2725 canvas->clipPath(path, SkClipOp::kIntersect);
2726 canvas->drawCircle(50, 50, 45, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002727}
2728##
2729
Cary Clark2ade9972017-11-02 17:49:34 -04002730#SeeAlso clipRect clipRRect clipRegion
Cary Clark8032b982017-07-28 11:04:54 -04002731
2732##
2733
2734# ------------------------------------------------------------------------------
2735
Herb Derbyefe39bc2018-05-01 17:06:20 -04002736#Method void setAllowSimplifyClip(bool allow)
Cary Clark8032b982017-07-28 11:04:54 -04002737
Cary Clarkab2621d2018-01-30 10:08:57 -05002738#In Clip
Cary Clark682c58d2018-05-16 07:07:07 -04002739#Experimental testing
Cary Clark8032b982017-07-28 11:04:54 -04002740
Cary Clarkce101242017-09-01 15:51:02 -04002741Set to simplify clip stack using PathOps.
Cary Clark8032b982017-07-28 11:04:54 -04002742
2743##
2744
2745# ------------------------------------------------------------------------------
2746
2747#Method void clipRegion(const SkRegion& deviceRgn, SkClipOp op = SkClipOp::kIntersect)
2748
Cary Clarkab2621d2018-01-30 10:08:57 -05002749#In Clip
2750#Line # combines Clip with Region ##
Cary Clark8032b982017-07-28 11:04:54 -04002751Replace Clip with the intersection or difference of Clip and Region deviceRgn.
Cary Clarkce101242017-09-01 15:51:02 -04002752Resulting Clip is Aliased; pixels are fully contained by the clip.
Cary Clark8032b982017-07-28 11:04:54 -04002753deviceRgn is unaffected by Matrix.
2754
Cary Clarkbad5ad72017-08-03 17:14:08 -04002755#Param deviceRgn Region to combine with Clip ##
2756#Param op Clip_Op to apply to Clip ##
Cary Clark8032b982017-07-28 11:04:54 -04002757
2758#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04002759#Description
Cary Clarkce101242017-09-01 15:51:02 -04002760 region is unaffected by canvas rotation; iRect is affected by canvas rotation.
2761 Both clips are Aliased; this is not noticeable on Region clip because it
Cary Clarkbad5ad72017-08-03 17:14:08 -04002762 aligns to pixel boundaries.
2763##
2764void draw(SkCanvas* canvas) {
2765 SkPaint paint;
2766 paint.setAntiAlias(true);
2767 SkIRect iRect = {30, 40, 120, 130 };
2768 SkRegion region(iRect);
2769 canvas->rotate(10);
2770 canvas->save();
2771 canvas->clipRegion(region, SkClipOp::kIntersect);
2772 canvas->drawCircle(50, 50, 45, paint);
2773 canvas->restore();
2774 canvas->translate(100, 100);
2775 canvas->clipRect(SkRect::Make(iRect), SkClipOp::kIntersect);
2776 canvas->drawCircle(50, 50, 45, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002777}
2778##
2779
Cary Clark2ade9972017-11-02 17:49:34 -04002780#SeeAlso clipRect clipRRect clipPath
Cary Clark8032b982017-07-28 11:04:54 -04002781
2782##
2783
2784#Method bool quickReject(const SkRect& rect) const
2785
Cary Clarkab2621d2018-01-30 10:08:57 -05002786#In Clip
2787#Line # returns if Rect is outside Clip ##
Cary Clark8032b982017-07-28 11:04:54 -04002788Return true if Rect rect, transformed by Matrix, can be quickly determined to be
2789outside of Clip. May return false even though rect is outside of Clip.
2790
2791Use to check if an area to be drawn is clipped out, to skip subsequent draw calls.
2792
Cary Clarkbad5ad72017-08-03 17:14:08 -04002793#Param rect Rect to compare with Clip ##
Cary Clark8032b982017-07-28 11:04:54 -04002794
Cary Clarkbad5ad72017-08-03 17:14:08 -04002795#Return true if rect, transformed by Matrix, does not intersect Clip ##
Cary Clark8032b982017-07-28 11:04:54 -04002796
2797#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04002798void draw(SkCanvas* canvas) {
Herb Derbyefe39bc2018-05-01 17:06:20 -04002799 SkRect testRect = {30, 30, 120, 129 };
2800 SkRect clipRect = {30, 130, 120, 230 };
Cary Clarkbad5ad72017-08-03 17:14:08 -04002801 canvas->save();
2802 canvas->clipRect(clipRect);
2803 SkDebugf("quickReject %s\n", canvas->quickReject(testRect) ? "true" : "false");
2804 canvas->restore();
2805 canvas->rotate(10);
2806 canvas->clipRect(clipRect);
2807 SkDebugf("quickReject %s\n", canvas->quickReject(testRect) ? "true" : "false");
Cary Clark8032b982017-07-28 11:04:54 -04002808}
2809 #StdOut
Cary Clarkbad5ad72017-08-03 17:14:08 -04002810 quickReject true
Cary Clark8032b982017-07-28 11:04:54 -04002811 quickReject false
2812 ##
2813##
2814
Cary Clark2ade9972017-11-02 17:49:34 -04002815#SeeAlso getLocalClipBounds getTotalMatrix SkBitmap::drawsNothing
Cary Clark8032b982017-07-28 11:04:54 -04002816
2817##
2818
2819#Method bool quickReject(const SkPath& path) const
2820
Cary Clarkab2621d2018-01-30 10:08:57 -05002821#In Clip
Cary Clark8032b982017-07-28 11:04:54 -04002822Return true if path, transformed by Matrix, can be quickly determined to be
2823outside of Clip. May return false even though path is outside of Clip.
2824
2825Use to check if an area to be drawn is clipped out, to skip subsequent draw calls.
2826
Cary Clarkbad5ad72017-08-03 17:14:08 -04002827#Param path Path to compare with Clip ##
Cary Clark8032b982017-07-28 11:04:54 -04002828
Cary Clarkbad5ad72017-08-03 17:14:08 -04002829#Return true if path, transformed by Matrix, does not intersect Clip ##
Cary Clark8032b982017-07-28 11:04:54 -04002830
2831#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04002832void draw(SkCanvas* canvas) {
Herb Derbyefe39bc2018-05-01 17:06:20 -04002833 SkPoint testPoints[] = {{30, 30}, {120, 30}, {120, 129} };
2834 SkPoint clipPoints[] = {{30, 130}, {120, 130}, {120, 230} };
Cary Clarkbad5ad72017-08-03 17:14:08 -04002835 SkPath testPath, clipPath;
2836 testPath.addPoly(testPoints, SK_ARRAY_COUNT(testPoints), true);
2837 clipPath.addPoly(clipPoints, SK_ARRAY_COUNT(clipPoints), true);
2838 canvas->save();
2839 canvas->clipPath(clipPath);
2840 SkDebugf("quickReject %s\n", canvas->quickReject(testPath) ? "true" : "false");
2841 canvas->restore();
2842 canvas->rotate(10);
2843 canvas->clipPath(clipPath);
2844 SkDebugf("quickReject %s\n", canvas->quickReject(testPath) ? "true" : "false");
Cary Clark8032b982017-07-28 11:04:54 -04002845 #StdOut
Cary Clarkbad5ad72017-08-03 17:14:08 -04002846 quickReject true
Cary Clark8032b982017-07-28 11:04:54 -04002847 quickReject false
2848 ##
2849}
2850##
2851
Cary Clark2ade9972017-11-02 17:49:34 -04002852#SeeAlso getLocalClipBounds getTotalMatrix SkBitmap::drawsNothing
Cary Clark8032b982017-07-28 11:04:54 -04002853
2854##
2855
Herb Derbyefe39bc2018-05-01 17:06:20 -04002856#Method SkRect getLocalClipBounds() const
Cary Clark8032b982017-07-28 11:04:54 -04002857
Cary Clarkab2621d2018-01-30 10:08:57 -05002858#In Clip
2859#Line # returns Clip bounds in source coordinates ##
Cary Clark8032b982017-07-28 11:04:54 -04002860Return bounds of Clip, transformed by inverse of Matrix. If Clip is empty,
2861return SkRect::MakeEmpty, where all Rect sides equal zero.
2862
2863Rect returned is outset by one to account for partial pixel coverage if Clip
Cary Clarkffb3d682018-05-17 12:17:28 -04002864is Anti_Aliased.
Cary Clark8032b982017-07-28 11:04:54 -04002865
Cary Clarkbad5ad72017-08-03 17:14:08 -04002866#Return bounds of Clip in local coordinates ##
Cary Clark8032b982017-07-28 11:04:54 -04002867
2868#Example
Herb Derbyefe39bc2018-05-01 17:06:20 -04002869 #Description
Cary Clark8032b982017-07-28 11:04:54 -04002870 Initial bounds is device bounds outset by 1 on all sides.
2871 Clipped bounds is clipPath bounds outset by 1 on all sides.
Cary Clark5538c132018-06-14 12:28:14 -04002872 Scaling the canvas by two on both axes scales the local bounds by 1/2
2873 on both axes.
Cary Clark8032b982017-07-28 11:04:54 -04002874 ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002875 SkCanvas local(256, 256);
2876 canvas = &local;
2877 SkRect bounds = canvas->getLocalClipBounds();
2878 SkDebugf("left:%g top:%g right:%g bottom:%g\n",
2879 bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom);
Herb Derbyefe39bc2018-05-01 17:06:20 -04002880 SkPoint clipPoints[] = {{30, 130}, {120, 130}, {120, 230} };
Cary Clarkbad5ad72017-08-03 17:14:08 -04002881 SkPath clipPath;
2882 clipPath.addPoly(clipPoints, SK_ARRAY_COUNT(clipPoints), true);
2883 canvas->clipPath(clipPath);
2884 bounds = canvas->getLocalClipBounds();
2885 SkDebugf("left:%g top:%g right:%g bottom:%g\n",
2886 bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom);
2887 canvas->scale(2, 2);
2888 bounds = canvas->getLocalClipBounds();
2889 SkDebugf("left:%g top:%g right:%g bottom:%g\n",
2890 bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom);
2891 #StdOut
2892 left:-1 top:-1 right:257 bottom:257
2893 left:29 top:129 right:121 bottom:231
2894 left:14.5 top:64.5 right:60.5 bottom:115.5
2895 ##
Cary Clark8032b982017-07-28 11:04:54 -04002896##
2897
2898# local canvas in example works around bug in fiddle ##
Cary Clark4855f782018-02-06 09:41:53 -05002899#Bug 6524
Cary Clark2ade9972017-11-02 17:49:34 -04002900#SeeAlso getDeviceClipBounds getBaseLayerSize quickReject
Cary Clark8032b982017-07-28 11:04:54 -04002901
2902##
2903
Herb Derbyefe39bc2018-05-01 17:06:20 -04002904#Method bool getLocalClipBounds(SkRect* bounds) const
Cary Clark8032b982017-07-28 11:04:54 -04002905
Cary Clarkab2621d2018-01-30 10:08:57 -05002906#In Clip
Cary Clark8032b982017-07-28 11:04:54 -04002907Return bounds of Clip, transformed by inverse of Matrix. If Clip is empty,
2908return false, and set bounds to SkRect::MakeEmpty, where all Rect sides equal zero.
2909
2910bounds is outset by one to account for partial pixel coverage if Clip
Cary Clarkffb3d682018-05-17 12:17:28 -04002911is Anti_Aliased.
Cary Clark8032b982017-07-28 11:04:54 -04002912
Cary Clarkbad5ad72017-08-03 17:14:08 -04002913#Param bounds Rect of Clip in local coordinates ##
Cary Clark8032b982017-07-28 11:04:54 -04002914
Cary Clarkbad5ad72017-08-03 17:14:08 -04002915#Return true if Clip bounds is not empty ##
Cary Clark8032b982017-07-28 11:04:54 -04002916
2917#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04002918 void draw(SkCanvas* canvas) {
2919 SkCanvas local(256, 256);
2920 canvas = &local;
2921 SkRect bounds;
2922 SkDebugf("local bounds empty = %s\n", canvas->getLocalClipBounds(&bounds)
2923 ? "false" : "true");
2924 SkPath path;
2925 canvas->clipPath(path);
2926 SkDebugf("local bounds empty = %s\n", canvas->getLocalClipBounds(&bounds)
2927 ? "false" : "true");
Cary Clark8032b982017-07-28 11:04:54 -04002928 }
2929 #StdOut
Cary Clarkbad5ad72017-08-03 17:14:08 -04002930 local bounds empty = false
Cary Clark8032b982017-07-28 11:04:54 -04002931 local bounds empty = true
2932 ##
2933##
2934
2935# local canvas in example works around bug in fiddle ##
Cary Clark4855f782018-02-06 09:41:53 -05002936#Bug 6524
Cary Clark2ade9972017-11-02 17:49:34 -04002937#SeeAlso getDeviceClipBounds getBaseLayerSize quickReject
Cary Clark8032b982017-07-28 11:04:54 -04002938
2939##
2940
Herb Derbyefe39bc2018-05-01 17:06:20 -04002941#Method SkIRect getDeviceClipBounds() const
Cary Clark8032b982017-07-28 11:04:54 -04002942
Cary Clarkab2621d2018-01-30 10:08:57 -05002943#In Clip
2944#Line # returns IRect bounds of Clip ##
Cary Clark8032b982017-07-28 11:04:54 -04002945Return IRect bounds of Clip, unaffected by Matrix. If Clip is empty,
2946return SkRect::MakeEmpty, where all Rect sides equal zero.
2947
Herb Derbyefe39bc2018-05-01 17:06:20 -04002948Unlike getLocalClipBounds, returned IRect is not outset.
Cary Clark8032b982017-07-28 11:04:54 -04002949
Cary Clarkbad5ad72017-08-03 17:14:08 -04002950#Return bounds of Clip in Device coordinates ##
Cary Clark8032b982017-07-28 11:04:54 -04002951
2952#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04002953void draw(SkCanvas* canvas) {
2954 #Description
Cary Clark8032b982017-07-28 11:04:54 -04002955 Initial bounds is device bounds, not outset.
2956 Clipped bounds is clipPath bounds, not outset.
Cary Clark5538c132018-06-14 12:28:14 -04002957 Scaling the canvas by 1/2 on both axes scales the device bounds by 1/2
2958 on both axes.
Cary Clarkbad5ad72017-08-03 17:14:08 -04002959 ##
2960 SkCanvas device(256, 256);
2961 canvas = &device;
2962 SkIRect bounds = canvas->getDeviceClipBounds();
2963 SkDebugf("left:%d top:%d right:%d bottom:%d\n",
2964 bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom);
Herb Derbyefe39bc2018-05-01 17:06:20 -04002965 SkPoint clipPoints[] = {{30, 130}, {120, 130}, {120, 230} };
Cary Clarkbad5ad72017-08-03 17:14:08 -04002966 SkPath clipPath;
2967 clipPath.addPoly(clipPoints, SK_ARRAY_COUNT(clipPoints), true);
2968 canvas->save();
2969 canvas->clipPath(clipPath);
2970 bounds = canvas->getDeviceClipBounds();
2971 SkDebugf("left:%d top:%d right:%d bottom:%d\n",
2972 bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom);
2973 canvas->restore();
2974 canvas->scale(1.f/2, 1.f/2);
2975 canvas->clipPath(clipPath);
2976 bounds = canvas->getDeviceClipBounds();
2977 SkDebugf("left:%d top:%d right:%d bottom:%d\n",
2978 bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom);
Cary Clark8032b982017-07-28 11:04:54 -04002979 #StdOut
Cary Clarkbad5ad72017-08-03 17:14:08 -04002980 left:0 top:0 right:256 bottom:256
2981 left:30 top:130 right:120 bottom:230
Cary Clark8032b982017-07-28 11:04:54 -04002982 left:15 top:65 right:60 bottom:115
2983 ##
2984}
2985##
2986
2987#ToDo some confusion on why with an identity Matrix local and device are different ##
Cary Clark2ade9972017-11-02 17:49:34 -04002988#SeeAlso getLocalClipBounds getBaseLayerSize quickReject
Cary Clark8032b982017-07-28 11:04:54 -04002989
2990# device canvas in example works around bug in fiddle ##
Cary Clark4855f782018-02-06 09:41:53 -05002991#Bug 6524
Cary Clark8032b982017-07-28 11:04:54 -04002992
2993##
2994
Herb Derbyefe39bc2018-05-01 17:06:20 -04002995#Method bool getDeviceClipBounds(SkIRect* bounds) const
Cary Clark8032b982017-07-28 11:04:54 -04002996
Cary Clarkab2621d2018-01-30 10:08:57 -05002997#In Clip
Cary Clark8032b982017-07-28 11:04:54 -04002998Return IRect bounds of Clip, unaffected by Matrix. If Clip is empty,
2999return false, and set bounds to SkRect::MakeEmpty, where all Rect sides equal zero.
3000
Herb Derbyefe39bc2018-05-01 17:06:20 -04003001Unlike getLocalClipBounds, bounds is not outset.
Cary Clark8032b982017-07-28 11:04:54 -04003002
Cary Clarkbad5ad72017-08-03 17:14:08 -04003003#Param bounds Rect of Clip in device coordinates ##
Cary Clark8032b982017-07-28 11:04:54 -04003004
Cary Clarkbad5ad72017-08-03 17:14:08 -04003005#Return true if Clip bounds is not empty ##
Cary Clark8032b982017-07-28 11:04:54 -04003006
3007#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003008 void draw(SkCanvas* canvas) {
3009 SkIRect bounds;
3010 SkDebugf("device bounds empty = %s\n", canvas->getDeviceClipBounds(&bounds)
3011 ? "false" : "true");
3012 SkPath path;
3013 canvas->clipPath(path);
3014 SkDebugf("device bounds empty = %s\n", canvas->getDeviceClipBounds(&bounds)
3015 ? "false" : "true");
Cary Clark8032b982017-07-28 11:04:54 -04003016 }
3017 #StdOut
Cary Clarkbad5ad72017-08-03 17:14:08 -04003018 device bounds empty = false
Cary Clark8032b982017-07-28 11:04:54 -04003019 device bounds empty = true
3020 ##
3021##
3022
Cary Clark2ade9972017-11-02 17:49:34 -04003023#SeeAlso getLocalClipBounds getBaseLayerSize quickReject
Cary Clark8032b982017-07-28 11:04:54 -04003024
3025##
3026
Cary Clark08895c42018-02-01 09:37:32 -05003027#Subtopic Clip ##
Cary Clark8032b982017-07-28 11:04:54 -04003028
3029# ------------------------------------------------------------------------------
Cary Clark78de7512018-02-07 07:27:09 -05003030#Subtopic Draw
3031#Populate
3032#Line # draws into Canvas ##
3033##
Cary Clark8032b982017-07-28 11:04:54 -04003034
3035#Method void drawColor(SkColor color, SkBlendMode mode = SkBlendMode::kSrcOver)
Cary Clark78de7512018-02-07 07:27:09 -05003036#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05003037#Line # fills Clip with Color and Blend_Mode ##
Cary Clark8032b982017-07-28 11:04:54 -04003038Fill Clip with Color color.
Cary Clarkffb3d682018-05-17 12:17:28 -04003039mode determines how ARGB is combined with destination.
Cary Clark8032b982017-07-28 11:04:54 -04003040
Cary Clarkffb3d682018-05-17 12:17:28 -04003041#Param color Unpremultiplied ARGB ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003042#Param mode SkBlendMode used to combine source color and destination ##
Cary Clark8032b982017-07-28 11:04:54 -04003043
3044#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003045 canvas->drawColor(SK_ColorRED);
3046 canvas->clipRect(SkRect::MakeWH(150, 150));
3047 canvas->drawColor(SkColorSetARGB(0x80, 0x00, 0xFF, 0x00), SkBlendMode::kPlus);
3048 canvas->clipRect(SkRect::MakeWH(75, 75));
3049 canvas->drawColor(SkColorSetARGB(0x80, 0x00, 0x00, 0xFF), SkBlendMode::kPlus);
Cary Clark8032b982017-07-28 11:04:54 -04003050##
3051
Cary Clark2ade9972017-11-02 17:49:34 -04003052#SeeAlso clear SkBitmap::erase drawPaint
Cary Clark8032b982017-07-28 11:04:54 -04003053
3054##
3055
3056# ------------------------------------------------------------------------------
3057
Herb Derbyefe39bc2018-05-01 17:06:20 -04003058#Method void clear(SkColor color)
Cary Clark78de7512018-02-07 07:27:09 -05003059#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05003060#Line # fills Clip with Color ##
Herb Derbyefe39bc2018-05-01 17:06:20 -04003061Fill Clip with Color color using SkBlendMode::kSrc.
Cary Clark8032b982017-07-28 11:04:54 -04003062This has the effect of replacing all pixels contained by Clip with color.
3063
Cary Clarkffb3d682018-05-17 12:17:28 -04003064#Param color Unpremultiplied ARGB ##
Cary Clark8032b982017-07-28 11:04:54 -04003065
3066#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003067void draw(SkCanvas* canvas) {
3068 canvas->save();
3069 canvas->clipRect(SkRect::MakeWH(256, 128));
Herb Derbyefe39bc2018-05-01 17:06:20 -04003070 canvas->clear(SkColorSetARGB(0x80, 0xFF, 0x00, 0x00));
Cary Clarkbad5ad72017-08-03 17:14:08 -04003071 canvas->restore();
3072 canvas->save();
3073 canvas->clipRect(SkRect::MakeWH(150, 192));
3074 canvas->clear(SkColorSetARGB(0x80, 0x00, 0xFF, 0x00));
3075 canvas->restore();
3076 canvas->clipRect(SkRect::MakeWH(75, 256));
3077 canvas->clear(SkColorSetARGB(0x80, 0x00, 0x00, 0xFF));
Cary Clark8032b982017-07-28 11:04:54 -04003078}
3079##
3080
Cary Clark2ade9972017-11-02 17:49:34 -04003081#SeeAlso drawColor SkBitmap::erase drawPaint
Cary Clark8032b982017-07-28 11:04:54 -04003082
3083##
3084
3085# ------------------------------------------------------------------------------
3086
Herb Derbyefe39bc2018-05-01 17:06:20 -04003087#Method void discard()
Cary Clark78de7512018-02-07 07:27:09 -05003088#In Utility
Cary Clarkab2621d2018-01-30 10:08:57 -05003089#Line # makes Canvas contents undefined ##
Cary Clark8032b982017-07-28 11:04:54 -04003090Make Canvas contents undefined. Subsequent calls that read Canvas pixels,
3091such as drawing with SkBlendMode, return undefined results. discard() does
3092not change Clip or Matrix.
3093
3094discard() may do nothing, depending on the implementation of Surface or Device
3095that created Canvas.
3096
3097discard() allows optimized performance on subsequent draws by removing
3098cached data associated with Surface or Device.
3099It is not necessary to call discard() once done with Canvas;
3100any cached data is deleted when owning Surface or Device is deleted.
3101
3102#ToDo example? not sure how to make this meaningful w/o more implementation detail ##
Cary Clark2ade9972017-11-02 17:49:34 -04003103#SeeAlso flush() SkSurface::prepareForExternalIO GrContext::abandonContext
Cary Clark8032b982017-07-28 11:04:54 -04003104
Herb Derbyefe39bc2018-05-01 17:06:20 -04003105#NoExample
Cary Clark8032b982017-07-28 11:04:54 -04003106##
3107
3108##
3109
3110# ------------------------------------------------------------------------------
3111
3112#Method void drawPaint(const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05003113#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05003114#Line # fills Clip with Paint ##
Mike Reed8ad91a92018-01-19 19:09:32 -05003115Fill Clip with Paint paint. Paint components Mask_Filter, Shader,
Cary Clarkbad5ad72017-08-03 17:14:08 -04003116Color_Filter, Image_Filter, and Blend_Mode affect drawing;
3117Path_Effect in paint is ignored.
Cary Clark8032b982017-07-28 11:04:54 -04003118
3119# can Path_Effect in paint ever alter drawPaint?
3120
Cary Clarkbad5ad72017-08-03 17:14:08 -04003121#Param paint graphics state used to fill Canvas ##
Cary Clark8032b982017-07-28 11:04:54 -04003122
3123#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003124void draw(SkCanvas* canvas) {
3125 SkColor colors[] = { SK_ColorRED, SK_ColorGREEN, SK_ColorBLUE };
3126 SkScalar pos[] = { 0, SK_Scalar1/2, SK_Scalar1 };
3127 SkPaint paint;
3128 paint.setShader(SkGradientShader::MakeSweep(256, 256, colors, pos, SK_ARRAY_COUNT(colors)));
3129 canvas->drawPaint(paint);
Cary Clark8032b982017-07-28 11:04:54 -04003130}
3131##
3132
Cary Clark2ade9972017-11-02 17:49:34 -04003133#SeeAlso clear drawColor SkBitmap::erase
Cary Clark8032b982017-07-28 11:04:54 -04003134
3135##
3136
3137# ------------------------------------------------------------------------------
3138
3139#Enum PointMode
Cary Clark08895c42018-02-01 09:37:32 -05003140#Line # sets drawPoints options ##
Cary Clark8032b982017-07-28 11:04:54 -04003141
3142#Code
3143 enum PointMode {
3144 kPoints_PointMode,
3145 kLines_PointMode,
Cary Clarkd0530ba2017-09-14 11:25:39 -04003146 kPolygon_PointMode,
Cary Clark8032b982017-07-28 11:04:54 -04003147 };
3148##
3149
3150Selects if an array of points are drawn as discrete points, as lines, or as
3151an open polygon.
3152
3153#Const kPoints_PointMode 0
Cary Clark682c58d2018-05-16 07:07:07 -04003154#Line # draw each point separately ##
Cary Clark8032b982017-07-28 11:04:54 -04003155##
3156
3157#Const kLines_PointMode 1
Cary Clark682c58d2018-05-16 07:07:07 -04003158#Line # draw each pair of points as a line segment ##
Cary Clark8032b982017-07-28 11:04:54 -04003159##
3160
3161#Const kPolygon_PointMode 2
Cary Clark682c58d2018-05-16 07:07:07 -04003162#Line # draw the array of points as a open polygon ##
Cary Clark8032b982017-07-28 11:04:54 -04003163##
3164
3165#Example
Herb Derbyefe39bc2018-05-01 17:06:20 -04003166 #Description
Cary Clark8032b982017-07-28 11:04:54 -04003167 The upper left corner shows three squares when drawn as points.
3168 The upper right corner shows one line; when drawn as lines, two points are required per line.
3169 The lower right corner shows two lines; when draw as polygon, no miter is drawn at the corner.
3170 The lower left corner shows two lines with a miter when path contains polygon.
3171 ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003172void draw(SkCanvas* canvas) {
3173 SkPaint paint;
3174 paint.setStyle(SkPaint::kStroke_Style);
3175 paint.setStrokeWidth(10);
3176 SkPoint points[] = {{64, 32}, {96, 96}, {32, 96}};
3177 canvas->drawPoints(SkCanvas::kPoints_PointMode, 3, points, paint);
3178 canvas->translate(128, 0);
3179 canvas->drawPoints(SkCanvas::kLines_PointMode, 3, points, paint);
3180 canvas->translate(0, 128);
3181 canvas->drawPoints(SkCanvas::kPolygon_PointMode, 3, points, paint);
3182 SkPath path;
3183 path.addPoly(points, 3, false);
3184 canvas->translate(-128, 0);
3185 canvas->drawPath(path, paint);
Cary Clark8032b982017-07-28 11:04:54 -04003186}
3187##
3188
Cary Clark2ade9972017-11-02 17:49:34 -04003189#SeeAlso drawLine drawPoint drawPath
Cary Clark8032b982017-07-28 11:04:54 -04003190
3191##
3192
3193# ------------------------------------------------------------------------------
3194
3195#Method void drawPoints(PointMode mode, size_t count, const SkPoint pts[], const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05003196#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05003197#Line # draws array as points, lines, polygon ##
Cary Clark8032b982017-07-28 11:04:54 -04003198Draw pts using Clip, Matrix and Paint paint.
Cary Clarkbad5ad72017-08-03 17:14:08 -04003199count is the number of points; if count is less than one, has no effect.
Cary Clark8032b982017-07-28 11:04:54 -04003200mode may be one of: kPoints_PointMode, kLines_PointMode, or kPolygon_PointMode.
3201
Cary Clarkbad5ad72017-08-03 17:14:08 -04003202If mode is kPoints_PointMode, the shape of point drawn depends on paint
3203Paint_Stroke_Cap. If paint is set to SkPaint::kRound_Cap, each point draws a
3204circle of diameter Paint_Stroke_Width. If paint is set to SkPaint::kSquare_Cap
3205or SkPaint::kButt_Cap, each point draws a square of width and height
3206Paint_Stroke_Width.
Cary Clark8032b982017-07-28 11:04:54 -04003207
3208If mode is kLines_PointMode, each pair of points draws a line segment.
3209One line is drawn for every two points; each point is used once. If count is odd,
Herb Derbyefe39bc2018-05-01 17:06:20 -04003210the final point is ignored.
Cary Clark8032b982017-07-28 11:04:54 -04003211
3212If mode is kPolygon_PointMode, each adjacent pair of points draws a line segment.
3213count minus one lines are drawn; the first and last point are used once.
3214
3215Each line segment respects paint Paint_Stroke_Cap and Paint_Stroke_Width.
3216Paint_Style is ignored, as if were set to SkPaint::kStroke_Style.
3217
Cary Clarkbad5ad72017-08-03 17:14:08 -04003218Always draws each element one at a time; is not affected by
3219Paint_Stroke_Join, and unlike drawPath, does not create a mask from all points
Herb Derbyefe39bc2018-05-01 17:06:20 -04003220and lines before drawing.
Cary Clark8032b982017-07-28 11:04:54 -04003221
Cary Clarka523d2d2017-08-30 08:58:10 -04003222#Param mode whether pts draws points or lines ##
3223#Param count number of points in the array ##
3224#Param pts array of points to draw ##
3225#Param paint stroke, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003226
3227#Example
3228#Height 200
Herb Derbyefe39bc2018-05-01 17:06:20 -04003229 #Description
Cary Clark8032b982017-07-28 11:04:54 -04003230 #List
3231 # The first column draws points. ##
3232 # The second column draws points as lines. ##
3233 # The third column draws points as a polygon. ##
3234 # The fourth column draws points as a polygonal path. ##
3235 # The first row uses a round cap and round join. ##
3236 # The second row uses a square cap and a miter join. ##
3237 # The third row uses a butt cap and a bevel join. ##
3238 ##
3239 The transparent color makes multiple line draws visible;
3240 the path is drawn all at once.
3241 ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003242void draw(SkCanvas* canvas) {
3243 SkPaint paint;
3244 paint.setAntiAlias(true);
3245 paint.setStyle(SkPaint::kStroke_Style);
3246 paint.setStrokeWidth(10);
3247 paint.setColor(0x80349a45);
3248 const SkPoint points[] = {{32, 16}, {48, 48}, {16, 32}};
Herb Derbyefe39bc2018-05-01 17:06:20 -04003249 const SkPaint::Join join[] = { SkPaint::kRound_Join,
Cary Clarkbad5ad72017-08-03 17:14:08 -04003250 SkPaint::kMiter_Join,
3251 SkPaint::kBevel_Join };
3252 int joinIndex = 0;
3253 SkPath path;
3254 path.addPoly(points, 3, false);
3255 for (const auto cap : { SkPaint::kRound_Cap, SkPaint::kSquare_Cap, SkPaint::kButt_Cap } ) {
3256 paint.setStrokeCap(cap);
3257 paint.setStrokeJoin(join[joinIndex++]);
3258 for (const auto mode : { SkCanvas::kPoints_PointMode,
3259 SkCanvas::kLines_PointMode,
3260 SkCanvas::kPolygon_PointMode } ) {
3261 canvas->drawPoints(mode, 3, points, paint);
3262 canvas->translate(64, 0);
3263 }
3264 canvas->drawPath(path, paint);
3265 canvas->translate(-192, 64);
3266 }
Cary Clark8032b982017-07-28 11:04:54 -04003267}
3268##
3269
Cary Clark2ade9972017-11-02 17:49:34 -04003270#SeeAlso drawLine drawPoint drawPath
Cary Clark8032b982017-07-28 11:04:54 -04003271
3272##
3273
3274# ------------------------------------------------------------------------------
3275
3276#Method void drawPoint(SkScalar x, SkScalar y, const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05003277#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05003278#Line # draws point at (x, y) position ##
Cary Clark8032b982017-07-28 11:04:54 -04003279Draw point at (x, y) using Clip, Matrix and Paint paint.
3280
3281The shape of point drawn depends on paint Paint_Stroke_Cap.
Cary Clarkbad5ad72017-08-03 17:14:08 -04003282If paint is set to SkPaint::kRound_Cap, draw a circle of diameter
Herb Derbyefe39bc2018-05-01 17:06:20 -04003283Paint_Stroke_Width. If paint is set to SkPaint::kSquare_Cap or SkPaint::kButt_Cap,
Cary Clark8032b982017-07-28 11:04:54 -04003284draw a square of width and height Paint_Stroke_Width.
3285Paint_Style is ignored, as if were set to SkPaint::kStroke_Style.
3286
Cary Clarkbad5ad72017-08-03 17:14:08 -04003287#Param x left edge of circle or square ##
3288#Param y top edge of circle or square ##
3289#Param paint stroke, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003290
3291#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003292void draw(SkCanvas* canvas) {
3293 SkPaint paint;
3294 paint.setAntiAlias(true);
3295 paint.setColor(0x80349a45);
3296 paint.setStyle(SkPaint::kStroke_Style);
3297 paint.setStrokeWidth(100);
3298 paint.setStrokeCap(SkPaint::kRound_Cap);
3299 canvas->scale(1, 1.2f);
3300 canvas->drawPoint(64, 96, paint);
3301 canvas->scale(.6f, .8f);
3302 paint.setColor(SK_ColorWHITE);
3303 canvas->drawPoint(106, 120, paint);
Cary Clark8032b982017-07-28 11:04:54 -04003304}
3305##
3306
Cary Clark2ade9972017-11-02 17:49:34 -04003307#SeeAlso drawPoints drawCircle drawRect drawLine drawPath
Cary Clark8032b982017-07-28 11:04:54 -04003308
3309##
3310
Cary Clarkbad5ad72017-08-03 17:14:08 -04003311#Method void drawPoint(SkPoint p, const SkPaint& paint)
3312
3313Draw point p using Clip, Matrix and Paint paint.
3314
3315The shape of point drawn depends on paint Paint_Stroke_Cap.
3316If paint is set to SkPaint::kRound_Cap, draw a circle of diameter
Herb Derbyefe39bc2018-05-01 17:06:20 -04003317Paint_Stroke_Width. If paint is set to SkPaint::kSquare_Cap or SkPaint::kButt_Cap,
Cary Clarkbad5ad72017-08-03 17:14:08 -04003318draw a square of width and height Paint_Stroke_Width.
3319Paint_Style is ignored, as if were set to SkPaint::kStroke_Style.
3320
3321#Param p top-left edge of circle or square ##
3322#Param paint stroke, blend, color, and so on, used to draw ##
3323
3324#Example
3325void draw(SkCanvas* canvas) {
3326 SkPaint paint;
3327 paint.setAntiAlias(true);
3328 paint.setColor(0x80349a45);
3329 paint.setStyle(SkPaint::kStroke_Style);
3330 paint.setStrokeWidth(100);
3331 paint.setStrokeCap(SkPaint::kSquare_Cap);
3332 canvas->scale(1, 1.2f);
3333 canvas->drawPoint({64, 96}, paint);
3334 canvas->scale(.6f, .8f);
3335 paint.setColor(SK_ColorWHITE);
3336 canvas->drawPoint(106, 120, paint);
3337}
3338##
3339
Cary Clark2ade9972017-11-02 17:49:34 -04003340#SeeAlso drawPoints drawCircle drawRect drawLine drawPath
Cary Clarkbad5ad72017-08-03 17:14:08 -04003341
3342##
3343
Cary Clark8032b982017-07-28 11:04:54 -04003344# ------------------------------------------------------------------------------
3345
3346#Method void drawLine(SkScalar x0, SkScalar y0, SkScalar x1, SkScalar y1, const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05003347#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05003348#Line # draws line segment between two points ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003349Draws line segment from (x0, y0) to (x1, y1) using Clip, Matrix, and Paint paint.
3350In paint: Paint_Stroke_Width describes the line thickness;
3351Paint_Stroke_Cap draws the end rounded or square;
Cary Clark8032b982017-07-28 11:04:54 -04003352Paint_Style is ignored, as if were set to SkPaint::kStroke_Style.
3353
Cary Clarkbad5ad72017-08-03 17:14:08 -04003354#Param x0 start of line segment on x-axis ##
3355#Param y0 start of line segment on y-axis ##
3356#Param x1 end of line segment on x-axis ##
3357#Param y1 end of line segment on y-axis ##
3358#Param paint stroke, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003359
3360#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003361 SkPaint paint;
3362 paint.setAntiAlias(true);
3363 paint.setColor(0xFF9a67be);
3364 paint.setStrokeWidth(20);
3365 canvas->skew(1, 0);
3366 canvas->drawLine(32, 96, 32, 160, paint);
3367 canvas->skew(-2, 0);
3368 canvas->drawLine(288, 96, 288, 160, paint);
3369##
3370
Cary Clark2ade9972017-11-02 17:49:34 -04003371#SeeAlso drawPoint drawCircle drawRect drawPath
Cary Clarkbad5ad72017-08-03 17:14:08 -04003372
3373##
3374
3375#Method void drawLine(SkPoint p0, SkPoint p1, const SkPaint& paint)
3376
3377Draws line segment from p0 to p1 using Clip, Matrix, and Paint paint.
3378In paint: Paint_Stroke_Width describes the line thickness;
3379Paint_Stroke_Cap draws the end rounded or square;
3380Paint_Style is ignored, as if were set to SkPaint::kStroke_Style.
3381
3382#Param p0 start of line segment ##
3383#Param p1 end of line segment ##
3384#Param paint stroke, blend, color, and so on, used to draw ##
3385
3386#Example
3387 SkPaint paint;
3388 paint.setAntiAlias(true);
3389 paint.setColor(0xFF9a67be);
3390 paint.setStrokeWidth(20);
3391 canvas->skew(1, 0);
3392 canvas->drawLine({32, 96}, {32, 160}, paint);
3393 canvas->skew(-2, 0);
3394 canvas->drawLine({288, 96}, {288, 160}, paint);
Cary Clark8032b982017-07-28 11:04:54 -04003395##
3396
Cary Clark2ade9972017-11-02 17:49:34 -04003397#SeeAlso drawPoint drawCircle drawRect drawPath
Cary Clark8032b982017-07-28 11:04:54 -04003398
3399##
3400
3401# ------------------------------------------------------------------------------
3402
3403#Method void drawRect(const SkRect& rect, const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05003404#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05003405#Line # draws Rect using Clip, Matrix, and Paint ##
Cary Clark8032b982017-07-28 11:04:54 -04003406Draw Rect rect using Clip, Matrix, and Paint paint.
Herb Derbyefe39bc2018-05-01 17:06:20 -04003407In paint: Paint_Style determines if rectangle is stroked or filled;
Cary Clark8032b982017-07-28 11:04:54 -04003408if stroked, Paint_Stroke_Width describes the line thickness, and
3409Paint_Stroke_Join draws the corners rounded or square.
3410
Cary Clarkbc5697d2017-10-04 14:31:33 -04003411#Param rect rectangle to draw ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003412#Param paint stroke or fill, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003413
3414#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003415void draw(SkCanvas* canvas) {
3416 SkPoint rectPts[] = { {64, 48}, {192, 160} };
3417 SkPaint paint;
3418 paint.setAntiAlias(true);
3419 paint.setStyle(SkPaint::kStroke_Style);
3420 paint.setStrokeWidth(20);
3421 paint.setStrokeJoin(SkPaint::kRound_Join);
3422 SkMatrix rotator;
3423 rotator.setRotate(30, 128, 128);
3424 for (auto color : { SK_ColorRED, SK_ColorBLUE, SK_ColorYELLOW, SK_ColorMAGENTA } ) {
3425 paint.setColor(color);
3426 SkRect rect;
3427 rect.set(rectPts[0], rectPts[1]);
3428 canvas->drawRect(rect, paint);
3429 rotator.mapPoints(rectPts, 2);
3430 }
Cary Clark8032b982017-07-28 11:04:54 -04003431}
3432##
3433
Herb Derbyefe39bc2018-05-01 17:06:20 -04003434#SeeAlso drawIRect drawRRect drawRoundRect drawRegion drawPath drawLine
Cary Clark8032b982017-07-28 11:04:54 -04003435
3436##
3437
3438# ------------------------------------------------------------------------------
3439
Herb Derbyefe39bc2018-05-01 17:06:20 -04003440#Method void drawIRect(const SkIRect& rect, const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05003441#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05003442#Line # draws IRect using Clip, Matrix, and Paint ##
Cary Clark8032b982017-07-28 11:04:54 -04003443Draw IRect rect using Clip, Matrix, and Paint paint.
Herb Derbyefe39bc2018-05-01 17:06:20 -04003444In paint: Paint_Style determines if rectangle is stroked or filled;
Cary Clark8032b982017-07-28 11:04:54 -04003445if stroked, Paint_Stroke_Width describes the line thickness, and
3446Paint_Stroke_Join draws the corners rounded or square.
3447
Cary Clarkbc5697d2017-10-04 14:31:33 -04003448#Param rect rectangle to draw ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003449#Param paint stroke or fill, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003450
3451#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003452 SkIRect rect = { 64, 48, 192, 160 };
3453 SkPaint paint;
3454 paint.setAntiAlias(true);
3455 paint.setStyle(SkPaint::kStroke_Style);
3456 paint.setStrokeWidth(20);
3457 paint.setStrokeJoin(SkPaint::kRound_Join);
3458 for (auto color : { SK_ColorRED, SK_ColorBLUE, SK_ColorYELLOW, SK_ColorMAGENTA } ) {
3459 paint.setColor(color);
3460 canvas->drawIRect(rect, paint);
3461 canvas->rotate(30, 128, 128);
3462 }
Cary Clark8032b982017-07-28 11:04:54 -04003463##
3464
Cary Clark2ade9972017-11-02 17:49:34 -04003465#SeeAlso drawRect drawRRect drawRoundRect drawRegion drawPath drawLine
Cary Clark8032b982017-07-28 11:04:54 -04003466
3467##
3468
3469# ------------------------------------------------------------------------------
3470
3471#Method void drawRegion(const SkRegion& region, const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05003472#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05003473#Line # draws Region using Clip, Matrix, and Paint ##
Cary Clark8032b982017-07-28 11:04:54 -04003474Draw Region region using Clip, Matrix, and Paint paint.
Herb Derbyefe39bc2018-05-01 17:06:20 -04003475In paint: Paint_Style determines if rectangle is stroked or filled;
Cary Clark8032b982017-07-28 11:04:54 -04003476if stroked, Paint_Stroke_Width describes the line thickness, and
3477Paint_Stroke_Join draws the corners rounded or square.
3478
Cary Clarkbc5697d2017-10-04 14:31:33 -04003479#Param region region to draw ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003480#Param paint Paint stroke or fill, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003481
3482#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003483void draw(SkCanvas* canvas) {
3484 SkRegion region;
3485 region.op( 10, 10, 50, 50, SkRegion::kUnion_Op);
3486 region.op( 10, 50, 90, 90, SkRegion::kUnion_Op);
3487 SkPaint paint;
3488 paint.setAntiAlias(true);
3489 paint.setStyle(SkPaint::kStroke_Style);
3490 paint.setStrokeWidth(20);
3491 paint.setStrokeJoin(SkPaint::kRound_Join);
3492 canvas->drawRegion(region, paint);
Cary Clark8032b982017-07-28 11:04:54 -04003493}
3494##
3495
Cary Clark2ade9972017-11-02 17:49:34 -04003496#SeeAlso drawRect drawIRect drawPath
Cary Clark8032b982017-07-28 11:04:54 -04003497
3498##
3499
3500# ------------------------------------------------------------------------------
3501
3502#Method void drawOval(const SkRect& oval, const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05003503#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05003504#Line # draws Oval using Clip, Matrix, and Paint ##
Cary Clark8032b982017-07-28 11:04:54 -04003505Draw Oval oval using Clip, Matrix, and Paint.
Herb Derbyefe39bc2018-05-01 17:06:20 -04003506In paint: Paint_Style determines if Oval is stroked or filled;
Cary Clark8032b982017-07-28 11:04:54 -04003507if stroked, Paint_Stroke_Width describes the line thickness.
3508
Cary Clarkbad5ad72017-08-03 17:14:08 -04003509#Param oval Rect bounds of Oval ##
3510#Param paint Paint stroke or fill, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003511
3512#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003513void draw(SkCanvas* canvas) {
3514 canvas->clear(0xFF3f5f9f);
3515 SkColor kColor1 = SkColorSetARGB(0xff, 0xff, 0x7f, 0);
3516 SkColor g1Colors[] = { kColor1, SkColorSetA(kColor1, 0x20) };
3517 SkPoint g1Points[] = { { 0, 0 }, { 0, 100 } };
3518 SkScalar pos[] = { 0.2f, 1.0f };
3519 SkRect bounds = SkRect::MakeWH(80, 70);
3520 SkPaint paint;
3521 paint.setAntiAlias(true);
3522 paint.setShader(SkGradientShader::MakeLinear(g1Points, g1Colors, pos, SK_ARRAY_COUNT(g1Colors),
3523 SkShader::kClamp_TileMode));
3524 canvas->drawOval(bounds , paint);
Cary Clark8032b982017-07-28 11:04:54 -04003525}
3526##
3527
Cary Clark2ade9972017-11-02 17:49:34 -04003528#SeeAlso drawCircle drawPoint drawPath drawRRect drawRoundRect
Cary Clark8032b982017-07-28 11:04:54 -04003529
3530##
3531
3532# ------------------------------------------------------------------------------
3533
3534#Method void drawRRect(const SkRRect& rrect, const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05003535#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05003536#Line # draws Round_Rect using Clip, Matrix, and Paint ##
Cary Clark8032b982017-07-28 11:04:54 -04003537Draw Round_Rect rrect using Clip, Matrix, and Paint paint.
Herb Derbyefe39bc2018-05-01 17:06:20 -04003538In paint: Paint_Style determines if rrect is stroked or filled;
Cary Clark8032b982017-07-28 11:04:54 -04003539if stroked, Paint_Stroke_Width describes the line thickness.
3540
Cary Clarkbad5ad72017-08-03 17:14:08 -04003541rrect may represent a rectangle, circle, oval, uniformly rounded rectangle, or
3542may have any combination of positive non-square radii for the four corners.
Cary Clark8032b982017-07-28 11:04:54 -04003543
Cary Clarkbad5ad72017-08-03 17:14:08 -04003544#Param rrect Round_Rect with up to eight corner radii to draw ##
3545#Param paint Paint stroke or fill, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003546
3547#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003548void draw(SkCanvas* canvas) {
3549 SkPaint paint;
3550 paint.setAntiAlias(true);
3551 SkRect outer = {30, 40, 210, 220};
3552 SkRect radii = {30, 50, 70, 90 };
3553 SkRRect rRect;
3554 rRect.setNinePatch(outer, radii.fLeft, radii.fTop, radii.fRight, radii.fBottom);
3555 canvas->drawRRect(rRect, paint);
3556 paint.setColor(SK_ColorWHITE);
3557 canvas->drawLine(outer.fLeft + radii.fLeft, outer.fTop,
3558 outer.fLeft + radii.fLeft, outer.fBottom, paint);
Herb Derbyefe39bc2018-05-01 17:06:20 -04003559 canvas->drawLine(outer.fRight - radii.fRight, outer.fTop,
Cary Clarkbad5ad72017-08-03 17:14:08 -04003560 outer.fRight - radii.fRight, outer.fBottom, paint);
Herb Derbyefe39bc2018-05-01 17:06:20 -04003561 canvas->drawLine(outer.fLeft, outer.fTop + radii.fTop,
Cary Clarkbad5ad72017-08-03 17:14:08 -04003562 outer.fRight, outer.fTop + radii.fTop, paint);
Herb Derbyefe39bc2018-05-01 17:06:20 -04003563 canvas->drawLine(outer.fLeft, outer.fBottom - radii.fBottom,
Cary Clarkbad5ad72017-08-03 17:14:08 -04003564 outer.fRight, outer.fBottom - radii.fBottom, paint);
3565}
Cary Clark8032b982017-07-28 11:04:54 -04003566##
3567
Cary Clark2ade9972017-11-02 17:49:34 -04003568#SeeAlso drawRect drawRoundRect drawDRRect drawCircle drawOval drawPath
Cary Clark8032b982017-07-28 11:04:54 -04003569
3570##
3571
3572# ------------------------------------------------------------------------------
3573
3574#Method void drawDRRect(const SkRRect& outer, const SkRRect& inner, const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05003575#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05003576#Line # draws double Round_Rect stroked or filled ##
Cary Clark8032b982017-07-28 11:04:54 -04003577Draw Round_Rect outer and inner
Herb Derbyefe39bc2018-05-01 17:06:20 -04003578using Clip, Matrix, and Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04003579outer must contain inner or the drawing is undefined.
Herb Derbyefe39bc2018-05-01 17:06:20 -04003580In paint: Paint_Style determines if Round_Rect is stroked or filled;
Cary Clark8032b982017-07-28 11:04:54 -04003581if stroked, Paint_Stroke_Width describes the line thickness.
Cary Clarkbad5ad72017-08-03 17:14:08 -04003582If stroked and Round_Rect corner has zero length radii, Paint_Stroke_Join can
Herb Derbyefe39bc2018-05-01 17:06:20 -04003583draw corners rounded or square.
Cary Clark8032b982017-07-28 11:04:54 -04003584
Cary Clarkbad5ad72017-08-03 17:14:08 -04003585GPU-backed platforms optimize drawing when both outer and inner are
Cary Clark8032b982017-07-28 11:04:54 -04003586concave and outer contains inner. These platforms may not be able to draw
Herb Derbyefe39bc2018-05-01 17:06:20 -04003587Path built with identical data as fast.
Cary Clark8032b982017-07-28 11:04:54 -04003588
Cary Clarkbad5ad72017-08-03 17:14:08 -04003589#Param outer Round_Rect outer bounds to draw ##
3590#Param inner Round_Rect inner bounds to draw ##
3591#Param paint Paint stroke or fill, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003592
3593#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003594void draw(SkCanvas* canvas) {
3595 SkRRect outer = SkRRect::MakeRect({20, 40, 210, 200});
3596 SkRRect inner = SkRRect::MakeOval({60, 70, 170, 160});
3597 SkPaint paint;
3598 canvas->drawDRRect(outer, inner, paint);
Cary Clark8032b982017-07-28 11:04:54 -04003599}
3600##
3601
3602#Example
3603#Description
3604 Outer Rect has no corner radii, but stroke join is rounded.
3605 Inner Round_Rect has corner radii; outset stroke increases radii of corners.
3606 Stroke join does not affect inner Round_Rect since it has no sharp corners.
3607##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003608void draw(SkCanvas* canvas) {
3609 SkRRect outer = SkRRect::MakeRect({20, 40, 210, 200});
3610 SkRRect inner = SkRRect::MakeRectXY({60, 70, 170, 160}, 10, 10);
3611 SkPaint paint;
3612 paint.setAntiAlias(true);
3613 paint.setStyle(SkPaint::kStroke_Style);
3614 paint.setStrokeWidth(20);
3615 paint.setStrokeJoin(SkPaint::kRound_Join);
3616 canvas->drawDRRect(outer, inner, paint);
3617 paint.setStrokeWidth(1);
3618 paint.setColor(SK_ColorWHITE);
3619 canvas->drawDRRect(outer, inner, paint);
Cary Clark8032b982017-07-28 11:04:54 -04003620}
3621##
3622
Cary Clark2ade9972017-11-02 17:49:34 -04003623#SeeAlso drawRect drawRoundRect drawRRect drawCircle drawOval drawPath
Cary Clark8032b982017-07-28 11:04:54 -04003624
3625##
3626
3627# ------------------------------------------------------------------------------
3628
3629#Method void drawCircle(SkScalar cx, SkScalar cy, SkScalar radius, const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05003630#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05003631#Line # draws Circle using Clip, Matrix, and Paint ##
Cary Clark8032b982017-07-28 11:04:54 -04003632Draw Circle at (cx, cy) with radius using Clip, Matrix, and Paint paint.
3633If radius is zero or less, nothing is drawn.
Herb Derbyefe39bc2018-05-01 17:06:20 -04003634In paint: Paint_Style determines if Circle is stroked or filled;
Cary Clark8032b982017-07-28 11:04:54 -04003635if stroked, Paint_Stroke_Width describes the line thickness.
3636
Cary Clarkbad5ad72017-08-03 17:14:08 -04003637#Param cx Circle center on the x-axis ##
3638#Param cy Circle center on the y-axis ##
3639#Param radius half the diameter of Circle ##
3640#Param paint Paint stroke or fill, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003641
3642#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003643 void draw(SkCanvas* canvas) {
3644 SkPaint paint;
3645 paint.setAntiAlias(true);
3646 canvas->drawCircle(128, 128, 90, paint);
3647 paint.setColor(SK_ColorWHITE);
3648 canvas->drawCircle(86, 86, 20, paint);
3649 canvas->drawCircle(160, 76, 20, paint);
3650 canvas->drawCircle(140, 150, 35, paint);
3651 }
3652##
3653
Cary Clark2ade9972017-11-02 17:49:34 -04003654#SeeAlso drawOval drawRRect drawRoundRect drawPath drawArc drawPoint drawLine
Cary Clarkbad5ad72017-08-03 17:14:08 -04003655
3656##
3657
3658#Method void drawCircle(SkPoint center, SkScalar radius, const SkPaint& paint)
3659
Cary Clarkce101242017-09-01 15:51:02 -04003660Draw Circle at center with radius using Clip, Matrix, and Paint paint.
Cary Clarkbad5ad72017-08-03 17:14:08 -04003661If radius is zero or less, nothing is drawn.
Herb Derbyefe39bc2018-05-01 17:06:20 -04003662In paint: Paint_Style determines if Circle is stroked or filled;
Cary Clarkbad5ad72017-08-03 17:14:08 -04003663if stroked, Paint_Stroke_Width describes the line thickness.
3664
3665#Param center Circle center ##
3666#Param radius half the diameter of Circle ##
3667#Param paint Paint stroke or fill, blend, color, and so on, used to draw ##
3668
3669#Example
3670 void draw(SkCanvas* canvas) {
3671 SkPaint paint;
3672 paint.setAntiAlias(true);
3673 canvas->drawCircle(128, 128, 90, paint);
3674 paint.setColor(SK_ColorWHITE);
3675 canvas->drawCircle({86, 86}, 20, paint);
3676 canvas->drawCircle({160, 76}, 20, paint);
3677 canvas->drawCircle({140, 150}, 35, paint);
3678 }
Cary Clark8032b982017-07-28 11:04:54 -04003679##
3680
Cary Clark2ade9972017-11-02 17:49:34 -04003681#SeeAlso drawOval drawRRect drawRoundRect drawPath drawArc drawPoint drawLine
Cary Clark8032b982017-07-28 11:04:54 -04003682
3683##
3684
3685# ------------------------------------------------------------------------------
3686
3687#Method void drawArc(const SkRect& oval, SkScalar startAngle, SkScalar sweepAngle,
3688 bool useCenter, const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05003689#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05003690#Line # draws Arc using Clip, Matrix, and Paint ##
Cary Clark8032b982017-07-28 11:04:54 -04003691
3692Draw Arc using Clip, Matrix, and Paint paint.
Cary Clarkbad5ad72017-08-03 17:14:08 -04003693
Cary Clark8032b982017-07-28 11:04:54 -04003694Arc is part of Oval bounded by oval, sweeping from startAngle to startAngle plus
3695sweepAngle. startAngle and sweepAngle are in degrees.
Cary Clarkbad5ad72017-08-03 17:14:08 -04003696
Cary Clark8032b982017-07-28 11:04:54 -04003697startAngle of zero places start point at the right middle edge of oval.
3698A positive sweepAngle places Arc end point clockwise from start point;
3699a negative sweepAngle places Arc end point counterclockwise from start point.
3700sweepAngle may exceed 360 degrees, a full circle.
3701If useCenter is true, draw a wedge that includes lines from oval
3702center to Arc end points. If useCenter is false, draw Arc between end points.
3703
3704If Rect oval is empty or sweepAngle is zero, nothing is drawn.
3705
Cary Clarkbad5ad72017-08-03 17:14:08 -04003706#Param oval Rect bounds of Oval containing Arc to draw ##
3707#Param startAngle angle in degrees where Arc begins ##
3708#Param sweepAngle sweep angle in degrees; positive is clockwise ##
3709#Param useCenter if true, include the center of the oval ##
3710#Param paint Paint stroke or fill, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003711
3712#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003713 void draw(SkCanvas* canvas) {
3714 SkPaint paint;
3715 paint.setAntiAlias(true);
3716 SkRect oval = { 4, 4, 60, 60};
3717 for (auto useCenter : { false, true } ) {
3718 for (auto style : { SkPaint::kFill_Style, SkPaint::kStroke_Style } ) {
3719 paint.setStyle(style);
3720 for (auto degrees : { 45, 90, 180, 360} ) {
3721 canvas->drawArc(oval, 0, degrees , useCenter, paint);
3722 canvas->translate(64, 0);
3723 }
3724 canvas->translate(-256, 64);
3725 }
3726 }
Cary Clark8032b982017-07-28 11:04:54 -04003727 }
3728##
3729
3730#Example
3731#Height 64
Cary Clarkbad5ad72017-08-03 17:14:08 -04003732 void draw(SkCanvas* canvas) {
3733 SkPaint paint;
3734 paint.setAntiAlias(true);
3735 paint.setStyle(SkPaint::kStroke_Style);
3736 paint.setStrokeWidth(4);
3737 SkRect oval = { 4, 4, 60, 60};
3738 float intervals[] = { 5, 5 };
3739 paint.setPathEffect(SkDashPathEffect::Make(intervals, 2, 2.5f));
3740 for (auto degrees : { 270, 360, 540, 720 } ) {
3741 canvas->drawArc(oval, 0, degrees, false, paint);
3742 canvas->translate(64, 0);
3743 }
Cary Clark8032b982017-07-28 11:04:54 -04003744 }
3745##
3746
Cary Clark2ade9972017-11-02 17:49:34 -04003747#SeeAlso SkPath::arcTo drawCircle drawOval drawPath
Cary Clark8032b982017-07-28 11:04:54 -04003748
3749##
3750
3751# ------------------------------------------------------------------------------
3752
3753#Method void drawRoundRect(const SkRect& rect, SkScalar rx, SkScalar ry, const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05003754#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05003755#Line # draws Round_Rect using Clip, Matrix, and Paint ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003756Draw Round_Rect bounded by Rect rect, with corner radii (rx, ry) using Clip,
3757Matrix, and Paint paint.
3758
Herb Derbyefe39bc2018-05-01 17:06:20 -04003759In paint: Paint_Style determines if Round_Rect is stroked or filled;
Cary Clark8032b982017-07-28 11:04:54 -04003760if stroked, Paint_Stroke_Width describes the line thickness.
3761If rx or ry are less than zero, they are treated as if they are zero.
3762If rx plus ry exceeds rect width or rect height, radii are scaled down to fit.
Cary Clarkbad5ad72017-08-03 17:14:08 -04003763If rx and ry are zero, Round_Rect is drawn as Rect and if stroked is affected by
3764Paint_Stroke_Join.
Cary Clark8032b982017-07-28 11:04:54 -04003765
Cary Clarkbad5ad72017-08-03 17:14:08 -04003766#Param rect Rect bounds of Round_Rect to draw ##
Cary Clark5538c132018-06-14 12:28:14 -04003767#Param rx axis length on x-axis of oval describing rounded corners ##
3768#Param ry axis length on y-axis of oval describing rounded corners ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003769#Param paint stroke, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003770
3771#Example
3772#Description
3773 Top row has a zero radius a generates a rectangle.
3774 Second row radii sum to less than sides.
3775 Third row radii sum equals sides.
3776 Fourth row radii sum exceeds sides; radii are scaled to fit.
3777##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003778 void draw(SkCanvas* canvas) {
3779 SkVector radii[] = { {0, 20}, {10, 10}, {10, 20}, {10, 40} };
3780 SkPaint paint;
3781 paint.setStrokeWidth(15);
3782 paint.setStrokeJoin(SkPaint::kRound_Join);
3783 paint.setAntiAlias(true);
3784 for (auto style : { SkPaint::kStroke_Style, SkPaint::kFill_Style } ) {
3785 paint.setStyle(style );
3786 for (size_t i = 0; i < SK_ARRAY_COUNT(radii); ++i) {
3787 canvas->drawRoundRect({10, 10, 60, 40}, radii[i].fX, radii[i].fY, paint);
3788 canvas->translate(0, 60);
3789 }
3790 canvas->translate(80, -240);
3791 }
Cary Clark8032b982017-07-28 11:04:54 -04003792 }
3793##
3794
Cary Clark2ade9972017-11-02 17:49:34 -04003795#SeeAlso DrawRRect drawRect drawDRRect drawPath drawCircle drawOval drawPoint
Cary Clark8032b982017-07-28 11:04:54 -04003796
3797##
3798
3799# ------------------------------------------------------------------------------
3800
3801#Method void drawPath(const SkPath& path, const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05003802#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05003803#Line # draws Path using Clip, Matrix, and Paint ##
Cary Clark8032b982017-07-28 11:04:54 -04003804Draw Path path using Clip, Matrix, and Paint paint.
3805Path contains an array of Path_Contour, each of which may be open or closed.
3806
3807In paint: Paint_Style determines if Round_Rect is stroked or filled:
Cary Clarkbad5ad72017-08-03 17:14:08 -04003808if filled, Path_Fill_Type determines whether Path_Contour describes inside or
3809outside of fill; if stroked, Paint_Stroke_Width describes the line thickness,
3810Paint_Stroke_Cap describes line ends, and Paint_Stroke_Join describes how
3811corners are drawn.
Cary Clark8032b982017-07-28 11:04:54 -04003812
Cary Clarkbad5ad72017-08-03 17:14:08 -04003813#Param path Path to draw ##
3814#Param paint stroke, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003815
3816#Example
3817#Description
3818 Top rows draw stroked path with combinations of joins and caps. The open contour
3819 is affected by caps; the closed contour is affected by joins.
Herb Derbyefe39bc2018-05-01 17:06:20 -04003820 Bottom row draws fill the same for open and closed contour.
Cary Clark8032b982017-07-28 11:04:54 -04003821 First bottom column shows winding fills overlap.
3822 Second bottom column shows even odd fills exclude overlap.
3823 Third bottom column shows inverse winding fills area outside both contours.
3824##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003825void draw(SkCanvas* canvas) {
3826 SkPath path;
3827 path.moveTo(20, 20);
3828 path.quadTo(60, 20, 60, 60);
3829 path.close();
3830 path.moveTo(60, 20);
3831 path.quadTo(60, 60, 20, 60);
3832 SkPaint paint;
3833 paint.setStrokeWidth(10);
3834 paint.setAntiAlias(true);
3835 paint.setStyle(SkPaint::kStroke_Style);
3836 for (auto join: { SkPaint::kBevel_Join, SkPaint::kRound_Join, SkPaint::kMiter_Join } ) {
3837 paint.setStrokeJoin(join);
3838 for (auto cap: { SkPaint::kButt_Cap, SkPaint::kSquare_Cap, SkPaint::kRound_Cap } ) {
3839 paint.setStrokeCap(cap);
3840 canvas->drawPath(path, paint);
3841 canvas->translate(80, 0);
3842 }
3843 canvas->translate(-240, 60);
3844 }
3845 paint.setStyle(SkPaint::kFill_Style);
Herb Derbyefe39bc2018-05-01 17:06:20 -04003846 for (auto fill : { SkPath::kWinding_FillType,
3847 SkPath::kEvenOdd_FillType,
Cary Clarkbad5ad72017-08-03 17:14:08 -04003848 SkPath::kInverseWinding_FillType } ) {
3849 path.setFillType(fill);
3850 canvas->save();
3851 canvas->clipRect({0, 10, 80, 70});
3852 canvas->drawPath(path, paint);
3853 canvas->restore();
3854 canvas->translate(80, 0);
3855 }
Cary Clark8032b982017-07-28 11:04:54 -04003856}
3857##
3858
Cary Clark2ade9972017-11-02 17:49:34 -04003859#SeeAlso SkPath drawLine drawArc drawRect drawPoints
Cary Clark8032b982017-07-28 11:04:54 -04003860
3861##
3862
3863# ------------------------------------------------------------------------------
Cary Clark08895c42018-02-01 09:37:32 -05003864#Subtopic Draw_Image
3865#Line # draws Image to Canvas ##
Cary Clark8032b982017-07-28 11:04:54 -04003866
Cary Clarkbad5ad72017-08-03 17:14:08 -04003867drawImage, drawImageRect, and drawImageNine can be called with a bare pointer or
3868a smart pointer as a convenience. The pairs of calls are otherwise identical.
Cary Clark8032b982017-07-28 11:04:54 -04003869
Cary Clark73fa9722017-08-29 17:36:51 -04003870#Method void drawImage(const SkImage* image, SkScalar left, SkScalar top, const SkPaint* paint = nullptr)
Cary Clarkab2621d2018-01-30 10:08:57 -05003871#In Draw_Image
Cary Clark78de7512018-02-07 07:27:09 -05003872#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05003873#Line # draws Image at (x, y) position ##
Cary Clark8032b982017-07-28 11:04:54 -04003874Draw Image image, with its top-left corner at (left, top),
3875using Clip, Matrix, and optional Paint paint.
3876
Cary Clarkbad5ad72017-08-03 17:14:08 -04003877If paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter, Blend_Mode,
3878and Draw_Looper. If image is kAlpha_8_SkColorType, apply Shader.
3879If paint contains Mask_Filter, generate mask from image bounds. If generated
3880mask extends beyond image bounds, replicate image edge colors, just as Shader
3881made from SkImage::makeShader with SkShader::kClamp_TileMode set replicates the
Herb Derbyefe39bc2018-05-01 17:06:20 -04003882image edge color when it samples outside of its bounds.
Cary Clark8032b982017-07-28 11:04:54 -04003883
Cary Clarkbad5ad72017-08-03 17:14:08 -04003884#Param image uncompressed rectangular map of pixels ##
3885#Param left left side of image ##
3886#Param top top side of image ##
3887#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
3888 and so on; or nullptr
3889##
Cary Clark8032b982017-07-28 11:04:54 -04003890
3891#Example
3892#Height 64
3893#Image 4
Cary Clarkbad5ad72017-08-03 17:14:08 -04003894void draw(SkCanvas* canvas) {
3895 // sk_sp<SkImage> image;
3896 SkImage* imagePtr = image.get();
3897 canvas->drawImage(imagePtr, 0, 0);
3898 SkPaint paint;
3899 canvas->drawImage(imagePtr, 80, 0, &paint);
3900 paint.setAlpha(0x80);
3901 canvas->drawImage(imagePtr, 160, 0, &paint);
Cary Clark8032b982017-07-28 11:04:54 -04003902}
3903##
3904
Cary Clark2ade9972017-11-02 17:49:34 -04003905#SeeAlso drawBitmap drawImageLattice drawImageNine drawImageRect SkPaint::setImageFilter
Cary Clark8032b982017-07-28 11:04:54 -04003906
3907##
3908
3909# ------------------------------------------------------------------------------
3910
3911#Method void drawImage(const sk_sp<SkImage>& image, SkScalar left, SkScalar top,
Herb Derbyefe39bc2018-05-01 17:06:20 -04003912 const SkPaint* paint = nullptr)
Cary Clark8032b982017-07-28 11:04:54 -04003913
3914Draw Image image, with its top-left corner at (left, top),
3915using Clip, Matrix, and optional Paint paint.
3916
Cary Clarkbad5ad72017-08-03 17:14:08 -04003917If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
3918Blend_Mode, and Draw_Looper. If image is kAlpha_8_SkColorType, apply Shader.
3919If paint contains Mask_Filter, generate mask from image bounds. If generated
3920mask extends beyond image bounds, replicate image edge colors, just as Shader
3921made from SkImage::makeShader with SkShader::kClamp_TileMode set replicates the
Herb Derbyefe39bc2018-05-01 17:06:20 -04003922image edge color when it samples outside of its bounds.
Cary Clark8032b982017-07-28 11:04:54 -04003923
Cary Clarkbad5ad72017-08-03 17:14:08 -04003924#Param image uncompressed rectangular map of pixels ##
3925#Param left left side of image ##
3926#Param top pop side of image ##
3927#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
3928 and so on; or nullptr
3929##
Cary Clark8032b982017-07-28 11:04:54 -04003930
3931#Example
3932#Height 64
3933#Image 4
Cary Clarkbad5ad72017-08-03 17:14:08 -04003934void draw(SkCanvas* canvas) {
3935 // sk_sp<SkImage> image;
3936 canvas->drawImage(image, 0, 0);
3937 SkPaint paint;
3938 canvas->drawImage(image, 80, 0, &paint);
3939 paint.setAlpha(0x80);
3940 canvas->drawImage(image, 160, 0, &paint);
Cary Clark8032b982017-07-28 11:04:54 -04003941}
3942##
3943
Cary Clark2ade9972017-11-02 17:49:34 -04003944#SeeAlso drawBitmap drawImageLattice drawImageNine drawImageRect SkPaint::setImageFilter
Cary Clark8032b982017-07-28 11:04:54 -04003945
3946##
3947
3948# ------------------------------------------------------------------------------
3949
3950#Enum SrcRectConstraint
Cary Clark08895c42018-02-01 09:37:32 -05003951#Line # sets drawImageRect options ##
Cary Clark8032b982017-07-28 11:04:54 -04003952
3953#Code
3954 enum SrcRectConstraint {
Herb Derbyefe39bc2018-05-01 17:06:20 -04003955 kStrict_SrcRectConstraint,
3956 kFast_SrcRectConstraint,
Cary Clark8032b982017-07-28 11:04:54 -04003957 };
3958##
3959
Cary Clarkce101242017-09-01 15:51:02 -04003960SrcRectConstraint controls the behavior at the edge of source Rect,
3961provided to drawImageRect, trading off speed for precision.
Cary Clark8032b982017-07-28 11:04:54 -04003962
Cary Clarkce101242017-09-01 15:51:02 -04003963Image_Filter in Paint may sample multiple pixels in the image. Source Rect
Cary Clarkbad5ad72017-08-03 17:14:08 -04003964restricts the bounds of pixels that may be read. Image_Filter may slow down if
Herb Derbyefe39bc2018-05-01 17:06:20 -04003965it cannot read outside the bounds, when sampling near the edge of source Rect.
Cary Clark8032b982017-07-28 11:04:54 -04003966SrcRectConstraint specifies whether an Image_Filter is allowed to read pixels
Cary Clarkce101242017-09-01 15:51:02 -04003967outside source Rect.
Cary Clark8032b982017-07-28 11:04:54 -04003968
Cary Clark682c58d2018-05-16 07:07:07 -04003969#Const kStrict_SrcRectConstraint 0
3970#Line # sample only inside bounds; slower ##
Cary Clarkce101242017-09-01 15:51:02 -04003971 Requires Image_Filter to respect source Rect,
Cary Clark8032b982017-07-28 11:04:54 -04003972 sampling only inside of its bounds, possibly with a performance penalty.
3973##
3974
Cary Clark682c58d2018-05-16 07:07:07 -04003975#Const kFast_SrcRectConstraint 1
3976#Line # sample outside bounds; faster ##
Cary Clarkce101242017-09-01 15:51:02 -04003977 Permits Image_Filter to sample outside of source Rect
Cary Clark8032b982017-07-28 11:04:54 -04003978 by half the width of Image_Filter, permitting it to run faster but with
3979 error at the image edges.
3980##
3981
3982#Example
3983#Height 64
3984#Description
3985 redBorder contains a black and white checkerboard bordered by red.
3986 redBorder is drawn scaled by 16 on the left.
Cary Clarkce101242017-09-01 15:51:02 -04003987 The middle and right bitmaps are filtered checkerboards.
Cary Clark8032b982017-07-28 11:04:54 -04003988 Drawing the checkerboard with kStrict_SrcRectConstraint shows only a blur of black and white.
3989 Drawing the checkerboard with kFast_SrcRectConstraint allows red to bleed in the corners.
3990##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003991void draw(SkCanvas* canvas) {
3992 SkBitmap redBorder;
3993 redBorder.allocPixels(SkImageInfo::MakeN32Premul(4, 4));
3994 SkCanvas checkRed(redBorder);
3995 checkRed.clear(SK_ColorRED);
3996 uint32_t checkers[][2] = { { SK_ColorBLACK, SK_ColorWHITE },
3997 { SK_ColorWHITE, SK_ColorBLACK } };
3998 checkRed.writePixels(
3999 SkImageInfo::MakeN32Premul(2, 2), (void*) checkers, sizeof(checkers[0]), 1, 1);
4000 canvas->scale(16, 16);
4001 canvas->drawBitmap(redBorder, 0, 0, nullptr);
4002 canvas->resetMatrix();
4003 sk_sp<SkImage> image = SkImage::MakeFromBitmap(redBorder);
4004 SkPaint lowPaint;
4005 lowPaint.setFilterQuality(kLow_SkFilterQuality);
4006 for (auto constraint : { SkCanvas::kStrict_SrcRectConstraint,
4007 SkCanvas::kFast_SrcRectConstraint } ) {
4008 canvas->translate(80, 0);
4009 canvas->drawImageRect(image.get(), SkRect::MakeLTRB(1, 1, 3, 3),
4010 SkRect::MakeLTRB(16, 16, 48, 48), &lowPaint, constraint);
4011 }
Cary Clark8032b982017-07-28 11:04:54 -04004012}
4013##
4014
Cary Clark2ade9972017-11-02 17:49:34 -04004015#SeeAlso drawImageRect drawImage SkPaint::setImageFilter
Cary Clark8032b982017-07-28 11:04:54 -04004016
4017##
4018
4019# ------------------------------------------------------------------------------
4020
4021#Method void drawImageRect(const SkImage* image, const SkRect& src, const SkRect& dst,
4022 const SkPaint* paint,
4023 SrcRectConstraint constraint = kStrict_SrcRectConstraint)
Cary Clarkab2621d2018-01-30 10:08:57 -05004024#In Draw_Image
Cary Clark78de7512018-02-07 07:27:09 -05004025#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05004026#Line # draws Image, source Rect to destination Rect ##
Cary Clark8032b982017-07-28 11:04:54 -04004027
4028Draw Rect src of Image image, scaled and translated to fill Rect dst.
4029Additionally transform draw using Clip, Matrix, and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004030
Cary Clarkbad5ad72017-08-03 17:14:08 -04004031If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4032Blend_Mode, and Draw_Looper. If image is kAlpha_8_SkColorType, apply Shader.
4033If paint contains Mask_Filter, generate mask from image bounds.
4034
4035If generated mask extends beyond image bounds, replicate image edge colors, just
4036as Shader made from SkImage::makeShader with SkShader::kClamp_TileMode set
Cary Clarkbc5697d2017-10-04 14:31:33 -04004037replicates the image edge color when it samples outside of its bounds.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004038
4039constraint set to kStrict_SrcRectConstraint limits Paint Filter_Quality to
4040sample within src; set to kFast_SrcRectConstraint allows sampling outside to
4041improve performance.
4042
4043#Param image Image containing pixels, dimensions, and format ##
4044#Param src source Rect of image to draw from ##
4045#Param dst destination Rect of image to draw to ##
4046#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4047 and so on; or nullptr
4048##
4049#Param constraint filter strictly within src or draw faster ##
Cary Clark8032b982017-07-28 11:04:54 -04004050
4051#Example
4052#Height 64
4053#Description
4054 The left bitmap draws with Paint default kNone_SkFilterQuality, and stays within
Cary Clarkbc5697d2017-10-04 14:31:33 -04004055 its bounds; there is no bleeding with kFast_SrcRectConstraint.
Cary Clark8032b982017-07-28 11:04:54 -04004056 the middle and right bitmaps draw with kLow_SkFilterQuality; with
4057 kStrict_SrcRectConstraint, the filter remains within the checkerboard, and
4058 with kFast_SrcRectConstraint red bleeds on the edges.
4059##
Cary Clarkbad5ad72017-08-03 17:14:08 -04004060void draw(SkCanvas* canvas) {
Herb Derbyefe39bc2018-05-01 17:06:20 -04004061 uint32_t pixels[][4] = {
Cary Clarkbad5ad72017-08-03 17:14:08 -04004062 { 0xFFFF0000, 0xFFFF0000, 0xFFFF0000, 0xFFFF0000 },
4063 { 0xFFFF0000, 0xFF000000, 0xFFFFFFFF, 0xFFFF0000 },
4064 { 0xFFFF0000, 0xFFFFFFFF, 0xFF000000, 0xFFFF0000 },
4065 { 0xFFFF0000, 0xFFFF0000, 0xFFFF0000, 0xFFFF0000 } };
4066 SkBitmap redBorder;
Herb Derbyefe39bc2018-05-01 17:06:20 -04004067 redBorder.installPixels(SkImageInfo::MakeN32Premul(4, 4),
Cary Clarkbad5ad72017-08-03 17:14:08 -04004068 (void*) pixels, sizeof(pixels[0]));
4069 sk_sp<SkImage> image = SkImage::MakeFromBitmap(redBorder);
4070 SkPaint lowPaint;
4071 for (auto constraint : {
4072 SkCanvas::kFast_SrcRectConstraint,
4073 SkCanvas::kStrict_SrcRectConstraint,
4074 SkCanvas::kFast_SrcRectConstraint } ) {
4075 canvas->drawImageRect(image.get(), SkRect::MakeLTRB(1, 1, 3, 3),
4076 SkRect::MakeLTRB(16, 16, 48, 48), &lowPaint, constraint);
4077 lowPaint.setFilterQuality(kLow_SkFilterQuality);
4078 canvas->translate(80, 0);
4079 }
4080}
Cary Clark8032b982017-07-28 11:04:54 -04004081##
4082
Cary Clark2ade9972017-11-02 17:49:34 -04004083#SeeAlso SrcRectConstraint drawImage drawImageLattice drawImageNine
Cary Clark8032b982017-07-28 11:04:54 -04004084
4085##
4086
4087# ------------------------------------------------------------------------------
4088
4089#Method void drawImageRect(const SkImage* image, const SkIRect& isrc, const SkRect& dst,
4090 const SkPaint* paint, SrcRectConstraint constraint = kStrict_SrcRectConstraint)
Cary Clarkab2621d2018-01-30 10:08:57 -05004091#In Draw_Image
Cary Clark78de7512018-02-07 07:27:09 -05004092#In Draw
Cary Clark8032b982017-07-28 11:04:54 -04004093
4094Draw IRect isrc of Image image, scaled and translated to fill Rect dst.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004095Note that isrc is on integer pixel boundaries; dst may include fractional
4096boundaries. Additionally transform draw using Clip, Matrix, and optional Paint
Herb Derbyefe39bc2018-05-01 17:06:20 -04004097paint.
Cary Clark8032b982017-07-28 11:04:54 -04004098
Cary Clarkbad5ad72017-08-03 17:14:08 -04004099If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4100Blend_Mode, and Draw_Looper. If image is kAlpha_8_SkColorType, apply Shader.
4101If paint contains Mask_Filter, generate mask from image bounds.
4102
4103If generated mask extends beyond image bounds, replicate image edge colors, just
4104as Shader made from SkImage::makeShader with SkShader::kClamp_TileMode set
Cary Clarkbc5697d2017-10-04 14:31:33 -04004105replicates the image edge color when it samples outside of its bounds.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004106
4107constraint set to kStrict_SrcRectConstraint limits Paint Filter_Quality to
Cary Clarkce101242017-09-01 15:51:02 -04004108sample within isrc; set to kFast_SrcRectConstraint allows sampling outside to
Cary Clarkbad5ad72017-08-03 17:14:08 -04004109improve performance.
4110
4111#Param image Image containing pixels, dimensions, and format ##
4112#Param isrc source IRect of image to draw from ##
4113#Param dst destination Rect of image to draw to ##
4114#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4115 and so on; or nullptr
4116##
Cary Clarkce101242017-09-01 15:51:02 -04004117#Param constraint filter strictly within isrc or draw faster ##
Cary Clark8032b982017-07-28 11:04:54 -04004118
4119#Example
4120#Image 4
Cary Clarkbad5ad72017-08-03 17:14:08 -04004121void draw(SkCanvas* canvas) {
4122 // sk_sp<SkImage> image;
4123 for (auto i : { 1, 2, 4, 8 } ) {
Herb Derbyefe39bc2018-05-01 17:06:20 -04004124 canvas->drawImageRect(image.get(), SkIRect::MakeLTRB(0, 0, 100, 100),
Cary Clarkbad5ad72017-08-03 17:14:08 -04004125 SkRect::MakeXYWH(i * 20, i * 20, i * 20, i * 20), nullptr);
4126 }
Cary Clark8032b982017-07-28 11:04:54 -04004127}
4128##
4129
Cary Clark2ade9972017-11-02 17:49:34 -04004130#SeeAlso SrcRectConstraint drawImage drawImageLattice drawImageNine
Cary Clark8032b982017-07-28 11:04:54 -04004131
4132##
4133
4134# ------------------------------------------------------------------------------
4135
4136#Method void drawImageRect(const SkImage* image, const SkRect& dst, const SkPaint* paint,
4137 SrcRectConstraint constraint = kStrict_SrcRectConstraint)
Cary Clarkab2621d2018-01-30 10:08:57 -05004138#In Draw_Image
Cary Clark78de7512018-02-07 07:27:09 -05004139#In Draw
Cary Clark8032b982017-07-28 11:04:54 -04004140
Cary Clarkbad5ad72017-08-03 17:14:08 -04004141Draw Image image, scaled and translated to fill Rect dst, using Clip, Matrix,
4142and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004143
Cary Clarkbad5ad72017-08-03 17:14:08 -04004144If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4145Blend_Mode, and Draw_Looper. If image is kAlpha_8_SkColorType, apply Shader.
4146If paint contains Mask_Filter, generate mask from image bounds.
4147
4148If generated mask extends beyond image bounds, replicate image edge colors, just
4149as Shader made from SkImage::makeShader with SkShader::kClamp_TileMode set
Cary Clarkbc5697d2017-10-04 14:31:33 -04004150replicates the image edge color when it samples outside of its bounds.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004151
4152constraint set to kStrict_SrcRectConstraint limits Paint Filter_Quality to
Cary Clarkce101242017-09-01 15:51:02 -04004153sample within image; set to kFast_SrcRectConstraint allows sampling outside to
Cary Clarkbad5ad72017-08-03 17:14:08 -04004154improve performance.
4155
4156#Param image Image containing pixels, dimensions, and format ##
4157#Param dst destination Rect of image to draw to ##
4158#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4159 and so on; or nullptr
4160##
Cary Clarkce101242017-09-01 15:51:02 -04004161#Param constraint filter strictly within image or draw faster ##
Cary Clark8032b982017-07-28 11:04:54 -04004162
4163#Example
4164#Image 4
Cary Clarkbad5ad72017-08-03 17:14:08 -04004165void draw(SkCanvas* canvas) {
4166 // sk_sp<SkImage> image;
4167 for (auto i : { 20, 40, 80, 160 } ) {
4168 canvas->drawImageRect(image.get(), SkRect::MakeXYWH(i, i, i, i), nullptr);
4169 }
Cary Clark8032b982017-07-28 11:04:54 -04004170}
4171##
4172
Cary Clark2ade9972017-11-02 17:49:34 -04004173#SeeAlso SrcRectConstraint drawImage drawImageLattice drawImageNine
Cary Clark8032b982017-07-28 11:04:54 -04004174
4175##
4176
4177# ------------------------------------------------------------------------------
4178
4179#Method void drawImageRect(const sk_sp<SkImage>& image, const SkRect& src, const SkRect& dst,
4180 const SkPaint* paint,
Herb Derbyefe39bc2018-05-01 17:06:20 -04004181 SrcRectConstraint constraint = kStrict_SrcRectConstraint)
Cary Clarkab2621d2018-01-30 10:08:57 -05004182#In Draw_Image
Cary Clark78de7512018-02-07 07:27:09 -05004183#In Draw
Cary Clark8032b982017-07-28 11:04:54 -04004184Draw Rect src of Image image, scaled and translated to fill Rect dst.
4185Additionally transform draw using Clip, Matrix, and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004186
Cary Clarkbad5ad72017-08-03 17:14:08 -04004187If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4188Blend_Mode, and Draw_Looper. If image is kAlpha_8_SkColorType, apply Shader.
4189If paint contains Mask_Filter, generate mask from image bounds.
4190
4191If generated mask extends beyond image bounds, replicate image edge colors, just
4192as Shader made from SkImage::makeShader with SkShader::kClamp_TileMode set
Cary Clarkbc5697d2017-10-04 14:31:33 -04004193replicates the image edge color when it samples outside of its bounds.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004194
4195constraint set to kStrict_SrcRectConstraint limits Paint Filter_Quality to
4196sample within src; set to kFast_SrcRectConstraint allows sampling outside to
4197improve performance.
4198
4199#Param image Image containing pixels, dimensions, and format ##
4200#Param src source Rect of image to draw from ##
4201#Param dst destination Rect of image to draw to ##
4202#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4203 and so on; or nullptr
4204##
4205#Param constraint filter strictly within src or draw faster ##
Cary Clark8032b982017-07-28 11:04:54 -04004206
4207#Example
4208#Height 64
4209#Description
4210 Canvas scales and translates; transformation from src to dst also scales.
4211 The two matrices are concatenated to create the final transformation.
4212##
Cary Clarkbad5ad72017-08-03 17:14:08 -04004213void draw(SkCanvas* canvas) {
4214 uint32_t pixels[][2] = { { SK_ColorBLACK, SK_ColorWHITE },
4215 { SK_ColorWHITE, SK_ColorBLACK } };
4216 SkBitmap bitmap;
Herb Derbyefe39bc2018-05-01 17:06:20 -04004217 bitmap.installPixels(SkImageInfo::MakeN32Premul(2, 2),
Cary Clarkbad5ad72017-08-03 17:14:08 -04004218 (void*) pixels, sizeof(pixels[0]));
4219 sk_sp<SkImage> image = SkImage::MakeFromBitmap(bitmap);
4220 SkPaint paint;
4221 canvas->scale(4, 4);
4222 for (auto alpha : { 50, 100, 150, 255 } ) {
4223 paint.setAlpha(alpha);
4224 canvas->drawImageRect(image, SkRect::MakeWH(2, 2), SkRect::MakeWH(8, 8), &paint);
4225 canvas->translate(8, 0);
4226 }
4227}
Cary Clark8032b982017-07-28 11:04:54 -04004228##
4229
Cary Clark2ade9972017-11-02 17:49:34 -04004230#SeeAlso SrcRectConstraint drawImage drawImageLattice drawImageNine
Cary Clark8032b982017-07-28 11:04:54 -04004231
4232##
4233
4234# ------------------------------------------------------------------------------
4235
4236#Method void drawImageRect(const sk_sp<SkImage>& image, const SkIRect& isrc, const SkRect& dst,
Herb Derbyefe39bc2018-05-01 17:06:20 -04004237 const SkPaint* paint, SrcRectConstraint constraint = kStrict_SrcRectConstraint)
Cary Clarkab2621d2018-01-30 10:08:57 -05004238#In Draw_Image
Cary Clark78de7512018-02-07 07:27:09 -05004239#In Draw
Cary Clark8032b982017-07-28 11:04:54 -04004240Draw IRect isrc of Image image, scaled and translated to fill Rect dst.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004241isrc is on integer pixel boundaries; dst may include fractional boundaries.
Cary Clark8032b982017-07-28 11:04:54 -04004242Additionally transform draw using Clip, Matrix, and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004243
Cary Clarkbad5ad72017-08-03 17:14:08 -04004244If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4245Blend_Mode, and Draw_Looper. If image is kAlpha_8_SkColorType, apply Shader.
4246If paint contains Mask_Filter, generate mask from image bounds.
4247
4248If generated mask extends beyond image bounds, replicate image edge colors, just
4249as Shader made from SkImage::makeShader with SkShader::kClamp_TileMode set
Cary Clarkbc5697d2017-10-04 14:31:33 -04004250replicates the image edge color when it samples outside of its bounds.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004251
4252constraint set to kStrict_SrcRectConstraint limits Paint Filter_Quality to
Cary Clarkce101242017-09-01 15:51:02 -04004253sample within image; set to kFast_SrcRectConstraint allows sampling outside to
Cary Clarkbad5ad72017-08-03 17:14:08 -04004254improve performance.
4255
4256#Param image Image containing pixels, dimensions, and format ##
4257#Param isrc source IRect of image to draw from ##
4258#Param dst destination Rect of image to draw to ##
4259#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4260 and so on; or nullptr
4261##
Cary Clarkce101242017-09-01 15:51:02 -04004262#Param constraint filter strictly within image or draw faster ##
Cary Clark8032b982017-07-28 11:04:54 -04004263
4264#Example
4265#Height 64
Cary Clarkbad5ad72017-08-03 17:14:08 -04004266void draw(SkCanvas* canvas) {
4267 uint32_t pixels[][2] = { { 0x00000000, 0x55555555},
4268 { 0xAAAAAAAA, 0xFFFFFFFF} };
4269 SkBitmap bitmap;
Herb Derbyefe39bc2018-05-01 17:06:20 -04004270 bitmap.installPixels(SkImageInfo::MakeN32Premul(2, 2),
Cary Clarkbad5ad72017-08-03 17:14:08 -04004271 (void*) pixels, sizeof(pixels[0]));
4272 sk_sp<SkImage> image = SkImage::MakeFromBitmap(bitmap);
4273 SkPaint paint;
4274 canvas->scale(4, 4);
4275 for (auto color : { SK_ColorRED, SK_ColorBLUE, SK_ColorGREEN } ) {
4276 paint.setColorFilter(SkColorFilter::MakeModeFilter(color, SkBlendMode::kPlus));
4277 canvas->drawImageRect(image, SkIRect::MakeWH(2, 2), SkRect::MakeWH(8, 8), &paint);
4278 canvas->translate(8, 0);
4279 }
Cary Clark8032b982017-07-28 11:04:54 -04004280}
4281##
4282
Cary Clark2ade9972017-11-02 17:49:34 -04004283#SeeAlso SrcRectConstraint drawImage drawImageLattice drawImageNine
4284
Cary Clark8032b982017-07-28 11:04:54 -04004285##
4286
4287# ------------------------------------------------------------------------------
4288
4289#Method void drawImageRect(const sk_sp<SkImage>& image, const SkRect& dst, const SkPaint* paint,
Herb Derbyefe39bc2018-05-01 17:06:20 -04004290 SrcRectConstraint constraint = kStrict_SrcRectConstraint)
Cary Clarkab2621d2018-01-30 10:08:57 -05004291#In Draw_Image
Cary Clark78de7512018-02-07 07:27:09 -05004292#In Draw
Cary Clark8032b982017-07-28 11:04:54 -04004293Draw Image image, scaled and translated to fill Rect dst,
4294using Clip, Matrix, and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004295
Cary Clarkbad5ad72017-08-03 17:14:08 -04004296If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4297Blend_Mode, and Draw_Looper. If image is kAlpha_8_SkColorType, apply Shader.
4298If paint contains Mask_Filter, generate mask from image bounds.
4299
4300If generated mask extends beyond image bounds, replicate image edge colors, just
4301as Shader made from SkImage::makeShader with SkShader::kClamp_TileMode set
Cary Clarkbc5697d2017-10-04 14:31:33 -04004302replicates the image edge color when it samples outside of its bounds.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004303
4304constraint set to kStrict_SrcRectConstraint limits Paint Filter_Quality to
Cary Clarkce101242017-09-01 15:51:02 -04004305sample within image; set to kFast_SrcRectConstraint allows sampling outside to
Cary Clarkbad5ad72017-08-03 17:14:08 -04004306improve performance.
4307
4308#Param image Image containing pixels, dimensions, and format ##
4309#Param dst destination Rect of image to draw to ##
4310#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4311 and so on; or nullptr
4312##
Cary Clarkce101242017-09-01 15:51:02 -04004313#Param constraint filter strictly within image or draw faster ##
Cary Clark8032b982017-07-28 11:04:54 -04004314
4315#Example
4316#Height 64
Cary Clarkbad5ad72017-08-03 17:14:08 -04004317void draw(SkCanvas* canvas) {
4318 uint32_t pixels[][2] = { { 0x00000000, 0x55550000},
4319 { 0xAAAA0000, 0xFFFF0000} };
4320 SkBitmap bitmap;
Herb Derbyefe39bc2018-05-01 17:06:20 -04004321 bitmap.installPixels(SkImageInfo::MakeN32Premul(2, 2),
Cary Clarkbad5ad72017-08-03 17:14:08 -04004322 (void*) pixels, sizeof(pixels[0]));
4323 sk_sp<SkImage> image = SkImage::MakeFromBitmap(bitmap);
4324 SkPaint paint;
4325 canvas->scale(4, 4);
4326 for (auto color : { SK_ColorRED, SK_ColorBLUE, SK_ColorGREEN } ) {
4327 paint.setColorFilter(SkColorFilter::MakeModeFilter(color, SkBlendMode::kPlus));
4328 canvas->drawImageRect(image, SkRect::MakeWH(8, 8), &paint);
4329 canvas->translate(8, 0);
4330 }
Cary Clark8032b982017-07-28 11:04:54 -04004331}
4332##
4333
Cary Clark2ade9972017-11-02 17:49:34 -04004334#SeeAlso SrcRectConstraint drawImage drawImageLattice drawImageNine
Cary Clark8032b982017-07-28 11:04:54 -04004335
4336##
4337
4338# ------------------------------------------------------------------------------
4339
4340#Method void drawImageNine(const SkImage* image, const SkIRect& center, const SkRect& dst,
4341 const SkPaint* paint = nullptr)
Cary Clarkab2621d2018-01-30 10:08:57 -05004342#In Draw_Image
Cary Clark78de7512018-02-07 07:27:09 -05004343#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05004344#Line # draws Nine_Patch Image ##
Cary Clark8032b982017-07-28 11:04:54 -04004345
Cary Clarkd0530ba2017-09-14 11:25:39 -04004346Draw Image image stretched proportionally to fit into Rect dst.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004347IRect center divides the image into nine sections: four sides, four corners, and
Cary Clarkce101242017-09-01 15:51:02 -04004348the center. Corners are unmodified or scaled down proportionately if their sides
Cary Clarkbad5ad72017-08-03 17:14:08 -04004349are larger than dst; center and four sides are scaled to fit remaining space, if any.
Cary Clark8032b982017-07-28 11:04:54 -04004350
Cary Clarkbad5ad72017-08-03 17:14:08 -04004351Additionally transform draw using Clip, Matrix, and optional Paint paint.
4352
Cary Clark682c58d2018-05-16 07:07:07 -04004353#paint_as_used_by_draw_lattice_or_draw_nine(image)#
Cary Clarkbad5ad72017-08-03 17:14:08 -04004354
4355If generated mask extends beyond image bounds, replicate image edge colors, just
4356as Shader made from SkImage::makeShader with SkShader::kClamp_TileMode set
Cary Clarkbc5697d2017-10-04 14:31:33 -04004357replicates the image edge color when it samples outside of its bounds.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004358
4359#Param image Image containing pixels, dimensions, and format ##
4360#Param center IRect edge of image corners and sides ##
4361#Param dst destination Rect of image to draw to ##
4362#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4363 and so on; or nullptr
4364##
Cary Clark8032b982017-07-28 11:04:54 -04004365
4366#Example
4367#Height 128
4368#Description
4369 The leftmost image is smaller than center; only corners are drawn, all scaled to fit.
Cary Clarkce101242017-09-01 15:51:02 -04004370 The second image equals the size of center; only corners are drawn without scaling.
4371 The remaining images are larger than center. All corners draw without scaling.
4372 The sides and center are scaled if needed to take up the remaining space.
Cary Clark8032b982017-07-28 11:04:54 -04004373##
Cary Clarkbad5ad72017-08-03 17:14:08 -04004374void draw(SkCanvas* canvas) {
4375 SkIRect center = { 20, 10, 50, 40 };
4376 SkBitmap bitmap;
4377 bitmap.allocPixels(SkImageInfo::MakeN32Premul(60, 60));
4378 SkCanvas bitCanvas(bitmap);
4379 SkPaint paint;
4380 SkColor gray = 0xFF000000;
4381 int left = 0;
4382 for (auto right: { center.fLeft, center.fRight, bitmap.width() } ) {
4383 int top = 0;
4384 for (auto bottom: { center.fTop, center.fBottom, bitmap.height() } ) {
4385 paint.setColor(gray);
4386 bitCanvas.drawIRect(SkIRect::MakeLTRB(left, top, right, bottom), paint);
4387 gray += 0x001f1f1f;
4388 top = bottom;
4389 }
Herb Derbyefe39bc2018-05-01 17:06:20 -04004390 left = right;
Cary Clarkbad5ad72017-08-03 17:14:08 -04004391 }
4392 sk_sp<SkImage> image = SkImage::MakeFromBitmap(bitmap);
4393 SkImage* imagePtr = image.get();
4394 for (auto dest: { 20, 30, 40, 60, 90 } ) {
4395 canvas->drawImageNine(imagePtr, center, SkRect::MakeWH(dest, dest), nullptr);
4396 canvas->translate(dest + 4, 0);
4397 }
Cary Clark8032b982017-07-28 11:04:54 -04004398}
4399##
4400
Cary Clark2ade9972017-11-02 17:49:34 -04004401#SeeAlso drawImage drawBitmapNine drawImageLattice drawImageRect
Cary Clark8032b982017-07-28 11:04:54 -04004402
4403##
4404
4405# ------------------------------------------------------------------------------
4406
4407#Method void drawImageNine(const sk_sp<SkImage>& image, const SkIRect& center, const SkRect& dst,
Herb Derbyefe39bc2018-05-01 17:06:20 -04004408 const SkPaint* paint = nullptr)
Cary Clarkab2621d2018-01-30 10:08:57 -05004409#In Draw_Image
Cary Clark78de7512018-02-07 07:27:09 -05004410#In Draw
Cary Clarkd0530ba2017-09-14 11:25:39 -04004411Draw Image image stretched proportionally to fit into Rect dst.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004412IRect center divides the image into nine sections: four sides, four corners, and
Cary Clarkce101242017-09-01 15:51:02 -04004413the center. Corners are not scaled, or scaled down proportionately if their sides
Cary Clarkbad5ad72017-08-03 17:14:08 -04004414are larger than dst; center and four sides are scaled to fit remaining space, if any.
Cary Clark8032b982017-07-28 11:04:54 -04004415
Cary Clarkbad5ad72017-08-03 17:14:08 -04004416Additionally transform draw using Clip, Matrix, and optional Paint paint.
4417
Cary Clark137b8742018-05-30 09:21:49 -04004418#paint_as_used_by_draw_lattice_or_draw_nine(image)#
Cary Clarkbad5ad72017-08-03 17:14:08 -04004419
4420If generated mask extends beyond image bounds, replicate image edge colors, just
4421as Shader made from SkImage::makeShader with SkShader::kClamp_TileMode set
Cary Clarkbc5697d2017-10-04 14:31:33 -04004422replicates the image edge color when it samples outside of its bounds.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004423
4424#Param image Image containing pixels, dimensions, and format ##
4425#Param center IRect edge of image corners and sides ##
4426#Param dst destination Rect of image to draw to ##
4427#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4428 and so on; or nullptr
4429##
Cary Clark8032b982017-07-28 11:04:54 -04004430
4431#Example
4432#Height 128
4433#Description
4434 The two leftmost images has four corners and sides to the left and right of center.
4435 The leftmost image scales the width of corners proportionately to fit.
Herb Derbyefe39bc2018-05-01 17:06:20 -04004436 The third and fourth image corners are not scaled; the sides and center are scaled to
Cary Clark8032b982017-07-28 11:04:54 -04004437 fill the remaining space.
4438 The rightmost image has four corners scaled vertically to fit, and uses sides above
4439 and below center to fill the remaining space.
4440##
Cary Clarkbad5ad72017-08-03 17:14:08 -04004441void draw(SkCanvas* canvas) {
4442 SkIRect center = { 20, 10, 50, 40 };
4443 SkBitmap bitmap;
4444 bitmap.allocPixels(SkImageInfo::MakeN32Premul(60, 60));
4445 SkCanvas bitCanvas(bitmap);
4446 SkPaint paint;
4447 SkColor gray = 0xFF000000;
4448 int left = 0;
4449 for (auto right: { center.fLeft, center.fRight, bitmap.width() } ) {
4450 int top = 0;
4451 for (auto bottom: { center.fTop, center.fBottom, bitmap.height() } ) {
4452 paint.setColor(gray);
4453 bitCanvas.drawIRect(SkIRect::MakeLTRB(left, top, right, bottom), paint);
4454 gray += 0x001f1f1f;
4455 top = bottom;
4456 }
Herb Derbyefe39bc2018-05-01 17:06:20 -04004457 left = right;
Cary Clarkbad5ad72017-08-03 17:14:08 -04004458 }
4459 sk_sp<SkImage> image = SkImage::MakeFromBitmap(bitmap);
4460 for (auto dest: { 20, 30, 40, 60, 90 } ) {
4461 canvas->drawImageNine(image, center, SkRect::MakeWH(dest, 110 - dest), nullptr);
4462 canvas->translate(dest + 4, 0);
4463 }
Cary Clark8032b982017-07-28 11:04:54 -04004464}
4465##
4466
Cary Clark2ade9972017-11-02 17:49:34 -04004467#SeeAlso drawImage drawBitmapNine drawImageLattice drawImageRect
Cary Clark8032b982017-07-28 11:04:54 -04004468
4469##
4470
4471# ------------------------------------------------------------------------------
4472
4473#Method void drawBitmap(const SkBitmap& bitmap, SkScalar left, SkScalar top,
Cary Clark73fa9722017-08-29 17:36:51 -04004474 const SkPaint* paint = nullptr)
Cary Clarkab2621d2018-01-30 10:08:57 -05004475#In Draw_Image
Cary Clark78de7512018-02-07 07:27:09 -05004476#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05004477#Line # draws Bitmap at (x, y) position ##
Cary Clark8032b982017-07-28 11:04:54 -04004478
4479Draw Bitmap bitmap, with its top-left corner at (left, top),
4480using Clip, Matrix, and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004481
Cary Clarka560c472017-11-27 10:44:06 -05004482If Paint paint is not nullptr, apply Color_Filter, Color_Alpha, Image_Filter,
Cary Clarkbad5ad72017-08-03 17:14:08 -04004483Blend_Mode, and Draw_Looper. If bitmap is kAlpha_8_SkColorType, apply Shader.
4484If paint contains Mask_Filter, generate mask from bitmap bounds.
4485
4486If generated mask extends beyond bitmap bounds, replicate bitmap edge colors,
4487just as Shader made from SkShader::MakeBitmapShader with
Cary Clarkbc5697d2017-10-04 14:31:33 -04004488SkShader::kClamp_TileMode set replicates the bitmap edge color when it samples
Herb Derbyefe39bc2018-05-01 17:06:20 -04004489outside of its bounds.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004490
4491#Param bitmap Bitmap containing pixels, dimensions, and format ##
4492#Param left left side of bitmap ##
4493#Param top top side of bitmap ##
4494#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4495 and so on; or nullptr
4496##
Cary Clark8032b982017-07-28 11:04:54 -04004497
4498#Example
4499#Height 64
Cary Clarkbad5ad72017-08-03 17:14:08 -04004500void draw(SkCanvas* canvas) {
4501 uint8_t pixels[][8] = { { 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00},
4502 { 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00},
4503 { 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00},
4504 { 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF},
4505 { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
4506 { 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00},
4507 { 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0x00},
4508 { 0xFF, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0xFF} };
4509 SkBitmap bitmap;
Herb Derbyefe39bc2018-05-01 17:06:20 -04004510 bitmap.installPixels(SkImageInfo::MakeA8(8, 8),
Cary Clarkbad5ad72017-08-03 17:14:08 -04004511 (void*) pixels, sizeof(pixels[0]));
4512 SkPaint paint;
4513 canvas->scale(4, 4);
4514 for (auto color : { SK_ColorRED, SK_ColorBLUE, 0xFF007F00} ) {
4515 paint.setColor(color);
4516 canvas->drawBitmap(bitmap, 0, 0, &paint);
4517 canvas->translate(12, 0);
4518 }
Cary Clark8032b982017-07-28 11:04:54 -04004519}
4520##
4521
Cary Clark2ade9972017-11-02 17:49:34 -04004522#SeeAlso drawImage drawBitmapLattice drawBitmapNine drawBitmapRect SkBitmap::readPixels SkBitmap::writePixels
Cary Clark8032b982017-07-28 11:04:54 -04004523
4524##
4525
4526# ------------------------------------------------------------------------------
4527
4528#Method void drawBitmapRect(const SkBitmap& bitmap, const SkRect& src, const SkRect& dst,
4529 const SkPaint* paint, SrcRectConstraint constraint = kStrict_SrcRectConstraint)
Cary Clarkab2621d2018-01-30 10:08:57 -05004530#In Draw_Image
Cary Clark78de7512018-02-07 07:27:09 -05004531#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05004532#Line # draws Bitmap, source Rect to destination Rect ##
Cary Clark8032b982017-07-28 11:04:54 -04004533
4534Draw Rect src of Bitmap bitmap, scaled and translated to fill Rect dst.
4535Additionally transform draw using Clip, Matrix, and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004536
Cary Clarkbad5ad72017-08-03 17:14:08 -04004537If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4538Blend_Mode, and Draw_Looper. If bitmap is kAlpha_8_SkColorType, apply Shader.
4539If paint contains Mask_Filter, generate mask from bitmap bounds.
4540
4541If generated mask extends beyond bitmap bounds, replicate bitmap edge colors,
4542just as Shader made from SkShader::MakeBitmapShader with
Cary Clarkbc5697d2017-10-04 14:31:33 -04004543SkShader::kClamp_TileMode set replicates the bitmap edge color when it samples
Cary Clarkbad5ad72017-08-03 17:14:08 -04004544outside of its bounds.
4545
4546constraint set to kStrict_SrcRectConstraint limits Paint Filter_Quality to
4547sample within src; set to kFast_SrcRectConstraint allows sampling outside to
4548improve performance.
4549
4550#Param bitmap Bitmap containing pixels, dimensions, and format ##
4551#Param src source Rect of image to draw from ##
4552#Param dst destination Rect of image to draw to ##
4553#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4554 and so on; or nullptr
4555##
4556#Param constraint filter strictly within src or draw faster ##
Cary Clark8032b982017-07-28 11:04:54 -04004557
4558#Example
4559#Height 64
Cary Clarkbad5ad72017-08-03 17:14:08 -04004560void draw(SkCanvas* canvas) {
4561 uint8_t pixels[][8] = { { 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00},
4562 { 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00},
4563 { 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00},
4564 { 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF},
4565 { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
4566 { 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00},
4567 { 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00},
4568 { 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00} };
4569 SkBitmap bitmap;
Herb Derbyefe39bc2018-05-01 17:06:20 -04004570 bitmap.installPixels(SkImageInfo::MakeA8(8, 8),
Cary Clarkbad5ad72017-08-03 17:14:08 -04004571 (void*) pixels, sizeof(pixels[0]));
4572 SkPaint paint;
Cary Clark681287e2018-03-16 11:34:15 -04004573 paint.setMaskFilter(SkMaskFilter::MakeBlur(kSolid_SkBlurStyle, 6));
Cary Clarkbad5ad72017-08-03 17:14:08 -04004574 for (auto color : { SK_ColorRED, SK_ColorBLUE, 0xFF007F00} ) {
4575 paint.setColor(color);
4576 canvas->drawBitmapRect(bitmap, SkRect::MakeWH(8, 8), SkRect::MakeWH(32, 32), &paint);
4577 canvas->translate(48, 0);
4578 }
Cary Clark8032b982017-07-28 11:04:54 -04004579}
4580##
4581
Cary Clark2ade9972017-11-02 17:49:34 -04004582#SeeAlso drawImageRect drawBitmap drawBitmapLattice drawBitmapNine
Cary Clark8032b982017-07-28 11:04:54 -04004583
4584##
4585
4586# ------------------------------------------------------------------------------
4587
4588#Method void drawBitmapRect(const SkBitmap& bitmap, const SkIRect& isrc, const SkRect& dst,
4589 const SkPaint* paint, SrcRectConstraint constraint = kStrict_SrcRectConstraint)
Cary Clarkab2621d2018-01-30 10:08:57 -05004590#In Draw_Image
Cary Clark78de7512018-02-07 07:27:09 -05004591#In Draw
Cary Clark8032b982017-07-28 11:04:54 -04004592Draw IRect isrc of Bitmap bitmap, scaled and translated to fill Rect dst.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004593isrc is on integer pixel boundaries; dst may include fractional boundaries.
Cary Clark8032b982017-07-28 11:04:54 -04004594Additionally transform draw using Clip, Matrix, and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004595
Cary Clarkbad5ad72017-08-03 17:14:08 -04004596If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4597Blend_Mode, and Draw_Looper. If bitmap is kAlpha_8_SkColorType, apply Shader.
4598If paint contains Mask_Filter, generate mask from bitmap bounds.
4599
4600If generated mask extends beyond bitmap bounds, replicate bitmap edge colors,
4601just as Shader made from SkShader::MakeBitmapShader with
Cary Clarkbc5697d2017-10-04 14:31:33 -04004602SkShader::kClamp_TileMode set replicates the bitmap edge color when it samples
Cary Clarkbad5ad72017-08-03 17:14:08 -04004603outside of its bounds.
4604
4605constraint set to kStrict_SrcRectConstraint limits Paint Filter_Quality to
Cary Clarkce101242017-09-01 15:51:02 -04004606sample within isrc; set to kFast_SrcRectConstraint allows sampling outside to
Cary Clarkbad5ad72017-08-03 17:14:08 -04004607improve performance.
4608
4609#Param bitmap Bitmap containing pixels, dimensions, and format ##
4610#Param isrc source IRect of image to draw from ##
4611#Param dst destination Rect of image to draw to ##
4612#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4613 and so on; or nullptr
4614##
Cary Clarkce101242017-09-01 15:51:02 -04004615#Param constraint sample strictly within isrc, or draw faster ##
Cary Clark8032b982017-07-28 11:04:54 -04004616
4617#Example
4618#Height 64
Cary Clarkbad5ad72017-08-03 17:14:08 -04004619void draw(SkCanvas* canvas) {
4620 uint8_t pixels[][8] = { { 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00},
4621 { 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00},
4622 { 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0xFF},
4623 { 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0xFF},
4624 { 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF},
4625 { 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF},
4626 { 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00},
4627 { 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00} };
4628 SkBitmap bitmap;
Herb Derbyefe39bc2018-05-01 17:06:20 -04004629 bitmap.installPixels(SkImageInfo::MakeA8(8, 8),
Cary Clarkbad5ad72017-08-03 17:14:08 -04004630 (void*) pixels, sizeof(pixels[0]));
4631 SkPaint paint;
4632 paint.setFilterQuality(kHigh_SkFilterQuality);
4633 for (auto color : { SK_ColorRED, SK_ColorBLUE, 0xFF007F00, 0xFF7f007f} ) {
4634 paint.setColor(color);
4635 canvas->drawBitmapRect(bitmap, SkIRect::MakeWH(8, 8), SkRect::MakeWH(32, 32), &paint);
4636 canvas->translate(48.25f, 0);
4637 }
Cary Clark8032b982017-07-28 11:04:54 -04004638}
4639##
4640
Cary Clark2ade9972017-11-02 17:49:34 -04004641#SeeAlso drawImageRect drawBitmap drawBitmapLattice drawBitmapNine
Cary Clark8032b982017-07-28 11:04:54 -04004642
4643##
4644
4645# ------------------------------------------------------------------------------
4646
4647#Method void drawBitmapRect(const SkBitmap& bitmap, const SkRect& dst, const SkPaint* paint,
4648 SrcRectConstraint constraint = kStrict_SrcRectConstraint)
Cary Clarkab2621d2018-01-30 10:08:57 -05004649#In Draw_Image
Cary Clark78de7512018-02-07 07:27:09 -05004650#In Draw
Cary Clark8032b982017-07-28 11:04:54 -04004651Draw Bitmap bitmap, scaled and translated to fill Rect dst.
Cary Clarkce101242017-09-01 15:51:02 -04004652bitmap bounds is on integer pixel boundaries; dst may include fractional boundaries.
Cary Clark8032b982017-07-28 11:04:54 -04004653Additionally transform draw using Clip, Matrix, and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004654
Cary Clarkbad5ad72017-08-03 17:14:08 -04004655If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4656Blend_Mode, and Draw_Looper. If bitmap is kAlpha_8_SkColorType, apply Shader.
4657If paint contains Mask_Filter, generate mask from bitmap bounds.
4658
4659If generated mask extends beyond bitmap bounds, replicate bitmap edge colors,
4660just as Shader made from SkShader::MakeBitmapShader with
Cary Clarkbc5697d2017-10-04 14:31:33 -04004661SkShader::kClamp_TileMode set replicates the bitmap edge color when it samples
Cary Clarkbad5ad72017-08-03 17:14:08 -04004662outside of its bounds.
4663
4664constraint set to kStrict_SrcRectConstraint limits Paint Filter_Quality to
Cary Clarkce101242017-09-01 15:51:02 -04004665sample within bitmap; set to kFast_SrcRectConstraint allows sampling outside to
Cary Clarkbad5ad72017-08-03 17:14:08 -04004666improve performance.
4667
4668#Param bitmap Bitmap containing pixels, dimensions, and format ##
4669#Param dst destination Rect of image to draw to ##
4670#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4671 and so on; or nullptr
4672##
Cary Clarkce101242017-09-01 15:51:02 -04004673#Param constraint filter strictly within bitmap or draw faster ##
Cary Clark8032b982017-07-28 11:04:54 -04004674
4675#Example
4676#Height 64
Cary Clarkbad5ad72017-08-03 17:14:08 -04004677void draw(SkCanvas* canvas) {
4678 uint32_t pixels[][2] = { { 0x00000000, 0x55550000},
4679 { 0xAAAA0000, 0xFFFF0000} };
4680 SkBitmap bitmap;
Herb Derbyefe39bc2018-05-01 17:06:20 -04004681 bitmap.installPixels(SkImageInfo::MakeN32Premul(2, 2),
Cary Clarkbad5ad72017-08-03 17:14:08 -04004682 (void*) pixels, sizeof(pixels[0]));
4683 SkPaint paint;
4684 canvas->scale(4, 4);
4685 for (auto color : { SK_ColorRED, SK_ColorBLUE, SK_ColorGREEN } ) {
4686 paint.setColorFilter(SkColorFilter::MakeModeFilter(color, SkBlendMode::kPlus));
4687 canvas->drawBitmapRect(bitmap, SkRect::MakeWH(8, 8), &paint);
4688 canvas->translate(8, 0);
4689 }
Cary Clark8032b982017-07-28 11:04:54 -04004690}
4691##
4692
Cary Clark2ade9972017-11-02 17:49:34 -04004693#SeeAlso drawImageRect drawBitmap drawBitmapLattice drawBitmapNine
Cary Clark8032b982017-07-28 11:04:54 -04004694
4695##
4696
4697# ------------------------------------------------------------------------------
4698
Cary Clark682c58d2018-05-16 07:07:07 -04004699#PhraseDef paint_as_used_by_draw_lattice_or_draw_nine(bitmap_or_image)
4700If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4701Blend_Mode, and Draw_Looper. If #bitmap_or_image# is kAlpha_8_SkColorType, apply Shader.
4702If paint contains Mask_Filter, generate mask from #bitmap_or_image# bounds. If paint
4703Filter_Quality set to kNone_SkFilterQuality, disable pixel filtering. For all
4704other values of paint Filter_Quality, use kLow_SkFilterQuality to filter pixels.
Cary Clark137b8742018-05-30 09:21:49 -04004705Any SkMaskFilter on paint is ignored as is paint Anti_Aliasing state.
Cary Clark682c58d2018-05-16 07:07:07 -04004706##
4707
Cary Clark8032b982017-07-28 11:04:54 -04004708#Method void drawBitmapNine(const SkBitmap& bitmap, const SkIRect& center, const SkRect& dst,
Cary Clark73fa9722017-08-29 17:36:51 -04004709 const SkPaint* paint = nullptr)
Cary Clarkab2621d2018-01-30 10:08:57 -05004710#In Draw_Image
Cary Clark78de7512018-02-07 07:27:09 -05004711#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05004712#Line # draws Nine_Patch Bitmap ##
Cary Clark8032b982017-07-28 11:04:54 -04004713
Cary Clarkd0530ba2017-09-14 11:25:39 -04004714Draw Bitmap bitmap stretched proportionally to fit into Rect dst.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004715IRect center divides the bitmap into nine sections: four sides, four corners,
Cary Clarkce101242017-09-01 15:51:02 -04004716and the center. Corners are not scaled, or scaled down proportionately if their
Cary Clarkbad5ad72017-08-03 17:14:08 -04004717sides are larger than dst; center and four sides are scaled to fit remaining
4718space, if any.
Cary Clark8032b982017-07-28 11:04:54 -04004719
Cary Clarkbad5ad72017-08-03 17:14:08 -04004720Additionally transform draw using Clip, Matrix, and optional Paint paint.
4721
Cary Clark682c58d2018-05-16 07:07:07 -04004722#paint_as_used_by_draw_lattice_or_draw_nine(bitmap)#
Cary Clarkbad5ad72017-08-03 17:14:08 -04004723
4724If generated mask extends beyond bitmap bounds, replicate bitmap edge colors,
4725just as Shader made from SkShader::MakeBitmapShader with
Cary Clarkbc5697d2017-10-04 14:31:33 -04004726SkShader::kClamp_TileMode set replicates the bitmap edge color when it samples
Cary Clarkbad5ad72017-08-03 17:14:08 -04004727outside of its bounds.
4728
4729#Param bitmap Bitmap containing pixels, dimensions, and format ##
4730#Param center IRect edge of image corners and sides ##
4731#Param dst destination Rect of image to draw to ##
4732#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4733 and so on; or nullptr
4734##
Cary Clark8032b982017-07-28 11:04:54 -04004735
4736#Example
4737#Height 128
4738#Description
4739 The two leftmost bitmap draws has four corners and sides to the left and right of center.
4740 The leftmost bitmap draw scales the width of corners proportionately to fit.
Herb Derbyefe39bc2018-05-01 17:06:20 -04004741 The third and fourth draw corners are not scaled; the sides and center are scaled to
Cary Clark8032b982017-07-28 11:04:54 -04004742 fill the remaining space.
4743 The rightmost bitmap draw has four corners scaled vertically to fit, and uses sides above
4744 and below center to fill the remaining space.
4745##
Cary Clarkbad5ad72017-08-03 17:14:08 -04004746void draw(SkCanvas* canvas) {
4747 SkIRect center = { 20, 10, 50, 40 };
4748 SkBitmap bitmap;
4749 bitmap.allocPixels(SkImageInfo::MakeN32Premul(60, 60));
4750 SkCanvas bitCanvas(bitmap);
4751 SkPaint paint;
4752 SkColor gray = 0xFF000000;
4753 int left = 0;
4754 for (auto right: { center.fLeft, center.fRight, bitmap.width() } ) {
4755 int top = 0;
4756 for (auto bottom: { center.fTop, center.fBottom, bitmap.height() } ) {
4757 paint.setColor(gray);
4758 bitCanvas.drawIRect(SkIRect::MakeLTRB(left, top, right, bottom), paint);
4759 gray += 0x001f1f1f;
4760 top = bottom;
4761 }
Herb Derbyefe39bc2018-05-01 17:06:20 -04004762 left = right;
Cary Clarkbad5ad72017-08-03 17:14:08 -04004763 }
4764 for (auto dest: { 20, 30, 40, 60, 90 } ) {
4765 canvas->drawBitmapNine(bitmap, center, SkRect::MakeWH(dest, 110 - dest), nullptr);
4766 canvas->translate(dest + 4, 0);
4767 }
Cary Clark8032b982017-07-28 11:04:54 -04004768}
4769##
4770
Cary Clark2ade9972017-11-02 17:49:34 -04004771#SeeAlso drawImageNine drawBitmap drawBitmapLattice drawBitmapRect
Cary Clark8032b982017-07-28 11:04:54 -04004772
4773##
4774
4775# ------------------------------------------------------------------------------
Cary Clark682c58d2018-05-16 07:07:07 -04004776#Subtopic Lattice
4777#Line # divides Bitmap or Image into a rectangular grid ##
4778
Cary Clark8032b982017-07-28 11:04:54 -04004779#Struct Lattice
Cary Clark08895c42018-02-01 09:37:32 -05004780#Line # divides Bitmap or Image into a rectangular grid ##
Cary Clark682c58d2018-05-16 07:07:07 -04004781
Cary Clark8032b982017-07-28 11:04:54 -04004782#Code
4783 struct Lattice {
Cary Clark2f466242017-12-11 16:03:17 -05004784 enum RectType ...
Cary Clark8032b982017-07-28 11:04:54 -04004785
Cary Clark2f466242017-12-11 16:03:17 -05004786 const int* fXDivs;
4787 const int* fYDivs;
4788 const RectType* fRectTypes;
4789 int fXCount;
4790 int fYCount;
4791 const SkIRect* fBounds;
4792 const SkColor* fColors;
Cary Clark8032b982017-07-28 11:04:54 -04004793 };
4794##
4795
Cary Clark137b8742018-05-30 09:21:49 -04004796Lattice divides Bitmap or Image into a rectangular grid.
4797Grid entries on even columns and even rows are fixed; these entries are
4798always drawn at their original size if the destination is large enough.
4799If the destination side is too small to hold the fixed entries, all fixed
4800entries are proportionately scaled down to fit.
4801The grid entries not on even columns and rows are scaled to fit the
4802remaining space, if any.
4803
Cary Clark682c58d2018-05-16 07:07:07 -04004804#Subtopic Overview
4805#Populate
4806##
4807
4808#Subtopic Constant
4809#Populate
4810##
Cary Clark154beea2017-10-26 07:58:48 -04004811
Cary Clark2f466242017-12-11 16:03:17 -05004812 #Enum RectType
Cary Clark682c58d2018-05-16 07:07:07 -04004813 #Line # optional setting per rectangular grid entry ##
Cary Clark8032b982017-07-28 11:04:54 -04004814 #Code
Cary Clark2f466242017-12-11 16:03:17 -05004815 enum RectType : uint8_t {
4816 kDefault = 0,
4817 kTransparent,
4818 kFixedColor,
Cary Clark8032b982017-07-28 11:04:54 -04004819 };
4820 ##
4821
Cary Clark2f466242017-12-11 16:03:17 -05004822 Optional setting per rectangular grid entry to make it transparent,
4823 or to fill the grid entry with a color.
Cary Clark8032b982017-07-28 11:04:54 -04004824
Cary Clark2f466242017-12-11 16:03:17 -05004825 #Const kDefault 0
Cary Clark682c58d2018-05-16 07:07:07 -04004826 #Line # draws Bitmap into lattice rectangle ##
Cary Clark2f466242017-12-11 16:03:17 -05004827 ##
4828
4829 #Const kTransparent 1
Cary Clark682c58d2018-05-16 07:07:07 -04004830 #Line # skips lattice rectangle by making it transparent ##
Cary Clark2f466242017-12-11 16:03:17 -05004831 ##
4832
4833 #Const kFixedColor 2
Cary Clark682c58d2018-05-16 07:07:07 -04004834 #Line # draws one of fColors into lattice rectangle ##
Cary Clark8032b982017-07-28 11:04:54 -04004835 ##
4836 ##
4837
Cary Clark682c58d2018-05-16 07:07:07 -04004838#Subtopic Member
4839#Populate
4840##
4841
Cary Clark8032b982017-07-28 11:04:54 -04004842 #Member const int* fXDivs
Cary Clark5538c132018-06-14 12:28:14 -04004843 #Line # x-axis values dividing bitmap ##
4844 Array of x-axis values that divide the bitmap vertically.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004845 Array entries must be unique, increasing, greater than or equal to
4846 fBounds left edge, and less than fBounds right edge.
4847 Set the first element to fBounds left to collapse the left column of
4848 fixed grid entries.
Cary Clark8032b982017-07-28 11:04:54 -04004849 ##
4850
4851 #Member const int* fYDivs
Cary Clark5538c132018-06-14 12:28:14 -04004852 #Line # y-axis values dividing bitmap ##
4853 Array of y-axis values that divide the bitmap horizontally.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004854 Array entries must be unique, increasing, greater than or equal to
4855 fBounds top edge, and less than fBounds bottom edge.
4856 Set the first element to fBounds top to collapse the top row of fixed
4857 grid entries.
Cary Clark8032b982017-07-28 11:04:54 -04004858 ##
4859
Cary Clark2f466242017-12-11 16:03:17 -05004860 #Member const RectType* fRectTypes
Cary Clark682c58d2018-05-16 07:07:07 -04004861 #Line # array of fill types ##
Cary Clark2f466242017-12-11 16:03:17 -05004862 Optional array of fill types, one per rectangular grid entry:
Cary Clarkbad5ad72017-08-03 17:14:08 -04004863 array length must be
4864 #Formula
4865 (fXCount + 1) * (fYCount + 1)
4866 ##
4867 .
Cary Clark6fc50412017-09-21 12:31:06 -04004868
Cary Clark2f466242017-12-11 16:03:17 -05004869 Each RectType is one of: kDefault, kTransparent, kFixedColor.
4870
Cary Clark8032b982017-07-28 11:04:54 -04004871 Array entries correspond to the rectangular grid entries, ascending
4872 left to right and then top to bottom.
4873 ##
4874
4875 #Member int fXCount
Cary Clark682c58d2018-05-16 07:07:07 -04004876 #Line # number of x-coordinates ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04004877 Number of entries in fXDivs array; one less than the number of
4878 horizontal divisions.
Cary Clark8032b982017-07-28 11:04:54 -04004879 ##
4880
4881 #Member int fYCount
Cary Clark682c58d2018-05-16 07:07:07 -04004882 #Line # number of y-coordinates ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04004883 Number of entries in fYDivs array; one less than the number of vertical
4884 divisions.
Cary Clark8032b982017-07-28 11:04:54 -04004885 ##
4886
4887 #Member const SkIRect* fBounds
Cary Clark682c58d2018-05-16 07:07:07 -04004888 #Line # source bounds to draw from ##
Cary Clark8032b982017-07-28 11:04:54 -04004889 Optional subset IRect source to draw from.
4890 If nullptr, source bounds is dimensions of Bitmap or Image.
4891 ##
4892
Cary Clark2f466242017-12-11 16:03:17 -05004893 #Member const SkColor* fColors
Cary Clark682c58d2018-05-16 07:07:07 -04004894 #Line # array of colors ##
Cary Clark2f466242017-12-11 16:03:17 -05004895 Optional array of colors, one per rectangular grid entry.
4896 Array length must be
4897 #Formula
4898 (fXCount + 1) * (fYCount + 1)
4899 ##
4900 .
4901
4902 Array entries correspond to the rectangular grid entries, ascending
4903 left to right, then top to bottom.
4904 ##
4905
Cary Clark8032b982017-07-28 11:04:54 -04004906#Struct Lattice ##
4907
4908#Method void drawBitmapLattice(const SkBitmap& bitmap, const Lattice& lattice, const SkRect& dst,
4909 const SkPaint* paint = nullptr)
Cary Clarkab2621d2018-01-30 10:08:57 -05004910#In Draw_Image
Cary Clark78de7512018-02-07 07:27:09 -05004911#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05004912#Line # draws proportionally stretched Bitmap ##
Cary Clark8032b982017-07-28 11:04:54 -04004913
Cary Clarkd0530ba2017-09-14 11:25:39 -04004914Draw Bitmap bitmap stretched proportionally to fit into Rect dst.
Cary Clark8032b982017-07-28 11:04:54 -04004915
4916Lattice lattice divides bitmap into a rectangular grid.
4917Each intersection of an even-numbered row and column is fixed; like the corners
Cary Clarkbad5ad72017-08-03 17:14:08 -04004918of drawBitmapNine, fixed lattice elements never scale larger than their initial
Cary Clarkbc5697d2017-10-04 14:31:33 -04004919size and shrink proportionately when all fixed elements exceed the bitmap
Cary Clarkbad5ad72017-08-03 17:14:08 -04004920dimension. All other grid elements scale to fill the available space, if any.
Cary Clark8032b982017-07-28 11:04:54 -04004921
4922Additionally transform draw using Clip, Matrix, and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004923
Cary Clark682c58d2018-05-16 07:07:07 -04004924#paint_as_used_by_draw_lattice_or_draw_nine(bitmap)#
Cary Clarkbad5ad72017-08-03 17:14:08 -04004925
4926If generated mask extends beyond bitmap bounds, replicate bitmap edge colors,
4927just as Shader made from SkShader::MakeBitmapShader with
Cary Clarkbc5697d2017-10-04 14:31:33 -04004928SkShader::kClamp_TileMode set replicates the bitmap edge color when it samples
Cary Clarkbad5ad72017-08-03 17:14:08 -04004929outside of its bounds.
4930
4931#Param bitmap Bitmap containing pixels, dimensions, and format ##
4932#Param lattice division of bitmap into fixed and variable rectangles ##
4933#Param dst destination Rect of image to draw to ##
4934#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4935 and so on; or nullptr
4936##
Cary Clark8032b982017-07-28 11:04:54 -04004937
4938#Example
4939#Height 128
4940#Description
4941 The two leftmost bitmap draws has four corners and sides to the left and right of center.
4942 The leftmost bitmap draw scales the width of corners proportionately to fit.
Herb Derbyefe39bc2018-05-01 17:06:20 -04004943 The third and fourth draw corners are not scaled; the sides are scaled to
Cary Clark8032b982017-07-28 11:04:54 -04004944 fill the remaining space; the center is transparent.
4945 The rightmost bitmap draw has four corners scaled vertically to fit, and uses sides above
4946 and below center to fill the remaining space.
4947##
Cary Clarkbad5ad72017-08-03 17:14:08 -04004948void draw(SkCanvas* canvas) {
4949 SkIRect center = { 20, 10, 50, 40 };
4950 SkBitmap bitmap;
4951 bitmap.allocPixels(SkImageInfo::MakeN32Premul(60, 60));
4952 SkCanvas bitCanvas(bitmap);
4953 SkPaint paint;
4954 SkColor gray = 0xFF000000;
4955 int left = 0;
4956 for (auto right: { center.fLeft, center.fRight, bitmap.width() } ) {
4957 int top = 0;
4958 for (auto bottom: { center.fTop, center.fBottom, bitmap.height() } ) {
4959 paint.setColor(gray);
4960 bitCanvas.drawIRect(SkIRect::MakeLTRB(left, top, right, bottom), paint);
4961 gray += 0x001f1f1f;
4962 top = bottom;
4963 }
Herb Derbyefe39bc2018-05-01 17:06:20 -04004964 left = right;
Cary Clarkbad5ad72017-08-03 17:14:08 -04004965 }
4966 const int xDivs[] = { center.fLeft, center.fRight };
4967 const int yDivs[] = { center.fTop, center.fBottom };
Cary Clarkca3ebcd2017-12-12 11:22:38 -05004968 SkCanvas::Lattice::RectType fillTypes[3][3];
4969 memset(fillTypes, 0, sizeof(fillTypes));
4970 fillTypes[1][1] = SkCanvas::Lattice::kTransparent;
4971 SkColor dummy[9]; // temporary pending bug fix
4972 SkCanvas::Lattice lattice = { xDivs, yDivs, fillTypes[0], SK_ARRAY_COUNT(xDivs),
4973 SK_ARRAY_COUNT(yDivs), nullptr, dummy };
Cary Clarkbad5ad72017-08-03 17:14:08 -04004974 for (auto dest: { 20, 30, 40, 60, 90 } ) {
Cary Clarkca3ebcd2017-12-12 11:22:38 -05004975 canvas->drawBitmapLattice(bitmap, lattice, SkRect::MakeWH(dest, 110 - dest), nullptr);
Cary Clarkbad5ad72017-08-03 17:14:08 -04004976 canvas->translate(dest + 4, 0);
4977 }
Cary Clark8032b982017-07-28 11:04:54 -04004978}
4979##
4980
Cary Clark2ade9972017-11-02 17:49:34 -04004981#SeeAlso drawImageLattice drawBitmap drawBitmapNine Lattice
Cary Clark8032b982017-07-28 11:04:54 -04004982
4983##
4984
4985# ------------------------------------------------------------------------------
4986
4987#Method void drawImageLattice(const SkImage* image, const Lattice& lattice, const SkRect& dst,
4988 const SkPaint* paint = nullptr)
Cary Clarkab2621d2018-01-30 10:08:57 -05004989#In Draw_Image
Cary Clark78de7512018-02-07 07:27:09 -05004990#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05004991#Line # draws proportionally stretched Image ##
Cary Clark8032b982017-07-28 11:04:54 -04004992
Cary Clarkd0530ba2017-09-14 11:25:39 -04004993Draw Image image stretched proportionally to fit into Rect dst.
Cary Clark8032b982017-07-28 11:04:54 -04004994
4995Lattice lattice divides image into a rectangular grid.
4996Each intersection of an even-numbered row and column is fixed; like the corners
Cary Clarkbad5ad72017-08-03 17:14:08 -04004997of drawBitmapNine, fixed lattice elements never scale larger than their initial
Cary Clarkbc5697d2017-10-04 14:31:33 -04004998size and shrink proportionately when all fixed elements exceed the bitmap
Cary Clarkbad5ad72017-08-03 17:14:08 -04004999dimension. All other grid elements scale to fill the available space, if any.
Cary Clark8032b982017-07-28 11:04:54 -04005000
5001Additionally transform draw using Clip, Matrix, and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04005002
Cary Clark682c58d2018-05-16 07:07:07 -04005003#paint_as_used_by_draw_lattice_or_draw_nine(image)#
Cary Clarkbad5ad72017-08-03 17:14:08 -04005004
5005If generated mask extends beyond bitmap bounds, replicate bitmap edge colors,
5006just as Shader made from SkShader::MakeBitmapShader with
Cary Clarkbc5697d2017-10-04 14:31:33 -04005007SkShader::kClamp_TileMode set replicates the bitmap edge color when it samples
Cary Clarkbad5ad72017-08-03 17:14:08 -04005008outside of its bounds.
5009
5010#Param image Image containing pixels, dimensions, and format ##
5011#Param lattice division of bitmap into fixed and variable rectangles ##
5012#Param dst destination Rect of image to draw to ##
5013#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
5014 and so on; or nullptr
5015##
Cary Clark8032b982017-07-28 11:04:54 -04005016
5017#Example
5018#Height 128
5019#Description
5020 The leftmost image is smaller than center; only corners are drawn, all scaled to fit.
Cary Clarkce101242017-09-01 15:51:02 -04005021 The second image equals the size of center; only corners are drawn without scaling.
5022 The remaining images are larger than center. All corners draw without scaling. The sides
Cary Clark8032b982017-07-28 11:04:54 -04005023 are scaled if needed to take up the remaining space; the center is transparent.
5024##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005025void draw(SkCanvas* canvas) {
5026 SkIRect center = { 20, 10, 50, 40 };
5027 SkBitmap bitmap;
5028 bitmap.allocPixels(SkImageInfo::MakeN32Premul(60, 60));
5029 SkCanvas bitCanvas(bitmap);
5030 SkPaint paint;
5031 SkColor gray = 0xFF000000;
5032 int left = 0;
5033 for (auto right: { center.fLeft, center.fRight, bitmap.width() } ) {
5034 int top = 0;
5035 for (auto bottom: { center.fTop, center.fBottom, bitmap.height() } ) {
5036 paint.setColor(gray);
5037 bitCanvas.drawIRect(SkIRect::MakeLTRB(left, top, right, bottom), paint);
5038 gray += 0x001f1f1f;
5039 top = bottom;
5040 }
Herb Derbyefe39bc2018-05-01 17:06:20 -04005041 left = right;
Cary Clarkbad5ad72017-08-03 17:14:08 -04005042 }
Cary Clarkbad5ad72017-08-03 17:14:08 -04005043 sk_sp<SkImage> image = SkImage::MakeFromBitmap(bitmap);
5044 SkImage* imagePtr = image.get();
5045 for (auto dest: { 20, 30, 40, 60, 90 } ) {
5046 canvas->drawImageNine(imagePtr, center, SkRect::MakeWH(dest, dest), nullptr);
5047 canvas->translate(dest + 4, 0);
5048 }
Cary Clark8032b982017-07-28 11:04:54 -04005049}
5050##
5051
Cary Clark2ade9972017-11-02 17:49:34 -04005052#SeeAlso drawBitmapLattice drawImage drawImageNine Lattice
Cary Clark8032b982017-07-28 11:04:54 -04005053
5054##
5055
Cary Clark682c58d2018-05-16 07:07:07 -04005056#Subtopic Lattice ##
5057
Cary Clark08895c42018-02-01 09:37:32 -05005058#Subtopic Draw_Image ##
Cary Clark8032b982017-07-28 11:04:54 -04005059
5060# ------------------------------------------------------------------------------
Cary Clark78de7512018-02-07 07:27:09 -05005061#Subtopic Draw_Text
5062#Populate
5063#Line # draws text into Canvas ##
5064##
Cary Clark8032b982017-07-28 11:04:54 -04005065
5066#Method void drawText(const void* text, size_t byteLength, SkScalar x, SkScalar y,
5067 const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05005068#In Draw_Text
5069#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05005070#Line # draws text at (x, y), using font advance ##
Cary Clark8032b982017-07-28 11:04:54 -04005071
5072Draw text, with origin at (x, y), using Clip, Matrix, and Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04005073
Cary Clarkbc5697d2017-10-04 14:31:33 -04005074text meaning depends on Paint_Text_Encoding; by default, text is encoded as
Cary Clarkbad5ad72017-08-03 17:14:08 -04005075UTF-8.
Cary Clark8032b982017-07-28 11:04:54 -04005076
Cary Clarkbad5ad72017-08-03 17:14:08 -04005077x and y meaning depends on Paint_Text_Align and Paint_Vertical_Text; by default
Cary Clarkbc5697d2017-10-04 14:31:33 -04005078text draws left to right, positioning the first glyph left side bearing at x
Herb Derbyefe39bc2018-05-01 17:06:20 -04005079and its baseline at y. Text size is affected by Matrix and Paint_Text_Size.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005080
Mike Reed8ad91a92018-01-19 19:09:32 -05005081All elements of paint: Path_Effect, Mask_Filter, Shader,
Cary Clarkbad5ad72017-08-03 17:14:08 -04005082Color_Filter, Image_Filter, and Draw_Looper; apply to text. By default, draws
Cary Clarkce101242017-09-01 15:51:02 -04005083filled 12 point black Glyphs.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005084
Cary Clarkce101242017-09-01 15:51:02 -04005085#Param text character code points or Glyphs drawn ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005086#Param byteLength byte length of text array ##
5087#Param x start of text on x-axis ##
5088#Param y start of text on y-axis ##
5089#Param paint text size, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005090
5091#Example
5092#Height 200
5093#Description
5094 The same text is drawn varying Paint_Text_Size and varying
Herb Derbyefe39bc2018-05-01 17:06:20 -04005095 Matrix.
Cary Clark8032b982017-07-28 11:04:54 -04005096##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005097void draw(SkCanvas* canvas) {
5098 SkPaint paint;
5099 paint.setAntiAlias(true);
5100 float textSizes[] = { 12, 18, 24, 36 };
5101 for (auto size: textSizes ) {
5102 paint.setTextSize(size);
5103 canvas->drawText("Aa", 2, 10, 20, paint);
5104 canvas->translate(0, size * 2);
5105 }
5106 paint.reset();
5107 paint.setAntiAlias(true);
5108 float yPos = 20;
5109 for (auto size: textSizes ) {
5110 float scale = size / 12.f;
5111 canvas->resetMatrix();
5112 canvas->translate(100, 0);
5113 canvas->scale(scale, scale);
5114 canvas->drawText("Aa", 2, 10 / scale, yPos / scale, paint);
Herb Derbyefe39bc2018-05-01 17:06:20 -04005115 yPos += size * 2;
Cary Clarkbad5ad72017-08-03 17:14:08 -04005116 }
5117}
Cary Clark8032b982017-07-28 11:04:54 -04005118##
5119
Cary Clark2ade9972017-11-02 17:49:34 -04005120#SeeAlso drawString drawPosText drawPosTextH drawTextBlob drawTextOnPath drawTextRSXform
Cary Clark8032b982017-07-28 11:04:54 -04005121
5122##
5123
5124#Method void drawString(const char* string, SkScalar x, SkScalar y, const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05005125#In Draw_Text
5126#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05005127#Line # draws null terminated string at (x, y) using font advance ##
Cary Clark682c58d2018-05-16 07:07:07 -04005128Draws null terminated string, with origin at (x, y), using Clip, Matrix, and
5129Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04005130
Cary Clarkbc5697d2017-10-04 14:31:33 -04005131string meaning depends on Paint_Text_Encoding; by default, strings are encoded
5132as UTF-8. Other values of Paint_Text_Encoding are unlikely to produce the desired
Cary Clarkbad5ad72017-08-03 17:14:08 -04005133results, since zero bytes may be embedded in the string.
Cary Clark8032b982017-07-28 11:04:54 -04005134
Cary Clarkbad5ad72017-08-03 17:14:08 -04005135x and y meaning depends on Paint_Text_Align and Paint_Vertical_Text; by default
Cary Clarkbc5697d2017-10-04 14:31:33 -04005136string draws left to right, positioning the first glyph left side bearing at x
Herb Derbyefe39bc2018-05-01 17:06:20 -04005137and its baseline at y. Text size is affected by Matrix and Paint_Text_Size.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005138
Mike Reed8ad91a92018-01-19 19:09:32 -05005139All elements of paint: Path_Effect, Mask_Filter, Shader,
Cary Clarkbad5ad72017-08-03 17:14:08 -04005140Color_Filter, Image_Filter, and Draw_Looper; apply to text. By default, draws
Cary Clarkce101242017-09-01 15:51:02 -04005141filled 12 point black Glyphs.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005142
Cary Clarkce101242017-09-01 15:51:02 -04005143#Param string character code points or Glyphs drawn,
Cary Clarkbad5ad72017-08-03 17:14:08 -04005144 ending with a char value of zero
5145##
5146#Param x start of string on x-axis ##
5147#Param y start of string on y-axis ##
5148#Param paint text size, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005149
5150#Example
Cary Clarkffb3d682018-05-17 12:17:28 -04005151#Height 48
Cary Clark8032b982017-07-28 11:04:54 -04005152 SkPaint paint;
5153 canvas->drawString("a small hello", 20, 20, paint);
5154##
5155
Cary Clark2ade9972017-11-02 17:49:34 -04005156#SeeAlso drawText drawPosText drawPosTextH drawTextBlob drawTextOnPath drawTextRSXform
Cary Clark8032b982017-07-28 11:04:54 -04005157
5158##
5159
5160#Method void drawString(const SkString& string, SkScalar x, SkScalar y, const SkPaint& paint)
5161
Cary Clarkbad5ad72017-08-03 17:14:08 -04005162Draw null terminated string, with origin at (x, y), using Clip, Matrix, and
5163Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04005164
Cary Clarkbc5697d2017-10-04 14:31:33 -04005165string meaning depends on Paint_Text_Encoding; by default, strings are encoded
5166as UTF-8. Other values of Paint_Text_Encoding are unlikely to produce the desired
Cary Clarkbad5ad72017-08-03 17:14:08 -04005167results, since zero bytes may be embedded in the string.
Cary Clark8032b982017-07-28 11:04:54 -04005168
Cary Clarkbad5ad72017-08-03 17:14:08 -04005169x and y meaning depends on Paint_Text_Align and Paint_Vertical_Text; by default
Cary Clarkbc5697d2017-10-04 14:31:33 -04005170string draws left to right, positioning the first glyph left side bearing at x
Herb Derbyefe39bc2018-05-01 17:06:20 -04005171and its baseline at y. Text size is affected by Matrix and Paint_Text_Size.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005172
Mike Reed8ad91a92018-01-19 19:09:32 -05005173All elements of paint: Path_Effect, Mask_Filter, Shader,
Cary Clarkbad5ad72017-08-03 17:14:08 -04005174Color_Filter, Image_Filter, and Draw_Looper; apply to text. By default, draws
Cary Clarkce101242017-09-01 15:51:02 -04005175filled 12 point black Glyphs.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005176
Cary Clarkce101242017-09-01 15:51:02 -04005177#Param string character code points or Glyphs drawn,
Cary Clarkbad5ad72017-08-03 17:14:08 -04005178 ending with a char value of zero
5179##
5180#Param x start of string on x-axis ##
5181#Param y start of string on y-axis ##
5182#Param paint text size, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005183
5184#Example
5185 SkPaint paint;
5186 SkString string("a small hello");
5187 canvas->drawString(string, 20, 20, paint);
5188##
5189
Cary Clark2ade9972017-11-02 17:49:34 -04005190#SeeAlso drawText drawPosText drawPosTextH drawTextBlob drawTextOnPath drawTextRSXform
Cary Clark8032b982017-07-28 11:04:54 -04005191
5192##
5193
5194# ------------------------------------------------------------------------------
5195
5196#Method void drawPosText(const void* text, size_t byteLength, const SkPoint pos[],
5197 const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05005198#In Draw_Text
5199#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05005200#Line # draws text at array of (x, y) positions ##
Cary Clark8032b982017-07-28 11:04:54 -04005201
Cary Clarkbad5ad72017-08-03 17:14:08 -04005202Draw each glyph in text with the origin in pos array, using Clip, Matrix, and
Cary Clarkce101242017-09-01 15:51:02 -04005203Paint paint. The number of entries in pos array must match the number of Glyphs
Cary Clarkbad5ad72017-08-03 17:14:08 -04005204described by byteLength of text.
Cary Clark8032b982017-07-28 11:04:54 -04005205
Cary Clarkbc5697d2017-10-04 14:31:33 -04005206text meaning depends on Paint_Text_Encoding; by default, text is encoded as
Cary Clark5538c132018-06-14 12:28:14 -04005207UTF-8. pos elements meaning depends on Paint_Vertical_Text; by default
5208glyph left side bearing and baseline are relative to Point in pos array.
5209Text size is affected by Matrix and Paint_Text_Size.
Cary Clark8032b982017-07-28 11:04:54 -04005210
Mike Reed8ad91a92018-01-19 19:09:32 -05005211All elements of paint: Path_Effect, Mask_Filter, Shader,
Cary Clarkbad5ad72017-08-03 17:14:08 -04005212Color_Filter, Image_Filter, and Draw_Looper; apply to text. By default, draws
Cary Clarkce101242017-09-01 15:51:02 -04005213filled 12 point black Glyphs.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005214
5215Layout engines such as Harfbuzz typically position each glyph
Cary Clarkbc5697d2017-10-04 14:31:33 -04005216rather than using the font advance widths.
Cary Clark8032b982017-07-28 11:04:54 -04005217
Cary Clarkce101242017-09-01 15:51:02 -04005218#Param text character code points or Glyphs drawn ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005219#Param byteLength byte length of text array ##
5220#Param pos array of glyph origins ##
5221#Param paint text size, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005222
5223#Example
5224#Height 120
Cary Clarkbad5ad72017-08-03 17:14:08 -04005225void draw(SkCanvas* canvas) {
5226 const char hello[] = "HeLLo!";
5227 const SkPoint pos[] = { {40, 100}, {82, 95}, {115, 110}, {130, 95}, {145, 85},
5228 {172, 100} };
5229 SkPaint paint;
5230 paint.setTextSize(60);
5231 canvas->drawPosText(hello, strlen(hello), pos, paint);
Cary Clark8032b982017-07-28 11:04:54 -04005232}
5233##
5234
Cary Clark2ade9972017-11-02 17:49:34 -04005235#SeeAlso drawText drawPosTextH drawTextBlob drawTextOnPath drawTextRSXform
Cary Clark8032b982017-07-28 11:04:54 -04005236
5237##
5238
5239# ------------------------------------------------------------------------------
5240
5241#Method void drawPosTextH(const void* text, size_t byteLength, const SkScalar xpos[], SkScalar constY,
5242 const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05005243#In Draw_Text
5244#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05005245#Line # draws text at x positions with common baseline ##
Cary Clark8032b982017-07-28 11:04:54 -04005246
Cary Clarkbad5ad72017-08-03 17:14:08 -04005247Draw each glyph in text with its (x, y) origin composed from xpos array and
5248constY, using Clip, Matrix, and Paint paint. The number of entries in xpos array
Cary Clarkce101242017-09-01 15:51:02 -04005249must match the number of Glyphs described by byteLength of text.
Cary Clark8032b982017-07-28 11:04:54 -04005250
Cary Clarkbc5697d2017-10-04 14:31:33 -04005251text meaning depends on Paint_Text_Encoding; by default, text is encoded as
Cary Clark137b8742018-05-30 09:21:49 -04005252UTF-8. xpos elements meaning depends on Paint_Vertical_Text;
Cary Clarkbc5697d2017-10-04 14:31:33 -04005253by default each glyph left side bearing is positioned at an xpos element and
Cary Clarkbad5ad72017-08-03 17:14:08 -04005254its baseline is positioned at constY. Text size is affected by Matrix and
Herb Derbyefe39bc2018-05-01 17:06:20 -04005255Paint_Text_Size.
Cary Clark8032b982017-07-28 11:04:54 -04005256
Mike Reed8ad91a92018-01-19 19:09:32 -05005257All elements of paint: Path_Effect, Mask_Filter, Shader,
Cary Clarkbad5ad72017-08-03 17:14:08 -04005258Color_Filter, Image_Filter, and Draw_Looper; apply to text. By default, draws
Cary Clarkce101242017-09-01 15:51:02 -04005259filled 12 point black Glyphs.
Cary Clark8032b982017-07-28 11:04:54 -04005260
Cary Clarkbad5ad72017-08-03 17:14:08 -04005261Layout engines such as Harfbuzz typically position each glyph
Cary Clarkbc5697d2017-10-04 14:31:33 -04005262rather than using the font advance widths if all Glyphs share the same
Cary Clarkbad5ad72017-08-03 17:14:08 -04005263baseline.
5264
Cary Clarkce101242017-09-01 15:51:02 -04005265#Param text character code points or Glyphs drawn ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005266#Param byteLength byte length of text array ##
Cary Clark5538c132018-06-14 12:28:14 -04005267#Param xpos array of x-axis positions, used to position each glyph ##
5268#Param constY shared y-axis value for all of x-axis positions ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005269#Param paint text size, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005270
5271#Example
5272#Height 40
Cary Clarkbad5ad72017-08-03 17:14:08 -04005273 void draw(SkCanvas* canvas) {
5274 SkScalar xpos[] = { 20, 40, 80, 160 };
5275 SkPaint paint;
5276 canvas->drawPosTextH("XXXX", 4, xpos, 20, paint);
5277 }
Cary Clark8032b982017-07-28 11:04:54 -04005278##
5279
Cary Clark2ade9972017-11-02 17:49:34 -04005280#SeeAlso drawText drawPosText drawTextBlob drawTextOnPath drawTextRSXform
Cary Clark8032b982017-07-28 11:04:54 -04005281
5282##
5283
5284# ------------------------------------------------------------------------------
5285
5286#Method void drawTextOnPathHV(const void* text, size_t byteLength, const SkPath& path, SkScalar hOffset,
5287 SkScalar vOffset, const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05005288#In Draw_Text
5289#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05005290#Line # draws text following Path with offsets ##
Cary Clark8032b982017-07-28 11:04:54 -04005291
5292Draw text on Path path, using Clip, Matrix, and Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04005293
Cary Clarkbad5ad72017-08-03 17:14:08 -04005294Origin of text is at distance hOffset along the path, offset by a perpendicular
5295vector of length vOffset. If the path section corresponding the glyph advance is
5296curved, the glyph is drawn curved to match; control points in the glyph are
Cary Clarkbc5697d2017-10-04 14:31:33 -04005297mapped to projected points parallel to the path. If the text advance is larger
Cary Clarkbad5ad72017-08-03 17:14:08 -04005298than the path length, the excess text is clipped.
5299
Cary Clarkbc5697d2017-10-04 14:31:33 -04005300text meaning depends on Paint_Text_Encoding; by default, text is encoded as
Cary Clarkbad5ad72017-08-03 17:14:08 -04005301UTF-8. Origin meaning depends on Paint_Text_Align and Paint_Vertical_Text; by
Cary Clark5538c132018-06-14 12:28:14 -04005302default text positions the first glyph left side bearing and baseline relative
5303to origin. Text size is affected by Matrix and Paint_Text_Size.
Cary Clark8032b982017-07-28 11:04:54 -04005304
Mike Reed8ad91a92018-01-19 19:09:32 -05005305All elements of paint: Path_Effect, Mask_Filter, Shader,
Cary Clarkbad5ad72017-08-03 17:14:08 -04005306Color_Filter, Image_Filter, and Draw_Looper; apply to text. By default, draws
Cary Clarkce101242017-09-01 15:51:02 -04005307filled 12 point black Glyphs.
Cary Clark8032b982017-07-28 11:04:54 -04005308
Cary Clarkce101242017-09-01 15:51:02 -04005309#Param text character code points or Glyphs drawn ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005310#Param byteLength byte length of text array ##
5311#Param path Path providing text baseline ##
5312#Param hOffset distance along path to offset origin ##
5313#Param vOffset offset of text above (if negative) or below (if positive) the path ##
5314#Param paint text size, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005315
5316#Example
Herb Derbyefe39bc2018-05-01 17:06:20 -04005317 void draw(SkCanvas* canvas) {
Cary Clarkbad5ad72017-08-03 17:14:08 -04005318 const char aero[] = "correo a" "\xC3" "\xA9" "reo";
5319 const size_t len = sizeof(aero) - 1;
5320 SkPath path;
5321 path.addOval({43-26, 43-26, 43+26, 43+26}, SkPath::kCW_Direction, 3);
5322 SkPaint paint;
5323 paint.setTextSize(24);
5324 for (auto offset : { 0, 10, 20 } ) {
5325 canvas->drawTextOnPathHV(aero, len, path, 0, -offset, paint);
5326 canvas->translate(70 + offset, 70 + offset);
5327 }
5328 }
Cary Clark8032b982017-07-28 11:04:54 -04005329##
5330
Cary Clark2ade9972017-11-02 17:49:34 -04005331#SeeAlso drawTextOnPath drawText drawPosTextH drawTextBlob drawTextRSXform
Cary Clark8032b982017-07-28 11:04:54 -04005332
5333##
5334
5335# ------------------------------------------------------------------------------
5336
5337#Method void drawTextOnPath(const void* text, size_t byteLength, const SkPath& path,
5338 const SkMatrix* matrix, const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05005339#In Draw_Text
5340#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05005341#Line # draws text following Path contour ##
Cary Clark8032b982017-07-28 11:04:54 -04005342
5343Draw text on Path path, using Clip, Matrix, and Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04005344
Cary Clark682c58d2018-05-16 07:07:07 -04005345Origin of text is at beginning of path offset by matrix, if not nullptr.
Cary Clark137b8742018-05-30 09:21:49 -04005346matrix transforms text before text is mapped to path. If the path section
Cary Clark682c58d2018-05-16 07:07:07 -04005347corresponding the glyph advance is curved, the glyph is drawn curved to match;
5348control points in the glyph are mapped to projected points parallel to the path.
5349If the text advance is larger than the path length, the excess text is clipped.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005350
Cary Clark137b8742018-05-30 09:21:49 -04005351matrix does not effect paint Shader.
5352
Cary Clarkbc5697d2017-10-04 14:31:33 -04005353text meaning depends on Paint_Text_Encoding; by default, text is encoded as
Cary Clarkbad5ad72017-08-03 17:14:08 -04005354UTF-8. Origin meaning depends on Paint_Text_Align and Paint_Vertical_Text; by
Cary Clark5538c132018-06-14 12:28:14 -04005355default text positions the first glyph left side bearing and baseline relative
5356to origin. Text size is affected by matrix parameter, Canvas Matrix,
Cary Clark682c58d2018-05-16 07:07:07 -04005357and Paint_Text_Size.
Cary Clark8032b982017-07-28 11:04:54 -04005358
Mike Reed8ad91a92018-01-19 19:09:32 -05005359All elements of paint: Path_Effect, Mask_Filter, Shader,
Cary Clarkbad5ad72017-08-03 17:14:08 -04005360Color_Filter, Image_Filter, and Draw_Looper; apply to text. By default, draws
Cary Clark137b8742018-05-30 09:21:49 -04005361filled 12 point black Glyphs.
Cary Clark8032b982017-07-28 11:04:54 -04005362
Cary Clarkce101242017-09-01 15:51:02 -04005363#Param text character code points or Glyphs drawn ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005364#Param byteLength byte length of text array ##
5365#Param path Path providing text baseline ##
Cary Clarkce101242017-09-01 15:51:02 -04005366#Param matrix transform of Glyphs before mapping to path; may be nullptr
Cary Clarka523d2d2017-08-30 08:58:10 -04005367 to use identity Matrix
Cary Clarkbad5ad72017-08-03 17:14:08 -04005368##
5369#Param paint text size, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005370
5371#Example
Herb Derbyefe39bc2018-05-01 17:06:20 -04005372 void draw(SkCanvas* canvas) {
Cary Clarkbad5ad72017-08-03 17:14:08 -04005373 const char roller[] = "rollercoaster";
5374 const size_t len = sizeof(roller) - 1;
5375 SkPath path;
5376 path.cubicTo(40, -80, 120, 80, 160, -40);
5377 SkPaint paint;
5378 paint.setTextSize(32);
5379 paint.setStyle(SkPaint::kStroke_Style);
5380 SkMatrix matrix;
5381 matrix.setIdentity();
5382 for (int i = 0; i < 3; ++i) {
5383 canvas->translate(25, 60);
5384 canvas->drawPath(path, paint);
5385 canvas->drawTextOnPath(roller, len, path, &matrix, paint);
5386 matrix.preTranslate(0, 10);
5387 }
5388 }
Cary Clark8032b982017-07-28 11:04:54 -04005389##
5390
Cary Clark2ade9972017-11-02 17:49:34 -04005391#SeeAlso drawTextOnPathHV drawText drawPosTextH drawTextBlob drawTextRSXform
Cary Clark8032b982017-07-28 11:04:54 -04005392
5393##
5394
5395# ------------------------------------------------------------------------------
5396
5397#Method void drawTextRSXform(const void* text, size_t byteLength, const SkRSXform xform[],
5398 const SkRect* cullRect, const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05005399#In Draw_Text
5400#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05005401#Line # draws text with array of RSXform ##
Cary Clark8032b982017-07-28 11:04:54 -04005402
5403Draw text, transforming each glyph by the corresponding SkRSXform,
5404using Clip, Matrix, and Paint paint.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005405
Cary Clark137b8742018-05-30 09:21:49 -04005406RSXform xform array specifies a separate square scale, rotation, and translation
5407for each glyph. xform does not affect paint Shader.
Cary Clark8032b982017-07-28 11:04:54 -04005408
Cary Clarkbad5ad72017-08-03 17:14:08 -04005409Optional Rect cullRect is a conservative bounds of text, taking into account
Cary Clarkce101242017-09-01 15:51:02 -04005410RSXform and paint. If cullRect is outside of Clip, canvas can skip drawing.
Cary Clark8032b982017-07-28 11:04:54 -04005411
Mike Reed8ad91a92018-01-19 19:09:32 -05005412All elements of paint: Path_Effect, Mask_Filter, Shader,
Cary Clarkbad5ad72017-08-03 17:14:08 -04005413Color_Filter, Image_Filter, and Draw_Looper; apply to text. By default, draws
Cary Clarkce101242017-09-01 15:51:02 -04005414filled 12 point black Glyphs.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005415
Cary Clarkce101242017-09-01 15:51:02 -04005416#Param text character code points or Glyphs drawn ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005417#Param byteLength byte length of text array ##
5418#Param xform RSXform rotates, scales, and translates each glyph individually ##
5419#Param cullRect Rect bounds of text for efficient clipping; or nullptr ##
5420#Param paint text size, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005421
5422#Example
Herb Derbyefe39bc2018-05-01 17:06:20 -04005423void draw(SkCanvas* canvas) {
Cary Clarkbad5ad72017-08-03 17:14:08 -04005424 const int iterations = 26;
5425 SkRSXform transforms[iterations];
5426 char alphabet[iterations];
5427 SkScalar angle = 0;
5428 SkScalar scale = 1;
5429 for (size_t i = 0; i < SK_ARRAY_COUNT(transforms); ++i) {
5430 const SkScalar s = SkScalarSin(angle) * scale;
5431 const SkScalar c = SkScalarCos(angle) * scale;
5432 transforms[i] = SkRSXform::Make(-c, -s, -s * 16, c * 16);
5433 angle += .45;
5434 scale += .2;
5435 alphabet[i] = 'A' + i;
5436 }
5437 SkPaint paint;
5438 paint.setTextAlign(SkPaint::kCenter_Align);
5439 canvas->translate(110, 138);
5440 canvas->drawTextRSXform(alphabet, sizeof(alphabet), transforms, nullptr, paint);
Cary Clark8032b982017-07-28 11:04:54 -04005441}
5442##
5443
Cary Clark2ade9972017-11-02 17:49:34 -04005444#SeeAlso drawTextOnPath drawTextOnPathHV drawText drawPosText drawTextBlob
Cary Clark8032b982017-07-28 11:04:54 -04005445
5446##
5447
5448# ------------------------------------------------------------------------------
5449
5450#Method void drawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y, const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05005451#In Draw_Text
5452#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05005453#Line # draws text with arrays of positions and Paint ##
Cary Clark8032b982017-07-28 11:04:54 -04005454Draw Text_Blob blob at (x, y), using Clip, Matrix, and Paint paint.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005455
Cary Clarkce101242017-09-01 15:51:02 -04005456blob contains Glyphs, their positions, and paint attributes specific to text:
Cary Clarkbad5ad72017-08-03 17:14:08 -04005457Typeface, Paint_Text_Size, Paint_Text_Scale_X, Paint_Text_Skew_X,
Cary Clarkffb3d682018-05-17 12:17:28 -04005458Paint_Text_Align, Paint_Hinting, Anti_Alias, Paint_Fake_Bold,
Cary Clarkbad5ad72017-08-03 17:14:08 -04005459Font_Embedded_Bitmaps, Full_Hinting_Spacing, LCD_Text, Linear_Text,
5460Subpixel_Text, and Paint_Vertical_Text.
Cary Clark8032b982017-07-28 11:04:54 -04005461
Cary Clark3cd22cc2017-12-01 11:49:58 -05005462Paint_Text_Encoding must be set to SkPaint::kGlyphID_TextEncoding.
5463
Mike Reed8ad91a92018-01-19 19:09:32 -05005464Elements of paint: Path_Effect, Mask_Filter, Shader, Color_Filter,
Cary Clark8032b982017-07-28 11:04:54 -04005465Image_Filter, and Draw_Looper; apply to blob.
5466
Cary Clarkce101242017-09-01 15:51:02 -04005467#Param blob Glyphs, positions, and their paints' text size, typeface, and so on ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005468#Param x horizontal offset applied to blob ##
5469#Param y vertical offset applied to blob ##
5470#Param paint blend, color, stroking, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005471
5472#Example
5473#Height 120
Cary Clarkbad5ad72017-08-03 17:14:08 -04005474 void draw(SkCanvas* canvas) {
Cary Clark2f466242017-12-11 16:03:17 -05005475 SkTextBlobBuilder textBlobBuilder;
5476 const char bunny[] = "/(^x^)\\";
5477 const int len = sizeof(bunny) - 1;
5478 uint16_t glyphs[len];
5479 SkPaint paint;
5480 paint.textToGlyphs(bunny, len, glyphs);
Cary Clark3cd22cc2017-12-01 11:49:58 -05005481 paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
Cary Clark2f466242017-12-11 16:03:17 -05005482 int runs[] = { 3, 1, 3 };
5483 SkPoint textPos = { 20, 100 };
5484 int glyphIndex = 0;
5485 for (auto runLen : runs) {
5486 paint.setTextSize(1 == runLen ? 20 : 50);
Herb Derbyefe39bc2018-05-01 17:06:20 -04005487 const SkTextBlobBuilder::RunBuffer& run =
Cary Clark2f466242017-12-11 16:03:17 -05005488 textBlobBuilder.allocRun(paint, runLen, textPos.fX, textPos.fY);
5489 memcpy(run.glyphs, &glyphs[glyphIndex], sizeof(glyphs[0]) * runLen);
5490 textPos.fX += paint.measureText(&glyphs[glyphIndex], sizeof(glyphs[0]) * runLen, nullptr);
5491 glyphIndex += runLen;
5492 }
5493 sk_sp<const SkTextBlob> blob = textBlobBuilder.make();
5494 paint.reset();
Cary Clarkbad5ad72017-08-03 17:14:08 -04005495 canvas->drawTextBlob(blob.get(), 0, 0, paint);
Cary Clark8032b982017-07-28 11:04:54 -04005496 }
5497##
5498
Cary Clark2ade9972017-11-02 17:49:34 -04005499#SeeAlso drawText drawPosText drawPosTextH
Cary Clark8032b982017-07-28 11:04:54 -04005500
5501##
5502
5503# ------------------------------------------------------------------------------
5504
Herb Derbyefe39bc2018-05-01 17:06:20 -04005505#Method void drawTextBlob(const sk_sp<SkTextBlob>& blob, SkScalar x, SkScalar y, const SkPaint& paint)
Cary Clark8032b982017-07-28 11:04:54 -04005506
5507Draw Text_Blob blob at (x, y), using Clip, Matrix, and Paint paint.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005508
Cary Clarkce101242017-09-01 15:51:02 -04005509blob contains Glyphs, their positions, and paint attributes specific to text:
Cary Clarkbad5ad72017-08-03 17:14:08 -04005510Typeface, Paint_Text_Size, Paint_Text_Scale_X, Paint_Text_Skew_X,
Cary Clarkffb3d682018-05-17 12:17:28 -04005511Paint_Text_Align, Paint_Hinting, Anti_Alias, Paint_Fake_Bold,
Cary Clarkbad5ad72017-08-03 17:14:08 -04005512Font_Embedded_Bitmaps, Full_Hinting_Spacing, LCD_Text, Linear_Text,
5513Subpixel_Text, and Paint_Vertical_Text.
Cary Clark8032b982017-07-28 11:04:54 -04005514
Cary Clark3cd22cc2017-12-01 11:49:58 -05005515Paint_Text_Encoding must be set to SkPaint::kGlyphID_TextEncoding.
5516
Herb Derbyefe39bc2018-05-01 17:06:20 -04005517Elements of paint: Path_Effect, Mask_Filter, Shader, Color_Filter,
Cary Clark8032b982017-07-28 11:04:54 -04005518Image_Filter, and Draw_Looper; apply to blob.
5519
Cary Clarkce101242017-09-01 15:51:02 -04005520#Param blob Glyphs, positions, and their paints' text size, typeface, and so on ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005521#Param x horizontal offset applied to blob ##
5522#Param y vertical offset applied to blob ##
5523#Param paint blend, color, stroking, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005524
5525#Example
5526#Height 120
5527#Description
5528Paint attributes unrelated to text, like color, have no effect on paint in allocated Text_Blob.
5529Paint attributes related to text, like text size, have no effect on paint passed to drawTextBlob.
5530##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005531 void draw(SkCanvas* canvas) {
5532 SkTextBlobBuilder textBlobBuilder;
5533 SkPaint paint;
5534 paint.setTextSize(50);
5535 paint.setColor(SK_ColorRED);
Cary Clark2f466242017-12-11 16:03:17 -05005536 paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
Herb Derbyefe39bc2018-05-01 17:06:20 -04005537 const SkTextBlobBuilder::RunBuffer& run =
Cary Clarkbad5ad72017-08-03 17:14:08 -04005538 textBlobBuilder.allocRun(paint, 1, 20, 100);
5539 run.glyphs[0] = 20;
5540 sk_sp<const SkTextBlob> blob = textBlobBuilder.make();
5541 paint.setTextSize(10);
5542 paint.setColor(SK_ColorBLUE);
5543 canvas->drawTextBlob(blob.get(), 0, 0, paint);
5544 }
Cary Clark8032b982017-07-28 11:04:54 -04005545##
5546
Cary Clark2ade9972017-11-02 17:49:34 -04005547#SeeAlso drawText drawPosText drawPosTextH
Cary Clark8032b982017-07-28 11:04:54 -04005548
5549##
5550
5551# ------------------------------------------------------------------------------
5552
Herb Derbyefe39bc2018-05-01 17:06:20 -04005553#Method void drawPicture(const SkPicture* picture)
Cary Clark78de7512018-02-07 07:27:09 -05005554#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05005555#Line # draws Picture using Clip and Matrix ##
Cary Clark8032b982017-07-28 11:04:54 -04005556Draw Picture picture, using Clip and Matrix.
5557Clip and Matrix are unchanged by picture contents, as if
5558save() was called before and restore() was called after drawPicture.
5559
5560Picture records a series of draw commands for later playback.
5561
Cary Clarkbad5ad72017-08-03 17:14:08 -04005562#Param picture recorded drawing commands to play ##
Cary Clark8032b982017-07-28 11:04:54 -04005563
5564#Example
Herb Derbyefe39bc2018-05-01 17:06:20 -04005565void draw(SkCanvas* canvas) {
Cary Clarkbad5ad72017-08-03 17:14:08 -04005566 SkPictureRecorder recorder;
5567 SkCanvas* recordingCanvas = recorder.beginRecording(50, 50);
5568 for (auto color : { SK_ColorRED, SK_ColorBLUE, 0xff007f00 } ) {
5569 SkPaint paint;
5570 paint.setColor(color);
5571 recordingCanvas->drawRect({10, 10, 30, 40}, paint);
5572 recordingCanvas->translate(10, 10);
5573 recordingCanvas->scale(1.2f, 1.4f);
5574 }
5575 sk_sp<SkPicture> playback = recorder.finishRecordingAsPicture();
Cary Clarkbad5ad72017-08-03 17:14:08 -04005576 canvas->drawPicture(playback);
5577 canvas->scale(2, 2);
5578 canvas->translate(50, 0);
5579 canvas->drawPicture(playback);
Cary Clark8032b982017-07-28 11:04:54 -04005580}
5581##
5582
Cary Clark2ade9972017-11-02 17:49:34 -04005583#SeeAlso drawDrawable SkPicture SkPicture::playback
Cary Clark8032b982017-07-28 11:04:54 -04005584
5585##
5586
5587# ------------------------------------------------------------------------------
5588
Herb Derbyefe39bc2018-05-01 17:06:20 -04005589#Method void drawPicture(const sk_sp<SkPicture>& picture)
Cary Clark8032b982017-07-28 11:04:54 -04005590
5591Draw Picture picture, using Clip and Matrix.
5592Clip and Matrix are unchanged by picture contents, as if
5593save() was called before and restore() was called after drawPicture.
5594
5595Picture records a series of draw commands for later playback.
5596
Cary Clarkbad5ad72017-08-03 17:14:08 -04005597#Param picture recorded drawing commands to play ##
Cary Clark8032b982017-07-28 11:04:54 -04005598
5599#Example
Herb Derbyefe39bc2018-05-01 17:06:20 -04005600void draw(SkCanvas* canvas) {
Cary Clarkbad5ad72017-08-03 17:14:08 -04005601 SkPictureRecorder recorder;
5602 SkCanvas* recordingCanvas = recorder.beginRecording(50, 50);
5603 for (auto color : { SK_ColorRED, SK_ColorBLUE, 0xff007f00 } ) {
5604 SkPaint paint;
5605 paint.setColor(color);
5606 recordingCanvas->drawRect({10, 10, 30, 40}, paint);
5607 recordingCanvas->translate(10, 10);
5608 recordingCanvas->scale(1.2f, 1.4f);
5609 }
5610 sk_sp<SkPicture> playback = recorder.finishRecordingAsPicture();
5611 canvas->drawPicture(playback);
5612 canvas->scale(2, 2);
5613 canvas->translate(50, 0);
5614 canvas->drawPicture(playback);
Cary Clark8032b982017-07-28 11:04:54 -04005615}
5616##
5617
Cary Clark2ade9972017-11-02 17:49:34 -04005618#SeeAlso drawDrawable SkPicture SkPicture::playback
Cary Clark8032b982017-07-28 11:04:54 -04005619
5620##
5621
5622# ------------------------------------------------------------------------------
5623
5624#Method void drawPicture(const SkPicture* picture, const SkMatrix* matrix, const SkPaint* paint)
5625
Cary Clarkbad5ad72017-08-03 17:14:08 -04005626Draw Picture picture, using Clip and Matrix; transforming picture with
5627Matrix matrix, if provided; and use Paint paint Color_Alpha, Color_Filter,
5628Image_Filter, and Blend_Mode, if provided.
Cary Clark8032b982017-07-28 11:04:54 -04005629
5630matrix transformation is equivalent to: save(), concat(), drawPicture, restore().
5631paint use is equivalent to: saveLayer, drawPicture, restore().
5632
Cary Clarkbad5ad72017-08-03 17:14:08 -04005633#Param picture recorded drawing commands to play ##
5634#Param matrix Matrix to rotate, scale, translate, and so on; may be nullptr ##
5635#Param paint Paint to apply transparency, filtering, and so on; may be nullptr ##
Cary Clark8032b982017-07-28 11:04:54 -04005636
5637#Example
Herb Derbyefe39bc2018-05-01 17:06:20 -04005638void draw(SkCanvas* canvas) {
Cary Clarkbad5ad72017-08-03 17:14:08 -04005639 SkPaint paint;
5640 SkPictureRecorder recorder;
5641 SkCanvas* recordingCanvas = recorder.beginRecording(50, 50);
5642 for (auto color : { SK_ColorRED, SK_ColorBLUE, 0xff007f00 } ) {
5643 paint.setColor(color);
5644 recordingCanvas->drawRect({10, 10, 30, 40}, paint);
5645 recordingCanvas->translate(10, 10);
5646 recordingCanvas->scale(1.2f, 1.4f);
5647 }
5648 sk_sp<SkPicture> playback = recorder.finishRecordingAsPicture();
5649 const SkPicture* playbackPtr = playback.get();
5650 SkMatrix matrix;
5651 matrix.reset();
5652 for (auto alpha : { 70, 140, 210 } ) {
5653 paint.setAlpha(alpha);
5654 canvas->drawPicture(playbackPtr, &matrix, &paint);
5655 matrix.preTranslate(70, 70);
5656 }
Cary Clark8032b982017-07-28 11:04:54 -04005657}
5658##
5659
Cary Clark2ade9972017-11-02 17:49:34 -04005660#SeeAlso drawDrawable SkPicture SkPicture::playback
Cary Clark8032b982017-07-28 11:04:54 -04005661
5662##
5663
5664# ------------------------------------------------------------------------------
5665
Herb Derbyefe39bc2018-05-01 17:06:20 -04005666#Method void drawPicture(const sk_sp<SkPicture>& picture, const SkMatrix* matrix, const SkPaint* paint)
Cary Clark8032b982017-07-28 11:04:54 -04005667
Cary Clarkbad5ad72017-08-03 17:14:08 -04005668Draw Picture picture, using Clip and Matrix; transforming picture with
5669Matrix matrix, if provided; and use Paint paint Color_Alpha, Color_Filter,
5670Image_Filter, and Blend_Mode, if provided.
Cary Clark8032b982017-07-28 11:04:54 -04005671
5672matrix transformation is equivalent to: save(), concat(), drawPicture, restore().
5673paint use is equivalent to: saveLayer, drawPicture, restore().
5674
Cary Clarkbad5ad72017-08-03 17:14:08 -04005675#Param picture recorded drawing commands to play ##
5676#Param matrix Matrix to rotate, scale, translate, and so on; may be nullptr ##
5677#Param paint Paint to apply transparency, filtering, and so on; may be nullptr ##
Cary Clark8032b982017-07-28 11:04:54 -04005678
5679#Example
Herb Derbyefe39bc2018-05-01 17:06:20 -04005680void draw(SkCanvas* canvas) {
Cary Clarkbad5ad72017-08-03 17:14:08 -04005681 SkPaint paint;
5682 SkPictureRecorder recorder;
5683 SkCanvas* recordingCanvas = recorder.beginRecording(50, 50);
5684 for (auto color : { SK_ColorRED, SK_ColorBLUE, 0xff007f00 } ) {
5685 paint.setColor(color);
5686 recordingCanvas->drawRect({10, 10, 30, 40}, paint);
5687 recordingCanvas->translate(10, 10);
5688 recordingCanvas->scale(1.2f, 1.4f);
5689 }
5690 sk_sp<SkPicture> playback = recorder.finishRecordingAsPicture();
5691 SkMatrix matrix;
5692 matrix.reset();
5693 for (auto alpha : { 70, 140, 210 } ) {
5694 paint.setAlpha(alpha);
5695 canvas->drawPicture(playback, &matrix, &paint);
5696 matrix.preTranslate(70, 70);
5697 }
Cary Clark8032b982017-07-28 11:04:54 -04005698}
5699##
5700
Cary Clark2ade9972017-11-02 17:49:34 -04005701#SeeAlso drawDrawable SkPicture SkPicture::playback
Cary Clark8032b982017-07-28 11:04:54 -04005702
5703##
5704
5705# ------------------------------------------------------------------------------
5706
5707#Method void drawVertices(const SkVertices* vertices, SkBlendMode mode, const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05005708#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05005709#Line # draws Vertices, a triangle mesh ##
Cary Clark8032b982017-07-28 11:04:54 -04005710Draw Vertices vertices, a triangle mesh, using Clip and Matrix.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005711If Vertices_Texs and Vertices_Colors are defined in vertices, and Paint paint
5712contains Shader, Blend_Mode mode combines Vertices_Colors with Shader.
Cary Clark8032b982017-07-28 11:04:54 -04005713
Cary Clarkbad5ad72017-08-03 17:14:08 -04005714#Param vertices triangle mesh to draw ##
5715#Param mode combines Vertices_Colors with Shader, if both are present ##
5716#Param paint specifies the Shader, used as Vertices texture; may be nullptr ##
Cary Clark8032b982017-07-28 11:04:54 -04005717
5718#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04005719void draw(SkCanvas* canvas) {
5720 SkPaint paint;
5721 SkPoint points[] = { { 0, 0 }, { 250, 0 }, { 100, 100 }, { 0, 250 } };
5722 SkColor colors[] = { SK_ColorRED, SK_ColorBLUE, SK_ColorYELLOW, SK_ColorCYAN };
5723 auto vertices = SkVertices::MakeCopy(SkVertices::kTriangleFan_VertexMode,
5724 SK_ARRAY_COUNT(points), points, nullptr, colors);
5725 canvas->drawVertices(vertices.get(), SkBlendMode::kSrc, paint);
5726}
Cary Clark8032b982017-07-28 11:04:54 -04005727##
5728
Cary Clark2ade9972017-11-02 17:49:34 -04005729#SeeAlso drawPatch drawPicture
Cary Clark8032b982017-07-28 11:04:54 -04005730
5731##
5732
5733# ------------------------------------------------------------------------------
5734
5735#Method void drawVertices(const sk_sp<SkVertices>& vertices, SkBlendMode mode, const SkPaint& paint)
5736
5737Draw Vertices vertices, a triangle mesh, using Clip and Matrix.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005738If Vertices_Texs and Vertices_Colors are defined in vertices, and Paint paint
5739contains Shader, Blend_Mode mode combines Vertices_Colors with Shader.
Cary Clark8032b982017-07-28 11:04:54 -04005740
Cary Clarkbad5ad72017-08-03 17:14:08 -04005741#Param vertices triangle mesh to draw ##
5742#Param mode combines Vertices_Colors with Shader, if both are present ##
5743#Param paint specifies the Shader, used as Vertices texture, may be nullptr ##
Cary Clark8032b982017-07-28 11:04:54 -04005744
5745#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04005746void draw(SkCanvas* canvas) {
5747 SkPaint paint;
5748 SkPoint points[] = { { 0, 0 }, { 250, 0 }, { 100, 100 }, { 0, 250 } };
5749 SkPoint texs[] = { { 0, 0 }, { 0, 250 }, { 250, 250 }, { 250, 0 } };
5750 SkColor colors[] = { SK_ColorRED, SK_ColorBLUE, SK_ColorYELLOW, SK_ColorCYAN };
5751 paint.setShader(SkGradientShader::MakeLinear(points, colors, nullptr, 4,
5752 SkShader::kClamp_TileMode));
5753 auto vertices = SkVertices::MakeCopy(SkVertices::kTriangleFan_VertexMode,
5754 SK_ARRAY_COUNT(points), points, texs, colors);
5755 canvas->drawVertices(vertices.get(), SkBlendMode::kDarken, paint);
Cary Clark8032b982017-07-28 11:04:54 -04005756}
5757##
5758
Cary Clark2ade9972017-11-02 17:49:34 -04005759#SeeAlso drawPatch drawPicture
Cary Clark8032b982017-07-28 11:04:54 -04005760
5761##
5762
5763# ------------------------------------------------------------------------------
5764
5765#Method void drawPatch(const SkPoint cubics[12], const SkColor colors[4],
5766 const SkPoint texCoords[4], SkBlendMode mode, const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05005767#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05005768#Line # draws Coons_Patch ##
Cary Clark8032b982017-07-28 11:04:54 -04005769
Herb Derbyefe39bc2018-05-01 17:06:20 -04005770Draws a Coons_Patch: the interpolation of four cubics with shared corners,
Cary Clark5538c132018-06-14 12:28:14 -04005771associating a color, and optionally a texture Point, with each corner.
Cary Clark8032b982017-07-28 11:04:54 -04005772
Cary Clarka560c472017-11-27 10:44:06 -05005773Coons_Patch uses Clip and Matrix, paint Shader, Color_Filter,
Cary Clarkbad5ad72017-08-03 17:14:08 -04005774Color_Alpha, Image_Filter, and Blend_Mode. If Shader is provided it is treated
Cary Clarka560c472017-11-27 10:44:06 -05005775as Coons_Patch texture; Blend_Mode mode combines Color colors and Shader if
Cary Clarkbad5ad72017-08-03 17:14:08 -04005776both are provided.
Cary Clark8032b982017-07-28 11:04:54 -04005777
Herb Derbyefe39bc2018-05-01 17:06:20 -04005778Point array cubics specifies four Cubics starting at the top-left corner,
Cary Clarkce101242017-09-01 15:51:02 -04005779in clockwise order, sharing every fourth point. The last Cubic ends at the
Cary Clarkbad5ad72017-08-03 17:14:08 -04005780first point.
Cary Clark8032b982017-07-28 11:04:54 -04005781
Cary Clarkbc5697d2017-10-04 14:31:33 -04005782Color array color associates colors with corners in top-left, top-right,
5783bottom-right, bottom-left order.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005784
5785If paint contains Shader, Point array texCoords maps Shader as texture to
Cary Clarkbc5697d2017-10-04 14:31:33 -04005786corners in top-left, top-right, bottom-right, bottom-left order.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005787
Cary Clarka523d2d2017-08-30 08:58:10 -04005788#Param cubics Path_Cubic array, sharing common points ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005789#Param colors Color array, one for each corner ##
Cary Clarkce101242017-09-01 15:51:02 -04005790#Param texCoords Point array of texture coordinates, mapping Shader to corners;
Herb Derbyefe39bc2018-05-01 17:06:20 -04005791 may be nullptr
Cary Clark579985c2017-07-31 11:48:27 -04005792#Param ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005793#Param mode Blend_Mode for colors, and for Shader if paint has one ##
5794#Param paint Shader, Color_Filter, Blend_Mode, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005795
5796#Example
5797#Image 5
Cary Clarkbad5ad72017-08-03 17:14:08 -04005798void draw(SkCanvas* canvas) {
5799 // SkBitmap source = cmbkygk;
5800 SkPaint paint;
5801 paint.setFilterQuality(kLow_SkFilterQuality);
5802 paint.setAntiAlias(true);
5803 SkPoint cubics[] = { { 3, 1 }, { 4, 2 }, { 5, 1 }, { 7, 3 },
5804 /* { 7, 3 }, */ { 6, 4 }, { 7, 5 }, { 5, 7 },
5805 /* { 5, 7 }, */ { 4, 6 }, { 3, 7 }, { 1, 5 },
5806 /* { 1, 5 }, */ { 2, 4 }, { 1, 3 }, /* { 3, 1 } */ };
5807 SkColor colors[] = { 0xbfff0000, 0xbf0000ff, 0xbfff00ff, 0xbf00ffff };
5808 SkPoint texCoords[] = { { -30, -30 }, { 162, -30}, { 162, 162}, { -30, 162} };
5809 paint.setShader(SkShader::MakeBitmapShader(source, SkShader::kClamp_TileMode,
5810 SkShader::kClamp_TileMode, nullptr));
5811 canvas->scale(15, 15);
5812 for (auto blend : { SkBlendMode::kSrcOver, SkBlendMode::kModulate, SkBlendMode::kXor } ) {
5813 canvas->drawPatch(cubics, colors, texCoords, blend, paint);
5814 canvas->translate(4, 4);
5815 }
Cary Clark8032b982017-07-28 11:04:54 -04005816}
5817##
5818
Cary Clark2ade9972017-11-02 17:49:34 -04005819#ToDo can patch use image filter? ##
5820#SeeAlso SeeAlso drawVertices drawPicture
Cary Clark8032b982017-07-28 11:04:54 -04005821
5822##
5823
5824# ------------------------------------------------------------------------------
5825
5826#Method void drawPatch(const SkPoint cubics[12], const SkColor colors[4],
Herb Derbyefe39bc2018-05-01 17:06:20 -04005827 const SkPoint texCoords[4], const SkPaint& paint)
Cary Clark8032b982017-07-28 11:04:54 -04005828
Herb Derbyefe39bc2018-05-01 17:06:20 -04005829Draws Cubic Coons_Patch: the interpolation of four cubics with shared corners,
Cary Clark5538c132018-06-14 12:28:14 -04005830associating a color, and optionally a texture Point, with each corner.
Cary Clark8032b982017-07-28 11:04:54 -04005831
Cary Clarka560c472017-11-27 10:44:06 -05005832Coons_Patch uses Clip and Matrix, paint Shader, Color_Filter,
Cary Clarkbad5ad72017-08-03 17:14:08 -04005833Color_Alpha, Image_Filter, and Blend_Mode. If Shader is provided it is treated
Cary Clarka560c472017-11-27 10:44:06 -05005834as Coons_Patch texture; Blend_Mode mode combines Color colors and Shader if
Cary Clarkbad5ad72017-08-03 17:14:08 -04005835both are provided.
Cary Clark8032b982017-07-28 11:04:54 -04005836
Herb Derbyefe39bc2018-05-01 17:06:20 -04005837Point array cubics specifies four Cubics starting at the top-left corner,
Cary Clarkce101242017-09-01 15:51:02 -04005838in clockwise order, sharing every fourth point. The last Cubic ends at the
Cary Clarkbad5ad72017-08-03 17:14:08 -04005839first point.
5840
Cary Clarkbc5697d2017-10-04 14:31:33 -04005841Color array color associates colors with corners in top-left, top-right,
5842bottom-right, bottom-left order.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005843
5844If paint contains Shader, Point array texCoords maps Shader as texture to
Cary Clarkbc5697d2017-10-04 14:31:33 -04005845corners in top-left, top-right, bottom-right, bottom-left order.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005846
Cary Clarka523d2d2017-08-30 08:58:10 -04005847#Param cubics Path_Cubic array, sharing common points ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005848#Param colors Color array, one for each corner ##
Cary Clarkce101242017-09-01 15:51:02 -04005849#Param texCoords Point array of texture coordinates, mapping Shader to corners;
Herb Derbyefe39bc2018-05-01 17:06:20 -04005850 may be nullptr
Cary Clark579985c2017-07-31 11:48:27 -04005851#Param ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005852#Param paint Shader, Color_Filter, Blend_Mode, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005853
5854#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04005855void draw(SkCanvas* canvas) {
5856 SkPaint paint;
5857 paint.setAntiAlias(true);
5858 SkPoint cubics[] = { { 3, 1 }, { 4, 2 }, { 5, 1 }, { 7, 3 },
5859 /* { 7, 3 }, */ { 6, 4 }, { 7, 5 }, { 5, 7 },
5860 /* { 5, 7 }, */ { 4, 6 }, { 3, 7 }, { 1, 5 },
5861 /* { 1, 5 }, */ { 2, 4 }, { 1, 3 }, /* { 3, 1 } */ };
5862 SkColor colors[] = { SK_ColorRED, SK_ColorBLUE, SK_ColorYELLOW, SK_ColorCYAN };
5863 canvas->scale(30, 30);
5864 canvas->drawPatch(cubics, colors, nullptr, paint);
5865 SkPoint text[] = { {3,0.9f}, {4,2.5f}, {5,0.9f}, {7.5f,3.2f}, {5.5f,4.2f},
5866 {7.5f,5.2f}, {5,7.5f}, {4,5.9f}, {3,7.5f}, {0.5f,5.2f}, {2.5f,4.2f},
5867 {0.5f,3.2f} };
5868 paint.setTextSize(18.f / 30);
5869 paint.setTextAlign(SkPaint::kCenter_Align);
5870 for (int i = 0; i< 10; ++i) {
5871 char digit = '0' + i;
5872 canvas->drawText(&digit, 1, text[i].fX, text[i].fY, paint);
5873 }
5874 canvas->drawString("10", text[10].fX, text[10].fY, paint);
5875 canvas->drawString("11", text[11].fX, text[11].fY, paint);
5876 paint.setStyle(SkPaint::kStroke_Style);
5877 canvas->drawPoints(SkCanvas::kPolygon_PointMode, 12, cubics, paint);
5878 canvas->drawLine(cubics[11].fX, cubics[11].fY, cubics[0].fX, cubics[0].fY, paint);
Cary Clark8032b982017-07-28 11:04:54 -04005879}
5880##
5881
5882#Example
5883#Image 6
Cary Clarkbad5ad72017-08-03 17:14:08 -04005884void draw(SkCanvas* canvas) {
5885 // SkBitmap source = checkerboard;
5886 SkPaint paint;
5887 paint.setFilterQuality(kLow_SkFilterQuality);
5888 paint.setAntiAlias(true);
5889 SkPoint cubics[] = { { 3, 1 }, { 4, 2 }, { 5, 1 }, { 7, 3 },
5890 /* { 7, 3 }, */ { 6, 4 }, { 7, 5 }, { 5, 7 },
5891 /* { 5, 7 }, */ { 4, 6 }, { 3, 7 }, { 1, 5 },
5892 /* { 1, 5 }, */ { 2, 4 }, { 1, 3 }, /* { 3, 1 } */ };
5893 SkPoint texCoords[] = { { 0, 0 }, { 0, 62}, { 62, 62}, { 62, 0 } };
5894 paint.setShader(SkShader::MakeBitmapShader(source, SkShader::kClamp_TileMode,
5895 SkShader::kClamp_TileMode, nullptr));
5896 canvas->scale(30, 30);
5897 canvas->drawPatch(cubics, nullptr, texCoords, paint);
Cary Clark8032b982017-07-28 11:04:54 -04005898}
5899##
5900
Cary Clark2ade9972017-11-02 17:49:34 -04005901#ToDo can patch use image filter? ##
5902#SeeAlso SeeAlso drawVertices drawPicture
Cary Clark8032b982017-07-28 11:04:54 -04005903
5904##
5905
5906# ------------------------------------------------------------------------------
5907
5908#Method void drawAtlas(const SkImage* atlas, const SkRSXform xform[], const SkRect tex[],
5909 const SkColor colors[], int count, SkBlendMode mode, const SkRect* cullRect,
5910 const SkPaint* paint)
Cary Clark78de7512018-02-07 07:27:09 -05005911#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05005912#Line # draws sprites using Clip, Matrix, and Paint ##
Cary Clark8032b982017-07-28 11:04:54 -04005913
5914Draw a set of sprites from atlas, using Clip, Matrix, and optional Paint paint.
Cary Clarkffb3d682018-05-17 12:17:28 -04005915paint uses Anti_Alias, Color_Alpha, Color_Filter, Image_Filter, and Blend_Mode
Cary Clarkbad5ad72017-08-03 17:14:08 -04005916to draw, if present. For each entry in the array, Rect tex locates sprite in
5917atlas, and RSXform xform transforms it into destination space.
5918
Cary Clark8032b982017-07-28 11:04:54 -04005919xform, text, and colors if present, must contain count entries.
Cary Clark224c7002018-06-27 11:00:21 -04005920Optional colors are applied for each sprite using Blend_Mode mode, treating
5921sprite as source and colors as destination.
Herb Derbyefe39bc2018-05-01 17:06:20 -04005922Optional cullRect is a conservative bounds of all transformed sprites.
Cary Clarkce101242017-09-01 15:51:02 -04005923If cullRect is outside of Clip, canvas can skip drawing.
Cary Clark8032b982017-07-28 11:04:54 -04005924
Cary Clark224c7002018-06-27 11:00:21 -04005925
5926
Cary Clarkbad5ad72017-08-03 17:14:08 -04005927#Param atlas Image containing sprites ##
5928#Param xform RSXform mappings for sprites in atlas ##
5929#Param tex Rect locations of sprites in atlas ##
Cary Clark6fc50412017-09-21 12:31:06 -04005930#Param colors one per sprite, blended with sprite using Blend_Mode; may be nullptr ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005931#Param count number of sprites to draw ##
5932#Param mode Blend_Mode combining colors and sprites ##
Cary Clark6fc50412017-09-21 12:31:06 -04005933#Param cullRect bounds of transformed sprites for efficient clipping; may be nullptr ##
5934#Param paint Color_Filter, Image_Filter, Blend_Mode, and so on; may be nullptr ##
Cary Clark8032b982017-07-28 11:04:54 -04005935
5936#Example
5937#Image 3
Cary Clarkbad5ad72017-08-03 17:14:08 -04005938void draw(SkCanvas* canvas) {
5939 // SkBitmap source = mandrill;
5940 SkRSXform xforms[] = { { .5f, 0, 0, 0 }, {0, .5f, 200, 100 } };
5941 SkRect tex[] = { { 0, 0, 250, 250 }, { 0, 0, 250, 250 } };
5942 SkColor colors[] = { 0x7f55aa00, 0x7f3333bf };
5943 const SkImage* imagePtr = image.get();
5944 canvas->drawAtlas(imagePtr, xforms, tex, colors, 2, SkBlendMode::kSrcOver, nullptr, nullptr);
Cary Clark8032b982017-07-28 11:04:54 -04005945}
5946##
5947
Cary Clark2ade9972017-11-02 17:49:34 -04005948#SeeAlso drawBitmap drawImage
Cary Clark8032b982017-07-28 11:04:54 -04005949
5950##
5951
5952# ------------------------------------------------------------------------------
5953
5954#Method void drawAtlas(const sk_sp<SkImage>& atlas, const SkRSXform xform[], const SkRect tex[],
5955 const SkColor colors[], int count, SkBlendMode mode, const SkRect* cullRect,
Herb Derbyefe39bc2018-05-01 17:06:20 -04005956 const SkPaint* paint)
Cary Clark8032b982017-07-28 11:04:54 -04005957
5958Draw a set of sprites from atlas, using Clip, Matrix, and optional Paint paint.
Cary Clarkffb3d682018-05-17 12:17:28 -04005959paint uses Anti_Alias, Color_Alpha, Color_Filter, Image_Filter, and Blend_Mode
Cary Clarkbad5ad72017-08-03 17:14:08 -04005960to draw, if present. For each entry in the array, Rect tex locates sprite in
5961atlas, and RSXform xform transforms it into destination space.
5962
Cary Clark8032b982017-07-28 11:04:54 -04005963xform, text, and colors if present, must contain count entries.
5964Optional colors is applied for each sprite using Blend_Mode.
Herb Derbyefe39bc2018-05-01 17:06:20 -04005965Optional cullRect is a conservative bounds of all transformed sprites.
Cary Clarkce101242017-09-01 15:51:02 -04005966If cullRect is outside of Clip, canvas can skip drawing.
Cary Clark8032b982017-07-28 11:04:54 -04005967
Cary Clarkbad5ad72017-08-03 17:14:08 -04005968#Param atlas Image containing sprites ##
5969#Param xform RSXform mappings for sprites in atlas ##
5970#Param tex Rect locations of sprites in atlas ##
Cary Clark6fc50412017-09-21 12:31:06 -04005971#Param colors one per sprite, blended with sprite using Blend_Mode; may be nullptr ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005972#Param count number of sprites to draw ##
5973#Param mode Blend_Mode combining colors and sprites ##
Cary Clark6fc50412017-09-21 12:31:06 -04005974#Param cullRect bounds of transformed sprites for efficient clipping; may be nullptr ##
5975#Param paint Color_Filter, Image_Filter, Blend_Mode, and so on; may be nullptr ##
Cary Clark8032b982017-07-28 11:04:54 -04005976
5977#Example
5978#Image 3
Cary Clarkbad5ad72017-08-03 17:14:08 -04005979void draw(SkCanvas* canvas) {
5980 // SkBitmap source = mandrill;
5981 SkRSXform xforms[] = { { .5f, 0, 0, 0 }, {0, .5f, 200, 100 } };
5982 SkRect tex[] = { { 0, 0, 250, 250 }, { 0, 0, 250, 250 } };
5983 SkColor colors[] = { 0x7f55aa00, 0x7f3333bf };
5984 SkPaint paint;
5985 paint.setAlpha(127);
5986 canvas->drawAtlas(image, xforms, tex, colors, 2, SkBlendMode::kPlus, nullptr, &paint);
Cary Clark8032b982017-07-28 11:04:54 -04005987}
5988##
5989
5990#ToDo bug in example on cpu side, gpu looks ok ##
5991
Cary Clark2ade9972017-11-02 17:49:34 -04005992#SeeAlso drawBitmap drawImage
5993
Cary Clark8032b982017-07-28 11:04:54 -04005994##
5995
5996# ------------------------------------------------------------------------------
5997
5998#Method void drawAtlas(const SkImage* atlas, const SkRSXform xform[], const SkRect tex[], int count,
Herb Derbyefe39bc2018-05-01 17:06:20 -04005999 const SkRect* cullRect, const SkPaint* paint)
Cary Clark8032b982017-07-28 11:04:54 -04006000
6001Draw a set of sprites from atlas, using Clip, Matrix, and optional Paint paint.
Cary Clarkffb3d682018-05-17 12:17:28 -04006002paint uses Anti_Alias, Color_Alpha, Color_Filter, Image_Filter, and Blend_Mode
Cary Clarkbad5ad72017-08-03 17:14:08 -04006003to draw, if present. For each entry in the array, Rect tex locates sprite in
6004atlas, and RSXform xform transforms it into destination space.
6005
Cary Clark8032b982017-07-28 11:04:54 -04006006xform and text must contain count entries.
Herb Derbyefe39bc2018-05-01 17:06:20 -04006007Optional cullRect is a conservative bounds of all transformed sprites.
Cary Clarkce101242017-09-01 15:51:02 -04006008If cullRect is outside of Clip, canvas can skip drawing.
Cary Clark8032b982017-07-28 11:04:54 -04006009
Cary Clarkbad5ad72017-08-03 17:14:08 -04006010#Param atlas Image containing sprites ##
6011#Param xform RSXform mappings for sprites in atlas ##
6012#Param tex Rect locations of sprites in atlas ##
6013#Param count number of sprites to draw ##
Cary Clark6fc50412017-09-21 12:31:06 -04006014#Param cullRect bounds of transformed sprites for efficient clipping; may be nullptr ##
6015#Param paint Color_Filter, Image_Filter, Blend_Mode, and so on; may be nullptr ##
Cary Clark8032b982017-07-28 11:04:54 -04006016
6017#Example
6018#Image 3
Cary Clarkbad5ad72017-08-03 17:14:08 -04006019void draw(SkCanvas* canvas) {
6020 // sk_sp<SkImage> image = mandrill;
6021 SkRSXform xforms[] = { { .5f, 0, 0, 0 }, {0, .5f, 200, 100 } };
6022 SkRect tex[] = { { 0, 0, 250, 250 }, { 0, 0, 250, 250 } };
6023 const SkImage* imagePtr = image.get();
6024 canvas->drawAtlas(imagePtr, xforms, tex, 2, nullptr, nullptr);
Cary Clark8032b982017-07-28 11:04:54 -04006025}
6026##
6027
Cary Clark2ade9972017-11-02 17:49:34 -04006028#SeeAlso drawBitmap drawImage
Cary Clark8032b982017-07-28 11:04:54 -04006029
6030##
6031
6032# ------------------------------------------------------------------------------
6033
6034#Method void drawAtlas(const sk_sp<SkImage>& atlas, const SkRSXform xform[], const SkRect tex[],
Herb Derbyefe39bc2018-05-01 17:06:20 -04006035 int count, const SkRect* cullRect, const SkPaint* paint)
Cary Clark8032b982017-07-28 11:04:54 -04006036
6037Draw a set of sprites from atlas, using Clip, Matrix, and optional Paint paint.
Cary Clarkffb3d682018-05-17 12:17:28 -04006038paint uses Anti_Alias, Color_Alpha, Color_Filter, Image_Filter, and Blend_Mode
Cary Clarkbad5ad72017-08-03 17:14:08 -04006039to draw, if present. For each entry in the array, Rect tex locates sprite in
6040atlas, and RSXform xform transforms it into destination space.
6041
Cary Clark8032b982017-07-28 11:04:54 -04006042xform and text must contain count entries.
Herb Derbyefe39bc2018-05-01 17:06:20 -04006043Optional cullRect is a conservative bounds of all transformed sprites.
Cary Clarkce101242017-09-01 15:51:02 -04006044If cullRect is outside of Clip, canvas can skip drawing.
Cary Clark8032b982017-07-28 11:04:54 -04006045
Cary Clarkbad5ad72017-08-03 17:14:08 -04006046#Param atlas Image containing sprites ##
6047#Param xform RSXform mappings for sprites in atlas ##
6048#Param tex Rect locations of sprites in atlas ##
6049#Param count number of sprites to draw ##
Cary Clark6fc50412017-09-21 12:31:06 -04006050#Param cullRect bounds of transformed sprites for efficient clipping; may be nullptr ##
6051#Param paint Color_Filter, Image_Filter, Blend_Mode, and so on; may be nullptr ##
Cary Clark8032b982017-07-28 11:04:54 -04006052
6053#Example
6054#Image 3
Cary Clarkbad5ad72017-08-03 17:14:08 -04006055void draw(SkCanvas* canvas) {
6056 // sk_sp<SkImage> image = mandrill;
6057 SkRSXform xforms[] = { { 1, 0, 0, 0 }, {0, 1, 300, 100 } };
6058 SkRect tex[] = { { 0, 0, 200, 200 }, { 200, 0, 400, 200 } };
6059 canvas->drawAtlas(image, xforms, tex, 2, nullptr, nullptr);
Cary Clark8032b982017-07-28 11:04:54 -04006060}
6061##
6062
Cary Clark2ade9972017-11-02 17:49:34 -04006063#SeeAlso drawBitmap drawImage
Cary Clark8032b982017-07-28 11:04:54 -04006064
6065##
6066
6067# ------------------------------------------------------------------------------
6068
Cary Clark73fa9722017-08-29 17:36:51 -04006069#Method void drawDrawable(SkDrawable* drawable, const SkMatrix* matrix = nullptr)
Cary Clark78de7512018-02-07 07:27:09 -05006070#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05006071#Line # draws Drawable, encapsulated drawing commands ##
Herb Derbyefe39bc2018-05-01 17:06:20 -04006072Draw Drawable drawable using Clip and Matrix, concatenated with
Cary Clark8032b982017-07-28 11:04:54 -04006073optional matrix.
6074
Herb Derbyefe39bc2018-05-01 17:06:20 -04006075If Canvas has an asynchronous implementation, as is the case
Cary Clark8032b982017-07-28 11:04:54 -04006076when it is recording into Picture, then drawable will be referenced,
6077so that SkDrawable::draw() can be called when the operation is finalized. To force
6078immediate drawing, call SkDrawable::draw() instead.
6079
Cary Clarkbad5ad72017-08-03 17:14:08 -04006080#Param drawable custom struct encapsulating drawing commands ##
6081#Param matrix transformation applied to drawing; may be nullptr ##
Cary Clark8032b982017-07-28 11:04:54 -04006082
6083#Example
6084#Height 100
6085#Function
Cary Clarkbad5ad72017-08-03 17:14:08 -04006086struct MyDrawable : public SkDrawable {
6087 SkRect onGetBounds() override { return SkRect::MakeWH(50, 100); }
6088
6089 void onDraw(SkCanvas* canvas) override {
6090 SkPath path;
6091 path.conicTo(10, 90, 50, 90, 0.9f);
6092 SkPaint paint;
6093 paint.setColor(SK_ColorBLUE);
6094 canvas->drawRect(path.getBounds(), paint);
6095 paint.setAntiAlias(true);
6096 paint.setColor(SK_ColorWHITE);
6097 canvas->drawPath(path, paint);
6098 }
6099};
6100
6101#Function ##
6102void draw(SkCanvas* canvas) {
6103 sk_sp<SkDrawable> drawable(new MyDrawable);
6104 SkMatrix matrix;
6105 matrix.setTranslate(10, 10);
6106 canvas->drawDrawable(drawable.get(), &matrix);
Cary Clark8032b982017-07-28 11:04:54 -04006107}
6108##
6109
Cary Clark2ade9972017-11-02 17:49:34 -04006110#SeeAlso SkDrawable drawPicture
Cary Clark8032b982017-07-28 11:04:54 -04006111
6112##
6113
6114# ------------------------------------------------------------------------------
6115
6116#Method void drawDrawable(SkDrawable* drawable, SkScalar x, SkScalar y)
6117
6118Draw Drawable drawable using Clip and Matrix, offset by (x, y).
6119
Herb Derbyefe39bc2018-05-01 17:06:20 -04006120If Canvas has an asynchronous implementation, as is the case
Cary Clark8032b982017-07-28 11:04:54 -04006121when it is recording into Picture, then drawable will be referenced,
6122so that SkDrawable::draw() can be called when the operation is finalized. To force
6123immediate drawing, call SkDrawable::draw() instead.
6124
Cary Clarkbad5ad72017-08-03 17:14:08 -04006125#Param drawable custom struct encapsulating drawing commands ##
Cary Clark5538c132018-06-14 12:28:14 -04006126#Param x offset into Canvas writable pixels on x-axis ##
6127#Param y offset into Canvas writable pixels on y-axis ##
Cary Clark8032b982017-07-28 11:04:54 -04006128
6129#Example
6130#Height 100
6131#Function
Cary Clarkbad5ad72017-08-03 17:14:08 -04006132struct MyDrawable : public SkDrawable {
6133 SkRect onGetBounds() override { return SkRect::MakeWH(50, 100); }
6134
6135 void onDraw(SkCanvas* canvas) override {
6136 SkPath path;
6137 path.conicTo(10, 90, 50, 90, 0.9f);
6138 SkPaint paint;
6139 paint.setColor(SK_ColorBLUE);
6140 canvas->drawRect(path.getBounds(), paint);
6141 paint.setAntiAlias(true);
6142 paint.setColor(SK_ColorWHITE);
6143 canvas->drawPath(path, paint);
6144 }
6145};
6146
6147#Function ##
6148void draw(SkCanvas* canvas) {
6149 sk_sp<SkDrawable> drawable(new MyDrawable);
6150 canvas->drawDrawable(drawable.get(), 10, 10);
Cary Clark8032b982017-07-28 11:04:54 -04006151}
6152##
6153
Cary Clark2ade9972017-11-02 17:49:34 -04006154#SeeAlso SkDrawable drawPicture
Cary Clark8032b982017-07-28 11:04:54 -04006155
6156##
6157
6158# ------------------------------------------------------------------------------
6159
6160#Method void drawAnnotation(const SkRect& rect, const char key[], SkData* value)
Cary Clark78de7512018-02-07 07:27:09 -05006161#In Draw
6162#In Utility
Cary Clarkab2621d2018-01-30 10:08:57 -05006163#Line # associates a Rect with a key-value pair ##
Cary Clark78de7512018-02-07 07:27:09 -05006164Associate Rect on Canvas with an annotation; a key-value pair, where the key is
Cary Clark8032b982017-07-28 11:04:54 -04006165a null-terminated utf8 string, and optional value is stored as Data.
6166
Herb Derbyefe39bc2018-05-01 17:06:20 -04006167Only some canvas implementations, such as recording to Picture, or drawing to
Cary Clark8032b982017-07-28 11:04:54 -04006168Document_PDF, use annotations.
6169
Cary Clarkbad5ad72017-08-03 17:14:08 -04006170#Param rect Rect extent of canvas to annotate ##
6171#Param key string used for lookup ##
6172#Param value data holding value stored in annotation ##
Cary Clark8032b982017-07-28 11:04:54 -04006173
6174#Example
6175 #Height 1
6176 const char text[] = "Click this link!";
6177 SkRect bounds;
6178 SkPaint paint;
6179 paint.setTextSize(40);
6180 (void)paint.measureText(text, strlen(text), &bounds);
6181 const char url[] = "https://www.google.com/";
6182 sk_sp<SkData> urlData(SkData::MakeWithCString(url));
6183 canvas->drawAnnotation(bounds, "url_key", urlData.get());
6184##
6185
Cary Clark2ade9972017-11-02 17:49:34 -04006186#SeeAlso SkPicture SkDocument
Cary Clark8032b982017-07-28 11:04:54 -04006187
6188##
6189
6190# ------------------------------------------------------------------------------
6191
Herb Derbyefe39bc2018-05-01 17:06:20 -04006192#Method void drawAnnotation(const SkRect& rect, const char key[], const sk_sp<SkData>& value)
Cary Clark8032b982017-07-28 11:04:54 -04006193
6194Associate Rect on Canvas when an annotation; a key-value pair, where the key is
6195a null-terminated utf8 string, and optional value is stored as Data.
6196
Herb Derbyefe39bc2018-05-01 17:06:20 -04006197Only some canvas implementations, such as recording to Picture, or drawing to
Cary Clark8032b982017-07-28 11:04:54 -04006198Document_PDF, use annotations.
6199
Cary Clarkbad5ad72017-08-03 17:14:08 -04006200#Param rect Rect extent of canvas to annotate ##
6201#Param key string used for lookup ##
6202#Param value data holding value stored in annotation ##
Cary Clark8032b982017-07-28 11:04:54 -04006203
6204#Example
6205#Height 1
6206 const char text[] = "Click this link!";
6207 SkRect bounds;
6208 SkPaint paint;
6209 paint.setTextSize(40);
6210 (void)paint.measureText(text, strlen(text), &bounds);
6211 const char url[] = "https://www.google.com/";
6212 sk_sp<SkData> urlData(SkData::MakeWithCString(url));
6213 canvas->drawAnnotation(bounds, "url_key", urlData.get());
6214##
6215
Cary Clark2ade9972017-11-02 17:49:34 -04006216#SeeAlso SkPicture SkDocument
Cary Clark8032b982017-07-28 11:04:54 -04006217
6218##
6219
6220#Method SkDrawFilter* getDrawFilter() const
Cary Clark4855f782018-02-06 09:41:53 -05006221#Deprecated soon
Cary Clark8032b982017-07-28 11:04:54 -04006222##
6223
6224#Method virtual SkDrawFilter* setDrawFilter(SkDrawFilter* filter)
Cary Clark4855f782018-02-06 09:41:53 -05006225#Deprecated soon
Cary Clark8032b982017-07-28 11:04:54 -04006226##
6227
6228# ------------------------------------------------------------------------------
6229
6230#Method virtual bool isClipEmpty() const
Cary Clark78de7512018-02-07 07:27:09 -05006231#In Property
Cary Clarkab2621d2018-01-30 10:08:57 -05006232#Line # returns if Clip is empty ##
Cary Clark8032b982017-07-28 11:04:54 -04006233Returns true if Clip is empty; that is, nothing will draw.
6234
Cary Clarkbad5ad72017-08-03 17:14:08 -04006235May do work when called; it should not be called
Cary Clark8032b982017-07-28 11:04:54 -04006236more often than needed. However, once called, subsequent calls perform no
6237work until Clip changes.
6238
Cary Clarkbad5ad72017-08-03 17:14:08 -04006239#Return true if Clip is empty ##
Cary Clark8032b982017-07-28 11:04:54 -04006240
6241#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04006242 void draw(SkCanvas* canvas) {
6243 SkDebugf("clip is%s empty\n", canvas->isClipEmpty() ? "" : " not");
6244 SkPath path;
6245 canvas->clipPath(path);
6246 SkDebugf("clip is%s empty\n", canvas->isClipEmpty() ? "" : " not");
Cary Clark8032b982017-07-28 11:04:54 -04006247 }
6248 #StdOut
Cary Clarkbad5ad72017-08-03 17:14:08 -04006249 clip is not empty
Cary Clark8032b982017-07-28 11:04:54 -04006250 clip is empty
6251 ##
6252##
6253
Cary Clark2ade9972017-11-02 17:49:34 -04006254#SeeAlso isClipRect getLocalClipBounds getDeviceClipBounds
Cary Clark8032b982017-07-28 11:04:54 -04006255
6256##
6257
6258# ------------------------------------------------------------------------------
6259
6260#Method virtual bool isClipRect() const
Cary Clark78de7512018-02-07 07:27:09 -05006261#In Property
Cary Clarkab2621d2018-01-30 10:08:57 -05006262#Line # returns if Clip is Rect and not empty ##
Cary Clark8032b982017-07-28 11:04:54 -04006263Returns true if Clip is Rect and not empty.
6264Returns false if the clip is empty, or if it is not Rect.
6265
Cary Clarkbad5ad72017-08-03 17:14:08 -04006266#Return true if Clip is Rect and not empty ##
Cary Clark8032b982017-07-28 11:04:54 -04006267
6268#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04006269 void draw(SkCanvas* canvas) {
6270 SkDebugf("clip is%s rect\n", canvas->isClipRect() ? "" : " not");
6271 canvas->clipRect({0, 0, 0, 0});
6272 SkDebugf("clip is%s rect\n", canvas->isClipRect() ? "" : " not");
Cary Clark8032b982017-07-28 11:04:54 -04006273 }
6274 #StdOut
Cary Clarkbad5ad72017-08-03 17:14:08 -04006275 clip is rect
Cary Clark8032b982017-07-28 11:04:54 -04006276 clip is not rect
6277 ##
6278##
6279
Cary Clark2ade9972017-11-02 17:49:34 -04006280#SeeAlso isClipEmpty getLocalClipBounds getDeviceClipBounds
Cary Clark8032b982017-07-28 11:04:54 -04006281
6282##
6283
6284#Class SkCanvas ##
Cary Clark884dd7d2017-10-11 10:37:52 -04006285
Cary Clark8032b982017-07-28 11:04:54 -04006286#Topic Canvas ##