blob: 0bce15e947746ab4baed751fa77d27615a2faf3a [file] [log] [blame]
Cary Clark8032b982017-07-28 11:04:54 -04001#Topic Canvas
Cary Clark12799e12017-07-28 15:18:29 -04002#Alias Canvas_Reference
Cary Clark8032b982017-07-28 11:04:54 -04003
Cary Clark08895c42018-02-01 09:37:32 -05004#Subtopic Overview
Cary Clark4855f782018-02-06 09:41:53 -05005 #Subtopic Subtopic
Cary Clark08895c42018-02-01 09:37:32 -05006 #Populate
7 ##
8##
9
Cary Clarke4aa3712017-09-15 02:56:12 -040010#Class SkCanvas
11
Cary Clark8032b982017-07-28 11:04:54 -040012Canvas provides an interface for drawing, and how the drawing is clipped and transformed.
13Canvas contains a stack of Matrix and Clip values.
14
15Canvas and Paint together provide the state to draw into Surface or Device.
Cary Clarkbad5ad72017-08-03 17:14:08 -040016Each Canvas draw call transforms the geometry of the object by the concatenation of all
17Matrix values in the stack. The transformed geometry is clipped by the intersection
18of all of Clip values in the stack. The Canvas draw calls use Paint to supply drawing
19state such as Color, Typeface, text size, stroke width, Shader and so on.
Cary Clark8032b982017-07-28 11:04:54 -040020
Mike Klein9ff8c8c2018-02-07 01:58:51 +000021To draw to a pixel-based destination, create Raster_Surface or GPU_Surface.
22Request Canvas from Surface to obtain the interface to draw.
23Canvas generated by Raster_Surface draws to memory visible to the CPU.
Cary Clark8032b982017-07-28 11:04:54 -040024Canvas generated by GPU_Surface uses Vulkan or OpenGL to draw to the GPU.
25
Cary Clarkbad5ad72017-08-03 17:14:08 -040026To draw to a document, obtain Canvas from SVG_Canvas, Document_PDF, or Picture_Recorder.
Cary Clarkce101242017-09-01 15:51:02 -040027Document based Canvas and other Canvas Subclasses reference Device describing the
Cary Clarkbad5ad72017-08-03 17:14:08 -040028destination.
29
Cary Clark8032b982017-07-28 11:04:54 -040030Canvas can be constructed to draw to Bitmap without first creating Raster_Surface.
Mike Klein9ff8c8c2018-02-07 01:58:51 +000031This approach may be deprecated in the future.
Cary Clark8032b982017-07-28 11:04:54 -040032
Cary Clark4855f782018-02-06 09:41:53 -050033#Subtopic Related_Function
Cary Clark08895c42018-02-01 09:37:32 -050034#Populate
35##
Cary Clark8032b982017-07-28 11:04:54 -040036
Cary Clark4855f782018-02-06 09:41:53 -050037#Subtopic Constant
Cary Clark08895c42018-02-01 09:37:32 -050038#Populate
39##
Cary Clark8032b982017-07-28 11:04:54 -040040
Cary Clark4855f782018-02-06 09:41:53 -050041#Subtopic Class_or_Struct
Cary Clark08895c42018-02-01 09:37:32 -050042#Populate
43##
Cary Clark8032b982017-07-28 11:04:54 -040044
Cary Clark4855f782018-02-06 09:41:53 -050045#Subtopic Constructor
Cary Clark8032b982017-07-28 11:04:54 -040046
Cary Clark4855f782018-02-06 09:41:53 -050047Create the desired type of Surface to obtain its Canvas when possible. Useful
Cary Clark8032b982017-07-28 11:04:54 -040048when no Surface is required, and some helpers implicitly create Raster_Surface.
49
Cary Clark08895c42018-02-01 09:37:32 -050050#Populate
51##
Cary Clark8032b982017-07-28 11:04:54 -040052
Cary Clark4855f782018-02-06 09:41:53 -050053#Subtopic Member_Function
Cary Clark08895c42018-02-01 09:37:32 -050054#Populate
55##
Cary Clark8032b982017-07-28 11:04:54 -040056
57# ------------------------------------------------------------------------------
58
Cary Clarka560c472017-11-27 10:44:06 -050059#Method static std::unique_ptr<SkCanvas> MakeRasterDirect(const SkImageInfo& info, void* pixels,
60 size_t rowBytes,
61 const SkSurfaceProps* props = nullptr)
Cary Clark78de7512018-02-07 07:27:09 -050062#In Constructor
Cary Clarkab2621d2018-01-30 10:08:57 -050063#Line # creates from SkImageInfo and Pixel_Storage ##
Cary Clark8032b982017-07-28 11:04:54 -040064
Cary Clarkbad5ad72017-08-03 17:14:08 -040065Allocates raster Canvas that will draw directly into pixels.
Cary Clark8032b982017-07-28 11:04:54 -040066
Cary Clarkbad5ad72017-08-03 17:14:08 -040067Canvas is returned if all parameters are valid.
68Valid parameters include:
69info dimensions are zero or positive;
Cary Clark2dc84ad2018-01-26 12:56:22 -050070info contains Color_Type and Alpha_Type supported by Raster_Surface;
Cary Clarkbad5ad72017-08-03 17:14:08 -040071pixels is not nullptr;
Cary Clark2dc84ad2018-01-26 12:56:22 -050072rowBytes is zero or large enough to contain info width pixels of Color_Type.
Cary Clarkbad5ad72017-08-03 17:14:08 -040073
Mike Klein9ff8c8c2018-02-07 01:58:51 +000074Pass zero for rowBytes to compute rowBytes from info width and size of pixel.
Cary Clarkf05bdda2017-08-24 12:59:48 -040075If rowBytes is greater than zero, it must be equal to or greater than
Cary Clark2dc84ad2018-01-26 12:56:22 -050076info width times bytes required for Color_Type.
Cary Clarkf05bdda2017-08-24 12:59:48 -040077
78Pixel buffer size should be info height times computed rowBytes.
Cary Clarka560c472017-11-27 10:44:06 -050079Pixels are not initialized.
80To access pixels after drawing, call flush() or peekPixels.
Cary Clarkbad5ad72017-08-03 17:14:08 -040081
Cary Clark2dc84ad2018-01-26 12:56:22 -050082#Param info width, height, Color_Type, Alpha_Type, Color_Space, of Raster_Surface;
Cary Clarkbad5ad72017-08-03 17:14:08 -040083 width, or height, or both, may be zero
Cary Clark8032b982017-07-28 11:04:54 -040084##
Cary Clarkf05bdda2017-08-24 12:59:48 -040085#Param pixels pointer to destination pixels buffer
Cary Clark8032b982017-07-28 11:04:54 -040086##
Cary Clarkf05bdda2017-08-24 12:59:48 -040087#Param rowBytes interval from one Surface row to the next, or zero
Cary Clark8032b982017-07-28 11:04:54 -040088##
Cary Clarka560c472017-11-27 10:44:06 -050089#Param props LCD striping orientation and setting for device independent fonts;
90 may be nullptr
91##
Cary Clark8032b982017-07-28 11:04:54 -040092
Cary Clarkbad5ad72017-08-03 17:14:08 -040093#Return Canvas if all parameters are valid; otherwise, nullptr ##
Cary Clark8032b982017-07-28 11:04:54 -040094
95#Example
96 #Description
97 Allocates a three by three bitmap, clears it to white, and draws a black pixel
98 in the center.
99 ##
Cary Clarkbad5ad72017-08-03 17:14:08 -0400100void draw(SkCanvas* ) {
Cary Clarkce101242017-09-01 15:51:02 -0400101 SkImageInfo info = SkImageInfo::MakeN32Premul(3, 3); // device aligned, 32 bpp, Premultiplied
Cary Clarkbad5ad72017-08-03 17:14:08 -0400102 const size_t minRowBytes = info.minRowBytes(); // bytes used by one bitmap row
Cary Clarka560c472017-11-27 10:44:06 -0500103 const size_t size = info.computeMinByteSize(); // bytes used by all rows
Cary Clarkbad5ad72017-08-03 17:14:08 -0400104 SkAutoTMalloc<SkPMColor> storage(size); // allocate storage for pixels
105 SkPMColor* pixels = storage.get(); // get pointer to allocated storage
106 // create a SkCanvas backed by a raster device, and delete it when the
107 // function goes out of scope.
108 std::unique_ptr<SkCanvas> canvas = SkCanvas::MakeRasterDirect(info, pixels, minRowBytes);
Cary Clarkce101242017-09-01 15:51:02 -0400109 canvas->clear(SK_ColorWHITE); // white is Unpremultiplied, in ARGB order
Cary Clarkbad5ad72017-08-03 17:14:08 -0400110 canvas->flush(); // ensure that pixels are cleared
Cary Clarkce101242017-09-01 15:51:02 -0400111 SkPMColor pmWhite = pixels[0]; // the Premultiplied format may vary
Cary Clarkbad5ad72017-08-03 17:14:08 -0400112 SkPaint paint; // by default, draws black
113 canvas->drawPoint(1, 1, paint); // draw in the center
114 canvas->flush(); // ensure that point was drawn
115 for (int y = 0; y < info.height(); ++y) {
116 for (int x = 0; x < info.width(); ++x) {
117 SkDebugf("%c", *pixels++ == pmWhite ? '-' : 'x');
118 }
119 SkDebugf("\n");
120 }
Cary Clark8032b982017-07-28 11:04:54 -0400121}
122 #StdOut
123 ---
124 -x-
125 ---
126 ##
127##
128
Cary Clark8032b982017-07-28 11:04:54 -0400129#SeeAlso MakeRasterDirectN32 SkSurface::MakeRasterDirect
Cary Clark2ade9972017-11-02 17:49:34 -0400130
Cary Clark8032b982017-07-28 11:04:54 -0400131##
132
133# ------------------------------------------------------------------------------
134
135#Method static std::unique_ptr<SkCanvas> MakeRasterDirectN32(int width, int height, SkPMColor* pixels,
Mike Klein9ff8c8c2018-02-07 01:58:51 +0000136 size_t rowBytes)
Cary Clark78de7512018-02-07 07:27:09 -0500137#In Constructor
Cary Clarkab2621d2018-01-30 10:08:57 -0500138#Line # creates from image data and Pixel_Storage ##
Cary Clark8032b982017-07-28 11:04:54 -0400139
Cary Clarkbad5ad72017-08-03 17:14:08 -0400140Allocates raster Canvas specified by inline image specification. Subsequent Canvas
141calls draw into pixels.
Cary Clark2dc84ad2018-01-26 12:56:22 -0500142Color_Type is set to kN32_SkColorType.
143Alpha_Type is set to kPremul_SkAlphaType.
Cary Clark8032b982017-07-28 11:04:54 -0400144To access pixels after drawing, call flush() or peekPixels.
145
Cary Clarkbad5ad72017-08-03 17:14:08 -0400146Canvas is returned if all parameters are valid.
147Valid parameters include:
Cary Clarkf05bdda2017-08-24 12:59:48 -0400148width and height are zero or positive;
Cary Clarkbad5ad72017-08-03 17:14:08 -0400149pixels is not nullptr;
Cary Clarkf05bdda2017-08-24 12:59:48 -0400150rowBytes is zero or large enough to contain width pixels of kN32_SkColorType.
Cary Clarkbad5ad72017-08-03 17:14:08 -0400151
Mike Klein9ff8c8c2018-02-07 01:58:51 +0000152Pass zero for rowBytes to compute rowBytes from width and size of pixel.
Cary Clarkf05bdda2017-08-24 12:59:48 -0400153If rowBytes is greater than zero, it must be equal to or greater than
Cary Clark2dc84ad2018-01-26 12:56:22 -0500154width times bytes required for Color_Type.
Cary Clarkf05bdda2017-08-24 12:59:48 -0400155
156Pixel buffer size should be height times rowBytes.
Cary Clarkbad5ad72017-08-03 17:14:08 -0400157
158#Param width pixel column count on Raster_Surface created; must be zero or greater ##
Cary Clarkbc5697d2017-10-04 14:31:33 -0400159#Param height pixel row count on Raster_Surface created; must be zero or greater ##
Cary Clarkbad5ad72017-08-03 17:14:08 -0400160#Param pixels pointer to destination pixels buffer; buffer size should be height
Cary Clarkf05bdda2017-08-24 12:59:48 -0400161 times rowBytes
Cary Clark8032b982017-07-28 11:04:54 -0400162##
Cary Clarkf05bdda2017-08-24 12:59:48 -0400163#Param rowBytes interval from one Surface row to the next, or zero
Cary Clark8032b982017-07-28 11:04:54 -0400164##
165
Cary Clarkbad5ad72017-08-03 17:14:08 -0400166#Return Canvas if all parameters are valid; otherwise, nullptr ##
Cary Clark8032b982017-07-28 11:04:54 -0400167
168#Example
169 #Description
170 Allocates a three by three bitmap, clears it to white, and draws a black pixel
171 in the center.
172 ##
173void draw(SkCanvas* ) {
174 const int width = 3;
175 const int height = 3;
Cary Clarkce101242017-09-01 15:51:02 -0400176 SkPMColor pixels[height][width]; // allocate a 3x3 Premultiplied bitmap on the stack
Cary Clark8032b982017-07-28 11:04:54 -0400177 // create a SkCanvas backed by a raster device, and delete it when the
178 // function goes out of scope.
179 std::unique_ptr<SkCanvas> canvas = SkCanvas::MakeRasterDirectN32(
180 width,
181 height,
Cary Clarkbc5697d2017-10-04 14:31:33 -0400182 pixels[0], // top-left of the bitmap
Cary Clark8032b982017-07-28 11:04:54 -0400183 sizeof(pixels[0])); // byte width of the each row
Cary Clarkce101242017-09-01 15:51:02 -0400184 // write a premultiplied value for white into all pixels in the bitmap
Cary Clark8032b982017-07-28 11:04:54 -0400185 canvas->clear(SK_ColorWHITE);
Cary Clarkce101242017-09-01 15:51:02 -0400186 SkPMColor pmWhite = pixels[0][0]; // the Premultiplied format may vary
Cary Clark8032b982017-07-28 11:04:54 -0400187 SkPaint paint; // by default, draws black
188 canvas->drawPoint(1, 1, paint); // draw in the center
189 canvas->flush(); // ensure that pixels is ready to be read
190 for (int y = 0; y < height; ++y) {
191 for (int x = 0; x < width; ++x) {
192 SkDebugf("%c", pixels[y][x] == pmWhite ? '-' : 'x');
193 }
194 SkDebugf("\n");
195 }
196}
197 #StdOut
198 ---
199 -x-
200 ---
201 ##
202##
203
Cary Clark2ade9972017-11-02 17:49:34 -0400204#SeeAlso MakeRasterDirect SkSurface::MakeRasterDirect SkImageInfo::MakeN32Premul
Cary Clark8032b982017-07-28 11:04:54 -0400205
206##
207
208# ------------------------------------------------------------------------------
209
210#Method SkCanvas()
211
Cary Clarkab2621d2018-01-30 10:08:57 -0500212#Line # creates with no Surface, no dimensions ##
Mike Klein9ff8c8c2018-02-07 01:58:51 +0000213Creates an empty Canvas with no backing device or pixels, with
Cary Clarkf05bdda2017-08-24 12:59:48 -0400214a width and height of zero.
Cary Clark8032b982017-07-28 11:04:54 -0400215
Cary Clarkd0530ba2017-09-14 11:25:39 -0400216#Return empty Canvas ##
Cary Clark8032b982017-07-28 11:04:54 -0400217
218#Example
219
220#Description
221Passes a placeholder to a function that requires one.
222##
223
224#Function
Cary Clarkbad5ad72017-08-03 17:14:08 -0400225// Returns true if either the canvas rotates the text by 90 degrees, or the paint does.
226static void check_for_up_and_down_text(const SkCanvas* canvas, const SkPaint& paint) {
227 bool paintHasVertical = paint.isVerticalText();
228 const SkMatrix& matrix = canvas->getTotalMatrix();
229 bool matrixIsVertical = matrix.preservesRightAngles() && !matrix.isScaleTranslate();
230 SkDebugf("paint draws text %s\n", paintHasVertical != matrixIsVertical ?
231 "top to bottom" : "left to right");
232}
233
234static void check_for_up_and_down_text(const SkPaint& paint) {
235 SkCanvas canvas; // placeholder only, does not have an associated device
236 check_for_up_and_down_text(&canvas, paint);
237}
238
Cary Clark8032b982017-07-28 11:04:54 -0400239##
Cary Clarkbad5ad72017-08-03 17:14:08 -0400240void draw(SkCanvas* canvas) {
241 SkPaint paint;
242 check_for_up_and_down_text(paint); // paint draws text left to right
243 paint.setVerticalText(true);
244 check_for_up_and_down_text(paint); // paint draws text top to bottom
245 paint.setVerticalText(false);
246 canvas->rotate(90);
247 check_for_up_and_down_text(canvas, paint); // paint draws text top to bottom
248}
Cary Clark8032b982017-07-28 11:04:54 -0400249
250 #StdOut
251 paint draws text left to right
252 paint draws text top to bottom
253 paint draws text top to bottom
254 ##
255##
256
Cary Clark2ade9972017-11-02 17:49:34 -0400257#SeeAlso MakeRasterDirect SkRasterHandleAllocator::MakeCanvas SkSurface::getCanvas SkCreateColorSpaceXformCanvas
Cary Clark8032b982017-07-28 11:04:54 -0400258
259##
260
261# ------------------------------------------------------------------------------
262
Cary Clark73fa9722017-08-29 17:36:51 -0400263#Method SkCanvas(int width, int height, const SkSurfaceProps* props = nullptr)
Cary Clark8032b982017-07-28 11:04:54 -0400264
Cary Clarkab2621d2018-01-30 10:08:57 -0500265#Line # no Surface, set dimensions, Surface_Properties ##
Cary Clark8032b982017-07-28 11:04:54 -0400266Creates Canvas of the specified dimensions without a Surface.
Cary Clarkce101242017-09-01 15:51:02 -0400267Used by Subclasses with custom implementations for draw methods.
Cary Clark8032b982017-07-28 11:04:54 -0400268
Cary Clarkd0530ba2017-09-14 11:25:39 -0400269If props equals nullptr, Surface_Properties are created with
Mike Klein9ff8c8c2018-02-07 01:58:51 +0000270Surface_Properties_Legacy_Font_Host settings, which choose the pixel striping
Cary Clarkd0530ba2017-09-14 11:25:39 -0400271direction and order. Since a platform may dynamically change its direction when
272the device is rotated, and since a platform may have multiple monitors with
273different characteristics, it is best not to rely on this legacy behavior.
Cary Clark8032b982017-07-28 11:04:54 -0400274
Cary Clarkbad5ad72017-08-03 17:14:08 -0400275#Param width zero or greater ##
276#Param height zero or greater ##
277#Param props LCD striping orientation and setting for device independent fonts;
278 may be nullptr
279##
280
281#Return Canvas placeholder with dimensions ##
Cary Clark8032b982017-07-28 11:04:54 -0400282
283#Example
284 SkCanvas canvas(10, 20); // 10 units wide, 20 units high
285 canvas.clipRect(SkRect::MakeXYWH(30, 40, 5, 10)); // clip is outside canvas' device
286 SkDebugf("canvas %s empty\n", canvas.getDeviceClipBounds().isEmpty() ? "is" : "is not");
287
288 #StdOut
289 canvas is empty
290 ##
291##
292
Cary Clark2ade9972017-11-02 17:49:34 -0400293#SeeAlso MakeRasterDirect SkSurfaceProps SkPixelGeometry SkCreateColorSpaceXformCanvas
Cary Clark8032b982017-07-28 11:04:54 -0400294
295##
296
297# ------------------------------------------------------------------------------
298
299#Method explicit SkCanvas(SkBaseDevice* device)
Cary Clark4855f782018-02-06 09:41:53 -0500300#Deprecated soon
Cary Clark8032b982017-07-28 11:04:54 -0400301##
302
303# ------------------------------------------------------------------------------
304
305#Method explicit SkCanvas(const SkBitmap& bitmap)
306
Cary Clarkab2621d2018-01-30 10:08:57 -0500307#Line # uses existing Bitmap ##
Cary Clark8032b982017-07-28 11:04:54 -0400308Construct a canvas that draws into bitmap.
Mike Klein9ff8c8c2018-02-07 01:58:51 +0000309Sets SkSurfaceProps::kLegacyFontHost_InitType in constructed Surface.
Cary Clark8032b982017-07-28 11:04:54 -0400310
Cary Clarkbad5ad72017-08-03 17:14:08 -0400311Bitmap is copied so that subsequently editing bitmap will not affect
312constructed Canvas.
313
314May be deprecated in the future.
315
Cary Clark8032b982017-07-28 11:04:54 -0400316#ToDo Should be deprecated? ##
317
Cary Clark2dc84ad2018-01-26 12:56:22 -0500318#Param bitmap width, height, Color_Type, Alpha_Type, and pixel
Cary Clarkbad5ad72017-08-03 17:14:08 -0400319 storage of Raster_Surface
Cary Clark8032b982017-07-28 11:04:54 -0400320##
321
Cary Clarkbad5ad72017-08-03 17:14:08 -0400322#Return Canvas that can be used to draw into bitmap ##
Cary Clark8032b982017-07-28 11:04:54 -0400323
324#Example
325#Description
326The actual output depends on the installed fonts.
327##
328 SkBitmap bitmap;
329 // create a bitmap 5 wide and 11 high
330 bitmap.allocPixels(SkImageInfo::MakeN32Premul(5, 11));
331 SkCanvas canvas(bitmap);
Cary Clarkce101242017-09-01 15:51:02 -0400332 canvas.clear(SK_ColorWHITE); // white is Unpremultiplied, in ARGB order
Cary Clark8032b982017-07-28 11:04:54 -0400333 SkPixmap pixmap; // provides guaranteed access to the drawn pixels
334 if (!canvas.peekPixels(&pixmap)) {
335 SkDebugf("peekPixels should never fail.\n");
336 }
Cary Clarkbc5697d2017-10-04 14:31:33 -0400337 const SkPMColor* pixels = pixmap.addr32(); // points to top-left of bitmap
Cary Clarkce101242017-09-01 15:51:02 -0400338 SkPMColor pmWhite = pixels[0]; // the Premultiplied format may vary
Cary Clark8032b982017-07-28 11:04:54 -0400339 SkPaint paint; // by default, draws black, 12 point text
340 canvas.drawString("!", 1, 10, paint); // 1 char at baseline (1, 10)
341 for (int y = 0; y < bitmap.height(); ++y) {
342 for (int x = 0; x < bitmap.width(); ++x) {
343 SkDebugf("%c", *pixels++ == pmWhite ? '-' : 'x');
344 }
345 SkDebugf("\n");
346 }
347
348 #StdOut
Cary Clarkd0530ba2017-09-14 11:25:39 -0400349 -----
350 ---x-
351 ---x-
352 ---x-
353 ---x-
354 ---x-
355 ---x-
356 -----
357 ---x-
358 ---x-
Cary Clark8032b982017-07-28 11:04:54 -0400359 -----
360 #StdOut ##
361##
362
Cary Clark2ade9972017-11-02 17:49:34 -0400363#SeeAlso MakeRasterDirect SkRasterHandleAllocator::MakeCanvas SkSurface::getCanvas SkCreateColorSpaceXformCanvas
Cary Clark8032b982017-07-28 11:04:54 -0400364
365##
366
Cary Clarkbad5ad72017-08-03 17:14:08 -0400367#EnumClass ColorBehavior
Cary Clark08895c42018-02-01 09:37:32 -0500368#Line # Android framework only ##
Cary Clark8032b982017-07-28 11:04:54 -0400369#Private
370Android framework only.
371##
372
373#Code
374 enum class ColorBehavior {
375 kLegacy,
376 };
377##
378#Const kLegacy 0
Cary Clarkbad5ad72017-08-03 17:14:08 -0400379 Is a placeholder to allow specialized constructor; has no meaning.
Cary Clark8032b982017-07-28 11:04:54 -0400380##
381##
382
Cary Clarkbad5ad72017-08-03 17:14:08 -0400383#Method SkCanvas(const SkBitmap& bitmap, ColorBehavior behavior)
384
Cary Clarkab2621d2018-01-30 10:08:57 -0500385#Line # Android framework only ##
Cary Clarkbad5ad72017-08-03 17:14:08 -0400386#Private
387Android framework only.
388##
389
390#Param bitmap specifies a bitmap for the canvas to draw into ##
391#Param behavior specializes this constructor; value is unused ##
392#Return Canvas that can be used to draw into bitmap ##
393
394#NoExample
395##
396##
Cary Clark8032b982017-07-28 11:04:54 -0400397
398# ------------------------------------------------------------------------------
399
400#Method SkCanvas(const SkBitmap& bitmap, const SkSurfaceProps& props)
401
Cary Clarkab2621d2018-01-30 10:08:57 -0500402#Line # uses existing Bitmap and Surface_Properties ##
Cary Clark8032b982017-07-28 11:04:54 -0400403Construct a canvas that draws into bitmap.
404Use props to match the device characteristics, like LCD striping.
405
Cary Clarkbad5ad72017-08-03 17:14:08 -0400406bitmap is copied so that subsequently editing bitmap will not affect
407constructed Canvas.
408
Cary Clark2dc84ad2018-01-26 12:56:22 -0500409#Param bitmap width, height, Color_Type, Alpha_Type,
Mike Klein9ff8c8c2018-02-07 01:58:51 +0000410 and pixel storage of Raster_Surface
Cary Clark8032b982017-07-28 11:04:54 -0400411##
Cary Clarkbad5ad72017-08-03 17:14:08 -0400412#Param props order and orientation of RGB striping; and whether to use
413 device independent fonts
Cary Clark8032b982017-07-28 11:04:54 -0400414##
415
Cary Clarkbad5ad72017-08-03 17:14:08 -0400416#Return Canvas that can be used to draw into bitmap ##
Cary Clark8032b982017-07-28 11:04:54 -0400417
418#Example
419#Description
420The actual output depends on the installed fonts.
421##
422 SkBitmap bitmap;
423 // create a bitmap 5 wide and 11 high
424 bitmap.allocPixels(SkImageInfo::MakeN32Premul(5, 11));
425 SkCanvas canvas(bitmap, SkSurfaceProps(0, kUnknown_SkPixelGeometry));
Cary Clarkce101242017-09-01 15:51:02 -0400426 canvas.clear(SK_ColorWHITE); // white is Unpremultiplied, in ARGB order
Cary Clark8032b982017-07-28 11:04:54 -0400427 SkPixmap pixmap; // provides guaranteed access to the drawn pixels
428 if (!canvas.peekPixels(&pixmap)) {
429 SkDebugf("peekPixels should never fail.\n");
430 }
Cary Clarkbc5697d2017-10-04 14:31:33 -0400431 const SkPMColor* pixels = pixmap.addr32(); // points to top-left of bitmap
Cary Clarkce101242017-09-01 15:51:02 -0400432 SkPMColor pmWhite = pixels[0]; // the Premultiplied format may vary
Cary Clark8032b982017-07-28 11:04:54 -0400433 SkPaint paint; // by default, draws black, 12 point text
434 canvas.drawString("!", 1, 10, paint); // 1 char at baseline (1, 10)
435 for (int y = 0; y < bitmap.height(); ++y) {
436 for (int x = 0; x < bitmap.width(); ++x) {
437 SkDebugf("%c", *pixels++ == pmWhite ? '-' : 'x');
438 }
439 SkDebugf("\n");
440 }
441
442 #StdOut
443 -----
444 ---x-
445 ---x-
446 ---x-
447 ---x-
448 ---x-
449 ---x-
450 -----
451 ---x-
452 ---x-
453 -----
454 #StdOut ##
455##
456
Cary Clark2ade9972017-11-02 17:49:34 -0400457#SeeAlso MakeRasterDirect SkRasterHandleAllocator::MakeCanvas SkSurface::getCanvas SkCreateColorSpaceXformCanvas
Cary Clark8032b982017-07-28 11:04:54 -0400458
459##
460
461# ------------------------------------------------------------------------------
462
463#Method virtual ~SkCanvas()
464
Cary Clarkab2621d2018-01-30 10:08:57 -0500465#Line # draws saved Layers, frees resources ##
Cary Clark5081eed2018-01-22 07:55:48 -0500466Draws saved Layers, if any.
467Frees up resources used by Canvas.
Cary Clark8032b982017-07-28 11:04:54 -0400468
469#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -0400470#Description
Cary Clarkce101242017-09-01 15:51:02 -0400471Canvas Layer draws into bitmap. saveLayerAlpha sets up an additional
472drawing surface that blends with the bitmap. When Layer goes out of
473scope, Layer Destructor is called. The saved Layer is restored, drawing
Cary Clarkbad5ad72017-08-03 17:14:08 -0400474transparent letters.
475##
Cary Clarkf05bdda2017-08-24 12:59:48 -0400476void draw(SkCanvas* canvas) {
477 SkBitmap bitmap;
478 bitmap.allocPixels(SkImageInfo::MakeN32Premul(200, 200));
479 {
480 SkCanvas offscreen(bitmap);
481 SkPaint paint;
482 paint.setTextSize(100);
483 offscreen.drawString("ABC", 20, 160, paint);
484 SkRect layerBounds = SkRect::MakeXYWH(32, 32, 192, 192);
485 offscreen.saveLayerAlpha(&layerBounds, 128);
486 offscreen.clear(SK_ColorWHITE);
487 offscreen.drawString("DEF", 20, 160, paint);
488 }
489 canvas->drawBitmap(bitmap, 0, 0, nullptr);
Cary Clarkbad5ad72017-08-03 17:14:08 -0400490}
Cary Clark8032b982017-07-28 11:04:54 -0400491##
492
Cary Clarkbad5ad72017-08-03 17:14:08 -0400493#SeeAlso State_Stack
Cary Clark8032b982017-07-28 11:04:54 -0400494
495##
496
497# ------------------------------------------------------------------------------
Cary Clark78de7512018-02-07 07:27:09 -0500498#Subtopic Property
499#Populate
500#Line # metrics and attributes ##
501##
Cary Clark8032b982017-07-28 11:04:54 -0400502
503#Method SkMetaData& getMetaData()
Cary Clark78de7512018-02-07 07:27:09 -0500504#In Property
505#In Utility
Cary Clarkab2621d2018-01-30 10:08:57 -0500506#Line # associates additional data with the canvas ##
Cary Clarkf05bdda2017-08-24 12:59:48 -0400507Returns storage to associate additional data with the canvas.
Cary Clark8032b982017-07-28 11:04:54 -0400508The storage is freed when Canvas is deleted.
509
Cary Clarkbad5ad72017-08-03 17:14:08 -0400510#Return storage that can be read from and written to ##
Cary Clark8032b982017-07-28 11:04:54 -0400511
512#Example
513 const char* kHelloMetaData = "HelloMetaData";
514 SkCanvas canvas;
515 SkMetaData& metaData = canvas.getMetaData();
516 SkDebugf("before: %s\n", metaData.findString(kHelloMetaData));
517 metaData.setString(kHelloMetaData, "Hello!");
518 SkDebugf("during: %s\n", metaData.findString(kHelloMetaData));
519 metaData.removeString(kHelloMetaData);
520 SkDebugf("after: %s\n", metaData.findString(kHelloMetaData));
521
522 #StdOut
523 before: (null)
524 during: Hello!
525 after: (null)
526 #StdOut ##
527##
528
Cary Clark2ade9972017-11-02 17:49:34 -0400529#SeeAlso SkMetaData
Cary Clark8032b982017-07-28 11:04:54 -0400530
531##
532
533# ------------------------------------------------------------------------------
534
535#Method SkImageInfo imageInfo() const
Cary Clark78de7512018-02-07 07:27:09 -0500536#In Property
Cary Clarkab2621d2018-01-30 10:08:57 -0500537#Line # returns Image_Info for Canvas ##
Cary Clark8032b982017-07-28 11:04:54 -0400538Returns Image_Info for Canvas. If Canvas is not associated with Raster_Surface or
Cary Clark2dc84ad2018-01-26 12:56:22 -0500539GPU_Surface, returned Color_Type is set to kUnknown_SkColorType.
Cary Clark8032b982017-07-28 11:04:54 -0400540
Cary Clark2dc84ad2018-01-26 12:56:22 -0500541#Return dimensions and Color_Type of Canvas ##
Cary Clark8032b982017-07-28 11:04:54 -0400542
543#Example
Cary Clarkf05bdda2017-08-24 12:59:48 -0400544 SkCanvas emptyCanvas;
545 SkImageInfo canvasInfo = emptyCanvas.imageInfo();
546 SkImageInfo emptyInfo;
547 SkDebugf("emptyInfo %c= canvasInfo\n", emptyInfo == canvasInfo ? '=' : '!');
548
549 #StdOut
550 emptyInfo == canvasInfo
551 ##
Cary Clark8032b982017-07-28 11:04:54 -0400552##
553
Cary Clark2ade9972017-11-02 17:49:34 -0400554#SeeAlso SkImageInfo MakeRasterDirect makeSurface
Cary Clark8032b982017-07-28 11:04:54 -0400555
556##
557
558# ------------------------------------------------------------------------------
559
560#Method bool getProps(SkSurfaceProps* props) const
Cary Clark78de7512018-02-07 07:27:09 -0500561#In Property
Cary Clarkab2621d2018-01-30 10:08:57 -0500562#Line # copies Surface_Properties if available ##
Cary Clark8032b982017-07-28 11:04:54 -0400563If Canvas is associated with Raster_Surface or
564GPU_Surface, copies Surface_Properties and returns true. Otherwise,
565return false and leave props unchanged.
566
Cary Clarkbad5ad72017-08-03 17:14:08 -0400567#Param props storage for writable SkSurfaceProps ##
Cary Clark8032b982017-07-28 11:04:54 -0400568
Cary Clarkbad5ad72017-08-03 17:14:08 -0400569#Return true if Surface_Properties was copied ##
Cary Clark8032b982017-07-28 11:04:54 -0400570
571#ToDo This seems old style. Deprecate? ##
572
573#Example
574 SkBitmap bitmap;
575 SkCanvas canvas(bitmap, SkSurfaceProps(0, kRGB_V_SkPixelGeometry));
576 SkSurfaceProps surfaceProps(0, kUnknown_SkPixelGeometry);
577 SkDebugf("isRGB:%d\n", SkPixelGeometryIsRGB(surfaceProps.pixelGeometry()));
578 if (!canvas.getProps(&surfaceProps)) {
579 SkDebugf("getProps failed unexpectedly.\n");
580 }
581 SkDebugf("isRGB:%d\n", SkPixelGeometryIsRGB(surfaceProps.pixelGeometry()));
582
583 #StdOut
584 isRGB:0
585 isRGB:1
586 #StdOut ##
587##
588
Cary Clark2ade9972017-11-02 17:49:34 -0400589#SeeAlso SkSurfaceProps makeSurface
Cary Clark8032b982017-07-28 11:04:54 -0400590
591##
592
593# ------------------------------------------------------------------------------
Cary Clark78de7512018-02-07 07:27:09 -0500594#Subtopic Utility
595#Populate
596#Line # rarely called management functions ##
597##
Cary Clark8032b982017-07-28 11:04:54 -0400598
599#Method void flush()
Cary Clark78de7512018-02-07 07:27:09 -0500600#In Utility
Cary Clarkab2621d2018-01-30 10:08:57 -0500601#Line # triggers execution of all pending draw operations ##
Mike Klein9ff8c8c2018-02-07 01:58:51 +0000602Triggers the immediate execution of all pending draw operations.
Cary Clarkbad5ad72017-08-03 17:14:08 -0400603If Canvas is associated with GPU_Surface, resolves all pending GPU operations.
Cary Clark2ade9972017-11-02 17:49:34 -0400604If Canvas is associated with Raster_Surface, has no effect; raster draw
605operations are never deferred.
606
607#ToDo
608In an overview section on managing the GPU, include:
609- flush should never change what is drawn
610- call to kick off gpu work
611- calling too much impacts performance
612- some calls (peekPixels, prepareForExternalIO) call it internally
613- canvas call is local, GrContext::flush is global
614- diffentiate between flush, flushAndSignalSemaphores
615- normally never needs to be called
616- call it when sharing gpu resources, feeling memory pressure, swapping out app, and before
617 abandoning context
618- also call to say "I'm finished drawing here", e.g., when drawing to a GPU-backed offscreen surface
619 (created with SkSurface::MakeRenderTarget)
620
621for posterity: this doesn't show a difference: fiddle.skia.org/c/@flushfail
622##
Cary Clark8032b982017-07-28 11:04:54 -0400623
Cary Clark08895c42018-02-01 09:37:32 -0500624#ToDo haven't thought of a useful example to put here ##
625#NoExample
Cary Clark8032b982017-07-28 11:04:54 -0400626##
627
Cary Clark2ade9972017-11-02 17:49:34 -0400628#SeeAlso peekPixels SkSurface::flush() GrContext::flush() SkSurface::prepareForExternalIO GrContext::abandonContext()
Cary Clark8032b982017-07-28 11:04:54 -0400629
630##
631
632# ------------------------------------------------------------------------------
633
634#Method virtual SkISize getBaseLayerSize() const
Cary Clark78de7512018-02-07 07:27:09 -0500635#In Property
Cary Clarkab2621d2018-01-30 10:08:57 -0500636#Line # returns size of base Layer in global coordinates ##
Cary Clarkce101242017-09-01 15:51:02 -0400637Gets the size of the base or root Layer in global canvas coordinates. The
638origin of the base Layer is always (0,0). The area available for drawing may be
Cary Clark8032b982017-07-28 11:04:54 -0400639smaller (due to clipping or saveLayer).
640
Cary Clarkce101242017-09-01 15:51:02 -0400641#Return integral width and height of base Layer ##
Cary Clark8032b982017-07-28 11:04:54 -0400642
643#Example
644 SkBitmap bitmap;
645 bitmap.allocPixels(SkImageInfo::MakeN32Premul(20, 30));
646 SkCanvas canvas(bitmap, SkSurfaceProps(0, kUnknown_SkPixelGeometry));
647 canvas.clipRect(SkRect::MakeWH(10, 40));
648 SkIRect clipDeviceBounds = canvas.getDeviceClipBounds();
649 if (clipDeviceBounds.isEmpty()) {
650 SkDebugf("Empty clip bounds is unexpected!\n");
651 }
652 SkDebugf("clip=%d,%d\n", clipDeviceBounds.width(), clipDeviceBounds.height());
653 SkISize baseLayerSize = canvas.getBaseLayerSize();
654 SkDebugf("size=%d,%d\n", baseLayerSize.width(), baseLayerSize.height());
655
656 #StdOut
657 clip=10,30
658 size=20,30
659 ##
660##
661
662#ToDo is this the same as the width and height of surface? ##
663
Cary Clark2ade9972017-11-02 17:49:34 -0400664#SeeAlso getDeviceClipBounds
665
Cary Clark8032b982017-07-28 11:04:54 -0400666##
667
668# ------------------------------------------------------------------------------
669
670#Method sk_sp<SkSurface> makeSurface(const SkImageInfo& info, const SkSurfaceProps* props = nullptr)
Cary Clark4855f782018-02-06 09:41:53 -0500671#In Constructor
Cary Clarkab2621d2018-01-30 10:08:57 -0500672#Line # creates Surface matching SkImageInfo and SkSurfaceProps ##
Cary Clark8032b982017-07-28 11:04:54 -0400673Creates Surface matching info and props, and associates it with Canvas.
Cary Clarkbad5ad72017-08-03 17:14:08 -0400674Returns nullptr if no match found.
Cary Clark8032b982017-07-28 11:04:54 -0400675
Cary Clarkbad5ad72017-08-03 17:14:08 -0400676If props is nullptr, matches Surface_Properties in Canvas. If props is nullptr and Canvas
677does not have Surface_Properties, creates Surface with default Surface_Properties.
Cary Clark8032b982017-07-28 11:04:54 -0400678
Cary Clark2dc84ad2018-01-26 12:56:22 -0500679#Param info width, height, Color_Type, Alpha_Type, and Color_Space ##
Cary Clarkbad5ad72017-08-03 17:14:08 -0400680#Param props Surface_Properties to match; may be nullptr to match Canvas ##
681
682#Return Surface matching info and props, or nullptr if no match is available ##
Cary Clark8032b982017-07-28 11:04:54 -0400683
684#Example
685 sk_sp<SkSurface> surface = SkSurface::MakeRasterN32Premul(5, 6);
686 SkCanvas* smallCanvas = surface->getCanvas();
687 SkImageInfo imageInfo = SkImageInfo::MakeN32Premul(3, 4);
688 sk_sp<SkSurface> compatible = smallCanvas->makeSurface(imageInfo);
689 SkDebugf("compatible %c= nullptr\n", compatible == nullptr ? '=' : '!');
690 SkDebugf("size = %d, %d\n", compatible->width(), compatible->height());
691
692 #StdOut
Cary Clarkbad5ad72017-08-03 17:14:08 -0400693 compatible != nullptr
Cary Clark8032b982017-07-28 11:04:54 -0400694 size = 3, 4
695 ##
696##
697
Cary Clark2ade9972017-11-02 17:49:34 -0400698#SeeAlso SkSurface SkSurface::makeSurface SkImageInfo SkSurfaceProps
Cary Clark8032b982017-07-28 11:04:54 -0400699
700##
701
702# ------------------------------------------------------------------------------
703
704#Method virtual GrContext* getGrContext()
Cary Clark78de7512018-02-07 07:27:09 -0500705#In Property
Cary Clarkab2621d2018-01-30 10:08:57 -0500706#Line # returns GPU_Context of the GPU_Surface ##
Cary Clark8032b982017-07-28 11:04:54 -0400707Returns GPU_Context of the GPU_Surface associated with Canvas.
708
Cary Clarkbad5ad72017-08-03 17:14:08 -0400709#Return GPU_Context, if available; nullptr otherwise ##
Cary Clark8032b982017-07-28 11:04:54 -0400710
711#Example
712void draw(SkCanvas* canvas) {
713 if (canvas->getGrContext()) {
714 canvas->clear(SK_ColorRED);
715 } else {
716 canvas->clear(SK_ColorBLUE);
717 }
718}
719##
720
721#ToDo fiddle should show both CPU and GPU out ##
722
Mike Klein9ff8c8c2018-02-07 01:58:51 +0000723#SeeAlso GrContext
Cary Clark2ade9972017-11-02 17:49:34 -0400724
Cary Clark8032b982017-07-28 11:04:54 -0400725##
726
727# ------------------------------------------------------------------------------
728
Cary Clark73fa9722017-08-29 17:36:51 -0400729#Method void* accessTopLayerPixels(SkImageInfo* info, size_t* rowBytes, SkIPoint* origin = nullptr)
Cary Clark78de7512018-02-07 07:27:09 -0500730#In Utility
731#In Property
Cary Clarkab2621d2018-01-30 10:08:57 -0500732#Line # returns writable pixel access if available ##
Cary Clark8032b982017-07-28 11:04:54 -0400733Returns the pixel base address, Image_Info, rowBytes, and origin if the pixels
Cary Clarkbad5ad72017-08-03 17:14:08 -0400734can be read directly. The returned address is only valid
Cary Clark8032b982017-07-28 11:04:54 -0400735while Canvas is in scope and unchanged. Any Canvas call or Surface call
736may invalidate the returned address and other returned values.
737
738If pixels are inaccessible, info, rowBytes, and origin are unchanged.
739
Cary Clarkbad5ad72017-08-03 17:14:08 -0400740#Param info storage for writable pixels' Image_Info; may be nullptr ##
741#Param rowBytes storage for writable pixels' row bytes; may be nullptr ##
Cary Clarkbc5697d2017-10-04 14:31:33 -0400742#Param origin storage for Canvas top Layer origin, its top-left corner;
Cary Clarkbad5ad72017-08-03 17:14:08 -0400743 may be nullptr
744##
Cary Clark8032b982017-07-28 11:04:54 -0400745
Cary Clarka523d2d2017-08-30 08:58:10 -0400746#Return address of pixels, or nullptr if inaccessible ##
Cary Clark8032b982017-07-28 11:04:54 -0400747
748#Example
749void draw(SkCanvas* canvas) {
750 if (canvas->accessTopLayerPixels(nullptr, nullptr)) {
751 canvas->clear(SK_ColorRED);
752 } else {
753 canvas->clear(SK_ColorBLUE);
754 }
755}
756##
757
758#Example
759#Description
Cary Clarkce101242017-09-01 15:51:02 -0400760Draws "ABC" on the device. Then draws "DEF" in Layer, and reads
761Layer to add a large dotted "DEF". Finally blends Layer with the
Mike Klein9ff8c8c2018-02-07 01:58:51 +0000762device.
Cary Clark8032b982017-07-28 11:04:54 -0400763
Cary Clarkce101242017-09-01 15:51:02 -0400764The Layer and blended result appear on the CPU and GPU but the large dotted
Cary Clark8032b982017-07-28 11:04:54 -0400765"DEF" appear only on the CPU.
766##
767void draw(SkCanvas* canvas) {
Cary Clarkbad5ad72017-08-03 17:14:08 -0400768 SkPaint paint;
769 paint.setTextSize(100);
770 canvas->drawString("ABC", 20, 160, paint);
771 SkRect layerBounds = SkRect::MakeXYWH(32, 32, 192, 192);
772 canvas->saveLayerAlpha(&layerBounds, 128);
773 canvas->clear(SK_ColorWHITE);
774 canvas->drawString("DEF", 20, 160, paint);
775 SkImageInfo imageInfo;
776 size_t rowBytes;
777 SkIPoint origin;
778 uint32_t* access = (uint32_t*) canvas->accessTopLayerPixels(&imageInfo, &rowBytes, &origin);
779 if (access) {
780 int h = imageInfo.height();
781 int v = imageInfo.width();
782 int rowWords = rowBytes / sizeof(uint32_t);
783 for (int y = 0; y < h; ++y) {
784 int newY = (y - h / 2) * 2 + h / 2;
785 if (newY < 0 || newY >= h) {
786 continue;
787 }
788 for (int x = 0; x < v; ++x) {
789 int newX = (x - v / 2) * 2 + v / 2;
790 if (newX < 0 || newX >= v) {
791 continue;
792 }
793 if (access[y * rowWords + x] == SK_ColorBLACK) {
794 access[newY * rowWords + newX] = SK_ColorGRAY;
795 }
796 }
797 }
798
799 }
Cary Clark8032b982017-07-28 11:04:54 -0400800 canvas->restore();
801}
802##
803
804#ToDo there are no callers of this that I can find. Deprecate? ##
805#ToDo fiddle should show both CPU and GPU out ##
806
Cary Clark2ade9972017-11-02 17:49:34 -0400807#SeeAlso SkImageInfo SkPixmap
808
Cary Clark8032b982017-07-28 11:04:54 -0400809##
810
811# ------------------------------------------------------------------------------
812
813#Method SkRasterHandleAllocator::Handle accessTopRasterHandle() const
Cary Clark78de7512018-02-07 07:27:09 -0500814#In Utility
815#In Property
Cary Clarkab2621d2018-01-30 10:08:57 -0500816#Line # returns context that tracks Clip and Matrix ##
Cary Clark8032b982017-07-28 11:04:54 -0400817Returns custom context that tracks the Matrix and Clip.
818
819Use Raster_Handle_Allocator to blend Skia drawing with custom drawing, typically performed
Cary Clarkbc5697d2017-10-04 14:31:33 -0400820by the host platform user interface. The custom context returned is generated by
Cary Clarkbad5ad72017-08-03 17:14:08 -0400821SkRasterHandleAllocator::MakeCanvas, which creates a custom canvas with raster storage for
Cary Clark8032b982017-07-28 11:04:54 -0400822the drawing destination.
823
Cary Clarkce101242017-09-01 15:51:02 -0400824#Return context of custom allocation ##
Cary Clark8032b982017-07-28 11:04:54 -0400825
826#Example
827#Description
828#ToDo ##
829##
830#Function
831 static void DeleteCallback(void*, void* context) {
832 delete (char*) context;
833 }
834
835 class CustomAllocator : public SkRasterHandleAllocator {
836 public:
837 bool allocHandle(const SkImageInfo& info, Rec* rec) override {
838 char* context = new char[4]{'s', 'k', 'i', 'a'};
839 rec->fReleaseProc = DeleteCallback;
840 rec->fReleaseCtx = context;
841 rec->fHandle = context;
842 rec->fPixels = context;
843 rec->fRowBytes = 4;
844 return true;
845 }
846
847 void updateHandle(Handle handle, const SkMatrix& ctm, const SkIRect& clip_bounds) override {
848 // apply canvas matrix and clip to custom environment
849 }
850 };
851
852##
853 void draw(SkCanvas* canvas) {
854 const SkImageInfo info = SkImageInfo::MakeN32Premul(1, 1);
855 std::unique_ptr<SkCanvas> c2 =
856 SkRasterHandleAllocator::MakeCanvas(std::unique_ptr<CustomAllocator>(
857 new CustomAllocator()), info);
858 char* context = (char*) c2->accessTopRasterHandle();
859 SkDebugf("context = %.4s\n", context);
860
861 }
862 #StdOut
863 context = skia
864 ##
865 #ToDo skstd::make_unique could not be used because def is private -- note to fix in c++14? ##
866##
867
868#SeeAlso SkRasterHandleAllocator
869
870##
871
872# ------------------------------------------------------------------------------
Cary Clark78de7512018-02-07 07:27:09 -0500873#Subtopic Pixels
874#Populate
875#Line # read and write pixel values ##
876##
Cary Clark8032b982017-07-28 11:04:54 -0400877
878#Method bool peekPixels(SkPixmap* pixmap)
Cary Clark78de7512018-02-07 07:27:09 -0500879#In Pixels
Cary Clarkab2621d2018-01-30 10:08:57 -0500880#Line # returns if Canvas has direct access to its pixels ##
Cary Clark8032b982017-07-28 11:04:54 -0400881Returns true if Canvas has direct access to its pixels.
882
Cary Clarkf05bdda2017-08-24 12:59:48 -0400883Pixels are readable when Device is raster. Pixels are not readable when Canvas
Cary Clarkbad5ad72017-08-03 17:14:08 -0400884is returned from GPU_Surface, returned by SkDocument::beginPage, returned by
Cary Clarkf05bdda2017-08-24 12:59:48 -0400885SkPictureRecorder::beginRecording, or Canvas is the base of a utility class
Brian Osman46fe9c72018-03-09 15:44:34 -0500886like SkDebugCanvas.
Cary Clark8032b982017-07-28 11:04:54 -0400887
Cary Clarkf05bdda2017-08-24 12:59:48 -0400888pixmap is valid only while Canvas is in scope and unchanged. Any
Cary Clarkbad5ad72017-08-03 17:14:08 -0400889Canvas or Surface call may invalidate the pixmap values.
Cary Clark8032b982017-07-28 11:04:54 -0400890
Cary Clarkbc5697d2017-10-04 14:31:33 -0400891#Param pixmap storage for pixel state if pixels are readable; otherwise, ignored ##
Cary Clark8032b982017-07-28 11:04:54 -0400892
Cary Clarkbad5ad72017-08-03 17:14:08 -0400893#Return true if Canvas has direct access to pixels ##
Cary Clark8032b982017-07-28 11:04:54 -0400894
895#Example
896 SkPixmap pixmap;
897 if (canvas->peekPixels(&pixmap)) {
898 SkDebugf("width=%d height=%d\n", pixmap.bounds().width(), pixmap.bounds().height());
899 }
900 #StdOut
901 width=256 height=256
902 ##
903##
904
Cary Clark2ade9972017-11-02 17:49:34 -0400905#SeeAlso readPixels SkBitmap::peekPixels SkImage::peekPixels SkSurface::peekPixels
906
Cary Clark8032b982017-07-28 11:04:54 -0400907##
908
909# ------------------------------------------------------------------------------
910
911#Method bool readPixels(const SkImageInfo& dstInfo, void* dstPixels, size_t dstRowBytes,
912 int srcX, int srcY)
Cary Clark78de7512018-02-07 07:27:09 -0500913#In Pixels
Cary Clarkab2621d2018-01-30 10:08:57 -0500914#Line # copies and converts rectangle of pixels from Canvas ##
Cary Clark8032b982017-07-28 11:04:54 -0400915
Cary Clark154beea2017-10-26 07:58:48 -0400916Copies Rect of pixels from Canvas into dstPixels. Matrix and Clip are
Mike Klein9ff8c8c2018-02-07 01:58:51 +0000917ignored.
Cary Clark6fc50412017-09-21 12:31:06 -0400918
Cary Clarka560c472017-11-27 10:44:06 -0500919Source Rect corners are (srcX, srcY) and (imageInfo().width(), imageInfo().height()).
920Destination Rect corners are (0, 0) and (dstInfo.width(), dstInfo.height()).
Cary Clark6fc50412017-09-21 12:31:06 -0400921Copies each readable pixel intersecting both rectangles, without scaling,
Cary Clarkf05bdda2017-08-24 12:59:48 -0400922converting to dstInfo.colorType() and dstInfo.alphaType() if required.
Cary Clark8032b982017-07-28 11:04:54 -0400923
Cary Clarkf05bdda2017-08-24 12:59:48 -0400924Pixels are readable when Device is raster, or backed by a GPU.
925Pixels are not readable when SkCanvas is returned by SkDocument::beginPage,
926returned by SkPictureRecorder::beginRecording, or Canvas is the base of a utility
Brian Osman46fe9c72018-03-09 15:44:34 -0500927class like SkDebugCanvas.
Cary Clark8032b982017-07-28 11:04:54 -0400928
Cary Clarkf05bdda2017-08-24 12:59:48 -0400929The destination pixel storage must be allocated by the caller.
Cary Clark8032b982017-07-28 11:04:54 -0400930
Cary Clark2dc84ad2018-01-26 12:56:22 -0500931Pixel values are converted only if Color_Type and Alpha_Type
Cary Clarkf05bdda2017-08-24 12:59:48 -0400932do not match. Only pixels within both source and destination rectangles
Cary Clark154beea2017-10-26 07:58:48 -0400933are copied. dstPixels contents outside Rect intersection are unchanged.
Cary Clarkf05bdda2017-08-24 12:59:48 -0400934
935Pass negative values for srcX or srcY to offset pixels across or down destination.
Cary Clark8032b982017-07-28 11:04:54 -0400936
937Does not copy, and returns false if:
938
939#List
Cary Clarkf05bdda2017-08-24 12:59:48 -0400940# Source and destination rectangles do not intersect. ##
941# Canvas pixels could not be converted to dstInfo.colorType() or dstInfo.alphaType(). ##
942# Canvas pixels are not readable; for instance, Canvas is document-based. ##
Cary Clark8032b982017-07-28 11:04:54 -0400943# dstRowBytes is too small to contain one row of pixels. ##
944##
945
Cary Clark2dc84ad2018-01-26 12:56:22 -0500946#Param dstInfo width, height, Color_Type, and Alpha_Type of dstPixels ##
Cary Clarkf05bdda2017-08-24 12:59:48 -0400947#Param dstPixels storage for pixels; dstInfo.height() times dstRowBytes, or larger ##
948#Param dstRowBytes size of one destination row; dstInfo.width() times pixel size, or larger ##
949#Param srcX offset into readable pixels in x; may be negative ##
950#Param srcY offset into readable pixels in y; may be negative ##
Cary Clark8032b982017-07-28 11:04:54 -0400951
Cary Clarkbad5ad72017-08-03 17:14:08 -0400952#Return true if pixels were copied ##
Cary Clark8032b982017-07-28 11:04:54 -0400953
954#Example
Cary Clarkf05bdda2017-08-24 12:59:48 -0400955#Width 64
956#Height 64
957#Description
958 A black circle drawn on a blue background provides an image to copy.
959 readPixels copies one quarter of the canvas into each of the four corners.
Cary Clarka560c472017-11-27 10:44:06 -0500960 The copied quarter circles overdraw the original circle.
Cary Clarkf05bdda2017-08-24 12:59:48 -0400961##
962 canvas->clear(SK_ColorBLUE);
963 SkPaint paint;
964 canvas->drawCircle(32, 32, 28, paint);
965 SkImageInfo info = SkImageInfo::Make(64, 64, kBGRA_8888_SkColorType, kPremul_SkAlphaType);
966 sk_sp<SkData> data(SkData::MakeUninitialized(info.minRowBytes() * info.height()));
967 sk_bzero(data->writable_data(), info.minRowBytes() * info.height());
968 for (int x : { 32, -32 } ) {
969 for (int y : { 32, -32 } ) {
970 canvas->readPixels(info, data->writable_data(), info.minRowBytes(), x, y);
Mike Klein9ff8c8c2018-02-07 01:58:51 +0000971 }
Cary Clarkf05bdda2017-08-24 12:59:48 -0400972 }
973 sk_sp<SkImage> image = SkImage::MakeRasterData(info, data, info.minRowBytes());
974 canvas->drawImage(image, 0, 0);
975##
976
977#Example
Cary Clark8032b982017-07-28 11:04:54 -0400978#Description
Cary Clarkce101242017-09-01 15:51:02 -0400979 Canvas returned by Raster_Surface has Premultiplied pixel values.
980 clear() takes Unpremultiplied input with Color_Alpha equal 0x80
981 and Color_RGB equal 0x55, 0xAA, 0xFF. Color_RGB is multiplied by Color_Alpha
982 to generate Premultiplied value 0x802B5580. readPixels converts pixel back
983 to Unpremultiplied value 0x8056A9FF, introducing error.
Cary Clark8032b982017-07-28 11:04:54 -0400984##
985 canvas->clear(0x8055aaff);
986 for (SkAlphaType alphaType : { kPremul_SkAlphaType, kUnpremul_SkAlphaType } ) {
987 uint32_t pixel = 0;
988 SkImageInfo info = SkImageInfo::Make(1, 1, kBGRA_8888_SkColorType, alphaType);
989 if (canvas->readPixels(info, &pixel, 4, 0, 0)) {
990 SkDebugf("pixel = %08x\n", pixel);
991 }
992 }
993
994 #StdOut
995 pixel = 802b5580
996 pixel = 8056a9ff
997 ##
998##
999
Cary Clark2ade9972017-11-02 17:49:34 -04001000#SeeAlso peekPixels writePixels drawBitmap drawImage SkBitmap::readPixels SkPixmap::readPixels SkImage::readPixels SkSurface::readPixels
Cary Clark8032b982017-07-28 11:04:54 -04001001
1002##
1003
1004# ------------------------------------------------------------------------------
1005
1006#Method bool readPixels(const SkPixmap& pixmap, int srcX, int srcY)
1007
Cary Clark154beea2017-10-26 07:58:48 -04001008Copies Rect of pixels from Canvas into pixmap. Matrix and Clip are
Cary Clarka560c472017-11-27 10:44:06 -05001009ignored.
Cary Clark6fc50412017-09-21 12:31:06 -04001010
Cary Clarka560c472017-11-27 10:44:06 -05001011Source Rect corners are (srcX, srcY) and (imageInfo().width(), imageInfo().height()).
1012Destination Rect corners are (0, 0) and (pixmap.width(), pixmap.height()).
Cary Clark6fc50412017-09-21 12:31:06 -04001013Copies each readable pixel intersecting both rectangles, without scaling,
Cary Clarkf05bdda2017-08-24 12:59:48 -04001014converting to pixmap.colorType() and pixmap.alphaType() if required.
Cary Clark8032b982017-07-28 11:04:54 -04001015
Cary Clarkf05bdda2017-08-24 12:59:48 -04001016Pixels are readable when Device is raster, or backed by a GPU.
1017Pixels are not readable when SkCanvas is returned by SkDocument::beginPage,
1018returned by SkPictureRecorder::beginRecording, or Canvas is the base of a utility
Brian Osman46fe9c72018-03-09 15:44:34 -05001019class like SkDebugCanvas.
Cary Clark8032b982017-07-28 11:04:54 -04001020
Cary Clark6fc50412017-09-21 12:31:06 -04001021Caller must allocate pixel storage in pixmap if needed.
Cary Clark8032b982017-07-28 11:04:54 -04001022
Cary Clark2dc84ad2018-01-26 12:56:22 -05001023Pixel values are converted only if Color_Type and Alpha_Type
Cary Clark154beea2017-10-26 07:58:48 -04001024do not match. Only pixels within both source and destination Rects
1025are copied. pixmap pixels contents outside Rect intersection are unchanged.
Cary Clarkf05bdda2017-08-24 12:59:48 -04001026
1027Pass negative values for srcX or srcY to offset pixels across or down pixmap.
Cary Clark8032b982017-07-28 11:04:54 -04001028
1029Does not copy, and returns false if:
1030
1031#List
Cary Clarkf05bdda2017-08-24 12:59:48 -04001032# Source and destination rectangles do not intersect. ##
1033# Canvas pixels could not be converted to pixmap.colorType() or pixmap.alphaType(). ##
1034# Canvas pixels are not readable; for instance, Canvas is document-based. ##
1035# Pixmap pixels could not be allocated. ##
1036# pixmap.rowBytes() is too small to contain one row of pixels. ##
Cary Clark8032b982017-07-28 11:04:54 -04001037##
1038
Cary Clarkbad5ad72017-08-03 17:14:08 -04001039#Param pixmap storage for pixels copied from Canvas ##
Cary Clarkf05bdda2017-08-24 12:59:48 -04001040#Param srcX offset into readable pixels in x; may be negative ##
1041#Param srcY offset into readable pixels in y; may be negative ##
Cary Clark8032b982017-07-28 11:04:54 -04001042
Cary Clarkbad5ad72017-08-03 17:14:08 -04001043#Return true if pixels were copied ##
Cary Clark8032b982017-07-28 11:04:54 -04001044
1045#Example
Cary Clarkf05bdda2017-08-24 12:59:48 -04001046 #Description
Cary Clarkce101242017-09-01 15:51:02 -04001047 clear() takes Unpremultiplied input with Color_Alpha equal 0x80
1048 and Color_RGB equal 0x55, 0xAA, 0xFF. Color_RGB is multiplied by Color_Alpha
1049 to generate Premultiplied value 0x802B5580.
Cary Clarkf05bdda2017-08-24 12:59:48 -04001050 ##
1051 void draw(SkCanvas* canvas) {
1052 canvas->clear(0x8055aaff);
1053 uint32_t pixels[1] = { 0 };
1054 SkPixmap pixmap(SkImageInfo::MakeN32Premul(1, 1), pixels, 4);
1055 canvas->readPixels(pixmap, 0, 0);
1056 SkDebugf("pixel = %08x\n", pixels[0]);
1057 }
Cary Clark8032b982017-07-28 11:04:54 -04001058 #StdOut
1059 pixel = 802b5580
1060 ##
1061##
1062
Cary Clark2ade9972017-11-02 17:49:34 -04001063#SeeAlso peekPixels writePixels drawBitmap drawImage SkBitmap::readPixels SkPixmap::readPixels SkImage::readPixels SkSurface::readPixels
Cary Clark8032b982017-07-28 11:04:54 -04001064
1065##
1066
1067# ------------------------------------------------------------------------------
1068
1069#Method bool readPixels(const SkBitmap& bitmap, int srcX, int srcY)
1070
Cary Clark154beea2017-10-26 07:58:48 -04001071Copies Rect of pixels from Canvas into bitmap. Matrix and Clip are
Cary Clarka560c472017-11-27 10:44:06 -05001072ignored.
Cary Clark6fc50412017-09-21 12:31:06 -04001073
Cary Clarka560c472017-11-27 10:44:06 -05001074Source Rect corners are (srcX, srcY) and (imageInfo().width(), imageInfo().height()).
Cary Clark154beea2017-10-26 07:58:48 -04001075Destination Rect corners are (0, 0) and (bitmap.width(), bitmap.height()).
Cary Clarkf05bdda2017-08-24 12:59:48 -04001076Copies each readable pixel intersecting both rectangles, without scaling,
1077converting to bitmap.colorType() and bitmap.alphaType() if required.
Cary Clark8032b982017-07-28 11:04:54 -04001078
Cary Clarkf05bdda2017-08-24 12:59:48 -04001079Pixels are readable when Device is raster, or backed by a GPU.
1080Pixels are not readable when SkCanvas is returned by SkDocument::beginPage,
1081returned by SkPictureRecorder::beginRecording, or Canvas is the base of a utility
Brian Osman46fe9c72018-03-09 15:44:34 -05001082class like SkDebugCanvas.
Cary Clark8032b982017-07-28 11:04:54 -04001083
Cary Clark6fc50412017-09-21 12:31:06 -04001084Caller must allocate pixel storage in bitmap if needed.
Cary Clarkf05bdda2017-08-24 12:59:48 -04001085
Cary Clark2dc84ad2018-01-26 12:56:22 -05001086Bitmap values are converted only if Color_Type and Alpha_Type
Cary Clarkf05bdda2017-08-24 12:59:48 -04001087do not match. Only pixels within both source and destination rectangles
Cary Clark154beea2017-10-26 07:58:48 -04001088are copied. Bitmap pixels outside Rect intersection are unchanged.
Cary Clarkf05bdda2017-08-24 12:59:48 -04001089
1090Pass negative values for srcX or srcY to offset pixels across or down bitmap.
Cary Clark8032b982017-07-28 11:04:54 -04001091
1092Does not copy, and returns false if:
1093
1094#List
Cary Clarkf05bdda2017-08-24 12:59:48 -04001095# Source and destination rectangles do not intersect. ##
1096# Canvas pixels could not be converted to bitmap.colorType() or bitmap.alphaType(). ##
1097# Canvas pixels are not readable; for instance, Canvas is document-based. ##
Cary Clark8032b982017-07-28 11:04:54 -04001098# bitmap pixels could not be allocated. ##
Cary Clarkf05bdda2017-08-24 12:59:48 -04001099# bitmap.rowBytes() is too small to contain one row of pixels. ##
Cary Clark8032b982017-07-28 11:04:54 -04001100##
1101
Cary Clarkbad5ad72017-08-03 17:14:08 -04001102#Param bitmap storage for pixels copied from Canvas ##
Cary Clarkf05bdda2017-08-24 12:59:48 -04001103#Param srcX offset into readable pixels in x; may be negative ##
1104#Param srcY offset into readable pixels in y; may be negative ##
Cary Clark8032b982017-07-28 11:04:54 -04001105
Cary Clarkbad5ad72017-08-03 17:14:08 -04001106#Return true if pixels were copied ##
Cary Clark8032b982017-07-28 11:04:54 -04001107
1108#Example
Cary Clarkf05bdda2017-08-24 12:59:48 -04001109 #Description
Cary Clarkce101242017-09-01 15:51:02 -04001110 clear() takes Unpremultiplied input with Color_Alpha equal 0x80
1111 and Color_RGB equal 0x55, 0xAA, 0xFF. Color_RGB is multiplied by Color_Alpha
1112 to generate Premultiplied value 0x802B5580.
Cary Clarkf05bdda2017-08-24 12:59:48 -04001113 ##
Cary Clark8032b982017-07-28 11:04:54 -04001114void draw(SkCanvas* canvas) {
1115 canvas->clear(0x8055aaff);
1116 SkBitmap bitmap;
1117 bitmap.allocPixels(SkImageInfo::MakeN32Premul(1, 1));
1118 canvas->readPixels(bitmap, 0, 0);
1119 SkDebugf("pixel = %08x\n", bitmap.getAddr32(0, 0)[0]);
1120}
1121 #StdOut
1122 pixel = 802b5580
1123 ##
1124##
1125
Cary Clark2ade9972017-11-02 17:49:34 -04001126#SeeAlso peekPixels writePixels drawBitmap drawImage SkBitmap::readPixels SkPixmap::readPixels SkImage::readPixels SkSurface::readPixels
Cary Clark8032b982017-07-28 11:04:54 -04001127
1128##
1129
1130# ------------------------------------------------------------------------------
1131
1132#Method bool writePixels(const SkImageInfo& info, const void* pixels, size_t rowBytes, int x, int y)
Cary Clark78de7512018-02-07 07:27:09 -05001133#In Pixels
Cary Clarkab2621d2018-01-30 10:08:57 -05001134#Line # copies and converts rectangle of pixels to Canvas ##
Cary Clark154beea2017-10-26 07:58:48 -04001135Copies Rect from pixels to Canvas. Matrix and Clip are ignored.
1136Source Rect corners are (0, 0) and (info.width(), info.height()).
1137Destination Rect corners are (x, y) and
1138(imageInfo().width(), imageInfo().height()).
Cary Clark6fc50412017-09-21 12:31:06 -04001139
1140Copies each readable pixel intersecting both rectangles, without scaling,
Cary Clark154beea2017-10-26 07:58:48 -04001141converting to imageInfo().colorType() and imageInfo().alphaType() if required.
Cary Clark8032b982017-07-28 11:04:54 -04001142
Cary Clarkf05bdda2017-08-24 12:59:48 -04001143Pixels are writable when Device is raster, or backed by a GPU.
1144Pixels are not writable when SkCanvas is returned by SkDocument::beginPage,
1145returned by SkPictureRecorder::beginRecording, or Canvas is the base of a utility
Brian Osman46fe9c72018-03-09 15:44:34 -05001146class like SkDebugCanvas.
Cary Clark8032b982017-07-28 11:04:54 -04001147
Cary Clark2dc84ad2018-01-26 12:56:22 -05001148Pixel values are converted only if Color_Type and Alpha_Type
Cary Clarkf05bdda2017-08-24 12:59:48 -04001149do not match. Only pixels within both source and destination rectangles
Cary Clark154beea2017-10-26 07:58:48 -04001150are copied. Canvas pixels outside Rect intersection are unchanged.
Cary Clark8032b982017-07-28 11:04:54 -04001151
Cary Clarkf05bdda2017-08-24 12:59:48 -04001152Pass negative values for x or y to offset pixels to the left or
1153above Canvas pixels.
Cary Clark8032b982017-07-28 11:04:54 -04001154
1155Does not copy, and returns false if:
1156
1157#List
Cary Clarkf05bdda2017-08-24 12:59:48 -04001158# Source and destination rectangles do not intersect. ##
Cary Clarkac47b882018-01-11 10:35:44 -05001159# pixels could not be converted to Canvas imageInfo().colorType() or
1160 imageInfo().alphaType(). ##
Cary Clark8032b982017-07-28 11:04:54 -04001161# Canvas pixels are not writable; for instance, Canvas is document-based. ##
1162# rowBytes is too small to contain one row of pixels. ##
1163##
1164
Cary Clark2dc84ad2018-01-26 12:56:22 -05001165#Param info width, height, Color_Type, and Alpha_Type of pixels ##
Cary Clarkf05bdda2017-08-24 12:59:48 -04001166#Param pixels pixels to copy, of size info.height() times rowBytes, or larger ##
Cary Clarkd0530ba2017-09-14 11:25:39 -04001167#Param rowBytes size of one row of pixels; info.width() times pixel size, or larger ##
Cary Clarkf05bdda2017-08-24 12:59:48 -04001168#Param x offset into Canvas writable pixels in x; may be negative ##
1169#Param y offset into Canvas writable pixels in y; may be negative ##
Cary Clark8032b982017-07-28 11:04:54 -04001170
Cary Clarkbad5ad72017-08-03 17:14:08 -04001171#Return true if pixels were written to Canvas ##
Cary Clark8032b982017-07-28 11:04:54 -04001172
1173#Example
1174 SkImageInfo imageInfo = SkImageInfo::MakeN32(256, 1, kPremul_SkAlphaType);
1175 for (int y = 0; y < 256; ++y) {
1176 uint32_t pixels[256];
1177 for (int x = 0; x < 256; ++x) {
1178 pixels[x] = SkColorSetARGB(x, x + y, x, x - y);
1179 }
1180 canvas->writePixels(imageInfo, &pixels, sizeof(pixels), 0, y);
1181 }
1182##
1183
Cary Clark2ade9972017-11-02 17:49:34 -04001184#SeeAlso readPixels drawBitmap drawImage SkBitmap::writePixels
Cary Clark8032b982017-07-28 11:04:54 -04001185
1186##
1187
1188# ------------------------------------------------------------------------------
1189
1190#Method bool writePixels(const SkBitmap& bitmap, int x, int y)
1191
Cary Clark154beea2017-10-26 07:58:48 -04001192Copies Rect from pixels to Canvas. Matrix and Clip are ignored.
1193Source Rect corners are (0, 0) and (bitmap.width(), bitmap.height()).
Cary Clark6fc50412017-09-21 12:31:06 -04001194
Cary Clark154beea2017-10-26 07:58:48 -04001195Destination Rect corners are (x, y) and
1196(imageInfo().width(), imageInfo().height()).
Cary Clark6fc50412017-09-21 12:31:06 -04001197
1198Copies each readable pixel intersecting both rectangles, without scaling,
Cary Clark154beea2017-10-26 07:58:48 -04001199converting to imageInfo().colorType() and imageInfo().alphaType() if required.
Cary Clark8032b982017-07-28 11:04:54 -04001200
Cary Clarkf05bdda2017-08-24 12:59:48 -04001201Pixels are writable when Device is raster, or backed by a GPU.
1202Pixels are not writable when SkCanvas is returned by SkDocument::beginPage,
1203returned by SkPictureRecorder::beginRecording, or Canvas is the base of a utility
Brian Osman46fe9c72018-03-09 15:44:34 -05001204class like SkDebugCanvas.
Cary Clark8032b982017-07-28 11:04:54 -04001205
Cary Clark2dc84ad2018-01-26 12:56:22 -05001206Pixel values are converted only if Color_Type and Alpha_Type
Cary Clarkf05bdda2017-08-24 12:59:48 -04001207do not match. Only pixels within both source and destination rectangles
Cary Clark154beea2017-10-26 07:58:48 -04001208are copied. Canvas pixels outside Rect intersection are unchanged.
Cary Clark8032b982017-07-28 11:04:54 -04001209
Cary Clarkf05bdda2017-08-24 12:59:48 -04001210Pass negative values for x or y to offset pixels to the left or
1211above Canvas pixels.
Cary Clark8032b982017-07-28 11:04:54 -04001212
1213Does not copy, and returns false if:
1214
1215#List
Cary Clarkf05bdda2017-08-24 12:59:48 -04001216# Source and destination rectangles do not intersect. ##
Cary Clark8032b982017-07-28 11:04:54 -04001217# bitmap does not have allocated pixels. ##
Cary Clarkac47b882018-01-11 10:35:44 -05001218# bitmap pixels could not be converted to Canvas imageInfo().colorType() or
1219 imageInfo().alphaType(). ##
Cary Clarkce101242017-09-01 15:51:02 -04001220# Canvas pixels are not writable; for instance, Canvas is document based. ##
Cary Clark8032b982017-07-28 11:04:54 -04001221# bitmap pixels are inaccessible; for instance, bitmap wraps a texture. ##
1222##
1223
Cary Clarkbad5ad72017-08-03 17:14:08 -04001224#Param bitmap contains pixels copied to Canvas ##
Cary Clarkf05bdda2017-08-24 12:59:48 -04001225#Param x offset into Canvas writable pixels in x; may be negative ##
1226#Param y offset into Canvas writable pixels in y; may be negative ##
Cary Clark8032b982017-07-28 11:04:54 -04001227
Cary Clarkbad5ad72017-08-03 17:14:08 -04001228#Return true if pixels were written to Canvas ##
Cary Clark8032b982017-07-28 11:04:54 -04001229
1230#Example
1231void draw(SkCanvas* canvas) {
1232 SkImageInfo imageInfo = SkImageInfo::MakeN32Premul(2, 2);
1233 SkBitmap bitmap;
1234 bitmap.setInfo(imageInfo);
1235 uint32_t pixels[4];
1236 bitmap.setPixels(pixels);
1237 for (int y = 0; y < 256; y += 2) {
1238 for (int x = 0; x < 256; x += 2) {
1239 pixels[0] = SkColorSetRGB(x, y, x | y);
1240 pixels[1] = SkColorSetRGB(x ^ y, y, x);
1241 pixels[2] = SkColorSetRGB(x, x & y, y);
1242 pixels[3] = SkColorSetRGB(~x, ~y, x);
1243 canvas->writePixels(bitmap, x, y);
1244 }
1245 }
1246}
1247##
1248
Cary Clark2ade9972017-11-02 17:49:34 -04001249#SeeAlso readPixels drawBitmap drawImage SkBitmap::writePixels
Cary Clark8032b982017-07-28 11:04:54 -04001250
1251##
1252
1253# ------------------------------------------------------------------------------
Cary Clark08895c42018-02-01 09:37:32 -05001254#Subtopic State_Stack
1255#Line # stack of state for hierarchical drawing ##
Cary Clark8032b982017-07-28 11:04:54 -04001256
1257Canvas maintains a stack of state that allows hierarchical drawing, commonly used
Cary Clarkbad5ad72017-08-03 17:14:08 -04001258to implement windows and views. The initial state has an identity matrix and and
1259an infinite clip. Even with a wide-open clip, drawing is constrained by the
1260bounds of the Canvas Surface or Device.
Cary Clark8032b982017-07-28 11:04:54 -04001261
1262Canvas savable state consists of Clip, Matrix, and Draw_Filter.
1263Clip describes the area that may be drawn to.
1264Matrix transforms the geometry.
1265Draw_Filter (deprecated on most platforms) modifies the paint before drawing.
1266
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;
Mike Klein9ff8c8c2018-02-07 01:58:51 +00001293 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
Mike Klein9ff8c8c2018-02-07 01:58:51 +00001296 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}
Mike Klein9ff8c8c2018-02-07 01:58:51 +00001304##
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 Clark8032b982017-07-28 11:04:54 -04001329Saves Matrix, Clip, and Draw_Filter (Draw_Filter deprecated on most platforms).
1330Calling restore() discards changes to Matrix, Clip, and Draw_Filter,
1331restoring the Matrix, Clip, and Draw_Filter to their state when save() was called.
1332
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
Mike Klein9ff8c8c2018-02-07 01:58:51 +00001344#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 Clark8032b982017-07-28 11:04:54 -04001373Removes changes to Matrix, Clip, and Draw_Filter since Canvas state was
Mike Klein9ff8c8c2018-02-07 01:58:51 +00001374last saved. The state is removed from the stack.
Cary Clark8032b982017-07-28 11:04:54 -04001375
Mike Klein9ff8c8c2018-02-07 01:58:51 +00001376Does 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 Clark8032b982017-07-28 11:04:54 -04001397Returns the number of saved states, each containing: Matrix, Clip, and Draw_Filter.
Mike Klein9ff8c8c2018-02-07 01:58:51 +00001398Equals 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 Clarkbad5ad72017-08-03 17:14:08 -04001429Restores state to Matrix, Clip, and Draw_Filter values when save(), saveLayer,
1430saveLayerPreserveLCDTextRequests, or saveLayerAlpha returned saveCount.
Cary Clark8032b982017-07-28 11:04:54 -04001431
Mike Klein9ff8c8c2018-02-07 01:58:51 +00001432Does 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
Mike Klein9ff8c8c2018-02-07 01:58:51 +00001453#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 Clark08895c42018-02-01 09:37:32 -05001464#Line # temporary Bitmap to draw into ##
Cary Clarkce101242017-09-01 15:51:02 -04001465
1466Layer allocates a temporary Bitmap to draw into. When the drawing is
Mike Klein9ff8c8c2018-02-07 01:58:51 +00001467complete, the Bitmap is drawn into the Canvas.
Cary Clarkce101242017-09-01 15:51:02 -04001468
1469Layer is saved in a stack along with other saved state. When state with a Layer
1470is restored, the Bitmap is drawn into the previous Layer.
1471
1472Layer may be initialized with the contents of the previous Layer. When Layer is
1473restored, its Bitmap can be modified by Paint passed to Layer to apply
1474Color_Alpha, Color_Filter, Image_Filter, and Blend_Mode.
1475
1476#Method int saveLayer(const SkRect* bounds, const SkPaint* paint)
1477
Cary Clarkab2621d2018-01-30 10:08:57 -05001478#In Layer
1479#Line # saves Clip and Matrix on stack; creates Layer ##
Cary Clarkce101242017-09-01 15:51:02 -04001480Saves Matrix, Clip, and Draw_Filter (Draw_Filter deprecated on most platforms),
1481and allocates a Bitmap for subsequent drawing.
1482Calling restore() discards changes to Matrix, Clip, and Draw_Filter,
1483and draws the Bitmap.
1484
1485Matrix may be changed by translate(), scale(), rotate(), skew(), concat(),
Mike Klein9ff8c8c2018-02-07 01:58:51 +00001486setMatrix, 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
1508void draw(SkCanvas* canvas) {
1509 SkPaint paint, blur;
Cary Clarka560c472017-11-27 10:44:06 -05001510 blur.setImageFilter(SkBlurImageFilter::Make(3, 3, nullptr));
Cary Clarkce101242017-09-01 15:51:02 -04001511 canvas->saveLayer(nullptr, &blur);
1512 SkRect rect = { 25, 25, 50, 50};
1513 canvas->drawRect(rect, paint);
1514 canvas->translate(50, 50);
1515 paint.setColor(SK_ColorRED);
1516 canvas->drawRect(rect, paint);
1517 canvas->restore();
1518}
1519##
1520
Cary Clark2ade9972017-11-02 17:49:34 -04001521#SeeAlso save() restore() saveLayer saveLayerPreserveLCDTextRequests saveLayerAlpha SaveLayerRec
Cary Clarkce101242017-09-01 15:51:02 -04001522
1523##
1524
Mike Klein9ff8c8c2018-02-07 01:58:51 +00001525#Method int saveLayer(const SkRect& bounds, const SkPaint* paint)
Cary Clarkce101242017-09-01 15:51:02 -04001526
Cary Clarkab2621d2018-01-30 10:08:57 -05001527#In Layer
Cary Clarkce101242017-09-01 15:51:02 -04001528Saves Matrix, Clip, and Draw_Filter (Draw_Filter deprecated on most platforms),
1529and allocates a Bitmap for subsequent drawing.
1530Calling restore() discards changes to Matrix, Clip, and Draw_Filter,
1531and draws the Bitmap.
1532
1533Matrix may be changed by translate(), scale(), rotate(), skew(), concat(),
1534setMatrix, and resetMatrix. Clip may be changed by clipRect, clipRRect,
1535clipPath, clipRegion.
1536
1537Rect bounds suggests but does not define the Layer size. To clip drawing to
1538a specific rectangle, use clipRect.
1539
1540Optional Paint paint applies Color_Alpha, Color_Filter, Image_Filter, and
1541Blend_Mode when restore() is called.
1542
1543Call restoreToCount with returned value to restore this and subsequent saves.
1544
1545#Param bounds hint to limit the size of Layer; may be nullptr ##
1546#Param paint graphics state for Layer; may be nullptr ##
1547
1548#Return depth of saved stack ##
1549
1550#Example
1551#Description
1552Rectangles are blurred by Image_Filter when restore() draws Layer to main Canvas.
Mike Klein9ff8c8c2018-02-07 01:58:51 +00001553The red rectangle is clipped; it does not fully fit on Layer.
Cary Clarkce101242017-09-01 15:51:02 -04001554Image_Filter blurs past edge of Layer so red rectangle is blurred on all sides.
1555##
1556#Height 128
1557void draw(SkCanvas* canvas) {
1558 SkPaint paint, blur;
Cary Clarka560c472017-11-27 10:44:06 -05001559 blur.setImageFilter(SkBlurImageFilter::Make(3, 3, nullptr));
Cary Clarkce101242017-09-01 15:51:02 -04001560 canvas->saveLayer(SkRect::MakeWH(90, 90), &blur);
1561 SkRect rect = { 25, 25, 50, 50};
1562 canvas->drawRect(rect, paint);
1563 canvas->translate(50, 50);
1564 paint.setColor(SK_ColorRED);
1565 canvas->drawRect(rect, paint);
1566 canvas->restore();
1567}
1568##
1569
Cary Clark2ade9972017-11-02 17:49:34 -04001570#SeeAlso save() restore() saveLayerPreserveLCDTextRequests saveLayerAlpha SaveLayerRec
Cary Clarkce101242017-09-01 15:51:02 -04001571
1572##
1573
1574#Method int saveLayerPreserveLCDTextRequests(const SkRect* bounds, const SkPaint* paint)
1575
Cary Clarkab2621d2018-01-30 10:08:57 -05001576#In Layer
1577#Line # saves Clip and Matrix on stack; creates Layer for LCD text ##
Cary Clarkce101242017-09-01 15:51:02 -04001578Saves Matrix, Clip, and Draw_Filter (Draw_Filter deprecated on most platforms),
1579and allocates a Bitmap for subsequent drawing.
1580LCD_Text is preserved when the Layer is drawn to the prior Layer.
1581
1582Calling restore() discards changes to Matrix, Clip, and Draw_Filter,
1583and draws Layer.
1584
1585Matrix may be changed by translate(), scale(), rotate(), skew(), concat(),
1586setMatrix, and resetMatrix. Clip may be changed by clipRect, clipRRect,
1587clipPath, clipRegion.
Mike Klein9ff8c8c2018-02-07 01:58:51 +00001588
Cary Clarkce101242017-09-01 15:51:02 -04001589Rect bounds suggests but does not define the Layer size. To clip drawing to
1590a specific rectangle, use clipRect.
1591
1592Optional Paint paint applies Color_Alpha, Color_Filter, Image_Filter, and
1593Blend_Mode when restore() is called.
1594
1595Call restoreToCount with returned value to restore this and subsequent saves.
1596
1597Draw text on an opaque background so that LCD_Text blends correctly with the
1598prior Layer. LCD_Text drawn on a background with transparency may result in
Cary Clark6fc50412017-09-21 12:31:06 -04001599incorrect blending.
Cary Clarkce101242017-09-01 15:51:02 -04001600
1601#Param bounds hint to limit the size of Layer; may be nullptr ##
1602#Param paint graphics state for Layer; may be nullptr ##
1603
1604#Return depth of saved stack ##
1605
1606#Example
1607 SkPaint paint;
1608 paint.setAntiAlias(true);
1609 paint.setLCDRenderText(true);
1610 paint.setTextSize(20);
1611 for (auto preserve : { false, true } ) {
1612 preserve ? canvas->saveLayerPreserveLCDTextRequests(nullptr, nullptr)
1613 : canvas->saveLayer(nullptr, nullptr);
1614 SkPaint p;
1615 p.setColor(SK_ColorWHITE);
1616 // Comment out the next line to draw on a non-opaque background.
1617 canvas->drawRect(SkRect::MakeLTRB(25, 40, 200, 70), p);
1618 canvas->drawString("Hamburgefons", 30, 60, paint);
1619
1620 p.setColor(0xFFCCCCCC);
1621 canvas->drawRect(SkRect::MakeLTRB(25, 70, 200, 100), p);
1622 canvas->drawString("Hamburgefons", 30, 90, paint);
1623
1624 canvas->restore();
1625 canvas->translate(0, 80);
1626 }
1627 ##
1628
Cary Clark2ade9972017-11-02 17:49:34 -04001629#SeeAlso save() restore() saveLayer saveLayerAlpha SaveLayerRec
Cary Clarkce101242017-09-01 15:51:02 -04001630
1631##
1632
1633#Method int saveLayerAlpha(const SkRect* bounds, U8CPU alpha)
1634
Cary Clarkab2621d2018-01-30 10:08:57 -05001635#In Layer
1636#Line # saves Clip and Matrix on stack; creates Layer; sets opacity ##
Cary Clarkce101242017-09-01 15:51:02 -04001637Saves Matrix, Clip, and Draw_Filter (Draw_Filter deprecated on most platforms),
1638and allocates Bitmap for subsequent drawing.
1639
1640Calling restore() discards changes to Matrix, Clip, and Draw_Filter,
1641and blends Layer with alpha opacity onto prior Layer.
1642
1643Matrix may be changed by translate(), scale(), rotate(), skew(), concat(),
1644setMatrix, and resetMatrix. Clip may be changed by clipRect, clipRRect,
1645clipPath, clipRegion.
1646
1647Rect bounds suggests but does not define Layer size. To clip drawing to
1648a specific rectangle, use clipRect.
1649
1650alpha of zero is fully transparent, 255 is fully opaque.
1651
1652Call restoreToCount with returned value to restore this and subsequent saves.
1653
1654#Param bounds hint to limit the size of Layer; may be nullptr ##
1655#Param alpha opacity of Layer ##
1656
1657#Return depth of saved stack ##
1658
1659#Example
1660 SkPaint paint;
1661 paint.setColor(SK_ColorRED);
1662 canvas->drawCircle(50, 50, 50, paint);
1663 canvas->saveLayerAlpha(nullptr, 128);
1664 paint.setColor(SK_ColorBLUE);
1665 canvas->drawCircle(100, 50, 50, paint);
1666 paint.setColor(SK_ColorGREEN);
1667 paint.setAlpha(128);
1668 canvas->drawCircle(75, 90, 50, paint);
1669 canvas->restore();
1670##
1671
Cary Clark2ade9972017-11-02 17:49:34 -04001672#SeeAlso save() restore() saveLayer saveLayerPreserveLCDTextRequests SaveLayerRec
Cary Clarkce101242017-09-01 15:51:02 -04001673
1674##
1675
Mike Klein9ff8c8c2018-02-07 01:58:51 +00001676#ToDo
Cary Clark08895c42018-02-01 09:37:32 -05001677add new markup to associate typedef SaveLayerFlags with Enum so that, for
1678documentation purposes, this enum is named rather than anonymous
1679##
Cary Clarkce101242017-09-01 15:51:02 -04001680
Cary Clark08895c42018-02-01 09:37:32 -05001681#Enum
1682#Line # sets SaveLayerRec options ##
Cary Clarkce101242017-09-01 15:51:02 -04001683#Code
1684 enum {
Cary Clarkce101242017-09-01 15:51:02 -04001685 kPreserveLCDText_SaveLayerFlag = 1 << 1,
1686 kInitWithPrevious_SaveLayerFlag = 1 << 2,
Mike Reed910ca0f2018-04-25 13:04:05 -04001687 kMaskAgainstCoverage_EXPERIMENTAL_DONT_USE_SaveLayerFlag = 1 << 3,
Cary Clarkce101242017-09-01 15:51:02 -04001688 kDontClipToLayer_Legacy_SaveLayerFlag = kDontClipToLayer_PrivateSaveLayerFlag,
1689 };
Cary Clarkce101242017-09-01 15:51:02 -04001690##
1691
1692SaveLayerFlags provides options that may be used in any combination in SaveLayerRec,
1693defining how Layer allocated by saveLayer operates.
1694
Cary Clarkce101242017-09-01 15:51:02 -04001695#Const kPreserveLCDText_SaveLayerFlag 2
1696 Creates Layer for LCD text. Flag is ignored if Layer Paint contains
1697 Image_Filter or Color_Filter.
1698##
1699
1700#Const kInitWithPrevious_SaveLayerFlag 4
1701 Initializes Layer with the contents of the previous Layer.
1702##
1703
Mike Reed910ca0f2018-04-25 13:04:05 -04001704#Const kMaskAgainstCoverage_EXPERIMENTAL_DONT_USE_SaveLayerFlag 8
1705 Experimental -- don't use
1706##
1707
Cary Clarkce101242017-09-01 15:51:02 -04001708#Const kDontClipToLayer_Legacy_SaveLayerFlag 0x80000000
Cary Clark4855f782018-02-06 09:41:53 -05001709#Deprecated soon
Cary Clarkce101242017-09-01 15:51:02 -04001710##
1711
1712#Example
1713#Height 160
1714#Description
1715Canvas Layer captures red and blue circles scaled up by four.
Mike Klein9ff8c8c2018-02-07 01:58:51 +00001716scalePaint blends Layer back with transparency.
Cary Clarkce101242017-09-01 15:51:02 -04001717##
1718void draw(SkCanvas* canvas) {
1719 SkPaint redPaint, bluePaint, scalePaint;
1720 redPaint.setColor(SK_ColorRED);
1721 canvas->drawCircle(21, 21, 8, redPaint);
1722 bluePaint.setColor(SK_ColorBLUE);
1723 canvas->drawCircle(31, 21, 8, bluePaint);
1724 SkMatrix matrix;
1725 matrix.setScale(4, 4);
1726 scalePaint.setAlpha(0x40);
1727 scalePaint.setImageFilter(
1728 SkImageFilter::MakeMatrixFilter(matrix, kNone_SkFilterQuality, nullptr));
1729 SkCanvas::SaveLayerRec saveLayerRec(nullptr, &scalePaint,
Mike Klein9ff8c8c2018-02-07 01:58:51 +00001730 SkCanvas::kInitWithPrevious_SaveLayerFlag);
Cary Clarkce101242017-09-01 15:51:02 -04001731 canvas->saveLayer(saveLayerRec);
1732 canvas->restore();
1733}
1734##
1735
Cary Clark2ade9972017-11-02 17:49:34 -04001736#SeeAlso save() restore() saveLayer saveLayerPreserveLCDTextRequests saveLayerAlpha SaveLayerRec
Cary Clarkce101242017-09-01 15:51:02 -04001737
1738#Enum ##
1739
Cary Clarka560c472017-11-27 10:44:06 -05001740#Typedef uint32_t SaveLayerFlags
1741
1742##
1743
Cary Clarkce101242017-09-01 15:51:02 -04001744#Struct SaveLayerRec
Cary Clark08895c42018-02-01 09:37:32 -05001745#Line # contains the state used to create the Layer ##
Cary Clarkce101242017-09-01 15:51:02 -04001746#Code
1747 struct SaveLayerRec {
1748 SaveLayerRec*(...
1749
1750 const SkRect* fBounds;
1751 const SkPaint* fPaint;
1752 const SkImageFilter* fBackdrop;
1753 SaveLayerFlags fSaveLayerFlags;
1754 };
1755##
1756
Mike Klein9ff8c8c2018-02-07 01:58:51 +00001757SaveLayerRec contains the state used to create the Layer.
Cary Clarkce101242017-09-01 15:51:02 -04001758
1759#Member const SkRect* fBounds
1760 fBounds is used as a hint to limit the size of Layer; may be nullptr.
1761 fBounds suggests but does not define Layer size. To clip drawing to
1762 a specific rectangle, use clipRect.
1763##
1764
1765#Member const SkPaint* fPaint
1766 fPaint modifies how Layer overlays the prior Layer; may be nullptr.
1767 Color_Alpha, Blend_Mode, Color_Filter, Draw_Looper, Image_Filter, and
1768 Mask_Filter affect Layer draw.
1769##
1770
1771#Member const SkImageFilter* fBackdrop
1772 fBackdrop applies Image_Filter to the prior Layer when copying to the Layer;
1773 may be nullptr. Use kInitWithPrevious_SaveLayerFlag to copy the
1774 prior Layer without an Image_Filter.
1775##
1776
1777#Member const SkImage* fClipMask
1778 restore() clips Layer by the Color_Alpha channel of fClipMask when
1779 Layer is copied to Device. fClipMask may be nullptr. .
1780##
1781
1782#Member const SkMatrix* fClipMatrix
Mike Klein9ff8c8c2018-02-07 01:58:51 +00001783 fClipMatrix transforms fClipMask before it clips Layer. If
Cary Clarkce101242017-09-01 15:51:02 -04001784 fClipMask describes a translucent gradient, it may be scaled and rotated
1785 without introducing artifacts. fClipMatrix may be nullptr.
1786##
1787
1788#Member SaveLayerFlags fSaveLayerFlags
1789 fSaveLayerFlags are used to create Layer without transparency,
1790 create Layer for LCD text, and to create Layer with the
1791 contents of the previous Layer.
1792##
1793
1794#Example
1795#Height 160
1796#Description
1797Canvas Layer captures a red Anti-aliased circle and a blue Aliased circle scaled
1798up by four. After drawing another red circle without scaling on top, the Layer is
Mike Klein9ff8c8c2018-02-07 01:58:51 +00001799transferred to the main canvas.
Cary Clarkce101242017-09-01 15:51:02 -04001800##
1801void draw(SkCanvas* canvas) {
1802 SkPaint redPaint, bluePaint;
1803 redPaint.setAntiAlias(true);
1804 redPaint.setColor(SK_ColorRED);
1805 canvas->drawCircle(21, 21, 8, redPaint);
1806 bluePaint.setColor(SK_ColorBLUE);
1807 canvas->drawCircle(31, 21, 8, bluePaint);
1808 SkMatrix matrix;
1809 matrix.setScale(4, 4);
1810 auto scaler = SkImageFilter::MakeMatrixFilter(matrix, kNone_SkFilterQuality, nullptr);
Mike Klein9ff8c8c2018-02-07 01:58:51 +00001811 SkCanvas::SaveLayerRec saveLayerRec(nullptr, nullptr, scaler.get(), 0);
Cary Clarkce101242017-09-01 15:51:02 -04001812 canvas->saveLayer(saveLayerRec);
1813 canvas->drawCircle(125, 85, 8, redPaint);
1814 canvas->restore();
1815}
1816##
1817
1818#Method SaveLayerRec()
1819
1820Sets fBounds, fPaint, and fBackdrop to nullptr. Clears fSaveLayerFlags.
1821
1822#Return empty SaveLayerRec ##
1823
1824#Example
1825 SkCanvas::SaveLayerRec rec1;
Mike Kleine083f7c2018-02-07 12:54:27 -05001826 rec1.fSaveLayerFlags = SkCanvas::kPreserveLCDText_SaveLayerFlag;
1827 SkCanvas::SaveLayerRec rec2(nullptr, nullptr, SkCanvas::kPreserveLCDText_SaveLayerFlag);
Cary Clarkce101242017-09-01 15:51:02 -04001828 SkDebugf("rec1 %c= rec2\n", rec1.fBounds == rec2.fBounds
1829 && rec1.fPaint == rec2.fPaint
1830 && rec1.fBackdrop == rec2.fBackdrop
1831 && rec1.fSaveLayerFlags == rec2.fSaveLayerFlags ? '=' : '!');
1832 #StdOut
1833 rec1 == rec2
1834 ##
1835##
1836
Cary Clark2ade9972017-11-02 17:49:34 -04001837#SeeAlso save() restore() saveLayer saveLayerPreserveLCDTextRequests saveLayerAlpha
1838
Cary Clarkce101242017-09-01 15:51:02 -04001839##
1840
1841#Method SaveLayerRec(const SkRect* bounds, const SkPaint* paint, SaveLayerFlags saveLayerFlags = 0)
1842
1843Sets fBounds, fPaint, and fSaveLayerFlags; sets fBackdrop to nullptr.
1844
1845#Param bounds Layer dimensions; may be nullptr ##
1846#Param paint applied to Layer when overlaying prior Layer; may be nullptr ##
1847#Param saveLayerFlags SaveLayerRec options to modify Layer ##
1848
1849#Return SaveLayerRec with empty backdrop ##
1850
1851#Example
1852 SkCanvas::SaveLayerRec rec1;
1853 SkCanvas::SaveLayerRec rec2(nullptr, nullptr);
1854 SkDebugf("rec1 %c= rec2\n", rec1.fBounds == rec2.fBounds
1855 && rec1.fPaint == rec2.fPaint
1856 && rec1.fBackdrop == rec2.fBackdrop
1857 && rec1.fSaveLayerFlags == rec2.fSaveLayerFlags ? '=' : '!');
1858 #StdOut
1859 rec1 == rec2
1860 ##
1861##
1862
Cary Clark2ade9972017-11-02 17:49:34 -04001863#SeeAlso save() restore() saveLayer saveLayerPreserveLCDTextRequests saveLayerAlpha
1864
Cary Clarkce101242017-09-01 15:51:02 -04001865##
1866
1867#Method SaveLayerRec(const SkRect* bounds, const SkPaint* paint, const SkImageFilter* backdrop,
1868 SaveLayerFlags saveLayerFlags)
1869
1870Sets fBounds, fPaint, fBackdrop, and fSaveLayerFlags.
1871
1872#Param bounds Layer dimensions; may be nullptr ##
1873#Param paint applied to Layer when overlaying prior Layer;
1874 may be nullptr
1875##
1876#Param backdrop prior Layer copied with Image_Filter; may be nullptr
1877##
1878#Param saveLayerFlags SaveLayerRec options to modify Layer ##
1879
1880#Return SaveLayerRec fully specified ##
1881
1882#Example
1883 SkCanvas::SaveLayerRec rec1;
1884 SkCanvas::SaveLayerRec rec2(nullptr, nullptr, nullptr, 0);
1885 SkDebugf("rec1 %c= rec2\n", rec1.fBounds == rec2.fBounds
1886 && rec1.fPaint == rec2.fPaint
1887 && rec1.fBackdrop == rec2.fBackdrop
1888 && rec1.fSaveLayerFlags == rec2.fSaveLayerFlags ? '=' : '!');
1889 #StdOut
1890 rec1 == rec2
1891 ##
1892##
1893
Cary Clark2ade9972017-11-02 17:49:34 -04001894#SeeAlso save() restore() saveLayer saveLayerPreserveLCDTextRequests saveLayerAlpha
1895
Cary Clarkce101242017-09-01 15:51:02 -04001896##
1897
1898#Method SaveLayerRec(const SkRect* bounds, const SkPaint* paint, const SkImageFilter* backdrop,
1899 const SkImage* clipMask, const SkMatrix* clipMatrix,
1900 SaveLayerFlags saveLayerFlags)
1901
1902#Experimental
1903Not ready for general use.
1904##
1905
1906Sets fBounds, fPaint, fBackdrop, fClipMask, fClipMatrix, and fSaveLayerFlags.
1907clipMatrix uses Color_Alpha channel of image, transformed by clipMatrix, to clip
1908Layer when drawn to Canvas.
1909
Cary Clark2ade9972017-11-02 17:49:34 -04001910Implementation is not complete; has no effect if Device is GPU-backed.
Cary Clarkce101242017-09-01 15:51:02 -04001911
1912#Param bounds Layer dimensions; may be nullptr ##
1913#Param paint graphics state applied to Layer when overlaying prior
1914 Layer; may be nullptr
1915##
1916#Param backdrop prior Layer copied with Image_Filter;
1917 may be nullptr
1918##
1919#Param clipMask clip applied to Layer; may be nullptr ##
1920#Param clipMatrix matrix applied to clipMask; may be nullptr to use
Mike Klein9ff8c8c2018-02-07 01:58:51 +00001921 identity matrix
Cary Clarkce101242017-09-01 15:51:02 -04001922##
1923#Param saveLayerFlags SaveLayerRec options to modify Layer ##
1924
1925#Return SaveLayerRec fully specified ##
1926
Cary Clark2ade9972017-11-02 17:49:34 -04001927#SeeAlso save() restore() saveLayer saveLayerPreserveLCDTextRequests saveLayerAlpha
Cary Clarkce101242017-09-01 15:51:02 -04001928
1929##
1930
1931#Struct ##
1932
1933#Method int saveLayer(const SaveLayerRec& layerRec)
1934
Cary Clarkab2621d2018-01-30 10:08:57 -05001935#In Layer
Cary Clarkce101242017-09-01 15:51:02 -04001936Saves Matrix, Clip, and Draw_Filter (Draw_Filter deprecated on most platforms),
1937and allocates Bitmap for subsequent drawing.
1938
1939Calling restore() discards changes to Matrix, Clip, and Draw_Filter,
1940and blends Bitmap with Color_Alpha opacity onto the prior Layer.
1941
1942Matrix may be changed by translate(), scale(), rotate(), skew(), concat(),
1943setMatrix, and resetMatrix. Clip may be changed by clipRect, clipRRect,
1944clipPath, clipRegion.
1945
1946SaveLayerRec contains the state used to create the Layer.
1947
1948Call restoreToCount with returned value to restore this and subsequent saves.
1949
1950#Param layerRec Layer state ##
1951
1952#Return depth of save state stack ##
1953
1954#Example
1955#Description
1956The example draws an image, and saves it into a Layer with kInitWithPrevious_SaveLayerFlag.
1957Next it punches a hole in Layer and restore with SkBlendMode::kPlus.
1958Where Layer was cleared, the original image will draw unchanged.
1959Outside of the circle the mandrill is brightened.
1960##
1961 #Image 3
Hal Canaryc465d132017-12-08 10:21:31 -05001962 // sk_sp<SkImage> image = GetResourceAsImage("images/mandrill_256.png");
Cary Clarkce101242017-09-01 15:51:02 -04001963 canvas->drawImage(image, 0, 0, nullptr);
1964 SkCanvas::SaveLayerRec rec;
1965 SkPaint paint;
1966 paint.setBlendMode(SkBlendMode::kPlus);
1967 rec.fSaveLayerFlags = SkCanvas::kInitWithPrevious_SaveLayerFlag;
1968 rec.fPaint = &paint;
1969 canvas->saveLayer(rec);
1970 paint.setBlendMode(SkBlendMode::kClear);
1971 canvas->drawCircle(128, 128, 96, paint);
1972 canvas->restore();
1973##
1974
1975#ToDo above example needs to replace GetResourceAsImage with way to select image in fiddle ##
1976
Cary Clark2ade9972017-11-02 17:49:34 -04001977#SeeAlso save() restore() saveLayer saveLayerPreserveLCDTextRequests saveLayerAlpha
1978
Cary Clarkce101242017-09-01 15:51:02 -04001979##
1980
Cary Clark08895c42018-02-01 09:37:32 -05001981#Subtopic Layer ##
Cary Clarkce101242017-09-01 15:51:02 -04001982
1983# ------------------------------------------------------------------------------
Cary Clark08895c42018-02-01 09:37:32 -05001984#Subtopic Matrix
1985#Line # coordinate transformation ##
Cary Clark8032b982017-07-28 11:04:54 -04001986
1987#Method void translate(SkScalar dx, SkScalar dy)
1988
Cary Clarkab2621d2018-01-30 10:08:57 -05001989#In Matrix
1990#Line # translates Matrix ##
Cary Clark8032b982017-07-28 11:04:54 -04001991Translate Matrix by dx along the x-axis and dy along the y-axis.
1992
1993Mathematically, replace Matrix with a translation matrix
Mike Klein9ff8c8c2018-02-07 01:58:51 +00001994Premultiplied with Matrix.
Cary Clark8032b982017-07-28 11:04:54 -04001995
1996This has the effect of moving the drawing by (dx, dy) before transforming
1997the result with Matrix.
1998
Cary Clarkbad5ad72017-08-03 17:14:08 -04001999#Param dx distance to translate in x ##
2000#Param dy distance to translate in y ##
Cary Clark8032b982017-07-28 11:04:54 -04002001
2002#Example
2003#Height 128
2004#Description
2005scale() followed by translate() produces different results from translate() followed
Mike Klein9ff8c8c2018-02-07 01:58:51 +00002006by scale().
Cary Clark8032b982017-07-28 11:04:54 -04002007
2008The blue stroke follows translate of (50, 50); a black
Mike Klein9ff8c8c2018-02-07 01:58:51 +00002009fill follows scale of (2, 1/2.f). After restoring the clip, which resets
Cary Clark8032b982017-07-28 11:04:54 -04002010Matrix, a red frame follows the same scale of (2, 1/2.f); a gray fill
2011follows translate of (50, 50).
2012##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002013void draw(SkCanvas* canvas) {
2014 SkPaint filledPaint;
2015 SkPaint outlinePaint;
2016 outlinePaint.setStyle(SkPaint::kStroke_Style);
2017 outlinePaint.setColor(SK_ColorBLUE);
2018 canvas->save();
2019 canvas->translate(50, 50);
2020 canvas->drawCircle(28, 28, 15, outlinePaint); // blue center: (50+28, 50+28)
2021 canvas->scale(2, 1/2.f);
2022 canvas->drawCircle(28, 28, 15, filledPaint); // black center: (50+(28*2), 50+(28/2))
2023 canvas->restore();
2024 filledPaint.setColor(SK_ColorGRAY);
2025 outlinePaint.setColor(SK_ColorRED);
2026 canvas->scale(2, 1/2.f);
2027 canvas->drawCircle(28, 28, 15, outlinePaint); // red center: (28*2, 28/2)
2028 canvas->translate(50, 50);
2029 canvas->drawCircle(28, 28, 15, filledPaint); // gray center: ((50+28)*2, (50+28)/2)
Cary Clark8032b982017-07-28 11:04:54 -04002030}
2031##
2032
Cary Clark2ade9972017-11-02 17:49:34 -04002033#SeeAlso concat() scale() skew() rotate() setMatrix
Cary Clark8032b982017-07-28 11:04:54 -04002034
2035##
2036
2037# ------------------------------------------------------------------------------
2038
2039#Method void scale(SkScalar sx, SkScalar sy)
2040
Cary Clarkab2621d2018-01-30 10:08:57 -05002041#In Matrix
2042#Line # scales Matrix ##
Cary Clark8032b982017-07-28 11:04:54 -04002043Scale Matrix by sx on the x-axis and sy on the y-axis.
2044
2045Mathematically, replace Matrix with a scale matrix
Mike Klein9ff8c8c2018-02-07 01:58:51 +00002046Premultiplied with Matrix.
Cary Clark8032b982017-07-28 11:04:54 -04002047
2048This has the effect of scaling the drawing by (sx, sy) before transforming
2049the result with Matrix.
2050
Cary Clarkbad5ad72017-08-03 17:14:08 -04002051#Param sx amount to scale in x ##
2052#Param sy amount to scale in y ##
Cary Clark8032b982017-07-28 11:04:54 -04002053
2054#Example
2055#Height 160
Cary Clarkbad5ad72017-08-03 17:14:08 -04002056void draw(SkCanvas* canvas) {
2057 SkPaint paint;
2058 SkRect rect = { 10, 20, 60, 120 };
2059 canvas->translate(20, 20);
2060 canvas->drawRect(rect, paint);
2061 canvas->scale(2, .5f);
2062 paint.setColor(SK_ColorGRAY);
2063 canvas->drawRect(rect, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002064}
2065##
2066
Cary Clark2ade9972017-11-02 17:49:34 -04002067#SeeAlso concat() translate() skew() rotate() setMatrix
Cary Clark8032b982017-07-28 11:04:54 -04002068
2069##
2070
2071# ------------------------------------------------------------------------------
2072
2073#Method void rotate(SkScalar degrees)
2074
Cary Clarkab2621d2018-01-30 10:08:57 -05002075#In Matrix
2076#Line # rotates Matrix ##
Cary Clark8032b982017-07-28 11:04:54 -04002077Rotate Matrix by degrees. Positive degrees rotates clockwise.
2078
2079Mathematically, replace Matrix with a rotation matrix
Mike Klein9ff8c8c2018-02-07 01:58:51 +00002080Premultiplied with Matrix.
Cary Clark8032b982017-07-28 11:04:54 -04002081
2082This has the effect of rotating the drawing by degrees before transforming
2083the result with Matrix.
2084
Cary Clarkbad5ad72017-08-03 17:14:08 -04002085#Param degrees amount to rotate, in degrees ##
Cary Clark8032b982017-07-28 11:04:54 -04002086
2087#Example
2088#Description
2089Draw clock hands at time 5:10. The hour hand and minute hand point up and
2090are rotated clockwise.
2091##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002092void draw(SkCanvas* canvas) {
2093 SkPaint paint;
2094 paint.setStyle(SkPaint::kStroke_Style);
2095 canvas->translate(128, 128);
2096 canvas->drawCircle(0, 0, 60, paint);
2097 canvas->save();
2098 canvas->rotate(10 * 360 / 60); // 10 minutes of 60 scaled to 360 degrees
Mike Klein9ff8c8c2018-02-07 01:58:51 +00002099 canvas->drawLine(0, 0, 0, -50, paint);
Cary Clarkbad5ad72017-08-03 17:14:08 -04002100 canvas->restore();
2101 canvas->rotate((5 + 10.f/60) * 360 / 12); // 5 and 10/60 hours of 12 scaled to 360 degrees
2102 canvas->drawLine(0, 0, 0, -30, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002103}
2104##
2105
Cary Clark2ade9972017-11-02 17:49:34 -04002106#SeeAlso concat() translate() skew() scale() setMatrix
Cary Clark8032b982017-07-28 11:04:54 -04002107
2108##
2109
2110# ------------------------------------------------------------------------------
2111
2112#Method void rotate(SkScalar degrees, SkScalar px, SkScalar py)
2113
Cary Clarkab2621d2018-01-30 10:08:57 -05002114#In Matrix
Cary Clarkbad5ad72017-08-03 17:14:08 -04002115Rotate Matrix by degrees about a point at (px, py). Positive degrees rotates
2116clockwise.
Cary Clark8032b982017-07-28 11:04:54 -04002117
Cary Clarkce101242017-09-01 15:51:02 -04002118Mathematically, construct a rotation matrix. Premultiply the rotation matrix by
Cary Clark8032b982017-07-28 11:04:54 -04002119a translation matrix, then replace Matrix with the resulting matrix
Mike Klein9ff8c8c2018-02-07 01:58:51 +00002120Premultiplied with Matrix.
Cary Clark8032b982017-07-28 11:04:54 -04002121
Cary Clarkbad5ad72017-08-03 17:14:08 -04002122This has the effect of rotating the drawing about a given point before
2123transforming the result with Matrix.
Cary Clark8032b982017-07-28 11:04:54 -04002124
Cary Clarkbad5ad72017-08-03 17:14:08 -04002125#Param degrees amount to rotate, in degrees ##
2126#Param px x-coordinate of the point to rotate about ##
2127#Param py y-coordinate of the point to rotate about ##
Cary Clark8032b982017-07-28 11:04:54 -04002128
2129#Example
2130#Height 192
Cary Clarkbad5ad72017-08-03 17:14:08 -04002131void draw(SkCanvas* canvas) {
2132 SkPaint paint;
2133 paint.setTextSize(96);
2134 canvas->drawString("A1", 130, 100, paint);
2135 canvas->rotate(180, 130, 100);
2136 canvas->drawString("A1", 130, 100, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002137}
2138##
2139
Cary Clark2ade9972017-11-02 17:49:34 -04002140#SeeAlso concat() translate() skew() scale() setMatrix
Cary Clark8032b982017-07-28 11:04:54 -04002141
2142##
2143
2144# ------------------------------------------------------------------------------
2145
2146#Method void skew(SkScalar sx, SkScalar sy)
2147
Cary Clarkab2621d2018-01-30 10:08:57 -05002148#In Matrix
2149#Line # skews Matrix ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002150Skew Matrix by sx on the x-axis and sy on the y-axis. A positive value of sx
2151skews the drawing right as y increases; a positive value of sy skews the drawing
2152down as x increases.
Cary Clark8032b982017-07-28 11:04:54 -04002153
Mike Klein9ff8c8c2018-02-07 01:58:51 +00002154Mathematically, replace Matrix with a skew matrix Premultiplied with Matrix.
Cary Clark8032b982017-07-28 11:04:54 -04002155
Cary Clarkbad5ad72017-08-03 17:14:08 -04002156This has the effect of skewing the drawing by (sx, sy) before transforming
Cary Clark8032b982017-07-28 11:04:54 -04002157the result with Matrix.
2158
Cary Clarkbad5ad72017-08-03 17:14:08 -04002159#Param sx amount to skew in x ##
2160#Param sy amount to skew in y ##
2161
Cary Clark8032b982017-07-28 11:04:54 -04002162#Example
Mike Klein9ff8c8c2018-02-07 01:58:51 +00002163 #Description
Cary Clark8032b982017-07-28 11:04:54 -04002164 Black text mimics an oblique text style by using a negative skew in x that
2165 shifts the geometry to the right as the y values decrease.
2166 Red text uses a positive skew in y to shift the geometry down as the x values
2167 increase.
2168 Blue text combines x and y skew to rotate and scale.
2169 ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002170 SkPaint paint;
2171 paint.setTextSize(128);
2172 canvas->translate(30, 130);
2173 canvas->save();
2174 canvas->skew(-.5, 0);
2175 canvas->drawString("A1", 0, 0, paint);
2176 canvas->restore();
2177 canvas->save();
2178 canvas->skew(0, .5);
2179 paint.setColor(SK_ColorRED);
2180 canvas->drawString("A1", 0, 0, paint);
2181 canvas->restore();
2182 canvas->skew(-.5, .5);
2183 paint.setColor(SK_ColorBLUE);
Cary Clark8032b982017-07-28 11:04:54 -04002184 canvas->drawString("A1", 0, 0, paint);
2185##
2186
Cary Clark2ade9972017-11-02 17:49:34 -04002187#SeeAlso concat() translate() rotate() scale() setMatrix
Cary Clark8032b982017-07-28 11:04:54 -04002188
2189##
2190
2191# ------------------------------------------------------------------------------
2192
2193#Method void concat(const SkMatrix& matrix)
2194
Cary Clarkab2621d2018-01-30 10:08:57 -05002195#In Matrix
2196#Line # multiplies Matrix by Matrix ##
Cary Clarkce101242017-09-01 15:51:02 -04002197Replace Matrix with matrix Premultiplied with existing Matrix.
Cary Clark8032b982017-07-28 11:04:54 -04002198
Cary Clarkbad5ad72017-08-03 17:14:08 -04002199This has the effect of transforming the drawn geometry by matrix, before
2200transforming the result with existing Matrix.
Cary Clark8032b982017-07-28 11:04:54 -04002201
Cary Clarkce101242017-09-01 15:51:02 -04002202#Param matrix matrix to Premultiply with existing Matrix ##
Cary Clark8032b982017-07-28 11:04:54 -04002203
2204#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04002205void draw(SkCanvas* canvas) {
2206 SkPaint paint;
2207 paint.setTextSize(80);
2208 paint.setTextScaleX(.3);
2209 SkMatrix matrix;
2210 SkRect rect[2] = {{ 10, 20, 90, 110 }, { 40, 130, 140, 180 }};
2211 matrix.setRectToRect(rect[0], rect[1], SkMatrix::kFill_ScaleToFit);
2212 canvas->drawRect(rect[0], paint);
2213 canvas->drawRect(rect[1], paint);
2214 paint.setColor(SK_ColorWHITE);
2215 canvas->drawString("Here", rect[0].fLeft + 10, rect[0].fBottom - 10, paint);
2216 canvas->concat(matrix);
2217 canvas->drawString("There", rect[0].fLeft + 10, rect[0].fBottom - 10, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002218}
2219##
2220
Cary Clark2ade9972017-11-02 17:49:34 -04002221#SeeAlso translate() rotate() scale() skew() setMatrix
Cary Clark8032b982017-07-28 11:04:54 -04002222
2223##
2224
2225# ------------------------------------------------------------------------------
2226
2227#Method void setMatrix(const SkMatrix& matrix)
2228
Cary Clarkab2621d2018-01-30 10:08:57 -05002229#In Matrix
2230#Line # sets Matrix ##
Cary Clark8032b982017-07-28 11:04:54 -04002231Replace Matrix with matrix.
2232Unlike concat(), any prior matrix state is overwritten.
2233
Cary Clarkbad5ad72017-08-03 17:14:08 -04002234#Param matrix matrix to copy, replacing existing Matrix ##
Cary Clark8032b982017-07-28 11:04:54 -04002235
2236#Example
2237#Height 128
Cary Clarkbad5ad72017-08-03 17:14:08 -04002238void draw(SkCanvas* canvas) {
2239 SkPaint paint;
2240 canvas->scale(4, 6);
2241 canvas->drawString("truth", 2, 10, paint);
2242 SkMatrix matrix;
2243 matrix.setScale(2.8f, 6);
2244 canvas->setMatrix(matrix);
2245 canvas->drawString("consequences", 2, 20, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002246}
2247##
2248
Cary Clark2ade9972017-11-02 17:49:34 -04002249#SeeAlso resetMatrix concat() translate() rotate() scale() skew()
Cary Clark8032b982017-07-28 11:04:54 -04002250
2251##
2252
2253# ------------------------------------------------------------------------------
2254
2255#Method void resetMatrix()
2256
Cary Clarkab2621d2018-01-30 10:08:57 -05002257#In Matrix
2258#Line # resets Matrix to identity ##
Cary Clark8032b982017-07-28 11:04:54 -04002259Sets Matrix to the identity matrix.
2260Any prior matrix state is overwritten.
2261
2262#Example
2263#Height 128
Cary Clarkbad5ad72017-08-03 17:14:08 -04002264void draw(SkCanvas* canvas) {
2265 SkPaint paint;
2266 canvas->scale(4, 6);
2267 canvas->drawString("truth", 2, 10, paint);
2268 canvas->resetMatrix();
2269 canvas->scale(2.8f, 6);
2270 canvas->drawString("consequences", 2, 20, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002271}
2272##
2273
Cary Clark2ade9972017-11-02 17:49:34 -04002274#SeeAlso setMatrix concat() translate() rotate() scale() skew()
Cary Clark8032b982017-07-28 11:04:54 -04002275
2276##
2277
2278# ------------------------------------------------------------------------------
2279
2280#Method const SkMatrix& getTotalMatrix() const
2281
Cary Clarkab2621d2018-01-30 10:08:57 -05002282#In Matrix
2283#Line # returns Matrix ##
Cary Clark8032b982017-07-28 11:04:54 -04002284Returns Matrix.
2285This does not account for translation by Device or Surface.
2286
Cary Clarkbad5ad72017-08-03 17:14:08 -04002287#Return Matrix in Canvas ##
Cary Clark8032b982017-07-28 11:04:54 -04002288
2289#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04002290 SkDebugf("isIdentity %s\n", canvas->getTotalMatrix().isIdentity() ? "true" : "false");
2291 #StdOut
2292 isIdentity true
2293 ##
Cary Clark8032b982017-07-28 11:04:54 -04002294##
2295
Cary Clark2ade9972017-11-02 17:49:34 -04002296#SeeAlso setMatrix resetMatrix concat()
Cary Clark8032b982017-07-28 11:04:54 -04002297
2298##
2299
Cary Clark08895c42018-02-01 09:37:32 -05002300#Subtopic Matrix ##
Cary Clark8032b982017-07-28 11:04:54 -04002301
2302# ------------------------------------------------------------------------------
Cary Clark08895c42018-02-01 09:37:32 -05002303#Subtopic Clip
2304#Line # stack of clipping Paths ##
Cary Clark8032b982017-07-28 11:04:54 -04002305
2306Clip is built from a stack of clipping paths. Each Path in the
Mike Klein9ff8c8c2018-02-07 01:58:51 +00002307stack can be constructed from one or more Path_Contour elements. The
Cary Clark8032b982017-07-28 11:04:54 -04002308Path_Contour may be composed of any number of Path_Verb segments. Each
2309Path_Contour forms a closed area; Path_Fill_Type defines the area enclosed
2310by Path_Contour.
2311
2312Clip stack of Path elements successfully restrict the Path area. Each
Mike Klein9ff8c8c2018-02-07 01:58:51 +00002313Path is transformed by Matrix, then intersected with or subtracted from the
Cary Clark8032b982017-07-28 11:04:54 -04002314prior Clip to form the replacement Clip. Use SkClipOp::kDifference
2315to subtract Path from Clip; use SkClipOp::kIntersect to intersect Path
2316with Clip.
2317
Cary Clarkce101242017-09-01 15:51:02 -04002318A clipping Path may be Anti-aliased; if Path, after transformation, is
Cary Clark8032b982017-07-28 11:04:54 -04002319composed of horizontal and vertical lines, clearing Anti-alias allows whole pixels
Cary Clarkce101242017-09-01 15:51:02 -04002320to either be inside or outside the clip. The fastest drawing has a Aliased,
2321rectangular clip.
Cary Clark8032b982017-07-28 11:04:54 -04002322
2323If clipping Path has Anti-alias set, clip may partially clip a pixel, requiring
Mike Klein9ff8c8c2018-02-07 01:58:51 +00002324that drawing blend partially with the destination along the edge. A rotated
Cary Clarkce101242017-09-01 15:51:02 -04002325rectangular Anti-aliased clip looks smoother but draws slower.
Cary Clark8032b982017-07-28 11:04:54 -04002326
2327Clip can combine with Rect and Round_Rect primitives; like
2328Path, these are transformed by Matrix before they are combined with Clip.
2329
2330Clip can combine with Region. Region is assumed to be in Device coordinates
2331and is unaffected by Matrix.
2332
2333#Example
2334#Height 90
2335 #Description
Cary Clarkce101242017-09-01 15:51:02 -04002336 Draw a red circle with an Aliased clip and an Anti-aliased clip.
Cary Clark8032b982017-07-28 11:04:54 -04002337 Use an image filter to zoom into the pixels drawn.
Cary Clarkce101242017-09-01 15:51:02 -04002338 The edge of the Aliased clip fully draws pixels in the red circle.
2339 The edge of the Anti-aliased clip partially draws pixels in the red circle.
Cary Clark8032b982017-07-28 11:04:54 -04002340 ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002341 SkPaint redPaint, scalePaint;
2342 redPaint.setAntiAlias(true);
2343 redPaint.setColor(SK_ColorRED);
2344 canvas->save();
2345 for (bool antialias : { false, true } ) {
2346 canvas->save();
2347 canvas->clipRect(SkRect::MakeWH(19.5f, 11.5f), antialias);
2348 canvas->drawCircle(17, 11, 8, redPaint);
2349 canvas->restore();
2350 canvas->translate(16, 0);
2351 }
2352 canvas->restore();
2353 SkMatrix matrix;
2354 matrix.setScale(6, 6);
2355 scalePaint.setImageFilter(
2356 SkImageFilter::MakeMatrixFilter(matrix, kNone_SkFilterQuality, nullptr));
2357 SkCanvas::SaveLayerRec saveLayerRec(
Mike Klein9ff8c8c2018-02-07 01:58:51 +00002358 nullptr, &scalePaint, SkCanvas::kInitWithPrevious_SaveLayerFlag);
Cary Clarkbad5ad72017-08-03 17:14:08 -04002359 canvas->saveLayer(saveLayerRec);
Cary Clark8032b982017-07-28 11:04:54 -04002360 canvas->restore();
2361##
2362
2363#Method void clipRect(const SkRect& rect, SkClipOp op, bool doAntiAlias)
2364
Cary Clarkab2621d2018-01-30 10:08:57 -05002365#In Clip
2366#Line # combines Clip with Rect ##
Cary Clark8032b982017-07-28 11:04:54 -04002367Replace Clip with the intersection or difference of Clip and rect,
Cary Clarkce101242017-09-01 15:51:02 -04002368with an Aliased or Anti-aliased clip edge. rect is transformed by Matrix
Cary Clark8032b982017-07-28 11:04:54 -04002369before it is combined with Clip.
2370
Cary Clarka523d2d2017-08-30 08:58:10 -04002371#Param rect Rect to combine with Clip ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002372#Param op Clip_Op to apply to Clip ##
Cary Clarkce101242017-09-01 15:51:02 -04002373#Param doAntiAlias true if Clip is to be Anti-aliased ##
Cary Clark8032b982017-07-28 11:04:54 -04002374
2375#Example
2376#Height 128
Cary Clarkbad5ad72017-08-03 17:14:08 -04002377void draw(SkCanvas* canvas) {
2378 canvas->rotate(10);
2379 SkPaint paint;
2380 paint.setAntiAlias(true);
2381 for (auto alias: { false, true } ) {
2382 canvas->save();
2383 canvas->clipRect(SkRect::MakeWH(90, 80), SkClipOp::kIntersect, alias);
2384 canvas->drawCircle(100, 60, 60, paint);
2385 canvas->restore();
2386 canvas->translate(80, 0);
2387 }
Cary Clark8032b982017-07-28 11:04:54 -04002388}
2389##
2390
Cary Clark2ade9972017-11-02 17:49:34 -04002391#SeeAlso clipRRect clipPath clipRegion
Cary Clark8032b982017-07-28 11:04:54 -04002392
2393##
2394
Mike Klein9ff8c8c2018-02-07 01:58:51 +00002395#Method void clipRect(const SkRect& rect, SkClipOp op)
Cary Clark8032b982017-07-28 11:04:54 -04002396
Cary Clarkab2621d2018-01-30 10:08:57 -05002397#In Clip
Cary Clark8032b982017-07-28 11:04:54 -04002398Replace Clip with the intersection or difference of Clip and rect.
Cary Clarkce101242017-09-01 15:51:02 -04002399Resulting Clip is Aliased; pixels are fully contained by the clip.
Cary Clarkbad5ad72017-08-03 17:14:08 -04002400rect is transformed by Matrix before it is combined with Clip.
Cary Clark8032b982017-07-28 11:04:54 -04002401
Cary Clarka523d2d2017-08-30 08:58:10 -04002402#Param rect Rect to combine with Clip ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002403#Param op Clip_Op to apply to Clip ##
Cary Clark8032b982017-07-28 11:04:54 -04002404
2405#Example
2406#Height 192
2407#Width 280
Cary Clarkbad5ad72017-08-03 17:14:08 -04002408void draw(SkCanvas* canvas) {
2409 SkPaint paint;
2410 for (SkClipOp op: { SkClipOp::kIntersect, SkClipOp::kDifference } ) {
2411 canvas->save();
2412 canvas->clipRect(SkRect::MakeWH(90, 120), op, false);
2413 canvas->drawCircle(100, 100, 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
Mike Klein9ff8c8c2018-02-07 01:58:51 +00002424#Method void clipRect(const SkRect& rect, bool doAntiAlias = false)
Cary Clark8032b982017-07-28 11:04:54 -04002425
Cary Clarkab2621d2018-01-30 10:08:57 -05002426#In Clip
Cary Clark8032b982017-07-28 11:04:54 -04002427Replace Clip with the intersection of Clip and rect.
Cary Clarkce101242017-09-01 15:51:02 -04002428Resulting Clip is Aliased; pixels are fully contained by the clip.
Cary Clark8032b982017-07-28 11:04:54 -04002429rect is transformed by Matrix
2430before it is combined with Clip.
2431
Cary Clarka523d2d2017-08-30 08:58:10 -04002432#Param rect Rect to combine with Clip ##
Cary Clarkce101242017-09-01 15:51:02 -04002433#Param doAntiAlias true if Clip is to be Anti-aliased ##
Cary Clark8032b982017-07-28 11:04:54 -04002434
2435#Example
2436#Height 133
2437 #Description
Cary Clarkce101242017-09-01 15:51:02 -04002438 A circle drawn in pieces looks uniform when drawn Aliased.
2439 The same circle pieces blend with pixels more than once when Anti-aliased,
Cary Clark8032b982017-07-28 11:04:54 -04002440 visible as a thin pair of lines through the right circle.
2441 ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002442void draw(SkCanvas* canvas) {
2443 canvas->clear(SK_ColorWHITE);
2444 SkPaint paint;
2445 paint.setAntiAlias(true);
2446 paint.setColor(0x8055aaff);
2447 SkRect clipRect = { 0, 0, 87.4f, 87.4f };
2448 for (auto alias: { false, true } ) {
2449 canvas->save();
2450 canvas->clipRect(clipRect, SkClipOp::kIntersect, alias);
2451 canvas->drawCircle(67, 67, 60, paint);
2452 canvas->restore();
2453 canvas->save();
2454 canvas->clipRect(clipRect, SkClipOp::kDifference, alias);
2455 canvas->drawCircle(67, 67, 60, paint);
2456 canvas->restore();
2457 canvas->translate(120, 0);
2458 }
Cary Clark8032b982017-07-28 11:04:54 -04002459}
2460##
2461
Cary Clark2ade9972017-11-02 17:49:34 -04002462#SeeAlso clipRRect clipPath clipRegion
Cary Clark8032b982017-07-28 11:04:54 -04002463
2464##
2465
2466#Method void androidFramework_setDeviceClipRestriction(const SkIRect& rect)
2467
Cary Clarkab2621d2018-01-30 10:08:57 -05002468#In Clip
2469#Line # for use by Android framework ##
Cary Clarkce101242017-09-01 15:51:02 -04002470Sets the maximum clip rectangle, which can be set by clipRect, clipRRect and
Cary Clark8032b982017-07-28 11:04:54 -04002471clipPath and intersect the current clip with the specified rect.
Cary Clarkce101242017-09-01 15:51:02 -04002472The maximum clip affects only future clipping operations; it is not retroactive.
Cary Clark8032b982017-07-28 11:04:54 -04002473The clip restriction is not recorded in pictures.
2474
Mike Klein9ff8c8c2018-02-07 01:58:51 +00002475Pass an empty rect to disable maximum clip.
Cary Clarkbad5ad72017-08-03 17:14:08 -04002476
Cary Clark8032b982017-07-28 11:04:54 -04002477#Private
2478This is private API to be used only by Android framework.
2479##
2480
Cary Clarkbad5ad72017-08-03 17:14:08 -04002481#Param rect maximum allowed clip in device coordinates
Cary Clark579985c2017-07-31 11:48:27 -04002482#Param ##
Cary Clark8032b982017-07-28 11:04:54 -04002483
2484##
2485
2486#Method void clipRRect(const SkRRect& rrect, SkClipOp op, bool doAntiAlias)
2487
Cary Clarkab2621d2018-01-30 10:08:57 -05002488#In Clip
2489#Line # combines Clip with Round_Rect ##
Cary Clark8032b982017-07-28 11:04:54 -04002490Replace Clip with the intersection or difference of Clip and rrect,
Cary Clarkce101242017-09-01 15:51:02 -04002491with an Aliased or Anti-aliased clip edge.
Cary Clark8032b982017-07-28 11:04:54 -04002492rrect is transformed by Matrix
2493before it is combined with Clip.
2494
Cary Clarkbad5ad72017-08-03 17:14:08 -04002495#Param rrect Round_Rect to combine with Clip ##
2496#Param op Clip_Op to apply to Clip ##
Cary Clarkce101242017-09-01 15:51:02 -04002497#Param doAntiAlias true if Clip is to be Anti-aliased ##
Cary Clark8032b982017-07-28 11:04:54 -04002498
2499#Example
2500#Height 128
Cary Clarkbad5ad72017-08-03 17:14:08 -04002501void draw(SkCanvas* canvas) {
2502 canvas->clear(SK_ColorWHITE);
2503 SkPaint paint;
2504 paint.setAntiAlias(true);
2505 paint.setColor(0x8055aaff);
2506 SkRRect oval;
2507 oval.setOval({10, 20, 90, 100});
2508 canvas->clipRRect(oval, SkClipOp::kIntersect, true);
2509 canvas->drawCircle(70, 100, 60, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002510}
2511##
2512
Cary Clark2ade9972017-11-02 17:49:34 -04002513#SeeAlso clipRect clipPath clipRegion
Cary Clark8032b982017-07-28 11:04:54 -04002514
2515##
2516
Mike Klein9ff8c8c2018-02-07 01:58:51 +00002517#Method void clipRRect(const SkRRect& rrect, SkClipOp op)
Cary Clark8032b982017-07-28 11:04:54 -04002518
Cary Clarkab2621d2018-01-30 10:08:57 -05002519#In Clip
Cary Clark8032b982017-07-28 11:04:54 -04002520Replace Clip with the intersection or difference of Clip and rrect.
Cary Clarkce101242017-09-01 15:51:02 -04002521Resulting Clip is Aliased; pixels are fully contained by the clip.
Cary Clarkbad5ad72017-08-03 17:14:08 -04002522rrect is transformed by Matrix before it is combined with Clip.
Cary Clark8032b982017-07-28 11:04:54 -04002523
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 Clark8032b982017-07-28 11:04:54 -04002526
2527#Example
2528#Height 128
Cary Clarkbad5ad72017-08-03 17:14:08 -04002529void draw(SkCanvas* canvas) {
2530 SkPaint paint;
2531 paint.setColor(0x8055aaff);
2532 auto oval = SkRRect::MakeOval({10, 20, 90, 100});
2533 canvas->clipRRect(oval, SkClipOp::kIntersect);
2534 canvas->drawCircle(70, 100, 60, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002535}
2536##
2537
Cary Clark2ade9972017-11-02 17:49:34 -04002538#SeeAlso clipRect clipPath clipRegion
Cary Clark8032b982017-07-28 11:04:54 -04002539
2540##
2541
Mike Klein9ff8c8c2018-02-07 01:58:51 +00002542#Method void clipRRect(const SkRRect& rrect, bool doAntiAlias = false)
Cary Clark8032b982017-07-28 11:04:54 -04002543
Cary Clarkab2621d2018-01-30 10:08:57 -05002544#In Clip
Cary Clark8032b982017-07-28 11:04:54 -04002545Replace Clip with the intersection of Clip and rrect,
Cary Clarkce101242017-09-01 15:51:02 -04002546with an Aliased or Anti-aliased clip edge.
Cary Clarkbad5ad72017-08-03 17:14:08 -04002547rrect is transformed by Matrix before it is combined with Clip.
Cary Clark8032b982017-07-28 11:04:54 -04002548
Cary Clarkbad5ad72017-08-03 17:14:08 -04002549#Param rrect Round_Rect to combine with Clip ##
Cary Clarkce101242017-09-01 15:51:02 -04002550#Param doAntiAlias true if Clip is to be Anti-aliased ##
Cary Clark8032b982017-07-28 11:04:54 -04002551
2552#Example
2553#Height 128
Cary Clarkbad5ad72017-08-03 17:14:08 -04002554void draw(SkCanvas* canvas) {
2555 SkPaint paint;
2556 paint.setAntiAlias(true);
2557 auto oval = SkRRect::MakeRectXY({10, 20, 90, 100}, 9, 13);
2558 canvas->clipRRect(oval, true);
2559 canvas->drawCircle(70, 100, 60, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002560}
2561##
2562
Cary Clark2ade9972017-11-02 17:49:34 -04002563#SeeAlso clipRect clipPath clipRegion
Cary Clark8032b982017-07-28 11:04:54 -04002564
2565##
2566
2567#Method void clipPath(const SkPath& path, SkClipOp op, bool doAntiAlias)
2568
Cary Clarkab2621d2018-01-30 10:08:57 -05002569#In Clip
2570#Line # combines Clip with Path ##
Cary Clark8032b982017-07-28 11:04:54 -04002571Replace Clip with the intersection or difference of Clip and path,
Cary Clarkce101242017-09-01 15:51:02 -04002572with an Aliased or Anti-aliased clip edge. Path_Fill_Type determines if path
Cary Clark8032b982017-07-28 11:04:54 -04002573describes the area inside or outside its contours; and if Path_Contour overlaps
2574itself or another Path_Contour, whether the overlaps form part of the area.
Cary Clarkbad5ad72017-08-03 17:14:08 -04002575path is transformed by Matrix before it is combined with Clip.
Cary Clark8032b982017-07-28 11:04:54 -04002576
Cary Clarkbad5ad72017-08-03 17:14:08 -04002577#Param path Path to combine with Clip ##
2578#Param op Clip_Op to apply to Clip ##
Cary Clarkce101242017-09-01 15:51:02 -04002579#Param doAntiAlias true if Clip is to be Anti-aliased ##
Cary Clark8032b982017-07-28 11:04:54 -04002580
2581#Example
2582#Description
2583Top figure uses SkPath::kInverseWinding_FillType and SkClipOp::kDifference;
2584area outside clip is subtracted from circle.
2585
2586Bottom figure uses SkPath::kWinding_FillType and SkClipOp::kIntersect;
2587area inside clip is intersected with circle.
2588##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002589void draw(SkCanvas* canvas) {
2590 SkPaint paint;
2591 paint.setAntiAlias(true);
2592 SkPath path;
2593 path.addRect({20, 30, 100, 110});
2594 path.setFillType(SkPath::kInverseWinding_FillType);
2595 canvas->save();
2596 canvas->clipPath(path, SkClipOp::kDifference, false);
2597 canvas->drawCircle(70, 100, 60, paint);
2598 canvas->restore();
2599 canvas->translate(100, 100);
2600 path.setFillType(SkPath::kWinding_FillType);
2601 canvas->clipPath(path, SkClipOp::kIntersect, false);
2602 canvas->drawCircle(70, 100, 60, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002603}
2604##
2605
Cary Clark2ade9972017-11-02 17:49:34 -04002606#SeeAlso clipRect clipRRect clipRegion
Cary Clark8032b982017-07-28 11:04:54 -04002607
2608##
2609
Mike Klein9ff8c8c2018-02-07 01:58:51 +00002610#Method void clipPath(const SkPath& path, SkClipOp op)
Cary Clark8032b982017-07-28 11:04:54 -04002611
Cary Clarkab2621d2018-01-30 10:08:57 -05002612#In Clip
Cary Clark8032b982017-07-28 11:04:54 -04002613Replace Clip with the intersection or difference of Clip and path.
Cary Clarkce101242017-09-01 15:51:02 -04002614Resulting Clip is Aliased; pixels are fully contained by the clip.
Cary Clark8032b982017-07-28 11:04:54 -04002615Path_Fill_Type determines if path
2616describes the area inside or outside its contours; and if Path_Contour overlaps
2617itself or another Path_Contour, whether the overlaps form part of the area.
2618path is transformed by Matrix
2619before it is combined with Clip.
2620
Cary Clarkbad5ad72017-08-03 17:14:08 -04002621#Param path Path to combine with Clip ##
2622#Param op Clip_Op to apply to Clip ##
Cary Clark8032b982017-07-28 11:04:54 -04002623
2624#Example
2625#Description
Cary Clarkbc5697d2017-10-04 14:31:33 -04002626Overlapping Rects form a clip. When clip Path_Fill_Type is set to
Mike Klein9ff8c8c2018-02-07 01:58:51 +00002627SkPath::kWinding_FillType, the overlap is included. Set to
Cary Clark8032b982017-07-28 11:04:54 -04002628SkPath::kEvenOdd_FillType, the overlap is excluded and forms a hole.
2629##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002630void draw(SkCanvas* canvas) {
2631 SkPaint paint;
2632 paint.setAntiAlias(true);
2633 SkPath path;
2634 path.addRect({20, 15, 100, 95});
2635 path.addRect({50, 65, 130, 135});
2636 path.setFillType(SkPath::kWinding_FillType);
2637 canvas->save();
2638 canvas->clipPath(path, SkClipOp::kIntersect);
2639 canvas->drawCircle(70, 85, 60, paint);
2640 canvas->restore();
2641 canvas->translate(100, 100);
2642 path.setFillType(SkPath::kEvenOdd_FillType);
2643 canvas->clipPath(path, SkClipOp::kIntersect);
2644 canvas->drawCircle(70, 85, 60, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002645}
2646##
2647
Cary Clark2ade9972017-11-02 17:49:34 -04002648#SeeAlso clipRect clipRRect clipRegion
Cary Clark8032b982017-07-28 11:04:54 -04002649
2650##
2651
Mike Klein9ff8c8c2018-02-07 01:58:51 +00002652#Method void clipPath(const SkPath& path, bool doAntiAlias = false)
Cary Clark8032b982017-07-28 11:04:54 -04002653
Cary Clarkab2621d2018-01-30 10:08:57 -05002654#In Clip
Cary Clark8032b982017-07-28 11:04:54 -04002655Replace Clip with the intersection of Clip and path.
Cary Clarkce101242017-09-01 15:51:02 -04002656Resulting Clip is Aliased; pixels are fully contained by the clip.
Cary Clark8032b982017-07-28 11:04:54 -04002657Path_Fill_Type determines if path
2658describes the area inside or outside its contours; and if Path_Contour overlaps
2659itself or another Path_Contour, whether the overlaps form part of the area.
Cary Clarkbad5ad72017-08-03 17:14:08 -04002660path is transformed by Matrix before it is combined with Clip.
Cary Clark8032b982017-07-28 11:04:54 -04002661
Cary Clarkbad5ad72017-08-03 17:14:08 -04002662#Param path Path to combine with Clip ##
Cary Clarkce101242017-09-01 15:51:02 -04002663#Param doAntiAlias true if Clip is to be Anti-aliased ##
Cary Clark8032b982017-07-28 11:04:54 -04002664
2665#Example
2666#Height 212
2667#Description
Mike Klein9ff8c8c2018-02-07 01:58:51 +00002668Clip loops over itself covering its center twice. When clip Path_Fill_Type
2669is set to SkPath::kWinding_FillType, the overlap is included. Set to
Cary Clark8032b982017-07-28 11:04:54 -04002670SkPath::kEvenOdd_FillType, the overlap is excluded and forms a hole.
2671##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002672void draw(SkCanvas* canvas) {
2673 SkPaint paint;
2674 paint.setAntiAlias(true);
2675 SkPath path;
2676 SkPoint poly[] = {{20, 20}, { 80, 20}, { 80, 80}, {40, 80},
2677 {40, 40}, {100, 40}, {100, 100}, {20, 100}};
2678 path.addPoly(poly, SK_ARRAY_COUNT(poly), true);
2679 path.setFillType(SkPath::kWinding_FillType);
2680 canvas->save();
2681 canvas->clipPath(path, SkClipOp::kIntersect);
2682 canvas->drawCircle(50, 50, 45, paint);
2683 canvas->restore();
2684 canvas->translate(100, 100);
2685 path.setFillType(SkPath::kEvenOdd_FillType);
2686 canvas->clipPath(path, SkClipOp::kIntersect);
2687 canvas->drawCircle(50, 50, 45, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002688}
2689##
2690
Cary Clark2ade9972017-11-02 17:49:34 -04002691#SeeAlso clipRect clipRRect clipRegion
Cary Clark8032b982017-07-28 11:04:54 -04002692
2693##
2694
2695# ------------------------------------------------------------------------------
2696
Mike Klein9ff8c8c2018-02-07 01:58:51 +00002697#Method void setAllowSimplifyClip(bool allow)
Cary Clark8032b982017-07-28 11:04:54 -04002698
Cary Clarkab2621d2018-01-30 10:08:57 -05002699#In Clip
2700#Line # experimental ##
Cary Clark8032b982017-07-28 11:04:54 -04002701#Experimental
2702Only used for testing.
2703##
2704
Cary Clarkce101242017-09-01 15:51:02 -04002705Set to simplify clip stack using PathOps.
Cary Clark8032b982017-07-28 11:04:54 -04002706
2707##
2708
2709# ------------------------------------------------------------------------------
2710
2711#Method void clipRegion(const SkRegion& deviceRgn, SkClipOp op = SkClipOp::kIntersect)
2712
Cary Clarkab2621d2018-01-30 10:08:57 -05002713#In Clip
2714#Line # combines Clip with Region ##
Cary Clark8032b982017-07-28 11:04:54 -04002715Replace Clip with the intersection or difference of Clip and Region deviceRgn.
Cary Clarkce101242017-09-01 15:51:02 -04002716Resulting Clip is Aliased; pixels are fully contained by the clip.
Cary Clark8032b982017-07-28 11:04:54 -04002717deviceRgn is unaffected by Matrix.
2718
Cary Clarkbad5ad72017-08-03 17:14:08 -04002719#Param deviceRgn Region to combine with Clip ##
2720#Param op Clip_Op to apply to Clip ##
Cary Clark8032b982017-07-28 11:04:54 -04002721
2722#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04002723#Description
Cary Clarkce101242017-09-01 15:51:02 -04002724 region is unaffected by canvas rotation; iRect is affected by canvas rotation.
2725 Both clips are Aliased; this is not noticeable on Region clip because it
Cary Clarkbad5ad72017-08-03 17:14:08 -04002726 aligns to pixel boundaries.
2727##
2728void draw(SkCanvas* canvas) {
2729 SkPaint paint;
2730 paint.setAntiAlias(true);
2731 SkIRect iRect = {30, 40, 120, 130 };
2732 SkRegion region(iRect);
2733 canvas->rotate(10);
2734 canvas->save();
2735 canvas->clipRegion(region, SkClipOp::kIntersect);
2736 canvas->drawCircle(50, 50, 45, paint);
2737 canvas->restore();
2738 canvas->translate(100, 100);
2739 canvas->clipRect(SkRect::Make(iRect), SkClipOp::kIntersect);
2740 canvas->drawCircle(50, 50, 45, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002741}
2742##
2743
Cary Clark2ade9972017-11-02 17:49:34 -04002744#SeeAlso clipRect clipRRect clipPath
Cary Clark8032b982017-07-28 11:04:54 -04002745
2746##
2747
2748#Method bool quickReject(const SkRect& rect) const
2749
Cary Clarkab2621d2018-01-30 10:08:57 -05002750#In Clip
2751#Line # returns if Rect is outside Clip ##
Cary Clark8032b982017-07-28 11:04:54 -04002752Return true if Rect rect, transformed by Matrix, can be quickly determined to be
2753outside of Clip. May return false even though rect is outside of Clip.
2754
2755Use to check if an area to be drawn is clipped out, to skip subsequent draw calls.
2756
Cary Clarkbad5ad72017-08-03 17:14:08 -04002757#Param rect Rect to compare with Clip ##
Cary Clark8032b982017-07-28 11:04:54 -04002758
Cary Clarkbad5ad72017-08-03 17:14:08 -04002759#Return true if rect, transformed by Matrix, does not intersect Clip ##
Cary Clark8032b982017-07-28 11:04:54 -04002760
2761#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04002762void draw(SkCanvas* canvas) {
Mike Klein9ff8c8c2018-02-07 01:58:51 +00002763 SkRect testRect = {30, 30, 120, 129 };
2764 SkRect clipRect = {30, 130, 120, 230 };
Cary Clarkbad5ad72017-08-03 17:14:08 -04002765 canvas->save();
2766 canvas->clipRect(clipRect);
2767 SkDebugf("quickReject %s\n", canvas->quickReject(testRect) ? "true" : "false");
2768 canvas->restore();
2769 canvas->rotate(10);
2770 canvas->clipRect(clipRect);
2771 SkDebugf("quickReject %s\n", canvas->quickReject(testRect) ? "true" : "false");
Cary Clark8032b982017-07-28 11:04:54 -04002772}
2773 #StdOut
Cary Clarkbad5ad72017-08-03 17:14:08 -04002774 quickReject true
Cary Clark8032b982017-07-28 11:04:54 -04002775 quickReject false
2776 ##
2777##
2778
Cary Clark2ade9972017-11-02 17:49:34 -04002779#SeeAlso getLocalClipBounds getTotalMatrix SkBitmap::drawsNothing
Cary Clark8032b982017-07-28 11:04:54 -04002780
2781##
2782
2783#Method bool quickReject(const SkPath& path) const
2784
Cary Clarkab2621d2018-01-30 10:08:57 -05002785#In Clip
Cary Clark8032b982017-07-28 11:04:54 -04002786Return true if path, transformed by Matrix, can be quickly determined to be
2787outside of Clip. May return false even though path is outside of Clip.
2788
2789Use to check if an area to be drawn is clipped out, to skip subsequent draw calls.
2790
Cary Clarkbad5ad72017-08-03 17:14:08 -04002791#Param path Path to compare with Clip ##
Cary Clark8032b982017-07-28 11:04:54 -04002792
Cary Clarkbad5ad72017-08-03 17:14:08 -04002793#Return true if path, transformed by Matrix, does not intersect Clip ##
Cary Clark8032b982017-07-28 11:04:54 -04002794
2795#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04002796void draw(SkCanvas* canvas) {
Mike Klein9ff8c8c2018-02-07 01:58:51 +00002797 SkPoint testPoints[] = {{30, 30}, {120, 30}, {120, 129} };
2798 SkPoint clipPoints[] = {{30, 130}, {120, 130}, {120, 230} };
Cary Clarkbad5ad72017-08-03 17:14:08 -04002799 SkPath testPath, clipPath;
2800 testPath.addPoly(testPoints, SK_ARRAY_COUNT(testPoints), true);
2801 clipPath.addPoly(clipPoints, SK_ARRAY_COUNT(clipPoints), true);
2802 canvas->save();
2803 canvas->clipPath(clipPath);
2804 SkDebugf("quickReject %s\n", canvas->quickReject(testPath) ? "true" : "false");
2805 canvas->restore();
2806 canvas->rotate(10);
2807 canvas->clipPath(clipPath);
2808 SkDebugf("quickReject %s\n", canvas->quickReject(testPath) ? "true" : "false");
Cary Clark8032b982017-07-28 11:04:54 -04002809 #StdOut
Cary Clarkbad5ad72017-08-03 17:14:08 -04002810 quickReject true
Cary Clark8032b982017-07-28 11:04:54 -04002811 quickReject false
2812 ##
2813}
2814##
2815
Cary Clark2ade9972017-11-02 17:49:34 -04002816#SeeAlso getLocalClipBounds getTotalMatrix SkBitmap::drawsNothing
Cary Clark8032b982017-07-28 11:04:54 -04002817
2818##
2819
Mike Klein9ff8c8c2018-02-07 01:58:51 +00002820#Method SkRect getLocalClipBounds() const
Cary Clark8032b982017-07-28 11:04:54 -04002821
Cary Clarkab2621d2018-01-30 10:08:57 -05002822#In Clip
2823#Line # returns Clip bounds in source coordinates ##
Cary Clark8032b982017-07-28 11:04:54 -04002824Return bounds of Clip, transformed by inverse of Matrix. If Clip is empty,
2825return SkRect::MakeEmpty, where all Rect sides equal zero.
2826
2827Rect returned is outset by one to account for partial pixel coverage if Clip
Cary Clarkce101242017-09-01 15:51:02 -04002828is Anti-aliased.
Cary Clark8032b982017-07-28 11:04:54 -04002829
Cary Clarkbad5ad72017-08-03 17:14:08 -04002830#Return bounds of Clip in local coordinates ##
Cary Clark8032b982017-07-28 11:04:54 -04002831
2832#Example
Mike Klein9ff8c8c2018-02-07 01:58:51 +00002833 #Description
Cary Clark8032b982017-07-28 11:04:54 -04002834 Initial bounds is device bounds outset by 1 on all sides.
2835 Clipped bounds is clipPath bounds outset by 1 on all sides.
2836 Scaling the canvas by two in x and y scales the local bounds by 1/2 in x and y.
2837 ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002838 SkCanvas local(256, 256);
2839 canvas = &local;
2840 SkRect bounds = canvas->getLocalClipBounds();
2841 SkDebugf("left:%g top:%g right:%g bottom:%g\n",
2842 bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom);
Mike Klein9ff8c8c2018-02-07 01:58:51 +00002843 SkPoint clipPoints[] = {{30, 130}, {120, 130}, {120, 230} };
Cary Clarkbad5ad72017-08-03 17:14:08 -04002844 SkPath clipPath;
2845 clipPath.addPoly(clipPoints, SK_ARRAY_COUNT(clipPoints), true);
2846 canvas->clipPath(clipPath);
2847 bounds = canvas->getLocalClipBounds();
2848 SkDebugf("left:%g top:%g right:%g bottom:%g\n",
2849 bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom);
2850 canvas->scale(2, 2);
2851 bounds = canvas->getLocalClipBounds();
2852 SkDebugf("left:%g top:%g right:%g bottom:%g\n",
2853 bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom);
2854 #StdOut
2855 left:-1 top:-1 right:257 bottom:257
2856 left:29 top:129 right:121 bottom:231
2857 left:14.5 top:64.5 right:60.5 bottom:115.5
2858 ##
Cary Clark8032b982017-07-28 11:04:54 -04002859##
2860
2861# local canvas in example works around bug in fiddle ##
Cary Clark4855f782018-02-06 09:41:53 -05002862#Bug 6524
Cary Clark2ade9972017-11-02 17:49:34 -04002863#SeeAlso getDeviceClipBounds getBaseLayerSize quickReject
Cary Clark8032b982017-07-28 11:04:54 -04002864
2865##
2866
Mike Klein9ff8c8c2018-02-07 01:58:51 +00002867#Method bool getLocalClipBounds(SkRect* bounds) const
Cary Clark8032b982017-07-28 11:04:54 -04002868
Cary Clarkab2621d2018-01-30 10:08:57 -05002869#In Clip
Cary Clark8032b982017-07-28 11:04:54 -04002870Return bounds of Clip, transformed by inverse of Matrix. If Clip is empty,
2871return false, and set bounds to SkRect::MakeEmpty, where all Rect sides equal zero.
2872
2873bounds is outset by one to account for partial pixel coverage if Clip
Cary Clarkce101242017-09-01 15:51:02 -04002874is Anti-aliased.
Cary Clark8032b982017-07-28 11:04:54 -04002875
Cary Clarkbad5ad72017-08-03 17:14:08 -04002876#Param bounds Rect of Clip in local coordinates ##
Cary Clark8032b982017-07-28 11:04:54 -04002877
Cary Clarkbad5ad72017-08-03 17:14:08 -04002878#Return true if Clip bounds is not empty ##
Cary Clark8032b982017-07-28 11:04:54 -04002879
2880#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04002881 void draw(SkCanvas* canvas) {
2882 SkCanvas local(256, 256);
2883 canvas = &local;
2884 SkRect bounds;
2885 SkDebugf("local bounds empty = %s\n", canvas->getLocalClipBounds(&bounds)
2886 ? "false" : "true");
2887 SkPath path;
2888 canvas->clipPath(path);
2889 SkDebugf("local bounds empty = %s\n", canvas->getLocalClipBounds(&bounds)
2890 ? "false" : "true");
Cary Clark8032b982017-07-28 11:04:54 -04002891 }
2892 #StdOut
Cary Clarkbad5ad72017-08-03 17:14:08 -04002893 local bounds empty = false
Cary Clark8032b982017-07-28 11:04:54 -04002894 local bounds empty = true
2895 ##
2896##
2897
2898# local canvas in example works around bug in fiddle ##
Cary Clark4855f782018-02-06 09:41:53 -05002899#Bug 6524
Cary Clark2ade9972017-11-02 17:49:34 -04002900#SeeAlso getDeviceClipBounds getBaseLayerSize quickReject
Cary Clark8032b982017-07-28 11:04:54 -04002901
2902##
2903
Mike Klein9ff8c8c2018-02-07 01:58:51 +00002904#Method SkIRect getDeviceClipBounds() const
Cary Clark8032b982017-07-28 11:04:54 -04002905
Cary Clarkab2621d2018-01-30 10:08:57 -05002906#In Clip
2907#Line # returns IRect bounds of Clip ##
Cary Clark8032b982017-07-28 11:04:54 -04002908Return IRect bounds of Clip, unaffected by Matrix. If Clip is empty,
2909return SkRect::MakeEmpty, where all Rect sides equal zero.
2910
Mike Klein9ff8c8c2018-02-07 01:58:51 +00002911Unlike getLocalClipBounds, returned IRect is not outset.
Cary Clark8032b982017-07-28 11:04:54 -04002912
Cary Clarkbad5ad72017-08-03 17:14:08 -04002913#Return bounds of Clip in Device coordinates ##
Cary Clark8032b982017-07-28 11:04:54 -04002914
2915#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04002916void draw(SkCanvas* canvas) {
2917 #Description
Cary Clark8032b982017-07-28 11:04:54 -04002918 Initial bounds is device bounds, not outset.
2919 Clipped bounds is clipPath bounds, not outset.
2920 Scaling the canvas by 1/2 in x and y scales the device bounds by 1/2 in x and y.
Cary Clarkbad5ad72017-08-03 17:14:08 -04002921 ##
2922 SkCanvas device(256, 256);
2923 canvas = &device;
2924 SkIRect bounds = canvas->getDeviceClipBounds();
2925 SkDebugf("left:%d top:%d right:%d bottom:%d\n",
2926 bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom);
Mike Klein9ff8c8c2018-02-07 01:58:51 +00002927 SkPoint clipPoints[] = {{30, 130}, {120, 130}, {120, 230} };
Cary Clarkbad5ad72017-08-03 17:14:08 -04002928 SkPath clipPath;
2929 clipPath.addPoly(clipPoints, SK_ARRAY_COUNT(clipPoints), true);
2930 canvas->save();
2931 canvas->clipPath(clipPath);
2932 bounds = canvas->getDeviceClipBounds();
2933 SkDebugf("left:%d top:%d right:%d bottom:%d\n",
2934 bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom);
2935 canvas->restore();
2936 canvas->scale(1.f/2, 1.f/2);
2937 canvas->clipPath(clipPath);
2938 bounds = canvas->getDeviceClipBounds();
2939 SkDebugf("left:%d top:%d right:%d bottom:%d\n",
2940 bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom);
Cary Clark8032b982017-07-28 11:04:54 -04002941 #StdOut
Cary Clarkbad5ad72017-08-03 17:14:08 -04002942 left:0 top:0 right:256 bottom:256
2943 left:30 top:130 right:120 bottom:230
Cary Clark8032b982017-07-28 11:04:54 -04002944 left:15 top:65 right:60 bottom:115
2945 ##
2946}
2947##
2948
2949#ToDo some confusion on why with an identity Matrix local and device are different ##
Cary Clark2ade9972017-11-02 17:49:34 -04002950#SeeAlso getLocalClipBounds getBaseLayerSize quickReject
Cary Clark8032b982017-07-28 11:04:54 -04002951
2952# device canvas in example works around bug in fiddle ##
Cary Clark4855f782018-02-06 09:41:53 -05002953#Bug 6524
Cary Clark8032b982017-07-28 11:04:54 -04002954
2955##
2956
Mike Klein9ff8c8c2018-02-07 01:58:51 +00002957#Method bool getDeviceClipBounds(SkIRect* bounds) const
Cary Clark8032b982017-07-28 11:04:54 -04002958
Cary Clarkab2621d2018-01-30 10:08:57 -05002959#In Clip
Cary Clark8032b982017-07-28 11:04:54 -04002960Return IRect bounds of Clip, unaffected by Matrix. If Clip is empty,
2961return false, and set bounds to SkRect::MakeEmpty, where all Rect sides equal zero.
2962
Mike Klein9ff8c8c2018-02-07 01:58:51 +00002963Unlike getLocalClipBounds, bounds is not outset.
Cary Clark8032b982017-07-28 11:04:54 -04002964
Cary Clarkbad5ad72017-08-03 17:14:08 -04002965#Param bounds Rect of Clip in device coordinates ##
Cary Clark8032b982017-07-28 11:04:54 -04002966
Cary Clarkbad5ad72017-08-03 17:14:08 -04002967#Return true if Clip bounds is not empty ##
Cary Clark8032b982017-07-28 11:04:54 -04002968
2969#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04002970 void draw(SkCanvas* canvas) {
2971 SkIRect bounds;
2972 SkDebugf("device bounds empty = %s\n", canvas->getDeviceClipBounds(&bounds)
2973 ? "false" : "true");
2974 SkPath path;
2975 canvas->clipPath(path);
2976 SkDebugf("device bounds empty = %s\n", canvas->getDeviceClipBounds(&bounds)
2977 ? "false" : "true");
Cary Clark8032b982017-07-28 11:04:54 -04002978 }
2979 #StdOut
Cary Clarkbad5ad72017-08-03 17:14:08 -04002980 device bounds empty = false
Cary Clark8032b982017-07-28 11:04:54 -04002981 device bounds empty = true
2982 ##
2983##
2984
Cary Clark2ade9972017-11-02 17:49:34 -04002985#SeeAlso getLocalClipBounds getBaseLayerSize quickReject
Cary Clark8032b982017-07-28 11:04:54 -04002986
2987##
2988
Cary Clark08895c42018-02-01 09:37:32 -05002989#Subtopic Clip ##
Cary Clark8032b982017-07-28 11:04:54 -04002990
2991# ------------------------------------------------------------------------------
Cary Clark78de7512018-02-07 07:27:09 -05002992#Subtopic Draw
2993#Populate
2994#Line # draws into Canvas ##
2995##
Cary Clark8032b982017-07-28 11:04:54 -04002996
2997#Method void drawColor(SkColor color, SkBlendMode mode = SkBlendMode::kSrcOver)
Cary Clark78de7512018-02-07 07:27:09 -05002998#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05002999#Line # fills Clip with Color and Blend_Mode ##
Cary Clark8032b982017-07-28 11:04:54 -04003000Fill Clip with Color color.
3001mode determines how Color_ARGB is combined with destination.
3002
Cary Clarkbad5ad72017-08-03 17:14:08 -04003003#Param color Unpremultiplied Color_ARGB ##
3004#Param mode SkBlendMode used to combine source color and destination ##
Cary Clark8032b982017-07-28 11:04:54 -04003005
3006#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003007 canvas->drawColor(SK_ColorRED);
3008 canvas->clipRect(SkRect::MakeWH(150, 150));
3009 canvas->drawColor(SkColorSetARGB(0x80, 0x00, 0xFF, 0x00), SkBlendMode::kPlus);
3010 canvas->clipRect(SkRect::MakeWH(75, 75));
3011 canvas->drawColor(SkColorSetARGB(0x80, 0x00, 0x00, 0xFF), SkBlendMode::kPlus);
Cary Clark8032b982017-07-28 11:04:54 -04003012##
3013
Cary Clark2ade9972017-11-02 17:49:34 -04003014#SeeAlso clear SkBitmap::erase drawPaint
Cary Clark8032b982017-07-28 11:04:54 -04003015
3016##
3017
3018# ------------------------------------------------------------------------------
3019
Mike Klein9ff8c8c2018-02-07 01:58:51 +00003020#Method void clear(SkColor color)
Cary Clark78de7512018-02-07 07:27:09 -05003021#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05003022#Line # fills Clip with Color ##
Mike Klein9ff8c8c2018-02-07 01:58:51 +00003023Fill Clip with Color color using SkBlendMode::kSrc.
Cary Clark8032b982017-07-28 11:04:54 -04003024This has the effect of replacing all pixels contained by Clip with color.
3025
Cary Clarkbad5ad72017-08-03 17:14:08 -04003026#Param color Unpremultiplied Color_ARGB ##
Cary Clark8032b982017-07-28 11:04:54 -04003027
3028#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003029void draw(SkCanvas* canvas) {
3030 canvas->save();
3031 canvas->clipRect(SkRect::MakeWH(256, 128));
Mike Klein9ff8c8c2018-02-07 01:58:51 +00003032 canvas->clear(SkColorSetARGB(0x80, 0xFF, 0x00, 0x00));
Cary Clarkbad5ad72017-08-03 17:14:08 -04003033 canvas->restore();
3034 canvas->save();
3035 canvas->clipRect(SkRect::MakeWH(150, 192));
3036 canvas->clear(SkColorSetARGB(0x80, 0x00, 0xFF, 0x00));
3037 canvas->restore();
3038 canvas->clipRect(SkRect::MakeWH(75, 256));
3039 canvas->clear(SkColorSetARGB(0x80, 0x00, 0x00, 0xFF));
Cary Clark8032b982017-07-28 11:04:54 -04003040}
3041##
3042
Cary Clark2ade9972017-11-02 17:49:34 -04003043#SeeAlso drawColor SkBitmap::erase drawPaint
Cary Clark8032b982017-07-28 11:04:54 -04003044
3045##
3046
3047# ------------------------------------------------------------------------------
3048
Mike Klein9ff8c8c2018-02-07 01:58:51 +00003049#Method void discard()
Cary Clark78de7512018-02-07 07:27:09 -05003050#In Utility
Cary Clarkab2621d2018-01-30 10:08:57 -05003051#Line # makes Canvas contents undefined ##
Cary Clark8032b982017-07-28 11:04:54 -04003052Make Canvas contents undefined. Subsequent calls that read Canvas pixels,
3053such as drawing with SkBlendMode, return undefined results. discard() does
3054not change Clip or Matrix.
3055
3056discard() may do nothing, depending on the implementation of Surface or Device
3057that created Canvas.
3058
3059discard() allows optimized performance on subsequent draws by removing
3060cached data associated with Surface or Device.
3061It is not necessary to call discard() once done with Canvas;
3062any cached data is deleted when owning Surface or Device is deleted.
3063
3064#ToDo example? not sure how to make this meaningful w/o more implementation detail ##
Cary Clark2ade9972017-11-02 17:49:34 -04003065#SeeAlso flush() SkSurface::prepareForExternalIO GrContext::abandonContext
Cary Clark8032b982017-07-28 11:04:54 -04003066
Mike Klein9ff8c8c2018-02-07 01:58:51 +00003067#NoExample
Cary Clark8032b982017-07-28 11:04:54 -04003068##
3069
3070##
3071
3072# ------------------------------------------------------------------------------
3073
3074#Method void drawPaint(const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05003075#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05003076#Line # fills Clip with Paint ##
Mike Reed8ad91a92018-01-19 19:09:32 -05003077Fill Clip with Paint paint. Paint components Mask_Filter, Shader,
Cary Clarkbad5ad72017-08-03 17:14:08 -04003078Color_Filter, Image_Filter, and Blend_Mode affect drawing;
3079Path_Effect in paint is ignored.
Cary Clark8032b982017-07-28 11:04:54 -04003080
3081# can Path_Effect in paint ever alter drawPaint?
3082
Cary Clarkbad5ad72017-08-03 17:14:08 -04003083#Param paint graphics state used to fill Canvas ##
Cary Clark8032b982017-07-28 11:04:54 -04003084
3085#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003086void draw(SkCanvas* canvas) {
3087 SkColor colors[] = { SK_ColorRED, SK_ColorGREEN, SK_ColorBLUE };
3088 SkScalar pos[] = { 0, SK_Scalar1/2, SK_Scalar1 };
3089 SkPaint paint;
3090 paint.setShader(SkGradientShader::MakeSweep(256, 256, colors, pos, SK_ARRAY_COUNT(colors)));
3091 canvas->drawPaint(paint);
Cary Clark8032b982017-07-28 11:04:54 -04003092}
3093##
3094
Cary Clark2ade9972017-11-02 17:49:34 -04003095#SeeAlso clear drawColor SkBitmap::erase
Cary Clark8032b982017-07-28 11:04:54 -04003096
3097##
3098
3099# ------------------------------------------------------------------------------
3100
3101#Enum PointMode
Cary Clark08895c42018-02-01 09:37:32 -05003102#Line # sets drawPoints options ##
Cary Clark8032b982017-07-28 11:04:54 -04003103
3104#Code
3105 enum PointMode {
3106 kPoints_PointMode,
3107 kLines_PointMode,
Cary Clarkd0530ba2017-09-14 11:25:39 -04003108 kPolygon_PointMode,
Cary Clark8032b982017-07-28 11:04:54 -04003109 };
3110##
3111
3112Selects if an array of points are drawn as discrete points, as lines, or as
3113an open polygon.
3114
3115#Const kPoints_PointMode 0
3116 Draw each point separately.
3117##
3118
3119#Const kLines_PointMode 1
3120 Draw each pair of points as a line segment.
3121##
3122
3123#Const kPolygon_PointMode 2
3124 Draw the array of points as a open polygon.
3125##
3126
3127#Example
Mike Klein9ff8c8c2018-02-07 01:58:51 +00003128 #Description
Cary Clark8032b982017-07-28 11:04:54 -04003129 The upper left corner shows three squares when drawn as points.
3130 The upper right corner shows one line; when drawn as lines, two points are required per line.
3131 The lower right corner shows two lines; when draw as polygon, no miter is drawn at the corner.
3132 The lower left corner shows two lines with a miter when path contains polygon.
3133 ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003134void draw(SkCanvas* canvas) {
3135 SkPaint paint;
3136 paint.setStyle(SkPaint::kStroke_Style);
3137 paint.setStrokeWidth(10);
3138 SkPoint points[] = {{64, 32}, {96, 96}, {32, 96}};
3139 canvas->drawPoints(SkCanvas::kPoints_PointMode, 3, points, paint);
3140 canvas->translate(128, 0);
3141 canvas->drawPoints(SkCanvas::kLines_PointMode, 3, points, paint);
3142 canvas->translate(0, 128);
3143 canvas->drawPoints(SkCanvas::kPolygon_PointMode, 3, points, paint);
3144 SkPath path;
3145 path.addPoly(points, 3, false);
3146 canvas->translate(-128, 0);
3147 canvas->drawPath(path, paint);
Cary Clark8032b982017-07-28 11:04:54 -04003148}
3149##
3150
Cary Clark2ade9972017-11-02 17:49:34 -04003151#SeeAlso drawLine drawPoint drawPath
Cary Clark8032b982017-07-28 11:04:54 -04003152
3153##
3154
3155# ------------------------------------------------------------------------------
3156
3157#Method void drawPoints(PointMode mode, size_t count, const SkPoint pts[], const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05003158#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05003159#Line # draws array as points, lines, polygon ##
Cary Clark8032b982017-07-28 11:04:54 -04003160Draw pts using Clip, Matrix and Paint paint.
Cary Clarkbad5ad72017-08-03 17:14:08 -04003161count is the number of points; if count is less than one, has no effect.
Cary Clark8032b982017-07-28 11:04:54 -04003162mode may be one of: kPoints_PointMode, kLines_PointMode, or kPolygon_PointMode.
3163
Cary Clarkbad5ad72017-08-03 17:14:08 -04003164If mode is kPoints_PointMode, the shape of point drawn depends on paint
3165Paint_Stroke_Cap. If paint is set to SkPaint::kRound_Cap, each point draws a
3166circle of diameter Paint_Stroke_Width. If paint is set to SkPaint::kSquare_Cap
3167or SkPaint::kButt_Cap, each point draws a square of width and height
3168Paint_Stroke_Width.
Cary Clark8032b982017-07-28 11:04:54 -04003169
3170If mode is kLines_PointMode, each pair of points draws a line segment.
3171One line is drawn for every two points; each point is used once. If count is odd,
Mike Klein9ff8c8c2018-02-07 01:58:51 +00003172the final point is ignored.
Cary Clark8032b982017-07-28 11:04:54 -04003173
3174If mode is kPolygon_PointMode, each adjacent pair of points draws a line segment.
3175count minus one lines are drawn; the first and last point are used once.
3176
3177Each line segment respects paint Paint_Stroke_Cap and Paint_Stroke_Width.
3178Paint_Style is ignored, as if were set to SkPaint::kStroke_Style.
3179
Cary Clarkbad5ad72017-08-03 17:14:08 -04003180Always draws each element one at a time; is not affected by
3181Paint_Stroke_Join, and unlike drawPath, does not create a mask from all points
Mike Klein9ff8c8c2018-02-07 01:58:51 +00003182and lines before drawing.
Cary Clark8032b982017-07-28 11:04:54 -04003183
Cary Clarka523d2d2017-08-30 08:58:10 -04003184#Param mode whether pts draws points or lines ##
3185#Param count number of points in the array ##
3186#Param pts array of points to draw ##
3187#Param paint stroke, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003188
3189#Example
3190#Height 200
Mike Klein9ff8c8c2018-02-07 01:58:51 +00003191 #Description
Cary Clark8032b982017-07-28 11:04:54 -04003192 #List
3193 # The first column draws points. ##
3194 # The second column draws points as lines. ##
3195 # The third column draws points as a polygon. ##
3196 # The fourth column draws points as a polygonal path. ##
3197 # The first row uses a round cap and round join. ##
3198 # The second row uses a square cap and a miter join. ##
3199 # The third row uses a butt cap and a bevel join. ##
3200 ##
3201 The transparent color makes multiple line draws visible;
3202 the path is drawn all at once.
3203 ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003204void draw(SkCanvas* canvas) {
3205 SkPaint paint;
3206 paint.setAntiAlias(true);
3207 paint.setStyle(SkPaint::kStroke_Style);
3208 paint.setStrokeWidth(10);
3209 paint.setColor(0x80349a45);
3210 const SkPoint points[] = {{32, 16}, {48, 48}, {16, 32}};
Mike Klein9ff8c8c2018-02-07 01:58:51 +00003211 const SkPaint::Join join[] = { SkPaint::kRound_Join,
Cary Clarkbad5ad72017-08-03 17:14:08 -04003212 SkPaint::kMiter_Join,
3213 SkPaint::kBevel_Join };
3214 int joinIndex = 0;
3215 SkPath path;
3216 path.addPoly(points, 3, false);
3217 for (const auto cap : { SkPaint::kRound_Cap, SkPaint::kSquare_Cap, SkPaint::kButt_Cap } ) {
3218 paint.setStrokeCap(cap);
3219 paint.setStrokeJoin(join[joinIndex++]);
3220 for (const auto mode : { SkCanvas::kPoints_PointMode,
3221 SkCanvas::kLines_PointMode,
3222 SkCanvas::kPolygon_PointMode } ) {
3223 canvas->drawPoints(mode, 3, points, paint);
3224 canvas->translate(64, 0);
3225 }
3226 canvas->drawPath(path, paint);
3227 canvas->translate(-192, 64);
3228 }
Cary Clark8032b982017-07-28 11:04:54 -04003229}
3230##
3231
Cary Clark2ade9972017-11-02 17:49:34 -04003232#SeeAlso drawLine drawPoint drawPath
Cary Clark8032b982017-07-28 11:04:54 -04003233
3234##
3235
3236# ------------------------------------------------------------------------------
3237
3238#Method void drawPoint(SkScalar x, SkScalar y, const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05003239#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05003240#Line # draws point at (x, y) position ##
Cary Clark8032b982017-07-28 11:04:54 -04003241Draw point at (x, y) using Clip, Matrix and Paint paint.
3242
3243The shape of point drawn depends on paint Paint_Stroke_Cap.
Cary Clarkbad5ad72017-08-03 17:14:08 -04003244If paint is set to SkPaint::kRound_Cap, draw a circle of diameter
Mike Klein9ff8c8c2018-02-07 01:58:51 +00003245Paint_Stroke_Width. If paint is set to SkPaint::kSquare_Cap or SkPaint::kButt_Cap,
Cary Clark8032b982017-07-28 11:04:54 -04003246draw a square of width and height Paint_Stroke_Width.
3247Paint_Style is ignored, as if were set to SkPaint::kStroke_Style.
3248
Cary Clarkbad5ad72017-08-03 17:14:08 -04003249#Param x left edge of circle or square ##
3250#Param y top edge of circle or square ##
3251#Param paint stroke, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003252
3253#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003254void draw(SkCanvas* canvas) {
3255 SkPaint paint;
3256 paint.setAntiAlias(true);
3257 paint.setColor(0x80349a45);
3258 paint.setStyle(SkPaint::kStroke_Style);
3259 paint.setStrokeWidth(100);
3260 paint.setStrokeCap(SkPaint::kRound_Cap);
3261 canvas->scale(1, 1.2f);
3262 canvas->drawPoint(64, 96, paint);
3263 canvas->scale(.6f, .8f);
3264 paint.setColor(SK_ColorWHITE);
3265 canvas->drawPoint(106, 120, paint);
Cary Clark8032b982017-07-28 11:04:54 -04003266}
3267##
3268
Cary Clark2ade9972017-11-02 17:49:34 -04003269#SeeAlso drawPoints drawCircle drawRect drawLine drawPath
Cary Clark8032b982017-07-28 11:04:54 -04003270
3271##
3272
Cary Clarkbad5ad72017-08-03 17:14:08 -04003273#Method void drawPoint(SkPoint p, const SkPaint& paint)
3274
3275Draw point p using Clip, Matrix and Paint paint.
3276
3277The shape of point drawn depends on paint Paint_Stroke_Cap.
3278If paint is set to SkPaint::kRound_Cap, draw a circle of diameter
Mike Klein9ff8c8c2018-02-07 01:58:51 +00003279Paint_Stroke_Width. If paint is set to SkPaint::kSquare_Cap or SkPaint::kButt_Cap,
Cary Clarkbad5ad72017-08-03 17:14:08 -04003280draw a square of width and height Paint_Stroke_Width.
3281Paint_Style is ignored, as if were set to SkPaint::kStroke_Style.
3282
3283#Param p top-left edge of circle or square ##
3284#Param paint stroke, blend, color, and so on, used to draw ##
3285
3286#Example
3287void draw(SkCanvas* canvas) {
3288 SkPaint paint;
3289 paint.setAntiAlias(true);
3290 paint.setColor(0x80349a45);
3291 paint.setStyle(SkPaint::kStroke_Style);
3292 paint.setStrokeWidth(100);
3293 paint.setStrokeCap(SkPaint::kSquare_Cap);
3294 canvas->scale(1, 1.2f);
3295 canvas->drawPoint({64, 96}, paint);
3296 canvas->scale(.6f, .8f);
3297 paint.setColor(SK_ColorWHITE);
3298 canvas->drawPoint(106, 120, paint);
3299}
3300##
3301
Cary Clark2ade9972017-11-02 17:49:34 -04003302#SeeAlso drawPoints drawCircle drawRect drawLine drawPath
Cary Clarkbad5ad72017-08-03 17:14:08 -04003303
3304##
3305
Cary Clark8032b982017-07-28 11:04:54 -04003306# ------------------------------------------------------------------------------
3307
3308#Method void drawLine(SkScalar x0, SkScalar y0, SkScalar x1, SkScalar y1, const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05003309#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05003310#Line # draws line segment between two points ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003311Draws line segment from (x0, y0) to (x1, y1) using Clip, Matrix, and Paint paint.
3312In paint: Paint_Stroke_Width describes the line thickness;
3313Paint_Stroke_Cap draws the end rounded or square;
Cary Clark8032b982017-07-28 11:04:54 -04003314Paint_Style is ignored, as if were set to SkPaint::kStroke_Style.
3315
Cary Clarkbad5ad72017-08-03 17:14:08 -04003316#Param x0 start of line segment on x-axis ##
3317#Param y0 start of line segment on y-axis ##
3318#Param x1 end of line segment on x-axis ##
3319#Param y1 end of line segment on y-axis ##
3320#Param paint stroke, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003321
3322#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003323 SkPaint paint;
3324 paint.setAntiAlias(true);
3325 paint.setColor(0xFF9a67be);
3326 paint.setStrokeWidth(20);
3327 canvas->skew(1, 0);
3328 canvas->drawLine(32, 96, 32, 160, paint);
3329 canvas->skew(-2, 0);
3330 canvas->drawLine(288, 96, 288, 160, paint);
3331##
3332
Cary Clark2ade9972017-11-02 17:49:34 -04003333#SeeAlso drawPoint drawCircle drawRect drawPath
Cary Clarkbad5ad72017-08-03 17:14:08 -04003334
3335##
3336
3337#Method void drawLine(SkPoint p0, SkPoint p1, const SkPaint& paint)
3338
3339Draws line segment from p0 to p1 using Clip, Matrix, and Paint paint.
3340In paint: Paint_Stroke_Width describes the line thickness;
3341Paint_Stroke_Cap draws the end rounded or square;
3342Paint_Style is ignored, as if were set to SkPaint::kStroke_Style.
3343
3344#Param p0 start of line segment ##
3345#Param p1 end of line segment ##
3346#Param paint stroke, blend, color, and so on, used to draw ##
3347
3348#Example
3349 SkPaint paint;
3350 paint.setAntiAlias(true);
3351 paint.setColor(0xFF9a67be);
3352 paint.setStrokeWidth(20);
3353 canvas->skew(1, 0);
3354 canvas->drawLine({32, 96}, {32, 160}, paint);
3355 canvas->skew(-2, 0);
3356 canvas->drawLine({288, 96}, {288, 160}, paint);
Cary Clark8032b982017-07-28 11:04:54 -04003357##
3358
Cary Clark2ade9972017-11-02 17:49:34 -04003359#SeeAlso drawPoint drawCircle drawRect drawPath
Cary Clark8032b982017-07-28 11:04:54 -04003360
3361##
3362
3363# ------------------------------------------------------------------------------
3364
3365#Method void drawRect(const SkRect& rect, const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05003366#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05003367#Line # draws Rect using Clip, Matrix, and Paint ##
Cary Clark8032b982017-07-28 11:04:54 -04003368Draw Rect rect using Clip, Matrix, and Paint paint.
Mike Klein9ff8c8c2018-02-07 01:58:51 +00003369In paint: Paint_Style determines if rectangle is stroked or filled;
Cary Clark8032b982017-07-28 11:04:54 -04003370if stroked, Paint_Stroke_Width describes the line thickness, and
3371Paint_Stroke_Join draws the corners rounded or square.
3372
Cary Clarkbc5697d2017-10-04 14:31:33 -04003373#Param rect rectangle to draw ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003374#Param paint stroke or fill, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003375
3376#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003377void draw(SkCanvas* canvas) {
3378 SkPoint rectPts[] = { {64, 48}, {192, 160} };
3379 SkPaint paint;
3380 paint.setAntiAlias(true);
3381 paint.setStyle(SkPaint::kStroke_Style);
3382 paint.setStrokeWidth(20);
3383 paint.setStrokeJoin(SkPaint::kRound_Join);
3384 SkMatrix rotator;
3385 rotator.setRotate(30, 128, 128);
3386 for (auto color : { SK_ColorRED, SK_ColorBLUE, SK_ColorYELLOW, SK_ColorMAGENTA } ) {
3387 paint.setColor(color);
3388 SkRect rect;
3389 rect.set(rectPts[0], rectPts[1]);
3390 canvas->drawRect(rect, paint);
3391 rotator.mapPoints(rectPts, 2);
3392 }
Cary Clark8032b982017-07-28 11:04:54 -04003393}
3394##
3395
Mike Klein9ff8c8c2018-02-07 01:58:51 +00003396#SeeAlso drawIRect drawRRect drawRoundRect drawRegion drawPath drawLine
Cary Clark8032b982017-07-28 11:04:54 -04003397
3398##
3399
3400# ------------------------------------------------------------------------------
3401
Mike Klein9ff8c8c2018-02-07 01:58:51 +00003402#Method void drawIRect(const SkIRect& rect, const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05003403#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05003404#Line # draws IRect using Clip, Matrix, and Paint ##
Cary Clark8032b982017-07-28 11:04:54 -04003405Draw IRect rect using Clip, Matrix, and Paint paint.
Mike Klein9ff8c8c2018-02-07 01:58:51 +00003406In paint: Paint_Style determines if rectangle is stroked or filled;
Cary Clark8032b982017-07-28 11:04:54 -04003407if stroked, Paint_Stroke_Width describes the line thickness, and
3408Paint_Stroke_Join draws the corners rounded or square.
3409
Cary Clarkbc5697d2017-10-04 14:31:33 -04003410#Param rect rectangle to draw ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003411#Param paint stroke or fill, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003412
3413#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003414 SkIRect rect = { 64, 48, 192, 160 };
3415 SkPaint paint;
3416 paint.setAntiAlias(true);
3417 paint.setStyle(SkPaint::kStroke_Style);
3418 paint.setStrokeWidth(20);
3419 paint.setStrokeJoin(SkPaint::kRound_Join);
3420 for (auto color : { SK_ColorRED, SK_ColorBLUE, SK_ColorYELLOW, SK_ColorMAGENTA } ) {
3421 paint.setColor(color);
3422 canvas->drawIRect(rect, paint);
3423 canvas->rotate(30, 128, 128);
3424 }
Cary Clark8032b982017-07-28 11:04:54 -04003425##
3426
Cary Clark2ade9972017-11-02 17:49:34 -04003427#SeeAlso drawRect drawRRect drawRoundRect drawRegion drawPath drawLine
Cary Clark8032b982017-07-28 11:04:54 -04003428
3429##
3430
3431# ------------------------------------------------------------------------------
3432
3433#Method void drawRegion(const SkRegion& region, const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05003434#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05003435#Line # draws Region using Clip, Matrix, and Paint ##
Cary Clark8032b982017-07-28 11:04:54 -04003436Draw Region region using Clip, Matrix, and Paint paint.
Mike Klein9ff8c8c2018-02-07 01:58:51 +00003437In paint: Paint_Style determines if rectangle is stroked or filled;
Cary Clark8032b982017-07-28 11:04:54 -04003438if stroked, Paint_Stroke_Width describes the line thickness, and
3439Paint_Stroke_Join draws the corners rounded or square.
3440
Cary Clarkbc5697d2017-10-04 14:31:33 -04003441#Param region region to draw ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003442#Param paint Paint stroke or fill, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003443
3444#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003445void draw(SkCanvas* canvas) {
3446 SkRegion region;
3447 region.op( 10, 10, 50, 50, SkRegion::kUnion_Op);
3448 region.op( 10, 50, 90, 90, SkRegion::kUnion_Op);
3449 SkPaint paint;
3450 paint.setAntiAlias(true);
3451 paint.setStyle(SkPaint::kStroke_Style);
3452 paint.setStrokeWidth(20);
3453 paint.setStrokeJoin(SkPaint::kRound_Join);
3454 canvas->drawRegion(region, paint);
Cary Clark8032b982017-07-28 11:04:54 -04003455}
3456##
3457
Cary Clark2ade9972017-11-02 17:49:34 -04003458#SeeAlso drawRect drawIRect drawPath
Cary Clark8032b982017-07-28 11:04:54 -04003459
3460##
3461
3462# ------------------------------------------------------------------------------
3463
3464#Method void drawOval(const SkRect& oval, const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05003465#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05003466#Line # draws Oval using Clip, Matrix, and Paint ##
Cary Clark8032b982017-07-28 11:04:54 -04003467Draw Oval oval using Clip, Matrix, and Paint.
Mike Klein9ff8c8c2018-02-07 01:58:51 +00003468In paint: Paint_Style determines if Oval is stroked or filled;
Cary Clark8032b982017-07-28 11:04:54 -04003469if stroked, Paint_Stroke_Width describes the line thickness.
3470
Cary Clarkbad5ad72017-08-03 17:14:08 -04003471#Param oval Rect bounds of Oval ##
3472#Param paint Paint stroke or fill, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003473
3474#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003475void draw(SkCanvas* canvas) {
3476 canvas->clear(0xFF3f5f9f);
3477 SkColor kColor1 = SkColorSetARGB(0xff, 0xff, 0x7f, 0);
3478 SkColor g1Colors[] = { kColor1, SkColorSetA(kColor1, 0x20) };
3479 SkPoint g1Points[] = { { 0, 0 }, { 0, 100 } };
3480 SkScalar pos[] = { 0.2f, 1.0f };
3481 SkRect bounds = SkRect::MakeWH(80, 70);
3482 SkPaint paint;
3483 paint.setAntiAlias(true);
3484 paint.setShader(SkGradientShader::MakeLinear(g1Points, g1Colors, pos, SK_ARRAY_COUNT(g1Colors),
3485 SkShader::kClamp_TileMode));
3486 canvas->drawOval(bounds , paint);
Cary Clark8032b982017-07-28 11:04:54 -04003487}
3488##
3489
Cary Clark2ade9972017-11-02 17:49:34 -04003490#SeeAlso drawCircle drawPoint drawPath drawRRect drawRoundRect
Cary Clark8032b982017-07-28 11:04:54 -04003491
3492##
3493
3494# ------------------------------------------------------------------------------
3495
3496#Method void drawRRect(const SkRRect& rrect, const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05003497#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05003498#Line # draws Round_Rect using Clip, Matrix, and Paint ##
Cary Clark8032b982017-07-28 11:04:54 -04003499Draw Round_Rect rrect using Clip, Matrix, and Paint paint.
Mike Klein9ff8c8c2018-02-07 01:58:51 +00003500In paint: Paint_Style determines if rrect is stroked or filled;
Cary Clark8032b982017-07-28 11:04:54 -04003501if stroked, Paint_Stroke_Width describes the line thickness.
3502
Cary Clarkbad5ad72017-08-03 17:14:08 -04003503rrect may represent a rectangle, circle, oval, uniformly rounded rectangle, or
3504may have any combination of positive non-square radii for the four corners.
Cary Clark8032b982017-07-28 11:04:54 -04003505
Cary Clarkbad5ad72017-08-03 17:14:08 -04003506#Param rrect Round_Rect with up to eight corner radii to draw ##
3507#Param paint Paint stroke or fill, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003508
3509#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003510void draw(SkCanvas* canvas) {
3511 SkPaint paint;
3512 paint.setAntiAlias(true);
3513 SkRect outer = {30, 40, 210, 220};
3514 SkRect radii = {30, 50, 70, 90 };
3515 SkRRect rRect;
3516 rRect.setNinePatch(outer, radii.fLeft, radii.fTop, radii.fRight, radii.fBottom);
3517 canvas->drawRRect(rRect, paint);
3518 paint.setColor(SK_ColorWHITE);
3519 canvas->drawLine(outer.fLeft + radii.fLeft, outer.fTop,
3520 outer.fLeft + radii.fLeft, outer.fBottom, paint);
Mike Klein9ff8c8c2018-02-07 01:58:51 +00003521 canvas->drawLine(outer.fRight - radii.fRight, outer.fTop,
Cary Clarkbad5ad72017-08-03 17:14:08 -04003522 outer.fRight - radii.fRight, outer.fBottom, paint);
Mike Klein9ff8c8c2018-02-07 01:58:51 +00003523 canvas->drawLine(outer.fLeft, outer.fTop + radii.fTop,
Cary Clarkbad5ad72017-08-03 17:14:08 -04003524 outer.fRight, outer.fTop + radii.fTop, paint);
Mike Klein9ff8c8c2018-02-07 01:58:51 +00003525 canvas->drawLine(outer.fLeft, outer.fBottom - radii.fBottom,
Cary Clarkbad5ad72017-08-03 17:14:08 -04003526 outer.fRight, outer.fBottom - radii.fBottom, paint);
3527}
Cary Clark8032b982017-07-28 11:04:54 -04003528##
3529
Cary Clark2ade9972017-11-02 17:49:34 -04003530#SeeAlso drawRect drawRoundRect drawDRRect drawCircle drawOval drawPath
Cary Clark8032b982017-07-28 11:04:54 -04003531
3532##
3533
3534# ------------------------------------------------------------------------------
3535
3536#Method void drawDRRect(const SkRRect& outer, const SkRRect& inner, const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05003537#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05003538#Line # draws double Round_Rect stroked or filled ##
Cary Clark8032b982017-07-28 11:04:54 -04003539Draw Round_Rect outer and inner
Mike Klein9ff8c8c2018-02-07 01:58:51 +00003540using Clip, Matrix, and Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04003541outer must contain inner or the drawing is undefined.
Mike Klein9ff8c8c2018-02-07 01:58:51 +00003542In paint: Paint_Style determines if Round_Rect is stroked or filled;
Cary Clark8032b982017-07-28 11:04:54 -04003543if stroked, Paint_Stroke_Width describes the line thickness.
Cary Clarkbad5ad72017-08-03 17:14:08 -04003544If stroked and Round_Rect corner has zero length radii, Paint_Stroke_Join can
Mike Klein9ff8c8c2018-02-07 01:58:51 +00003545draw corners rounded or square.
Cary Clark8032b982017-07-28 11:04:54 -04003546
Cary Clarkbad5ad72017-08-03 17:14:08 -04003547GPU-backed platforms optimize drawing when both outer and inner are
Cary Clark8032b982017-07-28 11:04:54 -04003548concave and outer contains inner. These platforms may not be able to draw
Mike Klein9ff8c8c2018-02-07 01:58:51 +00003549Path built with identical data as fast.
Cary Clark8032b982017-07-28 11:04:54 -04003550
Cary Clarkbad5ad72017-08-03 17:14:08 -04003551#Param outer Round_Rect outer bounds to draw ##
3552#Param inner Round_Rect inner bounds to draw ##
3553#Param paint Paint stroke or fill, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003554
3555#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003556void draw(SkCanvas* canvas) {
3557 SkRRect outer = SkRRect::MakeRect({20, 40, 210, 200});
3558 SkRRect inner = SkRRect::MakeOval({60, 70, 170, 160});
3559 SkPaint paint;
3560 canvas->drawDRRect(outer, inner, paint);
Cary Clark8032b982017-07-28 11:04:54 -04003561}
3562##
3563
3564#Example
3565#Description
3566 Outer Rect has no corner radii, but stroke join is rounded.
3567 Inner Round_Rect has corner radii; outset stroke increases radii of corners.
3568 Stroke join does not affect inner Round_Rect since it has no sharp corners.
3569##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003570void draw(SkCanvas* canvas) {
3571 SkRRect outer = SkRRect::MakeRect({20, 40, 210, 200});
3572 SkRRect inner = SkRRect::MakeRectXY({60, 70, 170, 160}, 10, 10);
3573 SkPaint paint;
3574 paint.setAntiAlias(true);
3575 paint.setStyle(SkPaint::kStroke_Style);
3576 paint.setStrokeWidth(20);
3577 paint.setStrokeJoin(SkPaint::kRound_Join);
3578 canvas->drawDRRect(outer, inner, paint);
3579 paint.setStrokeWidth(1);
3580 paint.setColor(SK_ColorWHITE);
3581 canvas->drawDRRect(outer, inner, paint);
Cary Clark8032b982017-07-28 11:04:54 -04003582}
3583##
3584
Cary Clark2ade9972017-11-02 17:49:34 -04003585#SeeAlso drawRect drawRoundRect drawRRect drawCircle drawOval drawPath
Cary Clark8032b982017-07-28 11:04:54 -04003586
3587##
3588
3589# ------------------------------------------------------------------------------
3590
3591#Method void drawCircle(SkScalar cx, SkScalar cy, SkScalar radius, const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05003592#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05003593#Line # draws Circle using Clip, Matrix, and Paint ##
Cary Clark8032b982017-07-28 11:04:54 -04003594Draw Circle at (cx, cy) with radius using Clip, Matrix, and Paint paint.
3595If radius is zero or less, nothing is drawn.
Mike Klein9ff8c8c2018-02-07 01:58:51 +00003596In paint: Paint_Style determines if Circle is stroked or filled;
Cary Clark8032b982017-07-28 11:04:54 -04003597if stroked, Paint_Stroke_Width describes the line thickness.
3598
Cary Clarkbad5ad72017-08-03 17:14:08 -04003599#Param cx Circle center on the x-axis ##
3600#Param cy Circle center on the y-axis ##
3601#Param radius half the diameter of Circle ##
3602#Param paint Paint stroke or fill, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003603
3604#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003605 void draw(SkCanvas* canvas) {
3606 SkPaint paint;
3607 paint.setAntiAlias(true);
3608 canvas->drawCircle(128, 128, 90, paint);
3609 paint.setColor(SK_ColorWHITE);
3610 canvas->drawCircle(86, 86, 20, paint);
3611 canvas->drawCircle(160, 76, 20, paint);
3612 canvas->drawCircle(140, 150, 35, paint);
3613 }
3614##
3615
Cary Clark2ade9972017-11-02 17:49:34 -04003616#SeeAlso drawOval drawRRect drawRoundRect drawPath drawArc drawPoint drawLine
Cary Clarkbad5ad72017-08-03 17:14:08 -04003617
3618##
3619
3620#Method void drawCircle(SkPoint center, SkScalar radius, const SkPaint& paint)
3621
Cary Clarkce101242017-09-01 15:51:02 -04003622Draw Circle at center with radius using Clip, Matrix, and Paint paint.
Cary Clarkbad5ad72017-08-03 17:14:08 -04003623If radius is zero or less, nothing is drawn.
Mike Klein9ff8c8c2018-02-07 01:58:51 +00003624In paint: Paint_Style determines if Circle is stroked or filled;
Cary Clarkbad5ad72017-08-03 17:14:08 -04003625if stroked, Paint_Stroke_Width describes the line thickness.
3626
3627#Param center Circle center ##
3628#Param radius half the diameter of Circle ##
3629#Param paint Paint stroke or fill, blend, color, and so on, used to draw ##
3630
3631#Example
3632 void draw(SkCanvas* canvas) {
3633 SkPaint paint;
3634 paint.setAntiAlias(true);
3635 canvas->drawCircle(128, 128, 90, paint);
3636 paint.setColor(SK_ColorWHITE);
3637 canvas->drawCircle({86, 86}, 20, paint);
3638 canvas->drawCircle({160, 76}, 20, paint);
3639 canvas->drawCircle({140, 150}, 35, paint);
3640 }
Cary Clark8032b982017-07-28 11:04:54 -04003641##
3642
Cary Clark2ade9972017-11-02 17:49:34 -04003643#SeeAlso drawOval drawRRect drawRoundRect drawPath drawArc drawPoint drawLine
Cary Clark8032b982017-07-28 11:04:54 -04003644
3645##
3646
3647# ------------------------------------------------------------------------------
3648
3649#Method void drawArc(const SkRect& oval, SkScalar startAngle, SkScalar sweepAngle,
3650 bool useCenter, const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05003651#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05003652#Line # draws Arc using Clip, Matrix, and Paint ##
Cary Clark8032b982017-07-28 11:04:54 -04003653
3654Draw Arc using Clip, Matrix, and Paint paint.
Cary Clarkbad5ad72017-08-03 17:14:08 -04003655
Cary Clark8032b982017-07-28 11:04:54 -04003656Arc is part of Oval bounded by oval, sweeping from startAngle to startAngle plus
3657sweepAngle. startAngle and sweepAngle are in degrees.
Cary Clarkbad5ad72017-08-03 17:14:08 -04003658
Cary Clark8032b982017-07-28 11:04:54 -04003659startAngle of zero places start point at the right middle edge of oval.
3660A positive sweepAngle places Arc end point clockwise from start point;
3661a negative sweepAngle places Arc end point counterclockwise from start point.
3662sweepAngle may exceed 360 degrees, a full circle.
3663If useCenter is true, draw a wedge that includes lines from oval
3664center to Arc end points. If useCenter is false, draw Arc between end points.
3665
3666If Rect oval is empty or sweepAngle is zero, nothing is drawn.
3667
Cary Clarkbad5ad72017-08-03 17:14:08 -04003668#Param oval Rect bounds of Oval containing Arc to draw ##
3669#Param startAngle angle in degrees where Arc begins ##
3670#Param sweepAngle sweep angle in degrees; positive is clockwise ##
3671#Param useCenter if true, include the center of the oval ##
3672#Param paint Paint stroke or fill, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003673
3674#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003675 void draw(SkCanvas* canvas) {
3676 SkPaint paint;
3677 paint.setAntiAlias(true);
3678 SkRect oval = { 4, 4, 60, 60};
3679 for (auto useCenter : { false, true } ) {
3680 for (auto style : { SkPaint::kFill_Style, SkPaint::kStroke_Style } ) {
3681 paint.setStyle(style);
3682 for (auto degrees : { 45, 90, 180, 360} ) {
3683 canvas->drawArc(oval, 0, degrees , useCenter, paint);
3684 canvas->translate(64, 0);
3685 }
3686 canvas->translate(-256, 64);
3687 }
3688 }
Cary Clark8032b982017-07-28 11:04:54 -04003689 }
3690##
3691
3692#Example
3693#Height 64
Cary Clarkbad5ad72017-08-03 17:14:08 -04003694 void draw(SkCanvas* canvas) {
3695 SkPaint paint;
3696 paint.setAntiAlias(true);
3697 paint.setStyle(SkPaint::kStroke_Style);
3698 paint.setStrokeWidth(4);
3699 SkRect oval = { 4, 4, 60, 60};
3700 float intervals[] = { 5, 5 };
3701 paint.setPathEffect(SkDashPathEffect::Make(intervals, 2, 2.5f));
3702 for (auto degrees : { 270, 360, 540, 720 } ) {
3703 canvas->drawArc(oval, 0, degrees, false, paint);
3704 canvas->translate(64, 0);
3705 }
Cary Clark8032b982017-07-28 11:04:54 -04003706 }
3707##
3708
Cary Clark2ade9972017-11-02 17:49:34 -04003709#SeeAlso SkPath::arcTo drawCircle drawOval drawPath
Cary Clark8032b982017-07-28 11:04:54 -04003710
3711##
3712
3713# ------------------------------------------------------------------------------
3714
3715#Method void drawRoundRect(const SkRect& rect, SkScalar rx, SkScalar ry, const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05003716#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05003717#Line # draws Round_Rect using Clip, Matrix, and Paint ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003718Draw Round_Rect bounded by Rect rect, with corner radii (rx, ry) using Clip,
3719Matrix, and Paint paint.
3720
Mike Klein9ff8c8c2018-02-07 01:58:51 +00003721In paint: Paint_Style determines if Round_Rect is stroked or filled;
Cary Clark8032b982017-07-28 11:04:54 -04003722if stroked, Paint_Stroke_Width describes the line thickness.
3723If rx or ry are less than zero, they are treated as if they are zero.
3724If rx plus ry exceeds rect width or rect height, radii are scaled down to fit.
Cary Clarkbad5ad72017-08-03 17:14:08 -04003725If rx and ry are zero, Round_Rect is drawn as Rect and if stroked is affected by
3726Paint_Stroke_Join.
Cary Clark8032b982017-07-28 11:04:54 -04003727
Cary Clarkbad5ad72017-08-03 17:14:08 -04003728#Param rect Rect bounds of Round_Rect to draw ##
Cary Clarkce101242017-09-01 15:51:02 -04003729#Param rx axis length in x of oval describing rounded corners ##
3730#Param ry axis length in y of oval describing rounded corners ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003731#Param paint stroke, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003732
3733#Example
3734#Description
3735 Top row has a zero radius a generates a rectangle.
3736 Second row radii sum to less than sides.
3737 Third row radii sum equals sides.
3738 Fourth row radii sum exceeds sides; radii are scaled to fit.
3739##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003740 void draw(SkCanvas* canvas) {
3741 SkVector radii[] = { {0, 20}, {10, 10}, {10, 20}, {10, 40} };
3742 SkPaint paint;
3743 paint.setStrokeWidth(15);
3744 paint.setStrokeJoin(SkPaint::kRound_Join);
3745 paint.setAntiAlias(true);
3746 for (auto style : { SkPaint::kStroke_Style, SkPaint::kFill_Style } ) {
3747 paint.setStyle(style );
3748 for (size_t i = 0; i < SK_ARRAY_COUNT(radii); ++i) {
3749 canvas->drawRoundRect({10, 10, 60, 40}, radii[i].fX, radii[i].fY, paint);
3750 canvas->translate(0, 60);
3751 }
3752 canvas->translate(80, -240);
3753 }
Cary Clark8032b982017-07-28 11:04:54 -04003754 }
3755##
3756
Cary Clark2ade9972017-11-02 17:49:34 -04003757#SeeAlso DrawRRect drawRect drawDRRect drawPath drawCircle drawOval drawPoint
Cary Clark8032b982017-07-28 11:04:54 -04003758
3759##
3760
3761# ------------------------------------------------------------------------------
3762
3763#Method void drawPath(const SkPath& path, const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05003764#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05003765#Line # draws Path using Clip, Matrix, and Paint ##
Cary Clark8032b982017-07-28 11:04:54 -04003766Draw Path path using Clip, Matrix, and Paint paint.
3767Path contains an array of Path_Contour, each of which may be open or closed.
3768
3769In paint: Paint_Style determines if Round_Rect is stroked or filled:
Cary Clarkbad5ad72017-08-03 17:14:08 -04003770if filled, Path_Fill_Type determines whether Path_Contour describes inside or
3771outside of fill; if stroked, Paint_Stroke_Width describes the line thickness,
3772Paint_Stroke_Cap describes line ends, and Paint_Stroke_Join describes how
3773corners are drawn.
Cary Clark8032b982017-07-28 11:04:54 -04003774
Cary Clarkbad5ad72017-08-03 17:14:08 -04003775#Param path Path to draw ##
3776#Param paint stroke, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003777
3778#Example
3779#Description
3780 Top rows draw stroked path with combinations of joins and caps. The open contour
3781 is affected by caps; the closed contour is affected by joins.
Mike Klein9ff8c8c2018-02-07 01:58:51 +00003782 Bottom row draws fill the same for open and closed contour.
Cary Clark8032b982017-07-28 11:04:54 -04003783 First bottom column shows winding fills overlap.
3784 Second bottom column shows even odd fills exclude overlap.
3785 Third bottom column shows inverse winding fills area outside both contours.
3786##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003787void draw(SkCanvas* canvas) {
3788 SkPath path;
3789 path.moveTo(20, 20);
3790 path.quadTo(60, 20, 60, 60);
3791 path.close();
3792 path.moveTo(60, 20);
3793 path.quadTo(60, 60, 20, 60);
3794 SkPaint paint;
3795 paint.setStrokeWidth(10);
3796 paint.setAntiAlias(true);
3797 paint.setStyle(SkPaint::kStroke_Style);
3798 for (auto join: { SkPaint::kBevel_Join, SkPaint::kRound_Join, SkPaint::kMiter_Join } ) {
3799 paint.setStrokeJoin(join);
3800 for (auto cap: { SkPaint::kButt_Cap, SkPaint::kSquare_Cap, SkPaint::kRound_Cap } ) {
3801 paint.setStrokeCap(cap);
3802 canvas->drawPath(path, paint);
3803 canvas->translate(80, 0);
3804 }
3805 canvas->translate(-240, 60);
3806 }
3807 paint.setStyle(SkPaint::kFill_Style);
Mike Klein9ff8c8c2018-02-07 01:58:51 +00003808 for (auto fill : { SkPath::kWinding_FillType,
3809 SkPath::kEvenOdd_FillType,
Cary Clarkbad5ad72017-08-03 17:14:08 -04003810 SkPath::kInverseWinding_FillType } ) {
3811 path.setFillType(fill);
3812 canvas->save();
3813 canvas->clipRect({0, 10, 80, 70});
3814 canvas->drawPath(path, paint);
3815 canvas->restore();
3816 canvas->translate(80, 0);
3817 }
Cary Clark8032b982017-07-28 11:04:54 -04003818}
3819##
3820
Cary Clark2ade9972017-11-02 17:49:34 -04003821#SeeAlso SkPath drawLine drawArc drawRect drawPoints
Cary Clark8032b982017-07-28 11:04:54 -04003822
3823##
3824
3825# ------------------------------------------------------------------------------
Cary Clark08895c42018-02-01 09:37:32 -05003826#Subtopic Draw_Image
3827#Line # draws Image to Canvas ##
Cary Clark8032b982017-07-28 11:04:54 -04003828
Cary Clarkbad5ad72017-08-03 17:14:08 -04003829drawImage, drawImageRect, and drawImageNine can be called with a bare pointer or
3830a smart pointer as a convenience. The pairs of calls are otherwise identical.
Cary Clark8032b982017-07-28 11:04:54 -04003831
Cary Clark73fa9722017-08-29 17:36:51 -04003832#Method void drawImage(const SkImage* image, SkScalar left, SkScalar top, const SkPaint* paint = nullptr)
Cary Clarkab2621d2018-01-30 10:08:57 -05003833#In Draw_Image
Cary Clark78de7512018-02-07 07:27:09 -05003834#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05003835#Line # draws Image at (x, y) position ##
Cary Clark8032b982017-07-28 11:04:54 -04003836Draw Image image, with its top-left corner at (left, top),
3837using Clip, Matrix, and optional Paint paint.
3838
Cary Clarkbad5ad72017-08-03 17:14:08 -04003839If paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter, Blend_Mode,
3840and Draw_Looper. If image is kAlpha_8_SkColorType, apply Shader.
3841If paint contains Mask_Filter, generate mask from image bounds. If generated
3842mask extends beyond image bounds, replicate image edge colors, just as Shader
3843made from SkImage::makeShader with SkShader::kClamp_TileMode set replicates the
Mike Klein9ff8c8c2018-02-07 01:58:51 +00003844image edge color when it samples outside of its bounds.
Cary Clark8032b982017-07-28 11:04:54 -04003845
Cary Clarkbad5ad72017-08-03 17:14:08 -04003846#Param image uncompressed rectangular map of pixels ##
3847#Param left left side of image ##
3848#Param top top side of image ##
3849#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
3850 and so on; or nullptr
3851##
Cary Clark8032b982017-07-28 11:04:54 -04003852
3853#Example
3854#Height 64
3855#Image 4
Cary Clarkbad5ad72017-08-03 17:14:08 -04003856void draw(SkCanvas* canvas) {
3857 // sk_sp<SkImage> image;
3858 SkImage* imagePtr = image.get();
3859 canvas->drawImage(imagePtr, 0, 0);
3860 SkPaint paint;
3861 canvas->drawImage(imagePtr, 80, 0, &paint);
3862 paint.setAlpha(0x80);
3863 canvas->drawImage(imagePtr, 160, 0, &paint);
Cary Clark8032b982017-07-28 11:04:54 -04003864}
3865##
3866
Cary Clark2ade9972017-11-02 17:49:34 -04003867#SeeAlso drawBitmap drawImageLattice drawImageNine drawImageRect SkPaint::setImageFilter
Cary Clark8032b982017-07-28 11:04:54 -04003868
3869##
3870
3871# ------------------------------------------------------------------------------
3872
3873#Method void drawImage(const sk_sp<SkImage>& image, SkScalar left, SkScalar top,
Mike Klein9ff8c8c2018-02-07 01:58:51 +00003874 const SkPaint* paint = nullptr)
Cary Clark8032b982017-07-28 11:04:54 -04003875
3876Draw Image image, with its top-left corner at (left, top),
3877using Clip, Matrix, and optional Paint paint.
3878
Cary Clarkbad5ad72017-08-03 17:14:08 -04003879If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
3880Blend_Mode, and Draw_Looper. If image is kAlpha_8_SkColorType, apply Shader.
3881If paint contains Mask_Filter, generate mask from image bounds. If generated
3882mask extends beyond image bounds, replicate image edge colors, just as Shader
3883made from SkImage::makeShader with SkShader::kClamp_TileMode set replicates the
Mike Klein9ff8c8c2018-02-07 01:58:51 +00003884image edge color when it samples outside of its bounds.
Cary Clark8032b982017-07-28 11:04:54 -04003885
Cary Clarkbad5ad72017-08-03 17:14:08 -04003886#Param image uncompressed rectangular map of pixels ##
3887#Param left left side of image ##
3888#Param top pop side of image ##
3889#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
3890 and so on; or nullptr
3891##
Cary Clark8032b982017-07-28 11:04:54 -04003892
3893#Example
3894#Height 64
3895#Image 4
Cary Clarkbad5ad72017-08-03 17:14:08 -04003896void draw(SkCanvas* canvas) {
3897 // sk_sp<SkImage> image;
3898 canvas->drawImage(image, 0, 0);
3899 SkPaint paint;
3900 canvas->drawImage(image, 80, 0, &paint);
3901 paint.setAlpha(0x80);
3902 canvas->drawImage(image, 160, 0, &paint);
Cary Clark8032b982017-07-28 11:04:54 -04003903}
3904##
3905
Cary Clark2ade9972017-11-02 17:49:34 -04003906#SeeAlso drawBitmap drawImageLattice drawImageNine drawImageRect SkPaint::setImageFilter
Cary Clark8032b982017-07-28 11:04:54 -04003907
3908##
3909
3910# ------------------------------------------------------------------------------
3911
3912#Enum SrcRectConstraint
Cary Clark08895c42018-02-01 09:37:32 -05003913#Line # sets drawImageRect options ##
Cary Clark8032b982017-07-28 11:04:54 -04003914
3915#Code
3916 enum SrcRectConstraint {
Mike Klein9ff8c8c2018-02-07 01:58:51 +00003917 kStrict_SrcRectConstraint,
3918 kFast_SrcRectConstraint,
Cary Clark8032b982017-07-28 11:04:54 -04003919 };
3920##
3921
Cary Clarkce101242017-09-01 15:51:02 -04003922SrcRectConstraint controls the behavior at the edge of source Rect,
3923provided to drawImageRect, trading off speed for precision.
Cary Clark8032b982017-07-28 11:04:54 -04003924
Cary Clarkce101242017-09-01 15:51:02 -04003925Image_Filter in Paint may sample multiple pixels in the image. Source Rect
Cary Clarkbad5ad72017-08-03 17:14:08 -04003926restricts the bounds of pixels that may be read. Image_Filter may slow down if
Mike Klein9ff8c8c2018-02-07 01:58:51 +00003927it cannot read outside the bounds, when sampling near the edge of source Rect.
Cary Clark8032b982017-07-28 11:04:54 -04003928SrcRectConstraint specifies whether an Image_Filter is allowed to read pixels
Cary Clarkce101242017-09-01 15:51:02 -04003929outside source Rect.
Cary Clark8032b982017-07-28 11:04:54 -04003930
3931#Const kStrict_SrcRectConstraint
Cary Clarkce101242017-09-01 15:51:02 -04003932 Requires Image_Filter to respect source Rect,
Cary Clark8032b982017-07-28 11:04:54 -04003933 sampling only inside of its bounds, possibly with a performance penalty.
3934##
3935
3936#Const kFast_SrcRectConstraint
Cary Clarkce101242017-09-01 15:51:02 -04003937 Permits Image_Filter to sample outside of source Rect
Cary Clark8032b982017-07-28 11:04:54 -04003938 by half the width of Image_Filter, permitting it to run faster but with
3939 error at the image edges.
3940##
3941
3942#Example
3943#Height 64
3944#Description
3945 redBorder contains a black and white checkerboard bordered by red.
3946 redBorder is drawn scaled by 16 on the left.
Cary Clarkce101242017-09-01 15:51:02 -04003947 The middle and right bitmaps are filtered checkerboards.
Cary Clark8032b982017-07-28 11:04:54 -04003948 Drawing the checkerboard with kStrict_SrcRectConstraint shows only a blur of black and white.
3949 Drawing the checkerboard with kFast_SrcRectConstraint allows red to bleed in the corners.
3950##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003951void draw(SkCanvas* canvas) {
3952 SkBitmap redBorder;
3953 redBorder.allocPixels(SkImageInfo::MakeN32Premul(4, 4));
3954 SkCanvas checkRed(redBorder);
3955 checkRed.clear(SK_ColorRED);
3956 uint32_t checkers[][2] = { { SK_ColorBLACK, SK_ColorWHITE },
3957 { SK_ColorWHITE, SK_ColorBLACK } };
3958 checkRed.writePixels(
3959 SkImageInfo::MakeN32Premul(2, 2), (void*) checkers, sizeof(checkers[0]), 1, 1);
3960 canvas->scale(16, 16);
3961 canvas->drawBitmap(redBorder, 0, 0, nullptr);
3962 canvas->resetMatrix();
3963 sk_sp<SkImage> image = SkImage::MakeFromBitmap(redBorder);
3964 SkPaint lowPaint;
3965 lowPaint.setFilterQuality(kLow_SkFilterQuality);
3966 for (auto constraint : { SkCanvas::kStrict_SrcRectConstraint,
3967 SkCanvas::kFast_SrcRectConstraint } ) {
3968 canvas->translate(80, 0);
3969 canvas->drawImageRect(image.get(), SkRect::MakeLTRB(1, 1, 3, 3),
3970 SkRect::MakeLTRB(16, 16, 48, 48), &lowPaint, constraint);
3971 }
Cary Clark8032b982017-07-28 11:04:54 -04003972}
3973##
3974
Cary Clark2ade9972017-11-02 17:49:34 -04003975#SeeAlso drawImageRect drawImage SkPaint::setImageFilter
Cary Clark8032b982017-07-28 11:04:54 -04003976
3977##
3978
3979# ------------------------------------------------------------------------------
3980
3981#Method void drawImageRect(const SkImage* image, const SkRect& src, const SkRect& dst,
3982 const SkPaint* paint,
3983 SrcRectConstraint constraint = kStrict_SrcRectConstraint)
Cary Clarkab2621d2018-01-30 10:08:57 -05003984#In Draw_Image
Cary Clark78de7512018-02-07 07:27:09 -05003985#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05003986#Line # draws Image, source Rect to destination Rect ##
Cary Clark8032b982017-07-28 11:04:54 -04003987
3988Draw Rect src of Image image, scaled and translated to fill Rect dst.
3989Additionally transform draw using Clip, Matrix, and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04003990
Cary Clarkbad5ad72017-08-03 17:14:08 -04003991If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
3992Blend_Mode, and Draw_Looper. If image is kAlpha_8_SkColorType, apply Shader.
3993If paint contains Mask_Filter, generate mask from image bounds.
3994
3995If generated mask extends beyond image bounds, replicate image edge colors, just
3996as Shader made from SkImage::makeShader with SkShader::kClamp_TileMode set
Cary Clarkbc5697d2017-10-04 14:31:33 -04003997replicates the image edge color when it samples outside of its bounds.
Cary Clarkbad5ad72017-08-03 17:14:08 -04003998
3999constraint set to kStrict_SrcRectConstraint limits Paint Filter_Quality to
4000sample within src; set to kFast_SrcRectConstraint allows sampling outside to
4001improve performance.
4002
4003#Param image Image containing pixels, dimensions, and format ##
4004#Param src source Rect of image to draw from ##
4005#Param dst destination Rect of image to draw to ##
4006#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4007 and so on; or nullptr
4008##
4009#Param constraint filter strictly within src or draw faster ##
Cary Clark8032b982017-07-28 11:04:54 -04004010
4011#Example
4012#Height 64
4013#Description
4014 The left bitmap draws with Paint default kNone_SkFilterQuality, and stays within
Cary Clarkbc5697d2017-10-04 14:31:33 -04004015 its bounds; there is no bleeding with kFast_SrcRectConstraint.
Cary Clark8032b982017-07-28 11:04:54 -04004016 the middle and right bitmaps draw with kLow_SkFilterQuality; with
4017 kStrict_SrcRectConstraint, the filter remains within the checkerboard, and
4018 with kFast_SrcRectConstraint red bleeds on the edges.
4019##
Cary Clarkbad5ad72017-08-03 17:14:08 -04004020void draw(SkCanvas* canvas) {
Mike Klein9ff8c8c2018-02-07 01:58:51 +00004021 uint32_t pixels[][4] = {
Cary Clarkbad5ad72017-08-03 17:14:08 -04004022 { 0xFFFF0000, 0xFFFF0000, 0xFFFF0000, 0xFFFF0000 },
4023 { 0xFFFF0000, 0xFF000000, 0xFFFFFFFF, 0xFFFF0000 },
4024 { 0xFFFF0000, 0xFFFFFFFF, 0xFF000000, 0xFFFF0000 },
4025 { 0xFFFF0000, 0xFFFF0000, 0xFFFF0000, 0xFFFF0000 } };
4026 SkBitmap redBorder;
Mike Klein9ff8c8c2018-02-07 01:58:51 +00004027 redBorder.installPixels(SkImageInfo::MakeN32Premul(4, 4),
Cary Clarkbad5ad72017-08-03 17:14:08 -04004028 (void*) pixels, sizeof(pixels[0]));
4029 sk_sp<SkImage> image = SkImage::MakeFromBitmap(redBorder);
4030 SkPaint lowPaint;
4031 for (auto constraint : {
4032 SkCanvas::kFast_SrcRectConstraint,
4033 SkCanvas::kStrict_SrcRectConstraint,
4034 SkCanvas::kFast_SrcRectConstraint } ) {
4035 canvas->drawImageRect(image.get(), SkRect::MakeLTRB(1, 1, 3, 3),
4036 SkRect::MakeLTRB(16, 16, 48, 48), &lowPaint, constraint);
4037 lowPaint.setFilterQuality(kLow_SkFilterQuality);
4038 canvas->translate(80, 0);
4039 }
4040}
Cary Clark8032b982017-07-28 11:04:54 -04004041##
4042
Cary Clark2ade9972017-11-02 17:49:34 -04004043#SeeAlso SrcRectConstraint drawImage drawImageLattice drawImageNine
Cary Clark8032b982017-07-28 11:04:54 -04004044
4045##
4046
4047# ------------------------------------------------------------------------------
4048
4049#Method void drawImageRect(const SkImage* image, const SkIRect& isrc, const SkRect& dst,
4050 const SkPaint* paint, SrcRectConstraint constraint = kStrict_SrcRectConstraint)
Cary Clarkab2621d2018-01-30 10:08:57 -05004051#In Draw_Image
Cary Clark78de7512018-02-07 07:27:09 -05004052#In Draw
Cary Clark8032b982017-07-28 11:04:54 -04004053
4054Draw IRect isrc of Image image, scaled and translated to fill Rect dst.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004055Note that isrc is on integer pixel boundaries; dst may include fractional
4056boundaries. Additionally transform draw using Clip, Matrix, and optional Paint
Mike Klein9ff8c8c2018-02-07 01:58:51 +00004057paint.
Cary Clark8032b982017-07-28 11:04:54 -04004058
Cary Clarkbad5ad72017-08-03 17:14:08 -04004059If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4060Blend_Mode, and Draw_Looper. If image is kAlpha_8_SkColorType, apply Shader.
4061If paint contains Mask_Filter, generate mask from image bounds.
4062
4063If generated mask extends beyond image bounds, replicate image edge colors, just
4064as Shader made from SkImage::makeShader with SkShader::kClamp_TileMode set
Cary Clarkbc5697d2017-10-04 14:31:33 -04004065replicates the image edge color when it samples outside of its bounds.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004066
4067constraint set to kStrict_SrcRectConstraint limits Paint Filter_Quality to
Cary Clarkce101242017-09-01 15:51:02 -04004068sample within isrc; set to kFast_SrcRectConstraint allows sampling outside to
Cary Clarkbad5ad72017-08-03 17:14:08 -04004069improve performance.
4070
4071#Param image Image containing pixels, dimensions, and format ##
4072#Param isrc source IRect of image to draw from ##
4073#Param dst destination Rect of image to draw to ##
4074#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4075 and so on; or nullptr
4076##
Cary Clarkce101242017-09-01 15:51:02 -04004077#Param constraint filter strictly within isrc or draw faster ##
Cary Clark8032b982017-07-28 11:04:54 -04004078
4079#Example
4080#Image 4
Cary Clarkbad5ad72017-08-03 17:14:08 -04004081void draw(SkCanvas* canvas) {
4082 // sk_sp<SkImage> image;
4083 for (auto i : { 1, 2, 4, 8 } ) {
Mike Klein9ff8c8c2018-02-07 01:58:51 +00004084 canvas->drawImageRect(image.get(), SkIRect::MakeLTRB(0, 0, 100, 100),
Cary Clarkbad5ad72017-08-03 17:14:08 -04004085 SkRect::MakeXYWH(i * 20, i * 20, i * 20, i * 20), nullptr);
4086 }
Cary Clark8032b982017-07-28 11:04:54 -04004087}
4088##
4089
Cary Clark2ade9972017-11-02 17:49:34 -04004090#SeeAlso SrcRectConstraint drawImage drawImageLattice drawImageNine
Cary Clark8032b982017-07-28 11:04:54 -04004091
4092##
4093
4094# ------------------------------------------------------------------------------
4095
4096#Method void drawImageRect(const SkImage* image, const SkRect& dst, const SkPaint* paint,
4097 SrcRectConstraint constraint = kStrict_SrcRectConstraint)
Cary Clarkab2621d2018-01-30 10:08:57 -05004098#In Draw_Image
Cary Clark78de7512018-02-07 07:27:09 -05004099#In Draw
Cary Clark8032b982017-07-28 11:04:54 -04004100
Cary Clarkbad5ad72017-08-03 17:14:08 -04004101Draw Image image, scaled and translated to fill Rect dst, using Clip, Matrix,
4102and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004103
Cary Clarkbad5ad72017-08-03 17:14:08 -04004104If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4105Blend_Mode, and Draw_Looper. If image is kAlpha_8_SkColorType, apply Shader.
4106If paint contains Mask_Filter, generate mask from image bounds.
4107
4108If generated mask extends beyond image bounds, replicate image edge colors, just
4109as Shader made from SkImage::makeShader with SkShader::kClamp_TileMode set
Cary Clarkbc5697d2017-10-04 14:31:33 -04004110replicates the image edge color when it samples outside of its bounds.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004111
4112constraint set to kStrict_SrcRectConstraint limits Paint Filter_Quality to
Cary Clarkce101242017-09-01 15:51:02 -04004113sample within image; set to kFast_SrcRectConstraint allows sampling outside to
Cary Clarkbad5ad72017-08-03 17:14:08 -04004114improve performance.
4115
4116#Param image Image containing pixels, dimensions, and format ##
4117#Param dst destination Rect of image to draw to ##
4118#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4119 and so on; or nullptr
4120##
Cary Clarkce101242017-09-01 15:51:02 -04004121#Param constraint filter strictly within image or draw faster ##
Cary Clark8032b982017-07-28 11:04:54 -04004122
4123#Example
4124#Image 4
Cary Clarkbad5ad72017-08-03 17:14:08 -04004125void draw(SkCanvas* canvas) {
4126 // sk_sp<SkImage> image;
4127 for (auto i : { 20, 40, 80, 160 } ) {
4128 canvas->drawImageRect(image.get(), SkRect::MakeXYWH(i, i, i, i), nullptr);
4129 }
Cary Clark8032b982017-07-28 11:04:54 -04004130}
4131##
4132
Cary Clark2ade9972017-11-02 17:49:34 -04004133#SeeAlso SrcRectConstraint drawImage drawImageLattice drawImageNine
Cary Clark8032b982017-07-28 11:04:54 -04004134
4135##
4136
4137# ------------------------------------------------------------------------------
4138
4139#Method void drawImageRect(const sk_sp<SkImage>& image, const SkRect& src, const SkRect& dst,
4140 const SkPaint* paint,
Mike Klein9ff8c8c2018-02-07 01:58:51 +00004141 SrcRectConstraint constraint = kStrict_SrcRectConstraint)
Cary Clarkab2621d2018-01-30 10:08:57 -05004142#In Draw_Image
Cary Clark78de7512018-02-07 07:27:09 -05004143#In Draw
Cary Clark8032b982017-07-28 11:04:54 -04004144Draw Rect src of Image image, scaled and translated to fill Rect dst.
4145Additionally transform draw using Clip, Matrix, and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004146
Cary Clarkbad5ad72017-08-03 17:14:08 -04004147If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4148Blend_Mode, and Draw_Looper. If image is kAlpha_8_SkColorType, apply Shader.
4149If paint contains Mask_Filter, generate mask from image bounds.
4150
4151If generated mask extends beyond image bounds, replicate image edge colors, just
4152as Shader made from SkImage::makeShader with SkShader::kClamp_TileMode set
Cary Clarkbc5697d2017-10-04 14:31:33 -04004153replicates the image edge color when it samples outside of its bounds.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004154
4155constraint set to kStrict_SrcRectConstraint limits Paint Filter_Quality to
4156sample within src; set to kFast_SrcRectConstraint allows sampling outside to
4157improve performance.
4158
4159#Param image Image containing pixels, dimensions, and format ##
4160#Param src source Rect of image to draw from ##
4161#Param dst destination Rect of image to draw to ##
4162#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4163 and so on; or nullptr
4164##
4165#Param constraint filter strictly within src or draw faster ##
Cary Clark8032b982017-07-28 11:04:54 -04004166
4167#Example
4168#Height 64
4169#Description
4170 Canvas scales and translates; transformation from src to dst also scales.
4171 The two matrices are concatenated to create the final transformation.
4172##
Cary Clarkbad5ad72017-08-03 17:14:08 -04004173void draw(SkCanvas* canvas) {
4174 uint32_t pixels[][2] = { { SK_ColorBLACK, SK_ColorWHITE },
4175 { SK_ColorWHITE, SK_ColorBLACK } };
4176 SkBitmap bitmap;
Mike Klein9ff8c8c2018-02-07 01:58:51 +00004177 bitmap.installPixels(SkImageInfo::MakeN32Premul(2, 2),
Cary Clarkbad5ad72017-08-03 17:14:08 -04004178 (void*) pixels, sizeof(pixels[0]));
4179 sk_sp<SkImage> image = SkImage::MakeFromBitmap(bitmap);
4180 SkPaint paint;
4181 canvas->scale(4, 4);
4182 for (auto alpha : { 50, 100, 150, 255 } ) {
4183 paint.setAlpha(alpha);
4184 canvas->drawImageRect(image, SkRect::MakeWH(2, 2), SkRect::MakeWH(8, 8), &paint);
4185 canvas->translate(8, 0);
4186 }
4187}
Cary Clark8032b982017-07-28 11:04:54 -04004188##
4189
Cary Clark2ade9972017-11-02 17:49:34 -04004190#SeeAlso SrcRectConstraint drawImage drawImageLattice drawImageNine
Cary Clark8032b982017-07-28 11:04:54 -04004191
4192##
4193
4194# ------------------------------------------------------------------------------
4195
4196#Method void drawImageRect(const sk_sp<SkImage>& image, const SkIRect& isrc, const SkRect& dst,
Mike Klein9ff8c8c2018-02-07 01:58:51 +00004197 const SkPaint* paint, SrcRectConstraint constraint = kStrict_SrcRectConstraint)
Cary Clarkab2621d2018-01-30 10:08:57 -05004198#In Draw_Image
Cary Clark78de7512018-02-07 07:27:09 -05004199#In Draw
Cary Clark8032b982017-07-28 11:04:54 -04004200Draw IRect isrc of Image image, scaled and translated to fill Rect dst.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004201isrc is on integer pixel boundaries; dst may include fractional boundaries.
Cary Clark8032b982017-07-28 11:04:54 -04004202Additionally transform draw using Clip, Matrix, and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004203
Cary Clarkbad5ad72017-08-03 17:14:08 -04004204If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4205Blend_Mode, and Draw_Looper. If image is kAlpha_8_SkColorType, apply Shader.
4206If paint contains Mask_Filter, generate mask from image bounds.
4207
4208If generated mask extends beyond image bounds, replicate image edge colors, just
4209as Shader made from SkImage::makeShader with SkShader::kClamp_TileMode set
Cary Clarkbc5697d2017-10-04 14:31:33 -04004210replicates the image edge color when it samples outside of its bounds.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004211
4212constraint set to kStrict_SrcRectConstraint limits Paint Filter_Quality to
Cary Clarkce101242017-09-01 15:51:02 -04004213sample within image; set to kFast_SrcRectConstraint allows sampling outside to
Cary Clarkbad5ad72017-08-03 17:14:08 -04004214improve performance.
4215
4216#Param image Image containing pixels, dimensions, and format ##
4217#Param isrc source IRect of image to draw from ##
4218#Param dst destination Rect of image to draw to ##
4219#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4220 and so on; or nullptr
4221##
Cary Clarkce101242017-09-01 15:51:02 -04004222#Param constraint filter strictly within image or draw faster ##
Cary Clark8032b982017-07-28 11:04:54 -04004223
4224#Example
4225#Height 64
Cary Clarkbad5ad72017-08-03 17:14:08 -04004226void draw(SkCanvas* canvas) {
4227 uint32_t pixels[][2] = { { 0x00000000, 0x55555555},
4228 { 0xAAAAAAAA, 0xFFFFFFFF} };
4229 SkBitmap bitmap;
Mike Klein9ff8c8c2018-02-07 01:58:51 +00004230 bitmap.installPixels(SkImageInfo::MakeN32Premul(2, 2),
Cary Clarkbad5ad72017-08-03 17:14:08 -04004231 (void*) pixels, sizeof(pixels[0]));
4232 sk_sp<SkImage> image = SkImage::MakeFromBitmap(bitmap);
4233 SkPaint paint;
4234 canvas->scale(4, 4);
4235 for (auto color : { SK_ColorRED, SK_ColorBLUE, SK_ColorGREEN } ) {
4236 paint.setColorFilter(SkColorFilter::MakeModeFilter(color, SkBlendMode::kPlus));
4237 canvas->drawImageRect(image, SkIRect::MakeWH(2, 2), SkRect::MakeWH(8, 8), &paint);
4238 canvas->translate(8, 0);
4239 }
Cary Clark8032b982017-07-28 11:04:54 -04004240}
4241##
4242
Cary Clark2ade9972017-11-02 17:49:34 -04004243#SeeAlso SrcRectConstraint drawImage drawImageLattice drawImageNine
4244
Cary Clark8032b982017-07-28 11:04:54 -04004245##
4246
4247# ------------------------------------------------------------------------------
4248
4249#Method void drawImageRect(const sk_sp<SkImage>& image, const SkRect& dst, const SkPaint* paint,
Mike Klein9ff8c8c2018-02-07 01:58:51 +00004250 SrcRectConstraint constraint = kStrict_SrcRectConstraint)
Cary Clarkab2621d2018-01-30 10:08:57 -05004251#In Draw_Image
Cary Clark78de7512018-02-07 07:27:09 -05004252#In Draw
Cary Clark8032b982017-07-28 11:04:54 -04004253Draw Image image, scaled and translated to fill Rect dst,
4254using Clip, Matrix, and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004255
Cary Clarkbad5ad72017-08-03 17:14:08 -04004256If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4257Blend_Mode, and Draw_Looper. If image is kAlpha_8_SkColorType, apply Shader.
4258If paint contains Mask_Filter, generate mask from image bounds.
4259
4260If generated mask extends beyond image bounds, replicate image edge colors, just
4261as Shader made from SkImage::makeShader with SkShader::kClamp_TileMode set
Cary Clarkbc5697d2017-10-04 14:31:33 -04004262replicates the image edge color when it samples outside of its bounds.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004263
4264constraint set to kStrict_SrcRectConstraint limits Paint Filter_Quality to
Cary Clarkce101242017-09-01 15:51:02 -04004265sample within image; set to kFast_SrcRectConstraint allows sampling outside to
Cary Clarkbad5ad72017-08-03 17:14:08 -04004266improve performance.
4267
4268#Param image Image containing pixels, dimensions, and format ##
4269#Param dst destination Rect of image to draw to ##
4270#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4271 and so on; or nullptr
4272##
Cary Clarkce101242017-09-01 15:51:02 -04004273#Param constraint filter strictly within image or draw faster ##
Cary Clark8032b982017-07-28 11:04:54 -04004274
4275#Example
4276#Height 64
Cary Clarkbad5ad72017-08-03 17:14:08 -04004277void draw(SkCanvas* canvas) {
4278 uint32_t pixels[][2] = { { 0x00000000, 0x55550000},
4279 { 0xAAAA0000, 0xFFFF0000} };
4280 SkBitmap bitmap;
Mike Klein9ff8c8c2018-02-07 01:58:51 +00004281 bitmap.installPixels(SkImageInfo::MakeN32Premul(2, 2),
Cary Clarkbad5ad72017-08-03 17:14:08 -04004282 (void*) pixels, sizeof(pixels[0]));
4283 sk_sp<SkImage> image = SkImage::MakeFromBitmap(bitmap);
4284 SkPaint paint;
4285 canvas->scale(4, 4);
4286 for (auto color : { SK_ColorRED, SK_ColorBLUE, SK_ColorGREEN } ) {
4287 paint.setColorFilter(SkColorFilter::MakeModeFilter(color, SkBlendMode::kPlus));
4288 canvas->drawImageRect(image, SkRect::MakeWH(8, 8), &paint);
4289 canvas->translate(8, 0);
4290 }
Cary Clark8032b982017-07-28 11:04:54 -04004291}
4292##
4293
Cary Clark2ade9972017-11-02 17:49:34 -04004294#SeeAlso SrcRectConstraint drawImage drawImageLattice drawImageNine
Cary Clark8032b982017-07-28 11:04:54 -04004295
4296##
4297
4298# ------------------------------------------------------------------------------
4299
4300#Method void drawImageNine(const SkImage* image, const SkIRect& center, const SkRect& dst,
4301 const SkPaint* paint = nullptr)
Cary Clarkab2621d2018-01-30 10:08:57 -05004302#In Draw_Image
Cary Clark78de7512018-02-07 07:27:09 -05004303#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05004304#Line # draws Nine_Patch Image ##
Cary Clark8032b982017-07-28 11:04:54 -04004305
Cary Clarkd0530ba2017-09-14 11:25:39 -04004306Draw Image image stretched proportionally to fit into Rect dst.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004307IRect center divides the image into nine sections: four sides, four corners, and
Cary Clarkce101242017-09-01 15:51:02 -04004308the center. Corners are unmodified or scaled down proportionately if their sides
Cary Clarkbad5ad72017-08-03 17:14:08 -04004309are larger than dst; center and four sides are scaled to fit remaining space, if any.
Cary Clark8032b982017-07-28 11:04:54 -04004310
Cary Clarkbad5ad72017-08-03 17:14:08 -04004311Additionally transform draw using Clip, Matrix, and optional Paint paint.
4312
4313If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4314Blend_Mode, and Draw_Looper. If image is kAlpha_8_SkColorType, apply Shader.
4315If paint contains Mask_Filter, generate mask from image bounds.
4316
4317If generated mask extends beyond image bounds, replicate image edge colors, just
4318as Shader made from SkImage::makeShader with SkShader::kClamp_TileMode set
Cary Clarkbc5697d2017-10-04 14:31:33 -04004319replicates the image edge color when it samples outside of its bounds.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004320
4321#Param image Image containing pixels, dimensions, and format ##
4322#Param center IRect edge of image corners and sides ##
4323#Param dst destination Rect of image to draw to ##
4324#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4325 and so on; or nullptr
4326##
Cary Clark8032b982017-07-28 11:04:54 -04004327
4328#Example
4329#Height 128
4330#Description
4331 The leftmost image is smaller than center; only corners are drawn, all scaled to fit.
Cary Clarkce101242017-09-01 15:51:02 -04004332 The second image equals the size of center; only corners are drawn without scaling.
4333 The remaining images are larger than center. All corners draw without scaling.
4334 The sides and center are scaled if needed to take up the remaining space.
Cary Clark8032b982017-07-28 11:04:54 -04004335##
Cary Clarkbad5ad72017-08-03 17:14:08 -04004336void draw(SkCanvas* canvas) {
4337 SkIRect center = { 20, 10, 50, 40 };
4338 SkBitmap bitmap;
4339 bitmap.allocPixels(SkImageInfo::MakeN32Premul(60, 60));
4340 SkCanvas bitCanvas(bitmap);
4341 SkPaint paint;
4342 SkColor gray = 0xFF000000;
4343 int left = 0;
4344 for (auto right: { center.fLeft, center.fRight, bitmap.width() } ) {
4345 int top = 0;
4346 for (auto bottom: { center.fTop, center.fBottom, bitmap.height() } ) {
4347 paint.setColor(gray);
4348 bitCanvas.drawIRect(SkIRect::MakeLTRB(left, top, right, bottom), paint);
4349 gray += 0x001f1f1f;
4350 top = bottom;
4351 }
Mike Klein9ff8c8c2018-02-07 01:58:51 +00004352 left = right;
Cary Clarkbad5ad72017-08-03 17:14:08 -04004353 }
4354 sk_sp<SkImage> image = SkImage::MakeFromBitmap(bitmap);
4355 SkImage* imagePtr = image.get();
4356 for (auto dest: { 20, 30, 40, 60, 90 } ) {
4357 canvas->drawImageNine(imagePtr, center, SkRect::MakeWH(dest, dest), nullptr);
4358 canvas->translate(dest + 4, 0);
4359 }
Cary Clark8032b982017-07-28 11:04:54 -04004360}
4361##
4362
Cary Clark2ade9972017-11-02 17:49:34 -04004363#SeeAlso drawImage drawBitmapNine drawImageLattice drawImageRect
Cary Clark8032b982017-07-28 11:04:54 -04004364
4365##
4366
4367# ------------------------------------------------------------------------------
4368
4369#Method void drawImageNine(const sk_sp<SkImage>& image, const SkIRect& center, const SkRect& dst,
Mike Klein9ff8c8c2018-02-07 01:58:51 +00004370 const SkPaint* paint = nullptr)
Cary Clarkab2621d2018-01-30 10:08:57 -05004371#In Draw_Image
Cary Clark78de7512018-02-07 07:27:09 -05004372#In Draw
Cary Clarkd0530ba2017-09-14 11:25:39 -04004373Draw Image image stretched proportionally to fit into Rect dst.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004374IRect center divides the image into nine sections: four sides, four corners, and
Cary Clarkce101242017-09-01 15:51:02 -04004375the center. Corners are not scaled, or scaled down proportionately if their sides
Cary Clarkbad5ad72017-08-03 17:14:08 -04004376are larger than dst; center and four sides are scaled to fit remaining space, if any.
Cary Clark8032b982017-07-28 11:04:54 -04004377
Cary Clarkbad5ad72017-08-03 17:14:08 -04004378Additionally transform draw using Clip, Matrix, and optional Paint paint.
4379
4380If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4381Blend_Mode, and Draw_Looper. If image is kAlpha_8_SkColorType, apply Shader.
4382If paint contains Mask_Filter, generate mask from image bounds.
4383
4384If generated mask extends beyond image bounds, replicate image edge colors, just
4385as Shader made from SkImage::makeShader with SkShader::kClamp_TileMode set
Cary Clarkbc5697d2017-10-04 14:31:33 -04004386replicates the image edge color when it samples outside of its bounds.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004387
4388#Param image Image containing pixels, dimensions, and format ##
4389#Param center IRect edge of image corners and sides ##
4390#Param dst destination Rect of image to draw to ##
4391#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4392 and so on; or nullptr
4393##
Cary Clark8032b982017-07-28 11:04:54 -04004394
4395#Example
4396#Height 128
4397#Description
4398 The two leftmost images has four corners and sides to the left and right of center.
4399 The leftmost image scales the width of corners proportionately to fit.
Mike Klein9ff8c8c2018-02-07 01:58:51 +00004400 The third and fourth image corners are not scaled; the sides and center are scaled to
Cary Clark8032b982017-07-28 11:04:54 -04004401 fill the remaining space.
4402 The rightmost image has four corners scaled vertically to fit, and uses sides above
4403 and below center to fill the remaining space.
4404##
Cary Clarkbad5ad72017-08-03 17:14:08 -04004405void draw(SkCanvas* canvas) {
4406 SkIRect center = { 20, 10, 50, 40 };
4407 SkBitmap bitmap;
4408 bitmap.allocPixels(SkImageInfo::MakeN32Premul(60, 60));
4409 SkCanvas bitCanvas(bitmap);
4410 SkPaint paint;
4411 SkColor gray = 0xFF000000;
4412 int left = 0;
4413 for (auto right: { center.fLeft, center.fRight, bitmap.width() } ) {
4414 int top = 0;
4415 for (auto bottom: { center.fTop, center.fBottom, bitmap.height() } ) {
4416 paint.setColor(gray);
4417 bitCanvas.drawIRect(SkIRect::MakeLTRB(left, top, right, bottom), paint);
4418 gray += 0x001f1f1f;
4419 top = bottom;
4420 }
Mike Klein9ff8c8c2018-02-07 01:58:51 +00004421 left = right;
Cary Clarkbad5ad72017-08-03 17:14:08 -04004422 }
4423 sk_sp<SkImage> image = SkImage::MakeFromBitmap(bitmap);
4424 for (auto dest: { 20, 30, 40, 60, 90 } ) {
4425 canvas->drawImageNine(image, center, SkRect::MakeWH(dest, 110 - dest), nullptr);
4426 canvas->translate(dest + 4, 0);
4427 }
Cary Clark8032b982017-07-28 11:04:54 -04004428}
4429##
4430
Cary Clark2ade9972017-11-02 17:49:34 -04004431#SeeAlso drawImage drawBitmapNine drawImageLattice drawImageRect
Cary Clark8032b982017-07-28 11:04:54 -04004432
4433##
4434
4435# ------------------------------------------------------------------------------
4436
4437#Method void drawBitmap(const SkBitmap& bitmap, SkScalar left, SkScalar top,
Cary Clark73fa9722017-08-29 17:36:51 -04004438 const SkPaint* paint = nullptr)
Cary Clarkab2621d2018-01-30 10:08:57 -05004439#In Draw_Image
Cary Clark78de7512018-02-07 07:27:09 -05004440#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05004441#Line # draws Bitmap at (x, y) position ##
Cary Clark8032b982017-07-28 11:04:54 -04004442
4443Draw Bitmap bitmap, with its top-left corner at (left, top),
4444using Clip, Matrix, and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004445
Cary Clarka560c472017-11-27 10:44:06 -05004446If Paint paint is not nullptr, apply Color_Filter, Color_Alpha, Image_Filter,
Cary Clarkbad5ad72017-08-03 17:14:08 -04004447Blend_Mode, and Draw_Looper. If bitmap is kAlpha_8_SkColorType, apply Shader.
4448If paint contains Mask_Filter, generate mask from bitmap bounds.
4449
4450If generated mask extends beyond bitmap bounds, replicate bitmap edge colors,
4451just as Shader made from SkShader::MakeBitmapShader with
Cary Clarkbc5697d2017-10-04 14:31:33 -04004452SkShader::kClamp_TileMode set replicates the bitmap edge color when it samples
Mike Klein9ff8c8c2018-02-07 01:58:51 +00004453outside of its bounds.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004454
4455#Param bitmap Bitmap containing pixels, dimensions, and format ##
4456#Param left left side of bitmap ##
4457#Param top top side of bitmap ##
4458#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4459 and so on; or nullptr
4460##
Cary Clark8032b982017-07-28 11:04:54 -04004461
4462#Example
4463#Height 64
Cary Clarkbad5ad72017-08-03 17:14:08 -04004464void draw(SkCanvas* canvas) {
4465 uint8_t pixels[][8] = { { 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00},
4466 { 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00},
4467 { 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00},
4468 { 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF},
4469 { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
4470 { 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00},
4471 { 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0x00},
4472 { 0xFF, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0xFF} };
4473 SkBitmap bitmap;
Mike Klein9ff8c8c2018-02-07 01:58:51 +00004474 bitmap.installPixels(SkImageInfo::MakeA8(8, 8),
Cary Clarkbad5ad72017-08-03 17:14:08 -04004475 (void*) pixels, sizeof(pixels[0]));
4476 SkPaint paint;
4477 canvas->scale(4, 4);
4478 for (auto color : { SK_ColorRED, SK_ColorBLUE, 0xFF007F00} ) {
4479 paint.setColor(color);
4480 canvas->drawBitmap(bitmap, 0, 0, &paint);
4481 canvas->translate(12, 0);
4482 }
Cary Clark8032b982017-07-28 11:04:54 -04004483}
4484##
4485
Cary Clark2ade9972017-11-02 17:49:34 -04004486#SeeAlso drawImage drawBitmapLattice drawBitmapNine drawBitmapRect SkBitmap::readPixels SkBitmap::writePixels
Cary Clark8032b982017-07-28 11:04:54 -04004487
4488##
4489
4490# ------------------------------------------------------------------------------
4491
4492#Method void drawBitmapRect(const SkBitmap& bitmap, const SkRect& src, const SkRect& dst,
4493 const SkPaint* paint, SrcRectConstraint constraint = kStrict_SrcRectConstraint)
Cary Clarkab2621d2018-01-30 10:08:57 -05004494#In Draw_Image
Cary Clark78de7512018-02-07 07:27:09 -05004495#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05004496#Line # draws Bitmap, source Rect to destination Rect ##
Cary Clark8032b982017-07-28 11:04:54 -04004497
4498Draw Rect src of Bitmap bitmap, scaled and translated to fill Rect dst.
4499Additionally transform draw using Clip, Matrix, and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004500
Cary Clarkbad5ad72017-08-03 17:14:08 -04004501If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4502Blend_Mode, and Draw_Looper. If bitmap is kAlpha_8_SkColorType, apply Shader.
4503If paint contains Mask_Filter, generate mask from bitmap bounds.
4504
4505If generated mask extends beyond bitmap bounds, replicate bitmap edge colors,
4506just as Shader made from SkShader::MakeBitmapShader with
Cary Clarkbc5697d2017-10-04 14:31:33 -04004507SkShader::kClamp_TileMode set replicates the bitmap edge color when it samples
Cary Clarkbad5ad72017-08-03 17:14:08 -04004508outside of its bounds.
4509
4510constraint set to kStrict_SrcRectConstraint limits Paint Filter_Quality to
4511sample within src; set to kFast_SrcRectConstraint allows sampling outside to
4512improve performance.
4513
4514#Param bitmap Bitmap containing pixels, dimensions, and format ##
4515#Param src source Rect of image to draw from ##
4516#Param dst destination Rect of image to draw to ##
4517#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4518 and so on; or nullptr
4519##
4520#Param constraint filter strictly within src or draw faster ##
Cary Clark8032b982017-07-28 11:04:54 -04004521
4522#Example
4523#Height 64
Cary Clarkbad5ad72017-08-03 17:14:08 -04004524void draw(SkCanvas* canvas) {
4525 uint8_t pixels[][8] = { { 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00},
4526 { 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00},
4527 { 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00},
4528 { 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF},
4529 { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
4530 { 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00},
4531 { 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00},
4532 { 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00} };
4533 SkBitmap bitmap;
Mike Klein9ff8c8c2018-02-07 01:58:51 +00004534 bitmap.installPixels(SkImageInfo::MakeA8(8, 8),
Cary Clarkbad5ad72017-08-03 17:14:08 -04004535 (void*) pixels, sizeof(pixels[0]));
4536 SkPaint paint;
Cary Clark681287e2018-03-16 11:34:15 -04004537 paint.setMaskFilter(SkMaskFilter::MakeBlur(kSolid_SkBlurStyle, 6));
Cary Clarkbad5ad72017-08-03 17:14:08 -04004538 for (auto color : { SK_ColorRED, SK_ColorBLUE, 0xFF007F00} ) {
4539 paint.setColor(color);
4540 canvas->drawBitmapRect(bitmap, SkRect::MakeWH(8, 8), SkRect::MakeWH(32, 32), &paint);
4541 canvas->translate(48, 0);
4542 }
Cary Clark8032b982017-07-28 11:04:54 -04004543}
4544##
4545
Cary Clark2ade9972017-11-02 17:49:34 -04004546#SeeAlso drawImageRect drawBitmap drawBitmapLattice drawBitmapNine
Cary Clark8032b982017-07-28 11:04:54 -04004547
4548##
4549
4550# ------------------------------------------------------------------------------
4551
4552#Method void drawBitmapRect(const SkBitmap& bitmap, const SkIRect& isrc, const SkRect& dst,
4553 const SkPaint* paint, SrcRectConstraint constraint = kStrict_SrcRectConstraint)
Cary Clarkab2621d2018-01-30 10:08:57 -05004554#In Draw_Image
Cary Clark78de7512018-02-07 07:27:09 -05004555#In Draw
Cary Clark8032b982017-07-28 11:04:54 -04004556Draw IRect isrc of Bitmap bitmap, scaled and translated to fill Rect dst.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004557isrc is on integer pixel boundaries; dst may include fractional boundaries.
Cary Clark8032b982017-07-28 11:04:54 -04004558Additionally transform draw using Clip, Matrix, and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004559
Cary Clarkbad5ad72017-08-03 17:14:08 -04004560If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4561Blend_Mode, and Draw_Looper. If bitmap is kAlpha_8_SkColorType, apply Shader.
4562If paint contains Mask_Filter, generate mask from bitmap bounds.
4563
4564If generated mask extends beyond bitmap bounds, replicate bitmap edge colors,
4565just as Shader made from SkShader::MakeBitmapShader with
Cary Clarkbc5697d2017-10-04 14:31:33 -04004566SkShader::kClamp_TileMode set replicates the bitmap edge color when it samples
Cary Clarkbad5ad72017-08-03 17:14:08 -04004567outside of its bounds.
4568
4569constraint set to kStrict_SrcRectConstraint limits Paint Filter_Quality to
Cary Clarkce101242017-09-01 15:51:02 -04004570sample within isrc; set to kFast_SrcRectConstraint allows sampling outside to
Cary Clarkbad5ad72017-08-03 17:14:08 -04004571improve performance.
4572
4573#Param bitmap Bitmap containing pixels, dimensions, and format ##
4574#Param isrc source IRect of image to draw from ##
4575#Param dst destination Rect of image to draw to ##
4576#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4577 and so on; or nullptr
4578##
Cary Clarkce101242017-09-01 15:51:02 -04004579#Param constraint sample strictly within isrc, or draw faster ##
Cary Clark8032b982017-07-28 11:04:54 -04004580
4581#Example
4582#Height 64
Cary Clarkbad5ad72017-08-03 17:14:08 -04004583void draw(SkCanvas* canvas) {
4584 uint8_t pixels[][8] = { { 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00},
4585 { 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00},
4586 { 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0xFF},
4587 { 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0xFF},
4588 { 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF},
4589 { 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF},
4590 { 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00},
4591 { 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00} };
4592 SkBitmap bitmap;
Mike Klein9ff8c8c2018-02-07 01:58:51 +00004593 bitmap.installPixels(SkImageInfo::MakeA8(8, 8),
Cary Clarkbad5ad72017-08-03 17:14:08 -04004594 (void*) pixels, sizeof(pixels[0]));
4595 SkPaint paint;
4596 paint.setFilterQuality(kHigh_SkFilterQuality);
4597 for (auto color : { SK_ColorRED, SK_ColorBLUE, 0xFF007F00, 0xFF7f007f} ) {
4598 paint.setColor(color);
4599 canvas->drawBitmapRect(bitmap, SkIRect::MakeWH(8, 8), SkRect::MakeWH(32, 32), &paint);
4600 canvas->translate(48.25f, 0);
4601 }
Cary Clark8032b982017-07-28 11:04:54 -04004602}
4603##
4604
Cary Clark2ade9972017-11-02 17:49:34 -04004605#SeeAlso drawImageRect drawBitmap drawBitmapLattice drawBitmapNine
Cary Clark8032b982017-07-28 11:04:54 -04004606
4607##
4608
4609# ------------------------------------------------------------------------------
4610
4611#Method void drawBitmapRect(const SkBitmap& bitmap, const SkRect& dst, const SkPaint* paint,
4612 SrcRectConstraint constraint = kStrict_SrcRectConstraint)
Cary Clarkab2621d2018-01-30 10:08:57 -05004613#In Draw_Image
Cary Clark78de7512018-02-07 07:27:09 -05004614#In Draw
Cary Clark8032b982017-07-28 11:04:54 -04004615Draw Bitmap bitmap, scaled and translated to fill Rect dst.
Cary Clarkce101242017-09-01 15:51:02 -04004616bitmap bounds is on integer pixel boundaries; dst may include fractional boundaries.
Cary Clark8032b982017-07-28 11:04:54 -04004617Additionally transform draw using Clip, Matrix, and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004618
Cary Clarkbad5ad72017-08-03 17:14:08 -04004619If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4620Blend_Mode, and Draw_Looper. If bitmap is kAlpha_8_SkColorType, apply Shader.
4621If paint contains Mask_Filter, generate mask from bitmap bounds.
4622
4623If generated mask extends beyond bitmap bounds, replicate bitmap edge colors,
4624just as Shader made from SkShader::MakeBitmapShader with
Cary Clarkbc5697d2017-10-04 14:31:33 -04004625SkShader::kClamp_TileMode set replicates the bitmap edge color when it samples
Cary Clarkbad5ad72017-08-03 17:14:08 -04004626outside of its bounds.
4627
4628constraint set to kStrict_SrcRectConstraint limits Paint Filter_Quality to
Cary Clarkce101242017-09-01 15:51:02 -04004629sample within bitmap; set to kFast_SrcRectConstraint allows sampling outside to
Cary Clarkbad5ad72017-08-03 17:14:08 -04004630improve performance.
4631
4632#Param bitmap Bitmap containing pixels, dimensions, and format ##
4633#Param dst destination Rect of image to draw to ##
4634#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4635 and so on; or nullptr
4636##
Cary Clarkce101242017-09-01 15:51:02 -04004637#Param constraint filter strictly within bitmap or draw faster ##
Cary Clark8032b982017-07-28 11:04:54 -04004638
4639#Example
4640#Height 64
Cary Clarkbad5ad72017-08-03 17:14:08 -04004641void draw(SkCanvas* canvas) {
4642 uint32_t pixels[][2] = { { 0x00000000, 0x55550000},
4643 { 0xAAAA0000, 0xFFFF0000} };
4644 SkBitmap bitmap;
Mike Klein9ff8c8c2018-02-07 01:58:51 +00004645 bitmap.installPixels(SkImageInfo::MakeN32Premul(2, 2),
Cary Clarkbad5ad72017-08-03 17:14:08 -04004646 (void*) pixels, sizeof(pixels[0]));
4647 SkPaint paint;
4648 canvas->scale(4, 4);
4649 for (auto color : { SK_ColorRED, SK_ColorBLUE, SK_ColorGREEN } ) {
4650 paint.setColorFilter(SkColorFilter::MakeModeFilter(color, SkBlendMode::kPlus));
4651 canvas->drawBitmapRect(bitmap, SkRect::MakeWH(8, 8), &paint);
4652 canvas->translate(8, 0);
4653 }
Cary Clark8032b982017-07-28 11:04:54 -04004654}
4655##
4656
Cary Clark2ade9972017-11-02 17:49:34 -04004657#SeeAlso drawImageRect drawBitmap drawBitmapLattice drawBitmapNine
Cary Clark8032b982017-07-28 11:04:54 -04004658
4659##
4660
4661# ------------------------------------------------------------------------------
4662
4663#Method void drawBitmapNine(const SkBitmap& bitmap, const SkIRect& center, const SkRect& dst,
Cary Clark73fa9722017-08-29 17:36:51 -04004664 const SkPaint* paint = nullptr)
Cary Clarkab2621d2018-01-30 10:08:57 -05004665#In Draw_Image
Cary Clark78de7512018-02-07 07:27:09 -05004666#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05004667#Line # draws Nine_Patch Bitmap ##
Cary Clark8032b982017-07-28 11:04:54 -04004668
Cary Clarkd0530ba2017-09-14 11:25:39 -04004669Draw Bitmap bitmap stretched proportionally to fit into Rect dst.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004670IRect center divides the bitmap into nine sections: four sides, four corners,
Cary Clarkce101242017-09-01 15:51:02 -04004671and the center. Corners are not scaled, or scaled down proportionately if their
Cary Clarkbad5ad72017-08-03 17:14:08 -04004672sides are larger than dst; center and four sides are scaled to fit remaining
4673space, if any.
Cary Clark8032b982017-07-28 11:04:54 -04004674
Cary Clarkbad5ad72017-08-03 17:14:08 -04004675Additionally transform draw using Clip, Matrix, and optional Paint paint.
4676
4677If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4678Blend_Mode, and Draw_Looper. If bitmap is kAlpha_8_SkColorType, apply Shader.
4679If paint contains Mask_Filter, generate mask from bitmap bounds.
4680
4681If generated mask extends beyond bitmap bounds, replicate bitmap edge colors,
4682just as Shader made from SkShader::MakeBitmapShader with
Cary Clarkbc5697d2017-10-04 14:31:33 -04004683SkShader::kClamp_TileMode set replicates the bitmap edge color when it samples
Cary Clarkbad5ad72017-08-03 17:14:08 -04004684outside of its bounds.
4685
4686#Param bitmap Bitmap containing pixels, dimensions, and format ##
4687#Param center IRect edge of image corners and sides ##
4688#Param dst destination Rect of image to draw to ##
4689#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4690 and so on; or nullptr
4691##
Cary Clark8032b982017-07-28 11:04:54 -04004692
4693#Example
4694#Height 128
4695#Description
4696 The two leftmost bitmap draws has four corners and sides to the left and right of center.
4697 The leftmost bitmap draw scales the width of corners proportionately to fit.
Mike Klein9ff8c8c2018-02-07 01:58:51 +00004698 The third and fourth draw corners are not scaled; the sides and center are scaled to
Cary Clark8032b982017-07-28 11:04:54 -04004699 fill the remaining space.
4700 The rightmost bitmap draw has four corners scaled vertically to fit, and uses sides above
4701 and below center to fill the remaining space.
4702##
Cary Clarkbad5ad72017-08-03 17:14:08 -04004703void draw(SkCanvas* canvas) {
4704 SkIRect center = { 20, 10, 50, 40 };
4705 SkBitmap bitmap;
4706 bitmap.allocPixels(SkImageInfo::MakeN32Premul(60, 60));
4707 SkCanvas bitCanvas(bitmap);
4708 SkPaint paint;
4709 SkColor gray = 0xFF000000;
4710 int left = 0;
4711 for (auto right: { center.fLeft, center.fRight, bitmap.width() } ) {
4712 int top = 0;
4713 for (auto bottom: { center.fTop, center.fBottom, bitmap.height() } ) {
4714 paint.setColor(gray);
4715 bitCanvas.drawIRect(SkIRect::MakeLTRB(left, top, right, bottom), paint);
4716 gray += 0x001f1f1f;
4717 top = bottom;
4718 }
Mike Klein9ff8c8c2018-02-07 01:58:51 +00004719 left = right;
Cary Clarkbad5ad72017-08-03 17:14:08 -04004720 }
4721 for (auto dest: { 20, 30, 40, 60, 90 } ) {
4722 canvas->drawBitmapNine(bitmap, center, SkRect::MakeWH(dest, 110 - dest), nullptr);
4723 canvas->translate(dest + 4, 0);
4724 }
Cary Clark8032b982017-07-28 11:04:54 -04004725}
4726##
4727
Cary Clark2ade9972017-11-02 17:49:34 -04004728#SeeAlso drawImageNine drawBitmap drawBitmapLattice drawBitmapRect
Cary Clark8032b982017-07-28 11:04:54 -04004729
4730##
4731
4732# ------------------------------------------------------------------------------
4733#Struct Lattice
Cary Clark08895c42018-02-01 09:37:32 -05004734#Line # divides Bitmap or Image into a rectangular grid ##
Cary Clark8032b982017-07-28 11:04:54 -04004735#Code
4736 struct Lattice {
Cary Clark2f466242017-12-11 16:03:17 -05004737 enum RectType ...
Cary Clark8032b982017-07-28 11:04:54 -04004738
Cary Clark2f466242017-12-11 16:03:17 -05004739 const int* fXDivs;
4740 const int* fYDivs;
4741 const RectType* fRectTypes;
4742 int fXCount;
4743 int fYCount;
4744 const SkIRect* fBounds;
4745 const SkColor* fColors;
Cary Clark8032b982017-07-28 11:04:54 -04004746 };
4747##
4748
Cary Clark154beea2017-10-26 07:58:48 -04004749 Lattice divides Bitmap or Image into a rectangular grid.
4750 Grid entries on even columns and even rows are fixed; these entries are
4751 always drawn at their original size if the destination is large enough.
4752 If the destination side is too small to hold the fixed entries, all fixed
4753 entries are proportionately scaled down to fit.
4754 The grid entries not on even columns and rows are scaled to fit the
4755 remaining space, if any.
4756
Cary Clark2f466242017-12-11 16:03:17 -05004757 #Enum RectType
Cary Clark8032b982017-07-28 11:04:54 -04004758 #Code
Cary Clark2f466242017-12-11 16:03:17 -05004759 enum RectType : uint8_t {
4760 kDefault = 0,
4761 kTransparent,
4762 kFixedColor,
Cary Clark8032b982017-07-28 11:04:54 -04004763 };
4764 ##
4765
Cary Clark2f466242017-12-11 16:03:17 -05004766 Optional setting per rectangular grid entry to make it transparent,
4767 or to fill the grid entry with a color.
Cary Clark8032b982017-07-28 11:04:54 -04004768
Cary Clark2f466242017-12-11 16:03:17 -05004769 #Const kDefault 0
4770 Draws Bitmap into lattice rectangle.
4771 ##
4772
4773 #Const kTransparent 1
4774 Skips lattice rectangle by making it transparent.
4775 ##
4776
4777 #Const kFixedColor 2
4778 Draws one of fColors into lattice rectangle.
Cary Clark8032b982017-07-28 11:04:54 -04004779 ##
4780 ##
4781
4782 #Member const int* fXDivs
4783 Array of x-coordinates that divide the bitmap vertically.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004784 Array entries must be unique, increasing, greater than or equal to
4785 fBounds left edge, and less than fBounds right edge.
4786 Set the first element to fBounds left to collapse the left column of
4787 fixed grid entries.
Cary Clark8032b982017-07-28 11:04:54 -04004788 ##
4789
4790 #Member const int* fYDivs
4791 Array of y-coordinates that divide the bitmap horizontally.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004792 Array entries must be unique, increasing, greater than or equal to
4793 fBounds top edge, and less than fBounds bottom edge.
4794 Set the first element to fBounds top to collapse the top row of fixed
4795 grid entries.
Cary Clark8032b982017-07-28 11:04:54 -04004796 ##
4797
Cary Clark2f466242017-12-11 16:03:17 -05004798 #Member const RectType* fRectTypes
4799 Optional array of fill types, one per rectangular grid entry:
Cary Clarkbad5ad72017-08-03 17:14:08 -04004800 array length must be
4801 #Formula
4802 (fXCount + 1) * (fYCount + 1)
4803 ##
4804 .
Cary Clark6fc50412017-09-21 12:31:06 -04004805
Cary Clark2f466242017-12-11 16:03:17 -05004806 Each RectType is one of: kDefault, kTransparent, kFixedColor.
4807
Cary Clark8032b982017-07-28 11:04:54 -04004808 Array entries correspond to the rectangular grid entries, ascending
4809 left to right and then top to bottom.
4810 ##
4811
4812 #Member int fXCount
Cary Clarkbad5ad72017-08-03 17:14:08 -04004813 Number of entries in fXDivs array; one less than the number of
4814 horizontal divisions.
Cary Clark8032b982017-07-28 11:04:54 -04004815 ##
4816
4817 #Member int fYCount
Cary Clarkbad5ad72017-08-03 17:14:08 -04004818 Number of entries in fYDivs array; one less than the number of vertical
4819 divisions.
Cary Clark8032b982017-07-28 11:04:54 -04004820 ##
4821
4822 #Member const SkIRect* fBounds
4823 Optional subset IRect source to draw from.
4824 If nullptr, source bounds is dimensions of Bitmap or Image.
4825 ##
4826
Cary Clark2f466242017-12-11 16:03:17 -05004827 #Member const SkColor* fColors
4828 Optional array of colors, one per rectangular grid entry.
4829 Array length must be
4830 #Formula
4831 (fXCount + 1) * (fYCount + 1)
4832 ##
4833 .
4834
4835 Array entries correspond to the rectangular grid entries, ascending
4836 left to right, then top to bottom.
4837 ##
4838
Cary Clark8032b982017-07-28 11:04:54 -04004839#Struct Lattice ##
4840
4841#Method void drawBitmapLattice(const SkBitmap& bitmap, const Lattice& lattice, const SkRect& dst,
4842 const SkPaint* paint = nullptr)
Cary Clarkab2621d2018-01-30 10:08:57 -05004843#In Draw_Image
Cary Clark78de7512018-02-07 07:27:09 -05004844#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05004845#Line # draws proportionally stretched Bitmap ##
Cary Clark8032b982017-07-28 11:04:54 -04004846
Cary Clarkd0530ba2017-09-14 11:25:39 -04004847Draw Bitmap bitmap stretched proportionally to fit into Rect dst.
Cary Clark8032b982017-07-28 11:04:54 -04004848
4849Lattice lattice divides bitmap into a rectangular grid.
4850Each intersection of an even-numbered row and column is fixed; like the corners
Cary Clarkbad5ad72017-08-03 17:14:08 -04004851of drawBitmapNine, fixed lattice elements never scale larger than their initial
Cary Clarkbc5697d2017-10-04 14:31:33 -04004852size and shrink proportionately when all fixed elements exceed the bitmap
Cary Clarkbad5ad72017-08-03 17:14:08 -04004853dimension. All other grid elements scale to fill the available space, if any.
Cary Clark8032b982017-07-28 11:04:54 -04004854
4855Additionally transform draw using Clip, Matrix, and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004856
Cary Clarkbad5ad72017-08-03 17:14:08 -04004857If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4858Blend_Mode, and Draw_Looper. If bitmap is kAlpha_8_SkColorType, apply Shader.
4859If paint contains Mask_Filter, generate mask from bitmap bounds.
4860
4861If generated mask extends beyond bitmap bounds, replicate bitmap edge colors,
4862just as Shader made from SkShader::MakeBitmapShader with
Cary Clarkbc5697d2017-10-04 14:31:33 -04004863SkShader::kClamp_TileMode set replicates the bitmap edge color when it samples
Cary Clarkbad5ad72017-08-03 17:14:08 -04004864outside of its bounds.
4865
4866#Param bitmap Bitmap containing pixels, dimensions, and format ##
4867#Param lattice division of bitmap into fixed and variable rectangles ##
4868#Param dst destination Rect of image to draw to ##
4869#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4870 and so on; or nullptr
4871##
Cary Clark8032b982017-07-28 11:04:54 -04004872
4873#Example
4874#Height 128
4875#Description
4876 The two leftmost bitmap draws has four corners and sides to the left and right of center.
4877 The leftmost bitmap draw scales the width of corners proportionately to fit.
Mike Klein9ff8c8c2018-02-07 01:58:51 +00004878 The third and fourth draw corners are not scaled; the sides are scaled to
Cary Clark8032b982017-07-28 11:04:54 -04004879 fill the remaining space; the center is transparent.
4880 The rightmost bitmap draw has four corners scaled vertically to fit, and uses sides above
4881 and below center to fill the remaining space.
4882##
Cary Clarkbad5ad72017-08-03 17:14:08 -04004883void draw(SkCanvas* canvas) {
4884 SkIRect center = { 20, 10, 50, 40 };
4885 SkBitmap bitmap;
4886 bitmap.allocPixels(SkImageInfo::MakeN32Premul(60, 60));
4887 SkCanvas bitCanvas(bitmap);
4888 SkPaint paint;
4889 SkColor gray = 0xFF000000;
4890 int left = 0;
4891 for (auto right: { center.fLeft, center.fRight, bitmap.width() } ) {
4892 int top = 0;
4893 for (auto bottom: { center.fTop, center.fBottom, bitmap.height() } ) {
4894 paint.setColor(gray);
4895 bitCanvas.drawIRect(SkIRect::MakeLTRB(left, top, right, bottom), paint);
4896 gray += 0x001f1f1f;
4897 top = bottom;
4898 }
Mike Klein9ff8c8c2018-02-07 01:58:51 +00004899 left = right;
Cary Clarkbad5ad72017-08-03 17:14:08 -04004900 }
4901 const int xDivs[] = { center.fLeft, center.fRight };
4902 const int yDivs[] = { center.fTop, center.fBottom };
Cary Clarkca3ebcd2017-12-12 11:22:38 -05004903 SkCanvas::Lattice::RectType fillTypes[3][3];
4904 memset(fillTypes, 0, sizeof(fillTypes));
4905 fillTypes[1][1] = SkCanvas::Lattice::kTransparent;
4906 SkColor dummy[9]; // temporary pending bug fix
4907 SkCanvas::Lattice lattice = { xDivs, yDivs, fillTypes[0], SK_ARRAY_COUNT(xDivs),
4908 SK_ARRAY_COUNT(yDivs), nullptr, dummy };
Cary Clarkbad5ad72017-08-03 17:14:08 -04004909 for (auto dest: { 20, 30, 40, 60, 90 } ) {
Cary Clarkca3ebcd2017-12-12 11:22:38 -05004910 canvas->drawBitmapLattice(bitmap, lattice, SkRect::MakeWH(dest, 110 - dest), nullptr);
Cary Clarkbad5ad72017-08-03 17:14:08 -04004911 canvas->translate(dest + 4, 0);
4912 }
Cary Clark8032b982017-07-28 11:04:54 -04004913}
4914##
4915
Cary Clark2ade9972017-11-02 17:49:34 -04004916#SeeAlso drawImageLattice drawBitmap drawBitmapNine Lattice
Cary Clark8032b982017-07-28 11:04:54 -04004917
4918##
4919
4920# ------------------------------------------------------------------------------
4921
4922#Method void drawImageLattice(const SkImage* image, const Lattice& lattice, const SkRect& dst,
4923 const SkPaint* paint = nullptr)
Cary Clarkab2621d2018-01-30 10:08:57 -05004924#In Draw_Image
Cary Clark78de7512018-02-07 07:27:09 -05004925#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05004926#Line # draws proportionally stretched Image ##
Cary Clark8032b982017-07-28 11:04:54 -04004927
Cary Clarkd0530ba2017-09-14 11:25:39 -04004928Draw Image image stretched proportionally to fit into Rect dst.
Cary Clark8032b982017-07-28 11:04:54 -04004929
4930Lattice lattice divides image into a rectangular grid.
4931Each intersection of an even-numbered row and column is fixed; like the corners
Cary Clarkbad5ad72017-08-03 17:14:08 -04004932of drawBitmapNine, fixed lattice elements never scale larger than their initial
Cary Clarkbc5697d2017-10-04 14:31:33 -04004933size and shrink proportionately when all fixed elements exceed the bitmap
Cary Clarkbad5ad72017-08-03 17:14:08 -04004934dimension. All other grid elements scale to fill the available space, if any.
Cary Clark8032b982017-07-28 11:04:54 -04004935
4936Additionally transform draw using Clip, Matrix, and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004937
Cary Clarkbad5ad72017-08-03 17:14:08 -04004938If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4939Blend_Mode, and Draw_Looper. If bitmap is kAlpha_8_SkColorType, apply Shader.
4940If paint contains Mask_Filter, generate mask from bitmap bounds.
4941
4942If generated mask extends beyond bitmap bounds, replicate bitmap edge colors,
4943just as Shader made from SkShader::MakeBitmapShader with
Cary Clarkbc5697d2017-10-04 14:31:33 -04004944SkShader::kClamp_TileMode set replicates the bitmap edge color when it samples
Cary Clarkbad5ad72017-08-03 17:14:08 -04004945outside of its bounds.
4946
4947#Param image Image containing pixels, dimensions, and format ##
4948#Param lattice division of bitmap into fixed and variable rectangles ##
4949#Param dst destination Rect of image to draw to ##
4950#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4951 and so on; or nullptr
4952##
Cary Clark8032b982017-07-28 11:04:54 -04004953
4954#Example
4955#Height 128
4956#Description
4957 The leftmost image is smaller than center; only corners are drawn, all scaled to fit.
Cary Clarkce101242017-09-01 15:51:02 -04004958 The second image equals the size of center; only corners are drawn without scaling.
4959 The remaining images are larger than center. All corners draw without scaling. The sides
Cary Clark8032b982017-07-28 11:04:54 -04004960 are scaled if needed to take up the remaining space; the center is transparent.
4961##
Cary Clarkbad5ad72017-08-03 17:14:08 -04004962void draw(SkCanvas* canvas) {
4963 SkIRect center = { 20, 10, 50, 40 };
4964 SkBitmap bitmap;
4965 bitmap.allocPixels(SkImageInfo::MakeN32Premul(60, 60));
4966 SkCanvas bitCanvas(bitmap);
4967 SkPaint paint;
4968 SkColor gray = 0xFF000000;
4969 int left = 0;
4970 for (auto right: { center.fLeft, center.fRight, bitmap.width() } ) {
4971 int top = 0;
4972 for (auto bottom: { center.fTop, center.fBottom, bitmap.height() } ) {
4973 paint.setColor(gray);
4974 bitCanvas.drawIRect(SkIRect::MakeLTRB(left, top, right, bottom), paint);
4975 gray += 0x001f1f1f;
4976 top = bottom;
4977 }
Mike Klein9ff8c8c2018-02-07 01:58:51 +00004978 left = right;
Cary Clarkbad5ad72017-08-03 17:14:08 -04004979 }
Cary Clarkbad5ad72017-08-03 17:14:08 -04004980 sk_sp<SkImage> image = SkImage::MakeFromBitmap(bitmap);
4981 SkImage* imagePtr = image.get();
4982 for (auto dest: { 20, 30, 40, 60, 90 } ) {
4983 canvas->drawImageNine(imagePtr, center, SkRect::MakeWH(dest, dest), nullptr);
4984 canvas->translate(dest + 4, 0);
4985 }
Cary Clark8032b982017-07-28 11:04:54 -04004986}
4987##
4988
Cary Clark2ade9972017-11-02 17:49:34 -04004989#SeeAlso drawBitmapLattice drawImage drawImageNine Lattice
Cary Clark8032b982017-07-28 11:04:54 -04004990
4991##
4992
Cary Clark08895c42018-02-01 09:37:32 -05004993#Subtopic Draw_Image ##
Cary Clark8032b982017-07-28 11:04:54 -04004994
4995# ------------------------------------------------------------------------------
Cary Clark78de7512018-02-07 07:27:09 -05004996#Subtopic Draw_Text
4997#Populate
4998#Line # draws text into Canvas ##
4999##
Cary Clark8032b982017-07-28 11:04:54 -04005000
5001#Method void drawText(const void* text, size_t byteLength, SkScalar x, SkScalar y,
5002 const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05005003#In Draw_Text
5004#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05005005#Line # draws text at (x, y), using font advance ##
Cary Clark8032b982017-07-28 11:04:54 -04005006
5007Draw text, with origin at (x, y), using Clip, Matrix, and Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04005008
Cary Clarkbc5697d2017-10-04 14:31:33 -04005009text meaning depends on Paint_Text_Encoding; by default, text is encoded as
Cary Clarkbad5ad72017-08-03 17:14:08 -04005010UTF-8.
Cary Clark8032b982017-07-28 11:04:54 -04005011
Cary Clarkbad5ad72017-08-03 17:14:08 -04005012x and y meaning depends on Paint_Text_Align and Paint_Vertical_Text; by default
Cary Clarkbc5697d2017-10-04 14:31:33 -04005013text draws left to right, positioning the first glyph left side bearing at x
Mike Klein9ff8c8c2018-02-07 01:58:51 +00005014and its baseline at y. Text size is affected by Matrix and Paint_Text_Size.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005015
Mike Reed8ad91a92018-01-19 19:09:32 -05005016All elements of paint: Path_Effect, Mask_Filter, Shader,
Cary Clarkbad5ad72017-08-03 17:14:08 -04005017Color_Filter, Image_Filter, and Draw_Looper; apply to text. By default, draws
Cary Clarkce101242017-09-01 15:51:02 -04005018filled 12 point black Glyphs.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005019
Cary Clarkce101242017-09-01 15:51:02 -04005020#Param text character code points or Glyphs drawn ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005021#Param byteLength byte length of text array ##
5022#Param x start of text on x-axis ##
5023#Param y start of text on y-axis ##
5024#Param paint text size, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005025
5026#Example
5027#Height 200
5028#Description
5029 The same text is drawn varying Paint_Text_Size and varying
Mike Klein9ff8c8c2018-02-07 01:58:51 +00005030 Matrix.
Cary Clark8032b982017-07-28 11:04:54 -04005031##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005032void draw(SkCanvas* canvas) {
5033 SkPaint paint;
5034 paint.setAntiAlias(true);
5035 float textSizes[] = { 12, 18, 24, 36 };
5036 for (auto size: textSizes ) {
5037 paint.setTextSize(size);
5038 canvas->drawText("Aa", 2, 10, 20, paint);
5039 canvas->translate(0, size * 2);
5040 }
5041 paint.reset();
5042 paint.setAntiAlias(true);
5043 float yPos = 20;
5044 for (auto size: textSizes ) {
5045 float scale = size / 12.f;
5046 canvas->resetMatrix();
5047 canvas->translate(100, 0);
5048 canvas->scale(scale, scale);
5049 canvas->drawText("Aa", 2, 10 / scale, yPos / scale, paint);
Mike Klein9ff8c8c2018-02-07 01:58:51 +00005050 yPos += size * 2;
Cary Clarkbad5ad72017-08-03 17:14:08 -04005051 }
5052}
Cary Clark8032b982017-07-28 11:04:54 -04005053##
5054
Cary Clark2ade9972017-11-02 17:49:34 -04005055#SeeAlso drawString drawPosText drawPosTextH drawTextBlob drawTextOnPath drawTextRSXform
Cary Clark8032b982017-07-28 11:04:54 -04005056
5057##
5058
5059#Method void drawString(const char* string, SkScalar x, SkScalar y, const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05005060#In Draw_Text
5061#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05005062#Line # draws null terminated string at (x, y) using font advance ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005063Draw null terminated string, with origin at (x, y), using Clip, Matrix, and
Mike Reed9c2916e2018-03-15 13:37:08 -04005064Paint paint. Note that this per-glyph xform does not affect the shader (if present)
5065on the paint, just the glyph's geometry.
Cary Clark8032b982017-07-28 11:04:54 -04005066
Cary Clarkbc5697d2017-10-04 14:31:33 -04005067string meaning depends on Paint_Text_Encoding; by default, strings are encoded
5068as UTF-8. Other values of Paint_Text_Encoding are unlikely to produce the desired
Cary Clarkbad5ad72017-08-03 17:14:08 -04005069results, since zero bytes may be embedded in the string.
Cary Clark8032b982017-07-28 11:04:54 -04005070
Cary Clarkbad5ad72017-08-03 17:14:08 -04005071x and y meaning depends on Paint_Text_Align and Paint_Vertical_Text; by default
Cary Clarkbc5697d2017-10-04 14:31:33 -04005072string draws left to right, positioning the first glyph left side bearing at x
Mike Klein9ff8c8c2018-02-07 01:58:51 +00005073and its baseline at y. Text size is affected by Matrix and Paint_Text_Size.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005074
Mike Reed8ad91a92018-01-19 19:09:32 -05005075All elements of paint: Path_Effect, Mask_Filter, Shader,
Cary Clarkbad5ad72017-08-03 17:14:08 -04005076Color_Filter, Image_Filter, and Draw_Looper; apply to text. By default, draws
Cary Clarkce101242017-09-01 15:51:02 -04005077filled 12 point black Glyphs.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005078
Cary Clarkce101242017-09-01 15:51:02 -04005079#Param string character code points or Glyphs drawn,
Cary Clarkbad5ad72017-08-03 17:14:08 -04005080 ending with a char value of zero
5081##
5082#Param x start of string on x-axis ##
5083#Param y start of string on y-axis ##
5084#Param paint text size, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005085
5086#Example
5087 SkPaint paint;
5088 canvas->drawString("a small hello", 20, 20, paint);
5089##
5090
Cary Clark2ade9972017-11-02 17:49:34 -04005091#SeeAlso drawText drawPosText drawPosTextH drawTextBlob drawTextOnPath drawTextRSXform
Cary Clark8032b982017-07-28 11:04:54 -04005092
5093##
5094
5095#Method void drawString(const SkString& string, SkScalar x, SkScalar y, const SkPaint& paint)
5096
Cary Clarkbad5ad72017-08-03 17:14:08 -04005097Draw null terminated string, with origin at (x, y), using Clip, Matrix, and
5098Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04005099
Cary Clarkbc5697d2017-10-04 14:31:33 -04005100string meaning depends on Paint_Text_Encoding; by default, strings are encoded
5101as UTF-8. Other values of Paint_Text_Encoding are unlikely to produce the desired
Cary Clarkbad5ad72017-08-03 17:14:08 -04005102results, since zero bytes may be embedded in the string.
Cary Clark8032b982017-07-28 11:04:54 -04005103
Cary Clarkbad5ad72017-08-03 17:14:08 -04005104x and y meaning depends on Paint_Text_Align and Paint_Vertical_Text; by default
Cary Clarkbc5697d2017-10-04 14:31:33 -04005105string draws left to right, positioning the first glyph left side bearing at x
Mike Klein9ff8c8c2018-02-07 01:58:51 +00005106and its baseline at y. Text size is affected by Matrix and Paint_Text_Size.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005107
Mike Reed8ad91a92018-01-19 19:09:32 -05005108All elements of paint: Path_Effect, Mask_Filter, Shader,
Cary Clarkbad5ad72017-08-03 17:14:08 -04005109Color_Filter, Image_Filter, and Draw_Looper; apply to text. By default, draws
Cary Clarkce101242017-09-01 15:51:02 -04005110filled 12 point black Glyphs.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005111
Cary Clarkce101242017-09-01 15:51:02 -04005112#Param string character code points or Glyphs drawn,
Cary Clarkbad5ad72017-08-03 17:14:08 -04005113 ending with a char value of zero
5114##
5115#Param x start of string on x-axis ##
5116#Param y start of string on y-axis ##
5117#Param paint text size, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005118
5119#Example
5120 SkPaint paint;
5121 SkString string("a small hello");
5122 canvas->drawString(string, 20, 20, paint);
5123##
5124
Cary Clark2ade9972017-11-02 17:49:34 -04005125#SeeAlso drawText drawPosText drawPosTextH drawTextBlob drawTextOnPath drawTextRSXform
Cary Clark8032b982017-07-28 11:04:54 -04005126
5127##
5128
5129# ------------------------------------------------------------------------------
5130
5131#Method void drawPosText(const void* text, size_t byteLength, const SkPoint pos[],
5132 const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05005133#In Draw_Text
5134#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05005135#Line # draws text at array of (x, y) positions ##
Cary Clark8032b982017-07-28 11:04:54 -04005136
Cary Clarkbad5ad72017-08-03 17:14:08 -04005137Draw each glyph in text with the origin in pos array, using Clip, Matrix, and
Cary Clarkce101242017-09-01 15:51:02 -04005138Paint paint. The number of entries in pos array must match the number of Glyphs
Cary Clarkbad5ad72017-08-03 17:14:08 -04005139described by byteLength of text.
Cary Clark8032b982017-07-28 11:04:54 -04005140
Cary Clarkbc5697d2017-10-04 14:31:33 -04005141text meaning depends on Paint_Text_Encoding; by default, text is encoded as
Cary Clarkbad5ad72017-08-03 17:14:08 -04005142UTF-8. pos elements' meaning depends on Paint_Text_Align and Paint_Vertical_Text;
Cary Clarkbc5697d2017-10-04 14:31:33 -04005143by default each glyph left side bearing is positioned at x and its
Cary Clarkbad5ad72017-08-03 17:14:08 -04005144baseline is positioned at y. Text size is affected by Matrix and
Mike Klein9ff8c8c2018-02-07 01:58:51 +00005145Paint_Text_Size.
Cary Clark8032b982017-07-28 11:04:54 -04005146
Mike Reed8ad91a92018-01-19 19:09:32 -05005147All elements of paint: Path_Effect, Mask_Filter, Shader,
Cary Clarkbad5ad72017-08-03 17:14:08 -04005148Color_Filter, Image_Filter, and Draw_Looper; apply to text. By default, draws
Cary Clarkce101242017-09-01 15:51:02 -04005149filled 12 point black Glyphs.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005150
5151Layout engines such as Harfbuzz typically position each glyph
Cary Clarkbc5697d2017-10-04 14:31:33 -04005152rather than using the font advance widths.
Cary Clark8032b982017-07-28 11:04:54 -04005153
Cary Clarkce101242017-09-01 15:51:02 -04005154#Param text character code points or Glyphs drawn ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005155#Param byteLength byte length of text array ##
5156#Param pos array of glyph origins ##
5157#Param paint text size, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005158
5159#Example
5160#Height 120
Cary Clarkbad5ad72017-08-03 17:14:08 -04005161void draw(SkCanvas* canvas) {
5162 const char hello[] = "HeLLo!";
5163 const SkPoint pos[] = { {40, 100}, {82, 95}, {115, 110}, {130, 95}, {145, 85},
5164 {172, 100} };
5165 SkPaint paint;
5166 paint.setTextSize(60);
5167 canvas->drawPosText(hello, strlen(hello), pos, paint);
Cary Clark8032b982017-07-28 11:04:54 -04005168}
5169##
5170
Cary Clark2ade9972017-11-02 17:49:34 -04005171#SeeAlso drawText drawPosTextH drawTextBlob drawTextOnPath drawTextRSXform
Cary Clark8032b982017-07-28 11:04:54 -04005172
5173##
5174
5175# ------------------------------------------------------------------------------
5176
5177#Method void drawPosTextH(const void* text, size_t byteLength, const SkScalar xpos[], SkScalar constY,
5178 const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05005179#In Draw_Text
5180#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05005181#Line # draws text at x positions with common baseline ##
Cary Clark8032b982017-07-28 11:04:54 -04005182
Cary Clarkbad5ad72017-08-03 17:14:08 -04005183Draw each glyph in text with its (x, y) origin composed from xpos array and
5184constY, using Clip, Matrix, and Paint paint. The number of entries in xpos array
Cary Clarkce101242017-09-01 15:51:02 -04005185must match the number of Glyphs described by byteLength of text.
Cary Clark8032b982017-07-28 11:04:54 -04005186
Cary Clarkbc5697d2017-10-04 14:31:33 -04005187text meaning depends on Paint_Text_Encoding; by default, text is encoded as
Cary Clarkce101242017-09-01 15:51:02 -04005188UTF-8. xpos elements' meaning depends on Paint_Text_Align and Paint_Vertical_Text;
Cary Clarkbc5697d2017-10-04 14:31:33 -04005189by default each glyph left side bearing is positioned at an xpos element and
Cary Clarkbad5ad72017-08-03 17:14:08 -04005190its baseline is positioned at constY. Text size is affected by Matrix and
Mike Klein9ff8c8c2018-02-07 01:58:51 +00005191Paint_Text_Size.
Cary Clark8032b982017-07-28 11:04:54 -04005192
Mike Reed8ad91a92018-01-19 19:09:32 -05005193All elements of paint: Path_Effect, Mask_Filter, Shader,
Cary Clarkbad5ad72017-08-03 17:14:08 -04005194Color_Filter, Image_Filter, and Draw_Looper; apply to text. By default, draws
Cary Clarkce101242017-09-01 15:51:02 -04005195filled 12 point black Glyphs.
Cary Clark8032b982017-07-28 11:04:54 -04005196
Cary Clarkbad5ad72017-08-03 17:14:08 -04005197Layout engines such as Harfbuzz typically position each glyph
Cary Clarkbc5697d2017-10-04 14:31:33 -04005198rather than using the font advance widths if all Glyphs share the same
Cary Clarkbad5ad72017-08-03 17:14:08 -04005199baseline.
5200
Cary Clarkce101242017-09-01 15:51:02 -04005201#Param text character code points or Glyphs drawn ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005202#Param byteLength byte length of text array ##
5203#Param xpos array of x positions, used to position each glyph ##
5204#Param constY shared y coordinate for all of x positions ##
5205#Param paint text size, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005206
5207#Example
5208#Height 40
Cary Clarkbad5ad72017-08-03 17:14:08 -04005209 void draw(SkCanvas* canvas) {
5210 SkScalar xpos[] = { 20, 40, 80, 160 };
5211 SkPaint paint;
5212 canvas->drawPosTextH("XXXX", 4, xpos, 20, paint);
5213 }
Cary Clark8032b982017-07-28 11:04:54 -04005214##
5215
Cary Clark2ade9972017-11-02 17:49:34 -04005216#SeeAlso drawText drawPosText drawTextBlob drawTextOnPath drawTextRSXform
Cary Clark8032b982017-07-28 11:04:54 -04005217
5218##
5219
5220# ------------------------------------------------------------------------------
5221
5222#Method void drawTextOnPathHV(const void* text, size_t byteLength, const SkPath& path, SkScalar hOffset,
5223 SkScalar vOffset, const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05005224#In Draw_Text
5225#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05005226#Line # draws text following Path with offsets ##
Cary Clark8032b982017-07-28 11:04:54 -04005227
5228Draw text on Path path, using Clip, Matrix, and Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04005229
Cary Clarkbad5ad72017-08-03 17:14:08 -04005230Origin of text is at distance hOffset along the path, offset by a perpendicular
5231vector of length vOffset. If the path section corresponding the glyph advance is
5232curved, the glyph is drawn curved to match; control points in the glyph are
Cary Clarkbc5697d2017-10-04 14:31:33 -04005233mapped to projected points parallel to the path. If the text advance is larger
Cary Clarkbad5ad72017-08-03 17:14:08 -04005234than the path length, the excess text is clipped.
5235
Cary Clarkbc5697d2017-10-04 14:31:33 -04005236text meaning depends on Paint_Text_Encoding; by default, text is encoded as
Cary Clarkbad5ad72017-08-03 17:14:08 -04005237UTF-8. Origin meaning depends on Paint_Text_Align and Paint_Vertical_Text; by
Cary Clarkbc5697d2017-10-04 14:31:33 -04005238default text positions the first glyph left side bearing at origin x and its
Mike Klein9ff8c8c2018-02-07 01:58:51 +00005239baseline at origin y. Text size is affected by Matrix and Paint_Text_Size.
Cary Clark8032b982017-07-28 11:04:54 -04005240
Mike Reed8ad91a92018-01-19 19:09:32 -05005241All elements of paint: Path_Effect, Mask_Filter, Shader,
Cary Clarkbad5ad72017-08-03 17:14:08 -04005242Color_Filter, Image_Filter, and Draw_Looper; apply to text. By default, draws
Cary Clarkce101242017-09-01 15:51:02 -04005243filled 12 point black Glyphs.
Cary Clark8032b982017-07-28 11:04:54 -04005244
Cary Clarkce101242017-09-01 15:51:02 -04005245#Param text character code points or Glyphs drawn ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005246#Param byteLength byte length of text array ##
5247#Param path Path providing text baseline ##
5248#Param hOffset distance along path to offset origin ##
5249#Param vOffset offset of text above (if negative) or below (if positive) the path ##
5250#Param paint text size, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005251
5252#Example
Mike Klein9ff8c8c2018-02-07 01:58:51 +00005253 void draw(SkCanvas* canvas) {
Cary Clarkbad5ad72017-08-03 17:14:08 -04005254 const char aero[] = "correo a" "\xC3" "\xA9" "reo";
5255 const size_t len = sizeof(aero) - 1;
5256 SkPath path;
5257 path.addOval({43-26, 43-26, 43+26, 43+26}, SkPath::kCW_Direction, 3);
5258 SkPaint paint;
5259 paint.setTextSize(24);
5260 for (auto offset : { 0, 10, 20 } ) {
5261 canvas->drawTextOnPathHV(aero, len, path, 0, -offset, paint);
5262 canvas->translate(70 + offset, 70 + offset);
5263 }
5264 }
Cary Clark8032b982017-07-28 11:04:54 -04005265##
5266
Cary Clark2ade9972017-11-02 17:49:34 -04005267#SeeAlso drawTextOnPath drawText drawPosTextH drawTextBlob drawTextRSXform
Cary Clark8032b982017-07-28 11:04:54 -04005268
5269##
5270
5271# ------------------------------------------------------------------------------
5272
5273#Method void drawTextOnPath(const void* text, size_t byteLength, const SkPath& path,
5274 const SkMatrix* matrix, const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05005275#In Draw_Text
5276#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05005277#Line # draws text following Path contour ##
Cary Clark8032b982017-07-28 11:04:54 -04005278
5279Draw text on Path path, using Clip, Matrix, and Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04005280
Cary Clarkbad5ad72017-08-03 17:14:08 -04005281Origin of text is at beginning of path offset by matrix, if provided, before it
5282is mapped to path. If the path section corresponding the glyph advance is
5283curved, the glyph is drawn curved to match; control points in the glyph are
Cary Clarkbc5697d2017-10-04 14:31:33 -04005284mapped to projected points parallel to the path. If the text advance is larger
Cary Clarkbad5ad72017-08-03 17:14:08 -04005285than the path length, the excess text is clipped.
5286
Cary Clarkbc5697d2017-10-04 14:31:33 -04005287text meaning depends on Paint_Text_Encoding; by default, text is encoded as
Cary Clarkbad5ad72017-08-03 17:14:08 -04005288UTF-8. Origin meaning depends on Paint_Text_Align and Paint_Vertical_Text; by
Cary Clarkbc5697d2017-10-04 14:31:33 -04005289default text positions the first glyph left side bearing at origin x and its
Mike Klein9ff8c8c2018-02-07 01:58:51 +00005290baseline at origin y. Text size is affected by Matrix and Paint_Text_Size.
Cary Clark8032b982017-07-28 11:04:54 -04005291
Mike Reed8ad91a92018-01-19 19:09:32 -05005292All elements of paint: Path_Effect, Mask_Filter, Shader,
Cary Clarkbad5ad72017-08-03 17:14:08 -04005293Color_Filter, Image_Filter, and Draw_Looper; apply to text. By default, draws
Cary Clarkce101242017-09-01 15:51:02 -04005294filled 12 point black Glyphs.
Cary Clark8032b982017-07-28 11:04:54 -04005295
Cary Clarkce101242017-09-01 15:51:02 -04005296#Param text character code points or Glyphs drawn ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005297#Param byteLength byte length of text array ##
5298#Param path Path providing text baseline ##
Cary Clarkce101242017-09-01 15:51:02 -04005299#Param matrix transform of Glyphs before mapping to path; may be nullptr
Cary Clarka523d2d2017-08-30 08:58:10 -04005300 to use identity Matrix
Cary Clarkbad5ad72017-08-03 17:14:08 -04005301##
5302#Param paint text size, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005303
5304#Example
Mike Klein9ff8c8c2018-02-07 01:58:51 +00005305 void draw(SkCanvas* canvas) {
Cary Clarkbad5ad72017-08-03 17:14:08 -04005306 const char roller[] = "rollercoaster";
5307 const size_t len = sizeof(roller) - 1;
5308 SkPath path;
5309 path.cubicTo(40, -80, 120, 80, 160, -40);
5310 SkPaint paint;
5311 paint.setTextSize(32);
5312 paint.setStyle(SkPaint::kStroke_Style);
5313 SkMatrix matrix;
5314 matrix.setIdentity();
5315 for (int i = 0; i < 3; ++i) {
5316 canvas->translate(25, 60);
5317 canvas->drawPath(path, paint);
5318 canvas->drawTextOnPath(roller, len, path, &matrix, paint);
5319 matrix.preTranslate(0, 10);
5320 }
5321 }
Cary Clark8032b982017-07-28 11:04:54 -04005322##
5323
Cary Clark2ade9972017-11-02 17:49:34 -04005324#SeeAlso drawTextOnPathHV drawText drawPosTextH drawTextBlob drawTextRSXform
Cary Clark8032b982017-07-28 11:04:54 -04005325
5326##
5327
5328# ------------------------------------------------------------------------------
5329
5330#Method void drawTextRSXform(const void* text, size_t byteLength, const SkRSXform xform[],
5331 const SkRect* cullRect, const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05005332#In Draw_Text
5333#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05005334#Line # draws text with array of RSXform ##
Cary Clark8032b982017-07-28 11:04:54 -04005335
5336Draw text, transforming each glyph by the corresponding SkRSXform,
5337using Clip, Matrix, and Paint paint.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005338
Mike Klein9ff8c8c2018-02-07 01:58:51 +00005339RSXform array specifies a separate square scale, rotation, and translation for
Cary Clark8032b982017-07-28 11:04:54 -04005340each glyph.
Cary Clark8032b982017-07-28 11:04:54 -04005341
Cary Clarkbad5ad72017-08-03 17:14:08 -04005342Optional Rect cullRect is a conservative bounds of text, taking into account
Cary Clarkce101242017-09-01 15:51:02 -04005343RSXform and paint. If cullRect is outside of Clip, canvas can skip drawing.
Cary Clark8032b982017-07-28 11:04:54 -04005344
Mike Reed8ad91a92018-01-19 19:09:32 -05005345All elements of paint: Path_Effect, Mask_Filter, Shader,
Cary Clarkbad5ad72017-08-03 17:14:08 -04005346Color_Filter, Image_Filter, and Draw_Looper; apply to text. By default, draws
Cary Clarkce101242017-09-01 15:51:02 -04005347filled 12 point black Glyphs.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005348
Cary Clarkce101242017-09-01 15:51:02 -04005349#Param text character code points or Glyphs drawn ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005350#Param byteLength byte length of text array ##
5351#Param xform RSXform rotates, scales, and translates each glyph individually ##
5352#Param cullRect Rect bounds of text for efficient clipping; or nullptr ##
5353#Param paint text size, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005354
5355#Example
Mike Klein9ff8c8c2018-02-07 01:58:51 +00005356void draw(SkCanvas* canvas) {
Cary Clarkbad5ad72017-08-03 17:14:08 -04005357 const int iterations = 26;
5358 SkRSXform transforms[iterations];
5359 char alphabet[iterations];
5360 SkScalar angle = 0;
5361 SkScalar scale = 1;
5362 for (size_t i = 0; i < SK_ARRAY_COUNT(transforms); ++i) {
5363 const SkScalar s = SkScalarSin(angle) * scale;
5364 const SkScalar c = SkScalarCos(angle) * scale;
5365 transforms[i] = SkRSXform::Make(-c, -s, -s * 16, c * 16);
5366 angle += .45;
5367 scale += .2;
5368 alphabet[i] = 'A' + i;
5369 }
5370 SkPaint paint;
5371 paint.setTextAlign(SkPaint::kCenter_Align);
5372 canvas->translate(110, 138);
5373 canvas->drawTextRSXform(alphabet, sizeof(alphabet), transforms, nullptr, paint);
Cary Clark8032b982017-07-28 11:04:54 -04005374}
5375##
5376
Cary Clark2ade9972017-11-02 17:49:34 -04005377#SeeAlso drawTextOnPath drawTextOnPathHV drawText drawPosText drawTextBlob
Cary Clark8032b982017-07-28 11:04:54 -04005378
5379##
5380
5381# ------------------------------------------------------------------------------
5382
5383#Method void drawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y, const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05005384#In Draw_Text
5385#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05005386#Line # draws text with arrays of positions and Paint ##
Cary Clark8032b982017-07-28 11:04:54 -04005387Draw Text_Blob blob at (x, y), using Clip, Matrix, and Paint paint.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005388
Cary Clarkce101242017-09-01 15:51:02 -04005389blob contains Glyphs, their positions, and paint attributes specific to text:
Cary Clarkbad5ad72017-08-03 17:14:08 -04005390Typeface, Paint_Text_Size, Paint_Text_Scale_X, Paint_Text_Skew_X,
5391Paint_Text_Align, Paint_Hinting, Anti-alias, Paint_Fake_Bold,
5392Font_Embedded_Bitmaps, Full_Hinting_Spacing, LCD_Text, Linear_Text,
5393Subpixel_Text, and Paint_Vertical_Text.
Cary Clark8032b982017-07-28 11:04:54 -04005394
Cary Clark3cd22cc2017-12-01 11:49:58 -05005395Paint_Text_Encoding must be set to SkPaint::kGlyphID_TextEncoding.
5396
Mike Reed8ad91a92018-01-19 19:09:32 -05005397Elements of paint: Path_Effect, Mask_Filter, Shader, Color_Filter,
Cary Clark8032b982017-07-28 11:04:54 -04005398Image_Filter, and Draw_Looper; apply to blob.
5399
Cary Clarkce101242017-09-01 15:51:02 -04005400#Param blob Glyphs, positions, and their paints' text size, typeface, and so on ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005401#Param x horizontal offset applied to blob ##
5402#Param y vertical offset applied to blob ##
5403#Param paint blend, color, stroking, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005404
5405#Example
5406#Height 120
Cary Clarkbad5ad72017-08-03 17:14:08 -04005407 void draw(SkCanvas* canvas) {
Cary Clark2f466242017-12-11 16:03:17 -05005408 SkTextBlobBuilder textBlobBuilder;
5409 const char bunny[] = "/(^x^)\\";
5410 const int len = sizeof(bunny) - 1;
5411 uint16_t glyphs[len];
5412 SkPaint paint;
5413 paint.textToGlyphs(bunny, len, glyphs);
Cary Clark3cd22cc2017-12-01 11:49:58 -05005414 paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
Cary Clark2f466242017-12-11 16:03:17 -05005415 int runs[] = { 3, 1, 3 };
5416 SkPoint textPos = { 20, 100 };
5417 int glyphIndex = 0;
5418 for (auto runLen : runs) {
5419 paint.setTextSize(1 == runLen ? 20 : 50);
Mike Klein9ff8c8c2018-02-07 01:58:51 +00005420 const SkTextBlobBuilder::RunBuffer& run =
Cary Clark2f466242017-12-11 16:03:17 -05005421 textBlobBuilder.allocRun(paint, runLen, textPos.fX, textPos.fY);
5422 memcpy(run.glyphs, &glyphs[glyphIndex], sizeof(glyphs[0]) * runLen);
5423 textPos.fX += paint.measureText(&glyphs[glyphIndex], sizeof(glyphs[0]) * runLen, nullptr);
5424 glyphIndex += runLen;
5425 }
5426 sk_sp<const SkTextBlob> blob = textBlobBuilder.make();
5427 paint.reset();
Cary Clarkbad5ad72017-08-03 17:14:08 -04005428 canvas->drawTextBlob(blob.get(), 0, 0, paint);
Cary Clark8032b982017-07-28 11:04:54 -04005429 }
5430##
5431
Cary Clark2ade9972017-11-02 17:49:34 -04005432#SeeAlso drawText drawPosText drawPosTextH
Cary Clark8032b982017-07-28 11:04:54 -04005433
5434##
5435
5436# ------------------------------------------------------------------------------
5437
Mike Klein9ff8c8c2018-02-07 01:58:51 +00005438#Method void drawTextBlob(const sk_sp<SkTextBlob>& blob, SkScalar x, SkScalar y, const SkPaint& paint)
Cary Clark8032b982017-07-28 11:04:54 -04005439
5440Draw Text_Blob blob at (x, y), using Clip, Matrix, and Paint paint.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005441
Cary Clarkce101242017-09-01 15:51:02 -04005442blob contains Glyphs, their positions, and paint attributes specific to text:
Cary Clarkbad5ad72017-08-03 17:14:08 -04005443Typeface, Paint_Text_Size, Paint_Text_Scale_X, Paint_Text_Skew_X,
5444Paint_Text_Align, Paint_Hinting, Anti-alias, Paint_Fake_Bold,
5445Font_Embedded_Bitmaps, Full_Hinting_Spacing, LCD_Text, Linear_Text,
5446Subpixel_Text, and Paint_Vertical_Text.
Cary Clark8032b982017-07-28 11:04:54 -04005447
Cary Clark3cd22cc2017-12-01 11:49:58 -05005448Paint_Text_Encoding must be set to SkPaint::kGlyphID_TextEncoding.
5449
Mike Klein9ff8c8c2018-02-07 01:58:51 +00005450Elements of paint: Path_Effect, Mask_Filter, Shader, Color_Filter,
Cary Clark8032b982017-07-28 11:04:54 -04005451Image_Filter, and Draw_Looper; apply to blob.
5452
Cary Clarkce101242017-09-01 15:51:02 -04005453#Param blob Glyphs, positions, and their paints' text size, typeface, and so on ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005454#Param x horizontal offset applied to blob ##
5455#Param y vertical offset applied to blob ##
5456#Param paint blend, color, stroking, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005457
5458#Example
5459#Height 120
5460#Description
5461Paint attributes unrelated to text, like color, have no effect on paint in allocated Text_Blob.
5462Paint attributes related to text, like text size, have no effect on paint passed to drawTextBlob.
5463##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005464 void draw(SkCanvas* canvas) {
5465 SkTextBlobBuilder textBlobBuilder;
5466 SkPaint paint;
5467 paint.setTextSize(50);
5468 paint.setColor(SK_ColorRED);
Cary Clark2f466242017-12-11 16:03:17 -05005469 paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
Mike Klein9ff8c8c2018-02-07 01:58:51 +00005470 const SkTextBlobBuilder::RunBuffer& run =
Cary Clarkbad5ad72017-08-03 17:14:08 -04005471 textBlobBuilder.allocRun(paint, 1, 20, 100);
5472 run.glyphs[0] = 20;
5473 sk_sp<const SkTextBlob> blob = textBlobBuilder.make();
5474 paint.setTextSize(10);
5475 paint.setColor(SK_ColorBLUE);
5476 canvas->drawTextBlob(blob.get(), 0, 0, paint);
5477 }
Cary Clark8032b982017-07-28 11:04:54 -04005478##
5479
Cary Clark2ade9972017-11-02 17:49:34 -04005480#SeeAlso drawText drawPosText drawPosTextH
Cary Clark8032b982017-07-28 11:04:54 -04005481
5482##
5483
5484# ------------------------------------------------------------------------------
5485
Mike Klein9ff8c8c2018-02-07 01:58:51 +00005486#Method void drawPicture(const SkPicture* picture)
Cary Clark78de7512018-02-07 07:27:09 -05005487#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05005488#Line # draws Picture using Clip and Matrix ##
Cary Clark8032b982017-07-28 11:04:54 -04005489Draw Picture picture, using Clip and Matrix.
5490Clip and Matrix are unchanged by picture contents, as if
5491save() was called before and restore() was called after drawPicture.
5492
5493Picture records a series of draw commands for later playback.
5494
Cary Clarkbad5ad72017-08-03 17:14:08 -04005495#Param picture recorded drawing commands to play ##
Cary Clark8032b982017-07-28 11:04:54 -04005496
5497#Example
Mike Klein9ff8c8c2018-02-07 01:58:51 +00005498void draw(SkCanvas* canvas) {
Cary Clarkbad5ad72017-08-03 17:14:08 -04005499 SkPictureRecorder recorder;
5500 SkCanvas* recordingCanvas = recorder.beginRecording(50, 50);
5501 for (auto color : { SK_ColorRED, SK_ColorBLUE, 0xff007f00 } ) {
5502 SkPaint paint;
5503 paint.setColor(color);
5504 recordingCanvas->drawRect({10, 10, 30, 40}, paint);
5505 recordingCanvas->translate(10, 10);
5506 recordingCanvas->scale(1.2f, 1.4f);
5507 }
5508 sk_sp<SkPicture> playback = recorder.finishRecordingAsPicture();
Cary Clarkbad5ad72017-08-03 17:14:08 -04005509 canvas->drawPicture(playback);
5510 canvas->scale(2, 2);
5511 canvas->translate(50, 0);
5512 canvas->drawPicture(playback);
Cary Clark8032b982017-07-28 11:04:54 -04005513}
5514##
5515
Cary Clark2ade9972017-11-02 17:49:34 -04005516#SeeAlso drawDrawable SkPicture SkPicture::playback
Cary Clark8032b982017-07-28 11:04:54 -04005517
5518##
5519
5520# ------------------------------------------------------------------------------
5521
Mike Klein9ff8c8c2018-02-07 01:58:51 +00005522#Method void drawPicture(const sk_sp<SkPicture>& picture)
Cary Clark8032b982017-07-28 11:04:54 -04005523
5524Draw Picture picture, using Clip and Matrix.
5525Clip and Matrix are unchanged by picture contents, as if
5526save() was called before and restore() was called after drawPicture.
5527
5528Picture records a series of draw commands for later playback.
5529
Cary Clarkbad5ad72017-08-03 17:14:08 -04005530#Param picture recorded drawing commands to play ##
Cary Clark8032b982017-07-28 11:04:54 -04005531
5532#Example
Mike Klein9ff8c8c2018-02-07 01:58:51 +00005533void draw(SkCanvas* canvas) {
Cary Clarkbad5ad72017-08-03 17:14:08 -04005534 SkPictureRecorder recorder;
5535 SkCanvas* recordingCanvas = recorder.beginRecording(50, 50);
5536 for (auto color : { SK_ColorRED, SK_ColorBLUE, 0xff007f00 } ) {
5537 SkPaint paint;
5538 paint.setColor(color);
5539 recordingCanvas->drawRect({10, 10, 30, 40}, paint);
5540 recordingCanvas->translate(10, 10);
5541 recordingCanvas->scale(1.2f, 1.4f);
5542 }
5543 sk_sp<SkPicture> playback = recorder.finishRecordingAsPicture();
5544 canvas->drawPicture(playback);
5545 canvas->scale(2, 2);
5546 canvas->translate(50, 0);
5547 canvas->drawPicture(playback);
Cary Clark8032b982017-07-28 11:04:54 -04005548}
5549##
5550
Cary Clark2ade9972017-11-02 17:49:34 -04005551#SeeAlso drawDrawable SkPicture SkPicture::playback
Cary Clark8032b982017-07-28 11:04:54 -04005552
5553##
5554
5555# ------------------------------------------------------------------------------
5556
5557#Method void drawPicture(const SkPicture* picture, const SkMatrix* matrix, const SkPaint* paint)
5558
Cary Clarkbad5ad72017-08-03 17:14:08 -04005559Draw Picture picture, using Clip and Matrix; transforming picture with
5560Matrix matrix, if provided; and use Paint paint Color_Alpha, Color_Filter,
5561Image_Filter, and Blend_Mode, if provided.
Cary Clark8032b982017-07-28 11:04:54 -04005562
5563matrix transformation is equivalent to: save(), concat(), drawPicture, restore().
5564paint use is equivalent to: saveLayer, drawPicture, restore().
5565
Cary Clarkbad5ad72017-08-03 17:14:08 -04005566#Param picture recorded drawing commands to play ##
5567#Param matrix Matrix to rotate, scale, translate, and so on; may be nullptr ##
5568#Param paint Paint to apply transparency, filtering, and so on; may be nullptr ##
Cary Clark8032b982017-07-28 11:04:54 -04005569
5570#Example
Mike Klein9ff8c8c2018-02-07 01:58:51 +00005571void draw(SkCanvas* canvas) {
Cary Clarkbad5ad72017-08-03 17:14:08 -04005572 SkPaint paint;
5573 SkPictureRecorder recorder;
5574 SkCanvas* recordingCanvas = recorder.beginRecording(50, 50);
5575 for (auto color : { SK_ColorRED, SK_ColorBLUE, 0xff007f00 } ) {
5576 paint.setColor(color);
5577 recordingCanvas->drawRect({10, 10, 30, 40}, paint);
5578 recordingCanvas->translate(10, 10);
5579 recordingCanvas->scale(1.2f, 1.4f);
5580 }
5581 sk_sp<SkPicture> playback = recorder.finishRecordingAsPicture();
5582 const SkPicture* playbackPtr = playback.get();
5583 SkMatrix matrix;
5584 matrix.reset();
5585 for (auto alpha : { 70, 140, 210 } ) {
5586 paint.setAlpha(alpha);
5587 canvas->drawPicture(playbackPtr, &matrix, &paint);
5588 matrix.preTranslate(70, 70);
5589 }
Cary Clark8032b982017-07-28 11:04:54 -04005590}
5591##
5592
Cary Clark2ade9972017-11-02 17:49:34 -04005593#SeeAlso drawDrawable SkPicture SkPicture::playback
Cary Clark8032b982017-07-28 11:04:54 -04005594
5595##
5596
5597# ------------------------------------------------------------------------------
5598
Mike Klein9ff8c8c2018-02-07 01:58:51 +00005599#Method void drawPicture(const sk_sp<SkPicture>& picture, const SkMatrix* matrix, const SkPaint* paint)
Cary Clark8032b982017-07-28 11:04:54 -04005600
Cary Clarkbad5ad72017-08-03 17:14:08 -04005601Draw Picture picture, using Clip and Matrix; transforming picture with
5602Matrix matrix, if provided; and use Paint paint Color_Alpha, Color_Filter,
5603Image_Filter, and Blend_Mode, if provided.
Cary Clark8032b982017-07-28 11:04:54 -04005604
5605matrix transformation is equivalent to: save(), concat(), drawPicture, restore().
5606paint use is equivalent to: saveLayer, drawPicture, restore().
5607
Cary Clarkbad5ad72017-08-03 17:14:08 -04005608#Param picture recorded drawing commands to play ##
5609#Param matrix Matrix to rotate, scale, translate, and so on; may be nullptr ##
5610#Param paint Paint to apply transparency, filtering, and so on; may be nullptr ##
Cary Clark8032b982017-07-28 11:04:54 -04005611
5612#Example
Mike Klein9ff8c8c2018-02-07 01:58:51 +00005613void draw(SkCanvas* canvas) {
Cary Clarkbad5ad72017-08-03 17:14:08 -04005614 SkPaint paint;
5615 SkPictureRecorder recorder;
5616 SkCanvas* recordingCanvas = recorder.beginRecording(50, 50);
5617 for (auto color : { SK_ColorRED, SK_ColorBLUE, 0xff007f00 } ) {
5618 paint.setColor(color);
5619 recordingCanvas->drawRect({10, 10, 30, 40}, paint);
5620 recordingCanvas->translate(10, 10);
5621 recordingCanvas->scale(1.2f, 1.4f);
5622 }
5623 sk_sp<SkPicture> playback = recorder.finishRecordingAsPicture();
5624 SkMatrix matrix;
5625 matrix.reset();
5626 for (auto alpha : { 70, 140, 210 } ) {
5627 paint.setAlpha(alpha);
5628 canvas->drawPicture(playback, &matrix, &paint);
5629 matrix.preTranslate(70, 70);
5630 }
Cary Clark8032b982017-07-28 11:04:54 -04005631}
5632##
5633
Cary Clark2ade9972017-11-02 17:49:34 -04005634#SeeAlso drawDrawable SkPicture SkPicture::playback
Cary Clark8032b982017-07-28 11:04:54 -04005635
5636##
5637
5638# ------------------------------------------------------------------------------
5639
5640#Method void drawVertices(const SkVertices* vertices, SkBlendMode mode, const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05005641#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05005642#Line # draws Vertices, a triangle mesh ##
Cary Clark8032b982017-07-28 11:04:54 -04005643Draw Vertices vertices, a triangle mesh, using Clip and Matrix.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005644If Vertices_Texs and Vertices_Colors are defined in vertices, and Paint paint
5645contains Shader, Blend_Mode mode combines Vertices_Colors with Shader.
Cary Clark8032b982017-07-28 11:04:54 -04005646
Cary Clarkbad5ad72017-08-03 17:14:08 -04005647#Param vertices triangle mesh to draw ##
5648#Param mode combines Vertices_Colors with Shader, if both are present ##
5649#Param paint specifies the Shader, used as Vertices texture; may be nullptr ##
Cary Clark8032b982017-07-28 11:04:54 -04005650
5651#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04005652void draw(SkCanvas* canvas) {
5653 SkPaint paint;
5654 SkPoint points[] = { { 0, 0 }, { 250, 0 }, { 100, 100 }, { 0, 250 } };
5655 SkColor colors[] = { SK_ColorRED, SK_ColorBLUE, SK_ColorYELLOW, SK_ColorCYAN };
5656 auto vertices = SkVertices::MakeCopy(SkVertices::kTriangleFan_VertexMode,
5657 SK_ARRAY_COUNT(points), points, nullptr, colors);
5658 canvas->drawVertices(vertices.get(), SkBlendMode::kSrc, paint);
5659}
Cary Clark8032b982017-07-28 11:04:54 -04005660##
5661
Cary Clark2ade9972017-11-02 17:49:34 -04005662#SeeAlso drawPatch drawPicture
Cary Clark8032b982017-07-28 11:04:54 -04005663
5664##
5665
5666# ------------------------------------------------------------------------------
5667
5668#Method void drawVertices(const sk_sp<SkVertices>& vertices, SkBlendMode mode, const SkPaint& paint)
5669
5670Draw Vertices vertices, a triangle mesh, using Clip and Matrix.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005671If Vertices_Texs and Vertices_Colors are defined in vertices, and Paint paint
5672contains Shader, Blend_Mode mode combines Vertices_Colors with Shader.
Cary Clark8032b982017-07-28 11:04:54 -04005673
Cary Clarkbad5ad72017-08-03 17:14:08 -04005674#Param vertices triangle mesh to draw ##
5675#Param mode combines Vertices_Colors with Shader, if both are present ##
5676#Param paint specifies the Shader, used as Vertices texture, may be nullptr ##
Cary Clark8032b982017-07-28 11:04:54 -04005677
5678#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04005679void draw(SkCanvas* canvas) {
5680 SkPaint paint;
5681 SkPoint points[] = { { 0, 0 }, { 250, 0 }, { 100, 100 }, { 0, 250 } };
5682 SkPoint texs[] = { { 0, 0 }, { 0, 250 }, { 250, 250 }, { 250, 0 } };
5683 SkColor colors[] = { SK_ColorRED, SK_ColorBLUE, SK_ColorYELLOW, SK_ColorCYAN };
5684 paint.setShader(SkGradientShader::MakeLinear(points, colors, nullptr, 4,
5685 SkShader::kClamp_TileMode));
5686 auto vertices = SkVertices::MakeCopy(SkVertices::kTriangleFan_VertexMode,
5687 SK_ARRAY_COUNT(points), points, texs, colors);
5688 canvas->drawVertices(vertices.get(), SkBlendMode::kDarken, paint);
Cary Clark8032b982017-07-28 11:04:54 -04005689}
5690##
5691
Cary Clark2ade9972017-11-02 17:49:34 -04005692#SeeAlso drawPatch drawPicture
Cary Clark8032b982017-07-28 11:04:54 -04005693
5694##
5695
5696# ------------------------------------------------------------------------------
5697
5698#Method void drawPatch(const SkPoint cubics[12], const SkColor colors[4],
5699 const SkPoint texCoords[4], SkBlendMode mode, const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05005700#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05005701#Line # draws Coons_Patch ##
Cary Clark8032b982017-07-28 11:04:54 -04005702
Mike Klein9ff8c8c2018-02-07 01:58:51 +00005703Draws a Coons_Patch: the interpolation of four cubics with shared corners,
Cary Clark8032b982017-07-28 11:04:54 -04005704associating a color, and optionally a texture coordinate, with each corner.
5705
Cary Clarka560c472017-11-27 10:44:06 -05005706Coons_Patch uses Clip and Matrix, paint Shader, Color_Filter,
Cary Clarkbad5ad72017-08-03 17:14:08 -04005707Color_Alpha, Image_Filter, and Blend_Mode. If Shader is provided it is treated
Cary Clarka560c472017-11-27 10:44:06 -05005708as Coons_Patch texture; Blend_Mode mode combines Color colors and Shader if
Cary Clarkbad5ad72017-08-03 17:14:08 -04005709both are provided.
Cary Clark8032b982017-07-28 11:04:54 -04005710
Mike Klein9ff8c8c2018-02-07 01:58:51 +00005711Point array cubics specifies four Cubics starting at the top-left corner,
Cary Clarkce101242017-09-01 15:51:02 -04005712in clockwise order, sharing every fourth point. The last Cubic ends at the
Cary Clarkbad5ad72017-08-03 17:14:08 -04005713first point.
Cary Clark8032b982017-07-28 11:04:54 -04005714
Cary Clarkbc5697d2017-10-04 14:31:33 -04005715Color array color associates colors with corners in top-left, top-right,
5716bottom-right, bottom-left order.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005717
5718If paint contains Shader, Point array texCoords maps Shader as texture to
Cary Clarkbc5697d2017-10-04 14:31:33 -04005719corners in top-left, top-right, bottom-right, bottom-left order.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005720
Cary Clarka523d2d2017-08-30 08:58:10 -04005721#Param cubics Path_Cubic array, sharing common points ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005722#Param colors Color array, one for each corner ##
Cary Clarkce101242017-09-01 15:51:02 -04005723#Param texCoords Point array of texture coordinates, mapping Shader to corners;
Mike Klein9ff8c8c2018-02-07 01:58:51 +00005724 may be nullptr
Cary Clark579985c2017-07-31 11:48:27 -04005725#Param ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005726#Param mode Blend_Mode for colors, and for Shader if paint has one ##
5727#Param paint Shader, Color_Filter, Blend_Mode, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005728
5729#Example
5730#Image 5
Cary Clarkbad5ad72017-08-03 17:14:08 -04005731void draw(SkCanvas* canvas) {
5732 // SkBitmap source = cmbkygk;
5733 SkPaint paint;
5734 paint.setFilterQuality(kLow_SkFilterQuality);
5735 paint.setAntiAlias(true);
5736 SkPoint cubics[] = { { 3, 1 }, { 4, 2 }, { 5, 1 }, { 7, 3 },
5737 /* { 7, 3 }, */ { 6, 4 }, { 7, 5 }, { 5, 7 },
5738 /* { 5, 7 }, */ { 4, 6 }, { 3, 7 }, { 1, 5 },
5739 /* { 1, 5 }, */ { 2, 4 }, { 1, 3 }, /* { 3, 1 } */ };
5740 SkColor colors[] = { 0xbfff0000, 0xbf0000ff, 0xbfff00ff, 0xbf00ffff };
5741 SkPoint texCoords[] = { { -30, -30 }, { 162, -30}, { 162, 162}, { -30, 162} };
5742 paint.setShader(SkShader::MakeBitmapShader(source, SkShader::kClamp_TileMode,
5743 SkShader::kClamp_TileMode, nullptr));
5744 canvas->scale(15, 15);
5745 for (auto blend : { SkBlendMode::kSrcOver, SkBlendMode::kModulate, SkBlendMode::kXor } ) {
5746 canvas->drawPatch(cubics, colors, texCoords, blend, paint);
5747 canvas->translate(4, 4);
5748 }
Cary Clark8032b982017-07-28 11:04:54 -04005749}
5750##
5751
Cary Clark2ade9972017-11-02 17:49:34 -04005752#ToDo can patch use image filter? ##
5753#SeeAlso SeeAlso drawVertices drawPicture
Cary Clark8032b982017-07-28 11:04:54 -04005754
5755##
5756
5757# ------------------------------------------------------------------------------
5758
5759#Method void drawPatch(const SkPoint cubics[12], const SkColor colors[4],
Mike Klein9ff8c8c2018-02-07 01:58:51 +00005760 const SkPoint texCoords[4], const SkPaint& paint)
Cary Clark8032b982017-07-28 11:04:54 -04005761
Mike Klein9ff8c8c2018-02-07 01:58:51 +00005762Draws Cubic Coons_Patch: the interpolation of four cubics with shared corners,
Cary Clarkbad5ad72017-08-03 17:14:08 -04005763associating a color, and optionally a texture coordinate, with each corner.
Cary Clark8032b982017-07-28 11:04:54 -04005764
Cary Clarka560c472017-11-27 10:44:06 -05005765Coons_Patch uses Clip and Matrix, paint Shader, Color_Filter,
Cary Clarkbad5ad72017-08-03 17:14:08 -04005766Color_Alpha, Image_Filter, and Blend_Mode. If Shader is provided it is treated
Cary Clarka560c472017-11-27 10:44:06 -05005767as Coons_Patch texture; Blend_Mode mode combines Color colors and Shader if
Cary Clarkbad5ad72017-08-03 17:14:08 -04005768both are provided.
Cary Clark8032b982017-07-28 11:04:54 -04005769
Mike Klein9ff8c8c2018-02-07 01:58:51 +00005770Point array cubics specifies four Cubics starting at the top-left corner,
Cary Clarkce101242017-09-01 15:51:02 -04005771in clockwise order, sharing every fourth point. The last Cubic ends at the
Cary Clarkbad5ad72017-08-03 17:14:08 -04005772first point.
5773
Cary Clarkbc5697d2017-10-04 14:31:33 -04005774Color array color associates colors with corners in top-left, top-right,
5775bottom-right, bottom-left order.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005776
5777If paint contains Shader, Point array texCoords maps Shader as texture to
Cary Clarkbc5697d2017-10-04 14:31:33 -04005778corners in top-left, top-right, bottom-right, bottom-left order.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005779
Cary Clarka523d2d2017-08-30 08:58:10 -04005780#Param cubics Path_Cubic array, sharing common points ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005781#Param colors Color array, one for each corner ##
Cary Clarkce101242017-09-01 15:51:02 -04005782#Param texCoords Point array of texture coordinates, mapping Shader to corners;
Mike Klein9ff8c8c2018-02-07 01:58:51 +00005783 may be nullptr
Cary Clark579985c2017-07-31 11:48:27 -04005784#Param ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005785#Param paint Shader, Color_Filter, Blend_Mode, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005786
5787#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04005788void draw(SkCanvas* canvas) {
5789 SkPaint paint;
5790 paint.setAntiAlias(true);
5791 SkPoint cubics[] = { { 3, 1 }, { 4, 2 }, { 5, 1 }, { 7, 3 },
5792 /* { 7, 3 }, */ { 6, 4 }, { 7, 5 }, { 5, 7 },
5793 /* { 5, 7 }, */ { 4, 6 }, { 3, 7 }, { 1, 5 },
5794 /* { 1, 5 }, */ { 2, 4 }, { 1, 3 }, /* { 3, 1 } */ };
5795 SkColor colors[] = { SK_ColorRED, SK_ColorBLUE, SK_ColorYELLOW, SK_ColorCYAN };
5796 canvas->scale(30, 30);
5797 canvas->drawPatch(cubics, colors, nullptr, paint);
5798 SkPoint text[] = { {3,0.9f}, {4,2.5f}, {5,0.9f}, {7.5f,3.2f}, {5.5f,4.2f},
5799 {7.5f,5.2f}, {5,7.5f}, {4,5.9f}, {3,7.5f}, {0.5f,5.2f}, {2.5f,4.2f},
5800 {0.5f,3.2f} };
5801 paint.setTextSize(18.f / 30);
5802 paint.setTextAlign(SkPaint::kCenter_Align);
5803 for (int i = 0; i< 10; ++i) {
5804 char digit = '0' + i;
5805 canvas->drawText(&digit, 1, text[i].fX, text[i].fY, paint);
5806 }
5807 canvas->drawString("10", text[10].fX, text[10].fY, paint);
5808 canvas->drawString("11", text[11].fX, text[11].fY, paint);
5809 paint.setStyle(SkPaint::kStroke_Style);
5810 canvas->drawPoints(SkCanvas::kPolygon_PointMode, 12, cubics, paint);
5811 canvas->drawLine(cubics[11].fX, cubics[11].fY, cubics[0].fX, cubics[0].fY, paint);
Cary Clark8032b982017-07-28 11:04:54 -04005812}
5813##
5814
5815#Example
5816#Image 6
Cary Clarkbad5ad72017-08-03 17:14:08 -04005817void draw(SkCanvas* canvas) {
5818 // SkBitmap source = checkerboard;
5819 SkPaint paint;
5820 paint.setFilterQuality(kLow_SkFilterQuality);
5821 paint.setAntiAlias(true);
5822 SkPoint cubics[] = { { 3, 1 }, { 4, 2 }, { 5, 1 }, { 7, 3 },
5823 /* { 7, 3 }, */ { 6, 4 }, { 7, 5 }, { 5, 7 },
5824 /* { 5, 7 }, */ { 4, 6 }, { 3, 7 }, { 1, 5 },
5825 /* { 1, 5 }, */ { 2, 4 }, { 1, 3 }, /* { 3, 1 } */ };
5826 SkPoint texCoords[] = { { 0, 0 }, { 0, 62}, { 62, 62}, { 62, 0 } };
5827 paint.setShader(SkShader::MakeBitmapShader(source, SkShader::kClamp_TileMode,
5828 SkShader::kClamp_TileMode, nullptr));
5829 canvas->scale(30, 30);
5830 canvas->drawPatch(cubics, nullptr, texCoords, paint);
Cary Clark8032b982017-07-28 11:04:54 -04005831}
5832##
5833
Cary Clark2ade9972017-11-02 17:49:34 -04005834#ToDo can patch use image filter? ##
5835#SeeAlso SeeAlso drawVertices drawPicture
Cary Clark8032b982017-07-28 11:04:54 -04005836
5837##
5838
5839# ------------------------------------------------------------------------------
5840
5841#Method void drawAtlas(const SkImage* atlas, const SkRSXform xform[], const SkRect tex[],
5842 const SkColor colors[], int count, SkBlendMode mode, const SkRect* cullRect,
5843 const SkPaint* paint)
Cary Clark78de7512018-02-07 07:27:09 -05005844#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05005845#Line # draws sprites using Clip, Matrix, and Paint ##
Cary Clark8032b982017-07-28 11:04:54 -04005846
5847Draw a set of sprites from atlas, using Clip, Matrix, and optional Paint paint.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005848paint uses Anti-alias, Color_Alpha, Color_Filter, Image_Filter, and Blend_Mode
5849to draw, if present. For each entry in the array, Rect tex locates sprite in
5850atlas, and RSXform xform transforms it into destination space.
5851
Cary Clark8032b982017-07-28 11:04:54 -04005852xform, text, and colors if present, must contain count entries.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005853Optional colors are applied for each sprite using Blend_Mode.
Mike Klein9ff8c8c2018-02-07 01:58:51 +00005854Optional cullRect is a conservative bounds of all transformed sprites.
Cary Clarkce101242017-09-01 15:51:02 -04005855If cullRect is outside of Clip, canvas can skip drawing.
Cary Clark8032b982017-07-28 11:04:54 -04005856
Cary Clarkbad5ad72017-08-03 17:14:08 -04005857#Param atlas Image containing sprites ##
5858#Param xform RSXform mappings for sprites in atlas ##
5859#Param tex Rect locations of sprites in atlas ##
Cary Clark6fc50412017-09-21 12:31:06 -04005860#Param colors one per sprite, blended with sprite using Blend_Mode; may be nullptr ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005861#Param count number of sprites to draw ##
5862#Param mode Blend_Mode combining colors and sprites ##
Cary Clark6fc50412017-09-21 12:31:06 -04005863#Param cullRect bounds of transformed sprites for efficient clipping; may be nullptr ##
5864#Param paint Color_Filter, Image_Filter, Blend_Mode, and so on; may be nullptr ##
Cary Clark8032b982017-07-28 11:04:54 -04005865
5866#Example
5867#Image 3
Cary Clarkbad5ad72017-08-03 17:14:08 -04005868void draw(SkCanvas* canvas) {
5869 // SkBitmap source = mandrill;
5870 SkRSXform xforms[] = { { .5f, 0, 0, 0 }, {0, .5f, 200, 100 } };
5871 SkRect tex[] = { { 0, 0, 250, 250 }, { 0, 0, 250, 250 } };
5872 SkColor colors[] = { 0x7f55aa00, 0x7f3333bf };
5873 const SkImage* imagePtr = image.get();
5874 canvas->drawAtlas(imagePtr, xforms, tex, colors, 2, SkBlendMode::kSrcOver, nullptr, nullptr);
Cary Clark8032b982017-07-28 11:04:54 -04005875}
5876##
5877
Cary Clark2ade9972017-11-02 17:49:34 -04005878#SeeAlso drawBitmap drawImage
Cary Clark8032b982017-07-28 11:04:54 -04005879
5880##
5881
5882# ------------------------------------------------------------------------------
5883
5884#Method void drawAtlas(const sk_sp<SkImage>& atlas, const SkRSXform xform[], const SkRect tex[],
5885 const SkColor colors[], int count, SkBlendMode mode, const SkRect* cullRect,
Mike Klein9ff8c8c2018-02-07 01:58:51 +00005886 const SkPaint* paint)
Cary Clark8032b982017-07-28 11:04:54 -04005887
5888Draw a set of sprites from atlas, using Clip, Matrix, and optional Paint paint.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005889paint uses Anti-alias, Color_Alpha, Color_Filter, Image_Filter, and Blend_Mode
5890to draw, if present. For each entry in the array, Rect tex locates sprite in
5891atlas, and RSXform xform transforms it into destination space.
5892
Cary Clark8032b982017-07-28 11:04:54 -04005893xform, text, and colors if present, must contain count entries.
5894Optional colors is applied for each sprite using Blend_Mode.
Mike Klein9ff8c8c2018-02-07 01:58:51 +00005895Optional cullRect is a conservative bounds of all transformed sprites.
Cary Clarkce101242017-09-01 15:51:02 -04005896If cullRect is outside of Clip, canvas can skip drawing.
Cary Clark8032b982017-07-28 11:04:54 -04005897
Cary Clarkbad5ad72017-08-03 17:14:08 -04005898#Param atlas Image containing sprites ##
5899#Param xform RSXform mappings for sprites in atlas ##
5900#Param tex Rect locations of sprites in atlas ##
Cary Clark6fc50412017-09-21 12:31:06 -04005901#Param colors one per sprite, blended with sprite using Blend_Mode; may be nullptr ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005902#Param count number of sprites to draw ##
5903#Param mode Blend_Mode combining colors and sprites ##
Cary Clark6fc50412017-09-21 12:31:06 -04005904#Param cullRect bounds of transformed sprites for efficient clipping; may be nullptr ##
5905#Param paint Color_Filter, Image_Filter, Blend_Mode, and so on; may be nullptr ##
Cary Clark8032b982017-07-28 11:04:54 -04005906
5907#Example
5908#Image 3
Cary Clarkbad5ad72017-08-03 17:14:08 -04005909void draw(SkCanvas* canvas) {
5910 // SkBitmap source = mandrill;
5911 SkRSXform xforms[] = { { .5f, 0, 0, 0 }, {0, .5f, 200, 100 } };
5912 SkRect tex[] = { { 0, 0, 250, 250 }, { 0, 0, 250, 250 } };
5913 SkColor colors[] = { 0x7f55aa00, 0x7f3333bf };
5914 SkPaint paint;
5915 paint.setAlpha(127);
5916 canvas->drawAtlas(image, xforms, tex, colors, 2, SkBlendMode::kPlus, nullptr, &paint);
Cary Clark8032b982017-07-28 11:04:54 -04005917}
5918##
5919
5920#ToDo bug in example on cpu side, gpu looks ok ##
5921
Cary Clark2ade9972017-11-02 17:49:34 -04005922#SeeAlso drawBitmap drawImage
5923
Cary Clark8032b982017-07-28 11:04:54 -04005924##
5925
5926# ------------------------------------------------------------------------------
5927
5928#Method void drawAtlas(const SkImage* atlas, const SkRSXform xform[], const SkRect tex[], int count,
Mike Klein9ff8c8c2018-02-07 01:58:51 +00005929 const SkRect* cullRect, const SkPaint* paint)
Cary Clark8032b982017-07-28 11:04:54 -04005930
5931Draw a set of sprites from atlas, using Clip, Matrix, and optional Paint paint.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005932paint uses Anti-alias, Color_Alpha, Color_Filter, Image_Filter, and Blend_Mode
5933to draw, if present. For each entry in the array, Rect tex locates sprite in
5934atlas, and RSXform xform transforms it into destination space.
5935
Cary Clark8032b982017-07-28 11:04:54 -04005936xform and text must contain count entries.
Mike Klein9ff8c8c2018-02-07 01:58:51 +00005937Optional cullRect is a conservative bounds of all transformed sprites.
Cary Clarkce101242017-09-01 15:51:02 -04005938If cullRect is outside of Clip, canvas can skip drawing.
Cary Clark8032b982017-07-28 11:04:54 -04005939
Cary Clarkbad5ad72017-08-03 17:14:08 -04005940#Param atlas Image containing sprites ##
5941#Param xform RSXform mappings for sprites in atlas ##
5942#Param tex Rect locations of sprites in atlas ##
5943#Param count number of sprites to draw ##
Cary Clark6fc50412017-09-21 12:31:06 -04005944#Param cullRect bounds of transformed sprites for efficient clipping; may be nullptr ##
5945#Param paint Color_Filter, Image_Filter, Blend_Mode, and so on; may be nullptr ##
Cary Clark8032b982017-07-28 11:04:54 -04005946
5947#Example
5948#Image 3
Cary Clarkbad5ad72017-08-03 17:14:08 -04005949void draw(SkCanvas* canvas) {
5950 // sk_sp<SkImage> image = mandrill;
5951 SkRSXform xforms[] = { { .5f, 0, 0, 0 }, {0, .5f, 200, 100 } };
5952 SkRect tex[] = { { 0, 0, 250, 250 }, { 0, 0, 250, 250 } };
5953 const SkImage* imagePtr = image.get();
5954 canvas->drawAtlas(imagePtr, xforms, tex, 2, nullptr, nullptr);
Cary Clark8032b982017-07-28 11:04:54 -04005955}
5956##
5957
Cary Clark2ade9972017-11-02 17:49:34 -04005958#SeeAlso drawBitmap drawImage
Cary Clark8032b982017-07-28 11:04:54 -04005959
5960##
5961
5962# ------------------------------------------------------------------------------
5963
5964#Method void drawAtlas(const sk_sp<SkImage>& atlas, const SkRSXform xform[], const SkRect tex[],
Mike Klein9ff8c8c2018-02-07 01:58:51 +00005965 int count, const SkRect* cullRect, const SkPaint* paint)
Cary Clark8032b982017-07-28 11:04:54 -04005966
5967Draw a set of sprites from atlas, using Clip, Matrix, and optional Paint paint.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005968paint uses Anti-alias, Color_Alpha, Color_Filter, Image_Filter, and Blend_Mode
5969to draw, if present. For each entry in the array, Rect tex locates sprite in
5970atlas, and RSXform xform transforms it into destination space.
5971
Cary Clark8032b982017-07-28 11:04:54 -04005972xform and text must contain count entries.
Mike Klein9ff8c8c2018-02-07 01:58:51 +00005973Optional cullRect is a conservative bounds of all transformed sprites.
Cary Clarkce101242017-09-01 15:51:02 -04005974If cullRect is outside of Clip, canvas can skip drawing.
Cary Clark8032b982017-07-28 11:04:54 -04005975
Cary Clarkbad5ad72017-08-03 17:14:08 -04005976#Param atlas Image containing sprites ##
5977#Param xform RSXform mappings for sprites in atlas ##
5978#Param tex Rect locations of sprites in atlas ##
5979#Param count number of sprites to draw ##
Cary Clark6fc50412017-09-21 12:31:06 -04005980#Param cullRect bounds of transformed sprites for efficient clipping; may be nullptr ##
5981#Param paint Color_Filter, Image_Filter, Blend_Mode, and so on; may be nullptr ##
Cary Clark8032b982017-07-28 11:04:54 -04005982
5983#Example
5984#Image 3
Cary Clarkbad5ad72017-08-03 17:14:08 -04005985void draw(SkCanvas* canvas) {
5986 // sk_sp<SkImage> image = mandrill;
5987 SkRSXform xforms[] = { { 1, 0, 0, 0 }, {0, 1, 300, 100 } };
5988 SkRect tex[] = { { 0, 0, 200, 200 }, { 200, 0, 400, 200 } };
5989 canvas->drawAtlas(image, xforms, tex, 2, nullptr, nullptr);
Cary Clark8032b982017-07-28 11:04:54 -04005990}
5991##
5992
Cary Clark2ade9972017-11-02 17:49:34 -04005993#SeeAlso drawBitmap drawImage
Cary Clark8032b982017-07-28 11:04:54 -04005994
5995##
5996
5997# ------------------------------------------------------------------------------
5998
Cary Clark73fa9722017-08-29 17:36:51 -04005999#Method void drawDrawable(SkDrawable* drawable, const SkMatrix* matrix = nullptr)
Cary Clark78de7512018-02-07 07:27:09 -05006000#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05006001#Line # draws Drawable, encapsulated drawing commands ##
Mike Klein9ff8c8c2018-02-07 01:58:51 +00006002Draw Drawable drawable using Clip and Matrix, concatenated with
Cary Clark8032b982017-07-28 11:04:54 -04006003optional matrix.
6004
Mike Klein9ff8c8c2018-02-07 01:58:51 +00006005If Canvas has an asynchronous implementation, as is the case
Cary Clark8032b982017-07-28 11:04:54 -04006006when it is recording into Picture, then drawable will be referenced,
6007so that SkDrawable::draw() can be called when the operation is finalized. To force
6008immediate drawing, call SkDrawable::draw() instead.
6009
Cary Clarkbad5ad72017-08-03 17:14:08 -04006010#Param drawable custom struct encapsulating drawing commands ##
6011#Param matrix transformation applied to drawing; may be nullptr ##
Cary Clark8032b982017-07-28 11:04:54 -04006012
6013#Example
6014#Height 100
6015#Function
Cary Clarkbad5ad72017-08-03 17:14:08 -04006016struct MyDrawable : public SkDrawable {
6017 SkRect onGetBounds() override { return SkRect::MakeWH(50, 100); }
6018
6019 void onDraw(SkCanvas* canvas) override {
6020 SkPath path;
6021 path.conicTo(10, 90, 50, 90, 0.9f);
6022 SkPaint paint;
6023 paint.setColor(SK_ColorBLUE);
6024 canvas->drawRect(path.getBounds(), paint);
6025 paint.setAntiAlias(true);
6026 paint.setColor(SK_ColorWHITE);
6027 canvas->drawPath(path, paint);
6028 }
6029};
6030
6031#Function ##
6032void draw(SkCanvas* canvas) {
6033 sk_sp<SkDrawable> drawable(new MyDrawable);
6034 SkMatrix matrix;
6035 matrix.setTranslate(10, 10);
6036 canvas->drawDrawable(drawable.get(), &matrix);
Cary Clark8032b982017-07-28 11:04:54 -04006037}
6038##
6039
Cary Clark2ade9972017-11-02 17:49:34 -04006040#SeeAlso SkDrawable drawPicture
Cary Clark8032b982017-07-28 11:04:54 -04006041
6042##
6043
6044# ------------------------------------------------------------------------------
6045
6046#Method void drawDrawable(SkDrawable* drawable, SkScalar x, SkScalar y)
6047
6048Draw Drawable drawable using Clip and Matrix, offset by (x, y).
6049
Mike Klein9ff8c8c2018-02-07 01:58:51 +00006050If Canvas has an asynchronous implementation, as is the case
Cary Clark8032b982017-07-28 11:04:54 -04006051when it is recording into Picture, then drawable will be referenced,
6052so that SkDrawable::draw() can be called when the operation is finalized. To force
6053immediate drawing, call SkDrawable::draw() instead.
6054
Cary Clarkbad5ad72017-08-03 17:14:08 -04006055#Param drawable custom struct encapsulating drawing commands ##
6056#Param x offset into Canvas writable pixels in x ##
6057#Param y offset into Canvas writable pixels in y ##
Cary Clark8032b982017-07-28 11:04:54 -04006058
6059#Example
6060#Height 100
6061#Function
Cary Clarkbad5ad72017-08-03 17:14:08 -04006062struct MyDrawable : public SkDrawable {
6063 SkRect onGetBounds() override { return SkRect::MakeWH(50, 100); }
6064
6065 void onDraw(SkCanvas* canvas) override {
6066 SkPath path;
6067 path.conicTo(10, 90, 50, 90, 0.9f);
6068 SkPaint paint;
6069 paint.setColor(SK_ColorBLUE);
6070 canvas->drawRect(path.getBounds(), paint);
6071 paint.setAntiAlias(true);
6072 paint.setColor(SK_ColorWHITE);
6073 canvas->drawPath(path, paint);
6074 }
6075};
6076
6077#Function ##
6078void draw(SkCanvas* canvas) {
6079 sk_sp<SkDrawable> drawable(new MyDrawable);
6080 canvas->drawDrawable(drawable.get(), 10, 10);
Cary Clark8032b982017-07-28 11:04:54 -04006081}
6082##
6083
Cary Clark2ade9972017-11-02 17:49:34 -04006084#SeeAlso SkDrawable drawPicture
Cary Clark8032b982017-07-28 11:04:54 -04006085
6086##
6087
6088# ------------------------------------------------------------------------------
6089
6090#Method void drawAnnotation(const SkRect& rect, const char key[], SkData* value)
Cary Clark78de7512018-02-07 07:27:09 -05006091#In Draw
6092#In Utility
Cary Clarkab2621d2018-01-30 10:08:57 -05006093#Line # associates a Rect with a key-value pair ##
Cary Clark78de7512018-02-07 07:27:09 -05006094Associate Rect on Canvas with an annotation; a key-value pair, where the key is
Cary Clark8032b982017-07-28 11:04:54 -04006095a null-terminated utf8 string, and optional value is stored as Data.
6096
Mike Klein9ff8c8c2018-02-07 01:58:51 +00006097Only some canvas implementations, such as recording to Picture, or drawing to
Cary Clark8032b982017-07-28 11:04:54 -04006098Document_PDF, use annotations.
6099
Cary Clarkbad5ad72017-08-03 17:14:08 -04006100#Param rect Rect extent of canvas to annotate ##
6101#Param key string used for lookup ##
6102#Param value data holding value stored in annotation ##
Cary Clark8032b982017-07-28 11:04:54 -04006103
6104#Example
6105 #Height 1
6106 const char text[] = "Click this link!";
6107 SkRect bounds;
6108 SkPaint paint;
6109 paint.setTextSize(40);
6110 (void)paint.measureText(text, strlen(text), &bounds);
6111 const char url[] = "https://www.google.com/";
6112 sk_sp<SkData> urlData(SkData::MakeWithCString(url));
6113 canvas->drawAnnotation(bounds, "url_key", urlData.get());
6114##
6115
Cary Clark2ade9972017-11-02 17:49:34 -04006116#SeeAlso SkPicture SkDocument
Cary Clark8032b982017-07-28 11:04:54 -04006117
6118##
6119
6120# ------------------------------------------------------------------------------
6121
Mike Klein9ff8c8c2018-02-07 01:58:51 +00006122#Method void drawAnnotation(const SkRect& rect, const char key[], const sk_sp<SkData>& value)
Cary Clark8032b982017-07-28 11:04:54 -04006123
6124Associate Rect on Canvas when an annotation; a key-value pair, where the key is
6125a null-terminated utf8 string, and optional value is stored as Data.
6126
Mike Klein9ff8c8c2018-02-07 01:58:51 +00006127Only some canvas implementations, such as recording to Picture, or drawing to
Cary Clark8032b982017-07-28 11:04:54 -04006128Document_PDF, use annotations.
6129
Cary Clarkbad5ad72017-08-03 17:14:08 -04006130#Param rect Rect extent of canvas to annotate ##
6131#Param key string used for lookup ##
6132#Param value data holding value stored in annotation ##
Cary Clark8032b982017-07-28 11:04:54 -04006133
6134#Example
6135#Height 1
6136 const char text[] = "Click this link!";
6137 SkRect bounds;
6138 SkPaint paint;
6139 paint.setTextSize(40);
6140 (void)paint.measureText(text, strlen(text), &bounds);
6141 const char url[] = "https://www.google.com/";
6142 sk_sp<SkData> urlData(SkData::MakeWithCString(url));
6143 canvas->drawAnnotation(bounds, "url_key", urlData.get());
6144##
6145
Cary Clark2ade9972017-11-02 17:49:34 -04006146#SeeAlso SkPicture SkDocument
Cary Clark8032b982017-07-28 11:04:54 -04006147
6148##
6149
6150#Method SkDrawFilter* getDrawFilter() const
Cary Clark4855f782018-02-06 09:41:53 -05006151#Deprecated soon
Cary Clark8032b982017-07-28 11:04:54 -04006152##
6153
6154#Method virtual SkDrawFilter* setDrawFilter(SkDrawFilter* filter)
Cary Clark4855f782018-02-06 09:41:53 -05006155#Deprecated soon
Cary Clark8032b982017-07-28 11:04:54 -04006156##
6157
6158# ------------------------------------------------------------------------------
6159
6160#Method virtual bool isClipEmpty() const
Cary Clark78de7512018-02-07 07:27:09 -05006161#In Property
Cary Clarkab2621d2018-01-30 10:08:57 -05006162#Line # returns if Clip is empty ##
Cary Clark8032b982017-07-28 11:04:54 -04006163Returns true if Clip is empty; that is, nothing will draw.
6164
Cary Clarkbad5ad72017-08-03 17:14:08 -04006165May do work when called; it should not be called
Cary Clark8032b982017-07-28 11:04:54 -04006166more often than needed. However, once called, subsequent calls perform no
6167work until Clip changes.
6168
Cary Clarkbad5ad72017-08-03 17:14:08 -04006169#Return true if Clip is empty ##
Cary Clark8032b982017-07-28 11:04:54 -04006170
6171#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04006172 void draw(SkCanvas* canvas) {
6173 SkDebugf("clip is%s empty\n", canvas->isClipEmpty() ? "" : " not");
6174 SkPath path;
6175 canvas->clipPath(path);
6176 SkDebugf("clip is%s empty\n", canvas->isClipEmpty() ? "" : " not");
Cary Clark8032b982017-07-28 11:04:54 -04006177 }
6178 #StdOut
Cary Clarkbad5ad72017-08-03 17:14:08 -04006179 clip is not empty
Cary Clark8032b982017-07-28 11:04:54 -04006180 clip is empty
6181 ##
6182##
6183
Cary Clark2ade9972017-11-02 17:49:34 -04006184#SeeAlso isClipRect getLocalClipBounds getDeviceClipBounds
Cary Clark8032b982017-07-28 11:04:54 -04006185
6186##
6187
6188# ------------------------------------------------------------------------------
6189
6190#Method virtual bool isClipRect() const
Cary Clark78de7512018-02-07 07:27:09 -05006191#In Property
Cary Clarkab2621d2018-01-30 10:08:57 -05006192#Line # returns if Clip is Rect and not empty ##
Cary Clark8032b982017-07-28 11:04:54 -04006193Returns true if Clip is Rect and not empty.
6194Returns false if the clip is empty, or if it is not Rect.
6195
Cary Clarkbad5ad72017-08-03 17:14:08 -04006196#Return true if Clip is Rect and not empty ##
Cary Clark8032b982017-07-28 11:04:54 -04006197
6198#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04006199 void draw(SkCanvas* canvas) {
6200 SkDebugf("clip is%s rect\n", canvas->isClipRect() ? "" : " not");
6201 canvas->clipRect({0, 0, 0, 0});
6202 SkDebugf("clip is%s rect\n", canvas->isClipRect() ? "" : " not");
Cary Clark8032b982017-07-28 11:04:54 -04006203 }
6204 #StdOut
Cary Clarkbad5ad72017-08-03 17:14:08 -04006205 clip is rect
Cary Clark8032b982017-07-28 11:04:54 -04006206 clip is not rect
6207 ##
6208##
6209
Cary Clark2ade9972017-11-02 17:49:34 -04006210#SeeAlso isClipEmpty getLocalClipBounds getDeviceClipBounds
Cary Clark8032b982017-07-28 11:04:54 -04006211
6212##
6213
6214#Class SkCanvas ##
Cary Clark884dd7d2017-10-11 10:37:52 -04006215
Cary Clark8032b982017-07-28 11:04:54 -04006216#Topic Canvas ##