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