blob: 67445d446470f364bf9f93207e9746b1fcd15203 [file] [log] [blame]
Cary Clark8032b982017-07-28 11:04:54 -04001#Topic Canvas
Cary Clark12799e12017-07-28 15:18:29 -04002#Alias Canvas_Reference
Cary Clark8032b982017-07-28 11:04:54 -04003
Cary Clark08895c42018-02-01 09:37:32 -05004#Subtopic Overview
Cary Clark4855f782018-02-06 09:41:53 -05005 #Subtopic Subtopic
Cary Clark08895c42018-02-01 09:37:32 -05006 #Populate
7 ##
8##
9
Cary Clarke4aa3712017-09-15 02:56:12 -040010#Class SkCanvas
11
Cary Clark8032b982017-07-28 11:04:54 -040012Canvas provides an interface for drawing, and how the drawing is clipped and transformed.
13Canvas contains a stack of Matrix and Clip values.
14
15Canvas and Paint together provide the state to draw into Surface or Device.
Cary Clarkbad5ad72017-08-03 17:14:08 -040016Each Canvas draw call transforms the geometry of the object by the concatenation of all
17Matrix values in the stack. The transformed geometry is clipped by the intersection
18of all of Clip values in the stack. The Canvas draw calls use Paint to supply drawing
19state such as Color, Typeface, text size, stroke width, Shader and so on.
Cary Clark8032b982017-07-28 11:04:54 -040020
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 Clark4855f782018-02-06 09:41:53 -050033#Subtopic Related_Function
Cary Clark08895c42018-02-01 09:37:32 -050034#Populate
35##
Cary Clark8032b982017-07-28 11:04:54 -040036
Cary Clark4855f782018-02-06 09:41:53 -050037#Subtopic Constant
Cary Clark08895c42018-02-01 09:37:32 -050038#Populate
39##
Cary Clark8032b982017-07-28 11:04:54 -040040
Cary Clark4855f782018-02-06 09:41:53 -050041#Subtopic Class_or_Struct
Cary Clark08895c42018-02-01 09:37:32 -050042#Populate
43##
Cary Clark8032b982017-07-28 11:04:54 -040044
Cary Clark4855f782018-02-06 09:41:53 -050045#Subtopic Constructor
Cary Clark8032b982017-07-28 11:04:54 -040046
Cary Clark4855f782018-02-06 09:41:53 -050047Create the desired type of Surface to obtain its Canvas when possible. Useful
Cary Clark8032b982017-07-28 11:04:54 -040048when no Surface is required, and some helpers implicitly create Raster_Surface.
49
Cary Clark08895c42018-02-01 09:37:32 -050050#Populate
51##
Cary Clark8032b982017-07-28 11:04:54 -040052
Cary Clark4855f782018-02-06 09:41:53 -050053#Subtopic Member_Function
Cary Clark08895c42018-02-01 09:37:32 -050054#Populate
55##
Cary Clark8032b982017-07-28 11:04:54 -040056
57# ------------------------------------------------------------------------------
58
Cary Clarka560c472017-11-27 10:44:06 -050059#Method static std::unique_ptr<SkCanvas> MakeRasterDirect(const SkImageInfo& info, void* pixels,
60 size_t rowBytes,
61 const SkSurfaceProps* props = nullptr)
Cary 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)
Cary Clark4855f782018-02-06 09:41:53 -0500298#Deprecated soon
Cary Clark8032b982017-07-28 11:04:54 -0400299##
300
301# ------------------------------------------------------------------------------
302
303#Method explicit SkCanvas(const SkBitmap& bitmap)
304
Cary Clarkab2621d2018-01-30 10:08:57 -0500305#Line # uses existing Bitmap ##
Cary Clark8032b982017-07-28 11:04:54 -0400306Construct a canvas that draws into bitmap.
307Sets SkSurfaceProps::kLegacyFontHost_InitType in constructed Surface.
308
Cary Clarkbad5ad72017-08-03 17:14:08 -0400309Bitmap is copied so that subsequently editing bitmap will not affect
310constructed Canvas.
311
312May be deprecated in the future.
313
Cary Clark8032b982017-07-28 11:04:54 -0400314#ToDo Should be deprecated? ##
315
Cary Clark2dc84ad2018-01-26 12:56:22 -0500316#Param bitmap width, height, Color_Type, Alpha_Type, and pixel
Cary Clarkbad5ad72017-08-03 17:14:08 -0400317 storage of Raster_Surface
Cary Clark8032b982017-07-28 11:04:54 -0400318##
319
Cary Clarkbad5ad72017-08-03 17:14:08 -0400320#Return Canvas that can be used to draw into bitmap ##
Cary Clark8032b982017-07-28 11:04:54 -0400321
322#Example
323#Description
324The actual output depends on the installed fonts.
325##
326 SkBitmap bitmap;
327 // create a bitmap 5 wide and 11 high
328 bitmap.allocPixels(SkImageInfo::MakeN32Premul(5, 11));
329 SkCanvas canvas(bitmap);
Cary Clarkce101242017-09-01 15:51:02 -0400330 canvas.clear(SK_ColorWHITE); // white is Unpremultiplied, in ARGB order
Cary Clark8032b982017-07-28 11:04:54 -0400331 SkPixmap pixmap; // provides guaranteed access to the drawn pixels
332 if (!canvas.peekPixels(&pixmap)) {
333 SkDebugf("peekPixels should never fail.\n");
334 }
Cary Clarkbc5697d2017-10-04 14:31:33 -0400335 const SkPMColor* pixels = pixmap.addr32(); // points to top-left of bitmap
Cary Clarkce101242017-09-01 15:51:02 -0400336 SkPMColor pmWhite = pixels[0]; // the Premultiplied format may vary
Cary Clark8032b982017-07-28 11:04:54 -0400337 SkPaint paint; // by default, draws black, 12 point text
338 canvas.drawString("!", 1, 10, paint); // 1 char at baseline (1, 10)
339 for (int y = 0; y < bitmap.height(); ++y) {
340 for (int x = 0; x < bitmap.width(); ++x) {
341 SkDebugf("%c", *pixels++ == pmWhite ? '-' : 'x');
342 }
343 SkDebugf("\n");
344 }
345
346 #StdOut
Cary Clarkd0530ba2017-09-14 11:25:39 -0400347 -----
348 ---x-
349 ---x-
350 ---x-
351 ---x-
352 ---x-
353 ---x-
354 -----
355 ---x-
356 ---x-
Cary Clark8032b982017-07-28 11:04:54 -0400357 -----
358 #StdOut ##
359##
360
Cary Clark2ade9972017-11-02 17:49:34 -0400361#SeeAlso MakeRasterDirect SkRasterHandleAllocator::MakeCanvas SkSurface::getCanvas SkCreateColorSpaceXformCanvas
Cary Clark8032b982017-07-28 11:04:54 -0400362
363##
364
Cary Clarkbad5ad72017-08-03 17:14:08 -0400365#EnumClass ColorBehavior
Cary Clark08895c42018-02-01 09:37:32 -0500366#Line # Android framework only ##
Cary Clark8032b982017-07-28 11:04:54 -0400367#Private
368Android framework only.
369##
370
371#Code
372 enum class ColorBehavior {
373 kLegacy,
374 };
375##
376#Const kLegacy 0
Cary Clarkbad5ad72017-08-03 17:14:08 -0400377 Is a placeholder to allow specialized constructor; has no meaning.
Cary Clark8032b982017-07-28 11:04:54 -0400378##
379##
380
Cary Clarkbad5ad72017-08-03 17:14:08 -0400381#Method SkCanvas(const SkBitmap& bitmap, ColorBehavior behavior)
382
Cary Clarkab2621d2018-01-30 10:08:57 -0500383#Line # Android framework only ##
Cary Clarkbad5ad72017-08-03 17:14:08 -0400384#Private
385Android framework only.
386##
387
388#Param bitmap specifies a bitmap for the canvas to draw into ##
389#Param behavior specializes this constructor; value is unused ##
390#Return Canvas that can be used to draw into bitmap ##
391
392#NoExample
393##
394##
Cary Clark8032b982017-07-28 11:04:54 -0400395
396# ------------------------------------------------------------------------------
397
398#Method SkCanvas(const SkBitmap& bitmap, const SkSurfaceProps& props)
399
Cary Clarkab2621d2018-01-30 10:08:57 -0500400#Line # uses existing Bitmap and Surface_Properties ##
Cary Clark8032b982017-07-28 11:04:54 -0400401Construct a canvas that draws into bitmap.
402Use props to match the device characteristics, like LCD striping.
403
Cary Clarkbad5ad72017-08-03 17:14:08 -0400404bitmap is copied so that subsequently editing bitmap will not affect
405constructed Canvas.
406
Cary Clark2dc84ad2018-01-26 12:56:22 -0500407#Param bitmap width, height, Color_Type, Alpha_Type,
Cary Clarkbad5ad72017-08-03 17:14:08 -0400408 and pixel storage of Raster_Surface
Cary Clark8032b982017-07-28 11:04:54 -0400409##
Cary Clarkbad5ad72017-08-03 17:14:08 -0400410#Param props order and orientation of RGB striping; and whether to use
411 device independent fonts
Cary Clark8032b982017-07-28 11:04:54 -0400412##
413
Cary Clarkbad5ad72017-08-03 17:14:08 -0400414#Return Canvas that can be used to draw into bitmap ##
Cary Clark8032b982017-07-28 11:04:54 -0400415
416#Example
417#Description
418The actual output depends on the installed fonts.
419##
420 SkBitmap bitmap;
421 // create a bitmap 5 wide and 11 high
422 bitmap.allocPixels(SkImageInfo::MakeN32Premul(5, 11));
423 SkCanvas canvas(bitmap, SkSurfaceProps(0, kUnknown_SkPixelGeometry));
Cary Clarkce101242017-09-01 15:51:02 -0400424 canvas.clear(SK_ColorWHITE); // white is Unpremultiplied, in ARGB order
Cary Clark8032b982017-07-28 11:04:54 -0400425 SkPixmap pixmap; // provides guaranteed access to the drawn pixels
426 if (!canvas.peekPixels(&pixmap)) {
427 SkDebugf("peekPixels should never fail.\n");
428 }
Cary Clarkbc5697d2017-10-04 14:31:33 -0400429 const SkPMColor* pixels = pixmap.addr32(); // points to top-left of bitmap
Cary Clarkce101242017-09-01 15:51:02 -0400430 SkPMColor pmWhite = pixels[0]; // the Premultiplied format may vary
Cary Clark8032b982017-07-28 11:04:54 -0400431 SkPaint paint; // by default, draws black, 12 point text
432 canvas.drawString("!", 1, 10, paint); // 1 char at baseline (1, 10)
433 for (int y = 0; y < bitmap.height(); ++y) {
434 for (int x = 0; x < bitmap.width(); ++x) {
435 SkDebugf("%c", *pixels++ == pmWhite ? '-' : 'x');
436 }
437 SkDebugf("\n");
438 }
439
440 #StdOut
441 -----
442 ---x-
443 ---x-
444 ---x-
445 ---x-
446 ---x-
447 ---x-
448 -----
449 ---x-
450 ---x-
451 -----
452 #StdOut ##
453##
454
Cary Clark2ade9972017-11-02 17:49:34 -0400455#SeeAlso MakeRasterDirect SkRasterHandleAllocator::MakeCanvas SkSurface::getCanvas SkCreateColorSpaceXformCanvas
Cary Clark8032b982017-07-28 11:04:54 -0400456
457##
458
459# ------------------------------------------------------------------------------
460
461#Method virtual ~SkCanvas()
462
Cary Clarkab2621d2018-01-30 10:08:57 -0500463#Line # draws saved Layers, frees resources ##
Cary Clark5081eed2018-01-22 07:55:48 -0500464Draws saved Layers, if any.
465Frees up resources used by Canvas.
Cary Clark8032b982017-07-28 11:04:54 -0400466
467#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -0400468#Description
Cary Clarkce101242017-09-01 15:51:02 -0400469Canvas Layer draws into bitmap. saveLayerAlpha sets up an additional
470drawing surface that blends with the bitmap. When Layer goes out of
471scope, Layer Destructor is called. The saved Layer is restored, drawing
Cary Clarkbad5ad72017-08-03 17:14:08 -0400472transparent letters.
473##
Cary Clarkf05bdda2017-08-24 12:59:48 -0400474void draw(SkCanvas* canvas) {
475 SkBitmap bitmap;
476 bitmap.allocPixels(SkImageInfo::MakeN32Premul(200, 200));
477 {
478 SkCanvas offscreen(bitmap);
479 SkPaint paint;
480 paint.setTextSize(100);
481 offscreen.drawString("ABC", 20, 160, paint);
482 SkRect layerBounds = SkRect::MakeXYWH(32, 32, 192, 192);
483 offscreen.saveLayerAlpha(&layerBounds, 128);
484 offscreen.clear(SK_ColorWHITE);
485 offscreen.drawString("DEF", 20, 160, paint);
486 }
487 canvas->drawBitmap(bitmap, 0, 0, nullptr);
Cary Clarkbad5ad72017-08-03 17:14:08 -0400488}
Cary Clark8032b982017-07-28 11:04:54 -0400489##
490
Cary Clarkbad5ad72017-08-03 17:14:08 -0400491#SeeAlso State_Stack
Cary Clark8032b982017-07-28 11:04:54 -0400492
493##
494
495# ------------------------------------------------------------------------------
496
497#Method SkMetaData& getMetaData()
498
Cary Clarkab2621d2018-01-30 10:08:57 -0500499#Line # associates additional data with the canvas ##
Cary Clarkf05bdda2017-08-24 12:59:48 -0400500Returns storage to associate additional data with the canvas.
Cary Clark8032b982017-07-28 11:04:54 -0400501The storage is freed when Canvas is deleted.
502
Cary Clarkbad5ad72017-08-03 17:14:08 -0400503#Return storage that can be read from and written to ##
Cary Clark8032b982017-07-28 11:04:54 -0400504
505#Example
506 const char* kHelloMetaData = "HelloMetaData";
507 SkCanvas canvas;
508 SkMetaData& metaData = canvas.getMetaData();
509 SkDebugf("before: %s\n", metaData.findString(kHelloMetaData));
510 metaData.setString(kHelloMetaData, "Hello!");
511 SkDebugf("during: %s\n", metaData.findString(kHelloMetaData));
512 metaData.removeString(kHelloMetaData);
513 SkDebugf("after: %s\n", metaData.findString(kHelloMetaData));
514
515 #StdOut
516 before: (null)
517 during: Hello!
518 after: (null)
519 #StdOut ##
520##
521
Cary Clark2ade9972017-11-02 17:49:34 -0400522#SeeAlso SkMetaData
Cary Clark8032b982017-07-28 11:04:54 -0400523
524##
525
526# ------------------------------------------------------------------------------
527
528#Method SkImageInfo imageInfo() const
529
Cary Clarkab2621d2018-01-30 10:08:57 -0500530#Line # returns Image_Info for Canvas ##
Cary Clark8032b982017-07-28 11:04:54 -0400531Returns Image_Info for Canvas. If Canvas is not associated with Raster_Surface or
Cary Clark2dc84ad2018-01-26 12:56:22 -0500532GPU_Surface, returned Color_Type is set to kUnknown_SkColorType.
Cary Clark8032b982017-07-28 11:04:54 -0400533
Cary Clark2dc84ad2018-01-26 12:56:22 -0500534#Return dimensions and Color_Type of Canvas ##
Cary Clark8032b982017-07-28 11:04:54 -0400535
536#Example
Cary Clarkf05bdda2017-08-24 12:59:48 -0400537 SkCanvas emptyCanvas;
538 SkImageInfo canvasInfo = emptyCanvas.imageInfo();
539 SkImageInfo emptyInfo;
540 SkDebugf("emptyInfo %c= canvasInfo\n", emptyInfo == canvasInfo ? '=' : '!');
541
542 #StdOut
543 emptyInfo == canvasInfo
544 ##
Cary Clark8032b982017-07-28 11:04:54 -0400545##
546
Cary Clark2ade9972017-11-02 17:49:34 -0400547#SeeAlso SkImageInfo MakeRasterDirect makeSurface
Cary Clark8032b982017-07-28 11:04:54 -0400548
549##
550
551# ------------------------------------------------------------------------------
552
553#Method bool getProps(SkSurfaceProps* props) const
554
Cary Clarkab2621d2018-01-30 10:08:57 -0500555#Line # copies Surface_Properties if available ##
Cary Clark8032b982017-07-28 11:04:54 -0400556If Canvas is associated with Raster_Surface or
557GPU_Surface, copies Surface_Properties and returns true. Otherwise,
558return false and leave props unchanged.
559
Cary Clarkbad5ad72017-08-03 17:14:08 -0400560#Param props storage for writable SkSurfaceProps ##
Cary Clark8032b982017-07-28 11:04:54 -0400561
Cary Clarkbad5ad72017-08-03 17:14:08 -0400562#Return true if Surface_Properties was copied ##
Cary Clark8032b982017-07-28 11:04:54 -0400563
564#ToDo This seems old style. Deprecate? ##
565
566#Example
567 SkBitmap bitmap;
568 SkCanvas canvas(bitmap, SkSurfaceProps(0, kRGB_V_SkPixelGeometry));
569 SkSurfaceProps surfaceProps(0, kUnknown_SkPixelGeometry);
570 SkDebugf("isRGB:%d\n", SkPixelGeometryIsRGB(surfaceProps.pixelGeometry()));
571 if (!canvas.getProps(&surfaceProps)) {
572 SkDebugf("getProps failed unexpectedly.\n");
573 }
574 SkDebugf("isRGB:%d\n", SkPixelGeometryIsRGB(surfaceProps.pixelGeometry()));
575
576 #StdOut
577 isRGB:0
578 isRGB:1
579 #StdOut ##
580##
581
Cary Clark2ade9972017-11-02 17:49:34 -0400582#SeeAlso SkSurfaceProps makeSurface
Cary Clark8032b982017-07-28 11:04:54 -0400583
584##
585
586# ------------------------------------------------------------------------------
587
588#Method void flush()
589
Cary Clarkab2621d2018-01-30 10:08:57 -0500590#Line # triggers execution of all pending draw operations ##
Cary Clark8032b982017-07-28 11:04:54 -0400591Triggers the immediate execution of all pending draw operations.
Cary Clarkbad5ad72017-08-03 17:14:08 -0400592If Canvas is associated with GPU_Surface, resolves all pending GPU operations.
Cary Clark2ade9972017-11-02 17:49:34 -0400593If Canvas is associated with Raster_Surface, has no effect; raster draw
594operations are never deferred.
595
596#ToDo
597In an overview section on managing the GPU, include:
598- flush should never change what is drawn
599- call to kick off gpu work
600- calling too much impacts performance
601- some calls (peekPixels, prepareForExternalIO) call it internally
602- canvas call is local, GrContext::flush is global
603- diffentiate between flush, flushAndSignalSemaphores
604- normally never needs to be called
605- call it when sharing gpu resources, feeling memory pressure, swapping out app, and before
606 abandoning context
607- also call to say "I'm finished drawing here", e.g., when drawing to a GPU-backed offscreen surface
608 (created with SkSurface::MakeRenderTarget)
609
610for posterity: this doesn't show a difference: fiddle.skia.org/c/@flushfail
611##
Cary Clark8032b982017-07-28 11:04:54 -0400612
Cary Clark08895c42018-02-01 09:37:32 -0500613#ToDo haven't thought of a useful example to put here ##
614#NoExample
Cary Clark8032b982017-07-28 11:04:54 -0400615##
616
Cary Clark2ade9972017-11-02 17:49:34 -0400617#SeeAlso peekPixels SkSurface::flush() GrContext::flush() SkSurface::prepareForExternalIO GrContext::abandonContext()
Cary Clark8032b982017-07-28 11:04:54 -0400618
619##
620
621# ------------------------------------------------------------------------------
622
623#Method virtual SkISize getBaseLayerSize() const
624
Cary Clarkab2621d2018-01-30 10:08:57 -0500625#Line # returns size of base Layer in global coordinates ##
Cary Clarkce101242017-09-01 15:51:02 -0400626Gets the size of the base or root Layer in global canvas coordinates. The
627origin of the base Layer is always (0,0). The area available for drawing may be
Cary Clark8032b982017-07-28 11:04:54 -0400628smaller (due to clipping or saveLayer).
629
Cary Clarkce101242017-09-01 15:51:02 -0400630#Return integral width and height of base Layer ##
Cary Clark8032b982017-07-28 11:04:54 -0400631
632#Example
633 SkBitmap bitmap;
634 bitmap.allocPixels(SkImageInfo::MakeN32Premul(20, 30));
635 SkCanvas canvas(bitmap, SkSurfaceProps(0, kUnknown_SkPixelGeometry));
636 canvas.clipRect(SkRect::MakeWH(10, 40));
637 SkIRect clipDeviceBounds = canvas.getDeviceClipBounds();
638 if (clipDeviceBounds.isEmpty()) {
639 SkDebugf("Empty clip bounds is unexpected!\n");
640 }
641 SkDebugf("clip=%d,%d\n", clipDeviceBounds.width(), clipDeviceBounds.height());
642 SkISize baseLayerSize = canvas.getBaseLayerSize();
643 SkDebugf("size=%d,%d\n", baseLayerSize.width(), baseLayerSize.height());
644
645 #StdOut
646 clip=10,30
647 size=20,30
648 ##
649##
650
651#ToDo is this the same as the width and height of surface? ##
652
Cary Clark2ade9972017-11-02 17:49:34 -0400653#SeeAlso getDeviceClipBounds
654
Cary Clark8032b982017-07-28 11:04:54 -0400655##
656
657# ------------------------------------------------------------------------------
658
659#Method sk_sp<SkSurface> makeSurface(const SkImageInfo& info, const SkSurfaceProps* props = nullptr)
Cary Clark4855f782018-02-06 09:41:53 -0500660#In Constructor
Cary Clarkab2621d2018-01-30 10:08:57 -0500661#Line # creates Surface matching SkImageInfo and SkSurfaceProps ##
Cary Clark8032b982017-07-28 11:04:54 -0400662Creates Surface matching info and props, and associates it with Canvas.
Cary Clarkbad5ad72017-08-03 17:14:08 -0400663Returns nullptr if no match found.
Cary Clark8032b982017-07-28 11:04:54 -0400664
Cary Clarkbad5ad72017-08-03 17:14:08 -0400665If props is nullptr, matches Surface_Properties in Canvas. If props is nullptr and Canvas
666does not have Surface_Properties, creates Surface with default Surface_Properties.
Cary Clark8032b982017-07-28 11:04:54 -0400667
Cary Clark2dc84ad2018-01-26 12:56:22 -0500668#Param info width, height, Color_Type, Alpha_Type, and Color_Space ##
Cary Clarkbad5ad72017-08-03 17:14:08 -0400669#Param props Surface_Properties to match; may be nullptr to match Canvas ##
670
671#Return Surface matching info and props, or nullptr if no match is available ##
Cary Clark8032b982017-07-28 11:04:54 -0400672
673#Example
674 sk_sp<SkSurface> surface = SkSurface::MakeRasterN32Premul(5, 6);
675 SkCanvas* smallCanvas = surface->getCanvas();
676 SkImageInfo imageInfo = SkImageInfo::MakeN32Premul(3, 4);
677 sk_sp<SkSurface> compatible = smallCanvas->makeSurface(imageInfo);
678 SkDebugf("compatible %c= nullptr\n", compatible == nullptr ? '=' : '!');
679 SkDebugf("size = %d, %d\n", compatible->width(), compatible->height());
680
681 #StdOut
Cary Clarkbad5ad72017-08-03 17:14:08 -0400682 compatible != nullptr
Cary Clark8032b982017-07-28 11:04:54 -0400683 size = 3, 4
684 ##
685##
686
Cary Clark2ade9972017-11-02 17:49:34 -0400687#SeeAlso SkSurface SkSurface::makeSurface SkImageInfo SkSurfaceProps
Cary Clark8032b982017-07-28 11:04:54 -0400688
689##
690
691# ------------------------------------------------------------------------------
692
693#Method virtual GrContext* getGrContext()
694
Cary Clarkab2621d2018-01-30 10:08:57 -0500695#Line # returns GPU_Context of the GPU_Surface ##
Cary Clark8032b982017-07-28 11:04:54 -0400696Returns GPU_Context of the GPU_Surface associated with Canvas.
697
Cary Clarkbad5ad72017-08-03 17:14:08 -0400698#Return GPU_Context, if available; nullptr otherwise ##
Cary Clark8032b982017-07-28 11:04:54 -0400699
700#Example
701void draw(SkCanvas* canvas) {
702 if (canvas->getGrContext()) {
703 canvas->clear(SK_ColorRED);
704 } else {
705 canvas->clear(SK_ColorBLUE);
706 }
707}
708##
709
710#ToDo fiddle should show both CPU and GPU out ##
711
Cary Clark2ade9972017-11-02 17:49:34 -0400712#SeeAlso GrContext
713
Cary Clark8032b982017-07-28 11:04:54 -0400714##
715
716# ------------------------------------------------------------------------------
717
Cary Clark73fa9722017-08-29 17:36:51 -0400718#Method void* accessTopLayerPixels(SkImageInfo* info, size_t* rowBytes, SkIPoint* origin = nullptr)
Cary Clark8032b982017-07-28 11:04:54 -0400719
Cary Clarkab2621d2018-01-30 10:08:57 -0500720#Line # returns writable pixel access if available ##
Cary Clark8032b982017-07-28 11:04:54 -0400721Returns the pixel base address, Image_Info, rowBytes, and origin if the pixels
Cary Clarkbad5ad72017-08-03 17:14:08 -0400722can be read directly. The returned address is only valid
Cary Clark8032b982017-07-28 11:04:54 -0400723while Canvas is in scope and unchanged. Any Canvas call or Surface call
724may invalidate the returned address and other returned values.
725
726If pixels are inaccessible, info, rowBytes, and origin are unchanged.
727
Cary Clarkbad5ad72017-08-03 17:14:08 -0400728#Param info storage for writable pixels' Image_Info; may be nullptr ##
729#Param rowBytes storage for writable pixels' row bytes; may be nullptr ##
Cary Clarkbc5697d2017-10-04 14:31:33 -0400730#Param origin storage for Canvas top Layer origin, its top-left corner;
Cary Clarkbad5ad72017-08-03 17:14:08 -0400731 may be nullptr
732##
Cary Clark8032b982017-07-28 11:04:54 -0400733
Cary Clarka523d2d2017-08-30 08:58:10 -0400734#Return address of pixels, or nullptr if inaccessible ##
Cary Clark8032b982017-07-28 11:04:54 -0400735
736#Example
737void draw(SkCanvas* canvas) {
738 if (canvas->accessTopLayerPixels(nullptr, nullptr)) {
739 canvas->clear(SK_ColorRED);
740 } else {
741 canvas->clear(SK_ColorBLUE);
742 }
743}
744##
745
746#Example
747#Description
Cary Clarkce101242017-09-01 15:51:02 -0400748Draws "ABC" on the device. Then draws "DEF" in Layer, and reads
749Layer to add a large dotted "DEF". Finally blends Layer with the
Cary Clark8032b982017-07-28 11:04:54 -0400750device.
751
Cary Clarkce101242017-09-01 15:51:02 -0400752The Layer and blended result appear on the CPU and GPU but the large dotted
Cary Clark8032b982017-07-28 11:04:54 -0400753"DEF" appear only on the CPU.
754##
755void draw(SkCanvas* canvas) {
Cary Clarkbad5ad72017-08-03 17:14:08 -0400756 SkPaint paint;
757 paint.setTextSize(100);
758 canvas->drawString("ABC", 20, 160, paint);
759 SkRect layerBounds = SkRect::MakeXYWH(32, 32, 192, 192);
760 canvas->saveLayerAlpha(&layerBounds, 128);
761 canvas->clear(SK_ColorWHITE);
762 canvas->drawString("DEF", 20, 160, paint);
763 SkImageInfo imageInfo;
764 size_t rowBytes;
765 SkIPoint origin;
766 uint32_t* access = (uint32_t*) canvas->accessTopLayerPixels(&imageInfo, &rowBytes, &origin);
767 if (access) {
768 int h = imageInfo.height();
769 int v = imageInfo.width();
770 int rowWords = rowBytes / sizeof(uint32_t);
771 for (int y = 0; y < h; ++y) {
772 int newY = (y - h / 2) * 2 + h / 2;
773 if (newY < 0 || newY >= h) {
774 continue;
775 }
776 for (int x = 0; x < v; ++x) {
777 int newX = (x - v / 2) * 2 + v / 2;
778 if (newX < 0 || newX >= v) {
779 continue;
780 }
781 if (access[y * rowWords + x] == SK_ColorBLACK) {
782 access[newY * rowWords + newX] = SK_ColorGRAY;
783 }
784 }
785 }
786
787 }
Cary Clark8032b982017-07-28 11:04:54 -0400788 canvas->restore();
789}
790##
791
792#ToDo there are no callers of this that I can find. Deprecate? ##
793#ToDo fiddle should show both CPU and GPU out ##
794
Cary Clark2ade9972017-11-02 17:49:34 -0400795#SeeAlso SkImageInfo SkPixmap
796
Cary Clark8032b982017-07-28 11:04:54 -0400797##
798
799# ------------------------------------------------------------------------------
800
801#Method SkRasterHandleAllocator::Handle accessTopRasterHandle() const
802
Cary Clarkab2621d2018-01-30 10:08:57 -0500803#Line # returns context that tracks Clip and Matrix ##
Cary Clark8032b982017-07-28 11:04:54 -0400804Returns custom context that tracks the Matrix and Clip.
805
806Use Raster_Handle_Allocator to blend Skia drawing with custom drawing, typically performed
Cary Clarkbc5697d2017-10-04 14:31:33 -0400807by the host platform user interface. The custom context returned is generated by
Cary Clarkbad5ad72017-08-03 17:14:08 -0400808SkRasterHandleAllocator::MakeCanvas, which creates a custom canvas with raster storage for
Cary Clark8032b982017-07-28 11:04:54 -0400809the drawing destination.
810
Cary Clarkce101242017-09-01 15:51:02 -0400811#Return context of custom allocation ##
Cary Clark8032b982017-07-28 11:04:54 -0400812
813#Example
814#Description
815#ToDo ##
816##
817#Function
818 static void DeleteCallback(void*, void* context) {
819 delete (char*) context;
820 }
821
822 class CustomAllocator : public SkRasterHandleAllocator {
823 public:
824 bool allocHandle(const SkImageInfo& info, Rec* rec) override {
825 char* context = new char[4]{'s', 'k', 'i', 'a'};
826 rec->fReleaseProc = DeleteCallback;
827 rec->fReleaseCtx = context;
828 rec->fHandle = context;
829 rec->fPixels = context;
830 rec->fRowBytes = 4;
831 return true;
832 }
833
834 void updateHandle(Handle handle, const SkMatrix& ctm, const SkIRect& clip_bounds) override {
835 // apply canvas matrix and clip to custom environment
836 }
837 };
838
839##
840 void draw(SkCanvas* canvas) {
841 const SkImageInfo info = SkImageInfo::MakeN32Premul(1, 1);
842 std::unique_ptr<SkCanvas> c2 =
843 SkRasterHandleAllocator::MakeCanvas(std::unique_ptr<CustomAllocator>(
844 new CustomAllocator()), info);
845 char* context = (char*) c2->accessTopRasterHandle();
846 SkDebugf("context = %.4s\n", context);
847
848 }
849 #StdOut
850 context = skia
851 ##
852 #ToDo skstd::make_unique could not be used because def is private -- note to fix in c++14? ##
853##
854
855#SeeAlso SkRasterHandleAllocator
856
857##
858
859# ------------------------------------------------------------------------------
860
861#Method bool peekPixels(SkPixmap* pixmap)
862
Cary Clarkab2621d2018-01-30 10:08:57 -0500863#Line # returns if Canvas has direct access to its pixels ##
Cary Clark8032b982017-07-28 11:04:54 -0400864Returns true if Canvas has direct access to its pixels.
865
Cary Clarkf05bdda2017-08-24 12:59:48 -0400866Pixels are readable when Device is raster. Pixels are not readable when Canvas
Cary Clarkbad5ad72017-08-03 17:14:08 -0400867is returned from GPU_Surface, returned by SkDocument::beginPage, returned by
Cary Clarkf05bdda2017-08-24 12:59:48 -0400868SkPictureRecorder::beginRecording, or Canvas is the base of a utility class
Cary Clarkbad5ad72017-08-03 17:14:08 -0400869like SkDumpCanvas.
Cary Clark8032b982017-07-28 11:04:54 -0400870
Cary Clarkf05bdda2017-08-24 12:59:48 -0400871pixmap is valid only while Canvas is in scope and unchanged. Any
Cary Clarkbad5ad72017-08-03 17:14:08 -0400872Canvas or Surface call may invalidate the pixmap values.
Cary Clark8032b982017-07-28 11:04:54 -0400873
Cary Clarkbc5697d2017-10-04 14:31:33 -0400874#Param pixmap storage for pixel state if pixels are readable; otherwise, ignored ##
Cary Clark8032b982017-07-28 11:04:54 -0400875
Cary Clarkbad5ad72017-08-03 17:14:08 -0400876#Return true if Canvas has direct access to pixels ##
Cary Clark8032b982017-07-28 11:04:54 -0400877
878#Example
879 SkPixmap pixmap;
880 if (canvas->peekPixels(&pixmap)) {
881 SkDebugf("width=%d height=%d\n", pixmap.bounds().width(), pixmap.bounds().height());
882 }
883 #StdOut
884 width=256 height=256
885 ##
886##
887
Cary Clark2ade9972017-11-02 17:49:34 -0400888#SeeAlso readPixels SkBitmap::peekPixels SkImage::peekPixels SkSurface::peekPixels
889
Cary Clark8032b982017-07-28 11:04:54 -0400890##
891
892# ------------------------------------------------------------------------------
893
894#Method bool readPixels(const SkImageInfo& dstInfo, void* dstPixels, size_t dstRowBytes,
895 int srcX, int srcY)
Cary Clarkab2621d2018-01-30 10:08:57 -0500896#Line # copies and converts rectangle of pixels from Canvas ##
Cary Clark8032b982017-07-28 11:04:54 -0400897
Cary Clark154beea2017-10-26 07:58:48 -0400898Copies Rect of pixels from Canvas into dstPixels. Matrix and Clip are
Cary Clarka560c472017-11-27 10:44:06 -0500899ignored.
Cary Clark6fc50412017-09-21 12:31:06 -0400900
Cary Clarka560c472017-11-27 10:44:06 -0500901Source Rect corners are (srcX, srcY) and (imageInfo().width(), imageInfo().height()).
902Destination Rect corners are (0, 0) and (dstInfo.width(), dstInfo.height()).
Cary Clark6fc50412017-09-21 12:31:06 -0400903Copies each readable pixel intersecting both rectangles, without scaling,
Cary Clarkf05bdda2017-08-24 12:59:48 -0400904converting to dstInfo.colorType() and dstInfo.alphaType() if required.
Cary Clark8032b982017-07-28 11:04:54 -0400905
Cary Clarkf05bdda2017-08-24 12:59:48 -0400906Pixels are readable when Device is raster, or backed by a GPU.
907Pixels are not readable when SkCanvas is returned by SkDocument::beginPage,
908returned by SkPictureRecorder::beginRecording, or Canvas is the base of a utility
909class like SkDumpCanvas.
Cary Clark8032b982017-07-28 11:04:54 -0400910
Cary Clarkf05bdda2017-08-24 12:59:48 -0400911The destination pixel storage must be allocated by the caller.
Cary Clark8032b982017-07-28 11:04:54 -0400912
Cary Clark2dc84ad2018-01-26 12:56:22 -0500913Pixel values are converted only if Color_Type and Alpha_Type
Cary Clarkf05bdda2017-08-24 12:59:48 -0400914do not match. Only pixels within both source and destination rectangles
Cary Clark154beea2017-10-26 07:58:48 -0400915are copied. dstPixels contents outside Rect intersection are unchanged.
Cary Clarkf05bdda2017-08-24 12:59:48 -0400916
917Pass negative values for srcX or srcY to offset pixels across or down destination.
Cary Clark8032b982017-07-28 11:04:54 -0400918
919Does not copy, and returns false if:
920
921#List
Cary Clarkf05bdda2017-08-24 12:59:48 -0400922# Source and destination rectangles do not intersect. ##
923# Canvas pixels could not be converted to dstInfo.colorType() or dstInfo.alphaType(). ##
924# Canvas pixels are not readable; for instance, Canvas is document-based. ##
Cary Clark8032b982017-07-28 11:04:54 -0400925# dstRowBytes is too small to contain one row of pixels. ##
926##
927
Cary Clark2dc84ad2018-01-26 12:56:22 -0500928#Param dstInfo width, height, Color_Type, and Alpha_Type of dstPixels ##
Cary Clarkf05bdda2017-08-24 12:59:48 -0400929#Param dstPixels storage for pixels; dstInfo.height() times dstRowBytes, or larger ##
930#Param dstRowBytes size of one destination row; dstInfo.width() times pixel size, or larger ##
931#Param srcX offset into readable pixels in x; may be negative ##
932#Param srcY offset into readable pixels in y; may be negative ##
Cary Clark8032b982017-07-28 11:04:54 -0400933
Cary Clarkbad5ad72017-08-03 17:14:08 -0400934#Return true if pixels were copied ##
Cary Clark8032b982017-07-28 11:04:54 -0400935
936#Example
Cary Clarkf05bdda2017-08-24 12:59:48 -0400937#Width 64
938#Height 64
939#Description
940 A black circle drawn on a blue background provides an image to copy.
941 readPixels copies one quarter of the canvas into each of the four corners.
Cary Clarka560c472017-11-27 10:44:06 -0500942 The copied quarter circles overdraw the original circle.
Cary Clarkf05bdda2017-08-24 12:59:48 -0400943##
944 canvas->clear(SK_ColorBLUE);
945 SkPaint paint;
946 canvas->drawCircle(32, 32, 28, paint);
947 SkImageInfo info = SkImageInfo::Make(64, 64, kBGRA_8888_SkColorType, kPremul_SkAlphaType);
948 sk_sp<SkData> data(SkData::MakeUninitialized(info.minRowBytes() * info.height()));
949 sk_bzero(data->writable_data(), info.minRowBytes() * info.height());
950 for (int x : { 32, -32 } ) {
951 for (int y : { 32, -32 } ) {
952 canvas->readPixels(info, data->writable_data(), info.minRowBytes(), x, y);
953 }
954 }
955 sk_sp<SkImage> image = SkImage::MakeRasterData(info, data, info.minRowBytes());
956 canvas->drawImage(image, 0, 0);
957##
958
959#Example
Cary Clark8032b982017-07-28 11:04:54 -0400960#Description
Cary Clarkce101242017-09-01 15:51:02 -0400961 Canvas returned by Raster_Surface has Premultiplied pixel values.
962 clear() takes Unpremultiplied input with Color_Alpha equal 0x80
963 and Color_RGB equal 0x55, 0xAA, 0xFF. Color_RGB is multiplied by Color_Alpha
964 to generate Premultiplied value 0x802B5580. readPixels converts pixel back
965 to Unpremultiplied value 0x8056A9FF, introducing error.
Cary Clark8032b982017-07-28 11:04:54 -0400966##
967 canvas->clear(0x8055aaff);
968 for (SkAlphaType alphaType : { kPremul_SkAlphaType, kUnpremul_SkAlphaType } ) {
969 uint32_t pixel = 0;
970 SkImageInfo info = SkImageInfo::Make(1, 1, kBGRA_8888_SkColorType, alphaType);
971 if (canvas->readPixels(info, &pixel, 4, 0, 0)) {
972 SkDebugf("pixel = %08x\n", pixel);
973 }
974 }
975
976 #StdOut
977 pixel = 802b5580
978 pixel = 8056a9ff
979 ##
980##
981
Cary Clark2ade9972017-11-02 17:49:34 -0400982#SeeAlso peekPixels writePixels drawBitmap drawImage SkBitmap::readPixels SkPixmap::readPixels SkImage::readPixels SkSurface::readPixels
Cary Clark8032b982017-07-28 11:04:54 -0400983
984##
985
986# ------------------------------------------------------------------------------
987
988#Method bool readPixels(const SkPixmap& pixmap, int srcX, int srcY)
989
Cary Clark154beea2017-10-26 07:58:48 -0400990Copies Rect of pixels from Canvas into pixmap. Matrix and Clip are
Cary Clarka560c472017-11-27 10:44:06 -0500991ignored.
Cary Clark6fc50412017-09-21 12:31:06 -0400992
Cary Clarka560c472017-11-27 10:44:06 -0500993Source Rect corners are (srcX, srcY) and (imageInfo().width(), imageInfo().height()).
994Destination Rect corners are (0, 0) and (pixmap.width(), pixmap.height()).
Cary Clark6fc50412017-09-21 12:31:06 -0400995Copies each readable pixel intersecting both rectangles, without scaling,
Cary Clarkf05bdda2017-08-24 12:59:48 -0400996converting to pixmap.colorType() and pixmap.alphaType() if required.
Cary Clark8032b982017-07-28 11:04:54 -0400997
Cary Clarkf05bdda2017-08-24 12:59:48 -0400998Pixels are readable when Device is raster, or backed by a GPU.
999Pixels are not readable when SkCanvas is returned by SkDocument::beginPage,
1000returned by SkPictureRecorder::beginRecording, or Canvas is the base of a utility
1001class like SkDumpCanvas.
Cary Clark8032b982017-07-28 11:04:54 -04001002
Cary Clark6fc50412017-09-21 12:31:06 -04001003Caller must allocate pixel storage in pixmap if needed.
Cary Clark8032b982017-07-28 11:04:54 -04001004
Cary Clark2dc84ad2018-01-26 12:56:22 -05001005Pixel values are converted only if Color_Type and Alpha_Type
Cary Clark154beea2017-10-26 07:58:48 -04001006do not match. Only pixels within both source and destination Rects
1007are copied. pixmap pixels contents outside Rect intersection are unchanged.
Cary Clarkf05bdda2017-08-24 12:59:48 -04001008
1009Pass negative values for srcX or srcY to offset pixels across or down pixmap.
Cary Clark8032b982017-07-28 11:04:54 -04001010
1011Does not copy, and returns false if:
1012
1013#List
Cary Clarkf05bdda2017-08-24 12:59:48 -04001014# Source and destination rectangles do not intersect. ##
1015# Canvas pixels could not be converted to pixmap.colorType() or pixmap.alphaType(). ##
1016# Canvas pixels are not readable; for instance, Canvas is document-based. ##
1017# Pixmap pixels could not be allocated. ##
1018# pixmap.rowBytes() is too small to contain one row of pixels. ##
Cary Clark8032b982017-07-28 11:04:54 -04001019##
1020
Cary Clarkbad5ad72017-08-03 17:14:08 -04001021#Param pixmap storage for pixels copied from Canvas ##
Cary Clarkf05bdda2017-08-24 12:59:48 -04001022#Param srcX offset into readable pixels in x; may be negative ##
1023#Param srcY offset into readable pixels in y; may be negative ##
Cary Clark8032b982017-07-28 11:04:54 -04001024
Cary Clarkbad5ad72017-08-03 17:14:08 -04001025#Return true if pixels were copied ##
Cary Clark8032b982017-07-28 11:04:54 -04001026
1027#Example
Cary Clarkf05bdda2017-08-24 12:59:48 -04001028 #Description
Cary Clarkce101242017-09-01 15:51:02 -04001029 clear() takes Unpremultiplied input with Color_Alpha equal 0x80
1030 and Color_RGB equal 0x55, 0xAA, 0xFF. Color_RGB is multiplied by Color_Alpha
1031 to generate Premultiplied value 0x802B5580.
Cary Clarkf05bdda2017-08-24 12:59:48 -04001032 ##
1033 void draw(SkCanvas* canvas) {
1034 canvas->clear(0x8055aaff);
1035 uint32_t pixels[1] = { 0 };
1036 SkPixmap pixmap(SkImageInfo::MakeN32Premul(1, 1), pixels, 4);
1037 canvas->readPixels(pixmap, 0, 0);
1038 SkDebugf("pixel = %08x\n", pixels[0]);
1039 }
Cary Clark8032b982017-07-28 11:04:54 -04001040 #StdOut
1041 pixel = 802b5580
1042 ##
1043##
1044
Cary Clark2ade9972017-11-02 17:49:34 -04001045#SeeAlso peekPixels writePixels drawBitmap drawImage SkBitmap::readPixels SkPixmap::readPixels SkImage::readPixels SkSurface::readPixels
Cary Clark8032b982017-07-28 11:04:54 -04001046
1047##
1048
1049# ------------------------------------------------------------------------------
1050
1051#Method bool readPixels(const SkBitmap& bitmap, int srcX, int srcY)
1052
Cary Clark154beea2017-10-26 07:58:48 -04001053Copies Rect of pixels from Canvas into bitmap. Matrix and Clip are
Cary Clarka560c472017-11-27 10:44:06 -05001054ignored.
Cary Clark6fc50412017-09-21 12:31:06 -04001055
Cary Clarka560c472017-11-27 10:44:06 -05001056Source Rect corners are (srcX, srcY) and (imageInfo().width(), imageInfo().height()).
Cary Clark154beea2017-10-26 07:58:48 -04001057Destination Rect corners are (0, 0) and (bitmap.width(), bitmap.height()).
Cary Clarkf05bdda2017-08-24 12:59:48 -04001058Copies each readable pixel intersecting both rectangles, without scaling,
1059converting to bitmap.colorType() and bitmap.alphaType() if required.
Cary Clark8032b982017-07-28 11:04:54 -04001060
Cary Clarkf05bdda2017-08-24 12:59:48 -04001061Pixels are readable when Device is raster, or backed by a GPU.
1062Pixels are not readable when SkCanvas is returned by SkDocument::beginPage,
1063returned by SkPictureRecorder::beginRecording, or Canvas is the base of a utility
1064class like SkDumpCanvas.
Cary Clark8032b982017-07-28 11:04:54 -04001065
Cary Clark6fc50412017-09-21 12:31:06 -04001066Caller must allocate pixel storage in bitmap if needed.
Cary Clarkf05bdda2017-08-24 12:59:48 -04001067
Cary Clark2dc84ad2018-01-26 12:56:22 -05001068Bitmap values are converted only if Color_Type and Alpha_Type
Cary Clarkf05bdda2017-08-24 12:59:48 -04001069do not match. Only pixels within both source and destination rectangles
Cary Clark154beea2017-10-26 07:58:48 -04001070are copied. Bitmap pixels outside Rect intersection are unchanged.
Cary Clarkf05bdda2017-08-24 12:59:48 -04001071
1072Pass negative values for srcX or srcY to offset pixels across or down bitmap.
Cary Clark8032b982017-07-28 11:04:54 -04001073
1074Does not copy, and returns false if:
1075
1076#List
Cary Clarkf05bdda2017-08-24 12:59:48 -04001077# Source and destination rectangles do not intersect. ##
1078# Canvas pixels could not be converted to bitmap.colorType() or bitmap.alphaType(). ##
1079# Canvas pixels are not readable; for instance, Canvas is document-based. ##
Cary Clark8032b982017-07-28 11:04:54 -04001080# bitmap pixels could not be allocated. ##
Cary Clarkf05bdda2017-08-24 12:59:48 -04001081# bitmap.rowBytes() is too small to contain one row of pixels. ##
Cary Clark8032b982017-07-28 11:04:54 -04001082##
1083
Cary Clarkbad5ad72017-08-03 17:14:08 -04001084#Param bitmap storage for pixels copied from Canvas ##
Cary Clarkf05bdda2017-08-24 12:59:48 -04001085#Param srcX offset into readable pixels in x; may be negative ##
1086#Param srcY offset into readable pixels in y; may be negative ##
Cary Clark8032b982017-07-28 11:04:54 -04001087
Cary Clarkbad5ad72017-08-03 17:14:08 -04001088#Return true if pixels were copied ##
Cary Clark8032b982017-07-28 11:04:54 -04001089
1090#Example
Cary Clarkf05bdda2017-08-24 12:59:48 -04001091 #Description
Cary Clarkce101242017-09-01 15:51:02 -04001092 clear() takes Unpremultiplied input with Color_Alpha equal 0x80
1093 and Color_RGB equal 0x55, 0xAA, 0xFF. Color_RGB is multiplied by Color_Alpha
1094 to generate Premultiplied value 0x802B5580.
Cary Clarkf05bdda2017-08-24 12:59:48 -04001095 ##
Cary Clark8032b982017-07-28 11:04:54 -04001096void draw(SkCanvas* canvas) {
1097 canvas->clear(0x8055aaff);
1098 SkBitmap bitmap;
1099 bitmap.allocPixels(SkImageInfo::MakeN32Premul(1, 1));
1100 canvas->readPixels(bitmap, 0, 0);
1101 SkDebugf("pixel = %08x\n", bitmap.getAddr32(0, 0)[0]);
1102}
1103 #StdOut
1104 pixel = 802b5580
1105 ##
1106##
1107
Cary Clark2ade9972017-11-02 17:49:34 -04001108#SeeAlso peekPixels writePixels drawBitmap drawImage SkBitmap::readPixels SkPixmap::readPixels SkImage::readPixels SkSurface::readPixels
Cary Clark8032b982017-07-28 11:04:54 -04001109
1110##
1111
1112# ------------------------------------------------------------------------------
1113
1114#Method bool writePixels(const SkImageInfo& info, const void* pixels, size_t rowBytes, int x, int y)
1115
Cary Clarkab2621d2018-01-30 10:08:57 -05001116#Line # copies and converts rectangle of pixels to Canvas ##
Cary Clark154beea2017-10-26 07:58:48 -04001117Copies Rect from pixels to Canvas. Matrix and Clip are ignored.
1118Source Rect corners are (0, 0) and (info.width(), info.height()).
1119Destination Rect corners are (x, y) and
1120(imageInfo().width(), imageInfo().height()).
Cary Clark6fc50412017-09-21 12:31:06 -04001121
1122Copies each readable pixel intersecting both rectangles, without scaling,
Cary Clark154beea2017-10-26 07:58:48 -04001123converting to imageInfo().colorType() and imageInfo().alphaType() if required.
Cary Clark8032b982017-07-28 11:04:54 -04001124
Cary Clarkf05bdda2017-08-24 12:59:48 -04001125Pixels are writable when Device is raster, or backed by a GPU.
1126Pixels are not writable when SkCanvas is returned by SkDocument::beginPage,
1127returned by SkPictureRecorder::beginRecording, or Canvas is the base of a utility
1128class like SkDumpCanvas.
Cary Clark8032b982017-07-28 11:04:54 -04001129
Cary Clark2dc84ad2018-01-26 12:56:22 -05001130Pixel values are converted only if Color_Type and Alpha_Type
Cary Clarkf05bdda2017-08-24 12:59:48 -04001131do not match. Only pixels within both source and destination rectangles
Cary Clark154beea2017-10-26 07:58:48 -04001132are copied. Canvas pixels outside Rect intersection are unchanged.
Cary Clark8032b982017-07-28 11:04:54 -04001133
Cary Clarkf05bdda2017-08-24 12:59:48 -04001134Pass negative values for x or y to offset pixels to the left or
1135above Canvas pixels.
Cary Clark8032b982017-07-28 11:04:54 -04001136
1137Does not copy, and returns false if:
1138
1139#List
Cary Clarkf05bdda2017-08-24 12:59:48 -04001140# Source and destination rectangles do not intersect. ##
Cary Clarkac47b882018-01-11 10:35:44 -05001141# pixels could not be converted to Canvas imageInfo().colorType() or
1142 imageInfo().alphaType(). ##
Cary Clark8032b982017-07-28 11:04:54 -04001143# Canvas pixels are not writable; for instance, Canvas is document-based. ##
1144# rowBytes is too small to contain one row of pixels. ##
1145##
1146
Cary Clark2dc84ad2018-01-26 12:56:22 -05001147#Param info width, height, Color_Type, and Alpha_Type of pixels ##
Cary Clarkf05bdda2017-08-24 12:59:48 -04001148#Param pixels pixels to copy, of size info.height() times rowBytes, or larger ##
Cary Clarkd0530ba2017-09-14 11:25:39 -04001149#Param rowBytes size of one row of pixels; info.width() times pixel size, or larger ##
Cary Clarkf05bdda2017-08-24 12:59:48 -04001150#Param x offset into Canvas writable pixels in x; may be negative ##
1151#Param y offset into Canvas writable pixels in y; may be negative ##
Cary Clark8032b982017-07-28 11:04:54 -04001152
Cary Clarkbad5ad72017-08-03 17:14:08 -04001153#Return true if pixels were written to Canvas ##
Cary Clark8032b982017-07-28 11:04:54 -04001154
1155#Example
1156 SkImageInfo imageInfo = SkImageInfo::MakeN32(256, 1, kPremul_SkAlphaType);
1157 for (int y = 0; y < 256; ++y) {
1158 uint32_t pixels[256];
1159 for (int x = 0; x < 256; ++x) {
1160 pixels[x] = SkColorSetARGB(x, x + y, x, x - y);
1161 }
1162 canvas->writePixels(imageInfo, &pixels, sizeof(pixels), 0, y);
1163 }
1164##
1165
Cary Clark2ade9972017-11-02 17:49:34 -04001166#SeeAlso readPixels drawBitmap drawImage SkBitmap::writePixels
Cary Clark8032b982017-07-28 11:04:54 -04001167
1168##
1169
1170# ------------------------------------------------------------------------------
1171
1172#Method bool writePixels(const SkBitmap& bitmap, int x, int y)
1173
Cary Clark154beea2017-10-26 07:58:48 -04001174Copies Rect from pixels to Canvas. Matrix and Clip are ignored.
1175Source Rect corners are (0, 0) and (bitmap.width(), bitmap.height()).
Cary Clark6fc50412017-09-21 12:31:06 -04001176
Cary Clark154beea2017-10-26 07:58:48 -04001177Destination Rect corners are (x, y) and
1178(imageInfo().width(), imageInfo().height()).
Cary Clark6fc50412017-09-21 12:31:06 -04001179
1180Copies each readable pixel intersecting both rectangles, without scaling,
Cary Clark154beea2017-10-26 07:58:48 -04001181converting to imageInfo().colorType() and imageInfo().alphaType() if required.
Cary Clark8032b982017-07-28 11:04:54 -04001182
Cary Clarkf05bdda2017-08-24 12:59:48 -04001183Pixels are writable when Device is raster, or backed by a GPU.
1184Pixels are not writable when SkCanvas is returned by SkDocument::beginPage,
1185returned by SkPictureRecorder::beginRecording, or Canvas is the base of a utility
1186class like SkDumpCanvas.
Cary Clark8032b982017-07-28 11:04:54 -04001187
Cary Clark2dc84ad2018-01-26 12:56:22 -05001188Pixel values are converted only if Color_Type and Alpha_Type
Cary Clarkf05bdda2017-08-24 12:59:48 -04001189do not match. Only pixels within both source and destination rectangles
Cary Clark154beea2017-10-26 07:58:48 -04001190are copied. Canvas pixels outside Rect intersection are unchanged.
Cary Clark8032b982017-07-28 11:04:54 -04001191
Cary Clarkf05bdda2017-08-24 12:59:48 -04001192Pass negative values for x or y to offset pixels to the left or
1193above Canvas pixels.
Cary Clark8032b982017-07-28 11:04:54 -04001194
1195Does not copy, and returns false if:
1196
1197#List
Cary Clarkf05bdda2017-08-24 12:59:48 -04001198# Source and destination rectangles do not intersect. ##
Cary Clark8032b982017-07-28 11:04:54 -04001199# bitmap does not have allocated pixels. ##
Cary Clarkac47b882018-01-11 10:35:44 -05001200# bitmap pixels could not be converted to Canvas imageInfo().colorType() or
1201 imageInfo().alphaType(). ##
Cary Clarkce101242017-09-01 15:51:02 -04001202# Canvas pixels are not writable; for instance, Canvas is document based. ##
Cary Clark8032b982017-07-28 11:04:54 -04001203# bitmap pixels are inaccessible; for instance, bitmap wraps a texture. ##
1204##
1205
Cary Clarkbad5ad72017-08-03 17:14:08 -04001206#Param bitmap contains pixels copied to Canvas ##
Cary Clarkf05bdda2017-08-24 12:59:48 -04001207#Param x offset into Canvas writable pixels in x; may be negative ##
1208#Param y offset into Canvas writable pixels in y; may be negative ##
Cary Clark8032b982017-07-28 11:04:54 -04001209
Cary Clarkbad5ad72017-08-03 17:14:08 -04001210#Return true if pixels were written to Canvas ##
Cary Clark8032b982017-07-28 11:04:54 -04001211
1212#Example
1213void draw(SkCanvas* canvas) {
1214 SkImageInfo imageInfo = SkImageInfo::MakeN32Premul(2, 2);
1215 SkBitmap bitmap;
1216 bitmap.setInfo(imageInfo);
1217 uint32_t pixels[4];
1218 bitmap.setPixels(pixels);
1219 for (int y = 0; y < 256; y += 2) {
1220 for (int x = 0; x < 256; x += 2) {
1221 pixels[0] = SkColorSetRGB(x, y, x | y);
1222 pixels[1] = SkColorSetRGB(x ^ y, y, x);
1223 pixels[2] = SkColorSetRGB(x, x & y, y);
1224 pixels[3] = SkColorSetRGB(~x, ~y, x);
1225 canvas->writePixels(bitmap, x, y);
1226 }
1227 }
1228}
1229##
1230
Cary Clark2ade9972017-11-02 17:49:34 -04001231#SeeAlso readPixels drawBitmap drawImage SkBitmap::writePixels
Cary Clark8032b982017-07-28 11:04:54 -04001232
1233##
1234
1235# ------------------------------------------------------------------------------
Cary Clark08895c42018-02-01 09:37:32 -05001236#Subtopic State_Stack
1237#Line # stack of state for hierarchical drawing ##
Cary Clark8032b982017-07-28 11:04:54 -04001238
1239Canvas maintains a stack of state that allows hierarchical drawing, commonly used
Cary Clarkbad5ad72017-08-03 17:14:08 -04001240to implement windows and views. The initial state has an identity matrix and and
1241an infinite clip. Even with a wide-open clip, drawing is constrained by the
1242bounds of the Canvas Surface or Device.
Cary Clark8032b982017-07-28 11:04:54 -04001243
1244Canvas savable state consists of Clip, Matrix, and Draw_Filter.
1245Clip describes the area that may be drawn to.
1246Matrix transforms the geometry.
1247Draw_Filter (deprecated on most platforms) modifies the paint before drawing.
1248
1249save(), saveLayer, saveLayerPreserveLCDTextRequests, and saveLayerAlpha
1250save state and return the depth of the stack.
1251
Cary Clarkbad5ad72017-08-03 17:14:08 -04001252restore(), restoreToCount, and ~SkCanvas() revert state to its value when saved.
Cary Clark8032b982017-07-28 11:04:54 -04001253
1254Each state on the stack intersects Clip with the previous Clip,
1255and concatenates Matrix with the previous Matrix.
1256The intersected Clip makes the drawing area the same or smaller;
1257the concatenated Matrix may move the origin and potentially scale or rotate
1258the coordinate space.
1259
1260Canvas does not require balancing the state stack but it is a good idea
1261to do so. Calling save() without restore() will eventually cause Skia to fail;
1262mismatched save() and restore() create hard to find bugs.
1263
1264It is not possible to use state to draw outside of the clip defined by the
1265previous state.
1266
1267#Example
1268#Description
1269Draw to ever smaller clips; then restore drawing to full canvas.
1270Note that the second clipRect is not permitted to enlarge Clip.
1271##
1272#Height 160
Cary Clarkbad5ad72017-08-03 17:14:08 -04001273void draw(SkCanvas* canvas) {
1274 SkPaint paint;
1275 canvas->save(); // records stack depth to restore
1276 canvas->clipRect(SkRect::MakeWH(100, 100)); // constrains drawing to clip
1277 canvas->clear(SK_ColorRED); // draws to limit of clip
1278 canvas->save(); // records stack depth to restore
1279 canvas->clipRect(SkRect::MakeWH(50, 150)); // Rect below 100 is ignored
1280 canvas->clear(SK_ColorBLUE); // draws to smaller clip
1281 canvas->restore(); // enlarges clip
1282 canvas->drawLine(20, 20, 150, 150, paint); // line below 100 is not drawn
1283 canvas->restore(); // enlarges clip
1284 canvas->drawLine(150, 20, 50, 120, paint); // line below 100 is drawn
Cary Clark8032b982017-07-28 11:04:54 -04001285}
1286##
1287
1288Each Clip uses the current Matrix for its coordinates.
1289
1290#Example
1291#Description
1292While clipRect is given the same rectangle twice, Matrix makes the second
1293clipRect draw at half the size of the first.
1294##
1295#Height 128
Cary Clarkbad5ad72017-08-03 17:14:08 -04001296void draw(SkCanvas* canvas) {
1297 canvas->clipRect(SkRect::MakeWH(100, 100));
1298 canvas->clear(SK_ColorRED);
1299 canvas->scale(.5, .5);
1300 canvas->clipRect(SkRect::MakeWH(100, 100));
1301 canvas->clear(SK_ColorBLUE);
Cary Clark8032b982017-07-28 11:04:54 -04001302}
1303##
1304
1305#SeeAlso save() saveLayer saveLayerPreserveLCDTextRequests saveLayerAlpha restore() restoreToCount
1306
1307#Method int save()
1308
Cary Clarkab2621d2018-01-30 10:08:57 -05001309#In State_Stack
1310#Line # saves Clip and Matrix on stack ##
Cary Clark8032b982017-07-28 11:04:54 -04001311Saves Matrix, Clip, and Draw_Filter (Draw_Filter deprecated on most platforms).
1312Calling restore() discards changes to Matrix, Clip, and Draw_Filter,
1313restoring the Matrix, Clip, and Draw_Filter to their state when save() was called.
1314
Cary Clarkbad5ad72017-08-03 17:14:08 -04001315Matrix may be changed by translate(), scale(), rotate(), skew(), concat(), setMatrix,
1316and resetMatrix. Clip may be changed by clipRect, clipRRect, clipPath, clipRegion.
Cary Clark8032b982017-07-28 11:04:54 -04001317
Cary Clarkbad5ad72017-08-03 17:14:08 -04001318Saved Canvas state is put on a stack; multiple calls to save() should be balance
1319by an equal number of calls to restore().
Cary Clark8032b982017-07-28 11:04:54 -04001320
1321Call restoreToCount with result to restore this and subsequent saves.
1322
Cary Clarkbad5ad72017-08-03 17:14:08 -04001323#Return depth of saved stack ##
Cary Clark8032b982017-07-28 11:04:54 -04001324
1325#Example
1326#Description
1327The black square is translated 50 pixels down and to the right.
1328Restoring Canvas state removes translate() from Canvas stack;
1329the red square is not translated, and is drawn at the origin.
1330##
1331#Height 100
1332void draw(SkCanvas* canvas) {
1333 SkPaint paint;
1334 SkRect rect = { 0, 0, 25, 25 };
1335 canvas->drawRect(rect, paint);
1336 canvas->save();
1337 canvas->translate(50, 50);
1338 canvas->drawRect(rect, paint);
1339 canvas->restore();
1340 paint.setColor(SK_ColorRED);
1341 canvas->drawRect(rect, paint);
1342}
1343##
1344
Cary Clark2ade9972017-11-02 17:49:34 -04001345#SeeAlso saveLayer saveLayerPreserveLCDTextRequests saveLayerAlpha restore() restoreToCount
Cary Clark8032b982017-07-28 11:04:54 -04001346
1347##
1348
1349# ------------------------------------------------------------------------------
Cary Clark8032b982017-07-28 11:04:54 -04001350
1351#Method void restore()
1352
Cary Clarkab2621d2018-01-30 10:08:57 -05001353#In State_Stack
1354#Line # restores changes to Clip and Matrix, pops save stack ##
Cary Clark8032b982017-07-28 11:04:54 -04001355Removes changes to Matrix, Clip, and Draw_Filter since Canvas state was
1356last saved. The state is removed from the stack.
1357
1358Does nothing if the stack is empty.
1359
1360#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04001361void draw(SkCanvas* canvas) {
1362 SkCanvas simple;
1363 SkDebugf("depth = %d\n", simple.getSaveCount());
1364 simple.restore();
1365 SkDebugf("depth = %d\n", simple.getSaveCount());
Cary Clark8032b982017-07-28 11:04:54 -04001366}
1367##
1368
Cary Clark2ade9972017-11-02 17:49:34 -04001369#SeeAlso save() saveLayer saveLayerPreserveLCDTextRequests saveLayerAlpha restoreToCount
1370
Cary Clark8032b982017-07-28 11:04:54 -04001371##
1372
1373# ------------------------------------------------------------------------------
1374
1375#Method int getSaveCount() const
1376
Cary Clarkab2621d2018-01-30 10:08:57 -05001377#In State_Stack
1378#Line # returns depth of stack containing Clip and Matrix ##
Cary Clark8032b982017-07-28 11:04:54 -04001379Returns the number of saved states, each containing: Matrix, Clip, and Draw_Filter.
1380Equals the number of save() calls less the number of restore() calls plus one.
1381The save count of a new canvas is one.
1382
Cary Clarkbad5ad72017-08-03 17:14:08 -04001383#Return depth of save state stack ##
Cary Clark8032b982017-07-28 11:04:54 -04001384
1385#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04001386void draw(SkCanvas* canvas) {
1387 SkCanvas simple;
1388 SkDebugf("depth = %d\n", simple.getSaveCount());
1389 simple.save();
1390 SkDebugf("depth = %d\n", simple.getSaveCount());
1391 simple.restore();
1392 SkDebugf("depth = %d\n", simple.getSaveCount());
Cary Clark8032b982017-07-28 11:04:54 -04001393}
1394#StdOut
Cary Clarkbad5ad72017-08-03 17:14:08 -04001395depth = 1
1396depth = 2
Cary Clark8032b982017-07-28 11:04:54 -04001397depth = 1
1398##
1399##
1400
Cary Clark2ade9972017-11-02 17:49:34 -04001401#SeeAlso save() restore() restoreToCount
1402
Cary Clark8032b982017-07-28 11:04:54 -04001403##
1404
1405# ------------------------------------------------------------------------------
1406
1407#Method void restoreToCount(int saveCount)
1408
Cary Clarkab2621d2018-01-30 10:08:57 -05001409#In State_Stack
1410#Line # restores changes to Clip and Matrix to given depth ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04001411Restores state to Matrix, Clip, and Draw_Filter values when save(), saveLayer,
1412saveLayerPreserveLCDTextRequests, or saveLayerAlpha returned saveCount.
Cary Clark8032b982017-07-28 11:04:54 -04001413
1414Does nothing if saveCount is greater than state stack count.
1415Restores state to initial values if saveCount is less than or equal to one.
1416
Cary Clarkbad5ad72017-08-03 17:14:08 -04001417#Param saveCount depth of state stack to restore ##
Cary Clark8032b982017-07-28 11:04:54 -04001418
1419#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04001420void draw(SkCanvas* canvas) {
1421 SkDebugf("depth = %d\n", canvas->getSaveCount());
1422 canvas->save();
1423 canvas->save();
1424 SkDebugf("depth = %d\n", canvas->getSaveCount());
1425 canvas->restoreToCount(0);
1426 SkDebugf("depth = %d\n", canvas->getSaveCount());
Cary Clark8032b982017-07-28 11:04:54 -04001427}
1428#StdOut
Cary Clarkbad5ad72017-08-03 17:14:08 -04001429depth = 1
1430depth = 3
Cary Clark8032b982017-07-28 11:04:54 -04001431depth = 1
1432##
1433##
1434
Cary Clark2ade9972017-11-02 17:49:34 -04001435#SeeAlso restore() getSaveCount save()
1436
Cary Clark8032b982017-07-28 11:04:54 -04001437##
1438
Cary Clark08895c42018-02-01 09:37:32 -05001439#Subtopic State_Stack ##
Cary Clark8032b982017-07-28 11:04:54 -04001440
1441# ------------------------------------------------------------------------------
Cary Clarkce101242017-09-01 15:51:02 -04001442
Cary Clark08895c42018-02-01 09:37:32 -05001443#Subtopic Layer
Cary Clarkd0530ba2017-09-14 11:25:39 -04001444#Substitute layer
Cary Clarkce101242017-09-01 15:51:02 -04001445#Alias Layers
Cary Clark08895c42018-02-01 09:37:32 -05001446#Line # temporary Bitmap to draw into ##
Cary Clarkce101242017-09-01 15:51:02 -04001447
1448Layer allocates a temporary Bitmap to draw into. When the drawing is
1449complete, the Bitmap is drawn into the Canvas.
1450
1451Layer is saved in a stack along with other saved state. When state with a Layer
1452is restored, the Bitmap is drawn into the previous Layer.
1453
1454Layer may be initialized with the contents of the previous Layer. When Layer is
1455restored, its Bitmap can be modified by Paint passed to Layer to apply
1456Color_Alpha, Color_Filter, Image_Filter, and Blend_Mode.
1457
1458#Method int saveLayer(const SkRect* bounds, const SkPaint* paint)
1459
Cary Clarkab2621d2018-01-30 10:08:57 -05001460#In Layer
1461#Line # saves Clip and Matrix on stack; creates Layer ##
Cary Clarkce101242017-09-01 15:51:02 -04001462Saves Matrix, Clip, and Draw_Filter (Draw_Filter deprecated on most platforms),
1463and allocates a Bitmap for subsequent drawing.
1464Calling restore() discards changes to Matrix, Clip, and Draw_Filter,
1465and draws the Bitmap.
1466
1467Matrix may be changed by translate(), scale(), rotate(), skew(), concat(),
1468setMatrix, and resetMatrix. Clip may be changed by clipRect, clipRRect,
1469clipPath, clipRegion.
1470
1471Rect bounds suggests but does not define the Bitmap size. To clip drawing to
1472a specific rectangle, use clipRect.
1473
1474Optional Paint paint applies Color_Alpha, Color_Filter, Image_Filter, and
1475Blend_Mode when restore() is called.
1476
1477Call restoreToCount with returned value to restore this and subsequent saves.
1478
1479#Param bounds hint to limit the size of the Layer; may be nullptr ##
1480#Param paint graphics state for Layer; may be nullptr ##
1481
1482#Return depth of saved stack ##
1483
1484#Example
1485#Description
1486Rectangles are blurred by Image_Filter when restore() draws Layer to main
1487Canvas.
1488##
1489#Height 128
1490void draw(SkCanvas* canvas) {
1491 SkPaint paint, blur;
Cary Clarka560c472017-11-27 10:44:06 -05001492 blur.setImageFilter(SkBlurImageFilter::Make(3, 3, nullptr));
Cary Clarkce101242017-09-01 15:51:02 -04001493 canvas->saveLayer(nullptr, &blur);
1494 SkRect rect = { 25, 25, 50, 50};
1495 canvas->drawRect(rect, paint);
1496 canvas->translate(50, 50);
1497 paint.setColor(SK_ColorRED);
1498 canvas->drawRect(rect, paint);
1499 canvas->restore();
1500}
1501##
1502
Cary Clark2ade9972017-11-02 17:49:34 -04001503#SeeAlso save() restore() saveLayer saveLayerPreserveLCDTextRequests saveLayerAlpha SaveLayerRec
Cary Clarkce101242017-09-01 15:51:02 -04001504
1505##
1506
1507#Method int saveLayer(const SkRect& bounds, const SkPaint* paint)
1508
Cary Clarkab2621d2018-01-30 10:08:57 -05001509#In Layer
Cary Clarkce101242017-09-01 15:51:02 -04001510Saves Matrix, Clip, and Draw_Filter (Draw_Filter deprecated on most platforms),
1511and allocates a Bitmap for subsequent drawing.
1512Calling restore() discards changes to Matrix, Clip, and Draw_Filter,
1513and draws the Bitmap.
1514
1515Matrix may be changed by translate(), scale(), rotate(), skew(), concat(),
1516setMatrix, and resetMatrix. Clip may be changed by clipRect, clipRRect,
1517clipPath, clipRegion.
1518
1519Rect bounds suggests but does not define the Layer size. To clip drawing to
1520a specific rectangle, use clipRect.
1521
1522Optional Paint paint applies Color_Alpha, Color_Filter, Image_Filter, and
1523Blend_Mode when restore() is called.
1524
1525Call restoreToCount with returned value to restore this and subsequent saves.
1526
1527#Param bounds hint to limit the size of Layer; may be nullptr ##
1528#Param paint graphics state for Layer; may be nullptr ##
1529
1530#Return depth of saved stack ##
1531
1532#Example
1533#Description
1534Rectangles are blurred by Image_Filter when restore() draws Layer to main Canvas.
1535The red rectangle is clipped; it does not fully fit on Layer.
1536Image_Filter blurs past edge of Layer so red rectangle is blurred on all sides.
1537##
1538#Height 128
1539void draw(SkCanvas* canvas) {
1540 SkPaint paint, blur;
Cary Clarka560c472017-11-27 10:44:06 -05001541 blur.setImageFilter(SkBlurImageFilter::Make(3, 3, nullptr));
Cary Clarkce101242017-09-01 15:51:02 -04001542 canvas->saveLayer(SkRect::MakeWH(90, 90), &blur);
1543 SkRect rect = { 25, 25, 50, 50};
1544 canvas->drawRect(rect, paint);
1545 canvas->translate(50, 50);
1546 paint.setColor(SK_ColorRED);
1547 canvas->drawRect(rect, paint);
1548 canvas->restore();
1549}
1550##
1551
Cary Clark2ade9972017-11-02 17:49:34 -04001552#SeeAlso save() restore() saveLayerPreserveLCDTextRequests saveLayerAlpha SaveLayerRec
Cary Clarkce101242017-09-01 15:51:02 -04001553
1554##
1555
1556#Method int saveLayerPreserveLCDTextRequests(const SkRect* bounds, const SkPaint* paint)
1557
Cary Clarkab2621d2018-01-30 10:08:57 -05001558#In Layer
1559#Line # saves Clip and Matrix on stack; creates Layer for LCD text ##
Cary Clarkce101242017-09-01 15:51:02 -04001560Saves Matrix, Clip, and Draw_Filter (Draw_Filter deprecated on most platforms),
1561and allocates a Bitmap for subsequent drawing.
1562LCD_Text is preserved when the Layer is drawn to the prior Layer.
1563
1564Calling restore() discards changes to Matrix, Clip, and Draw_Filter,
1565and draws Layer.
1566
1567Matrix may be changed by translate(), scale(), rotate(), skew(), concat(),
1568setMatrix, and resetMatrix. Clip may be changed by clipRect, clipRRect,
1569clipPath, clipRegion.
1570
1571Rect bounds suggests but does not define the Layer size. To clip drawing to
1572a specific rectangle, use clipRect.
1573
1574Optional Paint paint applies Color_Alpha, Color_Filter, Image_Filter, and
1575Blend_Mode when restore() is called.
1576
1577Call restoreToCount with returned value to restore this and subsequent saves.
1578
1579Draw text on an opaque background so that LCD_Text blends correctly with the
1580prior Layer. LCD_Text drawn on a background with transparency may result in
Cary Clark6fc50412017-09-21 12:31:06 -04001581incorrect blending.
Cary Clarkce101242017-09-01 15:51:02 -04001582
1583#Param bounds hint to limit the size of Layer; may be nullptr ##
1584#Param paint graphics state for Layer; may be nullptr ##
1585
1586#Return depth of saved stack ##
1587
1588#Example
1589 SkPaint paint;
1590 paint.setAntiAlias(true);
1591 paint.setLCDRenderText(true);
1592 paint.setTextSize(20);
1593 for (auto preserve : { false, true } ) {
1594 preserve ? canvas->saveLayerPreserveLCDTextRequests(nullptr, nullptr)
1595 : canvas->saveLayer(nullptr, nullptr);
1596 SkPaint p;
1597 p.setColor(SK_ColorWHITE);
1598 // Comment out the next line to draw on a non-opaque background.
1599 canvas->drawRect(SkRect::MakeLTRB(25, 40, 200, 70), p);
1600 canvas->drawString("Hamburgefons", 30, 60, paint);
1601
1602 p.setColor(0xFFCCCCCC);
1603 canvas->drawRect(SkRect::MakeLTRB(25, 70, 200, 100), p);
1604 canvas->drawString("Hamburgefons", 30, 90, paint);
1605
1606 canvas->restore();
1607 canvas->translate(0, 80);
1608 }
1609 ##
1610
Cary Clark2ade9972017-11-02 17:49:34 -04001611#SeeAlso save() restore() saveLayer saveLayerAlpha SaveLayerRec
Cary Clarkce101242017-09-01 15:51:02 -04001612
1613##
1614
1615#Method int saveLayerAlpha(const SkRect* bounds, U8CPU alpha)
1616
Cary Clarkab2621d2018-01-30 10:08:57 -05001617#In Layer
1618#Line # saves Clip and Matrix on stack; creates Layer; sets opacity ##
Cary Clarkce101242017-09-01 15:51:02 -04001619Saves Matrix, Clip, and Draw_Filter (Draw_Filter deprecated on most platforms),
1620and allocates Bitmap for subsequent drawing.
1621
1622Calling restore() discards changes to Matrix, Clip, and Draw_Filter,
1623and blends Layer with alpha opacity onto prior Layer.
1624
1625Matrix may be changed by translate(), scale(), rotate(), skew(), concat(),
1626setMatrix, and resetMatrix. Clip may be changed by clipRect, clipRRect,
1627clipPath, clipRegion.
1628
1629Rect bounds suggests but does not define Layer size. To clip drawing to
1630a specific rectangle, use clipRect.
1631
1632alpha of zero is fully transparent, 255 is fully opaque.
1633
1634Call restoreToCount with returned value to restore this and subsequent saves.
1635
1636#Param bounds hint to limit the size of Layer; may be nullptr ##
1637#Param alpha opacity of Layer ##
1638
1639#Return depth of saved stack ##
1640
1641#Example
1642 SkPaint paint;
1643 paint.setColor(SK_ColorRED);
1644 canvas->drawCircle(50, 50, 50, paint);
1645 canvas->saveLayerAlpha(nullptr, 128);
1646 paint.setColor(SK_ColorBLUE);
1647 canvas->drawCircle(100, 50, 50, paint);
1648 paint.setColor(SK_ColorGREEN);
1649 paint.setAlpha(128);
1650 canvas->drawCircle(75, 90, 50, paint);
1651 canvas->restore();
1652##
1653
Cary Clark2ade9972017-11-02 17:49:34 -04001654#SeeAlso save() restore() saveLayer saveLayerPreserveLCDTextRequests SaveLayerRec
Cary Clarkce101242017-09-01 15:51:02 -04001655
1656##
1657
Cary Clark08895c42018-02-01 09:37:32 -05001658#ToDo
1659add new markup to associate typedef SaveLayerFlags with Enum so that, for
1660documentation purposes, this enum is named rather than anonymous
1661##
Cary Clarkce101242017-09-01 15:51:02 -04001662
Cary Clark08895c42018-02-01 09:37:32 -05001663#Enum
1664#Line # sets SaveLayerRec options ##
Cary Clarkce101242017-09-01 15:51:02 -04001665#Code
1666 enum {
1667 kIsOpaque_SaveLayerFlag = 1 << 0,
1668 kPreserveLCDText_SaveLayerFlag = 1 << 1,
1669 kInitWithPrevious_SaveLayerFlag = 1 << 2,
1670 kDontClipToLayer_Legacy_SaveLayerFlag = kDontClipToLayer_PrivateSaveLayerFlag,
1671 };
Cary Clarkce101242017-09-01 15:51:02 -04001672##
1673
1674SaveLayerFlags provides options that may be used in any combination in SaveLayerRec,
1675defining how Layer allocated by saveLayer operates.
1676
1677#Const kIsOpaque_SaveLayerFlag 1
1678 Creates Layer without transparency. Flag is ignored if Layer Paint contains
1679 Image_Filter or Color_Filter.
1680##
1681
1682#Const kPreserveLCDText_SaveLayerFlag 2
1683 Creates Layer for LCD text. Flag is ignored if Layer Paint contains
1684 Image_Filter or Color_Filter.
1685##
1686
1687#Const kInitWithPrevious_SaveLayerFlag 4
1688 Initializes Layer with the contents of the previous Layer.
1689##
1690
1691#Const kDontClipToLayer_Legacy_SaveLayerFlag 0x80000000
Cary Clark4855f782018-02-06 09:41:53 -05001692#Deprecated soon
Cary Clarkce101242017-09-01 15:51:02 -04001693##
1694
1695#Example
1696#Height 160
1697#Description
1698Canvas Layer captures red and blue circles scaled up by four.
1699scalePaint blends Layer back with transparency.
1700##
1701void draw(SkCanvas* canvas) {
1702 SkPaint redPaint, bluePaint, scalePaint;
1703 redPaint.setColor(SK_ColorRED);
1704 canvas->drawCircle(21, 21, 8, redPaint);
1705 bluePaint.setColor(SK_ColorBLUE);
1706 canvas->drawCircle(31, 21, 8, bluePaint);
1707 SkMatrix matrix;
1708 matrix.setScale(4, 4);
1709 scalePaint.setAlpha(0x40);
1710 scalePaint.setImageFilter(
1711 SkImageFilter::MakeMatrixFilter(matrix, kNone_SkFilterQuality, nullptr));
1712 SkCanvas::SaveLayerRec saveLayerRec(nullptr, &scalePaint,
1713 SkCanvas::kInitWithPrevious_SaveLayerFlag);
1714 canvas->saveLayer(saveLayerRec);
1715 canvas->restore();
1716}
1717##
1718
Cary Clark2ade9972017-11-02 17:49:34 -04001719#SeeAlso save() restore() saveLayer saveLayerPreserveLCDTextRequests saveLayerAlpha SaveLayerRec
Cary Clarkce101242017-09-01 15:51:02 -04001720
1721#Enum ##
1722
Cary Clarka560c472017-11-27 10:44:06 -05001723#Typedef uint32_t SaveLayerFlags
1724
1725##
1726
Cary Clarkce101242017-09-01 15:51:02 -04001727#Struct SaveLayerRec
Cary Clark08895c42018-02-01 09:37:32 -05001728#Line # contains the state used to create the Layer ##
Cary Clarkce101242017-09-01 15:51:02 -04001729#Code
1730 struct SaveLayerRec {
1731 SaveLayerRec*(...
1732
1733 const SkRect* fBounds;
1734 const SkPaint* fPaint;
1735 const SkImageFilter* fBackdrop;
1736 SaveLayerFlags fSaveLayerFlags;
1737 };
1738##
1739
1740SaveLayerRec contains the state used to create the Layer.
1741
1742#Member const SkRect* fBounds
1743 fBounds is used as a hint to limit the size of Layer; may be nullptr.
1744 fBounds suggests but does not define Layer size. To clip drawing to
1745 a specific rectangle, use clipRect.
1746##
1747
1748#Member const SkPaint* fPaint
1749 fPaint modifies how Layer overlays the prior Layer; may be nullptr.
1750 Color_Alpha, Blend_Mode, Color_Filter, Draw_Looper, Image_Filter, and
1751 Mask_Filter affect Layer draw.
1752##
1753
1754#Member const SkImageFilter* fBackdrop
1755 fBackdrop applies Image_Filter to the prior Layer when copying to the Layer;
1756 may be nullptr. Use kInitWithPrevious_SaveLayerFlag to copy the
1757 prior Layer without an Image_Filter.
1758##
1759
1760#Member const SkImage* fClipMask
1761 restore() clips Layer by the Color_Alpha channel of fClipMask when
1762 Layer is copied to Device. fClipMask may be nullptr. .
1763##
1764
1765#Member const SkMatrix* fClipMatrix
1766 fClipMatrix transforms fClipMask before it clips Layer. If
1767 fClipMask describes a translucent gradient, it may be scaled and rotated
1768 without introducing artifacts. fClipMatrix may be nullptr.
1769##
1770
1771#Member SaveLayerFlags fSaveLayerFlags
1772 fSaveLayerFlags are used to create Layer without transparency,
1773 create Layer for LCD text, and to create Layer with the
1774 contents of the previous Layer.
1775##
1776
1777#Example
1778#Height 160
1779#Description
1780Canvas Layer captures a red Anti-aliased circle and a blue Aliased circle scaled
1781up by four. After drawing another red circle without scaling on top, the Layer is
1782transferred to the main canvas.
1783##
1784void draw(SkCanvas* canvas) {
1785 SkPaint redPaint, bluePaint;
1786 redPaint.setAntiAlias(true);
1787 redPaint.setColor(SK_ColorRED);
1788 canvas->drawCircle(21, 21, 8, redPaint);
1789 bluePaint.setColor(SK_ColorBLUE);
1790 canvas->drawCircle(31, 21, 8, bluePaint);
1791 SkMatrix matrix;
1792 matrix.setScale(4, 4);
1793 auto scaler = SkImageFilter::MakeMatrixFilter(matrix, kNone_SkFilterQuality, nullptr);
1794 SkCanvas::SaveLayerRec saveLayerRec(nullptr, nullptr, scaler.get(), 0);
1795 canvas->saveLayer(saveLayerRec);
1796 canvas->drawCircle(125, 85, 8, redPaint);
1797 canvas->restore();
1798}
1799##
1800
1801#Method SaveLayerRec()
1802
1803Sets fBounds, fPaint, and fBackdrop to nullptr. Clears fSaveLayerFlags.
1804
1805#Return empty SaveLayerRec ##
1806
1807#Example
1808 SkCanvas::SaveLayerRec rec1;
1809 rec1.fSaveLayerFlags = SkCanvas::kIsOpaque_SaveLayerFlag;
1810 SkCanvas::SaveLayerRec rec2(nullptr, nullptr, SkCanvas::kIsOpaque_SaveLayerFlag);
1811 SkDebugf("rec1 %c= rec2\n", rec1.fBounds == rec2.fBounds
1812 && rec1.fPaint == rec2.fPaint
1813 && rec1.fBackdrop == rec2.fBackdrop
1814 && rec1.fSaveLayerFlags == rec2.fSaveLayerFlags ? '=' : '!');
1815 #StdOut
1816 rec1 == rec2
1817 ##
1818##
1819
Cary Clark2ade9972017-11-02 17:49:34 -04001820#SeeAlso save() restore() saveLayer saveLayerPreserveLCDTextRequests saveLayerAlpha
1821
Cary Clarkce101242017-09-01 15:51:02 -04001822##
1823
1824#Method SaveLayerRec(const SkRect* bounds, const SkPaint* paint, SaveLayerFlags saveLayerFlags = 0)
1825
1826Sets fBounds, fPaint, and fSaveLayerFlags; sets fBackdrop to nullptr.
1827
1828#Param bounds Layer dimensions; may be nullptr ##
1829#Param paint applied to Layer when overlaying prior Layer; may be nullptr ##
1830#Param saveLayerFlags SaveLayerRec options to modify Layer ##
1831
1832#Return SaveLayerRec with empty backdrop ##
1833
1834#Example
1835 SkCanvas::SaveLayerRec rec1;
1836 SkCanvas::SaveLayerRec rec2(nullptr, nullptr);
1837 SkDebugf("rec1 %c= rec2\n", rec1.fBounds == rec2.fBounds
1838 && rec1.fPaint == rec2.fPaint
1839 && rec1.fBackdrop == rec2.fBackdrop
1840 && rec1.fSaveLayerFlags == rec2.fSaveLayerFlags ? '=' : '!');
1841 #StdOut
1842 rec1 == rec2
1843 ##
1844##
1845
Cary Clark2ade9972017-11-02 17:49:34 -04001846#SeeAlso save() restore() saveLayer saveLayerPreserveLCDTextRequests saveLayerAlpha
1847
Cary Clarkce101242017-09-01 15:51:02 -04001848##
1849
1850#Method SaveLayerRec(const SkRect* bounds, const SkPaint* paint, const SkImageFilter* backdrop,
1851 SaveLayerFlags saveLayerFlags)
1852
1853Sets fBounds, fPaint, fBackdrop, and fSaveLayerFlags.
1854
1855#Param bounds Layer dimensions; may be nullptr ##
1856#Param paint applied to Layer when overlaying prior Layer;
1857 may be nullptr
1858##
1859#Param backdrop prior Layer copied with Image_Filter; may be nullptr
1860##
1861#Param saveLayerFlags SaveLayerRec options to modify Layer ##
1862
1863#Return SaveLayerRec fully specified ##
1864
1865#Example
1866 SkCanvas::SaveLayerRec rec1;
1867 SkCanvas::SaveLayerRec rec2(nullptr, nullptr, nullptr, 0);
1868 SkDebugf("rec1 %c= rec2\n", rec1.fBounds == rec2.fBounds
1869 && rec1.fPaint == rec2.fPaint
1870 && rec1.fBackdrop == rec2.fBackdrop
1871 && rec1.fSaveLayerFlags == rec2.fSaveLayerFlags ? '=' : '!');
1872 #StdOut
1873 rec1 == rec2
1874 ##
1875##
1876
Cary Clark2ade9972017-11-02 17:49:34 -04001877#SeeAlso save() restore() saveLayer saveLayerPreserveLCDTextRequests saveLayerAlpha
1878
Cary Clarkce101242017-09-01 15:51:02 -04001879##
1880
1881#Method SaveLayerRec(const SkRect* bounds, const SkPaint* paint, const SkImageFilter* backdrop,
1882 const SkImage* clipMask, const SkMatrix* clipMatrix,
1883 SaveLayerFlags saveLayerFlags)
1884
1885#Experimental
1886Not ready for general use.
1887##
1888
1889Sets fBounds, fPaint, fBackdrop, fClipMask, fClipMatrix, and fSaveLayerFlags.
1890clipMatrix uses Color_Alpha channel of image, transformed by clipMatrix, to clip
1891Layer when drawn to Canvas.
1892
Cary Clark2ade9972017-11-02 17:49:34 -04001893Implementation is not complete; has no effect if Device is GPU-backed.
Cary Clarkce101242017-09-01 15:51:02 -04001894
1895#Param bounds Layer dimensions; may be nullptr ##
1896#Param paint graphics state applied to Layer when overlaying prior
1897 Layer; may be nullptr
1898##
1899#Param backdrop prior Layer copied with Image_Filter;
1900 may be nullptr
1901##
1902#Param clipMask clip applied to Layer; may be nullptr ##
1903#Param clipMatrix matrix applied to clipMask; may be nullptr to use
1904 identity matrix
1905##
1906#Param saveLayerFlags SaveLayerRec options to modify Layer ##
1907
1908#Return SaveLayerRec fully specified ##
1909
Cary Clark2ade9972017-11-02 17:49:34 -04001910#SeeAlso save() restore() saveLayer saveLayerPreserveLCDTextRequests saveLayerAlpha
Cary Clarkce101242017-09-01 15:51:02 -04001911
1912##
1913
1914#Struct ##
1915
1916#Method int saveLayer(const SaveLayerRec& layerRec)
1917
Cary Clarkab2621d2018-01-30 10:08:57 -05001918#In Layer
Cary Clarkce101242017-09-01 15:51:02 -04001919Saves Matrix, Clip, and Draw_Filter (Draw_Filter deprecated on most platforms),
1920and allocates Bitmap for subsequent drawing.
1921
1922Calling restore() discards changes to Matrix, Clip, and Draw_Filter,
1923and blends Bitmap with Color_Alpha opacity onto the prior Layer.
1924
1925Matrix may be changed by translate(), scale(), rotate(), skew(), concat(),
1926setMatrix, and resetMatrix. Clip may be changed by clipRect, clipRRect,
1927clipPath, clipRegion.
1928
1929SaveLayerRec contains the state used to create the Layer.
1930
1931Call restoreToCount with returned value to restore this and subsequent saves.
1932
1933#Param layerRec Layer state ##
1934
1935#Return depth of save state stack ##
1936
1937#Example
1938#Description
1939The example draws an image, and saves it into a Layer with kInitWithPrevious_SaveLayerFlag.
1940Next it punches a hole in Layer and restore with SkBlendMode::kPlus.
1941Where Layer was cleared, the original image will draw unchanged.
1942Outside of the circle the mandrill is brightened.
1943##
1944 #Image 3
Hal Canaryc465d132017-12-08 10:21:31 -05001945 // sk_sp<SkImage> image = GetResourceAsImage("images/mandrill_256.png");
Cary Clarkce101242017-09-01 15:51:02 -04001946 canvas->drawImage(image, 0, 0, nullptr);
1947 SkCanvas::SaveLayerRec rec;
1948 SkPaint paint;
1949 paint.setBlendMode(SkBlendMode::kPlus);
1950 rec.fSaveLayerFlags = SkCanvas::kInitWithPrevious_SaveLayerFlag;
1951 rec.fPaint = &paint;
1952 canvas->saveLayer(rec);
1953 paint.setBlendMode(SkBlendMode::kClear);
1954 canvas->drawCircle(128, 128, 96, paint);
1955 canvas->restore();
1956##
1957
1958#ToDo above example needs to replace GetResourceAsImage with way to select image in fiddle ##
1959
Cary Clark2ade9972017-11-02 17:49:34 -04001960#SeeAlso save() restore() saveLayer saveLayerPreserveLCDTextRequests saveLayerAlpha
1961
Cary Clarkce101242017-09-01 15:51:02 -04001962##
1963
Cary Clark08895c42018-02-01 09:37:32 -05001964#Subtopic Layer ##
Cary Clarkce101242017-09-01 15:51:02 -04001965
1966# ------------------------------------------------------------------------------
Cary Clark08895c42018-02-01 09:37:32 -05001967#Subtopic Matrix
1968#Line # coordinate transformation ##
Cary Clark8032b982017-07-28 11:04:54 -04001969
1970#Method void translate(SkScalar dx, SkScalar dy)
1971
Cary Clarkab2621d2018-01-30 10:08:57 -05001972#In Matrix
1973#Line # translates Matrix ##
Cary Clark8032b982017-07-28 11:04:54 -04001974Translate Matrix by dx along the x-axis and dy along the y-axis.
1975
1976Mathematically, replace Matrix with a translation matrix
Cary Clarkce101242017-09-01 15:51:02 -04001977Premultiplied with Matrix.
Cary Clark8032b982017-07-28 11:04:54 -04001978
1979This has the effect of moving the drawing by (dx, dy) before transforming
1980the result with Matrix.
1981
Cary Clarkbad5ad72017-08-03 17:14:08 -04001982#Param dx distance to translate in x ##
1983#Param dy distance to translate in y ##
Cary Clark8032b982017-07-28 11:04:54 -04001984
1985#Example
1986#Height 128
1987#Description
1988scale() followed by translate() produces different results from translate() followed
1989by scale().
1990
1991The blue stroke follows translate of (50, 50); a black
1992fill follows scale of (2, 1/2.f). After restoring the clip, which resets
1993Matrix, a red frame follows the same scale of (2, 1/2.f); a gray fill
1994follows translate of (50, 50).
1995##
Cary Clarkbad5ad72017-08-03 17:14:08 -04001996void draw(SkCanvas* canvas) {
1997 SkPaint filledPaint;
1998 SkPaint outlinePaint;
1999 outlinePaint.setStyle(SkPaint::kStroke_Style);
2000 outlinePaint.setColor(SK_ColorBLUE);
2001 canvas->save();
2002 canvas->translate(50, 50);
2003 canvas->drawCircle(28, 28, 15, outlinePaint); // blue center: (50+28, 50+28)
2004 canvas->scale(2, 1/2.f);
2005 canvas->drawCircle(28, 28, 15, filledPaint); // black center: (50+(28*2), 50+(28/2))
2006 canvas->restore();
2007 filledPaint.setColor(SK_ColorGRAY);
2008 outlinePaint.setColor(SK_ColorRED);
2009 canvas->scale(2, 1/2.f);
2010 canvas->drawCircle(28, 28, 15, outlinePaint); // red center: (28*2, 28/2)
2011 canvas->translate(50, 50);
2012 canvas->drawCircle(28, 28, 15, filledPaint); // gray center: ((50+28)*2, (50+28)/2)
Cary Clark8032b982017-07-28 11:04:54 -04002013}
2014##
2015
Cary Clark2ade9972017-11-02 17:49:34 -04002016#SeeAlso concat() scale() skew() rotate() setMatrix
Cary Clark8032b982017-07-28 11:04:54 -04002017
2018##
2019
2020# ------------------------------------------------------------------------------
2021
2022#Method void scale(SkScalar sx, SkScalar sy)
2023
Cary Clarkab2621d2018-01-30 10:08:57 -05002024#In Matrix
2025#Line # scales Matrix ##
Cary Clark8032b982017-07-28 11:04:54 -04002026Scale Matrix by sx on the x-axis and sy on the y-axis.
2027
2028Mathematically, replace Matrix with a scale matrix
Cary Clarkce101242017-09-01 15:51:02 -04002029Premultiplied with Matrix.
Cary Clark8032b982017-07-28 11:04:54 -04002030
2031This has the effect of scaling the drawing by (sx, sy) before transforming
2032the result with Matrix.
2033
Cary Clarkbad5ad72017-08-03 17:14:08 -04002034#Param sx amount to scale in x ##
2035#Param sy amount to scale in y ##
Cary Clark8032b982017-07-28 11:04:54 -04002036
2037#Example
2038#Height 160
Cary Clarkbad5ad72017-08-03 17:14:08 -04002039void draw(SkCanvas* canvas) {
2040 SkPaint paint;
2041 SkRect rect = { 10, 20, 60, 120 };
2042 canvas->translate(20, 20);
2043 canvas->drawRect(rect, paint);
2044 canvas->scale(2, .5f);
2045 paint.setColor(SK_ColorGRAY);
2046 canvas->drawRect(rect, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002047}
2048##
2049
Cary Clark2ade9972017-11-02 17:49:34 -04002050#SeeAlso concat() translate() skew() rotate() setMatrix
Cary Clark8032b982017-07-28 11:04:54 -04002051
2052##
2053
2054# ------------------------------------------------------------------------------
2055
2056#Method void rotate(SkScalar degrees)
2057
Cary Clarkab2621d2018-01-30 10:08:57 -05002058#In Matrix
2059#Line # rotates Matrix ##
Cary Clark8032b982017-07-28 11:04:54 -04002060Rotate Matrix by degrees. Positive degrees rotates clockwise.
2061
2062Mathematically, replace Matrix with a rotation matrix
Cary Clarkce101242017-09-01 15:51:02 -04002063Premultiplied with Matrix.
Cary Clark8032b982017-07-28 11:04:54 -04002064
2065This has the effect of rotating the drawing by degrees before transforming
2066the result with Matrix.
2067
Cary Clarkbad5ad72017-08-03 17:14:08 -04002068#Param degrees amount to rotate, in degrees ##
Cary Clark8032b982017-07-28 11:04:54 -04002069
2070#Example
2071#Description
2072Draw clock hands at time 5:10. The hour hand and minute hand point up and
2073are rotated clockwise.
2074##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002075void draw(SkCanvas* canvas) {
2076 SkPaint paint;
2077 paint.setStyle(SkPaint::kStroke_Style);
2078 canvas->translate(128, 128);
2079 canvas->drawCircle(0, 0, 60, paint);
2080 canvas->save();
2081 canvas->rotate(10 * 360 / 60); // 10 minutes of 60 scaled to 360 degrees
2082 canvas->drawLine(0, 0, 0, -50, paint);
2083 canvas->restore();
2084 canvas->rotate((5 + 10.f/60) * 360 / 12); // 5 and 10/60 hours of 12 scaled to 360 degrees
2085 canvas->drawLine(0, 0, 0, -30, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002086}
2087##
2088
Cary Clark2ade9972017-11-02 17:49:34 -04002089#SeeAlso concat() translate() skew() scale() setMatrix
Cary Clark8032b982017-07-28 11:04:54 -04002090
2091##
2092
2093# ------------------------------------------------------------------------------
2094
2095#Method void rotate(SkScalar degrees, SkScalar px, SkScalar py)
2096
Cary Clarkab2621d2018-01-30 10:08:57 -05002097#In Matrix
Cary Clarkbad5ad72017-08-03 17:14:08 -04002098Rotate Matrix by degrees about a point at (px, py). Positive degrees rotates
2099clockwise.
Cary Clark8032b982017-07-28 11:04:54 -04002100
Cary Clarkce101242017-09-01 15:51:02 -04002101Mathematically, construct a rotation matrix. Premultiply the rotation matrix by
Cary Clark8032b982017-07-28 11:04:54 -04002102a translation matrix, then replace Matrix with the resulting matrix
Cary Clarkce101242017-09-01 15:51:02 -04002103Premultiplied with Matrix.
Cary Clark8032b982017-07-28 11:04:54 -04002104
Cary Clarkbad5ad72017-08-03 17:14:08 -04002105This has the effect of rotating the drawing about a given point before
2106transforming the result with Matrix.
Cary Clark8032b982017-07-28 11:04:54 -04002107
Cary Clarkbad5ad72017-08-03 17:14:08 -04002108#Param degrees amount to rotate, in degrees ##
2109#Param px x-coordinate of the point to rotate about ##
2110#Param py y-coordinate of the point to rotate about ##
Cary Clark8032b982017-07-28 11:04:54 -04002111
2112#Example
2113#Height 192
Cary Clarkbad5ad72017-08-03 17:14:08 -04002114void draw(SkCanvas* canvas) {
2115 SkPaint paint;
2116 paint.setTextSize(96);
2117 canvas->drawString("A1", 130, 100, paint);
2118 canvas->rotate(180, 130, 100);
2119 canvas->drawString("A1", 130, 100, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002120}
2121##
2122
Cary Clark2ade9972017-11-02 17:49:34 -04002123#SeeAlso concat() translate() skew() scale() setMatrix
Cary Clark8032b982017-07-28 11:04:54 -04002124
2125##
2126
2127# ------------------------------------------------------------------------------
2128
2129#Method void skew(SkScalar sx, SkScalar sy)
2130
Cary Clarkab2621d2018-01-30 10:08:57 -05002131#In Matrix
2132#Line # skews Matrix ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002133Skew Matrix by sx on the x-axis and sy on the y-axis. A positive value of sx
2134skews the drawing right as y increases; a positive value of sy skews the drawing
2135down as x increases.
Cary Clark8032b982017-07-28 11:04:54 -04002136
Cary Clarkce101242017-09-01 15:51:02 -04002137Mathematically, replace Matrix with a skew matrix Premultiplied with Matrix.
Cary Clark8032b982017-07-28 11:04:54 -04002138
Cary Clarkbad5ad72017-08-03 17:14:08 -04002139This has the effect of skewing the drawing by (sx, sy) before transforming
Cary Clark8032b982017-07-28 11:04:54 -04002140the result with Matrix.
2141
Cary Clarkbad5ad72017-08-03 17:14:08 -04002142#Param sx amount to skew in x ##
2143#Param sy amount to skew in y ##
2144
Cary Clark8032b982017-07-28 11:04:54 -04002145#Example
2146 #Description
2147 Black text mimics an oblique text style by using a negative skew in x that
2148 shifts the geometry to the right as the y values decrease.
2149 Red text uses a positive skew in y to shift the geometry down as the x values
2150 increase.
2151 Blue text combines x and y skew to rotate and scale.
2152 ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002153 SkPaint paint;
2154 paint.setTextSize(128);
2155 canvas->translate(30, 130);
2156 canvas->save();
2157 canvas->skew(-.5, 0);
2158 canvas->drawString("A1", 0, 0, paint);
2159 canvas->restore();
2160 canvas->save();
2161 canvas->skew(0, .5);
2162 paint.setColor(SK_ColorRED);
2163 canvas->drawString("A1", 0, 0, paint);
2164 canvas->restore();
2165 canvas->skew(-.5, .5);
2166 paint.setColor(SK_ColorBLUE);
Cary Clark8032b982017-07-28 11:04:54 -04002167 canvas->drawString("A1", 0, 0, paint);
2168##
2169
Cary Clark2ade9972017-11-02 17:49:34 -04002170#SeeAlso concat() translate() rotate() scale() setMatrix
Cary Clark8032b982017-07-28 11:04:54 -04002171
2172##
2173
2174# ------------------------------------------------------------------------------
2175
2176#Method void concat(const SkMatrix& matrix)
2177
Cary Clarkab2621d2018-01-30 10:08:57 -05002178#In Matrix
2179#Line # multiplies Matrix by Matrix ##
Cary Clarkce101242017-09-01 15:51:02 -04002180Replace Matrix with matrix Premultiplied with existing Matrix.
Cary Clark8032b982017-07-28 11:04:54 -04002181
Cary Clarkbad5ad72017-08-03 17:14:08 -04002182This has the effect of transforming the drawn geometry by matrix, before
2183transforming the result with existing Matrix.
Cary Clark8032b982017-07-28 11:04:54 -04002184
Cary Clarkce101242017-09-01 15:51:02 -04002185#Param matrix matrix to Premultiply with existing Matrix ##
Cary Clark8032b982017-07-28 11:04:54 -04002186
2187#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04002188void draw(SkCanvas* canvas) {
2189 SkPaint paint;
2190 paint.setTextSize(80);
2191 paint.setTextScaleX(.3);
2192 SkMatrix matrix;
2193 SkRect rect[2] = {{ 10, 20, 90, 110 }, { 40, 130, 140, 180 }};
2194 matrix.setRectToRect(rect[0], rect[1], SkMatrix::kFill_ScaleToFit);
2195 canvas->drawRect(rect[0], paint);
2196 canvas->drawRect(rect[1], paint);
2197 paint.setColor(SK_ColorWHITE);
2198 canvas->drawString("Here", rect[0].fLeft + 10, rect[0].fBottom - 10, paint);
2199 canvas->concat(matrix);
2200 canvas->drawString("There", rect[0].fLeft + 10, rect[0].fBottom - 10, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002201}
2202##
2203
Cary Clark2ade9972017-11-02 17:49:34 -04002204#SeeAlso translate() rotate() scale() skew() setMatrix
Cary Clark8032b982017-07-28 11:04:54 -04002205
2206##
2207
2208# ------------------------------------------------------------------------------
2209
2210#Method void setMatrix(const SkMatrix& matrix)
2211
Cary Clarkab2621d2018-01-30 10:08:57 -05002212#In Matrix
2213#Line # sets Matrix ##
Cary Clark8032b982017-07-28 11:04:54 -04002214Replace Matrix with matrix.
2215Unlike concat(), any prior matrix state is overwritten.
2216
Cary Clarkbad5ad72017-08-03 17:14:08 -04002217#Param matrix matrix to copy, replacing existing Matrix ##
Cary Clark8032b982017-07-28 11:04:54 -04002218
2219#Example
2220#Height 128
Cary Clarkbad5ad72017-08-03 17:14:08 -04002221void draw(SkCanvas* canvas) {
2222 SkPaint paint;
2223 canvas->scale(4, 6);
2224 canvas->drawString("truth", 2, 10, paint);
2225 SkMatrix matrix;
2226 matrix.setScale(2.8f, 6);
2227 canvas->setMatrix(matrix);
2228 canvas->drawString("consequences", 2, 20, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002229}
2230##
2231
Cary Clark2ade9972017-11-02 17:49:34 -04002232#SeeAlso resetMatrix concat() translate() rotate() scale() skew()
Cary Clark8032b982017-07-28 11:04:54 -04002233
2234##
2235
2236# ------------------------------------------------------------------------------
2237
2238#Method void resetMatrix()
2239
Cary Clarkab2621d2018-01-30 10:08:57 -05002240#In Matrix
2241#Line # resets Matrix to identity ##
Cary Clark8032b982017-07-28 11:04:54 -04002242Sets Matrix to the identity matrix.
2243Any prior matrix state is overwritten.
2244
2245#Example
2246#Height 128
Cary Clarkbad5ad72017-08-03 17:14:08 -04002247void draw(SkCanvas* canvas) {
2248 SkPaint paint;
2249 canvas->scale(4, 6);
2250 canvas->drawString("truth", 2, 10, paint);
2251 canvas->resetMatrix();
2252 canvas->scale(2.8f, 6);
2253 canvas->drawString("consequences", 2, 20, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002254}
2255##
2256
Cary Clark2ade9972017-11-02 17:49:34 -04002257#SeeAlso setMatrix concat() translate() rotate() scale() skew()
Cary Clark8032b982017-07-28 11:04:54 -04002258
2259##
2260
2261# ------------------------------------------------------------------------------
2262
2263#Method const SkMatrix& getTotalMatrix() const
2264
Cary Clarkab2621d2018-01-30 10:08:57 -05002265#In Matrix
2266#Line # returns Matrix ##
Cary Clark8032b982017-07-28 11:04:54 -04002267Returns Matrix.
2268This does not account for translation by Device or Surface.
2269
Cary Clarkbad5ad72017-08-03 17:14:08 -04002270#Return Matrix in Canvas ##
Cary Clark8032b982017-07-28 11:04:54 -04002271
2272#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04002273 SkDebugf("isIdentity %s\n", canvas->getTotalMatrix().isIdentity() ? "true" : "false");
2274 #StdOut
2275 isIdentity true
2276 ##
Cary Clark8032b982017-07-28 11:04:54 -04002277##
2278
Cary Clark2ade9972017-11-02 17:49:34 -04002279#SeeAlso setMatrix resetMatrix concat()
Cary Clark8032b982017-07-28 11:04:54 -04002280
2281##
2282
Cary Clark08895c42018-02-01 09:37:32 -05002283#Subtopic Matrix ##
Cary Clark8032b982017-07-28 11:04:54 -04002284
2285# ------------------------------------------------------------------------------
Cary Clark08895c42018-02-01 09:37:32 -05002286#Subtopic Clip
2287#Line # stack of clipping Paths ##
Cary Clark8032b982017-07-28 11:04:54 -04002288
2289Clip is built from a stack of clipping paths. Each Path in the
2290stack can be constructed from one or more Path_Contour elements. The
2291Path_Contour may be composed of any number of Path_Verb segments. Each
2292Path_Contour forms a closed area; Path_Fill_Type defines the area enclosed
2293by Path_Contour.
2294
2295Clip stack of Path elements successfully restrict the Path area. Each
2296Path is transformed by Matrix, then intersected with or subtracted from the
2297prior Clip to form the replacement Clip. Use SkClipOp::kDifference
2298to subtract Path from Clip; use SkClipOp::kIntersect to intersect Path
2299with Clip.
2300
Cary Clarkce101242017-09-01 15:51:02 -04002301A clipping Path may be Anti-aliased; if Path, after transformation, is
Cary Clark8032b982017-07-28 11:04:54 -04002302composed of horizontal and vertical lines, clearing Anti-alias allows whole pixels
Cary Clarkce101242017-09-01 15:51:02 -04002303to either be inside or outside the clip. The fastest drawing has a Aliased,
2304rectangular clip.
Cary Clark8032b982017-07-28 11:04:54 -04002305
2306If clipping Path has Anti-alias set, clip may partially clip a pixel, requiring
2307that drawing blend partially with the destination along the edge. A rotated
Cary Clarkce101242017-09-01 15:51:02 -04002308rectangular Anti-aliased clip looks smoother but draws slower.
Cary Clark8032b982017-07-28 11:04:54 -04002309
2310Clip can combine with Rect and Round_Rect primitives; like
2311Path, these are transformed by Matrix before they are combined with Clip.
2312
2313Clip can combine with Region. Region is assumed to be in Device coordinates
2314and is unaffected by Matrix.
2315
2316#Example
2317#Height 90
2318 #Description
Cary Clarkce101242017-09-01 15:51:02 -04002319 Draw a red circle with an Aliased clip and an Anti-aliased clip.
Cary Clark8032b982017-07-28 11:04:54 -04002320 Use an image filter to zoom into the pixels drawn.
Cary Clarkce101242017-09-01 15:51:02 -04002321 The edge of the Aliased clip fully draws pixels in the red circle.
2322 The edge of the Anti-aliased clip partially draws pixels in the red circle.
Cary Clark8032b982017-07-28 11:04:54 -04002323 ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002324 SkPaint redPaint, scalePaint;
2325 redPaint.setAntiAlias(true);
2326 redPaint.setColor(SK_ColorRED);
2327 canvas->save();
2328 for (bool antialias : { false, true } ) {
2329 canvas->save();
2330 canvas->clipRect(SkRect::MakeWH(19.5f, 11.5f), antialias);
2331 canvas->drawCircle(17, 11, 8, redPaint);
2332 canvas->restore();
2333 canvas->translate(16, 0);
2334 }
2335 canvas->restore();
2336 SkMatrix matrix;
2337 matrix.setScale(6, 6);
2338 scalePaint.setImageFilter(
2339 SkImageFilter::MakeMatrixFilter(matrix, kNone_SkFilterQuality, nullptr));
2340 SkCanvas::SaveLayerRec saveLayerRec(
2341 nullptr, &scalePaint, SkCanvas::kInitWithPrevious_SaveLayerFlag);
2342 canvas->saveLayer(saveLayerRec);
Cary Clark8032b982017-07-28 11:04:54 -04002343 canvas->restore();
2344##
2345
2346#Method void clipRect(const SkRect& rect, SkClipOp op, bool doAntiAlias)
2347
Cary Clarkab2621d2018-01-30 10:08:57 -05002348#In Clip
2349#Line # combines Clip with Rect ##
Cary Clark8032b982017-07-28 11:04:54 -04002350Replace Clip with the intersection or difference of Clip and rect,
Cary Clarkce101242017-09-01 15:51:02 -04002351with an Aliased or Anti-aliased clip edge. rect is transformed by Matrix
Cary Clark8032b982017-07-28 11:04:54 -04002352before it is combined with Clip.
2353
Cary Clarka523d2d2017-08-30 08:58:10 -04002354#Param rect Rect to combine with Clip ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002355#Param op Clip_Op to apply to Clip ##
Cary Clarkce101242017-09-01 15:51:02 -04002356#Param doAntiAlias true if Clip is to be Anti-aliased ##
Cary Clark8032b982017-07-28 11:04:54 -04002357
2358#Example
2359#Height 128
Cary Clarkbad5ad72017-08-03 17:14:08 -04002360void draw(SkCanvas* canvas) {
2361 canvas->rotate(10);
2362 SkPaint paint;
2363 paint.setAntiAlias(true);
2364 for (auto alias: { false, true } ) {
2365 canvas->save();
2366 canvas->clipRect(SkRect::MakeWH(90, 80), SkClipOp::kIntersect, alias);
2367 canvas->drawCircle(100, 60, 60, paint);
2368 canvas->restore();
2369 canvas->translate(80, 0);
2370 }
Cary Clark8032b982017-07-28 11:04:54 -04002371}
2372##
2373
Cary Clark2ade9972017-11-02 17:49:34 -04002374#SeeAlso clipRRect clipPath clipRegion
Cary Clark8032b982017-07-28 11:04:54 -04002375
2376##
2377
2378#Method void clipRect(const SkRect& rect, SkClipOp op)
2379
Cary Clarkab2621d2018-01-30 10:08:57 -05002380#In Clip
Cary Clark8032b982017-07-28 11:04:54 -04002381Replace Clip with the intersection or difference of Clip and rect.
Cary Clarkce101242017-09-01 15:51:02 -04002382Resulting Clip is Aliased; pixels are fully contained by the clip.
Cary Clarkbad5ad72017-08-03 17:14:08 -04002383rect is transformed by Matrix before it is combined with Clip.
Cary Clark8032b982017-07-28 11:04:54 -04002384
Cary Clarka523d2d2017-08-30 08:58:10 -04002385#Param rect Rect to combine with Clip ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002386#Param op Clip_Op to apply to Clip ##
Cary Clark8032b982017-07-28 11:04:54 -04002387
2388#Example
2389#Height 192
2390#Width 280
Cary Clarkbad5ad72017-08-03 17:14:08 -04002391void draw(SkCanvas* canvas) {
2392 SkPaint paint;
2393 for (SkClipOp op: { SkClipOp::kIntersect, SkClipOp::kDifference } ) {
2394 canvas->save();
2395 canvas->clipRect(SkRect::MakeWH(90, 120), op, false);
2396 canvas->drawCircle(100, 100, 60, paint);
2397 canvas->restore();
2398 canvas->translate(80, 0);
2399 }
Cary Clark8032b982017-07-28 11:04:54 -04002400}
2401##
2402
Cary Clark2ade9972017-11-02 17:49:34 -04002403#SeeAlso clipRRect clipPath clipRegion
Cary Clark8032b982017-07-28 11:04:54 -04002404
2405##
2406
2407#Method void clipRect(const SkRect& rect, bool doAntiAlias = false)
2408
Cary Clarkab2621d2018-01-30 10:08:57 -05002409#In Clip
Cary Clark8032b982017-07-28 11:04:54 -04002410Replace Clip with the intersection of Clip and rect.
Cary Clarkce101242017-09-01 15:51:02 -04002411Resulting Clip is Aliased; pixels are fully contained by the clip.
Cary Clark8032b982017-07-28 11:04:54 -04002412rect is transformed by Matrix
2413before it is combined with Clip.
2414
Cary Clarka523d2d2017-08-30 08:58:10 -04002415#Param rect Rect to combine with Clip ##
Cary Clarkce101242017-09-01 15:51:02 -04002416#Param doAntiAlias true if Clip is to be Anti-aliased ##
Cary Clark8032b982017-07-28 11:04:54 -04002417
2418#Example
2419#Height 133
2420 #Description
Cary Clarkce101242017-09-01 15:51:02 -04002421 A circle drawn in pieces looks uniform when drawn Aliased.
2422 The same circle pieces blend with pixels more than once when Anti-aliased,
Cary Clark8032b982017-07-28 11:04:54 -04002423 visible as a thin pair of lines through the right circle.
2424 ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002425void draw(SkCanvas* canvas) {
2426 canvas->clear(SK_ColorWHITE);
2427 SkPaint paint;
2428 paint.setAntiAlias(true);
2429 paint.setColor(0x8055aaff);
2430 SkRect clipRect = { 0, 0, 87.4f, 87.4f };
2431 for (auto alias: { false, true } ) {
2432 canvas->save();
2433 canvas->clipRect(clipRect, SkClipOp::kIntersect, alias);
2434 canvas->drawCircle(67, 67, 60, paint);
2435 canvas->restore();
2436 canvas->save();
2437 canvas->clipRect(clipRect, SkClipOp::kDifference, alias);
2438 canvas->drawCircle(67, 67, 60, paint);
2439 canvas->restore();
2440 canvas->translate(120, 0);
2441 }
Cary Clark8032b982017-07-28 11:04:54 -04002442}
2443##
2444
Cary Clark2ade9972017-11-02 17:49:34 -04002445#SeeAlso clipRRect clipPath clipRegion
Cary Clark8032b982017-07-28 11:04:54 -04002446
2447##
2448
2449#Method void androidFramework_setDeviceClipRestriction(const SkIRect& rect)
2450
Cary Clarkab2621d2018-01-30 10:08:57 -05002451#In Clip
2452#Line # for use by Android framework ##
Cary Clarkce101242017-09-01 15:51:02 -04002453Sets the maximum clip rectangle, which can be set by clipRect, clipRRect and
Cary Clark8032b982017-07-28 11:04:54 -04002454clipPath and intersect the current clip with the specified rect.
Cary Clarkce101242017-09-01 15:51:02 -04002455The maximum clip affects only future clipping operations; it is not retroactive.
Cary Clark8032b982017-07-28 11:04:54 -04002456The clip restriction is not recorded in pictures.
2457
Cary Clarkce101242017-09-01 15:51:02 -04002458Pass an empty rect to disable maximum clip.
Cary Clarkbad5ad72017-08-03 17:14:08 -04002459
Cary Clark8032b982017-07-28 11:04:54 -04002460#Private
2461This is private API to be used only by Android framework.
2462##
2463
Cary Clarkbad5ad72017-08-03 17:14:08 -04002464#Param rect maximum allowed clip in device coordinates
Cary Clark579985c2017-07-31 11:48:27 -04002465#Param ##
Cary Clark8032b982017-07-28 11:04:54 -04002466
2467##
2468
2469#Method void clipRRect(const SkRRect& rrect, SkClipOp op, bool doAntiAlias)
2470
Cary Clarkab2621d2018-01-30 10:08:57 -05002471#In Clip
2472#Line # combines Clip with Round_Rect ##
Cary Clark8032b982017-07-28 11:04:54 -04002473Replace Clip with the intersection or difference of Clip and rrect,
Cary Clarkce101242017-09-01 15:51:02 -04002474with an Aliased or Anti-aliased clip edge.
Cary Clark8032b982017-07-28 11:04:54 -04002475rrect is transformed by Matrix
2476before it is combined with Clip.
2477
Cary Clarkbad5ad72017-08-03 17:14:08 -04002478#Param rrect Round_Rect to combine with Clip ##
2479#Param op Clip_Op to apply to Clip ##
Cary Clarkce101242017-09-01 15:51:02 -04002480#Param doAntiAlias true if Clip is to be Anti-aliased ##
Cary Clark8032b982017-07-28 11:04:54 -04002481
2482#Example
2483#Height 128
Cary Clarkbad5ad72017-08-03 17:14:08 -04002484void draw(SkCanvas* canvas) {
2485 canvas->clear(SK_ColorWHITE);
2486 SkPaint paint;
2487 paint.setAntiAlias(true);
2488 paint.setColor(0x8055aaff);
2489 SkRRect oval;
2490 oval.setOval({10, 20, 90, 100});
2491 canvas->clipRRect(oval, SkClipOp::kIntersect, true);
2492 canvas->drawCircle(70, 100, 60, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002493}
2494##
2495
Cary Clark2ade9972017-11-02 17:49:34 -04002496#SeeAlso clipRect clipPath clipRegion
Cary Clark8032b982017-07-28 11:04:54 -04002497
2498##
2499
2500#Method void clipRRect(const SkRRect& rrect, SkClipOp op)
2501
Cary Clarkab2621d2018-01-30 10:08:57 -05002502#In Clip
Cary Clark8032b982017-07-28 11:04:54 -04002503Replace Clip with the intersection or difference of Clip and rrect.
Cary Clarkce101242017-09-01 15:51:02 -04002504Resulting Clip is Aliased; pixels are fully contained by the clip.
Cary Clarkbad5ad72017-08-03 17:14:08 -04002505rrect is transformed by Matrix before it is combined with Clip.
Cary Clark8032b982017-07-28 11:04:54 -04002506
Cary Clarkbad5ad72017-08-03 17:14:08 -04002507#Param rrect Round_Rect to combine with Clip ##
2508#Param op Clip_Op to apply to Clip ##
Cary Clark8032b982017-07-28 11:04:54 -04002509
2510#Example
2511#Height 128
Cary Clarkbad5ad72017-08-03 17:14:08 -04002512void draw(SkCanvas* canvas) {
2513 SkPaint paint;
2514 paint.setColor(0x8055aaff);
2515 auto oval = SkRRect::MakeOval({10, 20, 90, 100});
2516 canvas->clipRRect(oval, SkClipOp::kIntersect);
2517 canvas->drawCircle(70, 100, 60, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002518}
2519##
2520
Cary Clark2ade9972017-11-02 17:49:34 -04002521#SeeAlso clipRect clipPath clipRegion
Cary Clark8032b982017-07-28 11:04:54 -04002522
2523##
2524
2525#Method void clipRRect(const SkRRect& rrect, bool doAntiAlias = false)
2526
Cary Clarkab2621d2018-01-30 10:08:57 -05002527#In Clip
Cary Clark8032b982017-07-28 11:04:54 -04002528Replace Clip with the intersection of Clip and rrect,
Cary Clarkce101242017-09-01 15:51:02 -04002529with an Aliased or Anti-aliased clip edge.
Cary Clarkbad5ad72017-08-03 17:14:08 -04002530rrect is transformed by Matrix before it is combined with Clip.
Cary Clark8032b982017-07-28 11:04:54 -04002531
Cary Clarkbad5ad72017-08-03 17:14:08 -04002532#Param rrect Round_Rect to combine with Clip ##
Cary Clarkce101242017-09-01 15:51:02 -04002533#Param doAntiAlias true if Clip is to be Anti-aliased ##
Cary Clark8032b982017-07-28 11:04:54 -04002534
2535#Example
2536#Height 128
Cary Clarkbad5ad72017-08-03 17:14:08 -04002537void draw(SkCanvas* canvas) {
2538 SkPaint paint;
2539 paint.setAntiAlias(true);
2540 auto oval = SkRRect::MakeRectXY({10, 20, 90, 100}, 9, 13);
2541 canvas->clipRRect(oval, true);
2542 canvas->drawCircle(70, 100, 60, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002543}
2544##
2545
Cary Clark2ade9972017-11-02 17:49:34 -04002546#SeeAlso clipRect clipPath clipRegion
Cary Clark8032b982017-07-28 11:04:54 -04002547
2548##
2549
2550#Method void clipPath(const SkPath& path, SkClipOp op, bool doAntiAlias)
2551
Cary Clarkab2621d2018-01-30 10:08:57 -05002552#In Clip
2553#Line # combines Clip with Path ##
Cary Clark8032b982017-07-28 11:04:54 -04002554Replace Clip with the intersection or difference of Clip and path,
Cary Clarkce101242017-09-01 15:51:02 -04002555with an Aliased or Anti-aliased clip edge. Path_Fill_Type determines if path
Cary Clark8032b982017-07-28 11:04:54 -04002556describes the area inside or outside its contours; and if Path_Contour overlaps
2557itself or another Path_Contour, whether the overlaps form part of the area.
Cary Clarkbad5ad72017-08-03 17:14:08 -04002558path is transformed by Matrix before it is combined with Clip.
Cary Clark8032b982017-07-28 11:04:54 -04002559
Cary Clarkbad5ad72017-08-03 17:14:08 -04002560#Param path Path to combine with Clip ##
2561#Param op Clip_Op to apply to Clip ##
Cary Clarkce101242017-09-01 15:51:02 -04002562#Param doAntiAlias true if Clip is to be Anti-aliased ##
Cary Clark8032b982017-07-28 11:04:54 -04002563
2564#Example
2565#Description
2566Top figure uses SkPath::kInverseWinding_FillType and SkClipOp::kDifference;
2567area outside clip is subtracted from circle.
2568
2569Bottom figure uses SkPath::kWinding_FillType and SkClipOp::kIntersect;
2570area inside clip is intersected with circle.
2571##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002572void draw(SkCanvas* canvas) {
2573 SkPaint paint;
2574 paint.setAntiAlias(true);
2575 SkPath path;
2576 path.addRect({20, 30, 100, 110});
2577 path.setFillType(SkPath::kInverseWinding_FillType);
2578 canvas->save();
2579 canvas->clipPath(path, SkClipOp::kDifference, false);
2580 canvas->drawCircle(70, 100, 60, paint);
2581 canvas->restore();
2582 canvas->translate(100, 100);
2583 path.setFillType(SkPath::kWinding_FillType);
2584 canvas->clipPath(path, SkClipOp::kIntersect, false);
2585 canvas->drawCircle(70, 100, 60, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002586}
2587##
2588
Cary Clark2ade9972017-11-02 17:49:34 -04002589#SeeAlso clipRect clipRRect clipRegion
Cary Clark8032b982017-07-28 11:04:54 -04002590
2591##
2592
2593#Method void clipPath(const SkPath& path, SkClipOp op)
2594
Cary Clarkab2621d2018-01-30 10:08:57 -05002595#In Clip
Cary Clark8032b982017-07-28 11:04:54 -04002596Replace Clip with the intersection or difference of Clip and path.
Cary Clarkce101242017-09-01 15:51:02 -04002597Resulting Clip is Aliased; pixels are fully contained by the clip.
Cary Clark8032b982017-07-28 11:04:54 -04002598Path_Fill_Type determines if path
2599describes the area inside or outside its contours; and if Path_Contour overlaps
2600itself or another Path_Contour, whether the overlaps form part of the area.
2601path is transformed by Matrix
2602before it is combined with Clip.
2603
Cary Clarkbad5ad72017-08-03 17:14:08 -04002604#Param path Path to combine with Clip ##
2605#Param op Clip_Op to apply to Clip ##
Cary Clark8032b982017-07-28 11:04:54 -04002606
2607#Example
2608#Description
Cary Clarkbc5697d2017-10-04 14:31:33 -04002609Overlapping Rects form a clip. When clip Path_Fill_Type is set to
Cary Clark8032b982017-07-28 11:04:54 -04002610SkPath::kWinding_FillType, the overlap is included. Set to
2611SkPath::kEvenOdd_FillType, the overlap is excluded and forms a hole.
2612##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002613void draw(SkCanvas* canvas) {
2614 SkPaint paint;
2615 paint.setAntiAlias(true);
2616 SkPath path;
2617 path.addRect({20, 15, 100, 95});
2618 path.addRect({50, 65, 130, 135});
2619 path.setFillType(SkPath::kWinding_FillType);
2620 canvas->save();
2621 canvas->clipPath(path, SkClipOp::kIntersect);
2622 canvas->drawCircle(70, 85, 60, paint);
2623 canvas->restore();
2624 canvas->translate(100, 100);
2625 path.setFillType(SkPath::kEvenOdd_FillType);
2626 canvas->clipPath(path, SkClipOp::kIntersect);
2627 canvas->drawCircle(70, 85, 60, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002628}
2629##
2630
Cary Clark2ade9972017-11-02 17:49:34 -04002631#SeeAlso clipRect clipRRect clipRegion
Cary Clark8032b982017-07-28 11:04:54 -04002632
2633##
2634
2635#Method void clipPath(const SkPath& path, bool doAntiAlias = false)
2636
Cary Clarkab2621d2018-01-30 10:08:57 -05002637#In Clip
Cary Clark8032b982017-07-28 11:04:54 -04002638Replace Clip with the intersection of Clip and path.
Cary Clarkce101242017-09-01 15:51:02 -04002639Resulting Clip is Aliased; pixels are fully contained by the clip.
Cary Clark8032b982017-07-28 11:04:54 -04002640Path_Fill_Type determines if path
2641describes the area inside or outside its contours; and if Path_Contour overlaps
2642itself or another Path_Contour, whether the overlaps form part of the area.
Cary Clarkbad5ad72017-08-03 17:14:08 -04002643path is transformed by Matrix before it is combined with Clip.
Cary Clark8032b982017-07-28 11:04:54 -04002644
Cary Clarkbad5ad72017-08-03 17:14:08 -04002645#Param path Path to combine with Clip ##
Cary Clarkce101242017-09-01 15:51:02 -04002646#Param doAntiAlias true if Clip is to be Anti-aliased ##
Cary Clark8032b982017-07-28 11:04:54 -04002647
2648#Example
2649#Height 212
2650#Description
Cary Clarkbc5697d2017-10-04 14:31:33 -04002651Clip loops over itself covering its center twice. When clip Path_Fill_Type
Cary Clark8032b982017-07-28 11:04:54 -04002652is set to SkPath::kWinding_FillType, the overlap is included. Set to
2653SkPath::kEvenOdd_FillType, the overlap is excluded and forms a hole.
2654##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002655void draw(SkCanvas* canvas) {
2656 SkPaint paint;
2657 paint.setAntiAlias(true);
2658 SkPath path;
2659 SkPoint poly[] = {{20, 20}, { 80, 20}, { 80, 80}, {40, 80},
2660 {40, 40}, {100, 40}, {100, 100}, {20, 100}};
2661 path.addPoly(poly, SK_ARRAY_COUNT(poly), true);
2662 path.setFillType(SkPath::kWinding_FillType);
2663 canvas->save();
2664 canvas->clipPath(path, SkClipOp::kIntersect);
2665 canvas->drawCircle(50, 50, 45, paint);
2666 canvas->restore();
2667 canvas->translate(100, 100);
2668 path.setFillType(SkPath::kEvenOdd_FillType);
2669 canvas->clipPath(path, SkClipOp::kIntersect);
2670 canvas->drawCircle(50, 50, 45, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002671}
2672##
2673
Cary Clark2ade9972017-11-02 17:49:34 -04002674#SeeAlso clipRect clipRRect clipRegion
Cary Clark8032b982017-07-28 11:04:54 -04002675
2676##
2677
2678# ------------------------------------------------------------------------------
2679
2680#Method void setAllowSimplifyClip(bool allow)
2681
Cary Clarkab2621d2018-01-30 10:08:57 -05002682#In Clip
2683#Line # experimental ##
Cary Clark8032b982017-07-28 11:04:54 -04002684#Experimental
2685Only used for testing.
2686##
2687
Cary Clarkce101242017-09-01 15:51:02 -04002688Set to simplify clip stack using PathOps.
Cary Clark8032b982017-07-28 11:04:54 -04002689
2690##
2691
2692# ------------------------------------------------------------------------------
2693
2694#Method void clipRegion(const SkRegion& deviceRgn, SkClipOp op = SkClipOp::kIntersect)
2695
Cary Clarkab2621d2018-01-30 10:08:57 -05002696#In Clip
2697#Line # combines Clip with Region ##
Cary Clark8032b982017-07-28 11:04:54 -04002698Replace Clip with the intersection or difference of Clip and Region deviceRgn.
Cary Clarkce101242017-09-01 15:51:02 -04002699Resulting Clip is Aliased; pixels are fully contained by the clip.
Cary Clark8032b982017-07-28 11:04:54 -04002700deviceRgn is unaffected by Matrix.
2701
Cary Clarkbad5ad72017-08-03 17:14:08 -04002702#Param deviceRgn Region to combine with Clip ##
2703#Param op Clip_Op to apply to Clip ##
Cary Clark8032b982017-07-28 11:04:54 -04002704
2705#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04002706#Description
Cary Clarkce101242017-09-01 15:51:02 -04002707 region is unaffected by canvas rotation; iRect is affected by canvas rotation.
2708 Both clips are Aliased; this is not noticeable on Region clip because it
Cary Clarkbad5ad72017-08-03 17:14:08 -04002709 aligns to pixel boundaries.
2710##
2711void draw(SkCanvas* canvas) {
2712 SkPaint paint;
2713 paint.setAntiAlias(true);
2714 SkIRect iRect = {30, 40, 120, 130 };
2715 SkRegion region(iRect);
2716 canvas->rotate(10);
2717 canvas->save();
2718 canvas->clipRegion(region, SkClipOp::kIntersect);
2719 canvas->drawCircle(50, 50, 45, paint);
2720 canvas->restore();
2721 canvas->translate(100, 100);
2722 canvas->clipRect(SkRect::Make(iRect), SkClipOp::kIntersect);
2723 canvas->drawCircle(50, 50, 45, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002724}
2725##
2726
Cary Clark2ade9972017-11-02 17:49:34 -04002727#SeeAlso clipRect clipRRect clipPath
Cary Clark8032b982017-07-28 11:04:54 -04002728
2729##
2730
2731#Method bool quickReject(const SkRect& rect) const
2732
Cary Clarkab2621d2018-01-30 10:08:57 -05002733#In Clip
2734#Line # returns if Rect is outside Clip ##
Cary Clark8032b982017-07-28 11:04:54 -04002735Return true if Rect rect, transformed by Matrix, can be quickly determined to be
2736outside of Clip. May return false even though rect is outside of Clip.
2737
2738Use to check if an area to be drawn is clipped out, to skip subsequent draw calls.
2739
Cary Clarkbad5ad72017-08-03 17:14:08 -04002740#Param rect Rect to compare with Clip ##
Cary Clark8032b982017-07-28 11:04:54 -04002741
Cary Clarkbad5ad72017-08-03 17:14:08 -04002742#Return true if rect, transformed by Matrix, does not intersect Clip ##
Cary Clark8032b982017-07-28 11:04:54 -04002743
2744#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04002745void draw(SkCanvas* canvas) {
2746 SkRect testRect = {30, 30, 120, 129 };
2747 SkRect clipRect = {30, 130, 120, 230 };
2748 canvas->save();
2749 canvas->clipRect(clipRect);
2750 SkDebugf("quickReject %s\n", canvas->quickReject(testRect) ? "true" : "false");
2751 canvas->restore();
2752 canvas->rotate(10);
2753 canvas->clipRect(clipRect);
2754 SkDebugf("quickReject %s\n", canvas->quickReject(testRect) ? "true" : "false");
Cary Clark8032b982017-07-28 11:04:54 -04002755}
2756 #StdOut
Cary Clarkbad5ad72017-08-03 17:14:08 -04002757 quickReject true
Cary Clark8032b982017-07-28 11:04:54 -04002758 quickReject false
2759 ##
2760##
2761
Cary Clark2ade9972017-11-02 17:49:34 -04002762#SeeAlso getLocalClipBounds getTotalMatrix SkBitmap::drawsNothing
Cary Clark8032b982017-07-28 11:04:54 -04002763
2764##
2765
2766#Method bool quickReject(const SkPath& path) const
2767
Cary Clarkab2621d2018-01-30 10:08:57 -05002768#In Clip
Cary Clark8032b982017-07-28 11:04:54 -04002769Return true if path, transformed by Matrix, can be quickly determined to be
2770outside of Clip. May return false even though path is outside of Clip.
2771
2772Use to check if an area to be drawn is clipped out, to skip subsequent draw calls.
2773
Cary Clarkbad5ad72017-08-03 17:14:08 -04002774#Param path Path to compare with Clip ##
Cary Clark8032b982017-07-28 11:04:54 -04002775
Cary Clarkbad5ad72017-08-03 17:14:08 -04002776#Return true if path, transformed by Matrix, does not intersect Clip ##
Cary Clark8032b982017-07-28 11:04:54 -04002777
2778#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04002779void draw(SkCanvas* canvas) {
2780 SkPoint testPoints[] = {{30, 30}, {120, 30}, {120, 129} };
2781 SkPoint clipPoints[] = {{30, 130}, {120, 130}, {120, 230} };
2782 SkPath testPath, clipPath;
2783 testPath.addPoly(testPoints, SK_ARRAY_COUNT(testPoints), true);
2784 clipPath.addPoly(clipPoints, SK_ARRAY_COUNT(clipPoints), true);
2785 canvas->save();
2786 canvas->clipPath(clipPath);
2787 SkDebugf("quickReject %s\n", canvas->quickReject(testPath) ? "true" : "false");
2788 canvas->restore();
2789 canvas->rotate(10);
2790 canvas->clipPath(clipPath);
2791 SkDebugf("quickReject %s\n", canvas->quickReject(testPath) ? "true" : "false");
Cary Clark8032b982017-07-28 11:04:54 -04002792 #StdOut
Cary Clarkbad5ad72017-08-03 17:14:08 -04002793 quickReject true
Cary Clark8032b982017-07-28 11:04:54 -04002794 quickReject false
2795 ##
2796}
2797##
2798
Cary Clark2ade9972017-11-02 17:49:34 -04002799#SeeAlso getLocalClipBounds getTotalMatrix SkBitmap::drawsNothing
Cary Clark8032b982017-07-28 11:04:54 -04002800
2801##
2802
2803#Method SkRect getLocalClipBounds() const
2804
Cary Clarkab2621d2018-01-30 10:08:57 -05002805#In Clip
2806#Line # returns Clip bounds in source coordinates ##
Cary Clark8032b982017-07-28 11:04:54 -04002807Return bounds of Clip, transformed by inverse of Matrix. If Clip is empty,
2808return SkRect::MakeEmpty, where all Rect sides equal zero.
2809
2810Rect returned is outset by one to account for partial pixel coverage if Clip
Cary Clarkce101242017-09-01 15:51:02 -04002811is Anti-aliased.
Cary Clark8032b982017-07-28 11:04:54 -04002812
Cary Clarkbad5ad72017-08-03 17:14:08 -04002813#Return bounds of Clip in local coordinates ##
Cary Clark8032b982017-07-28 11:04:54 -04002814
2815#Example
2816 #Description
2817 Initial bounds is device bounds outset by 1 on all sides.
2818 Clipped bounds is clipPath bounds outset by 1 on all sides.
2819 Scaling the canvas by two in x and y scales the local bounds by 1/2 in x and y.
2820 ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002821 SkCanvas local(256, 256);
2822 canvas = &local;
2823 SkRect bounds = canvas->getLocalClipBounds();
2824 SkDebugf("left:%g top:%g right:%g bottom:%g\n",
2825 bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom);
2826 SkPoint clipPoints[] = {{30, 130}, {120, 130}, {120, 230} };
2827 SkPath clipPath;
2828 clipPath.addPoly(clipPoints, SK_ARRAY_COUNT(clipPoints), true);
2829 canvas->clipPath(clipPath);
2830 bounds = canvas->getLocalClipBounds();
2831 SkDebugf("left:%g top:%g right:%g bottom:%g\n",
2832 bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom);
2833 canvas->scale(2, 2);
2834 bounds = canvas->getLocalClipBounds();
2835 SkDebugf("left:%g top:%g right:%g bottom:%g\n",
2836 bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom);
2837 #StdOut
2838 left:-1 top:-1 right:257 bottom:257
2839 left:29 top:129 right:121 bottom:231
2840 left:14.5 top:64.5 right:60.5 bottom:115.5
2841 ##
Cary Clark8032b982017-07-28 11:04:54 -04002842##
2843
2844# local canvas in example works around bug in fiddle ##
Cary Clark4855f782018-02-06 09:41:53 -05002845#Bug 6524
Cary Clark2ade9972017-11-02 17:49:34 -04002846#SeeAlso getDeviceClipBounds getBaseLayerSize quickReject
Cary Clark8032b982017-07-28 11:04:54 -04002847
2848##
2849
2850#Method bool getLocalClipBounds(SkRect* bounds) const
2851
Cary Clarkab2621d2018-01-30 10:08:57 -05002852#In Clip
Cary Clark8032b982017-07-28 11:04:54 -04002853Return bounds of Clip, transformed by inverse of Matrix. If Clip is empty,
2854return false, and set bounds to SkRect::MakeEmpty, where all Rect sides equal zero.
2855
2856bounds is outset by one to account for partial pixel coverage if Clip
Cary Clarkce101242017-09-01 15:51:02 -04002857is Anti-aliased.
Cary Clark8032b982017-07-28 11:04:54 -04002858
Cary Clarkbad5ad72017-08-03 17:14:08 -04002859#Param bounds Rect of Clip in local coordinates ##
Cary Clark8032b982017-07-28 11:04:54 -04002860
Cary Clarkbad5ad72017-08-03 17:14:08 -04002861#Return true if Clip bounds is not empty ##
Cary Clark8032b982017-07-28 11:04:54 -04002862
2863#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04002864 void draw(SkCanvas* canvas) {
2865 SkCanvas local(256, 256);
2866 canvas = &local;
2867 SkRect bounds;
2868 SkDebugf("local bounds empty = %s\n", canvas->getLocalClipBounds(&bounds)
2869 ? "false" : "true");
2870 SkPath path;
2871 canvas->clipPath(path);
2872 SkDebugf("local bounds empty = %s\n", canvas->getLocalClipBounds(&bounds)
2873 ? "false" : "true");
Cary Clark8032b982017-07-28 11:04:54 -04002874 }
2875 #StdOut
Cary Clarkbad5ad72017-08-03 17:14:08 -04002876 local bounds empty = false
Cary Clark8032b982017-07-28 11:04:54 -04002877 local bounds empty = true
2878 ##
2879##
2880
2881# local canvas in example works around bug in fiddle ##
Cary Clark4855f782018-02-06 09:41:53 -05002882#Bug 6524
Cary Clark2ade9972017-11-02 17:49:34 -04002883#SeeAlso getDeviceClipBounds getBaseLayerSize quickReject
Cary Clark8032b982017-07-28 11:04:54 -04002884
2885##
2886
2887#Method SkIRect getDeviceClipBounds() const
2888
Cary Clarkab2621d2018-01-30 10:08:57 -05002889#In Clip
2890#Line # returns IRect bounds of Clip ##
Cary Clark8032b982017-07-28 11:04:54 -04002891Return IRect bounds of Clip, unaffected by Matrix. If Clip is empty,
2892return SkRect::MakeEmpty, where all Rect sides equal zero.
2893
2894Unlike getLocalClipBounds, returned IRect is not outset.
2895
Cary Clarkbad5ad72017-08-03 17:14:08 -04002896#Return bounds of Clip in Device coordinates ##
Cary Clark8032b982017-07-28 11:04:54 -04002897
2898#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04002899void draw(SkCanvas* canvas) {
2900 #Description
Cary Clark8032b982017-07-28 11:04:54 -04002901 Initial bounds is device bounds, not outset.
2902 Clipped bounds is clipPath bounds, not outset.
2903 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 -04002904 ##
2905 SkCanvas device(256, 256);
2906 canvas = &device;
2907 SkIRect bounds = canvas->getDeviceClipBounds();
2908 SkDebugf("left:%d top:%d right:%d bottom:%d\n",
2909 bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom);
2910 SkPoint clipPoints[] = {{30, 130}, {120, 130}, {120, 230} };
2911 SkPath clipPath;
2912 clipPath.addPoly(clipPoints, SK_ARRAY_COUNT(clipPoints), true);
2913 canvas->save();
2914 canvas->clipPath(clipPath);
2915 bounds = canvas->getDeviceClipBounds();
2916 SkDebugf("left:%d top:%d right:%d bottom:%d\n",
2917 bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom);
2918 canvas->restore();
2919 canvas->scale(1.f/2, 1.f/2);
2920 canvas->clipPath(clipPath);
2921 bounds = canvas->getDeviceClipBounds();
2922 SkDebugf("left:%d top:%d right:%d bottom:%d\n",
2923 bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom);
Cary Clark8032b982017-07-28 11:04:54 -04002924 #StdOut
Cary Clarkbad5ad72017-08-03 17:14:08 -04002925 left:0 top:0 right:256 bottom:256
2926 left:30 top:130 right:120 bottom:230
Cary Clark8032b982017-07-28 11:04:54 -04002927 left:15 top:65 right:60 bottom:115
2928 ##
2929}
2930##
2931
2932#ToDo some confusion on why with an identity Matrix local and device are different ##
Cary Clark2ade9972017-11-02 17:49:34 -04002933#SeeAlso getLocalClipBounds getBaseLayerSize quickReject
Cary Clark8032b982017-07-28 11:04:54 -04002934
2935# device canvas in example works around bug in fiddle ##
Cary Clark4855f782018-02-06 09:41:53 -05002936#Bug 6524
Cary Clark8032b982017-07-28 11:04:54 -04002937
2938##
2939
2940#Method bool getDeviceClipBounds(SkIRect* bounds) const
2941
Cary Clarkab2621d2018-01-30 10:08:57 -05002942#In Clip
Cary Clark8032b982017-07-28 11:04:54 -04002943Return IRect bounds of Clip, unaffected by Matrix. If Clip is empty,
2944return false, and set bounds to SkRect::MakeEmpty, where all Rect sides equal zero.
2945
2946Unlike getLocalClipBounds, bounds is not outset.
2947
Cary Clarkbad5ad72017-08-03 17:14:08 -04002948#Param bounds Rect of Clip in device coordinates ##
Cary Clark8032b982017-07-28 11:04:54 -04002949
Cary Clarkbad5ad72017-08-03 17:14:08 -04002950#Return true if Clip bounds is not empty ##
Cary Clark8032b982017-07-28 11:04:54 -04002951
2952#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04002953 void draw(SkCanvas* canvas) {
2954 SkIRect bounds;
2955 SkDebugf("device bounds empty = %s\n", canvas->getDeviceClipBounds(&bounds)
2956 ? "false" : "true");
2957 SkPath path;
2958 canvas->clipPath(path);
2959 SkDebugf("device bounds empty = %s\n", canvas->getDeviceClipBounds(&bounds)
2960 ? "false" : "true");
Cary Clark8032b982017-07-28 11:04:54 -04002961 }
2962 #StdOut
Cary Clarkbad5ad72017-08-03 17:14:08 -04002963 device bounds empty = false
Cary Clark8032b982017-07-28 11:04:54 -04002964 device bounds empty = true
2965 ##
2966##
2967
Cary Clark2ade9972017-11-02 17:49:34 -04002968#SeeAlso getLocalClipBounds getBaseLayerSize quickReject
Cary Clark8032b982017-07-28 11:04:54 -04002969
2970##
2971
Cary Clark08895c42018-02-01 09:37:32 -05002972#Subtopic Clip ##
Cary Clark8032b982017-07-28 11:04:54 -04002973
2974# ------------------------------------------------------------------------------
2975
2976#Method void drawColor(SkColor color, SkBlendMode mode = SkBlendMode::kSrcOver)
2977
Cary Clarkab2621d2018-01-30 10:08:57 -05002978#Line # fills Clip with Color and Blend_Mode ##
Cary Clark8032b982017-07-28 11:04:54 -04002979Fill Clip with Color color.
2980mode determines how Color_ARGB is combined with destination.
2981
Cary Clarkbad5ad72017-08-03 17:14:08 -04002982#Param color Unpremultiplied Color_ARGB ##
2983#Param mode SkBlendMode used to combine source color and destination ##
Cary Clark8032b982017-07-28 11:04:54 -04002984
2985#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04002986 canvas->drawColor(SK_ColorRED);
2987 canvas->clipRect(SkRect::MakeWH(150, 150));
2988 canvas->drawColor(SkColorSetARGB(0x80, 0x00, 0xFF, 0x00), SkBlendMode::kPlus);
2989 canvas->clipRect(SkRect::MakeWH(75, 75));
2990 canvas->drawColor(SkColorSetARGB(0x80, 0x00, 0x00, 0xFF), SkBlendMode::kPlus);
Cary Clark8032b982017-07-28 11:04:54 -04002991##
2992
Cary Clark2ade9972017-11-02 17:49:34 -04002993#SeeAlso clear SkBitmap::erase drawPaint
Cary Clark8032b982017-07-28 11:04:54 -04002994
2995##
2996
2997# ------------------------------------------------------------------------------
2998
2999#Method void clear(SkColor color)
3000
Cary Clarkab2621d2018-01-30 10:08:57 -05003001#Line # fills Clip with Color ##
Cary Clark8032b982017-07-28 11:04:54 -04003002Fill Clip with Color color using SkBlendMode::kSrc.
3003This has the effect of replacing all pixels contained by Clip with color.
3004
Cary Clarkbad5ad72017-08-03 17:14:08 -04003005#Param color Unpremultiplied Color_ARGB ##
Cary Clark8032b982017-07-28 11:04:54 -04003006
3007#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003008void draw(SkCanvas* canvas) {
3009 canvas->save();
3010 canvas->clipRect(SkRect::MakeWH(256, 128));
3011 canvas->clear(SkColorSetARGB(0x80, 0xFF, 0x00, 0x00));
3012 canvas->restore();
3013 canvas->save();
3014 canvas->clipRect(SkRect::MakeWH(150, 192));
3015 canvas->clear(SkColorSetARGB(0x80, 0x00, 0xFF, 0x00));
3016 canvas->restore();
3017 canvas->clipRect(SkRect::MakeWH(75, 256));
3018 canvas->clear(SkColorSetARGB(0x80, 0x00, 0x00, 0xFF));
Cary Clark8032b982017-07-28 11:04:54 -04003019}
3020##
3021
Cary Clark2ade9972017-11-02 17:49:34 -04003022#SeeAlso drawColor SkBitmap::erase drawPaint
Cary Clark8032b982017-07-28 11:04:54 -04003023
3024##
3025
3026# ------------------------------------------------------------------------------
3027
3028#Method void discard()
3029
Cary Clarkab2621d2018-01-30 10:08:57 -05003030#Line # makes Canvas contents undefined ##
Cary Clark8032b982017-07-28 11:04:54 -04003031Make Canvas contents undefined. Subsequent calls that read Canvas pixels,
3032such as drawing with SkBlendMode, return undefined results. discard() does
3033not change Clip or Matrix.
3034
3035discard() may do nothing, depending on the implementation of Surface or Device
3036that created Canvas.
3037
3038discard() allows optimized performance on subsequent draws by removing
3039cached data associated with Surface or Device.
3040It is not necessary to call discard() once done with Canvas;
3041any cached data is deleted when owning Surface or Device is deleted.
3042
3043#ToDo example? not sure how to make this meaningful w/o more implementation detail ##
Cary Clark2ade9972017-11-02 17:49:34 -04003044#SeeAlso flush() SkSurface::prepareForExternalIO GrContext::abandonContext
Cary Clark8032b982017-07-28 11:04:54 -04003045
3046#NoExample
3047##
3048
3049##
3050
3051# ------------------------------------------------------------------------------
3052
3053#Method void drawPaint(const SkPaint& paint)
3054
Cary Clarkab2621d2018-01-30 10:08:57 -05003055#Line # fills Clip with Paint ##
Mike Reed8ad91a92018-01-19 19:09:32 -05003056Fill Clip with Paint paint. Paint components Mask_Filter, Shader,
Cary Clarkbad5ad72017-08-03 17:14:08 -04003057Color_Filter, Image_Filter, and Blend_Mode affect drawing;
3058Path_Effect in paint is ignored.
Cary Clark8032b982017-07-28 11:04:54 -04003059
3060# can Path_Effect in paint ever alter drawPaint?
3061
Cary Clarkbad5ad72017-08-03 17:14:08 -04003062#Param paint graphics state used to fill Canvas ##
Cary Clark8032b982017-07-28 11:04:54 -04003063
3064#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003065void draw(SkCanvas* canvas) {
3066 SkColor colors[] = { SK_ColorRED, SK_ColorGREEN, SK_ColorBLUE };
3067 SkScalar pos[] = { 0, SK_Scalar1/2, SK_Scalar1 };
3068 SkPaint paint;
3069 paint.setShader(SkGradientShader::MakeSweep(256, 256, colors, pos, SK_ARRAY_COUNT(colors)));
3070 canvas->drawPaint(paint);
Cary Clark8032b982017-07-28 11:04:54 -04003071}
3072##
3073
Cary Clark2ade9972017-11-02 17:49:34 -04003074#SeeAlso clear drawColor SkBitmap::erase
Cary Clark8032b982017-07-28 11:04:54 -04003075
3076##
3077
3078# ------------------------------------------------------------------------------
3079
3080#Enum PointMode
Cary Clark08895c42018-02-01 09:37:32 -05003081#Line # sets drawPoints options ##
Cary Clark8032b982017-07-28 11:04:54 -04003082
3083#Code
3084 enum PointMode {
3085 kPoints_PointMode,
3086 kLines_PointMode,
Cary Clarkd0530ba2017-09-14 11:25:39 -04003087 kPolygon_PointMode,
Cary Clark8032b982017-07-28 11:04:54 -04003088 };
3089##
3090
3091Selects if an array of points are drawn as discrete points, as lines, or as
3092an open polygon.
3093
3094#Const kPoints_PointMode 0
3095 Draw each point separately.
3096##
3097
3098#Const kLines_PointMode 1
3099 Draw each pair of points as a line segment.
3100##
3101
3102#Const kPolygon_PointMode 2
3103 Draw the array of points as a open polygon.
3104##
3105
3106#Example
3107 #Description
3108 The upper left corner shows three squares when drawn as points.
3109 The upper right corner shows one line; when drawn as lines, two points are required per line.
3110 The lower right corner shows two lines; when draw as polygon, no miter is drawn at the corner.
3111 The lower left corner shows two lines with a miter when path contains polygon.
3112 ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003113void draw(SkCanvas* canvas) {
3114 SkPaint paint;
3115 paint.setStyle(SkPaint::kStroke_Style);
3116 paint.setStrokeWidth(10);
3117 SkPoint points[] = {{64, 32}, {96, 96}, {32, 96}};
3118 canvas->drawPoints(SkCanvas::kPoints_PointMode, 3, points, paint);
3119 canvas->translate(128, 0);
3120 canvas->drawPoints(SkCanvas::kLines_PointMode, 3, points, paint);
3121 canvas->translate(0, 128);
3122 canvas->drawPoints(SkCanvas::kPolygon_PointMode, 3, points, paint);
3123 SkPath path;
3124 path.addPoly(points, 3, false);
3125 canvas->translate(-128, 0);
3126 canvas->drawPath(path, paint);
Cary Clark8032b982017-07-28 11:04:54 -04003127}
3128##
3129
Cary Clark2ade9972017-11-02 17:49:34 -04003130#SeeAlso drawLine drawPoint drawPath
Cary Clark8032b982017-07-28 11:04:54 -04003131
3132##
3133
3134# ------------------------------------------------------------------------------
3135
3136#Method void drawPoints(PointMode mode, size_t count, const SkPoint pts[], const SkPaint& paint)
3137
Cary Clarkab2621d2018-01-30 10:08:57 -05003138#Line # draws array as points, lines, polygon ##
Cary Clark8032b982017-07-28 11:04:54 -04003139Draw pts using Clip, Matrix and Paint paint.
Cary Clarkbad5ad72017-08-03 17:14:08 -04003140count is the number of points; if count is less than one, has no effect.
Cary Clark8032b982017-07-28 11:04:54 -04003141mode may be one of: kPoints_PointMode, kLines_PointMode, or kPolygon_PointMode.
3142
Cary Clarkbad5ad72017-08-03 17:14:08 -04003143If mode is kPoints_PointMode, the shape of point drawn depends on paint
3144Paint_Stroke_Cap. If paint is set to SkPaint::kRound_Cap, each point draws a
3145circle of diameter Paint_Stroke_Width. If paint is set to SkPaint::kSquare_Cap
3146or SkPaint::kButt_Cap, each point draws a square of width and height
3147Paint_Stroke_Width.
Cary Clark8032b982017-07-28 11:04:54 -04003148
3149If mode is kLines_PointMode, each pair of points draws a line segment.
3150One line is drawn for every two points; each point is used once. If count is odd,
3151the final point is ignored.
3152
3153If mode is kPolygon_PointMode, each adjacent pair of points draws a line segment.
3154count minus one lines are drawn; the first and last point are used once.
3155
3156Each line segment respects paint Paint_Stroke_Cap and Paint_Stroke_Width.
3157Paint_Style is ignored, as if were set to SkPaint::kStroke_Style.
3158
Cary Clarkbad5ad72017-08-03 17:14:08 -04003159Always draws each element one at a time; is not affected by
3160Paint_Stroke_Join, and unlike drawPath, does not create a mask from all points
3161and lines before drawing.
Cary Clark8032b982017-07-28 11:04:54 -04003162
Cary Clarka523d2d2017-08-30 08:58:10 -04003163#Param mode whether pts draws points or lines ##
3164#Param count number of points in the array ##
3165#Param pts array of points to draw ##
3166#Param paint stroke, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003167
3168#Example
3169#Height 200
3170 #Description
3171 #List
3172 # The first column draws points. ##
3173 # The second column draws points as lines. ##
3174 # The third column draws points as a polygon. ##
3175 # The fourth column draws points as a polygonal path. ##
3176 # The first row uses a round cap and round join. ##
3177 # The second row uses a square cap and a miter join. ##
3178 # The third row uses a butt cap and a bevel join. ##
3179 ##
3180 The transparent color makes multiple line draws visible;
3181 the path is drawn all at once.
3182 ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003183void draw(SkCanvas* canvas) {
3184 SkPaint paint;
3185 paint.setAntiAlias(true);
3186 paint.setStyle(SkPaint::kStroke_Style);
3187 paint.setStrokeWidth(10);
3188 paint.setColor(0x80349a45);
3189 const SkPoint points[] = {{32, 16}, {48, 48}, {16, 32}};
3190 const SkPaint::Join join[] = { SkPaint::kRound_Join,
3191 SkPaint::kMiter_Join,
3192 SkPaint::kBevel_Join };
3193 int joinIndex = 0;
3194 SkPath path;
3195 path.addPoly(points, 3, false);
3196 for (const auto cap : { SkPaint::kRound_Cap, SkPaint::kSquare_Cap, SkPaint::kButt_Cap } ) {
3197 paint.setStrokeCap(cap);
3198 paint.setStrokeJoin(join[joinIndex++]);
3199 for (const auto mode : { SkCanvas::kPoints_PointMode,
3200 SkCanvas::kLines_PointMode,
3201 SkCanvas::kPolygon_PointMode } ) {
3202 canvas->drawPoints(mode, 3, points, paint);
3203 canvas->translate(64, 0);
3204 }
3205 canvas->drawPath(path, paint);
3206 canvas->translate(-192, 64);
3207 }
Cary Clark8032b982017-07-28 11:04:54 -04003208}
3209##
3210
Cary Clark2ade9972017-11-02 17:49:34 -04003211#SeeAlso drawLine drawPoint drawPath
Cary Clark8032b982017-07-28 11:04:54 -04003212
3213##
3214
3215# ------------------------------------------------------------------------------
3216
3217#Method void drawPoint(SkScalar x, SkScalar y, const SkPaint& paint)
3218
Cary Clarkab2621d2018-01-30 10:08:57 -05003219#Line # draws point at (x, y) position ##
Cary Clark8032b982017-07-28 11:04:54 -04003220Draw point at (x, y) using Clip, Matrix and Paint paint.
3221
3222The shape of point drawn depends on paint Paint_Stroke_Cap.
Cary Clarkbad5ad72017-08-03 17:14:08 -04003223If paint is set to SkPaint::kRound_Cap, draw a circle of diameter
3224Paint_Stroke_Width. If paint is set to SkPaint::kSquare_Cap or SkPaint::kButt_Cap,
Cary Clark8032b982017-07-28 11:04:54 -04003225draw a square of width and height Paint_Stroke_Width.
3226Paint_Style is ignored, as if were set to SkPaint::kStroke_Style.
3227
Cary Clarkbad5ad72017-08-03 17:14:08 -04003228#Param x left edge of circle or square ##
3229#Param y top edge of circle or square ##
3230#Param paint stroke, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003231
3232#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003233void draw(SkCanvas* canvas) {
3234 SkPaint paint;
3235 paint.setAntiAlias(true);
3236 paint.setColor(0x80349a45);
3237 paint.setStyle(SkPaint::kStroke_Style);
3238 paint.setStrokeWidth(100);
3239 paint.setStrokeCap(SkPaint::kRound_Cap);
3240 canvas->scale(1, 1.2f);
3241 canvas->drawPoint(64, 96, paint);
3242 canvas->scale(.6f, .8f);
3243 paint.setColor(SK_ColorWHITE);
3244 canvas->drawPoint(106, 120, paint);
Cary Clark8032b982017-07-28 11:04:54 -04003245}
3246##
3247
Cary Clark2ade9972017-11-02 17:49:34 -04003248#SeeAlso drawPoints drawCircle drawRect drawLine drawPath
Cary Clark8032b982017-07-28 11:04:54 -04003249
3250##
3251
Cary Clarkbad5ad72017-08-03 17:14:08 -04003252#Method void drawPoint(SkPoint p, const SkPaint& paint)
3253
3254Draw point p using Clip, Matrix and Paint paint.
3255
3256The shape of point drawn depends on paint Paint_Stroke_Cap.
3257If paint is set to SkPaint::kRound_Cap, draw a circle of diameter
3258Paint_Stroke_Width. If paint is set to SkPaint::kSquare_Cap or SkPaint::kButt_Cap,
3259draw a square of width and height Paint_Stroke_Width.
3260Paint_Style is ignored, as if were set to SkPaint::kStroke_Style.
3261
3262#Param p top-left edge of circle or square ##
3263#Param paint stroke, blend, color, and so on, used to draw ##
3264
3265#Example
3266void draw(SkCanvas* canvas) {
3267 SkPaint paint;
3268 paint.setAntiAlias(true);
3269 paint.setColor(0x80349a45);
3270 paint.setStyle(SkPaint::kStroke_Style);
3271 paint.setStrokeWidth(100);
3272 paint.setStrokeCap(SkPaint::kSquare_Cap);
3273 canvas->scale(1, 1.2f);
3274 canvas->drawPoint({64, 96}, paint);
3275 canvas->scale(.6f, .8f);
3276 paint.setColor(SK_ColorWHITE);
3277 canvas->drawPoint(106, 120, paint);
3278}
3279##
3280
Cary Clark2ade9972017-11-02 17:49:34 -04003281#SeeAlso drawPoints drawCircle drawRect drawLine drawPath
Cary Clarkbad5ad72017-08-03 17:14:08 -04003282
3283##
3284
Cary Clark8032b982017-07-28 11:04:54 -04003285# ------------------------------------------------------------------------------
3286
3287#Method void drawLine(SkScalar x0, SkScalar y0, SkScalar x1, SkScalar y1, const SkPaint& paint)
3288
Cary Clarkab2621d2018-01-30 10:08:57 -05003289#Line # draws line segment between two points ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003290Draws line segment from (x0, y0) to (x1, y1) using Clip, Matrix, and Paint paint.
3291In paint: Paint_Stroke_Width describes the line thickness;
3292Paint_Stroke_Cap draws the end rounded or square;
Cary Clark8032b982017-07-28 11:04:54 -04003293Paint_Style is ignored, as if were set to SkPaint::kStroke_Style.
3294
Cary Clarkbad5ad72017-08-03 17:14:08 -04003295#Param x0 start of line segment on x-axis ##
3296#Param y0 start of line segment on y-axis ##
3297#Param x1 end of line segment on x-axis ##
3298#Param y1 end of line segment on y-axis ##
3299#Param paint stroke, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003300
3301#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003302 SkPaint paint;
3303 paint.setAntiAlias(true);
3304 paint.setColor(0xFF9a67be);
3305 paint.setStrokeWidth(20);
3306 canvas->skew(1, 0);
3307 canvas->drawLine(32, 96, 32, 160, paint);
3308 canvas->skew(-2, 0);
3309 canvas->drawLine(288, 96, 288, 160, paint);
3310##
3311
Cary Clark2ade9972017-11-02 17:49:34 -04003312#SeeAlso drawPoint drawCircle drawRect drawPath
Cary Clarkbad5ad72017-08-03 17:14:08 -04003313
3314##
3315
3316#Method void drawLine(SkPoint p0, SkPoint p1, const SkPaint& paint)
3317
3318Draws line segment from p0 to p1 using Clip, Matrix, and Paint paint.
3319In paint: Paint_Stroke_Width describes the line thickness;
3320Paint_Stroke_Cap draws the end rounded or square;
3321Paint_Style is ignored, as if were set to SkPaint::kStroke_Style.
3322
3323#Param p0 start of line segment ##
3324#Param p1 end of line segment ##
3325#Param paint stroke, blend, color, and so on, used to draw ##
3326
3327#Example
3328 SkPaint paint;
3329 paint.setAntiAlias(true);
3330 paint.setColor(0xFF9a67be);
3331 paint.setStrokeWidth(20);
3332 canvas->skew(1, 0);
3333 canvas->drawLine({32, 96}, {32, 160}, paint);
3334 canvas->skew(-2, 0);
3335 canvas->drawLine({288, 96}, {288, 160}, paint);
Cary Clark8032b982017-07-28 11:04:54 -04003336##
3337
Cary Clark2ade9972017-11-02 17:49:34 -04003338#SeeAlso drawPoint drawCircle drawRect drawPath
Cary Clark8032b982017-07-28 11:04:54 -04003339
3340##
3341
3342# ------------------------------------------------------------------------------
3343
3344#Method void drawRect(const SkRect& rect, const SkPaint& paint)
3345
Cary Clarkab2621d2018-01-30 10:08:57 -05003346#Line # draws Rect using Clip, Matrix, and Paint ##
Cary Clark8032b982017-07-28 11:04:54 -04003347Draw Rect rect using Clip, Matrix, and Paint paint.
3348In paint: Paint_Style determines if rectangle is stroked or filled;
3349if stroked, Paint_Stroke_Width describes the line thickness, and
3350Paint_Stroke_Join draws the corners rounded or square.
3351
Cary Clarkbc5697d2017-10-04 14:31:33 -04003352#Param rect rectangle to draw ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003353#Param paint stroke or fill, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003354
3355#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003356void draw(SkCanvas* canvas) {
3357 SkPoint rectPts[] = { {64, 48}, {192, 160} };
3358 SkPaint paint;
3359 paint.setAntiAlias(true);
3360 paint.setStyle(SkPaint::kStroke_Style);
3361 paint.setStrokeWidth(20);
3362 paint.setStrokeJoin(SkPaint::kRound_Join);
3363 SkMatrix rotator;
3364 rotator.setRotate(30, 128, 128);
3365 for (auto color : { SK_ColorRED, SK_ColorBLUE, SK_ColorYELLOW, SK_ColorMAGENTA } ) {
3366 paint.setColor(color);
3367 SkRect rect;
3368 rect.set(rectPts[0], rectPts[1]);
3369 canvas->drawRect(rect, paint);
3370 rotator.mapPoints(rectPts, 2);
3371 }
Cary Clark8032b982017-07-28 11:04:54 -04003372}
3373##
3374
Cary Clark2ade9972017-11-02 17:49:34 -04003375#SeeAlso drawIRect drawRRect drawRoundRect drawRegion drawPath drawLine
Cary Clark8032b982017-07-28 11:04:54 -04003376
3377##
3378
3379# ------------------------------------------------------------------------------
3380
3381#Method void drawIRect(const SkIRect& rect, const SkPaint& paint)
3382
Cary Clarkab2621d2018-01-30 10:08:57 -05003383#Line # draws IRect using Clip, Matrix, and Paint ##
Cary Clark8032b982017-07-28 11:04:54 -04003384Draw IRect rect using Clip, Matrix, and Paint paint.
3385In paint: Paint_Style determines if rectangle is stroked or filled;
3386if stroked, Paint_Stroke_Width describes the line thickness, and
3387Paint_Stroke_Join draws the corners rounded or square.
3388
Cary Clarkbc5697d2017-10-04 14:31:33 -04003389#Param rect rectangle to draw ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003390#Param paint stroke or fill, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003391
3392#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003393 SkIRect rect = { 64, 48, 192, 160 };
3394 SkPaint paint;
3395 paint.setAntiAlias(true);
3396 paint.setStyle(SkPaint::kStroke_Style);
3397 paint.setStrokeWidth(20);
3398 paint.setStrokeJoin(SkPaint::kRound_Join);
3399 for (auto color : { SK_ColorRED, SK_ColorBLUE, SK_ColorYELLOW, SK_ColorMAGENTA } ) {
3400 paint.setColor(color);
3401 canvas->drawIRect(rect, paint);
3402 canvas->rotate(30, 128, 128);
3403 }
Cary Clark8032b982017-07-28 11:04:54 -04003404##
3405
Cary Clark2ade9972017-11-02 17:49:34 -04003406#SeeAlso drawRect drawRRect drawRoundRect drawRegion drawPath drawLine
Cary Clark8032b982017-07-28 11:04:54 -04003407
3408##
3409
3410# ------------------------------------------------------------------------------
3411
3412#Method void drawRegion(const SkRegion& region, const SkPaint& paint)
3413
Cary Clarkab2621d2018-01-30 10:08:57 -05003414#Line # draws Region using Clip, Matrix, and Paint ##
Cary Clark8032b982017-07-28 11:04:54 -04003415Draw Region region using Clip, Matrix, and Paint paint.
3416In paint: Paint_Style determines if rectangle is stroked or filled;
3417if stroked, Paint_Stroke_Width describes the line thickness, and
3418Paint_Stroke_Join draws the corners rounded or square.
3419
Cary Clarkbc5697d2017-10-04 14:31:33 -04003420#Param region region to draw ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003421#Param paint Paint stroke or fill, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003422
3423#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003424void draw(SkCanvas* canvas) {
3425 SkRegion region;
3426 region.op( 10, 10, 50, 50, SkRegion::kUnion_Op);
3427 region.op( 10, 50, 90, 90, SkRegion::kUnion_Op);
3428 SkPaint paint;
3429 paint.setAntiAlias(true);
3430 paint.setStyle(SkPaint::kStroke_Style);
3431 paint.setStrokeWidth(20);
3432 paint.setStrokeJoin(SkPaint::kRound_Join);
3433 canvas->drawRegion(region, paint);
Cary Clark8032b982017-07-28 11:04:54 -04003434}
3435##
3436
Cary Clark2ade9972017-11-02 17:49:34 -04003437#SeeAlso drawRect drawIRect drawPath
Cary Clark8032b982017-07-28 11:04:54 -04003438
3439##
3440
3441# ------------------------------------------------------------------------------
3442
3443#Method void drawOval(const SkRect& oval, const SkPaint& paint)
3444
Cary Clarkab2621d2018-01-30 10:08:57 -05003445#Line # draws Oval using Clip, Matrix, and Paint ##
Cary Clark8032b982017-07-28 11:04:54 -04003446Draw Oval oval using Clip, Matrix, and Paint.
3447In paint: Paint_Style determines if Oval is stroked or filled;
3448if stroked, Paint_Stroke_Width describes the line thickness.
3449
Cary Clarkbad5ad72017-08-03 17:14:08 -04003450#Param oval Rect bounds of Oval ##
3451#Param paint Paint stroke or fill, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003452
3453#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003454void draw(SkCanvas* canvas) {
3455 canvas->clear(0xFF3f5f9f);
3456 SkColor kColor1 = SkColorSetARGB(0xff, 0xff, 0x7f, 0);
3457 SkColor g1Colors[] = { kColor1, SkColorSetA(kColor1, 0x20) };
3458 SkPoint g1Points[] = { { 0, 0 }, { 0, 100 } };
3459 SkScalar pos[] = { 0.2f, 1.0f };
3460 SkRect bounds = SkRect::MakeWH(80, 70);
3461 SkPaint paint;
3462 paint.setAntiAlias(true);
3463 paint.setShader(SkGradientShader::MakeLinear(g1Points, g1Colors, pos, SK_ARRAY_COUNT(g1Colors),
3464 SkShader::kClamp_TileMode));
3465 canvas->drawOval(bounds , paint);
Cary Clark8032b982017-07-28 11:04:54 -04003466}
3467##
3468
Cary Clark2ade9972017-11-02 17:49:34 -04003469#SeeAlso drawCircle drawPoint drawPath drawRRect drawRoundRect
Cary Clark8032b982017-07-28 11:04:54 -04003470
3471##
3472
3473# ------------------------------------------------------------------------------
3474
3475#Method void drawRRect(const SkRRect& rrect, const SkPaint& paint)
3476
Cary Clarkab2621d2018-01-30 10:08:57 -05003477#Line # draws Round_Rect using Clip, Matrix, and Paint ##
Cary Clark8032b982017-07-28 11:04:54 -04003478Draw Round_Rect rrect using Clip, Matrix, and Paint paint.
3479In paint: Paint_Style determines if rrect is stroked or filled;
3480if stroked, Paint_Stroke_Width describes the line thickness.
3481
Cary Clarkbad5ad72017-08-03 17:14:08 -04003482rrect may represent a rectangle, circle, oval, uniformly rounded rectangle, or
3483may have any combination of positive non-square radii for the four corners.
Cary Clark8032b982017-07-28 11:04:54 -04003484
Cary Clarkbad5ad72017-08-03 17:14:08 -04003485#Param rrect Round_Rect with up to eight corner radii to draw ##
3486#Param paint Paint stroke or fill, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003487
3488#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003489void draw(SkCanvas* canvas) {
3490 SkPaint paint;
3491 paint.setAntiAlias(true);
3492 SkRect outer = {30, 40, 210, 220};
3493 SkRect radii = {30, 50, 70, 90 };
3494 SkRRect rRect;
3495 rRect.setNinePatch(outer, radii.fLeft, radii.fTop, radii.fRight, radii.fBottom);
3496 canvas->drawRRect(rRect, paint);
3497 paint.setColor(SK_ColorWHITE);
3498 canvas->drawLine(outer.fLeft + radii.fLeft, outer.fTop,
3499 outer.fLeft + radii.fLeft, outer.fBottom, paint);
3500 canvas->drawLine(outer.fRight - radii.fRight, outer.fTop,
3501 outer.fRight - radii.fRight, outer.fBottom, paint);
3502 canvas->drawLine(outer.fLeft, outer.fTop + radii.fTop,
3503 outer.fRight, outer.fTop + radii.fTop, paint);
3504 canvas->drawLine(outer.fLeft, outer.fBottom - radii.fBottom,
3505 outer.fRight, outer.fBottom - radii.fBottom, paint);
3506}
Cary Clark8032b982017-07-28 11:04:54 -04003507##
3508
Cary Clark2ade9972017-11-02 17:49:34 -04003509#SeeAlso drawRect drawRoundRect drawDRRect drawCircle drawOval drawPath
Cary Clark8032b982017-07-28 11:04:54 -04003510
3511##
3512
3513# ------------------------------------------------------------------------------
3514
3515#Method void drawDRRect(const SkRRect& outer, const SkRRect& inner, const SkPaint& paint)
3516
Cary Clarkab2621d2018-01-30 10:08:57 -05003517#Line # draws double Round_Rect stroked or filled ##
Cary Clark8032b982017-07-28 11:04:54 -04003518Draw Round_Rect outer and inner
3519using Clip, Matrix, and Paint paint.
3520outer must contain inner or the drawing is undefined.
Cary Clarkce101242017-09-01 15:51:02 -04003521In paint: Paint_Style determines if Round_Rect is stroked or filled;
Cary Clark8032b982017-07-28 11:04:54 -04003522if stroked, Paint_Stroke_Width describes the line thickness.
Cary Clarkbad5ad72017-08-03 17:14:08 -04003523If stroked and Round_Rect corner has zero length radii, Paint_Stroke_Join can
3524draw corners rounded or square.
Cary Clark8032b982017-07-28 11:04:54 -04003525
Cary Clarkbad5ad72017-08-03 17:14:08 -04003526GPU-backed platforms optimize drawing when both outer and inner are
Cary Clark8032b982017-07-28 11:04:54 -04003527concave and outer contains inner. These platforms may not be able to draw
3528Path built with identical data as fast.
3529
Cary Clarkbad5ad72017-08-03 17:14:08 -04003530#Param outer Round_Rect outer bounds to draw ##
3531#Param inner Round_Rect inner bounds to draw ##
3532#Param paint Paint stroke or fill, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003533
3534#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003535void draw(SkCanvas* canvas) {
3536 SkRRect outer = SkRRect::MakeRect({20, 40, 210, 200});
3537 SkRRect inner = SkRRect::MakeOval({60, 70, 170, 160});
3538 SkPaint paint;
3539 canvas->drawDRRect(outer, inner, paint);
Cary Clark8032b982017-07-28 11:04:54 -04003540}
3541##
3542
3543#Example
3544#Description
3545 Outer Rect has no corner radii, but stroke join is rounded.
3546 Inner Round_Rect has corner radii; outset stroke increases radii of corners.
3547 Stroke join does not affect inner Round_Rect since it has no sharp corners.
3548##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003549void draw(SkCanvas* canvas) {
3550 SkRRect outer = SkRRect::MakeRect({20, 40, 210, 200});
3551 SkRRect inner = SkRRect::MakeRectXY({60, 70, 170, 160}, 10, 10);
3552 SkPaint paint;
3553 paint.setAntiAlias(true);
3554 paint.setStyle(SkPaint::kStroke_Style);
3555 paint.setStrokeWidth(20);
3556 paint.setStrokeJoin(SkPaint::kRound_Join);
3557 canvas->drawDRRect(outer, inner, paint);
3558 paint.setStrokeWidth(1);
3559 paint.setColor(SK_ColorWHITE);
3560 canvas->drawDRRect(outer, inner, paint);
Cary Clark8032b982017-07-28 11:04:54 -04003561}
3562##
3563
Cary Clark2ade9972017-11-02 17:49:34 -04003564#SeeAlso drawRect drawRoundRect drawRRect drawCircle drawOval drawPath
Cary Clark8032b982017-07-28 11:04:54 -04003565
3566##
3567
3568# ------------------------------------------------------------------------------
3569
3570#Method void drawCircle(SkScalar cx, SkScalar cy, SkScalar radius, const SkPaint& paint)
3571
Cary Clarkab2621d2018-01-30 10:08:57 -05003572#Line # draws Circle using Clip, Matrix, and Paint ##
Cary Clark8032b982017-07-28 11:04:54 -04003573Draw Circle at (cx, cy) with radius using Clip, Matrix, and Paint paint.
3574If radius is zero or less, nothing is drawn.
3575In paint: Paint_Style determines if Circle is stroked or filled;
3576if stroked, Paint_Stroke_Width describes the line thickness.
3577
Cary Clarkbad5ad72017-08-03 17:14:08 -04003578#Param cx Circle center on the x-axis ##
3579#Param cy Circle center on the y-axis ##
3580#Param radius half the diameter of Circle ##
3581#Param paint Paint stroke or fill, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003582
3583#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003584 void draw(SkCanvas* canvas) {
3585 SkPaint paint;
3586 paint.setAntiAlias(true);
3587 canvas->drawCircle(128, 128, 90, paint);
3588 paint.setColor(SK_ColorWHITE);
3589 canvas->drawCircle(86, 86, 20, paint);
3590 canvas->drawCircle(160, 76, 20, paint);
3591 canvas->drawCircle(140, 150, 35, paint);
3592 }
3593##
3594
Cary Clark2ade9972017-11-02 17:49:34 -04003595#SeeAlso drawOval drawRRect drawRoundRect drawPath drawArc drawPoint drawLine
Cary Clarkbad5ad72017-08-03 17:14:08 -04003596
3597##
3598
3599#Method void drawCircle(SkPoint center, SkScalar radius, const SkPaint& paint)
3600
Cary Clarkce101242017-09-01 15:51:02 -04003601Draw Circle at center with radius using Clip, Matrix, and Paint paint.
Cary Clarkbad5ad72017-08-03 17:14:08 -04003602If radius is zero or less, nothing is drawn.
3603In paint: Paint_Style determines if Circle is stroked or filled;
3604if stroked, Paint_Stroke_Width describes the line thickness.
3605
3606#Param center Circle center ##
3607#Param radius half the diameter of Circle ##
3608#Param paint Paint stroke or fill, blend, color, and so on, used to draw ##
3609
3610#Example
3611 void draw(SkCanvas* canvas) {
3612 SkPaint paint;
3613 paint.setAntiAlias(true);
3614 canvas->drawCircle(128, 128, 90, paint);
3615 paint.setColor(SK_ColorWHITE);
3616 canvas->drawCircle({86, 86}, 20, paint);
3617 canvas->drawCircle({160, 76}, 20, paint);
3618 canvas->drawCircle({140, 150}, 35, paint);
3619 }
Cary Clark8032b982017-07-28 11:04:54 -04003620##
3621
Cary Clark2ade9972017-11-02 17:49:34 -04003622#SeeAlso drawOval drawRRect drawRoundRect drawPath drawArc drawPoint drawLine
Cary Clark8032b982017-07-28 11:04:54 -04003623
3624##
3625
3626# ------------------------------------------------------------------------------
3627
3628#Method void drawArc(const SkRect& oval, SkScalar startAngle, SkScalar sweepAngle,
3629 bool useCenter, const SkPaint& paint)
Cary Clarkab2621d2018-01-30 10:08:57 -05003630#Line # draws Arc using Clip, Matrix, and Paint ##
Cary Clark8032b982017-07-28 11:04:54 -04003631
3632Draw Arc using Clip, Matrix, and Paint paint.
Cary Clarkbad5ad72017-08-03 17:14:08 -04003633
Cary Clark8032b982017-07-28 11:04:54 -04003634Arc is part of Oval bounded by oval, sweeping from startAngle to startAngle plus
3635sweepAngle. startAngle and sweepAngle are in degrees.
Cary Clarkbad5ad72017-08-03 17:14:08 -04003636
Cary Clark8032b982017-07-28 11:04:54 -04003637startAngle of zero places start point at the right middle edge of oval.
3638A positive sweepAngle places Arc end point clockwise from start point;
3639a negative sweepAngle places Arc end point counterclockwise from start point.
3640sweepAngle may exceed 360 degrees, a full circle.
3641If useCenter is true, draw a wedge that includes lines from oval
3642center to Arc end points. If useCenter is false, draw Arc between end points.
3643
3644If Rect oval is empty or sweepAngle is zero, nothing is drawn.
3645
Cary Clarkbad5ad72017-08-03 17:14:08 -04003646#Param oval Rect bounds of Oval containing Arc to draw ##
3647#Param startAngle angle in degrees where Arc begins ##
3648#Param sweepAngle sweep angle in degrees; positive is clockwise ##
3649#Param useCenter if true, include the center of the oval ##
3650#Param paint Paint stroke or fill, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003651
3652#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003653 void draw(SkCanvas* canvas) {
3654 SkPaint paint;
3655 paint.setAntiAlias(true);
3656 SkRect oval = { 4, 4, 60, 60};
3657 for (auto useCenter : { false, true } ) {
3658 for (auto style : { SkPaint::kFill_Style, SkPaint::kStroke_Style } ) {
3659 paint.setStyle(style);
3660 for (auto degrees : { 45, 90, 180, 360} ) {
3661 canvas->drawArc(oval, 0, degrees , useCenter, paint);
3662 canvas->translate(64, 0);
3663 }
3664 canvas->translate(-256, 64);
3665 }
3666 }
Cary Clark8032b982017-07-28 11:04:54 -04003667 }
3668##
3669
3670#Example
3671#Height 64
Cary Clarkbad5ad72017-08-03 17:14:08 -04003672 void draw(SkCanvas* canvas) {
3673 SkPaint paint;
3674 paint.setAntiAlias(true);
3675 paint.setStyle(SkPaint::kStroke_Style);
3676 paint.setStrokeWidth(4);
3677 SkRect oval = { 4, 4, 60, 60};
3678 float intervals[] = { 5, 5 };
3679 paint.setPathEffect(SkDashPathEffect::Make(intervals, 2, 2.5f));
3680 for (auto degrees : { 270, 360, 540, 720 } ) {
3681 canvas->drawArc(oval, 0, degrees, false, paint);
3682 canvas->translate(64, 0);
3683 }
Cary Clark8032b982017-07-28 11:04:54 -04003684 }
3685##
3686
Cary Clark2ade9972017-11-02 17:49:34 -04003687#SeeAlso SkPath::arcTo drawCircle drawOval drawPath
Cary Clark8032b982017-07-28 11:04:54 -04003688
3689##
3690
3691# ------------------------------------------------------------------------------
3692
3693#Method void drawRoundRect(const SkRect& rect, SkScalar rx, SkScalar ry, const SkPaint& paint)
3694
Cary Clarkab2621d2018-01-30 10:08:57 -05003695#Line # draws Round_Rect using Clip, Matrix, and Paint ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003696Draw Round_Rect bounded by Rect rect, with corner radii (rx, ry) using Clip,
3697Matrix, and Paint paint.
3698
Cary Clark8032b982017-07-28 11:04:54 -04003699In paint: Paint_Style determines if Round_Rect is stroked or filled;
3700if stroked, Paint_Stroke_Width describes the line thickness.
3701If rx or ry are less than zero, they are treated as if they are zero.
3702If rx plus ry exceeds rect width or rect height, radii are scaled down to fit.
Cary Clarkbad5ad72017-08-03 17:14:08 -04003703If rx and ry are zero, Round_Rect is drawn as Rect and if stroked is affected by
3704Paint_Stroke_Join.
Cary Clark8032b982017-07-28 11:04:54 -04003705
Cary Clarkbad5ad72017-08-03 17:14:08 -04003706#Param rect Rect bounds of Round_Rect to draw ##
Cary Clarkce101242017-09-01 15:51:02 -04003707#Param rx axis length in x of oval describing rounded corners ##
3708#Param ry axis length in y of oval describing rounded corners ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003709#Param paint stroke, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003710
3711#Example
3712#Description
3713 Top row has a zero radius a generates a rectangle.
3714 Second row radii sum to less than sides.
3715 Third row radii sum equals sides.
3716 Fourth row radii sum exceeds sides; radii are scaled to fit.
3717##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003718 void draw(SkCanvas* canvas) {
3719 SkVector radii[] = { {0, 20}, {10, 10}, {10, 20}, {10, 40} };
3720 SkPaint paint;
3721 paint.setStrokeWidth(15);
3722 paint.setStrokeJoin(SkPaint::kRound_Join);
3723 paint.setAntiAlias(true);
3724 for (auto style : { SkPaint::kStroke_Style, SkPaint::kFill_Style } ) {
3725 paint.setStyle(style );
3726 for (size_t i = 0; i < SK_ARRAY_COUNT(radii); ++i) {
3727 canvas->drawRoundRect({10, 10, 60, 40}, radii[i].fX, radii[i].fY, paint);
3728 canvas->translate(0, 60);
3729 }
3730 canvas->translate(80, -240);
3731 }
Cary Clark8032b982017-07-28 11:04:54 -04003732 }
3733##
3734
Cary Clark2ade9972017-11-02 17:49:34 -04003735#SeeAlso DrawRRect drawRect drawDRRect drawPath drawCircle drawOval drawPoint
Cary Clark8032b982017-07-28 11:04:54 -04003736
3737##
3738
3739# ------------------------------------------------------------------------------
3740
3741#Method void drawPath(const SkPath& path, const SkPaint& paint)
3742
Cary Clarkab2621d2018-01-30 10:08:57 -05003743#Line # draws Path using Clip, Matrix, and Paint ##
Cary Clark8032b982017-07-28 11:04:54 -04003744Draw Path path using Clip, Matrix, and Paint paint.
3745Path contains an array of Path_Contour, each of which may be open or closed.
3746
3747In paint: Paint_Style determines if Round_Rect is stroked or filled:
Cary Clarkbad5ad72017-08-03 17:14:08 -04003748if filled, Path_Fill_Type determines whether Path_Contour describes inside or
3749outside of fill; if stroked, Paint_Stroke_Width describes the line thickness,
3750Paint_Stroke_Cap describes line ends, and Paint_Stroke_Join describes how
3751corners are drawn.
Cary Clark8032b982017-07-28 11:04:54 -04003752
Cary Clarkbad5ad72017-08-03 17:14:08 -04003753#Param path Path to draw ##
3754#Param paint stroke, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003755
3756#Example
3757#Description
3758 Top rows draw stroked path with combinations of joins and caps. The open contour
3759 is affected by caps; the closed contour is affected by joins.
3760 Bottom row draws fill the same for open and closed contour.
3761 First bottom column shows winding fills overlap.
3762 Second bottom column shows even odd fills exclude overlap.
3763 Third bottom column shows inverse winding fills area outside both contours.
3764##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003765void draw(SkCanvas* canvas) {
3766 SkPath path;
3767 path.moveTo(20, 20);
3768 path.quadTo(60, 20, 60, 60);
3769 path.close();
3770 path.moveTo(60, 20);
3771 path.quadTo(60, 60, 20, 60);
3772 SkPaint paint;
3773 paint.setStrokeWidth(10);
3774 paint.setAntiAlias(true);
3775 paint.setStyle(SkPaint::kStroke_Style);
3776 for (auto join: { SkPaint::kBevel_Join, SkPaint::kRound_Join, SkPaint::kMiter_Join } ) {
3777 paint.setStrokeJoin(join);
3778 for (auto cap: { SkPaint::kButt_Cap, SkPaint::kSquare_Cap, SkPaint::kRound_Cap } ) {
3779 paint.setStrokeCap(cap);
3780 canvas->drawPath(path, paint);
3781 canvas->translate(80, 0);
3782 }
3783 canvas->translate(-240, 60);
3784 }
3785 paint.setStyle(SkPaint::kFill_Style);
3786 for (auto fill : { SkPath::kWinding_FillType,
3787 SkPath::kEvenOdd_FillType,
3788 SkPath::kInverseWinding_FillType } ) {
3789 path.setFillType(fill);
3790 canvas->save();
3791 canvas->clipRect({0, 10, 80, 70});
3792 canvas->drawPath(path, paint);
3793 canvas->restore();
3794 canvas->translate(80, 0);
3795 }
Cary Clark8032b982017-07-28 11:04:54 -04003796}
3797##
3798
Cary Clark2ade9972017-11-02 17:49:34 -04003799#SeeAlso SkPath drawLine drawArc drawRect drawPoints
Cary Clark8032b982017-07-28 11:04:54 -04003800
3801##
3802
3803# ------------------------------------------------------------------------------
Cary Clark08895c42018-02-01 09:37:32 -05003804#Subtopic Draw_Image
3805#Line # draws Image to Canvas ##
Cary Clark8032b982017-07-28 11:04:54 -04003806
Cary Clarkbad5ad72017-08-03 17:14:08 -04003807drawImage, drawImageRect, and drawImageNine can be called with a bare pointer or
3808a smart pointer as a convenience. The pairs of calls are otherwise identical.
Cary Clark8032b982017-07-28 11:04:54 -04003809
Cary Clark73fa9722017-08-29 17:36:51 -04003810#Method void drawImage(const SkImage* image, SkScalar left, SkScalar top, const SkPaint* paint = nullptr)
Cary Clark8032b982017-07-28 11:04:54 -04003811
Cary Clarkab2621d2018-01-30 10:08:57 -05003812#In Draw_Image
3813#Line # draws Image at (x, y) position ##
Cary Clark8032b982017-07-28 11:04:54 -04003814Draw Image image, with its top-left corner at (left, top),
3815using Clip, Matrix, and optional Paint paint.
3816
Cary Clarkbad5ad72017-08-03 17:14:08 -04003817If paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter, Blend_Mode,
3818and Draw_Looper. If image is kAlpha_8_SkColorType, apply Shader.
3819If paint contains Mask_Filter, generate mask from image bounds. If generated
3820mask extends beyond image bounds, replicate image edge colors, just as Shader
3821made from SkImage::makeShader with SkShader::kClamp_TileMode set replicates the
Cary Clarkbc5697d2017-10-04 14:31:33 -04003822image edge color when it samples outside of its bounds.
Cary Clark8032b982017-07-28 11:04:54 -04003823
Cary Clarkbad5ad72017-08-03 17:14:08 -04003824#Param image uncompressed rectangular map of pixels ##
3825#Param left left side of image ##
3826#Param top top side of image ##
3827#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
3828 and so on; or nullptr
3829##
Cary Clark8032b982017-07-28 11:04:54 -04003830
3831#Example
3832#Height 64
3833#Image 4
Cary Clarkbad5ad72017-08-03 17:14:08 -04003834void draw(SkCanvas* canvas) {
3835 // sk_sp<SkImage> image;
3836 SkImage* imagePtr = image.get();
3837 canvas->drawImage(imagePtr, 0, 0);
3838 SkPaint paint;
3839 canvas->drawImage(imagePtr, 80, 0, &paint);
3840 paint.setAlpha(0x80);
3841 canvas->drawImage(imagePtr, 160, 0, &paint);
Cary Clark8032b982017-07-28 11:04:54 -04003842}
3843##
3844
Cary Clark2ade9972017-11-02 17:49:34 -04003845#SeeAlso drawBitmap drawImageLattice drawImageNine drawImageRect SkPaint::setImageFilter
Cary Clark8032b982017-07-28 11:04:54 -04003846
3847##
3848
3849# ------------------------------------------------------------------------------
3850
3851#Method void drawImage(const sk_sp<SkImage>& image, SkScalar left, SkScalar top,
Cary Clark73fa9722017-08-29 17:36:51 -04003852 const SkPaint* paint = nullptr)
Cary Clarkab2621d2018-01-30 10:08:57 -05003853#In Draw_Image
Cary Clark8032b982017-07-28 11:04:54 -04003854
3855Draw Image image, with its top-left corner at (left, top),
3856using Clip, Matrix, and optional Paint paint.
3857
Cary Clarkbad5ad72017-08-03 17:14:08 -04003858If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
3859Blend_Mode, and Draw_Looper. If image is kAlpha_8_SkColorType, apply Shader.
3860If paint contains Mask_Filter, generate mask from image bounds. If generated
3861mask extends beyond image bounds, replicate image edge colors, just as Shader
3862made from SkImage::makeShader with SkShader::kClamp_TileMode set replicates the
Cary Clarkbc5697d2017-10-04 14:31:33 -04003863image edge color when it samples outside of its bounds.
Cary Clark8032b982017-07-28 11:04:54 -04003864
Cary Clarkbad5ad72017-08-03 17:14:08 -04003865#Param image uncompressed rectangular map of pixels ##
3866#Param left left side of image ##
3867#Param top pop side of image ##
3868#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
3869 and so on; or nullptr
3870##
Cary Clark8032b982017-07-28 11:04:54 -04003871
3872#Example
3873#Height 64
3874#Image 4
Cary Clarkbad5ad72017-08-03 17:14:08 -04003875void draw(SkCanvas* canvas) {
3876 // sk_sp<SkImage> image;
3877 canvas->drawImage(image, 0, 0);
3878 SkPaint paint;
3879 canvas->drawImage(image, 80, 0, &paint);
3880 paint.setAlpha(0x80);
3881 canvas->drawImage(image, 160, 0, &paint);
Cary Clark8032b982017-07-28 11:04:54 -04003882}
3883##
3884
Cary Clark2ade9972017-11-02 17:49:34 -04003885#SeeAlso drawBitmap drawImageLattice drawImageNine drawImageRect SkPaint::setImageFilter
Cary Clark8032b982017-07-28 11:04:54 -04003886
3887##
3888
3889# ------------------------------------------------------------------------------
3890
3891#Enum SrcRectConstraint
Cary Clark08895c42018-02-01 09:37:32 -05003892#Line # sets drawImageRect options ##
Cary Clark8032b982017-07-28 11:04:54 -04003893
3894#Code
3895 enum SrcRectConstraint {
3896 kStrict_SrcRectConstraint,
3897 kFast_SrcRectConstraint,
3898 };
3899##
3900
Cary Clarkce101242017-09-01 15:51:02 -04003901SrcRectConstraint controls the behavior at the edge of source Rect,
3902provided to drawImageRect, trading off speed for precision.
Cary Clark8032b982017-07-28 11:04:54 -04003903
Cary Clarkce101242017-09-01 15:51:02 -04003904Image_Filter in Paint may sample multiple pixels in the image. Source Rect
Cary Clarkbad5ad72017-08-03 17:14:08 -04003905restricts the bounds of pixels that may be read. Image_Filter may slow down if
Cary Clarkce101242017-09-01 15:51:02 -04003906it cannot read outside the bounds, when sampling near the edge of source Rect.
Cary Clark8032b982017-07-28 11:04:54 -04003907SrcRectConstraint specifies whether an Image_Filter is allowed to read pixels
Cary Clarkce101242017-09-01 15:51:02 -04003908outside source Rect.
Cary Clark8032b982017-07-28 11:04:54 -04003909
3910#Const kStrict_SrcRectConstraint
Cary Clarkce101242017-09-01 15:51:02 -04003911 Requires Image_Filter to respect source Rect,
Cary Clark8032b982017-07-28 11:04:54 -04003912 sampling only inside of its bounds, possibly with a performance penalty.
3913##
3914
3915#Const kFast_SrcRectConstraint
Cary Clarkce101242017-09-01 15:51:02 -04003916 Permits Image_Filter to sample outside of source Rect
Cary Clark8032b982017-07-28 11:04:54 -04003917 by half the width of Image_Filter, permitting it to run faster but with
3918 error at the image edges.
3919##
3920
3921#Example
3922#Height 64
3923#Description
3924 redBorder contains a black and white checkerboard bordered by red.
3925 redBorder is drawn scaled by 16 on the left.
Cary Clarkce101242017-09-01 15:51:02 -04003926 The middle and right bitmaps are filtered checkerboards.
Cary Clark8032b982017-07-28 11:04:54 -04003927 Drawing the checkerboard with kStrict_SrcRectConstraint shows only a blur of black and white.
3928 Drawing the checkerboard with kFast_SrcRectConstraint allows red to bleed in the corners.
3929##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003930void draw(SkCanvas* canvas) {
3931 SkBitmap redBorder;
3932 redBorder.allocPixels(SkImageInfo::MakeN32Premul(4, 4));
3933 SkCanvas checkRed(redBorder);
3934 checkRed.clear(SK_ColorRED);
3935 uint32_t checkers[][2] = { { SK_ColorBLACK, SK_ColorWHITE },
3936 { SK_ColorWHITE, SK_ColorBLACK } };
3937 checkRed.writePixels(
3938 SkImageInfo::MakeN32Premul(2, 2), (void*) checkers, sizeof(checkers[0]), 1, 1);
3939 canvas->scale(16, 16);
3940 canvas->drawBitmap(redBorder, 0, 0, nullptr);
3941 canvas->resetMatrix();
3942 sk_sp<SkImage> image = SkImage::MakeFromBitmap(redBorder);
3943 SkPaint lowPaint;
3944 lowPaint.setFilterQuality(kLow_SkFilterQuality);
3945 for (auto constraint : { SkCanvas::kStrict_SrcRectConstraint,
3946 SkCanvas::kFast_SrcRectConstraint } ) {
3947 canvas->translate(80, 0);
3948 canvas->drawImageRect(image.get(), SkRect::MakeLTRB(1, 1, 3, 3),
3949 SkRect::MakeLTRB(16, 16, 48, 48), &lowPaint, constraint);
3950 }
Cary Clark8032b982017-07-28 11:04:54 -04003951}
3952##
3953
Cary Clark2ade9972017-11-02 17:49:34 -04003954#SeeAlso drawImageRect drawImage SkPaint::setImageFilter
Cary Clark8032b982017-07-28 11:04:54 -04003955
3956##
3957
3958# ------------------------------------------------------------------------------
3959
3960#Method void drawImageRect(const SkImage* image, const SkRect& src, const SkRect& dst,
3961 const SkPaint* paint,
3962 SrcRectConstraint constraint = kStrict_SrcRectConstraint)
Cary Clarkab2621d2018-01-30 10:08:57 -05003963#In Draw_Image
3964#Line # draws Image, source Rect to destination Rect ##
Cary Clark8032b982017-07-28 11:04:54 -04003965
3966Draw Rect src of Image image, scaled and translated to fill Rect dst.
3967Additionally transform draw using Clip, Matrix, and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04003968
Cary Clarkbad5ad72017-08-03 17:14:08 -04003969If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
3970Blend_Mode, and Draw_Looper. If image is kAlpha_8_SkColorType, apply Shader.
3971If paint contains Mask_Filter, generate mask from image bounds.
3972
3973If generated mask extends beyond image bounds, replicate image edge colors, just
3974as Shader made from SkImage::makeShader with SkShader::kClamp_TileMode set
Cary Clarkbc5697d2017-10-04 14:31:33 -04003975replicates the image edge color when it samples outside of its bounds.
Cary Clarkbad5ad72017-08-03 17:14:08 -04003976
3977constraint set to kStrict_SrcRectConstraint limits Paint Filter_Quality to
3978sample within src; set to kFast_SrcRectConstraint allows sampling outside to
3979improve performance.
3980
3981#Param image Image containing pixels, dimensions, and format ##
3982#Param src source Rect of image to draw from ##
3983#Param dst destination Rect of image to draw to ##
3984#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
3985 and so on; or nullptr
3986##
3987#Param constraint filter strictly within src or draw faster ##
Cary Clark8032b982017-07-28 11:04:54 -04003988
3989#Example
3990#Height 64
3991#Description
3992 The left bitmap draws with Paint default kNone_SkFilterQuality, and stays within
Cary Clarkbc5697d2017-10-04 14:31:33 -04003993 its bounds; there is no bleeding with kFast_SrcRectConstraint.
Cary Clark8032b982017-07-28 11:04:54 -04003994 the middle and right bitmaps draw with kLow_SkFilterQuality; with
3995 kStrict_SrcRectConstraint, the filter remains within the checkerboard, and
3996 with kFast_SrcRectConstraint red bleeds on the edges.
3997##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003998void draw(SkCanvas* canvas) {
3999 uint32_t pixels[][4] = {
4000 { 0xFFFF0000, 0xFFFF0000, 0xFFFF0000, 0xFFFF0000 },
4001 { 0xFFFF0000, 0xFF000000, 0xFFFFFFFF, 0xFFFF0000 },
4002 { 0xFFFF0000, 0xFFFFFFFF, 0xFF000000, 0xFFFF0000 },
4003 { 0xFFFF0000, 0xFFFF0000, 0xFFFF0000, 0xFFFF0000 } };
4004 SkBitmap redBorder;
4005 redBorder.installPixels(SkImageInfo::MakeN32Premul(4, 4),
4006 (void*) pixels, sizeof(pixels[0]));
4007 sk_sp<SkImage> image = SkImage::MakeFromBitmap(redBorder);
4008 SkPaint lowPaint;
4009 for (auto constraint : {
4010 SkCanvas::kFast_SrcRectConstraint,
4011 SkCanvas::kStrict_SrcRectConstraint,
4012 SkCanvas::kFast_SrcRectConstraint } ) {
4013 canvas->drawImageRect(image.get(), SkRect::MakeLTRB(1, 1, 3, 3),
4014 SkRect::MakeLTRB(16, 16, 48, 48), &lowPaint, constraint);
4015 lowPaint.setFilterQuality(kLow_SkFilterQuality);
4016 canvas->translate(80, 0);
4017 }
4018}
Cary Clark8032b982017-07-28 11:04:54 -04004019##
4020
Cary Clark2ade9972017-11-02 17:49:34 -04004021#SeeAlso SrcRectConstraint drawImage drawImageLattice drawImageNine
Cary Clark8032b982017-07-28 11:04:54 -04004022
4023##
4024
4025# ------------------------------------------------------------------------------
4026
4027#Method void drawImageRect(const SkImage* image, const SkIRect& isrc, const SkRect& dst,
4028 const SkPaint* paint, SrcRectConstraint constraint = kStrict_SrcRectConstraint)
Cary Clarkab2621d2018-01-30 10:08:57 -05004029#In Draw_Image
Cary Clark8032b982017-07-28 11:04:54 -04004030
4031Draw IRect isrc of Image image, scaled and translated to fill Rect dst.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004032Note that isrc is on integer pixel boundaries; dst may include fractional
4033boundaries. Additionally transform draw using Clip, Matrix, and optional Paint
4034paint.
Cary Clark8032b982017-07-28 11:04:54 -04004035
Cary Clarkbad5ad72017-08-03 17:14:08 -04004036If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4037Blend_Mode, and Draw_Looper. If image is kAlpha_8_SkColorType, apply Shader.
4038If paint contains Mask_Filter, generate mask from image bounds.
4039
4040If generated mask extends beyond image bounds, replicate image edge colors, just
4041as Shader made from SkImage::makeShader with SkShader::kClamp_TileMode set
Cary Clarkbc5697d2017-10-04 14:31:33 -04004042replicates the image edge color when it samples outside of its bounds.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004043
4044constraint set to kStrict_SrcRectConstraint limits Paint Filter_Quality to
Cary Clarkce101242017-09-01 15:51:02 -04004045sample within isrc; set to kFast_SrcRectConstraint allows sampling outside to
Cary Clarkbad5ad72017-08-03 17:14:08 -04004046improve performance.
4047
4048#Param image Image containing pixels, dimensions, and format ##
4049#Param isrc source IRect of image to draw from ##
4050#Param dst destination Rect of image to draw to ##
4051#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4052 and so on; or nullptr
4053##
Cary Clarkce101242017-09-01 15:51:02 -04004054#Param constraint filter strictly within isrc or draw faster ##
Cary Clark8032b982017-07-28 11:04:54 -04004055
4056#Example
4057#Image 4
Cary Clarkbad5ad72017-08-03 17:14:08 -04004058void draw(SkCanvas* canvas) {
4059 // sk_sp<SkImage> image;
4060 for (auto i : { 1, 2, 4, 8 } ) {
4061 canvas->drawImageRect(image.get(), SkIRect::MakeLTRB(0, 0, 100, 100),
4062 SkRect::MakeXYWH(i * 20, i * 20, i * 20, i * 20), nullptr);
4063 }
Cary Clark8032b982017-07-28 11:04:54 -04004064}
4065##
4066
Cary Clark2ade9972017-11-02 17:49:34 -04004067#SeeAlso SrcRectConstraint drawImage drawImageLattice drawImageNine
Cary Clark8032b982017-07-28 11:04:54 -04004068
4069##
4070
4071# ------------------------------------------------------------------------------
4072
4073#Method void drawImageRect(const SkImage* image, const SkRect& dst, const SkPaint* paint,
4074 SrcRectConstraint constraint = kStrict_SrcRectConstraint)
Cary Clarkab2621d2018-01-30 10:08:57 -05004075#In Draw_Image
Cary Clark8032b982017-07-28 11:04:54 -04004076
Cary Clarkbad5ad72017-08-03 17:14:08 -04004077Draw Image image, scaled and translated to fill Rect dst, using Clip, Matrix,
4078and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004079
Cary Clarkbad5ad72017-08-03 17:14:08 -04004080If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4081Blend_Mode, and Draw_Looper. If image is kAlpha_8_SkColorType, apply Shader.
4082If paint contains Mask_Filter, generate mask from image bounds.
4083
4084If generated mask extends beyond image bounds, replicate image edge colors, just
4085as Shader made from SkImage::makeShader with SkShader::kClamp_TileMode set
Cary Clarkbc5697d2017-10-04 14:31:33 -04004086replicates the image edge color when it samples outside of its bounds.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004087
4088constraint set to kStrict_SrcRectConstraint limits Paint Filter_Quality to
Cary Clarkce101242017-09-01 15:51:02 -04004089sample within image; set to kFast_SrcRectConstraint allows sampling outside to
Cary Clarkbad5ad72017-08-03 17:14:08 -04004090improve performance.
4091
4092#Param image Image containing pixels, dimensions, and format ##
4093#Param dst destination Rect of image to draw to ##
4094#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4095 and so on; or nullptr
4096##
Cary Clarkce101242017-09-01 15:51:02 -04004097#Param constraint filter strictly within image or draw faster ##
Cary Clark8032b982017-07-28 11:04:54 -04004098
4099#Example
4100#Image 4
Cary Clarkbad5ad72017-08-03 17:14:08 -04004101void draw(SkCanvas* canvas) {
4102 // sk_sp<SkImage> image;
4103 for (auto i : { 20, 40, 80, 160 } ) {
4104 canvas->drawImageRect(image.get(), SkRect::MakeXYWH(i, i, i, i), nullptr);
4105 }
Cary Clark8032b982017-07-28 11:04:54 -04004106}
4107##
4108
Cary Clark2ade9972017-11-02 17:49:34 -04004109#SeeAlso SrcRectConstraint drawImage drawImageLattice drawImageNine
Cary Clark8032b982017-07-28 11:04:54 -04004110
4111##
4112
4113# ------------------------------------------------------------------------------
4114
4115#Method void drawImageRect(const sk_sp<SkImage>& image, const SkRect& src, const SkRect& dst,
4116 const SkPaint* paint,
4117 SrcRectConstraint constraint = kStrict_SrcRectConstraint)
Cary Clarkab2621d2018-01-30 10:08:57 -05004118#In Draw_Image
Cary Clark8032b982017-07-28 11:04:54 -04004119
4120Draw Rect src of Image image, scaled and translated to fill Rect dst.
4121Additionally transform draw using Clip, Matrix, and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004122
Cary Clarkbad5ad72017-08-03 17:14:08 -04004123If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4124Blend_Mode, and Draw_Looper. If image is kAlpha_8_SkColorType, apply Shader.
4125If paint contains Mask_Filter, generate mask from image bounds.
4126
4127If generated mask extends beyond image bounds, replicate image edge colors, just
4128as Shader made from SkImage::makeShader with SkShader::kClamp_TileMode set
Cary Clarkbc5697d2017-10-04 14:31:33 -04004129replicates the image edge color when it samples outside of its bounds.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004130
4131constraint set to kStrict_SrcRectConstraint limits Paint Filter_Quality to
4132sample within src; set to kFast_SrcRectConstraint allows sampling outside to
4133improve performance.
4134
4135#Param image Image containing pixels, dimensions, and format ##
4136#Param src source Rect of image to draw from ##
4137#Param dst destination Rect of image to draw to ##
4138#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4139 and so on; or nullptr
4140##
4141#Param constraint filter strictly within src or draw faster ##
Cary Clark8032b982017-07-28 11:04:54 -04004142
4143#Example
4144#Height 64
4145#Description
4146 Canvas scales and translates; transformation from src to dst also scales.
4147 The two matrices are concatenated to create the final transformation.
4148##
Cary Clarkbad5ad72017-08-03 17:14:08 -04004149void draw(SkCanvas* canvas) {
4150 uint32_t pixels[][2] = { { SK_ColorBLACK, SK_ColorWHITE },
4151 { SK_ColorWHITE, SK_ColorBLACK } };
4152 SkBitmap bitmap;
4153 bitmap.installPixels(SkImageInfo::MakeN32Premul(2, 2),
4154 (void*) pixels, sizeof(pixels[0]));
4155 sk_sp<SkImage> image = SkImage::MakeFromBitmap(bitmap);
4156 SkPaint paint;
4157 canvas->scale(4, 4);
4158 for (auto alpha : { 50, 100, 150, 255 } ) {
4159 paint.setAlpha(alpha);
4160 canvas->drawImageRect(image, SkRect::MakeWH(2, 2), SkRect::MakeWH(8, 8), &paint);
4161 canvas->translate(8, 0);
4162 }
4163}
Cary Clark8032b982017-07-28 11:04:54 -04004164##
4165
Cary Clark2ade9972017-11-02 17:49:34 -04004166#SeeAlso SrcRectConstraint drawImage drawImageLattice drawImageNine
Cary Clark8032b982017-07-28 11:04:54 -04004167
4168##
4169
4170# ------------------------------------------------------------------------------
4171
4172#Method void drawImageRect(const sk_sp<SkImage>& image, const SkIRect& isrc, const SkRect& dst,
4173 const SkPaint* paint, SrcRectConstraint constraint = kStrict_SrcRectConstraint)
Cary Clarkab2621d2018-01-30 10:08:57 -05004174#In Draw_Image
Cary Clark8032b982017-07-28 11:04:54 -04004175
4176Draw IRect isrc of Image image, scaled and translated to fill Rect dst.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004177isrc is on integer pixel boundaries; dst may include fractional boundaries.
Cary Clark8032b982017-07-28 11:04:54 -04004178Additionally transform draw using Clip, Matrix, and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004179
Cary Clarkbad5ad72017-08-03 17:14:08 -04004180If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4181Blend_Mode, and Draw_Looper. If image is kAlpha_8_SkColorType, apply Shader.
4182If paint contains Mask_Filter, generate mask from image bounds.
4183
4184If generated mask extends beyond image bounds, replicate image edge colors, just
4185as Shader made from SkImage::makeShader with SkShader::kClamp_TileMode set
Cary Clarkbc5697d2017-10-04 14:31:33 -04004186replicates the image edge color when it samples outside of its bounds.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004187
4188constraint set to kStrict_SrcRectConstraint limits Paint Filter_Quality to
Cary Clarkce101242017-09-01 15:51:02 -04004189sample within image; set to kFast_SrcRectConstraint allows sampling outside to
Cary Clarkbad5ad72017-08-03 17:14:08 -04004190improve performance.
4191
4192#Param image Image containing pixels, dimensions, and format ##
4193#Param isrc source IRect of image to draw from ##
4194#Param dst destination Rect of image to draw to ##
4195#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4196 and so on; or nullptr
4197##
Cary Clarkce101242017-09-01 15:51:02 -04004198#Param constraint filter strictly within image or draw faster ##
Cary Clark8032b982017-07-28 11:04:54 -04004199
4200#Example
4201#Height 64
Cary Clarkbad5ad72017-08-03 17:14:08 -04004202void draw(SkCanvas* canvas) {
4203 uint32_t pixels[][2] = { { 0x00000000, 0x55555555},
4204 { 0xAAAAAAAA, 0xFFFFFFFF} };
4205 SkBitmap bitmap;
4206 bitmap.installPixels(SkImageInfo::MakeN32Premul(2, 2),
4207 (void*) pixels, sizeof(pixels[0]));
4208 sk_sp<SkImage> image = SkImage::MakeFromBitmap(bitmap);
4209 SkPaint paint;
4210 canvas->scale(4, 4);
4211 for (auto color : { SK_ColorRED, SK_ColorBLUE, SK_ColorGREEN } ) {
4212 paint.setColorFilter(SkColorFilter::MakeModeFilter(color, SkBlendMode::kPlus));
4213 canvas->drawImageRect(image, SkIRect::MakeWH(2, 2), SkRect::MakeWH(8, 8), &paint);
4214 canvas->translate(8, 0);
4215 }
Cary Clark8032b982017-07-28 11:04:54 -04004216}
4217##
4218
Cary Clark2ade9972017-11-02 17:49:34 -04004219#SeeAlso SrcRectConstraint drawImage drawImageLattice drawImageNine
4220
Cary Clark8032b982017-07-28 11:04:54 -04004221##
4222
4223# ------------------------------------------------------------------------------
4224
4225#Method void drawImageRect(const sk_sp<SkImage>& image, const SkRect& dst, const SkPaint* paint,
4226 SrcRectConstraint constraint = kStrict_SrcRectConstraint)
Cary Clarkab2621d2018-01-30 10:08:57 -05004227#In Draw_Image
Cary Clark8032b982017-07-28 11:04:54 -04004228
4229Draw Image image, scaled and translated to fill Rect dst,
4230using Clip, Matrix, and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004231
Cary Clarkbad5ad72017-08-03 17:14:08 -04004232If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4233Blend_Mode, and Draw_Looper. If image is kAlpha_8_SkColorType, apply Shader.
4234If paint contains Mask_Filter, generate mask from image bounds.
4235
4236If generated mask extends beyond image bounds, replicate image edge colors, just
4237as Shader made from SkImage::makeShader with SkShader::kClamp_TileMode set
Cary Clarkbc5697d2017-10-04 14:31:33 -04004238replicates the image edge color when it samples outside of its bounds.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004239
4240constraint set to kStrict_SrcRectConstraint limits Paint Filter_Quality to
Cary Clarkce101242017-09-01 15:51:02 -04004241sample within image; set to kFast_SrcRectConstraint allows sampling outside to
Cary Clarkbad5ad72017-08-03 17:14:08 -04004242improve performance.
4243
4244#Param image Image containing pixels, dimensions, and format ##
4245#Param dst destination Rect of image to draw to ##
4246#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4247 and so on; or nullptr
4248##
Cary Clarkce101242017-09-01 15:51:02 -04004249#Param constraint filter strictly within image or draw faster ##
Cary Clark8032b982017-07-28 11:04:54 -04004250
4251#Example
4252#Height 64
Cary Clarkbad5ad72017-08-03 17:14:08 -04004253void draw(SkCanvas* canvas) {
4254 uint32_t pixels[][2] = { { 0x00000000, 0x55550000},
4255 { 0xAAAA0000, 0xFFFF0000} };
4256 SkBitmap bitmap;
4257 bitmap.installPixels(SkImageInfo::MakeN32Premul(2, 2),
4258 (void*) pixels, sizeof(pixels[0]));
4259 sk_sp<SkImage> image = SkImage::MakeFromBitmap(bitmap);
4260 SkPaint paint;
4261 canvas->scale(4, 4);
4262 for (auto color : { SK_ColorRED, SK_ColorBLUE, SK_ColorGREEN } ) {
4263 paint.setColorFilter(SkColorFilter::MakeModeFilter(color, SkBlendMode::kPlus));
4264 canvas->drawImageRect(image, SkRect::MakeWH(8, 8), &paint);
4265 canvas->translate(8, 0);
4266 }
Cary Clark8032b982017-07-28 11:04:54 -04004267}
4268##
4269
Cary Clark2ade9972017-11-02 17:49:34 -04004270#SeeAlso SrcRectConstraint drawImage drawImageLattice drawImageNine
Cary Clark8032b982017-07-28 11:04:54 -04004271
4272##
4273
4274# ------------------------------------------------------------------------------
4275
4276#Method void drawImageNine(const SkImage* image, const SkIRect& center, const SkRect& dst,
4277 const SkPaint* paint = nullptr)
Cary Clarkab2621d2018-01-30 10:08:57 -05004278#In Draw_Image
4279#Line # draws Nine_Patch Image ##
Cary Clark8032b982017-07-28 11:04:54 -04004280
Cary Clarkd0530ba2017-09-14 11:25:39 -04004281Draw Image image stretched proportionally to fit into Rect dst.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004282IRect center divides the image into nine sections: four sides, four corners, and
Cary Clarkce101242017-09-01 15:51:02 -04004283the center. Corners are unmodified or scaled down proportionately if their sides
Cary Clarkbad5ad72017-08-03 17:14:08 -04004284are larger than dst; center and four sides are scaled to fit remaining space, if any.
Cary Clark8032b982017-07-28 11:04:54 -04004285
Cary Clarkbad5ad72017-08-03 17:14:08 -04004286Additionally transform draw using Clip, Matrix, and optional Paint paint.
4287
4288If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4289Blend_Mode, and Draw_Looper. If image is kAlpha_8_SkColorType, apply Shader.
4290If paint contains Mask_Filter, generate mask from image bounds.
4291
4292If generated mask extends beyond image bounds, replicate image edge colors, just
4293as Shader made from SkImage::makeShader with SkShader::kClamp_TileMode set
Cary Clarkbc5697d2017-10-04 14:31:33 -04004294replicates the image edge color when it samples outside of its bounds.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004295
4296#Param image Image containing pixels, dimensions, and format ##
4297#Param center IRect edge of image corners and sides ##
4298#Param dst destination Rect of image to draw to ##
4299#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4300 and so on; or nullptr
4301##
Cary Clark8032b982017-07-28 11:04:54 -04004302
4303#Example
4304#Height 128
4305#Description
4306 The leftmost image is smaller than center; only corners are drawn, all scaled to fit.
Cary Clarkce101242017-09-01 15:51:02 -04004307 The second image equals the size of center; only corners are drawn without scaling.
4308 The remaining images are larger than center. All corners draw without scaling.
4309 The sides and center are scaled if needed to take up the remaining space.
Cary Clark8032b982017-07-28 11:04:54 -04004310##
Cary Clarkbad5ad72017-08-03 17:14:08 -04004311void draw(SkCanvas* canvas) {
4312 SkIRect center = { 20, 10, 50, 40 };
4313 SkBitmap bitmap;
4314 bitmap.allocPixels(SkImageInfo::MakeN32Premul(60, 60));
4315 SkCanvas bitCanvas(bitmap);
4316 SkPaint paint;
4317 SkColor gray = 0xFF000000;
4318 int left = 0;
4319 for (auto right: { center.fLeft, center.fRight, bitmap.width() } ) {
4320 int top = 0;
4321 for (auto bottom: { center.fTop, center.fBottom, bitmap.height() } ) {
4322 paint.setColor(gray);
4323 bitCanvas.drawIRect(SkIRect::MakeLTRB(left, top, right, bottom), paint);
4324 gray += 0x001f1f1f;
4325 top = bottom;
4326 }
4327 left = right;
4328 }
4329 sk_sp<SkImage> image = SkImage::MakeFromBitmap(bitmap);
4330 SkImage* imagePtr = image.get();
4331 for (auto dest: { 20, 30, 40, 60, 90 } ) {
4332 canvas->drawImageNine(imagePtr, center, SkRect::MakeWH(dest, dest), nullptr);
4333 canvas->translate(dest + 4, 0);
4334 }
Cary Clark8032b982017-07-28 11:04:54 -04004335}
4336##
4337
Cary Clark2ade9972017-11-02 17:49:34 -04004338#SeeAlso drawImage drawBitmapNine drawImageLattice drawImageRect
Cary Clark8032b982017-07-28 11:04:54 -04004339
4340##
4341
4342# ------------------------------------------------------------------------------
4343
4344#Method void drawImageNine(const sk_sp<SkImage>& image, const SkIRect& center, const SkRect& dst,
4345 const SkPaint* paint = nullptr)
Cary Clarkab2621d2018-01-30 10:08:57 -05004346#In Draw_Image
Cary Clark8032b982017-07-28 11:04:54 -04004347
Cary Clarkd0530ba2017-09-14 11:25:39 -04004348Draw Image image stretched proportionally to fit into Rect dst.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004349IRect center divides the image into nine sections: four sides, four corners, and
Cary Clarkce101242017-09-01 15:51:02 -04004350the center. Corners are not scaled, or scaled down proportionately if their sides
Cary Clarkbad5ad72017-08-03 17:14:08 -04004351are larger than dst; center and four sides are scaled to fit remaining space, if any.
Cary Clark8032b982017-07-28 11:04:54 -04004352
Cary Clarkbad5ad72017-08-03 17:14:08 -04004353Additionally transform draw using Clip, Matrix, and optional Paint paint.
4354
4355If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4356Blend_Mode, and Draw_Looper. If image is kAlpha_8_SkColorType, apply Shader.
4357If paint contains Mask_Filter, generate mask from image bounds.
4358
4359If generated mask extends beyond image bounds, replicate image edge colors, just
4360as Shader made from SkImage::makeShader with SkShader::kClamp_TileMode set
Cary Clarkbc5697d2017-10-04 14:31:33 -04004361replicates the image edge color when it samples outside of its bounds.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004362
4363#Param image Image containing pixels, dimensions, and format ##
4364#Param center IRect edge of image corners and sides ##
4365#Param dst destination Rect of image to draw to ##
4366#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4367 and so on; or nullptr
4368##
Cary Clark8032b982017-07-28 11:04:54 -04004369
4370#Example
4371#Height 128
4372#Description
4373 The two leftmost images has four corners and sides to the left and right of center.
4374 The leftmost image scales the width of corners proportionately to fit.
Cary Clarkce101242017-09-01 15:51:02 -04004375 The third and fourth image corners are not scaled; the sides and center are scaled to
Cary Clark8032b982017-07-28 11:04:54 -04004376 fill the remaining space.
4377 The rightmost image has four corners scaled vertically to fit, and uses sides above
4378 and below center to fill the remaining space.
4379##
Cary Clarkbad5ad72017-08-03 17:14:08 -04004380void draw(SkCanvas* canvas) {
4381 SkIRect center = { 20, 10, 50, 40 };
4382 SkBitmap bitmap;
4383 bitmap.allocPixels(SkImageInfo::MakeN32Premul(60, 60));
4384 SkCanvas bitCanvas(bitmap);
4385 SkPaint paint;
4386 SkColor gray = 0xFF000000;
4387 int left = 0;
4388 for (auto right: { center.fLeft, center.fRight, bitmap.width() } ) {
4389 int top = 0;
4390 for (auto bottom: { center.fTop, center.fBottom, bitmap.height() } ) {
4391 paint.setColor(gray);
4392 bitCanvas.drawIRect(SkIRect::MakeLTRB(left, top, right, bottom), paint);
4393 gray += 0x001f1f1f;
4394 top = bottom;
4395 }
4396 left = right;
4397 }
4398 sk_sp<SkImage> image = SkImage::MakeFromBitmap(bitmap);
4399 for (auto dest: { 20, 30, 40, 60, 90 } ) {
4400 canvas->drawImageNine(image, center, SkRect::MakeWH(dest, 110 - dest), nullptr);
4401 canvas->translate(dest + 4, 0);
4402 }
Cary Clark8032b982017-07-28 11:04:54 -04004403}
4404##
4405
Cary Clark2ade9972017-11-02 17:49:34 -04004406#SeeAlso drawImage drawBitmapNine drawImageLattice drawImageRect
Cary Clark8032b982017-07-28 11:04:54 -04004407
4408##
4409
4410# ------------------------------------------------------------------------------
4411
4412#Method void drawBitmap(const SkBitmap& bitmap, SkScalar left, SkScalar top,
Cary Clark73fa9722017-08-29 17:36:51 -04004413 const SkPaint* paint = nullptr)
Cary Clarkab2621d2018-01-30 10:08:57 -05004414#In Draw_Image
4415#Line # draws Bitmap at (x, y) position ##
Cary Clark8032b982017-07-28 11:04:54 -04004416
4417Draw Bitmap bitmap, with its top-left corner at (left, top),
4418using Clip, Matrix, and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004419
Cary Clarka560c472017-11-27 10:44:06 -05004420If Paint paint is not nullptr, apply Color_Filter, Color_Alpha, Image_Filter,
Cary Clarkbad5ad72017-08-03 17:14:08 -04004421Blend_Mode, and Draw_Looper. If bitmap is kAlpha_8_SkColorType, apply Shader.
4422If paint contains Mask_Filter, generate mask from bitmap bounds.
4423
4424If generated mask extends beyond bitmap bounds, replicate bitmap edge colors,
4425just as Shader made from SkShader::MakeBitmapShader with
Cary Clarkbc5697d2017-10-04 14:31:33 -04004426SkShader::kClamp_TileMode set replicates the bitmap edge color when it samples
Cary Clarkbad5ad72017-08-03 17:14:08 -04004427outside of its bounds.
4428
4429#Param bitmap Bitmap containing pixels, dimensions, and format ##
4430#Param left left side of bitmap ##
4431#Param top top side of bitmap ##
4432#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4433 and so on; or nullptr
4434##
Cary Clark8032b982017-07-28 11:04:54 -04004435
4436#Example
4437#Height 64
Cary Clarkbad5ad72017-08-03 17:14:08 -04004438void draw(SkCanvas* canvas) {
4439 uint8_t pixels[][8] = { { 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00},
4440 { 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00},
4441 { 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00},
4442 { 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF},
4443 { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
4444 { 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00},
4445 { 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0x00},
4446 { 0xFF, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0xFF} };
4447 SkBitmap bitmap;
4448 bitmap.installPixels(SkImageInfo::MakeA8(8, 8),
4449 (void*) pixels, sizeof(pixels[0]));
4450 SkPaint paint;
4451 canvas->scale(4, 4);
4452 for (auto color : { SK_ColorRED, SK_ColorBLUE, 0xFF007F00} ) {
4453 paint.setColor(color);
4454 canvas->drawBitmap(bitmap, 0, 0, &paint);
4455 canvas->translate(12, 0);
4456 }
Cary Clark8032b982017-07-28 11:04:54 -04004457}
4458##
4459
Cary Clark2ade9972017-11-02 17:49:34 -04004460#SeeAlso drawImage drawBitmapLattice drawBitmapNine drawBitmapRect SkBitmap::readPixels SkBitmap::writePixels
Cary Clark8032b982017-07-28 11:04:54 -04004461
4462##
4463
4464# ------------------------------------------------------------------------------
4465
4466#Method void drawBitmapRect(const SkBitmap& bitmap, const SkRect& src, const SkRect& dst,
4467 const SkPaint* paint, SrcRectConstraint constraint = kStrict_SrcRectConstraint)
Cary Clarkab2621d2018-01-30 10:08:57 -05004468#In Draw_Image
4469#Line # draws Bitmap, source Rect to destination Rect ##
Cary Clark8032b982017-07-28 11:04:54 -04004470
4471Draw Rect src of Bitmap bitmap, scaled and translated to fill Rect dst.
4472Additionally transform draw using Clip, Matrix, and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004473
Cary Clarkbad5ad72017-08-03 17:14:08 -04004474If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4475Blend_Mode, and Draw_Looper. If bitmap is kAlpha_8_SkColorType, apply Shader.
4476If paint contains Mask_Filter, generate mask from bitmap bounds.
4477
4478If generated mask extends beyond bitmap bounds, replicate bitmap edge colors,
4479just as Shader made from SkShader::MakeBitmapShader with
Cary Clarkbc5697d2017-10-04 14:31:33 -04004480SkShader::kClamp_TileMode set replicates the bitmap edge color when it samples
Cary Clarkbad5ad72017-08-03 17:14:08 -04004481outside of its bounds.
4482
4483constraint set to kStrict_SrcRectConstraint limits Paint Filter_Quality to
4484sample within src; set to kFast_SrcRectConstraint allows sampling outside to
4485improve performance.
4486
4487#Param bitmap Bitmap containing pixels, dimensions, and format ##
4488#Param src source Rect of image to draw from ##
4489#Param dst destination Rect of image to draw to ##
4490#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4491 and so on; or nullptr
4492##
4493#Param constraint filter strictly within src or draw faster ##
Cary Clark8032b982017-07-28 11:04:54 -04004494
4495#Example
4496#Height 64
Cary Clarkbad5ad72017-08-03 17:14:08 -04004497void draw(SkCanvas* canvas) {
4498 uint8_t pixels[][8] = { { 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00},
4499 { 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00},
4500 { 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00},
4501 { 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF},
4502 { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
4503 { 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00},
4504 { 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00},
4505 { 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00} };
4506 SkBitmap bitmap;
4507 bitmap.installPixels(SkImageInfo::MakeA8(8, 8),
4508 (void*) pixels, sizeof(pixels[0]));
4509 SkPaint paint;
4510 paint.setMaskFilter(SkBlurMaskFilter::Make(kSolid_SkBlurStyle, 6));
4511 for (auto color : { SK_ColorRED, SK_ColorBLUE, 0xFF007F00} ) {
4512 paint.setColor(color);
4513 canvas->drawBitmapRect(bitmap, SkRect::MakeWH(8, 8), SkRect::MakeWH(32, 32), &paint);
4514 canvas->translate(48, 0);
4515 }
Cary Clark8032b982017-07-28 11:04:54 -04004516}
4517##
4518
Cary Clark2ade9972017-11-02 17:49:34 -04004519#SeeAlso drawImageRect drawBitmap drawBitmapLattice drawBitmapNine
Cary Clark8032b982017-07-28 11:04:54 -04004520
4521##
4522
4523# ------------------------------------------------------------------------------
4524
4525#Method void drawBitmapRect(const SkBitmap& bitmap, const SkIRect& isrc, const SkRect& dst,
4526 const SkPaint* paint, SrcRectConstraint constraint = kStrict_SrcRectConstraint)
Cary Clarkab2621d2018-01-30 10:08:57 -05004527#In Draw_Image
Cary Clark8032b982017-07-28 11:04:54 -04004528
4529Draw IRect isrc of Bitmap bitmap, scaled and translated to fill Rect dst.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004530isrc is on integer pixel boundaries; dst may include fractional boundaries.
Cary Clark8032b982017-07-28 11:04:54 -04004531Additionally transform draw using Clip, Matrix, and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004532
Cary Clarkbad5ad72017-08-03 17:14:08 -04004533If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4534Blend_Mode, and Draw_Looper. If bitmap is kAlpha_8_SkColorType, apply Shader.
4535If paint contains Mask_Filter, generate mask from bitmap bounds.
4536
4537If generated mask extends beyond bitmap bounds, replicate bitmap edge colors,
4538just as Shader made from SkShader::MakeBitmapShader with
Cary Clarkbc5697d2017-10-04 14:31:33 -04004539SkShader::kClamp_TileMode set replicates the bitmap edge color when it samples
Cary Clarkbad5ad72017-08-03 17:14:08 -04004540outside of its bounds.
4541
4542constraint set to kStrict_SrcRectConstraint limits Paint Filter_Quality to
Cary Clarkce101242017-09-01 15:51:02 -04004543sample within isrc; set to kFast_SrcRectConstraint allows sampling outside to
Cary Clarkbad5ad72017-08-03 17:14:08 -04004544improve performance.
4545
4546#Param bitmap Bitmap containing pixels, dimensions, and format ##
4547#Param isrc source IRect of image to draw from ##
4548#Param dst destination Rect of image to draw to ##
4549#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4550 and so on; or nullptr
4551##
Cary Clarkce101242017-09-01 15:51:02 -04004552#Param constraint sample strictly within isrc, or draw faster ##
Cary Clark8032b982017-07-28 11:04:54 -04004553
4554#Example
4555#Height 64
Cary Clarkbad5ad72017-08-03 17:14:08 -04004556void draw(SkCanvas* canvas) {
4557 uint8_t pixels[][8] = { { 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00},
4558 { 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00},
4559 { 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0xFF},
4560 { 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0xFF},
4561 { 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF},
4562 { 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF},
4563 { 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00},
4564 { 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00} };
4565 SkBitmap bitmap;
4566 bitmap.installPixels(SkImageInfo::MakeA8(8, 8),
4567 (void*) pixels, sizeof(pixels[0]));
4568 SkPaint paint;
4569 paint.setFilterQuality(kHigh_SkFilterQuality);
4570 for (auto color : { SK_ColorRED, SK_ColorBLUE, 0xFF007F00, 0xFF7f007f} ) {
4571 paint.setColor(color);
4572 canvas->drawBitmapRect(bitmap, SkIRect::MakeWH(8, 8), SkRect::MakeWH(32, 32), &paint);
4573 canvas->translate(48.25f, 0);
4574 }
Cary Clark8032b982017-07-28 11:04:54 -04004575}
4576##
4577
Cary Clark2ade9972017-11-02 17:49:34 -04004578#SeeAlso drawImageRect drawBitmap drawBitmapLattice drawBitmapNine
Cary Clark8032b982017-07-28 11:04:54 -04004579
4580##
4581
4582# ------------------------------------------------------------------------------
4583
4584#Method void drawBitmapRect(const SkBitmap& bitmap, const SkRect& dst, const SkPaint* paint,
4585 SrcRectConstraint constraint = kStrict_SrcRectConstraint)
Cary Clarkab2621d2018-01-30 10:08:57 -05004586#In Draw_Image
Cary Clark8032b982017-07-28 11:04:54 -04004587
4588Draw Bitmap bitmap, scaled and translated to fill Rect dst.
Cary Clarkce101242017-09-01 15:51:02 -04004589bitmap bounds is on integer pixel boundaries; dst may include fractional boundaries.
Cary Clark8032b982017-07-28 11:04:54 -04004590Additionally transform draw using Clip, Matrix, and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004591
Cary Clarkbad5ad72017-08-03 17:14:08 -04004592If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4593Blend_Mode, and Draw_Looper. If bitmap is kAlpha_8_SkColorType, apply Shader.
4594If paint contains Mask_Filter, generate mask from bitmap bounds.
4595
4596If generated mask extends beyond bitmap bounds, replicate bitmap edge colors,
4597just as Shader made from SkShader::MakeBitmapShader with
Cary Clarkbc5697d2017-10-04 14:31:33 -04004598SkShader::kClamp_TileMode set replicates the bitmap edge color when it samples
Cary Clarkbad5ad72017-08-03 17:14:08 -04004599outside of its bounds.
4600
4601constraint set to kStrict_SrcRectConstraint limits Paint Filter_Quality to
Cary Clarkce101242017-09-01 15:51:02 -04004602sample within bitmap; set to kFast_SrcRectConstraint allows sampling outside to
Cary Clarkbad5ad72017-08-03 17:14:08 -04004603improve performance.
4604
4605#Param bitmap Bitmap containing pixels, dimensions, and format ##
4606#Param dst destination Rect of image to draw to ##
4607#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4608 and so on; or nullptr
4609##
Cary Clarkce101242017-09-01 15:51:02 -04004610#Param constraint filter strictly within bitmap or draw faster ##
Cary Clark8032b982017-07-28 11:04:54 -04004611
4612#Example
4613#Height 64
Cary Clarkbad5ad72017-08-03 17:14:08 -04004614void draw(SkCanvas* canvas) {
4615 uint32_t pixels[][2] = { { 0x00000000, 0x55550000},
4616 { 0xAAAA0000, 0xFFFF0000} };
4617 SkBitmap bitmap;
4618 bitmap.installPixels(SkImageInfo::MakeN32Premul(2, 2),
4619 (void*) pixels, sizeof(pixels[0]));
4620 SkPaint paint;
4621 canvas->scale(4, 4);
4622 for (auto color : { SK_ColorRED, SK_ColorBLUE, SK_ColorGREEN } ) {
4623 paint.setColorFilter(SkColorFilter::MakeModeFilter(color, SkBlendMode::kPlus));
4624 canvas->drawBitmapRect(bitmap, SkRect::MakeWH(8, 8), &paint);
4625 canvas->translate(8, 0);
4626 }
Cary Clark8032b982017-07-28 11:04:54 -04004627}
4628##
4629
Cary Clark2ade9972017-11-02 17:49:34 -04004630#SeeAlso drawImageRect drawBitmap drawBitmapLattice drawBitmapNine
Cary Clark8032b982017-07-28 11:04:54 -04004631
4632##
4633
4634# ------------------------------------------------------------------------------
4635
4636#Method void drawBitmapNine(const SkBitmap& bitmap, const SkIRect& center, const SkRect& dst,
Cary Clark73fa9722017-08-29 17:36:51 -04004637 const SkPaint* paint = nullptr)
Cary Clarkab2621d2018-01-30 10:08:57 -05004638#In Draw_Image
4639#Line # draws Nine_Patch Bitmap ##
Cary Clark8032b982017-07-28 11:04:54 -04004640
Cary Clarkd0530ba2017-09-14 11:25:39 -04004641Draw Bitmap bitmap stretched proportionally to fit into Rect dst.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004642IRect center divides the bitmap into nine sections: four sides, four corners,
Cary Clarkce101242017-09-01 15:51:02 -04004643and the center. Corners are not scaled, or scaled down proportionately if their
Cary Clarkbad5ad72017-08-03 17:14:08 -04004644sides are larger than dst; center and four sides are scaled to fit remaining
4645space, if any.
Cary Clark8032b982017-07-28 11:04:54 -04004646
Cary Clarkbad5ad72017-08-03 17:14:08 -04004647Additionally transform draw using Clip, Matrix, and optional Paint paint.
4648
4649If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4650Blend_Mode, and Draw_Looper. If bitmap is kAlpha_8_SkColorType, apply Shader.
4651If paint contains Mask_Filter, generate mask from bitmap bounds.
4652
4653If generated mask extends beyond bitmap bounds, replicate bitmap edge colors,
4654just as Shader made from SkShader::MakeBitmapShader with
Cary Clarkbc5697d2017-10-04 14:31:33 -04004655SkShader::kClamp_TileMode set replicates the bitmap edge color when it samples
Cary Clarkbad5ad72017-08-03 17:14:08 -04004656outside of its bounds.
4657
4658#Param bitmap Bitmap containing pixels, dimensions, and format ##
4659#Param center IRect edge of image corners and sides ##
4660#Param dst destination Rect of image to draw to ##
4661#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4662 and so on; or nullptr
4663##
Cary Clark8032b982017-07-28 11:04:54 -04004664
4665#Example
4666#Height 128
4667#Description
4668 The two leftmost bitmap draws has four corners and sides to the left and right of center.
4669 The leftmost bitmap draw scales the width of corners proportionately to fit.
Cary Clarkce101242017-09-01 15:51:02 -04004670 The third and fourth draw corners are not scaled; the sides and center are scaled to
Cary Clark8032b982017-07-28 11:04:54 -04004671 fill the remaining space.
4672 The rightmost bitmap draw has four corners scaled vertically to fit, and uses sides above
4673 and below center to fill the remaining space.
4674##
Cary Clarkbad5ad72017-08-03 17:14:08 -04004675void draw(SkCanvas* canvas) {
4676 SkIRect center = { 20, 10, 50, 40 };
4677 SkBitmap bitmap;
4678 bitmap.allocPixels(SkImageInfo::MakeN32Premul(60, 60));
4679 SkCanvas bitCanvas(bitmap);
4680 SkPaint paint;
4681 SkColor gray = 0xFF000000;
4682 int left = 0;
4683 for (auto right: { center.fLeft, center.fRight, bitmap.width() } ) {
4684 int top = 0;
4685 for (auto bottom: { center.fTop, center.fBottom, bitmap.height() } ) {
4686 paint.setColor(gray);
4687 bitCanvas.drawIRect(SkIRect::MakeLTRB(left, top, right, bottom), paint);
4688 gray += 0x001f1f1f;
4689 top = bottom;
4690 }
4691 left = right;
4692 }
4693 for (auto dest: { 20, 30, 40, 60, 90 } ) {
4694 canvas->drawBitmapNine(bitmap, center, SkRect::MakeWH(dest, 110 - dest), nullptr);
4695 canvas->translate(dest + 4, 0);
4696 }
Cary Clark8032b982017-07-28 11:04:54 -04004697}
4698##
4699
Cary Clark2ade9972017-11-02 17:49:34 -04004700#SeeAlso drawImageNine drawBitmap drawBitmapLattice drawBitmapRect
Cary Clark8032b982017-07-28 11:04:54 -04004701
4702##
4703
4704# ------------------------------------------------------------------------------
4705#Struct Lattice
Cary Clark08895c42018-02-01 09:37:32 -05004706#Line # divides Bitmap or Image into a rectangular grid ##
Cary Clark8032b982017-07-28 11:04:54 -04004707#Code
4708 struct Lattice {
Cary Clark2f466242017-12-11 16:03:17 -05004709 enum RectType ...
Cary Clark8032b982017-07-28 11:04:54 -04004710
Cary Clark2f466242017-12-11 16:03:17 -05004711 const int* fXDivs;
4712 const int* fYDivs;
4713 const RectType* fRectTypes;
4714 int fXCount;
4715 int fYCount;
4716 const SkIRect* fBounds;
4717 const SkColor* fColors;
Cary Clark8032b982017-07-28 11:04:54 -04004718 };
4719##
4720
Cary Clark154beea2017-10-26 07:58:48 -04004721 Lattice divides Bitmap or Image into a rectangular grid.
4722 Grid entries on even columns and even rows are fixed; these entries are
4723 always drawn at their original size if the destination is large enough.
4724 If the destination side is too small to hold the fixed entries, all fixed
4725 entries are proportionately scaled down to fit.
4726 The grid entries not on even columns and rows are scaled to fit the
4727 remaining space, if any.
4728
Cary Clark2f466242017-12-11 16:03:17 -05004729 #Enum RectType
Cary Clark8032b982017-07-28 11:04:54 -04004730 #Code
Cary Clark2f466242017-12-11 16:03:17 -05004731 enum RectType : uint8_t {
4732 kDefault = 0,
4733 kTransparent,
4734 kFixedColor,
Cary Clark8032b982017-07-28 11:04:54 -04004735 };
4736 ##
4737
Cary Clark2f466242017-12-11 16:03:17 -05004738 Optional setting per rectangular grid entry to make it transparent,
4739 or to fill the grid entry with a color.
Cary Clark8032b982017-07-28 11:04:54 -04004740
Cary Clark2f466242017-12-11 16:03:17 -05004741 #Const kDefault 0
4742 Draws Bitmap into lattice rectangle.
4743 ##
4744
4745 #Const kTransparent 1
4746 Skips lattice rectangle by making it transparent.
4747 ##
4748
4749 #Const kFixedColor 2
4750 Draws one of fColors into lattice rectangle.
Cary Clark8032b982017-07-28 11:04:54 -04004751 ##
4752 ##
4753
4754 #Member const int* fXDivs
4755 Array of x-coordinates that divide the bitmap vertically.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004756 Array entries must be unique, increasing, greater than or equal to
4757 fBounds left edge, and less than fBounds right edge.
4758 Set the first element to fBounds left to collapse the left column of
4759 fixed grid entries.
Cary Clark8032b982017-07-28 11:04:54 -04004760 ##
4761
4762 #Member const int* fYDivs
4763 Array of y-coordinates that divide the bitmap horizontally.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004764 Array entries must be unique, increasing, greater than or equal to
4765 fBounds top edge, and less than fBounds bottom edge.
4766 Set the first element to fBounds top to collapse the top row of fixed
4767 grid entries.
Cary Clark8032b982017-07-28 11:04:54 -04004768 ##
4769
Cary Clark2f466242017-12-11 16:03:17 -05004770 #Member const RectType* fRectTypes
4771 Optional array of fill types, one per rectangular grid entry:
Cary Clarkbad5ad72017-08-03 17:14:08 -04004772 array length must be
4773 #Formula
4774 (fXCount + 1) * (fYCount + 1)
4775 ##
4776 .
Cary Clark6fc50412017-09-21 12:31:06 -04004777
Cary Clark2f466242017-12-11 16:03:17 -05004778 Each RectType is one of: kDefault, kTransparent, kFixedColor.
4779
Cary Clark8032b982017-07-28 11:04:54 -04004780 Array entries correspond to the rectangular grid entries, ascending
4781 left to right and then top to bottom.
4782 ##
4783
4784 #Member int fXCount
Cary Clarkbad5ad72017-08-03 17:14:08 -04004785 Number of entries in fXDivs array; one less than the number of
4786 horizontal divisions.
Cary Clark8032b982017-07-28 11:04:54 -04004787 ##
4788
4789 #Member int fYCount
Cary Clarkbad5ad72017-08-03 17:14:08 -04004790 Number of entries in fYDivs array; one less than the number of vertical
4791 divisions.
Cary Clark8032b982017-07-28 11:04:54 -04004792 ##
4793
4794 #Member const SkIRect* fBounds
4795 Optional subset IRect source to draw from.
4796 If nullptr, source bounds is dimensions of Bitmap or Image.
4797 ##
4798
Cary Clark2f466242017-12-11 16:03:17 -05004799 #Member const SkColor* fColors
4800 Optional array of colors, one per rectangular grid entry.
4801 Array length must be
4802 #Formula
4803 (fXCount + 1) * (fYCount + 1)
4804 ##
4805 .
4806
4807 Array entries correspond to the rectangular grid entries, ascending
4808 left to right, then top to bottom.
4809 ##
4810
Cary Clark8032b982017-07-28 11:04:54 -04004811#Struct Lattice ##
4812
4813#Method void drawBitmapLattice(const SkBitmap& bitmap, const Lattice& lattice, const SkRect& dst,
4814 const SkPaint* paint = nullptr)
Cary Clarkab2621d2018-01-30 10:08:57 -05004815#In Draw_Image
4816#Line # draws proportionally stretched Bitmap ##
Cary Clark8032b982017-07-28 11:04:54 -04004817
Cary Clarkd0530ba2017-09-14 11:25:39 -04004818Draw Bitmap bitmap stretched proportionally to fit into Rect dst.
Cary Clark8032b982017-07-28 11:04:54 -04004819
4820Lattice lattice divides bitmap into a rectangular grid.
4821Each intersection of an even-numbered row and column is fixed; like the corners
Cary Clarkbad5ad72017-08-03 17:14:08 -04004822of drawBitmapNine, fixed lattice elements never scale larger than their initial
Cary Clarkbc5697d2017-10-04 14:31:33 -04004823size and shrink proportionately when all fixed elements exceed the bitmap
Cary Clarkbad5ad72017-08-03 17:14:08 -04004824dimension. All other grid elements scale to fill the available space, if any.
Cary Clark8032b982017-07-28 11:04:54 -04004825
4826Additionally transform draw using Clip, Matrix, and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004827
Cary Clarkbad5ad72017-08-03 17:14:08 -04004828If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4829Blend_Mode, and Draw_Looper. If bitmap is kAlpha_8_SkColorType, apply Shader.
4830If paint contains Mask_Filter, generate mask from bitmap bounds.
4831
4832If generated mask extends beyond bitmap bounds, replicate bitmap edge colors,
4833just as Shader made from SkShader::MakeBitmapShader with
Cary Clarkbc5697d2017-10-04 14:31:33 -04004834SkShader::kClamp_TileMode set replicates the bitmap edge color when it samples
Cary Clarkbad5ad72017-08-03 17:14:08 -04004835outside of its bounds.
4836
4837#Param bitmap Bitmap containing pixels, dimensions, and format ##
4838#Param lattice division of bitmap into fixed and variable rectangles ##
4839#Param dst destination Rect of image to draw to ##
4840#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4841 and so on; or nullptr
4842##
Cary Clark8032b982017-07-28 11:04:54 -04004843
4844#Example
4845#Height 128
4846#Description
4847 The two leftmost bitmap draws has four corners and sides to the left and right of center.
4848 The leftmost bitmap draw scales the width of corners proportionately to fit.
Cary Clarkce101242017-09-01 15:51:02 -04004849 The third and fourth draw corners are not scaled; the sides are scaled to
Cary Clark8032b982017-07-28 11:04:54 -04004850 fill the remaining space; the center is transparent.
4851 The rightmost bitmap draw has four corners scaled vertically to fit, and uses sides above
4852 and below center to fill the remaining space.
4853##
Cary Clarkbad5ad72017-08-03 17:14:08 -04004854void draw(SkCanvas* canvas) {
4855 SkIRect center = { 20, 10, 50, 40 };
4856 SkBitmap bitmap;
4857 bitmap.allocPixels(SkImageInfo::MakeN32Premul(60, 60));
4858 SkCanvas bitCanvas(bitmap);
4859 SkPaint paint;
4860 SkColor gray = 0xFF000000;
4861 int left = 0;
4862 for (auto right: { center.fLeft, center.fRight, bitmap.width() } ) {
4863 int top = 0;
4864 for (auto bottom: { center.fTop, center.fBottom, bitmap.height() } ) {
4865 paint.setColor(gray);
4866 bitCanvas.drawIRect(SkIRect::MakeLTRB(left, top, right, bottom), paint);
4867 gray += 0x001f1f1f;
4868 top = bottom;
4869 }
4870 left = right;
4871 }
4872 const int xDivs[] = { center.fLeft, center.fRight };
4873 const int yDivs[] = { center.fTop, center.fBottom };
Cary Clarkca3ebcd2017-12-12 11:22:38 -05004874 SkCanvas::Lattice::RectType fillTypes[3][3];
4875 memset(fillTypes, 0, sizeof(fillTypes));
4876 fillTypes[1][1] = SkCanvas::Lattice::kTransparent;
4877 SkColor dummy[9]; // temporary pending bug fix
4878 SkCanvas::Lattice lattice = { xDivs, yDivs, fillTypes[0], SK_ARRAY_COUNT(xDivs),
4879 SK_ARRAY_COUNT(yDivs), nullptr, dummy };
Cary Clarkbad5ad72017-08-03 17:14:08 -04004880 for (auto dest: { 20, 30, 40, 60, 90 } ) {
Cary Clarkca3ebcd2017-12-12 11:22:38 -05004881 canvas->drawBitmapLattice(bitmap, lattice, SkRect::MakeWH(dest, 110 - dest), nullptr);
Cary Clarkbad5ad72017-08-03 17:14:08 -04004882 canvas->translate(dest + 4, 0);
4883 }
Cary Clark8032b982017-07-28 11:04:54 -04004884}
4885##
4886
Cary Clark2ade9972017-11-02 17:49:34 -04004887#SeeAlso drawImageLattice drawBitmap drawBitmapNine Lattice
Cary Clark8032b982017-07-28 11:04:54 -04004888
4889##
4890
4891# ------------------------------------------------------------------------------
4892
4893#Method void drawImageLattice(const SkImage* image, const Lattice& lattice, const SkRect& dst,
4894 const SkPaint* paint = nullptr)
Cary Clarkab2621d2018-01-30 10:08:57 -05004895#In Draw_Image
4896#Line # draws proportionally stretched Image ##
Cary Clark8032b982017-07-28 11:04:54 -04004897
Cary Clarkd0530ba2017-09-14 11:25:39 -04004898Draw Image image stretched proportionally to fit into Rect dst.
Cary Clark8032b982017-07-28 11:04:54 -04004899
4900Lattice lattice divides image into a rectangular grid.
4901Each intersection of an even-numbered row and column is fixed; like the corners
Cary Clarkbad5ad72017-08-03 17:14:08 -04004902of drawBitmapNine, fixed lattice elements never scale larger than their initial
Cary Clarkbc5697d2017-10-04 14:31:33 -04004903size and shrink proportionately when all fixed elements exceed the bitmap
Cary Clarkbad5ad72017-08-03 17:14:08 -04004904dimension. All other grid elements scale to fill the available space, if any.
Cary Clark8032b982017-07-28 11:04:54 -04004905
4906Additionally transform draw using Clip, Matrix, and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004907
Cary Clarkbad5ad72017-08-03 17:14:08 -04004908If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4909Blend_Mode, and Draw_Looper. If bitmap is kAlpha_8_SkColorType, apply Shader.
4910If paint contains Mask_Filter, generate mask from bitmap bounds.
4911
4912If generated mask extends beyond bitmap bounds, replicate bitmap edge colors,
4913just as Shader made from SkShader::MakeBitmapShader with
Cary Clarkbc5697d2017-10-04 14:31:33 -04004914SkShader::kClamp_TileMode set replicates the bitmap edge color when it samples
Cary Clarkbad5ad72017-08-03 17:14:08 -04004915outside of its bounds.
4916
4917#Param image Image containing pixels, dimensions, and format ##
4918#Param lattice division of bitmap into fixed and variable rectangles ##
4919#Param dst destination Rect of image to draw to ##
4920#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4921 and so on; or nullptr
4922##
Cary Clark8032b982017-07-28 11:04:54 -04004923
4924#Example
4925#Height 128
4926#Description
4927 The leftmost image is smaller than center; only corners are drawn, all scaled to fit.
Cary Clarkce101242017-09-01 15:51:02 -04004928 The second image equals the size of center; only corners are drawn without scaling.
4929 The remaining images are larger than center. All corners draw without scaling. The sides
Cary Clark8032b982017-07-28 11:04:54 -04004930 are scaled if needed to take up the remaining space; the center is transparent.
4931##
Cary Clarkbad5ad72017-08-03 17:14:08 -04004932void draw(SkCanvas* canvas) {
4933 SkIRect center = { 20, 10, 50, 40 };
4934 SkBitmap bitmap;
4935 bitmap.allocPixels(SkImageInfo::MakeN32Premul(60, 60));
4936 SkCanvas bitCanvas(bitmap);
4937 SkPaint paint;
4938 SkColor gray = 0xFF000000;
4939 int left = 0;
4940 for (auto right: { center.fLeft, center.fRight, bitmap.width() } ) {
4941 int top = 0;
4942 for (auto bottom: { center.fTop, center.fBottom, bitmap.height() } ) {
4943 paint.setColor(gray);
4944 bitCanvas.drawIRect(SkIRect::MakeLTRB(left, top, right, bottom), paint);
4945 gray += 0x001f1f1f;
4946 top = bottom;
4947 }
4948 left = right;
4949 }
4950 const int xDivs[] = { center.fLeft, center.fRight };
4951 const int yDivs[] = { center.fTop, center.fBottom };
Cary Clarkca3ebcd2017-12-12 11:22:38 -05004952 SkCanvas::Lattice::RectType fillTypes[3][3];
4953 memset(fillTypes, 0, sizeof(fillTypes));
4954 fillTypes[1][1] = SkCanvas::Lattice::kTransparent;
4955 SkColor dummy[9]; // temporary pending bug fix
4956 SkCanvas::Lattice lattice = { xDivs, yDivs, fillTypes[0], SK_ARRAY_COUNT(xDivs),
4957 SK_ARRAY_COUNT(yDivs), nullptr, dummy };
Cary Clarkbad5ad72017-08-03 17:14:08 -04004958 sk_sp<SkImage> image = SkImage::MakeFromBitmap(bitmap);
4959 SkImage* imagePtr = image.get();
4960 for (auto dest: { 20, 30, 40, 60, 90 } ) {
4961 canvas->drawImageNine(imagePtr, center, SkRect::MakeWH(dest, dest), nullptr);
4962 canvas->translate(dest + 4, 0);
4963 }
Cary Clark8032b982017-07-28 11:04:54 -04004964}
4965##
4966
Cary Clark2ade9972017-11-02 17:49:34 -04004967#SeeAlso drawBitmapLattice drawImage drawImageNine Lattice
Cary Clark8032b982017-07-28 11:04:54 -04004968
4969##
4970
Cary Clark08895c42018-02-01 09:37:32 -05004971#Subtopic Draw_Image ##
Cary Clark8032b982017-07-28 11:04:54 -04004972
4973# ------------------------------------------------------------------------------
4974
4975#Method void drawText(const void* text, size_t byteLength, SkScalar x, SkScalar y,
4976 const SkPaint& paint)
Cary Clarkab2621d2018-01-30 10:08:57 -05004977#Line # draws text at (x, y), using font advance ##
Cary Clark8032b982017-07-28 11:04:54 -04004978
4979Draw text, with origin at (x, y), using Clip, Matrix, and Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004980
Cary Clarkbc5697d2017-10-04 14:31:33 -04004981text meaning depends on Paint_Text_Encoding; by default, text is encoded as
Cary Clarkbad5ad72017-08-03 17:14:08 -04004982UTF-8.
Cary Clark8032b982017-07-28 11:04:54 -04004983
Cary Clarkbad5ad72017-08-03 17:14:08 -04004984x and y meaning depends on Paint_Text_Align and Paint_Vertical_Text; by default
Cary Clarkbc5697d2017-10-04 14:31:33 -04004985text draws left to right, positioning the first glyph left side bearing at x
Cary Clarkbad5ad72017-08-03 17:14:08 -04004986and its baseline at y. Text size is affected by Matrix and Paint_Text_Size.
4987
Mike Reed8ad91a92018-01-19 19:09:32 -05004988All elements of paint: Path_Effect, Mask_Filter, Shader,
Cary Clarkbad5ad72017-08-03 17:14:08 -04004989Color_Filter, Image_Filter, and Draw_Looper; apply to text. By default, draws
Cary Clarkce101242017-09-01 15:51:02 -04004990filled 12 point black Glyphs.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004991
Cary Clarkce101242017-09-01 15:51:02 -04004992#Param text character code points or Glyphs drawn ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04004993#Param byteLength byte length of text array ##
4994#Param x start of text on x-axis ##
4995#Param y start of text on y-axis ##
4996#Param paint text size, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04004997
4998#Example
4999#Height 200
5000#Description
5001 The same text is drawn varying Paint_Text_Size and varying
5002 Matrix.
5003##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005004void draw(SkCanvas* canvas) {
5005 SkPaint paint;
5006 paint.setAntiAlias(true);
5007 float textSizes[] = { 12, 18, 24, 36 };
5008 for (auto size: textSizes ) {
5009 paint.setTextSize(size);
5010 canvas->drawText("Aa", 2, 10, 20, paint);
5011 canvas->translate(0, size * 2);
5012 }
5013 paint.reset();
5014 paint.setAntiAlias(true);
5015 float yPos = 20;
5016 for (auto size: textSizes ) {
5017 float scale = size / 12.f;
5018 canvas->resetMatrix();
5019 canvas->translate(100, 0);
5020 canvas->scale(scale, scale);
5021 canvas->drawText("Aa", 2, 10 / scale, yPos / scale, paint);
5022 yPos += size * 2;
5023 }
5024}
Cary Clark8032b982017-07-28 11:04:54 -04005025##
5026
Cary Clark2ade9972017-11-02 17:49:34 -04005027#SeeAlso drawString drawPosText drawPosTextH drawTextBlob drawTextOnPath drawTextRSXform
Cary Clark8032b982017-07-28 11:04:54 -04005028
5029##
5030
5031#Method void drawString(const char* string, SkScalar x, SkScalar y, const SkPaint& paint)
5032
Cary Clarkab2621d2018-01-30 10:08:57 -05005033#Line # draws null terminated string at (x, y) using font advance ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005034Draw null terminated string, with origin at (x, y), using Clip, Matrix, and
5035Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04005036
Cary Clarkbc5697d2017-10-04 14:31:33 -04005037string meaning depends on Paint_Text_Encoding; by default, strings are encoded
5038as UTF-8. Other values of Paint_Text_Encoding are unlikely to produce the desired
Cary Clarkbad5ad72017-08-03 17:14:08 -04005039results, since zero bytes may be embedded in the string.
Cary Clark8032b982017-07-28 11:04:54 -04005040
Cary Clarkbad5ad72017-08-03 17:14:08 -04005041x and y meaning depends on Paint_Text_Align and Paint_Vertical_Text; by default
Cary Clarkbc5697d2017-10-04 14:31:33 -04005042string draws left to right, positioning the first glyph left side bearing at x
Cary Clarkbad5ad72017-08-03 17:14:08 -04005043and its baseline at y. Text size is affected by Matrix and Paint_Text_Size.
5044
Mike Reed8ad91a92018-01-19 19:09:32 -05005045All elements of paint: Path_Effect, Mask_Filter, Shader,
Cary Clarkbad5ad72017-08-03 17:14:08 -04005046Color_Filter, Image_Filter, and Draw_Looper; apply to text. By default, draws
Cary Clarkce101242017-09-01 15:51:02 -04005047filled 12 point black Glyphs.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005048
Cary Clarkce101242017-09-01 15:51:02 -04005049#Param string character code points or Glyphs drawn,
Cary Clarkbad5ad72017-08-03 17:14:08 -04005050 ending with a char value of zero
5051##
5052#Param x start of string on x-axis ##
5053#Param y start of string on y-axis ##
5054#Param paint text size, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005055
5056#Example
5057 SkPaint paint;
5058 canvas->drawString("a small hello", 20, 20, paint);
5059##
5060
Cary Clark2ade9972017-11-02 17:49:34 -04005061#SeeAlso drawText drawPosText drawPosTextH drawTextBlob drawTextOnPath drawTextRSXform
Cary Clark8032b982017-07-28 11:04:54 -04005062
5063##
5064
5065#Method void drawString(const SkString& string, SkScalar x, SkScalar y, const SkPaint& paint)
5066
Cary Clarkbad5ad72017-08-03 17:14:08 -04005067Draw null terminated string, with origin at (x, y), using Clip, Matrix, and
5068Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04005069
Cary Clarkbc5697d2017-10-04 14:31:33 -04005070string meaning depends on Paint_Text_Encoding; by default, strings are encoded
5071as UTF-8. Other values of Paint_Text_Encoding are unlikely to produce the desired
Cary Clarkbad5ad72017-08-03 17:14:08 -04005072results, since zero bytes may be embedded in the string.
Cary Clark8032b982017-07-28 11:04:54 -04005073
Cary Clarkbad5ad72017-08-03 17:14:08 -04005074x and y meaning depends on Paint_Text_Align and Paint_Vertical_Text; by default
Cary Clarkbc5697d2017-10-04 14:31:33 -04005075string draws left to right, positioning the first glyph left side bearing at x
Cary Clarkbad5ad72017-08-03 17:14:08 -04005076and its baseline at y. Text size is affected by Matrix and Paint_Text_Size.
5077
Mike Reed8ad91a92018-01-19 19:09:32 -05005078All elements of paint: Path_Effect, Mask_Filter, Shader,
Cary Clarkbad5ad72017-08-03 17:14:08 -04005079Color_Filter, Image_Filter, and Draw_Looper; apply to text. By default, draws
Cary Clarkce101242017-09-01 15:51:02 -04005080filled 12 point black Glyphs.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005081
Cary Clarkce101242017-09-01 15:51:02 -04005082#Param string character code points or Glyphs drawn,
Cary Clarkbad5ad72017-08-03 17:14:08 -04005083 ending with a char value of zero
5084##
5085#Param x start of string on x-axis ##
5086#Param y start of string on y-axis ##
5087#Param paint text size, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005088
5089#Example
5090 SkPaint paint;
5091 SkString string("a small hello");
5092 canvas->drawString(string, 20, 20, paint);
5093##
5094
Cary Clark2ade9972017-11-02 17:49:34 -04005095#SeeAlso drawText drawPosText drawPosTextH drawTextBlob drawTextOnPath drawTextRSXform
Cary Clark8032b982017-07-28 11:04:54 -04005096
5097##
5098
5099# ------------------------------------------------------------------------------
5100
5101#Method void drawPosText(const void* text, size_t byteLength, const SkPoint pos[],
5102 const SkPaint& paint)
Cary Clarkab2621d2018-01-30 10:08:57 -05005103#Line # draws text at array of (x, y) positions ##
Cary Clark8032b982017-07-28 11:04:54 -04005104
Cary Clarkbad5ad72017-08-03 17:14:08 -04005105Draw each glyph in text with the origin in pos array, using Clip, Matrix, and
Cary Clarkce101242017-09-01 15:51:02 -04005106Paint paint. The number of entries in pos array must match the number of Glyphs
Cary Clarkbad5ad72017-08-03 17:14:08 -04005107described by byteLength of text.
Cary Clark8032b982017-07-28 11:04:54 -04005108
Cary Clarkbc5697d2017-10-04 14:31:33 -04005109text meaning depends on Paint_Text_Encoding; by default, text is encoded as
Cary Clarkbad5ad72017-08-03 17:14:08 -04005110UTF-8. pos elements' meaning depends on Paint_Text_Align and Paint_Vertical_Text;
Cary Clarkbc5697d2017-10-04 14:31:33 -04005111by default each glyph left side bearing is positioned at x and its
Cary Clarkbad5ad72017-08-03 17:14:08 -04005112baseline is positioned at y. Text size is affected by Matrix and
5113Paint_Text_Size.
Cary Clark8032b982017-07-28 11:04:54 -04005114
Mike Reed8ad91a92018-01-19 19:09:32 -05005115All elements of paint: Path_Effect, Mask_Filter, Shader,
Cary Clarkbad5ad72017-08-03 17:14:08 -04005116Color_Filter, Image_Filter, and Draw_Looper; apply to text. By default, draws
Cary Clarkce101242017-09-01 15:51:02 -04005117filled 12 point black Glyphs.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005118
5119Layout engines such as Harfbuzz typically position each glyph
Cary Clarkbc5697d2017-10-04 14:31:33 -04005120rather than using the font advance widths.
Cary Clark8032b982017-07-28 11:04:54 -04005121
Cary Clarkce101242017-09-01 15:51:02 -04005122#Param text character code points or Glyphs drawn ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005123#Param byteLength byte length of text array ##
5124#Param pos array of glyph origins ##
5125#Param paint text size, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005126
5127#Example
5128#Height 120
Cary Clarkbad5ad72017-08-03 17:14:08 -04005129void draw(SkCanvas* canvas) {
5130 const char hello[] = "HeLLo!";
5131 const SkPoint pos[] = { {40, 100}, {82, 95}, {115, 110}, {130, 95}, {145, 85},
5132 {172, 100} };
5133 SkPaint paint;
5134 paint.setTextSize(60);
5135 canvas->drawPosText(hello, strlen(hello), pos, paint);
Cary Clark8032b982017-07-28 11:04:54 -04005136}
5137##
5138
Cary Clark2ade9972017-11-02 17:49:34 -04005139#SeeAlso drawText drawPosTextH drawTextBlob drawTextOnPath drawTextRSXform
Cary Clark8032b982017-07-28 11:04:54 -04005140
5141##
5142
5143# ------------------------------------------------------------------------------
5144
5145#Method void drawPosTextH(const void* text, size_t byteLength, const SkScalar xpos[], SkScalar constY,
5146 const SkPaint& paint)
Cary Clarkab2621d2018-01-30 10:08:57 -05005147#Line # draws text at x positions with common baseline ##
Cary Clark8032b982017-07-28 11:04:54 -04005148
Cary Clarkbad5ad72017-08-03 17:14:08 -04005149Draw each glyph in text with its (x, y) origin composed from xpos array and
5150constY, using Clip, Matrix, and Paint paint. The number of entries in xpos array
Cary Clarkce101242017-09-01 15:51:02 -04005151must match the number of Glyphs described by byteLength of text.
Cary Clark8032b982017-07-28 11:04:54 -04005152
Cary Clarkbc5697d2017-10-04 14:31:33 -04005153text meaning depends on Paint_Text_Encoding; by default, text is encoded as
Cary Clarkce101242017-09-01 15:51:02 -04005154UTF-8. xpos elements' meaning depends on Paint_Text_Align and Paint_Vertical_Text;
Cary Clarkbc5697d2017-10-04 14:31:33 -04005155by default each glyph left side bearing is positioned at an xpos element and
Cary Clarkbad5ad72017-08-03 17:14:08 -04005156its baseline is positioned at constY. Text size is affected by Matrix and
5157Paint_Text_Size.
Cary Clark8032b982017-07-28 11:04:54 -04005158
Mike Reed8ad91a92018-01-19 19:09:32 -05005159All elements of paint: Path_Effect, Mask_Filter, Shader,
Cary Clarkbad5ad72017-08-03 17:14:08 -04005160Color_Filter, Image_Filter, and Draw_Looper; apply to text. By default, draws
Cary Clarkce101242017-09-01 15:51:02 -04005161filled 12 point black Glyphs.
Cary Clark8032b982017-07-28 11:04:54 -04005162
Cary Clarkbad5ad72017-08-03 17:14:08 -04005163Layout engines such as Harfbuzz typically position each glyph
Cary Clarkbc5697d2017-10-04 14:31:33 -04005164rather than using the font advance widths if all Glyphs share the same
Cary Clarkbad5ad72017-08-03 17:14:08 -04005165baseline.
5166
Cary Clarkce101242017-09-01 15:51:02 -04005167#Param text character code points or Glyphs drawn ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005168#Param byteLength byte length of text array ##
5169#Param xpos array of x positions, used to position each glyph ##
5170#Param constY shared y coordinate for all of x positions ##
5171#Param paint text size, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005172
5173#Example
5174#Height 40
Cary Clarkbad5ad72017-08-03 17:14:08 -04005175 void draw(SkCanvas* canvas) {
5176 SkScalar xpos[] = { 20, 40, 80, 160 };
5177 SkPaint paint;
5178 canvas->drawPosTextH("XXXX", 4, xpos, 20, paint);
5179 }
Cary Clark8032b982017-07-28 11:04:54 -04005180##
5181
Cary Clark2ade9972017-11-02 17:49:34 -04005182#SeeAlso drawText drawPosText drawTextBlob drawTextOnPath drawTextRSXform
Cary Clark8032b982017-07-28 11:04:54 -04005183
5184##
5185
5186# ------------------------------------------------------------------------------
5187
5188#Method void drawTextOnPathHV(const void* text, size_t byteLength, const SkPath& path, SkScalar hOffset,
5189 SkScalar vOffset, const SkPaint& paint)
Cary Clarkab2621d2018-01-30 10:08:57 -05005190#Line # draws text following Path with offsets ##
Cary Clark8032b982017-07-28 11:04:54 -04005191
5192Draw text on Path path, using Clip, Matrix, and Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04005193
Cary Clarkbad5ad72017-08-03 17:14:08 -04005194Origin of text is at distance hOffset along the path, offset by a perpendicular
5195vector of length vOffset. If the path section corresponding the glyph advance is
5196curved, the glyph is drawn curved to match; control points in the glyph are
Cary Clarkbc5697d2017-10-04 14:31:33 -04005197mapped to projected points parallel to the path. If the text advance is larger
Cary Clarkbad5ad72017-08-03 17:14:08 -04005198than the path length, the excess text is clipped.
5199
Cary Clarkbc5697d2017-10-04 14:31:33 -04005200text meaning depends on Paint_Text_Encoding; by default, text is encoded as
Cary Clarkbad5ad72017-08-03 17:14:08 -04005201UTF-8. Origin meaning depends on Paint_Text_Align and Paint_Vertical_Text; by
Cary Clarkbc5697d2017-10-04 14:31:33 -04005202default text positions the first glyph left side bearing at origin x and its
Cary Clark8032b982017-07-28 11:04:54 -04005203baseline at origin y. Text size is affected by Matrix and Paint_Text_Size.
5204
Mike Reed8ad91a92018-01-19 19:09:32 -05005205All elements of paint: Path_Effect, Mask_Filter, Shader,
Cary Clarkbad5ad72017-08-03 17:14:08 -04005206Color_Filter, Image_Filter, and Draw_Looper; apply to text. By default, draws
Cary Clarkce101242017-09-01 15:51:02 -04005207filled 12 point black Glyphs.
Cary Clark8032b982017-07-28 11:04:54 -04005208
Cary Clarkce101242017-09-01 15:51:02 -04005209#Param text character code points or Glyphs drawn ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005210#Param byteLength byte length of text array ##
5211#Param path Path providing text baseline ##
5212#Param hOffset distance along path to offset origin ##
5213#Param vOffset offset of text above (if negative) or below (if positive) the path ##
5214#Param paint text size, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005215
5216#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04005217 void draw(SkCanvas* canvas) {
5218 const char aero[] = "correo a" "\xC3" "\xA9" "reo";
5219 const size_t len = sizeof(aero) - 1;
5220 SkPath path;
5221 path.addOval({43-26, 43-26, 43+26, 43+26}, SkPath::kCW_Direction, 3);
5222 SkPaint paint;
5223 paint.setTextSize(24);
5224 for (auto offset : { 0, 10, 20 } ) {
5225 canvas->drawTextOnPathHV(aero, len, path, 0, -offset, paint);
5226 canvas->translate(70 + offset, 70 + offset);
5227 }
5228 }
Cary Clark8032b982017-07-28 11:04:54 -04005229##
5230
Cary Clark2ade9972017-11-02 17:49:34 -04005231#SeeAlso drawTextOnPath drawText drawPosTextH drawTextBlob drawTextRSXform
Cary Clark8032b982017-07-28 11:04:54 -04005232
5233##
5234
5235# ------------------------------------------------------------------------------
5236
5237#Method void drawTextOnPath(const void* text, size_t byteLength, const SkPath& path,
5238 const SkMatrix* matrix, const SkPaint& paint)
Cary Clarkab2621d2018-01-30 10:08:57 -05005239#Line # draws text following Path contour ##
Cary Clark8032b982017-07-28 11:04:54 -04005240
5241Draw text on Path path, using Clip, Matrix, and Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04005242
Cary Clarkbad5ad72017-08-03 17:14:08 -04005243Origin of text is at beginning of path offset by matrix, if provided, before it
5244is mapped to path. If the path section corresponding the glyph advance is
5245curved, the glyph is drawn curved to match; control points in the glyph are
Cary Clarkbc5697d2017-10-04 14:31:33 -04005246mapped to projected points parallel to the path. If the text advance is larger
Cary Clarkbad5ad72017-08-03 17:14:08 -04005247than the path length, the excess text is clipped.
5248
Cary Clarkbc5697d2017-10-04 14:31:33 -04005249text meaning depends on Paint_Text_Encoding; by default, text is encoded as
Cary Clarkbad5ad72017-08-03 17:14:08 -04005250UTF-8. Origin meaning depends on Paint_Text_Align and Paint_Vertical_Text; by
Cary Clarkbc5697d2017-10-04 14:31:33 -04005251default text positions the first glyph left side bearing at origin x and its
Cary Clark8032b982017-07-28 11:04:54 -04005252baseline at origin y. Text size is affected by Matrix and Paint_Text_Size.
5253
Mike Reed8ad91a92018-01-19 19:09:32 -05005254All elements of paint: Path_Effect, Mask_Filter, Shader,
Cary Clarkbad5ad72017-08-03 17:14:08 -04005255Color_Filter, Image_Filter, and Draw_Looper; apply to text. By default, draws
Cary Clarkce101242017-09-01 15:51:02 -04005256filled 12 point black Glyphs.
Cary Clark8032b982017-07-28 11:04:54 -04005257
Cary Clarkce101242017-09-01 15:51:02 -04005258#Param text character code points or Glyphs drawn ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005259#Param byteLength byte length of text array ##
5260#Param path Path providing text baseline ##
Cary Clarkce101242017-09-01 15:51:02 -04005261#Param matrix transform of Glyphs before mapping to path; may be nullptr
Cary Clarka523d2d2017-08-30 08:58:10 -04005262 to use identity Matrix
Cary Clarkbad5ad72017-08-03 17:14:08 -04005263##
5264#Param paint text size, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005265
5266#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04005267 void draw(SkCanvas* canvas) {
5268 const char roller[] = "rollercoaster";
5269 const size_t len = sizeof(roller) - 1;
5270 SkPath path;
5271 path.cubicTo(40, -80, 120, 80, 160, -40);
5272 SkPaint paint;
5273 paint.setTextSize(32);
5274 paint.setStyle(SkPaint::kStroke_Style);
5275 SkMatrix matrix;
5276 matrix.setIdentity();
5277 for (int i = 0; i < 3; ++i) {
5278 canvas->translate(25, 60);
5279 canvas->drawPath(path, paint);
5280 canvas->drawTextOnPath(roller, len, path, &matrix, paint);
5281 matrix.preTranslate(0, 10);
5282 }
5283 }
Cary Clark8032b982017-07-28 11:04:54 -04005284##
5285
Cary Clark2ade9972017-11-02 17:49:34 -04005286#SeeAlso drawTextOnPathHV drawText drawPosTextH drawTextBlob drawTextRSXform
Cary Clark8032b982017-07-28 11:04:54 -04005287
5288##
5289
5290# ------------------------------------------------------------------------------
5291
5292#Method void drawTextRSXform(const void* text, size_t byteLength, const SkRSXform xform[],
5293 const SkRect* cullRect, const SkPaint& paint)
Cary Clarkab2621d2018-01-30 10:08:57 -05005294#Line # draws text with array of RSXform ##
Cary Clark8032b982017-07-28 11:04:54 -04005295
5296Draw text, transforming each glyph by the corresponding SkRSXform,
5297using Clip, Matrix, and Paint paint.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005298
Cary Clark8032b982017-07-28 11:04:54 -04005299RSXform array specifies a separate square scale, rotation, and translation for
5300each glyph.
Cary Clark8032b982017-07-28 11:04:54 -04005301
Cary Clarkbad5ad72017-08-03 17:14:08 -04005302Optional Rect cullRect is a conservative bounds of text, taking into account
Cary Clarkce101242017-09-01 15:51:02 -04005303RSXform and paint. If cullRect is outside of Clip, canvas can skip drawing.
Cary Clark8032b982017-07-28 11:04:54 -04005304
Mike Reed8ad91a92018-01-19 19:09:32 -05005305All elements of paint: Path_Effect, Mask_Filter, Shader,
Cary Clarkbad5ad72017-08-03 17:14:08 -04005306Color_Filter, Image_Filter, and Draw_Looper; apply to text. By default, draws
Cary Clarkce101242017-09-01 15:51:02 -04005307filled 12 point black Glyphs.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005308
Cary Clarkce101242017-09-01 15:51:02 -04005309#Param text character code points or Glyphs drawn ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005310#Param byteLength byte length of text array ##
5311#Param xform RSXform rotates, scales, and translates each glyph individually ##
5312#Param cullRect Rect bounds of text for efficient clipping; or nullptr ##
5313#Param paint text size, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005314
5315#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04005316void draw(SkCanvas* canvas) {
5317 const int iterations = 26;
5318 SkRSXform transforms[iterations];
5319 char alphabet[iterations];
5320 SkScalar angle = 0;
5321 SkScalar scale = 1;
5322 for (size_t i = 0; i < SK_ARRAY_COUNT(transforms); ++i) {
5323 const SkScalar s = SkScalarSin(angle) * scale;
5324 const SkScalar c = SkScalarCos(angle) * scale;
5325 transforms[i] = SkRSXform::Make(-c, -s, -s * 16, c * 16);
5326 angle += .45;
5327 scale += .2;
5328 alphabet[i] = 'A' + i;
5329 }
5330 SkPaint paint;
5331 paint.setTextAlign(SkPaint::kCenter_Align);
5332 canvas->translate(110, 138);
5333 canvas->drawTextRSXform(alphabet, sizeof(alphabet), transforms, nullptr, paint);
Cary Clark8032b982017-07-28 11:04:54 -04005334}
5335##
5336
Cary Clark2ade9972017-11-02 17:49:34 -04005337#SeeAlso drawTextOnPath drawTextOnPathHV drawText drawPosText drawTextBlob
Cary Clark8032b982017-07-28 11:04:54 -04005338
5339##
5340
5341# ------------------------------------------------------------------------------
5342
5343#Method void drawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y, const SkPaint& paint)
5344
Cary Clarkab2621d2018-01-30 10:08:57 -05005345#Line # draws text with arrays of positions and Paint ##
Cary Clark8032b982017-07-28 11:04:54 -04005346Draw Text_Blob blob at (x, y), using Clip, Matrix, and Paint paint.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005347
Cary Clarkce101242017-09-01 15:51:02 -04005348blob contains Glyphs, their positions, and paint attributes specific to text:
Cary Clarkbad5ad72017-08-03 17:14:08 -04005349Typeface, Paint_Text_Size, Paint_Text_Scale_X, Paint_Text_Skew_X,
5350Paint_Text_Align, Paint_Hinting, Anti-alias, Paint_Fake_Bold,
5351Font_Embedded_Bitmaps, Full_Hinting_Spacing, LCD_Text, Linear_Text,
5352Subpixel_Text, and Paint_Vertical_Text.
Cary Clark8032b982017-07-28 11:04:54 -04005353
Cary Clark3cd22cc2017-12-01 11:49:58 -05005354Paint_Text_Encoding must be set to SkPaint::kGlyphID_TextEncoding.
5355
Mike Reed8ad91a92018-01-19 19:09:32 -05005356Elements of paint: Path_Effect, Mask_Filter, Shader, Color_Filter,
Cary Clark8032b982017-07-28 11:04:54 -04005357Image_Filter, and Draw_Looper; apply to blob.
5358
Cary Clarkce101242017-09-01 15:51:02 -04005359#Param blob Glyphs, positions, and their paints' text size, typeface, and so on ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005360#Param x horizontal offset applied to blob ##
5361#Param y vertical offset applied to blob ##
5362#Param paint blend, color, stroking, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005363
5364#Example
5365#Height 120
Cary Clarkbad5ad72017-08-03 17:14:08 -04005366 void draw(SkCanvas* canvas) {
Cary Clark2f466242017-12-11 16:03:17 -05005367 SkTextBlobBuilder textBlobBuilder;
5368 const char bunny[] = "/(^x^)\\";
5369 const int len = sizeof(bunny) - 1;
5370 uint16_t glyphs[len];
5371 SkPaint paint;
5372 paint.textToGlyphs(bunny, len, glyphs);
Cary Clark3cd22cc2017-12-01 11:49:58 -05005373 paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
Cary Clark2f466242017-12-11 16:03:17 -05005374 int runs[] = { 3, 1, 3 };
5375 SkPoint textPos = { 20, 100 };
5376 int glyphIndex = 0;
5377 for (auto runLen : runs) {
5378 paint.setTextSize(1 == runLen ? 20 : 50);
5379 const SkTextBlobBuilder::RunBuffer& run =
5380 textBlobBuilder.allocRun(paint, runLen, textPos.fX, textPos.fY);
5381 memcpy(run.glyphs, &glyphs[glyphIndex], sizeof(glyphs[0]) * runLen);
5382 textPos.fX += paint.measureText(&glyphs[glyphIndex], sizeof(glyphs[0]) * runLen, nullptr);
5383 glyphIndex += runLen;
5384 }
5385 sk_sp<const SkTextBlob> blob = textBlobBuilder.make();
5386 paint.reset();
Cary Clarkbad5ad72017-08-03 17:14:08 -04005387 canvas->drawTextBlob(blob.get(), 0, 0, paint);
Cary Clark8032b982017-07-28 11:04:54 -04005388 }
5389##
5390
Cary Clark2ade9972017-11-02 17:49:34 -04005391#SeeAlso drawText drawPosText drawPosTextH
Cary Clark8032b982017-07-28 11:04:54 -04005392
5393##
5394
5395# ------------------------------------------------------------------------------
5396
5397#Method void drawTextBlob(const sk_sp<SkTextBlob>& blob, SkScalar x, SkScalar y, const SkPaint& paint)
5398
5399Draw Text_Blob blob at (x, y), using Clip, Matrix, and Paint paint.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005400
Cary Clarkce101242017-09-01 15:51:02 -04005401blob contains Glyphs, their positions, and paint attributes specific to text:
Cary Clarkbad5ad72017-08-03 17:14:08 -04005402Typeface, Paint_Text_Size, Paint_Text_Scale_X, Paint_Text_Skew_X,
5403Paint_Text_Align, Paint_Hinting, Anti-alias, Paint_Fake_Bold,
5404Font_Embedded_Bitmaps, Full_Hinting_Spacing, LCD_Text, Linear_Text,
5405Subpixel_Text, and Paint_Vertical_Text.
Cary Clark8032b982017-07-28 11:04:54 -04005406
Cary Clark3cd22cc2017-12-01 11:49:58 -05005407Paint_Text_Encoding must be set to SkPaint::kGlyphID_TextEncoding.
5408
Mike Reed8ad91a92018-01-19 19:09:32 -05005409Elements of paint: Path_Effect, Mask_Filter, Shader, Color_Filter,
Cary Clark8032b982017-07-28 11:04:54 -04005410Image_Filter, and Draw_Looper; apply to blob.
5411
Cary Clarkce101242017-09-01 15:51:02 -04005412#Param blob Glyphs, positions, and their paints' text size, typeface, and so on ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005413#Param x horizontal offset applied to blob ##
5414#Param y vertical offset applied to blob ##
5415#Param paint blend, color, stroking, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005416
5417#Example
5418#Height 120
5419#Description
5420Paint attributes unrelated to text, like color, have no effect on paint in allocated Text_Blob.
5421Paint attributes related to text, like text size, have no effect on paint passed to drawTextBlob.
5422##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005423 void draw(SkCanvas* canvas) {
5424 SkTextBlobBuilder textBlobBuilder;
5425 SkPaint paint;
5426 paint.setTextSize(50);
5427 paint.setColor(SK_ColorRED);
Cary Clark2f466242017-12-11 16:03:17 -05005428 paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
Cary Clarkbad5ad72017-08-03 17:14:08 -04005429 const SkTextBlobBuilder::RunBuffer& run =
5430 textBlobBuilder.allocRun(paint, 1, 20, 100);
5431 run.glyphs[0] = 20;
5432 sk_sp<const SkTextBlob> blob = textBlobBuilder.make();
5433 paint.setTextSize(10);
5434 paint.setColor(SK_ColorBLUE);
5435 canvas->drawTextBlob(blob.get(), 0, 0, paint);
5436 }
Cary Clark8032b982017-07-28 11:04:54 -04005437##
5438
Cary Clark2ade9972017-11-02 17:49:34 -04005439#SeeAlso drawText drawPosText drawPosTextH
Cary Clark8032b982017-07-28 11:04:54 -04005440
5441##
5442
5443# ------------------------------------------------------------------------------
5444
5445#Method void drawPicture(const SkPicture* picture)
5446
Cary Clarkab2621d2018-01-30 10:08:57 -05005447#Line # draws Picture using Clip and Matrix ##
Cary Clark8032b982017-07-28 11:04:54 -04005448Draw Picture picture, using Clip and Matrix.
5449Clip and Matrix are unchanged by picture contents, as if
5450save() was called before and restore() was called after drawPicture.
5451
5452Picture records a series of draw commands for later playback.
5453
Cary Clarkbad5ad72017-08-03 17:14:08 -04005454#Param picture recorded drawing commands to play ##
Cary Clark8032b982017-07-28 11:04:54 -04005455
5456#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04005457void draw(SkCanvas* canvas) {
5458 SkPictureRecorder recorder;
5459 SkCanvas* recordingCanvas = recorder.beginRecording(50, 50);
5460 for (auto color : { SK_ColorRED, SK_ColorBLUE, 0xff007f00 } ) {
5461 SkPaint paint;
5462 paint.setColor(color);
5463 recordingCanvas->drawRect({10, 10, 30, 40}, paint);
5464 recordingCanvas->translate(10, 10);
5465 recordingCanvas->scale(1.2f, 1.4f);
5466 }
5467 sk_sp<SkPicture> playback = recorder.finishRecordingAsPicture();
5468 const SkPicture* playbackPtr = playback.get();
5469 canvas->drawPicture(playback);
5470 canvas->scale(2, 2);
5471 canvas->translate(50, 0);
5472 canvas->drawPicture(playback);
Cary Clark8032b982017-07-28 11:04:54 -04005473}
5474##
5475
Cary Clark2ade9972017-11-02 17:49:34 -04005476#SeeAlso drawDrawable SkPicture SkPicture::playback
Cary Clark8032b982017-07-28 11:04:54 -04005477
5478##
5479
5480# ------------------------------------------------------------------------------
5481
5482#Method void drawPicture(const sk_sp<SkPicture>& picture)
5483
5484Draw Picture picture, using Clip and Matrix.
5485Clip and Matrix are unchanged by picture contents, as if
5486save() was called before and restore() was called after drawPicture.
5487
5488Picture records a series of draw commands for later playback.
5489
Cary Clarkbad5ad72017-08-03 17:14:08 -04005490#Param picture recorded drawing commands to play ##
Cary Clark8032b982017-07-28 11:04:54 -04005491
5492#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04005493void draw(SkCanvas* canvas) {
5494 SkPictureRecorder recorder;
5495 SkCanvas* recordingCanvas = recorder.beginRecording(50, 50);
5496 for (auto color : { SK_ColorRED, SK_ColorBLUE, 0xff007f00 } ) {
5497 SkPaint paint;
5498 paint.setColor(color);
5499 recordingCanvas->drawRect({10, 10, 30, 40}, paint);
5500 recordingCanvas->translate(10, 10);
5501 recordingCanvas->scale(1.2f, 1.4f);
5502 }
5503 sk_sp<SkPicture> playback = recorder.finishRecordingAsPicture();
5504 canvas->drawPicture(playback);
5505 canvas->scale(2, 2);
5506 canvas->translate(50, 0);
5507 canvas->drawPicture(playback);
Cary Clark8032b982017-07-28 11:04:54 -04005508}
5509##
5510
Cary Clark2ade9972017-11-02 17:49:34 -04005511#SeeAlso drawDrawable SkPicture SkPicture::playback
Cary Clark8032b982017-07-28 11:04:54 -04005512
5513##
5514
5515# ------------------------------------------------------------------------------
5516
5517#Method void drawPicture(const SkPicture* picture, const SkMatrix* matrix, const SkPaint* paint)
5518
Cary Clarkbad5ad72017-08-03 17:14:08 -04005519Draw Picture picture, using Clip and Matrix; transforming picture with
5520Matrix matrix, if provided; and use Paint paint Color_Alpha, Color_Filter,
5521Image_Filter, and Blend_Mode, if provided.
Cary Clark8032b982017-07-28 11:04:54 -04005522
5523matrix transformation is equivalent to: save(), concat(), drawPicture, restore().
5524paint use is equivalent to: saveLayer, drawPicture, restore().
5525
Cary Clarkbad5ad72017-08-03 17:14:08 -04005526#Param picture recorded drawing commands to play ##
5527#Param matrix Matrix to rotate, scale, translate, and so on; may be nullptr ##
5528#Param paint Paint to apply transparency, filtering, and so on; may be nullptr ##
Cary Clark8032b982017-07-28 11:04:54 -04005529
5530#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04005531void draw(SkCanvas* canvas) {
5532 SkPaint paint;
5533 SkPictureRecorder recorder;
5534 SkCanvas* recordingCanvas = recorder.beginRecording(50, 50);
5535 for (auto color : { SK_ColorRED, SK_ColorBLUE, 0xff007f00 } ) {
5536 paint.setColor(color);
5537 recordingCanvas->drawRect({10, 10, 30, 40}, paint);
5538 recordingCanvas->translate(10, 10);
5539 recordingCanvas->scale(1.2f, 1.4f);
5540 }
5541 sk_sp<SkPicture> playback = recorder.finishRecordingAsPicture();
5542 const SkPicture* playbackPtr = playback.get();
5543 SkMatrix matrix;
5544 matrix.reset();
5545 for (auto alpha : { 70, 140, 210 } ) {
5546 paint.setAlpha(alpha);
5547 canvas->drawPicture(playbackPtr, &matrix, &paint);
5548 matrix.preTranslate(70, 70);
5549 }
Cary Clark8032b982017-07-28 11:04:54 -04005550}
5551##
5552
Cary Clark2ade9972017-11-02 17:49:34 -04005553#SeeAlso drawDrawable SkPicture SkPicture::playback
Cary Clark8032b982017-07-28 11:04:54 -04005554
5555##
5556
5557# ------------------------------------------------------------------------------
5558
5559#Method void drawPicture(const sk_sp<SkPicture>& picture, const SkMatrix* matrix, const SkPaint* paint)
5560
Cary Clarkbad5ad72017-08-03 17:14:08 -04005561Draw Picture picture, using Clip and Matrix; transforming picture with
5562Matrix matrix, if provided; and use Paint paint Color_Alpha, Color_Filter,
5563Image_Filter, and Blend_Mode, if provided.
Cary Clark8032b982017-07-28 11:04:54 -04005564
5565matrix transformation is equivalent to: save(), concat(), drawPicture, restore().
5566paint use is equivalent to: saveLayer, drawPicture, restore().
5567
Cary Clarkbad5ad72017-08-03 17:14:08 -04005568#Param picture recorded drawing commands to play ##
5569#Param matrix Matrix to rotate, scale, translate, and so on; may be nullptr ##
5570#Param paint Paint to apply transparency, filtering, and so on; may be nullptr ##
Cary Clark8032b982017-07-28 11:04:54 -04005571
5572#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04005573void draw(SkCanvas* canvas) {
5574 SkPaint paint;
5575 SkPictureRecorder recorder;
5576 SkCanvas* recordingCanvas = recorder.beginRecording(50, 50);
5577 for (auto color : { SK_ColorRED, SK_ColorBLUE, 0xff007f00 } ) {
5578 paint.setColor(color);
5579 recordingCanvas->drawRect({10, 10, 30, 40}, paint);
5580 recordingCanvas->translate(10, 10);
5581 recordingCanvas->scale(1.2f, 1.4f);
5582 }
5583 sk_sp<SkPicture> playback = recorder.finishRecordingAsPicture();
5584 SkMatrix matrix;
5585 matrix.reset();
5586 for (auto alpha : { 70, 140, 210 } ) {
5587 paint.setAlpha(alpha);
5588 canvas->drawPicture(playback, &matrix, &paint);
5589 matrix.preTranslate(70, 70);
5590 }
Cary Clark8032b982017-07-28 11:04:54 -04005591}
5592##
5593
Cary Clark2ade9972017-11-02 17:49:34 -04005594#SeeAlso drawDrawable SkPicture SkPicture::playback
Cary Clark8032b982017-07-28 11:04:54 -04005595
5596##
5597
5598# ------------------------------------------------------------------------------
5599
5600#Method void drawVertices(const SkVertices* vertices, SkBlendMode mode, const SkPaint& paint)
5601
Cary Clarkab2621d2018-01-30 10:08:57 -05005602#Line # draws Vertices, a triangle mesh ##
Cary Clark8032b982017-07-28 11:04:54 -04005603Draw Vertices vertices, a triangle mesh, using Clip and Matrix.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005604If Vertices_Texs and Vertices_Colors are defined in vertices, and Paint paint
5605contains Shader, Blend_Mode mode combines Vertices_Colors with Shader.
Cary Clark8032b982017-07-28 11:04:54 -04005606
Cary Clarkbad5ad72017-08-03 17:14:08 -04005607#Param vertices triangle mesh to draw ##
5608#Param mode combines Vertices_Colors with Shader, if both are present ##
5609#Param paint specifies the Shader, used as Vertices texture; may be nullptr ##
Cary Clark8032b982017-07-28 11:04:54 -04005610
5611#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04005612void draw(SkCanvas* canvas) {
5613 SkPaint paint;
5614 SkPoint points[] = { { 0, 0 }, { 250, 0 }, { 100, 100 }, { 0, 250 } };
5615 SkColor colors[] = { SK_ColorRED, SK_ColorBLUE, SK_ColorYELLOW, SK_ColorCYAN };
5616 auto vertices = SkVertices::MakeCopy(SkVertices::kTriangleFan_VertexMode,
5617 SK_ARRAY_COUNT(points), points, nullptr, colors);
5618 canvas->drawVertices(vertices.get(), SkBlendMode::kSrc, paint);
5619}
Cary Clark8032b982017-07-28 11:04:54 -04005620##
5621
Cary Clark2ade9972017-11-02 17:49:34 -04005622#SeeAlso drawPatch drawPicture
Cary Clark8032b982017-07-28 11:04:54 -04005623
5624##
5625
5626# ------------------------------------------------------------------------------
5627
5628#Method void drawVertices(const sk_sp<SkVertices>& vertices, SkBlendMode mode, const SkPaint& paint)
5629
5630Draw Vertices vertices, a triangle mesh, using Clip and Matrix.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005631If Vertices_Texs and Vertices_Colors are defined in vertices, and Paint paint
5632contains Shader, Blend_Mode mode combines Vertices_Colors with Shader.
Cary Clark8032b982017-07-28 11:04:54 -04005633
Cary Clarkbad5ad72017-08-03 17:14:08 -04005634#Param vertices triangle mesh to draw ##
5635#Param mode combines Vertices_Colors with Shader, if both are present ##
5636#Param paint specifies the Shader, used as Vertices texture, may be nullptr ##
Cary Clark8032b982017-07-28 11:04:54 -04005637
5638#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04005639void draw(SkCanvas* canvas) {
5640 SkPaint paint;
5641 SkPoint points[] = { { 0, 0 }, { 250, 0 }, { 100, 100 }, { 0, 250 } };
5642 SkPoint texs[] = { { 0, 0 }, { 0, 250 }, { 250, 250 }, { 250, 0 } };
5643 SkColor colors[] = { SK_ColorRED, SK_ColorBLUE, SK_ColorYELLOW, SK_ColorCYAN };
5644 paint.setShader(SkGradientShader::MakeLinear(points, colors, nullptr, 4,
5645 SkShader::kClamp_TileMode));
5646 auto vertices = SkVertices::MakeCopy(SkVertices::kTriangleFan_VertexMode,
5647 SK_ARRAY_COUNT(points), points, texs, colors);
5648 canvas->drawVertices(vertices.get(), SkBlendMode::kDarken, paint);
Cary Clark8032b982017-07-28 11:04:54 -04005649}
5650##
5651
Cary Clark2ade9972017-11-02 17:49:34 -04005652#SeeAlso drawPatch drawPicture
Cary Clark8032b982017-07-28 11:04:54 -04005653
5654##
5655
5656# ------------------------------------------------------------------------------
5657
5658#Method void drawPatch(const SkPoint cubics[12], const SkColor colors[4],
5659 const SkPoint texCoords[4], SkBlendMode mode, const SkPaint& paint)
Cary Clarkab2621d2018-01-30 10:08:57 -05005660#Line # draws Coons_Patch ##
Cary Clark8032b982017-07-28 11:04:54 -04005661
Cary Clarka560c472017-11-27 10:44:06 -05005662Draws a Coons_Patch: the interpolation of four cubics with shared corners,
Cary Clark8032b982017-07-28 11:04:54 -04005663associating a color, and optionally a texture coordinate, with each corner.
5664
Cary Clarka560c472017-11-27 10:44:06 -05005665Coons_Patch uses Clip and Matrix, paint Shader, Color_Filter,
Cary Clarkbad5ad72017-08-03 17:14:08 -04005666Color_Alpha, Image_Filter, and Blend_Mode. If Shader is provided it is treated
Cary Clarka560c472017-11-27 10:44:06 -05005667as Coons_Patch texture; Blend_Mode mode combines Color colors and Shader if
Cary Clarkbad5ad72017-08-03 17:14:08 -04005668both are provided.
Cary Clark8032b982017-07-28 11:04:54 -04005669
Cary Clarkbc5697d2017-10-04 14:31:33 -04005670Point array cubics specifies four Cubics starting at the top-left corner,
Cary Clarkce101242017-09-01 15:51:02 -04005671in clockwise order, sharing every fourth point. The last Cubic ends at the
Cary Clarkbad5ad72017-08-03 17:14:08 -04005672first point.
Cary Clark8032b982017-07-28 11:04:54 -04005673
Cary Clarkbc5697d2017-10-04 14:31:33 -04005674Color array color associates colors with corners in top-left, top-right,
5675bottom-right, bottom-left order.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005676
5677If paint contains Shader, Point array texCoords maps Shader as texture to
Cary Clarkbc5697d2017-10-04 14:31:33 -04005678corners in top-left, top-right, bottom-right, bottom-left order.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005679
Cary Clarka523d2d2017-08-30 08:58:10 -04005680#Param cubics Path_Cubic array, sharing common points ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005681#Param colors Color array, one for each corner ##
Cary Clarkce101242017-09-01 15:51:02 -04005682#Param texCoords Point array of texture coordinates, mapping Shader to corners;
Cary Clarkbad5ad72017-08-03 17:14:08 -04005683 may be nullptr
Cary Clark579985c2017-07-31 11:48:27 -04005684#Param ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005685#Param mode Blend_Mode for colors, and for Shader if paint has one ##
5686#Param paint Shader, Color_Filter, Blend_Mode, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005687
5688#Example
5689#Image 5
Cary Clarkbad5ad72017-08-03 17:14:08 -04005690void draw(SkCanvas* canvas) {
5691 // SkBitmap source = cmbkygk;
5692 SkPaint paint;
5693 paint.setFilterQuality(kLow_SkFilterQuality);
5694 paint.setAntiAlias(true);
5695 SkPoint cubics[] = { { 3, 1 }, { 4, 2 }, { 5, 1 }, { 7, 3 },
5696 /* { 7, 3 }, */ { 6, 4 }, { 7, 5 }, { 5, 7 },
5697 /* { 5, 7 }, */ { 4, 6 }, { 3, 7 }, { 1, 5 },
5698 /* { 1, 5 }, */ { 2, 4 }, { 1, 3 }, /* { 3, 1 } */ };
5699 SkColor colors[] = { 0xbfff0000, 0xbf0000ff, 0xbfff00ff, 0xbf00ffff };
5700 SkPoint texCoords[] = { { -30, -30 }, { 162, -30}, { 162, 162}, { -30, 162} };
5701 paint.setShader(SkShader::MakeBitmapShader(source, SkShader::kClamp_TileMode,
5702 SkShader::kClamp_TileMode, nullptr));
5703 canvas->scale(15, 15);
5704 for (auto blend : { SkBlendMode::kSrcOver, SkBlendMode::kModulate, SkBlendMode::kXor } ) {
5705 canvas->drawPatch(cubics, colors, texCoords, blend, paint);
5706 canvas->translate(4, 4);
5707 }
Cary Clark8032b982017-07-28 11:04:54 -04005708}
5709##
5710
Cary Clark2ade9972017-11-02 17:49:34 -04005711#ToDo can patch use image filter? ##
5712#SeeAlso SeeAlso drawVertices drawPicture
Cary Clark8032b982017-07-28 11:04:54 -04005713
5714##
5715
5716# ------------------------------------------------------------------------------
5717
5718#Method void drawPatch(const SkPoint cubics[12], const SkColor colors[4],
5719 const SkPoint texCoords[4], const SkPaint& paint)
5720
Cary Clarka560c472017-11-27 10:44:06 -05005721Draws Cubic Coons_Patch: the interpolation of four cubics with shared corners,
Cary Clarkbad5ad72017-08-03 17:14:08 -04005722associating a color, and optionally a texture coordinate, with each corner.
Cary Clark8032b982017-07-28 11:04:54 -04005723
Cary Clarka560c472017-11-27 10:44:06 -05005724Coons_Patch uses Clip and Matrix, paint Shader, Color_Filter,
Cary Clarkbad5ad72017-08-03 17:14:08 -04005725Color_Alpha, Image_Filter, and Blend_Mode. If Shader is provided it is treated
Cary Clarka560c472017-11-27 10:44:06 -05005726as Coons_Patch texture; Blend_Mode mode combines Color colors and Shader if
Cary Clarkbad5ad72017-08-03 17:14:08 -04005727both are provided.
Cary Clark8032b982017-07-28 11:04:54 -04005728
Cary Clarkbc5697d2017-10-04 14:31:33 -04005729Point array cubics specifies four Cubics starting at the top-left corner,
Cary Clarkce101242017-09-01 15:51:02 -04005730in clockwise order, sharing every fourth point. The last Cubic ends at the
Cary Clarkbad5ad72017-08-03 17:14:08 -04005731first point.
5732
Cary Clarkbc5697d2017-10-04 14:31:33 -04005733Color array color associates colors with corners in top-left, top-right,
5734bottom-right, bottom-left order.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005735
5736If paint contains Shader, Point array texCoords maps Shader as texture to
Cary Clarkbc5697d2017-10-04 14:31:33 -04005737corners in top-left, top-right, bottom-right, bottom-left order.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005738
Cary Clarka523d2d2017-08-30 08:58:10 -04005739#Param cubics Path_Cubic array, sharing common points ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005740#Param colors Color array, one for each corner ##
Cary Clarkce101242017-09-01 15:51:02 -04005741#Param texCoords Point array of texture coordinates, mapping Shader to corners;
Cary Clarkbad5ad72017-08-03 17:14:08 -04005742 may be nullptr
Cary Clark579985c2017-07-31 11:48:27 -04005743#Param ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005744#Param paint Shader, Color_Filter, Blend_Mode, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005745
5746#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04005747void draw(SkCanvas* canvas) {
5748 SkPaint paint;
5749 paint.setAntiAlias(true);
5750 SkPoint cubics[] = { { 3, 1 }, { 4, 2 }, { 5, 1 }, { 7, 3 },
5751 /* { 7, 3 }, */ { 6, 4 }, { 7, 5 }, { 5, 7 },
5752 /* { 5, 7 }, */ { 4, 6 }, { 3, 7 }, { 1, 5 },
5753 /* { 1, 5 }, */ { 2, 4 }, { 1, 3 }, /* { 3, 1 } */ };
5754 SkColor colors[] = { SK_ColorRED, SK_ColorBLUE, SK_ColorYELLOW, SK_ColorCYAN };
5755 canvas->scale(30, 30);
5756 canvas->drawPatch(cubics, colors, nullptr, paint);
5757 SkPoint text[] = { {3,0.9f}, {4,2.5f}, {5,0.9f}, {7.5f,3.2f}, {5.5f,4.2f},
5758 {7.5f,5.2f}, {5,7.5f}, {4,5.9f}, {3,7.5f}, {0.5f,5.2f}, {2.5f,4.2f},
5759 {0.5f,3.2f} };
5760 paint.setTextSize(18.f / 30);
5761 paint.setTextAlign(SkPaint::kCenter_Align);
5762 for (int i = 0; i< 10; ++i) {
5763 char digit = '0' + i;
5764 canvas->drawText(&digit, 1, text[i].fX, text[i].fY, paint);
5765 }
5766 canvas->drawString("10", text[10].fX, text[10].fY, paint);
5767 canvas->drawString("11", text[11].fX, text[11].fY, paint);
5768 paint.setStyle(SkPaint::kStroke_Style);
5769 canvas->drawPoints(SkCanvas::kPolygon_PointMode, 12, cubics, paint);
5770 canvas->drawLine(cubics[11].fX, cubics[11].fY, cubics[0].fX, cubics[0].fY, paint);
Cary Clark8032b982017-07-28 11:04:54 -04005771}
5772##
5773
5774#Example
5775#Image 6
Cary Clarkbad5ad72017-08-03 17:14:08 -04005776void draw(SkCanvas* canvas) {
5777 // SkBitmap source = checkerboard;
5778 SkPaint paint;
5779 paint.setFilterQuality(kLow_SkFilterQuality);
5780 paint.setAntiAlias(true);
5781 SkPoint cubics[] = { { 3, 1 }, { 4, 2 }, { 5, 1 }, { 7, 3 },
5782 /* { 7, 3 }, */ { 6, 4 }, { 7, 5 }, { 5, 7 },
5783 /* { 5, 7 }, */ { 4, 6 }, { 3, 7 }, { 1, 5 },
5784 /* { 1, 5 }, */ { 2, 4 }, { 1, 3 }, /* { 3, 1 } */ };
5785 SkPoint texCoords[] = { { 0, 0 }, { 0, 62}, { 62, 62}, { 62, 0 } };
5786 paint.setShader(SkShader::MakeBitmapShader(source, SkShader::kClamp_TileMode,
5787 SkShader::kClamp_TileMode, nullptr));
5788 canvas->scale(30, 30);
5789 canvas->drawPatch(cubics, nullptr, texCoords, paint);
Cary Clark8032b982017-07-28 11:04:54 -04005790}
5791##
5792
Cary Clark2ade9972017-11-02 17:49:34 -04005793#ToDo can patch use image filter? ##
5794#SeeAlso SeeAlso drawVertices drawPicture
Cary Clark8032b982017-07-28 11:04:54 -04005795
5796##
5797
5798# ------------------------------------------------------------------------------
5799
5800#Method void drawAtlas(const SkImage* atlas, const SkRSXform xform[], const SkRect tex[],
5801 const SkColor colors[], int count, SkBlendMode mode, const SkRect* cullRect,
5802 const SkPaint* paint)
Cary Clarkab2621d2018-01-30 10:08:57 -05005803#Line # draws sprites using Clip, Matrix, and Paint ##
Cary Clark8032b982017-07-28 11:04:54 -04005804
5805Draw a set of sprites from atlas, using Clip, Matrix, and optional Paint paint.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005806paint uses Anti-alias, Color_Alpha, Color_Filter, Image_Filter, and Blend_Mode
5807to draw, if present. For each entry in the array, Rect tex locates sprite in
5808atlas, and RSXform xform transforms it into destination space.
5809
Cary Clark8032b982017-07-28 11:04:54 -04005810xform, text, and colors if present, must contain count entries.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005811Optional colors are applied for each sprite using Blend_Mode.
Cary Clark8032b982017-07-28 11:04:54 -04005812Optional cullRect is a conservative bounds of all transformed sprites.
Cary Clarkce101242017-09-01 15:51:02 -04005813If cullRect is outside of Clip, canvas can skip drawing.
Cary Clark8032b982017-07-28 11:04:54 -04005814
Cary Clarkbad5ad72017-08-03 17:14:08 -04005815#Param atlas Image containing sprites ##
5816#Param xform RSXform mappings for sprites in atlas ##
5817#Param tex Rect locations of sprites in atlas ##
Cary Clark6fc50412017-09-21 12:31:06 -04005818#Param colors one per sprite, blended with sprite using Blend_Mode; may be nullptr ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005819#Param count number of sprites to draw ##
5820#Param mode Blend_Mode combining colors and sprites ##
Cary Clark6fc50412017-09-21 12:31:06 -04005821#Param cullRect bounds of transformed sprites for efficient clipping; may be nullptr ##
5822#Param paint Color_Filter, Image_Filter, Blend_Mode, and so on; may be nullptr ##
Cary Clark8032b982017-07-28 11:04:54 -04005823
5824#Example
5825#Image 3
Cary Clarkbad5ad72017-08-03 17:14:08 -04005826void draw(SkCanvas* canvas) {
5827 // SkBitmap source = mandrill;
5828 SkRSXform xforms[] = { { .5f, 0, 0, 0 }, {0, .5f, 200, 100 } };
5829 SkRect tex[] = { { 0, 0, 250, 250 }, { 0, 0, 250, 250 } };
5830 SkColor colors[] = { 0x7f55aa00, 0x7f3333bf };
5831 const SkImage* imagePtr = image.get();
5832 canvas->drawAtlas(imagePtr, xforms, tex, colors, 2, SkBlendMode::kSrcOver, nullptr, nullptr);
Cary Clark8032b982017-07-28 11:04:54 -04005833}
5834##
5835
Cary Clark2ade9972017-11-02 17:49:34 -04005836#SeeAlso drawBitmap drawImage
Cary Clark8032b982017-07-28 11:04:54 -04005837
5838##
5839
5840# ------------------------------------------------------------------------------
5841
5842#Method void drawAtlas(const sk_sp<SkImage>& atlas, const SkRSXform xform[], const SkRect tex[],
5843 const SkColor colors[], int count, SkBlendMode mode, const SkRect* cullRect,
5844 const SkPaint* paint)
5845
5846Draw a set of sprites from atlas, using Clip, Matrix, and optional Paint paint.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005847paint uses Anti-alias, Color_Alpha, Color_Filter, Image_Filter, and Blend_Mode
5848to draw, if present. For each entry in the array, Rect tex locates sprite in
5849atlas, and RSXform xform transforms it into destination space.
5850
Cary Clark8032b982017-07-28 11:04:54 -04005851xform, text, and colors if present, must contain count entries.
5852Optional colors is applied for each sprite using Blend_Mode.
5853Optional cullRect is a conservative bounds of all transformed sprites.
Cary Clarkce101242017-09-01 15:51:02 -04005854If cullRect is outside of Clip, canvas can skip drawing.
Cary Clark8032b982017-07-28 11:04:54 -04005855
Cary Clarkbad5ad72017-08-03 17:14:08 -04005856#Param atlas Image containing sprites ##
5857#Param xform RSXform mappings for sprites in atlas ##
5858#Param tex Rect locations of sprites in atlas ##
Cary Clark6fc50412017-09-21 12:31:06 -04005859#Param colors one per sprite, blended with sprite using Blend_Mode; may be nullptr ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005860#Param count number of sprites to draw ##
5861#Param mode Blend_Mode combining colors and sprites ##
Cary Clark6fc50412017-09-21 12:31:06 -04005862#Param cullRect bounds of transformed sprites for efficient clipping; may be nullptr ##
5863#Param paint Color_Filter, Image_Filter, Blend_Mode, and so on; may be nullptr ##
Cary Clark8032b982017-07-28 11:04:54 -04005864
5865#Example
5866#Image 3
Cary Clarkbad5ad72017-08-03 17:14:08 -04005867void draw(SkCanvas* canvas) {
5868 // SkBitmap source = mandrill;
5869 SkRSXform xforms[] = { { .5f, 0, 0, 0 }, {0, .5f, 200, 100 } };
5870 SkRect tex[] = { { 0, 0, 250, 250 }, { 0, 0, 250, 250 } };
5871 SkColor colors[] = { 0x7f55aa00, 0x7f3333bf };
5872 SkPaint paint;
5873 paint.setAlpha(127);
5874 canvas->drawAtlas(image, xforms, tex, colors, 2, SkBlendMode::kPlus, nullptr, &paint);
Cary Clark8032b982017-07-28 11:04:54 -04005875}
5876##
5877
5878#ToDo bug in example on cpu side, gpu looks ok ##
5879
Cary Clark2ade9972017-11-02 17:49:34 -04005880#SeeAlso drawBitmap drawImage
5881
Cary Clark8032b982017-07-28 11:04:54 -04005882##
5883
5884# ------------------------------------------------------------------------------
5885
5886#Method void drawAtlas(const SkImage* atlas, const SkRSXform xform[], const SkRect tex[], int count,
5887 const SkRect* cullRect, const SkPaint* paint)
5888
5889Draw a set of sprites from atlas, using Clip, Matrix, and optional Paint paint.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005890paint uses Anti-alias, Color_Alpha, Color_Filter, Image_Filter, and Blend_Mode
5891to draw, if present. For each entry in the array, Rect tex locates sprite in
5892atlas, and RSXform xform transforms it into destination space.
5893
Cary Clark8032b982017-07-28 11:04:54 -04005894xform and text must contain count entries.
5895Optional cullRect is a conservative bounds of all transformed sprites.
Cary Clarkce101242017-09-01 15:51:02 -04005896If cullRect is outside of Clip, canvas can skip drawing.
Cary Clark8032b982017-07-28 11:04:54 -04005897
Cary Clarkbad5ad72017-08-03 17:14:08 -04005898#Param atlas Image containing sprites ##
5899#Param xform RSXform mappings for sprites in atlas ##
5900#Param tex Rect locations of sprites in atlas ##
5901#Param count number of sprites to draw ##
Cary Clark6fc50412017-09-21 12:31:06 -04005902#Param cullRect bounds of transformed sprites for efficient clipping; may be nullptr ##
5903#Param paint Color_Filter, Image_Filter, Blend_Mode, and so on; may be nullptr ##
Cary Clark8032b982017-07-28 11:04:54 -04005904
5905#Example
5906#Image 3
Cary Clarkbad5ad72017-08-03 17:14:08 -04005907void draw(SkCanvas* canvas) {
5908 // sk_sp<SkImage> image = mandrill;
5909 SkRSXform xforms[] = { { .5f, 0, 0, 0 }, {0, .5f, 200, 100 } };
5910 SkRect tex[] = { { 0, 0, 250, 250 }, { 0, 0, 250, 250 } };
5911 const SkImage* imagePtr = image.get();
5912 canvas->drawAtlas(imagePtr, xforms, tex, 2, nullptr, nullptr);
Cary Clark8032b982017-07-28 11:04:54 -04005913}
5914##
5915
Cary Clark2ade9972017-11-02 17:49:34 -04005916#SeeAlso drawBitmap drawImage
Cary Clark8032b982017-07-28 11:04:54 -04005917
5918##
5919
5920# ------------------------------------------------------------------------------
5921
5922#Method void drawAtlas(const sk_sp<SkImage>& atlas, const SkRSXform xform[], const SkRect tex[],
5923 int count, const SkRect* cullRect, const SkPaint* paint)
5924
5925Draw a set of sprites from atlas, using Clip, Matrix, and optional Paint paint.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005926paint uses Anti-alias, Color_Alpha, Color_Filter, Image_Filter, and Blend_Mode
5927to draw, if present. For each entry in the array, Rect tex locates sprite in
5928atlas, and RSXform xform transforms it into destination space.
5929
Cary Clark8032b982017-07-28 11:04:54 -04005930xform and text must contain count entries.
5931Optional cullRect is a conservative bounds of all transformed sprites.
Cary Clarkce101242017-09-01 15:51:02 -04005932If cullRect is outside of Clip, canvas can skip drawing.
Cary Clark8032b982017-07-28 11:04:54 -04005933
Cary Clarkbad5ad72017-08-03 17:14:08 -04005934#Param atlas Image containing sprites ##
5935#Param xform RSXform mappings for sprites in atlas ##
5936#Param tex Rect locations of sprites in atlas ##
5937#Param count number of sprites to draw ##
Cary Clark6fc50412017-09-21 12:31:06 -04005938#Param cullRect bounds of transformed sprites for efficient clipping; may be nullptr ##
5939#Param paint Color_Filter, Image_Filter, Blend_Mode, and so on; may be nullptr ##
Cary Clark8032b982017-07-28 11:04:54 -04005940
5941#Example
5942#Image 3
Cary Clarkbad5ad72017-08-03 17:14:08 -04005943void draw(SkCanvas* canvas) {
5944 // sk_sp<SkImage> image = mandrill;
5945 SkRSXform xforms[] = { { 1, 0, 0, 0 }, {0, 1, 300, 100 } };
5946 SkRect tex[] = { { 0, 0, 200, 200 }, { 200, 0, 400, 200 } };
5947 canvas->drawAtlas(image, xforms, tex, 2, nullptr, nullptr);
Cary Clark8032b982017-07-28 11:04:54 -04005948}
5949##
5950
Cary Clark2ade9972017-11-02 17:49:34 -04005951#SeeAlso drawBitmap drawImage
Cary Clark8032b982017-07-28 11:04:54 -04005952
5953##
5954
5955# ------------------------------------------------------------------------------
5956
Cary Clark73fa9722017-08-29 17:36:51 -04005957#Method void drawDrawable(SkDrawable* drawable, const SkMatrix* matrix = nullptr)
Cary Clark8032b982017-07-28 11:04:54 -04005958
Cary Clarkab2621d2018-01-30 10:08:57 -05005959#Line # draws Drawable, encapsulated drawing commands ##
Cary Clark8032b982017-07-28 11:04:54 -04005960Draw Drawable drawable using Clip and Matrix, concatenated with
5961optional matrix.
5962
5963If Canvas has an asynchronous implementation, as is the case
5964when it is recording into Picture, then drawable will be referenced,
5965so that SkDrawable::draw() can be called when the operation is finalized. To force
5966immediate drawing, call SkDrawable::draw() instead.
5967
Cary Clarkbad5ad72017-08-03 17:14:08 -04005968#Param drawable custom struct encapsulating drawing commands ##
5969#Param matrix transformation applied to drawing; may be nullptr ##
Cary Clark8032b982017-07-28 11:04:54 -04005970
5971#Example
5972#Height 100
5973#Function
Cary Clarkbad5ad72017-08-03 17:14:08 -04005974struct MyDrawable : public SkDrawable {
5975 SkRect onGetBounds() override { return SkRect::MakeWH(50, 100); }
5976
5977 void onDraw(SkCanvas* canvas) override {
5978 SkPath path;
5979 path.conicTo(10, 90, 50, 90, 0.9f);
5980 SkPaint paint;
5981 paint.setColor(SK_ColorBLUE);
5982 canvas->drawRect(path.getBounds(), paint);
5983 paint.setAntiAlias(true);
5984 paint.setColor(SK_ColorWHITE);
5985 canvas->drawPath(path, paint);
5986 }
5987};
5988
5989#Function ##
5990void draw(SkCanvas* canvas) {
5991 sk_sp<SkDrawable> drawable(new MyDrawable);
5992 SkMatrix matrix;
5993 matrix.setTranslate(10, 10);
5994 canvas->drawDrawable(drawable.get(), &matrix);
Cary Clark8032b982017-07-28 11:04:54 -04005995}
5996##
5997
Cary Clark2ade9972017-11-02 17:49:34 -04005998#SeeAlso SkDrawable drawPicture
Cary Clark8032b982017-07-28 11:04:54 -04005999
6000##
6001
6002# ------------------------------------------------------------------------------
6003
6004#Method void drawDrawable(SkDrawable* drawable, SkScalar x, SkScalar y)
6005
6006Draw Drawable drawable using Clip and Matrix, offset by (x, y).
6007
6008If Canvas has an asynchronous implementation, as is the case
6009when it is recording into Picture, then drawable will be referenced,
6010so that SkDrawable::draw() can be called when the operation is finalized. To force
6011immediate drawing, call SkDrawable::draw() instead.
6012
Cary Clarkbad5ad72017-08-03 17:14:08 -04006013#Param drawable custom struct encapsulating drawing commands ##
6014#Param x offset into Canvas writable pixels in x ##
6015#Param y offset into Canvas writable pixels in y ##
Cary Clark8032b982017-07-28 11:04:54 -04006016
6017#Example
6018#Height 100
6019#Function
Cary Clarkbad5ad72017-08-03 17:14:08 -04006020struct MyDrawable : public SkDrawable {
6021 SkRect onGetBounds() override { return SkRect::MakeWH(50, 100); }
6022
6023 void onDraw(SkCanvas* canvas) override {
6024 SkPath path;
6025 path.conicTo(10, 90, 50, 90, 0.9f);
6026 SkPaint paint;
6027 paint.setColor(SK_ColorBLUE);
6028 canvas->drawRect(path.getBounds(), paint);
6029 paint.setAntiAlias(true);
6030 paint.setColor(SK_ColorWHITE);
6031 canvas->drawPath(path, paint);
6032 }
6033};
6034
6035#Function ##
6036void draw(SkCanvas* canvas) {
6037 sk_sp<SkDrawable> drawable(new MyDrawable);
6038 canvas->drawDrawable(drawable.get(), 10, 10);
Cary Clark8032b982017-07-28 11:04:54 -04006039}
6040##
6041
Cary Clark2ade9972017-11-02 17:49:34 -04006042#SeeAlso SkDrawable drawPicture
Cary Clark8032b982017-07-28 11:04:54 -04006043
6044##
6045
6046# ------------------------------------------------------------------------------
6047
6048#Method void drawAnnotation(const SkRect& rect, const char key[], SkData* value)
6049
Cary Clarkab2621d2018-01-30 10:08:57 -05006050#Line # associates a Rect with a key-value pair ##
Cary Clark8032b982017-07-28 11:04:54 -04006051Associate Rect on Canvas when an annotation; a key-value pair, where the key is
6052a null-terminated utf8 string, and optional value is stored as Data.
6053
6054Only some canvas implementations, such as recording to Picture, or drawing to
6055Document_PDF, use annotations.
6056
Cary Clarkbad5ad72017-08-03 17:14:08 -04006057#Param rect Rect extent of canvas to annotate ##
6058#Param key string used for lookup ##
6059#Param value data holding value stored in annotation ##
Cary Clark8032b982017-07-28 11:04:54 -04006060
6061#Example
6062 #Height 1
6063 const char text[] = "Click this link!";
6064 SkRect bounds;
6065 SkPaint paint;
6066 paint.setTextSize(40);
6067 (void)paint.measureText(text, strlen(text), &bounds);
6068 const char url[] = "https://www.google.com/";
6069 sk_sp<SkData> urlData(SkData::MakeWithCString(url));
6070 canvas->drawAnnotation(bounds, "url_key", urlData.get());
6071##
6072
Cary Clark2ade9972017-11-02 17:49:34 -04006073#SeeAlso SkPicture SkDocument
Cary Clark8032b982017-07-28 11:04:54 -04006074
6075##
6076
6077# ------------------------------------------------------------------------------
6078
6079#Method void drawAnnotation(const SkRect& rect, const char key[], const sk_sp<SkData>& value)
6080
6081Associate Rect on Canvas when an annotation; a key-value pair, where the key is
6082a null-terminated utf8 string, and optional value is stored as Data.
6083
6084Only some canvas implementations, such as recording to Picture, or drawing to
6085Document_PDF, use annotations.
6086
Cary Clarkbad5ad72017-08-03 17:14:08 -04006087#Param rect Rect extent of canvas to annotate ##
6088#Param key string used for lookup ##
6089#Param value data holding value stored in annotation ##
Cary Clark8032b982017-07-28 11:04:54 -04006090
6091#Example
6092#Height 1
6093 const char text[] = "Click this link!";
6094 SkRect bounds;
6095 SkPaint paint;
6096 paint.setTextSize(40);
6097 (void)paint.measureText(text, strlen(text), &bounds);
6098 const char url[] = "https://www.google.com/";
6099 sk_sp<SkData> urlData(SkData::MakeWithCString(url));
6100 canvas->drawAnnotation(bounds, "url_key", urlData.get());
6101##
6102
Cary Clark2ade9972017-11-02 17:49:34 -04006103#SeeAlso SkPicture SkDocument
Cary Clark8032b982017-07-28 11:04:54 -04006104
6105##
6106
6107#Method SkDrawFilter* getDrawFilter() const
Cary Clark4855f782018-02-06 09:41:53 -05006108#Deprecated soon
Cary Clark8032b982017-07-28 11:04:54 -04006109##
6110
6111#Method virtual SkDrawFilter* setDrawFilter(SkDrawFilter* filter)
Cary Clark4855f782018-02-06 09:41:53 -05006112#Deprecated soon
Cary Clark8032b982017-07-28 11:04:54 -04006113##
6114
6115# ------------------------------------------------------------------------------
6116
6117#Method virtual bool isClipEmpty() const
6118
Cary Clarkab2621d2018-01-30 10:08:57 -05006119#Line # returns if Clip is empty ##
Cary Clark8032b982017-07-28 11:04:54 -04006120Returns true if Clip is empty; that is, nothing will draw.
6121
Cary Clarkbad5ad72017-08-03 17:14:08 -04006122May do work when called; it should not be called
Cary Clark8032b982017-07-28 11:04:54 -04006123more often than needed. However, once called, subsequent calls perform no
6124work until Clip changes.
6125
Cary Clarkbad5ad72017-08-03 17:14:08 -04006126#Return true if Clip is empty ##
Cary Clark8032b982017-07-28 11:04:54 -04006127
6128#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04006129 void draw(SkCanvas* canvas) {
6130 SkDebugf("clip is%s empty\n", canvas->isClipEmpty() ? "" : " not");
6131 SkPath path;
6132 canvas->clipPath(path);
6133 SkDebugf("clip is%s empty\n", canvas->isClipEmpty() ? "" : " not");
Cary Clark8032b982017-07-28 11:04:54 -04006134 }
6135 #StdOut
Cary Clarkbad5ad72017-08-03 17:14:08 -04006136 clip is not empty
Cary Clark8032b982017-07-28 11:04:54 -04006137 clip is empty
6138 ##
6139##
6140
Cary Clark2ade9972017-11-02 17:49:34 -04006141#SeeAlso isClipRect getLocalClipBounds getDeviceClipBounds
Cary Clark8032b982017-07-28 11:04:54 -04006142
6143##
6144
6145# ------------------------------------------------------------------------------
6146
6147#Method virtual bool isClipRect() const
6148
Cary Clarkab2621d2018-01-30 10:08:57 -05006149#Line # returns if Clip is Rect and not empty ##
Cary Clark8032b982017-07-28 11:04:54 -04006150Returns true if Clip is Rect and not empty.
6151Returns false if the clip is empty, or if it is not Rect.
6152
Cary Clarkbad5ad72017-08-03 17:14:08 -04006153#Return true if Clip is Rect and not empty ##
Cary Clark8032b982017-07-28 11:04:54 -04006154
6155#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04006156 void draw(SkCanvas* canvas) {
6157 SkDebugf("clip is%s rect\n", canvas->isClipRect() ? "" : " not");
6158 canvas->clipRect({0, 0, 0, 0});
6159 SkDebugf("clip is%s rect\n", canvas->isClipRect() ? "" : " not");
Cary Clark8032b982017-07-28 11:04:54 -04006160 }
6161 #StdOut
Cary Clarkbad5ad72017-08-03 17:14:08 -04006162 clip is rect
Cary Clark8032b982017-07-28 11:04:54 -04006163 clip is not rect
6164 ##
6165##
6166
Cary Clark2ade9972017-11-02 17:49:34 -04006167#SeeAlso isClipEmpty getLocalClipBounds getDeviceClipBounds
Cary Clark8032b982017-07-28 11:04:54 -04006168
6169##
6170
6171#Class SkCanvas ##
Cary Clark884dd7d2017-10-11 10:37:52 -04006172
Cary Clark8032b982017-07-28 11:04:54 -04006173#Topic Canvas ##