blob: e91aee56dabb24bba8008e23114e6f9a7e03195c [file] [log] [blame]
Cary Clark8032b982017-07-28 11:04:54 -04001#Topic Canvas
Cary Clark137b8742018-05-30 09:21:49 -04002#Alias Canvas_Reference ##
Cary Clark8032b982017-07-28 11:04:54 -04003
Cary Clarke4aa3712017-09-15 02:56:12 -04004#Class SkCanvas
5
Cary Clark8032b982017-07-28 11:04:54 -04006Canvas provides an interface for drawing, and how the drawing is clipped and transformed.
7Canvas contains a stack of Matrix and Clip values.
8
9Canvas and Paint together provide the state to draw into Surface or Device.
Cary Clarkbad5ad72017-08-03 17:14:08 -040010Each Canvas draw call transforms the geometry of the object by the concatenation of all
11Matrix values in the stack. The transformed geometry is clipped by the intersection
12of all of Clip values in the stack. The Canvas draw calls use Paint to supply drawing
13state such as Color, Typeface, text size, stroke width, Shader and so on.
Cary Clark8032b982017-07-28 11:04:54 -040014
Herb Derbyefe39bc2018-05-01 17:06:20 -040015To draw to a pixel-based destination, create Raster_Surface or GPU_Surface.
16Request Canvas from Surface to obtain the interface to draw.
17Canvas generated by Raster_Surface draws to memory visible to the CPU.
Cary Clark8032b982017-07-28 11:04:54 -040018Canvas generated by GPU_Surface uses Vulkan or OpenGL to draw to the GPU.
19
Cary Clarkbad5ad72017-08-03 17:14:08 -040020To draw to a document, obtain Canvas from SVG_Canvas, Document_PDF, or Picture_Recorder.
Cary Clarkce101242017-09-01 15:51:02 -040021Document based Canvas and other Canvas Subclasses reference Device describing the
Cary Clarkbad5ad72017-08-03 17:14:08 -040022destination.
23
Cary Clark8032b982017-07-28 11:04:54 -040024Canvas can be constructed to draw to Bitmap without first creating Raster_Surface.
Herb Derbyefe39bc2018-05-01 17:06:20 -040025This approach may be deprecated in the future.
Cary Clark8032b982017-07-28 11:04:54 -040026
Cary Clark682c58d2018-05-16 07:07:07 -040027#Subtopic Overview
28#Populate
29##
30
Cary Clark4855f782018-02-06 09:41:53 -050031#Subtopic Related_Function
Cary Clark08895c42018-02-01 09:37:32 -050032#Populate
33##
Cary Clark8032b982017-07-28 11:04:54 -040034
Cary Clark4855f782018-02-06 09:41:53 -050035#Subtopic Constant
Cary Clark08895c42018-02-01 09:37:32 -050036#Populate
37##
Cary Clark8032b982017-07-28 11:04:54 -040038
Cary Clark682c58d2018-05-16 07:07:07 -040039#Subtopic Struct
40#Populate
41##
42
43#Subtopic Typedef
Cary Clark08895c42018-02-01 09:37:32 -050044#Populate
45##
Cary Clark8032b982017-07-28 11:04:54 -040046
Cary Clark4855f782018-02-06 09:41:53 -050047#Subtopic Constructor
Cary Clark8032b982017-07-28 11:04:54 -040048
Cary Clark4855f782018-02-06 09:41:53 -050049Create the desired type of Surface to obtain its Canvas when possible. Useful
Cary Clark8032b982017-07-28 11:04:54 -040050when no Surface is required, and some helpers implicitly create Raster_Surface.
51
Cary Clark08895c42018-02-01 09:37:32 -050052#Populate
53##
Cary Clark8032b982017-07-28 11:04:54 -040054
Cary Clark4855f782018-02-06 09:41:53 -050055#Subtopic Member_Function
Cary Clark08895c42018-02-01 09:37:32 -050056#Populate
57##
Cary Clark8032b982017-07-28 11:04:54 -040058
59# ------------------------------------------------------------------------------
60
Cary Clarka560c472017-11-27 10:44:06 -050061#Method static std::unique_ptr<SkCanvas> MakeRasterDirect(const SkImageInfo& info, void* pixels,
62 size_t rowBytes,
63 const SkSurfaceProps* props = nullptr)
Cary Clark78de7512018-02-07 07:27:09 -050064#In Constructor
Cary Clarkab2621d2018-01-30 10:08:57 -050065#Line # creates from SkImageInfo and Pixel_Storage ##
Cary Clark8032b982017-07-28 11:04:54 -040066
Cary Clarkbad5ad72017-08-03 17:14:08 -040067Allocates raster Canvas that will draw directly into pixels.
Cary Clark8032b982017-07-28 11:04:54 -040068
Cary Clarkbad5ad72017-08-03 17:14:08 -040069Canvas is returned if all parameters are valid.
70Valid parameters include:
71info dimensions are zero or positive;
Cary Clark2dc84ad2018-01-26 12:56:22 -050072info contains Color_Type and Alpha_Type supported by Raster_Surface;
Cary Clarkbad5ad72017-08-03 17:14:08 -040073pixels is not nullptr;
Cary Clark2dc84ad2018-01-26 12:56:22 -050074rowBytes is zero or large enough to contain info width pixels of Color_Type.
Cary Clarkbad5ad72017-08-03 17:14:08 -040075
Herb Derbyefe39bc2018-05-01 17:06:20 -040076Pass zero for rowBytes to compute rowBytes from info width and size of pixel.
Cary Clarkf05bdda2017-08-24 12:59:48 -040077If rowBytes is greater than zero, it must be equal to or greater than
Cary Clark2dc84ad2018-01-26 12:56:22 -050078info width times bytes required for Color_Type.
Cary Clarkf05bdda2017-08-24 12:59:48 -040079
80Pixel buffer size should be info height times computed rowBytes.
Cary Clarka560c472017-11-27 10:44:06 -050081Pixels are not initialized.
82To access pixels after drawing, call flush() or peekPixels.
Cary Clarkbad5ad72017-08-03 17:14:08 -040083
Cary Clark2dc84ad2018-01-26 12:56:22 -050084#Param info width, height, Color_Type, Alpha_Type, Color_Space, of Raster_Surface;
Cary Clarkbad5ad72017-08-03 17:14:08 -040085 width, or height, or both, may be zero
Cary Clark8032b982017-07-28 11:04:54 -040086##
Cary Clarkf05bdda2017-08-24 12:59:48 -040087#Param pixels pointer to destination pixels buffer
Cary Clark8032b982017-07-28 11:04:54 -040088##
Cary Clarkf05bdda2017-08-24 12:59:48 -040089#Param rowBytes interval from one Surface row to the next, or zero
Cary Clark8032b982017-07-28 11:04:54 -040090##
Cary Clarka560c472017-11-27 10:44:06 -050091#Param props LCD striping orientation and setting for device independent fonts;
92 may be nullptr
93##
Cary Clark8032b982017-07-28 11:04:54 -040094
Cary Clarkbad5ad72017-08-03 17:14:08 -040095#Return Canvas if all parameters are valid; otherwise, nullptr ##
Cary Clark8032b982017-07-28 11:04:54 -040096
97#Example
98 #Description
99 Allocates a three by three bitmap, clears it to white, and draws a black pixel
100 in the center.
101 ##
Cary Clarkbad5ad72017-08-03 17:14:08 -0400102void draw(SkCanvas* ) {
Cary Clarkce101242017-09-01 15:51:02 -0400103 SkImageInfo info = SkImageInfo::MakeN32Premul(3, 3); // device aligned, 32 bpp, Premultiplied
Cary Clarkbad5ad72017-08-03 17:14:08 -0400104 const size_t minRowBytes = info.minRowBytes(); // bytes used by one bitmap row
Cary Clarka560c472017-11-27 10:44:06 -0500105 const size_t size = info.computeMinByteSize(); // bytes used by all rows
Cary Clarkbad5ad72017-08-03 17:14:08 -0400106 SkAutoTMalloc<SkPMColor> storage(size); // allocate storage for pixels
107 SkPMColor* pixels = storage.get(); // get pointer to allocated storage
108 // create a SkCanvas backed by a raster device, and delete it when the
109 // function goes out of scope.
110 std::unique_ptr<SkCanvas> canvas = SkCanvas::MakeRasterDirect(info, pixels, minRowBytes);
Cary Clarkce101242017-09-01 15:51:02 -0400111 canvas->clear(SK_ColorWHITE); // white is Unpremultiplied, in ARGB order
Cary Clarkbad5ad72017-08-03 17:14:08 -0400112 canvas->flush(); // ensure that pixels are cleared
Cary Clarkce101242017-09-01 15:51:02 -0400113 SkPMColor pmWhite = pixels[0]; // the Premultiplied format may vary
Cary Clarkbad5ad72017-08-03 17:14:08 -0400114 SkPaint paint; // by default, draws black
115 canvas->drawPoint(1, 1, paint); // draw in the center
116 canvas->flush(); // ensure that point was drawn
117 for (int y = 0; y < info.height(); ++y) {
118 for (int x = 0; x < info.width(); ++x) {
119 SkDebugf("%c", *pixels++ == pmWhite ? '-' : 'x');
120 }
121 SkDebugf("\n");
122 }
Cary Clark8032b982017-07-28 11:04:54 -0400123}
124 #StdOut
125 ---
126 -x-
127 ---
128 ##
129##
130
Cary Clark8032b982017-07-28 11:04:54 -0400131#SeeAlso MakeRasterDirectN32 SkSurface::MakeRasterDirect
Cary Clark2ade9972017-11-02 17:49:34 -0400132
Cary Clark8032b982017-07-28 11:04:54 -0400133##
134
135# ------------------------------------------------------------------------------
136
137#Method static std::unique_ptr<SkCanvas> MakeRasterDirectN32(int width, int height, SkPMColor* pixels,
Herb Derbyefe39bc2018-05-01 17:06:20 -0400138 size_t rowBytes)
Cary Clark78de7512018-02-07 07:27:09 -0500139#In Constructor
Cary Clarkab2621d2018-01-30 10:08:57 -0500140#Line # creates from image data and Pixel_Storage ##
Cary Clark8032b982017-07-28 11:04:54 -0400141
Cary Clarkbad5ad72017-08-03 17:14:08 -0400142Allocates raster Canvas specified by inline image specification. Subsequent Canvas
143calls draw into pixels.
Cary Clark2dc84ad2018-01-26 12:56:22 -0500144Color_Type is set to kN32_SkColorType.
145Alpha_Type is set to kPremul_SkAlphaType.
Cary Clark8032b982017-07-28 11:04:54 -0400146To access pixels after drawing, call flush() or peekPixels.
147
Cary Clarkbad5ad72017-08-03 17:14:08 -0400148Canvas is returned if all parameters are valid.
149Valid parameters include:
Cary Clarkf05bdda2017-08-24 12:59:48 -0400150width and height are zero or positive;
Cary Clarkbad5ad72017-08-03 17:14:08 -0400151pixels is not nullptr;
Cary Clarkf05bdda2017-08-24 12:59:48 -0400152rowBytes is zero or large enough to contain width pixels of kN32_SkColorType.
Cary Clarkbad5ad72017-08-03 17:14:08 -0400153
Herb Derbyefe39bc2018-05-01 17:06:20 -0400154Pass zero for rowBytes to compute rowBytes from width and size of pixel.
Cary Clarkf05bdda2017-08-24 12:59:48 -0400155If rowBytes is greater than zero, it must be equal to or greater than
Cary Clark2dc84ad2018-01-26 12:56:22 -0500156width times bytes required for Color_Type.
Cary Clarkf05bdda2017-08-24 12:59:48 -0400157
158Pixel buffer size should be height times rowBytes.
Cary Clarkbad5ad72017-08-03 17:14:08 -0400159
160#Param width pixel column count on Raster_Surface created; must be zero or greater ##
Cary Clarkbc5697d2017-10-04 14:31:33 -0400161#Param height pixel row count on Raster_Surface created; must be zero or greater ##
Cary Clarkbad5ad72017-08-03 17:14:08 -0400162#Param pixels pointer to destination pixels buffer; buffer size should be height
Cary Clarkf05bdda2017-08-24 12:59:48 -0400163 times rowBytes
Cary Clark8032b982017-07-28 11:04:54 -0400164##
Cary Clarkf05bdda2017-08-24 12:59:48 -0400165#Param rowBytes interval from one Surface row to the next, or zero
Cary Clark8032b982017-07-28 11:04:54 -0400166##
167
Cary Clarkbad5ad72017-08-03 17:14:08 -0400168#Return Canvas if all parameters are valid; otherwise, nullptr ##
Cary Clark8032b982017-07-28 11:04:54 -0400169
170#Example
171 #Description
172 Allocates a three by three bitmap, clears it to white, and draws a black pixel
173 in the center.
174 ##
175void draw(SkCanvas* ) {
176 const int width = 3;
177 const int height = 3;
Cary Clarkce101242017-09-01 15:51:02 -0400178 SkPMColor pixels[height][width]; // allocate a 3x3 Premultiplied bitmap on the stack
Cary Clark8032b982017-07-28 11:04:54 -0400179 // create a SkCanvas backed by a raster device, and delete it when the
180 // function goes out of scope.
181 std::unique_ptr<SkCanvas> canvas = SkCanvas::MakeRasterDirectN32(
182 width,
183 height,
Cary Clarkbc5697d2017-10-04 14:31:33 -0400184 pixels[0], // top-left of the bitmap
Cary Clark8032b982017-07-28 11:04:54 -0400185 sizeof(pixels[0])); // byte width of the each row
Cary Clark682c58d2018-05-16 07:07:07 -0400186 // write a Premultiplied value for white into all pixels in the bitmap
Cary Clark8032b982017-07-28 11:04:54 -0400187 canvas->clear(SK_ColorWHITE);
Cary Clarkce101242017-09-01 15:51:02 -0400188 SkPMColor pmWhite = pixels[0][0]; // the Premultiplied format may vary
Cary Clark8032b982017-07-28 11:04:54 -0400189 SkPaint paint; // by default, draws black
190 canvas->drawPoint(1, 1, paint); // draw in the center
191 canvas->flush(); // ensure that pixels is ready to be read
192 for (int y = 0; y < height; ++y) {
193 for (int x = 0; x < width; ++x) {
194 SkDebugf("%c", pixels[y][x] == pmWhite ? '-' : 'x');
195 }
196 SkDebugf("\n");
197 }
198}
199 #StdOut
200 ---
201 -x-
202 ---
203 ##
204##
205
Cary Clark2ade9972017-11-02 17:49:34 -0400206#SeeAlso MakeRasterDirect SkSurface::MakeRasterDirect SkImageInfo::MakeN32Premul
Cary Clark8032b982017-07-28 11:04:54 -0400207
208##
209
210# ------------------------------------------------------------------------------
211
212#Method SkCanvas()
213
Cary Clarkab2621d2018-01-30 10:08:57 -0500214#Line # creates with no Surface, no dimensions ##
Herb Derbyefe39bc2018-05-01 17:06:20 -0400215Creates an empty Canvas with no backing device or pixels, with
Cary Clarkf05bdda2017-08-24 12:59:48 -0400216a width and height of zero.
Cary Clark8032b982017-07-28 11:04:54 -0400217
Cary Clarkd0530ba2017-09-14 11:25:39 -0400218#Return empty Canvas ##
Cary Clark8032b982017-07-28 11:04:54 -0400219
220#Example
221
222#Description
223Passes a placeholder to a function that requires one.
224##
225
226#Function
Cary Clarkbad5ad72017-08-03 17:14:08 -0400227// Returns true if either the canvas rotates the text by 90 degrees, or the paint does.
228static void check_for_up_and_down_text(const SkCanvas* canvas, const SkPaint& paint) {
229 bool paintHasVertical = paint.isVerticalText();
230 const SkMatrix& matrix = canvas->getTotalMatrix();
231 bool matrixIsVertical = matrix.preservesRightAngles() && !matrix.isScaleTranslate();
232 SkDebugf("paint draws text %s\n", paintHasVertical != matrixIsVertical ?
233 "top to bottom" : "left to right");
234}
235
236static void check_for_up_and_down_text(const SkPaint& paint) {
237 SkCanvas canvas; // placeholder only, does not have an associated device
238 check_for_up_and_down_text(&canvas, paint);
239}
240
Cary Clark8032b982017-07-28 11:04:54 -0400241##
Cary Clarkbad5ad72017-08-03 17:14:08 -0400242void draw(SkCanvas* canvas) {
243 SkPaint paint;
244 check_for_up_and_down_text(paint); // paint draws text left to right
245 paint.setVerticalText(true);
246 check_for_up_and_down_text(paint); // paint draws text top to bottom
247 paint.setVerticalText(false);
248 canvas->rotate(90);
249 check_for_up_and_down_text(canvas, paint); // paint draws text top to bottom
250}
Cary Clark8032b982017-07-28 11:04:54 -0400251
252 #StdOut
253 paint draws text left to right
254 paint draws text top to bottom
255 paint draws text top to bottom
256 ##
257##
258
Cary Clark2ade9972017-11-02 17:49:34 -0400259#SeeAlso MakeRasterDirect SkRasterHandleAllocator::MakeCanvas SkSurface::getCanvas SkCreateColorSpaceXformCanvas
Cary Clark8032b982017-07-28 11:04:54 -0400260
261##
262
263# ------------------------------------------------------------------------------
264
Cary Clark73fa9722017-08-29 17:36:51 -0400265#Method SkCanvas(int width, int height, const SkSurfaceProps* props = nullptr)
Cary Clark8032b982017-07-28 11:04:54 -0400266
Cary Clark682c58d2018-05-16 07:07:07 -0400267#Line # creates with no Surface, set dimensions, Surface_Properties ##
Cary Clark8032b982017-07-28 11:04:54 -0400268Creates Canvas of the specified dimensions without a Surface.
Cary Clark682c58d2018-05-16 07:07:07 -0400269Used by Subclasses with custom implementations for draw member functions.
Cary Clark8032b982017-07-28 11:04:54 -0400270
Cary Clarkd0530ba2017-09-14 11:25:39 -0400271If props equals nullptr, Surface_Properties are created with
Herb Derbyefe39bc2018-05-01 17:06:20 -0400272Surface_Properties_Legacy_Font_Host settings, which choose the pixel striping
Cary Clarkd0530ba2017-09-14 11:25:39 -0400273direction and order. Since a platform may dynamically change its direction when
274the device is rotated, and since a platform may have multiple monitors with
275different characteristics, it is best not to rely on this legacy behavior.
Cary Clark8032b982017-07-28 11:04:54 -0400276
Cary Clarkbad5ad72017-08-03 17:14:08 -0400277#Param width zero or greater ##
278#Param height zero or greater ##
279#Param props LCD striping orientation and setting for device independent fonts;
280 may be nullptr
281##
282
283#Return Canvas placeholder with dimensions ##
Cary Clark8032b982017-07-28 11:04:54 -0400284
285#Example
286 SkCanvas canvas(10, 20); // 10 units wide, 20 units high
287 canvas.clipRect(SkRect::MakeXYWH(30, 40, 5, 10)); // clip is outside canvas' device
288 SkDebugf("canvas %s empty\n", canvas.getDeviceClipBounds().isEmpty() ? "is" : "is not");
289
290 #StdOut
291 canvas is empty
292 ##
293##
294
Cary Clark2ade9972017-11-02 17:49:34 -0400295#SeeAlso MakeRasterDirect SkSurfaceProps SkPixelGeometry SkCreateColorSpaceXformCanvas
Cary Clark8032b982017-07-28 11:04:54 -0400296
297##
298
299# ------------------------------------------------------------------------------
300
Herb Derbyefe39bc2018-05-01 17:06:20 -0400301#Method explicit SkCanvas(sk_sp<SkBaseDevice> device)
Cary Clark4855f782018-02-06 09:41:53 -0500302#Deprecated soon
Cary Clark8032b982017-07-28 11:04:54 -0400303##
304
305# ------------------------------------------------------------------------------
306
307#Method explicit SkCanvas(const SkBitmap& bitmap)
308
Cary Clarkab2621d2018-01-30 10:08:57 -0500309#Line # uses existing Bitmap ##
Cary Clark80247e52018-07-11 16:18:41 -0400310Constructs a canvas that draws into bitmap.
Herb Derbyefe39bc2018-05-01 17:06:20 -0400311Sets SkSurfaceProps::kLegacyFontHost_InitType in constructed Surface.
Cary Clark8032b982017-07-28 11:04:54 -0400312
Cary Clarkbad5ad72017-08-03 17:14:08 -0400313Bitmap is copied so that subsequently editing bitmap will not affect
314constructed Canvas.
315
316May be deprecated in the future.
317
Cary Clark8032b982017-07-28 11:04:54 -0400318#ToDo Should be deprecated? ##
319
Cary Clark2dc84ad2018-01-26 12:56:22 -0500320#Param bitmap width, height, Color_Type, Alpha_Type, and pixel
Cary Clarkbad5ad72017-08-03 17:14:08 -0400321 storage of Raster_Surface
Cary Clark8032b982017-07-28 11:04:54 -0400322##
323
Cary Clarkbad5ad72017-08-03 17:14:08 -0400324#Return Canvas that can be used to draw into bitmap ##
Cary Clark8032b982017-07-28 11:04:54 -0400325
326#Example
327#Description
328The actual output depends on the installed fonts.
329##
330 SkBitmap bitmap;
331 // create a bitmap 5 wide and 11 high
332 bitmap.allocPixels(SkImageInfo::MakeN32Premul(5, 11));
333 SkCanvas canvas(bitmap);
Cary Clarkce101242017-09-01 15:51:02 -0400334 canvas.clear(SK_ColorWHITE); // white is Unpremultiplied, in ARGB order
Cary Clark8032b982017-07-28 11:04:54 -0400335 SkPixmap pixmap; // provides guaranteed access to the drawn pixels
336 if (!canvas.peekPixels(&pixmap)) {
337 SkDebugf("peekPixels should never fail.\n");
338 }
Cary Clarkbc5697d2017-10-04 14:31:33 -0400339 const SkPMColor* pixels = pixmap.addr32(); // points to top-left of bitmap
Cary Clarkce101242017-09-01 15:51:02 -0400340 SkPMColor pmWhite = pixels[0]; // the Premultiplied format may vary
Cary Clark8032b982017-07-28 11:04:54 -0400341 SkPaint paint; // by default, draws black, 12 point text
342 canvas.drawString("!", 1, 10, paint); // 1 char at baseline (1, 10)
343 for (int y = 0; y < bitmap.height(); ++y) {
344 for (int x = 0; x < bitmap.width(); ++x) {
345 SkDebugf("%c", *pixels++ == pmWhite ? '-' : 'x');
346 }
347 SkDebugf("\n");
348 }
349
350 #StdOut
Cary Clarkd0530ba2017-09-14 11:25:39 -0400351 -----
352 ---x-
353 ---x-
354 ---x-
355 ---x-
356 ---x-
357 ---x-
358 -----
359 ---x-
360 ---x-
Cary Clark8032b982017-07-28 11:04:54 -0400361 -----
362 #StdOut ##
363##
364
Cary Clark2ade9972017-11-02 17:49:34 -0400365#SeeAlso MakeRasterDirect SkRasterHandleAllocator::MakeCanvas SkSurface::getCanvas SkCreateColorSpaceXformCanvas
Cary Clark8032b982017-07-28 11:04:54 -0400366
367##
368
Cary Clarkbad5ad72017-08-03 17:14:08 -0400369#EnumClass ColorBehavior
Cary Clark682c58d2018-05-16 07:07:07 -0400370#Line # exists for Android framework only ##
Cary Clark8032b982017-07-28 11:04:54 -0400371#Private
372Android framework only.
373##
374
375#Code
376 enum class ColorBehavior {
377 kLegacy,
378 };
379##
380#Const kLegacy 0
Cary Clark682c58d2018-05-16 07:07:07 -0400381#Line # placeholder ##
Cary Clarkbad5ad72017-08-03 17:14:08 -0400382 Is a placeholder to allow specialized constructor; has no meaning.
Cary Clark8032b982017-07-28 11:04:54 -0400383##
384##
385
Cary Clarkbad5ad72017-08-03 17:14:08 -0400386#Method SkCanvas(const SkBitmap& bitmap, ColorBehavior behavior)
387
Cary Clark682c58d2018-05-16 07:07:07 -0400388#Line # exists for Android framework only ##
389
Cary Clark80247e52018-07-11 16:18:41 -0400390For use by Android framework only.
Cary Clarkbad5ad72017-08-03 17:14:08 -0400391
392#Param bitmap specifies a bitmap for the canvas to draw into ##
393#Param behavior specializes this constructor; value is unused ##
394#Return Canvas that can be used to draw into bitmap ##
395
396#NoExample
397##
398##
Cary Clark8032b982017-07-28 11:04:54 -0400399
400# ------------------------------------------------------------------------------
401
402#Method SkCanvas(const SkBitmap& bitmap, const SkSurfaceProps& props)
403
Cary Clarkab2621d2018-01-30 10:08:57 -0500404#Line # uses existing Bitmap and Surface_Properties ##
Cary Clark80247e52018-07-11 16:18:41 -0400405Constructs a canvas that draws into bitmap.
Cary Clark8032b982017-07-28 11:04:54 -0400406Use props to match the device characteristics, like LCD striping.
407
Cary Clarkbad5ad72017-08-03 17:14:08 -0400408bitmap is copied so that subsequently editing bitmap will not affect
409constructed Canvas.
410
Cary Clark2dc84ad2018-01-26 12:56:22 -0500411#Param bitmap width, height, Color_Type, Alpha_Type,
Herb Derbyefe39bc2018-05-01 17:06:20 -0400412 and pixel storage of Raster_Surface
Cary Clark8032b982017-07-28 11:04:54 -0400413##
Cary Clarkbad5ad72017-08-03 17:14:08 -0400414#Param props order and orientation of RGB striping; and whether to use
415 device independent fonts
Cary Clark8032b982017-07-28 11:04:54 -0400416##
417
Cary Clarkbad5ad72017-08-03 17:14:08 -0400418#Return Canvas that can be used to draw into bitmap ##
Cary Clark8032b982017-07-28 11:04:54 -0400419
420#Example
421#Description
422The actual output depends on the installed fonts.
423##
424 SkBitmap bitmap;
425 // create a bitmap 5 wide and 11 high
426 bitmap.allocPixels(SkImageInfo::MakeN32Premul(5, 11));
427 SkCanvas canvas(bitmap, SkSurfaceProps(0, kUnknown_SkPixelGeometry));
Cary Clarkce101242017-09-01 15:51:02 -0400428 canvas.clear(SK_ColorWHITE); // white is Unpremultiplied, in ARGB order
Cary Clark8032b982017-07-28 11:04:54 -0400429 SkPixmap pixmap; // provides guaranteed access to the drawn pixels
430 if (!canvas.peekPixels(&pixmap)) {
431 SkDebugf("peekPixels should never fail.\n");
432 }
Cary Clarkbc5697d2017-10-04 14:31:33 -0400433 const SkPMColor* pixels = pixmap.addr32(); // points to top-left of bitmap
Cary Clarkce101242017-09-01 15:51:02 -0400434 SkPMColor pmWhite = pixels[0]; // the Premultiplied format may vary
Cary Clark8032b982017-07-28 11:04:54 -0400435 SkPaint paint; // by default, draws black, 12 point text
436 canvas.drawString("!", 1, 10, paint); // 1 char at baseline (1, 10)
437 for (int y = 0; y < bitmap.height(); ++y) {
438 for (int x = 0; x < bitmap.width(); ++x) {
439 SkDebugf("%c", *pixels++ == pmWhite ? '-' : 'x');
440 }
441 SkDebugf("\n");
442 }
443
444 #StdOut
445 -----
446 ---x-
447 ---x-
448 ---x-
449 ---x-
450 ---x-
451 ---x-
452 -----
453 ---x-
454 ---x-
455 -----
456 #StdOut ##
457##
458
Cary Clark2ade9972017-11-02 17:49:34 -0400459#SeeAlso MakeRasterDirect SkRasterHandleAllocator::MakeCanvas SkSurface::getCanvas SkCreateColorSpaceXformCanvas
Cary Clark8032b982017-07-28 11:04:54 -0400460
461##
462
463# ------------------------------------------------------------------------------
464
465#Method virtual ~SkCanvas()
466
Cary Clarkab2621d2018-01-30 10:08:57 -0500467#Line # draws saved Layers, frees resources ##
Cary Clark5081eed2018-01-22 07:55:48 -0500468Draws saved Layers, if any.
469Frees up resources used by Canvas.
Cary Clark8032b982017-07-28 11:04:54 -0400470
471#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -0400472#Description
Cary Clarkce101242017-09-01 15:51:02 -0400473Canvas Layer draws into bitmap. saveLayerAlpha sets up an additional
474drawing surface that blends with the bitmap. When Layer goes out of
475scope, Layer Destructor is called. The saved Layer is restored, drawing
Cary Clarkbad5ad72017-08-03 17:14:08 -0400476transparent letters.
477##
Cary Clarkf05bdda2017-08-24 12:59:48 -0400478void draw(SkCanvas* canvas) {
479 SkBitmap bitmap;
480 bitmap.allocPixels(SkImageInfo::MakeN32Premul(200, 200));
481 {
482 SkCanvas offscreen(bitmap);
483 SkPaint paint;
484 paint.setTextSize(100);
485 offscreen.drawString("ABC", 20, 160, paint);
486 SkRect layerBounds = SkRect::MakeXYWH(32, 32, 192, 192);
487 offscreen.saveLayerAlpha(&layerBounds, 128);
488 offscreen.clear(SK_ColorWHITE);
489 offscreen.drawString("DEF", 20, 160, paint);
490 }
491 canvas->drawBitmap(bitmap, 0, 0, nullptr);
Cary Clarkbad5ad72017-08-03 17:14:08 -0400492}
Cary Clark8032b982017-07-28 11:04:54 -0400493##
494
Cary Clarkbad5ad72017-08-03 17:14:08 -0400495#SeeAlso State_Stack
Cary Clark8032b982017-07-28 11:04:54 -0400496
497##
498
499# ------------------------------------------------------------------------------
Cary Clark78de7512018-02-07 07:27:09 -0500500#Subtopic Property
501#Populate
502#Line # metrics and attributes ##
503##
Cary Clark8032b982017-07-28 11:04:54 -0400504
505#Method SkMetaData& getMetaData()
Cary Clark78de7512018-02-07 07:27:09 -0500506#In Property
507#In Utility
Cary Clarkab2621d2018-01-30 10:08:57 -0500508#Line # associates additional data with the canvas ##
Cary Clarkf05bdda2017-08-24 12:59:48 -0400509Returns storage to associate additional data with the canvas.
Cary Clark8032b982017-07-28 11:04:54 -0400510The storage is freed when Canvas is deleted.
511
Cary Clarkbad5ad72017-08-03 17:14:08 -0400512#Return storage that can be read from and written to ##
Cary Clark8032b982017-07-28 11:04:54 -0400513
514#Example
515 const char* kHelloMetaData = "HelloMetaData";
516 SkCanvas canvas;
517 SkMetaData& metaData = canvas.getMetaData();
518 SkDebugf("before: %s\n", metaData.findString(kHelloMetaData));
519 metaData.setString(kHelloMetaData, "Hello!");
520 SkDebugf("during: %s\n", metaData.findString(kHelloMetaData));
521 metaData.removeString(kHelloMetaData);
522 SkDebugf("after: %s\n", metaData.findString(kHelloMetaData));
523
524 #StdOut
525 before: (null)
526 during: Hello!
527 after: (null)
528 #StdOut ##
529##
530
Cary Clark2ade9972017-11-02 17:49:34 -0400531#SeeAlso SkMetaData
Cary Clark8032b982017-07-28 11:04:54 -0400532
533##
534
535# ------------------------------------------------------------------------------
536
537#Method SkImageInfo imageInfo() const
Cary Clark78de7512018-02-07 07:27:09 -0500538#In Property
Cary Clarkab2621d2018-01-30 10:08:57 -0500539#Line # returns Image_Info for Canvas ##
Cary Clark8032b982017-07-28 11:04:54 -0400540Returns Image_Info for Canvas. If Canvas is not associated with Raster_Surface or
Cary Clark2dc84ad2018-01-26 12:56:22 -0500541GPU_Surface, returned Color_Type is set to kUnknown_SkColorType.
Cary Clark8032b982017-07-28 11:04:54 -0400542
Cary Clark2dc84ad2018-01-26 12:56:22 -0500543#Return dimensions and Color_Type of Canvas ##
Cary Clark8032b982017-07-28 11:04:54 -0400544
545#Example
Cary Clarkf05bdda2017-08-24 12:59:48 -0400546 SkCanvas emptyCanvas;
547 SkImageInfo canvasInfo = emptyCanvas.imageInfo();
548 SkImageInfo emptyInfo;
549 SkDebugf("emptyInfo %c= canvasInfo\n", emptyInfo == canvasInfo ? '=' : '!');
550
551 #StdOut
552 emptyInfo == canvasInfo
553 ##
Cary Clark8032b982017-07-28 11:04:54 -0400554##
555
Cary Clark2ade9972017-11-02 17:49:34 -0400556#SeeAlso SkImageInfo MakeRasterDirect makeSurface
Cary Clark8032b982017-07-28 11:04:54 -0400557
558##
559
560# ------------------------------------------------------------------------------
561
562#Method bool getProps(SkSurfaceProps* props) const
Cary Clark78de7512018-02-07 07:27:09 -0500563#In Property
Cary Clarkab2621d2018-01-30 10:08:57 -0500564#Line # copies Surface_Properties if available ##
Cary Clark80247e52018-07-11 16:18:41 -0400565Copies Surface_Properties, if Canvas is associated with Raster_Surface or
566GPU_Surface, and returns true. Otherwise, returns false and leave props unchanged.
Cary Clark8032b982017-07-28 11:04:54 -0400567
Cary Clarkbad5ad72017-08-03 17:14:08 -0400568#Param props storage for writable SkSurfaceProps ##
Cary Clark8032b982017-07-28 11:04:54 -0400569
Cary Clarkbad5ad72017-08-03 17:14:08 -0400570#Return true if Surface_Properties was copied ##
Cary Clark8032b982017-07-28 11:04:54 -0400571
572#ToDo This seems old style. Deprecate? ##
573
574#Example
575 SkBitmap bitmap;
576 SkCanvas canvas(bitmap, SkSurfaceProps(0, kRGB_V_SkPixelGeometry));
577 SkSurfaceProps surfaceProps(0, kUnknown_SkPixelGeometry);
578 SkDebugf("isRGB:%d\n", SkPixelGeometryIsRGB(surfaceProps.pixelGeometry()));
579 if (!canvas.getProps(&surfaceProps)) {
580 SkDebugf("getProps failed unexpectedly.\n");
581 }
582 SkDebugf("isRGB:%d\n", SkPixelGeometryIsRGB(surfaceProps.pixelGeometry()));
583
584 #StdOut
585 isRGB:0
586 isRGB:1
587 #StdOut ##
588##
589
Cary Clark2ade9972017-11-02 17:49:34 -0400590#SeeAlso SkSurfaceProps makeSurface
Cary Clark8032b982017-07-28 11:04:54 -0400591
592##
593
594# ------------------------------------------------------------------------------
Cary Clark78de7512018-02-07 07:27:09 -0500595#Subtopic Utility
596#Populate
597#Line # rarely called management functions ##
598##
Cary Clark8032b982017-07-28 11:04:54 -0400599
600#Method void flush()
Cary Clark78de7512018-02-07 07:27:09 -0500601#In Utility
Cary Clarkab2621d2018-01-30 10:08:57 -0500602#Line # triggers execution of all pending draw operations ##
Herb Derbyefe39bc2018-05-01 17:06:20 -0400603Triggers the immediate execution of all pending draw operations.
Cary Clarkbad5ad72017-08-03 17:14:08 -0400604If Canvas is associated with GPU_Surface, resolves all pending GPU operations.
Cary Clark2ade9972017-11-02 17:49:34 -0400605If Canvas is associated with Raster_Surface, has no effect; raster draw
606operations are never deferred.
607
608#ToDo
609In an overview section on managing the GPU, include:
610- flush should never change what is drawn
611- call to kick off gpu work
612- calling too much impacts performance
613- some calls (peekPixels, prepareForExternalIO) call it internally
614- canvas call is local, GrContext::flush is global
615- diffentiate between flush, flushAndSignalSemaphores
616- normally never needs to be called
617- call it when sharing gpu resources, feeling memory pressure, swapping out app, and before
618 abandoning context
619- also call to say "I'm finished drawing here", e.g., when drawing to a GPU-backed offscreen surface
620 (created with SkSurface::MakeRenderTarget)
621
622for posterity: this doesn't show a difference: fiddle.skia.org/c/@flushfail
623##
Cary Clark8032b982017-07-28 11:04:54 -0400624
Cary Clark08895c42018-02-01 09:37:32 -0500625#ToDo haven't thought of a useful example to put here ##
626#NoExample
Cary Clark8032b982017-07-28 11:04:54 -0400627##
628
Cary Clark2ade9972017-11-02 17:49:34 -0400629#SeeAlso peekPixels SkSurface::flush() GrContext::flush() SkSurface::prepareForExternalIO GrContext::abandonContext()
Cary Clark8032b982017-07-28 11:04:54 -0400630
631##
632
633# ------------------------------------------------------------------------------
634
635#Method virtual SkISize getBaseLayerSize() const
Cary Clark78de7512018-02-07 07:27:09 -0500636#In Property
Cary Clarkab2621d2018-01-30 10:08:57 -0500637#Line # returns size of base Layer in global coordinates ##
Cary Clarkce101242017-09-01 15:51:02 -0400638Gets the size of the base or root Layer in global canvas coordinates. The
639origin of the base Layer is always (0,0). The area available for drawing may be
Cary Clark8032b982017-07-28 11:04:54 -0400640smaller (due to clipping or saveLayer).
641
Cary Clarkce101242017-09-01 15:51:02 -0400642#Return integral width and height of base Layer ##
Cary Clark8032b982017-07-28 11:04:54 -0400643
644#Example
645 SkBitmap bitmap;
646 bitmap.allocPixels(SkImageInfo::MakeN32Premul(20, 30));
647 SkCanvas canvas(bitmap, SkSurfaceProps(0, kUnknown_SkPixelGeometry));
648 canvas.clipRect(SkRect::MakeWH(10, 40));
649 SkIRect clipDeviceBounds = canvas.getDeviceClipBounds();
650 if (clipDeviceBounds.isEmpty()) {
651 SkDebugf("Empty clip bounds is unexpected!\n");
652 }
653 SkDebugf("clip=%d,%d\n", clipDeviceBounds.width(), clipDeviceBounds.height());
654 SkISize baseLayerSize = canvas.getBaseLayerSize();
655 SkDebugf("size=%d,%d\n", baseLayerSize.width(), baseLayerSize.height());
656
657 #StdOut
658 clip=10,30
659 size=20,30
660 ##
661##
662
663#ToDo is this the same as the width and height of surface? ##
664
Cary Clark2ade9972017-11-02 17:49:34 -0400665#SeeAlso getDeviceClipBounds
666
Cary Clark8032b982017-07-28 11:04:54 -0400667##
668
669# ------------------------------------------------------------------------------
670
671#Method sk_sp<SkSurface> makeSurface(const SkImageInfo& info, const SkSurfaceProps* props = nullptr)
Cary Clark4855f782018-02-06 09:41:53 -0500672#In Constructor
Cary Clarkab2621d2018-01-30 10:08:57 -0500673#Line # creates Surface matching SkImageInfo and SkSurfaceProps ##
Cary Clark8032b982017-07-28 11:04:54 -0400674Creates Surface matching info and props, and associates it with Canvas.
Cary Clarkbad5ad72017-08-03 17:14:08 -0400675Returns nullptr if no match found.
Cary Clark8032b982017-07-28 11:04:54 -0400676
Cary Clarkbad5ad72017-08-03 17:14:08 -0400677If props is nullptr, matches Surface_Properties in Canvas. If props is nullptr and Canvas
678does not have Surface_Properties, creates Surface with default Surface_Properties.
Cary Clark8032b982017-07-28 11:04:54 -0400679
Cary Clark2dc84ad2018-01-26 12:56:22 -0500680#Param info width, height, Color_Type, Alpha_Type, and Color_Space ##
Cary Clarkbad5ad72017-08-03 17:14:08 -0400681#Param props Surface_Properties to match; may be nullptr to match Canvas ##
682
683#Return Surface matching info and props, or nullptr if no match is available ##
Cary Clark8032b982017-07-28 11:04:54 -0400684
685#Example
686 sk_sp<SkSurface> surface = SkSurface::MakeRasterN32Premul(5, 6);
687 SkCanvas* smallCanvas = surface->getCanvas();
688 SkImageInfo imageInfo = SkImageInfo::MakeN32Premul(3, 4);
689 sk_sp<SkSurface> compatible = smallCanvas->makeSurface(imageInfo);
690 SkDebugf("compatible %c= nullptr\n", compatible == nullptr ? '=' : '!');
691 SkDebugf("size = %d, %d\n", compatible->width(), compatible->height());
692
693 #StdOut
Cary Clarkbad5ad72017-08-03 17:14:08 -0400694 compatible != nullptr
Cary Clark8032b982017-07-28 11:04:54 -0400695 size = 3, 4
696 ##
697##
698
Cary Clark2ade9972017-11-02 17:49:34 -0400699#SeeAlso SkSurface SkSurface::makeSurface SkImageInfo SkSurfaceProps
Cary Clark8032b982017-07-28 11:04:54 -0400700
701##
702
703# ------------------------------------------------------------------------------
704
705#Method virtual GrContext* getGrContext()
Cary Clark78de7512018-02-07 07:27:09 -0500706#In Property
Cary Clarkab2621d2018-01-30 10:08:57 -0500707#Line # returns GPU_Context of the GPU_Surface ##
Cary Clark8032b982017-07-28 11:04:54 -0400708Returns GPU_Context of the GPU_Surface associated with Canvas.
709
Cary Clarkbad5ad72017-08-03 17:14:08 -0400710#Return GPU_Context, if available; nullptr otherwise ##
Cary Clark8032b982017-07-28 11:04:54 -0400711
712#Example
713void draw(SkCanvas* canvas) {
714 if (canvas->getGrContext()) {
715 canvas->clear(SK_ColorRED);
716 } else {
717 canvas->clear(SK_ColorBLUE);
718 }
719}
720##
721
722#ToDo fiddle should show both CPU and GPU out ##
723
Herb Derbyefe39bc2018-05-01 17:06:20 -0400724#SeeAlso GrContext
Cary Clark2ade9972017-11-02 17:49:34 -0400725
Cary Clark8032b982017-07-28 11:04:54 -0400726##
727
728# ------------------------------------------------------------------------------
729
Cary Clark73fa9722017-08-29 17:36:51 -0400730#Method void* accessTopLayerPixels(SkImageInfo* info, size_t* rowBytes, SkIPoint* origin = nullptr)
Cary Clark78de7512018-02-07 07:27:09 -0500731#In Utility
732#In Property
Cary Clarkab2621d2018-01-30 10:08:57 -0500733#Line # returns writable pixel access if available ##
Cary Clark8032b982017-07-28 11:04:54 -0400734Returns the pixel base address, Image_Info, rowBytes, and origin if the pixels
Cary Clarkbad5ad72017-08-03 17:14:08 -0400735can be read directly. The returned address is only valid
Cary Clark8032b982017-07-28 11:04:54 -0400736while Canvas is in scope and unchanged. Any Canvas call or Surface call
737may invalidate the returned address and other returned values.
738
739If pixels are inaccessible, info, rowBytes, and origin are unchanged.
740
Cary Clarkbad5ad72017-08-03 17:14:08 -0400741#Param info storage for writable pixels' Image_Info; may be nullptr ##
742#Param rowBytes storage for writable pixels' row bytes; may be nullptr ##
Cary Clarkbc5697d2017-10-04 14:31:33 -0400743#Param origin storage for Canvas top Layer origin, its top-left corner;
Cary Clarkbad5ad72017-08-03 17:14:08 -0400744 may be nullptr
745##
Cary Clark8032b982017-07-28 11:04:54 -0400746
Cary Clarka523d2d2017-08-30 08:58:10 -0400747#Return address of pixels, or nullptr if inaccessible ##
Cary Clark8032b982017-07-28 11:04:54 -0400748
749#Example
750void draw(SkCanvas* canvas) {
751 if (canvas->accessTopLayerPixels(nullptr, nullptr)) {
752 canvas->clear(SK_ColorRED);
753 } else {
754 canvas->clear(SK_ColorBLUE);
755 }
756}
757##
758
759#Example
760#Description
Cary Clarkce101242017-09-01 15:51:02 -0400761Draws "ABC" on the device. Then draws "DEF" in Layer, and reads
762Layer to add a large dotted "DEF". Finally blends Layer with the
Herb Derbyefe39bc2018-05-01 17:06:20 -0400763device.
Cary Clark8032b982017-07-28 11:04:54 -0400764
Cary Clarkce101242017-09-01 15:51:02 -0400765The Layer and blended result appear on the CPU and GPU but the large dotted
Cary Clark8032b982017-07-28 11:04:54 -0400766"DEF" appear only on the CPU.
767##
768void draw(SkCanvas* canvas) {
Cary Clarkbad5ad72017-08-03 17:14:08 -0400769 SkPaint paint;
770 paint.setTextSize(100);
771 canvas->drawString("ABC", 20, 160, paint);
772 SkRect layerBounds = SkRect::MakeXYWH(32, 32, 192, 192);
773 canvas->saveLayerAlpha(&layerBounds, 128);
774 canvas->clear(SK_ColorWHITE);
775 canvas->drawString("DEF", 20, 160, paint);
776 SkImageInfo imageInfo;
777 size_t rowBytes;
778 SkIPoint origin;
779 uint32_t* access = (uint32_t*) canvas->accessTopLayerPixels(&imageInfo, &rowBytes, &origin);
780 if (access) {
781 int h = imageInfo.height();
782 int v = imageInfo.width();
783 int rowWords = rowBytes / sizeof(uint32_t);
784 for (int y = 0; y < h; ++y) {
785 int newY = (y - h / 2) * 2 + h / 2;
786 if (newY < 0 || newY >= h) {
787 continue;
788 }
789 for (int x = 0; x < v; ++x) {
790 int newX = (x - v / 2) * 2 + v / 2;
791 if (newX < 0 || newX >= v) {
792 continue;
793 }
794 if (access[y * rowWords + x] == SK_ColorBLACK) {
795 access[newY * rowWords + newX] = SK_ColorGRAY;
796 }
797 }
798 }
799
800 }
Cary Clark8032b982017-07-28 11:04:54 -0400801 canvas->restore();
802}
803##
804
805#ToDo there are no callers of this that I can find. Deprecate? ##
806#ToDo fiddle should show both CPU and GPU out ##
807
Cary Clark2ade9972017-11-02 17:49:34 -0400808#SeeAlso SkImageInfo SkPixmap
809
Cary Clark8032b982017-07-28 11:04:54 -0400810##
811
812# ------------------------------------------------------------------------------
813
814#Method SkRasterHandleAllocator::Handle accessTopRasterHandle() const
Cary Clark78de7512018-02-07 07:27:09 -0500815#In Utility
816#In Property
Cary Clarkab2621d2018-01-30 10:08:57 -0500817#Line # returns context that tracks Clip and Matrix ##
Cary Clark8032b982017-07-28 11:04:54 -0400818Returns custom context that tracks the Matrix and Clip.
819
820Use Raster_Handle_Allocator to blend Skia drawing with custom drawing, typically performed
Cary Clarkbc5697d2017-10-04 14:31:33 -0400821by the host platform user interface. The custom context returned is generated by
Cary Clarkbad5ad72017-08-03 17:14:08 -0400822SkRasterHandleAllocator::MakeCanvas, which creates a custom canvas with raster storage for
Cary Clark8032b982017-07-28 11:04:54 -0400823the drawing destination.
824
Cary Clarkce101242017-09-01 15:51:02 -0400825#Return context of custom allocation ##
Cary Clark8032b982017-07-28 11:04:54 -0400826
827#Example
828#Description
829#ToDo ##
830##
831#Function
832 static void DeleteCallback(void*, void* context) {
833 delete (char*) context;
834 }
835
836 class CustomAllocator : public SkRasterHandleAllocator {
837 public:
838 bool allocHandle(const SkImageInfo& info, Rec* rec) override {
839 char* context = new char[4]{'s', 'k', 'i', 'a'};
840 rec->fReleaseProc = DeleteCallback;
841 rec->fReleaseCtx = context;
842 rec->fHandle = context;
843 rec->fPixels = context;
844 rec->fRowBytes = 4;
845 return true;
846 }
847
848 void updateHandle(Handle handle, const SkMatrix& ctm, const SkIRect& clip_bounds) override {
849 // apply canvas matrix and clip to custom environment
850 }
851 };
852
853##
854 void draw(SkCanvas* canvas) {
855 const SkImageInfo info = SkImageInfo::MakeN32Premul(1, 1);
856 std::unique_ptr<SkCanvas> c2 =
857 SkRasterHandleAllocator::MakeCanvas(std::unique_ptr<CustomAllocator>(
858 new CustomAllocator()), info);
859 char* context = (char*) c2->accessTopRasterHandle();
860 SkDebugf("context = %.4s\n", context);
861
862 }
863 #StdOut
864 context = skia
865 ##
866 #ToDo skstd::make_unique could not be used because def is private -- note to fix in c++14? ##
867##
868
869#SeeAlso SkRasterHandleAllocator
870
871##
872
873# ------------------------------------------------------------------------------
Cary Clark78de7512018-02-07 07:27:09 -0500874#Subtopic Pixels
875#Populate
876#Line # read and write pixel values ##
877##
Cary Clark8032b982017-07-28 11:04:54 -0400878
879#Method bool peekPixels(SkPixmap* pixmap)
Cary Clark78de7512018-02-07 07:27:09 -0500880#In Pixels
Cary Clarkab2621d2018-01-30 10:08:57 -0500881#Line # returns if Canvas has direct access to its pixels ##
Cary Clark8032b982017-07-28 11:04:54 -0400882Returns true if Canvas has direct access to its pixels.
883
Cary Clarkf05bdda2017-08-24 12:59:48 -0400884Pixels are readable when Device is raster. Pixels are not readable when Canvas
Cary Clarkbad5ad72017-08-03 17:14:08 -0400885is returned from GPU_Surface, returned by SkDocument::beginPage, returned by
Cary Clarkf05bdda2017-08-24 12:59:48 -0400886SkPictureRecorder::beginRecording, or Canvas is the base of a utility class
Brian Osman46fe9c72018-03-09 15:44:34 -0500887like SkDebugCanvas.
Cary Clark8032b982017-07-28 11:04:54 -0400888
Cary Clarkf05bdda2017-08-24 12:59:48 -0400889pixmap is valid only while Canvas is in scope and unchanged. Any
Cary Clarkbad5ad72017-08-03 17:14:08 -0400890Canvas or Surface call may invalidate the pixmap values.
Cary Clark8032b982017-07-28 11:04:54 -0400891
Cary Clarkbc5697d2017-10-04 14:31:33 -0400892#Param pixmap storage for pixel state if pixels are readable; otherwise, ignored ##
Cary Clark8032b982017-07-28 11:04:54 -0400893
Cary Clarkbad5ad72017-08-03 17:14:08 -0400894#Return true if Canvas has direct access to pixels ##
Cary Clark8032b982017-07-28 11:04:54 -0400895
896#Example
897 SkPixmap pixmap;
898 if (canvas->peekPixels(&pixmap)) {
899 SkDebugf("width=%d height=%d\n", pixmap.bounds().width(), pixmap.bounds().height());
900 }
901 #StdOut
902 width=256 height=256
903 ##
904##
905
Cary Clark2ade9972017-11-02 17:49:34 -0400906#SeeAlso readPixels SkBitmap::peekPixels SkImage::peekPixels SkSurface::peekPixels
907
Cary Clark8032b982017-07-28 11:04:54 -0400908##
909
910# ------------------------------------------------------------------------------
911
912#Method bool readPixels(const SkImageInfo& dstInfo, void* dstPixels, size_t dstRowBytes,
913 int srcX, int srcY)
Cary Clark78de7512018-02-07 07:27:09 -0500914#In Pixels
Cary Clarkab2621d2018-01-30 10:08:57 -0500915#Line # copies and converts rectangle of pixels from Canvas ##
Cary Clark8032b982017-07-28 11:04:54 -0400916
Cary Clark154beea2017-10-26 07:58:48 -0400917Copies Rect of pixels from Canvas into dstPixels. Matrix and Clip are
Herb Derbyefe39bc2018-05-01 17:06:20 -0400918ignored.
Cary Clark6fc50412017-09-21 12:31:06 -0400919
Cary Clarka560c472017-11-27 10:44:06 -0500920Source Rect corners are (srcX, srcY) and (imageInfo().width(), imageInfo().height()).
921Destination Rect corners are (0, 0) and (dstInfo.width(), dstInfo.height()).
Cary Clark6fc50412017-09-21 12:31:06 -0400922Copies each readable pixel intersecting both rectangles, without scaling,
Cary Clarkf05bdda2017-08-24 12:59:48 -0400923converting to dstInfo.colorType() and dstInfo.alphaType() if required.
Cary Clark8032b982017-07-28 11:04:54 -0400924
Cary Clarkf05bdda2017-08-24 12:59:48 -0400925Pixels are readable when Device is raster, or backed by a GPU.
926Pixels are not readable when SkCanvas is returned by SkDocument::beginPage,
927returned by SkPictureRecorder::beginRecording, or Canvas is the base of a utility
Brian Osman46fe9c72018-03-09 15:44:34 -0500928class like SkDebugCanvas.
Cary Clark8032b982017-07-28 11:04:54 -0400929
Cary Clarkf05bdda2017-08-24 12:59:48 -0400930The destination pixel storage must be allocated by the caller.
Cary Clark8032b982017-07-28 11:04:54 -0400931
Cary Clark2dc84ad2018-01-26 12:56:22 -0500932Pixel values are converted only if Color_Type and Alpha_Type
Cary Clarkf05bdda2017-08-24 12:59:48 -0400933do not match. Only pixels within both source and destination rectangles
Cary Clark154beea2017-10-26 07:58:48 -0400934are copied. dstPixels contents outside Rect intersection are unchanged.
Cary Clarkf05bdda2017-08-24 12:59:48 -0400935
936Pass negative values for srcX or srcY to offset pixels across or down destination.
Cary Clark8032b982017-07-28 11:04:54 -0400937
938Does not copy, and returns false if:
939
940#List
Cary Clarkf05bdda2017-08-24 12:59:48 -0400941# Source and destination rectangles do not intersect. ##
942# Canvas pixels could not be converted to dstInfo.colorType() or dstInfo.alphaType(). ##
943# Canvas pixels are not readable; for instance, Canvas is document-based. ##
Cary Clark8032b982017-07-28 11:04:54 -0400944# dstRowBytes is too small to contain one row of pixels. ##
945##
Cary Clark80247e52018-07-11 16:18:41 -0400946.
Cary Clark8032b982017-07-28 11:04:54 -0400947
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##
Cary Clark80247e52018-07-11 16:18:41 -04001040.
Cary Clark8032b982017-07-28 11:04:54 -04001041
Cary Clarkbad5ad72017-08-03 17:14:08 -04001042#Param pixmap storage for pixels copied from Canvas ##
Cary Clark5538c132018-06-14 12:28:14 -04001043#Param srcX offset into readable pixels on x-axis; may be negative ##
1044#Param srcY offset into readable pixels on y-axis; may be negative ##
Cary Clark8032b982017-07-28 11:04:54 -04001045
Cary Clarkbad5ad72017-08-03 17:14:08 -04001046#Return true if pixels were copied ##
Cary Clark8032b982017-07-28 11:04:54 -04001047
1048#Example
Cary Clarkf05bdda2017-08-24 12:59:48 -04001049 #Description
Cary Clarkce101242017-09-01 15:51:02 -04001050 clear() takes Unpremultiplied input with Color_Alpha equal 0x80
Cary Clarkffb3d682018-05-17 12:17:28 -04001051 and RGB equal 0x55, 0xAA, 0xFF. RGB is multiplied by Color_Alpha
Cary Clarkce101242017-09-01 15:51:02 -04001052 to generate Premultiplied value 0x802B5580.
Cary Clarkf05bdda2017-08-24 12:59:48 -04001053 ##
1054 void draw(SkCanvas* canvas) {
1055 canvas->clear(0x8055aaff);
1056 uint32_t pixels[1] = { 0 };
1057 SkPixmap pixmap(SkImageInfo::MakeN32Premul(1, 1), pixels, 4);
1058 canvas->readPixels(pixmap, 0, 0);
1059 SkDebugf("pixel = %08x\n", pixels[0]);
1060 }
Cary Clark8032b982017-07-28 11:04:54 -04001061 #StdOut
1062 pixel = 802b5580
1063 ##
1064##
1065
Cary Clark2ade9972017-11-02 17:49:34 -04001066#SeeAlso peekPixels writePixels drawBitmap drawImage SkBitmap::readPixels SkPixmap::readPixels SkImage::readPixels SkSurface::readPixels
Cary Clark8032b982017-07-28 11:04:54 -04001067
1068##
1069
1070# ------------------------------------------------------------------------------
1071
1072#Method bool readPixels(const SkBitmap& bitmap, int srcX, int srcY)
1073
Cary Clark154beea2017-10-26 07:58:48 -04001074Copies Rect of pixels from Canvas into bitmap. Matrix and Clip are
Cary Clarka560c472017-11-27 10:44:06 -05001075ignored.
Cary Clark6fc50412017-09-21 12:31:06 -04001076
Cary Clarka560c472017-11-27 10:44:06 -05001077Source Rect corners are (srcX, srcY) and (imageInfo().width(), imageInfo().height()).
Cary Clark154beea2017-10-26 07:58:48 -04001078Destination Rect corners are (0, 0) and (bitmap.width(), bitmap.height()).
Cary Clarkf05bdda2017-08-24 12:59:48 -04001079Copies each readable pixel intersecting both rectangles, without scaling,
1080converting to bitmap.colorType() and bitmap.alphaType() if required.
Cary Clark8032b982017-07-28 11:04:54 -04001081
Cary Clarkf05bdda2017-08-24 12:59:48 -04001082Pixels are readable when Device is raster, or backed by a GPU.
1083Pixels are not readable when SkCanvas is returned by SkDocument::beginPage,
1084returned by SkPictureRecorder::beginRecording, or Canvas is the base of a utility
Brian Osman46fe9c72018-03-09 15:44:34 -05001085class like SkDebugCanvas.
Cary Clark8032b982017-07-28 11:04:54 -04001086
Cary Clark6fc50412017-09-21 12:31:06 -04001087Caller must allocate pixel storage in bitmap if needed.
Cary Clarkf05bdda2017-08-24 12:59:48 -04001088
Cary Clark2dc84ad2018-01-26 12:56:22 -05001089Bitmap values are converted only if Color_Type and Alpha_Type
Cary Clarkf05bdda2017-08-24 12:59:48 -04001090do not match. Only pixels within both source and destination rectangles
Cary Clark154beea2017-10-26 07:58:48 -04001091are copied. Bitmap pixels outside Rect intersection are unchanged.
Cary Clarkf05bdda2017-08-24 12:59:48 -04001092
1093Pass negative values for srcX or srcY to offset pixels across or down bitmap.
Cary Clark8032b982017-07-28 11:04:54 -04001094
1095Does not copy, and returns false if:
1096
1097#List
Cary Clarkf05bdda2017-08-24 12:59:48 -04001098# Source and destination rectangles do not intersect. ##
1099# Canvas pixels could not be converted to bitmap.colorType() or bitmap.alphaType(). ##
1100# Canvas pixels are not readable; for instance, Canvas is document-based. ##
Cary Clark8032b982017-07-28 11:04:54 -04001101# bitmap pixels could not be allocated. ##
Cary Clarkf05bdda2017-08-24 12:59:48 -04001102# bitmap.rowBytes() is too small to contain one row of pixels. ##
Cary Clark8032b982017-07-28 11:04:54 -04001103##
Cary Clark80247e52018-07-11 16:18:41 -04001104.
Cary Clark8032b982017-07-28 11:04:54 -04001105
Cary Clarkbad5ad72017-08-03 17:14:08 -04001106#Param bitmap storage for pixels copied from Canvas ##
Cary Clark5538c132018-06-14 12:28:14 -04001107#Param srcX offset into readable pixels on x-axis; may be negative ##
1108#Param srcY offset into readable pixels on y-axis; may be negative ##
Cary Clark8032b982017-07-28 11:04:54 -04001109
Cary Clarkbad5ad72017-08-03 17:14:08 -04001110#Return true if pixels were copied ##
Cary Clark8032b982017-07-28 11:04:54 -04001111
1112#Example
Cary Clarkf05bdda2017-08-24 12:59:48 -04001113 #Description
Cary Clarkce101242017-09-01 15:51:02 -04001114 clear() takes Unpremultiplied input with Color_Alpha equal 0x80
Cary Clarkffb3d682018-05-17 12:17:28 -04001115 and RGB equal 0x55, 0xAA, 0xFF. RGB is multiplied by Color_Alpha
Cary Clarkce101242017-09-01 15:51:02 -04001116 to generate Premultiplied value 0x802B5580.
Cary Clarkf05bdda2017-08-24 12:59:48 -04001117 ##
Cary Clark8032b982017-07-28 11:04:54 -04001118void draw(SkCanvas* canvas) {
1119 canvas->clear(0x8055aaff);
1120 SkBitmap bitmap;
1121 bitmap.allocPixels(SkImageInfo::MakeN32Premul(1, 1));
1122 canvas->readPixels(bitmap, 0, 0);
1123 SkDebugf("pixel = %08x\n", bitmap.getAddr32(0, 0)[0]);
1124}
1125 #StdOut
1126 pixel = 802b5580
1127 ##
1128##
1129
Cary Clark2ade9972017-11-02 17:49:34 -04001130#SeeAlso peekPixels writePixels drawBitmap drawImage SkBitmap::readPixels SkPixmap::readPixels SkImage::readPixels SkSurface::readPixels
Cary Clark8032b982017-07-28 11:04:54 -04001131
1132##
1133
1134# ------------------------------------------------------------------------------
1135
1136#Method bool writePixels(const SkImageInfo& info, const void* pixels, size_t rowBytes, int x, int y)
Cary Clark78de7512018-02-07 07:27:09 -05001137#In Pixels
Cary Clarkab2621d2018-01-30 10:08:57 -05001138#Line # copies and converts rectangle of pixels to Canvas ##
Cary Clark154beea2017-10-26 07:58:48 -04001139Copies Rect from pixels to Canvas. Matrix and Clip are ignored.
1140Source Rect corners are (0, 0) and (info.width(), info.height()).
1141Destination Rect corners are (x, y) and
1142(imageInfo().width(), imageInfo().height()).
Cary Clark6fc50412017-09-21 12:31:06 -04001143
1144Copies each readable pixel intersecting both rectangles, without scaling,
Cary Clark154beea2017-10-26 07:58:48 -04001145converting to imageInfo().colorType() and imageInfo().alphaType() if required.
Cary Clark8032b982017-07-28 11:04:54 -04001146
Cary Clarkf05bdda2017-08-24 12:59:48 -04001147Pixels are writable when Device is raster, or backed by a GPU.
1148Pixels are not writable when SkCanvas is returned by SkDocument::beginPage,
1149returned by SkPictureRecorder::beginRecording, or Canvas is the base of a utility
Brian Osman46fe9c72018-03-09 15:44:34 -05001150class like SkDebugCanvas.
Cary Clark8032b982017-07-28 11:04:54 -04001151
Cary Clark2dc84ad2018-01-26 12:56:22 -05001152Pixel values are converted only if Color_Type and Alpha_Type
Cary Clarkf05bdda2017-08-24 12:59:48 -04001153do not match. Only pixels within both source and destination rectangles
Cary Clark154beea2017-10-26 07:58:48 -04001154are copied. Canvas pixels outside Rect intersection are unchanged.
Cary Clark8032b982017-07-28 11:04:54 -04001155
Cary Clarkf05bdda2017-08-24 12:59:48 -04001156Pass negative values for x or y to offset pixels to the left or
1157above Canvas pixels.
Cary Clark8032b982017-07-28 11:04:54 -04001158
1159Does not copy, and returns false if:
1160
1161#List
Cary Clarkf05bdda2017-08-24 12:59:48 -04001162# Source and destination rectangles do not intersect. ##
Cary Clarkac47b882018-01-11 10:35:44 -05001163# pixels could not be converted to Canvas imageInfo().colorType() or
1164 imageInfo().alphaType(). ##
Cary Clark8032b982017-07-28 11:04:54 -04001165# Canvas pixels are not writable; for instance, Canvas is document-based. ##
1166# rowBytes is too small to contain one row of pixels. ##
1167##
Cary Clark80247e52018-07-11 16:18:41 -04001168.
Cary Clark8032b982017-07-28 11:04:54 -04001169
Cary Clark2dc84ad2018-01-26 12:56:22 -05001170#Param info width, height, Color_Type, and Alpha_Type of pixels ##
Cary Clarkf05bdda2017-08-24 12:59:48 -04001171#Param pixels pixels to copy, of size info.height() times rowBytes, or larger ##
Cary Clarkd0530ba2017-09-14 11:25:39 -04001172#Param rowBytes size of one row of pixels; info.width() times pixel size, or larger ##
Cary Clark5538c132018-06-14 12:28:14 -04001173#Param x offset into Canvas writable pixels on x-axis; may be negative ##
1174#Param y offset into Canvas writable pixels on y-axis; may be negative ##
Cary Clark8032b982017-07-28 11:04:54 -04001175
Cary Clarkbad5ad72017-08-03 17:14:08 -04001176#Return true if pixels were written to Canvas ##
Cary Clark8032b982017-07-28 11:04:54 -04001177
1178#Example
1179 SkImageInfo imageInfo = SkImageInfo::MakeN32(256, 1, kPremul_SkAlphaType);
1180 for (int y = 0; y < 256; ++y) {
1181 uint32_t pixels[256];
1182 for (int x = 0; x < 256; ++x) {
1183 pixels[x] = SkColorSetARGB(x, x + y, x, x - y);
1184 }
1185 canvas->writePixels(imageInfo, &pixels, sizeof(pixels), 0, y);
1186 }
1187##
1188
Cary Clark2ade9972017-11-02 17:49:34 -04001189#SeeAlso readPixels drawBitmap drawImage SkBitmap::writePixels
Cary Clark8032b982017-07-28 11:04:54 -04001190
1191##
1192
1193# ------------------------------------------------------------------------------
1194
1195#Method bool writePixels(const SkBitmap& bitmap, int x, int y)
1196
Cary Clark154beea2017-10-26 07:58:48 -04001197Copies Rect from pixels to Canvas. Matrix and Clip are ignored.
1198Source Rect corners are (0, 0) and (bitmap.width(), bitmap.height()).
Cary Clark6fc50412017-09-21 12:31:06 -04001199
Cary Clark154beea2017-10-26 07:58:48 -04001200Destination Rect corners are (x, y) and
1201(imageInfo().width(), imageInfo().height()).
Cary Clark6fc50412017-09-21 12:31:06 -04001202
1203Copies each readable pixel intersecting both rectangles, without scaling,
Cary Clark154beea2017-10-26 07:58:48 -04001204converting to imageInfo().colorType() and imageInfo().alphaType() if required.
Cary Clark8032b982017-07-28 11:04:54 -04001205
Cary Clarkf05bdda2017-08-24 12:59:48 -04001206Pixels are writable when Device is raster, or backed by a GPU.
1207Pixels are not writable when SkCanvas is returned by SkDocument::beginPage,
1208returned by SkPictureRecorder::beginRecording, or Canvas is the base of a utility
Brian Osman46fe9c72018-03-09 15:44:34 -05001209class like SkDebugCanvas.
Cary Clark8032b982017-07-28 11:04:54 -04001210
Cary Clark2dc84ad2018-01-26 12:56:22 -05001211Pixel values are converted only if Color_Type and Alpha_Type
Cary Clarkf05bdda2017-08-24 12:59:48 -04001212do not match. Only pixels within both source and destination rectangles
Cary Clark154beea2017-10-26 07:58:48 -04001213are copied. Canvas pixels outside Rect intersection are unchanged.
Cary Clark8032b982017-07-28 11:04:54 -04001214
Cary Clarkf05bdda2017-08-24 12:59:48 -04001215Pass negative values for x or y to offset pixels to the left or
1216above Canvas pixels.
Cary Clark8032b982017-07-28 11:04:54 -04001217
1218Does not copy, and returns false if:
1219
1220#List
Cary Clarkf05bdda2017-08-24 12:59:48 -04001221# Source and destination rectangles do not intersect. ##
Cary Clark8032b982017-07-28 11:04:54 -04001222# bitmap does not have allocated pixels. ##
Cary Clarkac47b882018-01-11 10:35:44 -05001223# bitmap pixels could not be converted to Canvas imageInfo().colorType() or
1224 imageInfo().alphaType(). ##
Cary Clarkce101242017-09-01 15:51:02 -04001225# Canvas pixels are not writable; for instance, Canvas is document based. ##
Cary Clark8032b982017-07-28 11:04:54 -04001226# bitmap pixels are inaccessible; for instance, bitmap wraps a texture. ##
1227##
Cary Clark80247e52018-07-11 16:18:41 -04001228.
Cary Clark8032b982017-07-28 11:04:54 -04001229
Cary Clarkbad5ad72017-08-03 17:14:08 -04001230#Param bitmap contains pixels copied to Canvas ##
Cary Clarkf05bdda2017-08-24 12:59:48 -04001231#Param x offset into Canvas writable pixels in x; may be negative ##
1232#Param y offset into Canvas writable pixels in y; may be negative ##
Cary Clark8032b982017-07-28 11:04:54 -04001233
Cary Clarkbad5ad72017-08-03 17:14:08 -04001234#Return true if pixels were written to Canvas ##
Cary Clark8032b982017-07-28 11:04:54 -04001235
1236#Example
1237void draw(SkCanvas* canvas) {
1238 SkImageInfo imageInfo = SkImageInfo::MakeN32Premul(2, 2);
1239 SkBitmap bitmap;
1240 bitmap.setInfo(imageInfo);
1241 uint32_t pixels[4];
1242 bitmap.setPixels(pixels);
1243 for (int y = 0; y < 256; y += 2) {
1244 for (int x = 0; x < 256; x += 2) {
1245 pixels[0] = SkColorSetRGB(x, y, x | y);
1246 pixels[1] = SkColorSetRGB(x ^ y, y, x);
1247 pixels[2] = SkColorSetRGB(x, x & y, y);
1248 pixels[3] = SkColorSetRGB(~x, ~y, x);
1249 canvas->writePixels(bitmap, x, y);
1250 }
1251 }
1252}
1253##
1254
Cary Clark2ade9972017-11-02 17:49:34 -04001255#SeeAlso readPixels drawBitmap drawImage SkBitmap::writePixels
Cary Clark8032b982017-07-28 11:04:54 -04001256
1257##
1258
1259# ------------------------------------------------------------------------------
Cary Clark08895c42018-02-01 09:37:32 -05001260#Subtopic State_Stack
1261#Line # stack of state for hierarchical drawing ##
Cary Clark8032b982017-07-28 11:04:54 -04001262
1263Canvas maintains a stack of state that allows hierarchical drawing, commonly used
Cary Clarkbad5ad72017-08-03 17:14:08 -04001264to implement windows and views. The initial state has an identity matrix and and
1265an infinite clip. Even with a wide-open clip, drawing is constrained by the
1266bounds of the Canvas Surface or Device.
Cary Clark8032b982017-07-28 11:04:54 -04001267
Cary Clark939fd6c2018-07-12 08:40:13 -04001268Canvas savable state consists of Clip and Matrix.
Cary Clark8032b982017-07-28 11:04:54 -04001269Clip describes the area that may be drawn to.
1270Matrix transforms the geometry.
Cary Clark8032b982017-07-28 11:04:54 -04001271
1272save(), saveLayer, saveLayerPreserveLCDTextRequests, and saveLayerAlpha
1273save state and return the depth of the stack.
1274
Cary Clarkbad5ad72017-08-03 17:14:08 -04001275restore(), restoreToCount, and ~SkCanvas() revert state to its value when saved.
Cary Clark8032b982017-07-28 11:04:54 -04001276
1277Each state on the stack intersects Clip with the previous Clip,
1278and concatenates Matrix with the previous Matrix.
1279The intersected Clip makes the drawing area the same or smaller;
1280the concatenated Matrix may move the origin and potentially scale or rotate
1281the coordinate space.
1282
1283Canvas does not require balancing the state stack but it is a good idea
1284to do so. Calling save() without restore() will eventually cause Skia to fail;
1285mismatched save() and restore() create hard to find bugs.
1286
1287It is not possible to use state to draw outside of the clip defined by the
1288previous state.
1289
1290#Example
1291#Description
1292Draw to ever smaller clips; then restore drawing to full canvas.
1293Note that the second clipRect is not permitted to enlarge Clip.
1294##
1295#Height 160
Cary Clarkbad5ad72017-08-03 17:14:08 -04001296void draw(SkCanvas* canvas) {
1297 SkPaint paint;
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(100, 100)); // constrains drawing to clip
1300 canvas->clear(SK_ColorRED); // draws to limit of clip
Herb Derbyefe39bc2018-05-01 17:06:20 -04001301 canvas->save(); // records stack depth to restore
Cary Clarkbad5ad72017-08-03 17:14:08 -04001302 canvas->clipRect(SkRect::MakeWH(50, 150)); // Rect below 100 is ignored
1303 canvas->clear(SK_ColorBLUE); // draws to smaller clip
1304 canvas->restore(); // enlarges clip
1305 canvas->drawLine(20, 20, 150, 150, paint); // line below 100 is not drawn
1306 canvas->restore(); // enlarges clip
1307 canvas->drawLine(150, 20, 50, 120, paint); // line below 100 is drawn
Cary Clark8032b982017-07-28 11:04:54 -04001308}
Herb Derbyefe39bc2018-05-01 17:06:20 -04001309##
Cary Clark8032b982017-07-28 11:04:54 -04001310
1311Each Clip uses the current Matrix for its coordinates.
1312
1313#Example
1314#Description
1315While clipRect is given the same rectangle twice, Matrix makes the second
1316clipRect draw at half the size of the first.
1317##
1318#Height 128
Cary Clarkbad5ad72017-08-03 17:14:08 -04001319void draw(SkCanvas* canvas) {
1320 canvas->clipRect(SkRect::MakeWH(100, 100));
1321 canvas->clear(SK_ColorRED);
1322 canvas->scale(.5, .5);
1323 canvas->clipRect(SkRect::MakeWH(100, 100));
1324 canvas->clear(SK_ColorBLUE);
Cary Clark8032b982017-07-28 11:04:54 -04001325}
1326##
1327
1328#SeeAlso save() saveLayer saveLayerPreserveLCDTextRequests saveLayerAlpha restore() restoreToCount
1329
1330#Method int save()
1331
Cary Clarkab2621d2018-01-30 10:08:57 -05001332#In State_Stack
1333#Line # saves Clip and Matrix on stack ##
Cary Clark939fd6c2018-07-12 08:40:13 -04001334Saves Matrix and Clip.
1335Calling restore() discards changes to Matrix and Clip,
1336restoring the Matrix and Clip to their state when save() was called.
Cary Clark8032b982017-07-28 11:04:54 -04001337
Cary Clarkbad5ad72017-08-03 17:14:08 -04001338Matrix may be changed by translate(), scale(), rotate(), skew(), concat(), setMatrix,
1339and resetMatrix. Clip may be changed by clipRect, clipRRect, clipPath, clipRegion.
Cary Clark8032b982017-07-28 11:04:54 -04001340
Cary Clarkbad5ad72017-08-03 17:14:08 -04001341Saved Canvas state is put on a stack; multiple calls to save() should be balance
1342by an equal number of calls to restore().
Cary Clark8032b982017-07-28 11:04:54 -04001343
1344Call restoreToCount with result to restore this and subsequent saves.
1345
Cary Clarkbad5ad72017-08-03 17:14:08 -04001346#Return depth of saved stack ##
Cary Clark8032b982017-07-28 11:04:54 -04001347
1348#Example
Herb Derbyefe39bc2018-05-01 17:06:20 -04001349#Description
Cary Clark8032b982017-07-28 11:04:54 -04001350The black square is translated 50 pixels down and to the right.
1351Restoring Canvas state removes translate() from Canvas stack;
1352the red square is not translated, and is drawn at the origin.
1353##
1354#Height 100
1355void draw(SkCanvas* canvas) {
1356 SkPaint paint;
1357 SkRect rect = { 0, 0, 25, 25 };
1358 canvas->drawRect(rect, paint);
1359 canvas->save();
1360 canvas->translate(50, 50);
1361 canvas->drawRect(rect, paint);
1362 canvas->restore();
1363 paint.setColor(SK_ColorRED);
1364 canvas->drawRect(rect, paint);
1365}
1366##
1367
Cary Clark2ade9972017-11-02 17:49:34 -04001368#SeeAlso saveLayer saveLayerPreserveLCDTextRequests saveLayerAlpha restore() restoreToCount
Cary Clark8032b982017-07-28 11:04:54 -04001369
1370##
1371
1372# ------------------------------------------------------------------------------
Cary Clark8032b982017-07-28 11:04:54 -04001373
1374#Method void restore()
1375
Cary Clarkab2621d2018-01-30 10:08:57 -05001376#In State_Stack
1377#Line # restores changes to Clip and Matrix, pops save stack ##
Cary Clark939fd6c2018-07-12 08:40:13 -04001378Removes changes to Matrix and Clip since Canvas state was
Herb Derbyefe39bc2018-05-01 17:06:20 -04001379last saved. The state is removed from the stack.
Cary Clark8032b982017-07-28 11:04:54 -04001380
Herb Derbyefe39bc2018-05-01 17:06:20 -04001381Does nothing if the stack is empty.
Cary Clark8032b982017-07-28 11:04:54 -04001382
1383#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04001384void draw(SkCanvas* canvas) {
1385 SkCanvas simple;
1386 SkDebugf("depth = %d\n", simple.getSaveCount());
1387 simple.restore();
1388 SkDebugf("depth = %d\n", simple.getSaveCount());
Cary Clark8032b982017-07-28 11:04:54 -04001389}
1390##
1391
Cary Clark2ade9972017-11-02 17:49:34 -04001392#SeeAlso save() saveLayer saveLayerPreserveLCDTextRequests saveLayerAlpha restoreToCount
1393
Cary Clark8032b982017-07-28 11:04:54 -04001394##
1395
1396# ------------------------------------------------------------------------------
1397
1398#Method int getSaveCount() const
1399
Cary Clarkab2621d2018-01-30 10:08:57 -05001400#In State_Stack
1401#Line # returns depth of stack containing Clip and Matrix ##
Cary Clark939fd6c2018-07-12 08:40:13 -04001402Returns the number of saved states, each containing: Matrix and Clip.
Herb Derbyefe39bc2018-05-01 17:06:20 -04001403Equals the number of save() calls less the number of restore() calls plus one.
Cary Clark8032b982017-07-28 11:04:54 -04001404The save count of a new canvas is one.
1405
Cary Clarkbad5ad72017-08-03 17:14:08 -04001406#Return depth of save state stack ##
Cary Clark8032b982017-07-28 11:04:54 -04001407
1408#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04001409void draw(SkCanvas* canvas) {
1410 SkCanvas simple;
1411 SkDebugf("depth = %d\n", simple.getSaveCount());
1412 simple.save();
1413 SkDebugf("depth = %d\n", simple.getSaveCount());
1414 simple.restore();
1415 SkDebugf("depth = %d\n", simple.getSaveCount());
Cary Clark8032b982017-07-28 11:04:54 -04001416}
1417#StdOut
Cary Clarkbad5ad72017-08-03 17:14:08 -04001418depth = 1
1419depth = 2
Cary Clark8032b982017-07-28 11:04:54 -04001420depth = 1
1421##
1422##
1423
Cary Clark2ade9972017-11-02 17:49:34 -04001424#SeeAlso save() restore() restoreToCount
1425
Cary Clark8032b982017-07-28 11:04:54 -04001426##
1427
1428# ------------------------------------------------------------------------------
1429
1430#Method void restoreToCount(int saveCount)
1431
Cary Clarkab2621d2018-01-30 10:08:57 -05001432#In State_Stack
1433#Line # restores changes to Clip and Matrix to given depth ##
Cary Clark939fd6c2018-07-12 08:40:13 -04001434Restores state to Matrix and Clip values when save(), saveLayer,
Cary Clarkbad5ad72017-08-03 17:14:08 -04001435saveLayerPreserveLCDTextRequests, or saveLayerAlpha returned saveCount.
Cary Clark8032b982017-07-28 11:04:54 -04001436
Herb Derbyefe39bc2018-05-01 17:06:20 -04001437Does nothing if saveCount is greater than state stack count.
Cary Clark8032b982017-07-28 11:04:54 -04001438Restores state to initial values if saveCount is less than or equal to one.
1439
Cary Clarkbad5ad72017-08-03 17:14:08 -04001440#Param saveCount depth of state stack to restore ##
Cary Clark8032b982017-07-28 11:04:54 -04001441
1442#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04001443void draw(SkCanvas* canvas) {
1444 SkDebugf("depth = %d\n", canvas->getSaveCount());
1445 canvas->save();
1446 canvas->save();
1447 SkDebugf("depth = %d\n", canvas->getSaveCount());
1448 canvas->restoreToCount(0);
1449 SkDebugf("depth = %d\n", canvas->getSaveCount());
Cary Clark8032b982017-07-28 11:04:54 -04001450}
1451#StdOut
Cary Clarkbad5ad72017-08-03 17:14:08 -04001452depth = 1
1453depth = 3
Cary Clark8032b982017-07-28 11:04:54 -04001454depth = 1
1455##
1456##
1457
Herb Derbyefe39bc2018-05-01 17:06:20 -04001458#SeeAlso restore() getSaveCount save()
Cary Clark2ade9972017-11-02 17:49:34 -04001459
Cary Clark8032b982017-07-28 11:04:54 -04001460##
1461
Cary Clark08895c42018-02-01 09:37:32 -05001462#Subtopic State_Stack ##
Cary Clark8032b982017-07-28 11:04:54 -04001463
1464# ------------------------------------------------------------------------------
Cary Clarkce101242017-09-01 15:51:02 -04001465
Cary Clark08895c42018-02-01 09:37:32 -05001466#Subtopic Layer
Cary Clarkd0530ba2017-09-14 11:25:39 -04001467#Substitute layer
Cary Clarkce101242017-09-01 15:51:02 -04001468#Alias Layers
Cary Clark137b8742018-05-30 09:21:49 -04001469#Substitute layers
1470##
Cary Clark08895c42018-02-01 09:37:32 -05001471#Line # temporary Bitmap to draw into ##
Cary Clarkce101242017-09-01 15:51:02 -04001472
1473Layer allocates a temporary Bitmap to draw into. When the drawing is
Herb Derbyefe39bc2018-05-01 17:06:20 -04001474complete, the Bitmap is drawn into the Canvas.
Cary Clarkce101242017-09-01 15:51:02 -04001475
1476Layer is saved in a stack along with other saved state. When state with a Layer
1477is restored, the Bitmap is drawn into the previous Layer.
1478
1479Layer may be initialized with the contents of the previous Layer. When Layer is
1480restored, its Bitmap can be modified by Paint passed to Layer to apply
1481Color_Alpha, Color_Filter, Image_Filter, and Blend_Mode.
1482
1483#Method int saveLayer(const SkRect* bounds, const SkPaint* paint)
1484
Cary Clarkab2621d2018-01-30 10:08:57 -05001485#In Layer
1486#Line # saves Clip and Matrix on stack; creates Layer ##
Cary Clark939fd6c2018-07-12 08:40:13 -04001487Saves Matrix and Clip, and allocates a Bitmap for subsequent drawing.
1488Calling restore() discards changes to Matrix and Clip, and draws the Bitmap.
Cary Clarkce101242017-09-01 15:51:02 -04001489
1490Matrix may be changed by translate(), scale(), rotate(), skew(), concat(),
Herb Derbyefe39bc2018-05-01 17:06:20 -04001491setMatrix, and resetMatrix. Clip may be changed by clipRect, clipRRect,
Cary Clarkce101242017-09-01 15:51:02 -04001492clipPath, clipRegion.
1493
1494Rect bounds suggests but does not define the Bitmap size. To clip drawing to
1495a specific rectangle, use clipRect.
1496
1497Optional Paint paint applies Color_Alpha, Color_Filter, Image_Filter, and
1498Blend_Mode when restore() is called.
1499
1500Call restoreToCount with returned value to restore this and subsequent saves.
1501
1502#Param bounds hint to limit the size of the Layer; may be nullptr ##
1503#Param paint graphics state for Layer; may be nullptr ##
1504
1505#Return depth of saved stack ##
1506
1507#Example
1508#Description
1509Rectangles are blurred by Image_Filter when restore() draws Layer to main
1510Canvas.
1511##
1512#Height 128
Cary Clark81abc432018-06-25 16:30:08 -04001513#Function
1514###$
1515#include "SkBlurImageFilter.h"
1516$$$#
1517##
1518
Cary Clarkce101242017-09-01 15:51:02 -04001519void draw(SkCanvas* canvas) {
1520 SkPaint paint, blur;
Cary Clarka560c472017-11-27 10:44:06 -05001521 blur.setImageFilter(SkBlurImageFilter::Make(3, 3, nullptr));
Cary Clarkce101242017-09-01 15:51:02 -04001522 canvas->saveLayer(nullptr, &blur);
1523 SkRect rect = { 25, 25, 50, 50};
1524 canvas->drawRect(rect, paint);
1525 canvas->translate(50, 50);
1526 paint.setColor(SK_ColorRED);
1527 canvas->drawRect(rect, paint);
1528 canvas->restore();
1529}
1530##
1531
Cary Clark2ade9972017-11-02 17:49:34 -04001532#SeeAlso save() restore() saveLayer saveLayerPreserveLCDTextRequests saveLayerAlpha SaveLayerRec
Cary Clarkce101242017-09-01 15:51:02 -04001533
1534##
1535
Herb Derbyefe39bc2018-05-01 17:06:20 -04001536#Method int saveLayer(const SkRect& bounds, const SkPaint* paint)
Cary Clarkce101242017-09-01 15:51:02 -04001537
Cary Clarkab2621d2018-01-30 10:08:57 -05001538#In Layer
Cary Clark939fd6c2018-07-12 08:40:13 -04001539Saves Matrix and Clip, and allocates a Bitmap for subsequent drawing.
1540Calling restore() discards changes to Matrix and Clip, and draws the Bitmap.
Cary Clarkce101242017-09-01 15:51:02 -04001541
1542Matrix may be changed by translate(), scale(), rotate(), skew(), concat(),
1543setMatrix, and resetMatrix. Clip may be changed by clipRect, clipRRect,
1544clipPath, clipRegion.
1545
1546Rect bounds suggests but does not define the Layer size. To clip drawing to
1547a specific rectangle, use clipRect.
1548
1549Optional Paint paint applies Color_Alpha, Color_Filter, Image_Filter, and
1550Blend_Mode when restore() is called.
1551
1552Call restoreToCount with returned value to restore this and subsequent saves.
1553
1554#Param bounds hint to limit the size of Layer; may be nullptr ##
1555#Param paint graphics state for Layer; may be nullptr ##
1556
1557#Return depth of saved stack ##
1558
1559#Example
1560#Description
1561Rectangles are blurred by Image_Filter when restore() draws Layer to main Canvas.
Herb Derbyefe39bc2018-05-01 17:06:20 -04001562The red rectangle is clipped; it does not fully fit on Layer.
Cary Clarkce101242017-09-01 15:51:02 -04001563Image_Filter blurs past edge of Layer so red rectangle is blurred on all sides.
1564##
1565#Height 128
Cary Clark81abc432018-06-25 16:30:08 -04001566#Function
1567###$
1568#include "SkBlurImageFilter.h"
1569$$$#
1570##
1571
Cary Clarkce101242017-09-01 15:51:02 -04001572void draw(SkCanvas* canvas) {
1573 SkPaint paint, blur;
Cary Clarka560c472017-11-27 10:44:06 -05001574 blur.setImageFilter(SkBlurImageFilter::Make(3, 3, nullptr));
Cary Clarkce101242017-09-01 15:51:02 -04001575 canvas->saveLayer(SkRect::MakeWH(90, 90), &blur);
1576 SkRect rect = { 25, 25, 50, 50};
1577 canvas->drawRect(rect, paint);
1578 canvas->translate(50, 50);
1579 paint.setColor(SK_ColorRED);
1580 canvas->drawRect(rect, paint);
1581 canvas->restore();
1582}
1583##
1584
Cary Clark2ade9972017-11-02 17:49:34 -04001585#SeeAlso save() restore() saveLayerPreserveLCDTextRequests saveLayerAlpha SaveLayerRec
Cary Clarkce101242017-09-01 15:51:02 -04001586
1587##
1588
1589#Method int saveLayerPreserveLCDTextRequests(const SkRect* bounds, const SkPaint* paint)
1590
Cary Clarkab2621d2018-01-30 10:08:57 -05001591#In Layer
1592#Line # saves Clip and Matrix on stack; creates Layer for LCD text ##
Cary Clark939fd6c2018-07-12 08:40:13 -04001593Saves Matrix and Clip, and allocates a Bitmap for subsequent drawing.
Cary Clarkce101242017-09-01 15:51:02 -04001594LCD_Text is preserved when the Layer is drawn to the prior Layer.
1595
Cary Clark939fd6c2018-07-12 08:40:13 -04001596Calling restore() discards changes to Matrix and Clip, and draws Layer.
Cary Clarkce101242017-09-01 15:51:02 -04001597
1598Matrix may be changed by translate(), scale(), rotate(), skew(), concat(),
1599setMatrix, and resetMatrix. Clip may be changed by clipRect, clipRRect,
1600clipPath, clipRegion.
Herb Derbyefe39bc2018-05-01 17:06:20 -04001601
Cary Clarkce101242017-09-01 15:51:02 -04001602Rect bounds suggests but does not define the Layer size. To clip drawing to
1603a specific rectangle, use clipRect.
1604
1605Optional Paint paint applies Color_Alpha, Color_Filter, Image_Filter, and
1606Blend_Mode when restore() is called.
1607
1608Call restoreToCount with returned value to restore this and subsequent saves.
1609
1610Draw text on an opaque background so that LCD_Text blends correctly with the
1611prior Layer. LCD_Text drawn on a background with transparency may result in
Cary Clark6fc50412017-09-21 12:31:06 -04001612incorrect blending.
Cary Clarkce101242017-09-01 15:51:02 -04001613
1614#Param bounds hint to limit the size of Layer; may be nullptr ##
1615#Param paint graphics state for Layer; may be nullptr ##
1616
1617#Return depth of saved stack ##
1618
1619#Example
1620 SkPaint paint;
1621 paint.setAntiAlias(true);
1622 paint.setLCDRenderText(true);
1623 paint.setTextSize(20);
1624 for (auto preserve : { false, true } ) {
1625 preserve ? canvas->saveLayerPreserveLCDTextRequests(nullptr, nullptr)
1626 : canvas->saveLayer(nullptr, nullptr);
1627 SkPaint p;
1628 p.setColor(SK_ColorWHITE);
1629 // Comment out the next line to draw on a non-opaque background.
1630 canvas->drawRect(SkRect::MakeLTRB(25, 40, 200, 70), p);
1631 canvas->drawString("Hamburgefons", 30, 60, paint);
1632
1633 p.setColor(0xFFCCCCCC);
1634 canvas->drawRect(SkRect::MakeLTRB(25, 70, 200, 100), p);
1635 canvas->drawString("Hamburgefons", 30, 90, paint);
1636
1637 canvas->restore();
1638 canvas->translate(0, 80);
1639 }
1640 ##
1641
Cary Clark2ade9972017-11-02 17:49:34 -04001642#SeeAlso save() restore() saveLayer saveLayerAlpha SaveLayerRec
Cary Clarkce101242017-09-01 15:51:02 -04001643
1644##
1645
1646#Method int saveLayerAlpha(const SkRect* bounds, U8CPU alpha)
1647
Cary Clarkab2621d2018-01-30 10:08:57 -05001648#In Layer
1649#Line # saves Clip and Matrix on stack; creates Layer; sets opacity ##
Cary Clark939fd6c2018-07-12 08:40:13 -04001650Saves Matrix and Clip, and allocates Bitmap for subsequent drawing.
Cary Clarkce101242017-09-01 15:51:02 -04001651
Cary Clark939fd6c2018-07-12 08:40:13 -04001652Calling restore() discards changes to Matrix and Clip,
Cary Clarkce101242017-09-01 15:51:02 -04001653and blends Layer with alpha opacity onto prior Layer.
1654
1655Matrix may be changed by translate(), scale(), rotate(), skew(), concat(),
1656setMatrix, and resetMatrix. Clip may be changed by clipRect, clipRRect,
1657clipPath, clipRegion.
1658
1659Rect bounds suggests but does not define Layer size. To clip drawing to
1660a specific rectangle, use clipRect.
1661
1662alpha of zero is fully transparent, 255 is fully opaque.
1663
1664Call restoreToCount with returned value to restore this and subsequent saves.
1665
1666#Param bounds hint to limit the size of Layer; may be nullptr ##
1667#Param alpha opacity of Layer ##
1668
1669#Return depth of saved stack ##
1670
1671#Example
1672 SkPaint paint;
1673 paint.setColor(SK_ColorRED);
1674 canvas->drawCircle(50, 50, 50, paint);
1675 canvas->saveLayerAlpha(nullptr, 128);
1676 paint.setColor(SK_ColorBLUE);
1677 canvas->drawCircle(100, 50, 50, paint);
1678 paint.setColor(SK_ColorGREEN);
1679 paint.setAlpha(128);
1680 canvas->drawCircle(75, 90, 50, paint);
1681 canvas->restore();
1682##
1683
Cary Clark2ade9972017-11-02 17:49:34 -04001684#SeeAlso save() restore() saveLayer saveLayerPreserveLCDTextRequests SaveLayerRec
Cary Clarkce101242017-09-01 15:51:02 -04001685
1686##
1687
Cary Clarkd98f78c2018-04-26 08:32:37 -04001688#Enum SaveLayerFlagsSet
Cary Clark08895c42018-02-01 09:37:32 -05001689#Line # sets SaveLayerRec options ##
Cary Clarkce101242017-09-01 15:51:02 -04001690#Code
Cary Clarkd98f78c2018-04-26 08:32:37 -04001691 enum SaveLayerFlagsSet {
Cary Clarkce101242017-09-01 15:51:02 -04001692 kPreserveLCDText_SaveLayerFlag = 1 << 1,
1693 kInitWithPrevious_SaveLayerFlag = 1 << 2,
Mike Reed910ca0f2018-04-25 13:04:05 -04001694 kMaskAgainstCoverage_EXPERIMENTAL_DONT_USE_SaveLayerFlag = 1 << 3,
Cary Clarkce101242017-09-01 15:51:02 -04001695 kDontClipToLayer_Legacy_SaveLayerFlag = kDontClipToLayer_PrivateSaveLayerFlag,
1696 };
Cary Clarkd98f78c2018-04-26 08:32:37 -04001697
1698 typedef uint32_t SaveLayerFlags;
Cary Clarkce101242017-09-01 15:51:02 -04001699##
1700
Cary Clark682c58d2018-05-16 07:07:07 -04001701
1702#Typedef uint32_t SaveLayerFlags
1703#Line # options for SaveLayerRec ##
Cary Clark137b8742018-05-30 09:21:49 -04001704##
Cary Clark682c58d2018-05-16 07:07:07 -04001705
Cary Clarkce101242017-09-01 15:51:02 -04001706SaveLayerFlags provides options that may be used in any combination in SaveLayerRec,
Cary Clark682c58d2018-05-16 07:07:07 -04001707defining how Layer allocated by saveLayer operates. It may be set to zero,
1708kPreserveLCDText_SaveLayerFlag, kInitWithPrevious_SaveLayerFlag, or both flags.
1709
Cary Clarkce101242017-09-01 15:51:02 -04001710#Const kPreserveLCDText_SaveLayerFlag 2
Cary Clark682c58d2018-05-16 07:07:07 -04001711#Line # creates Layer for LCD text ##
Cary Clarkce101242017-09-01 15:51:02 -04001712 Creates Layer for LCD text. Flag is ignored if Layer Paint contains
1713 Image_Filter or Color_Filter.
1714##
1715
1716#Const kInitWithPrevious_SaveLayerFlag 4
Cary Clark682c58d2018-05-16 07:07:07 -04001717#Line # initializes with previous contents ##
Cary Clarkce101242017-09-01 15:51:02 -04001718 Initializes Layer with the contents of the previous Layer.
1719##
1720
Mike Reed910ca0f2018-04-25 13:04:05 -04001721#Const kMaskAgainstCoverage_EXPERIMENTAL_DONT_USE_SaveLayerFlag 8
Cary Clark682c58d2018-05-16 07:07:07 -04001722#Experimental do not use
Mike Reed910ca0f2018-04-25 13:04:05 -04001723##
1724
Cary Clarkce101242017-09-01 15:51:02 -04001725#Const kDontClipToLayer_Legacy_SaveLayerFlag 0x80000000
Cary Clark4855f782018-02-06 09:41:53 -05001726#Deprecated soon
Cary Clarkce101242017-09-01 15:51:02 -04001727##
1728
1729#Example
1730#Height 160
1731#Description
1732Canvas Layer captures red and blue circles scaled up by four.
Herb Derbyefe39bc2018-05-01 17:06:20 -04001733scalePaint blends Layer back with transparency.
Cary Clarkce101242017-09-01 15:51:02 -04001734##
1735void draw(SkCanvas* canvas) {
1736 SkPaint redPaint, bluePaint, scalePaint;
1737 redPaint.setColor(SK_ColorRED);
1738 canvas->drawCircle(21, 21, 8, redPaint);
1739 bluePaint.setColor(SK_ColorBLUE);
1740 canvas->drawCircle(31, 21, 8, bluePaint);
1741 SkMatrix matrix;
1742 matrix.setScale(4, 4);
1743 scalePaint.setAlpha(0x40);
1744 scalePaint.setImageFilter(
1745 SkImageFilter::MakeMatrixFilter(matrix, kNone_SkFilterQuality, nullptr));
1746 SkCanvas::SaveLayerRec saveLayerRec(nullptr, &scalePaint,
Herb Derbyefe39bc2018-05-01 17:06:20 -04001747 SkCanvas::kInitWithPrevious_SaveLayerFlag);
Cary Clarkce101242017-09-01 15:51:02 -04001748 canvas->saveLayer(saveLayerRec);
1749 canvas->restore();
1750}
1751##
1752
Cary Clark2ade9972017-11-02 17:49:34 -04001753#SeeAlso save() restore() saveLayer saveLayerPreserveLCDTextRequests saveLayerAlpha SaveLayerRec
Cary Clarkce101242017-09-01 15:51:02 -04001754
1755#Enum ##
1756
Cary Clark682c58d2018-05-16 07:07:07 -04001757#Subtopic SaveLayerRec
1758#Line # contains the state used to create the Layer ##
Cary Clarka560c472017-11-27 10:44:06 -05001759
Cary Clarkce101242017-09-01 15:51:02 -04001760#Struct SaveLayerRec
Cary Clark08895c42018-02-01 09:37:32 -05001761#Line # contains the state used to create the Layer ##
Cary Clark682c58d2018-05-16 07:07:07 -04001762
Cary Clarkce101242017-09-01 15:51:02 -04001763#Code
1764 struct SaveLayerRec {
1765 SaveLayerRec*(...
1766
1767 const SkRect* fBounds;
1768 const SkPaint* fPaint;
1769 const SkImageFilter* fBackdrop;
1770 SaveLayerFlags fSaveLayerFlags;
1771 };
1772##
1773
Cary Clark137b8742018-05-30 09:21:49 -04001774SaveLayerRec contains the state used to create the Layer.
1775
Cary Clark682c58d2018-05-16 07:07:07 -04001776#Subtopic Overview
1777#Populate
1778##
1779
1780#Subtopic Member
1781#Populate
1782##
Cary Clarkce101242017-09-01 15:51:02 -04001783
1784#Member const SkRect* fBounds
Cary Clark682c58d2018-05-16 07:07:07 -04001785#Line # hints at Layer size limit ##
Cary Clarkce101242017-09-01 15:51:02 -04001786 fBounds is used as a hint to limit the size of Layer; may be nullptr.
1787 fBounds suggests but does not define Layer size. To clip drawing to
1788 a specific rectangle, use clipRect.
1789##
1790
1791#Member const SkPaint* fPaint
Cary Clark682c58d2018-05-16 07:07:07 -04001792#Line # modifies overlay ##
Cary Clarkce101242017-09-01 15:51:02 -04001793 fPaint modifies how Layer overlays the prior Layer; may be nullptr.
1794 Color_Alpha, Blend_Mode, Color_Filter, Draw_Looper, Image_Filter, and
1795 Mask_Filter affect Layer draw.
1796##
1797
1798#Member const SkImageFilter* fBackdrop
Cary Clark682c58d2018-05-16 07:07:07 -04001799#Line # applies Image_Filter to prior Layer ##
Cary Clarkce101242017-09-01 15:51:02 -04001800 fBackdrop applies Image_Filter to the prior Layer when copying to the Layer;
1801 may be nullptr. Use kInitWithPrevious_SaveLayerFlag to copy the
1802 prior Layer without an Image_Filter.
1803##
1804
1805#Member const SkImage* fClipMask
Cary Clark682c58d2018-05-16 07:07:07 -04001806#Line # clips Layer with Mask_Alpha ##
Cary Clarkce101242017-09-01 15:51:02 -04001807 restore() clips Layer by the Color_Alpha channel of fClipMask when
1808 Layer is copied to Device. fClipMask may be nullptr. .
1809##
1810
1811#Member const SkMatrix* fClipMatrix
Cary Clark682c58d2018-05-16 07:07:07 -04001812#Line # transforms Mask_Alpha used to clip ##
Herb Derbyefe39bc2018-05-01 17:06:20 -04001813 fClipMatrix transforms fClipMask before it clips Layer. If
Cary Clarkce101242017-09-01 15:51:02 -04001814 fClipMask describes a translucent gradient, it may be scaled and rotated
1815 without introducing artifacts. fClipMatrix may be nullptr.
1816##
1817
1818#Member SaveLayerFlags fSaveLayerFlags
Cary Clark682c58d2018-05-16 07:07:07 -04001819#Line # preserves LCD Text, creates with prior Layer contents ##
Cary Clarkce101242017-09-01 15:51:02 -04001820 fSaveLayerFlags are used to create Layer without transparency,
1821 create Layer for LCD text, and to create Layer with the
1822 contents of the previous Layer.
1823##
1824
1825#Example
1826#Height 160
1827#Description
Cary Clarkffb3d682018-05-17 12:17:28 -04001828Canvas Layer captures a red Anti_Aliased circle and a blue Aliased circle scaled
Cary Clarkce101242017-09-01 15:51:02 -04001829up by four. After drawing another red circle without scaling on top, the Layer is
Herb Derbyefe39bc2018-05-01 17:06:20 -04001830transferred to the main canvas.
Cary Clarkce101242017-09-01 15:51:02 -04001831##
1832void draw(SkCanvas* canvas) {
1833 SkPaint redPaint, bluePaint;
1834 redPaint.setAntiAlias(true);
1835 redPaint.setColor(SK_ColorRED);
1836 canvas->drawCircle(21, 21, 8, redPaint);
1837 bluePaint.setColor(SK_ColorBLUE);
1838 canvas->drawCircle(31, 21, 8, bluePaint);
1839 SkMatrix matrix;
1840 matrix.setScale(4, 4);
1841 auto scaler = SkImageFilter::MakeMatrixFilter(matrix, kNone_SkFilterQuality, nullptr);
Herb Derbyefe39bc2018-05-01 17:06:20 -04001842 SkCanvas::SaveLayerRec saveLayerRec(nullptr, nullptr, scaler.get(), 0);
Cary Clarkce101242017-09-01 15:51:02 -04001843 canvas->saveLayer(saveLayerRec);
1844 canvas->drawCircle(125, 85, 8, redPaint);
1845 canvas->restore();
1846}
1847##
1848
Cary Clark682c58d2018-05-16 07:07:07 -04001849#Subtopic Constructor
1850#Populate
1851##
Cary Clarkce101242017-09-01 15:51:02 -04001852
Cary Clark682c58d2018-05-16 07:07:07 -04001853#Method SaveLayerRec()
1854#Line # constructs SaveLayerRec ##
Cary Clarkce101242017-09-01 15:51:02 -04001855Sets fBounds, fPaint, and fBackdrop to nullptr. Clears fSaveLayerFlags.
1856
1857#Return empty SaveLayerRec ##
1858
1859#Example
1860 SkCanvas::SaveLayerRec rec1;
Mike Kleine083f7c2018-02-07 12:54:27 -05001861 rec1.fSaveLayerFlags = SkCanvas::kPreserveLCDText_SaveLayerFlag;
1862 SkCanvas::SaveLayerRec rec2(nullptr, nullptr, SkCanvas::kPreserveLCDText_SaveLayerFlag);
Cary Clarkce101242017-09-01 15:51:02 -04001863 SkDebugf("rec1 %c= rec2\n", rec1.fBounds == rec2.fBounds
1864 && rec1.fPaint == rec2.fPaint
1865 && rec1.fBackdrop == rec2.fBackdrop
1866 && rec1.fSaveLayerFlags == rec2.fSaveLayerFlags ? '=' : '!');
1867 #StdOut
1868 rec1 == rec2
1869 ##
1870##
1871
Cary Clark2ade9972017-11-02 17:49:34 -04001872#SeeAlso save() restore() saveLayer saveLayerPreserveLCDTextRequests saveLayerAlpha
1873
Cary Clarkce101242017-09-01 15:51:02 -04001874##
1875
Cary Clark224c7002018-06-27 11:00:21 -04001876#Method SaveLayerRec(const SkRect* bounds, const SkPaint* paint, SaveLayerFlags saveLayerFlags = 0)
Cary Clarkce101242017-09-01 15:51:02 -04001877
1878Sets fBounds, fPaint, and fSaveLayerFlags; sets fBackdrop to nullptr.
1879
1880#Param bounds Layer dimensions; may be nullptr ##
1881#Param paint applied to Layer when overlaying prior Layer; may be nullptr ##
1882#Param saveLayerFlags SaveLayerRec options to modify Layer ##
1883
1884#Return SaveLayerRec with empty backdrop ##
1885
1886#Example
1887 SkCanvas::SaveLayerRec rec1;
1888 SkCanvas::SaveLayerRec rec2(nullptr, nullptr);
1889 SkDebugf("rec1 %c= rec2\n", rec1.fBounds == rec2.fBounds
1890 && rec1.fPaint == rec2.fPaint
1891 && rec1.fBackdrop == rec2.fBackdrop
1892 && rec1.fSaveLayerFlags == rec2.fSaveLayerFlags ? '=' : '!');
1893 #StdOut
1894 rec1 == rec2
1895 ##
1896##
1897
Cary Clark2ade9972017-11-02 17:49:34 -04001898#SeeAlso save() restore() saveLayer saveLayerPreserveLCDTextRequests saveLayerAlpha
1899
Cary Clarkce101242017-09-01 15:51:02 -04001900##
1901
1902#Method SaveLayerRec(const SkRect* bounds, const SkPaint* paint, const SkImageFilter* backdrop,
1903 SaveLayerFlags saveLayerFlags)
1904
1905Sets fBounds, fPaint, fBackdrop, and fSaveLayerFlags.
1906
1907#Param bounds Layer dimensions; may be nullptr ##
1908#Param paint applied to Layer when overlaying prior Layer;
1909 may be nullptr
1910##
1911#Param backdrop prior Layer copied with Image_Filter; may be nullptr
1912##
1913#Param saveLayerFlags SaveLayerRec options to modify Layer ##
1914
1915#Return SaveLayerRec fully specified ##
1916
1917#Example
1918 SkCanvas::SaveLayerRec rec1;
1919 SkCanvas::SaveLayerRec rec2(nullptr, nullptr, nullptr, 0);
1920 SkDebugf("rec1 %c= rec2\n", rec1.fBounds == rec2.fBounds
1921 && rec1.fPaint == rec2.fPaint
1922 && rec1.fBackdrop == rec2.fBackdrop
1923 && rec1.fSaveLayerFlags == rec2.fSaveLayerFlags ? '=' : '!');
1924 #StdOut
1925 rec1 == rec2
1926 ##
1927##
1928
Cary Clark2ade9972017-11-02 17:49:34 -04001929#SeeAlso save() restore() saveLayer saveLayerPreserveLCDTextRequests saveLayerAlpha
1930
Cary Clarkce101242017-09-01 15:51:02 -04001931##
1932
1933#Method SaveLayerRec(const SkRect* bounds, const SkPaint* paint, const SkImageFilter* backdrop,
1934 const SkImage* clipMask, const SkMatrix* clipMatrix,
1935 SaveLayerFlags saveLayerFlags)
1936
Cary Clark682c58d2018-05-16 07:07:07 -04001937#Experimental not ready
Cary Clarkce101242017-09-01 15:51:02 -04001938
1939Sets fBounds, fPaint, fBackdrop, fClipMask, fClipMatrix, and fSaveLayerFlags.
1940clipMatrix uses Color_Alpha channel of image, transformed by clipMatrix, to clip
1941Layer when drawn to Canvas.
1942
Cary Clark2ade9972017-11-02 17:49:34 -04001943Implementation is not complete; has no effect if Device is GPU-backed.
Cary Clarkce101242017-09-01 15:51:02 -04001944
1945#Param bounds Layer dimensions; may be nullptr ##
1946#Param paint graphics state applied to Layer when overlaying prior
1947 Layer; may be nullptr
1948##
1949#Param backdrop prior Layer copied with Image_Filter;
1950 may be nullptr
1951##
1952#Param clipMask clip applied to Layer; may be nullptr ##
1953#Param clipMatrix matrix applied to clipMask; may be nullptr to use
Herb Derbyefe39bc2018-05-01 17:06:20 -04001954 identity matrix
Cary Clarkce101242017-09-01 15:51:02 -04001955##
1956#Param saveLayerFlags SaveLayerRec options to modify Layer ##
1957
1958#Return SaveLayerRec fully specified ##
1959
Cary Clark2ade9972017-11-02 17:49:34 -04001960#SeeAlso save() restore() saveLayer saveLayerPreserveLCDTextRequests saveLayerAlpha
Cary Clarkce101242017-09-01 15:51:02 -04001961
1962##
1963
1964#Struct ##
1965
Cary Clark682c58d2018-05-16 07:07:07 -04001966#Subtopic ##
1967
Cary Clarkce101242017-09-01 15:51:02 -04001968#Method int saveLayer(const SaveLayerRec& layerRec)
1969
Cary Clarkab2621d2018-01-30 10:08:57 -05001970#In Layer
Cary Clark939fd6c2018-07-12 08:40:13 -04001971Saves Matrix and Clip, and allocates Bitmap for subsequent drawing.
Cary Clarkce101242017-09-01 15:51:02 -04001972
Cary Clark939fd6c2018-07-12 08:40:13 -04001973Calling restore() discards changes to Matrix and Clip,
Cary Clarkce101242017-09-01 15:51:02 -04001974and blends Bitmap with Color_Alpha opacity onto the prior Layer.
1975
1976Matrix may be changed by translate(), scale(), rotate(), skew(), concat(),
1977setMatrix, and resetMatrix. Clip may be changed by clipRect, clipRRect,
1978clipPath, clipRegion.
1979
1980SaveLayerRec contains the state used to create the Layer.
1981
1982Call restoreToCount with returned value to restore this and subsequent saves.
1983
1984#Param layerRec Layer state ##
1985
1986#Return depth of save state stack ##
1987
1988#Example
1989#Description
1990The example draws an image, and saves it into a Layer with kInitWithPrevious_SaveLayerFlag.
1991Next it punches a hole in Layer and restore with SkBlendMode::kPlus.
1992Where Layer was cleared, the original image will draw unchanged.
1993Outside of the circle the mandrill is brightened.
1994##
1995 #Image 3
Hal Canaryc465d132017-12-08 10:21:31 -05001996 // sk_sp<SkImage> image = GetResourceAsImage("images/mandrill_256.png");
Cary Clarkce101242017-09-01 15:51:02 -04001997 canvas->drawImage(image, 0, 0, nullptr);
1998 SkCanvas::SaveLayerRec rec;
1999 SkPaint paint;
2000 paint.setBlendMode(SkBlendMode::kPlus);
2001 rec.fSaveLayerFlags = SkCanvas::kInitWithPrevious_SaveLayerFlag;
2002 rec.fPaint = &paint;
2003 canvas->saveLayer(rec);
2004 paint.setBlendMode(SkBlendMode::kClear);
2005 canvas->drawCircle(128, 128, 96, paint);
2006 canvas->restore();
2007##
2008
2009#ToDo above example needs to replace GetResourceAsImage with way to select image in fiddle ##
2010
Cary Clark2ade9972017-11-02 17:49:34 -04002011#SeeAlso save() restore() saveLayer saveLayerPreserveLCDTextRequests saveLayerAlpha
2012
Cary Clarkce101242017-09-01 15:51:02 -04002013##
2014
Cary Clark08895c42018-02-01 09:37:32 -05002015#Subtopic Layer ##
Cary Clarkce101242017-09-01 15:51:02 -04002016
2017# ------------------------------------------------------------------------------
Cary Clark08895c42018-02-01 09:37:32 -05002018#Subtopic Matrix
2019#Line # coordinate transformation ##
Cary Clark8032b982017-07-28 11:04:54 -04002020
2021#Method void translate(SkScalar dx, SkScalar dy)
2022
Cary Clarkab2621d2018-01-30 10:08:57 -05002023#In Matrix
2024#Line # translates Matrix ##
Cary Clark80247e52018-07-11 16:18:41 -04002025Translates Matrix by dx along the x-axis and dy along the y-axis.
Cary Clark8032b982017-07-28 11:04:54 -04002026
Cary Clark80247e52018-07-11 16:18:41 -04002027Mathematically, replaces Matrix with a translation matrix
Herb Derbyefe39bc2018-05-01 17:06:20 -04002028Premultiplied with Matrix.
Cary Clark8032b982017-07-28 11:04:54 -04002029
2030This has the effect of moving the drawing by (dx, dy) before transforming
2031the result with Matrix.
2032
Cary Clarkbad5ad72017-08-03 17:14:08 -04002033#Param dx distance to translate in x ##
2034#Param dy distance to translate in y ##
Cary Clark8032b982017-07-28 11:04:54 -04002035
2036#Example
2037#Height 128
2038#Description
2039scale() followed by translate() produces different results from translate() followed
Herb Derbyefe39bc2018-05-01 17:06:20 -04002040by scale().
Cary Clark8032b982017-07-28 11:04:54 -04002041
2042The blue stroke follows translate of (50, 50); a black
Herb Derbyefe39bc2018-05-01 17:06:20 -04002043fill follows scale of (2, 1/2.f). After restoring the clip, which resets
Cary Clark8032b982017-07-28 11:04:54 -04002044Matrix, a red frame follows the same scale of (2, 1/2.f); a gray fill
2045follows translate of (50, 50).
2046##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002047void draw(SkCanvas* canvas) {
2048 SkPaint filledPaint;
2049 SkPaint outlinePaint;
2050 outlinePaint.setStyle(SkPaint::kStroke_Style);
2051 outlinePaint.setColor(SK_ColorBLUE);
2052 canvas->save();
2053 canvas->translate(50, 50);
2054 canvas->drawCircle(28, 28, 15, outlinePaint); // blue center: (50+28, 50+28)
2055 canvas->scale(2, 1/2.f);
2056 canvas->drawCircle(28, 28, 15, filledPaint); // black center: (50+(28*2), 50+(28/2))
2057 canvas->restore();
2058 filledPaint.setColor(SK_ColorGRAY);
2059 outlinePaint.setColor(SK_ColorRED);
2060 canvas->scale(2, 1/2.f);
2061 canvas->drawCircle(28, 28, 15, outlinePaint); // red center: (28*2, 28/2)
2062 canvas->translate(50, 50);
2063 canvas->drawCircle(28, 28, 15, filledPaint); // gray center: ((50+28)*2, (50+28)/2)
Cary Clark8032b982017-07-28 11:04:54 -04002064}
2065##
2066
Cary Clark2ade9972017-11-02 17:49:34 -04002067#SeeAlso concat() scale() skew() rotate() setMatrix
Cary Clark8032b982017-07-28 11:04:54 -04002068
2069##
2070
2071# ------------------------------------------------------------------------------
2072
2073#Method void scale(SkScalar sx, SkScalar sy)
2074
Cary Clarkab2621d2018-01-30 10:08:57 -05002075#In Matrix
2076#Line # scales Matrix ##
Cary Clark80247e52018-07-11 16:18:41 -04002077Scales Matrix by sx on the x-axis and sy on the y-axis.
Cary Clark8032b982017-07-28 11:04:54 -04002078
Cary Clark80247e52018-07-11 16:18:41 -04002079Mathematically, replaces Matrix with a scale matrix
Herb Derbyefe39bc2018-05-01 17:06:20 -04002080Premultiplied with Matrix.
Cary Clark8032b982017-07-28 11:04:54 -04002081
2082This has the effect of scaling the drawing by (sx, sy) before transforming
2083the result with Matrix.
2084
Cary Clarkbad5ad72017-08-03 17:14:08 -04002085#Param sx amount to scale in x ##
2086#Param sy amount to scale in y ##
Cary Clark8032b982017-07-28 11:04:54 -04002087
2088#Example
2089#Height 160
Cary Clarkbad5ad72017-08-03 17:14:08 -04002090void draw(SkCanvas* canvas) {
2091 SkPaint paint;
2092 SkRect rect = { 10, 20, 60, 120 };
2093 canvas->translate(20, 20);
2094 canvas->drawRect(rect, paint);
2095 canvas->scale(2, .5f);
2096 paint.setColor(SK_ColorGRAY);
2097 canvas->drawRect(rect, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002098}
2099##
2100
Cary Clark2ade9972017-11-02 17:49:34 -04002101#SeeAlso concat() translate() skew() rotate() setMatrix
Cary Clark8032b982017-07-28 11:04:54 -04002102
2103##
2104
2105# ------------------------------------------------------------------------------
2106
2107#Method void rotate(SkScalar degrees)
2108
Cary Clarkab2621d2018-01-30 10:08:57 -05002109#In Matrix
2110#Line # rotates Matrix ##
Cary Clark80247e52018-07-11 16:18:41 -04002111Rotates Matrix by degrees. Positive degrees rotates clockwise.
Cary Clark8032b982017-07-28 11:04:54 -04002112
Cary Clark80247e52018-07-11 16:18:41 -04002113Mathematically, replaces Matrix with a rotation matrix
Herb Derbyefe39bc2018-05-01 17:06:20 -04002114Premultiplied with Matrix.
Cary Clark8032b982017-07-28 11:04:54 -04002115
2116This has the effect of rotating the drawing by degrees before transforming
2117the result with Matrix.
2118
Cary Clarkbad5ad72017-08-03 17:14:08 -04002119#Param degrees amount to rotate, in degrees ##
Cary Clark8032b982017-07-28 11:04:54 -04002120
2121#Example
2122#Description
2123Draw clock hands at time 5:10. The hour hand and minute hand point up and
2124are rotated clockwise.
2125##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002126void draw(SkCanvas* canvas) {
2127 SkPaint paint;
2128 paint.setStyle(SkPaint::kStroke_Style);
2129 canvas->translate(128, 128);
2130 canvas->drawCircle(0, 0, 60, paint);
2131 canvas->save();
2132 canvas->rotate(10 * 360 / 60); // 10 minutes of 60 scaled to 360 degrees
Herb Derbyefe39bc2018-05-01 17:06:20 -04002133 canvas->drawLine(0, 0, 0, -50, paint);
Cary Clarkbad5ad72017-08-03 17:14:08 -04002134 canvas->restore();
2135 canvas->rotate((5 + 10.f/60) * 360 / 12); // 5 and 10/60 hours of 12 scaled to 360 degrees
2136 canvas->drawLine(0, 0, 0, -30, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002137}
2138##
2139
Cary Clark2ade9972017-11-02 17:49:34 -04002140#SeeAlso concat() translate() skew() scale() setMatrix
Cary Clark8032b982017-07-28 11:04:54 -04002141
2142##
2143
2144# ------------------------------------------------------------------------------
2145
2146#Method void rotate(SkScalar degrees, SkScalar px, SkScalar py)
2147
Cary Clarkab2621d2018-01-30 10:08:57 -05002148#In Matrix
Cary Clark80247e52018-07-11 16:18:41 -04002149Rotates Matrix by degrees about a point at (px, py). Positive degrees rotates
Cary Clarkbad5ad72017-08-03 17:14:08 -04002150clockwise.
Cary Clark8032b982017-07-28 11:04:54 -04002151
Cary Clark80247e52018-07-11 16:18:41 -04002152Mathematically, constructs a rotation matrix; Premultiplies the rotation matrix by
2153a translation matrix; then replaces Matrix with the resulting matrix
Herb Derbyefe39bc2018-05-01 17:06:20 -04002154Premultiplied with Matrix.
Cary Clark8032b982017-07-28 11:04:54 -04002155
Cary Clarkbad5ad72017-08-03 17:14:08 -04002156This has the effect of rotating the drawing about a given point before
2157transforming the result with Matrix.
Cary Clark8032b982017-07-28 11:04:54 -04002158
Cary Clarkbad5ad72017-08-03 17:14:08 -04002159#Param degrees amount to rotate, in degrees ##
Cary Clark5538c132018-06-14 12:28:14 -04002160#Param px x-axis value of the point to rotate about ##
2161#Param py y-axis value of the point to rotate about ##
Cary Clark8032b982017-07-28 11:04:54 -04002162
2163#Example
2164#Height 192
Cary Clarkbad5ad72017-08-03 17:14:08 -04002165void draw(SkCanvas* canvas) {
2166 SkPaint paint;
2167 paint.setTextSize(96);
2168 canvas->drawString("A1", 130, 100, paint);
2169 canvas->rotate(180, 130, 100);
2170 canvas->drawString("A1", 130, 100, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002171}
2172##
2173
Cary Clark2ade9972017-11-02 17:49:34 -04002174#SeeAlso concat() translate() skew() scale() setMatrix
Cary Clark8032b982017-07-28 11:04:54 -04002175
2176##
2177
2178# ------------------------------------------------------------------------------
2179
2180#Method void skew(SkScalar sx, SkScalar sy)
2181
Cary Clarkab2621d2018-01-30 10:08:57 -05002182#In Matrix
2183#Line # skews Matrix ##
Cary Clark80247e52018-07-11 16:18:41 -04002184Skews 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 -04002185skews the drawing right as y-axis values increase; a positive value of sy skews
2186the drawing down as x-axis values increase.
Cary Clark8032b982017-07-28 11:04:54 -04002187
Cary Clark80247e52018-07-11 16:18:41 -04002188Mathematically, replaces Matrix with a skew matrix Premultiplied with Matrix.
Cary Clark8032b982017-07-28 11:04:54 -04002189
Cary Clarkbad5ad72017-08-03 17:14:08 -04002190This has the effect of skewing the drawing by (sx, sy) before transforming
Cary Clark8032b982017-07-28 11:04:54 -04002191the result with Matrix.
2192
Cary Clark5538c132018-06-14 12:28:14 -04002193#Param sx amount to skew on x-axis ##
2194#Param sy amount to skew on y-axis ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002195
Cary Clark8032b982017-07-28 11:04:54 -04002196#Example
Herb Derbyefe39bc2018-05-01 17:06:20 -04002197 #Description
Cary Clark5538c132018-06-14 12:28:14 -04002198 Black text mimics an oblique text style by using a negative skew on x-axis
2199 that shifts the geometry to the right as the y-axis values decrease.
2200 Red text uses a positive skew on y-axis to shift the geometry down
2201 as the x-axis values increase.
2202 Blue text combines sx and sy skew to rotate and scale.
Cary Clark8032b982017-07-28 11:04:54 -04002203 ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002204 SkPaint paint;
2205 paint.setTextSize(128);
2206 canvas->translate(30, 130);
2207 canvas->save();
2208 canvas->skew(-.5, 0);
2209 canvas->drawString("A1", 0, 0, paint);
2210 canvas->restore();
2211 canvas->save();
2212 canvas->skew(0, .5);
2213 paint.setColor(SK_ColorRED);
2214 canvas->drawString("A1", 0, 0, paint);
2215 canvas->restore();
2216 canvas->skew(-.5, .5);
2217 paint.setColor(SK_ColorBLUE);
Cary Clark8032b982017-07-28 11:04:54 -04002218 canvas->drawString("A1", 0, 0, paint);
2219##
2220
Cary Clark2ade9972017-11-02 17:49:34 -04002221#SeeAlso concat() translate() rotate() scale() setMatrix
Cary Clark8032b982017-07-28 11:04:54 -04002222
2223##
2224
2225# ------------------------------------------------------------------------------
2226
2227#Method void concat(const SkMatrix& matrix)
2228
Cary Clarkab2621d2018-01-30 10:08:57 -05002229#In Matrix
2230#Line # multiplies Matrix by Matrix ##
Cary Clark80247e52018-07-11 16:18:41 -04002231Replaces Matrix with matrix Premultiplied with existing Matrix.
Cary Clark8032b982017-07-28 11:04:54 -04002232
Cary Clarkbad5ad72017-08-03 17:14:08 -04002233This has the effect of transforming the drawn geometry by matrix, before
2234transforming the result with existing Matrix.
Cary Clark8032b982017-07-28 11:04:54 -04002235
Cary Clarkce101242017-09-01 15:51:02 -04002236#Param matrix matrix to Premultiply with existing Matrix ##
Cary Clark8032b982017-07-28 11:04:54 -04002237
2238#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04002239void draw(SkCanvas* canvas) {
2240 SkPaint paint;
2241 paint.setTextSize(80);
2242 paint.setTextScaleX(.3);
2243 SkMatrix matrix;
2244 SkRect rect[2] = {{ 10, 20, 90, 110 }, { 40, 130, 140, 180 }};
2245 matrix.setRectToRect(rect[0], rect[1], SkMatrix::kFill_ScaleToFit);
2246 canvas->drawRect(rect[0], paint);
2247 canvas->drawRect(rect[1], paint);
2248 paint.setColor(SK_ColorWHITE);
2249 canvas->drawString("Here", rect[0].fLeft + 10, rect[0].fBottom - 10, paint);
2250 canvas->concat(matrix);
2251 canvas->drawString("There", rect[0].fLeft + 10, rect[0].fBottom - 10, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002252}
2253##
2254
Cary Clark2ade9972017-11-02 17:49:34 -04002255#SeeAlso translate() rotate() scale() skew() setMatrix
Cary Clark8032b982017-07-28 11:04:54 -04002256
2257##
2258
2259# ------------------------------------------------------------------------------
2260
2261#Method void setMatrix(const SkMatrix& matrix)
2262
Cary Clarkab2621d2018-01-30 10:08:57 -05002263#In Matrix
2264#Line # sets Matrix ##
Cary Clark80247e52018-07-11 16:18:41 -04002265Replaces Matrix with matrix.
Cary Clark8032b982017-07-28 11:04:54 -04002266Unlike concat(), any prior matrix state is overwritten.
2267
Cary Clarkbad5ad72017-08-03 17:14:08 -04002268#Param matrix matrix to copy, replacing existing Matrix ##
Cary Clark8032b982017-07-28 11:04:54 -04002269
2270#Example
2271#Height 128
Cary Clarkbad5ad72017-08-03 17:14:08 -04002272void draw(SkCanvas* canvas) {
2273 SkPaint paint;
2274 canvas->scale(4, 6);
2275 canvas->drawString("truth", 2, 10, paint);
2276 SkMatrix matrix;
2277 matrix.setScale(2.8f, 6);
2278 canvas->setMatrix(matrix);
2279 canvas->drawString("consequences", 2, 20, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002280}
2281##
2282
Cary Clark2ade9972017-11-02 17:49:34 -04002283#SeeAlso resetMatrix concat() translate() rotate() scale() skew()
Cary Clark8032b982017-07-28 11:04:54 -04002284
2285##
2286
2287# ------------------------------------------------------------------------------
2288
2289#Method void resetMatrix()
2290
Cary Clarkab2621d2018-01-30 10:08:57 -05002291#In Matrix
2292#Line # resets Matrix to identity ##
Cary Clark8032b982017-07-28 11:04:54 -04002293Sets Matrix to the identity matrix.
2294Any prior matrix state is overwritten.
2295
2296#Example
2297#Height 128
Cary Clarkbad5ad72017-08-03 17:14:08 -04002298void draw(SkCanvas* canvas) {
2299 SkPaint paint;
2300 canvas->scale(4, 6);
2301 canvas->drawString("truth", 2, 10, paint);
2302 canvas->resetMatrix();
2303 canvas->scale(2.8f, 6);
2304 canvas->drawString("consequences", 2, 20, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002305}
2306##
2307
Cary Clark2ade9972017-11-02 17:49:34 -04002308#SeeAlso setMatrix concat() translate() rotate() scale() skew()
Cary Clark8032b982017-07-28 11:04:54 -04002309
2310##
2311
2312# ------------------------------------------------------------------------------
2313
2314#Method const SkMatrix& getTotalMatrix() const
2315
Cary Clarkab2621d2018-01-30 10:08:57 -05002316#In Matrix
2317#Line # returns Matrix ##
Cary Clark8032b982017-07-28 11:04:54 -04002318Returns Matrix.
2319This does not account for translation by Device or Surface.
2320
Cary Clarkbad5ad72017-08-03 17:14:08 -04002321#Return Matrix in Canvas ##
Cary Clark8032b982017-07-28 11:04:54 -04002322
2323#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04002324 SkDebugf("isIdentity %s\n", canvas->getTotalMatrix().isIdentity() ? "true" : "false");
2325 #StdOut
2326 isIdentity true
2327 ##
Cary Clark8032b982017-07-28 11:04:54 -04002328##
2329
Cary Clark2ade9972017-11-02 17:49:34 -04002330#SeeAlso setMatrix resetMatrix concat()
Cary Clark8032b982017-07-28 11:04:54 -04002331
2332##
2333
Cary Clark08895c42018-02-01 09:37:32 -05002334#Subtopic Matrix ##
Cary Clark8032b982017-07-28 11:04:54 -04002335
2336# ------------------------------------------------------------------------------
Cary Clark08895c42018-02-01 09:37:32 -05002337#Subtopic Clip
2338#Line # stack of clipping Paths ##
Cary Clark8032b982017-07-28 11:04:54 -04002339
2340Clip is built from a stack of clipping paths. Each Path in the
Herb Derbyefe39bc2018-05-01 17:06:20 -04002341stack can be constructed from one or more Path_Contour elements. The
Cary Clark8032b982017-07-28 11:04:54 -04002342Path_Contour may be composed of any number of Path_Verb segments. Each
2343Path_Contour forms a closed area; Path_Fill_Type defines the area enclosed
2344by Path_Contour.
2345
2346Clip stack of Path elements successfully restrict the Path area. Each
Herb Derbyefe39bc2018-05-01 17:06:20 -04002347Path is transformed by Matrix, then intersected with or subtracted from the
Cary Clark8032b982017-07-28 11:04:54 -04002348prior Clip to form the replacement Clip. Use SkClipOp::kDifference
2349to subtract Path from Clip; use SkClipOp::kIntersect to intersect Path
2350with Clip.
2351
Cary Clarkffb3d682018-05-17 12:17:28 -04002352A clipping Path may be Anti_Aliased; if Path, after transformation, is
2353composed of horizontal and vertical lines, clearing Anti_Alias allows whole pixels
Cary Clarkce101242017-09-01 15:51:02 -04002354to either be inside or outside the clip. The fastest drawing has a Aliased,
2355rectangular clip.
Cary Clark8032b982017-07-28 11:04:54 -04002356
Cary Clarkffb3d682018-05-17 12:17:28 -04002357If clipping Path has Anti_Alias set, clip may partially clip a pixel, requiring
Herb Derbyefe39bc2018-05-01 17:06:20 -04002358that drawing blend partially with the destination along the edge. A rotated
Cary Clarkffb3d682018-05-17 12:17:28 -04002359rectangular Anti_Aliased clip looks smoother but draws slower.
Cary Clark8032b982017-07-28 11:04:54 -04002360
2361Clip can combine with Rect and Round_Rect primitives; like
2362Path, these are transformed by Matrix before they are combined with Clip.
2363
2364Clip can combine with Region. Region is assumed to be in Device coordinates
2365and is unaffected by Matrix.
2366
2367#Example
2368#Height 90
2369 #Description
Cary Clarkffb3d682018-05-17 12:17:28 -04002370 Draw a red circle with an Aliased clip and an Anti_Aliased clip.
Cary Clark8032b982017-07-28 11:04:54 -04002371 Use an image filter to zoom into the pixels drawn.
Cary Clarkce101242017-09-01 15:51:02 -04002372 The edge of the Aliased clip fully draws pixels in the red circle.
Cary Clarkffb3d682018-05-17 12:17:28 -04002373 The edge of the Anti_Aliased clip partially draws pixels in the red circle.
Cary Clark8032b982017-07-28 11:04:54 -04002374 ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002375 SkPaint redPaint, scalePaint;
2376 redPaint.setAntiAlias(true);
2377 redPaint.setColor(SK_ColorRED);
2378 canvas->save();
2379 for (bool antialias : { false, true } ) {
2380 canvas->save();
2381 canvas->clipRect(SkRect::MakeWH(19.5f, 11.5f), antialias);
2382 canvas->drawCircle(17, 11, 8, redPaint);
2383 canvas->restore();
2384 canvas->translate(16, 0);
2385 }
2386 canvas->restore();
2387 SkMatrix matrix;
2388 matrix.setScale(6, 6);
2389 scalePaint.setImageFilter(
2390 SkImageFilter::MakeMatrixFilter(matrix, kNone_SkFilterQuality, nullptr));
2391 SkCanvas::SaveLayerRec saveLayerRec(
Herb Derbyefe39bc2018-05-01 17:06:20 -04002392 nullptr, &scalePaint, SkCanvas::kInitWithPrevious_SaveLayerFlag);
Cary Clarkbad5ad72017-08-03 17:14:08 -04002393 canvas->saveLayer(saveLayerRec);
Cary Clark8032b982017-07-28 11:04:54 -04002394 canvas->restore();
2395##
2396
2397#Method void clipRect(const SkRect& rect, SkClipOp op, bool doAntiAlias)
2398
Cary Clarkab2621d2018-01-30 10:08:57 -05002399#In Clip
2400#Line # combines Clip with Rect ##
Cary Clark80247e52018-07-11 16:18:41 -04002401Replaces Clip with the intersection or difference of Clip and rect,
Cary Clarkffb3d682018-05-17 12:17:28 -04002402with an Aliased or Anti_Aliased clip edge. rect is transformed by Matrix
Cary Clark8032b982017-07-28 11:04:54 -04002403before it is combined with Clip.
2404
Cary Clarka523d2d2017-08-30 08:58:10 -04002405#Param rect Rect to combine with Clip ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002406#Param op Clip_Op to apply to Clip ##
Cary Clarkffb3d682018-05-17 12:17:28 -04002407#Param doAntiAlias true if Clip is to be Anti_Aliased ##
Cary Clark8032b982017-07-28 11:04:54 -04002408
2409#Example
2410#Height 128
Cary Clarkbad5ad72017-08-03 17:14:08 -04002411void draw(SkCanvas* canvas) {
2412 canvas->rotate(10);
2413 SkPaint paint;
2414 paint.setAntiAlias(true);
2415 for (auto alias: { false, true } ) {
2416 canvas->save();
2417 canvas->clipRect(SkRect::MakeWH(90, 80), SkClipOp::kIntersect, alias);
2418 canvas->drawCircle(100, 60, 60, paint);
2419 canvas->restore();
2420 canvas->translate(80, 0);
2421 }
Cary Clark8032b982017-07-28 11:04:54 -04002422}
2423##
2424
Cary Clark2ade9972017-11-02 17:49:34 -04002425#SeeAlso clipRRect clipPath clipRegion
Cary Clark8032b982017-07-28 11:04:54 -04002426
2427##
2428
Herb Derbyefe39bc2018-05-01 17:06:20 -04002429#Method void clipRect(const SkRect& rect, SkClipOp op)
Cary Clark8032b982017-07-28 11:04:54 -04002430
Cary Clarkab2621d2018-01-30 10:08:57 -05002431#In Clip
Cary Clark80247e52018-07-11 16:18:41 -04002432Replaces Clip with the intersection or difference of Clip and rect.
Cary Clarkce101242017-09-01 15:51:02 -04002433Resulting Clip is Aliased; pixels are fully contained by the clip.
Cary Clarkbad5ad72017-08-03 17:14:08 -04002434rect is transformed by Matrix before it is combined with Clip.
Cary Clark8032b982017-07-28 11:04:54 -04002435
Cary Clarka523d2d2017-08-30 08:58:10 -04002436#Param rect Rect to combine with Clip ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002437#Param op Clip_Op to apply to Clip ##
Cary Clark8032b982017-07-28 11:04:54 -04002438
2439#Example
2440#Height 192
2441#Width 280
Cary Clarkbad5ad72017-08-03 17:14:08 -04002442void draw(SkCanvas* canvas) {
2443 SkPaint paint;
2444 for (SkClipOp op: { SkClipOp::kIntersect, SkClipOp::kDifference } ) {
2445 canvas->save();
2446 canvas->clipRect(SkRect::MakeWH(90, 120), op, false);
2447 canvas->drawCircle(100, 100, 60, paint);
2448 canvas->restore();
2449 canvas->translate(80, 0);
2450 }
Cary Clark8032b982017-07-28 11:04:54 -04002451}
2452##
2453
Cary Clark2ade9972017-11-02 17:49:34 -04002454#SeeAlso clipRRect clipPath clipRegion
Cary Clark8032b982017-07-28 11:04:54 -04002455
2456##
2457
Herb Derbyefe39bc2018-05-01 17:06:20 -04002458#Method void clipRect(const SkRect& rect, bool doAntiAlias = false)
Cary Clark8032b982017-07-28 11:04:54 -04002459
Cary Clarkab2621d2018-01-30 10:08:57 -05002460#In Clip
Cary Clark80247e52018-07-11 16:18:41 -04002461Replaces Clip with the intersection of Clip and rect.
Cary Clarkce101242017-09-01 15:51:02 -04002462Resulting Clip is Aliased; pixels are fully contained by the clip.
Cary Clark8032b982017-07-28 11:04:54 -04002463rect is transformed by Matrix
2464before it is combined with Clip.
2465
Cary Clarka523d2d2017-08-30 08:58:10 -04002466#Param rect Rect to combine with Clip ##
Cary Clarkffb3d682018-05-17 12:17:28 -04002467#Param doAntiAlias true if Clip is to be Anti_Aliased ##
Cary Clark8032b982017-07-28 11:04:54 -04002468
2469#Example
2470#Height 133
2471 #Description
Cary Clarkce101242017-09-01 15:51:02 -04002472 A circle drawn in pieces looks uniform when drawn Aliased.
Cary Clarkffb3d682018-05-17 12:17:28 -04002473 The same circle pieces blend with pixels more than once when Anti_Aliased,
Cary Clark8032b982017-07-28 11:04:54 -04002474 visible as a thin pair of lines through the right circle.
2475 ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002476void draw(SkCanvas* canvas) {
2477 canvas->clear(SK_ColorWHITE);
2478 SkPaint paint;
2479 paint.setAntiAlias(true);
2480 paint.setColor(0x8055aaff);
2481 SkRect clipRect = { 0, 0, 87.4f, 87.4f };
2482 for (auto alias: { false, true } ) {
2483 canvas->save();
2484 canvas->clipRect(clipRect, SkClipOp::kIntersect, alias);
2485 canvas->drawCircle(67, 67, 60, paint);
2486 canvas->restore();
2487 canvas->save();
2488 canvas->clipRect(clipRect, SkClipOp::kDifference, alias);
2489 canvas->drawCircle(67, 67, 60, paint);
2490 canvas->restore();
2491 canvas->translate(120, 0);
2492 }
Cary Clark8032b982017-07-28 11:04:54 -04002493}
2494##
2495
Cary Clark2ade9972017-11-02 17:49:34 -04002496#SeeAlso clipRRect clipPath clipRegion
Cary Clark8032b982017-07-28 11:04:54 -04002497
2498##
2499
2500#Method void androidFramework_setDeviceClipRestriction(const SkIRect& rect)
2501
Cary Clarkab2621d2018-01-30 10:08:57 -05002502#In Clip
Cary Clark682c58d2018-05-16 07:07:07 -04002503#Line # exists for use by Android framework ##
Cary Clarkce101242017-09-01 15:51:02 -04002504Sets the maximum clip rectangle, which can be set by clipRect, clipRRect and
Cary Clark8032b982017-07-28 11:04:54 -04002505clipPath and intersect the current clip with the specified rect.
Cary Clarkce101242017-09-01 15:51:02 -04002506The maximum clip affects only future clipping operations; it is not retroactive.
Cary Clark8032b982017-07-28 11:04:54 -04002507The clip restriction is not recorded in pictures.
2508
Herb Derbyefe39bc2018-05-01 17:06:20 -04002509Pass an empty rect to disable maximum clip.
Cary Clarkbad5ad72017-08-03 17:14:08 -04002510
Cary Clark8032b982017-07-28 11:04:54 -04002511#Private
Cary Clark137b8742018-05-30 09:21:49 -04002512This private API is for use by Android framework only.
Cary Clark8032b982017-07-28 11:04:54 -04002513##
2514
Cary Clarkbad5ad72017-08-03 17:14:08 -04002515#Param rect maximum allowed clip in device coordinates
Cary Clark579985c2017-07-31 11:48:27 -04002516#Param ##
Cary Clark8032b982017-07-28 11:04:54 -04002517
2518##
2519
2520#Method void clipRRect(const SkRRect& rrect, SkClipOp op, bool doAntiAlias)
2521
Cary Clarkab2621d2018-01-30 10:08:57 -05002522#In Clip
2523#Line # combines Clip with Round_Rect ##
Cary Clark80247e52018-07-11 16:18:41 -04002524Replaces Clip with the intersection or difference of Clip and rrect,
Cary Clarkffb3d682018-05-17 12:17:28 -04002525with an Aliased or Anti_Aliased clip edge.
Cary Clark8032b982017-07-28 11:04:54 -04002526rrect is transformed by Matrix
2527before it is combined with Clip.
2528
Cary Clarkbad5ad72017-08-03 17:14:08 -04002529#Param rrect Round_Rect to combine with Clip ##
2530#Param op Clip_Op to apply to Clip ##
Cary Clarkffb3d682018-05-17 12:17:28 -04002531#Param doAntiAlias true if Clip is to be Anti_Aliased ##
Cary Clark8032b982017-07-28 11:04:54 -04002532
2533#Example
2534#Height 128
Cary Clarkbad5ad72017-08-03 17:14:08 -04002535void draw(SkCanvas* canvas) {
2536 canvas->clear(SK_ColorWHITE);
2537 SkPaint paint;
2538 paint.setAntiAlias(true);
2539 paint.setColor(0x8055aaff);
2540 SkRRect oval;
2541 oval.setOval({10, 20, 90, 100});
2542 canvas->clipRRect(oval, SkClipOp::kIntersect, true);
2543 canvas->drawCircle(70, 100, 60, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002544}
2545##
2546
Cary Clark2ade9972017-11-02 17:49:34 -04002547#SeeAlso clipRect clipPath clipRegion
Cary Clark8032b982017-07-28 11:04:54 -04002548
2549##
2550
Herb Derbyefe39bc2018-05-01 17:06:20 -04002551#Method void clipRRect(const SkRRect& rrect, SkClipOp op)
Cary Clark8032b982017-07-28 11:04:54 -04002552
Cary Clarkab2621d2018-01-30 10:08:57 -05002553#In Clip
Cary Clark80247e52018-07-11 16:18:41 -04002554Replaces Clip with the intersection or difference of Clip and rrect.
Cary Clarkce101242017-09-01 15:51:02 -04002555Resulting Clip is Aliased; pixels are fully contained by the clip.
Cary Clarkbad5ad72017-08-03 17:14:08 -04002556rrect is transformed by Matrix before it is combined with Clip.
Cary Clark8032b982017-07-28 11:04:54 -04002557
Cary Clarkbad5ad72017-08-03 17:14:08 -04002558#Param rrect Round_Rect to combine with Clip ##
2559#Param op Clip_Op to apply to Clip ##
Cary Clark8032b982017-07-28 11:04:54 -04002560
2561#Example
2562#Height 128
Cary Clarkbad5ad72017-08-03 17:14:08 -04002563void draw(SkCanvas* canvas) {
2564 SkPaint paint;
2565 paint.setColor(0x8055aaff);
2566 auto oval = SkRRect::MakeOval({10, 20, 90, 100});
2567 canvas->clipRRect(oval, SkClipOp::kIntersect);
2568 canvas->drawCircle(70, 100, 60, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002569}
2570##
2571
Cary Clark2ade9972017-11-02 17:49:34 -04002572#SeeAlso clipRect clipPath clipRegion
Cary Clark8032b982017-07-28 11:04:54 -04002573
2574##
2575
Herb Derbyefe39bc2018-05-01 17:06:20 -04002576#Method void clipRRect(const SkRRect& rrect, bool doAntiAlias = false)
Cary Clark8032b982017-07-28 11:04:54 -04002577
Cary Clarkab2621d2018-01-30 10:08:57 -05002578#In Clip
Cary Clark80247e52018-07-11 16:18:41 -04002579Replaces Clip with the intersection of Clip and rrect,
Cary Clarkffb3d682018-05-17 12:17:28 -04002580with an Aliased or Anti_Aliased clip edge.
Cary Clarkbad5ad72017-08-03 17:14:08 -04002581rrect is transformed by Matrix before it is combined with Clip.
Cary Clark8032b982017-07-28 11:04:54 -04002582
Cary Clarkbad5ad72017-08-03 17:14:08 -04002583#Param rrect Round_Rect to combine with Clip ##
Cary Clarkffb3d682018-05-17 12:17:28 -04002584#Param doAntiAlias true if Clip is to be Anti_Aliased ##
Cary Clark8032b982017-07-28 11:04:54 -04002585
2586#Example
2587#Height 128
Cary Clarkbad5ad72017-08-03 17:14:08 -04002588void draw(SkCanvas* canvas) {
2589 SkPaint paint;
2590 paint.setAntiAlias(true);
2591 auto oval = SkRRect::MakeRectXY({10, 20, 90, 100}, 9, 13);
2592 canvas->clipRRect(oval, true);
2593 canvas->drawCircle(70, 100, 60, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002594}
2595##
2596
Cary Clark2ade9972017-11-02 17:49:34 -04002597#SeeAlso clipRect clipPath clipRegion
Cary Clark8032b982017-07-28 11:04:54 -04002598
2599##
2600
2601#Method void clipPath(const SkPath& path, SkClipOp op, bool doAntiAlias)
2602
Cary Clarkab2621d2018-01-30 10:08:57 -05002603#In Clip
2604#Line # combines Clip with Path ##
Cary Clark80247e52018-07-11 16:18:41 -04002605Replaces Clip with the intersection or difference of Clip and path,
Cary Clarkffb3d682018-05-17 12:17:28 -04002606with an Aliased or Anti_Aliased clip edge. Path_Fill_Type determines if path
Cary Clark8032b982017-07-28 11:04:54 -04002607describes the area inside or outside its contours; and if Path_Contour overlaps
2608itself or another Path_Contour, whether the overlaps form part of the area.
Cary Clarkbad5ad72017-08-03 17:14:08 -04002609path is transformed by Matrix before it is combined with Clip.
Cary Clark8032b982017-07-28 11:04:54 -04002610
Cary Clarkbad5ad72017-08-03 17:14:08 -04002611#Param path Path to combine with Clip ##
2612#Param op Clip_Op to apply to Clip ##
Cary Clarkffb3d682018-05-17 12:17:28 -04002613#Param doAntiAlias true if Clip is to be Anti_Aliased ##
Cary Clark8032b982017-07-28 11:04:54 -04002614
2615#Example
2616#Description
2617Top figure uses SkPath::kInverseWinding_FillType and SkClipOp::kDifference;
2618area outside clip is subtracted from circle.
2619
2620Bottom figure uses SkPath::kWinding_FillType and SkClipOp::kIntersect;
2621area inside clip is intersected with circle.
2622##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002623void draw(SkCanvas* canvas) {
2624 SkPaint paint;
2625 paint.setAntiAlias(true);
2626 SkPath path;
2627 path.addRect({20, 30, 100, 110});
2628 path.setFillType(SkPath::kInverseWinding_FillType);
2629 canvas->save();
2630 canvas->clipPath(path, SkClipOp::kDifference, false);
2631 canvas->drawCircle(70, 100, 60, paint);
2632 canvas->restore();
2633 canvas->translate(100, 100);
2634 path.setFillType(SkPath::kWinding_FillType);
2635 canvas->clipPath(path, SkClipOp::kIntersect, false);
2636 canvas->drawCircle(70, 100, 60, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002637}
2638##
2639
Cary Clark2ade9972017-11-02 17:49:34 -04002640#SeeAlso clipRect clipRRect clipRegion
Cary Clark8032b982017-07-28 11:04:54 -04002641
2642##
2643
Herb Derbyefe39bc2018-05-01 17:06:20 -04002644#Method void clipPath(const SkPath& path, SkClipOp op)
Cary Clark8032b982017-07-28 11:04:54 -04002645
Cary Clarkab2621d2018-01-30 10:08:57 -05002646#In Clip
Cary Clark80247e52018-07-11 16:18:41 -04002647Replaces Clip with the intersection or difference of Clip and path.
Cary Clarkce101242017-09-01 15:51:02 -04002648Resulting Clip is Aliased; pixels are fully contained by the clip.
Cary Clark8032b982017-07-28 11:04:54 -04002649Path_Fill_Type determines if path
2650describes the area inside or outside its contours; and if Path_Contour overlaps
2651itself or another Path_Contour, whether the overlaps form part of the area.
2652path is transformed by Matrix
2653before it is combined with Clip.
2654
Cary Clarkbad5ad72017-08-03 17:14:08 -04002655#Param path Path to combine with Clip ##
2656#Param op Clip_Op to apply to Clip ##
Cary Clark8032b982017-07-28 11:04:54 -04002657
2658#Example
2659#Description
Cary Clarkbc5697d2017-10-04 14:31:33 -04002660Overlapping Rects form a clip. When clip Path_Fill_Type is set to
Herb Derbyefe39bc2018-05-01 17:06:20 -04002661SkPath::kWinding_FillType, the overlap is included. Set to
Cary Clark8032b982017-07-28 11:04:54 -04002662SkPath::kEvenOdd_FillType, the overlap is excluded and forms a hole.
2663##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002664void draw(SkCanvas* canvas) {
2665 SkPaint paint;
2666 paint.setAntiAlias(true);
2667 SkPath path;
2668 path.addRect({20, 15, 100, 95});
2669 path.addRect({50, 65, 130, 135});
2670 path.setFillType(SkPath::kWinding_FillType);
2671 canvas->save();
2672 canvas->clipPath(path, SkClipOp::kIntersect);
2673 canvas->drawCircle(70, 85, 60, paint);
2674 canvas->restore();
2675 canvas->translate(100, 100);
2676 path.setFillType(SkPath::kEvenOdd_FillType);
2677 canvas->clipPath(path, SkClipOp::kIntersect);
2678 canvas->drawCircle(70, 85, 60, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002679}
2680##
2681
Cary Clark2ade9972017-11-02 17:49:34 -04002682#SeeAlso clipRect clipRRect clipRegion
Cary Clark8032b982017-07-28 11:04:54 -04002683
2684##
2685
Herb Derbyefe39bc2018-05-01 17:06:20 -04002686#Method void clipPath(const SkPath& path, bool doAntiAlias = false)
Cary Clark8032b982017-07-28 11:04:54 -04002687
Cary Clarkab2621d2018-01-30 10:08:57 -05002688#In Clip
Cary Clark80247e52018-07-11 16:18:41 -04002689Replaces Clip with the intersection of Clip and path.
Cary Clarkce101242017-09-01 15:51:02 -04002690Resulting Clip is Aliased; pixels are fully contained by the clip.
Cary Clark8032b982017-07-28 11:04:54 -04002691Path_Fill_Type determines if path
2692describes the area inside or outside its contours; and if Path_Contour overlaps
2693itself or another Path_Contour, whether the overlaps form part of the area.
Cary Clarkbad5ad72017-08-03 17:14:08 -04002694path is transformed by Matrix before it is combined with Clip.
Cary Clark8032b982017-07-28 11:04:54 -04002695
Cary Clarkbad5ad72017-08-03 17:14:08 -04002696#Param path Path to combine with Clip ##
Cary Clarkffb3d682018-05-17 12:17:28 -04002697#Param doAntiAlias true if Clip is to be Anti_Aliased ##
Cary Clark8032b982017-07-28 11:04:54 -04002698
2699#Example
2700#Height 212
2701#Description
Herb Derbyefe39bc2018-05-01 17:06:20 -04002702Clip loops over itself covering its center twice. When clip Path_Fill_Type
2703is set to SkPath::kWinding_FillType, the overlap is included. Set to
Cary Clark8032b982017-07-28 11:04:54 -04002704SkPath::kEvenOdd_FillType, the overlap is excluded and forms a hole.
2705##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002706void draw(SkCanvas* canvas) {
2707 SkPaint paint;
2708 paint.setAntiAlias(true);
2709 SkPath path;
2710 SkPoint poly[] = {{20, 20}, { 80, 20}, { 80, 80}, {40, 80},
2711 {40, 40}, {100, 40}, {100, 100}, {20, 100}};
2712 path.addPoly(poly, SK_ARRAY_COUNT(poly), true);
2713 path.setFillType(SkPath::kWinding_FillType);
2714 canvas->save();
2715 canvas->clipPath(path, SkClipOp::kIntersect);
2716 canvas->drawCircle(50, 50, 45, paint);
2717 canvas->restore();
2718 canvas->translate(100, 100);
2719 path.setFillType(SkPath::kEvenOdd_FillType);
2720 canvas->clipPath(path, SkClipOp::kIntersect);
2721 canvas->drawCircle(50, 50, 45, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002722}
2723##
2724
Cary Clark2ade9972017-11-02 17:49:34 -04002725#SeeAlso clipRect clipRRect clipRegion
Cary Clark8032b982017-07-28 11:04:54 -04002726
2727##
2728
2729# ------------------------------------------------------------------------------
2730
Herb Derbyefe39bc2018-05-01 17:06:20 -04002731#Method void setAllowSimplifyClip(bool allow)
Cary Clark8032b982017-07-28 11:04:54 -04002732
Cary Clarkab2621d2018-01-30 10:08:57 -05002733#In Clip
Cary Clark682c58d2018-05-16 07:07:07 -04002734#Experimental testing
Cary Clark8032b982017-07-28 11:04:54 -04002735
Cary Clarkce101242017-09-01 15:51:02 -04002736Set to simplify clip stack using PathOps.
Cary Clark8032b982017-07-28 11:04:54 -04002737
2738##
2739
2740# ------------------------------------------------------------------------------
2741
2742#Method void clipRegion(const SkRegion& deviceRgn, SkClipOp op = SkClipOp::kIntersect)
2743
Cary Clarkab2621d2018-01-30 10:08:57 -05002744#In Clip
2745#Line # combines Clip with Region ##
Cary Clark80247e52018-07-11 16:18:41 -04002746Replaces Clip with the intersection or difference of Clip and Region deviceRgn.
Cary Clarkce101242017-09-01 15:51:02 -04002747Resulting Clip is Aliased; pixels are fully contained by the clip.
Cary Clark8032b982017-07-28 11:04:54 -04002748deviceRgn is unaffected by Matrix.
2749
Cary Clarkbad5ad72017-08-03 17:14:08 -04002750#Param deviceRgn Region to combine with Clip ##
2751#Param op Clip_Op to apply to Clip ##
Cary Clark8032b982017-07-28 11:04:54 -04002752
2753#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04002754#Description
Cary Clarkce101242017-09-01 15:51:02 -04002755 region is unaffected by canvas rotation; iRect is affected by canvas rotation.
2756 Both clips are Aliased; this is not noticeable on Region clip because it
Cary Clarkbad5ad72017-08-03 17:14:08 -04002757 aligns to pixel boundaries.
2758##
2759void draw(SkCanvas* canvas) {
2760 SkPaint paint;
2761 paint.setAntiAlias(true);
2762 SkIRect iRect = {30, 40, 120, 130 };
2763 SkRegion region(iRect);
2764 canvas->rotate(10);
2765 canvas->save();
2766 canvas->clipRegion(region, SkClipOp::kIntersect);
2767 canvas->drawCircle(50, 50, 45, paint);
2768 canvas->restore();
2769 canvas->translate(100, 100);
2770 canvas->clipRect(SkRect::Make(iRect), SkClipOp::kIntersect);
2771 canvas->drawCircle(50, 50, 45, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002772}
2773##
2774
Cary Clark2ade9972017-11-02 17:49:34 -04002775#SeeAlso clipRect clipRRect clipPath
Cary Clark8032b982017-07-28 11:04:54 -04002776
2777##
2778
2779#Method bool quickReject(const SkRect& rect) const
2780
Cary Clarkab2621d2018-01-30 10:08:57 -05002781#In Clip
2782#Line # returns if Rect is outside Clip ##
Cary Clark80247e52018-07-11 16:18:41 -04002783Returns true if Rect rect, transformed by Matrix, can be quickly determined to be
Cary Clark8032b982017-07-28 11:04:54 -04002784outside of Clip. May return false even though rect is outside of Clip.
2785
2786Use to check if an area to be drawn is clipped out, to skip subsequent draw calls.
2787
Cary Clarkbad5ad72017-08-03 17:14:08 -04002788#Param rect Rect to compare with Clip ##
Cary Clark8032b982017-07-28 11:04:54 -04002789
Cary Clarkbad5ad72017-08-03 17:14:08 -04002790#Return true if rect, transformed by Matrix, does not intersect Clip ##
Cary Clark8032b982017-07-28 11:04:54 -04002791
2792#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04002793void draw(SkCanvas* canvas) {
Herb Derbyefe39bc2018-05-01 17:06:20 -04002794 SkRect testRect = {30, 30, 120, 129 };
2795 SkRect clipRect = {30, 130, 120, 230 };
Cary Clarkbad5ad72017-08-03 17:14:08 -04002796 canvas->save();
2797 canvas->clipRect(clipRect);
2798 SkDebugf("quickReject %s\n", canvas->quickReject(testRect) ? "true" : "false");
2799 canvas->restore();
2800 canvas->rotate(10);
2801 canvas->clipRect(clipRect);
2802 SkDebugf("quickReject %s\n", canvas->quickReject(testRect) ? "true" : "false");
Cary Clark8032b982017-07-28 11:04:54 -04002803}
2804 #StdOut
Cary Clarkbad5ad72017-08-03 17:14:08 -04002805 quickReject true
Cary Clark8032b982017-07-28 11:04:54 -04002806 quickReject false
2807 ##
2808##
2809
Cary Clark2ade9972017-11-02 17:49:34 -04002810#SeeAlso getLocalClipBounds getTotalMatrix SkBitmap::drawsNothing
Cary Clark8032b982017-07-28 11:04:54 -04002811
2812##
2813
2814#Method bool quickReject(const SkPath& path) const
2815
Cary Clarkab2621d2018-01-30 10:08:57 -05002816#In Clip
Cary Clark80247e52018-07-11 16:18:41 -04002817Returns true if path, transformed by Matrix, can be quickly determined to be
Cary Clark8032b982017-07-28 11:04:54 -04002818outside of Clip. May return false even though path is outside of Clip.
2819
2820Use to check if an area to be drawn is clipped out, to skip subsequent draw calls.
2821
Cary Clarkbad5ad72017-08-03 17:14:08 -04002822#Param path Path to compare with Clip ##
Cary Clark8032b982017-07-28 11:04:54 -04002823
Cary Clarkbad5ad72017-08-03 17:14:08 -04002824#Return true if path, transformed by Matrix, does not intersect Clip ##
Cary Clark8032b982017-07-28 11:04:54 -04002825
2826#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04002827void draw(SkCanvas* canvas) {
Herb Derbyefe39bc2018-05-01 17:06:20 -04002828 SkPoint testPoints[] = {{30, 30}, {120, 30}, {120, 129} };
2829 SkPoint clipPoints[] = {{30, 130}, {120, 130}, {120, 230} };
Cary Clarkbad5ad72017-08-03 17:14:08 -04002830 SkPath testPath, clipPath;
2831 testPath.addPoly(testPoints, SK_ARRAY_COUNT(testPoints), true);
2832 clipPath.addPoly(clipPoints, SK_ARRAY_COUNT(clipPoints), true);
2833 canvas->save();
2834 canvas->clipPath(clipPath);
2835 SkDebugf("quickReject %s\n", canvas->quickReject(testPath) ? "true" : "false");
2836 canvas->restore();
2837 canvas->rotate(10);
2838 canvas->clipPath(clipPath);
2839 SkDebugf("quickReject %s\n", canvas->quickReject(testPath) ? "true" : "false");
Cary Clark8032b982017-07-28 11:04:54 -04002840 #StdOut
Cary Clarkbad5ad72017-08-03 17:14:08 -04002841 quickReject true
Cary Clark8032b982017-07-28 11:04:54 -04002842 quickReject false
2843 ##
2844}
2845##
2846
Cary Clark2ade9972017-11-02 17:49:34 -04002847#SeeAlso getLocalClipBounds getTotalMatrix SkBitmap::drawsNothing
Cary Clark8032b982017-07-28 11:04:54 -04002848
2849##
2850
Herb Derbyefe39bc2018-05-01 17:06:20 -04002851#Method SkRect getLocalClipBounds() const
Cary Clark8032b982017-07-28 11:04:54 -04002852
Cary Clarkab2621d2018-01-30 10:08:57 -05002853#In Clip
2854#Line # returns Clip bounds in source coordinates ##
Cary Clark80247e52018-07-11 16:18:41 -04002855Returns bounds of Clip, transformed by inverse of Matrix. If Clip is empty,
Cary Clark8032b982017-07-28 11:04:54 -04002856return SkRect::MakeEmpty, where all Rect sides equal zero.
2857
2858Rect returned is outset by one to account for partial pixel coverage if Clip
Cary Clarkffb3d682018-05-17 12:17:28 -04002859is Anti_Aliased.
Cary Clark8032b982017-07-28 11:04:54 -04002860
Cary Clarkbad5ad72017-08-03 17:14:08 -04002861#Return bounds of Clip in local coordinates ##
Cary Clark8032b982017-07-28 11:04:54 -04002862
2863#Example
Herb Derbyefe39bc2018-05-01 17:06:20 -04002864 #Description
Cary Clark8032b982017-07-28 11:04:54 -04002865 Initial bounds is device bounds outset by 1 on all sides.
2866 Clipped bounds is clipPath bounds outset by 1 on all sides.
Cary Clark5538c132018-06-14 12:28:14 -04002867 Scaling the canvas by two on both axes scales the local bounds by 1/2
2868 on both axes.
Cary Clark8032b982017-07-28 11:04:54 -04002869 ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002870 SkCanvas local(256, 256);
2871 canvas = &local;
2872 SkRect bounds = canvas->getLocalClipBounds();
2873 SkDebugf("left:%g top:%g right:%g bottom:%g\n",
2874 bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom);
Herb Derbyefe39bc2018-05-01 17:06:20 -04002875 SkPoint clipPoints[] = {{30, 130}, {120, 130}, {120, 230} };
Cary Clarkbad5ad72017-08-03 17:14:08 -04002876 SkPath clipPath;
2877 clipPath.addPoly(clipPoints, SK_ARRAY_COUNT(clipPoints), true);
2878 canvas->clipPath(clipPath);
2879 bounds = canvas->getLocalClipBounds();
2880 SkDebugf("left:%g top:%g right:%g bottom:%g\n",
2881 bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom);
2882 canvas->scale(2, 2);
2883 bounds = canvas->getLocalClipBounds();
2884 SkDebugf("left:%g top:%g right:%g bottom:%g\n",
2885 bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom);
2886 #StdOut
2887 left:-1 top:-1 right:257 bottom:257
2888 left:29 top:129 right:121 bottom:231
2889 left:14.5 top:64.5 right:60.5 bottom:115.5
2890 ##
Cary Clark8032b982017-07-28 11:04:54 -04002891##
2892
2893# local canvas in example works around bug in fiddle ##
Cary Clark4855f782018-02-06 09:41:53 -05002894#Bug 6524
Cary Clark2ade9972017-11-02 17:49:34 -04002895#SeeAlso getDeviceClipBounds getBaseLayerSize quickReject
Cary Clark8032b982017-07-28 11:04:54 -04002896
2897##
2898
Herb Derbyefe39bc2018-05-01 17:06:20 -04002899#Method bool getLocalClipBounds(SkRect* bounds) const
Cary Clark8032b982017-07-28 11:04:54 -04002900
Cary Clarkab2621d2018-01-30 10:08:57 -05002901#In Clip
Cary Clark80247e52018-07-11 16:18:41 -04002902Returns bounds of Clip, transformed by inverse of Matrix. If Clip is empty,
Cary Clark8032b982017-07-28 11:04:54 -04002903return false, and set bounds to SkRect::MakeEmpty, where all Rect sides equal zero.
2904
2905bounds is outset by one to account for partial pixel coverage if Clip
Cary Clarkffb3d682018-05-17 12:17:28 -04002906is Anti_Aliased.
Cary Clark8032b982017-07-28 11:04:54 -04002907
Cary Clarkbad5ad72017-08-03 17:14:08 -04002908#Param bounds Rect of Clip in local coordinates ##
Cary Clark8032b982017-07-28 11:04:54 -04002909
Cary Clarkbad5ad72017-08-03 17:14:08 -04002910#Return true if Clip bounds is not empty ##
Cary Clark8032b982017-07-28 11:04:54 -04002911
2912#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04002913 void draw(SkCanvas* canvas) {
2914 SkCanvas local(256, 256);
2915 canvas = &local;
2916 SkRect bounds;
2917 SkDebugf("local bounds empty = %s\n", canvas->getLocalClipBounds(&bounds)
2918 ? "false" : "true");
2919 SkPath path;
2920 canvas->clipPath(path);
2921 SkDebugf("local bounds empty = %s\n", canvas->getLocalClipBounds(&bounds)
2922 ? "false" : "true");
Cary Clark8032b982017-07-28 11:04:54 -04002923 }
2924 #StdOut
Cary Clarkbad5ad72017-08-03 17:14:08 -04002925 local bounds empty = false
Cary Clark8032b982017-07-28 11:04:54 -04002926 local bounds empty = true
2927 ##
2928##
2929
2930# local canvas in example works around bug in fiddle ##
Cary Clark4855f782018-02-06 09:41:53 -05002931#Bug 6524
Cary Clark2ade9972017-11-02 17:49:34 -04002932#SeeAlso getDeviceClipBounds getBaseLayerSize quickReject
Cary Clark8032b982017-07-28 11:04:54 -04002933
2934##
2935
Herb Derbyefe39bc2018-05-01 17:06:20 -04002936#Method SkIRect getDeviceClipBounds() const
Cary Clark8032b982017-07-28 11:04:54 -04002937
Cary Clarkab2621d2018-01-30 10:08:57 -05002938#In Clip
2939#Line # returns IRect bounds of Clip ##
Cary Clark80247e52018-07-11 16:18:41 -04002940Returns IRect bounds of Clip, unaffected by Matrix. If Clip is empty,
Cary Clark8032b982017-07-28 11:04:54 -04002941return SkRect::MakeEmpty, where all Rect sides equal zero.
2942
Herb Derbyefe39bc2018-05-01 17:06:20 -04002943Unlike getLocalClipBounds, returned IRect is not outset.
Cary Clark8032b982017-07-28 11:04:54 -04002944
Cary Clarkbad5ad72017-08-03 17:14:08 -04002945#Return bounds of Clip in Device coordinates ##
Cary Clark8032b982017-07-28 11:04:54 -04002946
2947#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04002948void draw(SkCanvas* canvas) {
2949 #Description
Cary Clark8032b982017-07-28 11:04:54 -04002950 Initial bounds is device bounds, not outset.
2951 Clipped bounds is clipPath bounds, not outset.
Cary Clark5538c132018-06-14 12:28:14 -04002952 Scaling the canvas by 1/2 on both axes scales the device bounds by 1/2
2953 on both axes.
Cary Clarkbad5ad72017-08-03 17:14:08 -04002954 ##
2955 SkCanvas device(256, 256);
2956 canvas = &device;
2957 SkIRect bounds = canvas->getDeviceClipBounds();
2958 SkDebugf("left:%d top:%d right:%d bottom:%d\n",
2959 bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom);
Herb Derbyefe39bc2018-05-01 17:06:20 -04002960 SkPoint clipPoints[] = {{30, 130}, {120, 130}, {120, 230} };
Cary Clarkbad5ad72017-08-03 17:14:08 -04002961 SkPath clipPath;
2962 clipPath.addPoly(clipPoints, SK_ARRAY_COUNT(clipPoints), true);
2963 canvas->save();
2964 canvas->clipPath(clipPath);
2965 bounds = canvas->getDeviceClipBounds();
2966 SkDebugf("left:%d top:%d right:%d bottom:%d\n",
2967 bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom);
2968 canvas->restore();
2969 canvas->scale(1.f/2, 1.f/2);
2970 canvas->clipPath(clipPath);
2971 bounds = canvas->getDeviceClipBounds();
2972 SkDebugf("left:%d top:%d right:%d bottom:%d\n",
2973 bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom);
Cary Clark8032b982017-07-28 11:04:54 -04002974 #StdOut
Cary Clarkbad5ad72017-08-03 17:14:08 -04002975 left:0 top:0 right:256 bottom:256
2976 left:30 top:130 right:120 bottom:230
Cary Clark8032b982017-07-28 11:04:54 -04002977 left:15 top:65 right:60 bottom:115
2978 ##
2979}
2980##
2981
2982#ToDo some confusion on why with an identity Matrix local and device are different ##
Cary Clark2ade9972017-11-02 17:49:34 -04002983#SeeAlso getLocalClipBounds getBaseLayerSize quickReject
Cary Clark8032b982017-07-28 11:04:54 -04002984
2985# device canvas in example works around bug in fiddle ##
Cary Clark4855f782018-02-06 09:41:53 -05002986#Bug 6524
Cary Clark8032b982017-07-28 11:04:54 -04002987
2988##
2989
Herb Derbyefe39bc2018-05-01 17:06:20 -04002990#Method bool getDeviceClipBounds(SkIRect* bounds) const
Cary Clark8032b982017-07-28 11:04:54 -04002991
Cary Clarkab2621d2018-01-30 10:08:57 -05002992#In Clip
Cary Clark80247e52018-07-11 16:18:41 -04002993Returns IRect bounds of Clip, unaffected by Matrix. If Clip is empty,
Cary Clark8032b982017-07-28 11:04:54 -04002994return false, and set bounds to SkRect::MakeEmpty, where all Rect sides equal zero.
2995
Herb Derbyefe39bc2018-05-01 17:06:20 -04002996Unlike getLocalClipBounds, bounds is not outset.
Cary Clark8032b982017-07-28 11:04:54 -04002997
Cary Clarkbad5ad72017-08-03 17:14:08 -04002998#Param bounds Rect of Clip in device coordinates ##
Cary Clark8032b982017-07-28 11:04:54 -04002999
Cary Clarkbad5ad72017-08-03 17:14:08 -04003000#Return true if Clip bounds is not empty ##
Cary Clark8032b982017-07-28 11:04:54 -04003001
3002#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003003 void draw(SkCanvas* canvas) {
3004 SkIRect bounds;
3005 SkDebugf("device bounds empty = %s\n", canvas->getDeviceClipBounds(&bounds)
3006 ? "false" : "true");
3007 SkPath path;
3008 canvas->clipPath(path);
3009 SkDebugf("device bounds empty = %s\n", canvas->getDeviceClipBounds(&bounds)
3010 ? "false" : "true");
Cary Clark8032b982017-07-28 11:04:54 -04003011 }
3012 #StdOut
Cary Clarkbad5ad72017-08-03 17:14:08 -04003013 device bounds empty = false
Cary Clark8032b982017-07-28 11:04:54 -04003014 device bounds empty = true
3015 ##
3016##
3017
Cary Clark2ade9972017-11-02 17:49:34 -04003018#SeeAlso getLocalClipBounds getBaseLayerSize quickReject
Cary Clark8032b982017-07-28 11:04:54 -04003019
3020##
3021
Cary Clark08895c42018-02-01 09:37:32 -05003022#Subtopic Clip ##
Cary Clark8032b982017-07-28 11:04:54 -04003023
3024# ------------------------------------------------------------------------------
Cary Clark78de7512018-02-07 07:27:09 -05003025#Subtopic Draw
3026#Populate
3027#Line # draws into Canvas ##
3028##
Cary Clark8032b982017-07-28 11:04:54 -04003029
3030#Method void drawColor(SkColor color, SkBlendMode mode = SkBlendMode::kSrcOver)
Cary Clark78de7512018-02-07 07:27:09 -05003031#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05003032#Line # fills Clip with Color and Blend_Mode ##
Cary Clark80247e52018-07-11 16:18:41 -04003033Fills Clip with Color color.
Cary Clarkffb3d682018-05-17 12:17:28 -04003034mode determines how ARGB is combined with destination.
Cary Clark8032b982017-07-28 11:04:54 -04003035
Cary Clarkffb3d682018-05-17 12:17:28 -04003036#Param color Unpremultiplied ARGB ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003037#Param mode SkBlendMode used to combine source color and destination ##
Cary Clark8032b982017-07-28 11:04:54 -04003038
3039#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003040 canvas->drawColor(SK_ColorRED);
3041 canvas->clipRect(SkRect::MakeWH(150, 150));
3042 canvas->drawColor(SkColorSetARGB(0x80, 0x00, 0xFF, 0x00), SkBlendMode::kPlus);
3043 canvas->clipRect(SkRect::MakeWH(75, 75));
3044 canvas->drawColor(SkColorSetARGB(0x80, 0x00, 0x00, 0xFF), SkBlendMode::kPlus);
Cary Clark8032b982017-07-28 11:04:54 -04003045##
3046
Cary Clark2ade9972017-11-02 17:49:34 -04003047#SeeAlso clear SkBitmap::erase drawPaint
Cary Clark8032b982017-07-28 11:04:54 -04003048
3049##
3050
3051# ------------------------------------------------------------------------------
3052
Herb Derbyefe39bc2018-05-01 17:06:20 -04003053#Method void clear(SkColor color)
Cary Clark78de7512018-02-07 07:27:09 -05003054#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05003055#Line # fills Clip with Color ##
Cary Clark80247e52018-07-11 16:18:41 -04003056Fills Clip with Color color using SkBlendMode::kSrc.
Cary Clark8032b982017-07-28 11:04:54 -04003057This has the effect of replacing all pixels contained by Clip with color.
3058
Cary Clarkffb3d682018-05-17 12:17:28 -04003059#Param color Unpremultiplied ARGB ##
Cary Clark8032b982017-07-28 11:04:54 -04003060
3061#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003062void draw(SkCanvas* canvas) {
3063 canvas->save();
3064 canvas->clipRect(SkRect::MakeWH(256, 128));
Herb Derbyefe39bc2018-05-01 17:06:20 -04003065 canvas->clear(SkColorSetARGB(0x80, 0xFF, 0x00, 0x00));
Cary Clarkbad5ad72017-08-03 17:14:08 -04003066 canvas->restore();
3067 canvas->save();
3068 canvas->clipRect(SkRect::MakeWH(150, 192));
3069 canvas->clear(SkColorSetARGB(0x80, 0x00, 0xFF, 0x00));
3070 canvas->restore();
3071 canvas->clipRect(SkRect::MakeWH(75, 256));
3072 canvas->clear(SkColorSetARGB(0x80, 0x00, 0x00, 0xFF));
Cary Clark8032b982017-07-28 11:04:54 -04003073}
3074##
3075
Cary Clark2ade9972017-11-02 17:49:34 -04003076#SeeAlso drawColor SkBitmap::erase drawPaint
Cary Clark8032b982017-07-28 11:04:54 -04003077
3078##
3079
3080# ------------------------------------------------------------------------------
3081
Herb Derbyefe39bc2018-05-01 17:06:20 -04003082#Method void discard()
Cary Clark78de7512018-02-07 07:27:09 -05003083#In Utility
Cary Clarkab2621d2018-01-30 10:08:57 -05003084#Line # makes Canvas contents undefined ##
Cary Clark80247e52018-07-11 16:18:41 -04003085Makes Canvas contents undefined. Subsequent calls that read Canvas pixels,
Cary Clark8032b982017-07-28 11:04:54 -04003086such as drawing with SkBlendMode, return undefined results. discard() does
3087not change Clip or Matrix.
3088
3089discard() may do nothing, depending on the implementation of Surface or Device
3090that created Canvas.
3091
3092discard() allows optimized performance on subsequent draws by removing
3093cached data associated with Surface or Device.
3094It is not necessary to call discard() once done with Canvas;
3095any cached data is deleted when owning Surface or Device is deleted.
3096
3097#ToDo example? not sure how to make this meaningful w/o more implementation detail ##
Cary Clark2ade9972017-11-02 17:49:34 -04003098#SeeAlso flush() SkSurface::prepareForExternalIO GrContext::abandonContext
Cary Clark8032b982017-07-28 11:04:54 -04003099
Herb Derbyefe39bc2018-05-01 17:06:20 -04003100#NoExample
Cary Clark8032b982017-07-28 11:04:54 -04003101##
3102
3103##
3104
3105# ------------------------------------------------------------------------------
3106
3107#Method void drawPaint(const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05003108#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05003109#Line # fills Clip with Paint ##
Cary Clark80247e52018-07-11 16:18:41 -04003110Fills Clip with Paint paint. Paint components Mask_Filter, Shader,
Cary Clarkbad5ad72017-08-03 17:14:08 -04003111Color_Filter, Image_Filter, and Blend_Mode affect drawing;
3112Path_Effect in paint is ignored.
Cary Clark8032b982017-07-28 11:04:54 -04003113
3114# can Path_Effect in paint ever alter drawPaint?
3115
Cary Clarkbad5ad72017-08-03 17:14:08 -04003116#Param paint graphics state used to fill Canvas ##
Cary Clark8032b982017-07-28 11:04:54 -04003117
3118#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003119void draw(SkCanvas* canvas) {
3120 SkColor colors[] = { SK_ColorRED, SK_ColorGREEN, SK_ColorBLUE };
3121 SkScalar pos[] = { 0, SK_Scalar1/2, SK_Scalar1 };
3122 SkPaint paint;
3123 paint.setShader(SkGradientShader::MakeSweep(256, 256, colors, pos, SK_ARRAY_COUNT(colors)));
3124 canvas->drawPaint(paint);
Cary Clark8032b982017-07-28 11:04:54 -04003125}
3126##
3127
Cary Clark2ade9972017-11-02 17:49:34 -04003128#SeeAlso clear drawColor SkBitmap::erase
Cary Clark8032b982017-07-28 11:04:54 -04003129
3130##
3131
3132# ------------------------------------------------------------------------------
3133
3134#Enum PointMode
Cary Clark08895c42018-02-01 09:37:32 -05003135#Line # sets drawPoints options ##
Cary Clark8032b982017-07-28 11:04:54 -04003136
3137#Code
3138 enum PointMode {
3139 kPoints_PointMode,
3140 kLines_PointMode,
Cary Clarkd0530ba2017-09-14 11:25:39 -04003141 kPolygon_PointMode,
Cary Clark8032b982017-07-28 11:04:54 -04003142 };
3143##
3144
3145Selects if an array of points are drawn as discrete points, as lines, or as
3146an open polygon.
3147
3148#Const kPoints_PointMode 0
Cary Clark682c58d2018-05-16 07:07:07 -04003149#Line # draw each point separately ##
Cary Clark8032b982017-07-28 11:04:54 -04003150##
3151
3152#Const kLines_PointMode 1
Cary Clark682c58d2018-05-16 07:07:07 -04003153#Line # draw each pair of points as a line segment ##
Cary Clark8032b982017-07-28 11:04:54 -04003154##
3155
3156#Const kPolygon_PointMode 2
Cary Clark682c58d2018-05-16 07:07:07 -04003157#Line # draw the array of points as a open polygon ##
Cary Clark8032b982017-07-28 11:04:54 -04003158##
3159
3160#Example
Herb Derbyefe39bc2018-05-01 17:06:20 -04003161 #Description
Cary Clark8032b982017-07-28 11:04:54 -04003162 The upper left corner shows three squares when drawn as points.
3163 The upper right corner shows one line; when drawn as lines, two points are required per line.
3164 The lower right corner shows two lines; when draw as polygon, no miter is drawn at the corner.
3165 The lower left corner shows two lines with a miter when path contains polygon.
3166 ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003167void draw(SkCanvas* canvas) {
3168 SkPaint paint;
3169 paint.setStyle(SkPaint::kStroke_Style);
3170 paint.setStrokeWidth(10);
3171 SkPoint points[] = {{64, 32}, {96, 96}, {32, 96}};
3172 canvas->drawPoints(SkCanvas::kPoints_PointMode, 3, points, paint);
3173 canvas->translate(128, 0);
3174 canvas->drawPoints(SkCanvas::kLines_PointMode, 3, points, paint);
3175 canvas->translate(0, 128);
3176 canvas->drawPoints(SkCanvas::kPolygon_PointMode, 3, points, paint);
3177 SkPath path;
3178 path.addPoly(points, 3, false);
3179 canvas->translate(-128, 0);
3180 canvas->drawPath(path, paint);
Cary Clark8032b982017-07-28 11:04:54 -04003181}
3182##
3183
Cary Clark2ade9972017-11-02 17:49:34 -04003184#SeeAlso drawLine drawPoint drawPath
Cary Clark8032b982017-07-28 11:04:54 -04003185
3186##
3187
3188# ------------------------------------------------------------------------------
3189
3190#Method void drawPoints(PointMode mode, size_t count, const SkPoint pts[], const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05003191#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05003192#Line # draws array as points, lines, polygon ##
Cary Clark80247e52018-07-11 16:18:41 -04003193Draws pts using Clip, Matrix and Paint paint.
Cary Clarkbad5ad72017-08-03 17:14:08 -04003194count is the number of points; if count is less than one, has no effect.
Cary Clark8032b982017-07-28 11:04:54 -04003195mode may be one of: kPoints_PointMode, kLines_PointMode, or kPolygon_PointMode.
3196
Cary Clarkbad5ad72017-08-03 17:14:08 -04003197If mode is kPoints_PointMode, the shape of point drawn depends on paint
3198Paint_Stroke_Cap. If paint is set to SkPaint::kRound_Cap, each point draws a
3199circle of diameter Paint_Stroke_Width. If paint is set to SkPaint::kSquare_Cap
3200or SkPaint::kButt_Cap, each point draws a square of width and height
3201Paint_Stroke_Width.
Cary Clark8032b982017-07-28 11:04:54 -04003202
3203If mode is kLines_PointMode, each pair of points draws a line segment.
3204One line is drawn for every two points; each point is used once. If count is odd,
Herb Derbyefe39bc2018-05-01 17:06:20 -04003205the final point is ignored.
Cary Clark8032b982017-07-28 11:04:54 -04003206
3207If mode is kPolygon_PointMode, each adjacent pair of points draws a line segment.
3208count minus one lines are drawn; the first and last point are used once.
3209
3210Each line segment respects paint Paint_Stroke_Cap and Paint_Stroke_Width.
3211Paint_Style is ignored, as if were set to SkPaint::kStroke_Style.
3212
Cary Clarkbad5ad72017-08-03 17:14:08 -04003213Always draws each element one at a time; is not affected by
3214Paint_Stroke_Join, and unlike drawPath, does not create a mask from all points
Herb Derbyefe39bc2018-05-01 17:06:20 -04003215and lines before drawing.
Cary Clark8032b982017-07-28 11:04:54 -04003216
Cary Clarka523d2d2017-08-30 08:58:10 -04003217#Param mode whether pts draws points or lines ##
3218#Param count number of points in the array ##
3219#Param pts array of points to draw ##
3220#Param paint stroke, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003221
3222#Example
3223#Height 200
Herb Derbyefe39bc2018-05-01 17:06:20 -04003224 #Description
Cary Clark8032b982017-07-28 11:04:54 -04003225 #List
3226 # The first column draws points. ##
3227 # The second column draws points as lines. ##
3228 # The third column draws points as a polygon. ##
3229 # The fourth column draws points as a polygonal path. ##
3230 # The first row uses a round cap and round join. ##
3231 # The second row uses a square cap and a miter join. ##
3232 # The third row uses a butt cap and a bevel join. ##
3233 ##
3234 The transparent color makes multiple line draws visible;
3235 the path is drawn all at once.
3236 ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003237void draw(SkCanvas* canvas) {
3238 SkPaint paint;
3239 paint.setAntiAlias(true);
3240 paint.setStyle(SkPaint::kStroke_Style);
3241 paint.setStrokeWidth(10);
3242 paint.setColor(0x80349a45);
3243 const SkPoint points[] = {{32, 16}, {48, 48}, {16, 32}};
Herb Derbyefe39bc2018-05-01 17:06:20 -04003244 const SkPaint::Join join[] = { SkPaint::kRound_Join,
Cary Clarkbad5ad72017-08-03 17:14:08 -04003245 SkPaint::kMiter_Join,
3246 SkPaint::kBevel_Join };
3247 int joinIndex = 0;
3248 SkPath path;
3249 path.addPoly(points, 3, false);
3250 for (const auto cap : { SkPaint::kRound_Cap, SkPaint::kSquare_Cap, SkPaint::kButt_Cap } ) {
3251 paint.setStrokeCap(cap);
3252 paint.setStrokeJoin(join[joinIndex++]);
3253 for (const auto mode : { SkCanvas::kPoints_PointMode,
3254 SkCanvas::kLines_PointMode,
3255 SkCanvas::kPolygon_PointMode } ) {
3256 canvas->drawPoints(mode, 3, points, paint);
3257 canvas->translate(64, 0);
3258 }
3259 canvas->drawPath(path, paint);
3260 canvas->translate(-192, 64);
3261 }
Cary Clark8032b982017-07-28 11:04:54 -04003262}
3263##
3264
Cary Clark2ade9972017-11-02 17:49:34 -04003265#SeeAlso drawLine drawPoint drawPath
Cary Clark8032b982017-07-28 11:04:54 -04003266
3267##
3268
3269# ------------------------------------------------------------------------------
3270
3271#Method void drawPoint(SkScalar x, SkScalar y, const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05003272#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05003273#Line # draws point at (x, y) position ##
Cary Clark80247e52018-07-11 16:18:41 -04003274Draws point at (x, y) using Clip, Matrix and Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04003275
3276The shape of point drawn depends on paint Paint_Stroke_Cap.
Cary Clarkbad5ad72017-08-03 17:14:08 -04003277If paint is set to SkPaint::kRound_Cap, draw a circle of diameter
Herb Derbyefe39bc2018-05-01 17:06:20 -04003278Paint_Stroke_Width. If paint is set to SkPaint::kSquare_Cap or SkPaint::kButt_Cap,
Cary Clark8032b982017-07-28 11:04:54 -04003279draw a square of width and height Paint_Stroke_Width.
3280Paint_Style is ignored, as if were set to SkPaint::kStroke_Style.
3281
Cary Clarkbad5ad72017-08-03 17:14:08 -04003282#Param x left edge of circle or square ##
3283#Param y top edge of circle or square ##
3284#Param paint stroke, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003285
3286#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003287void draw(SkCanvas* canvas) {
3288 SkPaint paint;
3289 paint.setAntiAlias(true);
3290 paint.setColor(0x80349a45);
3291 paint.setStyle(SkPaint::kStroke_Style);
3292 paint.setStrokeWidth(100);
3293 paint.setStrokeCap(SkPaint::kRound_Cap);
3294 canvas->scale(1, 1.2f);
3295 canvas->drawPoint(64, 96, paint);
3296 canvas->scale(.6f, .8f);
3297 paint.setColor(SK_ColorWHITE);
3298 canvas->drawPoint(106, 120, paint);
Cary Clark8032b982017-07-28 11:04:54 -04003299}
3300##
3301
Cary Clark2ade9972017-11-02 17:49:34 -04003302#SeeAlso drawPoints drawCircle drawRect drawLine drawPath
Cary Clark8032b982017-07-28 11:04:54 -04003303
3304##
3305
Cary Clarkbad5ad72017-08-03 17:14:08 -04003306#Method void drawPoint(SkPoint p, const SkPaint& paint)
3307
Cary Clark80247e52018-07-11 16:18:41 -04003308Draws point p using Clip, Matrix and Paint paint.
Cary Clarkbad5ad72017-08-03 17:14:08 -04003309
3310The shape of point drawn depends on paint Paint_Stroke_Cap.
3311If paint is set to SkPaint::kRound_Cap, draw a circle of diameter
Herb Derbyefe39bc2018-05-01 17:06:20 -04003312Paint_Stroke_Width. If paint is set to SkPaint::kSquare_Cap or SkPaint::kButt_Cap,
Cary Clarkbad5ad72017-08-03 17:14:08 -04003313draw a square of width and height Paint_Stroke_Width.
3314Paint_Style is ignored, as if were set to SkPaint::kStroke_Style.
3315
3316#Param p top-left edge of circle or square ##
3317#Param paint stroke, blend, color, and so on, used to draw ##
3318
3319#Example
3320void draw(SkCanvas* canvas) {
3321 SkPaint paint;
3322 paint.setAntiAlias(true);
3323 paint.setColor(0x80349a45);
3324 paint.setStyle(SkPaint::kStroke_Style);
3325 paint.setStrokeWidth(100);
3326 paint.setStrokeCap(SkPaint::kSquare_Cap);
3327 canvas->scale(1, 1.2f);
3328 canvas->drawPoint({64, 96}, paint);
3329 canvas->scale(.6f, .8f);
3330 paint.setColor(SK_ColorWHITE);
3331 canvas->drawPoint(106, 120, paint);
3332}
3333##
3334
Cary Clark2ade9972017-11-02 17:49:34 -04003335#SeeAlso drawPoints drawCircle drawRect drawLine drawPath
Cary Clarkbad5ad72017-08-03 17:14:08 -04003336
3337##
3338
Cary Clark8032b982017-07-28 11:04:54 -04003339# ------------------------------------------------------------------------------
3340
3341#Method void drawLine(SkScalar x0, SkScalar y0, SkScalar x1, SkScalar y1, const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05003342#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05003343#Line # draws line segment between two points ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003344Draws line segment from (x0, y0) to (x1, y1) using Clip, Matrix, and Paint paint.
3345In paint: Paint_Stroke_Width describes the line thickness;
3346Paint_Stroke_Cap draws the end rounded or square;
Cary Clark8032b982017-07-28 11:04:54 -04003347Paint_Style is ignored, as if were set to SkPaint::kStroke_Style.
3348
Cary Clarkbad5ad72017-08-03 17:14:08 -04003349#Param x0 start of line segment on x-axis ##
3350#Param y0 start of line segment on y-axis ##
3351#Param x1 end of line segment on x-axis ##
3352#Param y1 end of line segment on y-axis ##
3353#Param paint stroke, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003354
3355#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003356 SkPaint paint;
3357 paint.setAntiAlias(true);
3358 paint.setColor(0xFF9a67be);
3359 paint.setStrokeWidth(20);
3360 canvas->skew(1, 0);
3361 canvas->drawLine(32, 96, 32, 160, paint);
3362 canvas->skew(-2, 0);
3363 canvas->drawLine(288, 96, 288, 160, paint);
3364##
3365
Cary Clark2ade9972017-11-02 17:49:34 -04003366#SeeAlso drawPoint drawCircle drawRect drawPath
Cary Clarkbad5ad72017-08-03 17:14:08 -04003367
3368##
3369
3370#Method void drawLine(SkPoint p0, SkPoint p1, const SkPaint& paint)
3371
3372Draws line segment from p0 to p1 using Clip, Matrix, and Paint paint.
3373In paint: Paint_Stroke_Width describes the line thickness;
3374Paint_Stroke_Cap draws the end rounded or square;
3375Paint_Style is ignored, as if were set to SkPaint::kStroke_Style.
3376
3377#Param p0 start of line segment ##
3378#Param p1 end of line segment ##
3379#Param paint stroke, blend, color, and so on, used to draw ##
3380
3381#Example
3382 SkPaint paint;
3383 paint.setAntiAlias(true);
3384 paint.setColor(0xFF9a67be);
3385 paint.setStrokeWidth(20);
3386 canvas->skew(1, 0);
3387 canvas->drawLine({32, 96}, {32, 160}, paint);
3388 canvas->skew(-2, 0);
3389 canvas->drawLine({288, 96}, {288, 160}, paint);
Cary Clark8032b982017-07-28 11:04:54 -04003390##
3391
Cary Clark2ade9972017-11-02 17:49:34 -04003392#SeeAlso drawPoint drawCircle drawRect drawPath
Cary Clark8032b982017-07-28 11:04:54 -04003393
3394##
3395
3396# ------------------------------------------------------------------------------
3397
3398#Method void drawRect(const SkRect& rect, const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05003399#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05003400#Line # draws Rect using Clip, Matrix, and Paint ##
Cary Clark80247e52018-07-11 16:18:41 -04003401Draws Rect rect using Clip, Matrix, and Paint paint.
Herb Derbyefe39bc2018-05-01 17:06:20 -04003402In paint: Paint_Style determines if rectangle is stroked or filled;
Cary Clark8032b982017-07-28 11:04:54 -04003403if stroked, Paint_Stroke_Width describes the line thickness, and
3404Paint_Stroke_Join draws the corners rounded or square.
3405
Cary Clarkbc5697d2017-10-04 14:31:33 -04003406#Param rect rectangle to draw ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003407#Param paint stroke or fill, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003408
3409#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003410void draw(SkCanvas* canvas) {
3411 SkPoint rectPts[] = { {64, 48}, {192, 160} };
3412 SkPaint paint;
3413 paint.setAntiAlias(true);
3414 paint.setStyle(SkPaint::kStroke_Style);
3415 paint.setStrokeWidth(20);
3416 paint.setStrokeJoin(SkPaint::kRound_Join);
3417 SkMatrix rotator;
3418 rotator.setRotate(30, 128, 128);
3419 for (auto color : { SK_ColorRED, SK_ColorBLUE, SK_ColorYELLOW, SK_ColorMAGENTA } ) {
3420 paint.setColor(color);
3421 SkRect rect;
3422 rect.set(rectPts[0], rectPts[1]);
3423 canvas->drawRect(rect, paint);
3424 rotator.mapPoints(rectPts, 2);
3425 }
Cary Clark8032b982017-07-28 11:04:54 -04003426}
3427##
3428
Herb Derbyefe39bc2018-05-01 17:06:20 -04003429#SeeAlso drawIRect drawRRect drawRoundRect drawRegion drawPath drawLine
Cary Clark8032b982017-07-28 11:04:54 -04003430
3431##
3432
3433# ------------------------------------------------------------------------------
3434
Herb Derbyefe39bc2018-05-01 17:06:20 -04003435#Method void drawIRect(const SkIRect& rect, const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05003436#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05003437#Line # draws IRect using Clip, Matrix, and Paint ##
Cary Clark80247e52018-07-11 16:18:41 -04003438Draws IRect rect using Clip, Matrix, and Paint paint.
Herb Derbyefe39bc2018-05-01 17:06:20 -04003439In paint: Paint_Style determines if rectangle is stroked or filled;
Cary Clark8032b982017-07-28 11:04:54 -04003440if stroked, Paint_Stroke_Width describes the line thickness, and
3441Paint_Stroke_Join draws the corners rounded or square.
3442
Cary Clarkbc5697d2017-10-04 14:31:33 -04003443#Param rect rectangle to draw ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003444#Param paint stroke or fill, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003445
3446#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003447 SkIRect rect = { 64, 48, 192, 160 };
3448 SkPaint paint;
3449 paint.setAntiAlias(true);
3450 paint.setStyle(SkPaint::kStroke_Style);
3451 paint.setStrokeWidth(20);
3452 paint.setStrokeJoin(SkPaint::kRound_Join);
3453 for (auto color : { SK_ColorRED, SK_ColorBLUE, SK_ColorYELLOW, SK_ColorMAGENTA } ) {
3454 paint.setColor(color);
3455 canvas->drawIRect(rect, paint);
3456 canvas->rotate(30, 128, 128);
3457 }
Cary Clark8032b982017-07-28 11:04:54 -04003458##
3459
Cary Clark2ade9972017-11-02 17:49:34 -04003460#SeeAlso drawRect drawRRect drawRoundRect drawRegion drawPath drawLine
Cary Clark8032b982017-07-28 11:04:54 -04003461
3462##
3463
3464# ------------------------------------------------------------------------------
3465
3466#Method void drawRegion(const SkRegion& region, const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05003467#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05003468#Line # draws Region using Clip, Matrix, and Paint ##
Cary Clark80247e52018-07-11 16:18:41 -04003469Draws Region region using Clip, Matrix, and Paint paint.
Herb Derbyefe39bc2018-05-01 17:06:20 -04003470In paint: Paint_Style determines if rectangle is stroked or filled;
Cary Clark8032b982017-07-28 11:04:54 -04003471if stroked, Paint_Stroke_Width describes the line thickness, and
3472Paint_Stroke_Join draws the corners rounded or square.
3473
Cary Clarkbc5697d2017-10-04 14:31:33 -04003474#Param region region to draw ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003475#Param paint Paint stroke or fill, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003476
3477#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003478void draw(SkCanvas* canvas) {
3479 SkRegion region;
3480 region.op( 10, 10, 50, 50, SkRegion::kUnion_Op);
3481 region.op( 10, 50, 90, 90, SkRegion::kUnion_Op);
3482 SkPaint paint;
3483 paint.setAntiAlias(true);
3484 paint.setStyle(SkPaint::kStroke_Style);
3485 paint.setStrokeWidth(20);
3486 paint.setStrokeJoin(SkPaint::kRound_Join);
3487 canvas->drawRegion(region, paint);
Cary Clark8032b982017-07-28 11:04:54 -04003488}
3489##
3490
Cary Clark2ade9972017-11-02 17:49:34 -04003491#SeeAlso drawRect drawIRect drawPath
Cary Clark8032b982017-07-28 11:04:54 -04003492
3493##
3494
3495# ------------------------------------------------------------------------------
3496
3497#Method void drawOval(const SkRect& oval, const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05003498#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05003499#Line # draws Oval using Clip, Matrix, and Paint ##
Cary Clark80247e52018-07-11 16:18:41 -04003500Draws Oval oval using Clip, Matrix, and Paint.
Herb Derbyefe39bc2018-05-01 17:06:20 -04003501In paint: Paint_Style determines if Oval is stroked or filled;
Cary Clark8032b982017-07-28 11:04:54 -04003502if stroked, Paint_Stroke_Width describes the line thickness.
3503
Cary Clarkbad5ad72017-08-03 17:14:08 -04003504#Param oval Rect bounds of Oval ##
3505#Param paint Paint stroke or fill, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003506
3507#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003508void draw(SkCanvas* canvas) {
3509 canvas->clear(0xFF3f5f9f);
3510 SkColor kColor1 = SkColorSetARGB(0xff, 0xff, 0x7f, 0);
3511 SkColor g1Colors[] = { kColor1, SkColorSetA(kColor1, 0x20) };
3512 SkPoint g1Points[] = { { 0, 0 }, { 0, 100 } };
3513 SkScalar pos[] = { 0.2f, 1.0f };
3514 SkRect bounds = SkRect::MakeWH(80, 70);
3515 SkPaint paint;
3516 paint.setAntiAlias(true);
3517 paint.setShader(SkGradientShader::MakeLinear(g1Points, g1Colors, pos, SK_ARRAY_COUNT(g1Colors),
3518 SkShader::kClamp_TileMode));
3519 canvas->drawOval(bounds , paint);
Cary Clark8032b982017-07-28 11:04:54 -04003520}
3521##
3522
Cary Clark2ade9972017-11-02 17:49:34 -04003523#SeeAlso drawCircle drawPoint drawPath drawRRect drawRoundRect
Cary Clark8032b982017-07-28 11:04:54 -04003524
3525##
3526
3527# ------------------------------------------------------------------------------
3528
3529#Method void drawRRect(const SkRRect& rrect, const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05003530#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05003531#Line # draws Round_Rect using Clip, Matrix, and Paint ##
Cary Clark80247e52018-07-11 16:18:41 -04003532Draws Round_Rect rrect using Clip, Matrix, and Paint paint.
Herb Derbyefe39bc2018-05-01 17:06:20 -04003533In paint: Paint_Style determines if rrect is stroked or filled;
Cary Clark8032b982017-07-28 11:04:54 -04003534if stroked, Paint_Stroke_Width describes the line thickness.
3535
Cary Clarkbad5ad72017-08-03 17:14:08 -04003536rrect may represent a rectangle, circle, oval, uniformly rounded rectangle, or
3537may have any combination of positive non-square radii for the four corners.
Cary Clark8032b982017-07-28 11:04:54 -04003538
Cary Clarkbad5ad72017-08-03 17:14:08 -04003539#Param rrect Round_Rect with up to eight corner radii to draw ##
3540#Param paint Paint stroke or fill, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003541
3542#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003543void draw(SkCanvas* canvas) {
3544 SkPaint paint;
3545 paint.setAntiAlias(true);
3546 SkRect outer = {30, 40, 210, 220};
3547 SkRect radii = {30, 50, 70, 90 };
3548 SkRRect rRect;
3549 rRect.setNinePatch(outer, radii.fLeft, radii.fTop, radii.fRight, radii.fBottom);
3550 canvas->drawRRect(rRect, paint);
3551 paint.setColor(SK_ColorWHITE);
3552 canvas->drawLine(outer.fLeft + radii.fLeft, outer.fTop,
3553 outer.fLeft + radii.fLeft, outer.fBottom, paint);
Herb Derbyefe39bc2018-05-01 17:06:20 -04003554 canvas->drawLine(outer.fRight - radii.fRight, outer.fTop,
Cary Clarkbad5ad72017-08-03 17:14:08 -04003555 outer.fRight - radii.fRight, outer.fBottom, paint);
Herb Derbyefe39bc2018-05-01 17:06:20 -04003556 canvas->drawLine(outer.fLeft, outer.fTop + radii.fTop,
Cary Clarkbad5ad72017-08-03 17:14:08 -04003557 outer.fRight, outer.fTop + radii.fTop, paint);
Herb Derbyefe39bc2018-05-01 17:06:20 -04003558 canvas->drawLine(outer.fLeft, outer.fBottom - radii.fBottom,
Cary Clarkbad5ad72017-08-03 17:14:08 -04003559 outer.fRight, outer.fBottom - radii.fBottom, paint);
3560}
Cary Clark8032b982017-07-28 11:04:54 -04003561##
3562
Cary Clark2ade9972017-11-02 17:49:34 -04003563#SeeAlso drawRect drawRoundRect drawDRRect drawCircle drawOval drawPath
Cary Clark8032b982017-07-28 11:04:54 -04003564
3565##
3566
3567# ------------------------------------------------------------------------------
3568
3569#Method void drawDRRect(const SkRRect& outer, const SkRRect& inner, const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05003570#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05003571#Line # draws double Round_Rect stroked or filled ##
Cary Clark80247e52018-07-11 16:18:41 -04003572Draws Round_Rect outer and inner
Herb Derbyefe39bc2018-05-01 17:06:20 -04003573using Clip, Matrix, and Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04003574outer must contain inner or the drawing is undefined.
Herb Derbyefe39bc2018-05-01 17:06:20 -04003575In paint: Paint_Style determines if Round_Rect is stroked or filled;
Cary Clark8032b982017-07-28 11:04:54 -04003576if stroked, Paint_Stroke_Width describes the line thickness.
Cary Clarkbad5ad72017-08-03 17:14:08 -04003577If stroked and Round_Rect corner has zero length radii, Paint_Stroke_Join can
Herb Derbyefe39bc2018-05-01 17:06:20 -04003578draw corners rounded or square.
Cary Clark8032b982017-07-28 11:04:54 -04003579
Cary Clarkbad5ad72017-08-03 17:14:08 -04003580GPU-backed platforms optimize drawing when both outer and inner are
Cary Clark8032b982017-07-28 11:04:54 -04003581concave and outer contains inner. These platforms may not be able to draw
Herb Derbyefe39bc2018-05-01 17:06:20 -04003582Path built with identical data as fast.
Cary Clark8032b982017-07-28 11:04:54 -04003583
Cary Clarkbad5ad72017-08-03 17:14:08 -04003584#Param outer Round_Rect outer bounds to draw ##
3585#Param inner Round_Rect inner bounds to draw ##
3586#Param paint Paint stroke or fill, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003587
3588#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003589void draw(SkCanvas* canvas) {
3590 SkRRect outer = SkRRect::MakeRect({20, 40, 210, 200});
3591 SkRRect inner = SkRRect::MakeOval({60, 70, 170, 160});
3592 SkPaint paint;
3593 canvas->drawDRRect(outer, inner, paint);
Cary Clark8032b982017-07-28 11:04:54 -04003594}
3595##
3596
3597#Example
3598#Description
3599 Outer Rect has no corner radii, but stroke join is rounded.
3600 Inner Round_Rect has corner radii; outset stroke increases radii of corners.
3601 Stroke join does not affect inner Round_Rect since it has no sharp corners.
3602##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003603void draw(SkCanvas* canvas) {
3604 SkRRect outer = SkRRect::MakeRect({20, 40, 210, 200});
3605 SkRRect inner = SkRRect::MakeRectXY({60, 70, 170, 160}, 10, 10);
3606 SkPaint paint;
3607 paint.setAntiAlias(true);
3608 paint.setStyle(SkPaint::kStroke_Style);
3609 paint.setStrokeWidth(20);
3610 paint.setStrokeJoin(SkPaint::kRound_Join);
3611 canvas->drawDRRect(outer, inner, paint);
3612 paint.setStrokeWidth(1);
3613 paint.setColor(SK_ColorWHITE);
3614 canvas->drawDRRect(outer, inner, paint);
Cary Clark8032b982017-07-28 11:04:54 -04003615}
3616##
3617
Cary Clark2ade9972017-11-02 17:49:34 -04003618#SeeAlso drawRect drawRoundRect drawRRect drawCircle drawOval drawPath
Cary Clark8032b982017-07-28 11:04:54 -04003619
3620##
3621
3622# ------------------------------------------------------------------------------
3623
3624#Method void drawCircle(SkScalar cx, SkScalar cy, SkScalar radius, const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05003625#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05003626#Line # draws Circle using Clip, Matrix, and Paint ##
Cary Clark80247e52018-07-11 16:18:41 -04003627Draws Circle at (cx, cy) with radius using Clip, Matrix, and Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04003628If radius is zero or less, nothing is drawn.
Herb Derbyefe39bc2018-05-01 17:06:20 -04003629In paint: Paint_Style determines if Circle is stroked or filled;
Cary Clark8032b982017-07-28 11:04:54 -04003630if stroked, Paint_Stroke_Width describes the line thickness.
3631
Cary Clarkbad5ad72017-08-03 17:14:08 -04003632#Param cx Circle center on the x-axis ##
3633#Param cy Circle center on the y-axis ##
3634#Param radius half the diameter of Circle ##
3635#Param paint Paint stroke or fill, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003636
3637#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003638 void draw(SkCanvas* canvas) {
3639 SkPaint paint;
3640 paint.setAntiAlias(true);
3641 canvas->drawCircle(128, 128, 90, paint);
3642 paint.setColor(SK_ColorWHITE);
3643 canvas->drawCircle(86, 86, 20, paint);
3644 canvas->drawCircle(160, 76, 20, paint);
3645 canvas->drawCircle(140, 150, 35, paint);
3646 }
3647##
3648
Cary Clark2ade9972017-11-02 17:49:34 -04003649#SeeAlso drawOval drawRRect drawRoundRect drawPath drawArc drawPoint drawLine
Cary Clarkbad5ad72017-08-03 17:14:08 -04003650
3651##
3652
3653#Method void drawCircle(SkPoint center, SkScalar radius, const SkPaint& paint)
3654
Cary Clark80247e52018-07-11 16:18:41 -04003655Draws Circle at center with radius using Clip, Matrix, and Paint paint.
Cary Clarkbad5ad72017-08-03 17:14:08 -04003656If radius is zero or less, nothing is drawn.
Herb Derbyefe39bc2018-05-01 17:06:20 -04003657In paint: Paint_Style determines if Circle is stroked or filled;
Cary Clarkbad5ad72017-08-03 17:14:08 -04003658if stroked, Paint_Stroke_Width describes the line thickness.
3659
3660#Param center Circle center ##
3661#Param radius half the diameter of Circle ##
3662#Param paint Paint stroke or fill, blend, color, and so on, used to draw ##
3663
3664#Example
3665 void draw(SkCanvas* canvas) {
3666 SkPaint paint;
3667 paint.setAntiAlias(true);
3668 canvas->drawCircle(128, 128, 90, paint);
3669 paint.setColor(SK_ColorWHITE);
3670 canvas->drawCircle({86, 86}, 20, paint);
3671 canvas->drawCircle({160, 76}, 20, paint);
3672 canvas->drawCircle({140, 150}, 35, paint);
3673 }
Cary Clark8032b982017-07-28 11:04:54 -04003674##
3675
Cary Clark2ade9972017-11-02 17:49:34 -04003676#SeeAlso drawOval drawRRect drawRoundRect drawPath drawArc drawPoint drawLine
Cary Clark8032b982017-07-28 11:04:54 -04003677
3678##
3679
3680# ------------------------------------------------------------------------------
3681
3682#Method void drawArc(const SkRect& oval, SkScalar startAngle, SkScalar sweepAngle,
3683 bool useCenter, const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05003684#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05003685#Line # draws Arc using Clip, Matrix, and Paint ##
Cary Clark8032b982017-07-28 11:04:54 -04003686
Cary Clark80247e52018-07-11 16:18:41 -04003687Draws Arc using Clip, Matrix, and Paint paint.
Cary Clarkbad5ad72017-08-03 17:14:08 -04003688
Cary Clark8032b982017-07-28 11:04:54 -04003689Arc is part of Oval bounded by oval, sweeping from startAngle to startAngle plus
3690sweepAngle. startAngle and sweepAngle are in degrees.
Cary Clarkbad5ad72017-08-03 17:14:08 -04003691
Cary Clark8032b982017-07-28 11:04:54 -04003692startAngle of zero places start point at the right middle edge of oval.
3693A positive sweepAngle places Arc end point clockwise from start point;
3694a negative sweepAngle places Arc end point counterclockwise from start point.
3695sweepAngle may exceed 360 degrees, a full circle.
3696If useCenter is true, draw a wedge that includes lines from oval
3697center to Arc end points. If useCenter is false, draw Arc between end points.
3698
3699If Rect oval is empty or sweepAngle is zero, nothing is drawn.
3700
Cary Clarkbad5ad72017-08-03 17:14:08 -04003701#Param oval Rect bounds of Oval containing Arc to draw ##
3702#Param startAngle angle in degrees where Arc begins ##
3703#Param sweepAngle sweep angle in degrees; positive is clockwise ##
3704#Param useCenter if true, include the center of the oval ##
3705#Param paint Paint stroke or fill, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003706
3707#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003708 void draw(SkCanvas* canvas) {
3709 SkPaint paint;
3710 paint.setAntiAlias(true);
3711 SkRect oval = { 4, 4, 60, 60};
3712 for (auto useCenter : { false, true } ) {
3713 for (auto style : { SkPaint::kFill_Style, SkPaint::kStroke_Style } ) {
3714 paint.setStyle(style);
3715 for (auto degrees : { 45, 90, 180, 360} ) {
3716 canvas->drawArc(oval, 0, degrees , useCenter, paint);
3717 canvas->translate(64, 0);
3718 }
3719 canvas->translate(-256, 64);
3720 }
3721 }
Cary Clark8032b982017-07-28 11:04:54 -04003722 }
3723##
3724
3725#Example
3726#Height 64
Cary Clarkbad5ad72017-08-03 17:14:08 -04003727 void draw(SkCanvas* canvas) {
3728 SkPaint paint;
3729 paint.setAntiAlias(true);
3730 paint.setStyle(SkPaint::kStroke_Style);
3731 paint.setStrokeWidth(4);
3732 SkRect oval = { 4, 4, 60, 60};
3733 float intervals[] = { 5, 5 };
3734 paint.setPathEffect(SkDashPathEffect::Make(intervals, 2, 2.5f));
3735 for (auto degrees : { 270, 360, 540, 720 } ) {
3736 canvas->drawArc(oval, 0, degrees, false, paint);
3737 canvas->translate(64, 0);
3738 }
Cary Clark8032b982017-07-28 11:04:54 -04003739 }
3740##
3741
Cary Clark2ade9972017-11-02 17:49:34 -04003742#SeeAlso SkPath::arcTo drawCircle drawOval drawPath
Cary Clark8032b982017-07-28 11:04:54 -04003743
3744##
3745
3746# ------------------------------------------------------------------------------
3747
3748#Method void drawRoundRect(const SkRect& rect, SkScalar rx, SkScalar ry, const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05003749#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05003750#Line # draws Round_Rect using Clip, Matrix, and Paint ##
Cary Clark80247e52018-07-11 16:18:41 -04003751Draws Round_Rect bounded by Rect rect, with corner radii (rx, ry) using Clip,
Cary Clarkbad5ad72017-08-03 17:14:08 -04003752Matrix, and Paint paint.
3753
Herb Derbyefe39bc2018-05-01 17:06:20 -04003754In paint: Paint_Style determines if Round_Rect is stroked or filled;
Cary Clark8032b982017-07-28 11:04:54 -04003755if stroked, Paint_Stroke_Width describes the line thickness.
3756If rx or ry are less than zero, they are treated as if they are zero.
3757If rx plus ry exceeds rect width or rect height, radii are scaled down to fit.
Cary Clarkbad5ad72017-08-03 17:14:08 -04003758If rx and ry are zero, Round_Rect is drawn as Rect and if stroked is affected by
3759Paint_Stroke_Join.
Cary Clark8032b982017-07-28 11:04:54 -04003760
Cary Clarkbad5ad72017-08-03 17:14:08 -04003761#Param rect Rect bounds of Round_Rect to draw ##
Cary Clark5538c132018-06-14 12:28:14 -04003762#Param rx axis length on x-axis of oval describing rounded corners ##
3763#Param ry axis length on y-axis of oval describing rounded corners ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003764#Param paint stroke, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003765
3766#Example
3767#Description
3768 Top row has a zero radius a generates a rectangle.
3769 Second row radii sum to less than sides.
3770 Third row radii sum equals sides.
3771 Fourth row radii sum exceeds sides; radii are scaled to fit.
3772##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003773 void draw(SkCanvas* canvas) {
3774 SkVector radii[] = { {0, 20}, {10, 10}, {10, 20}, {10, 40} };
3775 SkPaint paint;
3776 paint.setStrokeWidth(15);
3777 paint.setStrokeJoin(SkPaint::kRound_Join);
3778 paint.setAntiAlias(true);
3779 for (auto style : { SkPaint::kStroke_Style, SkPaint::kFill_Style } ) {
3780 paint.setStyle(style );
3781 for (size_t i = 0; i < SK_ARRAY_COUNT(radii); ++i) {
3782 canvas->drawRoundRect({10, 10, 60, 40}, radii[i].fX, radii[i].fY, paint);
3783 canvas->translate(0, 60);
3784 }
3785 canvas->translate(80, -240);
3786 }
Cary Clark8032b982017-07-28 11:04:54 -04003787 }
3788##
3789
Cary Clark2ade9972017-11-02 17:49:34 -04003790#SeeAlso DrawRRect drawRect drawDRRect drawPath drawCircle drawOval drawPoint
Cary Clark8032b982017-07-28 11:04:54 -04003791
3792##
3793
3794# ------------------------------------------------------------------------------
3795
3796#Method void drawPath(const SkPath& path, const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05003797#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05003798#Line # draws Path using Clip, Matrix, and Paint ##
Cary Clark80247e52018-07-11 16:18:41 -04003799Draws Path path using Clip, Matrix, and Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04003800Path contains an array of Path_Contour, each of which may be open or closed.
3801
3802In paint: Paint_Style determines if Round_Rect is stroked or filled:
Cary Clarkbad5ad72017-08-03 17:14:08 -04003803if filled, Path_Fill_Type determines whether Path_Contour describes inside or
3804outside of fill; if stroked, Paint_Stroke_Width describes the line thickness,
3805Paint_Stroke_Cap describes line ends, and Paint_Stroke_Join describes how
3806corners are drawn.
Cary Clark8032b982017-07-28 11:04:54 -04003807
Cary Clarkbad5ad72017-08-03 17:14:08 -04003808#Param path Path to draw ##
3809#Param paint stroke, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003810
3811#Example
3812#Description
3813 Top rows draw stroked path with combinations of joins and caps. The open contour
3814 is affected by caps; the closed contour is affected by joins.
Herb Derbyefe39bc2018-05-01 17:06:20 -04003815 Bottom row draws fill the same for open and closed contour.
Cary Clark8032b982017-07-28 11:04:54 -04003816 First bottom column shows winding fills overlap.
3817 Second bottom column shows even odd fills exclude overlap.
3818 Third bottom column shows inverse winding fills area outside both contours.
3819##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003820void draw(SkCanvas* canvas) {
3821 SkPath path;
3822 path.moveTo(20, 20);
3823 path.quadTo(60, 20, 60, 60);
3824 path.close();
3825 path.moveTo(60, 20);
3826 path.quadTo(60, 60, 20, 60);
3827 SkPaint paint;
3828 paint.setStrokeWidth(10);
3829 paint.setAntiAlias(true);
3830 paint.setStyle(SkPaint::kStroke_Style);
3831 for (auto join: { SkPaint::kBevel_Join, SkPaint::kRound_Join, SkPaint::kMiter_Join } ) {
3832 paint.setStrokeJoin(join);
3833 for (auto cap: { SkPaint::kButt_Cap, SkPaint::kSquare_Cap, SkPaint::kRound_Cap } ) {
3834 paint.setStrokeCap(cap);
3835 canvas->drawPath(path, paint);
3836 canvas->translate(80, 0);
3837 }
3838 canvas->translate(-240, 60);
3839 }
3840 paint.setStyle(SkPaint::kFill_Style);
Herb Derbyefe39bc2018-05-01 17:06:20 -04003841 for (auto fill : { SkPath::kWinding_FillType,
3842 SkPath::kEvenOdd_FillType,
Cary Clarkbad5ad72017-08-03 17:14:08 -04003843 SkPath::kInverseWinding_FillType } ) {
3844 path.setFillType(fill);
3845 canvas->save();
3846 canvas->clipRect({0, 10, 80, 70});
3847 canvas->drawPath(path, paint);
3848 canvas->restore();
3849 canvas->translate(80, 0);
3850 }
Cary Clark8032b982017-07-28 11:04:54 -04003851}
3852##
3853
Cary Clark2ade9972017-11-02 17:49:34 -04003854#SeeAlso SkPath drawLine drawArc drawRect drawPoints
Cary Clark8032b982017-07-28 11:04:54 -04003855
3856##
3857
3858# ------------------------------------------------------------------------------
Cary Clark08895c42018-02-01 09:37:32 -05003859#Subtopic Draw_Image
3860#Line # draws Image to Canvas ##
Cary Clark8032b982017-07-28 11:04:54 -04003861
Cary Clarkbad5ad72017-08-03 17:14:08 -04003862drawImage, drawImageRect, and drawImageNine can be called with a bare pointer or
3863a smart pointer as a convenience. The pairs of calls are otherwise identical.
Cary Clark8032b982017-07-28 11:04:54 -04003864
Cary Clark73fa9722017-08-29 17:36:51 -04003865#Method void drawImage(const SkImage* image, SkScalar left, SkScalar top, const SkPaint* paint = nullptr)
Cary Clarkab2621d2018-01-30 10:08:57 -05003866#In Draw_Image
Cary Clark78de7512018-02-07 07:27:09 -05003867#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05003868#Line # draws Image at (x, y) position ##
Cary Clark80247e52018-07-11 16:18:41 -04003869Draws Image image, with its top-left corner at (left, top),
Cary Clark8032b982017-07-28 11:04:54 -04003870using Clip, Matrix, and optional Paint paint.
3871
Cary Clarkbad5ad72017-08-03 17:14:08 -04003872If paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter, Blend_Mode,
3873and Draw_Looper. If image is kAlpha_8_SkColorType, apply Shader.
3874If paint contains Mask_Filter, generate mask from image bounds. If generated
3875mask extends beyond image bounds, replicate image edge colors, just as Shader
3876made from SkImage::makeShader with SkShader::kClamp_TileMode set replicates the
Herb Derbyefe39bc2018-05-01 17:06:20 -04003877image edge color when it samples outside of its bounds.
Cary Clark8032b982017-07-28 11:04:54 -04003878
Cary Clarkbad5ad72017-08-03 17:14:08 -04003879#Param image uncompressed rectangular map of pixels ##
3880#Param left left side of image ##
3881#Param top top side of image ##
3882#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
3883 and so on; or nullptr
3884##
Cary Clark8032b982017-07-28 11:04:54 -04003885
3886#Example
3887#Height 64
3888#Image 4
Cary Clarkbad5ad72017-08-03 17:14:08 -04003889void draw(SkCanvas* canvas) {
3890 // sk_sp<SkImage> image;
3891 SkImage* imagePtr = image.get();
3892 canvas->drawImage(imagePtr, 0, 0);
3893 SkPaint paint;
3894 canvas->drawImage(imagePtr, 80, 0, &paint);
3895 paint.setAlpha(0x80);
3896 canvas->drawImage(imagePtr, 160, 0, &paint);
Cary Clark8032b982017-07-28 11:04:54 -04003897}
3898##
3899
Cary Clark2ade9972017-11-02 17:49:34 -04003900#SeeAlso drawBitmap drawImageLattice drawImageNine drawImageRect SkPaint::setImageFilter
Cary Clark8032b982017-07-28 11:04:54 -04003901
3902##
3903
3904# ------------------------------------------------------------------------------
3905
3906#Method void drawImage(const sk_sp<SkImage>& image, SkScalar left, SkScalar top,
Herb Derbyefe39bc2018-05-01 17:06:20 -04003907 const SkPaint* paint = nullptr)
Cary Clark8032b982017-07-28 11:04:54 -04003908
Cary Clark80247e52018-07-11 16:18:41 -04003909Draws Image image, with its top-left corner at (left, top),
Cary Clark8032b982017-07-28 11:04:54 -04003910using Clip, Matrix, and optional Paint paint.
3911
Cary Clarkbad5ad72017-08-03 17:14:08 -04003912If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
3913Blend_Mode, and Draw_Looper. If image is kAlpha_8_SkColorType, apply Shader.
3914If paint contains Mask_Filter, generate mask from image bounds. If generated
3915mask extends beyond image bounds, replicate image edge colors, just as Shader
3916made from SkImage::makeShader with SkShader::kClamp_TileMode set replicates the
Herb Derbyefe39bc2018-05-01 17:06:20 -04003917image edge color when it samples outside of its bounds.
Cary Clark8032b982017-07-28 11:04:54 -04003918
Cary Clarkbad5ad72017-08-03 17:14:08 -04003919#Param image uncompressed rectangular map of pixels ##
3920#Param left left side of image ##
3921#Param top pop side of image ##
3922#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
3923 and so on; or nullptr
3924##
Cary Clark8032b982017-07-28 11:04:54 -04003925
3926#Example
3927#Height 64
3928#Image 4
Cary Clarkbad5ad72017-08-03 17:14:08 -04003929void draw(SkCanvas* canvas) {
3930 // sk_sp<SkImage> image;
3931 canvas->drawImage(image, 0, 0);
3932 SkPaint paint;
3933 canvas->drawImage(image, 80, 0, &paint);
3934 paint.setAlpha(0x80);
3935 canvas->drawImage(image, 160, 0, &paint);
Cary Clark8032b982017-07-28 11:04:54 -04003936}
3937##
3938
Cary Clark2ade9972017-11-02 17:49:34 -04003939#SeeAlso drawBitmap drawImageLattice drawImageNine drawImageRect SkPaint::setImageFilter
Cary Clark8032b982017-07-28 11:04:54 -04003940
3941##
3942
3943# ------------------------------------------------------------------------------
3944
3945#Enum SrcRectConstraint
Cary Clark08895c42018-02-01 09:37:32 -05003946#Line # sets drawImageRect options ##
Cary Clark8032b982017-07-28 11:04:54 -04003947
3948#Code
3949 enum SrcRectConstraint {
Herb Derbyefe39bc2018-05-01 17:06:20 -04003950 kStrict_SrcRectConstraint,
3951 kFast_SrcRectConstraint,
Cary Clark8032b982017-07-28 11:04:54 -04003952 };
3953##
3954
Cary Clarkce101242017-09-01 15:51:02 -04003955SrcRectConstraint controls the behavior at the edge of source Rect,
3956provided to drawImageRect, trading off speed for precision.
Cary Clark8032b982017-07-28 11:04:54 -04003957
Cary Clarkce101242017-09-01 15:51:02 -04003958Image_Filter in Paint may sample multiple pixels in the image. Source Rect
Cary Clarkbad5ad72017-08-03 17:14:08 -04003959restricts the bounds of pixels that may be read. Image_Filter may slow down if
Herb Derbyefe39bc2018-05-01 17:06:20 -04003960it cannot read outside the bounds, when sampling near the edge of source Rect.
Cary Clark8032b982017-07-28 11:04:54 -04003961SrcRectConstraint specifies whether an Image_Filter is allowed to read pixels
Cary Clarkce101242017-09-01 15:51:02 -04003962outside source Rect.
Cary Clark8032b982017-07-28 11:04:54 -04003963
Cary Clark682c58d2018-05-16 07:07:07 -04003964#Const kStrict_SrcRectConstraint 0
3965#Line # sample only inside bounds; slower ##
Cary Clarkce101242017-09-01 15:51:02 -04003966 Requires Image_Filter to respect source Rect,
Cary Clark8032b982017-07-28 11:04:54 -04003967 sampling only inside of its bounds, possibly with a performance penalty.
3968##
3969
Cary Clark682c58d2018-05-16 07:07:07 -04003970#Const kFast_SrcRectConstraint 1
3971#Line # sample outside bounds; faster ##
Cary Clarkce101242017-09-01 15:51:02 -04003972 Permits Image_Filter to sample outside of source Rect
Cary Clark8032b982017-07-28 11:04:54 -04003973 by half the width of Image_Filter, permitting it to run faster but with
3974 error at the image edges.
3975##
3976
3977#Example
3978#Height 64
3979#Description
3980 redBorder contains a black and white checkerboard bordered by red.
3981 redBorder is drawn scaled by 16 on the left.
Cary Clarkce101242017-09-01 15:51:02 -04003982 The middle and right bitmaps are filtered checkerboards.
Cary Clark8032b982017-07-28 11:04:54 -04003983 Drawing the checkerboard with kStrict_SrcRectConstraint shows only a blur of black and white.
3984 Drawing the checkerboard with kFast_SrcRectConstraint allows red to bleed in the corners.
3985##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003986void draw(SkCanvas* canvas) {
3987 SkBitmap redBorder;
3988 redBorder.allocPixels(SkImageInfo::MakeN32Premul(4, 4));
3989 SkCanvas checkRed(redBorder);
3990 checkRed.clear(SK_ColorRED);
3991 uint32_t checkers[][2] = { { SK_ColorBLACK, SK_ColorWHITE },
3992 { SK_ColorWHITE, SK_ColorBLACK } };
3993 checkRed.writePixels(
3994 SkImageInfo::MakeN32Premul(2, 2), (void*) checkers, sizeof(checkers[0]), 1, 1);
3995 canvas->scale(16, 16);
3996 canvas->drawBitmap(redBorder, 0, 0, nullptr);
3997 canvas->resetMatrix();
3998 sk_sp<SkImage> image = SkImage::MakeFromBitmap(redBorder);
3999 SkPaint lowPaint;
4000 lowPaint.setFilterQuality(kLow_SkFilterQuality);
4001 for (auto constraint : { SkCanvas::kStrict_SrcRectConstraint,
4002 SkCanvas::kFast_SrcRectConstraint } ) {
4003 canvas->translate(80, 0);
4004 canvas->drawImageRect(image.get(), SkRect::MakeLTRB(1, 1, 3, 3),
4005 SkRect::MakeLTRB(16, 16, 48, 48), &lowPaint, constraint);
4006 }
Cary Clark8032b982017-07-28 11:04:54 -04004007}
4008##
4009
Cary Clark2ade9972017-11-02 17:49:34 -04004010#SeeAlso drawImageRect drawImage SkPaint::setImageFilter
Cary Clark8032b982017-07-28 11:04:54 -04004011
4012##
4013
4014# ------------------------------------------------------------------------------
4015
4016#Method void drawImageRect(const SkImage* image, const SkRect& src, const SkRect& dst,
4017 const SkPaint* paint,
4018 SrcRectConstraint constraint = kStrict_SrcRectConstraint)
Cary Clarkab2621d2018-01-30 10:08:57 -05004019#In Draw_Image
Cary Clark78de7512018-02-07 07:27:09 -05004020#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05004021#Line # draws Image, source Rect to destination Rect ##
Cary Clark8032b982017-07-28 11:04:54 -04004022
Cary Clark80247e52018-07-11 16:18:41 -04004023Draws Rect src of Image image, scaled and translated to fill Rect dst.
Cary Clark8032b982017-07-28 11:04:54 -04004024Additionally transform draw using Clip, Matrix, and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004025
Cary Clarkbad5ad72017-08-03 17:14:08 -04004026If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4027Blend_Mode, and Draw_Looper. If image is kAlpha_8_SkColorType, apply Shader.
4028If paint contains Mask_Filter, generate mask from image bounds.
4029
4030If generated mask extends beyond image bounds, replicate image edge colors, just
4031as Shader made from SkImage::makeShader with SkShader::kClamp_TileMode set
Cary Clarkbc5697d2017-10-04 14:31:33 -04004032replicates the image edge color when it samples outside of its bounds.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004033
4034constraint set to kStrict_SrcRectConstraint limits Paint Filter_Quality to
4035sample within src; set to kFast_SrcRectConstraint allows sampling outside to
4036improve performance.
4037
4038#Param image Image containing pixels, dimensions, and format ##
4039#Param src source Rect of image to draw from ##
4040#Param dst destination Rect of image to draw to ##
4041#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4042 and so on; or nullptr
4043##
4044#Param constraint filter strictly within src or draw faster ##
Cary Clark8032b982017-07-28 11:04:54 -04004045
4046#Example
4047#Height 64
4048#Description
4049 The left bitmap draws with Paint default kNone_SkFilterQuality, and stays within
Cary Clarkbc5697d2017-10-04 14:31:33 -04004050 its bounds; there is no bleeding with kFast_SrcRectConstraint.
Cary Clark8032b982017-07-28 11:04:54 -04004051 the middle and right bitmaps draw with kLow_SkFilterQuality; with
4052 kStrict_SrcRectConstraint, the filter remains within the checkerboard, and
4053 with kFast_SrcRectConstraint red bleeds on the edges.
4054##
Cary Clarkbad5ad72017-08-03 17:14:08 -04004055void draw(SkCanvas* canvas) {
Herb Derbyefe39bc2018-05-01 17:06:20 -04004056 uint32_t pixels[][4] = {
Cary Clarkbad5ad72017-08-03 17:14:08 -04004057 { 0xFFFF0000, 0xFFFF0000, 0xFFFF0000, 0xFFFF0000 },
4058 { 0xFFFF0000, 0xFF000000, 0xFFFFFFFF, 0xFFFF0000 },
4059 { 0xFFFF0000, 0xFFFFFFFF, 0xFF000000, 0xFFFF0000 },
4060 { 0xFFFF0000, 0xFFFF0000, 0xFFFF0000, 0xFFFF0000 } };
4061 SkBitmap redBorder;
Herb Derbyefe39bc2018-05-01 17:06:20 -04004062 redBorder.installPixels(SkImageInfo::MakeN32Premul(4, 4),
Cary Clarkbad5ad72017-08-03 17:14:08 -04004063 (void*) pixels, sizeof(pixels[0]));
4064 sk_sp<SkImage> image = SkImage::MakeFromBitmap(redBorder);
4065 SkPaint lowPaint;
4066 for (auto constraint : {
4067 SkCanvas::kFast_SrcRectConstraint,
4068 SkCanvas::kStrict_SrcRectConstraint,
4069 SkCanvas::kFast_SrcRectConstraint } ) {
4070 canvas->drawImageRect(image.get(), SkRect::MakeLTRB(1, 1, 3, 3),
4071 SkRect::MakeLTRB(16, 16, 48, 48), &lowPaint, constraint);
4072 lowPaint.setFilterQuality(kLow_SkFilterQuality);
4073 canvas->translate(80, 0);
4074 }
4075}
Cary Clark8032b982017-07-28 11:04:54 -04004076##
4077
Cary Clark2ade9972017-11-02 17:49:34 -04004078#SeeAlso SrcRectConstraint drawImage drawImageLattice drawImageNine
Cary Clark8032b982017-07-28 11:04:54 -04004079
4080##
4081
4082# ------------------------------------------------------------------------------
4083
4084#Method void drawImageRect(const SkImage* image, const SkIRect& isrc, const SkRect& dst,
4085 const SkPaint* paint, SrcRectConstraint constraint = kStrict_SrcRectConstraint)
Cary Clarkab2621d2018-01-30 10:08:57 -05004086#In Draw_Image
Cary Clark78de7512018-02-07 07:27:09 -05004087#In Draw
Cary Clark8032b982017-07-28 11:04:54 -04004088
Cary Clark80247e52018-07-11 16:18:41 -04004089Draws IRect isrc of Image image, scaled and translated to fill Rect dst.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004090Note that isrc is on integer pixel boundaries; dst may include fractional
4091boundaries. Additionally transform draw using Clip, Matrix, and optional Paint
Herb Derbyefe39bc2018-05-01 17:06:20 -04004092paint.
Cary Clark8032b982017-07-28 11:04:54 -04004093
Cary Clarkbad5ad72017-08-03 17:14:08 -04004094If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4095Blend_Mode, and Draw_Looper. If image is kAlpha_8_SkColorType, apply Shader.
4096If paint contains Mask_Filter, generate mask from image bounds.
4097
4098If generated mask extends beyond image bounds, replicate image edge colors, just
4099as Shader made from SkImage::makeShader with SkShader::kClamp_TileMode set
Cary Clarkbc5697d2017-10-04 14:31:33 -04004100replicates the image edge color when it samples outside of its bounds.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004101
4102constraint set to kStrict_SrcRectConstraint limits Paint Filter_Quality to
Cary Clarkce101242017-09-01 15:51:02 -04004103sample within isrc; set to kFast_SrcRectConstraint allows sampling outside to
Cary Clarkbad5ad72017-08-03 17:14:08 -04004104improve performance.
4105
4106#Param image Image containing pixels, dimensions, and format ##
4107#Param isrc source IRect of image to draw from ##
4108#Param dst destination Rect of image to draw to ##
4109#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4110 and so on; or nullptr
4111##
Cary Clarkce101242017-09-01 15:51:02 -04004112#Param constraint filter strictly within isrc or draw faster ##
Cary Clark8032b982017-07-28 11:04:54 -04004113
4114#Example
4115#Image 4
Cary Clarkbad5ad72017-08-03 17:14:08 -04004116void draw(SkCanvas* canvas) {
4117 // sk_sp<SkImage> image;
4118 for (auto i : { 1, 2, 4, 8 } ) {
Herb Derbyefe39bc2018-05-01 17:06:20 -04004119 canvas->drawImageRect(image.get(), SkIRect::MakeLTRB(0, 0, 100, 100),
Cary Clarkbad5ad72017-08-03 17:14:08 -04004120 SkRect::MakeXYWH(i * 20, i * 20, i * 20, i * 20), nullptr);
4121 }
Cary Clark8032b982017-07-28 11:04:54 -04004122}
4123##
4124
Cary Clark2ade9972017-11-02 17:49:34 -04004125#SeeAlso SrcRectConstraint drawImage drawImageLattice drawImageNine
Cary Clark8032b982017-07-28 11:04:54 -04004126
4127##
4128
4129# ------------------------------------------------------------------------------
4130
4131#Method void drawImageRect(const SkImage* image, const SkRect& dst, const SkPaint* paint,
4132 SrcRectConstraint constraint = kStrict_SrcRectConstraint)
Cary Clarkab2621d2018-01-30 10:08:57 -05004133#In Draw_Image
Cary Clark78de7512018-02-07 07:27:09 -05004134#In Draw
Cary Clark8032b982017-07-28 11:04:54 -04004135
Cary Clark80247e52018-07-11 16:18:41 -04004136Draws Image image, scaled and translated to fill Rect dst, using Clip, Matrix,
Cary Clarkbad5ad72017-08-03 17:14:08 -04004137and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004138
Cary Clarkbad5ad72017-08-03 17:14:08 -04004139If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4140Blend_Mode, and Draw_Looper. If image is kAlpha_8_SkColorType, apply Shader.
4141If paint contains Mask_Filter, generate mask from image bounds.
4142
4143If generated mask extends beyond image bounds, replicate image edge colors, just
4144as Shader made from SkImage::makeShader with SkShader::kClamp_TileMode set
Cary Clarkbc5697d2017-10-04 14:31:33 -04004145replicates the image edge color when it samples outside of its bounds.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004146
4147constraint set to kStrict_SrcRectConstraint limits Paint Filter_Quality to
Cary Clarkce101242017-09-01 15:51:02 -04004148sample within image; set to kFast_SrcRectConstraint allows sampling outside to
Cary Clarkbad5ad72017-08-03 17:14:08 -04004149improve performance.
4150
4151#Param image Image containing pixels, dimensions, and format ##
4152#Param dst destination Rect of image to draw to ##
4153#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4154 and so on; or nullptr
4155##
Cary Clarkce101242017-09-01 15:51:02 -04004156#Param constraint filter strictly within image or draw faster ##
Cary Clark8032b982017-07-28 11:04:54 -04004157
4158#Example
4159#Image 4
Cary Clarkbad5ad72017-08-03 17:14:08 -04004160void draw(SkCanvas* canvas) {
4161 // sk_sp<SkImage> image;
4162 for (auto i : { 20, 40, 80, 160 } ) {
4163 canvas->drawImageRect(image.get(), SkRect::MakeXYWH(i, i, i, i), nullptr);
4164 }
Cary Clark8032b982017-07-28 11:04:54 -04004165}
4166##
4167
Cary Clark2ade9972017-11-02 17:49:34 -04004168#SeeAlso SrcRectConstraint drawImage drawImageLattice drawImageNine
Cary Clark8032b982017-07-28 11:04:54 -04004169
4170##
4171
4172# ------------------------------------------------------------------------------
4173
4174#Method void drawImageRect(const sk_sp<SkImage>& image, const SkRect& src, const SkRect& dst,
4175 const SkPaint* paint,
Herb Derbyefe39bc2018-05-01 17:06:20 -04004176 SrcRectConstraint constraint = kStrict_SrcRectConstraint)
Cary Clarkab2621d2018-01-30 10:08:57 -05004177#In Draw_Image
Cary Clark78de7512018-02-07 07:27:09 -05004178#In Draw
Cary Clark80247e52018-07-11 16:18:41 -04004179Draws Rect src of Image image, scaled and translated to fill Rect dst.
Cary Clark8032b982017-07-28 11:04:54 -04004180Additionally transform draw using Clip, Matrix, and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004181
Cary Clarkbad5ad72017-08-03 17:14:08 -04004182If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4183Blend_Mode, and Draw_Looper. If image is kAlpha_8_SkColorType, apply Shader.
4184If paint contains Mask_Filter, generate mask from image bounds.
4185
4186If generated mask extends beyond image bounds, replicate image edge colors, just
4187as Shader made from SkImage::makeShader with SkShader::kClamp_TileMode set
Cary Clarkbc5697d2017-10-04 14:31:33 -04004188replicates the image edge color when it samples outside of its bounds.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004189
4190constraint set to kStrict_SrcRectConstraint limits Paint Filter_Quality to
4191sample within src; set to kFast_SrcRectConstraint allows sampling outside to
4192improve performance.
4193
4194#Param image Image containing pixels, dimensions, and format ##
4195#Param src source Rect of image to draw from ##
4196#Param dst destination Rect of image to draw to ##
4197#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4198 and so on; or nullptr
4199##
4200#Param constraint filter strictly within src or draw faster ##
Cary Clark8032b982017-07-28 11:04:54 -04004201
4202#Example
4203#Height 64
4204#Description
4205 Canvas scales and translates; transformation from src to dst also scales.
4206 The two matrices are concatenated to create the final transformation.
4207##
Cary Clarkbad5ad72017-08-03 17:14:08 -04004208void draw(SkCanvas* canvas) {
4209 uint32_t pixels[][2] = { { SK_ColorBLACK, SK_ColorWHITE },
4210 { SK_ColorWHITE, SK_ColorBLACK } };
4211 SkBitmap bitmap;
Herb Derbyefe39bc2018-05-01 17:06:20 -04004212 bitmap.installPixels(SkImageInfo::MakeN32Premul(2, 2),
Cary Clarkbad5ad72017-08-03 17:14:08 -04004213 (void*) pixels, sizeof(pixels[0]));
4214 sk_sp<SkImage> image = SkImage::MakeFromBitmap(bitmap);
4215 SkPaint paint;
4216 canvas->scale(4, 4);
4217 for (auto alpha : { 50, 100, 150, 255 } ) {
4218 paint.setAlpha(alpha);
4219 canvas->drawImageRect(image, SkRect::MakeWH(2, 2), SkRect::MakeWH(8, 8), &paint);
4220 canvas->translate(8, 0);
4221 }
4222}
Cary Clark8032b982017-07-28 11:04:54 -04004223##
4224
Cary Clark2ade9972017-11-02 17:49:34 -04004225#SeeAlso SrcRectConstraint drawImage drawImageLattice drawImageNine
Cary Clark8032b982017-07-28 11:04:54 -04004226
4227##
4228
4229# ------------------------------------------------------------------------------
4230
4231#Method void drawImageRect(const sk_sp<SkImage>& image, const SkIRect& isrc, const SkRect& dst,
Herb Derbyefe39bc2018-05-01 17:06:20 -04004232 const SkPaint* paint, SrcRectConstraint constraint = kStrict_SrcRectConstraint)
Cary Clarkab2621d2018-01-30 10:08:57 -05004233#In Draw_Image
Cary Clark78de7512018-02-07 07:27:09 -05004234#In Draw
Cary Clark80247e52018-07-11 16:18:41 -04004235Draws IRect isrc of Image image, scaled and translated to fill Rect dst.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004236isrc is on integer pixel boundaries; dst may include fractional boundaries.
Cary Clark8032b982017-07-28 11:04:54 -04004237Additionally transform draw using Clip, Matrix, and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004238
Cary Clarkbad5ad72017-08-03 17:14:08 -04004239If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4240Blend_Mode, and Draw_Looper. If image is kAlpha_8_SkColorType, apply Shader.
4241If paint contains Mask_Filter, generate mask from image bounds.
4242
4243If generated mask extends beyond image bounds, replicate image edge colors, just
4244as Shader made from SkImage::makeShader with SkShader::kClamp_TileMode set
Cary Clarkbc5697d2017-10-04 14:31:33 -04004245replicates the image edge color when it samples outside of its bounds.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004246
4247constraint set to kStrict_SrcRectConstraint limits Paint Filter_Quality to
Cary Clarkce101242017-09-01 15:51:02 -04004248sample within image; set to kFast_SrcRectConstraint allows sampling outside to
Cary Clarkbad5ad72017-08-03 17:14:08 -04004249improve performance.
4250
4251#Param image Image containing pixels, dimensions, and format ##
4252#Param isrc source IRect of image to draw from ##
4253#Param dst destination Rect of image to draw to ##
4254#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4255 and so on; or nullptr
4256##
Cary Clarkce101242017-09-01 15:51:02 -04004257#Param constraint filter strictly within image or draw faster ##
Cary Clark8032b982017-07-28 11:04:54 -04004258
4259#Example
4260#Height 64
Cary Clarkbad5ad72017-08-03 17:14:08 -04004261void draw(SkCanvas* canvas) {
4262 uint32_t pixels[][2] = { { 0x00000000, 0x55555555},
4263 { 0xAAAAAAAA, 0xFFFFFFFF} };
4264 SkBitmap bitmap;
Herb Derbyefe39bc2018-05-01 17:06:20 -04004265 bitmap.installPixels(SkImageInfo::MakeN32Premul(2, 2),
Cary Clarkbad5ad72017-08-03 17:14:08 -04004266 (void*) pixels, sizeof(pixels[0]));
4267 sk_sp<SkImage> image = SkImage::MakeFromBitmap(bitmap);
4268 SkPaint paint;
4269 canvas->scale(4, 4);
4270 for (auto color : { SK_ColorRED, SK_ColorBLUE, SK_ColorGREEN } ) {
4271 paint.setColorFilter(SkColorFilter::MakeModeFilter(color, SkBlendMode::kPlus));
4272 canvas->drawImageRect(image, SkIRect::MakeWH(2, 2), SkRect::MakeWH(8, 8), &paint);
4273 canvas->translate(8, 0);
4274 }
Cary Clark8032b982017-07-28 11:04:54 -04004275}
4276##
4277
Cary Clark2ade9972017-11-02 17:49:34 -04004278#SeeAlso SrcRectConstraint drawImage drawImageLattice drawImageNine
4279
Cary Clark8032b982017-07-28 11:04:54 -04004280##
4281
4282# ------------------------------------------------------------------------------
4283
4284#Method void drawImageRect(const sk_sp<SkImage>& image, const SkRect& dst, const SkPaint* paint,
Herb Derbyefe39bc2018-05-01 17:06:20 -04004285 SrcRectConstraint constraint = kStrict_SrcRectConstraint)
Cary Clarkab2621d2018-01-30 10:08:57 -05004286#In Draw_Image
Cary Clark78de7512018-02-07 07:27:09 -05004287#In Draw
Cary Clark80247e52018-07-11 16:18:41 -04004288Draws Image image, scaled and translated to fill Rect dst,
Cary Clark8032b982017-07-28 11:04:54 -04004289using Clip, Matrix, and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004290
Cary Clarkbad5ad72017-08-03 17:14:08 -04004291If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4292Blend_Mode, and Draw_Looper. If image is kAlpha_8_SkColorType, apply Shader.
4293If paint contains Mask_Filter, generate mask from image bounds.
4294
4295If generated mask extends beyond image bounds, replicate image edge colors, just
4296as Shader made from SkImage::makeShader with SkShader::kClamp_TileMode set
Cary Clarkbc5697d2017-10-04 14:31:33 -04004297replicates the image edge color when it samples outside of its bounds.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004298
4299constraint set to kStrict_SrcRectConstraint limits Paint Filter_Quality to
Cary Clarkce101242017-09-01 15:51:02 -04004300sample within image; set to kFast_SrcRectConstraint allows sampling outside to
Cary Clarkbad5ad72017-08-03 17:14:08 -04004301improve performance.
4302
4303#Param image Image containing pixels, dimensions, and format ##
4304#Param dst destination Rect of image to draw to ##
4305#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4306 and so on; or nullptr
4307##
Cary Clarkce101242017-09-01 15:51:02 -04004308#Param constraint filter strictly within image or draw faster ##
Cary Clark8032b982017-07-28 11:04:54 -04004309
4310#Example
4311#Height 64
Cary Clarkbad5ad72017-08-03 17:14:08 -04004312void draw(SkCanvas* canvas) {
4313 uint32_t pixels[][2] = { { 0x00000000, 0x55550000},
4314 { 0xAAAA0000, 0xFFFF0000} };
4315 SkBitmap bitmap;
Herb Derbyefe39bc2018-05-01 17:06:20 -04004316 bitmap.installPixels(SkImageInfo::MakeN32Premul(2, 2),
Cary Clarkbad5ad72017-08-03 17:14:08 -04004317 (void*) pixels, sizeof(pixels[0]));
4318 sk_sp<SkImage> image = SkImage::MakeFromBitmap(bitmap);
4319 SkPaint paint;
4320 canvas->scale(4, 4);
4321 for (auto color : { SK_ColorRED, SK_ColorBLUE, SK_ColorGREEN } ) {
4322 paint.setColorFilter(SkColorFilter::MakeModeFilter(color, SkBlendMode::kPlus));
4323 canvas->drawImageRect(image, SkRect::MakeWH(8, 8), &paint);
4324 canvas->translate(8, 0);
4325 }
Cary Clark8032b982017-07-28 11:04:54 -04004326}
4327##
4328
Cary Clark2ade9972017-11-02 17:49:34 -04004329#SeeAlso SrcRectConstraint drawImage drawImageLattice drawImageNine
Cary Clark8032b982017-07-28 11:04:54 -04004330
4331##
4332
4333# ------------------------------------------------------------------------------
4334
4335#Method void drawImageNine(const SkImage* image, const SkIRect& center, const SkRect& dst,
4336 const SkPaint* paint = nullptr)
Cary Clarkab2621d2018-01-30 10:08:57 -05004337#In Draw_Image
Cary Clark78de7512018-02-07 07:27:09 -05004338#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05004339#Line # draws Nine_Patch Image ##
Cary Clark8032b982017-07-28 11:04:54 -04004340
Cary Clark80247e52018-07-11 16:18:41 -04004341Draws Image image stretched proportionally to fit into Rect dst.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004342IRect center divides the image into nine sections: four sides, four corners, and
Cary Clarkce101242017-09-01 15:51:02 -04004343the center. Corners are unmodified or scaled down proportionately if their sides
Cary Clarkbad5ad72017-08-03 17:14:08 -04004344are larger than dst; center and four sides are scaled to fit remaining space, if any.
Cary Clark8032b982017-07-28 11:04:54 -04004345
Cary Clarkbad5ad72017-08-03 17:14:08 -04004346Additionally transform draw using Clip, Matrix, and optional Paint paint.
4347
Cary Clark682c58d2018-05-16 07:07:07 -04004348#paint_as_used_by_draw_lattice_or_draw_nine(image)#
Cary Clarkbad5ad72017-08-03 17:14:08 -04004349
4350If generated mask extends beyond image bounds, replicate image edge colors, just
4351as Shader made from SkImage::makeShader with SkShader::kClamp_TileMode set
Cary Clarkbc5697d2017-10-04 14:31:33 -04004352replicates the image edge color when it samples outside of its bounds.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004353
4354#Param image Image containing pixels, dimensions, and format ##
4355#Param center IRect edge of image corners and sides ##
4356#Param dst destination Rect of image to draw to ##
4357#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4358 and so on; or nullptr
4359##
Cary Clark8032b982017-07-28 11:04:54 -04004360
4361#Example
4362#Height 128
4363#Description
4364 The leftmost image is smaller than center; only corners are drawn, all scaled to fit.
Cary Clarkce101242017-09-01 15:51:02 -04004365 The second image equals the size of center; only corners are drawn without scaling.
4366 The remaining images are larger than center. All corners draw without scaling.
4367 The sides and center are scaled if needed to take up the remaining space.
Cary Clark8032b982017-07-28 11:04:54 -04004368##
Cary Clarkbad5ad72017-08-03 17:14:08 -04004369void draw(SkCanvas* canvas) {
4370 SkIRect center = { 20, 10, 50, 40 };
4371 SkBitmap bitmap;
4372 bitmap.allocPixels(SkImageInfo::MakeN32Premul(60, 60));
4373 SkCanvas bitCanvas(bitmap);
4374 SkPaint paint;
4375 SkColor gray = 0xFF000000;
4376 int left = 0;
4377 for (auto right: { center.fLeft, center.fRight, bitmap.width() } ) {
4378 int top = 0;
4379 for (auto bottom: { center.fTop, center.fBottom, bitmap.height() } ) {
4380 paint.setColor(gray);
4381 bitCanvas.drawIRect(SkIRect::MakeLTRB(left, top, right, bottom), paint);
4382 gray += 0x001f1f1f;
4383 top = bottom;
4384 }
Herb Derbyefe39bc2018-05-01 17:06:20 -04004385 left = right;
Cary Clarkbad5ad72017-08-03 17:14:08 -04004386 }
4387 sk_sp<SkImage> image = SkImage::MakeFromBitmap(bitmap);
4388 SkImage* imagePtr = image.get();
4389 for (auto dest: { 20, 30, 40, 60, 90 } ) {
4390 canvas->drawImageNine(imagePtr, center, SkRect::MakeWH(dest, dest), nullptr);
4391 canvas->translate(dest + 4, 0);
4392 }
Cary Clark8032b982017-07-28 11:04:54 -04004393}
4394##
4395
Cary Clark2ade9972017-11-02 17:49:34 -04004396#SeeAlso drawImage drawBitmapNine drawImageLattice drawImageRect
Cary Clark8032b982017-07-28 11:04:54 -04004397
4398##
4399
4400# ------------------------------------------------------------------------------
4401
4402#Method void drawImageNine(const sk_sp<SkImage>& image, const SkIRect& center, const SkRect& dst,
Herb Derbyefe39bc2018-05-01 17:06:20 -04004403 const SkPaint* paint = nullptr)
Cary Clarkab2621d2018-01-30 10:08:57 -05004404#In Draw_Image
Cary Clark78de7512018-02-07 07:27:09 -05004405#In Draw
Cary Clark80247e52018-07-11 16:18:41 -04004406Draws Image image stretched proportionally to fit into Rect dst.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004407IRect center divides the image into nine sections: four sides, four corners, and
Cary Clarkce101242017-09-01 15:51:02 -04004408the center. Corners are not scaled, or scaled down proportionately if their sides
Cary Clarkbad5ad72017-08-03 17:14:08 -04004409are larger than dst; center and four sides are scaled to fit remaining space, if any.
Cary Clark8032b982017-07-28 11:04:54 -04004410
Cary Clarkbad5ad72017-08-03 17:14:08 -04004411Additionally transform draw using Clip, Matrix, and optional Paint paint.
4412
Cary Clark137b8742018-05-30 09:21:49 -04004413#paint_as_used_by_draw_lattice_or_draw_nine(image)#
Cary Clarkbad5ad72017-08-03 17:14:08 -04004414
4415If generated mask extends beyond image bounds, replicate image edge colors, just
4416as Shader made from SkImage::makeShader with SkShader::kClamp_TileMode set
Cary Clarkbc5697d2017-10-04 14:31:33 -04004417replicates the image edge color when it samples outside of its bounds.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004418
4419#Param image Image containing pixels, dimensions, and format ##
4420#Param center IRect edge of image corners and sides ##
4421#Param dst destination Rect of image to draw to ##
4422#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4423 and so on; or nullptr
4424##
Cary Clark8032b982017-07-28 11:04:54 -04004425
4426#Example
4427#Height 128
4428#Description
4429 The two leftmost images has four corners and sides to the left and right of center.
4430 The leftmost image scales the width of corners proportionately to fit.
Herb Derbyefe39bc2018-05-01 17:06:20 -04004431 The third and fourth image corners are not scaled; the sides and center are scaled to
Cary Clark8032b982017-07-28 11:04:54 -04004432 fill the remaining space.
4433 The rightmost image has four corners scaled vertically to fit, and uses sides above
4434 and below center to fill the remaining space.
4435##
Cary Clarkbad5ad72017-08-03 17:14:08 -04004436void draw(SkCanvas* canvas) {
4437 SkIRect center = { 20, 10, 50, 40 };
4438 SkBitmap bitmap;
4439 bitmap.allocPixels(SkImageInfo::MakeN32Premul(60, 60));
4440 SkCanvas bitCanvas(bitmap);
4441 SkPaint paint;
4442 SkColor gray = 0xFF000000;
4443 int left = 0;
4444 for (auto right: { center.fLeft, center.fRight, bitmap.width() } ) {
4445 int top = 0;
4446 for (auto bottom: { center.fTop, center.fBottom, bitmap.height() } ) {
4447 paint.setColor(gray);
4448 bitCanvas.drawIRect(SkIRect::MakeLTRB(left, top, right, bottom), paint);
4449 gray += 0x001f1f1f;
4450 top = bottom;
4451 }
Herb Derbyefe39bc2018-05-01 17:06:20 -04004452 left = right;
Cary Clarkbad5ad72017-08-03 17:14:08 -04004453 }
4454 sk_sp<SkImage> image = SkImage::MakeFromBitmap(bitmap);
4455 for (auto dest: { 20, 30, 40, 60, 90 } ) {
4456 canvas->drawImageNine(image, center, SkRect::MakeWH(dest, 110 - dest), nullptr);
4457 canvas->translate(dest + 4, 0);
4458 }
Cary Clark8032b982017-07-28 11:04:54 -04004459}
4460##
4461
Cary Clark2ade9972017-11-02 17:49:34 -04004462#SeeAlso drawImage drawBitmapNine drawImageLattice drawImageRect
Cary Clark8032b982017-07-28 11:04:54 -04004463
4464##
4465
4466# ------------------------------------------------------------------------------
4467
4468#Method void drawBitmap(const SkBitmap& bitmap, SkScalar left, SkScalar top,
Cary Clark73fa9722017-08-29 17:36:51 -04004469 const SkPaint* paint = nullptr)
Cary Clarkab2621d2018-01-30 10:08:57 -05004470#In Draw_Image
Cary Clark78de7512018-02-07 07:27:09 -05004471#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05004472#Line # draws Bitmap at (x, y) position ##
Cary Clark8032b982017-07-28 11:04:54 -04004473
Cary Clark80247e52018-07-11 16:18:41 -04004474Draws Bitmap bitmap, with its top-left corner at (left, top),
Cary Clark8032b982017-07-28 11:04:54 -04004475using Clip, Matrix, and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004476
Cary Clarka560c472017-11-27 10:44:06 -05004477If Paint paint is not nullptr, apply Color_Filter, Color_Alpha, Image_Filter,
Cary Clarkbad5ad72017-08-03 17:14:08 -04004478Blend_Mode, and Draw_Looper. If bitmap is kAlpha_8_SkColorType, apply Shader.
4479If paint contains Mask_Filter, generate mask from bitmap bounds.
4480
4481If generated mask extends beyond bitmap bounds, replicate bitmap edge colors,
4482just as Shader made from SkShader::MakeBitmapShader with
Cary Clarkbc5697d2017-10-04 14:31:33 -04004483SkShader::kClamp_TileMode set replicates the bitmap edge color when it samples
Herb Derbyefe39bc2018-05-01 17:06:20 -04004484outside of its bounds.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004485
4486#Param bitmap Bitmap containing pixels, dimensions, and format ##
4487#Param left left side of bitmap ##
4488#Param top top side of bitmap ##
4489#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4490 and so on; or nullptr
4491##
Cary Clark8032b982017-07-28 11:04:54 -04004492
4493#Example
4494#Height 64
Cary Clarkbad5ad72017-08-03 17:14:08 -04004495void draw(SkCanvas* canvas) {
4496 uint8_t pixels[][8] = { { 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00},
4497 { 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00},
4498 { 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00},
4499 { 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF},
4500 { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
4501 { 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00},
4502 { 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0x00},
4503 { 0xFF, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0xFF} };
4504 SkBitmap bitmap;
Herb Derbyefe39bc2018-05-01 17:06:20 -04004505 bitmap.installPixels(SkImageInfo::MakeA8(8, 8),
Cary Clarkbad5ad72017-08-03 17:14:08 -04004506 (void*) pixels, sizeof(pixels[0]));
4507 SkPaint paint;
4508 canvas->scale(4, 4);
4509 for (auto color : { SK_ColorRED, SK_ColorBLUE, 0xFF007F00} ) {
4510 paint.setColor(color);
4511 canvas->drawBitmap(bitmap, 0, 0, &paint);
4512 canvas->translate(12, 0);
4513 }
Cary Clark8032b982017-07-28 11:04:54 -04004514}
4515##
4516
Cary Clark2ade9972017-11-02 17:49:34 -04004517#SeeAlso drawImage drawBitmapLattice drawBitmapNine drawBitmapRect SkBitmap::readPixels SkBitmap::writePixels
Cary Clark8032b982017-07-28 11:04:54 -04004518
4519##
4520
4521# ------------------------------------------------------------------------------
4522
4523#Method void drawBitmapRect(const SkBitmap& bitmap, const SkRect& src, const SkRect& dst,
4524 const SkPaint* paint, SrcRectConstraint constraint = kStrict_SrcRectConstraint)
Cary Clarkab2621d2018-01-30 10:08:57 -05004525#In Draw_Image
Cary Clark78de7512018-02-07 07:27:09 -05004526#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05004527#Line # draws Bitmap, source Rect to destination Rect ##
Cary Clark8032b982017-07-28 11:04:54 -04004528
Cary Clark80247e52018-07-11 16:18:41 -04004529Draws Rect src of Bitmap bitmap, scaled and translated to fill Rect dst.
Cary Clark8032b982017-07-28 11:04:54 -04004530Additionally transform draw using Clip, Matrix, and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004531
Cary Clarkbad5ad72017-08-03 17:14:08 -04004532If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4533Blend_Mode, and Draw_Looper. If bitmap is kAlpha_8_SkColorType, apply Shader.
4534If paint contains Mask_Filter, generate mask from bitmap bounds.
4535
4536If generated mask extends beyond bitmap bounds, replicate bitmap edge colors,
4537just as Shader made from SkShader::MakeBitmapShader with
Cary Clarkbc5697d2017-10-04 14:31:33 -04004538SkShader::kClamp_TileMode set replicates the bitmap edge color when it samples
Cary Clarkbad5ad72017-08-03 17:14:08 -04004539outside of its bounds.
4540
4541constraint set to kStrict_SrcRectConstraint limits Paint Filter_Quality to
4542sample within src; set to kFast_SrcRectConstraint allows sampling outside to
4543improve performance.
4544
4545#Param bitmap Bitmap containing pixels, dimensions, and format ##
4546#Param src source Rect of image to draw from ##
4547#Param dst destination Rect of image to draw to ##
4548#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4549 and so on; or nullptr
4550##
4551#Param constraint filter strictly within src or draw faster ##
Cary Clark8032b982017-07-28 11:04:54 -04004552
4553#Example
4554#Height 64
Cary Clarkbad5ad72017-08-03 17:14:08 -04004555void draw(SkCanvas* canvas) {
4556 uint8_t pixels[][8] = { { 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00},
4557 { 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00},
4558 { 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00},
4559 { 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF},
4560 { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
4561 { 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00},
4562 { 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00},
4563 { 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00} };
4564 SkBitmap bitmap;
Herb Derbyefe39bc2018-05-01 17:06:20 -04004565 bitmap.installPixels(SkImageInfo::MakeA8(8, 8),
Cary Clarkbad5ad72017-08-03 17:14:08 -04004566 (void*) pixels, sizeof(pixels[0]));
4567 SkPaint paint;
Cary Clark681287e2018-03-16 11:34:15 -04004568 paint.setMaskFilter(SkMaskFilter::MakeBlur(kSolid_SkBlurStyle, 6));
Cary Clarkbad5ad72017-08-03 17:14:08 -04004569 for (auto color : { SK_ColorRED, SK_ColorBLUE, 0xFF007F00} ) {
4570 paint.setColor(color);
4571 canvas->drawBitmapRect(bitmap, SkRect::MakeWH(8, 8), SkRect::MakeWH(32, 32), &paint);
4572 canvas->translate(48, 0);
4573 }
Cary Clark8032b982017-07-28 11:04:54 -04004574}
4575##
4576
Cary Clark2ade9972017-11-02 17:49:34 -04004577#SeeAlso drawImageRect drawBitmap drawBitmapLattice drawBitmapNine
Cary Clark8032b982017-07-28 11:04:54 -04004578
4579##
4580
4581# ------------------------------------------------------------------------------
4582
4583#Method void drawBitmapRect(const SkBitmap& bitmap, const SkIRect& isrc, const SkRect& dst,
4584 const SkPaint* paint, SrcRectConstraint constraint = kStrict_SrcRectConstraint)
Cary Clarkab2621d2018-01-30 10:08:57 -05004585#In Draw_Image
Cary Clark78de7512018-02-07 07:27:09 -05004586#In Draw
Cary Clark80247e52018-07-11 16:18:41 -04004587Draws IRect isrc of Bitmap bitmap, scaled and translated to fill Rect dst.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004588isrc is on integer pixel boundaries; dst may include fractional boundaries.
Cary Clark8032b982017-07-28 11:04:54 -04004589Additionally transform draw using Clip, Matrix, and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004590
Cary Clarkbad5ad72017-08-03 17:14:08 -04004591If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4592Blend_Mode, and Draw_Looper. If bitmap is kAlpha_8_SkColorType, apply Shader.
4593If paint contains Mask_Filter, generate mask from bitmap bounds.
4594
4595If generated mask extends beyond bitmap bounds, replicate bitmap edge colors,
4596just as Shader made from SkShader::MakeBitmapShader with
Cary Clarkbc5697d2017-10-04 14:31:33 -04004597SkShader::kClamp_TileMode set replicates the bitmap edge color when it samples
Cary Clarkbad5ad72017-08-03 17:14:08 -04004598outside of its bounds.
4599
4600constraint set to kStrict_SrcRectConstraint limits Paint Filter_Quality to
Cary Clarkce101242017-09-01 15:51:02 -04004601sample within isrc; set to kFast_SrcRectConstraint allows sampling outside to
Cary Clarkbad5ad72017-08-03 17:14:08 -04004602improve performance.
4603
4604#Param bitmap Bitmap containing pixels, dimensions, and format ##
4605#Param isrc source IRect of image to draw from ##
4606#Param dst destination Rect of image to draw to ##
4607#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4608 and so on; or nullptr
4609##
Cary Clarkce101242017-09-01 15:51:02 -04004610#Param constraint sample strictly within isrc, or draw faster ##
Cary Clark8032b982017-07-28 11:04:54 -04004611
4612#Example
4613#Height 64
Cary Clarkbad5ad72017-08-03 17:14:08 -04004614void draw(SkCanvas* canvas) {
4615 uint8_t pixels[][8] = { { 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00},
4616 { 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00},
4617 { 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0xFF},
4618 { 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0xFF},
4619 { 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF},
4620 { 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF},
4621 { 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00},
4622 { 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00} };
4623 SkBitmap bitmap;
Herb Derbyefe39bc2018-05-01 17:06:20 -04004624 bitmap.installPixels(SkImageInfo::MakeA8(8, 8),
Cary Clarkbad5ad72017-08-03 17:14:08 -04004625 (void*) pixels, sizeof(pixels[0]));
4626 SkPaint paint;
4627 paint.setFilterQuality(kHigh_SkFilterQuality);
4628 for (auto color : { SK_ColorRED, SK_ColorBLUE, 0xFF007F00, 0xFF7f007f} ) {
4629 paint.setColor(color);
4630 canvas->drawBitmapRect(bitmap, SkIRect::MakeWH(8, 8), SkRect::MakeWH(32, 32), &paint);
4631 canvas->translate(48.25f, 0);
4632 }
Cary Clark8032b982017-07-28 11:04:54 -04004633}
4634##
4635
Cary Clark2ade9972017-11-02 17:49:34 -04004636#SeeAlso drawImageRect drawBitmap drawBitmapLattice drawBitmapNine
Cary Clark8032b982017-07-28 11:04:54 -04004637
4638##
4639
4640# ------------------------------------------------------------------------------
4641
4642#Method void drawBitmapRect(const SkBitmap& bitmap, const SkRect& dst, const SkPaint* paint,
4643 SrcRectConstraint constraint = kStrict_SrcRectConstraint)
Cary Clarkab2621d2018-01-30 10:08:57 -05004644#In Draw_Image
Cary Clark78de7512018-02-07 07:27:09 -05004645#In Draw
Cary Clark80247e52018-07-11 16:18:41 -04004646Draws Bitmap bitmap, scaled and translated to fill Rect dst.
Cary Clarkce101242017-09-01 15:51:02 -04004647bitmap bounds is on integer pixel boundaries; dst may include fractional boundaries.
Cary Clark8032b982017-07-28 11:04:54 -04004648Additionally transform draw using Clip, Matrix, and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004649
Cary Clarkbad5ad72017-08-03 17:14:08 -04004650If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4651Blend_Mode, and Draw_Looper. If bitmap is kAlpha_8_SkColorType, apply Shader.
4652If paint contains Mask_Filter, generate mask from bitmap bounds.
4653
4654If generated mask extends beyond bitmap bounds, replicate bitmap edge colors,
4655just as Shader made from SkShader::MakeBitmapShader with
Cary Clarkbc5697d2017-10-04 14:31:33 -04004656SkShader::kClamp_TileMode set replicates the bitmap edge color when it samples
Cary Clarkbad5ad72017-08-03 17:14:08 -04004657outside of its bounds.
4658
4659constraint set to kStrict_SrcRectConstraint limits Paint Filter_Quality to
Cary Clarkce101242017-09-01 15:51:02 -04004660sample within bitmap; set to kFast_SrcRectConstraint allows sampling outside to
Cary Clarkbad5ad72017-08-03 17:14:08 -04004661improve performance.
4662
4663#Param bitmap Bitmap containing pixels, dimensions, and format ##
4664#Param dst destination Rect of image to draw to ##
4665#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4666 and so on; or nullptr
4667##
Cary Clarkce101242017-09-01 15:51:02 -04004668#Param constraint filter strictly within bitmap or draw faster ##
Cary Clark8032b982017-07-28 11:04:54 -04004669
4670#Example
4671#Height 64
Cary Clarkbad5ad72017-08-03 17:14:08 -04004672void draw(SkCanvas* canvas) {
4673 uint32_t pixels[][2] = { { 0x00000000, 0x55550000},
4674 { 0xAAAA0000, 0xFFFF0000} };
4675 SkBitmap bitmap;
Herb Derbyefe39bc2018-05-01 17:06:20 -04004676 bitmap.installPixels(SkImageInfo::MakeN32Premul(2, 2),
Cary Clarkbad5ad72017-08-03 17:14:08 -04004677 (void*) pixels, sizeof(pixels[0]));
4678 SkPaint paint;
4679 canvas->scale(4, 4);
4680 for (auto color : { SK_ColorRED, SK_ColorBLUE, SK_ColorGREEN } ) {
4681 paint.setColorFilter(SkColorFilter::MakeModeFilter(color, SkBlendMode::kPlus));
4682 canvas->drawBitmapRect(bitmap, SkRect::MakeWH(8, 8), &paint);
4683 canvas->translate(8, 0);
4684 }
Cary Clark8032b982017-07-28 11:04:54 -04004685}
4686##
4687
Cary Clark2ade9972017-11-02 17:49:34 -04004688#SeeAlso drawImageRect drawBitmap drawBitmapLattice drawBitmapNine
Cary Clark8032b982017-07-28 11:04:54 -04004689
4690##
4691
4692# ------------------------------------------------------------------------------
4693
Cary Clark682c58d2018-05-16 07:07:07 -04004694#PhraseDef paint_as_used_by_draw_lattice_or_draw_nine(bitmap_or_image)
4695If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4696Blend_Mode, and Draw_Looper. If #bitmap_or_image# is kAlpha_8_SkColorType, apply Shader.
4697If paint contains Mask_Filter, generate mask from #bitmap_or_image# bounds. If paint
4698Filter_Quality set to kNone_SkFilterQuality, disable pixel filtering. For all
4699other values of paint Filter_Quality, use kLow_SkFilterQuality to filter pixels.
Cary Clark137b8742018-05-30 09:21:49 -04004700Any SkMaskFilter on paint is ignored as is paint Anti_Aliasing state.
Cary Clark682c58d2018-05-16 07:07:07 -04004701##
4702
Cary Clark8032b982017-07-28 11:04:54 -04004703#Method void drawBitmapNine(const SkBitmap& bitmap, const SkIRect& center, const SkRect& dst,
Cary Clark73fa9722017-08-29 17:36:51 -04004704 const SkPaint* paint = nullptr)
Cary Clarkab2621d2018-01-30 10:08:57 -05004705#In Draw_Image
Cary Clark78de7512018-02-07 07:27:09 -05004706#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05004707#Line # draws Nine_Patch Bitmap ##
Cary Clark8032b982017-07-28 11:04:54 -04004708
Cary Clark80247e52018-07-11 16:18:41 -04004709Draws Bitmap bitmap stretched proportionally to fit into Rect dst.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004710IRect center divides the bitmap into nine sections: four sides, four corners,
Cary Clarkce101242017-09-01 15:51:02 -04004711and the center. Corners are not scaled, or scaled down proportionately if their
Cary Clarkbad5ad72017-08-03 17:14:08 -04004712sides are larger than dst; center and four sides are scaled to fit remaining
4713space, if any.
Cary Clark8032b982017-07-28 11:04:54 -04004714
Cary Clarkbad5ad72017-08-03 17:14:08 -04004715Additionally transform draw using Clip, Matrix, and optional Paint paint.
4716
Cary Clark682c58d2018-05-16 07:07:07 -04004717#paint_as_used_by_draw_lattice_or_draw_nine(bitmap)#
Cary Clarkbad5ad72017-08-03 17:14:08 -04004718
4719If generated mask extends beyond bitmap bounds, replicate bitmap edge colors,
4720just as Shader made from SkShader::MakeBitmapShader with
Cary Clarkbc5697d2017-10-04 14:31:33 -04004721SkShader::kClamp_TileMode set replicates the bitmap edge color when it samples
Cary Clarkbad5ad72017-08-03 17:14:08 -04004722outside of its bounds.
4723
4724#Param bitmap Bitmap containing pixels, dimensions, and format ##
4725#Param center IRect edge of image corners and sides ##
4726#Param dst destination Rect of image to draw to ##
4727#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4728 and so on; or nullptr
4729##
Cary Clark8032b982017-07-28 11:04:54 -04004730
4731#Example
4732#Height 128
4733#Description
4734 The two leftmost bitmap draws has four corners and sides to the left and right of center.
4735 The leftmost bitmap draw scales the width of corners proportionately to fit.
Herb Derbyefe39bc2018-05-01 17:06:20 -04004736 The third and fourth draw corners are not scaled; the sides and center are scaled to
Cary Clark8032b982017-07-28 11:04:54 -04004737 fill the remaining space.
4738 The rightmost bitmap draw has four corners scaled vertically to fit, and uses sides above
4739 and below center to fill the remaining space.
4740##
Cary Clarkbad5ad72017-08-03 17:14:08 -04004741void draw(SkCanvas* canvas) {
4742 SkIRect center = { 20, 10, 50, 40 };
4743 SkBitmap bitmap;
4744 bitmap.allocPixels(SkImageInfo::MakeN32Premul(60, 60));
4745 SkCanvas bitCanvas(bitmap);
4746 SkPaint paint;
4747 SkColor gray = 0xFF000000;
4748 int left = 0;
4749 for (auto right: { center.fLeft, center.fRight, bitmap.width() } ) {
4750 int top = 0;
4751 for (auto bottom: { center.fTop, center.fBottom, bitmap.height() } ) {
4752 paint.setColor(gray);
4753 bitCanvas.drawIRect(SkIRect::MakeLTRB(left, top, right, bottom), paint);
4754 gray += 0x001f1f1f;
4755 top = bottom;
4756 }
Herb Derbyefe39bc2018-05-01 17:06:20 -04004757 left = right;
Cary Clarkbad5ad72017-08-03 17:14:08 -04004758 }
4759 for (auto dest: { 20, 30, 40, 60, 90 } ) {
4760 canvas->drawBitmapNine(bitmap, center, SkRect::MakeWH(dest, 110 - dest), nullptr);
4761 canvas->translate(dest + 4, 0);
4762 }
Cary Clark8032b982017-07-28 11:04:54 -04004763}
4764##
4765
Cary Clark2ade9972017-11-02 17:49:34 -04004766#SeeAlso drawImageNine drawBitmap drawBitmapLattice drawBitmapRect
Cary Clark8032b982017-07-28 11:04:54 -04004767
4768##
4769
4770# ------------------------------------------------------------------------------
Cary Clark682c58d2018-05-16 07:07:07 -04004771#Subtopic Lattice
4772#Line # divides Bitmap or Image into a rectangular grid ##
4773
Cary Clark8032b982017-07-28 11:04:54 -04004774#Struct Lattice
Cary Clark08895c42018-02-01 09:37:32 -05004775#Line # divides Bitmap or Image into a rectangular grid ##
Cary Clark682c58d2018-05-16 07:07:07 -04004776
Cary Clark8032b982017-07-28 11:04:54 -04004777#Code
4778 struct Lattice {
Cary Clark2f466242017-12-11 16:03:17 -05004779 enum RectType ...
Cary Clark8032b982017-07-28 11:04:54 -04004780
Cary Clark2f466242017-12-11 16:03:17 -05004781 const int* fXDivs;
4782 const int* fYDivs;
4783 const RectType* fRectTypes;
4784 int fXCount;
4785 int fYCount;
4786 const SkIRect* fBounds;
4787 const SkColor* fColors;
Cary Clark8032b982017-07-28 11:04:54 -04004788 };
4789##
4790
Cary Clark137b8742018-05-30 09:21:49 -04004791Lattice divides Bitmap or Image into a rectangular grid.
4792Grid entries on even columns and even rows are fixed; these entries are
4793always drawn at their original size if the destination is large enough.
4794If the destination side is too small to hold the fixed entries, all fixed
4795entries are proportionately scaled down to fit.
4796The grid entries not on even columns and rows are scaled to fit the
4797remaining space, if any.
4798
Cary Clark682c58d2018-05-16 07:07:07 -04004799#Subtopic Overview
4800#Populate
4801##
4802
4803#Subtopic Constant
4804#Populate
4805##
Cary Clark154beea2017-10-26 07:58:48 -04004806
Cary Clark2f466242017-12-11 16:03:17 -05004807 #Enum RectType
Cary Clark682c58d2018-05-16 07:07:07 -04004808 #Line # optional setting per rectangular grid entry ##
Cary Clark8032b982017-07-28 11:04:54 -04004809 #Code
Cary Clark2f466242017-12-11 16:03:17 -05004810 enum RectType : uint8_t {
4811 kDefault = 0,
4812 kTransparent,
4813 kFixedColor,
Cary Clark8032b982017-07-28 11:04:54 -04004814 };
4815 ##
4816
Cary Clark2f466242017-12-11 16:03:17 -05004817 Optional setting per rectangular grid entry to make it transparent,
4818 or to fill the grid entry with a color.
Cary Clark8032b982017-07-28 11:04:54 -04004819
Cary Clark2f466242017-12-11 16:03:17 -05004820 #Const kDefault 0
Cary Clark682c58d2018-05-16 07:07:07 -04004821 #Line # draws Bitmap into lattice rectangle ##
Cary Clark2f466242017-12-11 16:03:17 -05004822 ##
4823
4824 #Const kTransparent 1
Cary Clark682c58d2018-05-16 07:07:07 -04004825 #Line # skips lattice rectangle by making it transparent ##
Cary Clark2f466242017-12-11 16:03:17 -05004826 ##
4827
4828 #Const kFixedColor 2
Cary Clark682c58d2018-05-16 07:07:07 -04004829 #Line # draws one of fColors into lattice rectangle ##
Cary Clark8032b982017-07-28 11:04:54 -04004830 ##
4831 ##
4832
Cary Clark682c58d2018-05-16 07:07:07 -04004833#Subtopic Member
4834#Populate
4835##
4836
Cary Clark8032b982017-07-28 11:04:54 -04004837 #Member const int* fXDivs
Cary Clark5538c132018-06-14 12:28:14 -04004838 #Line # x-axis values dividing bitmap ##
4839 Array of x-axis values that divide the bitmap vertically.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004840 Array entries must be unique, increasing, greater than or equal to
4841 fBounds left edge, and less than fBounds right edge.
4842 Set the first element to fBounds left to collapse the left column of
4843 fixed grid entries.
Cary Clark8032b982017-07-28 11:04:54 -04004844 ##
4845
4846 #Member const int* fYDivs
Cary Clark5538c132018-06-14 12:28:14 -04004847 #Line # y-axis values dividing bitmap ##
4848 Array of y-axis values that divide the bitmap horizontally.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004849 Array entries must be unique, increasing, greater than or equal to
4850 fBounds top edge, and less than fBounds bottom edge.
4851 Set the first element to fBounds top to collapse the top row of fixed
4852 grid entries.
Cary Clark8032b982017-07-28 11:04:54 -04004853 ##
4854
Cary Clark2f466242017-12-11 16:03:17 -05004855 #Member const RectType* fRectTypes
Cary Clark682c58d2018-05-16 07:07:07 -04004856 #Line # array of fill types ##
Cary Clark2f466242017-12-11 16:03:17 -05004857 Optional array of fill types, one per rectangular grid entry:
Cary Clarkbad5ad72017-08-03 17:14:08 -04004858 array length must be
4859 #Formula
4860 (fXCount + 1) * (fYCount + 1)
4861 ##
4862 .
Cary Clark6fc50412017-09-21 12:31:06 -04004863
Cary Clark2f466242017-12-11 16:03:17 -05004864 Each RectType is one of: kDefault, kTransparent, kFixedColor.
4865
Cary Clark8032b982017-07-28 11:04:54 -04004866 Array entries correspond to the rectangular grid entries, ascending
4867 left to right and then top to bottom.
4868 ##
4869
4870 #Member int fXCount
Cary Clark682c58d2018-05-16 07:07:07 -04004871 #Line # number of x-coordinates ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04004872 Number of entries in fXDivs array; one less than the number of
4873 horizontal divisions.
Cary Clark8032b982017-07-28 11:04:54 -04004874 ##
4875
4876 #Member int fYCount
Cary Clark682c58d2018-05-16 07:07:07 -04004877 #Line # number of y-coordinates ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04004878 Number of entries in fYDivs array; one less than the number of vertical
4879 divisions.
Cary Clark8032b982017-07-28 11:04:54 -04004880 ##
4881
4882 #Member const SkIRect* fBounds
Cary Clark682c58d2018-05-16 07:07:07 -04004883 #Line # source bounds to draw from ##
Cary Clark8032b982017-07-28 11:04:54 -04004884 Optional subset IRect source to draw from.
4885 If nullptr, source bounds is dimensions of Bitmap or Image.
4886 ##
4887
Cary Clark2f466242017-12-11 16:03:17 -05004888 #Member const SkColor* fColors
Cary Clark682c58d2018-05-16 07:07:07 -04004889 #Line # array of colors ##
Cary Clark2f466242017-12-11 16:03:17 -05004890 Optional array of colors, one per rectangular grid entry.
4891 Array length must be
4892 #Formula
4893 (fXCount + 1) * (fYCount + 1)
4894 ##
4895 .
4896
4897 Array entries correspond to the rectangular grid entries, ascending
4898 left to right, then top to bottom.
4899 ##
4900
Cary Clark8032b982017-07-28 11:04:54 -04004901#Struct Lattice ##
4902
4903#Method void drawBitmapLattice(const SkBitmap& bitmap, const Lattice& lattice, const SkRect& dst,
4904 const SkPaint* paint = nullptr)
Cary Clarkab2621d2018-01-30 10:08:57 -05004905#In Draw_Image
Cary Clark78de7512018-02-07 07:27:09 -05004906#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05004907#Line # draws proportionally stretched Bitmap ##
Cary Clark8032b982017-07-28 11:04:54 -04004908
Cary Clark80247e52018-07-11 16:18:41 -04004909Draws Bitmap bitmap stretched proportionally to fit into Rect dst.
Cary Clark8032b982017-07-28 11:04:54 -04004910
4911Lattice lattice divides bitmap into a rectangular grid.
4912Each intersection of an even-numbered row and column is fixed; like the corners
Cary Clarkbad5ad72017-08-03 17:14:08 -04004913of drawBitmapNine, fixed lattice elements never scale larger than their initial
Cary Clarkbc5697d2017-10-04 14:31:33 -04004914size and shrink proportionately when all fixed elements exceed the bitmap
Cary Clarkbad5ad72017-08-03 17:14:08 -04004915dimension. All other grid elements scale to fill the available space, if any.
Cary Clark8032b982017-07-28 11:04:54 -04004916
4917Additionally transform draw using Clip, Matrix, and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004918
Cary Clark682c58d2018-05-16 07:07:07 -04004919#paint_as_used_by_draw_lattice_or_draw_nine(bitmap)#
Cary Clarkbad5ad72017-08-03 17:14:08 -04004920
4921If generated mask extends beyond bitmap bounds, replicate bitmap edge colors,
4922just as Shader made from SkShader::MakeBitmapShader with
Cary Clarkbc5697d2017-10-04 14:31:33 -04004923SkShader::kClamp_TileMode set replicates the bitmap edge color when it samples
Cary Clarkbad5ad72017-08-03 17:14:08 -04004924outside of its bounds.
4925
4926#Param bitmap Bitmap containing pixels, dimensions, and format ##
4927#Param lattice division of bitmap into fixed and variable rectangles ##
4928#Param dst destination Rect of image to draw to ##
4929#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4930 and so on; or nullptr
4931##
Cary Clark8032b982017-07-28 11:04:54 -04004932
4933#Example
4934#Height 128
4935#Description
4936 The two leftmost bitmap draws has four corners and sides to the left and right of center.
4937 The leftmost bitmap draw scales the width of corners proportionately to fit.
Herb Derbyefe39bc2018-05-01 17:06:20 -04004938 The third and fourth draw corners are not scaled; the sides are scaled to
Cary Clark8032b982017-07-28 11:04:54 -04004939 fill the remaining space; the center is transparent.
4940 The rightmost bitmap draw has four corners scaled vertically to fit, and uses sides above
4941 and below center to fill the remaining space.
4942##
Cary Clarkbad5ad72017-08-03 17:14:08 -04004943void draw(SkCanvas* canvas) {
4944 SkIRect center = { 20, 10, 50, 40 };
4945 SkBitmap bitmap;
4946 bitmap.allocPixels(SkImageInfo::MakeN32Premul(60, 60));
4947 SkCanvas bitCanvas(bitmap);
4948 SkPaint paint;
4949 SkColor gray = 0xFF000000;
4950 int left = 0;
4951 for (auto right: { center.fLeft, center.fRight, bitmap.width() } ) {
4952 int top = 0;
4953 for (auto bottom: { center.fTop, center.fBottom, bitmap.height() } ) {
4954 paint.setColor(gray);
4955 bitCanvas.drawIRect(SkIRect::MakeLTRB(left, top, right, bottom), paint);
4956 gray += 0x001f1f1f;
4957 top = bottom;
4958 }
Herb Derbyefe39bc2018-05-01 17:06:20 -04004959 left = right;
Cary Clarkbad5ad72017-08-03 17:14:08 -04004960 }
4961 const int xDivs[] = { center.fLeft, center.fRight };
4962 const int yDivs[] = { center.fTop, center.fBottom };
Cary Clarkca3ebcd2017-12-12 11:22:38 -05004963 SkCanvas::Lattice::RectType fillTypes[3][3];
4964 memset(fillTypes, 0, sizeof(fillTypes));
4965 fillTypes[1][1] = SkCanvas::Lattice::kTransparent;
4966 SkColor dummy[9]; // temporary pending bug fix
4967 SkCanvas::Lattice lattice = { xDivs, yDivs, fillTypes[0], SK_ARRAY_COUNT(xDivs),
4968 SK_ARRAY_COUNT(yDivs), nullptr, dummy };
Cary Clarkbad5ad72017-08-03 17:14:08 -04004969 for (auto dest: { 20, 30, 40, 60, 90 } ) {
Cary Clarkca3ebcd2017-12-12 11:22:38 -05004970 canvas->drawBitmapLattice(bitmap, lattice, SkRect::MakeWH(dest, 110 - dest), nullptr);
Cary Clarkbad5ad72017-08-03 17:14:08 -04004971 canvas->translate(dest + 4, 0);
4972 }
Cary Clark8032b982017-07-28 11:04:54 -04004973}
4974##
4975
Cary Clark2ade9972017-11-02 17:49:34 -04004976#SeeAlso drawImageLattice drawBitmap drawBitmapNine Lattice
Cary Clark8032b982017-07-28 11:04:54 -04004977
4978##
4979
4980# ------------------------------------------------------------------------------
4981
4982#Method void drawImageLattice(const SkImage* image, const Lattice& lattice, const SkRect& dst,
4983 const SkPaint* paint = nullptr)
Cary Clarkab2621d2018-01-30 10:08:57 -05004984#In Draw_Image
Cary Clark78de7512018-02-07 07:27:09 -05004985#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05004986#Line # draws proportionally stretched Image ##
Cary Clark8032b982017-07-28 11:04:54 -04004987
Cary Clark80247e52018-07-11 16:18:41 -04004988Draws Image image stretched proportionally to fit into Rect dst.
Cary Clark8032b982017-07-28 11:04:54 -04004989
4990Lattice lattice divides image into a rectangular grid.
4991Each intersection of an even-numbered row and column is fixed; like the corners
Cary Clarkbad5ad72017-08-03 17:14:08 -04004992of drawBitmapNine, fixed lattice elements never scale larger than their initial
Cary Clarkbc5697d2017-10-04 14:31:33 -04004993size and shrink proportionately when all fixed elements exceed the bitmap
Cary Clarkbad5ad72017-08-03 17:14:08 -04004994dimension. All other grid elements scale to fill the available space, if any.
Cary Clark8032b982017-07-28 11:04:54 -04004995
4996Additionally transform draw using Clip, Matrix, and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004997
Cary Clark682c58d2018-05-16 07:07:07 -04004998#paint_as_used_by_draw_lattice_or_draw_nine(image)#
Cary Clarkbad5ad72017-08-03 17:14:08 -04004999
5000If generated mask extends beyond bitmap bounds, replicate bitmap edge colors,
5001just as Shader made from SkShader::MakeBitmapShader with
Cary Clarkbc5697d2017-10-04 14:31:33 -04005002SkShader::kClamp_TileMode set replicates the bitmap edge color when it samples
Cary Clarkbad5ad72017-08-03 17:14:08 -04005003outside of its bounds.
5004
5005#Param image Image containing pixels, dimensions, and format ##
5006#Param lattice division of bitmap into fixed and variable rectangles ##
5007#Param dst destination Rect of image to draw to ##
5008#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
5009 and so on; or nullptr
5010##
Cary Clark8032b982017-07-28 11:04:54 -04005011
5012#Example
5013#Height 128
5014#Description
5015 The leftmost image is smaller than center; only corners are drawn, all scaled to fit.
Cary Clarkce101242017-09-01 15:51:02 -04005016 The second image equals the size of center; only corners are drawn without scaling.
5017 The remaining images are larger than center. All corners draw without scaling. The sides
Cary Clark8032b982017-07-28 11:04:54 -04005018 are scaled if needed to take up the remaining space; the center is transparent.
5019##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005020void draw(SkCanvas* canvas) {
5021 SkIRect center = { 20, 10, 50, 40 };
5022 SkBitmap bitmap;
5023 bitmap.allocPixels(SkImageInfo::MakeN32Premul(60, 60));
5024 SkCanvas bitCanvas(bitmap);
5025 SkPaint paint;
5026 SkColor gray = 0xFF000000;
5027 int left = 0;
5028 for (auto right: { center.fLeft, center.fRight, bitmap.width() } ) {
5029 int top = 0;
5030 for (auto bottom: { center.fTop, center.fBottom, bitmap.height() } ) {
5031 paint.setColor(gray);
5032 bitCanvas.drawIRect(SkIRect::MakeLTRB(left, top, right, bottom), paint);
5033 gray += 0x001f1f1f;
5034 top = bottom;
5035 }
Herb Derbyefe39bc2018-05-01 17:06:20 -04005036 left = right;
Cary Clarkbad5ad72017-08-03 17:14:08 -04005037 }
Cary Clarkbad5ad72017-08-03 17:14:08 -04005038 sk_sp<SkImage> image = SkImage::MakeFromBitmap(bitmap);
5039 SkImage* imagePtr = image.get();
5040 for (auto dest: { 20, 30, 40, 60, 90 } ) {
5041 canvas->drawImageNine(imagePtr, center, SkRect::MakeWH(dest, dest), nullptr);
5042 canvas->translate(dest + 4, 0);
5043 }
Cary Clark8032b982017-07-28 11:04:54 -04005044}
5045##
5046
Cary Clark2ade9972017-11-02 17:49:34 -04005047#SeeAlso drawBitmapLattice drawImage drawImageNine Lattice
Cary Clark8032b982017-07-28 11:04:54 -04005048
5049##
5050
Cary Clark682c58d2018-05-16 07:07:07 -04005051#Subtopic Lattice ##
5052
Cary Clark08895c42018-02-01 09:37:32 -05005053#Subtopic Draw_Image ##
Cary Clark8032b982017-07-28 11:04:54 -04005054
5055# ------------------------------------------------------------------------------
Cary Clark78de7512018-02-07 07:27:09 -05005056#Subtopic Draw_Text
5057#Populate
5058#Line # draws text into Canvas ##
5059##
Cary Clark8032b982017-07-28 11:04:54 -04005060
5061#Method void drawText(const void* text, size_t byteLength, SkScalar x, SkScalar y,
5062 const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05005063#In Draw_Text
5064#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05005065#Line # draws text at (x, y), using font advance ##
Cary Clark8032b982017-07-28 11:04:54 -04005066
Cary Clark80247e52018-07-11 16:18:41 -04005067Draws text, with origin at (x, y), using Clip, Matrix, and Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04005068
Cary Clarkbc5697d2017-10-04 14:31:33 -04005069text meaning depends on Paint_Text_Encoding; by default, text is encoded as
Cary Clarkbad5ad72017-08-03 17:14:08 -04005070UTF-8.
Cary Clark8032b982017-07-28 11:04:54 -04005071
Cary Clarkbad5ad72017-08-03 17:14:08 -04005072x and y meaning depends on Paint_Text_Align and Paint_Vertical_Text; by default
Cary Clarkbc5697d2017-10-04 14:31:33 -04005073text draws left to right, positioning the first glyph left side bearing at x
Herb Derbyefe39bc2018-05-01 17:06:20 -04005074and its baseline at y. Text size is affected by Matrix and Paint_Text_Size.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005075
Mike Reed8ad91a92018-01-19 19:09:32 -05005076All elements of paint: Path_Effect, Mask_Filter, Shader,
Cary Clarkbad5ad72017-08-03 17:14:08 -04005077Color_Filter, Image_Filter, and Draw_Looper; apply to text. By default, draws
Cary Clarkce101242017-09-01 15:51:02 -04005078filled 12 point black Glyphs.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005079
Cary Clarkce101242017-09-01 15:51:02 -04005080#Param text character code points or Glyphs drawn ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005081#Param byteLength byte length of text array ##
5082#Param x start of text on x-axis ##
5083#Param y start of text on y-axis ##
5084#Param paint text size, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005085
5086#Example
5087#Height 200
5088#Description
5089 The same text is drawn varying Paint_Text_Size and varying
Herb Derbyefe39bc2018-05-01 17:06:20 -04005090 Matrix.
Cary Clark8032b982017-07-28 11:04:54 -04005091##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005092void draw(SkCanvas* canvas) {
5093 SkPaint paint;
5094 paint.setAntiAlias(true);
5095 float textSizes[] = { 12, 18, 24, 36 };
5096 for (auto size: textSizes ) {
5097 paint.setTextSize(size);
5098 canvas->drawText("Aa", 2, 10, 20, paint);
5099 canvas->translate(0, size * 2);
5100 }
5101 paint.reset();
5102 paint.setAntiAlias(true);
5103 float yPos = 20;
5104 for (auto size: textSizes ) {
5105 float scale = size / 12.f;
5106 canvas->resetMatrix();
5107 canvas->translate(100, 0);
5108 canvas->scale(scale, scale);
5109 canvas->drawText("Aa", 2, 10 / scale, yPos / scale, paint);
Herb Derbyefe39bc2018-05-01 17:06:20 -04005110 yPos += size * 2;
Cary Clarkbad5ad72017-08-03 17:14:08 -04005111 }
5112}
Cary Clark8032b982017-07-28 11:04:54 -04005113##
5114
Cary Clark2ade9972017-11-02 17:49:34 -04005115#SeeAlso drawString drawPosText drawPosTextH drawTextBlob drawTextOnPath drawTextRSXform
Cary Clark8032b982017-07-28 11:04:54 -04005116
5117##
5118
5119#Method void drawString(const char* string, SkScalar x, SkScalar y, const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05005120#In Draw_Text
5121#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05005122#Line # draws null terminated string at (x, y) using font advance ##
Cary Clark682c58d2018-05-16 07:07:07 -04005123Draws null terminated string, with origin at (x, y), using Clip, Matrix, and
5124Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04005125
Cary Clarkbc5697d2017-10-04 14:31:33 -04005126string meaning depends on Paint_Text_Encoding; by default, strings are encoded
5127as UTF-8. Other values of Paint_Text_Encoding are unlikely to produce the desired
Cary Clarkbad5ad72017-08-03 17:14:08 -04005128results, since zero bytes may be embedded in the string.
Cary Clark8032b982017-07-28 11:04:54 -04005129
Cary Clarkbad5ad72017-08-03 17:14:08 -04005130x and y meaning depends on Paint_Text_Align and Paint_Vertical_Text; by default
Cary Clarkbc5697d2017-10-04 14:31:33 -04005131string draws left to right, positioning the first glyph left side bearing at x
Herb Derbyefe39bc2018-05-01 17:06:20 -04005132and its baseline at y. Text size is affected by Matrix and Paint_Text_Size.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005133
Mike Reed8ad91a92018-01-19 19:09:32 -05005134All elements of paint: Path_Effect, Mask_Filter, Shader,
Cary Clarkbad5ad72017-08-03 17:14:08 -04005135Color_Filter, Image_Filter, and Draw_Looper; apply to text. By default, draws
Cary Clarkce101242017-09-01 15:51:02 -04005136filled 12 point black Glyphs.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005137
Cary Clarkce101242017-09-01 15:51:02 -04005138#Param string character code points or Glyphs drawn,
Cary Clarkbad5ad72017-08-03 17:14:08 -04005139 ending with a char value of zero
5140##
5141#Param x start of string on x-axis ##
5142#Param y start of string on y-axis ##
5143#Param paint text size, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005144
5145#Example
Cary Clarkffb3d682018-05-17 12:17:28 -04005146#Height 48
Cary Clark8032b982017-07-28 11:04:54 -04005147 SkPaint paint;
5148 canvas->drawString("a small hello", 20, 20, paint);
5149##
5150
Cary Clark2ade9972017-11-02 17:49:34 -04005151#SeeAlso drawText drawPosText drawPosTextH drawTextBlob drawTextOnPath drawTextRSXform
Cary Clark8032b982017-07-28 11:04:54 -04005152
5153##
5154
5155#Method void drawString(const SkString& string, SkScalar x, SkScalar y, const SkPaint& paint)
5156
Cary Clark80247e52018-07-11 16:18:41 -04005157Draws null terminated string, with origin at (x, y), using Clip, Matrix, and
Cary Clarkbad5ad72017-08-03 17:14:08 -04005158Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04005159
Cary Clarkbc5697d2017-10-04 14:31:33 -04005160string meaning depends on Paint_Text_Encoding; by default, strings are encoded
5161as UTF-8. Other values of Paint_Text_Encoding are unlikely to produce the desired
Cary Clarkbad5ad72017-08-03 17:14:08 -04005162results, since zero bytes may be embedded in the string.
Cary Clark8032b982017-07-28 11:04:54 -04005163
Cary Clarkbad5ad72017-08-03 17:14:08 -04005164x and y meaning depends on Paint_Text_Align and Paint_Vertical_Text; by default
Cary Clarkbc5697d2017-10-04 14:31:33 -04005165string draws left to right, positioning the first glyph left side bearing at x
Herb Derbyefe39bc2018-05-01 17:06:20 -04005166and its baseline at y. Text size is affected by Matrix and Paint_Text_Size.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005167
Mike Reed8ad91a92018-01-19 19:09:32 -05005168All elements of paint: Path_Effect, Mask_Filter, Shader,
Cary Clarkbad5ad72017-08-03 17:14:08 -04005169Color_Filter, Image_Filter, and Draw_Looper; apply to text. By default, draws
Cary Clarkce101242017-09-01 15:51:02 -04005170filled 12 point black Glyphs.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005171
Cary Clarkce101242017-09-01 15:51:02 -04005172#Param string character code points or Glyphs drawn,
Cary Clarkbad5ad72017-08-03 17:14:08 -04005173 ending with a char value of zero
5174##
5175#Param x start of string on x-axis ##
5176#Param y start of string on y-axis ##
5177#Param paint text size, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005178
5179#Example
5180 SkPaint paint;
5181 SkString string("a small hello");
5182 canvas->drawString(string, 20, 20, paint);
5183##
5184
Cary Clark2ade9972017-11-02 17:49:34 -04005185#SeeAlso drawText drawPosText drawPosTextH drawTextBlob drawTextOnPath drawTextRSXform
Cary Clark8032b982017-07-28 11:04:54 -04005186
5187##
5188
5189# ------------------------------------------------------------------------------
5190
5191#Method void drawPosText(const void* text, size_t byteLength, const SkPoint pos[],
5192 const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05005193#In Draw_Text
5194#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05005195#Line # draws text at array of (x, y) positions ##
Cary Clark8032b982017-07-28 11:04:54 -04005196
Cary Clark80247e52018-07-11 16:18:41 -04005197Draws each glyph in text with the origin in pos array, using Clip, Matrix, and
Cary Clarkce101242017-09-01 15:51:02 -04005198Paint paint. The number of entries in pos array must match the number of Glyphs
Cary Clarkbad5ad72017-08-03 17:14:08 -04005199described by byteLength of text.
Cary Clark8032b982017-07-28 11:04:54 -04005200
Cary Clarkbc5697d2017-10-04 14:31:33 -04005201text meaning depends on Paint_Text_Encoding; by default, text is encoded as
Cary Clark5538c132018-06-14 12:28:14 -04005202UTF-8. pos elements meaning depends on Paint_Vertical_Text; by default
5203glyph left side bearing and baseline are relative to Point in pos array.
5204Text size is affected by Matrix and Paint_Text_Size.
Cary Clark8032b982017-07-28 11:04:54 -04005205
Mike Reed8ad91a92018-01-19 19:09:32 -05005206All elements of paint: Path_Effect, Mask_Filter, Shader,
Cary Clarkbad5ad72017-08-03 17:14:08 -04005207Color_Filter, Image_Filter, and Draw_Looper; apply to text. By default, draws
Cary Clarkce101242017-09-01 15:51:02 -04005208filled 12 point black Glyphs.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005209
5210Layout engines such as Harfbuzz typically position each glyph
Cary Clarkbc5697d2017-10-04 14:31:33 -04005211rather than using the font advance widths.
Cary Clark8032b982017-07-28 11:04:54 -04005212
Cary Clarkce101242017-09-01 15:51:02 -04005213#Param text character code points or Glyphs drawn ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005214#Param byteLength byte length of text array ##
5215#Param pos array of glyph origins ##
5216#Param paint text size, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005217
5218#Example
5219#Height 120
Cary Clarkbad5ad72017-08-03 17:14:08 -04005220void draw(SkCanvas* canvas) {
5221 const char hello[] = "HeLLo!";
5222 const SkPoint pos[] = { {40, 100}, {82, 95}, {115, 110}, {130, 95}, {145, 85},
5223 {172, 100} };
5224 SkPaint paint;
5225 paint.setTextSize(60);
5226 canvas->drawPosText(hello, strlen(hello), pos, paint);
Cary Clark8032b982017-07-28 11:04:54 -04005227}
5228##
5229
Cary Clark2ade9972017-11-02 17:49:34 -04005230#SeeAlso drawText drawPosTextH drawTextBlob drawTextOnPath drawTextRSXform
Cary Clark8032b982017-07-28 11:04:54 -04005231
5232##
5233
5234# ------------------------------------------------------------------------------
5235
5236#Method void drawPosTextH(const void* text, size_t byteLength, const SkScalar xpos[], SkScalar constY,
5237 const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05005238#In Draw_Text
5239#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05005240#Line # draws text at x positions with common baseline ##
Cary Clark8032b982017-07-28 11:04:54 -04005241
Cary Clark80247e52018-07-11 16:18:41 -04005242Draws each glyph in text with its (x, y) origin composed from xpos array and
Cary Clarkbad5ad72017-08-03 17:14:08 -04005243constY, using Clip, Matrix, and Paint paint. The number of entries in xpos array
Cary Clarkce101242017-09-01 15:51:02 -04005244must match the number of Glyphs described by byteLength of text.
Cary Clark8032b982017-07-28 11:04:54 -04005245
Cary Clarkbc5697d2017-10-04 14:31:33 -04005246text meaning depends on Paint_Text_Encoding; by default, text is encoded as
Cary Clark137b8742018-05-30 09:21:49 -04005247UTF-8. xpos elements meaning depends on Paint_Vertical_Text;
Cary Clarkbc5697d2017-10-04 14:31:33 -04005248by default each glyph left side bearing is positioned at an xpos element and
Cary Clarkbad5ad72017-08-03 17:14:08 -04005249its baseline is positioned at constY. Text size is affected by Matrix and
Herb Derbyefe39bc2018-05-01 17:06:20 -04005250Paint_Text_Size.
Cary Clark8032b982017-07-28 11:04:54 -04005251
Mike Reed8ad91a92018-01-19 19:09:32 -05005252All elements of paint: Path_Effect, Mask_Filter, Shader,
Cary Clarkbad5ad72017-08-03 17:14:08 -04005253Color_Filter, Image_Filter, and Draw_Looper; apply to text. By default, draws
Cary Clarkce101242017-09-01 15:51:02 -04005254filled 12 point black Glyphs.
Cary Clark8032b982017-07-28 11:04:54 -04005255
Cary Clarkbad5ad72017-08-03 17:14:08 -04005256Layout engines such as Harfbuzz typically position each glyph
Cary Clarkbc5697d2017-10-04 14:31:33 -04005257rather than using the font advance widths if all Glyphs share the same
Cary Clarkbad5ad72017-08-03 17:14:08 -04005258baseline.
5259
Cary Clarkce101242017-09-01 15:51:02 -04005260#Param text character code points or Glyphs drawn ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005261#Param byteLength byte length of text array ##
Cary Clark5538c132018-06-14 12:28:14 -04005262#Param xpos array of x-axis positions, used to position each glyph ##
5263#Param constY shared y-axis value for all of x-axis positions ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005264#Param paint text size, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005265
5266#Example
5267#Height 40
Cary Clarkbad5ad72017-08-03 17:14:08 -04005268 void draw(SkCanvas* canvas) {
5269 SkScalar xpos[] = { 20, 40, 80, 160 };
5270 SkPaint paint;
5271 canvas->drawPosTextH("XXXX", 4, xpos, 20, paint);
5272 }
Cary Clark8032b982017-07-28 11:04:54 -04005273##
5274
Cary Clark2ade9972017-11-02 17:49:34 -04005275#SeeAlso drawText drawPosText drawTextBlob drawTextOnPath drawTextRSXform
Cary Clark8032b982017-07-28 11:04:54 -04005276
5277##
5278
5279# ------------------------------------------------------------------------------
5280
5281#Method void drawTextOnPathHV(const void* text, size_t byteLength, const SkPath& path, SkScalar hOffset,
5282 SkScalar vOffset, const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05005283#In Draw_Text
5284#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05005285#Line # draws text following Path with offsets ##
Cary Clark8032b982017-07-28 11:04:54 -04005286
Cary Clark80247e52018-07-11 16:18:41 -04005287Draws text on Path path, using Clip, Matrix, and Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04005288
Cary Clarkbad5ad72017-08-03 17:14:08 -04005289Origin of text is at distance hOffset along the path, offset by a perpendicular
5290vector of length vOffset. If the path section corresponding the glyph advance is
5291curved, the glyph is drawn curved to match; control points in the glyph are
Cary Clarkbc5697d2017-10-04 14:31:33 -04005292mapped to projected points parallel to the path. If the text advance is larger
Cary Clarkbad5ad72017-08-03 17:14:08 -04005293than the path length, the excess text is clipped.
5294
Cary Clarkbc5697d2017-10-04 14:31:33 -04005295text meaning depends on Paint_Text_Encoding; by default, text is encoded as
Cary Clarkbad5ad72017-08-03 17:14:08 -04005296UTF-8. Origin meaning depends on Paint_Text_Align and Paint_Vertical_Text; by
Cary Clark5538c132018-06-14 12:28:14 -04005297default text positions the first glyph left side bearing and baseline relative
5298to origin. Text size is affected by Matrix and Paint_Text_Size.
Cary Clark8032b982017-07-28 11:04:54 -04005299
Mike Reed8ad91a92018-01-19 19:09:32 -05005300All elements of paint: Path_Effect, Mask_Filter, Shader,
Cary Clarkbad5ad72017-08-03 17:14:08 -04005301Color_Filter, Image_Filter, and Draw_Looper; apply to text. By default, draws
Cary Clarkce101242017-09-01 15:51:02 -04005302filled 12 point black Glyphs.
Cary Clark8032b982017-07-28 11:04:54 -04005303
Cary Clarkce101242017-09-01 15:51:02 -04005304#Param text character code points or Glyphs drawn ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005305#Param byteLength byte length of text array ##
5306#Param path Path providing text baseline ##
5307#Param hOffset distance along path to offset origin ##
5308#Param vOffset offset of text above (if negative) or below (if positive) the path ##
5309#Param paint text size, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005310
5311#Example
Herb Derbyefe39bc2018-05-01 17:06:20 -04005312 void draw(SkCanvas* canvas) {
Cary Clarkbad5ad72017-08-03 17:14:08 -04005313 const char aero[] = "correo a" "\xC3" "\xA9" "reo";
5314 const size_t len = sizeof(aero) - 1;
5315 SkPath path;
5316 path.addOval({43-26, 43-26, 43+26, 43+26}, SkPath::kCW_Direction, 3);
5317 SkPaint paint;
5318 paint.setTextSize(24);
5319 for (auto offset : { 0, 10, 20 } ) {
5320 canvas->drawTextOnPathHV(aero, len, path, 0, -offset, paint);
5321 canvas->translate(70 + offset, 70 + offset);
5322 }
5323 }
Cary Clark8032b982017-07-28 11:04:54 -04005324##
5325
Cary Clark2ade9972017-11-02 17:49:34 -04005326#SeeAlso drawTextOnPath drawText drawPosTextH drawTextBlob drawTextRSXform
Cary Clark8032b982017-07-28 11:04:54 -04005327
5328##
5329
5330# ------------------------------------------------------------------------------
5331
5332#Method void drawTextOnPath(const void* text, size_t byteLength, const SkPath& path,
5333 const SkMatrix* matrix, const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05005334#In Draw_Text
5335#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05005336#Line # draws text following Path contour ##
Cary Clark8032b982017-07-28 11:04:54 -04005337
Cary Clark80247e52018-07-11 16:18:41 -04005338Draws text on Path path, using Clip, Matrix, and Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04005339
Cary Clark682c58d2018-05-16 07:07:07 -04005340Origin of text is at beginning of path offset by matrix, if not nullptr.
Cary Clark137b8742018-05-30 09:21:49 -04005341matrix transforms text before text is mapped to path. If the path section
Cary Clark682c58d2018-05-16 07:07:07 -04005342corresponding the glyph advance is curved, the glyph is drawn curved to match;
5343control points in the glyph are mapped to projected points parallel to the path.
5344If the text advance is larger than the path length, the excess text is clipped.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005345
Cary Clark137b8742018-05-30 09:21:49 -04005346matrix does not effect paint Shader.
5347
Cary Clarkbc5697d2017-10-04 14:31:33 -04005348text meaning depends on Paint_Text_Encoding; by default, text is encoded as
Cary Clarkbad5ad72017-08-03 17:14:08 -04005349UTF-8. Origin meaning depends on Paint_Text_Align and Paint_Vertical_Text; by
Cary Clark5538c132018-06-14 12:28:14 -04005350default text positions the first glyph left side bearing and baseline relative
5351to origin. Text size is affected by matrix parameter, Canvas Matrix,
Cary Clark682c58d2018-05-16 07:07:07 -04005352and Paint_Text_Size.
Cary Clark8032b982017-07-28 11:04:54 -04005353
Mike Reed8ad91a92018-01-19 19:09:32 -05005354All elements of paint: Path_Effect, Mask_Filter, Shader,
Cary Clarkbad5ad72017-08-03 17:14:08 -04005355Color_Filter, Image_Filter, and Draw_Looper; apply to text. By default, draws
Cary Clark137b8742018-05-30 09:21:49 -04005356filled 12 point black Glyphs.
Cary Clark8032b982017-07-28 11:04:54 -04005357
Cary Clarkce101242017-09-01 15:51:02 -04005358#Param text character code points or Glyphs drawn ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005359#Param byteLength byte length of text array ##
5360#Param path Path providing text baseline ##
Cary Clarkce101242017-09-01 15:51:02 -04005361#Param matrix transform of Glyphs before mapping to path; may be nullptr
Cary Clarka523d2d2017-08-30 08:58:10 -04005362 to use identity Matrix
Cary Clarkbad5ad72017-08-03 17:14:08 -04005363##
5364#Param paint text size, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005365
5366#Example
Herb Derbyefe39bc2018-05-01 17:06:20 -04005367 void draw(SkCanvas* canvas) {
Cary Clarkbad5ad72017-08-03 17:14:08 -04005368 const char roller[] = "rollercoaster";
5369 const size_t len = sizeof(roller) - 1;
5370 SkPath path;
5371 path.cubicTo(40, -80, 120, 80, 160, -40);
5372 SkPaint paint;
5373 paint.setTextSize(32);
5374 paint.setStyle(SkPaint::kStroke_Style);
5375 SkMatrix matrix;
5376 matrix.setIdentity();
5377 for (int i = 0; i < 3; ++i) {
5378 canvas->translate(25, 60);
5379 canvas->drawPath(path, paint);
5380 canvas->drawTextOnPath(roller, len, path, &matrix, paint);
5381 matrix.preTranslate(0, 10);
5382 }
5383 }
Cary Clark8032b982017-07-28 11:04:54 -04005384##
5385
Cary Clark2ade9972017-11-02 17:49:34 -04005386#SeeAlso drawTextOnPathHV drawText drawPosTextH drawTextBlob drawTextRSXform
Cary Clark8032b982017-07-28 11:04:54 -04005387
5388##
5389
5390# ------------------------------------------------------------------------------
5391
5392#Method void drawTextRSXform(const void* text, size_t byteLength, const SkRSXform xform[],
5393 const SkRect* cullRect, const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05005394#In Draw_Text
5395#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05005396#Line # draws text with array of RSXform ##
Cary Clark8032b982017-07-28 11:04:54 -04005397
Cary Clark80247e52018-07-11 16:18:41 -04005398Draws text, transforming each glyph by the corresponding SkRSXform,
Cary Clark8032b982017-07-28 11:04:54 -04005399using Clip, Matrix, and Paint paint.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005400
Cary Clark137b8742018-05-30 09:21:49 -04005401RSXform xform array specifies a separate square scale, rotation, and translation
5402for each glyph. xform does not affect paint Shader.
Cary Clark8032b982017-07-28 11:04:54 -04005403
Cary Clarkbad5ad72017-08-03 17:14:08 -04005404Optional Rect cullRect is a conservative bounds of text, taking into account
Cary Clarkce101242017-09-01 15:51:02 -04005405RSXform and paint. If cullRect is outside of Clip, canvas can skip drawing.
Cary Clark8032b982017-07-28 11:04:54 -04005406
Mike Reed8ad91a92018-01-19 19:09:32 -05005407All elements of paint: Path_Effect, Mask_Filter, Shader,
Cary Clarkbad5ad72017-08-03 17:14:08 -04005408Color_Filter, Image_Filter, and Draw_Looper; apply to text. By default, draws
Cary Clarkce101242017-09-01 15:51:02 -04005409filled 12 point black Glyphs.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005410
Cary Clarkce101242017-09-01 15:51:02 -04005411#Param text character code points or Glyphs drawn ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005412#Param byteLength byte length of text array ##
5413#Param xform RSXform rotates, scales, and translates each glyph individually ##
5414#Param cullRect Rect bounds of text for efficient clipping; or nullptr ##
5415#Param paint text size, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005416
5417#Example
Herb Derbyefe39bc2018-05-01 17:06:20 -04005418void draw(SkCanvas* canvas) {
Cary Clarkbad5ad72017-08-03 17:14:08 -04005419 const int iterations = 26;
5420 SkRSXform transforms[iterations];
5421 char alphabet[iterations];
5422 SkScalar angle = 0;
5423 SkScalar scale = 1;
5424 for (size_t i = 0; i < SK_ARRAY_COUNT(transforms); ++i) {
5425 const SkScalar s = SkScalarSin(angle) * scale;
5426 const SkScalar c = SkScalarCos(angle) * scale;
5427 transforms[i] = SkRSXform::Make(-c, -s, -s * 16, c * 16);
5428 angle += .45;
5429 scale += .2;
5430 alphabet[i] = 'A' + i;
5431 }
5432 SkPaint paint;
5433 paint.setTextAlign(SkPaint::kCenter_Align);
5434 canvas->translate(110, 138);
5435 canvas->drawTextRSXform(alphabet, sizeof(alphabet), transforms, nullptr, paint);
Cary Clark8032b982017-07-28 11:04:54 -04005436}
5437##
5438
Cary Clark2ade9972017-11-02 17:49:34 -04005439#SeeAlso drawTextOnPath drawTextOnPathHV drawText drawPosText drawTextBlob
Cary Clark8032b982017-07-28 11:04:54 -04005440
5441##
5442
5443# ------------------------------------------------------------------------------
5444
5445#Method void drawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y, const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05005446#In Draw_Text
5447#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05005448#Line # draws text with arrays of positions and Paint ##
Cary Clark80247e52018-07-11 16:18:41 -04005449Draws Text_Blob blob at (x, y), using Clip, Matrix, and Paint paint.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005450
Cary Clarkce101242017-09-01 15:51:02 -04005451blob contains Glyphs, their positions, and paint attributes specific to text:
Cary Clarkbad5ad72017-08-03 17:14:08 -04005452Typeface, Paint_Text_Size, Paint_Text_Scale_X, Paint_Text_Skew_X,
Cary Clarkffb3d682018-05-17 12:17:28 -04005453Paint_Text_Align, Paint_Hinting, Anti_Alias, Paint_Fake_Bold,
Cary Clarkbad5ad72017-08-03 17:14:08 -04005454Font_Embedded_Bitmaps, Full_Hinting_Spacing, LCD_Text, Linear_Text,
5455Subpixel_Text, and Paint_Vertical_Text.
Cary Clark8032b982017-07-28 11:04:54 -04005456
Cary Clark3cd22cc2017-12-01 11:49:58 -05005457Paint_Text_Encoding must be set to SkPaint::kGlyphID_TextEncoding.
5458
Mike Reed8ad91a92018-01-19 19:09:32 -05005459Elements of paint: Path_Effect, Mask_Filter, Shader, Color_Filter,
Cary Clark8032b982017-07-28 11:04:54 -04005460Image_Filter, and Draw_Looper; apply to blob.
5461
Cary Clarkce101242017-09-01 15:51:02 -04005462#Param blob Glyphs, positions, and their paints' text size, typeface, and so on ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005463#Param x horizontal offset applied to blob ##
5464#Param y vertical offset applied to blob ##
5465#Param paint blend, color, stroking, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005466
5467#Example
5468#Height 120
Cary Clarkbad5ad72017-08-03 17:14:08 -04005469 void draw(SkCanvas* canvas) {
Cary Clark2f466242017-12-11 16:03:17 -05005470 SkTextBlobBuilder textBlobBuilder;
5471 const char bunny[] = "/(^x^)\\";
5472 const int len = sizeof(bunny) - 1;
5473 uint16_t glyphs[len];
5474 SkPaint paint;
5475 paint.textToGlyphs(bunny, len, glyphs);
Cary Clark3cd22cc2017-12-01 11:49:58 -05005476 paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
Cary Clark2f466242017-12-11 16:03:17 -05005477 int runs[] = { 3, 1, 3 };
5478 SkPoint textPos = { 20, 100 };
5479 int glyphIndex = 0;
5480 for (auto runLen : runs) {
5481 paint.setTextSize(1 == runLen ? 20 : 50);
Herb Derbyefe39bc2018-05-01 17:06:20 -04005482 const SkTextBlobBuilder::RunBuffer& run =
Cary Clark2f466242017-12-11 16:03:17 -05005483 textBlobBuilder.allocRun(paint, runLen, textPos.fX, textPos.fY);
5484 memcpy(run.glyphs, &glyphs[glyphIndex], sizeof(glyphs[0]) * runLen);
5485 textPos.fX += paint.measureText(&glyphs[glyphIndex], sizeof(glyphs[0]) * runLen, nullptr);
5486 glyphIndex += runLen;
5487 }
5488 sk_sp<const SkTextBlob> blob = textBlobBuilder.make();
5489 paint.reset();
Cary Clarkbad5ad72017-08-03 17:14:08 -04005490 canvas->drawTextBlob(blob.get(), 0, 0, paint);
Cary Clark8032b982017-07-28 11:04:54 -04005491 }
5492##
5493
Cary Clark2ade9972017-11-02 17:49:34 -04005494#SeeAlso drawText drawPosText drawPosTextH
Cary Clark8032b982017-07-28 11:04:54 -04005495
5496##
5497
5498# ------------------------------------------------------------------------------
5499
Herb Derbyefe39bc2018-05-01 17:06:20 -04005500#Method void drawTextBlob(const sk_sp<SkTextBlob>& blob, SkScalar x, SkScalar y, const SkPaint& paint)
Cary Clark8032b982017-07-28 11:04:54 -04005501
Cary Clark80247e52018-07-11 16:18:41 -04005502Draws Text_Blob blob at (x, y), using Clip, Matrix, and Paint paint.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005503
Cary Clarkce101242017-09-01 15:51:02 -04005504blob contains Glyphs, their positions, and paint attributes specific to text:
Cary Clarkbad5ad72017-08-03 17:14:08 -04005505Typeface, Paint_Text_Size, Paint_Text_Scale_X, Paint_Text_Skew_X,
Cary Clarkffb3d682018-05-17 12:17:28 -04005506Paint_Text_Align, Paint_Hinting, Anti_Alias, Paint_Fake_Bold,
Cary Clarkbad5ad72017-08-03 17:14:08 -04005507Font_Embedded_Bitmaps, Full_Hinting_Spacing, LCD_Text, Linear_Text,
5508Subpixel_Text, and Paint_Vertical_Text.
Cary Clark8032b982017-07-28 11:04:54 -04005509
Cary Clark3cd22cc2017-12-01 11:49:58 -05005510Paint_Text_Encoding must be set to SkPaint::kGlyphID_TextEncoding.
5511
Herb Derbyefe39bc2018-05-01 17:06:20 -04005512Elements of paint: Path_Effect, Mask_Filter, Shader, Color_Filter,
Cary Clark8032b982017-07-28 11:04:54 -04005513Image_Filter, and Draw_Looper; apply to blob.
5514
Cary Clarkce101242017-09-01 15:51:02 -04005515#Param blob Glyphs, positions, and their paints' text size, typeface, and so on ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005516#Param x horizontal offset applied to blob ##
5517#Param y vertical offset applied to blob ##
5518#Param paint blend, color, stroking, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005519
5520#Example
5521#Height 120
5522#Description
5523Paint attributes unrelated to text, like color, have no effect on paint in allocated Text_Blob.
5524Paint attributes related to text, like text size, have no effect on paint passed to drawTextBlob.
5525##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005526 void draw(SkCanvas* canvas) {
5527 SkTextBlobBuilder textBlobBuilder;
5528 SkPaint paint;
5529 paint.setTextSize(50);
5530 paint.setColor(SK_ColorRED);
Cary Clark2f466242017-12-11 16:03:17 -05005531 paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
Herb Derbyefe39bc2018-05-01 17:06:20 -04005532 const SkTextBlobBuilder::RunBuffer& run =
Cary Clarkbad5ad72017-08-03 17:14:08 -04005533 textBlobBuilder.allocRun(paint, 1, 20, 100);
5534 run.glyphs[0] = 20;
5535 sk_sp<const SkTextBlob> blob = textBlobBuilder.make();
5536 paint.setTextSize(10);
5537 paint.setColor(SK_ColorBLUE);
5538 canvas->drawTextBlob(blob.get(), 0, 0, paint);
5539 }
Cary Clark8032b982017-07-28 11:04:54 -04005540##
5541
Cary Clark2ade9972017-11-02 17:49:34 -04005542#SeeAlso drawText drawPosText drawPosTextH
Cary Clark8032b982017-07-28 11:04:54 -04005543
5544##
5545
5546# ------------------------------------------------------------------------------
5547
Herb Derbyefe39bc2018-05-01 17:06:20 -04005548#Method void drawPicture(const SkPicture* picture)
Cary Clark78de7512018-02-07 07:27:09 -05005549#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05005550#Line # draws Picture using Clip and Matrix ##
Cary Clark80247e52018-07-11 16:18:41 -04005551Draws Picture picture, using Clip and Matrix.
Cary Clark8032b982017-07-28 11:04:54 -04005552Clip and Matrix are unchanged by picture contents, as if
5553save() was called before and restore() was called after drawPicture.
5554
5555Picture records a series of draw commands for later playback.
5556
Cary Clarkbad5ad72017-08-03 17:14:08 -04005557#Param picture recorded drawing commands to play ##
Cary Clark8032b982017-07-28 11:04:54 -04005558
5559#Example
Herb Derbyefe39bc2018-05-01 17:06:20 -04005560void draw(SkCanvas* canvas) {
Cary Clarkbad5ad72017-08-03 17:14:08 -04005561 SkPictureRecorder recorder;
5562 SkCanvas* recordingCanvas = recorder.beginRecording(50, 50);
5563 for (auto color : { SK_ColorRED, SK_ColorBLUE, 0xff007f00 } ) {
5564 SkPaint paint;
5565 paint.setColor(color);
5566 recordingCanvas->drawRect({10, 10, 30, 40}, paint);
5567 recordingCanvas->translate(10, 10);
5568 recordingCanvas->scale(1.2f, 1.4f);
5569 }
5570 sk_sp<SkPicture> playback = recorder.finishRecordingAsPicture();
Cary Clarkbad5ad72017-08-03 17:14:08 -04005571 canvas->drawPicture(playback);
5572 canvas->scale(2, 2);
5573 canvas->translate(50, 0);
5574 canvas->drawPicture(playback);
Cary Clark8032b982017-07-28 11:04:54 -04005575}
5576##
5577
Cary Clark2ade9972017-11-02 17:49:34 -04005578#SeeAlso drawDrawable SkPicture SkPicture::playback
Cary Clark8032b982017-07-28 11:04:54 -04005579
5580##
5581
5582# ------------------------------------------------------------------------------
5583
Herb Derbyefe39bc2018-05-01 17:06:20 -04005584#Method void drawPicture(const sk_sp<SkPicture>& picture)
Cary Clark8032b982017-07-28 11:04:54 -04005585
Cary Clark80247e52018-07-11 16:18:41 -04005586Draws Picture picture, using Clip and Matrix.
Cary Clark8032b982017-07-28 11:04:54 -04005587Clip and Matrix are unchanged by picture contents, as if
5588save() was called before and restore() was called after drawPicture.
5589
5590Picture records a series of draw commands for later playback.
5591
Cary Clarkbad5ad72017-08-03 17:14:08 -04005592#Param picture recorded drawing commands to play ##
Cary Clark8032b982017-07-28 11:04:54 -04005593
5594#Example
Herb Derbyefe39bc2018-05-01 17:06:20 -04005595void draw(SkCanvas* canvas) {
Cary Clarkbad5ad72017-08-03 17:14:08 -04005596 SkPictureRecorder recorder;
5597 SkCanvas* recordingCanvas = recorder.beginRecording(50, 50);
5598 for (auto color : { SK_ColorRED, SK_ColorBLUE, 0xff007f00 } ) {
5599 SkPaint paint;
5600 paint.setColor(color);
5601 recordingCanvas->drawRect({10, 10, 30, 40}, paint);
5602 recordingCanvas->translate(10, 10);
5603 recordingCanvas->scale(1.2f, 1.4f);
5604 }
5605 sk_sp<SkPicture> playback = recorder.finishRecordingAsPicture();
5606 canvas->drawPicture(playback);
5607 canvas->scale(2, 2);
5608 canvas->translate(50, 0);
5609 canvas->drawPicture(playback);
Cary Clark8032b982017-07-28 11:04:54 -04005610}
5611##
5612
Cary Clark2ade9972017-11-02 17:49:34 -04005613#SeeAlso drawDrawable SkPicture SkPicture::playback
Cary Clark8032b982017-07-28 11:04:54 -04005614
5615##
5616
5617# ------------------------------------------------------------------------------
5618
5619#Method void drawPicture(const SkPicture* picture, const SkMatrix* matrix, const SkPaint* paint)
5620
Cary Clark80247e52018-07-11 16:18:41 -04005621Draws Picture picture, using Clip and Matrix; transforming picture with
Cary Clarkbad5ad72017-08-03 17:14:08 -04005622Matrix matrix, if provided; and use Paint paint Color_Alpha, Color_Filter,
5623Image_Filter, and Blend_Mode, if provided.
Cary Clark8032b982017-07-28 11:04:54 -04005624
5625matrix transformation is equivalent to: save(), concat(), drawPicture, restore().
5626paint use is equivalent to: saveLayer, drawPicture, restore().
5627
Cary Clarkbad5ad72017-08-03 17:14:08 -04005628#Param picture recorded drawing commands to play ##
5629#Param matrix Matrix to rotate, scale, translate, and so on; may be nullptr ##
5630#Param paint Paint to apply transparency, filtering, and so on; may be nullptr ##
Cary Clark8032b982017-07-28 11:04:54 -04005631
5632#Example
Herb Derbyefe39bc2018-05-01 17:06:20 -04005633void draw(SkCanvas* canvas) {
Cary Clarkbad5ad72017-08-03 17:14:08 -04005634 SkPaint paint;
5635 SkPictureRecorder recorder;
5636 SkCanvas* recordingCanvas = recorder.beginRecording(50, 50);
5637 for (auto color : { SK_ColorRED, SK_ColorBLUE, 0xff007f00 } ) {
5638 paint.setColor(color);
5639 recordingCanvas->drawRect({10, 10, 30, 40}, paint);
5640 recordingCanvas->translate(10, 10);
5641 recordingCanvas->scale(1.2f, 1.4f);
5642 }
5643 sk_sp<SkPicture> playback = recorder.finishRecordingAsPicture();
5644 const SkPicture* playbackPtr = playback.get();
5645 SkMatrix matrix;
5646 matrix.reset();
5647 for (auto alpha : { 70, 140, 210 } ) {
5648 paint.setAlpha(alpha);
5649 canvas->drawPicture(playbackPtr, &matrix, &paint);
5650 matrix.preTranslate(70, 70);
5651 }
Cary Clark8032b982017-07-28 11:04:54 -04005652}
5653##
5654
Cary Clark2ade9972017-11-02 17:49:34 -04005655#SeeAlso drawDrawable SkPicture SkPicture::playback
Cary Clark8032b982017-07-28 11:04:54 -04005656
5657##
5658
5659# ------------------------------------------------------------------------------
5660
Herb Derbyefe39bc2018-05-01 17:06:20 -04005661#Method void drawPicture(const sk_sp<SkPicture>& picture, const SkMatrix* matrix, const SkPaint* paint)
Cary Clark8032b982017-07-28 11:04:54 -04005662
Cary Clark80247e52018-07-11 16:18:41 -04005663Draws Picture picture, using Clip and Matrix; transforming picture with
Cary Clarkbad5ad72017-08-03 17:14:08 -04005664Matrix matrix, if provided; and use Paint paint Color_Alpha, Color_Filter,
5665Image_Filter, and Blend_Mode, if provided.
Cary Clark8032b982017-07-28 11:04:54 -04005666
5667matrix transformation is equivalent to: save(), concat(), drawPicture, restore().
5668paint use is equivalent to: saveLayer, drawPicture, restore().
5669
Cary Clarkbad5ad72017-08-03 17:14:08 -04005670#Param picture recorded drawing commands to play ##
5671#Param matrix Matrix to rotate, scale, translate, and so on; may be nullptr ##
5672#Param paint Paint to apply transparency, filtering, and so on; may be nullptr ##
Cary Clark8032b982017-07-28 11:04:54 -04005673
5674#Example
Herb Derbyefe39bc2018-05-01 17:06:20 -04005675void draw(SkCanvas* canvas) {
Cary Clarkbad5ad72017-08-03 17:14:08 -04005676 SkPaint paint;
5677 SkPictureRecorder recorder;
5678 SkCanvas* recordingCanvas = recorder.beginRecording(50, 50);
5679 for (auto color : { SK_ColorRED, SK_ColorBLUE, 0xff007f00 } ) {
5680 paint.setColor(color);
5681 recordingCanvas->drawRect({10, 10, 30, 40}, paint);
5682 recordingCanvas->translate(10, 10);
5683 recordingCanvas->scale(1.2f, 1.4f);
5684 }
5685 sk_sp<SkPicture> playback = recorder.finishRecordingAsPicture();
5686 SkMatrix matrix;
5687 matrix.reset();
5688 for (auto alpha : { 70, 140, 210 } ) {
5689 paint.setAlpha(alpha);
5690 canvas->drawPicture(playback, &matrix, &paint);
5691 matrix.preTranslate(70, 70);
5692 }
Cary Clark8032b982017-07-28 11:04:54 -04005693}
5694##
5695
Cary Clark2ade9972017-11-02 17:49:34 -04005696#SeeAlso drawDrawable SkPicture SkPicture::playback
Cary Clark8032b982017-07-28 11:04:54 -04005697
5698##
5699
5700# ------------------------------------------------------------------------------
5701
5702#Method void drawVertices(const SkVertices* vertices, SkBlendMode mode, const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05005703#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05005704#Line # draws Vertices, a triangle mesh ##
Cary Clark80247e52018-07-11 16:18:41 -04005705Draws Vertices vertices, a triangle mesh, using Clip and Matrix.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005706If Vertices_Texs and Vertices_Colors are defined in vertices, and Paint paint
5707contains Shader, Blend_Mode mode combines Vertices_Colors with Shader.
Cary Clark8032b982017-07-28 11:04:54 -04005708
Cary Clarkbad5ad72017-08-03 17:14:08 -04005709#Param vertices triangle mesh to draw ##
5710#Param mode combines Vertices_Colors with Shader, if both are present ##
5711#Param paint specifies the Shader, used as Vertices texture; may be nullptr ##
Cary Clark8032b982017-07-28 11:04:54 -04005712
5713#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04005714void draw(SkCanvas* canvas) {
5715 SkPaint paint;
5716 SkPoint points[] = { { 0, 0 }, { 250, 0 }, { 100, 100 }, { 0, 250 } };
5717 SkColor colors[] = { SK_ColorRED, SK_ColorBLUE, SK_ColorYELLOW, SK_ColorCYAN };
5718 auto vertices = SkVertices::MakeCopy(SkVertices::kTriangleFan_VertexMode,
5719 SK_ARRAY_COUNT(points), points, nullptr, colors);
5720 canvas->drawVertices(vertices.get(), SkBlendMode::kSrc, paint);
5721}
Cary Clark8032b982017-07-28 11:04:54 -04005722##
5723
Cary Clark2ade9972017-11-02 17:49:34 -04005724#SeeAlso drawPatch drawPicture
Cary Clark8032b982017-07-28 11:04:54 -04005725
5726##
5727
5728# ------------------------------------------------------------------------------
5729
5730#Method void drawVertices(const sk_sp<SkVertices>& vertices, SkBlendMode mode, const SkPaint& paint)
5731
Cary Clark80247e52018-07-11 16:18:41 -04005732Draws Vertices vertices, a triangle mesh, using Clip and Matrix.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005733If Vertices_Texs and Vertices_Colors are defined in vertices, and Paint paint
5734contains Shader, Blend_Mode mode combines Vertices_Colors with Shader.
Cary Clark8032b982017-07-28 11:04:54 -04005735
Cary Clarkbad5ad72017-08-03 17:14:08 -04005736#Param vertices triangle mesh to draw ##
5737#Param mode combines Vertices_Colors with Shader, if both are present ##
5738#Param paint specifies the Shader, used as Vertices texture, may be nullptr ##
Cary Clark8032b982017-07-28 11:04:54 -04005739
5740#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04005741void draw(SkCanvas* canvas) {
5742 SkPaint paint;
5743 SkPoint points[] = { { 0, 0 }, { 250, 0 }, { 100, 100 }, { 0, 250 } };
5744 SkPoint texs[] = { { 0, 0 }, { 0, 250 }, { 250, 250 }, { 250, 0 } };
5745 SkColor colors[] = { SK_ColorRED, SK_ColorBLUE, SK_ColorYELLOW, SK_ColorCYAN };
5746 paint.setShader(SkGradientShader::MakeLinear(points, colors, nullptr, 4,
5747 SkShader::kClamp_TileMode));
5748 auto vertices = SkVertices::MakeCopy(SkVertices::kTriangleFan_VertexMode,
5749 SK_ARRAY_COUNT(points), points, texs, colors);
Ruiqi Mao94d57c42018-07-02 15:20:10 -04005750 canvas->drawVertices(vertices, SkBlendMode::kDarken, paint);
5751}
5752##
5753
5754#SeeAlso drawPatch drawPicture
5755
5756##
5757
5758# ------------------------------------------------------------------------------
5759
5760#Method void drawVertices(const SkVertices* vertices, const SkMatrix* bones, int boneCount,
5761 SkBlendMode mode, const SkPaint& paint)
5762
Cary Clark80247e52018-07-11 16:18:41 -04005763Draws Vertices vertices, a triangle mesh, using Clip and Matrix. Bone data is used to
Ruiqi Mao94d57c42018-07-02 15:20:10 -04005764deform vertices with bone weights.
5765If Vertices_Texs and Vertices_Colors are defined in vertices, and Paint paint
5766contains Shader, Blend_Mode mode combines Vertices_Colors with Shader.
5767The first element of bones should be an object to world space transformation matrix that
5768will be applied before performing mesh deformations. If no such transformation is needed,
5769it should be the identity matrix.
Ruiqi Mao9a6e42f2018-07-09 14:16:56 -04005770boneCount must be at most 100, and thus the size of bones should be at most 100.
Ruiqi Mao94d57c42018-07-02 15:20:10 -04005771
5772#Param vertices triangle mesh to draw ##
5773#Param bones bone matrix data ##
5774#Param boneCount number of bone matrices ##
5775#Param mode combines Vertices_Colors with Shader, if both are present ##
5776#Param paint specifies the Shader, used as Vertices texture, may be nullptr ##
5777
5778#Example
5779void draw(SkCanvas* canvas) {
5780 SkPaint paint;
5781 SkPoint points[] = { { 0, 0 }, { 250, 0 }, { 100, 100 }, { 0, 250 } };
5782 SkPoint texs[] = { { 0, 0 }, { 0, 250 }, { 250, 250 }, { 250, 0 } };
5783 SkColor colors[] = { SK_ColorRED, SK_ColorBLUE, SK_ColorYELLOW, SK_ColorCYAN };
5784 SkVertices::BoneIndices boneIndices[] = { { 0, 0, 0, 0 },
5785 { 1, 0, 0, 0 },
5786 { 2, 0, 0, 0 },
5787 { 3, 0, 0, 0 } };
5788 SkVertices::BoneWeights boneWeights[] = { { 0.0f, 0.0f, 0.0f, 0.0f },
5789 { 1.0f, 0.0f, 0.0f, 0.0f },
5790 { 1.0f, 0.0f, 0.0f, 0.0f },
5791 { 1.0f, 0.0f, 0.0f, 0.0f } };
5792 SkMatrix bones[] = { SkMatrix::I(),
5793 SkMatrix::MakeTrans(0, 20),
5794 SkMatrix::MakeTrans(50, 50),
5795 SkMatrix::MakeTrans(20, 0) };
5796 paint.setShader(SkGradientShader::MakeLinear(points, colors, nullptr, 4,
5797 SkShader::kClamp_TileMode));
5798 auto vertices = SkVertices::MakeCopy(SkVertices::kTriangleFan_VertexMode,
5799 SK_ARRAY_COUNT(points), points, texs, colors, boneIndices, boneWeights);
5800 canvas->drawVertices(vertices.get(), bones, SK_ARRAY_COUNT(bones), SkBlendMode::kDarken, paint);
5801}
5802##
5803
5804#SeeAlso drawPatch drawPicture
5805
5806##
5807
5808# ------------------------------------------------------------------------------
5809
5810#Method void drawVertices(const sk_sp<SkVertices>& vertices, const SkMatrix* bones, int boneCount,
5811 SkBlendMode mode, const SkPaint& paint)
5812
Cary Clark80247e52018-07-11 16:18:41 -04005813Draws Vertices vertices, a triangle mesh, using Clip and Matrix. Bone data is used to
Ruiqi Mao94d57c42018-07-02 15:20:10 -04005814deform vertices with bone weights.
5815If Vertices_Texs and Vertices_Colors are defined in vertices, and Paint paint
5816contains Shader, Blend_Mode mode combines Vertices_Colors with Shader.
5817The first element of bones should be an object to world space transformation matrix that
5818will be applied before performing mesh deformations. If no such transformation is needed,
5819it should be the identity matrix.
Ruiqi Mao9a6e42f2018-07-09 14:16:56 -04005820boneCount must be at most 100, and thus the size of bones should be at most 100.
Ruiqi Mao94d57c42018-07-02 15:20:10 -04005821
5822#Param vertices triangle mesh to draw ##
5823#Param bones bone matrix data ##
5824#Param boneCount number of bone matrices ##
5825#Param mode combines Vertices_Colors with Shader, if both are present ##
5826#Param paint specifies the Shader, used as Vertices texture, may be nullptr ##
5827
5828#Example
5829void draw(SkCanvas* canvas) {
5830 SkPaint paint;
5831 SkPoint points[] = { { 0, 0 }, { 250, 0 }, { 100, 100 }, { 0, 250 } };
5832 SkPoint texs[] = { { 0, 0 }, { 0, 250 }, { 250, 250 }, { 250, 0 } };
5833 SkColor colors[] = { SK_ColorRED, SK_ColorBLUE, SK_ColorYELLOW, SK_ColorCYAN };
5834 SkVertices::BoneIndices boneIndices[] = { { 0, 0, 0, 0 },
5835 { 1, 0, 0, 0 },
5836 { 2, 0, 0, 0 },
5837 { 3, 0, 0, 0 } };
5838 SkVertices::BoneWeights boneWeights[] = { { 0.0f, 0.0f, 0.0f, 0.0f },
5839 { 1.0f, 0.0f, 0.0f, 0.0f },
5840 { 1.0f, 0.0f, 0.0f, 0.0f },
5841 { 1.0f, 0.0f, 0.0f, 0.0f } };
5842 SkMatrix bones[] = { SkMatrix::I(),
5843 SkMatrix::MakeTrans(0, 20),
5844 SkMatrix::MakeTrans(50, 50),
5845 SkMatrix::MakeTrans(20, 0) };
5846 paint.setShader(SkGradientShader::MakeLinear(points, colors, nullptr, 4,
5847 SkShader::kClamp_TileMode));
5848 auto vertices = SkVertices::MakeCopy(SkVertices::kTriangleFan_VertexMode,
5849 SK_ARRAY_COUNT(points), points, texs, colors, boneIndices, boneWeights);
5850 canvas->drawVertices(vertices, bones, SK_ARRAY_COUNT(bones), SkBlendMode::kDarken, paint);
Cary Clark8032b982017-07-28 11:04:54 -04005851}
5852##
5853
Cary Clark2ade9972017-11-02 17:49:34 -04005854#SeeAlso drawPatch drawPicture
Cary Clark8032b982017-07-28 11:04:54 -04005855
5856##
5857
5858# ------------------------------------------------------------------------------
5859
5860#Method void drawPatch(const SkPoint cubics[12], const SkColor colors[4],
5861 const SkPoint texCoords[4], SkBlendMode mode, const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05005862#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05005863#Line # draws Coons_Patch ##
Cary Clark8032b982017-07-28 11:04:54 -04005864
Herb Derbyefe39bc2018-05-01 17:06:20 -04005865Draws a Coons_Patch: the interpolation of four cubics with shared corners,
Cary Clark5538c132018-06-14 12:28:14 -04005866associating a color, and optionally a texture Point, with each corner.
Cary Clark8032b982017-07-28 11:04:54 -04005867
Cary Clarka560c472017-11-27 10:44:06 -05005868Coons_Patch uses Clip and Matrix, paint Shader, Color_Filter,
Cary Clarkbad5ad72017-08-03 17:14:08 -04005869Color_Alpha, Image_Filter, and Blend_Mode. If Shader is provided it is treated
Cary Clarka560c472017-11-27 10:44:06 -05005870as Coons_Patch texture; Blend_Mode mode combines Color colors and Shader if
Cary Clarkbad5ad72017-08-03 17:14:08 -04005871both are provided.
Cary Clark8032b982017-07-28 11:04:54 -04005872
Herb Derbyefe39bc2018-05-01 17:06:20 -04005873Point array cubics specifies four Cubics starting at the top-left corner,
Cary Clarkce101242017-09-01 15:51:02 -04005874in clockwise order, sharing every fourth point. The last Cubic ends at the
Cary Clarkbad5ad72017-08-03 17:14:08 -04005875first point.
Cary Clark8032b982017-07-28 11:04:54 -04005876
Cary Clarkbc5697d2017-10-04 14:31:33 -04005877Color array color associates colors with corners in top-left, top-right,
5878bottom-right, bottom-left order.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005879
5880If paint contains Shader, Point array texCoords maps Shader as texture to
Cary Clarkbc5697d2017-10-04 14:31:33 -04005881corners in top-left, top-right, bottom-right, bottom-left order.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005882
Cary Clarka523d2d2017-08-30 08:58:10 -04005883#Param cubics Path_Cubic array, sharing common points ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005884#Param colors Color array, one for each corner ##
Cary Clarkce101242017-09-01 15:51:02 -04005885#Param texCoords Point array of texture coordinates, mapping Shader to corners;
Herb Derbyefe39bc2018-05-01 17:06:20 -04005886 may be nullptr
Cary Clark579985c2017-07-31 11:48:27 -04005887#Param ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005888#Param mode Blend_Mode for colors, and for Shader if paint has one ##
5889#Param paint Shader, Color_Filter, Blend_Mode, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005890
5891#Example
5892#Image 5
Cary Clarkbad5ad72017-08-03 17:14:08 -04005893void draw(SkCanvas* canvas) {
5894 // SkBitmap source = cmbkygk;
5895 SkPaint paint;
5896 paint.setFilterQuality(kLow_SkFilterQuality);
5897 paint.setAntiAlias(true);
5898 SkPoint cubics[] = { { 3, 1 }, { 4, 2 }, { 5, 1 }, { 7, 3 },
5899 /* { 7, 3 }, */ { 6, 4 }, { 7, 5 }, { 5, 7 },
5900 /* { 5, 7 }, */ { 4, 6 }, { 3, 7 }, { 1, 5 },
5901 /* { 1, 5 }, */ { 2, 4 }, { 1, 3 }, /* { 3, 1 } */ };
5902 SkColor colors[] = { 0xbfff0000, 0xbf0000ff, 0xbfff00ff, 0xbf00ffff };
5903 SkPoint texCoords[] = { { -30, -30 }, { 162, -30}, { 162, 162}, { -30, 162} };
5904 paint.setShader(SkShader::MakeBitmapShader(source, SkShader::kClamp_TileMode,
5905 SkShader::kClamp_TileMode, nullptr));
5906 canvas->scale(15, 15);
5907 for (auto blend : { SkBlendMode::kSrcOver, SkBlendMode::kModulate, SkBlendMode::kXor } ) {
5908 canvas->drawPatch(cubics, colors, texCoords, blend, paint);
5909 canvas->translate(4, 4);
5910 }
Cary Clark8032b982017-07-28 11:04:54 -04005911}
5912##
5913
Cary Clark2ade9972017-11-02 17:49:34 -04005914#ToDo can patch use image filter? ##
5915#SeeAlso SeeAlso drawVertices drawPicture
Cary Clark8032b982017-07-28 11:04:54 -04005916
5917##
5918
5919# ------------------------------------------------------------------------------
5920
5921#Method void drawPatch(const SkPoint cubics[12], const SkColor colors[4],
Herb Derbyefe39bc2018-05-01 17:06:20 -04005922 const SkPoint texCoords[4], const SkPaint& paint)
Cary Clark8032b982017-07-28 11:04:54 -04005923
Herb Derbyefe39bc2018-05-01 17:06:20 -04005924Draws Cubic Coons_Patch: the interpolation of four cubics with shared corners,
Cary Clark5538c132018-06-14 12:28:14 -04005925associating a color, and optionally a texture Point, with each corner.
Cary Clark8032b982017-07-28 11:04:54 -04005926
Cary Clarka560c472017-11-27 10:44:06 -05005927Coons_Patch uses Clip and Matrix, paint Shader, Color_Filter,
Cary Clarkbad5ad72017-08-03 17:14:08 -04005928Color_Alpha, Image_Filter, and Blend_Mode. If Shader is provided it is treated
Cary Clarka560c472017-11-27 10:44:06 -05005929as Coons_Patch texture; Blend_Mode mode combines Color colors and Shader if
Cary Clarkbad5ad72017-08-03 17:14:08 -04005930both are provided.
Cary Clark8032b982017-07-28 11:04:54 -04005931
Herb Derbyefe39bc2018-05-01 17:06:20 -04005932Point array cubics specifies four Cubics starting at the top-left corner,
Cary Clarkce101242017-09-01 15:51:02 -04005933in clockwise order, sharing every fourth point. The last Cubic ends at the
Cary Clarkbad5ad72017-08-03 17:14:08 -04005934first point.
5935
Cary Clarkbc5697d2017-10-04 14:31:33 -04005936Color array color associates colors with corners in top-left, top-right,
5937bottom-right, bottom-left order.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005938
5939If paint contains Shader, Point array texCoords maps Shader as texture to
Cary Clarkbc5697d2017-10-04 14:31:33 -04005940corners in top-left, top-right, bottom-right, bottom-left order.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005941
Cary Clarka523d2d2017-08-30 08:58:10 -04005942#Param cubics Path_Cubic array, sharing common points ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005943#Param colors Color array, one for each corner ##
Cary Clarkce101242017-09-01 15:51:02 -04005944#Param texCoords Point array of texture coordinates, mapping Shader to corners;
Herb Derbyefe39bc2018-05-01 17:06:20 -04005945 may be nullptr
Cary Clark579985c2017-07-31 11:48:27 -04005946#Param ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005947#Param paint Shader, Color_Filter, Blend_Mode, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005948
5949#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04005950void draw(SkCanvas* canvas) {
5951 SkPaint paint;
5952 paint.setAntiAlias(true);
5953 SkPoint cubics[] = { { 3, 1 }, { 4, 2 }, { 5, 1 }, { 7, 3 },
5954 /* { 7, 3 }, */ { 6, 4 }, { 7, 5 }, { 5, 7 },
5955 /* { 5, 7 }, */ { 4, 6 }, { 3, 7 }, { 1, 5 },
5956 /* { 1, 5 }, */ { 2, 4 }, { 1, 3 }, /* { 3, 1 } */ };
5957 SkColor colors[] = { SK_ColorRED, SK_ColorBLUE, SK_ColorYELLOW, SK_ColorCYAN };
5958 canvas->scale(30, 30);
5959 canvas->drawPatch(cubics, colors, nullptr, paint);
5960 SkPoint text[] = { {3,0.9f}, {4,2.5f}, {5,0.9f}, {7.5f,3.2f}, {5.5f,4.2f},
5961 {7.5f,5.2f}, {5,7.5f}, {4,5.9f}, {3,7.5f}, {0.5f,5.2f}, {2.5f,4.2f},
5962 {0.5f,3.2f} };
5963 paint.setTextSize(18.f / 30);
5964 paint.setTextAlign(SkPaint::kCenter_Align);
5965 for (int i = 0; i< 10; ++i) {
5966 char digit = '0' + i;
5967 canvas->drawText(&digit, 1, text[i].fX, text[i].fY, paint);
5968 }
5969 canvas->drawString("10", text[10].fX, text[10].fY, paint);
5970 canvas->drawString("11", text[11].fX, text[11].fY, paint);
5971 paint.setStyle(SkPaint::kStroke_Style);
5972 canvas->drawPoints(SkCanvas::kPolygon_PointMode, 12, cubics, paint);
5973 canvas->drawLine(cubics[11].fX, cubics[11].fY, cubics[0].fX, cubics[0].fY, paint);
Cary Clark8032b982017-07-28 11:04:54 -04005974}
5975##
5976
5977#Example
5978#Image 6
Cary Clarkbad5ad72017-08-03 17:14:08 -04005979void draw(SkCanvas* canvas) {
5980 // SkBitmap source = checkerboard;
5981 SkPaint paint;
5982 paint.setFilterQuality(kLow_SkFilterQuality);
5983 paint.setAntiAlias(true);
5984 SkPoint cubics[] = { { 3, 1 }, { 4, 2 }, { 5, 1 }, { 7, 3 },
5985 /* { 7, 3 }, */ { 6, 4 }, { 7, 5 }, { 5, 7 },
5986 /* { 5, 7 }, */ { 4, 6 }, { 3, 7 }, { 1, 5 },
5987 /* { 1, 5 }, */ { 2, 4 }, { 1, 3 }, /* { 3, 1 } */ };
5988 SkPoint texCoords[] = { { 0, 0 }, { 0, 62}, { 62, 62}, { 62, 0 } };
5989 paint.setShader(SkShader::MakeBitmapShader(source, SkShader::kClamp_TileMode,
5990 SkShader::kClamp_TileMode, nullptr));
5991 canvas->scale(30, 30);
5992 canvas->drawPatch(cubics, nullptr, texCoords, paint);
Cary Clark8032b982017-07-28 11:04:54 -04005993}
5994##
5995
Cary Clark2ade9972017-11-02 17:49:34 -04005996#ToDo can patch use image filter? ##
5997#SeeAlso SeeAlso drawVertices drawPicture
Cary Clark8032b982017-07-28 11:04:54 -04005998
5999##
6000
6001# ------------------------------------------------------------------------------
6002
6003#Method void drawAtlas(const SkImage* atlas, const SkRSXform xform[], const SkRect tex[],
6004 const SkColor colors[], int count, SkBlendMode mode, const SkRect* cullRect,
6005 const SkPaint* paint)
Cary Clark78de7512018-02-07 07:27:09 -05006006#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05006007#Line # draws sprites using Clip, Matrix, and Paint ##
Cary Clark8032b982017-07-28 11:04:54 -04006008
Cary Clark80247e52018-07-11 16:18:41 -04006009Draws a set of sprites from atlas, using Clip, Matrix, and optional Paint paint.
Cary Clarkffb3d682018-05-17 12:17:28 -04006010paint uses Anti_Alias, Color_Alpha, Color_Filter, Image_Filter, and Blend_Mode
Cary Clarkbad5ad72017-08-03 17:14:08 -04006011to draw, if present. For each entry in the array, Rect tex locates sprite in
6012atlas, and RSXform xform transforms it into destination space.
6013
Cary Clark8032b982017-07-28 11:04:54 -04006014xform, text, and colors if present, must contain count entries.
Cary Clark224c7002018-06-27 11:00:21 -04006015Optional colors are applied for each sprite using Blend_Mode mode, treating
6016sprite as source and colors as destination.
Herb Derbyefe39bc2018-05-01 17:06:20 -04006017Optional cullRect is a conservative bounds of all transformed sprites.
Cary Clarkce101242017-09-01 15:51:02 -04006018If cullRect is outside of Clip, canvas can skip drawing.
Cary Clark8032b982017-07-28 11:04:54 -04006019
Cary Clark224c7002018-06-27 11:00:21 -04006020
6021
Cary Clarkbad5ad72017-08-03 17:14:08 -04006022#Param atlas Image containing sprites ##
6023#Param xform RSXform mappings for sprites in atlas ##
6024#Param tex Rect locations of sprites in atlas ##
Cary Clark6fc50412017-09-21 12:31:06 -04006025#Param colors one per sprite, blended with sprite using Blend_Mode; may be nullptr ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04006026#Param count number of sprites to draw ##
6027#Param mode Blend_Mode combining colors and sprites ##
Cary Clark6fc50412017-09-21 12:31:06 -04006028#Param cullRect bounds of transformed sprites for efficient clipping; may be nullptr ##
6029#Param paint Color_Filter, Image_Filter, Blend_Mode, and so on; may be nullptr ##
Cary Clark8032b982017-07-28 11:04:54 -04006030
6031#Example
6032#Image 3
Cary Clarkbad5ad72017-08-03 17:14:08 -04006033void draw(SkCanvas* canvas) {
6034 // SkBitmap source = mandrill;
6035 SkRSXform xforms[] = { { .5f, 0, 0, 0 }, {0, .5f, 200, 100 } };
6036 SkRect tex[] = { { 0, 0, 250, 250 }, { 0, 0, 250, 250 } };
6037 SkColor colors[] = { 0x7f55aa00, 0x7f3333bf };
6038 const SkImage* imagePtr = image.get();
6039 canvas->drawAtlas(imagePtr, xforms, tex, colors, 2, SkBlendMode::kSrcOver, nullptr, nullptr);
Cary Clark8032b982017-07-28 11:04:54 -04006040}
6041##
6042
Cary Clark2ade9972017-11-02 17:49:34 -04006043#SeeAlso drawBitmap drawImage
Cary Clark8032b982017-07-28 11:04:54 -04006044
6045##
6046
6047# ------------------------------------------------------------------------------
6048
6049#Method void drawAtlas(const sk_sp<SkImage>& atlas, const SkRSXform xform[], const SkRect tex[],
6050 const SkColor colors[], int count, SkBlendMode mode, const SkRect* cullRect,
Herb Derbyefe39bc2018-05-01 17:06:20 -04006051 const SkPaint* paint)
Cary Clark8032b982017-07-28 11:04:54 -04006052
Cary Clark80247e52018-07-11 16:18:41 -04006053Draws a set of sprites from atlas, using Clip, Matrix, and optional Paint paint.
Cary Clarkffb3d682018-05-17 12:17:28 -04006054paint uses Anti_Alias, Color_Alpha, Color_Filter, Image_Filter, and Blend_Mode
Cary Clarkbad5ad72017-08-03 17:14:08 -04006055to draw, if present. For each entry in the array, Rect tex locates sprite in
6056atlas, and RSXform xform transforms it into destination space.
6057
Cary Clark8032b982017-07-28 11:04:54 -04006058xform, text, and colors if present, must contain count entries.
6059Optional colors is applied for each sprite using Blend_Mode.
Herb Derbyefe39bc2018-05-01 17:06:20 -04006060Optional cullRect is a conservative bounds of all transformed sprites.
Cary Clarkce101242017-09-01 15:51:02 -04006061If cullRect is outside of Clip, canvas can skip drawing.
Cary Clark8032b982017-07-28 11:04:54 -04006062
Cary Clarkbad5ad72017-08-03 17:14:08 -04006063#Param atlas Image containing sprites ##
6064#Param xform RSXform mappings for sprites in atlas ##
6065#Param tex Rect locations of sprites in atlas ##
Cary Clark6fc50412017-09-21 12:31:06 -04006066#Param colors one per sprite, blended with sprite using Blend_Mode; may be nullptr ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04006067#Param count number of sprites to draw ##
6068#Param mode Blend_Mode combining colors and sprites ##
Cary Clark6fc50412017-09-21 12:31:06 -04006069#Param cullRect bounds of transformed sprites for efficient clipping; may be nullptr ##
6070#Param paint Color_Filter, Image_Filter, Blend_Mode, and so on; may be nullptr ##
Cary Clark8032b982017-07-28 11:04:54 -04006071
6072#Example
6073#Image 3
Cary Clarkbad5ad72017-08-03 17:14:08 -04006074void draw(SkCanvas* canvas) {
6075 // SkBitmap source = mandrill;
6076 SkRSXform xforms[] = { { .5f, 0, 0, 0 }, {0, .5f, 200, 100 } };
6077 SkRect tex[] = { { 0, 0, 250, 250 }, { 0, 0, 250, 250 } };
6078 SkColor colors[] = { 0x7f55aa00, 0x7f3333bf };
6079 SkPaint paint;
6080 paint.setAlpha(127);
6081 canvas->drawAtlas(image, xforms, tex, colors, 2, SkBlendMode::kPlus, nullptr, &paint);
Cary Clark8032b982017-07-28 11:04:54 -04006082}
6083##
6084
6085#ToDo bug in example on cpu side, gpu looks ok ##
6086
Cary Clark2ade9972017-11-02 17:49:34 -04006087#SeeAlso drawBitmap drawImage
6088
Cary Clark8032b982017-07-28 11:04:54 -04006089##
6090
6091# ------------------------------------------------------------------------------
6092
6093#Method void drawAtlas(const SkImage* atlas, const SkRSXform xform[], const SkRect tex[], int count,
Herb Derbyefe39bc2018-05-01 17:06:20 -04006094 const SkRect* cullRect, const SkPaint* paint)
Cary Clark8032b982017-07-28 11:04:54 -04006095
Cary Clark80247e52018-07-11 16:18:41 -04006096Draws a set of sprites from atlas, using Clip, Matrix, and optional Paint paint.
Cary Clarkffb3d682018-05-17 12:17:28 -04006097paint uses Anti_Alias, Color_Alpha, Color_Filter, Image_Filter, and Blend_Mode
Cary Clarkbad5ad72017-08-03 17:14:08 -04006098to draw, if present. For each entry in the array, Rect tex locates sprite in
6099atlas, and RSXform xform transforms it into destination space.
6100
Cary Clark8032b982017-07-28 11:04:54 -04006101xform and text must contain count entries.
Herb Derbyefe39bc2018-05-01 17:06:20 -04006102Optional cullRect is a conservative bounds of all transformed sprites.
Cary Clarkce101242017-09-01 15:51:02 -04006103If cullRect is outside of Clip, canvas can skip drawing.
Cary Clark8032b982017-07-28 11:04:54 -04006104
Cary Clarkbad5ad72017-08-03 17:14:08 -04006105#Param atlas Image containing sprites ##
6106#Param xform RSXform mappings for sprites in atlas ##
6107#Param tex Rect locations of sprites in atlas ##
6108#Param count number of sprites to draw ##
Cary Clark6fc50412017-09-21 12:31:06 -04006109#Param cullRect bounds of transformed sprites for efficient clipping; may be nullptr ##
6110#Param paint Color_Filter, Image_Filter, Blend_Mode, and so on; may be nullptr ##
Cary Clark8032b982017-07-28 11:04:54 -04006111
6112#Example
6113#Image 3
Cary Clarkbad5ad72017-08-03 17:14:08 -04006114void draw(SkCanvas* canvas) {
6115 // sk_sp<SkImage> image = mandrill;
6116 SkRSXform xforms[] = { { .5f, 0, 0, 0 }, {0, .5f, 200, 100 } };
6117 SkRect tex[] = { { 0, 0, 250, 250 }, { 0, 0, 250, 250 } };
6118 const SkImage* imagePtr = image.get();
6119 canvas->drawAtlas(imagePtr, xforms, tex, 2, nullptr, nullptr);
Cary Clark8032b982017-07-28 11:04:54 -04006120}
6121##
6122
Cary Clark2ade9972017-11-02 17:49:34 -04006123#SeeAlso drawBitmap drawImage
Cary Clark8032b982017-07-28 11:04:54 -04006124
6125##
6126
6127# ------------------------------------------------------------------------------
6128
6129#Method void drawAtlas(const sk_sp<SkImage>& atlas, const SkRSXform xform[], const SkRect tex[],
Herb Derbyefe39bc2018-05-01 17:06:20 -04006130 int count, const SkRect* cullRect, const SkPaint* paint)
Cary Clark8032b982017-07-28 11:04:54 -04006131
Cary Clark80247e52018-07-11 16:18:41 -04006132Draws a set of sprites from atlas, using Clip, Matrix, and optional Paint paint.
Cary Clarkffb3d682018-05-17 12:17:28 -04006133paint uses Anti_Alias, Color_Alpha, Color_Filter, Image_Filter, and Blend_Mode
Cary Clarkbad5ad72017-08-03 17:14:08 -04006134to draw, if present. For each entry in the array, Rect tex locates sprite in
6135atlas, and RSXform xform transforms it into destination space.
6136
Cary Clark8032b982017-07-28 11:04:54 -04006137xform and text must contain count entries.
Herb Derbyefe39bc2018-05-01 17:06:20 -04006138Optional cullRect is a conservative bounds of all transformed sprites.
Cary Clarkce101242017-09-01 15:51:02 -04006139If cullRect is outside of Clip, canvas can skip drawing.
Cary Clark8032b982017-07-28 11:04:54 -04006140
Cary Clarkbad5ad72017-08-03 17:14:08 -04006141#Param atlas Image containing sprites ##
6142#Param xform RSXform mappings for sprites in atlas ##
6143#Param tex Rect locations of sprites in atlas ##
6144#Param count number of sprites to draw ##
Cary Clark6fc50412017-09-21 12:31:06 -04006145#Param cullRect bounds of transformed sprites for efficient clipping; may be nullptr ##
6146#Param paint Color_Filter, Image_Filter, Blend_Mode, and so on; may be nullptr ##
Cary Clark8032b982017-07-28 11:04:54 -04006147
6148#Example
6149#Image 3
Cary Clarkbad5ad72017-08-03 17:14:08 -04006150void draw(SkCanvas* canvas) {
6151 // sk_sp<SkImage> image = mandrill;
6152 SkRSXform xforms[] = { { 1, 0, 0, 0 }, {0, 1, 300, 100 } };
6153 SkRect tex[] = { { 0, 0, 200, 200 }, { 200, 0, 400, 200 } };
6154 canvas->drawAtlas(image, xforms, tex, 2, nullptr, nullptr);
Cary Clark8032b982017-07-28 11:04:54 -04006155}
6156##
6157
Cary Clark2ade9972017-11-02 17:49:34 -04006158#SeeAlso drawBitmap drawImage
Cary Clark8032b982017-07-28 11:04:54 -04006159
6160##
6161
6162# ------------------------------------------------------------------------------
6163
Cary Clark73fa9722017-08-29 17:36:51 -04006164#Method void drawDrawable(SkDrawable* drawable, const SkMatrix* matrix = nullptr)
Cary Clark78de7512018-02-07 07:27:09 -05006165#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05006166#Line # draws Drawable, encapsulated drawing commands ##
Cary Clark80247e52018-07-11 16:18:41 -04006167Draws Drawable drawable using Clip and Matrix, concatenated with
Cary Clark8032b982017-07-28 11:04:54 -04006168optional matrix.
6169
Herb Derbyefe39bc2018-05-01 17:06:20 -04006170If Canvas has an asynchronous implementation, as is the case
Cary Clark8032b982017-07-28 11:04:54 -04006171when it is recording into Picture, then drawable will be referenced,
6172so that SkDrawable::draw() can be called when the operation is finalized. To force
6173immediate drawing, call SkDrawable::draw() instead.
6174
Cary Clarkbad5ad72017-08-03 17:14:08 -04006175#Param drawable custom struct encapsulating drawing commands ##
6176#Param matrix transformation applied to drawing; may be nullptr ##
Cary Clark8032b982017-07-28 11:04:54 -04006177
6178#Example
6179#Height 100
6180#Function
Cary Clarkbad5ad72017-08-03 17:14:08 -04006181struct MyDrawable : public SkDrawable {
6182 SkRect onGetBounds() override { return SkRect::MakeWH(50, 100); }
6183
6184 void onDraw(SkCanvas* canvas) override {
6185 SkPath path;
6186 path.conicTo(10, 90, 50, 90, 0.9f);
6187 SkPaint paint;
6188 paint.setColor(SK_ColorBLUE);
6189 canvas->drawRect(path.getBounds(), paint);
6190 paint.setAntiAlias(true);
6191 paint.setColor(SK_ColorWHITE);
6192 canvas->drawPath(path, paint);
6193 }
6194};
6195
6196#Function ##
6197void draw(SkCanvas* canvas) {
6198 sk_sp<SkDrawable> drawable(new MyDrawable);
6199 SkMatrix matrix;
6200 matrix.setTranslate(10, 10);
6201 canvas->drawDrawable(drawable.get(), &matrix);
Cary Clark8032b982017-07-28 11:04:54 -04006202}
6203##
6204
Cary Clark2ade9972017-11-02 17:49:34 -04006205#SeeAlso SkDrawable drawPicture
Cary Clark8032b982017-07-28 11:04:54 -04006206
6207##
6208
6209# ------------------------------------------------------------------------------
6210
6211#Method void drawDrawable(SkDrawable* drawable, SkScalar x, SkScalar y)
6212
Cary Clark80247e52018-07-11 16:18:41 -04006213Draws Drawable drawable using Clip and Matrix, offset by (x, y).
Cary Clark8032b982017-07-28 11:04:54 -04006214
Herb Derbyefe39bc2018-05-01 17:06:20 -04006215If Canvas has an asynchronous implementation, as is the case
Cary Clark8032b982017-07-28 11:04:54 -04006216when it is recording into Picture, then drawable will be referenced,
6217so that SkDrawable::draw() can be called when the operation is finalized. To force
6218immediate drawing, call SkDrawable::draw() instead.
6219
Cary Clarkbad5ad72017-08-03 17:14:08 -04006220#Param drawable custom struct encapsulating drawing commands ##
Cary Clark5538c132018-06-14 12:28:14 -04006221#Param x offset into Canvas writable pixels on x-axis ##
6222#Param y offset into Canvas writable pixels on y-axis ##
Cary Clark8032b982017-07-28 11:04:54 -04006223
6224#Example
6225#Height 100
6226#Function
Cary Clarkbad5ad72017-08-03 17:14:08 -04006227struct MyDrawable : public SkDrawable {
6228 SkRect onGetBounds() override { return SkRect::MakeWH(50, 100); }
6229
6230 void onDraw(SkCanvas* canvas) override {
6231 SkPath path;
6232 path.conicTo(10, 90, 50, 90, 0.9f);
6233 SkPaint paint;
6234 paint.setColor(SK_ColorBLUE);
6235 canvas->drawRect(path.getBounds(), paint);
6236 paint.setAntiAlias(true);
6237 paint.setColor(SK_ColorWHITE);
6238 canvas->drawPath(path, paint);
6239 }
6240};
6241
6242#Function ##
6243void draw(SkCanvas* canvas) {
6244 sk_sp<SkDrawable> drawable(new MyDrawable);
6245 canvas->drawDrawable(drawable.get(), 10, 10);
Cary Clark8032b982017-07-28 11:04:54 -04006246}
6247##
6248
Cary Clark2ade9972017-11-02 17:49:34 -04006249#SeeAlso SkDrawable drawPicture
Cary Clark8032b982017-07-28 11:04:54 -04006250
6251##
6252
6253# ------------------------------------------------------------------------------
6254
6255#Method void drawAnnotation(const SkRect& rect, const char key[], SkData* value)
Cary Clark78de7512018-02-07 07:27:09 -05006256#In Draw
6257#In Utility
Cary Clarkab2621d2018-01-30 10:08:57 -05006258#Line # associates a Rect with a key-value pair ##
Cary Clark80247e52018-07-11 16:18:41 -04006259Associates Rect on Canvas with an annotation; a key-value pair, where the key is
Cary Clark8032b982017-07-28 11:04:54 -04006260a null-terminated utf8 string, and optional value is stored as Data.
6261
Herb Derbyefe39bc2018-05-01 17:06:20 -04006262Only some canvas implementations, such as recording to Picture, or drawing to
Cary Clark8032b982017-07-28 11:04:54 -04006263Document_PDF, use annotations.
6264
Cary Clarkbad5ad72017-08-03 17:14:08 -04006265#Param rect Rect extent of canvas to annotate ##
6266#Param key string used for lookup ##
6267#Param value data holding value stored in annotation ##
Cary Clark8032b982017-07-28 11:04:54 -04006268
6269#Example
6270 #Height 1
6271 const char text[] = "Click this link!";
6272 SkRect bounds;
6273 SkPaint paint;
6274 paint.setTextSize(40);
6275 (void)paint.measureText(text, strlen(text), &bounds);
6276 const char url[] = "https://www.google.com/";
6277 sk_sp<SkData> urlData(SkData::MakeWithCString(url));
6278 canvas->drawAnnotation(bounds, "url_key", urlData.get());
6279##
6280
Cary Clark2ade9972017-11-02 17:49:34 -04006281#SeeAlso SkPicture SkDocument
Cary Clark8032b982017-07-28 11:04:54 -04006282
6283##
6284
6285# ------------------------------------------------------------------------------
6286
Herb Derbyefe39bc2018-05-01 17:06:20 -04006287#Method void drawAnnotation(const SkRect& rect, const char key[], const sk_sp<SkData>& value)
Cary Clark8032b982017-07-28 11:04:54 -04006288
Cary Clark80247e52018-07-11 16:18:41 -04006289Associates Rect on Canvas when an annotation; a key-value pair, where the key is
Cary Clark8032b982017-07-28 11:04:54 -04006290a null-terminated utf8 string, and optional value is stored as Data.
6291
Herb Derbyefe39bc2018-05-01 17:06:20 -04006292Only some canvas implementations, such as recording to Picture, or drawing to
Cary Clark8032b982017-07-28 11:04:54 -04006293Document_PDF, use annotations.
6294
Cary Clarkbad5ad72017-08-03 17:14:08 -04006295#Param rect Rect extent of canvas to annotate ##
6296#Param key string used for lookup ##
6297#Param value data holding value stored in annotation ##
Cary Clark8032b982017-07-28 11:04:54 -04006298
6299#Example
6300#Height 1
6301 const char text[] = "Click this link!";
6302 SkRect bounds;
6303 SkPaint paint;
6304 paint.setTextSize(40);
6305 (void)paint.measureText(text, strlen(text), &bounds);
6306 const char url[] = "https://www.google.com/";
6307 sk_sp<SkData> urlData(SkData::MakeWithCString(url));
6308 canvas->drawAnnotation(bounds, "url_key", urlData.get());
6309##
6310
Cary Clark2ade9972017-11-02 17:49:34 -04006311#SeeAlso SkPicture SkDocument
Cary Clark8032b982017-07-28 11:04:54 -04006312
6313##
6314
Cary Clark8032b982017-07-28 11:04:54 -04006315# ------------------------------------------------------------------------------
6316
6317#Method virtual bool isClipEmpty() const
Cary Clark78de7512018-02-07 07:27:09 -05006318#In Property
Cary Clarkab2621d2018-01-30 10:08:57 -05006319#Line # returns if Clip is empty ##
Cary Clark8032b982017-07-28 11:04:54 -04006320Returns true if Clip is empty; that is, nothing will draw.
6321
Cary Clarkbad5ad72017-08-03 17:14:08 -04006322May do work when called; it should not be called
Cary Clark8032b982017-07-28 11:04:54 -04006323more often than needed. However, once called, subsequent calls perform no
6324work until Clip changes.
6325
Cary Clarkbad5ad72017-08-03 17:14:08 -04006326#Return true if Clip is empty ##
Cary Clark8032b982017-07-28 11:04:54 -04006327
6328#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04006329 void draw(SkCanvas* canvas) {
6330 SkDebugf("clip is%s empty\n", canvas->isClipEmpty() ? "" : " not");
6331 SkPath path;
6332 canvas->clipPath(path);
6333 SkDebugf("clip is%s empty\n", canvas->isClipEmpty() ? "" : " not");
Cary Clark8032b982017-07-28 11:04:54 -04006334 }
6335 #StdOut
Cary Clarkbad5ad72017-08-03 17:14:08 -04006336 clip is not empty
Cary Clark8032b982017-07-28 11:04:54 -04006337 clip is empty
6338 ##
6339##
6340
Cary Clark2ade9972017-11-02 17:49:34 -04006341#SeeAlso isClipRect getLocalClipBounds getDeviceClipBounds
Cary Clark8032b982017-07-28 11:04:54 -04006342
6343##
6344
6345# ------------------------------------------------------------------------------
6346
6347#Method virtual bool isClipRect() const
Cary Clark78de7512018-02-07 07:27:09 -05006348#In Property
Cary Clarkab2621d2018-01-30 10:08:57 -05006349#Line # returns if Clip is Rect and not empty ##
Cary Clark8032b982017-07-28 11:04:54 -04006350Returns true if Clip is Rect and not empty.
6351Returns false if the clip is empty, or if it is not Rect.
6352
Cary Clarkbad5ad72017-08-03 17:14:08 -04006353#Return true if Clip is Rect and not empty ##
Cary Clark8032b982017-07-28 11:04:54 -04006354
6355#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04006356 void draw(SkCanvas* canvas) {
6357 SkDebugf("clip is%s rect\n", canvas->isClipRect() ? "" : " not");
6358 canvas->clipRect({0, 0, 0, 0});
6359 SkDebugf("clip is%s rect\n", canvas->isClipRect() ? "" : " not");
Cary Clark8032b982017-07-28 11:04:54 -04006360 }
6361 #StdOut
Cary Clarkbad5ad72017-08-03 17:14:08 -04006362 clip is rect
Cary Clark8032b982017-07-28 11:04:54 -04006363 clip is not rect
6364 ##
6365##
6366
Cary Clark2ade9972017-11-02 17:49:34 -04006367#SeeAlso isClipEmpty getLocalClipBounds getDeviceClipBounds
Cary Clark8032b982017-07-28 11:04:54 -04006368
6369##
6370
6371#Class SkCanvas ##
Cary Clark884dd7d2017-10-11 10:37:52 -04006372
Cary Clark8032b982017-07-28 11:04:54 -04006373#Topic Canvas ##