blob: 2225b205deb2d64b2cfc2bbff5cf8f8988392720 [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
5 #Subtopic Subtopics
6 #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
21To 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.
24Canvas 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.
31This approach may be deprecated in the future.
32
Cary Clark08895c42018-02-01 09:37:32 -050033#Subtopic Related_Functions
34#Populate
35##
Cary Clark8032b982017-07-28 11:04:54 -040036
37#Subtopic Constants
Cary Clark08895c42018-02-01 09:37:32 -050038#Populate
39##
Cary Clark8032b982017-07-28 11:04:54 -040040
Cary Clark5081eed2018-01-22 07:55:48 -050041#Subtopic Classes_and_Structs
Cary Clark08895c42018-02-01 09:37:32 -050042#Populate
43##
Cary Clark8032b982017-07-28 11:04:54 -040044
45#Subtopic Constructors
46
47Create the desired type of Surface to obtain its Canvas when possible. Constructors are useful
48when 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
53#Subtopic Member_Functions
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 Clarkab2621d2018-01-30 10:08:57 -050062#Line # creates from SkImageInfo and Pixel_Storage ##
Cary Clark8032b982017-07-28 11:04:54 -040063
Cary Clarkbad5ad72017-08-03 17:14:08 -040064Allocates raster Canvas that will draw directly into pixels.
Cary Clark8032b982017-07-28 11:04:54 -040065
Cary Clarkbad5ad72017-08-03 17:14:08 -040066Canvas is returned if all parameters are valid.
67Valid parameters include:
68info dimensions are zero or positive;
Cary Clark2dc84ad2018-01-26 12:56:22 -050069info contains Color_Type and Alpha_Type supported by Raster_Surface;
Cary Clarkbad5ad72017-08-03 17:14:08 -040070pixels is not nullptr;
Cary Clark2dc84ad2018-01-26 12:56:22 -050071rowBytes is zero or large enough to contain info width pixels of Color_Type.
Cary Clarkbad5ad72017-08-03 17:14:08 -040072
Cary Clarkf05bdda2017-08-24 12:59:48 -040073Pass zero for rowBytes to compute rowBytes from info width and size of pixel.
74If rowBytes is greater than zero, it must be equal to or greater than
Cary Clark2dc84ad2018-01-26 12:56:22 -050075info width times bytes required for Color_Type.
Cary Clarkf05bdda2017-08-24 12:59:48 -040076
77Pixel buffer size should be info height times computed rowBytes.
Cary Clarka560c472017-11-27 10:44:06 -050078Pixels are not initialized.
79To access pixels after drawing, call flush() or peekPixels.
Cary Clarkbad5ad72017-08-03 17:14:08 -040080
Cary Clark2dc84ad2018-01-26 12:56:22 -050081#Param info width, height, Color_Type, Alpha_Type, Color_Space, of Raster_Surface;
Cary Clarkbad5ad72017-08-03 17:14:08 -040082 width, or height, or both, may be zero
Cary Clark8032b982017-07-28 11:04:54 -040083##
Cary Clarkf05bdda2017-08-24 12:59:48 -040084#Param pixels pointer to destination pixels buffer
Cary Clark8032b982017-07-28 11:04:54 -040085##
Cary Clarkf05bdda2017-08-24 12:59:48 -040086#Param rowBytes interval from one Surface row to the next, or zero
Cary Clark8032b982017-07-28 11:04:54 -040087##
Cary Clarka560c472017-11-27 10:44:06 -050088#Param props LCD striping orientation and setting for device independent fonts;
89 may be nullptr
90##
Cary Clark8032b982017-07-28 11:04:54 -040091
Cary Clarkbad5ad72017-08-03 17:14:08 -040092#Return Canvas if all parameters are valid; otherwise, nullptr ##
Cary Clark8032b982017-07-28 11:04:54 -040093
94#Example
95 #Description
96 Allocates a three by three bitmap, clears it to white, and draws a black pixel
97 in the center.
98 ##
Cary Clarkbad5ad72017-08-03 17:14:08 -040099void draw(SkCanvas* ) {
Cary Clarkce101242017-09-01 15:51:02 -0400100 SkImageInfo info = SkImageInfo::MakeN32Premul(3, 3); // device aligned, 32 bpp, Premultiplied
Cary Clarkbad5ad72017-08-03 17:14:08 -0400101 const size_t minRowBytes = info.minRowBytes(); // bytes used by one bitmap row
Cary Clarka560c472017-11-27 10:44:06 -0500102 const size_t size = info.computeMinByteSize(); // bytes used by all rows
Cary Clarkbad5ad72017-08-03 17:14:08 -0400103 SkAutoTMalloc<SkPMColor> storage(size); // allocate storage for pixels
104 SkPMColor* pixels = storage.get(); // get pointer to allocated storage
105 // create a SkCanvas backed by a raster device, and delete it when the
106 // function goes out of scope.
107 std::unique_ptr<SkCanvas> canvas = SkCanvas::MakeRasterDirect(info, pixels, minRowBytes);
Cary Clarkce101242017-09-01 15:51:02 -0400108 canvas->clear(SK_ColorWHITE); // white is Unpremultiplied, in ARGB order
Cary Clarkbad5ad72017-08-03 17:14:08 -0400109 canvas->flush(); // ensure that pixels are cleared
Cary Clarkce101242017-09-01 15:51:02 -0400110 SkPMColor pmWhite = pixels[0]; // the Premultiplied format may vary
Cary Clarkbad5ad72017-08-03 17:14:08 -0400111 SkPaint paint; // by default, draws black
112 canvas->drawPoint(1, 1, paint); // draw in the center
113 canvas->flush(); // ensure that point was drawn
114 for (int y = 0; y < info.height(); ++y) {
115 for (int x = 0; x < info.width(); ++x) {
116 SkDebugf("%c", *pixels++ == pmWhite ? '-' : 'x');
117 }
118 SkDebugf("\n");
119 }
Cary Clark8032b982017-07-28 11:04:54 -0400120}
121 #StdOut
122 ---
123 -x-
124 ---
125 ##
126##
127
Cary Clark8032b982017-07-28 11:04:54 -0400128#SeeAlso MakeRasterDirectN32 SkSurface::MakeRasterDirect
Cary Clark2ade9972017-11-02 17:49:34 -0400129
Cary Clark8032b982017-07-28 11:04:54 -0400130##
131
132# ------------------------------------------------------------------------------
133
134#Method static std::unique_ptr<SkCanvas> MakeRasterDirectN32(int width, int height, SkPMColor* pixels,
135 size_t rowBytes)
Cary Clarkab2621d2018-01-30 10:08:57 -0500136#Line # creates from image data and Pixel_Storage ##
Cary Clark8032b982017-07-28 11:04:54 -0400137
Cary Clarkbad5ad72017-08-03 17:14:08 -0400138Allocates raster Canvas specified by inline image specification. Subsequent Canvas
139calls draw into pixels.
Cary Clark2dc84ad2018-01-26 12:56:22 -0500140Color_Type is set to kN32_SkColorType.
141Alpha_Type is set to kPremul_SkAlphaType.
Cary Clark8032b982017-07-28 11:04:54 -0400142To access pixels after drawing, call flush() or peekPixels.
143
Cary Clarkbad5ad72017-08-03 17:14:08 -0400144Canvas is returned if all parameters are valid.
145Valid parameters include:
Cary Clarkf05bdda2017-08-24 12:59:48 -0400146width and height are zero or positive;
Cary Clarkbad5ad72017-08-03 17:14:08 -0400147pixels is not nullptr;
Cary Clarkf05bdda2017-08-24 12:59:48 -0400148rowBytes is zero or large enough to contain width pixels of kN32_SkColorType.
Cary Clarkbad5ad72017-08-03 17:14:08 -0400149
Cary Clarkce101242017-09-01 15:51:02 -0400150Pass zero for rowBytes to compute rowBytes from width and size of pixel.
Cary Clarkf05bdda2017-08-24 12:59:48 -0400151If rowBytes is greater than zero, it must be equal to or greater than
Cary Clark2dc84ad2018-01-26 12:56:22 -0500152width times bytes required for Color_Type.
Cary Clarkf05bdda2017-08-24 12:59:48 -0400153
154Pixel buffer size should be height times rowBytes.
Cary Clarkbad5ad72017-08-03 17:14:08 -0400155
156#Param width pixel column count on Raster_Surface created; must be zero or greater ##
Cary Clarkbc5697d2017-10-04 14:31:33 -0400157#Param height pixel row count on Raster_Surface created; must be zero or greater ##
Cary Clarkbad5ad72017-08-03 17:14:08 -0400158#Param pixels pointer to destination pixels buffer; buffer size should be height
Cary Clarkf05bdda2017-08-24 12:59:48 -0400159 times rowBytes
Cary Clark8032b982017-07-28 11:04:54 -0400160##
Cary Clarkf05bdda2017-08-24 12:59:48 -0400161#Param rowBytes interval from one Surface row to the next, or zero
Cary Clark8032b982017-07-28 11:04:54 -0400162##
163
Cary Clarkbad5ad72017-08-03 17:14:08 -0400164#Return Canvas if all parameters are valid; otherwise, nullptr ##
Cary Clark8032b982017-07-28 11:04:54 -0400165
166#Example
167 #Description
168 Allocates a three by three bitmap, clears it to white, and draws a black pixel
169 in the center.
170 ##
171void draw(SkCanvas* ) {
172 const int width = 3;
173 const int height = 3;
Cary Clarkce101242017-09-01 15:51:02 -0400174 SkPMColor pixels[height][width]; // allocate a 3x3 Premultiplied bitmap on the stack
Cary Clark8032b982017-07-28 11:04:54 -0400175 // create a SkCanvas backed by a raster device, and delete it when the
176 // function goes out of scope.
177 std::unique_ptr<SkCanvas> canvas = SkCanvas::MakeRasterDirectN32(
178 width,
179 height,
Cary Clarkbc5697d2017-10-04 14:31:33 -0400180 pixels[0], // top-left of the bitmap
Cary Clark8032b982017-07-28 11:04:54 -0400181 sizeof(pixels[0])); // byte width of the each row
Cary Clarkce101242017-09-01 15:51:02 -0400182 // write a premultiplied value for white into all pixels in the bitmap
Cary Clark8032b982017-07-28 11:04:54 -0400183 canvas->clear(SK_ColorWHITE);
Cary Clarkce101242017-09-01 15:51:02 -0400184 SkPMColor pmWhite = pixels[0][0]; // the Premultiplied format may vary
Cary Clark8032b982017-07-28 11:04:54 -0400185 SkPaint paint; // by default, draws black
186 canvas->drawPoint(1, 1, paint); // draw in the center
187 canvas->flush(); // ensure that pixels is ready to be read
188 for (int y = 0; y < height; ++y) {
189 for (int x = 0; x < width; ++x) {
190 SkDebugf("%c", pixels[y][x] == pmWhite ? '-' : 'x');
191 }
192 SkDebugf("\n");
193 }
194}
195 #StdOut
196 ---
197 -x-
198 ---
199 ##
200##
201
Cary Clark2ade9972017-11-02 17:49:34 -0400202#SeeAlso MakeRasterDirect SkSurface::MakeRasterDirect SkImageInfo::MakeN32Premul
Cary Clark8032b982017-07-28 11:04:54 -0400203
204##
205
206# ------------------------------------------------------------------------------
207
208#Method SkCanvas()
209
Cary Clarkab2621d2018-01-30 10:08:57 -0500210#Line # creates with no Surface, no dimensions ##
Cary Clarkd0530ba2017-09-14 11:25:39 -0400211Creates an empty Canvas with no backing device or pixels, with
Cary Clarkf05bdda2017-08-24 12:59:48 -0400212a width and height of zero.
Cary Clark8032b982017-07-28 11:04:54 -0400213
Cary Clarkd0530ba2017-09-14 11:25:39 -0400214#Return empty Canvas ##
Cary Clark8032b982017-07-28 11:04:54 -0400215
216#Example
217
218#Description
219Passes a placeholder to a function that requires one.
220##
221
222#Function
Cary Clarkbad5ad72017-08-03 17:14:08 -0400223// Returns true if either the canvas rotates the text by 90 degrees, or the paint does.
224static void check_for_up_and_down_text(const SkCanvas* canvas, const SkPaint& paint) {
225 bool paintHasVertical = paint.isVerticalText();
226 const SkMatrix& matrix = canvas->getTotalMatrix();
227 bool matrixIsVertical = matrix.preservesRightAngles() && !matrix.isScaleTranslate();
228 SkDebugf("paint draws text %s\n", paintHasVertical != matrixIsVertical ?
229 "top to bottom" : "left to right");
230}
231
232static void check_for_up_and_down_text(const SkPaint& paint) {
233 SkCanvas canvas; // placeholder only, does not have an associated device
234 check_for_up_and_down_text(&canvas, paint);
235}
236
Cary Clark8032b982017-07-28 11:04:54 -0400237##
Cary Clarkbad5ad72017-08-03 17:14:08 -0400238void draw(SkCanvas* canvas) {
239 SkPaint paint;
240 check_for_up_and_down_text(paint); // paint draws text left to right
241 paint.setVerticalText(true);
242 check_for_up_and_down_text(paint); // paint draws text top to bottom
243 paint.setVerticalText(false);
244 canvas->rotate(90);
245 check_for_up_and_down_text(canvas, paint); // paint draws text top to bottom
246}
Cary Clark8032b982017-07-28 11:04:54 -0400247
248 #StdOut
249 paint draws text left to right
250 paint draws text top to bottom
251 paint draws text top to bottom
252 ##
253##
254
Cary Clark2ade9972017-11-02 17:49:34 -0400255#SeeAlso MakeRasterDirect SkRasterHandleAllocator::MakeCanvas SkSurface::getCanvas SkCreateColorSpaceXformCanvas
Cary Clark8032b982017-07-28 11:04:54 -0400256
257##
258
259# ------------------------------------------------------------------------------
260
Cary Clark73fa9722017-08-29 17:36:51 -0400261#Method SkCanvas(int width, int height, const SkSurfaceProps* props = nullptr)
Cary Clark8032b982017-07-28 11:04:54 -0400262
Cary Clarkab2621d2018-01-30 10:08:57 -0500263#Line # no Surface, set dimensions, Surface_Properties ##
Cary Clark8032b982017-07-28 11:04:54 -0400264Creates Canvas of the specified dimensions without a Surface.
Cary Clarkce101242017-09-01 15:51:02 -0400265Used by Subclasses with custom implementations for draw methods.
Cary Clark8032b982017-07-28 11:04:54 -0400266
Cary Clarkd0530ba2017-09-14 11:25:39 -0400267If props equals nullptr, Surface_Properties are created with
268Surface_Properties_Legacy_Font_Host settings, which choose the pixel striping
269direction and order. Since a platform may dynamically change its direction when
270the device is rotated, and since a platform may have multiple monitors with
271different characteristics, it is best not to rely on this legacy behavior.
Cary Clark8032b982017-07-28 11:04:54 -0400272
Cary Clarkbad5ad72017-08-03 17:14:08 -0400273#Param width zero or greater ##
274#Param height zero or greater ##
275#Param props LCD striping orientation and setting for device independent fonts;
276 may be nullptr
277##
278
279#Return Canvas placeholder with dimensions ##
Cary Clark8032b982017-07-28 11:04:54 -0400280
281#Example
282 SkCanvas canvas(10, 20); // 10 units wide, 20 units high
283 canvas.clipRect(SkRect::MakeXYWH(30, 40, 5, 10)); // clip is outside canvas' device
284 SkDebugf("canvas %s empty\n", canvas.getDeviceClipBounds().isEmpty() ? "is" : "is not");
285
286 #StdOut
287 canvas is empty
288 ##
289##
290
Cary Clark2ade9972017-11-02 17:49:34 -0400291#SeeAlso MakeRasterDirect SkSurfaceProps SkPixelGeometry SkCreateColorSpaceXformCanvas
Cary Clark8032b982017-07-28 11:04:54 -0400292
293##
294
295# ------------------------------------------------------------------------------
296
297#Method explicit SkCanvas(SkBaseDevice* device)
298
Cary Clarkab2621d2018-01-30 10:08:57 -0500299#Line # to be deprecated ##
Cary Clark8032b982017-07-28 11:04:54 -0400300Construct a canvas that draws into device.
301Used by child classes of SkCanvas.
302
303#ToDo Since SkBaseDevice is private, shouldn't this be private also? ##
304
Cary Clarkbad5ad72017-08-03 17:14:08 -0400305#Param device specifies a device for the canvas to draw into ##
Cary Clark8032b982017-07-28 11:04:54 -0400306
Cary Clarkbad5ad72017-08-03 17:14:08 -0400307#Return Canvas that can be used to draw into device ##
Cary Clark8032b982017-07-28 11:04:54 -0400308
Cary Clark08895c42018-02-01 09:37:32 -0500309#ToDo unsure how to create a meaningful example ##
310#NoExample
Cary Clark8032b982017-07-28 11:04:54 -0400311##
312
Cary Clark2ade9972017-11-02 17:49:34 -0400313#ToDo either remove doc or figure out a way to fiddle it ##
314
315#SeeAlso MakeRasterDirect SkRasterHandleAllocator::MakeCanvas SkSurface::getCanvas SkCreateColorSpaceXformCanvas
Cary Clark8032b982017-07-28 11:04:54 -0400316
317##
318
319# ------------------------------------------------------------------------------
320
321#Method explicit SkCanvas(const SkBitmap& bitmap)
322
Cary Clarkab2621d2018-01-30 10:08:57 -0500323#Line # uses existing Bitmap ##
Cary Clark8032b982017-07-28 11:04:54 -0400324Construct a canvas that draws into bitmap.
325Sets SkSurfaceProps::kLegacyFontHost_InitType in constructed Surface.
326
Cary Clarkbad5ad72017-08-03 17:14:08 -0400327Bitmap is copied so that subsequently editing bitmap will not affect
328constructed Canvas.
329
330May be deprecated in the future.
331
Cary Clark8032b982017-07-28 11:04:54 -0400332#ToDo Should be deprecated? ##
333
Cary Clark2dc84ad2018-01-26 12:56:22 -0500334#Param bitmap width, height, Color_Type, Alpha_Type, and pixel
Cary Clarkbad5ad72017-08-03 17:14:08 -0400335 storage of Raster_Surface
Cary Clark8032b982017-07-28 11:04:54 -0400336##
337
Cary Clarkbad5ad72017-08-03 17:14:08 -0400338#Return Canvas that can be used to draw into bitmap ##
Cary Clark8032b982017-07-28 11:04:54 -0400339
340#Example
341#Description
342The actual output depends on the installed fonts.
343##
344 SkBitmap bitmap;
345 // create a bitmap 5 wide and 11 high
346 bitmap.allocPixels(SkImageInfo::MakeN32Premul(5, 11));
347 SkCanvas canvas(bitmap);
Cary Clarkce101242017-09-01 15:51:02 -0400348 canvas.clear(SK_ColorWHITE); // white is Unpremultiplied, in ARGB order
Cary Clark8032b982017-07-28 11:04:54 -0400349 SkPixmap pixmap; // provides guaranteed access to the drawn pixels
350 if (!canvas.peekPixels(&pixmap)) {
351 SkDebugf("peekPixels should never fail.\n");
352 }
Cary Clarkbc5697d2017-10-04 14:31:33 -0400353 const SkPMColor* pixels = pixmap.addr32(); // points to top-left of bitmap
Cary Clarkce101242017-09-01 15:51:02 -0400354 SkPMColor pmWhite = pixels[0]; // the Premultiplied format may vary
Cary Clark8032b982017-07-28 11:04:54 -0400355 SkPaint paint; // by default, draws black, 12 point text
356 canvas.drawString("!", 1, 10, paint); // 1 char at baseline (1, 10)
357 for (int y = 0; y < bitmap.height(); ++y) {
358 for (int x = 0; x < bitmap.width(); ++x) {
359 SkDebugf("%c", *pixels++ == pmWhite ? '-' : 'x');
360 }
361 SkDebugf("\n");
362 }
363
364 #StdOut
Cary Clarkd0530ba2017-09-14 11:25:39 -0400365 -----
366 ---x-
367 ---x-
368 ---x-
369 ---x-
370 ---x-
371 ---x-
372 -----
373 ---x-
374 ---x-
Cary Clark8032b982017-07-28 11:04:54 -0400375 -----
376 #StdOut ##
377##
378
Cary Clark2ade9972017-11-02 17:49:34 -0400379#SeeAlso MakeRasterDirect SkRasterHandleAllocator::MakeCanvas SkSurface::getCanvas SkCreateColorSpaceXformCanvas
Cary Clark8032b982017-07-28 11:04:54 -0400380
381##
382
Cary Clarkbad5ad72017-08-03 17:14:08 -0400383#EnumClass ColorBehavior
Cary Clark08895c42018-02-01 09:37:32 -0500384#Line # Android framework only ##
Cary Clark8032b982017-07-28 11:04:54 -0400385#Private
386Android framework only.
387##
388
389#Code
390 enum class ColorBehavior {
391 kLegacy,
392 };
393##
394#Const kLegacy 0
Cary Clarkbad5ad72017-08-03 17:14:08 -0400395 Is a placeholder to allow specialized constructor; has no meaning.
Cary Clark8032b982017-07-28 11:04:54 -0400396##
397##
398
Cary Clarkbad5ad72017-08-03 17:14:08 -0400399#Method SkCanvas(const SkBitmap& bitmap, ColorBehavior behavior)
400
Cary Clarkab2621d2018-01-30 10:08:57 -0500401#Line # Android framework only ##
Cary Clarkbad5ad72017-08-03 17:14:08 -0400402#Private
403Android framework only.
404##
405
406#Param bitmap specifies a bitmap for the canvas to draw into ##
407#Param behavior specializes this constructor; value is unused ##
408#Return Canvas that can be used to draw into bitmap ##
409
410#NoExample
411##
412##
Cary Clark8032b982017-07-28 11:04:54 -0400413
414# ------------------------------------------------------------------------------
415
416#Method SkCanvas(const SkBitmap& bitmap, const SkSurfaceProps& props)
417
Cary Clarkab2621d2018-01-30 10:08:57 -0500418#Line # uses existing Bitmap and Surface_Properties ##
Cary Clark8032b982017-07-28 11:04:54 -0400419Construct a canvas that draws into bitmap.
420Use props to match the device characteristics, like LCD striping.
421
Cary Clarkbad5ad72017-08-03 17:14:08 -0400422bitmap is copied so that subsequently editing bitmap will not affect
423constructed Canvas.
424
Cary Clark2dc84ad2018-01-26 12:56:22 -0500425#Param bitmap width, height, Color_Type, Alpha_Type,
Cary Clarkbad5ad72017-08-03 17:14:08 -0400426 and pixel storage of Raster_Surface
Cary Clark8032b982017-07-28 11:04:54 -0400427##
Cary Clarkbad5ad72017-08-03 17:14:08 -0400428#Param props order and orientation of RGB striping; and whether to use
429 device independent fonts
Cary Clark8032b982017-07-28 11:04:54 -0400430##
431
Cary Clarkbad5ad72017-08-03 17:14:08 -0400432#Return Canvas that can be used to draw into bitmap ##
Cary Clark8032b982017-07-28 11:04:54 -0400433
434#Example
435#Description
436The actual output depends on the installed fonts.
437##
438 SkBitmap bitmap;
439 // create a bitmap 5 wide and 11 high
440 bitmap.allocPixels(SkImageInfo::MakeN32Premul(5, 11));
441 SkCanvas canvas(bitmap, SkSurfaceProps(0, kUnknown_SkPixelGeometry));
Cary Clarkce101242017-09-01 15:51:02 -0400442 canvas.clear(SK_ColorWHITE); // white is Unpremultiplied, in ARGB order
Cary Clark8032b982017-07-28 11:04:54 -0400443 SkPixmap pixmap; // provides guaranteed access to the drawn pixels
444 if (!canvas.peekPixels(&pixmap)) {
445 SkDebugf("peekPixels should never fail.\n");
446 }
Cary Clarkbc5697d2017-10-04 14:31:33 -0400447 const SkPMColor* pixels = pixmap.addr32(); // points to top-left of bitmap
Cary Clarkce101242017-09-01 15:51:02 -0400448 SkPMColor pmWhite = pixels[0]; // the Premultiplied format may vary
Cary Clark8032b982017-07-28 11:04:54 -0400449 SkPaint paint; // by default, draws black, 12 point text
450 canvas.drawString("!", 1, 10, paint); // 1 char at baseline (1, 10)
451 for (int y = 0; y < bitmap.height(); ++y) {
452 for (int x = 0; x < bitmap.width(); ++x) {
453 SkDebugf("%c", *pixels++ == pmWhite ? '-' : 'x');
454 }
455 SkDebugf("\n");
456 }
457
458 #StdOut
459 -----
460 ---x-
461 ---x-
462 ---x-
463 ---x-
464 ---x-
465 ---x-
466 -----
467 ---x-
468 ---x-
469 -----
470 #StdOut ##
471##
472
Cary Clark2ade9972017-11-02 17:49:34 -0400473#SeeAlso MakeRasterDirect SkRasterHandleAllocator::MakeCanvas SkSurface::getCanvas SkCreateColorSpaceXformCanvas
Cary Clark8032b982017-07-28 11:04:54 -0400474
475##
476
477# ------------------------------------------------------------------------------
478
479#Method virtual ~SkCanvas()
480
Cary Clarkab2621d2018-01-30 10:08:57 -0500481#Line # draws saved Layers, frees resources ##
Cary Clark5081eed2018-01-22 07:55:48 -0500482Draws saved Layers, if any.
483Frees up resources used by Canvas.
Cary Clark8032b982017-07-28 11:04:54 -0400484
485#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -0400486#Description
Cary Clarkce101242017-09-01 15:51:02 -0400487Canvas Layer draws into bitmap. saveLayerAlpha sets up an additional
488drawing surface that blends with the bitmap. When Layer goes out of
489scope, Layer Destructor is called. The saved Layer is restored, drawing
Cary Clarkbad5ad72017-08-03 17:14:08 -0400490transparent letters.
491##
Cary Clarkf05bdda2017-08-24 12:59:48 -0400492void draw(SkCanvas* canvas) {
493 SkBitmap bitmap;
494 bitmap.allocPixels(SkImageInfo::MakeN32Premul(200, 200));
495 {
496 SkCanvas offscreen(bitmap);
497 SkPaint paint;
498 paint.setTextSize(100);
499 offscreen.drawString("ABC", 20, 160, paint);
500 SkRect layerBounds = SkRect::MakeXYWH(32, 32, 192, 192);
501 offscreen.saveLayerAlpha(&layerBounds, 128);
502 offscreen.clear(SK_ColorWHITE);
503 offscreen.drawString("DEF", 20, 160, paint);
504 }
505 canvas->drawBitmap(bitmap, 0, 0, nullptr);
Cary Clarkbad5ad72017-08-03 17:14:08 -0400506}
Cary Clark8032b982017-07-28 11:04:54 -0400507##
508
Cary Clarkbad5ad72017-08-03 17:14:08 -0400509#SeeAlso State_Stack
Cary Clark8032b982017-07-28 11:04:54 -0400510
511##
512
513# ------------------------------------------------------------------------------
514
515#Method SkMetaData& getMetaData()
516
Cary Clarkab2621d2018-01-30 10:08:57 -0500517#Line # associates additional data with the canvas ##
Cary Clarkf05bdda2017-08-24 12:59:48 -0400518Returns storage to associate additional data with the canvas.
Cary Clark8032b982017-07-28 11:04:54 -0400519The storage is freed when Canvas is deleted.
520
Cary Clarkbad5ad72017-08-03 17:14:08 -0400521#Return storage that can be read from and written to ##
Cary Clark8032b982017-07-28 11:04:54 -0400522
523#Example
524 const char* kHelloMetaData = "HelloMetaData";
525 SkCanvas canvas;
526 SkMetaData& metaData = canvas.getMetaData();
527 SkDebugf("before: %s\n", metaData.findString(kHelloMetaData));
528 metaData.setString(kHelloMetaData, "Hello!");
529 SkDebugf("during: %s\n", metaData.findString(kHelloMetaData));
530 metaData.removeString(kHelloMetaData);
531 SkDebugf("after: %s\n", metaData.findString(kHelloMetaData));
532
533 #StdOut
534 before: (null)
535 during: Hello!
536 after: (null)
537 #StdOut ##
538##
539
Cary Clark2ade9972017-11-02 17:49:34 -0400540#SeeAlso SkMetaData
Cary Clark8032b982017-07-28 11:04:54 -0400541
542##
543
544# ------------------------------------------------------------------------------
545
546#Method SkImageInfo imageInfo() const
547
Cary Clarkab2621d2018-01-30 10:08:57 -0500548#Line # returns Image_Info for Canvas ##
Cary Clark8032b982017-07-28 11:04:54 -0400549Returns Image_Info for Canvas. If Canvas is not associated with Raster_Surface or
Cary Clark2dc84ad2018-01-26 12:56:22 -0500550GPU_Surface, returned Color_Type is set to kUnknown_SkColorType.
Cary Clark8032b982017-07-28 11:04:54 -0400551
Cary Clark2dc84ad2018-01-26 12:56:22 -0500552#Return dimensions and Color_Type of Canvas ##
Cary Clark8032b982017-07-28 11:04:54 -0400553
554#Example
Cary Clarkf05bdda2017-08-24 12:59:48 -0400555 SkCanvas emptyCanvas;
556 SkImageInfo canvasInfo = emptyCanvas.imageInfo();
557 SkImageInfo emptyInfo;
558 SkDebugf("emptyInfo %c= canvasInfo\n", emptyInfo == canvasInfo ? '=' : '!');
559
560 #StdOut
561 emptyInfo == canvasInfo
562 ##
Cary Clark8032b982017-07-28 11:04:54 -0400563##
564
Cary Clark2ade9972017-11-02 17:49:34 -0400565#SeeAlso SkImageInfo MakeRasterDirect makeSurface
Cary Clark8032b982017-07-28 11:04:54 -0400566
567##
568
569# ------------------------------------------------------------------------------
570
571#Method bool getProps(SkSurfaceProps* props) const
572
Cary Clarkab2621d2018-01-30 10:08:57 -0500573#Line # copies Surface_Properties if available ##
Cary Clark8032b982017-07-28 11:04:54 -0400574If Canvas is associated with Raster_Surface or
575GPU_Surface, copies Surface_Properties and returns true. Otherwise,
576return false and leave props unchanged.
577
Cary Clarkbad5ad72017-08-03 17:14:08 -0400578#Param props storage for writable SkSurfaceProps ##
Cary Clark8032b982017-07-28 11:04:54 -0400579
Cary Clarkbad5ad72017-08-03 17:14:08 -0400580#Return true if Surface_Properties was copied ##
Cary Clark8032b982017-07-28 11:04:54 -0400581
582#ToDo This seems old style. Deprecate? ##
583
584#Example
585 SkBitmap bitmap;
586 SkCanvas canvas(bitmap, SkSurfaceProps(0, kRGB_V_SkPixelGeometry));
587 SkSurfaceProps surfaceProps(0, kUnknown_SkPixelGeometry);
588 SkDebugf("isRGB:%d\n", SkPixelGeometryIsRGB(surfaceProps.pixelGeometry()));
589 if (!canvas.getProps(&surfaceProps)) {
590 SkDebugf("getProps failed unexpectedly.\n");
591 }
592 SkDebugf("isRGB:%d\n", SkPixelGeometryIsRGB(surfaceProps.pixelGeometry()));
593
594 #StdOut
595 isRGB:0
596 isRGB:1
597 #StdOut ##
598##
599
Cary Clark2ade9972017-11-02 17:49:34 -0400600#SeeAlso SkSurfaceProps makeSurface
Cary Clark8032b982017-07-28 11:04:54 -0400601
602##
603
604# ------------------------------------------------------------------------------
605
606#Method void flush()
607
Cary Clarkab2621d2018-01-30 10:08:57 -0500608#Line # triggers execution of all pending draw operations ##
Cary Clark8032b982017-07-28 11:04:54 -0400609Triggers the immediate execution of all pending draw operations.
Cary Clarkbad5ad72017-08-03 17:14:08 -0400610If Canvas is associated with GPU_Surface, resolves all pending GPU operations.
Cary Clark2ade9972017-11-02 17:49:34 -0400611If Canvas is associated with Raster_Surface, has no effect; raster draw
612operations are never deferred.
613
614#ToDo
615In an overview section on managing the GPU, include:
616- flush should never change what is drawn
617- call to kick off gpu work
618- calling too much impacts performance
619- some calls (peekPixels, prepareForExternalIO) call it internally
620- canvas call is local, GrContext::flush is global
621- diffentiate between flush, flushAndSignalSemaphores
622- normally never needs to be called
623- call it when sharing gpu resources, feeling memory pressure, swapping out app, and before
624 abandoning context
625- also call to say "I'm finished drawing here", e.g., when drawing to a GPU-backed offscreen surface
626 (created with SkSurface::MakeRenderTarget)
627
628for posterity: this doesn't show a difference: fiddle.skia.org/c/@flushfail
629##
Cary Clark8032b982017-07-28 11:04:54 -0400630
Cary Clark08895c42018-02-01 09:37:32 -0500631#ToDo haven't thought of a useful example to put here ##
632#NoExample
Cary Clark8032b982017-07-28 11:04:54 -0400633##
634
Cary Clark2ade9972017-11-02 17:49:34 -0400635#SeeAlso peekPixels SkSurface::flush() GrContext::flush() SkSurface::prepareForExternalIO GrContext::abandonContext()
Cary Clark8032b982017-07-28 11:04:54 -0400636
637##
638
639# ------------------------------------------------------------------------------
640
641#Method virtual SkISize getBaseLayerSize() const
642
Cary Clarkab2621d2018-01-30 10:08:57 -0500643#Line # returns size of base Layer in global coordinates ##
Cary Clarkce101242017-09-01 15:51:02 -0400644Gets the size of the base or root Layer in global canvas coordinates. The
645origin of the base Layer is always (0,0). The area available for drawing may be
Cary Clark8032b982017-07-28 11:04:54 -0400646smaller (due to clipping or saveLayer).
647
Cary Clarkce101242017-09-01 15:51:02 -0400648#Return integral width and height of base Layer ##
Cary Clark8032b982017-07-28 11:04:54 -0400649
650#Example
651 SkBitmap bitmap;
652 bitmap.allocPixels(SkImageInfo::MakeN32Premul(20, 30));
653 SkCanvas canvas(bitmap, SkSurfaceProps(0, kUnknown_SkPixelGeometry));
654 canvas.clipRect(SkRect::MakeWH(10, 40));
655 SkIRect clipDeviceBounds = canvas.getDeviceClipBounds();
656 if (clipDeviceBounds.isEmpty()) {
657 SkDebugf("Empty clip bounds is unexpected!\n");
658 }
659 SkDebugf("clip=%d,%d\n", clipDeviceBounds.width(), clipDeviceBounds.height());
660 SkISize baseLayerSize = canvas.getBaseLayerSize();
661 SkDebugf("size=%d,%d\n", baseLayerSize.width(), baseLayerSize.height());
662
663 #StdOut
664 clip=10,30
665 size=20,30
666 ##
667##
668
669#ToDo is this the same as the width and height of surface? ##
670
Cary Clark2ade9972017-11-02 17:49:34 -0400671#SeeAlso getDeviceClipBounds
672
Cary Clark8032b982017-07-28 11:04:54 -0400673##
674
675# ------------------------------------------------------------------------------
676
677#Method sk_sp<SkSurface> makeSurface(const SkImageInfo& info, const SkSurfaceProps* props = nullptr)
678
Cary Clarkab2621d2018-01-30 10:08:57 -0500679#Line # creates Surface matching SkImageInfo and SkSurfaceProps ##
Cary Clark8032b982017-07-28 11:04:54 -0400680Creates Surface matching info and props, and associates it with Canvas.
Cary Clarkbad5ad72017-08-03 17:14:08 -0400681Returns nullptr if no match found.
Cary Clark8032b982017-07-28 11:04:54 -0400682
Cary Clarkbad5ad72017-08-03 17:14:08 -0400683If props is nullptr, matches Surface_Properties in Canvas. If props is nullptr and Canvas
684does not have Surface_Properties, creates Surface with default Surface_Properties.
Cary Clark8032b982017-07-28 11:04:54 -0400685
Cary Clark2dc84ad2018-01-26 12:56:22 -0500686#Param info width, height, Color_Type, Alpha_Type, and Color_Space ##
Cary Clarkbad5ad72017-08-03 17:14:08 -0400687#Param props Surface_Properties to match; may be nullptr to match Canvas ##
688
689#Return Surface matching info and props, or nullptr if no match is available ##
Cary Clark8032b982017-07-28 11:04:54 -0400690
691#Example
692 sk_sp<SkSurface> surface = SkSurface::MakeRasterN32Premul(5, 6);
693 SkCanvas* smallCanvas = surface->getCanvas();
694 SkImageInfo imageInfo = SkImageInfo::MakeN32Premul(3, 4);
695 sk_sp<SkSurface> compatible = smallCanvas->makeSurface(imageInfo);
696 SkDebugf("compatible %c= nullptr\n", compatible == nullptr ? '=' : '!');
697 SkDebugf("size = %d, %d\n", compatible->width(), compatible->height());
698
699 #StdOut
Cary Clarkbad5ad72017-08-03 17:14:08 -0400700 compatible != nullptr
Cary Clark8032b982017-07-28 11:04:54 -0400701 size = 3, 4
702 ##
703##
704
Cary Clark2ade9972017-11-02 17:49:34 -0400705#SeeAlso SkSurface SkSurface::makeSurface SkImageInfo SkSurfaceProps
Cary Clark8032b982017-07-28 11:04:54 -0400706
707##
708
709# ------------------------------------------------------------------------------
710
711#Method virtual GrContext* getGrContext()
712
Cary Clarkab2621d2018-01-30 10:08:57 -0500713#Line # returns GPU_Context of the GPU_Surface ##
Cary Clark8032b982017-07-28 11:04:54 -0400714Returns GPU_Context of the GPU_Surface associated with Canvas.
715
Cary Clarkbad5ad72017-08-03 17:14:08 -0400716#Return GPU_Context, if available; nullptr otherwise ##
Cary Clark8032b982017-07-28 11:04:54 -0400717
718#Example
719void draw(SkCanvas* canvas) {
720 if (canvas->getGrContext()) {
721 canvas->clear(SK_ColorRED);
722 } else {
723 canvas->clear(SK_ColorBLUE);
724 }
725}
726##
727
728#ToDo fiddle should show both CPU and GPU out ##
729
Cary Clark2ade9972017-11-02 17:49:34 -0400730#SeeAlso GrContext
731
Cary Clark8032b982017-07-28 11:04:54 -0400732##
733
734# ------------------------------------------------------------------------------
735
Cary Clark73fa9722017-08-29 17:36:51 -0400736#Method void* accessTopLayerPixels(SkImageInfo* info, size_t* rowBytes, SkIPoint* origin = nullptr)
Cary Clark8032b982017-07-28 11:04:54 -0400737
Cary Clarkab2621d2018-01-30 10:08:57 -0500738#Line # returns writable pixel access if available ##
Cary Clark8032b982017-07-28 11:04:54 -0400739Returns the pixel base address, Image_Info, rowBytes, and origin if the pixels
Cary Clarkbad5ad72017-08-03 17:14:08 -0400740can be read directly. The returned address is only valid
Cary Clark8032b982017-07-28 11:04:54 -0400741while Canvas is in scope and unchanged. Any Canvas call or Surface call
742may invalidate the returned address and other returned values.
743
744If pixels are inaccessible, info, rowBytes, and origin are unchanged.
745
Cary Clarkbad5ad72017-08-03 17:14:08 -0400746#Param info storage for writable pixels' Image_Info; may be nullptr ##
747#Param rowBytes storage for writable pixels' row bytes; may be nullptr ##
Cary Clarkbc5697d2017-10-04 14:31:33 -0400748#Param origin storage for Canvas top Layer origin, its top-left corner;
Cary Clarkbad5ad72017-08-03 17:14:08 -0400749 may be nullptr
750##
Cary Clark8032b982017-07-28 11:04:54 -0400751
Cary Clarka523d2d2017-08-30 08:58:10 -0400752#Return address of pixels, or nullptr if inaccessible ##
Cary Clark8032b982017-07-28 11:04:54 -0400753
754#Example
755void draw(SkCanvas* canvas) {
756 if (canvas->accessTopLayerPixels(nullptr, nullptr)) {
757 canvas->clear(SK_ColorRED);
758 } else {
759 canvas->clear(SK_ColorBLUE);
760 }
761}
762##
763
764#Example
765#Description
Cary Clarkce101242017-09-01 15:51:02 -0400766Draws "ABC" on the device. Then draws "DEF" in Layer, and reads
767Layer to add a large dotted "DEF". Finally blends Layer with the
Cary Clark8032b982017-07-28 11:04:54 -0400768device.
769
Cary Clarkce101242017-09-01 15:51:02 -0400770The Layer and blended result appear on the CPU and GPU but the large dotted
Cary Clark8032b982017-07-28 11:04:54 -0400771"DEF" appear only on the CPU.
772##
773void draw(SkCanvas* canvas) {
Cary Clarkbad5ad72017-08-03 17:14:08 -0400774 SkPaint paint;
775 paint.setTextSize(100);
776 canvas->drawString("ABC", 20, 160, paint);
777 SkRect layerBounds = SkRect::MakeXYWH(32, 32, 192, 192);
778 canvas->saveLayerAlpha(&layerBounds, 128);
779 canvas->clear(SK_ColorWHITE);
780 canvas->drawString("DEF", 20, 160, paint);
781 SkImageInfo imageInfo;
782 size_t rowBytes;
783 SkIPoint origin;
784 uint32_t* access = (uint32_t*) canvas->accessTopLayerPixels(&imageInfo, &rowBytes, &origin);
785 if (access) {
786 int h = imageInfo.height();
787 int v = imageInfo.width();
788 int rowWords = rowBytes / sizeof(uint32_t);
789 for (int y = 0; y < h; ++y) {
790 int newY = (y - h / 2) * 2 + h / 2;
791 if (newY < 0 || newY >= h) {
792 continue;
793 }
794 for (int x = 0; x < v; ++x) {
795 int newX = (x - v / 2) * 2 + v / 2;
796 if (newX < 0 || newX >= v) {
797 continue;
798 }
799 if (access[y * rowWords + x] == SK_ColorBLACK) {
800 access[newY * rowWords + newX] = SK_ColorGRAY;
801 }
802 }
803 }
804
805 }
Cary Clark8032b982017-07-28 11:04:54 -0400806 canvas->restore();
807}
808##
809
810#ToDo there are no callers of this that I can find. Deprecate? ##
811#ToDo fiddle should show both CPU and GPU out ##
812
Cary Clark2ade9972017-11-02 17:49:34 -0400813#SeeAlso SkImageInfo SkPixmap
814
Cary Clark8032b982017-07-28 11:04:54 -0400815##
816
817# ------------------------------------------------------------------------------
818
819#Method SkRasterHandleAllocator::Handle accessTopRasterHandle() const
820
Cary Clarkab2621d2018-01-30 10:08:57 -0500821#Line # returns context that tracks Clip and Matrix ##
Cary Clark8032b982017-07-28 11:04:54 -0400822Returns custom context that tracks the Matrix and Clip.
823
824Use Raster_Handle_Allocator to blend Skia drawing with custom drawing, typically performed
Cary Clarkbc5697d2017-10-04 14:31:33 -0400825by the host platform user interface. The custom context returned is generated by
Cary Clarkbad5ad72017-08-03 17:14:08 -0400826SkRasterHandleAllocator::MakeCanvas, which creates a custom canvas with raster storage for
Cary Clark8032b982017-07-28 11:04:54 -0400827the drawing destination.
828
Cary Clarkce101242017-09-01 15:51:02 -0400829#Return context of custom allocation ##
Cary Clark8032b982017-07-28 11:04:54 -0400830
831#Example
832#Description
833#ToDo ##
834##
835#Function
836 static void DeleteCallback(void*, void* context) {
837 delete (char*) context;
838 }
839
840 class CustomAllocator : public SkRasterHandleAllocator {
841 public:
842 bool allocHandle(const SkImageInfo& info, Rec* rec) override {
843 char* context = new char[4]{'s', 'k', 'i', 'a'};
844 rec->fReleaseProc = DeleteCallback;
845 rec->fReleaseCtx = context;
846 rec->fHandle = context;
847 rec->fPixels = context;
848 rec->fRowBytes = 4;
849 return true;
850 }
851
852 void updateHandle(Handle handle, const SkMatrix& ctm, const SkIRect& clip_bounds) override {
853 // apply canvas matrix and clip to custom environment
854 }
855 };
856
857##
858 void draw(SkCanvas* canvas) {
859 const SkImageInfo info = SkImageInfo::MakeN32Premul(1, 1);
860 std::unique_ptr<SkCanvas> c2 =
861 SkRasterHandleAllocator::MakeCanvas(std::unique_ptr<CustomAllocator>(
862 new CustomAllocator()), info);
863 char* context = (char*) c2->accessTopRasterHandle();
864 SkDebugf("context = %.4s\n", context);
865
866 }
867 #StdOut
868 context = skia
869 ##
870 #ToDo skstd::make_unique could not be used because def is private -- note to fix in c++14? ##
871##
872
873#SeeAlso SkRasterHandleAllocator
874
875##
876
877# ------------------------------------------------------------------------------
878
879#Method bool peekPixels(SkPixmap* pixmap)
880
Cary Clarkab2621d2018-01-30 10:08:57 -0500881#Line # returns if Canvas has direct access to its pixels ##
Cary Clark8032b982017-07-28 11:04:54 -0400882Returns true if Canvas has direct access to its pixels.
883
Cary Clarkf05bdda2017-08-24 12:59:48 -0400884Pixels are readable when Device is raster. Pixels are not readable when Canvas
Cary Clarkbad5ad72017-08-03 17:14:08 -0400885is returned from GPU_Surface, returned by SkDocument::beginPage, returned by
Cary Clarkf05bdda2017-08-24 12:59:48 -0400886SkPictureRecorder::beginRecording, or Canvas is the base of a utility class
Cary Clarkbad5ad72017-08-03 17:14:08 -0400887like SkDumpCanvas.
Cary Clark8032b982017-07-28 11:04:54 -0400888
Cary Clarkf05bdda2017-08-24 12:59:48 -0400889pixmap is valid only while Canvas is in scope and unchanged. Any
Cary Clarkbad5ad72017-08-03 17:14:08 -0400890Canvas or Surface call may invalidate the pixmap values.
Cary Clark8032b982017-07-28 11:04:54 -0400891
Cary Clarkbc5697d2017-10-04 14:31:33 -0400892#Param pixmap storage for pixel state if pixels are readable; otherwise, ignored ##
Cary Clark8032b982017-07-28 11:04:54 -0400893
Cary Clarkbad5ad72017-08-03 17:14:08 -0400894#Return true if Canvas has direct access to pixels ##
Cary Clark8032b982017-07-28 11:04:54 -0400895
896#Example
897 SkPixmap pixmap;
898 if (canvas->peekPixels(&pixmap)) {
899 SkDebugf("width=%d height=%d\n", pixmap.bounds().width(), pixmap.bounds().height());
900 }
901 #StdOut
902 width=256 height=256
903 ##
904##
905
Cary Clark2ade9972017-11-02 17:49:34 -0400906#SeeAlso readPixels SkBitmap::peekPixels SkImage::peekPixels SkSurface::peekPixels
907
Cary Clark8032b982017-07-28 11:04:54 -0400908##
909
910# ------------------------------------------------------------------------------
911
912#Method bool readPixels(const SkImageInfo& dstInfo, void* dstPixels, size_t dstRowBytes,
913 int srcX, int srcY)
Cary 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
Cary Clarka560c472017-11-27 10:44:06 -0500917ignored.
Cary Clark6fc50412017-09-21 12:31:06 -0400918
Cary Clarka560c472017-11-27 10:44:06 -0500919Source Rect corners are (srcX, srcY) and (imageInfo().width(), imageInfo().height()).
920Destination Rect corners are (0, 0) and (dstInfo.width(), dstInfo.height()).
Cary Clark6fc50412017-09-21 12:31:06 -0400921Copies each readable pixel intersecting both rectangles, without scaling,
Cary Clarkf05bdda2017-08-24 12:59:48 -0400922converting to dstInfo.colorType() and dstInfo.alphaType() if required.
Cary Clark8032b982017-07-28 11:04:54 -0400923
Cary Clarkf05bdda2017-08-24 12:59:48 -0400924Pixels are readable when Device is raster, or backed by a GPU.
925Pixels are not readable when SkCanvas is returned by SkDocument::beginPage,
926returned by SkPictureRecorder::beginRecording, or Canvas is the base of a utility
927class like SkDumpCanvas.
Cary Clark8032b982017-07-28 11:04:54 -0400928
Cary Clarkf05bdda2017-08-24 12:59:48 -0400929The destination pixel storage must be allocated by the caller.
Cary Clark8032b982017-07-28 11:04:54 -0400930
Cary Clark2dc84ad2018-01-26 12:56:22 -0500931Pixel values are converted only if Color_Type and Alpha_Type
Cary Clarkf05bdda2017-08-24 12:59:48 -0400932do not match. Only pixels within both source and destination rectangles
Cary Clark154beea2017-10-26 07:58:48 -0400933are copied. dstPixels contents outside Rect intersection are unchanged.
Cary Clarkf05bdda2017-08-24 12:59:48 -0400934
935Pass negative values for srcX or srcY to offset pixels across or down destination.
Cary Clark8032b982017-07-28 11:04:54 -0400936
937Does not copy, and returns false if:
938
939#List
Cary Clarkf05bdda2017-08-24 12:59:48 -0400940# Source and destination rectangles do not intersect. ##
941# Canvas pixels could not be converted to dstInfo.colorType() or dstInfo.alphaType(). ##
942# Canvas pixels are not readable; for instance, Canvas is document-based. ##
Cary Clark8032b982017-07-28 11:04:54 -0400943# dstRowBytes is too small to contain one row of pixels. ##
944##
945
Cary Clark2dc84ad2018-01-26 12:56:22 -0500946#Param dstInfo width, height, Color_Type, and Alpha_Type of dstPixels ##
Cary Clarkf05bdda2017-08-24 12:59:48 -0400947#Param dstPixels storage for pixels; dstInfo.height() times dstRowBytes, or larger ##
948#Param dstRowBytes size of one destination row; dstInfo.width() times pixel size, or larger ##
949#Param srcX offset into readable pixels in x; may be negative ##
950#Param srcY offset into readable pixels in y; may be negative ##
Cary Clark8032b982017-07-28 11:04:54 -0400951
Cary Clarkbad5ad72017-08-03 17:14:08 -0400952#Return true if pixels were copied ##
Cary Clark8032b982017-07-28 11:04:54 -0400953
954#Example
Cary Clarkf05bdda2017-08-24 12:59:48 -0400955#Width 64
956#Height 64
957#Description
958 A black circle drawn on a blue background provides an image to copy.
959 readPixels copies one quarter of the canvas into each of the four corners.
Cary Clarka560c472017-11-27 10:44:06 -0500960 The copied quarter circles overdraw the original circle.
Cary Clarkf05bdda2017-08-24 12:59:48 -0400961##
962 canvas->clear(SK_ColorBLUE);
963 SkPaint paint;
964 canvas->drawCircle(32, 32, 28, paint);
965 SkImageInfo info = SkImageInfo::Make(64, 64, kBGRA_8888_SkColorType, kPremul_SkAlphaType);
966 sk_sp<SkData> data(SkData::MakeUninitialized(info.minRowBytes() * info.height()));
967 sk_bzero(data->writable_data(), info.minRowBytes() * info.height());
968 for (int x : { 32, -32 } ) {
969 for (int y : { 32, -32 } ) {
970 canvas->readPixels(info, data->writable_data(), info.minRowBytes(), x, y);
971 }
972 }
973 sk_sp<SkImage> image = SkImage::MakeRasterData(info, data, info.minRowBytes());
974 canvas->drawImage(image, 0, 0);
975##
976
977#Example
Cary Clark8032b982017-07-28 11:04:54 -0400978#Description
Cary Clarkce101242017-09-01 15:51:02 -0400979 Canvas returned by Raster_Surface has Premultiplied pixel values.
980 clear() takes Unpremultiplied input with Color_Alpha equal 0x80
981 and Color_RGB equal 0x55, 0xAA, 0xFF. Color_RGB is multiplied by Color_Alpha
982 to generate Premultiplied value 0x802B5580. readPixels converts pixel back
983 to Unpremultiplied value 0x8056A9FF, introducing error.
Cary Clark8032b982017-07-28 11:04:54 -0400984##
985 canvas->clear(0x8055aaff);
986 for (SkAlphaType alphaType : { kPremul_SkAlphaType, kUnpremul_SkAlphaType } ) {
987 uint32_t pixel = 0;
988 SkImageInfo info = SkImageInfo::Make(1, 1, kBGRA_8888_SkColorType, alphaType);
989 if (canvas->readPixels(info, &pixel, 4, 0, 0)) {
990 SkDebugf("pixel = %08x\n", pixel);
991 }
992 }
993
994 #StdOut
995 pixel = 802b5580
996 pixel = 8056a9ff
997 ##
998##
999
Cary Clark2ade9972017-11-02 17:49:34 -04001000#SeeAlso peekPixels writePixels drawBitmap drawImage SkBitmap::readPixels SkPixmap::readPixels SkImage::readPixels SkSurface::readPixels
Cary Clark8032b982017-07-28 11:04:54 -04001001
1002##
1003
1004# ------------------------------------------------------------------------------
1005
1006#Method bool readPixels(const SkPixmap& pixmap, int srcX, int srcY)
1007
Cary Clark154beea2017-10-26 07:58:48 -04001008Copies Rect of pixels from Canvas into pixmap. Matrix and Clip are
Cary Clarka560c472017-11-27 10:44:06 -05001009ignored.
Cary Clark6fc50412017-09-21 12:31:06 -04001010
Cary Clarka560c472017-11-27 10:44:06 -05001011Source Rect corners are (srcX, srcY) and (imageInfo().width(), imageInfo().height()).
1012Destination Rect corners are (0, 0) and (pixmap.width(), pixmap.height()).
Cary Clark6fc50412017-09-21 12:31:06 -04001013Copies each readable pixel intersecting both rectangles, without scaling,
Cary Clarkf05bdda2017-08-24 12:59:48 -04001014converting to pixmap.colorType() and pixmap.alphaType() if required.
Cary Clark8032b982017-07-28 11:04:54 -04001015
Cary Clarkf05bdda2017-08-24 12:59:48 -04001016Pixels are readable when Device is raster, or backed by a GPU.
1017Pixels are not readable when SkCanvas is returned by SkDocument::beginPage,
1018returned by SkPictureRecorder::beginRecording, or Canvas is the base of a utility
1019class like SkDumpCanvas.
Cary Clark8032b982017-07-28 11:04:54 -04001020
Cary Clark6fc50412017-09-21 12:31:06 -04001021Caller must allocate pixel storage in pixmap if needed.
Cary Clark8032b982017-07-28 11:04:54 -04001022
Cary Clark2dc84ad2018-01-26 12:56:22 -05001023Pixel values are converted only if Color_Type and Alpha_Type
Cary Clark154beea2017-10-26 07:58:48 -04001024do not match. Only pixels within both source and destination Rects
1025are copied. pixmap pixels contents outside Rect intersection are unchanged.
Cary Clarkf05bdda2017-08-24 12:59:48 -04001026
1027Pass negative values for srcX or srcY to offset pixels across or down pixmap.
Cary Clark8032b982017-07-28 11:04:54 -04001028
1029Does not copy, and returns false if:
1030
1031#List
Cary Clarkf05bdda2017-08-24 12:59:48 -04001032# Source and destination rectangles do not intersect. ##
1033# Canvas pixels could not be converted to pixmap.colorType() or pixmap.alphaType(). ##
1034# Canvas pixels are not readable; for instance, Canvas is document-based. ##
1035# Pixmap pixels could not be allocated. ##
1036# pixmap.rowBytes() is too small to contain one row of pixels. ##
Cary Clark8032b982017-07-28 11:04:54 -04001037##
1038
Cary Clarkbad5ad72017-08-03 17:14:08 -04001039#Param pixmap storage for pixels copied from Canvas ##
Cary Clarkf05bdda2017-08-24 12:59:48 -04001040#Param srcX offset into readable pixels in x; may be negative ##
1041#Param srcY offset into readable pixels in y; may be negative ##
Cary Clark8032b982017-07-28 11:04:54 -04001042
Cary Clarkbad5ad72017-08-03 17:14:08 -04001043#Return true if pixels were copied ##
Cary Clark8032b982017-07-28 11:04:54 -04001044
1045#Example
Cary Clarkf05bdda2017-08-24 12:59:48 -04001046 #Description
Cary Clarkce101242017-09-01 15:51:02 -04001047 clear() takes Unpremultiplied input with Color_Alpha equal 0x80
1048 and Color_RGB equal 0x55, 0xAA, 0xFF. Color_RGB is multiplied by Color_Alpha
1049 to generate Premultiplied value 0x802B5580.
Cary Clarkf05bdda2017-08-24 12:59:48 -04001050 ##
1051 void draw(SkCanvas* canvas) {
1052 canvas->clear(0x8055aaff);
1053 uint32_t pixels[1] = { 0 };
1054 SkPixmap pixmap(SkImageInfo::MakeN32Premul(1, 1), pixels, 4);
1055 canvas->readPixels(pixmap, 0, 0);
1056 SkDebugf("pixel = %08x\n", pixels[0]);
1057 }
Cary Clark8032b982017-07-28 11:04:54 -04001058 #StdOut
1059 pixel = 802b5580
1060 ##
1061##
1062
Cary Clark2ade9972017-11-02 17:49:34 -04001063#SeeAlso peekPixels writePixels drawBitmap drawImage SkBitmap::readPixels SkPixmap::readPixels SkImage::readPixels SkSurface::readPixels
Cary Clark8032b982017-07-28 11:04:54 -04001064
1065##
1066
1067# ------------------------------------------------------------------------------
1068
1069#Method bool readPixels(const SkBitmap& bitmap, int srcX, int srcY)
1070
Cary Clark154beea2017-10-26 07:58:48 -04001071Copies Rect of pixels from Canvas into bitmap. Matrix and Clip are
Cary Clarka560c472017-11-27 10:44:06 -05001072ignored.
Cary Clark6fc50412017-09-21 12:31:06 -04001073
Cary Clarka560c472017-11-27 10:44:06 -05001074Source Rect corners are (srcX, srcY) and (imageInfo().width(), imageInfo().height()).
Cary Clark154beea2017-10-26 07:58:48 -04001075Destination Rect corners are (0, 0) and (bitmap.width(), bitmap.height()).
Cary Clarkf05bdda2017-08-24 12:59:48 -04001076Copies each readable pixel intersecting both rectangles, without scaling,
1077converting to bitmap.colorType() and bitmap.alphaType() if required.
Cary Clark8032b982017-07-28 11:04:54 -04001078
Cary Clarkf05bdda2017-08-24 12:59:48 -04001079Pixels are readable when Device is raster, or backed by a GPU.
1080Pixels are not readable when SkCanvas is returned by SkDocument::beginPage,
1081returned by SkPictureRecorder::beginRecording, or Canvas is the base of a utility
1082class like SkDumpCanvas.
Cary Clark8032b982017-07-28 11:04:54 -04001083
Cary Clark6fc50412017-09-21 12:31:06 -04001084Caller must allocate pixel storage in bitmap if needed.
Cary Clarkf05bdda2017-08-24 12:59:48 -04001085
Cary Clark2dc84ad2018-01-26 12:56:22 -05001086Bitmap values are converted only if Color_Type and Alpha_Type
Cary Clarkf05bdda2017-08-24 12:59:48 -04001087do not match. Only pixels within both source and destination rectangles
Cary Clark154beea2017-10-26 07:58:48 -04001088are copied. Bitmap pixels outside Rect intersection are unchanged.
Cary Clarkf05bdda2017-08-24 12:59:48 -04001089
1090Pass negative values for srcX or srcY to offset pixels across or down bitmap.
Cary Clark8032b982017-07-28 11:04:54 -04001091
1092Does not copy, and returns false if:
1093
1094#List
Cary Clarkf05bdda2017-08-24 12:59:48 -04001095# Source and destination rectangles do not intersect. ##
1096# Canvas pixels could not be converted to bitmap.colorType() or bitmap.alphaType(). ##
1097# Canvas pixels are not readable; for instance, Canvas is document-based. ##
Cary Clark8032b982017-07-28 11:04:54 -04001098# bitmap pixels could not be allocated. ##
Cary Clarkf05bdda2017-08-24 12:59:48 -04001099# bitmap.rowBytes() is too small to contain one row of pixels. ##
Cary Clark8032b982017-07-28 11:04:54 -04001100##
1101
Cary Clarkbad5ad72017-08-03 17:14:08 -04001102#Param bitmap storage for pixels copied from Canvas ##
Cary Clarkf05bdda2017-08-24 12:59:48 -04001103#Param srcX offset into readable pixels in x; may be negative ##
1104#Param srcY offset into readable pixels in y; may be negative ##
Cary Clark8032b982017-07-28 11:04:54 -04001105
Cary Clarkbad5ad72017-08-03 17:14:08 -04001106#Return true if pixels were copied ##
Cary Clark8032b982017-07-28 11:04:54 -04001107
1108#Example
Cary Clarkf05bdda2017-08-24 12:59:48 -04001109 #Description
Cary Clarkce101242017-09-01 15:51:02 -04001110 clear() takes Unpremultiplied input with Color_Alpha equal 0x80
1111 and Color_RGB equal 0x55, 0xAA, 0xFF. Color_RGB is multiplied by Color_Alpha
1112 to generate Premultiplied value 0x802B5580.
Cary Clarkf05bdda2017-08-24 12:59:48 -04001113 ##
Cary Clark8032b982017-07-28 11:04:54 -04001114void draw(SkCanvas* canvas) {
1115 canvas->clear(0x8055aaff);
1116 SkBitmap bitmap;
1117 bitmap.allocPixels(SkImageInfo::MakeN32Premul(1, 1));
1118 canvas->readPixels(bitmap, 0, 0);
1119 SkDebugf("pixel = %08x\n", bitmap.getAddr32(0, 0)[0]);
1120}
1121 #StdOut
1122 pixel = 802b5580
1123 ##
1124##
1125
Cary Clark2ade9972017-11-02 17:49:34 -04001126#SeeAlso peekPixels writePixels drawBitmap drawImage SkBitmap::readPixels SkPixmap::readPixels SkImage::readPixels SkSurface::readPixels
Cary Clark8032b982017-07-28 11:04:54 -04001127
1128##
1129
1130# ------------------------------------------------------------------------------
1131
1132#Method bool writePixels(const SkImageInfo& info, const void* pixels, size_t rowBytes, int x, int y)
1133
Cary Clarkab2621d2018-01-30 10:08:57 -05001134#Line # copies and converts rectangle of pixels to Canvas ##
Cary Clark154beea2017-10-26 07:58:48 -04001135Copies Rect from pixels to Canvas. Matrix and Clip are ignored.
1136Source Rect corners are (0, 0) and (info.width(), info.height()).
1137Destination Rect corners are (x, y) and
1138(imageInfo().width(), imageInfo().height()).
Cary Clark6fc50412017-09-21 12:31:06 -04001139
1140Copies each readable pixel intersecting both rectangles, without scaling,
Cary Clark154beea2017-10-26 07:58:48 -04001141converting to imageInfo().colorType() and imageInfo().alphaType() if required.
Cary Clark8032b982017-07-28 11:04:54 -04001142
Cary Clarkf05bdda2017-08-24 12:59:48 -04001143Pixels are writable when Device is raster, or backed by a GPU.
1144Pixels are not writable when SkCanvas is returned by SkDocument::beginPage,
1145returned by SkPictureRecorder::beginRecording, or Canvas is the base of a utility
1146class like SkDumpCanvas.
Cary Clark8032b982017-07-28 11:04:54 -04001147
Cary Clark2dc84ad2018-01-26 12:56:22 -05001148Pixel values are converted only if Color_Type and Alpha_Type
Cary Clarkf05bdda2017-08-24 12:59:48 -04001149do not match. Only pixels within both source and destination rectangles
Cary Clark154beea2017-10-26 07:58:48 -04001150are copied. Canvas pixels outside Rect intersection are unchanged.
Cary Clark8032b982017-07-28 11:04:54 -04001151
Cary Clarkf05bdda2017-08-24 12:59:48 -04001152Pass negative values for x or y to offset pixels to the left or
1153above Canvas pixels.
Cary Clark8032b982017-07-28 11:04:54 -04001154
1155Does not copy, and returns false if:
1156
1157#List
Cary Clarkf05bdda2017-08-24 12:59:48 -04001158# Source and destination rectangles do not intersect. ##
Cary Clarkac47b882018-01-11 10:35:44 -05001159# pixels could not be converted to Canvas imageInfo().colorType() or
1160 imageInfo().alphaType(). ##
Cary Clark8032b982017-07-28 11:04:54 -04001161# Canvas pixels are not writable; for instance, Canvas is document-based. ##
1162# rowBytes is too small to contain one row of pixels. ##
1163##
1164
Cary Clark2dc84ad2018-01-26 12:56:22 -05001165#Param info width, height, Color_Type, and Alpha_Type of pixels ##
Cary Clarkf05bdda2017-08-24 12:59:48 -04001166#Param pixels pixels to copy, of size info.height() times rowBytes, or larger ##
Cary Clarkd0530ba2017-09-14 11:25:39 -04001167#Param rowBytes size of one row of pixels; info.width() times pixel size, or larger ##
Cary Clarkf05bdda2017-08-24 12:59:48 -04001168#Param x offset into Canvas writable pixels in x; may be negative ##
1169#Param y offset into Canvas writable pixels in y; may be negative ##
Cary Clark8032b982017-07-28 11:04:54 -04001170
Cary Clarkbad5ad72017-08-03 17:14:08 -04001171#Return true if pixels were written to Canvas ##
Cary Clark8032b982017-07-28 11:04:54 -04001172
1173#Example
1174 SkImageInfo imageInfo = SkImageInfo::MakeN32(256, 1, kPremul_SkAlphaType);
1175 for (int y = 0; y < 256; ++y) {
1176 uint32_t pixels[256];
1177 for (int x = 0; x < 256; ++x) {
1178 pixels[x] = SkColorSetARGB(x, x + y, x, x - y);
1179 }
1180 canvas->writePixels(imageInfo, &pixels, sizeof(pixels), 0, y);
1181 }
1182##
1183
Cary Clark2ade9972017-11-02 17:49:34 -04001184#SeeAlso readPixels drawBitmap drawImage SkBitmap::writePixels
Cary Clark8032b982017-07-28 11:04:54 -04001185
1186##
1187
1188# ------------------------------------------------------------------------------
1189
1190#Method bool writePixels(const SkBitmap& bitmap, int x, int y)
1191
Cary Clark154beea2017-10-26 07:58:48 -04001192Copies Rect from pixels to Canvas. Matrix and Clip are ignored.
1193Source Rect corners are (0, 0) and (bitmap.width(), bitmap.height()).
Cary Clark6fc50412017-09-21 12:31:06 -04001194
Cary Clark154beea2017-10-26 07:58:48 -04001195Destination Rect corners are (x, y) and
1196(imageInfo().width(), imageInfo().height()).
Cary Clark6fc50412017-09-21 12:31:06 -04001197
1198Copies each readable pixel intersecting both rectangles, without scaling,
Cary Clark154beea2017-10-26 07:58:48 -04001199converting to imageInfo().colorType() and imageInfo().alphaType() if required.
Cary Clark8032b982017-07-28 11:04:54 -04001200
Cary Clarkf05bdda2017-08-24 12:59:48 -04001201Pixels are writable when Device is raster, or backed by a GPU.
1202Pixels are not writable when SkCanvas is returned by SkDocument::beginPage,
1203returned by SkPictureRecorder::beginRecording, or Canvas is the base of a utility
1204class like SkDumpCanvas.
Cary Clark8032b982017-07-28 11:04:54 -04001205
Cary Clark2dc84ad2018-01-26 12:56:22 -05001206Pixel values are converted only if Color_Type and Alpha_Type
Cary Clarkf05bdda2017-08-24 12:59:48 -04001207do not match. Only pixels within both source and destination rectangles
Cary Clark154beea2017-10-26 07:58:48 -04001208are copied. Canvas pixels outside Rect intersection are unchanged.
Cary Clark8032b982017-07-28 11:04:54 -04001209
Cary Clarkf05bdda2017-08-24 12:59:48 -04001210Pass negative values for x or y to offset pixels to the left or
1211above Canvas pixels.
Cary Clark8032b982017-07-28 11:04:54 -04001212
1213Does not copy, and returns false if:
1214
1215#List
Cary Clarkf05bdda2017-08-24 12:59:48 -04001216# Source and destination rectangles do not intersect. ##
Cary Clark8032b982017-07-28 11:04:54 -04001217# bitmap does not have allocated pixels. ##
Cary Clarkac47b882018-01-11 10:35:44 -05001218# bitmap pixels could not be converted to Canvas imageInfo().colorType() or
1219 imageInfo().alphaType(). ##
Cary Clarkce101242017-09-01 15:51:02 -04001220# Canvas pixels are not writable; for instance, Canvas is document based. ##
Cary Clark8032b982017-07-28 11:04:54 -04001221# bitmap pixels are inaccessible; for instance, bitmap wraps a texture. ##
1222##
1223
Cary Clarkbad5ad72017-08-03 17:14:08 -04001224#Param bitmap contains pixels copied to Canvas ##
Cary Clarkf05bdda2017-08-24 12:59:48 -04001225#Param x offset into Canvas writable pixels in x; may be negative ##
1226#Param y offset into Canvas writable pixels in y; may be negative ##
Cary Clark8032b982017-07-28 11:04:54 -04001227
Cary Clarkbad5ad72017-08-03 17:14:08 -04001228#Return true if pixels were written to Canvas ##
Cary Clark8032b982017-07-28 11:04:54 -04001229
1230#Example
1231void draw(SkCanvas* canvas) {
1232 SkImageInfo imageInfo = SkImageInfo::MakeN32Premul(2, 2);
1233 SkBitmap bitmap;
1234 bitmap.setInfo(imageInfo);
1235 uint32_t pixels[4];
1236 bitmap.setPixels(pixels);
1237 for (int y = 0; y < 256; y += 2) {
1238 for (int x = 0; x < 256; x += 2) {
1239 pixels[0] = SkColorSetRGB(x, y, x | y);
1240 pixels[1] = SkColorSetRGB(x ^ y, y, x);
1241 pixels[2] = SkColorSetRGB(x, x & y, y);
1242 pixels[3] = SkColorSetRGB(~x, ~y, x);
1243 canvas->writePixels(bitmap, x, y);
1244 }
1245 }
1246}
1247##
1248
Cary Clark2ade9972017-11-02 17:49:34 -04001249#SeeAlso readPixels drawBitmap drawImage SkBitmap::writePixels
Cary Clark8032b982017-07-28 11:04:54 -04001250
1251##
1252
1253# ------------------------------------------------------------------------------
Cary Clark08895c42018-02-01 09:37:32 -05001254#Subtopic State_Stack
1255#Line # stack of state for hierarchical drawing ##
Cary Clark8032b982017-07-28 11:04:54 -04001256
1257Canvas maintains a stack of state that allows hierarchical drawing, commonly used
Cary Clarkbad5ad72017-08-03 17:14:08 -04001258to implement windows and views. The initial state has an identity matrix and and
1259an infinite clip. Even with a wide-open clip, drawing is constrained by the
1260bounds of the Canvas Surface or Device.
Cary Clark8032b982017-07-28 11:04:54 -04001261
1262Canvas savable state consists of Clip, Matrix, and Draw_Filter.
1263Clip describes the area that may be drawn to.
1264Matrix transforms the geometry.
1265Draw_Filter (deprecated on most platforms) modifies the paint before drawing.
1266
1267save(), saveLayer, saveLayerPreserveLCDTextRequests, and saveLayerAlpha
1268save state and return the depth of the stack.
1269
Cary Clarkbad5ad72017-08-03 17:14:08 -04001270restore(), restoreToCount, and ~SkCanvas() revert state to its value when saved.
Cary Clark8032b982017-07-28 11:04:54 -04001271
1272Each state on the stack intersects Clip with the previous Clip,
1273and concatenates Matrix with the previous Matrix.
1274The intersected Clip makes the drawing area the same or smaller;
1275the concatenated Matrix may move the origin and potentially scale or rotate
1276the coordinate space.
1277
1278Canvas does not require balancing the state stack but it is a good idea
1279to do so. Calling save() without restore() will eventually cause Skia to fail;
1280mismatched save() and restore() create hard to find bugs.
1281
1282It is not possible to use state to draw outside of the clip defined by the
1283previous state.
1284
1285#Example
1286#Description
1287Draw to ever smaller clips; then restore drawing to full canvas.
1288Note that the second clipRect is not permitted to enlarge Clip.
1289##
1290#Height 160
Cary Clarkbad5ad72017-08-03 17:14:08 -04001291void draw(SkCanvas* canvas) {
1292 SkPaint paint;
1293 canvas->save(); // records stack depth to restore
1294 canvas->clipRect(SkRect::MakeWH(100, 100)); // constrains drawing to clip
1295 canvas->clear(SK_ColorRED); // draws to limit of clip
1296 canvas->save(); // records stack depth to restore
1297 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}
1304##
1305
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
1344#Description
1345The 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
1374last saved. The state is removed from the stack.
1375
1376Does nothing if the stack is empty.
1377
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.
1398Equals the number of save() calls less the number of restore() calls plus one.
1399The 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
1432Does nothing if saveCount is greater than state stack count.
1433Restores 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
Cary Clark2ade9972017-11-02 17:49:34 -04001453#SeeAlso restore() getSaveCount save()
1454
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
1467complete, the Bitmap is drawn into the Canvas.
1468
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(),
1486setMatrix, and resetMatrix. Clip may be changed by clipRect, clipRRect,
1487clipPath, 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
1525#Method int saveLayer(const SkRect& bounds, const SkPaint* paint)
1526
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.
1553The red rectangle is clipped; it does not fully fit on Layer.
1554Image_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.
1588
1589Rect 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
Cary Clark08895c42018-02-01 09:37:32 -05001676#ToDo
1677add new markup to associate typedef SaveLayerFlags with Enum so that, for
1678documentation purposes, this enum is named rather than anonymous
1679##
Cary Clarkce101242017-09-01 15:51:02 -04001680
Cary Clark08895c42018-02-01 09:37:32 -05001681#Enum
1682#Line # sets SaveLayerRec options ##
Cary Clarkce101242017-09-01 15:51:02 -04001683#Code
1684 enum {
1685 kIsOpaque_SaveLayerFlag = 1 << 0,
1686 kPreserveLCDText_SaveLayerFlag = 1 << 1,
1687 kInitWithPrevious_SaveLayerFlag = 1 << 2,
1688 kDontClipToLayer_Legacy_SaveLayerFlag = kDontClipToLayer_PrivateSaveLayerFlag,
1689 };
Cary Clarkce101242017-09-01 15:51:02 -04001690##
1691
1692SaveLayerFlags provides options that may be used in any combination in SaveLayerRec,
1693defining how Layer allocated by saveLayer operates.
1694
1695#Const kIsOpaque_SaveLayerFlag 1
1696 Creates Layer without transparency. Flag is ignored if Layer Paint contains
1697 Image_Filter or Color_Filter.
1698##
1699
1700#Const kPreserveLCDText_SaveLayerFlag 2
1701 Creates Layer for LCD text. Flag is ignored if Layer Paint contains
1702 Image_Filter or Color_Filter.
1703##
1704
1705#Const kInitWithPrevious_SaveLayerFlag 4
1706 Initializes Layer with the contents of the previous Layer.
1707##
1708
1709#Const kDontClipToLayer_Legacy_SaveLayerFlag 0x80000000
1710#Private
1711 to be deprecated: bug.skia.org/2440
1712##
1713 Only present on Android.
1714 Skips setting a clip to the Layer bounds.
1715##
1716
1717#Example
1718#Height 160
1719#Description
1720Canvas Layer captures red and blue circles scaled up by four.
1721scalePaint blends Layer back with transparency.
1722##
1723void draw(SkCanvas* canvas) {
1724 SkPaint redPaint, bluePaint, scalePaint;
1725 redPaint.setColor(SK_ColorRED);
1726 canvas->drawCircle(21, 21, 8, redPaint);
1727 bluePaint.setColor(SK_ColorBLUE);
1728 canvas->drawCircle(31, 21, 8, bluePaint);
1729 SkMatrix matrix;
1730 matrix.setScale(4, 4);
1731 scalePaint.setAlpha(0x40);
1732 scalePaint.setImageFilter(
1733 SkImageFilter::MakeMatrixFilter(matrix, kNone_SkFilterQuality, nullptr));
1734 SkCanvas::SaveLayerRec saveLayerRec(nullptr, &scalePaint,
1735 SkCanvas::kInitWithPrevious_SaveLayerFlag);
1736 canvas->saveLayer(saveLayerRec);
1737 canvas->restore();
1738}
1739##
1740
Cary Clark2ade9972017-11-02 17:49:34 -04001741#SeeAlso save() restore() saveLayer saveLayerPreserveLCDTextRequests saveLayerAlpha SaveLayerRec
Cary Clarkce101242017-09-01 15:51:02 -04001742
1743#Enum ##
1744
Cary Clarka560c472017-11-27 10:44:06 -05001745#Typedef uint32_t SaveLayerFlags
1746
1747##
1748
Cary Clarkce101242017-09-01 15:51:02 -04001749#Struct SaveLayerRec
Cary Clark08895c42018-02-01 09:37:32 -05001750#Line # contains the state used to create the Layer ##
Cary Clarkce101242017-09-01 15:51:02 -04001751#Code
1752 struct SaveLayerRec {
1753 SaveLayerRec*(...
1754
1755 const SkRect* fBounds;
1756 const SkPaint* fPaint;
1757 const SkImageFilter* fBackdrop;
1758 SaveLayerFlags fSaveLayerFlags;
1759 };
1760##
1761
1762SaveLayerRec contains the state used to create the Layer.
1763
1764#Member const SkRect* fBounds
1765 fBounds is used as a hint to limit the size of Layer; may be nullptr.
1766 fBounds suggests but does not define Layer size. To clip drawing to
1767 a specific rectangle, use clipRect.
1768##
1769
1770#Member const SkPaint* fPaint
1771 fPaint modifies how Layer overlays the prior Layer; may be nullptr.
1772 Color_Alpha, Blend_Mode, Color_Filter, Draw_Looper, Image_Filter, and
1773 Mask_Filter affect Layer draw.
1774##
1775
1776#Member const SkImageFilter* fBackdrop
1777 fBackdrop applies Image_Filter to the prior Layer when copying to the Layer;
1778 may be nullptr. Use kInitWithPrevious_SaveLayerFlag to copy the
1779 prior Layer without an Image_Filter.
1780##
1781
1782#Member const SkImage* fClipMask
1783 restore() clips Layer by the Color_Alpha channel of fClipMask when
1784 Layer is copied to Device. fClipMask may be nullptr. .
1785##
1786
1787#Member const SkMatrix* fClipMatrix
1788 fClipMatrix transforms fClipMask before it clips Layer. If
1789 fClipMask describes a translucent gradient, it may be scaled and rotated
1790 without introducing artifacts. fClipMatrix may be nullptr.
1791##
1792
1793#Member SaveLayerFlags fSaveLayerFlags
1794 fSaveLayerFlags are used to create Layer without transparency,
1795 create Layer for LCD text, and to create Layer with the
1796 contents of the previous Layer.
1797##
1798
1799#Example
1800#Height 160
1801#Description
1802Canvas Layer captures a red Anti-aliased circle and a blue Aliased circle scaled
1803up by four. After drawing another red circle without scaling on top, the Layer is
1804transferred to the main canvas.
1805##
1806void draw(SkCanvas* canvas) {
1807 SkPaint redPaint, bluePaint;
1808 redPaint.setAntiAlias(true);
1809 redPaint.setColor(SK_ColorRED);
1810 canvas->drawCircle(21, 21, 8, redPaint);
1811 bluePaint.setColor(SK_ColorBLUE);
1812 canvas->drawCircle(31, 21, 8, bluePaint);
1813 SkMatrix matrix;
1814 matrix.setScale(4, 4);
1815 auto scaler = SkImageFilter::MakeMatrixFilter(matrix, kNone_SkFilterQuality, nullptr);
1816 SkCanvas::SaveLayerRec saveLayerRec(nullptr, nullptr, scaler.get(), 0);
1817 canvas->saveLayer(saveLayerRec);
1818 canvas->drawCircle(125, 85, 8, redPaint);
1819 canvas->restore();
1820}
1821##
1822
1823#Method SaveLayerRec()
1824
1825Sets fBounds, fPaint, and fBackdrop to nullptr. Clears fSaveLayerFlags.
1826
1827#Return empty SaveLayerRec ##
1828
1829#Example
1830 SkCanvas::SaveLayerRec rec1;
1831 rec1.fSaveLayerFlags = SkCanvas::kIsOpaque_SaveLayerFlag;
1832 SkCanvas::SaveLayerRec rec2(nullptr, nullptr, SkCanvas::kIsOpaque_SaveLayerFlag);
1833 SkDebugf("rec1 %c= rec2\n", rec1.fBounds == rec2.fBounds
1834 && rec1.fPaint == rec2.fPaint
1835 && rec1.fBackdrop == rec2.fBackdrop
1836 && rec1.fSaveLayerFlags == rec2.fSaveLayerFlags ? '=' : '!');
1837 #StdOut
1838 rec1 == rec2
1839 ##
1840##
1841
Cary Clark2ade9972017-11-02 17:49:34 -04001842#SeeAlso save() restore() saveLayer saveLayerPreserveLCDTextRequests saveLayerAlpha
1843
Cary Clarkce101242017-09-01 15:51:02 -04001844##
1845
1846#Method SaveLayerRec(const SkRect* bounds, const SkPaint* paint, SaveLayerFlags saveLayerFlags = 0)
1847
1848Sets fBounds, fPaint, and fSaveLayerFlags; sets fBackdrop to nullptr.
1849
1850#Param bounds Layer dimensions; may be nullptr ##
1851#Param paint applied to Layer when overlaying prior Layer; may be nullptr ##
1852#Param saveLayerFlags SaveLayerRec options to modify Layer ##
1853
1854#Return SaveLayerRec with empty backdrop ##
1855
1856#Example
1857 SkCanvas::SaveLayerRec rec1;
1858 SkCanvas::SaveLayerRec rec2(nullptr, nullptr);
1859 SkDebugf("rec1 %c= rec2\n", rec1.fBounds == rec2.fBounds
1860 && rec1.fPaint == rec2.fPaint
1861 && rec1.fBackdrop == rec2.fBackdrop
1862 && rec1.fSaveLayerFlags == rec2.fSaveLayerFlags ? '=' : '!');
1863 #StdOut
1864 rec1 == rec2
1865 ##
1866##
1867
Cary Clark2ade9972017-11-02 17:49:34 -04001868#SeeAlso save() restore() saveLayer saveLayerPreserveLCDTextRequests saveLayerAlpha
1869
Cary Clarkce101242017-09-01 15:51:02 -04001870##
1871
1872#Method SaveLayerRec(const SkRect* bounds, const SkPaint* paint, const SkImageFilter* backdrop,
1873 SaveLayerFlags saveLayerFlags)
1874
1875Sets fBounds, fPaint, fBackdrop, and fSaveLayerFlags.
1876
1877#Param bounds Layer dimensions; may be nullptr ##
1878#Param paint applied to Layer when overlaying prior Layer;
1879 may be nullptr
1880##
1881#Param backdrop prior Layer copied with Image_Filter; may be nullptr
1882##
1883#Param saveLayerFlags SaveLayerRec options to modify Layer ##
1884
1885#Return SaveLayerRec fully specified ##
1886
1887#Example
1888 SkCanvas::SaveLayerRec rec1;
1889 SkCanvas::SaveLayerRec rec2(nullptr, nullptr, nullptr, 0);
1890 SkDebugf("rec1 %c= rec2\n", rec1.fBounds == rec2.fBounds
1891 && rec1.fPaint == rec2.fPaint
1892 && rec1.fBackdrop == rec2.fBackdrop
1893 && rec1.fSaveLayerFlags == rec2.fSaveLayerFlags ? '=' : '!');
1894 #StdOut
1895 rec1 == rec2
1896 ##
1897##
1898
Cary Clark2ade9972017-11-02 17:49:34 -04001899#SeeAlso save() restore() saveLayer saveLayerPreserveLCDTextRequests saveLayerAlpha
1900
Cary Clarkce101242017-09-01 15:51:02 -04001901##
1902
1903#Method SaveLayerRec(const SkRect* bounds, const SkPaint* paint, const SkImageFilter* backdrop,
1904 const SkImage* clipMask, const SkMatrix* clipMatrix,
1905 SaveLayerFlags saveLayerFlags)
1906
1907#Experimental
1908Not ready for general use.
1909##
1910
1911Sets fBounds, fPaint, fBackdrop, fClipMask, fClipMatrix, and fSaveLayerFlags.
1912clipMatrix uses Color_Alpha channel of image, transformed by clipMatrix, to clip
1913Layer when drawn to Canvas.
1914
Cary Clark2ade9972017-11-02 17:49:34 -04001915Implementation is not complete; has no effect if Device is GPU-backed.
Cary Clarkce101242017-09-01 15:51:02 -04001916
1917#Param bounds Layer dimensions; may be nullptr ##
1918#Param paint graphics state applied to Layer when overlaying prior
1919 Layer; may be nullptr
1920##
1921#Param backdrop prior Layer copied with Image_Filter;
1922 may be nullptr
1923##
1924#Param clipMask clip applied to Layer; may be nullptr ##
1925#Param clipMatrix matrix applied to clipMask; may be nullptr to use
1926 identity matrix
1927##
1928#Param saveLayerFlags SaveLayerRec options to modify Layer ##
1929
1930#Return SaveLayerRec fully specified ##
1931
Cary Clark2ade9972017-11-02 17:49:34 -04001932#SeeAlso save() restore() saveLayer saveLayerPreserveLCDTextRequests saveLayerAlpha
Cary Clarkce101242017-09-01 15:51:02 -04001933
1934##
1935
1936#Struct ##
1937
1938#Method int saveLayer(const SaveLayerRec& layerRec)
1939
Cary Clarkab2621d2018-01-30 10:08:57 -05001940#In Layer
Cary Clarkce101242017-09-01 15:51:02 -04001941Saves Matrix, Clip, and Draw_Filter (Draw_Filter deprecated on most platforms),
1942and allocates Bitmap for subsequent drawing.
1943
1944Calling restore() discards changes to Matrix, Clip, and Draw_Filter,
1945and blends Bitmap with Color_Alpha opacity onto the prior Layer.
1946
1947Matrix may be changed by translate(), scale(), rotate(), skew(), concat(),
1948setMatrix, and resetMatrix. Clip may be changed by clipRect, clipRRect,
1949clipPath, clipRegion.
1950
1951SaveLayerRec contains the state used to create the Layer.
1952
1953Call restoreToCount with returned value to restore this and subsequent saves.
1954
1955#Param layerRec Layer state ##
1956
1957#Return depth of save state stack ##
1958
1959#Example
1960#Description
1961The example draws an image, and saves it into a Layer with kInitWithPrevious_SaveLayerFlag.
1962Next it punches a hole in Layer and restore with SkBlendMode::kPlus.
1963Where Layer was cleared, the original image will draw unchanged.
1964Outside of the circle the mandrill is brightened.
1965##
1966 #Image 3
Hal Canaryc465d132017-12-08 10:21:31 -05001967 // sk_sp<SkImage> image = GetResourceAsImage("images/mandrill_256.png");
Cary Clarkce101242017-09-01 15:51:02 -04001968 canvas->drawImage(image, 0, 0, nullptr);
1969 SkCanvas::SaveLayerRec rec;
1970 SkPaint paint;
1971 paint.setBlendMode(SkBlendMode::kPlus);
1972 rec.fSaveLayerFlags = SkCanvas::kInitWithPrevious_SaveLayerFlag;
1973 rec.fPaint = &paint;
1974 canvas->saveLayer(rec);
1975 paint.setBlendMode(SkBlendMode::kClear);
1976 canvas->drawCircle(128, 128, 96, paint);
1977 canvas->restore();
1978##
1979
1980#ToDo above example needs to replace GetResourceAsImage with way to select image in fiddle ##
1981
Cary Clark2ade9972017-11-02 17:49:34 -04001982#SeeAlso save() restore() saveLayer saveLayerPreserveLCDTextRequests saveLayerAlpha
1983
Cary Clarkce101242017-09-01 15:51:02 -04001984##
1985
Cary Clark08895c42018-02-01 09:37:32 -05001986#Subtopic Layer ##
Cary Clarkce101242017-09-01 15:51:02 -04001987
1988# ------------------------------------------------------------------------------
Cary Clark08895c42018-02-01 09:37:32 -05001989#Subtopic Matrix
1990#Line # coordinate transformation ##
Cary Clark8032b982017-07-28 11:04:54 -04001991
1992#Method void translate(SkScalar dx, SkScalar dy)
1993
Cary Clarkab2621d2018-01-30 10:08:57 -05001994#In Matrix
1995#Line # translates Matrix ##
Cary Clark8032b982017-07-28 11:04:54 -04001996Translate Matrix by dx along the x-axis and dy along the y-axis.
1997
1998Mathematically, replace Matrix with a translation matrix
Cary Clarkce101242017-09-01 15:51:02 -04001999Premultiplied with Matrix.
Cary Clark8032b982017-07-28 11:04:54 -04002000
2001This has the effect of moving the drawing by (dx, dy) before transforming
2002the result with Matrix.
2003
Cary Clarkbad5ad72017-08-03 17:14:08 -04002004#Param dx distance to translate in x ##
2005#Param dy distance to translate in y ##
Cary Clark8032b982017-07-28 11:04:54 -04002006
2007#Example
2008#Height 128
2009#Description
2010scale() followed by translate() produces different results from translate() followed
2011by scale().
2012
2013The blue stroke follows translate of (50, 50); a black
2014fill follows scale of (2, 1/2.f). After restoring the clip, which resets
2015Matrix, a red frame follows the same scale of (2, 1/2.f); a gray fill
2016follows translate of (50, 50).
2017##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002018void draw(SkCanvas* canvas) {
2019 SkPaint filledPaint;
2020 SkPaint outlinePaint;
2021 outlinePaint.setStyle(SkPaint::kStroke_Style);
2022 outlinePaint.setColor(SK_ColorBLUE);
2023 canvas->save();
2024 canvas->translate(50, 50);
2025 canvas->drawCircle(28, 28, 15, outlinePaint); // blue center: (50+28, 50+28)
2026 canvas->scale(2, 1/2.f);
2027 canvas->drawCircle(28, 28, 15, filledPaint); // black center: (50+(28*2), 50+(28/2))
2028 canvas->restore();
2029 filledPaint.setColor(SK_ColorGRAY);
2030 outlinePaint.setColor(SK_ColorRED);
2031 canvas->scale(2, 1/2.f);
2032 canvas->drawCircle(28, 28, 15, outlinePaint); // red center: (28*2, 28/2)
2033 canvas->translate(50, 50);
2034 canvas->drawCircle(28, 28, 15, filledPaint); // gray center: ((50+28)*2, (50+28)/2)
Cary Clark8032b982017-07-28 11:04:54 -04002035}
2036##
2037
Cary Clark2ade9972017-11-02 17:49:34 -04002038#SeeAlso concat() scale() skew() rotate() setMatrix
Cary Clark8032b982017-07-28 11:04:54 -04002039
2040##
2041
2042# ------------------------------------------------------------------------------
2043
2044#Method void scale(SkScalar sx, SkScalar sy)
2045
Cary Clarkab2621d2018-01-30 10:08:57 -05002046#In Matrix
2047#Line # scales Matrix ##
Cary Clark8032b982017-07-28 11:04:54 -04002048Scale Matrix by sx on the x-axis and sy on the y-axis.
2049
2050Mathematically, replace Matrix with a scale matrix
Cary Clarkce101242017-09-01 15:51:02 -04002051Premultiplied with Matrix.
Cary Clark8032b982017-07-28 11:04:54 -04002052
2053This has the effect of scaling the drawing by (sx, sy) before transforming
2054the result with Matrix.
2055
Cary Clarkbad5ad72017-08-03 17:14:08 -04002056#Param sx amount to scale in x ##
2057#Param sy amount to scale in y ##
Cary Clark8032b982017-07-28 11:04:54 -04002058
2059#Example
2060#Height 160
Cary Clarkbad5ad72017-08-03 17:14:08 -04002061void draw(SkCanvas* canvas) {
2062 SkPaint paint;
2063 SkRect rect = { 10, 20, 60, 120 };
2064 canvas->translate(20, 20);
2065 canvas->drawRect(rect, paint);
2066 canvas->scale(2, .5f);
2067 paint.setColor(SK_ColorGRAY);
2068 canvas->drawRect(rect, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002069}
2070##
2071
Cary Clark2ade9972017-11-02 17:49:34 -04002072#SeeAlso concat() translate() skew() rotate() setMatrix
Cary Clark8032b982017-07-28 11:04:54 -04002073
2074##
2075
2076# ------------------------------------------------------------------------------
2077
2078#Method void rotate(SkScalar degrees)
2079
Cary Clarkab2621d2018-01-30 10:08:57 -05002080#In Matrix
2081#Line # rotates Matrix ##
Cary Clark8032b982017-07-28 11:04:54 -04002082Rotate Matrix by degrees. Positive degrees rotates clockwise.
2083
2084Mathematically, replace Matrix with a rotation matrix
Cary Clarkce101242017-09-01 15:51:02 -04002085Premultiplied with Matrix.
Cary Clark8032b982017-07-28 11:04:54 -04002086
2087This has the effect of rotating the drawing by degrees before transforming
2088the result with Matrix.
2089
Cary Clarkbad5ad72017-08-03 17:14:08 -04002090#Param degrees amount to rotate, in degrees ##
Cary Clark8032b982017-07-28 11:04:54 -04002091
2092#Example
2093#Description
2094Draw clock hands at time 5:10. The hour hand and minute hand point up and
2095are rotated clockwise.
2096##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002097void draw(SkCanvas* canvas) {
2098 SkPaint paint;
2099 paint.setStyle(SkPaint::kStroke_Style);
2100 canvas->translate(128, 128);
2101 canvas->drawCircle(0, 0, 60, paint);
2102 canvas->save();
2103 canvas->rotate(10 * 360 / 60); // 10 minutes of 60 scaled to 360 degrees
2104 canvas->drawLine(0, 0, 0, -50, paint);
2105 canvas->restore();
2106 canvas->rotate((5 + 10.f/60) * 360 / 12); // 5 and 10/60 hours of 12 scaled to 360 degrees
2107 canvas->drawLine(0, 0, 0, -30, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002108}
2109##
2110
Cary Clark2ade9972017-11-02 17:49:34 -04002111#SeeAlso concat() translate() skew() scale() setMatrix
Cary Clark8032b982017-07-28 11:04:54 -04002112
2113##
2114
2115# ------------------------------------------------------------------------------
2116
2117#Method void rotate(SkScalar degrees, SkScalar px, SkScalar py)
2118
Cary Clarkab2621d2018-01-30 10:08:57 -05002119#In Matrix
Cary Clarkbad5ad72017-08-03 17:14:08 -04002120Rotate Matrix by degrees about a point at (px, py). Positive degrees rotates
2121clockwise.
Cary Clark8032b982017-07-28 11:04:54 -04002122
Cary Clarkce101242017-09-01 15:51:02 -04002123Mathematically, construct a rotation matrix. Premultiply the rotation matrix by
Cary Clark8032b982017-07-28 11:04:54 -04002124a translation matrix, then replace Matrix with the resulting matrix
Cary Clarkce101242017-09-01 15:51:02 -04002125Premultiplied with Matrix.
Cary Clark8032b982017-07-28 11:04:54 -04002126
Cary Clarkbad5ad72017-08-03 17:14:08 -04002127This has the effect of rotating the drawing about a given point before
2128transforming the result with Matrix.
Cary Clark8032b982017-07-28 11:04:54 -04002129
Cary Clarkbad5ad72017-08-03 17:14:08 -04002130#Param degrees amount to rotate, in degrees ##
2131#Param px x-coordinate of the point to rotate about ##
2132#Param py y-coordinate of the point to rotate about ##
Cary Clark8032b982017-07-28 11:04:54 -04002133
2134#Example
2135#Height 192
Cary Clarkbad5ad72017-08-03 17:14:08 -04002136void draw(SkCanvas* canvas) {
2137 SkPaint paint;
2138 paint.setTextSize(96);
2139 canvas->drawString("A1", 130, 100, paint);
2140 canvas->rotate(180, 130, 100);
2141 canvas->drawString("A1", 130, 100, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002142}
2143##
2144
Cary Clark2ade9972017-11-02 17:49:34 -04002145#SeeAlso concat() translate() skew() scale() setMatrix
Cary Clark8032b982017-07-28 11:04:54 -04002146
2147##
2148
2149# ------------------------------------------------------------------------------
2150
2151#Method void skew(SkScalar sx, SkScalar sy)
2152
Cary Clarkab2621d2018-01-30 10:08:57 -05002153#In Matrix
2154#Line # skews Matrix ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002155Skew Matrix by sx on the x-axis and sy on the y-axis. A positive value of sx
2156skews the drawing right as y increases; a positive value of sy skews the drawing
2157down as x increases.
Cary Clark8032b982017-07-28 11:04:54 -04002158
Cary Clarkce101242017-09-01 15:51:02 -04002159Mathematically, replace Matrix with a skew matrix Premultiplied with Matrix.
Cary Clark8032b982017-07-28 11:04:54 -04002160
Cary Clarkbad5ad72017-08-03 17:14:08 -04002161This has the effect of skewing the drawing by (sx, sy) before transforming
Cary Clark8032b982017-07-28 11:04:54 -04002162the result with Matrix.
2163
Cary Clarkbad5ad72017-08-03 17:14:08 -04002164#Param sx amount to skew in x ##
2165#Param sy amount to skew in y ##
2166
Cary Clark8032b982017-07-28 11:04:54 -04002167#Example
2168 #Description
2169 Black text mimics an oblique text style by using a negative skew in x that
2170 shifts the geometry to the right as the y values decrease.
2171 Red text uses a positive skew in y to shift the geometry down as the x values
2172 increase.
2173 Blue text combines x and y skew to rotate and scale.
2174 ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002175 SkPaint paint;
2176 paint.setTextSize(128);
2177 canvas->translate(30, 130);
2178 canvas->save();
2179 canvas->skew(-.5, 0);
2180 canvas->drawString("A1", 0, 0, paint);
2181 canvas->restore();
2182 canvas->save();
2183 canvas->skew(0, .5);
2184 paint.setColor(SK_ColorRED);
2185 canvas->drawString("A1", 0, 0, paint);
2186 canvas->restore();
2187 canvas->skew(-.5, .5);
2188 paint.setColor(SK_ColorBLUE);
Cary Clark8032b982017-07-28 11:04:54 -04002189 canvas->drawString("A1", 0, 0, paint);
2190##
2191
Cary Clark2ade9972017-11-02 17:49:34 -04002192#SeeAlso concat() translate() rotate() scale() setMatrix
Cary Clark8032b982017-07-28 11:04:54 -04002193
2194##
2195
2196# ------------------------------------------------------------------------------
2197
2198#Method void concat(const SkMatrix& matrix)
2199
Cary Clarkab2621d2018-01-30 10:08:57 -05002200#In Matrix
2201#Line # multiplies Matrix by Matrix ##
Cary Clarkce101242017-09-01 15:51:02 -04002202Replace Matrix with matrix Premultiplied with existing Matrix.
Cary Clark8032b982017-07-28 11:04:54 -04002203
Cary Clarkbad5ad72017-08-03 17:14:08 -04002204This has the effect of transforming the drawn geometry by matrix, before
2205transforming the result with existing Matrix.
Cary Clark8032b982017-07-28 11:04:54 -04002206
Cary Clarkce101242017-09-01 15:51:02 -04002207#Param matrix matrix to Premultiply with existing Matrix ##
Cary Clark8032b982017-07-28 11:04:54 -04002208
2209#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04002210void draw(SkCanvas* canvas) {
2211 SkPaint paint;
2212 paint.setTextSize(80);
2213 paint.setTextScaleX(.3);
2214 SkMatrix matrix;
2215 SkRect rect[2] = {{ 10, 20, 90, 110 }, { 40, 130, 140, 180 }};
2216 matrix.setRectToRect(rect[0], rect[1], SkMatrix::kFill_ScaleToFit);
2217 canvas->drawRect(rect[0], paint);
2218 canvas->drawRect(rect[1], paint);
2219 paint.setColor(SK_ColorWHITE);
2220 canvas->drawString("Here", rect[0].fLeft + 10, rect[0].fBottom - 10, paint);
2221 canvas->concat(matrix);
2222 canvas->drawString("There", rect[0].fLeft + 10, rect[0].fBottom - 10, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002223}
2224##
2225
Cary Clark2ade9972017-11-02 17:49:34 -04002226#SeeAlso translate() rotate() scale() skew() setMatrix
Cary Clark8032b982017-07-28 11:04:54 -04002227
2228##
2229
2230# ------------------------------------------------------------------------------
2231
2232#Method void setMatrix(const SkMatrix& matrix)
2233
Cary Clarkab2621d2018-01-30 10:08:57 -05002234#In Matrix
2235#Line # sets Matrix ##
Cary Clark8032b982017-07-28 11:04:54 -04002236Replace Matrix with matrix.
2237Unlike concat(), any prior matrix state is overwritten.
2238
Cary Clarkbad5ad72017-08-03 17:14:08 -04002239#Param matrix matrix to copy, replacing existing Matrix ##
Cary Clark8032b982017-07-28 11:04:54 -04002240
2241#Example
2242#Height 128
Cary Clarkbad5ad72017-08-03 17:14:08 -04002243void draw(SkCanvas* canvas) {
2244 SkPaint paint;
2245 canvas->scale(4, 6);
2246 canvas->drawString("truth", 2, 10, paint);
2247 SkMatrix matrix;
2248 matrix.setScale(2.8f, 6);
2249 canvas->setMatrix(matrix);
2250 canvas->drawString("consequences", 2, 20, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002251}
2252##
2253
Cary Clark2ade9972017-11-02 17:49:34 -04002254#SeeAlso resetMatrix concat() translate() rotate() scale() skew()
Cary Clark8032b982017-07-28 11:04:54 -04002255
2256##
2257
2258# ------------------------------------------------------------------------------
2259
2260#Method void resetMatrix()
2261
Cary Clarkab2621d2018-01-30 10:08:57 -05002262#In Matrix
2263#Line # resets Matrix to identity ##
Cary Clark8032b982017-07-28 11:04:54 -04002264Sets Matrix to the identity matrix.
2265Any prior matrix state is overwritten.
2266
2267#Example
2268#Height 128
Cary Clarkbad5ad72017-08-03 17:14:08 -04002269void draw(SkCanvas* canvas) {
2270 SkPaint paint;
2271 canvas->scale(4, 6);
2272 canvas->drawString("truth", 2, 10, paint);
2273 canvas->resetMatrix();
2274 canvas->scale(2.8f, 6);
2275 canvas->drawString("consequences", 2, 20, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002276}
2277##
2278
Cary Clark2ade9972017-11-02 17:49:34 -04002279#SeeAlso setMatrix concat() translate() rotate() scale() skew()
Cary Clark8032b982017-07-28 11:04:54 -04002280
2281##
2282
2283# ------------------------------------------------------------------------------
2284
2285#Method const SkMatrix& getTotalMatrix() const
2286
Cary Clarkab2621d2018-01-30 10:08:57 -05002287#In Matrix
2288#Line # returns Matrix ##
Cary Clark8032b982017-07-28 11:04:54 -04002289Returns Matrix.
2290This does not account for translation by Device or Surface.
2291
Cary Clarkbad5ad72017-08-03 17:14:08 -04002292#Return Matrix in Canvas ##
Cary Clark8032b982017-07-28 11:04:54 -04002293
2294#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04002295 SkDebugf("isIdentity %s\n", canvas->getTotalMatrix().isIdentity() ? "true" : "false");
2296 #StdOut
2297 isIdentity true
2298 ##
Cary Clark8032b982017-07-28 11:04:54 -04002299##
2300
Cary Clark2ade9972017-11-02 17:49:34 -04002301#SeeAlso setMatrix resetMatrix concat()
Cary Clark8032b982017-07-28 11:04:54 -04002302
2303##
2304
Cary Clark08895c42018-02-01 09:37:32 -05002305#Subtopic Matrix ##
Cary Clark8032b982017-07-28 11:04:54 -04002306
2307# ------------------------------------------------------------------------------
Cary Clark08895c42018-02-01 09:37:32 -05002308#Subtopic Clip
2309#Line # stack of clipping Paths ##
Cary Clark8032b982017-07-28 11:04:54 -04002310
2311Clip is built from a stack of clipping paths. Each Path in the
2312stack can be constructed from one or more Path_Contour elements. The
2313Path_Contour may be composed of any number of Path_Verb segments. Each
2314Path_Contour forms a closed area; Path_Fill_Type defines the area enclosed
2315by Path_Contour.
2316
2317Clip stack of Path elements successfully restrict the Path area. Each
2318Path is transformed by Matrix, then intersected with or subtracted from the
2319prior Clip to form the replacement Clip. Use SkClipOp::kDifference
2320to subtract Path from Clip; use SkClipOp::kIntersect to intersect Path
2321with Clip.
2322
Cary Clarkce101242017-09-01 15:51:02 -04002323A clipping Path may be Anti-aliased; if Path, after transformation, is
Cary Clark8032b982017-07-28 11:04:54 -04002324composed of horizontal and vertical lines, clearing Anti-alias allows whole pixels
Cary Clarkce101242017-09-01 15:51:02 -04002325to either be inside or outside the clip. The fastest drawing has a Aliased,
2326rectangular clip.
Cary Clark8032b982017-07-28 11:04:54 -04002327
2328If clipping Path has Anti-alias set, clip may partially clip a pixel, requiring
2329that drawing blend partially with the destination along the edge. A rotated
Cary Clarkce101242017-09-01 15:51:02 -04002330rectangular Anti-aliased clip looks smoother but draws slower.
Cary Clark8032b982017-07-28 11:04:54 -04002331
2332Clip can combine with Rect and Round_Rect primitives; like
2333Path, these are transformed by Matrix before they are combined with Clip.
2334
2335Clip can combine with Region. Region is assumed to be in Device coordinates
2336and is unaffected by Matrix.
2337
2338#Example
2339#Height 90
2340 #Description
Cary Clarkce101242017-09-01 15:51:02 -04002341 Draw a red circle with an Aliased clip and an Anti-aliased clip.
Cary Clark8032b982017-07-28 11:04:54 -04002342 Use an image filter to zoom into the pixels drawn.
Cary Clarkce101242017-09-01 15:51:02 -04002343 The edge of the Aliased clip fully draws pixels in the red circle.
2344 The edge of the Anti-aliased clip partially draws pixels in the red circle.
Cary Clark8032b982017-07-28 11:04:54 -04002345 ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002346 SkPaint redPaint, scalePaint;
2347 redPaint.setAntiAlias(true);
2348 redPaint.setColor(SK_ColorRED);
2349 canvas->save();
2350 for (bool antialias : { false, true } ) {
2351 canvas->save();
2352 canvas->clipRect(SkRect::MakeWH(19.5f, 11.5f), antialias);
2353 canvas->drawCircle(17, 11, 8, redPaint);
2354 canvas->restore();
2355 canvas->translate(16, 0);
2356 }
2357 canvas->restore();
2358 SkMatrix matrix;
2359 matrix.setScale(6, 6);
2360 scalePaint.setImageFilter(
2361 SkImageFilter::MakeMatrixFilter(matrix, kNone_SkFilterQuality, nullptr));
2362 SkCanvas::SaveLayerRec saveLayerRec(
2363 nullptr, &scalePaint, SkCanvas::kInitWithPrevious_SaveLayerFlag);
2364 canvas->saveLayer(saveLayerRec);
Cary Clark8032b982017-07-28 11:04:54 -04002365 canvas->restore();
2366##
2367
2368#Method void clipRect(const SkRect& rect, SkClipOp op, bool doAntiAlias)
2369
Cary Clarkab2621d2018-01-30 10:08:57 -05002370#In Clip
2371#Line # combines Clip with Rect ##
Cary Clark8032b982017-07-28 11:04:54 -04002372Replace Clip with the intersection or difference of Clip and rect,
Cary Clarkce101242017-09-01 15:51:02 -04002373with an Aliased or Anti-aliased clip edge. rect is transformed by Matrix
Cary Clark8032b982017-07-28 11:04:54 -04002374before it is combined with Clip.
2375
Cary Clarka523d2d2017-08-30 08:58:10 -04002376#Param rect Rect to combine with Clip ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002377#Param op Clip_Op to apply to Clip ##
Cary Clarkce101242017-09-01 15:51:02 -04002378#Param doAntiAlias true if Clip is to be Anti-aliased ##
Cary Clark8032b982017-07-28 11:04:54 -04002379
2380#Example
2381#Height 128
Cary Clarkbad5ad72017-08-03 17:14:08 -04002382void draw(SkCanvas* canvas) {
2383 canvas->rotate(10);
2384 SkPaint paint;
2385 paint.setAntiAlias(true);
2386 for (auto alias: { false, true } ) {
2387 canvas->save();
2388 canvas->clipRect(SkRect::MakeWH(90, 80), SkClipOp::kIntersect, alias);
2389 canvas->drawCircle(100, 60, 60, paint);
2390 canvas->restore();
2391 canvas->translate(80, 0);
2392 }
Cary Clark8032b982017-07-28 11:04:54 -04002393}
2394##
2395
Cary Clark2ade9972017-11-02 17:49:34 -04002396#SeeAlso clipRRect clipPath clipRegion
Cary Clark8032b982017-07-28 11:04:54 -04002397
2398##
2399
2400#Method void clipRect(const SkRect& rect, SkClipOp op)
2401
Cary Clarkab2621d2018-01-30 10:08:57 -05002402#In Clip
Cary Clark8032b982017-07-28 11:04:54 -04002403Replace Clip with the intersection or difference of Clip and rect.
Cary Clarkce101242017-09-01 15:51:02 -04002404Resulting Clip is Aliased; pixels are fully contained by the clip.
Cary Clarkbad5ad72017-08-03 17:14:08 -04002405rect is transformed by Matrix before it is combined with Clip.
Cary Clark8032b982017-07-28 11:04:54 -04002406
Cary Clarka523d2d2017-08-30 08:58:10 -04002407#Param rect Rect to combine with Clip ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002408#Param op Clip_Op to apply to Clip ##
Cary Clark8032b982017-07-28 11:04:54 -04002409
2410#Example
2411#Height 192
2412#Width 280
Cary Clarkbad5ad72017-08-03 17:14:08 -04002413void draw(SkCanvas* canvas) {
2414 SkPaint paint;
2415 for (SkClipOp op: { SkClipOp::kIntersect, SkClipOp::kDifference } ) {
2416 canvas->save();
2417 canvas->clipRect(SkRect::MakeWH(90, 120), op, false);
2418 canvas->drawCircle(100, 100, 60, paint);
2419 canvas->restore();
2420 canvas->translate(80, 0);
2421 }
Cary Clark8032b982017-07-28 11:04:54 -04002422}
2423##
2424
Cary Clark2ade9972017-11-02 17:49:34 -04002425#SeeAlso clipRRect clipPath clipRegion
Cary Clark8032b982017-07-28 11:04:54 -04002426
2427##
2428
2429#Method void clipRect(const SkRect& rect, bool doAntiAlias = false)
2430
Cary Clarkab2621d2018-01-30 10:08:57 -05002431#In Clip
Cary Clark8032b982017-07-28 11:04:54 -04002432Replace Clip with the intersection of Clip and rect.
Cary Clarkce101242017-09-01 15:51:02 -04002433Resulting Clip is Aliased; pixels are fully contained by the clip.
Cary Clark8032b982017-07-28 11:04:54 -04002434rect is transformed by Matrix
2435before it is combined with Clip.
2436
Cary Clarka523d2d2017-08-30 08:58:10 -04002437#Param rect Rect to combine with Clip ##
Cary Clarkce101242017-09-01 15:51:02 -04002438#Param doAntiAlias true if Clip is to be Anti-aliased ##
Cary Clark8032b982017-07-28 11:04:54 -04002439
2440#Example
2441#Height 133
2442 #Description
Cary Clarkce101242017-09-01 15:51:02 -04002443 A circle drawn in pieces looks uniform when drawn Aliased.
2444 The same circle pieces blend with pixels more than once when Anti-aliased,
Cary Clark8032b982017-07-28 11:04:54 -04002445 visible as a thin pair of lines through the right circle.
2446 ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002447void draw(SkCanvas* canvas) {
2448 canvas->clear(SK_ColorWHITE);
2449 SkPaint paint;
2450 paint.setAntiAlias(true);
2451 paint.setColor(0x8055aaff);
2452 SkRect clipRect = { 0, 0, 87.4f, 87.4f };
2453 for (auto alias: { false, true } ) {
2454 canvas->save();
2455 canvas->clipRect(clipRect, SkClipOp::kIntersect, alias);
2456 canvas->drawCircle(67, 67, 60, paint);
2457 canvas->restore();
2458 canvas->save();
2459 canvas->clipRect(clipRect, SkClipOp::kDifference, alias);
2460 canvas->drawCircle(67, 67, 60, paint);
2461 canvas->restore();
2462 canvas->translate(120, 0);
2463 }
Cary Clark8032b982017-07-28 11:04:54 -04002464}
2465##
2466
Cary Clark2ade9972017-11-02 17:49:34 -04002467#SeeAlso clipRRect clipPath clipRegion
Cary Clark8032b982017-07-28 11:04:54 -04002468
2469##
2470
2471#Method void androidFramework_setDeviceClipRestriction(const SkIRect& rect)
2472
Cary Clarkab2621d2018-01-30 10:08:57 -05002473#In Clip
2474#Line # for use by Android framework ##
Cary Clarkce101242017-09-01 15:51:02 -04002475Sets the maximum clip rectangle, which can be set by clipRect, clipRRect and
Cary Clark8032b982017-07-28 11:04:54 -04002476clipPath and intersect the current clip with the specified rect.
Cary Clarkce101242017-09-01 15:51:02 -04002477The maximum clip affects only future clipping operations; it is not retroactive.
Cary Clark8032b982017-07-28 11:04:54 -04002478The clip restriction is not recorded in pictures.
2479
Cary Clarkce101242017-09-01 15:51:02 -04002480Pass an empty rect to disable maximum clip.
Cary Clarkbad5ad72017-08-03 17:14:08 -04002481
Cary Clark8032b982017-07-28 11:04:54 -04002482#Private
2483This is private API to be used only by Android framework.
2484##
2485
Cary Clarkbad5ad72017-08-03 17:14:08 -04002486#Param rect maximum allowed clip in device coordinates
Cary Clark579985c2017-07-31 11:48:27 -04002487#Param ##
Cary Clark8032b982017-07-28 11:04:54 -04002488
2489##
2490
2491#Method void clipRRect(const SkRRect& rrect, SkClipOp op, bool doAntiAlias)
2492
Cary Clarkab2621d2018-01-30 10:08:57 -05002493#In Clip
2494#Line # combines Clip with Round_Rect ##
Cary Clark8032b982017-07-28 11:04:54 -04002495Replace Clip with the intersection or difference of Clip and rrect,
Cary Clarkce101242017-09-01 15:51:02 -04002496with an Aliased or Anti-aliased clip edge.
Cary Clark8032b982017-07-28 11:04:54 -04002497rrect is transformed by Matrix
2498before it is combined with Clip.
2499
Cary Clarkbad5ad72017-08-03 17:14:08 -04002500#Param rrect Round_Rect to combine with Clip ##
2501#Param op Clip_Op to apply to Clip ##
Cary Clarkce101242017-09-01 15:51:02 -04002502#Param doAntiAlias true if Clip is to be Anti-aliased ##
Cary Clark8032b982017-07-28 11:04:54 -04002503
2504#Example
2505#Height 128
Cary Clarkbad5ad72017-08-03 17:14:08 -04002506void draw(SkCanvas* canvas) {
2507 canvas->clear(SK_ColorWHITE);
2508 SkPaint paint;
2509 paint.setAntiAlias(true);
2510 paint.setColor(0x8055aaff);
2511 SkRRect oval;
2512 oval.setOval({10, 20, 90, 100});
2513 canvas->clipRRect(oval, SkClipOp::kIntersect, true);
2514 canvas->drawCircle(70, 100, 60, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002515}
2516##
2517
Cary Clark2ade9972017-11-02 17:49:34 -04002518#SeeAlso clipRect clipPath clipRegion
Cary Clark8032b982017-07-28 11:04:54 -04002519
2520##
2521
2522#Method void clipRRect(const SkRRect& rrect, SkClipOp op)
2523
Cary Clarkab2621d2018-01-30 10:08:57 -05002524#In Clip
Cary Clark8032b982017-07-28 11:04:54 -04002525Replace Clip with the intersection or difference of Clip and rrect.
Cary Clarkce101242017-09-01 15:51:02 -04002526Resulting Clip is Aliased; pixels are fully contained by the clip.
Cary Clarkbad5ad72017-08-03 17:14:08 -04002527rrect is transformed by Matrix before it is combined with Clip.
Cary Clark8032b982017-07-28 11:04:54 -04002528
Cary Clarkbad5ad72017-08-03 17:14:08 -04002529#Param rrect Round_Rect to combine with Clip ##
2530#Param op Clip_Op to apply to Clip ##
Cary Clark8032b982017-07-28 11:04:54 -04002531
2532#Example
2533#Height 128
Cary Clarkbad5ad72017-08-03 17:14:08 -04002534void draw(SkCanvas* canvas) {
2535 SkPaint paint;
2536 paint.setColor(0x8055aaff);
2537 auto oval = SkRRect::MakeOval({10, 20, 90, 100});
2538 canvas->clipRRect(oval, SkClipOp::kIntersect);
2539 canvas->drawCircle(70, 100, 60, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002540}
2541##
2542
Cary Clark2ade9972017-11-02 17:49:34 -04002543#SeeAlso clipRect clipPath clipRegion
Cary Clark8032b982017-07-28 11:04:54 -04002544
2545##
2546
2547#Method void clipRRect(const SkRRect& rrect, bool doAntiAlias = false)
2548
Cary Clarkab2621d2018-01-30 10:08:57 -05002549#In Clip
Cary Clark8032b982017-07-28 11:04:54 -04002550Replace Clip with the intersection of Clip and rrect,
Cary Clarkce101242017-09-01 15:51:02 -04002551with an Aliased or Anti-aliased clip edge.
Cary Clarkbad5ad72017-08-03 17:14:08 -04002552rrect is transformed by Matrix before it is combined with Clip.
Cary Clark8032b982017-07-28 11:04:54 -04002553
Cary Clarkbad5ad72017-08-03 17:14:08 -04002554#Param rrect Round_Rect to combine with Clip ##
Cary Clarkce101242017-09-01 15:51:02 -04002555#Param doAntiAlias true if Clip is to be Anti-aliased ##
Cary Clark8032b982017-07-28 11:04:54 -04002556
2557#Example
2558#Height 128
Cary Clarkbad5ad72017-08-03 17:14:08 -04002559void draw(SkCanvas* canvas) {
2560 SkPaint paint;
2561 paint.setAntiAlias(true);
2562 auto oval = SkRRect::MakeRectXY({10, 20, 90, 100}, 9, 13);
2563 canvas->clipRRect(oval, true);
2564 canvas->drawCircle(70, 100, 60, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002565}
2566##
2567
Cary Clark2ade9972017-11-02 17:49:34 -04002568#SeeAlso clipRect clipPath clipRegion
Cary Clark8032b982017-07-28 11:04:54 -04002569
2570##
2571
2572#Method void clipPath(const SkPath& path, SkClipOp op, bool doAntiAlias)
2573
Cary Clarkab2621d2018-01-30 10:08:57 -05002574#In Clip
2575#Line # combines Clip with Path ##
Cary Clark8032b982017-07-28 11:04:54 -04002576Replace Clip with the intersection or difference of Clip and path,
Cary Clarkce101242017-09-01 15:51:02 -04002577with an Aliased or Anti-aliased clip edge. Path_Fill_Type determines if path
Cary Clark8032b982017-07-28 11:04:54 -04002578describes the area inside or outside its contours; and if Path_Contour overlaps
2579itself or another Path_Contour, whether the overlaps form part of the area.
Cary Clarkbad5ad72017-08-03 17:14:08 -04002580path is transformed by Matrix before it is combined with Clip.
Cary Clark8032b982017-07-28 11:04:54 -04002581
Cary Clarkbad5ad72017-08-03 17:14:08 -04002582#Param path Path to combine with Clip ##
2583#Param op Clip_Op to apply to Clip ##
Cary Clarkce101242017-09-01 15:51:02 -04002584#Param doAntiAlias true if Clip is to be Anti-aliased ##
Cary Clark8032b982017-07-28 11:04:54 -04002585
2586#Example
2587#Description
2588Top figure uses SkPath::kInverseWinding_FillType and SkClipOp::kDifference;
2589area outside clip is subtracted from circle.
2590
2591Bottom figure uses SkPath::kWinding_FillType and SkClipOp::kIntersect;
2592area inside clip is intersected with circle.
2593##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002594void draw(SkCanvas* canvas) {
2595 SkPaint paint;
2596 paint.setAntiAlias(true);
2597 SkPath path;
2598 path.addRect({20, 30, 100, 110});
2599 path.setFillType(SkPath::kInverseWinding_FillType);
2600 canvas->save();
2601 canvas->clipPath(path, SkClipOp::kDifference, false);
2602 canvas->drawCircle(70, 100, 60, paint);
2603 canvas->restore();
2604 canvas->translate(100, 100);
2605 path.setFillType(SkPath::kWinding_FillType);
2606 canvas->clipPath(path, SkClipOp::kIntersect, false);
2607 canvas->drawCircle(70, 100, 60, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002608}
2609##
2610
Cary Clark2ade9972017-11-02 17:49:34 -04002611#SeeAlso clipRect clipRRect clipRegion
Cary Clark8032b982017-07-28 11:04:54 -04002612
2613##
2614
2615#Method void clipPath(const SkPath& path, SkClipOp op)
2616
Cary Clarkab2621d2018-01-30 10:08:57 -05002617#In Clip
Cary Clark8032b982017-07-28 11:04:54 -04002618Replace Clip with the intersection or difference of Clip and path.
Cary Clarkce101242017-09-01 15:51:02 -04002619Resulting Clip is Aliased; pixels are fully contained by the clip.
Cary Clark8032b982017-07-28 11:04:54 -04002620Path_Fill_Type determines if path
2621describes the area inside or outside its contours; and if Path_Contour overlaps
2622itself or another Path_Contour, whether the overlaps form part of the area.
2623path is transformed by Matrix
2624before it is combined with Clip.
2625
Cary Clarkbad5ad72017-08-03 17:14:08 -04002626#Param path Path to combine with Clip ##
2627#Param op Clip_Op to apply to Clip ##
Cary Clark8032b982017-07-28 11:04:54 -04002628
2629#Example
2630#Description
Cary Clarkbc5697d2017-10-04 14:31:33 -04002631Overlapping Rects form a clip. When clip Path_Fill_Type is set to
Cary Clark8032b982017-07-28 11:04:54 -04002632SkPath::kWinding_FillType, the overlap is included. Set to
2633SkPath::kEvenOdd_FillType, the overlap is excluded and forms a hole.
2634##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002635void draw(SkCanvas* canvas) {
2636 SkPaint paint;
2637 paint.setAntiAlias(true);
2638 SkPath path;
2639 path.addRect({20, 15, 100, 95});
2640 path.addRect({50, 65, 130, 135});
2641 path.setFillType(SkPath::kWinding_FillType);
2642 canvas->save();
2643 canvas->clipPath(path, SkClipOp::kIntersect);
2644 canvas->drawCircle(70, 85, 60, paint);
2645 canvas->restore();
2646 canvas->translate(100, 100);
2647 path.setFillType(SkPath::kEvenOdd_FillType);
2648 canvas->clipPath(path, SkClipOp::kIntersect);
2649 canvas->drawCircle(70, 85, 60, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002650}
2651##
2652
Cary Clark2ade9972017-11-02 17:49:34 -04002653#SeeAlso clipRect clipRRect clipRegion
Cary Clark8032b982017-07-28 11:04:54 -04002654
2655##
2656
2657#Method void clipPath(const SkPath& path, bool doAntiAlias = false)
2658
Cary Clarkab2621d2018-01-30 10:08:57 -05002659#In Clip
Cary Clark8032b982017-07-28 11:04:54 -04002660Replace Clip with the intersection of Clip and path.
Cary Clarkce101242017-09-01 15:51:02 -04002661Resulting Clip is Aliased; pixels are fully contained by the clip.
Cary Clark8032b982017-07-28 11:04:54 -04002662Path_Fill_Type determines if path
2663describes the area inside or outside its contours; and if Path_Contour overlaps
2664itself or another Path_Contour, whether the overlaps form part of the area.
Cary Clarkbad5ad72017-08-03 17:14:08 -04002665path is transformed by Matrix before it is combined with Clip.
Cary Clark8032b982017-07-28 11:04:54 -04002666
Cary Clarkbad5ad72017-08-03 17:14:08 -04002667#Param path Path to combine with Clip ##
Cary Clarkce101242017-09-01 15:51:02 -04002668#Param doAntiAlias true if Clip is to be Anti-aliased ##
Cary Clark8032b982017-07-28 11:04:54 -04002669
2670#Example
2671#Height 212
2672#Description
Cary Clarkbc5697d2017-10-04 14:31:33 -04002673Clip loops over itself covering its center twice. When clip Path_Fill_Type
Cary Clark8032b982017-07-28 11:04:54 -04002674is set to SkPath::kWinding_FillType, the overlap is included. Set to
2675SkPath::kEvenOdd_FillType, the overlap is excluded and forms a hole.
2676##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002677void draw(SkCanvas* canvas) {
2678 SkPaint paint;
2679 paint.setAntiAlias(true);
2680 SkPath path;
2681 SkPoint poly[] = {{20, 20}, { 80, 20}, { 80, 80}, {40, 80},
2682 {40, 40}, {100, 40}, {100, 100}, {20, 100}};
2683 path.addPoly(poly, SK_ARRAY_COUNT(poly), true);
2684 path.setFillType(SkPath::kWinding_FillType);
2685 canvas->save();
2686 canvas->clipPath(path, SkClipOp::kIntersect);
2687 canvas->drawCircle(50, 50, 45, paint);
2688 canvas->restore();
2689 canvas->translate(100, 100);
2690 path.setFillType(SkPath::kEvenOdd_FillType);
2691 canvas->clipPath(path, SkClipOp::kIntersect);
2692 canvas->drawCircle(50, 50, 45, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002693}
2694##
2695
Cary Clark2ade9972017-11-02 17:49:34 -04002696#SeeAlso clipRect clipRRect clipRegion
Cary Clark8032b982017-07-28 11:04:54 -04002697
2698##
2699
2700# ------------------------------------------------------------------------------
2701
2702#Method void setAllowSimplifyClip(bool allow)
2703
Cary Clarkab2621d2018-01-30 10:08:57 -05002704#In Clip
2705#Line # experimental ##
Cary Clark8032b982017-07-28 11:04:54 -04002706#Experimental
2707Only used for testing.
2708##
2709
Cary Clarkce101242017-09-01 15:51:02 -04002710Set to simplify clip stack using PathOps.
Cary Clark8032b982017-07-28 11:04:54 -04002711
2712##
2713
2714# ------------------------------------------------------------------------------
2715
2716#Method void clipRegion(const SkRegion& deviceRgn, SkClipOp op = SkClipOp::kIntersect)
2717
Cary Clarkab2621d2018-01-30 10:08:57 -05002718#In Clip
2719#Line # combines Clip with Region ##
Cary Clark8032b982017-07-28 11:04:54 -04002720Replace Clip with the intersection or difference of Clip and Region deviceRgn.
Cary Clarkce101242017-09-01 15:51:02 -04002721Resulting Clip is Aliased; pixels are fully contained by the clip.
Cary Clark8032b982017-07-28 11:04:54 -04002722deviceRgn is unaffected by Matrix.
2723
Cary Clarkbad5ad72017-08-03 17:14:08 -04002724#Param deviceRgn Region to combine with Clip ##
2725#Param op Clip_Op to apply to Clip ##
Cary Clark8032b982017-07-28 11:04:54 -04002726
2727#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04002728#Description
Cary Clarkce101242017-09-01 15:51:02 -04002729 region is unaffected by canvas rotation; iRect is affected by canvas rotation.
2730 Both clips are Aliased; this is not noticeable on Region clip because it
Cary Clarkbad5ad72017-08-03 17:14:08 -04002731 aligns to pixel boundaries.
2732##
2733void draw(SkCanvas* canvas) {
2734 SkPaint paint;
2735 paint.setAntiAlias(true);
2736 SkIRect iRect = {30, 40, 120, 130 };
2737 SkRegion region(iRect);
2738 canvas->rotate(10);
2739 canvas->save();
2740 canvas->clipRegion(region, SkClipOp::kIntersect);
2741 canvas->drawCircle(50, 50, 45, paint);
2742 canvas->restore();
2743 canvas->translate(100, 100);
2744 canvas->clipRect(SkRect::Make(iRect), SkClipOp::kIntersect);
2745 canvas->drawCircle(50, 50, 45, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002746}
2747##
2748
Cary Clark2ade9972017-11-02 17:49:34 -04002749#SeeAlso clipRect clipRRect clipPath
Cary Clark8032b982017-07-28 11:04:54 -04002750
2751##
2752
2753#Method bool quickReject(const SkRect& rect) const
2754
Cary Clarkab2621d2018-01-30 10:08:57 -05002755#In Clip
2756#Line # returns if Rect is outside Clip ##
Cary Clark8032b982017-07-28 11:04:54 -04002757Return true if Rect rect, transformed by Matrix, can be quickly determined to be
2758outside of Clip. May return false even though rect is outside of Clip.
2759
2760Use to check if an area to be drawn is clipped out, to skip subsequent draw calls.
2761
Cary Clarkbad5ad72017-08-03 17:14:08 -04002762#Param rect Rect to compare with Clip ##
Cary Clark8032b982017-07-28 11:04:54 -04002763
Cary Clarkbad5ad72017-08-03 17:14:08 -04002764#Return true if rect, transformed by Matrix, does not intersect Clip ##
Cary Clark8032b982017-07-28 11:04:54 -04002765
2766#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04002767void draw(SkCanvas* canvas) {
2768 SkRect testRect = {30, 30, 120, 129 };
2769 SkRect clipRect = {30, 130, 120, 230 };
2770 canvas->save();
2771 canvas->clipRect(clipRect);
2772 SkDebugf("quickReject %s\n", canvas->quickReject(testRect) ? "true" : "false");
2773 canvas->restore();
2774 canvas->rotate(10);
2775 canvas->clipRect(clipRect);
2776 SkDebugf("quickReject %s\n", canvas->quickReject(testRect) ? "true" : "false");
Cary Clark8032b982017-07-28 11:04:54 -04002777}
2778 #StdOut
Cary Clarkbad5ad72017-08-03 17:14:08 -04002779 quickReject true
Cary Clark8032b982017-07-28 11:04:54 -04002780 quickReject false
2781 ##
2782##
2783
Cary Clark2ade9972017-11-02 17:49:34 -04002784#SeeAlso getLocalClipBounds getTotalMatrix SkBitmap::drawsNothing
Cary Clark8032b982017-07-28 11:04:54 -04002785
2786##
2787
2788#Method bool quickReject(const SkPath& path) const
2789
Cary Clarkab2621d2018-01-30 10:08:57 -05002790#In Clip
Cary Clark8032b982017-07-28 11:04:54 -04002791Return true if path, transformed by Matrix, can be quickly determined to be
2792outside of Clip. May return false even though path is outside of Clip.
2793
2794Use to check if an area to be drawn is clipped out, to skip subsequent draw calls.
2795
Cary Clarkbad5ad72017-08-03 17:14:08 -04002796#Param path Path to compare with Clip ##
Cary Clark8032b982017-07-28 11:04:54 -04002797
Cary Clarkbad5ad72017-08-03 17:14:08 -04002798#Return true if path, transformed by Matrix, does not intersect Clip ##
Cary Clark8032b982017-07-28 11:04:54 -04002799
2800#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04002801void draw(SkCanvas* canvas) {
2802 SkPoint testPoints[] = {{30, 30}, {120, 30}, {120, 129} };
2803 SkPoint clipPoints[] = {{30, 130}, {120, 130}, {120, 230} };
2804 SkPath testPath, clipPath;
2805 testPath.addPoly(testPoints, SK_ARRAY_COUNT(testPoints), true);
2806 clipPath.addPoly(clipPoints, SK_ARRAY_COUNT(clipPoints), true);
2807 canvas->save();
2808 canvas->clipPath(clipPath);
2809 SkDebugf("quickReject %s\n", canvas->quickReject(testPath) ? "true" : "false");
2810 canvas->restore();
2811 canvas->rotate(10);
2812 canvas->clipPath(clipPath);
2813 SkDebugf("quickReject %s\n", canvas->quickReject(testPath) ? "true" : "false");
Cary Clark8032b982017-07-28 11:04:54 -04002814 #StdOut
Cary Clarkbad5ad72017-08-03 17:14:08 -04002815 quickReject true
Cary Clark8032b982017-07-28 11:04:54 -04002816 quickReject false
2817 ##
2818}
2819##
2820
Cary Clark2ade9972017-11-02 17:49:34 -04002821#SeeAlso getLocalClipBounds getTotalMatrix SkBitmap::drawsNothing
Cary Clark8032b982017-07-28 11:04:54 -04002822
2823##
2824
2825#Method SkRect getLocalClipBounds() const
2826
Cary Clarkab2621d2018-01-30 10:08:57 -05002827#In Clip
2828#Line # returns Clip bounds in source coordinates ##
Cary Clark8032b982017-07-28 11:04:54 -04002829Return bounds of Clip, transformed by inverse of Matrix. If Clip is empty,
2830return SkRect::MakeEmpty, where all Rect sides equal zero.
2831
2832Rect returned is outset by one to account for partial pixel coverage if Clip
Cary Clarkce101242017-09-01 15:51:02 -04002833is Anti-aliased.
Cary Clark8032b982017-07-28 11:04:54 -04002834
Cary Clarkbad5ad72017-08-03 17:14:08 -04002835#Return bounds of Clip in local coordinates ##
Cary Clark8032b982017-07-28 11:04:54 -04002836
2837#Example
2838 #Description
2839 Initial bounds is device bounds outset by 1 on all sides.
2840 Clipped bounds is clipPath bounds outset by 1 on all sides.
2841 Scaling the canvas by two in x and y scales the local bounds by 1/2 in x and y.
2842 ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002843 SkCanvas local(256, 256);
2844 canvas = &local;
2845 SkRect bounds = canvas->getLocalClipBounds();
2846 SkDebugf("left:%g top:%g right:%g bottom:%g\n",
2847 bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom);
2848 SkPoint clipPoints[] = {{30, 130}, {120, 130}, {120, 230} };
2849 SkPath clipPath;
2850 clipPath.addPoly(clipPoints, SK_ARRAY_COUNT(clipPoints), true);
2851 canvas->clipPath(clipPath);
2852 bounds = canvas->getLocalClipBounds();
2853 SkDebugf("left:%g top:%g right:%g bottom:%g\n",
2854 bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom);
2855 canvas->scale(2, 2);
2856 bounds = canvas->getLocalClipBounds();
2857 SkDebugf("left:%g top:%g right:%g bottom:%g\n",
2858 bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom);
2859 #StdOut
2860 left:-1 top:-1 right:257 bottom:257
2861 left:29 top:129 right:121 bottom:231
2862 left:14.5 top:64.5 right:60.5 bottom:115.5
2863 ##
Cary Clark8032b982017-07-28 11:04:54 -04002864##
2865
2866# local canvas in example works around bug in fiddle ##
2867#Bug 6524 ##
Cary Clark2ade9972017-11-02 17:49:34 -04002868#SeeAlso getDeviceClipBounds getBaseLayerSize quickReject
Cary Clark8032b982017-07-28 11:04:54 -04002869
2870##
2871
2872#Method bool getLocalClipBounds(SkRect* bounds) const
2873
Cary Clarkab2621d2018-01-30 10:08:57 -05002874#In Clip
Cary Clark8032b982017-07-28 11:04:54 -04002875Return bounds of Clip, transformed by inverse of Matrix. If Clip is empty,
2876return false, and set bounds to SkRect::MakeEmpty, where all Rect sides equal zero.
2877
2878bounds is outset by one to account for partial pixel coverage if Clip
Cary Clarkce101242017-09-01 15:51:02 -04002879is Anti-aliased.
Cary Clark8032b982017-07-28 11:04:54 -04002880
Cary Clarkbad5ad72017-08-03 17:14:08 -04002881#Param bounds Rect of Clip in local coordinates ##
Cary Clark8032b982017-07-28 11:04:54 -04002882
Cary Clarkbad5ad72017-08-03 17:14:08 -04002883#Return true if Clip bounds is not empty ##
Cary Clark8032b982017-07-28 11:04:54 -04002884
2885#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04002886 void draw(SkCanvas* canvas) {
2887 SkCanvas local(256, 256);
2888 canvas = &local;
2889 SkRect bounds;
2890 SkDebugf("local bounds empty = %s\n", canvas->getLocalClipBounds(&bounds)
2891 ? "false" : "true");
2892 SkPath path;
2893 canvas->clipPath(path);
2894 SkDebugf("local bounds empty = %s\n", canvas->getLocalClipBounds(&bounds)
2895 ? "false" : "true");
Cary Clark8032b982017-07-28 11:04:54 -04002896 }
2897 #StdOut
Cary Clarkbad5ad72017-08-03 17:14:08 -04002898 local bounds empty = false
Cary Clark8032b982017-07-28 11:04:54 -04002899 local bounds empty = true
2900 ##
2901##
2902
2903# local canvas in example works around bug in fiddle ##
2904#Bug 6524 ##
Cary Clark2ade9972017-11-02 17:49:34 -04002905#SeeAlso getDeviceClipBounds getBaseLayerSize quickReject
Cary Clark8032b982017-07-28 11:04:54 -04002906
2907##
2908
2909#Method SkIRect getDeviceClipBounds() const
2910
Cary Clarkab2621d2018-01-30 10:08:57 -05002911#In Clip
2912#Line # returns IRect bounds of Clip ##
Cary Clark8032b982017-07-28 11:04:54 -04002913Return IRect bounds of Clip, unaffected by Matrix. If Clip is empty,
2914return SkRect::MakeEmpty, where all Rect sides equal zero.
2915
2916Unlike getLocalClipBounds, returned IRect is not outset.
2917
Cary Clarkbad5ad72017-08-03 17:14:08 -04002918#Return bounds of Clip in Device coordinates ##
Cary Clark8032b982017-07-28 11:04:54 -04002919
2920#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04002921void draw(SkCanvas* canvas) {
2922 #Description
Cary Clark8032b982017-07-28 11:04:54 -04002923 Initial bounds is device bounds, not outset.
2924 Clipped bounds is clipPath bounds, not outset.
2925 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 -04002926 ##
2927 SkCanvas device(256, 256);
2928 canvas = &device;
2929 SkIRect bounds = canvas->getDeviceClipBounds();
2930 SkDebugf("left:%d top:%d right:%d bottom:%d\n",
2931 bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom);
2932 SkPoint clipPoints[] = {{30, 130}, {120, 130}, {120, 230} };
2933 SkPath clipPath;
2934 clipPath.addPoly(clipPoints, SK_ARRAY_COUNT(clipPoints), true);
2935 canvas->save();
2936 canvas->clipPath(clipPath);
2937 bounds = canvas->getDeviceClipBounds();
2938 SkDebugf("left:%d top:%d right:%d bottom:%d\n",
2939 bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom);
2940 canvas->restore();
2941 canvas->scale(1.f/2, 1.f/2);
2942 canvas->clipPath(clipPath);
2943 bounds = canvas->getDeviceClipBounds();
2944 SkDebugf("left:%d top:%d right:%d bottom:%d\n",
2945 bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom);
Cary Clark8032b982017-07-28 11:04:54 -04002946 #StdOut
Cary Clarkbad5ad72017-08-03 17:14:08 -04002947 left:0 top:0 right:256 bottom:256
2948 left:30 top:130 right:120 bottom:230
Cary Clark8032b982017-07-28 11:04:54 -04002949 left:15 top:65 right:60 bottom:115
2950 ##
2951}
2952##
2953
2954#ToDo some confusion on why with an identity Matrix local and device are different ##
Cary Clark2ade9972017-11-02 17:49:34 -04002955#SeeAlso getLocalClipBounds getBaseLayerSize quickReject
Cary Clark8032b982017-07-28 11:04:54 -04002956
2957# device canvas in example works around bug in fiddle ##
2958#Bug 6524 ##
2959
2960##
2961
2962#Method bool getDeviceClipBounds(SkIRect* bounds) const
2963
Cary Clarkab2621d2018-01-30 10:08:57 -05002964#In Clip
Cary Clark8032b982017-07-28 11:04:54 -04002965Return IRect bounds of Clip, unaffected by Matrix. If Clip is empty,
2966return false, and set bounds to SkRect::MakeEmpty, where all Rect sides equal zero.
2967
2968Unlike getLocalClipBounds, bounds is not outset.
2969
Cary Clarkbad5ad72017-08-03 17:14:08 -04002970#Param bounds Rect of Clip in device coordinates ##
Cary Clark8032b982017-07-28 11:04:54 -04002971
Cary Clarkbad5ad72017-08-03 17:14:08 -04002972#Return true if Clip bounds is not empty ##
Cary Clark8032b982017-07-28 11:04:54 -04002973
2974#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04002975 void draw(SkCanvas* canvas) {
2976 SkIRect bounds;
2977 SkDebugf("device bounds empty = %s\n", canvas->getDeviceClipBounds(&bounds)
2978 ? "false" : "true");
2979 SkPath path;
2980 canvas->clipPath(path);
2981 SkDebugf("device bounds empty = %s\n", canvas->getDeviceClipBounds(&bounds)
2982 ? "false" : "true");
Cary Clark8032b982017-07-28 11:04:54 -04002983 }
2984 #StdOut
Cary Clarkbad5ad72017-08-03 17:14:08 -04002985 device bounds empty = false
Cary Clark8032b982017-07-28 11:04:54 -04002986 device bounds empty = true
2987 ##
2988##
2989
Cary Clark2ade9972017-11-02 17:49:34 -04002990#SeeAlso getLocalClipBounds getBaseLayerSize quickReject
Cary Clark8032b982017-07-28 11:04:54 -04002991
2992##
2993
Cary Clark08895c42018-02-01 09:37:32 -05002994#Subtopic Clip ##
Cary Clark8032b982017-07-28 11:04:54 -04002995
2996# ------------------------------------------------------------------------------
2997
2998#Method void drawColor(SkColor color, SkBlendMode mode = SkBlendMode::kSrcOver)
2999
Cary Clarkab2621d2018-01-30 10:08:57 -05003000#Line # fills Clip with Color and Blend_Mode ##
Cary Clark8032b982017-07-28 11:04:54 -04003001Fill Clip with Color color.
3002mode determines how Color_ARGB is combined with destination.
3003
Cary Clarkbad5ad72017-08-03 17:14:08 -04003004#Param color Unpremultiplied Color_ARGB ##
3005#Param mode SkBlendMode used to combine source color and destination ##
Cary Clark8032b982017-07-28 11:04:54 -04003006
3007#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003008 canvas->drawColor(SK_ColorRED);
3009 canvas->clipRect(SkRect::MakeWH(150, 150));
3010 canvas->drawColor(SkColorSetARGB(0x80, 0x00, 0xFF, 0x00), SkBlendMode::kPlus);
3011 canvas->clipRect(SkRect::MakeWH(75, 75));
3012 canvas->drawColor(SkColorSetARGB(0x80, 0x00, 0x00, 0xFF), SkBlendMode::kPlus);
Cary Clark8032b982017-07-28 11:04:54 -04003013##
3014
Cary Clark2ade9972017-11-02 17:49:34 -04003015#SeeAlso clear SkBitmap::erase drawPaint
Cary Clark8032b982017-07-28 11:04:54 -04003016
3017##
3018
3019# ------------------------------------------------------------------------------
3020
3021#Method void clear(SkColor color)
3022
Cary Clarkab2621d2018-01-30 10:08:57 -05003023#Line # fills Clip with Color ##
Cary Clark8032b982017-07-28 11:04:54 -04003024Fill Clip with Color color using SkBlendMode::kSrc.
3025This has the effect of replacing all pixels contained by Clip with color.
3026
Cary Clarkbad5ad72017-08-03 17:14:08 -04003027#Param color Unpremultiplied Color_ARGB ##
Cary Clark8032b982017-07-28 11:04:54 -04003028
3029#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003030void draw(SkCanvas* canvas) {
3031 canvas->save();
3032 canvas->clipRect(SkRect::MakeWH(256, 128));
3033 canvas->clear(SkColorSetARGB(0x80, 0xFF, 0x00, 0x00));
3034 canvas->restore();
3035 canvas->save();
3036 canvas->clipRect(SkRect::MakeWH(150, 192));
3037 canvas->clear(SkColorSetARGB(0x80, 0x00, 0xFF, 0x00));
3038 canvas->restore();
3039 canvas->clipRect(SkRect::MakeWH(75, 256));
3040 canvas->clear(SkColorSetARGB(0x80, 0x00, 0x00, 0xFF));
Cary Clark8032b982017-07-28 11:04:54 -04003041}
3042##
3043
Cary Clark2ade9972017-11-02 17:49:34 -04003044#SeeAlso drawColor SkBitmap::erase drawPaint
Cary Clark8032b982017-07-28 11:04:54 -04003045
3046##
3047
3048# ------------------------------------------------------------------------------
3049
3050#Method void discard()
3051
Cary Clarkab2621d2018-01-30 10:08:57 -05003052#Line # makes Canvas contents undefined ##
Cary Clark8032b982017-07-28 11:04:54 -04003053Make Canvas contents undefined. Subsequent calls that read Canvas pixels,
3054such as drawing with SkBlendMode, return undefined results. discard() does
3055not change Clip or Matrix.
3056
3057discard() may do nothing, depending on the implementation of Surface or Device
3058that created Canvas.
3059
3060discard() allows optimized performance on subsequent draws by removing
3061cached data associated with Surface or Device.
3062It is not necessary to call discard() once done with Canvas;
3063any cached data is deleted when owning Surface or Device is deleted.
3064
3065#ToDo example? not sure how to make this meaningful w/o more implementation detail ##
Cary Clark2ade9972017-11-02 17:49:34 -04003066#SeeAlso flush() SkSurface::prepareForExternalIO GrContext::abandonContext
Cary Clark8032b982017-07-28 11:04:54 -04003067
3068#NoExample
3069##
3070
3071##
3072
3073# ------------------------------------------------------------------------------
3074
3075#Method void drawPaint(const SkPaint& paint)
3076
Cary Clarkab2621d2018-01-30 10:08:57 -05003077#Line # fills Clip with Paint ##
Mike Reed8ad91a92018-01-19 19:09:32 -05003078Fill Clip with Paint paint. Paint components Mask_Filter, Shader,
Cary Clarkbad5ad72017-08-03 17:14:08 -04003079Color_Filter, Image_Filter, and Blend_Mode affect drawing;
3080Path_Effect in paint is ignored.
Cary Clark8032b982017-07-28 11:04:54 -04003081
3082# can Path_Effect in paint ever alter drawPaint?
3083
Cary Clarkbad5ad72017-08-03 17:14:08 -04003084#Param paint graphics state used to fill Canvas ##
Cary Clark8032b982017-07-28 11:04:54 -04003085
3086#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003087void draw(SkCanvas* canvas) {
3088 SkColor colors[] = { SK_ColorRED, SK_ColorGREEN, SK_ColorBLUE };
3089 SkScalar pos[] = { 0, SK_Scalar1/2, SK_Scalar1 };
3090 SkPaint paint;
3091 paint.setShader(SkGradientShader::MakeSweep(256, 256, colors, pos, SK_ARRAY_COUNT(colors)));
3092 canvas->drawPaint(paint);
Cary Clark8032b982017-07-28 11:04:54 -04003093}
3094##
3095
Cary Clark2ade9972017-11-02 17:49:34 -04003096#SeeAlso clear drawColor SkBitmap::erase
Cary Clark8032b982017-07-28 11:04:54 -04003097
3098##
3099
3100# ------------------------------------------------------------------------------
3101
3102#Enum PointMode
Cary Clark08895c42018-02-01 09:37:32 -05003103#Line # sets drawPoints options ##
Cary Clark8032b982017-07-28 11:04:54 -04003104
3105#Code
3106 enum PointMode {
3107 kPoints_PointMode,
3108 kLines_PointMode,
Cary Clarkd0530ba2017-09-14 11:25:39 -04003109 kPolygon_PointMode,
Cary Clark8032b982017-07-28 11:04:54 -04003110 };
3111##
3112
3113Selects if an array of points are drawn as discrete points, as lines, or as
3114an open polygon.
3115
3116#Const kPoints_PointMode 0
3117 Draw each point separately.
3118##
3119
3120#Const kLines_PointMode 1
3121 Draw each pair of points as a line segment.
3122##
3123
3124#Const kPolygon_PointMode 2
3125 Draw the array of points as a open polygon.
3126##
3127
3128#Example
3129 #Description
3130 The upper left corner shows three squares when drawn as points.
3131 The upper right corner shows one line; when drawn as lines, two points are required per line.
3132 The lower right corner shows two lines; when draw as polygon, no miter is drawn at the corner.
3133 The lower left corner shows two lines with a miter when path contains polygon.
3134 ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003135void draw(SkCanvas* canvas) {
3136 SkPaint paint;
3137 paint.setStyle(SkPaint::kStroke_Style);
3138 paint.setStrokeWidth(10);
3139 SkPoint points[] = {{64, 32}, {96, 96}, {32, 96}};
3140 canvas->drawPoints(SkCanvas::kPoints_PointMode, 3, points, paint);
3141 canvas->translate(128, 0);
3142 canvas->drawPoints(SkCanvas::kLines_PointMode, 3, points, paint);
3143 canvas->translate(0, 128);
3144 canvas->drawPoints(SkCanvas::kPolygon_PointMode, 3, points, paint);
3145 SkPath path;
3146 path.addPoly(points, 3, false);
3147 canvas->translate(-128, 0);
3148 canvas->drawPath(path, paint);
Cary Clark8032b982017-07-28 11:04:54 -04003149}
3150##
3151
Cary Clark2ade9972017-11-02 17:49:34 -04003152#SeeAlso drawLine drawPoint drawPath
Cary Clark8032b982017-07-28 11:04:54 -04003153
3154##
3155
3156# ------------------------------------------------------------------------------
3157
3158#Method void drawPoints(PointMode mode, size_t count, const SkPoint pts[], const SkPaint& paint)
3159
Cary Clarkab2621d2018-01-30 10:08:57 -05003160#Line # draws array as points, lines, polygon ##
Cary Clark8032b982017-07-28 11:04:54 -04003161Draw pts using Clip, Matrix and Paint paint.
Cary Clarkbad5ad72017-08-03 17:14:08 -04003162count is the number of points; if count is less than one, has no effect.
Cary Clark8032b982017-07-28 11:04:54 -04003163mode may be one of: kPoints_PointMode, kLines_PointMode, or kPolygon_PointMode.
3164
Cary Clarkbad5ad72017-08-03 17:14:08 -04003165If mode is kPoints_PointMode, the shape of point drawn depends on paint
3166Paint_Stroke_Cap. If paint is set to SkPaint::kRound_Cap, each point draws a
3167circle of diameter Paint_Stroke_Width. If paint is set to SkPaint::kSquare_Cap
3168or SkPaint::kButt_Cap, each point draws a square of width and height
3169Paint_Stroke_Width.
Cary Clark8032b982017-07-28 11:04:54 -04003170
3171If mode is kLines_PointMode, each pair of points draws a line segment.
3172One line is drawn for every two points; each point is used once. If count is odd,
3173the final point is ignored.
3174
3175If mode is kPolygon_PointMode, each adjacent pair of points draws a line segment.
3176count minus one lines are drawn; the first and last point are used once.
3177
3178Each line segment respects paint Paint_Stroke_Cap and Paint_Stroke_Width.
3179Paint_Style is ignored, as if were set to SkPaint::kStroke_Style.
3180
Cary Clarkbad5ad72017-08-03 17:14:08 -04003181Always draws each element one at a time; is not affected by
3182Paint_Stroke_Join, and unlike drawPath, does not create a mask from all points
3183and lines before drawing.
Cary Clark8032b982017-07-28 11:04:54 -04003184
Cary Clarka523d2d2017-08-30 08:58:10 -04003185#Param mode whether pts draws points or lines ##
3186#Param count number of points in the array ##
3187#Param pts array of points to draw ##
3188#Param paint stroke, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003189
3190#Example
3191#Height 200
3192 #Description
3193 #List
3194 # The first column draws points. ##
3195 # The second column draws points as lines. ##
3196 # The third column draws points as a polygon. ##
3197 # The fourth column draws points as a polygonal path. ##
3198 # The first row uses a round cap and round join. ##
3199 # The second row uses a square cap and a miter join. ##
3200 # The third row uses a butt cap and a bevel join. ##
3201 ##
3202 The transparent color makes multiple line draws visible;
3203 the path is drawn all at once.
3204 ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003205void draw(SkCanvas* canvas) {
3206 SkPaint paint;
3207 paint.setAntiAlias(true);
3208 paint.setStyle(SkPaint::kStroke_Style);
3209 paint.setStrokeWidth(10);
3210 paint.setColor(0x80349a45);
3211 const SkPoint points[] = {{32, 16}, {48, 48}, {16, 32}};
3212 const SkPaint::Join join[] = { SkPaint::kRound_Join,
3213 SkPaint::kMiter_Join,
3214 SkPaint::kBevel_Join };
3215 int joinIndex = 0;
3216 SkPath path;
3217 path.addPoly(points, 3, false);
3218 for (const auto cap : { SkPaint::kRound_Cap, SkPaint::kSquare_Cap, SkPaint::kButt_Cap } ) {
3219 paint.setStrokeCap(cap);
3220 paint.setStrokeJoin(join[joinIndex++]);
3221 for (const auto mode : { SkCanvas::kPoints_PointMode,
3222 SkCanvas::kLines_PointMode,
3223 SkCanvas::kPolygon_PointMode } ) {
3224 canvas->drawPoints(mode, 3, points, paint);
3225 canvas->translate(64, 0);
3226 }
3227 canvas->drawPath(path, paint);
3228 canvas->translate(-192, 64);
3229 }
Cary Clark8032b982017-07-28 11:04:54 -04003230}
3231##
3232
Cary Clark2ade9972017-11-02 17:49:34 -04003233#SeeAlso drawLine drawPoint drawPath
Cary Clark8032b982017-07-28 11:04:54 -04003234
3235##
3236
3237# ------------------------------------------------------------------------------
3238
3239#Method void drawPoint(SkScalar x, SkScalar y, const SkPaint& paint)
3240
Cary Clarkab2621d2018-01-30 10:08:57 -05003241#Line # draws point at (x, y) position ##
Cary Clark8032b982017-07-28 11:04:54 -04003242Draw point at (x, y) using Clip, Matrix and Paint paint.
3243
3244The shape of point drawn depends on paint Paint_Stroke_Cap.
Cary Clarkbad5ad72017-08-03 17:14:08 -04003245If paint is set to SkPaint::kRound_Cap, draw a circle of diameter
3246Paint_Stroke_Width. If paint is set to SkPaint::kSquare_Cap or SkPaint::kButt_Cap,
Cary Clark8032b982017-07-28 11:04:54 -04003247draw a square of width and height Paint_Stroke_Width.
3248Paint_Style is ignored, as if were set to SkPaint::kStroke_Style.
3249
Cary Clarkbad5ad72017-08-03 17:14:08 -04003250#Param x left edge of circle or square ##
3251#Param y top edge of circle or square ##
3252#Param paint stroke, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003253
3254#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003255void draw(SkCanvas* canvas) {
3256 SkPaint paint;
3257 paint.setAntiAlias(true);
3258 paint.setColor(0x80349a45);
3259 paint.setStyle(SkPaint::kStroke_Style);
3260 paint.setStrokeWidth(100);
3261 paint.setStrokeCap(SkPaint::kRound_Cap);
3262 canvas->scale(1, 1.2f);
3263 canvas->drawPoint(64, 96, paint);
3264 canvas->scale(.6f, .8f);
3265 paint.setColor(SK_ColorWHITE);
3266 canvas->drawPoint(106, 120, paint);
Cary Clark8032b982017-07-28 11:04:54 -04003267}
3268##
3269
Cary Clark2ade9972017-11-02 17:49:34 -04003270#SeeAlso drawPoints drawCircle drawRect drawLine drawPath
Cary Clark8032b982017-07-28 11:04:54 -04003271
3272##
3273
Cary Clarkbad5ad72017-08-03 17:14:08 -04003274#Method void drawPoint(SkPoint p, const SkPaint& paint)
3275
3276Draw point p using Clip, Matrix and Paint paint.
3277
3278The shape of point drawn depends on paint Paint_Stroke_Cap.
3279If paint is set to SkPaint::kRound_Cap, draw a circle of diameter
3280Paint_Stroke_Width. If paint is set to SkPaint::kSquare_Cap or SkPaint::kButt_Cap,
3281draw a square of width and height Paint_Stroke_Width.
3282Paint_Style is ignored, as if were set to SkPaint::kStroke_Style.
3283
3284#Param p top-left edge of circle or square ##
3285#Param paint stroke, blend, color, and so on, used to draw ##
3286
3287#Example
3288void draw(SkCanvas* canvas) {
3289 SkPaint paint;
3290 paint.setAntiAlias(true);
3291 paint.setColor(0x80349a45);
3292 paint.setStyle(SkPaint::kStroke_Style);
3293 paint.setStrokeWidth(100);
3294 paint.setStrokeCap(SkPaint::kSquare_Cap);
3295 canvas->scale(1, 1.2f);
3296 canvas->drawPoint({64, 96}, paint);
3297 canvas->scale(.6f, .8f);
3298 paint.setColor(SK_ColorWHITE);
3299 canvas->drawPoint(106, 120, paint);
3300}
3301##
3302
Cary Clark2ade9972017-11-02 17:49:34 -04003303#SeeAlso drawPoints drawCircle drawRect drawLine drawPath
Cary Clarkbad5ad72017-08-03 17:14:08 -04003304
3305##
3306
Cary Clark8032b982017-07-28 11:04:54 -04003307# ------------------------------------------------------------------------------
3308
3309#Method void drawLine(SkScalar x0, SkScalar y0, SkScalar x1, SkScalar y1, const SkPaint& paint)
3310
Cary Clarkab2621d2018-01-30 10:08:57 -05003311#Line # draws line segment between two points ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003312Draws line segment from (x0, y0) to (x1, y1) using Clip, Matrix, and Paint paint.
3313In paint: Paint_Stroke_Width describes the line thickness;
3314Paint_Stroke_Cap draws the end rounded or square;
Cary Clark8032b982017-07-28 11:04:54 -04003315Paint_Style is ignored, as if were set to SkPaint::kStroke_Style.
3316
Cary Clarkbad5ad72017-08-03 17:14:08 -04003317#Param x0 start of line segment on x-axis ##
3318#Param y0 start of line segment on y-axis ##
3319#Param x1 end of line segment on x-axis ##
3320#Param y1 end of line segment on y-axis ##
3321#Param paint stroke, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003322
3323#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003324 SkPaint paint;
3325 paint.setAntiAlias(true);
3326 paint.setColor(0xFF9a67be);
3327 paint.setStrokeWidth(20);
3328 canvas->skew(1, 0);
3329 canvas->drawLine(32, 96, 32, 160, paint);
3330 canvas->skew(-2, 0);
3331 canvas->drawLine(288, 96, 288, 160, paint);
3332##
3333
Cary Clark2ade9972017-11-02 17:49:34 -04003334#SeeAlso drawPoint drawCircle drawRect drawPath
Cary Clarkbad5ad72017-08-03 17:14:08 -04003335
3336##
3337
3338#Method void drawLine(SkPoint p0, SkPoint p1, const SkPaint& paint)
3339
3340Draws line segment from p0 to p1 using Clip, Matrix, and Paint paint.
3341In paint: Paint_Stroke_Width describes the line thickness;
3342Paint_Stroke_Cap draws the end rounded or square;
3343Paint_Style is ignored, as if were set to SkPaint::kStroke_Style.
3344
3345#Param p0 start of line segment ##
3346#Param p1 end of line segment ##
3347#Param paint stroke, blend, color, and so on, used to draw ##
3348
3349#Example
3350 SkPaint paint;
3351 paint.setAntiAlias(true);
3352 paint.setColor(0xFF9a67be);
3353 paint.setStrokeWidth(20);
3354 canvas->skew(1, 0);
3355 canvas->drawLine({32, 96}, {32, 160}, paint);
3356 canvas->skew(-2, 0);
3357 canvas->drawLine({288, 96}, {288, 160}, paint);
Cary Clark8032b982017-07-28 11:04:54 -04003358##
3359
Cary Clark2ade9972017-11-02 17:49:34 -04003360#SeeAlso drawPoint drawCircle drawRect drawPath
Cary Clark8032b982017-07-28 11:04:54 -04003361
3362##
3363
3364# ------------------------------------------------------------------------------
3365
3366#Method void drawRect(const SkRect& rect, const SkPaint& paint)
3367
Cary Clarkab2621d2018-01-30 10:08:57 -05003368#Line # draws Rect using Clip, Matrix, and Paint ##
Cary Clark8032b982017-07-28 11:04:54 -04003369Draw Rect rect using Clip, Matrix, and Paint paint.
3370In paint: Paint_Style determines if rectangle is stroked or filled;
3371if stroked, Paint_Stroke_Width describes the line thickness, and
3372Paint_Stroke_Join draws the corners rounded or square.
3373
Cary Clarkbc5697d2017-10-04 14:31:33 -04003374#Param rect rectangle to draw ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003375#Param paint stroke or fill, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003376
3377#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003378void draw(SkCanvas* canvas) {
3379 SkPoint rectPts[] = { {64, 48}, {192, 160} };
3380 SkPaint paint;
3381 paint.setAntiAlias(true);
3382 paint.setStyle(SkPaint::kStroke_Style);
3383 paint.setStrokeWidth(20);
3384 paint.setStrokeJoin(SkPaint::kRound_Join);
3385 SkMatrix rotator;
3386 rotator.setRotate(30, 128, 128);
3387 for (auto color : { SK_ColorRED, SK_ColorBLUE, SK_ColorYELLOW, SK_ColorMAGENTA } ) {
3388 paint.setColor(color);
3389 SkRect rect;
3390 rect.set(rectPts[0], rectPts[1]);
3391 canvas->drawRect(rect, paint);
3392 rotator.mapPoints(rectPts, 2);
3393 }
Cary Clark8032b982017-07-28 11:04:54 -04003394}
3395##
3396
Cary Clark2ade9972017-11-02 17:49:34 -04003397#SeeAlso drawIRect drawRRect drawRoundRect drawRegion drawPath drawLine
Cary Clark8032b982017-07-28 11:04:54 -04003398
3399##
3400
3401# ------------------------------------------------------------------------------
3402
3403#Method void drawIRect(const SkIRect& rect, const SkPaint& paint)
3404
Cary Clarkab2621d2018-01-30 10:08:57 -05003405#Line # draws IRect using Clip, Matrix, and Paint ##
Cary Clark8032b982017-07-28 11:04:54 -04003406Draw IRect rect using Clip, Matrix, and Paint paint.
3407In paint: Paint_Style determines if rectangle is stroked or filled;
3408if stroked, Paint_Stroke_Width describes the line thickness, and
3409Paint_Stroke_Join draws the corners rounded or square.
3410
Cary Clarkbc5697d2017-10-04 14:31:33 -04003411#Param rect rectangle to draw ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003412#Param paint stroke or fill, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003413
3414#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003415 SkIRect rect = { 64, 48, 192, 160 };
3416 SkPaint paint;
3417 paint.setAntiAlias(true);
3418 paint.setStyle(SkPaint::kStroke_Style);
3419 paint.setStrokeWidth(20);
3420 paint.setStrokeJoin(SkPaint::kRound_Join);
3421 for (auto color : { SK_ColorRED, SK_ColorBLUE, SK_ColorYELLOW, SK_ColorMAGENTA } ) {
3422 paint.setColor(color);
3423 canvas->drawIRect(rect, paint);
3424 canvas->rotate(30, 128, 128);
3425 }
Cary Clark8032b982017-07-28 11:04:54 -04003426##
3427
Cary Clark2ade9972017-11-02 17:49:34 -04003428#SeeAlso drawRect drawRRect drawRoundRect drawRegion drawPath drawLine
Cary Clark8032b982017-07-28 11:04:54 -04003429
3430##
3431
3432# ------------------------------------------------------------------------------
3433
3434#Method void drawRegion(const SkRegion& region, const SkPaint& paint)
3435
Cary Clarkab2621d2018-01-30 10:08:57 -05003436#Line # draws Region using Clip, Matrix, and Paint ##
Cary Clark8032b982017-07-28 11:04:54 -04003437Draw Region region using Clip, Matrix, and Paint paint.
3438In paint: Paint_Style determines if rectangle is stroked or filled;
3439if stroked, Paint_Stroke_Width describes the line thickness, and
3440Paint_Stroke_Join draws the corners rounded or square.
3441
Cary Clarkbc5697d2017-10-04 14:31:33 -04003442#Param region region to draw ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003443#Param paint Paint stroke or fill, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003444
3445#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003446void draw(SkCanvas* canvas) {
3447 SkRegion region;
3448 region.op( 10, 10, 50, 50, SkRegion::kUnion_Op);
3449 region.op( 10, 50, 90, 90, SkRegion::kUnion_Op);
3450 SkPaint paint;
3451 paint.setAntiAlias(true);
3452 paint.setStyle(SkPaint::kStroke_Style);
3453 paint.setStrokeWidth(20);
3454 paint.setStrokeJoin(SkPaint::kRound_Join);
3455 canvas->drawRegion(region, paint);
Cary Clark8032b982017-07-28 11:04:54 -04003456}
3457##
3458
Cary Clark2ade9972017-11-02 17:49:34 -04003459#SeeAlso drawRect drawIRect drawPath
Cary Clark8032b982017-07-28 11:04:54 -04003460
3461##
3462
3463# ------------------------------------------------------------------------------
3464
3465#Method void drawOval(const SkRect& oval, const SkPaint& paint)
3466
Cary Clarkab2621d2018-01-30 10:08:57 -05003467#Line # draws Oval using Clip, Matrix, and Paint ##
Cary Clark8032b982017-07-28 11:04:54 -04003468Draw Oval oval using Clip, Matrix, and Paint.
3469In paint: Paint_Style determines if Oval is stroked or filled;
3470if stroked, Paint_Stroke_Width describes the line thickness.
3471
Cary Clarkbad5ad72017-08-03 17:14:08 -04003472#Param oval Rect bounds of Oval ##
3473#Param paint Paint stroke or fill, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003474
3475#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003476void draw(SkCanvas* canvas) {
3477 canvas->clear(0xFF3f5f9f);
3478 SkColor kColor1 = SkColorSetARGB(0xff, 0xff, 0x7f, 0);
3479 SkColor g1Colors[] = { kColor1, SkColorSetA(kColor1, 0x20) };
3480 SkPoint g1Points[] = { { 0, 0 }, { 0, 100 } };
3481 SkScalar pos[] = { 0.2f, 1.0f };
3482 SkRect bounds = SkRect::MakeWH(80, 70);
3483 SkPaint paint;
3484 paint.setAntiAlias(true);
3485 paint.setShader(SkGradientShader::MakeLinear(g1Points, g1Colors, pos, SK_ARRAY_COUNT(g1Colors),
3486 SkShader::kClamp_TileMode));
3487 canvas->drawOval(bounds , paint);
Cary Clark8032b982017-07-28 11:04:54 -04003488}
3489##
3490
Cary Clark2ade9972017-11-02 17:49:34 -04003491#SeeAlso drawCircle drawPoint drawPath drawRRect drawRoundRect
Cary Clark8032b982017-07-28 11:04:54 -04003492
3493##
3494
3495# ------------------------------------------------------------------------------
3496
3497#Method void drawRRect(const SkRRect& rrect, const SkPaint& paint)
3498
Cary Clarkab2621d2018-01-30 10:08:57 -05003499#Line # draws Round_Rect using Clip, Matrix, and Paint ##
Cary Clark8032b982017-07-28 11:04:54 -04003500Draw Round_Rect rrect using Clip, Matrix, and Paint paint.
3501In paint: Paint_Style determines if rrect is stroked or filled;
3502if stroked, Paint_Stroke_Width describes the line thickness.
3503
Cary Clarkbad5ad72017-08-03 17:14:08 -04003504rrect may represent a rectangle, circle, oval, uniformly rounded rectangle, or
3505may have any combination of positive non-square radii for the four corners.
Cary Clark8032b982017-07-28 11:04:54 -04003506
Cary Clarkbad5ad72017-08-03 17:14:08 -04003507#Param rrect Round_Rect with up to eight corner radii to draw ##
3508#Param paint Paint stroke or fill, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003509
3510#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003511void draw(SkCanvas* canvas) {
3512 SkPaint paint;
3513 paint.setAntiAlias(true);
3514 SkRect outer = {30, 40, 210, 220};
3515 SkRect radii = {30, 50, 70, 90 };
3516 SkRRect rRect;
3517 rRect.setNinePatch(outer, radii.fLeft, radii.fTop, radii.fRight, radii.fBottom);
3518 canvas->drawRRect(rRect, paint);
3519 paint.setColor(SK_ColorWHITE);
3520 canvas->drawLine(outer.fLeft + radii.fLeft, outer.fTop,
3521 outer.fLeft + radii.fLeft, outer.fBottom, paint);
3522 canvas->drawLine(outer.fRight - radii.fRight, outer.fTop,
3523 outer.fRight - radii.fRight, outer.fBottom, paint);
3524 canvas->drawLine(outer.fLeft, outer.fTop + radii.fTop,
3525 outer.fRight, outer.fTop + radii.fTop, paint);
3526 canvas->drawLine(outer.fLeft, outer.fBottom - radii.fBottom,
3527 outer.fRight, outer.fBottom - radii.fBottom, paint);
3528}
Cary Clark8032b982017-07-28 11:04:54 -04003529##
3530
Cary Clark2ade9972017-11-02 17:49:34 -04003531#SeeAlso drawRect drawRoundRect drawDRRect drawCircle drawOval drawPath
Cary Clark8032b982017-07-28 11:04:54 -04003532
3533##
3534
3535# ------------------------------------------------------------------------------
3536
3537#Method void drawDRRect(const SkRRect& outer, const SkRRect& inner, const SkPaint& paint)
3538
Cary Clarkab2621d2018-01-30 10:08:57 -05003539#Line # draws double Round_Rect stroked or filled ##
Cary Clark8032b982017-07-28 11:04:54 -04003540Draw Round_Rect outer and inner
3541using Clip, Matrix, and Paint paint.
3542outer must contain inner or the drawing is undefined.
Cary Clarkce101242017-09-01 15:51:02 -04003543In paint: Paint_Style determines if Round_Rect is stroked or filled;
Cary Clark8032b982017-07-28 11:04:54 -04003544if stroked, Paint_Stroke_Width describes the line thickness.
Cary Clarkbad5ad72017-08-03 17:14:08 -04003545If stroked and Round_Rect corner has zero length radii, Paint_Stroke_Join can
3546draw corners rounded or square.
Cary Clark8032b982017-07-28 11:04:54 -04003547
Cary Clarkbad5ad72017-08-03 17:14:08 -04003548GPU-backed platforms optimize drawing when both outer and inner are
Cary Clark8032b982017-07-28 11:04:54 -04003549concave and outer contains inner. These platforms may not be able to draw
3550Path built with identical data as fast.
3551
Cary Clarkbad5ad72017-08-03 17:14:08 -04003552#Param outer Round_Rect outer bounds to draw ##
3553#Param inner Round_Rect inner bounds to draw ##
3554#Param paint Paint stroke or fill, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003555
3556#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003557void draw(SkCanvas* canvas) {
3558 SkRRect outer = SkRRect::MakeRect({20, 40, 210, 200});
3559 SkRRect inner = SkRRect::MakeOval({60, 70, 170, 160});
3560 SkPaint paint;
3561 canvas->drawDRRect(outer, inner, paint);
Cary Clark8032b982017-07-28 11:04:54 -04003562}
3563##
3564
3565#Example
3566#Description
3567 Outer Rect has no corner radii, but stroke join is rounded.
3568 Inner Round_Rect has corner radii; outset stroke increases radii of corners.
3569 Stroke join does not affect inner Round_Rect since it has no sharp corners.
3570##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003571void draw(SkCanvas* canvas) {
3572 SkRRect outer = SkRRect::MakeRect({20, 40, 210, 200});
3573 SkRRect inner = SkRRect::MakeRectXY({60, 70, 170, 160}, 10, 10);
3574 SkPaint paint;
3575 paint.setAntiAlias(true);
3576 paint.setStyle(SkPaint::kStroke_Style);
3577 paint.setStrokeWidth(20);
3578 paint.setStrokeJoin(SkPaint::kRound_Join);
3579 canvas->drawDRRect(outer, inner, paint);
3580 paint.setStrokeWidth(1);
3581 paint.setColor(SK_ColorWHITE);
3582 canvas->drawDRRect(outer, inner, paint);
Cary Clark8032b982017-07-28 11:04:54 -04003583}
3584##
3585
Cary Clark2ade9972017-11-02 17:49:34 -04003586#SeeAlso drawRect drawRoundRect drawRRect drawCircle drawOval drawPath
Cary Clark8032b982017-07-28 11:04:54 -04003587
3588##
3589
3590# ------------------------------------------------------------------------------
3591
3592#Method void drawCircle(SkScalar cx, SkScalar cy, SkScalar radius, const SkPaint& paint)
3593
Cary Clarkab2621d2018-01-30 10:08:57 -05003594#Line # draws Circle using Clip, Matrix, and Paint ##
Cary Clark8032b982017-07-28 11:04:54 -04003595Draw Circle at (cx, cy) with radius using Clip, Matrix, and Paint paint.
3596If radius is zero or less, nothing is drawn.
3597In paint: Paint_Style determines if Circle is stroked or filled;
3598if stroked, Paint_Stroke_Width describes the line thickness.
3599
Cary Clarkbad5ad72017-08-03 17:14:08 -04003600#Param cx Circle center on the x-axis ##
3601#Param cy Circle center on the y-axis ##
3602#Param radius half the diameter of Circle ##
3603#Param paint Paint stroke or fill, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003604
3605#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003606 void draw(SkCanvas* canvas) {
3607 SkPaint paint;
3608 paint.setAntiAlias(true);
3609 canvas->drawCircle(128, 128, 90, paint);
3610 paint.setColor(SK_ColorWHITE);
3611 canvas->drawCircle(86, 86, 20, paint);
3612 canvas->drawCircle(160, 76, 20, paint);
3613 canvas->drawCircle(140, 150, 35, paint);
3614 }
3615##
3616
Cary Clark2ade9972017-11-02 17:49:34 -04003617#SeeAlso drawOval drawRRect drawRoundRect drawPath drawArc drawPoint drawLine
Cary Clarkbad5ad72017-08-03 17:14:08 -04003618
3619##
3620
3621#Method void drawCircle(SkPoint center, SkScalar radius, const SkPaint& paint)
3622
Cary Clarkce101242017-09-01 15:51:02 -04003623Draw Circle at center with radius using Clip, Matrix, and Paint paint.
Cary Clarkbad5ad72017-08-03 17:14:08 -04003624If radius is zero or less, nothing is drawn.
3625In paint: Paint_Style determines if Circle is stroked or filled;
3626if stroked, Paint_Stroke_Width describes the line thickness.
3627
3628#Param center Circle center ##
3629#Param radius half the diameter of Circle ##
3630#Param paint Paint stroke or fill, blend, color, and so on, used to draw ##
3631
3632#Example
3633 void draw(SkCanvas* canvas) {
3634 SkPaint paint;
3635 paint.setAntiAlias(true);
3636 canvas->drawCircle(128, 128, 90, paint);
3637 paint.setColor(SK_ColorWHITE);
3638 canvas->drawCircle({86, 86}, 20, paint);
3639 canvas->drawCircle({160, 76}, 20, paint);
3640 canvas->drawCircle({140, 150}, 35, paint);
3641 }
Cary Clark8032b982017-07-28 11:04:54 -04003642##
3643
Cary Clark2ade9972017-11-02 17:49:34 -04003644#SeeAlso drawOval drawRRect drawRoundRect drawPath drawArc drawPoint drawLine
Cary Clark8032b982017-07-28 11:04:54 -04003645
3646##
3647
3648# ------------------------------------------------------------------------------
3649
3650#Method void drawArc(const SkRect& oval, SkScalar startAngle, SkScalar sweepAngle,
3651 bool useCenter, const SkPaint& paint)
Cary Clarkab2621d2018-01-30 10:08:57 -05003652#Line # draws Arc using Clip, Matrix, and Paint ##
Cary Clark8032b982017-07-28 11:04:54 -04003653
3654Draw Arc using Clip, Matrix, and Paint paint.
Cary Clarkbad5ad72017-08-03 17:14:08 -04003655
Cary Clark8032b982017-07-28 11:04:54 -04003656Arc is part of Oval bounded by oval, sweeping from startAngle to startAngle plus
3657sweepAngle. startAngle and sweepAngle are in degrees.
Cary Clarkbad5ad72017-08-03 17:14:08 -04003658
Cary Clark8032b982017-07-28 11:04:54 -04003659startAngle of zero places start point at the right middle edge of oval.
3660A positive sweepAngle places Arc end point clockwise from start point;
3661a negative sweepAngle places Arc end point counterclockwise from start point.
3662sweepAngle may exceed 360 degrees, a full circle.
3663If useCenter is true, draw a wedge that includes lines from oval
3664center to Arc end points. If useCenter is false, draw Arc between end points.
3665
3666If Rect oval is empty or sweepAngle is zero, nothing is drawn.
3667
Cary Clarkbad5ad72017-08-03 17:14:08 -04003668#Param oval Rect bounds of Oval containing Arc to draw ##
3669#Param startAngle angle in degrees where Arc begins ##
3670#Param sweepAngle sweep angle in degrees; positive is clockwise ##
3671#Param useCenter if true, include the center of the oval ##
3672#Param paint Paint stroke or fill, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003673
3674#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003675 void draw(SkCanvas* canvas) {
3676 SkPaint paint;
3677 paint.setAntiAlias(true);
3678 SkRect oval = { 4, 4, 60, 60};
3679 for (auto useCenter : { false, true } ) {
3680 for (auto style : { SkPaint::kFill_Style, SkPaint::kStroke_Style } ) {
3681 paint.setStyle(style);
3682 for (auto degrees : { 45, 90, 180, 360} ) {
3683 canvas->drawArc(oval, 0, degrees , useCenter, paint);
3684 canvas->translate(64, 0);
3685 }
3686 canvas->translate(-256, 64);
3687 }
3688 }
Cary Clark8032b982017-07-28 11:04:54 -04003689 }
3690##
3691
3692#Example
3693#Height 64
Cary Clarkbad5ad72017-08-03 17:14:08 -04003694 void draw(SkCanvas* canvas) {
3695 SkPaint paint;
3696 paint.setAntiAlias(true);
3697 paint.setStyle(SkPaint::kStroke_Style);
3698 paint.setStrokeWidth(4);
3699 SkRect oval = { 4, 4, 60, 60};
3700 float intervals[] = { 5, 5 };
3701 paint.setPathEffect(SkDashPathEffect::Make(intervals, 2, 2.5f));
3702 for (auto degrees : { 270, 360, 540, 720 } ) {
3703 canvas->drawArc(oval, 0, degrees, false, paint);
3704 canvas->translate(64, 0);
3705 }
Cary Clark8032b982017-07-28 11:04:54 -04003706 }
3707##
3708
Cary Clark2ade9972017-11-02 17:49:34 -04003709#SeeAlso SkPath::arcTo drawCircle drawOval drawPath
Cary Clark8032b982017-07-28 11:04:54 -04003710
3711##
3712
3713# ------------------------------------------------------------------------------
3714
3715#Method void drawRoundRect(const SkRect& rect, SkScalar rx, SkScalar ry, const SkPaint& paint)
3716
Cary Clarkab2621d2018-01-30 10:08:57 -05003717#Line # draws Round_Rect using Clip, Matrix, and Paint ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003718Draw Round_Rect bounded by Rect rect, with corner radii (rx, ry) using Clip,
3719Matrix, and Paint paint.
3720
Cary Clark8032b982017-07-28 11:04:54 -04003721In paint: Paint_Style determines if Round_Rect is stroked or filled;
3722if stroked, Paint_Stroke_Width describes the line thickness.
3723If rx or ry are less than zero, they are treated as if they are zero.
3724If rx plus ry exceeds rect width or rect height, radii are scaled down to fit.
Cary Clarkbad5ad72017-08-03 17:14:08 -04003725If rx and ry are zero, Round_Rect is drawn as Rect and if stroked is affected by
3726Paint_Stroke_Join.
Cary Clark8032b982017-07-28 11:04:54 -04003727
Cary Clarkbad5ad72017-08-03 17:14:08 -04003728#Param rect Rect bounds of Round_Rect to draw ##
Cary Clarkce101242017-09-01 15:51:02 -04003729#Param rx axis length in x of oval describing rounded corners ##
3730#Param ry axis length in y of oval describing rounded corners ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003731#Param paint stroke, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003732
3733#Example
3734#Description
3735 Top row has a zero radius a generates a rectangle.
3736 Second row radii sum to less than sides.
3737 Third row radii sum equals sides.
3738 Fourth row radii sum exceeds sides; radii are scaled to fit.
3739##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003740 void draw(SkCanvas* canvas) {
3741 SkVector radii[] = { {0, 20}, {10, 10}, {10, 20}, {10, 40} };
3742 SkPaint paint;
3743 paint.setStrokeWidth(15);
3744 paint.setStrokeJoin(SkPaint::kRound_Join);
3745 paint.setAntiAlias(true);
3746 for (auto style : { SkPaint::kStroke_Style, SkPaint::kFill_Style } ) {
3747 paint.setStyle(style );
3748 for (size_t i = 0; i < SK_ARRAY_COUNT(radii); ++i) {
3749 canvas->drawRoundRect({10, 10, 60, 40}, radii[i].fX, radii[i].fY, paint);
3750 canvas->translate(0, 60);
3751 }
3752 canvas->translate(80, -240);
3753 }
Cary Clark8032b982017-07-28 11:04:54 -04003754 }
3755##
3756
Cary Clark2ade9972017-11-02 17:49:34 -04003757#SeeAlso DrawRRect drawRect drawDRRect drawPath drawCircle drawOval drawPoint
Cary Clark8032b982017-07-28 11:04:54 -04003758
3759##
3760
3761# ------------------------------------------------------------------------------
3762
3763#Method void drawPath(const SkPath& path, const SkPaint& paint)
3764
Cary Clarkab2621d2018-01-30 10:08:57 -05003765#Line # draws Path using Clip, Matrix, and Paint ##
Cary Clark8032b982017-07-28 11:04:54 -04003766Draw Path path using Clip, Matrix, and Paint paint.
3767Path contains an array of Path_Contour, each of which may be open or closed.
3768
3769In paint: Paint_Style determines if Round_Rect is stroked or filled:
Cary Clarkbad5ad72017-08-03 17:14:08 -04003770if filled, Path_Fill_Type determines whether Path_Contour describes inside or
3771outside of fill; if stroked, Paint_Stroke_Width describes the line thickness,
3772Paint_Stroke_Cap describes line ends, and Paint_Stroke_Join describes how
3773corners are drawn.
Cary Clark8032b982017-07-28 11:04:54 -04003774
Cary Clarkbad5ad72017-08-03 17:14:08 -04003775#Param path Path to draw ##
3776#Param paint stroke, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003777
3778#Example
3779#Description
3780 Top rows draw stroked path with combinations of joins and caps. The open contour
3781 is affected by caps; the closed contour is affected by joins.
3782 Bottom row draws fill the same for open and closed contour.
3783 First bottom column shows winding fills overlap.
3784 Second bottom column shows even odd fills exclude overlap.
3785 Third bottom column shows inverse winding fills area outside both contours.
3786##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003787void draw(SkCanvas* canvas) {
3788 SkPath path;
3789 path.moveTo(20, 20);
3790 path.quadTo(60, 20, 60, 60);
3791 path.close();
3792 path.moveTo(60, 20);
3793 path.quadTo(60, 60, 20, 60);
3794 SkPaint paint;
3795 paint.setStrokeWidth(10);
3796 paint.setAntiAlias(true);
3797 paint.setStyle(SkPaint::kStroke_Style);
3798 for (auto join: { SkPaint::kBevel_Join, SkPaint::kRound_Join, SkPaint::kMiter_Join } ) {
3799 paint.setStrokeJoin(join);
3800 for (auto cap: { SkPaint::kButt_Cap, SkPaint::kSquare_Cap, SkPaint::kRound_Cap } ) {
3801 paint.setStrokeCap(cap);
3802 canvas->drawPath(path, paint);
3803 canvas->translate(80, 0);
3804 }
3805 canvas->translate(-240, 60);
3806 }
3807 paint.setStyle(SkPaint::kFill_Style);
3808 for (auto fill : { SkPath::kWinding_FillType,
3809 SkPath::kEvenOdd_FillType,
3810 SkPath::kInverseWinding_FillType } ) {
3811 path.setFillType(fill);
3812 canvas->save();
3813 canvas->clipRect({0, 10, 80, 70});
3814 canvas->drawPath(path, paint);
3815 canvas->restore();
3816 canvas->translate(80, 0);
3817 }
Cary Clark8032b982017-07-28 11:04:54 -04003818}
3819##
3820
Cary Clark2ade9972017-11-02 17:49:34 -04003821#SeeAlso SkPath drawLine drawArc drawRect drawPoints
Cary Clark8032b982017-07-28 11:04:54 -04003822
3823##
3824
3825# ------------------------------------------------------------------------------
Cary Clark08895c42018-02-01 09:37:32 -05003826#Subtopic Draw_Image
3827#Line # draws Image to Canvas ##
Cary Clark8032b982017-07-28 11:04:54 -04003828
Cary Clarkbad5ad72017-08-03 17:14:08 -04003829drawImage, drawImageRect, and drawImageNine can be called with a bare pointer or
3830a smart pointer as a convenience. The pairs of calls are otherwise identical.
Cary Clark8032b982017-07-28 11:04:54 -04003831
Cary Clark73fa9722017-08-29 17:36:51 -04003832#Method void drawImage(const SkImage* image, SkScalar left, SkScalar top, const SkPaint* paint = nullptr)
Cary Clark8032b982017-07-28 11:04:54 -04003833
Cary Clarkab2621d2018-01-30 10:08:57 -05003834#In Draw_Image
3835#Line # draws Image at (x, y) position ##
Cary Clark8032b982017-07-28 11:04:54 -04003836Draw Image image, with its top-left corner at (left, top),
3837using Clip, Matrix, and optional Paint paint.
3838
Cary Clarkbad5ad72017-08-03 17:14:08 -04003839If paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter, Blend_Mode,
3840and Draw_Looper. If image is kAlpha_8_SkColorType, apply Shader.
3841If paint contains Mask_Filter, generate mask from image bounds. If generated
3842mask extends beyond image bounds, replicate image edge colors, just as Shader
3843made from SkImage::makeShader with SkShader::kClamp_TileMode set replicates the
Cary Clarkbc5697d2017-10-04 14:31:33 -04003844image edge color when it samples outside of its bounds.
Cary Clark8032b982017-07-28 11:04:54 -04003845
Cary Clarkbad5ad72017-08-03 17:14:08 -04003846#Param image uncompressed rectangular map of pixels ##
3847#Param left left side of image ##
3848#Param top top side of image ##
3849#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
3850 and so on; or nullptr
3851##
Cary Clark8032b982017-07-28 11:04:54 -04003852
3853#Example
3854#Height 64
3855#Image 4
Cary Clarkbad5ad72017-08-03 17:14:08 -04003856void draw(SkCanvas* canvas) {
3857 // sk_sp<SkImage> image;
3858 SkImage* imagePtr = image.get();
3859 canvas->drawImage(imagePtr, 0, 0);
3860 SkPaint paint;
3861 canvas->drawImage(imagePtr, 80, 0, &paint);
3862 paint.setAlpha(0x80);
3863 canvas->drawImage(imagePtr, 160, 0, &paint);
Cary Clark8032b982017-07-28 11:04:54 -04003864}
3865##
3866
Cary Clark2ade9972017-11-02 17:49:34 -04003867#SeeAlso drawBitmap drawImageLattice drawImageNine drawImageRect SkPaint::setImageFilter
Cary Clark8032b982017-07-28 11:04:54 -04003868
3869##
3870
3871# ------------------------------------------------------------------------------
3872
3873#Method void drawImage(const sk_sp<SkImage>& image, SkScalar left, SkScalar top,
Cary Clark73fa9722017-08-29 17:36:51 -04003874 const SkPaint* paint = nullptr)
Cary Clarkab2621d2018-01-30 10:08:57 -05003875#In Draw_Image
Cary Clark8032b982017-07-28 11:04:54 -04003876
3877Draw Image image, with its top-left corner at (left, top),
3878using Clip, Matrix, and optional Paint paint.
3879
Cary Clarkbad5ad72017-08-03 17:14:08 -04003880If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
3881Blend_Mode, and Draw_Looper. If image is kAlpha_8_SkColorType, apply Shader.
3882If paint contains Mask_Filter, generate mask from image bounds. If generated
3883mask extends beyond image bounds, replicate image edge colors, just as Shader
3884made from SkImage::makeShader with SkShader::kClamp_TileMode set replicates the
Cary Clarkbc5697d2017-10-04 14:31:33 -04003885image edge color when it samples outside of its bounds.
Cary Clark8032b982017-07-28 11:04:54 -04003886
Cary Clarkbad5ad72017-08-03 17:14:08 -04003887#Param image uncompressed rectangular map of pixels ##
3888#Param left left side of image ##
3889#Param top pop side of image ##
3890#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
3891 and so on; or nullptr
3892##
Cary Clark8032b982017-07-28 11:04:54 -04003893
3894#Example
3895#Height 64
3896#Image 4
Cary Clarkbad5ad72017-08-03 17:14:08 -04003897void draw(SkCanvas* canvas) {
3898 // sk_sp<SkImage> image;
3899 canvas->drawImage(image, 0, 0);
3900 SkPaint paint;
3901 canvas->drawImage(image, 80, 0, &paint);
3902 paint.setAlpha(0x80);
3903 canvas->drawImage(image, 160, 0, &paint);
Cary Clark8032b982017-07-28 11:04:54 -04003904}
3905##
3906
Cary Clark2ade9972017-11-02 17:49:34 -04003907#SeeAlso drawBitmap drawImageLattice drawImageNine drawImageRect SkPaint::setImageFilter
Cary Clark8032b982017-07-28 11:04:54 -04003908
3909##
3910
3911# ------------------------------------------------------------------------------
3912
3913#Enum SrcRectConstraint
Cary Clark08895c42018-02-01 09:37:32 -05003914#Line # sets drawImageRect options ##
Cary Clark8032b982017-07-28 11:04:54 -04003915
3916#Code
3917 enum SrcRectConstraint {
3918 kStrict_SrcRectConstraint,
3919 kFast_SrcRectConstraint,
3920 };
3921##
3922
Cary Clarkce101242017-09-01 15:51:02 -04003923SrcRectConstraint controls the behavior at the edge of source Rect,
3924provided to drawImageRect, trading off speed for precision.
Cary Clark8032b982017-07-28 11:04:54 -04003925
Cary Clarkce101242017-09-01 15:51:02 -04003926Image_Filter in Paint may sample multiple pixels in the image. Source Rect
Cary Clarkbad5ad72017-08-03 17:14:08 -04003927restricts the bounds of pixels that may be read. Image_Filter may slow down if
Cary Clarkce101242017-09-01 15:51:02 -04003928it cannot read outside the bounds, when sampling near the edge of source Rect.
Cary Clark8032b982017-07-28 11:04:54 -04003929SrcRectConstraint specifies whether an Image_Filter is allowed to read pixels
Cary Clarkce101242017-09-01 15:51:02 -04003930outside source Rect.
Cary Clark8032b982017-07-28 11:04:54 -04003931
3932#Const kStrict_SrcRectConstraint
Cary Clarkce101242017-09-01 15:51:02 -04003933 Requires Image_Filter to respect source Rect,
Cary Clark8032b982017-07-28 11:04:54 -04003934 sampling only inside of its bounds, possibly with a performance penalty.
3935##
3936
3937#Const kFast_SrcRectConstraint
Cary Clarkce101242017-09-01 15:51:02 -04003938 Permits Image_Filter to sample outside of source Rect
Cary Clark8032b982017-07-28 11:04:54 -04003939 by half the width of Image_Filter, permitting it to run faster but with
3940 error at the image edges.
3941##
3942
3943#Example
3944#Height 64
3945#Description
3946 redBorder contains a black and white checkerboard bordered by red.
3947 redBorder is drawn scaled by 16 on the left.
Cary Clarkce101242017-09-01 15:51:02 -04003948 The middle and right bitmaps are filtered checkerboards.
Cary Clark8032b982017-07-28 11:04:54 -04003949 Drawing the checkerboard with kStrict_SrcRectConstraint shows only a blur of black and white.
3950 Drawing the checkerboard with kFast_SrcRectConstraint allows red to bleed in the corners.
3951##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003952void draw(SkCanvas* canvas) {
3953 SkBitmap redBorder;
3954 redBorder.allocPixels(SkImageInfo::MakeN32Premul(4, 4));
3955 SkCanvas checkRed(redBorder);
3956 checkRed.clear(SK_ColorRED);
3957 uint32_t checkers[][2] = { { SK_ColorBLACK, SK_ColorWHITE },
3958 { SK_ColorWHITE, SK_ColorBLACK } };
3959 checkRed.writePixels(
3960 SkImageInfo::MakeN32Premul(2, 2), (void*) checkers, sizeof(checkers[0]), 1, 1);
3961 canvas->scale(16, 16);
3962 canvas->drawBitmap(redBorder, 0, 0, nullptr);
3963 canvas->resetMatrix();
3964 sk_sp<SkImage> image = SkImage::MakeFromBitmap(redBorder);
3965 SkPaint lowPaint;
3966 lowPaint.setFilterQuality(kLow_SkFilterQuality);
3967 for (auto constraint : { SkCanvas::kStrict_SrcRectConstraint,
3968 SkCanvas::kFast_SrcRectConstraint } ) {
3969 canvas->translate(80, 0);
3970 canvas->drawImageRect(image.get(), SkRect::MakeLTRB(1, 1, 3, 3),
3971 SkRect::MakeLTRB(16, 16, 48, 48), &lowPaint, constraint);
3972 }
Cary Clark8032b982017-07-28 11:04:54 -04003973}
3974##
3975
Cary Clark2ade9972017-11-02 17:49:34 -04003976#SeeAlso drawImageRect drawImage SkPaint::setImageFilter
Cary Clark8032b982017-07-28 11:04:54 -04003977
3978##
3979
3980# ------------------------------------------------------------------------------
3981
3982#Method void drawImageRect(const SkImage* image, const SkRect& src, const SkRect& dst,
3983 const SkPaint* paint,
3984 SrcRectConstraint constraint = kStrict_SrcRectConstraint)
Cary Clarkab2621d2018-01-30 10:08:57 -05003985#In Draw_Image
3986#Line # draws Image, source Rect to destination Rect ##
Cary Clark8032b982017-07-28 11:04:54 -04003987
3988Draw Rect src of Image image, scaled and translated to fill Rect dst.
3989Additionally transform draw using Clip, Matrix, and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04003990
Cary Clarkbad5ad72017-08-03 17:14:08 -04003991If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
3992Blend_Mode, and Draw_Looper. If image is kAlpha_8_SkColorType, apply Shader.
3993If paint contains Mask_Filter, generate mask from image bounds.
3994
3995If generated mask extends beyond image bounds, replicate image edge colors, just
3996as Shader made from SkImage::makeShader with SkShader::kClamp_TileMode set
Cary Clarkbc5697d2017-10-04 14:31:33 -04003997replicates the image edge color when it samples outside of its bounds.
Cary Clarkbad5ad72017-08-03 17:14:08 -04003998
3999constraint set to kStrict_SrcRectConstraint limits Paint Filter_Quality to
4000sample within src; set to kFast_SrcRectConstraint allows sampling outside to
4001improve performance.
4002
4003#Param image Image containing pixels, dimensions, and format ##
4004#Param src source Rect of image to draw from ##
4005#Param dst destination Rect of image to draw to ##
4006#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4007 and so on; or nullptr
4008##
4009#Param constraint filter strictly within src or draw faster ##
Cary Clark8032b982017-07-28 11:04:54 -04004010
4011#Example
4012#Height 64
4013#Description
4014 The left bitmap draws with Paint default kNone_SkFilterQuality, and stays within
Cary Clarkbc5697d2017-10-04 14:31:33 -04004015 its bounds; there is no bleeding with kFast_SrcRectConstraint.
Cary Clark8032b982017-07-28 11:04:54 -04004016 the middle and right bitmaps draw with kLow_SkFilterQuality; with
4017 kStrict_SrcRectConstraint, the filter remains within the checkerboard, and
4018 with kFast_SrcRectConstraint red bleeds on the edges.
4019##
Cary Clarkbad5ad72017-08-03 17:14:08 -04004020void draw(SkCanvas* canvas) {
4021 uint32_t pixels[][4] = {
4022 { 0xFFFF0000, 0xFFFF0000, 0xFFFF0000, 0xFFFF0000 },
4023 { 0xFFFF0000, 0xFF000000, 0xFFFFFFFF, 0xFFFF0000 },
4024 { 0xFFFF0000, 0xFFFFFFFF, 0xFF000000, 0xFFFF0000 },
4025 { 0xFFFF0000, 0xFFFF0000, 0xFFFF0000, 0xFFFF0000 } };
4026 SkBitmap redBorder;
4027 redBorder.installPixels(SkImageInfo::MakeN32Premul(4, 4),
4028 (void*) pixels, sizeof(pixels[0]));
4029 sk_sp<SkImage> image = SkImage::MakeFromBitmap(redBorder);
4030 SkPaint lowPaint;
4031 for (auto constraint : {
4032 SkCanvas::kFast_SrcRectConstraint,
4033 SkCanvas::kStrict_SrcRectConstraint,
4034 SkCanvas::kFast_SrcRectConstraint } ) {
4035 canvas->drawImageRect(image.get(), SkRect::MakeLTRB(1, 1, 3, 3),
4036 SkRect::MakeLTRB(16, 16, 48, 48), &lowPaint, constraint);
4037 lowPaint.setFilterQuality(kLow_SkFilterQuality);
4038 canvas->translate(80, 0);
4039 }
4040}
Cary Clark8032b982017-07-28 11:04:54 -04004041##
4042
Cary Clark2ade9972017-11-02 17:49:34 -04004043#SeeAlso SrcRectConstraint drawImage drawImageLattice drawImageNine
Cary Clark8032b982017-07-28 11:04:54 -04004044
4045##
4046
4047# ------------------------------------------------------------------------------
4048
4049#Method void drawImageRect(const SkImage* image, const SkIRect& isrc, const SkRect& dst,
4050 const SkPaint* paint, SrcRectConstraint constraint = kStrict_SrcRectConstraint)
Cary Clarkab2621d2018-01-30 10:08:57 -05004051#In Draw_Image
Cary Clark8032b982017-07-28 11:04:54 -04004052
4053Draw IRect isrc of Image image, scaled and translated to fill Rect dst.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004054Note that isrc is on integer pixel boundaries; dst may include fractional
4055boundaries. Additionally transform draw using Clip, Matrix, and optional Paint
4056paint.
Cary Clark8032b982017-07-28 11:04:54 -04004057
Cary Clarkbad5ad72017-08-03 17:14:08 -04004058If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4059Blend_Mode, and Draw_Looper. If image is kAlpha_8_SkColorType, apply Shader.
4060If paint contains Mask_Filter, generate mask from image bounds.
4061
4062If generated mask extends beyond image bounds, replicate image edge colors, just
4063as Shader made from SkImage::makeShader with SkShader::kClamp_TileMode set
Cary Clarkbc5697d2017-10-04 14:31:33 -04004064replicates the image edge color when it samples outside of its bounds.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004065
4066constraint set to kStrict_SrcRectConstraint limits Paint Filter_Quality to
Cary Clarkce101242017-09-01 15:51:02 -04004067sample within isrc; set to kFast_SrcRectConstraint allows sampling outside to
Cary Clarkbad5ad72017-08-03 17:14:08 -04004068improve performance.
4069
4070#Param image Image containing pixels, dimensions, and format ##
4071#Param isrc source IRect of image to draw from ##
4072#Param dst destination Rect of image to draw to ##
4073#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4074 and so on; or nullptr
4075##
Cary Clarkce101242017-09-01 15:51:02 -04004076#Param constraint filter strictly within isrc or draw faster ##
Cary Clark8032b982017-07-28 11:04:54 -04004077
4078#Example
4079#Image 4
Cary Clarkbad5ad72017-08-03 17:14:08 -04004080void draw(SkCanvas* canvas) {
4081 // sk_sp<SkImage> image;
4082 for (auto i : { 1, 2, 4, 8 } ) {
4083 canvas->drawImageRect(image.get(), SkIRect::MakeLTRB(0, 0, 100, 100),
4084 SkRect::MakeXYWH(i * 20, i * 20, i * 20, i * 20), nullptr);
4085 }
Cary Clark8032b982017-07-28 11:04:54 -04004086}
4087##
4088
Cary Clark2ade9972017-11-02 17:49:34 -04004089#SeeAlso SrcRectConstraint drawImage drawImageLattice drawImageNine
Cary Clark8032b982017-07-28 11:04:54 -04004090
4091##
4092
4093# ------------------------------------------------------------------------------
4094
4095#Method void drawImageRect(const SkImage* image, const SkRect& dst, const SkPaint* paint,
4096 SrcRectConstraint constraint = kStrict_SrcRectConstraint)
Cary Clarkab2621d2018-01-30 10:08:57 -05004097#In Draw_Image
Cary Clark8032b982017-07-28 11:04:54 -04004098
Cary Clarkbad5ad72017-08-03 17:14:08 -04004099Draw Image image, scaled and translated to fill Rect dst, using Clip, Matrix,
4100and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004101
Cary Clarkbad5ad72017-08-03 17:14:08 -04004102If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4103Blend_Mode, and Draw_Looper. If image is kAlpha_8_SkColorType, apply Shader.
4104If paint contains Mask_Filter, generate mask from image bounds.
4105
4106If generated mask extends beyond image bounds, replicate image edge colors, just
4107as Shader made from SkImage::makeShader with SkShader::kClamp_TileMode set
Cary Clarkbc5697d2017-10-04 14:31:33 -04004108replicates the image edge color when it samples outside of its bounds.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004109
4110constraint set to kStrict_SrcRectConstraint limits Paint Filter_Quality to
Cary Clarkce101242017-09-01 15:51:02 -04004111sample within image; set to kFast_SrcRectConstraint allows sampling outside to
Cary Clarkbad5ad72017-08-03 17:14:08 -04004112improve performance.
4113
4114#Param image Image containing pixels, dimensions, and format ##
4115#Param dst destination Rect of image to draw to ##
4116#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4117 and so on; or nullptr
4118##
Cary Clarkce101242017-09-01 15:51:02 -04004119#Param constraint filter strictly within image or draw faster ##
Cary Clark8032b982017-07-28 11:04:54 -04004120
4121#Example
4122#Image 4
Cary Clarkbad5ad72017-08-03 17:14:08 -04004123void draw(SkCanvas* canvas) {
4124 // sk_sp<SkImage> image;
4125 for (auto i : { 20, 40, 80, 160 } ) {
4126 canvas->drawImageRect(image.get(), SkRect::MakeXYWH(i, i, i, i), nullptr);
4127 }
Cary Clark8032b982017-07-28 11:04:54 -04004128}
4129##
4130
Cary Clark2ade9972017-11-02 17:49:34 -04004131#SeeAlso SrcRectConstraint drawImage drawImageLattice drawImageNine
Cary Clark8032b982017-07-28 11:04:54 -04004132
4133##
4134
4135# ------------------------------------------------------------------------------
4136
4137#Method void drawImageRect(const sk_sp<SkImage>& image, const SkRect& src, const SkRect& dst,
4138 const SkPaint* paint,
4139 SrcRectConstraint constraint = kStrict_SrcRectConstraint)
Cary Clarkab2621d2018-01-30 10:08:57 -05004140#In Draw_Image
Cary Clark8032b982017-07-28 11:04:54 -04004141
4142Draw Rect src of Image image, scaled and translated to fill Rect dst.
4143Additionally transform draw using Clip, Matrix, and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004144
Cary Clarkbad5ad72017-08-03 17:14:08 -04004145If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4146Blend_Mode, and Draw_Looper. If image is kAlpha_8_SkColorType, apply Shader.
4147If paint contains Mask_Filter, generate mask from image bounds.
4148
4149If generated mask extends beyond image bounds, replicate image edge colors, just
4150as Shader made from SkImage::makeShader with SkShader::kClamp_TileMode set
Cary Clarkbc5697d2017-10-04 14:31:33 -04004151replicates the image edge color when it samples outside of its bounds.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004152
4153constraint set to kStrict_SrcRectConstraint limits Paint Filter_Quality to
4154sample within src; set to kFast_SrcRectConstraint allows sampling outside to
4155improve performance.
4156
4157#Param image Image containing pixels, dimensions, and format ##
4158#Param src source Rect of image to draw from ##
4159#Param dst destination Rect of image to draw to ##
4160#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4161 and so on; or nullptr
4162##
4163#Param constraint filter strictly within src or draw faster ##
Cary Clark8032b982017-07-28 11:04:54 -04004164
4165#Example
4166#Height 64
4167#Description
4168 Canvas scales and translates; transformation from src to dst also scales.
4169 The two matrices are concatenated to create the final transformation.
4170##
Cary Clarkbad5ad72017-08-03 17:14:08 -04004171void draw(SkCanvas* canvas) {
4172 uint32_t pixels[][2] = { { SK_ColorBLACK, SK_ColorWHITE },
4173 { SK_ColorWHITE, SK_ColorBLACK } };
4174 SkBitmap bitmap;
4175 bitmap.installPixels(SkImageInfo::MakeN32Premul(2, 2),
4176 (void*) pixels, sizeof(pixels[0]));
4177 sk_sp<SkImage> image = SkImage::MakeFromBitmap(bitmap);
4178 SkPaint paint;
4179 canvas->scale(4, 4);
4180 for (auto alpha : { 50, 100, 150, 255 } ) {
4181 paint.setAlpha(alpha);
4182 canvas->drawImageRect(image, SkRect::MakeWH(2, 2), SkRect::MakeWH(8, 8), &paint);
4183 canvas->translate(8, 0);
4184 }
4185}
Cary Clark8032b982017-07-28 11:04:54 -04004186##
4187
Cary Clark2ade9972017-11-02 17:49:34 -04004188#SeeAlso SrcRectConstraint drawImage drawImageLattice drawImageNine
Cary Clark8032b982017-07-28 11:04:54 -04004189
4190##
4191
4192# ------------------------------------------------------------------------------
4193
4194#Method void drawImageRect(const sk_sp<SkImage>& image, const SkIRect& isrc, const SkRect& dst,
4195 const SkPaint* paint, SrcRectConstraint constraint = kStrict_SrcRectConstraint)
Cary Clarkab2621d2018-01-30 10:08:57 -05004196#In Draw_Image
Cary Clark8032b982017-07-28 11:04:54 -04004197
4198Draw IRect isrc of Image image, scaled and translated to fill Rect dst.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004199isrc is on integer pixel boundaries; dst may include fractional boundaries.
Cary Clark8032b982017-07-28 11:04:54 -04004200Additionally transform draw using Clip, Matrix, and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004201
Cary Clarkbad5ad72017-08-03 17:14:08 -04004202If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4203Blend_Mode, and Draw_Looper. If image is kAlpha_8_SkColorType, apply Shader.
4204If paint contains Mask_Filter, generate mask from image bounds.
4205
4206If generated mask extends beyond image bounds, replicate image edge colors, just
4207as Shader made from SkImage::makeShader with SkShader::kClamp_TileMode set
Cary Clarkbc5697d2017-10-04 14:31:33 -04004208replicates the image edge color when it samples outside of its bounds.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004209
4210constraint set to kStrict_SrcRectConstraint limits Paint Filter_Quality to
Cary Clarkce101242017-09-01 15:51:02 -04004211sample within image; set to kFast_SrcRectConstraint allows sampling outside to
Cary Clarkbad5ad72017-08-03 17:14:08 -04004212improve performance.
4213
4214#Param image Image containing pixels, dimensions, and format ##
4215#Param isrc source IRect of image to draw from ##
4216#Param dst destination Rect of image to draw to ##
4217#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4218 and so on; or nullptr
4219##
Cary Clarkce101242017-09-01 15:51:02 -04004220#Param constraint filter strictly within image or draw faster ##
Cary Clark8032b982017-07-28 11:04:54 -04004221
4222#Example
4223#Height 64
Cary Clarkbad5ad72017-08-03 17:14:08 -04004224void draw(SkCanvas* canvas) {
4225 uint32_t pixels[][2] = { { 0x00000000, 0x55555555},
4226 { 0xAAAAAAAA, 0xFFFFFFFF} };
4227 SkBitmap bitmap;
4228 bitmap.installPixels(SkImageInfo::MakeN32Premul(2, 2),
4229 (void*) pixels, sizeof(pixels[0]));
4230 sk_sp<SkImage> image = SkImage::MakeFromBitmap(bitmap);
4231 SkPaint paint;
4232 canvas->scale(4, 4);
4233 for (auto color : { SK_ColorRED, SK_ColorBLUE, SK_ColorGREEN } ) {
4234 paint.setColorFilter(SkColorFilter::MakeModeFilter(color, SkBlendMode::kPlus));
4235 canvas->drawImageRect(image, SkIRect::MakeWH(2, 2), SkRect::MakeWH(8, 8), &paint);
4236 canvas->translate(8, 0);
4237 }
Cary Clark8032b982017-07-28 11:04:54 -04004238}
4239##
4240
Cary Clark2ade9972017-11-02 17:49:34 -04004241#SeeAlso SrcRectConstraint drawImage drawImageLattice drawImageNine
4242
Cary Clark8032b982017-07-28 11:04:54 -04004243##
4244
4245# ------------------------------------------------------------------------------
4246
4247#Method void drawImageRect(const sk_sp<SkImage>& image, const SkRect& dst, const SkPaint* paint,
4248 SrcRectConstraint constraint = kStrict_SrcRectConstraint)
Cary Clarkab2621d2018-01-30 10:08:57 -05004249#In Draw_Image
Cary Clark8032b982017-07-28 11:04:54 -04004250
4251Draw Image image, scaled and translated to fill Rect dst,
4252using Clip, Matrix, and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004253
Cary Clarkbad5ad72017-08-03 17:14:08 -04004254If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4255Blend_Mode, and Draw_Looper. If image is kAlpha_8_SkColorType, apply Shader.
4256If paint contains Mask_Filter, generate mask from image bounds.
4257
4258If generated mask extends beyond image bounds, replicate image edge colors, just
4259as Shader made from SkImage::makeShader with SkShader::kClamp_TileMode set
Cary Clarkbc5697d2017-10-04 14:31:33 -04004260replicates the image edge color when it samples outside of its bounds.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004261
4262constraint set to kStrict_SrcRectConstraint limits Paint Filter_Quality to
Cary Clarkce101242017-09-01 15:51:02 -04004263sample within image; set to kFast_SrcRectConstraint allows sampling outside to
Cary Clarkbad5ad72017-08-03 17:14:08 -04004264improve performance.
4265
4266#Param image Image containing pixels, dimensions, and format ##
4267#Param dst destination Rect of image to draw to ##
4268#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4269 and so on; or nullptr
4270##
Cary Clarkce101242017-09-01 15:51:02 -04004271#Param constraint filter strictly within image or draw faster ##
Cary Clark8032b982017-07-28 11:04:54 -04004272
4273#Example
4274#Height 64
Cary Clarkbad5ad72017-08-03 17:14:08 -04004275void draw(SkCanvas* canvas) {
4276 uint32_t pixels[][2] = { { 0x00000000, 0x55550000},
4277 { 0xAAAA0000, 0xFFFF0000} };
4278 SkBitmap bitmap;
4279 bitmap.installPixels(SkImageInfo::MakeN32Premul(2, 2),
4280 (void*) pixels, sizeof(pixels[0]));
4281 sk_sp<SkImage> image = SkImage::MakeFromBitmap(bitmap);
4282 SkPaint paint;
4283 canvas->scale(4, 4);
4284 for (auto color : { SK_ColorRED, SK_ColorBLUE, SK_ColorGREEN } ) {
4285 paint.setColorFilter(SkColorFilter::MakeModeFilter(color, SkBlendMode::kPlus));
4286 canvas->drawImageRect(image, SkRect::MakeWH(8, 8), &paint);
4287 canvas->translate(8, 0);
4288 }
Cary Clark8032b982017-07-28 11:04:54 -04004289}
4290##
4291
Cary Clark2ade9972017-11-02 17:49:34 -04004292#SeeAlso SrcRectConstraint drawImage drawImageLattice drawImageNine
Cary Clark8032b982017-07-28 11:04:54 -04004293
4294##
4295
4296# ------------------------------------------------------------------------------
4297
4298#Method void drawImageNine(const SkImage* image, const SkIRect& center, const SkRect& dst,
4299 const SkPaint* paint = nullptr)
Cary Clarkab2621d2018-01-30 10:08:57 -05004300#In Draw_Image
4301#Line # draws Nine_Patch Image ##
Cary Clark8032b982017-07-28 11:04:54 -04004302
Cary Clarkd0530ba2017-09-14 11:25:39 -04004303Draw Image image stretched proportionally to fit into Rect dst.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004304IRect center divides the image into nine sections: four sides, four corners, and
Cary Clarkce101242017-09-01 15:51:02 -04004305the center. Corners are unmodified or scaled down proportionately if their sides
Cary Clarkbad5ad72017-08-03 17:14:08 -04004306are larger than dst; center and four sides are scaled to fit remaining space, if any.
Cary Clark8032b982017-07-28 11:04:54 -04004307
Cary Clarkbad5ad72017-08-03 17:14:08 -04004308Additionally transform draw using Clip, Matrix, and optional Paint paint.
4309
4310If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4311Blend_Mode, and Draw_Looper. If image is kAlpha_8_SkColorType, apply Shader.
4312If paint contains Mask_Filter, generate mask from image bounds.
4313
4314If generated mask extends beyond image bounds, replicate image edge colors, just
4315as Shader made from SkImage::makeShader with SkShader::kClamp_TileMode set
Cary Clarkbc5697d2017-10-04 14:31:33 -04004316replicates the image edge color when it samples outside of its bounds.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004317
4318#Param image Image containing pixels, dimensions, and format ##
4319#Param center IRect edge of image corners and sides ##
4320#Param dst destination Rect of image to draw to ##
4321#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4322 and so on; or nullptr
4323##
Cary Clark8032b982017-07-28 11:04:54 -04004324
4325#Example
4326#Height 128
4327#Description
4328 The leftmost image is smaller than center; only corners are drawn, all scaled to fit.
Cary Clarkce101242017-09-01 15:51:02 -04004329 The second image equals the size of center; only corners are drawn without scaling.
4330 The remaining images are larger than center. All corners draw without scaling.
4331 The sides and center are scaled if needed to take up the remaining space.
Cary Clark8032b982017-07-28 11:04:54 -04004332##
Cary Clarkbad5ad72017-08-03 17:14:08 -04004333void draw(SkCanvas* canvas) {
4334 SkIRect center = { 20, 10, 50, 40 };
4335 SkBitmap bitmap;
4336 bitmap.allocPixels(SkImageInfo::MakeN32Premul(60, 60));
4337 SkCanvas bitCanvas(bitmap);
4338 SkPaint paint;
4339 SkColor gray = 0xFF000000;
4340 int left = 0;
4341 for (auto right: { center.fLeft, center.fRight, bitmap.width() } ) {
4342 int top = 0;
4343 for (auto bottom: { center.fTop, center.fBottom, bitmap.height() } ) {
4344 paint.setColor(gray);
4345 bitCanvas.drawIRect(SkIRect::MakeLTRB(left, top, right, bottom), paint);
4346 gray += 0x001f1f1f;
4347 top = bottom;
4348 }
4349 left = right;
4350 }
4351 sk_sp<SkImage> image = SkImage::MakeFromBitmap(bitmap);
4352 SkImage* imagePtr = image.get();
4353 for (auto dest: { 20, 30, 40, 60, 90 } ) {
4354 canvas->drawImageNine(imagePtr, center, SkRect::MakeWH(dest, dest), nullptr);
4355 canvas->translate(dest + 4, 0);
4356 }
Cary Clark8032b982017-07-28 11:04:54 -04004357}
4358##
4359
Cary Clark2ade9972017-11-02 17:49:34 -04004360#SeeAlso drawImage drawBitmapNine drawImageLattice drawImageRect
Cary Clark8032b982017-07-28 11:04:54 -04004361
4362##
4363
4364# ------------------------------------------------------------------------------
4365
4366#Method void drawImageNine(const sk_sp<SkImage>& image, const SkIRect& center, const SkRect& dst,
4367 const SkPaint* paint = nullptr)
Cary Clarkab2621d2018-01-30 10:08:57 -05004368#In Draw_Image
Cary Clark8032b982017-07-28 11:04:54 -04004369
Cary Clarkd0530ba2017-09-14 11:25:39 -04004370Draw Image image stretched proportionally to fit into Rect dst.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004371IRect center divides the image into nine sections: four sides, four corners, and
Cary Clarkce101242017-09-01 15:51:02 -04004372the center. Corners are not scaled, or scaled down proportionately if their sides
Cary Clarkbad5ad72017-08-03 17:14:08 -04004373are larger than dst; center and four sides are scaled to fit remaining space, if any.
Cary Clark8032b982017-07-28 11:04:54 -04004374
Cary Clarkbad5ad72017-08-03 17:14:08 -04004375Additionally transform draw using Clip, Matrix, and optional Paint paint.
4376
4377If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4378Blend_Mode, and Draw_Looper. If image is kAlpha_8_SkColorType, apply Shader.
4379If paint contains Mask_Filter, generate mask from image bounds.
4380
4381If generated mask extends beyond image bounds, replicate image edge colors, just
4382as Shader made from SkImage::makeShader with SkShader::kClamp_TileMode set
Cary Clarkbc5697d2017-10-04 14:31:33 -04004383replicates the image edge color when it samples outside of its bounds.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004384
4385#Param image Image containing pixels, dimensions, and format ##
4386#Param center IRect edge of image corners and sides ##
4387#Param dst destination Rect of image to draw to ##
4388#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4389 and so on; or nullptr
4390##
Cary Clark8032b982017-07-28 11:04:54 -04004391
4392#Example
4393#Height 128
4394#Description
4395 The two leftmost images has four corners and sides to the left and right of center.
4396 The leftmost image scales the width of corners proportionately to fit.
Cary Clarkce101242017-09-01 15:51:02 -04004397 The third and fourth image corners are not scaled; the sides and center are scaled to
Cary Clark8032b982017-07-28 11:04:54 -04004398 fill the remaining space.
4399 The rightmost image has four corners scaled vertically to fit, and uses sides above
4400 and below center to fill the remaining space.
4401##
Cary Clarkbad5ad72017-08-03 17:14:08 -04004402void draw(SkCanvas* canvas) {
4403 SkIRect center = { 20, 10, 50, 40 };
4404 SkBitmap bitmap;
4405 bitmap.allocPixels(SkImageInfo::MakeN32Premul(60, 60));
4406 SkCanvas bitCanvas(bitmap);
4407 SkPaint paint;
4408 SkColor gray = 0xFF000000;
4409 int left = 0;
4410 for (auto right: { center.fLeft, center.fRight, bitmap.width() } ) {
4411 int top = 0;
4412 for (auto bottom: { center.fTop, center.fBottom, bitmap.height() } ) {
4413 paint.setColor(gray);
4414 bitCanvas.drawIRect(SkIRect::MakeLTRB(left, top, right, bottom), paint);
4415 gray += 0x001f1f1f;
4416 top = bottom;
4417 }
4418 left = right;
4419 }
4420 sk_sp<SkImage> image = SkImage::MakeFromBitmap(bitmap);
4421 for (auto dest: { 20, 30, 40, 60, 90 } ) {
4422 canvas->drawImageNine(image, center, SkRect::MakeWH(dest, 110 - dest), nullptr);
4423 canvas->translate(dest + 4, 0);
4424 }
Cary Clark8032b982017-07-28 11:04:54 -04004425}
4426##
4427
Cary Clark2ade9972017-11-02 17:49:34 -04004428#SeeAlso drawImage drawBitmapNine drawImageLattice drawImageRect
Cary Clark8032b982017-07-28 11:04:54 -04004429
4430##
4431
4432# ------------------------------------------------------------------------------
4433
4434#Method void drawBitmap(const SkBitmap& bitmap, SkScalar left, SkScalar top,
Cary Clark73fa9722017-08-29 17:36:51 -04004435 const SkPaint* paint = nullptr)
Cary Clarkab2621d2018-01-30 10:08:57 -05004436#In Draw_Image
4437#Line # draws Bitmap at (x, y) position ##
Cary Clark8032b982017-07-28 11:04:54 -04004438
4439Draw Bitmap bitmap, with its top-left corner at (left, top),
4440using Clip, Matrix, and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004441
Cary Clarka560c472017-11-27 10:44:06 -05004442If Paint paint is not nullptr, apply Color_Filter, Color_Alpha, Image_Filter,
Cary Clarkbad5ad72017-08-03 17:14:08 -04004443Blend_Mode, and Draw_Looper. If bitmap is kAlpha_8_SkColorType, apply Shader.
4444If paint contains Mask_Filter, generate mask from bitmap bounds.
4445
4446If generated mask extends beyond bitmap bounds, replicate bitmap edge colors,
4447just as Shader made from SkShader::MakeBitmapShader with
Cary Clarkbc5697d2017-10-04 14:31:33 -04004448SkShader::kClamp_TileMode set replicates the bitmap edge color when it samples
Cary Clarkbad5ad72017-08-03 17:14:08 -04004449outside of its bounds.
4450
4451#Param bitmap Bitmap containing pixels, dimensions, and format ##
4452#Param left left side of bitmap ##
4453#Param top top side of bitmap ##
4454#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4455 and so on; or nullptr
4456##
Cary Clark8032b982017-07-28 11:04:54 -04004457
4458#Example
4459#Height 64
Cary Clarkbad5ad72017-08-03 17:14:08 -04004460void draw(SkCanvas* canvas) {
4461 uint8_t pixels[][8] = { { 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00},
4462 { 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00},
4463 { 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00},
4464 { 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF},
4465 { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
4466 { 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00},
4467 { 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0x00},
4468 { 0xFF, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0xFF} };
4469 SkBitmap bitmap;
4470 bitmap.installPixels(SkImageInfo::MakeA8(8, 8),
4471 (void*) pixels, sizeof(pixels[0]));
4472 SkPaint paint;
4473 canvas->scale(4, 4);
4474 for (auto color : { SK_ColorRED, SK_ColorBLUE, 0xFF007F00} ) {
4475 paint.setColor(color);
4476 canvas->drawBitmap(bitmap, 0, 0, &paint);
4477 canvas->translate(12, 0);
4478 }
Cary Clark8032b982017-07-28 11:04:54 -04004479}
4480##
4481
Cary Clark2ade9972017-11-02 17:49:34 -04004482#SeeAlso drawImage drawBitmapLattice drawBitmapNine drawBitmapRect SkBitmap::readPixels SkBitmap::writePixels
Cary Clark8032b982017-07-28 11:04:54 -04004483
4484##
4485
4486# ------------------------------------------------------------------------------
4487
4488#Method void drawBitmapRect(const SkBitmap& bitmap, const SkRect& src, const SkRect& dst,
4489 const SkPaint* paint, SrcRectConstraint constraint = kStrict_SrcRectConstraint)
Cary Clarkab2621d2018-01-30 10:08:57 -05004490#In Draw_Image
4491#Line # draws Bitmap, source Rect to destination Rect ##
Cary Clark8032b982017-07-28 11:04:54 -04004492
4493Draw Rect src of Bitmap bitmap, scaled and translated to fill Rect dst.
4494Additionally transform draw using Clip, Matrix, and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004495
Cary Clarkbad5ad72017-08-03 17:14:08 -04004496If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4497Blend_Mode, and Draw_Looper. If bitmap is kAlpha_8_SkColorType, apply Shader.
4498If paint contains Mask_Filter, generate mask from bitmap bounds.
4499
4500If generated mask extends beyond bitmap bounds, replicate bitmap edge colors,
4501just as Shader made from SkShader::MakeBitmapShader with
Cary Clarkbc5697d2017-10-04 14:31:33 -04004502SkShader::kClamp_TileMode set replicates the bitmap edge color when it samples
Cary Clarkbad5ad72017-08-03 17:14:08 -04004503outside of its bounds.
4504
4505constraint set to kStrict_SrcRectConstraint limits Paint Filter_Quality to
4506sample within src; set to kFast_SrcRectConstraint allows sampling outside to
4507improve performance.
4508
4509#Param bitmap Bitmap containing pixels, dimensions, and format ##
4510#Param src source Rect of image to draw from ##
4511#Param dst destination Rect of image to draw to ##
4512#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4513 and so on; or nullptr
4514##
4515#Param constraint filter strictly within src or draw faster ##
Cary Clark8032b982017-07-28 11:04:54 -04004516
4517#Example
4518#Height 64
Cary Clarkbad5ad72017-08-03 17:14:08 -04004519void draw(SkCanvas* canvas) {
4520 uint8_t pixels[][8] = { { 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00},
4521 { 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00},
4522 { 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00},
4523 { 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF},
4524 { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
4525 { 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00},
4526 { 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00},
4527 { 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00} };
4528 SkBitmap bitmap;
4529 bitmap.installPixels(SkImageInfo::MakeA8(8, 8),
4530 (void*) pixels, sizeof(pixels[0]));
4531 SkPaint paint;
4532 paint.setMaskFilter(SkBlurMaskFilter::Make(kSolid_SkBlurStyle, 6));
4533 for (auto color : { SK_ColorRED, SK_ColorBLUE, 0xFF007F00} ) {
4534 paint.setColor(color);
4535 canvas->drawBitmapRect(bitmap, SkRect::MakeWH(8, 8), SkRect::MakeWH(32, 32), &paint);
4536 canvas->translate(48, 0);
4537 }
Cary Clark8032b982017-07-28 11:04:54 -04004538}
4539##
4540
Cary Clark2ade9972017-11-02 17:49:34 -04004541#SeeAlso drawImageRect drawBitmap drawBitmapLattice drawBitmapNine
Cary Clark8032b982017-07-28 11:04:54 -04004542
4543##
4544
4545# ------------------------------------------------------------------------------
4546
4547#Method void drawBitmapRect(const SkBitmap& bitmap, const SkIRect& isrc, const SkRect& dst,
4548 const SkPaint* paint, SrcRectConstraint constraint = kStrict_SrcRectConstraint)
Cary Clarkab2621d2018-01-30 10:08:57 -05004549#In Draw_Image
Cary Clark8032b982017-07-28 11:04:54 -04004550
4551Draw IRect isrc of Bitmap bitmap, scaled and translated to fill Rect dst.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004552isrc is on integer pixel boundaries; dst may include fractional boundaries.
Cary Clark8032b982017-07-28 11:04:54 -04004553Additionally transform draw using Clip, Matrix, and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004554
Cary Clarkbad5ad72017-08-03 17:14:08 -04004555If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4556Blend_Mode, and Draw_Looper. If bitmap is kAlpha_8_SkColorType, apply Shader.
4557If paint contains Mask_Filter, generate mask from bitmap bounds.
4558
4559If generated mask extends beyond bitmap bounds, replicate bitmap edge colors,
4560just as Shader made from SkShader::MakeBitmapShader with
Cary Clarkbc5697d2017-10-04 14:31:33 -04004561SkShader::kClamp_TileMode set replicates the bitmap edge color when it samples
Cary Clarkbad5ad72017-08-03 17:14:08 -04004562outside of its bounds.
4563
4564constraint set to kStrict_SrcRectConstraint limits Paint Filter_Quality to
Cary Clarkce101242017-09-01 15:51:02 -04004565sample within isrc; set to kFast_SrcRectConstraint allows sampling outside to
Cary Clarkbad5ad72017-08-03 17:14:08 -04004566improve performance.
4567
4568#Param bitmap Bitmap containing pixels, dimensions, and format ##
4569#Param isrc source IRect of image to draw from ##
4570#Param dst destination Rect of image to draw to ##
4571#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4572 and so on; or nullptr
4573##
Cary Clarkce101242017-09-01 15:51:02 -04004574#Param constraint sample strictly within isrc, or draw faster ##
Cary Clark8032b982017-07-28 11:04:54 -04004575
4576#Example
4577#Height 64
Cary Clarkbad5ad72017-08-03 17:14:08 -04004578void draw(SkCanvas* canvas) {
4579 uint8_t pixels[][8] = { { 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00},
4580 { 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00},
4581 { 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0xFF},
4582 { 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0xFF},
4583 { 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF},
4584 { 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF},
4585 { 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00},
4586 { 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00} };
4587 SkBitmap bitmap;
4588 bitmap.installPixels(SkImageInfo::MakeA8(8, 8),
4589 (void*) pixels, sizeof(pixels[0]));
4590 SkPaint paint;
4591 paint.setFilterQuality(kHigh_SkFilterQuality);
4592 for (auto color : { SK_ColorRED, SK_ColorBLUE, 0xFF007F00, 0xFF7f007f} ) {
4593 paint.setColor(color);
4594 canvas->drawBitmapRect(bitmap, SkIRect::MakeWH(8, 8), SkRect::MakeWH(32, 32), &paint);
4595 canvas->translate(48.25f, 0);
4596 }
Cary Clark8032b982017-07-28 11:04:54 -04004597}
4598##
4599
Cary Clark2ade9972017-11-02 17:49:34 -04004600#SeeAlso drawImageRect drawBitmap drawBitmapLattice drawBitmapNine
Cary Clark8032b982017-07-28 11:04:54 -04004601
4602##
4603
4604# ------------------------------------------------------------------------------
4605
4606#Method void drawBitmapRect(const SkBitmap& bitmap, const SkRect& dst, const SkPaint* paint,
4607 SrcRectConstraint constraint = kStrict_SrcRectConstraint)
Cary Clarkab2621d2018-01-30 10:08:57 -05004608#In Draw_Image
Cary Clark8032b982017-07-28 11:04:54 -04004609
4610Draw Bitmap bitmap, scaled and translated to fill Rect dst.
Cary Clarkce101242017-09-01 15:51:02 -04004611bitmap bounds is on integer pixel boundaries; dst may include fractional boundaries.
Cary Clark8032b982017-07-28 11:04:54 -04004612Additionally transform draw using Clip, Matrix, and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004613
Cary Clarkbad5ad72017-08-03 17:14:08 -04004614If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4615Blend_Mode, and Draw_Looper. If bitmap is kAlpha_8_SkColorType, apply Shader.
4616If paint contains Mask_Filter, generate mask from bitmap bounds.
4617
4618If generated mask extends beyond bitmap bounds, replicate bitmap edge colors,
4619just as Shader made from SkShader::MakeBitmapShader with
Cary Clarkbc5697d2017-10-04 14:31:33 -04004620SkShader::kClamp_TileMode set replicates the bitmap edge color when it samples
Cary Clarkbad5ad72017-08-03 17:14:08 -04004621outside of its bounds.
4622
4623constraint set to kStrict_SrcRectConstraint limits Paint Filter_Quality to
Cary Clarkce101242017-09-01 15:51:02 -04004624sample within bitmap; set to kFast_SrcRectConstraint allows sampling outside to
Cary Clarkbad5ad72017-08-03 17:14:08 -04004625improve performance.
4626
4627#Param bitmap Bitmap containing pixels, dimensions, and format ##
4628#Param dst destination Rect of image to draw to ##
4629#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4630 and so on; or nullptr
4631##
Cary Clarkce101242017-09-01 15:51:02 -04004632#Param constraint filter strictly within bitmap or draw faster ##
Cary Clark8032b982017-07-28 11:04:54 -04004633
4634#Example
4635#Height 64
Cary Clarkbad5ad72017-08-03 17:14:08 -04004636void draw(SkCanvas* canvas) {
4637 uint32_t pixels[][2] = { { 0x00000000, 0x55550000},
4638 { 0xAAAA0000, 0xFFFF0000} };
4639 SkBitmap bitmap;
4640 bitmap.installPixels(SkImageInfo::MakeN32Premul(2, 2),
4641 (void*) pixels, sizeof(pixels[0]));
4642 SkPaint paint;
4643 canvas->scale(4, 4);
4644 for (auto color : { SK_ColorRED, SK_ColorBLUE, SK_ColorGREEN } ) {
4645 paint.setColorFilter(SkColorFilter::MakeModeFilter(color, SkBlendMode::kPlus));
4646 canvas->drawBitmapRect(bitmap, SkRect::MakeWH(8, 8), &paint);
4647 canvas->translate(8, 0);
4648 }
Cary Clark8032b982017-07-28 11:04:54 -04004649}
4650##
4651
Cary Clark2ade9972017-11-02 17:49:34 -04004652#SeeAlso drawImageRect drawBitmap drawBitmapLattice drawBitmapNine
Cary Clark8032b982017-07-28 11:04:54 -04004653
4654##
4655
4656# ------------------------------------------------------------------------------
4657
4658#Method void drawBitmapNine(const SkBitmap& bitmap, const SkIRect& center, const SkRect& dst,
Cary Clark73fa9722017-08-29 17:36:51 -04004659 const SkPaint* paint = nullptr)
Cary Clarkab2621d2018-01-30 10:08:57 -05004660#In Draw_Image
4661#Line # draws Nine_Patch Bitmap ##
Cary Clark8032b982017-07-28 11:04:54 -04004662
Cary Clarkd0530ba2017-09-14 11:25:39 -04004663Draw Bitmap bitmap stretched proportionally to fit into Rect dst.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004664IRect center divides the bitmap into nine sections: four sides, four corners,
Cary Clarkce101242017-09-01 15:51:02 -04004665and the center. Corners are not scaled, or scaled down proportionately if their
Cary Clarkbad5ad72017-08-03 17:14:08 -04004666sides are larger than dst; center and four sides are scaled to fit remaining
4667space, if any.
Cary Clark8032b982017-07-28 11:04:54 -04004668
Cary Clarkbad5ad72017-08-03 17:14:08 -04004669Additionally transform draw using Clip, Matrix, and optional Paint paint.
4670
4671If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4672Blend_Mode, and Draw_Looper. If bitmap is kAlpha_8_SkColorType, apply Shader.
4673If paint contains Mask_Filter, generate mask from bitmap bounds.
4674
4675If generated mask extends beyond bitmap bounds, replicate bitmap edge colors,
4676just as Shader made from SkShader::MakeBitmapShader with
Cary Clarkbc5697d2017-10-04 14:31:33 -04004677SkShader::kClamp_TileMode set replicates the bitmap edge color when it samples
Cary Clarkbad5ad72017-08-03 17:14:08 -04004678outside of its bounds.
4679
4680#Param bitmap Bitmap containing pixels, dimensions, and format ##
4681#Param center IRect edge of image corners and sides ##
4682#Param dst destination Rect of image to draw to ##
4683#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4684 and so on; or nullptr
4685##
Cary Clark8032b982017-07-28 11:04:54 -04004686
4687#Example
4688#Height 128
4689#Description
4690 The two leftmost bitmap draws has four corners and sides to the left and right of center.
4691 The leftmost bitmap draw scales the width of corners proportionately to fit.
Cary Clarkce101242017-09-01 15:51:02 -04004692 The third and fourth draw corners are not scaled; the sides and center are scaled to
Cary Clark8032b982017-07-28 11:04:54 -04004693 fill the remaining space.
4694 The rightmost bitmap draw has four corners scaled vertically to fit, and uses sides above
4695 and below center to fill the remaining space.
4696##
Cary Clarkbad5ad72017-08-03 17:14:08 -04004697void draw(SkCanvas* canvas) {
4698 SkIRect center = { 20, 10, 50, 40 };
4699 SkBitmap bitmap;
4700 bitmap.allocPixels(SkImageInfo::MakeN32Premul(60, 60));
4701 SkCanvas bitCanvas(bitmap);
4702 SkPaint paint;
4703 SkColor gray = 0xFF000000;
4704 int left = 0;
4705 for (auto right: { center.fLeft, center.fRight, bitmap.width() } ) {
4706 int top = 0;
4707 for (auto bottom: { center.fTop, center.fBottom, bitmap.height() } ) {
4708 paint.setColor(gray);
4709 bitCanvas.drawIRect(SkIRect::MakeLTRB(left, top, right, bottom), paint);
4710 gray += 0x001f1f1f;
4711 top = bottom;
4712 }
4713 left = right;
4714 }
4715 for (auto dest: { 20, 30, 40, 60, 90 } ) {
4716 canvas->drawBitmapNine(bitmap, center, SkRect::MakeWH(dest, 110 - dest), nullptr);
4717 canvas->translate(dest + 4, 0);
4718 }
Cary Clark8032b982017-07-28 11:04:54 -04004719}
4720##
4721
Cary Clark2ade9972017-11-02 17:49:34 -04004722#SeeAlso drawImageNine drawBitmap drawBitmapLattice drawBitmapRect
Cary Clark8032b982017-07-28 11:04:54 -04004723
4724##
4725
4726# ------------------------------------------------------------------------------
4727#Struct Lattice
Cary Clark08895c42018-02-01 09:37:32 -05004728#Line # divides Bitmap or Image into a rectangular grid ##
Cary Clark8032b982017-07-28 11:04:54 -04004729#Code
4730 struct Lattice {
Cary Clark2f466242017-12-11 16:03:17 -05004731 enum RectType ...
Cary Clark8032b982017-07-28 11:04:54 -04004732
Cary Clark2f466242017-12-11 16:03:17 -05004733 const int* fXDivs;
4734 const int* fYDivs;
4735 const RectType* fRectTypes;
4736 int fXCount;
4737 int fYCount;
4738 const SkIRect* fBounds;
4739 const SkColor* fColors;
Cary Clark8032b982017-07-28 11:04:54 -04004740 };
4741##
4742
Cary Clark154beea2017-10-26 07:58:48 -04004743 Lattice divides Bitmap or Image into a rectangular grid.
4744 Grid entries on even columns and even rows are fixed; these entries are
4745 always drawn at their original size if the destination is large enough.
4746 If the destination side is too small to hold the fixed entries, all fixed
4747 entries are proportionately scaled down to fit.
4748 The grid entries not on even columns and rows are scaled to fit the
4749 remaining space, if any.
4750
Cary Clark2f466242017-12-11 16:03:17 -05004751 #Enum RectType
Cary Clark8032b982017-07-28 11:04:54 -04004752 #Code
Cary Clark2f466242017-12-11 16:03:17 -05004753 enum RectType : uint8_t {
4754 kDefault = 0,
4755 kTransparent,
4756 kFixedColor,
Cary Clark8032b982017-07-28 11:04:54 -04004757 };
4758 ##
4759
Cary Clark2f466242017-12-11 16:03:17 -05004760 Optional setting per rectangular grid entry to make it transparent,
4761 or to fill the grid entry with a color.
Cary Clark8032b982017-07-28 11:04:54 -04004762
Cary Clark2f466242017-12-11 16:03:17 -05004763 #Const kDefault 0
4764 Draws Bitmap into lattice rectangle.
4765 ##
4766
4767 #Const kTransparent 1
4768 Skips lattice rectangle by making it transparent.
4769 ##
4770
4771 #Const kFixedColor 2
4772 Draws one of fColors into lattice rectangle.
Cary Clark8032b982017-07-28 11:04:54 -04004773 ##
4774 ##
4775
4776 #Member const int* fXDivs
4777 Array of x-coordinates that divide the bitmap vertically.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004778 Array entries must be unique, increasing, greater than or equal to
4779 fBounds left edge, and less than fBounds right edge.
4780 Set the first element to fBounds left to collapse the left column of
4781 fixed grid entries.
Cary Clark8032b982017-07-28 11:04:54 -04004782 ##
4783
4784 #Member const int* fYDivs
4785 Array of y-coordinates that divide the bitmap horizontally.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004786 Array entries must be unique, increasing, greater than or equal to
4787 fBounds top edge, and less than fBounds bottom edge.
4788 Set the first element to fBounds top to collapse the top row of fixed
4789 grid entries.
Cary Clark8032b982017-07-28 11:04:54 -04004790 ##
4791
Cary Clark2f466242017-12-11 16:03:17 -05004792 #Member const RectType* fRectTypes
4793 Optional array of fill types, one per rectangular grid entry:
Cary Clarkbad5ad72017-08-03 17:14:08 -04004794 array length must be
4795 #Formula
4796 (fXCount + 1) * (fYCount + 1)
4797 ##
4798 .
Cary Clark6fc50412017-09-21 12:31:06 -04004799
Cary Clark2f466242017-12-11 16:03:17 -05004800 Each RectType is one of: kDefault, kTransparent, kFixedColor.
4801
Cary Clark8032b982017-07-28 11:04:54 -04004802 Array entries correspond to the rectangular grid entries, ascending
4803 left to right and then top to bottom.
4804 ##
4805
4806 #Member int fXCount
Cary Clarkbad5ad72017-08-03 17:14:08 -04004807 Number of entries in fXDivs array; one less than the number of
4808 horizontal divisions.
Cary Clark8032b982017-07-28 11:04:54 -04004809 ##
4810
4811 #Member int fYCount
Cary Clarkbad5ad72017-08-03 17:14:08 -04004812 Number of entries in fYDivs array; one less than the number of vertical
4813 divisions.
Cary Clark8032b982017-07-28 11:04:54 -04004814 ##
4815
4816 #Member const SkIRect* fBounds
4817 Optional subset IRect source to draw from.
4818 If nullptr, source bounds is dimensions of Bitmap or Image.
4819 ##
4820
Cary Clark2f466242017-12-11 16:03:17 -05004821 #Member const SkColor* fColors
4822 Optional array of colors, one per rectangular grid entry.
4823 Array length must be
4824 #Formula
4825 (fXCount + 1) * (fYCount + 1)
4826 ##
4827 .
4828
4829 Array entries correspond to the rectangular grid entries, ascending
4830 left to right, then top to bottom.
4831 ##
4832
Cary Clark8032b982017-07-28 11:04:54 -04004833#Struct Lattice ##
4834
4835#Method void drawBitmapLattice(const SkBitmap& bitmap, const Lattice& lattice, const SkRect& dst,
4836 const SkPaint* paint = nullptr)
Cary Clarkab2621d2018-01-30 10:08:57 -05004837#In Draw_Image
4838#Line # draws proportionally stretched Bitmap ##
Cary Clark8032b982017-07-28 11:04:54 -04004839
Cary Clarkd0530ba2017-09-14 11:25:39 -04004840Draw Bitmap bitmap stretched proportionally to fit into Rect dst.
Cary Clark8032b982017-07-28 11:04:54 -04004841
4842Lattice lattice divides bitmap into a rectangular grid.
4843Each intersection of an even-numbered row and column is fixed; like the corners
Cary Clarkbad5ad72017-08-03 17:14:08 -04004844of drawBitmapNine, fixed lattice elements never scale larger than their initial
Cary Clarkbc5697d2017-10-04 14:31:33 -04004845size and shrink proportionately when all fixed elements exceed the bitmap
Cary Clarkbad5ad72017-08-03 17:14:08 -04004846dimension. All other grid elements scale to fill the available space, if any.
Cary Clark8032b982017-07-28 11:04:54 -04004847
4848Additionally transform draw using Clip, Matrix, and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004849
Cary Clarkbad5ad72017-08-03 17:14:08 -04004850If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4851Blend_Mode, and Draw_Looper. If bitmap is kAlpha_8_SkColorType, apply Shader.
4852If paint contains Mask_Filter, generate mask from bitmap bounds.
4853
4854If generated mask extends beyond bitmap bounds, replicate bitmap edge colors,
4855just as Shader made from SkShader::MakeBitmapShader with
Cary Clarkbc5697d2017-10-04 14:31:33 -04004856SkShader::kClamp_TileMode set replicates the bitmap edge color when it samples
Cary Clarkbad5ad72017-08-03 17:14:08 -04004857outside of its bounds.
4858
4859#Param bitmap Bitmap containing pixels, dimensions, and format ##
4860#Param lattice division of bitmap into fixed and variable rectangles ##
4861#Param dst destination Rect of image to draw to ##
4862#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4863 and so on; or nullptr
4864##
Cary Clark8032b982017-07-28 11:04:54 -04004865
4866#Example
4867#Height 128
4868#Description
4869 The two leftmost bitmap draws has four corners and sides to the left and right of center.
4870 The leftmost bitmap draw scales the width of corners proportionately to fit.
Cary Clarkce101242017-09-01 15:51:02 -04004871 The third and fourth draw corners are not scaled; the sides are scaled to
Cary Clark8032b982017-07-28 11:04:54 -04004872 fill the remaining space; the center is transparent.
4873 The rightmost bitmap draw has four corners scaled vertically to fit, and uses sides above
4874 and below center to fill the remaining space.
4875##
Cary Clarkbad5ad72017-08-03 17:14:08 -04004876void draw(SkCanvas* canvas) {
4877 SkIRect center = { 20, 10, 50, 40 };
4878 SkBitmap bitmap;
4879 bitmap.allocPixels(SkImageInfo::MakeN32Premul(60, 60));
4880 SkCanvas bitCanvas(bitmap);
4881 SkPaint paint;
4882 SkColor gray = 0xFF000000;
4883 int left = 0;
4884 for (auto right: { center.fLeft, center.fRight, bitmap.width() } ) {
4885 int top = 0;
4886 for (auto bottom: { center.fTop, center.fBottom, bitmap.height() } ) {
4887 paint.setColor(gray);
4888 bitCanvas.drawIRect(SkIRect::MakeLTRB(left, top, right, bottom), paint);
4889 gray += 0x001f1f1f;
4890 top = bottom;
4891 }
4892 left = right;
4893 }
4894 const int xDivs[] = { center.fLeft, center.fRight };
4895 const int yDivs[] = { center.fTop, center.fBottom };
Cary Clarkca3ebcd2017-12-12 11:22:38 -05004896 SkCanvas::Lattice::RectType fillTypes[3][3];
4897 memset(fillTypes, 0, sizeof(fillTypes));
4898 fillTypes[1][1] = SkCanvas::Lattice::kTransparent;
4899 SkColor dummy[9]; // temporary pending bug fix
4900 SkCanvas::Lattice lattice = { xDivs, yDivs, fillTypes[0], SK_ARRAY_COUNT(xDivs),
4901 SK_ARRAY_COUNT(yDivs), nullptr, dummy };
Cary Clarkbad5ad72017-08-03 17:14:08 -04004902 for (auto dest: { 20, 30, 40, 60, 90 } ) {
Cary Clarkca3ebcd2017-12-12 11:22:38 -05004903 canvas->drawBitmapLattice(bitmap, lattice, SkRect::MakeWH(dest, 110 - dest), nullptr);
Cary Clarkbad5ad72017-08-03 17:14:08 -04004904 canvas->translate(dest + 4, 0);
4905 }
Cary Clark8032b982017-07-28 11:04:54 -04004906}
4907##
4908
Cary Clark2ade9972017-11-02 17:49:34 -04004909#SeeAlso drawImageLattice drawBitmap drawBitmapNine Lattice
Cary Clark8032b982017-07-28 11:04:54 -04004910
4911##
4912
4913# ------------------------------------------------------------------------------
4914
4915#Method void drawImageLattice(const SkImage* image, const Lattice& lattice, const SkRect& dst,
4916 const SkPaint* paint = nullptr)
Cary Clarkab2621d2018-01-30 10:08:57 -05004917#In Draw_Image
4918#Line # draws proportionally stretched Image ##
Cary Clark8032b982017-07-28 11:04:54 -04004919
Cary Clarkd0530ba2017-09-14 11:25:39 -04004920Draw Image image stretched proportionally to fit into Rect dst.
Cary Clark8032b982017-07-28 11:04:54 -04004921
4922Lattice lattice divides image into a rectangular grid.
4923Each intersection of an even-numbered row and column is fixed; like the corners
Cary Clarkbad5ad72017-08-03 17:14:08 -04004924of drawBitmapNine, fixed lattice elements never scale larger than their initial
Cary Clarkbc5697d2017-10-04 14:31:33 -04004925size and shrink proportionately when all fixed elements exceed the bitmap
Cary Clarkbad5ad72017-08-03 17:14:08 -04004926dimension. All other grid elements scale to fill the available space, if any.
Cary Clark8032b982017-07-28 11:04:54 -04004927
4928Additionally transform draw using Clip, Matrix, and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004929
Cary Clarkbad5ad72017-08-03 17:14:08 -04004930If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4931Blend_Mode, and Draw_Looper. If bitmap is kAlpha_8_SkColorType, apply Shader.
4932If paint contains Mask_Filter, generate mask from bitmap bounds.
4933
4934If generated mask extends beyond bitmap bounds, replicate bitmap edge colors,
4935just as Shader made from SkShader::MakeBitmapShader with
Cary Clarkbc5697d2017-10-04 14:31:33 -04004936SkShader::kClamp_TileMode set replicates the bitmap edge color when it samples
Cary Clarkbad5ad72017-08-03 17:14:08 -04004937outside of its bounds.
4938
4939#Param image Image containing pixels, dimensions, and format ##
4940#Param lattice division of bitmap into fixed and variable rectangles ##
4941#Param dst destination Rect of image to draw to ##
4942#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4943 and so on; or nullptr
4944##
Cary Clark8032b982017-07-28 11:04:54 -04004945
4946#Example
4947#Height 128
4948#Description
4949 The leftmost image is smaller than center; only corners are drawn, all scaled to fit.
Cary Clarkce101242017-09-01 15:51:02 -04004950 The second image equals the size of center; only corners are drawn without scaling.
4951 The remaining images are larger than center. All corners draw without scaling. The sides
Cary Clark8032b982017-07-28 11:04:54 -04004952 are scaled if needed to take up the remaining space; the center is transparent.
4953##
Cary Clarkbad5ad72017-08-03 17:14:08 -04004954void draw(SkCanvas* canvas) {
4955 SkIRect center = { 20, 10, 50, 40 };
4956 SkBitmap bitmap;
4957 bitmap.allocPixels(SkImageInfo::MakeN32Premul(60, 60));
4958 SkCanvas bitCanvas(bitmap);
4959 SkPaint paint;
4960 SkColor gray = 0xFF000000;
4961 int left = 0;
4962 for (auto right: { center.fLeft, center.fRight, bitmap.width() } ) {
4963 int top = 0;
4964 for (auto bottom: { center.fTop, center.fBottom, bitmap.height() } ) {
4965 paint.setColor(gray);
4966 bitCanvas.drawIRect(SkIRect::MakeLTRB(left, top, right, bottom), paint);
4967 gray += 0x001f1f1f;
4968 top = bottom;
4969 }
4970 left = right;
4971 }
4972 const int xDivs[] = { center.fLeft, center.fRight };
4973 const int yDivs[] = { center.fTop, center.fBottom };
Cary Clarkca3ebcd2017-12-12 11:22:38 -05004974 SkCanvas::Lattice::RectType fillTypes[3][3];
4975 memset(fillTypes, 0, sizeof(fillTypes));
4976 fillTypes[1][1] = SkCanvas::Lattice::kTransparent;
4977 SkColor dummy[9]; // temporary pending bug fix
4978 SkCanvas::Lattice lattice = { xDivs, yDivs, fillTypes[0], SK_ARRAY_COUNT(xDivs),
4979 SK_ARRAY_COUNT(yDivs), nullptr, dummy };
Cary Clarkbad5ad72017-08-03 17:14:08 -04004980 sk_sp<SkImage> image = SkImage::MakeFromBitmap(bitmap);
4981 SkImage* imagePtr = image.get();
4982 for (auto dest: { 20, 30, 40, 60, 90 } ) {
4983 canvas->drawImageNine(imagePtr, center, SkRect::MakeWH(dest, dest), nullptr);
4984 canvas->translate(dest + 4, 0);
4985 }
Cary Clark8032b982017-07-28 11:04:54 -04004986}
4987##
4988
Cary Clark2ade9972017-11-02 17:49:34 -04004989#SeeAlso drawBitmapLattice drawImage drawImageNine Lattice
Cary Clark8032b982017-07-28 11:04:54 -04004990
4991##
4992
Cary Clark08895c42018-02-01 09:37:32 -05004993#Subtopic Draw_Image ##
Cary Clark8032b982017-07-28 11:04:54 -04004994
4995# ------------------------------------------------------------------------------
4996
4997#Method void drawText(const void* text, size_t byteLength, SkScalar x, SkScalar y,
4998 const SkPaint& paint)
Cary Clarkab2621d2018-01-30 10:08:57 -05004999#Line # draws text at (x, y), using font advance ##
Cary Clark8032b982017-07-28 11:04:54 -04005000
5001Draw text, with origin at (x, y), using Clip, Matrix, and Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04005002
Cary Clarkbc5697d2017-10-04 14:31:33 -04005003text meaning depends on Paint_Text_Encoding; by default, text is encoded as
Cary Clarkbad5ad72017-08-03 17:14:08 -04005004UTF-8.
Cary Clark8032b982017-07-28 11:04:54 -04005005
Cary Clarkbad5ad72017-08-03 17:14:08 -04005006x and y meaning depends on Paint_Text_Align and Paint_Vertical_Text; by default
Cary Clarkbc5697d2017-10-04 14:31:33 -04005007text draws left to right, positioning the first glyph left side bearing at x
Cary Clarkbad5ad72017-08-03 17:14:08 -04005008and its baseline at y. Text size is affected by Matrix and Paint_Text_Size.
5009
Mike Reed8ad91a92018-01-19 19:09:32 -05005010All elements of paint: Path_Effect, Mask_Filter, Shader,
Cary Clarkbad5ad72017-08-03 17:14:08 -04005011Color_Filter, Image_Filter, and Draw_Looper; apply to text. By default, draws
Cary Clarkce101242017-09-01 15:51:02 -04005012filled 12 point black Glyphs.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005013
Cary Clarkce101242017-09-01 15:51:02 -04005014#Param text character code points or Glyphs drawn ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005015#Param byteLength byte length of text array ##
5016#Param x start of text on x-axis ##
5017#Param y start of text on y-axis ##
5018#Param paint text size, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005019
5020#Example
5021#Height 200
5022#Description
5023 The same text is drawn varying Paint_Text_Size and varying
5024 Matrix.
5025##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005026void draw(SkCanvas* canvas) {
5027 SkPaint paint;
5028 paint.setAntiAlias(true);
5029 float textSizes[] = { 12, 18, 24, 36 };
5030 for (auto size: textSizes ) {
5031 paint.setTextSize(size);
5032 canvas->drawText("Aa", 2, 10, 20, paint);
5033 canvas->translate(0, size * 2);
5034 }
5035 paint.reset();
5036 paint.setAntiAlias(true);
5037 float yPos = 20;
5038 for (auto size: textSizes ) {
5039 float scale = size / 12.f;
5040 canvas->resetMatrix();
5041 canvas->translate(100, 0);
5042 canvas->scale(scale, scale);
5043 canvas->drawText("Aa", 2, 10 / scale, yPos / scale, paint);
5044 yPos += size * 2;
5045 }
5046}
Cary Clark8032b982017-07-28 11:04:54 -04005047##
5048
Cary Clark2ade9972017-11-02 17:49:34 -04005049#SeeAlso drawString drawPosText drawPosTextH drawTextBlob drawTextOnPath drawTextRSXform
Cary Clark8032b982017-07-28 11:04:54 -04005050
5051##
5052
5053#Method void drawString(const char* string, SkScalar x, SkScalar y, const SkPaint& paint)
5054
Cary Clarkab2621d2018-01-30 10:08:57 -05005055#Line # draws null terminated string at (x, y) using font advance ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005056Draw null terminated string, with origin at (x, y), using Clip, Matrix, and
5057Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04005058
Cary Clarkbc5697d2017-10-04 14:31:33 -04005059string meaning depends on Paint_Text_Encoding; by default, strings are encoded
5060as UTF-8. Other values of Paint_Text_Encoding are unlikely to produce the desired
Cary Clarkbad5ad72017-08-03 17:14:08 -04005061results, since zero bytes may be embedded in the string.
Cary Clark8032b982017-07-28 11:04:54 -04005062
Cary Clarkbad5ad72017-08-03 17:14:08 -04005063x and y meaning depends on Paint_Text_Align and Paint_Vertical_Text; by default
Cary Clarkbc5697d2017-10-04 14:31:33 -04005064string draws left to right, positioning the first glyph left side bearing at x
Cary Clarkbad5ad72017-08-03 17:14:08 -04005065and its baseline at y. Text size is affected by Matrix and Paint_Text_Size.
5066
Mike Reed8ad91a92018-01-19 19:09:32 -05005067All elements of paint: Path_Effect, Mask_Filter, Shader,
Cary Clarkbad5ad72017-08-03 17:14:08 -04005068Color_Filter, Image_Filter, and Draw_Looper; apply to text. By default, draws
Cary Clarkce101242017-09-01 15:51:02 -04005069filled 12 point black Glyphs.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005070
Cary Clarkce101242017-09-01 15:51:02 -04005071#Param string character code points or Glyphs drawn,
Cary Clarkbad5ad72017-08-03 17:14:08 -04005072 ending with a char value of zero
5073##
5074#Param x start of string on x-axis ##
5075#Param y start of string on y-axis ##
5076#Param paint text size, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005077
5078#Example
5079 SkPaint paint;
5080 canvas->drawString("a small hello", 20, 20, paint);
5081##
5082
Cary Clark2ade9972017-11-02 17:49:34 -04005083#SeeAlso drawText drawPosText drawPosTextH drawTextBlob drawTextOnPath drawTextRSXform
Cary Clark8032b982017-07-28 11:04:54 -04005084
5085##
5086
5087#Method void drawString(const SkString& string, SkScalar x, SkScalar y, const SkPaint& paint)
5088
Cary Clarkbad5ad72017-08-03 17:14:08 -04005089Draw null terminated string, with origin at (x, y), using Clip, Matrix, and
5090Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04005091
Cary Clarkbc5697d2017-10-04 14:31:33 -04005092string meaning depends on Paint_Text_Encoding; by default, strings are encoded
5093as UTF-8. Other values of Paint_Text_Encoding are unlikely to produce the desired
Cary Clarkbad5ad72017-08-03 17:14:08 -04005094results, since zero bytes may be embedded in the string.
Cary Clark8032b982017-07-28 11:04:54 -04005095
Cary Clarkbad5ad72017-08-03 17:14:08 -04005096x and y meaning depends on Paint_Text_Align and Paint_Vertical_Text; by default
Cary Clarkbc5697d2017-10-04 14:31:33 -04005097string draws left to right, positioning the first glyph left side bearing at x
Cary Clarkbad5ad72017-08-03 17:14:08 -04005098and its baseline at y. Text size is affected by Matrix and Paint_Text_Size.
5099
Mike Reed8ad91a92018-01-19 19:09:32 -05005100All elements of paint: Path_Effect, Mask_Filter, Shader,
Cary Clarkbad5ad72017-08-03 17:14:08 -04005101Color_Filter, Image_Filter, and Draw_Looper; apply to text. By default, draws
Cary Clarkce101242017-09-01 15:51:02 -04005102filled 12 point black Glyphs.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005103
Cary Clarkce101242017-09-01 15:51:02 -04005104#Param string character code points or Glyphs drawn,
Cary Clarkbad5ad72017-08-03 17:14:08 -04005105 ending with a char value of zero
5106##
5107#Param x start of string on x-axis ##
5108#Param y start of string on y-axis ##
5109#Param paint text size, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005110
5111#Example
5112 SkPaint paint;
5113 SkString string("a small hello");
5114 canvas->drawString(string, 20, 20, paint);
5115##
5116
Cary Clark2ade9972017-11-02 17:49:34 -04005117#SeeAlso drawText drawPosText drawPosTextH drawTextBlob drawTextOnPath drawTextRSXform
Cary Clark8032b982017-07-28 11:04:54 -04005118
5119##
5120
5121# ------------------------------------------------------------------------------
5122
5123#Method void drawPosText(const void* text, size_t byteLength, const SkPoint pos[],
5124 const SkPaint& paint)
Cary Clarkab2621d2018-01-30 10:08:57 -05005125#Line # draws text at array of (x, y) positions ##
Cary Clark8032b982017-07-28 11:04:54 -04005126
Cary Clarkbad5ad72017-08-03 17:14:08 -04005127Draw each glyph in text with the origin in pos array, using Clip, Matrix, and
Cary Clarkce101242017-09-01 15:51:02 -04005128Paint paint. The number of entries in pos array must match the number of Glyphs
Cary Clarkbad5ad72017-08-03 17:14:08 -04005129described by byteLength of text.
Cary Clark8032b982017-07-28 11:04:54 -04005130
Cary Clarkbc5697d2017-10-04 14:31:33 -04005131text meaning depends on Paint_Text_Encoding; by default, text is encoded as
Cary Clarkbad5ad72017-08-03 17:14:08 -04005132UTF-8. pos elements' meaning depends on Paint_Text_Align and Paint_Vertical_Text;
Cary Clarkbc5697d2017-10-04 14:31:33 -04005133by default each glyph left side bearing is positioned at x and its
Cary Clarkbad5ad72017-08-03 17:14:08 -04005134baseline is positioned at y. Text size is affected by Matrix and
5135Paint_Text_Size.
Cary Clark8032b982017-07-28 11:04:54 -04005136
Mike Reed8ad91a92018-01-19 19:09:32 -05005137All elements of paint: Path_Effect, Mask_Filter, Shader,
Cary Clarkbad5ad72017-08-03 17:14:08 -04005138Color_Filter, Image_Filter, and Draw_Looper; apply to text. By default, draws
Cary Clarkce101242017-09-01 15:51:02 -04005139filled 12 point black Glyphs.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005140
5141Layout engines such as Harfbuzz typically position each glyph
Cary Clarkbc5697d2017-10-04 14:31:33 -04005142rather than using the font advance widths.
Cary Clark8032b982017-07-28 11:04:54 -04005143
Cary Clarkce101242017-09-01 15:51:02 -04005144#Param text character code points or Glyphs drawn ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005145#Param byteLength byte length of text array ##
5146#Param pos array of glyph origins ##
5147#Param paint text size, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005148
5149#Example
5150#Height 120
Cary Clarkbad5ad72017-08-03 17:14:08 -04005151void draw(SkCanvas* canvas) {
5152 const char hello[] = "HeLLo!";
5153 const SkPoint pos[] = { {40, 100}, {82, 95}, {115, 110}, {130, 95}, {145, 85},
5154 {172, 100} };
5155 SkPaint paint;
5156 paint.setTextSize(60);
5157 canvas->drawPosText(hello, strlen(hello), pos, paint);
Cary Clark8032b982017-07-28 11:04:54 -04005158}
5159##
5160
Cary Clark2ade9972017-11-02 17:49:34 -04005161#SeeAlso drawText drawPosTextH drawTextBlob drawTextOnPath drawTextRSXform
Cary Clark8032b982017-07-28 11:04:54 -04005162
5163##
5164
5165# ------------------------------------------------------------------------------
5166
5167#Method void drawPosTextH(const void* text, size_t byteLength, const SkScalar xpos[], SkScalar constY,
5168 const SkPaint& paint)
Cary Clarkab2621d2018-01-30 10:08:57 -05005169#Line # draws text at x positions with common baseline ##
Cary Clark8032b982017-07-28 11:04:54 -04005170
Cary Clarkbad5ad72017-08-03 17:14:08 -04005171Draw each glyph in text with its (x, y) origin composed from xpos array and
5172constY, using Clip, Matrix, and Paint paint. The number of entries in xpos array
Cary Clarkce101242017-09-01 15:51:02 -04005173must match the number of Glyphs described by byteLength of text.
Cary Clark8032b982017-07-28 11:04:54 -04005174
Cary Clarkbc5697d2017-10-04 14:31:33 -04005175text meaning depends on Paint_Text_Encoding; by default, text is encoded as
Cary Clarkce101242017-09-01 15:51:02 -04005176UTF-8. xpos elements' meaning depends on Paint_Text_Align and Paint_Vertical_Text;
Cary Clarkbc5697d2017-10-04 14:31:33 -04005177by default each glyph left side bearing is positioned at an xpos element and
Cary Clarkbad5ad72017-08-03 17:14:08 -04005178its baseline is positioned at constY. Text size is affected by Matrix and
5179Paint_Text_Size.
Cary Clark8032b982017-07-28 11:04:54 -04005180
Mike Reed8ad91a92018-01-19 19:09:32 -05005181All elements of paint: Path_Effect, Mask_Filter, Shader,
Cary Clarkbad5ad72017-08-03 17:14:08 -04005182Color_Filter, Image_Filter, and Draw_Looper; apply to text. By default, draws
Cary Clarkce101242017-09-01 15:51:02 -04005183filled 12 point black Glyphs.
Cary Clark8032b982017-07-28 11:04:54 -04005184
Cary Clarkbad5ad72017-08-03 17:14:08 -04005185Layout engines such as Harfbuzz typically position each glyph
Cary Clarkbc5697d2017-10-04 14:31:33 -04005186rather than using the font advance widths if all Glyphs share the same
Cary Clarkbad5ad72017-08-03 17:14:08 -04005187baseline.
5188
Cary Clarkce101242017-09-01 15:51:02 -04005189#Param text character code points or Glyphs drawn ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005190#Param byteLength byte length of text array ##
5191#Param xpos array of x positions, used to position each glyph ##
5192#Param constY shared y coordinate for all of x positions ##
5193#Param paint text size, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005194
5195#Example
5196#Height 40
Cary Clarkbad5ad72017-08-03 17:14:08 -04005197 void draw(SkCanvas* canvas) {
5198 SkScalar xpos[] = { 20, 40, 80, 160 };
5199 SkPaint paint;
5200 canvas->drawPosTextH("XXXX", 4, xpos, 20, paint);
5201 }
Cary Clark8032b982017-07-28 11:04:54 -04005202##
5203
Cary Clark2ade9972017-11-02 17:49:34 -04005204#SeeAlso drawText drawPosText drawTextBlob drawTextOnPath drawTextRSXform
Cary Clark8032b982017-07-28 11:04:54 -04005205
5206##
5207
5208# ------------------------------------------------------------------------------
5209
5210#Method void drawTextOnPathHV(const void* text, size_t byteLength, const SkPath& path, SkScalar hOffset,
5211 SkScalar vOffset, const SkPaint& paint)
Cary Clarkab2621d2018-01-30 10:08:57 -05005212#Line # draws text following Path with offsets ##
Cary Clark8032b982017-07-28 11:04:54 -04005213
5214Draw text on Path path, using Clip, Matrix, and Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04005215
Cary Clarkbad5ad72017-08-03 17:14:08 -04005216Origin of text is at distance hOffset along the path, offset by a perpendicular
5217vector of length vOffset. If the path section corresponding the glyph advance is
5218curved, the glyph is drawn curved to match; control points in the glyph are
Cary Clarkbc5697d2017-10-04 14:31:33 -04005219mapped to projected points parallel to the path. If the text advance is larger
Cary Clarkbad5ad72017-08-03 17:14:08 -04005220than the path length, the excess text is clipped.
5221
Cary Clarkbc5697d2017-10-04 14:31:33 -04005222text meaning depends on Paint_Text_Encoding; by default, text is encoded as
Cary Clarkbad5ad72017-08-03 17:14:08 -04005223UTF-8. Origin meaning depends on Paint_Text_Align and Paint_Vertical_Text; by
Cary Clarkbc5697d2017-10-04 14:31:33 -04005224default text positions the first glyph left side bearing at origin x and its
Cary Clark8032b982017-07-28 11:04:54 -04005225baseline at origin y. Text size is affected by Matrix and Paint_Text_Size.
5226
Mike Reed8ad91a92018-01-19 19:09:32 -05005227All elements of paint: Path_Effect, Mask_Filter, Shader,
Cary Clarkbad5ad72017-08-03 17:14:08 -04005228Color_Filter, Image_Filter, and Draw_Looper; apply to text. By default, draws
Cary Clarkce101242017-09-01 15:51:02 -04005229filled 12 point black Glyphs.
Cary Clark8032b982017-07-28 11:04:54 -04005230
Cary Clarkce101242017-09-01 15:51:02 -04005231#Param text character code points or Glyphs drawn ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005232#Param byteLength byte length of text array ##
5233#Param path Path providing text baseline ##
5234#Param hOffset distance along path to offset origin ##
5235#Param vOffset offset of text above (if negative) or below (if positive) the path ##
5236#Param paint text size, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005237
5238#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04005239 void draw(SkCanvas* canvas) {
5240 const char aero[] = "correo a" "\xC3" "\xA9" "reo";
5241 const size_t len = sizeof(aero) - 1;
5242 SkPath path;
5243 path.addOval({43-26, 43-26, 43+26, 43+26}, SkPath::kCW_Direction, 3);
5244 SkPaint paint;
5245 paint.setTextSize(24);
5246 for (auto offset : { 0, 10, 20 } ) {
5247 canvas->drawTextOnPathHV(aero, len, path, 0, -offset, paint);
5248 canvas->translate(70 + offset, 70 + offset);
5249 }
5250 }
Cary Clark8032b982017-07-28 11:04:54 -04005251##
5252
Cary Clark2ade9972017-11-02 17:49:34 -04005253#SeeAlso drawTextOnPath drawText drawPosTextH drawTextBlob drawTextRSXform
Cary Clark8032b982017-07-28 11:04:54 -04005254
5255##
5256
5257# ------------------------------------------------------------------------------
5258
5259#Method void drawTextOnPath(const void* text, size_t byteLength, const SkPath& path,
5260 const SkMatrix* matrix, const SkPaint& paint)
Cary Clarkab2621d2018-01-30 10:08:57 -05005261#Line # draws text following Path contour ##
Cary Clark8032b982017-07-28 11:04:54 -04005262
5263Draw text on Path path, using Clip, Matrix, and Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04005264
Cary Clarkbad5ad72017-08-03 17:14:08 -04005265Origin of text is at beginning of path offset by matrix, if provided, before it
5266is mapped to path. If the path section corresponding the glyph advance is
5267curved, the glyph is drawn curved to match; control points in the glyph are
Cary Clarkbc5697d2017-10-04 14:31:33 -04005268mapped to projected points parallel to the path. If the text advance is larger
Cary Clarkbad5ad72017-08-03 17:14:08 -04005269than the path length, the excess text is clipped.
5270
Cary Clarkbc5697d2017-10-04 14:31:33 -04005271text meaning depends on Paint_Text_Encoding; by default, text is encoded as
Cary Clarkbad5ad72017-08-03 17:14:08 -04005272UTF-8. Origin meaning depends on Paint_Text_Align and Paint_Vertical_Text; by
Cary Clarkbc5697d2017-10-04 14:31:33 -04005273default text positions the first glyph left side bearing at origin x and its
Cary Clark8032b982017-07-28 11:04:54 -04005274baseline at origin y. Text size is affected by Matrix and Paint_Text_Size.
5275
Mike Reed8ad91a92018-01-19 19:09:32 -05005276All elements of paint: Path_Effect, Mask_Filter, Shader,
Cary Clarkbad5ad72017-08-03 17:14:08 -04005277Color_Filter, Image_Filter, and Draw_Looper; apply to text. By default, draws
Cary Clarkce101242017-09-01 15:51:02 -04005278filled 12 point black Glyphs.
Cary Clark8032b982017-07-28 11:04:54 -04005279
Cary Clarkce101242017-09-01 15:51:02 -04005280#Param text character code points or Glyphs drawn ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005281#Param byteLength byte length of text array ##
5282#Param path Path providing text baseline ##
Cary Clarkce101242017-09-01 15:51:02 -04005283#Param matrix transform of Glyphs before mapping to path; may be nullptr
Cary Clarka523d2d2017-08-30 08:58:10 -04005284 to use identity Matrix
Cary Clarkbad5ad72017-08-03 17:14:08 -04005285##
5286#Param paint text size, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005287
5288#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04005289 void draw(SkCanvas* canvas) {
5290 const char roller[] = "rollercoaster";
5291 const size_t len = sizeof(roller) - 1;
5292 SkPath path;
5293 path.cubicTo(40, -80, 120, 80, 160, -40);
5294 SkPaint paint;
5295 paint.setTextSize(32);
5296 paint.setStyle(SkPaint::kStroke_Style);
5297 SkMatrix matrix;
5298 matrix.setIdentity();
5299 for (int i = 0; i < 3; ++i) {
5300 canvas->translate(25, 60);
5301 canvas->drawPath(path, paint);
5302 canvas->drawTextOnPath(roller, len, path, &matrix, paint);
5303 matrix.preTranslate(0, 10);
5304 }
5305 }
Cary Clark8032b982017-07-28 11:04:54 -04005306##
5307
Cary Clark2ade9972017-11-02 17:49:34 -04005308#SeeAlso drawTextOnPathHV drawText drawPosTextH drawTextBlob drawTextRSXform
Cary Clark8032b982017-07-28 11:04:54 -04005309
5310##
5311
5312# ------------------------------------------------------------------------------
5313
5314#Method void drawTextRSXform(const void* text, size_t byteLength, const SkRSXform xform[],
5315 const SkRect* cullRect, const SkPaint& paint)
Cary Clarkab2621d2018-01-30 10:08:57 -05005316#Line # draws text with array of RSXform ##
Cary Clark8032b982017-07-28 11:04:54 -04005317
5318Draw text, transforming each glyph by the corresponding SkRSXform,
5319using Clip, Matrix, and Paint paint.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005320
Cary Clark8032b982017-07-28 11:04:54 -04005321RSXform array specifies a separate square scale, rotation, and translation for
5322each glyph.
Cary Clark8032b982017-07-28 11:04:54 -04005323
Cary Clarkbad5ad72017-08-03 17:14:08 -04005324Optional Rect cullRect is a conservative bounds of text, taking into account
Cary Clarkce101242017-09-01 15:51:02 -04005325RSXform and paint. If cullRect is outside of Clip, canvas can skip drawing.
Cary Clark8032b982017-07-28 11:04:54 -04005326
Mike Reed8ad91a92018-01-19 19:09:32 -05005327All elements of paint: Path_Effect, Mask_Filter, Shader,
Cary Clarkbad5ad72017-08-03 17:14:08 -04005328Color_Filter, Image_Filter, and Draw_Looper; apply to text. By default, draws
Cary Clarkce101242017-09-01 15:51:02 -04005329filled 12 point black Glyphs.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005330
Cary Clarkce101242017-09-01 15:51:02 -04005331#Param text character code points or Glyphs drawn ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005332#Param byteLength byte length of text array ##
5333#Param xform RSXform rotates, scales, and translates each glyph individually ##
5334#Param cullRect Rect bounds of text for efficient clipping; or nullptr ##
5335#Param paint text size, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005336
5337#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04005338void draw(SkCanvas* canvas) {
5339 const int iterations = 26;
5340 SkRSXform transforms[iterations];
5341 char alphabet[iterations];
5342 SkScalar angle = 0;
5343 SkScalar scale = 1;
5344 for (size_t i = 0; i < SK_ARRAY_COUNT(transforms); ++i) {
5345 const SkScalar s = SkScalarSin(angle) * scale;
5346 const SkScalar c = SkScalarCos(angle) * scale;
5347 transforms[i] = SkRSXform::Make(-c, -s, -s * 16, c * 16);
5348 angle += .45;
5349 scale += .2;
5350 alphabet[i] = 'A' + i;
5351 }
5352 SkPaint paint;
5353 paint.setTextAlign(SkPaint::kCenter_Align);
5354 canvas->translate(110, 138);
5355 canvas->drawTextRSXform(alphabet, sizeof(alphabet), transforms, nullptr, paint);
Cary Clark8032b982017-07-28 11:04:54 -04005356}
5357##
5358
Cary Clark2ade9972017-11-02 17:49:34 -04005359#SeeAlso drawTextOnPath drawTextOnPathHV drawText drawPosText drawTextBlob
Cary Clark8032b982017-07-28 11:04:54 -04005360
5361##
5362
5363# ------------------------------------------------------------------------------
5364
5365#Method void drawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y, const SkPaint& paint)
5366
Cary Clarkab2621d2018-01-30 10:08:57 -05005367#Line # draws text with arrays of positions and Paint ##
Cary Clark8032b982017-07-28 11:04:54 -04005368Draw Text_Blob blob at (x, y), using Clip, Matrix, and Paint paint.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005369
Cary Clarkce101242017-09-01 15:51:02 -04005370blob contains Glyphs, their positions, and paint attributes specific to text:
Cary Clarkbad5ad72017-08-03 17:14:08 -04005371Typeface, Paint_Text_Size, Paint_Text_Scale_X, Paint_Text_Skew_X,
5372Paint_Text_Align, Paint_Hinting, Anti-alias, Paint_Fake_Bold,
5373Font_Embedded_Bitmaps, Full_Hinting_Spacing, LCD_Text, Linear_Text,
5374Subpixel_Text, and Paint_Vertical_Text.
Cary Clark8032b982017-07-28 11:04:54 -04005375
Cary Clark3cd22cc2017-12-01 11:49:58 -05005376Paint_Text_Encoding must be set to SkPaint::kGlyphID_TextEncoding.
5377
Mike Reed8ad91a92018-01-19 19:09:32 -05005378Elements of paint: Path_Effect, Mask_Filter, Shader, Color_Filter,
Cary Clark8032b982017-07-28 11:04:54 -04005379Image_Filter, and Draw_Looper; apply to blob.
5380
Cary Clarkce101242017-09-01 15:51:02 -04005381#Param blob Glyphs, positions, and their paints' text size, typeface, and so on ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005382#Param x horizontal offset applied to blob ##
5383#Param y vertical offset applied to blob ##
5384#Param paint blend, color, stroking, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005385
5386#Example
5387#Height 120
Cary Clarkbad5ad72017-08-03 17:14:08 -04005388 void draw(SkCanvas* canvas) {
Cary Clark2f466242017-12-11 16:03:17 -05005389 SkTextBlobBuilder textBlobBuilder;
5390 const char bunny[] = "/(^x^)\\";
5391 const int len = sizeof(bunny) - 1;
5392 uint16_t glyphs[len];
5393 SkPaint paint;
5394 paint.textToGlyphs(bunny, len, glyphs);
Cary Clark3cd22cc2017-12-01 11:49:58 -05005395 paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
Cary Clark2f466242017-12-11 16:03:17 -05005396 int runs[] = { 3, 1, 3 };
5397 SkPoint textPos = { 20, 100 };
5398 int glyphIndex = 0;
5399 for (auto runLen : runs) {
5400 paint.setTextSize(1 == runLen ? 20 : 50);
5401 const SkTextBlobBuilder::RunBuffer& run =
5402 textBlobBuilder.allocRun(paint, runLen, textPos.fX, textPos.fY);
5403 memcpy(run.glyphs, &glyphs[glyphIndex], sizeof(glyphs[0]) * runLen);
5404 textPos.fX += paint.measureText(&glyphs[glyphIndex], sizeof(glyphs[0]) * runLen, nullptr);
5405 glyphIndex += runLen;
5406 }
5407 sk_sp<const SkTextBlob> blob = textBlobBuilder.make();
5408 paint.reset();
Cary Clarkbad5ad72017-08-03 17:14:08 -04005409 canvas->drawTextBlob(blob.get(), 0, 0, paint);
Cary Clark8032b982017-07-28 11:04:54 -04005410 }
5411##
5412
Cary Clark2ade9972017-11-02 17:49:34 -04005413#SeeAlso drawText drawPosText drawPosTextH
Cary Clark8032b982017-07-28 11:04:54 -04005414
5415##
5416
5417# ------------------------------------------------------------------------------
5418
5419#Method void drawTextBlob(const sk_sp<SkTextBlob>& blob, SkScalar x, SkScalar y, const SkPaint& paint)
5420
5421Draw Text_Blob blob at (x, y), using Clip, Matrix, and Paint paint.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005422
Cary Clarkce101242017-09-01 15:51:02 -04005423blob contains Glyphs, their positions, and paint attributes specific to text:
Cary Clarkbad5ad72017-08-03 17:14:08 -04005424Typeface, Paint_Text_Size, Paint_Text_Scale_X, Paint_Text_Skew_X,
5425Paint_Text_Align, Paint_Hinting, Anti-alias, Paint_Fake_Bold,
5426Font_Embedded_Bitmaps, Full_Hinting_Spacing, LCD_Text, Linear_Text,
5427Subpixel_Text, and Paint_Vertical_Text.
Cary Clark8032b982017-07-28 11:04:54 -04005428
Cary Clark3cd22cc2017-12-01 11:49:58 -05005429Paint_Text_Encoding must be set to SkPaint::kGlyphID_TextEncoding.
5430
Mike Reed8ad91a92018-01-19 19:09:32 -05005431Elements of paint: Path_Effect, Mask_Filter, Shader, Color_Filter,
Cary Clark8032b982017-07-28 11:04:54 -04005432Image_Filter, and Draw_Looper; apply to blob.
5433
Cary Clarkce101242017-09-01 15:51:02 -04005434#Param blob Glyphs, positions, and their paints' text size, typeface, and so on ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005435#Param x horizontal offset applied to blob ##
5436#Param y vertical offset applied to blob ##
5437#Param paint blend, color, stroking, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005438
5439#Example
5440#Height 120
5441#Description
5442Paint attributes unrelated to text, like color, have no effect on paint in allocated Text_Blob.
5443Paint attributes related to text, like text size, have no effect on paint passed to drawTextBlob.
5444##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005445 void draw(SkCanvas* canvas) {
5446 SkTextBlobBuilder textBlobBuilder;
5447 SkPaint paint;
5448 paint.setTextSize(50);
5449 paint.setColor(SK_ColorRED);
Cary Clark2f466242017-12-11 16:03:17 -05005450 paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
Cary Clarkbad5ad72017-08-03 17:14:08 -04005451 const SkTextBlobBuilder::RunBuffer& run =
5452 textBlobBuilder.allocRun(paint, 1, 20, 100);
5453 run.glyphs[0] = 20;
5454 sk_sp<const SkTextBlob> blob = textBlobBuilder.make();
5455 paint.setTextSize(10);
5456 paint.setColor(SK_ColorBLUE);
5457 canvas->drawTextBlob(blob.get(), 0, 0, paint);
5458 }
Cary Clark8032b982017-07-28 11:04:54 -04005459##
5460
Cary Clark2ade9972017-11-02 17:49:34 -04005461#SeeAlso drawText drawPosText drawPosTextH
Cary Clark8032b982017-07-28 11:04:54 -04005462
5463##
5464
5465# ------------------------------------------------------------------------------
5466
5467#Method void drawPicture(const SkPicture* picture)
5468
Cary Clarkab2621d2018-01-30 10:08:57 -05005469#Line # draws Picture using Clip and Matrix ##
Cary Clark8032b982017-07-28 11:04:54 -04005470Draw Picture picture, using Clip and Matrix.
5471Clip and Matrix are unchanged by picture contents, as if
5472save() was called before and restore() was called after drawPicture.
5473
5474Picture records a series of draw commands for later playback.
5475
Cary Clarkbad5ad72017-08-03 17:14:08 -04005476#Param picture recorded drawing commands to play ##
Cary Clark8032b982017-07-28 11:04:54 -04005477
5478#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04005479void draw(SkCanvas* canvas) {
5480 SkPictureRecorder recorder;
5481 SkCanvas* recordingCanvas = recorder.beginRecording(50, 50);
5482 for (auto color : { SK_ColorRED, SK_ColorBLUE, 0xff007f00 } ) {
5483 SkPaint paint;
5484 paint.setColor(color);
5485 recordingCanvas->drawRect({10, 10, 30, 40}, paint);
5486 recordingCanvas->translate(10, 10);
5487 recordingCanvas->scale(1.2f, 1.4f);
5488 }
5489 sk_sp<SkPicture> playback = recorder.finishRecordingAsPicture();
5490 const SkPicture* playbackPtr = playback.get();
5491 canvas->drawPicture(playback);
5492 canvas->scale(2, 2);
5493 canvas->translate(50, 0);
5494 canvas->drawPicture(playback);
Cary Clark8032b982017-07-28 11:04:54 -04005495}
5496##
5497
Cary Clark2ade9972017-11-02 17:49:34 -04005498#SeeAlso drawDrawable SkPicture SkPicture::playback
Cary Clark8032b982017-07-28 11:04:54 -04005499
5500##
5501
5502# ------------------------------------------------------------------------------
5503
5504#Method void drawPicture(const sk_sp<SkPicture>& picture)
5505
5506Draw Picture picture, using Clip and Matrix.
5507Clip and Matrix are unchanged by picture contents, as if
5508save() was called before and restore() was called after drawPicture.
5509
5510Picture records a series of draw commands for later playback.
5511
Cary Clarkbad5ad72017-08-03 17:14:08 -04005512#Param picture recorded drawing commands to play ##
Cary Clark8032b982017-07-28 11:04:54 -04005513
5514#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04005515void draw(SkCanvas* canvas) {
5516 SkPictureRecorder recorder;
5517 SkCanvas* recordingCanvas = recorder.beginRecording(50, 50);
5518 for (auto color : { SK_ColorRED, SK_ColorBLUE, 0xff007f00 } ) {
5519 SkPaint paint;
5520 paint.setColor(color);
5521 recordingCanvas->drawRect({10, 10, 30, 40}, paint);
5522 recordingCanvas->translate(10, 10);
5523 recordingCanvas->scale(1.2f, 1.4f);
5524 }
5525 sk_sp<SkPicture> playback = recorder.finishRecordingAsPicture();
5526 canvas->drawPicture(playback);
5527 canvas->scale(2, 2);
5528 canvas->translate(50, 0);
5529 canvas->drawPicture(playback);
Cary Clark8032b982017-07-28 11:04:54 -04005530}
5531##
5532
Cary Clark2ade9972017-11-02 17:49:34 -04005533#SeeAlso drawDrawable SkPicture SkPicture::playback
Cary Clark8032b982017-07-28 11:04:54 -04005534
5535##
5536
5537# ------------------------------------------------------------------------------
5538
5539#Method void drawPicture(const SkPicture* picture, const SkMatrix* matrix, const SkPaint* paint)
5540
Cary Clarkbad5ad72017-08-03 17:14:08 -04005541Draw Picture picture, using Clip and Matrix; transforming picture with
5542Matrix matrix, if provided; and use Paint paint Color_Alpha, Color_Filter,
5543Image_Filter, and Blend_Mode, if provided.
Cary Clark8032b982017-07-28 11:04:54 -04005544
5545matrix transformation is equivalent to: save(), concat(), drawPicture, restore().
5546paint use is equivalent to: saveLayer, drawPicture, restore().
5547
Cary Clarkbad5ad72017-08-03 17:14:08 -04005548#Param picture recorded drawing commands to play ##
5549#Param matrix Matrix to rotate, scale, translate, and so on; may be nullptr ##
5550#Param paint Paint to apply transparency, filtering, and so on; may be nullptr ##
Cary Clark8032b982017-07-28 11:04:54 -04005551
5552#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04005553void draw(SkCanvas* canvas) {
5554 SkPaint paint;
5555 SkPictureRecorder recorder;
5556 SkCanvas* recordingCanvas = recorder.beginRecording(50, 50);
5557 for (auto color : { SK_ColorRED, SK_ColorBLUE, 0xff007f00 } ) {
5558 paint.setColor(color);
5559 recordingCanvas->drawRect({10, 10, 30, 40}, paint);
5560 recordingCanvas->translate(10, 10);
5561 recordingCanvas->scale(1.2f, 1.4f);
5562 }
5563 sk_sp<SkPicture> playback = recorder.finishRecordingAsPicture();
5564 const SkPicture* playbackPtr = playback.get();
5565 SkMatrix matrix;
5566 matrix.reset();
5567 for (auto alpha : { 70, 140, 210 } ) {
5568 paint.setAlpha(alpha);
5569 canvas->drawPicture(playbackPtr, &matrix, &paint);
5570 matrix.preTranslate(70, 70);
5571 }
Cary Clark8032b982017-07-28 11:04:54 -04005572}
5573##
5574
Cary Clark2ade9972017-11-02 17:49:34 -04005575#SeeAlso drawDrawable SkPicture SkPicture::playback
Cary Clark8032b982017-07-28 11:04:54 -04005576
5577##
5578
5579# ------------------------------------------------------------------------------
5580
5581#Method void drawPicture(const sk_sp<SkPicture>& picture, const SkMatrix* matrix, const SkPaint* paint)
5582
Cary Clarkbad5ad72017-08-03 17:14:08 -04005583Draw Picture picture, using Clip and Matrix; transforming picture with
5584Matrix matrix, if provided; and use Paint paint Color_Alpha, Color_Filter,
5585Image_Filter, and Blend_Mode, if provided.
Cary Clark8032b982017-07-28 11:04:54 -04005586
5587matrix transformation is equivalent to: save(), concat(), drawPicture, restore().
5588paint use is equivalent to: saveLayer, drawPicture, restore().
5589
Cary Clarkbad5ad72017-08-03 17:14:08 -04005590#Param picture recorded drawing commands to play ##
5591#Param matrix Matrix to rotate, scale, translate, and so on; may be nullptr ##
5592#Param paint Paint to apply transparency, filtering, and so on; may be nullptr ##
Cary Clark8032b982017-07-28 11:04:54 -04005593
5594#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04005595void draw(SkCanvas* canvas) {
5596 SkPaint paint;
5597 SkPictureRecorder recorder;
5598 SkCanvas* recordingCanvas = recorder.beginRecording(50, 50);
5599 for (auto color : { SK_ColorRED, SK_ColorBLUE, 0xff007f00 } ) {
5600 paint.setColor(color);
5601 recordingCanvas->drawRect({10, 10, 30, 40}, paint);
5602 recordingCanvas->translate(10, 10);
5603 recordingCanvas->scale(1.2f, 1.4f);
5604 }
5605 sk_sp<SkPicture> playback = recorder.finishRecordingAsPicture();
5606 SkMatrix matrix;
5607 matrix.reset();
5608 for (auto alpha : { 70, 140, 210 } ) {
5609 paint.setAlpha(alpha);
5610 canvas->drawPicture(playback, &matrix, &paint);
5611 matrix.preTranslate(70, 70);
5612 }
Cary Clark8032b982017-07-28 11:04:54 -04005613}
5614##
5615
Cary Clark2ade9972017-11-02 17:49:34 -04005616#SeeAlso drawDrawable SkPicture SkPicture::playback
Cary Clark8032b982017-07-28 11:04:54 -04005617
5618##
5619
5620# ------------------------------------------------------------------------------
5621
5622#Method void drawVertices(const SkVertices* vertices, SkBlendMode mode, const SkPaint& paint)
5623
Cary Clarkab2621d2018-01-30 10:08:57 -05005624#Line # draws Vertices, a triangle mesh ##
Cary Clark8032b982017-07-28 11:04:54 -04005625Draw Vertices vertices, a triangle mesh, using Clip and Matrix.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005626If Vertices_Texs and Vertices_Colors are defined in vertices, and Paint paint
5627contains Shader, Blend_Mode mode combines Vertices_Colors with Shader.
Cary Clark8032b982017-07-28 11:04:54 -04005628
Cary Clarkbad5ad72017-08-03 17:14:08 -04005629#Param vertices triangle mesh to draw ##
5630#Param mode combines Vertices_Colors with Shader, if both are present ##
5631#Param paint specifies the Shader, used as Vertices texture; may be nullptr ##
Cary Clark8032b982017-07-28 11:04:54 -04005632
5633#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04005634void draw(SkCanvas* canvas) {
5635 SkPaint paint;
5636 SkPoint points[] = { { 0, 0 }, { 250, 0 }, { 100, 100 }, { 0, 250 } };
5637 SkColor colors[] = { SK_ColorRED, SK_ColorBLUE, SK_ColorYELLOW, SK_ColorCYAN };
5638 auto vertices = SkVertices::MakeCopy(SkVertices::kTriangleFan_VertexMode,
5639 SK_ARRAY_COUNT(points), points, nullptr, colors);
5640 canvas->drawVertices(vertices.get(), SkBlendMode::kSrc, paint);
5641}
Cary Clark8032b982017-07-28 11:04:54 -04005642##
5643
Cary Clark2ade9972017-11-02 17:49:34 -04005644#SeeAlso drawPatch drawPicture
Cary Clark8032b982017-07-28 11:04:54 -04005645
5646##
5647
5648# ------------------------------------------------------------------------------
5649
5650#Method void drawVertices(const sk_sp<SkVertices>& vertices, SkBlendMode mode, const SkPaint& paint)
5651
5652Draw Vertices vertices, a triangle mesh, using Clip and Matrix.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005653If Vertices_Texs and Vertices_Colors are defined in vertices, and Paint paint
5654contains Shader, Blend_Mode mode combines Vertices_Colors with Shader.
Cary Clark8032b982017-07-28 11:04:54 -04005655
Cary Clarkbad5ad72017-08-03 17:14:08 -04005656#Param vertices triangle mesh to draw ##
5657#Param mode combines Vertices_Colors with Shader, if both are present ##
5658#Param paint specifies the Shader, used as Vertices texture, may be nullptr ##
Cary Clark8032b982017-07-28 11:04:54 -04005659
5660#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04005661void draw(SkCanvas* canvas) {
5662 SkPaint paint;
5663 SkPoint points[] = { { 0, 0 }, { 250, 0 }, { 100, 100 }, { 0, 250 } };
5664 SkPoint texs[] = { { 0, 0 }, { 0, 250 }, { 250, 250 }, { 250, 0 } };
5665 SkColor colors[] = { SK_ColorRED, SK_ColorBLUE, SK_ColorYELLOW, SK_ColorCYAN };
5666 paint.setShader(SkGradientShader::MakeLinear(points, colors, nullptr, 4,
5667 SkShader::kClamp_TileMode));
5668 auto vertices = SkVertices::MakeCopy(SkVertices::kTriangleFan_VertexMode,
5669 SK_ARRAY_COUNT(points), points, texs, colors);
5670 canvas->drawVertices(vertices.get(), SkBlendMode::kDarken, paint);
Cary Clark8032b982017-07-28 11:04:54 -04005671}
5672##
5673
Cary Clark2ade9972017-11-02 17:49:34 -04005674#SeeAlso drawPatch drawPicture
Cary Clark8032b982017-07-28 11:04:54 -04005675
5676##
5677
5678# ------------------------------------------------------------------------------
5679
5680#Method void drawPatch(const SkPoint cubics[12], const SkColor colors[4],
5681 const SkPoint texCoords[4], SkBlendMode mode, const SkPaint& paint)
Cary Clarkab2621d2018-01-30 10:08:57 -05005682#Line # draws Coons_Patch ##
Cary Clark8032b982017-07-28 11:04:54 -04005683
Cary Clarka560c472017-11-27 10:44:06 -05005684Draws a Coons_Patch: the interpolation of four cubics with shared corners,
Cary Clark8032b982017-07-28 11:04:54 -04005685associating a color, and optionally a texture coordinate, with each corner.
5686
Cary Clarka560c472017-11-27 10:44:06 -05005687Coons_Patch uses Clip and Matrix, paint Shader, Color_Filter,
Cary Clarkbad5ad72017-08-03 17:14:08 -04005688Color_Alpha, Image_Filter, and Blend_Mode. If Shader is provided it is treated
Cary Clarka560c472017-11-27 10:44:06 -05005689as Coons_Patch texture; Blend_Mode mode combines Color colors and Shader if
Cary Clarkbad5ad72017-08-03 17:14:08 -04005690both are provided.
Cary Clark8032b982017-07-28 11:04:54 -04005691
Cary Clarkbc5697d2017-10-04 14:31:33 -04005692Point array cubics specifies four Cubics starting at the top-left corner,
Cary Clarkce101242017-09-01 15:51:02 -04005693in clockwise order, sharing every fourth point. The last Cubic ends at the
Cary Clarkbad5ad72017-08-03 17:14:08 -04005694first point.
Cary Clark8032b982017-07-28 11:04:54 -04005695
Cary Clarkbc5697d2017-10-04 14:31:33 -04005696Color array color associates colors with corners in top-left, top-right,
5697bottom-right, bottom-left order.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005698
5699If paint contains Shader, Point array texCoords maps Shader as texture to
Cary Clarkbc5697d2017-10-04 14:31:33 -04005700corners in top-left, top-right, bottom-right, bottom-left order.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005701
Cary Clarka523d2d2017-08-30 08:58:10 -04005702#Param cubics Path_Cubic array, sharing common points ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005703#Param colors Color array, one for each corner ##
Cary Clarkce101242017-09-01 15:51:02 -04005704#Param texCoords Point array of texture coordinates, mapping Shader to corners;
Cary Clarkbad5ad72017-08-03 17:14:08 -04005705 may be nullptr
Cary Clark579985c2017-07-31 11:48:27 -04005706#Param ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005707#Param mode Blend_Mode for colors, and for Shader if paint has one ##
5708#Param paint Shader, Color_Filter, Blend_Mode, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005709
5710#Example
5711#Image 5
Cary Clarkbad5ad72017-08-03 17:14:08 -04005712void draw(SkCanvas* canvas) {
5713 // SkBitmap source = cmbkygk;
5714 SkPaint paint;
5715 paint.setFilterQuality(kLow_SkFilterQuality);
5716 paint.setAntiAlias(true);
5717 SkPoint cubics[] = { { 3, 1 }, { 4, 2 }, { 5, 1 }, { 7, 3 },
5718 /* { 7, 3 }, */ { 6, 4 }, { 7, 5 }, { 5, 7 },
5719 /* { 5, 7 }, */ { 4, 6 }, { 3, 7 }, { 1, 5 },
5720 /* { 1, 5 }, */ { 2, 4 }, { 1, 3 }, /* { 3, 1 } */ };
5721 SkColor colors[] = { 0xbfff0000, 0xbf0000ff, 0xbfff00ff, 0xbf00ffff };
5722 SkPoint texCoords[] = { { -30, -30 }, { 162, -30}, { 162, 162}, { -30, 162} };
5723 paint.setShader(SkShader::MakeBitmapShader(source, SkShader::kClamp_TileMode,
5724 SkShader::kClamp_TileMode, nullptr));
5725 canvas->scale(15, 15);
5726 for (auto blend : { SkBlendMode::kSrcOver, SkBlendMode::kModulate, SkBlendMode::kXor } ) {
5727 canvas->drawPatch(cubics, colors, texCoords, blend, paint);
5728 canvas->translate(4, 4);
5729 }
Cary Clark8032b982017-07-28 11:04:54 -04005730}
5731##
5732
Cary Clark2ade9972017-11-02 17:49:34 -04005733#ToDo can patch use image filter? ##
5734#SeeAlso SeeAlso drawVertices drawPicture
Cary Clark8032b982017-07-28 11:04:54 -04005735
5736##
5737
5738# ------------------------------------------------------------------------------
5739
5740#Method void drawPatch(const SkPoint cubics[12], const SkColor colors[4],
5741 const SkPoint texCoords[4], const SkPaint& paint)
5742
Cary Clarka560c472017-11-27 10:44:06 -05005743Draws Cubic Coons_Patch: the interpolation of four cubics with shared corners,
Cary Clarkbad5ad72017-08-03 17:14:08 -04005744associating a color, and optionally a texture coordinate, with each corner.
Cary Clark8032b982017-07-28 11:04:54 -04005745
Cary Clarka560c472017-11-27 10:44:06 -05005746Coons_Patch uses Clip and Matrix, paint Shader, Color_Filter,
Cary Clarkbad5ad72017-08-03 17:14:08 -04005747Color_Alpha, Image_Filter, and Blend_Mode. If Shader is provided it is treated
Cary Clarka560c472017-11-27 10:44:06 -05005748as Coons_Patch texture; Blend_Mode mode combines Color colors and Shader if
Cary Clarkbad5ad72017-08-03 17:14:08 -04005749both are provided.
Cary Clark8032b982017-07-28 11:04:54 -04005750
Cary Clarkbc5697d2017-10-04 14:31:33 -04005751Point array cubics specifies four Cubics starting at the top-left corner,
Cary Clarkce101242017-09-01 15:51:02 -04005752in clockwise order, sharing every fourth point. The last Cubic ends at the
Cary Clarkbad5ad72017-08-03 17:14:08 -04005753first point.
5754
Cary Clarkbc5697d2017-10-04 14:31:33 -04005755Color array color associates colors with corners in top-left, top-right,
5756bottom-right, bottom-left order.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005757
5758If paint contains Shader, Point array texCoords maps Shader as texture to
Cary Clarkbc5697d2017-10-04 14:31:33 -04005759corners in top-left, top-right, bottom-right, bottom-left order.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005760
Cary Clarka523d2d2017-08-30 08:58:10 -04005761#Param cubics Path_Cubic array, sharing common points ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005762#Param colors Color array, one for each corner ##
Cary Clarkce101242017-09-01 15:51:02 -04005763#Param texCoords Point array of texture coordinates, mapping Shader to corners;
Cary Clarkbad5ad72017-08-03 17:14:08 -04005764 may be nullptr
Cary Clark579985c2017-07-31 11:48:27 -04005765#Param ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005766#Param paint Shader, Color_Filter, Blend_Mode, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005767
5768#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04005769void draw(SkCanvas* canvas) {
5770 SkPaint paint;
5771 paint.setAntiAlias(true);
5772 SkPoint cubics[] = { { 3, 1 }, { 4, 2 }, { 5, 1 }, { 7, 3 },
5773 /* { 7, 3 }, */ { 6, 4 }, { 7, 5 }, { 5, 7 },
5774 /* { 5, 7 }, */ { 4, 6 }, { 3, 7 }, { 1, 5 },
5775 /* { 1, 5 }, */ { 2, 4 }, { 1, 3 }, /* { 3, 1 } */ };
5776 SkColor colors[] = { SK_ColorRED, SK_ColorBLUE, SK_ColorYELLOW, SK_ColorCYAN };
5777 canvas->scale(30, 30);
5778 canvas->drawPatch(cubics, colors, nullptr, paint);
5779 SkPoint text[] = { {3,0.9f}, {4,2.5f}, {5,0.9f}, {7.5f,3.2f}, {5.5f,4.2f},
5780 {7.5f,5.2f}, {5,7.5f}, {4,5.9f}, {3,7.5f}, {0.5f,5.2f}, {2.5f,4.2f},
5781 {0.5f,3.2f} };
5782 paint.setTextSize(18.f / 30);
5783 paint.setTextAlign(SkPaint::kCenter_Align);
5784 for (int i = 0; i< 10; ++i) {
5785 char digit = '0' + i;
5786 canvas->drawText(&digit, 1, text[i].fX, text[i].fY, paint);
5787 }
5788 canvas->drawString("10", text[10].fX, text[10].fY, paint);
5789 canvas->drawString("11", text[11].fX, text[11].fY, paint);
5790 paint.setStyle(SkPaint::kStroke_Style);
5791 canvas->drawPoints(SkCanvas::kPolygon_PointMode, 12, cubics, paint);
5792 canvas->drawLine(cubics[11].fX, cubics[11].fY, cubics[0].fX, cubics[0].fY, paint);
Cary Clark8032b982017-07-28 11:04:54 -04005793}
5794##
5795
5796#Example
5797#Image 6
Cary Clarkbad5ad72017-08-03 17:14:08 -04005798void draw(SkCanvas* canvas) {
5799 // SkBitmap source = checkerboard;
5800 SkPaint paint;
5801 paint.setFilterQuality(kLow_SkFilterQuality);
5802 paint.setAntiAlias(true);
5803 SkPoint cubics[] = { { 3, 1 }, { 4, 2 }, { 5, 1 }, { 7, 3 },
5804 /* { 7, 3 }, */ { 6, 4 }, { 7, 5 }, { 5, 7 },
5805 /* { 5, 7 }, */ { 4, 6 }, { 3, 7 }, { 1, 5 },
5806 /* { 1, 5 }, */ { 2, 4 }, { 1, 3 }, /* { 3, 1 } */ };
5807 SkPoint texCoords[] = { { 0, 0 }, { 0, 62}, { 62, 62}, { 62, 0 } };
5808 paint.setShader(SkShader::MakeBitmapShader(source, SkShader::kClamp_TileMode,
5809 SkShader::kClamp_TileMode, nullptr));
5810 canvas->scale(30, 30);
5811 canvas->drawPatch(cubics, nullptr, texCoords, paint);
Cary Clark8032b982017-07-28 11:04:54 -04005812}
5813##
5814
Cary Clark2ade9972017-11-02 17:49:34 -04005815#ToDo can patch use image filter? ##
5816#SeeAlso SeeAlso drawVertices drawPicture
Cary Clark8032b982017-07-28 11:04:54 -04005817
5818##
5819
5820# ------------------------------------------------------------------------------
5821
5822#Method void drawAtlas(const SkImage* atlas, const SkRSXform xform[], const SkRect tex[],
5823 const SkColor colors[], int count, SkBlendMode mode, const SkRect* cullRect,
5824 const SkPaint* paint)
Cary Clarkab2621d2018-01-30 10:08:57 -05005825#Line # draws sprites using Clip, Matrix, and Paint ##
Cary Clark8032b982017-07-28 11:04:54 -04005826
5827Draw a set of sprites from atlas, using Clip, Matrix, and optional Paint paint.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005828paint uses Anti-alias, Color_Alpha, Color_Filter, Image_Filter, and Blend_Mode
5829to draw, if present. For each entry in the array, Rect tex locates sprite in
5830atlas, and RSXform xform transforms it into destination space.
5831
Cary Clark8032b982017-07-28 11:04:54 -04005832xform, text, and colors if present, must contain count entries.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005833Optional colors are applied for each sprite using Blend_Mode.
Cary Clark8032b982017-07-28 11:04:54 -04005834Optional cullRect is a conservative bounds of all transformed sprites.
Cary Clarkce101242017-09-01 15:51:02 -04005835If cullRect is outside of Clip, canvas can skip drawing.
Cary Clark8032b982017-07-28 11:04:54 -04005836
Cary Clarkbad5ad72017-08-03 17:14:08 -04005837#Param atlas Image containing sprites ##
5838#Param xform RSXform mappings for sprites in atlas ##
5839#Param tex Rect locations of sprites in atlas ##
Cary Clark6fc50412017-09-21 12:31:06 -04005840#Param colors one per sprite, blended with sprite using Blend_Mode; may be nullptr ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005841#Param count number of sprites to draw ##
5842#Param mode Blend_Mode combining colors and sprites ##
Cary Clark6fc50412017-09-21 12:31:06 -04005843#Param cullRect bounds of transformed sprites for efficient clipping; may be nullptr ##
5844#Param paint Color_Filter, Image_Filter, Blend_Mode, and so on; may be nullptr ##
Cary Clark8032b982017-07-28 11:04:54 -04005845
5846#Example
5847#Image 3
Cary Clarkbad5ad72017-08-03 17:14:08 -04005848void draw(SkCanvas* canvas) {
5849 // SkBitmap source = mandrill;
5850 SkRSXform xforms[] = { { .5f, 0, 0, 0 }, {0, .5f, 200, 100 } };
5851 SkRect tex[] = { { 0, 0, 250, 250 }, { 0, 0, 250, 250 } };
5852 SkColor colors[] = { 0x7f55aa00, 0x7f3333bf };
5853 const SkImage* imagePtr = image.get();
5854 canvas->drawAtlas(imagePtr, xforms, tex, colors, 2, SkBlendMode::kSrcOver, nullptr, nullptr);
Cary Clark8032b982017-07-28 11:04:54 -04005855}
5856##
5857
Cary Clark2ade9972017-11-02 17:49:34 -04005858#SeeAlso drawBitmap drawImage
Cary Clark8032b982017-07-28 11:04:54 -04005859
5860##
5861
5862# ------------------------------------------------------------------------------
5863
5864#Method void drawAtlas(const sk_sp<SkImage>& atlas, const SkRSXform xform[], const SkRect tex[],
5865 const SkColor colors[], int count, SkBlendMode mode, const SkRect* cullRect,
5866 const SkPaint* paint)
5867
5868Draw a set of sprites from atlas, using Clip, Matrix, and optional Paint paint.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005869paint uses Anti-alias, Color_Alpha, Color_Filter, Image_Filter, and Blend_Mode
5870to draw, if present. For each entry in the array, Rect tex locates sprite in
5871atlas, and RSXform xform transforms it into destination space.
5872
Cary Clark8032b982017-07-28 11:04:54 -04005873xform, text, and colors if present, must contain count entries.
5874Optional colors is applied for each sprite using Blend_Mode.
5875Optional cullRect is a conservative bounds of all transformed sprites.
Cary Clarkce101242017-09-01 15:51:02 -04005876If cullRect is outside of Clip, canvas can skip drawing.
Cary Clark8032b982017-07-28 11:04:54 -04005877
Cary Clarkbad5ad72017-08-03 17:14:08 -04005878#Param atlas Image containing sprites ##
5879#Param xform RSXform mappings for sprites in atlas ##
5880#Param tex Rect locations of sprites in atlas ##
Cary Clark6fc50412017-09-21 12:31:06 -04005881#Param colors one per sprite, blended with sprite using Blend_Mode; may be nullptr ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005882#Param count number of sprites to draw ##
5883#Param mode Blend_Mode combining colors and sprites ##
Cary Clark6fc50412017-09-21 12:31:06 -04005884#Param cullRect bounds of transformed sprites for efficient clipping; may be nullptr ##
5885#Param paint Color_Filter, Image_Filter, Blend_Mode, and so on; may be nullptr ##
Cary Clark8032b982017-07-28 11:04:54 -04005886
5887#Example
5888#Image 3
Cary Clarkbad5ad72017-08-03 17:14:08 -04005889void draw(SkCanvas* canvas) {
5890 // SkBitmap source = mandrill;
5891 SkRSXform xforms[] = { { .5f, 0, 0, 0 }, {0, .5f, 200, 100 } };
5892 SkRect tex[] = { { 0, 0, 250, 250 }, { 0, 0, 250, 250 } };
5893 SkColor colors[] = { 0x7f55aa00, 0x7f3333bf };
5894 SkPaint paint;
5895 paint.setAlpha(127);
5896 canvas->drawAtlas(image, xforms, tex, colors, 2, SkBlendMode::kPlus, nullptr, &paint);
Cary Clark8032b982017-07-28 11:04:54 -04005897}
5898##
5899
5900#ToDo bug in example on cpu side, gpu looks ok ##
5901
Cary Clark2ade9972017-11-02 17:49:34 -04005902#SeeAlso drawBitmap drawImage
5903
Cary Clark8032b982017-07-28 11:04:54 -04005904##
5905
5906# ------------------------------------------------------------------------------
5907
5908#Method void drawAtlas(const SkImage* atlas, const SkRSXform xform[], const SkRect tex[], int count,
5909 const SkRect* cullRect, const SkPaint* paint)
5910
5911Draw a set of sprites from atlas, using Clip, Matrix, and optional Paint paint.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005912paint uses Anti-alias, Color_Alpha, Color_Filter, Image_Filter, and Blend_Mode
5913to draw, if present. For each entry in the array, Rect tex locates sprite in
5914atlas, and RSXform xform transforms it into destination space.
5915
Cary Clark8032b982017-07-28 11:04:54 -04005916xform and text must contain count entries.
5917Optional cullRect is a conservative bounds of all transformed sprites.
Cary Clarkce101242017-09-01 15:51:02 -04005918If cullRect is outside of Clip, canvas can skip drawing.
Cary Clark8032b982017-07-28 11:04:54 -04005919
Cary Clarkbad5ad72017-08-03 17:14:08 -04005920#Param atlas Image containing sprites ##
5921#Param xform RSXform mappings for sprites in atlas ##
5922#Param tex Rect locations of sprites in atlas ##
5923#Param count number of sprites to draw ##
Cary Clark6fc50412017-09-21 12:31:06 -04005924#Param cullRect bounds of transformed sprites for efficient clipping; may be nullptr ##
5925#Param paint Color_Filter, Image_Filter, Blend_Mode, and so on; may be nullptr ##
Cary Clark8032b982017-07-28 11:04:54 -04005926
5927#Example
5928#Image 3
Cary Clarkbad5ad72017-08-03 17:14:08 -04005929void draw(SkCanvas* canvas) {
5930 // sk_sp<SkImage> image = mandrill;
5931 SkRSXform xforms[] = { { .5f, 0, 0, 0 }, {0, .5f, 200, 100 } };
5932 SkRect tex[] = { { 0, 0, 250, 250 }, { 0, 0, 250, 250 } };
5933 const SkImage* imagePtr = image.get();
5934 canvas->drawAtlas(imagePtr, xforms, tex, 2, nullptr, nullptr);
Cary Clark8032b982017-07-28 11:04:54 -04005935}
5936##
5937
Cary Clark2ade9972017-11-02 17:49:34 -04005938#SeeAlso drawBitmap drawImage
Cary Clark8032b982017-07-28 11:04:54 -04005939
5940##
5941
5942# ------------------------------------------------------------------------------
5943
5944#Method void drawAtlas(const sk_sp<SkImage>& atlas, const SkRSXform xform[], const SkRect tex[],
5945 int count, const SkRect* cullRect, const SkPaint* paint)
5946
5947Draw a set of sprites from atlas, using Clip, Matrix, and optional Paint paint.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005948paint uses Anti-alias, Color_Alpha, Color_Filter, Image_Filter, and Blend_Mode
5949to draw, if present. For each entry in the array, Rect tex locates sprite in
5950atlas, and RSXform xform transforms it into destination space.
5951
Cary Clark8032b982017-07-28 11:04:54 -04005952xform and text must contain count entries.
5953Optional cullRect is a conservative bounds of all transformed sprites.
Cary Clarkce101242017-09-01 15:51:02 -04005954If cullRect is outside of Clip, canvas can skip drawing.
Cary Clark8032b982017-07-28 11:04:54 -04005955
Cary Clarkbad5ad72017-08-03 17:14:08 -04005956#Param atlas Image containing sprites ##
5957#Param xform RSXform mappings for sprites in atlas ##
5958#Param tex Rect locations of sprites in atlas ##
5959#Param count number of sprites to draw ##
Cary Clark6fc50412017-09-21 12:31:06 -04005960#Param cullRect bounds of transformed sprites for efficient clipping; may be nullptr ##
5961#Param paint Color_Filter, Image_Filter, Blend_Mode, and so on; may be nullptr ##
Cary Clark8032b982017-07-28 11:04:54 -04005962
5963#Example
5964#Image 3
Cary Clarkbad5ad72017-08-03 17:14:08 -04005965void draw(SkCanvas* canvas) {
5966 // sk_sp<SkImage> image = mandrill;
5967 SkRSXform xforms[] = { { 1, 0, 0, 0 }, {0, 1, 300, 100 } };
5968 SkRect tex[] = { { 0, 0, 200, 200 }, { 200, 0, 400, 200 } };
5969 canvas->drawAtlas(image, xforms, tex, 2, nullptr, nullptr);
Cary Clark8032b982017-07-28 11:04:54 -04005970}
5971##
5972
Cary Clark2ade9972017-11-02 17:49:34 -04005973#SeeAlso drawBitmap drawImage
Cary Clark8032b982017-07-28 11:04:54 -04005974
5975##
5976
5977# ------------------------------------------------------------------------------
5978
Cary Clark73fa9722017-08-29 17:36:51 -04005979#Method void drawDrawable(SkDrawable* drawable, const SkMatrix* matrix = nullptr)
Cary Clark8032b982017-07-28 11:04:54 -04005980
Cary Clarkab2621d2018-01-30 10:08:57 -05005981#Line # draws Drawable, encapsulated drawing commands ##
Cary Clark8032b982017-07-28 11:04:54 -04005982Draw Drawable drawable using Clip and Matrix, concatenated with
5983optional matrix.
5984
5985If Canvas has an asynchronous implementation, as is the case
5986when it is recording into Picture, then drawable will be referenced,
5987so that SkDrawable::draw() can be called when the operation is finalized. To force
5988immediate drawing, call SkDrawable::draw() instead.
5989
Cary Clarkbad5ad72017-08-03 17:14:08 -04005990#Param drawable custom struct encapsulating drawing commands ##
5991#Param matrix transformation applied to drawing; may be nullptr ##
Cary Clark8032b982017-07-28 11:04:54 -04005992
5993#Example
5994#Height 100
5995#Function
Cary Clarkbad5ad72017-08-03 17:14:08 -04005996struct MyDrawable : public SkDrawable {
5997 SkRect onGetBounds() override { return SkRect::MakeWH(50, 100); }
5998
5999 void onDraw(SkCanvas* canvas) override {
6000 SkPath path;
6001 path.conicTo(10, 90, 50, 90, 0.9f);
6002 SkPaint paint;
6003 paint.setColor(SK_ColorBLUE);
6004 canvas->drawRect(path.getBounds(), paint);
6005 paint.setAntiAlias(true);
6006 paint.setColor(SK_ColorWHITE);
6007 canvas->drawPath(path, paint);
6008 }
6009};
6010
6011#Function ##
6012void draw(SkCanvas* canvas) {
6013 sk_sp<SkDrawable> drawable(new MyDrawable);
6014 SkMatrix matrix;
6015 matrix.setTranslate(10, 10);
6016 canvas->drawDrawable(drawable.get(), &matrix);
Cary Clark8032b982017-07-28 11:04:54 -04006017}
6018##
6019
Cary Clark2ade9972017-11-02 17:49:34 -04006020#SeeAlso SkDrawable drawPicture
Cary Clark8032b982017-07-28 11:04:54 -04006021
6022##
6023
6024# ------------------------------------------------------------------------------
6025
6026#Method void drawDrawable(SkDrawable* drawable, SkScalar x, SkScalar y)
6027
6028Draw Drawable drawable using Clip and Matrix, offset by (x, y).
6029
6030If Canvas has an asynchronous implementation, as is the case
6031when it is recording into Picture, then drawable will be referenced,
6032so that SkDrawable::draw() can be called when the operation is finalized. To force
6033immediate drawing, call SkDrawable::draw() instead.
6034
Cary Clarkbad5ad72017-08-03 17:14:08 -04006035#Param drawable custom struct encapsulating drawing commands ##
6036#Param x offset into Canvas writable pixels in x ##
6037#Param y offset into Canvas writable pixels in y ##
Cary Clark8032b982017-07-28 11:04:54 -04006038
6039#Example
6040#Height 100
6041#Function
Cary Clarkbad5ad72017-08-03 17:14:08 -04006042struct MyDrawable : public SkDrawable {
6043 SkRect onGetBounds() override { return SkRect::MakeWH(50, 100); }
6044
6045 void onDraw(SkCanvas* canvas) override {
6046 SkPath path;
6047 path.conicTo(10, 90, 50, 90, 0.9f);
6048 SkPaint paint;
6049 paint.setColor(SK_ColorBLUE);
6050 canvas->drawRect(path.getBounds(), paint);
6051 paint.setAntiAlias(true);
6052 paint.setColor(SK_ColorWHITE);
6053 canvas->drawPath(path, paint);
6054 }
6055};
6056
6057#Function ##
6058void draw(SkCanvas* canvas) {
6059 sk_sp<SkDrawable> drawable(new MyDrawable);
6060 canvas->drawDrawable(drawable.get(), 10, 10);
Cary Clark8032b982017-07-28 11:04:54 -04006061}
6062##
6063
Cary Clark2ade9972017-11-02 17:49:34 -04006064#SeeAlso SkDrawable drawPicture
Cary Clark8032b982017-07-28 11:04:54 -04006065
6066##
6067
6068# ------------------------------------------------------------------------------
6069
6070#Method void drawAnnotation(const SkRect& rect, const char key[], SkData* value)
6071
Cary Clarkab2621d2018-01-30 10:08:57 -05006072#Line # associates a Rect with a key-value pair ##
Cary Clark8032b982017-07-28 11:04:54 -04006073Associate Rect on Canvas when an annotation; a key-value pair, where the key is
6074a null-terminated utf8 string, and optional value is stored as Data.
6075
6076Only some canvas implementations, such as recording to Picture, or drawing to
6077Document_PDF, use annotations.
6078
Cary Clarkbad5ad72017-08-03 17:14:08 -04006079#Param rect Rect extent of canvas to annotate ##
6080#Param key string used for lookup ##
6081#Param value data holding value stored in annotation ##
Cary Clark8032b982017-07-28 11:04:54 -04006082
6083#Example
6084 #Height 1
6085 const char text[] = "Click this link!";
6086 SkRect bounds;
6087 SkPaint paint;
6088 paint.setTextSize(40);
6089 (void)paint.measureText(text, strlen(text), &bounds);
6090 const char url[] = "https://www.google.com/";
6091 sk_sp<SkData> urlData(SkData::MakeWithCString(url));
6092 canvas->drawAnnotation(bounds, "url_key", urlData.get());
6093##
6094
Cary Clark2ade9972017-11-02 17:49:34 -04006095#SeeAlso SkPicture SkDocument
Cary Clark8032b982017-07-28 11:04:54 -04006096
6097##
6098
6099# ------------------------------------------------------------------------------
6100
6101#Method void drawAnnotation(const SkRect& rect, const char key[], const sk_sp<SkData>& value)
6102
6103Associate Rect on Canvas when an annotation; a key-value pair, where the key is
6104a null-terminated utf8 string, and optional value is stored as Data.
6105
6106Only some canvas implementations, such as recording to Picture, or drawing to
6107Document_PDF, use annotations.
6108
Cary Clarkbad5ad72017-08-03 17:14:08 -04006109#Param rect Rect extent of canvas to annotate ##
6110#Param key string used for lookup ##
6111#Param value data holding value stored in annotation ##
Cary Clark8032b982017-07-28 11:04:54 -04006112
6113#Example
6114#Height 1
6115 const char text[] = "Click this link!";
6116 SkRect bounds;
6117 SkPaint paint;
6118 paint.setTextSize(40);
6119 (void)paint.measureText(text, strlen(text), &bounds);
6120 const char url[] = "https://www.google.com/";
6121 sk_sp<SkData> urlData(SkData::MakeWithCString(url));
6122 canvas->drawAnnotation(bounds, "url_key", urlData.get());
6123##
6124
Cary Clark2ade9972017-11-02 17:49:34 -04006125#SeeAlso SkPicture SkDocument
Cary Clark8032b982017-07-28 11:04:54 -04006126
6127##
6128
6129#Method SkDrawFilter* getDrawFilter() const
6130
Cary Clarkab2621d2018-01-30 10:08:57 -05006131#Line # legacy; to be deprecated ##
Cary Clark8032b982017-07-28 11:04:54 -04006132Legacy call to be deprecated.
6133
6134#Deprecated
6135##
6136
6137##
6138
6139#Method virtual SkDrawFilter* setDrawFilter(SkDrawFilter* filter)
6140
Cary Clarkab2621d2018-01-30 10:08:57 -05006141#Line # legacy; to be deprecated ##
Cary Clark8032b982017-07-28 11:04:54 -04006142Legacy call to be deprecated.
6143
6144#Deprecated
6145##
6146
6147##
6148
6149# ------------------------------------------------------------------------------
6150
6151#Method virtual bool isClipEmpty() const
6152
Cary Clarkab2621d2018-01-30 10:08:57 -05006153#Line # returns if Clip is empty ##
Cary Clark8032b982017-07-28 11:04:54 -04006154Returns true if Clip is empty; that is, nothing will draw.
6155
Cary Clarkbad5ad72017-08-03 17:14:08 -04006156May do work when called; it should not be called
Cary Clark8032b982017-07-28 11:04:54 -04006157more often than needed. However, once called, subsequent calls perform no
6158work until Clip changes.
6159
Cary Clarkbad5ad72017-08-03 17:14:08 -04006160#Return true if Clip is empty ##
Cary Clark8032b982017-07-28 11:04:54 -04006161
6162#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04006163 void draw(SkCanvas* canvas) {
6164 SkDebugf("clip is%s empty\n", canvas->isClipEmpty() ? "" : " not");
6165 SkPath path;
6166 canvas->clipPath(path);
6167 SkDebugf("clip is%s empty\n", canvas->isClipEmpty() ? "" : " not");
Cary Clark8032b982017-07-28 11:04:54 -04006168 }
6169 #StdOut
Cary Clarkbad5ad72017-08-03 17:14:08 -04006170 clip is not empty
Cary Clark8032b982017-07-28 11:04:54 -04006171 clip is empty
6172 ##
6173##
6174
Cary Clark2ade9972017-11-02 17:49:34 -04006175#SeeAlso isClipRect getLocalClipBounds getDeviceClipBounds
Cary Clark8032b982017-07-28 11:04:54 -04006176
6177##
6178
6179# ------------------------------------------------------------------------------
6180
6181#Method virtual bool isClipRect() const
6182
Cary Clarkab2621d2018-01-30 10:08:57 -05006183#Line # returns if Clip is Rect and not empty ##
Cary Clark8032b982017-07-28 11:04:54 -04006184Returns true if Clip is Rect and not empty.
6185Returns false if the clip is empty, or if it is not Rect.
6186
Cary Clarkbad5ad72017-08-03 17:14:08 -04006187#Return true if Clip is Rect and not empty ##
Cary Clark8032b982017-07-28 11:04:54 -04006188
6189#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04006190 void draw(SkCanvas* canvas) {
6191 SkDebugf("clip is%s rect\n", canvas->isClipRect() ? "" : " not");
6192 canvas->clipRect({0, 0, 0, 0});
6193 SkDebugf("clip is%s rect\n", canvas->isClipRect() ? "" : " not");
Cary Clark8032b982017-07-28 11:04:54 -04006194 }
6195 #StdOut
Cary Clarkbad5ad72017-08-03 17:14:08 -04006196 clip is rect
Cary Clark8032b982017-07-28 11:04:54 -04006197 clip is not rect
6198 ##
6199##
6200
Cary Clark2ade9972017-11-02 17:49:34 -04006201#SeeAlso isClipEmpty getLocalClipBounds getDeviceClipBounds
Cary Clark8032b982017-07-28 11:04:54 -04006202
6203##
6204
6205#Class SkCanvas ##
Cary Clark884dd7d2017-10-11 10:37:52 -04006206
Cary Clark8032b982017-07-28 11:04:54 -04006207#Topic Canvas ##