blob: db14d0190ba8a9cf7ae3c7e6f19c062938b6ca1b [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
1268Canvas savable state consists of Clip, Matrix, and Draw_Filter.
1269Clip describes the area that may be drawn to.
1270Matrix transforms the geometry.
1271Draw_Filter (deprecated on most platforms) modifies the paint before drawing.
1272
1273save(), saveLayer, saveLayerPreserveLCDTextRequests, and saveLayerAlpha
1274save state and return the depth of the stack.
1275
Cary Clarkbad5ad72017-08-03 17:14:08 -04001276restore(), restoreToCount, and ~SkCanvas() revert state to its value when saved.
Cary Clark8032b982017-07-28 11:04:54 -04001277
1278Each state on the stack intersects Clip with the previous Clip,
1279and concatenates Matrix with the previous Matrix.
1280The intersected Clip makes the drawing area the same or smaller;
1281the concatenated Matrix may move the origin and potentially scale or rotate
1282the coordinate space.
1283
1284Canvas does not require balancing the state stack but it is a good idea
1285to do so. Calling save() without restore() will eventually cause Skia to fail;
1286mismatched save() and restore() create hard to find bugs.
1287
1288It is not possible to use state to draw outside of the clip defined by the
1289previous state.
1290
1291#Example
1292#Description
1293Draw to ever smaller clips; then restore drawing to full canvas.
1294Note that the second clipRect is not permitted to enlarge Clip.
1295##
1296#Height 160
Cary Clarkbad5ad72017-08-03 17:14:08 -04001297void draw(SkCanvas* canvas) {
1298 SkPaint paint;
Herb Derbyefe39bc2018-05-01 17:06:20 -04001299 canvas->save(); // records stack depth to restore
Cary Clarkbad5ad72017-08-03 17:14:08 -04001300 canvas->clipRect(SkRect::MakeWH(100, 100)); // constrains drawing to clip
1301 canvas->clear(SK_ColorRED); // draws to limit of clip
Herb Derbyefe39bc2018-05-01 17:06:20 -04001302 canvas->save(); // records stack depth to restore
Cary Clarkbad5ad72017-08-03 17:14:08 -04001303 canvas->clipRect(SkRect::MakeWH(50, 150)); // Rect below 100 is ignored
1304 canvas->clear(SK_ColorBLUE); // draws to smaller clip
1305 canvas->restore(); // enlarges clip
1306 canvas->drawLine(20, 20, 150, 150, paint); // line below 100 is not drawn
1307 canvas->restore(); // enlarges clip
1308 canvas->drawLine(150, 20, 50, 120, paint); // line below 100 is drawn
Cary Clark8032b982017-07-28 11:04:54 -04001309}
Herb Derbyefe39bc2018-05-01 17:06:20 -04001310##
Cary Clark8032b982017-07-28 11:04:54 -04001311
1312Each Clip uses the current Matrix for its coordinates.
1313
1314#Example
1315#Description
1316While clipRect is given the same rectangle twice, Matrix makes the second
1317clipRect draw at half the size of the first.
1318##
1319#Height 128
Cary Clarkbad5ad72017-08-03 17:14:08 -04001320void draw(SkCanvas* canvas) {
1321 canvas->clipRect(SkRect::MakeWH(100, 100));
1322 canvas->clear(SK_ColorRED);
1323 canvas->scale(.5, .5);
1324 canvas->clipRect(SkRect::MakeWH(100, 100));
1325 canvas->clear(SK_ColorBLUE);
Cary Clark8032b982017-07-28 11:04:54 -04001326}
1327##
1328
1329#SeeAlso save() saveLayer saveLayerPreserveLCDTextRequests saveLayerAlpha restore() restoreToCount
1330
1331#Method int save()
1332
Cary Clarkab2621d2018-01-30 10:08:57 -05001333#In State_Stack
1334#Line # saves Clip and Matrix on stack ##
Cary Clark8032b982017-07-28 11:04:54 -04001335Saves Matrix, Clip, and Draw_Filter (Draw_Filter deprecated on most platforms).
1336Calling restore() discards changes to Matrix, Clip, and Draw_Filter,
1337restoring the Matrix, Clip, and Draw_Filter to their state when save() was called.
1338
Cary Clarkbad5ad72017-08-03 17:14:08 -04001339Matrix may be changed by translate(), scale(), rotate(), skew(), concat(), setMatrix,
1340and resetMatrix. Clip may be changed by clipRect, clipRRect, clipPath, clipRegion.
Cary Clark8032b982017-07-28 11:04:54 -04001341
Cary Clarkbad5ad72017-08-03 17:14:08 -04001342Saved Canvas state is put on a stack; multiple calls to save() should be balance
1343by an equal number of calls to restore().
Cary Clark8032b982017-07-28 11:04:54 -04001344
1345Call restoreToCount with result to restore this and subsequent saves.
1346
Cary Clarkbad5ad72017-08-03 17:14:08 -04001347#Return depth of saved stack ##
Cary Clark8032b982017-07-28 11:04:54 -04001348
1349#Example
Herb Derbyefe39bc2018-05-01 17:06:20 -04001350#Description
Cary Clark8032b982017-07-28 11:04:54 -04001351The black square is translated 50 pixels down and to the right.
1352Restoring Canvas state removes translate() from Canvas stack;
1353the red square is not translated, and is drawn at the origin.
1354##
1355#Height 100
1356void draw(SkCanvas* canvas) {
1357 SkPaint paint;
1358 SkRect rect = { 0, 0, 25, 25 };
1359 canvas->drawRect(rect, paint);
1360 canvas->save();
1361 canvas->translate(50, 50);
1362 canvas->drawRect(rect, paint);
1363 canvas->restore();
1364 paint.setColor(SK_ColorRED);
1365 canvas->drawRect(rect, paint);
1366}
1367##
1368
Cary Clark2ade9972017-11-02 17:49:34 -04001369#SeeAlso saveLayer saveLayerPreserveLCDTextRequests saveLayerAlpha restore() restoreToCount
Cary Clark8032b982017-07-28 11:04:54 -04001370
1371##
1372
1373# ------------------------------------------------------------------------------
Cary Clark8032b982017-07-28 11:04:54 -04001374
1375#Method void restore()
1376
Cary Clarkab2621d2018-01-30 10:08:57 -05001377#In State_Stack
1378#Line # restores changes to Clip and Matrix, pops save stack ##
Cary Clark8032b982017-07-28 11:04:54 -04001379Removes changes to Matrix, Clip, and Draw_Filter since Canvas state was
Herb Derbyefe39bc2018-05-01 17:06:20 -04001380last saved. The state is removed from the stack.
Cary Clark8032b982017-07-28 11:04:54 -04001381
Herb Derbyefe39bc2018-05-01 17:06:20 -04001382Does nothing if the stack is empty.
Cary Clark8032b982017-07-28 11:04:54 -04001383
1384#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04001385void draw(SkCanvas* canvas) {
1386 SkCanvas simple;
1387 SkDebugf("depth = %d\n", simple.getSaveCount());
1388 simple.restore();
1389 SkDebugf("depth = %d\n", simple.getSaveCount());
Cary Clark8032b982017-07-28 11:04:54 -04001390}
1391##
1392
Cary Clark2ade9972017-11-02 17:49:34 -04001393#SeeAlso save() saveLayer saveLayerPreserveLCDTextRequests saveLayerAlpha restoreToCount
1394
Cary Clark8032b982017-07-28 11:04:54 -04001395##
1396
1397# ------------------------------------------------------------------------------
1398
1399#Method int getSaveCount() const
1400
Cary Clarkab2621d2018-01-30 10:08:57 -05001401#In State_Stack
1402#Line # returns depth of stack containing Clip and Matrix ##
Cary Clark8032b982017-07-28 11:04:54 -04001403Returns the number of saved states, each containing: Matrix, Clip, and Draw_Filter.
Herb Derbyefe39bc2018-05-01 17:06:20 -04001404Equals the number of save() calls less the number of restore() calls plus one.
Cary Clark8032b982017-07-28 11:04:54 -04001405The save count of a new canvas is one.
1406
Cary Clarkbad5ad72017-08-03 17:14:08 -04001407#Return depth of save state stack ##
Cary Clark8032b982017-07-28 11:04:54 -04001408
1409#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04001410void draw(SkCanvas* canvas) {
1411 SkCanvas simple;
1412 SkDebugf("depth = %d\n", simple.getSaveCount());
1413 simple.save();
1414 SkDebugf("depth = %d\n", simple.getSaveCount());
1415 simple.restore();
1416 SkDebugf("depth = %d\n", simple.getSaveCount());
Cary Clark8032b982017-07-28 11:04:54 -04001417}
1418#StdOut
Cary Clarkbad5ad72017-08-03 17:14:08 -04001419depth = 1
1420depth = 2
Cary Clark8032b982017-07-28 11:04:54 -04001421depth = 1
1422##
1423##
1424
Cary Clark2ade9972017-11-02 17:49:34 -04001425#SeeAlso save() restore() restoreToCount
1426
Cary Clark8032b982017-07-28 11:04:54 -04001427##
1428
1429# ------------------------------------------------------------------------------
1430
1431#Method void restoreToCount(int saveCount)
1432
Cary Clarkab2621d2018-01-30 10:08:57 -05001433#In State_Stack
1434#Line # restores changes to Clip and Matrix to given depth ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04001435Restores state to Matrix, Clip, and Draw_Filter values when save(), saveLayer,
1436saveLayerPreserveLCDTextRequests, or saveLayerAlpha returned saveCount.
Cary Clark8032b982017-07-28 11:04:54 -04001437
Herb Derbyefe39bc2018-05-01 17:06:20 -04001438Does nothing if saveCount is greater than state stack count.
Cary Clark8032b982017-07-28 11:04:54 -04001439Restores state to initial values if saveCount is less than or equal to one.
1440
Cary Clarkbad5ad72017-08-03 17:14:08 -04001441#Param saveCount depth of state stack to restore ##
Cary Clark8032b982017-07-28 11:04:54 -04001442
1443#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04001444void draw(SkCanvas* canvas) {
1445 SkDebugf("depth = %d\n", canvas->getSaveCount());
1446 canvas->save();
1447 canvas->save();
1448 SkDebugf("depth = %d\n", canvas->getSaveCount());
1449 canvas->restoreToCount(0);
1450 SkDebugf("depth = %d\n", canvas->getSaveCount());
Cary Clark8032b982017-07-28 11:04:54 -04001451}
1452#StdOut
Cary Clarkbad5ad72017-08-03 17:14:08 -04001453depth = 1
1454depth = 3
Cary Clark8032b982017-07-28 11:04:54 -04001455depth = 1
1456##
1457##
1458
Herb Derbyefe39bc2018-05-01 17:06:20 -04001459#SeeAlso restore() getSaveCount save()
Cary Clark2ade9972017-11-02 17:49:34 -04001460
Cary Clark8032b982017-07-28 11:04:54 -04001461##
1462
Cary Clark08895c42018-02-01 09:37:32 -05001463#Subtopic State_Stack ##
Cary Clark8032b982017-07-28 11:04:54 -04001464
1465# ------------------------------------------------------------------------------
Cary Clarkce101242017-09-01 15:51:02 -04001466
Cary Clark08895c42018-02-01 09:37:32 -05001467#Subtopic Layer
Cary Clarkd0530ba2017-09-14 11:25:39 -04001468#Substitute layer
Cary Clarkce101242017-09-01 15:51:02 -04001469#Alias Layers
Cary Clark137b8742018-05-30 09:21:49 -04001470#Substitute layers
1471##
Cary Clark08895c42018-02-01 09:37:32 -05001472#Line # temporary Bitmap to draw into ##
Cary Clarkce101242017-09-01 15:51:02 -04001473
1474Layer allocates a temporary Bitmap to draw into. When the drawing is
Herb Derbyefe39bc2018-05-01 17:06:20 -04001475complete, the Bitmap is drawn into the Canvas.
Cary Clarkce101242017-09-01 15:51:02 -04001476
1477Layer is saved in a stack along with other saved state. When state with a Layer
1478is restored, the Bitmap is drawn into the previous Layer.
1479
1480Layer may be initialized with the contents of the previous Layer. When Layer is
1481restored, its Bitmap can be modified by Paint passed to Layer to apply
1482Color_Alpha, Color_Filter, Image_Filter, and Blend_Mode.
1483
1484#Method int saveLayer(const SkRect* bounds, const SkPaint* paint)
1485
Cary Clarkab2621d2018-01-30 10:08:57 -05001486#In Layer
1487#Line # saves Clip and Matrix on stack; creates Layer ##
Cary Clarkce101242017-09-01 15:51:02 -04001488Saves Matrix, Clip, and Draw_Filter (Draw_Filter deprecated on most platforms),
1489and allocates a Bitmap for subsequent drawing.
1490Calling restore() discards changes to Matrix, Clip, and Draw_Filter,
1491and draws the Bitmap.
1492
1493Matrix may be changed by translate(), scale(), rotate(), skew(), concat(),
Herb Derbyefe39bc2018-05-01 17:06:20 -04001494setMatrix, and resetMatrix. Clip may be changed by clipRect, clipRRect,
Cary Clarkce101242017-09-01 15:51:02 -04001495clipPath, clipRegion.
1496
1497Rect bounds suggests but does not define the Bitmap size. To clip drawing to
1498a specific rectangle, use clipRect.
1499
1500Optional Paint paint applies Color_Alpha, Color_Filter, Image_Filter, and
1501Blend_Mode when restore() is called.
1502
1503Call restoreToCount with returned value to restore this and subsequent saves.
1504
1505#Param bounds hint to limit the size of the Layer; may be nullptr ##
1506#Param paint graphics state for Layer; may be nullptr ##
1507
1508#Return depth of saved stack ##
1509
1510#Example
1511#Description
1512Rectangles are blurred by Image_Filter when restore() draws Layer to main
1513Canvas.
1514##
1515#Height 128
Cary Clark81abc432018-06-25 16:30:08 -04001516#Function
1517###$
1518#include "SkBlurImageFilter.h"
1519$$$#
1520##
1521
Cary Clarkce101242017-09-01 15:51:02 -04001522void draw(SkCanvas* canvas) {
1523 SkPaint paint, blur;
Cary Clarka560c472017-11-27 10:44:06 -05001524 blur.setImageFilter(SkBlurImageFilter::Make(3, 3, nullptr));
Cary Clarkce101242017-09-01 15:51:02 -04001525 canvas->saveLayer(nullptr, &blur);
1526 SkRect rect = { 25, 25, 50, 50};
1527 canvas->drawRect(rect, paint);
1528 canvas->translate(50, 50);
1529 paint.setColor(SK_ColorRED);
1530 canvas->drawRect(rect, paint);
1531 canvas->restore();
1532}
1533##
1534
Cary Clark2ade9972017-11-02 17:49:34 -04001535#SeeAlso save() restore() saveLayer saveLayerPreserveLCDTextRequests saveLayerAlpha SaveLayerRec
Cary Clarkce101242017-09-01 15:51:02 -04001536
1537##
1538
Herb Derbyefe39bc2018-05-01 17:06:20 -04001539#Method int saveLayer(const SkRect& bounds, const SkPaint* paint)
Cary Clarkce101242017-09-01 15:51:02 -04001540
Cary Clarkab2621d2018-01-30 10:08:57 -05001541#In Layer
Cary Clarkce101242017-09-01 15:51:02 -04001542Saves Matrix, Clip, and Draw_Filter (Draw_Filter deprecated on most platforms),
1543and allocates a Bitmap for subsequent drawing.
1544Calling restore() discards changes to Matrix, Clip, and Draw_Filter,
1545and draws the Bitmap.
1546
1547Matrix may be changed by translate(), scale(), rotate(), skew(), concat(),
1548setMatrix, and resetMatrix. Clip may be changed by clipRect, clipRRect,
1549clipPath, clipRegion.
1550
1551Rect bounds suggests but does not define the Layer size. To clip drawing to
1552a specific rectangle, use clipRect.
1553
1554Optional Paint paint applies Color_Alpha, Color_Filter, Image_Filter, and
1555Blend_Mode when restore() is called.
1556
1557Call restoreToCount with returned value to restore this and subsequent saves.
1558
1559#Param bounds hint to limit the size of Layer; may be nullptr ##
1560#Param paint graphics state for Layer; may be nullptr ##
1561
1562#Return depth of saved stack ##
1563
1564#Example
1565#Description
1566Rectangles are blurred by Image_Filter when restore() draws Layer to main Canvas.
Herb Derbyefe39bc2018-05-01 17:06:20 -04001567The red rectangle is clipped; it does not fully fit on Layer.
Cary Clarkce101242017-09-01 15:51:02 -04001568Image_Filter blurs past edge of Layer so red rectangle is blurred on all sides.
1569##
1570#Height 128
Cary Clark81abc432018-06-25 16:30:08 -04001571#Function
1572###$
1573#include "SkBlurImageFilter.h"
1574$$$#
1575##
1576
Cary Clarkce101242017-09-01 15:51:02 -04001577void draw(SkCanvas* canvas) {
1578 SkPaint paint, blur;
Cary Clarka560c472017-11-27 10:44:06 -05001579 blur.setImageFilter(SkBlurImageFilter::Make(3, 3, nullptr));
Cary Clarkce101242017-09-01 15:51:02 -04001580 canvas->saveLayer(SkRect::MakeWH(90, 90), &blur);
1581 SkRect rect = { 25, 25, 50, 50};
1582 canvas->drawRect(rect, paint);
1583 canvas->translate(50, 50);
1584 paint.setColor(SK_ColorRED);
1585 canvas->drawRect(rect, paint);
1586 canvas->restore();
1587}
1588##
1589
Cary Clark2ade9972017-11-02 17:49:34 -04001590#SeeAlso save() restore() saveLayerPreserveLCDTextRequests saveLayerAlpha SaveLayerRec
Cary Clarkce101242017-09-01 15:51:02 -04001591
1592##
1593
1594#Method int saveLayerPreserveLCDTextRequests(const SkRect* bounds, const SkPaint* paint)
1595
Cary Clarkab2621d2018-01-30 10:08:57 -05001596#In Layer
1597#Line # saves Clip and Matrix on stack; creates Layer for LCD text ##
Cary Clarkce101242017-09-01 15:51:02 -04001598Saves Matrix, Clip, and Draw_Filter (Draw_Filter deprecated on most platforms),
1599and allocates a Bitmap for subsequent drawing.
1600LCD_Text is preserved when the Layer is drawn to the prior Layer.
1601
1602Calling restore() discards changes to Matrix, Clip, and Draw_Filter,
1603and draws Layer.
1604
1605Matrix may be changed by translate(), scale(), rotate(), skew(), concat(),
1606setMatrix, and resetMatrix. Clip may be changed by clipRect, clipRRect,
1607clipPath, clipRegion.
Herb Derbyefe39bc2018-05-01 17:06:20 -04001608
Cary Clarkce101242017-09-01 15:51:02 -04001609Rect bounds suggests but does not define the Layer size. To clip drawing to
1610a specific rectangle, use clipRect.
1611
1612Optional Paint paint applies Color_Alpha, Color_Filter, Image_Filter, and
1613Blend_Mode when restore() is called.
1614
1615Call restoreToCount with returned value to restore this and subsequent saves.
1616
1617Draw text on an opaque background so that LCD_Text blends correctly with the
1618prior Layer. LCD_Text drawn on a background with transparency may result in
Cary Clark6fc50412017-09-21 12:31:06 -04001619incorrect blending.
Cary Clarkce101242017-09-01 15:51:02 -04001620
1621#Param bounds hint to limit the size of Layer; may be nullptr ##
1622#Param paint graphics state for Layer; may be nullptr ##
1623
1624#Return depth of saved stack ##
1625
1626#Example
1627 SkPaint paint;
1628 paint.setAntiAlias(true);
1629 paint.setLCDRenderText(true);
1630 paint.setTextSize(20);
1631 for (auto preserve : { false, true } ) {
1632 preserve ? canvas->saveLayerPreserveLCDTextRequests(nullptr, nullptr)
1633 : canvas->saveLayer(nullptr, nullptr);
1634 SkPaint p;
1635 p.setColor(SK_ColorWHITE);
1636 // Comment out the next line to draw on a non-opaque background.
1637 canvas->drawRect(SkRect::MakeLTRB(25, 40, 200, 70), p);
1638 canvas->drawString("Hamburgefons", 30, 60, paint);
1639
1640 p.setColor(0xFFCCCCCC);
1641 canvas->drawRect(SkRect::MakeLTRB(25, 70, 200, 100), p);
1642 canvas->drawString("Hamburgefons", 30, 90, paint);
1643
1644 canvas->restore();
1645 canvas->translate(0, 80);
1646 }
1647 ##
1648
Cary Clark2ade9972017-11-02 17:49:34 -04001649#SeeAlso save() restore() saveLayer saveLayerAlpha SaveLayerRec
Cary Clarkce101242017-09-01 15:51:02 -04001650
1651##
1652
1653#Method int saveLayerAlpha(const SkRect* bounds, U8CPU alpha)
1654
Cary Clarkab2621d2018-01-30 10:08:57 -05001655#In Layer
1656#Line # saves Clip and Matrix on stack; creates Layer; sets opacity ##
Cary Clarkce101242017-09-01 15:51:02 -04001657Saves Matrix, Clip, and Draw_Filter (Draw_Filter deprecated on most platforms),
1658and allocates Bitmap for subsequent drawing.
1659
1660Calling restore() discards changes to Matrix, Clip, and Draw_Filter,
1661and blends Layer with alpha opacity onto prior Layer.
1662
1663Matrix may be changed by translate(), scale(), rotate(), skew(), concat(),
1664setMatrix, and resetMatrix. Clip may be changed by clipRect, clipRRect,
1665clipPath, clipRegion.
1666
1667Rect bounds suggests but does not define Layer size. To clip drawing to
1668a specific rectangle, use clipRect.
1669
1670alpha of zero is fully transparent, 255 is fully opaque.
1671
1672Call restoreToCount with returned value to restore this and subsequent saves.
1673
1674#Param bounds hint to limit the size of Layer; may be nullptr ##
1675#Param alpha opacity of Layer ##
1676
1677#Return depth of saved stack ##
1678
1679#Example
1680 SkPaint paint;
1681 paint.setColor(SK_ColorRED);
1682 canvas->drawCircle(50, 50, 50, paint);
1683 canvas->saveLayerAlpha(nullptr, 128);
1684 paint.setColor(SK_ColorBLUE);
1685 canvas->drawCircle(100, 50, 50, paint);
1686 paint.setColor(SK_ColorGREEN);
1687 paint.setAlpha(128);
1688 canvas->drawCircle(75, 90, 50, paint);
1689 canvas->restore();
1690##
1691
Cary Clark2ade9972017-11-02 17:49:34 -04001692#SeeAlso save() restore() saveLayer saveLayerPreserveLCDTextRequests SaveLayerRec
Cary Clarkce101242017-09-01 15:51:02 -04001693
1694##
1695
Cary Clarkd98f78c2018-04-26 08:32:37 -04001696#Enum SaveLayerFlagsSet
Cary Clark08895c42018-02-01 09:37:32 -05001697#Line # sets SaveLayerRec options ##
Cary Clarkce101242017-09-01 15:51:02 -04001698#Code
Cary Clarkd98f78c2018-04-26 08:32:37 -04001699 enum SaveLayerFlagsSet {
Cary Clarkce101242017-09-01 15:51:02 -04001700 kPreserveLCDText_SaveLayerFlag = 1 << 1,
1701 kInitWithPrevious_SaveLayerFlag = 1 << 2,
Mike Reed910ca0f2018-04-25 13:04:05 -04001702 kMaskAgainstCoverage_EXPERIMENTAL_DONT_USE_SaveLayerFlag = 1 << 3,
Cary Clarkce101242017-09-01 15:51:02 -04001703 kDontClipToLayer_Legacy_SaveLayerFlag = kDontClipToLayer_PrivateSaveLayerFlag,
1704 };
Cary Clarkd98f78c2018-04-26 08:32:37 -04001705
1706 typedef uint32_t SaveLayerFlags;
Cary Clarkce101242017-09-01 15:51:02 -04001707##
1708
Cary Clark682c58d2018-05-16 07:07:07 -04001709
1710#Typedef uint32_t SaveLayerFlags
1711#Line # options for SaveLayerRec ##
Cary Clark137b8742018-05-30 09:21:49 -04001712##
Cary Clark682c58d2018-05-16 07:07:07 -04001713
Cary Clarkce101242017-09-01 15:51:02 -04001714SaveLayerFlags provides options that may be used in any combination in SaveLayerRec,
Cary Clark682c58d2018-05-16 07:07:07 -04001715defining how Layer allocated by saveLayer operates. It may be set to zero,
1716kPreserveLCDText_SaveLayerFlag, kInitWithPrevious_SaveLayerFlag, or both flags.
1717
Cary Clarkce101242017-09-01 15:51:02 -04001718#Const kPreserveLCDText_SaveLayerFlag 2
Cary Clark682c58d2018-05-16 07:07:07 -04001719#Line # creates Layer for LCD text ##
Cary Clarkce101242017-09-01 15:51:02 -04001720 Creates Layer for LCD text. Flag is ignored if Layer Paint contains
1721 Image_Filter or Color_Filter.
1722##
1723
1724#Const kInitWithPrevious_SaveLayerFlag 4
Cary Clark682c58d2018-05-16 07:07:07 -04001725#Line # initializes with previous contents ##
Cary Clarkce101242017-09-01 15:51:02 -04001726 Initializes Layer with the contents of the previous Layer.
1727##
1728
Mike Reed910ca0f2018-04-25 13:04:05 -04001729#Const kMaskAgainstCoverage_EXPERIMENTAL_DONT_USE_SaveLayerFlag 8
Cary Clark682c58d2018-05-16 07:07:07 -04001730#Experimental do not use
Mike Reed910ca0f2018-04-25 13:04:05 -04001731##
1732
Cary Clarkce101242017-09-01 15:51:02 -04001733#Const kDontClipToLayer_Legacy_SaveLayerFlag 0x80000000
Cary Clark4855f782018-02-06 09:41:53 -05001734#Deprecated soon
Cary Clarkce101242017-09-01 15:51:02 -04001735##
1736
1737#Example
1738#Height 160
1739#Description
1740Canvas Layer captures red and blue circles scaled up by four.
Herb Derbyefe39bc2018-05-01 17:06:20 -04001741scalePaint blends Layer back with transparency.
Cary Clarkce101242017-09-01 15:51:02 -04001742##
1743void draw(SkCanvas* canvas) {
1744 SkPaint redPaint, bluePaint, scalePaint;
1745 redPaint.setColor(SK_ColorRED);
1746 canvas->drawCircle(21, 21, 8, redPaint);
1747 bluePaint.setColor(SK_ColorBLUE);
1748 canvas->drawCircle(31, 21, 8, bluePaint);
1749 SkMatrix matrix;
1750 matrix.setScale(4, 4);
1751 scalePaint.setAlpha(0x40);
1752 scalePaint.setImageFilter(
1753 SkImageFilter::MakeMatrixFilter(matrix, kNone_SkFilterQuality, nullptr));
1754 SkCanvas::SaveLayerRec saveLayerRec(nullptr, &scalePaint,
Herb Derbyefe39bc2018-05-01 17:06:20 -04001755 SkCanvas::kInitWithPrevious_SaveLayerFlag);
Cary Clarkce101242017-09-01 15:51:02 -04001756 canvas->saveLayer(saveLayerRec);
1757 canvas->restore();
1758}
1759##
1760
Cary Clark2ade9972017-11-02 17:49:34 -04001761#SeeAlso save() restore() saveLayer saveLayerPreserveLCDTextRequests saveLayerAlpha SaveLayerRec
Cary Clarkce101242017-09-01 15:51:02 -04001762
1763#Enum ##
1764
Cary Clark682c58d2018-05-16 07:07:07 -04001765#Subtopic SaveLayerRec
1766#Line # contains the state used to create the Layer ##
Cary Clarka560c472017-11-27 10:44:06 -05001767
Cary Clarkce101242017-09-01 15:51:02 -04001768#Struct SaveLayerRec
Cary Clark08895c42018-02-01 09:37:32 -05001769#Line # contains the state used to create the Layer ##
Cary Clark682c58d2018-05-16 07:07:07 -04001770
Cary Clarkce101242017-09-01 15:51:02 -04001771#Code
1772 struct SaveLayerRec {
1773 SaveLayerRec*(...
1774
1775 const SkRect* fBounds;
1776 const SkPaint* fPaint;
1777 const SkImageFilter* fBackdrop;
1778 SaveLayerFlags fSaveLayerFlags;
1779 };
1780##
1781
Cary Clark137b8742018-05-30 09:21:49 -04001782SaveLayerRec contains the state used to create the Layer.
1783
Cary Clark682c58d2018-05-16 07:07:07 -04001784#Subtopic Overview
1785#Populate
1786##
1787
1788#Subtopic Member
1789#Populate
1790##
Cary Clarkce101242017-09-01 15:51:02 -04001791
1792#Member const SkRect* fBounds
Cary Clark682c58d2018-05-16 07:07:07 -04001793#Line # hints at Layer size limit ##
Cary Clarkce101242017-09-01 15:51:02 -04001794 fBounds is used as a hint to limit the size of Layer; may be nullptr.
1795 fBounds suggests but does not define Layer size. To clip drawing to
1796 a specific rectangle, use clipRect.
1797##
1798
1799#Member const SkPaint* fPaint
Cary Clark682c58d2018-05-16 07:07:07 -04001800#Line # modifies overlay ##
Cary Clarkce101242017-09-01 15:51:02 -04001801 fPaint modifies how Layer overlays the prior Layer; may be nullptr.
1802 Color_Alpha, Blend_Mode, Color_Filter, Draw_Looper, Image_Filter, and
1803 Mask_Filter affect Layer draw.
1804##
1805
1806#Member const SkImageFilter* fBackdrop
Cary Clark682c58d2018-05-16 07:07:07 -04001807#Line # applies Image_Filter to prior Layer ##
Cary Clarkce101242017-09-01 15:51:02 -04001808 fBackdrop applies Image_Filter to the prior Layer when copying to the Layer;
1809 may be nullptr. Use kInitWithPrevious_SaveLayerFlag to copy the
1810 prior Layer without an Image_Filter.
1811##
1812
1813#Member const SkImage* fClipMask
Cary Clark682c58d2018-05-16 07:07:07 -04001814#Line # clips Layer with Mask_Alpha ##
Cary Clarkce101242017-09-01 15:51:02 -04001815 restore() clips Layer by the Color_Alpha channel of fClipMask when
1816 Layer is copied to Device. fClipMask may be nullptr. .
1817##
1818
1819#Member const SkMatrix* fClipMatrix
Cary Clark682c58d2018-05-16 07:07:07 -04001820#Line # transforms Mask_Alpha used to clip ##
Herb Derbyefe39bc2018-05-01 17:06:20 -04001821 fClipMatrix transforms fClipMask before it clips Layer. If
Cary Clarkce101242017-09-01 15:51:02 -04001822 fClipMask describes a translucent gradient, it may be scaled and rotated
1823 without introducing artifacts. fClipMatrix may be nullptr.
1824##
1825
1826#Member SaveLayerFlags fSaveLayerFlags
Cary Clark682c58d2018-05-16 07:07:07 -04001827#Line # preserves LCD Text, creates with prior Layer contents ##
Cary Clarkce101242017-09-01 15:51:02 -04001828 fSaveLayerFlags are used to create Layer without transparency,
1829 create Layer for LCD text, and to create Layer with the
1830 contents of the previous Layer.
1831##
1832
1833#Example
1834#Height 160
1835#Description
Cary Clarkffb3d682018-05-17 12:17:28 -04001836Canvas Layer captures a red Anti_Aliased circle and a blue Aliased circle scaled
Cary Clarkce101242017-09-01 15:51:02 -04001837up by four. After drawing another red circle without scaling on top, the Layer is
Herb Derbyefe39bc2018-05-01 17:06:20 -04001838transferred to the main canvas.
Cary Clarkce101242017-09-01 15:51:02 -04001839##
1840void draw(SkCanvas* canvas) {
1841 SkPaint redPaint, bluePaint;
1842 redPaint.setAntiAlias(true);
1843 redPaint.setColor(SK_ColorRED);
1844 canvas->drawCircle(21, 21, 8, redPaint);
1845 bluePaint.setColor(SK_ColorBLUE);
1846 canvas->drawCircle(31, 21, 8, bluePaint);
1847 SkMatrix matrix;
1848 matrix.setScale(4, 4);
1849 auto scaler = SkImageFilter::MakeMatrixFilter(matrix, kNone_SkFilterQuality, nullptr);
Herb Derbyefe39bc2018-05-01 17:06:20 -04001850 SkCanvas::SaveLayerRec saveLayerRec(nullptr, nullptr, scaler.get(), 0);
Cary Clarkce101242017-09-01 15:51:02 -04001851 canvas->saveLayer(saveLayerRec);
1852 canvas->drawCircle(125, 85, 8, redPaint);
1853 canvas->restore();
1854}
1855##
1856
Cary Clark682c58d2018-05-16 07:07:07 -04001857#Subtopic Constructor
1858#Populate
1859##
Cary Clarkce101242017-09-01 15:51:02 -04001860
Cary Clark682c58d2018-05-16 07:07:07 -04001861#Method SaveLayerRec()
1862#Line # constructs SaveLayerRec ##
Cary Clarkce101242017-09-01 15:51:02 -04001863Sets fBounds, fPaint, and fBackdrop to nullptr. Clears fSaveLayerFlags.
1864
1865#Return empty SaveLayerRec ##
1866
1867#Example
1868 SkCanvas::SaveLayerRec rec1;
Mike Kleine083f7c2018-02-07 12:54:27 -05001869 rec1.fSaveLayerFlags = SkCanvas::kPreserveLCDText_SaveLayerFlag;
1870 SkCanvas::SaveLayerRec rec2(nullptr, nullptr, SkCanvas::kPreserveLCDText_SaveLayerFlag);
Cary Clarkce101242017-09-01 15:51:02 -04001871 SkDebugf("rec1 %c= rec2\n", rec1.fBounds == rec2.fBounds
1872 && rec1.fPaint == rec2.fPaint
1873 && rec1.fBackdrop == rec2.fBackdrop
1874 && rec1.fSaveLayerFlags == rec2.fSaveLayerFlags ? '=' : '!');
1875 #StdOut
1876 rec1 == rec2
1877 ##
1878##
1879
Cary Clark2ade9972017-11-02 17:49:34 -04001880#SeeAlso save() restore() saveLayer saveLayerPreserveLCDTextRequests saveLayerAlpha
1881
Cary Clarkce101242017-09-01 15:51:02 -04001882##
1883
Cary Clark224c7002018-06-27 11:00:21 -04001884#Method SaveLayerRec(const SkRect* bounds, const SkPaint* paint, SaveLayerFlags saveLayerFlags = 0)
Cary Clarkce101242017-09-01 15:51:02 -04001885
1886Sets fBounds, fPaint, and fSaveLayerFlags; sets fBackdrop to nullptr.
1887
1888#Param bounds Layer dimensions; may be nullptr ##
1889#Param paint applied to Layer when overlaying prior Layer; may be nullptr ##
1890#Param saveLayerFlags SaveLayerRec options to modify Layer ##
1891
1892#Return SaveLayerRec with empty backdrop ##
1893
1894#Example
1895 SkCanvas::SaveLayerRec rec1;
1896 SkCanvas::SaveLayerRec rec2(nullptr, nullptr);
1897 SkDebugf("rec1 %c= rec2\n", rec1.fBounds == rec2.fBounds
1898 && rec1.fPaint == rec2.fPaint
1899 && rec1.fBackdrop == rec2.fBackdrop
1900 && rec1.fSaveLayerFlags == rec2.fSaveLayerFlags ? '=' : '!');
1901 #StdOut
1902 rec1 == rec2
1903 ##
1904##
1905
Cary Clark2ade9972017-11-02 17:49:34 -04001906#SeeAlso save() restore() saveLayer saveLayerPreserveLCDTextRequests saveLayerAlpha
1907
Cary Clarkce101242017-09-01 15:51:02 -04001908##
1909
1910#Method SaveLayerRec(const SkRect* bounds, const SkPaint* paint, const SkImageFilter* backdrop,
1911 SaveLayerFlags saveLayerFlags)
1912
1913Sets fBounds, fPaint, fBackdrop, and fSaveLayerFlags.
1914
1915#Param bounds Layer dimensions; may be nullptr ##
1916#Param paint applied to Layer when overlaying prior Layer;
1917 may be nullptr
1918##
1919#Param backdrop prior Layer copied with Image_Filter; may be nullptr
1920##
1921#Param saveLayerFlags SaveLayerRec options to modify Layer ##
1922
1923#Return SaveLayerRec fully specified ##
1924
1925#Example
1926 SkCanvas::SaveLayerRec rec1;
1927 SkCanvas::SaveLayerRec rec2(nullptr, nullptr, nullptr, 0);
1928 SkDebugf("rec1 %c= rec2\n", rec1.fBounds == rec2.fBounds
1929 && rec1.fPaint == rec2.fPaint
1930 && rec1.fBackdrop == rec2.fBackdrop
1931 && rec1.fSaveLayerFlags == rec2.fSaveLayerFlags ? '=' : '!');
1932 #StdOut
1933 rec1 == rec2
1934 ##
1935##
1936
Cary Clark2ade9972017-11-02 17:49:34 -04001937#SeeAlso save() restore() saveLayer saveLayerPreserveLCDTextRequests saveLayerAlpha
1938
Cary Clarkce101242017-09-01 15:51:02 -04001939##
1940
1941#Method SaveLayerRec(const SkRect* bounds, const SkPaint* paint, const SkImageFilter* backdrop,
1942 const SkImage* clipMask, const SkMatrix* clipMatrix,
1943 SaveLayerFlags saveLayerFlags)
1944
Cary Clark682c58d2018-05-16 07:07:07 -04001945#Experimental not ready
Cary Clarkce101242017-09-01 15:51:02 -04001946
1947Sets fBounds, fPaint, fBackdrop, fClipMask, fClipMatrix, and fSaveLayerFlags.
1948clipMatrix uses Color_Alpha channel of image, transformed by clipMatrix, to clip
1949Layer when drawn to Canvas.
1950
Cary Clark2ade9972017-11-02 17:49:34 -04001951Implementation is not complete; has no effect if Device is GPU-backed.
Cary Clarkce101242017-09-01 15:51:02 -04001952
1953#Param bounds Layer dimensions; may be nullptr ##
1954#Param paint graphics state applied to Layer when overlaying prior
1955 Layer; may be nullptr
1956##
1957#Param backdrop prior Layer copied with Image_Filter;
1958 may be nullptr
1959##
1960#Param clipMask clip applied to Layer; may be nullptr ##
1961#Param clipMatrix matrix applied to clipMask; may be nullptr to use
Herb Derbyefe39bc2018-05-01 17:06:20 -04001962 identity matrix
Cary Clarkce101242017-09-01 15:51:02 -04001963##
1964#Param saveLayerFlags SaveLayerRec options to modify Layer ##
1965
1966#Return SaveLayerRec fully specified ##
1967
Cary Clark2ade9972017-11-02 17:49:34 -04001968#SeeAlso save() restore() saveLayer saveLayerPreserveLCDTextRequests saveLayerAlpha
Cary Clarkce101242017-09-01 15:51:02 -04001969
1970##
1971
1972#Struct ##
1973
Cary Clark682c58d2018-05-16 07:07:07 -04001974#Subtopic ##
1975
Cary Clarkce101242017-09-01 15:51:02 -04001976#Method int saveLayer(const SaveLayerRec& layerRec)
1977
Cary Clarkab2621d2018-01-30 10:08:57 -05001978#In Layer
Cary Clarkce101242017-09-01 15:51:02 -04001979Saves Matrix, Clip, and Draw_Filter (Draw_Filter deprecated on most platforms),
1980and allocates Bitmap for subsequent drawing.
1981
1982Calling restore() discards changes to Matrix, Clip, and Draw_Filter,
1983and blends Bitmap with Color_Alpha opacity onto the prior Layer.
1984
1985Matrix may be changed by translate(), scale(), rotate(), skew(), concat(),
1986setMatrix, and resetMatrix. Clip may be changed by clipRect, clipRRect,
1987clipPath, clipRegion.
1988
1989SaveLayerRec contains the state used to create the Layer.
1990
1991Call restoreToCount with returned value to restore this and subsequent saves.
1992
1993#Param layerRec Layer state ##
1994
1995#Return depth of save state stack ##
1996
1997#Example
1998#Description
1999The example draws an image, and saves it into a Layer with kInitWithPrevious_SaveLayerFlag.
2000Next it punches a hole in Layer and restore with SkBlendMode::kPlus.
2001Where Layer was cleared, the original image will draw unchanged.
2002Outside of the circle the mandrill is brightened.
2003##
2004 #Image 3
Hal Canaryc465d132017-12-08 10:21:31 -05002005 // sk_sp<SkImage> image = GetResourceAsImage("images/mandrill_256.png");
Cary Clarkce101242017-09-01 15:51:02 -04002006 canvas->drawImage(image, 0, 0, nullptr);
2007 SkCanvas::SaveLayerRec rec;
2008 SkPaint paint;
2009 paint.setBlendMode(SkBlendMode::kPlus);
2010 rec.fSaveLayerFlags = SkCanvas::kInitWithPrevious_SaveLayerFlag;
2011 rec.fPaint = &paint;
2012 canvas->saveLayer(rec);
2013 paint.setBlendMode(SkBlendMode::kClear);
2014 canvas->drawCircle(128, 128, 96, paint);
2015 canvas->restore();
2016##
2017
2018#ToDo above example needs to replace GetResourceAsImage with way to select image in fiddle ##
2019
Cary Clark2ade9972017-11-02 17:49:34 -04002020#SeeAlso save() restore() saveLayer saveLayerPreserveLCDTextRequests saveLayerAlpha
2021
Cary Clarkce101242017-09-01 15:51:02 -04002022##
2023
Cary Clark08895c42018-02-01 09:37:32 -05002024#Subtopic Layer ##
Cary Clarkce101242017-09-01 15:51:02 -04002025
2026# ------------------------------------------------------------------------------
Cary Clark08895c42018-02-01 09:37:32 -05002027#Subtopic Matrix
2028#Line # coordinate transformation ##
Cary Clark8032b982017-07-28 11:04:54 -04002029
2030#Method void translate(SkScalar dx, SkScalar dy)
2031
Cary Clarkab2621d2018-01-30 10:08:57 -05002032#In Matrix
2033#Line # translates Matrix ##
Cary Clark80247e52018-07-11 16:18:41 -04002034Translates Matrix by dx along the x-axis and dy along the y-axis.
Cary Clark8032b982017-07-28 11:04:54 -04002035
Cary Clark80247e52018-07-11 16:18:41 -04002036Mathematically, replaces Matrix with a translation matrix
Herb Derbyefe39bc2018-05-01 17:06:20 -04002037Premultiplied with Matrix.
Cary Clark8032b982017-07-28 11:04:54 -04002038
2039This has the effect of moving the drawing by (dx, dy) before transforming
2040the result with Matrix.
2041
Cary Clarkbad5ad72017-08-03 17:14:08 -04002042#Param dx distance to translate in x ##
2043#Param dy distance to translate in y ##
Cary Clark8032b982017-07-28 11:04:54 -04002044
2045#Example
2046#Height 128
2047#Description
2048scale() followed by translate() produces different results from translate() followed
Herb Derbyefe39bc2018-05-01 17:06:20 -04002049by scale().
Cary Clark8032b982017-07-28 11:04:54 -04002050
2051The blue stroke follows translate of (50, 50); a black
Herb Derbyefe39bc2018-05-01 17:06:20 -04002052fill follows scale of (2, 1/2.f). After restoring the clip, which resets
Cary Clark8032b982017-07-28 11:04:54 -04002053Matrix, a red frame follows the same scale of (2, 1/2.f); a gray fill
2054follows translate of (50, 50).
2055##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002056void draw(SkCanvas* canvas) {
2057 SkPaint filledPaint;
2058 SkPaint outlinePaint;
2059 outlinePaint.setStyle(SkPaint::kStroke_Style);
2060 outlinePaint.setColor(SK_ColorBLUE);
2061 canvas->save();
2062 canvas->translate(50, 50);
2063 canvas->drawCircle(28, 28, 15, outlinePaint); // blue center: (50+28, 50+28)
2064 canvas->scale(2, 1/2.f);
2065 canvas->drawCircle(28, 28, 15, filledPaint); // black center: (50+(28*2), 50+(28/2))
2066 canvas->restore();
2067 filledPaint.setColor(SK_ColorGRAY);
2068 outlinePaint.setColor(SK_ColorRED);
2069 canvas->scale(2, 1/2.f);
2070 canvas->drawCircle(28, 28, 15, outlinePaint); // red center: (28*2, 28/2)
2071 canvas->translate(50, 50);
2072 canvas->drawCircle(28, 28, 15, filledPaint); // gray center: ((50+28)*2, (50+28)/2)
Cary Clark8032b982017-07-28 11:04:54 -04002073}
2074##
2075
Cary Clark2ade9972017-11-02 17:49:34 -04002076#SeeAlso concat() scale() skew() rotate() setMatrix
Cary Clark8032b982017-07-28 11:04:54 -04002077
2078##
2079
2080# ------------------------------------------------------------------------------
2081
2082#Method void scale(SkScalar sx, SkScalar sy)
2083
Cary Clarkab2621d2018-01-30 10:08:57 -05002084#In Matrix
2085#Line # scales Matrix ##
Cary Clark80247e52018-07-11 16:18:41 -04002086Scales Matrix by sx on the x-axis and sy on the y-axis.
Cary Clark8032b982017-07-28 11:04:54 -04002087
Cary Clark80247e52018-07-11 16:18:41 -04002088Mathematically, replaces Matrix with a scale matrix
Herb Derbyefe39bc2018-05-01 17:06:20 -04002089Premultiplied with Matrix.
Cary Clark8032b982017-07-28 11:04:54 -04002090
2091This has the effect of scaling the drawing by (sx, sy) before transforming
2092the result with Matrix.
2093
Cary Clarkbad5ad72017-08-03 17:14:08 -04002094#Param sx amount to scale in x ##
2095#Param sy amount to scale in y ##
Cary Clark8032b982017-07-28 11:04:54 -04002096
2097#Example
2098#Height 160
Cary Clarkbad5ad72017-08-03 17:14:08 -04002099void draw(SkCanvas* canvas) {
2100 SkPaint paint;
2101 SkRect rect = { 10, 20, 60, 120 };
2102 canvas->translate(20, 20);
2103 canvas->drawRect(rect, paint);
2104 canvas->scale(2, .5f);
2105 paint.setColor(SK_ColorGRAY);
2106 canvas->drawRect(rect, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002107}
2108##
2109
Cary Clark2ade9972017-11-02 17:49:34 -04002110#SeeAlso concat() translate() skew() rotate() setMatrix
Cary Clark8032b982017-07-28 11:04:54 -04002111
2112##
2113
2114# ------------------------------------------------------------------------------
2115
2116#Method void rotate(SkScalar degrees)
2117
Cary Clarkab2621d2018-01-30 10:08:57 -05002118#In Matrix
2119#Line # rotates Matrix ##
Cary Clark80247e52018-07-11 16:18:41 -04002120Rotates Matrix by degrees. Positive degrees rotates clockwise.
Cary Clark8032b982017-07-28 11:04:54 -04002121
Cary Clark80247e52018-07-11 16:18:41 -04002122Mathematically, replaces Matrix with a rotation matrix
Herb Derbyefe39bc2018-05-01 17:06:20 -04002123Premultiplied with Matrix.
Cary Clark8032b982017-07-28 11:04:54 -04002124
2125This has the effect of rotating the drawing by degrees before transforming
2126the result with Matrix.
2127
Cary Clarkbad5ad72017-08-03 17:14:08 -04002128#Param degrees amount to rotate, in degrees ##
Cary Clark8032b982017-07-28 11:04:54 -04002129
2130#Example
2131#Description
2132Draw clock hands at time 5:10. The hour hand and minute hand point up and
2133are rotated clockwise.
2134##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002135void draw(SkCanvas* canvas) {
2136 SkPaint paint;
2137 paint.setStyle(SkPaint::kStroke_Style);
2138 canvas->translate(128, 128);
2139 canvas->drawCircle(0, 0, 60, paint);
2140 canvas->save();
2141 canvas->rotate(10 * 360 / 60); // 10 minutes of 60 scaled to 360 degrees
Herb Derbyefe39bc2018-05-01 17:06:20 -04002142 canvas->drawLine(0, 0, 0, -50, paint);
Cary Clarkbad5ad72017-08-03 17:14:08 -04002143 canvas->restore();
2144 canvas->rotate((5 + 10.f/60) * 360 / 12); // 5 and 10/60 hours of 12 scaled to 360 degrees
2145 canvas->drawLine(0, 0, 0, -30, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002146}
2147##
2148
Cary Clark2ade9972017-11-02 17:49:34 -04002149#SeeAlso concat() translate() skew() scale() setMatrix
Cary Clark8032b982017-07-28 11:04:54 -04002150
2151##
2152
2153# ------------------------------------------------------------------------------
2154
2155#Method void rotate(SkScalar degrees, SkScalar px, SkScalar py)
2156
Cary Clarkab2621d2018-01-30 10:08:57 -05002157#In Matrix
Cary Clark80247e52018-07-11 16:18:41 -04002158Rotates Matrix by degrees about a point at (px, py). Positive degrees rotates
Cary Clarkbad5ad72017-08-03 17:14:08 -04002159clockwise.
Cary Clark8032b982017-07-28 11:04:54 -04002160
Cary Clark80247e52018-07-11 16:18:41 -04002161Mathematically, constructs a rotation matrix; Premultiplies the rotation matrix by
2162a translation matrix; then replaces Matrix with the resulting matrix
Herb Derbyefe39bc2018-05-01 17:06:20 -04002163Premultiplied with Matrix.
Cary Clark8032b982017-07-28 11:04:54 -04002164
Cary Clarkbad5ad72017-08-03 17:14:08 -04002165This has the effect of rotating the drawing about a given point before
2166transforming the result with Matrix.
Cary Clark8032b982017-07-28 11:04:54 -04002167
Cary Clarkbad5ad72017-08-03 17:14:08 -04002168#Param degrees amount to rotate, in degrees ##
Cary Clark5538c132018-06-14 12:28:14 -04002169#Param px x-axis value of the point to rotate about ##
2170#Param py y-axis value of the point to rotate about ##
Cary Clark8032b982017-07-28 11:04:54 -04002171
2172#Example
2173#Height 192
Cary Clarkbad5ad72017-08-03 17:14:08 -04002174void draw(SkCanvas* canvas) {
2175 SkPaint paint;
2176 paint.setTextSize(96);
2177 canvas->drawString("A1", 130, 100, paint);
2178 canvas->rotate(180, 130, 100);
2179 canvas->drawString("A1", 130, 100, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002180}
2181##
2182
Cary Clark2ade9972017-11-02 17:49:34 -04002183#SeeAlso concat() translate() skew() scale() setMatrix
Cary Clark8032b982017-07-28 11:04:54 -04002184
2185##
2186
2187# ------------------------------------------------------------------------------
2188
2189#Method void skew(SkScalar sx, SkScalar sy)
2190
Cary Clarkab2621d2018-01-30 10:08:57 -05002191#In Matrix
2192#Line # skews Matrix ##
Cary Clark80247e52018-07-11 16:18:41 -04002193Skews 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 -04002194skews the drawing right as y-axis values increase; a positive value of sy skews
2195the drawing down as x-axis values increase.
Cary Clark8032b982017-07-28 11:04:54 -04002196
Cary Clark80247e52018-07-11 16:18:41 -04002197Mathematically, replaces Matrix with a skew matrix Premultiplied with Matrix.
Cary Clark8032b982017-07-28 11:04:54 -04002198
Cary Clarkbad5ad72017-08-03 17:14:08 -04002199This has the effect of skewing the drawing by (sx, sy) before transforming
Cary Clark8032b982017-07-28 11:04:54 -04002200the result with Matrix.
2201
Cary Clark5538c132018-06-14 12:28:14 -04002202#Param sx amount to skew on x-axis ##
2203#Param sy amount to skew on y-axis ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002204
Cary Clark8032b982017-07-28 11:04:54 -04002205#Example
Herb Derbyefe39bc2018-05-01 17:06:20 -04002206 #Description
Cary Clark5538c132018-06-14 12:28:14 -04002207 Black text mimics an oblique text style by using a negative skew on x-axis
2208 that shifts the geometry to the right as the y-axis values decrease.
2209 Red text uses a positive skew on y-axis to shift the geometry down
2210 as the x-axis values increase.
2211 Blue text combines sx and sy skew to rotate and scale.
Cary Clark8032b982017-07-28 11:04:54 -04002212 ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002213 SkPaint paint;
2214 paint.setTextSize(128);
2215 canvas->translate(30, 130);
2216 canvas->save();
2217 canvas->skew(-.5, 0);
2218 canvas->drawString("A1", 0, 0, paint);
2219 canvas->restore();
2220 canvas->save();
2221 canvas->skew(0, .5);
2222 paint.setColor(SK_ColorRED);
2223 canvas->drawString("A1", 0, 0, paint);
2224 canvas->restore();
2225 canvas->skew(-.5, .5);
2226 paint.setColor(SK_ColorBLUE);
Cary Clark8032b982017-07-28 11:04:54 -04002227 canvas->drawString("A1", 0, 0, paint);
2228##
2229
Cary Clark2ade9972017-11-02 17:49:34 -04002230#SeeAlso concat() translate() rotate() scale() setMatrix
Cary Clark8032b982017-07-28 11:04:54 -04002231
2232##
2233
2234# ------------------------------------------------------------------------------
2235
2236#Method void concat(const SkMatrix& matrix)
2237
Cary Clarkab2621d2018-01-30 10:08:57 -05002238#In Matrix
2239#Line # multiplies Matrix by Matrix ##
Cary Clark80247e52018-07-11 16:18:41 -04002240Replaces Matrix with matrix Premultiplied with existing Matrix.
Cary Clark8032b982017-07-28 11:04:54 -04002241
Cary Clarkbad5ad72017-08-03 17:14:08 -04002242This has the effect of transforming the drawn geometry by matrix, before
2243transforming the result with existing Matrix.
Cary Clark8032b982017-07-28 11:04:54 -04002244
Cary Clarkce101242017-09-01 15:51:02 -04002245#Param matrix matrix to Premultiply with existing Matrix ##
Cary Clark8032b982017-07-28 11:04:54 -04002246
2247#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04002248void draw(SkCanvas* canvas) {
2249 SkPaint paint;
2250 paint.setTextSize(80);
2251 paint.setTextScaleX(.3);
2252 SkMatrix matrix;
2253 SkRect rect[2] = {{ 10, 20, 90, 110 }, { 40, 130, 140, 180 }};
2254 matrix.setRectToRect(rect[0], rect[1], SkMatrix::kFill_ScaleToFit);
2255 canvas->drawRect(rect[0], paint);
2256 canvas->drawRect(rect[1], paint);
2257 paint.setColor(SK_ColorWHITE);
2258 canvas->drawString("Here", rect[0].fLeft + 10, rect[0].fBottom - 10, paint);
2259 canvas->concat(matrix);
2260 canvas->drawString("There", rect[0].fLeft + 10, rect[0].fBottom - 10, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002261}
2262##
2263
Cary Clark2ade9972017-11-02 17:49:34 -04002264#SeeAlso translate() rotate() scale() skew() setMatrix
Cary Clark8032b982017-07-28 11:04:54 -04002265
2266##
2267
2268# ------------------------------------------------------------------------------
2269
2270#Method void setMatrix(const SkMatrix& matrix)
2271
Cary Clarkab2621d2018-01-30 10:08:57 -05002272#In Matrix
2273#Line # sets Matrix ##
Cary Clark80247e52018-07-11 16:18:41 -04002274Replaces Matrix with matrix.
Cary Clark8032b982017-07-28 11:04:54 -04002275Unlike concat(), any prior matrix state is overwritten.
2276
Cary Clarkbad5ad72017-08-03 17:14:08 -04002277#Param matrix matrix to copy, replacing existing Matrix ##
Cary Clark8032b982017-07-28 11:04:54 -04002278
2279#Example
2280#Height 128
Cary Clarkbad5ad72017-08-03 17:14:08 -04002281void draw(SkCanvas* canvas) {
2282 SkPaint paint;
2283 canvas->scale(4, 6);
2284 canvas->drawString("truth", 2, 10, paint);
2285 SkMatrix matrix;
2286 matrix.setScale(2.8f, 6);
2287 canvas->setMatrix(matrix);
2288 canvas->drawString("consequences", 2, 20, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002289}
2290##
2291
Cary Clark2ade9972017-11-02 17:49:34 -04002292#SeeAlso resetMatrix concat() translate() rotate() scale() skew()
Cary Clark8032b982017-07-28 11:04:54 -04002293
2294##
2295
2296# ------------------------------------------------------------------------------
2297
2298#Method void resetMatrix()
2299
Cary Clarkab2621d2018-01-30 10:08:57 -05002300#In Matrix
2301#Line # resets Matrix to identity ##
Cary Clark8032b982017-07-28 11:04:54 -04002302Sets Matrix to the identity matrix.
2303Any prior matrix state is overwritten.
2304
2305#Example
2306#Height 128
Cary Clarkbad5ad72017-08-03 17:14:08 -04002307void draw(SkCanvas* canvas) {
2308 SkPaint paint;
2309 canvas->scale(4, 6);
2310 canvas->drawString("truth", 2, 10, paint);
2311 canvas->resetMatrix();
2312 canvas->scale(2.8f, 6);
2313 canvas->drawString("consequences", 2, 20, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002314}
2315##
2316
Cary Clark2ade9972017-11-02 17:49:34 -04002317#SeeAlso setMatrix concat() translate() rotate() scale() skew()
Cary Clark8032b982017-07-28 11:04:54 -04002318
2319##
2320
2321# ------------------------------------------------------------------------------
2322
2323#Method const SkMatrix& getTotalMatrix() const
2324
Cary Clarkab2621d2018-01-30 10:08:57 -05002325#In Matrix
2326#Line # returns Matrix ##
Cary Clark8032b982017-07-28 11:04:54 -04002327Returns Matrix.
2328This does not account for translation by Device or Surface.
2329
Cary Clarkbad5ad72017-08-03 17:14:08 -04002330#Return Matrix in Canvas ##
Cary Clark8032b982017-07-28 11:04:54 -04002331
2332#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04002333 SkDebugf("isIdentity %s\n", canvas->getTotalMatrix().isIdentity() ? "true" : "false");
2334 #StdOut
2335 isIdentity true
2336 ##
Cary Clark8032b982017-07-28 11:04:54 -04002337##
2338
Cary Clark2ade9972017-11-02 17:49:34 -04002339#SeeAlso setMatrix resetMatrix concat()
Cary Clark8032b982017-07-28 11:04:54 -04002340
2341##
2342
Cary Clark08895c42018-02-01 09:37:32 -05002343#Subtopic Matrix ##
Cary Clark8032b982017-07-28 11:04:54 -04002344
2345# ------------------------------------------------------------------------------
Cary Clark08895c42018-02-01 09:37:32 -05002346#Subtopic Clip
2347#Line # stack of clipping Paths ##
Cary Clark8032b982017-07-28 11:04:54 -04002348
2349Clip is built from a stack of clipping paths. Each Path in the
Herb Derbyefe39bc2018-05-01 17:06:20 -04002350stack can be constructed from one or more Path_Contour elements. The
Cary Clark8032b982017-07-28 11:04:54 -04002351Path_Contour may be composed of any number of Path_Verb segments. Each
2352Path_Contour forms a closed area; Path_Fill_Type defines the area enclosed
2353by Path_Contour.
2354
2355Clip stack of Path elements successfully restrict the Path area. Each
Herb Derbyefe39bc2018-05-01 17:06:20 -04002356Path is transformed by Matrix, then intersected with or subtracted from the
Cary Clark8032b982017-07-28 11:04:54 -04002357prior Clip to form the replacement Clip. Use SkClipOp::kDifference
2358to subtract Path from Clip; use SkClipOp::kIntersect to intersect Path
2359with Clip.
2360
Cary Clarkffb3d682018-05-17 12:17:28 -04002361A clipping Path may be Anti_Aliased; if Path, after transformation, is
2362composed of horizontal and vertical lines, clearing Anti_Alias allows whole pixels
Cary Clarkce101242017-09-01 15:51:02 -04002363to either be inside or outside the clip. The fastest drawing has a Aliased,
2364rectangular clip.
Cary Clark8032b982017-07-28 11:04:54 -04002365
Cary Clarkffb3d682018-05-17 12:17:28 -04002366If clipping Path has Anti_Alias set, clip may partially clip a pixel, requiring
Herb Derbyefe39bc2018-05-01 17:06:20 -04002367that drawing blend partially with the destination along the edge. A rotated
Cary Clarkffb3d682018-05-17 12:17:28 -04002368rectangular Anti_Aliased clip looks smoother but draws slower.
Cary Clark8032b982017-07-28 11:04:54 -04002369
2370Clip can combine with Rect and Round_Rect primitives; like
2371Path, these are transformed by Matrix before they are combined with Clip.
2372
2373Clip can combine with Region. Region is assumed to be in Device coordinates
2374and is unaffected by Matrix.
2375
2376#Example
2377#Height 90
2378 #Description
Cary Clarkffb3d682018-05-17 12:17:28 -04002379 Draw a red circle with an Aliased clip and an Anti_Aliased clip.
Cary Clark8032b982017-07-28 11:04:54 -04002380 Use an image filter to zoom into the pixels drawn.
Cary Clarkce101242017-09-01 15:51:02 -04002381 The edge of the Aliased clip fully draws pixels in the red circle.
Cary Clarkffb3d682018-05-17 12:17:28 -04002382 The edge of the Anti_Aliased clip partially draws pixels in the red circle.
Cary Clark8032b982017-07-28 11:04:54 -04002383 ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002384 SkPaint redPaint, scalePaint;
2385 redPaint.setAntiAlias(true);
2386 redPaint.setColor(SK_ColorRED);
2387 canvas->save();
2388 for (bool antialias : { false, true } ) {
2389 canvas->save();
2390 canvas->clipRect(SkRect::MakeWH(19.5f, 11.5f), antialias);
2391 canvas->drawCircle(17, 11, 8, redPaint);
2392 canvas->restore();
2393 canvas->translate(16, 0);
2394 }
2395 canvas->restore();
2396 SkMatrix matrix;
2397 matrix.setScale(6, 6);
2398 scalePaint.setImageFilter(
2399 SkImageFilter::MakeMatrixFilter(matrix, kNone_SkFilterQuality, nullptr));
2400 SkCanvas::SaveLayerRec saveLayerRec(
Herb Derbyefe39bc2018-05-01 17:06:20 -04002401 nullptr, &scalePaint, SkCanvas::kInitWithPrevious_SaveLayerFlag);
Cary Clarkbad5ad72017-08-03 17:14:08 -04002402 canvas->saveLayer(saveLayerRec);
Cary Clark8032b982017-07-28 11:04:54 -04002403 canvas->restore();
2404##
2405
2406#Method void clipRect(const SkRect& rect, SkClipOp op, bool doAntiAlias)
2407
Cary Clarkab2621d2018-01-30 10:08:57 -05002408#In Clip
2409#Line # combines Clip with Rect ##
Cary Clark80247e52018-07-11 16:18:41 -04002410Replaces Clip with the intersection or difference of Clip and rect,
Cary Clarkffb3d682018-05-17 12:17:28 -04002411with an Aliased or Anti_Aliased clip edge. rect is transformed by Matrix
Cary Clark8032b982017-07-28 11:04:54 -04002412before it is combined with Clip.
2413
Cary Clarka523d2d2017-08-30 08:58:10 -04002414#Param rect Rect to combine with Clip ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002415#Param op Clip_Op to apply to Clip ##
Cary Clarkffb3d682018-05-17 12:17:28 -04002416#Param doAntiAlias true if Clip is to be Anti_Aliased ##
Cary Clark8032b982017-07-28 11:04:54 -04002417
2418#Example
2419#Height 128
Cary Clarkbad5ad72017-08-03 17:14:08 -04002420void draw(SkCanvas* canvas) {
2421 canvas->rotate(10);
2422 SkPaint paint;
2423 paint.setAntiAlias(true);
2424 for (auto alias: { false, true } ) {
2425 canvas->save();
2426 canvas->clipRect(SkRect::MakeWH(90, 80), SkClipOp::kIntersect, alias);
2427 canvas->drawCircle(100, 60, 60, paint);
2428 canvas->restore();
2429 canvas->translate(80, 0);
2430 }
Cary Clark8032b982017-07-28 11:04:54 -04002431}
2432##
2433
Cary Clark2ade9972017-11-02 17:49:34 -04002434#SeeAlso clipRRect clipPath clipRegion
Cary Clark8032b982017-07-28 11:04:54 -04002435
2436##
2437
Herb Derbyefe39bc2018-05-01 17:06:20 -04002438#Method void clipRect(const SkRect& rect, SkClipOp op)
Cary Clark8032b982017-07-28 11:04:54 -04002439
Cary Clarkab2621d2018-01-30 10:08:57 -05002440#In Clip
Cary Clark80247e52018-07-11 16:18:41 -04002441Replaces Clip with the intersection or difference of Clip and rect.
Cary Clarkce101242017-09-01 15:51:02 -04002442Resulting Clip is Aliased; pixels are fully contained by the clip.
Cary Clarkbad5ad72017-08-03 17:14:08 -04002443rect is transformed by Matrix before it is combined with Clip.
Cary Clark8032b982017-07-28 11:04:54 -04002444
Cary Clarka523d2d2017-08-30 08:58:10 -04002445#Param rect Rect to combine with Clip ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002446#Param op Clip_Op to apply to Clip ##
Cary Clark8032b982017-07-28 11:04:54 -04002447
2448#Example
2449#Height 192
2450#Width 280
Cary Clarkbad5ad72017-08-03 17:14:08 -04002451void draw(SkCanvas* canvas) {
2452 SkPaint paint;
2453 for (SkClipOp op: { SkClipOp::kIntersect, SkClipOp::kDifference } ) {
2454 canvas->save();
2455 canvas->clipRect(SkRect::MakeWH(90, 120), op, false);
2456 canvas->drawCircle(100, 100, 60, paint);
2457 canvas->restore();
2458 canvas->translate(80, 0);
2459 }
Cary Clark8032b982017-07-28 11:04:54 -04002460}
2461##
2462
Cary Clark2ade9972017-11-02 17:49:34 -04002463#SeeAlso clipRRect clipPath clipRegion
Cary Clark8032b982017-07-28 11:04:54 -04002464
2465##
2466
Herb Derbyefe39bc2018-05-01 17:06:20 -04002467#Method void clipRect(const SkRect& rect, bool doAntiAlias = false)
Cary Clark8032b982017-07-28 11:04:54 -04002468
Cary Clarkab2621d2018-01-30 10:08:57 -05002469#In Clip
Cary Clark80247e52018-07-11 16:18:41 -04002470Replaces Clip with the intersection of Clip and rect.
Cary Clarkce101242017-09-01 15:51:02 -04002471Resulting Clip is Aliased; pixels are fully contained by the clip.
Cary Clark8032b982017-07-28 11:04:54 -04002472rect is transformed by Matrix
2473before it is combined with Clip.
2474
Cary Clarka523d2d2017-08-30 08:58:10 -04002475#Param rect Rect to combine with Clip ##
Cary Clarkffb3d682018-05-17 12:17:28 -04002476#Param doAntiAlias true if Clip is to be Anti_Aliased ##
Cary Clark8032b982017-07-28 11:04:54 -04002477
2478#Example
2479#Height 133
2480 #Description
Cary Clarkce101242017-09-01 15:51:02 -04002481 A circle drawn in pieces looks uniform when drawn Aliased.
Cary Clarkffb3d682018-05-17 12:17:28 -04002482 The same circle pieces blend with pixels more than once when Anti_Aliased,
Cary Clark8032b982017-07-28 11:04:54 -04002483 visible as a thin pair of lines through the right circle.
2484 ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002485void draw(SkCanvas* canvas) {
2486 canvas->clear(SK_ColorWHITE);
2487 SkPaint paint;
2488 paint.setAntiAlias(true);
2489 paint.setColor(0x8055aaff);
2490 SkRect clipRect = { 0, 0, 87.4f, 87.4f };
2491 for (auto alias: { false, true } ) {
2492 canvas->save();
2493 canvas->clipRect(clipRect, SkClipOp::kIntersect, alias);
2494 canvas->drawCircle(67, 67, 60, paint);
2495 canvas->restore();
2496 canvas->save();
2497 canvas->clipRect(clipRect, SkClipOp::kDifference, alias);
2498 canvas->drawCircle(67, 67, 60, paint);
2499 canvas->restore();
2500 canvas->translate(120, 0);
2501 }
Cary Clark8032b982017-07-28 11:04:54 -04002502}
2503##
2504
Cary Clark2ade9972017-11-02 17:49:34 -04002505#SeeAlso clipRRect clipPath clipRegion
Cary Clark8032b982017-07-28 11:04:54 -04002506
2507##
2508
2509#Method void androidFramework_setDeviceClipRestriction(const SkIRect& rect)
2510
Cary Clarkab2621d2018-01-30 10:08:57 -05002511#In Clip
Cary Clark682c58d2018-05-16 07:07:07 -04002512#Line # exists for use by Android framework ##
Cary Clarkce101242017-09-01 15:51:02 -04002513Sets the maximum clip rectangle, which can be set by clipRect, clipRRect and
Cary Clark8032b982017-07-28 11:04:54 -04002514clipPath and intersect the current clip with the specified rect.
Cary Clarkce101242017-09-01 15:51:02 -04002515The maximum clip affects only future clipping operations; it is not retroactive.
Cary Clark8032b982017-07-28 11:04:54 -04002516The clip restriction is not recorded in pictures.
2517
Herb Derbyefe39bc2018-05-01 17:06:20 -04002518Pass an empty rect to disable maximum clip.
Cary Clarkbad5ad72017-08-03 17:14:08 -04002519
Cary Clark8032b982017-07-28 11:04:54 -04002520#Private
Cary Clark137b8742018-05-30 09:21:49 -04002521This private API is for use by Android framework only.
Cary Clark8032b982017-07-28 11:04:54 -04002522##
2523
Cary Clarkbad5ad72017-08-03 17:14:08 -04002524#Param rect maximum allowed clip in device coordinates
Cary Clark579985c2017-07-31 11:48:27 -04002525#Param ##
Cary Clark8032b982017-07-28 11:04:54 -04002526
2527##
2528
2529#Method void clipRRect(const SkRRect& rrect, SkClipOp op, bool doAntiAlias)
2530
Cary Clarkab2621d2018-01-30 10:08:57 -05002531#In Clip
2532#Line # combines Clip with Round_Rect ##
Cary Clark80247e52018-07-11 16:18:41 -04002533Replaces Clip with the intersection or difference of Clip and rrect,
Cary Clarkffb3d682018-05-17 12:17:28 -04002534with an Aliased or Anti_Aliased clip edge.
Cary Clark8032b982017-07-28 11:04:54 -04002535rrect is transformed by Matrix
2536before it is combined with Clip.
2537
Cary Clarkbad5ad72017-08-03 17:14:08 -04002538#Param rrect Round_Rect to combine with Clip ##
2539#Param op Clip_Op to apply to Clip ##
Cary Clarkffb3d682018-05-17 12:17:28 -04002540#Param doAntiAlias true if Clip is to be Anti_Aliased ##
Cary Clark8032b982017-07-28 11:04:54 -04002541
2542#Example
2543#Height 128
Cary Clarkbad5ad72017-08-03 17:14:08 -04002544void draw(SkCanvas* canvas) {
2545 canvas->clear(SK_ColorWHITE);
2546 SkPaint paint;
2547 paint.setAntiAlias(true);
2548 paint.setColor(0x8055aaff);
2549 SkRRect oval;
2550 oval.setOval({10, 20, 90, 100});
2551 canvas->clipRRect(oval, SkClipOp::kIntersect, true);
2552 canvas->drawCircle(70, 100, 60, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002553}
2554##
2555
Cary Clark2ade9972017-11-02 17:49:34 -04002556#SeeAlso clipRect clipPath clipRegion
Cary Clark8032b982017-07-28 11:04:54 -04002557
2558##
2559
Herb Derbyefe39bc2018-05-01 17:06:20 -04002560#Method void clipRRect(const SkRRect& rrect, SkClipOp op)
Cary Clark8032b982017-07-28 11:04:54 -04002561
Cary Clarkab2621d2018-01-30 10:08:57 -05002562#In Clip
Cary Clark80247e52018-07-11 16:18:41 -04002563Replaces Clip with the intersection or difference of Clip and rrect.
Cary Clarkce101242017-09-01 15:51:02 -04002564Resulting Clip is Aliased; pixels are fully contained by the clip.
Cary Clarkbad5ad72017-08-03 17:14:08 -04002565rrect is transformed by Matrix before it is combined with Clip.
Cary Clark8032b982017-07-28 11:04:54 -04002566
Cary Clarkbad5ad72017-08-03 17:14:08 -04002567#Param rrect Round_Rect to combine with Clip ##
2568#Param op Clip_Op to apply to Clip ##
Cary Clark8032b982017-07-28 11:04:54 -04002569
2570#Example
2571#Height 128
Cary Clarkbad5ad72017-08-03 17:14:08 -04002572void draw(SkCanvas* canvas) {
2573 SkPaint paint;
2574 paint.setColor(0x8055aaff);
2575 auto oval = SkRRect::MakeOval({10, 20, 90, 100});
2576 canvas->clipRRect(oval, SkClipOp::kIntersect);
2577 canvas->drawCircle(70, 100, 60, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002578}
2579##
2580
Cary Clark2ade9972017-11-02 17:49:34 -04002581#SeeAlso clipRect clipPath clipRegion
Cary Clark8032b982017-07-28 11:04:54 -04002582
2583##
2584
Herb Derbyefe39bc2018-05-01 17:06:20 -04002585#Method void clipRRect(const SkRRect& rrect, bool doAntiAlias = false)
Cary Clark8032b982017-07-28 11:04:54 -04002586
Cary Clarkab2621d2018-01-30 10:08:57 -05002587#In Clip
Cary Clark80247e52018-07-11 16:18:41 -04002588Replaces Clip with the intersection of Clip and rrect,
Cary Clarkffb3d682018-05-17 12:17:28 -04002589with an Aliased or Anti_Aliased clip edge.
Cary Clarkbad5ad72017-08-03 17:14:08 -04002590rrect is transformed by Matrix before it is combined with Clip.
Cary Clark8032b982017-07-28 11:04:54 -04002591
Cary Clarkbad5ad72017-08-03 17:14:08 -04002592#Param rrect Round_Rect to combine with Clip ##
Cary Clarkffb3d682018-05-17 12:17:28 -04002593#Param doAntiAlias true if Clip is to be Anti_Aliased ##
Cary Clark8032b982017-07-28 11:04:54 -04002594
2595#Example
2596#Height 128
Cary Clarkbad5ad72017-08-03 17:14:08 -04002597void draw(SkCanvas* canvas) {
2598 SkPaint paint;
2599 paint.setAntiAlias(true);
2600 auto oval = SkRRect::MakeRectXY({10, 20, 90, 100}, 9, 13);
2601 canvas->clipRRect(oval, true);
2602 canvas->drawCircle(70, 100, 60, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002603}
2604##
2605
Cary Clark2ade9972017-11-02 17:49:34 -04002606#SeeAlso clipRect clipPath clipRegion
Cary Clark8032b982017-07-28 11:04:54 -04002607
2608##
2609
2610#Method void clipPath(const SkPath& path, SkClipOp op, bool doAntiAlias)
2611
Cary Clarkab2621d2018-01-30 10:08:57 -05002612#In Clip
2613#Line # combines Clip with Path ##
Cary Clark80247e52018-07-11 16:18:41 -04002614Replaces Clip with the intersection or difference of Clip and path,
Cary Clarkffb3d682018-05-17 12:17:28 -04002615with an Aliased or Anti_Aliased clip edge. Path_Fill_Type determines if path
Cary Clark8032b982017-07-28 11:04:54 -04002616describes the area inside or outside its contours; and if Path_Contour overlaps
2617itself or another Path_Contour, whether the overlaps form part of the area.
Cary Clarkbad5ad72017-08-03 17:14:08 -04002618path is transformed by Matrix before it is combined with Clip.
Cary Clark8032b982017-07-28 11:04:54 -04002619
Cary Clarkbad5ad72017-08-03 17:14:08 -04002620#Param path Path to combine with Clip ##
2621#Param op Clip_Op to apply to Clip ##
Cary Clarkffb3d682018-05-17 12:17:28 -04002622#Param doAntiAlias true if Clip is to be Anti_Aliased ##
Cary Clark8032b982017-07-28 11:04:54 -04002623
2624#Example
2625#Description
2626Top figure uses SkPath::kInverseWinding_FillType and SkClipOp::kDifference;
2627area outside clip is subtracted from circle.
2628
2629Bottom figure uses SkPath::kWinding_FillType and SkClipOp::kIntersect;
2630area inside clip is intersected with circle.
2631##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002632void draw(SkCanvas* canvas) {
2633 SkPaint paint;
2634 paint.setAntiAlias(true);
2635 SkPath path;
2636 path.addRect({20, 30, 100, 110});
2637 path.setFillType(SkPath::kInverseWinding_FillType);
2638 canvas->save();
2639 canvas->clipPath(path, SkClipOp::kDifference, false);
2640 canvas->drawCircle(70, 100, 60, paint);
2641 canvas->restore();
2642 canvas->translate(100, 100);
2643 path.setFillType(SkPath::kWinding_FillType);
2644 canvas->clipPath(path, SkClipOp::kIntersect, false);
2645 canvas->drawCircle(70, 100, 60, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002646}
2647##
2648
Cary Clark2ade9972017-11-02 17:49:34 -04002649#SeeAlso clipRect clipRRect clipRegion
Cary Clark8032b982017-07-28 11:04:54 -04002650
2651##
2652
Herb Derbyefe39bc2018-05-01 17:06:20 -04002653#Method void clipPath(const SkPath& path, SkClipOp op)
Cary Clark8032b982017-07-28 11:04:54 -04002654
Cary Clarkab2621d2018-01-30 10:08:57 -05002655#In Clip
Cary Clark80247e52018-07-11 16:18:41 -04002656Replaces Clip with the intersection or difference of Clip and path.
Cary Clarkce101242017-09-01 15:51:02 -04002657Resulting Clip is Aliased; pixels are fully contained by the clip.
Cary Clark8032b982017-07-28 11:04:54 -04002658Path_Fill_Type determines if path
2659describes the area inside or outside its contours; and if Path_Contour overlaps
2660itself or another Path_Contour, whether the overlaps form part of the area.
2661path is transformed by Matrix
2662before it is combined with Clip.
2663
Cary Clarkbad5ad72017-08-03 17:14:08 -04002664#Param path Path to combine with Clip ##
2665#Param op Clip_Op to apply to Clip ##
Cary Clark8032b982017-07-28 11:04:54 -04002666
2667#Example
2668#Description
Cary Clarkbc5697d2017-10-04 14:31:33 -04002669Overlapping Rects form a clip. When clip Path_Fill_Type is set to
Herb Derbyefe39bc2018-05-01 17:06:20 -04002670SkPath::kWinding_FillType, the overlap is included. Set to
Cary Clark8032b982017-07-28 11:04:54 -04002671SkPath::kEvenOdd_FillType, the overlap is excluded and forms a hole.
2672##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002673void draw(SkCanvas* canvas) {
2674 SkPaint paint;
2675 paint.setAntiAlias(true);
2676 SkPath path;
2677 path.addRect({20, 15, 100, 95});
2678 path.addRect({50, 65, 130, 135});
2679 path.setFillType(SkPath::kWinding_FillType);
2680 canvas->save();
2681 canvas->clipPath(path, SkClipOp::kIntersect);
2682 canvas->drawCircle(70, 85, 60, paint);
2683 canvas->restore();
2684 canvas->translate(100, 100);
2685 path.setFillType(SkPath::kEvenOdd_FillType);
2686 canvas->clipPath(path, SkClipOp::kIntersect);
2687 canvas->drawCircle(70, 85, 60, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002688}
2689##
2690
Cary Clark2ade9972017-11-02 17:49:34 -04002691#SeeAlso clipRect clipRRect clipRegion
Cary Clark8032b982017-07-28 11:04:54 -04002692
2693##
2694
Herb Derbyefe39bc2018-05-01 17:06:20 -04002695#Method void clipPath(const SkPath& path, bool doAntiAlias = false)
Cary Clark8032b982017-07-28 11:04:54 -04002696
Cary Clarkab2621d2018-01-30 10:08:57 -05002697#In Clip
Cary Clark80247e52018-07-11 16:18:41 -04002698Replaces Clip with the intersection of Clip and path.
Cary Clarkce101242017-09-01 15:51:02 -04002699Resulting Clip is Aliased; pixels are fully contained by the clip.
Cary Clark8032b982017-07-28 11:04:54 -04002700Path_Fill_Type determines if path
2701describes the area inside or outside its contours; and if Path_Contour overlaps
2702itself or another Path_Contour, whether the overlaps form part of the area.
Cary Clarkbad5ad72017-08-03 17:14:08 -04002703path is transformed by Matrix before it is combined with Clip.
Cary Clark8032b982017-07-28 11:04:54 -04002704
Cary Clarkbad5ad72017-08-03 17:14:08 -04002705#Param path Path to combine with Clip ##
Cary Clarkffb3d682018-05-17 12:17:28 -04002706#Param doAntiAlias true if Clip is to be Anti_Aliased ##
Cary Clark8032b982017-07-28 11:04:54 -04002707
2708#Example
2709#Height 212
2710#Description
Herb Derbyefe39bc2018-05-01 17:06:20 -04002711Clip loops over itself covering its center twice. When clip Path_Fill_Type
2712is set to SkPath::kWinding_FillType, the overlap is included. Set to
Cary Clark8032b982017-07-28 11:04:54 -04002713SkPath::kEvenOdd_FillType, the overlap is excluded and forms a hole.
2714##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002715void draw(SkCanvas* canvas) {
2716 SkPaint paint;
2717 paint.setAntiAlias(true);
2718 SkPath path;
2719 SkPoint poly[] = {{20, 20}, { 80, 20}, { 80, 80}, {40, 80},
2720 {40, 40}, {100, 40}, {100, 100}, {20, 100}};
2721 path.addPoly(poly, SK_ARRAY_COUNT(poly), true);
2722 path.setFillType(SkPath::kWinding_FillType);
2723 canvas->save();
2724 canvas->clipPath(path, SkClipOp::kIntersect);
2725 canvas->drawCircle(50, 50, 45, paint);
2726 canvas->restore();
2727 canvas->translate(100, 100);
2728 path.setFillType(SkPath::kEvenOdd_FillType);
2729 canvas->clipPath(path, SkClipOp::kIntersect);
2730 canvas->drawCircle(50, 50, 45, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002731}
2732##
2733
Cary Clark2ade9972017-11-02 17:49:34 -04002734#SeeAlso clipRect clipRRect clipRegion
Cary Clark8032b982017-07-28 11:04:54 -04002735
2736##
2737
2738# ------------------------------------------------------------------------------
2739
Herb Derbyefe39bc2018-05-01 17:06:20 -04002740#Method void setAllowSimplifyClip(bool allow)
Cary Clark8032b982017-07-28 11:04:54 -04002741
Cary Clarkab2621d2018-01-30 10:08:57 -05002742#In Clip
Cary Clark682c58d2018-05-16 07:07:07 -04002743#Experimental testing
Cary Clark8032b982017-07-28 11:04:54 -04002744
Cary Clarkce101242017-09-01 15:51:02 -04002745Set to simplify clip stack using PathOps.
Cary Clark8032b982017-07-28 11:04:54 -04002746
2747##
2748
2749# ------------------------------------------------------------------------------
2750
2751#Method void clipRegion(const SkRegion& deviceRgn, SkClipOp op = SkClipOp::kIntersect)
2752
Cary Clarkab2621d2018-01-30 10:08:57 -05002753#In Clip
2754#Line # combines Clip with Region ##
Cary Clark80247e52018-07-11 16:18:41 -04002755Replaces Clip with the intersection or difference of Clip and Region deviceRgn.
Cary Clarkce101242017-09-01 15:51:02 -04002756Resulting Clip is Aliased; pixels are fully contained by the clip.
Cary Clark8032b982017-07-28 11:04:54 -04002757deviceRgn is unaffected by Matrix.
2758
Cary Clarkbad5ad72017-08-03 17:14:08 -04002759#Param deviceRgn Region to combine with Clip ##
2760#Param op Clip_Op to apply to Clip ##
Cary Clark8032b982017-07-28 11:04:54 -04002761
2762#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04002763#Description
Cary Clarkce101242017-09-01 15:51:02 -04002764 region is unaffected by canvas rotation; iRect is affected by canvas rotation.
2765 Both clips are Aliased; this is not noticeable on Region clip because it
Cary Clarkbad5ad72017-08-03 17:14:08 -04002766 aligns to pixel boundaries.
2767##
2768void draw(SkCanvas* canvas) {
2769 SkPaint paint;
2770 paint.setAntiAlias(true);
2771 SkIRect iRect = {30, 40, 120, 130 };
2772 SkRegion region(iRect);
2773 canvas->rotate(10);
2774 canvas->save();
2775 canvas->clipRegion(region, SkClipOp::kIntersect);
2776 canvas->drawCircle(50, 50, 45, paint);
2777 canvas->restore();
2778 canvas->translate(100, 100);
2779 canvas->clipRect(SkRect::Make(iRect), SkClipOp::kIntersect);
2780 canvas->drawCircle(50, 50, 45, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002781}
2782##
2783
Cary Clark2ade9972017-11-02 17:49:34 -04002784#SeeAlso clipRect clipRRect clipPath
Cary Clark8032b982017-07-28 11:04:54 -04002785
2786##
2787
2788#Method bool quickReject(const SkRect& rect) const
2789
Cary Clarkab2621d2018-01-30 10:08:57 -05002790#In Clip
2791#Line # returns if Rect is outside Clip ##
Cary Clark80247e52018-07-11 16:18:41 -04002792Returns true if Rect rect, transformed by Matrix, can be quickly determined to be
Cary Clark8032b982017-07-28 11:04:54 -04002793outside of Clip. May return false even though rect is outside of Clip.
2794
2795Use to check if an area to be drawn is clipped out, to skip subsequent draw calls.
2796
Cary Clarkbad5ad72017-08-03 17:14:08 -04002797#Param rect Rect to compare with Clip ##
Cary Clark8032b982017-07-28 11:04:54 -04002798
Cary Clarkbad5ad72017-08-03 17:14:08 -04002799#Return true if rect, transformed by Matrix, does not intersect Clip ##
Cary Clark8032b982017-07-28 11:04:54 -04002800
2801#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04002802void draw(SkCanvas* canvas) {
Herb Derbyefe39bc2018-05-01 17:06:20 -04002803 SkRect testRect = {30, 30, 120, 129 };
2804 SkRect clipRect = {30, 130, 120, 230 };
Cary Clarkbad5ad72017-08-03 17:14:08 -04002805 canvas->save();
2806 canvas->clipRect(clipRect);
2807 SkDebugf("quickReject %s\n", canvas->quickReject(testRect) ? "true" : "false");
2808 canvas->restore();
2809 canvas->rotate(10);
2810 canvas->clipRect(clipRect);
2811 SkDebugf("quickReject %s\n", canvas->quickReject(testRect) ? "true" : "false");
Cary Clark8032b982017-07-28 11:04:54 -04002812}
2813 #StdOut
Cary Clarkbad5ad72017-08-03 17:14:08 -04002814 quickReject true
Cary Clark8032b982017-07-28 11:04:54 -04002815 quickReject false
2816 ##
2817##
2818
Cary Clark2ade9972017-11-02 17:49:34 -04002819#SeeAlso getLocalClipBounds getTotalMatrix SkBitmap::drawsNothing
Cary Clark8032b982017-07-28 11:04:54 -04002820
2821##
2822
2823#Method bool quickReject(const SkPath& path) const
2824
Cary Clarkab2621d2018-01-30 10:08:57 -05002825#In Clip
Cary Clark80247e52018-07-11 16:18:41 -04002826Returns true if path, transformed by Matrix, can be quickly determined to be
Cary Clark8032b982017-07-28 11:04:54 -04002827outside of Clip. May return false even though path is outside of Clip.
2828
2829Use to check if an area to be drawn is clipped out, to skip subsequent draw calls.
2830
Cary Clarkbad5ad72017-08-03 17:14:08 -04002831#Param path Path to compare with Clip ##
Cary Clark8032b982017-07-28 11:04:54 -04002832
Cary Clarkbad5ad72017-08-03 17:14:08 -04002833#Return true if path, transformed by Matrix, does not intersect Clip ##
Cary Clark8032b982017-07-28 11:04:54 -04002834
2835#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04002836void draw(SkCanvas* canvas) {
Herb Derbyefe39bc2018-05-01 17:06:20 -04002837 SkPoint testPoints[] = {{30, 30}, {120, 30}, {120, 129} };
2838 SkPoint clipPoints[] = {{30, 130}, {120, 130}, {120, 230} };
Cary Clarkbad5ad72017-08-03 17:14:08 -04002839 SkPath testPath, clipPath;
2840 testPath.addPoly(testPoints, SK_ARRAY_COUNT(testPoints), true);
2841 clipPath.addPoly(clipPoints, SK_ARRAY_COUNT(clipPoints), true);
2842 canvas->save();
2843 canvas->clipPath(clipPath);
2844 SkDebugf("quickReject %s\n", canvas->quickReject(testPath) ? "true" : "false");
2845 canvas->restore();
2846 canvas->rotate(10);
2847 canvas->clipPath(clipPath);
2848 SkDebugf("quickReject %s\n", canvas->quickReject(testPath) ? "true" : "false");
Cary Clark8032b982017-07-28 11:04:54 -04002849 #StdOut
Cary Clarkbad5ad72017-08-03 17:14:08 -04002850 quickReject true
Cary Clark8032b982017-07-28 11:04:54 -04002851 quickReject false
2852 ##
2853}
2854##
2855
Cary Clark2ade9972017-11-02 17:49:34 -04002856#SeeAlso getLocalClipBounds getTotalMatrix SkBitmap::drawsNothing
Cary Clark8032b982017-07-28 11:04:54 -04002857
2858##
2859
Herb Derbyefe39bc2018-05-01 17:06:20 -04002860#Method SkRect getLocalClipBounds() const
Cary Clark8032b982017-07-28 11:04:54 -04002861
Cary Clarkab2621d2018-01-30 10:08:57 -05002862#In Clip
2863#Line # returns Clip bounds in source coordinates ##
Cary Clark80247e52018-07-11 16:18:41 -04002864Returns bounds of Clip, transformed by inverse of Matrix. If Clip is empty,
Cary Clark8032b982017-07-28 11:04:54 -04002865return SkRect::MakeEmpty, where all Rect sides equal zero.
2866
2867Rect returned is outset by one to account for partial pixel coverage if Clip
Cary Clarkffb3d682018-05-17 12:17:28 -04002868is Anti_Aliased.
Cary Clark8032b982017-07-28 11:04:54 -04002869
Cary Clarkbad5ad72017-08-03 17:14:08 -04002870#Return bounds of Clip in local coordinates ##
Cary Clark8032b982017-07-28 11:04:54 -04002871
2872#Example
Herb Derbyefe39bc2018-05-01 17:06:20 -04002873 #Description
Cary Clark8032b982017-07-28 11:04:54 -04002874 Initial bounds is device bounds outset by 1 on all sides.
2875 Clipped bounds is clipPath bounds outset by 1 on all sides.
Cary Clark5538c132018-06-14 12:28:14 -04002876 Scaling the canvas by two on both axes scales the local bounds by 1/2
2877 on both axes.
Cary Clark8032b982017-07-28 11:04:54 -04002878 ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002879 SkCanvas local(256, 256);
2880 canvas = &local;
2881 SkRect bounds = canvas->getLocalClipBounds();
2882 SkDebugf("left:%g top:%g right:%g bottom:%g\n",
2883 bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom);
Herb Derbyefe39bc2018-05-01 17:06:20 -04002884 SkPoint clipPoints[] = {{30, 130}, {120, 130}, {120, 230} };
Cary Clarkbad5ad72017-08-03 17:14:08 -04002885 SkPath clipPath;
2886 clipPath.addPoly(clipPoints, SK_ARRAY_COUNT(clipPoints), true);
2887 canvas->clipPath(clipPath);
2888 bounds = canvas->getLocalClipBounds();
2889 SkDebugf("left:%g top:%g right:%g bottom:%g\n",
2890 bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom);
2891 canvas->scale(2, 2);
2892 bounds = canvas->getLocalClipBounds();
2893 SkDebugf("left:%g top:%g right:%g bottom:%g\n",
2894 bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom);
2895 #StdOut
2896 left:-1 top:-1 right:257 bottom:257
2897 left:29 top:129 right:121 bottom:231
2898 left:14.5 top:64.5 right:60.5 bottom:115.5
2899 ##
Cary Clark8032b982017-07-28 11:04:54 -04002900##
2901
2902# local canvas in example works around bug in fiddle ##
Cary Clark4855f782018-02-06 09:41:53 -05002903#Bug 6524
Cary Clark2ade9972017-11-02 17:49:34 -04002904#SeeAlso getDeviceClipBounds getBaseLayerSize quickReject
Cary Clark8032b982017-07-28 11:04:54 -04002905
2906##
2907
Herb Derbyefe39bc2018-05-01 17:06:20 -04002908#Method bool getLocalClipBounds(SkRect* bounds) const
Cary Clark8032b982017-07-28 11:04:54 -04002909
Cary Clarkab2621d2018-01-30 10:08:57 -05002910#In Clip
Cary Clark80247e52018-07-11 16:18:41 -04002911Returns bounds of Clip, transformed by inverse of Matrix. If Clip is empty,
Cary Clark8032b982017-07-28 11:04:54 -04002912return false, and set bounds to SkRect::MakeEmpty, where all Rect sides equal zero.
2913
2914bounds is outset by one to account for partial pixel coverage if Clip
Cary Clarkffb3d682018-05-17 12:17:28 -04002915is Anti_Aliased.
Cary Clark8032b982017-07-28 11:04:54 -04002916
Cary Clarkbad5ad72017-08-03 17:14:08 -04002917#Param bounds Rect of Clip in local coordinates ##
Cary Clark8032b982017-07-28 11:04:54 -04002918
Cary Clarkbad5ad72017-08-03 17:14:08 -04002919#Return true if Clip bounds is not empty ##
Cary Clark8032b982017-07-28 11:04:54 -04002920
2921#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04002922 void draw(SkCanvas* canvas) {
2923 SkCanvas local(256, 256);
2924 canvas = &local;
2925 SkRect bounds;
2926 SkDebugf("local bounds empty = %s\n", canvas->getLocalClipBounds(&bounds)
2927 ? "false" : "true");
2928 SkPath path;
2929 canvas->clipPath(path);
2930 SkDebugf("local bounds empty = %s\n", canvas->getLocalClipBounds(&bounds)
2931 ? "false" : "true");
Cary Clark8032b982017-07-28 11:04:54 -04002932 }
2933 #StdOut
Cary Clarkbad5ad72017-08-03 17:14:08 -04002934 local bounds empty = false
Cary Clark8032b982017-07-28 11:04:54 -04002935 local bounds empty = true
2936 ##
2937##
2938
2939# local canvas in example works around bug in fiddle ##
Cary Clark4855f782018-02-06 09:41:53 -05002940#Bug 6524
Cary Clark2ade9972017-11-02 17:49:34 -04002941#SeeAlso getDeviceClipBounds getBaseLayerSize quickReject
Cary Clark8032b982017-07-28 11:04:54 -04002942
2943##
2944
Herb Derbyefe39bc2018-05-01 17:06:20 -04002945#Method SkIRect getDeviceClipBounds() const
Cary Clark8032b982017-07-28 11:04:54 -04002946
Cary Clarkab2621d2018-01-30 10:08:57 -05002947#In Clip
2948#Line # returns IRect bounds of Clip ##
Cary Clark80247e52018-07-11 16:18:41 -04002949Returns IRect bounds of Clip, unaffected by Matrix. If Clip is empty,
Cary Clark8032b982017-07-28 11:04:54 -04002950return SkRect::MakeEmpty, where all Rect sides equal zero.
2951
Herb Derbyefe39bc2018-05-01 17:06:20 -04002952Unlike getLocalClipBounds, returned IRect is not outset.
Cary Clark8032b982017-07-28 11:04:54 -04002953
Cary Clarkbad5ad72017-08-03 17:14:08 -04002954#Return bounds of Clip in Device coordinates ##
Cary Clark8032b982017-07-28 11:04:54 -04002955
2956#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04002957void draw(SkCanvas* canvas) {
2958 #Description
Cary Clark8032b982017-07-28 11:04:54 -04002959 Initial bounds is device bounds, not outset.
2960 Clipped bounds is clipPath bounds, not outset.
Cary Clark5538c132018-06-14 12:28:14 -04002961 Scaling the canvas by 1/2 on both axes scales the device bounds by 1/2
2962 on both axes.
Cary Clarkbad5ad72017-08-03 17:14:08 -04002963 ##
2964 SkCanvas device(256, 256);
2965 canvas = &device;
2966 SkIRect bounds = canvas->getDeviceClipBounds();
2967 SkDebugf("left:%d top:%d right:%d bottom:%d\n",
2968 bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom);
Herb Derbyefe39bc2018-05-01 17:06:20 -04002969 SkPoint clipPoints[] = {{30, 130}, {120, 130}, {120, 230} };
Cary Clarkbad5ad72017-08-03 17:14:08 -04002970 SkPath clipPath;
2971 clipPath.addPoly(clipPoints, SK_ARRAY_COUNT(clipPoints), true);
2972 canvas->save();
2973 canvas->clipPath(clipPath);
2974 bounds = canvas->getDeviceClipBounds();
2975 SkDebugf("left:%d top:%d right:%d bottom:%d\n",
2976 bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom);
2977 canvas->restore();
2978 canvas->scale(1.f/2, 1.f/2);
2979 canvas->clipPath(clipPath);
2980 bounds = canvas->getDeviceClipBounds();
2981 SkDebugf("left:%d top:%d right:%d bottom:%d\n",
2982 bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom);
Cary Clark8032b982017-07-28 11:04:54 -04002983 #StdOut
Cary Clarkbad5ad72017-08-03 17:14:08 -04002984 left:0 top:0 right:256 bottom:256
2985 left:30 top:130 right:120 bottom:230
Cary Clark8032b982017-07-28 11:04:54 -04002986 left:15 top:65 right:60 bottom:115
2987 ##
2988}
2989##
2990
2991#ToDo some confusion on why with an identity Matrix local and device are different ##
Cary Clark2ade9972017-11-02 17:49:34 -04002992#SeeAlso getLocalClipBounds getBaseLayerSize quickReject
Cary Clark8032b982017-07-28 11:04:54 -04002993
2994# device canvas in example works around bug in fiddle ##
Cary Clark4855f782018-02-06 09:41:53 -05002995#Bug 6524
Cary Clark8032b982017-07-28 11:04:54 -04002996
2997##
2998
Herb Derbyefe39bc2018-05-01 17:06:20 -04002999#Method bool getDeviceClipBounds(SkIRect* bounds) const
Cary Clark8032b982017-07-28 11:04:54 -04003000
Cary Clarkab2621d2018-01-30 10:08:57 -05003001#In Clip
Cary Clark80247e52018-07-11 16:18:41 -04003002Returns IRect bounds of Clip, unaffected by Matrix. If Clip is empty,
Cary Clark8032b982017-07-28 11:04:54 -04003003return false, and set bounds to SkRect::MakeEmpty, where all Rect sides equal zero.
3004
Herb Derbyefe39bc2018-05-01 17:06:20 -04003005Unlike getLocalClipBounds, bounds is not outset.
Cary Clark8032b982017-07-28 11:04:54 -04003006
Cary Clarkbad5ad72017-08-03 17:14:08 -04003007#Param bounds Rect of Clip in device coordinates ##
Cary Clark8032b982017-07-28 11:04:54 -04003008
Cary Clarkbad5ad72017-08-03 17:14:08 -04003009#Return true if Clip bounds is not empty ##
Cary Clark8032b982017-07-28 11:04:54 -04003010
3011#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003012 void draw(SkCanvas* canvas) {
3013 SkIRect bounds;
3014 SkDebugf("device bounds empty = %s\n", canvas->getDeviceClipBounds(&bounds)
3015 ? "false" : "true");
3016 SkPath path;
3017 canvas->clipPath(path);
3018 SkDebugf("device bounds empty = %s\n", canvas->getDeviceClipBounds(&bounds)
3019 ? "false" : "true");
Cary Clark8032b982017-07-28 11:04:54 -04003020 }
3021 #StdOut
Cary Clarkbad5ad72017-08-03 17:14:08 -04003022 device bounds empty = false
Cary Clark8032b982017-07-28 11:04:54 -04003023 device bounds empty = true
3024 ##
3025##
3026
Cary Clark2ade9972017-11-02 17:49:34 -04003027#SeeAlso getLocalClipBounds getBaseLayerSize quickReject
Cary Clark8032b982017-07-28 11:04:54 -04003028
3029##
3030
Cary Clark08895c42018-02-01 09:37:32 -05003031#Subtopic Clip ##
Cary Clark8032b982017-07-28 11:04:54 -04003032
3033# ------------------------------------------------------------------------------
Cary Clark78de7512018-02-07 07:27:09 -05003034#Subtopic Draw
3035#Populate
3036#Line # draws into Canvas ##
3037##
Cary Clark8032b982017-07-28 11:04:54 -04003038
3039#Method void drawColor(SkColor color, SkBlendMode mode = SkBlendMode::kSrcOver)
Cary Clark78de7512018-02-07 07:27:09 -05003040#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05003041#Line # fills Clip with Color and Blend_Mode ##
Cary Clark80247e52018-07-11 16:18:41 -04003042Fills Clip with Color color.
Cary Clarkffb3d682018-05-17 12:17:28 -04003043mode determines how ARGB is combined with destination.
Cary Clark8032b982017-07-28 11:04:54 -04003044
Cary Clarkffb3d682018-05-17 12:17:28 -04003045#Param color Unpremultiplied ARGB ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003046#Param mode SkBlendMode used to combine source color and destination ##
Cary Clark8032b982017-07-28 11:04:54 -04003047
3048#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003049 canvas->drawColor(SK_ColorRED);
3050 canvas->clipRect(SkRect::MakeWH(150, 150));
3051 canvas->drawColor(SkColorSetARGB(0x80, 0x00, 0xFF, 0x00), SkBlendMode::kPlus);
3052 canvas->clipRect(SkRect::MakeWH(75, 75));
3053 canvas->drawColor(SkColorSetARGB(0x80, 0x00, 0x00, 0xFF), SkBlendMode::kPlus);
Cary Clark8032b982017-07-28 11:04:54 -04003054##
3055
Cary Clark2ade9972017-11-02 17:49:34 -04003056#SeeAlso clear SkBitmap::erase drawPaint
Cary Clark8032b982017-07-28 11:04:54 -04003057
3058##
3059
3060# ------------------------------------------------------------------------------
3061
Herb Derbyefe39bc2018-05-01 17:06:20 -04003062#Method void clear(SkColor color)
Cary Clark78de7512018-02-07 07:27:09 -05003063#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05003064#Line # fills Clip with Color ##
Cary Clark80247e52018-07-11 16:18:41 -04003065Fills Clip with Color color using SkBlendMode::kSrc.
Cary Clark8032b982017-07-28 11:04:54 -04003066This has the effect of replacing all pixels contained by Clip with color.
3067
Cary Clarkffb3d682018-05-17 12:17:28 -04003068#Param color Unpremultiplied ARGB ##
Cary Clark8032b982017-07-28 11:04:54 -04003069
3070#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003071void draw(SkCanvas* canvas) {
3072 canvas->save();
3073 canvas->clipRect(SkRect::MakeWH(256, 128));
Herb Derbyefe39bc2018-05-01 17:06:20 -04003074 canvas->clear(SkColorSetARGB(0x80, 0xFF, 0x00, 0x00));
Cary Clarkbad5ad72017-08-03 17:14:08 -04003075 canvas->restore();
3076 canvas->save();
3077 canvas->clipRect(SkRect::MakeWH(150, 192));
3078 canvas->clear(SkColorSetARGB(0x80, 0x00, 0xFF, 0x00));
3079 canvas->restore();
3080 canvas->clipRect(SkRect::MakeWH(75, 256));
3081 canvas->clear(SkColorSetARGB(0x80, 0x00, 0x00, 0xFF));
Cary Clark8032b982017-07-28 11:04:54 -04003082}
3083##
3084
Cary Clark2ade9972017-11-02 17:49:34 -04003085#SeeAlso drawColor SkBitmap::erase drawPaint
Cary Clark8032b982017-07-28 11:04:54 -04003086
3087##
3088
3089# ------------------------------------------------------------------------------
3090
Herb Derbyefe39bc2018-05-01 17:06:20 -04003091#Method void discard()
Cary Clark78de7512018-02-07 07:27:09 -05003092#In Utility
Cary Clarkab2621d2018-01-30 10:08:57 -05003093#Line # makes Canvas contents undefined ##
Cary Clark80247e52018-07-11 16:18:41 -04003094Makes Canvas contents undefined. Subsequent calls that read Canvas pixels,
Cary Clark8032b982017-07-28 11:04:54 -04003095such as drawing with SkBlendMode, return undefined results. discard() does
3096not change Clip or Matrix.
3097
3098discard() may do nothing, depending on the implementation of Surface or Device
3099that created Canvas.
3100
3101discard() allows optimized performance on subsequent draws by removing
3102cached data associated with Surface or Device.
3103It is not necessary to call discard() once done with Canvas;
3104any cached data is deleted when owning Surface or Device is deleted.
3105
3106#ToDo example? not sure how to make this meaningful w/o more implementation detail ##
Cary Clark2ade9972017-11-02 17:49:34 -04003107#SeeAlso flush() SkSurface::prepareForExternalIO GrContext::abandonContext
Cary Clark8032b982017-07-28 11:04:54 -04003108
Herb Derbyefe39bc2018-05-01 17:06:20 -04003109#NoExample
Cary Clark8032b982017-07-28 11:04:54 -04003110##
3111
3112##
3113
3114# ------------------------------------------------------------------------------
3115
3116#Method void drawPaint(const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05003117#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05003118#Line # fills Clip with Paint ##
Cary Clark80247e52018-07-11 16:18:41 -04003119Fills Clip with Paint paint. Paint components Mask_Filter, Shader,
Cary Clarkbad5ad72017-08-03 17:14:08 -04003120Color_Filter, Image_Filter, and Blend_Mode affect drawing;
3121Path_Effect in paint is ignored.
Cary Clark8032b982017-07-28 11:04:54 -04003122
3123# can Path_Effect in paint ever alter drawPaint?
3124
Cary Clarkbad5ad72017-08-03 17:14:08 -04003125#Param paint graphics state used to fill Canvas ##
Cary Clark8032b982017-07-28 11:04:54 -04003126
3127#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003128void draw(SkCanvas* canvas) {
3129 SkColor colors[] = { SK_ColorRED, SK_ColorGREEN, SK_ColorBLUE };
3130 SkScalar pos[] = { 0, SK_Scalar1/2, SK_Scalar1 };
3131 SkPaint paint;
3132 paint.setShader(SkGradientShader::MakeSweep(256, 256, colors, pos, SK_ARRAY_COUNT(colors)));
3133 canvas->drawPaint(paint);
Cary Clark8032b982017-07-28 11:04:54 -04003134}
3135##
3136
Cary Clark2ade9972017-11-02 17:49:34 -04003137#SeeAlso clear drawColor SkBitmap::erase
Cary Clark8032b982017-07-28 11:04:54 -04003138
3139##
3140
3141# ------------------------------------------------------------------------------
3142
3143#Enum PointMode
Cary Clark08895c42018-02-01 09:37:32 -05003144#Line # sets drawPoints options ##
Cary Clark8032b982017-07-28 11:04:54 -04003145
3146#Code
3147 enum PointMode {
3148 kPoints_PointMode,
3149 kLines_PointMode,
Cary Clarkd0530ba2017-09-14 11:25:39 -04003150 kPolygon_PointMode,
Cary Clark8032b982017-07-28 11:04:54 -04003151 };
3152##
3153
3154Selects if an array of points are drawn as discrete points, as lines, or as
3155an open polygon.
3156
3157#Const kPoints_PointMode 0
Cary Clark682c58d2018-05-16 07:07:07 -04003158#Line # draw each point separately ##
Cary Clark8032b982017-07-28 11:04:54 -04003159##
3160
3161#Const kLines_PointMode 1
Cary Clark682c58d2018-05-16 07:07:07 -04003162#Line # draw each pair of points as a line segment ##
Cary Clark8032b982017-07-28 11:04:54 -04003163##
3164
3165#Const kPolygon_PointMode 2
Cary Clark682c58d2018-05-16 07:07:07 -04003166#Line # draw the array of points as a open polygon ##
Cary Clark8032b982017-07-28 11:04:54 -04003167##
3168
3169#Example
Herb Derbyefe39bc2018-05-01 17:06:20 -04003170 #Description
Cary Clark8032b982017-07-28 11:04:54 -04003171 The upper left corner shows three squares when drawn as points.
3172 The upper right corner shows one line; when drawn as lines, two points are required per line.
3173 The lower right corner shows two lines; when draw as polygon, no miter is drawn at the corner.
3174 The lower left corner shows two lines with a miter when path contains polygon.
3175 ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003176void draw(SkCanvas* canvas) {
3177 SkPaint paint;
3178 paint.setStyle(SkPaint::kStroke_Style);
3179 paint.setStrokeWidth(10);
3180 SkPoint points[] = {{64, 32}, {96, 96}, {32, 96}};
3181 canvas->drawPoints(SkCanvas::kPoints_PointMode, 3, points, paint);
3182 canvas->translate(128, 0);
3183 canvas->drawPoints(SkCanvas::kLines_PointMode, 3, points, paint);
3184 canvas->translate(0, 128);
3185 canvas->drawPoints(SkCanvas::kPolygon_PointMode, 3, points, paint);
3186 SkPath path;
3187 path.addPoly(points, 3, false);
3188 canvas->translate(-128, 0);
3189 canvas->drawPath(path, paint);
Cary Clark8032b982017-07-28 11:04:54 -04003190}
3191##
3192
Cary Clark2ade9972017-11-02 17:49:34 -04003193#SeeAlso drawLine drawPoint drawPath
Cary Clark8032b982017-07-28 11:04:54 -04003194
3195##
3196
3197# ------------------------------------------------------------------------------
3198
3199#Method void drawPoints(PointMode mode, size_t count, const SkPoint pts[], const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05003200#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05003201#Line # draws array as points, lines, polygon ##
Cary Clark80247e52018-07-11 16:18:41 -04003202Draws pts using Clip, Matrix and Paint paint.
Cary Clarkbad5ad72017-08-03 17:14:08 -04003203count is the number of points; if count is less than one, has no effect.
Cary Clark8032b982017-07-28 11:04:54 -04003204mode may be one of: kPoints_PointMode, kLines_PointMode, or kPolygon_PointMode.
3205
Cary Clarkbad5ad72017-08-03 17:14:08 -04003206If mode is kPoints_PointMode, the shape of point drawn depends on paint
3207Paint_Stroke_Cap. If paint is set to SkPaint::kRound_Cap, each point draws a
3208circle of diameter Paint_Stroke_Width. If paint is set to SkPaint::kSquare_Cap
3209or SkPaint::kButt_Cap, each point draws a square of width and height
3210Paint_Stroke_Width.
Cary Clark8032b982017-07-28 11:04:54 -04003211
3212If mode is kLines_PointMode, each pair of points draws a line segment.
3213One line is drawn for every two points; each point is used once. If count is odd,
Herb Derbyefe39bc2018-05-01 17:06:20 -04003214the final point is ignored.
Cary Clark8032b982017-07-28 11:04:54 -04003215
3216If mode is kPolygon_PointMode, each adjacent pair of points draws a line segment.
3217count minus one lines are drawn; the first and last point are used once.
3218
3219Each line segment respects paint Paint_Stroke_Cap and Paint_Stroke_Width.
3220Paint_Style is ignored, as if were set to SkPaint::kStroke_Style.
3221
Cary Clarkbad5ad72017-08-03 17:14:08 -04003222Always draws each element one at a time; is not affected by
3223Paint_Stroke_Join, and unlike drawPath, does not create a mask from all points
Herb Derbyefe39bc2018-05-01 17:06:20 -04003224and lines before drawing.
Cary Clark8032b982017-07-28 11:04:54 -04003225
Cary Clarka523d2d2017-08-30 08:58:10 -04003226#Param mode whether pts draws points or lines ##
3227#Param count number of points in the array ##
3228#Param pts array of points to draw ##
3229#Param paint stroke, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003230
3231#Example
3232#Height 200
Herb Derbyefe39bc2018-05-01 17:06:20 -04003233 #Description
Cary Clark8032b982017-07-28 11:04:54 -04003234 #List
3235 # The first column draws points. ##
3236 # The second column draws points as lines. ##
3237 # The third column draws points as a polygon. ##
3238 # The fourth column draws points as a polygonal path. ##
3239 # The first row uses a round cap and round join. ##
3240 # The second row uses a square cap and a miter join. ##
3241 # The third row uses a butt cap and a bevel join. ##
3242 ##
3243 The transparent color makes multiple line draws visible;
3244 the path is drawn all at once.
3245 ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003246void draw(SkCanvas* canvas) {
3247 SkPaint paint;
3248 paint.setAntiAlias(true);
3249 paint.setStyle(SkPaint::kStroke_Style);
3250 paint.setStrokeWidth(10);
3251 paint.setColor(0x80349a45);
3252 const SkPoint points[] = {{32, 16}, {48, 48}, {16, 32}};
Herb Derbyefe39bc2018-05-01 17:06:20 -04003253 const SkPaint::Join join[] = { SkPaint::kRound_Join,
Cary Clarkbad5ad72017-08-03 17:14:08 -04003254 SkPaint::kMiter_Join,
3255 SkPaint::kBevel_Join };
3256 int joinIndex = 0;
3257 SkPath path;
3258 path.addPoly(points, 3, false);
3259 for (const auto cap : { SkPaint::kRound_Cap, SkPaint::kSquare_Cap, SkPaint::kButt_Cap } ) {
3260 paint.setStrokeCap(cap);
3261 paint.setStrokeJoin(join[joinIndex++]);
3262 for (const auto mode : { SkCanvas::kPoints_PointMode,
3263 SkCanvas::kLines_PointMode,
3264 SkCanvas::kPolygon_PointMode } ) {
3265 canvas->drawPoints(mode, 3, points, paint);
3266 canvas->translate(64, 0);
3267 }
3268 canvas->drawPath(path, paint);
3269 canvas->translate(-192, 64);
3270 }
Cary Clark8032b982017-07-28 11:04:54 -04003271}
3272##
3273
Cary Clark2ade9972017-11-02 17:49:34 -04003274#SeeAlso drawLine drawPoint drawPath
Cary Clark8032b982017-07-28 11:04:54 -04003275
3276##
3277
3278# ------------------------------------------------------------------------------
3279
3280#Method void drawPoint(SkScalar x, SkScalar y, const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05003281#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05003282#Line # draws point at (x, y) position ##
Cary Clark80247e52018-07-11 16:18:41 -04003283Draws point at (x, y) using Clip, Matrix and Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04003284
3285The shape of point drawn depends on paint Paint_Stroke_Cap.
Cary Clarkbad5ad72017-08-03 17:14:08 -04003286If paint is set to SkPaint::kRound_Cap, draw a circle of diameter
Herb Derbyefe39bc2018-05-01 17:06:20 -04003287Paint_Stroke_Width. If paint is set to SkPaint::kSquare_Cap or SkPaint::kButt_Cap,
Cary Clark8032b982017-07-28 11:04:54 -04003288draw a square of width and height Paint_Stroke_Width.
3289Paint_Style is ignored, as if were set to SkPaint::kStroke_Style.
3290
Cary Clarkbad5ad72017-08-03 17:14:08 -04003291#Param x left edge of circle or square ##
3292#Param y top edge of circle or square ##
3293#Param paint stroke, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003294
3295#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003296void draw(SkCanvas* canvas) {
3297 SkPaint paint;
3298 paint.setAntiAlias(true);
3299 paint.setColor(0x80349a45);
3300 paint.setStyle(SkPaint::kStroke_Style);
3301 paint.setStrokeWidth(100);
3302 paint.setStrokeCap(SkPaint::kRound_Cap);
3303 canvas->scale(1, 1.2f);
3304 canvas->drawPoint(64, 96, paint);
3305 canvas->scale(.6f, .8f);
3306 paint.setColor(SK_ColorWHITE);
3307 canvas->drawPoint(106, 120, paint);
Cary Clark8032b982017-07-28 11:04:54 -04003308}
3309##
3310
Cary Clark2ade9972017-11-02 17:49:34 -04003311#SeeAlso drawPoints drawCircle drawRect drawLine drawPath
Cary Clark8032b982017-07-28 11:04:54 -04003312
3313##
3314
Cary Clarkbad5ad72017-08-03 17:14:08 -04003315#Method void drawPoint(SkPoint p, const SkPaint& paint)
3316
Cary Clark80247e52018-07-11 16:18:41 -04003317Draws point p using Clip, Matrix and Paint paint.
Cary Clarkbad5ad72017-08-03 17:14:08 -04003318
3319The shape of point drawn depends on paint Paint_Stroke_Cap.
3320If paint is set to SkPaint::kRound_Cap, draw a circle of diameter
Herb Derbyefe39bc2018-05-01 17:06:20 -04003321Paint_Stroke_Width. If paint is set to SkPaint::kSquare_Cap or SkPaint::kButt_Cap,
Cary Clarkbad5ad72017-08-03 17:14:08 -04003322draw a square of width and height Paint_Stroke_Width.
3323Paint_Style is ignored, as if were set to SkPaint::kStroke_Style.
3324
3325#Param p top-left edge of circle or square ##
3326#Param paint stroke, blend, color, and so on, used to draw ##
3327
3328#Example
3329void draw(SkCanvas* canvas) {
3330 SkPaint paint;
3331 paint.setAntiAlias(true);
3332 paint.setColor(0x80349a45);
3333 paint.setStyle(SkPaint::kStroke_Style);
3334 paint.setStrokeWidth(100);
3335 paint.setStrokeCap(SkPaint::kSquare_Cap);
3336 canvas->scale(1, 1.2f);
3337 canvas->drawPoint({64, 96}, paint);
3338 canvas->scale(.6f, .8f);
3339 paint.setColor(SK_ColorWHITE);
3340 canvas->drawPoint(106, 120, paint);
3341}
3342##
3343
Cary Clark2ade9972017-11-02 17:49:34 -04003344#SeeAlso drawPoints drawCircle drawRect drawLine drawPath
Cary Clarkbad5ad72017-08-03 17:14:08 -04003345
3346##
3347
Cary Clark8032b982017-07-28 11:04:54 -04003348# ------------------------------------------------------------------------------
3349
3350#Method void drawLine(SkScalar x0, SkScalar y0, SkScalar x1, SkScalar y1, const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05003351#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05003352#Line # draws line segment between two points ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003353Draws line segment from (x0, y0) to (x1, y1) using Clip, Matrix, and Paint paint.
3354In paint: Paint_Stroke_Width describes the line thickness;
3355Paint_Stroke_Cap draws the end rounded or square;
Cary Clark8032b982017-07-28 11:04:54 -04003356Paint_Style is ignored, as if were set to SkPaint::kStroke_Style.
3357
Cary Clarkbad5ad72017-08-03 17:14:08 -04003358#Param x0 start of line segment on x-axis ##
3359#Param y0 start of line segment on y-axis ##
3360#Param x1 end of line segment on x-axis ##
3361#Param y1 end of line segment on y-axis ##
3362#Param paint stroke, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003363
3364#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003365 SkPaint paint;
3366 paint.setAntiAlias(true);
3367 paint.setColor(0xFF9a67be);
3368 paint.setStrokeWidth(20);
3369 canvas->skew(1, 0);
3370 canvas->drawLine(32, 96, 32, 160, paint);
3371 canvas->skew(-2, 0);
3372 canvas->drawLine(288, 96, 288, 160, paint);
3373##
3374
Cary Clark2ade9972017-11-02 17:49:34 -04003375#SeeAlso drawPoint drawCircle drawRect drawPath
Cary Clarkbad5ad72017-08-03 17:14:08 -04003376
3377##
3378
3379#Method void drawLine(SkPoint p0, SkPoint p1, const SkPaint& paint)
3380
3381Draws line segment from p0 to p1 using Clip, Matrix, and Paint paint.
3382In paint: Paint_Stroke_Width describes the line thickness;
3383Paint_Stroke_Cap draws the end rounded or square;
3384Paint_Style is ignored, as if were set to SkPaint::kStroke_Style.
3385
3386#Param p0 start of line segment ##
3387#Param p1 end of line segment ##
3388#Param paint stroke, blend, color, and so on, used to draw ##
3389
3390#Example
3391 SkPaint paint;
3392 paint.setAntiAlias(true);
3393 paint.setColor(0xFF9a67be);
3394 paint.setStrokeWidth(20);
3395 canvas->skew(1, 0);
3396 canvas->drawLine({32, 96}, {32, 160}, paint);
3397 canvas->skew(-2, 0);
3398 canvas->drawLine({288, 96}, {288, 160}, paint);
Cary Clark8032b982017-07-28 11:04:54 -04003399##
3400
Cary Clark2ade9972017-11-02 17:49:34 -04003401#SeeAlso drawPoint drawCircle drawRect drawPath
Cary Clark8032b982017-07-28 11:04:54 -04003402
3403##
3404
3405# ------------------------------------------------------------------------------
3406
3407#Method void drawRect(const SkRect& rect, const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05003408#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05003409#Line # draws Rect using Clip, Matrix, and Paint ##
Cary Clark80247e52018-07-11 16:18:41 -04003410Draws Rect rect using Clip, Matrix, and Paint paint.
Herb Derbyefe39bc2018-05-01 17:06:20 -04003411In paint: Paint_Style determines if rectangle is stroked or filled;
Cary Clark8032b982017-07-28 11:04:54 -04003412if stroked, Paint_Stroke_Width describes the line thickness, and
3413Paint_Stroke_Join draws the corners rounded or square.
3414
Cary Clarkbc5697d2017-10-04 14:31:33 -04003415#Param rect rectangle to draw ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003416#Param paint stroke or fill, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003417
3418#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003419void draw(SkCanvas* canvas) {
3420 SkPoint rectPts[] = { {64, 48}, {192, 160} };
3421 SkPaint paint;
3422 paint.setAntiAlias(true);
3423 paint.setStyle(SkPaint::kStroke_Style);
3424 paint.setStrokeWidth(20);
3425 paint.setStrokeJoin(SkPaint::kRound_Join);
3426 SkMatrix rotator;
3427 rotator.setRotate(30, 128, 128);
3428 for (auto color : { SK_ColorRED, SK_ColorBLUE, SK_ColorYELLOW, SK_ColorMAGENTA } ) {
3429 paint.setColor(color);
3430 SkRect rect;
3431 rect.set(rectPts[0], rectPts[1]);
3432 canvas->drawRect(rect, paint);
3433 rotator.mapPoints(rectPts, 2);
3434 }
Cary Clark8032b982017-07-28 11:04:54 -04003435}
3436##
3437
Herb Derbyefe39bc2018-05-01 17:06:20 -04003438#SeeAlso drawIRect drawRRect drawRoundRect drawRegion drawPath drawLine
Cary Clark8032b982017-07-28 11:04:54 -04003439
3440##
3441
3442# ------------------------------------------------------------------------------
3443
Herb Derbyefe39bc2018-05-01 17:06:20 -04003444#Method void drawIRect(const SkIRect& rect, const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05003445#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05003446#Line # draws IRect using Clip, Matrix, and Paint ##
Cary Clark80247e52018-07-11 16:18:41 -04003447Draws IRect rect using Clip, Matrix, and Paint paint.
Herb Derbyefe39bc2018-05-01 17:06:20 -04003448In paint: Paint_Style determines if rectangle is stroked or filled;
Cary Clark8032b982017-07-28 11:04:54 -04003449if stroked, Paint_Stroke_Width describes the line thickness, and
3450Paint_Stroke_Join draws the corners rounded or square.
3451
Cary Clarkbc5697d2017-10-04 14:31:33 -04003452#Param rect rectangle to draw ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003453#Param paint stroke or fill, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003454
3455#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003456 SkIRect rect = { 64, 48, 192, 160 };
3457 SkPaint paint;
3458 paint.setAntiAlias(true);
3459 paint.setStyle(SkPaint::kStroke_Style);
3460 paint.setStrokeWidth(20);
3461 paint.setStrokeJoin(SkPaint::kRound_Join);
3462 for (auto color : { SK_ColorRED, SK_ColorBLUE, SK_ColorYELLOW, SK_ColorMAGENTA } ) {
3463 paint.setColor(color);
3464 canvas->drawIRect(rect, paint);
3465 canvas->rotate(30, 128, 128);
3466 }
Cary Clark8032b982017-07-28 11:04:54 -04003467##
3468
Cary Clark2ade9972017-11-02 17:49:34 -04003469#SeeAlso drawRect drawRRect drawRoundRect drawRegion drawPath drawLine
Cary Clark8032b982017-07-28 11:04:54 -04003470
3471##
3472
3473# ------------------------------------------------------------------------------
3474
3475#Method void drawRegion(const SkRegion& region, const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05003476#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05003477#Line # draws Region using Clip, Matrix, and Paint ##
Cary Clark80247e52018-07-11 16:18:41 -04003478Draws Region region using Clip, Matrix, and Paint paint.
Herb Derbyefe39bc2018-05-01 17:06:20 -04003479In paint: Paint_Style determines if rectangle is stroked or filled;
Cary Clark8032b982017-07-28 11:04:54 -04003480if stroked, Paint_Stroke_Width describes the line thickness, and
3481Paint_Stroke_Join draws the corners rounded or square.
3482
Cary Clarkbc5697d2017-10-04 14:31:33 -04003483#Param region region to draw ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003484#Param paint Paint stroke or fill, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003485
3486#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003487void draw(SkCanvas* canvas) {
3488 SkRegion region;
3489 region.op( 10, 10, 50, 50, SkRegion::kUnion_Op);
3490 region.op( 10, 50, 90, 90, SkRegion::kUnion_Op);
3491 SkPaint paint;
3492 paint.setAntiAlias(true);
3493 paint.setStyle(SkPaint::kStroke_Style);
3494 paint.setStrokeWidth(20);
3495 paint.setStrokeJoin(SkPaint::kRound_Join);
3496 canvas->drawRegion(region, paint);
Cary Clark8032b982017-07-28 11:04:54 -04003497}
3498##
3499
Cary Clark2ade9972017-11-02 17:49:34 -04003500#SeeAlso drawRect drawIRect drawPath
Cary Clark8032b982017-07-28 11:04:54 -04003501
3502##
3503
3504# ------------------------------------------------------------------------------
3505
3506#Method void drawOval(const SkRect& oval, const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05003507#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05003508#Line # draws Oval using Clip, Matrix, and Paint ##
Cary Clark80247e52018-07-11 16:18:41 -04003509Draws Oval oval using Clip, Matrix, and Paint.
Herb Derbyefe39bc2018-05-01 17:06:20 -04003510In paint: Paint_Style determines if Oval is stroked or filled;
Cary Clark8032b982017-07-28 11:04:54 -04003511if stroked, Paint_Stroke_Width describes the line thickness.
3512
Cary Clarkbad5ad72017-08-03 17:14:08 -04003513#Param oval Rect bounds of Oval ##
3514#Param paint Paint stroke or fill, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003515
3516#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003517void draw(SkCanvas* canvas) {
3518 canvas->clear(0xFF3f5f9f);
3519 SkColor kColor1 = SkColorSetARGB(0xff, 0xff, 0x7f, 0);
3520 SkColor g1Colors[] = { kColor1, SkColorSetA(kColor1, 0x20) };
3521 SkPoint g1Points[] = { { 0, 0 }, { 0, 100 } };
3522 SkScalar pos[] = { 0.2f, 1.0f };
3523 SkRect bounds = SkRect::MakeWH(80, 70);
3524 SkPaint paint;
3525 paint.setAntiAlias(true);
3526 paint.setShader(SkGradientShader::MakeLinear(g1Points, g1Colors, pos, SK_ARRAY_COUNT(g1Colors),
3527 SkShader::kClamp_TileMode));
3528 canvas->drawOval(bounds , paint);
Cary Clark8032b982017-07-28 11:04:54 -04003529}
3530##
3531
Cary Clark2ade9972017-11-02 17:49:34 -04003532#SeeAlso drawCircle drawPoint drawPath drawRRect drawRoundRect
Cary Clark8032b982017-07-28 11:04:54 -04003533
3534##
3535
3536# ------------------------------------------------------------------------------
3537
3538#Method void drawRRect(const SkRRect& rrect, const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05003539#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05003540#Line # draws Round_Rect using Clip, Matrix, and Paint ##
Cary Clark80247e52018-07-11 16:18:41 -04003541Draws Round_Rect rrect using Clip, Matrix, and Paint paint.
Herb Derbyefe39bc2018-05-01 17:06:20 -04003542In paint: Paint_Style determines if rrect is stroked or filled;
Cary Clark8032b982017-07-28 11:04:54 -04003543if stroked, Paint_Stroke_Width describes the line thickness.
3544
Cary Clarkbad5ad72017-08-03 17:14:08 -04003545rrect may represent a rectangle, circle, oval, uniformly rounded rectangle, or
3546may have any combination of positive non-square radii for the four corners.
Cary Clark8032b982017-07-28 11:04:54 -04003547
Cary Clarkbad5ad72017-08-03 17:14:08 -04003548#Param rrect Round_Rect with up to eight corner radii to draw ##
3549#Param paint Paint stroke or fill, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003550
3551#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003552void draw(SkCanvas* canvas) {
3553 SkPaint paint;
3554 paint.setAntiAlias(true);
3555 SkRect outer = {30, 40, 210, 220};
3556 SkRect radii = {30, 50, 70, 90 };
3557 SkRRect rRect;
3558 rRect.setNinePatch(outer, radii.fLeft, radii.fTop, radii.fRight, radii.fBottom);
3559 canvas->drawRRect(rRect, paint);
3560 paint.setColor(SK_ColorWHITE);
3561 canvas->drawLine(outer.fLeft + radii.fLeft, outer.fTop,
3562 outer.fLeft + radii.fLeft, outer.fBottom, paint);
Herb Derbyefe39bc2018-05-01 17:06:20 -04003563 canvas->drawLine(outer.fRight - radii.fRight, outer.fTop,
Cary Clarkbad5ad72017-08-03 17:14:08 -04003564 outer.fRight - radii.fRight, outer.fBottom, paint);
Herb Derbyefe39bc2018-05-01 17:06:20 -04003565 canvas->drawLine(outer.fLeft, outer.fTop + radii.fTop,
Cary Clarkbad5ad72017-08-03 17:14:08 -04003566 outer.fRight, outer.fTop + radii.fTop, paint);
Herb Derbyefe39bc2018-05-01 17:06:20 -04003567 canvas->drawLine(outer.fLeft, outer.fBottom - radii.fBottom,
Cary Clarkbad5ad72017-08-03 17:14:08 -04003568 outer.fRight, outer.fBottom - radii.fBottom, paint);
3569}
Cary Clark8032b982017-07-28 11:04:54 -04003570##
3571
Cary Clark2ade9972017-11-02 17:49:34 -04003572#SeeAlso drawRect drawRoundRect drawDRRect drawCircle drawOval drawPath
Cary Clark8032b982017-07-28 11:04:54 -04003573
3574##
3575
3576# ------------------------------------------------------------------------------
3577
3578#Method void drawDRRect(const SkRRect& outer, const SkRRect& inner, const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05003579#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05003580#Line # draws double Round_Rect stroked or filled ##
Cary Clark80247e52018-07-11 16:18:41 -04003581Draws Round_Rect outer and inner
Herb Derbyefe39bc2018-05-01 17:06:20 -04003582using Clip, Matrix, and Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04003583outer must contain inner or the drawing is undefined.
Herb Derbyefe39bc2018-05-01 17:06:20 -04003584In paint: Paint_Style determines if Round_Rect is stroked or filled;
Cary Clark8032b982017-07-28 11:04:54 -04003585if stroked, Paint_Stroke_Width describes the line thickness.
Cary Clarkbad5ad72017-08-03 17:14:08 -04003586If stroked and Round_Rect corner has zero length radii, Paint_Stroke_Join can
Herb Derbyefe39bc2018-05-01 17:06:20 -04003587draw corners rounded or square.
Cary Clark8032b982017-07-28 11:04:54 -04003588
Cary Clarkbad5ad72017-08-03 17:14:08 -04003589GPU-backed platforms optimize drawing when both outer and inner are
Cary Clark8032b982017-07-28 11:04:54 -04003590concave and outer contains inner. These platforms may not be able to draw
Herb Derbyefe39bc2018-05-01 17:06:20 -04003591Path built with identical data as fast.
Cary Clark8032b982017-07-28 11:04:54 -04003592
Cary Clarkbad5ad72017-08-03 17:14:08 -04003593#Param outer Round_Rect outer bounds to draw ##
3594#Param inner Round_Rect inner bounds to draw ##
3595#Param paint Paint stroke or fill, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003596
3597#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003598void draw(SkCanvas* canvas) {
3599 SkRRect outer = SkRRect::MakeRect({20, 40, 210, 200});
3600 SkRRect inner = SkRRect::MakeOval({60, 70, 170, 160});
3601 SkPaint paint;
3602 canvas->drawDRRect(outer, inner, paint);
Cary Clark8032b982017-07-28 11:04:54 -04003603}
3604##
3605
3606#Example
3607#Description
3608 Outer Rect has no corner radii, but stroke join is rounded.
3609 Inner Round_Rect has corner radii; outset stroke increases radii of corners.
3610 Stroke join does not affect inner Round_Rect since it has no sharp corners.
3611##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003612void draw(SkCanvas* canvas) {
3613 SkRRect outer = SkRRect::MakeRect({20, 40, 210, 200});
3614 SkRRect inner = SkRRect::MakeRectXY({60, 70, 170, 160}, 10, 10);
3615 SkPaint paint;
3616 paint.setAntiAlias(true);
3617 paint.setStyle(SkPaint::kStroke_Style);
3618 paint.setStrokeWidth(20);
3619 paint.setStrokeJoin(SkPaint::kRound_Join);
3620 canvas->drawDRRect(outer, inner, paint);
3621 paint.setStrokeWidth(1);
3622 paint.setColor(SK_ColorWHITE);
3623 canvas->drawDRRect(outer, inner, paint);
Cary Clark8032b982017-07-28 11:04:54 -04003624}
3625##
3626
Cary Clark2ade9972017-11-02 17:49:34 -04003627#SeeAlso drawRect drawRoundRect drawRRect drawCircle drawOval drawPath
Cary Clark8032b982017-07-28 11:04:54 -04003628
3629##
3630
3631# ------------------------------------------------------------------------------
3632
3633#Method void drawCircle(SkScalar cx, SkScalar cy, SkScalar radius, const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05003634#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05003635#Line # draws Circle using Clip, Matrix, and Paint ##
Cary Clark80247e52018-07-11 16:18:41 -04003636Draws Circle at (cx, cy) with radius using Clip, Matrix, and Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04003637If radius is zero or less, nothing is drawn.
Herb Derbyefe39bc2018-05-01 17:06:20 -04003638In paint: Paint_Style determines if Circle is stroked or filled;
Cary Clark8032b982017-07-28 11:04:54 -04003639if stroked, Paint_Stroke_Width describes the line thickness.
3640
Cary Clarkbad5ad72017-08-03 17:14:08 -04003641#Param cx Circle center on the x-axis ##
3642#Param cy Circle center on the y-axis ##
3643#Param radius half the diameter of Circle ##
3644#Param paint Paint stroke or fill, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003645
3646#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003647 void draw(SkCanvas* canvas) {
3648 SkPaint paint;
3649 paint.setAntiAlias(true);
3650 canvas->drawCircle(128, 128, 90, paint);
3651 paint.setColor(SK_ColorWHITE);
3652 canvas->drawCircle(86, 86, 20, paint);
3653 canvas->drawCircle(160, 76, 20, paint);
3654 canvas->drawCircle(140, 150, 35, paint);
3655 }
3656##
3657
Cary Clark2ade9972017-11-02 17:49:34 -04003658#SeeAlso drawOval drawRRect drawRoundRect drawPath drawArc drawPoint drawLine
Cary Clarkbad5ad72017-08-03 17:14:08 -04003659
3660##
3661
3662#Method void drawCircle(SkPoint center, SkScalar radius, const SkPaint& paint)
3663
Cary Clark80247e52018-07-11 16:18:41 -04003664Draws Circle at center with radius using Clip, Matrix, and Paint paint.
Cary Clarkbad5ad72017-08-03 17:14:08 -04003665If radius is zero or less, nothing is drawn.
Herb Derbyefe39bc2018-05-01 17:06:20 -04003666In paint: Paint_Style determines if Circle is stroked or filled;
Cary Clarkbad5ad72017-08-03 17:14:08 -04003667if stroked, Paint_Stroke_Width describes the line thickness.
3668
3669#Param center Circle center ##
3670#Param radius half the diameter of Circle ##
3671#Param paint Paint stroke or fill, blend, color, and so on, used to draw ##
3672
3673#Example
3674 void draw(SkCanvas* canvas) {
3675 SkPaint paint;
3676 paint.setAntiAlias(true);
3677 canvas->drawCircle(128, 128, 90, paint);
3678 paint.setColor(SK_ColorWHITE);
3679 canvas->drawCircle({86, 86}, 20, paint);
3680 canvas->drawCircle({160, 76}, 20, paint);
3681 canvas->drawCircle({140, 150}, 35, paint);
3682 }
Cary Clark8032b982017-07-28 11:04:54 -04003683##
3684
Cary Clark2ade9972017-11-02 17:49:34 -04003685#SeeAlso drawOval drawRRect drawRoundRect drawPath drawArc drawPoint drawLine
Cary Clark8032b982017-07-28 11:04:54 -04003686
3687##
3688
3689# ------------------------------------------------------------------------------
3690
3691#Method void drawArc(const SkRect& oval, SkScalar startAngle, SkScalar sweepAngle,
3692 bool useCenter, const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05003693#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05003694#Line # draws Arc using Clip, Matrix, and Paint ##
Cary Clark8032b982017-07-28 11:04:54 -04003695
Cary Clark80247e52018-07-11 16:18:41 -04003696Draws Arc using Clip, Matrix, and Paint paint.
Cary Clarkbad5ad72017-08-03 17:14:08 -04003697
Cary Clark8032b982017-07-28 11:04:54 -04003698Arc is part of Oval bounded by oval, sweeping from startAngle to startAngle plus
3699sweepAngle. startAngle and sweepAngle are in degrees.
Cary Clarkbad5ad72017-08-03 17:14:08 -04003700
Cary Clark8032b982017-07-28 11:04:54 -04003701startAngle of zero places start point at the right middle edge of oval.
3702A positive sweepAngle places Arc end point clockwise from start point;
3703a negative sweepAngle places Arc end point counterclockwise from start point.
3704sweepAngle may exceed 360 degrees, a full circle.
3705If useCenter is true, draw a wedge that includes lines from oval
3706center to Arc end points. If useCenter is false, draw Arc between end points.
3707
3708If Rect oval is empty or sweepAngle is zero, nothing is drawn.
3709
Cary Clarkbad5ad72017-08-03 17:14:08 -04003710#Param oval Rect bounds of Oval containing Arc to draw ##
3711#Param startAngle angle in degrees where Arc begins ##
3712#Param sweepAngle sweep angle in degrees; positive is clockwise ##
3713#Param useCenter if true, include the center of the oval ##
3714#Param paint Paint stroke or fill, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003715
3716#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003717 void draw(SkCanvas* canvas) {
3718 SkPaint paint;
3719 paint.setAntiAlias(true);
3720 SkRect oval = { 4, 4, 60, 60};
3721 for (auto useCenter : { false, true } ) {
3722 for (auto style : { SkPaint::kFill_Style, SkPaint::kStroke_Style } ) {
3723 paint.setStyle(style);
3724 for (auto degrees : { 45, 90, 180, 360} ) {
3725 canvas->drawArc(oval, 0, degrees , useCenter, paint);
3726 canvas->translate(64, 0);
3727 }
3728 canvas->translate(-256, 64);
3729 }
3730 }
Cary Clark8032b982017-07-28 11:04:54 -04003731 }
3732##
3733
3734#Example
3735#Height 64
Cary Clarkbad5ad72017-08-03 17:14:08 -04003736 void draw(SkCanvas* canvas) {
3737 SkPaint paint;
3738 paint.setAntiAlias(true);
3739 paint.setStyle(SkPaint::kStroke_Style);
3740 paint.setStrokeWidth(4);
3741 SkRect oval = { 4, 4, 60, 60};
3742 float intervals[] = { 5, 5 };
3743 paint.setPathEffect(SkDashPathEffect::Make(intervals, 2, 2.5f));
3744 for (auto degrees : { 270, 360, 540, 720 } ) {
3745 canvas->drawArc(oval, 0, degrees, false, paint);
3746 canvas->translate(64, 0);
3747 }
Cary Clark8032b982017-07-28 11:04:54 -04003748 }
3749##
3750
Cary Clark2ade9972017-11-02 17:49:34 -04003751#SeeAlso SkPath::arcTo drawCircle drawOval drawPath
Cary Clark8032b982017-07-28 11:04:54 -04003752
3753##
3754
3755# ------------------------------------------------------------------------------
3756
3757#Method void drawRoundRect(const SkRect& rect, SkScalar rx, SkScalar ry, const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05003758#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05003759#Line # draws Round_Rect using Clip, Matrix, and Paint ##
Cary Clark80247e52018-07-11 16:18:41 -04003760Draws Round_Rect bounded by Rect rect, with corner radii (rx, ry) using Clip,
Cary Clarkbad5ad72017-08-03 17:14:08 -04003761Matrix, and Paint paint.
3762
Herb Derbyefe39bc2018-05-01 17:06:20 -04003763In paint: Paint_Style determines if Round_Rect is stroked or filled;
Cary Clark8032b982017-07-28 11:04:54 -04003764if stroked, Paint_Stroke_Width describes the line thickness.
3765If rx or ry are less than zero, they are treated as if they are zero.
3766If rx plus ry exceeds rect width or rect height, radii are scaled down to fit.
Cary Clarkbad5ad72017-08-03 17:14:08 -04003767If rx and ry are zero, Round_Rect is drawn as Rect and if stroked is affected by
3768Paint_Stroke_Join.
Cary Clark8032b982017-07-28 11:04:54 -04003769
Cary Clarkbad5ad72017-08-03 17:14:08 -04003770#Param rect Rect bounds of Round_Rect to draw ##
Cary Clark5538c132018-06-14 12:28:14 -04003771#Param rx axis length on x-axis of oval describing rounded corners ##
3772#Param ry axis length on y-axis of oval describing rounded corners ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003773#Param paint stroke, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003774
3775#Example
3776#Description
3777 Top row has a zero radius a generates a rectangle.
3778 Second row radii sum to less than sides.
3779 Third row radii sum equals sides.
3780 Fourth row radii sum exceeds sides; radii are scaled to fit.
3781##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003782 void draw(SkCanvas* canvas) {
3783 SkVector radii[] = { {0, 20}, {10, 10}, {10, 20}, {10, 40} };
3784 SkPaint paint;
3785 paint.setStrokeWidth(15);
3786 paint.setStrokeJoin(SkPaint::kRound_Join);
3787 paint.setAntiAlias(true);
3788 for (auto style : { SkPaint::kStroke_Style, SkPaint::kFill_Style } ) {
3789 paint.setStyle(style );
3790 for (size_t i = 0; i < SK_ARRAY_COUNT(radii); ++i) {
3791 canvas->drawRoundRect({10, 10, 60, 40}, radii[i].fX, radii[i].fY, paint);
3792 canvas->translate(0, 60);
3793 }
3794 canvas->translate(80, -240);
3795 }
Cary Clark8032b982017-07-28 11:04:54 -04003796 }
3797##
3798
Cary Clark2ade9972017-11-02 17:49:34 -04003799#SeeAlso DrawRRect drawRect drawDRRect drawPath drawCircle drawOval drawPoint
Cary Clark8032b982017-07-28 11:04:54 -04003800
3801##
3802
3803# ------------------------------------------------------------------------------
3804
3805#Method void drawPath(const SkPath& path, const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05003806#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05003807#Line # draws Path using Clip, Matrix, and Paint ##
Cary Clark80247e52018-07-11 16:18:41 -04003808Draws Path path using Clip, Matrix, and Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04003809Path contains an array of Path_Contour, each of which may be open or closed.
3810
3811In paint: Paint_Style determines if Round_Rect is stroked or filled:
Cary Clarkbad5ad72017-08-03 17:14:08 -04003812if filled, Path_Fill_Type determines whether Path_Contour describes inside or
3813outside of fill; if stroked, Paint_Stroke_Width describes the line thickness,
3814Paint_Stroke_Cap describes line ends, and Paint_Stroke_Join describes how
3815corners are drawn.
Cary Clark8032b982017-07-28 11:04:54 -04003816
Cary Clarkbad5ad72017-08-03 17:14:08 -04003817#Param path Path to draw ##
3818#Param paint stroke, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003819
3820#Example
3821#Description
3822 Top rows draw stroked path with combinations of joins and caps. The open contour
3823 is affected by caps; the closed contour is affected by joins.
Herb Derbyefe39bc2018-05-01 17:06:20 -04003824 Bottom row draws fill the same for open and closed contour.
Cary Clark8032b982017-07-28 11:04:54 -04003825 First bottom column shows winding fills overlap.
3826 Second bottom column shows even odd fills exclude overlap.
3827 Third bottom column shows inverse winding fills area outside both contours.
3828##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003829void draw(SkCanvas* canvas) {
3830 SkPath path;
3831 path.moveTo(20, 20);
3832 path.quadTo(60, 20, 60, 60);
3833 path.close();
3834 path.moveTo(60, 20);
3835 path.quadTo(60, 60, 20, 60);
3836 SkPaint paint;
3837 paint.setStrokeWidth(10);
3838 paint.setAntiAlias(true);
3839 paint.setStyle(SkPaint::kStroke_Style);
3840 for (auto join: { SkPaint::kBevel_Join, SkPaint::kRound_Join, SkPaint::kMiter_Join } ) {
3841 paint.setStrokeJoin(join);
3842 for (auto cap: { SkPaint::kButt_Cap, SkPaint::kSquare_Cap, SkPaint::kRound_Cap } ) {
3843 paint.setStrokeCap(cap);
3844 canvas->drawPath(path, paint);
3845 canvas->translate(80, 0);
3846 }
3847 canvas->translate(-240, 60);
3848 }
3849 paint.setStyle(SkPaint::kFill_Style);
Herb Derbyefe39bc2018-05-01 17:06:20 -04003850 for (auto fill : { SkPath::kWinding_FillType,
3851 SkPath::kEvenOdd_FillType,
Cary Clarkbad5ad72017-08-03 17:14:08 -04003852 SkPath::kInverseWinding_FillType } ) {
3853 path.setFillType(fill);
3854 canvas->save();
3855 canvas->clipRect({0, 10, 80, 70});
3856 canvas->drawPath(path, paint);
3857 canvas->restore();
3858 canvas->translate(80, 0);
3859 }
Cary Clark8032b982017-07-28 11:04:54 -04003860}
3861##
3862
Cary Clark2ade9972017-11-02 17:49:34 -04003863#SeeAlso SkPath drawLine drawArc drawRect drawPoints
Cary Clark8032b982017-07-28 11:04:54 -04003864
3865##
3866
3867# ------------------------------------------------------------------------------
Cary Clark08895c42018-02-01 09:37:32 -05003868#Subtopic Draw_Image
3869#Line # draws Image to Canvas ##
Cary Clark8032b982017-07-28 11:04:54 -04003870
Cary Clarkbad5ad72017-08-03 17:14:08 -04003871drawImage, drawImageRect, and drawImageNine can be called with a bare pointer or
3872a smart pointer as a convenience. The pairs of calls are otherwise identical.
Cary Clark8032b982017-07-28 11:04:54 -04003873
Cary Clark73fa9722017-08-29 17:36:51 -04003874#Method void drawImage(const SkImage* image, SkScalar left, SkScalar top, const SkPaint* paint = nullptr)
Cary Clarkab2621d2018-01-30 10:08:57 -05003875#In Draw_Image
Cary Clark78de7512018-02-07 07:27:09 -05003876#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05003877#Line # draws Image at (x, y) position ##
Cary Clark80247e52018-07-11 16:18:41 -04003878Draws Image image, with its top-left corner at (left, top),
Cary Clark8032b982017-07-28 11:04:54 -04003879using Clip, Matrix, and optional Paint paint.
3880
Cary Clarkbad5ad72017-08-03 17:14:08 -04003881If paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter, Blend_Mode,
3882and Draw_Looper. If image is kAlpha_8_SkColorType, apply Shader.
3883If paint contains Mask_Filter, generate mask from image bounds. If generated
3884mask extends beyond image bounds, replicate image edge colors, just as Shader
3885made from SkImage::makeShader with SkShader::kClamp_TileMode set replicates the
Herb Derbyefe39bc2018-05-01 17:06:20 -04003886image edge color when it samples outside of its bounds.
Cary Clark8032b982017-07-28 11:04:54 -04003887
Cary Clarkbad5ad72017-08-03 17:14:08 -04003888#Param image uncompressed rectangular map of pixels ##
3889#Param left left side of image ##
3890#Param top top side of image ##
3891#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
3892 and so on; or nullptr
3893##
Cary Clark8032b982017-07-28 11:04:54 -04003894
3895#Example
3896#Height 64
3897#Image 4
Cary Clarkbad5ad72017-08-03 17:14:08 -04003898void draw(SkCanvas* canvas) {
3899 // sk_sp<SkImage> image;
3900 SkImage* imagePtr = image.get();
3901 canvas->drawImage(imagePtr, 0, 0);
3902 SkPaint paint;
3903 canvas->drawImage(imagePtr, 80, 0, &paint);
3904 paint.setAlpha(0x80);
3905 canvas->drawImage(imagePtr, 160, 0, &paint);
Cary Clark8032b982017-07-28 11:04:54 -04003906}
3907##
3908
Cary Clark2ade9972017-11-02 17:49:34 -04003909#SeeAlso drawBitmap drawImageLattice drawImageNine drawImageRect SkPaint::setImageFilter
Cary Clark8032b982017-07-28 11:04:54 -04003910
3911##
3912
3913# ------------------------------------------------------------------------------
3914
3915#Method void drawImage(const sk_sp<SkImage>& image, SkScalar left, SkScalar top,
Herb Derbyefe39bc2018-05-01 17:06:20 -04003916 const SkPaint* paint = nullptr)
Cary Clark8032b982017-07-28 11:04:54 -04003917
Cary Clark80247e52018-07-11 16:18:41 -04003918Draws Image image, with its top-left corner at (left, top),
Cary Clark8032b982017-07-28 11:04:54 -04003919using Clip, Matrix, and optional Paint paint.
3920
Cary Clarkbad5ad72017-08-03 17:14:08 -04003921If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
3922Blend_Mode, and Draw_Looper. If image is kAlpha_8_SkColorType, apply Shader.
3923If paint contains Mask_Filter, generate mask from image bounds. If generated
3924mask extends beyond image bounds, replicate image edge colors, just as Shader
3925made from SkImage::makeShader with SkShader::kClamp_TileMode set replicates the
Herb Derbyefe39bc2018-05-01 17:06:20 -04003926image edge color when it samples outside of its bounds.
Cary Clark8032b982017-07-28 11:04:54 -04003927
Cary Clarkbad5ad72017-08-03 17:14:08 -04003928#Param image uncompressed rectangular map of pixels ##
3929#Param left left side of image ##
3930#Param top pop side of image ##
3931#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
3932 and so on; or nullptr
3933##
Cary Clark8032b982017-07-28 11:04:54 -04003934
3935#Example
3936#Height 64
3937#Image 4
Cary Clarkbad5ad72017-08-03 17:14:08 -04003938void draw(SkCanvas* canvas) {
3939 // sk_sp<SkImage> image;
3940 canvas->drawImage(image, 0, 0);
3941 SkPaint paint;
3942 canvas->drawImage(image, 80, 0, &paint);
3943 paint.setAlpha(0x80);
3944 canvas->drawImage(image, 160, 0, &paint);
Cary Clark8032b982017-07-28 11:04:54 -04003945}
3946##
3947
Cary Clark2ade9972017-11-02 17:49:34 -04003948#SeeAlso drawBitmap drawImageLattice drawImageNine drawImageRect SkPaint::setImageFilter
Cary Clark8032b982017-07-28 11:04:54 -04003949
3950##
3951
3952# ------------------------------------------------------------------------------
3953
3954#Enum SrcRectConstraint
Cary Clark08895c42018-02-01 09:37:32 -05003955#Line # sets drawImageRect options ##
Cary Clark8032b982017-07-28 11:04:54 -04003956
3957#Code
3958 enum SrcRectConstraint {
Herb Derbyefe39bc2018-05-01 17:06:20 -04003959 kStrict_SrcRectConstraint,
3960 kFast_SrcRectConstraint,
Cary Clark8032b982017-07-28 11:04:54 -04003961 };
3962##
3963
Cary Clarkce101242017-09-01 15:51:02 -04003964SrcRectConstraint controls the behavior at the edge of source Rect,
3965provided to drawImageRect, trading off speed for precision.
Cary Clark8032b982017-07-28 11:04:54 -04003966
Cary Clarkce101242017-09-01 15:51:02 -04003967Image_Filter in Paint may sample multiple pixels in the image. Source Rect
Cary Clarkbad5ad72017-08-03 17:14:08 -04003968restricts the bounds of pixels that may be read. Image_Filter may slow down if
Herb Derbyefe39bc2018-05-01 17:06:20 -04003969it cannot read outside the bounds, when sampling near the edge of source Rect.
Cary Clark8032b982017-07-28 11:04:54 -04003970SrcRectConstraint specifies whether an Image_Filter is allowed to read pixels
Cary Clarkce101242017-09-01 15:51:02 -04003971outside source Rect.
Cary Clark8032b982017-07-28 11:04:54 -04003972
Cary Clark682c58d2018-05-16 07:07:07 -04003973#Const kStrict_SrcRectConstraint 0
3974#Line # sample only inside bounds; slower ##
Cary Clarkce101242017-09-01 15:51:02 -04003975 Requires Image_Filter to respect source Rect,
Cary Clark8032b982017-07-28 11:04:54 -04003976 sampling only inside of its bounds, possibly with a performance penalty.
3977##
3978
Cary Clark682c58d2018-05-16 07:07:07 -04003979#Const kFast_SrcRectConstraint 1
3980#Line # sample outside bounds; faster ##
Cary Clarkce101242017-09-01 15:51:02 -04003981 Permits Image_Filter to sample outside of source Rect
Cary Clark8032b982017-07-28 11:04:54 -04003982 by half the width of Image_Filter, permitting it to run faster but with
3983 error at the image edges.
3984##
3985
3986#Example
3987#Height 64
3988#Description
3989 redBorder contains a black and white checkerboard bordered by red.
3990 redBorder is drawn scaled by 16 on the left.
Cary Clarkce101242017-09-01 15:51:02 -04003991 The middle and right bitmaps are filtered checkerboards.
Cary Clark8032b982017-07-28 11:04:54 -04003992 Drawing the checkerboard with kStrict_SrcRectConstraint shows only a blur of black and white.
3993 Drawing the checkerboard with kFast_SrcRectConstraint allows red to bleed in the corners.
3994##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003995void draw(SkCanvas* canvas) {
3996 SkBitmap redBorder;
3997 redBorder.allocPixels(SkImageInfo::MakeN32Premul(4, 4));
3998 SkCanvas checkRed(redBorder);
3999 checkRed.clear(SK_ColorRED);
4000 uint32_t checkers[][2] = { { SK_ColorBLACK, SK_ColorWHITE },
4001 { SK_ColorWHITE, SK_ColorBLACK } };
4002 checkRed.writePixels(
4003 SkImageInfo::MakeN32Premul(2, 2), (void*) checkers, sizeof(checkers[0]), 1, 1);
4004 canvas->scale(16, 16);
4005 canvas->drawBitmap(redBorder, 0, 0, nullptr);
4006 canvas->resetMatrix();
4007 sk_sp<SkImage> image = SkImage::MakeFromBitmap(redBorder);
4008 SkPaint lowPaint;
4009 lowPaint.setFilterQuality(kLow_SkFilterQuality);
4010 for (auto constraint : { SkCanvas::kStrict_SrcRectConstraint,
4011 SkCanvas::kFast_SrcRectConstraint } ) {
4012 canvas->translate(80, 0);
4013 canvas->drawImageRect(image.get(), SkRect::MakeLTRB(1, 1, 3, 3),
4014 SkRect::MakeLTRB(16, 16, 48, 48), &lowPaint, constraint);
4015 }
Cary Clark8032b982017-07-28 11:04:54 -04004016}
4017##
4018
Cary Clark2ade9972017-11-02 17:49:34 -04004019#SeeAlso drawImageRect drawImage SkPaint::setImageFilter
Cary Clark8032b982017-07-28 11:04:54 -04004020
4021##
4022
4023# ------------------------------------------------------------------------------
4024
4025#Method void drawImageRect(const SkImage* image, const SkRect& src, const SkRect& dst,
4026 const SkPaint* paint,
4027 SrcRectConstraint constraint = kStrict_SrcRectConstraint)
Cary Clarkab2621d2018-01-30 10:08:57 -05004028#In Draw_Image
Cary Clark78de7512018-02-07 07:27:09 -05004029#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05004030#Line # draws Image, source Rect to destination Rect ##
Cary Clark8032b982017-07-28 11:04:54 -04004031
Cary Clark80247e52018-07-11 16:18:41 -04004032Draws Rect src of Image image, scaled and translated to fill Rect dst.
Cary Clark8032b982017-07-28 11:04:54 -04004033Additionally transform draw using Clip, Matrix, and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004034
Cary Clarkbad5ad72017-08-03 17:14:08 -04004035If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4036Blend_Mode, and Draw_Looper. If image is kAlpha_8_SkColorType, apply Shader.
4037If paint contains Mask_Filter, generate mask from image bounds.
4038
4039If generated mask extends beyond image bounds, replicate image edge colors, just
4040as Shader made from SkImage::makeShader with SkShader::kClamp_TileMode set
Cary Clarkbc5697d2017-10-04 14:31:33 -04004041replicates the image edge color when it samples outside of its bounds.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004042
4043constraint set to kStrict_SrcRectConstraint limits Paint Filter_Quality to
4044sample within src; set to kFast_SrcRectConstraint allows sampling outside to
4045improve performance.
4046
4047#Param image Image containing pixels, dimensions, and format ##
4048#Param src source Rect of image to draw from ##
4049#Param dst destination Rect of image to draw to ##
4050#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4051 and so on; or nullptr
4052##
4053#Param constraint filter strictly within src or draw faster ##
Cary Clark8032b982017-07-28 11:04:54 -04004054
4055#Example
4056#Height 64
4057#Description
4058 The left bitmap draws with Paint default kNone_SkFilterQuality, and stays within
Cary Clarkbc5697d2017-10-04 14:31:33 -04004059 its bounds; there is no bleeding with kFast_SrcRectConstraint.
Cary Clark8032b982017-07-28 11:04:54 -04004060 the middle and right bitmaps draw with kLow_SkFilterQuality; with
4061 kStrict_SrcRectConstraint, the filter remains within the checkerboard, and
4062 with kFast_SrcRectConstraint red bleeds on the edges.
4063##
Cary Clarkbad5ad72017-08-03 17:14:08 -04004064void draw(SkCanvas* canvas) {
Herb Derbyefe39bc2018-05-01 17:06:20 -04004065 uint32_t pixels[][4] = {
Cary Clarkbad5ad72017-08-03 17:14:08 -04004066 { 0xFFFF0000, 0xFFFF0000, 0xFFFF0000, 0xFFFF0000 },
4067 { 0xFFFF0000, 0xFF000000, 0xFFFFFFFF, 0xFFFF0000 },
4068 { 0xFFFF0000, 0xFFFFFFFF, 0xFF000000, 0xFFFF0000 },
4069 { 0xFFFF0000, 0xFFFF0000, 0xFFFF0000, 0xFFFF0000 } };
4070 SkBitmap redBorder;
Herb Derbyefe39bc2018-05-01 17:06:20 -04004071 redBorder.installPixels(SkImageInfo::MakeN32Premul(4, 4),
Cary Clarkbad5ad72017-08-03 17:14:08 -04004072 (void*) pixels, sizeof(pixels[0]));
4073 sk_sp<SkImage> image = SkImage::MakeFromBitmap(redBorder);
4074 SkPaint lowPaint;
4075 for (auto constraint : {
4076 SkCanvas::kFast_SrcRectConstraint,
4077 SkCanvas::kStrict_SrcRectConstraint,
4078 SkCanvas::kFast_SrcRectConstraint } ) {
4079 canvas->drawImageRect(image.get(), SkRect::MakeLTRB(1, 1, 3, 3),
4080 SkRect::MakeLTRB(16, 16, 48, 48), &lowPaint, constraint);
4081 lowPaint.setFilterQuality(kLow_SkFilterQuality);
4082 canvas->translate(80, 0);
4083 }
4084}
Cary Clark8032b982017-07-28 11:04:54 -04004085##
4086
Cary Clark2ade9972017-11-02 17:49:34 -04004087#SeeAlso SrcRectConstraint drawImage drawImageLattice drawImageNine
Cary Clark8032b982017-07-28 11:04:54 -04004088
4089##
4090
4091# ------------------------------------------------------------------------------
4092
4093#Method void drawImageRect(const SkImage* image, const SkIRect& isrc, const SkRect& dst,
4094 const SkPaint* paint, SrcRectConstraint constraint = kStrict_SrcRectConstraint)
Cary Clarkab2621d2018-01-30 10:08:57 -05004095#In Draw_Image
Cary Clark78de7512018-02-07 07:27:09 -05004096#In Draw
Cary Clark8032b982017-07-28 11:04:54 -04004097
Cary Clark80247e52018-07-11 16:18:41 -04004098Draws IRect isrc of Image image, scaled and translated to fill Rect dst.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004099Note that isrc is on integer pixel boundaries; dst may include fractional
4100boundaries. Additionally transform draw using Clip, Matrix, and optional Paint
Herb Derbyefe39bc2018-05-01 17:06:20 -04004101paint.
Cary Clark8032b982017-07-28 11:04:54 -04004102
Cary Clarkbad5ad72017-08-03 17:14:08 -04004103If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4104Blend_Mode, and Draw_Looper. If image is kAlpha_8_SkColorType, apply Shader.
4105If paint contains Mask_Filter, generate mask from image bounds.
4106
4107If generated mask extends beyond image bounds, replicate image edge colors, just
4108as Shader made from SkImage::makeShader with SkShader::kClamp_TileMode set
Cary Clarkbc5697d2017-10-04 14:31:33 -04004109replicates the image edge color when it samples outside of its bounds.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004110
4111constraint set to kStrict_SrcRectConstraint limits Paint Filter_Quality to
Cary Clarkce101242017-09-01 15:51:02 -04004112sample within isrc; set to kFast_SrcRectConstraint allows sampling outside to
Cary Clarkbad5ad72017-08-03 17:14:08 -04004113improve performance.
4114
4115#Param image Image containing pixels, dimensions, and format ##
4116#Param isrc source IRect of image to draw from ##
4117#Param dst destination Rect of image to draw to ##
4118#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4119 and so on; or nullptr
4120##
Cary Clarkce101242017-09-01 15:51:02 -04004121#Param constraint filter strictly within isrc or draw faster ##
Cary Clark8032b982017-07-28 11:04:54 -04004122
4123#Example
4124#Image 4
Cary Clarkbad5ad72017-08-03 17:14:08 -04004125void draw(SkCanvas* canvas) {
4126 // sk_sp<SkImage> image;
4127 for (auto i : { 1, 2, 4, 8 } ) {
Herb Derbyefe39bc2018-05-01 17:06:20 -04004128 canvas->drawImageRect(image.get(), SkIRect::MakeLTRB(0, 0, 100, 100),
Cary Clarkbad5ad72017-08-03 17:14:08 -04004129 SkRect::MakeXYWH(i * 20, i * 20, i * 20, i * 20), nullptr);
4130 }
Cary Clark8032b982017-07-28 11:04:54 -04004131}
4132##
4133
Cary Clark2ade9972017-11-02 17:49:34 -04004134#SeeAlso SrcRectConstraint drawImage drawImageLattice drawImageNine
Cary Clark8032b982017-07-28 11:04:54 -04004135
4136##
4137
4138# ------------------------------------------------------------------------------
4139
4140#Method void drawImageRect(const SkImage* image, const SkRect& dst, const SkPaint* paint,
4141 SrcRectConstraint constraint = kStrict_SrcRectConstraint)
Cary Clarkab2621d2018-01-30 10:08:57 -05004142#In Draw_Image
Cary Clark78de7512018-02-07 07:27:09 -05004143#In Draw
Cary Clark8032b982017-07-28 11:04:54 -04004144
Cary Clark80247e52018-07-11 16:18:41 -04004145Draws Image image, scaled and translated to fill Rect dst, using Clip, Matrix,
Cary Clarkbad5ad72017-08-03 17:14:08 -04004146and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004147
Cary Clarkbad5ad72017-08-03 17:14:08 -04004148If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4149Blend_Mode, and Draw_Looper. If image is kAlpha_8_SkColorType, apply Shader.
4150If paint contains Mask_Filter, generate mask from image bounds.
4151
4152If generated mask extends beyond image bounds, replicate image edge colors, just
4153as Shader made from SkImage::makeShader with SkShader::kClamp_TileMode set
Cary Clarkbc5697d2017-10-04 14:31:33 -04004154replicates the image edge color when it samples outside of its bounds.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004155
4156constraint set to kStrict_SrcRectConstraint limits Paint Filter_Quality to
Cary Clarkce101242017-09-01 15:51:02 -04004157sample within image; set to kFast_SrcRectConstraint allows sampling outside to
Cary Clarkbad5ad72017-08-03 17:14:08 -04004158improve performance.
4159
4160#Param image Image containing pixels, dimensions, and format ##
4161#Param dst destination Rect of image to draw to ##
4162#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4163 and so on; or nullptr
4164##
Cary Clarkce101242017-09-01 15:51:02 -04004165#Param constraint filter strictly within image or draw faster ##
Cary Clark8032b982017-07-28 11:04:54 -04004166
4167#Example
4168#Image 4
Cary Clarkbad5ad72017-08-03 17:14:08 -04004169void draw(SkCanvas* canvas) {
4170 // sk_sp<SkImage> image;
4171 for (auto i : { 20, 40, 80, 160 } ) {
4172 canvas->drawImageRect(image.get(), SkRect::MakeXYWH(i, i, i, i), nullptr);
4173 }
Cary Clark8032b982017-07-28 11:04:54 -04004174}
4175##
4176
Cary Clark2ade9972017-11-02 17:49:34 -04004177#SeeAlso SrcRectConstraint drawImage drawImageLattice drawImageNine
Cary Clark8032b982017-07-28 11:04:54 -04004178
4179##
4180
4181# ------------------------------------------------------------------------------
4182
4183#Method void drawImageRect(const sk_sp<SkImage>& image, const SkRect& src, const SkRect& dst,
4184 const SkPaint* paint,
Herb Derbyefe39bc2018-05-01 17:06:20 -04004185 SrcRectConstraint constraint = kStrict_SrcRectConstraint)
Cary Clarkab2621d2018-01-30 10:08:57 -05004186#In Draw_Image
Cary Clark78de7512018-02-07 07:27:09 -05004187#In Draw
Cary Clark80247e52018-07-11 16:18:41 -04004188Draws Rect src of Image image, scaled and translated to fill Rect dst.
Cary Clark8032b982017-07-28 11:04:54 -04004189Additionally transform draw using Clip, Matrix, and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004190
Cary Clarkbad5ad72017-08-03 17:14:08 -04004191If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4192Blend_Mode, and Draw_Looper. If image is kAlpha_8_SkColorType, apply Shader.
4193If paint contains Mask_Filter, generate mask from image bounds.
4194
4195If generated mask extends beyond image bounds, replicate image edge colors, just
4196as Shader made from SkImage::makeShader with SkShader::kClamp_TileMode set
Cary Clarkbc5697d2017-10-04 14:31:33 -04004197replicates the image edge color when it samples outside of its bounds.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004198
4199constraint set to kStrict_SrcRectConstraint limits Paint Filter_Quality to
4200sample within src; set to kFast_SrcRectConstraint allows sampling outside to
4201improve performance.
4202
4203#Param image Image containing pixels, dimensions, and format ##
4204#Param src source Rect of image to draw from ##
4205#Param dst destination Rect of image to draw to ##
4206#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4207 and so on; or nullptr
4208##
4209#Param constraint filter strictly within src or draw faster ##
Cary Clark8032b982017-07-28 11:04:54 -04004210
4211#Example
4212#Height 64
4213#Description
4214 Canvas scales and translates; transformation from src to dst also scales.
4215 The two matrices are concatenated to create the final transformation.
4216##
Cary Clarkbad5ad72017-08-03 17:14:08 -04004217void draw(SkCanvas* canvas) {
4218 uint32_t pixels[][2] = { { SK_ColorBLACK, SK_ColorWHITE },
4219 { SK_ColorWHITE, SK_ColorBLACK } };
4220 SkBitmap bitmap;
Herb Derbyefe39bc2018-05-01 17:06:20 -04004221 bitmap.installPixels(SkImageInfo::MakeN32Premul(2, 2),
Cary Clarkbad5ad72017-08-03 17:14:08 -04004222 (void*) pixels, sizeof(pixels[0]));
4223 sk_sp<SkImage> image = SkImage::MakeFromBitmap(bitmap);
4224 SkPaint paint;
4225 canvas->scale(4, 4);
4226 for (auto alpha : { 50, 100, 150, 255 } ) {
4227 paint.setAlpha(alpha);
4228 canvas->drawImageRect(image, SkRect::MakeWH(2, 2), SkRect::MakeWH(8, 8), &paint);
4229 canvas->translate(8, 0);
4230 }
4231}
Cary Clark8032b982017-07-28 11:04:54 -04004232##
4233
Cary Clark2ade9972017-11-02 17:49:34 -04004234#SeeAlso SrcRectConstraint drawImage drawImageLattice drawImageNine
Cary Clark8032b982017-07-28 11:04:54 -04004235
4236##
4237
4238# ------------------------------------------------------------------------------
4239
4240#Method void drawImageRect(const sk_sp<SkImage>& image, const SkIRect& isrc, const SkRect& dst,
Herb Derbyefe39bc2018-05-01 17:06:20 -04004241 const SkPaint* paint, SrcRectConstraint constraint = kStrict_SrcRectConstraint)
Cary Clarkab2621d2018-01-30 10:08:57 -05004242#In Draw_Image
Cary Clark78de7512018-02-07 07:27:09 -05004243#In Draw
Cary Clark80247e52018-07-11 16:18:41 -04004244Draws IRect isrc of Image image, scaled and translated to fill Rect dst.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004245isrc is on integer pixel boundaries; dst may include fractional boundaries.
Cary Clark8032b982017-07-28 11:04:54 -04004246Additionally transform draw using Clip, Matrix, and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004247
Cary Clarkbad5ad72017-08-03 17:14:08 -04004248If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4249Blend_Mode, and Draw_Looper. If image is kAlpha_8_SkColorType, apply Shader.
4250If paint contains Mask_Filter, generate mask from image bounds.
4251
4252If generated mask extends beyond image bounds, replicate image edge colors, just
4253as Shader made from SkImage::makeShader with SkShader::kClamp_TileMode set
Cary Clarkbc5697d2017-10-04 14:31:33 -04004254replicates the image edge color when it samples outside of its bounds.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004255
4256constraint set to kStrict_SrcRectConstraint limits Paint Filter_Quality to
Cary Clarkce101242017-09-01 15:51:02 -04004257sample within image; set to kFast_SrcRectConstraint allows sampling outside to
Cary Clarkbad5ad72017-08-03 17:14:08 -04004258improve performance.
4259
4260#Param image Image containing pixels, dimensions, and format ##
4261#Param isrc source IRect of image to draw from ##
4262#Param dst destination Rect of image to draw to ##
4263#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4264 and so on; or nullptr
4265##
Cary Clarkce101242017-09-01 15:51:02 -04004266#Param constraint filter strictly within image or draw faster ##
Cary Clark8032b982017-07-28 11:04:54 -04004267
4268#Example
4269#Height 64
Cary Clarkbad5ad72017-08-03 17:14:08 -04004270void draw(SkCanvas* canvas) {
4271 uint32_t pixels[][2] = { { 0x00000000, 0x55555555},
4272 { 0xAAAAAAAA, 0xFFFFFFFF} };
4273 SkBitmap bitmap;
Herb Derbyefe39bc2018-05-01 17:06:20 -04004274 bitmap.installPixels(SkImageInfo::MakeN32Premul(2, 2),
Cary Clarkbad5ad72017-08-03 17:14:08 -04004275 (void*) pixels, sizeof(pixels[0]));
4276 sk_sp<SkImage> image = SkImage::MakeFromBitmap(bitmap);
4277 SkPaint paint;
4278 canvas->scale(4, 4);
4279 for (auto color : { SK_ColorRED, SK_ColorBLUE, SK_ColorGREEN } ) {
4280 paint.setColorFilter(SkColorFilter::MakeModeFilter(color, SkBlendMode::kPlus));
4281 canvas->drawImageRect(image, SkIRect::MakeWH(2, 2), SkRect::MakeWH(8, 8), &paint);
4282 canvas->translate(8, 0);
4283 }
Cary Clark8032b982017-07-28 11:04:54 -04004284}
4285##
4286
Cary Clark2ade9972017-11-02 17:49:34 -04004287#SeeAlso SrcRectConstraint drawImage drawImageLattice drawImageNine
4288
Cary Clark8032b982017-07-28 11:04:54 -04004289##
4290
4291# ------------------------------------------------------------------------------
4292
4293#Method void drawImageRect(const sk_sp<SkImage>& image, const SkRect& dst, const SkPaint* paint,
Herb Derbyefe39bc2018-05-01 17:06:20 -04004294 SrcRectConstraint constraint = kStrict_SrcRectConstraint)
Cary Clarkab2621d2018-01-30 10:08:57 -05004295#In Draw_Image
Cary Clark78de7512018-02-07 07:27:09 -05004296#In Draw
Cary Clark80247e52018-07-11 16:18:41 -04004297Draws Image image, scaled and translated to fill Rect dst,
Cary Clark8032b982017-07-28 11:04:54 -04004298using Clip, Matrix, and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004299
Cary Clarkbad5ad72017-08-03 17:14:08 -04004300If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4301Blend_Mode, and Draw_Looper. If image is kAlpha_8_SkColorType, apply Shader.
4302If paint contains Mask_Filter, generate mask from image bounds.
4303
4304If generated mask extends beyond image bounds, replicate image edge colors, just
4305as Shader made from SkImage::makeShader with SkShader::kClamp_TileMode set
Cary Clarkbc5697d2017-10-04 14:31:33 -04004306replicates the image edge color when it samples outside of its bounds.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004307
4308constraint set to kStrict_SrcRectConstraint limits Paint Filter_Quality to
Cary Clarkce101242017-09-01 15:51:02 -04004309sample within image; set to kFast_SrcRectConstraint allows sampling outside to
Cary Clarkbad5ad72017-08-03 17:14:08 -04004310improve performance.
4311
4312#Param image Image containing pixels, dimensions, and format ##
4313#Param dst destination Rect of image to draw to ##
4314#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4315 and so on; or nullptr
4316##
Cary Clarkce101242017-09-01 15:51:02 -04004317#Param constraint filter strictly within image or draw faster ##
Cary Clark8032b982017-07-28 11:04:54 -04004318
4319#Example
4320#Height 64
Cary Clarkbad5ad72017-08-03 17:14:08 -04004321void draw(SkCanvas* canvas) {
4322 uint32_t pixels[][2] = { { 0x00000000, 0x55550000},
4323 { 0xAAAA0000, 0xFFFF0000} };
4324 SkBitmap bitmap;
Herb Derbyefe39bc2018-05-01 17:06:20 -04004325 bitmap.installPixels(SkImageInfo::MakeN32Premul(2, 2),
Cary Clarkbad5ad72017-08-03 17:14:08 -04004326 (void*) pixels, sizeof(pixels[0]));
4327 sk_sp<SkImage> image = SkImage::MakeFromBitmap(bitmap);
4328 SkPaint paint;
4329 canvas->scale(4, 4);
4330 for (auto color : { SK_ColorRED, SK_ColorBLUE, SK_ColorGREEN } ) {
4331 paint.setColorFilter(SkColorFilter::MakeModeFilter(color, SkBlendMode::kPlus));
4332 canvas->drawImageRect(image, SkRect::MakeWH(8, 8), &paint);
4333 canvas->translate(8, 0);
4334 }
Cary Clark8032b982017-07-28 11:04:54 -04004335}
4336##
4337
Cary Clark2ade9972017-11-02 17:49:34 -04004338#SeeAlso SrcRectConstraint drawImage drawImageLattice drawImageNine
Cary Clark8032b982017-07-28 11:04:54 -04004339
4340##
4341
4342# ------------------------------------------------------------------------------
4343
4344#Method void drawImageNine(const SkImage* image, const SkIRect& center, const SkRect& dst,
4345 const SkPaint* paint = nullptr)
Cary Clarkab2621d2018-01-30 10:08:57 -05004346#In Draw_Image
Cary Clark78de7512018-02-07 07:27:09 -05004347#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05004348#Line # draws Nine_Patch Image ##
Cary Clark8032b982017-07-28 11:04:54 -04004349
Cary Clark80247e52018-07-11 16:18:41 -04004350Draws Image image stretched proportionally to fit into Rect dst.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004351IRect center divides the image into nine sections: four sides, four corners, and
Cary Clarkce101242017-09-01 15:51:02 -04004352the center. Corners are unmodified or scaled down proportionately if their sides
Cary Clarkbad5ad72017-08-03 17:14:08 -04004353are larger than dst; center and four sides are scaled to fit remaining space, if any.
Cary Clark8032b982017-07-28 11:04:54 -04004354
Cary Clarkbad5ad72017-08-03 17:14:08 -04004355Additionally transform draw using Clip, Matrix, and optional Paint paint.
4356
Cary Clark682c58d2018-05-16 07:07:07 -04004357#paint_as_used_by_draw_lattice_or_draw_nine(image)#
Cary Clarkbad5ad72017-08-03 17:14:08 -04004358
4359If generated mask extends beyond image bounds, replicate image edge colors, just
4360as Shader made from SkImage::makeShader with SkShader::kClamp_TileMode set
Cary Clarkbc5697d2017-10-04 14:31:33 -04004361replicates the image edge color when it samples outside of its bounds.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004362
4363#Param image Image containing pixels, dimensions, and format ##
4364#Param center IRect edge of image corners and sides ##
4365#Param dst destination Rect of image to draw to ##
4366#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4367 and so on; or nullptr
4368##
Cary Clark8032b982017-07-28 11:04:54 -04004369
4370#Example
4371#Height 128
4372#Description
4373 The leftmost image is smaller than center; only corners are drawn, all scaled to fit.
Cary Clarkce101242017-09-01 15:51:02 -04004374 The second image equals the size of center; only corners are drawn without scaling.
4375 The remaining images are larger than center. All corners draw without scaling.
4376 The sides and center are scaled if needed to take up the remaining space.
Cary Clark8032b982017-07-28 11:04:54 -04004377##
Cary Clarkbad5ad72017-08-03 17:14:08 -04004378void draw(SkCanvas* canvas) {
4379 SkIRect center = { 20, 10, 50, 40 };
4380 SkBitmap bitmap;
4381 bitmap.allocPixels(SkImageInfo::MakeN32Premul(60, 60));
4382 SkCanvas bitCanvas(bitmap);
4383 SkPaint paint;
4384 SkColor gray = 0xFF000000;
4385 int left = 0;
4386 for (auto right: { center.fLeft, center.fRight, bitmap.width() } ) {
4387 int top = 0;
4388 for (auto bottom: { center.fTop, center.fBottom, bitmap.height() } ) {
4389 paint.setColor(gray);
4390 bitCanvas.drawIRect(SkIRect::MakeLTRB(left, top, right, bottom), paint);
4391 gray += 0x001f1f1f;
4392 top = bottom;
4393 }
Herb Derbyefe39bc2018-05-01 17:06:20 -04004394 left = right;
Cary Clarkbad5ad72017-08-03 17:14:08 -04004395 }
4396 sk_sp<SkImage> image = SkImage::MakeFromBitmap(bitmap);
4397 SkImage* imagePtr = image.get();
4398 for (auto dest: { 20, 30, 40, 60, 90 } ) {
4399 canvas->drawImageNine(imagePtr, center, SkRect::MakeWH(dest, dest), nullptr);
4400 canvas->translate(dest + 4, 0);
4401 }
Cary Clark8032b982017-07-28 11:04:54 -04004402}
4403##
4404
Cary Clark2ade9972017-11-02 17:49:34 -04004405#SeeAlso drawImage drawBitmapNine drawImageLattice drawImageRect
Cary Clark8032b982017-07-28 11:04:54 -04004406
4407##
4408
4409# ------------------------------------------------------------------------------
4410
4411#Method void drawImageNine(const sk_sp<SkImage>& image, const SkIRect& center, const SkRect& dst,
Herb Derbyefe39bc2018-05-01 17:06:20 -04004412 const SkPaint* paint = nullptr)
Cary Clarkab2621d2018-01-30 10:08:57 -05004413#In Draw_Image
Cary Clark78de7512018-02-07 07:27:09 -05004414#In Draw
Cary Clark80247e52018-07-11 16:18:41 -04004415Draws Image image stretched proportionally to fit into Rect dst.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004416IRect center divides the image into nine sections: four sides, four corners, and
Cary Clarkce101242017-09-01 15:51:02 -04004417the center. Corners are not scaled, or scaled down proportionately if their sides
Cary Clarkbad5ad72017-08-03 17:14:08 -04004418are larger than dst; center and four sides are scaled to fit remaining space, if any.
Cary Clark8032b982017-07-28 11:04:54 -04004419
Cary Clarkbad5ad72017-08-03 17:14:08 -04004420Additionally transform draw using Clip, Matrix, and optional Paint paint.
4421
Cary Clark137b8742018-05-30 09:21:49 -04004422#paint_as_used_by_draw_lattice_or_draw_nine(image)#
Cary Clarkbad5ad72017-08-03 17:14:08 -04004423
4424If generated mask extends beyond image bounds, replicate image edge colors, just
4425as Shader made from SkImage::makeShader with SkShader::kClamp_TileMode set
Cary Clarkbc5697d2017-10-04 14:31:33 -04004426replicates the image edge color when it samples outside of its bounds.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004427
4428#Param image Image containing pixels, dimensions, and format ##
4429#Param center IRect edge of image corners and sides ##
4430#Param dst destination Rect of image to draw to ##
4431#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4432 and so on; or nullptr
4433##
Cary Clark8032b982017-07-28 11:04:54 -04004434
4435#Example
4436#Height 128
4437#Description
4438 The two leftmost images has four corners and sides to the left and right of center.
4439 The leftmost image scales the width of corners proportionately to fit.
Herb Derbyefe39bc2018-05-01 17:06:20 -04004440 The third and fourth image corners are not scaled; the sides and center are scaled to
Cary Clark8032b982017-07-28 11:04:54 -04004441 fill the remaining space.
4442 The rightmost image has four corners scaled vertically to fit, and uses sides above
4443 and below center to fill the remaining space.
4444##
Cary Clarkbad5ad72017-08-03 17:14:08 -04004445void draw(SkCanvas* canvas) {
4446 SkIRect center = { 20, 10, 50, 40 };
4447 SkBitmap bitmap;
4448 bitmap.allocPixels(SkImageInfo::MakeN32Premul(60, 60));
4449 SkCanvas bitCanvas(bitmap);
4450 SkPaint paint;
4451 SkColor gray = 0xFF000000;
4452 int left = 0;
4453 for (auto right: { center.fLeft, center.fRight, bitmap.width() } ) {
4454 int top = 0;
4455 for (auto bottom: { center.fTop, center.fBottom, bitmap.height() } ) {
4456 paint.setColor(gray);
4457 bitCanvas.drawIRect(SkIRect::MakeLTRB(left, top, right, bottom), paint);
4458 gray += 0x001f1f1f;
4459 top = bottom;
4460 }
Herb Derbyefe39bc2018-05-01 17:06:20 -04004461 left = right;
Cary Clarkbad5ad72017-08-03 17:14:08 -04004462 }
4463 sk_sp<SkImage> image = SkImage::MakeFromBitmap(bitmap);
4464 for (auto dest: { 20, 30, 40, 60, 90 } ) {
4465 canvas->drawImageNine(image, center, SkRect::MakeWH(dest, 110 - dest), nullptr);
4466 canvas->translate(dest + 4, 0);
4467 }
Cary Clark8032b982017-07-28 11:04:54 -04004468}
4469##
4470
Cary Clark2ade9972017-11-02 17:49:34 -04004471#SeeAlso drawImage drawBitmapNine drawImageLattice drawImageRect
Cary Clark8032b982017-07-28 11:04:54 -04004472
4473##
4474
4475# ------------------------------------------------------------------------------
4476
4477#Method void drawBitmap(const SkBitmap& bitmap, SkScalar left, SkScalar top,
Cary Clark73fa9722017-08-29 17:36:51 -04004478 const SkPaint* paint = nullptr)
Cary Clarkab2621d2018-01-30 10:08:57 -05004479#In Draw_Image
Cary Clark78de7512018-02-07 07:27:09 -05004480#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05004481#Line # draws Bitmap at (x, y) position ##
Cary Clark8032b982017-07-28 11:04:54 -04004482
Cary Clark80247e52018-07-11 16:18:41 -04004483Draws Bitmap bitmap, with its top-left corner at (left, top),
Cary Clark8032b982017-07-28 11:04:54 -04004484using Clip, Matrix, and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004485
Cary Clarka560c472017-11-27 10:44:06 -05004486If Paint paint is not nullptr, apply Color_Filter, Color_Alpha, Image_Filter,
Cary Clarkbad5ad72017-08-03 17:14:08 -04004487Blend_Mode, and Draw_Looper. If bitmap is kAlpha_8_SkColorType, apply Shader.
4488If paint contains Mask_Filter, generate mask from bitmap bounds.
4489
4490If generated mask extends beyond bitmap bounds, replicate bitmap edge colors,
4491just as Shader made from SkShader::MakeBitmapShader with
Cary Clarkbc5697d2017-10-04 14:31:33 -04004492SkShader::kClamp_TileMode set replicates the bitmap edge color when it samples
Herb Derbyefe39bc2018-05-01 17:06:20 -04004493outside of its bounds.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004494
4495#Param bitmap Bitmap containing pixels, dimensions, and format ##
4496#Param left left side of bitmap ##
4497#Param top top side of bitmap ##
4498#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4499 and so on; or nullptr
4500##
Cary Clark8032b982017-07-28 11:04:54 -04004501
4502#Example
4503#Height 64
Cary Clarkbad5ad72017-08-03 17:14:08 -04004504void draw(SkCanvas* canvas) {
4505 uint8_t pixels[][8] = { { 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00},
4506 { 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00},
4507 { 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00},
4508 { 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF},
4509 { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
4510 { 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00},
4511 { 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0x00},
4512 { 0xFF, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0xFF} };
4513 SkBitmap bitmap;
Herb Derbyefe39bc2018-05-01 17:06:20 -04004514 bitmap.installPixels(SkImageInfo::MakeA8(8, 8),
Cary Clarkbad5ad72017-08-03 17:14:08 -04004515 (void*) pixels, sizeof(pixels[0]));
4516 SkPaint paint;
4517 canvas->scale(4, 4);
4518 for (auto color : { SK_ColorRED, SK_ColorBLUE, 0xFF007F00} ) {
4519 paint.setColor(color);
4520 canvas->drawBitmap(bitmap, 0, 0, &paint);
4521 canvas->translate(12, 0);
4522 }
Cary Clark8032b982017-07-28 11:04:54 -04004523}
4524##
4525
Cary Clark2ade9972017-11-02 17:49:34 -04004526#SeeAlso drawImage drawBitmapLattice drawBitmapNine drawBitmapRect SkBitmap::readPixels SkBitmap::writePixels
Cary Clark8032b982017-07-28 11:04:54 -04004527
4528##
4529
4530# ------------------------------------------------------------------------------
4531
4532#Method void drawBitmapRect(const SkBitmap& bitmap, const SkRect& src, const SkRect& dst,
4533 const SkPaint* paint, SrcRectConstraint constraint = kStrict_SrcRectConstraint)
Cary Clarkab2621d2018-01-30 10:08:57 -05004534#In Draw_Image
Cary Clark78de7512018-02-07 07:27:09 -05004535#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05004536#Line # draws Bitmap, source Rect to destination Rect ##
Cary Clark8032b982017-07-28 11:04:54 -04004537
Cary Clark80247e52018-07-11 16:18:41 -04004538Draws Rect src of Bitmap bitmap, scaled and translated to fill Rect dst.
Cary Clark8032b982017-07-28 11:04:54 -04004539Additionally transform draw using Clip, Matrix, and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004540
Cary Clarkbad5ad72017-08-03 17:14:08 -04004541If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4542Blend_Mode, and Draw_Looper. If bitmap is kAlpha_8_SkColorType, apply Shader.
4543If paint contains Mask_Filter, generate mask from bitmap bounds.
4544
4545If generated mask extends beyond bitmap bounds, replicate bitmap edge colors,
4546just as Shader made from SkShader::MakeBitmapShader with
Cary Clarkbc5697d2017-10-04 14:31:33 -04004547SkShader::kClamp_TileMode set replicates the bitmap edge color when it samples
Cary Clarkbad5ad72017-08-03 17:14:08 -04004548outside of its bounds.
4549
4550constraint set to kStrict_SrcRectConstraint limits Paint Filter_Quality to
4551sample within src; set to kFast_SrcRectConstraint allows sampling outside to
4552improve performance.
4553
4554#Param bitmap Bitmap containing pixels, dimensions, and format ##
4555#Param src source Rect of image to draw from ##
4556#Param dst destination Rect of image to draw to ##
4557#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4558 and so on; or nullptr
4559##
4560#Param constraint filter strictly within src or draw faster ##
Cary Clark8032b982017-07-28 11:04:54 -04004561
4562#Example
4563#Height 64
Cary Clarkbad5ad72017-08-03 17:14:08 -04004564void draw(SkCanvas* canvas) {
4565 uint8_t pixels[][8] = { { 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00},
4566 { 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00},
4567 { 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00},
4568 { 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF},
4569 { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
4570 { 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00},
4571 { 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00},
4572 { 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00} };
4573 SkBitmap bitmap;
Herb Derbyefe39bc2018-05-01 17:06:20 -04004574 bitmap.installPixels(SkImageInfo::MakeA8(8, 8),
Cary Clarkbad5ad72017-08-03 17:14:08 -04004575 (void*) pixels, sizeof(pixels[0]));
4576 SkPaint paint;
Cary Clark681287e2018-03-16 11:34:15 -04004577 paint.setMaskFilter(SkMaskFilter::MakeBlur(kSolid_SkBlurStyle, 6));
Cary Clarkbad5ad72017-08-03 17:14:08 -04004578 for (auto color : { SK_ColorRED, SK_ColorBLUE, 0xFF007F00} ) {
4579 paint.setColor(color);
4580 canvas->drawBitmapRect(bitmap, SkRect::MakeWH(8, 8), SkRect::MakeWH(32, 32), &paint);
4581 canvas->translate(48, 0);
4582 }
Cary Clark8032b982017-07-28 11:04:54 -04004583}
4584##
4585
Cary Clark2ade9972017-11-02 17:49:34 -04004586#SeeAlso drawImageRect drawBitmap drawBitmapLattice drawBitmapNine
Cary Clark8032b982017-07-28 11:04:54 -04004587
4588##
4589
4590# ------------------------------------------------------------------------------
4591
4592#Method void drawBitmapRect(const SkBitmap& bitmap, const SkIRect& isrc, const SkRect& dst,
4593 const SkPaint* paint, SrcRectConstraint constraint = kStrict_SrcRectConstraint)
Cary Clarkab2621d2018-01-30 10:08:57 -05004594#In Draw_Image
Cary Clark78de7512018-02-07 07:27:09 -05004595#In Draw
Cary Clark80247e52018-07-11 16:18:41 -04004596Draws IRect isrc of Bitmap bitmap, scaled and translated to fill Rect dst.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004597isrc is on integer pixel boundaries; dst may include fractional boundaries.
Cary Clark8032b982017-07-28 11:04:54 -04004598Additionally transform draw using Clip, Matrix, and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004599
Cary Clarkbad5ad72017-08-03 17:14:08 -04004600If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4601Blend_Mode, and Draw_Looper. If bitmap is kAlpha_8_SkColorType, apply Shader.
4602If paint contains Mask_Filter, generate mask from bitmap bounds.
4603
4604If generated mask extends beyond bitmap bounds, replicate bitmap edge colors,
4605just as Shader made from SkShader::MakeBitmapShader with
Cary Clarkbc5697d2017-10-04 14:31:33 -04004606SkShader::kClamp_TileMode set replicates the bitmap edge color when it samples
Cary Clarkbad5ad72017-08-03 17:14:08 -04004607outside of its bounds.
4608
4609constraint set to kStrict_SrcRectConstraint limits Paint Filter_Quality to
Cary Clarkce101242017-09-01 15:51:02 -04004610sample within isrc; set to kFast_SrcRectConstraint allows sampling outside to
Cary Clarkbad5ad72017-08-03 17:14:08 -04004611improve performance.
4612
4613#Param bitmap Bitmap containing pixels, dimensions, and format ##
4614#Param isrc source IRect of image to draw from ##
4615#Param dst destination Rect of image to draw to ##
4616#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4617 and so on; or nullptr
4618##
Cary Clarkce101242017-09-01 15:51:02 -04004619#Param constraint sample strictly within isrc, or draw faster ##
Cary Clark8032b982017-07-28 11:04:54 -04004620
4621#Example
4622#Height 64
Cary Clarkbad5ad72017-08-03 17:14:08 -04004623void draw(SkCanvas* canvas) {
4624 uint8_t pixels[][8] = { { 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00},
4625 { 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00},
4626 { 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0xFF},
4627 { 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0xFF},
4628 { 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF},
4629 { 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF},
4630 { 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00},
4631 { 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00} };
4632 SkBitmap bitmap;
Herb Derbyefe39bc2018-05-01 17:06:20 -04004633 bitmap.installPixels(SkImageInfo::MakeA8(8, 8),
Cary Clarkbad5ad72017-08-03 17:14:08 -04004634 (void*) pixels, sizeof(pixels[0]));
4635 SkPaint paint;
4636 paint.setFilterQuality(kHigh_SkFilterQuality);
4637 for (auto color : { SK_ColorRED, SK_ColorBLUE, 0xFF007F00, 0xFF7f007f} ) {
4638 paint.setColor(color);
4639 canvas->drawBitmapRect(bitmap, SkIRect::MakeWH(8, 8), SkRect::MakeWH(32, 32), &paint);
4640 canvas->translate(48.25f, 0);
4641 }
Cary Clark8032b982017-07-28 11:04:54 -04004642}
4643##
4644
Cary Clark2ade9972017-11-02 17:49:34 -04004645#SeeAlso drawImageRect drawBitmap drawBitmapLattice drawBitmapNine
Cary Clark8032b982017-07-28 11:04:54 -04004646
4647##
4648
4649# ------------------------------------------------------------------------------
4650
4651#Method void drawBitmapRect(const SkBitmap& bitmap, const SkRect& dst, const SkPaint* paint,
4652 SrcRectConstraint constraint = kStrict_SrcRectConstraint)
Cary Clarkab2621d2018-01-30 10:08:57 -05004653#In Draw_Image
Cary Clark78de7512018-02-07 07:27:09 -05004654#In Draw
Cary Clark80247e52018-07-11 16:18:41 -04004655Draws Bitmap bitmap, scaled and translated to fill Rect dst.
Cary Clarkce101242017-09-01 15:51:02 -04004656bitmap bounds is on integer pixel boundaries; dst may include fractional boundaries.
Cary Clark8032b982017-07-28 11:04:54 -04004657Additionally transform draw using Clip, Matrix, and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004658
Cary Clarkbad5ad72017-08-03 17:14:08 -04004659If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4660Blend_Mode, and Draw_Looper. If bitmap is kAlpha_8_SkColorType, apply Shader.
4661If paint contains Mask_Filter, generate mask from bitmap bounds.
4662
4663If generated mask extends beyond bitmap bounds, replicate bitmap edge colors,
4664just as Shader made from SkShader::MakeBitmapShader with
Cary Clarkbc5697d2017-10-04 14:31:33 -04004665SkShader::kClamp_TileMode set replicates the bitmap edge color when it samples
Cary Clarkbad5ad72017-08-03 17:14:08 -04004666outside of its bounds.
4667
4668constraint set to kStrict_SrcRectConstraint limits Paint Filter_Quality to
Cary Clarkce101242017-09-01 15:51:02 -04004669sample within bitmap; set to kFast_SrcRectConstraint allows sampling outside to
Cary Clarkbad5ad72017-08-03 17:14:08 -04004670improve performance.
4671
4672#Param bitmap Bitmap containing pixels, dimensions, and format ##
4673#Param dst destination Rect of image to draw to ##
4674#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4675 and so on; or nullptr
4676##
Cary Clarkce101242017-09-01 15:51:02 -04004677#Param constraint filter strictly within bitmap or draw faster ##
Cary Clark8032b982017-07-28 11:04:54 -04004678
4679#Example
4680#Height 64
Cary Clarkbad5ad72017-08-03 17:14:08 -04004681void draw(SkCanvas* canvas) {
4682 uint32_t pixels[][2] = { { 0x00000000, 0x55550000},
4683 { 0xAAAA0000, 0xFFFF0000} };
4684 SkBitmap bitmap;
Herb Derbyefe39bc2018-05-01 17:06:20 -04004685 bitmap.installPixels(SkImageInfo::MakeN32Premul(2, 2),
Cary Clarkbad5ad72017-08-03 17:14:08 -04004686 (void*) pixels, sizeof(pixels[0]));
4687 SkPaint paint;
4688 canvas->scale(4, 4);
4689 for (auto color : { SK_ColorRED, SK_ColorBLUE, SK_ColorGREEN } ) {
4690 paint.setColorFilter(SkColorFilter::MakeModeFilter(color, SkBlendMode::kPlus));
4691 canvas->drawBitmapRect(bitmap, SkRect::MakeWH(8, 8), &paint);
4692 canvas->translate(8, 0);
4693 }
Cary Clark8032b982017-07-28 11:04:54 -04004694}
4695##
4696
Cary Clark2ade9972017-11-02 17:49:34 -04004697#SeeAlso drawImageRect drawBitmap drawBitmapLattice drawBitmapNine
Cary Clark8032b982017-07-28 11:04:54 -04004698
4699##
4700
4701# ------------------------------------------------------------------------------
4702
Cary Clark682c58d2018-05-16 07:07:07 -04004703#PhraseDef paint_as_used_by_draw_lattice_or_draw_nine(bitmap_or_image)
4704If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4705Blend_Mode, and Draw_Looper. If #bitmap_or_image# is kAlpha_8_SkColorType, apply Shader.
4706If paint contains Mask_Filter, generate mask from #bitmap_or_image# bounds. If paint
4707Filter_Quality set to kNone_SkFilterQuality, disable pixel filtering. For all
4708other values of paint Filter_Quality, use kLow_SkFilterQuality to filter pixels.
Cary Clark137b8742018-05-30 09:21:49 -04004709Any SkMaskFilter on paint is ignored as is paint Anti_Aliasing state.
Cary Clark682c58d2018-05-16 07:07:07 -04004710##
4711
Cary Clark8032b982017-07-28 11:04:54 -04004712#Method void drawBitmapNine(const SkBitmap& bitmap, const SkIRect& center, const SkRect& dst,
Cary Clark73fa9722017-08-29 17:36:51 -04004713 const SkPaint* paint = nullptr)
Cary Clarkab2621d2018-01-30 10:08:57 -05004714#In Draw_Image
Cary Clark78de7512018-02-07 07:27:09 -05004715#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05004716#Line # draws Nine_Patch Bitmap ##
Cary Clark8032b982017-07-28 11:04:54 -04004717
Cary Clark80247e52018-07-11 16:18:41 -04004718Draws Bitmap bitmap stretched proportionally to fit into Rect dst.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004719IRect center divides the bitmap into nine sections: four sides, four corners,
Cary Clarkce101242017-09-01 15:51:02 -04004720and the center. Corners are not scaled, or scaled down proportionately if their
Cary Clarkbad5ad72017-08-03 17:14:08 -04004721sides are larger than dst; center and four sides are scaled to fit remaining
4722space, if any.
Cary Clark8032b982017-07-28 11:04:54 -04004723
Cary Clarkbad5ad72017-08-03 17:14:08 -04004724Additionally transform draw using Clip, Matrix, and optional Paint paint.
4725
Cary Clark682c58d2018-05-16 07:07:07 -04004726#paint_as_used_by_draw_lattice_or_draw_nine(bitmap)#
Cary Clarkbad5ad72017-08-03 17:14:08 -04004727
4728If generated mask extends beyond bitmap bounds, replicate bitmap edge colors,
4729just as Shader made from SkShader::MakeBitmapShader with
Cary Clarkbc5697d2017-10-04 14:31:33 -04004730SkShader::kClamp_TileMode set replicates the bitmap edge color when it samples
Cary Clarkbad5ad72017-08-03 17:14:08 -04004731outside of its bounds.
4732
4733#Param bitmap Bitmap containing pixels, dimensions, and format ##
4734#Param center IRect edge of image corners and sides ##
4735#Param dst destination Rect of image to draw to ##
4736#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4737 and so on; or nullptr
4738##
Cary Clark8032b982017-07-28 11:04:54 -04004739
4740#Example
4741#Height 128
4742#Description
4743 The two leftmost bitmap draws has four corners and sides to the left and right of center.
4744 The leftmost bitmap draw scales the width of corners proportionately to fit.
Herb Derbyefe39bc2018-05-01 17:06:20 -04004745 The third and fourth draw corners are not scaled; the sides and center are scaled to
Cary Clark8032b982017-07-28 11:04:54 -04004746 fill the remaining space.
4747 The rightmost bitmap draw has four corners scaled vertically to fit, and uses sides above
4748 and below center to fill the remaining space.
4749##
Cary Clarkbad5ad72017-08-03 17:14:08 -04004750void draw(SkCanvas* canvas) {
4751 SkIRect center = { 20, 10, 50, 40 };
4752 SkBitmap bitmap;
4753 bitmap.allocPixels(SkImageInfo::MakeN32Premul(60, 60));
4754 SkCanvas bitCanvas(bitmap);
4755 SkPaint paint;
4756 SkColor gray = 0xFF000000;
4757 int left = 0;
4758 for (auto right: { center.fLeft, center.fRight, bitmap.width() } ) {
4759 int top = 0;
4760 for (auto bottom: { center.fTop, center.fBottom, bitmap.height() } ) {
4761 paint.setColor(gray);
4762 bitCanvas.drawIRect(SkIRect::MakeLTRB(left, top, right, bottom), paint);
4763 gray += 0x001f1f1f;
4764 top = bottom;
4765 }
Herb Derbyefe39bc2018-05-01 17:06:20 -04004766 left = right;
Cary Clarkbad5ad72017-08-03 17:14:08 -04004767 }
4768 for (auto dest: { 20, 30, 40, 60, 90 } ) {
4769 canvas->drawBitmapNine(bitmap, center, SkRect::MakeWH(dest, 110 - dest), nullptr);
4770 canvas->translate(dest + 4, 0);
4771 }
Cary Clark8032b982017-07-28 11:04:54 -04004772}
4773##
4774
Cary Clark2ade9972017-11-02 17:49:34 -04004775#SeeAlso drawImageNine drawBitmap drawBitmapLattice drawBitmapRect
Cary Clark8032b982017-07-28 11:04:54 -04004776
4777##
4778
4779# ------------------------------------------------------------------------------
Cary Clark682c58d2018-05-16 07:07:07 -04004780#Subtopic Lattice
4781#Line # divides Bitmap or Image into a rectangular grid ##
4782
Cary Clark8032b982017-07-28 11:04:54 -04004783#Struct Lattice
Cary Clark08895c42018-02-01 09:37:32 -05004784#Line # divides Bitmap or Image into a rectangular grid ##
Cary Clark682c58d2018-05-16 07:07:07 -04004785
Cary Clark8032b982017-07-28 11:04:54 -04004786#Code
4787 struct Lattice {
Cary Clark2f466242017-12-11 16:03:17 -05004788 enum RectType ...
Cary Clark8032b982017-07-28 11:04:54 -04004789
Cary Clark2f466242017-12-11 16:03:17 -05004790 const int* fXDivs;
4791 const int* fYDivs;
4792 const RectType* fRectTypes;
4793 int fXCount;
4794 int fYCount;
4795 const SkIRect* fBounds;
4796 const SkColor* fColors;
Cary Clark8032b982017-07-28 11:04:54 -04004797 };
4798##
4799
Cary Clark137b8742018-05-30 09:21:49 -04004800Lattice divides Bitmap or Image into a rectangular grid.
4801Grid entries on even columns and even rows are fixed; these entries are
4802always drawn at their original size if the destination is large enough.
4803If the destination side is too small to hold the fixed entries, all fixed
4804entries are proportionately scaled down to fit.
4805The grid entries not on even columns and rows are scaled to fit the
4806remaining space, if any.
4807
Cary Clark682c58d2018-05-16 07:07:07 -04004808#Subtopic Overview
4809#Populate
4810##
4811
4812#Subtopic Constant
4813#Populate
4814##
Cary Clark154beea2017-10-26 07:58:48 -04004815
Cary Clark2f466242017-12-11 16:03:17 -05004816 #Enum RectType
Cary Clark682c58d2018-05-16 07:07:07 -04004817 #Line # optional setting per rectangular grid entry ##
Cary Clark8032b982017-07-28 11:04:54 -04004818 #Code
Cary Clark2f466242017-12-11 16:03:17 -05004819 enum RectType : uint8_t {
4820 kDefault = 0,
4821 kTransparent,
4822 kFixedColor,
Cary Clark8032b982017-07-28 11:04:54 -04004823 };
4824 ##
4825
Cary Clark2f466242017-12-11 16:03:17 -05004826 Optional setting per rectangular grid entry to make it transparent,
4827 or to fill the grid entry with a color.
Cary Clark8032b982017-07-28 11:04:54 -04004828
Cary Clark2f466242017-12-11 16:03:17 -05004829 #Const kDefault 0
Cary Clark682c58d2018-05-16 07:07:07 -04004830 #Line # draws Bitmap into lattice rectangle ##
Cary Clark2f466242017-12-11 16:03:17 -05004831 ##
4832
4833 #Const kTransparent 1
Cary Clark682c58d2018-05-16 07:07:07 -04004834 #Line # skips lattice rectangle by making it transparent ##
Cary Clark2f466242017-12-11 16:03:17 -05004835 ##
4836
4837 #Const kFixedColor 2
Cary Clark682c58d2018-05-16 07:07:07 -04004838 #Line # draws one of fColors into lattice rectangle ##
Cary Clark8032b982017-07-28 11:04:54 -04004839 ##
4840 ##
4841
Cary Clark682c58d2018-05-16 07:07:07 -04004842#Subtopic Member
4843#Populate
4844##
4845
Cary Clark8032b982017-07-28 11:04:54 -04004846 #Member const int* fXDivs
Cary Clark5538c132018-06-14 12:28:14 -04004847 #Line # x-axis values dividing bitmap ##
4848 Array of x-axis values that divide the bitmap vertically.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004849 Array entries must be unique, increasing, greater than or equal to
4850 fBounds left edge, and less than fBounds right edge.
4851 Set the first element to fBounds left to collapse the left column of
4852 fixed grid entries.
Cary Clark8032b982017-07-28 11:04:54 -04004853 ##
4854
4855 #Member const int* fYDivs
Cary Clark5538c132018-06-14 12:28:14 -04004856 #Line # y-axis values dividing bitmap ##
4857 Array of y-axis values that divide the bitmap horizontally.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004858 Array entries must be unique, increasing, greater than or equal to
4859 fBounds top edge, and less than fBounds bottom edge.
4860 Set the first element to fBounds top to collapse the top row of fixed
4861 grid entries.
Cary Clark8032b982017-07-28 11:04:54 -04004862 ##
4863
Cary Clark2f466242017-12-11 16:03:17 -05004864 #Member const RectType* fRectTypes
Cary Clark682c58d2018-05-16 07:07:07 -04004865 #Line # array of fill types ##
Cary Clark2f466242017-12-11 16:03:17 -05004866 Optional array of fill types, one per rectangular grid entry:
Cary Clarkbad5ad72017-08-03 17:14:08 -04004867 array length must be
4868 #Formula
4869 (fXCount + 1) * (fYCount + 1)
4870 ##
4871 .
Cary Clark6fc50412017-09-21 12:31:06 -04004872
Cary Clark2f466242017-12-11 16:03:17 -05004873 Each RectType is one of: kDefault, kTransparent, kFixedColor.
4874
Cary Clark8032b982017-07-28 11:04:54 -04004875 Array entries correspond to the rectangular grid entries, ascending
4876 left to right and then top to bottom.
4877 ##
4878
4879 #Member int fXCount
Cary Clark682c58d2018-05-16 07:07:07 -04004880 #Line # number of x-coordinates ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04004881 Number of entries in fXDivs array; one less than the number of
4882 horizontal divisions.
Cary Clark8032b982017-07-28 11:04:54 -04004883 ##
4884
4885 #Member int fYCount
Cary Clark682c58d2018-05-16 07:07:07 -04004886 #Line # number of y-coordinates ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04004887 Number of entries in fYDivs array; one less than the number of vertical
4888 divisions.
Cary Clark8032b982017-07-28 11:04:54 -04004889 ##
4890
4891 #Member const SkIRect* fBounds
Cary Clark682c58d2018-05-16 07:07:07 -04004892 #Line # source bounds to draw from ##
Cary Clark8032b982017-07-28 11:04:54 -04004893 Optional subset IRect source to draw from.
4894 If nullptr, source bounds is dimensions of Bitmap or Image.
4895 ##
4896
Cary Clark2f466242017-12-11 16:03:17 -05004897 #Member const SkColor* fColors
Cary Clark682c58d2018-05-16 07:07:07 -04004898 #Line # array of colors ##
Cary Clark2f466242017-12-11 16:03:17 -05004899 Optional array of colors, one per rectangular grid entry.
4900 Array length must be
4901 #Formula
4902 (fXCount + 1) * (fYCount + 1)
4903 ##
4904 .
4905
4906 Array entries correspond to the rectangular grid entries, ascending
4907 left to right, then top to bottom.
4908 ##
4909
Cary Clark8032b982017-07-28 11:04:54 -04004910#Struct Lattice ##
4911
4912#Method void drawBitmapLattice(const SkBitmap& bitmap, const Lattice& lattice, const SkRect& dst,
4913 const SkPaint* paint = nullptr)
Cary Clarkab2621d2018-01-30 10:08:57 -05004914#In Draw_Image
Cary Clark78de7512018-02-07 07:27:09 -05004915#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05004916#Line # draws proportionally stretched Bitmap ##
Cary Clark8032b982017-07-28 11:04:54 -04004917
Cary Clark80247e52018-07-11 16:18:41 -04004918Draws Bitmap bitmap stretched proportionally to fit into Rect dst.
Cary Clark8032b982017-07-28 11:04:54 -04004919
4920Lattice lattice divides bitmap into a rectangular grid.
4921Each intersection of an even-numbered row and column is fixed; like the corners
Cary Clarkbad5ad72017-08-03 17:14:08 -04004922of drawBitmapNine, fixed lattice elements never scale larger than their initial
Cary Clarkbc5697d2017-10-04 14:31:33 -04004923size and shrink proportionately when all fixed elements exceed the bitmap
Cary Clarkbad5ad72017-08-03 17:14:08 -04004924dimension. All other grid elements scale to fill the available space, if any.
Cary Clark8032b982017-07-28 11:04:54 -04004925
4926Additionally transform draw using Clip, Matrix, and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004927
Cary Clark682c58d2018-05-16 07:07:07 -04004928#paint_as_used_by_draw_lattice_or_draw_nine(bitmap)#
Cary Clarkbad5ad72017-08-03 17:14:08 -04004929
4930If generated mask extends beyond bitmap bounds, replicate bitmap edge colors,
4931just as Shader made from SkShader::MakeBitmapShader with
Cary Clarkbc5697d2017-10-04 14:31:33 -04004932SkShader::kClamp_TileMode set replicates the bitmap edge color when it samples
Cary Clarkbad5ad72017-08-03 17:14:08 -04004933outside of its bounds.
4934
4935#Param bitmap Bitmap containing pixels, dimensions, and format ##
4936#Param lattice division of bitmap into fixed and variable rectangles ##
4937#Param dst destination Rect of image to draw to ##
4938#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4939 and so on; or nullptr
4940##
Cary Clark8032b982017-07-28 11:04:54 -04004941
4942#Example
4943#Height 128
4944#Description
4945 The two leftmost bitmap draws has four corners and sides to the left and right of center.
4946 The leftmost bitmap draw scales the width of corners proportionately to fit.
Herb Derbyefe39bc2018-05-01 17:06:20 -04004947 The third and fourth draw corners are not scaled; the sides are scaled to
Cary Clark8032b982017-07-28 11:04:54 -04004948 fill the remaining space; the center is transparent.
4949 The rightmost bitmap draw has four corners scaled vertically to fit, and uses sides above
4950 and below center to fill the remaining space.
4951##
Cary Clarkbad5ad72017-08-03 17:14:08 -04004952void draw(SkCanvas* canvas) {
4953 SkIRect center = { 20, 10, 50, 40 };
4954 SkBitmap bitmap;
4955 bitmap.allocPixels(SkImageInfo::MakeN32Premul(60, 60));
4956 SkCanvas bitCanvas(bitmap);
4957 SkPaint paint;
4958 SkColor gray = 0xFF000000;
4959 int left = 0;
4960 for (auto right: { center.fLeft, center.fRight, bitmap.width() } ) {
4961 int top = 0;
4962 for (auto bottom: { center.fTop, center.fBottom, bitmap.height() } ) {
4963 paint.setColor(gray);
4964 bitCanvas.drawIRect(SkIRect::MakeLTRB(left, top, right, bottom), paint);
4965 gray += 0x001f1f1f;
4966 top = bottom;
4967 }
Herb Derbyefe39bc2018-05-01 17:06:20 -04004968 left = right;
Cary Clarkbad5ad72017-08-03 17:14:08 -04004969 }
4970 const int xDivs[] = { center.fLeft, center.fRight };
4971 const int yDivs[] = { center.fTop, center.fBottom };
Cary Clarkca3ebcd2017-12-12 11:22:38 -05004972 SkCanvas::Lattice::RectType fillTypes[3][3];
4973 memset(fillTypes, 0, sizeof(fillTypes));
4974 fillTypes[1][1] = SkCanvas::Lattice::kTransparent;
4975 SkColor dummy[9]; // temporary pending bug fix
4976 SkCanvas::Lattice lattice = { xDivs, yDivs, fillTypes[0], SK_ARRAY_COUNT(xDivs),
4977 SK_ARRAY_COUNT(yDivs), nullptr, dummy };
Cary Clarkbad5ad72017-08-03 17:14:08 -04004978 for (auto dest: { 20, 30, 40, 60, 90 } ) {
Cary Clarkca3ebcd2017-12-12 11:22:38 -05004979 canvas->drawBitmapLattice(bitmap, lattice, SkRect::MakeWH(dest, 110 - dest), nullptr);
Cary Clarkbad5ad72017-08-03 17:14:08 -04004980 canvas->translate(dest + 4, 0);
4981 }
Cary Clark8032b982017-07-28 11:04:54 -04004982}
4983##
4984
Cary Clark2ade9972017-11-02 17:49:34 -04004985#SeeAlso drawImageLattice drawBitmap drawBitmapNine Lattice
Cary Clark8032b982017-07-28 11:04:54 -04004986
4987##
4988
4989# ------------------------------------------------------------------------------
4990
4991#Method void drawImageLattice(const SkImage* image, const Lattice& lattice, const SkRect& dst,
4992 const SkPaint* paint = nullptr)
Cary Clarkab2621d2018-01-30 10:08:57 -05004993#In Draw_Image
Cary Clark78de7512018-02-07 07:27:09 -05004994#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05004995#Line # draws proportionally stretched Image ##
Cary Clark8032b982017-07-28 11:04:54 -04004996
Cary Clark80247e52018-07-11 16:18:41 -04004997Draws Image image stretched proportionally to fit into Rect dst.
Cary Clark8032b982017-07-28 11:04:54 -04004998
4999Lattice lattice divides image into a rectangular grid.
5000Each intersection of an even-numbered row and column is fixed; like the corners
Cary Clarkbad5ad72017-08-03 17:14:08 -04005001of drawBitmapNine, fixed lattice elements never scale larger than their initial
Cary Clarkbc5697d2017-10-04 14:31:33 -04005002size and shrink proportionately when all fixed elements exceed the bitmap
Cary Clarkbad5ad72017-08-03 17:14:08 -04005003dimension. All other grid elements scale to fill the available space, if any.
Cary Clark8032b982017-07-28 11:04:54 -04005004
5005Additionally transform draw using Clip, Matrix, and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04005006
Cary Clark682c58d2018-05-16 07:07:07 -04005007#paint_as_used_by_draw_lattice_or_draw_nine(image)#
Cary Clarkbad5ad72017-08-03 17:14:08 -04005008
5009If generated mask extends beyond bitmap bounds, replicate bitmap edge colors,
5010just as Shader made from SkShader::MakeBitmapShader with
Cary Clarkbc5697d2017-10-04 14:31:33 -04005011SkShader::kClamp_TileMode set replicates the bitmap edge color when it samples
Cary Clarkbad5ad72017-08-03 17:14:08 -04005012outside of its bounds.
5013
5014#Param image Image containing pixels, dimensions, and format ##
5015#Param lattice division of bitmap into fixed and variable rectangles ##
5016#Param dst destination Rect of image to draw to ##
5017#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
5018 and so on; or nullptr
5019##
Cary Clark8032b982017-07-28 11:04:54 -04005020
5021#Example
5022#Height 128
5023#Description
5024 The leftmost image is smaller than center; only corners are drawn, all scaled to fit.
Cary Clarkce101242017-09-01 15:51:02 -04005025 The second image equals the size of center; only corners are drawn without scaling.
5026 The remaining images are larger than center. All corners draw without scaling. The sides
Cary Clark8032b982017-07-28 11:04:54 -04005027 are scaled if needed to take up the remaining space; the center is transparent.
5028##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005029void draw(SkCanvas* canvas) {
5030 SkIRect center = { 20, 10, 50, 40 };
5031 SkBitmap bitmap;
5032 bitmap.allocPixels(SkImageInfo::MakeN32Premul(60, 60));
5033 SkCanvas bitCanvas(bitmap);
5034 SkPaint paint;
5035 SkColor gray = 0xFF000000;
5036 int left = 0;
5037 for (auto right: { center.fLeft, center.fRight, bitmap.width() } ) {
5038 int top = 0;
5039 for (auto bottom: { center.fTop, center.fBottom, bitmap.height() } ) {
5040 paint.setColor(gray);
5041 bitCanvas.drawIRect(SkIRect::MakeLTRB(left, top, right, bottom), paint);
5042 gray += 0x001f1f1f;
5043 top = bottom;
5044 }
Herb Derbyefe39bc2018-05-01 17:06:20 -04005045 left = right;
Cary Clarkbad5ad72017-08-03 17:14:08 -04005046 }
Cary Clarkbad5ad72017-08-03 17:14:08 -04005047 sk_sp<SkImage> image = SkImage::MakeFromBitmap(bitmap);
5048 SkImage* imagePtr = image.get();
5049 for (auto dest: { 20, 30, 40, 60, 90 } ) {
5050 canvas->drawImageNine(imagePtr, center, SkRect::MakeWH(dest, dest), nullptr);
5051 canvas->translate(dest + 4, 0);
5052 }
Cary Clark8032b982017-07-28 11:04:54 -04005053}
5054##
5055
Cary Clark2ade9972017-11-02 17:49:34 -04005056#SeeAlso drawBitmapLattice drawImage drawImageNine Lattice
Cary Clark8032b982017-07-28 11:04:54 -04005057
5058##
5059
Cary Clark682c58d2018-05-16 07:07:07 -04005060#Subtopic Lattice ##
5061
Cary Clark08895c42018-02-01 09:37:32 -05005062#Subtopic Draw_Image ##
Cary Clark8032b982017-07-28 11:04:54 -04005063
5064# ------------------------------------------------------------------------------
Cary Clark78de7512018-02-07 07:27:09 -05005065#Subtopic Draw_Text
5066#Populate
5067#Line # draws text into Canvas ##
5068##
Cary Clark8032b982017-07-28 11:04:54 -04005069
5070#Method void drawText(const void* text, size_t byteLength, SkScalar x, SkScalar y,
5071 const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05005072#In Draw_Text
5073#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05005074#Line # draws text at (x, y), using font advance ##
Cary Clark8032b982017-07-28 11:04:54 -04005075
Cary Clark80247e52018-07-11 16:18:41 -04005076Draws text, with origin at (x, y), using Clip, Matrix, and Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04005077
Cary Clarkbc5697d2017-10-04 14:31:33 -04005078text meaning depends on Paint_Text_Encoding; by default, text is encoded as
Cary Clarkbad5ad72017-08-03 17:14:08 -04005079UTF-8.
Cary Clark8032b982017-07-28 11:04:54 -04005080
Cary Clarkbad5ad72017-08-03 17:14:08 -04005081x and y meaning depends on Paint_Text_Align and Paint_Vertical_Text; by default
Cary Clarkbc5697d2017-10-04 14:31:33 -04005082text draws left to right, positioning the first glyph left side bearing at x
Herb Derbyefe39bc2018-05-01 17:06:20 -04005083and its baseline at y. Text size is affected by Matrix and Paint_Text_Size.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005084
Mike Reed8ad91a92018-01-19 19:09:32 -05005085All elements of paint: Path_Effect, Mask_Filter, Shader,
Cary Clarkbad5ad72017-08-03 17:14:08 -04005086Color_Filter, Image_Filter, and Draw_Looper; apply to text. By default, draws
Cary Clarkce101242017-09-01 15:51:02 -04005087filled 12 point black Glyphs.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005088
Cary Clarkce101242017-09-01 15:51:02 -04005089#Param text character code points or Glyphs drawn ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005090#Param byteLength byte length of text array ##
5091#Param x start of text on x-axis ##
5092#Param y start of text on y-axis ##
5093#Param paint text size, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005094
5095#Example
5096#Height 200
5097#Description
5098 The same text is drawn varying Paint_Text_Size and varying
Herb Derbyefe39bc2018-05-01 17:06:20 -04005099 Matrix.
Cary Clark8032b982017-07-28 11:04:54 -04005100##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005101void draw(SkCanvas* canvas) {
5102 SkPaint paint;
5103 paint.setAntiAlias(true);
5104 float textSizes[] = { 12, 18, 24, 36 };
5105 for (auto size: textSizes ) {
5106 paint.setTextSize(size);
5107 canvas->drawText("Aa", 2, 10, 20, paint);
5108 canvas->translate(0, size * 2);
5109 }
5110 paint.reset();
5111 paint.setAntiAlias(true);
5112 float yPos = 20;
5113 for (auto size: textSizes ) {
5114 float scale = size / 12.f;
5115 canvas->resetMatrix();
5116 canvas->translate(100, 0);
5117 canvas->scale(scale, scale);
5118 canvas->drawText("Aa", 2, 10 / scale, yPos / scale, paint);
Herb Derbyefe39bc2018-05-01 17:06:20 -04005119 yPos += size * 2;
Cary Clarkbad5ad72017-08-03 17:14:08 -04005120 }
5121}
Cary Clark8032b982017-07-28 11:04:54 -04005122##
5123
Cary Clark2ade9972017-11-02 17:49:34 -04005124#SeeAlso drawString drawPosText drawPosTextH drawTextBlob drawTextOnPath drawTextRSXform
Cary Clark8032b982017-07-28 11:04:54 -04005125
5126##
5127
5128#Method void drawString(const char* string, SkScalar x, SkScalar y, const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05005129#In Draw_Text
5130#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05005131#Line # draws null terminated string at (x, y) using font advance ##
Cary Clark682c58d2018-05-16 07:07:07 -04005132Draws null terminated string, with origin at (x, y), using Clip, Matrix, and
5133Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04005134
Cary Clarkbc5697d2017-10-04 14:31:33 -04005135string meaning depends on Paint_Text_Encoding; by default, strings are encoded
5136as UTF-8. Other values of Paint_Text_Encoding are unlikely to produce the desired
Cary Clarkbad5ad72017-08-03 17:14:08 -04005137results, since zero bytes may be embedded in the string.
Cary Clark8032b982017-07-28 11:04:54 -04005138
Cary Clarkbad5ad72017-08-03 17:14:08 -04005139x and y meaning depends on Paint_Text_Align and Paint_Vertical_Text; by default
Cary Clarkbc5697d2017-10-04 14:31:33 -04005140string draws left to right, positioning the first glyph left side bearing at x
Herb Derbyefe39bc2018-05-01 17:06:20 -04005141and its baseline at y. Text size is affected by Matrix and Paint_Text_Size.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005142
Mike Reed8ad91a92018-01-19 19:09:32 -05005143All elements of paint: Path_Effect, Mask_Filter, Shader,
Cary Clarkbad5ad72017-08-03 17:14:08 -04005144Color_Filter, Image_Filter, and Draw_Looper; apply to text. By default, draws
Cary Clarkce101242017-09-01 15:51:02 -04005145filled 12 point black Glyphs.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005146
Cary Clarkce101242017-09-01 15:51:02 -04005147#Param string character code points or Glyphs drawn,
Cary Clarkbad5ad72017-08-03 17:14:08 -04005148 ending with a char value of zero
5149##
5150#Param x start of string on x-axis ##
5151#Param y start of string on y-axis ##
5152#Param paint text size, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005153
5154#Example
Cary Clarkffb3d682018-05-17 12:17:28 -04005155#Height 48
Cary Clark8032b982017-07-28 11:04:54 -04005156 SkPaint paint;
5157 canvas->drawString("a small hello", 20, 20, paint);
5158##
5159
Cary Clark2ade9972017-11-02 17:49:34 -04005160#SeeAlso drawText drawPosText drawPosTextH drawTextBlob drawTextOnPath drawTextRSXform
Cary Clark8032b982017-07-28 11:04:54 -04005161
5162##
5163
5164#Method void drawString(const SkString& string, SkScalar x, SkScalar y, const SkPaint& paint)
5165
Cary Clark80247e52018-07-11 16:18:41 -04005166Draws null terminated string, with origin at (x, y), using Clip, Matrix, and
Cary Clarkbad5ad72017-08-03 17:14:08 -04005167Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04005168
Cary Clarkbc5697d2017-10-04 14:31:33 -04005169string meaning depends on Paint_Text_Encoding; by default, strings are encoded
5170as UTF-8. Other values of Paint_Text_Encoding are unlikely to produce the desired
Cary Clarkbad5ad72017-08-03 17:14:08 -04005171results, since zero bytes may be embedded in the string.
Cary Clark8032b982017-07-28 11:04:54 -04005172
Cary Clarkbad5ad72017-08-03 17:14:08 -04005173x and y meaning depends on Paint_Text_Align and Paint_Vertical_Text; by default
Cary Clarkbc5697d2017-10-04 14:31:33 -04005174string draws left to right, positioning the first glyph left side bearing at x
Herb Derbyefe39bc2018-05-01 17:06:20 -04005175and its baseline at y. Text size is affected by Matrix and Paint_Text_Size.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005176
Mike Reed8ad91a92018-01-19 19:09:32 -05005177All elements of paint: Path_Effect, Mask_Filter, Shader,
Cary Clarkbad5ad72017-08-03 17:14:08 -04005178Color_Filter, Image_Filter, and Draw_Looper; apply to text. By default, draws
Cary Clarkce101242017-09-01 15:51:02 -04005179filled 12 point black Glyphs.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005180
Cary Clarkce101242017-09-01 15:51:02 -04005181#Param string character code points or Glyphs drawn,
Cary Clarkbad5ad72017-08-03 17:14:08 -04005182 ending with a char value of zero
5183##
5184#Param x start of string on x-axis ##
5185#Param y start of string on y-axis ##
5186#Param paint text size, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005187
5188#Example
5189 SkPaint paint;
5190 SkString string("a small hello");
5191 canvas->drawString(string, 20, 20, paint);
5192##
5193
Cary Clark2ade9972017-11-02 17:49:34 -04005194#SeeAlso drawText drawPosText drawPosTextH drawTextBlob drawTextOnPath drawTextRSXform
Cary Clark8032b982017-07-28 11:04:54 -04005195
5196##
5197
5198# ------------------------------------------------------------------------------
5199
5200#Method void drawPosText(const void* text, size_t byteLength, const SkPoint pos[],
5201 const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05005202#In Draw_Text
5203#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05005204#Line # draws text at array of (x, y) positions ##
Cary Clark8032b982017-07-28 11:04:54 -04005205
Cary Clark80247e52018-07-11 16:18:41 -04005206Draws each glyph in text with the origin in pos array, using Clip, Matrix, and
Cary Clarkce101242017-09-01 15:51:02 -04005207Paint paint. The number of entries in pos array must match the number of Glyphs
Cary Clarkbad5ad72017-08-03 17:14:08 -04005208described by byteLength of text.
Cary Clark8032b982017-07-28 11:04:54 -04005209
Cary Clarkbc5697d2017-10-04 14:31:33 -04005210text meaning depends on Paint_Text_Encoding; by default, text is encoded as
Cary Clark5538c132018-06-14 12:28:14 -04005211UTF-8. pos elements meaning depends on Paint_Vertical_Text; by default
5212glyph left side bearing and baseline are relative to Point in pos array.
5213Text size is affected by Matrix and Paint_Text_Size.
Cary Clark8032b982017-07-28 11:04:54 -04005214
Mike Reed8ad91a92018-01-19 19:09:32 -05005215All elements of paint: Path_Effect, Mask_Filter, Shader,
Cary Clarkbad5ad72017-08-03 17:14:08 -04005216Color_Filter, Image_Filter, and Draw_Looper; apply to text. By default, draws
Cary Clarkce101242017-09-01 15:51:02 -04005217filled 12 point black Glyphs.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005218
5219Layout engines such as Harfbuzz typically position each glyph
Cary Clarkbc5697d2017-10-04 14:31:33 -04005220rather than using the font advance widths.
Cary Clark8032b982017-07-28 11:04:54 -04005221
Cary Clarkce101242017-09-01 15:51:02 -04005222#Param text character code points or Glyphs drawn ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005223#Param byteLength byte length of text array ##
5224#Param pos array of glyph origins ##
5225#Param paint text size, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005226
5227#Example
5228#Height 120
Cary Clarkbad5ad72017-08-03 17:14:08 -04005229void draw(SkCanvas* canvas) {
5230 const char hello[] = "HeLLo!";
5231 const SkPoint pos[] = { {40, 100}, {82, 95}, {115, 110}, {130, 95}, {145, 85},
5232 {172, 100} };
5233 SkPaint paint;
5234 paint.setTextSize(60);
5235 canvas->drawPosText(hello, strlen(hello), pos, paint);
Cary Clark8032b982017-07-28 11:04:54 -04005236}
5237##
5238
Cary Clark2ade9972017-11-02 17:49:34 -04005239#SeeAlso drawText drawPosTextH drawTextBlob drawTextOnPath drawTextRSXform
Cary Clark8032b982017-07-28 11:04:54 -04005240
5241##
5242
5243# ------------------------------------------------------------------------------
5244
5245#Method void drawPosTextH(const void* text, size_t byteLength, const SkScalar xpos[], SkScalar constY,
5246 const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05005247#In Draw_Text
5248#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05005249#Line # draws text at x positions with common baseline ##
Cary Clark8032b982017-07-28 11:04:54 -04005250
Cary Clark80247e52018-07-11 16:18:41 -04005251Draws each glyph in text with its (x, y) origin composed from xpos array and
Cary Clarkbad5ad72017-08-03 17:14:08 -04005252constY, using Clip, Matrix, and Paint paint. The number of entries in xpos array
Cary Clarkce101242017-09-01 15:51:02 -04005253must match the number of Glyphs described by byteLength of text.
Cary Clark8032b982017-07-28 11:04:54 -04005254
Cary Clarkbc5697d2017-10-04 14:31:33 -04005255text meaning depends on Paint_Text_Encoding; by default, text is encoded as
Cary Clark137b8742018-05-30 09:21:49 -04005256UTF-8. xpos elements meaning depends on Paint_Vertical_Text;
Cary Clarkbc5697d2017-10-04 14:31:33 -04005257by default each glyph left side bearing is positioned at an xpos element and
Cary Clarkbad5ad72017-08-03 17:14:08 -04005258its baseline is positioned at constY. Text size is affected by Matrix and
Herb Derbyefe39bc2018-05-01 17:06:20 -04005259Paint_Text_Size.
Cary Clark8032b982017-07-28 11:04:54 -04005260
Mike Reed8ad91a92018-01-19 19:09:32 -05005261All elements of paint: Path_Effect, Mask_Filter, Shader,
Cary Clarkbad5ad72017-08-03 17:14:08 -04005262Color_Filter, Image_Filter, and Draw_Looper; apply to text. By default, draws
Cary Clarkce101242017-09-01 15:51:02 -04005263filled 12 point black Glyphs.
Cary Clark8032b982017-07-28 11:04:54 -04005264
Cary Clarkbad5ad72017-08-03 17:14:08 -04005265Layout engines such as Harfbuzz typically position each glyph
Cary Clarkbc5697d2017-10-04 14:31:33 -04005266rather than using the font advance widths if all Glyphs share the same
Cary Clarkbad5ad72017-08-03 17:14:08 -04005267baseline.
5268
Cary Clarkce101242017-09-01 15:51:02 -04005269#Param text character code points or Glyphs drawn ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005270#Param byteLength byte length of text array ##
Cary Clark5538c132018-06-14 12:28:14 -04005271#Param xpos array of x-axis positions, used to position each glyph ##
5272#Param constY shared y-axis value for all of x-axis positions ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005273#Param paint text size, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005274
5275#Example
5276#Height 40
Cary Clarkbad5ad72017-08-03 17:14:08 -04005277 void draw(SkCanvas* canvas) {
5278 SkScalar xpos[] = { 20, 40, 80, 160 };
5279 SkPaint paint;
5280 canvas->drawPosTextH("XXXX", 4, xpos, 20, paint);
5281 }
Cary Clark8032b982017-07-28 11:04:54 -04005282##
5283
Cary Clark2ade9972017-11-02 17:49:34 -04005284#SeeAlso drawText drawPosText drawTextBlob drawTextOnPath drawTextRSXform
Cary Clark8032b982017-07-28 11:04:54 -04005285
5286##
5287
5288# ------------------------------------------------------------------------------
5289
5290#Method void drawTextOnPathHV(const void* text, size_t byteLength, const SkPath& path, SkScalar hOffset,
5291 SkScalar vOffset, const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05005292#In Draw_Text
5293#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05005294#Line # draws text following Path with offsets ##
Cary Clark8032b982017-07-28 11:04:54 -04005295
Cary Clark80247e52018-07-11 16:18:41 -04005296Draws text on Path path, using Clip, Matrix, and Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04005297
Cary Clarkbad5ad72017-08-03 17:14:08 -04005298Origin of text is at distance hOffset along the path, offset by a perpendicular
5299vector of length vOffset. If the path section corresponding the glyph advance is
5300curved, the glyph is drawn curved to match; control points in the glyph are
Cary Clarkbc5697d2017-10-04 14:31:33 -04005301mapped to projected points parallel to the path. If the text advance is larger
Cary Clarkbad5ad72017-08-03 17:14:08 -04005302than the path length, the excess text is clipped.
5303
Cary Clarkbc5697d2017-10-04 14:31:33 -04005304text meaning depends on Paint_Text_Encoding; by default, text is encoded as
Cary Clarkbad5ad72017-08-03 17:14:08 -04005305UTF-8. Origin meaning depends on Paint_Text_Align and Paint_Vertical_Text; by
Cary Clark5538c132018-06-14 12:28:14 -04005306default text positions the first glyph left side bearing and baseline relative
5307to origin. Text size is affected by Matrix and Paint_Text_Size.
Cary Clark8032b982017-07-28 11:04:54 -04005308
Mike Reed8ad91a92018-01-19 19:09:32 -05005309All elements of paint: Path_Effect, Mask_Filter, Shader,
Cary Clarkbad5ad72017-08-03 17:14:08 -04005310Color_Filter, Image_Filter, and Draw_Looper; apply to text. By default, draws
Cary Clarkce101242017-09-01 15:51:02 -04005311filled 12 point black Glyphs.
Cary Clark8032b982017-07-28 11:04:54 -04005312
Cary Clarkce101242017-09-01 15:51:02 -04005313#Param text character code points or Glyphs drawn ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005314#Param byteLength byte length of text array ##
5315#Param path Path providing text baseline ##
5316#Param hOffset distance along path to offset origin ##
5317#Param vOffset offset of text above (if negative) or below (if positive) the path ##
5318#Param paint text size, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005319
5320#Example
Herb Derbyefe39bc2018-05-01 17:06:20 -04005321 void draw(SkCanvas* canvas) {
Cary Clarkbad5ad72017-08-03 17:14:08 -04005322 const char aero[] = "correo a" "\xC3" "\xA9" "reo";
5323 const size_t len = sizeof(aero) - 1;
5324 SkPath path;
5325 path.addOval({43-26, 43-26, 43+26, 43+26}, SkPath::kCW_Direction, 3);
5326 SkPaint paint;
5327 paint.setTextSize(24);
5328 for (auto offset : { 0, 10, 20 } ) {
5329 canvas->drawTextOnPathHV(aero, len, path, 0, -offset, paint);
5330 canvas->translate(70 + offset, 70 + offset);
5331 }
5332 }
Cary Clark8032b982017-07-28 11:04:54 -04005333##
5334
Cary Clark2ade9972017-11-02 17:49:34 -04005335#SeeAlso drawTextOnPath drawText drawPosTextH drawTextBlob drawTextRSXform
Cary Clark8032b982017-07-28 11:04:54 -04005336
5337##
5338
5339# ------------------------------------------------------------------------------
5340
5341#Method void drawTextOnPath(const void* text, size_t byteLength, const SkPath& path,
5342 const SkMatrix* matrix, const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05005343#In Draw_Text
5344#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05005345#Line # draws text following Path contour ##
Cary Clark8032b982017-07-28 11:04:54 -04005346
Cary Clark80247e52018-07-11 16:18:41 -04005347Draws text on Path path, using Clip, Matrix, and Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04005348
Cary Clark682c58d2018-05-16 07:07:07 -04005349Origin of text is at beginning of path offset by matrix, if not nullptr.
Cary Clark137b8742018-05-30 09:21:49 -04005350matrix transforms text before text is mapped to path. If the path section
Cary Clark682c58d2018-05-16 07:07:07 -04005351corresponding the glyph advance is curved, the glyph is drawn curved to match;
5352control points in the glyph are mapped to projected points parallel to the path.
5353If the text advance is larger than the path length, the excess text is clipped.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005354
Cary Clark137b8742018-05-30 09:21:49 -04005355matrix does not effect paint Shader.
5356
Cary Clarkbc5697d2017-10-04 14:31:33 -04005357text meaning depends on Paint_Text_Encoding; by default, text is encoded as
Cary Clarkbad5ad72017-08-03 17:14:08 -04005358UTF-8. Origin meaning depends on Paint_Text_Align and Paint_Vertical_Text; by
Cary Clark5538c132018-06-14 12:28:14 -04005359default text positions the first glyph left side bearing and baseline relative
5360to origin. Text size is affected by matrix parameter, Canvas Matrix,
Cary Clark682c58d2018-05-16 07:07:07 -04005361and Paint_Text_Size.
Cary Clark8032b982017-07-28 11:04:54 -04005362
Mike Reed8ad91a92018-01-19 19:09:32 -05005363All elements of paint: Path_Effect, Mask_Filter, Shader,
Cary Clarkbad5ad72017-08-03 17:14:08 -04005364Color_Filter, Image_Filter, and Draw_Looper; apply to text. By default, draws
Cary Clark137b8742018-05-30 09:21:49 -04005365filled 12 point black Glyphs.
Cary Clark8032b982017-07-28 11:04:54 -04005366
Cary Clarkce101242017-09-01 15:51:02 -04005367#Param text character code points or Glyphs drawn ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005368#Param byteLength byte length of text array ##
5369#Param path Path providing text baseline ##
Cary Clarkce101242017-09-01 15:51:02 -04005370#Param matrix transform of Glyphs before mapping to path; may be nullptr
Cary Clarka523d2d2017-08-30 08:58:10 -04005371 to use identity Matrix
Cary Clarkbad5ad72017-08-03 17:14:08 -04005372##
5373#Param paint text size, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005374
5375#Example
Herb Derbyefe39bc2018-05-01 17:06:20 -04005376 void draw(SkCanvas* canvas) {
Cary Clarkbad5ad72017-08-03 17:14:08 -04005377 const char roller[] = "rollercoaster";
5378 const size_t len = sizeof(roller) - 1;
5379 SkPath path;
5380 path.cubicTo(40, -80, 120, 80, 160, -40);
5381 SkPaint paint;
5382 paint.setTextSize(32);
5383 paint.setStyle(SkPaint::kStroke_Style);
5384 SkMatrix matrix;
5385 matrix.setIdentity();
5386 for (int i = 0; i < 3; ++i) {
5387 canvas->translate(25, 60);
5388 canvas->drawPath(path, paint);
5389 canvas->drawTextOnPath(roller, len, path, &matrix, paint);
5390 matrix.preTranslate(0, 10);
5391 }
5392 }
Cary Clark8032b982017-07-28 11:04:54 -04005393##
5394
Cary Clark2ade9972017-11-02 17:49:34 -04005395#SeeAlso drawTextOnPathHV drawText drawPosTextH drawTextBlob drawTextRSXform
Cary Clark8032b982017-07-28 11:04:54 -04005396
5397##
5398
5399# ------------------------------------------------------------------------------
5400
5401#Method void drawTextRSXform(const void* text, size_t byteLength, const SkRSXform xform[],
5402 const SkRect* cullRect, const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05005403#In Draw_Text
5404#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05005405#Line # draws text with array of RSXform ##
Cary Clark8032b982017-07-28 11:04:54 -04005406
Cary Clark80247e52018-07-11 16:18:41 -04005407Draws text, transforming each glyph by the corresponding SkRSXform,
Cary Clark8032b982017-07-28 11:04:54 -04005408using Clip, Matrix, and Paint paint.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005409
Cary Clark137b8742018-05-30 09:21:49 -04005410RSXform xform array specifies a separate square scale, rotation, and translation
5411for each glyph. xform does not affect paint Shader.
Cary Clark8032b982017-07-28 11:04:54 -04005412
Cary Clarkbad5ad72017-08-03 17:14:08 -04005413Optional Rect cullRect is a conservative bounds of text, taking into account
Cary Clarkce101242017-09-01 15:51:02 -04005414RSXform and paint. If cullRect is outside of Clip, canvas can skip drawing.
Cary Clark8032b982017-07-28 11:04:54 -04005415
Mike Reed8ad91a92018-01-19 19:09:32 -05005416All elements of paint: Path_Effect, Mask_Filter, Shader,
Cary Clarkbad5ad72017-08-03 17:14:08 -04005417Color_Filter, Image_Filter, and Draw_Looper; apply to text. By default, draws
Cary Clarkce101242017-09-01 15:51:02 -04005418filled 12 point black Glyphs.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005419
Cary Clarkce101242017-09-01 15:51:02 -04005420#Param text character code points or Glyphs drawn ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005421#Param byteLength byte length of text array ##
5422#Param xform RSXform rotates, scales, and translates each glyph individually ##
5423#Param cullRect Rect bounds of text for efficient clipping; or nullptr ##
5424#Param paint text size, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005425
5426#Example
Herb Derbyefe39bc2018-05-01 17:06:20 -04005427void draw(SkCanvas* canvas) {
Cary Clarkbad5ad72017-08-03 17:14:08 -04005428 const int iterations = 26;
5429 SkRSXform transforms[iterations];
5430 char alphabet[iterations];
5431 SkScalar angle = 0;
5432 SkScalar scale = 1;
5433 for (size_t i = 0; i < SK_ARRAY_COUNT(transforms); ++i) {
5434 const SkScalar s = SkScalarSin(angle) * scale;
5435 const SkScalar c = SkScalarCos(angle) * scale;
5436 transforms[i] = SkRSXform::Make(-c, -s, -s * 16, c * 16);
5437 angle += .45;
5438 scale += .2;
5439 alphabet[i] = 'A' + i;
5440 }
5441 SkPaint paint;
5442 paint.setTextAlign(SkPaint::kCenter_Align);
5443 canvas->translate(110, 138);
5444 canvas->drawTextRSXform(alphabet, sizeof(alphabet), transforms, nullptr, paint);
Cary Clark8032b982017-07-28 11:04:54 -04005445}
5446##
5447
Cary Clark2ade9972017-11-02 17:49:34 -04005448#SeeAlso drawTextOnPath drawTextOnPathHV drawText drawPosText drawTextBlob
Cary Clark8032b982017-07-28 11:04:54 -04005449
5450##
5451
5452# ------------------------------------------------------------------------------
5453
5454#Method void drawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y, const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05005455#In Draw_Text
5456#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05005457#Line # draws text with arrays of positions and Paint ##
Cary Clark80247e52018-07-11 16:18:41 -04005458Draws Text_Blob blob at (x, y), using Clip, Matrix, and Paint paint.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005459
Cary Clarkce101242017-09-01 15:51:02 -04005460blob contains Glyphs, their positions, and paint attributes specific to text:
Cary Clarkbad5ad72017-08-03 17:14:08 -04005461Typeface, Paint_Text_Size, Paint_Text_Scale_X, Paint_Text_Skew_X,
Cary Clarkffb3d682018-05-17 12:17:28 -04005462Paint_Text_Align, Paint_Hinting, Anti_Alias, Paint_Fake_Bold,
Cary Clarkbad5ad72017-08-03 17:14:08 -04005463Font_Embedded_Bitmaps, Full_Hinting_Spacing, LCD_Text, Linear_Text,
5464Subpixel_Text, and Paint_Vertical_Text.
Cary Clark8032b982017-07-28 11:04:54 -04005465
Cary Clark3cd22cc2017-12-01 11:49:58 -05005466Paint_Text_Encoding must be set to SkPaint::kGlyphID_TextEncoding.
5467
Mike Reed8ad91a92018-01-19 19:09:32 -05005468Elements of paint: Path_Effect, Mask_Filter, Shader, Color_Filter,
Cary Clark8032b982017-07-28 11:04:54 -04005469Image_Filter, and Draw_Looper; apply to blob.
5470
Cary Clarkce101242017-09-01 15:51:02 -04005471#Param blob Glyphs, positions, and their paints' text size, typeface, and so on ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005472#Param x horizontal offset applied to blob ##
5473#Param y vertical offset applied to blob ##
5474#Param paint blend, color, stroking, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005475
5476#Example
5477#Height 120
Cary Clarkbad5ad72017-08-03 17:14:08 -04005478 void draw(SkCanvas* canvas) {
Cary Clark2f466242017-12-11 16:03:17 -05005479 SkTextBlobBuilder textBlobBuilder;
5480 const char bunny[] = "/(^x^)\\";
5481 const int len = sizeof(bunny) - 1;
5482 uint16_t glyphs[len];
5483 SkPaint paint;
5484 paint.textToGlyphs(bunny, len, glyphs);
Cary Clark3cd22cc2017-12-01 11:49:58 -05005485 paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
Cary Clark2f466242017-12-11 16:03:17 -05005486 int runs[] = { 3, 1, 3 };
5487 SkPoint textPos = { 20, 100 };
5488 int glyphIndex = 0;
5489 for (auto runLen : runs) {
5490 paint.setTextSize(1 == runLen ? 20 : 50);
Herb Derbyefe39bc2018-05-01 17:06:20 -04005491 const SkTextBlobBuilder::RunBuffer& run =
Cary Clark2f466242017-12-11 16:03:17 -05005492 textBlobBuilder.allocRun(paint, runLen, textPos.fX, textPos.fY);
5493 memcpy(run.glyphs, &glyphs[glyphIndex], sizeof(glyphs[0]) * runLen);
5494 textPos.fX += paint.measureText(&glyphs[glyphIndex], sizeof(glyphs[0]) * runLen, nullptr);
5495 glyphIndex += runLen;
5496 }
5497 sk_sp<const SkTextBlob> blob = textBlobBuilder.make();
5498 paint.reset();
Cary Clarkbad5ad72017-08-03 17:14:08 -04005499 canvas->drawTextBlob(blob.get(), 0, 0, paint);
Cary Clark8032b982017-07-28 11:04:54 -04005500 }
5501##
5502
Cary Clark2ade9972017-11-02 17:49:34 -04005503#SeeAlso drawText drawPosText drawPosTextH
Cary Clark8032b982017-07-28 11:04:54 -04005504
5505##
5506
5507# ------------------------------------------------------------------------------
5508
Herb Derbyefe39bc2018-05-01 17:06:20 -04005509#Method void drawTextBlob(const sk_sp<SkTextBlob>& blob, SkScalar x, SkScalar y, const SkPaint& paint)
Cary Clark8032b982017-07-28 11:04:54 -04005510
Cary Clark80247e52018-07-11 16:18:41 -04005511Draws Text_Blob blob at (x, y), using Clip, Matrix, and Paint paint.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005512
Cary Clarkce101242017-09-01 15:51:02 -04005513blob contains Glyphs, their positions, and paint attributes specific to text:
Cary Clarkbad5ad72017-08-03 17:14:08 -04005514Typeface, Paint_Text_Size, Paint_Text_Scale_X, Paint_Text_Skew_X,
Cary Clarkffb3d682018-05-17 12:17:28 -04005515Paint_Text_Align, Paint_Hinting, Anti_Alias, Paint_Fake_Bold,
Cary Clarkbad5ad72017-08-03 17:14:08 -04005516Font_Embedded_Bitmaps, Full_Hinting_Spacing, LCD_Text, Linear_Text,
5517Subpixel_Text, and Paint_Vertical_Text.
Cary Clark8032b982017-07-28 11:04:54 -04005518
Cary Clark3cd22cc2017-12-01 11:49:58 -05005519Paint_Text_Encoding must be set to SkPaint::kGlyphID_TextEncoding.
5520
Herb Derbyefe39bc2018-05-01 17:06:20 -04005521Elements of paint: Path_Effect, Mask_Filter, Shader, Color_Filter,
Cary Clark8032b982017-07-28 11:04:54 -04005522Image_Filter, and Draw_Looper; apply to blob.
5523
Cary Clarkce101242017-09-01 15:51:02 -04005524#Param blob Glyphs, positions, and their paints' text size, typeface, and so on ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005525#Param x horizontal offset applied to blob ##
5526#Param y vertical offset applied to blob ##
5527#Param paint blend, color, stroking, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005528
5529#Example
5530#Height 120
5531#Description
5532Paint attributes unrelated to text, like color, have no effect on paint in allocated Text_Blob.
5533Paint attributes related to text, like text size, have no effect on paint passed to drawTextBlob.
5534##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005535 void draw(SkCanvas* canvas) {
5536 SkTextBlobBuilder textBlobBuilder;
5537 SkPaint paint;
5538 paint.setTextSize(50);
5539 paint.setColor(SK_ColorRED);
Cary Clark2f466242017-12-11 16:03:17 -05005540 paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
Herb Derbyefe39bc2018-05-01 17:06:20 -04005541 const SkTextBlobBuilder::RunBuffer& run =
Cary Clarkbad5ad72017-08-03 17:14:08 -04005542 textBlobBuilder.allocRun(paint, 1, 20, 100);
5543 run.glyphs[0] = 20;
5544 sk_sp<const SkTextBlob> blob = textBlobBuilder.make();
5545 paint.setTextSize(10);
5546 paint.setColor(SK_ColorBLUE);
5547 canvas->drawTextBlob(blob.get(), 0, 0, paint);
5548 }
Cary Clark8032b982017-07-28 11:04:54 -04005549##
5550
Cary Clark2ade9972017-11-02 17:49:34 -04005551#SeeAlso drawText drawPosText drawPosTextH
Cary Clark8032b982017-07-28 11:04:54 -04005552
5553##
5554
5555# ------------------------------------------------------------------------------
5556
Herb Derbyefe39bc2018-05-01 17:06:20 -04005557#Method void drawPicture(const SkPicture* picture)
Cary Clark78de7512018-02-07 07:27:09 -05005558#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05005559#Line # draws Picture using Clip and Matrix ##
Cary Clark80247e52018-07-11 16:18:41 -04005560Draws Picture picture, using Clip and Matrix.
Cary Clark8032b982017-07-28 11:04:54 -04005561Clip and Matrix are unchanged by picture contents, as if
5562save() was called before and restore() was called after drawPicture.
5563
5564Picture records a series of draw commands for later playback.
5565
Cary Clarkbad5ad72017-08-03 17:14:08 -04005566#Param picture recorded drawing commands to play ##
Cary Clark8032b982017-07-28 11:04:54 -04005567
5568#Example
Herb Derbyefe39bc2018-05-01 17:06:20 -04005569void draw(SkCanvas* canvas) {
Cary Clarkbad5ad72017-08-03 17:14:08 -04005570 SkPictureRecorder recorder;
5571 SkCanvas* recordingCanvas = recorder.beginRecording(50, 50);
5572 for (auto color : { SK_ColorRED, SK_ColorBLUE, 0xff007f00 } ) {
5573 SkPaint paint;
5574 paint.setColor(color);
5575 recordingCanvas->drawRect({10, 10, 30, 40}, paint);
5576 recordingCanvas->translate(10, 10);
5577 recordingCanvas->scale(1.2f, 1.4f);
5578 }
5579 sk_sp<SkPicture> playback = recorder.finishRecordingAsPicture();
Cary Clarkbad5ad72017-08-03 17:14:08 -04005580 canvas->drawPicture(playback);
5581 canvas->scale(2, 2);
5582 canvas->translate(50, 0);
5583 canvas->drawPicture(playback);
Cary Clark8032b982017-07-28 11:04:54 -04005584}
5585##
5586
Cary Clark2ade9972017-11-02 17:49:34 -04005587#SeeAlso drawDrawable SkPicture SkPicture::playback
Cary Clark8032b982017-07-28 11:04:54 -04005588
5589##
5590
5591# ------------------------------------------------------------------------------
5592
Herb Derbyefe39bc2018-05-01 17:06:20 -04005593#Method void drawPicture(const sk_sp<SkPicture>& picture)
Cary Clark8032b982017-07-28 11:04:54 -04005594
Cary Clark80247e52018-07-11 16:18:41 -04005595Draws Picture picture, using Clip and Matrix.
Cary Clark8032b982017-07-28 11:04:54 -04005596Clip and Matrix are unchanged by picture contents, as if
5597save() was called before and restore() was called after drawPicture.
5598
5599Picture records a series of draw commands for later playback.
5600
Cary Clarkbad5ad72017-08-03 17:14:08 -04005601#Param picture recorded drawing commands to play ##
Cary Clark8032b982017-07-28 11:04:54 -04005602
5603#Example
Herb Derbyefe39bc2018-05-01 17:06:20 -04005604void draw(SkCanvas* canvas) {
Cary Clarkbad5ad72017-08-03 17:14:08 -04005605 SkPictureRecorder recorder;
5606 SkCanvas* recordingCanvas = recorder.beginRecording(50, 50);
5607 for (auto color : { SK_ColorRED, SK_ColorBLUE, 0xff007f00 } ) {
5608 SkPaint paint;
5609 paint.setColor(color);
5610 recordingCanvas->drawRect({10, 10, 30, 40}, paint);
5611 recordingCanvas->translate(10, 10);
5612 recordingCanvas->scale(1.2f, 1.4f);
5613 }
5614 sk_sp<SkPicture> playback = recorder.finishRecordingAsPicture();
5615 canvas->drawPicture(playback);
5616 canvas->scale(2, 2);
5617 canvas->translate(50, 0);
5618 canvas->drawPicture(playback);
Cary Clark8032b982017-07-28 11:04:54 -04005619}
5620##
5621
Cary Clark2ade9972017-11-02 17:49:34 -04005622#SeeAlso drawDrawable SkPicture SkPicture::playback
Cary Clark8032b982017-07-28 11:04:54 -04005623
5624##
5625
5626# ------------------------------------------------------------------------------
5627
5628#Method void drawPicture(const SkPicture* picture, const SkMatrix* matrix, const SkPaint* paint)
5629
Cary Clark80247e52018-07-11 16:18:41 -04005630Draws Picture picture, using Clip and Matrix; transforming picture with
Cary Clarkbad5ad72017-08-03 17:14:08 -04005631Matrix matrix, if provided; and use Paint paint Color_Alpha, Color_Filter,
5632Image_Filter, and Blend_Mode, if provided.
Cary Clark8032b982017-07-28 11:04:54 -04005633
5634matrix transformation is equivalent to: save(), concat(), drawPicture, restore().
5635paint use is equivalent to: saveLayer, drawPicture, restore().
5636
Cary Clarkbad5ad72017-08-03 17:14:08 -04005637#Param picture recorded drawing commands to play ##
5638#Param matrix Matrix to rotate, scale, translate, and so on; may be nullptr ##
5639#Param paint Paint to apply transparency, filtering, and so on; may be nullptr ##
Cary Clark8032b982017-07-28 11:04:54 -04005640
5641#Example
Herb Derbyefe39bc2018-05-01 17:06:20 -04005642void draw(SkCanvas* canvas) {
Cary Clarkbad5ad72017-08-03 17:14:08 -04005643 SkPaint paint;
5644 SkPictureRecorder recorder;
5645 SkCanvas* recordingCanvas = recorder.beginRecording(50, 50);
5646 for (auto color : { SK_ColorRED, SK_ColorBLUE, 0xff007f00 } ) {
5647 paint.setColor(color);
5648 recordingCanvas->drawRect({10, 10, 30, 40}, paint);
5649 recordingCanvas->translate(10, 10);
5650 recordingCanvas->scale(1.2f, 1.4f);
5651 }
5652 sk_sp<SkPicture> playback = recorder.finishRecordingAsPicture();
5653 const SkPicture* playbackPtr = playback.get();
5654 SkMatrix matrix;
5655 matrix.reset();
5656 for (auto alpha : { 70, 140, 210 } ) {
5657 paint.setAlpha(alpha);
5658 canvas->drawPicture(playbackPtr, &matrix, &paint);
5659 matrix.preTranslate(70, 70);
5660 }
Cary Clark8032b982017-07-28 11:04:54 -04005661}
5662##
5663
Cary Clark2ade9972017-11-02 17:49:34 -04005664#SeeAlso drawDrawable SkPicture SkPicture::playback
Cary Clark8032b982017-07-28 11:04:54 -04005665
5666##
5667
5668# ------------------------------------------------------------------------------
5669
Herb Derbyefe39bc2018-05-01 17:06:20 -04005670#Method void drawPicture(const sk_sp<SkPicture>& picture, const SkMatrix* matrix, const SkPaint* paint)
Cary Clark8032b982017-07-28 11:04:54 -04005671
Cary Clark80247e52018-07-11 16:18:41 -04005672Draws Picture picture, using Clip and Matrix; transforming picture with
Cary Clarkbad5ad72017-08-03 17:14:08 -04005673Matrix matrix, if provided; and use Paint paint Color_Alpha, Color_Filter,
5674Image_Filter, and Blend_Mode, if provided.
Cary Clark8032b982017-07-28 11:04:54 -04005675
5676matrix transformation is equivalent to: save(), concat(), drawPicture, restore().
5677paint use is equivalent to: saveLayer, drawPicture, restore().
5678
Cary Clarkbad5ad72017-08-03 17:14:08 -04005679#Param picture recorded drawing commands to play ##
5680#Param matrix Matrix to rotate, scale, translate, and so on; may be nullptr ##
5681#Param paint Paint to apply transparency, filtering, and so on; may be nullptr ##
Cary Clark8032b982017-07-28 11:04:54 -04005682
5683#Example
Herb Derbyefe39bc2018-05-01 17:06:20 -04005684void draw(SkCanvas* canvas) {
Cary Clarkbad5ad72017-08-03 17:14:08 -04005685 SkPaint paint;
5686 SkPictureRecorder recorder;
5687 SkCanvas* recordingCanvas = recorder.beginRecording(50, 50);
5688 for (auto color : { SK_ColorRED, SK_ColorBLUE, 0xff007f00 } ) {
5689 paint.setColor(color);
5690 recordingCanvas->drawRect({10, 10, 30, 40}, paint);
5691 recordingCanvas->translate(10, 10);
5692 recordingCanvas->scale(1.2f, 1.4f);
5693 }
5694 sk_sp<SkPicture> playback = recorder.finishRecordingAsPicture();
5695 SkMatrix matrix;
5696 matrix.reset();
5697 for (auto alpha : { 70, 140, 210 } ) {
5698 paint.setAlpha(alpha);
5699 canvas->drawPicture(playback, &matrix, &paint);
5700 matrix.preTranslate(70, 70);
5701 }
Cary Clark8032b982017-07-28 11:04:54 -04005702}
5703##
5704
Cary Clark2ade9972017-11-02 17:49:34 -04005705#SeeAlso drawDrawable SkPicture SkPicture::playback
Cary Clark8032b982017-07-28 11:04:54 -04005706
5707##
5708
5709# ------------------------------------------------------------------------------
5710
5711#Method void drawVertices(const SkVertices* vertices, SkBlendMode mode, const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05005712#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05005713#Line # draws Vertices, a triangle mesh ##
Cary Clark80247e52018-07-11 16:18:41 -04005714Draws Vertices vertices, a triangle mesh, using Clip and Matrix.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005715If Vertices_Texs and Vertices_Colors are defined in vertices, and Paint paint
5716contains Shader, Blend_Mode mode combines Vertices_Colors with Shader.
Cary Clark8032b982017-07-28 11:04:54 -04005717
Cary Clarkbad5ad72017-08-03 17:14:08 -04005718#Param vertices triangle mesh to draw ##
5719#Param mode combines Vertices_Colors with Shader, if both are present ##
5720#Param paint specifies the Shader, used as Vertices texture; may be nullptr ##
Cary Clark8032b982017-07-28 11:04:54 -04005721
5722#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04005723void draw(SkCanvas* canvas) {
5724 SkPaint paint;
5725 SkPoint points[] = { { 0, 0 }, { 250, 0 }, { 100, 100 }, { 0, 250 } };
5726 SkColor colors[] = { SK_ColorRED, SK_ColorBLUE, SK_ColorYELLOW, SK_ColorCYAN };
5727 auto vertices = SkVertices::MakeCopy(SkVertices::kTriangleFan_VertexMode,
5728 SK_ARRAY_COUNT(points), points, nullptr, colors);
5729 canvas->drawVertices(vertices.get(), SkBlendMode::kSrc, paint);
5730}
Cary Clark8032b982017-07-28 11:04:54 -04005731##
5732
Cary Clark2ade9972017-11-02 17:49:34 -04005733#SeeAlso drawPatch drawPicture
Cary Clark8032b982017-07-28 11:04:54 -04005734
5735##
5736
5737# ------------------------------------------------------------------------------
5738
5739#Method void drawVertices(const sk_sp<SkVertices>& vertices, SkBlendMode mode, const SkPaint& paint)
5740
Cary Clark80247e52018-07-11 16:18:41 -04005741Draws Vertices vertices, a triangle mesh, using Clip and Matrix.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005742If Vertices_Texs and Vertices_Colors are defined in vertices, and Paint paint
5743contains Shader, Blend_Mode mode combines Vertices_Colors with Shader.
Cary Clark8032b982017-07-28 11:04:54 -04005744
Cary Clarkbad5ad72017-08-03 17:14:08 -04005745#Param vertices triangle mesh to draw ##
5746#Param mode combines Vertices_Colors with Shader, if both are present ##
5747#Param paint specifies the Shader, used as Vertices texture, may be nullptr ##
Cary Clark8032b982017-07-28 11:04:54 -04005748
5749#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04005750void draw(SkCanvas* canvas) {
5751 SkPaint paint;
5752 SkPoint points[] = { { 0, 0 }, { 250, 0 }, { 100, 100 }, { 0, 250 } };
5753 SkPoint texs[] = { { 0, 0 }, { 0, 250 }, { 250, 250 }, { 250, 0 } };
5754 SkColor colors[] = { SK_ColorRED, SK_ColorBLUE, SK_ColorYELLOW, SK_ColorCYAN };
5755 paint.setShader(SkGradientShader::MakeLinear(points, colors, nullptr, 4,
5756 SkShader::kClamp_TileMode));
5757 auto vertices = SkVertices::MakeCopy(SkVertices::kTriangleFan_VertexMode,
5758 SK_ARRAY_COUNT(points), points, texs, colors);
Ruiqi Mao94d57c42018-07-02 15:20:10 -04005759 canvas->drawVertices(vertices, SkBlendMode::kDarken, paint);
5760}
5761##
5762
5763#SeeAlso drawPatch drawPicture
5764
5765##
5766
5767# ------------------------------------------------------------------------------
5768
5769#Method void drawVertices(const SkVertices* vertices, const SkMatrix* bones, int boneCount,
5770 SkBlendMode mode, const SkPaint& paint)
5771
Cary Clark80247e52018-07-11 16:18:41 -04005772Draws Vertices vertices, a triangle mesh, using Clip and Matrix. Bone data is used to
Ruiqi Mao94d57c42018-07-02 15:20:10 -04005773deform vertices with bone weights.
5774If Vertices_Texs and Vertices_Colors are defined in vertices, and Paint paint
5775contains Shader, Blend_Mode mode combines Vertices_Colors with Shader.
5776The first element of bones should be an object to world space transformation matrix that
5777will be applied before performing mesh deformations. If no such transformation is needed,
5778it should be the identity matrix.
Ruiqi Mao9a6e42f2018-07-09 14:16:56 -04005779boneCount must be at most 100, and thus the size of bones should be at most 100.
Ruiqi Mao94d57c42018-07-02 15:20:10 -04005780
5781#Param vertices triangle mesh to draw ##
5782#Param bones bone matrix data ##
5783#Param boneCount number of bone matrices ##
5784#Param mode combines Vertices_Colors with Shader, if both are present ##
5785#Param paint specifies the Shader, used as Vertices texture, may be nullptr ##
5786
5787#Example
5788void draw(SkCanvas* canvas) {
5789 SkPaint paint;
5790 SkPoint points[] = { { 0, 0 }, { 250, 0 }, { 100, 100 }, { 0, 250 } };
5791 SkPoint texs[] = { { 0, 0 }, { 0, 250 }, { 250, 250 }, { 250, 0 } };
5792 SkColor colors[] = { SK_ColorRED, SK_ColorBLUE, SK_ColorYELLOW, SK_ColorCYAN };
5793 SkVertices::BoneIndices boneIndices[] = { { 0, 0, 0, 0 },
5794 { 1, 0, 0, 0 },
5795 { 2, 0, 0, 0 },
5796 { 3, 0, 0, 0 } };
5797 SkVertices::BoneWeights boneWeights[] = { { 0.0f, 0.0f, 0.0f, 0.0f },
5798 { 1.0f, 0.0f, 0.0f, 0.0f },
5799 { 1.0f, 0.0f, 0.0f, 0.0f },
5800 { 1.0f, 0.0f, 0.0f, 0.0f } };
5801 SkMatrix bones[] = { SkMatrix::I(),
5802 SkMatrix::MakeTrans(0, 20),
5803 SkMatrix::MakeTrans(50, 50),
5804 SkMatrix::MakeTrans(20, 0) };
5805 paint.setShader(SkGradientShader::MakeLinear(points, colors, nullptr, 4,
5806 SkShader::kClamp_TileMode));
5807 auto vertices = SkVertices::MakeCopy(SkVertices::kTriangleFan_VertexMode,
5808 SK_ARRAY_COUNT(points), points, texs, colors, boneIndices, boneWeights);
5809 canvas->drawVertices(vertices.get(), bones, SK_ARRAY_COUNT(bones), SkBlendMode::kDarken, paint);
5810}
5811##
5812
5813#SeeAlso drawPatch drawPicture
5814
5815##
5816
5817# ------------------------------------------------------------------------------
5818
5819#Method void drawVertices(const sk_sp<SkVertices>& vertices, const SkMatrix* bones, int boneCount,
5820 SkBlendMode mode, const SkPaint& paint)
5821
Cary Clark80247e52018-07-11 16:18:41 -04005822Draws Vertices vertices, a triangle mesh, using Clip and Matrix. Bone data is used to
Ruiqi Mao94d57c42018-07-02 15:20:10 -04005823deform vertices with bone weights.
5824If Vertices_Texs and Vertices_Colors are defined in vertices, and Paint paint
5825contains Shader, Blend_Mode mode combines Vertices_Colors with Shader.
5826The first element of bones should be an object to world space transformation matrix that
5827will be applied before performing mesh deformations. If no such transformation is needed,
5828it should be the identity matrix.
Ruiqi Mao9a6e42f2018-07-09 14:16:56 -04005829boneCount must be at most 100, and thus the size of bones should be at most 100.
Ruiqi Mao94d57c42018-07-02 15:20:10 -04005830
5831#Param vertices triangle mesh to draw ##
5832#Param bones bone matrix data ##
5833#Param boneCount number of bone matrices ##
5834#Param mode combines Vertices_Colors with Shader, if both are present ##
5835#Param paint specifies the Shader, used as Vertices texture, may be nullptr ##
5836
5837#Example
5838void draw(SkCanvas* canvas) {
5839 SkPaint paint;
5840 SkPoint points[] = { { 0, 0 }, { 250, 0 }, { 100, 100 }, { 0, 250 } };
5841 SkPoint texs[] = { { 0, 0 }, { 0, 250 }, { 250, 250 }, { 250, 0 } };
5842 SkColor colors[] = { SK_ColorRED, SK_ColorBLUE, SK_ColorYELLOW, SK_ColorCYAN };
5843 SkVertices::BoneIndices boneIndices[] = { { 0, 0, 0, 0 },
5844 { 1, 0, 0, 0 },
5845 { 2, 0, 0, 0 },
5846 { 3, 0, 0, 0 } };
5847 SkVertices::BoneWeights boneWeights[] = { { 0.0f, 0.0f, 0.0f, 0.0f },
5848 { 1.0f, 0.0f, 0.0f, 0.0f },
5849 { 1.0f, 0.0f, 0.0f, 0.0f },
5850 { 1.0f, 0.0f, 0.0f, 0.0f } };
5851 SkMatrix bones[] = { SkMatrix::I(),
5852 SkMatrix::MakeTrans(0, 20),
5853 SkMatrix::MakeTrans(50, 50),
5854 SkMatrix::MakeTrans(20, 0) };
5855 paint.setShader(SkGradientShader::MakeLinear(points, colors, nullptr, 4,
5856 SkShader::kClamp_TileMode));
5857 auto vertices = SkVertices::MakeCopy(SkVertices::kTriangleFan_VertexMode,
5858 SK_ARRAY_COUNT(points), points, texs, colors, boneIndices, boneWeights);
5859 canvas->drawVertices(vertices, bones, SK_ARRAY_COUNT(bones), SkBlendMode::kDarken, paint);
Cary Clark8032b982017-07-28 11:04:54 -04005860}
5861##
5862
Cary Clark2ade9972017-11-02 17:49:34 -04005863#SeeAlso drawPatch drawPicture
Cary Clark8032b982017-07-28 11:04:54 -04005864
5865##
5866
5867# ------------------------------------------------------------------------------
5868
5869#Method void drawPatch(const SkPoint cubics[12], const SkColor colors[4],
5870 const SkPoint texCoords[4], SkBlendMode mode, const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05005871#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05005872#Line # draws Coons_Patch ##
Cary Clark8032b982017-07-28 11:04:54 -04005873
Herb Derbyefe39bc2018-05-01 17:06:20 -04005874Draws a Coons_Patch: the interpolation of four cubics with shared corners,
Cary Clark5538c132018-06-14 12:28:14 -04005875associating a color, and optionally a texture Point, with each corner.
Cary Clark8032b982017-07-28 11:04:54 -04005876
Cary Clarka560c472017-11-27 10:44:06 -05005877Coons_Patch uses Clip and Matrix, paint Shader, Color_Filter,
Cary Clarkbad5ad72017-08-03 17:14:08 -04005878Color_Alpha, Image_Filter, and Blend_Mode. If Shader is provided it is treated
Cary Clarka560c472017-11-27 10:44:06 -05005879as Coons_Patch texture; Blend_Mode mode combines Color colors and Shader if
Cary Clarkbad5ad72017-08-03 17:14:08 -04005880both are provided.
Cary Clark8032b982017-07-28 11:04:54 -04005881
Herb Derbyefe39bc2018-05-01 17:06:20 -04005882Point array cubics specifies four Cubics starting at the top-left corner,
Cary Clarkce101242017-09-01 15:51:02 -04005883in clockwise order, sharing every fourth point. The last Cubic ends at the
Cary Clarkbad5ad72017-08-03 17:14:08 -04005884first point.
Cary Clark8032b982017-07-28 11:04:54 -04005885
Cary Clarkbc5697d2017-10-04 14:31:33 -04005886Color array color associates colors with corners in top-left, top-right,
5887bottom-right, bottom-left order.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005888
5889If paint contains Shader, Point array texCoords maps Shader as texture to
Cary Clarkbc5697d2017-10-04 14:31:33 -04005890corners in top-left, top-right, bottom-right, bottom-left order.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005891
Cary Clarka523d2d2017-08-30 08:58:10 -04005892#Param cubics Path_Cubic array, sharing common points ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005893#Param colors Color array, one for each corner ##
Cary Clarkce101242017-09-01 15:51:02 -04005894#Param texCoords Point array of texture coordinates, mapping Shader to corners;
Herb Derbyefe39bc2018-05-01 17:06:20 -04005895 may be nullptr
Cary Clark579985c2017-07-31 11:48:27 -04005896#Param ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005897#Param mode Blend_Mode for colors, and for Shader if paint has one ##
5898#Param paint Shader, Color_Filter, Blend_Mode, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005899
5900#Example
5901#Image 5
Cary Clarkbad5ad72017-08-03 17:14:08 -04005902void draw(SkCanvas* canvas) {
5903 // SkBitmap source = cmbkygk;
5904 SkPaint paint;
5905 paint.setFilterQuality(kLow_SkFilterQuality);
5906 paint.setAntiAlias(true);
5907 SkPoint cubics[] = { { 3, 1 }, { 4, 2 }, { 5, 1 }, { 7, 3 },
5908 /* { 7, 3 }, */ { 6, 4 }, { 7, 5 }, { 5, 7 },
5909 /* { 5, 7 }, */ { 4, 6 }, { 3, 7 }, { 1, 5 },
5910 /* { 1, 5 }, */ { 2, 4 }, { 1, 3 }, /* { 3, 1 } */ };
5911 SkColor colors[] = { 0xbfff0000, 0xbf0000ff, 0xbfff00ff, 0xbf00ffff };
5912 SkPoint texCoords[] = { { -30, -30 }, { 162, -30}, { 162, 162}, { -30, 162} };
5913 paint.setShader(SkShader::MakeBitmapShader(source, SkShader::kClamp_TileMode,
5914 SkShader::kClamp_TileMode, nullptr));
5915 canvas->scale(15, 15);
5916 for (auto blend : { SkBlendMode::kSrcOver, SkBlendMode::kModulate, SkBlendMode::kXor } ) {
5917 canvas->drawPatch(cubics, colors, texCoords, blend, paint);
5918 canvas->translate(4, 4);
5919 }
Cary Clark8032b982017-07-28 11:04:54 -04005920}
5921##
5922
Cary Clark2ade9972017-11-02 17:49:34 -04005923#ToDo can patch use image filter? ##
5924#SeeAlso SeeAlso drawVertices drawPicture
Cary Clark8032b982017-07-28 11:04:54 -04005925
5926##
5927
5928# ------------------------------------------------------------------------------
5929
5930#Method void drawPatch(const SkPoint cubics[12], const SkColor colors[4],
Herb Derbyefe39bc2018-05-01 17:06:20 -04005931 const SkPoint texCoords[4], const SkPaint& paint)
Cary Clark8032b982017-07-28 11:04:54 -04005932
Herb Derbyefe39bc2018-05-01 17:06:20 -04005933Draws Cubic Coons_Patch: the interpolation of four cubics with shared corners,
Cary Clark5538c132018-06-14 12:28:14 -04005934associating a color, and optionally a texture Point, with each corner.
Cary Clark8032b982017-07-28 11:04:54 -04005935
Cary Clarka560c472017-11-27 10:44:06 -05005936Coons_Patch uses Clip and Matrix, paint Shader, Color_Filter,
Cary Clarkbad5ad72017-08-03 17:14:08 -04005937Color_Alpha, Image_Filter, and Blend_Mode. If Shader is provided it is treated
Cary Clarka560c472017-11-27 10:44:06 -05005938as Coons_Patch texture; Blend_Mode mode combines Color colors and Shader if
Cary Clarkbad5ad72017-08-03 17:14:08 -04005939both are provided.
Cary Clark8032b982017-07-28 11:04:54 -04005940
Herb Derbyefe39bc2018-05-01 17:06:20 -04005941Point array cubics specifies four Cubics starting at the top-left corner,
Cary Clarkce101242017-09-01 15:51:02 -04005942in clockwise order, sharing every fourth point. The last Cubic ends at the
Cary Clarkbad5ad72017-08-03 17:14:08 -04005943first point.
5944
Cary Clarkbc5697d2017-10-04 14:31:33 -04005945Color array color associates colors with corners in top-left, top-right,
5946bottom-right, bottom-left order.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005947
5948If paint contains Shader, Point array texCoords maps Shader as texture to
Cary Clarkbc5697d2017-10-04 14:31:33 -04005949corners in top-left, top-right, bottom-right, bottom-left order.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005950
Cary Clarka523d2d2017-08-30 08:58:10 -04005951#Param cubics Path_Cubic array, sharing common points ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005952#Param colors Color array, one for each corner ##
Cary Clarkce101242017-09-01 15:51:02 -04005953#Param texCoords Point array of texture coordinates, mapping Shader to corners;
Herb Derbyefe39bc2018-05-01 17:06:20 -04005954 may be nullptr
Cary Clark579985c2017-07-31 11:48:27 -04005955#Param ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005956#Param paint Shader, Color_Filter, Blend_Mode, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005957
5958#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04005959void draw(SkCanvas* canvas) {
5960 SkPaint paint;
5961 paint.setAntiAlias(true);
5962 SkPoint cubics[] = { { 3, 1 }, { 4, 2 }, { 5, 1 }, { 7, 3 },
5963 /* { 7, 3 }, */ { 6, 4 }, { 7, 5 }, { 5, 7 },
5964 /* { 5, 7 }, */ { 4, 6 }, { 3, 7 }, { 1, 5 },
5965 /* { 1, 5 }, */ { 2, 4 }, { 1, 3 }, /* { 3, 1 } */ };
5966 SkColor colors[] = { SK_ColorRED, SK_ColorBLUE, SK_ColorYELLOW, SK_ColorCYAN };
5967 canvas->scale(30, 30);
5968 canvas->drawPatch(cubics, colors, nullptr, paint);
5969 SkPoint text[] = { {3,0.9f}, {4,2.5f}, {5,0.9f}, {7.5f,3.2f}, {5.5f,4.2f},
5970 {7.5f,5.2f}, {5,7.5f}, {4,5.9f}, {3,7.5f}, {0.5f,5.2f}, {2.5f,4.2f},
5971 {0.5f,3.2f} };
5972 paint.setTextSize(18.f / 30);
5973 paint.setTextAlign(SkPaint::kCenter_Align);
5974 for (int i = 0; i< 10; ++i) {
5975 char digit = '0' + i;
5976 canvas->drawText(&digit, 1, text[i].fX, text[i].fY, paint);
5977 }
5978 canvas->drawString("10", text[10].fX, text[10].fY, paint);
5979 canvas->drawString("11", text[11].fX, text[11].fY, paint);
5980 paint.setStyle(SkPaint::kStroke_Style);
5981 canvas->drawPoints(SkCanvas::kPolygon_PointMode, 12, cubics, paint);
5982 canvas->drawLine(cubics[11].fX, cubics[11].fY, cubics[0].fX, cubics[0].fY, paint);
Cary Clark8032b982017-07-28 11:04:54 -04005983}
5984##
5985
5986#Example
5987#Image 6
Cary Clarkbad5ad72017-08-03 17:14:08 -04005988void draw(SkCanvas* canvas) {
5989 // SkBitmap source = checkerboard;
5990 SkPaint paint;
5991 paint.setFilterQuality(kLow_SkFilterQuality);
5992 paint.setAntiAlias(true);
5993 SkPoint cubics[] = { { 3, 1 }, { 4, 2 }, { 5, 1 }, { 7, 3 },
5994 /* { 7, 3 }, */ { 6, 4 }, { 7, 5 }, { 5, 7 },
5995 /* { 5, 7 }, */ { 4, 6 }, { 3, 7 }, { 1, 5 },
5996 /* { 1, 5 }, */ { 2, 4 }, { 1, 3 }, /* { 3, 1 } */ };
5997 SkPoint texCoords[] = { { 0, 0 }, { 0, 62}, { 62, 62}, { 62, 0 } };
5998 paint.setShader(SkShader::MakeBitmapShader(source, SkShader::kClamp_TileMode,
5999 SkShader::kClamp_TileMode, nullptr));
6000 canvas->scale(30, 30);
6001 canvas->drawPatch(cubics, nullptr, texCoords, paint);
Cary Clark8032b982017-07-28 11:04:54 -04006002}
6003##
6004
Cary Clark2ade9972017-11-02 17:49:34 -04006005#ToDo can patch use image filter? ##
6006#SeeAlso SeeAlso drawVertices drawPicture
Cary Clark8032b982017-07-28 11:04:54 -04006007
6008##
6009
6010# ------------------------------------------------------------------------------
6011
6012#Method void drawAtlas(const SkImage* atlas, const SkRSXform xform[], const SkRect tex[],
6013 const SkColor colors[], int count, SkBlendMode mode, const SkRect* cullRect,
6014 const SkPaint* paint)
Cary Clark78de7512018-02-07 07:27:09 -05006015#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05006016#Line # draws sprites using Clip, Matrix, and Paint ##
Cary Clark8032b982017-07-28 11:04:54 -04006017
Cary Clark80247e52018-07-11 16:18:41 -04006018Draws a set of sprites from atlas, using Clip, Matrix, and optional Paint paint.
Cary Clarkffb3d682018-05-17 12:17:28 -04006019paint uses Anti_Alias, Color_Alpha, Color_Filter, Image_Filter, and Blend_Mode
Cary Clarkbad5ad72017-08-03 17:14:08 -04006020to draw, if present. For each entry in the array, Rect tex locates sprite in
6021atlas, and RSXform xform transforms it into destination space.
6022
Cary Clark8032b982017-07-28 11:04:54 -04006023xform, text, and colors if present, must contain count entries.
Cary Clark224c7002018-06-27 11:00:21 -04006024Optional colors are applied for each sprite using Blend_Mode mode, treating
6025sprite as source and colors as destination.
Herb Derbyefe39bc2018-05-01 17:06:20 -04006026Optional cullRect is a conservative bounds of all transformed sprites.
Cary Clarkce101242017-09-01 15:51:02 -04006027If cullRect is outside of Clip, canvas can skip drawing.
Cary Clark8032b982017-07-28 11:04:54 -04006028
Cary Clark224c7002018-06-27 11:00:21 -04006029
6030
Cary Clarkbad5ad72017-08-03 17:14:08 -04006031#Param atlas Image containing sprites ##
6032#Param xform RSXform mappings for sprites in atlas ##
6033#Param tex Rect locations of sprites in atlas ##
Cary Clark6fc50412017-09-21 12:31:06 -04006034#Param colors one per sprite, blended with sprite using Blend_Mode; may be nullptr ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04006035#Param count number of sprites to draw ##
6036#Param mode Blend_Mode combining colors and sprites ##
Cary Clark6fc50412017-09-21 12:31:06 -04006037#Param cullRect bounds of transformed sprites for efficient clipping; may be nullptr ##
6038#Param paint Color_Filter, Image_Filter, Blend_Mode, and so on; may be nullptr ##
Cary Clark8032b982017-07-28 11:04:54 -04006039
6040#Example
6041#Image 3
Cary Clarkbad5ad72017-08-03 17:14:08 -04006042void draw(SkCanvas* canvas) {
6043 // SkBitmap source = mandrill;
6044 SkRSXform xforms[] = { { .5f, 0, 0, 0 }, {0, .5f, 200, 100 } };
6045 SkRect tex[] = { { 0, 0, 250, 250 }, { 0, 0, 250, 250 } };
6046 SkColor colors[] = { 0x7f55aa00, 0x7f3333bf };
6047 const SkImage* imagePtr = image.get();
6048 canvas->drawAtlas(imagePtr, xforms, tex, colors, 2, SkBlendMode::kSrcOver, nullptr, nullptr);
Cary Clark8032b982017-07-28 11:04:54 -04006049}
6050##
6051
Cary Clark2ade9972017-11-02 17:49:34 -04006052#SeeAlso drawBitmap drawImage
Cary Clark8032b982017-07-28 11:04:54 -04006053
6054##
6055
6056# ------------------------------------------------------------------------------
6057
6058#Method void drawAtlas(const sk_sp<SkImage>& atlas, const SkRSXform xform[], const SkRect tex[],
6059 const SkColor colors[], int count, SkBlendMode mode, const SkRect* cullRect,
Herb Derbyefe39bc2018-05-01 17:06:20 -04006060 const SkPaint* paint)
Cary Clark8032b982017-07-28 11:04:54 -04006061
Cary Clark80247e52018-07-11 16:18:41 -04006062Draws a set of sprites from atlas, using Clip, Matrix, and optional Paint paint.
Cary Clarkffb3d682018-05-17 12:17:28 -04006063paint uses Anti_Alias, Color_Alpha, Color_Filter, Image_Filter, and Blend_Mode
Cary Clarkbad5ad72017-08-03 17:14:08 -04006064to draw, if present. For each entry in the array, Rect tex locates sprite in
6065atlas, and RSXform xform transforms it into destination space.
6066
Cary Clark8032b982017-07-28 11:04:54 -04006067xform, text, and colors if present, must contain count entries.
6068Optional colors is applied for each sprite using Blend_Mode.
Herb Derbyefe39bc2018-05-01 17:06:20 -04006069Optional cullRect is a conservative bounds of all transformed sprites.
Cary Clarkce101242017-09-01 15:51:02 -04006070If cullRect is outside of Clip, canvas can skip drawing.
Cary Clark8032b982017-07-28 11:04:54 -04006071
Cary Clarkbad5ad72017-08-03 17:14:08 -04006072#Param atlas Image containing sprites ##
6073#Param xform RSXform mappings for sprites in atlas ##
6074#Param tex Rect locations of sprites in atlas ##
Cary Clark6fc50412017-09-21 12:31:06 -04006075#Param colors one per sprite, blended with sprite using Blend_Mode; may be nullptr ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04006076#Param count number of sprites to draw ##
6077#Param mode Blend_Mode combining colors and sprites ##
Cary Clark6fc50412017-09-21 12:31:06 -04006078#Param cullRect bounds of transformed sprites for efficient clipping; may be nullptr ##
6079#Param paint Color_Filter, Image_Filter, Blend_Mode, and so on; may be nullptr ##
Cary Clark8032b982017-07-28 11:04:54 -04006080
6081#Example
6082#Image 3
Cary Clarkbad5ad72017-08-03 17:14:08 -04006083void draw(SkCanvas* canvas) {
6084 // SkBitmap source = mandrill;
6085 SkRSXform xforms[] = { { .5f, 0, 0, 0 }, {0, .5f, 200, 100 } };
6086 SkRect tex[] = { { 0, 0, 250, 250 }, { 0, 0, 250, 250 } };
6087 SkColor colors[] = { 0x7f55aa00, 0x7f3333bf };
6088 SkPaint paint;
6089 paint.setAlpha(127);
6090 canvas->drawAtlas(image, xforms, tex, colors, 2, SkBlendMode::kPlus, nullptr, &paint);
Cary Clark8032b982017-07-28 11:04:54 -04006091}
6092##
6093
6094#ToDo bug in example on cpu side, gpu looks ok ##
6095
Cary Clark2ade9972017-11-02 17:49:34 -04006096#SeeAlso drawBitmap drawImage
6097
Cary Clark8032b982017-07-28 11:04:54 -04006098##
6099
6100# ------------------------------------------------------------------------------
6101
6102#Method void drawAtlas(const SkImage* atlas, const SkRSXform xform[], const SkRect tex[], int count,
Herb Derbyefe39bc2018-05-01 17:06:20 -04006103 const SkRect* cullRect, const SkPaint* paint)
Cary Clark8032b982017-07-28 11:04:54 -04006104
Cary Clark80247e52018-07-11 16:18:41 -04006105Draws a set of sprites from atlas, using Clip, Matrix, and optional Paint paint.
Cary Clarkffb3d682018-05-17 12:17:28 -04006106paint uses Anti_Alias, Color_Alpha, Color_Filter, Image_Filter, and Blend_Mode
Cary Clarkbad5ad72017-08-03 17:14:08 -04006107to draw, if present. For each entry in the array, Rect tex locates sprite in
6108atlas, and RSXform xform transforms it into destination space.
6109
Cary Clark8032b982017-07-28 11:04:54 -04006110xform and text must contain count entries.
Herb Derbyefe39bc2018-05-01 17:06:20 -04006111Optional cullRect is a conservative bounds of all transformed sprites.
Cary Clarkce101242017-09-01 15:51:02 -04006112If cullRect is outside of Clip, canvas can skip drawing.
Cary Clark8032b982017-07-28 11:04:54 -04006113
Cary Clarkbad5ad72017-08-03 17:14:08 -04006114#Param atlas Image containing sprites ##
6115#Param xform RSXform mappings for sprites in atlas ##
6116#Param tex Rect locations of sprites in atlas ##
6117#Param count number of sprites to draw ##
Cary Clark6fc50412017-09-21 12:31:06 -04006118#Param cullRect bounds of transformed sprites for efficient clipping; may be nullptr ##
6119#Param paint Color_Filter, Image_Filter, Blend_Mode, and so on; may be nullptr ##
Cary Clark8032b982017-07-28 11:04:54 -04006120
6121#Example
6122#Image 3
Cary Clarkbad5ad72017-08-03 17:14:08 -04006123void draw(SkCanvas* canvas) {
6124 // sk_sp<SkImage> image = mandrill;
6125 SkRSXform xforms[] = { { .5f, 0, 0, 0 }, {0, .5f, 200, 100 } };
6126 SkRect tex[] = { { 0, 0, 250, 250 }, { 0, 0, 250, 250 } };
6127 const SkImage* imagePtr = image.get();
6128 canvas->drawAtlas(imagePtr, xforms, tex, 2, nullptr, nullptr);
Cary Clark8032b982017-07-28 11:04:54 -04006129}
6130##
6131
Cary Clark2ade9972017-11-02 17:49:34 -04006132#SeeAlso drawBitmap drawImage
Cary Clark8032b982017-07-28 11:04:54 -04006133
6134##
6135
6136# ------------------------------------------------------------------------------
6137
6138#Method void drawAtlas(const sk_sp<SkImage>& atlas, const SkRSXform xform[], const SkRect tex[],
Herb Derbyefe39bc2018-05-01 17:06:20 -04006139 int count, const SkRect* cullRect, const SkPaint* paint)
Cary Clark8032b982017-07-28 11:04:54 -04006140
Cary Clark80247e52018-07-11 16:18:41 -04006141Draws a set of sprites from atlas, using Clip, Matrix, and optional Paint paint.
Cary Clarkffb3d682018-05-17 12:17:28 -04006142paint uses Anti_Alias, Color_Alpha, Color_Filter, Image_Filter, and Blend_Mode
Cary Clarkbad5ad72017-08-03 17:14:08 -04006143to draw, if present. For each entry in the array, Rect tex locates sprite in
6144atlas, and RSXform xform transforms it into destination space.
6145
Cary Clark8032b982017-07-28 11:04:54 -04006146xform and text must contain count entries.
Herb Derbyefe39bc2018-05-01 17:06:20 -04006147Optional cullRect is a conservative bounds of all transformed sprites.
Cary Clarkce101242017-09-01 15:51:02 -04006148If cullRect is outside of Clip, canvas can skip drawing.
Cary Clark8032b982017-07-28 11:04:54 -04006149
Cary Clarkbad5ad72017-08-03 17:14:08 -04006150#Param atlas Image containing sprites ##
6151#Param xform RSXform mappings for sprites in atlas ##
6152#Param tex Rect locations of sprites in atlas ##
6153#Param count number of sprites to draw ##
Cary Clark6fc50412017-09-21 12:31:06 -04006154#Param cullRect bounds of transformed sprites for efficient clipping; may be nullptr ##
6155#Param paint Color_Filter, Image_Filter, Blend_Mode, and so on; may be nullptr ##
Cary Clark8032b982017-07-28 11:04:54 -04006156
6157#Example
6158#Image 3
Cary Clarkbad5ad72017-08-03 17:14:08 -04006159void draw(SkCanvas* canvas) {
6160 // sk_sp<SkImage> image = mandrill;
6161 SkRSXform xforms[] = { { 1, 0, 0, 0 }, {0, 1, 300, 100 } };
6162 SkRect tex[] = { { 0, 0, 200, 200 }, { 200, 0, 400, 200 } };
6163 canvas->drawAtlas(image, xforms, tex, 2, nullptr, nullptr);
Cary Clark8032b982017-07-28 11:04:54 -04006164}
6165##
6166
Cary Clark2ade9972017-11-02 17:49:34 -04006167#SeeAlso drawBitmap drawImage
Cary Clark8032b982017-07-28 11:04:54 -04006168
6169##
6170
6171# ------------------------------------------------------------------------------
6172
Cary Clark73fa9722017-08-29 17:36:51 -04006173#Method void drawDrawable(SkDrawable* drawable, const SkMatrix* matrix = nullptr)
Cary Clark78de7512018-02-07 07:27:09 -05006174#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05006175#Line # draws Drawable, encapsulated drawing commands ##
Cary Clark80247e52018-07-11 16:18:41 -04006176Draws Drawable drawable using Clip and Matrix, concatenated with
Cary Clark8032b982017-07-28 11:04:54 -04006177optional matrix.
6178
Herb Derbyefe39bc2018-05-01 17:06:20 -04006179If Canvas has an asynchronous implementation, as is the case
Cary Clark8032b982017-07-28 11:04:54 -04006180when it is recording into Picture, then drawable will be referenced,
6181so that SkDrawable::draw() can be called when the operation is finalized. To force
6182immediate drawing, call SkDrawable::draw() instead.
6183
Cary Clarkbad5ad72017-08-03 17:14:08 -04006184#Param drawable custom struct encapsulating drawing commands ##
6185#Param matrix transformation applied to drawing; may be nullptr ##
Cary Clark8032b982017-07-28 11:04:54 -04006186
6187#Example
6188#Height 100
6189#Function
Cary Clarkbad5ad72017-08-03 17:14:08 -04006190struct MyDrawable : public SkDrawable {
6191 SkRect onGetBounds() override { return SkRect::MakeWH(50, 100); }
6192
6193 void onDraw(SkCanvas* canvas) override {
6194 SkPath path;
6195 path.conicTo(10, 90, 50, 90, 0.9f);
6196 SkPaint paint;
6197 paint.setColor(SK_ColorBLUE);
6198 canvas->drawRect(path.getBounds(), paint);
6199 paint.setAntiAlias(true);
6200 paint.setColor(SK_ColorWHITE);
6201 canvas->drawPath(path, paint);
6202 }
6203};
6204
6205#Function ##
6206void draw(SkCanvas* canvas) {
6207 sk_sp<SkDrawable> drawable(new MyDrawable);
6208 SkMatrix matrix;
6209 matrix.setTranslate(10, 10);
6210 canvas->drawDrawable(drawable.get(), &matrix);
Cary Clark8032b982017-07-28 11:04:54 -04006211}
6212##
6213
Cary Clark2ade9972017-11-02 17:49:34 -04006214#SeeAlso SkDrawable drawPicture
Cary Clark8032b982017-07-28 11:04:54 -04006215
6216##
6217
6218# ------------------------------------------------------------------------------
6219
6220#Method void drawDrawable(SkDrawable* drawable, SkScalar x, SkScalar y)
6221
Cary Clark80247e52018-07-11 16:18:41 -04006222Draws Drawable drawable using Clip and Matrix, offset by (x, y).
Cary Clark8032b982017-07-28 11:04:54 -04006223
Herb Derbyefe39bc2018-05-01 17:06:20 -04006224If Canvas has an asynchronous implementation, as is the case
Cary Clark8032b982017-07-28 11:04:54 -04006225when it is recording into Picture, then drawable will be referenced,
6226so that SkDrawable::draw() can be called when the operation is finalized. To force
6227immediate drawing, call SkDrawable::draw() instead.
6228
Cary Clarkbad5ad72017-08-03 17:14:08 -04006229#Param drawable custom struct encapsulating drawing commands ##
Cary Clark5538c132018-06-14 12:28:14 -04006230#Param x offset into Canvas writable pixels on x-axis ##
6231#Param y offset into Canvas writable pixels on y-axis ##
Cary Clark8032b982017-07-28 11:04:54 -04006232
6233#Example
6234#Height 100
6235#Function
Cary Clarkbad5ad72017-08-03 17:14:08 -04006236struct MyDrawable : public SkDrawable {
6237 SkRect onGetBounds() override { return SkRect::MakeWH(50, 100); }
6238
6239 void onDraw(SkCanvas* canvas) override {
6240 SkPath path;
6241 path.conicTo(10, 90, 50, 90, 0.9f);
6242 SkPaint paint;
6243 paint.setColor(SK_ColorBLUE);
6244 canvas->drawRect(path.getBounds(), paint);
6245 paint.setAntiAlias(true);
6246 paint.setColor(SK_ColorWHITE);
6247 canvas->drawPath(path, paint);
6248 }
6249};
6250
6251#Function ##
6252void draw(SkCanvas* canvas) {
6253 sk_sp<SkDrawable> drawable(new MyDrawable);
6254 canvas->drawDrawable(drawable.get(), 10, 10);
Cary Clark8032b982017-07-28 11:04:54 -04006255}
6256##
6257
Cary Clark2ade9972017-11-02 17:49:34 -04006258#SeeAlso SkDrawable drawPicture
Cary Clark8032b982017-07-28 11:04:54 -04006259
6260##
6261
6262# ------------------------------------------------------------------------------
6263
6264#Method void drawAnnotation(const SkRect& rect, const char key[], SkData* value)
Cary Clark78de7512018-02-07 07:27:09 -05006265#In Draw
6266#In Utility
Cary Clarkab2621d2018-01-30 10:08:57 -05006267#Line # associates a Rect with a key-value pair ##
Cary Clark80247e52018-07-11 16:18:41 -04006268Associates Rect on Canvas with an annotation; a key-value pair, where the key is
Cary Clark8032b982017-07-28 11:04:54 -04006269a null-terminated utf8 string, and optional value is stored as Data.
6270
Herb Derbyefe39bc2018-05-01 17:06:20 -04006271Only some canvas implementations, such as recording to Picture, or drawing to
Cary Clark8032b982017-07-28 11:04:54 -04006272Document_PDF, use annotations.
6273
Cary Clarkbad5ad72017-08-03 17:14:08 -04006274#Param rect Rect extent of canvas to annotate ##
6275#Param key string used for lookup ##
6276#Param value data holding value stored in annotation ##
Cary Clark8032b982017-07-28 11:04:54 -04006277
6278#Example
6279 #Height 1
6280 const char text[] = "Click this link!";
6281 SkRect bounds;
6282 SkPaint paint;
6283 paint.setTextSize(40);
6284 (void)paint.measureText(text, strlen(text), &bounds);
6285 const char url[] = "https://www.google.com/";
6286 sk_sp<SkData> urlData(SkData::MakeWithCString(url));
6287 canvas->drawAnnotation(bounds, "url_key", urlData.get());
6288##
6289
Cary Clark2ade9972017-11-02 17:49:34 -04006290#SeeAlso SkPicture SkDocument
Cary Clark8032b982017-07-28 11:04:54 -04006291
6292##
6293
6294# ------------------------------------------------------------------------------
6295
Herb Derbyefe39bc2018-05-01 17:06:20 -04006296#Method void drawAnnotation(const SkRect& rect, const char key[], const sk_sp<SkData>& value)
Cary Clark8032b982017-07-28 11:04:54 -04006297
Cary Clark80247e52018-07-11 16:18:41 -04006298Associates Rect on Canvas when an annotation; a key-value pair, where the key is
Cary Clark8032b982017-07-28 11:04:54 -04006299a null-terminated utf8 string, and optional value is stored as Data.
6300
Herb Derbyefe39bc2018-05-01 17:06:20 -04006301Only some canvas implementations, such as recording to Picture, or drawing to
Cary Clark8032b982017-07-28 11:04:54 -04006302Document_PDF, use annotations.
6303
Cary Clarkbad5ad72017-08-03 17:14:08 -04006304#Param rect Rect extent of canvas to annotate ##
6305#Param key string used for lookup ##
6306#Param value data holding value stored in annotation ##
Cary Clark8032b982017-07-28 11:04:54 -04006307
6308#Example
6309#Height 1
6310 const char text[] = "Click this link!";
6311 SkRect bounds;
6312 SkPaint paint;
6313 paint.setTextSize(40);
6314 (void)paint.measureText(text, strlen(text), &bounds);
6315 const char url[] = "https://www.google.com/";
6316 sk_sp<SkData> urlData(SkData::MakeWithCString(url));
6317 canvas->drawAnnotation(bounds, "url_key", urlData.get());
6318##
6319
Cary Clark2ade9972017-11-02 17:49:34 -04006320#SeeAlso SkPicture SkDocument
Cary Clark8032b982017-07-28 11:04:54 -04006321
6322##
6323
6324#Method SkDrawFilter* getDrawFilter() const
Cary Clark4855f782018-02-06 09:41:53 -05006325#Deprecated soon
Cary Clark8032b982017-07-28 11:04:54 -04006326##
6327
6328#Method virtual SkDrawFilter* setDrawFilter(SkDrawFilter* filter)
Cary Clark4855f782018-02-06 09:41:53 -05006329#Deprecated soon
Cary Clark8032b982017-07-28 11:04:54 -04006330##
6331
6332# ------------------------------------------------------------------------------
6333
6334#Method virtual bool isClipEmpty() const
Cary Clark78de7512018-02-07 07:27:09 -05006335#In Property
Cary Clarkab2621d2018-01-30 10:08:57 -05006336#Line # returns if Clip is empty ##
Cary Clark8032b982017-07-28 11:04:54 -04006337Returns true if Clip is empty; that is, nothing will draw.
6338
Cary Clarkbad5ad72017-08-03 17:14:08 -04006339May do work when called; it should not be called
Cary Clark8032b982017-07-28 11:04:54 -04006340more often than needed. However, once called, subsequent calls perform no
6341work until Clip changes.
6342
Cary Clarkbad5ad72017-08-03 17:14:08 -04006343#Return true if Clip is empty ##
Cary Clark8032b982017-07-28 11:04:54 -04006344
6345#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04006346 void draw(SkCanvas* canvas) {
6347 SkDebugf("clip is%s empty\n", canvas->isClipEmpty() ? "" : " not");
6348 SkPath path;
6349 canvas->clipPath(path);
6350 SkDebugf("clip is%s empty\n", canvas->isClipEmpty() ? "" : " not");
Cary Clark8032b982017-07-28 11:04:54 -04006351 }
6352 #StdOut
Cary Clarkbad5ad72017-08-03 17:14:08 -04006353 clip is not empty
Cary Clark8032b982017-07-28 11:04:54 -04006354 clip is empty
6355 ##
6356##
6357
Cary Clark2ade9972017-11-02 17:49:34 -04006358#SeeAlso isClipRect getLocalClipBounds getDeviceClipBounds
Cary Clark8032b982017-07-28 11:04:54 -04006359
6360##
6361
6362# ------------------------------------------------------------------------------
6363
6364#Method virtual bool isClipRect() const
Cary Clark78de7512018-02-07 07:27:09 -05006365#In Property
Cary Clarkab2621d2018-01-30 10:08:57 -05006366#Line # returns if Clip is Rect and not empty ##
Cary Clark8032b982017-07-28 11:04:54 -04006367Returns true if Clip is Rect and not empty.
6368Returns false if the clip is empty, or if it is not Rect.
6369
Cary Clarkbad5ad72017-08-03 17:14:08 -04006370#Return true if Clip is Rect and not empty ##
Cary Clark8032b982017-07-28 11:04:54 -04006371
6372#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04006373 void draw(SkCanvas* canvas) {
6374 SkDebugf("clip is%s rect\n", canvas->isClipRect() ? "" : " not");
6375 canvas->clipRect({0, 0, 0, 0});
6376 SkDebugf("clip is%s rect\n", canvas->isClipRect() ? "" : " not");
Cary Clark8032b982017-07-28 11:04:54 -04006377 }
6378 #StdOut
Cary Clarkbad5ad72017-08-03 17:14:08 -04006379 clip is rect
Cary Clark8032b982017-07-28 11:04:54 -04006380 clip is not rect
6381 ##
6382##
6383
Cary Clark2ade9972017-11-02 17:49:34 -04006384#SeeAlso isClipEmpty getLocalClipBounds getDeviceClipBounds
Cary Clark8032b982017-07-28 11:04:54 -04006385
6386##
6387
6388#Class SkCanvas ##
Cary Clark884dd7d2017-10-11 10:37:52 -04006389
Cary Clark8032b982017-07-28 11:04:54 -04006390#Topic Canvas ##