blob: 6e6d6a745653b916623b6ed89f37c7442790852b [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
Cary Clarkbad5ad72017-08-03 17:14:08 -0400886like SkDumpCanvas.
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
927class like SkDumpCanvas.
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
1019class like SkDumpCanvas.
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
1082class like SkDumpCanvas.
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
1146class like SkDumpCanvas.
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
1204class like SkDumpCanvas.
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 {
Mike Klein9ff8c8c2018-02-07 01:58:51 +00001685 kIsOpaque_SaveLayerFlag = 1 << 0,
Cary Clarkce101242017-09-01 15:51:02 -04001686 kPreserveLCDText_SaveLayerFlag = 1 << 1,
1687 kInitWithPrevious_SaveLayerFlag = 1 << 2,
1688 kDontClipToLayer_Legacy_SaveLayerFlag = kDontClipToLayer_PrivateSaveLayerFlag,
1689 };
Cary Clarkce101242017-09-01 15:51:02 -04001690##
1691
1692SaveLayerFlags provides options that may be used in any combination in SaveLayerRec,
1693defining how Layer allocated by saveLayer operates.
1694
Mike Klein9ff8c8c2018-02-07 01:58:51 +00001695#Const kIsOpaque_SaveLayerFlag 1
1696 Creates Layer without transparency. Flag is ignored if Layer Paint contains
1697 Image_Filter or Color_Filter.
1698##
1699
Cary Clarkce101242017-09-01 15:51:02 -04001700#Const kPreserveLCDText_SaveLayerFlag 2
1701 Creates Layer for LCD text. Flag is ignored if Layer Paint contains
1702 Image_Filter or Color_Filter.
1703##
1704
1705#Const kInitWithPrevious_SaveLayerFlag 4
1706 Initializes Layer with the contents of the previous Layer.
1707##
1708
1709#Const kDontClipToLayer_Legacy_SaveLayerFlag 0x80000000
Cary Clark4855f782018-02-06 09:41:53 -05001710#Deprecated soon
Cary Clarkce101242017-09-01 15:51:02 -04001711##
1712
1713#Example
1714#Height 160
1715#Description
1716Canvas Layer captures red and blue circles scaled up by four.
Mike Klein9ff8c8c2018-02-07 01:58:51 +00001717scalePaint blends Layer back with transparency.
Cary Clarkce101242017-09-01 15:51:02 -04001718##
1719void draw(SkCanvas* canvas) {
1720 SkPaint redPaint, bluePaint, scalePaint;
1721 redPaint.setColor(SK_ColorRED);
1722 canvas->drawCircle(21, 21, 8, redPaint);
1723 bluePaint.setColor(SK_ColorBLUE);
1724 canvas->drawCircle(31, 21, 8, bluePaint);
1725 SkMatrix matrix;
1726 matrix.setScale(4, 4);
1727 scalePaint.setAlpha(0x40);
1728 scalePaint.setImageFilter(
1729 SkImageFilter::MakeMatrixFilter(matrix, kNone_SkFilterQuality, nullptr));
1730 SkCanvas::SaveLayerRec saveLayerRec(nullptr, &scalePaint,
Mike Klein9ff8c8c2018-02-07 01:58:51 +00001731 SkCanvas::kInitWithPrevious_SaveLayerFlag);
Cary Clarkce101242017-09-01 15:51:02 -04001732 canvas->saveLayer(saveLayerRec);
1733 canvas->restore();
1734}
1735##
1736
Cary Clark2ade9972017-11-02 17:49:34 -04001737#SeeAlso save() restore() saveLayer saveLayerPreserveLCDTextRequests saveLayerAlpha SaveLayerRec
Cary Clarkce101242017-09-01 15:51:02 -04001738
1739#Enum ##
1740
Cary Clarka560c472017-11-27 10:44:06 -05001741#Typedef uint32_t SaveLayerFlags
1742
1743##
1744
Cary Clarkce101242017-09-01 15:51:02 -04001745#Struct SaveLayerRec
Cary Clark08895c42018-02-01 09:37:32 -05001746#Line # contains the state used to create the Layer ##
Cary Clarkce101242017-09-01 15:51:02 -04001747#Code
1748 struct SaveLayerRec {
1749 SaveLayerRec*(...
1750
1751 const SkRect* fBounds;
1752 const SkPaint* fPaint;
1753 const SkImageFilter* fBackdrop;
1754 SaveLayerFlags fSaveLayerFlags;
1755 };
1756##
1757
Mike Klein9ff8c8c2018-02-07 01:58:51 +00001758SaveLayerRec contains the state used to create the Layer.
Cary Clarkce101242017-09-01 15:51:02 -04001759
1760#Member const SkRect* fBounds
1761 fBounds is used as a hint to limit the size of Layer; may be nullptr.
1762 fBounds suggests but does not define Layer size. To clip drawing to
1763 a specific rectangle, use clipRect.
1764##
1765
1766#Member const SkPaint* fPaint
1767 fPaint modifies how Layer overlays the prior Layer; may be nullptr.
1768 Color_Alpha, Blend_Mode, Color_Filter, Draw_Looper, Image_Filter, and
1769 Mask_Filter affect Layer draw.
1770##
1771
1772#Member const SkImageFilter* fBackdrop
1773 fBackdrop applies Image_Filter to the prior Layer when copying to the Layer;
1774 may be nullptr. Use kInitWithPrevious_SaveLayerFlag to copy the
1775 prior Layer without an Image_Filter.
1776##
1777
1778#Member const SkImage* fClipMask
1779 restore() clips Layer by the Color_Alpha channel of fClipMask when
1780 Layer is copied to Device. fClipMask may be nullptr. .
1781##
1782
1783#Member const SkMatrix* fClipMatrix
Mike Klein9ff8c8c2018-02-07 01:58:51 +00001784 fClipMatrix transforms fClipMask before it clips Layer. If
Cary Clarkce101242017-09-01 15:51:02 -04001785 fClipMask describes a translucent gradient, it may be scaled and rotated
1786 without introducing artifacts. fClipMatrix may be nullptr.
1787##
1788
1789#Member SaveLayerFlags fSaveLayerFlags
1790 fSaveLayerFlags are used to create Layer without transparency,
1791 create Layer for LCD text, and to create Layer with the
1792 contents of the previous Layer.
1793##
1794
1795#Example
1796#Height 160
1797#Description
1798Canvas Layer captures a red Anti-aliased circle and a blue Aliased circle scaled
1799up by four. After drawing another red circle without scaling on top, the Layer is
Mike Klein9ff8c8c2018-02-07 01:58:51 +00001800transferred to the main canvas.
Cary Clarkce101242017-09-01 15:51:02 -04001801##
1802void draw(SkCanvas* canvas) {
1803 SkPaint redPaint, bluePaint;
1804 redPaint.setAntiAlias(true);
1805 redPaint.setColor(SK_ColorRED);
1806 canvas->drawCircle(21, 21, 8, redPaint);
1807 bluePaint.setColor(SK_ColorBLUE);
1808 canvas->drawCircle(31, 21, 8, bluePaint);
1809 SkMatrix matrix;
1810 matrix.setScale(4, 4);
1811 auto scaler = SkImageFilter::MakeMatrixFilter(matrix, kNone_SkFilterQuality, nullptr);
Mike Klein9ff8c8c2018-02-07 01:58:51 +00001812 SkCanvas::SaveLayerRec saveLayerRec(nullptr, nullptr, scaler.get(), 0);
Cary Clarkce101242017-09-01 15:51:02 -04001813 canvas->saveLayer(saveLayerRec);
1814 canvas->drawCircle(125, 85, 8, redPaint);
1815 canvas->restore();
1816}
1817##
1818
1819#Method SaveLayerRec()
1820
1821Sets fBounds, fPaint, and fBackdrop to nullptr. Clears fSaveLayerFlags.
1822
1823#Return empty SaveLayerRec ##
1824
1825#Example
1826 SkCanvas::SaveLayerRec rec1;
Mike Klein9ff8c8c2018-02-07 01:58:51 +00001827 rec1.fSaveLayerFlags = SkCanvas::kIsOpaque_SaveLayerFlag;
1828 SkCanvas::SaveLayerRec rec2(nullptr, nullptr, SkCanvas::kIsOpaque_SaveLayerFlag);
Cary Clarkce101242017-09-01 15:51:02 -04001829 SkDebugf("rec1 %c= rec2\n", rec1.fBounds == rec2.fBounds
1830 && rec1.fPaint == rec2.fPaint
1831 && rec1.fBackdrop == rec2.fBackdrop
1832 && rec1.fSaveLayerFlags == rec2.fSaveLayerFlags ? '=' : '!');
1833 #StdOut
1834 rec1 == rec2
1835 ##
1836##
1837
Cary Clark2ade9972017-11-02 17:49:34 -04001838#SeeAlso save() restore() saveLayer saveLayerPreserveLCDTextRequests saveLayerAlpha
1839
Cary Clarkce101242017-09-01 15:51:02 -04001840##
1841
1842#Method SaveLayerRec(const SkRect* bounds, const SkPaint* paint, SaveLayerFlags saveLayerFlags = 0)
1843
1844Sets fBounds, fPaint, and fSaveLayerFlags; sets fBackdrop to nullptr.
1845
1846#Param bounds Layer dimensions; may be nullptr ##
1847#Param paint applied to Layer when overlaying prior Layer; may be nullptr ##
1848#Param saveLayerFlags SaveLayerRec options to modify Layer ##
1849
1850#Return SaveLayerRec with empty backdrop ##
1851
1852#Example
1853 SkCanvas::SaveLayerRec rec1;
1854 SkCanvas::SaveLayerRec rec2(nullptr, nullptr);
1855 SkDebugf("rec1 %c= rec2\n", rec1.fBounds == rec2.fBounds
1856 && rec1.fPaint == rec2.fPaint
1857 && rec1.fBackdrop == rec2.fBackdrop
1858 && rec1.fSaveLayerFlags == rec2.fSaveLayerFlags ? '=' : '!');
1859 #StdOut
1860 rec1 == rec2
1861 ##
1862##
1863
Cary Clark2ade9972017-11-02 17:49:34 -04001864#SeeAlso save() restore() saveLayer saveLayerPreserveLCDTextRequests saveLayerAlpha
1865
Cary Clarkce101242017-09-01 15:51:02 -04001866##
1867
1868#Method SaveLayerRec(const SkRect* bounds, const SkPaint* paint, const SkImageFilter* backdrop,
1869 SaveLayerFlags saveLayerFlags)
1870
1871Sets fBounds, fPaint, fBackdrop, and fSaveLayerFlags.
1872
1873#Param bounds Layer dimensions; may be nullptr ##
1874#Param paint applied to Layer when overlaying prior Layer;
1875 may be nullptr
1876##
1877#Param backdrop prior Layer copied with Image_Filter; may be nullptr
1878##
1879#Param saveLayerFlags SaveLayerRec options to modify Layer ##
1880
1881#Return SaveLayerRec fully specified ##
1882
1883#Example
1884 SkCanvas::SaveLayerRec rec1;
1885 SkCanvas::SaveLayerRec rec2(nullptr, nullptr, nullptr, 0);
1886 SkDebugf("rec1 %c= rec2\n", rec1.fBounds == rec2.fBounds
1887 && rec1.fPaint == rec2.fPaint
1888 && rec1.fBackdrop == rec2.fBackdrop
1889 && rec1.fSaveLayerFlags == rec2.fSaveLayerFlags ? '=' : '!');
1890 #StdOut
1891 rec1 == rec2
1892 ##
1893##
1894
Cary Clark2ade9972017-11-02 17:49:34 -04001895#SeeAlso save() restore() saveLayer saveLayerPreserveLCDTextRequests saveLayerAlpha
1896
Cary Clarkce101242017-09-01 15:51:02 -04001897##
1898
1899#Method SaveLayerRec(const SkRect* bounds, const SkPaint* paint, const SkImageFilter* backdrop,
1900 const SkImage* clipMask, const SkMatrix* clipMatrix,
1901 SaveLayerFlags saveLayerFlags)
1902
1903#Experimental
1904Not ready for general use.
1905##
1906
1907Sets fBounds, fPaint, fBackdrop, fClipMask, fClipMatrix, and fSaveLayerFlags.
1908clipMatrix uses Color_Alpha channel of image, transformed by clipMatrix, to clip
1909Layer when drawn to Canvas.
1910
Cary Clark2ade9972017-11-02 17:49:34 -04001911Implementation is not complete; has no effect if Device is GPU-backed.
Cary Clarkce101242017-09-01 15:51:02 -04001912
1913#Param bounds Layer dimensions; may be nullptr ##
1914#Param paint graphics state applied to Layer when overlaying prior
1915 Layer; may be nullptr
1916##
1917#Param backdrop prior Layer copied with Image_Filter;
1918 may be nullptr
1919##
1920#Param clipMask clip applied to Layer; may be nullptr ##
1921#Param clipMatrix matrix applied to clipMask; may be nullptr to use
Mike Klein9ff8c8c2018-02-07 01:58:51 +00001922 identity matrix
Cary Clarkce101242017-09-01 15:51:02 -04001923##
1924#Param saveLayerFlags SaveLayerRec options to modify Layer ##
1925
1926#Return SaveLayerRec fully specified ##
1927
Cary Clark2ade9972017-11-02 17:49:34 -04001928#SeeAlso save() restore() saveLayer saveLayerPreserveLCDTextRequests saveLayerAlpha
Cary Clarkce101242017-09-01 15:51:02 -04001929
1930##
1931
1932#Struct ##
1933
1934#Method int saveLayer(const SaveLayerRec& layerRec)
1935
Cary Clarkab2621d2018-01-30 10:08:57 -05001936#In Layer
Cary Clarkce101242017-09-01 15:51:02 -04001937Saves Matrix, Clip, and Draw_Filter (Draw_Filter deprecated on most platforms),
1938and allocates Bitmap for subsequent drawing.
1939
1940Calling restore() discards changes to Matrix, Clip, and Draw_Filter,
1941and blends Bitmap with Color_Alpha opacity onto the prior Layer.
1942
1943Matrix may be changed by translate(), scale(), rotate(), skew(), concat(),
1944setMatrix, and resetMatrix. Clip may be changed by clipRect, clipRRect,
1945clipPath, clipRegion.
1946
1947SaveLayerRec contains the state used to create the Layer.
1948
1949Call restoreToCount with returned value to restore this and subsequent saves.
1950
1951#Param layerRec Layer state ##
1952
1953#Return depth of save state stack ##
1954
1955#Example
1956#Description
1957The example draws an image, and saves it into a Layer with kInitWithPrevious_SaveLayerFlag.
1958Next it punches a hole in Layer and restore with SkBlendMode::kPlus.
1959Where Layer was cleared, the original image will draw unchanged.
1960Outside of the circle the mandrill is brightened.
1961##
1962 #Image 3
Hal Canaryc465d132017-12-08 10:21:31 -05001963 // sk_sp<SkImage> image = GetResourceAsImage("images/mandrill_256.png");
Cary Clarkce101242017-09-01 15:51:02 -04001964 canvas->drawImage(image, 0, 0, nullptr);
1965 SkCanvas::SaveLayerRec rec;
1966 SkPaint paint;
1967 paint.setBlendMode(SkBlendMode::kPlus);
1968 rec.fSaveLayerFlags = SkCanvas::kInitWithPrevious_SaveLayerFlag;
1969 rec.fPaint = &paint;
1970 canvas->saveLayer(rec);
1971 paint.setBlendMode(SkBlendMode::kClear);
1972 canvas->drawCircle(128, 128, 96, paint);
1973 canvas->restore();
1974##
1975
1976#ToDo above example needs to replace GetResourceAsImage with way to select image in fiddle ##
1977
Cary Clark2ade9972017-11-02 17:49:34 -04001978#SeeAlso save() restore() saveLayer saveLayerPreserveLCDTextRequests saveLayerAlpha
1979
Cary Clarkce101242017-09-01 15:51:02 -04001980##
1981
Cary Clark08895c42018-02-01 09:37:32 -05001982#Subtopic Layer ##
Cary Clarkce101242017-09-01 15:51:02 -04001983
1984# ------------------------------------------------------------------------------
Cary Clark08895c42018-02-01 09:37:32 -05001985#Subtopic Matrix
1986#Line # coordinate transformation ##
Cary Clark8032b982017-07-28 11:04:54 -04001987
1988#Method void translate(SkScalar dx, SkScalar dy)
1989
Cary Clarkab2621d2018-01-30 10:08:57 -05001990#In Matrix
1991#Line # translates Matrix ##
Cary Clark8032b982017-07-28 11:04:54 -04001992Translate Matrix by dx along the x-axis and dy along the y-axis.
1993
1994Mathematically, replace Matrix with a translation matrix
Mike Klein9ff8c8c2018-02-07 01:58:51 +00001995Premultiplied with Matrix.
Cary Clark8032b982017-07-28 11:04:54 -04001996
1997This has the effect of moving the drawing by (dx, dy) before transforming
1998the result with Matrix.
1999
Cary Clarkbad5ad72017-08-03 17:14:08 -04002000#Param dx distance to translate in x ##
2001#Param dy distance to translate in y ##
Cary Clark8032b982017-07-28 11:04:54 -04002002
2003#Example
2004#Height 128
2005#Description
2006scale() followed by translate() produces different results from translate() followed
Mike Klein9ff8c8c2018-02-07 01:58:51 +00002007by scale().
Cary Clark8032b982017-07-28 11:04:54 -04002008
2009The blue stroke follows translate of (50, 50); a black
Mike Klein9ff8c8c2018-02-07 01:58:51 +00002010fill follows scale of (2, 1/2.f). After restoring the clip, which resets
Cary Clark8032b982017-07-28 11:04:54 -04002011Matrix, a red frame follows the same scale of (2, 1/2.f); a gray fill
2012follows translate of (50, 50).
2013##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002014void draw(SkCanvas* canvas) {
2015 SkPaint filledPaint;
2016 SkPaint outlinePaint;
2017 outlinePaint.setStyle(SkPaint::kStroke_Style);
2018 outlinePaint.setColor(SK_ColorBLUE);
2019 canvas->save();
2020 canvas->translate(50, 50);
2021 canvas->drawCircle(28, 28, 15, outlinePaint); // blue center: (50+28, 50+28)
2022 canvas->scale(2, 1/2.f);
2023 canvas->drawCircle(28, 28, 15, filledPaint); // black center: (50+(28*2), 50+(28/2))
2024 canvas->restore();
2025 filledPaint.setColor(SK_ColorGRAY);
2026 outlinePaint.setColor(SK_ColorRED);
2027 canvas->scale(2, 1/2.f);
2028 canvas->drawCircle(28, 28, 15, outlinePaint); // red center: (28*2, 28/2)
2029 canvas->translate(50, 50);
2030 canvas->drawCircle(28, 28, 15, filledPaint); // gray center: ((50+28)*2, (50+28)/2)
Cary Clark8032b982017-07-28 11:04:54 -04002031}
2032##
2033
Cary Clark2ade9972017-11-02 17:49:34 -04002034#SeeAlso concat() scale() skew() rotate() setMatrix
Cary Clark8032b982017-07-28 11:04:54 -04002035
2036##
2037
2038# ------------------------------------------------------------------------------
2039
2040#Method void scale(SkScalar sx, SkScalar sy)
2041
Cary Clarkab2621d2018-01-30 10:08:57 -05002042#In Matrix
2043#Line # scales Matrix ##
Cary Clark8032b982017-07-28 11:04:54 -04002044Scale Matrix by sx on the x-axis and sy on the y-axis.
2045
2046Mathematically, replace Matrix with a scale matrix
Mike Klein9ff8c8c2018-02-07 01:58:51 +00002047Premultiplied with Matrix.
Cary Clark8032b982017-07-28 11:04:54 -04002048
2049This has the effect of scaling the drawing by (sx, sy) before transforming
2050the result with Matrix.
2051
Cary Clarkbad5ad72017-08-03 17:14:08 -04002052#Param sx amount to scale in x ##
2053#Param sy amount to scale in y ##
Cary Clark8032b982017-07-28 11:04:54 -04002054
2055#Example
2056#Height 160
Cary Clarkbad5ad72017-08-03 17:14:08 -04002057void draw(SkCanvas* canvas) {
2058 SkPaint paint;
2059 SkRect rect = { 10, 20, 60, 120 };
2060 canvas->translate(20, 20);
2061 canvas->drawRect(rect, paint);
2062 canvas->scale(2, .5f);
2063 paint.setColor(SK_ColorGRAY);
2064 canvas->drawRect(rect, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002065}
2066##
2067
Cary Clark2ade9972017-11-02 17:49:34 -04002068#SeeAlso concat() translate() skew() rotate() setMatrix
Cary Clark8032b982017-07-28 11:04:54 -04002069
2070##
2071
2072# ------------------------------------------------------------------------------
2073
2074#Method void rotate(SkScalar degrees)
2075
Cary Clarkab2621d2018-01-30 10:08:57 -05002076#In Matrix
2077#Line # rotates Matrix ##
Cary Clark8032b982017-07-28 11:04:54 -04002078Rotate Matrix by degrees. Positive degrees rotates clockwise.
2079
2080Mathematically, replace Matrix with a rotation matrix
Mike Klein9ff8c8c2018-02-07 01:58:51 +00002081Premultiplied with Matrix.
Cary Clark8032b982017-07-28 11:04:54 -04002082
2083This has the effect of rotating the drawing by degrees before transforming
2084the result with Matrix.
2085
Cary Clarkbad5ad72017-08-03 17:14:08 -04002086#Param degrees amount to rotate, in degrees ##
Cary Clark8032b982017-07-28 11:04:54 -04002087
2088#Example
2089#Description
2090Draw clock hands at time 5:10. The hour hand and minute hand point up and
2091are rotated clockwise.
2092##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002093void draw(SkCanvas* canvas) {
2094 SkPaint paint;
2095 paint.setStyle(SkPaint::kStroke_Style);
2096 canvas->translate(128, 128);
2097 canvas->drawCircle(0, 0, 60, paint);
2098 canvas->save();
2099 canvas->rotate(10 * 360 / 60); // 10 minutes of 60 scaled to 360 degrees
Mike Klein9ff8c8c2018-02-07 01:58:51 +00002100 canvas->drawLine(0, 0, 0, -50, paint);
Cary Clarkbad5ad72017-08-03 17:14:08 -04002101 canvas->restore();
2102 canvas->rotate((5 + 10.f/60) * 360 / 12); // 5 and 10/60 hours of 12 scaled to 360 degrees
2103 canvas->drawLine(0, 0, 0, -30, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002104}
2105##
2106
Cary Clark2ade9972017-11-02 17:49:34 -04002107#SeeAlso concat() translate() skew() scale() setMatrix
Cary Clark8032b982017-07-28 11:04:54 -04002108
2109##
2110
2111# ------------------------------------------------------------------------------
2112
2113#Method void rotate(SkScalar degrees, SkScalar px, SkScalar py)
2114
Cary Clarkab2621d2018-01-30 10:08:57 -05002115#In Matrix
Cary Clarkbad5ad72017-08-03 17:14:08 -04002116Rotate Matrix by degrees about a point at (px, py). Positive degrees rotates
2117clockwise.
Cary Clark8032b982017-07-28 11:04:54 -04002118
Cary Clarkce101242017-09-01 15:51:02 -04002119Mathematically, construct a rotation matrix. Premultiply the rotation matrix by
Cary Clark8032b982017-07-28 11:04:54 -04002120a translation matrix, then replace Matrix with the resulting matrix
Mike Klein9ff8c8c2018-02-07 01:58:51 +00002121Premultiplied with Matrix.
Cary Clark8032b982017-07-28 11:04:54 -04002122
Cary Clarkbad5ad72017-08-03 17:14:08 -04002123This has the effect of rotating the drawing about a given point before
2124transforming the result with Matrix.
Cary Clark8032b982017-07-28 11:04:54 -04002125
Cary Clarkbad5ad72017-08-03 17:14:08 -04002126#Param degrees amount to rotate, in degrees ##
2127#Param px x-coordinate of the point to rotate about ##
2128#Param py y-coordinate of the point to rotate about ##
Cary Clark8032b982017-07-28 11:04:54 -04002129
2130#Example
2131#Height 192
Cary Clarkbad5ad72017-08-03 17:14:08 -04002132void draw(SkCanvas* canvas) {
2133 SkPaint paint;
2134 paint.setTextSize(96);
2135 canvas->drawString("A1", 130, 100, paint);
2136 canvas->rotate(180, 130, 100);
2137 canvas->drawString("A1", 130, 100, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002138}
2139##
2140
Cary Clark2ade9972017-11-02 17:49:34 -04002141#SeeAlso concat() translate() skew() scale() setMatrix
Cary Clark8032b982017-07-28 11:04:54 -04002142
2143##
2144
2145# ------------------------------------------------------------------------------
2146
2147#Method void skew(SkScalar sx, SkScalar sy)
2148
Cary Clarkab2621d2018-01-30 10:08:57 -05002149#In Matrix
2150#Line # skews Matrix ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002151Skew Matrix by sx on the x-axis and sy on the y-axis. A positive value of sx
2152skews the drawing right as y increases; a positive value of sy skews the drawing
2153down as x increases.
Cary Clark8032b982017-07-28 11:04:54 -04002154
Mike Klein9ff8c8c2018-02-07 01:58:51 +00002155Mathematically, replace Matrix with a skew matrix Premultiplied with Matrix.
Cary Clark8032b982017-07-28 11:04:54 -04002156
Cary Clarkbad5ad72017-08-03 17:14:08 -04002157This has the effect of skewing the drawing by (sx, sy) before transforming
Cary Clark8032b982017-07-28 11:04:54 -04002158the result with Matrix.
2159
Cary Clarkbad5ad72017-08-03 17:14:08 -04002160#Param sx amount to skew in x ##
2161#Param sy amount to skew in y ##
2162
Cary Clark8032b982017-07-28 11:04:54 -04002163#Example
Mike Klein9ff8c8c2018-02-07 01:58:51 +00002164 #Description
Cary Clark8032b982017-07-28 11:04:54 -04002165 Black text mimics an oblique text style by using a negative skew in x that
2166 shifts the geometry to the right as the y values decrease.
2167 Red text uses a positive skew in y to shift the geometry down as the x values
2168 increase.
2169 Blue text combines x and y skew to rotate and scale.
2170 ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002171 SkPaint paint;
2172 paint.setTextSize(128);
2173 canvas->translate(30, 130);
2174 canvas->save();
2175 canvas->skew(-.5, 0);
2176 canvas->drawString("A1", 0, 0, paint);
2177 canvas->restore();
2178 canvas->save();
2179 canvas->skew(0, .5);
2180 paint.setColor(SK_ColorRED);
2181 canvas->drawString("A1", 0, 0, paint);
2182 canvas->restore();
2183 canvas->skew(-.5, .5);
2184 paint.setColor(SK_ColorBLUE);
Cary Clark8032b982017-07-28 11:04:54 -04002185 canvas->drawString("A1", 0, 0, paint);
2186##
2187
Cary Clark2ade9972017-11-02 17:49:34 -04002188#SeeAlso concat() translate() rotate() scale() setMatrix
Cary Clark8032b982017-07-28 11:04:54 -04002189
2190##
2191
2192# ------------------------------------------------------------------------------
2193
2194#Method void concat(const SkMatrix& matrix)
2195
Cary Clarkab2621d2018-01-30 10:08:57 -05002196#In Matrix
2197#Line # multiplies Matrix by Matrix ##
Cary Clarkce101242017-09-01 15:51:02 -04002198Replace Matrix with matrix Premultiplied with existing Matrix.
Cary Clark8032b982017-07-28 11:04:54 -04002199
Cary Clarkbad5ad72017-08-03 17:14:08 -04002200This has the effect of transforming the drawn geometry by matrix, before
2201transforming the result with existing Matrix.
Cary Clark8032b982017-07-28 11:04:54 -04002202
Cary Clarkce101242017-09-01 15:51:02 -04002203#Param matrix matrix to Premultiply with existing Matrix ##
Cary Clark8032b982017-07-28 11:04:54 -04002204
2205#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04002206void draw(SkCanvas* canvas) {
2207 SkPaint paint;
2208 paint.setTextSize(80);
2209 paint.setTextScaleX(.3);
2210 SkMatrix matrix;
2211 SkRect rect[2] = {{ 10, 20, 90, 110 }, { 40, 130, 140, 180 }};
2212 matrix.setRectToRect(rect[0], rect[1], SkMatrix::kFill_ScaleToFit);
2213 canvas->drawRect(rect[0], paint);
2214 canvas->drawRect(rect[1], paint);
2215 paint.setColor(SK_ColorWHITE);
2216 canvas->drawString("Here", rect[0].fLeft + 10, rect[0].fBottom - 10, paint);
2217 canvas->concat(matrix);
2218 canvas->drawString("There", rect[0].fLeft + 10, rect[0].fBottom - 10, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002219}
2220##
2221
Cary Clark2ade9972017-11-02 17:49:34 -04002222#SeeAlso translate() rotate() scale() skew() setMatrix
Cary Clark8032b982017-07-28 11:04:54 -04002223
2224##
2225
2226# ------------------------------------------------------------------------------
2227
2228#Method void setMatrix(const SkMatrix& matrix)
2229
Cary Clarkab2621d2018-01-30 10:08:57 -05002230#In Matrix
2231#Line # sets Matrix ##
Cary Clark8032b982017-07-28 11:04:54 -04002232Replace Matrix with matrix.
2233Unlike concat(), any prior matrix state is overwritten.
2234
Cary Clarkbad5ad72017-08-03 17:14:08 -04002235#Param matrix matrix to copy, replacing existing Matrix ##
Cary Clark8032b982017-07-28 11:04:54 -04002236
2237#Example
2238#Height 128
Cary Clarkbad5ad72017-08-03 17:14:08 -04002239void draw(SkCanvas* canvas) {
2240 SkPaint paint;
2241 canvas->scale(4, 6);
2242 canvas->drawString("truth", 2, 10, paint);
2243 SkMatrix matrix;
2244 matrix.setScale(2.8f, 6);
2245 canvas->setMatrix(matrix);
2246 canvas->drawString("consequences", 2, 20, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002247}
2248##
2249
Cary Clark2ade9972017-11-02 17:49:34 -04002250#SeeAlso resetMatrix concat() translate() rotate() scale() skew()
Cary Clark8032b982017-07-28 11:04:54 -04002251
2252##
2253
2254# ------------------------------------------------------------------------------
2255
2256#Method void resetMatrix()
2257
Cary Clarkab2621d2018-01-30 10:08:57 -05002258#In Matrix
2259#Line # resets Matrix to identity ##
Cary Clark8032b982017-07-28 11:04:54 -04002260Sets Matrix to the identity matrix.
2261Any prior matrix state is overwritten.
2262
2263#Example
2264#Height 128
Cary Clarkbad5ad72017-08-03 17:14:08 -04002265void draw(SkCanvas* canvas) {
2266 SkPaint paint;
2267 canvas->scale(4, 6);
2268 canvas->drawString("truth", 2, 10, paint);
2269 canvas->resetMatrix();
2270 canvas->scale(2.8f, 6);
2271 canvas->drawString("consequences", 2, 20, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002272}
2273##
2274
Cary Clark2ade9972017-11-02 17:49:34 -04002275#SeeAlso setMatrix concat() translate() rotate() scale() skew()
Cary Clark8032b982017-07-28 11:04:54 -04002276
2277##
2278
2279# ------------------------------------------------------------------------------
2280
2281#Method const SkMatrix& getTotalMatrix() const
2282
Cary Clarkab2621d2018-01-30 10:08:57 -05002283#In Matrix
2284#Line # returns Matrix ##
Cary Clark8032b982017-07-28 11:04:54 -04002285Returns Matrix.
2286This does not account for translation by Device or Surface.
2287
Cary Clarkbad5ad72017-08-03 17:14:08 -04002288#Return Matrix in Canvas ##
Cary Clark8032b982017-07-28 11:04:54 -04002289
2290#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04002291 SkDebugf("isIdentity %s\n", canvas->getTotalMatrix().isIdentity() ? "true" : "false");
2292 #StdOut
2293 isIdentity true
2294 ##
Cary Clark8032b982017-07-28 11:04:54 -04002295##
2296
Cary Clark2ade9972017-11-02 17:49:34 -04002297#SeeAlso setMatrix resetMatrix concat()
Cary Clark8032b982017-07-28 11:04:54 -04002298
2299##
2300
Cary Clark08895c42018-02-01 09:37:32 -05002301#Subtopic Matrix ##
Cary Clark8032b982017-07-28 11:04:54 -04002302
2303# ------------------------------------------------------------------------------
Cary Clark08895c42018-02-01 09:37:32 -05002304#Subtopic Clip
2305#Line # stack of clipping Paths ##
Cary Clark8032b982017-07-28 11:04:54 -04002306
2307Clip is built from a stack of clipping paths. Each Path in the
Mike Klein9ff8c8c2018-02-07 01:58:51 +00002308stack can be constructed from one or more Path_Contour elements. The
Cary Clark8032b982017-07-28 11:04:54 -04002309Path_Contour may be composed of any number of Path_Verb segments. Each
2310Path_Contour forms a closed area; Path_Fill_Type defines the area enclosed
2311by Path_Contour.
2312
2313Clip stack of Path elements successfully restrict the Path area. Each
Mike Klein9ff8c8c2018-02-07 01:58:51 +00002314Path is transformed by Matrix, then intersected with or subtracted from the
Cary Clark8032b982017-07-28 11:04:54 -04002315prior Clip to form the replacement Clip. Use SkClipOp::kDifference
2316to subtract Path from Clip; use SkClipOp::kIntersect to intersect Path
2317with Clip.
2318
Cary Clarkce101242017-09-01 15:51:02 -04002319A clipping Path may be Anti-aliased; if Path, after transformation, is
Cary Clark8032b982017-07-28 11:04:54 -04002320composed of horizontal and vertical lines, clearing Anti-alias allows whole pixels
Cary Clarkce101242017-09-01 15:51:02 -04002321to either be inside or outside the clip. The fastest drawing has a Aliased,
2322rectangular clip.
Cary Clark8032b982017-07-28 11:04:54 -04002323
2324If clipping Path has Anti-alias set, clip may partially clip a pixel, requiring
Mike Klein9ff8c8c2018-02-07 01:58:51 +00002325that drawing blend partially with the destination along the edge. A rotated
Cary Clarkce101242017-09-01 15:51:02 -04002326rectangular Anti-aliased clip looks smoother but draws slower.
Cary Clark8032b982017-07-28 11:04:54 -04002327
2328Clip can combine with Rect and Round_Rect primitives; like
2329Path, these are transformed by Matrix before they are combined with Clip.
2330
2331Clip can combine with Region. Region is assumed to be in Device coordinates
2332and is unaffected by Matrix.
2333
2334#Example
2335#Height 90
2336 #Description
Cary Clarkce101242017-09-01 15:51:02 -04002337 Draw a red circle with an Aliased clip and an Anti-aliased clip.
Cary Clark8032b982017-07-28 11:04:54 -04002338 Use an image filter to zoom into the pixels drawn.
Cary Clarkce101242017-09-01 15:51:02 -04002339 The edge of the Aliased clip fully draws pixels in the red circle.
2340 The edge of the Anti-aliased clip partially draws pixels in the red circle.
Cary Clark8032b982017-07-28 11:04:54 -04002341 ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002342 SkPaint redPaint, scalePaint;
2343 redPaint.setAntiAlias(true);
2344 redPaint.setColor(SK_ColorRED);
2345 canvas->save();
2346 for (bool antialias : { false, true } ) {
2347 canvas->save();
2348 canvas->clipRect(SkRect::MakeWH(19.5f, 11.5f), antialias);
2349 canvas->drawCircle(17, 11, 8, redPaint);
2350 canvas->restore();
2351 canvas->translate(16, 0);
2352 }
2353 canvas->restore();
2354 SkMatrix matrix;
2355 matrix.setScale(6, 6);
2356 scalePaint.setImageFilter(
2357 SkImageFilter::MakeMatrixFilter(matrix, kNone_SkFilterQuality, nullptr));
2358 SkCanvas::SaveLayerRec saveLayerRec(
Mike Klein9ff8c8c2018-02-07 01:58:51 +00002359 nullptr, &scalePaint, SkCanvas::kInitWithPrevious_SaveLayerFlag);
Cary Clarkbad5ad72017-08-03 17:14:08 -04002360 canvas->saveLayer(saveLayerRec);
Cary Clark8032b982017-07-28 11:04:54 -04002361 canvas->restore();
2362##
2363
2364#Method void clipRect(const SkRect& rect, SkClipOp op, bool doAntiAlias)
2365
Cary Clarkab2621d2018-01-30 10:08:57 -05002366#In Clip
2367#Line # combines Clip with Rect ##
Cary Clark8032b982017-07-28 11:04:54 -04002368Replace Clip with the intersection or difference of Clip and rect,
Cary Clarkce101242017-09-01 15:51:02 -04002369with an Aliased or Anti-aliased clip edge. rect is transformed by Matrix
Cary Clark8032b982017-07-28 11:04:54 -04002370before it is combined with Clip.
2371
Cary Clarka523d2d2017-08-30 08:58:10 -04002372#Param rect Rect to combine with Clip ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002373#Param op Clip_Op to apply to Clip ##
Cary Clarkce101242017-09-01 15:51:02 -04002374#Param doAntiAlias true if Clip is to be Anti-aliased ##
Cary Clark8032b982017-07-28 11:04:54 -04002375
2376#Example
2377#Height 128
Cary Clarkbad5ad72017-08-03 17:14:08 -04002378void draw(SkCanvas* canvas) {
2379 canvas->rotate(10);
2380 SkPaint paint;
2381 paint.setAntiAlias(true);
2382 for (auto alias: { false, true } ) {
2383 canvas->save();
2384 canvas->clipRect(SkRect::MakeWH(90, 80), SkClipOp::kIntersect, alias);
2385 canvas->drawCircle(100, 60, 60, paint);
2386 canvas->restore();
2387 canvas->translate(80, 0);
2388 }
Cary Clark8032b982017-07-28 11:04:54 -04002389}
2390##
2391
Cary Clark2ade9972017-11-02 17:49:34 -04002392#SeeAlso clipRRect clipPath clipRegion
Cary Clark8032b982017-07-28 11:04:54 -04002393
2394##
2395
Mike Klein9ff8c8c2018-02-07 01:58:51 +00002396#Method void clipRect(const SkRect& rect, SkClipOp op)
Cary Clark8032b982017-07-28 11:04:54 -04002397
Cary Clarkab2621d2018-01-30 10:08:57 -05002398#In Clip
Cary Clark8032b982017-07-28 11:04:54 -04002399Replace Clip with the intersection or difference of Clip and rect.
Cary Clarkce101242017-09-01 15:51:02 -04002400Resulting Clip is Aliased; pixels are fully contained by the clip.
Cary Clarkbad5ad72017-08-03 17:14:08 -04002401rect is transformed by Matrix before it is combined with Clip.
Cary Clark8032b982017-07-28 11:04:54 -04002402
Cary Clarka523d2d2017-08-30 08:58:10 -04002403#Param rect Rect to combine with Clip ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002404#Param op Clip_Op to apply to Clip ##
Cary Clark8032b982017-07-28 11:04:54 -04002405
2406#Example
2407#Height 192
2408#Width 280
Cary Clarkbad5ad72017-08-03 17:14:08 -04002409void draw(SkCanvas* canvas) {
2410 SkPaint paint;
2411 for (SkClipOp op: { SkClipOp::kIntersect, SkClipOp::kDifference } ) {
2412 canvas->save();
2413 canvas->clipRect(SkRect::MakeWH(90, 120), op, false);
2414 canvas->drawCircle(100, 100, 60, paint);
2415 canvas->restore();
2416 canvas->translate(80, 0);
2417 }
Cary Clark8032b982017-07-28 11:04:54 -04002418}
2419##
2420
Cary Clark2ade9972017-11-02 17:49:34 -04002421#SeeAlso clipRRect clipPath clipRegion
Cary Clark8032b982017-07-28 11:04:54 -04002422
2423##
2424
Mike Klein9ff8c8c2018-02-07 01:58:51 +00002425#Method void clipRect(const SkRect& rect, bool doAntiAlias = false)
Cary Clark8032b982017-07-28 11:04:54 -04002426
Cary Clarkab2621d2018-01-30 10:08:57 -05002427#In Clip
Cary Clark8032b982017-07-28 11:04:54 -04002428Replace Clip with the intersection of Clip and rect.
Cary Clarkce101242017-09-01 15:51:02 -04002429Resulting Clip is Aliased; pixels are fully contained by the clip.
Cary Clark8032b982017-07-28 11:04:54 -04002430rect is transformed by Matrix
2431before it is combined with Clip.
2432
Cary Clarka523d2d2017-08-30 08:58:10 -04002433#Param rect Rect to combine with Clip ##
Cary Clarkce101242017-09-01 15:51:02 -04002434#Param doAntiAlias true if Clip is to be Anti-aliased ##
Cary Clark8032b982017-07-28 11:04:54 -04002435
2436#Example
2437#Height 133
2438 #Description
Cary Clarkce101242017-09-01 15:51:02 -04002439 A circle drawn in pieces looks uniform when drawn Aliased.
2440 The same circle pieces blend with pixels more than once when Anti-aliased,
Cary Clark8032b982017-07-28 11:04:54 -04002441 visible as a thin pair of lines through the right circle.
2442 ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002443void draw(SkCanvas* canvas) {
2444 canvas->clear(SK_ColorWHITE);
2445 SkPaint paint;
2446 paint.setAntiAlias(true);
2447 paint.setColor(0x8055aaff);
2448 SkRect clipRect = { 0, 0, 87.4f, 87.4f };
2449 for (auto alias: { false, true } ) {
2450 canvas->save();
2451 canvas->clipRect(clipRect, SkClipOp::kIntersect, alias);
2452 canvas->drawCircle(67, 67, 60, paint);
2453 canvas->restore();
2454 canvas->save();
2455 canvas->clipRect(clipRect, SkClipOp::kDifference, alias);
2456 canvas->drawCircle(67, 67, 60, paint);
2457 canvas->restore();
2458 canvas->translate(120, 0);
2459 }
Cary Clark8032b982017-07-28 11:04:54 -04002460}
2461##
2462
Cary Clark2ade9972017-11-02 17:49:34 -04002463#SeeAlso clipRRect clipPath clipRegion
Cary Clark8032b982017-07-28 11:04:54 -04002464
2465##
2466
2467#Method void androidFramework_setDeviceClipRestriction(const SkIRect& rect)
2468
Cary Clarkab2621d2018-01-30 10:08:57 -05002469#In Clip
2470#Line # for use by Android framework ##
Cary Clarkce101242017-09-01 15:51:02 -04002471Sets the maximum clip rectangle, which can be set by clipRect, clipRRect and
Cary Clark8032b982017-07-28 11:04:54 -04002472clipPath and intersect the current clip with the specified rect.
Cary Clarkce101242017-09-01 15:51:02 -04002473The maximum clip affects only future clipping operations; it is not retroactive.
Cary Clark8032b982017-07-28 11:04:54 -04002474The clip restriction is not recorded in pictures.
2475
Mike Klein9ff8c8c2018-02-07 01:58:51 +00002476Pass an empty rect to disable maximum clip.
Cary Clarkbad5ad72017-08-03 17:14:08 -04002477
Cary Clark8032b982017-07-28 11:04:54 -04002478#Private
2479This is private API to be used only by Android framework.
2480##
2481
Cary Clarkbad5ad72017-08-03 17:14:08 -04002482#Param rect maximum allowed clip in device coordinates
Cary Clark579985c2017-07-31 11:48:27 -04002483#Param ##
Cary Clark8032b982017-07-28 11:04:54 -04002484
2485##
2486
2487#Method void clipRRect(const SkRRect& rrect, SkClipOp op, bool doAntiAlias)
2488
Cary Clarkab2621d2018-01-30 10:08:57 -05002489#In Clip
2490#Line # combines Clip with Round_Rect ##
Cary Clark8032b982017-07-28 11:04:54 -04002491Replace Clip with the intersection or difference of Clip and rrect,
Cary Clarkce101242017-09-01 15:51:02 -04002492with an Aliased or Anti-aliased clip edge.
Cary Clark8032b982017-07-28 11:04:54 -04002493rrect is transformed by Matrix
2494before it is combined with Clip.
2495
Cary Clarkbad5ad72017-08-03 17:14:08 -04002496#Param rrect Round_Rect to combine with Clip ##
2497#Param op Clip_Op to apply to Clip ##
Cary Clarkce101242017-09-01 15:51:02 -04002498#Param doAntiAlias true if Clip is to be Anti-aliased ##
Cary Clark8032b982017-07-28 11:04:54 -04002499
2500#Example
2501#Height 128
Cary Clarkbad5ad72017-08-03 17:14:08 -04002502void draw(SkCanvas* canvas) {
2503 canvas->clear(SK_ColorWHITE);
2504 SkPaint paint;
2505 paint.setAntiAlias(true);
2506 paint.setColor(0x8055aaff);
2507 SkRRect oval;
2508 oval.setOval({10, 20, 90, 100});
2509 canvas->clipRRect(oval, SkClipOp::kIntersect, true);
2510 canvas->drawCircle(70, 100, 60, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002511}
2512##
2513
Cary Clark2ade9972017-11-02 17:49:34 -04002514#SeeAlso clipRect clipPath clipRegion
Cary Clark8032b982017-07-28 11:04:54 -04002515
2516##
2517
Mike Klein9ff8c8c2018-02-07 01:58:51 +00002518#Method void clipRRect(const SkRRect& rrect, SkClipOp op)
Cary Clark8032b982017-07-28 11:04:54 -04002519
Cary Clarkab2621d2018-01-30 10:08:57 -05002520#In Clip
Cary Clark8032b982017-07-28 11:04:54 -04002521Replace Clip with the intersection or difference of Clip and rrect.
Cary Clarkce101242017-09-01 15:51:02 -04002522Resulting Clip is Aliased; pixels are fully contained by the clip.
Cary Clarkbad5ad72017-08-03 17:14:08 -04002523rrect is transformed by Matrix before it is combined with Clip.
Cary Clark8032b982017-07-28 11:04:54 -04002524
Cary Clarkbad5ad72017-08-03 17:14:08 -04002525#Param rrect Round_Rect to combine with Clip ##
2526#Param op Clip_Op to apply to Clip ##
Cary Clark8032b982017-07-28 11:04:54 -04002527
2528#Example
2529#Height 128
Cary Clarkbad5ad72017-08-03 17:14:08 -04002530void draw(SkCanvas* canvas) {
2531 SkPaint paint;
2532 paint.setColor(0x8055aaff);
2533 auto oval = SkRRect::MakeOval({10, 20, 90, 100});
2534 canvas->clipRRect(oval, SkClipOp::kIntersect);
2535 canvas->drawCircle(70, 100, 60, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002536}
2537##
2538
Cary Clark2ade9972017-11-02 17:49:34 -04002539#SeeAlso clipRect clipPath clipRegion
Cary Clark8032b982017-07-28 11:04:54 -04002540
2541##
2542
Mike Klein9ff8c8c2018-02-07 01:58:51 +00002543#Method void clipRRect(const SkRRect& rrect, bool doAntiAlias = false)
Cary Clark8032b982017-07-28 11:04:54 -04002544
Cary Clarkab2621d2018-01-30 10:08:57 -05002545#In Clip
Cary Clark8032b982017-07-28 11:04:54 -04002546Replace Clip with the intersection of Clip and rrect,
Cary Clarkce101242017-09-01 15:51:02 -04002547with an Aliased or Anti-aliased clip edge.
Cary Clarkbad5ad72017-08-03 17:14:08 -04002548rrect is transformed by Matrix before it is combined with Clip.
Cary Clark8032b982017-07-28 11:04:54 -04002549
Cary Clarkbad5ad72017-08-03 17:14:08 -04002550#Param rrect Round_Rect to combine with Clip ##
Cary Clarkce101242017-09-01 15:51:02 -04002551#Param doAntiAlias true if Clip is to be Anti-aliased ##
Cary Clark8032b982017-07-28 11:04:54 -04002552
2553#Example
2554#Height 128
Cary Clarkbad5ad72017-08-03 17:14:08 -04002555void draw(SkCanvas* canvas) {
2556 SkPaint paint;
2557 paint.setAntiAlias(true);
2558 auto oval = SkRRect::MakeRectXY({10, 20, 90, 100}, 9, 13);
2559 canvas->clipRRect(oval, true);
2560 canvas->drawCircle(70, 100, 60, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002561}
2562##
2563
Cary Clark2ade9972017-11-02 17:49:34 -04002564#SeeAlso clipRect clipPath clipRegion
Cary Clark8032b982017-07-28 11:04:54 -04002565
2566##
2567
2568#Method void clipPath(const SkPath& path, SkClipOp op, bool doAntiAlias)
2569
Cary Clarkab2621d2018-01-30 10:08:57 -05002570#In Clip
2571#Line # combines Clip with Path ##
Cary Clark8032b982017-07-28 11:04:54 -04002572Replace Clip with the intersection or difference of Clip and path,
Cary Clarkce101242017-09-01 15:51:02 -04002573with an Aliased or Anti-aliased clip edge. Path_Fill_Type determines if path
Cary Clark8032b982017-07-28 11:04:54 -04002574describes the area inside or outside its contours; and if Path_Contour overlaps
2575itself or another Path_Contour, whether the overlaps form part of the area.
Cary Clarkbad5ad72017-08-03 17:14:08 -04002576path is transformed by Matrix before it is combined with Clip.
Cary Clark8032b982017-07-28 11:04:54 -04002577
Cary Clarkbad5ad72017-08-03 17:14:08 -04002578#Param path Path to combine with Clip ##
2579#Param op Clip_Op to apply to Clip ##
Cary Clarkce101242017-09-01 15:51:02 -04002580#Param doAntiAlias true if Clip is to be Anti-aliased ##
Cary Clark8032b982017-07-28 11:04:54 -04002581
2582#Example
2583#Description
2584Top figure uses SkPath::kInverseWinding_FillType and SkClipOp::kDifference;
2585area outside clip is subtracted from circle.
2586
2587Bottom figure uses SkPath::kWinding_FillType and SkClipOp::kIntersect;
2588area inside clip is intersected with circle.
2589##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002590void draw(SkCanvas* canvas) {
2591 SkPaint paint;
2592 paint.setAntiAlias(true);
2593 SkPath path;
2594 path.addRect({20, 30, 100, 110});
2595 path.setFillType(SkPath::kInverseWinding_FillType);
2596 canvas->save();
2597 canvas->clipPath(path, SkClipOp::kDifference, false);
2598 canvas->drawCircle(70, 100, 60, paint);
2599 canvas->restore();
2600 canvas->translate(100, 100);
2601 path.setFillType(SkPath::kWinding_FillType);
2602 canvas->clipPath(path, SkClipOp::kIntersect, false);
2603 canvas->drawCircle(70, 100, 60, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002604}
2605##
2606
Cary Clark2ade9972017-11-02 17:49:34 -04002607#SeeAlso clipRect clipRRect clipRegion
Cary Clark8032b982017-07-28 11:04:54 -04002608
2609##
2610
Mike Klein9ff8c8c2018-02-07 01:58:51 +00002611#Method void clipPath(const SkPath& path, SkClipOp op)
Cary Clark8032b982017-07-28 11:04:54 -04002612
Cary Clarkab2621d2018-01-30 10:08:57 -05002613#In Clip
Cary Clark8032b982017-07-28 11:04:54 -04002614Replace Clip with the intersection or difference of Clip and path.
Cary Clarkce101242017-09-01 15:51:02 -04002615Resulting Clip is Aliased; pixels are fully contained by the clip.
Cary Clark8032b982017-07-28 11:04:54 -04002616Path_Fill_Type determines if path
2617describes the area inside or outside its contours; and if Path_Contour overlaps
2618itself or another Path_Contour, whether the overlaps form part of the area.
2619path is transformed by Matrix
2620before it is combined with Clip.
2621
Cary Clarkbad5ad72017-08-03 17:14:08 -04002622#Param path Path to combine with Clip ##
2623#Param op Clip_Op to apply to Clip ##
Cary Clark8032b982017-07-28 11:04:54 -04002624
2625#Example
2626#Description
Cary Clarkbc5697d2017-10-04 14:31:33 -04002627Overlapping Rects form a clip. When clip Path_Fill_Type is set to
Mike Klein9ff8c8c2018-02-07 01:58:51 +00002628SkPath::kWinding_FillType, the overlap is included. Set to
Cary Clark8032b982017-07-28 11:04:54 -04002629SkPath::kEvenOdd_FillType, the overlap is excluded and forms a hole.
2630##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002631void draw(SkCanvas* canvas) {
2632 SkPaint paint;
2633 paint.setAntiAlias(true);
2634 SkPath path;
2635 path.addRect({20, 15, 100, 95});
2636 path.addRect({50, 65, 130, 135});
2637 path.setFillType(SkPath::kWinding_FillType);
2638 canvas->save();
2639 canvas->clipPath(path, SkClipOp::kIntersect);
2640 canvas->drawCircle(70, 85, 60, paint);
2641 canvas->restore();
2642 canvas->translate(100, 100);
2643 path.setFillType(SkPath::kEvenOdd_FillType);
2644 canvas->clipPath(path, SkClipOp::kIntersect);
2645 canvas->drawCircle(70, 85, 60, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002646}
2647##
2648
Cary Clark2ade9972017-11-02 17:49:34 -04002649#SeeAlso clipRect clipRRect clipRegion
Cary Clark8032b982017-07-28 11:04:54 -04002650
2651##
2652
Mike Klein9ff8c8c2018-02-07 01:58:51 +00002653#Method void clipPath(const SkPath& path, bool doAntiAlias = false)
Cary Clark8032b982017-07-28 11:04:54 -04002654
Cary Clarkab2621d2018-01-30 10:08:57 -05002655#In Clip
Cary Clark8032b982017-07-28 11:04:54 -04002656Replace Clip with the intersection of Clip and path.
Cary Clarkce101242017-09-01 15:51:02 -04002657Resulting Clip is Aliased; pixels are fully contained by the clip.
Cary Clark8032b982017-07-28 11:04:54 -04002658Path_Fill_Type determines if path
2659describes the area inside or outside its contours; and if Path_Contour overlaps
2660itself or another Path_Contour, whether the overlaps form part of the area.
Cary Clarkbad5ad72017-08-03 17:14:08 -04002661path is transformed by Matrix before it is combined with Clip.
Cary Clark8032b982017-07-28 11:04:54 -04002662
Cary Clarkbad5ad72017-08-03 17:14:08 -04002663#Param path Path to combine with Clip ##
Cary Clarkce101242017-09-01 15:51:02 -04002664#Param doAntiAlias true if Clip is to be Anti-aliased ##
Cary Clark8032b982017-07-28 11:04:54 -04002665
2666#Example
2667#Height 212
2668#Description
Mike Klein9ff8c8c2018-02-07 01:58:51 +00002669Clip loops over itself covering its center twice. When clip Path_Fill_Type
2670is set to SkPath::kWinding_FillType, the overlap is included. Set to
Cary Clark8032b982017-07-28 11:04:54 -04002671SkPath::kEvenOdd_FillType, the overlap is excluded and forms a hole.
2672##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002673void draw(SkCanvas* canvas) {
2674 SkPaint paint;
2675 paint.setAntiAlias(true);
2676 SkPath path;
2677 SkPoint poly[] = {{20, 20}, { 80, 20}, { 80, 80}, {40, 80},
2678 {40, 40}, {100, 40}, {100, 100}, {20, 100}};
2679 path.addPoly(poly, SK_ARRAY_COUNT(poly), true);
2680 path.setFillType(SkPath::kWinding_FillType);
2681 canvas->save();
2682 canvas->clipPath(path, SkClipOp::kIntersect);
2683 canvas->drawCircle(50, 50, 45, paint);
2684 canvas->restore();
2685 canvas->translate(100, 100);
2686 path.setFillType(SkPath::kEvenOdd_FillType);
2687 canvas->clipPath(path, SkClipOp::kIntersect);
2688 canvas->drawCircle(50, 50, 45, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002689}
2690##
2691
Cary Clark2ade9972017-11-02 17:49:34 -04002692#SeeAlso clipRect clipRRect clipRegion
Cary Clark8032b982017-07-28 11:04:54 -04002693
2694##
2695
2696# ------------------------------------------------------------------------------
2697
Mike Klein9ff8c8c2018-02-07 01:58:51 +00002698#Method void setAllowSimplifyClip(bool allow)
Cary Clark8032b982017-07-28 11:04:54 -04002699
Cary Clarkab2621d2018-01-30 10:08:57 -05002700#In Clip
2701#Line # experimental ##
Cary Clark8032b982017-07-28 11:04:54 -04002702#Experimental
2703Only used for testing.
2704##
2705
Cary Clarkce101242017-09-01 15:51:02 -04002706Set to simplify clip stack using PathOps.
Cary Clark8032b982017-07-28 11:04:54 -04002707
2708##
2709
2710# ------------------------------------------------------------------------------
2711
2712#Method void clipRegion(const SkRegion& deviceRgn, SkClipOp op = SkClipOp::kIntersect)
2713
Cary Clarkab2621d2018-01-30 10:08:57 -05002714#In Clip
2715#Line # combines Clip with Region ##
Cary Clark8032b982017-07-28 11:04:54 -04002716Replace Clip with the intersection or difference of Clip and Region deviceRgn.
Cary Clarkce101242017-09-01 15:51:02 -04002717Resulting Clip is Aliased; pixels are fully contained by the clip.
Cary Clark8032b982017-07-28 11:04:54 -04002718deviceRgn is unaffected by Matrix.
2719
Cary Clarkbad5ad72017-08-03 17:14:08 -04002720#Param deviceRgn Region to combine with Clip ##
2721#Param op Clip_Op to apply to Clip ##
Cary Clark8032b982017-07-28 11:04:54 -04002722
2723#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04002724#Description
Cary Clarkce101242017-09-01 15:51:02 -04002725 region is unaffected by canvas rotation; iRect is affected by canvas rotation.
2726 Both clips are Aliased; this is not noticeable on Region clip because it
Cary Clarkbad5ad72017-08-03 17:14:08 -04002727 aligns to pixel boundaries.
2728##
2729void draw(SkCanvas* canvas) {
2730 SkPaint paint;
2731 paint.setAntiAlias(true);
2732 SkIRect iRect = {30, 40, 120, 130 };
2733 SkRegion region(iRect);
2734 canvas->rotate(10);
2735 canvas->save();
2736 canvas->clipRegion(region, SkClipOp::kIntersect);
2737 canvas->drawCircle(50, 50, 45, paint);
2738 canvas->restore();
2739 canvas->translate(100, 100);
2740 canvas->clipRect(SkRect::Make(iRect), SkClipOp::kIntersect);
2741 canvas->drawCircle(50, 50, 45, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002742}
2743##
2744
Cary Clark2ade9972017-11-02 17:49:34 -04002745#SeeAlso clipRect clipRRect clipPath
Cary Clark8032b982017-07-28 11:04:54 -04002746
2747##
2748
2749#Method bool quickReject(const SkRect& rect) const
2750
Cary Clarkab2621d2018-01-30 10:08:57 -05002751#In Clip
2752#Line # returns if Rect is outside Clip ##
Cary Clark8032b982017-07-28 11:04:54 -04002753Return true if Rect rect, transformed by Matrix, can be quickly determined to be
2754outside of Clip. May return false even though rect is outside of Clip.
2755
2756Use to check if an area to be drawn is clipped out, to skip subsequent draw calls.
2757
Cary Clarkbad5ad72017-08-03 17:14:08 -04002758#Param rect Rect to compare with Clip ##
Cary Clark8032b982017-07-28 11:04:54 -04002759
Cary Clarkbad5ad72017-08-03 17:14:08 -04002760#Return true if rect, transformed by Matrix, does not intersect Clip ##
Cary Clark8032b982017-07-28 11:04:54 -04002761
2762#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04002763void draw(SkCanvas* canvas) {
Mike Klein9ff8c8c2018-02-07 01:58:51 +00002764 SkRect testRect = {30, 30, 120, 129 };
2765 SkRect clipRect = {30, 130, 120, 230 };
Cary Clarkbad5ad72017-08-03 17:14:08 -04002766 canvas->save();
2767 canvas->clipRect(clipRect);
2768 SkDebugf("quickReject %s\n", canvas->quickReject(testRect) ? "true" : "false");
2769 canvas->restore();
2770 canvas->rotate(10);
2771 canvas->clipRect(clipRect);
2772 SkDebugf("quickReject %s\n", canvas->quickReject(testRect) ? "true" : "false");
Cary Clark8032b982017-07-28 11:04:54 -04002773}
2774 #StdOut
Cary Clarkbad5ad72017-08-03 17:14:08 -04002775 quickReject true
Cary Clark8032b982017-07-28 11:04:54 -04002776 quickReject false
2777 ##
2778##
2779
Cary Clark2ade9972017-11-02 17:49:34 -04002780#SeeAlso getLocalClipBounds getTotalMatrix SkBitmap::drawsNothing
Cary Clark8032b982017-07-28 11:04:54 -04002781
2782##
2783
2784#Method bool quickReject(const SkPath& path) const
2785
Cary Clarkab2621d2018-01-30 10:08:57 -05002786#In Clip
Cary Clark8032b982017-07-28 11:04:54 -04002787Return true if path, transformed by Matrix, can be quickly determined to be
2788outside of Clip. May return false even though path is outside of Clip.
2789
2790Use to check if an area to be drawn is clipped out, to skip subsequent draw calls.
2791
Cary Clarkbad5ad72017-08-03 17:14:08 -04002792#Param path Path to compare with Clip ##
Cary Clark8032b982017-07-28 11:04:54 -04002793
Cary Clarkbad5ad72017-08-03 17:14:08 -04002794#Return true if path, transformed by Matrix, does not intersect Clip ##
Cary Clark8032b982017-07-28 11:04:54 -04002795
2796#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04002797void draw(SkCanvas* canvas) {
Mike Klein9ff8c8c2018-02-07 01:58:51 +00002798 SkPoint testPoints[] = {{30, 30}, {120, 30}, {120, 129} };
2799 SkPoint clipPoints[] = {{30, 130}, {120, 130}, {120, 230} };
Cary Clarkbad5ad72017-08-03 17:14:08 -04002800 SkPath testPath, clipPath;
2801 testPath.addPoly(testPoints, SK_ARRAY_COUNT(testPoints), true);
2802 clipPath.addPoly(clipPoints, SK_ARRAY_COUNT(clipPoints), true);
2803 canvas->save();
2804 canvas->clipPath(clipPath);
2805 SkDebugf("quickReject %s\n", canvas->quickReject(testPath) ? "true" : "false");
2806 canvas->restore();
2807 canvas->rotate(10);
2808 canvas->clipPath(clipPath);
2809 SkDebugf("quickReject %s\n", canvas->quickReject(testPath) ? "true" : "false");
Cary Clark8032b982017-07-28 11:04:54 -04002810 #StdOut
Cary Clarkbad5ad72017-08-03 17:14:08 -04002811 quickReject true
Cary Clark8032b982017-07-28 11:04:54 -04002812 quickReject false
2813 ##
2814}
2815##
2816
Cary Clark2ade9972017-11-02 17:49:34 -04002817#SeeAlso getLocalClipBounds getTotalMatrix SkBitmap::drawsNothing
Cary Clark8032b982017-07-28 11:04:54 -04002818
2819##
2820
Mike Klein9ff8c8c2018-02-07 01:58:51 +00002821#Method SkRect getLocalClipBounds() const
Cary Clark8032b982017-07-28 11:04:54 -04002822
Cary Clarkab2621d2018-01-30 10:08:57 -05002823#In Clip
2824#Line # returns Clip bounds in source coordinates ##
Cary Clark8032b982017-07-28 11:04:54 -04002825Return bounds of Clip, transformed by inverse of Matrix. If Clip is empty,
2826return SkRect::MakeEmpty, where all Rect sides equal zero.
2827
2828Rect returned is outset by one to account for partial pixel coverage if Clip
Cary Clarkce101242017-09-01 15:51:02 -04002829is Anti-aliased.
Cary Clark8032b982017-07-28 11:04:54 -04002830
Cary Clarkbad5ad72017-08-03 17:14:08 -04002831#Return bounds of Clip in local coordinates ##
Cary Clark8032b982017-07-28 11:04:54 -04002832
2833#Example
Mike Klein9ff8c8c2018-02-07 01:58:51 +00002834 #Description
Cary Clark8032b982017-07-28 11:04:54 -04002835 Initial bounds is device bounds outset by 1 on all sides.
2836 Clipped bounds is clipPath bounds outset by 1 on all sides.
2837 Scaling the canvas by two in x and y scales the local bounds by 1/2 in x and y.
2838 ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002839 SkCanvas local(256, 256);
2840 canvas = &local;
2841 SkRect bounds = canvas->getLocalClipBounds();
2842 SkDebugf("left:%g top:%g right:%g bottom:%g\n",
2843 bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom);
Mike Klein9ff8c8c2018-02-07 01:58:51 +00002844 SkPoint clipPoints[] = {{30, 130}, {120, 130}, {120, 230} };
Cary Clarkbad5ad72017-08-03 17:14:08 -04002845 SkPath clipPath;
2846 clipPath.addPoly(clipPoints, SK_ARRAY_COUNT(clipPoints), true);
2847 canvas->clipPath(clipPath);
2848 bounds = canvas->getLocalClipBounds();
2849 SkDebugf("left:%g top:%g right:%g bottom:%g\n",
2850 bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom);
2851 canvas->scale(2, 2);
2852 bounds = canvas->getLocalClipBounds();
2853 SkDebugf("left:%g top:%g right:%g bottom:%g\n",
2854 bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom);
2855 #StdOut
2856 left:-1 top:-1 right:257 bottom:257
2857 left:29 top:129 right:121 bottom:231
2858 left:14.5 top:64.5 right:60.5 bottom:115.5
2859 ##
Cary Clark8032b982017-07-28 11:04:54 -04002860##
2861
2862# local canvas in example works around bug in fiddle ##
Cary Clark4855f782018-02-06 09:41:53 -05002863#Bug 6524
Cary Clark2ade9972017-11-02 17:49:34 -04002864#SeeAlso getDeviceClipBounds getBaseLayerSize quickReject
Cary Clark8032b982017-07-28 11:04:54 -04002865
2866##
2867
Mike Klein9ff8c8c2018-02-07 01:58:51 +00002868#Method bool getLocalClipBounds(SkRect* bounds) const
Cary Clark8032b982017-07-28 11:04:54 -04002869
Cary Clarkab2621d2018-01-30 10:08:57 -05002870#In Clip
Cary Clark8032b982017-07-28 11:04:54 -04002871Return bounds of Clip, transformed by inverse of Matrix. If Clip is empty,
2872return false, and set bounds to SkRect::MakeEmpty, where all Rect sides equal zero.
2873
2874bounds is outset by one to account for partial pixel coverage if Clip
Cary Clarkce101242017-09-01 15:51:02 -04002875is Anti-aliased.
Cary Clark8032b982017-07-28 11:04:54 -04002876
Cary Clarkbad5ad72017-08-03 17:14:08 -04002877#Param bounds Rect of Clip in local coordinates ##
Cary Clark8032b982017-07-28 11:04:54 -04002878
Cary Clarkbad5ad72017-08-03 17:14:08 -04002879#Return true if Clip bounds is not empty ##
Cary Clark8032b982017-07-28 11:04:54 -04002880
2881#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04002882 void draw(SkCanvas* canvas) {
2883 SkCanvas local(256, 256);
2884 canvas = &local;
2885 SkRect bounds;
2886 SkDebugf("local bounds empty = %s\n", canvas->getLocalClipBounds(&bounds)
2887 ? "false" : "true");
2888 SkPath path;
2889 canvas->clipPath(path);
2890 SkDebugf("local bounds empty = %s\n", canvas->getLocalClipBounds(&bounds)
2891 ? "false" : "true");
Cary Clark8032b982017-07-28 11:04:54 -04002892 }
2893 #StdOut
Cary Clarkbad5ad72017-08-03 17:14:08 -04002894 local bounds empty = false
Cary Clark8032b982017-07-28 11:04:54 -04002895 local bounds empty = true
2896 ##
2897##
2898
2899# local canvas in example works around bug in fiddle ##
Cary Clark4855f782018-02-06 09:41:53 -05002900#Bug 6524
Cary Clark2ade9972017-11-02 17:49:34 -04002901#SeeAlso getDeviceClipBounds getBaseLayerSize quickReject
Cary Clark8032b982017-07-28 11:04:54 -04002902
2903##
2904
Mike Klein9ff8c8c2018-02-07 01:58:51 +00002905#Method SkIRect getDeviceClipBounds() const
Cary Clark8032b982017-07-28 11:04:54 -04002906
Cary Clarkab2621d2018-01-30 10:08:57 -05002907#In Clip
2908#Line # returns IRect bounds of Clip ##
Cary Clark8032b982017-07-28 11:04:54 -04002909Return IRect bounds of Clip, unaffected by Matrix. If Clip is empty,
2910return SkRect::MakeEmpty, where all Rect sides equal zero.
2911
Mike Klein9ff8c8c2018-02-07 01:58:51 +00002912Unlike getLocalClipBounds, returned IRect is not outset.
Cary Clark8032b982017-07-28 11:04:54 -04002913
Cary Clarkbad5ad72017-08-03 17:14:08 -04002914#Return bounds of Clip in Device coordinates ##
Cary Clark8032b982017-07-28 11:04:54 -04002915
2916#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04002917void draw(SkCanvas* canvas) {
2918 #Description
Cary Clark8032b982017-07-28 11:04:54 -04002919 Initial bounds is device bounds, not outset.
2920 Clipped bounds is clipPath bounds, not outset.
2921 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 -04002922 ##
2923 SkCanvas device(256, 256);
2924 canvas = &device;
2925 SkIRect bounds = canvas->getDeviceClipBounds();
2926 SkDebugf("left:%d top:%d right:%d bottom:%d\n",
2927 bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom);
Mike Klein9ff8c8c2018-02-07 01:58:51 +00002928 SkPoint clipPoints[] = {{30, 130}, {120, 130}, {120, 230} };
Cary Clarkbad5ad72017-08-03 17:14:08 -04002929 SkPath clipPath;
2930 clipPath.addPoly(clipPoints, SK_ARRAY_COUNT(clipPoints), true);
2931 canvas->save();
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);
2936 canvas->restore();
2937 canvas->scale(1.f/2, 1.f/2);
2938 canvas->clipPath(clipPath);
2939 bounds = canvas->getDeviceClipBounds();
2940 SkDebugf("left:%d top:%d right:%d bottom:%d\n",
2941 bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom);
Cary Clark8032b982017-07-28 11:04:54 -04002942 #StdOut
Cary Clarkbad5ad72017-08-03 17:14:08 -04002943 left:0 top:0 right:256 bottom:256
2944 left:30 top:130 right:120 bottom:230
Cary Clark8032b982017-07-28 11:04:54 -04002945 left:15 top:65 right:60 bottom:115
2946 ##
2947}
2948##
2949
2950#ToDo some confusion on why with an identity Matrix local and device are different ##
Cary Clark2ade9972017-11-02 17:49:34 -04002951#SeeAlso getLocalClipBounds getBaseLayerSize quickReject
Cary Clark8032b982017-07-28 11:04:54 -04002952
2953# device canvas in example works around bug in fiddle ##
Cary Clark4855f782018-02-06 09:41:53 -05002954#Bug 6524
Cary Clark8032b982017-07-28 11:04:54 -04002955
2956##
2957
Mike Klein9ff8c8c2018-02-07 01:58:51 +00002958#Method bool getDeviceClipBounds(SkIRect* bounds) const
Cary Clark8032b982017-07-28 11:04:54 -04002959
Cary Clarkab2621d2018-01-30 10:08:57 -05002960#In Clip
Cary Clark8032b982017-07-28 11:04:54 -04002961Return IRect bounds of Clip, unaffected by Matrix. If Clip is empty,
2962return false, and set bounds to SkRect::MakeEmpty, where all Rect sides equal zero.
2963
Mike Klein9ff8c8c2018-02-07 01:58:51 +00002964Unlike getLocalClipBounds, bounds is not outset.
Cary Clark8032b982017-07-28 11:04:54 -04002965
Cary Clarkbad5ad72017-08-03 17:14:08 -04002966#Param bounds Rect of Clip in device coordinates ##
Cary Clark8032b982017-07-28 11:04:54 -04002967
Cary Clarkbad5ad72017-08-03 17:14:08 -04002968#Return true if Clip bounds is not empty ##
Cary Clark8032b982017-07-28 11:04:54 -04002969
2970#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04002971 void draw(SkCanvas* canvas) {
2972 SkIRect bounds;
2973 SkDebugf("device bounds empty = %s\n", canvas->getDeviceClipBounds(&bounds)
2974 ? "false" : "true");
2975 SkPath path;
2976 canvas->clipPath(path);
2977 SkDebugf("device bounds empty = %s\n", canvas->getDeviceClipBounds(&bounds)
2978 ? "false" : "true");
Cary Clark8032b982017-07-28 11:04:54 -04002979 }
2980 #StdOut
Cary Clarkbad5ad72017-08-03 17:14:08 -04002981 device bounds empty = false
Cary Clark8032b982017-07-28 11:04:54 -04002982 device bounds empty = true
2983 ##
2984##
2985
Cary Clark2ade9972017-11-02 17:49:34 -04002986#SeeAlso getLocalClipBounds getBaseLayerSize quickReject
Cary Clark8032b982017-07-28 11:04:54 -04002987
2988##
2989
Cary Clark08895c42018-02-01 09:37:32 -05002990#Subtopic Clip ##
Cary Clark8032b982017-07-28 11:04:54 -04002991
2992# ------------------------------------------------------------------------------
Cary Clark78de7512018-02-07 07:27:09 -05002993#Subtopic Draw
2994#Populate
2995#Line # draws into Canvas ##
2996##
Cary Clark8032b982017-07-28 11:04:54 -04002997
2998#Method void drawColor(SkColor color, SkBlendMode mode = SkBlendMode::kSrcOver)
Cary Clark78de7512018-02-07 07:27:09 -05002999#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05003000#Line # fills Clip with Color and Blend_Mode ##
Cary Clark8032b982017-07-28 11:04:54 -04003001Fill Clip with Color color.
3002mode determines how Color_ARGB is combined with destination.
3003
Cary Clarkbad5ad72017-08-03 17:14:08 -04003004#Param color Unpremultiplied Color_ARGB ##
3005#Param mode SkBlendMode used to combine source color and destination ##
Cary Clark8032b982017-07-28 11:04:54 -04003006
3007#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003008 canvas->drawColor(SK_ColorRED);
3009 canvas->clipRect(SkRect::MakeWH(150, 150));
3010 canvas->drawColor(SkColorSetARGB(0x80, 0x00, 0xFF, 0x00), SkBlendMode::kPlus);
3011 canvas->clipRect(SkRect::MakeWH(75, 75));
3012 canvas->drawColor(SkColorSetARGB(0x80, 0x00, 0x00, 0xFF), SkBlendMode::kPlus);
Cary Clark8032b982017-07-28 11:04:54 -04003013##
3014
Cary Clark2ade9972017-11-02 17:49:34 -04003015#SeeAlso clear SkBitmap::erase drawPaint
Cary Clark8032b982017-07-28 11:04:54 -04003016
3017##
3018
3019# ------------------------------------------------------------------------------
3020
Mike Klein9ff8c8c2018-02-07 01:58:51 +00003021#Method void clear(SkColor color)
Cary Clark78de7512018-02-07 07:27:09 -05003022#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05003023#Line # fills Clip with Color ##
Mike Klein9ff8c8c2018-02-07 01:58:51 +00003024Fill Clip with Color color using SkBlendMode::kSrc.
Cary Clark8032b982017-07-28 11:04:54 -04003025This has the effect of replacing all pixels contained by Clip with color.
3026
Cary Clarkbad5ad72017-08-03 17:14:08 -04003027#Param color Unpremultiplied Color_ARGB ##
Cary Clark8032b982017-07-28 11:04:54 -04003028
3029#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003030void draw(SkCanvas* canvas) {
3031 canvas->save();
3032 canvas->clipRect(SkRect::MakeWH(256, 128));
Mike Klein9ff8c8c2018-02-07 01:58:51 +00003033 canvas->clear(SkColorSetARGB(0x80, 0xFF, 0x00, 0x00));
Cary Clarkbad5ad72017-08-03 17:14:08 -04003034 canvas->restore();
3035 canvas->save();
3036 canvas->clipRect(SkRect::MakeWH(150, 192));
3037 canvas->clear(SkColorSetARGB(0x80, 0x00, 0xFF, 0x00));
3038 canvas->restore();
3039 canvas->clipRect(SkRect::MakeWH(75, 256));
3040 canvas->clear(SkColorSetARGB(0x80, 0x00, 0x00, 0xFF));
Cary Clark8032b982017-07-28 11:04:54 -04003041}
3042##
3043
Cary Clark2ade9972017-11-02 17:49:34 -04003044#SeeAlso drawColor SkBitmap::erase drawPaint
Cary Clark8032b982017-07-28 11:04:54 -04003045
3046##
3047
3048# ------------------------------------------------------------------------------
3049
Mike Klein9ff8c8c2018-02-07 01:58:51 +00003050#Method void discard()
Cary Clark78de7512018-02-07 07:27:09 -05003051#In Utility
Cary Clarkab2621d2018-01-30 10:08:57 -05003052#Line # makes Canvas contents undefined ##
Cary Clark8032b982017-07-28 11:04:54 -04003053Make Canvas contents undefined. Subsequent calls that read Canvas pixels,
3054such as drawing with SkBlendMode, return undefined results. discard() does
3055not change Clip or Matrix.
3056
3057discard() may do nothing, depending on the implementation of Surface or Device
3058that created Canvas.
3059
3060discard() allows optimized performance on subsequent draws by removing
3061cached data associated with Surface or Device.
3062It is not necessary to call discard() once done with Canvas;
3063any cached data is deleted when owning Surface or Device is deleted.
3064
3065#ToDo example? not sure how to make this meaningful w/o more implementation detail ##
Cary Clark2ade9972017-11-02 17:49:34 -04003066#SeeAlso flush() SkSurface::prepareForExternalIO GrContext::abandonContext
Cary Clark8032b982017-07-28 11:04:54 -04003067
Mike Klein9ff8c8c2018-02-07 01:58:51 +00003068#NoExample
Cary Clark8032b982017-07-28 11:04:54 -04003069##
3070
3071##
3072
3073# ------------------------------------------------------------------------------
3074
3075#Method void drawPaint(const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05003076#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05003077#Line # fills Clip with Paint ##
Mike Reed8ad91a92018-01-19 19:09:32 -05003078Fill Clip with Paint paint. Paint components Mask_Filter, Shader,
Cary Clarkbad5ad72017-08-03 17:14:08 -04003079Color_Filter, Image_Filter, and Blend_Mode affect drawing;
3080Path_Effect in paint is ignored.
Cary Clark8032b982017-07-28 11:04:54 -04003081
3082# can Path_Effect in paint ever alter drawPaint?
3083
Cary Clarkbad5ad72017-08-03 17:14:08 -04003084#Param paint graphics state used to fill Canvas ##
Cary Clark8032b982017-07-28 11:04:54 -04003085
3086#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003087void draw(SkCanvas* canvas) {
3088 SkColor colors[] = { SK_ColorRED, SK_ColorGREEN, SK_ColorBLUE };
3089 SkScalar pos[] = { 0, SK_Scalar1/2, SK_Scalar1 };
3090 SkPaint paint;
3091 paint.setShader(SkGradientShader::MakeSweep(256, 256, colors, pos, SK_ARRAY_COUNT(colors)));
3092 canvas->drawPaint(paint);
Cary Clark8032b982017-07-28 11:04:54 -04003093}
3094##
3095
Cary Clark2ade9972017-11-02 17:49:34 -04003096#SeeAlso clear drawColor SkBitmap::erase
Cary Clark8032b982017-07-28 11:04:54 -04003097
3098##
3099
3100# ------------------------------------------------------------------------------
3101
3102#Enum PointMode
Cary Clark08895c42018-02-01 09:37:32 -05003103#Line # sets drawPoints options ##
Cary Clark8032b982017-07-28 11:04:54 -04003104
3105#Code
3106 enum PointMode {
3107 kPoints_PointMode,
3108 kLines_PointMode,
Cary Clarkd0530ba2017-09-14 11:25:39 -04003109 kPolygon_PointMode,
Cary Clark8032b982017-07-28 11:04:54 -04003110 };
3111##
3112
3113Selects if an array of points are drawn as discrete points, as lines, or as
3114an open polygon.
3115
3116#Const kPoints_PointMode 0
3117 Draw each point separately.
3118##
3119
3120#Const kLines_PointMode 1
3121 Draw each pair of points as a line segment.
3122##
3123
3124#Const kPolygon_PointMode 2
3125 Draw the array of points as a open polygon.
3126##
3127
3128#Example
Mike Klein9ff8c8c2018-02-07 01:58:51 +00003129 #Description
Cary Clark8032b982017-07-28 11:04:54 -04003130 The upper left corner shows three squares when drawn as points.
3131 The upper right corner shows one line; when drawn as lines, two points are required per line.
3132 The lower right corner shows two lines; when draw as polygon, no miter is drawn at the corner.
3133 The lower left corner shows two lines with a miter when path contains polygon.
3134 ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003135void draw(SkCanvas* canvas) {
3136 SkPaint paint;
3137 paint.setStyle(SkPaint::kStroke_Style);
3138 paint.setStrokeWidth(10);
3139 SkPoint points[] = {{64, 32}, {96, 96}, {32, 96}};
3140 canvas->drawPoints(SkCanvas::kPoints_PointMode, 3, points, paint);
3141 canvas->translate(128, 0);
3142 canvas->drawPoints(SkCanvas::kLines_PointMode, 3, points, paint);
3143 canvas->translate(0, 128);
3144 canvas->drawPoints(SkCanvas::kPolygon_PointMode, 3, points, paint);
3145 SkPath path;
3146 path.addPoly(points, 3, false);
3147 canvas->translate(-128, 0);
3148 canvas->drawPath(path, paint);
Cary Clark8032b982017-07-28 11:04:54 -04003149}
3150##
3151
Cary Clark2ade9972017-11-02 17:49:34 -04003152#SeeAlso drawLine drawPoint drawPath
Cary Clark8032b982017-07-28 11:04:54 -04003153
3154##
3155
3156# ------------------------------------------------------------------------------
3157
3158#Method void drawPoints(PointMode mode, size_t count, const SkPoint pts[], const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05003159#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05003160#Line # draws array as points, lines, polygon ##
Cary Clark8032b982017-07-28 11:04:54 -04003161Draw pts using Clip, Matrix and Paint paint.
Cary Clarkbad5ad72017-08-03 17:14:08 -04003162count is the number of points; if count is less than one, has no effect.
Cary Clark8032b982017-07-28 11:04:54 -04003163mode may be one of: kPoints_PointMode, kLines_PointMode, or kPolygon_PointMode.
3164
Cary Clarkbad5ad72017-08-03 17:14:08 -04003165If mode is kPoints_PointMode, the shape of point drawn depends on paint
3166Paint_Stroke_Cap. If paint is set to SkPaint::kRound_Cap, each point draws a
3167circle of diameter Paint_Stroke_Width. If paint is set to SkPaint::kSquare_Cap
3168or SkPaint::kButt_Cap, each point draws a square of width and height
3169Paint_Stroke_Width.
Cary Clark8032b982017-07-28 11:04:54 -04003170
3171If mode is kLines_PointMode, each pair of points draws a line segment.
3172One line is drawn for every two points; each point is used once. If count is odd,
Mike Klein9ff8c8c2018-02-07 01:58:51 +00003173the final point is ignored.
Cary Clark8032b982017-07-28 11:04:54 -04003174
3175If mode is kPolygon_PointMode, each adjacent pair of points draws a line segment.
3176count minus one lines are drawn; the first and last point are used once.
3177
3178Each line segment respects paint Paint_Stroke_Cap and Paint_Stroke_Width.
3179Paint_Style is ignored, as if were set to SkPaint::kStroke_Style.
3180
Cary Clarkbad5ad72017-08-03 17:14:08 -04003181Always draws each element one at a time; is not affected by
3182Paint_Stroke_Join, and unlike drawPath, does not create a mask from all points
Mike Klein9ff8c8c2018-02-07 01:58:51 +00003183and lines before drawing.
Cary Clark8032b982017-07-28 11:04:54 -04003184
Cary Clarka523d2d2017-08-30 08:58:10 -04003185#Param mode whether pts draws points or lines ##
3186#Param count number of points in the array ##
3187#Param pts array of points to draw ##
3188#Param paint stroke, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003189
3190#Example
3191#Height 200
Mike Klein9ff8c8c2018-02-07 01:58:51 +00003192 #Description
Cary Clark8032b982017-07-28 11:04:54 -04003193 #List
3194 # The first column draws points. ##
3195 # The second column draws points as lines. ##
3196 # The third column draws points as a polygon. ##
3197 # The fourth column draws points as a polygonal path. ##
3198 # The first row uses a round cap and round join. ##
3199 # The second row uses a square cap and a miter join. ##
3200 # The third row uses a butt cap and a bevel join. ##
3201 ##
3202 The transparent color makes multiple line draws visible;
3203 the path is drawn all at once.
3204 ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003205void draw(SkCanvas* canvas) {
3206 SkPaint paint;
3207 paint.setAntiAlias(true);
3208 paint.setStyle(SkPaint::kStroke_Style);
3209 paint.setStrokeWidth(10);
3210 paint.setColor(0x80349a45);
3211 const SkPoint points[] = {{32, 16}, {48, 48}, {16, 32}};
Mike Klein9ff8c8c2018-02-07 01:58:51 +00003212 const SkPaint::Join join[] = { SkPaint::kRound_Join,
Cary Clarkbad5ad72017-08-03 17:14:08 -04003213 SkPaint::kMiter_Join,
3214 SkPaint::kBevel_Join };
3215 int joinIndex = 0;
3216 SkPath path;
3217 path.addPoly(points, 3, false);
3218 for (const auto cap : { SkPaint::kRound_Cap, SkPaint::kSquare_Cap, SkPaint::kButt_Cap } ) {
3219 paint.setStrokeCap(cap);
3220 paint.setStrokeJoin(join[joinIndex++]);
3221 for (const auto mode : { SkCanvas::kPoints_PointMode,
3222 SkCanvas::kLines_PointMode,
3223 SkCanvas::kPolygon_PointMode } ) {
3224 canvas->drawPoints(mode, 3, points, paint);
3225 canvas->translate(64, 0);
3226 }
3227 canvas->drawPath(path, paint);
3228 canvas->translate(-192, 64);
3229 }
Cary Clark8032b982017-07-28 11:04:54 -04003230}
3231##
3232
Cary Clark2ade9972017-11-02 17:49:34 -04003233#SeeAlso drawLine drawPoint drawPath
Cary Clark8032b982017-07-28 11:04:54 -04003234
3235##
3236
3237# ------------------------------------------------------------------------------
3238
3239#Method void drawPoint(SkScalar x, SkScalar y, const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05003240#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05003241#Line # draws point at (x, y) position ##
Cary Clark8032b982017-07-28 11:04:54 -04003242Draw point at (x, y) using Clip, Matrix and Paint paint.
3243
3244The shape of point drawn depends on paint Paint_Stroke_Cap.
Cary Clarkbad5ad72017-08-03 17:14:08 -04003245If paint is set to SkPaint::kRound_Cap, draw a circle of diameter
Mike Klein9ff8c8c2018-02-07 01:58:51 +00003246Paint_Stroke_Width. If paint is set to SkPaint::kSquare_Cap or SkPaint::kButt_Cap,
Cary Clark8032b982017-07-28 11:04:54 -04003247draw a square of width and height Paint_Stroke_Width.
3248Paint_Style is ignored, as if were set to SkPaint::kStroke_Style.
3249
Cary Clarkbad5ad72017-08-03 17:14:08 -04003250#Param x left edge of circle or square ##
3251#Param y top edge of circle or square ##
3252#Param paint stroke, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003253
3254#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003255void draw(SkCanvas* canvas) {
3256 SkPaint paint;
3257 paint.setAntiAlias(true);
3258 paint.setColor(0x80349a45);
3259 paint.setStyle(SkPaint::kStroke_Style);
3260 paint.setStrokeWidth(100);
3261 paint.setStrokeCap(SkPaint::kRound_Cap);
3262 canvas->scale(1, 1.2f);
3263 canvas->drawPoint(64, 96, paint);
3264 canvas->scale(.6f, .8f);
3265 paint.setColor(SK_ColorWHITE);
3266 canvas->drawPoint(106, 120, paint);
Cary Clark8032b982017-07-28 11:04:54 -04003267}
3268##
3269
Cary Clark2ade9972017-11-02 17:49:34 -04003270#SeeAlso drawPoints drawCircle drawRect drawLine drawPath
Cary Clark8032b982017-07-28 11:04:54 -04003271
3272##
3273
Cary Clarkbad5ad72017-08-03 17:14:08 -04003274#Method void drawPoint(SkPoint p, const SkPaint& paint)
3275
3276Draw point p using Clip, Matrix and Paint paint.
3277
3278The shape of point drawn depends on paint Paint_Stroke_Cap.
3279If paint is set to SkPaint::kRound_Cap, draw a circle of diameter
Mike Klein9ff8c8c2018-02-07 01:58:51 +00003280Paint_Stroke_Width. If paint is set to SkPaint::kSquare_Cap or SkPaint::kButt_Cap,
Cary Clarkbad5ad72017-08-03 17:14:08 -04003281draw a square of width and height Paint_Stroke_Width.
3282Paint_Style is ignored, as if were set to SkPaint::kStroke_Style.
3283
3284#Param p top-left edge of circle or square ##
3285#Param paint stroke, blend, color, and so on, used to draw ##
3286
3287#Example
3288void draw(SkCanvas* canvas) {
3289 SkPaint paint;
3290 paint.setAntiAlias(true);
3291 paint.setColor(0x80349a45);
3292 paint.setStyle(SkPaint::kStroke_Style);
3293 paint.setStrokeWidth(100);
3294 paint.setStrokeCap(SkPaint::kSquare_Cap);
3295 canvas->scale(1, 1.2f);
3296 canvas->drawPoint({64, 96}, paint);
3297 canvas->scale(.6f, .8f);
3298 paint.setColor(SK_ColorWHITE);
3299 canvas->drawPoint(106, 120, paint);
3300}
3301##
3302
Cary Clark2ade9972017-11-02 17:49:34 -04003303#SeeAlso drawPoints drawCircle drawRect drawLine drawPath
Cary Clarkbad5ad72017-08-03 17:14:08 -04003304
3305##
3306
Cary Clark8032b982017-07-28 11:04:54 -04003307# ------------------------------------------------------------------------------
3308
3309#Method void drawLine(SkScalar x0, SkScalar y0, SkScalar x1, SkScalar y1, const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05003310#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05003311#Line # draws line segment between two points ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003312Draws line segment from (x0, y0) to (x1, y1) using Clip, Matrix, and Paint paint.
3313In paint: Paint_Stroke_Width describes the line thickness;
3314Paint_Stroke_Cap draws the end rounded or square;
Cary Clark8032b982017-07-28 11:04:54 -04003315Paint_Style is ignored, as if were set to SkPaint::kStroke_Style.
3316
Cary Clarkbad5ad72017-08-03 17:14:08 -04003317#Param x0 start of line segment on x-axis ##
3318#Param y0 start of line segment on y-axis ##
3319#Param x1 end of line segment on x-axis ##
3320#Param y1 end of line segment on y-axis ##
3321#Param paint stroke, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003322
3323#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003324 SkPaint paint;
3325 paint.setAntiAlias(true);
3326 paint.setColor(0xFF9a67be);
3327 paint.setStrokeWidth(20);
3328 canvas->skew(1, 0);
3329 canvas->drawLine(32, 96, 32, 160, paint);
3330 canvas->skew(-2, 0);
3331 canvas->drawLine(288, 96, 288, 160, paint);
3332##
3333
Cary Clark2ade9972017-11-02 17:49:34 -04003334#SeeAlso drawPoint drawCircle drawRect drawPath
Cary Clarkbad5ad72017-08-03 17:14:08 -04003335
3336##
3337
3338#Method void drawLine(SkPoint p0, SkPoint p1, const SkPaint& paint)
3339
3340Draws line segment from p0 to p1 using Clip, Matrix, and Paint paint.
3341In paint: Paint_Stroke_Width describes the line thickness;
3342Paint_Stroke_Cap draws the end rounded or square;
3343Paint_Style is ignored, as if were set to SkPaint::kStroke_Style.
3344
3345#Param p0 start of line segment ##
3346#Param p1 end of line segment ##
3347#Param paint stroke, blend, color, and so on, used to draw ##
3348
3349#Example
3350 SkPaint paint;
3351 paint.setAntiAlias(true);
3352 paint.setColor(0xFF9a67be);
3353 paint.setStrokeWidth(20);
3354 canvas->skew(1, 0);
3355 canvas->drawLine({32, 96}, {32, 160}, paint);
3356 canvas->skew(-2, 0);
3357 canvas->drawLine({288, 96}, {288, 160}, paint);
Cary Clark8032b982017-07-28 11:04:54 -04003358##
3359
Cary Clark2ade9972017-11-02 17:49:34 -04003360#SeeAlso drawPoint drawCircle drawRect drawPath
Cary Clark8032b982017-07-28 11:04:54 -04003361
3362##
3363
3364# ------------------------------------------------------------------------------
3365
3366#Method void drawRect(const SkRect& rect, const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05003367#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05003368#Line # draws Rect using Clip, Matrix, and Paint ##
Cary Clark8032b982017-07-28 11:04:54 -04003369Draw Rect rect using Clip, Matrix, and Paint paint.
Mike Klein9ff8c8c2018-02-07 01:58:51 +00003370In paint: Paint_Style determines if rectangle is stroked or filled;
Cary Clark8032b982017-07-28 11:04:54 -04003371if stroked, Paint_Stroke_Width describes the line thickness, and
3372Paint_Stroke_Join draws the corners rounded or square.
3373
Cary Clarkbc5697d2017-10-04 14:31:33 -04003374#Param rect rectangle to draw ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003375#Param paint stroke or fill, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003376
3377#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003378void draw(SkCanvas* canvas) {
3379 SkPoint rectPts[] = { {64, 48}, {192, 160} };
3380 SkPaint paint;
3381 paint.setAntiAlias(true);
3382 paint.setStyle(SkPaint::kStroke_Style);
3383 paint.setStrokeWidth(20);
3384 paint.setStrokeJoin(SkPaint::kRound_Join);
3385 SkMatrix rotator;
3386 rotator.setRotate(30, 128, 128);
3387 for (auto color : { SK_ColorRED, SK_ColorBLUE, SK_ColorYELLOW, SK_ColorMAGENTA } ) {
3388 paint.setColor(color);
3389 SkRect rect;
3390 rect.set(rectPts[0], rectPts[1]);
3391 canvas->drawRect(rect, paint);
3392 rotator.mapPoints(rectPts, 2);
3393 }
Cary Clark8032b982017-07-28 11:04:54 -04003394}
3395##
3396
Mike Klein9ff8c8c2018-02-07 01:58:51 +00003397#SeeAlso drawIRect drawRRect drawRoundRect drawRegion drawPath drawLine
Cary Clark8032b982017-07-28 11:04:54 -04003398
3399##
3400
3401# ------------------------------------------------------------------------------
3402
Mike Klein9ff8c8c2018-02-07 01:58:51 +00003403#Method void drawIRect(const SkIRect& rect, const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05003404#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05003405#Line # draws IRect using Clip, Matrix, and Paint ##
Cary Clark8032b982017-07-28 11:04:54 -04003406Draw IRect rect using Clip, Matrix, and Paint paint.
Mike Klein9ff8c8c2018-02-07 01:58:51 +00003407In paint: Paint_Style determines if rectangle is stroked or filled;
Cary Clark8032b982017-07-28 11:04:54 -04003408if stroked, Paint_Stroke_Width describes the line thickness, and
3409Paint_Stroke_Join draws the corners rounded or square.
3410
Cary Clarkbc5697d2017-10-04 14:31:33 -04003411#Param rect rectangle to draw ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003412#Param paint stroke or fill, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003413
3414#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003415 SkIRect rect = { 64, 48, 192, 160 };
3416 SkPaint paint;
3417 paint.setAntiAlias(true);
3418 paint.setStyle(SkPaint::kStroke_Style);
3419 paint.setStrokeWidth(20);
3420 paint.setStrokeJoin(SkPaint::kRound_Join);
3421 for (auto color : { SK_ColorRED, SK_ColorBLUE, SK_ColorYELLOW, SK_ColorMAGENTA } ) {
3422 paint.setColor(color);
3423 canvas->drawIRect(rect, paint);
3424 canvas->rotate(30, 128, 128);
3425 }
Cary Clark8032b982017-07-28 11:04:54 -04003426##
3427
Cary Clark2ade9972017-11-02 17:49:34 -04003428#SeeAlso drawRect drawRRect drawRoundRect drawRegion drawPath drawLine
Cary Clark8032b982017-07-28 11:04:54 -04003429
3430##
3431
3432# ------------------------------------------------------------------------------
3433
3434#Method void drawRegion(const SkRegion& region, const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05003435#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05003436#Line # draws Region using Clip, Matrix, and Paint ##
Cary Clark8032b982017-07-28 11:04:54 -04003437Draw Region region using Clip, Matrix, and Paint paint.
Mike Klein9ff8c8c2018-02-07 01:58:51 +00003438In paint: Paint_Style determines if rectangle is stroked or filled;
Cary Clark8032b982017-07-28 11:04:54 -04003439if stroked, Paint_Stroke_Width describes the line thickness, and
3440Paint_Stroke_Join draws the corners rounded or square.
3441
Cary Clarkbc5697d2017-10-04 14:31:33 -04003442#Param region region to draw ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003443#Param paint Paint stroke or fill, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003444
3445#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003446void draw(SkCanvas* canvas) {
3447 SkRegion region;
3448 region.op( 10, 10, 50, 50, SkRegion::kUnion_Op);
3449 region.op( 10, 50, 90, 90, SkRegion::kUnion_Op);
3450 SkPaint paint;
3451 paint.setAntiAlias(true);
3452 paint.setStyle(SkPaint::kStroke_Style);
3453 paint.setStrokeWidth(20);
3454 paint.setStrokeJoin(SkPaint::kRound_Join);
3455 canvas->drawRegion(region, paint);
Cary Clark8032b982017-07-28 11:04:54 -04003456}
3457##
3458
Cary Clark2ade9972017-11-02 17:49:34 -04003459#SeeAlso drawRect drawIRect drawPath
Cary Clark8032b982017-07-28 11:04:54 -04003460
3461##
3462
3463# ------------------------------------------------------------------------------
3464
3465#Method void drawOval(const SkRect& oval, const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05003466#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05003467#Line # draws Oval using Clip, Matrix, and Paint ##
Cary Clark8032b982017-07-28 11:04:54 -04003468Draw Oval oval using Clip, Matrix, and Paint.
Mike Klein9ff8c8c2018-02-07 01:58:51 +00003469In paint: Paint_Style determines if Oval is stroked or filled;
Cary Clark8032b982017-07-28 11:04:54 -04003470if stroked, Paint_Stroke_Width describes the line thickness.
3471
Cary Clarkbad5ad72017-08-03 17:14:08 -04003472#Param oval Rect bounds of Oval ##
3473#Param paint Paint stroke or fill, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003474
3475#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003476void draw(SkCanvas* canvas) {
3477 canvas->clear(0xFF3f5f9f);
3478 SkColor kColor1 = SkColorSetARGB(0xff, 0xff, 0x7f, 0);
3479 SkColor g1Colors[] = { kColor1, SkColorSetA(kColor1, 0x20) };
3480 SkPoint g1Points[] = { { 0, 0 }, { 0, 100 } };
3481 SkScalar pos[] = { 0.2f, 1.0f };
3482 SkRect bounds = SkRect::MakeWH(80, 70);
3483 SkPaint paint;
3484 paint.setAntiAlias(true);
3485 paint.setShader(SkGradientShader::MakeLinear(g1Points, g1Colors, pos, SK_ARRAY_COUNT(g1Colors),
3486 SkShader::kClamp_TileMode));
3487 canvas->drawOval(bounds , paint);
Cary Clark8032b982017-07-28 11:04:54 -04003488}
3489##
3490
Cary Clark2ade9972017-11-02 17:49:34 -04003491#SeeAlso drawCircle drawPoint drawPath drawRRect drawRoundRect
Cary Clark8032b982017-07-28 11:04:54 -04003492
3493##
3494
3495# ------------------------------------------------------------------------------
3496
3497#Method void drawRRect(const SkRRect& rrect, const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05003498#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05003499#Line # draws Round_Rect using Clip, Matrix, and Paint ##
Cary Clark8032b982017-07-28 11:04:54 -04003500Draw Round_Rect rrect using Clip, Matrix, and Paint paint.
Mike Klein9ff8c8c2018-02-07 01:58:51 +00003501In paint: Paint_Style determines if rrect is stroked or filled;
Cary Clark8032b982017-07-28 11:04:54 -04003502if stroked, Paint_Stroke_Width describes the line thickness.
3503
Cary Clarkbad5ad72017-08-03 17:14:08 -04003504rrect may represent a rectangle, circle, oval, uniformly rounded rectangle, or
3505may have any combination of positive non-square radii for the four corners.
Cary Clark8032b982017-07-28 11:04:54 -04003506
Cary Clarkbad5ad72017-08-03 17:14:08 -04003507#Param rrect Round_Rect with up to eight corner radii to draw ##
3508#Param paint Paint stroke or fill, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003509
3510#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003511void draw(SkCanvas* canvas) {
3512 SkPaint paint;
3513 paint.setAntiAlias(true);
3514 SkRect outer = {30, 40, 210, 220};
3515 SkRect radii = {30, 50, 70, 90 };
3516 SkRRect rRect;
3517 rRect.setNinePatch(outer, radii.fLeft, radii.fTop, radii.fRight, radii.fBottom);
3518 canvas->drawRRect(rRect, paint);
3519 paint.setColor(SK_ColorWHITE);
3520 canvas->drawLine(outer.fLeft + radii.fLeft, outer.fTop,
3521 outer.fLeft + radii.fLeft, outer.fBottom, paint);
Mike Klein9ff8c8c2018-02-07 01:58:51 +00003522 canvas->drawLine(outer.fRight - radii.fRight, outer.fTop,
Cary Clarkbad5ad72017-08-03 17:14:08 -04003523 outer.fRight - radii.fRight, outer.fBottom, paint);
Mike Klein9ff8c8c2018-02-07 01:58:51 +00003524 canvas->drawLine(outer.fLeft, outer.fTop + radii.fTop,
Cary Clarkbad5ad72017-08-03 17:14:08 -04003525 outer.fRight, outer.fTop + radii.fTop, paint);
Mike Klein9ff8c8c2018-02-07 01:58:51 +00003526 canvas->drawLine(outer.fLeft, outer.fBottom - radii.fBottom,
Cary Clarkbad5ad72017-08-03 17:14:08 -04003527 outer.fRight, outer.fBottom - radii.fBottom, paint);
3528}
Cary Clark8032b982017-07-28 11:04:54 -04003529##
3530
Cary Clark2ade9972017-11-02 17:49:34 -04003531#SeeAlso drawRect drawRoundRect drawDRRect drawCircle drawOval drawPath
Cary Clark8032b982017-07-28 11:04:54 -04003532
3533##
3534
3535# ------------------------------------------------------------------------------
3536
3537#Method void drawDRRect(const SkRRect& outer, const SkRRect& inner, const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05003538#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05003539#Line # draws double Round_Rect stroked or filled ##
Cary Clark8032b982017-07-28 11:04:54 -04003540Draw Round_Rect outer and inner
Mike Klein9ff8c8c2018-02-07 01:58:51 +00003541using Clip, Matrix, and Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04003542outer must contain inner or the drawing is undefined.
Mike Klein9ff8c8c2018-02-07 01:58:51 +00003543In paint: Paint_Style determines if Round_Rect is stroked or filled;
Cary Clark8032b982017-07-28 11:04:54 -04003544if stroked, Paint_Stroke_Width describes the line thickness.
Cary Clarkbad5ad72017-08-03 17:14:08 -04003545If stroked and Round_Rect corner has zero length radii, Paint_Stroke_Join can
Mike Klein9ff8c8c2018-02-07 01:58:51 +00003546draw corners rounded or square.
Cary Clark8032b982017-07-28 11:04:54 -04003547
Cary Clarkbad5ad72017-08-03 17:14:08 -04003548GPU-backed platforms optimize drawing when both outer and inner are
Cary Clark8032b982017-07-28 11:04:54 -04003549concave and outer contains inner. These platforms may not be able to draw
Mike Klein9ff8c8c2018-02-07 01:58:51 +00003550Path built with identical data as fast.
Cary Clark8032b982017-07-28 11:04:54 -04003551
Cary Clarkbad5ad72017-08-03 17:14:08 -04003552#Param outer Round_Rect outer bounds to draw ##
3553#Param inner Round_Rect inner bounds to draw ##
3554#Param paint Paint stroke or fill, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003555
3556#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003557void draw(SkCanvas* canvas) {
3558 SkRRect outer = SkRRect::MakeRect({20, 40, 210, 200});
3559 SkRRect inner = SkRRect::MakeOval({60, 70, 170, 160});
3560 SkPaint paint;
3561 canvas->drawDRRect(outer, inner, paint);
Cary Clark8032b982017-07-28 11:04:54 -04003562}
3563##
3564
3565#Example
3566#Description
3567 Outer Rect has no corner radii, but stroke join is rounded.
3568 Inner Round_Rect has corner radii; outset stroke increases radii of corners.
3569 Stroke join does not affect inner Round_Rect since it has no sharp corners.
3570##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003571void draw(SkCanvas* canvas) {
3572 SkRRect outer = SkRRect::MakeRect({20, 40, 210, 200});
3573 SkRRect inner = SkRRect::MakeRectXY({60, 70, 170, 160}, 10, 10);
3574 SkPaint paint;
3575 paint.setAntiAlias(true);
3576 paint.setStyle(SkPaint::kStroke_Style);
3577 paint.setStrokeWidth(20);
3578 paint.setStrokeJoin(SkPaint::kRound_Join);
3579 canvas->drawDRRect(outer, inner, paint);
3580 paint.setStrokeWidth(1);
3581 paint.setColor(SK_ColorWHITE);
3582 canvas->drawDRRect(outer, inner, paint);
Cary Clark8032b982017-07-28 11:04:54 -04003583}
3584##
3585
Cary Clark2ade9972017-11-02 17:49:34 -04003586#SeeAlso drawRect drawRoundRect drawRRect drawCircle drawOval drawPath
Cary Clark8032b982017-07-28 11:04:54 -04003587
3588##
3589
3590# ------------------------------------------------------------------------------
3591
3592#Method void drawCircle(SkScalar cx, SkScalar cy, SkScalar radius, const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05003593#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05003594#Line # draws Circle using Clip, Matrix, and Paint ##
Cary Clark8032b982017-07-28 11:04:54 -04003595Draw Circle at (cx, cy) with radius using Clip, Matrix, and Paint paint.
3596If radius is zero or less, nothing is drawn.
Mike Klein9ff8c8c2018-02-07 01:58:51 +00003597In paint: Paint_Style determines if Circle is stroked or filled;
Cary Clark8032b982017-07-28 11:04:54 -04003598if stroked, Paint_Stroke_Width describes the line thickness.
3599
Cary Clarkbad5ad72017-08-03 17:14:08 -04003600#Param cx Circle center on the x-axis ##
3601#Param cy Circle center on the y-axis ##
3602#Param radius half the diameter of Circle ##
3603#Param paint Paint stroke or fill, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003604
3605#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003606 void draw(SkCanvas* canvas) {
3607 SkPaint paint;
3608 paint.setAntiAlias(true);
3609 canvas->drawCircle(128, 128, 90, paint);
3610 paint.setColor(SK_ColorWHITE);
3611 canvas->drawCircle(86, 86, 20, paint);
3612 canvas->drawCircle(160, 76, 20, paint);
3613 canvas->drawCircle(140, 150, 35, paint);
3614 }
3615##
3616
Cary Clark2ade9972017-11-02 17:49:34 -04003617#SeeAlso drawOval drawRRect drawRoundRect drawPath drawArc drawPoint drawLine
Cary Clarkbad5ad72017-08-03 17:14:08 -04003618
3619##
3620
3621#Method void drawCircle(SkPoint center, SkScalar radius, const SkPaint& paint)
3622
Cary Clarkce101242017-09-01 15:51:02 -04003623Draw Circle at center with radius using Clip, Matrix, and Paint paint.
Cary Clarkbad5ad72017-08-03 17:14:08 -04003624If radius is zero or less, nothing is drawn.
Mike Klein9ff8c8c2018-02-07 01:58:51 +00003625In paint: Paint_Style determines if Circle is stroked or filled;
Cary Clarkbad5ad72017-08-03 17:14:08 -04003626if stroked, Paint_Stroke_Width describes the line thickness.
3627
3628#Param center Circle center ##
3629#Param radius half the diameter of Circle ##
3630#Param paint Paint stroke or fill, blend, color, and so on, used to draw ##
3631
3632#Example
3633 void draw(SkCanvas* canvas) {
3634 SkPaint paint;
3635 paint.setAntiAlias(true);
3636 canvas->drawCircle(128, 128, 90, paint);
3637 paint.setColor(SK_ColorWHITE);
3638 canvas->drawCircle({86, 86}, 20, paint);
3639 canvas->drawCircle({160, 76}, 20, paint);
3640 canvas->drawCircle({140, 150}, 35, paint);
3641 }
Cary Clark8032b982017-07-28 11:04:54 -04003642##
3643
Cary Clark2ade9972017-11-02 17:49:34 -04003644#SeeAlso drawOval drawRRect drawRoundRect drawPath drawArc drawPoint drawLine
Cary Clark8032b982017-07-28 11:04:54 -04003645
3646##
3647
3648# ------------------------------------------------------------------------------
3649
3650#Method void drawArc(const SkRect& oval, SkScalar startAngle, SkScalar sweepAngle,
3651 bool useCenter, const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05003652#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05003653#Line # draws Arc using Clip, Matrix, and Paint ##
Cary Clark8032b982017-07-28 11:04:54 -04003654
3655Draw Arc using Clip, Matrix, and Paint paint.
Cary Clarkbad5ad72017-08-03 17:14:08 -04003656
Cary Clark8032b982017-07-28 11:04:54 -04003657Arc is part of Oval bounded by oval, sweeping from startAngle to startAngle plus
3658sweepAngle. startAngle and sweepAngle are in degrees.
Cary Clarkbad5ad72017-08-03 17:14:08 -04003659
Cary Clark8032b982017-07-28 11:04:54 -04003660startAngle of zero places start point at the right middle edge of oval.
3661A positive sweepAngle places Arc end point clockwise from start point;
3662a negative sweepAngle places Arc end point counterclockwise from start point.
3663sweepAngle may exceed 360 degrees, a full circle.
3664If useCenter is true, draw a wedge that includes lines from oval
3665center to Arc end points. If useCenter is false, draw Arc between end points.
3666
3667If Rect oval is empty or sweepAngle is zero, nothing is drawn.
3668
Cary Clarkbad5ad72017-08-03 17:14:08 -04003669#Param oval Rect bounds of Oval containing Arc to draw ##
3670#Param startAngle angle in degrees where Arc begins ##
3671#Param sweepAngle sweep angle in degrees; positive is clockwise ##
3672#Param useCenter if true, include the center of the oval ##
3673#Param paint Paint stroke or fill, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003674
3675#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003676 void draw(SkCanvas* canvas) {
3677 SkPaint paint;
3678 paint.setAntiAlias(true);
3679 SkRect oval = { 4, 4, 60, 60};
3680 for (auto useCenter : { false, true } ) {
3681 for (auto style : { SkPaint::kFill_Style, SkPaint::kStroke_Style } ) {
3682 paint.setStyle(style);
3683 for (auto degrees : { 45, 90, 180, 360} ) {
3684 canvas->drawArc(oval, 0, degrees , useCenter, paint);
3685 canvas->translate(64, 0);
3686 }
3687 canvas->translate(-256, 64);
3688 }
3689 }
Cary Clark8032b982017-07-28 11:04:54 -04003690 }
3691##
3692
3693#Example
3694#Height 64
Cary Clarkbad5ad72017-08-03 17:14:08 -04003695 void draw(SkCanvas* canvas) {
3696 SkPaint paint;
3697 paint.setAntiAlias(true);
3698 paint.setStyle(SkPaint::kStroke_Style);
3699 paint.setStrokeWidth(4);
3700 SkRect oval = { 4, 4, 60, 60};
3701 float intervals[] = { 5, 5 };
3702 paint.setPathEffect(SkDashPathEffect::Make(intervals, 2, 2.5f));
3703 for (auto degrees : { 270, 360, 540, 720 } ) {
3704 canvas->drawArc(oval, 0, degrees, false, paint);
3705 canvas->translate(64, 0);
3706 }
Cary Clark8032b982017-07-28 11:04:54 -04003707 }
3708##
3709
Cary Clark2ade9972017-11-02 17:49:34 -04003710#SeeAlso SkPath::arcTo drawCircle drawOval drawPath
Cary Clark8032b982017-07-28 11:04:54 -04003711
3712##
3713
3714# ------------------------------------------------------------------------------
3715
3716#Method void drawRoundRect(const SkRect& rect, SkScalar rx, SkScalar ry, const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05003717#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05003718#Line # draws Round_Rect using Clip, Matrix, and Paint ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003719Draw Round_Rect bounded by Rect rect, with corner radii (rx, ry) using Clip,
3720Matrix, and Paint paint.
3721
Mike Klein9ff8c8c2018-02-07 01:58:51 +00003722In paint: Paint_Style determines if Round_Rect is stroked or filled;
Cary Clark8032b982017-07-28 11:04:54 -04003723if stroked, Paint_Stroke_Width describes the line thickness.
3724If rx or ry are less than zero, they are treated as if they are zero.
3725If rx plus ry exceeds rect width or rect height, radii are scaled down to fit.
Cary Clarkbad5ad72017-08-03 17:14:08 -04003726If rx and ry are zero, Round_Rect is drawn as Rect and if stroked is affected by
3727Paint_Stroke_Join.
Cary Clark8032b982017-07-28 11:04:54 -04003728
Cary Clarkbad5ad72017-08-03 17:14:08 -04003729#Param rect Rect bounds of Round_Rect to draw ##
Cary Clarkce101242017-09-01 15:51:02 -04003730#Param rx axis length in x of oval describing rounded corners ##
3731#Param ry axis length in y of oval describing rounded corners ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003732#Param paint stroke, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003733
3734#Example
3735#Description
3736 Top row has a zero radius a generates a rectangle.
3737 Second row radii sum to less than sides.
3738 Third row radii sum equals sides.
3739 Fourth row radii sum exceeds sides; radii are scaled to fit.
3740##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003741 void draw(SkCanvas* canvas) {
3742 SkVector radii[] = { {0, 20}, {10, 10}, {10, 20}, {10, 40} };
3743 SkPaint paint;
3744 paint.setStrokeWidth(15);
3745 paint.setStrokeJoin(SkPaint::kRound_Join);
3746 paint.setAntiAlias(true);
3747 for (auto style : { SkPaint::kStroke_Style, SkPaint::kFill_Style } ) {
3748 paint.setStyle(style );
3749 for (size_t i = 0; i < SK_ARRAY_COUNT(radii); ++i) {
3750 canvas->drawRoundRect({10, 10, 60, 40}, radii[i].fX, radii[i].fY, paint);
3751 canvas->translate(0, 60);
3752 }
3753 canvas->translate(80, -240);
3754 }
Cary Clark8032b982017-07-28 11:04:54 -04003755 }
3756##
3757
Cary Clark2ade9972017-11-02 17:49:34 -04003758#SeeAlso DrawRRect drawRect drawDRRect drawPath drawCircle drawOval drawPoint
Cary Clark8032b982017-07-28 11:04:54 -04003759
3760##
3761
3762# ------------------------------------------------------------------------------
3763
3764#Method void drawPath(const SkPath& path, const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05003765#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05003766#Line # draws Path using Clip, Matrix, and Paint ##
Cary Clark8032b982017-07-28 11:04:54 -04003767Draw Path path using Clip, Matrix, and Paint paint.
3768Path contains an array of Path_Contour, each of which may be open or closed.
3769
3770In paint: Paint_Style determines if Round_Rect is stroked or filled:
Cary Clarkbad5ad72017-08-03 17:14:08 -04003771if filled, Path_Fill_Type determines whether Path_Contour describes inside or
3772outside of fill; if stroked, Paint_Stroke_Width describes the line thickness,
3773Paint_Stroke_Cap describes line ends, and Paint_Stroke_Join describes how
3774corners are drawn.
Cary Clark8032b982017-07-28 11:04:54 -04003775
Cary Clarkbad5ad72017-08-03 17:14:08 -04003776#Param path Path to draw ##
3777#Param paint stroke, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003778
3779#Example
3780#Description
3781 Top rows draw stroked path with combinations of joins and caps. The open contour
3782 is affected by caps; the closed contour is affected by joins.
Mike Klein9ff8c8c2018-02-07 01:58:51 +00003783 Bottom row draws fill the same for open and closed contour.
Cary Clark8032b982017-07-28 11:04:54 -04003784 First bottom column shows winding fills overlap.
3785 Second bottom column shows even odd fills exclude overlap.
3786 Third bottom column shows inverse winding fills area outside both contours.
3787##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003788void draw(SkCanvas* canvas) {
3789 SkPath path;
3790 path.moveTo(20, 20);
3791 path.quadTo(60, 20, 60, 60);
3792 path.close();
3793 path.moveTo(60, 20);
3794 path.quadTo(60, 60, 20, 60);
3795 SkPaint paint;
3796 paint.setStrokeWidth(10);
3797 paint.setAntiAlias(true);
3798 paint.setStyle(SkPaint::kStroke_Style);
3799 for (auto join: { SkPaint::kBevel_Join, SkPaint::kRound_Join, SkPaint::kMiter_Join } ) {
3800 paint.setStrokeJoin(join);
3801 for (auto cap: { SkPaint::kButt_Cap, SkPaint::kSquare_Cap, SkPaint::kRound_Cap } ) {
3802 paint.setStrokeCap(cap);
3803 canvas->drawPath(path, paint);
3804 canvas->translate(80, 0);
3805 }
3806 canvas->translate(-240, 60);
3807 }
3808 paint.setStyle(SkPaint::kFill_Style);
Mike Klein9ff8c8c2018-02-07 01:58:51 +00003809 for (auto fill : { SkPath::kWinding_FillType,
3810 SkPath::kEvenOdd_FillType,
Cary Clarkbad5ad72017-08-03 17:14:08 -04003811 SkPath::kInverseWinding_FillType } ) {
3812 path.setFillType(fill);
3813 canvas->save();
3814 canvas->clipRect({0, 10, 80, 70});
3815 canvas->drawPath(path, paint);
3816 canvas->restore();
3817 canvas->translate(80, 0);
3818 }
Cary Clark8032b982017-07-28 11:04:54 -04003819}
3820##
3821
Cary Clark2ade9972017-11-02 17:49:34 -04003822#SeeAlso SkPath drawLine drawArc drawRect drawPoints
Cary Clark8032b982017-07-28 11:04:54 -04003823
3824##
3825
3826# ------------------------------------------------------------------------------
Cary Clark08895c42018-02-01 09:37:32 -05003827#Subtopic Draw_Image
3828#Line # draws Image to Canvas ##
Cary Clark8032b982017-07-28 11:04:54 -04003829
Cary Clarkbad5ad72017-08-03 17:14:08 -04003830drawImage, drawImageRect, and drawImageNine can be called with a bare pointer or
3831a smart pointer as a convenience. The pairs of calls are otherwise identical.
Cary Clark8032b982017-07-28 11:04:54 -04003832
Cary Clark73fa9722017-08-29 17:36:51 -04003833#Method void drawImage(const SkImage* image, SkScalar left, SkScalar top, const SkPaint* paint = nullptr)
Cary Clarkab2621d2018-01-30 10:08:57 -05003834#In Draw_Image
Cary Clark78de7512018-02-07 07:27:09 -05003835#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05003836#Line # draws Image at (x, y) position ##
Cary Clark8032b982017-07-28 11:04:54 -04003837Draw Image image, with its top-left corner at (left, top),
3838using Clip, Matrix, and optional Paint paint.
3839
Cary Clarkbad5ad72017-08-03 17:14:08 -04003840If paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter, Blend_Mode,
3841and Draw_Looper. If image is kAlpha_8_SkColorType, apply Shader.
3842If paint contains Mask_Filter, generate mask from image bounds. If generated
3843mask extends beyond image bounds, replicate image edge colors, just as Shader
3844made from SkImage::makeShader with SkShader::kClamp_TileMode set replicates the
Mike Klein9ff8c8c2018-02-07 01:58:51 +00003845image edge color when it samples outside of its bounds.
Cary Clark8032b982017-07-28 11:04:54 -04003846
Cary Clarkbad5ad72017-08-03 17:14:08 -04003847#Param image uncompressed rectangular map of pixels ##
3848#Param left left side of image ##
3849#Param top top side of image ##
3850#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
3851 and so on; or nullptr
3852##
Cary Clark8032b982017-07-28 11:04:54 -04003853
3854#Example
3855#Height 64
3856#Image 4
Cary Clarkbad5ad72017-08-03 17:14:08 -04003857void draw(SkCanvas* canvas) {
3858 // sk_sp<SkImage> image;
3859 SkImage* imagePtr = image.get();
3860 canvas->drawImage(imagePtr, 0, 0);
3861 SkPaint paint;
3862 canvas->drawImage(imagePtr, 80, 0, &paint);
3863 paint.setAlpha(0x80);
3864 canvas->drawImage(imagePtr, 160, 0, &paint);
Cary Clark8032b982017-07-28 11:04:54 -04003865}
3866##
3867
Cary Clark2ade9972017-11-02 17:49:34 -04003868#SeeAlso drawBitmap drawImageLattice drawImageNine drawImageRect SkPaint::setImageFilter
Cary Clark8032b982017-07-28 11:04:54 -04003869
3870##
3871
3872# ------------------------------------------------------------------------------
3873
3874#Method void drawImage(const sk_sp<SkImage>& image, SkScalar left, SkScalar top,
Mike Klein9ff8c8c2018-02-07 01:58:51 +00003875 const SkPaint* paint = nullptr)
Cary Clark8032b982017-07-28 11:04:54 -04003876
3877Draw Image image, with its top-left corner at (left, top),
3878using Clip, Matrix, and optional Paint paint.
3879
Cary Clarkbad5ad72017-08-03 17:14:08 -04003880If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
3881Blend_Mode, and Draw_Looper. If image is kAlpha_8_SkColorType, apply Shader.
3882If paint contains Mask_Filter, generate mask from image bounds. If generated
3883mask extends beyond image bounds, replicate image edge colors, just as Shader
3884made from SkImage::makeShader with SkShader::kClamp_TileMode set replicates the
Mike Klein9ff8c8c2018-02-07 01:58:51 +00003885image edge color when it samples outside of its bounds.
Cary Clark8032b982017-07-28 11:04:54 -04003886
Cary Clarkbad5ad72017-08-03 17:14:08 -04003887#Param image uncompressed rectangular map of pixels ##
3888#Param left left side of image ##
3889#Param top pop side of image ##
3890#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
3891 and so on; or nullptr
3892##
Cary Clark8032b982017-07-28 11:04:54 -04003893
3894#Example
3895#Height 64
3896#Image 4
Cary Clarkbad5ad72017-08-03 17:14:08 -04003897void draw(SkCanvas* canvas) {
3898 // sk_sp<SkImage> image;
3899 canvas->drawImage(image, 0, 0);
3900 SkPaint paint;
3901 canvas->drawImage(image, 80, 0, &paint);
3902 paint.setAlpha(0x80);
3903 canvas->drawImage(image, 160, 0, &paint);
Cary Clark8032b982017-07-28 11:04:54 -04003904}
3905##
3906
Cary Clark2ade9972017-11-02 17:49:34 -04003907#SeeAlso drawBitmap drawImageLattice drawImageNine drawImageRect SkPaint::setImageFilter
Cary Clark8032b982017-07-28 11:04:54 -04003908
3909##
3910
3911# ------------------------------------------------------------------------------
3912
3913#Enum SrcRectConstraint
Cary Clark08895c42018-02-01 09:37:32 -05003914#Line # sets drawImageRect options ##
Cary Clark8032b982017-07-28 11:04:54 -04003915
3916#Code
3917 enum SrcRectConstraint {
Mike Klein9ff8c8c2018-02-07 01:58:51 +00003918 kStrict_SrcRectConstraint,
3919 kFast_SrcRectConstraint,
Cary Clark8032b982017-07-28 11:04:54 -04003920 };
3921##
3922
Cary Clarkce101242017-09-01 15:51:02 -04003923SrcRectConstraint controls the behavior at the edge of source Rect,
3924provided to drawImageRect, trading off speed for precision.
Cary Clark8032b982017-07-28 11:04:54 -04003925
Cary Clarkce101242017-09-01 15:51:02 -04003926Image_Filter in Paint may sample multiple pixels in the image. Source Rect
Cary Clarkbad5ad72017-08-03 17:14:08 -04003927restricts the bounds of pixels that may be read. Image_Filter may slow down if
Mike Klein9ff8c8c2018-02-07 01:58:51 +00003928it cannot read outside the bounds, when sampling near the edge of source Rect.
Cary Clark8032b982017-07-28 11:04:54 -04003929SrcRectConstraint specifies whether an Image_Filter is allowed to read pixels
Cary Clarkce101242017-09-01 15:51:02 -04003930outside source Rect.
Cary Clark8032b982017-07-28 11:04:54 -04003931
3932#Const kStrict_SrcRectConstraint
Cary Clarkce101242017-09-01 15:51:02 -04003933 Requires Image_Filter to respect source Rect,
Cary Clark8032b982017-07-28 11:04:54 -04003934 sampling only inside of its bounds, possibly with a performance penalty.
3935##
3936
3937#Const kFast_SrcRectConstraint
Cary Clarkce101242017-09-01 15:51:02 -04003938 Permits Image_Filter to sample outside of source Rect
Cary Clark8032b982017-07-28 11:04:54 -04003939 by half the width of Image_Filter, permitting it to run faster but with
3940 error at the image edges.
3941##
3942
3943#Example
3944#Height 64
3945#Description
3946 redBorder contains a black and white checkerboard bordered by red.
3947 redBorder is drawn scaled by 16 on the left.
Cary Clarkce101242017-09-01 15:51:02 -04003948 The middle and right bitmaps are filtered checkerboards.
Cary Clark8032b982017-07-28 11:04:54 -04003949 Drawing the checkerboard with kStrict_SrcRectConstraint shows only a blur of black and white.
3950 Drawing the checkerboard with kFast_SrcRectConstraint allows red to bleed in the corners.
3951##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003952void draw(SkCanvas* canvas) {
3953 SkBitmap redBorder;
3954 redBorder.allocPixels(SkImageInfo::MakeN32Premul(4, 4));
3955 SkCanvas checkRed(redBorder);
3956 checkRed.clear(SK_ColorRED);
3957 uint32_t checkers[][2] = { { SK_ColorBLACK, SK_ColorWHITE },
3958 { SK_ColorWHITE, SK_ColorBLACK } };
3959 checkRed.writePixels(
3960 SkImageInfo::MakeN32Premul(2, 2), (void*) checkers, sizeof(checkers[0]), 1, 1);
3961 canvas->scale(16, 16);
3962 canvas->drawBitmap(redBorder, 0, 0, nullptr);
3963 canvas->resetMatrix();
3964 sk_sp<SkImage> image = SkImage::MakeFromBitmap(redBorder);
3965 SkPaint lowPaint;
3966 lowPaint.setFilterQuality(kLow_SkFilterQuality);
3967 for (auto constraint : { SkCanvas::kStrict_SrcRectConstraint,
3968 SkCanvas::kFast_SrcRectConstraint } ) {
3969 canvas->translate(80, 0);
3970 canvas->drawImageRect(image.get(), SkRect::MakeLTRB(1, 1, 3, 3),
3971 SkRect::MakeLTRB(16, 16, 48, 48), &lowPaint, constraint);
3972 }
Cary Clark8032b982017-07-28 11:04:54 -04003973}
3974##
3975
Cary Clark2ade9972017-11-02 17:49:34 -04003976#SeeAlso drawImageRect drawImage SkPaint::setImageFilter
Cary Clark8032b982017-07-28 11:04:54 -04003977
3978##
3979
3980# ------------------------------------------------------------------------------
3981
3982#Method void drawImageRect(const SkImage* image, const SkRect& src, const SkRect& dst,
3983 const SkPaint* paint,
3984 SrcRectConstraint constraint = kStrict_SrcRectConstraint)
Cary Clarkab2621d2018-01-30 10:08:57 -05003985#In Draw_Image
Cary Clark78de7512018-02-07 07:27:09 -05003986#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05003987#Line # draws Image, source Rect to destination Rect ##
Cary Clark8032b982017-07-28 11:04:54 -04003988
3989Draw Rect src of Image image, scaled and translated to fill Rect dst.
3990Additionally transform draw using Clip, Matrix, and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04003991
Cary Clarkbad5ad72017-08-03 17:14:08 -04003992If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
3993Blend_Mode, and Draw_Looper. If image is kAlpha_8_SkColorType, apply Shader.
3994If paint contains Mask_Filter, generate mask from image bounds.
3995
3996If generated mask extends beyond image bounds, replicate image edge colors, just
3997as Shader made from SkImage::makeShader with SkShader::kClamp_TileMode set
Cary Clarkbc5697d2017-10-04 14:31:33 -04003998replicates the image edge color when it samples outside of its bounds.
Cary Clarkbad5ad72017-08-03 17:14:08 -04003999
4000constraint set to kStrict_SrcRectConstraint limits Paint Filter_Quality to
4001sample within src; set to kFast_SrcRectConstraint allows sampling outside to
4002improve performance.
4003
4004#Param image Image containing pixels, dimensions, and format ##
4005#Param src source Rect of image to draw from ##
4006#Param dst destination Rect of image to draw to ##
4007#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4008 and so on; or nullptr
4009##
4010#Param constraint filter strictly within src or draw faster ##
Cary Clark8032b982017-07-28 11:04:54 -04004011
4012#Example
4013#Height 64
4014#Description
4015 The left bitmap draws with Paint default kNone_SkFilterQuality, and stays within
Cary Clarkbc5697d2017-10-04 14:31:33 -04004016 its bounds; there is no bleeding with kFast_SrcRectConstraint.
Cary Clark8032b982017-07-28 11:04:54 -04004017 the middle and right bitmaps draw with kLow_SkFilterQuality; with
4018 kStrict_SrcRectConstraint, the filter remains within the checkerboard, and
4019 with kFast_SrcRectConstraint red bleeds on the edges.
4020##
Cary Clarkbad5ad72017-08-03 17:14:08 -04004021void draw(SkCanvas* canvas) {
Mike Klein9ff8c8c2018-02-07 01:58:51 +00004022 uint32_t pixels[][4] = {
Cary Clarkbad5ad72017-08-03 17:14:08 -04004023 { 0xFFFF0000, 0xFFFF0000, 0xFFFF0000, 0xFFFF0000 },
4024 { 0xFFFF0000, 0xFF000000, 0xFFFFFFFF, 0xFFFF0000 },
4025 { 0xFFFF0000, 0xFFFFFFFF, 0xFF000000, 0xFFFF0000 },
4026 { 0xFFFF0000, 0xFFFF0000, 0xFFFF0000, 0xFFFF0000 } };
4027 SkBitmap redBorder;
Mike Klein9ff8c8c2018-02-07 01:58:51 +00004028 redBorder.installPixels(SkImageInfo::MakeN32Premul(4, 4),
Cary Clarkbad5ad72017-08-03 17:14:08 -04004029 (void*) pixels, sizeof(pixels[0]));
4030 sk_sp<SkImage> image = SkImage::MakeFromBitmap(redBorder);
4031 SkPaint lowPaint;
4032 for (auto constraint : {
4033 SkCanvas::kFast_SrcRectConstraint,
4034 SkCanvas::kStrict_SrcRectConstraint,
4035 SkCanvas::kFast_SrcRectConstraint } ) {
4036 canvas->drawImageRect(image.get(), SkRect::MakeLTRB(1, 1, 3, 3),
4037 SkRect::MakeLTRB(16, 16, 48, 48), &lowPaint, constraint);
4038 lowPaint.setFilterQuality(kLow_SkFilterQuality);
4039 canvas->translate(80, 0);
4040 }
4041}
Cary Clark8032b982017-07-28 11:04:54 -04004042##
4043
Cary Clark2ade9972017-11-02 17:49:34 -04004044#SeeAlso SrcRectConstraint drawImage drawImageLattice drawImageNine
Cary Clark8032b982017-07-28 11:04:54 -04004045
4046##
4047
4048# ------------------------------------------------------------------------------
4049
4050#Method void drawImageRect(const SkImage* image, const SkIRect& isrc, const SkRect& dst,
4051 const SkPaint* paint, SrcRectConstraint constraint = kStrict_SrcRectConstraint)
Cary Clarkab2621d2018-01-30 10:08:57 -05004052#In Draw_Image
Cary Clark78de7512018-02-07 07:27:09 -05004053#In Draw
Cary Clark8032b982017-07-28 11:04:54 -04004054
4055Draw IRect isrc of Image image, scaled and translated to fill Rect dst.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004056Note that isrc is on integer pixel boundaries; dst may include fractional
4057boundaries. Additionally transform draw using Clip, Matrix, and optional Paint
Mike Klein9ff8c8c2018-02-07 01:58:51 +00004058paint.
Cary Clark8032b982017-07-28 11:04:54 -04004059
Cary Clarkbad5ad72017-08-03 17:14:08 -04004060If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4061Blend_Mode, and Draw_Looper. If image is kAlpha_8_SkColorType, apply Shader.
4062If paint contains Mask_Filter, generate mask from image bounds.
4063
4064If generated mask extends beyond image bounds, replicate image edge colors, just
4065as Shader made from SkImage::makeShader with SkShader::kClamp_TileMode set
Cary Clarkbc5697d2017-10-04 14:31:33 -04004066replicates the image edge color when it samples outside of its bounds.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004067
4068constraint set to kStrict_SrcRectConstraint limits Paint Filter_Quality to
Cary Clarkce101242017-09-01 15:51:02 -04004069sample within isrc; set to kFast_SrcRectConstraint allows sampling outside to
Cary Clarkbad5ad72017-08-03 17:14:08 -04004070improve performance.
4071
4072#Param image Image containing pixels, dimensions, and format ##
4073#Param isrc source IRect of image to draw from ##
4074#Param dst destination Rect of image to draw to ##
4075#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4076 and so on; or nullptr
4077##
Cary Clarkce101242017-09-01 15:51:02 -04004078#Param constraint filter strictly within isrc or draw faster ##
Cary Clark8032b982017-07-28 11:04:54 -04004079
4080#Example
4081#Image 4
Cary Clarkbad5ad72017-08-03 17:14:08 -04004082void draw(SkCanvas* canvas) {
4083 // sk_sp<SkImage> image;
4084 for (auto i : { 1, 2, 4, 8 } ) {
Mike Klein9ff8c8c2018-02-07 01:58:51 +00004085 canvas->drawImageRect(image.get(), SkIRect::MakeLTRB(0, 0, 100, 100),
Cary Clarkbad5ad72017-08-03 17:14:08 -04004086 SkRect::MakeXYWH(i * 20, i * 20, i * 20, i * 20), nullptr);
4087 }
Cary Clark8032b982017-07-28 11:04:54 -04004088}
4089##
4090
Cary Clark2ade9972017-11-02 17:49:34 -04004091#SeeAlso SrcRectConstraint drawImage drawImageLattice drawImageNine
Cary Clark8032b982017-07-28 11:04:54 -04004092
4093##
4094
4095# ------------------------------------------------------------------------------
4096
4097#Method void drawImageRect(const SkImage* image, const SkRect& dst, const SkPaint* paint,
4098 SrcRectConstraint constraint = kStrict_SrcRectConstraint)
Cary Clarkab2621d2018-01-30 10:08:57 -05004099#In Draw_Image
Cary Clark78de7512018-02-07 07:27:09 -05004100#In Draw
Cary Clark8032b982017-07-28 11:04:54 -04004101
Cary Clarkbad5ad72017-08-03 17:14:08 -04004102Draw Image image, scaled and translated to fill Rect dst, using Clip, Matrix,
4103and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004104
Cary Clarkbad5ad72017-08-03 17:14:08 -04004105If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4106Blend_Mode, and Draw_Looper. If image is kAlpha_8_SkColorType, apply Shader.
4107If paint contains Mask_Filter, generate mask from image bounds.
4108
4109If generated mask extends beyond image bounds, replicate image edge colors, just
4110as Shader made from SkImage::makeShader with SkShader::kClamp_TileMode set
Cary Clarkbc5697d2017-10-04 14:31:33 -04004111replicates the image edge color when it samples outside of its bounds.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004112
4113constraint set to kStrict_SrcRectConstraint limits Paint Filter_Quality to
Cary Clarkce101242017-09-01 15:51:02 -04004114sample within image; set to kFast_SrcRectConstraint allows sampling outside to
Cary Clarkbad5ad72017-08-03 17:14:08 -04004115improve performance.
4116
4117#Param image Image containing pixels, dimensions, and format ##
4118#Param dst destination Rect of image to draw to ##
4119#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4120 and so on; or nullptr
4121##
Cary Clarkce101242017-09-01 15:51:02 -04004122#Param constraint filter strictly within image or draw faster ##
Cary Clark8032b982017-07-28 11:04:54 -04004123
4124#Example
4125#Image 4
Cary Clarkbad5ad72017-08-03 17:14:08 -04004126void draw(SkCanvas* canvas) {
4127 // sk_sp<SkImage> image;
4128 for (auto i : { 20, 40, 80, 160 } ) {
4129 canvas->drawImageRect(image.get(), SkRect::MakeXYWH(i, i, i, i), nullptr);
4130 }
Cary Clark8032b982017-07-28 11:04:54 -04004131}
4132##
4133
Cary Clark2ade9972017-11-02 17:49:34 -04004134#SeeAlso SrcRectConstraint drawImage drawImageLattice drawImageNine
Cary Clark8032b982017-07-28 11:04:54 -04004135
4136##
4137
4138# ------------------------------------------------------------------------------
4139
4140#Method void drawImageRect(const sk_sp<SkImage>& image, const SkRect& src, const SkRect& dst,
4141 const SkPaint* paint,
Mike Klein9ff8c8c2018-02-07 01:58:51 +00004142 SrcRectConstraint constraint = kStrict_SrcRectConstraint)
Cary Clarkab2621d2018-01-30 10:08:57 -05004143#In Draw_Image
Cary Clark78de7512018-02-07 07:27:09 -05004144#In Draw
Cary Clark8032b982017-07-28 11:04:54 -04004145Draw Rect src of Image image, scaled and translated to fill Rect dst.
4146Additionally transform draw using Clip, Matrix, and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004147
Cary Clarkbad5ad72017-08-03 17:14:08 -04004148If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4149Blend_Mode, and Draw_Looper. If image is kAlpha_8_SkColorType, apply Shader.
4150If paint contains Mask_Filter, generate mask from image bounds.
4151
4152If generated mask extends beyond image bounds, replicate image edge colors, just
4153as Shader made from SkImage::makeShader with SkShader::kClamp_TileMode set
Cary Clarkbc5697d2017-10-04 14:31:33 -04004154replicates the image edge color when it samples outside of its bounds.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004155
4156constraint set to kStrict_SrcRectConstraint limits Paint Filter_Quality to
4157sample within src; set to kFast_SrcRectConstraint allows sampling outside to
4158improve performance.
4159
4160#Param image Image containing pixels, dimensions, and format ##
4161#Param src source Rect of image to draw from ##
4162#Param dst destination Rect of image to draw to ##
4163#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4164 and so on; or nullptr
4165##
4166#Param constraint filter strictly within src or draw faster ##
Cary Clark8032b982017-07-28 11:04:54 -04004167
4168#Example
4169#Height 64
4170#Description
4171 Canvas scales and translates; transformation from src to dst also scales.
4172 The two matrices are concatenated to create the final transformation.
4173##
Cary Clarkbad5ad72017-08-03 17:14:08 -04004174void draw(SkCanvas* canvas) {
4175 uint32_t pixels[][2] = { { SK_ColorBLACK, SK_ColorWHITE },
4176 { SK_ColorWHITE, SK_ColorBLACK } };
4177 SkBitmap bitmap;
Mike Klein9ff8c8c2018-02-07 01:58:51 +00004178 bitmap.installPixels(SkImageInfo::MakeN32Premul(2, 2),
Cary Clarkbad5ad72017-08-03 17:14:08 -04004179 (void*) pixels, sizeof(pixels[0]));
4180 sk_sp<SkImage> image = SkImage::MakeFromBitmap(bitmap);
4181 SkPaint paint;
4182 canvas->scale(4, 4);
4183 for (auto alpha : { 50, 100, 150, 255 } ) {
4184 paint.setAlpha(alpha);
4185 canvas->drawImageRect(image, SkRect::MakeWH(2, 2), SkRect::MakeWH(8, 8), &paint);
4186 canvas->translate(8, 0);
4187 }
4188}
Cary Clark8032b982017-07-28 11:04:54 -04004189##
4190
Cary Clark2ade9972017-11-02 17:49:34 -04004191#SeeAlso SrcRectConstraint drawImage drawImageLattice drawImageNine
Cary Clark8032b982017-07-28 11:04:54 -04004192
4193##
4194
4195# ------------------------------------------------------------------------------
4196
4197#Method void drawImageRect(const sk_sp<SkImage>& image, const SkIRect& isrc, const SkRect& dst,
Mike Klein9ff8c8c2018-02-07 01:58:51 +00004198 const SkPaint* paint, SrcRectConstraint constraint = kStrict_SrcRectConstraint)
Cary Clarkab2621d2018-01-30 10:08:57 -05004199#In Draw_Image
Cary Clark78de7512018-02-07 07:27:09 -05004200#In Draw
Cary Clark8032b982017-07-28 11:04:54 -04004201Draw IRect isrc of Image image, scaled and translated to fill Rect dst.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004202isrc is on integer pixel boundaries; dst may include fractional boundaries.
Cary Clark8032b982017-07-28 11:04:54 -04004203Additionally transform draw using Clip, Matrix, and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004204
Cary Clarkbad5ad72017-08-03 17:14:08 -04004205If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4206Blend_Mode, and Draw_Looper. If image is kAlpha_8_SkColorType, apply Shader.
4207If paint contains Mask_Filter, generate mask from image bounds.
4208
4209If generated mask extends beyond image bounds, replicate image edge colors, just
4210as Shader made from SkImage::makeShader with SkShader::kClamp_TileMode set
Cary Clarkbc5697d2017-10-04 14:31:33 -04004211replicates the image edge color when it samples outside of its bounds.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004212
4213constraint set to kStrict_SrcRectConstraint limits Paint Filter_Quality to
Cary Clarkce101242017-09-01 15:51:02 -04004214sample within image; set to kFast_SrcRectConstraint allows sampling outside to
Cary Clarkbad5ad72017-08-03 17:14:08 -04004215improve performance.
4216
4217#Param image Image containing pixels, dimensions, and format ##
4218#Param isrc source IRect of image to draw from ##
4219#Param dst destination Rect of image to draw to ##
4220#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4221 and so on; or nullptr
4222##
Cary Clarkce101242017-09-01 15:51:02 -04004223#Param constraint filter strictly within image or draw faster ##
Cary Clark8032b982017-07-28 11:04:54 -04004224
4225#Example
4226#Height 64
Cary Clarkbad5ad72017-08-03 17:14:08 -04004227void draw(SkCanvas* canvas) {
4228 uint32_t pixels[][2] = { { 0x00000000, 0x55555555},
4229 { 0xAAAAAAAA, 0xFFFFFFFF} };
4230 SkBitmap bitmap;
Mike Klein9ff8c8c2018-02-07 01:58:51 +00004231 bitmap.installPixels(SkImageInfo::MakeN32Premul(2, 2),
Cary Clarkbad5ad72017-08-03 17:14:08 -04004232 (void*) pixels, sizeof(pixels[0]));
4233 sk_sp<SkImage> image = SkImage::MakeFromBitmap(bitmap);
4234 SkPaint paint;
4235 canvas->scale(4, 4);
4236 for (auto color : { SK_ColorRED, SK_ColorBLUE, SK_ColorGREEN } ) {
4237 paint.setColorFilter(SkColorFilter::MakeModeFilter(color, SkBlendMode::kPlus));
4238 canvas->drawImageRect(image, SkIRect::MakeWH(2, 2), SkRect::MakeWH(8, 8), &paint);
4239 canvas->translate(8, 0);
4240 }
Cary Clark8032b982017-07-28 11:04:54 -04004241}
4242##
4243
Cary Clark2ade9972017-11-02 17:49:34 -04004244#SeeAlso SrcRectConstraint drawImage drawImageLattice drawImageNine
4245
Cary Clark8032b982017-07-28 11:04:54 -04004246##
4247
4248# ------------------------------------------------------------------------------
4249
4250#Method void drawImageRect(const sk_sp<SkImage>& image, const SkRect& dst, const SkPaint* paint,
Mike Klein9ff8c8c2018-02-07 01:58:51 +00004251 SrcRectConstraint constraint = kStrict_SrcRectConstraint)
Cary Clarkab2621d2018-01-30 10:08:57 -05004252#In Draw_Image
Cary Clark78de7512018-02-07 07:27:09 -05004253#In Draw
Cary Clark8032b982017-07-28 11:04:54 -04004254Draw Image image, scaled and translated to fill Rect dst,
4255using Clip, Matrix, and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004256
Cary Clarkbad5ad72017-08-03 17:14:08 -04004257If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4258Blend_Mode, and Draw_Looper. If image is kAlpha_8_SkColorType, apply Shader.
4259If paint contains Mask_Filter, generate mask from image bounds.
4260
4261If generated mask extends beyond image bounds, replicate image edge colors, just
4262as Shader made from SkImage::makeShader with SkShader::kClamp_TileMode set
Cary Clarkbc5697d2017-10-04 14:31:33 -04004263replicates the image edge color when it samples outside of its bounds.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004264
4265constraint set to kStrict_SrcRectConstraint limits Paint Filter_Quality to
Cary Clarkce101242017-09-01 15:51:02 -04004266sample within image; set to kFast_SrcRectConstraint allows sampling outside to
Cary Clarkbad5ad72017-08-03 17:14:08 -04004267improve performance.
4268
4269#Param image Image containing pixels, dimensions, and format ##
4270#Param dst destination Rect of image to draw to ##
4271#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4272 and so on; or nullptr
4273##
Cary Clarkce101242017-09-01 15:51:02 -04004274#Param constraint filter strictly within image or draw faster ##
Cary Clark8032b982017-07-28 11:04:54 -04004275
4276#Example
4277#Height 64
Cary Clarkbad5ad72017-08-03 17:14:08 -04004278void draw(SkCanvas* canvas) {
4279 uint32_t pixels[][2] = { { 0x00000000, 0x55550000},
4280 { 0xAAAA0000, 0xFFFF0000} };
4281 SkBitmap bitmap;
Mike Klein9ff8c8c2018-02-07 01:58:51 +00004282 bitmap.installPixels(SkImageInfo::MakeN32Premul(2, 2),
Cary Clarkbad5ad72017-08-03 17:14:08 -04004283 (void*) pixels, sizeof(pixels[0]));
4284 sk_sp<SkImage> image = SkImage::MakeFromBitmap(bitmap);
4285 SkPaint paint;
4286 canvas->scale(4, 4);
4287 for (auto color : { SK_ColorRED, SK_ColorBLUE, SK_ColorGREEN } ) {
4288 paint.setColorFilter(SkColorFilter::MakeModeFilter(color, SkBlendMode::kPlus));
4289 canvas->drawImageRect(image, SkRect::MakeWH(8, 8), &paint);
4290 canvas->translate(8, 0);
4291 }
Cary Clark8032b982017-07-28 11:04:54 -04004292}
4293##
4294
Cary Clark2ade9972017-11-02 17:49:34 -04004295#SeeAlso SrcRectConstraint drawImage drawImageLattice drawImageNine
Cary Clark8032b982017-07-28 11:04:54 -04004296
4297##
4298
4299# ------------------------------------------------------------------------------
4300
4301#Method void drawImageNine(const SkImage* image, const SkIRect& center, const SkRect& dst,
4302 const SkPaint* paint = nullptr)
Cary Clarkab2621d2018-01-30 10:08:57 -05004303#In Draw_Image
Cary Clark78de7512018-02-07 07:27:09 -05004304#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05004305#Line # draws Nine_Patch Image ##
Cary Clark8032b982017-07-28 11:04:54 -04004306
Cary Clarkd0530ba2017-09-14 11:25:39 -04004307Draw Image image stretched proportionally to fit into Rect dst.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004308IRect center divides the image into nine sections: four sides, four corners, and
Cary Clarkce101242017-09-01 15:51:02 -04004309the center. Corners are unmodified or scaled down proportionately if their sides
Cary Clarkbad5ad72017-08-03 17:14:08 -04004310are larger than dst; center and four sides are scaled to fit remaining space, if any.
Cary Clark8032b982017-07-28 11:04:54 -04004311
Cary Clarkbad5ad72017-08-03 17:14:08 -04004312Additionally transform draw using Clip, Matrix, and optional Paint paint.
4313
4314If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4315Blend_Mode, and Draw_Looper. If image is kAlpha_8_SkColorType, apply Shader.
4316If paint contains Mask_Filter, generate mask from image bounds.
4317
4318If generated mask extends beyond image bounds, replicate image edge colors, just
4319as Shader made from SkImage::makeShader with SkShader::kClamp_TileMode set
Cary Clarkbc5697d2017-10-04 14:31:33 -04004320replicates the image edge color when it samples outside of its bounds.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004321
4322#Param image Image containing pixels, dimensions, and format ##
4323#Param center IRect edge of image corners and sides ##
4324#Param dst destination Rect of image to draw to ##
4325#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4326 and so on; or nullptr
4327##
Cary Clark8032b982017-07-28 11:04:54 -04004328
4329#Example
4330#Height 128
4331#Description
4332 The leftmost image is smaller than center; only corners are drawn, all scaled to fit.
Cary Clarkce101242017-09-01 15:51:02 -04004333 The second image equals the size of center; only corners are drawn without scaling.
4334 The remaining images are larger than center. All corners draw without scaling.
4335 The sides and center are scaled if needed to take up the remaining space.
Cary Clark8032b982017-07-28 11:04:54 -04004336##
Cary Clarkbad5ad72017-08-03 17:14:08 -04004337void draw(SkCanvas* canvas) {
4338 SkIRect center = { 20, 10, 50, 40 };
4339 SkBitmap bitmap;
4340 bitmap.allocPixels(SkImageInfo::MakeN32Premul(60, 60));
4341 SkCanvas bitCanvas(bitmap);
4342 SkPaint paint;
4343 SkColor gray = 0xFF000000;
4344 int left = 0;
4345 for (auto right: { center.fLeft, center.fRight, bitmap.width() } ) {
4346 int top = 0;
4347 for (auto bottom: { center.fTop, center.fBottom, bitmap.height() } ) {
4348 paint.setColor(gray);
4349 bitCanvas.drawIRect(SkIRect::MakeLTRB(left, top, right, bottom), paint);
4350 gray += 0x001f1f1f;
4351 top = bottom;
4352 }
Mike Klein9ff8c8c2018-02-07 01:58:51 +00004353 left = right;
Cary Clarkbad5ad72017-08-03 17:14:08 -04004354 }
4355 sk_sp<SkImage> image = SkImage::MakeFromBitmap(bitmap);
4356 SkImage* imagePtr = image.get();
4357 for (auto dest: { 20, 30, 40, 60, 90 } ) {
4358 canvas->drawImageNine(imagePtr, center, SkRect::MakeWH(dest, dest), nullptr);
4359 canvas->translate(dest + 4, 0);
4360 }
Cary Clark8032b982017-07-28 11:04:54 -04004361}
4362##
4363
Cary Clark2ade9972017-11-02 17:49:34 -04004364#SeeAlso drawImage drawBitmapNine drawImageLattice drawImageRect
Cary Clark8032b982017-07-28 11:04:54 -04004365
4366##
4367
4368# ------------------------------------------------------------------------------
4369
4370#Method void drawImageNine(const sk_sp<SkImage>& image, const SkIRect& center, const SkRect& dst,
Mike Klein9ff8c8c2018-02-07 01:58:51 +00004371 const SkPaint* paint = nullptr)
Cary Clarkab2621d2018-01-30 10:08:57 -05004372#In Draw_Image
Cary Clark78de7512018-02-07 07:27:09 -05004373#In Draw
Cary Clarkd0530ba2017-09-14 11:25:39 -04004374Draw Image image stretched proportionally to fit into Rect dst.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004375IRect center divides the image into nine sections: four sides, four corners, and
Cary Clarkce101242017-09-01 15:51:02 -04004376the center. Corners are not scaled, or scaled down proportionately if their sides
Cary Clarkbad5ad72017-08-03 17:14:08 -04004377are larger than dst; center and four sides are scaled to fit remaining space, if any.
Cary Clark8032b982017-07-28 11:04:54 -04004378
Cary Clarkbad5ad72017-08-03 17:14:08 -04004379Additionally transform draw using Clip, Matrix, and optional Paint paint.
4380
4381If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4382Blend_Mode, and Draw_Looper. If image is kAlpha_8_SkColorType, apply Shader.
4383If paint contains Mask_Filter, generate mask from image bounds.
4384
4385If generated mask extends beyond image bounds, replicate image edge colors, just
4386as Shader made from SkImage::makeShader with SkShader::kClamp_TileMode set
Cary Clarkbc5697d2017-10-04 14:31:33 -04004387replicates the image edge color when it samples outside of its bounds.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004388
4389#Param image Image containing pixels, dimensions, and format ##
4390#Param center IRect edge of image corners and sides ##
4391#Param dst destination Rect of image to draw to ##
4392#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4393 and so on; or nullptr
4394##
Cary Clark8032b982017-07-28 11:04:54 -04004395
4396#Example
4397#Height 128
4398#Description
4399 The two leftmost images has four corners and sides to the left and right of center.
4400 The leftmost image scales the width of corners proportionately to fit.
Mike Klein9ff8c8c2018-02-07 01:58:51 +00004401 The third and fourth image corners are not scaled; the sides and center are scaled to
Cary Clark8032b982017-07-28 11:04:54 -04004402 fill the remaining space.
4403 The rightmost image has four corners scaled vertically to fit, and uses sides above
4404 and below center to fill the remaining space.
4405##
Cary Clarkbad5ad72017-08-03 17:14:08 -04004406void draw(SkCanvas* canvas) {
4407 SkIRect center = { 20, 10, 50, 40 };
4408 SkBitmap bitmap;
4409 bitmap.allocPixels(SkImageInfo::MakeN32Premul(60, 60));
4410 SkCanvas bitCanvas(bitmap);
4411 SkPaint paint;
4412 SkColor gray = 0xFF000000;
4413 int left = 0;
4414 for (auto right: { center.fLeft, center.fRight, bitmap.width() } ) {
4415 int top = 0;
4416 for (auto bottom: { center.fTop, center.fBottom, bitmap.height() } ) {
4417 paint.setColor(gray);
4418 bitCanvas.drawIRect(SkIRect::MakeLTRB(left, top, right, bottom), paint);
4419 gray += 0x001f1f1f;
4420 top = bottom;
4421 }
Mike Klein9ff8c8c2018-02-07 01:58:51 +00004422 left = right;
Cary Clarkbad5ad72017-08-03 17:14:08 -04004423 }
4424 sk_sp<SkImage> image = SkImage::MakeFromBitmap(bitmap);
4425 for (auto dest: { 20, 30, 40, 60, 90 } ) {
4426 canvas->drawImageNine(image, center, SkRect::MakeWH(dest, 110 - dest), nullptr);
4427 canvas->translate(dest + 4, 0);
4428 }
Cary Clark8032b982017-07-28 11:04:54 -04004429}
4430##
4431
Cary Clark2ade9972017-11-02 17:49:34 -04004432#SeeAlso drawImage drawBitmapNine drawImageLattice drawImageRect
Cary Clark8032b982017-07-28 11:04:54 -04004433
4434##
4435
4436# ------------------------------------------------------------------------------
4437
4438#Method void drawBitmap(const SkBitmap& bitmap, SkScalar left, SkScalar top,
Cary Clark73fa9722017-08-29 17:36:51 -04004439 const SkPaint* paint = nullptr)
Cary Clarkab2621d2018-01-30 10:08:57 -05004440#In Draw_Image
Cary Clark78de7512018-02-07 07:27:09 -05004441#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05004442#Line # draws Bitmap at (x, y) position ##
Cary Clark8032b982017-07-28 11:04:54 -04004443
4444Draw Bitmap bitmap, with its top-left corner at (left, top),
4445using Clip, Matrix, and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004446
Cary Clarka560c472017-11-27 10:44:06 -05004447If Paint paint is not nullptr, apply Color_Filter, Color_Alpha, Image_Filter,
Cary Clarkbad5ad72017-08-03 17:14:08 -04004448Blend_Mode, and Draw_Looper. If bitmap is kAlpha_8_SkColorType, apply Shader.
4449If paint contains Mask_Filter, generate mask from bitmap bounds.
4450
4451If generated mask extends beyond bitmap bounds, replicate bitmap edge colors,
4452just as Shader made from SkShader::MakeBitmapShader with
Cary Clarkbc5697d2017-10-04 14:31:33 -04004453SkShader::kClamp_TileMode set replicates the bitmap edge color when it samples
Mike Klein9ff8c8c2018-02-07 01:58:51 +00004454outside of its bounds.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004455
4456#Param bitmap Bitmap containing pixels, dimensions, and format ##
4457#Param left left side of bitmap ##
4458#Param top top side of bitmap ##
4459#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4460 and so on; or nullptr
4461##
Cary Clark8032b982017-07-28 11:04:54 -04004462
4463#Example
4464#Height 64
Cary Clarkbad5ad72017-08-03 17:14:08 -04004465void draw(SkCanvas* canvas) {
4466 uint8_t pixels[][8] = { { 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00},
4467 { 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00},
4468 { 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00},
4469 { 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF},
4470 { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
4471 { 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00},
4472 { 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0x00},
4473 { 0xFF, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0xFF} };
4474 SkBitmap bitmap;
Mike Klein9ff8c8c2018-02-07 01:58:51 +00004475 bitmap.installPixels(SkImageInfo::MakeA8(8, 8),
Cary Clarkbad5ad72017-08-03 17:14:08 -04004476 (void*) pixels, sizeof(pixels[0]));
4477 SkPaint paint;
4478 canvas->scale(4, 4);
4479 for (auto color : { SK_ColorRED, SK_ColorBLUE, 0xFF007F00} ) {
4480 paint.setColor(color);
4481 canvas->drawBitmap(bitmap, 0, 0, &paint);
4482 canvas->translate(12, 0);
4483 }
Cary Clark8032b982017-07-28 11:04:54 -04004484}
4485##
4486
Cary Clark2ade9972017-11-02 17:49:34 -04004487#SeeAlso drawImage drawBitmapLattice drawBitmapNine drawBitmapRect SkBitmap::readPixels SkBitmap::writePixels
Cary Clark8032b982017-07-28 11:04:54 -04004488
4489##
4490
4491# ------------------------------------------------------------------------------
4492
4493#Method void drawBitmapRect(const SkBitmap& bitmap, const SkRect& src, const SkRect& dst,
4494 const SkPaint* paint, SrcRectConstraint constraint = kStrict_SrcRectConstraint)
Cary Clarkab2621d2018-01-30 10:08:57 -05004495#In Draw_Image
Cary Clark78de7512018-02-07 07:27:09 -05004496#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05004497#Line # draws Bitmap, source Rect to destination Rect ##
Cary Clark8032b982017-07-28 11:04:54 -04004498
4499Draw Rect src of Bitmap bitmap, scaled and translated to fill Rect dst.
4500Additionally transform draw using Clip, Matrix, and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004501
Cary Clarkbad5ad72017-08-03 17:14:08 -04004502If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4503Blend_Mode, and Draw_Looper. If bitmap is kAlpha_8_SkColorType, apply Shader.
4504If paint contains Mask_Filter, generate mask from bitmap bounds.
4505
4506If generated mask extends beyond bitmap bounds, replicate bitmap edge colors,
4507just as Shader made from SkShader::MakeBitmapShader with
Cary Clarkbc5697d2017-10-04 14:31:33 -04004508SkShader::kClamp_TileMode set replicates the bitmap edge color when it samples
Cary Clarkbad5ad72017-08-03 17:14:08 -04004509outside of its bounds.
4510
4511constraint set to kStrict_SrcRectConstraint limits Paint Filter_Quality to
4512sample within src; set to kFast_SrcRectConstraint allows sampling outside to
4513improve performance.
4514
4515#Param bitmap Bitmap containing pixels, dimensions, and format ##
4516#Param src source Rect of image to draw from ##
4517#Param dst destination Rect of image to draw to ##
4518#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4519 and so on; or nullptr
4520##
4521#Param constraint filter strictly within src or draw faster ##
Cary Clark8032b982017-07-28 11:04:54 -04004522
4523#Example
4524#Height 64
Cary Clarkbad5ad72017-08-03 17:14:08 -04004525void draw(SkCanvas* canvas) {
4526 uint8_t pixels[][8] = { { 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00},
4527 { 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00},
4528 { 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00},
4529 { 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF},
4530 { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
4531 { 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00},
4532 { 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00},
4533 { 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00} };
4534 SkBitmap bitmap;
Mike Klein9ff8c8c2018-02-07 01:58:51 +00004535 bitmap.installPixels(SkImageInfo::MakeA8(8, 8),
Cary Clarkbad5ad72017-08-03 17:14:08 -04004536 (void*) pixels, sizeof(pixels[0]));
4537 SkPaint paint;
4538 paint.setMaskFilter(SkBlurMaskFilter::Make(kSolid_SkBlurStyle, 6));
4539 for (auto color : { SK_ColorRED, SK_ColorBLUE, 0xFF007F00} ) {
4540 paint.setColor(color);
4541 canvas->drawBitmapRect(bitmap, SkRect::MakeWH(8, 8), SkRect::MakeWH(32, 32), &paint);
4542 canvas->translate(48, 0);
4543 }
Cary Clark8032b982017-07-28 11:04:54 -04004544}
4545##
4546
Cary Clark2ade9972017-11-02 17:49:34 -04004547#SeeAlso drawImageRect drawBitmap drawBitmapLattice drawBitmapNine
Cary Clark8032b982017-07-28 11:04:54 -04004548
4549##
4550
4551# ------------------------------------------------------------------------------
4552
4553#Method void drawBitmapRect(const SkBitmap& bitmap, const SkIRect& isrc, const SkRect& dst,
4554 const SkPaint* paint, SrcRectConstraint constraint = kStrict_SrcRectConstraint)
Cary Clarkab2621d2018-01-30 10:08:57 -05004555#In Draw_Image
Cary Clark78de7512018-02-07 07:27:09 -05004556#In Draw
Cary Clark8032b982017-07-28 11:04:54 -04004557Draw IRect isrc of Bitmap bitmap, scaled and translated to fill Rect dst.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004558isrc is on integer pixel boundaries; dst may include fractional boundaries.
Cary Clark8032b982017-07-28 11:04:54 -04004559Additionally transform draw using Clip, Matrix, and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004560
Cary Clarkbad5ad72017-08-03 17:14:08 -04004561If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4562Blend_Mode, and Draw_Looper. If bitmap is kAlpha_8_SkColorType, apply Shader.
4563If paint contains Mask_Filter, generate mask from bitmap bounds.
4564
4565If generated mask extends beyond bitmap bounds, replicate bitmap edge colors,
4566just as Shader made from SkShader::MakeBitmapShader with
Cary Clarkbc5697d2017-10-04 14:31:33 -04004567SkShader::kClamp_TileMode set replicates the bitmap edge color when it samples
Cary Clarkbad5ad72017-08-03 17:14:08 -04004568outside of its bounds.
4569
4570constraint set to kStrict_SrcRectConstraint limits Paint Filter_Quality to
Cary Clarkce101242017-09-01 15:51:02 -04004571sample within isrc; set to kFast_SrcRectConstraint allows sampling outside to
Cary Clarkbad5ad72017-08-03 17:14:08 -04004572improve performance.
4573
4574#Param bitmap Bitmap containing pixels, dimensions, and format ##
4575#Param isrc source IRect of image to draw from ##
4576#Param dst destination Rect of image to draw to ##
4577#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4578 and so on; or nullptr
4579##
Cary Clarkce101242017-09-01 15:51:02 -04004580#Param constraint sample strictly within isrc, or draw faster ##
Cary Clark8032b982017-07-28 11:04:54 -04004581
4582#Example
4583#Height 64
Cary Clarkbad5ad72017-08-03 17:14:08 -04004584void draw(SkCanvas* canvas) {
4585 uint8_t pixels[][8] = { { 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00},
4586 { 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00},
4587 { 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0xFF},
4588 { 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0xFF},
4589 { 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF},
4590 { 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF},
4591 { 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00},
4592 { 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00} };
4593 SkBitmap bitmap;
Mike Klein9ff8c8c2018-02-07 01:58:51 +00004594 bitmap.installPixels(SkImageInfo::MakeA8(8, 8),
Cary Clarkbad5ad72017-08-03 17:14:08 -04004595 (void*) pixels, sizeof(pixels[0]));
4596 SkPaint paint;
4597 paint.setFilterQuality(kHigh_SkFilterQuality);
4598 for (auto color : { SK_ColorRED, SK_ColorBLUE, 0xFF007F00, 0xFF7f007f} ) {
4599 paint.setColor(color);
4600 canvas->drawBitmapRect(bitmap, SkIRect::MakeWH(8, 8), SkRect::MakeWH(32, 32), &paint);
4601 canvas->translate(48.25f, 0);
4602 }
Cary Clark8032b982017-07-28 11:04:54 -04004603}
4604##
4605
Cary Clark2ade9972017-11-02 17:49:34 -04004606#SeeAlso drawImageRect drawBitmap drawBitmapLattice drawBitmapNine
Cary Clark8032b982017-07-28 11:04:54 -04004607
4608##
4609
4610# ------------------------------------------------------------------------------
4611
4612#Method void drawBitmapRect(const SkBitmap& bitmap, const SkRect& dst, const SkPaint* paint,
4613 SrcRectConstraint constraint = kStrict_SrcRectConstraint)
Cary Clarkab2621d2018-01-30 10:08:57 -05004614#In Draw_Image
Cary Clark78de7512018-02-07 07:27:09 -05004615#In Draw
Cary Clark8032b982017-07-28 11:04:54 -04004616Draw Bitmap bitmap, scaled and translated to fill Rect dst.
Cary Clarkce101242017-09-01 15:51:02 -04004617bitmap bounds is on integer pixel boundaries; dst may include fractional boundaries.
Cary Clark8032b982017-07-28 11:04:54 -04004618Additionally transform draw using Clip, Matrix, and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004619
Cary Clarkbad5ad72017-08-03 17:14:08 -04004620If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4621Blend_Mode, and Draw_Looper. If bitmap is kAlpha_8_SkColorType, apply Shader.
4622If paint contains Mask_Filter, generate mask from bitmap bounds.
4623
4624If generated mask extends beyond bitmap bounds, replicate bitmap edge colors,
4625just as Shader made from SkShader::MakeBitmapShader with
Cary Clarkbc5697d2017-10-04 14:31:33 -04004626SkShader::kClamp_TileMode set replicates the bitmap edge color when it samples
Cary Clarkbad5ad72017-08-03 17:14:08 -04004627outside of its bounds.
4628
4629constraint set to kStrict_SrcRectConstraint limits Paint Filter_Quality to
Cary Clarkce101242017-09-01 15:51:02 -04004630sample within bitmap; set to kFast_SrcRectConstraint allows sampling outside to
Cary Clarkbad5ad72017-08-03 17:14:08 -04004631improve performance.
4632
4633#Param bitmap Bitmap containing pixels, dimensions, and format ##
4634#Param dst destination Rect of image to draw to ##
4635#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4636 and so on; or nullptr
4637##
Cary Clarkce101242017-09-01 15:51:02 -04004638#Param constraint filter strictly within bitmap or draw faster ##
Cary Clark8032b982017-07-28 11:04:54 -04004639
4640#Example
4641#Height 64
Cary Clarkbad5ad72017-08-03 17:14:08 -04004642void draw(SkCanvas* canvas) {
4643 uint32_t pixels[][2] = { { 0x00000000, 0x55550000},
4644 { 0xAAAA0000, 0xFFFF0000} };
4645 SkBitmap bitmap;
Mike Klein9ff8c8c2018-02-07 01:58:51 +00004646 bitmap.installPixels(SkImageInfo::MakeN32Premul(2, 2),
Cary Clarkbad5ad72017-08-03 17:14:08 -04004647 (void*) pixels, sizeof(pixels[0]));
4648 SkPaint paint;
4649 canvas->scale(4, 4);
4650 for (auto color : { SK_ColorRED, SK_ColorBLUE, SK_ColorGREEN } ) {
4651 paint.setColorFilter(SkColorFilter::MakeModeFilter(color, SkBlendMode::kPlus));
4652 canvas->drawBitmapRect(bitmap, SkRect::MakeWH(8, 8), &paint);
4653 canvas->translate(8, 0);
4654 }
Cary Clark8032b982017-07-28 11:04:54 -04004655}
4656##
4657
Cary Clark2ade9972017-11-02 17:49:34 -04004658#SeeAlso drawImageRect drawBitmap drawBitmapLattice drawBitmapNine
Cary Clark8032b982017-07-28 11:04:54 -04004659
4660##
4661
4662# ------------------------------------------------------------------------------
4663
4664#Method void drawBitmapNine(const SkBitmap& bitmap, const SkIRect& center, const SkRect& dst,
Cary Clark73fa9722017-08-29 17:36:51 -04004665 const SkPaint* paint = nullptr)
Cary Clarkab2621d2018-01-30 10:08:57 -05004666#In Draw_Image
Cary Clark78de7512018-02-07 07:27:09 -05004667#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05004668#Line # draws Nine_Patch Bitmap ##
Cary Clark8032b982017-07-28 11:04:54 -04004669
Cary Clarkd0530ba2017-09-14 11:25:39 -04004670Draw Bitmap bitmap stretched proportionally to fit into Rect dst.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004671IRect center divides the bitmap into nine sections: four sides, four corners,
Cary Clarkce101242017-09-01 15:51:02 -04004672and the center. Corners are not scaled, or scaled down proportionately if their
Cary Clarkbad5ad72017-08-03 17:14:08 -04004673sides are larger than dst; center and four sides are scaled to fit remaining
4674space, if any.
Cary Clark8032b982017-07-28 11:04:54 -04004675
Cary Clarkbad5ad72017-08-03 17:14:08 -04004676Additionally transform draw using Clip, Matrix, and optional Paint paint.
4677
4678If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4679Blend_Mode, and Draw_Looper. If bitmap is kAlpha_8_SkColorType, apply Shader.
4680If paint contains Mask_Filter, generate mask from bitmap bounds.
4681
4682If generated mask extends beyond bitmap bounds, replicate bitmap edge colors,
4683just as Shader made from SkShader::MakeBitmapShader with
Cary Clarkbc5697d2017-10-04 14:31:33 -04004684SkShader::kClamp_TileMode set replicates the bitmap edge color when it samples
Cary Clarkbad5ad72017-08-03 17:14:08 -04004685outside of its bounds.
4686
4687#Param bitmap Bitmap containing pixels, dimensions, and format ##
4688#Param center IRect edge of image corners and sides ##
4689#Param dst destination Rect of image to draw to ##
4690#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4691 and so on; or nullptr
4692##
Cary Clark8032b982017-07-28 11:04:54 -04004693
4694#Example
4695#Height 128
4696#Description
4697 The two leftmost bitmap draws has four corners and sides to the left and right of center.
4698 The leftmost bitmap draw scales the width of corners proportionately to fit.
Mike Klein9ff8c8c2018-02-07 01:58:51 +00004699 The third and fourth draw corners are not scaled; the sides and center are scaled to
Cary Clark8032b982017-07-28 11:04:54 -04004700 fill the remaining space.
4701 The rightmost bitmap draw has four corners scaled vertically to fit, and uses sides above
4702 and below center to fill the remaining space.
4703##
Cary Clarkbad5ad72017-08-03 17:14:08 -04004704void draw(SkCanvas* canvas) {
4705 SkIRect center = { 20, 10, 50, 40 };
4706 SkBitmap bitmap;
4707 bitmap.allocPixels(SkImageInfo::MakeN32Premul(60, 60));
4708 SkCanvas bitCanvas(bitmap);
4709 SkPaint paint;
4710 SkColor gray = 0xFF000000;
4711 int left = 0;
4712 for (auto right: { center.fLeft, center.fRight, bitmap.width() } ) {
4713 int top = 0;
4714 for (auto bottom: { center.fTop, center.fBottom, bitmap.height() } ) {
4715 paint.setColor(gray);
4716 bitCanvas.drawIRect(SkIRect::MakeLTRB(left, top, right, bottom), paint);
4717 gray += 0x001f1f1f;
4718 top = bottom;
4719 }
Mike Klein9ff8c8c2018-02-07 01:58:51 +00004720 left = right;
Cary Clarkbad5ad72017-08-03 17:14:08 -04004721 }
4722 for (auto dest: { 20, 30, 40, 60, 90 } ) {
4723 canvas->drawBitmapNine(bitmap, center, SkRect::MakeWH(dest, 110 - dest), nullptr);
4724 canvas->translate(dest + 4, 0);
4725 }
Cary Clark8032b982017-07-28 11:04:54 -04004726}
4727##
4728
Cary Clark2ade9972017-11-02 17:49:34 -04004729#SeeAlso drawImageNine drawBitmap drawBitmapLattice drawBitmapRect
Cary Clark8032b982017-07-28 11:04:54 -04004730
4731##
4732
4733# ------------------------------------------------------------------------------
4734#Struct Lattice
Cary Clark08895c42018-02-01 09:37:32 -05004735#Line # divides Bitmap or Image into a rectangular grid ##
Cary Clark8032b982017-07-28 11:04:54 -04004736#Code
4737 struct Lattice {
Cary Clark2f466242017-12-11 16:03:17 -05004738 enum RectType ...
Cary Clark8032b982017-07-28 11:04:54 -04004739
Cary Clark2f466242017-12-11 16:03:17 -05004740 const int* fXDivs;
4741 const int* fYDivs;
4742 const RectType* fRectTypes;
4743 int fXCount;
4744 int fYCount;
4745 const SkIRect* fBounds;
4746 const SkColor* fColors;
Cary Clark8032b982017-07-28 11:04:54 -04004747 };
4748##
4749
Cary Clark154beea2017-10-26 07:58:48 -04004750 Lattice divides Bitmap or Image into a rectangular grid.
4751 Grid entries on even columns and even rows are fixed; these entries are
4752 always drawn at their original size if the destination is large enough.
4753 If the destination side is too small to hold the fixed entries, all fixed
4754 entries are proportionately scaled down to fit.
4755 The grid entries not on even columns and rows are scaled to fit the
4756 remaining space, if any.
4757
Cary Clark2f466242017-12-11 16:03:17 -05004758 #Enum RectType
Cary Clark8032b982017-07-28 11:04:54 -04004759 #Code
Cary Clark2f466242017-12-11 16:03:17 -05004760 enum RectType : uint8_t {
4761 kDefault = 0,
4762 kTransparent,
4763 kFixedColor,
Cary Clark8032b982017-07-28 11:04:54 -04004764 };
4765 ##
4766
Cary Clark2f466242017-12-11 16:03:17 -05004767 Optional setting per rectangular grid entry to make it transparent,
4768 or to fill the grid entry with a color.
Cary Clark8032b982017-07-28 11:04:54 -04004769
Cary Clark2f466242017-12-11 16:03:17 -05004770 #Const kDefault 0
4771 Draws Bitmap into lattice rectangle.
4772 ##
4773
4774 #Const kTransparent 1
4775 Skips lattice rectangle by making it transparent.
4776 ##
4777
4778 #Const kFixedColor 2
4779 Draws one of fColors into lattice rectangle.
Cary Clark8032b982017-07-28 11:04:54 -04004780 ##
4781 ##
4782
4783 #Member const int* fXDivs
4784 Array of x-coordinates that divide the bitmap vertically.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004785 Array entries must be unique, increasing, greater than or equal to
4786 fBounds left edge, and less than fBounds right edge.
4787 Set the first element to fBounds left to collapse the left column of
4788 fixed grid entries.
Cary Clark8032b982017-07-28 11:04:54 -04004789 ##
4790
4791 #Member const int* fYDivs
4792 Array of y-coordinates that divide the bitmap horizontally.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004793 Array entries must be unique, increasing, greater than or equal to
4794 fBounds top edge, and less than fBounds bottom edge.
4795 Set the first element to fBounds top to collapse the top row of fixed
4796 grid entries.
Cary Clark8032b982017-07-28 11:04:54 -04004797 ##
4798
Cary Clark2f466242017-12-11 16:03:17 -05004799 #Member const RectType* fRectTypes
4800 Optional array of fill types, one per rectangular grid entry:
Cary Clarkbad5ad72017-08-03 17:14:08 -04004801 array length must be
4802 #Formula
4803 (fXCount + 1) * (fYCount + 1)
4804 ##
4805 .
Cary Clark6fc50412017-09-21 12:31:06 -04004806
Cary Clark2f466242017-12-11 16:03:17 -05004807 Each RectType is one of: kDefault, kTransparent, kFixedColor.
4808
Cary Clark8032b982017-07-28 11:04:54 -04004809 Array entries correspond to the rectangular grid entries, ascending
4810 left to right and then top to bottom.
4811 ##
4812
4813 #Member int fXCount
Cary Clarkbad5ad72017-08-03 17:14:08 -04004814 Number of entries in fXDivs array; one less than the number of
4815 horizontal divisions.
Cary Clark8032b982017-07-28 11:04:54 -04004816 ##
4817
4818 #Member int fYCount
Cary Clarkbad5ad72017-08-03 17:14:08 -04004819 Number of entries in fYDivs array; one less than the number of vertical
4820 divisions.
Cary Clark8032b982017-07-28 11:04:54 -04004821 ##
4822
4823 #Member const SkIRect* fBounds
4824 Optional subset IRect source to draw from.
4825 If nullptr, source bounds is dimensions of Bitmap or Image.
4826 ##
4827
Cary Clark2f466242017-12-11 16:03:17 -05004828 #Member const SkColor* fColors
4829 Optional array of colors, one per rectangular grid entry.
4830 Array length must be
4831 #Formula
4832 (fXCount + 1) * (fYCount + 1)
4833 ##
4834 .
4835
4836 Array entries correspond to the rectangular grid entries, ascending
4837 left to right, then top to bottom.
4838 ##
4839
Cary Clark8032b982017-07-28 11:04:54 -04004840#Struct Lattice ##
4841
4842#Method void drawBitmapLattice(const SkBitmap& bitmap, const Lattice& lattice, const SkRect& dst,
4843 const SkPaint* paint = nullptr)
Cary Clarkab2621d2018-01-30 10:08:57 -05004844#In Draw_Image
Cary Clark78de7512018-02-07 07:27:09 -05004845#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05004846#Line # draws proportionally stretched Bitmap ##
Cary Clark8032b982017-07-28 11:04:54 -04004847
Cary Clarkd0530ba2017-09-14 11:25:39 -04004848Draw Bitmap bitmap stretched proportionally to fit into Rect dst.
Cary Clark8032b982017-07-28 11:04:54 -04004849
4850Lattice lattice divides bitmap into a rectangular grid.
4851Each intersection of an even-numbered row and column is fixed; like the corners
Cary Clarkbad5ad72017-08-03 17:14:08 -04004852of drawBitmapNine, fixed lattice elements never scale larger than their initial
Cary Clarkbc5697d2017-10-04 14:31:33 -04004853size and shrink proportionately when all fixed elements exceed the bitmap
Cary Clarkbad5ad72017-08-03 17:14:08 -04004854dimension. All other grid elements scale to fill the available space, if any.
Cary Clark8032b982017-07-28 11:04:54 -04004855
4856Additionally transform draw using Clip, Matrix, and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004857
Cary Clarkbad5ad72017-08-03 17:14:08 -04004858If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4859Blend_Mode, and Draw_Looper. If bitmap is kAlpha_8_SkColorType, apply Shader.
4860If paint contains Mask_Filter, generate mask from bitmap bounds.
4861
4862If generated mask extends beyond bitmap bounds, replicate bitmap edge colors,
4863just as Shader made from SkShader::MakeBitmapShader with
Cary Clarkbc5697d2017-10-04 14:31:33 -04004864SkShader::kClamp_TileMode set replicates the bitmap edge color when it samples
Cary Clarkbad5ad72017-08-03 17:14:08 -04004865outside of its bounds.
4866
4867#Param bitmap Bitmap containing pixels, dimensions, and format ##
4868#Param lattice division of bitmap into fixed and variable rectangles ##
4869#Param dst destination Rect of image to draw to ##
4870#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4871 and so on; or nullptr
4872##
Cary Clark8032b982017-07-28 11:04:54 -04004873
4874#Example
4875#Height 128
4876#Description
4877 The two leftmost bitmap draws has four corners and sides to the left and right of center.
4878 The leftmost bitmap draw scales the width of corners proportionately to fit.
Mike Klein9ff8c8c2018-02-07 01:58:51 +00004879 The third and fourth draw corners are not scaled; the sides are scaled to
Cary Clark8032b982017-07-28 11:04:54 -04004880 fill the remaining space; the center is transparent.
4881 The rightmost bitmap draw has four corners scaled vertically to fit, and uses sides above
4882 and below center to fill the remaining space.
4883##
Cary Clarkbad5ad72017-08-03 17:14:08 -04004884void draw(SkCanvas* canvas) {
4885 SkIRect center = { 20, 10, 50, 40 };
4886 SkBitmap bitmap;
4887 bitmap.allocPixels(SkImageInfo::MakeN32Premul(60, 60));
4888 SkCanvas bitCanvas(bitmap);
4889 SkPaint paint;
4890 SkColor gray = 0xFF000000;
4891 int left = 0;
4892 for (auto right: { center.fLeft, center.fRight, bitmap.width() } ) {
4893 int top = 0;
4894 for (auto bottom: { center.fTop, center.fBottom, bitmap.height() } ) {
4895 paint.setColor(gray);
4896 bitCanvas.drawIRect(SkIRect::MakeLTRB(left, top, right, bottom), paint);
4897 gray += 0x001f1f1f;
4898 top = bottom;
4899 }
Mike Klein9ff8c8c2018-02-07 01:58:51 +00004900 left = right;
Cary Clarkbad5ad72017-08-03 17:14:08 -04004901 }
4902 const int xDivs[] = { center.fLeft, center.fRight };
4903 const int yDivs[] = { center.fTop, center.fBottom };
Cary Clarkca3ebcd2017-12-12 11:22:38 -05004904 SkCanvas::Lattice::RectType fillTypes[3][3];
4905 memset(fillTypes, 0, sizeof(fillTypes));
4906 fillTypes[1][1] = SkCanvas::Lattice::kTransparent;
4907 SkColor dummy[9]; // temporary pending bug fix
4908 SkCanvas::Lattice lattice = { xDivs, yDivs, fillTypes[0], SK_ARRAY_COUNT(xDivs),
4909 SK_ARRAY_COUNT(yDivs), nullptr, dummy };
Cary Clarkbad5ad72017-08-03 17:14:08 -04004910 for (auto dest: { 20, 30, 40, 60, 90 } ) {
Cary Clarkca3ebcd2017-12-12 11:22:38 -05004911 canvas->drawBitmapLattice(bitmap, lattice, SkRect::MakeWH(dest, 110 - dest), nullptr);
Cary Clarkbad5ad72017-08-03 17:14:08 -04004912 canvas->translate(dest + 4, 0);
4913 }
Cary Clark8032b982017-07-28 11:04:54 -04004914}
4915##
4916
Cary Clark2ade9972017-11-02 17:49:34 -04004917#SeeAlso drawImageLattice drawBitmap drawBitmapNine Lattice
Cary Clark8032b982017-07-28 11:04:54 -04004918
4919##
4920
4921# ------------------------------------------------------------------------------
4922
4923#Method void drawImageLattice(const SkImage* image, const Lattice& lattice, const SkRect& dst,
4924 const SkPaint* paint = nullptr)
Cary Clarkab2621d2018-01-30 10:08:57 -05004925#In Draw_Image
Cary Clark78de7512018-02-07 07:27:09 -05004926#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05004927#Line # draws proportionally stretched Image ##
Cary Clark8032b982017-07-28 11:04:54 -04004928
Cary Clarkd0530ba2017-09-14 11:25:39 -04004929Draw Image image stretched proportionally to fit into Rect dst.
Cary Clark8032b982017-07-28 11:04:54 -04004930
4931Lattice lattice divides image into a rectangular grid.
4932Each intersection of an even-numbered row and column is fixed; like the corners
Cary Clarkbad5ad72017-08-03 17:14:08 -04004933of drawBitmapNine, fixed lattice elements never scale larger than their initial
Cary Clarkbc5697d2017-10-04 14:31:33 -04004934size and shrink proportionately when all fixed elements exceed the bitmap
Cary Clarkbad5ad72017-08-03 17:14:08 -04004935dimension. All other grid elements scale to fill the available space, if any.
Cary Clark8032b982017-07-28 11:04:54 -04004936
4937Additionally transform draw using Clip, Matrix, and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004938
Cary Clarkbad5ad72017-08-03 17:14:08 -04004939If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4940Blend_Mode, and Draw_Looper. If bitmap is kAlpha_8_SkColorType, apply Shader.
4941If paint contains Mask_Filter, generate mask from bitmap bounds.
4942
4943If generated mask extends beyond bitmap bounds, replicate bitmap edge colors,
4944just as Shader made from SkShader::MakeBitmapShader with
Cary Clarkbc5697d2017-10-04 14:31:33 -04004945SkShader::kClamp_TileMode set replicates the bitmap edge color when it samples
Cary Clarkbad5ad72017-08-03 17:14:08 -04004946outside of its bounds.
4947
4948#Param image Image containing pixels, dimensions, and format ##
4949#Param lattice division of bitmap into fixed and variable rectangles ##
4950#Param dst destination Rect of image to draw to ##
4951#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4952 and so on; or nullptr
4953##
Cary Clark8032b982017-07-28 11:04:54 -04004954
4955#Example
4956#Height 128
4957#Description
4958 The leftmost image is smaller than center; only corners are drawn, all scaled to fit.
Cary Clarkce101242017-09-01 15:51:02 -04004959 The second image equals the size of center; only corners are drawn without scaling.
4960 The remaining images are larger than center. All corners draw without scaling. The sides
Cary Clark8032b982017-07-28 11:04:54 -04004961 are scaled if needed to take up the remaining space; the center is transparent.
4962##
Cary Clarkbad5ad72017-08-03 17:14:08 -04004963void draw(SkCanvas* canvas) {
4964 SkIRect center = { 20, 10, 50, 40 };
4965 SkBitmap bitmap;
4966 bitmap.allocPixels(SkImageInfo::MakeN32Premul(60, 60));
4967 SkCanvas bitCanvas(bitmap);
4968 SkPaint paint;
4969 SkColor gray = 0xFF000000;
4970 int left = 0;
4971 for (auto right: { center.fLeft, center.fRight, bitmap.width() } ) {
4972 int top = 0;
4973 for (auto bottom: { center.fTop, center.fBottom, bitmap.height() } ) {
4974 paint.setColor(gray);
4975 bitCanvas.drawIRect(SkIRect::MakeLTRB(left, top, right, bottom), paint);
4976 gray += 0x001f1f1f;
4977 top = bottom;
4978 }
Mike Klein9ff8c8c2018-02-07 01:58:51 +00004979 left = right;
Cary Clarkbad5ad72017-08-03 17:14:08 -04004980 }
4981 const int xDivs[] = { center.fLeft, center.fRight };
4982 const int yDivs[] = { center.fTop, center.fBottom };
Cary Clarkca3ebcd2017-12-12 11:22:38 -05004983 SkCanvas::Lattice::RectType fillTypes[3][3];
Mike Klein9ff8c8c2018-02-07 01:58:51 +00004984 memset(fillTypes, 0, sizeof(fillTypes));
Cary Clarkca3ebcd2017-12-12 11:22:38 -05004985 fillTypes[1][1] = SkCanvas::Lattice::kTransparent;
4986 SkColor dummy[9]; // temporary pending bug fix
4987 SkCanvas::Lattice lattice = { xDivs, yDivs, fillTypes[0], SK_ARRAY_COUNT(xDivs),
4988 SK_ARRAY_COUNT(yDivs), nullptr, dummy };
Cary Clarkbad5ad72017-08-03 17:14:08 -04004989 sk_sp<SkImage> image = SkImage::MakeFromBitmap(bitmap);
4990 SkImage* imagePtr = image.get();
4991 for (auto dest: { 20, 30, 40, 60, 90 } ) {
4992 canvas->drawImageNine(imagePtr, center, SkRect::MakeWH(dest, dest), nullptr);
4993 canvas->translate(dest + 4, 0);
4994 }
Cary Clark8032b982017-07-28 11:04:54 -04004995}
4996##
4997
Cary Clark2ade9972017-11-02 17:49:34 -04004998#SeeAlso drawBitmapLattice drawImage drawImageNine Lattice
Cary Clark8032b982017-07-28 11:04:54 -04004999
5000##
5001
Cary Clark08895c42018-02-01 09:37:32 -05005002#Subtopic Draw_Image ##
Cary Clark8032b982017-07-28 11:04:54 -04005003
5004# ------------------------------------------------------------------------------
Cary Clark78de7512018-02-07 07:27:09 -05005005#Subtopic Draw_Text
5006#Populate
5007#Line # draws text into Canvas ##
5008##
Cary Clark8032b982017-07-28 11:04:54 -04005009
5010#Method void drawText(const void* text, size_t byteLength, SkScalar x, SkScalar y,
5011 const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05005012#In Draw_Text
5013#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05005014#Line # draws text at (x, y), using font advance ##
Cary Clark8032b982017-07-28 11:04:54 -04005015
5016Draw text, with origin at (x, y), using Clip, Matrix, and Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04005017
Cary Clarkbc5697d2017-10-04 14:31:33 -04005018text meaning depends on Paint_Text_Encoding; by default, text is encoded as
Cary Clarkbad5ad72017-08-03 17:14:08 -04005019UTF-8.
Cary Clark8032b982017-07-28 11:04:54 -04005020
Cary Clarkbad5ad72017-08-03 17:14:08 -04005021x and y meaning depends on Paint_Text_Align and Paint_Vertical_Text; by default
Cary Clarkbc5697d2017-10-04 14:31:33 -04005022text draws left to right, positioning the first glyph left side bearing at x
Mike Klein9ff8c8c2018-02-07 01:58:51 +00005023and its baseline at y. Text size is affected by Matrix and Paint_Text_Size.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005024
Mike Reed8ad91a92018-01-19 19:09:32 -05005025All elements of paint: Path_Effect, Mask_Filter, Shader,
Cary Clarkbad5ad72017-08-03 17:14:08 -04005026Color_Filter, Image_Filter, and Draw_Looper; apply to text. By default, draws
Cary Clarkce101242017-09-01 15:51:02 -04005027filled 12 point black Glyphs.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005028
Cary Clarkce101242017-09-01 15:51:02 -04005029#Param text character code points or Glyphs drawn ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005030#Param byteLength byte length of text array ##
5031#Param x start of text on x-axis ##
5032#Param y start of text on y-axis ##
5033#Param paint text size, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005034
5035#Example
5036#Height 200
5037#Description
5038 The same text is drawn varying Paint_Text_Size and varying
Mike Klein9ff8c8c2018-02-07 01:58:51 +00005039 Matrix.
Cary Clark8032b982017-07-28 11:04:54 -04005040##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005041void draw(SkCanvas* canvas) {
5042 SkPaint paint;
5043 paint.setAntiAlias(true);
5044 float textSizes[] = { 12, 18, 24, 36 };
5045 for (auto size: textSizes ) {
5046 paint.setTextSize(size);
5047 canvas->drawText("Aa", 2, 10, 20, paint);
5048 canvas->translate(0, size * 2);
5049 }
5050 paint.reset();
5051 paint.setAntiAlias(true);
5052 float yPos = 20;
5053 for (auto size: textSizes ) {
5054 float scale = size / 12.f;
5055 canvas->resetMatrix();
5056 canvas->translate(100, 0);
5057 canvas->scale(scale, scale);
5058 canvas->drawText("Aa", 2, 10 / scale, yPos / scale, paint);
Mike Klein9ff8c8c2018-02-07 01:58:51 +00005059 yPos += size * 2;
Cary Clarkbad5ad72017-08-03 17:14:08 -04005060 }
5061}
Cary Clark8032b982017-07-28 11:04:54 -04005062##
5063
Cary Clark2ade9972017-11-02 17:49:34 -04005064#SeeAlso drawString drawPosText drawPosTextH drawTextBlob drawTextOnPath drawTextRSXform
Cary Clark8032b982017-07-28 11:04:54 -04005065
5066##
5067
5068#Method void drawString(const char* string, SkScalar x, SkScalar y, const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05005069#In Draw_Text
5070#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05005071#Line # draws null terminated string at (x, y) using font advance ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005072Draw null terminated string, with origin at (x, y), using Clip, Matrix, and
5073Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04005074
Cary Clarkbc5697d2017-10-04 14:31:33 -04005075string meaning depends on Paint_Text_Encoding; by default, strings are encoded
5076as UTF-8. Other values of Paint_Text_Encoding are unlikely to produce the desired
Cary Clarkbad5ad72017-08-03 17:14:08 -04005077results, since zero bytes may be embedded in the string.
Cary Clark8032b982017-07-28 11:04:54 -04005078
Cary Clarkbad5ad72017-08-03 17:14:08 -04005079x and y meaning depends on Paint_Text_Align and Paint_Vertical_Text; by default
Cary Clarkbc5697d2017-10-04 14:31:33 -04005080string draws left to right, positioning the first glyph left side bearing at x
Mike Klein9ff8c8c2018-02-07 01:58:51 +00005081and its baseline at y. Text size is affected by Matrix and Paint_Text_Size.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005082
Mike Reed8ad91a92018-01-19 19:09:32 -05005083All elements of paint: Path_Effect, Mask_Filter, Shader,
Cary Clarkbad5ad72017-08-03 17:14:08 -04005084Color_Filter, Image_Filter, and Draw_Looper; apply to text. By default, draws
Cary Clarkce101242017-09-01 15:51:02 -04005085filled 12 point black Glyphs.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005086
Cary Clarkce101242017-09-01 15:51:02 -04005087#Param string character code points or Glyphs drawn,
Cary Clarkbad5ad72017-08-03 17:14:08 -04005088 ending with a char value of zero
5089##
5090#Param x start of string on x-axis ##
5091#Param y start of string on y-axis ##
5092#Param paint text size, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005093
5094#Example
5095 SkPaint paint;
5096 canvas->drawString("a small hello", 20, 20, paint);
5097##
5098
Cary Clark2ade9972017-11-02 17:49:34 -04005099#SeeAlso drawText drawPosText drawPosTextH drawTextBlob drawTextOnPath drawTextRSXform
Cary Clark8032b982017-07-28 11:04:54 -04005100
5101##
5102
5103#Method void drawString(const SkString& string, SkScalar x, SkScalar y, const SkPaint& paint)
5104
Cary Clarkbad5ad72017-08-03 17:14:08 -04005105Draw null terminated string, with origin at (x, y), using Clip, Matrix, and
5106Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04005107
Cary Clarkbc5697d2017-10-04 14:31:33 -04005108string meaning depends on Paint_Text_Encoding; by default, strings are encoded
5109as UTF-8. Other values of Paint_Text_Encoding are unlikely to produce the desired
Cary Clarkbad5ad72017-08-03 17:14:08 -04005110results, since zero bytes may be embedded in the string.
Cary Clark8032b982017-07-28 11:04:54 -04005111
Cary Clarkbad5ad72017-08-03 17:14:08 -04005112x and y meaning depends on Paint_Text_Align and Paint_Vertical_Text; by default
Cary Clarkbc5697d2017-10-04 14:31:33 -04005113string draws left to right, positioning the first glyph left side bearing at x
Mike Klein9ff8c8c2018-02-07 01:58:51 +00005114and its baseline at y. Text size is affected by Matrix and Paint_Text_Size.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005115
Mike Reed8ad91a92018-01-19 19:09:32 -05005116All elements of paint: Path_Effect, Mask_Filter, Shader,
Cary Clarkbad5ad72017-08-03 17:14:08 -04005117Color_Filter, Image_Filter, and Draw_Looper; apply to text. By default, draws
Cary Clarkce101242017-09-01 15:51:02 -04005118filled 12 point black Glyphs.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005119
Cary Clarkce101242017-09-01 15:51:02 -04005120#Param string character code points or Glyphs drawn,
Cary Clarkbad5ad72017-08-03 17:14:08 -04005121 ending with a char value of zero
5122##
5123#Param x start of string on x-axis ##
5124#Param y start of string on y-axis ##
5125#Param paint text size, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005126
5127#Example
5128 SkPaint paint;
5129 SkString string("a small hello");
5130 canvas->drawString(string, 20, 20, paint);
5131##
5132
Cary Clark2ade9972017-11-02 17:49:34 -04005133#SeeAlso drawText drawPosText drawPosTextH drawTextBlob drawTextOnPath drawTextRSXform
Cary Clark8032b982017-07-28 11:04:54 -04005134
5135##
5136
5137# ------------------------------------------------------------------------------
5138
5139#Method void drawPosText(const void* text, size_t byteLength, const SkPoint pos[],
5140 const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05005141#In Draw_Text
5142#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05005143#Line # draws text at array of (x, y) positions ##
Cary Clark8032b982017-07-28 11:04:54 -04005144
Cary Clarkbad5ad72017-08-03 17:14:08 -04005145Draw each glyph in text with the origin in pos array, using Clip, Matrix, and
Cary Clarkce101242017-09-01 15:51:02 -04005146Paint paint. The number of entries in pos array must match the number of Glyphs
Cary Clarkbad5ad72017-08-03 17:14:08 -04005147described by byteLength of text.
Cary Clark8032b982017-07-28 11:04:54 -04005148
Cary Clarkbc5697d2017-10-04 14:31:33 -04005149text meaning depends on Paint_Text_Encoding; by default, text is encoded as
Cary Clarkbad5ad72017-08-03 17:14:08 -04005150UTF-8. pos elements' meaning depends on Paint_Text_Align and Paint_Vertical_Text;
Cary Clarkbc5697d2017-10-04 14:31:33 -04005151by default each glyph left side bearing is positioned at x and its
Cary Clarkbad5ad72017-08-03 17:14:08 -04005152baseline is positioned at y. Text size is affected by Matrix and
Mike Klein9ff8c8c2018-02-07 01:58:51 +00005153Paint_Text_Size.
Cary Clark8032b982017-07-28 11:04:54 -04005154
Mike Reed8ad91a92018-01-19 19:09:32 -05005155All elements of paint: Path_Effect, Mask_Filter, Shader,
Cary Clarkbad5ad72017-08-03 17:14:08 -04005156Color_Filter, Image_Filter, and Draw_Looper; apply to text. By default, draws
Cary Clarkce101242017-09-01 15:51:02 -04005157filled 12 point black Glyphs.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005158
5159Layout engines such as Harfbuzz typically position each glyph
Cary Clarkbc5697d2017-10-04 14:31:33 -04005160rather than using the font advance widths.
Cary Clark8032b982017-07-28 11:04:54 -04005161
Cary Clarkce101242017-09-01 15:51:02 -04005162#Param text character code points or Glyphs drawn ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005163#Param byteLength byte length of text array ##
5164#Param pos array of glyph origins ##
5165#Param paint text size, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005166
5167#Example
5168#Height 120
Cary Clarkbad5ad72017-08-03 17:14:08 -04005169void draw(SkCanvas* canvas) {
5170 const char hello[] = "HeLLo!";
5171 const SkPoint pos[] = { {40, 100}, {82, 95}, {115, 110}, {130, 95}, {145, 85},
5172 {172, 100} };
5173 SkPaint paint;
5174 paint.setTextSize(60);
5175 canvas->drawPosText(hello, strlen(hello), pos, paint);
Cary Clark8032b982017-07-28 11:04:54 -04005176}
5177##
5178
Cary Clark2ade9972017-11-02 17:49:34 -04005179#SeeAlso drawText drawPosTextH drawTextBlob drawTextOnPath drawTextRSXform
Cary Clark8032b982017-07-28 11:04:54 -04005180
5181##
5182
5183# ------------------------------------------------------------------------------
5184
5185#Method void drawPosTextH(const void* text, size_t byteLength, const SkScalar xpos[], SkScalar constY,
5186 const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05005187#In Draw_Text
5188#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05005189#Line # draws text at x positions with common baseline ##
Cary Clark8032b982017-07-28 11:04:54 -04005190
Cary Clarkbad5ad72017-08-03 17:14:08 -04005191Draw each glyph in text with its (x, y) origin composed from xpos array and
5192constY, using Clip, Matrix, and Paint paint. The number of entries in xpos array
Cary Clarkce101242017-09-01 15:51:02 -04005193must match the number of Glyphs described by byteLength of text.
Cary Clark8032b982017-07-28 11:04:54 -04005194
Cary Clarkbc5697d2017-10-04 14:31:33 -04005195text meaning depends on Paint_Text_Encoding; by default, text is encoded as
Cary Clarkce101242017-09-01 15:51:02 -04005196UTF-8. xpos elements' meaning depends on Paint_Text_Align and Paint_Vertical_Text;
Cary Clarkbc5697d2017-10-04 14:31:33 -04005197by default each glyph left side bearing is positioned at an xpos element and
Cary Clarkbad5ad72017-08-03 17:14:08 -04005198its baseline is positioned at constY. Text size is affected by Matrix and
Mike Klein9ff8c8c2018-02-07 01:58:51 +00005199Paint_Text_Size.
Cary Clark8032b982017-07-28 11:04:54 -04005200
Mike Reed8ad91a92018-01-19 19:09:32 -05005201All elements of paint: Path_Effect, Mask_Filter, Shader,
Cary Clarkbad5ad72017-08-03 17:14:08 -04005202Color_Filter, Image_Filter, and Draw_Looper; apply to text. By default, draws
Cary Clarkce101242017-09-01 15:51:02 -04005203filled 12 point black Glyphs.
Cary Clark8032b982017-07-28 11:04:54 -04005204
Cary Clarkbad5ad72017-08-03 17:14:08 -04005205Layout engines such as Harfbuzz typically position each glyph
Cary Clarkbc5697d2017-10-04 14:31:33 -04005206rather than using the font advance widths if all Glyphs share the same
Cary Clarkbad5ad72017-08-03 17:14:08 -04005207baseline.
5208
Cary Clarkce101242017-09-01 15:51:02 -04005209#Param text character code points or Glyphs drawn ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005210#Param byteLength byte length of text array ##
5211#Param xpos array of x positions, used to position each glyph ##
5212#Param constY shared y coordinate for all of x positions ##
5213#Param paint text size, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005214
5215#Example
5216#Height 40
Cary Clarkbad5ad72017-08-03 17:14:08 -04005217 void draw(SkCanvas* canvas) {
5218 SkScalar xpos[] = { 20, 40, 80, 160 };
5219 SkPaint paint;
5220 canvas->drawPosTextH("XXXX", 4, xpos, 20, paint);
5221 }
Cary Clark8032b982017-07-28 11:04:54 -04005222##
5223
Cary Clark2ade9972017-11-02 17:49:34 -04005224#SeeAlso drawText drawPosText drawTextBlob drawTextOnPath drawTextRSXform
Cary Clark8032b982017-07-28 11:04:54 -04005225
5226##
5227
5228# ------------------------------------------------------------------------------
5229
5230#Method void drawTextOnPathHV(const void* text, size_t byteLength, const SkPath& path, SkScalar hOffset,
5231 SkScalar vOffset, const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05005232#In Draw_Text
5233#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05005234#Line # draws text following Path with offsets ##
Cary Clark8032b982017-07-28 11:04:54 -04005235
5236Draw text on Path path, using Clip, Matrix, and Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04005237
Cary Clarkbad5ad72017-08-03 17:14:08 -04005238Origin of text is at distance hOffset along the path, offset by a perpendicular
5239vector of length vOffset. If the path section corresponding the glyph advance is
5240curved, the glyph is drawn curved to match; control points in the glyph are
Cary Clarkbc5697d2017-10-04 14:31:33 -04005241mapped to projected points parallel to the path. If the text advance is larger
Cary Clarkbad5ad72017-08-03 17:14:08 -04005242than the path length, the excess text is clipped.
5243
Cary Clarkbc5697d2017-10-04 14:31:33 -04005244text meaning depends on Paint_Text_Encoding; by default, text is encoded as
Cary Clarkbad5ad72017-08-03 17:14:08 -04005245UTF-8. Origin meaning depends on Paint_Text_Align and Paint_Vertical_Text; by
Cary Clarkbc5697d2017-10-04 14:31:33 -04005246default text positions the first glyph left side bearing at origin x and its
Mike Klein9ff8c8c2018-02-07 01:58:51 +00005247baseline at origin y. Text size is affected by Matrix and Paint_Text_Size.
Cary Clark8032b982017-07-28 11:04:54 -04005248
Mike Reed8ad91a92018-01-19 19:09:32 -05005249All elements of paint: Path_Effect, Mask_Filter, Shader,
Cary Clarkbad5ad72017-08-03 17:14:08 -04005250Color_Filter, Image_Filter, and Draw_Looper; apply to text. By default, draws
Cary Clarkce101242017-09-01 15:51:02 -04005251filled 12 point black Glyphs.
Cary Clark8032b982017-07-28 11:04:54 -04005252
Cary Clarkce101242017-09-01 15:51:02 -04005253#Param text character code points or Glyphs drawn ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005254#Param byteLength byte length of text array ##
5255#Param path Path providing text baseline ##
5256#Param hOffset distance along path to offset origin ##
5257#Param vOffset offset of text above (if negative) or below (if positive) the path ##
5258#Param paint text size, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005259
5260#Example
Mike Klein9ff8c8c2018-02-07 01:58:51 +00005261 void draw(SkCanvas* canvas) {
Cary Clarkbad5ad72017-08-03 17:14:08 -04005262 const char aero[] = "correo a" "\xC3" "\xA9" "reo";
5263 const size_t len = sizeof(aero) - 1;
5264 SkPath path;
5265 path.addOval({43-26, 43-26, 43+26, 43+26}, SkPath::kCW_Direction, 3);
5266 SkPaint paint;
5267 paint.setTextSize(24);
5268 for (auto offset : { 0, 10, 20 } ) {
5269 canvas->drawTextOnPathHV(aero, len, path, 0, -offset, paint);
5270 canvas->translate(70 + offset, 70 + offset);
5271 }
5272 }
Cary Clark8032b982017-07-28 11:04:54 -04005273##
5274
Cary Clark2ade9972017-11-02 17:49:34 -04005275#SeeAlso drawTextOnPath drawText drawPosTextH drawTextBlob drawTextRSXform
Cary Clark8032b982017-07-28 11:04:54 -04005276
5277##
5278
5279# ------------------------------------------------------------------------------
5280
5281#Method void drawTextOnPath(const void* text, size_t byteLength, const SkPath& path,
5282 const SkMatrix* matrix, const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05005283#In Draw_Text
5284#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05005285#Line # draws text following Path contour ##
Cary Clark8032b982017-07-28 11:04:54 -04005286
5287Draw text on Path path, using Clip, Matrix, and Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04005288
Cary Clarkbad5ad72017-08-03 17:14:08 -04005289Origin of text is at beginning of path offset by matrix, if provided, before it
5290is mapped to path. If the path section corresponding the glyph advance is
5291curved, the glyph is drawn curved to match; control points in the glyph are
Cary Clarkbc5697d2017-10-04 14:31:33 -04005292mapped to projected points parallel to the path. If the text advance is larger
Cary Clarkbad5ad72017-08-03 17:14:08 -04005293than the path length, the excess text is clipped.
5294
Cary Clarkbc5697d2017-10-04 14:31:33 -04005295text meaning depends on Paint_Text_Encoding; by default, text is encoded as
Cary Clarkbad5ad72017-08-03 17:14:08 -04005296UTF-8. Origin meaning depends on Paint_Text_Align and Paint_Vertical_Text; by
Cary Clarkbc5697d2017-10-04 14:31:33 -04005297default text positions the first glyph left side bearing at origin x and its
Mike Klein9ff8c8c2018-02-07 01:58:51 +00005298baseline at origin y. Text size is affected by Matrix and Paint_Text_Size.
Cary Clark8032b982017-07-28 11:04:54 -04005299
Mike Reed8ad91a92018-01-19 19:09:32 -05005300All elements of paint: Path_Effect, Mask_Filter, Shader,
Cary Clarkbad5ad72017-08-03 17:14:08 -04005301Color_Filter, Image_Filter, and Draw_Looper; apply to text. By default, draws
Cary Clarkce101242017-09-01 15:51:02 -04005302filled 12 point black Glyphs.
Cary Clark8032b982017-07-28 11:04:54 -04005303
Cary Clarkce101242017-09-01 15:51:02 -04005304#Param text character code points or Glyphs drawn ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005305#Param byteLength byte length of text array ##
5306#Param path Path providing text baseline ##
Cary Clarkce101242017-09-01 15:51:02 -04005307#Param matrix transform of Glyphs before mapping to path; may be nullptr
Cary Clarka523d2d2017-08-30 08:58:10 -04005308 to use identity Matrix
Cary Clarkbad5ad72017-08-03 17:14:08 -04005309##
5310#Param paint text size, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005311
5312#Example
Mike Klein9ff8c8c2018-02-07 01:58:51 +00005313 void draw(SkCanvas* canvas) {
Cary Clarkbad5ad72017-08-03 17:14:08 -04005314 const char roller[] = "rollercoaster";
5315 const size_t len = sizeof(roller) - 1;
5316 SkPath path;
5317 path.cubicTo(40, -80, 120, 80, 160, -40);
5318 SkPaint paint;
5319 paint.setTextSize(32);
5320 paint.setStyle(SkPaint::kStroke_Style);
5321 SkMatrix matrix;
5322 matrix.setIdentity();
5323 for (int i = 0; i < 3; ++i) {
5324 canvas->translate(25, 60);
5325 canvas->drawPath(path, paint);
5326 canvas->drawTextOnPath(roller, len, path, &matrix, paint);
5327 matrix.preTranslate(0, 10);
5328 }
5329 }
Cary Clark8032b982017-07-28 11:04:54 -04005330##
5331
Cary Clark2ade9972017-11-02 17:49:34 -04005332#SeeAlso drawTextOnPathHV drawText drawPosTextH drawTextBlob drawTextRSXform
Cary Clark8032b982017-07-28 11:04:54 -04005333
5334##
5335
5336# ------------------------------------------------------------------------------
5337
5338#Method void drawTextRSXform(const void* text, size_t byteLength, const SkRSXform xform[],
5339 const SkRect* cullRect, const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05005340#In Draw_Text
5341#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05005342#Line # draws text with array of RSXform ##
Cary Clark8032b982017-07-28 11:04:54 -04005343
5344Draw text, transforming each glyph by the corresponding SkRSXform,
5345using Clip, Matrix, and Paint paint.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005346
Mike Klein9ff8c8c2018-02-07 01:58:51 +00005347RSXform array specifies a separate square scale, rotation, and translation for
Cary Clark8032b982017-07-28 11:04:54 -04005348each glyph.
Cary Clark8032b982017-07-28 11:04:54 -04005349
Cary Clarkbad5ad72017-08-03 17:14:08 -04005350Optional Rect cullRect is a conservative bounds of text, taking into account
Cary Clarkce101242017-09-01 15:51:02 -04005351RSXform and paint. If cullRect is outside of Clip, canvas can skip drawing.
Cary Clark8032b982017-07-28 11:04:54 -04005352
Mike Reed8ad91a92018-01-19 19:09:32 -05005353All elements of paint: Path_Effect, Mask_Filter, Shader,
Cary Clarkbad5ad72017-08-03 17:14:08 -04005354Color_Filter, Image_Filter, and Draw_Looper; apply to text. By default, draws
Cary Clarkce101242017-09-01 15:51:02 -04005355filled 12 point black Glyphs.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005356
Cary Clarkce101242017-09-01 15:51:02 -04005357#Param text character code points or Glyphs drawn ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005358#Param byteLength byte length of text array ##
5359#Param xform RSXform rotates, scales, and translates each glyph individually ##
5360#Param cullRect Rect bounds of text for efficient clipping; or nullptr ##
5361#Param paint text size, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005362
5363#Example
Mike Klein9ff8c8c2018-02-07 01:58:51 +00005364void draw(SkCanvas* canvas) {
Cary Clarkbad5ad72017-08-03 17:14:08 -04005365 const int iterations = 26;
5366 SkRSXform transforms[iterations];
5367 char alphabet[iterations];
5368 SkScalar angle = 0;
5369 SkScalar scale = 1;
5370 for (size_t i = 0; i < SK_ARRAY_COUNT(transforms); ++i) {
5371 const SkScalar s = SkScalarSin(angle) * scale;
5372 const SkScalar c = SkScalarCos(angle) * scale;
5373 transforms[i] = SkRSXform::Make(-c, -s, -s * 16, c * 16);
5374 angle += .45;
5375 scale += .2;
5376 alphabet[i] = 'A' + i;
5377 }
5378 SkPaint paint;
5379 paint.setTextAlign(SkPaint::kCenter_Align);
5380 canvas->translate(110, 138);
5381 canvas->drawTextRSXform(alphabet, sizeof(alphabet), transforms, nullptr, paint);
Cary Clark8032b982017-07-28 11:04:54 -04005382}
5383##
5384
Cary Clark2ade9972017-11-02 17:49:34 -04005385#SeeAlso drawTextOnPath drawTextOnPathHV drawText drawPosText drawTextBlob
Cary Clark8032b982017-07-28 11:04:54 -04005386
5387##
5388
5389# ------------------------------------------------------------------------------
5390
5391#Method void drawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y, const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05005392#In Draw_Text
5393#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05005394#Line # draws text with arrays of positions and Paint ##
Cary Clark8032b982017-07-28 11:04:54 -04005395Draw Text_Blob blob at (x, y), using Clip, Matrix, and Paint paint.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005396
Cary Clarkce101242017-09-01 15:51:02 -04005397blob contains Glyphs, their positions, and paint attributes specific to text:
Cary Clarkbad5ad72017-08-03 17:14:08 -04005398Typeface, Paint_Text_Size, Paint_Text_Scale_X, Paint_Text_Skew_X,
5399Paint_Text_Align, Paint_Hinting, Anti-alias, Paint_Fake_Bold,
5400Font_Embedded_Bitmaps, Full_Hinting_Spacing, LCD_Text, Linear_Text,
5401Subpixel_Text, and Paint_Vertical_Text.
Cary Clark8032b982017-07-28 11:04:54 -04005402
Cary Clark3cd22cc2017-12-01 11:49:58 -05005403Paint_Text_Encoding must be set to SkPaint::kGlyphID_TextEncoding.
5404
Mike Reed8ad91a92018-01-19 19:09:32 -05005405Elements of paint: Path_Effect, Mask_Filter, Shader, Color_Filter,
Cary Clark8032b982017-07-28 11:04:54 -04005406Image_Filter, and Draw_Looper; apply to blob.
5407
Cary Clarkce101242017-09-01 15:51:02 -04005408#Param blob Glyphs, positions, and their paints' text size, typeface, and so on ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005409#Param x horizontal offset applied to blob ##
5410#Param y vertical offset applied to blob ##
5411#Param paint blend, color, stroking, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005412
5413#Example
5414#Height 120
Cary Clarkbad5ad72017-08-03 17:14:08 -04005415 void draw(SkCanvas* canvas) {
Cary Clark2f466242017-12-11 16:03:17 -05005416 SkTextBlobBuilder textBlobBuilder;
5417 const char bunny[] = "/(^x^)\\";
5418 const int len = sizeof(bunny) - 1;
5419 uint16_t glyphs[len];
5420 SkPaint paint;
5421 paint.textToGlyphs(bunny, len, glyphs);
Cary Clark3cd22cc2017-12-01 11:49:58 -05005422 paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
Cary Clark2f466242017-12-11 16:03:17 -05005423 int runs[] = { 3, 1, 3 };
5424 SkPoint textPos = { 20, 100 };
5425 int glyphIndex = 0;
5426 for (auto runLen : runs) {
5427 paint.setTextSize(1 == runLen ? 20 : 50);
Mike Klein9ff8c8c2018-02-07 01:58:51 +00005428 const SkTextBlobBuilder::RunBuffer& run =
Cary Clark2f466242017-12-11 16:03:17 -05005429 textBlobBuilder.allocRun(paint, runLen, textPos.fX, textPos.fY);
5430 memcpy(run.glyphs, &glyphs[glyphIndex], sizeof(glyphs[0]) * runLen);
5431 textPos.fX += paint.measureText(&glyphs[glyphIndex], sizeof(glyphs[0]) * runLen, nullptr);
5432 glyphIndex += runLen;
5433 }
5434 sk_sp<const SkTextBlob> blob = textBlobBuilder.make();
5435 paint.reset();
Cary Clarkbad5ad72017-08-03 17:14:08 -04005436 canvas->drawTextBlob(blob.get(), 0, 0, paint);
Cary Clark8032b982017-07-28 11:04:54 -04005437 }
5438##
5439
Cary Clark2ade9972017-11-02 17:49:34 -04005440#SeeAlso drawText drawPosText drawPosTextH
Cary Clark8032b982017-07-28 11:04:54 -04005441
5442##
5443
5444# ------------------------------------------------------------------------------
5445
Mike Klein9ff8c8c2018-02-07 01:58:51 +00005446#Method void drawTextBlob(const sk_sp<SkTextBlob>& blob, SkScalar x, SkScalar y, const SkPaint& paint)
Cary Clark8032b982017-07-28 11:04:54 -04005447
5448Draw Text_Blob blob at (x, y), using Clip, Matrix, and Paint paint.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005449
Cary Clarkce101242017-09-01 15:51:02 -04005450blob contains Glyphs, their positions, and paint attributes specific to text:
Cary Clarkbad5ad72017-08-03 17:14:08 -04005451Typeface, Paint_Text_Size, Paint_Text_Scale_X, Paint_Text_Skew_X,
5452Paint_Text_Align, Paint_Hinting, Anti-alias, Paint_Fake_Bold,
5453Font_Embedded_Bitmaps, Full_Hinting_Spacing, LCD_Text, Linear_Text,
5454Subpixel_Text, and Paint_Vertical_Text.
Cary Clark8032b982017-07-28 11:04:54 -04005455
Cary Clark3cd22cc2017-12-01 11:49:58 -05005456Paint_Text_Encoding must be set to SkPaint::kGlyphID_TextEncoding.
5457
Mike Klein9ff8c8c2018-02-07 01:58:51 +00005458Elements of paint: Path_Effect, Mask_Filter, Shader, Color_Filter,
Cary Clark8032b982017-07-28 11:04:54 -04005459Image_Filter, and Draw_Looper; apply to blob.
5460
Cary Clarkce101242017-09-01 15:51:02 -04005461#Param blob Glyphs, positions, and their paints' text size, typeface, and so on ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005462#Param x horizontal offset applied to blob ##
5463#Param y vertical offset applied to blob ##
5464#Param paint blend, color, stroking, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005465
5466#Example
5467#Height 120
5468#Description
5469Paint attributes unrelated to text, like color, have no effect on paint in allocated Text_Blob.
5470Paint attributes related to text, like text size, have no effect on paint passed to drawTextBlob.
5471##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005472 void draw(SkCanvas* canvas) {
5473 SkTextBlobBuilder textBlobBuilder;
5474 SkPaint paint;
5475 paint.setTextSize(50);
5476 paint.setColor(SK_ColorRED);
Cary Clark2f466242017-12-11 16:03:17 -05005477 paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
Mike Klein9ff8c8c2018-02-07 01:58:51 +00005478 const SkTextBlobBuilder::RunBuffer& run =
Cary Clarkbad5ad72017-08-03 17:14:08 -04005479 textBlobBuilder.allocRun(paint, 1, 20, 100);
5480 run.glyphs[0] = 20;
5481 sk_sp<const SkTextBlob> blob = textBlobBuilder.make();
5482 paint.setTextSize(10);
5483 paint.setColor(SK_ColorBLUE);
5484 canvas->drawTextBlob(blob.get(), 0, 0, paint);
5485 }
Cary Clark8032b982017-07-28 11:04:54 -04005486##
5487
Cary Clark2ade9972017-11-02 17:49:34 -04005488#SeeAlso drawText drawPosText drawPosTextH
Cary Clark8032b982017-07-28 11:04:54 -04005489
5490##
5491
5492# ------------------------------------------------------------------------------
5493
Mike Klein9ff8c8c2018-02-07 01:58:51 +00005494#Method void drawPicture(const SkPicture* picture)
Cary Clark78de7512018-02-07 07:27:09 -05005495#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05005496#Line # draws Picture using Clip and Matrix ##
Cary Clark8032b982017-07-28 11:04:54 -04005497Draw Picture picture, using Clip and Matrix.
5498Clip and Matrix are unchanged by picture contents, as if
5499save() was called before and restore() was called after drawPicture.
5500
5501Picture records a series of draw commands for later playback.
5502
Cary Clarkbad5ad72017-08-03 17:14:08 -04005503#Param picture recorded drawing commands to play ##
Cary Clark8032b982017-07-28 11:04:54 -04005504
5505#Example
Mike Klein9ff8c8c2018-02-07 01:58:51 +00005506void draw(SkCanvas* canvas) {
Cary Clarkbad5ad72017-08-03 17:14:08 -04005507 SkPictureRecorder recorder;
5508 SkCanvas* recordingCanvas = recorder.beginRecording(50, 50);
5509 for (auto color : { SK_ColorRED, SK_ColorBLUE, 0xff007f00 } ) {
5510 SkPaint paint;
5511 paint.setColor(color);
5512 recordingCanvas->drawRect({10, 10, 30, 40}, paint);
5513 recordingCanvas->translate(10, 10);
5514 recordingCanvas->scale(1.2f, 1.4f);
5515 }
5516 sk_sp<SkPicture> playback = recorder.finishRecordingAsPicture();
5517 const SkPicture* playbackPtr = playback.get();
5518 canvas->drawPicture(playback);
5519 canvas->scale(2, 2);
5520 canvas->translate(50, 0);
5521 canvas->drawPicture(playback);
Cary Clark8032b982017-07-28 11:04:54 -04005522}
5523##
5524
Cary Clark2ade9972017-11-02 17:49:34 -04005525#SeeAlso drawDrawable SkPicture SkPicture::playback
Cary Clark8032b982017-07-28 11:04:54 -04005526
5527##
5528
5529# ------------------------------------------------------------------------------
5530
Mike Klein9ff8c8c2018-02-07 01:58:51 +00005531#Method void drawPicture(const sk_sp<SkPicture>& picture)
Cary Clark8032b982017-07-28 11:04:54 -04005532
5533Draw Picture picture, using Clip and Matrix.
5534Clip and Matrix are unchanged by picture contents, as if
5535save() was called before and restore() was called after drawPicture.
5536
5537Picture records a series of draw commands for later playback.
5538
Cary Clarkbad5ad72017-08-03 17:14:08 -04005539#Param picture recorded drawing commands to play ##
Cary Clark8032b982017-07-28 11:04:54 -04005540
5541#Example
Mike Klein9ff8c8c2018-02-07 01:58:51 +00005542void draw(SkCanvas* canvas) {
Cary Clarkbad5ad72017-08-03 17:14:08 -04005543 SkPictureRecorder recorder;
5544 SkCanvas* recordingCanvas = recorder.beginRecording(50, 50);
5545 for (auto color : { SK_ColorRED, SK_ColorBLUE, 0xff007f00 } ) {
5546 SkPaint paint;
5547 paint.setColor(color);
5548 recordingCanvas->drawRect({10, 10, 30, 40}, paint);
5549 recordingCanvas->translate(10, 10);
5550 recordingCanvas->scale(1.2f, 1.4f);
5551 }
5552 sk_sp<SkPicture> playback = recorder.finishRecordingAsPicture();
5553 canvas->drawPicture(playback);
5554 canvas->scale(2, 2);
5555 canvas->translate(50, 0);
5556 canvas->drawPicture(playback);
Cary Clark8032b982017-07-28 11:04:54 -04005557}
5558##
5559
Cary Clark2ade9972017-11-02 17:49:34 -04005560#SeeAlso drawDrawable SkPicture SkPicture::playback
Cary Clark8032b982017-07-28 11:04:54 -04005561
5562##
5563
5564# ------------------------------------------------------------------------------
5565
5566#Method void drawPicture(const SkPicture* picture, const SkMatrix* matrix, const SkPaint* paint)
5567
Cary Clarkbad5ad72017-08-03 17:14:08 -04005568Draw Picture picture, using Clip and Matrix; transforming picture with
5569Matrix matrix, if provided; and use Paint paint Color_Alpha, Color_Filter,
5570Image_Filter, and Blend_Mode, if provided.
Cary Clark8032b982017-07-28 11:04:54 -04005571
5572matrix transformation is equivalent to: save(), concat(), drawPicture, restore().
5573paint use is equivalent to: saveLayer, drawPicture, restore().
5574
Cary Clarkbad5ad72017-08-03 17:14:08 -04005575#Param picture recorded drawing commands to play ##
5576#Param matrix Matrix to rotate, scale, translate, and so on; may be nullptr ##
5577#Param paint Paint to apply transparency, filtering, and so on; may be nullptr ##
Cary Clark8032b982017-07-28 11:04:54 -04005578
5579#Example
Mike Klein9ff8c8c2018-02-07 01:58:51 +00005580void draw(SkCanvas* canvas) {
Cary Clarkbad5ad72017-08-03 17:14:08 -04005581 SkPaint paint;
5582 SkPictureRecorder recorder;
5583 SkCanvas* recordingCanvas = recorder.beginRecording(50, 50);
5584 for (auto color : { SK_ColorRED, SK_ColorBLUE, 0xff007f00 } ) {
5585 paint.setColor(color);
5586 recordingCanvas->drawRect({10, 10, 30, 40}, paint);
5587 recordingCanvas->translate(10, 10);
5588 recordingCanvas->scale(1.2f, 1.4f);
5589 }
5590 sk_sp<SkPicture> playback = recorder.finishRecordingAsPicture();
5591 const SkPicture* playbackPtr = playback.get();
5592 SkMatrix matrix;
5593 matrix.reset();
5594 for (auto alpha : { 70, 140, 210 } ) {
5595 paint.setAlpha(alpha);
5596 canvas->drawPicture(playbackPtr, &matrix, &paint);
5597 matrix.preTranslate(70, 70);
5598 }
Cary Clark8032b982017-07-28 11:04:54 -04005599}
5600##
5601
Cary Clark2ade9972017-11-02 17:49:34 -04005602#SeeAlso drawDrawable SkPicture SkPicture::playback
Cary Clark8032b982017-07-28 11:04:54 -04005603
5604##
5605
5606# ------------------------------------------------------------------------------
5607
Mike Klein9ff8c8c2018-02-07 01:58:51 +00005608#Method void drawPicture(const sk_sp<SkPicture>& picture, const SkMatrix* matrix, const SkPaint* paint)
Cary Clark8032b982017-07-28 11:04:54 -04005609
Cary Clarkbad5ad72017-08-03 17:14:08 -04005610Draw Picture picture, using Clip and Matrix; transforming picture with
5611Matrix matrix, if provided; and use Paint paint Color_Alpha, Color_Filter,
5612Image_Filter, and Blend_Mode, if provided.
Cary Clark8032b982017-07-28 11:04:54 -04005613
5614matrix transformation is equivalent to: save(), concat(), drawPicture, restore().
5615paint use is equivalent to: saveLayer, drawPicture, restore().
5616
Cary Clarkbad5ad72017-08-03 17:14:08 -04005617#Param picture recorded drawing commands to play ##
5618#Param matrix Matrix to rotate, scale, translate, and so on; may be nullptr ##
5619#Param paint Paint to apply transparency, filtering, and so on; may be nullptr ##
Cary Clark8032b982017-07-28 11:04:54 -04005620
5621#Example
Mike Klein9ff8c8c2018-02-07 01:58:51 +00005622void draw(SkCanvas* canvas) {
Cary Clarkbad5ad72017-08-03 17:14:08 -04005623 SkPaint paint;
5624 SkPictureRecorder recorder;
5625 SkCanvas* recordingCanvas = recorder.beginRecording(50, 50);
5626 for (auto color : { SK_ColorRED, SK_ColorBLUE, 0xff007f00 } ) {
5627 paint.setColor(color);
5628 recordingCanvas->drawRect({10, 10, 30, 40}, paint);
5629 recordingCanvas->translate(10, 10);
5630 recordingCanvas->scale(1.2f, 1.4f);
5631 }
5632 sk_sp<SkPicture> playback = recorder.finishRecordingAsPicture();
5633 SkMatrix matrix;
5634 matrix.reset();
5635 for (auto alpha : { 70, 140, 210 } ) {
5636 paint.setAlpha(alpha);
5637 canvas->drawPicture(playback, &matrix, &paint);
5638 matrix.preTranslate(70, 70);
5639 }
Cary Clark8032b982017-07-28 11:04:54 -04005640}
5641##
5642
Cary Clark2ade9972017-11-02 17:49:34 -04005643#SeeAlso drawDrawable SkPicture SkPicture::playback
Cary Clark8032b982017-07-28 11:04:54 -04005644
5645##
5646
5647# ------------------------------------------------------------------------------
5648
5649#Method void drawVertices(const SkVertices* vertices, SkBlendMode mode, const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05005650#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05005651#Line # draws Vertices, a triangle mesh ##
Cary Clark8032b982017-07-28 11:04:54 -04005652Draw Vertices vertices, a triangle mesh, using Clip and Matrix.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005653If Vertices_Texs and Vertices_Colors are defined in vertices, and Paint paint
5654contains Shader, Blend_Mode mode combines Vertices_Colors with Shader.
Cary Clark8032b982017-07-28 11:04:54 -04005655
Cary Clarkbad5ad72017-08-03 17:14:08 -04005656#Param vertices triangle mesh to draw ##
5657#Param mode combines Vertices_Colors with Shader, if both are present ##
5658#Param paint specifies the Shader, used as Vertices texture; may be nullptr ##
Cary Clark8032b982017-07-28 11:04:54 -04005659
5660#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04005661void draw(SkCanvas* canvas) {
5662 SkPaint paint;
5663 SkPoint points[] = { { 0, 0 }, { 250, 0 }, { 100, 100 }, { 0, 250 } };
5664 SkColor colors[] = { SK_ColorRED, SK_ColorBLUE, SK_ColorYELLOW, SK_ColorCYAN };
5665 auto vertices = SkVertices::MakeCopy(SkVertices::kTriangleFan_VertexMode,
5666 SK_ARRAY_COUNT(points), points, nullptr, colors);
5667 canvas->drawVertices(vertices.get(), SkBlendMode::kSrc, paint);
5668}
Cary Clark8032b982017-07-28 11:04:54 -04005669##
5670
Cary Clark2ade9972017-11-02 17:49:34 -04005671#SeeAlso drawPatch drawPicture
Cary Clark8032b982017-07-28 11:04:54 -04005672
5673##
5674
5675# ------------------------------------------------------------------------------
5676
5677#Method void drawVertices(const sk_sp<SkVertices>& vertices, SkBlendMode mode, const SkPaint& paint)
5678
5679Draw Vertices vertices, a triangle mesh, using Clip and Matrix.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005680If Vertices_Texs and Vertices_Colors are defined in vertices, and Paint paint
5681contains Shader, Blend_Mode mode combines Vertices_Colors with Shader.
Cary Clark8032b982017-07-28 11:04:54 -04005682
Cary Clarkbad5ad72017-08-03 17:14:08 -04005683#Param vertices triangle mesh to draw ##
5684#Param mode combines Vertices_Colors with Shader, if both are present ##
5685#Param paint specifies the Shader, used as Vertices texture, may be nullptr ##
Cary Clark8032b982017-07-28 11:04:54 -04005686
5687#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04005688void draw(SkCanvas* canvas) {
5689 SkPaint paint;
5690 SkPoint points[] = { { 0, 0 }, { 250, 0 }, { 100, 100 }, { 0, 250 } };
5691 SkPoint texs[] = { { 0, 0 }, { 0, 250 }, { 250, 250 }, { 250, 0 } };
5692 SkColor colors[] = { SK_ColorRED, SK_ColorBLUE, SK_ColorYELLOW, SK_ColorCYAN };
5693 paint.setShader(SkGradientShader::MakeLinear(points, colors, nullptr, 4,
5694 SkShader::kClamp_TileMode));
5695 auto vertices = SkVertices::MakeCopy(SkVertices::kTriangleFan_VertexMode,
5696 SK_ARRAY_COUNT(points), points, texs, colors);
5697 canvas->drawVertices(vertices.get(), SkBlendMode::kDarken, paint);
Cary Clark8032b982017-07-28 11:04:54 -04005698}
5699##
5700
Cary Clark2ade9972017-11-02 17:49:34 -04005701#SeeAlso drawPatch drawPicture
Cary Clark8032b982017-07-28 11:04:54 -04005702
5703##
5704
5705# ------------------------------------------------------------------------------
5706
5707#Method void drawPatch(const SkPoint cubics[12], const SkColor colors[4],
5708 const SkPoint texCoords[4], SkBlendMode mode, const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05005709#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05005710#Line # draws Coons_Patch ##
Cary Clark8032b982017-07-28 11:04:54 -04005711
Mike Klein9ff8c8c2018-02-07 01:58:51 +00005712Draws a Coons_Patch: the interpolation of four cubics with shared corners,
Cary Clark8032b982017-07-28 11:04:54 -04005713associating a color, and optionally a texture coordinate, with each corner.
5714
Cary Clarka560c472017-11-27 10:44:06 -05005715Coons_Patch uses Clip and Matrix, paint Shader, Color_Filter,
Cary Clarkbad5ad72017-08-03 17:14:08 -04005716Color_Alpha, Image_Filter, and Blend_Mode. If Shader is provided it is treated
Cary Clarka560c472017-11-27 10:44:06 -05005717as Coons_Patch texture; Blend_Mode mode combines Color colors and Shader if
Cary Clarkbad5ad72017-08-03 17:14:08 -04005718both are provided.
Cary Clark8032b982017-07-28 11:04:54 -04005719
Mike Klein9ff8c8c2018-02-07 01:58:51 +00005720Point array cubics specifies four Cubics starting at the top-left corner,
Cary Clarkce101242017-09-01 15:51:02 -04005721in clockwise order, sharing every fourth point. The last Cubic ends at the
Cary Clarkbad5ad72017-08-03 17:14:08 -04005722first point.
Cary Clark8032b982017-07-28 11:04:54 -04005723
Cary Clarkbc5697d2017-10-04 14:31:33 -04005724Color array color associates colors with corners in top-left, top-right,
5725bottom-right, bottom-left order.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005726
5727If paint contains Shader, Point array texCoords maps Shader as texture to
Cary Clarkbc5697d2017-10-04 14:31:33 -04005728corners in top-left, top-right, bottom-right, bottom-left order.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005729
Cary Clarka523d2d2017-08-30 08:58:10 -04005730#Param cubics Path_Cubic array, sharing common points ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005731#Param colors Color array, one for each corner ##
Cary Clarkce101242017-09-01 15:51:02 -04005732#Param texCoords Point array of texture coordinates, mapping Shader to corners;
Mike Klein9ff8c8c2018-02-07 01:58:51 +00005733 may be nullptr
Cary Clark579985c2017-07-31 11:48:27 -04005734#Param ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005735#Param mode Blend_Mode for colors, and for Shader if paint has one ##
5736#Param paint Shader, Color_Filter, Blend_Mode, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005737
5738#Example
5739#Image 5
Cary Clarkbad5ad72017-08-03 17:14:08 -04005740void draw(SkCanvas* canvas) {
5741 // SkBitmap source = cmbkygk;
5742 SkPaint paint;
5743 paint.setFilterQuality(kLow_SkFilterQuality);
5744 paint.setAntiAlias(true);
5745 SkPoint cubics[] = { { 3, 1 }, { 4, 2 }, { 5, 1 }, { 7, 3 },
5746 /* { 7, 3 }, */ { 6, 4 }, { 7, 5 }, { 5, 7 },
5747 /* { 5, 7 }, */ { 4, 6 }, { 3, 7 }, { 1, 5 },
5748 /* { 1, 5 }, */ { 2, 4 }, { 1, 3 }, /* { 3, 1 } */ };
5749 SkColor colors[] = { 0xbfff0000, 0xbf0000ff, 0xbfff00ff, 0xbf00ffff };
5750 SkPoint texCoords[] = { { -30, -30 }, { 162, -30}, { 162, 162}, { -30, 162} };
5751 paint.setShader(SkShader::MakeBitmapShader(source, SkShader::kClamp_TileMode,
5752 SkShader::kClamp_TileMode, nullptr));
5753 canvas->scale(15, 15);
5754 for (auto blend : { SkBlendMode::kSrcOver, SkBlendMode::kModulate, SkBlendMode::kXor } ) {
5755 canvas->drawPatch(cubics, colors, texCoords, blend, paint);
5756 canvas->translate(4, 4);
5757 }
Cary Clark8032b982017-07-28 11:04:54 -04005758}
5759##
5760
Cary Clark2ade9972017-11-02 17:49:34 -04005761#ToDo can patch use image filter? ##
5762#SeeAlso SeeAlso drawVertices drawPicture
Cary Clark8032b982017-07-28 11:04:54 -04005763
5764##
5765
5766# ------------------------------------------------------------------------------
5767
5768#Method void drawPatch(const SkPoint cubics[12], const SkColor colors[4],
Mike Klein9ff8c8c2018-02-07 01:58:51 +00005769 const SkPoint texCoords[4], const SkPaint& paint)
Cary Clark8032b982017-07-28 11:04:54 -04005770
Mike Klein9ff8c8c2018-02-07 01:58:51 +00005771Draws Cubic Coons_Patch: the interpolation of four cubics with shared corners,
Cary Clarkbad5ad72017-08-03 17:14:08 -04005772associating a color, and optionally a texture coordinate, with each corner.
Cary Clark8032b982017-07-28 11:04:54 -04005773
Cary Clarka560c472017-11-27 10:44:06 -05005774Coons_Patch uses Clip and Matrix, paint Shader, Color_Filter,
Cary Clarkbad5ad72017-08-03 17:14:08 -04005775Color_Alpha, Image_Filter, and Blend_Mode. If Shader is provided it is treated
Cary Clarka560c472017-11-27 10:44:06 -05005776as Coons_Patch texture; Blend_Mode mode combines Color colors and Shader if
Cary Clarkbad5ad72017-08-03 17:14:08 -04005777both are provided.
Cary Clark8032b982017-07-28 11:04:54 -04005778
Mike Klein9ff8c8c2018-02-07 01:58:51 +00005779Point array cubics specifies four Cubics starting at the top-left corner,
Cary Clarkce101242017-09-01 15:51:02 -04005780in clockwise order, sharing every fourth point. The last Cubic ends at the
Cary Clarkbad5ad72017-08-03 17:14:08 -04005781first point.
5782
Cary Clarkbc5697d2017-10-04 14:31:33 -04005783Color array color associates colors with corners in top-left, top-right,
5784bottom-right, bottom-left order.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005785
5786If paint contains Shader, Point array texCoords maps Shader as texture to
Cary Clarkbc5697d2017-10-04 14:31:33 -04005787corners in top-left, top-right, bottom-right, bottom-left order.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005788
Cary Clarka523d2d2017-08-30 08:58:10 -04005789#Param cubics Path_Cubic array, sharing common points ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005790#Param colors Color array, one for each corner ##
Cary Clarkce101242017-09-01 15:51:02 -04005791#Param texCoords Point array of texture coordinates, mapping Shader to corners;
Mike Klein9ff8c8c2018-02-07 01:58:51 +00005792 may be nullptr
Cary Clark579985c2017-07-31 11:48:27 -04005793#Param ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005794#Param paint Shader, Color_Filter, Blend_Mode, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005795
5796#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04005797void draw(SkCanvas* canvas) {
5798 SkPaint paint;
5799 paint.setAntiAlias(true);
5800 SkPoint cubics[] = { { 3, 1 }, { 4, 2 }, { 5, 1 }, { 7, 3 },
5801 /* { 7, 3 }, */ { 6, 4 }, { 7, 5 }, { 5, 7 },
5802 /* { 5, 7 }, */ { 4, 6 }, { 3, 7 }, { 1, 5 },
5803 /* { 1, 5 }, */ { 2, 4 }, { 1, 3 }, /* { 3, 1 } */ };
5804 SkColor colors[] = { SK_ColorRED, SK_ColorBLUE, SK_ColorYELLOW, SK_ColorCYAN };
5805 canvas->scale(30, 30);
5806 canvas->drawPatch(cubics, colors, nullptr, paint);
5807 SkPoint text[] = { {3,0.9f}, {4,2.5f}, {5,0.9f}, {7.5f,3.2f}, {5.5f,4.2f},
5808 {7.5f,5.2f}, {5,7.5f}, {4,5.9f}, {3,7.5f}, {0.5f,5.2f}, {2.5f,4.2f},
5809 {0.5f,3.2f} };
5810 paint.setTextSize(18.f / 30);
5811 paint.setTextAlign(SkPaint::kCenter_Align);
5812 for (int i = 0; i< 10; ++i) {
5813 char digit = '0' + i;
5814 canvas->drawText(&digit, 1, text[i].fX, text[i].fY, paint);
5815 }
5816 canvas->drawString("10", text[10].fX, text[10].fY, paint);
5817 canvas->drawString("11", text[11].fX, text[11].fY, paint);
5818 paint.setStyle(SkPaint::kStroke_Style);
5819 canvas->drawPoints(SkCanvas::kPolygon_PointMode, 12, cubics, paint);
5820 canvas->drawLine(cubics[11].fX, cubics[11].fY, cubics[0].fX, cubics[0].fY, paint);
Cary Clark8032b982017-07-28 11:04:54 -04005821}
5822##
5823
5824#Example
5825#Image 6
Cary Clarkbad5ad72017-08-03 17:14:08 -04005826void draw(SkCanvas* canvas) {
5827 // SkBitmap source = checkerboard;
5828 SkPaint paint;
5829 paint.setFilterQuality(kLow_SkFilterQuality);
5830 paint.setAntiAlias(true);
5831 SkPoint cubics[] = { { 3, 1 }, { 4, 2 }, { 5, 1 }, { 7, 3 },
5832 /* { 7, 3 }, */ { 6, 4 }, { 7, 5 }, { 5, 7 },
5833 /* { 5, 7 }, */ { 4, 6 }, { 3, 7 }, { 1, 5 },
5834 /* { 1, 5 }, */ { 2, 4 }, { 1, 3 }, /* { 3, 1 } */ };
5835 SkPoint texCoords[] = { { 0, 0 }, { 0, 62}, { 62, 62}, { 62, 0 } };
5836 paint.setShader(SkShader::MakeBitmapShader(source, SkShader::kClamp_TileMode,
5837 SkShader::kClamp_TileMode, nullptr));
5838 canvas->scale(30, 30);
5839 canvas->drawPatch(cubics, nullptr, texCoords, paint);
Cary Clark8032b982017-07-28 11:04:54 -04005840}
5841##
5842
Cary Clark2ade9972017-11-02 17:49:34 -04005843#ToDo can patch use image filter? ##
5844#SeeAlso SeeAlso drawVertices drawPicture
Cary Clark8032b982017-07-28 11:04:54 -04005845
5846##
5847
5848# ------------------------------------------------------------------------------
5849
5850#Method void drawAtlas(const SkImage* atlas, const SkRSXform xform[], const SkRect tex[],
5851 const SkColor colors[], int count, SkBlendMode mode, const SkRect* cullRect,
5852 const SkPaint* paint)
Cary Clark78de7512018-02-07 07:27:09 -05005853#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05005854#Line # draws sprites using Clip, Matrix, and Paint ##
Cary Clark8032b982017-07-28 11:04:54 -04005855
5856Draw a set of sprites from atlas, using Clip, Matrix, and optional Paint paint.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005857paint uses Anti-alias, Color_Alpha, Color_Filter, Image_Filter, and Blend_Mode
5858to draw, if present. For each entry in the array, Rect tex locates sprite in
5859atlas, and RSXform xform transforms it into destination space.
5860
Cary Clark8032b982017-07-28 11:04:54 -04005861xform, text, and colors if present, must contain count entries.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005862Optional colors are applied for each sprite using Blend_Mode.
Mike Klein9ff8c8c2018-02-07 01:58:51 +00005863Optional cullRect is a conservative bounds of all transformed sprites.
Cary Clarkce101242017-09-01 15:51:02 -04005864If cullRect is outside of Clip, canvas can skip drawing.
Cary Clark8032b982017-07-28 11:04:54 -04005865
Cary Clarkbad5ad72017-08-03 17:14:08 -04005866#Param atlas Image containing sprites ##
5867#Param xform RSXform mappings for sprites in atlas ##
5868#Param tex Rect locations of sprites in atlas ##
Cary Clark6fc50412017-09-21 12:31:06 -04005869#Param colors one per sprite, blended with sprite using Blend_Mode; may be nullptr ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005870#Param count number of sprites to draw ##
5871#Param mode Blend_Mode combining colors and sprites ##
Cary Clark6fc50412017-09-21 12:31:06 -04005872#Param cullRect bounds of transformed sprites for efficient clipping; may be nullptr ##
5873#Param paint Color_Filter, Image_Filter, Blend_Mode, and so on; may be nullptr ##
Cary Clark8032b982017-07-28 11:04:54 -04005874
5875#Example
5876#Image 3
Cary Clarkbad5ad72017-08-03 17:14:08 -04005877void draw(SkCanvas* canvas) {
5878 // SkBitmap source = mandrill;
5879 SkRSXform xforms[] = { { .5f, 0, 0, 0 }, {0, .5f, 200, 100 } };
5880 SkRect tex[] = { { 0, 0, 250, 250 }, { 0, 0, 250, 250 } };
5881 SkColor colors[] = { 0x7f55aa00, 0x7f3333bf };
5882 const SkImage* imagePtr = image.get();
5883 canvas->drawAtlas(imagePtr, xforms, tex, colors, 2, SkBlendMode::kSrcOver, nullptr, nullptr);
Cary Clark8032b982017-07-28 11:04:54 -04005884}
5885##
5886
Cary Clark2ade9972017-11-02 17:49:34 -04005887#SeeAlso drawBitmap drawImage
Cary Clark8032b982017-07-28 11:04:54 -04005888
5889##
5890
5891# ------------------------------------------------------------------------------
5892
5893#Method void drawAtlas(const sk_sp<SkImage>& atlas, const SkRSXform xform[], const SkRect tex[],
5894 const SkColor colors[], int count, SkBlendMode mode, const SkRect* cullRect,
Mike Klein9ff8c8c2018-02-07 01:58:51 +00005895 const SkPaint* paint)
Cary Clark8032b982017-07-28 11:04:54 -04005896
5897Draw a set of sprites from atlas, using Clip, Matrix, and optional Paint paint.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005898paint uses Anti-alias, Color_Alpha, Color_Filter, Image_Filter, and Blend_Mode
5899to draw, if present. For each entry in the array, Rect tex locates sprite in
5900atlas, and RSXform xform transforms it into destination space.
5901
Cary Clark8032b982017-07-28 11:04:54 -04005902xform, text, and colors if present, must contain count entries.
5903Optional colors is applied for each sprite using Blend_Mode.
Mike Klein9ff8c8c2018-02-07 01:58:51 +00005904Optional cullRect is a conservative bounds of all transformed sprites.
Cary Clarkce101242017-09-01 15:51:02 -04005905If cullRect is outside of Clip, canvas can skip drawing.
Cary Clark8032b982017-07-28 11:04:54 -04005906
Cary Clarkbad5ad72017-08-03 17:14:08 -04005907#Param atlas Image containing sprites ##
5908#Param xform RSXform mappings for sprites in atlas ##
5909#Param tex Rect locations of sprites in atlas ##
Cary Clark6fc50412017-09-21 12:31:06 -04005910#Param colors one per sprite, blended with sprite using Blend_Mode; may be nullptr ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005911#Param count number of sprites to draw ##
5912#Param mode Blend_Mode combining colors and sprites ##
Cary Clark6fc50412017-09-21 12:31:06 -04005913#Param cullRect bounds of transformed sprites for efficient clipping; may be nullptr ##
5914#Param paint Color_Filter, Image_Filter, Blend_Mode, and so on; may be nullptr ##
Cary Clark8032b982017-07-28 11:04:54 -04005915
5916#Example
5917#Image 3
Cary Clarkbad5ad72017-08-03 17:14:08 -04005918void draw(SkCanvas* canvas) {
5919 // SkBitmap source = mandrill;
5920 SkRSXform xforms[] = { { .5f, 0, 0, 0 }, {0, .5f, 200, 100 } };
5921 SkRect tex[] = { { 0, 0, 250, 250 }, { 0, 0, 250, 250 } };
5922 SkColor colors[] = { 0x7f55aa00, 0x7f3333bf };
5923 SkPaint paint;
5924 paint.setAlpha(127);
5925 canvas->drawAtlas(image, xforms, tex, colors, 2, SkBlendMode::kPlus, nullptr, &paint);
Cary Clark8032b982017-07-28 11:04:54 -04005926}
5927##
5928
5929#ToDo bug in example on cpu side, gpu looks ok ##
5930
Cary Clark2ade9972017-11-02 17:49:34 -04005931#SeeAlso drawBitmap drawImage
5932
Cary Clark8032b982017-07-28 11:04:54 -04005933##
5934
5935# ------------------------------------------------------------------------------
5936
5937#Method void drawAtlas(const SkImage* atlas, const SkRSXform xform[], const SkRect tex[], int count,
Mike Klein9ff8c8c2018-02-07 01:58:51 +00005938 const SkRect* cullRect, const SkPaint* paint)
Cary Clark8032b982017-07-28 11:04:54 -04005939
5940Draw a set of sprites from atlas, using Clip, Matrix, and optional Paint paint.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005941paint uses Anti-alias, Color_Alpha, Color_Filter, Image_Filter, and Blend_Mode
5942to draw, if present. For each entry in the array, Rect tex locates sprite in
5943atlas, and RSXform xform transforms it into destination space.
5944
Cary Clark8032b982017-07-28 11:04:54 -04005945xform and text must contain count entries.
Mike Klein9ff8c8c2018-02-07 01:58:51 +00005946Optional cullRect is a conservative bounds of all transformed sprites.
Cary Clarkce101242017-09-01 15:51:02 -04005947If cullRect is outside of Clip, canvas can skip drawing.
Cary Clark8032b982017-07-28 11:04:54 -04005948
Cary Clarkbad5ad72017-08-03 17:14:08 -04005949#Param atlas Image containing sprites ##
5950#Param xform RSXform mappings for sprites in atlas ##
5951#Param tex Rect locations of sprites in atlas ##
5952#Param count number of sprites to draw ##
Cary Clark6fc50412017-09-21 12:31:06 -04005953#Param cullRect bounds of transformed sprites for efficient clipping; may be nullptr ##
5954#Param paint Color_Filter, Image_Filter, Blend_Mode, and so on; may be nullptr ##
Cary Clark8032b982017-07-28 11:04:54 -04005955
5956#Example
5957#Image 3
Cary Clarkbad5ad72017-08-03 17:14:08 -04005958void draw(SkCanvas* canvas) {
5959 // sk_sp<SkImage> image = mandrill;
5960 SkRSXform xforms[] = { { .5f, 0, 0, 0 }, {0, .5f, 200, 100 } };
5961 SkRect tex[] = { { 0, 0, 250, 250 }, { 0, 0, 250, 250 } };
5962 const SkImage* imagePtr = image.get();
5963 canvas->drawAtlas(imagePtr, xforms, tex, 2, nullptr, nullptr);
Cary Clark8032b982017-07-28 11:04:54 -04005964}
5965##
5966
Cary Clark2ade9972017-11-02 17:49:34 -04005967#SeeAlso drawBitmap drawImage
Cary Clark8032b982017-07-28 11:04:54 -04005968
5969##
5970
5971# ------------------------------------------------------------------------------
5972
5973#Method void drawAtlas(const sk_sp<SkImage>& atlas, const SkRSXform xform[], const SkRect tex[],
Mike Klein9ff8c8c2018-02-07 01:58:51 +00005974 int count, const SkRect* cullRect, const SkPaint* paint)
Cary Clark8032b982017-07-28 11:04:54 -04005975
5976Draw a set of sprites from atlas, using Clip, Matrix, and optional Paint paint.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005977paint uses Anti-alias, Color_Alpha, Color_Filter, Image_Filter, and Blend_Mode
5978to draw, if present. For each entry in the array, Rect tex locates sprite in
5979atlas, and RSXform xform transforms it into destination space.
5980
Cary Clark8032b982017-07-28 11:04:54 -04005981xform and text must contain count entries.
Mike Klein9ff8c8c2018-02-07 01:58:51 +00005982Optional cullRect is a conservative bounds of all transformed sprites.
Cary Clarkce101242017-09-01 15:51:02 -04005983If cullRect is outside of Clip, canvas can skip drawing.
Cary Clark8032b982017-07-28 11:04:54 -04005984
Cary Clarkbad5ad72017-08-03 17:14:08 -04005985#Param atlas Image containing sprites ##
5986#Param xform RSXform mappings for sprites in atlas ##
5987#Param tex Rect locations of sprites in atlas ##
5988#Param count number of sprites to draw ##
Cary Clark6fc50412017-09-21 12:31:06 -04005989#Param cullRect bounds of transformed sprites for efficient clipping; may be nullptr ##
5990#Param paint Color_Filter, Image_Filter, Blend_Mode, and so on; may be nullptr ##
Cary Clark8032b982017-07-28 11:04:54 -04005991
5992#Example
5993#Image 3
Cary Clarkbad5ad72017-08-03 17:14:08 -04005994void draw(SkCanvas* canvas) {
5995 // sk_sp<SkImage> image = mandrill;
5996 SkRSXform xforms[] = { { 1, 0, 0, 0 }, {0, 1, 300, 100 } };
5997 SkRect tex[] = { { 0, 0, 200, 200 }, { 200, 0, 400, 200 } };
5998 canvas->drawAtlas(image, xforms, tex, 2, nullptr, nullptr);
Cary Clark8032b982017-07-28 11:04:54 -04005999}
6000##
6001
Cary Clark2ade9972017-11-02 17:49:34 -04006002#SeeAlso drawBitmap drawImage
Cary Clark8032b982017-07-28 11:04:54 -04006003
6004##
6005
6006# ------------------------------------------------------------------------------
6007
Cary Clark73fa9722017-08-29 17:36:51 -04006008#Method void drawDrawable(SkDrawable* drawable, const SkMatrix* matrix = nullptr)
Cary Clark78de7512018-02-07 07:27:09 -05006009#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05006010#Line # draws Drawable, encapsulated drawing commands ##
Mike Klein9ff8c8c2018-02-07 01:58:51 +00006011Draw Drawable drawable using Clip and Matrix, concatenated with
Cary Clark8032b982017-07-28 11:04:54 -04006012optional matrix.
6013
Mike Klein9ff8c8c2018-02-07 01:58:51 +00006014If Canvas has an asynchronous implementation, as is the case
Cary Clark8032b982017-07-28 11:04:54 -04006015when it is recording into Picture, then drawable will be referenced,
6016so that SkDrawable::draw() can be called when the operation is finalized. To force
6017immediate drawing, call SkDrawable::draw() instead.
6018
Cary Clarkbad5ad72017-08-03 17:14:08 -04006019#Param drawable custom struct encapsulating drawing commands ##
6020#Param matrix transformation applied to drawing; may be nullptr ##
Cary Clark8032b982017-07-28 11:04:54 -04006021
6022#Example
6023#Height 100
6024#Function
Cary Clarkbad5ad72017-08-03 17:14:08 -04006025struct MyDrawable : public SkDrawable {
6026 SkRect onGetBounds() override { return SkRect::MakeWH(50, 100); }
6027
6028 void onDraw(SkCanvas* canvas) override {
6029 SkPath path;
6030 path.conicTo(10, 90, 50, 90, 0.9f);
6031 SkPaint paint;
6032 paint.setColor(SK_ColorBLUE);
6033 canvas->drawRect(path.getBounds(), paint);
6034 paint.setAntiAlias(true);
6035 paint.setColor(SK_ColorWHITE);
6036 canvas->drawPath(path, paint);
6037 }
6038};
6039
6040#Function ##
6041void draw(SkCanvas* canvas) {
6042 sk_sp<SkDrawable> drawable(new MyDrawable);
6043 SkMatrix matrix;
6044 matrix.setTranslate(10, 10);
6045 canvas->drawDrawable(drawable.get(), &matrix);
Cary Clark8032b982017-07-28 11:04:54 -04006046}
6047##
6048
Cary Clark2ade9972017-11-02 17:49:34 -04006049#SeeAlso SkDrawable drawPicture
Cary Clark8032b982017-07-28 11:04:54 -04006050
6051##
6052
6053# ------------------------------------------------------------------------------
6054
6055#Method void drawDrawable(SkDrawable* drawable, SkScalar x, SkScalar y)
6056
6057Draw Drawable drawable using Clip and Matrix, offset by (x, y).
6058
Mike Klein9ff8c8c2018-02-07 01:58:51 +00006059If Canvas has an asynchronous implementation, as is the case
Cary Clark8032b982017-07-28 11:04:54 -04006060when it is recording into Picture, then drawable will be referenced,
6061so that SkDrawable::draw() can be called when the operation is finalized. To force
6062immediate drawing, call SkDrawable::draw() instead.
6063
Cary Clarkbad5ad72017-08-03 17:14:08 -04006064#Param drawable custom struct encapsulating drawing commands ##
6065#Param x offset into Canvas writable pixels in x ##
6066#Param y offset into Canvas writable pixels in y ##
Cary Clark8032b982017-07-28 11:04:54 -04006067
6068#Example
6069#Height 100
6070#Function
Cary Clarkbad5ad72017-08-03 17:14:08 -04006071struct MyDrawable : public SkDrawable {
6072 SkRect onGetBounds() override { return SkRect::MakeWH(50, 100); }
6073
6074 void onDraw(SkCanvas* canvas) override {
6075 SkPath path;
6076 path.conicTo(10, 90, 50, 90, 0.9f);
6077 SkPaint paint;
6078 paint.setColor(SK_ColorBLUE);
6079 canvas->drawRect(path.getBounds(), paint);
6080 paint.setAntiAlias(true);
6081 paint.setColor(SK_ColorWHITE);
6082 canvas->drawPath(path, paint);
6083 }
6084};
6085
6086#Function ##
6087void draw(SkCanvas* canvas) {
6088 sk_sp<SkDrawable> drawable(new MyDrawable);
6089 canvas->drawDrawable(drawable.get(), 10, 10);
Cary Clark8032b982017-07-28 11:04:54 -04006090}
6091##
6092
Cary Clark2ade9972017-11-02 17:49:34 -04006093#SeeAlso SkDrawable drawPicture
Cary Clark8032b982017-07-28 11:04:54 -04006094
6095##
6096
6097# ------------------------------------------------------------------------------
6098
6099#Method void drawAnnotation(const SkRect& rect, const char key[], SkData* value)
Cary Clark78de7512018-02-07 07:27:09 -05006100#In Draw
6101#In Utility
Cary Clarkab2621d2018-01-30 10:08:57 -05006102#Line # associates a Rect with a key-value pair ##
Cary Clark78de7512018-02-07 07:27:09 -05006103Associate Rect on Canvas with an annotation; a key-value pair, where the key is
Cary Clark8032b982017-07-28 11:04:54 -04006104a null-terminated utf8 string, and optional value is stored as Data.
6105
Mike Klein9ff8c8c2018-02-07 01:58:51 +00006106Only some canvas implementations, such as recording to Picture, or drawing to
Cary Clark8032b982017-07-28 11:04:54 -04006107Document_PDF, use annotations.
6108
Cary Clarkbad5ad72017-08-03 17:14:08 -04006109#Param rect Rect extent of canvas to annotate ##
6110#Param key string used for lookup ##
6111#Param value data holding value stored in annotation ##
Cary Clark8032b982017-07-28 11:04:54 -04006112
6113#Example
6114 #Height 1
6115 const char text[] = "Click this link!";
6116 SkRect bounds;
6117 SkPaint paint;
6118 paint.setTextSize(40);
6119 (void)paint.measureText(text, strlen(text), &bounds);
6120 const char url[] = "https://www.google.com/";
6121 sk_sp<SkData> urlData(SkData::MakeWithCString(url));
6122 canvas->drawAnnotation(bounds, "url_key", urlData.get());
6123##
6124
Cary Clark2ade9972017-11-02 17:49:34 -04006125#SeeAlso SkPicture SkDocument
Cary Clark8032b982017-07-28 11:04:54 -04006126
6127##
6128
6129# ------------------------------------------------------------------------------
6130
Mike Klein9ff8c8c2018-02-07 01:58:51 +00006131#Method void drawAnnotation(const SkRect& rect, const char key[], const sk_sp<SkData>& value)
Cary Clark8032b982017-07-28 11:04:54 -04006132
6133Associate Rect on Canvas when an annotation; a key-value pair, where the key is
6134a null-terminated utf8 string, and optional value is stored as Data.
6135
Mike Klein9ff8c8c2018-02-07 01:58:51 +00006136Only some canvas implementations, such as recording to Picture, or drawing to
Cary Clark8032b982017-07-28 11:04:54 -04006137Document_PDF, use annotations.
6138
Cary Clarkbad5ad72017-08-03 17:14:08 -04006139#Param rect Rect extent of canvas to annotate ##
6140#Param key string used for lookup ##
6141#Param value data holding value stored in annotation ##
Cary Clark8032b982017-07-28 11:04:54 -04006142
6143#Example
6144#Height 1
6145 const char text[] = "Click this link!";
6146 SkRect bounds;
6147 SkPaint paint;
6148 paint.setTextSize(40);
6149 (void)paint.measureText(text, strlen(text), &bounds);
6150 const char url[] = "https://www.google.com/";
6151 sk_sp<SkData> urlData(SkData::MakeWithCString(url));
6152 canvas->drawAnnotation(bounds, "url_key", urlData.get());
6153##
6154
Cary Clark2ade9972017-11-02 17:49:34 -04006155#SeeAlso SkPicture SkDocument
Cary Clark8032b982017-07-28 11:04:54 -04006156
6157##
6158
6159#Method SkDrawFilter* getDrawFilter() const
Cary Clark4855f782018-02-06 09:41:53 -05006160#Deprecated soon
Cary Clark8032b982017-07-28 11:04:54 -04006161##
6162
6163#Method virtual SkDrawFilter* setDrawFilter(SkDrawFilter* filter)
Cary Clark4855f782018-02-06 09:41:53 -05006164#Deprecated soon
Cary Clark8032b982017-07-28 11:04:54 -04006165##
6166
6167# ------------------------------------------------------------------------------
6168
6169#Method virtual bool isClipEmpty() const
Cary Clark78de7512018-02-07 07:27:09 -05006170#In Property
Cary Clarkab2621d2018-01-30 10:08:57 -05006171#Line # returns if Clip is empty ##
Cary Clark8032b982017-07-28 11:04:54 -04006172Returns true if Clip is empty; that is, nothing will draw.
6173
Cary Clarkbad5ad72017-08-03 17:14:08 -04006174May do work when called; it should not be called
Cary Clark8032b982017-07-28 11:04:54 -04006175more often than needed. However, once called, subsequent calls perform no
6176work until Clip changes.
6177
Cary Clarkbad5ad72017-08-03 17:14:08 -04006178#Return true if Clip is empty ##
Cary Clark8032b982017-07-28 11:04:54 -04006179
6180#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04006181 void draw(SkCanvas* canvas) {
6182 SkDebugf("clip is%s empty\n", canvas->isClipEmpty() ? "" : " not");
6183 SkPath path;
6184 canvas->clipPath(path);
6185 SkDebugf("clip is%s empty\n", canvas->isClipEmpty() ? "" : " not");
Cary Clark8032b982017-07-28 11:04:54 -04006186 }
6187 #StdOut
Cary Clarkbad5ad72017-08-03 17:14:08 -04006188 clip is not empty
Cary Clark8032b982017-07-28 11:04:54 -04006189 clip is empty
6190 ##
6191##
6192
Cary Clark2ade9972017-11-02 17:49:34 -04006193#SeeAlso isClipRect getLocalClipBounds getDeviceClipBounds
Cary Clark8032b982017-07-28 11:04:54 -04006194
6195##
6196
6197# ------------------------------------------------------------------------------
6198
6199#Method virtual bool isClipRect() const
Cary Clark78de7512018-02-07 07:27:09 -05006200#In Property
Cary Clarkab2621d2018-01-30 10:08:57 -05006201#Line # returns if Clip is Rect and not empty ##
Cary Clark8032b982017-07-28 11:04:54 -04006202Returns true if Clip is Rect and not empty.
6203Returns false if the clip is empty, or if it is not Rect.
6204
Cary Clarkbad5ad72017-08-03 17:14:08 -04006205#Return true if Clip is Rect and not empty ##
Cary Clark8032b982017-07-28 11:04:54 -04006206
6207#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04006208 void draw(SkCanvas* canvas) {
6209 SkDebugf("clip is%s rect\n", canvas->isClipRect() ? "" : " not");
6210 canvas->clipRect({0, 0, 0, 0});
6211 SkDebugf("clip is%s rect\n", canvas->isClipRect() ? "" : " not");
Cary Clark8032b982017-07-28 11:04:54 -04006212 }
6213 #StdOut
Cary Clarkbad5ad72017-08-03 17:14:08 -04006214 clip is rect
Cary Clark8032b982017-07-28 11:04:54 -04006215 clip is not rect
6216 ##
6217##
6218
Cary Clark2ade9972017-11-02 17:49:34 -04006219#SeeAlso isClipEmpty getLocalClipBounds getDeviceClipBounds
Cary Clark8032b982017-07-28 11:04:54 -04006220
6221##
6222
6223#Class SkCanvas ##
Cary Clark884dd7d2017-10-11 10:37:52 -04006224
Cary Clark8032b982017-07-28 11:04:54 -04006225#Topic Canvas ##