blob: de33770122fd9c174fe63f7636882f88dac0842d [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,
1687 kDontClipToLayer_Legacy_SaveLayerFlag = kDontClipToLayer_PrivateSaveLayerFlag,
1688 };
Cary Clarkce101242017-09-01 15:51:02 -04001689##
1690
1691SaveLayerFlags provides options that may be used in any combination in SaveLayerRec,
1692defining how Layer allocated by saveLayer operates.
1693
Cary Clarkce101242017-09-01 15:51:02 -04001694#Const kPreserveLCDText_SaveLayerFlag 2
1695 Creates Layer for LCD text. Flag is ignored if Layer Paint contains
1696 Image_Filter or Color_Filter.
1697##
1698
1699#Const kInitWithPrevious_SaveLayerFlag 4
1700 Initializes Layer with the contents of the previous Layer.
1701##
1702
1703#Const kDontClipToLayer_Legacy_SaveLayerFlag 0x80000000
Cary Clark4855f782018-02-06 09:41:53 -05001704#Deprecated soon
Cary Clarkce101242017-09-01 15:51:02 -04001705##
1706
1707#Example
1708#Height 160
1709#Description
1710Canvas Layer captures red and blue circles scaled up by four.
Mike Klein9ff8c8c2018-02-07 01:58:51 +00001711scalePaint blends Layer back with transparency.
Cary Clarkce101242017-09-01 15:51:02 -04001712##
1713void draw(SkCanvas* canvas) {
1714 SkPaint redPaint, bluePaint, scalePaint;
1715 redPaint.setColor(SK_ColorRED);
1716 canvas->drawCircle(21, 21, 8, redPaint);
1717 bluePaint.setColor(SK_ColorBLUE);
1718 canvas->drawCircle(31, 21, 8, bluePaint);
1719 SkMatrix matrix;
1720 matrix.setScale(4, 4);
1721 scalePaint.setAlpha(0x40);
1722 scalePaint.setImageFilter(
1723 SkImageFilter::MakeMatrixFilter(matrix, kNone_SkFilterQuality, nullptr));
1724 SkCanvas::SaveLayerRec saveLayerRec(nullptr, &scalePaint,
Mike Klein9ff8c8c2018-02-07 01:58:51 +00001725 SkCanvas::kInitWithPrevious_SaveLayerFlag);
Cary Clarkce101242017-09-01 15:51:02 -04001726 canvas->saveLayer(saveLayerRec);
1727 canvas->restore();
1728}
1729##
1730
Cary Clark2ade9972017-11-02 17:49:34 -04001731#SeeAlso save() restore() saveLayer saveLayerPreserveLCDTextRequests saveLayerAlpha SaveLayerRec
Cary Clarkce101242017-09-01 15:51:02 -04001732
1733#Enum ##
1734
Cary Clarka560c472017-11-27 10:44:06 -05001735#Typedef uint32_t SaveLayerFlags
1736
1737##
1738
Cary Clarkce101242017-09-01 15:51:02 -04001739#Struct SaveLayerRec
Cary Clark08895c42018-02-01 09:37:32 -05001740#Line # contains the state used to create the Layer ##
Cary Clarkce101242017-09-01 15:51:02 -04001741#Code
1742 struct SaveLayerRec {
1743 SaveLayerRec*(...
1744
1745 const SkRect* fBounds;
1746 const SkPaint* fPaint;
1747 const SkImageFilter* fBackdrop;
1748 SaveLayerFlags fSaveLayerFlags;
1749 };
1750##
1751
Mike Klein9ff8c8c2018-02-07 01:58:51 +00001752SaveLayerRec contains the state used to create the Layer.
Cary Clarkce101242017-09-01 15:51:02 -04001753
1754#Member const SkRect* fBounds
1755 fBounds is used as a hint to limit the size of Layer; may be nullptr.
1756 fBounds suggests but does not define Layer size. To clip drawing to
1757 a specific rectangle, use clipRect.
1758##
1759
1760#Member const SkPaint* fPaint
1761 fPaint modifies how Layer overlays the prior Layer; may be nullptr.
1762 Color_Alpha, Blend_Mode, Color_Filter, Draw_Looper, Image_Filter, and
1763 Mask_Filter affect Layer draw.
1764##
1765
1766#Member const SkImageFilter* fBackdrop
1767 fBackdrop applies Image_Filter to the prior Layer when copying to the Layer;
1768 may be nullptr. Use kInitWithPrevious_SaveLayerFlag to copy the
1769 prior Layer without an Image_Filter.
1770##
1771
1772#Member const SkImage* fClipMask
1773 restore() clips Layer by the Color_Alpha channel of fClipMask when
1774 Layer is copied to Device. fClipMask may be nullptr. .
1775##
1776
1777#Member const SkMatrix* fClipMatrix
Mike Klein9ff8c8c2018-02-07 01:58:51 +00001778 fClipMatrix transforms fClipMask before it clips Layer. If
Cary Clarkce101242017-09-01 15:51:02 -04001779 fClipMask describes a translucent gradient, it may be scaled and rotated
1780 without introducing artifacts. fClipMatrix may be nullptr.
1781##
1782
1783#Member SaveLayerFlags fSaveLayerFlags
1784 fSaveLayerFlags are used to create Layer without transparency,
1785 create Layer for LCD text, and to create Layer with the
1786 contents of the previous Layer.
1787##
1788
1789#Example
1790#Height 160
1791#Description
1792Canvas Layer captures a red Anti-aliased circle and a blue Aliased circle scaled
1793up by four. After drawing another red circle without scaling on top, the Layer is
Mike Klein9ff8c8c2018-02-07 01:58:51 +00001794transferred to the main canvas.
Cary Clarkce101242017-09-01 15:51:02 -04001795##
1796void draw(SkCanvas* canvas) {
1797 SkPaint redPaint, bluePaint;
1798 redPaint.setAntiAlias(true);
1799 redPaint.setColor(SK_ColorRED);
1800 canvas->drawCircle(21, 21, 8, redPaint);
1801 bluePaint.setColor(SK_ColorBLUE);
1802 canvas->drawCircle(31, 21, 8, bluePaint);
1803 SkMatrix matrix;
1804 matrix.setScale(4, 4);
1805 auto scaler = SkImageFilter::MakeMatrixFilter(matrix, kNone_SkFilterQuality, nullptr);
Mike Klein9ff8c8c2018-02-07 01:58:51 +00001806 SkCanvas::SaveLayerRec saveLayerRec(nullptr, nullptr, scaler.get(), 0);
Cary Clarkce101242017-09-01 15:51:02 -04001807 canvas->saveLayer(saveLayerRec);
1808 canvas->drawCircle(125, 85, 8, redPaint);
1809 canvas->restore();
1810}
1811##
1812
1813#Method SaveLayerRec()
1814
1815Sets fBounds, fPaint, and fBackdrop to nullptr. Clears fSaveLayerFlags.
1816
1817#Return empty SaveLayerRec ##
1818
1819#Example
1820 SkCanvas::SaveLayerRec rec1;
Mike Kleine083f7c2018-02-07 12:54:27 -05001821 rec1.fSaveLayerFlags = SkCanvas::kPreserveLCDText_SaveLayerFlag;
1822 SkCanvas::SaveLayerRec rec2(nullptr, nullptr, SkCanvas::kPreserveLCDText_SaveLayerFlag);
Cary Clarkce101242017-09-01 15:51:02 -04001823 SkDebugf("rec1 %c= rec2\n", rec1.fBounds == rec2.fBounds
1824 && rec1.fPaint == rec2.fPaint
1825 && rec1.fBackdrop == rec2.fBackdrop
1826 && rec1.fSaveLayerFlags == rec2.fSaveLayerFlags ? '=' : '!');
1827 #StdOut
1828 rec1 == rec2
1829 ##
1830##
1831
Cary Clark2ade9972017-11-02 17:49:34 -04001832#SeeAlso save() restore() saveLayer saveLayerPreserveLCDTextRequests saveLayerAlpha
1833
Cary Clarkce101242017-09-01 15:51:02 -04001834##
1835
1836#Method SaveLayerRec(const SkRect* bounds, const SkPaint* paint, SaveLayerFlags saveLayerFlags = 0)
1837
1838Sets fBounds, fPaint, and fSaveLayerFlags; sets fBackdrop to nullptr.
1839
1840#Param bounds Layer dimensions; may be nullptr ##
1841#Param paint applied to Layer when overlaying prior Layer; may be nullptr ##
1842#Param saveLayerFlags SaveLayerRec options to modify Layer ##
1843
1844#Return SaveLayerRec with empty backdrop ##
1845
1846#Example
1847 SkCanvas::SaveLayerRec rec1;
1848 SkCanvas::SaveLayerRec rec2(nullptr, nullptr);
1849 SkDebugf("rec1 %c= rec2\n", rec1.fBounds == rec2.fBounds
1850 && rec1.fPaint == rec2.fPaint
1851 && rec1.fBackdrop == rec2.fBackdrop
1852 && rec1.fSaveLayerFlags == rec2.fSaveLayerFlags ? '=' : '!');
1853 #StdOut
1854 rec1 == rec2
1855 ##
1856##
1857
Cary Clark2ade9972017-11-02 17:49:34 -04001858#SeeAlso save() restore() saveLayer saveLayerPreserveLCDTextRequests saveLayerAlpha
1859
Cary Clarkce101242017-09-01 15:51:02 -04001860##
1861
1862#Method SaveLayerRec(const SkRect* bounds, const SkPaint* paint, const SkImageFilter* backdrop,
1863 SaveLayerFlags saveLayerFlags)
1864
1865Sets fBounds, fPaint, fBackdrop, and fSaveLayerFlags.
1866
1867#Param bounds Layer dimensions; may be nullptr ##
1868#Param paint applied to Layer when overlaying prior Layer;
1869 may be nullptr
1870##
1871#Param backdrop prior Layer copied with Image_Filter; may be nullptr
1872##
1873#Param saveLayerFlags SaveLayerRec options to modify Layer ##
1874
1875#Return SaveLayerRec fully specified ##
1876
1877#Example
1878 SkCanvas::SaveLayerRec rec1;
1879 SkCanvas::SaveLayerRec rec2(nullptr, nullptr, nullptr, 0);
1880 SkDebugf("rec1 %c= rec2\n", rec1.fBounds == rec2.fBounds
1881 && rec1.fPaint == rec2.fPaint
1882 && rec1.fBackdrop == rec2.fBackdrop
1883 && rec1.fSaveLayerFlags == rec2.fSaveLayerFlags ? '=' : '!');
1884 #StdOut
1885 rec1 == rec2
1886 ##
1887##
1888
Cary Clark2ade9972017-11-02 17:49:34 -04001889#SeeAlso save() restore() saveLayer saveLayerPreserveLCDTextRequests saveLayerAlpha
1890
Cary Clarkce101242017-09-01 15:51:02 -04001891##
1892
1893#Method SaveLayerRec(const SkRect* bounds, const SkPaint* paint, const SkImageFilter* backdrop,
1894 const SkImage* clipMask, const SkMatrix* clipMatrix,
1895 SaveLayerFlags saveLayerFlags)
1896
1897#Experimental
1898Not ready for general use.
1899##
1900
1901Sets fBounds, fPaint, fBackdrop, fClipMask, fClipMatrix, and fSaveLayerFlags.
1902clipMatrix uses Color_Alpha channel of image, transformed by clipMatrix, to clip
1903Layer when drawn to Canvas.
1904
Cary Clark2ade9972017-11-02 17:49:34 -04001905Implementation is not complete; has no effect if Device is GPU-backed.
Cary Clarkce101242017-09-01 15:51:02 -04001906
1907#Param bounds Layer dimensions; may be nullptr ##
1908#Param paint graphics state applied to Layer when overlaying prior
1909 Layer; may be nullptr
1910##
1911#Param backdrop prior Layer copied with Image_Filter;
1912 may be nullptr
1913##
1914#Param clipMask clip applied to Layer; may be nullptr ##
1915#Param clipMatrix matrix applied to clipMask; may be nullptr to use
Mike Klein9ff8c8c2018-02-07 01:58:51 +00001916 identity matrix
Cary Clarkce101242017-09-01 15:51:02 -04001917##
1918#Param saveLayerFlags SaveLayerRec options to modify Layer ##
1919
1920#Return SaveLayerRec fully specified ##
1921
Cary Clark2ade9972017-11-02 17:49:34 -04001922#SeeAlso save() restore() saveLayer saveLayerPreserveLCDTextRequests saveLayerAlpha
Cary Clarkce101242017-09-01 15:51:02 -04001923
1924##
1925
1926#Struct ##
1927
1928#Method int saveLayer(const SaveLayerRec& layerRec)
1929
Cary Clarkab2621d2018-01-30 10:08:57 -05001930#In Layer
Cary Clarkce101242017-09-01 15:51:02 -04001931Saves Matrix, Clip, and Draw_Filter (Draw_Filter deprecated on most platforms),
1932and allocates Bitmap for subsequent drawing.
1933
1934Calling restore() discards changes to Matrix, Clip, and Draw_Filter,
1935and blends Bitmap with Color_Alpha opacity onto the prior Layer.
1936
1937Matrix may be changed by translate(), scale(), rotate(), skew(), concat(),
1938setMatrix, and resetMatrix. Clip may be changed by clipRect, clipRRect,
1939clipPath, clipRegion.
1940
1941SaveLayerRec contains the state used to create the Layer.
1942
1943Call restoreToCount with returned value to restore this and subsequent saves.
1944
1945#Param layerRec Layer state ##
1946
1947#Return depth of save state stack ##
1948
1949#Example
1950#Description
1951The example draws an image, and saves it into a Layer with kInitWithPrevious_SaveLayerFlag.
1952Next it punches a hole in Layer and restore with SkBlendMode::kPlus.
1953Where Layer was cleared, the original image will draw unchanged.
1954Outside of the circle the mandrill is brightened.
1955##
1956 #Image 3
Hal Canaryc465d132017-12-08 10:21:31 -05001957 // sk_sp<SkImage> image = GetResourceAsImage("images/mandrill_256.png");
Cary Clarkce101242017-09-01 15:51:02 -04001958 canvas->drawImage(image, 0, 0, nullptr);
1959 SkCanvas::SaveLayerRec rec;
1960 SkPaint paint;
1961 paint.setBlendMode(SkBlendMode::kPlus);
1962 rec.fSaveLayerFlags = SkCanvas::kInitWithPrevious_SaveLayerFlag;
1963 rec.fPaint = &paint;
1964 canvas->saveLayer(rec);
1965 paint.setBlendMode(SkBlendMode::kClear);
1966 canvas->drawCircle(128, 128, 96, paint);
1967 canvas->restore();
1968##
1969
1970#ToDo above example needs to replace GetResourceAsImage with way to select image in fiddle ##
1971
Cary Clark2ade9972017-11-02 17:49:34 -04001972#SeeAlso save() restore() saveLayer saveLayerPreserveLCDTextRequests saveLayerAlpha
1973
Cary Clarkce101242017-09-01 15:51:02 -04001974##
1975
Cary Clark08895c42018-02-01 09:37:32 -05001976#Subtopic Layer ##
Cary Clarkce101242017-09-01 15:51:02 -04001977
1978# ------------------------------------------------------------------------------
Cary Clark08895c42018-02-01 09:37:32 -05001979#Subtopic Matrix
1980#Line # coordinate transformation ##
Cary Clark8032b982017-07-28 11:04:54 -04001981
1982#Method void translate(SkScalar dx, SkScalar dy)
1983
Cary Clarkab2621d2018-01-30 10:08:57 -05001984#In Matrix
1985#Line # translates Matrix ##
Cary Clark8032b982017-07-28 11:04:54 -04001986Translate Matrix by dx along the x-axis and dy along the y-axis.
1987
1988Mathematically, replace Matrix with a translation matrix
Mike Klein9ff8c8c2018-02-07 01:58:51 +00001989Premultiplied with Matrix.
Cary Clark8032b982017-07-28 11:04:54 -04001990
1991This has the effect of moving the drawing by (dx, dy) before transforming
1992the result with Matrix.
1993
Cary Clarkbad5ad72017-08-03 17:14:08 -04001994#Param dx distance to translate in x ##
1995#Param dy distance to translate in y ##
Cary Clark8032b982017-07-28 11:04:54 -04001996
1997#Example
1998#Height 128
1999#Description
2000scale() followed by translate() produces different results from translate() followed
Mike Klein9ff8c8c2018-02-07 01:58:51 +00002001by scale().
Cary Clark8032b982017-07-28 11:04:54 -04002002
2003The blue stroke follows translate of (50, 50); a black
Mike Klein9ff8c8c2018-02-07 01:58:51 +00002004fill follows scale of (2, 1/2.f). After restoring the clip, which resets
Cary Clark8032b982017-07-28 11:04:54 -04002005Matrix, a red frame follows the same scale of (2, 1/2.f); a gray fill
2006follows translate of (50, 50).
2007##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002008void draw(SkCanvas* canvas) {
2009 SkPaint filledPaint;
2010 SkPaint outlinePaint;
2011 outlinePaint.setStyle(SkPaint::kStroke_Style);
2012 outlinePaint.setColor(SK_ColorBLUE);
2013 canvas->save();
2014 canvas->translate(50, 50);
2015 canvas->drawCircle(28, 28, 15, outlinePaint); // blue center: (50+28, 50+28)
2016 canvas->scale(2, 1/2.f);
2017 canvas->drawCircle(28, 28, 15, filledPaint); // black center: (50+(28*2), 50+(28/2))
2018 canvas->restore();
2019 filledPaint.setColor(SK_ColorGRAY);
2020 outlinePaint.setColor(SK_ColorRED);
2021 canvas->scale(2, 1/2.f);
2022 canvas->drawCircle(28, 28, 15, outlinePaint); // red center: (28*2, 28/2)
2023 canvas->translate(50, 50);
2024 canvas->drawCircle(28, 28, 15, filledPaint); // gray center: ((50+28)*2, (50+28)/2)
Cary Clark8032b982017-07-28 11:04:54 -04002025}
2026##
2027
Cary Clark2ade9972017-11-02 17:49:34 -04002028#SeeAlso concat() scale() skew() rotate() setMatrix
Cary Clark8032b982017-07-28 11:04:54 -04002029
2030##
2031
2032# ------------------------------------------------------------------------------
2033
2034#Method void scale(SkScalar sx, SkScalar sy)
2035
Cary Clarkab2621d2018-01-30 10:08:57 -05002036#In Matrix
2037#Line # scales Matrix ##
Cary Clark8032b982017-07-28 11:04:54 -04002038Scale Matrix by sx on the x-axis and sy on the y-axis.
2039
2040Mathematically, replace Matrix with a scale matrix
Mike Klein9ff8c8c2018-02-07 01:58:51 +00002041Premultiplied with Matrix.
Cary Clark8032b982017-07-28 11:04:54 -04002042
2043This has the effect of scaling the drawing by (sx, sy) before transforming
2044the result with Matrix.
2045
Cary Clarkbad5ad72017-08-03 17:14:08 -04002046#Param sx amount to scale in x ##
2047#Param sy amount to scale in y ##
Cary Clark8032b982017-07-28 11:04:54 -04002048
2049#Example
2050#Height 160
Cary Clarkbad5ad72017-08-03 17:14:08 -04002051void draw(SkCanvas* canvas) {
2052 SkPaint paint;
2053 SkRect rect = { 10, 20, 60, 120 };
2054 canvas->translate(20, 20);
2055 canvas->drawRect(rect, paint);
2056 canvas->scale(2, .5f);
2057 paint.setColor(SK_ColorGRAY);
2058 canvas->drawRect(rect, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002059}
2060##
2061
Cary Clark2ade9972017-11-02 17:49:34 -04002062#SeeAlso concat() translate() skew() rotate() setMatrix
Cary Clark8032b982017-07-28 11:04:54 -04002063
2064##
2065
2066# ------------------------------------------------------------------------------
2067
2068#Method void rotate(SkScalar degrees)
2069
Cary Clarkab2621d2018-01-30 10:08:57 -05002070#In Matrix
2071#Line # rotates Matrix ##
Cary Clark8032b982017-07-28 11:04:54 -04002072Rotate Matrix by degrees. Positive degrees rotates clockwise.
2073
2074Mathematically, replace Matrix with a rotation matrix
Mike Klein9ff8c8c2018-02-07 01:58:51 +00002075Premultiplied with Matrix.
Cary Clark8032b982017-07-28 11:04:54 -04002076
2077This has the effect of rotating the drawing by degrees before transforming
2078the result with Matrix.
2079
Cary Clarkbad5ad72017-08-03 17:14:08 -04002080#Param degrees amount to rotate, in degrees ##
Cary Clark8032b982017-07-28 11:04:54 -04002081
2082#Example
2083#Description
2084Draw clock hands at time 5:10. The hour hand and minute hand point up and
2085are rotated clockwise.
2086##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002087void draw(SkCanvas* canvas) {
2088 SkPaint paint;
2089 paint.setStyle(SkPaint::kStroke_Style);
2090 canvas->translate(128, 128);
2091 canvas->drawCircle(0, 0, 60, paint);
2092 canvas->save();
2093 canvas->rotate(10 * 360 / 60); // 10 minutes of 60 scaled to 360 degrees
Mike Klein9ff8c8c2018-02-07 01:58:51 +00002094 canvas->drawLine(0, 0, 0, -50, paint);
Cary Clarkbad5ad72017-08-03 17:14:08 -04002095 canvas->restore();
2096 canvas->rotate((5 + 10.f/60) * 360 / 12); // 5 and 10/60 hours of 12 scaled to 360 degrees
2097 canvas->drawLine(0, 0, 0, -30, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002098}
2099##
2100
Cary Clark2ade9972017-11-02 17:49:34 -04002101#SeeAlso concat() translate() skew() scale() setMatrix
Cary Clark8032b982017-07-28 11:04:54 -04002102
2103##
2104
2105# ------------------------------------------------------------------------------
2106
2107#Method void rotate(SkScalar degrees, SkScalar px, SkScalar py)
2108
Cary Clarkab2621d2018-01-30 10:08:57 -05002109#In Matrix
Cary Clarkbad5ad72017-08-03 17:14:08 -04002110Rotate Matrix by degrees about a point at (px, py). Positive degrees rotates
2111clockwise.
Cary Clark8032b982017-07-28 11:04:54 -04002112
Cary Clarkce101242017-09-01 15:51:02 -04002113Mathematically, construct a rotation matrix. Premultiply the rotation matrix by
Cary Clark8032b982017-07-28 11:04:54 -04002114a translation matrix, then replace Matrix with the resulting matrix
Mike Klein9ff8c8c2018-02-07 01:58:51 +00002115Premultiplied with Matrix.
Cary Clark8032b982017-07-28 11:04:54 -04002116
Cary Clarkbad5ad72017-08-03 17:14:08 -04002117This has the effect of rotating the drawing about a given point before
2118transforming the result with Matrix.
Cary Clark8032b982017-07-28 11:04:54 -04002119
Cary Clarkbad5ad72017-08-03 17:14:08 -04002120#Param degrees amount to rotate, in degrees ##
2121#Param px x-coordinate of the point to rotate about ##
2122#Param py y-coordinate of the point to rotate about ##
Cary Clark8032b982017-07-28 11:04:54 -04002123
2124#Example
2125#Height 192
Cary Clarkbad5ad72017-08-03 17:14:08 -04002126void draw(SkCanvas* canvas) {
2127 SkPaint paint;
2128 paint.setTextSize(96);
2129 canvas->drawString("A1", 130, 100, paint);
2130 canvas->rotate(180, 130, 100);
2131 canvas->drawString("A1", 130, 100, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002132}
2133##
2134
Cary Clark2ade9972017-11-02 17:49:34 -04002135#SeeAlso concat() translate() skew() scale() setMatrix
Cary Clark8032b982017-07-28 11:04:54 -04002136
2137##
2138
2139# ------------------------------------------------------------------------------
2140
2141#Method void skew(SkScalar sx, SkScalar sy)
2142
Cary Clarkab2621d2018-01-30 10:08:57 -05002143#In Matrix
2144#Line # skews Matrix ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002145Skew Matrix by sx on the x-axis and sy on the y-axis. A positive value of sx
2146skews the drawing right as y increases; a positive value of sy skews the drawing
2147down as x increases.
Cary Clark8032b982017-07-28 11:04:54 -04002148
Mike Klein9ff8c8c2018-02-07 01:58:51 +00002149Mathematically, replace Matrix with a skew matrix Premultiplied with Matrix.
Cary Clark8032b982017-07-28 11:04:54 -04002150
Cary Clarkbad5ad72017-08-03 17:14:08 -04002151This has the effect of skewing the drawing by (sx, sy) before transforming
Cary Clark8032b982017-07-28 11:04:54 -04002152the result with Matrix.
2153
Cary Clarkbad5ad72017-08-03 17:14:08 -04002154#Param sx amount to skew in x ##
2155#Param sy amount to skew in y ##
2156
Cary Clark8032b982017-07-28 11:04:54 -04002157#Example
Mike Klein9ff8c8c2018-02-07 01:58:51 +00002158 #Description
Cary Clark8032b982017-07-28 11:04:54 -04002159 Black text mimics an oblique text style by using a negative skew in x that
2160 shifts the geometry to the right as the y values decrease.
2161 Red text uses a positive skew in y to shift the geometry down as the x values
2162 increase.
2163 Blue text combines x and y skew to rotate and scale.
2164 ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002165 SkPaint paint;
2166 paint.setTextSize(128);
2167 canvas->translate(30, 130);
2168 canvas->save();
2169 canvas->skew(-.5, 0);
2170 canvas->drawString("A1", 0, 0, paint);
2171 canvas->restore();
2172 canvas->save();
2173 canvas->skew(0, .5);
2174 paint.setColor(SK_ColorRED);
2175 canvas->drawString("A1", 0, 0, paint);
2176 canvas->restore();
2177 canvas->skew(-.5, .5);
2178 paint.setColor(SK_ColorBLUE);
Cary Clark8032b982017-07-28 11:04:54 -04002179 canvas->drawString("A1", 0, 0, paint);
2180##
2181
Cary Clark2ade9972017-11-02 17:49:34 -04002182#SeeAlso concat() translate() rotate() scale() setMatrix
Cary Clark8032b982017-07-28 11:04:54 -04002183
2184##
2185
2186# ------------------------------------------------------------------------------
2187
2188#Method void concat(const SkMatrix& matrix)
2189
Cary Clarkab2621d2018-01-30 10:08:57 -05002190#In Matrix
2191#Line # multiplies Matrix by Matrix ##
Cary Clarkce101242017-09-01 15:51:02 -04002192Replace Matrix with matrix Premultiplied with existing Matrix.
Cary Clark8032b982017-07-28 11:04:54 -04002193
Cary Clarkbad5ad72017-08-03 17:14:08 -04002194This has the effect of transforming the drawn geometry by matrix, before
2195transforming the result with existing Matrix.
Cary Clark8032b982017-07-28 11:04:54 -04002196
Cary Clarkce101242017-09-01 15:51:02 -04002197#Param matrix matrix to Premultiply with existing Matrix ##
Cary Clark8032b982017-07-28 11:04:54 -04002198
2199#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04002200void draw(SkCanvas* canvas) {
2201 SkPaint paint;
2202 paint.setTextSize(80);
2203 paint.setTextScaleX(.3);
2204 SkMatrix matrix;
2205 SkRect rect[2] = {{ 10, 20, 90, 110 }, { 40, 130, 140, 180 }};
2206 matrix.setRectToRect(rect[0], rect[1], SkMatrix::kFill_ScaleToFit);
2207 canvas->drawRect(rect[0], paint);
2208 canvas->drawRect(rect[1], paint);
2209 paint.setColor(SK_ColorWHITE);
2210 canvas->drawString("Here", rect[0].fLeft + 10, rect[0].fBottom - 10, paint);
2211 canvas->concat(matrix);
2212 canvas->drawString("There", rect[0].fLeft + 10, rect[0].fBottom - 10, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002213}
2214##
2215
Cary Clark2ade9972017-11-02 17:49:34 -04002216#SeeAlso translate() rotate() scale() skew() setMatrix
Cary Clark8032b982017-07-28 11:04:54 -04002217
2218##
2219
2220# ------------------------------------------------------------------------------
2221
2222#Method void setMatrix(const SkMatrix& matrix)
2223
Cary Clarkab2621d2018-01-30 10:08:57 -05002224#In Matrix
2225#Line # sets Matrix ##
Cary Clark8032b982017-07-28 11:04:54 -04002226Replace Matrix with matrix.
2227Unlike concat(), any prior matrix state is overwritten.
2228
Cary Clarkbad5ad72017-08-03 17:14:08 -04002229#Param matrix matrix to copy, replacing existing Matrix ##
Cary Clark8032b982017-07-28 11:04:54 -04002230
2231#Example
2232#Height 128
Cary Clarkbad5ad72017-08-03 17:14:08 -04002233void draw(SkCanvas* canvas) {
2234 SkPaint paint;
2235 canvas->scale(4, 6);
2236 canvas->drawString("truth", 2, 10, paint);
2237 SkMatrix matrix;
2238 matrix.setScale(2.8f, 6);
2239 canvas->setMatrix(matrix);
2240 canvas->drawString("consequences", 2, 20, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002241}
2242##
2243
Cary Clark2ade9972017-11-02 17:49:34 -04002244#SeeAlso resetMatrix concat() translate() rotate() scale() skew()
Cary Clark8032b982017-07-28 11:04:54 -04002245
2246##
2247
2248# ------------------------------------------------------------------------------
2249
2250#Method void resetMatrix()
2251
Cary Clarkab2621d2018-01-30 10:08:57 -05002252#In Matrix
2253#Line # resets Matrix to identity ##
Cary Clark8032b982017-07-28 11:04:54 -04002254Sets Matrix to the identity matrix.
2255Any prior matrix state is overwritten.
2256
2257#Example
2258#Height 128
Cary Clarkbad5ad72017-08-03 17:14:08 -04002259void draw(SkCanvas* canvas) {
2260 SkPaint paint;
2261 canvas->scale(4, 6);
2262 canvas->drawString("truth", 2, 10, paint);
2263 canvas->resetMatrix();
2264 canvas->scale(2.8f, 6);
2265 canvas->drawString("consequences", 2, 20, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002266}
2267##
2268
Cary Clark2ade9972017-11-02 17:49:34 -04002269#SeeAlso setMatrix concat() translate() rotate() scale() skew()
Cary Clark8032b982017-07-28 11:04:54 -04002270
2271##
2272
2273# ------------------------------------------------------------------------------
2274
2275#Method const SkMatrix& getTotalMatrix() const
2276
Cary Clarkab2621d2018-01-30 10:08:57 -05002277#In Matrix
2278#Line # returns Matrix ##
Cary Clark8032b982017-07-28 11:04:54 -04002279Returns Matrix.
2280This does not account for translation by Device or Surface.
2281
Cary Clarkbad5ad72017-08-03 17:14:08 -04002282#Return Matrix in Canvas ##
Cary Clark8032b982017-07-28 11:04:54 -04002283
2284#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04002285 SkDebugf("isIdentity %s\n", canvas->getTotalMatrix().isIdentity() ? "true" : "false");
2286 #StdOut
2287 isIdentity true
2288 ##
Cary Clark8032b982017-07-28 11:04:54 -04002289##
2290
Cary Clark2ade9972017-11-02 17:49:34 -04002291#SeeAlso setMatrix resetMatrix concat()
Cary Clark8032b982017-07-28 11:04:54 -04002292
2293##
2294
Cary Clark08895c42018-02-01 09:37:32 -05002295#Subtopic Matrix ##
Cary Clark8032b982017-07-28 11:04:54 -04002296
2297# ------------------------------------------------------------------------------
Cary Clark08895c42018-02-01 09:37:32 -05002298#Subtopic Clip
2299#Line # stack of clipping Paths ##
Cary Clark8032b982017-07-28 11:04:54 -04002300
2301Clip is built from a stack of clipping paths. Each Path in the
Mike Klein9ff8c8c2018-02-07 01:58:51 +00002302stack can be constructed from one or more Path_Contour elements. The
Cary Clark8032b982017-07-28 11:04:54 -04002303Path_Contour may be composed of any number of Path_Verb segments. Each
2304Path_Contour forms a closed area; Path_Fill_Type defines the area enclosed
2305by Path_Contour.
2306
2307Clip stack of Path elements successfully restrict the Path area. Each
Mike Klein9ff8c8c2018-02-07 01:58:51 +00002308Path is transformed by Matrix, then intersected with or subtracted from the
Cary Clark8032b982017-07-28 11:04:54 -04002309prior Clip to form the replacement Clip. Use SkClipOp::kDifference
2310to subtract Path from Clip; use SkClipOp::kIntersect to intersect Path
2311with Clip.
2312
Cary Clarkce101242017-09-01 15:51:02 -04002313A clipping Path may be Anti-aliased; if Path, after transformation, is
Cary Clark8032b982017-07-28 11:04:54 -04002314composed of horizontal and vertical lines, clearing Anti-alias allows whole pixels
Cary Clarkce101242017-09-01 15:51:02 -04002315to either be inside or outside the clip. The fastest drawing has a Aliased,
2316rectangular clip.
Cary Clark8032b982017-07-28 11:04:54 -04002317
2318If clipping Path has Anti-alias set, clip may partially clip a pixel, requiring
Mike Klein9ff8c8c2018-02-07 01:58:51 +00002319that drawing blend partially with the destination along the edge. A rotated
Cary Clarkce101242017-09-01 15:51:02 -04002320rectangular Anti-aliased clip looks smoother but draws slower.
Cary Clark8032b982017-07-28 11:04:54 -04002321
2322Clip can combine with Rect and Round_Rect primitives; like
2323Path, these are transformed by Matrix before they are combined with Clip.
2324
2325Clip can combine with Region. Region is assumed to be in Device coordinates
2326and is unaffected by Matrix.
2327
2328#Example
2329#Height 90
2330 #Description
Cary Clarkce101242017-09-01 15:51:02 -04002331 Draw a red circle with an Aliased clip and an Anti-aliased clip.
Cary Clark8032b982017-07-28 11:04:54 -04002332 Use an image filter to zoom into the pixels drawn.
Cary Clarkce101242017-09-01 15:51:02 -04002333 The edge of the Aliased clip fully draws pixels in the red circle.
2334 The edge of the Anti-aliased clip partially draws pixels in the red circle.
Cary Clark8032b982017-07-28 11:04:54 -04002335 ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002336 SkPaint redPaint, scalePaint;
2337 redPaint.setAntiAlias(true);
2338 redPaint.setColor(SK_ColorRED);
2339 canvas->save();
2340 for (bool antialias : { false, true } ) {
2341 canvas->save();
2342 canvas->clipRect(SkRect::MakeWH(19.5f, 11.5f), antialias);
2343 canvas->drawCircle(17, 11, 8, redPaint);
2344 canvas->restore();
2345 canvas->translate(16, 0);
2346 }
2347 canvas->restore();
2348 SkMatrix matrix;
2349 matrix.setScale(6, 6);
2350 scalePaint.setImageFilter(
2351 SkImageFilter::MakeMatrixFilter(matrix, kNone_SkFilterQuality, nullptr));
2352 SkCanvas::SaveLayerRec saveLayerRec(
Mike Klein9ff8c8c2018-02-07 01:58:51 +00002353 nullptr, &scalePaint, SkCanvas::kInitWithPrevious_SaveLayerFlag);
Cary Clarkbad5ad72017-08-03 17:14:08 -04002354 canvas->saveLayer(saveLayerRec);
Cary Clark8032b982017-07-28 11:04:54 -04002355 canvas->restore();
2356##
2357
2358#Method void clipRect(const SkRect& rect, SkClipOp op, bool doAntiAlias)
2359
Cary Clarkab2621d2018-01-30 10:08:57 -05002360#In Clip
2361#Line # combines Clip with Rect ##
Cary Clark8032b982017-07-28 11:04:54 -04002362Replace Clip with the intersection or difference of Clip and rect,
Cary Clarkce101242017-09-01 15:51:02 -04002363with an Aliased or Anti-aliased clip edge. rect is transformed by Matrix
Cary Clark8032b982017-07-28 11:04:54 -04002364before it is combined with Clip.
2365
Cary Clarka523d2d2017-08-30 08:58:10 -04002366#Param rect Rect to combine with Clip ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002367#Param op Clip_Op to apply to Clip ##
Cary Clarkce101242017-09-01 15:51:02 -04002368#Param doAntiAlias true if Clip is to be Anti-aliased ##
Cary Clark8032b982017-07-28 11:04:54 -04002369
2370#Example
2371#Height 128
Cary Clarkbad5ad72017-08-03 17:14:08 -04002372void draw(SkCanvas* canvas) {
2373 canvas->rotate(10);
2374 SkPaint paint;
2375 paint.setAntiAlias(true);
2376 for (auto alias: { false, true } ) {
2377 canvas->save();
2378 canvas->clipRect(SkRect::MakeWH(90, 80), SkClipOp::kIntersect, alias);
2379 canvas->drawCircle(100, 60, 60, paint);
2380 canvas->restore();
2381 canvas->translate(80, 0);
2382 }
Cary Clark8032b982017-07-28 11:04:54 -04002383}
2384##
2385
Cary Clark2ade9972017-11-02 17:49:34 -04002386#SeeAlso clipRRect clipPath clipRegion
Cary Clark8032b982017-07-28 11:04:54 -04002387
2388##
2389
Mike Klein9ff8c8c2018-02-07 01:58:51 +00002390#Method void clipRect(const SkRect& rect, SkClipOp op)
Cary Clark8032b982017-07-28 11:04:54 -04002391
Cary Clarkab2621d2018-01-30 10:08:57 -05002392#In Clip
Cary Clark8032b982017-07-28 11:04:54 -04002393Replace Clip with the intersection or difference of Clip and rect.
Cary Clarkce101242017-09-01 15:51:02 -04002394Resulting Clip is Aliased; pixels are fully contained by the clip.
Cary Clarkbad5ad72017-08-03 17:14:08 -04002395rect is transformed by Matrix before it is combined with Clip.
Cary Clark8032b982017-07-28 11:04:54 -04002396
Cary Clarka523d2d2017-08-30 08:58:10 -04002397#Param rect Rect to combine with Clip ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002398#Param op Clip_Op to apply to Clip ##
Cary Clark8032b982017-07-28 11:04:54 -04002399
2400#Example
2401#Height 192
2402#Width 280
Cary Clarkbad5ad72017-08-03 17:14:08 -04002403void draw(SkCanvas* canvas) {
2404 SkPaint paint;
2405 for (SkClipOp op: { SkClipOp::kIntersect, SkClipOp::kDifference } ) {
2406 canvas->save();
2407 canvas->clipRect(SkRect::MakeWH(90, 120), op, false);
2408 canvas->drawCircle(100, 100, 60, paint);
2409 canvas->restore();
2410 canvas->translate(80, 0);
2411 }
Cary Clark8032b982017-07-28 11:04:54 -04002412}
2413##
2414
Cary Clark2ade9972017-11-02 17:49:34 -04002415#SeeAlso clipRRect clipPath clipRegion
Cary Clark8032b982017-07-28 11:04:54 -04002416
2417##
2418
Mike Klein9ff8c8c2018-02-07 01:58:51 +00002419#Method void clipRect(const SkRect& rect, bool doAntiAlias = false)
Cary Clark8032b982017-07-28 11:04:54 -04002420
Cary Clarkab2621d2018-01-30 10:08:57 -05002421#In Clip
Cary Clark8032b982017-07-28 11:04:54 -04002422Replace Clip with the intersection of Clip and rect.
Cary Clarkce101242017-09-01 15:51:02 -04002423Resulting Clip is Aliased; pixels are fully contained by the clip.
Cary Clark8032b982017-07-28 11:04:54 -04002424rect is transformed by Matrix
2425before it is combined with Clip.
2426
Cary Clarka523d2d2017-08-30 08:58:10 -04002427#Param rect Rect to combine with Clip ##
Cary Clarkce101242017-09-01 15:51:02 -04002428#Param doAntiAlias true if Clip is to be Anti-aliased ##
Cary Clark8032b982017-07-28 11:04:54 -04002429
2430#Example
2431#Height 133
2432 #Description
Cary Clarkce101242017-09-01 15:51:02 -04002433 A circle drawn in pieces looks uniform when drawn Aliased.
2434 The same circle pieces blend with pixels more than once when Anti-aliased,
Cary Clark8032b982017-07-28 11:04:54 -04002435 visible as a thin pair of lines through the right circle.
2436 ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002437void draw(SkCanvas* canvas) {
2438 canvas->clear(SK_ColorWHITE);
2439 SkPaint paint;
2440 paint.setAntiAlias(true);
2441 paint.setColor(0x8055aaff);
2442 SkRect clipRect = { 0, 0, 87.4f, 87.4f };
2443 for (auto alias: { false, true } ) {
2444 canvas->save();
2445 canvas->clipRect(clipRect, SkClipOp::kIntersect, alias);
2446 canvas->drawCircle(67, 67, 60, paint);
2447 canvas->restore();
2448 canvas->save();
2449 canvas->clipRect(clipRect, SkClipOp::kDifference, alias);
2450 canvas->drawCircle(67, 67, 60, paint);
2451 canvas->restore();
2452 canvas->translate(120, 0);
2453 }
Cary Clark8032b982017-07-28 11:04:54 -04002454}
2455##
2456
Cary Clark2ade9972017-11-02 17:49:34 -04002457#SeeAlso clipRRect clipPath clipRegion
Cary Clark8032b982017-07-28 11:04:54 -04002458
2459##
2460
2461#Method void androidFramework_setDeviceClipRestriction(const SkIRect& rect)
2462
Cary Clarkab2621d2018-01-30 10:08:57 -05002463#In Clip
2464#Line # for use by Android framework ##
Cary Clarkce101242017-09-01 15:51:02 -04002465Sets the maximum clip rectangle, which can be set by clipRect, clipRRect and
Cary Clark8032b982017-07-28 11:04:54 -04002466clipPath and intersect the current clip with the specified rect.
Cary Clarkce101242017-09-01 15:51:02 -04002467The maximum clip affects only future clipping operations; it is not retroactive.
Cary Clark8032b982017-07-28 11:04:54 -04002468The clip restriction is not recorded in pictures.
2469
Mike Klein9ff8c8c2018-02-07 01:58:51 +00002470Pass an empty rect to disable maximum clip.
Cary Clarkbad5ad72017-08-03 17:14:08 -04002471
Cary Clark8032b982017-07-28 11:04:54 -04002472#Private
2473This is private API to be used only by Android framework.
2474##
2475
Cary Clarkbad5ad72017-08-03 17:14:08 -04002476#Param rect maximum allowed clip in device coordinates
Cary Clark579985c2017-07-31 11:48:27 -04002477#Param ##
Cary Clark8032b982017-07-28 11:04:54 -04002478
2479##
2480
2481#Method void clipRRect(const SkRRect& rrect, SkClipOp op, bool doAntiAlias)
2482
Cary Clarkab2621d2018-01-30 10:08:57 -05002483#In Clip
2484#Line # combines Clip with Round_Rect ##
Cary Clark8032b982017-07-28 11:04:54 -04002485Replace Clip with the intersection or difference of Clip and rrect,
Cary Clarkce101242017-09-01 15:51:02 -04002486with an Aliased or Anti-aliased clip edge.
Cary Clark8032b982017-07-28 11:04:54 -04002487rrect is transformed by Matrix
2488before it is combined with Clip.
2489
Cary Clarkbad5ad72017-08-03 17:14:08 -04002490#Param rrect Round_Rect to combine with Clip ##
2491#Param op Clip_Op to apply to Clip ##
Cary Clarkce101242017-09-01 15:51:02 -04002492#Param doAntiAlias true if Clip is to be Anti-aliased ##
Cary Clark8032b982017-07-28 11:04:54 -04002493
2494#Example
2495#Height 128
Cary Clarkbad5ad72017-08-03 17:14:08 -04002496void draw(SkCanvas* canvas) {
2497 canvas->clear(SK_ColorWHITE);
2498 SkPaint paint;
2499 paint.setAntiAlias(true);
2500 paint.setColor(0x8055aaff);
2501 SkRRect oval;
2502 oval.setOval({10, 20, 90, 100});
2503 canvas->clipRRect(oval, SkClipOp::kIntersect, true);
2504 canvas->drawCircle(70, 100, 60, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002505}
2506##
2507
Cary Clark2ade9972017-11-02 17:49:34 -04002508#SeeAlso clipRect clipPath clipRegion
Cary Clark8032b982017-07-28 11:04:54 -04002509
2510##
2511
Mike Klein9ff8c8c2018-02-07 01:58:51 +00002512#Method void clipRRect(const SkRRect& rrect, SkClipOp op)
Cary Clark8032b982017-07-28 11:04:54 -04002513
Cary Clarkab2621d2018-01-30 10:08:57 -05002514#In Clip
Cary Clark8032b982017-07-28 11:04:54 -04002515Replace Clip with the intersection or difference of Clip and rrect.
Cary Clarkce101242017-09-01 15:51:02 -04002516Resulting Clip is Aliased; pixels are fully contained by the clip.
Cary Clarkbad5ad72017-08-03 17:14:08 -04002517rrect is transformed by Matrix before it is combined with Clip.
Cary Clark8032b982017-07-28 11:04:54 -04002518
Cary Clarkbad5ad72017-08-03 17:14:08 -04002519#Param rrect Round_Rect to combine with Clip ##
2520#Param op Clip_Op to apply to Clip ##
Cary Clark8032b982017-07-28 11:04:54 -04002521
2522#Example
2523#Height 128
Cary Clarkbad5ad72017-08-03 17:14:08 -04002524void draw(SkCanvas* canvas) {
2525 SkPaint paint;
2526 paint.setColor(0x8055aaff);
2527 auto oval = SkRRect::MakeOval({10, 20, 90, 100});
2528 canvas->clipRRect(oval, SkClipOp::kIntersect);
2529 canvas->drawCircle(70, 100, 60, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002530}
2531##
2532
Cary Clark2ade9972017-11-02 17:49:34 -04002533#SeeAlso clipRect clipPath clipRegion
Cary Clark8032b982017-07-28 11:04:54 -04002534
2535##
2536
Mike Klein9ff8c8c2018-02-07 01:58:51 +00002537#Method void clipRRect(const SkRRect& rrect, bool doAntiAlias = false)
Cary Clark8032b982017-07-28 11:04:54 -04002538
Cary Clarkab2621d2018-01-30 10:08:57 -05002539#In Clip
Cary Clark8032b982017-07-28 11:04:54 -04002540Replace Clip with the intersection of Clip and rrect,
Cary Clarkce101242017-09-01 15:51:02 -04002541with an Aliased or Anti-aliased clip edge.
Cary Clarkbad5ad72017-08-03 17:14:08 -04002542rrect is transformed by Matrix before it is combined with Clip.
Cary Clark8032b982017-07-28 11:04:54 -04002543
Cary Clarkbad5ad72017-08-03 17:14:08 -04002544#Param rrect Round_Rect to combine with Clip ##
Cary Clarkce101242017-09-01 15:51:02 -04002545#Param doAntiAlias true if Clip is to be Anti-aliased ##
Cary Clark8032b982017-07-28 11:04:54 -04002546
2547#Example
2548#Height 128
Cary Clarkbad5ad72017-08-03 17:14:08 -04002549void draw(SkCanvas* canvas) {
2550 SkPaint paint;
2551 paint.setAntiAlias(true);
2552 auto oval = SkRRect::MakeRectXY({10, 20, 90, 100}, 9, 13);
2553 canvas->clipRRect(oval, true);
2554 canvas->drawCircle(70, 100, 60, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002555}
2556##
2557
Cary Clark2ade9972017-11-02 17:49:34 -04002558#SeeAlso clipRect clipPath clipRegion
Cary Clark8032b982017-07-28 11:04:54 -04002559
2560##
2561
2562#Method void clipPath(const SkPath& path, SkClipOp op, bool doAntiAlias)
2563
Cary Clarkab2621d2018-01-30 10:08:57 -05002564#In Clip
2565#Line # combines Clip with Path ##
Cary Clark8032b982017-07-28 11:04:54 -04002566Replace Clip with the intersection or difference of Clip and path,
Cary Clarkce101242017-09-01 15:51:02 -04002567with an Aliased or Anti-aliased clip edge. Path_Fill_Type determines if path
Cary Clark8032b982017-07-28 11:04:54 -04002568describes the area inside or outside its contours; and if Path_Contour overlaps
2569itself or another Path_Contour, whether the overlaps form part of the area.
Cary Clarkbad5ad72017-08-03 17:14:08 -04002570path is transformed by Matrix before it is combined with Clip.
Cary Clark8032b982017-07-28 11:04:54 -04002571
Cary Clarkbad5ad72017-08-03 17:14:08 -04002572#Param path Path to combine with Clip ##
2573#Param op Clip_Op to apply to Clip ##
Cary Clarkce101242017-09-01 15:51:02 -04002574#Param doAntiAlias true if Clip is to be Anti-aliased ##
Cary Clark8032b982017-07-28 11:04:54 -04002575
2576#Example
2577#Description
2578Top figure uses SkPath::kInverseWinding_FillType and SkClipOp::kDifference;
2579area outside clip is subtracted from circle.
2580
2581Bottom figure uses SkPath::kWinding_FillType and SkClipOp::kIntersect;
2582area inside clip is intersected with circle.
2583##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002584void draw(SkCanvas* canvas) {
2585 SkPaint paint;
2586 paint.setAntiAlias(true);
2587 SkPath path;
2588 path.addRect({20, 30, 100, 110});
2589 path.setFillType(SkPath::kInverseWinding_FillType);
2590 canvas->save();
2591 canvas->clipPath(path, SkClipOp::kDifference, false);
2592 canvas->drawCircle(70, 100, 60, paint);
2593 canvas->restore();
2594 canvas->translate(100, 100);
2595 path.setFillType(SkPath::kWinding_FillType);
2596 canvas->clipPath(path, SkClipOp::kIntersect, false);
2597 canvas->drawCircle(70, 100, 60, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002598}
2599##
2600
Cary Clark2ade9972017-11-02 17:49:34 -04002601#SeeAlso clipRect clipRRect clipRegion
Cary Clark8032b982017-07-28 11:04:54 -04002602
2603##
2604
Mike Klein9ff8c8c2018-02-07 01:58:51 +00002605#Method void clipPath(const SkPath& path, SkClipOp op)
Cary Clark8032b982017-07-28 11:04:54 -04002606
Cary Clarkab2621d2018-01-30 10:08:57 -05002607#In Clip
Cary Clark8032b982017-07-28 11:04:54 -04002608Replace Clip with the intersection or difference of Clip and path.
Cary Clarkce101242017-09-01 15:51:02 -04002609Resulting Clip is Aliased; pixels are fully contained by the clip.
Cary Clark8032b982017-07-28 11:04:54 -04002610Path_Fill_Type determines if path
2611describes the area inside or outside its contours; and if Path_Contour overlaps
2612itself or another Path_Contour, whether the overlaps form part of the area.
2613path is transformed by Matrix
2614before it is combined with Clip.
2615
Cary Clarkbad5ad72017-08-03 17:14:08 -04002616#Param path Path to combine with Clip ##
2617#Param op Clip_Op to apply to Clip ##
Cary Clark8032b982017-07-28 11:04:54 -04002618
2619#Example
2620#Description
Cary Clarkbc5697d2017-10-04 14:31:33 -04002621Overlapping Rects form a clip. When clip Path_Fill_Type is set to
Mike Klein9ff8c8c2018-02-07 01:58:51 +00002622SkPath::kWinding_FillType, the overlap is included. Set to
Cary Clark8032b982017-07-28 11:04:54 -04002623SkPath::kEvenOdd_FillType, the overlap is excluded and forms a hole.
2624##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002625void draw(SkCanvas* canvas) {
2626 SkPaint paint;
2627 paint.setAntiAlias(true);
2628 SkPath path;
2629 path.addRect({20, 15, 100, 95});
2630 path.addRect({50, 65, 130, 135});
2631 path.setFillType(SkPath::kWinding_FillType);
2632 canvas->save();
2633 canvas->clipPath(path, SkClipOp::kIntersect);
2634 canvas->drawCircle(70, 85, 60, paint);
2635 canvas->restore();
2636 canvas->translate(100, 100);
2637 path.setFillType(SkPath::kEvenOdd_FillType);
2638 canvas->clipPath(path, SkClipOp::kIntersect);
2639 canvas->drawCircle(70, 85, 60, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002640}
2641##
2642
Cary Clark2ade9972017-11-02 17:49:34 -04002643#SeeAlso clipRect clipRRect clipRegion
Cary Clark8032b982017-07-28 11:04:54 -04002644
2645##
2646
Mike Klein9ff8c8c2018-02-07 01:58:51 +00002647#Method void clipPath(const SkPath& path, bool doAntiAlias = false)
Cary Clark8032b982017-07-28 11:04:54 -04002648
Cary Clarkab2621d2018-01-30 10:08:57 -05002649#In Clip
Cary Clark8032b982017-07-28 11:04:54 -04002650Replace Clip with the intersection of Clip and path.
Cary Clarkce101242017-09-01 15:51:02 -04002651Resulting Clip is Aliased; pixels are fully contained by the clip.
Cary Clark8032b982017-07-28 11:04:54 -04002652Path_Fill_Type determines if path
2653describes the area inside or outside its contours; and if Path_Contour overlaps
2654itself or another Path_Contour, whether the overlaps form part of the area.
Cary Clarkbad5ad72017-08-03 17:14:08 -04002655path is transformed by Matrix before it is combined with Clip.
Cary Clark8032b982017-07-28 11:04:54 -04002656
Cary Clarkbad5ad72017-08-03 17:14:08 -04002657#Param path Path to combine with Clip ##
Cary Clarkce101242017-09-01 15:51:02 -04002658#Param doAntiAlias true if Clip is to be Anti-aliased ##
Cary Clark8032b982017-07-28 11:04:54 -04002659
2660#Example
2661#Height 212
2662#Description
Mike Klein9ff8c8c2018-02-07 01:58:51 +00002663Clip loops over itself covering its center twice. When clip Path_Fill_Type
2664is set to SkPath::kWinding_FillType, the overlap is included. Set to
Cary Clark8032b982017-07-28 11:04:54 -04002665SkPath::kEvenOdd_FillType, the overlap is excluded and forms a hole.
2666##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002667void draw(SkCanvas* canvas) {
2668 SkPaint paint;
2669 paint.setAntiAlias(true);
2670 SkPath path;
2671 SkPoint poly[] = {{20, 20}, { 80, 20}, { 80, 80}, {40, 80},
2672 {40, 40}, {100, 40}, {100, 100}, {20, 100}};
2673 path.addPoly(poly, SK_ARRAY_COUNT(poly), true);
2674 path.setFillType(SkPath::kWinding_FillType);
2675 canvas->save();
2676 canvas->clipPath(path, SkClipOp::kIntersect);
2677 canvas->drawCircle(50, 50, 45, paint);
2678 canvas->restore();
2679 canvas->translate(100, 100);
2680 path.setFillType(SkPath::kEvenOdd_FillType);
2681 canvas->clipPath(path, SkClipOp::kIntersect);
2682 canvas->drawCircle(50, 50, 45, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002683}
2684##
2685
Cary Clark2ade9972017-11-02 17:49:34 -04002686#SeeAlso clipRect clipRRect clipRegion
Cary Clark8032b982017-07-28 11:04:54 -04002687
2688##
2689
2690# ------------------------------------------------------------------------------
2691
Mike Klein9ff8c8c2018-02-07 01:58:51 +00002692#Method void setAllowSimplifyClip(bool allow)
Cary Clark8032b982017-07-28 11:04:54 -04002693
Cary Clarkab2621d2018-01-30 10:08:57 -05002694#In Clip
2695#Line # experimental ##
Cary Clark8032b982017-07-28 11:04:54 -04002696#Experimental
2697Only used for testing.
2698##
2699
Cary Clarkce101242017-09-01 15:51:02 -04002700Set to simplify clip stack using PathOps.
Cary Clark8032b982017-07-28 11:04:54 -04002701
2702##
2703
2704# ------------------------------------------------------------------------------
2705
2706#Method void clipRegion(const SkRegion& deviceRgn, SkClipOp op = SkClipOp::kIntersect)
2707
Cary Clarkab2621d2018-01-30 10:08:57 -05002708#In Clip
2709#Line # combines Clip with Region ##
Cary Clark8032b982017-07-28 11:04:54 -04002710Replace Clip with the intersection or difference of Clip and Region deviceRgn.
Cary Clarkce101242017-09-01 15:51:02 -04002711Resulting Clip is Aliased; pixels are fully contained by the clip.
Cary Clark8032b982017-07-28 11:04:54 -04002712deviceRgn is unaffected by Matrix.
2713
Cary Clarkbad5ad72017-08-03 17:14:08 -04002714#Param deviceRgn Region to combine with Clip ##
2715#Param op Clip_Op to apply to Clip ##
Cary Clark8032b982017-07-28 11:04:54 -04002716
2717#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04002718#Description
Cary Clarkce101242017-09-01 15:51:02 -04002719 region is unaffected by canvas rotation; iRect is affected by canvas rotation.
2720 Both clips are Aliased; this is not noticeable on Region clip because it
Cary Clarkbad5ad72017-08-03 17:14:08 -04002721 aligns to pixel boundaries.
2722##
2723void draw(SkCanvas* canvas) {
2724 SkPaint paint;
2725 paint.setAntiAlias(true);
2726 SkIRect iRect = {30, 40, 120, 130 };
2727 SkRegion region(iRect);
2728 canvas->rotate(10);
2729 canvas->save();
2730 canvas->clipRegion(region, SkClipOp::kIntersect);
2731 canvas->drawCircle(50, 50, 45, paint);
2732 canvas->restore();
2733 canvas->translate(100, 100);
2734 canvas->clipRect(SkRect::Make(iRect), SkClipOp::kIntersect);
2735 canvas->drawCircle(50, 50, 45, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002736}
2737##
2738
Cary Clark2ade9972017-11-02 17:49:34 -04002739#SeeAlso clipRect clipRRect clipPath
Cary Clark8032b982017-07-28 11:04:54 -04002740
2741##
2742
2743#Method bool quickReject(const SkRect& rect) const
2744
Cary Clarkab2621d2018-01-30 10:08:57 -05002745#In Clip
2746#Line # returns if Rect is outside Clip ##
Cary Clark8032b982017-07-28 11:04:54 -04002747Return true if Rect rect, transformed by Matrix, can be quickly determined to be
2748outside of Clip. May return false even though rect is outside of Clip.
2749
2750Use to check if an area to be drawn is clipped out, to skip subsequent draw calls.
2751
Cary Clarkbad5ad72017-08-03 17:14:08 -04002752#Param rect Rect to compare with Clip ##
Cary Clark8032b982017-07-28 11:04:54 -04002753
Cary Clarkbad5ad72017-08-03 17:14:08 -04002754#Return true if rect, transformed by Matrix, does not intersect Clip ##
Cary Clark8032b982017-07-28 11:04:54 -04002755
2756#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04002757void draw(SkCanvas* canvas) {
Mike Klein9ff8c8c2018-02-07 01:58:51 +00002758 SkRect testRect = {30, 30, 120, 129 };
2759 SkRect clipRect = {30, 130, 120, 230 };
Cary Clarkbad5ad72017-08-03 17:14:08 -04002760 canvas->save();
2761 canvas->clipRect(clipRect);
2762 SkDebugf("quickReject %s\n", canvas->quickReject(testRect) ? "true" : "false");
2763 canvas->restore();
2764 canvas->rotate(10);
2765 canvas->clipRect(clipRect);
2766 SkDebugf("quickReject %s\n", canvas->quickReject(testRect) ? "true" : "false");
Cary Clark8032b982017-07-28 11:04:54 -04002767}
2768 #StdOut
Cary Clarkbad5ad72017-08-03 17:14:08 -04002769 quickReject true
Cary Clark8032b982017-07-28 11:04:54 -04002770 quickReject false
2771 ##
2772##
2773
Cary Clark2ade9972017-11-02 17:49:34 -04002774#SeeAlso getLocalClipBounds getTotalMatrix SkBitmap::drawsNothing
Cary Clark8032b982017-07-28 11:04:54 -04002775
2776##
2777
2778#Method bool quickReject(const SkPath& path) const
2779
Cary Clarkab2621d2018-01-30 10:08:57 -05002780#In Clip
Cary Clark8032b982017-07-28 11:04:54 -04002781Return true if path, transformed by Matrix, can be quickly determined to be
2782outside of Clip. May return false even though path is outside of Clip.
2783
2784Use to check if an area to be drawn is clipped out, to skip subsequent draw calls.
2785
Cary Clarkbad5ad72017-08-03 17:14:08 -04002786#Param path Path to compare with Clip ##
Cary Clark8032b982017-07-28 11:04:54 -04002787
Cary Clarkbad5ad72017-08-03 17:14:08 -04002788#Return true if path, transformed by Matrix, does not intersect Clip ##
Cary Clark8032b982017-07-28 11:04:54 -04002789
2790#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04002791void draw(SkCanvas* canvas) {
Mike Klein9ff8c8c2018-02-07 01:58:51 +00002792 SkPoint testPoints[] = {{30, 30}, {120, 30}, {120, 129} };
2793 SkPoint clipPoints[] = {{30, 130}, {120, 130}, {120, 230} };
Cary Clarkbad5ad72017-08-03 17:14:08 -04002794 SkPath testPath, clipPath;
2795 testPath.addPoly(testPoints, SK_ARRAY_COUNT(testPoints), true);
2796 clipPath.addPoly(clipPoints, SK_ARRAY_COUNT(clipPoints), true);
2797 canvas->save();
2798 canvas->clipPath(clipPath);
2799 SkDebugf("quickReject %s\n", canvas->quickReject(testPath) ? "true" : "false");
2800 canvas->restore();
2801 canvas->rotate(10);
2802 canvas->clipPath(clipPath);
2803 SkDebugf("quickReject %s\n", canvas->quickReject(testPath) ? "true" : "false");
Cary Clark8032b982017-07-28 11:04:54 -04002804 #StdOut
Cary Clarkbad5ad72017-08-03 17:14:08 -04002805 quickReject true
Cary Clark8032b982017-07-28 11:04:54 -04002806 quickReject false
2807 ##
2808}
2809##
2810
Cary Clark2ade9972017-11-02 17:49:34 -04002811#SeeAlso getLocalClipBounds getTotalMatrix SkBitmap::drawsNothing
Cary Clark8032b982017-07-28 11:04:54 -04002812
2813##
2814
Mike Klein9ff8c8c2018-02-07 01:58:51 +00002815#Method SkRect getLocalClipBounds() const
Cary Clark8032b982017-07-28 11:04:54 -04002816
Cary Clarkab2621d2018-01-30 10:08:57 -05002817#In Clip
2818#Line # returns Clip bounds in source coordinates ##
Cary Clark8032b982017-07-28 11:04:54 -04002819Return bounds of Clip, transformed by inverse of Matrix. If Clip is empty,
2820return SkRect::MakeEmpty, where all Rect sides equal zero.
2821
2822Rect returned is outset by one to account for partial pixel coverage if Clip
Cary Clarkce101242017-09-01 15:51:02 -04002823is Anti-aliased.
Cary Clark8032b982017-07-28 11:04:54 -04002824
Cary Clarkbad5ad72017-08-03 17:14:08 -04002825#Return bounds of Clip in local coordinates ##
Cary Clark8032b982017-07-28 11:04:54 -04002826
2827#Example
Mike Klein9ff8c8c2018-02-07 01:58:51 +00002828 #Description
Cary Clark8032b982017-07-28 11:04:54 -04002829 Initial bounds is device bounds outset by 1 on all sides.
2830 Clipped bounds is clipPath bounds outset by 1 on all sides.
2831 Scaling the canvas by two in x and y scales the local bounds by 1/2 in x and y.
2832 ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002833 SkCanvas local(256, 256);
2834 canvas = &local;
2835 SkRect bounds = canvas->getLocalClipBounds();
2836 SkDebugf("left:%g top:%g right:%g bottom:%g\n",
2837 bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom);
Mike Klein9ff8c8c2018-02-07 01:58:51 +00002838 SkPoint clipPoints[] = {{30, 130}, {120, 130}, {120, 230} };
Cary Clarkbad5ad72017-08-03 17:14:08 -04002839 SkPath clipPath;
2840 clipPath.addPoly(clipPoints, SK_ARRAY_COUNT(clipPoints), true);
2841 canvas->clipPath(clipPath);
2842 bounds = canvas->getLocalClipBounds();
2843 SkDebugf("left:%g top:%g right:%g bottom:%g\n",
2844 bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom);
2845 canvas->scale(2, 2);
2846 bounds = canvas->getLocalClipBounds();
2847 SkDebugf("left:%g top:%g right:%g bottom:%g\n",
2848 bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom);
2849 #StdOut
2850 left:-1 top:-1 right:257 bottom:257
2851 left:29 top:129 right:121 bottom:231
2852 left:14.5 top:64.5 right:60.5 bottom:115.5
2853 ##
Cary Clark8032b982017-07-28 11:04:54 -04002854##
2855
2856# local canvas in example works around bug in fiddle ##
Cary Clark4855f782018-02-06 09:41:53 -05002857#Bug 6524
Cary Clark2ade9972017-11-02 17:49:34 -04002858#SeeAlso getDeviceClipBounds getBaseLayerSize quickReject
Cary Clark8032b982017-07-28 11:04:54 -04002859
2860##
2861
Mike Klein9ff8c8c2018-02-07 01:58:51 +00002862#Method bool getLocalClipBounds(SkRect* bounds) const
Cary Clark8032b982017-07-28 11:04:54 -04002863
Cary Clarkab2621d2018-01-30 10:08:57 -05002864#In Clip
Cary Clark8032b982017-07-28 11:04:54 -04002865Return bounds of Clip, transformed by inverse of Matrix. If Clip is empty,
2866return false, and set bounds to SkRect::MakeEmpty, where all Rect sides equal zero.
2867
2868bounds is outset by one to account for partial pixel coverage if Clip
Cary Clarkce101242017-09-01 15:51:02 -04002869is Anti-aliased.
Cary Clark8032b982017-07-28 11:04:54 -04002870
Cary Clarkbad5ad72017-08-03 17:14:08 -04002871#Param bounds Rect of Clip in local coordinates ##
Cary Clark8032b982017-07-28 11:04:54 -04002872
Cary Clarkbad5ad72017-08-03 17:14:08 -04002873#Return true if Clip bounds is not empty ##
Cary Clark8032b982017-07-28 11:04:54 -04002874
2875#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04002876 void draw(SkCanvas* canvas) {
2877 SkCanvas local(256, 256);
2878 canvas = &local;
2879 SkRect bounds;
2880 SkDebugf("local bounds empty = %s\n", canvas->getLocalClipBounds(&bounds)
2881 ? "false" : "true");
2882 SkPath path;
2883 canvas->clipPath(path);
2884 SkDebugf("local bounds empty = %s\n", canvas->getLocalClipBounds(&bounds)
2885 ? "false" : "true");
Cary Clark8032b982017-07-28 11:04:54 -04002886 }
2887 #StdOut
Cary Clarkbad5ad72017-08-03 17:14:08 -04002888 local bounds empty = false
Cary Clark8032b982017-07-28 11:04:54 -04002889 local bounds empty = true
2890 ##
2891##
2892
2893# local canvas in example works around bug in fiddle ##
Cary Clark4855f782018-02-06 09:41:53 -05002894#Bug 6524
Cary Clark2ade9972017-11-02 17:49:34 -04002895#SeeAlso getDeviceClipBounds getBaseLayerSize quickReject
Cary Clark8032b982017-07-28 11:04:54 -04002896
2897##
2898
Mike Klein9ff8c8c2018-02-07 01:58:51 +00002899#Method SkIRect getDeviceClipBounds() const
Cary Clark8032b982017-07-28 11:04:54 -04002900
Cary Clarkab2621d2018-01-30 10:08:57 -05002901#In Clip
2902#Line # returns IRect bounds of Clip ##
Cary Clark8032b982017-07-28 11:04:54 -04002903Return IRect bounds of Clip, unaffected by Matrix. If Clip is empty,
2904return SkRect::MakeEmpty, where all Rect sides equal zero.
2905
Mike Klein9ff8c8c2018-02-07 01:58:51 +00002906Unlike getLocalClipBounds, returned IRect is not outset.
Cary Clark8032b982017-07-28 11:04:54 -04002907
Cary Clarkbad5ad72017-08-03 17:14:08 -04002908#Return bounds of Clip in Device coordinates ##
Cary Clark8032b982017-07-28 11:04:54 -04002909
2910#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04002911void draw(SkCanvas* canvas) {
2912 #Description
Cary Clark8032b982017-07-28 11:04:54 -04002913 Initial bounds is device bounds, not outset.
2914 Clipped bounds is clipPath bounds, not outset.
2915 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 -04002916 ##
2917 SkCanvas device(256, 256);
2918 canvas = &device;
2919 SkIRect bounds = canvas->getDeviceClipBounds();
2920 SkDebugf("left:%d top:%d right:%d bottom:%d\n",
2921 bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom);
Mike Klein9ff8c8c2018-02-07 01:58:51 +00002922 SkPoint clipPoints[] = {{30, 130}, {120, 130}, {120, 230} };
Cary Clarkbad5ad72017-08-03 17:14:08 -04002923 SkPath clipPath;
2924 clipPath.addPoly(clipPoints, SK_ARRAY_COUNT(clipPoints), true);
2925 canvas->save();
2926 canvas->clipPath(clipPath);
2927 bounds = canvas->getDeviceClipBounds();
2928 SkDebugf("left:%d top:%d right:%d bottom:%d\n",
2929 bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom);
2930 canvas->restore();
2931 canvas->scale(1.f/2, 1.f/2);
2932 canvas->clipPath(clipPath);
2933 bounds = canvas->getDeviceClipBounds();
2934 SkDebugf("left:%d top:%d right:%d bottom:%d\n",
2935 bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom);
Cary Clark8032b982017-07-28 11:04:54 -04002936 #StdOut
Cary Clarkbad5ad72017-08-03 17:14:08 -04002937 left:0 top:0 right:256 bottom:256
2938 left:30 top:130 right:120 bottom:230
Cary Clark8032b982017-07-28 11:04:54 -04002939 left:15 top:65 right:60 bottom:115
2940 ##
2941}
2942##
2943
2944#ToDo some confusion on why with an identity Matrix local and device are different ##
Cary Clark2ade9972017-11-02 17:49:34 -04002945#SeeAlso getLocalClipBounds getBaseLayerSize quickReject
Cary Clark8032b982017-07-28 11:04:54 -04002946
2947# device canvas in example works around bug in fiddle ##
Cary Clark4855f782018-02-06 09:41:53 -05002948#Bug 6524
Cary Clark8032b982017-07-28 11:04:54 -04002949
2950##
2951
Mike Klein9ff8c8c2018-02-07 01:58:51 +00002952#Method bool getDeviceClipBounds(SkIRect* bounds) const
Cary Clark8032b982017-07-28 11:04:54 -04002953
Cary Clarkab2621d2018-01-30 10:08:57 -05002954#In Clip
Cary Clark8032b982017-07-28 11:04:54 -04002955Return IRect bounds of Clip, unaffected by Matrix. If Clip is empty,
2956return false, and set bounds to SkRect::MakeEmpty, where all Rect sides equal zero.
2957
Mike Klein9ff8c8c2018-02-07 01:58:51 +00002958Unlike getLocalClipBounds, bounds is not outset.
Cary Clark8032b982017-07-28 11:04:54 -04002959
Cary Clarkbad5ad72017-08-03 17:14:08 -04002960#Param bounds Rect of Clip in device coordinates ##
Cary Clark8032b982017-07-28 11:04:54 -04002961
Cary Clarkbad5ad72017-08-03 17:14:08 -04002962#Return true if Clip bounds is not empty ##
Cary Clark8032b982017-07-28 11:04:54 -04002963
2964#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04002965 void draw(SkCanvas* canvas) {
2966 SkIRect bounds;
2967 SkDebugf("device bounds empty = %s\n", canvas->getDeviceClipBounds(&bounds)
2968 ? "false" : "true");
2969 SkPath path;
2970 canvas->clipPath(path);
2971 SkDebugf("device bounds empty = %s\n", canvas->getDeviceClipBounds(&bounds)
2972 ? "false" : "true");
Cary Clark8032b982017-07-28 11:04:54 -04002973 }
2974 #StdOut
Cary Clarkbad5ad72017-08-03 17:14:08 -04002975 device bounds empty = false
Cary Clark8032b982017-07-28 11:04:54 -04002976 device bounds empty = true
2977 ##
2978##
2979
Cary Clark2ade9972017-11-02 17:49:34 -04002980#SeeAlso getLocalClipBounds getBaseLayerSize quickReject
Cary Clark8032b982017-07-28 11:04:54 -04002981
2982##
2983
Cary Clark08895c42018-02-01 09:37:32 -05002984#Subtopic Clip ##
Cary Clark8032b982017-07-28 11:04:54 -04002985
2986# ------------------------------------------------------------------------------
Cary Clark78de7512018-02-07 07:27:09 -05002987#Subtopic Draw
2988#Populate
2989#Line # draws into Canvas ##
2990##
Cary Clark8032b982017-07-28 11:04:54 -04002991
2992#Method void drawColor(SkColor color, SkBlendMode mode = SkBlendMode::kSrcOver)
Cary Clark78de7512018-02-07 07:27:09 -05002993#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05002994#Line # fills Clip with Color and Blend_Mode ##
Cary Clark8032b982017-07-28 11:04:54 -04002995Fill Clip with Color color.
2996mode determines how Color_ARGB is combined with destination.
2997
Cary Clarkbad5ad72017-08-03 17:14:08 -04002998#Param color Unpremultiplied Color_ARGB ##
2999#Param mode SkBlendMode used to combine source color and destination ##
Cary Clark8032b982017-07-28 11:04:54 -04003000
3001#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003002 canvas->drawColor(SK_ColorRED);
3003 canvas->clipRect(SkRect::MakeWH(150, 150));
3004 canvas->drawColor(SkColorSetARGB(0x80, 0x00, 0xFF, 0x00), SkBlendMode::kPlus);
3005 canvas->clipRect(SkRect::MakeWH(75, 75));
3006 canvas->drawColor(SkColorSetARGB(0x80, 0x00, 0x00, 0xFF), SkBlendMode::kPlus);
Cary Clark8032b982017-07-28 11:04:54 -04003007##
3008
Cary Clark2ade9972017-11-02 17:49:34 -04003009#SeeAlso clear SkBitmap::erase drawPaint
Cary Clark8032b982017-07-28 11:04:54 -04003010
3011##
3012
3013# ------------------------------------------------------------------------------
3014
Mike Klein9ff8c8c2018-02-07 01:58:51 +00003015#Method void clear(SkColor color)
Cary Clark78de7512018-02-07 07:27:09 -05003016#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05003017#Line # fills Clip with Color ##
Mike Klein9ff8c8c2018-02-07 01:58:51 +00003018Fill Clip with Color color using SkBlendMode::kSrc.
Cary Clark8032b982017-07-28 11:04:54 -04003019This has the effect of replacing all pixels contained by Clip with color.
3020
Cary Clarkbad5ad72017-08-03 17:14:08 -04003021#Param color Unpremultiplied Color_ARGB ##
Cary Clark8032b982017-07-28 11:04:54 -04003022
3023#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003024void draw(SkCanvas* canvas) {
3025 canvas->save();
3026 canvas->clipRect(SkRect::MakeWH(256, 128));
Mike Klein9ff8c8c2018-02-07 01:58:51 +00003027 canvas->clear(SkColorSetARGB(0x80, 0xFF, 0x00, 0x00));
Cary Clarkbad5ad72017-08-03 17:14:08 -04003028 canvas->restore();
3029 canvas->save();
3030 canvas->clipRect(SkRect::MakeWH(150, 192));
3031 canvas->clear(SkColorSetARGB(0x80, 0x00, 0xFF, 0x00));
3032 canvas->restore();
3033 canvas->clipRect(SkRect::MakeWH(75, 256));
3034 canvas->clear(SkColorSetARGB(0x80, 0x00, 0x00, 0xFF));
Cary Clark8032b982017-07-28 11:04:54 -04003035}
3036##
3037
Cary Clark2ade9972017-11-02 17:49:34 -04003038#SeeAlso drawColor SkBitmap::erase drawPaint
Cary Clark8032b982017-07-28 11:04:54 -04003039
3040##
3041
3042# ------------------------------------------------------------------------------
3043
Mike Klein9ff8c8c2018-02-07 01:58:51 +00003044#Method void discard()
Cary Clark78de7512018-02-07 07:27:09 -05003045#In Utility
Cary Clarkab2621d2018-01-30 10:08:57 -05003046#Line # makes Canvas contents undefined ##
Cary Clark8032b982017-07-28 11:04:54 -04003047Make Canvas contents undefined. Subsequent calls that read Canvas pixels,
3048such as drawing with SkBlendMode, return undefined results. discard() does
3049not change Clip or Matrix.
3050
3051discard() may do nothing, depending on the implementation of Surface or Device
3052that created Canvas.
3053
3054discard() allows optimized performance on subsequent draws by removing
3055cached data associated with Surface or Device.
3056It is not necessary to call discard() once done with Canvas;
3057any cached data is deleted when owning Surface or Device is deleted.
3058
3059#ToDo example? not sure how to make this meaningful w/o more implementation detail ##
Cary Clark2ade9972017-11-02 17:49:34 -04003060#SeeAlso flush() SkSurface::prepareForExternalIO GrContext::abandonContext
Cary Clark8032b982017-07-28 11:04:54 -04003061
Mike Klein9ff8c8c2018-02-07 01:58:51 +00003062#NoExample
Cary Clark8032b982017-07-28 11:04:54 -04003063##
3064
3065##
3066
3067# ------------------------------------------------------------------------------
3068
3069#Method void drawPaint(const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05003070#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05003071#Line # fills Clip with Paint ##
Mike Reed8ad91a92018-01-19 19:09:32 -05003072Fill Clip with Paint paint. Paint components Mask_Filter, Shader,
Cary Clarkbad5ad72017-08-03 17:14:08 -04003073Color_Filter, Image_Filter, and Blend_Mode affect drawing;
3074Path_Effect in paint is ignored.
Cary Clark8032b982017-07-28 11:04:54 -04003075
3076# can Path_Effect in paint ever alter drawPaint?
3077
Cary Clarkbad5ad72017-08-03 17:14:08 -04003078#Param paint graphics state used to fill Canvas ##
Cary Clark8032b982017-07-28 11:04:54 -04003079
3080#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003081void draw(SkCanvas* canvas) {
3082 SkColor colors[] = { SK_ColorRED, SK_ColorGREEN, SK_ColorBLUE };
3083 SkScalar pos[] = { 0, SK_Scalar1/2, SK_Scalar1 };
3084 SkPaint paint;
3085 paint.setShader(SkGradientShader::MakeSweep(256, 256, colors, pos, SK_ARRAY_COUNT(colors)));
3086 canvas->drawPaint(paint);
Cary Clark8032b982017-07-28 11:04:54 -04003087}
3088##
3089
Cary Clark2ade9972017-11-02 17:49:34 -04003090#SeeAlso clear drawColor SkBitmap::erase
Cary Clark8032b982017-07-28 11:04:54 -04003091
3092##
3093
3094# ------------------------------------------------------------------------------
3095
3096#Enum PointMode
Cary Clark08895c42018-02-01 09:37:32 -05003097#Line # sets drawPoints options ##
Cary Clark8032b982017-07-28 11:04:54 -04003098
3099#Code
3100 enum PointMode {
3101 kPoints_PointMode,
3102 kLines_PointMode,
Cary Clarkd0530ba2017-09-14 11:25:39 -04003103 kPolygon_PointMode,
Cary Clark8032b982017-07-28 11:04:54 -04003104 };
3105##
3106
3107Selects if an array of points are drawn as discrete points, as lines, or as
3108an open polygon.
3109
3110#Const kPoints_PointMode 0
3111 Draw each point separately.
3112##
3113
3114#Const kLines_PointMode 1
3115 Draw each pair of points as a line segment.
3116##
3117
3118#Const kPolygon_PointMode 2
3119 Draw the array of points as a open polygon.
3120##
3121
3122#Example
Mike Klein9ff8c8c2018-02-07 01:58:51 +00003123 #Description
Cary Clark8032b982017-07-28 11:04:54 -04003124 The upper left corner shows three squares when drawn as points.
3125 The upper right corner shows one line; when drawn as lines, two points are required per line.
3126 The lower right corner shows two lines; when draw as polygon, no miter is drawn at the corner.
3127 The lower left corner shows two lines with a miter when path contains polygon.
3128 ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003129void draw(SkCanvas* canvas) {
3130 SkPaint paint;
3131 paint.setStyle(SkPaint::kStroke_Style);
3132 paint.setStrokeWidth(10);
3133 SkPoint points[] = {{64, 32}, {96, 96}, {32, 96}};
3134 canvas->drawPoints(SkCanvas::kPoints_PointMode, 3, points, paint);
3135 canvas->translate(128, 0);
3136 canvas->drawPoints(SkCanvas::kLines_PointMode, 3, points, paint);
3137 canvas->translate(0, 128);
3138 canvas->drawPoints(SkCanvas::kPolygon_PointMode, 3, points, paint);
3139 SkPath path;
3140 path.addPoly(points, 3, false);
3141 canvas->translate(-128, 0);
3142 canvas->drawPath(path, paint);
Cary Clark8032b982017-07-28 11:04:54 -04003143}
3144##
3145
Cary Clark2ade9972017-11-02 17:49:34 -04003146#SeeAlso drawLine drawPoint drawPath
Cary Clark8032b982017-07-28 11:04:54 -04003147
3148##
3149
3150# ------------------------------------------------------------------------------
3151
3152#Method void drawPoints(PointMode mode, size_t count, const SkPoint pts[], const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05003153#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05003154#Line # draws array as points, lines, polygon ##
Cary Clark8032b982017-07-28 11:04:54 -04003155Draw pts using Clip, Matrix and Paint paint.
Cary Clarkbad5ad72017-08-03 17:14:08 -04003156count is the number of points; if count is less than one, has no effect.
Cary Clark8032b982017-07-28 11:04:54 -04003157mode may be one of: kPoints_PointMode, kLines_PointMode, or kPolygon_PointMode.
3158
Cary Clarkbad5ad72017-08-03 17:14:08 -04003159If mode is kPoints_PointMode, the shape of point drawn depends on paint
3160Paint_Stroke_Cap. If paint is set to SkPaint::kRound_Cap, each point draws a
3161circle of diameter Paint_Stroke_Width. If paint is set to SkPaint::kSquare_Cap
3162or SkPaint::kButt_Cap, each point draws a square of width and height
3163Paint_Stroke_Width.
Cary Clark8032b982017-07-28 11:04:54 -04003164
3165If mode is kLines_PointMode, each pair of points draws a line segment.
3166One line is drawn for every two points; each point is used once. If count is odd,
Mike Klein9ff8c8c2018-02-07 01:58:51 +00003167the final point is ignored.
Cary Clark8032b982017-07-28 11:04:54 -04003168
3169If mode is kPolygon_PointMode, each adjacent pair of points draws a line segment.
3170count minus one lines are drawn; the first and last point are used once.
3171
3172Each line segment respects paint Paint_Stroke_Cap and Paint_Stroke_Width.
3173Paint_Style is ignored, as if were set to SkPaint::kStroke_Style.
3174
Cary Clarkbad5ad72017-08-03 17:14:08 -04003175Always draws each element one at a time; is not affected by
3176Paint_Stroke_Join, and unlike drawPath, does not create a mask from all points
Mike Klein9ff8c8c2018-02-07 01:58:51 +00003177and lines before drawing.
Cary Clark8032b982017-07-28 11:04:54 -04003178
Cary Clarka523d2d2017-08-30 08:58:10 -04003179#Param mode whether pts draws points or lines ##
3180#Param count number of points in the array ##
3181#Param pts array of points to draw ##
3182#Param paint stroke, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003183
3184#Example
3185#Height 200
Mike Klein9ff8c8c2018-02-07 01:58:51 +00003186 #Description
Cary Clark8032b982017-07-28 11:04:54 -04003187 #List
3188 # The first column draws points. ##
3189 # The second column draws points as lines. ##
3190 # The third column draws points as a polygon. ##
3191 # The fourth column draws points as a polygonal path. ##
3192 # The first row uses a round cap and round join. ##
3193 # The second row uses a square cap and a miter join. ##
3194 # The third row uses a butt cap and a bevel join. ##
3195 ##
3196 The transparent color makes multiple line draws visible;
3197 the path is drawn all at once.
3198 ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003199void draw(SkCanvas* canvas) {
3200 SkPaint paint;
3201 paint.setAntiAlias(true);
3202 paint.setStyle(SkPaint::kStroke_Style);
3203 paint.setStrokeWidth(10);
3204 paint.setColor(0x80349a45);
3205 const SkPoint points[] = {{32, 16}, {48, 48}, {16, 32}};
Mike Klein9ff8c8c2018-02-07 01:58:51 +00003206 const SkPaint::Join join[] = { SkPaint::kRound_Join,
Cary Clarkbad5ad72017-08-03 17:14:08 -04003207 SkPaint::kMiter_Join,
3208 SkPaint::kBevel_Join };
3209 int joinIndex = 0;
3210 SkPath path;
3211 path.addPoly(points, 3, false);
3212 for (const auto cap : { SkPaint::kRound_Cap, SkPaint::kSquare_Cap, SkPaint::kButt_Cap } ) {
3213 paint.setStrokeCap(cap);
3214 paint.setStrokeJoin(join[joinIndex++]);
3215 for (const auto mode : { SkCanvas::kPoints_PointMode,
3216 SkCanvas::kLines_PointMode,
3217 SkCanvas::kPolygon_PointMode } ) {
3218 canvas->drawPoints(mode, 3, points, paint);
3219 canvas->translate(64, 0);
3220 }
3221 canvas->drawPath(path, paint);
3222 canvas->translate(-192, 64);
3223 }
Cary Clark8032b982017-07-28 11:04:54 -04003224}
3225##
3226
Cary Clark2ade9972017-11-02 17:49:34 -04003227#SeeAlso drawLine drawPoint drawPath
Cary Clark8032b982017-07-28 11:04:54 -04003228
3229##
3230
3231# ------------------------------------------------------------------------------
3232
3233#Method void drawPoint(SkScalar x, SkScalar y, const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05003234#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05003235#Line # draws point at (x, y) position ##
Cary Clark8032b982017-07-28 11:04:54 -04003236Draw point at (x, y) using Clip, Matrix and Paint paint.
3237
3238The shape of point drawn depends on paint Paint_Stroke_Cap.
Cary Clarkbad5ad72017-08-03 17:14:08 -04003239If paint is set to SkPaint::kRound_Cap, draw a circle of diameter
Mike Klein9ff8c8c2018-02-07 01:58:51 +00003240Paint_Stroke_Width. If paint is set to SkPaint::kSquare_Cap or SkPaint::kButt_Cap,
Cary Clark8032b982017-07-28 11:04:54 -04003241draw a square of width and height Paint_Stroke_Width.
3242Paint_Style is ignored, as if were set to SkPaint::kStroke_Style.
3243
Cary Clarkbad5ad72017-08-03 17:14:08 -04003244#Param x left edge of circle or square ##
3245#Param y top edge of circle or square ##
3246#Param paint stroke, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003247
3248#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003249void draw(SkCanvas* canvas) {
3250 SkPaint paint;
3251 paint.setAntiAlias(true);
3252 paint.setColor(0x80349a45);
3253 paint.setStyle(SkPaint::kStroke_Style);
3254 paint.setStrokeWidth(100);
3255 paint.setStrokeCap(SkPaint::kRound_Cap);
3256 canvas->scale(1, 1.2f);
3257 canvas->drawPoint(64, 96, paint);
3258 canvas->scale(.6f, .8f);
3259 paint.setColor(SK_ColorWHITE);
3260 canvas->drawPoint(106, 120, paint);
Cary Clark8032b982017-07-28 11:04:54 -04003261}
3262##
3263
Cary Clark2ade9972017-11-02 17:49:34 -04003264#SeeAlso drawPoints drawCircle drawRect drawLine drawPath
Cary Clark8032b982017-07-28 11:04:54 -04003265
3266##
3267
Cary Clarkbad5ad72017-08-03 17:14:08 -04003268#Method void drawPoint(SkPoint p, const SkPaint& paint)
3269
3270Draw point p using Clip, Matrix and Paint paint.
3271
3272The shape of point drawn depends on paint Paint_Stroke_Cap.
3273If paint is set to SkPaint::kRound_Cap, draw a circle of diameter
Mike Klein9ff8c8c2018-02-07 01:58:51 +00003274Paint_Stroke_Width. If paint is set to SkPaint::kSquare_Cap or SkPaint::kButt_Cap,
Cary Clarkbad5ad72017-08-03 17:14:08 -04003275draw a square of width and height Paint_Stroke_Width.
3276Paint_Style is ignored, as if were set to SkPaint::kStroke_Style.
3277
3278#Param p top-left edge of circle or square ##
3279#Param paint stroke, blend, color, and so on, used to draw ##
3280
3281#Example
3282void draw(SkCanvas* canvas) {
3283 SkPaint paint;
3284 paint.setAntiAlias(true);
3285 paint.setColor(0x80349a45);
3286 paint.setStyle(SkPaint::kStroke_Style);
3287 paint.setStrokeWidth(100);
3288 paint.setStrokeCap(SkPaint::kSquare_Cap);
3289 canvas->scale(1, 1.2f);
3290 canvas->drawPoint({64, 96}, paint);
3291 canvas->scale(.6f, .8f);
3292 paint.setColor(SK_ColorWHITE);
3293 canvas->drawPoint(106, 120, paint);
3294}
3295##
3296
Cary Clark2ade9972017-11-02 17:49:34 -04003297#SeeAlso drawPoints drawCircle drawRect drawLine drawPath
Cary Clarkbad5ad72017-08-03 17:14:08 -04003298
3299##
3300
Cary Clark8032b982017-07-28 11:04:54 -04003301# ------------------------------------------------------------------------------
3302
3303#Method void drawLine(SkScalar x0, SkScalar y0, SkScalar x1, SkScalar y1, const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05003304#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05003305#Line # draws line segment between two points ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003306Draws line segment from (x0, y0) to (x1, y1) using Clip, Matrix, and Paint paint.
3307In paint: Paint_Stroke_Width describes the line thickness;
3308Paint_Stroke_Cap draws the end rounded or square;
Cary Clark8032b982017-07-28 11:04:54 -04003309Paint_Style is ignored, as if were set to SkPaint::kStroke_Style.
3310
Cary Clarkbad5ad72017-08-03 17:14:08 -04003311#Param x0 start of line segment on x-axis ##
3312#Param y0 start of line segment on y-axis ##
3313#Param x1 end of line segment on x-axis ##
3314#Param y1 end of line segment on y-axis ##
3315#Param paint stroke, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003316
3317#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003318 SkPaint paint;
3319 paint.setAntiAlias(true);
3320 paint.setColor(0xFF9a67be);
3321 paint.setStrokeWidth(20);
3322 canvas->skew(1, 0);
3323 canvas->drawLine(32, 96, 32, 160, paint);
3324 canvas->skew(-2, 0);
3325 canvas->drawLine(288, 96, 288, 160, paint);
3326##
3327
Cary Clark2ade9972017-11-02 17:49:34 -04003328#SeeAlso drawPoint drawCircle drawRect drawPath
Cary Clarkbad5ad72017-08-03 17:14:08 -04003329
3330##
3331
3332#Method void drawLine(SkPoint p0, SkPoint p1, const SkPaint& paint)
3333
3334Draws line segment from p0 to p1 using Clip, Matrix, and Paint paint.
3335In paint: Paint_Stroke_Width describes the line thickness;
3336Paint_Stroke_Cap draws the end rounded or square;
3337Paint_Style is ignored, as if were set to SkPaint::kStroke_Style.
3338
3339#Param p0 start of line segment ##
3340#Param p1 end of line segment ##
3341#Param paint stroke, blend, color, and so on, used to draw ##
3342
3343#Example
3344 SkPaint paint;
3345 paint.setAntiAlias(true);
3346 paint.setColor(0xFF9a67be);
3347 paint.setStrokeWidth(20);
3348 canvas->skew(1, 0);
3349 canvas->drawLine({32, 96}, {32, 160}, paint);
3350 canvas->skew(-2, 0);
3351 canvas->drawLine({288, 96}, {288, 160}, paint);
Cary Clark8032b982017-07-28 11:04:54 -04003352##
3353
Cary Clark2ade9972017-11-02 17:49:34 -04003354#SeeAlso drawPoint drawCircle drawRect drawPath
Cary Clark8032b982017-07-28 11:04:54 -04003355
3356##
3357
3358# ------------------------------------------------------------------------------
3359
3360#Method void drawRect(const SkRect& rect, const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05003361#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05003362#Line # draws Rect using Clip, Matrix, and Paint ##
Cary Clark8032b982017-07-28 11:04:54 -04003363Draw Rect rect using Clip, Matrix, and Paint paint.
Mike Klein9ff8c8c2018-02-07 01:58:51 +00003364In paint: Paint_Style determines if rectangle is stroked or filled;
Cary Clark8032b982017-07-28 11:04:54 -04003365if stroked, Paint_Stroke_Width describes the line thickness, and
3366Paint_Stroke_Join draws the corners rounded or square.
3367
Cary Clarkbc5697d2017-10-04 14:31:33 -04003368#Param rect rectangle to draw ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003369#Param paint stroke or fill, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003370
3371#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003372void draw(SkCanvas* canvas) {
3373 SkPoint rectPts[] = { {64, 48}, {192, 160} };
3374 SkPaint paint;
3375 paint.setAntiAlias(true);
3376 paint.setStyle(SkPaint::kStroke_Style);
3377 paint.setStrokeWidth(20);
3378 paint.setStrokeJoin(SkPaint::kRound_Join);
3379 SkMatrix rotator;
3380 rotator.setRotate(30, 128, 128);
3381 for (auto color : { SK_ColorRED, SK_ColorBLUE, SK_ColorYELLOW, SK_ColorMAGENTA } ) {
3382 paint.setColor(color);
3383 SkRect rect;
3384 rect.set(rectPts[0], rectPts[1]);
3385 canvas->drawRect(rect, paint);
3386 rotator.mapPoints(rectPts, 2);
3387 }
Cary Clark8032b982017-07-28 11:04:54 -04003388}
3389##
3390
Mike Klein9ff8c8c2018-02-07 01:58:51 +00003391#SeeAlso drawIRect drawRRect drawRoundRect drawRegion drawPath drawLine
Cary Clark8032b982017-07-28 11:04:54 -04003392
3393##
3394
3395# ------------------------------------------------------------------------------
3396
Mike Klein9ff8c8c2018-02-07 01:58:51 +00003397#Method void drawIRect(const SkIRect& rect, const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05003398#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05003399#Line # draws IRect using Clip, Matrix, and Paint ##
Cary Clark8032b982017-07-28 11:04:54 -04003400Draw IRect rect using Clip, Matrix, and Paint paint.
Mike Klein9ff8c8c2018-02-07 01:58:51 +00003401In paint: Paint_Style determines if rectangle is stroked or filled;
Cary Clark8032b982017-07-28 11:04:54 -04003402if stroked, Paint_Stroke_Width describes the line thickness, and
3403Paint_Stroke_Join draws the corners rounded or square.
3404
Cary Clarkbc5697d2017-10-04 14:31:33 -04003405#Param rect rectangle to draw ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003406#Param paint stroke or fill, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003407
3408#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003409 SkIRect rect = { 64, 48, 192, 160 };
3410 SkPaint paint;
3411 paint.setAntiAlias(true);
3412 paint.setStyle(SkPaint::kStroke_Style);
3413 paint.setStrokeWidth(20);
3414 paint.setStrokeJoin(SkPaint::kRound_Join);
3415 for (auto color : { SK_ColorRED, SK_ColorBLUE, SK_ColorYELLOW, SK_ColorMAGENTA } ) {
3416 paint.setColor(color);
3417 canvas->drawIRect(rect, paint);
3418 canvas->rotate(30, 128, 128);
3419 }
Cary Clark8032b982017-07-28 11:04:54 -04003420##
3421
Cary Clark2ade9972017-11-02 17:49:34 -04003422#SeeAlso drawRect drawRRect drawRoundRect drawRegion drawPath drawLine
Cary Clark8032b982017-07-28 11:04:54 -04003423
3424##
3425
3426# ------------------------------------------------------------------------------
3427
3428#Method void drawRegion(const SkRegion& region, const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05003429#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05003430#Line # draws Region using Clip, Matrix, and Paint ##
Cary Clark8032b982017-07-28 11:04:54 -04003431Draw Region region using Clip, Matrix, and Paint paint.
Mike Klein9ff8c8c2018-02-07 01:58:51 +00003432In paint: Paint_Style determines if rectangle is stroked or filled;
Cary Clark8032b982017-07-28 11:04:54 -04003433if stroked, Paint_Stroke_Width describes the line thickness, and
3434Paint_Stroke_Join draws the corners rounded or square.
3435
Cary Clarkbc5697d2017-10-04 14:31:33 -04003436#Param region region to draw ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003437#Param paint Paint stroke or fill, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003438
3439#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003440void draw(SkCanvas* canvas) {
3441 SkRegion region;
3442 region.op( 10, 10, 50, 50, SkRegion::kUnion_Op);
3443 region.op( 10, 50, 90, 90, SkRegion::kUnion_Op);
3444 SkPaint paint;
3445 paint.setAntiAlias(true);
3446 paint.setStyle(SkPaint::kStroke_Style);
3447 paint.setStrokeWidth(20);
3448 paint.setStrokeJoin(SkPaint::kRound_Join);
3449 canvas->drawRegion(region, paint);
Cary Clark8032b982017-07-28 11:04:54 -04003450}
3451##
3452
Cary Clark2ade9972017-11-02 17:49:34 -04003453#SeeAlso drawRect drawIRect drawPath
Cary Clark8032b982017-07-28 11:04:54 -04003454
3455##
3456
3457# ------------------------------------------------------------------------------
3458
3459#Method void drawOval(const SkRect& oval, const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05003460#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05003461#Line # draws Oval using Clip, Matrix, and Paint ##
Cary Clark8032b982017-07-28 11:04:54 -04003462Draw Oval oval using Clip, Matrix, and Paint.
Mike Klein9ff8c8c2018-02-07 01:58:51 +00003463In paint: Paint_Style determines if Oval is stroked or filled;
Cary Clark8032b982017-07-28 11:04:54 -04003464if stroked, Paint_Stroke_Width describes the line thickness.
3465
Cary Clarkbad5ad72017-08-03 17:14:08 -04003466#Param oval Rect bounds of Oval ##
3467#Param paint Paint stroke or fill, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003468
3469#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003470void draw(SkCanvas* canvas) {
3471 canvas->clear(0xFF3f5f9f);
3472 SkColor kColor1 = SkColorSetARGB(0xff, 0xff, 0x7f, 0);
3473 SkColor g1Colors[] = { kColor1, SkColorSetA(kColor1, 0x20) };
3474 SkPoint g1Points[] = { { 0, 0 }, { 0, 100 } };
3475 SkScalar pos[] = { 0.2f, 1.0f };
3476 SkRect bounds = SkRect::MakeWH(80, 70);
3477 SkPaint paint;
3478 paint.setAntiAlias(true);
3479 paint.setShader(SkGradientShader::MakeLinear(g1Points, g1Colors, pos, SK_ARRAY_COUNT(g1Colors),
3480 SkShader::kClamp_TileMode));
3481 canvas->drawOval(bounds , paint);
Cary Clark8032b982017-07-28 11:04:54 -04003482}
3483##
3484
Cary Clark2ade9972017-11-02 17:49:34 -04003485#SeeAlso drawCircle drawPoint drawPath drawRRect drawRoundRect
Cary Clark8032b982017-07-28 11:04:54 -04003486
3487##
3488
3489# ------------------------------------------------------------------------------
3490
3491#Method void drawRRect(const SkRRect& rrect, const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05003492#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05003493#Line # draws Round_Rect using Clip, Matrix, and Paint ##
Cary Clark8032b982017-07-28 11:04:54 -04003494Draw Round_Rect rrect using Clip, Matrix, and Paint paint.
Mike Klein9ff8c8c2018-02-07 01:58:51 +00003495In paint: Paint_Style determines if rrect is stroked or filled;
Cary Clark8032b982017-07-28 11:04:54 -04003496if stroked, Paint_Stroke_Width describes the line thickness.
3497
Cary Clarkbad5ad72017-08-03 17:14:08 -04003498rrect may represent a rectangle, circle, oval, uniformly rounded rectangle, or
3499may have any combination of positive non-square radii for the four corners.
Cary Clark8032b982017-07-28 11:04:54 -04003500
Cary Clarkbad5ad72017-08-03 17:14:08 -04003501#Param rrect Round_Rect with up to eight corner radii to draw ##
3502#Param paint Paint stroke or fill, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003503
3504#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003505void draw(SkCanvas* canvas) {
3506 SkPaint paint;
3507 paint.setAntiAlias(true);
3508 SkRect outer = {30, 40, 210, 220};
3509 SkRect radii = {30, 50, 70, 90 };
3510 SkRRect rRect;
3511 rRect.setNinePatch(outer, radii.fLeft, radii.fTop, radii.fRight, radii.fBottom);
3512 canvas->drawRRect(rRect, paint);
3513 paint.setColor(SK_ColorWHITE);
3514 canvas->drawLine(outer.fLeft + radii.fLeft, outer.fTop,
3515 outer.fLeft + radii.fLeft, outer.fBottom, paint);
Mike Klein9ff8c8c2018-02-07 01:58:51 +00003516 canvas->drawLine(outer.fRight - radii.fRight, outer.fTop,
Cary Clarkbad5ad72017-08-03 17:14:08 -04003517 outer.fRight - radii.fRight, outer.fBottom, paint);
Mike Klein9ff8c8c2018-02-07 01:58:51 +00003518 canvas->drawLine(outer.fLeft, outer.fTop + radii.fTop,
Cary Clarkbad5ad72017-08-03 17:14:08 -04003519 outer.fRight, outer.fTop + radii.fTop, paint);
Mike Klein9ff8c8c2018-02-07 01:58:51 +00003520 canvas->drawLine(outer.fLeft, outer.fBottom - radii.fBottom,
Cary Clarkbad5ad72017-08-03 17:14:08 -04003521 outer.fRight, outer.fBottom - radii.fBottom, paint);
3522}
Cary Clark8032b982017-07-28 11:04:54 -04003523##
3524
Cary Clark2ade9972017-11-02 17:49:34 -04003525#SeeAlso drawRect drawRoundRect drawDRRect drawCircle drawOval drawPath
Cary Clark8032b982017-07-28 11:04:54 -04003526
3527##
3528
3529# ------------------------------------------------------------------------------
3530
3531#Method void drawDRRect(const SkRRect& outer, const SkRRect& inner, const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05003532#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05003533#Line # draws double Round_Rect stroked or filled ##
Cary Clark8032b982017-07-28 11:04:54 -04003534Draw Round_Rect outer and inner
Mike Klein9ff8c8c2018-02-07 01:58:51 +00003535using Clip, Matrix, and Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04003536outer must contain inner or the drawing is undefined.
Mike Klein9ff8c8c2018-02-07 01:58:51 +00003537In paint: Paint_Style determines if Round_Rect is stroked or filled;
Cary Clark8032b982017-07-28 11:04:54 -04003538if stroked, Paint_Stroke_Width describes the line thickness.
Cary Clarkbad5ad72017-08-03 17:14:08 -04003539If stroked and Round_Rect corner has zero length radii, Paint_Stroke_Join can
Mike Klein9ff8c8c2018-02-07 01:58:51 +00003540draw corners rounded or square.
Cary Clark8032b982017-07-28 11:04:54 -04003541
Cary Clarkbad5ad72017-08-03 17:14:08 -04003542GPU-backed platforms optimize drawing when both outer and inner are
Cary Clark8032b982017-07-28 11:04:54 -04003543concave and outer contains inner. These platforms may not be able to draw
Mike Klein9ff8c8c2018-02-07 01:58:51 +00003544Path built with identical data as fast.
Cary Clark8032b982017-07-28 11:04:54 -04003545
Cary Clarkbad5ad72017-08-03 17:14:08 -04003546#Param outer Round_Rect outer bounds to draw ##
3547#Param inner Round_Rect inner bounds to draw ##
3548#Param paint Paint stroke or fill, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003549
3550#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003551void draw(SkCanvas* canvas) {
3552 SkRRect outer = SkRRect::MakeRect({20, 40, 210, 200});
3553 SkRRect inner = SkRRect::MakeOval({60, 70, 170, 160});
3554 SkPaint paint;
3555 canvas->drawDRRect(outer, inner, paint);
Cary Clark8032b982017-07-28 11:04:54 -04003556}
3557##
3558
3559#Example
3560#Description
3561 Outer Rect has no corner radii, but stroke join is rounded.
3562 Inner Round_Rect has corner radii; outset stroke increases radii of corners.
3563 Stroke join does not affect inner Round_Rect since it has no sharp corners.
3564##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003565void draw(SkCanvas* canvas) {
3566 SkRRect outer = SkRRect::MakeRect({20, 40, 210, 200});
3567 SkRRect inner = SkRRect::MakeRectXY({60, 70, 170, 160}, 10, 10);
3568 SkPaint paint;
3569 paint.setAntiAlias(true);
3570 paint.setStyle(SkPaint::kStroke_Style);
3571 paint.setStrokeWidth(20);
3572 paint.setStrokeJoin(SkPaint::kRound_Join);
3573 canvas->drawDRRect(outer, inner, paint);
3574 paint.setStrokeWidth(1);
3575 paint.setColor(SK_ColorWHITE);
3576 canvas->drawDRRect(outer, inner, paint);
Cary Clark8032b982017-07-28 11:04:54 -04003577}
3578##
3579
Cary Clark2ade9972017-11-02 17:49:34 -04003580#SeeAlso drawRect drawRoundRect drawRRect drawCircle drawOval drawPath
Cary Clark8032b982017-07-28 11:04:54 -04003581
3582##
3583
3584# ------------------------------------------------------------------------------
3585
3586#Method void drawCircle(SkScalar cx, SkScalar cy, SkScalar radius, const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05003587#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05003588#Line # draws Circle using Clip, Matrix, and Paint ##
Cary Clark8032b982017-07-28 11:04:54 -04003589Draw Circle at (cx, cy) with radius using Clip, Matrix, and Paint paint.
3590If radius is zero or less, nothing is drawn.
Mike Klein9ff8c8c2018-02-07 01:58:51 +00003591In paint: Paint_Style determines if Circle is stroked or filled;
Cary Clark8032b982017-07-28 11:04:54 -04003592if stroked, Paint_Stroke_Width describes the line thickness.
3593
Cary Clarkbad5ad72017-08-03 17:14:08 -04003594#Param cx Circle center on the x-axis ##
3595#Param cy Circle center on the y-axis ##
3596#Param radius half the diameter of Circle ##
3597#Param paint Paint stroke or fill, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003598
3599#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003600 void draw(SkCanvas* canvas) {
3601 SkPaint paint;
3602 paint.setAntiAlias(true);
3603 canvas->drawCircle(128, 128, 90, paint);
3604 paint.setColor(SK_ColorWHITE);
3605 canvas->drawCircle(86, 86, 20, paint);
3606 canvas->drawCircle(160, 76, 20, paint);
3607 canvas->drawCircle(140, 150, 35, paint);
3608 }
3609##
3610
Cary Clark2ade9972017-11-02 17:49:34 -04003611#SeeAlso drawOval drawRRect drawRoundRect drawPath drawArc drawPoint drawLine
Cary Clarkbad5ad72017-08-03 17:14:08 -04003612
3613##
3614
3615#Method void drawCircle(SkPoint center, SkScalar radius, const SkPaint& paint)
3616
Cary Clarkce101242017-09-01 15:51:02 -04003617Draw Circle at center with radius using Clip, Matrix, and Paint paint.
Cary Clarkbad5ad72017-08-03 17:14:08 -04003618If radius is zero or less, nothing is drawn.
Mike Klein9ff8c8c2018-02-07 01:58:51 +00003619In paint: Paint_Style determines if Circle is stroked or filled;
Cary Clarkbad5ad72017-08-03 17:14:08 -04003620if stroked, Paint_Stroke_Width describes the line thickness.
3621
3622#Param center Circle center ##
3623#Param radius half the diameter of Circle ##
3624#Param paint Paint stroke or fill, blend, color, and so on, used to draw ##
3625
3626#Example
3627 void draw(SkCanvas* canvas) {
3628 SkPaint paint;
3629 paint.setAntiAlias(true);
3630 canvas->drawCircle(128, 128, 90, paint);
3631 paint.setColor(SK_ColorWHITE);
3632 canvas->drawCircle({86, 86}, 20, paint);
3633 canvas->drawCircle({160, 76}, 20, paint);
3634 canvas->drawCircle({140, 150}, 35, paint);
3635 }
Cary Clark8032b982017-07-28 11:04:54 -04003636##
3637
Cary Clark2ade9972017-11-02 17:49:34 -04003638#SeeAlso drawOval drawRRect drawRoundRect drawPath drawArc drawPoint drawLine
Cary Clark8032b982017-07-28 11:04:54 -04003639
3640##
3641
3642# ------------------------------------------------------------------------------
3643
3644#Method void drawArc(const SkRect& oval, SkScalar startAngle, SkScalar sweepAngle,
3645 bool useCenter, const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05003646#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05003647#Line # draws Arc using Clip, Matrix, and Paint ##
Cary Clark8032b982017-07-28 11:04:54 -04003648
3649Draw Arc using Clip, Matrix, and Paint paint.
Cary Clarkbad5ad72017-08-03 17:14:08 -04003650
Cary Clark8032b982017-07-28 11:04:54 -04003651Arc is part of Oval bounded by oval, sweeping from startAngle to startAngle plus
3652sweepAngle. startAngle and sweepAngle are in degrees.
Cary Clarkbad5ad72017-08-03 17:14:08 -04003653
Cary Clark8032b982017-07-28 11:04:54 -04003654startAngle of zero places start point at the right middle edge of oval.
3655A positive sweepAngle places Arc end point clockwise from start point;
3656a negative sweepAngle places Arc end point counterclockwise from start point.
3657sweepAngle may exceed 360 degrees, a full circle.
3658If useCenter is true, draw a wedge that includes lines from oval
3659center to Arc end points. If useCenter is false, draw Arc between end points.
3660
3661If Rect oval is empty or sweepAngle is zero, nothing is drawn.
3662
Cary Clarkbad5ad72017-08-03 17:14:08 -04003663#Param oval Rect bounds of Oval containing Arc to draw ##
3664#Param startAngle angle in degrees where Arc begins ##
3665#Param sweepAngle sweep angle in degrees; positive is clockwise ##
3666#Param useCenter if true, include the center of the oval ##
3667#Param paint Paint stroke or fill, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003668
3669#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003670 void draw(SkCanvas* canvas) {
3671 SkPaint paint;
3672 paint.setAntiAlias(true);
3673 SkRect oval = { 4, 4, 60, 60};
3674 for (auto useCenter : { false, true } ) {
3675 for (auto style : { SkPaint::kFill_Style, SkPaint::kStroke_Style } ) {
3676 paint.setStyle(style);
3677 for (auto degrees : { 45, 90, 180, 360} ) {
3678 canvas->drawArc(oval, 0, degrees , useCenter, paint);
3679 canvas->translate(64, 0);
3680 }
3681 canvas->translate(-256, 64);
3682 }
3683 }
Cary Clark8032b982017-07-28 11:04:54 -04003684 }
3685##
3686
3687#Example
3688#Height 64
Cary Clarkbad5ad72017-08-03 17:14:08 -04003689 void draw(SkCanvas* canvas) {
3690 SkPaint paint;
3691 paint.setAntiAlias(true);
3692 paint.setStyle(SkPaint::kStroke_Style);
3693 paint.setStrokeWidth(4);
3694 SkRect oval = { 4, 4, 60, 60};
3695 float intervals[] = { 5, 5 };
3696 paint.setPathEffect(SkDashPathEffect::Make(intervals, 2, 2.5f));
3697 for (auto degrees : { 270, 360, 540, 720 } ) {
3698 canvas->drawArc(oval, 0, degrees, false, paint);
3699 canvas->translate(64, 0);
3700 }
Cary Clark8032b982017-07-28 11:04:54 -04003701 }
3702##
3703
Cary Clark2ade9972017-11-02 17:49:34 -04003704#SeeAlso SkPath::arcTo drawCircle drawOval drawPath
Cary Clark8032b982017-07-28 11:04:54 -04003705
3706##
3707
3708# ------------------------------------------------------------------------------
3709
3710#Method void drawRoundRect(const SkRect& rect, SkScalar rx, SkScalar ry, const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05003711#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05003712#Line # draws Round_Rect using Clip, Matrix, and Paint ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003713Draw Round_Rect bounded by Rect rect, with corner radii (rx, ry) using Clip,
3714Matrix, and Paint paint.
3715
Mike Klein9ff8c8c2018-02-07 01:58:51 +00003716In paint: Paint_Style determines if Round_Rect is stroked or filled;
Cary Clark8032b982017-07-28 11:04:54 -04003717if stroked, Paint_Stroke_Width describes the line thickness.
3718If rx or ry are less than zero, they are treated as if they are zero.
3719If rx plus ry exceeds rect width or rect height, radii are scaled down to fit.
Cary Clarkbad5ad72017-08-03 17:14:08 -04003720If rx and ry are zero, Round_Rect is drawn as Rect and if stroked is affected by
3721Paint_Stroke_Join.
Cary Clark8032b982017-07-28 11:04:54 -04003722
Cary Clarkbad5ad72017-08-03 17:14:08 -04003723#Param rect Rect bounds of Round_Rect to draw ##
Cary Clarkce101242017-09-01 15:51:02 -04003724#Param rx axis length in x of oval describing rounded corners ##
3725#Param ry axis length in y of oval describing rounded corners ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003726#Param paint stroke, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003727
3728#Example
3729#Description
3730 Top row has a zero radius a generates a rectangle.
3731 Second row radii sum to less than sides.
3732 Third row radii sum equals sides.
3733 Fourth row radii sum exceeds sides; radii are scaled to fit.
3734##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003735 void draw(SkCanvas* canvas) {
3736 SkVector radii[] = { {0, 20}, {10, 10}, {10, 20}, {10, 40} };
3737 SkPaint paint;
3738 paint.setStrokeWidth(15);
3739 paint.setStrokeJoin(SkPaint::kRound_Join);
3740 paint.setAntiAlias(true);
3741 for (auto style : { SkPaint::kStroke_Style, SkPaint::kFill_Style } ) {
3742 paint.setStyle(style );
3743 for (size_t i = 0; i < SK_ARRAY_COUNT(radii); ++i) {
3744 canvas->drawRoundRect({10, 10, 60, 40}, radii[i].fX, radii[i].fY, paint);
3745 canvas->translate(0, 60);
3746 }
3747 canvas->translate(80, -240);
3748 }
Cary Clark8032b982017-07-28 11:04:54 -04003749 }
3750##
3751
Cary Clark2ade9972017-11-02 17:49:34 -04003752#SeeAlso DrawRRect drawRect drawDRRect drawPath drawCircle drawOval drawPoint
Cary Clark8032b982017-07-28 11:04:54 -04003753
3754##
3755
3756# ------------------------------------------------------------------------------
3757
3758#Method void drawPath(const SkPath& path, const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05003759#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05003760#Line # draws Path using Clip, Matrix, and Paint ##
Cary Clark8032b982017-07-28 11:04:54 -04003761Draw Path path using Clip, Matrix, and Paint paint.
3762Path contains an array of Path_Contour, each of which may be open or closed.
3763
3764In paint: Paint_Style determines if Round_Rect is stroked or filled:
Cary Clarkbad5ad72017-08-03 17:14:08 -04003765if filled, Path_Fill_Type determines whether Path_Contour describes inside or
3766outside of fill; if stroked, Paint_Stroke_Width describes the line thickness,
3767Paint_Stroke_Cap describes line ends, and Paint_Stroke_Join describes how
3768corners are drawn.
Cary Clark8032b982017-07-28 11:04:54 -04003769
Cary Clarkbad5ad72017-08-03 17:14:08 -04003770#Param path Path to draw ##
3771#Param paint stroke, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003772
3773#Example
3774#Description
3775 Top rows draw stroked path with combinations of joins and caps. The open contour
3776 is affected by caps; the closed contour is affected by joins.
Mike Klein9ff8c8c2018-02-07 01:58:51 +00003777 Bottom row draws fill the same for open and closed contour.
Cary Clark8032b982017-07-28 11:04:54 -04003778 First bottom column shows winding fills overlap.
3779 Second bottom column shows even odd fills exclude overlap.
3780 Third bottom column shows inverse winding fills area outside both contours.
3781##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003782void draw(SkCanvas* canvas) {
3783 SkPath path;
3784 path.moveTo(20, 20);
3785 path.quadTo(60, 20, 60, 60);
3786 path.close();
3787 path.moveTo(60, 20);
3788 path.quadTo(60, 60, 20, 60);
3789 SkPaint paint;
3790 paint.setStrokeWidth(10);
3791 paint.setAntiAlias(true);
3792 paint.setStyle(SkPaint::kStroke_Style);
3793 for (auto join: { SkPaint::kBevel_Join, SkPaint::kRound_Join, SkPaint::kMiter_Join } ) {
3794 paint.setStrokeJoin(join);
3795 for (auto cap: { SkPaint::kButt_Cap, SkPaint::kSquare_Cap, SkPaint::kRound_Cap } ) {
3796 paint.setStrokeCap(cap);
3797 canvas->drawPath(path, paint);
3798 canvas->translate(80, 0);
3799 }
3800 canvas->translate(-240, 60);
3801 }
3802 paint.setStyle(SkPaint::kFill_Style);
Mike Klein9ff8c8c2018-02-07 01:58:51 +00003803 for (auto fill : { SkPath::kWinding_FillType,
3804 SkPath::kEvenOdd_FillType,
Cary Clarkbad5ad72017-08-03 17:14:08 -04003805 SkPath::kInverseWinding_FillType } ) {
3806 path.setFillType(fill);
3807 canvas->save();
3808 canvas->clipRect({0, 10, 80, 70});
3809 canvas->drawPath(path, paint);
3810 canvas->restore();
3811 canvas->translate(80, 0);
3812 }
Cary Clark8032b982017-07-28 11:04:54 -04003813}
3814##
3815
Cary Clark2ade9972017-11-02 17:49:34 -04003816#SeeAlso SkPath drawLine drawArc drawRect drawPoints
Cary Clark8032b982017-07-28 11:04:54 -04003817
3818##
3819
3820# ------------------------------------------------------------------------------
Cary Clark08895c42018-02-01 09:37:32 -05003821#Subtopic Draw_Image
3822#Line # draws Image to Canvas ##
Cary Clark8032b982017-07-28 11:04:54 -04003823
Cary Clarkbad5ad72017-08-03 17:14:08 -04003824drawImage, drawImageRect, and drawImageNine can be called with a bare pointer or
3825a smart pointer as a convenience. The pairs of calls are otherwise identical.
Cary Clark8032b982017-07-28 11:04:54 -04003826
Cary Clark73fa9722017-08-29 17:36:51 -04003827#Method void drawImage(const SkImage* image, SkScalar left, SkScalar top, const SkPaint* paint = nullptr)
Cary Clarkab2621d2018-01-30 10:08:57 -05003828#In Draw_Image
Cary Clark78de7512018-02-07 07:27:09 -05003829#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05003830#Line # draws Image at (x, y) position ##
Cary Clark8032b982017-07-28 11:04:54 -04003831Draw Image image, with its top-left corner at (left, top),
3832using Clip, Matrix, and optional Paint paint.
3833
Cary Clarkbad5ad72017-08-03 17:14:08 -04003834If paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter, Blend_Mode,
3835and Draw_Looper. If image is kAlpha_8_SkColorType, apply Shader.
3836If paint contains Mask_Filter, generate mask from image bounds. If generated
3837mask extends beyond image bounds, replicate image edge colors, just as Shader
3838made from SkImage::makeShader with SkShader::kClamp_TileMode set replicates the
Mike Klein9ff8c8c2018-02-07 01:58:51 +00003839image edge color when it samples outside of its bounds.
Cary Clark8032b982017-07-28 11:04:54 -04003840
Cary Clarkbad5ad72017-08-03 17:14:08 -04003841#Param image uncompressed rectangular map of pixels ##
3842#Param left left side of image ##
3843#Param top top side of image ##
3844#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
3845 and so on; or nullptr
3846##
Cary Clark8032b982017-07-28 11:04:54 -04003847
3848#Example
3849#Height 64
3850#Image 4
Cary Clarkbad5ad72017-08-03 17:14:08 -04003851void draw(SkCanvas* canvas) {
3852 // sk_sp<SkImage> image;
3853 SkImage* imagePtr = image.get();
3854 canvas->drawImage(imagePtr, 0, 0);
3855 SkPaint paint;
3856 canvas->drawImage(imagePtr, 80, 0, &paint);
3857 paint.setAlpha(0x80);
3858 canvas->drawImage(imagePtr, 160, 0, &paint);
Cary Clark8032b982017-07-28 11:04:54 -04003859}
3860##
3861
Cary Clark2ade9972017-11-02 17:49:34 -04003862#SeeAlso drawBitmap drawImageLattice drawImageNine drawImageRect SkPaint::setImageFilter
Cary Clark8032b982017-07-28 11:04:54 -04003863
3864##
3865
3866# ------------------------------------------------------------------------------
3867
3868#Method void drawImage(const sk_sp<SkImage>& image, SkScalar left, SkScalar top,
Mike Klein9ff8c8c2018-02-07 01:58:51 +00003869 const SkPaint* paint = nullptr)
Cary Clark8032b982017-07-28 11:04:54 -04003870
3871Draw Image image, with its top-left corner at (left, top),
3872using Clip, Matrix, and optional Paint paint.
3873
Cary Clarkbad5ad72017-08-03 17:14:08 -04003874If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
3875Blend_Mode, and Draw_Looper. If image is kAlpha_8_SkColorType, apply Shader.
3876If paint contains Mask_Filter, generate mask from image bounds. If generated
3877mask extends beyond image bounds, replicate image edge colors, just as Shader
3878made from SkImage::makeShader with SkShader::kClamp_TileMode set replicates the
Mike Klein9ff8c8c2018-02-07 01:58:51 +00003879image edge color when it samples outside of its bounds.
Cary Clark8032b982017-07-28 11:04:54 -04003880
Cary Clarkbad5ad72017-08-03 17:14:08 -04003881#Param image uncompressed rectangular map of pixels ##
3882#Param left left side of image ##
3883#Param top pop side of image ##
3884#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
3885 and so on; or nullptr
3886##
Cary Clark8032b982017-07-28 11:04:54 -04003887
3888#Example
3889#Height 64
3890#Image 4
Cary Clarkbad5ad72017-08-03 17:14:08 -04003891void draw(SkCanvas* canvas) {
3892 // sk_sp<SkImage> image;
3893 canvas->drawImage(image, 0, 0);
3894 SkPaint paint;
3895 canvas->drawImage(image, 80, 0, &paint);
3896 paint.setAlpha(0x80);
3897 canvas->drawImage(image, 160, 0, &paint);
Cary Clark8032b982017-07-28 11:04:54 -04003898}
3899##
3900
Cary Clark2ade9972017-11-02 17:49:34 -04003901#SeeAlso drawBitmap drawImageLattice drawImageNine drawImageRect SkPaint::setImageFilter
Cary Clark8032b982017-07-28 11:04:54 -04003902
3903##
3904
3905# ------------------------------------------------------------------------------
3906
3907#Enum SrcRectConstraint
Cary Clark08895c42018-02-01 09:37:32 -05003908#Line # sets drawImageRect options ##
Cary Clark8032b982017-07-28 11:04:54 -04003909
3910#Code
3911 enum SrcRectConstraint {
Mike Klein9ff8c8c2018-02-07 01:58:51 +00003912 kStrict_SrcRectConstraint,
3913 kFast_SrcRectConstraint,
Cary Clark8032b982017-07-28 11:04:54 -04003914 };
3915##
3916
Cary Clarkce101242017-09-01 15:51:02 -04003917SrcRectConstraint controls the behavior at the edge of source Rect,
3918provided to drawImageRect, trading off speed for precision.
Cary Clark8032b982017-07-28 11:04:54 -04003919
Cary Clarkce101242017-09-01 15:51:02 -04003920Image_Filter in Paint may sample multiple pixels in the image. Source Rect
Cary Clarkbad5ad72017-08-03 17:14:08 -04003921restricts the bounds of pixels that may be read. Image_Filter may slow down if
Mike Klein9ff8c8c2018-02-07 01:58:51 +00003922it cannot read outside the bounds, when sampling near the edge of source Rect.
Cary Clark8032b982017-07-28 11:04:54 -04003923SrcRectConstraint specifies whether an Image_Filter is allowed to read pixels
Cary Clarkce101242017-09-01 15:51:02 -04003924outside source Rect.
Cary Clark8032b982017-07-28 11:04:54 -04003925
3926#Const kStrict_SrcRectConstraint
Cary Clarkce101242017-09-01 15:51:02 -04003927 Requires Image_Filter to respect source Rect,
Cary Clark8032b982017-07-28 11:04:54 -04003928 sampling only inside of its bounds, possibly with a performance penalty.
3929##
3930
3931#Const kFast_SrcRectConstraint
Cary Clarkce101242017-09-01 15:51:02 -04003932 Permits Image_Filter to sample outside of source Rect
Cary Clark8032b982017-07-28 11:04:54 -04003933 by half the width of Image_Filter, permitting it to run faster but with
3934 error at the image edges.
3935##
3936
3937#Example
3938#Height 64
3939#Description
3940 redBorder contains a black and white checkerboard bordered by red.
3941 redBorder is drawn scaled by 16 on the left.
Cary Clarkce101242017-09-01 15:51:02 -04003942 The middle and right bitmaps are filtered checkerboards.
Cary Clark8032b982017-07-28 11:04:54 -04003943 Drawing the checkerboard with kStrict_SrcRectConstraint shows only a blur of black and white.
3944 Drawing the checkerboard with kFast_SrcRectConstraint allows red to bleed in the corners.
3945##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003946void draw(SkCanvas* canvas) {
3947 SkBitmap redBorder;
3948 redBorder.allocPixels(SkImageInfo::MakeN32Premul(4, 4));
3949 SkCanvas checkRed(redBorder);
3950 checkRed.clear(SK_ColorRED);
3951 uint32_t checkers[][2] = { { SK_ColorBLACK, SK_ColorWHITE },
3952 { SK_ColorWHITE, SK_ColorBLACK } };
3953 checkRed.writePixels(
3954 SkImageInfo::MakeN32Premul(2, 2), (void*) checkers, sizeof(checkers[0]), 1, 1);
3955 canvas->scale(16, 16);
3956 canvas->drawBitmap(redBorder, 0, 0, nullptr);
3957 canvas->resetMatrix();
3958 sk_sp<SkImage> image = SkImage::MakeFromBitmap(redBorder);
3959 SkPaint lowPaint;
3960 lowPaint.setFilterQuality(kLow_SkFilterQuality);
3961 for (auto constraint : { SkCanvas::kStrict_SrcRectConstraint,
3962 SkCanvas::kFast_SrcRectConstraint } ) {
3963 canvas->translate(80, 0);
3964 canvas->drawImageRect(image.get(), SkRect::MakeLTRB(1, 1, 3, 3),
3965 SkRect::MakeLTRB(16, 16, 48, 48), &lowPaint, constraint);
3966 }
Cary Clark8032b982017-07-28 11:04:54 -04003967}
3968##
3969
Cary Clark2ade9972017-11-02 17:49:34 -04003970#SeeAlso drawImageRect drawImage SkPaint::setImageFilter
Cary Clark8032b982017-07-28 11:04:54 -04003971
3972##
3973
3974# ------------------------------------------------------------------------------
3975
3976#Method void drawImageRect(const SkImage* image, const SkRect& src, const SkRect& dst,
3977 const SkPaint* paint,
3978 SrcRectConstraint constraint = kStrict_SrcRectConstraint)
Cary Clarkab2621d2018-01-30 10:08:57 -05003979#In Draw_Image
Cary Clark78de7512018-02-07 07:27:09 -05003980#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05003981#Line # draws Image, source Rect to destination Rect ##
Cary Clark8032b982017-07-28 11:04:54 -04003982
3983Draw Rect src of Image image, scaled and translated to fill Rect dst.
3984Additionally transform draw using Clip, Matrix, and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04003985
Cary Clarkbad5ad72017-08-03 17:14:08 -04003986If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
3987Blend_Mode, and Draw_Looper. If image is kAlpha_8_SkColorType, apply Shader.
3988If paint contains Mask_Filter, generate mask from image bounds.
3989
3990If generated mask extends beyond image bounds, replicate image edge colors, just
3991as Shader made from SkImage::makeShader with SkShader::kClamp_TileMode set
Cary Clarkbc5697d2017-10-04 14:31:33 -04003992replicates the image edge color when it samples outside of its bounds.
Cary Clarkbad5ad72017-08-03 17:14:08 -04003993
3994constraint set to kStrict_SrcRectConstraint limits Paint Filter_Quality to
3995sample within src; set to kFast_SrcRectConstraint allows sampling outside to
3996improve performance.
3997
3998#Param image Image containing pixels, dimensions, and format ##
3999#Param src source Rect of image to draw from ##
4000#Param dst destination Rect of image to draw to ##
4001#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4002 and so on; or nullptr
4003##
4004#Param constraint filter strictly within src or draw faster ##
Cary Clark8032b982017-07-28 11:04:54 -04004005
4006#Example
4007#Height 64
4008#Description
4009 The left bitmap draws with Paint default kNone_SkFilterQuality, and stays within
Cary Clarkbc5697d2017-10-04 14:31:33 -04004010 its bounds; there is no bleeding with kFast_SrcRectConstraint.
Cary Clark8032b982017-07-28 11:04:54 -04004011 the middle and right bitmaps draw with kLow_SkFilterQuality; with
4012 kStrict_SrcRectConstraint, the filter remains within the checkerboard, and
4013 with kFast_SrcRectConstraint red bleeds on the edges.
4014##
Cary Clarkbad5ad72017-08-03 17:14:08 -04004015void draw(SkCanvas* canvas) {
Mike Klein9ff8c8c2018-02-07 01:58:51 +00004016 uint32_t pixels[][4] = {
Cary Clarkbad5ad72017-08-03 17:14:08 -04004017 { 0xFFFF0000, 0xFFFF0000, 0xFFFF0000, 0xFFFF0000 },
4018 { 0xFFFF0000, 0xFF000000, 0xFFFFFFFF, 0xFFFF0000 },
4019 { 0xFFFF0000, 0xFFFFFFFF, 0xFF000000, 0xFFFF0000 },
4020 { 0xFFFF0000, 0xFFFF0000, 0xFFFF0000, 0xFFFF0000 } };
4021 SkBitmap redBorder;
Mike Klein9ff8c8c2018-02-07 01:58:51 +00004022 redBorder.installPixels(SkImageInfo::MakeN32Premul(4, 4),
Cary Clarkbad5ad72017-08-03 17:14:08 -04004023 (void*) pixels, sizeof(pixels[0]));
4024 sk_sp<SkImage> image = SkImage::MakeFromBitmap(redBorder);
4025 SkPaint lowPaint;
4026 for (auto constraint : {
4027 SkCanvas::kFast_SrcRectConstraint,
4028 SkCanvas::kStrict_SrcRectConstraint,
4029 SkCanvas::kFast_SrcRectConstraint } ) {
4030 canvas->drawImageRect(image.get(), SkRect::MakeLTRB(1, 1, 3, 3),
4031 SkRect::MakeLTRB(16, 16, 48, 48), &lowPaint, constraint);
4032 lowPaint.setFilterQuality(kLow_SkFilterQuality);
4033 canvas->translate(80, 0);
4034 }
4035}
Cary Clark8032b982017-07-28 11:04:54 -04004036##
4037
Cary Clark2ade9972017-11-02 17:49:34 -04004038#SeeAlso SrcRectConstraint drawImage drawImageLattice drawImageNine
Cary Clark8032b982017-07-28 11:04:54 -04004039
4040##
4041
4042# ------------------------------------------------------------------------------
4043
4044#Method void drawImageRect(const SkImage* image, const SkIRect& isrc, const SkRect& dst,
4045 const SkPaint* paint, SrcRectConstraint constraint = kStrict_SrcRectConstraint)
Cary Clarkab2621d2018-01-30 10:08:57 -05004046#In Draw_Image
Cary Clark78de7512018-02-07 07:27:09 -05004047#In Draw
Cary Clark8032b982017-07-28 11:04:54 -04004048
4049Draw IRect isrc of Image image, scaled and translated to fill Rect dst.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004050Note that isrc is on integer pixel boundaries; dst may include fractional
4051boundaries. Additionally transform draw using Clip, Matrix, and optional Paint
Mike Klein9ff8c8c2018-02-07 01:58:51 +00004052paint.
Cary Clark8032b982017-07-28 11:04:54 -04004053
Cary Clarkbad5ad72017-08-03 17:14:08 -04004054If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4055Blend_Mode, and Draw_Looper. If image is kAlpha_8_SkColorType, apply Shader.
4056If paint contains Mask_Filter, generate mask from image bounds.
4057
4058If generated mask extends beyond image bounds, replicate image edge colors, just
4059as Shader made from SkImage::makeShader with SkShader::kClamp_TileMode set
Cary Clarkbc5697d2017-10-04 14:31:33 -04004060replicates the image edge color when it samples outside of its bounds.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004061
4062constraint set to kStrict_SrcRectConstraint limits Paint Filter_Quality to
Cary Clarkce101242017-09-01 15:51:02 -04004063sample within isrc; set to kFast_SrcRectConstraint allows sampling outside to
Cary Clarkbad5ad72017-08-03 17:14:08 -04004064improve performance.
4065
4066#Param image Image containing pixels, dimensions, and format ##
4067#Param isrc source IRect of image to draw from ##
4068#Param dst destination Rect of image to draw to ##
4069#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4070 and so on; or nullptr
4071##
Cary Clarkce101242017-09-01 15:51:02 -04004072#Param constraint filter strictly within isrc or draw faster ##
Cary Clark8032b982017-07-28 11:04:54 -04004073
4074#Example
4075#Image 4
Cary Clarkbad5ad72017-08-03 17:14:08 -04004076void draw(SkCanvas* canvas) {
4077 // sk_sp<SkImage> image;
4078 for (auto i : { 1, 2, 4, 8 } ) {
Mike Klein9ff8c8c2018-02-07 01:58:51 +00004079 canvas->drawImageRect(image.get(), SkIRect::MakeLTRB(0, 0, 100, 100),
Cary Clarkbad5ad72017-08-03 17:14:08 -04004080 SkRect::MakeXYWH(i * 20, i * 20, i * 20, i * 20), nullptr);
4081 }
Cary Clark8032b982017-07-28 11:04:54 -04004082}
4083##
4084
Cary Clark2ade9972017-11-02 17:49:34 -04004085#SeeAlso SrcRectConstraint drawImage drawImageLattice drawImageNine
Cary Clark8032b982017-07-28 11:04:54 -04004086
4087##
4088
4089# ------------------------------------------------------------------------------
4090
4091#Method void drawImageRect(const SkImage* image, const SkRect& dst, const SkPaint* paint,
4092 SrcRectConstraint constraint = kStrict_SrcRectConstraint)
Cary Clarkab2621d2018-01-30 10:08:57 -05004093#In Draw_Image
Cary Clark78de7512018-02-07 07:27:09 -05004094#In Draw
Cary Clark8032b982017-07-28 11:04:54 -04004095
Cary Clarkbad5ad72017-08-03 17:14:08 -04004096Draw Image image, scaled and translated to fill Rect dst, using Clip, Matrix,
4097and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004098
Cary Clarkbad5ad72017-08-03 17:14:08 -04004099If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4100Blend_Mode, and Draw_Looper. If image is kAlpha_8_SkColorType, apply Shader.
4101If paint contains Mask_Filter, generate mask from image bounds.
4102
4103If generated mask extends beyond image bounds, replicate image edge colors, just
4104as Shader made from SkImage::makeShader with SkShader::kClamp_TileMode set
Cary Clarkbc5697d2017-10-04 14:31:33 -04004105replicates the image edge color when it samples outside of its bounds.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004106
4107constraint set to kStrict_SrcRectConstraint limits Paint Filter_Quality to
Cary Clarkce101242017-09-01 15:51:02 -04004108sample within image; set to kFast_SrcRectConstraint allows sampling outside to
Cary Clarkbad5ad72017-08-03 17:14:08 -04004109improve performance.
4110
4111#Param image Image containing pixels, dimensions, and format ##
4112#Param dst destination Rect of image to draw to ##
4113#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4114 and so on; or nullptr
4115##
Cary Clarkce101242017-09-01 15:51:02 -04004116#Param constraint filter strictly within image or draw faster ##
Cary Clark8032b982017-07-28 11:04:54 -04004117
4118#Example
4119#Image 4
Cary Clarkbad5ad72017-08-03 17:14:08 -04004120void draw(SkCanvas* canvas) {
4121 // sk_sp<SkImage> image;
4122 for (auto i : { 20, 40, 80, 160 } ) {
4123 canvas->drawImageRect(image.get(), SkRect::MakeXYWH(i, i, i, i), nullptr);
4124 }
Cary Clark8032b982017-07-28 11:04:54 -04004125}
4126##
4127
Cary Clark2ade9972017-11-02 17:49:34 -04004128#SeeAlso SrcRectConstraint drawImage drawImageLattice drawImageNine
Cary Clark8032b982017-07-28 11:04:54 -04004129
4130##
4131
4132# ------------------------------------------------------------------------------
4133
4134#Method void drawImageRect(const sk_sp<SkImage>& image, const SkRect& src, const SkRect& dst,
4135 const SkPaint* paint,
Mike Klein9ff8c8c2018-02-07 01:58:51 +00004136 SrcRectConstraint constraint = kStrict_SrcRectConstraint)
Cary Clarkab2621d2018-01-30 10:08:57 -05004137#In Draw_Image
Cary Clark78de7512018-02-07 07:27:09 -05004138#In Draw
Cary Clark8032b982017-07-28 11:04:54 -04004139Draw Rect src of Image image, scaled and translated to fill Rect dst.
4140Additionally transform draw using Clip, Matrix, and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004141
Cary Clarkbad5ad72017-08-03 17:14:08 -04004142If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4143Blend_Mode, and Draw_Looper. If image is kAlpha_8_SkColorType, apply Shader.
4144If paint contains Mask_Filter, generate mask from image bounds.
4145
4146If generated mask extends beyond image bounds, replicate image edge colors, just
4147as Shader made from SkImage::makeShader with SkShader::kClamp_TileMode set
Cary Clarkbc5697d2017-10-04 14:31:33 -04004148replicates the image edge color when it samples outside of its bounds.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004149
4150constraint set to kStrict_SrcRectConstraint limits Paint Filter_Quality to
4151sample within src; set to kFast_SrcRectConstraint allows sampling outside to
4152improve performance.
4153
4154#Param image Image containing pixels, dimensions, and format ##
4155#Param src source Rect of image to draw from ##
4156#Param dst destination Rect of image to draw to ##
4157#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4158 and so on; or nullptr
4159##
4160#Param constraint filter strictly within src or draw faster ##
Cary Clark8032b982017-07-28 11:04:54 -04004161
4162#Example
4163#Height 64
4164#Description
4165 Canvas scales and translates; transformation from src to dst also scales.
4166 The two matrices are concatenated to create the final transformation.
4167##
Cary Clarkbad5ad72017-08-03 17:14:08 -04004168void draw(SkCanvas* canvas) {
4169 uint32_t pixels[][2] = { { SK_ColorBLACK, SK_ColorWHITE },
4170 { SK_ColorWHITE, SK_ColorBLACK } };
4171 SkBitmap bitmap;
Mike Klein9ff8c8c2018-02-07 01:58:51 +00004172 bitmap.installPixels(SkImageInfo::MakeN32Premul(2, 2),
Cary Clarkbad5ad72017-08-03 17:14:08 -04004173 (void*) pixels, sizeof(pixels[0]));
4174 sk_sp<SkImage> image = SkImage::MakeFromBitmap(bitmap);
4175 SkPaint paint;
4176 canvas->scale(4, 4);
4177 for (auto alpha : { 50, 100, 150, 255 } ) {
4178 paint.setAlpha(alpha);
4179 canvas->drawImageRect(image, SkRect::MakeWH(2, 2), SkRect::MakeWH(8, 8), &paint);
4180 canvas->translate(8, 0);
4181 }
4182}
Cary Clark8032b982017-07-28 11:04:54 -04004183##
4184
Cary Clark2ade9972017-11-02 17:49:34 -04004185#SeeAlso SrcRectConstraint drawImage drawImageLattice drawImageNine
Cary Clark8032b982017-07-28 11:04:54 -04004186
4187##
4188
4189# ------------------------------------------------------------------------------
4190
4191#Method void drawImageRect(const sk_sp<SkImage>& image, const SkIRect& isrc, const SkRect& dst,
Mike Klein9ff8c8c2018-02-07 01:58:51 +00004192 const SkPaint* paint, SrcRectConstraint constraint = kStrict_SrcRectConstraint)
Cary Clarkab2621d2018-01-30 10:08:57 -05004193#In Draw_Image
Cary Clark78de7512018-02-07 07:27:09 -05004194#In Draw
Cary Clark8032b982017-07-28 11:04:54 -04004195Draw IRect isrc of Image image, scaled and translated to fill Rect dst.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004196isrc is on integer pixel boundaries; dst may include fractional boundaries.
Cary Clark8032b982017-07-28 11:04:54 -04004197Additionally transform draw using Clip, Matrix, and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004198
Cary Clarkbad5ad72017-08-03 17:14:08 -04004199If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4200Blend_Mode, and Draw_Looper. If image is kAlpha_8_SkColorType, apply Shader.
4201If paint contains Mask_Filter, generate mask from image bounds.
4202
4203If generated mask extends beyond image bounds, replicate image edge colors, just
4204as Shader made from SkImage::makeShader with SkShader::kClamp_TileMode set
Cary Clarkbc5697d2017-10-04 14:31:33 -04004205replicates the image edge color when it samples outside of its bounds.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004206
4207constraint set to kStrict_SrcRectConstraint limits Paint Filter_Quality to
Cary Clarkce101242017-09-01 15:51:02 -04004208sample within image; set to kFast_SrcRectConstraint allows sampling outside to
Cary Clarkbad5ad72017-08-03 17:14:08 -04004209improve performance.
4210
4211#Param image Image containing pixels, dimensions, and format ##
4212#Param isrc source IRect of image to draw from ##
4213#Param dst destination Rect of image to draw to ##
4214#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4215 and so on; or nullptr
4216##
Cary Clarkce101242017-09-01 15:51:02 -04004217#Param constraint filter strictly within image or draw faster ##
Cary Clark8032b982017-07-28 11:04:54 -04004218
4219#Example
4220#Height 64
Cary Clarkbad5ad72017-08-03 17:14:08 -04004221void draw(SkCanvas* canvas) {
4222 uint32_t pixels[][2] = { { 0x00000000, 0x55555555},
4223 { 0xAAAAAAAA, 0xFFFFFFFF} };
4224 SkBitmap bitmap;
Mike Klein9ff8c8c2018-02-07 01:58:51 +00004225 bitmap.installPixels(SkImageInfo::MakeN32Premul(2, 2),
Cary Clarkbad5ad72017-08-03 17:14:08 -04004226 (void*) pixels, sizeof(pixels[0]));
4227 sk_sp<SkImage> image = SkImage::MakeFromBitmap(bitmap);
4228 SkPaint paint;
4229 canvas->scale(4, 4);
4230 for (auto color : { SK_ColorRED, SK_ColorBLUE, SK_ColorGREEN } ) {
4231 paint.setColorFilter(SkColorFilter::MakeModeFilter(color, SkBlendMode::kPlus));
4232 canvas->drawImageRect(image, SkIRect::MakeWH(2, 2), SkRect::MakeWH(8, 8), &paint);
4233 canvas->translate(8, 0);
4234 }
Cary Clark8032b982017-07-28 11:04:54 -04004235}
4236##
4237
Cary Clark2ade9972017-11-02 17:49:34 -04004238#SeeAlso SrcRectConstraint drawImage drawImageLattice drawImageNine
4239
Cary Clark8032b982017-07-28 11:04:54 -04004240##
4241
4242# ------------------------------------------------------------------------------
4243
4244#Method void drawImageRect(const sk_sp<SkImage>& image, const SkRect& dst, const SkPaint* paint,
Mike Klein9ff8c8c2018-02-07 01:58:51 +00004245 SrcRectConstraint constraint = kStrict_SrcRectConstraint)
Cary Clarkab2621d2018-01-30 10:08:57 -05004246#In Draw_Image
Cary Clark78de7512018-02-07 07:27:09 -05004247#In Draw
Cary Clark8032b982017-07-28 11:04:54 -04004248Draw Image image, scaled and translated to fill Rect dst,
4249using Clip, Matrix, and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004250
Cary Clarkbad5ad72017-08-03 17:14:08 -04004251If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4252Blend_Mode, and Draw_Looper. If image is kAlpha_8_SkColorType, apply Shader.
4253If paint contains Mask_Filter, generate mask from image bounds.
4254
4255If generated mask extends beyond image bounds, replicate image edge colors, just
4256as Shader made from SkImage::makeShader with SkShader::kClamp_TileMode set
Cary Clarkbc5697d2017-10-04 14:31:33 -04004257replicates the image edge color when it samples outside of its bounds.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004258
4259constraint set to kStrict_SrcRectConstraint limits Paint Filter_Quality to
Cary Clarkce101242017-09-01 15:51:02 -04004260sample within image; set to kFast_SrcRectConstraint allows sampling outside to
Cary Clarkbad5ad72017-08-03 17:14:08 -04004261improve performance.
4262
4263#Param image Image containing pixels, dimensions, and format ##
4264#Param dst destination Rect of image to draw to ##
4265#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4266 and so on; or nullptr
4267##
Cary Clarkce101242017-09-01 15:51:02 -04004268#Param constraint filter strictly within image or draw faster ##
Cary Clark8032b982017-07-28 11:04:54 -04004269
4270#Example
4271#Height 64
Cary Clarkbad5ad72017-08-03 17:14:08 -04004272void draw(SkCanvas* canvas) {
4273 uint32_t pixels[][2] = { { 0x00000000, 0x55550000},
4274 { 0xAAAA0000, 0xFFFF0000} };
4275 SkBitmap bitmap;
Mike Klein9ff8c8c2018-02-07 01:58:51 +00004276 bitmap.installPixels(SkImageInfo::MakeN32Premul(2, 2),
Cary Clarkbad5ad72017-08-03 17:14:08 -04004277 (void*) pixels, sizeof(pixels[0]));
4278 sk_sp<SkImage> image = SkImage::MakeFromBitmap(bitmap);
4279 SkPaint paint;
4280 canvas->scale(4, 4);
4281 for (auto color : { SK_ColorRED, SK_ColorBLUE, SK_ColorGREEN } ) {
4282 paint.setColorFilter(SkColorFilter::MakeModeFilter(color, SkBlendMode::kPlus));
4283 canvas->drawImageRect(image, SkRect::MakeWH(8, 8), &paint);
4284 canvas->translate(8, 0);
4285 }
Cary Clark8032b982017-07-28 11:04:54 -04004286}
4287##
4288
Cary Clark2ade9972017-11-02 17:49:34 -04004289#SeeAlso SrcRectConstraint drawImage drawImageLattice drawImageNine
Cary Clark8032b982017-07-28 11:04:54 -04004290
4291##
4292
4293# ------------------------------------------------------------------------------
4294
4295#Method void drawImageNine(const SkImage* image, const SkIRect& center, const SkRect& dst,
4296 const SkPaint* paint = nullptr)
Cary Clarkab2621d2018-01-30 10:08:57 -05004297#In Draw_Image
Cary Clark78de7512018-02-07 07:27:09 -05004298#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05004299#Line # draws Nine_Patch Image ##
Cary Clark8032b982017-07-28 11:04:54 -04004300
Cary Clarkd0530ba2017-09-14 11:25:39 -04004301Draw Image image stretched proportionally to fit into Rect dst.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004302IRect center divides the image into nine sections: four sides, four corners, and
Cary Clarkce101242017-09-01 15:51:02 -04004303the center. Corners are unmodified or scaled down proportionately if their sides
Cary Clarkbad5ad72017-08-03 17:14:08 -04004304are larger than dst; center and four sides are scaled to fit remaining space, if any.
Cary Clark8032b982017-07-28 11:04:54 -04004305
Cary Clarkbad5ad72017-08-03 17:14:08 -04004306Additionally transform draw using Clip, Matrix, and optional Paint paint.
4307
4308If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4309Blend_Mode, and Draw_Looper. If image is kAlpha_8_SkColorType, apply Shader.
4310If paint contains Mask_Filter, generate mask from image bounds.
4311
4312If generated mask extends beyond image bounds, replicate image edge colors, just
4313as Shader made from SkImage::makeShader with SkShader::kClamp_TileMode set
Cary Clarkbc5697d2017-10-04 14:31:33 -04004314replicates the image edge color when it samples outside of its bounds.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004315
4316#Param image Image containing pixels, dimensions, and format ##
4317#Param center IRect edge of image corners and sides ##
4318#Param dst destination Rect of image to draw to ##
4319#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4320 and so on; or nullptr
4321##
Cary Clark8032b982017-07-28 11:04:54 -04004322
4323#Example
4324#Height 128
4325#Description
4326 The leftmost image is smaller than center; only corners are drawn, all scaled to fit.
Cary Clarkce101242017-09-01 15:51:02 -04004327 The second image equals the size of center; only corners are drawn without scaling.
4328 The remaining images are larger than center. All corners draw without scaling.
4329 The sides and center are scaled if needed to take up the remaining space.
Cary Clark8032b982017-07-28 11:04:54 -04004330##
Cary Clarkbad5ad72017-08-03 17:14:08 -04004331void draw(SkCanvas* canvas) {
4332 SkIRect center = { 20, 10, 50, 40 };
4333 SkBitmap bitmap;
4334 bitmap.allocPixels(SkImageInfo::MakeN32Premul(60, 60));
4335 SkCanvas bitCanvas(bitmap);
4336 SkPaint paint;
4337 SkColor gray = 0xFF000000;
4338 int left = 0;
4339 for (auto right: { center.fLeft, center.fRight, bitmap.width() } ) {
4340 int top = 0;
4341 for (auto bottom: { center.fTop, center.fBottom, bitmap.height() } ) {
4342 paint.setColor(gray);
4343 bitCanvas.drawIRect(SkIRect::MakeLTRB(left, top, right, bottom), paint);
4344 gray += 0x001f1f1f;
4345 top = bottom;
4346 }
Mike Klein9ff8c8c2018-02-07 01:58:51 +00004347 left = right;
Cary Clarkbad5ad72017-08-03 17:14:08 -04004348 }
4349 sk_sp<SkImage> image = SkImage::MakeFromBitmap(bitmap);
4350 SkImage* imagePtr = image.get();
4351 for (auto dest: { 20, 30, 40, 60, 90 } ) {
4352 canvas->drawImageNine(imagePtr, center, SkRect::MakeWH(dest, dest), nullptr);
4353 canvas->translate(dest + 4, 0);
4354 }
Cary Clark8032b982017-07-28 11:04:54 -04004355}
4356##
4357
Cary Clark2ade9972017-11-02 17:49:34 -04004358#SeeAlso drawImage drawBitmapNine drawImageLattice drawImageRect
Cary Clark8032b982017-07-28 11:04:54 -04004359
4360##
4361
4362# ------------------------------------------------------------------------------
4363
4364#Method void drawImageNine(const sk_sp<SkImage>& image, const SkIRect& center, const SkRect& dst,
Mike Klein9ff8c8c2018-02-07 01:58:51 +00004365 const SkPaint* paint = nullptr)
Cary Clarkab2621d2018-01-30 10:08:57 -05004366#In Draw_Image
Cary Clark78de7512018-02-07 07:27:09 -05004367#In Draw
Cary Clarkd0530ba2017-09-14 11:25:39 -04004368Draw Image image stretched proportionally to fit into Rect dst.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004369IRect center divides the image into nine sections: four sides, four corners, and
Cary Clarkce101242017-09-01 15:51:02 -04004370the center. Corners are not scaled, or scaled down proportionately if their sides
Cary Clarkbad5ad72017-08-03 17:14:08 -04004371are larger than dst; center and four sides are scaled to fit remaining space, if any.
Cary Clark8032b982017-07-28 11:04:54 -04004372
Cary Clarkbad5ad72017-08-03 17:14:08 -04004373Additionally transform draw using Clip, Matrix, and optional Paint paint.
4374
4375If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4376Blend_Mode, and Draw_Looper. If image is kAlpha_8_SkColorType, apply Shader.
4377If paint contains Mask_Filter, generate mask from image bounds.
4378
4379If generated mask extends beyond image bounds, replicate image edge colors, just
4380as Shader made from SkImage::makeShader with SkShader::kClamp_TileMode set
Cary Clarkbc5697d2017-10-04 14:31:33 -04004381replicates the image edge color when it samples outside of its bounds.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004382
4383#Param image Image containing pixels, dimensions, and format ##
4384#Param center IRect edge of image corners and sides ##
4385#Param dst destination Rect of image to draw to ##
4386#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4387 and so on; or nullptr
4388##
Cary Clark8032b982017-07-28 11:04:54 -04004389
4390#Example
4391#Height 128
4392#Description
4393 The two leftmost images has four corners and sides to the left and right of center.
4394 The leftmost image scales the width of corners proportionately to fit.
Mike Klein9ff8c8c2018-02-07 01:58:51 +00004395 The third and fourth image corners are not scaled; the sides and center are scaled to
Cary Clark8032b982017-07-28 11:04:54 -04004396 fill the remaining space.
4397 The rightmost image has four corners scaled vertically to fit, and uses sides above
4398 and below center to fill the remaining space.
4399##
Cary Clarkbad5ad72017-08-03 17:14:08 -04004400void draw(SkCanvas* canvas) {
4401 SkIRect center = { 20, 10, 50, 40 };
4402 SkBitmap bitmap;
4403 bitmap.allocPixels(SkImageInfo::MakeN32Premul(60, 60));
4404 SkCanvas bitCanvas(bitmap);
4405 SkPaint paint;
4406 SkColor gray = 0xFF000000;
4407 int left = 0;
4408 for (auto right: { center.fLeft, center.fRight, bitmap.width() } ) {
4409 int top = 0;
4410 for (auto bottom: { center.fTop, center.fBottom, bitmap.height() } ) {
4411 paint.setColor(gray);
4412 bitCanvas.drawIRect(SkIRect::MakeLTRB(left, top, right, bottom), paint);
4413 gray += 0x001f1f1f;
4414 top = bottom;
4415 }
Mike Klein9ff8c8c2018-02-07 01:58:51 +00004416 left = right;
Cary Clarkbad5ad72017-08-03 17:14:08 -04004417 }
4418 sk_sp<SkImage> image = SkImage::MakeFromBitmap(bitmap);
4419 for (auto dest: { 20, 30, 40, 60, 90 } ) {
4420 canvas->drawImageNine(image, center, SkRect::MakeWH(dest, 110 - dest), nullptr);
4421 canvas->translate(dest + 4, 0);
4422 }
Cary Clark8032b982017-07-28 11:04:54 -04004423}
4424##
4425
Cary Clark2ade9972017-11-02 17:49:34 -04004426#SeeAlso drawImage drawBitmapNine drawImageLattice drawImageRect
Cary Clark8032b982017-07-28 11:04:54 -04004427
4428##
4429
4430# ------------------------------------------------------------------------------
4431
4432#Method void drawBitmap(const SkBitmap& bitmap, SkScalar left, SkScalar top,
Cary Clark73fa9722017-08-29 17:36:51 -04004433 const SkPaint* paint = nullptr)
Cary Clarkab2621d2018-01-30 10:08:57 -05004434#In Draw_Image
Cary Clark78de7512018-02-07 07:27:09 -05004435#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05004436#Line # draws Bitmap at (x, y) position ##
Cary Clark8032b982017-07-28 11:04:54 -04004437
4438Draw Bitmap bitmap, with its top-left corner at (left, top),
4439using Clip, Matrix, and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004440
Cary Clarka560c472017-11-27 10:44:06 -05004441If Paint paint is not nullptr, apply Color_Filter, Color_Alpha, Image_Filter,
Cary Clarkbad5ad72017-08-03 17:14:08 -04004442Blend_Mode, and Draw_Looper. If bitmap is kAlpha_8_SkColorType, apply Shader.
4443If paint contains Mask_Filter, generate mask from bitmap bounds.
4444
4445If generated mask extends beyond bitmap bounds, replicate bitmap edge colors,
4446just as Shader made from SkShader::MakeBitmapShader with
Cary Clarkbc5697d2017-10-04 14:31:33 -04004447SkShader::kClamp_TileMode set replicates the bitmap edge color when it samples
Mike Klein9ff8c8c2018-02-07 01:58:51 +00004448outside of its bounds.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004449
4450#Param bitmap Bitmap containing pixels, dimensions, and format ##
4451#Param left left side of bitmap ##
4452#Param top top side of bitmap ##
4453#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4454 and so on; or nullptr
4455##
Cary Clark8032b982017-07-28 11:04:54 -04004456
4457#Example
4458#Height 64
Cary Clarkbad5ad72017-08-03 17:14:08 -04004459void draw(SkCanvas* canvas) {
4460 uint8_t pixels[][8] = { { 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00},
4461 { 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00},
4462 { 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00},
4463 { 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF},
4464 { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
4465 { 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00},
4466 { 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0x00},
4467 { 0xFF, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0xFF} };
4468 SkBitmap bitmap;
Mike Klein9ff8c8c2018-02-07 01:58:51 +00004469 bitmap.installPixels(SkImageInfo::MakeA8(8, 8),
Cary Clarkbad5ad72017-08-03 17:14:08 -04004470 (void*) pixels, sizeof(pixels[0]));
4471 SkPaint paint;
4472 canvas->scale(4, 4);
4473 for (auto color : { SK_ColorRED, SK_ColorBLUE, 0xFF007F00} ) {
4474 paint.setColor(color);
4475 canvas->drawBitmap(bitmap, 0, 0, &paint);
4476 canvas->translate(12, 0);
4477 }
Cary Clark8032b982017-07-28 11:04:54 -04004478}
4479##
4480
Cary Clark2ade9972017-11-02 17:49:34 -04004481#SeeAlso drawImage drawBitmapLattice drawBitmapNine drawBitmapRect SkBitmap::readPixels SkBitmap::writePixels
Cary Clark8032b982017-07-28 11:04:54 -04004482
4483##
4484
4485# ------------------------------------------------------------------------------
4486
4487#Method void drawBitmapRect(const SkBitmap& bitmap, const SkRect& src, const SkRect& dst,
4488 const SkPaint* paint, SrcRectConstraint constraint = kStrict_SrcRectConstraint)
Cary Clarkab2621d2018-01-30 10:08:57 -05004489#In Draw_Image
Cary Clark78de7512018-02-07 07:27:09 -05004490#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05004491#Line # draws Bitmap, source Rect to destination Rect ##
Cary Clark8032b982017-07-28 11:04:54 -04004492
4493Draw Rect src of Bitmap bitmap, scaled and translated to fill Rect dst.
4494Additionally transform draw using Clip, Matrix, and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004495
Cary Clarkbad5ad72017-08-03 17:14:08 -04004496If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4497Blend_Mode, and Draw_Looper. If bitmap is kAlpha_8_SkColorType, apply Shader.
4498If paint contains Mask_Filter, generate mask from bitmap bounds.
4499
4500If generated mask extends beyond bitmap bounds, replicate bitmap edge colors,
4501just as Shader made from SkShader::MakeBitmapShader with
Cary Clarkbc5697d2017-10-04 14:31:33 -04004502SkShader::kClamp_TileMode set replicates the bitmap edge color when it samples
Cary Clarkbad5ad72017-08-03 17:14:08 -04004503outside of its bounds.
4504
4505constraint set to kStrict_SrcRectConstraint limits Paint Filter_Quality to
4506sample within src; set to kFast_SrcRectConstraint allows sampling outside to
4507improve performance.
4508
4509#Param bitmap Bitmap containing pixels, dimensions, and format ##
4510#Param src source Rect of image to draw from ##
4511#Param dst destination Rect of image to draw to ##
4512#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4513 and so on; or nullptr
4514##
4515#Param constraint filter strictly within src or draw faster ##
Cary Clark8032b982017-07-28 11:04:54 -04004516
4517#Example
4518#Height 64
Cary Clarkbad5ad72017-08-03 17:14:08 -04004519void draw(SkCanvas* canvas) {
4520 uint8_t pixels[][8] = { { 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00},
4521 { 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00},
4522 { 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00},
4523 { 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF},
4524 { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
4525 { 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00},
4526 { 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00},
4527 { 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00} };
4528 SkBitmap bitmap;
Mike Klein9ff8c8c2018-02-07 01:58:51 +00004529 bitmap.installPixels(SkImageInfo::MakeA8(8, 8),
Cary Clarkbad5ad72017-08-03 17:14:08 -04004530 (void*) pixels, sizeof(pixels[0]));
4531 SkPaint paint;
Cary Clark681287e2018-03-16 11:34:15 -04004532 paint.setMaskFilter(SkMaskFilter::MakeBlur(kSolid_SkBlurStyle, 6));
Cary Clarkbad5ad72017-08-03 17:14:08 -04004533 for (auto color : { SK_ColorRED, SK_ColorBLUE, 0xFF007F00} ) {
4534 paint.setColor(color);
4535 canvas->drawBitmapRect(bitmap, SkRect::MakeWH(8, 8), SkRect::MakeWH(32, 32), &paint);
4536 canvas->translate(48, 0);
4537 }
Cary Clark8032b982017-07-28 11:04:54 -04004538}
4539##
4540
Cary Clark2ade9972017-11-02 17:49:34 -04004541#SeeAlso drawImageRect drawBitmap drawBitmapLattice drawBitmapNine
Cary Clark8032b982017-07-28 11:04:54 -04004542
4543##
4544
4545# ------------------------------------------------------------------------------
4546
4547#Method void drawBitmapRect(const SkBitmap& bitmap, const SkIRect& isrc, const SkRect& dst,
4548 const SkPaint* paint, SrcRectConstraint constraint = kStrict_SrcRectConstraint)
Cary Clarkab2621d2018-01-30 10:08:57 -05004549#In Draw_Image
Cary Clark78de7512018-02-07 07:27:09 -05004550#In Draw
Cary Clark8032b982017-07-28 11:04:54 -04004551Draw IRect isrc of Bitmap bitmap, scaled and translated to fill Rect dst.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004552isrc is on integer pixel boundaries; dst may include fractional boundaries.
Cary Clark8032b982017-07-28 11:04:54 -04004553Additionally transform draw using Clip, Matrix, and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004554
Cary Clarkbad5ad72017-08-03 17:14:08 -04004555If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4556Blend_Mode, and Draw_Looper. If bitmap is kAlpha_8_SkColorType, apply Shader.
4557If paint contains Mask_Filter, generate mask from bitmap bounds.
4558
4559If generated mask extends beyond bitmap bounds, replicate bitmap edge colors,
4560just as Shader made from SkShader::MakeBitmapShader with
Cary Clarkbc5697d2017-10-04 14:31:33 -04004561SkShader::kClamp_TileMode set replicates the bitmap edge color when it samples
Cary Clarkbad5ad72017-08-03 17:14:08 -04004562outside of its bounds.
4563
4564constraint set to kStrict_SrcRectConstraint limits Paint Filter_Quality to
Cary Clarkce101242017-09-01 15:51:02 -04004565sample within isrc; set to kFast_SrcRectConstraint allows sampling outside to
Cary Clarkbad5ad72017-08-03 17:14:08 -04004566improve performance.
4567
4568#Param bitmap Bitmap containing pixels, dimensions, and format ##
4569#Param isrc source IRect of image to draw from ##
4570#Param dst destination Rect of image to draw to ##
4571#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4572 and so on; or nullptr
4573##
Cary Clarkce101242017-09-01 15:51:02 -04004574#Param constraint sample strictly within isrc, or draw faster ##
Cary Clark8032b982017-07-28 11:04:54 -04004575
4576#Example
4577#Height 64
Cary Clarkbad5ad72017-08-03 17:14:08 -04004578void draw(SkCanvas* canvas) {
4579 uint8_t pixels[][8] = { { 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00},
4580 { 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00},
4581 { 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0xFF},
4582 { 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0xFF},
4583 { 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF},
4584 { 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF},
4585 { 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00},
4586 { 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00} };
4587 SkBitmap bitmap;
Mike Klein9ff8c8c2018-02-07 01:58:51 +00004588 bitmap.installPixels(SkImageInfo::MakeA8(8, 8),
Cary Clarkbad5ad72017-08-03 17:14:08 -04004589 (void*) pixels, sizeof(pixels[0]));
4590 SkPaint paint;
4591 paint.setFilterQuality(kHigh_SkFilterQuality);
4592 for (auto color : { SK_ColorRED, SK_ColorBLUE, 0xFF007F00, 0xFF7f007f} ) {
4593 paint.setColor(color);
4594 canvas->drawBitmapRect(bitmap, SkIRect::MakeWH(8, 8), SkRect::MakeWH(32, 32), &paint);
4595 canvas->translate(48.25f, 0);
4596 }
Cary Clark8032b982017-07-28 11:04:54 -04004597}
4598##
4599
Cary Clark2ade9972017-11-02 17:49:34 -04004600#SeeAlso drawImageRect drawBitmap drawBitmapLattice drawBitmapNine
Cary Clark8032b982017-07-28 11:04:54 -04004601
4602##
4603
4604# ------------------------------------------------------------------------------
4605
4606#Method void drawBitmapRect(const SkBitmap& bitmap, const SkRect& dst, const SkPaint* paint,
4607 SrcRectConstraint constraint = kStrict_SrcRectConstraint)
Cary Clarkab2621d2018-01-30 10:08:57 -05004608#In Draw_Image
Cary Clark78de7512018-02-07 07:27:09 -05004609#In Draw
Cary Clark8032b982017-07-28 11:04:54 -04004610Draw Bitmap bitmap, scaled and translated to fill Rect dst.
Cary Clarkce101242017-09-01 15:51:02 -04004611bitmap bounds is on integer pixel boundaries; dst may include fractional boundaries.
Cary Clark8032b982017-07-28 11:04:54 -04004612Additionally transform draw using Clip, Matrix, and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004613
Cary Clarkbad5ad72017-08-03 17:14:08 -04004614If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4615Blend_Mode, and Draw_Looper. If bitmap is kAlpha_8_SkColorType, apply Shader.
4616If paint contains Mask_Filter, generate mask from bitmap bounds.
4617
4618If generated mask extends beyond bitmap bounds, replicate bitmap edge colors,
4619just as Shader made from SkShader::MakeBitmapShader with
Cary Clarkbc5697d2017-10-04 14:31:33 -04004620SkShader::kClamp_TileMode set replicates the bitmap edge color when it samples
Cary Clarkbad5ad72017-08-03 17:14:08 -04004621outside of its bounds.
4622
4623constraint set to kStrict_SrcRectConstraint limits Paint Filter_Quality to
Cary Clarkce101242017-09-01 15:51:02 -04004624sample within bitmap; set to kFast_SrcRectConstraint allows sampling outside to
Cary Clarkbad5ad72017-08-03 17:14:08 -04004625improve performance.
4626
4627#Param bitmap Bitmap containing pixels, dimensions, and format ##
4628#Param dst destination Rect of image to draw to ##
4629#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4630 and so on; or nullptr
4631##
Cary Clarkce101242017-09-01 15:51:02 -04004632#Param constraint filter strictly within bitmap or draw faster ##
Cary Clark8032b982017-07-28 11:04:54 -04004633
4634#Example
4635#Height 64
Cary Clarkbad5ad72017-08-03 17:14:08 -04004636void draw(SkCanvas* canvas) {
4637 uint32_t pixels[][2] = { { 0x00000000, 0x55550000},
4638 { 0xAAAA0000, 0xFFFF0000} };
4639 SkBitmap bitmap;
Mike Klein9ff8c8c2018-02-07 01:58:51 +00004640 bitmap.installPixels(SkImageInfo::MakeN32Premul(2, 2),
Cary Clarkbad5ad72017-08-03 17:14:08 -04004641 (void*) pixels, sizeof(pixels[0]));
4642 SkPaint paint;
4643 canvas->scale(4, 4);
4644 for (auto color : { SK_ColorRED, SK_ColorBLUE, SK_ColorGREEN } ) {
4645 paint.setColorFilter(SkColorFilter::MakeModeFilter(color, SkBlendMode::kPlus));
4646 canvas->drawBitmapRect(bitmap, SkRect::MakeWH(8, 8), &paint);
4647 canvas->translate(8, 0);
4648 }
Cary Clark8032b982017-07-28 11:04:54 -04004649}
4650##
4651
Cary Clark2ade9972017-11-02 17:49:34 -04004652#SeeAlso drawImageRect drawBitmap drawBitmapLattice drawBitmapNine
Cary Clark8032b982017-07-28 11:04:54 -04004653
4654##
4655
4656# ------------------------------------------------------------------------------
4657
4658#Method void drawBitmapNine(const SkBitmap& bitmap, const SkIRect& center, const SkRect& dst,
Cary Clark73fa9722017-08-29 17:36:51 -04004659 const SkPaint* paint = nullptr)
Cary Clarkab2621d2018-01-30 10:08:57 -05004660#In Draw_Image
Cary Clark78de7512018-02-07 07:27:09 -05004661#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05004662#Line # draws Nine_Patch Bitmap ##
Cary Clark8032b982017-07-28 11:04:54 -04004663
Cary Clarkd0530ba2017-09-14 11:25:39 -04004664Draw Bitmap bitmap stretched proportionally to fit into Rect dst.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004665IRect center divides the bitmap into nine sections: four sides, four corners,
Cary Clarkce101242017-09-01 15:51:02 -04004666and the center. Corners are not scaled, or scaled down proportionately if their
Cary Clarkbad5ad72017-08-03 17:14:08 -04004667sides are larger than dst; center and four sides are scaled to fit remaining
4668space, if any.
Cary Clark8032b982017-07-28 11:04:54 -04004669
Cary Clarkbad5ad72017-08-03 17:14:08 -04004670Additionally transform draw using Clip, Matrix, and optional Paint paint.
4671
4672If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4673Blend_Mode, and Draw_Looper. If bitmap is kAlpha_8_SkColorType, apply Shader.
4674If paint contains Mask_Filter, generate mask from bitmap bounds.
4675
4676If generated mask extends beyond bitmap bounds, replicate bitmap edge colors,
4677just as Shader made from SkShader::MakeBitmapShader with
Cary Clarkbc5697d2017-10-04 14:31:33 -04004678SkShader::kClamp_TileMode set replicates the bitmap edge color when it samples
Cary Clarkbad5ad72017-08-03 17:14:08 -04004679outside of its bounds.
4680
4681#Param bitmap Bitmap containing pixels, dimensions, and format ##
4682#Param center IRect edge of image corners and sides ##
4683#Param dst destination Rect of image to draw to ##
4684#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4685 and so on; or nullptr
4686##
Cary Clark8032b982017-07-28 11:04:54 -04004687
4688#Example
4689#Height 128
4690#Description
4691 The two leftmost bitmap draws has four corners and sides to the left and right of center.
4692 The leftmost bitmap draw scales the width of corners proportionately to fit.
Mike Klein9ff8c8c2018-02-07 01:58:51 +00004693 The third and fourth draw corners are not scaled; the sides and center are scaled to
Cary Clark8032b982017-07-28 11:04:54 -04004694 fill the remaining space.
4695 The rightmost bitmap draw has four corners scaled vertically to fit, and uses sides above
4696 and below center to fill the remaining space.
4697##
Cary Clarkbad5ad72017-08-03 17:14:08 -04004698void draw(SkCanvas* canvas) {
4699 SkIRect center = { 20, 10, 50, 40 };
4700 SkBitmap bitmap;
4701 bitmap.allocPixels(SkImageInfo::MakeN32Premul(60, 60));
4702 SkCanvas bitCanvas(bitmap);
4703 SkPaint paint;
4704 SkColor gray = 0xFF000000;
4705 int left = 0;
4706 for (auto right: { center.fLeft, center.fRight, bitmap.width() } ) {
4707 int top = 0;
4708 for (auto bottom: { center.fTop, center.fBottom, bitmap.height() } ) {
4709 paint.setColor(gray);
4710 bitCanvas.drawIRect(SkIRect::MakeLTRB(left, top, right, bottom), paint);
4711 gray += 0x001f1f1f;
4712 top = bottom;
4713 }
Mike Klein9ff8c8c2018-02-07 01:58:51 +00004714 left = right;
Cary Clarkbad5ad72017-08-03 17:14:08 -04004715 }
4716 for (auto dest: { 20, 30, 40, 60, 90 } ) {
4717 canvas->drawBitmapNine(bitmap, center, SkRect::MakeWH(dest, 110 - dest), nullptr);
4718 canvas->translate(dest + 4, 0);
4719 }
Cary Clark8032b982017-07-28 11:04:54 -04004720}
4721##
4722
Cary Clark2ade9972017-11-02 17:49:34 -04004723#SeeAlso drawImageNine drawBitmap drawBitmapLattice drawBitmapRect
Cary Clark8032b982017-07-28 11:04:54 -04004724
4725##
4726
4727# ------------------------------------------------------------------------------
4728#Struct Lattice
Cary Clark08895c42018-02-01 09:37:32 -05004729#Line # divides Bitmap or Image into a rectangular grid ##
Cary Clark8032b982017-07-28 11:04:54 -04004730#Code
4731 struct Lattice {
Cary Clark2f466242017-12-11 16:03:17 -05004732 enum RectType ...
Cary Clark8032b982017-07-28 11:04:54 -04004733
Cary Clark2f466242017-12-11 16:03:17 -05004734 const int* fXDivs;
4735 const int* fYDivs;
4736 const RectType* fRectTypes;
4737 int fXCount;
4738 int fYCount;
4739 const SkIRect* fBounds;
4740 const SkColor* fColors;
Cary Clark8032b982017-07-28 11:04:54 -04004741 };
4742##
4743
Cary Clark154beea2017-10-26 07:58:48 -04004744 Lattice divides Bitmap or Image into a rectangular grid.
4745 Grid entries on even columns and even rows are fixed; these entries are
4746 always drawn at their original size if the destination is large enough.
4747 If the destination side is too small to hold the fixed entries, all fixed
4748 entries are proportionately scaled down to fit.
4749 The grid entries not on even columns and rows are scaled to fit the
4750 remaining space, if any.
4751
Cary Clark2f466242017-12-11 16:03:17 -05004752 #Enum RectType
Cary Clark8032b982017-07-28 11:04:54 -04004753 #Code
Cary Clark2f466242017-12-11 16:03:17 -05004754 enum RectType : uint8_t {
4755 kDefault = 0,
4756 kTransparent,
4757 kFixedColor,
Cary Clark8032b982017-07-28 11:04:54 -04004758 };
4759 ##
4760
Cary Clark2f466242017-12-11 16:03:17 -05004761 Optional setting per rectangular grid entry to make it transparent,
4762 or to fill the grid entry with a color.
Cary Clark8032b982017-07-28 11:04:54 -04004763
Cary Clark2f466242017-12-11 16:03:17 -05004764 #Const kDefault 0
4765 Draws Bitmap into lattice rectangle.
4766 ##
4767
4768 #Const kTransparent 1
4769 Skips lattice rectangle by making it transparent.
4770 ##
4771
4772 #Const kFixedColor 2
4773 Draws one of fColors into lattice rectangle.
Cary Clark8032b982017-07-28 11:04:54 -04004774 ##
4775 ##
4776
4777 #Member const int* fXDivs
4778 Array of x-coordinates that divide the bitmap vertically.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004779 Array entries must be unique, increasing, greater than or equal to
4780 fBounds left edge, and less than fBounds right edge.
4781 Set the first element to fBounds left to collapse the left column of
4782 fixed grid entries.
Cary Clark8032b982017-07-28 11:04:54 -04004783 ##
4784
4785 #Member const int* fYDivs
4786 Array of y-coordinates that divide the bitmap horizontally.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004787 Array entries must be unique, increasing, greater than or equal to
4788 fBounds top edge, and less than fBounds bottom edge.
4789 Set the first element to fBounds top to collapse the top row of fixed
4790 grid entries.
Cary Clark8032b982017-07-28 11:04:54 -04004791 ##
4792
Cary Clark2f466242017-12-11 16:03:17 -05004793 #Member const RectType* fRectTypes
4794 Optional array of fill types, one per rectangular grid entry:
Cary Clarkbad5ad72017-08-03 17:14:08 -04004795 array length must be
4796 #Formula
4797 (fXCount + 1) * (fYCount + 1)
4798 ##
4799 .
Cary Clark6fc50412017-09-21 12:31:06 -04004800
Cary Clark2f466242017-12-11 16:03:17 -05004801 Each RectType is one of: kDefault, kTransparent, kFixedColor.
4802
Cary Clark8032b982017-07-28 11:04:54 -04004803 Array entries correspond to the rectangular grid entries, ascending
4804 left to right and then top to bottom.
4805 ##
4806
4807 #Member int fXCount
Cary Clarkbad5ad72017-08-03 17:14:08 -04004808 Number of entries in fXDivs array; one less than the number of
4809 horizontal divisions.
Cary Clark8032b982017-07-28 11:04:54 -04004810 ##
4811
4812 #Member int fYCount
Cary Clarkbad5ad72017-08-03 17:14:08 -04004813 Number of entries in fYDivs array; one less than the number of vertical
4814 divisions.
Cary Clark8032b982017-07-28 11:04:54 -04004815 ##
4816
4817 #Member const SkIRect* fBounds
4818 Optional subset IRect source to draw from.
4819 If nullptr, source bounds is dimensions of Bitmap or Image.
4820 ##
4821
Cary Clark2f466242017-12-11 16:03:17 -05004822 #Member const SkColor* fColors
4823 Optional array of colors, one per rectangular grid entry.
4824 Array length must be
4825 #Formula
4826 (fXCount + 1) * (fYCount + 1)
4827 ##
4828 .
4829
4830 Array entries correspond to the rectangular grid entries, ascending
4831 left to right, then top to bottom.
4832 ##
4833
Cary Clark8032b982017-07-28 11:04:54 -04004834#Struct Lattice ##
4835
4836#Method void drawBitmapLattice(const SkBitmap& bitmap, const Lattice& lattice, const SkRect& dst,
4837 const SkPaint* paint = nullptr)
Cary Clarkab2621d2018-01-30 10:08:57 -05004838#In Draw_Image
Cary Clark78de7512018-02-07 07:27:09 -05004839#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05004840#Line # draws proportionally stretched Bitmap ##
Cary Clark8032b982017-07-28 11:04:54 -04004841
Cary Clarkd0530ba2017-09-14 11:25:39 -04004842Draw Bitmap bitmap stretched proportionally to fit into Rect dst.
Cary Clark8032b982017-07-28 11:04:54 -04004843
4844Lattice lattice divides bitmap into a rectangular grid.
4845Each intersection of an even-numbered row and column is fixed; like the corners
Cary Clarkbad5ad72017-08-03 17:14:08 -04004846of drawBitmapNine, fixed lattice elements never scale larger than their initial
Cary Clarkbc5697d2017-10-04 14:31:33 -04004847size and shrink proportionately when all fixed elements exceed the bitmap
Cary Clarkbad5ad72017-08-03 17:14:08 -04004848dimension. All other grid elements scale to fill the available space, if any.
Cary Clark8032b982017-07-28 11:04:54 -04004849
4850Additionally transform draw using Clip, Matrix, and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004851
Cary Clarkbad5ad72017-08-03 17:14:08 -04004852If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4853Blend_Mode, and Draw_Looper. If bitmap is kAlpha_8_SkColorType, apply Shader.
4854If paint contains Mask_Filter, generate mask from bitmap bounds.
4855
4856If generated mask extends beyond bitmap bounds, replicate bitmap edge colors,
4857just as Shader made from SkShader::MakeBitmapShader with
Cary Clarkbc5697d2017-10-04 14:31:33 -04004858SkShader::kClamp_TileMode set replicates the bitmap edge color when it samples
Cary Clarkbad5ad72017-08-03 17:14:08 -04004859outside of its bounds.
4860
4861#Param bitmap Bitmap containing pixels, dimensions, and format ##
4862#Param lattice division of bitmap into fixed and variable rectangles ##
4863#Param dst destination Rect of image to draw to ##
4864#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4865 and so on; or nullptr
4866##
Cary Clark8032b982017-07-28 11:04:54 -04004867
4868#Example
4869#Height 128
4870#Description
4871 The two leftmost bitmap draws has four corners and sides to the left and right of center.
4872 The leftmost bitmap draw scales the width of corners proportionately to fit.
Mike Klein9ff8c8c2018-02-07 01:58:51 +00004873 The third and fourth draw corners are not scaled; the sides are scaled to
Cary Clark8032b982017-07-28 11:04:54 -04004874 fill the remaining space; the center is transparent.
4875 The rightmost bitmap draw has four corners scaled vertically to fit, and uses sides above
4876 and below center to fill the remaining space.
4877##
Cary Clarkbad5ad72017-08-03 17:14:08 -04004878void draw(SkCanvas* canvas) {
4879 SkIRect center = { 20, 10, 50, 40 };
4880 SkBitmap bitmap;
4881 bitmap.allocPixels(SkImageInfo::MakeN32Premul(60, 60));
4882 SkCanvas bitCanvas(bitmap);
4883 SkPaint paint;
4884 SkColor gray = 0xFF000000;
4885 int left = 0;
4886 for (auto right: { center.fLeft, center.fRight, bitmap.width() } ) {
4887 int top = 0;
4888 for (auto bottom: { center.fTop, center.fBottom, bitmap.height() } ) {
4889 paint.setColor(gray);
4890 bitCanvas.drawIRect(SkIRect::MakeLTRB(left, top, right, bottom), paint);
4891 gray += 0x001f1f1f;
4892 top = bottom;
4893 }
Mike Klein9ff8c8c2018-02-07 01:58:51 +00004894 left = right;
Cary Clarkbad5ad72017-08-03 17:14:08 -04004895 }
4896 const int xDivs[] = { center.fLeft, center.fRight };
4897 const int yDivs[] = { center.fTop, center.fBottom };
Cary Clarkca3ebcd2017-12-12 11:22:38 -05004898 SkCanvas::Lattice::RectType fillTypes[3][3];
4899 memset(fillTypes, 0, sizeof(fillTypes));
4900 fillTypes[1][1] = SkCanvas::Lattice::kTransparent;
4901 SkColor dummy[9]; // temporary pending bug fix
4902 SkCanvas::Lattice lattice = { xDivs, yDivs, fillTypes[0], SK_ARRAY_COUNT(xDivs),
4903 SK_ARRAY_COUNT(yDivs), nullptr, dummy };
Cary Clarkbad5ad72017-08-03 17:14:08 -04004904 for (auto dest: { 20, 30, 40, 60, 90 } ) {
Cary Clarkca3ebcd2017-12-12 11:22:38 -05004905 canvas->drawBitmapLattice(bitmap, lattice, SkRect::MakeWH(dest, 110 - dest), nullptr);
Cary Clarkbad5ad72017-08-03 17:14:08 -04004906 canvas->translate(dest + 4, 0);
4907 }
Cary Clark8032b982017-07-28 11:04:54 -04004908}
4909##
4910
Cary Clark2ade9972017-11-02 17:49:34 -04004911#SeeAlso drawImageLattice drawBitmap drawBitmapNine Lattice
Cary Clark8032b982017-07-28 11:04:54 -04004912
4913##
4914
4915# ------------------------------------------------------------------------------
4916
4917#Method void drawImageLattice(const SkImage* image, const Lattice& lattice, const SkRect& dst,
4918 const SkPaint* paint = nullptr)
Cary Clarkab2621d2018-01-30 10:08:57 -05004919#In Draw_Image
Cary Clark78de7512018-02-07 07:27:09 -05004920#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05004921#Line # draws proportionally stretched Image ##
Cary Clark8032b982017-07-28 11:04:54 -04004922
Cary Clarkd0530ba2017-09-14 11:25:39 -04004923Draw Image image stretched proportionally to fit into Rect dst.
Cary Clark8032b982017-07-28 11:04:54 -04004924
4925Lattice lattice divides image into a rectangular grid.
4926Each intersection of an even-numbered row and column is fixed; like the corners
Cary Clarkbad5ad72017-08-03 17:14:08 -04004927of drawBitmapNine, fixed lattice elements never scale larger than their initial
Cary Clarkbc5697d2017-10-04 14:31:33 -04004928size and shrink proportionately when all fixed elements exceed the bitmap
Cary Clarkbad5ad72017-08-03 17:14:08 -04004929dimension. All other grid elements scale to fill the available space, if any.
Cary Clark8032b982017-07-28 11:04:54 -04004930
4931Additionally transform draw using Clip, Matrix, and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004932
Cary Clarkbad5ad72017-08-03 17:14:08 -04004933If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4934Blend_Mode, and Draw_Looper. If bitmap is kAlpha_8_SkColorType, apply Shader.
4935If paint contains Mask_Filter, generate mask from bitmap bounds.
4936
4937If generated mask extends beyond bitmap bounds, replicate bitmap edge colors,
4938just as Shader made from SkShader::MakeBitmapShader with
Cary Clarkbc5697d2017-10-04 14:31:33 -04004939SkShader::kClamp_TileMode set replicates the bitmap edge color when it samples
Cary Clarkbad5ad72017-08-03 17:14:08 -04004940outside of its bounds.
4941
4942#Param image Image containing pixels, dimensions, and format ##
4943#Param lattice division of bitmap into fixed and variable rectangles ##
4944#Param dst destination Rect of image to draw to ##
4945#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4946 and so on; or nullptr
4947##
Cary Clark8032b982017-07-28 11:04:54 -04004948
4949#Example
4950#Height 128
4951#Description
4952 The leftmost image is smaller than center; only corners are drawn, all scaled to fit.
Cary Clarkce101242017-09-01 15:51:02 -04004953 The second image equals the size of center; only corners are drawn without scaling.
4954 The remaining images are larger than center. All corners draw without scaling. The sides
Cary Clark8032b982017-07-28 11:04:54 -04004955 are scaled if needed to take up the remaining space; the center is transparent.
4956##
Cary Clarkbad5ad72017-08-03 17:14:08 -04004957void draw(SkCanvas* canvas) {
4958 SkIRect center = { 20, 10, 50, 40 };
4959 SkBitmap bitmap;
4960 bitmap.allocPixels(SkImageInfo::MakeN32Premul(60, 60));
4961 SkCanvas bitCanvas(bitmap);
4962 SkPaint paint;
4963 SkColor gray = 0xFF000000;
4964 int left = 0;
4965 for (auto right: { center.fLeft, center.fRight, bitmap.width() } ) {
4966 int top = 0;
4967 for (auto bottom: { center.fTop, center.fBottom, bitmap.height() } ) {
4968 paint.setColor(gray);
4969 bitCanvas.drawIRect(SkIRect::MakeLTRB(left, top, right, bottom), paint);
4970 gray += 0x001f1f1f;
4971 top = bottom;
4972 }
Mike Klein9ff8c8c2018-02-07 01:58:51 +00004973 left = right;
Cary Clarkbad5ad72017-08-03 17:14:08 -04004974 }
Cary Clarkbad5ad72017-08-03 17:14:08 -04004975 sk_sp<SkImage> image = SkImage::MakeFromBitmap(bitmap);
4976 SkImage* imagePtr = image.get();
4977 for (auto dest: { 20, 30, 40, 60, 90 } ) {
4978 canvas->drawImageNine(imagePtr, center, SkRect::MakeWH(dest, dest), nullptr);
4979 canvas->translate(dest + 4, 0);
4980 }
Cary Clark8032b982017-07-28 11:04:54 -04004981}
4982##
4983
Cary Clark2ade9972017-11-02 17:49:34 -04004984#SeeAlso drawBitmapLattice drawImage drawImageNine Lattice
Cary Clark8032b982017-07-28 11:04:54 -04004985
4986##
4987
Cary Clark08895c42018-02-01 09:37:32 -05004988#Subtopic Draw_Image ##
Cary Clark8032b982017-07-28 11:04:54 -04004989
4990# ------------------------------------------------------------------------------
Cary Clark78de7512018-02-07 07:27:09 -05004991#Subtopic Draw_Text
4992#Populate
4993#Line # draws text into Canvas ##
4994##
Cary Clark8032b982017-07-28 11:04:54 -04004995
4996#Method void drawText(const void* text, size_t byteLength, SkScalar x, SkScalar y,
4997 const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05004998#In Draw_Text
4999#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05005000#Line # draws text at (x, y), using font advance ##
Cary Clark8032b982017-07-28 11:04:54 -04005001
5002Draw text, with origin at (x, y), using Clip, Matrix, and Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04005003
Cary Clarkbc5697d2017-10-04 14:31:33 -04005004text meaning depends on Paint_Text_Encoding; by default, text is encoded as
Cary Clarkbad5ad72017-08-03 17:14:08 -04005005UTF-8.
Cary Clark8032b982017-07-28 11:04:54 -04005006
Cary Clarkbad5ad72017-08-03 17:14:08 -04005007x and y meaning depends on Paint_Text_Align and Paint_Vertical_Text; by default
Cary Clarkbc5697d2017-10-04 14:31:33 -04005008text draws left to right, positioning the first glyph left side bearing at x
Mike Klein9ff8c8c2018-02-07 01:58:51 +00005009and its baseline at y. Text size is affected by Matrix and Paint_Text_Size.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005010
Mike Reed8ad91a92018-01-19 19:09:32 -05005011All elements of paint: Path_Effect, Mask_Filter, Shader,
Cary Clarkbad5ad72017-08-03 17:14:08 -04005012Color_Filter, Image_Filter, and Draw_Looper; apply to text. By default, draws
Cary Clarkce101242017-09-01 15:51:02 -04005013filled 12 point black Glyphs.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005014
Cary Clarkce101242017-09-01 15:51:02 -04005015#Param text character code points or Glyphs drawn ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005016#Param byteLength byte length of text array ##
5017#Param x start of text on x-axis ##
5018#Param y start of text on y-axis ##
5019#Param paint text size, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005020
5021#Example
5022#Height 200
5023#Description
5024 The same text is drawn varying Paint_Text_Size and varying
Mike Klein9ff8c8c2018-02-07 01:58:51 +00005025 Matrix.
Cary Clark8032b982017-07-28 11:04:54 -04005026##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005027void draw(SkCanvas* canvas) {
5028 SkPaint paint;
5029 paint.setAntiAlias(true);
5030 float textSizes[] = { 12, 18, 24, 36 };
5031 for (auto size: textSizes ) {
5032 paint.setTextSize(size);
5033 canvas->drawText("Aa", 2, 10, 20, paint);
5034 canvas->translate(0, size * 2);
5035 }
5036 paint.reset();
5037 paint.setAntiAlias(true);
5038 float yPos = 20;
5039 for (auto size: textSizes ) {
5040 float scale = size / 12.f;
5041 canvas->resetMatrix();
5042 canvas->translate(100, 0);
5043 canvas->scale(scale, scale);
5044 canvas->drawText("Aa", 2, 10 / scale, yPos / scale, paint);
Mike Klein9ff8c8c2018-02-07 01:58:51 +00005045 yPos += size * 2;
Cary Clarkbad5ad72017-08-03 17:14:08 -04005046 }
5047}
Cary Clark8032b982017-07-28 11:04:54 -04005048##
5049
Cary Clark2ade9972017-11-02 17:49:34 -04005050#SeeAlso drawString drawPosText drawPosTextH drawTextBlob drawTextOnPath drawTextRSXform
Cary Clark8032b982017-07-28 11:04:54 -04005051
5052##
5053
5054#Method void drawString(const char* string, SkScalar x, SkScalar y, const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05005055#In Draw_Text
5056#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05005057#Line # draws null terminated string at (x, y) using font advance ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005058Draw null terminated string, with origin at (x, y), using Clip, Matrix, and
Mike Reed9c2916e2018-03-15 13:37:08 -04005059Paint paint. Note that this per-glyph xform does not affect the shader (if present)
5060on the paint, just the glyph's geometry.
Cary Clark8032b982017-07-28 11:04:54 -04005061
Cary Clarkbc5697d2017-10-04 14:31:33 -04005062string meaning depends on Paint_Text_Encoding; by default, strings are encoded
5063as UTF-8. Other values of Paint_Text_Encoding are unlikely to produce the desired
Cary Clarkbad5ad72017-08-03 17:14:08 -04005064results, since zero bytes may be embedded in the string.
Cary Clark8032b982017-07-28 11:04:54 -04005065
Cary Clarkbad5ad72017-08-03 17:14:08 -04005066x and y meaning depends on Paint_Text_Align and Paint_Vertical_Text; by default
Cary Clarkbc5697d2017-10-04 14:31:33 -04005067string draws left to right, positioning the first glyph left side bearing at x
Mike Klein9ff8c8c2018-02-07 01:58:51 +00005068and its baseline at y. Text size is affected by Matrix and Paint_Text_Size.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005069
Mike Reed8ad91a92018-01-19 19:09:32 -05005070All elements of paint: Path_Effect, Mask_Filter, Shader,
Cary Clarkbad5ad72017-08-03 17:14:08 -04005071Color_Filter, Image_Filter, and Draw_Looper; apply to text. By default, draws
Cary Clarkce101242017-09-01 15:51:02 -04005072filled 12 point black Glyphs.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005073
Cary Clarkce101242017-09-01 15:51:02 -04005074#Param string character code points or Glyphs drawn,
Cary Clarkbad5ad72017-08-03 17:14:08 -04005075 ending with a char value of zero
5076##
5077#Param x start of string on x-axis ##
5078#Param y start of string on y-axis ##
5079#Param paint text size, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005080
5081#Example
5082 SkPaint paint;
5083 canvas->drawString("a small hello", 20, 20, paint);
5084##
5085
Cary Clark2ade9972017-11-02 17:49:34 -04005086#SeeAlso drawText drawPosText drawPosTextH drawTextBlob drawTextOnPath drawTextRSXform
Cary Clark8032b982017-07-28 11:04:54 -04005087
5088##
5089
5090#Method void drawString(const SkString& string, SkScalar x, SkScalar y, const SkPaint& paint)
5091
Cary Clarkbad5ad72017-08-03 17:14:08 -04005092Draw null terminated string, with origin at (x, y), using Clip, Matrix, and
5093Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04005094
Cary Clarkbc5697d2017-10-04 14:31:33 -04005095string meaning depends on Paint_Text_Encoding; by default, strings are encoded
5096as UTF-8. Other values of Paint_Text_Encoding are unlikely to produce the desired
Cary Clarkbad5ad72017-08-03 17:14:08 -04005097results, since zero bytes may be embedded in the string.
Cary Clark8032b982017-07-28 11:04:54 -04005098
Cary Clarkbad5ad72017-08-03 17:14:08 -04005099x and y meaning depends on Paint_Text_Align and Paint_Vertical_Text; by default
Cary Clarkbc5697d2017-10-04 14:31:33 -04005100string draws left to right, positioning the first glyph left side bearing at x
Mike Klein9ff8c8c2018-02-07 01:58:51 +00005101and its baseline at y. Text size is affected by Matrix and Paint_Text_Size.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005102
Mike Reed8ad91a92018-01-19 19:09:32 -05005103All elements of paint: Path_Effect, Mask_Filter, Shader,
Cary Clarkbad5ad72017-08-03 17:14:08 -04005104Color_Filter, Image_Filter, and Draw_Looper; apply to text. By default, draws
Cary Clarkce101242017-09-01 15:51:02 -04005105filled 12 point black Glyphs.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005106
Cary Clarkce101242017-09-01 15:51:02 -04005107#Param string character code points or Glyphs drawn,
Cary Clarkbad5ad72017-08-03 17:14:08 -04005108 ending with a char value of zero
5109##
5110#Param x start of string on x-axis ##
5111#Param y start of string on y-axis ##
5112#Param paint text size, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005113
5114#Example
5115 SkPaint paint;
5116 SkString string("a small hello");
5117 canvas->drawString(string, 20, 20, paint);
5118##
5119
Cary Clark2ade9972017-11-02 17:49:34 -04005120#SeeAlso drawText drawPosText drawPosTextH drawTextBlob drawTextOnPath drawTextRSXform
Cary Clark8032b982017-07-28 11:04:54 -04005121
5122##
5123
5124# ------------------------------------------------------------------------------
5125
5126#Method void drawPosText(const void* text, size_t byteLength, const SkPoint pos[],
5127 const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05005128#In Draw_Text
5129#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05005130#Line # draws text at array of (x, y) positions ##
Cary Clark8032b982017-07-28 11:04:54 -04005131
Cary Clarkbad5ad72017-08-03 17:14:08 -04005132Draw each glyph in text with the origin in pos array, using Clip, Matrix, and
Cary Clarkce101242017-09-01 15:51:02 -04005133Paint paint. The number of entries in pos array must match the number of Glyphs
Cary Clarkbad5ad72017-08-03 17:14:08 -04005134described by byteLength of text.
Cary Clark8032b982017-07-28 11:04:54 -04005135
Cary Clarkbc5697d2017-10-04 14:31:33 -04005136text meaning depends on Paint_Text_Encoding; by default, text is encoded as
Cary Clarkbad5ad72017-08-03 17:14:08 -04005137UTF-8. pos elements' meaning depends on Paint_Text_Align and Paint_Vertical_Text;
Cary Clarkbc5697d2017-10-04 14:31:33 -04005138by default each glyph left side bearing is positioned at x and its
Cary Clarkbad5ad72017-08-03 17:14:08 -04005139baseline is positioned at y. Text size is affected by Matrix and
Mike Klein9ff8c8c2018-02-07 01:58:51 +00005140Paint_Text_Size.
Cary Clark8032b982017-07-28 11:04:54 -04005141
Mike Reed8ad91a92018-01-19 19:09:32 -05005142All elements of paint: Path_Effect, Mask_Filter, Shader,
Cary Clarkbad5ad72017-08-03 17:14:08 -04005143Color_Filter, Image_Filter, and Draw_Looper; apply to text. By default, draws
Cary Clarkce101242017-09-01 15:51:02 -04005144filled 12 point black Glyphs.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005145
5146Layout engines such as Harfbuzz typically position each glyph
Cary Clarkbc5697d2017-10-04 14:31:33 -04005147rather than using the font advance widths.
Cary Clark8032b982017-07-28 11:04:54 -04005148
Cary Clarkce101242017-09-01 15:51:02 -04005149#Param text character code points or Glyphs drawn ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005150#Param byteLength byte length of text array ##
5151#Param pos array of glyph origins ##
5152#Param paint text size, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005153
5154#Example
5155#Height 120
Cary Clarkbad5ad72017-08-03 17:14:08 -04005156void draw(SkCanvas* canvas) {
5157 const char hello[] = "HeLLo!";
5158 const SkPoint pos[] = { {40, 100}, {82, 95}, {115, 110}, {130, 95}, {145, 85},
5159 {172, 100} };
5160 SkPaint paint;
5161 paint.setTextSize(60);
5162 canvas->drawPosText(hello, strlen(hello), pos, paint);
Cary Clark8032b982017-07-28 11:04:54 -04005163}
5164##
5165
Cary Clark2ade9972017-11-02 17:49:34 -04005166#SeeAlso drawText drawPosTextH drawTextBlob drawTextOnPath drawTextRSXform
Cary Clark8032b982017-07-28 11:04:54 -04005167
5168##
5169
5170# ------------------------------------------------------------------------------
5171
5172#Method void drawPosTextH(const void* text, size_t byteLength, const SkScalar xpos[], SkScalar constY,
5173 const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05005174#In Draw_Text
5175#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05005176#Line # draws text at x positions with common baseline ##
Cary Clark8032b982017-07-28 11:04:54 -04005177
Cary Clarkbad5ad72017-08-03 17:14:08 -04005178Draw each glyph in text with its (x, y) origin composed from xpos array and
5179constY, using Clip, Matrix, and Paint paint. The number of entries in xpos array
Cary Clarkce101242017-09-01 15:51:02 -04005180must match the number of Glyphs described by byteLength of text.
Cary Clark8032b982017-07-28 11:04:54 -04005181
Cary Clarkbc5697d2017-10-04 14:31:33 -04005182text meaning depends on Paint_Text_Encoding; by default, text is encoded as
Cary Clarkce101242017-09-01 15:51:02 -04005183UTF-8. xpos elements' meaning depends on Paint_Text_Align and Paint_Vertical_Text;
Cary Clarkbc5697d2017-10-04 14:31:33 -04005184by default each glyph left side bearing is positioned at an xpos element and
Cary Clarkbad5ad72017-08-03 17:14:08 -04005185its baseline is positioned at constY. Text size is affected by Matrix and
Mike Klein9ff8c8c2018-02-07 01:58:51 +00005186Paint_Text_Size.
Cary Clark8032b982017-07-28 11:04:54 -04005187
Mike Reed8ad91a92018-01-19 19:09:32 -05005188All elements of paint: Path_Effect, Mask_Filter, Shader,
Cary Clarkbad5ad72017-08-03 17:14:08 -04005189Color_Filter, Image_Filter, and Draw_Looper; apply to text. By default, draws
Cary Clarkce101242017-09-01 15:51:02 -04005190filled 12 point black Glyphs.
Cary Clark8032b982017-07-28 11:04:54 -04005191
Cary Clarkbad5ad72017-08-03 17:14:08 -04005192Layout engines such as Harfbuzz typically position each glyph
Cary Clarkbc5697d2017-10-04 14:31:33 -04005193rather than using the font advance widths if all Glyphs share the same
Cary Clarkbad5ad72017-08-03 17:14:08 -04005194baseline.
5195
Cary Clarkce101242017-09-01 15:51:02 -04005196#Param text character code points or Glyphs drawn ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005197#Param byteLength byte length of text array ##
5198#Param xpos array of x positions, used to position each glyph ##
5199#Param constY shared y coordinate for all of x positions ##
5200#Param paint text size, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005201
5202#Example
5203#Height 40
Cary Clarkbad5ad72017-08-03 17:14:08 -04005204 void draw(SkCanvas* canvas) {
5205 SkScalar xpos[] = { 20, 40, 80, 160 };
5206 SkPaint paint;
5207 canvas->drawPosTextH("XXXX", 4, xpos, 20, paint);
5208 }
Cary Clark8032b982017-07-28 11:04:54 -04005209##
5210
Cary Clark2ade9972017-11-02 17:49:34 -04005211#SeeAlso drawText drawPosText drawTextBlob drawTextOnPath drawTextRSXform
Cary Clark8032b982017-07-28 11:04:54 -04005212
5213##
5214
5215# ------------------------------------------------------------------------------
5216
5217#Method void drawTextOnPathHV(const void* text, size_t byteLength, const SkPath& path, SkScalar hOffset,
5218 SkScalar vOffset, const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05005219#In Draw_Text
5220#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05005221#Line # draws text following Path with offsets ##
Cary Clark8032b982017-07-28 11:04:54 -04005222
5223Draw text on Path path, using Clip, Matrix, and Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04005224
Cary Clarkbad5ad72017-08-03 17:14:08 -04005225Origin of text is at distance hOffset along the path, offset by a perpendicular
5226vector of length vOffset. If the path section corresponding the glyph advance is
5227curved, the glyph is drawn curved to match; control points in the glyph are
Cary Clarkbc5697d2017-10-04 14:31:33 -04005228mapped to projected points parallel to the path. If the text advance is larger
Cary Clarkbad5ad72017-08-03 17:14:08 -04005229than the path length, the excess text is clipped.
5230
Cary Clarkbc5697d2017-10-04 14:31:33 -04005231text meaning depends on Paint_Text_Encoding; by default, text is encoded as
Cary Clarkbad5ad72017-08-03 17:14:08 -04005232UTF-8. Origin meaning depends on Paint_Text_Align and Paint_Vertical_Text; by
Cary Clarkbc5697d2017-10-04 14:31:33 -04005233default text positions the first glyph left side bearing at origin x and its
Mike Klein9ff8c8c2018-02-07 01:58:51 +00005234baseline at origin y. Text size is affected by Matrix and Paint_Text_Size.
Cary Clark8032b982017-07-28 11:04:54 -04005235
Mike Reed8ad91a92018-01-19 19:09:32 -05005236All elements of paint: Path_Effect, Mask_Filter, Shader,
Cary Clarkbad5ad72017-08-03 17:14:08 -04005237Color_Filter, Image_Filter, and Draw_Looper; apply to text. By default, draws
Cary Clarkce101242017-09-01 15:51:02 -04005238filled 12 point black Glyphs.
Cary Clark8032b982017-07-28 11:04:54 -04005239
Cary Clarkce101242017-09-01 15:51:02 -04005240#Param text character code points or Glyphs drawn ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005241#Param byteLength byte length of text array ##
5242#Param path Path providing text baseline ##
5243#Param hOffset distance along path to offset origin ##
5244#Param vOffset offset of text above (if negative) or below (if positive) the path ##
5245#Param paint text size, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005246
5247#Example
Mike Klein9ff8c8c2018-02-07 01:58:51 +00005248 void draw(SkCanvas* canvas) {
Cary Clarkbad5ad72017-08-03 17:14:08 -04005249 const char aero[] = "correo a" "\xC3" "\xA9" "reo";
5250 const size_t len = sizeof(aero) - 1;
5251 SkPath path;
5252 path.addOval({43-26, 43-26, 43+26, 43+26}, SkPath::kCW_Direction, 3);
5253 SkPaint paint;
5254 paint.setTextSize(24);
5255 for (auto offset : { 0, 10, 20 } ) {
5256 canvas->drawTextOnPathHV(aero, len, path, 0, -offset, paint);
5257 canvas->translate(70 + offset, 70 + offset);
5258 }
5259 }
Cary Clark8032b982017-07-28 11:04:54 -04005260##
5261
Cary Clark2ade9972017-11-02 17:49:34 -04005262#SeeAlso drawTextOnPath drawText drawPosTextH drawTextBlob drawTextRSXform
Cary Clark8032b982017-07-28 11:04:54 -04005263
5264##
5265
5266# ------------------------------------------------------------------------------
5267
5268#Method void drawTextOnPath(const void* text, size_t byteLength, const SkPath& path,
5269 const SkMatrix* matrix, const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05005270#In Draw_Text
5271#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05005272#Line # draws text following Path contour ##
Cary Clark8032b982017-07-28 11:04:54 -04005273
5274Draw text on Path path, using Clip, Matrix, and Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04005275
Cary Clarkbad5ad72017-08-03 17:14:08 -04005276Origin of text is at beginning of path offset by matrix, if provided, before it
5277is mapped to path. If the path section corresponding the glyph advance is
5278curved, the glyph is drawn curved to match; control points in the glyph are
Cary Clarkbc5697d2017-10-04 14:31:33 -04005279mapped to projected points parallel to the path. If the text advance is larger
Cary Clarkbad5ad72017-08-03 17:14:08 -04005280than the path length, the excess text is clipped.
5281
Cary Clarkbc5697d2017-10-04 14:31:33 -04005282text meaning depends on Paint_Text_Encoding; by default, text is encoded as
Cary Clarkbad5ad72017-08-03 17:14:08 -04005283UTF-8. Origin meaning depends on Paint_Text_Align and Paint_Vertical_Text; by
Cary Clarkbc5697d2017-10-04 14:31:33 -04005284default text positions the first glyph left side bearing at origin x and its
Mike Klein9ff8c8c2018-02-07 01:58:51 +00005285baseline at origin y. Text size is affected by Matrix and Paint_Text_Size.
Cary Clark8032b982017-07-28 11:04:54 -04005286
Mike Reed8ad91a92018-01-19 19:09:32 -05005287All elements of paint: Path_Effect, Mask_Filter, Shader,
Cary Clarkbad5ad72017-08-03 17:14:08 -04005288Color_Filter, Image_Filter, and Draw_Looper; apply to text. By default, draws
Cary Clarkce101242017-09-01 15:51:02 -04005289filled 12 point black Glyphs.
Cary Clark8032b982017-07-28 11:04:54 -04005290
Cary Clarkce101242017-09-01 15:51:02 -04005291#Param text character code points or Glyphs drawn ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005292#Param byteLength byte length of text array ##
5293#Param path Path providing text baseline ##
Cary Clarkce101242017-09-01 15:51:02 -04005294#Param matrix transform of Glyphs before mapping to path; may be nullptr
Cary Clarka523d2d2017-08-30 08:58:10 -04005295 to use identity Matrix
Cary Clarkbad5ad72017-08-03 17:14:08 -04005296##
5297#Param paint text size, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005298
5299#Example
Mike Klein9ff8c8c2018-02-07 01:58:51 +00005300 void draw(SkCanvas* canvas) {
Cary Clarkbad5ad72017-08-03 17:14:08 -04005301 const char roller[] = "rollercoaster";
5302 const size_t len = sizeof(roller) - 1;
5303 SkPath path;
5304 path.cubicTo(40, -80, 120, 80, 160, -40);
5305 SkPaint paint;
5306 paint.setTextSize(32);
5307 paint.setStyle(SkPaint::kStroke_Style);
5308 SkMatrix matrix;
5309 matrix.setIdentity();
5310 for (int i = 0; i < 3; ++i) {
5311 canvas->translate(25, 60);
5312 canvas->drawPath(path, paint);
5313 canvas->drawTextOnPath(roller, len, path, &matrix, paint);
5314 matrix.preTranslate(0, 10);
5315 }
5316 }
Cary Clark8032b982017-07-28 11:04:54 -04005317##
5318
Cary Clark2ade9972017-11-02 17:49:34 -04005319#SeeAlso drawTextOnPathHV drawText drawPosTextH drawTextBlob drawTextRSXform
Cary Clark8032b982017-07-28 11:04:54 -04005320
5321##
5322
5323# ------------------------------------------------------------------------------
5324
5325#Method void drawTextRSXform(const void* text, size_t byteLength, const SkRSXform xform[],
5326 const SkRect* cullRect, const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05005327#In Draw_Text
5328#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05005329#Line # draws text with array of RSXform ##
Cary Clark8032b982017-07-28 11:04:54 -04005330
5331Draw text, transforming each glyph by the corresponding SkRSXform,
5332using Clip, Matrix, and Paint paint.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005333
Mike Klein9ff8c8c2018-02-07 01:58:51 +00005334RSXform array specifies a separate square scale, rotation, and translation for
Cary Clark8032b982017-07-28 11:04:54 -04005335each glyph.
Cary Clark8032b982017-07-28 11:04:54 -04005336
Cary Clarkbad5ad72017-08-03 17:14:08 -04005337Optional Rect cullRect is a conservative bounds of text, taking into account
Cary Clarkce101242017-09-01 15:51:02 -04005338RSXform and paint. If cullRect is outside of Clip, canvas can skip drawing.
Cary Clark8032b982017-07-28 11:04:54 -04005339
Mike Reed8ad91a92018-01-19 19:09:32 -05005340All elements of paint: Path_Effect, Mask_Filter, Shader,
Cary Clarkbad5ad72017-08-03 17:14:08 -04005341Color_Filter, Image_Filter, and Draw_Looper; apply to text. By default, draws
Cary Clarkce101242017-09-01 15:51:02 -04005342filled 12 point black Glyphs.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005343
Cary Clarkce101242017-09-01 15:51:02 -04005344#Param text character code points or Glyphs drawn ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005345#Param byteLength byte length of text array ##
5346#Param xform RSXform rotates, scales, and translates each glyph individually ##
5347#Param cullRect Rect bounds of text for efficient clipping; or nullptr ##
5348#Param paint text size, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005349
5350#Example
Mike Klein9ff8c8c2018-02-07 01:58:51 +00005351void draw(SkCanvas* canvas) {
Cary Clarkbad5ad72017-08-03 17:14:08 -04005352 const int iterations = 26;
5353 SkRSXform transforms[iterations];
5354 char alphabet[iterations];
5355 SkScalar angle = 0;
5356 SkScalar scale = 1;
5357 for (size_t i = 0; i < SK_ARRAY_COUNT(transforms); ++i) {
5358 const SkScalar s = SkScalarSin(angle) * scale;
5359 const SkScalar c = SkScalarCos(angle) * scale;
5360 transforms[i] = SkRSXform::Make(-c, -s, -s * 16, c * 16);
5361 angle += .45;
5362 scale += .2;
5363 alphabet[i] = 'A' + i;
5364 }
5365 SkPaint paint;
5366 paint.setTextAlign(SkPaint::kCenter_Align);
5367 canvas->translate(110, 138);
5368 canvas->drawTextRSXform(alphabet, sizeof(alphabet), transforms, nullptr, paint);
Cary Clark8032b982017-07-28 11:04:54 -04005369}
5370##
5371
Cary Clark2ade9972017-11-02 17:49:34 -04005372#SeeAlso drawTextOnPath drawTextOnPathHV drawText drawPosText drawTextBlob
Cary Clark8032b982017-07-28 11:04:54 -04005373
5374##
5375
5376# ------------------------------------------------------------------------------
5377
5378#Method void drawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y, const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05005379#In Draw_Text
5380#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05005381#Line # draws text with arrays of positions and Paint ##
Cary Clark8032b982017-07-28 11:04:54 -04005382Draw Text_Blob blob at (x, y), using Clip, Matrix, and Paint paint.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005383
Cary Clarkce101242017-09-01 15:51:02 -04005384blob contains Glyphs, their positions, and paint attributes specific to text:
Cary Clarkbad5ad72017-08-03 17:14:08 -04005385Typeface, Paint_Text_Size, Paint_Text_Scale_X, Paint_Text_Skew_X,
5386Paint_Text_Align, Paint_Hinting, Anti-alias, Paint_Fake_Bold,
5387Font_Embedded_Bitmaps, Full_Hinting_Spacing, LCD_Text, Linear_Text,
5388Subpixel_Text, and Paint_Vertical_Text.
Cary Clark8032b982017-07-28 11:04:54 -04005389
Cary Clark3cd22cc2017-12-01 11:49:58 -05005390Paint_Text_Encoding must be set to SkPaint::kGlyphID_TextEncoding.
5391
Mike Reed8ad91a92018-01-19 19:09:32 -05005392Elements of paint: Path_Effect, Mask_Filter, Shader, Color_Filter,
Cary Clark8032b982017-07-28 11:04:54 -04005393Image_Filter, and Draw_Looper; apply to blob.
5394
Cary Clarkce101242017-09-01 15:51:02 -04005395#Param blob Glyphs, positions, and their paints' text size, typeface, and so on ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005396#Param x horizontal offset applied to blob ##
5397#Param y vertical offset applied to blob ##
5398#Param paint blend, color, stroking, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005399
5400#Example
5401#Height 120
Cary Clarkbad5ad72017-08-03 17:14:08 -04005402 void draw(SkCanvas* canvas) {
Cary Clark2f466242017-12-11 16:03:17 -05005403 SkTextBlobBuilder textBlobBuilder;
5404 const char bunny[] = "/(^x^)\\";
5405 const int len = sizeof(bunny) - 1;
5406 uint16_t glyphs[len];
5407 SkPaint paint;
5408 paint.textToGlyphs(bunny, len, glyphs);
Cary Clark3cd22cc2017-12-01 11:49:58 -05005409 paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
Cary Clark2f466242017-12-11 16:03:17 -05005410 int runs[] = { 3, 1, 3 };
5411 SkPoint textPos = { 20, 100 };
5412 int glyphIndex = 0;
5413 for (auto runLen : runs) {
5414 paint.setTextSize(1 == runLen ? 20 : 50);
Mike Klein9ff8c8c2018-02-07 01:58:51 +00005415 const SkTextBlobBuilder::RunBuffer& run =
Cary Clark2f466242017-12-11 16:03:17 -05005416 textBlobBuilder.allocRun(paint, runLen, textPos.fX, textPos.fY);
5417 memcpy(run.glyphs, &glyphs[glyphIndex], sizeof(glyphs[0]) * runLen);
5418 textPos.fX += paint.measureText(&glyphs[glyphIndex], sizeof(glyphs[0]) * runLen, nullptr);
5419 glyphIndex += runLen;
5420 }
5421 sk_sp<const SkTextBlob> blob = textBlobBuilder.make();
5422 paint.reset();
Cary Clarkbad5ad72017-08-03 17:14:08 -04005423 canvas->drawTextBlob(blob.get(), 0, 0, paint);
Cary Clark8032b982017-07-28 11:04:54 -04005424 }
5425##
5426
Cary Clark2ade9972017-11-02 17:49:34 -04005427#SeeAlso drawText drawPosText drawPosTextH
Cary Clark8032b982017-07-28 11:04:54 -04005428
5429##
5430
5431# ------------------------------------------------------------------------------
5432
Mike Klein9ff8c8c2018-02-07 01:58:51 +00005433#Method void drawTextBlob(const sk_sp<SkTextBlob>& blob, SkScalar x, SkScalar y, const SkPaint& paint)
Cary Clark8032b982017-07-28 11:04:54 -04005434
5435Draw Text_Blob blob at (x, y), using Clip, Matrix, and Paint paint.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005436
Cary Clarkce101242017-09-01 15:51:02 -04005437blob contains Glyphs, their positions, and paint attributes specific to text:
Cary Clarkbad5ad72017-08-03 17:14:08 -04005438Typeface, Paint_Text_Size, Paint_Text_Scale_X, Paint_Text_Skew_X,
5439Paint_Text_Align, Paint_Hinting, Anti-alias, Paint_Fake_Bold,
5440Font_Embedded_Bitmaps, Full_Hinting_Spacing, LCD_Text, Linear_Text,
5441Subpixel_Text, and Paint_Vertical_Text.
Cary Clark8032b982017-07-28 11:04:54 -04005442
Cary Clark3cd22cc2017-12-01 11:49:58 -05005443Paint_Text_Encoding must be set to SkPaint::kGlyphID_TextEncoding.
5444
Mike Klein9ff8c8c2018-02-07 01:58:51 +00005445Elements of paint: Path_Effect, Mask_Filter, Shader, Color_Filter,
Cary Clark8032b982017-07-28 11:04:54 -04005446Image_Filter, and Draw_Looper; apply to blob.
5447
Cary Clarkce101242017-09-01 15:51:02 -04005448#Param blob Glyphs, positions, and their paints' text size, typeface, and so on ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005449#Param x horizontal offset applied to blob ##
5450#Param y vertical offset applied to blob ##
5451#Param paint blend, color, stroking, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005452
5453#Example
5454#Height 120
5455#Description
5456Paint attributes unrelated to text, like color, have no effect on paint in allocated Text_Blob.
5457Paint attributes related to text, like text size, have no effect on paint passed to drawTextBlob.
5458##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005459 void draw(SkCanvas* canvas) {
5460 SkTextBlobBuilder textBlobBuilder;
5461 SkPaint paint;
5462 paint.setTextSize(50);
5463 paint.setColor(SK_ColorRED);
Cary Clark2f466242017-12-11 16:03:17 -05005464 paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
Mike Klein9ff8c8c2018-02-07 01:58:51 +00005465 const SkTextBlobBuilder::RunBuffer& run =
Cary Clarkbad5ad72017-08-03 17:14:08 -04005466 textBlobBuilder.allocRun(paint, 1, 20, 100);
5467 run.glyphs[0] = 20;
5468 sk_sp<const SkTextBlob> blob = textBlobBuilder.make();
5469 paint.setTextSize(10);
5470 paint.setColor(SK_ColorBLUE);
5471 canvas->drawTextBlob(blob.get(), 0, 0, paint);
5472 }
Cary Clark8032b982017-07-28 11:04:54 -04005473##
5474
Cary Clark2ade9972017-11-02 17:49:34 -04005475#SeeAlso drawText drawPosText drawPosTextH
Cary Clark8032b982017-07-28 11:04:54 -04005476
5477##
5478
5479# ------------------------------------------------------------------------------
5480
Mike Klein9ff8c8c2018-02-07 01:58:51 +00005481#Method void drawPicture(const SkPicture* picture)
Cary Clark78de7512018-02-07 07:27:09 -05005482#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05005483#Line # draws Picture using Clip and Matrix ##
Cary Clark8032b982017-07-28 11:04:54 -04005484Draw Picture picture, using Clip and Matrix.
5485Clip and Matrix are unchanged by picture contents, as if
5486save() was called before and restore() was called after drawPicture.
5487
5488Picture records a series of draw commands for later playback.
5489
Cary Clarkbad5ad72017-08-03 17:14:08 -04005490#Param picture recorded drawing commands to play ##
Cary Clark8032b982017-07-28 11:04:54 -04005491
5492#Example
Mike Klein9ff8c8c2018-02-07 01:58:51 +00005493void draw(SkCanvas* canvas) {
Cary Clarkbad5ad72017-08-03 17:14:08 -04005494 SkPictureRecorder recorder;
5495 SkCanvas* recordingCanvas = recorder.beginRecording(50, 50);
5496 for (auto color : { SK_ColorRED, SK_ColorBLUE, 0xff007f00 } ) {
5497 SkPaint paint;
5498 paint.setColor(color);
5499 recordingCanvas->drawRect({10, 10, 30, 40}, paint);
5500 recordingCanvas->translate(10, 10);
5501 recordingCanvas->scale(1.2f, 1.4f);
5502 }
5503 sk_sp<SkPicture> playback = recorder.finishRecordingAsPicture();
Cary Clarkbad5ad72017-08-03 17:14:08 -04005504 canvas->drawPicture(playback);
5505 canvas->scale(2, 2);
5506 canvas->translate(50, 0);
5507 canvas->drawPicture(playback);
Cary Clark8032b982017-07-28 11:04:54 -04005508}
5509##
5510
Cary Clark2ade9972017-11-02 17:49:34 -04005511#SeeAlso drawDrawable SkPicture SkPicture::playback
Cary Clark8032b982017-07-28 11:04:54 -04005512
5513##
5514
5515# ------------------------------------------------------------------------------
5516
Mike Klein9ff8c8c2018-02-07 01:58:51 +00005517#Method void drawPicture(const sk_sp<SkPicture>& picture)
Cary Clark8032b982017-07-28 11:04:54 -04005518
5519Draw Picture picture, using Clip and Matrix.
5520Clip and Matrix are unchanged by picture contents, as if
5521save() was called before and restore() was called after drawPicture.
5522
5523Picture records a series of draw commands for later playback.
5524
Cary Clarkbad5ad72017-08-03 17:14:08 -04005525#Param picture recorded drawing commands to play ##
Cary Clark8032b982017-07-28 11:04:54 -04005526
5527#Example
Mike Klein9ff8c8c2018-02-07 01:58:51 +00005528void draw(SkCanvas* canvas) {
Cary Clarkbad5ad72017-08-03 17:14:08 -04005529 SkPictureRecorder recorder;
5530 SkCanvas* recordingCanvas = recorder.beginRecording(50, 50);
5531 for (auto color : { SK_ColorRED, SK_ColorBLUE, 0xff007f00 } ) {
5532 SkPaint paint;
5533 paint.setColor(color);
5534 recordingCanvas->drawRect({10, 10, 30, 40}, paint);
5535 recordingCanvas->translate(10, 10);
5536 recordingCanvas->scale(1.2f, 1.4f);
5537 }
5538 sk_sp<SkPicture> playback = recorder.finishRecordingAsPicture();
5539 canvas->drawPicture(playback);
5540 canvas->scale(2, 2);
5541 canvas->translate(50, 0);
5542 canvas->drawPicture(playback);
Cary Clark8032b982017-07-28 11:04:54 -04005543}
5544##
5545
Cary Clark2ade9972017-11-02 17:49:34 -04005546#SeeAlso drawDrawable SkPicture SkPicture::playback
Cary Clark8032b982017-07-28 11:04:54 -04005547
5548##
5549
5550# ------------------------------------------------------------------------------
5551
5552#Method void drawPicture(const SkPicture* picture, const SkMatrix* matrix, const SkPaint* paint)
5553
Cary Clarkbad5ad72017-08-03 17:14:08 -04005554Draw Picture picture, using Clip and Matrix; transforming picture with
5555Matrix matrix, if provided; and use Paint paint Color_Alpha, Color_Filter,
5556Image_Filter, and Blend_Mode, if provided.
Cary Clark8032b982017-07-28 11:04:54 -04005557
5558matrix transformation is equivalent to: save(), concat(), drawPicture, restore().
5559paint use is equivalent to: saveLayer, drawPicture, restore().
5560
Cary Clarkbad5ad72017-08-03 17:14:08 -04005561#Param picture recorded drawing commands to play ##
5562#Param matrix Matrix to rotate, scale, translate, and so on; may be nullptr ##
5563#Param paint Paint to apply transparency, filtering, and so on; may be nullptr ##
Cary Clark8032b982017-07-28 11:04:54 -04005564
5565#Example
Mike Klein9ff8c8c2018-02-07 01:58:51 +00005566void draw(SkCanvas* canvas) {
Cary Clarkbad5ad72017-08-03 17:14:08 -04005567 SkPaint paint;
5568 SkPictureRecorder recorder;
5569 SkCanvas* recordingCanvas = recorder.beginRecording(50, 50);
5570 for (auto color : { SK_ColorRED, SK_ColorBLUE, 0xff007f00 } ) {
5571 paint.setColor(color);
5572 recordingCanvas->drawRect({10, 10, 30, 40}, paint);
5573 recordingCanvas->translate(10, 10);
5574 recordingCanvas->scale(1.2f, 1.4f);
5575 }
5576 sk_sp<SkPicture> playback = recorder.finishRecordingAsPicture();
5577 const SkPicture* playbackPtr = playback.get();
5578 SkMatrix matrix;
5579 matrix.reset();
5580 for (auto alpha : { 70, 140, 210 } ) {
5581 paint.setAlpha(alpha);
5582 canvas->drawPicture(playbackPtr, &matrix, &paint);
5583 matrix.preTranslate(70, 70);
5584 }
Cary Clark8032b982017-07-28 11:04:54 -04005585}
5586##
5587
Cary Clark2ade9972017-11-02 17:49:34 -04005588#SeeAlso drawDrawable SkPicture SkPicture::playback
Cary Clark8032b982017-07-28 11:04:54 -04005589
5590##
5591
5592# ------------------------------------------------------------------------------
5593
Mike Klein9ff8c8c2018-02-07 01:58:51 +00005594#Method void drawPicture(const sk_sp<SkPicture>& picture, const SkMatrix* matrix, const SkPaint* paint)
Cary Clark8032b982017-07-28 11:04:54 -04005595
Cary Clarkbad5ad72017-08-03 17:14:08 -04005596Draw Picture picture, using Clip and Matrix; transforming picture with
5597Matrix matrix, if provided; and use Paint paint Color_Alpha, Color_Filter,
5598Image_Filter, and Blend_Mode, if provided.
Cary Clark8032b982017-07-28 11:04:54 -04005599
5600matrix transformation is equivalent to: save(), concat(), drawPicture, restore().
5601paint use is equivalent to: saveLayer, drawPicture, restore().
5602
Cary Clarkbad5ad72017-08-03 17:14:08 -04005603#Param picture recorded drawing commands to play ##
5604#Param matrix Matrix to rotate, scale, translate, and so on; may be nullptr ##
5605#Param paint Paint to apply transparency, filtering, and so on; may be nullptr ##
Cary Clark8032b982017-07-28 11:04:54 -04005606
5607#Example
Mike Klein9ff8c8c2018-02-07 01:58:51 +00005608void draw(SkCanvas* canvas) {
Cary Clarkbad5ad72017-08-03 17:14:08 -04005609 SkPaint paint;
5610 SkPictureRecorder recorder;
5611 SkCanvas* recordingCanvas = recorder.beginRecording(50, 50);
5612 for (auto color : { SK_ColorRED, SK_ColorBLUE, 0xff007f00 } ) {
5613 paint.setColor(color);
5614 recordingCanvas->drawRect({10, 10, 30, 40}, paint);
5615 recordingCanvas->translate(10, 10);
5616 recordingCanvas->scale(1.2f, 1.4f);
5617 }
5618 sk_sp<SkPicture> playback = recorder.finishRecordingAsPicture();
5619 SkMatrix matrix;
5620 matrix.reset();
5621 for (auto alpha : { 70, 140, 210 } ) {
5622 paint.setAlpha(alpha);
5623 canvas->drawPicture(playback, &matrix, &paint);
5624 matrix.preTranslate(70, 70);
5625 }
Cary Clark8032b982017-07-28 11:04:54 -04005626}
5627##
5628
Cary Clark2ade9972017-11-02 17:49:34 -04005629#SeeAlso drawDrawable SkPicture SkPicture::playback
Cary Clark8032b982017-07-28 11:04:54 -04005630
5631##
5632
5633# ------------------------------------------------------------------------------
5634
5635#Method void drawVertices(const SkVertices* vertices, SkBlendMode mode, const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05005636#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05005637#Line # draws Vertices, a triangle mesh ##
Cary Clark8032b982017-07-28 11:04:54 -04005638Draw Vertices vertices, a triangle mesh, using Clip and Matrix.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005639If Vertices_Texs and Vertices_Colors are defined in vertices, and Paint paint
5640contains Shader, Blend_Mode mode combines Vertices_Colors with Shader.
Cary Clark8032b982017-07-28 11:04:54 -04005641
Cary Clarkbad5ad72017-08-03 17:14:08 -04005642#Param vertices triangle mesh to draw ##
5643#Param mode combines Vertices_Colors with Shader, if both are present ##
5644#Param paint specifies the Shader, used as Vertices texture; may be nullptr ##
Cary Clark8032b982017-07-28 11:04:54 -04005645
5646#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04005647void draw(SkCanvas* canvas) {
5648 SkPaint paint;
5649 SkPoint points[] = { { 0, 0 }, { 250, 0 }, { 100, 100 }, { 0, 250 } };
5650 SkColor colors[] = { SK_ColorRED, SK_ColorBLUE, SK_ColorYELLOW, SK_ColorCYAN };
5651 auto vertices = SkVertices::MakeCopy(SkVertices::kTriangleFan_VertexMode,
5652 SK_ARRAY_COUNT(points), points, nullptr, colors);
5653 canvas->drawVertices(vertices.get(), SkBlendMode::kSrc, paint);
5654}
Cary Clark8032b982017-07-28 11:04:54 -04005655##
5656
Cary Clark2ade9972017-11-02 17:49:34 -04005657#SeeAlso drawPatch drawPicture
Cary Clark8032b982017-07-28 11:04:54 -04005658
5659##
5660
5661# ------------------------------------------------------------------------------
5662
5663#Method void drawVertices(const sk_sp<SkVertices>& vertices, SkBlendMode mode, const SkPaint& paint)
5664
5665Draw Vertices vertices, a triangle mesh, using Clip and Matrix.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005666If Vertices_Texs and Vertices_Colors are defined in vertices, and Paint paint
5667contains Shader, Blend_Mode mode combines Vertices_Colors with Shader.
Cary Clark8032b982017-07-28 11:04:54 -04005668
Cary Clarkbad5ad72017-08-03 17:14:08 -04005669#Param vertices triangle mesh to draw ##
5670#Param mode combines Vertices_Colors with Shader, if both are present ##
5671#Param paint specifies the Shader, used as Vertices texture, may be nullptr ##
Cary Clark8032b982017-07-28 11:04:54 -04005672
5673#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04005674void draw(SkCanvas* canvas) {
5675 SkPaint paint;
5676 SkPoint points[] = { { 0, 0 }, { 250, 0 }, { 100, 100 }, { 0, 250 } };
5677 SkPoint texs[] = { { 0, 0 }, { 0, 250 }, { 250, 250 }, { 250, 0 } };
5678 SkColor colors[] = { SK_ColorRED, SK_ColorBLUE, SK_ColorYELLOW, SK_ColorCYAN };
5679 paint.setShader(SkGradientShader::MakeLinear(points, colors, nullptr, 4,
5680 SkShader::kClamp_TileMode));
5681 auto vertices = SkVertices::MakeCopy(SkVertices::kTriangleFan_VertexMode,
5682 SK_ARRAY_COUNT(points), points, texs, colors);
5683 canvas->drawVertices(vertices.get(), SkBlendMode::kDarken, paint);
Cary Clark8032b982017-07-28 11:04:54 -04005684}
5685##
5686
Cary Clark2ade9972017-11-02 17:49:34 -04005687#SeeAlso drawPatch drawPicture
Cary Clark8032b982017-07-28 11:04:54 -04005688
5689##
5690
5691# ------------------------------------------------------------------------------
5692
5693#Method void drawPatch(const SkPoint cubics[12], const SkColor colors[4],
5694 const SkPoint texCoords[4], SkBlendMode mode, const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05005695#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05005696#Line # draws Coons_Patch ##
Cary Clark8032b982017-07-28 11:04:54 -04005697
Mike Klein9ff8c8c2018-02-07 01:58:51 +00005698Draws a Coons_Patch: the interpolation of four cubics with shared corners,
Cary Clark8032b982017-07-28 11:04:54 -04005699associating a color, and optionally a texture coordinate, with each corner.
5700
Cary Clarka560c472017-11-27 10:44:06 -05005701Coons_Patch uses Clip and Matrix, paint Shader, Color_Filter,
Cary Clarkbad5ad72017-08-03 17:14:08 -04005702Color_Alpha, Image_Filter, and Blend_Mode. If Shader is provided it is treated
Cary Clarka560c472017-11-27 10:44:06 -05005703as Coons_Patch texture; Blend_Mode mode combines Color colors and Shader if
Cary Clarkbad5ad72017-08-03 17:14:08 -04005704both are provided.
Cary Clark8032b982017-07-28 11:04:54 -04005705
Mike Klein9ff8c8c2018-02-07 01:58:51 +00005706Point array cubics specifies four Cubics starting at the top-left corner,
Cary Clarkce101242017-09-01 15:51:02 -04005707in clockwise order, sharing every fourth point. The last Cubic ends at the
Cary Clarkbad5ad72017-08-03 17:14:08 -04005708first point.
Cary Clark8032b982017-07-28 11:04:54 -04005709
Cary Clarkbc5697d2017-10-04 14:31:33 -04005710Color array color associates colors with corners in top-left, top-right,
5711bottom-right, bottom-left order.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005712
5713If paint contains Shader, Point array texCoords maps Shader as texture to
Cary Clarkbc5697d2017-10-04 14:31:33 -04005714corners in top-left, top-right, bottom-right, bottom-left order.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005715
Cary Clarka523d2d2017-08-30 08:58:10 -04005716#Param cubics Path_Cubic array, sharing common points ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005717#Param colors Color array, one for each corner ##
Cary Clarkce101242017-09-01 15:51:02 -04005718#Param texCoords Point array of texture coordinates, mapping Shader to corners;
Mike Klein9ff8c8c2018-02-07 01:58:51 +00005719 may be nullptr
Cary Clark579985c2017-07-31 11:48:27 -04005720#Param ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005721#Param mode Blend_Mode for colors, and for Shader if paint has one ##
5722#Param paint Shader, Color_Filter, Blend_Mode, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005723
5724#Example
5725#Image 5
Cary Clarkbad5ad72017-08-03 17:14:08 -04005726void draw(SkCanvas* canvas) {
5727 // SkBitmap source = cmbkygk;
5728 SkPaint paint;
5729 paint.setFilterQuality(kLow_SkFilterQuality);
5730 paint.setAntiAlias(true);
5731 SkPoint cubics[] = { { 3, 1 }, { 4, 2 }, { 5, 1 }, { 7, 3 },
5732 /* { 7, 3 }, */ { 6, 4 }, { 7, 5 }, { 5, 7 },
5733 /* { 5, 7 }, */ { 4, 6 }, { 3, 7 }, { 1, 5 },
5734 /* { 1, 5 }, */ { 2, 4 }, { 1, 3 }, /* { 3, 1 } */ };
5735 SkColor colors[] = { 0xbfff0000, 0xbf0000ff, 0xbfff00ff, 0xbf00ffff };
5736 SkPoint texCoords[] = { { -30, -30 }, { 162, -30}, { 162, 162}, { -30, 162} };
5737 paint.setShader(SkShader::MakeBitmapShader(source, SkShader::kClamp_TileMode,
5738 SkShader::kClamp_TileMode, nullptr));
5739 canvas->scale(15, 15);
5740 for (auto blend : { SkBlendMode::kSrcOver, SkBlendMode::kModulate, SkBlendMode::kXor } ) {
5741 canvas->drawPatch(cubics, colors, texCoords, blend, paint);
5742 canvas->translate(4, 4);
5743 }
Cary Clark8032b982017-07-28 11:04:54 -04005744}
5745##
5746
Cary Clark2ade9972017-11-02 17:49:34 -04005747#ToDo can patch use image filter? ##
5748#SeeAlso SeeAlso drawVertices drawPicture
Cary Clark8032b982017-07-28 11:04:54 -04005749
5750##
5751
5752# ------------------------------------------------------------------------------
5753
5754#Method void drawPatch(const SkPoint cubics[12], const SkColor colors[4],
Mike Klein9ff8c8c2018-02-07 01:58:51 +00005755 const SkPoint texCoords[4], const SkPaint& paint)
Cary Clark8032b982017-07-28 11:04:54 -04005756
Mike Klein9ff8c8c2018-02-07 01:58:51 +00005757Draws Cubic Coons_Patch: the interpolation of four cubics with shared corners,
Cary Clarkbad5ad72017-08-03 17:14:08 -04005758associating a color, and optionally a texture coordinate, with each corner.
Cary Clark8032b982017-07-28 11:04:54 -04005759
Cary Clarka560c472017-11-27 10:44:06 -05005760Coons_Patch uses Clip and Matrix, paint Shader, Color_Filter,
Cary Clarkbad5ad72017-08-03 17:14:08 -04005761Color_Alpha, Image_Filter, and Blend_Mode. If Shader is provided it is treated
Cary Clarka560c472017-11-27 10:44:06 -05005762as Coons_Patch texture; Blend_Mode mode combines Color colors and Shader if
Cary Clarkbad5ad72017-08-03 17:14:08 -04005763both are provided.
Cary Clark8032b982017-07-28 11:04:54 -04005764
Mike Klein9ff8c8c2018-02-07 01:58:51 +00005765Point array cubics specifies four Cubics starting at the top-left corner,
Cary Clarkce101242017-09-01 15:51:02 -04005766in clockwise order, sharing every fourth point. The last Cubic ends at the
Cary Clarkbad5ad72017-08-03 17:14:08 -04005767first point.
5768
Cary Clarkbc5697d2017-10-04 14:31:33 -04005769Color array color associates colors with corners in top-left, top-right,
5770bottom-right, bottom-left order.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005771
5772If paint contains Shader, Point array texCoords maps Shader as texture to
Cary Clarkbc5697d2017-10-04 14:31:33 -04005773corners in top-left, top-right, bottom-right, bottom-left order.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005774
Cary Clarka523d2d2017-08-30 08:58:10 -04005775#Param cubics Path_Cubic array, sharing common points ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005776#Param colors Color array, one for each corner ##
Cary Clarkce101242017-09-01 15:51:02 -04005777#Param texCoords Point array of texture coordinates, mapping Shader to corners;
Mike Klein9ff8c8c2018-02-07 01:58:51 +00005778 may be nullptr
Cary Clark579985c2017-07-31 11:48:27 -04005779#Param ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005780#Param paint Shader, Color_Filter, Blend_Mode, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005781
5782#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04005783void draw(SkCanvas* canvas) {
5784 SkPaint paint;
5785 paint.setAntiAlias(true);
5786 SkPoint cubics[] = { { 3, 1 }, { 4, 2 }, { 5, 1 }, { 7, 3 },
5787 /* { 7, 3 }, */ { 6, 4 }, { 7, 5 }, { 5, 7 },
5788 /* { 5, 7 }, */ { 4, 6 }, { 3, 7 }, { 1, 5 },
5789 /* { 1, 5 }, */ { 2, 4 }, { 1, 3 }, /* { 3, 1 } */ };
5790 SkColor colors[] = { SK_ColorRED, SK_ColorBLUE, SK_ColorYELLOW, SK_ColorCYAN };
5791 canvas->scale(30, 30);
5792 canvas->drawPatch(cubics, colors, nullptr, paint);
5793 SkPoint text[] = { {3,0.9f}, {4,2.5f}, {5,0.9f}, {7.5f,3.2f}, {5.5f,4.2f},
5794 {7.5f,5.2f}, {5,7.5f}, {4,5.9f}, {3,7.5f}, {0.5f,5.2f}, {2.5f,4.2f},
5795 {0.5f,3.2f} };
5796 paint.setTextSize(18.f / 30);
5797 paint.setTextAlign(SkPaint::kCenter_Align);
5798 for (int i = 0; i< 10; ++i) {
5799 char digit = '0' + i;
5800 canvas->drawText(&digit, 1, text[i].fX, text[i].fY, paint);
5801 }
5802 canvas->drawString("10", text[10].fX, text[10].fY, paint);
5803 canvas->drawString("11", text[11].fX, text[11].fY, paint);
5804 paint.setStyle(SkPaint::kStroke_Style);
5805 canvas->drawPoints(SkCanvas::kPolygon_PointMode, 12, cubics, paint);
5806 canvas->drawLine(cubics[11].fX, cubics[11].fY, cubics[0].fX, cubics[0].fY, paint);
Cary Clark8032b982017-07-28 11:04:54 -04005807}
5808##
5809
5810#Example
5811#Image 6
Cary Clarkbad5ad72017-08-03 17:14:08 -04005812void draw(SkCanvas* canvas) {
5813 // SkBitmap source = checkerboard;
5814 SkPaint paint;
5815 paint.setFilterQuality(kLow_SkFilterQuality);
5816 paint.setAntiAlias(true);
5817 SkPoint cubics[] = { { 3, 1 }, { 4, 2 }, { 5, 1 }, { 7, 3 },
5818 /* { 7, 3 }, */ { 6, 4 }, { 7, 5 }, { 5, 7 },
5819 /* { 5, 7 }, */ { 4, 6 }, { 3, 7 }, { 1, 5 },
5820 /* { 1, 5 }, */ { 2, 4 }, { 1, 3 }, /* { 3, 1 } */ };
5821 SkPoint texCoords[] = { { 0, 0 }, { 0, 62}, { 62, 62}, { 62, 0 } };
5822 paint.setShader(SkShader::MakeBitmapShader(source, SkShader::kClamp_TileMode,
5823 SkShader::kClamp_TileMode, nullptr));
5824 canvas->scale(30, 30);
5825 canvas->drawPatch(cubics, nullptr, texCoords, paint);
Cary Clark8032b982017-07-28 11:04:54 -04005826}
5827##
5828
Cary Clark2ade9972017-11-02 17:49:34 -04005829#ToDo can patch use image filter? ##
5830#SeeAlso SeeAlso drawVertices drawPicture
Cary Clark8032b982017-07-28 11:04:54 -04005831
5832##
5833
5834# ------------------------------------------------------------------------------
5835
5836#Method void drawAtlas(const SkImage* atlas, const SkRSXform xform[], const SkRect tex[],
5837 const SkColor colors[], int count, SkBlendMode mode, const SkRect* cullRect,
5838 const SkPaint* paint)
Cary Clark78de7512018-02-07 07:27:09 -05005839#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05005840#Line # draws sprites using Clip, Matrix, and Paint ##
Cary Clark8032b982017-07-28 11:04:54 -04005841
5842Draw a set of sprites from atlas, using Clip, Matrix, and optional Paint paint.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005843paint uses Anti-alias, Color_Alpha, Color_Filter, Image_Filter, and Blend_Mode
5844to draw, if present. For each entry in the array, Rect tex locates sprite in
5845atlas, and RSXform xform transforms it into destination space.
5846
Cary Clark8032b982017-07-28 11:04:54 -04005847xform, text, and colors if present, must contain count entries.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005848Optional colors are applied for each sprite using Blend_Mode.
Mike Klein9ff8c8c2018-02-07 01:58:51 +00005849Optional cullRect is a conservative bounds of all transformed sprites.
Cary Clarkce101242017-09-01 15:51:02 -04005850If cullRect is outside of Clip, canvas can skip drawing.
Cary Clark8032b982017-07-28 11:04:54 -04005851
Cary Clarkbad5ad72017-08-03 17:14:08 -04005852#Param atlas Image containing sprites ##
5853#Param xform RSXform mappings for sprites in atlas ##
5854#Param tex Rect locations of sprites in atlas ##
Cary Clark6fc50412017-09-21 12:31:06 -04005855#Param colors one per sprite, blended with sprite using Blend_Mode; may be nullptr ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005856#Param count number of sprites to draw ##
5857#Param mode Blend_Mode combining colors and sprites ##
Cary Clark6fc50412017-09-21 12:31:06 -04005858#Param cullRect bounds of transformed sprites for efficient clipping; may be nullptr ##
5859#Param paint Color_Filter, Image_Filter, Blend_Mode, and so on; may be nullptr ##
Cary Clark8032b982017-07-28 11:04:54 -04005860
5861#Example
5862#Image 3
Cary Clarkbad5ad72017-08-03 17:14:08 -04005863void draw(SkCanvas* canvas) {
5864 // SkBitmap source = mandrill;
5865 SkRSXform xforms[] = { { .5f, 0, 0, 0 }, {0, .5f, 200, 100 } };
5866 SkRect tex[] = { { 0, 0, 250, 250 }, { 0, 0, 250, 250 } };
5867 SkColor colors[] = { 0x7f55aa00, 0x7f3333bf };
5868 const SkImage* imagePtr = image.get();
5869 canvas->drawAtlas(imagePtr, xforms, tex, colors, 2, SkBlendMode::kSrcOver, nullptr, nullptr);
Cary Clark8032b982017-07-28 11:04:54 -04005870}
5871##
5872
Cary Clark2ade9972017-11-02 17:49:34 -04005873#SeeAlso drawBitmap drawImage
Cary Clark8032b982017-07-28 11:04:54 -04005874
5875##
5876
5877# ------------------------------------------------------------------------------
5878
5879#Method void drawAtlas(const sk_sp<SkImage>& atlas, const SkRSXform xform[], const SkRect tex[],
5880 const SkColor colors[], int count, SkBlendMode mode, const SkRect* cullRect,
Mike Klein9ff8c8c2018-02-07 01:58:51 +00005881 const SkPaint* paint)
Cary Clark8032b982017-07-28 11:04:54 -04005882
5883Draw a set of sprites from atlas, using Clip, Matrix, and optional Paint paint.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005884paint uses Anti-alias, Color_Alpha, Color_Filter, Image_Filter, and Blend_Mode
5885to draw, if present. For each entry in the array, Rect tex locates sprite in
5886atlas, and RSXform xform transforms it into destination space.
5887
Cary Clark8032b982017-07-28 11:04:54 -04005888xform, text, and colors if present, must contain count entries.
5889Optional colors is applied for each sprite using Blend_Mode.
Mike Klein9ff8c8c2018-02-07 01:58:51 +00005890Optional cullRect is a conservative bounds of all transformed sprites.
Cary Clarkce101242017-09-01 15:51:02 -04005891If cullRect is outside of Clip, canvas can skip drawing.
Cary Clark8032b982017-07-28 11:04:54 -04005892
Cary Clarkbad5ad72017-08-03 17:14:08 -04005893#Param atlas Image containing sprites ##
5894#Param xform RSXform mappings for sprites in atlas ##
5895#Param tex Rect locations of sprites in atlas ##
Cary Clark6fc50412017-09-21 12:31:06 -04005896#Param colors one per sprite, blended with sprite using Blend_Mode; may be nullptr ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005897#Param count number of sprites to draw ##
5898#Param mode Blend_Mode combining colors and sprites ##
Cary Clark6fc50412017-09-21 12:31:06 -04005899#Param cullRect bounds of transformed sprites for efficient clipping; may be nullptr ##
5900#Param paint Color_Filter, Image_Filter, Blend_Mode, and so on; may be nullptr ##
Cary Clark8032b982017-07-28 11:04:54 -04005901
5902#Example
5903#Image 3
Cary Clarkbad5ad72017-08-03 17:14:08 -04005904void draw(SkCanvas* canvas) {
5905 // SkBitmap source = mandrill;
5906 SkRSXform xforms[] = { { .5f, 0, 0, 0 }, {0, .5f, 200, 100 } };
5907 SkRect tex[] = { { 0, 0, 250, 250 }, { 0, 0, 250, 250 } };
5908 SkColor colors[] = { 0x7f55aa00, 0x7f3333bf };
5909 SkPaint paint;
5910 paint.setAlpha(127);
5911 canvas->drawAtlas(image, xforms, tex, colors, 2, SkBlendMode::kPlus, nullptr, &paint);
Cary Clark8032b982017-07-28 11:04:54 -04005912}
5913##
5914
5915#ToDo bug in example on cpu side, gpu looks ok ##
5916
Cary Clark2ade9972017-11-02 17:49:34 -04005917#SeeAlso drawBitmap drawImage
5918
Cary Clark8032b982017-07-28 11:04:54 -04005919##
5920
5921# ------------------------------------------------------------------------------
5922
5923#Method void drawAtlas(const SkImage* atlas, const SkRSXform xform[], const SkRect tex[], int count,
Mike Klein9ff8c8c2018-02-07 01:58:51 +00005924 const SkRect* cullRect, const SkPaint* paint)
Cary Clark8032b982017-07-28 11:04:54 -04005925
5926Draw a set of sprites from atlas, using Clip, Matrix, and optional Paint paint.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005927paint uses Anti-alias, Color_Alpha, Color_Filter, Image_Filter, and Blend_Mode
5928to draw, if present. For each entry in the array, Rect tex locates sprite in
5929atlas, and RSXform xform transforms it into destination space.
5930
Cary Clark8032b982017-07-28 11:04:54 -04005931xform and text must contain count entries.
Mike Klein9ff8c8c2018-02-07 01:58:51 +00005932Optional cullRect is a conservative bounds of all transformed sprites.
Cary Clarkce101242017-09-01 15:51:02 -04005933If cullRect is outside of Clip, canvas can skip drawing.
Cary Clark8032b982017-07-28 11:04:54 -04005934
Cary Clarkbad5ad72017-08-03 17:14:08 -04005935#Param atlas Image containing sprites ##
5936#Param xform RSXform mappings for sprites in atlas ##
5937#Param tex Rect locations of sprites in atlas ##
5938#Param count number of sprites to draw ##
Cary Clark6fc50412017-09-21 12:31:06 -04005939#Param cullRect bounds of transformed sprites for efficient clipping; may be nullptr ##
5940#Param paint Color_Filter, Image_Filter, Blend_Mode, and so on; may be nullptr ##
Cary Clark8032b982017-07-28 11:04:54 -04005941
5942#Example
5943#Image 3
Cary Clarkbad5ad72017-08-03 17:14:08 -04005944void draw(SkCanvas* canvas) {
5945 // sk_sp<SkImage> image = mandrill;
5946 SkRSXform xforms[] = { { .5f, 0, 0, 0 }, {0, .5f, 200, 100 } };
5947 SkRect tex[] = { { 0, 0, 250, 250 }, { 0, 0, 250, 250 } };
5948 const SkImage* imagePtr = image.get();
5949 canvas->drawAtlas(imagePtr, xforms, tex, 2, nullptr, nullptr);
Cary Clark8032b982017-07-28 11:04:54 -04005950}
5951##
5952
Cary Clark2ade9972017-11-02 17:49:34 -04005953#SeeAlso drawBitmap drawImage
Cary Clark8032b982017-07-28 11:04:54 -04005954
5955##
5956
5957# ------------------------------------------------------------------------------
5958
5959#Method void drawAtlas(const sk_sp<SkImage>& atlas, const SkRSXform xform[], const SkRect tex[],
Mike Klein9ff8c8c2018-02-07 01:58:51 +00005960 int count, const SkRect* cullRect, const SkPaint* paint)
Cary Clark8032b982017-07-28 11:04:54 -04005961
5962Draw a set of sprites from atlas, using Clip, Matrix, and optional Paint paint.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005963paint uses Anti-alias, Color_Alpha, Color_Filter, Image_Filter, and Blend_Mode
5964to draw, if present. For each entry in the array, Rect tex locates sprite in
5965atlas, and RSXform xform transforms it into destination space.
5966
Cary Clark8032b982017-07-28 11:04:54 -04005967xform and text must contain count entries.
Mike Klein9ff8c8c2018-02-07 01:58:51 +00005968Optional cullRect is a conservative bounds of all transformed sprites.
Cary Clarkce101242017-09-01 15:51:02 -04005969If cullRect is outside of Clip, canvas can skip drawing.
Cary Clark8032b982017-07-28 11:04:54 -04005970
Cary Clarkbad5ad72017-08-03 17:14:08 -04005971#Param atlas Image containing sprites ##
5972#Param xform RSXform mappings for sprites in atlas ##
5973#Param tex Rect locations of sprites in atlas ##
5974#Param count number of sprites to draw ##
Cary Clark6fc50412017-09-21 12:31:06 -04005975#Param cullRect bounds of transformed sprites for efficient clipping; may be nullptr ##
5976#Param paint Color_Filter, Image_Filter, Blend_Mode, and so on; may be nullptr ##
Cary Clark8032b982017-07-28 11:04:54 -04005977
5978#Example
5979#Image 3
Cary Clarkbad5ad72017-08-03 17:14:08 -04005980void draw(SkCanvas* canvas) {
5981 // sk_sp<SkImage> image = mandrill;
5982 SkRSXform xforms[] = { { 1, 0, 0, 0 }, {0, 1, 300, 100 } };
5983 SkRect tex[] = { { 0, 0, 200, 200 }, { 200, 0, 400, 200 } };
5984 canvas->drawAtlas(image, xforms, tex, 2, nullptr, nullptr);
Cary Clark8032b982017-07-28 11:04:54 -04005985}
5986##
5987
Cary Clark2ade9972017-11-02 17:49:34 -04005988#SeeAlso drawBitmap drawImage
Cary Clark8032b982017-07-28 11:04:54 -04005989
5990##
5991
5992# ------------------------------------------------------------------------------
5993
Cary Clark73fa9722017-08-29 17:36:51 -04005994#Method void drawDrawable(SkDrawable* drawable, const SkMatrix* matrix = nullptr)
Cary Clark78de7512018-02-07 07:27:09 -05005995#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05005996#Line # draws Drawable, encapsulated drawing commands ##
Mike Klein9ff8c8c2018-02-07 01:58:51 +00005997Draw Drawable drawable using Clip and Matrix, concatenated with
Cary Clark8032b982017-07-28 11:04:54 -04005998optional matrix.
5999
Mike Klein9ff8c8c2018-02-07 01:58:51 +00006000If Canvas has an asynchronous implementation, as is the case
Cary Clark8032b982017-07-28 11:04:54 -04006001when it is recording into Picture, then drawable will be referenced,
6002so that SkDrawable::draw() can be called when the operation is finalized. To force
6003immediate drawing, call SkDrawable::draw() instead.
6004
Cary Clarkbad5ad72017-08-03 17:14:08 -04006005#Param drawable custom struct encapsulating drawing commands ##
6006#Param matrix transformation applied to drawing; may be nullptr ##
Cary Clark8032b982017-07-28 11:04:54 -04006007
6008#Example
6009#Height 100
6010#Function
Cary Clarkbad5ad72017-08-03 17:14:08 -04006011struct MyDrawable : public SkDrawable {
6012 SkRect onGetBounds() override { return SkRect::MakeWH(50, 100); }
6013
6014 void onDraw(SkCanvas* canvas) override {
6015 SkPath path;
6016 path.conicTo(10, 90, 50, 90, 0.9f);
6017 SkPaint paint;
6018 paint.setColor(SK_ColorBLUE);
6019 canvas->drawRect(path.getBounds(), paint);
6020 paint.setAntiAlias(true);
6021 paint.setColor(SK_ColorWHITE);
6022 canvas->drawPath(path, paint);
6023 }
6024};
6025
6026#Function ##
6027void draw(SkCanvas* canvas) {
6028 sk_sp<SkDrawable> drawable(new MyDrawable);
6029 SkMatrix matrix;
6030 matrix.setTranslate(10, 10);
6031 canvas->drawDrawable(drawable.get(), &matrix);
Cary Clark8032b982017-07-28 11:04:54 -04006032}
6033##
6034
Cary Clark2ade9972017-11-02 17:49:34 -04006035#SeeAlso SkDrawable drawPicture
Cary Clark8032b982017-07-28 11:04:54 -04006036
6037##
6038
6039# ------------------------------------------------------------------------------
6040
6041#Method void drawDrawable(SkDrawable* drawable, SkScalar x, SkScalar y)
6042
6043Draw Drawable drawable using Clip and Matrix, offset by (x, y).
6044
Mike Klein9ff8c8c2018-02-07 01:58:51 +00006045If Canvas has an asynchronous implementation, as is the case
Cary Clark8032b982017-07-28 11:04:54 -04006046when it is recording into Picture, then drawable will be referenced,
6047so that SkDrawable::draw() can be called when the operation is finalized. To force
6048immediate drawing, call SkDrawable::draw() instead.
6049
Cary Clarkbad5ad72017-08-03 17:14:08 -04006050#Param drawable custom struct encapsulating drawing commands ##
6051#Param x offset into Canvas writable pixels in x ##
6052#Param y offset into Canvas writable pixels in y ##
Cary Clark8032b982017-07-28 11:04:54 -04006053
6054#Example
6055#Height 100
6056#Function
Cary Clarkbad5ad72017-08-03 17:14:08 -04006057struct MyDrawable : public SkDrawable {
6058 SkRect onGetBounds() override { return SkRect::MakeWH(50, 100); }
6059
6060 void onDraw(SkCanvas* canvas) override {
6061 SkPath path;
6062 path.conicTo(10, 90, 50, 90, 0.9f);
6063 SkPaint paint;
6064 paint.setColor(SK_ColorBLUE);
6065 canvas->drawRect(path.getBounds(), paint);
6066 paint.setAntiAlias(true);
6067 paint.setColor(SK_ColorWHITE);
6068 canvas->drawPath(path, paint);
6069 }
6070};
6071
6072#Function ##
6073void draw(SkCanvas* canvas) {
6074 sk_sp<SkDrawable> drawable(new MyDrawable);
6075 canvas->drawDrawable(drawable.get(), 10, 10);
Cary Clark8032b982017-07-28 11:04:54 -04006076}
6077##
6078
Cary Clark2ade9972017-11-02 17:49:34 -04006079#SeeAlso SkDrawable drawPicture
Cary Clark8032b982017-07-28 11:04:54 -04006080
6081##
6082
6083# ------------------------------------------------------------------------------
6084
6085#Method void drawAnnotation(const SkRect& rect, const char key[], SkData* value)
Cary Clark78de7512018-02-07 07:27:09 -05006086#In Draw
6087#In Utility
Cary Clarkab2621d2018-01-30 10:08:57 -05006088#Line # associates a Rect with a key-value pair ##
Cary Clark78de7512018-02-07 07:27:09 -05006089Associate Rect on Canvas with an annotation; a key-value pair, where the key is
Cary Clark8032b982017-07-28 11:04:54 -04006090a null-terminated utf8 string, and optional value is stored as Data.
6091
Mike Klein9ff8c8c2018-02-07 01:58:51 +00006092Only some canvas implementations, such as recording to Picture, or drawing to
Cary Clark8032b982017-07-28 11:04:54 -04006093Document_PDF, use annotations.
6094
Cary Clarkbad5ad72017-08-03 17:14:08 -04006095#Param rect Rect extent of canvas to annotate ##
6096#Param key string used for lookup ##
6097#Param value data holding value stored in annotation ##
Cary Clark8032b982017-07-28 11:04:54 -04006098
6099#Example
6100 #Height 1
6101 const char text[] = "Click this link!";
6102 SkRect bounds;
6103 SkPaint paint;
6104 paint.setTextSize(40);
6105 (void)paint.measureText(text, strlen(text), &bounds);
6106 const char url[] = "https://www.google.com/";
6107 sk_sp<SkData> urlData(SkData::MakeWithCString(url));
6108 canvas->drawAnnotation(bounds, "url_key", urlData.get());
6109##
6110
Cary Clark2ade9972017-11-02 17:49:34 -04006111#SeeAlso SkPicture SkDocument
Cary Clark8032b982017-07-28 11:04:54 -04006112
6113##
6114
6115# ------------------------------------------------------------------------------
6116
Mike Klein9ff8c8c2018-02-07 01:58:51 +00006117#Method void drawAnnotation(const SkRect& rect, const char key[], const sk_sp<SkData>& value)
Cary Clark8032b982017-07-28 11:04:54 -04006118
6119Associate Rect on Canvas when an annotation; a key-value pair, where the key is
6120a null-terminated utf8 string, and optional value is stored as Data.
6121
Mike Klein9ff8c8c2018-02-07 01:58:51 +00006122Only some canvas implementations, such as recording to Picture, or drawing to
Cary Clark8032b982017-07-28 11:04:54 -04006123Document_PDF, use annotations.
6124
Cary Clarkbad5ad72017-08-03 17:14:08 -04006125#Param rect Rect extent of canvas to annotate ##
6126#Param key string used for lookup ##
6127#Param value data holding value stored in annotation ##
Cary Clark8032b982017-07-28 11:04:54 -04006128
6129#Example
6130#Height 1
6131 const char text[] = "Click this link!";
6132 SkRect bounds;
6133 SkPaint paint;
6134 paint.setTextSize(40);
6135 (void)paint.measureText(text, strlen(text), &bounds);
6136 const char url[] = "https://www.google.com/";
6137 sk_sp<SkData> urlData(SkData::MakeWithCString(url));
6138 canvas->drawAnnotation(bounds, "url_key", urlData.get());
6139##
6140
Cary Clark2ade9972017-11-02 17:49:34 -04006141#SeeAlso SkPicture SkDocument
Cary Clark8032b982017-07-28 11:04:54 -04006142
6143##
6144
6145#Method SkDrawFilter* getDrawFilter() const
Cary Clark4855f782018-02-06 09:41:53 -05006146#Deprecated soon
Cary Clark8032b982017-07-28 11:04:54 -04006147##
6148
6149#Method virtual SkDrawFilter* setDrawFilter(SkDrawFilter* filter)
Cary Clark4855f782018-02-06 09:41:53 -05006150#Deprecated soon
Cary Clark8032b982017-07-28 11:04:54 -04006151##
6152
6153# ------------------------------------------------------------------------------
6154
6155#Method virtual bool isClipEmpty() const
Cary Clark78de7512018-02-07 07:27:09 -05006156#In Property
Cary Clarkab2621d2018-01-30 10:08:57 -05006157#Line # returns if Clip is empty ##
Cary Clark8032b982017-07-28 11:04:54 -04006158Returns true if Clip is empty; that is, nothing will draw.
6159
Cary Clarkbad5ad72017-08-03 17:14:08 -04006160May do work when called; it should not be called
Cary Clark8032b982017-07-28 11:04:54 -04006161more often than needed. However, once called, subsequent calls perform no
6162work until Clip changes.
6163
Cary Clarkbad5ad72017-08-03 17:14:08 -04006164#Return true if Clip is empty ##
Cary Clark8032b982017-07-28 11:04:54 -04006165
6166#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04006167 void draw(SkCanvas* canvas) {
6168 SkDebugf("clip is%s empty\n", canvas->isClipEmpty() ? "" : " not");
6169 SkPath path;
6170 canvas->clipPath(path);
6171 SkDebugf("clip is%s empty\n", canvas->isClipEmpty() ? "" : " not");
Cary Clark8032b982017-07-28 11:04:54 -04006172 }
6173 #StdOut
Cary Clarkbad5ad72017-08-03 17:14:08 -04006174 clip is not empty
Cary Clark8032b982017-07-28 11:04:54 -04006175 clip is empty
6176 ##
6177##
6178
Cary Clark2ade9972017-11-02 17:49:34 -04006179#SeeAlso isClipRect getLocalClipBounds getDeviceClipBounds
Cary Clark8032b982017-07-28 11:04:54 -04006180
6181##
6182
6183# ------------------------------------------------------------------------------
6184
6185#Method virtual bool isClipRect() const
Cary Clark78de7512018-02-07 07:27:09 -05006186#In Property
Cary Clarkab2621d2018-01-30 10:08:57 -05006187#Line # returns if Clip is Rect and not empty ##
Cary Clark8032b982017-07-28 11:04:54 -04006188Returns true if Clip is Rect and not empty.
6189Returns false if the clip is empty, or if it is not Rect.
6190
Cary Clarkbad5ad72017-08-03 17:14:08 -04006191#Return true if Clip is Rect and not empty ##
Cary Clark8032b982017-07-28 11:04:54 -04006192
6193#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04006194 void draw(SkCanvas* canvas) {
6195 SkDebugf("clip is%s rect\n", canvas->isClipRect() ? "" : " not");
6196 canvas->clipRect({0, 0, 0, 0});
6197 SkDebugf("clip is%s rect\n", canvas->isClipRect() ? "" : " not");
Cary Clark8032b982017-07-28 11:04:54 -04006198 }
6199 #StdOut
Cary Clarkbad5ad72017-08-03 17:14:08 -04006200 clip is rect
Cary Clark8032b982017-07-28 11:04:54 -04006201 clip is not rect
6202 ##
6203##
6204
Cary Clark2ade9972017-11-02 17:49:34 -04006205#SeeAlso isClipEmpty getLocalClipBounds getDeviceClipBounds
Cary Clark8032b982017-07-28 11:04:54 -04006206
6207##
6208
6209#Class SkCanvas ##
Cary Clark884dd7d2017-10-11 10:37:52 -04006210
Cary Clark8032b982017-07-28 11:04:54 -04006211#Topic Canvas ##