blob: 2f4774f56636ed6b129e37529c3c21adfd8d45a1 [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
Herb Derbyefe39bc2018-05-01 17:06:20 -040021To 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.
Herb Derbyefe39bc2018-05-01 17:06:20 -040031This 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
Herb Derbyefe39bc2018-05-01 17:06:20 -040074Pass 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,
Herb Derbyefe39bc2018-05-01 17:06:20 -0400136 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
Herb Derbyefe39bc2018-05-01 17:06:20 -0400152Pass 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 ##
Herb Derbyefe39bc2018-05-01 17:06:20 -0400213Creates 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
Herb Derbyefe39bc2018-05-01 17:06:20 -0400270Surface_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
Herb Derbyefe39bc2018-05-01 17:06:20 -0400299#Method explicit SkCanvas(sk_sp<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.
Herb Derbyefe39bc2018-05-01 17:06:20 -0400309Sets 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,
Herb Derbyefe39bc2018-05-01 17:06:20 -0400410 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 ##
Herb Derbyefe39bc2018-05-01 17:06:20 -0400602Triggers 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
Herb Derbyefe39bc2018-05-01 17:06:20 -0400723#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
Herb Derbyefe39bc2018-05-01 17:06:20 -0400762device.
Cary Clark8032b982017-07-28 11:04:54 -0400763
Cary Clarkce101242017-09-01 15:51:02 -0400764The Layer and blended result appear on the CPU and GPU but the large dotted
Cary Clark8032b982017-07-28 11:04:54 -0400765"DEF" appear only on the CPU.
766##
767void draw(SkCanvas* canvas) {
Cary Clarkbad5ad72017-08-03 17:14:08 -0400768 SkPaint paint;
769 paint.setTextSize(100);
770 canvas->drawString("ABC", 20, 160, paint);
771 SkRect layerBounds = SkRect::MakeXYWH(32, 32, 192, 192);
772 canvas->saveLayerAlpha(&layerBounds, 128);
773 canvas->clear(SK_ColorWHITE);
774 canvas->drawString("DEF", 20, 160, paint);
775 SkImageInfo imageInfo;
776 size_t rowBytes;
777 SkIPoint origin;
778 uint32_t* access = (uint32_t*) canvas->accessTopLayerPixels(&imageInfo, &rowBytes, &origin);
779 if (access) {
780 int h = imageInfo.height();
781 int v = imageInfo.width();
782 int rowWords = rowBytes / sizeof(uint32_t);
783 for (int y = 0; y < h; ++y) {
784 int newY = (y - h / 2) * 2 + h / 2;
785 if (newY < 0 || newY >= h) {
786 continue;
787 }
788 for (int x = 0; x < v; ++x) {
789 int newX = (x - v / 2) * 2 + v / 2;
790 if (newX < 0 || newX >= v) {
791 continue;
792 }
793 if (access[y * rowWords + x] == SK_ColorBLACK) {
794 access[newY * rowWords + newX] = SK_ColorGRAY;
795 }
796 }
797 }
798
799 }
Cary Clark8032b982017-07-28 11:04:54 -0400800 canvas->restore();
801}
802##
803
804#ToDo there are no callers of this that I can find. Deprecate? ##
805#ToDo fiddle should show both CPU and GPU out ##
806
Cary Clark2ade9972017-11-02 17:49:34 -0400807#SeeAlso SkImageInfo SkPixmap
808
Cary Clark8032b982017-07-28 11:04:54 -0400809##
810
811# ------------------------------------------------------------------------------
812
813#Method SkRasterHandleAllocator::Handle accessTopRasterHandle() const
Cary Clark78de7512018-02-07 07:27:09 -0500814#In Utility
815#In Property
Cary Clarkab2621d2018-01-30 10:08:57 -0500816#Line # returns context that tracks Clip and Matrix ##
Cary Clark8032b982017-07-28 11:04:54 -0400817Returns custom context that tracks the Matrix and Clip.
818
819Use Raster_Handle_Allocator to blend Skia drawing with custom drawing, typically performed
Cary Clarkbc5697d2017-10-04 14:31:33 -0400820by the host platform user interface. The custom context returned is generated by
Cary Clarkbad5ad72017-08-03 17:14:08 -0400821SkRasterHandleAllocator::MakeCanvas, which creates a custom canvas with raster storage for
Cary Clark8032b982017-07-28 11:04:54 -0400822the drawing destination.
823
Cary Clarkce101242017-09-01 15:51:02 -0400824#Return context of custom allocation ##
Cary Clark8032b982017-07-28 11:04:54 -0400825
826#Example
827#Description
828#ToDo ##
829##
830#Function
831 static void DeleteCallback(void*, void* context) {
832 delete (char*) context;
833 }
834
835 class CustomAllocator : public SkRasterHandleAllocator {
836 public:
837 bool allocHandle(const SkImageInfo& info, Rec* rec) override {
838 char* context = new char[4]{'s', 'k', 'i', 'a'};
839 rec->fReleaseProc = DeleteCallback;
840 rec->fReleaseCtx = context;
841 rec->fHandle = context;
842 rec->fPixels = context;
843 rec->fRowBytes = 4;
844 return true;
845 }
846
847 void updateHandle(Handle handle, const SkMatrix& ctm, const SkIRect& clip_bounds) override {
848 // apply canvas matrix and clip to custom environment
849 }
850 };
851
852##
853 void draw(SkCanvas* canvas) {
854 const SkImageInfo info = SkImageInfo::MakeN32Premul(1, 1);
855 std::unique_ptr<SkCanvas> c2 =
856 SkRasterHandleAllocator::MakeCanvas(std::unique_ptr<CustomAllocator>(
857 new CustomAllocator()), info);
858 char* context = (char*) c2->accessTopRasterHandle();
859 SkDebugf("context = %.4s\n", context);
860
861 }
862 #StdOut
863 context = skia
864 ##
865 #ToDo skstd::make_unique could not be used because def is private -- note to fix in c++14? ##
866##
867
868#SeeAlso SkRasterHandleAllocator
869
870##
871
872# ------------------------------------------------------------------------------
Cary Clark78de7512018-02-07 07:27:09 -0500873#Subtopic Pixels
874#Populate
875#Line # read and write pixel values ##
876##
Cary Clark8032b982017-07-28 11:04:54 -0400877
878#Method bool peekPixels(SkPixmap* pixmap)
Cary Clark78de7512018-02-07 07:27:09 -0500879#In Pixels
Cary Clarkab2621d2018-01-30 10:08:57 -0500880#Line # returns if Canvas has direct access to its pixels ##
Cary Clark8032b982017-07-28 11:04:54 -0400881Returns true if Canvas has direct access to its pixels.
882
Cary Clarkf05bdda2017-08-24 12:59:48 -0400883Pixels are readable when Device is raster. Pixels are not readable when Canvas
Cary Clarkbad5ad72017-08-03 17:14:08 -0400884is returned from GPU_Surface, returned by SkDocument::beginPage, returned by
Cary Clarkf05bdda2017-08-24 12:59:48 -0400885SkPictureRecorder::beginRecording, or Canvas is the base of a utility class
Brian Osman46fe9c72018-03-09 15:44:34 -0500886like SkDebugCanvas.
Cary Clark8032b982017-07-28 11:04:54 -0400887
Cary Clarkf05bdda2017-08-24 12:59:48 -0400888pixmap is valid only while Canvas is in scope and unchanged. Any
Cary Clarkbad5ad72017-08-03 17:14:08 -0400889Canvas or Surface call may invalidate the pixmap values.
Cary Clark8032b982017-07-28 11:04:54 -0400890
Cary Clarkbc5697d2017-10-04 14:31:33 -0400891#Param pixmap storage for pixel state if pixels are readable; otherwise, ignored ##
Cary Clark8032b982017-07-28 11:04:54 -0400892
Cary Clarkbad5ad72017-08-03 17:14:08 -0400893#Return true if Canvas has direct access to pixels ##
Cary Clark8032b982017-07-28 11:04:54 -0400894
895#Example
896 SkPixmap pixmap;
897 if (canvas->peekPixels(&pixmap)) {
898 SkDebugf("width=%d height=%d\n", pixmap.bounds().width(), pixmap.bounds().height());
899 }
900 #StdOut
901 width=256 height=256
902 ##
903##
904
Cary Clark2ade9972017-11-02 17:49:34 -0400905#SeeAlso readPixels SkBitmap::peekPixels SkImage::peekPixels SkSurface::peekPixels
906
Cary Clark8032b982017-07-28 11:04:54 -0400907##
908
909# ------------------------------------------------------------------------------
910
911#Method bool readPixels(const SkImageInfo& dstInfo, void* dstPixels, size_t dstRowBytes,
912 int srcX, int srcY)
Cary Clark78de7512018-02-07 07:27:09 -0500913#In Pixels
Cary Clarkab2621d2018-01-30 10:08:57 -0500914#Line # copies and converts rectangle of pixels from Canvas ##
Cary Clark8032b982017-07-28 11:04:54 -0400915
Cary Clark154beea2017-10-26 07:58:48 -0400916Copies Rect of pixels from Canvas into dstPixels. Matrix and Clip are
Herb Derbyefe39bc2018-05-01 17:06:20 -0400917ignored.
Cary Clark6fc50412017-09-21 12:31:06 -0400918
Cary Clarka560c472017-11-27 10:44:06 -0500919Source Rect corners are (srcX, srcY) and (imageInfo().width(), imageInfo().height()).
920Destination Rect corners are (0, 0) and (dstInfo.width(), dstInfo.height()).
Cary Clark6fc50412017-09-21 12:31:06 -0400921Copies each readable pixel intersecting both rectangles, without scaling,
Cary Clarkf05bdda2017-08-24 12:59:48 -0400922converting to dstInfo.colorType() and dstInfo.alphaType() if required.
Cary Clark8032b982017-07-28 11:04:54 -0400923
Cary Clarkf05bdda2017-08-24 12:59:48 -0400924Pixels are readable when Device is raster, or backed by a GPU.
925Pixels are not readable when SkCanvas is returned by SkDocument::beginPage,
926returned by SkPictureRecorder::beginRecording, or Canvas is the base of a utility
Brian Osman46fe9c72018-03-09 15:44:34 -0500927class like SkDebugCanvas.
Cary Clark8032b982017-07-28 11:04:54 -0400928
Cary Clarkf05bdda2017-08-24 12:59:48 -0400929The destination pixel storage must be allocated by the caller.
Cary Clark8032b982017-07-28 11:04:54 -0400930
Cary Clark2dc84ad2018-01-26 12:56:22 -0500931Pixel values are converted only if Color_Type and Alpha_Type
Cary Clarkf05bdda2017-08-24 12:59:48 -0400932do not match. Only pixels within both source and destination rectangles
Cary Clark154beea2017-10-26 07:58:48 -0400933are copied. dstPixels contents outside Rect intersection are unchanged.
Cary Clarkf05bdda2017-08-24 12:59:48 -0400934
935Pass negative values for srcX or srcY to offset pixels across or down destination.
Cary Clark8032b982017-07-28 11:04:54 -0400936
937Does not copy, and returns false if:
938
939#List
Cary Clarkf05bdda2017-08-24 12:59:48 -0400940# Source and destination rectangles do not intersect. ##
941# Canvas pixels could not be converted to dstInfo.colorType() or dstInfo.alphaType(). ##
942# Canvas pixels are not readable; for instance, Canvas is document-based. ##
Cary Clark8032b982017-07-28 11:04:54 -0400943# dstRowBytes is too small to contain one row of pixels. ##
944##
945
Cary Clark2dc84ad2018-01-26 12:56:22 -0500946#Param dstInfo width, height, Color_Type, and Alpha_Type of dstPixels ##
Cary Clarkf05bdda2017-08-24 12:59:48 -0400947#Param dstPixels storage for pixels; dstInfo.height() times dstRowBytes, or larger ##
948#Param dstRowBytes size of one destination row; dstInfo.width() times pixel size, or larger ##
949#Param srcX offset into readable pixels in x; may be negative ##
950#Param srcY offset into readable pixels in y; may be negative ##
Cary Clark8032b982017-07-28 11:04:54 -0400951
Cary Clarkbad5ad72017-08-03 17:14:08 -0400952#Return true if pixels were copied ##
Cary Clark8032b982017-07-28 11:04:54 -0400953
954#Example
Cary Clarkf05bdda2017-08-24 12:59:48 -0400955#Width 64
956#Height 64
957#Description
958 A black circle drawn on a blue background provides an image to copy.
959 readPixels copies one quarter of the canvas into each of the four corners.
Cary Clarka560c472017-11-27 10:44:06 -0500960 The copied quarter circles overdraw the original circle.
Cary Clarkf05bdda2017-08-24 12:59:48 -0400961##
962 canvas->clear(SK_ColorBLUE);
963 SkPaint paint;
964 canvas->drawCircle(32, 32, 28, paint);
965 SkImageInfo info = SkImageInfo::Make(64, 64, kBGRA_8888_SkColorType, kPremul_SkAlphaType);
966 sk_sp<SkData> data(SkData::MakeUninitialized(info.minRowBytes() * info.height()));
967 sk_bzero(data->writable_data(), info.minRowBytes() * info.height());
968 for (int x : { 32, -32 } ) {
969 for (int y : { 32, -32 } ) {
970 canvas->readPixels(info, data->writable_data(), info.minRowBytes(), x, y);
Herb Derbyefe39bc2018-05-01 17:06:20 -0400971 }
Cary Clarkf05bdda2017-08-24 12:59:48 -0400972 }
973 sk_sp<SkImage> image = SkImage::MakeRasterData(info, data, info.minRowBytes());
974 canvas->drawImage(image, 0, 0);
975##
976
977#Example
Cary Clark8032b982017-07-28 11:04:54 -0400978#Description
Cary Clarkce101242017-09-01 15:51:02 -0400979 Canvas returned by Raster_Surface has Premultiplied pixel values.
980 clear() takes Unpremultiplied input with Color_Alpha equal 0x80
981 and Color_RGB equal 0x55, 0xAA, 0xFF. Color_RGB is multiplied by Color_Alpha
982 to generate Premultiplied value 0x802B5580. readPixels converts pixel back
983 to Unpremultiplied value 0x8056A9FF, introducing error.
Cary Clark8032b982017-07-28 11:04:54 -0400984##
985 canvas->clear(0x8055aaff);
986 for (SkAlphaType alphaType : { kPremul_SkAlphaType, kUnpremul_SkAlphaType } ) {
987 uint32_t pixel = 0;
988 SkImageInfo info = SkImageInfo::Make(1, 1, kBGRA_8888_SkColorType, alphaType);
989 if (canvas->readPixels(info, &pixel, 4, 0, 0)) {
990 SkDebugf("pixel = %08x\n", pixel);
991 }
992 }
993
994 #StdOut
995 pixel = 802b5580
996 pixel = 8056a9ff
997 ##
998##
999
Cary Clark2ade9972017-11-02 17:49:34 -04001000#SeeAlso peekPixels writePixels drawBitmap drawImage SkBitmap::readPixels SkPixmap::readPixels SkImage::readPixels SkSurface::readPixels
Cary Clark8032b982017-07-28 11:04:54 -04001001
1002##
1003
1004# ------------------------------------------------------------------------------
1005
1006#Method bool readPixels(const SkPixmap& pixmap, int srcX, int srcY)
1007
Cary Clark154beea2017-10-26 07:58:48 -04001008Copies Rect of pixels from Canvas into pixmap. Matrix and Clip are
Cary Clarka560c472017-11-27 10:44:06 -05001009ignored.
Cary Clark6fc50412017-09-21 12:31:06 -04001010
Cary Clarka560c472017-11-27 10:44:06 -05001011Source Rect corners are (srcX, srcY) and (imageInfo().width(), imageInfo().height()).
1012Destination Rect corners are (0, 0) and (pixmap.width(), pixmap.height()).
Cary Clark6fc50412017-09-21 12:31:06 -04001013Copies each readable pixel intersecting both rectangles, without scaling,
Cary Clarkf05bdda2017-08-24 12:59:48 -04001014converting to pixmap.colorType() and pixmap.alphaType() if required.
Cary Clark8032b982017-07-28 11:04:54 -04001015
Cary Clarkf05bdda2017-08-24 12:59:48 -04001016Pixels are readable when Device is raster, or backed by a GPU.
1017Pixels are not readable when SkCanvas is returned by SkDocument::beginPage,
1018returned by SkPictureRecorder::beginRecording, or Canvas is the base of a utility
Brian Osman46fe9c72018-03-09 15:44:34 -05001019class like SkDebugCanvas.
Cary Clark8032b982017-07-28 11:04:54 -04001020
Cary Clark6fc50412017-09-21 12:31:06 -04001021Caller must allocate pixel storage in pixmap if needed.
Cary Clark8032b982017-07-28 11:04:54 -04001022
Cary Clark2dc84ad2018-01-26 12:56:22 -05001023Pixel values are converted only if Color_Type and Alpha_Type
Cary Clark154beea2017-10-26 07:58:48 -04001024do not match. Only pixels within both source and destination Rects
1025are copied. pixmap pixels contents outside Rect intersection are unchanged.
Cary Clarkf05bdda2017-08-24 12:59:48 -04001026
1027Pass negative values for srcX or srcY to offset pixels across or down pixmap.
Cary Clark8032b982017-07-28 11:04:54 -04001028
1029Does not copy, and returns false if:
1030
1031#List
Cary Clarkf05bdda2017-08-24 12:59:48 -04001032# Source and destination rectangles do not intersect. ##
1033# Canvas pixels could not be converted to pixmap.colorType() or pixmap.alphaType(). ##
1034# Canvas pixels are not readable; for instance, Canvas is document-based. ##
1035# Pixmap pixels could not be allocated. ##
1036# pixmap.rowBytes() is too small to contain one row of pixels. ##
Cary Clark8032b982017-07-28 11:04:54 -04001037##
1038
Cary Clarkbad5ad72017-08-03 17:14:08 -04001039#Param pixmap storage for pixels copied from Canvas ##
Cary Clarkf05bdda2017-08-24 12:59:48 -04001040#Param srcX offset into readable pixels in x; may be negative ##
1041#Param srcY offset into readable pixels in y; may be negative ##
Cary Clark8032b982017-07-28 11:04:54 -04001042
Cary Clarkbad5ad72017-08-03 17:14:08 -04001043#Return true if pixels were copied ##
Cary Clark8032b982017-07-28 11:04:54 -04001044
1045#Example
Cary Clarkf05bdda2017-08-24 12:59:48 -04001046 #Description
Cary Clarkce101242017-09-01 15:51:02 -04001047 clear() takes Unpremultiplied input with Color_Alpha equal 0x80
1048 and Color_RGB equal 0x55, 0xAA, 0xFF. Color_RGB is multiplied by Color_Alpha
1049 to generate Premultiplied value 0x802B5580.
Cary Clarkf05bdda2017-08-24 12:59:48 -04001050 ##
1051 void draw(SkCanvas* canvas) {
1052 canvas->clear(0x8055aaff);
1053 uint32_t pixels[1] = { 0 };
1054 SkPixmap pixmap(SkImageInfo::MakeN32Premul(1, 1), pixels, 4);
1055 canvas->readPixels(pixmap, 0, 0);
1056 SkDebugf("pixel = %08x\n", pixels[0]);
1057 }
Cary Clark8032b982017-07-28 11:04:54 -04001058 #StdOut
1059 pixel = 802b5580
1060 ##
1061##
1062
Cary Clark2ade9972017-11-02 17:49:34 -04001063#SeeAlso peekPixels writePixels drawBitmap drawImage SkBitmap::readPixels SkPixmap::readPixels SkImage::readPixels SkSurface::readPixels
Cary Clark8032b982017-07-28 11:04:54 -04001064
1065##
1066
1067# ------------------------------------------------------------------------------
1068
1069#Method bool readPixels(const SkBitmap& bitmap, int srcX, int srcY)
1070
Cary Clark154beea2017-10-26 07:58:48 -04001071Copies Rect of pixels from Canvas into bitmap. Matrix and Clip are
Cary Clarka560c472017-11-27 10:44:06 -05001072ignored.
Cary Clark6fc50412017-09-21 12:31:06 -04001073
Cary Clarka560c472017-11-27 10:44:06 -05001074Source Rect corners are (srcX, srcY) and (imageInfo().width(), imageInfo().height()).
Cary Clark154beea2017-10-26 07:58:48 -04001075Destination Rect corners are (0, 0) and (bitmap.width(), bitmap.height()).
Cary Clarkf05bdda2017-08-24 12:59:48 -04001076Copies each readable pixel intersecting both rectangles, without scaling,
1077converting to bitmap.colorType() and bitmap.alphaType() if required.
Cary Clark8032b982017-07-28 11:04:54 -04001078
Cary Clarkf05bdda2017-08-24 12:59:48 -04001079Pixels are readable when Device is raster, or backed by a GPU.
1080Pixels are not readable when SkCanvas is returned by SkDocument::beginPage,
1081returned by SkPictureRecorder::beginRecording, or Canvas is the base of a utility
Brian Osman46fe9c72018-03-09 15:44:34 -05001082class like SkDebugCanvas.
Cary Clark8032b982017-07-28 11:04:54 -04001083
Cary Clark6fc50412017-09-21 12:31:06 -04001084Caller must allocate pixel storage in bitmap if needed.
Cary Clarkf05bdda2017-08-24 12:59:48 -04001085
Cary Clark2dc84ad2018-01-26 12:56:22 -05001086Bitmap values are converted only if Color_Type and Alpha_Type
Cary Clarkf05bdda2017-08-24 12:59:48 -04001087do not match. Only pixels within both source and destination rectangles
Cary Clark154beea2017-10-26 07:58:48 -04001088are copied. Bitmap pixels outside Rect intersection are unchanged.
Cary Clarkf05bdda2017-08-24 12:59:48 -04001089
1090Pass negative values for srcX or srcY to offset pixels across or down bitmap.
Cary Clark8032b982017-07-28 11:04:54 -04001091
1092Does not copy, and returns false if:
1093
1094#List
Cary Clarkf05bdda2017-08-24 12:59:48 -04001095# Source and destination rectangles do not intersect. ##
1096# Canvas pixels could not be converted to bitmap.colorType() or bitmap.alphaType(). ##
1097# Canvas pixels are not readable; for instance, Canvas is document-based. ##
Cary Clark8032b982017-07-28 11:04:54 -04001098# bitmap pixels could not be allocated. ##
Cary Clarkf05bdda2017-08-24 12:59:48 -04001099# bitmap.rowBytes() is too small to contain one row of pixels. ##
Cary Clark8032b982017-07-28 11:04:54 -04001100##
1101
Cary Clarkbad5ad72017-08-03 17:14:08 -04001102#Param bitmap storage for pixels copied from Canvas ##
Cary Clarkf05bdda2017-08-24 12:59:48 -04001103#Param srcX offset into readable pixels in x; may be negative ##
1104#Param srcY offset into readable pixels in y; may be negative ##
Cary Clark8032b982017-07-28 11:04:54 -04001105
Cary Clarkbad5ad72017-08-03 17:14:08 -04001106#Return true if pixels were copied ##
Cary Clark8032b982017-07-28 11:04:54 -04001107
1108#Example
Cary Clarkf05bdda2017-08-24 12:59:48 -04001109 #Description
Cary Clarkce101242017-09-01 15:51:02 -04001110 clear() takes Unpremultiplied input with Color_Alpha equal 0x80
1111 and Color_RGB equal 0x55, 0xAA, 0xFF. Color_RGB is multiplied by Color_Alpha
1112 to generate Premultiplied value 0x802B5580.
Cary Clarkf05bdda2017-08-24 12:59:48 -04001113 ##
Cary Clark8032b982017-07-28 11:04:54 -04001114void draw(SkCanvas* canvas) {
1115 canvas->clear(0x8055aaff);
1116 SkBitmap bitmap;
1117 bitmap.allocPixels(SkImageInfo::MakeN32Premul(1, 1));
1118 canvas->readPixels(bitmap, 0, 0);
1119 SkDebugf("pixel = %08x\n", bitmap.getAddr32(0, 0)[0]);
1120}
1121 #StdOut
1122 pixel = 802b5580
1123 ##
1124##
1125
Cary Clark2ade9972017-11-02 17:49:34 -04001126#SeeAlso peekPixels writePixels drawBitmap drawImage SkBitmap::readPixels SkPixmap::readPixels SkImage::readPixels SkSurface::readPixels
Cary Clark8032b982017-07-28 11:04:54 -04001127
1128##
1129
1130# ------------------------------------------------------------------------------
1131
1132#Method bool writePixels(const SkImageInfo& info, const void* pixels, size_t rowBytes, int x, int y)
Cary Clark78de7512018-02-07 07:27:09 -05001133#In Pixels
Cary Clarkab2621d2018-01-30 10:08:57 -05001134#Line # copies and converts rectangle of pixels to Canvas ##
Cary Clark154beea2017-10-26 07:58:48 -04001135Copies Rect from pixels to Canvas. Matrix and Clip are ignored.
1136Source Rect corners are (0, 0) and (info.width(), info.height()).
1137Destination Rect corners are (x, y) and
1138(imageInfo().width(), imageInfo().height()).
Cary Clark6fc50412017-09-21 12:31:06 -04001139
1140Copies each readable pixel intersecting both rectangles, without scaling,
Cary Clark154beea2017-10-26 07:58:48 -04001141converting to imageInfo().colorType() and imageInfo().alphaType() if required.
Cary Clark8032b982017-07-28 11:04:54 -04001142
Cary Clarkf05bdda2017-08-24 12:59:48 -04001143Pixels are writable when Device is raster, or backed by a GPU.
1144Pixels are not writable when SkCanvas is returned by SkDocument::beginPage,
1145returned by SkPictureRecorder::beginRecording, or Canvas is the base of a utility
Brian Osman46fe9c72018-03-09 15:44:34 -05001146class like SkDebugCanvas.
Cary Clark8032b982017-07-28 11:04:54 -04001147
Cary Clark2dc84ad2018-01-26 12:56:22 -05001148Pixel values are converted only if Color_Type and Alpha_Type
Cary Clarkf05bdda2017-08-24 12:59:48 -04001149do not match. Only pixels within both source and destination rectangles
Cary Clark154beea2017-10-26 07:58:48 -04001150are copied. Canvas pixels outside Rect intersection are unchanged.
Cary Clark8032b982017-07-28 11:04:54 -04001151
Cary Clarkf05bdda2017-08-24 12:59:48 -04001152Pass negative values for x or y to offset pixels to the left or
1153above Canvas pixels.
Cary Clark8032b982017-07-28 11:04:54 -04001154
1155Does not copy, and returns false if:
1156
1157#List
Cary Clarkf05bdda2017-08-24 12:59:48 -04001158# Source and destination rectangles do not intersect. ##
Cary Clarkac47b882018-01-11 10:35:44 -05001159# pixels could not be converted to Canvas imageInfo().colorType() or
1160 imageInfo().alphaType(). ##
Cary Clark8032b982017-07-28 11:04:54 -04001161# Canvas pixels are not writable; for instance, Canvas is document-based. ##
1162# rowBytes is too small to contain one row of pixels. ##
1163##
1164
Cary Clark2dc84ad2018-01-26 12:56:22 -05001165#Param info width, height, Color_Type, and Alpha_Type of pixels ##
Cary Clarkf05bdda2017-08-24 12:59:48 -04001166#Param pixels pixels to copy, of size info.height() times rowBytes, or larger ##
Cary Clarkd0530ba2017-09-14 11:25:39 -04001167#Param rowBytes size of one row of pixels; info.width() times pixel size, or larger ##
Cary Clarkf05bdda2017-08-24 12:59:48 -04001168#Param x offset into Canvas writable pixels in x; may be negative ##
1169#Param y offset into Canvas writable pixels in y; may be negative ##
Cary Clark8032b982017-07-28 11:04:54 -04001170
Cary Clarkbad5ad72017-08-03 17:14:08 -04001171#Return true if pixels were written to Canvas ##
Cary Clark8032b982017-07-28 11:04:54 -04001172
1173#Example
1174 SkImageInfo imageInfo = SkImageInfo::MakeN32(256, 1, kPremul_SkAlphaType);
1175 for (int y = 0; y < 256; ++y) {
1176 uint32_t pixels[256];
1177 for (int x = 0; x < 256; ++x) {
1178 pixels[x] = SkColorSetARGB(x, x + y, x, x - y);
1179 }
1180 canvas->writePixels(imageInfo, &pixels, sizeof(pixels), 0, y);
1181 }
1182##
1183
Cary Clark2ade9972017-11-02 17:49:34 -04001184#SeeAlso readPixels drawBitmap drawImage SkBitmap::writePixels
Cary Clark8032b982017-07-28 11:04:54 -04001185
1186##
1187
1188# ------------------------------------------------------------------------------
1189
1190#Method bool writePixels(const SkBitmap& bitmap, int x, int y)
1191
Cary Clark154beea2017-10-26 07:58:48 -04001192Copies Rect from pixels to Canvas. Matrix and Clip are ignored.
1193Source Rect corners are (0, 0) and (bitmap.width(), bitmap.height()).
Cary Clark6fc50412017-09-21 12:31:06 -04001194
Cary Clark154beea2017-10-26 07:58:48 -04001195Destination Rect corners are (x, y) and
1196(imageInfo().width(), imageInfo().height()).
Cary Clark6fc50412017-09-21 12:31:06 -04001197
1198Copies each readable pixel intersecting both rectangles, without scaling,
Cary Clark154beea2017-10-26 07:58:48 -04001199converting to imageInfo().colorType() and imageInfo().alphaType() if required.
Cary Clark8032b982017-07-28 11:04:54 -04001200
Cary Clarkf05bdda2017-08-24 12:59:48 -04001201Pixels are writable when Device is raster, or backed by a GPU.
1202Pixels are not writable when SkCanvas is returned by SkDocument::beginPage,
1203returned by SkPictureRecorder::beginRecording, or Canvas is the base of a utility
Brian Osman46fe9c72018-03-09 15:44:34 -05001204class like SkDebugCanvas.
Cary Clark8032b982017-07-28 11:04:54 -04001205
Cary Clark2dc84ad2018-01-26 12:56:22 -05001206Pixel values are converted only if Color_Type and Alpha_Type
Cary Clarkf05bdda2017-08-24 12:59:48 -04001207do not match. Only pixels within both source and destination rectangles
Cary Clark154beea2017-10-26 07:58:48 -04001208are copied. Canvas pixels outside Rect intersection are unchanged.
Cary Clark8032b982017-07-28 11:04:54 -04001209
Cary Clarkf05bdda2017-08-24 12:59:48 -04001210Pass negative values for x or y to offset pixels to the left or
1211above Canvas pixels.
Cary Clark8032b982017-07-28 11:04:54 -04001212
1213Does not copy, and returns false if:
1214
1215#List
Cary Clarkf05bdda2017-08-24 12:59:48 -04001216# Source and destination rectangles do not intersect. ##
Cary Clark8032b982017-07-28 11:04:54 -04001217# bitmap does not have allocated pixels. ##
Cary Clarkac47b882018-01-11 10:35:44 -05001218# bitmap pixels could not be converted to Canvas imageInfo().colorType() or
1219 imageInfo().alphaType(). ##
Cary Clarkce101242017-09-01 15:51:02 -04001220# Canvas pixels are not writable; for instance, Canvas is document based. ##
Cary Clark8032b982017-07-28 11:04:54 -04001221# bitmap pixels are inaccessible; for instance, bitmap wraps a texture. ##
1222##
1223
Cary Clarkbad5ad72017-08-03 17:14:08 -04001224#Param bitmap contains pixels copied to Canvas ##
Cary Clarkf05bdda2017-08-24 12:59:48 -04001225#Param x offset into Canvas writable pixels in x; may be negative ##
1226#Param y offset into Canvas writable pixels in y; may be negative ##
Cary Clark8032b982017-07-28 11:04:54 -04001227
Cary Clarkbad5ad72017-08-03 17:14:08 -04001228#Return true if pixels were written to Canvas ##
Cary Clark8032b982017-07-28 11:04:54 -04001229
1230#Example
1231void draw(SkCanvas* canvas) {
1232 SkImageInfo imageInfo = SkImageInfo::MakeN32Premul(2, 2);
1233 SkBitmap bitmap;
1234 bitmap.setInfo(imageInfo);
1235 uint32_t pixels[4];
1236 bitmap.setPixels(pixels);
1237 for (int y = 0; y < 256; y += 2) {
1238 for (int x = 0; x < 256; x += 2) {
1239 pixels[0] = SkColorSetRGB(x, y, x | y);
1240 pixels[1] = SkColorSetRGB(x ^ y, y, x);
1241 pixels[2] = SkColorSetRGB(x, x & y, y);
1242 pixels[3] = SkColorSetRGB(~x, ~y, x);
1243 canvas->writePixels(bitmap, x, y);
1244 }
1245 }
1246}
1247##
1248
Cary Clark2ade9972017-11-02 17:49:34 -04001249#SeeAlso readPixels drawBitmap drawImage SkBitmap::writePixels
Cary Clark8032b982017-07-28 11:04:54 -04001250
1251##
1252
1253# ------------------------------------------------------------------------------
Cary Clark08895c42018-02-01 09:37:32 -05001254#Subtopic State_Stack
1255#Line # stack of state for hierarchical drawing ##
Cary Clark8032b982017-07-28 11:04:54 -04001256
1257Canvas maintains a stack of state that allows hierarchical drawing, commonly used
Cary Clarkbad5ad72017-08-03 17:14:08 -04001258to implement windows and views. The initial state has an identity matrix and and
1259an infinite clip. Even with a wide-open clip, drawing is constrained by the
1260bounds of the Canvas Surface or Device.
Cary Clark8032b982017-07-28 11:04:54 -04001261
1262Canvas savable state consists of Clip, Matrix, and Draw_Filter.
1263Clip describes the area that may be drawn to.
1264Matrix transforms the geometry.
1265Draw_Filter (deprecated on most platforms) modifies the paint before drawing.
1266
1267save(), saveLayer, saveLayerPreserveLCDTextRequests, and saveLayerAlpha
1268save state and return the depth of the stack.
1269
Cary Clarkbad5ad72017-08-03 17:14:08 -04001270restore(), restoreToCount, and ~SkCanvas() revert state to its value when saved.
Cary Clark8032b982017-07-28 11:04:54 -04001271
1272Each state on the stack intersects Clip with the previous Clip,
1273and concatenates Matrix with the previous Matrix.
1274The intersected Clip makes the drawing area the same or smaller;
1275the concatenated Matrix may move the origin and potentially scale or rotate
1276the coordinate space.
1277
1278Canvas does not require balancing the state stack but it is a good idea
1279to do so. Calling save() without restore() will eventually cause Skia to fail;
1280mismatched save() and restore() create hard to find bugs.
1281
1282It is not possible to use state to draw outside of the clip defined by the
1283previous state.
1284
1285#Example
1286#Description
1287Draw to ever smaller clips; then restore drawing to full canvas.
1288Note that the second clipRect is not permitted to enlarge Clip.
1289##
1290#Height 160
Cary Clarkbad5ad72017-08-03 17:14:08 -04001291void draw(SkCanvas* canvas) {
1292 SkPaint paint;
Herb Derbyefe39bc2018-05-01 17:06:20 -04001293 canvas->save(); // records stack depth to restore
Cary Clarkbad5ad72017-08-03 17:14:08 -04001294 canvas->clipRect(SkRect::MakeWH(100, 100)); // constrains drawing to clip
1295 canvas->clear(SK_ColorRED); // draws to limit of clip
Herb Derbyefe39bc2018-05-01 17:06:20 -04001296 canvas->save(); // records stack depth to restore
Cary Clarkbad5ad72017-08-03 17:14:08 -04001297 canvas->clipRect(SkRect::MakeWH(50, 150)); // Rect below 100 is ignored
1298 canvas->clear(SK_ColorBLUE); // draws to smaller clip
1299 canvas->restore(); // enlarges clip
1300 canvas->drawLine(20, 20, 150, 150, paint); // line below 100 is not drawn
1301 canvas->restore(); // enlarges clip
1302 canvas->drawLine(150, 20, 50, 120, paint); // line below 100 is drawn
Cary Clark8032b982017-07-28 11:04:54 -04001303}
Herb Derbyefe39bc2018-05-01 17:06:20 -04001304##
Cary Clark8032b982017-07-28 11:04:54 -04001305
1306Each Clip uses the current Matrix for its coordinates.
1307
1308#Example
1309#Description
1310While clipRect is given the same rectangle twice, Matrix makes the second
1311clipRect draw at half the size of the first.
1312##
1313#Height 128
Cary Clarkbad5ad72017-08-03 17:14:08 -04001314void draw(SkCanvas* canvas) {
1315 canvas->clipRect(SkRect::MakeWH(100, 100));
1316 canvas->clear(SK_ColorRED);
1317 canvas->scale(.5, .5);
1318 canvas->clipRect(SkRect::MakeWH(100, 100));
1319 canvas->clear(SK_ColorBLUE);
Cary Clark8032b982017-07-28 11:04:54 -04001320}
1321##
1322
1323#SeeAlso save() saveLayer saveLayerPreserveLCDTextRequests saveLayerAlpha restore() restoreToCount
1324
1325#Method int save()
1326
Cary Clarkab2621d2018-01-30 10:08:57 -05001327#In State_Stack
1328#Line # saves Clip and Matrix on stack ##
Cary 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
Herb Derbyefe39bc2018-05-01 17:06:20 -04001344#Description
Cary Clark8032b982017-07-28 11:04:54 -04001345The black square is translated 50 pixels down and to the right.
1346Restoring Canvas state removes translate() from Canvas stack;
1347the red square is not translated, and is drawn at the origin.
1348##
1349#Height 100
1350void draw(SkCanvas* canvas) {
1351 SkPaint paint;
1352 SkRect rect = { 0, 0, 25, 25 };
1353 canvas->drawRect(rect, paint);
1354 canvas->save();
1355 canvas->translate(50, 50);
1356 canvas->drawRect(rect, paint);
1357 canvas->restore();
1358 paint.setColor(SK_ColorRED);
1359 canvas->drawRect(rect, paint);
1360}
1361##
1362
Cary Clark2ade9972017-11-02 17:49:34 -04001363#SeeAlso saveLayer saveLayerPreserveLCDTextRequests saveLayerAlpha restore() restoreToCount
Cary Clark8032b982017-07-28 11:04:54 -04001364
1365##
1366
1367# ------------------------------------------------------------------------------
Cary Clark8032b982017-07-28 11:04:54 -04001368
1369#Method void restore()
1370
Cary Clarkab2621d2018-01-30 10:08:57 -05001371#In State_Stack
1372#Line # restores changes to Clip and Matrix, pops save stack ##
Cary Clark8032b982017-07-28 11:04:54 -04001373Removes changes to Matrix, Clip, and Draw_Filter since Canvas state was
Herb Derbyefe39bc2018-05-01 17:06:20 -04001374last saved. The state is removed from the stack.
Cary Clark8032b982017-07-28 11:04:54 -04001375
Herb Derbyefe39bc2018-05-01 17:06:20 -04001376Does nothing if the stack is empty.
Cary Clark8032b982017-07-28 11:04:54 -04001377
1378#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04001379void draw(SkCanvas* canvas) {
1380 SkCanvas simple;
1381 SkDebugf("depth = %d\n", simple.getSaveCount());
1382 simple.restore();
1383 SkDebugf("depth = %d\n", simple.getSaveCount());
Cary Clark8032b982017-07-28 11:04:54 -04001384}
1385##
1386
Cary Clark2ade9972017-11-02 17:49:34 -04001387#SeeAlso save() saveLayer saveLayerPreserveLCDTextRequests saveLayerAlpha restoreToCount
1388
Cary Clark8032b982017-07-28 11:04:54 -04001389##
1390
1391# ------------------------------------------------------------------------------
1392
1393#Method int getSaveCount() const
1394
Cary Clarkab2621d2018-01-30 10:08:57 -05001395#In State_Stack
1396#Line # returns depth of stack containing Clip and Matrix ##
Cary Clark8032b982017-07-28 11:04:54 -04001397Returns the number of saved states, each containing: Matrix, Clip, and Draw_Filter.
Herb Derbyefe39bc2018-05-01 17:06:20 -04001398Equals the number of save() calls less the number of restore() calls plus one.
Cary Clark8032b982017-07-28 11:04:54 -04001399The save count of a new canvas is one.
1400
Cary Clarkbad5ad72017-08-03 17:14:08 -04001401#Return depth of save state stack ##
Cary Clark8032b982017-07-28 11:04:54 -04001402
1403#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04001404void draw(SkCanvas* canvas) {
1405 SkCanvas simple;
1406 SkDebugf("depth = %d\n", simple.getSaveCount());
1407 simple.save();
1408 SkDebugf("depth = %d\n", simple.getSaveCount());
1409 simple.restore();
1410 SkDebugf("depth = %d\n", simple.getSaveCount());
Cary Clark8032b982017-07-28 11:04:54 -04001411}
1412#StdOut
Cary Clarkbad5ad72017-08-03 17:14:08 -04001413depth = 1
1414depth = 2
Cary Clark8032b982017-07-28 11:04:54 -04001415depth = 1
1416##
1417##
1418
Cary Clark2ade9972017-11-02 17:49:34 -04001419#SeeAlso save() restore() restoreToCount
1420
Cary Clark8032b982017-07-28 11:04:54 -04001421##
1422
1423# ------------------------------------------------------------------------------
1424
1425#Method void restoreToCount(int saveCount)
1426
Cary Clarkab2621d2018-01-30 10:08:57 -05001427#In State_Stack
1428#Line # restores changes to Clip and Matrix to given depth ##
Cary 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
Herb Derbyefe39bc2018-05-01 17:06:20 -04001432Does nothing if saveCount is greater than state stack count.
Cary Clark8032b982017-07-28 11:04:54 -04001433Restores state to initial values if saveCount is less than or equal to one.
1434
Cary Clarkbad5ad72017-08-03 17:14:08 -04001435#Param saveCount depth of state stack to restore ##
Cary Clark8032b982017-07-28 11:04:54 -04001436
1437#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04001438void draw(SkCanvas* canvas) {
1439 SkDebugf("depth = %d\n", canvas->getSaveCount());
1440 canvas->save();
1441 canvas->save();
1442 SkDebugf("depth = %d\n", canvas->getSaveCount());
1443 canvas->restoreToCount(0);
1444 SkDebugf("depth = %d\n", canvas->getSaveCount());
Cary Clark8032b982017-07-28 11:04:54 -04001445}
1446#StdOut
Cary Clarkbad5ad72017-08-03 17:14:08 -04001447depth = 1
1448depth = 3
Cary Clark8032b982017-07-28 11:04:54 -04001449depth = 1
1450##
1451##
1452
Herb Derbyefe39bc2018-05-01 17:06:20 -04001453#SeeAlso restore() getSaveCount save()
Cary Clark2ade9972017-11-02 17:49:34 -04001454
Cary Clark8032b982017-07-28 11:04:54 -04001455##
1456
Cary Clark08895c42018-02-01 09:37:32 -05001457#Subtopic State_Stack ##
Cary Clark8032b982017-07-28 11:04:54 -04001458
1459# ------------------------------------------------------------------------------
Cary Clarkce101242017-09-01 15:51:02 -04001460
Cary Clark08895c42018-02-01 09:37:32 -05001461#Subtopic Layer
Cary Clarkd0530ba2017-09-14 11:25:39 -04001462#Substitute layer
Cary Clarkce101242017-09-01 15:51:02 -04001463#Alias Layers
Cary 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
Herb Derbyefe39bc2018-05-01 17:06:20 -04001467complete, 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(),
Herb Derbyefe39bc2018-05-01 17:06:20 -04001486setMatrix, and resetMatrix. Clip may be changed by clipRect, clipRRect,
Cary Clarkce101242017-09-01 15:51:02 -04001487clipPath, clipRegion.
1488
1489Rect bounds suggests but does not define the Bitmap size. To clip drawing to
1490a specific rectangle, use clipRect.
1491
1492Optional Paint paint applies Color_Alpha, Color_Filter, Image_Filter, and
1493Blend_Mode when restore() is called.
1494
1495Call restoreToCount with returned value to restore this and subsequent saves.
1496
1497#Param bounds hint to limit the size of the Layer; may be nullptr ##
1498#Param paint graphics state for Layer; may be nullptr ##
1499
1500#Return depth of saved stack ##
1501
1502#Example
1503#Description
1504Rectangles are blurred by Image_Filter when restore() draws Layer to main
1505Canvas.
1506##
1507#Height 128
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
Herb Derbyefe39bc2018-05-01 17:06:20 -04001525#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.
Herb Derbyefe39bc2018-05-01 17:06:20 -04001553The 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.
Herb Derbyefe39bc2018-05-01 17:06:20 -04001588
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
Herb Derbyefe39bc2018-05-01 17:06:20 -04001676#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 Clarkd98f78c2018-04-26 08:32:37 -04001681#Enum SaveLayerFlagsSet
Cary Clark08895c42018-02-01 09:37:32 -05001682#Line # sets SaveLayerRec options ##
Cary Clarkce101242017-09-01 15:51:02 -04001683#Code
Cary Clarkd98f78c2018-04-26 08:32:37 -04001684 enum SaveLayerFlagsSet {
Cary Clarkce101242017-09-01 15:51:02 -04001685 kPreserveLCDText_SaveLayerFlag = 1 << 1,
1686 kInitWithPrevious_SaveLayerFlag = 1 << 2,
Mike Reed910ca0f2018-04-25 13:04:05 -04001687 kMaskAgainstCoverage_EXPERIMENTAL_DONT_USE_SaveLayerFlag = 1 << 3,
Cary Clarkce101242017-09-01 15:51:02 -04001688 kDontClipToLayer_Legacy_SaveLayerFlag = kDontClipToLayer_PrivateSaveLayerFlag,
1689 };
Cary Clarkd98f78c2018-04-26 08:32:37 -04001690
1691 typedef uint32_t SaveLayerFlags;
Cary Clarkce101242017-09-01 15:51:02 -04001692##
1693
1694SaveLayerFlags provides options that may be used in any combination in SaveLayerRec,
1695defining how Layer allocated by saveLayer operates.
1696
Cary Clarkce101242017-09-01 15:51:02 -04001697#Const kPreserveLCDText_SaveLayerFlag 2
1698 Creates Layer for LCD text. Flag is ignored if Layer Paint contains
1699 Image_Filter or Color_Filter.
1700##
1701
1702#Const kInitWithPrevious_SaveLayerFlag 4
1703 Initializes Layer with the contents of the previous Layer.
1704##
1705
Mike Reed910ca0f2018-04-25 13:04:05 -04001706#Const kMaskAgainstCoverage_EXPERIMENTAL_DONT_USE_SaveLayerFlag 8
1707 Experimental -- don't use
1708##
1709
Cary Clarkce101242017-09-01 15:51:02 -04001710#Const kDontClipToLayer_Legacy_SaveLayerFlag 0x80000000
Cary Clark4855f782018-02-06 09:41:53 -05001711#Deprecated soon
Cary Clarkce101242017-09-01 15:51:02 -04001712##
1713
1714#Example
1715#Height 160
1716#Description
1717Canvas Layer captures red and blue circles scaled up by four.
Herb Derbyefe39bc2018-05-01 17:06:20 -04001718scalePaint blends Layer back with transparency.
Cary Clarkce101242017-09-01 15:51:02 -04001719##
1720void draw(SkCanvas* canvas) {
1721 SkPaint redPaint, bluePaint, scalePaint;
1722 redPaint.setColor(SK_ColorRED);
1723 canvas->drawCircle(21, 21, 8, redPaint);
1724 bluePaint.setColor(SK_ColorBLUE);
1725 canvas->drawCircle(31, 21, 8, bluePaint);
1726 SkMatrix matrix;
1727 matrix.setScale(4, 4);
1728 scalePaint.setAlpha(0x40);
1729 scalePaint.setImageFilter(
1730 SkImageFilter::MakeMatrixFilter(matrix, kNone_SkFilterQuality, nullptr));
1731 SkCanvas::SaveLayerRec saveLayerRec(nullptr, &scalePaint,
Herb Derbyefe39bc2018-05-01 17:06:20 -04001732 SkCanvas::kInitWithPrevious_SaveLayerFlag);
Cary Clarkce101242017-09-01 15:51:02 -04001733 canvas->saveLayer(saveLayerRec);
1734 canvas->restore();
1735}
1736##
1737
Cary Clark2ade9972017-11-02 17:49:34 -04001738#SeeAlso save() restore() saveLayer saveLayerPreserveLCDTextRequests saveLayerAlpha SaveLayerRec
Cary Clarkce101242017-09-01 15:51:02 -04001739
1740#Enum ##
1741
Cary Clarka560c472017-11-27 10:44:06 -05001742#Typedef uint32_t SaveLayerFlags
1743
1744##
1745
Cary Clarkce101242017-09-01 15:51:02 -04001746#Struct SaveLayerRec
Cary Clark08895c42018-02-01 09:37:32 -05001747#Line # contains the state used to create the Layer ##
Cary Clarkce101242017-09-01 15:51:02 -04001748#Code
1749 struct SaveLayerRec {
1750 SaveLayerRec*(...
1751
1752 const SkRect* fBounds;
1753 const SkPaint* fPaint;
1754 const SkImageFilter* fBackdrop;
1755 SaveLayerFlags fSaveLayerFlags;
1756 };
1757##
1758
Herb Derbyefe39bc2018-05-01 17:06:20 -04001759SaveLayerRec contains the state used to create the Layer.
Cary Clarkce101242017-09-01 15:51:02 -04001760
1761#Member const SkRect* fBounds
1762 fBounds is used as a hint to limit the size of Layer; may be nullptr.
1763 fBounds suggests but does not define Layer size. To clip drawing to
1764 a specific rectangle, use clipRect.
1765##
1766
1767#Member const SkPaint* fPaint
1768 fPaint modifies how Layer overlays the prior Layer; may be nullptr.
1769 Color_Alpha, Blend_Mode, Color_Filter, Draw_Looper, Image_Filter, and
1770 Mask_Filter affect Layer draw.
1771##
1772
1773#Member const SkImageFilter* fBackdrop
1774 fBackdrop applies Image_Filter to the prior Layer when copying to the Layer;
1775 may be nullptr. Use kInitWithPrevious_SaveLayerFlag to copy the
1776 prior Layer without an Image_Filter.
1777##
1778
1779#Member const SkImage* fClipMask
1780 restore() clips Layer by the Color_Alpha channel of fClipMask when
1781 Layer is copied to Device. fClipMask may be nullptr. .
1782##
1783
1784#Member const SkMatrix* fClipMatrix
Herb Derbyefe39bc2018-05-01 17:06:20 -04001785 fClipMatrix transforms fClipMask before it clips Layer. If
Cary Clarkce101242017-09-01 15:51:02 -04001786 fClipMask describes a translucent gradient, it may be scaled and rotated
1787 without introducing artifacts. fClipMatrix may be nullptr.
1788##
1789
1790#Member SaveLayerFlags fSaveLayerFlags
1791 fSaveLayerFlags are used to create Layer without transparency,
1792 create Layer for LCD text, and to create Layer with the
1793 contents of the previous Layer.
1794##
1795
1796#Example
1797#Height 160
1798#Description
1799Canvas Layer captures a red Anti-aliased circle and a blue Aliased circle scaled
1800up by four. After drawing another red circle without scaling on top, the Layer is
Herb Derbyefe39bc2018-05-01 17:06:20 -04001801transferred to the main canvas.
Cary Clarkce101242017-09-01 15:51:02 -04001802##
1803void draw(SkCanvas* canvas) {
1804 SkPaint redPaint, bluePaint;
1805 redPaint.setAntiAlias(true);
1806 redPaint.setColor(SK_ColorRED);
1807 canvas->drawCircle(21, 21, 8, redPaint);
1808 bluePaint.setColor(SK_ColorBLUE);
1809 canvas->drawCircle(31, 21, 8, bluePaint);
1810 SkMatrix matrix;
1811 matrix.setScale(4, 4);
1812 auto scaler = SkImageFilter::MakeMatrixFilter(matrix, kNone_SkFilterQuality, nullptr);
Herb Derbyefe39bc2018-05-01 17:06:20 -04001813 SkCanvas::SaveLayerRec saveLayerRec(nullptr, nullptr, scaler.get(), 0);
Cary Clarkce101242017-09-01 15:51:02 -04001814 canvas->saveLayer(saveLayerRec);
1815 canvas->drawCircle(125, 85, 8, redPaint);
1816 canvas->restore();
1817}
1818##
1819
1820#Method SaveLayerRec()
1821
1822Sets fBounds, fPaint, and fBackdrop to nullptr. Clears fSaveLayerFlags.
1823
1824#Return empty SaveLayerRec ##
1825
1826#Example
1827 SkCanvas::SaveLayerRec rec1;
Mike Kleine083f7c2018-02-07 12:54:27 -05001828 rec1.fSaveLayerFlags = SkCanvas::kPreserveLCDText_SaveLayerFlag;
1829 SkCanvas::SaveLayerRec rec2(nullptr, nullptr, SkCanvas::kPreserveLCDText_SaveLayerFlag);
Cary Clarkce101242017-09-01 15:51:02 -04001830 SkDebugf("rec1 %c= rec2\n", rec1.fBounds == rec2.fBounds
1831 && rec1.fPaint == rec2.fPaint
1832 && rec1.fBackdrop == rec2.fBackdrop
1833 && rec1.fSaveLayerFlags == rec2.fSaveLayerFlags ? '=' : '!');
1834 #StdOut
1835 rec1 == rec2
1836 ##
1837##
1838
Cary Clark2ade9972017-11-02 17:49:34 -04001839#SeeAlso save() restore() saveLayer saveLayerPreserveLCDTextRequests saveLayerAlpha
1840
Cary Clarkce101242017-09-01 15:51:02 -04001841##
1842
Cary Clarkd98f78c2018-04-26 08:32:37 -04001843#Method SaveLayerRec(const SkRect* bounds, const SkPaint* paint,
1844 SaveLayerFlags saveLayerFlags = 0)
Cary Clarkce101242017-09-01 15:51:02 -04001845
1846Sets fBounds, fPaint, and fSaveLayerFlags; sets fBackdrop to nullptr.
1847
1848#Param bounds Layer dimensions; may be nullptr ##
1849#Param paint applied to Layer when overlaying prior Layer; may be nullptr ##
1850#Param saveLayerFlags SaveLayerRec options to modify Layer ##
1851
1852#Return SaveLayerRec with empty backdrop ##
1853
1854#Example
1855 SkCanvas::SaveLayerRec rec1;
1856 SkCanvas::SaveLayerRec rec2(nullptr, nullptr);
1857 SkDebugf("rec1 %c= rec2\n", rec1.fBounds == rec2.fBounds
1858 && rec1.fPaint == rec2.fPaint
1859 && rec1.fBackdrop == rec2.fBackdrop
1860 && rec1.fSaveLayerFlags == rec2.fSaveLayerFlags ? '=' : '!');
1861 #StdOut
1862 rec1 == rec2
1863 ##
1864##
1865
Cary Clark2ade9972017-11-02 17:49:34 -04001866#SeeAlso save() restore() saveLayer saveLayerPreserveLCDTextRequests saveLayerAlpha
1867
Cary Clarkce101242017-09-01 15:51:02 -04001868##
1869
1870#Method SaveLayerRec(const SkRect* bounds, const SkPaint* paint, const SkImageFilter* backdrop,
1871 SaveLayerFlags saveLayerFlags)
1872
1873Sets fBounds, fPaint, fBackdrop, and fSaveLayerFlags.
1874
1875#Param bounds Layer dimensions; may be nullptr ##
1876#Param paint applied to Layer when overlaying prior Layer;
1877 may be nullptr
1878##
1879#Param backdrop prior Layer copied with Image_Filter; may be nullptr
1880##
1881#Param saveLayerFlags SaveLayerRec options to modify Layer ##
1882
1883#Return SaveLayerRec fully specified ##
1884
1885#Example
1886 SkCanvas::SaveLayerRec rec1;
1887 SkCanvas::SaveLayerRec rec2(nullptr, nullptr, nullptr, 0);
1888 SkDebugf("rec1 %c= rec2\n", rec1.fBounds == rec2.fBounds
1889 && rec1.fPaint == rec2.fPaint
1890 && rec1.fBackdrop == rec2.fBackdrop
1891 && rec1.fSaveLayerFlags == rec2.fSaveLayerFlags ? '=' : '!');
1892 #StdOut
1893 rec1 == rec2
1894 ##
1895##
1896
Cary Clark2ade9972017-11-02 17:49:34 -04001897#SeeAlso save() restore() saveLayer saveLayerPreserveLCDTextRequests saveLayerAlpha
1898
Cary Clarkce101242017-09-01 15:51:02 -04001899##
1900
1901#Method SaveLayerRec(const SkRect* bounds, const SkPaint* paint, const SkImageFilter* backdrop,
1902 const SkImage* clipMask, const SkMatrix* clipMatrix,
1903 SaveLayerFlags saveLayerFlags)
1904
1905#Experimental
1906Not ready for general use.
1907##
1908
1909Sets fBounds, fPaint, fBackdrop, fClipMask, fClipMatrix, and fSaveLayerFlags.
1910clipMatrix uses Color_Alpha channel of image, transformed by clipMatrix, to clip
1911Layer when drawn to Canvas.
1912
Cary Clark2ade9972017-11-02 17:49:34 -04001913Implementation is not complete; has no effect if Device is GPU-backed.
Cary Clarkce101242017-09-01 15:51:02 -04001914
1915#Param bounds Layer dimensions; may be nullptr ##
1916#Param paint graphics state applied to Layer when overlaying prior
1917 Layer; may be nullptr
1918##
1919#Param backdrop prior Layer copied with Image_Filter;
1920 may be nullptr
1921##
1922#Param clipMask clip applied to Layer; may be nullptr ##
1923#Param clipMatrix matrix applied to clipMask; may be nullptr to use
Herb Derbyefe39bc2018-05-01 17:06:20 -04001924 identity matrix
Cary Clarkce101242017-09-01 15:51:02 -04001925##
1926#Param saveLayerFlags SaveLayerRec options to modify Layer ##
1927
1928#Return SaveLayerRec fully specified ##
1929
Cary Clark2ade9972017-11-02 17:49:34 -04001930#SeeAlso save() restore() saveLayer saveLayerPreserveLCDTextRequests saveLayerAlpha
Cary Clarkce101242017-09-01 15:51:02 -04001931
1932##
1933
1934#Struct ##
1935
1936#Method int saveLayer(const SaveLayerRec& layerRec)
1937
Cary Clarkab2621d2018-01-30 10:08:57 -05001938#In Layer
Cary Clarkce101242017-09-01 15:51:02 -04001939Saves Matrix, Clip, and Draw_Filter (Draw_Filter deprecated on most platforms),
1940and allocates Bitmap for subsequent drawing.
1941
1942Calling restore() discards changes to Matrix, Clip, and Draw_Filter,
1943and blends Bitmap with Color_Alpha opacity onto the prior Layer.
1944
1945Matrix may be changed by translate(), scale(), rotate(), skew(), concat(),
1946setMatrix, and resetMatrix. Clip may be changed by clipRect, clipRRect,
1947clipPath, clipRegion.
1948
1949SaveLayerRec contains the state used to create the Layer.
1950
1951Call restoreToCount with returned value to restore this and subsequent saves.
1952
1953#Param layerRec Layer state ##
1954
1955#Return depth of save state stack ##
1956
1957#Example
1958#Description
1959The example draws an image, and saves it into a Layer with kInitWithPrevious_SaveLayerFlag.
1960Next it punches a hole in Layer and restore with SkBlendMode::kPlus.
1961Where Layer was cleared, the original image will draw unchanged.
1962Outside of the circle the mandrill is brightened.
1963##
1964 #Image 3
Hal Canaryc465d132017-12-08 10:21:31 -05001965 // sk_sp<SkImage> image = GetResourceAsImage("images/mandrill_256.png");
Cary Clarkce101242017-09-01 15:51:02 -04001966 canvas->drawImage(image, 0, 0, nullptr);
1967 SkCanvas::SaveLayerRec rec;
1968 SkPaint paint;
1969 paint.setBlendMode(SkBlendMode::kPlus);
1970 rec.fSaveLayerFlags = SkCanvas::kInitWithPrevious_SaveLayerFlag;
1971 rec.fPaint = &paint;
1972 canvas->saveLayer(rec);
1973 paint.setBlendMode(SkBlendMode::kClear);
1974 canvas->drawCircle(128, 128, 96, paint);
1975 canvas->restore();
1976##
1977
1978#ToDo above example needs to replace GetResourceAsImage with way to select image in fiddle ##
1979
Cary Clark2ade9972017-11-02 17:49:34 -04001980#SeeAlso save() restore() saveLayer saveLayerPreserveLCDTextRequests saveLayerAlpha
1981
Cary Clarkce101242017-09-01 15:51:02 -04001982##
1983
Cary Clark08895c42018-02-01 09:37:32 -05001984#Subtopic Layer ##
Cary Clarkce101242017-09-01 15:51:02 -04001985
1986# ------------------------------------------------------------------------------
Cary Clark08895c42018-02-01 09:37:32 -05001987#Subtopic Matrix
1988#Line # coordinate transformation ##
Cary Clark8032b982017-07-28 11:04:54 -04001989
1990#Method void translate(SkScalar dx, SkScalar dy)
1991
Cary Clarkab2621d2018-01-30 10:08:57 -05001992#In Matrix
1993#Line # translates Matrix ##
Cary Clark8032b982017-07-28 11:04:54 -04001994Translate Matrix by dx along the x-axis and dy along the y-axis.
1995
1996Mathematically, replace Matrix with a translation matrix
Herb Derbyefe39bc2018-05-01 17:06:20 -04001997Premultiplied with Matrix.
Cary Clark8032b982017-07-28 11:04:54 -04001998
1999This has the effect of moving the drawing by (dx, dy) before transforming
2000the result with Matrix.
2001
Cary Clarkbad5ad72017-08-03 17:14:08 -04002002#Param dx distance to translate in x ##
2003#Param dy distance to translate in y ##
Cary Clark8032b982017-07-28 11:04:54 -04002004
2005#Example
2006#Height 128
2007#Description
2008scale() followed by translate() produces different results from translate() followed
Herb Derbyefe39bc2018-05-01 17:06:20 -04002009by scale().
Cary Clark8032b982017-07-28 11:04:54 -04002010
2011The blue stroke follows translate of (50, 50); a black
Herb Derbyefe39bc2018-05-01 17:06:20 -04002012fill follows scale of (2, 1/2.f). After restoring the clip, which resets
Cary Clark8032b982017-07-28 11:04:54 -04002013Matrix, a red frame follows the same scale of (2, 1/2.f); a gray fill
2014follows translate of (50, 50).
2015##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002016void draw(SkCanvas* canvas) {
2017 SkPaint filledPaint;
2018 SkPaint outlinePaint;
2019 outlinePaint.setStyle(SkPaint::kStroke_Style);
2020 outlinePaint.setColor(SK_ColorBLUE);
2021 canvas->save();
2022 canvas->translate(50, 50);
2023 canvas->drawCircle(28, 28, 15, outlinePaint); // blue center: (50+28, 50+28)
2024 canvas->scale(2, 1/2.f);
2025 canvas->drawCircle(28, 28, 15, filledPaint); // black center: (50+(28*2), 50+(28/2))
2026 canvas->restore();
2027 filledPaint.setColor(SK_ColorGRAY);
2028 outlinePaint.setColor(SK_ColorRED);
2029 canvas->scale(2, 1/2.f);
2030 canvas->drawCircle(28, 28, 15, outlinePaint); // red center: (28*2, 28/2)
2031 canvas->translate(50, 50);
2032 canvas->drawCircle(28, 28, 15, filledPaint); // gray center: ((50+28)*2, (50+28)/2)
Cary Clark8032b982017-07-28 11:04:54 -04002033}
2034##
2035
Cary Clark2ade9972017-11-02 17:49:34 -04002036#SeeAlso concat() scale() skew() rotate() setMatrix
Cary Clark8032b982017-07-28 11:04:54 -04002037
2038##
2039
2040# ------------------------------------------------------------------------------
2041
2042#Method void scale(SkScalar sx, SkScalar sy)
2043
Cary Clarkab2621d2018-01-30 10:08:57 -05002044#In Matrix
2045#Line # scales Matrix ##
Cary Clark8032b982017-07-28 11:04:54 -04002046Scale Matrix by sx on the x-axis and sy on the y-axis.
2047
2048Mathematically, replace Matrix with a scale matrix
Herb Derbyefe39bc2018-05-01 17:06:20 -04002049Premultiplied with Matrix.
Cary Clark8032b982017-07-28 11:04:54 -04002050
2051This has the effect of scaling the drawing by (sx, sy) before transforming
2052the result with Matrix.
2053
Cary Clarkbad5ad72017-08-03 17:14:08 -04002054#Param sx amount to scale in x ##
2055#Param sy amount to scale in y ##
Cary Clark8032b982017-07-28 11:04:54 -04002056
2057#Example
2058#Height 160
Cary Clarkbad5ad72017-08-03 17:14:08 -04002059void draw(SkCanvas* canvas) {
2060 SkPaint paint;
2061 SkRect rect = { 10, 20, 60, 120 };
2062 canvas->translate(20, 20);
2063 canvas->drawRect(rect, paint);
2064 canvas->scale(2, .5f);
2065 paint.setColor(SK_ColorGRAY);
2066 canvas->drawRect(rect, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002067}
2068##
2069
Cary Clark2ade9972017-11-02 17:49:34 -04002070#SeeAlso concat() translate() skew() rotate() setMatrix
Cary Clark8032b982017-07-28 11:04:54 -04002071
2072##
2073
2074# ------------------------------------------------------------------------------
2075
2076#Method void rotate(SkScalar degrees)
2077
Cary Clarkab2621d2018-01-30 10:08:57 -05002078#In Matrix
2079#Line # rotates Matrix ##
Cary Clark8032b982017-07-28 11:04:54 -04002080Rotate Matrix by degrees. Positive degrees rotates clockwise.
2081
2082Mathematically, replace Matrix with a rotation matrix
Herb Derbyefe39bc2018-05-01 17:06:20 -04002083Premultiplied with Matrix.
Cary Clark8032b982017-07-28 11:04:54 -04002084
2085This has the effect of rotating the drawing by degrees before transforming
2086the result with Matrix.
2087
Cary Clarkbad5ad72017-08-03 17:14:08 -04002088#Param degrees amount to rotate, in degrees ##
Cary Clark8032b982017-07-28 11:04:54 -04002089
2090#Example
2091#Description
2092Draw clock hands at time 5:10. The hour hand and minute hand point up and
2093are rotated clockwise.
2094##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002095void draw(SkCanvas* canvas) {
2096 SkPaint paint;
2097 paint.setStyle(SkPaint::kStroke_Style);
2098 canvas->translate(128, 128);
2099 canvas->drawCircle(0, 0, 60, paint);
2100 canvas->save();
2101 canvas->rotate(10 * 360 / 60); // 10 minutes of 60 scaled to 360 degrees
Herb Derbyefe39bc2018-05-01 17:06:20 -04002102 canvas->drawLine(0, 0, 0, -50, paint);
Cary Clarkbad5ad72017-08-03 17:14:08 -04002103 canvas->restore();
2104 canvas->rotate((5 + 10.f/60) * 360 / 12); // 5 and 10/60 hours of 12 scaled to 360 degrees
2105 canvas->drawLine(0, 0, 0, -30, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002106}
2107##
2108
Cary Clark2ade9972017-11-02 17:49:34 -04002109#SeeAlso concat() translate() skew() scale() setMatrix
Cary Clark8032b982017-07-28 11:04:54 -04002110
2111##
2112
2113# ------------------------------------------------------------------------------
2114
2115#Method void rotate(SkScalar degrees, SkScalar px, SkScalar py)
2116
Cary Clarkab2621d2018-01-30 10:08:57 -05002117#In Matrix
Cary Clarkbad5ad72017-08-03 17:14:08 -04002118Rotate Matrix by degrees about a point at (px, py). Positive degrees rotates
2119clockwise.
Cary Clark8032b982017-07-28 11:04:54 -04002120
Cary Clarkce101242017-09-01 15:51:02 -04002121Mathematically, construct a rotation matrix. Premultiply the rotation matrix by
Cary Clark8032b982017-07-28 11:04:54 -04002122a translation matrix, then replace Matrix with the resulting matrix
Herb Derbyefe39bc2018-05-01 17:06:20 -04002123Premultiplied with Matrix.
Cary Clark8032b982017-07-28 11:04:54 -04002124
Cary Clarkbad5ad72017-08-03 17:14:08 -04002125This has the effect of rotating the drawing about a given point before
2126transforming the result with Matrix.
Cary Clark8032b982017-07-28 11:04:54 -04002127
Cary Clarkbad5ad72017-08-03 17:14:08 -04002128#Param degrees amount to rotate, in degrees ##
2129#Param px x-coordinate of the point to rotate about ##
2130#Param py y-coordinate of the point to rotate about ##
Cary Clark8032b982017-07-28 11:04:54 -04002131
2132#Example
2133#Height 192
Cary Clarkbad5ad72017-08-03 17:14:08 -04002134void draw(SkCanvas* canvas) {
2135 SkPaint paint;
2136 paint.setTextSize(96);
2137 canvas->drawString("A1", 130, 100, paint);
2138 canvas->rotate(180, 130, 100);
2139 canvas->drawString("A1", 130, 100, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002140}
2141##
2142
Cary Clark2ade9972017-11-02 17:49:34 -04002143#SeeAlso concat() translate() skew() scale() setMatrix
Cary Clark8032b982017-07-28 11:04:54 -04002144
2145##
2146
2147# ------------------------------------------------------------------------------
2148
2149#Method void skew(SkScalar sx, SkScalar sy)
2150
Cary Clarkab2621d2018-01-30 10:08:57 -05002151#In Matrix
2152#Line # skews Matrix ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002153Skew Matrix by sx on the x-axis and sy on the y-axis. A positive value of sx
2154skews the drawing right as y increases; a positive value of sy skews the drawing
2155down as x increases.
Cary Clark8032b982017-07-28 11:04:54 -04002156
Herb Derbyefe39bc2018-05-01 17:06:20 -04002157Mathematically, replace Matrix with a skew matrix Premultiplied with Matrix.
Cary Clark8032b982017-07-28 11:04:54 -04002158
Cary Clarkbad5ad72017-08-03 17:14:08 -04002159This has the effect of skewing the drawing by (sx, sy) before transforming
Cary Clark8032b982017-07-28 11:04:54 -04002160the result with Matrix.
2161
Cary Clarkbad5ad72017-08-03 17:14:08 -04002162#Param sx amount to skew in x ##
2163#Param sy amount to skew in y ##
2164
Cary Clark8032b982017-07-28 11:04:54 -04002165#Example
Herb Derbyefe39bc2018-05-01 17:06:20 -04002166 #Description
Cary Clark8032b982017-07-28 11:04:54 -04002167 Black text mimics an oblique text style by using a negative skew in x that
2168 shifts the geometry to the right as the y values decrease.
2169 Red text uses a positive skew in y to shift the geometry down as the x values
2170 increase.
2171 Blue text combines x and y skew to rotate and scale.
2172 ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002173 SkPaint paint;
2174 paint.setTextSize(128);
2175 canvas->translate(30, 130);
2176 canvas->save();
2177 canvas->skew(-.5, 0);
2178 canvas->drawString("A1", 0, 0, paint);
2179 canvas->restore();
2180 canvas->save();
2181 canvas->skew(0, .5);
2182 paint.setColor(SK_ColorRED);
2183 canvas->drawString("A1", 0, 0, paint);
2184 canvas->restore();
2185 canvas->skew(-.5, .5);
2186 paint.setColor(SK_ColorBLUE);
Cary Clark8032b982017-07-28 11:04:54 -04002187 canvas->drawString("A1", 0, 0, paint);
2188##
2189
Cary Clark2ade9972017-11-02 17:49:34 -04002190#SeeAlso concat() translate() rotate() scale() setMatrix
Cary Clark8032b982017-07-28 11:04:54 -04002191
2192##
2193
2194# ------------------------------------------------------------------------------
2195
2196#Method void concat(const SkMatrix& matrix)
2197
Cary Clarkab2621d2018-01-30 10:08:57 -05002198#In Matrix
2199#Line # multiplies Matrix by Matrix ##
Cary Clarkce101242017-09-01 15:51:02 -04002200Replace Matrix with matrix Premultiplied with existing Matrix.
Cary Clark8032b982017-07-28 11:04:54 -04002201
Cary Clarkbad5ad72017-08-03 17:14:08 -04002202This has the effect of transforming the drawn geometry by matrix, before
2203transforming the result with existing Matrix.
Cary Clark8032b982017-07-28 11:04:54 -04002204
Cary Clarkce101242017-09-01 15:51:02 -04002205#Param matrix matrix to Premultiply with existing Matrix ##
Cary Clark8032b982017-07-28 11:04:54 -04002206
2207#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04002208void draw(SkCanvas* canvas) {
2209 SkPaint paint;
2210 paint.setTextSize(80);
2211 paint.setTextScaleX(.3);
2212 SkMatrix matrix;
2213 SkRect rect[2] = {{ 10, 20, 90, 110 }, { 40, 130, 140, 180 }};
2214 matrix.setRectToRect(rect[0], rect[1], SkMatrix::kFill_ScaleToFit);
2215 canvas->drawRect(rect[0], paint);
2216 canvas->drawRect(rect[1], paint);
2217 paint.setColor(SK_ColorWHITE);
2218 canvas->drawString("Here", rect[0].fLeft + 10, rect[0].fBottom - 10, paint);
2219 canvas->concat(matrix);
2220 canvas->drawString("There", rect[0].fLeft + 10, rect[0].fBottom - 10, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002221}
2222##
2223
Cary Clark2ade9972017-11-02 17:49:34 -04002224#SeeAlso translate() rotate() scale() skew() setMatrix
Cary Clark8032b982017-07-28 11:04:54 -04002225
2226##
2227
2228# ------------------------------------------------------------------------------
2229
2230#Method void setMatrix(const SkMatrix& matrix)
2231
Cary Clarkab2621d2018-01-30 10:08:57 -05002232#In Matrix
2233#Line # sets Matrix ##
Cary Clark8032b982017-07-28 11:04:54 -04002234Replace Matrix with matrix.
2235Unlike concat(), any prior matrix state is overwritten.
2236
Cary Clarkbad5ad72017-08-03 17:14:08 -04002237#Param matrix matrix to copy, replacing existing Matrix ##
Cary Clark8032b982017-07-28 11:04:54 -04002238
2239#Example
2240#Height 128
Cary Clarkbad5ad72017-08-03 17:14:08 -04002241void draw(SkCanvas* canvas) {
2242 SkPaint paint;
2243 canvas->scale(4, 6);
2244 canvas->drawString("truth", 2, 10, paint);
2245 SkMatrix matrix;
2246 matrix.setScale(2.8f, 6);
2247 canvas->setMatrix(matrix);
2248 canvas->drawString("consequences", 2, 20, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002249}
2250##
2251
Cary Clark2ade9972017-11-02 17:49:34 -04002252#SeeAlso resetMatrix concat() translate() rotate() scale() skew()
Cary Clark8032b982017-07-28 11:04:54 -04002253
2254##
2255
2256# ------------------------------------------------------------------------------
2257
2258#Method void resetMatrix()
2259
Cary Clarkab2621d2018-01-30 10:08:57 -05002260#In Matrix
2261#Line # resets Matrix to identity ##
Cary Clark8032b982017-07-28 11:04:54 -04002262Sets Matrix to the identity matrix.
2263Any prior matrix state is overwritten.
2264
2265#Example
2266#Height 128
Cary Clarkbad5ad72017-08-03 17:14:08 -04002267void draw(SkCanvas* canvas) {
2268 SkPaint paint;
2269 canvas->scale(4, 6);
2270 canvas->drawString("truth", 2, 10, paint);
2271 canvas->resetMatrix();
2272 canvas->scale(2.8f, 6);
2273 canvas->drawString("consequences", 2, 20, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002274}
2275##
2276
Cary Clark2ade9972017-11-02 17:49:34 -04002277#SeeAlso setMatrix concat() translate() rotate() scale() skew()
Cary Clark8032b982017-07-28 11:04:54 -04002278
2279##
2280
2281# ------------------------------------------------------------------------------
2282
2283#Method const SkMatrix& getTotalMatrix() const
2284
Cary Clarkab2621d2018-01-30 10:08:57 -05002285#In Matrix
2286#Line # returns Matrix ##
Cary Clark8032b982017-07-28 11:04:54 -04002287Returns Matrix.
2288This does not account for translation by Device or Surface.
2289
Cary Clarkbad5ad72017-08-03 17:14:08 -04002290#Return Matrix in Canvas ##
Cary Clark8032b982017-07-28 11:04:54 -04002291
2292#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04002293 SkDebugf("isIdentity %s\n", canvas->getTotalMatrix().isIdentity() ? "true" : "false");
2294 #StdOut
2295 isIdentity true
2296 ##
Cary Clark8032b982017-07-28 11:04:54 -04002297##
2298
Cary Clark2ade9972017-11-02 17:49:34 -04002299#SeeAlso setMatrix resetMatrix concat()
Cary Clark8032b982017-07-28 11:04:54 -04002300
2301##
2302
Cary Clark08895c42018-02-01 09:37:32 -05002303#Subtopic Matrix ##
Cary Clark8032b982017-07-28 11:04:54 -04002304
2305# ------------------------------------------------------------------------------
Cary Clark08895c42018-02-01 09:37:32 -05002306#Subtopic Clip
2307#Line # stack of clipping Paths ##
Cary Clark8032b982017-07-28 11:04:54 -04002308
2309Clip is built from a stack of clipping paths. Each Path in the
Herb Derbyefe39bc2018-05-01 17:06:20 -04002310stack can be constructed from one or more Path_Contour elements. The
Cary Clark8032b982017-07-28 11:04:54 -04002311Path_Contour may be composed of any number of Path_Verb segments. Each
2312Path_Contour forms a closed area; Path_Fill_Type defines the area enclosed
2313by Path_Contour.
2314
2315Clip stack of Path elements successfully restrict the Path area. Each
Herb Derbyefe39bc2018-05-01 17:06:20 -04002316Path is transformed by Matrix, then intersected with or subtracted from the
Cary Clark8032b982017-07-28 11:04:54 -04002317prior Clip to form the replacement Clip. Use SkClipOp::kDifference
2318to subtract Path from Clip; use SkClipOp::kIntersect to intersect Path
2319with Clip.
2320
Cary Clarkce101242017-09-01 15:51:02 -04002321A clipping Path may be Anti-aliased; if Path, after transformation, is
Cary Clark8032b982017-07-28 11:04:54 -04002322composed of horizontal and vertical lines, clearing Anti-alias allows whole pixels
Cary Clarkce101242017-09-01 15:51:02 -04002323to either be inside or outside the clip. The fastest drawing has a Aliased,
2324rectangular clip.
Cary Clark8032b982017-07-28 11:04:54 -04002325
2326If clipping Path has Anti-alias set, clip may partially clip a pixel, requiring
Herb Derbyefe39bc2018-05-01 17:06:20 -04002327that drawing blend partially with the destination along the edge. A rotated
Cary Clarkce101242017-09-01 15:51:02 -04002328rectangular Anti-aliased clip looks smoother but draws slower.
Cary Clark8032b982017-07-28 11:04:54 -04002329
2330Clip can combine with Rect and Round_Rect primitives; like
2331Path, these are transformed by Matrix before they are combined with Clip.
2332
2333Clip can combine with Region. Region is assumed to be in Device coordinates
2334and is unaffected by Matrix.
2335
2336#Example
2337#Height 90
2338 #Description
Cary Clarkce101242017-09-01 15:51:02 -04002339 Draw a red circle with an Aliased clip and an Anti-aliased clip.
Cary Clark8032b982017-07-28 11:04:54 -04002340 Use an image filter to zoom into the pixels drawn.
Cary Clarkce101242017-09-01 15:51:02 -04002341 The edge of the Aliased clip fully draws pixels in the red circle.
2342 The edge of the Anti-aliased clip partially draws pixels in the red circle.
Cary Clark8032b982017-07-28 11:04:54 -04002343 ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002344 SkPaint redPaint, scalePaint;
2345 redPaint.setAntiAlias(true);
2346 redPaint.setColor(SK_ColorRED);
2347 canvas->save();
2348 for (bool antialias : { false, true } ) {
2349 canvas->save();
2350 canvas->clipRect(SkRect::MakeWH(19.5f, 11.5f), antialias);
2351 canvas->drawCircle(17, 11, 8, redPaint);
2352 canvas->restore();
2353 canvas->translate(16, 0);
2354 }
2355 canvas->restore();
2356 SkMatrix matrix;
2357 matrix.setScale(6, 6);
2358 scalePaint.setImageFilter(
2359 SkImageFilter::MakeMatrixFilter(matrix, kNone_SkFilterQuality, nullptr));
2360 SkCanvas::SaveLayerRec saveLayerRec(
Herb Derbyefe39bc2018-05-01 17:06:20 -04002361 nullptr, &scalePaint, SkCanvas::kInitWithPrevious_SaveLayerFlag);
Cary Clarkbad5ad72017-08-03 17:14:08 -04002362 canvas->saveLayer(saveLayerRec);
Cary Clark8032b982017-07-28 11:04:54 -04002363 canvas->restore();
2364##
2365
2366#Method void clipRect(const SkRect& rect, SkClipOp op, bool doAntiAlias)
2367
Cary Clarkab2621d2018-01-30 10:08:57 -05002368#In Clip
2369#Line # combines Clip with Rect ##
Cary Clark8032b982017-07-28 11:04:54 -04002370Replace Clip with the intersection or difference of Clip and rect,
Cary Clarkce101242017-09-01 15:51:02 -04002371with an Aliased or Anti-aliased clip edge. rect is transformed by Matrix
Cary Clark8032b982017-07-28 11:04:54 -04002372before it is combined with Clip.
2373
Cary Clarka523d2d2017-08-30 08:58:10 -04002374#Param rect Rect to combine with Clip ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002375#Param op Clip_Op to apply to Clip ##
Cary Clarkce101242017-09-01 15:51:02 -04002376#Param doAntiAlias true if Clip is to be Anti-aliased ##
Cary Clark8032b982017-07-28 11:04:54 -04002377
2378#Example
2379#Height 128
Cary Clarkbad5ad72017-08-03 17:14:08 -04002380void draw(SkCanvas* canvas) {
2381 canvas->rotate(10);
2382 SkPaint paint;
2383 paint.setAntiAlias(true);
2384 for (auto alias: { false, true } ) {
2385 canvas->save();
2386 canvas->clipRect(SkRect::MakeWH(90, 80), SkClipOp::kIntersect, alias);
2387 canvas->drawCircle(100, 60, 60, paint);
2388 canvas->restore();
2389 canvas->translate(80, 0);
2390 }
Cary Clark8032b982017-07-28 11:04:54 -04002391}
2392##
2393
Cary Clark2ade9972017-11-02 17:49:34 -04002394#SeeAlso clipRRect clipPath clipRegion
Cary Clark8032b982017-07-28 11:04:54 -04002395
2396##
2397
Herb Derbyefe39bc2018-05-01 17:06:20 -04002398#Method void clipRect(const SkRect& rect, SkClipOp op)
Cary Clark8032b982017-07-28 11:04:54 -04002399
Cary Clarkab2621d2018-01-30 10:08:57 -05002400#In Clip
Cary Clark8032b982017-07-28 11:04:54 -04002401Replace Clip with the intersection or difference of Clip and rect.
Cary Clarkce101242017-09-01 15:51:02 -04002402Resulting Clip is Aliased; pixels are fully contained by the clip.
Cary Clarkbad5ad72017-08-03 17:14:08 -04002403rect is transformed by Matrix before it is combined with Clip.
Cary Clark8032b982017-07-28 11:04:54 -04002404
Cary Clarka523d2d2017-08-30 08:58:10 -04002405#Param rect Rect to combine with Clip ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002406#Param op Clip_Op to apply to Clip ##
Cary Clark8032b982017-07-28 11:04:54 -04002407
2408#Example
2409#Height 192
2410#Width 280
Cary Clarkbad5ad72017-08-03 17:14:08 -04002411void draw(SkCanvas* canvas) {
2412 SkPaint paint;
2413 for (SkClipOp op: { SkClipOp::kIntersect, SkClipOp::kDifference } ) {
2414 canvas->save();
2415 canvas->clipRect(SkRect::MakeWH(90, 120), op, false);
2416 canvas->drawCircle(100, 100, 60, paint);
2417 canvas->restore();
2418 canvas->translate(80, 0);
2419 }
Cary Clark8032b982017-07-28 11:04:54 -04002420}
2421##
2422
Cary Clark2ade9972017-11-02 17:49:34 -04002423#SeeAlso clipRRect clipPath clipRegion
Cary Clark8032b982017-07-28 11:04:54 -04002424
2425##
2426
Herb Derbyefe39bc2018-05-01 17:06:20 -04002427#Method void clipRect(const SkRect& rect, bool doAntiAlias = false)
Cary Clark8032b982017-07-28 11:04:54 -04002428
Cary Clarkab2621d2018-01-30 10:08:57 -05002429#In Clip
Cary Clark8032b982017-07-28 11:04:54 -04002430Replace Clip with the intersection of Clip and rect.
Cary Clarkce101242017-09-01 15:51:02 -04002431Resulting Clip is Aliased; pixels are fully contained by the clip.
Cary Clark8032b982017-07-28 11:04:54 -04002432rect is transformed by Matrix
2433before it is combined with Clip.
2434
Cary Clarka523d2d2017-08-30 08:58:10 -04002435#Param rect Rect to combine with Clip ##
Cary Clarkce101242017-09-01 15:51:02 -04002436#Param doAntiAlias true if Clip is to be Anti-aliased ##
Cary Clark8032b982017-07-28 11:04:54 -04002437
2438#Example
2439#Height 133
2440 #Description
Cary Clarkce101242017-09-01 15:51:02 -04002441 A circle drawn in pieces looks uniform when drawn Aliased.
2442 The same circle pieces blend with pixels more than once when Anti-aliased,
Cary Clark8032b982017-07-28 11:04:54 -04002443 visible as a thin pair of lines through the right circle.
2444 ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002445void draw(SkCanvas* canvas) {
2446 canvas->clear(SK_ColorWHITE);
2447 SkPaint paint;
2448 paint.setAntiAlias(true);
2449 paint.setColor(0x8055aaff);
2450 SkRect clipRect = { 0, 0, 87.4f, 87.4f };
2451 for (auto alias: { false, true } ) {
2452 canvas->save();
2453 canvas->clipRect(clipRect, SkClipOp::kIntersect, alias);
2454 canvas->drawCircle(67, 67, 60, paint);
2455 canvas->restore();
2456 canvas->save();
2457 canvas->clipRect(clipRect, SkClipOp::kDifference, alias);
2458 canvas->drawCircle(67, 67, 60, paint);
2459 canvas->restore();
2460 canvas->translate(120, 0);
2461 }
Cary Clark8032b982017-07-28 11:04:54 -04002462}
2463##
2464
Cary Clark2ade9972017-11-02 17:49:34 -04002465#SeeAlso clipRRect clipPath clipRegion
Cary Clark8032b982017-07-28 11:04:54 -04002466
2467##
2468
2469#Method void androidFramework_setDeviceClipRestriction(const SkIRect& rect)
2470
Cary Clarkab2621d2018-01-30 10:08:57 -05002471#In Clip
2472#Line # for use by Android framework ##
Cary Clarkce101242017-09-01 15:51:02 -04002473Sets the maximum clip rectangle, which can be set by clipRect, clipRRect and
Cary Clark8032b982017-07-28 11:04:54 -04002474clipPath and intersect the current clip with the specified rect.
Cary Clarkce101242017-09-01 15:51:02 -04002475The maximum clip affects only future clipping operations; it is not retroactive.
Cary Clark8032b982017-07-28 11:04:54 -04002476The clip restriction is not recorded in pictures.
2477
Herb Derbyefe39bc2018-05-01 17:06:20 -04002478Pass an empty rect to disable maximum clip.
Cary Clarkbad5ad72017-08-03 17:14:08 -04002479
Cary Clark8032b982017-07-28 11:04:54 -04002480#Private
2481This is private API to be used only by Android framework.
2482##
2483
Cary Clarkbad5ad72017-08-03 17:14:08 -04002484#Param rect maximum allowed clip in device coordinates
Cary Clark579985c2017-07-31 11:48:27 -04002485#Param ##
Cary Clark8032b982017-07-28 11:04:54 -04002486
2487##
2488
2489#Method void clipRRect(const SkRRect& rrect, SkClipOp op, bool doAntiAlias)
2490
Cary Clarkab2621d2018-01-30 10:08:57 -05002491#In Clip
2492#Line # combines Clip with Round_Rect ##
Cary Clark8032b982017-07-28 11:04:54 -04002493Replace Clip with the intersection or difference of Clip and rrect,
Cary Clarkce101242017-09-01 15:51:02 -04002494with an Aliased or Anti-aliased clip edge.
Cary Clark8032b982017-07-28 11:04:54 -04002495rrect is transformed by Matrix
2496before it is combined with Clip.
2497
Cary Clarkbad5ad72017-08-03 17:14:08 -04002498#Param rrect Round_Rect to combine with Clip ##
2499#Param op Clip_Op to apply to Clip ##
Cary Clarkce101242017-09-01 15:51:02 -04002500#Param doAntiAlias true if Clip is to be Anti-aliased ##
Cary Clark8032b982017-07-28 11:04:54 -04002501
2502#Example
2503#Height 128
Cary Clarkbad5ad72017-08-03 17:14:08 -04002504void draw(SkCanvas* canvas) {
2505 canvas->clear(SK_ColorWHITE);
2506 SkPaint paint;
2507 paint.setAntiAlias(true);
2508 paint.setColor(0x8055aaff);
2509 SkRRect oval;
2510 oval.setOval({10, 20, 90, 100});
2511 canvas->clipRRect(oval, SkClipOp::kIntersect, true);
2512 canvas->drawCircle(70, 100, 60, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002513}
2514##
2515
Cary Clark2ade9972017-11-02 17:49:34 -04002516#SeeAlso clipRect clipPath clipRegion
Cary Clark8032b982017-07-28 11:04:54 -04002517
2518##
2519
Herb Derbyefe39bc2018-05-01 17:06:20 -04002520#Method void clipRRect(const SkRRect& rrect, SkClipOp op)
Cary Clark8032b982017-07-28 11:04:54 -04002521
Cary Clarkab2621d2018-01-30 10:08:57 -05002522#In Clip
Cary Clark8032b982017-07-28 11:04:54 -04002523Replace Clip with the intersection or difference of Clip and rrect.
Cary Clarkce101242017-09-01 15:51:02 -04002524Resulting Clip is Aliased; pixels are fully contained by the clip.
Cary Clarkbad5ad72017-08-03 17:14:08 -04002525rrect is transformed by Matrix before it is combined with Clip.
Cary Clark8032b982017-07-28 11:04:54 -04002526
Cary Clarkbad5ad72017-08-03 17:14:08 -04002527#Param rrect Round_Rect to combine with Clip ##
2528#Param op Clip_Op to apply to Clip ##
Cary Clark8032b982017-07-28 11:04:54 -04002529
2530#Example
2531#Height 128
Cary Clarkbad5ad72017-08-03 17:14:08 -04002532void draw(SkCanvas* canvas) {
2533 SkPaint paint;
2534 paint.setColor(0x8055aaff);
2535 auto oval = SkRRect::MakeOval({10, 20, 90, 100});
2536 canvas->clipRRect(oval, SkClipOp::kIntersect);
2537 canvas->drawCircle(70, 100, 60, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002538}
2539##
2540
Cary Clark2ade9972017-11-02 17:49:34 -04002541#SeeAlso clipRect clipPath clipRegion
Cary Clark8032b982017-07-28 11:04:54 -04002542
2543##
2544
Herb Derbyefe39bc2018-05-01 17:06:20 -04002545#Method void clipRRect(const SkRRect& rrect, bool doAntiAlias = false)
Cary Clark8032b982017-07-28 11:04:54 -04002546
Cary Clarkab2621d2018-01-30 10:08:57 -05002547#In Clip
Cary Clark8032b982017-07-28 11:04:54 -04002548Replace Clip with the intersection of Clip and rrect,
Cary Clarkce101242017-09-01 15:51:02 -04002549with an Aliased or Anti-aliased clip edge.
Cary Clarkbad5ad72017-08-03 17:14:08 -04002550rrect is transformed by Matrix before it is combined with Clip.
Cary Clark8032b982017-07-28 11:04:54 -04002551
Cary Clarkbad5ad72017-08-03 17:14:08 -04002552#Param rrect Round_Rect to combine with Clip ##
Cary Clarkce101242017-09-01 15:51:02 -04002553#Param doAntiAlias true if Clip is to be Anti-aliased ##
Cary Clark8032b982017-07-28 11:04:54 -04002554
2555#Example
2556#Height 128
Cary Clarkbad5ad72017-08-03 17:14:08 -04002557void draw(SkCanvas* canvas) {
2558 SkPaint paint;
2559 paint.setAntiAlias(true);
2560 auto oval = SkRRect::MakeRectXY({10, 20, 90, 100}, 9, 13);
2561 canvas->clipRRect(oval, true);
2562 canvas->drawCircle(70, 100, 60, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002563}
2564##
2565
Cary Clark2ade9972017-11-02 17:49:34 -04002566#SeeAlso clipRect clipPath clipRegion
Cary Clark8032b982017-07-28 11:04:54 -04002567
2568##
2569
2570#Method void clipPath(const SkPath& path, SkClipOp op, bool doAntiAlias)
2571
Cary Clarkab2621d2018-01-30 10:08:57 -05002572#In Clip
2573#Line # combines Clip with Path ##
Cary Clark8032b982017-07-28 11:04:54 -04002574Replace Clip with the intersection or difference of Clip and path,
Cary Clarkce101242017-09-01 15:51:02 -04002575with an Aliased or Anti-aliased clip edge. Path_Fill_Type determines if path
Cary Clark8032b982017-07-28 11:04:54 -04002576describes the area inside or outside its contours; and if Path_Contour overlaps
2577itself or another Path_Contour, whether the overlaps form part of the area.
Cary Clarkbad5ad72017-08-03 17:14:08 -04002578path is transformed by Matrix before it is combined with Clip.
Cary Clark8032b982017-07-28 11:04:54 -04002579
Cary Clarkbad5ad72017-08-03 17:14:08 -04002580#Param path Path to combine with Clip ##
2581#Param op Clip_Op to apply to Clip ##
Cary Clarkce101242017-09-01 15:51:02 -04002582#Param doAntiAlias true if Clip is to be Anti-aliased ##
Cary Clark8032b982017-07-28 11:04:54 -04002583
2584#Example
2585#Description
2586Top figure uses SkPath::kInverseWinding_FillType and SkClipOp::kDifference;
2587area outside clip is subtracted from circle.
2588
2589Bottom figure uses SkPath::kWinding_FillType and SkClipOp::kIntersect;
2590area inside clip is intersected with circle.
2591##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002592void draw(SkCanvas* canvas) {
2593 SkPaint paint;
2594 paint.setAntiAlias(true);
2595 SkPath path;
2596 path.addRect({20, 30, 100, 110});
2597 path.setFillType(SkPath::kInverseWinding_FillType);
2598 canvas->save();
2599 canvas->clipPath(path, SkClipOp::kDifference, false);
2600 canvas->drawCircle(70, 100, 60, paint);
2601 canvas->restore();
2602 canvas->translate(100, 100);
2603 path.setFillType(SkPath::kWinding_FillType);
2604 canvas->clipPath(path, SkClipOp::kIntersect, false);
2605 canvas->drawCircle(70, 100, 60, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002606}
2607##
2608
Cary Clark2ade9972017-11-02 17:49:34 -04002609#SeeAlso clipRect clipRRect clipRegion
Cary Clark8032b982017-07-28 11:04:54 -04002610
2611##
2612
Herb Derbyefe39bc2018-05-01 17:06:20 -04002613#Method void clipPath(const SkPath& path, SkClipOp op)
Cary Clark8032b982017-07-28 11:04:54 -04002614
Cary Clarkab2621d2018-01-30 10:08:57 -05002615#In Clip
Cary Clark8032b982017-07-28 11:04:54 -04002616Replace Clip with the intersection or difference of Clip and path.
Cary Clarkce101242017-09-01 15:51:02 -04002617Resulting Clip is Aliased; pixels are fully contained by the clip.
Cary Clark8032b982017-07-28 11:04:54 -04002618Path_Fill_Type determines if path
2619describes the area inside or outside its contours; and if Path_Contour overlaps
2620itself or another Path_Contour, whether the overlaps form part of the area.
2621path is transformed by Matrix
2622before it is combined with Clip.
2623
Cary Clarkbad5ad72017-08-03 17:14:08 -04002624#Param path Path to combine with Clip ##
2625#Param op Clip_Op to apply to Clip ##
Cary Clark8032b982017-07-28 11:04:54 -04002626
2627#Example
2628#Description
Cary Clarkbc5697d2017-10-04 14:31:33 -04002629Overlapping Rects form a clip. When clip Path_Fill_Type is set to
Herb Derbyefe39bc2018-05-01 17:06:20 -04002630SkPath::kWinding_FillType, the overlap is included. Set to
Cary Clark8032b982017-07-28 11:04:54 -04002631SkPath::kEvenOdd_FillType, the overlap is excluded and forms a hole.
2632##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002633void draw(SkCanvas* canvas) {
2634 SkPaint paint;
2635 paint.setAntiAlias(true);
2636 SkPath path;
2637 path.addRect({20, 15, 100, 95});
2638 path.addRect({50, 65, 130, 135});
2639 path.setFillType(SkPath::kWinding_FillType);
2640 canvas->save();
2641 canvas->clipPath(path, SkClipOp::kIntersect);
2642 canvas->drawCircle(70, 85, 60, paint);
2643 canvas->restore();
2644 canvas->translate(100, 100);
2645 path.setFillType(SkPath::kEvenOdd_FillType);
2646 canvas->clipPath(path, SkClipOp::kIntersect);
2647 canvas->drawCircle(70, 85, 60, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002648}
2649##
2650
Cary Clark2ade9972017-11-02 17:49:34 -04002651#SeeAlso clipRect clipRRect clipRegion
Cary Clark8032b982017-07-28 11:04:54 -04002652
2653##
2654
Herb Derbyefe39bc2018-05-01 17:06:20 -04002655#Method void clipPath(const SkPath& path, bool doAntiAlias = false)
Cary Clark8032b982017-07-28 11:04:54 -04002656
Cary Clarkab2621d2018-01-30 10:08:57 -05002657#In Clip
Cary Clark8032b982017-07-28 11:04:54 -04002658Replace Clip with the intersection of Clip and path.
Cary Clarkce101242017-09-01 15:51:02 -04002659Resulting Clip is Aliased; pixels are fully contained by the clip.
Cary Clark8032b982017-07-28 11:04:54 -04002660Path_Fill_Type determines if path
2661describes the area inside or outside its contours; and if Path_Contour overlaps
2662itself or another Path_Contour, whether the overlaps form part of the area.
Cary Clarkbad5ad72017-08-03 17:14:08 -04002663path is transformed by Matrix before it is combined with Clip.
Cary Clark8032b982017-07-28 11:04:54 -04002664
Cary Clarkbad5ad72017-08-03 17:14:08 -04002665#Param path Path to combine with Clip ##
Cary Clarkce101242017-09-01 15:51:02 -04002666#Param doAntiAlias true if Clip is to be Anti-aliased ##
Cary Clark8032b982017-07-28 11:04:54 -04002667
2668#Example
2669#Height 212
2670#Description
Herb Derbyefe39bc2018-05-01 17:06:20 -04002671Clip loops over itself covering its center twice. When clip Path_Fill_Type
2672is set to SkPath::kWinding_FillType, the overlap is included. Set to
Cary Clark8032b982017-07-28 11:04:54 -04002673SkPath::kEvenOdd_FillType, the overlap is excluded and forms a hole.
2674##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002675void draw(SkCanvas* canvas) {
2676 SkPaint paint;
2677 paint.setAntiAlias(true);
2678 SkPath path;
2679 SkPoint poly[] = {{20, 20}, { 80, 20}, { 80, 80}, {40, 80},
2680 {40, 40}, {100, 40}, {100, 100}, {20, 100}};
2681 path.addPoly(poly, SK_ARRAY_COUNT(poly), true);
2682 path.setFillType(SkPath::kWinding_FillType);
2683 canvas->save();
2684 canvas->clipPath(path, SkClipOp::kIntersect);
2685 canvas->drawCircle(50, 50, 45, paint);
2686 canvas->restore();
2687 canvas->translate(100, 100);
2688 path.setFillType(SkPath::kEvenOdd_FillType);
2689 canvas->clipPath(path, SkClipOp::kIntersect);
2690 canvas->drawCircle(50, 50, 45, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002691}
2692##
2693
Cary Clark2ade9972017-11-02 17:49:34 -04002694#SeeAlso clipRect clipRRect clipRegion
Cary Clark8032b982017-07-28 11:04:54 -04002695
2696##
2697
2698# ------------------------------------------------------------------------------
2699
Herb Derbyefe39bc2018-05-01 17:06:20 -04002700#Method void setAllowSimplifyClip(bool allow)
Cary Clark8032b982017-07-28 11:04:54 -04002701
Cary Clarkab2621d2018-01-30 10:08:57 -05002702#In Clip
2703#Line # experimental ##
Cary Clark8032b982017-07-28 11:04:54 -04002704#Experimental
2705Only used for testing.
2706##
2707
Cary Clarkce101242017-09-01 15:51:02 -04002708Set to simplify clip stack using PathOps.
Cary Clark8032b982017-07-28 11:04:54 -04002709
2710##
2711
2712# ------------------------------------------------------------------------------
2713
2714#Method void clipRegion(const SkRegion& deviceRgn, SkClipOp op = SkClipOp::kIntersect)
2715
Cary Clarkab2621d2018-01-30 10:08:57 -05002716#In Clip
2717#Line # combines Clip with Region ##
Cary Clark8032b982017-07-28 11:04:54 -04002718Replace Clip with the intersection or difference of Clip and Region deviceRgn.
Cary Clarkce101242017-09-01 15:51:02 -04002719Resulting Clip is Aliased; pixels are fully contained by the clip.
Cary Clark8032b982017-07-28 11:04:54 -04002720deviceRgn is unaffected by Matrix.
2721
Cary Clarkbad5ad72017-08-03 17:14:08 -04002722#Param deviceRgn Region to combine with Clip ##
2723#Param op Clip_Op to apply to Clip ##
Cary Clark8032b982017-07-28 11:04:54 -04002724
2725#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04002726#Description
Cary Clarkce101242017-09-01 15:51:02 -04002727 region is unaffected by canvas rotation; iRect is affected by canvas rotation.
2728 Both clips are Aliased; this is not noticeable on Region clip because it
Cary Clarkbad5ad72017-08-03 17:14:08 -04002729 aligns to pixel boundaries.
2730##
2731void draw(SkCanvas* canvas) {
2732 SkPaint paint;
2733 paint.setAntiAlias(true);
2734 SkIRect iRect = {30, 40, 120, 130 };
2735 SkRegion region(iRect);
2736 canvas->rotate(10);
2737 canvas->save();
2738 canvas->clipRegion(region, SkClipOp::kIntersect);
2739 canvas->drawCircle(50, 50, 45, paint);
2740 canvas->restore();
2741 canvas->translate(100, 100);
2742 canvas->clipRect(SkRect::Make(iRect), SkClipOp::kIntersect);
2743 canvas->drawCircle(50, 50, 45, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002744}
2745##
2746
Cary Clark2ade9972017-11-02 17:49:34 -04002747#SeeAlso clipRect clipRRect clipPath
Cary Clark8032b982017-07-28 11:04:54 -04002748
2749##
2750
2751#Method bool quickReject(const SkRect& rect) const
2752
Cary Clarkab2621d2018-01-30 10:08:57 -05002753#In Clip
2754#Line # returns if Rect is outside Clip ##
Cary Clark8032b982017-07-28 11:04:54 -04002755Return true if Rect rect, transformed by Matrix, can be quickly determined to be
2756outside of Clip. May return false even though rect is outside of Clip.
2757
2758Use to check if an area to be drawn is clipped out, to skip subsequent draw calls.
2759
Cary Clarkbad5ad72017-08-03 17:14:08 -04002760#Param rect Rect to compare with Clip ##
Cary Clark8032b982017-07-28 11:04:54 -04002761
Cary Clarkbad5ad72017-08-03 17:14:08 -04002762#Return true if rect, transformed by Matrix, does not intersect Clip ##
Cary Clark8032b982017-07-28 11:04:54 -04002763
2764#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04002765void draw(SkCanvas* canvas) {
Herb Derbyefe39bc2018-05-01 17:06:20 -04002766 SkRect testRect = {30, 30, 120, 129 };
2767 SkRect clipRect = {30, 130, 120, 230 };
Cary Clarkbad5ad72017-08-03 17:14:08 -04002768 canvas->save();
2769 canvas->clipRect(clipRect);
2770 SkDebugf("quickReject %s\n", canvas->quickReject(testRect) ? "true" : "false");
2771 canvas->restore();
2772 canvas->rotate(10);
2773 canvas->clipRect(clipRect);
2774 SkDebugf("quickReject %s\n", canvas->quickReject(testRect) ? "true" : "false");
Cary Clark8032b982017-07-28 11:04:54 -04002775}
2776 #StdOut
Cary Clarkbad5ad72017-08-03 17:14:08 -04002777 quickReject true
Cary Clark8032b982017-07-28 11:04:54 -04002778 quickReject false
2779 ##
2780##
2781
Cary Clark2ade9972017-11-02 17:49:34 -04002782#SeeAlso getLocalClipBounds getTotalMatrix SkBitmap::drawsNothing
Cary Clark8032b982017-07-28 11:04:54 -04002783
2784##
2785
2786#Method bool quickReject(const SkPath& path) const
2787
Cary Clarkab2621d2018-01-30 10:08:57 -05002788#In Clip
Cary Clark8032b982017-07-28 11:04:54 -04002789Return true if path, transformed by Matrix, can be quickly determined to be
2790outside of Clip. May return false even though path is outside of Clip.
2791
2792Use to check if an area to be drawn is clipped out, to skip subsequent draw calls.
2793
Cary Clarkbad5ad72017-08-03 17:14:08 -04002794#Param path Path to compare with Clip ##
Cary Clark8032b982017-07-28 11:04:54 -04002795
Cary Clarkbad5ad72017-08-03 17:14:08 -04002796#Return true if path, transformed by Matrix, does not intersect Clip ##
Cary Clark8032b982017-07-28 11:04:54 -04002797
2798#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04002799void draw(SkCanvas* canvas) {
Herb Derbyefe39bc2018-05-01 17:06:20 -04002800 SkPoint testPoints[] = {{30, 30}, {120, 30}, {120, 129} };
2801 SkPoint clipPoints[] = {{30, 130}, {120, 130}, {120, 230} };
Cary Clarkbad5ad72017-08-03 17:14:08 -04002802 SkPath testPath, clipPath;
2803 testPath.addPoly(testPoints, SK_ARRAY_COUNT(testPoints), true);
2804 clipPath.addPoly(clipPoints, SK_ARRAY_COUNT(clipPoints), true);
2805 canvas->save();
2806 canvas->clipPath(clipPath);
2807 SkDebugf("quickReject %s\n", canvas->quickReject(testPath) ? "true" : "false");
2808 canvas->restore();
2809 canvas->rotate(10);
2810 canvas->clipPath(clipPath);
2811 SkDebugf("quickReject %s\n", canvas->quickReject(testPath) ? "true" : "false");
Cary Clark8032b982017-07-28 11:04:54 -04002812 #StdOut
Cary Clarkbad5ad72017-08-03 17:14:08 -04002813 quickReject true
Cary Clark8032b982017-07-28 11:04:54 -04002814 quickReject false
2815 ##
2816}
2817##
2818
Cary Clark2ade9972017-11-02 17:49:34 -04002819#SeeAlso getLocalClipBounds getTotalMatrix SkBitmap::drawsNothing
Cary Clark8032b982017-07-28 11:04:54 -04002820
2821##
2822
Herb Derbyefe39bc2018-05-01 17:06:20 -04002823#Method SkRect getLocalClipBounds() const
Cary Clark8032b982017-07-28 11:04:54 -04002824
Cary Clarkab2621d2018-01-30 10:08:57 -05002825#In Clip
2826#Line # returns Clip bounds in source coordinates ##
Cary Clark8032b982017-07-28 11:04:54 -04002827Return bounds of Clip, transformed by inverse of Matrix. If Clip is empty,
2828return SkRect::MakeEmpty, where all Rect sides equal zero.
2829
2830Rect returned is outset by one to account for partial pixel coverage if Clip
Cary Clarkce101242017-09-01 15:51:02 -04002831is Anti-aliased.
Cary Clark8032b982017-07-28 11:04:54 -04002832
Cary Clarkbad5ad72017-08-03 17:14:08 -04002833#Return bounds of Clip in local coordinates ##
Cary Clark8032b982017-07-28 11:04:54 -04002834
2835#Example
Herb Derbyefe39bc2018-05-01 17:06:20 -04002836 #Description
Cary Clark8032b982017-07-28 11:04:54 -04002837 Initial bounds is device bounds outset by 1 on all sides.
2838 Clipped bounds is clipPath bounds outset by 1 on all sides.
2839 Scaling the canvas by two in x and y scales the local bounds by 1/2 in x and y.
2840 ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002841 SkCanvas local(256, 256);
2842 canvas = &local;
2843 SkRect bounds = canvas->getLocalClipBounds();
2844 SkDebugf("left:%g top:%g right:%g bottom:%g\n",
2845 bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom);
Herb Derbyefe39bc2018-05-01 17:06:20 -04002846 SkPoint clipPoints[] = {{30, 130}, {120, 130}, {120, 230} };
Cary Clarkbad5ad72017-08-03 17:14:08 -04002847 SkPath clipPath;
2848 clipPath.addPoly(clipPoints, SK_ARRAY_COUNT(clipPoints), true);
2849 canvas->clipPath(clipPath);
2850 bounds = canvas->getLocalClipBounds();
2851 SkDebugf("left:%g top:%g right:%g bottom:%g\n",
2852 bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom);
2853 canvas->scale(2, 2);
2854 bounds = canvas->getLocalClipBounds();
2855 SkDebugf("left:%g top:%g right:%g bottom:%g\n",
2856 bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom);
2857 #StdOut
2858 left:-1 top:-1 right:257 bottom:257
2859 left:29 top:129 right:121 bottom:231
2860 left:14.5 top:64.5 right:60.5 bottom:115.5
2861 ##
Cary Clark8032b982017-07-28 11:04:54 -04002862##
2863
2864# local canvas in example works around bug in fiddle ##
Cary Clark4855f782018-02-06 09:41:53 -05002865#Bug 6524
Cary Clark2ade9972017-11-02 17:49:34 -04002866#SeeAlso getDeviceClipBounds getBaseLayerSize quickReject
Cary Clark8032b982017-07-28 11:04:54 -04002867
2868##
2869
Herb Derbyefe39bc2018-05-01 17:06:20 -04002870#Method bool getLocalClipBounds(SkRect* bounds) const
Cary Clark8032b982017-07-28 11:04:54 -04002871
Cary Clarkab2621d2018-01-30 10:08:57 -05002872#In Clip
Cary Clark8032b982017-07-28 11:04:54 -04002873Return bounds of Clip, transformed by inverse of Matrix. If Clip is empty,
2874return false, and set bounds to SkRect::MakeEmpty, where all Rect sides equal zero.
2875
2876bounds is outset by one to account for partial pixel coverage if Clip
Cary Clarkce101242017-09-01 15:51:02 -04002877is Anti-aliased.
Cary Clark8032b982017-07-28 11:04:54 -04002878
Cary Clarkbad5ad72017-08-03 17:14:08 -04002879#Param bounds Rect of Clip in local coordinates ##
Cary Clark8032b982017-07-28 11:04:54 -04002880
Cary Clarkbad5ad72017-08-03 17:14:08 -04002881#Return true if Clip bounds is not empty ##
Cary Clark8032b982017-07-28 11:04:54 -04002882
2883#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04002884 void draw(SkCanvas* canvas) {
2885 SkCanvas local(256, 256);
2886 canvas = &local;
2887 SkRect bounds;
2888 SkDebugf("local bounds empty = %s\n", canvas->getLocalClipBounds(&bounds)
2889 ? "false" : "true");
2890 SkPath path;
2891 canvas->clipPath(path);
2892 SkDebugf("local bounds empty = %s\n", canvas->getLocalClipBounds(&bounds)
2893 ? "false" : "true");
Cary Clark8032b982017-07-28 11:04:54 -04002894 }
2895 #StdOut
Cary Clarkbad5ad72017-08-03 17:14:08 -04002896 local bounds empty = false
Cary Clark8032b982017-07-28 11:04:54 -04002897 local bounds empty = true
2898 ##
2899##
2900
2901# local canvas in example works around bug in fiddle ##
Cary Clark4855f782018-02-06 09:41:53 -05002902#Bug 6524
Cary Clark2ade9972017-11-02 17:49:34 -04002903#SeeAlso getDeviceClipBounds getBaseLayerSize quickReject
Cary Clark8032b982017-07-28 11:04:54 -04002904
2905##
2906
Herb Derbyefe39bc2018-05-01 17:06:20 -04002907#Method SkIRect getDeviceClipBounds() const
Cary Clark8032b982017-07-28 11:04:54 -04002908
Cary Clarkab2621d2018-01-30 10:08:57 -05002909#In Clip
2910#Line # returns IRect bounds of Clip ##
Cary Clark8032b982017-07-28 11:04:54 -04002911Return IRect bounds of Clip, unaffected by Matrix. If Clip is empty,
2912return SkRect::MakeEmpty, where all Rect sides equal zero.
2913
Herb Derbyefe39bc2018-05-01 17:06:20 -04002914Unlike getLocalClipBounds, returned IRect is not outset.
Cary Clark8032b982017-07-28 11:04:54 -04002915
Cary Clarkbad5ad72017-08-03 17:14:08 -04002916#Return bounds of Clip in Device coordinates ##
Cary Clark8032b982017-07-28 11:04:54 -04002917
2918#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04002919void draw(SkCanvas* canvas) {
2920 #Description
Cary Clark8032b982017-07-28 11:04:54 -04002921 Initial bounds is device bounds, not outset.
2922 Clipped bounds is clipPath bounds, not outset.
2923 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 -04002924 ##
2925 SkCanvas device(256, 256);
2926 canvas = &device;
2927 SkIRect bounds = canvas->getDeviceClipBounds();
2928 SkDebugf("left:%d top:%d right:%d bottom:%d\n",
2929 bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom);
Herb Derbyefe39bc2018-05-01 17:06:20 -04002930 SkPoint clipPoints[] = {{30, 130}, {120, 130}, {120, 230} };
Cary Clarkbad5ad72017-08-03 17:14:08 -04002931 SkPath clipPath;
2932 clipPath.addPoly(clipPoints, SK_ARRAY_COUNT(clipPoints), true);
2933 canvas->save();
2934 canvas->clipPath(clipPath);
2935 bounds = canvas->getDeviceClipBounds();
2936 SkDebugf("left:%d top:%d right:%d bottom:%d\n",
2937 bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom);
2938 canvas->restore();
2939 canvas->scale(1.f/2, 1.f/2);
2940 canvas->clipPath(clipPath);
2941 bounds = canvas->getDeviceClipBounds();
2942 SkDebugf("left:%d top:%d right:%d bottom:%d\n",
2943 bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom);
Cary Clark8032b982017-07-28 11:04:54 -04002944 #StdOut
Cary Clarkbad5ad72017-08-03 17:14:08 -04002945 left:0 top:0 right:256 bottom:256
2946 left:30 top:130 right:120 bottom:230
Cary Clark8032b982017-07-28 11:04:54 -04002947 left:15 top:65 right:60 bottom:115
2948 ##
2949}
2950##
2951
2952#ToDo some confusion on why with an identity Matrix local and device are different ##
Cary Clark2ade9972017-11-02 17:49:34 -04002953#SeeAlso getLocalClipBounds getBaseLayerSize quickReject
Cary Clark8032b982017-07-28 11:04:54 -04002954
2955# device canvas in example works around bug in fiddle ##
Cary Clark4855f782018-02-06 09:41:53 -05002956#Bug 6524
Cary Clark8032b982017-07-28 11:04:54 -04002957
2958##
2959
Herb Derbyefe39bc2018-05-01 17:06:20 -04002960#Method bool getDeviceClipBounds(SkIRect* bounds) const
Cary Clark8032b982017-07-28 11:04:54 -04002961
Cary Clarkab2621d2018-01-30 10:08:57 -05002962#In Clip
Cary Clark8032b982017-07-28 11:04:54 -04002963Return IRect bounds of Clip, unaffected by Matrix. If Clip is empty,
2964return false, and set bounds to SkRect::MakeEmpty, where all Rect sides equal zero.
2965
Herb Derbyefe39bc2018-05-01 17:06:20 -04002966Unlike getLocalClipBounds, bounds is not outset.
Cary Clark8032b982017-07-28 11:04:54 -04002967
Cary Clarkbad5ad72017-08-03 17:14:08 -04002968#Param bounds Rect of Clip in device coordinates ##
Cary Clark8032b982017-07-28 11:04:54 -04002969
Cary Clarkbad5ad72017-08-03 17:14:08 -04002970#Return true if Clip bounds is not empty ##
Cary Clark8032b982017-07-28 11:04:54 -04002971
2972#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04002973 void draw(SkCanvas* canvas) {
2974 SkIRect bounds;
2975 SkDebugf("device bounds empty = %s\n", canvas->getDeviceClipBounds(&bounds)
2976 ? "false" : "true");
2977 SkPath path;
2978 canvas->clipPath(path);
2979 SkDebugf("device bounds empty = %s\n", canvas->getDeviceClipBounds(&bounds)
2980 ? "false" : "true");
Cary Clark8032b982017-07-28 11:04:54 -04002981 }
2982 #StdOut
Cary Clarkbad5ad72017-08-03 17:14:08 -04002983 device bounds empty = false
Cary Clark8032b982017-07-28 11:04:54 -04002984 device bounds empty = true
2985 ##
2986##
2987
Cary Clark2ade9972017-11-02 17:49:34 -04002988#SeeAlso getLocalClipBounds getBaseLayerSize quickReject
Cary Clark8032b982017-07-28 11:04:54 -04002989
2990##
2991
Cary Clark08895c42018-02-01 09:37:32 -05002992#Subtopic Clip ##
Cary Clark8032b982017-07-28 11:04:54 -04002993
2994# ------------------------------------------------------------------------------
Cary Clark78de7512018-02-07 07:27:09 -05002995#Subtopic Draw
2996#Populate
2997#Line # draws into Canvas ##
2998##
Cary Clark8032b982017-07-28 11:04:54 -04002999
3000#Method void drawColor(SkColor color, SkBlendMode mode = SkBlendMode::kSrcOver)
Cary Clark78de7512018-02-07 07:27:09 -05003001#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05003002#Line # fills Clip with Color and Blend_Mode ##
Cary Clark8032b982017-07-28 11:04:54 -04003003Fill Clip with Color color.
3004mode determines how Color_ARGB is combined with destination.
3005
Cary Clarkbad5ad72017-08-03 17:14:08 -04003006#Param color Unpremultiplied Color_ARGB ##
3007#Param mode SkBlendMode used to combine source color and destination ##
Cary Clark8032b982017-07-28 11:04:54 -04003008
3009#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003010 canvas->drawColor(SK_ColorRED);
3011 canvas->clipRect(SkRect::MakeWH(150, 150));
3012 canvas->drawColor(SkColorSetARGB(0x80, 0x00, 0xFF, 0x00), SkBlendMode::kPlus);
3013 canvas->clipRect(SkRect::MakeWH(75, 75));
3014 canvas->drawColor(SkColorSetARGB(0x80, 0x00, 0x00, 0xFF), SkBlendMode::kPlus);
Cary Clark8032b982017-07-28 11:04:54 -04003015##
3016
Cary Clark2ade9972017-11-02 17:49:34 -04003017#SeeAlso clear SkBitmap::erase drawPaint
Cary Clark8032b982017-07-28 11:04:54 -04003018
3019##
3020
3021# ------------------------------------------------------------------------------
3022
Herb Derbyefe39bc2018-05-01 17:06:20 -04003023#Method void clear(SkColor color)
Cary Clark78de7512018-02-07 07:27:09 -05003024#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05003025#Line # fills Clip with Color ##
Herb Derbyefe39bc2018-05-01 17:06:20 -04003026Fill Clip with Color color using SkBlendMode::kSrc.
Cary Clark8032b982017-07-28 11:04:54 -04003027This has the effect of replacing all pixels contained by Clip with color.
3028
Cary Clarkbad5ad72017-08-03 17:14:08 -04003029#Param color Unpremultiplied Color_ARGB ##
Cary Clark8032b982017-07-28 11:04:54 -04003030
3031#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003032void draw(SkCanvas* canvas) {
3033 canvas->save();
3034 canvas->clipRect(SkRect::MakeWH(256, 128));
Herb Derbyefe39bc2018-05-01 17:06:20 -04003035 canvas->clear(SkColorSetARGB(0x80, 0xFF, 0x00, 0x00));
Cary Clarkbad5ad72017-08-03 17:14:08 -04003036 canvas->restore();
3037 canvas->save();
3038 canvas->clipRect(SkRect::MakeWH(150, 192));
3039 canvas->clear(SkColorSetARGB(0x80, 0x00, 0xFF, 0x00));
3040 canvas->restore();
3041 canvas->clipRect(SkRect::MakeWH(75, 256));
3042 canvas->clear(SkColorSetARGB(0x80, 0x00, 0x00, 0xFF));
Cary Clark8032b982017-07-28 11:04:54 -04003043}
3044##
3045
Cary Clark2ade9972017-11-02 17:49:34 -04003046#SeeAlso drawColor SkBitmap::erase drawPaint
Cary Clark8032b982017-07-28 11:04:54 -04003047
3048##
3049
3050# ------------------------------------------------------------------------------
3051
Herb Derbyefe39bc2018-05-01 17:06:20 -04003052#Method void discard()
Cary Clark78de7512018-02-07 07:27:09 -05003053#In Utility
Cary Clarkab2621d2018-01-30 10:08:57 -05003054#Line # makes Canvas contents undefined ##
Cary Clark8032b982017-07-28 11:04:54 -04003055Make Canvas contents undefined. Subsequent calls that read Canvas pixels,
3056such as drawing with SkBlendMode, return undefined results. discard() does
3057not change Clip or Matrix.
3058
3059discard() may do nothing, depending on the implementation of Surface or Device
3060that created Canvas.
3061
3062discard() allows optimized performance on subsequent draws by removing
3063cached data associated with Surface or Device.
3064It is not necessary to call discard() once done with Canvas;
3065any cached data is deleted when owning Surface or Device is deleted.
3066
3067#ToDo example? not sure how to make this meaningful w/o more implementation detail ##
Cary Clark2ade9972017-11-02 17:49:34 -04003068#SeeAlso flush() SkSurface::prepareForExternalIO GrContext::abandonContext
Cary Clark8032b982017-07-28 11:04:54 -04003069
Herb Derbyefe39bc2018-05-01 17:06:20 -04003070#NoExample
Cary Clark8032b982017-07-28 11:04:54 -04003071##
3072
3073##
3074
3075# ------------------------------------------------------------------------------
3076
3077#Method void drawPaint(const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05003078#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05003079#Line # fills Clip with Paint ##
Mike Reed8ad91a92018-01-19 19:09:32 -05003080Fill Clip with Paint paint. Paint components Mask_Filter, Shader,
Cary Clarkbad5ad72017-08-03 17:14:08 -04003081Color_Filter, Image_Filter, and Blend_Mode affect drawing;
3082Path_Effect in paint is ignored.
Cary Clark8032b982017-07-28 11:04:54 -04003083
3084# can Path_Effect in paint ever alter drawPaint?
3085
Cary Clarkbad5ad72017-08-03 17:14:08 -04003086#Param paint graphics state used to fill Canvas ##
Cary Clark8032b982017-07-28 11:04:54 -04003087
3088#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003089void draw(SkCanvas* canvas) {
3090 SkColor colors[] = { SK_ColorRED, SK_ColorGREEN, SK_ColorBLUE };
3091 SkScalar pos[] = { 0, SK_Scalar1/2, SK_Scalar1 };
3092 SkPaint paint;
3093 paint.setShader(SkGradientShader::MakeSweep(256, 256, colors, pos, SK_ARRAY_COUNT(colors)));
3094 canvas->drawPaint(paint);
Cary Clark8032b982017-07-28 11:04:54 -04003095}
3096##
3097
Cary Clark2ade9972017-11-02 17:49:34 -04003098#SeeAlso clear drawColor SkBitmap::erase
Cary Clark8032b982017-07-28 11:04:54 -04003099
3100##
3101
3102# ------------------------------------------------------------------------------
3103
3104#Enum PointMode
Cary Clark08895c42018-02-01 09:37:32 -05003105#Line # sets drawPoints options ##
Cary Clark8032b982017-07-28 11:04:54 -04003106
3107#Code
3108 enum PointMode {
3109 kPoints_PointMode,
3110 kLines_PointMode,
Cary Clarkd0530ba2017-09-14 11:25:39 -04003111 kPolygon_PointMode,
Cary Clark8032b982017-07-28 11:04:54 -04003112 };
3113##
3114
3115Selects if an array of points are drawn as discrete points, as lines, or as
3116an open polygon.
3117
3118#Const kPoints_PointMode 0
3119 Draw each point separately.
3120##
3121
3122#Const kLines_PointMode 1
3123 Draw each pair of points as a line segment.
3124##
3125
3126#Const kPolygon_PointMode 2
3127 Draw the array of points as a open polygon.
3128##
3129
3130#Example
Herb Derbyefe39bc2018-05-01 17:06:20 -04003131 #Description
Cary Clark8032b982017-07-28 11:04:54 -04003132 The upper left corner shows three squares when drawn as points.
3133 The upper right corner shows one line; when drawn as lines, two points are required per line.
3134 The lower right corner shows two lines; when draw as polygon, no miter is drawn at the corner.
3135 The lower left corner shows two lines with a miter when path contains polygon.
3136 ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003137void draw(SkCanvas* canvas) {
3138 SkPaint paint;
3139 paint.setStyle(SkPaint::kStroke_Style);
3140 paint.setStrokeWidth(10);
3141 SkPoint points[] = {{64, 32}, {96, 96}, {32, 96}};
3142 canvas->drawPoints(SkCanvas::kPoints_PointMode, 3, points, paint);
3143 canvas->translate(128, 0);
3144 canvas->drawPoints(SkCanvas::kLines_PointMode, 3, points, paint);
3145 canvas->translate(0, 128);
3146 canvas->drawPoints(SkCanvas::kPolygon_PointMode, 3, points, paint);
3147 SkPath path;
3148 path.addPoly(points, 3, false);
3149 canvas->translate(-128, 0);
3150 canvas->drawPath(path, paint);
Cary Clark8032b982017-07-28 11:04:54 -04003151}
3152##
3153
Cary Clark2ade9972017-11-02 17:49:34 -04003154#SeeAlso drawLine drawPoint drawPath
Cary Clark8032b982017-07-28 11:04:54 -04003155
3156##
3157
3158# ------------------------------------------------------------------------------
3159
3160#Method void drawPoints(PointMode mode, size_t count, const SkPoint pts[], const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05003161#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05003162#Line # draws array as points, lines, polygon ##
Cary Clark8032b982017-07-28 11:04:54 -04003163Draw pts using Clip, Matrix and Paint paint.
Cary Clarkbad5ad72017-08-03 17:14:08 -04003164count is the number of points; if count is less than one, has no effect.
Cary Clark8032b982017-07-28 11:04:54 -04003165mode may be one of: kPoints_PointMode, kLines_PointMode, or kPolygon_PointMode.
3166
Cary Clarkbad5ad72017-08-03 17:14:08 -04003167If mode is kPoints_PointMode, the shape of point drawn depends on paint
3168Paint_Stroke_Cap. If paint is set to SkPaint::kRound_Cap, each point draws a
3169circle of diameter Paint_Stroke_Width. If paint is set to SkPaint::kSquare_Cap
3170or SkPaint::kButt_Cap, each point draws a square of width and height
3171Paint_Stroke_Width.
Cary Clark8032b982017-07-28 11:04:54 -04003172
3173If mode is kLines_PointMode, each pair of points draws a line segment.
3174One line is drawn for every two points; each point is used once. If count is odd,
Herb Derbyefe39bc2018-05-01 17:06:20 -04003175the final point is ignored.
Cary Clark8032b982017-07-28 11:04:54 -04003176
3177If mode is kPolygon_PointMode, each adjacent pair of points draws a line segment.
3178count minus one lines are drawn; the first and last point are used once.
3179
3180Each line segment respects paint Paint_Stroke_Cap and Paint_Stroke_Width.
3181Paint_Style is ignored, as if were set to SkPaint::kStroke_Style.
3182
Cary Clarkbad5ad72017-08-03 17:14:08 -04003183Always draws each element one at a time; is not affected by
3184Paint_Stroke_Join, and unlike drawPath, does not create a mask from all points
Herb Derbyefe39bc2018-05-01 17:06:20 -04003185and lines before drawing.
Cary Clark8032b982017-07-28 11:04:54 -04003186
Cary Clarka523d2d2017-08-30 08:58:10 -04003187#Param mode whether pts draws points or lines ##
3188#Param count number of points in the array ##
3189#Param pts array of points to draw ##
3190#Param paint stroke, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003191
3192#Example
3193#Height 200
Herb Derbyefe39bc2018-05-01 17:06:20 -04003194 #Description
Cary Clark8032b982017-07-28 11:04:54 -04003195 #List
3196 # The first column draws points. ##
3197 # The second column draws points as lines. ##
3198 # The third column draws points as a polygon. ##
3199 # The fourth column draws points as a polygonal path. ##
3200 # The first row uses a round cap and round join. ##
3201 # The second row uses a square cap and a miter join. ##
3202 # The third row uses a butt cap and a bevel join. ##
3203 ##
3204 The transparent color makes multiple line draws visible;
3205 the path is drawn all at once.
3206 ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003207void draw(SkCanvas* canvas) {
3208 SkPaint paint;
3209 paint.setAntiAlias(true);
3210 paint.setStyle(SkPaint::kStroke_Style);
3211 paint.setStrokeWidth(10);
3212 paint.setColor(0x80349a45);
3213 const SkPoint points[] = {{32, 16}, {48, 48}, {16, 32}};
Herb Derbyefe39bc2018-05-01 17:06:20 -04003214 const SkPaint::Join join[] = { SkPaint::kRound_Join,
Cary Clarkbad5ad72017-08-03 17:14:08 -04003215 SkPaint::kMiter_Join,
3216 SkPaint::kBevel_Join };
3217 int joinIndex = 0;
3218 SkPath path;
3219 path.addPoly(points, 3, false);
3220 for (const auto cap : { SkPaint::kRound_Cap, SkPaint::kSquare_Cap, SkPaint::kButt_Cap } ) {
3221 paint.setStrokeCap(cap);
3222 paint.setStrokeJoin(join[joinIndex++]);
3223 for (const auto mode : { SkCanvas::kPoints_PointMode,
3224 SkCanvas::kLines_PointMode,
3225 SkCanvas::kPolygon_PointMode } ) {
3226 canvas->drawPoints(mode, 3, points, paint);
3227 canvas->translate(64, 0);
3228 }
3229 canvas->drawPath(path, paint);
3230 canvas->translate(-192, 64);
3231 }
Cary Clark8032b982017-07-28 11:04:54 -04003232}
3233##
3234
Cary Clark2ade9972017-11-02 17:49:34 -04003235#SeeAlso drawLine drawPoint drawPath
Cary Clark8032b982017-07-28 11:04:54 -04003236
3237##
3238
3239# ------------------------------------------------------------------------------
3240
3241#Method void drawPoint(SkScalar x, SkScalar y, const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05003242#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05003243#Line # draws point at (x, y) position ##
Cary Clark8032b982017-07-28 11:04:54 -04003244Draw point at (x, y) using Clip, Matrix and Paint paint.
3245
3246The shape of point drawn depends on paint Paint_Stroke_Cap.
Cary Clarkbad5ad72017-08-03 17:14:08 -04003247If paint is set to SkPaint::kRound_Cap, draw a circle of diameter
Herb Derbyefe39bc2018-05-01 17:06:20 -04003248Paint_Stroke_Width. If paint is set to SkPaint::kSquare_Cap or SkPaint::kButt_Cap,
Cary Clark8032b982017-07-28 11:04:54 -04003249draw a square of width and height Paint_Stroke_Width.
3250Paint_Style is ignored, as if were set to SkPaint::kStroke_Style.
3251
Cary Clarkbad5ad72017-08-03 17:14:08 -04003252#Param x left edge of circle or square ##
3253#Param y top edge of circle or square ##
3254#Param paint stroke, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003255
3256#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003257void draw(SkCanvas* canvas) {
3258 SkPaint paint;
3259 paint.setAntiAlias(true);
3260 paint.setColor(0x80349a45);
3261 paint.setStyle(SkPaint::kStroke_Style);
3262 paint.setStrokeWidth(100);
3263 paint.setStrokeCap(SkPaint::kRound_Cap);
3264 canvas->scale(1, 1.2f);
3265 canvas->drawPoint(64, 96, paint);
3266 canvas->scale(.6f, .8f);
3267 paint.setColor(SK_ColorWHITE);
3268 canvas->drawPoint(106, 120, paint);
Cary Clark8032b982017-07-28 11:04:54 -04003269}
3270##
3271
Cary Clark2ade9972017-11-02 17:49:34 -04003272#SeeAlso drawPoints drawCircle drawRect drawLine drawPath
Cary Clark8032b982017-07-28 11:04:54 -04003273
3274##
3275
Cary Clarkbad5ad72017-08-03 17:14:08 -04003276#Method void drawPoint(SkPoint p, const SkPaint& paint)
3277
3278Draw point p using Clip, Matrix and Paint paint.
3279
3280The shape of point drawn depends on paint Paint_Stroke_Cap.
3281If paint is set to SkPaint::kRound_Cap, draw a circle of diameter
Herb Derbyefe39bc2018-05-01 17:06:20 -04003282Paint_Stroke_Width. If paint is set to SkPaint::kSquare_Cap or SkPaint::kButt_Cap,
Cary Clarkbad5ad72017-08-03 17:14:08 -04003283draw a square of width and height Paint_Stroke_Width.
3284Paint_Style is ignored, as if were set to SkPaint::kStroke_Style.
3285
3286#Param p top-left edge of circle or square ##
3287#Param paint stroke, blend, color, and so on, used to draw ##
3288
3289#Example
3290void draw(SkCanvas* canvas) {
3291 SkPaint paint;
3292 paint.setAntiAlias(true);
3293 paint.setColor(0x80349a45);
3294 paint.setStyle(SkPaint::kStroke_Style);
3295 paint.setStrokeWidth(100);
3296 paint.setStrokeCap(SkPaint::kSquare_Cap);
3297 canvas->scale(1, 1.2f);
3298 canvas->drawPoint({64, 96}, paint);
3299 canvas->scale(.6f, .8f);
3300 paint.setColor(SK_ColorWHITE);
3301 canvas->drawPoint(106, 120, paint);
3302}
3303##
3304
Cary Clark2ade9972017-11-02 17:49:34 -04003305#SeeAlso drawPoints drawCircle drawRect drawLine drawPath
Cary Clarkbad5ad72017-08-03 17:14:08 -04003306
3307##
3308
Cary Clark8032b982017-07-28 11:04:54 -04003309# ------------------------------------------------------------------------------
3310
3311#Method void drawLine(SkScalar x0, SkScalar y0, SkScalar x1, SkScalar y1, const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05003312#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05003313#Line # draws line segment between two points ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003314Draws line segment from (x0, y0) to (x1, y1) using Clip, Matrix, and Paint paint.
3315In paint: Paint_Stroke_Width describes the line thickness;
3316Paint_Stroke_Cap draws the end rounded or square;
Cary Clark8032b982017-07-28 11:04:54 -04003317Paint_Style is ignored, as if were set to SkPaint::kStroke_Style.
3318
Cary Clarkbad5ad72017-08-03 17:14:08 -04003319#Param x0 start of line segment on x-axis ##
3320#Param y0 start of line segment on y-axis ##
3321#Param x1 end of line segment on x-axis ##
3322#Param y1 end of line segment on y-axis ##
3323#Param paint stroke, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003324
3325#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003326 SkPaint paint;
3327 paint.setAntiAlias(true);
3328 paint.setColor(0xFF9a67be);
3329 paint.setStrokeWidth(20);
3330 canvas->skew(1, 0);
3331 canvas->drawLine(32, 96, 32, 160, paint);
3332 canvas->skew(-2, 0);
3333 canvas->drawLine(288, 96, 288, 160, paint);
3334##
3335
Cary Clark2ade9972017-11-02 17:49:34 -04003336#SeeAlso drawPoint drawCircle drawRect drawPath
Cary Clarkbad5ad72017-08-03 17:14:08 -04003337
3338##
3339
3340#Method void drawLine(SkPoint p0, SkPoint p1, const SkPaint& paint)
3341
3342Draws line segment from p0 to p1 using Clip, Matrix, and Paint paint.
3343In paint: Paint_Stroke_Width describes the line thickness;
3344Paint_Stroke_Cap draws the end rounded or square;
3345Paint_Style is ignored, as if were set to SkPaint::kStroke_Style.
3346
3347#Param p0 start of line segment ##
3348#Param p1 end of line segment ##
3349#Param paint stroke, blend, color, and so on, used to draw ##
3350
3351#Example
3352 SkPaint paint;
3353 paint.setAntiAlias(true);
3354 paint.setColor(0xFF9a67be);
3355 paint.setStrokeWidth(20);
3356 canvas->skew(1, 0);
3357 canvas->drawLine({32, 96}, {32, 160}, paint);
3358 canvas->skew(-2, 0);
3359 canvas->drawLine({288, 96}, {288, 160}, paint);
Cary Clark8032b982017-07-28 11:04:54 -04003360##
3361
Cary Clark2ade9972017-11-02 17:49:34 -04003362#SeeAlso drawPoint drawCircle drawRect drawPath
Cary Clark8032b982017-07-28 11:04:54 -04003363
3364##
3365
3366# ------------------------------------------------------------------------------
3367
3368#Method void drawRect(const SkRect& rect, const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05003369#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05003370#Line # draws Rect using Clip, Matrix, and Paint ##
Cary Clark8032b982017-07-28 11:04:54 -04003371Draw Rect rect using Clip, Matrix, and Paint paint.
Herb Derbyefe39bc2018-05-01 17:06:20 -04003372In paint: Paint_Style determines if rectangle is stroked or filled;
Cary Clark8032b982017-07-28 11:04:54 -04003373if stroked, Paint_Stroke_Width describes the line thickness, and
3374Paint_Stroke_Join draws the corners rounded or square.
3375
Cary Clarkbc5697d2017-10-04 14:31:33 -04003376#Param rect rectangle to draw ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003377#Param paint stroke or fill, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003378
3379#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003380void draw(SkCanvas* canvas) {
3381 SkPoint rectPts[] = { {64, 48}, {192, 160} };
3382 SkPaint paint;
3383 paint.setAntiAlias(true);
3384 paint.setStyle(SkPaint::kStroke_Style);
3385 paint.setStrokeWidth(20);
3386 paint.setStrokeJoin(SkPaint::kRound_Join);
3387 SkMatrix rotator;
3388 rotator.setRotate(30, 128, 128);
3389 for (auto color : { SK_ColorRED, SK_ColorBLUE, SK_ColorYELLOW, SK_ColorMAGENTA } ) {
3390 paint.setColor(color);
3391 SkRect rect;
3392 rect.set(rectPts[0], rectPts[1]);
3393 canvas->drawRect(rect, paint);
3394 rotator.mapPoints(rectPts, 2);
3395 }
Cary Clark8032b982017-07-28 11:04:54 -04003396}
3397##
3398
Herb Derbyefe39bc2018-05-01 17:06:20 -04003399#SeeAlso drawIRect drawRRect drawRoundRect drawRegion drawPath drawLine
Cary Clark8032b982017-07-28 11:04:54 -04003400
3401##
3402
3403# ------------------------------------------------------------------------------
3404
Herb Derbyefe39bc2018-05-01 17:06:20 -04003405#Method void drawIRect(const SkIRect& rect, const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05003406#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05003407#Line # draws IRect using Clip, Matrix, and Paint ##
Cary Clark8032b982017-07-28 11:04:54 -04003408Draw IRect rect using Clip, Matrix, and Paint paint.
Herb Derbyefe39bc2018-05-01 17:06:20 -04003409In paint: Paint_Style determines if rectangle is stroked or filled;
Cary Clark8032b982017-07-28 11:04:54 -04003410if stroked, Paint_Stroke_Width describes the line thickness, and
3411Paint_Stroke_Join draws the corners rounded or square.
3412
Cary Clarkbc5697d2017-10-04 14:31:33 -04003413#Param rect rectangle to draw ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003414#Param paint stroke or fill, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003415
3416#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003417 SkIRect rect = { 64, 48, 192, 160 };
3418 SkPaint paint;
3419 paint.setAntiAlias(true);
3420 paint.setStyle(SkPaint::kStroke_Style);
3421 paint.setStrokeWidth(20);
3422 paint.setStrokeJoin(SkPaint::kRound_Join);
3423 for (auto color : { SK_ColorRED, SK_ColorBLUE, SK_ColorYELLOW, SK_ColorMAGENTA } ) {
3424 paint.setColor(color);
3425 canvas->drawIRect(rect, paint);
3426 canvas->rotate(30, 128, 128);
3427 }
Cary Clark8032b982017-07-28 11:04:54 -04003428##
3429
Cary Clark2ade9972017-11-02 17:49:34 -04003430#SeeAlso drawRect drawRRect drawRoundRect drawRegion drawPath drawLine
Cary Clark8032b982017-07-28 11:04:54 -04003431
3432##
3433
3434# ------------------------------------------------------------------------------
3435
3436#Method void drawRegion(const SkRegion& region, const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05003437#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05003438#Line # draws Region using Clip, Matrix, and Paint ##
Cary Clark8032b982017-07-28 11:04:54 -04003439Draw Region region using Clip, Matrix, and Paint paint.
Herb Derbyefe39bc2018-05-01 17:06:20 -04003440In paint: Paint_Style determines if rectangle is stroked or filled;
Cary Clark8032b982017-07-28 11:04:54 -04003441if stroked, Paint_Stroke_Width describes the line thickness, and
3442Paint_Stroke_Join draws the corners rounded or square.
3443
Cary Clarkbc5697d2017-10-04 14:31:33 -04003444#Param region region to draw ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003445#Param paint Paint stroke or fill, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003446
3447#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003448void draw(SkCanvas* canvas) {
3449 SkRegion region;
3450 region.op( 10, 10, 50, 50, SkRegion::kUnion_Op);
3451 region.op( 10, 50, 90, 90, SkRegion::kUnion_Op);
3452 SkPaint paint;
3453 paint.setAntiAlias(true);
3454 paint.setStyle(SkPaint::kStroke_Style);
3455 paint.setStrokeWidth(20);
3456 paint.setStrokeJoin(SkPaint::kRound_Join);
3457 canvas->drawRegion(region, paint);
Cary Clark8032b982017-07-28 11:04:54 -04003458}
3459##
3460
Cary Clark2ade9972017-11-02 17:49:34 -04003461#SeeAlso drawRect drawIRect drawPath
Cary Clark8032b982017-07-28 11:04:54 -04003462
3463##
3464
3465# ------------------------------------------------------------------------------
3466
3467#Method void drawOval(const SkRect& oval, const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05003468#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05003469#Line # draws Oval using Clip, Matrix, and Paint ##
Cary Clark8032b982017-07-28 11:04:54 -04003470Draw Oval oval using Clip, Matrix, and Paint.
Herb Derbyefe39bc2018-05-01 17:06:20 -04003471In paint: Paint_Style determines if Oval is stroked or filled;
Cary Clark8032b982017-07-28 11:04:54 -04003472if stroked, Paint_Stroke_Width describes the line thickness.
3473
Cary Clarkbad5ad72017-08-03 17:14:08 -04003474#Param oval Rect bounds of Oval ##
3475#Param paint Paint stroke or fill, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003476
3477#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003478void draw(SkCanvas* canvas) {
3479 canvas->clear(0xFF3f5f9f);
3480 SkColor kColor1 = SkColorSetARGB(0xff, 0xff, 0x7f, 0);
3481 SkColor g1Colors[] = { kColor1, SkColorSetA(kColor1, 0x20) };
3482 SkPoint g1Points[] = { { 0, 0 }, { 0, 100 } };
3483 SkScalar pos[] = { 0.2f, 1.0f };
3484 SkRect bounds = SkRect::MakeWH(80, 70);
3485 SkPaint paint;
3486 paint.setAntiAlias(true);
3487 paint.setShader(SkGradientShader::MakeLinear(g1Points, g1Colors, pos, SK_ARRAY_COUNT(g1Colors),
3488 SkShader::kClamp_TileMode));
3489 canvas->drawOval(bounds , paint);
Cary Clark8032b982017-07-28 11:04:54 -04003490}
3491##
3492
Cary Clark2ade9972017-11-02 17:49:34 -04003493#SeeAlso drawCircle drawPoint drawPath drawRRect drawRoundRect
Cary Clark8032b982017-07-28 11:04:54 -04003494
3495##
3496
3497# ------------------------------------------------------------------------------
3498
3499#Method void drawRRect(const SkRRect& rrect, const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05003500#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05003501#Line # draws Round_Rect using Clip, Matrix, and Paint ##
Cary Clark8032b982017-07-28 11:04:54 -04003502Draw Round_Rect rrect using Clip, Matrix, and Paint paint.
Herb Derbyefe39bc2018-05-01 17:06:20 -04003503In paint: Paint_Style determines if rrect is stroked or filled;
Cary Clark8032b982017-07-28 11:04:54 -04003504if stroked, Paint_Stroke_Width describes the line thickness.
3505
Cary Clarkbad5ad72017-08-03 17:14:08 -04003506rrect may represent a rectangle, circle, oval, uniformly rounded rectangle, or
3507may have any combination of positive non-square radii for the four corners.
Cary Clark8032b982017-07-28 11:04:54 -04003508
Cary Clarkbad5ad72017-08-03 17:14:08 -04003509#Param rrect Round_Rect with up to eight corner radii to draw ##
3510#Param paint Paint stroke or fill, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003511
3512#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003513void draw(SkCanvas* canvas) {
3514 SkPaint paint;
3515 paint.setAntiAlias(true);
3516 SkRect outer = {30, 40, 210, 220};
3517 SkRect radii = {30, 50, 70, 90 };
3518 SkRRect rRect;
3519 rRect.setNinePatch(outer, radii.fLeft, radii.fTop, radii.fRight, radii.fBottom);
3520 canvas->drawRRect(rRect, paint);
3521 paint.setColor(SK_ColorWHITE);
3522 canvas->drawLine(outer.fLeft + radii.fLeft, outer.fTop,
3523 outer.fLeft + radii.fLeft, outer.fBottom, paint);
Herb Derbyefe39bc2018-05-01 17:06:20 -04003524 canvas->drawLine(outer.fRight - radii.fRight, outer.fTop,
Cary Clarkbad5ad72017-08-03 17:14:08 -04003525 outer.fRight - radii.fRight, outer.fBottom, paint);
Herb Derbyefe39bc2018-05-01 17:06:20 -04003526 canvas->drawLine(outer.fLeft, outer.fTop + radii.fTop,
Cary Clarkbad5ad72017-08-03 17:14:08 -04003527 outer.fRight, outer.fTop + radii.fTop, paint);
Herb Derbyefe39bc2018-05-01 17:06:20 -04003528 canvas->drawLine(outer.fLeft, outer.fBottom - radii.fBottom,
Cary Clarkbad5ad72017-08-03 17:14:08 -04003529 outer.fRight, outer.fBottom - radii.fBottom, paint);
3530}
Cary Clark8032b982017-07-28 11:04:54 -04003531##
3532
Cary Clark2ade9972017-11-02 17:49:34 -04003533#SeeAlso drawRect drawRoundRect drawDRRect drawCircle drawOval drawPath
Cary Clark8032b982017-07-28 11:04:54 -04003534
3535##
3536
3537# ------------------------------------------------------------------------------
3538
3539#Method void drawDRRect(const SkRRect& outer, const SkRRect& inner, const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05003540#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05003541#Line # draws double Round_Rect stroked or filled ##
Cary Clark8032b982017-07-28 11:04:54 -04003542Draw Round_Rect outer and inner
Herb Derbyefe39bc2018-05-01 17:06:20 -04003543using Clip, Matrix, and Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04003544outer must contain inner or the drawing is undefined.
Herb Derbyefe39bc2018-05-01 17:06:20 -04003545In paint: Paint_Style determines if Round_Rect is stroked or filled;
Cary Clark8032b982017-07-28 11:04:54 -04003546if stroked, Paint_Stroke_Width describes the line thickness.
Cary Clarkbad5ad72017-08-03 17:14:08 -04003547If stroked and Round_Rect corner has zero length radii, Paint_Stroke_Join can
Herb Derbyefe39bc2018-05-01 17:06:20 -04003548draw corners rounded or square.
Cary Clark8032b982017-07-28 11:04:54 -04003549
Cary Clarkbad5ad72017-08-03 17:14:08 -04003550GPU-backed platforms optimize drawing when both outer and inner are
Cary Clark8032b982017-07-28 11:04:54 -04003551concave and outer contains inner. These platforms may not be able to draw
Herb Derbyefe39bc2018-05-01 17:06:20 -04003552Path built with identical data as fast.
Cary Clark8032b982017-07-28 11:04:54 -04003553
Cary Clarkbad5ad72017-08-03 17:14:08 -04003554#Param outer Round_Rect outer bounds to draw ##
3555#Param inner Round_Rect inner bounds to draw ##
3556#Param paint Paint stroke or fill, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003557
3558#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003559void draw(SkCanvas* canvas) {
3560 SkRRect outer = SkRRect::MakeRect({20, 40, 210, 200});
3561 SkRRect inner = SkRRect::MakeOval({60, 70, 170, 160});
3562 SkPaint paint;
3563 canvas->drawDRRect(outer, inner, paint);
Cary Clark8032b982017-07-28 11:04:54 -04003564}
3565##
3566
3567#Example
3568#Description
3569 Outer Rect has no corner radii, but stroke join is rounded.
3570 Inner Round_Rect has corner radii; outset stroke increases radii of corners.
3571 Stroke join does not affect inner Round_Rect since it has no sharp corners.
3572##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003573void draw(SkCanvas* canvas) {
3574 SkRRect outer = SkRRect::MakeRect({20, 40, 210, 200});
3575 SkRRect inner = SkRRect::MakeRectXY({60, 70, 170, 160}, 10, 10);
3576 SkPaint paint;
3577 paint.setAntiAlias(true);
3578 paint.setStyle(SkPaint::kStroke_Style);
3579 paint.setStrokeWidth(20);
3580 paint.setStrokeJoin(SkPaint::kRound_Join);
3581 canvas->drawDRRect(outer, inner, paint);
3582 paint.setStrokeWidth(1);
3583 paint.setColor(SK_ColorWHITE);
3584 canvas->drawDRRect(outer, inner, paint);
Cary Clark8032b982017-07-28 11:04:54 -04003585}
3586##
3587
Cary Clark2ade9972017-11-02 17:49:34 -04003588#SeeAlso drawRect drawRoundRect drawRRect drawCircle drawOval drawPath
Cary Clark8032b982017-07-28 11:04:54 -04003589
3590##
3591
3592# ------------------------------------------------------------------------------
3593
3594#Method void drawCircle(SkScalar cx, SkScalar cy, SkScalar radius, const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05003595#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05003596#Line # draws Circle using Clip, Matrix, and Paint ##
Cary Clark8032b982017-07-28 11:04:54 -04003597Draw Circle at (cx, cy) with radius using Clip, Matrix, and Paint paint.
3598If radius is zero or less, nothing is drawn.
Herb Derbyefe39bc2018-05-01 17:06:20 -04003599In paint: Paint_Style determines if Circle is stroked or filled;
Cary Clark8032b982017-07-28 11:04:54 -04003600if stroked, Paint_Stroke_Width describes the line thickness.
3601
Cary Clarkbad5ad72017-08-03 17:14:08 -04003602#Param cx Circle center on the x-axis ##
3603#Param cy Circle center on the y-axis ##
3604#Param radius half the diameter of Circle ##
3605#Param paint Paint stroke or fill, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003606
3607#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003608 void draw(SkCanvas* canvas) {
3609 SkPaint paint;
3610 paint.setAntiAlias(true);
3611 canvas->drawCircle(128, 128, 90, paint);
3612 paint.setColor(SK_ColorWHITE);
3613 canvas->drawCircle(86, 86, 20, paint);
3614 canvas->drawCircle(160, 76, 20, paint);
3615 canvas->drawCircle(140, 150, 35, paint);
3616 }
3617##
3618
Cary Clark2ade9972017-11-02 17:49:34 -04003619#SeeAlso drawOval drawRRect drawRoundRect drawPath drawArc drawPoint drawLine
Cary Clarkbad5ad72017-08-03 17:14:08 -04003620
3621##
3622
3623#Method void drawCircle(SkPoint center, SkScalar radius, const SkPaint& paint)
3624
Cary Clarkce101242017-09-01 15:51:02 -04003625Draw Circle at center with radius using Clip, Matrix, and Paint paint.
Cary Clarkbad5ad72017-08-03 17:14:08 -04003626If radius is zero or less, nothing is drawn.
Herb Derbyefe39bc2018-05-01 17:06:20 -04003627In paint: Paint_Style determines if Circle is stroked or filled;
Cary Clarkbad5ad72017-08-03 17:14:08 -04003628if stroked, Paint_Stroke_Width describes the line thickness.
3629
3630#Param center Circle center ##
3631#Param radius half the diameter of Circle ##
3632#Param paint Paint stroke or fill, blend, color, and so on, used to draw ##
3633
3634#Example
3635 void draw(SkCanvas* canvas) {
3636 SkPaint paint;
3637 paint.setAntiAlias(true);
3638 canvas->drawCircle(128, 128, 90, paint);
3639 paint.setColor(SK_ColorWHITE);
3640 canvas->drawCircle({86, 86}, 20, paint);
3641 canvas->drawCircle({160, 76}, 20, paint);
3642 canvas->drawCircle({140, 150}, 35, paint);
3643 }
Cary Clark8032b982017-07-28 11:04:54 -04003644##
3645
Cary Clark2ade9972017-11-02 17:49:34 -04003646#SeeAlso drawOval drawRRect drawRoundRect drawPath drawArc drawPoint drawLine
Cary Clark8032b982017-07-28 11:04:54 -04003647
3648##
3649
3650# ------------------------------------------------------------------------------
3651
3652#Method void drawArc(const SkRect& oval, SkScalar startAngle, SkScalar sweepAngle,
3653 bool useCenter, const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05003654#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05003655#Line # draws Arc using Clip, Matrix, and Paint ##
Cary Clark8032b982017-07-28 11:04:54 -04003656
3657Draw Arc using Clip, Matrix, and Paint paint.
Cary Clarkbad5ad72017-08-03 17:14:08 -04003658
Cary Clark8032b982017-07-28 11:04:54 -04003659Arc is part of Oval bounded by oval, sweeping from startAngle to startAngle plus
3660sweepAngle. startAngle and sweepAngle are in degrees.
Cary Clarkbad5ad72017-08-03 17:14:08 -04003661
Cary Clark8032b982017-07-28 11:04:54 -04003662startAngle of zero places start point at the right middle edge of oval.
3663A positive sweepAngle places Arc end point clockwise from start point;
3664a negative sweepAngle places Arc end point counterclockwise from start point.
3665sweepAngle may exceed 360 degrees, a full circle.
3666If useCenter is true, draw a wedge that includes lines from oval
3667center to Arc end points. If useCenter is false, draw Arc between end points.
3668
3669If Rect oval is empty or sweepAngle is zero, nothing is drawn.
3670
Cary Clarkbad5ad72017-08-03 17:14:08 -04003671#Param oval Rect bounds of Oval containing Arc to draw ##
3672#Param startAngle angle in degrees where Arc begins ##
3673#Param sweepAngle sweep angle in degrees; positive is clockwise ##
3674#Param useCenter if true, include the center of the oval ##
3675#Param paint Paint stroke or fill, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003676
3677#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003678 void draw(SkCanvas* canvas) {
3679 SkPaint paint;
3680 paint.setAntiAlias(true);
3681 SkRect oval = { 4, 4, 60, 60};
3682 for (auto useCenter : { false, true } ) {
3683 for (auto style : { SkPaint::kFill_Style, SkPaint::kStroke_Style } ) {
3684 paint.setStyle(style);
3685 for (auto degrees : { 45, 90, 180, 360} ) {
3686 canvas->drawArc(oval, 0, degrees , useCenter, paint);
3687 canvas->translate(64, 0);
3688 }
3689 canvas->translate(-256, 64);
3690 }
3691 }
Cary Clark8032b982017-07-28 11:04:54 -04003692 }
3693##
3694
3695#Example
3696#Height 64
Cary Clarkbad5ad72017-08-03 17:14:08 -04003697 void draw(SkCanvas* canvas) {
3698 SkPaint paint;
3699 paint.setAntiAlias(true);
3700 paint.setStyle(SkPaint::kStroke_Style);
3701 paint.setStrokeWidth(4);
3702 SkRect oval = { 4, 4, 60, 60};
3703 float intervals[] = { 5, 5 };
3704 paint.setPathEffect(SkDashPathEffect::Make(intervals, 2, 2.5f));
3705 for (auto degrees : { 270, 360, 540, 720 } ) {
3706 canvas->drawArc(oval, 0, degrees, false, paint);
3707 canvas->translate(64, 0);
3708 }
Cary Clark8032b982017-07-28 11:04:54 -04003709 }
3710##
3711
Cary Clark2ade9972017-11-02 17:49:34 -04003712#SeeAlso SkPath::arcTo drawCircle drawOval drawPath
Cary Clark8032b982017-07-28 11:04:54 -04003713
3714##
3715
3716# ------------------------------------------------------------------------------
3717
3718#Method void drawRoundRect(const SkRect& rect, SkScalar rx, SkScalar ry, const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05003719#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05003720#Line # draws Round_Rect using Clip, Matrix, and Paint ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003721Draw Round_Rect bounded by Rect rect, with corner radii (rx, ry) using Clip,
3722Matrix, and Paint paint.
3723
Herb Derbyefe39bc2018-05-01 17:06:20 -04003724In paint: Paint_Style determines if Round_Rect is stroked or filled;
Cary Clark8032b982017-07-28 11:04:54 -04003725if stroked, Paint_Stroke_Width describes the line thickness.
3726If rx or ry are less than zero, they are treated as if they are zero.
3727If rx plus ry exceeds rect width or rect height, radii are scaled down to fit.
Cary Clarkbad5ad72017-08-03 17:14:08 -04003728If rx and ry are zero, Round_Rect is drawn as Rect and if stroked is affected by
3729Paint_Stroke_Join.
Cary Clark8032b982017-07-28 11:04:54 -04003730
Cary Clarkbad5ad72017-08-03 17:14:08 -04003731#Param rect Rect bounds of Round_Rect to draw ##
Cary Clarkce101242017-09-01 15:51:02 -04003732#Param rx axis length in x of oval describing rounded corners ##
3733#Param ry axis length in y of oval describing rounded corners ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003734#Param paint stroke, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003735
3736#Example
3737#Description
3738 Top row has a zero radius a generates a rectangle.
3739 Second row radii sum to less than sides.
3740 Third row radii sum equals sides.
3741 Fourth row radii sum exceeds sides; radii are scaled to fit.
3742##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003743 void draw(SkCanvas* canvas) {
3744 SkVector radii[] = { {0, 20}, {10, 10}, {10, 20}, {10, 40} };
3745 SkPaint paint;
3746 paint.setStrokeWidth(15);
3747 paint.setStrokeJoin(SkPaint::kRound_Join);
3748 paint.setAntiAlias(true);
3749 for (auto style : { SkPaint::kStroke_Style, SkPaint::kFill_Style } ) {
3750 paint.setStyle(style );
3751 for (size_t i = 0; i < SK_ARRAY_COUNT(radii); ++i) {
3752 canvas->drawRoundRect({10, 10, 60, 40}, radii[i].fX, radii[i].fY, paint);
3753 canvas->translate(0, 60);
3754 }
3755 canvas->translate(80, -240);
3756 }
Cary Clark8032b982017-07-28 11:04:54 -04003757 }
3758##
3759
Cary Clark2ade9972017-11-02 17:49:34 -04003760#SeeAlso DrawRRect drawRect drawDRRect drawPath drawCircle drawOval drawPoint
Cary Clark8032b982017-07-28 11:04:54 -04003761
3762##
3763
3764# ------------------------------------------------------------------------------
3765
3766#Method void drawPath(const SkPath& path, const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05003767#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05003768#Line # draws Path using Clip, Matrix, and Paint ##
Cary Clark8032b982017-07-28 11:04:54 -04003769Draw Path path using Clip, Matrix, and Paint paint.
3770Path contains an array of Path_Contour, each of which may be open or closed.
3771
3772In paint: Paint_Style determines if Round_Rect is stroked or filled:
Cary Clarkbad5ad72017-08-03 17:14:08 -04003773if filled, Path_Fill_Type determines whether Path_Contour describes inside or
3774outside of fill; if stroked, Paint_Stroke_Width describes the line thickness,
3775Paint_Stroke_Cap describes line ends, and Paint_Stroke_Join describes how
3776corners are drawn.
Cary Clark8032b982017-07-28 11:04:54 -04003777
Cary Clarkbad5ad72017-08-03 17:14:08 -04003778#Param path Path to draw ##
3779#Param paint stroke, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003780
3781#Example
3782#Description
3783 Top rows draw stroked path with combinations of joins and caps. The open contour
3784 is affected by caps; the closed contour is affected by joins.
Herb Derbyefe39bc2018-05-01 17:06:20 -04003785 Bottom row draws fill the same for open and closed contour.
Cary Clark8032b982017-07-28 11:04:54 -04003786 First bottom column shows winding fills overlap.
3787 Second bottom column shows even odd fills exclude overlap.
3788 Third bottom column shows inverse winding fills area outside both contours.
3789##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003790void draw(SkCanvas* canvas) {
3791 SkPath path;
3792 path.moveTo(20, 20);
3793 path.quadTo(60, 20, 60, 60);
3794 path.close();
3795 path.moveTo(60, 20);
3796 path.quadTo(60, 60, 20, 60);
3797 SkPaint paint;
3798 paint.setStrokeWidth(10);
3799 paint.setAntiAlias(true);
3800 paint.setStyle(SkPaint::kStroke_Style);
3801 for (auto join: { SkPaint::kBevel_Join, SkPaint::kRound_Join, SkPaint::kMiter_Join } ) {
3802 paint.setStrokeJoin(join);
3803 for (auto cap: { SkPaint::kButt_Cap, SkPaint::kSquare_Cap, SkPaint::kRound_Cap } ) {
3804 paint.setStrokeCap(cap);
3805 canvas->drawPath(path, paint);
3806 canvas->translate(80, 0);
3807 }
3808 canvas->translate(-240, 60);
3809 }
3810 paint.setStyle(SkPaint::kFill_Style);
Herb Derbyefe39bc2018-05-01 17:06:20 -04003811 for (auto fill : { SkPath::kWinding_FillType,
3812 SkPath::kEvenOdd_FillType,
Cary Clarkbad5ad72017-08-03 17:14:08 -04003813 SkPath::kInverseWinding_FillType } ) {
3814 path.setFillType(fill);
3815 canvas->save();
3816 canvas->clipRect({0, 10, 80, 70});
3817 canvas->drawPath(path, paint);
3818 canvas->restore();
3819 canvas->translate(80, 0);
3820 }
Cary Clark8032b982017-07-28 11:04:54 -04003821}
3822##
3823
Cary Clark2ade9972017-11-02 17:49:34 -04003824#SeeAlso SkPath drawLine drawArc drawRect drawPoints
Cary Clark8032b982017-07-28 11:04:54 -04003825
3826##
3827
3828# ------------------------------------------------------------------------------
Cary Clark08895c42018-02-01 09:37:32 -05003829#Subtopic Draw_Image
3830#Line # draws Image to Canvas ##
Cary Clark8032b982017-07-28 11:04:54 -04003831
Cary Clarkbad5ad72017-08-03 17:14:08 -04003832drawImage, drawImageRect, and drawImageNine can be called with a bare pointer or
3833a smart pointer as a convenience. The pairs of calls are otherwise identical.
Cary Clark8032b982017-07-28 11:04:54 -04003834
Cary Clark73fa9722017-08-29 17:36:51 -04003835#Method void drawImage(const SkImage* image, SkScalar left, SkScalar top, const SkPaint* paint = nullptr)
Cary Clarkab2621d2018-01-30 10:08:57 -05003836#In Draw_Image
Cary Clark78de7512018-02-07 07:27:09 -05003837#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05003838#Line # draws Image at (x, y) position ##
Cary Clark8032b982017-07-28 11:04:54 -04003839Draw Image image, with its top-left corner at (left, top),
3840using Clip, Matrix, and optional Paint paint.
3841
Cary Clarkbad5ad72017-08-03 17:14:08 -04003842If paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter, Blend_Mode,
3843and Draw_Looper. If image is kAlpha_8_SkColorType, apply Shader.
3844If paint contains Mask_Filter, generate mask from image bounds. If generated
3845mask extends beyond image bounds, replicate image edge colors, just as Shader
3846made from SkImage::makeShader with SkShader::kClamp_TileMode set replicates the
Herb Derbyefe39bc2018-05-01 17:06:20 -04003847image edge color when it samples outside of its bounds.
Cary Clark8032b982017-07-28 11:04:54 -04003848
Cary Clarkbad5ad72017-08-03 17:14:08 -04003849#Param image uncompressed rectangular map of pixels ##
3850#Param left left side of image ##
3851#Param top top side of image ##
3852#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
3853 and so on; or nullptr
3854##
Cary Clark8032b982017-07-28 11:04:54 -04003855
3856#Example
3857#Height 64
3858#Image 4
Cary Clarkbad5ad72017-08-03 17:14:08 -04003859void draw(SkCanvas* canvas) {
3860 // sk_sp<SkImage> image;
3861 SkImage* imagePtr = image.get();
3862 canvas->drawImage(imagePtr, 0, 0);
3863 SkPaint paint;
3864 canvas->drawImage(imagePtr, 80, 0, &paint);
3865 paint.setAlpha(0x80);
3866 canvas->drawImage(imagePtr, 160, 0, &paint);
Cary Clark8032b982017-07-28 11:04:54 -04003867}
3868##
3869
Cary Clark2ade9972017-11-02 17:49:34 -04003870#SeeAlso drawBitmap drawImageLattice drawImageNine drawImageRect SkPaint::setImageFilter
Cary Clark8032b982017-07-28 11:04:54 -04003871
3872##
3873
3874# ------------------------------------------------------------------------------
3875
3876#Method void drawImage(const sk_sp<SkImage>& image, SkScalar left, SkScalar top,
Herb Derbyefe39bc2018-05-01 17:06:20 -04003877 const SkPaint* paint = nullptr)
Cary Clark8032b982017-07-28 11:04:54 -04003878
3879Draw Image image, with its top-left corner at (left, top),
3880using Clip, Matrix, and optional Paint paint.
3881
Cary Clarkbad5ad72017-08-03 17:14:08 -04003882If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
3883Blend_Mode, and Draw_Looper. If image is kAlpha_8_SkColorType, apply Shader.
3884If paint contains Mask_Filter, generate mask from image bounds. If generated
3885mask extends beyond image bounds, replicate image edge colors, just as Shader
3886made from SkImage::makeShader with SkShader::kClamp_TileMode set replicates the
Herb Derbyefe39bc2018-05-01 17:06:20 -04003887image edge color when it samples outside of its bounds.
Cary Clark8032b982017-07-28 11:04:54 -04003888
Cary Clarkbad5ad72017-08-03 17:14:08 -04003889#Param image uncompressed rectangular map of pixels ##
3890#Param left left side of image ##
3891#Param top pop side of image ##
3892#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
3893 and so on; or nullptr
3894##
Cary Clark8032b982017-07-28 11:04:54 -04003895
3896#Example
3897#Height 64
3898#Image 4
Cary Clarkbad5ad72017-08-03 17:14:08 -04003899void draw(SkCanvas* canvas) {
3900 // sk_sp<SkImage> image;
3901 canvas->drawImage(image, 0, 0);
3902 SkPaint paint;
3903 canvas->drawImage(image, 80, 0, &paint);
3904 paint.setAlpha(0x80);
3905 canvas->drawImage(image, 160, 0, &paint);
Cary Clark8032b982017-07-28 11:04:54 -04003906}
3907##
3908
Cary Clark2ade9972017-11-02 17:49:34 -04003909#SeeAlso drawBitmap drawImageLattice drawImageNine drawImageRect SkPaint::setImageFilter
Cary Clark8032b982017-07-28 11:04:54 -04003910
3911##
3912
3913# ------------------------------------------------------------------------------
3914
3915#Enum SrcRectConstraint
Cary Clark08895c42018-02-01 09:37:32 -05003916#Line # sets drawImageRect options ##
Cary Clark8032b982017-07-28 11:04:54 -04003917
3918#Code
3919 enum SrcRectConstraint {
Herb Derbyefe39bc2018-05-01 17:06:20 -04003920 kStrict_SrcRectConstraint,
3921 kFast_SrcRectConstraint,
Cary Clark8032b982017-07-28 11:04:54 -04003922 };
3923##
3924
Cary Clarkce101242017-09-01 15:51:02 -04003925SrcRectConstraint controls the behavior at the edge of source Rect,
3926provided to drawImageRect, trading off speed for precision.
Cary Clark8032b982017-07-28 11:04:54 -04003927
Cary Clarkce101242017-09-01 15:51:02 -04003928Image_Filter in Paint may sample multiple pixels in the image. Source Rect
Cary Clarkbad5ad72017-08-03 17:14:08 -04003929restricts the bounds of pixels that may be read. Image_Filter may slow down if
Herb Derbyefe39bc2018-05-01 17:06:20 -04003930it cannot read outside the bounds, when sampling near the edge of source Rect.
Cary Clark8032b982017-07-28 11:04:54 -04003931SrcRectConstraint specifies whether an Image_Filter is allowed to read pixels
Cary Clarkce101242017-09-01 15:51:02 -04003932outside source Rect.
Cary Clark8032b982017-07-28 11:04:54 -04003933
3934#Const kStrict_SrcRectConstraint
Cary Clarkce101242017-09-01 15:51:02 -04003935 Requires Image_Filter to respect source Rect,
Cary Clark8032b982017-07-28 11:04:54 -04003936 sampling only inside of its bounds, possibly with a performance penalty.
3937##
3938
3939#Const kFast_SrcRectConstraint
Cary Clarkce101242017-09-01 15:51:02 -04003940 Permits Image_Filter to sample outside of source Rect
Cary Clark8032b982017-07-28 11:04:54 -04003941 by half the width of Image_Filter, permitting it to run faster but with
3942 error at the image edges.
3943##
3944
3945#Example
3946#Height 64
3947#Description
3948 redBorder contains a black and white checkerboard bordered by red.
3949 redBorder is drawn scaled by 16 on the left.
Cary Clarkce101242017-09-01 15:51:02 -04003950 The middle and right bitmaps are filtered checkerboards.
Cary Clark8032b982017-07-28 11:04:54 -04003951 Drawing the checkerboard with kStrict_SrcRectConstraint shows only a blur of black and white.
3952 Drawing the checkerboard with kFast_SrcRectConstraint allows red to bleed in the corners.
3953##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003954void draw(SkCanvas* canvas) {
3955 SkBitmap redBorder;
3956 redBorder.allocPixels(SkImageInfo::MakeN32Premul(4, 4));
3957 SkCanvas checkRed(redBorder);
3958 checkRed.clear(SK_ColorRED);
3959 uint32_t checkers[][2] = { { SK_ColorBLACK, SK_ColorWHITE },
3960 { SK_ColorWHITE, SK_ColorBLACK } };
3961 checkRed.writePixels(
3962 SkImageInfo::MakeN32Premul(2, 2), (void*) checkers, sizeof(checkers[0]), 1, 1);
3963 canvas->scale(16, 16);
3964 canvas->drawBitmap(redBorder, 0, 0, nullptr);
3965 canvas->resetMatrix();
3966 sk_sp<SkImage> image = SkImage::MakeFromBitmap(redBorder);
3967 SkPaint lowPaint;
3968 lowPaint.setFilterQuality(kLow_SkFilterQuality);
3969 for (auto constraint : { SkCanvas::kStrict_SrcRectConstraint,
3970 SkCanvas::kFast_SrcRectConstraint } ) {
3971 canvas->translate(80, 0);
3972 canvas->drawImageRect(image.get(), SkRect::MakeLTRB(1, 1, 3, 3),
3973 SkRect::MakeLTRB(16, 16, 48, 48), &lowPaint, constraint);
3974 }
Cary Clark8032b982017-07-28 11:04:54 -04003975}
3976##
3977
Cary Clark2ade9972017-11-02 17:49:34 -04003978#SeeAlso drawImageRect drawImage SkPaint::setImageFilter
Cary Clark8032b982017-07-28 11:04:54 -04003979
3980##
3981
3982# ------------------------------------------------------------------------------
3983
3984#Method void drawImageRect(const SkImage* image, const SkRect& src, const SkRect& dst,
3985 const SkPaint* paint,
3986 SrcRectConstraint constraint = kStrict_SrcRectConstraint)
Cary Clarkab2621d2018-01-30 10:08:57 -05003987#In Draw_Image
Cary Clark78de7512018-02-07 07:27:09 -05003988#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05003989#Line # draws Image, source Rect to destination Rect ##
Cary Clark8032b982017-07-28 11:04:54 -04003990
3991Draw Rect src of Image image, scaled and translated to fill Rect dst.
3992Additionally transform draw using Clip, Matrix, and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04003993
Cary Clarkbad5ad72017-08-03 17:14:08 -04003994If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
3995Blend_Mode, and Draw_Looper. If image is kAlpha_8_SkColorType, apply Shader.
3996If paint contains Mask_Filter, generate mask from image bounds.
3997
3998If generated mask extends beyond image bounds, replicate image edge colors, just
3999as Shader made from SkImage::makeShader with SkShader::kClamp_TileMode set
Cary Clarkbc5697d2017-10-04 14:31:33 -04004000replicates the image edge color when it samples outside of its bounds.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004001
4002constraint set to kStrict_SrcRectConstraint limits Paint Filter_Quality to
4003sample within src; set to kFast_SrcRectConstraint allows sampling outside to
4004improve performance.
4005
4006#Param image Image containing pixels, dimensions, and format ##
4007#Param src source Rect of image to draw from ##
4008#Param dst destination Rect of image to draw to ##
4009#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4010 and so on; or nullptr
4011##
4012#Param constraint filter strictly within src or draw faster ##
Cary Clark8032b982017-07-28 11:04:54 -04004013
4014#Example
4015#Height 64
4016#Description
4017 The left bitmap draws with Paint default kNone_SkFilterQuality, and stays within
Cary Clarkbc5697d2017-10-04 14:31:33 -04004018 its bounds; there is no bleeding with kFast_SrcRectConstraint.
Cary Clark8032b982017-07-28 11:04:54 -04004019 the middle and right bitmaps draw with kLow_SkFilterQuality; with
4020 kStrict_SrcRectConstraint, the filter remains within the checkerboard, and
4021 with kFast_SrcRectConstraint red bleeds on the edges.
4022##
Cary Clarkbad5ad72017-08-03 17:14:08 -04004023void draw(SkCanvas* canvas) {
Herb Derbyefe39bc2018-05-01 17:06:20 -04004024 uint32_t pixels[][4] = {
Cary Clarkbad5ad72017-08-03 17:14:08 -04004025 { 0xFFFF0000, 0xFFFF0000, 0xFFFF0000, 0xFFFF0000 },
4026 { 0xFFFF0000, 0xFF000000, 0xFFFFFFFF, 0xFFFF0000 },
4027 { 0xFFFF0000, 0xFFFFFFFF, 0xFF000000, 0xFFFF0000 },
4028 { 0xFFFF0000, 0xFFFF0000, 0xFFFF0000, 0xFFFF0000 } };
4029 SkBitmap redBorder;
Herb Derbyefe39bc2018-05-01 17:06:20 -04004030 redBorder.installPixels(SkImageInfo::MakeN32Premul(4, 4),
Cary Clarkbad5ad72017-08-03 17:14:08 -04004031 (void*) pixels, sizeof(pixels[0]));
4032 sk_sp<SkImage> image = SkImage::MakeFromBitmap(redBorder);
4033 SkPaint lowPaint;
4034 for (auto constraint : {
4035 SkCanvas::kFast_SrcRectConstraint,
4036 SkCanvas::kStrict_SrcRectConstraint,
4037 SkCanvas::kFast_SrcRectConstraint } ) {
4038 canvas->drawImageRect(image.get(), SkRect::MakeLTRB(1, 1, 3, 3),
4039 SkRect::MakeLTRB(16, 16, 48, 48), &lowPaint, constraint);
4040 lowPaint.setFilterQuality(kLow_SkFilterQuality);
4041 canvas->translate(80, 0);
4042 }
4043}
Cary Clark8032b982017-07-28 11:04:54 -04004044##
4045
Cary Clark2ade9972017-11-02 17:49:34 -04004046#SeeAlso SrcRectConstraint drawImage drawImageLattice drawImageNine
Cary Clark8032b982017-07-28 11:04:54 -04004047
4048##
4049
4050# ------------------------------------------------------------------------------
4051
4052#Method void drawImageRect(const SkImage* image, const SkIRect& isrc, const SkRect& dst,
4053 const SkPaint* paint, SrcRectConstraint constraint = kStrict_SrcRectConstraint)
Cary Clarkab2621d2018-01-30 10:08:57 -05004054#In Draw_Image
Cary Clark78de7512018-02-07 07:27:09 -05004055#In Draw
Cary Clark8032b982017-07-28 11:04:54 -04004056
4057Draw IRect isrc of Image image, scaled and translated to fill Rect dst.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004058Note that isrc is on integer pixel boundaries; dst may include fractional
4059boundaries. Additionally transform draw using Clip, Matrix, and optional Paint
Herb Derbyefe39bc2018-05-01 17:06:20 -04004060paint.
Cary Clark8032b982017-07-28 11:04:54 -04004061
Cary Clarkbad5ad72017-08-03 17:14:08 -04004062If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4063Blend_Mode, and Draw_Looper. If image is kAlpha_8_SkColorType, apply Shader.
4064If paint contains Mask_Filter, generate mask from image bounds.
4065
4066If generated mask extends beyond image bounds, replicate image edge colors, just
4067as Shader made from SkImage::makeShader with SkShader::kClamp_TileMode set
Cary Clarkbc5697d2017-10-04 14:31:33 -04004068replicates the image edge color when it samples outside of its bounds.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004069
4070constraint set to kStrict_SrcRectConstraint limits Paint Filter_Quality to
Cary Clarkce101242017-09-01 15:51:02 -04004071sample within isrc; set to kFast_SrcRectConstraint allows sampling outside to
Cary Clarkbad5ad72017-08-03 17:14:08 -04004072improve performance.
4073
4074#Param image Image containing pixels, dimensions, and format ##
4075#Param isrc source IRect of image to draw from ##
4076#Param dst destination Rect of image to draw to ##
4077#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4078 and so on; or nullptr
4079##
Cary Clarkce101242017-09-01 15:51:02 -04004080#Param constraint filter strictly within isrc or draw faster ##
Cary Clark8032b982017-07-28 11:04:54 -04004081
4082#Example
4083#Image 4
Cary Clarkbad5ad72017-08-03 17:14:08 -04004084void draw(SkCanvas* canvas) {
4085 // sk_sp<SkImage> image;
4086 for (auto i : { 1, 2, 4, 8 } ) {
Herb Derbyefe39bc2018-05-01 17:06:20 -04004087 canvas->drawImageRect(image.get(), SkIRect::MakeLTRB(0, 0, 100, 100),
Cary Clarkbad5ad72017-08-03 17:14:08 -04004088 SkRect::MakeXYWH(i * 20, i * 20, i * 20, i * 20), nullptr);
4089 }
Cary Clark8032b982017-07-28 11:04:54 -04004090}
4091##
4092
Cary Clark2ade9972017-11-02 17:49:34 -04004093#SeeAlso SrcRectConstraint drawImage drawImageLattice drawImageNine
Cary Clark8032b982017-07-28 11:04:54 -04004094
4095##
4096
4097# ------------------------------------------------------------------------------
4098
4099#Method void drawImageRect(const SkImage* image, const SkRect& dst, const SkPaint* paint,
4100 SrcRectConstraint constraint = kStrict_SrcRectConstraint)
Cary Clarkab2621d2018-01-30 10:08:57 -05004101#In Draw_Image
Cary Clark78de7512018-02-07 07:27:09 -05004102#In Draw
Cary Clark8032b982017-07-28 11:04:54 -04004103
Cary Clarkbad5ad72017-08-03 17:14:08 -04004104Draw Image image, scaled and translated to fill Rect dst, using Clip, Matrix,
4105and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004106
Cary Clarkbad5ad72017-08-03 17:14:08 -04004107If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4108Blend_Mode, and Draw_Looper. If image is kAlpha_8_SkColorType, apply Shader.
4109If paint contains Mask_Filter, generate mask from image bounds.
4110
4111If generated mask extends beyond image bounds, replicate image edge colors, just
4112as Shader made from SkImage::makeShader with SkShader::kClamp_TileMode set
Cary Clarkbc5697d2017-10-04 14:31:33 -04004113replicates the image edge color when it samples outside of its bounds.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004114
4115constraint set to kStrict_SrcRectConstraint limits Paint Filter_Quality to
Cary Clarkce101242017-09-01 15:51:02 -04004116sample within image; set to kFast_SrcRectConstraint allows sampling outside to
Cary Clarkbad5ad72017-08-03 17:14:08 -04004117improve performance.
4118
4119#Param image Image containing pixels, dimensions, and format ##
4120#Param dst destination Rect of image to draw to ##
4121#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4122 and so on; or nullptr
4123##
Cary Clarkce101242017-09-01 15:51:02 -04004124#Param constraint filter strictly within image or draw faster ##
Cary Clark8032b982017-07-28 11:04:54 -04004125
4126#Example
4127#Image 4
Cary Clarkbad5ad72017-08-03 17:14:08 -04004128void draw(SkCanvas* canvas) {
4129 // sk_sp<SkImage> image;
4130 for (auto i : { 20, 40, 80, 160 } ) {
4131 canvas->drawImageRect(image.get(), SkRect::MakeXYWH(i, i, i, i), nullptr);
4132 }
Cary Clark8032b982017-07-28 11:04:54 -04004133}
4134##
4135
Cary Clark2ade9972017-11-02 17:49:34 -04004136#SeeAlso SrcRectConstraint drawImage drawImageLattice drawImageNine
Cary Clark8032b982017-07-28 11:04:54 -04004137
4138##
4139
4140# ------------------------------------------------------------------------------
4141
4142#Method void drawImageRect(const sk_sp<SkImage>& image, const SkRect& src, const SkRect& dst,
4143 const SkPaint* paint,
Herb Derbyefe39bc2018-05-01 17:06:20 -04004144 SrcRectConstraint constraint = kStrict_SrcRectConstraint)
Cary Clarkab2621d2018-01-30 10:08:57 -05004145#In Draw_Image
Cary Clark78de7512018-02-07 07:27:09 -05004146#In Draw
Cary Clark8032b982017-07-28 11:04:54 -04004147Draw Rect src of Image image, scaled and translated to fill Rect dst.
4148Additionally transform draw using Clip, Matrix, and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004149
Cary Clarkbad5ad72017-08-03 17:14:08 -04004150If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4151Blend_Mode, and Draw_Looper. If image is kAlpha_8_SkColorType, apply Shader.
4152If paint contains Mask_Filter, generate mask from image bounds.
4153
4154If generated mask extends beyond image bounds, replicate image edge colors, just
4155as Shader made from SkImage::makeShader with SkShader::kClamp_TileMode set
Cary Clarkbc5697d2017-10-04 14:31:33 -04004156replicates the image edge color when it samples outside of its bounds.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004157
4158constraint set to kStrict_SrcRectConstraint limits Paint Filter_Quality to
4159sample within src; set to kFast_SrcRectConstraint allows sampling outside to
4160improve performance.
4161
4162#Param image Image containing pixels, dimensions, and format ##
4163#Param src source Rect of image to draw from ##
4164#Param dst destination Rect of image to draw to ##
4165#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4166 and so on; or nullptr
4167##
4168#Param constraint filter strictly within src or draw faster ##
Cary Clark8032b982017-07-28 11:04:54 -04004169
4170#Example
4171#Height 64
4172#Description
4173 Canvas scales and translates; transformation from src to dst also scales.
4174 The two matrices are concatenated to create the final transformation.
4175##
Cary Clarkbad5ad72017-08-03 17:14:08 -04004176void draw(SkCanvas* canvas) {
4177 uint32_t pixels[][2] = { { SK_ColorBLACK, SK_ColorWHITE },
4178 { SK_ColorWHITE, SK_ColorBLACK } };
4179 SkBitmap bitmap;
Herb Derbyefe39bc2018-05-01 17:06:20 -04004180 bitmap.installPixels(SkImageInfo::MakeN32Premul(2, 2),
Cary Clarkbad5ad72017-08-03 17:14:08 -04004181 (void*) pixels, sizeof(pixels[0]));
4182 sk_sp<SkImage> image = SkImage::MakeFromBitmap(bitmap);
4183 SkPaint paint;
4184 canvas->scale(4, 4);
4185 for (auto alpha : { 50, 100, 150, 255 } ) {
4186 paint.setAlpha(alpha);
4187 canvas->drawImageRect(image, SkRect::MakeWH(2, 2), SkRect::MakeWH(8, 8), &paint);
4188 canvas->translate(8, 0);
4189 }
4190}
Cary Clark8032b982017-07-28 11:04:54 -04004191##
4192
Cary Clark2ade9972017-11-02 17:49:34 -04004193#SeeAlso SrcRectConstraint drawImage drawImageLattice drawImageNine
Cary Clark8032b982017-07-28 11:04:54 -04004194
4195##
4196
4197# ------------------------------------------------------------------------------
4198
4199#Method void drawImageRect(const sk_sp<SkImage>& image, const SkIRect& isrc, const SkRect& dst,
Herb Derbyefe39bc2018-05-01 17:06:20 -04004200 const SkPaint* paint, SrcRectConstraint constraint = kStrict_SrcRectConstraint)
Cary Clarkab2621d2018-01-30 10:08:57 -05004201#In Draw_Image
Cary Clark78de7512018-02-07 07:27:09 -05004202#In Draw
Cary Clark8032b982017-07-28 11:04:54 -04004203Draw IRect isrc of Image image, scaled and translated to fill Rect dst.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004204isrc is on integer pixel boundaries; dst may include fractional boundaries.
Cary Clark8032b982017-07-28 11:04:54 -04004205Additionally transform draw using Clip, Matrix, and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004206
Cary Clarkbad5ad72017-08-03 17:14:08 -04004207If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4208Blend_Mode, and Draw_Looper. If image is kAlpha_8_SkColorType, apply Shader.
4209If paint contains Mask_Filter, generate mask from image bounds.
4210
4211If generated mask extends beyond image bounds, replicate image edge colors, just
4212as Shader made from SkImage::makeShader with SkShader::kClamp_TileMode set
Cary Clarkbc5697d2017-10-04 14:31:33 -04004213replicates the image edge color when it samples outside of its bounds.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004214
4215constraint set to kStrict_SrcRectConstraint limits Paint Filter_Quality to
Cary Clarkce101242017-09-01 15:51:02 -04004216sample within image; set to kFast_SrcRectConstraint allows sampling outside to
Cary Clarkbad5ad72017-08-03 17:14:08 -04004217improve performance.
4218
4219#Param image Image containing pixels, dimensions, and format ##
4220#Param isrc source IRect of image to draw from ##
4221#Param dst destination Rect of image to draw to ##
4222#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4223 and so on; or nullptr
4224##
Cary Clarkce101242017-09-01 15:51:02 -04004225#Param constraint filter strictly within image or draw faster ##
Cary Clark8032b982017-07-28 11:04:54 -04004226
4227#Example
4228#Height 64
Cary Clarkbad5ad72017-08-03 17:14:08 -04004229void draw(SkCanvas* canvas) {
4230 uint32_t pixels[][2] = { { 0x00000000, 0x55555555},
4231 { 0xAAAAAAAA, 0xFFFFFFFF} };
4232 SkBitmap bitmap;
Herb Derbyefe39bc2018-05-01 17:06:20 -04004233 bitmap.installPixels(SkImageInfo::MakeN32Premul(2, 2),
Cary Clarkbad5ad72017-08-03 17:14:08 -04004234 (void*) pixels, sizeof(pixels[0]));
4235 sk_sp<SkImage> image = SkImage::MakeFromBitmap(bitmap);
4236 SkPaint paint;
4237 canvas->scale(4, 4);
4238 for (auto color : { SK_ColorRED, SK_ColorBLUE, SK_ColorGREEN } ) {
4239 paint.setColorFilter(SkColorFilter::MakeModeFilter(color, SkBlendMode::kPlus));
4240 canvas->drawImageRect(image, SkIRect::MakeWH(2, 2), SkRect::MakeWH(8, 8), &paint);
4241 canvas->translate(8, 0);
4242 }
Cary Clark8032b982017-07-28 11:04:54 -04004243}
4244##
4245
Cary Clark2ade9972017-11-02 17:49:34 -04004246#SeeAlso SrcRectConstraint drawImage drawImageLattice drawImageNine
4247
Cary Clark8032b982017-07-28 11:04:54 -04004248##
4249
4250# ------------------------------------------------------------------------------
4251
4252#Method void drawImageRect(const sk_sp<SkImage>& image, const SkRect& dst, const SkPaint* paint,
Herb Derbyefe39bc2018-05-01 17:06:20 -04004253 SrcRectConstraint constraint = kStrict_SrcRectConstraint)
Cary Clarkab2621d2018-01-30 10:08:57 -05004254#In Draw_Image
Cary Clark78de7512018-02-07 07:27:09 -05004255#In Draw
Cary Clark8032b982017-07-28 11:04:54 -04004256Draw Image image, scaled and translated to fill Rect dst,
4257using Clip, Matrix, and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004258
Cary Clarkbad5ad72017-08-03 17:14:08 -04004259If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4260Blend_Mode, and Draw_Looper. If image is kAlpha_8_SkColorType, apply Shader.
4261If paint contains Mask_Filter, generate mask from image bounds.
4262
4263If generated mask extends beyond image bounds, replicate image edge colors, just
4264as Shader made from SkImage::makeShader with SkShader::kClamp_TileMode set
Cary Clarkbc5697d2017-10-04 14:31:33 -04004265replicates the image edge color when it samples outside of its bounds.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004266
4267constraint set to kStrict_SrcRectConstraint limits Paint Filter_Quality to
Cary Clarkce101242017-09-01 15:51:02 -04004268sample within image; set to kFast_SrcRectConstraint allows sampling outside to
Cary Clarkbad5ad72017-08-03 17:14:08 -04004269improve performance.
4270
4271#Param image Image containing pixels, dimensions, and format ##
4272#Param dst destination Rect of image to draw to ##
4273#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4274 and so on; or nullptr
4275##
Cary Clarkce101242017-09-01 15:51:02 -04004276#Param constraint filter strictly within image or draw faster ##
Cary Clark8032b982017-07-28 11:04:54 -04004277
4278#Example
4279#Height 64
Cary Clarkbad5ad72017-08-03 17:14:08 -04004280void draw(SkCanvas* canvas) {
4281 uint32_t pixels[][2] = { { 0x00000000, 0x55550000},
4282 { 0xAAAA0000, 0xFFFF0000} };
4283 SkBitmap bitmap;
Herb Derbyefe39bc2018-05-01 17:06:20 -04004284 bitmap.installPixels(SkImageInfo::MakeN32Premul(2, 2),
Cary Clarkbad5ad72017-08-03 17:14:08 -04004285 (void*) pixels, sizeof(pixels[0]));
4286 sk_sp<SkImage> image = SkImage::MakeFromBitmap(bitmap);
4287 SkPaint paint;
4288 canvas->scale(4, 4);
4289 for (auto color : { SK_ColorRED, SK_ColorBLUE, SK_ColorGREEN } ) {
4290 paint.setColorFilter(SkColorFilter::MakeModeFilter(color, SkBlendMode::kPlus));
4291 canvas->drawImageRect(image, SkRect::MakeWH(8, 8), &paint);
4292 canvas->translate(8, 0);
4293 }
Cary Clark8032b982017-07-28 11:04:54 -04004294}
4295##
4296
Cary Clark2ade9972017-11-02 17:49:34 -04004297#SeeAlso SrcRectConstraint drawImage drawImageLattice drawImageNine
Cary Clark8032b982017-07-28 11:04:54 -04004298
4299##
4300
4301# ------------------------------------------------------------------------------
4302
4303#Method void drawImageNine(const SkImage* image, const SkIRect& center, const SkRect& dst,
4304 const SkPaint* paint = nullptr)
Cary Clarkab2621d2018-01-30 10:08:57 -05004305#In Draw_Image
Cary Clark78de7512018-02-07 07:27:09 -05004306#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05004307#Line # draws Nine_Patch Image ##
Cary Clark8032b982017-07-28 11:04:54 -04004308
Cary Clarkd0530ba2017-09-14 11:25:39 -04004309Draw Image image stretched proportionally to fit into Rect dst.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004310IRect center divides the image into nine sections: four sides, four corners, and
Cary Clarkce101242017-09-01 15:51:02 -04004311the center. Corners are unmodified or scaled down proportionately if their sides
Cary Clarkbad5ad72017-08-03 17:14:08 -04004312are larger than dst; center and four sides are scaled to fit remaining space, if any.
Cary Clark8032b982017-07-28 11:04:54 -04004313
Cary Clarkbad5ad72017-08-03 17:14:08 -04004314Additionally transform draw using Clip, Matrix, and optional Paint paint.
4315
4316If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4317Blend_Mode, and Draw_Looper. If image is kAlpha_8_SkColorType, apply Shader.
4318If paint contains Mask_Filter, generate mask from image bounds.
4319
4320If generated mask extends beyond image bounds, replicate image edge colors, just
4321as Shader made from SkImage::makeShader with SkShader::kClamp_TileMode set
Cary Clarkbc5697d2017-10-04 14:31:33 -04004322replicates the image edge color when it samples outside of its bounds.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004323
4324#Param image Image containing pixels, dimensions, and format ##
4325#Param center IRect edge of image corners and sides ##
4326#Param dst destination Rect of image to draw to ##
4327#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4328 and so on; or nullptr
4329##
Cary Clark8032b982017-07-28 11:04:54 -04004330
4331#Example
4332#Height 128
4333#Description
4334 The leftmost image is smaller than center; only corners are drawn, all scaled to fit.
Cary Clarkce101242017-09-01 15:51:02 -04004335 The second image equals the size of center; only corners are drawn without scaling.
4336 The remaining images are larger than center. All corners draw without scaling.
4337 The sides and center are scaled if needed to take up the remaining space.
Cary Clark8032b982017-07-28 11:04:54 -04004338##
Cary Clarkbad5ad72017-08-03 17:14:08 -04004339void draw(SkCanvas* canvas) {
4340 SkIRect center = { 20, 10, 50, 40 };
4341 SkBitmap bitmap;
4342 bitmap.allocPixels(SkImageInfo::MakeN32Premul(60, 60));
4343 SkCanvas bitCanvas(bitmap);
4344 SkPaint paint;
4345 SkColor gray = 0xFF000000;
4346 int left = 0;
4347 for (auto right: { center.fLeft, center.fRight, bitmap.width() } ) {
4348 int top = 0;
4349 for (auto bottom: { center.fTop, center.fBottom, bitmap.height() } ) {
4350 paint.setColor(gray);
4351 bitCanvas.drawIRect(SkIRect::MakeLTRB(left, top, right, bottom), paint);
4352 gray += 0x001f1f1f;
4353 top = bottom;
4354 }
Herb Derbyefe39bc2018-05-01 17:06:20 -04004355 left = right;
Cary Clarkbad5ad72017-08-03 17:14:08 -04004356 }
4357 sk_sp<SkImage> image = SkImage::MakeFromBitmap(bitmap);
4358 SkImage* imagePtr = image.get();
4359 for (auto dest: { 20, 30, 40, 60, 90 } ) {
4360 canvas->drawImageNine(imagePtr, center, SkRect::MakeWH(dest, dest), nullptr);
4361 canvas->translate(dest + 4, 0);
4362 }
Cary Clark8032b982017-07-28 11:04:54 -04004363}
4364##
4365
Cary Clark2ade9972017-11-02 17:49:34 -04004366#SeeAlso drawImage drawBitmapNine drawImageLattice drawImageRect
Cary Clark8032b982017-07-28 11:04:54 -04004367
4368##
4369
4370# ------------------------------------------------------------------------------
4371
4372#Method void drawImageNine(const sk_sp<SkImage>& image, const SkIRect& center, const SkRect& dst,
Herb Derbyefe39bc2018-05-01 17:06:20 -04004373 const SkPaint* paint = nullptr)
Cary Clarkab2621d2018-01-30 10:08:57 -05004374#In Draw_Image
Cary Clark78de7512018-02-07 07:27:09 -05004375#In Draw
Cary Clarkd0530ba2017-09-14 11:25:39 -04004376Draw Image image stretched proportionally to fit into Rect dst.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004377IRect center divides the image into nine sections: four sides, four corners, and
Cary Clarkce101242017-09-01 15:51:02 -04004378the center. Corners are not scaled, or scaled down proportionately if their sides
Cary Clarkbad5ad72017-08-03 17:14:08 -04004379are larger than dst; center and four sides are scaled to fit remaining space, if any.
Cary Clark8032b982017-07-28 11:04:54 -04004380
Cary Clarkbad5ad72017-08-03 17:14:08 -04004381Additionally transform draw using Clip, Matrix, and optional Paint paint.
4382
4383If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4384Blend_Mode, and Draw_Looper. If image is kAlpha_8_SkColorType, apply Shader.
4385If paint contains Mask_Filter, generate mask from image bounds.
4386
4387If generated mask extends beyond image bounds, replicate image edge colors, just
4388as Shader made from SkImage::makeShader with SkShader::kClamp_TileMode set
Cary Clarkbc5697d2017-10-04 14:31:33 -04004389replicates the image edge color when it samples outside of its bounds.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004390
4391#Param image Image containing pixels, dimensions, and format ##
4392#Param center IRect edge of image corners and sides ##
4393#Param dst destination Rect of image to draw to ##
4394#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4395 and so on; or nullptr
4396##
Cary Clark8032b982017-07-28 11:04:54 -04004397
4398#Example
4399#Height 128
4400#Description
4401 The two leftmost images has four corners and sides to the left and right of center.
4402 The leftmost image scales the width of corners proportionately to fit.
Herb Derbyefe39bc2018-05-01 17:06:20 -04004403 The third and fourth image corners are not scaled; the sides and center are scaled to
Cary Clark8032b982017-07-28 11:04:54 -04004404 fill the remaining space.
4405 The rightmost image has four corners scaled vertically to fit, and uses sides above
4406 and below center to fill the remaining space.
4407##
Cary Clarkbad5ad72017-08-03 17:14:08 -04004408void draw(SkCanvas* canvas) {
4409 SkIRect center = { 20, 10, 50, 40 };
4410 SkBitmap bitmap;
4411 bitmap.allocPixels(SkImageInfo::MakeN32Premul(60, 60));
4412 SkCanvas bitCanvas(bitmap);
4413 SkPaint paint;
4414 SkColor gray = 0xFF000000;
4415 int left = 0;
4416 for (auto right: { center.fLeft, center.fRight, bitmap.width() } ) {
4417 int top = 0;
4418 for (auto bottom: { center.fTop, center.fBottom, bitmap.height() } ) {
4419 paint.setColor(gray);
4420 bitCanvas.drawIRect(SkIRect::MakeLTRB(left, top, right, bottom), paint);
4421 gray += 0x001f1f1f;
4422 top = bottom;
4423 }
Herb Derbyefe39bc2018-05-01 17:06:20 -04004424 left = right;
Cary Clarkbad5ad72017-08-03 17:14:08 -04004425 }
4426 sk_sp<SkImage> image = SkImage::MakeFromBitmap(bitmap);
4427 for (auto dest: { 20, 30, 40, 60, 90 } ) {
4428 canvas->drawImageNine(image, center, SkRect::MakeWH(dest, 110 - dest), nullptr);
4429 canvas->translate(dest + 4, 0);
4430 }
Cary Clark8032b982017-07-28 11:04:54 -04004431}
4432##
4433
Cary Clark2ade9972017-11-02 17:49:34 -04004434#SeeAlso drawImage drawBitmapNine drawImageLattice drawImageRect
Cary Clark8032b982017-07-28 11:04:54 -04004435
4436##
4437
4438# ------------------------------------------------------------------------------
4439
4440#Method void drawBitmap(const SkBitmap& bitmap, SkScalar left, SkScalar top,
Cary Clark73fa9722017-08-29 17:36:51 -04004441 const SkPaint* paint = nullptr)
Cary Clarkab2621d2018-01-30 10:08:57 -05004442#In Draw_Image
Cary Clark78de7512018-02-07 07:27:09 -05004443#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05004444#Line # draws Bitmap at (x, y) position ##
Cary Clark8032b982017-07-28 11:04:54 -04004445
4446Draw Bitmap bitmap, with its top-left corner at (left, top),
4447using Clip, Matrix, and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004448
Cary Clarka560c472017-11-27 10:44:06 -05004449If Paint paint is not nullptr, apply Color_Filter, Color_Alpha, Image_Filter,
Cary Clarkbad5ad72017-08-03 17:14:08 -04004450Blend_Mode, and Draw_Looper. If bitmap is kAlpha_8_SkColorType, apply Shader.
4451If paint contains Mask_Filter, generate mask from bitmap bounds.
4452
4453If generated mask extends beyond bitmap bounds, replicate bitmap edge colors,
4454just as Shader made from SkShader::MakeBitmapShader with
Cary Clarkbc5697d2017-10-04 14:31:33 -04004455SkShader::kClamp_TileMode set replicates the bitmap edge color when it samples
Herb Derbyefe39bc2018-05-01 17:06:20 -04004456outside of its bounds.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004457
4458#Param bitmap Bitmap containing pixels, dimensions, and format ##
4459#Param left left side of bitmap ##
4460#Param top top side of bitmap ##
4461#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4462 and so on; or nullptr
4463##
Cary Clark8032b982017-07-28 11:04:54 -04004464
4465#Example
4466#Height 64
Cary Clarkbad5ad72017-08-03 17:14:08 -04004467void draw(SkCanvas* canvas) {
4468 uint8_t pixels[][8] = { { 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00},
4469 { 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00},
4470 { 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00},
4471 { 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF},
4472 { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
4473 { 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00},
4474 { 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0x00},
4475 { 0xFF, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0xFF} };
4476 SkBitmap bitmap;
Herb Derbyefe39bc2018-05-01 17:06:20 -04004477 bitmap.installPixels(SkImageInfo::MakeA8(8, 8),
Cary Clarkbad5ad72017-08-03 17:14:08 -04004478 (void*) pixels, sizeof(pixels[0]));
4479 SkPaint paint;
4480 canvas->scale(4, 4);
4481 for (auto color : { SK_ColorRED, SK_ColorBLUE, 0xFF007F00} ) {
4482 paint.setColor(color);
4483 canvas->drawBitmap(bitmap, 0, 0, &paint);
4484 canvas->translate(12, 0);
4485 }
Cary Clark8032b982017-07-28 11:04:54 -04004486}
4487##
4488
Cary Clark2ade9972017-11-02 17:49:34 -04004489#SeeAlso drawImage drawBitmapLattice drawBitmapNine drawBitmapRect SkBitmap::readPixels SkBitmap::writePixels
Cary Clark8032b982017-07-28 11:04:54 -04004490
4491##
4492
4493# ------------------------------------------------------------------------------
4494
4495#Method void drawBitmapRect(const SkBitmap& bitmap, const SkRect& src, const SkRect& dst,
4496 const SkPaint* paint, SrcRectConstraint constraint = kStrict_SrcRectConstraint)
Cary Clarkab2621d2018-01-30 10:08:57 -05004497#In Draw_Image
Cary Clark78de7512018-02-07 07:27:09 -05004498#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05004499#Line # draws Bitmap, source Rect to destination Rect ##
Cary Clark8032b982017-07-28 11:04:54 -04004500
4501Draw Rect src of Bitmap bitmap, scaled and translated to fill Rect dst.
4502Additionally transform draw using Clip, Matrix, and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004503
Cary Clarkbad5ad72017-08-03 17:14:08 -04004504If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4505Blend_Mode, and Draw_Looper. If bitmap is kAlpha_8_SkColorType, apply Shader.
4506If paint contains Mask_Filter, generate mask from bitmap bounds.
4507
4508If generated mask extends beyond bitmap bounds, replicate bitmap edge colors,
4509just as Shader made from SkShader::MakeBitmapShader with
Cary Clarkbc5697d2017-10-04 14:31:33 -04004510SkShader::kClamp_TileMode set replicates the bitmap edge color when it samples
Cary Clarkbad5ad72017-08-03 17:14:08 -04004511outside of its bounds.
4512
4513constraint set to kStrict_SrcRectConstraint limits Paint Filter_Quality to
4514sample within src; set to kFast_SrcRectConstraint allows sampling outside to
4515improve performance.
4516
4517#Param bitmap Bitmap containing pixels, dimensions, and format ##
4518#Param src source Rect of image to draw from ##
4519#Param dst destination Rect of image to draw to ##
4520#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4521 and so on; or nullptr
4522##
4523#Param constraint filter strictly within src or draw faster ##
Cary Clark8032b982017-07-28 11:04:54 -04004524
4525#Example
4526#Height 64
Cary Clarkbad5ad72017-08-03 17:14:08 -04004527void draw(SkCanvas* canvas) {
4528 uint8_t pixels[][8] = { { 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00},
4529 { 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00},
4530 { 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00},
4531 { 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF},
4532 { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
4533 { 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00},
4534 { 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00},
4535 { 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00} };
4536 SkBitmap bitmap;
Herb Derbyefe39bc2018-05-01 17:06:20 -04004537 bitmap.installPixels(SkImageInfo::MakeA8(8, 8),
Cary Clarkbad5ad72017-08-03 17:14:08 -04004538 (void*) pixels, sizeof(pixels[0]));
4539 SkPaint paint;
Cary Clark681287e2018-03-16 11:34:15 -04004540 paint.setMaskFilter(SkMaskFilter::MakeBlur(kSolid_SkBlurStyle, 6));
Cary Clarkbad5ad72017-08-03 17:14:08 -04004541 for (auto color : { SK_ColorRED, SK_ColorBLUE, 0xFF007F00} ) {
4542 paint.setColor(color);
4543 canvas->drawBitmapRect(bitmap, SkRect::MakeWH(8, 8), SkRect::MakeWH(32, 32), &paint);
4544 canvas->translate(48, 0);
4545 }
Cary Clark8032b982017-07-28 11:04:54 -04004546}
4547##
4548
Cary Clark2ade9972017-11-02 17:49:34 -04004549#SeeAlso drawImageRect drawBitmap drawBitmapLattice drawBitmapNine
Cary Clark8032b982017-07-28 11:04:54 -04004550
4551##
4552
4553# ------------------------------------------------------------------------------
4554
4555#Method void drawBitmapRect(const SkBitmap& bitmap, const SkIRect& isrc, const SkRect& dst,
4556 const SkPaint* paint, SrcRectConstraint constraint = kStrict_SrcRectConstraint)
Cary Clarkab2621d2018-01-30 10:08:57 -05004557#In Draw_Image
Cary Clark78de7512018-02-07 07:27:09 -05004558#In Draw
Cary Clark8032b982017-07-28 11:04:54 -04004559Draw IRect isrc of Bitmap bitmap, scaled and translated to fill Rect dst.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004560isrc is on integer pixel boundaries; dst may include fractional boundaries.
Cary Clark8032b982017-07-28 11:04:54 -04004561Additionally transform draw using Clip, Matrix, and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004562
Cary Clarkbad5ad72017-08-03 17:14:08 -04004563If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4564Blend_Mode, and Draw_Looper. If bitmap is kAlpha_8_SkColorType, apply Shader.
4565If paint contains Mask_Filter, generate mask from bitmap bounds.
4566
4567If generated mask extends beyond bitmap bounds, replicate bitmap edge colors,
4568just as Shader made from SkShader::MakeBitmapShader with
Cary Clarkbc5697d2017-10-04 14:31:33 -04004569SkShader::kClamp_TileMode set replicates the bitmap edge color when it samples
Cary Clarkbad5ad72017-08-03 17:14:08 -04004570outside of its bounds.
4571
4572constraint set to kStrict_SrcRectConstraint limits Paint Filter_Quality to
Cary Clarkce101242017-09-01 15:51:02 -04004573sample within isrc; set to kFast_SrcRectConstraint allows sampling outside to
Cary Clarkbad5ad72017-08-03 17:14:08 -04004574improve performance.
4575
4576#Param bitmap Bitmap containing pixels, dimensions, and format ##
4577#Param isrc source IRect of image to draw from ##
4578#Param dst destination Rect of image to draw to ##
4579#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4580 and so on; or nullptr
4581##
Cary Clarkce101242017-09-01 15:51:02 -04004582#Param constraint sample strictly within isrc, or draw faster ##
Cary Clark8032b982017-07-28 11:04:54 -04004583
4584#Example
4585#Height 64
Cary Clarkbad5ad72017-08-03 17:14:08 -04004586void draw(SkCanvas* canvas) {
4587 uint8_t pixels[][8] = { { 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00},
4588 { 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00},
4589 { 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0xFF},
4590 { 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0xFF},
4591 { 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF},
4592 { 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF},
4593 { 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00},
4594 { 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00} };
4595 SkBitmap bitmap;
Herb Derbyefe39bc2018-05-01 17:06:20 -04004596 bitmap.installPixels(SkImageInfo::MakeA8(8, 8),
Cary Clarkbad5ad72017-08-03 17:14:08 -04004597 (void*) pixels, sizeof(pixels[0]));
4598 SkPaint paint;
4599 paint.setFilterQuality(kHigh_SkFilterQuality);
4600 for (auto color : { SK_ColorRED, SK_ColorBLUE, 0xFF007F00, 0xFF7f007f} ) {
4601 paint.setColor(color);
4602 canvas->drawBitmapRect(bitmap, SkIRect::MakeWH(8, 8), SkRect::MakeWH(32, 32), &paint);
4603 canvas->translate(48.25f, 0);
4604 }
Cary Clark8032b982017-07-28 11:04:54 -04004605}
4606##
4607
Cary Clark2ade9972017-11-02 17:49:34 -04004608#SeeAlso drawImageRect drawBitmap drawBitmapLattice drawBitmapNine
Cary Clark8032b982017-07-28 11:04:54 -04004609
4610##
4611
4612# ------------------------------------------------------------------------------
4613
4614#Method void drawBitmapRect(const SkBitmap& bitmap, const SkRect& dst, const SkPaint* paint,
4615 SrcRectConstraint constraint = kStrict_SrcRectConstraint)
Cary Clarkab2621d2018-01-30 10:08:57 -05004616#In Draw_Image
Cary Clark78de7512018-02-07 07:27:09 -05004617#In Draw
Cary Clark8032b982017-07-28 11:04:54 -04004618Draw Bitmap bitmap, scaled and translated to fill Rect dst.
Cary Clarkce101242017-09-01 15:51:02 -04004619bitmap bounds is on integer pixel boundaries; dst may include fractional boundaries.
Cary Clark8032b982017-07-28 11:04:54 -04004620Additionally transform draw using Clip, Matrix, and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004621
Cary Clarkbad5ad72017-08-03 17:14:08 -04004622If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4623Blend_Mode, and Draw_Looper. If bitmap is kAlpha_8_SkColorType, apply Shader.
4624If paint contains Mask_Filter, generate mask from bitmap bounds.
4625
4626If generated mask extends beyond bitmap bounds, replicate bitmap edge colors,
4627just as Shader made from SkShader::MakeBitmapShader with
Cary Clarkbc5697d2017-10-04 14:31:33 -04004628SkShader::kClamp_TileMode set replicates the bitmap edge color when it samples
Cary Clarkbad5ad72017-08-03 17:14:08 -04004629outside of its bounds.
4630
4631constraint set to kStrict_SrcRectConstraint limits Paint Filter_Quality to
Cary Clarkce101242017-09-01 15:51:02 -04004632sample within bitmap; set to kFast_SrcRectConstraint allows sampling outside to
Cary Clarkbad5ad72017-08-03 17:14:08 -04004633improve performance.
4634
4635#Param bitmap Bitmap containing pixels, dimensions, and format ##
4636#Param dst destination Rect of image to draw to ##
4637#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4638 and so on; or nullptr
4639##
Cary Clarkce101242017-09-01 15:51:02 -04004640#Param constraint filter strictly within bitmap or draw faster ##
Cary Clark8032b982017-07-28 11:04:54 -04004641
4642#Example
4643#Height 64
Cary Clarkbad5ad72017-08-03 17:14:08 -04004644void draw(SkCanvas* canvas) {
4645 uint32_t pixels[][2] = { { 0x00000000, 0x55550000},
4646 { 0xAAAA0000, 0xFFFF0000} };
4647 SkBitmap bitmap;
Herb Derbyefe39bc2018-05-01 17:06:20 -04004648 bitmap.installPixels(SkImageInfo::MakeN32Premul(2, 2),
Cary Clarkbad5ad72017-08-03 17:14:08 -04004649 (void*) pixels, sizeof(pixels[0]));
4650 SkPaint paint;
4651 canvas->scale(4, 4);
4652 for (auto color : { SK_ColorRED, SK_ColorBLUE, SK_ColorGREEN } ) {
4653 paint.setColorFilter(SkColorFilter::MakeModeFilter(color, SkBlendMode::kPlus));
4654 canvas->drawBitmapRect(bitmap, SkRect::MakeWH(8, 8), &paint);
4655 canvas->translate(8, 0);
4656 }
Cary Clark8032b982017-07-28 11:04:54 -04004657}
4658##
4659
Cary Clark2ade9972017-11-02 17:49:34 -04004660#SeeAlso drawImageRect drawBitmap drawBitmapLattice drawBitmapNine
Cary Clark8032b982017-07-28 11:04:54 -04004661
4662##
4663
4664# ------------------------------------------------------------------------------
4665
4666#Method void drawBitmapNine(const SkBitmap& bitmap, const SkIRect& center, const SkRect& dst,
Cary Clark73fa9722017-08-29 17:36:51 -04004667 const SkPaint* paint = nullptr)
Cary Clarkab2621d2018-01-30 10:08:57 -05004668#In Draw_Image
Cary Clark78de7512018-02-07 07:27:09 -05004669#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05004670#Line # draws Nine_Patch Bitmap ##
Cary Clark8032b982017-07-28 11:04:54 -04004671
Cary Clarkd0530ba2017-09-14 11:25:39 -04004672Draw Bitmap bitmap stretched proportionally to fit into Rect dst.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004673IRect center divides the bitmap into nine sections: four sides, four corners,
Cary Clarkce101242017-09-01 15:51:02 -04004674and the center. Corners are not scaled, or scaled down proportionately if their
Cary Clarkbad5ad72017-08-03 17:14:08 -04004675sides are larger than dst; center and four sides are scaled to fit remaining
4676space, if any.
Cary Clark8032b982017-07-28 11:04:54 -04004677
Cary Clarkbad5ad72017-08-03 17:14:08 -04004678Additionally transform draw using Clip, Matrix, and optional Paint paint.
4679
4680If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4681Blend_Mode, and Draw_Looper. If bitmap is kAlpha_8_SkColorType, apply Shader.
4682If paint contains Mask_Filter, generate mask from bitmap bounds.
4683
4684If generated mask extends beyond bitmap bounds, replicate bitmap edge colors,
4685just as Shader made from SkShader::MakeBitmapShader with
Cary Clarkbc5697d2017-10-04 14:31:33 -04004686SkShader::kClamp_TileMode set replicates the bitmap edge color when it samples
Cary Clarkbad5ad72017-08-03 17:14:08 -04004687outside of its bounds.
4688
4689#Param bitmap Bitmap containing pixels, dimensions, and format ##
4690#Param center IRect edge of image corners and sides ##
4691#Param dst destination Rect of image to draw to ##
4692#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4693 and so on; or nullptr
4694##
Cary Clark8032b982017-07-28 11:04:54 -04004695
4696#Example
4697#Height 128
4698#Description
4699 The two leftmost bitmap draws has four corners and sides to the left and right of center.
4700 The leftmost bitmap draw scales the width of corners proportionately to fit.
Herb Derbyefe39bc2018-05-01 17:06:20 -04004701 The third and fourth draw corners are not scaled; the sides and center are scaled to
Cary Clark8032b982017-07-28 11:04:54 -04004702 fill the remaining space.
4703 The rightmost bitmap draw has four corners scaled vertically to fit, and uses sides above
4704 and below center to fill the remaining space.
4705##
Cary Clarkbad5ad72017-08-03 17:14:08 -04004706void draw(SkCanvas* canvas) {
4707 SkIRect center = { 20, 10, 50, 40 };
4708 SkBitmap bitmap;
4709 bitmap.allocPixels(SkImageInfo::MakeN32Premul(60, 60));
4710 SkCanvas bitCanvas(bitmap);
4711 SkPaint paint;
4712 SkColor gray = 0xFF000000;
4713 int left = 0;
4714 for (auto right: { center.fLeft, center.fRight, bitmap.width() } ) {
4715 int top = 0;
4716 for (auto bottom: { center.fTop, center.fBottom, bitmap.height() } ) {
4717 paint.setColor(gray);
4718 bitCanvas.drawIRect(SkIRect::MakeLTRB(left, top, right, bottom), paint);
4719 gray += 0x001f1f1f;
4720 top = bottom;
4721 }
Herb Derbyefe39bc2018-05-01 17:06:20 -04004722 left = right;
Cary Clarkbad5ad72017-08-03 17:14:08 -04004723 }
4724 for (auto dest: { 20, 30, 40, 60, 90 } ) {
4725 canvas->drawBitmapNine(bitmap, center, SkRect::MakeWH(dest, 110 - dest), nullptr);
4726 canvas->translate(dest + 4, 0);
4727 }
Cary Clark8032b982017-07-28 11:04:54 -04004728}
4729##
4730
Cary Clark2ade9972017-11-02 17:49:34 -04004731#SeeAlso drawImageNine drawBitmap drawBitmapLattice drawBitmapRect
Cary Clark8032b982017-07-28 11:04:54 -04004732
4733##
4734
4735# ------------------------------------------------------------------------------
4736#Struct Lattice
Cary Clark08895c42018-02-01 09:37:32 -05004737#Line # divides Bitmap or Image into a rectangular grid ##
Cary Clark8032b982017-07-28 11:04:54 -04004738#Code
4739 struct Lattice {
Cary Clark2f466242017-12-11 16:03:17 -05004740 enum RectType ...
Cary Clark8032b982017-07-28 11:04:54 -04004741
Cary Clark2f466242017-12-11 16:03:17 -05004742 const int* fXDivs;
4743 const int* fYDivs;
4744 const RectType* fRectTypes;
4745 int fXCount;
4746 int fYCount;
4747 const SkIRect* fBounds;
4748 const SkColor* fColors;
Cary Clark8032b982017-07-28 11:04:54 -04004749 };
4750##
4751
Cary Clark154beea2017-10-26 07:58:48 -04004752 Lattice divides Bitmap or Image into a rectangular grid.
4753 Grid entries on even columns and even rows are fixed; these entries are
4754 always drawn at their original size if the destination is large enough.
4755 If the destination side is too small to hold the fixed entries, all fixed
4756 entries are proportionately scaled down to fit.
4757 The grid entries not on even columns and rows are scaled to fit the
4758 remaining space, if any.
4759
Cary Clark2f466242017-12-11 16:03:17 -05004760 #Enum RectType
Cary Clark8032b982017-07-28 11:04:54 -04004761 #Code
Cary Clark2f466242017-12-11 16:03:17 -05004762 enum RectType : uint8_t {
4763 kDefault = 0,
4764 kTransparent,
4765 kFixedColor,
Cary Clark8032b982017-07-28 11:04:54 -04004766 };
4767 ##
4768
Cary Clark2f466242017-12-11 16:03:17 -05004769 Optional setting per rectangular grid entry to make it transparent,
4770 or to fill the grid entry with a color.
Cary Clark8032b982017-07-28 11:04:54 -04004771
Cary Clark2f466242017-12-11 16:03:17 -05004772 #Const kDefault 0
4773 Draws Bitmap into lattice rectangle.
4774 ##
4775
4776 #Const kTransparent 1
4777 Skips lattice rectangle by making it transparent.
4778 ##
4779
4780 #Const kFixedColor 2
4781 Draws one of fColors into lattice rectangle.
Cary Clark8032b982017-07-28 11:04:54 -04004782 ##
4783 ##
4784
4785 #Member const int* fXDivs
4786 Array of x-coordinates that divide the bitmap vertically.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004787 Array entries must be unique, increasing, greater than or equal to
4788 fBounds left edge, and less than fBounds right edge.
4789 Set the first element to fBounds left to collapse the left column of
4790 fixed grid entries.
Cary Clark8032b982017-07-28 11:04:54 -04004791 ##
4792
4793 #Member const int* fYDivs
4794 Array of y-coordinates that divide the bitmap horizontally.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004795 Array entries must be unique, increasing, greater than or equal to
4796 fBounds top edge, and less than fBounds bottom edge.
4797 Set the first element to fBounds top to collapse the top row of fixed
4798 grid entries.
Cary Clark8032b982017-07-28 11:04:54 -04004799 ##
4800
Cary Clark2f466242017-12-11 16:03:17 -05004801 #Member const RectType* fRectTypes
4802 Optional array of fill types, one per rectangular grid entry:
Cary Clarkbad5ad72017-08-03 17:14:08 -04004803 array length must be
4804 #Formula
4805 (fXCount + 1) * (fYCount + 1)
4806 ##
4807 .
Cary Clark6fc50412017-09-21 12:31:06 -04004808
Cary Clark2f466242017-12-11 16:03:17 -05004809 Each RectType is one of: kDefault, kTransparent, kFixedColor.
4810
Cary Clark8032b982017-07-28 11:04:54 -04004811 Array entries correspond to the rectangular grid entries, ascending
4812 left to right and then top to bottom.
4813 ##
4814
4815 #Member int fXCount
Cary Clarkbad5ad72017-08-03 17:14:08 -04004816 Number of entries in fXDivs array; one less than the number of
4817 horizontal divisions.
Cary Clark8032b982017-07-28 11:04:54 -04004818 ##
4819
4820 #Member int fYCount
Cary Clarkbad5ad72017-08-03 17:14:08 -04004821 Number of entries in fYDivs array; one less than the number of vertical
4822 divisions.
Cary Clark8032b982017-07-28 11:04:54 -04004823 ##
4824
4825 #Member const SkIRect* fBounds
4826 Optional subset IRect source to draw from.
4827 If nullptr, source bounds is dimensions of Bitmap or Image.
4828 ##
4829
Cary Clark2f466242017-12-11 16:03:17 -05004830 #Member const SkColor* fColors
4831 Optional array of colors, one per rectangular grid entry.
4832 Array length must be
4833 #Formula
4834 (fXCount + 1) * (fYCount + 1)
4835 ##
4836 .
4837
4838 Array entries correspond to the rectangular grid entries, ascending
4839 left to right, then top to bottom.
4840 ##
4841
Cary Clark8032b982017-07-28 11:04:54 -04004842#Struct Lattice ##
4843
4844#Method void drawBitmapLattice(const SkBitmap& bitmap, const Lattice& lattice, const SkRect& dst,
4845 const SkPaint* paint = nullptr)
Cary Clarkab2621d2018-01-30 10:08:57 -05004846#In Draw_Image
Cary Clark78de7512018-02-07 07:27:09 -05004847#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05004848#Line # draws proportionally stretched Bitmap ##
Cary Clark8032b982017-07-28 11:04:54 -04004849
Cary Clarkd0530ba2017-09-14 11:25:39 -04004850Draw Bitmap bitmap stretched proportionally to fit into Rect dst.
Cary Clark8032b982017-07-28 11:04:54 -04004851
4852Lattice lattice divides bitmap into a rectangular grid.
4853Each intersection of an even-numbered row and column is fixed; like the corners
Cary Clarkbad5ad72017-08-03 17:14:08 -04004854of drawBitmapNine, fixed lattice elements never scale larger than their initial
Cary Clarkbc5697d2017-10-04 14:31:33 -04004855size and shrink proportionately when all fixed elements exceed the bitmap
Cary Clarkbad5ad72017-08-03 17:14:08 -04004856dimension. All other grid elements scale to fill the available space, if any.
Cary Clark8032b982017-07-28 11:04:54 -04004857
4858Additionally transform draw using Clip, Matrix, and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004859
Cary Clarkbad5ad72017-08-03 17:14:08 -04004860If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4861Blend_Mode, and Draw_Looper. If bitmap is kAlpha_8_SkColorType, apply Shader.
4862If paint contains Mask_Filter, generate mask from bitmap bounds.
4863
4864If generated mask extends beyond bitmap bounds, replicate bitmap edge colors,
4865just as Shader made from SkShader::MakeBitmapShader with
Cary Clarkbc5697d2017-10-04 14:31:33 -04004866SkShader::kClamp_TileMode set replicates the bitmap edge color when it samples
Cary Clarkbad5ad72017-08-03 17:14:08 -04004867outside of its bounds.
4868
4869#Param bitmap Bitmap containing pixels, dimensions, and format ##
4870#Param lattice division of bitmap into fixed and variable rectangles ##
4871#Param dst destination Rect of image to draw to ##
4872#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4873 and so on; or nullptr
4874##
Cary Clark8032b982017-07-28 11:04:54 -04004875
4876#Example
4877#Height 128
4878#Description
4879 The two leftmost bitmap draws has four corners and sides to the left and right of center.
4880 The leftmost bitmap draw scales the width of corners proportionately to fit.
Herb Derbyefe39bc2018-05-01 17:06:20 -04004881 The third and fourth draw corners are not scaled; the sides are scaled to
Cary Clark8032b982017-07-28 11:04:54 -04004882 fill the remaining space; the center is transparent.
4883 The rightmost bitmap draw has four corners scaled vertically to fit, and uses sides above
4884 and below center to fill the remaining space.
4885##
Cary Clarkbad5ad72017-08-03 17:14:08 -04004886void draw(SkCanvas* canvas) {
4887 SkIRect center = { 20, 10, 50, 40 };
4888 SkBitmap bitmap;
4889 bitmap.allocPixels(SkImageInfo::MakeN32Premul(60, 60));
4890 SkCanvas bitCanvas(bitmap);
4891 SkPaint paint;
4892 SkColor gray = 0xFF000000;
4893 int left = 0;
4894 for (auto right: { center.fLeft, center.fRight, bitmap.width() } ) {
4895 int top = 0;
4896 for (auto bottom: { center.fTop, center.fBottom, bitmap.height() } ) {
4897 paint.setColor(gray);
4898 bitCanvas.drawIRect(SkIRect::MakeLTRB(left, top, right, bottom), paint);
4899 gray += 0x001f1f1f;
4900 top = bottom;
4901 }
Herb Derbyefe39bc2018-05-01 17:06:20 -04004902 left = right;
Cary Clarkbad5ad72017-08-03 17:14:08 -04004903 }
4904 const int xDivs[] = { center.fLeft, center.fRight };
4905 const int yDivs[] = { center.fTop, center.fBottom };
Cary Clarkca3ebcd2017-12-12 11:22:38 -05004906 SkCanvas::Lattice::RectType fillTypes[3][3];
4907 memset(fillTypes, 0, sizeof(fillTypes));
4908 fillTypes[1][1] = SkCanvas::Lattice::kTransparent;
4909 SkColor dummy[9]; // temporary pending bug fix
4910 SkCanvas::Lattice lattice = { xDivs, yDivs, fillTypes[0], SK_ARRAY_COUNT(xDivs),
4911 SK_ARRAY_COUNT(yDivs), nullptr, dummy };
Cary Clarkbad5ad72017-08-03 17:14:08 -04004912 for (auto dest: { 20, 30, 40, 60, 90 } ) {
Cary Clarkca3ebcd2017-12-12 11:22:38 -05004913 canvas->drawBitmapLattice(bitmap, lattice, SkRect::MakeWH(dest, 110 - dest), nullptr);
Cary Clarkbad5ad72017-08-03 17:14:08 -04004914 canvas->translate(dest + 4, 0);
4915 }
Cary Clark8032b982017-07-28 11:04:54 -04004916}
4917##
4918
Cary Clark2ade9972017-11-02 17:49:34 -04004919#SeeAlso drawImageLattice drawBitmap drawBitmapNine Lattice
Cary Clark8032b982017-07-28 11:04:54 -04004920
4921##
4922
4923# ------------------------------------------------------------------------------
4924
4925#Method void drawImageLattice(const SkImage* image, const Lattice& lattice, const SkRect& dst,
4926 const SkPaint* paint = nullptr)
Cary Clarkab2621d2018-01-30 10:08:57 -05004927#In Draw_Image
Cary Clark78de7512018-02-07 07:27:09 -05004928#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05004929#Line # draws proportionally stretched Image ##
Cary Clark8032b982017-07-28 11:04:54 -04004930
Cary Clarkd0530ba2017-09-14 11:25:39 -04004931Draw Image image stretched proportionally to fit into Rect dst.
Cary Clark8032b982017-07-28 11:04:54 -04004932
4933Lattice lattice divides image into a rectangular grid.
4934Each intersection of an even-numbered row and column is fixed; like the corners
Cary Clarkbad5ad72017-08-03 17:14:08 -04004935of drawBitmapNine, fixed lattice elements never scale larger than their initial
Cary Clarkbc5697d2017-10-04 14:31:33 -04004936size and shrink proportionately when all fixed elements exceed the bitmap
Cary Clarkbad5ad72017-08-03 17:14:08 -04004937dimension. All other grid elements scale to fill the available space, if any.
Cary Clark8032b982017-07-28 11:04:54 -04004938
4939Additionally transform draw using Clip, Matrix, and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004940
Cary Clarkbad5ad72017-08-03 17:14:08 -04004941If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4942Blend_Mode, and Draw_Looper. If bitmap is kAlpha_8_SkColorType, apply Shader.
4943If paint contains Mask_Filter, generate mask from bitmap bounds.
4944
4945If generated mask extends beyond bitmap bounds, replicate bitmap edge colors,
4946just as Shader made from SkShader::MakeBitmapShader with
Cary Clarkbc5697d2017-10-04 14:31:33 -04004947SkShader::kClamp_TileMode set replicates the bitmap edge color when it samples
Cary Clarkbad5ad72017-08-03 17:14:08 -04004948outside of its bounds.
4949
4950#Param image Image containing pixels, dimensions, and format ##
4951#Param lattice division of bitmap into fixed and variable rectangles ##
4952#Param dst destination Rect of image to draw to ##
4953#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4954 and so on; or nullptr
4955##
Cary Clark8032b982017-07-28 11:04:54 -04004956
4957#Example
4958#Height 128
4959#Description
4960 The leftmost image is smaller than center; only corners are drawn, all scaled to fit.
Cary Clarkce101242017-09-01 15:51:02 -04004961 The second image equals the size of center; only corners are drawn without scaling.
4962 The remaining images are larger than center. All corners draw without scaling. The sides
Cary Clark8032b982017-07-28 11:04:54 -04004963 are scaled if needed to take up the remaining space; the center is transparent.
4964##
Cary Clarkbad5ad72017-08-03 17:14:08 -04004965void draw(SkCanvas* canvas) {
4966 SkIRect center = { 20, 10, 50, 40 };
4967 SkBitmap bitmap;
4968 bitmap.allocPixels(SkImageInfo::MakeN32Premul(60, 60));
4969 SkCanvas bitCanvas(bitmap);
4970 SkPaint paint;
4971 SkColor gray = 0xFF000000;
4972 int left = 0;
4973 for (auto right: { center.fLeft, center.fRight, bitmap.width() } ) {
4974 int top = 0;
4975 for (auto bottom: { center.fTop, center.fBottom, bitmap.height() } ) {
4976 paint.setColor(gray);
4977 bitCanvas.drawIRect(SkIRect::MakeLTRB(left, top, right, bottom), paint);
4978 gray += 0x001f1f1f;
4979 top = bottom;
4980 }
Herb Derbyefe39bc2018-05-01 17:06:20 -04004981 left = right;
Cary Clarkbad5ad72017-08-03 17:14:08 -04004982 }
Cary Clarkbad5ad72017-08-03 17:14:08 -04004983 sk_sp<SkImage> image = SkImage::MakeFromBitmap(bitmap);
4984 SkImage* imagePtr = image.get();
4985 for (auto dest: { 20, 30, 40, 60, 90 } ) {
4986 canvas->drawImageNine(imagePtr, center, SkRect::MakeWH(dest, dest), nullptr);
4987 canvas->translate(dest + 4, 0);
4988 }
Cary Clark8032b982017-07-28 11:04:54 -04004989}
4990##
4991
Cary Clark2ade9972017-11-02 17:49:34 -04004992#SeeAlso drawBitmapLattice drawImage drawImageNine Lattice
Cary Clark8032b982017-07-28 11:04:54 -04004993
4994##
4995
Cary Clark08895c42018-02-01 09:37:32 -05004996#Subtopic Draw_Image ##
Cary Clark8032b982017-07-28 11:04:54 -04004997
4998# ------------------------------------------------------------------------------
Cary Clark78de7512018-02-07 07:27:09 -05004999#Subtopic Draw_Text
5000#Populate
5001#Line # draws text into Canvas ##
5002##
Cary Clark8032b982017-07-28 11:04:54 -04005003
5004#Method void drawText(const void* text, size_t byteLength, SkScalar x, SkScalar y,
5005 const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05005006#In Draw_Text
5007#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05005008#Line # draws text at (x, y), using font advance ##
Cary Clark8032b982017-07-28 11:04:54 -04005009
5010Draw text, with origin at (x, y), using Clip, Matrix, and Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04005011
Cary Clarkbc5697d2017-10-04 14:31:33 -04005012text meaning depends on Paint_Text_Encoding; by default, text is encoded as
Cary Clarkbad5ad72017-08-03 17:14:08 -04005013UTF-8.
Cary Clark8032b982017-07-28 11:04:54 -04005014
Cary Clarkbad5ad72017-08-03 17:14:08 -04005015x and y meaning depends on Paint_Text_Align and Paint_Vertical_Text; by default
Cary Clarkbc5697d2017-10-04 14:31:33 -04005016text draws left to right, positioning the first glyph left side bearing at x
Herb Derbyefe39bc2018-05-01 17:06:20 -04005017and its baseline at y. Text size is affected by Matrix and Paint_Text_Size.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005018
Mike Reed8ad91a92018-01-19 19:09:32 -05005019All elements of paint: Path_Effect, Mask_Filter, Shader,
Cary Clarkbad5ad72017-08-03 17:14:08 -04005020Color_Filter, Image_Filter, and Draw_Looper; apply to text. By default, draws
Cary Clarkce101242017-09-01 15:51:02 -04005021filled 12 point black Glyphs.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005022
Cary Clarkce101242017-09-01 15:51:02 -04005023#Param text character code points or Glyphs drawn ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005024#Param byteLength byte length of text array ##
5025#Param x start of text on x-axis ##
5026#Param y start of text on y-axis ##
5027#Param paint text size, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005028
5029#Example
5030#Height 200
5031#Description
5032 The same text is drawn varying Paint_Text_Size and varying
Herb Derbyefe39bc2018-05-01 17:06:20 -04005033 Matrix.
Cary Clark8032b982017-07-28 11:04:54 -04005034##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005035void draw(SkCanvas* canvas) {
5036 SkPaint paint;
5037 paint.setAntiAlias(true);
5038 float textSizes[] = { 12, 18, 24, 36 };
5039 for (auto size: textSizes ) {
5040 paint.setTextSize(size);
5041 canvas->drawText("Aa", 2, 10, 20, paint);
5042 canvas->translate(0, size * 2);
5043 }
5044 paint.reset();
5045 paint.setAntiAlias(true);
5046 float yPos = 20;
5047 for (auto size: textSizes ) {
5048 float scale = size / 12.f;
5049 canvas->resetMatrix();
5050 canvas->translate(100, 0);
5051 canvas->scale(scale, scale);
5052 canvas->drawText("Aa", 2, 10 / scale, yPos / scale, paint);
Herb Derbyefe39bc2018-05-01 17:06:20 -04005053 yPos += size * 2;
Cary Clarkbad5ad72017-08-03 17:14:08 -04005054 }
5055}
Cary Clark8032b982017-07-28 11:04:54 -04005056##
5057
Cary Clark2ade9972017-11-02 17:49:34 -04005058#SeeAlso drawString drawPosText drawPosTextH drawTextBlob drawTextOnPath drawTextRSXform
Cary Clark8032b982017-07-28 11:04:54 -04005059
5060##
5061
5062#Method void drawString(const char* string, SkScalar x, SkScalar y, const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05005063#In Draw_Text
5064#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05005065#Line # draws null terminated string at (x, y) using font advance ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005066Draw null terminated string, with origin at (x, y), using Clip, Matrix, and
Mike Reed9c2916e2018-03-15 13:37:08 -04005067Paint paint. Note that this per-glyph xform does not affect the shader (if present)
5068on the paint, just the glyph's geometry.
Cary Clark8032b982017-07-28 11:04:54 -04005069
Cary Clarkbc5697d2017-10-04 14:31:33 -04005070string meaning depends on Paint_Text_Encoding; by default, strings are encoded
5071as UTF-8. Other values of Paint_Text_Encoding are unlikely to produce the desired
Cary Clarkbad5ad72017-08-03 17:14:08 -04005072results, since zero bytes may be embedded in the string.
Cary Clark8032b982017-07-28 11:04:54 -04005073
Cary Clarkbad5ad72017-08-03 17:14:08 -04005074x and y meaning depends on Paint_Text_Align and Paint_Vertical_Text; by default
Cary Clarkbc5697d2017-10-04 14:31:33 -04005075string draws left to right, positioning the first glyph left side bearing at x
Herb Derbyefe39bc2018-05-01 17:06:20 -04005076and its baseline at y. Text size is affected by Matrix and Paint_Text_Size.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005077
Mike Reed8ad91a92018-01-19 19:09:32 -05005078All elements of paint: Path_Effect, Mask_Filter, Shader,
Cary Clarkbad5ad72017-08-03 17:14:08 -04005079Color_Filter, Image_Filter, and Draw_Looper; apply to text. By default, draws
Cary Clarkce101242017-09-01 15:51:02 -04005080filled 12 point black Glyphs.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005081
Cary Clarkce101242017-09-01 15:51:02 -04005082#Param string character code points or Glyphs drawn,
Cary Clarkbad5ad72017-08-03 17:14:08 -04005083 ending with a char value of zero
5084##
5085#Param x start of string on x-axis ##
5086#Param y start of string on y-axis ##
5087#Param paint text size, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005088
5089#Example
5090 SkPaint paint;
5091 canvas->drawString("a small hello", 20, 20, paint);
5092##
5093
Cary Clark2ade9972017-11-02 17:49:34 -04005094#SeeAlso drawText drawPosText drawPosTextH drawTextBlob drawTextOnPath drawTextRSXform
Cary Clark8032b982017-07-28 11:04:54 -04005095
5096##
5097
5098#Method void drawString(const SkString& string, SkScalar x, SkScalar y, const SkPaint& paint)
5099
Cary Clarkbad5ad72017-08-03 17:14:08 -04005100Draw null terminated string, with origin at (x, y), using Clip, Matrix, and
5101Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04005102
Cary Clarkbc5697d2017-10-04 14:31:33 -04005103string meaning depends on Paint_Text_Encoding; by default, strings are encoded
5104as UTF-8. Other values of Paint_Text_Encoding are unlikely to produce the desired
Cary Clarkbad5ad72017-08-03 17:14:08 -04005105results, since zero bytes may be embedded in the string.
Cary Clark8032b982017-07-28 11:04:54 -04005106
Cary Clarkbad5ad72017-08-03 17:14:08 -04005107x and y meaning depends on Paint_Text_Align and Paint_Vertical_Text; by default
Cary Clarkbc5697d2017-10-04 14:31:33 -04005108string draws left to right, positioning the first glyph left side bearing at x
Herb Derbyefe39bc2018-05-01 17:06:20 -04005109and its baseline at y. Text size is affected by Matrix and Paint_Text_Size.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005110
Mike Reed8ad91a92018-01-19 19:09:32 -05005111All elements of paint: Path_Effect, Mask_Filter, Shader,
Cary Clarkbad5ad72017-08-03 17:14:08 -04005112Color_Filter, Image_Filter, and Draw_Looper; apply to text. By default, draws
Cary Clarkce101242017-09-01 15:51:02 -04005113filled 12 point black Glyphs.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005114
Cary Clarkce101242017-09-01 15:51:02 -04005115#Param string character code points or Glyphs drawn,
Cary Clarkbad5ad72017-08-03 17:14:08 -04005116 ending with a char value of zero
5117##
5118#Param x start of string on x-axis ##
5119#Param y start of string on y-axis ##
5120#Param paint text size, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005121
5122#Example
5123 SkPaint paint;
5124 SkString string("a small hello");
5125 canvas->drawString(string, 20, 20, paint);
5126##
5127
Cary Clark2ade9972017-11-02 17:49:34 -04005128#SeeAlso drawText drawPosText drawPosTextH drawTextBlob drawTextOnPath drawTextRSXform
Cary Clark8032b982017-07-28 11:04:54 -04005129
5130##
5131
5132# ------------------------------------------------------------------------------
5133
5134#Method void drawPosText(const void* text, size_t byteLength, const SkPoint pos[],
5135 const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05005136#In Draw_Text
5137#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05005138#Line # draws text at array of (x, y) positions ##
Cary Clark8032b982017-07-28 11:04:54 -04005139
Cary Clarkbad5ad72017-08-03 17:14:08 -04005140Draw each glyph in text with the origin in pos array, using Clip, Matrix, and
Cary Clarkce101242017-09-01 15:51:02 -04005141Paint paint. The number of entries in pos array must match the number of Glyphs
Cary Clarkbad5ad72017-08-03 17:14:08 -04005142described by byteLength of text.
Cary Clark8032b982017-07-28 11:04:54 -04005143
Cary Clarkbc5697d2017-10-04 14:31:33 -04005144text meaning depends on Paint_Text_Encoding; by default, text is encoded as
Cary Clarkbad5ad72017-08-03 17:14:08 -04005145UTF-8. pos elements' meaning depends on Paint_Text_Align and Paint_Vertical_Text;
Cary Clarkbc5697d2017-10-04 14:31:33 -04005146by default each glyph left side bearing is positioned at x and its
Cary Clarkbad5ad72017-08-03 17:14:08 -04005147baseline is positioned at y. Text size is affected by Matrix and
Herb Derbyefe39bc2018-05-01 17:06:20 -04005148Paint_Text_Size.
Cary Clark8032b982017-07-28 11:04:54 -04005149
Mike Reed8ad91a92018-01-19 19:09:32 -05005150All elements of paint: Path_Effect, Mask_Filter, Shader,
Cary Clarkbad5ad72017-08-03 17:14:08 -04005151Color_Filter, Image_Filter, and Draw_Looper; apply to text. By default, draws
Cary Clarkce101242017-09-01 15:51:02 -04005152filled 12 point black Glyphs.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005153
5154Layout engines such as Harfbuzz typically position each glyph
Cary Clarkbc5697d2017-10-04 14:31:33 -04005155rather than using the font advance widths.
Cary Clark8032b982017-07-28 11:04:54 -04005156
Cary Clarkce101242017-09-01 15:51:02 -04005157#Param text character code points or Glyphs drawn ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005158#Param byteLength byte length of text array ##
5159#Param pos array of glyph origins ##
5160#Param paint text size, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005161
5162#Example
5163#Height 120
Cary Clarkbad5ad72017-08-03 17:14:08 -04005164void draw(SkCanvas* canvas) {
5165 const char hello[] = "HeLLo!";
5166 const SkPoint pos[] = { {40, 100}, {82, 95}, {115, 110}, {130, 95}, {145, 85},
5167 {172, 100} };
5168 SkPaint paint;
5169 paint.setTextSize(60);
5170 canvas->drawPosText(hello, strlen(hello), pos, paint);
Cary Clark8032b982017-07-28 11:04:54 -04005171}
5172##
5173
Cary Clark2ade9972017-11-02 17:49:34 -04005174#SeeAlso drawText drawPosTextH drawTextBlob drawTextOnPath drawTextRSXform
Cary Clark8032b982017-07-28 11:04:54 -04005175
5176##
5177
5178# ------------------------------------------------------------------------------
5179
5180#Method void drawPosTextH(const void* text, size_t byteLength, const SkScalar xpos[], SkScalar constY,
5181 const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05005182#In Draw_Text
5183#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05005184#Line # draws text at x positions with common baseline ##
Cary Clark8032b982017-07-28 11:04:54 -04005185
Cary Clarkbad5ad72017-08-03 17:14:08 -04005186Draw each glyph in text with its (x, y) origin composed from xpos array and
5187constY, using Clip, Matrix, and Paint paint. The number of entries in xpos array
Cary Clarkce101242017-09-01 15:51:02 -04005188must match the number of Glyphs described by byteLength of text.
Cary Clark8032b982017-07-28 11:04:54 -04005189
Cary Clarkbc5697d2017-10-04 14:31:33 -04005190text meaning depends on Paint_Text_Encoding; by default, text is encoded as
Cary Clarkce101242017-09-01 15:51:02 -04005191UTF-8. xpos elements' meaning depends on Paint_Text_Align and Paint_Vertical_Text;
Cary Clarkbc5697d2017-10-04 14:31:33 -04005192by default each glyph left side bearing is positioned at an xpos element and
Cary Clarkbad5ad72017-08-03 17:14:08 -04005193its baseline is positioned at constY. Text size is affected by Matrix and
Herb Derbyefe39bc2018-05-01 17:06:20 -04005194Paint_Text_Size.
Cary Clark8032b982017-07-28 11:04:54 -04005195
Mike Reed8ad91a92018-01-19 19:09:32 -05005196All elements of paint: Path_Effect, Mask_Filter, Shader,
Cary Clarkbad5ad72017-08-03 17:14:08 -04005197Color_Filter, Image_Filter, and Draw_Looper; apply to text. By default, draws
Cary Clarkce101242017-09-01 15:51:02 -04005198filled 12 point black Glyphs.
Cary Clark8032b982017-07-28 11:04:54 -04005199
Cary Clarkbad5ad72017-08-03 17:14:08 -04005200Layout engines such as Harfbuzz typically position each glyph
Cary Clarkbc5697d2017-10-04 14:31:33 -04005201rather than using the font advance widths if all Glyphs share the same
Cary Clarkbad5ad72017-08-03 17:14:08 -04005202baseline.
5203
Cary Clarkce101242017-09-01 15:51:02 -04005204#Param text character code points or Glyphs drawn ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005205#Param byteLength byte length of text array ##
5206#Param xpos array of x positions, used to position each glyph ##
5207#Param constY shared y coordinate for all of x positions ##
5208#Param paint text size, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005209
5210#Example
5211#Height 40
Cary Clarkbad5ad72017-08-03 17:14:08 -04005212 void draw(SkCanvas* canvas) {
5213 SkScalar xpos[] = { 20, 40, 80, 160 };
5214 SkPaint paint;
5215 canvas->drawPosTextH("XXXX", 4, xpos, 20, paint);
5216 }
Cary Clark8032b982017-07-28 11:04:54 -04005217##
5218
Cary Clark2ade9972017-11-02 17:49:34 -04005219#SeeAlso drawText drawPosText drawTextBlob drawTextOnPath drawTextRSXform
Cary Clark8032b982017-07-28 11:04:54 -04005220
5221##
5222
5223# ------------------------------------------------------------------------------
5224
5225#Method void drawTextOnPathHV(const void* text, size_t byteLength, const SkPath& path, SkScalar hOffset,
5226 SkScalar vOffset, const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05005227#In Draw_Text
5228#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05005229#Line # draws text following Path with offsets ##
Cary Clark8032b982017-07-28 11:04:54 -04005230
5231Draw text on Path path, using Clip, Matrix, and Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04005232
Cary Clarkbad5ad72017-08-03 17:14:08 -04005233Origin of text is at distance hOffset along the path, offset by a perpendicular
5234vector of length vOffset. If the path section corresponding the glyph advance is
5235curved, the glyph is drawn curved to match; control points in the glyph are
Cary Clarkbc5697d2017-10-04 14:31:33 -04005236mapped to projected points parallel to the path. If the text advance is larger
Cary Clarkbad5ad72017-08-03 17:14:08 -04005237than the path length, the excess text is clipped.
5238
Cary Clarkbc5697d2017-10-04 14:31:33 -04005239text meaning depends on Paint_Text_Encoding; by default, text is encoded as
Cary Clarkbad5ad72017-08-03 17:14:08 -04005240UTF-8. Origin meaning depends on Paint_Text_Align and Paint_Vertical_Text; by
Cary Clarkbc5697d2017-10-04 14:31:33 -04005241default text positions the first glyph left side bearing at origin x and its
Herb Derbyefe39bc2018-05-01 17:06:20 -04005242baseline at origin y. Text size is affected by Matrix and Paint_Text_Size.
Cary Clark8032b982017-07-28 11:04:54 -04005243
Mike Reed8ad91a92018-01-19 19:09:32 -05005244All elements of paint: Path_Effect, Mask_Filter, Shader,
Cary Clarkbad5ad72017-08-03 17:14:08 -04005245Color_Filter, Image_Filter, and Draw_Looper; apply to text. By default, draws
Cary Clarkce101242017-09-01 15:51:02 -04005246filled 12 point black Glyphs.
Cary Clark8032b982017-07-28 11:04:54 -04005247
Cary Clarkce101242017-09-01 15:51:02 -04005248#Param text character code points or Glyphs drawn ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005249#Param byteLength byte length of text array ##
5250#Param path Path providing text baseline ##
5251#Param hOffset distance along path to offset origin ##
5252#Param vOffset offset of text above (if negative) or below (if positive) the path ##
5253#Param paint text size, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005254
5255#Example
Herb Derbyefe39bc2018-05-01 17:06:20 -04005256 void draw(SkCanvas* canvas) {
Cary Clarkbad5ad72017-08-03 17:14:08 -04005257 const char aero[] = "correo a" "\xC3" "\xA9" "reo";
5258 const size_t len = sizeof(aero) - 1;
5259 SkPath path;
5260 path.addOval({43-26, 43-26, 43+26, 43+26}, SkPath::kCW_Direction, 3);
5261 SkPaint paint;
5262 paint.setTextSize(24);
5263 for (auto offset : { 0, 10, 20 } ) {
5264 canvas->drawTextOnPathHV(aero, len, path, 0, -offset, paint);
5265 canvas->translate(70 + offset, 70 + offset);
5266 }
5267 }
Cary Clark8032b982017-07-28 11:04:54 -04005268##
5269
Cary Clark2ade9972017-11-02 17:49:34 -04005270#SeeAlso drawTextOnPath drawText drawPosTextH drawTextBlob drawTextRSXform
Cary Clark8032b982017-07-28 11:04:54 -04005271
5272##
5273
5274# ------------------------------------------------------------------------------
5275
5276#Method void drawTextOnPath(const void* text, size_t byteLength, const SkPath& path,
5277 const SkMatrix* matrix, const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05005278#In Draw_Text
5279#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05005280#Line # draws text following Path contour ##
Cary Clark8032b982017-07-28 11:04:54 -04005281
5282Draw text on Path path, using Clip, Matrix, and Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04005283
Cary Clarkbad5ad72017-08-03 17:14:08 -04005284Origin of text is at beginning of path offset by matrix, if provided, before it
5285is mapped to path. If the path section corresponding the glyph advance is
5286curved, the glyph is drawn curved to match; control points in the glyph are
Cary Clarkbc5697d2017-10-04 14:31:33 -04005287mapped to projected points parallel to the path. If the text advance is larger
Cary Clarkbad5ad72017-08-03 17:14:08 -04005288than the path length, the excess text is clipped.
5289
Cary Clarkbc5697d2017-10-04 14:31:33 -04005290text meaning depends on Paint_Text_Encoding; by default, text is encoded as
Cary Clarkbad5ad72017-08-03 17:14:08 -04005291UTF-8. Origin meaning depends on Paint_Text_Align and Paint_Vertical_Text; by
Cary Clarkbc5697d2017-10-04 14:31:33 -04005292default text positions the first glyph left side bearing at origin x and its
Herb Derbyefe39bc2018-05-01 17:06:20 -04005293baseline at origin y. Text size is affected by Matrix and Paint_Text_Size.
Cary Clark8032b982017-07-28 11:04:54 -04005294
Mike Reed8ad91a92018-01-19 19:09:32 -05005295All elements of paint: Path_Effect, Mask_Filter, Shader,
Cary Clarkbad5ad72017-08-03 17:14:08 -04005296Color_Filter, Image_Filter, and Draw_Looper; apply to text. By default, draws
Cary Clarkce101242017-09-01 15:51:02 -04005297filled 12 point black Glyphs.
Cary Clark8032b982017-07-28 11:04:54 -04005298
Cary Clarkce101242017-09-01 15:51:02 -04005299#Param text character code points or Glyphs drawn ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005300#Param byteLength byte length of text array ##
5301#Param path Path providing text baseline ##
Cary Clarkce101242017-09-01 15:51:02 -04005302#Param matrix transform of Glyphs before mapping to path; may be nullptr
Cary Clarka523d2d2017-08-30 08:58:10 -04005303 to use identity Matrix
Cary Clarkbad5ad72017-08-03 17:14:08 -04005304##
5305#Param paint text size, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005306
5307#Example
Herb Derbyefe39bc2018-05-01 17:06:20 -04005308 void draw(SkCanvas* canvas) {
Cary Clarkbad5ad72017-08-03 17:14:08 -04005309 const char roller[] = "rollercoaster";
5310 const size_t len = sizeof(roller) - 1;
5311 SkPath path;
5312 path.cubicTo(40, -80, 120, 80, 160, -40);
5313 SkPaint paint;
5314 paint.setTextSize(32);
5315 paint.setStyle(SkPaint::kStroke_Style);
5316 SkMatrix matrix;
5317 matrix.setIdentity();
5318 for (int i = 0; i < 3; ++i) {
5319 canvas->translate(25, 60);
5320 canvas->drawPath(path, paint);
5321 canvas->drawTextOnPath(roller, len, path, &matrix, paint);
5322 matrix.preTranslate(0, 10);
5323 }
5324 }
Cary Clark8032b982017-07-28 11:04:54 -04005325##
5326
Cary Clark2ade9972017-11-02 17:49:34 -04005327#SeeAlso drawTextOnPathHV drawText drawPosTextH drawTextBlob drawTextRSXform
Cary Clark8032b982017-07-28 11:04:54 -04005328
5329##
5330
5331# ------------------------------------------------------------------------------
5332
5333#Method void drawTextRSXform(const void* text, size_t byteLength, const SkRSXform xform[],
5334 const SkRect* cullRect, const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05005335#In Draw_Text
5336#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05005337#Line # draws text with array of RSXform ##
Cary Clark8032b982017-07-28 11:04:54 -04005338
5339Draw text, transforming each glyph by the corresponding SkRSXform,
5340using Clip, Matrix, and Paint paint.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005341
Herb Derbyefe39bc2018-05-01 17:06:20 -04005342RSXform array specifies a separate square scale, rotation, and translation for
Cary Clark8032b982017-07-28 11:04:54 -04005343each glyph.
Cary Clark8032b982017-07-28 11:04:54 -04005344
Cary Clarkbad5ad72017-08-03 17:14:08 -04005345Optional Rect cullRect is a conservative bounds of text, taking into account
Cary Clarkce101242017-09-01 15:51:02 -04005346RSXform and paint. If cullRect is outside of Clip, canvas can skip drawing.
Cary Clark8032b982017-07-28 11:04:54 -04005347
Mike Reed8ad91a92018-01-19 19:09:32 -05005348All elements of paint: Path_Effect, Mask_Filter, Shader,
Cary Clarkbad5ad72017-08-03 17:14:08 -04005349Color_Filter, Image_Filter, and Draw_Looper; apply to text. By default, draws
Cary Clarkce101242017-09-01 15:51:02 -04005350filled 12 point black Glyphs.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005351
Cary Clarkce101242017-09-01 15:51:02 -04005352#Param text character code points or Glyphs drawn ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005353#Param byteLength byte length of text array ##
5354#Param xform RSXform rotates, scales, and translates each glyph individually ##
5355#Param cullRect Rect bounds of text for efficient clipping; or nullptr ##
5356#Param paint text size, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005357
5358#Example
Herb Derbyefe39bc2018-05-01 17:06:20 -04005359void draw(SkCanvas* canvas) {
Cary Clarkbad5ad72017-08-03 17:14:08 -04005360 const int iterations = 26;
5361 SkRSXform transforms[iterations];
5362 char alphabet[iterations];
5363 SkScalar angle = 0;
5364 SkScalar scale = 1;
5365 for (size_t i = 0; i < SK_ARRAY_COUNT(transforms); ++i) {
5366 const SkScalar s = SkScalarSin(angle) * scale;
5367 const SkScalar c = SkScalarCos(angle) * scale;
5368 transforms[i] = SkRSXform::Make(-c, -s, -s * 16, c * 16);
5369 angle += .45;
5370 scale += .2;
5371 alphabet[i] = 'A' + i;
5372 }
5373 SkPaint paint;
5374 paint.setTextAlign(SkPaint::kCenter_Align);
5375 canvas->translate(110, 138);
5376 canvas->drawTextRSXform(alphabet, sizeof(alphabet), transforms, nullptr, paint);
Cary Clark8032b982017-07-28 11:04:54 -04005377}
5378##
5379
Cary Clark2ade9972017-11-02 17:49:34 -04005380#SeeAlso drawTextOnPath drawTextOnPathHV drawText drawPosText drawTextBlob
Cary Clark8032b982017-07-28 11:04:54 -04005381
5382##
5383
5384# ------------------------------------------------------------------------------
5385
5386#Method void drawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y, const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05005387#In Draw_Text
5388#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05005389#Line # draws text with arrays of positions and Paint ##
Cary Clark8032b982017-07-28 11:04:54 -04005390Draw Text_Blob blob at (x, y), using Clip, Matrix, and Paint paint.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005391
Cary Clarkce101242017-09-01 15:51:02 -04005392blob contains Glyphs, their positions, and paint attributes specific to text:
Cary Clarkbad5ad72017-08-03 17:14:08 -04005393Typeface, Paint_Text_Size, Paint_Text_Scale_X, Paint_Text_Skew_X,
5394Paint_Text_Align, Paint_Hinting, Anti-alias, Paint_Fake_Bold,
5395Font_Embedded_Bitmaps, Full_Hinting_Spacing, LCD_Text, Linear_Text,
5396Subpixel_Text, and Paint_Vertical_Text.
Cary Clark8032b982017-07-28 11:04:54 -04005397
Cary Clark3cd22cc2017-12-01 11:49:58 -05005398Paint_Text_Encoding must be set to SkPaint::kGlyphID_TextEncoding.
5399
Mike Reed8ad91a92018-01-19 19:09:32 -05005400Elements of paint: Path_Effect, Mask_Filter, Shader, Color_Filter,
Cary Clark8032b982017-07-28 11:04:54 -04005401Image_Filter, and Draw_Looper; apply to blob.
5402
Cary Clarkce101242017-09-01 15:51:02 -04005403#Param blob Glyphs, positions, and their paints' text size, typeface, and so on ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005404#Param x horizontal offset applied to blob ##
5405#Param y vertical offset applied to blob ##
5406#Param paint blend, color, stroking, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005407
5408#Example
5409#Height 120
Cary Clarkbad5ad72017-08-03 17:14:08 -04005410 void draw(SkCanvas* canvas) {
Cary Clark2f466242017-12-11 16:03:17 -05005411 SkTextBlobBuilder textBlobBuilder;
5412 const char bunny[] = "/(^x^)\\";
5413 const int len = sizeof(bunny) - 1;
5414 uint16_t glyphs[len];
5415 SkPaint paint;
5416 paint.textToGlyphs(bunny, len, glyphs);
Cary Clark3cd22cc2017-12-01 11:49:58 -05005417 paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
Cary Clark2f466242017-12-11 16:03:17 -05005418 int runs[] = { 3, 1, 3 };
5419 SkPoint textPos = { 20, 100 };
5420 int glyphIndex = 0;
5421 for (auto runLen : runs) {
5422 paint.setTextSize(1 == runLen ? 20 : 50);
Herb Derbyefe39bc2018-05-01 17:06:20 -04005423 const SkTextBlobBuilder::RunBuffer& run =
Cary Clark2f466242017-12-11 16:03:17 -05005424 textBlobBuilder.allocRun(paint, runLen, textPos.fX, textPos.fY);
5425 memcpy(run.glyphs, &glyphs[glyphIndex], sizeof(glyphs[0]) * runLen);
5426 textPos.fX += paint.measureText(&glyphs[glyphIndex], sizeof(glyphs[0]) * runLen, nullptr);
5427 glyphIndex += runLen;
5428 }
5429 sk_sp<const SkTextBlob> blob = textBlobBuilder.make();
5430 paint.reset();
Cary Clarkbad5ad72017-08-03 17:14:08 -04005431 canvas->drawTextBlob(blob.get(), 0, 0, paint);
Cary Clark8032b982017-07-28 11:04:54 -04005432 }
5433##
5434
Cary Clark2ade9972017-11-02 17:49:34 -04005435#SeeAlso drawText drawPosText drawPosTextH
Cary Clark8032b982017-07-28 11:04:54 -04005436
5437##
5438
5439# ------------------------------------------------------------------------------
5440
Herb Derbyefe39bc2018-05-01 17:06:20 -04005441#Method void drawTextBlob(const sk_sp<SkTextBlob>& blob, SkScalar x, SkScalar y, const SkPaint& paint)
Cary Clark8032b982017-07-28 11:04:54 -04005442
5443Draw Text_Blob blob at (x, y), using Clip, Matrix, and Paint paint.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005444
Cary Clarkce101242017-09-01 15:51:02 -04005445blob contains Glyphs, their positions, and paint attributes specific to text:
Cary Clarkbad5ad72017-08-03 17:14:08 -04005446Typeface, Paint_Text_Size, Paint_Text_Scale_X, Paint_Text_Skew_X,
5447Paint_Text_Align, Paint_Hinting, Anti-alias, Paint_Fake_Bold,
5448Font_Embedded_Bitmaps, Full_Hinting_Spacing, LCD_Text, Linear_Text,
5449Subpixel_Text, and Paint_Vertical_Text.
Cary Clark8032b982017-07-28 11:04:54 -04005450
Cary Clark3cd22cc2017-12-01 11:49:58 -05005451Paint_Text_Encoding must be set to SkPaint::kGlyphID_TextEncoding.
5452
Herb Derbyefe39bc2018-05-01 17:06:20 -04005453Elements of paint: Path_Effect, Mask_Filter, Shader, Color_Filter,
Cary Clark8032b982017-07-28 11:04:54 -04005454Image_Filter, and Draw_Looper; apply to blob.
5455
Cary Clarkce101242017-09-01 15:51:02 -04005456#Param blob Glyphs, positions, and their paints' text size, typeface, and so on ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005457#Param x horizontal offset applied to blob ##
5458#Param y vertical offset applied to blob ##
5459#Param paint blend, color, stroking, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005460
5461#Example
5462#Height 120
5463#Description
5464Paint attributes unrelated to text, like color, have no effect on paint in allocated Text_Blob.
5465Paint attributes related to text, like text size, have no effect on paint passed to drawTextBlob.
5466##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005467 void draw(SkCanvas* canvas) {
5468 SkTextBlobBuilder textBlobBuilder;
5469 SkPaint paint;
5470 paint.setTextSize(50);
5471 paint.setColor(SK_ColorRED);
Cary Clark2f466242017-12-11 16:03:17 -05005472 paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
Herb Derbyefe39bc2018-05-01 17:06:20 -04005473 const SkTextBlobBuilder::RunBuffer& run =
Cary Clarkbad5ad72017-08-03 17:14:08 -04005474 textBlobBuilder.allocRun(paint, 1, 20, 100);
5475 run.glyphs[0] = 20;
5476 sk_sp<const SkTextBlob> blob = textBlobBuilder.make();
5477 paint.setTextSize(10);
5478 paint.setColor(SK_ColorBLUE);
5479 canvas->drawTextBlob(blob.get(), 0, 0, paint);
5480 }
Cary Clark8032b982017-07-28 11:04:54 -04005481##
5482
Cary Clark2ade9972017-11-02 17:49:34 -04005483#SeeAlso drawText drawPosText drawPosTextH
Cary Clark8032b982017-07-28 11:04:54 -04005484
5485##
5486
5487# ------------------------------------------------------------------------------
5488
Herb Derbyefe39bc2018-05-01 17:06:20 -04005489#Method void drawPicture(const SkPicture* picture)
Cary Clark78de7512018-02-07 07:27:09 -05005490#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05005491#Line # draws Picture using Clip and Matrix ##
Cary Clark8032b982017-07-28 11:04:54 -04005492Draw Picture picture, using Clip and Matrix.
5493Clip and Matrix are unchanged by picture contents, as if
5494save() was called before and restore() was called after drawPicture.
5495
5496Picture records a series of draw commands for later playback.
5497
Cary Clarkbad5ad72017-08-03 17:14:08 -04005498#Param picture recorded drawing commands to play ##
Cary Clark8032b982017-07-28 11:04:54 -04005499
5500#Example
Herb Derbyefe39bc2018-05-01 17:06:20 -04005501void draw(SkCanvas* canvas) {
Cary Clarkbad5ad72017-08-03 17:14:08 -04005502 SkPictureRecorder recorder;
5503 SkCanvas* recordingCanvas = recorder.beginRecording(50, 50);
5504 for (auto color : { SK_ColorRED, SK_ColorBLUE, 0xff007f00 } ) {
5505 SkPaint paint;
5506 paint.setColor(color);
5507 recordingCanvas->drawRect({10, 10, 30, 40}, paint);
5508 recordingCanvas->translate(10, 10);
5509 recordingCanvas->scale(1.2f, 1.4f);
5510 }
5511 sk_sp<SkPicture> playback = recorder.finishRecordingAsPicture();
Cary Clarkbad5ad72017-08-03 17:14:08 -04005512 canvas->drawPicture(playback);
5513 canvas->scale(2, 2);
5514 canvas->translate(50, 0);
5515 canvas->drawPicture(playback);
Cary Clark8032b982017-07-28 11:04:54 -04005516}
5517##
5518
Cary Clark2ade9972017-11-02 17:49:34 -04005519#SeeAlso drawDrawable SkPicture SkPicture::playback
Cary Clark8032b982017-07-28 11:04:54 -04005520
5521##
5522
5523# ------------------------------------------------------------------------------
5524
Herb Derbyefe39bc2018-05-01 17:06:20 -04005525#Method void drawPicture(const sk_sp<SkPicture>& picture)
Cary Clark8032b982017-07-28 11:04:54 -04005526
5527Draw Picture picture, using Clip and Matrix.
5528Clip and Matrix are unchanged by picture contents, as if
5529save() was called before and restore() was called after drawPicture.
5530
5531Picture records a series of draw commands for later playback.
5532
Cary Clarkbad5ad72017-08-03 17:14:08 -04005533#Param picture recorded drawing commands to play ##
Cary Clark8032b982017-07-28 11:04:54 -04005534
5535#Example
Herb Derbyefe39bc2018-05-01 17:06:20 -04005536void draw(SkCanvas* canvas) {
Cary Clarkbad5ad72017-08-03 17:14:08 -04005537 SkPictureRecorder recorder;
5538 SkCanvas* recordingCanvas = recorder.beginRecording(50, 50);
5539 for (auto color : { SK_ColorRED, SK_ColorBLUE, 0xff007f00 } ) {
5540 SkPaint paint;
5541 paint.setColor(color);
5542 recordingCanvas->drawRect({10, 10, 30, 40}, paint);
5543 recordingCanvas->translate(10, 10);
5544 recordingCanvas->scale(1.2f, 1.4f);
5545 }
5546 sk_sp<SkPicture> playback = recorder.finishRecordingAsPicture();
5547 canvas->drawPicture(playback);
5548 canvas->scale(2, 2);
5549 canvas->translate(50, 0);
5550 canvas->drawPicture(playback);
Cary Clark8032b982017-07-28 11:04:54 -04005551}
5552##
5553
Cary Clark2ade9972017-11-02 17:49:34 -04005554#SeeAlso drawDrawable SkPicture SkPicture::playback
Cary Clark8032b982017-07-28 11:04:54 -04005555
5556##
5557
5558# ------------------------------------------------------------------------------
5559
5560#Method void drawPicture(const SkPicture* picture, const SkMatrix* matrix, const SkPaint* paint)
5561
Cary Clarkbad5ad72017-08-03 17:14:08 -04005562Draw Picture picture, using Clip and Matrix; transforming picture with
5563Matrix matrix, if provided; and use Paint paint Color_Alpha, Color_Filter,
5564Image_Filter, and Blend_Mode, if provided.
Cary Clark8032b982017-07-28 11:04:54 -04005565
5566matrix transformation is equivalent to: save(), concat(), drawPicture, restore().
5567paint use is equivalent to: saveLayer, drawPicture, restore().
5568
Cary Clarkbad5ad72017-08-03 17:14:08 -04005569#Param picture recorded drawing commands to play ##
5570#Param matrix Matrix to rotate, scale, translate, and so on; may be nullptr ##
5571#Param paint Paint to apply transparency, filtering, and so on; may be nullptr ##
Cary Clark8032b982017-07-28 11:04:54 -04005572
5573#Example
Herb Derbyefe39bc2018-05-01 17:06:20 -04005574void draw(SkCanvas* canvas) {
Cary Clarkbad5ad72017-08-03 17:14:08 -04005575 SkPaint paint;
5576 SkPictureRecorder recorder;
5577 SkCanvas* recordingCanvas = recorder.beginRecording(50, 50);
5578 for (auto color : { SK_ColorRED, SK_ColorBLUE, 0xff007f00 } ) {
5579 paint.setColor(color);
5580 recordingCanvas->drawRect({10, 10, 30, 40}, paint);
5581 recordingCanvas->translate(10, 10);
5582 recordingCanvas->scale(1.2f, 1.4f);
5583 }
5584 sk_sp<SkPicture> playback = recorder.finishRecordingAsPicture();
5585 const SkPicture* playbackPtr = playback.get();
5586 SkMatrix matrix;
5587 matrix.reset();
5588 for (auto alpha : { 70, 140, 210 } ) {
5589 paint.setAlpha(alpha);
5590 canvas->drawPicture(playbackPtr, &matrix, &paint);
5591 matrix.preTranslate(70, 70);
5592 }
Cary Clark8032b982017-07-28 11:04:54 -04005593}
5594##
5595
Cary Clark2ade9972017-11-02 17:49:34 -04005596#SeeAlso drawDrawable SkPicture SkPicture::playback
Cary Clark8032b982017-07-28 11:04:54 -04005597
5598##
5599
5600# ------------------------------------------------------------------------------
5601
Herb Derbyefe39bc2018-05-01 17:06:20 -04005602#Method void drawPicture(const sk_sp<SkPicture>& picture, const SkMatrix* matrix, const SkPaint* paint)
Cary Clark8032b982017-07-28 11:04:54 -04005603
Cary Clarkbad5ad72017-08-03 17:14:08 -04005604Draw Picture picture, using Clip and Matrix; transforming picture with
5605Matrix matrix, if provided; and use Paint paint Color_Alpha, Color_Filter,
5606Image_Filter, and Blend_Mode, if provided.
Cary Clark8032b982017-07-28 11:04:54 -04005607
5608matrix transformation is equivalent to: save(), concat(), drawPicture, restore().
5609paint use is equivalent to: saveLayer, drawPicture, restore().
5610
Cary Clarkbad5ad72017-08-03 17:14:08 -04005611#Param picture recorded drawing commands to play ##
5612#Param matrix Matrix to rotate, scale, translate, and so on; may be nullptr ##
5613#Param paint Paint to apply transparency, filtering, and so on; may be nullptr ##
Cary Clark8032b982017-07-28 11:04:54 -04005614
5615#Example
Herb Derbyefe39bc2018-05-01 17:06:20 -04005616void draw(SkCanvas* canvas) {
Cary Clarkbad5ad72017-08-03 17:14:08 -04005617 SkPaint paint;
5618 SkPictureRecorder recorder;
5619 SkCanvas* recordingCanvas = recorder.beginRecording(50, 50);
5620 for (auto color : { SK_ColorRED, SK_ColorBLUE, 0xff007f00 } ) {
5621 paint.setColor(color);
5622 recordingCanvas->drawRect({10, 10, 30, 40}, paint);
5623 recordingCanvas->translate(10, 10);
5624 recordingCanvas->scale(1.2f, 1.4f);
5625 }
5626 sk_sp<SkPicture> playback = recorder.finishRecordingAsPicture();
5627 SkMatrix matrix;
5628 matrix.reset();
5629 for (auto alpha : { 70, 140, 210 } ) {
5630 paint.setAlpha(alpha);
5631 canvas->drawPicture(playback, &matrix, &paint);
5632 matrix.preTranslate(70, 70);
5633 }
Cary Clark8032b982017-07-28 11:04:54 -04005634}
5635##
5636
Cary Clark2ade9972017-11-02 17:49:34 -04005637#SeeAlso drawDrawable SkPicture SkPicture::playback
Cary Clark8032b982017-07-28 11:04:54 -04005638
5639##
5640
5641# ------------------------------------------------------------------------------
5642
5643#Method void drawVertices(const SkVertices* vertices, SkBlendMode mode, const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05005644#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05005645#Line # draws Vertices, a triangle mesh ##
Cary Clark8032b982017-07-28 11:04:54 -04005646Draw Vertices vertices, a triangle mesh, using Clip and Matrix.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005647If Vertices_Texs and Vertices_Colors are defined in vertices, and Paint paint
5648contains Shader, Blend_Mode mode combines Vertices_Colors with Shader.
Cary Clark8032b982017-07-28 11:04:54 -04005649
Cary Clarkbad5ad72017-08-03 17:14:08 -04005650#Param vertices triangle mesh to draw ##
5651#Param mode combines Vertices_Colors with Shader, if both are present ##
5652#Param paint specifies the Shader, used as Vertices texture; may be nullptr ##
Cary Clark8032b982017-07-28 11:04:54 -04005653
5654#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04005655void draw(SkCanvas* canvas) {
5656 SkPaint paint;
5657 SkPoint points[] = { { 0, 0 }, { 250, 0 }, { 100, 100 }, { 0, 250 } };
5658 SkColor colors[] = { SK_ColorRED, SK_ColorBLUE, SK_ColorYELLOW, SK_ColorCYAN };
5659 auto vertices = SkVertices::MakeCopy(SkVertices::kTriangleFan_VertexMode,
5660 SK_ARRAY_COUNT(points), points, nullptr, colors);
5661 canvas->drawVertices(vertices.get(), SkBlendMode::kSrc, paint);
5662}
Cary Clark8032b982017-07-28 11:04:54 -04005663##
5664
Cary Clark2ade9972017-11-02 17:49:34 -04005665#SeeAlso drawPatch drawPicture
Cary Clark8032b982017-07-28 11:04:54 -04005666
5667##
5668
5669# ------------------------------------------------------------------------------
5670
5671#Method void drawVertices(const sk_sp<SkVertices>& vertices, SkBlendMode mode, const SkPaint& paint)
5672
5673Draw Vertices vertices, a triangle mesh, using Clip and Matrix.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005674If Vertices_Texs and Vertices_Colors are defined in vertices, and Paint paint
5675contains Shader, Blend_Mode mode combines Vertices_Colors with Shader.
Cary Clark8032b982017-07-28 11:04:54 -04005676
Cary Clarkbad5ad72017-08-03 17:14:08 -04005677#Param vertices triangle mesh to draw ##
5678#Param mode combines Vertices_Colors with Shader, if both are present ##
5679#Param paint specifies the Shader, used as Vertices texture, may be nullptr ##
Cary Clark8032b982017-07-28 11:04:54 -04005680
5681#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04005682void draw(SkCanvas* canvas) {
5683 SkPaint paint;
5684 SkPoint points[] = { { 0, 0 }, { 250, 0 }, { 100, 100 }, { 0, 250 } };
5685 SkPoint texs[] = { { 0, 0 }, { 0, 250 }, { 250, 250 }, { 250, 0 } };
5686 SkColor colors[] = { SK_ColorRED, SK_ColorBLUE, SK_ColorYELLOW, SK_ColorCYAN };
5687 paint.setShader(SkGradientShader::MakeLinear(points, colors, nullptr, 4,
5688 SkShader::kClamp_TileMode));
5689 auto vertices = SkVertices::MakeCopy(SkVertices::kTriangleFan_VertexMode,
5690 SK_ARRAY_COUNT(points), points, texs, colors);
5691 canvas->drawVertices(vertices.get(), SkBlendMode::kDarken, paint);
Cary Clark8032b982017-07-28 11:04:54 -04005692}
5693##
5694
Cary Clark2ade9972017-11-02 17:49:34 -04005695#SeeAlso drawPatch drawPicture
Cary Clark8032b982017-07-28 11:04:54 -04005696
5697##
5698
5699# ------------------------------------------------------------------------------
5700
5701#Method void drawPatch(const SkPoint cubics[12], const SkColor colors[4],
5702 const SkPoint texCoords[4], SkBlendMode mode, const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05005703#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05005704#Line # draws Coons_Patch ##
Cary Clark8032b982017-07-28 11:04:54 -04005705
Herb Derbyefe39bc2018-05-01 17:06:20 -04005706Draws a Coons_Patch: the interpolation of four cubics with shared corners,
Cary Clark8032b982017-07-28 11:04:54 -04005707associating a color, and optionally a texture coordinate, with each corner.
5708
Cary Clarka560c472017-11-27 10:44:06 -05005709Coons_Patch uses Clip and Matrix, paint Shader, Color_Filter,
Cary Clarkbad5ad72017-08-03 17:14:08 -04005710Color_Alpha, Image_Filter, and Blend_Mode. If Shader is provided it is treated
Cary Clarka560c472017-11-27 10:44:06 -05005711as Coons_Patch texture; Blend_Mode mode combines Color colors and Shader if
Cary Clarkbad5ad72017-08-03 17:14:08 -04005712both are provided.
Cary Clark8032b982017-07-28 11:04:54 -04005713
Herb Derbyefe39bc2018-05-01 17:06:20 -04005714Point array cubics specifies four Cubics starting at the top-left corner,
Cary Clarkce101242017-09-01 15:51:02 -04005715in clockwise order, sharing every fourth point. The last Cubic ends at the
Cary Clarkbad5ad72017-08-03 17:14:08 -04005716first point.
Cary Clark8032b982017-07-28 11:04:54 -04005717
Cary Clarkbc5697d2017-10-04 14:31:33 -04005718Color array color associates colors with corners in top-left, top-right,
5719bottom-right, bottom-left order.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005720
5721If paint contains Shader, Point array texCoords maps Shader as texture to
Cary Clarkbc5697d2017-10-04 14:31:33 -04005722corners in top-left, top-right, bottom-right, bottom-left order.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005723
Cary Clarka523d2d2017-08-30 08:58:10 -04005724#Param cubics Path_Cubic array, sharing common points ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005725#Param colors Color array, one for each corner ##
Cary Clarkce101242017-09-01 15:51:02 -04005726#Param texCoords Point array of texture coordinates, mapping Shader to corners;
Herb Derbyefe39bc2018-05-01 17:06:20 -04005727 may be nullptr
Cary Clark579985c2017-07-31 11:48:27 -04005728#Param ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005729#Param mode Blend_Mode for colors, and for Shader if paint has one ##
5730#Param paint Shader, Color_Filter, Blend_Mode, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005731
5732#Example
5733#Image 5
Cary Clarkbad5ad72017-08-03 17:14:08 -04005734void draw(SkCanvas* canvas) {
5735 // SkBitmap source = cmbkygk;
5736 SkPaint paint;
5737 paint.setFilterQuality(kLow_SkFilterQuality);
5738 paint.setAntiAlias(true);
5739 SkPoint cubics[] = { { 3, 1 }, { 4, 2 }, { 5, 1 }, { 7, 3 },
5740 /* { 7, 3 }, */ { 6, 4 }, { 7, 5 }, { 5, 7 },
5741 /* { 5, 7 }, */ { 4, 6 }, { 3, 7 }, { 1, 5 },
5742 /* { 1, 5 }, */ { 2, 4 }, { 1, 3 }, /* { 3, 1 } */ };
5743 SkColor colors[] = { 0xbfff0000, 0xbf0000ff, 0xbfff00ff, 0xbf00ffff };
5744 SkPoint texCoords[] = { { -30, -30 }, { 162, -30}, { 162, 162}, { -30, 162} };
5745 paint.setShader(SkShader::MakeBitmapShader(source, SkShader::kClamp_TileMode,
5746 SkShader::kClamp_TileMode, nullptr));
5747 canvas->scale(15, 15);
5748 for (auto blend : { SkBlendMode::kSrcOver, SkBlendMode::kModulate, SkBlendMode::kXor } ) {
5749 canvas->drawPatch(cubics, colors, texCoords, blend, paint);
5750 canvas->translate(4, 4);
5751 }
Cary Clark8032b982017-07-28 11:04:54 -04005752}
5753##
5754
Cary Clark2ade9972017-11-02 17:49:34 -04005755#ToDo can patch use image filter? ##
5756#SeeAlso SeeAlso drawVertices drawPicture
Cary Clark8032b982017-07-28 11:04:54 -04005757
5758##
5759
5760# ------------------------------------------------------------------------------
5761
5762#Method void drawPatch(const SkPoint cubics[12], const SkColor colors[4],
Herb Derbyefe39bc2018-05-01 17:06:20 -04005763 const SkPoint texCoords[4], const SkPaint& paint)
Cary Clark8032b982017-07-28 11:04:54 -04005764
Herb Derbyefe39bc2018-05-01 17:06:20 -04005765Draws Cubic Coons_Patch: the interpolation of four cubics with shared corners,
Cary Clarkbad5ad72017-08-03 17:14:08 -04005766associating a color, and optionally a texture coordinate, with each corner.
Cary Clark8032b982017-07-28 11:04:54 -04005767
Cary Clarka560c472017-11-27 10:44:06 -05005768Coons_Patch uses Clip and Matrix, paint Shader, Color_Filter,
Cary Clarkbad5ad72017-08-03 17:14:08 -04005769Color_Alpha, Image_Filter, and Blend_Mode. If Shader is provided it is treated
Cary Clarka560c472017-11-27 10:44:06 -05005770as Coons_Patch texture; Blend_Mode mode combines Color colors and Shader if
Cary Clarkbad5ad72017-08-03 17:14:08 -04005771both are provided.
Cary Clark8032b982017-07-28 11:04:54 -04005772
Herb Derbyefe39bc2018-05-01 17:06:20 -04005773Point array cubics specifies four Cubics starting at the top-left corner,
Cary Clarkce101242017-09-01 15:51:02 -04005774in clockwise order, sharing every fourth point. The last Cubic ends at the
Cary Clarkbad5ad72017-08-03 17:14:08 -04005775first point.
5776
Cary Clarkbc5697d2017-10-04 14:31:33 -04005777Color array color associates colors with corners in top-left, top-right,
5778bottom-right, bottom-left order.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005779
5780If paint contains Shader, Point array texCoords maps Shader as texture to
Cary Clarkbc5697d2017-10-04 14:31:33 -04005781corners in top-left, top-right, bottom-right, bottom-left order.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005782
Cary Clarka523d2d2017-08-30 08:58:10 -04005783#Param cubics Path_Cubic array, sharing common points ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005784#Param colors Color array, one for each corner ##
Cary Clarkce101242017-09-01 15:51:02 -04005785#Param texCoords Point array of texture coordinates, mapping Shader to corners;
Herb Derbyefe39bc2018-05-01 17:06:20 -04005786 may be nullptr
Cary Clark579985c2017-07-31 11:48:27 -04005787#Param ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005788#Param paint Shader, Color_Filter, Blend_Mode, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005789
5790#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04005791void draw(SkCanvas* canvas) {
5792 SkPaint paint;
5793 paint.setAntiAlias(true);
5794 SkPoint cubics[] = { { 3, 1 }, { 4, 2 }, { 5, 1 }, { 7, 3 },
5795 /* { 7, 3 }, */ { 6, 4 }, { 7, 5 }, { 5, 7 },
5796 /* { 5, 7 }, */ { 4, 6 }, { 3, 7 }, { 1, 5 },
5797 /* { 1, 5 }, */ { 2, 4 }, { 1, 3 }, /* { 3, 1 } */ };
5798 SkColor colors[] = { SK_ColorRED, SK_ColorBLUE, SK_ColorYELLOW, SK_ColorCYAN };
5799 canvas->scale(30, 30);
5800 canvas->drawPatch(cubics, colors, nullptr, paint);
5801 SkPoint text[] = { {3,0.9f}, {4,2.5f}, {5,0.9f}, {7.5f,3.2f}, {5.5f,4.2f},
5802 {7.5f,5.2f}, {5,7.5f}, {4,5.9f}, {3,7.5f}, {0.5f,5.2f}, {2.5f,4.2f},
5803 {0.5f,3.2f} };
5804 paint.setTextSize(18.f / 30);
5805 paint.setTextAlign(SkPaint::kCenter_Align);
5806 for (int i = 0; i< 10; ++i) {
5807 char digit = '0' + i;
5808 canvas->drawText(&digit, 1, text[i].fX, text[i].fY, paint);
5809 }
5810 canvas->drawString("10", text[10].fX, text[10].fY, paint);
5811 canvas->drawString("11", text[11].fX, text[11].fY, paint);
5812 paint.setStyle(SkPaint::kStroke_Style);
5813 canvas->drawPoints(SkCanvas::kPolygon_PointMode, 12, cubics, paint);
5814 canvas->drawLine(cubics[11].fX, cubics[11].fY, cubics[0].fX, cubics[0].fY, paint);
Cary Clark8032b982017-07-28 11:04:54 -04005815}
5816##
5817
5818#Example
5819#Image 6
Cary Clarkbad5ad72017-08-03 17:14:08 -04005820void draw(SkCanvas* canvas) {
5821 // SkBitmap source = checkerboard;
5822 SkPaint paint;
5823 paint.setFilterQuality(kLow_SkFilterQuality);
5824 paint.setAntiAlias(true);
5825 SkPoint cubics[] = { { 3, 1 }, { 4, 2 }, { 5, 1 }, { 7, 3 },
5826 /* { 7, 3 }, */ { 6, 4 }, { 7, 5 }, { 5, 7 },
5827 /* { 5, 7 }, */ { 4, 6 }, { 3, 7 }, { 1, 5 },
5828 /* { 1, 5 }, */ { 2, 4 }, { 1, 3 }, /* { 3, 1 } */ };
5829 SkPoint texCoords[] = { { 0, 0 }, { 0, 62}, { 62, 62}, { 62, 0 } };
5830 paint.setShader(SkShader::MakeBitmapShader(source, SkShader::kClamp_TileMode,
5831 SkShader::kClamp_TileMode, nullptr));
5832 canvas->scale(30, 30);
5833 canvas->drawPatch(cubics, nullptr, texCoords, paint);
Cary Clark8032b982017-07-28 11:04:54 -04005834}
5835##
5836
Cary Clark2ade9972017-11-02 17:49:34 -04005837#ToDo can patch use image filter? ##
5838#SeeAlso SeeAlso drawVertices drawPicture
Cary Clark8032b982017-07-28 11:04:54 -04005839
5840##
5841
5842# ------------------------------------------------------------------------------
5843
5844#Method void drawAtlas(const SkImage* atlas, const SkRSXform xform[], const SkRect tex[],
5845 const SkColor colors[], int count, SkBlendMode mode, const SkRect* cullRect,
5846 const SkPaint* paint)
Cary Clark78de7512018-02-07 07:27:09 -05005847#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05005848#Line # draws sprites using Clip, Matrix, and Paint ##
Cary Clark8032b982017-07-28 11:04:54 -04005849
5850Draw a set of sprites from atlas, using Clip, Matrix, and optional Paint paint.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005851paint uses Anti-alias, Color_Alpha, Color_Filter, Image_Filter, and Blend_Mode
5852to draw, if present. For each entry in the array, Rect tex locates sprite in
5853atlas, and RSXform xform transforms it into destination space.
5854
Cary Clark8032b982017-07-28 11:04:54 -04005855xform, text, and colors if present, must contain count entries.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005856Optional colors are applied for each sprite using Blend_Mode.
Herb Derbyefe39bc2018-05-01 17:06:20 -04005857Optional cullRect is a conservative bounds of all transformed sprites.
Cary Clarkce101242017-09-01 15:51:02 -04005858If cullRect is outside of Clip, canvas can skip drawing.
Cary Clark8032b982017-07-28 11:04:54 -04005859
Cary Clarkbad5ad72017-08-03 17:14:08 -04005860#Param atlas Image containing sprites ##
5861#Param xform RSXform mappings for sprites in atlas ##
5862#Param tex Rect locations of sprites in atlas ##
Cary Clark6fc50412017-09-21 12:31:06 -04005863#Param colors one per sprite, blended with sprite using Blend_Mode; may be nullptr ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005864#Param count number of sprites to draw ##
5865#Param mode Blend_Mode combining colors and sprites ##
Cary Clark6fc50412017-09-21 12:31:06 -04005866#Param cullRect bounds of transformed sprites for efficient clipping; may be nullptr ##
5867#Param paint Color_Filter, Image_Filter, Blend_Mode, and so on; may be nullptr ##
Cary Clark8032b982017-07-28 11:04:54 -04005868
5869#Example
5870#Image 3
Cary Clarkbad5ad72017-08-03 17:14:08 -04005871void draw(SkCanvas* canvas) {
5872 // SkBitmap source = mandrill;
5873 SkRSXform xforms[] = { { .5f, 0, 0, 0 }, {0, .5f, 200, 100 } };
5874 SkRect tex[] = { { 0, 0, 250, 250 }, { 0, 0, 250, 250 } };
5875 SkColor colors[] = { 0x7f55aa00, 0x7f3333bf };
5876 const SkImage* imagePtr = image.get();
5877 canvas->drawAtlas(imagePtr, xforms, tex, colors, 2, SkBlendMode::kSrcOver, nullptr, nullptr);
Cary Clark8032b982017-07-28 11:04:54 -04005878}
5879##
5880
Cary Clark2ade9972017-11-02 17:49:34 -04005881#SeeAlso drawBitmap drawImage
Cary Clark8032b982017-07-28 11:04:54 -04005882
5883##
5884
5885# ------------------------------------------------------------------------------
5886
5887#Method void drawAtlas(const sk_sp<SkImage>& atlas, const SkRSXform xform[], const SkRect tex[],
5888 const SkColor colors[], int count, SkBlendMode mode, const SkRect* cullRect,
Herb Derbyefe39bc2018-05-01 17:06:20 -04005889 const SkPaint* paint)
Cary Clark8032b982017-07-28 11:04:54 -04005890
5891Draw a set of sprites from atlas, using Clip, Matrix, and optional Paint paint.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005892paint uses Anti-alias, Color_Alpha, Color_Filter, Image_Filter, and Blend_Mode
5893to draw, if present. For each entry in the array, Rect tex locates sprite in
5894atlas, and RSXform xform transforms it into destination space.
5895
Cary Clark8032b982017-07-28 11:04:54 -04005896xform, text, and colors if present, must contain count entries.
5897Optional colors is applied for each sprite using Blend_Mode.
Herb Derbyefe39bc2018-05-01 17:06:20 -04005898Optional cullRect is a conservative bounds of all transformed sprites.
Cary Clarkce101242017-09-01 15:51:02 -04005899If cullRect is outside of Clip, canvas can skip drawing.
Cary Clark8032b982017-07-28 11:04:54 -04005900
Cary Clarkbad5ad72017-08-03 17:14:08 -04005901#Param atlas Image containing sprites ##
5902#Param xform RSXform mappings for sprites in atlas ##
5903#Param tex Rect locations of sprites in atlas ##
Cary Clark6fc50412017-09-21 12:31:06 -04005904#Param colors one per sprite, blended with sprite using Blend_Mode; may be nullptr ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005905#Param count number of sprites to draw ##
5906#Param mode Blend_Mode combining colors and sprites ##
Cary Clark6fc50412017-09-21 12:31:06 -04005907#Param cullRect bounds of transformed sprites for efficient clipping; may be nullptr ##
5908#Param paint Color_Filter, Image_Filter, Blend_Mode, and so on; may be nullptr ##
Cary Clark8032b982017-07-28 11:04:54 -04005909
5910#Example
5911#Image 3
Cary Clarkbad5ad72017-08-03 17:14:08 -04005912void draw(SkCanvas* canvas) {
5913 // SkBitmap source = mandrill;
5914 SkRSXform xforms[] = { { .5f, 0, 0, 0 }, {0, .5f, 200, 100 } };
5915 SkRect tex[] = { { 0, 0, 250, 250 }, { 0, 0, 250, 250 } };
5916 SkColor colors[] = { 0x7f55aa00, 0x7f3333bf };
5917 SkPaint paint;
5918 paint.setAlpha(127);
5919 canvas->drawAtlas(image, xforms, tex, colors, 2, SkBlendMode::kPlus, nullptr, &paint);
Cary Clark8032b982017-07-28 11:04:54 -04005920}
5921##
5922
5923#ToDo bug in example on cpu side, gpu looks ok ##
5924
Cary Clark2ade9972017-11-02 17:49:34 -04005925#SeeAlso drawBitmap drawImage
5926
Cary Clark8032b982017-07-28 11:04:54 -04005927##
5928
5929# ------------------------------------------------------------------------------
5930
5931#Method void drawAtlas(const SkImage* atlas, const SkRSXform xform[], const SkRect tex[], int count,
Herb Derbyefe39bc2018-05-01 17:06:20 -04005932 const SkRect* cullRect, const SkPaint* paint)
Cary Clark8032b982017-07-28 11:04:54 -04005933
5934Draw a set of sprites from atlas, using Clip, Matrix, and optional Paint paint.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005935paint uses Anti-alias, Color_Alpha, Color_Filter, Image_Filter, and Blend_Mode
5936to draw, if present. For each entry in the array, Rect tex locates sprite in
5937atlas, and RSXform xform transforms it into destination space.
5938
Cary Clark8032b982017-07-28 11:04:54 -04005939xform and text must contain count entries.
Herb Derbyefe39bc2018-05-01 17:06:20 -04005940Optional cullRect is a conservative bounds of all transformed sprites.
Cary Clarkce101242017-09-01 15:51:02 -04005941If cullRect is outside of Clip, canvas can skip drawing.
Cary Clark8032b982017-07-28 11:04:54 -04005942
Cary Clarkbad5ad72017-08-03 17:14:08 -04005943#Param atlas Image containing sprites ##
5944#Param xform RSXform mappings for sprites in atlas ##
5945#Param tex Rect locations of sprites in atlas ##
5946#Param count number of sprites to draw ##
Cary Clark6fc50412017-09-21 12:31:06 -04005947#Param cullRect bounds of transformed sprites for efficient clipping; may be nullptr ##
5948#Param paint Color_Filter, Image_Filter, Blend_Mode, and so on; may be nullptr ##
Cary Clark8032b982017-07-28 11:04:54 -04005949
5950#Example
5951#Image 3
Cary Clarkbad5ad72017-08-03 17:14:08 -04005952void draw(SkCanvas* canvas) {
5953 // sk_sp<SkImage> image = mandrill;
5954 SkRSXform xforms[] = { { .5f, 0, 0, 0 }, {0, .5f, 200, 100 } };
5955 SkRect tex[] = { { 0, 0, 250, 250 }, { 0, 0, 250, 250 } };
5956 const SkImage* imagePtr = image.get();
5957 canvas->drawAtlas(imagePtr, xforms, tex, 2, nullptr, nullptr);
Cary Clark8032b982017-07-28 11:04:54 -04005958}
5959##
5960
Cary Clark2ade9972017-11-02 17:49:34 -04005961#SeeAlso drawBitmap drawImage
Cary Clark8032b982017-07-28 11:04:54 -04005962
5963##
5964
5965# ------------------------------------------------------------------------------
5966
5967#Method void drawAtlas(const sk_sp<SkImage>& atlas, const SkRSXform xform[], const SkRect tex[],
Herb Derbyefe39bc2018-05-01 17:06:20 -04005968 int count, const SkRect* cullRect, const SkPaint* paint)
Cary Clark8032b982017-07-28 11:04:54 -04005969
5970Draw a set of sprites from atlas, using Clip, Matrix, and optional Paint paint.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005971paint uses Anti-alias, Color_Alpha, Color_Filter, Image_Filter, and Blend_Mode
5972to draw, if present. For each entry in the array, Rect tex locates sprite in
5973atlas, and RSXform xform transforms it into destination space.
5974
Cary Clark8032b982017-07-28 11:04:54 -04005975xform and text must contain count entries.
Herb Derbyefe39bc2018-05-01 17:06:20 -04005976Optional cullRect is a conservative bounds of all transformed sprites.
Cary Clarkce101242017-09-01 15:51:02 -04005977If cullRect is outside of Clip, canvas can skip drawing.
Cary Clark8032b982017-07-28 11:04:54 -04005978
Cary Clarkbad5ad72017-08-03 17:14:08 -04005979#Param atlas Image containing sprites ##
5980#Param xform RSXform mappings for sprites in atlas ##
5981#Param tex Rect locations of sprites in atlas ##
5982#Param count number of sprites to draw ##
Cary Clark6fc50412017-09-21 12:31:06 -04005983#Param cullRect bounds of transformed sprites for efficient clipping; may be nullptr ##
5984#Param paint Color_Filter, Image_Filter, Blend_Mode, and so on; may be nullptr ##
Cary Clark8032b982017-07-28 11:04:54 -04005985
5986#Example
5987#Image 3
Cary Clarkbad5ad72017-08-03 17:14:08 -04005988void draw(SkCanvas* canvas) {
5989 // sk_sp<SkImage> image = mandrill;
5990 SkRSXform xforms[] = { { 1, 0, 0, 0 }, {0, 1, 300, 100 } };
5991 SkRect tex[] = { { 0, 0, 200, 200 }, { 200, 0, 400, 200 } };
5992 canvas->drawAtlas(image, xforms, tex, 2, nullptr, nullptr);
Cary Clark8032b982017-07-28 11:04:54 -04005993}
5994##
5995
Cary Clark2ade9972017-11-02 17:49:34 -04005996#SeeAlso drawBitmap drawImage
Cary Clark8032b982017-07-28 11:04:54 -04005997
5998##
5999
6000# ------------------------------------------------------------------------------
6001
Cary Clark73fa9722017-08-29 17:36:51 -04006002#Method void drawDrawable(SkDrawable* drawable, const SkMatrix* matrix = nullptr)
Cary Clark78de7512018-02-07 07:27:09 -05006003#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05006004#Line # draws Drawable, encapsulated drawing commands ##
Herb Derbyefe39bc2018-05-01 17:06:20 -04006005Draw Drawable drawable using Clip and Matrix, concatenated with
Cary Clark8032b982017-07-28 11:04:54 -04006006optional matrix.
6007
Herb Derbyefe39bc2018-05-01 17:06:20 -04006008If Canvas has an asynchronous implementation, as is the case
Cary Clark8032b982017-07-28 11:04:54 -04006009when it is recording into Picture, then drawable will be referenced,
6010so that SkDrawable::draw() can be called when the operation is finalized. To force
6011immediate drawing, call SkDrawable::draw() instead.
6012
Cary Clarkbad5ad72017-08-03 17:14:08 -04006013#Param drawable custom struct encapsulating drawing commands ##
6014#Param matrix transformation applied to drawing; may be nullptr ##
Cary Clark8032b982017-07-28 11:04:54 -04006015
6016#Example
6017#Height 100
6018#Function
Cary Clarkbad5ad72017-08-03 17:14:08 -04006019struct MyDrawable : public SkDrawable {
6020 SkRect onGetBounds() override { return SkRect::MakeWH(50, 100); }
6021
6022 void onDraw(SkCanvas* canvas) override {
6023 SkPath path;
6024 path.conicTo(10, 90, 50, 90, 0.9f);
6025 SkPaint paint;
6026 paint.setColor(SK_ColorBLUE);
6027 canvas->drawRect(path.getBounds(), paint);
6028 paint.setAntiAlias(true);
6029 paint.setColor(SK_ColorWHITE);
6030 canvas->drawPath(path, paint);
6031 }
6032};
6033
6034#Function ##
6035void draw(SkCanvas* canvas) {
6036 sk_sp<SkDrawable> drawable(new MyDrawable);
6037 SkMatrix matrix;
6038 matrix.setTranslate(10, 10);
6039 canvas->drawDrawable(drawable.get(), &matrix);
Cary Clark8032b982017-07-28 11:04:54 -04006040}
6041##
6042
Cary Clark2ade9972017-11-02 17:49:34 -04006043#SeeAlso SkDrawable drawPicture
Cary Clark8032b982017-07-28 11:04:54 -04006044
6045##
6046
6047# ------------------------------------------------------------------------------
6048
6049#Method void drawDrawable(SkDrawable* drawable, SkScalar x, SkScalar y)
6050
6051Draw Drawable drawable using Clip and Matrix, offset by (x, y).
6052
Herb Derbyefe39bc2018-05-01 17:06:20 -04006053If Canvas has an asynchronous implementation, as is the case
Cary Clark8032b982017-07-28 11:04:54 -04006054when it is recording into Picture, then drawable will be referenced,
6055so that SkDrawable::draw() can be called when the operation is finalized. To force
6056immediate drawing, call SkDrawable::draw() instead.
6057
Cary Clarkbad5ad72017-08-03 17:14:08 -04006058#Param drawable custom struct encapsulating drawing commands ##
6059#Param x offset into Canvas writable pixels in x ##
6060#Param y offset into Canvas writable pixels in y ##
Cary Clark8032b982017-07-28 11:04:54 -04006061
6062#Example
6063#Height 100
6064#Function
Cary Clarkbad5ad72017-08-03 17:14:08 -04006065struct MyDrawable : public SkDrawable {
6066 SkRect onGetBounds() override { return SkRect::MakeWH(50, 100); }
6067
6068 void onDraw(SkCanvas* canvas) override {
6069 SkPath path;
6070 path.conicTo(10, 90, 50, 90, 0.9f);
6071 SkPaint paint;
6072 paint.setColor(SK_ColorBLUE);
6073 canvas->drawRect(path.getBounds(), paint);
6074 paint.setAntiAlias(true);
6075 paint.setColor(SK_ColorWHITE);
6076 canvas->drawPath(path, paint);
6077 }
6078};
6079
6080#Function ##
6081void draw(SkCanvas* canvas) {
6082 sk_sp<SkDrawable> drawable(new MyDrawable);
6083 canvas->drawDrawable(drawable.get(), 10, 10);
Cary Clark8032b982017-07-28 11:04:54 -04006084}
6085##
6086
Cary Clark2ade9972017-11-02 17:49:34 -04006087#SeeAlso SkDrawable drawPicture
Cary Clark8032b982017-07-28 11:04:54 -04006088
6089##
6090
6091# ------------------------------------------------------------------------------
6092
6093#Method void drawAnnotation(const SkRect& rect, const char key[], SkData* value)
Cary Clark78de7512018-02-07 07:27:09 -05006094#In Draw
6095#In Utility
Cary Clarkab2621d2018-01-30 10:08:57 -05006096#Line # associates a Rect with a key-value pair ##
Cary Clark78de7512018-02-07 07:27:09 -05006097Associate Rect on Canvas with an annotation; a key-value pair, where the key is
Cary Clark8032b982017-07-28 11:04:54 -04006098a null-terminated utf8 string, and optional value is stored as Data.
6099
Herb Derbyefe39bc2018-05-01 17:06:20 -04006100Only some canvas implementations, such as recording to Picture, or drawing to
Cary Clark8032b982017-07-28 11:04:54 -04006101Document_PDF, use annotations.
6102
Cary Clarkbad5ad72017-08-03 17:14:08 -04006103#Param rect Rect extent of canvas to annotate ##
6104#Param key string used for lookup ##
6105#Param value data holding value stored in annotation ##
Cary Clark8032b982017-07-28 11:04:54 -04006106
6107#Example
6108 #Height 1
6109 const char text[] = "Click this link!";
6110 SkRect bounds;
6111 SkPaint paint;
6112 paint.setTextSize(40);
6113 (void)paint.measureText(text, strlen(text), &bounds);
6114 const char url[] = "https://www.google.com/";
6115 sk_sp<SkData> urlData(SkData::MakeWithCString(url));
6116 canvas->drawAnnotation(bounds, "url_key", urlData.get());
6117##
6118
Cary Clark2ade9972017-11-02 17:49:34 -04006119#SeeAlso SkPicture SkDocument
Cary Clark8032b982017-07-28 11:04:54 -04006120
6121##
6122
6123# ------------------------------------------------------------------------------
6124
Herb Derbyefe39bc2018-05-01 17:06:20 -04006125#Method void drawAnnotation(const SkRect& rect, const char key[], const sk_sp<SkData>& value)
Cary Clark8032b982017-07-28 11:04:54 -04006126
6127Associate Rect on Canvas when an annotation; a key-value pair, where the key is
6128a null-terminated utf8 string, and optional value is stored as Data.
6129
Herb Derbyefe39bc2018-05-01 17:06:20 -04006130Only some canvas implementations, such as recording to Picture, or drawing to
Cary Clark8032b982017-07-28 11:04:54 -04006131Document_PDF, use annotations.
6132
Cary Clarkbad5ad72017-08-03 17:14:08 -04006133#Param rect Rect extent of canvas to annotate ##
6134#Param key string used for lookup ##
6135#Param value data holding value stored in annotation ##
Cary Clark8032b982017-07-28 11:04:54 -04006136
6137#Example
6138#Height 1
6139 const char text[] = "Click this link!";
6140 SkRect bounds;
6141 SkPaint paint;
6142 paint.setTextSize(40);
6143 (void)paint.measureText(text, strlen(text), &bounds);
6144 const char url[] = "https://www.google.com/";
6145 sk_sp<SkData> urlData(SkData::MakeWithCString(url));
6146 canvas->drawAnnotation(bounds, "url_key", urlData.get());
6147##
6148
Cary Clark2ade9972017-11-02 17:49:34 -04006149#SeeAlso SkPicture SkDocument
Cary Clark8032b982017-07-28 11:04:54 -04006150
6151##
6152
6153#Method SkDrawFilter* getDrawFilter() const
Cary Clark4855f782018-02-06 09:41:53 -05006154#Deprecated soon
Cary Clark8032b982017-07-28 11:04:54 -04006155##
6156
6157#Method virtual SkDrawFilter* setDrawFilter(SkDrawFilter* filter)
Cary Clark4855f782018-02-06 09:41:53 -05006158#Deprecated soon
Cary Clark8032b982017-07-28 11:04:54 -04006159##
6160
6161# ------------------------------------------------------------------------------
6162
6163#Method virtual bool isClipEmpty() const
Cary Clark78de7512018-02-07 07:27:09 -05006164#In Property
Cary Clarkab2621d2018-01-30 10:08:57 -05006165#Line # returns if Clip is empty ##
Cary Clark8032b982017-07-28 11:04:54 -04006166Returns true if Clip is empty; that is, nothing will draw.
6167
Cary Clarkbad5ad72017-08-03 17:14:08 -04006168May do work when called; it should not be called
Cary Clark8032b982017-07-28 11:04:54 -04006169more often than needed. However, once called, subsequent calls perform no
6170work until Clip changes.
6171
Cary Clarkbad5ad72017-08-03 17:14:08 -04006172#Return true if Clip is empty ##
Cary Clark8032b982017-07-28 11:04:54 -04006173
6174#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04006175 void draw(SkCanvas* canvas) {
6176 SkDebugf("clip is%s empty\n", canvas->isClipEmpty() ? "" : " not");
6177 SkPath path;
6178 canvas->clipPath(path);
6179 SkDebugf("clip is%s empty\n", canvas->isClipEmpty() ? "" : " not");
Cary Clark8032b982017-07-28 11:04:54 -04006180 }
6181 #StdOut
Cary Clarkbad5ad72017-08-03 17:14:08 -04006182 clip is not empty
Cary Clark8032b982017-07-28 11:04:54 -04006183 clip is empty
6184 ##
6185##
6186
Cary Clark2ade9972017-11-02 17:49:34 -04006187#SeeAlso isClipRect getLocalClipBounds getDeviceClipBounds
Cary Clark8032b982017-07-28 11:04:54 -04006188
6189##
6190
6191# ------------------------------------------------------------------------------
6192
6193#Method virtual bool isClipRect() const
Cary Clark78de7512018-02-07 07:27:09 -05006194#In Property
Cary Clarkab2621d2018-01-30 10:08:57 -05006195#Line # returns if Clip is Rect and not empty ##
Cary Clark8032b982017-07-28 11:04:54 -04006196Returns true if Clip is Rect and not empty.
6197Returns false if the clip is empty, or if it is not Rect.
6198
Cary Clarkbad5ad72017-08-03 17:14:08 -04006199#Return true if Clip is Rect and not empty ##
Cary Clark8032b982017-07-28 11:04:54 -04006200
6201#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04006202 void draw(SkCanvas* canvas) {
6203 SkDebugf("clip is%s rect\n", canvas->isClipRect() ? "" : " not");
6204 canvas->clipRect({0, 0, 0, 0});
6205 SkDebugf("clip is%s rect\n", canvas->isClipRect() ? "" : " not");
Cary Clark8032b982017-07-28 11:04:54 -04006206 }
6207 #StdOut
Cary Clarkbad5ad72017-08-03 17:14:08 -04006208 clip is rect
Cary Clark8032b982017-07-28 11:04:54 -04006209 clip is not rect
6210 ##
6211##
6212
Cary Clark2ade9972017-11-02 17:49:34 -04006213#SeeAlso isClipEmpty getLocalClipBounds getDeviceClipBounds
Cary Clark8032b982017-07-28 11:04:54 -04006214
6215##
6216
6217#Class SkCanvas ##
Cary Clark884dd7d2017-10-11 10:37:52 -04006218
Cary Clark8032b982017-07-28 11:04:54 -04006219#Topic Canvas ##