blob: b9a48acd776a967ff278ac9805482f29ba55021e [file] [log] [blame]
Cary Clark8032b982017-07-28 11:04:54 -04001#Topic Canvas
Cary Clark137b8742018-05-30 09:21:49 -04002#Alias Canvas_Reference ##
Cary Clark8032b982017-07-28 11:04:54 -04003
Cary Clarke4aa3712017-09-15 02:56:12 -04004#Class SkCanvas
5
Cary Clark61313f32018-10-08 14:57:48 -04006#Code
7#Populate
8##
9
Cary Clark8032b982017-07-28 11:04:54 -040010Canvas provides an interface for drawing, and how the drawing is clipped and transformed.
11Canvas contains a stack of Matrix and Clip values.
12
13Canvas and Paint together provide the state to draw into Surface or Device.
Cary Clarkbad5ad72017-08-03 17:14:08 -040014Each Canvas draw call transforms the geometry of the object by the concatenation of all
15Matrix values in the stack. The transformed geometry is clipped by the intersection
16of all of Clip values in the stack. The Canvas draw calls use Paint to supply drawing
17state such as Color, Typeface, text size, stroke width, Shader and so on.
Cary Clark8032b982017-07-28 11:04:54 -040018
Herb Derbyefe39bc2018-05-01 17:06:20 -040019To draw to a pixel-based destination, create Raster_Surface or GPU_Surface.
20Request Canvas from Surface to obtain the interface to draw.
21Canvas generated by Raster_Surface draws to memory visible to the CPU.
Cary Clark8032b982017-07-28 11:04:54 -040022Canvas generated by GPU_Surface uses Vulkan or OpenGL to draw to the GPU.
23
Cary Clarkbad5ad72017-08-03 17:14:08 -040024To draw to a document, obtain Canvas from SVG_Canvas, Document_PDF, or Picture_Recorder.
Cary Clarkce101242017-09-01 15:51:02 -040025Document based Canvas and other Canvas Subclasses reference Device describing the
Cary Clarkbad5ad72017-08-03 17:14:08 -040026destination.
27
Cary Clark8032b982017-07-28 11:04:54 -040028Canvas can be constructed to draw to Bitmap without first creating Raster_Surface.
Herb Derbyefe39bc2018-05-01 17:06:20 -040029This approach may be deprecated in the future.
Cary Clark8032b982017-07-28 11:04:54 -040030
Cary Clark61313f32018-10-08 14:57:48 -040031#Subtopic Constructors
Cary Clark8032b982017-07-28 11:04:54 -040032
Cary Clark4855f782018-02-06 09:41:53 -050033Create the desired type of Surface to obtain its Canvas when possible. Useful
Cary Clark8032b982017-07-28 11:04:54 -040034when no Surface is required, and some helpers implicitly create Raster_Surface.
35
Cary Clark08895c42018-02-01 09:37:32 -050036##
Cary Clark8032b982017-07-28 11:04:54 -040037
38# ------------------------------------------------------------------------------
39
Cary Clarka560c472017-11-27 10:44:06 -050040#Method static std::unique_ptr<SkCanvas> MakeRasterDirect(const SkImageInfo& info, void* pixels,
41 size_t rowBytes,
42 const SkSurfaceProps* props = nullptr)
Cary Clark61313f32018-10-08 14:57:48 -040043#In Constructors
Cary Clarkab2621d2018-01-30 10:08:57 -050044#Line # creates from SkImageInfo and Pixel_Storage ##
Cary Clark8032b982017-07-28 11:04:54 -040045
Cary Clarkbad5ad72017-08-03 17:14:08 -040046Allocates raster Canvas that will draw directly into pixels.
Cary Clark8032b982017-07-28 11:04:54 -040047
Cary Clarkbad5ad72017-08-03 17:14:08 -040048Canvas is returned if all parameters are valid.
49Valid parameters include:
50info dimensions are zero or positive;
Cary Clark2dc84ad2018-01-26 12:56:22 -050051info contains Color_Type and Alpha_Type supported by Raster_Surface;
Cary Clarkbad5ad72017-08-03 17:14:08 -040052pixels is not nullptr;
Cary Clark2dc84ad2018-01-26 12:56:22 -050053rowBytes is zero or large enough to contain info width pixels of Color_Type.
Cary Clarkbad5ad72017-08-03 17:14:08 -040054
Herb Derbyefe39bc2018-05-01 17:06:20 -040055Pass zero for rowBytes to compute rowBytes from info width and size of pixel.
Cary Clarkf05bdda2017-08-24 12:59:48 -040056If rowBytes is greater than zero, it must be equal to or greater than
Cary Clark2dc84ad2018-01-26 12:56:22 -050057info width times bytes required for Color_Type.
Cary Clarkf05bdda2017-08-24 12:59:48 -040058
59Pixel buffer size should be info height times computed rowBytes.
Cary Clarka560c472017-11-27 10:44:06 -050060Pixels are not initialized.
61To access pixels after drawing, call flush() or peekPixels.
Cary Clarkbad5ad72017-08-03 17:14:08 -040062
Cary Clark2dc84ad2018-01-26 12:56:22 -050063#Param info width, height, Color_Type, Alpha_Type, Color_Space, of Raster_Surface;
Cary Clarkbad5ad72017-08-03 17:14:08 -040064 width, or height, or both, may be zero
Cary Clark8032b982017-07-28 11:04:54 -040065##
Cary Clarkf05bdda2017-08-24 12:59:48 -040066#Param pixels pointer to destination pixels buffer
Cary Clark8032b982017-07-28 11:04:54 -040067##
Cary Clarkf05bdda2017-08-24 12:59:48 -040068#Param rowBytes interval from one Surface row to the next, or zero
Cary Clark8032b982017-07-28 11:04:54 -040069##
Cary Clarka560c472017-11-27 10:44:06 -050070#Param props LCD striping orientation and setting for device independent fonts;
71 may be nullptr
72##
Cary Clark8032b982017-07-28 11:04:54 -040073
Cary Clarkbad5ad72017-08-03 17:14:08 -040074#Return Canvas if all parameters are valid; otherwise, nullptr ##
Cary Clark8032b982017-07-28 11:04:54 -040075
76#Example
77 #Description
78 Allocates a three by three bitmap, clears it to white, and draws a black pixel
79 in the center.
80 ##
Cary Clarkbad5ad72017-08-03 17:14:08 -040081void draw(SkCanvas* ) {
Cary Clarkce101242017-09-01 15:51:02 -040082 SkImageInfo info = SkImageInfo::MakeN32Premul(3, 3); // device aligned, 32 bpp, Premultiplied
Cary Clarkbad5ad72017-08-03 17:14:08 -040083 const size_t minRowBytes = info.minRowBytes(); // bytes used by one bitmap row
Cary Clarka560c472017-11-27 10:44:06 -050084 const size_t size = info.computeMinByteSize(); // bytes used by all rows
Cary Clarkbad5ad72017-08-03 17:14:08 -040085 SkAutoTMalloc<SkPMColor> storage(size); // allocate storage for pixels
86 SkPMColor* pixels = storage.get(); // get pointer to allocated storage
87 // create a SkCanvas backed by a raster device, and delete it when the
88 // function goes out of scope.
89 std::unique_ptr<SkCanvas> canvas = SkCanvas::MakeRasterDirect(info, pixels, minRowBytes);
Cary Clarkce101242017-09-01 15:51:02 -040090 canvas->clear(SK_ColorWHITE); // white is Unpremultiplied, in ARGB order
Cary Clarkbad5ad72017-08-03 17:14:08 -040091 canvas->flush(); // ensure that pixels are cleared
Cary Clarkce101242017-09-01 15:51:02 -040092 SkPMColor pmWhite = pixels[0]; // the Premultiplied format may vary
Cary Clarkbad5ad72017-08-03 17:14:08 -040093 SkPaint paint; // by default, draws black
94 canvas->drawPoint(1, 1, paint); // draw in the center
95 canvas->flush(); // ensure that point was drawn
96 for (int y = 0; y < info.height(); ++y) {
97 for (int x = 0; x < info.width(); ++x) {
98 SkDebugf("%c", *pixels++ == pmWhite ? '-' : 'x');
99 }
100 SkDebugf("\n");
101 }
Cary Clark8032b982017-07-28 11:04:54 -0400102}
103 #StdOut
104 ---
105 -x-
106 ---
107 ##
108##
109
Cary Clark8032b982017-07-28 11:04:54 -0400110#SeeAlso MakeRasterDirectN32 SkSurface::MakeRasterDirect
Cary Clark2ade9972017-11-02 17:49:34 -0400111
Cary Clark8032b982017-07-28 11:04:54 -0400112##
113
114# ------------------------------------------------------------------------------
115
116#Method static std::unique_ptr<SkCanvas> MakeRasterDirectN32(int width, int height, SkPMColor* pixels,
Herb Derbyefe39bc2018-05-01 17:06:20 -0400117 size_t rowBytes)
Cary Clark61313f32018-10-08 14:57:48 -0400118#In Constructors
Cary Clarkab2621d2018-01-30 10:08:57 -0500119#Line # creates from image data and Pixel_Storage ##
Cary Clark8032b982017-07-28 11:04:54 -0400120
Cary Clarkbad5ad72017-08-03 17:14:08 -0400121Allocates raster Canvas specified by inline image specification. Subsequent Canvas
122calls draw into pixels.
Cary Clark2dc84ad2018-01-26 12:56:22 -0500123Color_Type is set to kN32_SkColorType.
124Alpha_Type is set to kPremul_SkAlphaType.
Cary Clark8032b982017-07-28 11:04:54 -0400125To access pixels after drawing, call flush() or peekPixels.
126
Cary Clarkbad5ad72017-08-03 17:14:08 -0400127Canvas is returned if all parameters are valid.
128Valid parameters include:
Cary Clarkf05bdda2017-08-24 12:59:48 -0400129width and height are zero or positive;
Cary Clarkbad5ad72017-08-03 17:14:08 -0400130pixels is not nullptr;
Cary Clarkf05bdda2017-08-24 12:59:48 -0400131rowBytes is zero or large enough to contain width pixels of kN32_SkColorType.
Cary Clarkbad5ad72017-08-03 17:14:08 -0400132
Herb Derbyefe39bc2018-05-01 17:06:20 -0400133Pass zero for rowBytes to compute rowBytes from width and size of pixel.
Cary Clarkf05bdda2017-08-24 12:59:48 -0400134If rowBytes is greater than zero, it must be equal to or greater than
Cary Clark2dc84ad2018-01-26 12:56:22 -0500135width times bytes required for Color_Type.
Cary Clarkf05bdda2017-08-24 12:59:48 -0400136
137Pixel buffer size should be height times rowBytes.
Cary Clarkbad5ad72017-08-03 17:14:08 -0400138
139#Param width pixel column count on Raster_Surface created; must be zero or greater ##
Cary Clarkbc5697d2017-10-04 14:31:33 -0400140#Param height pixel row count on Raster_Surface created; must be zero or greater ##
Cary Clarkbad5ad72017-08-03 17:14:08 -0400141#Param pixels pointer to destination pixels buffer; buffer size should be height
Cary Clarkf05bdda2017-08-24 12:59:48 -0400142 times rowBytes
Cary Clark8032b982017-07-28 11:04:54 -0400143##
Cary Clarkf05bdda2017-08-24 12:59:48 -0400144#Param rowBytes interval from one Surface row to the next, or zero
Cary Clark8032b982017-07-28 11:04:54 -0400145##
146
Cary Clarkbad5ad72017-08-03 17:14:08 -0400147#Return Canvas if all parameters are valid; otherwise, nullptr ##
Cary Clark8032b982017-07-28 11:04:54 -0400148
149#Example
150 #Description
151 Allocates a three by three bitmap, clears it to white, and draws a black pixel
152 in the center.
153 ##
154void draw(SkCanvas* ) {
155 const int width = 3;
156 const int height = 3;
Cary Clarkce101242017-09-01 15:51:02 -0400157 SkPMColor pixels[height][width]; // allocate a 3x3 Premultiplied bitmap on the stack
Cary Clark8032b982017-07-28 11:04:54 -0400158 // create a SkCanvas backed by a raster device, and delete it when the
159 // function goes out of scope.
160 std::unique_ptr<SkCanvas> canvas = SkCanvas::MakeRasterDirectN32(
161 width,
162 height,
Cary Clarkbc5697d2017-10-04 14:31:33 -0400163 pixels[0], // top-left of the bitmap
Cary Clark8032b982017-07-28 11:04:54 -0400164 sizeof(pixels[0])); // byte width of the each row
Cary Clark682c58d2018-05-16 07:07:07 -0400165 // write a Premultiplied value for white into all pixels in the bitmap
Cary Clark8032b982017-07-28 11:04:54 -0400166 canvas->clear(SK_ColorWHITE);
Cary Clarkce101242017-09-01 15:51:02 -0400167 SkPMColor pmWhite = pixels[0][0]; // the Premultiplied format may vary
Cary Clark8032b982017-07-28 11:04:54 -0400168 SkPaint paint; // by default, draws black
169 canvas->drawPoint(1, 1, paint); // draw in the center
170 canvas->flush(); // ensure that pixels is ready to be read
171 for (int y = 0; y < height; ++y) {
172 for (int x = 0; x < width; ++x) {
173 SkDebugf("%c", pixels[y][x] == pmWhite ? '-' : 'x');
174 }
175 SkDebugf("\n");
176 }
177}
178 #StdOut
179 ---
180 -x-
181 ---
182 ##
183##
184
Cary Clark2ade9972017-11-02 17:49:34 -0400185#SeeAlso MakeRasterDirect SkSurface::MakeRasterDirect SkImageInfo::MakeN32Premul
Cary Clark8032b982017-07-28 11:04:54 -0400186
187##
188
189# ------------------------------------------------------------------------------
190
191#Method SkCanvas()
192
Cary Clarkab2621d2018-01-30 10:08:57 -0500193#Line # creates with no Surface, no dimensions ##
Herb Derbyefe39bc2018-05-01 17:06:20 -0400194Creates an empty Canvas with no backing device or pixels, with
Cary Clarkf05bdda2017-08-24 12:59:48 -0400195a width and height of zero.
Cary Clark8032b982017-07-28 11:04:54 -0400196
Cary Clarkd0530ba2017-09-14 11:25:39 -0400197#Return empty Canvas ##
Cary Clark8032b982017-07-28 11:04:54 -0400198
199#Example
200
201#Description
202Passes a placeholder to a function that requires one.
203##
204
205#Function
Cary Clarkbad5ad72017-08-03 17:14:08 -0400206// Returns true if either the canvas rotates the text by 90 degrees, or the paint does.
207static void check_for_up_and_down_text(const SkCanvas* canvas, const SkPaint& paint) {
208 bool paintHasVertical = paint.isVerticalText();
209 const SkMatrix& matrix = canvas->getTotalMatrix();
210 bool matrixIsVertical = matrix.preservesRightAngles() && !matrix.isScaleTranslate();
211 SkDebugf("paint draws text %s\n", paintHasVertical != matrixIsVertical ?
212 "top to bottom" : "left to right");
213}
214
215static void check_for_up_and_down_text(const SkPaint& paint) {
216 SkCanvas canvas; // placeholder only, does not have an associated device
217 check_for_up_and_down_text(&canvas, paint);
218}
219
Cary Clark8032b982017-07-28 11:04:54 -0400220##
Cary Clarkbad5ad72017-08-03 17:14:08 -0400221void draw(SkCanvas* canvas) {
222 SkPaint paint;
223 check_for_up_and_down_text(paint); // paint draws text left to right
224 paint.setVerticalText(true);
225 check_for_up_and_down_text(paint); // paint draws text top to bottom
226 paint.setVerticalText(false);
227 canvas->rotate(90);
228 check_for_up_and_down_text(canvas, paint); // paint draws text top to bottom
229}
Cary Clark8032b982017-07-28 11:04:54 -0400230
231 #StdOut
232 paint draws text left to right
233 paint draws text top to bottom
234 paint draws text top to bottom
235 ##
236##
237
Cary Clark2ade9972017-11-02 17:49:34 -0400238#SeeAlso MakeRasterDirect SkRasterHandleAllocator::MakeCanvas SkSurface::getCanvas SkCreateColorSpaceXformCanvas
Cary Clark8032b982017-07-28 11:04:54 -0400239
240##
241
242# ------------------------------------------------------------------------------
243
Cary Clark73fa9722017-08-29 17:36:51 -0400244#Method SkCanvas(int width, int height, const SkSurfaceProps* props = nullptr)
Cary Clark8032b982017-07-28 11:04:54 -0400245
Cary Clark682c58d2018-05-16 07:07:07 -0400246#Line # creates with no Surface, set dimensions, Surface_Properties ##
Cary Clark8032b982017-07-28 11:04:54 -0400247Creates Canvas of the specified dimensions without a Surface.
Cary Clark682c58d2018-05-16 07:07:07 -0400248Used by Subclasses with custom implementations for draw member functions.
Cary Clark8032b982017-07-28 11:04:54 -0400249
Cary Clarkd0530ba2017-09-14 11:25:39 -0400250If props equals nullptr, Surface_Properties are created with
Herb Derbyefe39bc2018-05-01 17:06:20 -0400251Surface_Properties_Legacy_Font_Host settings, which choose the pixel striping
Cary Clarkd0530ba2017-09-14 11:25:39 -0400252direction and order. Since a platform may dynamically change its direction when
253the device is rotated, and since a platform may have multiple monitors with
254different characteristics, it is best not to rely on this legacy behavior.
Cary Clark8032b982017-07-28 11:04:54 -0400255
Cary Clarkbad5ad72017-08-03 17:14:08 -0400256#Param width zero or greater ##
257#Param height zero or greater ##
258#Param props LCD striping orientation and setting for device independent fonts;
259 may be nullptr
260##
261
262#Return Canvas placeholder with dimensions ##
Cary Clark8032b982017-07-28 11:04:54 -0400263
264#Example
265 SkCanvas canvas(10, 20); // 10 units wide, 20 units high
266 canvas.clipRect(SkRect::MakeXYWH(30, 40, 5, 10)); // clip is outside canvas' device
267 SkDebugf("canvas %s empty\n", canvas.getDeviceClipBounds().isEmpty() ? "is" : "is not");
268
269 #StdOut
270 canvas is empty
271 ##
272##
273
Cary Clark2ade9972017-11-02 17:49:34 -0400274#SeeAlso MakeRasterDirect SkSurfaceProps SkPixelGeometry SkCreateColorSpaceXformCanvas
Cary Clark8032b982017-07-28 11:04:54 -0400275
276##
277
278# ------------------------------------------------------------------------------
279
Herb Derbyefe39bc2018-05-01 17:06:20 -0400280#Method explicit SkCanvas(sk_sp<SkBaseDevice> device)
Cary Clark4855f782018-02-06 09:41:53 -0500281#Deprecated soon
Cary Clark8032b982017-07-28 11:04:54 -0400282##
283
284# ------------------------------------------------------------------------------
285
286#Method explicit SkCanvas(const SkBitmap& bitmap)
287
Cary Clarkab2621d2018-01-30 10:08:57 -0500288#Line # uses existing Bitmap ##
Cary Clark80247e52018-07-11 16:18:41 -0400289Constructs a canvas that draws into bitmap.
Herb Derbyefe39bc2018-05-01 17:06:20 -0400290Sets SkSurfaceProps::kLegacyFontHost_InitType in constructed Surface.
Cary Clark8032b982017-07-28 11:04:54 -0400291
Cary Clarkbad5ad72017-08-03 17:14:08 -0400292Bitmap is copied so that subsequently editing bitmap will not affect
293constructed Canvas.
294
295May be deprecated in the future.
296
Cary Clark8032b982017-07-28 11:04:54 -0400297#ToDo Should be deprecated? ##
298
Cary Clark2dc84ad2018-01-26 12:56:22 -0500299#Param bitmap width, height, Color_Type, Alpha_Type, and pixel
Cary Clarkbad5ad72017-08-03 17:14:08 -0400300 storage of Raster_Surface
Cary Clark8032b982017-07-28 11:04:54 -0400301##
302
Cary Clarkbad5ad72017-08-03 17:14:08 -0400303#Return Canvas that can be used to draw into bitmap ##
Cary Clark8032b982017-07-28 11:04:54 -0400304
305#Example
306#Description
307The actual output depends on the installed fonts.
308##
309 SkBitmap bitmap;
310 // create a bitmap 5 wide and 11 high
311 bitmap.allocPixels(SkImageInfo::MakeN32Premul(5, 11));
312 SkCanvas canvas(bitmap);
Cary Clarkce101242017-09-01 15:51:02 -0400313 canvas.clear(SK_ColorWHITE); // white is Unpremultiplied, in ARGB order
Cary Clark8032b982017-07-28 11:04:54 -0400314 SkPixmap pixmap; // provides guaranteed access to the drawn pixels
315 if (!canvas.peekPixels(&pixmap)) {
316 SkDebugf("peekPixels should never fail.\n");
317 }
Cary Clarkbc5697d2017-10-04 14:31:33 -0400318 const SkPMColor* pixels = pixmap.addr32(); // points to top-left of bitmap
Cary Clarkce101242017-09-01 15:51:02 -0400319 SkPMColor pmWhite = pixels[0]; // the Premultiplied format may vary
Cary Clark8032b982017-07-28 11:04:54 -0400320 SkPaint paint; // by default, draws black, 12 point text
321 canvas.drawString("!", 1, 10, paint); // 1 char at baseline (1, 10)
322 for (int y = 0; y < bitmap.height(); ++y) {
323 for (int x = 0; x < bitmap.width(); ++x) {
324 SkDebugf("%c", *pixels++ == pmWhite ? '-' : 'x');
325 }
326 SkDebugf("\n");
327 }
328
329 #StdOut
Cary Clarkd0530ba2017-09-14 11:25:39 -0400330 -----
331 ---x-
332 ---x-
333 ---x-
334 ---x-
335 ---x-
336 ---x-
337 -----
338 ---x-
339 ---x-
Cary Clark8032b982017-07-28 11:04:54 -0400340 -----
341 #StdOut ##
342##
343
Cary Clark2ade9972017-11-02 17:49:34 -0400344#SeeAlso MakeRasterDirect SkRasterHandleAllocator::MakeCanvas SkSurface::getCanvas SkCreateColorSpaceXformCanvas
Cary Clark8032b982017-07-28 11:04:54 -0400345
346##
347
Cary Clarkbad5ad72017-08-03 17:14:08 -0400348#EnumClass ColorBehavior
Cary Clark682c58d2018-05-16 07:07:07 -0400349#Line # exists for Android framework only ##
Cary Clark8032b982017-07-28 11:04:54 -0400350#Private
351Android framework only.
352##
353
354#Code
Cary Clark61313f32018-10-08 14:57:48 -0400355#Populate
Cary Clark8032b982017-07-28 11:04:54 -0400356##
357#Const kLegacy 0
Cary Clark682c58d2018-05-16 07:07:07 -0400358#Line # placeholder ##
Cary Clarkbad5ad72017-08-03 17:14:08 -0400359 Is a placeholder to allow specialized constructor; has no meaning.
Cary Clark8032b982017-07-28 11:04:54 -0400360##
361##
362
Cary Clarkbad5ad72017-08-03 17:14:08 -0400363#Method SkCanvas(const SkBitmap& bitmap, ColorBehavior behavior)
364
Cary Clark682c58d2018-05-16 07:07:07 -0400365#Line # exists for Android framework only ##
366
Cary Clark80247e52018-07-11 16:18:41 -0400367For use by Android framework only.
Cary Clarkbad5ad72017-08-03 17:14:08 -0400368
369#Param bitmap specifies a bitmap for the canvas to draw into ##
370#Param behavior specializes this constructor; value is unused ##
371#Return Canvas that can be used to draw into bitmap ##
372
373#NoExample
374##
375##
Cary Clark8032b982017-07-28 11:04:54 -0400376
377# ------------------------------------------------------------------------------
378
379#Method SkCanvas(const SkBitmap& bitmap, const SkSurfaceProps& props)
380
Cary Clarkab2621d2018-01-30 10:08:57 -0500381#Line # uses existing Bitmap and Surface_Properties ##
Cary Clark80247e52018-07-11 16:18:41 -0400382Constructs a canvas that draws into bitmap.
Cary Clark8032b982017-07-28 11:04:54 -0400383Use props to match the device characteristics, like LCD striping.
384
Cary Clarkbad5ad72017-08-03 17:14:08 -0400385bitmap is copied so that subsequently editing bitmap will not affect
386constructed Canvas.
387
Cary Clark2dc84ad2018-01-26 12:56:22 -0500388#Param bitmap width, height, Color_Type, Alpha_Type,
Herb Derbyefe39bc2018-05-01 17:06:20 -0400389 and pixel storage of Raster_Surface
Cary Clark8032b982017-07-28 11:04:54 -0400390##
Cary Clarkbad5ad72017-08-03 17:14:08 -0400391#Param props order and orientation of RGB striping; and whether to use
392 device independent fonts
Cary Clark8032b982017-07-28 11:04:54 -0400393##
394
Cary Clarkbad5ad72017-08-03 17:14:08 -0400395#Return Canvas that can be used to draw into bitmap ##
Cary Clark8032b982017-07-28 11:04:54 -0400396
397#Example
398#Description
399The actual output depends on the installed fonts.
400##
401 SkBitmap bitmap;
402 // create a bitmap 5 wide and 11 high
403 bitmap.allocPixels(SkImageInfo::MakeN32Premul(5, 11));
404 SkCanvas canvas(bitmap, SkSurfaceProps(0, kUnknown_SkPixelGeometry));
Cary Clarkce101242017-09-01 15:51:02 -0400405 canvas.clear(SK_ColorWHITE); // white is Unpremultiplied, in ARGB order
Cary Clark8032b982017-07-28 11:04:54 -0400406 SkPixmap pixmap; // provides guaranteed access to the drawn pixels
407 if (!canvas.peekPixels(&pixmap)) {
408 SkDebugf("peekPixels should never fail.\n");
409 }
Cary Clarkbc5697d2017-10-04 14:31:33 -0400410 const SkPMColor* pixels = pixmap.addr32(); // points to top-left of bitmap
Cary Clarkce101242017-09-01 15:51:02 -0400411 SkPMColor pmWhite = pixels[0]; // the Premultiplied format may vary
Cary Clark8032b982017-07-28 11:04:54 -0400412 SkPaint paint; // by default, draws black, 12 point text
413 canvas.drawString("!", 1, 10, paint); // 1 char at baseline (1, 10)
414 for (int y = 0; y < bitmap.height(); ++y) {
415 for (int x = 0; x < bitmap.width(); ++x) {
416 SkDebugf("%c", *pixels++ == pmWhite ? '-' : 'x');
417 }
418 SkDebugf("\n");
419 }
420
421 #StdOut
422 -----
423 ---x-
424 ---x-
425 ---x-
426 ---x-
427 ---x-
428 ---x-
429 -----
430 ---x-
431 ---x-
432 -----
433 #StdOut ##
434##
435
Cary Clark2ade9972017-11-02 17:49:34 -0400436#SeeAlso MakeRasterDirect SkRasterHandleAllocator::MakeCanvas SkSurface::getCanvas SkCreateColorSpaceXformCanvas
Cary Clark8032b982017-07-28 11:04:54 -0400437
438##
439
440# ------------------------------------------------------------------------------
441
442#Method virtual ~SkCanvas()
443
Cary Clarkab2621d2018-01-30 10:08:57 -0500444#Line # draws saved Layers, frees resources ##
Cary Clark5081eed2018-01-22 07:55:48 -0500445Draws saved Layers, if any.
446Frees up resources used by Canvas.
Cary Clark8032b982017-07-28 11:04:54 -0400447
448#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -0400449#Description
Cary Clarkce101242017-09-01 15:51:02 -0400450Canvas Layer draws into bitmap. saveLayerAlpha sets up an additional
451drawing surface that blends with the bitmap. When Layer goes out of
452scope, Layer Destructor is called. The saved Layer is restored, drawing
Cary Clarkbad5ad72017-08-03 17:14:08 -0400453transparent letters.
454##
Cary Clarkf05bdda2017-08-24 12:59:48 -0400455void draw(SkCanvas* canvas) {
456 SkBitmap bitmap;
457 bitmap.allocPixels(SkImageInfo::MakeN32Premul(200, 200));
458 {
459 SkCanvas offscreen(bitmap);
460 SkPaint paint;
461 paint.setTextSize(100);
462 offscreen.drawString("ABC", 20, 160, paint);
463 SkRect layerBounds = SkRect::MakeXYWH(32, 32, 192, 192);
464 offscreen.saveLayerAlpha(&layerBounds, 128);
465 offscreen.clear(SK_ColorWHITE);
466 offscreen.drawString("DEF", 20, 160, paint);
467 }
468 canvas->drawBitmap(bitmap, 0, 0, nullptr);
Cary Clarkbad5ad72017-08-03 17:14:08 -0400469}
Cary Clark8032b982017-07-28 11:04:54 -0400470##
471
Cary Clarkbad5ad72017-08-03 17:14:08 -0400472#SeeAlso State_Stack
Cary Clark8032b982017-07-28 11:04:54 -0400473
474##
475
476# ------------------------------------------------------------------------------
Cary Clark78de7512018-02-07 07:27:09 -0500477#Subtopic Property
Cary Clark78de7512018-02-07 07:27:09 -0500478#Line # metrics and attributes ##
479##
Cary Clark8032b982017-07-28 11:04:54 -0400480
481#Method SkMetaData& getMetaData()
Cary Clark78de7512018-02-07 07:27:09 -0500482#In Property
483#In Utility
Cary Clarkab2621d2018-01-30 10:08:57 -0500484#Line # associates additional data with the canvas ##
Cary Clarkf05bdda2017-08-24 12:59:48 -0400485Returns storage to associate additional data with the canvas.
Cary Clark8032b982017-07-28 11:04:54 -0400486The storage is freed when Canvas is deleted.
487
Cary Clarkbad5ad72017-08-03 17:14:08 -0400488#Return storage that can be read from and written to ##
Cary Clark8032b982017-07-28 11:04:54 -0400489
490#Example
491 const char* kHelloMetaData = "HelloMetaData";
492 SkCanvas canvas;
493 SkMetaData& metaData = canvas.getMetaData();
494 SkDebugf("before: %s\n", metaData.findString(kHelloMetaData));
495 metaData.setString(kHelloMetaData, "Hello!");
496 SkDebugf("during: %s\n", metaData.findString(kHelloMetaData));
497 metaData.removeString(kHelloMetaData);
498 SkDebugf("after: %s\n", metaData.findString(kHelloMetaData));
499
500 #StdOut
501 before: (null)
502 during: Hello!
503 after: (null)
504 #StdOut ##
505##
506
Cary Clark2ade9972017-11-02 17:49:34 -0400507#SeeAlso SkMetaData
Cary Clark8032b982017-07-28 11:04:54 -0400508
509##
510
511# ------------------------------------------------------------------------------
512
513#Method SkImageInfo imageInfo() const
Cary Clark78de7512018-02-07 07:27:09 -0500514#In Property
Cary Clarkab2621d2018-01-30 10:08:57 -0500515#Line # returns Image_Info for Canvas ##
Cary Clark8032b982017-07-28 11:04:54 -0400516Returns Image_Info for Canvas. If Canvas is not associated with Raster_Surface or
Cary Clark2dc84ad2018-01-26 12:56:22 -0500517GPU_Surface, returned Color_Type is set to kUnknown_SkColorType.
Cary Clark8032b982017-07-28 11:04:54 -0400518
Cary Clark2dc84ad2018-01-26 12:56:22 -0500519#Return dimensions and Color_Type of Canvas ##
Cary Clark8032b982017-07-28 11:04:54 -0400520
521#Example
Cary Clarkf05bdda2017-08-24 12:59:48 -0400522 SkCanvas emptyCanvas;
523 SkImageInfo canvasInfo = emptyCanvas.imageInfo();
524 SkImageInfo emptyInfo;
525 SkDebugf("emptyInfo %c= canvasInfo\n", emptyInfo == canvasInfo ? '=' : '!');
526
527 #StdOut
528 emptyInfo == canvasInfo
529 ##
Cary Clark8032b982017-07-28 11:04:54 -0400530##
531
Cary Clark2ade9972017-11-02 17:49:34 -0400532#SeeAlso SkImageInfo MakeRasterDirect makeSurface
Cary Clark8032b982017-07-28 11:04:54 -0400533
534##
535
536# ------------------------------------------------------------------------------
537
538#Method bool getProps(SkSurfaceProps* props) const
Cary Clark78de7512018-02-07 07:27:09 -0500539#In Property
Cary Clarkab2621d2018-01-30 10:08:57 -0500540#Line # copies Surface_Properties if available ##
Cary Clark80247e52018-07-11 16:18:41 -0400541Copies Surface_Properties, if Canvas is associated with Raster_Surface or
542GPU_Surface, and returns true. Otherwise, returns false and leave props unchanged.
Cary Clark8032b982017-07-28 11:04:54 -0400543
Cary Clarkbad5ad72017-08-03 17:14:08 -0400544#Param props storage for writable SkSurfaceProps ##
Cary Clark8032b982017-07-28 11:04:54 -0400545
Cary Clarkbad5ad72017-08-03 17:14:08 -0400546#Return true if Surface_Properties was copied ##
Cary Clark8032b982017-07-28 11:04:54 -0400547
548#ToDo This seems old style. Deprecate? ##
549
550#Example
551 SkBitmap bitmap;
552 SkCanvas canvas(bitmap, SkSurfaceProps(0, kRGB_V_SkPixelGeometry));
553 SkSurfaceProps surfaceProps(0, kUnknown_SkPixelGeometry);
554 SkDebugf("isRGB:%d\n", SkPixelGeometryIsRGB(surfaceProps.pixelGeometry()));
555 if (!canvas.getProps(&surfaceProps)) {
556 SkDebugf("getProps failed unexpectedly.\n");
557 }
558 SkDebugf("isRGB:%d\n", SkPixelGeometryIsRGB(surfaceProps.pixelGeometry()));
559
560 #StdOut
561 isRGB:0
562 isRGB:1
563 #StdOut ##
564##
565
Cary Clark2ade9972017-11-02 17:49:34 -0400566#SeeAlso SkSurfaceProps makeSurface
Cary Clark8032b982017-07-28 11:04:54 -0400567
568##
569
570# ------------------------------------------------------------------------------
Cary Clark78de7512018-02-07 07:27:09 -0500571#Subtopic Utility
Cary Clark78de7512018-02-07 07:27:09 -0500572#Line # rarely called management functions ##
573##
Cary Clark8032b982017-07-28 11:04:54 -0400574
575#Method void flush()
Cary Clark78de7512018-02-07 07:27:09 -0500576#In Utility
Cary Clarkab2621d2018-01-30 10:08:57 -0500577#Line # triggers execution of all pending draw operations ##
Herb Derbyefe39bc2018-05-01 17:06:20 -0400578Triggers the immediate execution of all pending draw operations.
Cary Clarkbad5ad72017-08-03 17:14:08 -0400579If Canvas is associated with GPU_Surface, resolves all pending GPU operations.
Cary Clark2ade9972017-11-02 17:49:34 -0400580If Canvas is associated with Raster_Surface, has no effect; raster draw
581operations are never deferred.
582
583#ToDo
584In an overview section on managing the GPU, include:
585- flush should never change what is drawn
586- call to kick off gpu work
587- calling too much impacts performance
588- some calls (peekPixels, prepareForExternalIO) call it internally
589- canvas call is local, GrContext::flush is global
590- diffentiate between flush, flushAndSignalSemaphores
591- normally never needs to be called
592- call it when sharing gpu resources, feeling memory pressure, swapping out app, and before
593 abandoning context
594- also call to say "I'm finished drawing here", e.g., when drawing to a GPU-backed offscreen surface
595 (created with SkSurface::MakeRenderTarget)
596
597for posterity: this doesn't show a difference: fiddle.skia.org/c/@flushfail
598##
Cary Clark8032b982017-07-28 11:04:54 -0400599
Cary Clark08895c42018-02-01 09:37:32 -0500600#ToDo haven't thought of a useful example to put here ##
601#NoExample
Cary Clark8032b982017-07-28 11:04:54 -0400602##
603
Cary Clark2ade9972017-11-02 17:49:34 -0400604#SeeAlso peekPixels SkSurface::flush() GrContext::flush() SkSurface::prepareForExternalIO GrContext::abandonContext()
Cary Clark8032b982017-07-28 11:04:54 -0400605
606##
607
608# ------------------------------------------------------------------------------
609
610#Method virtual SkISize getBaseLayerSize() const
Cary Clark78de7512018-02-07 07:27:09 -0500611#In Property
Cary Clarkab2621d2018-01-30 10:08:57 -0500612#Line # returns size of base Layer in global coordinates ##
Cary Clarkce101242017-09-01 15:51:02 -0400613Gets the size of the base or root Layer in global canvas coordinates. The
614origin of the base Layer is always (0,0). The area available for drawing may be
Cary Clark8032b982017-07-28 11:04:54 -0400615smaller (due to clipping or saveLayer).
616
Cary Clarkce101242017-09-01 15:51:02 -0400617#Return integral width and height of base Layer ##
Cary Clark8032b982017-07-28 11:04:54 -0400618
619#Example
620 SkBitmap bitmap;
621 bitmap.allocPixels(SkImageInfo::MakeN32Premul(20, 30));
622 SkCanvas canvas(bitmap, SkSurfaceProps(0, kUnknown_SkPixelGeometry));
623 canvas.clipRect(SkRect::MakeWH(10, 40));
624 SkIRect clipDeviceBounds = canvas.getDeviceClipBounds();
625 if (clipDeviceBounds.isEmpty()) {
626 SkDebugf("Empty clip bounds is unexpected!\n");
627 }
628 SkDebugf("clip=%d,%d\n", clipDeviceBounds.width(), clipDeviceBounds.height());
629 SkISize baseLayerSize = canvas.getBaseLayerSize();
630 SkDebugf("size=%d,%d\n", baseLayerSize.width(), baseLayerSize.height());
631
632 #StdOut
633 clip=10,30
634 size=20,30
635 ##
636##
637
638#ToDo is this the same as the width and height of surface? ##
639
Cary Clark2ade9972017-11-02 17:49:34 -0400640#SeeAlso getDeviceClipBounds
641
Cary Clark8032b982017-07-28 11:04:54 -0400642##
643
644# ------------------------------------------------------------------------------
645
646#Method sk_sp<SkSurface> makeSurface(const SkImageInfo& info, const SkSurfaceProps* props = nullptr)
Cary Clark61313f32018-10-08 14:57:48 -0400647#In Constructors
Cary Clarkab2621d2018-01-30 10:08:57 -0500648#Line # creates Surface matching SkImageInfo and SkSurfaceProps ##
Cary Clark8032b982017-07-28 11:04:54 -0400649Creates Surface matching info and props, and associates it with Canvas.
Cary Clarkbad5ad72017-08-03 17:14:08 -0400650Returns nullptr if no match found.
Cary Clark8032b982017-07-28 11:04:54 -0400651
Cary Clarkbad5ad72017-08-03 17:14:08 -0400652If props is nullptr, matches Surface_Properties in Canvas. If props is nullptr and Canvas
653does not have Surface_Properties, creates Surface with default Surface_Properties.
Cary Clark8032b982017-07-28 11:04:54 -0400654
Cary Clark2dc84ad2018-01-26 12:56:22 -0500655#Param info width, height, Color_Type, Alpha_Type, and Color_Space ##
Cary Clarkbad5ad72017-08-03 17:14:08 -0400656#Param props Surface_Properties to match; may be nullptr to match Canvas ##
657
658#Return Surface matching info and props, or nullptr if no match is available ##
Cary Clark8032b982017-07-28 11:04:54 -0400659
660#Example
661 sk_sp<SkSurface> surface = SkSurface::MakeRasterN32Premul(5, 6);
662 SkCanvas* smallCanvas = surface->getCanvas();
663 SkImageInfo imageInfo = SkImageInfo::MakeN32Premul(3, 4);
664 sk_sp<SkSurface> compatible = smallCanvas->makeSurface(imageInfo);
665 SkDebugf("compatible %c= nullptr\n", compatible == nullptr ? '=' : '!');
666 SkDebugf("size = %d, %d\n", compatible->width(), compatible->height());
667
668 #StdOut
Cary Clarkbad5ad72017-08-03 17:14:08 -0400669 compatible != nullptr
Cary Clark8032b982017-07-28 11:04:54 -0400670 size = 3, 4
671 ##
672##
673
Cary Clark2ade9972017-11-02 17:49:34 -0400674#SeeAlso SkSurface SkSurface::makeSurface SkImageInfo SkSurfaceProps
Cary Clark8032b982017-07-28 11:04:54 -0400675
676##
677
678# ------------------------------------------------------------------------------
679
680#Method virtual GrContext* getGrContext()
Cary Clark78de7512018-02-07 07:27:09 -0500681#In Property
Cary Clarkab2621d2018-01-30 10:08:57 -0500682#Line # returns GPU_Context of the GPU_Surface ##
Cary Clark8032b982017-07-28 11:04:54 -0400683Returns GPU_Context of the GPU_Surface associated with Canvas.
684
Cary Clarkbad5ad72017-08-03 17:14:08 -0400685#Return GPU_Context, if available; nullptr otherwise ##
Cary Clark8032b982017-07-28 11:04:54 -0400686
687#Example
688void draw(SkCanvas* canvas) {
689 if (canvas->getGrContext()) {
690 canvas->clear(SK_ColorRED);
691 } else {
692 canvas->clear(SK_ColorBLUE);
693 }
694}
695##
696
697#ToDo fiddle should show both CPU and GPU out ##
698
Herb Derbyefe39bc2018-05-01 17:06:20 -0400699#SeeAlso GrContext
Cary Clark2ade9972017-11-02 17:49:34 -0400700
Cary Clark8032b982017-07-28 11:04:54 -0400701##
702
703# ------------------------------------------------------------------------------
704
Cary Clark73fa9722017-08-29 17:36:51 -0400705#Method void* accessTopLayerPixels(SkImageInfo* info, size_t* rowBytes, SkIPoint* origin = nullptr)
Cary Clark78de7512018-02-07 07:27:09 -0500706#In Utility
707#In Property
Cary Clarkab2621d2018-01-30 10:08:57 -0500708#Line # returns writable pixel access if available ##
Cary Clark8032b982017-07-28 11:04:54 -0400709Returns the pixel base address, Image_Info, rowBytes, and origin if the pixels
Cary Clarkbad5ad72017-08-03 17:14:08 -0400710can be read directly. The returned address is only valid
Cary Clark8032b982017-07-28 11:04:54 -0400711while Canvas is in scope and unchanged. Any Canvas call or Surface call
712may invalidate the returned address and other returned values.
713
714If pixels are inaccessible, info, rowBytes, and origin are unchanged.
715
Cary Clarkbad5ad72017-08-03 17:14:08 -0400716#Param info storage for writable pixels' Image_Info; may be nullptr ##
717#Param rowBytes storage for writable pixels' row bytes; may be nullptr ##
Cary Clarkbc5697d2017-10-04 14:31:33 -0400718#Param origin storage for Canvas top Layer origin, its top-left corner;
Cary Clarkbad5ad72017-08-03 17:14:08 -0400719 may be nullptr
720##
Cary Clark8032b982017-07-28 11:04:54 -0400721
Cary Clarka523d2d2017-08-30 08:58:10 -0400722#Return address of pixels, or nullptr if inaccessible ##
Cary Clark8032b982017-07-28 11:04:54 -0400723
724#Example
725void draw(SkCanvas* canvas) {
726 if (canvas->accessTopLayerPixels(nullptr, nullptr)) {
727 canvas->clear(SK_ColorRED);
728 } else {
729 canvas->clear(SK_ColorBLUE);
730 }
731}
732##
733
734#Example
735#Description
Cary Clarkce101242017-09-01 15:51:02 -0400736Draws "ABC" on the device. Then draws "DEF" in Layer, and reads
737Layer to add a large dotted "DEF". Finally blends Layer with the
Herb Derbyefe39bc2018-05-01 17:06:20 -0400738device.
Cary Clark8032b982017-07-28 11:04:54 -0400739
Cary Clarkce101242017-09-01 15:51:02 -0400740The Layer and blended result appear on the CPU and GPU but the large dotted
Cary Clark8032b982017-07-28 11:04:54 -0400741"DEF" appear only on the CPU.
742##
743void draw(SkCanvas* canvas) {
Cary Clarkbad5ad72017-08-03 17:14:08 -0400744 SkPaint paint;
745 paint.setTextSize(100);
746 canvas->drawString("ABC", 20, 160, paint);
747 SkRect layerBounds = SkRect::MakeXYWH(32, 32, 192, 192);
748 canvas->saveLayerAlpha(&layerBounds, 128);
749 canvas->clear(SK_ColorWHITE);
750 canvas->drawString("DEF", 20, 160, paint);
751 SkImageInfo imageInfo;
752 size_t rowBytes;
753 SkIPoint origin;
754 uint32_t* access = (uint32_t*) canvas->accessTopLayerPixels(&imageInfo, &rowBytes, &origin);
755 if (access) {
756 int h = imageInfo.height();
757 int v = imageInfo.width();
758 int rowWords = rowBytes / sizeof(uint32_t);
759 for (int y = 0; y < h; ++y) {
760 int newY = (y - h / 2) * 2 + h / 2;
761 if (newY < 0 || newY >= h) {
762 continue;
763 }
764 for (int x = 0; x < v; ++x) {
765 int newX = (x - v / 2) * 2 + v / 2;
766 if (newX < 0 || newX >= v) {
767 continue;
768 }
769 if (access[y * rowWords + x] == SK_ColorBLACK) {
770 access[newY * rowWords + newX] = SK_ColorGRAY;
771 }
772 }
773 }
774
775 }
Cary Clark8032b982017-07-28 11:04:54 -0400776 canvas->restore();
777}
778##
779
780#ToDo there are no callers of this that I can find. Deprecate? ##
781#ToDo fiddle should show both CPU and GPU out ##
782
Cary Clark2ade9972017-11-02 17:49:34 -0400783#SeeAlso SkImageInfo SkPixmap
784
Cary Clark8032b982017-07-28 11:04:54 -0400785##
786
787# ------------------------------------------------------------------------------
788
789#Method SkRasterHandleAllocator::Handle accessTopRasterHandle() const
Cary Clark78de7512018-02-07 07:27:09 -0500790#In Utility
791#In Property
Cary Clarkab2621d2018-01-30 10:08:57 -0500792#Line # returns context that tracks Clip and Matrix ##
Cary Clark8032b982017-07-28 11:04:54 -0400793Returns custom context that tracks the Matrix and Clip.
794
795Use Raster_Handle_Allocator to blend Skia drawing with custom drawing, typically performed
Cary Clarkbc5697d2017-10-04 14:31:33 -0400796by the host platform user interface. The custom context returned is generated by
Cary Clarkbad5ad72017-08-03 17:14:08 -0400797SkRasterHandleAllocator::MakeCanvas, which creates a custom canvas with raster storage for
Cary Clark8032b982017-07-28 11:04:54 -0400798the drawing destination.
799
Cary Clarkce101242017-09-01 15:51:02 -0400800#Return context of custom allocation ##
Cary Clark8032b982017-07-28 11:04:54 -0400801
802#Example
803#Description
804#ToDo ##
805##
806#Function
807 static void DeleteCallback(void*, void* context) {
808 delete (char*) context;
809 }
810
811 class CustomAllocator : public SkRasterHandleAllocator {
812 public:
813 bool allocHandle(const SkImageInfo& info, Rec* rec) override {
814 char* context = new char[4]{'s', 'k', 'i', 'a'};
815 rec->fReleaseProc = DeleteCallback;
816 rec->fReleaseCtx = context;
817 rec->fHandle = context;
818 rec->fPixels = context;
819 rec->fRowBytes = 4;
820 return true;
821 }
822
823 void updateHandle(Handle handle, const SkMatrix& ctm, const SkIRect& clip_bounds) override {
824 // apply canvas matrix and clip to custom environment
825 }
826 };
827
828##
829 void draw(SkCanvas* canvas) {
830 const SkImageInfo info = SkImageInfo::MakeN32Premul(1, 1);
831 std::unique_ptr<SkCanvas> c2 =
832 SkRasterHandleAllocator::MakeCanvas(std::unique_ptr<CustomAllocator>(
833 new CustomAllocator()), info);
834 char* context = (char*) c2->accessTopRasterHandle();
835 SkDebugf("context = %.4s\n", context);
836
837 }
838 #StdOut
839 context = skia
840 ##
841 #ToDo skstd::make_unique could not be used because def is private -- note to fix in c++14? ##
842##
843
844#SeeAlso SkRasterHandleAllocator
845
846##
847
848# ------------------------------------------------------------------------------
Cary Clark78de7512018-02-07 07:27:09 -0500849#Subtopic Pixels
Cary Clark78de7512018-02-07 07:27:09 -0500850#Line # read and write pixel values ##
851##
Cary Clark8032b982017-07-28 11:04:54 -0400852
853#Method bool peekPixels(SkPixmap* pixmap)
Cary Clark78de7512018-02-07 07:27:09 -0500854#In Pixels
Cary Clarkab2621d2018-01-30 10:08:57 -0500855#Line # returns if Canvas has direct access to its pixels ##
Cary Clark8032b982017-07-28 11:04:54 -0400856Returns true if Canvas has direct access to its pixels.
857
Cary Clarkf05bdda2017-08-24 12:59:48 -0400858Pixels are readable when Device is raster. Pixels are not readable when Canvas
Cary Clarkbad5ad72017-08-03 17:14:08 -0400859is returned from GPU_Surface, returned by SkDocument::beginPage, returned by
Cary Clarkf05bdda2017-08-24 12:59:48 -0400860SkPictureRecorder::beginRecording, or Canvas is the base of a utility class
Brian Osman46fe9c72018-03-09 15:44:34 -0500861like SkDebugCanvas.
Cary Clark8032b982017-07-28 11:04:54 -0400862
Cary Clarkf05bdda2017-08-24 12:59:48 -0400863pixmap is valid only while Canvas is in scope and unchanged. Any
Cary Clarkbad5ad72017-08-03 17:14:08 -0400864Canvas or Surface call may invalidate the pixmap values.
Cary Clark8032b982017-07-28 11:04:54 -0400865
Cary Clarkbc5697d2017-10-04 14:31:33 -0400866#Param pixmap storage for pixel state if pixels are readable; otherwise, ignored ##
Cary Clark8032b982017-07-28 11:04:54 -0400867
Cary Clarkbad5ad72017-08-03 17:14:08 -0400868#Return true if Canvas has direct access to pixels ##
Cary Clark8032b982017-07-28 11:04:54 -0400869
870#Example
871 SkPixmap pixmap;
872 if (canvas->peekPixels(&pixmap)) {
873 SkDebugf("width=%d height=%d\n", pixmap.bounds().width(), pixmap.bounds().height());
874 }
875 #StdOut
876 width=256 height=256
877 ##
878##
879
Cary Clark2ade9972017-11-02 17:49:34 -0400880#SeeAlso readPixels SkBitmap::peekPixels SkImage::peekPixels SkSurface::peekPixels
881
Cary Clark8032b982017-07-28 11:04:54 -0400882##
883
884# ------------------------------------------------------------------------------
885
886#Method bool readPixels(const SkImageInfo& dstInfo, void* dstPixels, size_t dstRowBytes,
887 int srcX, int srcY)
Cary Clark78de7512018-02-07 07:27:09 -0500888#In Pixels
Cary Clarkab2621d2018-01-30 10:08:57 -0500889#Line # copies and converts rectangle of pixels from Canvas ##
Cary Clark8032b982017-07-28 11:04:54 -0400890
Cary Clark154beea2017-10-26 07:58:48 -0400891Copies Rect of pixels from Canvas into dstPixels. Matrix and Clip are
Herb Derbyefe39bc2018-05-01 17:06:20 -0400892ignored.
Cary Clark6fc50412017-09-21 12:31:06 -0400893
Cary Clarka560c472017-11-27 10:44:06 -0500894Source Rect corners are (srcX, srcY) and (imageInfo().width(), imageInfo().height()).
895Destination Rect corners are (0, 0) and (dstInfo.width(), dstInfo.height()).
Cary Clark6fc50412017-09-21 12:31:06 -0400896Copies each readable pixel intersecting both rectangles, without scaling,
Cary Clarkf05bdda2017-08-24 12:59:48 -0400897converting to dstInfo.colorType() and dstInfo.alphaType() if required.
Cary Clark8032b982017-07-28 11:04:54 -0400898
Cary Clarkf05bdda2017-08-24 12:59:48 -0400899Pixels are readable when Device is raster, or backed by a GPU.
900Pixels are not readable when SkCanvas is returned by SkDocument::beginPage,
901returned by SkPictureRecorder::beginRecording, or Canvas is the base of a utility
Brian Osman46fe9c72018-03-09 15:44:34 -0500902class like SkDebugCanvas.
Cary Clark8032b982017-07-28 11:04:54 -0400903
Cary Clarkf05bdda2017-08-24 12:59:48 -0400904The destination pixel storage must be allocated by the caller.
Cary Clark8032b982017-07-28 11:04:54 -0400905
Cary Clark2dc84ad2018-01-26 12:56:22 -0500906Pixel values are converted only if Color_Type and Alpha_Type
Cary Clarkf05bdda2017-08-24 12:59:48 -0400907do not match. Only pixels within both source and destination rectangles
Cary Clark154beea2017-10-26 07:58:48 -0400908are copied. dstPixels contents outside Rect intersection are unchanged.
Cary Clarkf05bdda2017-08-24 12:59:48 -0400909
910Pass negative values for srcX or srcY to offset pixels across or down destination.
Cary Clark8032b982017-07-28 11:04:54 -0400911
912Does not copy, and returns false if:
913
914#List
Cary Clarkf05bdda2017-08-24 12:59:48 -0400915# Source and destination rectangles do not intersect. ##
916# Canvas pixels could not be converted to dstInfo.colorType() or dstInfo.alphaType(). ##
917# Canvas pixels are not readable; for instance, Canvas is document-based. ##
Cary Clark8032b982017-07-28 11:04:54 -0400918# dstRowBytes is too small to contain one row of pixels. ##
919##
920
Cary Clark2dc84ad2018-01-26 12:56:22 -0500921#Param dstInfo width, height, Color_Type, and Alpha_Type of dstPixels ##
Cary Clarkf05bdda2017-08-24 12:59:48 -0400922#Param dstPixels storage for pixels; dstInfo.height() times dstRowBytes, or larger ##
923#Param dstRowBytes size of one destination row; dstInfo.width() times pixel size, or larger ##
Cary Clark5538c132018-06-14 12:28:14 -0400924#Param srcX offset into readable pixels on x-axis; may be negative ##
925#Param srcY offset into readable pixels on y-axis; may be negative ##
Cary Clark8032b982017-07-28 11:04:54 -0400926
Cary Clarkbad5ad72017-08-03 17:14:08 -0400927#Return true if pixels were copied ##
Cary Clark8032b982017-07-28 11:04:54 -0400928
929#Example
Cary Clarkf05bdda2017-08-24 12:59:48 -0400930#Width 64
931#Height 64
932#Description
933 A black circle drawn on a blue background provides an image to copy.
934 readPixels copies one quarter of the canvas into each of the four corners.
Cary Clarka560c472017-11-27 10:44:06 -0500935 The copied quarter circles overdraw the original circle.
Cary Clarkf05bdda2017-08-24 12:59:48 -0400936##
937 canvas->clear(SK_ColorBLUE);
938 SkPaint paint;
939 canvas->drawCircle(32, 32, 28, paint);
940 SkImageInfo info = SkImageInfo::Make(64, 64, kBGRA_8888_SkColorType, kPremul_SkAlphaType);
941 sk_sp<SkData> data(SkData::MakeUninitialized(info.minRowBytes() * info.height()));
942 sk_bzero(data->writable_data(), info.minRowBytes() * info.height());
943 for (int x : { 32, -32 } ) {
944 for (int y : { 32, -32 } ) {
945 canvas->readPixels(info, data->writable_data(), info.minRowBytes(), x, y);
Herb Derbyefe39bc2018-05-01 17:06:20 -0400946 }
Cary Clarkf05bdda2017-08-24 12:59:48 -0400947 }
948 sk_sp<SkImage> image = SkImage::MakeRasterData(info, data, info.minRowBytes());
949 canvas->drawImage(image, 0, 0);
950##
951
952#Example
Cary Clark8032b982017-07-28 11:04:54 -0400953#Description
Cary Clarkce101242017-09-01 15:51:02 -0400954 Canvas returned by Raster_Surface has Premultiplied pixel values.
955 clear() takes Unpremultiplied input with Color_Alpha equal 0x80
Cary Clarkffb3d682018-05-17 12:17:28 -0400956 and RGB equal 0x55, 0xAA, 0xFF. RGB is multiplied by Color_Alpha
Cary Clarkce101242017-09-01 15:51:02 -0400957 to generate Premultiplied value 0x802B5580. readPixels converts pixel back
958 to Unpremultiplied value 0x8056A9FF, introducing error.
Cary Clark8032b982017-07-28 11:04:54 -0400959##
960 canvas->clear(0x8055aaff);
961 for (SkAlphaType alphaType : { kPremul_SkAlphaType, kUnpremul_SkAlphaType } ) {
962 uint32_t pixel = 0;
963 SkImageInfo info = SkImageInfo::Make(1, 1, kBGRA_8888_SkColorType, alphaType);
964 if (canvas->readPixels(info, &pixel, 4, 0, 0)) {
965 SkDebugf("pixel = %08x\n", pixel);
966 }
967 }
968
969 #StdOut
970 pixel = 802b5580
971 pixel = 8056a9ff
972 ##
973##
974
Cary Clark2ade9972017-11-02 17:49:34 -0400975#SeeAlso peekPixels writePixels drawBitmap drawImage SkBitmap::readPixels SkPixmap::readPixels SkImage::readPixels SkSurface::readPixels
Cary Clark8032b982017-07-28 11:04:54 -0400976
977##
978
979# ------------------------------------------------------------------------------
980
981#Method bool readPixels(const SkPixmap& pixmap, int srcX, int srcY)
982
Cary Clark154beea2017-10-26 07:58:48 -0400983Copies Rect of pixels from Canvas into pixmap. Matrix and Clip are
Cary Clarka560c472017-11-27 10:44:06 -0500984ignored.
Cary Clark6fc50412017-09-21 12:31:06 -0400985
Cary Clarka560c472017-11-27 10:44:06 -0500986Source Rect corners are (srcX, srcY) and (imageInfo().width(), imageInfo().height()).
987Destination Rect corners are (0, 0) and (pixmap.width(), pixmap.height()).
Cary Clark6fc50412017-09-21 12:31:06 -0400988Copies each readable pixel intersecting both rectangles, without scaling,
Cary Clarkf05bdda2017-08-24 12:59:48 -0400989converting to pixmap.colorType() and pixmap.alphaType() if required.
Cary Clark8032b982017-07-28 11:04:54 -0400990
Cary Clarkf05bdda2017-08-24 12:59:48 -0400991Pixels are readable when Device is raster, or backed by a GPU.
992Pixels are not readable when SkCanvas is returned by SkDocument::beginPage,
993returned by SkPictureRecorder::beginRecording, or Canvas is the base of a utility
Brian Osman46fe9c72018-03-09 15:44:34 -0500994class like SkDebugCanvas.
Cary Clark8032b982017-07-28 11:04:54 -0400995
Cary Clark6fc50412017-09-21 12:31:06 -0400996Caller must allocate pixel storage in pixmap if needed.
Cary Clark8032b982017-07-28 11:04:54 -0400997
Cary Clark2dc84ad2018-01-26 12:56:22 -0500998Pixel values are converted only if Color_Type and Alpha_Type
Cary Clark154beea2017-10-26 07:58:48 -0400999do not match. Only pixels within both source and destination Rects
1000are copied. pixmap pixels contents outside Rect intersection are unchanged.
Cary Clarkf05bdda2017-08-24 12:59:48 -04001001
1002Pass negative values for srcX or srcY to offset pixels across or down pixmap.
Cary Clark8032b982017-07-28 11:04:54 -04001003
1004Does not copy, and returns false if:
1005
1006#List
Cary Clarkf05bdda2017-08-24 12:59:48 -04001007# Source and destination rectangles do not intersect. ##
1008# Canvas pixels could not be converted to pixmap.colorType() or pixmap.alphaType(). ##
1009# Canvas pixels are not readable; for instance, Canvas is document-based. ##
1010# Pixmap pixels could not be allocated. ##
1011# pixmap.rowBytes() is too small to contain one row of pixels. ##
Cary Clark8032b982017-07-28 11:04:54 -04001012##
1013
Cary Clarkbad5ad72017-08-03 17:14:08 -04001014#Param pixmap storage for pixels copied from Canvas ##
Cary Clark5538c132018-06-14 12:28:14 -04001015#Param srcX offset into readable pixels on x-axis; may be negative ##
1016#Param srcY offset into readable pixels on y-axis; may be negative ##
Cary Clark8032b982017-07-28 11:04:54 -04001017
Cary Clarkbad5ad72017-08-03 17:14:08 -04001018#Return true if pixels were copied ##
Cary Clark8032b982017-07-28 11:04:54 -04001019
1020#Example
Cary Clarkf05bdda2017-08-24 12:59:48 -04001021 #Description
Cary Clarkce101242017-09-01 15:51:02 -04001022 clear() takes Unpremultiplied input with Color_Alpha equal 0x80
Cary Clarkffb3d682018-05-17 12:17:28 -04001023 and RGB equal 0x55, 0xAA, 0xFF. RGB is multiplied by Color_Alpha
Cary Clarkce101242017-09-01 15:51:02 -04001024 to generate Premultiplied value 0x802B5580.
Cary Clarkf05bdda2017-08-24 12:59:48 -04001025 ##
1026 void draw(SkCanvas* canvas) {
1027 canvas->clear(0x8055aaff);
1028 uint32_t pixels[1] = { 0 };
1029 SkPixmap pixmap(SkImageInfo::MakeN32Premul(1, 1), pixels, 4);
1030 canvas->readPixels(pixmap, 0, 0);
1031 SkDebugf("pixel = %08x\n", pixels[0]);
1032 }
Cary Clark8032b982017-07-28 11:04:54 -04001033 #StdOut
1034 pixel = 802b5580
1035 ##
1036##
1037
Cary Clark2ade9972017-11-02 17:49:34 -04001038#SeeAlso peekPixels writePixels drawBitmap drawImage SkBitmap::readPixels SkPixmap::readPixels SkImage::readPixels SkSurface::readPixels
Cary Clark8032b982017-07-28 11:04:54 -04001039
1040##
1041
1042# ------------------------------------------------------------------------------
1043
1044#Method bool readPixels(const SkBitmap& bitmap, int srcX, int srcY)
1045
Cary Clark154beea2017-10-26 07:58:48 -04001046Copies Rect of pixels from Canvas into bitmap. Matrix and Clip are
Cary Clarka560c472017-11-27 10:44:06 -05001047ignored.
Cary Clark6fc50412017-09-21 12:31:06 -04001048
Cary Clarka560c472017-11-27 10:44:06 -05001049Source Rect corners are (srcX, srcY) and (imageInfo().width(), imageInfo().height()).
Cary Clark154beea2017-10-26 07:58:48 -04001050Destination Rect corners are (0, 0) and (bitmap.width(), bitmap.height()).
Cary Clarkf05bdda2017-08-24 12:59:48 -04001051Copies each readable pixel intersecting both rectangles, without scaling,
1052converting to bitmap.colorType() and bitmap.alphaType() if required.
Cary Clark8032b982017-07-28 11:04:54 -04001053
Cary Clarkf05bdda2017-08-24 12:59:48 -04001054Pixels are readable when Device is raster, or backed by a GPU.
1055Pixels are not readable when SkCanvas is returned by SkDocument::beginPage,
1056returned by SkPictureRecorder::beginRecording, or Canvas is the base of a utility
Brian Osman46fe9c72018-03-09 15:44:34 -05001057class like SkDebugCanvas.
Cary Clark8032b982017-07-28 11:04:54 -04001058
Cary Clark6fc50412017-09-21 12:31:06 -04001059Caller must allocate pixel storage in bitmap if needed.
Cary Clarkf05bdda2017-08-24 12:59:48 -04001060
Cary Clark2dc84ad2018-01-26 12:56:22 -05001061Bitmap values are converted only if Color_Type and Alpha_Type
Cary Clarkf05bdda2017-08-24 12:59:48 -04001062do not match. Only pixels within both source and destination rectangles
Cary Clark154beea2017-10-26 07:58:48 -04001063are copied. Bitmap pixels outside Rect intersection are unchanged.
Cary Clarkf05bdda2017-08-24 12:59:48 -04001064
1065Pass negative values for srcX or srcY to offset pixels across or down bitmap.
Cary Clark8032b982017-07-28 11:04:54 -04001066
1067Does not copy, and returns false if:
1068
1069#List
Cary Clarkf05bdda2017-08-24 12:59:48 -04001070# Source and destination rectangles do not intersect. ##
1071# Canvas pixels could not be converted to bitmap.colorType() or bitmap.alphaType(). ##
1072# Canvas pixels are not readable; for instance, Canvas is document-based. ##
Cary Clark8032b982017-07-28 11:04:54 -04001073# bitmap pixels could not be allocated. ##
Cary Clarkf05bdda2017-08-24 12:59:48 -04001074# bitmap.rowBytes() is too small to contain one row of pixels. ##
Cary Clark8032b982017-07-28 11:04:54 -04001075##
1076
Cary Clarkbad5ad72017-08-03 17:14:08 -04001077#Param bitmap storage for pixels copied from Canvas ##
Cary Clark5538c132018-06-14 12:28:14 -04001078#Param srcX offset into readable pixels on x-axis; may be negative ##
1079#Param srcY offset into readable pixels on y-axis; may be negative ##
Cary Clark8032b982017-07-28 11:04:54 -04001080
Cary Clarkbad5ad72017-08-03 17:14:08 -04001081#Return true if pixels were copied ##
Cary Clark8032b982017-07-28 11:04:54 -04001082
1083#Example
Cary Clarkf05bdda2017-08-24 12:59:48 -04001084 #Description
Cary Clarkce101242017-09-01 15:51:02 -04001085 clear() takes Unpremultiplied input with Color_Alpha equal 0x80
Cary Clarkffb3d682018-05-17 12:17:28 -04001086 and RGB equal 0x55, 0xAA, 0xFF. RGB is multiplied by Color_Alpha
Cary Clarkce101242017-09-01 15:51:02 -04001087 to generate Premultiplied value 0x802B5580.
Cary Clarkf05bdda2017-08-24 12:59:48 -04001088 ##
Cary Clark8032b982017-07-28 11:04:54 -04001089void draw(SkCanvas* canvas) {
1090 canvas->clear(0x8055aaff);
1091 SkBitmap bitmap;
1092 bitmap.allocPixels(SkImageInfo::MakeN32Premul(1, 1));
1093 canvas->readPixels(bitmap, 0, 0);
1094 SkDebugf("pixel = %08x\n", bitmap.getAddr32(0, 0)[0]);
1095}
1096 #StdOut
1097 pixel = 802b5580
1098 ##
1099##
1100
Cary Clark2ade9972017-11-02 17:49:34 -04001101#SeeAlso peekPixels writePixels drawBitmap drawImage SkBitmap::readPixels SkPixmap::readPixels SkImage::readPixels SkSurface::readPixels
Cary Clark8032b982017-07-28 11:04:54 -04001102
1103##
1104
1105# ------------------------------------------------------------------------------
1106
1107#Method bool writePixels(const SkImageInfo& info, const void* pixels, size_t rowBytes, int x, int y)
Cary Clark78de7512018-02-07 07:27:09 -05001108#In Pixels
Cary Clarkab2621d2018-01-30 10:08:57 -05001109#Line # copies and converts rectangle of pixels to Canvas ##
Cary Clark154beea2017-10-26 07:58:48 -04001110Copies Rect from pixels to Canvas. Matrix and Clip are ignored.
1111Source Rect corners are (0, 0) and (info.width(), info.height()).
1112Destination Rect corners are (x, y) and
1113(imageInfo().width(), imageInfo().height()).
Cary Clark6fc50412017-09-21 12:31:06 -04001114
1115Copies each readable pixel intersecting both rectangles, without scaling,
Cary Clark154beea2017-10-26 07:58:48 -04001116converting to imageInfo().colorType() and imageInfo().alphaType() if required.
Cary Clark8032b982017-07-28 11:04:54 -04001117
Cary Clarkf05bdda2017-08-24 12:59:48 -04001118Pixels are writable when Device is raster, or backed by a GPU.
1119Pixels are not writable when SkCanvas is returned by SkDocument::beginPage,
1120returned by SkPictureRecorder::beginRecording, or Canvas is the base of a utility
Brian Osman46fe9c72018-03-09 15:44:34 -05001121class like SkDebugCanvas.
Cary Clark8032b982017-07-28 11:04:54 -04001122
Cary Clark2dc84ad2018-01-26 12:56:22 -05001123Pixel values are converted only if Color_Type and Alpha_Type
Cary Clarkf05bdda2017-08-24 12:59:48 -04001124do not match. Only pixels within both source and destination rectangles
Cary Clark154beea2017-10-26 07:58:48 -04001125are copied. Canvas pixels outside Rect intersection are unchanged.
Cary Clark8032b982017-07-28 11:04:54 -04001126
Cary Clarkf05bdda2017-08-24 12:59:48 -04001127Pass negative values for x or y to offset pixels to the left or
1128above Canvas pixels.
Cary Clark8032b982017-07-28 11:04:54 -04001129
1130Does not copy, and returns false if:
1131
1132#List
Cary Clarkf05bdda2017-08-24 12:59:48 -04001133# Source and destination rectangles do not intersect. ##
Cary Clarkac47b882018-01-11 10:35:44 -05001134# pixels could not be converted to Canvas imageInfo().colorType() or
1135 imageInfo().alphaType(). ##
Cary Clark8032b982017-07-28 11:04:54 -04001136# Canvas pixels are not writable; for instance, Canvas is document-based. ##
1137# rowBytes is too small to contain one row of pixels. ##
1138##
1139
Cary Clark2dc84ad2018-01-26 12:56:22 -05001140#Param info width, height, Color_Type, and Alpha_Type of pixels ##
Cary Clarkf05bdda2017-08-24 12:59:48 -04001141#Param pixels pixels to copy, of size info.height() times rowBytes, or larger ##
Cary Clarkd0530ba2017-09-14 11:25:39 -04001142#Param rowBytes size of one row of pixels; info.width() times pixel size, or larger ##
Cary Clark5538c132018-06-14 12:28:14 -04001143#Param x offset into Canvas writable pixels on x-axis; may be negative ##
1144#Param y offset into Canvas writable pixels on y-axis; may be negative ##
Cary Clark8032b982017-07-28 11:04:54 -04001145
Cary Clarkbad5ad72017-08-03 17:14:08 -04001146#Return true if pixels were written to Canvas ##
Cary Clark8032b982017-07-28 11:04:54 -04001147
1148#Example
1149 SkImageInfo imageInfo = SkImageInfo::MakeN32(256, 1, kPremul_SkAlphaType);
1150 for (int y = 0; y < 256; ++y) {
1151 uint32_t pixels[256];
1152 for (int x = 0; x < 256; ++x) {
1153 pixels[x] = SkColorSetARGB(x, x + y, x, x - y);
1154 }
1155 canvas->writePixels(imageInfo, &pixels, sizeof(pixels), 0, y);
1156 }
1157##
1158
Cary Clark2ade9972017-11-02 17:49:34 -04001159#SeeAlso readPixels drawBitmap drawImage SkBitmap::writePixels
Cary Clark8032b982017-07-28 11:04:54 -04001160
1161##
1162
1163# ------------------------------------------------------------------------------
1164
1165#Method bool writePixels(const SkBitmap& bitmap, int x, int y)
1166
Cary Clark154beea2017-10-26 07:58:48 -04001167Copies Rect from pixels to Canvas. Matrix and Clip are ignored.
1168Source Rect corners are (0, 0) and (bitmap.width(), bitmap.height()).
Cary Clark6fc50412017-09-21 12:31:06 -04001169
Cary Clark154beea2017-10-26 07:58:48 -04001170Destination Rect corners are (x, y) and
1171(imageInfo().width(), imageInfo().height()).
Cary Clark6fc50412017-09-21 12:31:06 -04001172
1173Copies each readable pixel intersecting both rectangles, without scaling,
Cary Clark154beea2017-10-26 07:58:48 -04001174converting to imageInfo().colorType() and imageInfo().alphaType() if required.
Cary Clark8032b982017-07-28 11:04:54 -04001175
Cary Clarkf05bdda2017-08-24 12:59:48 -04001176Pixels are writable when Device is raster, or backed by a GPU.
1177Pixels are not writable when SkCanvas is returned by SkDocument::beginPage,
1178returned by SkPictureRecorder::beginRecording, or Canvas is the base of a utility
Brian Osman46fe9c72018-03-09 15:44:34 -05001179class like SkDebugCanvas.
Cary Clark8032b982017-07-28 11:04:54 -04001180
Cary Clark2dc84ad2018-01-26 12:56:22 -05001181Pixel values are converted only if Color_Type and Alpha_Type
Cary Clarkf05bdda2017-08-24 12:59:48 -04001182do not match. Only pixels within both source and destination rectangles
Cary Clark154beea2017-10-26 07:58:48 -04001183are copied. Canvas pixels outside Rect intersection are unchanged.
Cary Clark8032b982017-07-28 11:04:54 -04001184
Cary Clarkf05bdda2017-08-24 12:59:48 -04001185Pass negative values for x or y to offset pixels to the left or
1186above Canvas pixels.
Cary Clark8032b982017-07-28 11:04:54 -04001187
1188Does not copy, and returns false if:
1189
1190#List
Cary Clarkf05bdda2017-08-24 12:59:48 -04001191# Source and destination rectangles do not intersect. ##
Cary Clark8032b982017-07-28 11:04:54 -04001192# bitmap does not have allocated pixels. ##
Cary Clarkac47b882018-01-11 10:35:44 -05001193# bitmap pixels could not be converted to Canvas imageInfo().colorType() or
1194 imageInfo().alphaType(). ##
Cary Clarkce101242017-09-01 15:51:02 -04001195# Canvas pixels are not writable; for instance, Canvas is document based. ##
Cary Clark8032b982017-07-28 11:04:54 -04001196# bitmap pixels are inaccessible; for instance, bitmap wraps a texture. ##
1197##
1198
Cary Clarkbad5ad72017-08-03 17:14:08 -04001199#Param bitmap contains pixels copied to Canvas ##
Cary Clarkf05bdda2017-08-24 12:59:48 -04001200#Param x offset into Canvas writable pixels in x; may be negative ##
1201#Param y offset into Canvas writable pixels in y; may be negative ##
Cary Clark8032b982017-07-28 11:04:54 -04001202
Cary Clarkbad5ad72017-08-03 17:14:08 -04001203#Return true if pixels were written to Canvas ##
Cary Clark8032b982017-07-28 11:04:54 -04001204
1205#Example
1206void draw(SkCanvas* canvas) {
1207 SkImageInfo imageInfo = SkImageInfo::MakeN32Premul(2, 2);
1208 SkBitmap bitmap;
1209 bitmap.setInfo(imageInfo);
1210 uint32_t pixels[4];
1211 bitmap.setPixels(pixels);
1212 for (int y = 0; y < 256; y += 2) {
1213 for (int x = 0; x < 256; x += 2) {
1214 pixels[0] = SkColorSetRGB(x, y, x | y);
1215 pixels[1] = SkColorSetRGB(x ^ y, y, x);
1216 pixels[2] = SkColorSetRGB(x, x & y, y);
1217 pixels[3] = SkColorSetRGB(~x, ~y, x);
1218 canvas->writePixels(bitmap, x, y);
1219 }
1220 }
1221}
1222##
1223
Cary Clark2ade9972017-11-02 17:49:34 -04001224#SeeAlso readPixels drawBitmap drawImage SkBitmap::writePixels
Cary Clark8032b982017-07-28 11:04:54 -04001225
1226##
1227
1228# ------------------------------------------------------------------------------
Cary Clark08895c42018-02-01 09:37:32 -05001229#Subtopic State_Stack
1230#Line # stack of state for hierarchical drawing ##
Cary Clark8032b982017-07-28 11:04:54 -04001231
1232Canvas maintains a stack of state that allows hierarchical drawing, commonly used
Cary Clarkbad5ad72017-08-03 17:14:08 -04001233to implement windows and views. The initial state has an identity matrix and and
1234an infinite clip. Even with a wide-open clip, drawing is constrained by the
1235bounds of the Canvas Surface or Device.
Cary Clark8032b982017-07-28 11:04:54 -04001236
Cary Clark939fd6c2018-07-12 08:40:13 -04001237Canvas savable state consists of Clip and Matrix.
Cary Clark8032b982017-07-28 11:04:54 -04001238Clip describes the area that may be drawn to.
1239Matrix transforms the geometry.
Cary Clark8032b982017-07-28 11:04:54 -04001240
1241save(), saveLayer, saveLayerPreserveLCDTextRequests, and saveLayerAlpha
1242save state and return the depth of the stack.
1243
Cary Clarkbad5ad72017-08-03 17:14:08 -04001244restore(), restoreToCount, and ~SkCanvas() revert state to its value when saved.
Cary Clark8032b982017-07-28 11:04:54 -04001245
1246Each state on the stack intersects Clip with the previous Clip,
1247and concatenates Matrix with the previous Matrix.
1248The intersected Clip makes the drawing area the same or smaller;
1249the concatenated Matrix may move the origin and potentially scale or rotate
1250the coordinate space.
1251
1252Canvas does not require balancing the state stack but it is a good idea
1253to do so. Calling save() without restore() will eventually cause Skia to fail;
1254mismatched save() and restore() create hard to find bugs.
1255
1256It is not possible to use state to draw outside of the clip defined by the
1257previous state.
1258
1259#Example
1260#Description
1261Draw to ever smaller clips; then restore drawing to full canvas.
1262Note that the second clipRect is not permitted to enlarge Clip.
1263##
1264#Height 160
Cary Clarkbad5ad72017-08-03 17:14:08 -04001265void draw(SkCanvas* canvas) {
1266 SkPaint paint;
Herb Derbyefe39bc2018-05-01 17:06:20 -04001267 canvas->save(); // records stack depth to restore
Cary Clarkbad5ad72017-08-03 17:14:08 -04001268 canvas->clipRect(SkRect::MakeWH(100, 100)); // constrains drawing to clip
1269 canvas->clear(SK_ColorRED); // draws to limit of clip
Herb Derbyefe39bc2018-05-01 17:06:20 -04001270 canvas->save(); // records stack depth to restore
Cary Clarkbad5ad72017-08-03 17:14:08 -04001271 canvas->clipRect(SkRect::MakeWH(50, 150)); // Rect below 100 is ignored
1272 canvas->clear(SK_ColorBLUE); // draws to smaller clip
1273 canvas->restore(); // enlarges clip
1274 canvas->drawLine(20, 20, 150, 150, paint); // line below 100 is not drawn
1275 canvas->restore(); // enlarges clip
1276 canvas->drawLine(150, 20, 50, 120, paint); // line below 100 is drawn
Cary Clark8032b982017-07-28 11:04:54 -04001277}
Herb Derbyefe39bc2018-05-01 17:06:20 -04001278##
Cary Clark8032b982017-07-28 11:04:54 -04001279
1280Each Clip uses the current Matrix for its coordinates.
1281
1282#Example
1283#Description
1284While clipRect is given the same rectangle twice, Matrix makes the second
1285clipRect draw at half the size of the first.
1286##
1287#Height 128
Cary Clarkbad5ad72017-08-03 17:14:08 -04001288void draw(SkCanvas* canvas) {
1289 canvas->clipRect(SkRect::MakeWH(100, 100));
1290 canvas->clear(SK_ColorRED);
1291 canvas->scale(.5, .5);
1292 canvas->clipRect(SkRect::MakeWH(100, 100));
1293 canvas->clear(SK_ColorBLUE);
Cary Clark8032b982017-07-28 11:04:54 -04001294}
1295##
1296
1297#SeeAlso save() saveLayer saveLayerPreserveLCDTextRequests saveLayerAlpha restore() restoreToCount
1298
1299#Method int save()
1300
Cary Clarkab2621d2018-01-30 10:08:57 -05001301#In State_Stack
1302#Line # saves Clip and Matrix on stack ##
Cary Clark939fd6c2018-07-12 08:40:13 -04001303Saves Matrix and Clip.
1304Calling restore() discards changes to Matrix and Clip,
1305restoring the Matrix and Clip to their state when save() was called.
Cary Clark8032b982017-07-28 11:04:54 -04001306
Cary Clarkbad5ad72017-08-03 17:14:08 -04001307Matrix may be changed by translate(), scale(), rotate(), skew(), concat(), setMatrix,
1308and resetMatrix. Clip may be changed by clipRect, clipRRect, clipPath, clipRegion.
Cary Clark8032b982017-07-28 11:04:54 -04001309
Cary Clarkbad5ad72017-08-03 17:14:08 -04001310Saved Canvas state is put on a stack; multiple calls to save() should be balance
1311by an equal number of calls to restore().
Cary Clark8032b982017-07-28 11:04:54 -04001312
1313Call restoreToCount with result to restore this and subsequent saves.
1314
Cary Clarkbad5ad72017-08-03 17:14:08 -04001315#Return depth of saved stack ##
Cary Clark8032b982017-07-28 11:04:54 -04001316
1317#Example
Herb Derbyefe39bc2018-05-01 17:06:20 -04001318#Description
Cary Clark8032b982017-07-28 11:04:54 -04001319The black square is translated 50 pixels down and to the right.
1320Restoring Canvas state removes translate() from Canvas stack;
1321the red square is not translated, and is drawn at the origin.
1322##
1323#Height 100
1324void draw(SkCanvas* canvas) {
1325 SkPaint paint;
1326 SkRect rect = { 0, 0, 25, 25 };
1327 canvas->drawRect(rect, paint);
1328 canvas->save();
1329 canvas->translate(50, 50);
1330 canvas->drawRect(rect, paint);
1331 canvas->restore();
1332 paint.setColor(SK_ColorRED);
1333 canvas->drawRect(rect, paint);
1334}
1335##
1336
Cary Clark2ade9972017-11-02 17:49:34 -04001337#SeeAlso saveLayer saveLayerPreserveLCDTextRequests saveLayerAlpha restore() restoreToCount
Cary Clark8032b982017-07-28 11:04:54 -04001338
1339##
1340
1341# ------------------------------------------------------------------------------
Cary Clark8032b982017-07-28 11:04:54 -04001342
1343#Method void restore()
1344
Cary Clarkab2621d2018-01-30 10:08:57 -05001345#In State_Stack
1346#Line # restores changes to Clip and Matrix, pops save stack ##
Cary Clark939fd6c2018-07-12 08:40:13 -04001347Removes changes to Matrix and Clip since Canvas state was
Herb Derbyefe39bc2018-05-01 17:06:20 -04001348last saved. The state is removed from the stack.
Cary Clark8032b982017-07-28 11:04:54 -04001349
Herb Derbyefe39bc2018-05-01 17:06:20 -04001350Does nothing if the stack is empty.
Cary Clark8032b982017-07-28 11:04:54 -04001351
1352#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04001353void draw(SkCanvas* canvas) {
1354 SkCanvas simple;
1355 SkDebugf("depth = %d\n", simple.getSaveCount());
1356 simple.restore();
1357 SkDebugf("depth = %d\n", simple.getSaveCount());
Cary Clark8032b982017-07-28 11:04:54 -04001358}
1359##
1360
Cary Clark2ade9972017-11-02 17:49:34 -04001361#SeeAlso save() saveLayer saveLayerPreserveLCDTextRequests saveLayerAlpha restoreToCount
1362
Cary Clark8032b982017-07-28 11:04:54 -04001363##
1364
1365# ------------------------------------------------------------------------------
1366
1367#Method int getSaveCount() const
1368
Cary Clarkab2621d2018-01-30 10:08:57 -05001369#In State_Stack
1370#Line # returns depth of stack containing Clip and Matrix ##
Cary Clark939fd6c2018-07-12 08:40:13 -04001371Returns the number of saved states, each containing: Matrix and Clip.
Herb Derbyefe39bc2018-05-01 17:06:20 -04001372Equals the number of save() calls less the number of restore() calls plus one.
Cary Clark8032b982017-07-28 11:04:54 -04001373The save count of a new canvas is one.
1374
Cary Clarkbad5ad72017-08-03 17:14:08 -04001375#Return depth of save state stack ##
Cary Clark8032b982017-07-28 11:04:54 -04001376
1377#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04001378void draw(SkCanvas* canvas) {
1379 SkCanvas simple;
1380 SkDebugf("depth = %d\n", simple.getSaveCount());
1381 simple.save();
1382 SkDebugf("depth = %d\n", simple.getSaveCount());
1383 simple.restore();
1384 SkDebugf("depth = %d\n", simple.getSaveCount());
Cary Clark8032b982017-07-28 11:04:54 -04001385}
1386#StdOut
Cary Clarkbad5ad72017-08-03 17:14:08 -04001387depth = 1
1388depth = 2
Cary Clark8032b982017-07-28 11:04:54 -04001389depth = 1
1390##
1391##
1392
Cary Clark2ade9972017-11-02 17:49:34 -04001393#SeeAlso save() restore() restoreToCount
1394
Cary Clark8032b982017-07-28 11:04:54 -04001395##
1396
1397# ------------------------------------------------------------------------------
1398
1399#Method void restoreToCount(int saveCount)
1400
Cary Clarkab2621d2018-01-30 10:08:57 -05001401#In State_Stack
1402#Line # restores changes to Clip and Matrix to given depth ##
Cary Clark939fd6c2018-07-12 08:40:13 -04001403Restores state to Matrix and Clip values when save(), saveLayer,
Cary Clarkbad5ad72017-08-03 17:14:08 -04001404saveLayerPreserveLCDTextRequests, or saveLayerAlpha returned saveCount.
Cary Clark8032b982017-07-28 11:04:54 -04001405
Herb Derbyefe39bc2018-05-01 17:06:20 -04001406Does nothing if saveCount is greater than state stack count.
Cary Clark8032b982017-07-28 11:04:54 -04001407Restores state to initial values if saveCount is less than or equal to one.
1408
Cary Clarkbad5ad72017-08-03 17:14:08 -04001409#Param saveCount depth of state stack to restore ##
Cary Clark8032b982017-07-28 11:04:54 -04001410
1411#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04001412void draw(SkCanvas* canvas) {
1413 SkDebugf("depth = %d\n", canvas->getSaveCount());
1414 canvas->save();
1415 canvas->save();
1416 SkDebugf("depth = %d\n", canvas->getSaveCount());
1417 canvas->restoreToCount(0);
1418 SkDebugf("depth = %d\n", canvas->getSaveCount());
Cary Clark8032b982017-07-28 11:04:54 -04001419}
1420#StdOut
Cary Clarkbad5ad72017-08-03 17:14:08 -04001421depth = 1
1422depth = 3
Cary Clark8032b982017-07-28 11:04:54 -04001423depth = 1
1424##
1425##
1426
Herb Derbyefe39bc2018-05-01 17:06:20 -04001427#SeeAlso restore() getSaveCount save()
Cary Clark2ade9972017-11-02 17:49:34 -04001428
Cary Clark8032b982017-07-28 11:04:54 -04001429##
1430
Cary Clark08895c42018-02-01 09:37:32 -05001431#Subtopic State_Stack ##
Cary Clark8032b982017-07-28 11:04:54 -04001432
1433# ------------------------------------------------------------------------------
Cary Clarkce101242017-09-01 15:51:02 -04001434
Cary Clark08895c42018-02-01 09:37:32 -05001435#Subtopic Layer
Cary Clarkd0530ba2017-09-14 11:25:39 -04001436#Substitute layer
Cary Clarkce101242017-09-01 15:51:02 -04001437#Alias Layers
Cary Clark137b8742018-05-30 09:21:49 -04001438#Substitute layers
1439##
Cary Clark08895c42018-02-01 09:37:32 -05001440#Line # temporary Bitmap to draw into ##
Cary Clarkce101242017-09-01 15:51:02 -04001441
1442Layer allocates a temporary Bitmap to draw into. When the drawing is
Herb Derbyefe39bc2018-05-01 17:06:20 -04001443complete, the Bitmap is drawn into the Canvas.
Cary Clarkce101242017-09-01 15:51:02 -04001444
1445Layer is saved in a stack along with other saved state. When state with a Layer
1446is restored, the Bitmap is drawn into the previous Layer.
1447
1448Layer may be initialized with the contents of the previous Layer. When Layer is
1449restored, its Bitmap can be modified by Paint passed to Layer to apply
1450Color_Alpha, Color_Filter, Image_Filter, and Blend_Mode.
1451
1452#Method int saveLayer(const SkRect* bounds, const SkPaint* paint)
1453
Cary Clarkab2621d2018-01-30 10:08:57 -05001454#In Layer
1455#Line # saves Clip and Matrix on stack; creates Layer ##
Cary Clark939fd6c2018-07-12 08:40:13 -04001456Saves Matrix and Clip, and allocates a Bitmap for subsequent drawing.
1457Calling restore() discards changes to Matrix and Clip, and draws the Bitmap.
Cary Clarkce101242017-09-01 15:51:02 -04001458
1459Matrix may be changed by translate(), scale(), rotate(), skew(), concat(),
Herb Derbyefe39bc2018-05-01 17:06:20 -04001460setMatrix, and resetMatrix. Clip may be changed by clipRect, clipRRect,
Cary Clarkce101242017-09-01 15:51:02 -04001461clipPath, clipRegion.
1462
1463Rect bounds suggests but does not define the Bitmap size. To clip drawing to
1464a specific rectangle, use clipRect.
1465
1466Optional Paint paint applies Color_Alpha, Color_Filter, Image_Filter, and
1467Blend_Mode when restore() is called.
1468
1469Call restoreToCount with returned value to restore this and subsequent saves.
1470
1471#Param bounds hint to limit the size of the Layer; may be nullptr ##
1472#Param paint graphics state for Layer; may be nullptr ##
1473
1474#Return depth of saved stack ##
1475
1476#Example
1477#Description
1478Rectangles are blurred by Image_Filter when restore() draws Layer to main
1479Canvas.
1480##
1481#Height 128
Cary Clark81abc432018-06-25 16:30:08 -04001482#Function
1483###$
1484#include "SkBlurImageFilter.h"
1485$$$#
1486##
1487
Cary Clarkce101242017-09-01 15:51:02 -04001488void draw(SkCanvas* canvas) {
1489 SkPaint paint, blur;
Cary Clarka560c472017-11-27 10:44:06 -05001490 blur.setImageFilter(SkBlurImageFilter::Make(3, 3, nullptr));
Cary Clarkce101242017-09-01 15:51:02 -04001491 canvas->saveLayer(nullptr, &blur);
1492 SkRect rect = { 25, 25, 50, 50};
1493 canvas->drawRect(rect, paint);
1494 canvas->translate(50, 50);
1495 paint.setColor(SK_ColorRED);
1496 canvas->drawRect(rect, paint);
1497 canvas->restore();
1498}
1499##
1500
Cary Clark2ade9972017-11-02 17:49:34 -04001501#SeeAlso save() restore() saveLayer saveLayerPreserveLCDTextRequests saveLayerAlpha SaveLayerRec
Cary Clarkce101242017-09-01 15:51:02 -04001502
1503##
1504
Herb Derbyefe39bc2018-05-01 17:06:20 -04001505#Method int saveLayer(const SkRect& bounds, const SkPaint* paint)
Cary Clarkce101242017-09-01 15:51:02 -04001506
Cary Clarkab2621d2018-01-30 10:08:57 -05001507#In Layer
Cary Clark939fd6c2018-07-12 08:40:13 -04001508Saves Matrix and Clip, and allocates a Bitmap for subsequent drawing.
1509Calling restore() discards changes to Matrix and Clip, and draws the Bitmap.
Cary Clarkce101242017-09-01 15:51:02 -04001510
1511Matrix may be changed by translate(), scale(), rotate(), skew(), concat(),
1512setMatrix, and resetMatrix. Clip may be changed by clipRect, clipRRect,
1513clipPath, clipRegion.
1514
1515Rect bounds suggests but does not define the Layer size. To clip drawing to
1516a specific rectangle, use clipRect.
1517
1518Optional Paint paint applies Color_Alpha, Color_Filter, Image_Filter, and
1519Blend_Mode when restore() is called.
1520
1521Call restoreToCount with returned value to restore this and subsequent saves.
1522
1523#Param bounds hint to limit the size of Layer; may be nullptr ##
1524#Param paint graphics state for Layer; may be nullptr ##
1525
1526#Return depth of saved stack ##
1527
1528#Example
1529#Description
1530Rectangles are blurred by Image_Filter when restore() draws Layer to main Canvas.
Herb Derbyefe39bc2018-05-01 17:06:20 -04001531The red rectangle is clipped; it does not fully fit on Layer.
Cary Clarkce101242017-09-01 15:51:02 -04001532Image_Filter blurs past edge of Layer so red rectangle is blurred on all sides.
1533##
1534#Height 128
Cary Clark81abc432018-06-25 16:30:08 -04001535#Function
1536###$
1537#include "SkBlurImageFilter.h"
1538$$$#
1539##
1540
Cary Clarkce101242017-09-01 15:51:02 -04001541void draw(SkCanvas* canvas) {
1542 SkPaint paint, blur;
Cary Clarka560c472017-11-27 10:44:06 -05001543 blur.setImageFilter(SkBlurImageFilter::Make(3, 3, nullptr));
Cary Clarkce101242017-09-01 15:51:02 -04001544 canvas->saveLayer(SkRect::MakeWH(90, 90), &blur);
1545 SkRect rect = { 25, 25, 50, 50};
1546 canvas->drawRect(rect, paint);
1547 canvas->translate(50, 50);
1548 paint.setColor(SK_ColorRED);
1549 canvas->drawRect(rect, paint);
1550 canvas->restore();
1551}
1552##
1553
Cary Clark2ade9972017-11-02 17:49:34 -04001554#SeeAlso save() restore() saveLayerPreserveLCDTextRequests saveLayerAlpha SaveLayerRec
Cary Clarkce101242017-09-01 15:51:02 -04001555
1556##
1557
1558#Method int saveLayerPreserveLCDTextRequests(const SkRect* bounds, const SkPaint* paint)
1559
Cary Clarkab2621d2018-01-30 10:08:57 -05001560#In Layer
1561#Line # saves Clip and Matrix on stack; creates Layer for LCD text ##
Cary Clark939fd6c2018-07-12 08:40:13 -04001562Saves Matrix and Clip, and allocates a Bitmap for subsequent drawing.
Cary Clarkce101242017-09-01 15:51:02 -04001563LCD_Text is preserved when the Layer is drawn to the prior Layer.
1564
Cary Clark939fd6c2018-07-12 08:40:13 -04001565Calling restore() discards changes to Matrix and Clip, and draws Layer.
Cary Clarkce101242017-09-01 15:51:02 -04001566
1567Matrix may be changed by translate(), scale(), rotate(), skew(), concat(),
1568setMatrix, and resetMatrix. Clip may be changed by clipRect, clipRRect,
1569clipPath, clipRegion.
Herb Derbyefe39bc2018-05-01 17:06:20 -04001570
Cary Clarkce101242017-09-01 15:51:02 -04001571Rect 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 Clark939fd6c2018-07-12 08:40:13 -04001619Saves Matrix and Clip, and allocates Bitmap for subsequent drawing.
Cary Clarkce101242017-09-01 15:51:02 -04001620
Cary Clark939fd6c2018-07-12 08:40:13 -04001621Calling restore() discards changes to Matrix and Clip,
Cary Clarkce101242017-09-01 15:51:02 -04001622and blends Layer with alpha opacity onto prior Layer.
1623
1624Matrix may be changed by translate(), scale(), rotate(), skew(), concat(),
1625setMatrix, and resetMatrix. Clip may be changed by clipRect, clipRRect,
1626clipPath, clipRegion.
1627
1628Rect bounds suggests but does not define Layer size. To clip drawing to
1629a specific rectangle, use clipRect.
1630
1631alpha of zero is fully transparent, 255 is fully opaque.
1632
1633Call restoreToCount with returned value to restore this and subsequent saves.
1634
1635#Param bounds hint to limit the size of Layer; may be nullptr ##
1636#Param alpha opacity of Layer ##
1637
1638#Return depth of saved stack ##
1639
1640#Example
1641 SkPaint paint;
1642 paint.setColor(SK_ColorRED);
1643 canvas->drawCircle(50, 50, 50, paint);
1644 canvas->saveLayerAlpha(nullptr, 128);
1645 paint.setColor(SK_ColorBLUE);
1646 canvas->drawCircle(100, 50, 50, paint);
1647 paint.setColor(SK_ColorGREEN);
1648 paint.setAlpha(128);
1649 canvas->drawCircle(75, 90, 50, paint);
1650 canvas->restore();
1651##
1652
Cary Clark2ade9972017-11-02 17:49:34 -04001653#SeeAlso save() restore() saveLayer saveLayerPreserveLCDTextRequests SaveLayerRec
Cary Clarkce101242017-09-01 15:51:02 -04001654
1655##
1656
Cary Clarkd98f78c2018-04-26 08:32:37 -04001657#Enum SaveLayerFlagsSet
Cary Clark08895c42018-02-01 09:37:32 -05001658#Line # sets SaveLayerRec options ##
Cary Clarkce101242017-09-01 15:51:02 -04001659#Code
Cary Clark61313f32018-10-08 14:57:48 -04001660#Populate
Cary Clarkce101242017-09-01 15:51:02 -04001661##
1662
Cary Clark682c58d2018-05-16 07:07:07 -04001663
1664#Typedef uint32_t SaveLayerFlags
1665#Line # options for SaveLayerRec ##
Cary Clark137b8742018-05-30 09:21:49 -04001666##
Cary Clark682c58d2018-05-16 07:07:07 -04001667
Cary Clarkce101242017-09-01 15:51:02 -04001668SaveLayerFlags provides options that may be used in any combination in SaveLayerRec,
Cary Clark682c58d2018-05-16 07:07:07 -04001669defining how Layer allocated by saveLayer operates. It may be set to zero,
1670kPreserveLCDText_SaveLayerFlag, kInitWithPrevious_SaveLayerFlag, or both flags.
1671
Cary Clarkce101242017-09-01 15:51:02 -04001672#Const kPreserveLCDText_SaveLayerFlag 2
Cary Clark682c58d2018-05-16 07:07:07 -04001673#Line # creates Layer for LCD text ##
Cary Clarkce101242017-09-01 15:51:02 -04001674 Creates Layer for LCD text. Flag is ignored if Layer Paint contains
1675 Image_Filter or Color_Filter.
1676##
1677
1678#Const kInitWithPrevious_SaveLayerFlag 4
Cary Clark682c58d2018-05-16 07:07:07 -04001679#Line # initializes with previous contents ##
Cary Clarkce101242017-09-01 15:51:02 -04001680 Initializes Layer with the contents of the previous Layer.
1681##
1682
Mike Reed910ca0f2018-04-25 13:04:05 -04001683#Const kMaskAgainstCoverage_EXPERIMENTAL_DONT_USE_SaveLayerFlag 8
Cary Clark682c58d2018-05-16 07:07:07 -04001684#Experimental do not use
Mike Reed910ca0f2018-04-25 13:04:05 -04001685##
1686
Cary Clarkce101242017-09-01 15:51:02 -04001687#Const kDontClipToLayer_Legacy_SaveLayerFlag 0x80000000
Cary Clark4855f782018-02-06 09:41:53 -05001688#Deprecated soon
Cary Clarkce101242017-09-01 15:51:02 -04001689##
1690
1691#Example
1692#Height 160
1693#Description
1694Canvas Layer captures red and blue circles scaled up by four.
Herb Derbyefe39bc2018-05-01 17:06:20 -04001695scalePaint blends Layer back with transparency.
Cary Clarkce101242017-09-01 15:51:02 -04001696##
1697void draw(SkCanvas* canvas) {
1698 SkPaint redPaint, bluePaint, scalePaint;
1699 redPaint.setColor(SK_ColorRED);
1700 canvas->drawCircle(21, 21, 8, redPaint);
1701 bluePaint.setColor(SK_ColorBLUE);
1702 canvas->drawCircle(31, 21, 8, bluePaint);
1703 SkMatrix matrix;
1704 matrix.setScale(4, 4);
1705 scalePaint.setAlpha(0x40);
1706 scalePaint.setImageFilter(
1707 SkImageFilter::MakeMatrixFilter(matrix, kNone_SkFilterQuality, nullptr));
1708 SkCanvas::SaveLayerRec saveLayerRec(nullptr, &scalePaint,
Herb Derbyefe39bc2018-05-01 17:06:20 -04001709 SkCanvas::kInitWithPrevious_SaveLayerFlag);
Cary Clarkce101242017-09-01 15:51:02 -04001710 canvas->saveLayer(saveLayerRec);
1711 canvas->restore();
1712}
1713##
1714
Cary Clark2ade9972017-11-02 17:49:34 -04001715#SeeAlso save() restore() saveLayer saveLayerPreserveLCDTextRequests saveLayerAlpha SaveLayerRec
Cary Clarkce101242017-09-01 15:51:02 -04001716
1717#Enum ##
1718
Cary Clark682c58d2018-05-16 07:07:07 -04001719#Subtopic SaveLayerRec
1720#Line # contains the state used to create the Layer ##
Cary Clarka560c472017-11-27 10:44:06 -05001721
Cary Clarkce101242017-09-01 15:51:02 -04001722#Struct SaveLayerRec
Cary Clark08895c42018-02-01 09:37:32 -05001723#Line # contains the state used to create the Layer ##
Cary Clark682c58d2018-05-16 07:07:07 -04001724
Cary Clarkce101242017-09-01 15:51:02 -04001725#Code
Cary Clark61313f32018-10-08 14:57:48 -04001726#Populate
Cary Clarkce101242017-09-01 15:51:02 -04001727##
1728
Cary Clark137b8742018-05-30 09:21:49 -04001729SaveLayerRec contains the state used to create the Layer.
1730
Cary Clarkce101242017-09-01 15:51:02 -04001731#Member const SkRect* fBounds
Cary Clark682c58d2018-05-16 07:07:07 -04001732#Line # hints at Layer size limit ##
Cary Clarkce101242017-09-01 15:51:02 -04001733 fBounds is used as a hint to limit the size of Layer; may be nullptr.
1734 fBounds suggests but does not define Layer size. To clip drawing to
1735 a specific rectangle, use clipRect.
1736##
1737
1738#Member const SkPaint* fPaint
Cary Clark682c58d2018-05-16 07:07:07 -04001739#Line # modifies overlay ##
Cary Clarkce101242017-09-01 15:51:02 -04001740 fPaint modifies how Layer overlays the prior Layer; may be nullptr.
1741 Color_Alpha, Blend_Mode, Color_Filter, Draw_Looper, Image_Filter, and
1742 Mask_Filter affect Layer draw.
1743##
1744
1745#Member const SkImageFilter* fBackdrop
Cary Clark682c58d2018-05-16 07:07:07 -04001746#Line # applies Image_Filter to prior Layer ##
Cary Clarkce101242017-09-01 15:51:02 -04001747 fBackdrop applies Image_Filter to the prior Layer when copying to the Layer;
1748 may be nullptr. Use kInitWithPrevious_SaveLayerFlag to copy the
1749 prior Layer without an Image_Filter.
1750##
1751
1752#Member const SkImage* fClipMask
Cary Clark682c58d2018-05-16 07:07:07 -04001753#Line # clips Layer with Mask_Alpha ##
Cary Clarkce101242017-09-01 15:51:02 -04001754 restore() clips Layer by the Color_Alpha channel of fClipMask when
1755 Layer is copied to Device. fClipMask may be nullptr. .
1756##
1757
1758#Member const SkMatrix* fClipMatrix
Cary Clark682c58d2018-05-16 07:07:07 -04001759#Line # transforms Mask_Alpha used to clip ##
Herb Derbyefe39bc2018-05-01 17:06:20 -04001760 fClipMatrix transforms fClipMask before it clips Layer. If
Cary Clarkce101242017-09-01 15:51:02 -04001761 fClipMask describes a translucent gradient, it may be scaled and rotated
1762 without introducing artifacts. fClipMatrix may be nullptr.
1763##
1764
1765#Member SaveLayerFlags fSaveLayerFlags
Cary Clark682c58d2018-05-16 07:07:07 -04001766#Line # preserves LCD Text, creates with prior Layer contents ##
Cary Clarkce101242017-09-01 15:51:02 -04001767 fSaveLayerFlags are used to create Layer without transparency,
1768 create Layer for LCD text, and to create Layer with the
1769 contents of the previous Layer.
1770##
1771
1772#Example
1773#Height 160
1774#Description
Cary Clarkffb3d682018-05-17 12:17:28 -04001775Canvas Layer captures a red Anti_Aliased circle and a blue Aliased circle scaled
Cary Clarkce101242017-09-01 15:51:02 -04001776up by four. After drawing another red circle without scaling on top, the Layer is
Herb Derbyefe39bc2018-05-01 17:06:20 -04001777transferred to the main canvas.
Cary Clarkce101242017-09-01 15:51:02 -04001778##
1779void draw(SkCanvas* canvas) {
1780 SkPaint redPaint, bluePaint;
1781 redPaint.setAntiAlias(true);
1782 redPaint.setColor(SK_ColorRED);
1783 canvas->drawCircle(21, 21, 8, redPaint);
1784 bluePaint.setColor(SK_ColorBLUE);
1785 canvas->drawCircle(31, 21, 8, bluePaint);
1786 SkMatrix matrix;
1787 matrix.setScale(4, 4);
1788 auto scaler = SkImageFilter::MakeMatrixFilter(matrix, kNone_SkFilterQuality, nullptr);
Herb Derbyefe39bc2018-05-01 17:06:20 -04001789 SkCanvas::SaveLayerRec saveLayerRec(nullptr, nullptr, scaler.get(), 0);
Cary Clarkce101242017-09-01 15:51:02 -04001790 canvas->saveLayer(saveLayerRec);
1791 canvas->drawCircle(125, 85, 8, redPaint);
1792 canvas->restore();
1793}
1794##
1795
Cary Clark61313f32018-10-08 14:57:48 -04001796#Subtopic Constructors
Cary Clark682c58d2018-05-16 07:07:07 -04001797##
Cary Clarkce101242017-09-01 15:51:02 -04001798
Cary Clark682c58d2018-05-16 07:07:07 -04001799#Method SaveLayerRec()
1800#Line # constructs SaveLayerRec ##
Cary Clarkce101242017-09-01 15:51:02 -04001801Sets fBounds, fPaint, and fBackdrop to nullptr. Clears fSaveLayerFlags.
1802
1803#Return empty SaveLayerRec ##
1804
1805#Example
1806 SkCanvas::SaveLayerRec rec1;
Mike Kleine083f7c2018-02-07 12:54:27 -05001807 rec1.fSaveLayerFlags = SkCanvas::kPreserveLCDText_SaveLayerFlag;
1808 SkCanvas::SaveLayerRec rec2(nullptr, nullptr, SkCanvas::kPreserveLCDText_SaveLayerFlag);
Cary Clarkce101242017-09-01 15:51:02 -04001809 SkDebugf("rec1 %c= rec2\n", rec1.fBounds == rec2.fBounds
1810 && rec1.fPaint == rec2.fPaint
1811 && rec1.fBackdrop == rec2.fBackdrop
1812 && rec1.fSaveLayerFlags == rec2.fSaveLayerFlags ? '=' : '!');
1813 #StdOut
1814 rec1 == rec2
1815 ##
1816##
1817
Cary Clark2ade9972017-11-02 17:49:34 -04001818#SeeAlso save() restore() saveLayer saveLayerPreserveLCDTextRequests saveLayerAlpha
1819
Cary Clarkce101242017-09-01 15:51:02 -04001820##
1821
Cary Clark224c7002018-06-27 11:00:21 -04001822#Method SaveLayerRec(const SkRect* bounds, const SkPaint* paint, SaveLayerFlags saveLayerFlags = 0)
Cary Clarkce101242017-09-01 15:51:02 -04001823
1824Sets fBounds, fPaint, and fSaveLayerFlags; sets fBackdrop to nullptr.
1825
1826#Param bounds Layer dimensions; may be nullptr ##
1827#Param paint applied to Layer when overlaying prior Layer; may be nullptr ##
1828#Param saveLayerFlags SaveLayerRec options to modify Layer ##
1829
1830#Return SaveLayerRec with empty backdrop ##
1831
1832#Example
1833 SkCanvas::SaveLayerRec rec1;
1834 SkCanvas::SaveLayerRec rec2(nullptr, nullptr);
1835 SkDebugf("rec1 %c= rec2\n", rec1.fBounds == rec2.fBounds
1836 && rec1.fPaint == rec2.fPaint
1837 && rec1.fBackdrop == rec2.fBackdrop
1838 && rec1.fSaveLayerFlags == rec2.fSaveLayerFlags ? '=' : '!');
1839 #StdOut
1840 rec1 == rec2
1841 ##
1842##
1843
Cary Clark2ade9972017-11-02 17:49:34 -04001844#SeeAlso save() restore() saveLayer saveLayerPreserveLCDTextRequests saveLayerAlpha
1845
Cary Clarkce101242017-09-01 15:51:02 -04001846##
1847
1848#Method SaveLayerRec(const SkRect* bounds, const SkPaint* paint, const SkImageFilter* backdrop,
1849 SaveLayerFlags saveLayerFlags)
1850
1851Sets fBounds, fPaint, fBackdrop, and fSaveLayerFlags.
1852
1853#Param bounds Layer dimensions; may be nullptr ##
1854#Param paint applied to Layer when overlaying prior Layer;
1855 may be nullptr
1856##
1857#Param backdrop prior Layer copied with Image_Filter; may be nullptr
1858##
1859#Param saveLayerFlags SaveLayerRec options to modify Layer ##
1860
1861#Return SaveLayerRec fully specified ##
1862
1863#Example
1864 SkCanvas::SaveLayerRec rec1;
1865 SkCanvas::SaveLayerRec rec2(nullptr, nullptr, nullptr, 0);
1866 SkDebugf("rec1 %c= rec2\n", rec1.fBounds == rec2.fBounds
1867 && rec1.fPaint == rec2.fPaint
1868 && rec1.fBackdrop == rec2.fBackdrop
1869 && rec1.fSaveLayerFlags == rec2.fSaveLayerFlags ? '=' : '!');
1870 #StdOut
1871 rec1 == rec2
1872 ##
1873##
1874
Cary Clark2ade9972017-11-02 17:49:34 -04001875#SeeAlso save() restore() saveLayer saveLayerPreserveLCDTextRequests saveLayerAlpha
1876
Cary Clarkce101242017-09-01 15:51:02 -04001877##
1878
1879#Method SaveLayerRec(const SkRect* bounds, const SkPaint* paint, const SkImageFilter* backdrop,
1880 const SkImage* clipMask, const SkMatrix* clipMatrix,
1881 SaveLayerFlags saveLayerFlags)
1882
Cary Clark682c58d2018-05-16 07:07:07 -04001883#Experimental not ready
Cary Clarkce101242017-09-01 15:51:02 -04001884
1885Sets fBounds, fPaint, fBackdrop, fClipMask, fClipMatrix, and fSaveLayerFlags.
1886clipMatrix uses Color_Alpha channel of image, transformed by clipMatrix, to clip
1887Layer when drawn to Canvas.
1888
Cary Clark2ade9972017-11-02 17:49:34 -04001889Implementation is not complete; has no effect if Device is GPU-backed.
Cary Clarkce101242017-09-01 15:51:02 -04001890
1891#Param bounds Layer dimensions; may be nullptr ##
1892#Param paint graphics state applied to Layer when overlaying prior
1893 Layer; may be nullptr
1894##
1895#Param backdrop prior Layer copied with Image_Filter;
1896 may be nullptr
1897##
1898#Param clipMask clip applied to Layer; may be nullptr ##
1899#Param clipMatrix matrix applied to clipMask; may be nullptr to use
Herb Derbyefe39bc2018-05-01 17:06:20 -04001900 identity matrix
Cary Clarkce101242017-09-01 15:51:02 -04001901##
1902#Param saveLayerFlags SaveLayerRec options to modify Layer ##
1903
1904#Return SaveLayerRec fully specified ##
1905
Cary Clark2ade9972017-11-02 17:49:34 -04001906#SeeAlso save() restore() saveLayer saveLayerPreserveLCDTextRequests saveLayerAlpha
Cary Clarkce101242017-09-01 15:51:02 -04001907
1908##
1909
1910#Struct ##
1911
Cary Clark682c58d2018-05-16 07:07:07 -04001912#Subtopic ##
1913
Cary Clarkce101242017-09-01 15:51:02 -04001914#Method int saveLayer(const SaveLayerRec& layerRec)
1915
Cary Clarkab2621d2018-01-30 10:08:57 -05001916#In Layer
Cary Clark939fd6c2018-07-12 08:40:13 -04001917Saves Matrix and Clip, and allocates Bitmap for subsequent drawing.
Cary Clarkce101242017-09-01 15:51:02 -04001918
Cary Clark939fd6c2018-07-12 08:40:13 -04001919Calling restore() discards changes to Matrix and Clip,
Cary Clarkce101242017-09-01 15:51:02 -04001920and blends Bitmap with Color_Alpha opacity onto the prior Layer.
1921
1922Matrix may be changed by translate(), scale(), rotate(), skew(), concat(),
1923setMatrix, and resetMatrix. Clip may be changed by clipRect, clipRRect,
1924clipPath, clipRegion.
1925
1926SaveLayerRec contains the state used to create the Layer.
1927
1928Call restoreToCount with returned value to restore this and subsequent saves.
1929
1930#Param layerRec Layer state ##
1931
1932#Return depth of save state stack ##
1933
1934#Example
1935#Description
1936The example draws an image, and saves it into a Layer with kInitWithPrevious_SaveLayerFlag.
1937Next it punches a hole in Layer and restore with SkBlendMode::kPlus.
1938Where Layer was cleared, the original image will draw unchanged.
1939Outside of the circle the mandrill is brightened.
1940##
1941 #Image 3
Hal Canaryc465d132017-12-08 10:21:31 -05001942 // sk_sp<SkImage> image = GetResourceAsImage("images/mandrill_256.png");
Cary Clarkce101242017-09-01 15:51:02 -04001943 canvas->drawImage(image, 0, 0, nullptr);
1944 SkCanvas::SaveLayerRec rec;
1945 SkPaint paint;
1946 paint.setBlendMode(SkBlendMode::kPlus);
1947 rec.fSaveLayerFlags = SkCanvas::kInitWithPrevious_SaveLayerFlag;
1948 rec.fPaint = &paint;
1949 canvas->saveLayer(rec);
1950 paint.setBlendMode(SkBlendMode::kClear);
1951 canvas->drawCircle(128, 128, 96, paint);
1952 canvas->restore();
1953##
1954
1955#ToDo above example needs to replace GetResourceAsImage with way to select image in fiddle ##
1956
Cary Clark2ade9972017-11-02 17:49:34 -04001957#SeeAlso save() restore() saveLayer saveLayerPreserveLCDTextRequests saveLayerAlpha
1958
Cary Clarkce101242017-09-01 15:51:02 -04001959##
1960
Cary Clark08895c42018-02-01 09:37:32 -05001961#Subtopic Layer ##
Cary Clarkce101242017-09-01 15:51:02 -04001962
1963# ------------------------------------------------------------------------------
Cary Clark08895c42018-02-01 09:37:32 -05001964#Subtopic Matrix
1965#Line # coordinate transformation ##
Cary Clark8032b982017-07-28 11:04:54 -04001966
1967#Method void translate(SkScalar dx, SkScalar dy)
1968
Cary Clarkab2621d2018-01-30 10:08:57 -05001969#In Matrix
1970#Line # translates Matrix ##
Cary Clark80247e52018-07-11 16:18:41 -04001971Translates Matrix by dx along the x-axis and dy along the y-axis.
Cary Clark8032b982017-07-28 11:04:54 -04001972
Cary Clark80247e52018-07-11 16:18:41 -04001973Mathematically, replaces Matrix with a translation matrix
Herb Derbyefe39bc2018-05-01 17:06:20 -04001974Premultiplied with Matrix.
Cary Clark8032b982017-07-28 11:04:54 -04001975
1976This has the effect of moving the drawing by (dx, dy) before transforming
1977the result with Matrix.
1978
Cary Clarkbad5ad72017-08-03 17:14:08 -04001979#Param dx distance to translate in x ##
1980#Param dy distance to translate in y ##
Cary Clark8032b982017-07-28 11:04:54 -04001981
1982#Example
1983#Height 128
1984#Description
1985scale() followed by translate() produces different results from translate() followed
Herb Derbyefe39bc2018-05-01 17:06:20 -04001986by scale().
Cary Clark8032b982017-07-28 11:04:54 -04001987
1988The blue stroke follows translate of (50, 50); a black
Herb Derbyefe39bc2018-05-01 17:06:20 -04001989fill follows scale of (2, 1/2.f). After restoring the clip, which resets
Cary Clark8032b982017-07-28 11:04:54 -04001990Matrix, a red frame follows the same scale of (2, 1/2.f); a gray fill
1991follows translate of (50, 50).
1992##
Cary Clarkbad5ad72017-08-03 17:14:08 -04001993void draw(SkCanvas* canvas) {
1994 SkPaint filledPaint;
1995 SkPaint outlinePaint;
1996 outlinePaint.setStyle(SkPaint::kStroke_Style);
1997 outlinePaint.setColor(SK_ColorBLUE);
1998 canvas->save();
1999 canvas->translate(50, 50);
2000 canvas->drawCircle(28, 28, 15, outlinePaint); // blue center: (50+28, 50+28)
2001 canvas->scale(2, 1/2.f);
2002 canvas->drawCircle(28, 28, 15, filledPaint); // black center: (50+(28*2), 50+(28/2))
2003 canvas->restore();
2004 filledPaint.setColor(SK_ColorGRAY);
2005 outlinePaint.setColor(SK_ColorRED);
2006 canvas->scale(2, 1/2.f);
2007 canvas->drawCircle(28, 28, 15, outlinePaint); // red center: (28*2, 28/2)
2008 canvas->translate(50, 50);
2009 canvas->drawCircle(28, 28, 15, filledPaint); // gray center: ((50+28)*2, (50+28)/2)
Cary Clark8032b982017-07-28 11:04:54 -04002010}
2011##
2012
Cary Clark2ade9972017-11-02 17:49:34 -04002013#SeeAlso concat() scale() skew() rotate() setMatrix
Cary Clark8032b982017-07-28 11:04:54 -04002014
2015##
2016
2017# ------------------------------------------------------------------------------
2018
2019#Method void scale(SkScalar sx, SkScalar sy)
2020
Cary Clarkab2621d2018-01-30 10:08:57 -05002021#In Matrix
2022#Line # scales Matrix ##
Cary Clark80247e52018-07-11 16:18:41 -04002023Scales Matrix by sx on the x-axis and sy on the y-axis.
Cary Clark8032b982017-07-28 11:04:54 -04002024
Cary Clark80247e52018-07-11 16:18:41 -04002025Mathematically, replaces Matrix with a scale matrix
Herb Derbyefe39bc2018-05-01 17:06:20 -04002026Premultiplied with Matrix.
Cary Clark8032b982017-07-28 11:04:54 -04002027
2028This has the effect of scaling the drawing by (sx, sy) before transforming
2029the result with Matrix.
2030
Cary Clarkbad5ad72017-08-03 17:14:08 -04002031#Param sx amount to scale in x ##
2032#Param sy amount to scale in y ##
Cary Clark8032b982017-07-28 11:04:54 -04002033
2034#Example
2035#Height 160
Cary Clarkbad5ad72017-08-03 17:14:08 -04002036void draw(SkCanvas* canvas) {
2037 SkPaint paint;
2038 SkRect rect = { 10, 20, 60, 120 };
2039 canvas->translate(20, 20);
2040 canvas->drawRect(rect, paint);
2041 canvas->scale(2, .5f);
2042 paint.setColor(SK_ColorGRAY);
2043 canvas->drawRect(rect, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002044}
2045##
2046
Cary Clark2ade9972017-11-02 17:49:34 -04002047#SeeAlso concat() translate() skew() rotate() setMatrix
Cary Clark8032b982017-07-28 11:04:54 -04002048
2049##
2050
2051# ------------------------------------------------------------------------------
2052
2053#Method void rotate(SkScalar degrees)
2054
Cary Clarkab2621d2018-01-30 10:08:57 -05002055#In Matrix
2056#Line # rotates Matrix ##
Cary Clark80247e52018-07-11 16:18:41 -04002057Rotates Matrix by degrees. Positive degrees rotates clockwise.
Cary Clark8032b982017-07-28 11:04:54 -04002058
Cary Clark80247e52018-07-11 16:18:41 -04002059Mathematically, replaces Matrix with a rotation matrix
Herb Derbyefe39bc2018-05-01 17:06:20 -04002060Premultiplied with Matrix.
Cary Clark8032b982017-07-28 11:04:54 -04002061
2062This has the effect of rotating the drawing by degrees before transforming
2063the result with Matrix.
2064
Cary Clarkbad5ad72017-08-03 17:14:08 -04002065#Param degrees amount to rotate, in degrees ##
Cary Clark8032b982017-07-28 11:04:54 -04002066
2067#Example
2068#Description
2069Draw clock hands at time 5:10. The hour hand and minute hand point up and
2070are rotated clockwise.
2071##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002072void draw(SkCanvas* canvas) {
2073 SkPaint paint;
2074 paint.setStyle(SkPaint::kStroke_Style);
2075 canvas->translate(128, 128);
2076 canvas->drawCircle(0, 0, 60, paint);
2077 canvas->save();
2078 canvas->rotate(10 * 360 / 60); // 10 minutes of 60 scaled to 360 degrees
Herb Derbyefe39bc2018-05-01 17:06:20 -04002079 canvas->drawLine(0, 0, 0, -50, paint);
Cary Clarkbad5ad72017-08-03 17:14:08 -04002080 canvas->restore();
2081 canvas->rotate((5 + 10.f/60) * 360 / 12); // 5 and 10/60 hours of 12 scaled to 360 degrees
2082 canvas->drawLine(0, 0, 0, -30, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002083}
2084##
2085
Cary Clark2ade9972017-11-02 17:49:34 -04002086#SeeAlso concat() translate() skew() scale() setMatrix
Cary Clark8032b982017-07-28 11:04:54 -04002087
2088##
2089
2090# ------------------------------------------------------------------------------
2091
2092#Method void rotate(SkScalar degrees, SkScalar px, SkScalar py)
2093
Cary Clarkab2621d2018-01-30 10:08:57 -05002094#In Matrix
Cary Clark80247e52018-07-11 16:18:41 -04002095Rotates Matrix by degrees about a point at (px, py). Positive degrees rotates
Cary Clarkbad5ad72017-08-03 17:14:08 -04002096clockwise.
Cary Clark8032b982017-07-28 11:04:54 -04002097
Cary Clark80247e52018-07-11 16:18:41 -04002098Mathematically, constructs a rotation matrix; Premultiplies the rotation matrix by
2099a translation matrix; then replaces Matrix with the resulting matrix
Herb Derbyefe39bc2018-05-01 17:06:20 -04002100Premultiplied with Matrix.
Cary Clark8032b982017-07-28 11:04:54 -04002101
Cary Clarkbad5ad72017-08-03 17:14:08 -04002102This has the effect of rotating the drawing about a given point before
2103transforming the result with Matrix.
Cary Clark8032b982017-07-28 11:04:54 -04002104
Cary Clarkbad5ad72017-08-03 17:14:08 -04002105#Param degrees amount to rotate, in degrees ##
Cary Clark5538c132018-06-14 12:28:14 -04002106#Param px x-axis value of the point to rotate about ##
2107#Param py y-axis value of the point to rotate about ##
Cary Clark8032b982017-07-28 11:04:54 -04002108
2109#Example
2110#Height 192
Cary Clarkbad5ad72017-08-03 17:14:08 -04002111void draw(SkCanvas* canvas) {
2112 SkPaint paint;
2113 paint.setTextSize(96);
2114 canvas->drawString("A1", 130, 100, paint);
2115 canvas->rotate(180, 130, 100);
2116 canvas->drawString("A1", 130, 100, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002117}
2118##
2119
Cary Clark2ade9972017-11-02 17:49:34 -04002120#SeeAlso concat() translate() skew() scale() setMatrix
Cary Clark8032b982017-07-28 11:04:54 -04002121
2122##
2123
2124# ------------------------------------------------------------------------------
2125
2126#Method void skew(SkScalar sx, SkScalar sy)
2127
Cary Clarkab2621d2018-01-30 10:08:57 -05002128#In Matrix
2129#Line # skews Matrix ##
Cary Clark80247e52018-07-11 16:18:41 -04002130Skews Matrix by sx on the x-axis and sy on the y-axis. A positive value of sx
Cary Clark5538c132018-06-14 12:28:14 -04002131skews the drawing right as y-axis values increase; a positive value of sy skews
2132the drawing down as x-axis values increase.
Cary Clark8032b982017-07-28 11:04:54 -04002133
Cary Clark80247e52018-07-11 16:18:41 -04002134Mathematically, replaces Matrix with a skew matrix Premultiplied with Matrix.
Cary Clark8032b982017-07-28 11:04:54 -04002135
Cary Clarkbad5ad72017-08-03 17:14:08 -04002136This has the effect of skewing the drawing by (sx, sy) before transforming
Cary Clark8032b982017-07-28 11:04:54 -04002137the result with Matrix.
2138
Cary Clark5538c132018-06-14 12:28:14 -04002139#Param sx amount to skew on x-axis ##
2140#Param sy amount to skew on y-axis ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002141
Cary Clark8032b982017-07-28 11:04:54 -04002142#Example
Herb Derbyefe39bc2018-05-01 17:06:20 -04002143 #Description
Cary Clark5538c132018-06-14 12:28:14 -04002144 Black text mimics an oblique text style by using a negative skew on x-axis
2145 that shifts the geometry to the right as the y-axis values decrease.
2146 Red text uses a positive skew on y-axis to shift the geometry down
2147 as the x-axis values increase.
2148 Blue text combines sx and sy skew to rotate and scale.
Cary Clark8032b982017-07-28 11:04:54 -04002149 ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002150 SkPaint paint;
2151 paint.setTextSize(128);
2152 canvas->translate(30, 130);
2153 canvas->save();
2154 canvas->skew(-.5, 0);
2155 canvas->drawString("A1", 0, 0, paint);
2156 canvas->restore();
2157 canvas->save();
2158 canvas->skew(0, .5);
2159 paint.setColor(SK_ColorRED);
2160 canvas->drawString("A1", 0, 0, paint);
2161 canvas->restore();
2162 canvas->skew(-.5, .5);
2163 paint.setColor(SK_ColorBLUE);
Cary Clark8032b982017-07-28 11:04:54 -04002164 canvas->drawString("A1", 0, 0, paint);
2165##
2166
Cary Clark2ade9972017-11-02 17:49:34 -04002167#SeeAlso concat() translate() rotate() scale() setMatrix
Cary Clark8032b982017-07-28 11:04:54 -04002168
2169##
2170
2171# ------------------------------------------------------------------------------
2172
2173#Method void concat(const SkMatrix& matrix)
2174
Cary Clarkab2621d2018-01-30 10:08:57 -05002175#In Matrix
2176#Line # multiplies Matrix by Matrix ##
Cary Clark80247e52018-07-11 16:18:41 -04002177Replaces Matrix with matrix Premultiplied with existing Matrix.
Cary Clark8032b982017-07-28 11:04:54 -04002178
Cary Clarkbad5ad72017-08-03 17:14:08 -04002179This has the effect of transforming the drawn geometry by matrix, before
2180transforming the result with existing Matrix.
Cary Clark8032b982017-07-28 11:04:54 -04002181
Cary Clarkce101242017-09-01 15:51:02 -04002182#Param matrix matrix to Premultiply with existing Matrix ##
Cary Clark8032b982017-07-28 11:04:54 -04002183
2184#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04002185void draw(SkCanvas* canvas) {
2186 SkPaint paint;
2187 paint.setTextSize(80);
2188 paint.setTextScaleX(.3);
2189 SkMatrix matrix;
2190 SkRect rect[2] = {{ 10, 20, 90, 110 }, { 40, 130, 140, 180 }};
2191 matrix.setRectToRect(rect[0], rect[1], SkMatrix::kFill_ScaleToFit);
2192 canvas->drawRect(rect[0], paint);
2193 canvas->drawRect(rect[1], paint);
2194 paint.setColor(SK_ColorWHITE);
2195 canvas->drawString("Here", rect[0].fLeft + 10, rect[0].fBottom - 10, paint);
2196 canvas->concat(matrix);
2197 canvas->drawString("There", rect[0].fLeft + 10, rect[0].fBottom - 10, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002198}
2199##
2200
Cary Clark2ade9972017-11-02 17:49:34 -04002201#SeeAlso translate() rotate() scale() skew() setMatrix
Cary Clark8032b982017-07-28 11:04:54 -04002202
2203##
2204
2205# ------------------------------------------------------------------------------
2206
2207#Method void setMatrix(const SkMatrix& matrix)
2208
Cary Clarkab2621d2018-01-30 10:08:57 -05002209#In Matrix
2210#Line # sets Matrix ##
Cary Clark80247e52018-07-11 16:18:41 -04002211Replaces Matrix with matrix.
Cary Clark8032b982017-07-28 11:04:54 -04002212Unlike concat(), any prior matrix state is overwritten.
2213
Cary Clarkbad5ad72017-08-03 17:14:08 -04002214#Param matrix matrix to copy, replacing existing Matrix ##
Cary Clark8032b982017-07-28 11:04:54 -04002215
2216#Example
2217#Height 128
Cary Clarkbad5ad72017-08-03 17:14:08 -04002218void draw(SkCanvas* canvas) {
2219 SkPaint paint;
2220 canvas->scale(4, 6);
2221 canvas->drawString("truth", 2, 10, paint);
2222 SkMatrix matrix;
2223 matrix.setScale(2.8f, 6);
2224 canvas->setMatrix(matrix);
2225 canvas->drawString("consequences", 2, 20, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002226}
2227##
2228
Cary Clark2ade9972017-11-02 17:49:34 -04002229#SeeAlso resetMatrix concat() translate() rotate() scale() skew()
Cary Clark8032b982017-07-28 11:04:54 -04002230
2231##
2232
2233# ------------------------------------------------------------------------------
2234
2235#Method void resetMatrix()
2236
Cary Clarkab2621d2018-01-30 10:08:57 -05002237#In Matrix
2238#Line # resets Matrix to identity ##
Cary Clark8032b982017-07-28 11:04:54 -04002239Sets Matrix to the identity matrix.
2240Any prior matrix state is overwritten.
2241
2242#Example
2243#Height 128
Cary Clarkbad5ad72017-08-03 17:14:08 -04002244void draw(SkCanvas* canvas) {
2245 SkPaint paint;
2246 canvas->scale(4, 6);
2247 canvas->drawString("truth", 2, 10, paint);
2248 canvas->resetMatrix();
2249 canvas->scale(2.8f, 6);
2250 canvas->drawString("consequences", 2, 20, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002251}
2252##
2253
Cary Clark2ade9972017-11-02 17:49:34 -04002254#SeeAlso setMatrix concat() translate() rotate() scale() skew()
Cary Clark8032b982017-07-28 11:04:54 -04002255
2256##
2257
2258# ------------------------------------------------------------------------------
2259
2260#Method const SkMatrix& getTotalMatrix() const
2261
Cary Clarkab2621d2018-01-30 10:08:57 -05002262#In Matrix
2263#Line # returns Matrix ##
Cary Clark8032b982017-07-28 11:04:54 -04002264Returns Matrix.
2265This does not account for translation by Device or Surface.
2266
Cary Clarkbad5ad72017-08-03 17:14:08 -04002267#Return Matrix in Canvas ##
Cary Clark8032b982017-07-28 11:04:54 -04002268
2269#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04002270 SkDebugf("isIdentity %s\n", canvas->getTotalMatrix().isIdentity() ? "true" : "false");
2271 #StdOut
2272 isIdentity true
2273 ##
Cary Clark8032b982017-07-28 11:04:54 -04002274##
2275
Cary Clark2ade9972017-11-02 17:49:34 -04002276#SeeAlso setMatrix resetMatrix concat()
Cary Clark8032b982017-07-28 11:04:54 -04002277
2278##
2279
Cary Clark08895c42018-02-01 09:37:32 -05002280#Subtopic Matrix ##
Cary Clark8032b982017-07-28 11:04:54 -04002281
2282# ------------------------------------------------------------------------------
Cary Clark08895c42018-02-01 09:37:32 -05002283#Subtopic Clip
2284#Line # stack of clipping Paths ##
Cary Clark8032b982017-07-28 11:04:54 -04002285
2286Clip is built from a stack of clipping paths. Each Path in the
Herb Derbyefe39bc2018-05-01 17:06:20 -04002287stack can be constructed from one or more Path_Contour elements. The
Cary Clark8032b982017-07-28 11:04:54 -04002288Path_Contour may be composed of any number of Path_Verb segments. Each
2289Path_Contour forms a closed area; Path_Fill_Type defines the area enclosed
2290by Path_Contour.
2291
2292Clip stack of Path elements successfully restrict the Path area. Each
Herb Derbyefe39bc2018-05-01 17:06:20 -04002293Path is transformed by Matrix, then intersected with or subtracted from the
Cary Clark8032b982017-07-28 11:04:54 -04002294prior Clip to form the replacement Clip. Use SkClipOp::kDifference
2295to subtract Path from Clip; use SkClipOp::kIntersect to intersect Path
2296with Clip.
2297
Cary Clarkffb3d682018-05-17 12:17:28 -04002298A clipping Path may be Anti_Aliased; if Path, after transformation, is
2299composed of horizontal and vertical lines, clearing Anti_Alias allows whole pixels
Cary Clarkce101242017-09-01 15:51:02 -04002300to either be inside or outside the clip. The fastest drawing has a Aliased,
2301rectangular clip.
Cary Clark8032b982017-07-28 11:04:54 -04002302
Cary Clarkffb3d682018-05-17 12:17:28 -04002303If clipping Path has Anti_Alias set, clip may partially clip a pixel, requiring
Herb Derbyefe39bc2018-05-01 17:06:20 -04002304that drawing blend partially with the destination along the edge. A rotated
Cary Clarkffb3d682018-05-17 12:17:28 -04002305rectangular Anti_Aliased clip looks smoother but draws slower.
Cary Clark8032b982017-07-28 11:04:54 -04002306
2307Clip can combine with Rect and Round_Rect primitives; like
2308Path, these are transformed by Matrix before they are combined with Clip.
2309
2310Clip can combine with Region. Region is assumed to be in Device coordinates
2311and is unaffected by Matrix.
2312
2313#Example
2314#Height 90
2315 #Description
Cary Clarkffb3d682018-05-17 12:17:28 -04002316 Draw a red circle with an Aliased clip and an Anti_Aliased clip.
Cary Clark8032b982017-07-28 11:04:54 -04002317 Use an image filter to zoom into the pixels drawn.
Cary Clarkce101242017-09-01 15:51:02 -04002318 The edge of the Aliased clip fully draws pixels in the red circle.
Cary Clarkffb3d682018-05-17 12:17:28 -04002319 The edge of the Anti_Aliased clip partially draws pixels in the red circle.
Cary Clark8032b982017-07-28 11:04:54 -04002320 ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002321 SkPaint redPaint, scalePaint;
2322 redPaint.setAntiAlias(true);
2323 redPaint.setColor(SK_ColorRED);
2324 canvas->save();
2325 for (bool antialias : { false, true } ) {
2326 canvas->save();
2327 canvas->clipRect(SkRect::MakeWH(19.5f, 11.5f), antialias);
2328 canvas->drawCircle(17, 11, 8, redPaint);
2329 canvas->restore();
2330 canvas->translate(16, 0);
2331 }
2332 canvas->restore();
2333 SkMatrix matrix;
2334 matrix.setScale(6, 6);
2335 scalePaint.setImageFilter(
2336 SkImageFilter::MakeMatrixFilter(matrix, kNone_SkFilterQuality, nullptr));
2337 SkCanvas::SaveLayerRec saveLayerRec(
Herb Derbyefe39bc2018-05-01 17:06:20 -04002338 nullptr, &scalePaint, SkCanvas::kInitWithPrevious_SaveLayerFlag);
Cary Clarkbad5ad72017-08-03 17:14:08 -04002339 canvas->saveLayer(saveLayerRec);
Cary Clark8032b982017-07-28 11:04:54 -04002340 canvas->restore();
2341##
2342
2343#Method void clipRect(const SkRect& rect, SkClipOp op, bool doAntiAlias)
2344
Cary Clarkab2621d2018-01-30 10:08:57 -05002345#In Clip
2346#Line # combines Clip with Rect ##
Cary Clark80247e52018-07-11 16:18:41 -04002347Replaces Clip with the intersection or difference of Clip and rect,
Cary Clarkffb3d682018-05-17 12:17:28 -04002348with an Aliased or Anti_Aliased clip edge. rect is transformed by Matrix
Cary Clark8032b982017-07-28 11:04:54 -04002349before it is combined with Clip.
2350
Cary Clarka523d2d2017-08-30 08:58:10 -04002351#Param rect Rect to combine with Clip ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002352#Param op Clip_Op to apply to Clip ##
Cary Clarkffb3d682018-05-17 12:17:28 -04002353#Param doAntiAlias true if Clip is to be Anti_Aliased ##
Cary Clark8032b982017-07-28 11:04:54 -04002354
2355#Example
2356#Height 128
Cary Clarkbad5ad72017-08-03 17:14:08 -04002357void draw(SkCanvas* canvas) {
2358 canvas->rotate(10);
2359 SkPaint paint;
2360 paint.setAntiAlias(true);
2361 for (auto alias: { false, true } ) {
2362 canvas->save();
2363 canvas->clipRect(SkRect::MakeWH(90, 80), SkClipOp::kIntersect, alias);
2364 canvas->drawCircle(100, 60, 60, paint);
2365 canvas->restore();
2366 canvas->translate(80, 0);
2367 }
Cary Clark8032b982017-07-28 11:04:54 -04002368}
2369##
2370
Cary Clark2ade9972017-11-02 17:49:34 -04002371#SeeAlso clipRRect clipPath clipRegion
Cary Clark8032b982017-07-28 11:04:54 -04002372
2373##
2374
Herb Derbyefe39bc2018-05-01 17:06:20 -04002375#Method void clipRect(const SkRect& rect, SkClipOp op)
Cary Clark8032b982017-07-28 11:04:54 -04002376
Cary Clarkab2621d2018-01-30 10:08:57 -05002377#In Clip
Cary Clark80247e52018-07-11 16:18:41 -04002378Replaces Clip with the intersection or difference of Clip and rect.
Cary Clarkce101242017-09-01 15:51:02 -04002379Resulting Clip is Aliased; pixels are fully contained by the clip.
Cary Clarkbad5ad72017-08-03 17:14:08 -04002380rect is transformed by Matrix before it is combined with Clip.
Cary Clark8032b982017-07-28 11:04:54 -04002381
Cary Clarka523d2d2017-08-30 08:58:10 -04002382#Param rect Rect to combine with Clip ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002383#Param op Clip_Op to apply to Clip ##
Cary Clark8032b982017-07-28 11:04:54 -04002384
2385#Example
2386#Height 192
2387#Width 280
Cary Clarkbad5ad72017-08-03 17:14:08 -04002388void draw(SkCanvas* canvas) {
2389 SkPaint paint;
2390 for (SkClipOp op: { SkClipOp::kIntersect, SkClipOp::kDifference } ) {
2391 canvas->save();
2392 canvas->clipRect(SkRect::MakeWH(90, 120), op, false);
2393 canvas->drawCircle(100, 100, 60, paint);
2394 canvas->restore();
2395 canvas->translate(80, 0);
2396 }
Cary Clark8032b982017-07-28 11:04:54 -04002397}
2398##
2399
Cary Clark2ade9972017-11-02 17:49:34 -04002400#SeeAlso clipRRect clipPath clipRegion
Cary Clark8032b982017-07-28 11:04:54 -04002401
2402##
2403
Herb Derbyefe39bc2018-05-01 17:06:20 -04002404#Method void clipRect(const SkRect& rect, bool doAntiAlias = false)
Cary Clark8032b982017-07-28 11:04:54 -04002405
Cary Clarkab2621d2018-01-30 10:08:57 -05002406#In Clip
Cary Clark80247e52018-07-11 16:18:41 -04002407Replaces Clip with the intersection of Clip and rect.
Cary Clarkce101242017-09-01 15:51:02 -04002408Resulting Clip is Aliased; pixels are fully contained by the clip.
Cary Clark8032b982017-07-28 11:04:54 -04002409rect is transformed by Matrix
2410before it is combined with Clip.
2411
Cary Clarka523d2d2017-08-30 08:58:10 -04002412#Param rect Rect to combine with Clip ##
Cary Clarkffb3d682018-05-17 12:17:28 -04002413#Param doAntiAlias true if Clip is to be Anti_Aliased ##
Cary Clark8032b982017-07-28 11:04:54 -04002414
2415#Example
2416#Height 133
2417 #Description
Cary Clarkce101242017-09-01 15:51:02 -04002418 A circle drawn in pieces looks uniform when drawn Aliased.
Cary Clarkffb3d682018-05-17 12:17:28 -04002419 The same circle pieces blend with pixels more than once when Anti_Aliased,
Cary Clark8032b982017-07-28 11:04:54 -04002420 visible as a thin pair of lines through the right circle.
2421 ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002422void draw(SkCanvas* canvas) {
2423 canvas->clear(SK_ColorWHITE);
2424 SkPaint paint;
2425 paint.setAntiAlias(true);
2426 paint.setColor(0x8055aaff);
2427 SkRect clipRect = { 0, 0, 87.4f, 87.4f };
2428 for (auto alias: { false, true } ) {
2429 canvas->save();
2430 canvas->clipRect(clipRect, SkClipOp::kIntersect, alias);
2431 canvas->drawCircle(67, 67, 60, paint);
2432 canvas->restore();
2433 canvas->save();
2434 canvas->clipRect(clipRect, SkClipOp::kDifference, alias);
2435 canvas->drawCircle(67, 67, 60, paint);
2436 canvas->restore();
2437 canvas->translate(120, 0);
2438 }
Cary Clark8032b982017-07-28 11:04:54 -04002439}
2440##
2441
Cary Clark2ade9972017-11-02 17:49:34 -04002442#SeeAlso clipRRect clipPath clipRegion
Cary Clark8032b982017-07-28 11:04:54 -04002443
2444##
2445
2446#Method void androidFramework_setDeviceClipRestriction(const SkIRect& rect)
2447
Cary Clarkab2621d2018-01-30 10:08:57 -05002448#In Clip
Cary Clark682c58d2018-05-16 07:07:07 -04002449#Line # exists for use by Android framework ##
Cary Clarkce101242017-09-01 15:51:02 -04002450Sets the maximum clip rectangle, which can be set by clipRect, clipRRect and
Cary Clark8032b982017-07-28 11:04:54 -04002451clipPath and intersect the current clip with the specified rect.
Cary Clarkce101242017-09-01 15:51:02 -04002452The maximum clip affects only future clipping operations; it is not retroactive.
Cary Clark8032b982017-07-28 11:04:54 -04002453The clip restriction is not recorded in pictures.
2454
Herb Derbyefe39bc2018-05-01 17:06:20 -04002455Pass an empty rect to disable maximum clip.
Cary Clarkbad5ad72017-08-03 17:14:08 -04002456
Cary Clark8032b982017-07-28 11:04:54 -04002457#Private
Cary Clark137b8742018-05-30 09:21:49 -04002458This private API is for use by Android framework only.
Cary Clark8032b982017-07-28 11:04:54 -04002459##
2460
Cary Clarkbad5ad72017-08-03 17:14:08 -04002461#Param rect maximum allowed clip in device coordinates
Cary Clark579985c2017-07-31 11:48:27 -04002462#Param ##
Cary Clark8032b982017-07-28 11:04:54 -04002463
2464##
2465
2466#Method void clipRRect(const SkRRect& rrect, SkClipOp op, bool doAntiAlias)
2467
Cary Clarkab2621d2018-01-30 10:08:57 -05002468#In Clip
2469#Line # combines Clip with Round_Rect ##
Cary Clark80247e52018-07-11 16:18:41 -04002470Replaces Clip with the intersection or difference of Clip and rrect,
Cary Clarkffb3d682018-05-17 12:17:28 -04002471with an Aliased or Anti_Aliased clip edge.
Cary Clark8032b982017-07-28 11:04:54 -04002472rrect is transformed by Matrix
2473before it is combined with Clip.
2474
Cary Clarkbad5ad72017-08-03 17:14:08 -04002475#Param rrect Round_Rect to combine with Clip ##
2476#Param op Clip_Op to apply to Clip ##
Cary Clarkffb3d682018-05-17 12:17:28 -04002477#Param doAntiAlias true if Clip is to be Anti_Aliased ##
Cary Clark8032b982017-07-28 11:04:54 -04002478
2479#Example
2480#Height 128
Cary Clarkbad5ad72017-08-03 17:14:08 -04002481void draw(SkCanvas* canvas) {
2482 canvas->clear(SK_ColorWHITE);
2483 SkPaint paint;
2484 paint.setAntiAlias(true);
2485 paint.setColor(0x8055aaff);
2486 SkRRect oval;
2487 oval.setOval({10, 20, 90, 100});
2488 canvas->clipRRect(oval, SkClipOp::kIntersect, true);
2489 canvas->drawCircle(70, 100, 60, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002490}
2491##
2492
Cary Clark2ade9972017-11-02 17:49:34 -04002493#SeeAlso clipRect clipPath clipRegion
Cary Clark8032b982017-07-28 11:04:54 -04002494
2495##
2496
Herb Derbyefe39bc2018-05-01 17:06:20 -04002497#Method void clipRRect(const SkRRect& rrect, SkClipOp op)
Cary Clark8032b982017-07-28 11:04:54 -04002498
Cary Clarkab2621d2018-01-30 10:08:57 -05002499#In Clip
Cary Clark80247e52018-07-11 16:18:41 -04002500Replaces Clip with the intersection or difference of Clip and rrect.
Cary Clarkce101242017-09-01 15:51:02 -04002501Resulting Clip is Aliased; pixels are fully contained by the clip.
Cary Clarkbad5ad72017-08-03 17:14:08 -04002502rrect is transformed by Matrix before it is combined with Clip.
Cary Clark8032b982017-07-28 11:04:54 -04002503
Cary Clarkbad5ad72017-08-03 17:14:08 -04002504#Param rrect Round_Rect to combine with Clip ##
2505#Param op Clip_Op to apply to Clip ##
Cary Clark8032b982017-07-28 11:04:54 -04002506
2507#Example
2508#Height 128
Cary Clarkbad5ad72017-08-03 17:14:08 -04002509void draw(SkCanvas* canvas) {
2510 SkPaint paint;
2511 paint.setColor(0x8055aaff);
2512 auto oval = SkRRect::MakeOval({10, 20, 90, 100});
2513 canvas->clipRRect(oval, SkClipOp::kIntersect);
2514 canvas->drawCircle(70, 100, 60, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002515}
2516##
2517
Cary Clark2ade9972017-11-02 17:49:34 -04002518#SeeAlso clipRect clipPath clipRegion
Cary Clark8032b982017-07-28 11:04:54 -04002519
2520##
2521
Herb Derbyefe39bc2018-05-01 17:06:20 -04002522#Method void clipRRect(const SkRRect& rrect, bool doAntiAlias = false)
Cary Clark8032b982017-07-28 11:04:54 -04002523
Cary Clarkab2621d2018-01-30 10:08:57 -05002524#In Clip
Cary Clark80247e52018-07-11 16:18:41 -04002525Replaces Clip with the intersection of Clip and rrect,
Cary Clarkffb3d682018-05-17 12:17:28 -04002526with an Aliased or Anti_Aliased clip edge.
Cary Clarkbad5ad72017-08-03 17:14:08 -04002527rrect is transformed by Matrix before it is combined with Clip.
Cary Clark8032b982017-07-28 11:04:54 -04002528
Cary Clarkbad5ad72017-08-03 17:14:08 -04002529#Param rrect Round_Rect to combine with Clip ##
Cary Clarkffb3d682018-05-17 12:17:28 -04002530#Param doAntiAlias true if Clip is to be Anti_Aliased ##
Cary Clark8032b982017-07-28 11:04:54 -04002531
2532#Example
2533#Height 128
Cary Clarkbad5ad72017-08-03 17:14:08 -04002534void draw(SkCanvas* canvas) {
2535 SkPaint paint;
2536 paint.setAntiAlias(true);
2537 auto oval = SkRRect::MakeRectXY({10, 20, 90, 100}, 9, 13);
2538 canvas->clipRRect(oval, true);
2539 canvas->drawCircle(70, 100, 60, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002540}
2541##
2542
Cary Clark2ade9972017-11-02 17:49:34 -04002543#SeeAlso clipRect clipPath clipRegion
Cary Clark8032b982017-07-28 11:04:54 -04002544
2545##
2546
2547#Method void clipPath(const SkPath& path, SkClipOp op, bool doAntiAlias)
2548
Cary Clarkab2621d2018-01-30 10:08:57 -05002549#In Clip
2550#Line # combines Clip with Path ##
Cary Clark80247e52018-07-11 16:18:41 -04002551Replaces Clip with the intersection or difference of Clip and path,
Cary Clarkffb3d682018-05-17 12:17:28 -04002552with an Aliased or Anti_Aliased clip edge. Path_Fill_Type determines if path
Cary Clark8032b982017-07-28 11:04:54 -04002553describes the area inside or outside its contours; and if Path_Contour overlaps
2554itself or another Path_Contour, whether the overlaps form part of the area.
Cary Clarkbad5ad72017-08-03 17:14:08 -04002555path is transformed by Matrix before it is combined with Clip.
Cary Clark8032b982017-07-28 11:04:54 -04002556
Cary Clarkbad5ad72017-08-03 17:14:08 -04002557#Param path Path to combine with Clip ##
2558#Param op Clip_Op to apply to Clip ##
Cary Clarkffb3d682018-05-17 12:17:28 -04002559#Param doAntiAlias true if Clip is to be Anti_Aliased ##
Cary Clark8032b982017-07-28 11:04:54 -04002560
2561#Example
2562#Description
2563Top figure uses SkPath::kInverseWinding_FillType and SkClipOp::kDifference;
2564area outside clip is subtracted from circle.
2565
2566Bottom figure uses SkPath::kWinding_FillType and SkClipOp::kIntersect;
2567area inside clip is intersected with circle.
2568##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002569void draw(SkCanvas* canvas) {
2570 SkPaint paint;
2571 paint.setAntiAlias(true);
2572 SkPath path;
2573 path.addRect({20, 30, 100, 110});
2574 path.setFillType(SkPath::kInverseWinding_FillType);
2575 canvas->save();
2576 canvas->clipPath(path, SkClipOp::kDifference, false);
2577 canvas->drawCircle(70, 100, 60, paint);
2578 canvas->restore();
2579 canvas->translate(100, 100);
2580 path.setFillType(SkPath::kWinding_FillType);
2581 canvas->clipPath(path, SkClipOp::kIntersect, false);
2582 canvas->drawCircle(70, 100, 60, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002583}
2584##
2585
Cary Clark2ade9972017-11-02 17:49:34 -04002586#SeeAlso clipRect clipRRect clipRegion
Cary Clark8032b982017-07-28 11:04:54 -04002587
2588##
2589
Herb Derbyefe39bc2018-05-01 17:06:20 -04002590#Method void clipPath(const SkPath& path, SkClipOp op)
Cary Clark8032b982017-07-28 11:04:54 -04002591
Cary Clarkab2621d2018-01-30 10:08:57 -05002592#In Clip
Cary Clark80247e52018-07-11 16:18:41 -04002593Replaces Clip with the intersection or difference of Clip and path.
Cary Clarkce101242017-09-01 15:51:02 -04002594Resulting Clip is Aliased; pixels are fully contained by the clip.
Cary Clark8032b982017-07-28 11:04:54 -04002595Path_Fill_Type determines if path
2596describes the area inside or outside its contours; and if Path_Contour overlaps
2597itself or another Path_Contour, whether the overlaps form part of the area.
2598path is transformed by Matrix
2599before it is combined with Clip.
2600
Cary Clarkbad5ad72017-08-03 17:14:08 -04002601#Param path Path to combine with Clip ##
2602#Param op Clip_Op to apply to Clip ##
Cary Clark8032b982017-07-28 11:04:54 -04002603
2604#Example
2605#Description
Cary Clarkbc5697d2017-10-04 14:31:33 -04002606Overlapping Rects form a clip. When clip Path_Fill_Type is set to
Herb Derbyefe39bc2018-05-01 17:06:20 -04002607SkPath::kWinding_FillType, the overlap is included. Set to
Cary Clark8032b982017-07-28 11:04:54 -04002608SkPath::kEvenOdd_FillType, the overlap is excluded and forms a hole.
2609##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002610void draw(SkCanvas* canvas) {
2611 SkPaint paint;
2612 paint.setAntiAlias(true);
2613 SkPath path;
2614 path.addRect({20, 15, 100, 95});
2615 path.addRect({50, 65, 130, 135});
2616 path.setFillType(SkPath::kWinding_FillType);
2617 canvas->save();
2618 canvas->clipPath(path, SkClipOp::kIntersect);
2619 canvas->drawCircle(70, 85, 60, paint);
2620 canvas->restore();
2621 canvas->translate(100, 100);
2622 path.setFillType(SkPath::kEvenOdd_FillType);
2623 canvas->clipPath(path, SkClipOp::kIntersect);
2624 canvas->drawCircle(70, 85, 60, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002625}
2626##
2627
Cary Clark2ade9972017-11-02 17:49:34 -04002628#SeeAlso clipRect clipRRect clipRegion
Cary Clark8032b982017-07-28 11:04:54 -04002629
2630##
2631
Herb Derbyefe39bc2018-05-01 17:06:20 -04002632#Method void clipPath(const SkPath& path, bool doAntiAlias = false)
Cary Clark8032b982017-07-28 11:04:54 -04002633
Cary Clarkab2621d2018-01-30 10:08:57 -05002634#In Clip
Cary Clark80247e52018-07-11 16:18:41 -04002635Replaces Clip with the intersection of Clip and path.
Cary Clarkce101242017-09-01 15:51:02 -04002636Resulting Clip is Aliased; pixels are fully contained by the clip.
Cary Clark8032b982017-07-28 11:04:54 -04002637Path_Fill_Type determines if path
2638describes the area inside or outside its contours; and if Path_Contour overlaps
2639itself or another Path_Contour, whether the overlaps form part of the area.
Cary Clarkbad5ad72017-08-03 17:14:08 -04002640path is transformed by Matrix before it is combined with Clip.
Cary Clark8032b982017-07-28 11:04:54 -04002641
Cary Clarkbad5ad72017-08-03 17:14:08 -04002642#Param path Path to combine with Clip ##
Cary Clarkffb3d682018-05-17 12:17:28 -04002643#Param doAntiAlias true if Clip is to be Anti_Aliased ##
Cary Clark8032b982017-07-28 11:04:54 -04002644
2645#Example
2646#Height 212
2647#Description
Herb Derbyefe39bc2018-05-01 17:06:20 -04002648Clip loops over itself covering its center twice. When clip Path_Fill_Type
2649is set to SkPath::kWinding_FillType, the overlap is included. Set to
Cary Clark8032b982017-07-28 11:04:54 -04002650SkPath::kEvenOdd_FillType, the overlap is excluded and forms a hole.
2651##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002652void draw(SkCanvas* canvas) {
2653 SkPaint paint;
2654 paint.setAntiAlias(true);
2655 SkPath path;
2656 SkPoint poly[] = {{20, 20}, { 80, 20}, { 80, 80}, {40, 80},
2657 {40, 40}, {100, 40}, {100, 100}, {20, 100}};
2658 path.addPoly(poly, SK_ARRAY_COUNT(poly), true);
2659 path.setFillType(SkPath::kWinding_FillType);
2660 canvas->save();
2661 canvas->clipPath(path, SkClipOp::kIntersect);
2662 canvas->drawCircle(50, 50, 45, paint);
2663 canvas->restore();
2664 canvas->translate(100, 100);
2665 path.setFillType(SkPath::kEvenOdd_FillType);
2666 canvas->clipPath(path, SkClipOp::kIntersect);
2667 canvas->drawCircle(50, 50, 45, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002668}
2669##
2670
Cary Clark2ade9972017-11-02 17:49:34 -04002671#SeeAlso clipRect clipRRect clipRegion
Cary Clark8032b982017-07-28 11:04:54 -04002672
2673##
2674
2675# ------------------------------------------------------------------------------
2676
Herb Derbyefe39bc2018-05-01 17:06:20 -04002677#Method void setAllowSimplifyClip(bool allow)
Cary Clark8032b982017-07-28 11:04:54 -04002678
Cary Clarkab2621d2018-01-30 10:08:57 -05002679#In Clip
Cary Clark682c58d2018-05-16 07:07:07 -04002680#Experimental testing
Cary Clark8032b982017-07-28 11:04:54 -04002681
Cary Clarkce101242017-09-01 15:51:02 -04002682Set to simplify clip stack using PathOps.
Cary Clark8032b982017-07-28 11:04:54 -04002683
2684##
2685
2686# ------------------------------------------------------------------------------
2687
2688#Method void clipRegion(const SkRegion& deviceRgn, SkClipOp op = SkClipOp::kIntersect)
2689
Cary Clarkab2621d2018-01-30 10:08:57 -05002690#In Clip
2691#Line # combines Clip with Region ##
Cary Clark80247e52018-07-11 16:18:41 -04002692Replaces Clip with the intersection or difference of Clip and Region deviceRgn.
Cary Clarkce101242017-09-01 15:51:02 -04002693Resulting Clip is Aliased; pixels are fully contained by the clip.
Cary Clark8032b982017-07-28 11:04:54 -04002694deviceRgn is unaffected by Matrix.
2695
Cary Clarkbad5ad72017-08-03 17:14:08 -04002696#Param deviceRgn Region to combine with Clip ##
2697#Param op Clip_Op to apply to Clip ##
Cary Clark8032b982017-07-28 11:04:54 -04002698
2699#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04002700#Description
Cary Clarkce101242017-09-01 15:51:02 -04002701 region is unaffected by canvas rotation; iRect is affected by canvas rotation.
2702 Both clips are Aliased; this is not noticeable on Region clip because it
Cary Clarkbad5ad72017-08-03 17:14:08 -04002703 aligns to pixel boundaries.
2704##
2705void draw(SkCanvas* canvas) {
2706 SkPaint paint;
2707 paint.setAntiAlias(true);
2708 SkIRect iRect = {30, 40, 120, 130 };
2709 SkRegion region(iRect);
2710 canvas->rotate(10);
2711 canvas->save();
2712 canvas->clipRegion(region, SkClipOp::kIntersect);
2713 canvas->drawCircle(50, 50, 45, paint);
2714 canvas->restore();
2715 canvas->translate(100, 100);
2716 canvas->clipRect(SkRect::Make(iRect), SkClipOp::kIntersect);
2717 canvas->drawCircle(50, 50, 45, paint);
Cary Clark8032b982017-07-28 11:04:54 -04002718}
2719##
2720
Cary Clark2ade9972017-11-02 17:49:34 -04002721#SeeAlso clipRect clipRRect clipPath
Cary Clark8032b982017-07-28 11:04:54 -04002722
2723##
2724
2725#Method bool quickReject(const SkRect& rect) const
2726
Cary Clarkab2621d2018-01-30 10:08:57 -05002727#In Clip
2728#Line # returns if Rect is outside Clip ##
Cary Clark80247e52018-07-11 16:18:41 -04002729Returns true if Rect rect, transformed by Matrix, can be quickly determined to be
Cary Clark8032b982017-07-28 11:04:54 -04002730outside of Clip. May return false even though rect is outside of Clip.
2731
2732Use to check if an area to be drawn is clipped out, to skip subsequent draw calls.
2733
Cary Clarkbad5ad72017-08-03 17:14:08 -04002734#Param rect Rect to compare with Clip ##
Cary Clark8032b982017-07-28 11:04:54 -04002735
Cary Clarkbad5ad72017-08-03 17:14:08 -04002736#Return true if rect, transformed by Matrix, does not intersect Clip ##
Cary Clark8032b982017-07-28 11:04:54 -04002737
2738#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04002739void draw(SkCanvas* canvas) {
Herb Derbyefe39bc2018-05-01 17:06:20 -04002740 SkRect testRect = {30, 30, 120, 129 };
2741 SkRect clipRect = {30, 130, 120, 230 };
Cary Clarkbad5ad72017-08-03 17:14:08 -04002742 canvas->save();
2743 canvas->clipRect(clipRect);
2744 SkDebugf("quickReject %s\n", canvas->quickReject(testRect) ? "true" : "false");
2745 canvas->restore();
2746 canvas->rotate(10);
2747 canvas->clipRect(clipRect);
2748 SkDebugf("quickReject %s\n", canvas->quickReject(testRect) ? "true" : "false");
Cary Clark8032b982017-07-28 11:04:54 -04002749}
2750 #StdOut
Cary Clarkbad5ad72017-08-03 17:14:08 -04002751 quickReject true
Cary Clark8032b982017-07-28 11:04:54 -04002752 quickReject false
2753 ##
2754##
2755
Cary Clark2ade9972017-11-02 17:49:34 -04002756#SeeAlso getLocalClipBounds getTotalMatrix SkBitmap::drawsNothing
Cary Clark8032b982017-07-28 11:04:54 -04002757
2758##
2759
2760#Method bool quickReject(const SkPath& path) const
2761
Cary Clarkab2621d2018-01-30 10:08:57 -05002762#In Clip
Cary Clark80247e52018-07-11 16:18:41 -04002763Returns true if path, transformed by Matrix, can be quickly determined to be
Cary Clark8032b982017-07-28 11:04:54 -04002764outside of Clip. May return false even though path is outside of Clip.
2765
2766Use to check if an area to be drawn is clipped out, to skip subsequent draw calls.
2767
Cary Clarkbad5ad72017-08-03 17:14:08 -04002768#Param path Path to compare with Clip ##
Cary Clark8032b982017-07-28 11:04:54 -04002769
Cary Clarkbad5ad72017-08-03 17:14:08 -04002770#Return true if path, transformed by Matrix, does not intersect Clip ##
Cary Clark8032b982017-07-28 11:04:54 -04002771
2772#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04002773void draw(SkCanvas* canvas) {
Herb Derbyefe39bc2018-05-01 17:06:20 -04002774 SkPoint testPoints[] = {{30, 30}, {120, 30}, {120, 129} };
2775 SkPoint clipPoints[] = {{30, 130}, {120, 130}, {120, 230} };
Cary Clarkbad5ad72017-08-03 17:14:08 -04002776 SkPath testPath, clipPath;
2777 testPath.addPoly(testPoints, SK_ARRAY_COUNT(testPoints), true);
2778 clipPath.addPoly(clipPoints, SK_ARRAY_COUNT(clipPoints), true);
2779 canvas->save();
2780 canvas->clipPath(clipPath);
2781 SkDebugf("quickReject %s\n", canvas->quickReject(testPath) ? "true" : "false");
2782 canvas->restore();
2783 canvas->rotate(10);
2784 canvas->clipPath(clipPath);
2785 SkDebugf("quickReject %s\n", canvas->quickReject(testPath) ? "true" : "false");
Cary Clark8032b982017-07-28 11:04:54 -04002786 #StdOut
Cary Clarkbad5ad72017-08-03 17:14:08 -04002787 quickReject true
Cary Clark8032b982017-07-28 11:04:54 -04002788 quickReject false
2789 ##
2790}
2791##
2792
Cary Clark2ade9972017-11-02 17:49:34 -04002793#SeeAlso getLocalClipBounds getTotalMatrix SkBitmap::drawsNothing
Cary Clark8032b982017-07-28 11:04:54 -04002794
2795##
2796
Herb Derbyefe39bc2018-05-01 17:06:20 -04002797#Method SkRect getLocalClipBounds() const
Cary Clark8032b982017-07-28 11:04:54 -04002798
Cary Clarkab2621d2018-01-30 10:08:57 -05002799#In Clip
2800#Line # returns Clip bounds in source coordinates ##
Cary Clark80247e52018-07-11 16:18:41 -04002801Returns bounds of Clip, transformed by inverse of Matrix. If Clip is empty,
Cary Clark8032b982017-07-28 11:04:54 -04002802return SkRect::MakeEmpty, where all Rect sides equal zero.
2803
2804Rect returned is outset by one to account for partial pixel coverage if Clip
Cary Clarkffb3d682018-05-17 12:17:28 -04002805is Anti_Aliased.
Cary Clark8032b982017-07-28 11:04:54 -04002806
Cary Clarkbad5ad72017-08-03 17:14:08 -04002807#Return bounds of Clip in local coordinates ##
Cary Clark8032b982017-07-28 11:04:54 -04002808
2809#Example
Herb Derbyefe39bc2018-05-01 17:06:20 -04002810 #Description
Cary Clark8032b982017-07-28 11:04:54 -04002811 Initial bounds is device bounds outset by 1 on all sides.
2812 Clipped bounds is clipPath bounds outset by 1 on all sides.
Cary Clark5538c132018-06-14 12:28:14 -04002813 Scaling the canvas by two on both axes scales the local bounds by 1/2
2814 on both axes.
Cary Clark8032b982017-07-28 11:04:54 -04002815 ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002816 SkCanvas local(256, 256);
2817 canvas = &local;
2818 SkRect bounds = canvas->getLocalClipBounds();
2819 SkDebugf("left:%g top:%g right:%g bottom:%g\n",
2820 bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom);
Herb Derbyefe39bc2018-05-01 17:06:20 -04002821 SkPoint clipPoints[] = {{30, 130}, {120, 130}, {120, 230} };
Cary Clarkbad5ad72017-08-03 17:14:08 -04002822 SkPath clipPath;
2823 clipPath.addPoly(clipPoints, SK_ARRAY_COUNT(clipPoints), true);
2824 canvas->clipPath(clipPath);
2825 bounds = canvas->getLocalClipBounds();
2826 SkDebugf("left:%g top:%g right:%g bottom:%g\n",
2827 bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom);
2828 canvas->scale(2, 2);
2829 bounds = canvas->getLocalClipBounds();
2830 SkDebugf("left:%g top:%g right:%g bottom:%g\n",
2831 bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom);
2832 #StdOut
2833 left:-1 top:-1 right:257 bottom:257
2834 left:29 top:129 right:121 bottom:231
2835 left:14.5 top:64.5 right:60.5 bottom:115.5
2836 ##
Cary Clark8032b982017-07-28 11:04:54 -04002837##
2838
2839# local canvas in example works around bug in fiddle ##
Cary Clark4855f782018-02-06 09:41:53 -05002840#Bug 6524
Cary Clark2ade9972017-11-02 17:49:34 -04002841#SeeAlso getDeviceClipBounds getBaseLayerSize quickReject
Cary Clark8032b982017-07-28 11:04:54 -04002842
2843##
2844
Herb Derbyefe39bc2018-05-01 17:06:20 -04002845#Method bool getLocalClipBounds(SkRect* bounds) const
Cary Clark8032b982017-07-28 11:04:54 -04002846
Cary Clarkab2621d2018-01-30 10:08:57 -05002847#In Clip
Cary Clark80247e52018-07-11 16:18:41 -04002848Returns bounds of Clip, transformed by inverse of Matrix. If Clip is empty,
Cary Clark8032b982017-07-28 11:04:54 -04002849return false, and set bounds to SkRect::MakeEmpty, where all Rect sides equal zero.
2850
2851bounds is outset by one to account for partial pixel coverage if Clip
Cary Clarkffb3d682018-05-17 12:17:28 -04002852is Anti_Aliased.
Cary Clark8032b982017-07-28 11:04:54 -04002853
Cary Clarkbad5ad72017-08-03 17:14:08 -04002854#Param bounds Rect of Clip in local coordinates ##
Cary Clark8032b982017-07-28 11:04:54 -04002855
Cary Clarkbad5ad72017-08-03 17:14:08 -04002856#Return true if Clip bounds is not empty ##
Cary Clark8032b982017-07-28 11:04:54 -04002857
2858#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04002859 void draw(SkCanvas* canvas) {
2860 SkCanvas local(256, 256);
2861 canvas = &local;
2862 SkRect bounds;
2863 SkDebugf("local bounds empty = %s\n", canvas->getLocalClipBounds(&bounds)
2864 ? "false" : "true");
2865 SkPath path;
2866 canvas->clipPath(path);
2867 SkDebugf("local bounds empty = %s\n", canvas->getLocalClipBounds(&bounds)
2868 ? "false" : "true");
Cary Clark8032b982017-07-28 11:04:54 -04002869 }
2870 #StdOut
Cary Clarkbad5ad72017-08-03 17:14:08 -04002871 local bounds empty = false
Cary Clark8032b982017-07-28 11:04:54 -04002872 local bounds empty = true
2873 ##
2874##
2875
2876# local canvas in example works around bug in fiddle ##
Cary Clark4855f782018-02-06 09:41:53 -05002877#Bug 6524
Cary Clark2ade9972017-11-02 17:49:34 -04002878#SeeAlso getDeviceClipBounds getBaseLayerSize quickReject
Cary Clark8032b982017-07-28 11:04:54 -04002879
2880##
2881
Herb Derbyefe39bc2018-05-01 17:06:20 -04002882#Method SkIRect getDeviceClipBounds() const
Cary Clark8032b982017-07-28 11:04:54 -04002883
Cary Clarkab2621d2018-01-30 10:08:57 -05002884#In Clip
2885#Line # returns IRect bounds of Clip ##
Cary Clark80247e52018-07-11 16:18:41 -04002886Returns IRect bounds of Clip, unaffected by Matrix. If Clip is empty,
Cary Clark8032b982017-07-28 11:04:54 -04002887return SkRect::MakeEmpty, where all Rect sides equal zero.
2888
Herb Derbyefe39bc2018-05-01 17:06:20 -04002889Unlike getLocalClipBounds, returned IRect is not outset.
Cary Clark8032b982017-07-28 11:04:54 -04002890
Cary Clarkbad5ad72017-08-03 17:14:08 -04002891#Return bounds of Clip in Device coordinates ##
Cary Clark8032b982017-07-28 11:04:54 -04002892
2893#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04002894void draw(SkCanvas* canvas) {
2895 #Description
Cary Clark8032b982017-07-28 11:04:54 -04002896 Initial bounds is device bounds, not outset.
2897 Clipped bounds is clipPath bounds, not outset.
Cary Clark5538c132018-06-14 12:28:14 -04002898 Scaling the canvas by 1/2 on both axes scales the device bounds by 1/2
2899 on both axes.
Cary Clarkbad5ad72017-08-03 17:14:08 -04002900 ##
2901 SkCanvas device(256, 256);
2902 canvas = &device;
2903 SkIRect bounds = canvas->getDeviceClipBounds();
2904 SkDebugf("left:%d top:%d right:%d bottom:%d\n",
2905 bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom);
Herb Derbyefe39bc2018-05-01 17:06:20 -04002906 SkPoint clipPoints[] = {{30, 130}, {120, 130}, {120, 230} };
Cary Clarkbad5ad72017-08-03 17:14:08 -04002907 SkPath clipPath;
2908 clipPath.addPoly(clipPoints, SK_ARRAY_COUNT(clipPoints), true);
2909 canvas->save();
2910 canvas->clipPath(clipPath);
2911 bounds = canvas->getDeviceClipBounds();
2912 SkDebugf("left:%d top:%d right:%d bottom:%d\n",
2913 bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom);
2914 canvas->restore();
2915 canvas->scale(1.f/2, 1.f/2);
2916 canvas->clipPath(clipPath);
2917 bounds = canvas->getDeviceClipBounds();
2918 SkDebugf("left:%d top:%d right:%d bottom:%d\n",
2919 bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom);
Cary Clark8032b982017-07-28 11:04:54 -04002920 #StdOut
Cary Clarkbad5ad72017-08-03 17:14:08 -04002921 left:0 top:0 right:256 bottom:256
2922 left:30 top:130 right:120 bottom:230
Cary Clark8032b982017-07-28 11:04:54 -04002923 left:15 top:65 right:60 bottom:115
2924 ##
2925}
2926##
2927
2928#ToDo some confusion on why with an identity Matrix local and device are different ##
Cary Clark2ade9972017-11-02 17:49:34 -04002929#SeeAlso getLocalClipBounds getBaseLayerSize quickReject
Cary Clark8032b982017-07-28 11:04:54 -04002930
2931# device canvas in example works around bug in fiddle ##
Cary Clark4855f782018-02-06 09:41:53 -05002932#Bug 6524
Cary Clark8032b982017-07-28 11:04:54 -04002933
2934##
2935
Herb Derbyefe39bc2018-05-01 17:06:20 -04002936#Method bool getDeviceClipBounds(SkIRect* bounds) const
Cary Clark8032b982017-07-28 11:04:54 -04002937
Cary Clarkab2621d2018-01-30 10:08:57 -05002938#In Clip
Cary Clark80247e52018-07-11 16:18:41 -04002939Returns IRect bounds of Clip, unaffected by Matrix. If Clip is empty,
Cary Clark8032b982017-07-28 11:04:54 -04002940return false, and set bounds to SkRect::MakeEmpty, where all Rect sides equal zero.
2941
Herb Derbyefe39bc2018-05-01 17:06:20 -04002942Unlike getLocalClipBounds, bounds is not outset.
Cary Clark8032b982017-07-28 11:04:54 -04002943
Cary Clarkbad5ad72017-08-03 17:14:08 -04002944#Param bounds Rect of Clip in device coordinates ##
Cary Clark8032b982017-07-28 11:04:54 -04002945
Cary Clarkbad5ad72017-08-03 17:14:08 -04002946#Return true if Clip bounds is not empty ##
Cary Clark8032b982017-07-28 11:04:54 -04002947
2948#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04002949 void draw(SkCanvas* canvas) {
2950 SkIRect bounds;
2951 SkDebugf("device bounds empty = %s\n", canvas->getDeviceClipBounds(&bounds)
2952 ? "false" : "true");
2953 SkPath path;
2954 canvas->clipPath(path);
2955 SkDebugf("device bounds empty = %s\n", canvas->getDeviceClipBounds(&bounds)
2956 ? "false" : "true");
Cary Clark8032b982017-07-28 11:04:54 -04002957 }
2958 #StdOut
Cary Clarkbad5ad72017-08-03 17:14:08 -04002959 device bounds empty = false
Cary Clark8032b982017-07-28 11:04:54 -04002960 device bounds empty = true
2961 ##
2962##
2963
Cary Clark2ade9972017-11-02 17:49:34 -04002964#SeeAlso getLocalClipBounds getBaseLayerSize quickReject
Cary Clark8032b982017-07-28 11:04:54 -04002965
2966##
2967
Cary Clark08895c42018-02-01 09:37:32 -05002968#Subtopic Clip ##
Cary Clark8032b982017-07-28 11:04:54 -04002969
2970# ------------------------------------------------------------------------------
Cary Clark78de7512018-02-07 07:27:09 -05002971#Subtopic Draw
Cary Clark78de7512018-02-07 07:27:09 -05002972#Line # draws into Canvas ##
2973##
Cary Clark8032b982017-07-28 11:04:54 -04002974
2975#Method void drawColor(SkColor color, SkBlendMode mode = SkBlendMode::kSrcOver)
Cary Clark78de7512018-02-07 07:27:09 -05002976#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05002977#Line # fills Clip with Color and Blend_Mode ##
Cary Clark80247e52018-07-11 16:18:41 -04002978Fills Clip with Color color.
Cary Clarkffb3d682018-05-17 12:17:28 -04002979mode determines how ARGB is combined with destination.
Cary Clark8032b982017-07-28 11:04:54 -04002980
Cary Clarkffb3d682018-05-17 12:17:28 -04002981#Param color Unpremultiplied ARGB ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04002982#Param mode SkBlendMode used to combine source color and destination ##
Cary Clark8032b982017-07-28 11:04:54 -04002983
2984#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04002985 canvas->drawColor(SK_ColorRED);
2986 canvas->clipRect(SkRect::MakeWH(150, 150));
2987 canvas->drawColor(SkColorSetARGB(0x80, 0x00, 0xFF, 0x00), SkBlendMode::kPlus);
2988 canvas->clipRect(SkRect::MakeWH(75, 75));
2989 canvas->drawColor(SkColorSetARGB(0x80, 0x00, 0x00, 0xFF), SkBlendMode::kPlus);
Cary Clark8032b982017-07-28 11:04:54 -04002990##
2991
Cary Clark2ade9972017-11-02 17:49:34 -04002992#SeeAlso clear SkBitmap::erase drawPaint
Cary Clark8032b982017-07-28 11:04:54 -04002993
2994##
2995
2996# ------------------------------------------------------------------------------
2997
Herb Derbyefe39bc2018-05-01 17:06:20 -04002998#Method void clear(SkColor color)
Cary Clark78de7512018-02-07 07:27:09 -05002999#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05003000#Line # fills Clip with Color ##
Cary Clark80247e52018-07-11 16:18:41 -04003001Fills Clip with Color color using SkBlendMode::kSrc.
Cary Clark8032b982017-07-28 11:04:54 -04003002This has the effect of replacing all pixels contained by Clip with color.
3003
Cary Clarkffb3d682018-05-17 12:17:28 -04003004#Param color Unpremultiplied ARGB ##
Cary Clark8032b982017-07-28 11:04:54 -04003005
3006#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003007void draw(SkCanvas* canvas) {
3008 canvas->save();
3009 canvas->clipRect(SkRect::MakeWH(256, 128));
Herb Derbyefe39bc2018-05-01 17:06:20 -04003010 canvas->clear(SkColorSetARGB(0x80, 0xFF, 0x00, 0x00));
Cary Clarkbad5ad72017-08-03 17:14:08 -04003011 canvas->restore();
3012 canvas->save();
3013 canvas->clipRect(SkRect::MakeWH(150, 192));
3014 canvas->clear(SkColorSetARGB(0x80, 0x00, 0xFF, 0x00));
3015 canvas->restore();
3016 canvas->clipRect(SkRect::MakeWH(75, 256));
3017 canvas->clear(SkColorSetARGB(0x80, 0x00, 0x00, 0xFF));
Cary Clark8032b982017-07-28 11:04:54 -04003018}
3019##
3020
Cary Clark2ade9972017-11-02 17:49:34 -04003021#SeeAlso drawColor SkBitmap::erase drawPaint
Cary Clark8032b982017-07-28 11:04:54 -04003022
3023##
3024
3025# ------------------------------------------------------------------------------
3026
Herb Derbyefe39bc2018-05-01 17:06:20 -04003027#Method void discard()
Cary Clark78de7512018-02-07 07:27:09 -05003028#In Utility
Cary Clarkab2621d2018-01-30 10:08:57 -05003029#Line # makes Canvas contents undefined ##
Cary Clark80247e52018-07-11 16:18:41 -04003030Makes Canvas contents undefined. Subsequent calls that read Canvas pixels,
Cary Clark8032b982017-07-28 11:04:54 -04003031such as drawing with SkBlendMode, return undefined results. discard() does
3032not change Clip or Matrix.
3033
3034discard() may do nothing, depending on the implementation of Surface or Device
3035that created Canvas.
3036
3037discard() allows optimized performance on subsequent draws by removing
3038cached data associated with Surface or Device.
3039It is not necessary to call discard() once done with Canvas;
3040any cached data is deleted when owning Surface or Device is deleted.
3041
3042#ToDo example? not sure how to make this meaningful w/o more implementation detail ##
Cary Clark2ade9972017-11-02 17:49:34 -04003043#SeeAlso flush() SkSurface::prepareForExternalIO GrContext::abandonContext
Cary Clark8032b982017-07-28 11:04:54 -04003044
Herb Derbyefe39bc2018-05-01 17:06:20 -04003045#NoExample
Cary Clark8032b982017-07-28 11:04:54 -04003046##
3047
3048##
3049
3050# ------------------------------------------------------------------------------
3051
3052#Method void drawPaint(const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05003053#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05003054#Line # fills Clip with Paint ##
Cary Clark80247e52018-07-11 16:18:41 -04003055Fills Clip with Paint paint. Paint components Mask_Filter, Shader,
Cary Clarkbad5ad72017-08-03 17:14:08 -04003056Color_Filter, Image_Filter, and Blend_Mode affect drawing;
3057Path_Effect in paint is ignored.
Cary Clark8032b982017-07-28 11:04:54 -04003058
3059# can Path_Effect in paint ever alter drawPaint?
3060
Cary Clarkbad5ad72017-08-03 17:14:08 -04003061#Param paint graphics state used to fill Canvas ##
Cary Clark8032b982017-07-28 11:04:54 -04003062
3063#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003064void draw(SkCanvas* canvas) {
3065 SkColor colors[] = { SK_ColorRED, SK_ColorGREEN, SK_ColorBLUE };
3066 SkScalar pos[] = { 0, SK_Scalar1/2, SK_Scalar1 };
3067 SkPaint paint;
3068 paint.setShader(SkGradientShader::MakeSweep(256, 256, colors, pos, SK_ARRAY_COUNT(colors)));
3069 canvas->drawPaint(paint);
Cary Clark8032b982017-07-28 11:04:54 -04003070}
3071##
3072
Cary Clark2ade9972017-11-02 17:49:34 -04003073#SeeAlso clear drawColor SkBitmap::erase
Cary Clark8032b982017-07-28 11:04:54 -04003074
3075##
3076
3077# ------------------------------------------------------------------------------
3078
3079#Enum PointMode
Cary Clark08895c42018-02-01 09:37:32 -05003080#Line # sets drawPoints options ##
Cary Clark8032b982017-07-28 11:04:54 -04003081
3082#Code
Cary Clark61313f32018-10-08 14:57:48 -04003083#Populate
Cary Clark8032b982017-07-28 11:04:54 -04003084##
3085
3086Selects if an array of points are drawn as discrete points, as lines, or as
3087an open polygon.
3088
3089#Const kPoints_PointMode 0
Cary Clark682c58d2018-05-16 07:07:07 -04003090#Line # draw each point separately ##
Cary Clark8032b982017-07-28 11:04:54 -04003091##
3092
3093#Const kLines_PointMode 1
Cary Clark682c58d2018-05-16 07:07:07 -04003094#Line # draw each pair of points as a line segment ##
Cary Clark8032b982017-07-28 11:04:54 -04003095##
3096
3097#Const kPolygon_PointMode 2
Cary Clark682c58d2018-05-16 07:07:07 -04003098#Line # draw the array of points as a open polygon ##
Cary Clark8032b982017-07-28 11:04:54 -04003099##
3100
3101#Example
Herb Derbyefe39bc2018-05-01 17:06:20 -04003102 #Description
Cary Clark8032b982017-07-28 11:04:54 -04003103 The upper left corner shows three squares when drawn as points.
3104 The upper right corner shows one line; when drawn as lines, two points are required per line.
3105 The lower right corner shows two lines; when draw as polygon, no miter is drawn at the corner.
3106 The lower left corner shows two lines with a miter when path contains polygon.
3107 ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003108void draw(SkCanvas* canvas) {
3109 SkPaint paint;
3110 paint.setStyle(SkPaint::kStroke_Style);
3111 paint.setStrokeWidth(10);
3112 SkPoint points[] = {{64, 32}, {96, 96}, {32, 96}};
3113 canvas->drawPoints(SkCanvas::kPoints_PointMode, 3, points, paint);
3114 canvas->translate(128, 0);
3115 canvas->drawPoints(SkCanvas::kLines_PointMode, 3, points, paint);
3116 canvas->translate(0, 128);
3117 canvas->drawPoints(SkCanvas::kPolygon_PointMode, 3, points, paint);
3118 SkPath path;
3119 path.addPoly(points, 3, false);
3120 canvas->translate(-128, 0);
3121 canvas->drawPath(path, paint);
Cary Clark8032b982017-07-28 11:04:54 -04003122}
3123##
3124
Cary Clark2ade9972017-11-02 17:49:34 -04003125#SeeAlso drawLine drawPoint drawPath
Cary Clark8032b982017-07-28 11:04:54 -04003126
3127##
3128
3129# ------------------------------------------------------------------------------
3130
3131#Method void drawPoints(PointMode mode, size_t count, const SkPoint pts[], const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05003132#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05003133#Line # draws array as points, lines, polygon ##
Cary Clark80247e52018-07-11 16:18:41 -04003134Draws pts using Clip, Matrix and Paint paint.
Cary Clarkbad5ad72017-08-03 17:14:08 -04003135count is the number of points; if count is less than one, has no effect.
Cary Clark8032b982017-07-28 11:04:54 -04003136mode may be one of: kPoints_PointMode, kLines_PointMode, or kPolygon_PointMode.
3137
Cary Clarkbad5ad72017-08-03 17:14:08 -04003138If mode is kPoints_PointMode, the shape of point drawn depends on paint
3139Paint_Stroke_Cap. If paint is set to SkPaint::kRound_Cap, each point draws a
3140circle of diameter Paint_Stroke_Width. If paint is set to SkPaint::kSquare_Cap
3141or SkPaint::kButt_Cap, each point draws a square of width and height
3142Paint_Stroke_Width.
Cary Clark8032b982017-07-28 11:04:54 -04003143
3144If mode is kLines_PointMode, each pair of points draws a line segment.
3145One line is drawn for every two points; each point is used once. If count is odd,
Herb Derbyefe39bc2018-05-01 17:06:20 -04003146the final point is ignored.
Cary Clark8032b982017-07-28 11:04:54 -04003147
3148If mode is kPolygon_PointMode, each adjacent pair of points draws a line segment.
3149count minus one lines are drawn; the first and last point are used once.
3150
3151Each line segment respects paint Paint_Stroke_Cap and Paint_Stroke_Width.
3152Paint_Style is ignored, as if were set to SkPaint::kStroke_Style.
3153
Cary Clarkbad5ad72017-08-03 17:14:08 -04003154Always draws each element one at a time; is not affected by
3155Paint_Stroke_Join, and unlike drawPath, does not create a mask from all points
Herb Derbyefe39bc2018-05-01 17:06:20 -04003156and lines before drawing.
Cary Clark8032b982017-07-28 11:04:54 -04003157
Cary Clarka523d2d2017-08-30 08:58:10 -04003158#Param mode whether pts draws points or lines ##
3159#Param count number of points in the array ##
3160#Param pts array of points to draw ##
3161#Param paint stroke, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003162
3163#Example
3164#Height 200
Herb Derbyefe39bc2018-05-01 17:06:20 -04003165 #Description
Cary Clark8032b982017-07-28 11:04:54 -04003166 #List
3167 # The first column draws points. ##
3168 # The second column draws points as lines. ##
3169 # The third column draws points as a polygon. ##
3170 # The fourth column draws points as a polygonal path. ##
3171 # The first row uses a round cap and round join. ##
3172 # The second row uses a square cap and a miter join. ##
3173 # The third row uses a butt cap and a bevel join. ##
3174 ##
3175 The transparent color makes multiple line draws visible;
3176 the path is drawn all at once.
3177 ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003178void draw(SkCanvas* canvas) {
3179 SkPaint paint;
3180 paint.setAntiAlias(true);
3181 paint.setStyle(SkPaint::kStroke_Style);
3182 paint.setStrokeWidth(10);
3183 paint.setColor(0x80349a45);
3184 const SkPoint points[] = {{32, 16}, {48, 48}, {16, 32}};
Herb Derbyefe39bc2018-05-01 17:06:20 -04003185 const SkPaint::Join join[] = { SkPaint::kRound_Join,
Cary Clarkbad5ad72017-08-03 17:14:08 -04003186 SkPaint::kMiter_Join,
3187 SkPaint::kBevel_Join };
3188 int joinIndex = 0;
3189 SkPath path;
3190 path.addPoly(points, 3, false);
3191 for (const auto cap : { SkPaint::kRound_Cap, SkPaint::kSquare_Cap, SkPaint::kButt_Cap } ) {
3192 paint.setStrokeCap(cap);
3193 paint.setStrokeJoin(join[joinIndex++]);
3194 for (const auto mode : { SkCanvas::kPoints_PointMode,
3195 SkCanvas::kLines_PointMode,
3196 SkCanvas::kPolygon_PointMode } ) {
3197 canvas->drawPoints(mode, 3, points, paint);
3198 canvas->translate(64, 0);
3199 }
3200 canvas->drawPath(path, paint);
3201 canvas->translate(-192, 64);
3202 }
Cary Clark8032b982017-07-28 11:04:54 -04003203}
3204##
3205
Cary Clark2ade9972017-11-02 17:49:34 -04003206#SeeAlso drawLine drawPoint drawPath
Cary Clark8032b982017-07-28 11:04:54 -04003207
3208##
3209
3210# ------------------------------------------------------------------------------
3211
3212#Method void drawPoint(SkScalar x, SkScalar y, const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05003213#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05003214#Line # draws point at (x, y) position ##
Cary Clark80247e52018-07-11 16:18:41 -04003215Draws point at (x, y) using Clip, Matrix and Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04003216
3217The shape of point drawn depends on paint Paint_Stroke_Cap.
Cary Clarkbad5ad72017-08-03 17:14:08 -04003218If paint is set to SkPaint::kRound_Cap, draw a circle of diameter
Herb Derbyefe39bc2018-05-01 17:06:20 -04003219Paint_Stroke_Width. If paint is set to SkPaint::kSquare_Cap or SkPaint::kButt_Cap,
Cary Clark8032b982017-07-28 11:04:54 -04003220draw a square of width and height Paint_Stroke_Width.
3221Paint_Style is ignored, as if were set to SkPaint::kStroke_Style.
3222
Cary Clarkbad5ad72017-08-03 17:14:08 -04003223#Param x left edge of circle or square ##
3224#Param y top edge of circle or square ##
3225#Param paint stroke, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003226
3227#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003228void draw(SkCanvas* canvas) {
3229 SkPaint paint;
3230 paint.setAntiAlias(true);
3231 paint.setColor(0x80349a45);
3232 paint.setStyle(SkPaint::kStroke_Style);
3233 paint.setStrokeWidth(100);
3234 paint.setStrokeCap(SkPaint::kRound_Cap);
3235 canvas->scale(1, 1.2f);
3236 canvas->drawPoint(64, 96, paint);
3237 canvas->scale(.6f, .8f);
3238 paint.setColor(SK_ColorWHITE);
3239 canvas->drawPoint(106, 120, paint);
Cary Clark8032b982017-07-28 11:04:54 -04003240}
3241##
3242
Cary Clark2ade9972017-11-02 17:49:34 -04003243#SeeAlso drawPoints drawCircle drawRect drawLine drawPath
Cary Clark8032b982017-07-28 11:04:54 -04003244
3245##
3246
Cary Clarkbad5ad72017-08-03 17:14:08 -04003247#Method void drawPoint(SkPoint p, const SkPaint& paint)
3248
Cary Clark80247e52018-07-11 16:18:41 -04003249Draws point p using Clip, Matrix and Paint paint.
Cary Clarkbad5ad72017-08-03 17:14:08 -04003250
3251The shape of point drawn depends on paint Paint_Stroke_Cap.
3252If paint is set to SkPaint::kRound_Cap, draw a circle of diameter
Herb Derbyefe39bc2018-05-01 17:06:20 -04003253Paint_Stroke_Width. If paint is set to SkPaint::kSquare_Cap or SkPaint::kButt_Cap,
Cary Clarkbad5ad72017-08-03 17:14:08 -04003254draw a square of width and height Paint_Stroke_Width.
3255Paint_Style is ignored, as if were set to SkPaint::kStroke_Style.
3256
3257#Param p top-left edge of circle or square ##
3258#Param paint stroke, blend, color, and so on, used to draw ##
3259
3260#Example
3261void draw(SkCanvas* canvas) {
3262 SkPaint paint;
3263 paint.setAntiAlias(true);
3264 paint.setColor(0x80349a45);
3265 paint.setStyle(SkPaint::kStroke_Style);
3266 paint.setStrokeWidth(100);
3267 paint.setStrokeCap(SkPaint::kSquare_Cap);
3268 canvas->scale(1, 1.2f);
3269 canvas->drawPoint({64, 96}, paint);
3270 canvas->scale(.6f, .8f);
3271 paint.setColor(SK_ColorWHITE);
3272 canvas->drawPoint(106, 120, paint);
3273}
3274##
3275
Cary Clark2ade9972017-11-02 17:49:34 -04003276#SeeAlso drawPoints drawCircle drawRect drawLine drawPath
Cary Clarkbad5ad72017-08-03 17:14:08 -04003277
3278##
3279
Cary Clark8032b982017-07-28 11:04:54 -04003280# ------------------------------------------------------------------------------
3281
3282#Method void drawLine(SkScalar x0, SkScalar y0, SkScalar x1, SkScalar y1, const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05003283#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05003284#Line # draws line segment between two points ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003285Draws line segment from (x0, y0) to (x1, y1) using Clip, Matrix, and Paint paint.
3286In paint: Paint_Stroke_Width describes the line thickness;
3287Paint_Stroke_Cap draws the end rounded or square;
Cary Clark8032b982017-07-28 11:04:54 -04003288Paint_Style is ignored, as if were set to SkPaint::kStroke_Style.
3289
Cary Clarkbad5ad72017-08-03 17:14:08 -04003290#Param x0 start of line segment on x-axis ##
3291#Param y0 start of line segment on y-axis ##
3292#Param x1 end of line segment on x-axis ##
3293#Param y1 end of line segment on y-axis ##
3294#Param paint stroke, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003295
3296#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003297 SkPaint paint;
3298 paint.setAntiAlias(true);
3299 paint.setColor(0xFF9a67be);
3300 paint.setStrokeWidth(20);
3301 canvas->skew(1, 0);
3302 canvas->drawLine(32, 96, 32, 160, paint);
3303 canvas->skew(-2, 0);
3304 canvas->drawLine(288, 96, 288, 160, paint);
3305##
3306
Cary Clark2ade9972017-11-02 17:49:34 -04003307#SeeAlso drawPoint drawCircle drawRect drawPath
Cary Clarkbad5ad72017-08-03 17:14:08 -04003308
3309##
3310
3311#Method void drawLine(SkPoint p0, SkPoint p1, const SkPaint& paint)
3312
3313Draws line segment from p0 to p1 using Clip, Matrix, and Paint paint.
3314In paint: Paint_Stroke_Width describes the line thickness;
3315Paint_Stroke_Cap draws the end rounded or square;
3316Paint_Style is ignored, as if were set to SkPaint::kStroke_Style.
3317
3318#Param p0 start of line segment ##
3319#Param p1 end of line segment ##
3320#Param paint stroke, blend, color, and so on, used to draw ##
3321
3322#Example
3323 SkPaint paint;
3324 paint.setAntiAlias(true);
3325 paint.setColor(0xFF9a67be);
3326 paint.setStrokeWidth(20);
3327 canvas->skew(1, 0);
3328 canvas->drawLine({32, 96}, {32, 160}, paint);
3329 canvas->skew(-2, 0);
3330 canvas->drawLine({288, 96}, {288, 160}, paint);
Cary Clark8032b982017-07-28 11:04:54 -04003331##
3332
Cary Clark2ade9972017-11-02 17:49:34 -04003333#SeeAlso drawPoint drawCircle drawRect drawPath
Cary Clark8032b982017-07-28 11:04:54 -04003334
3335##
3336
3337# ------------------------------------------------------------------------------
3338
3339#Method void drawRect(const SkRect& rect, const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05003340#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05003341#Line # draws Rect using Clip, Matrix, and Paint ##
Cary Clark80247e52018-07-11 16:18:41 -04003342Draws Rect rect using Clip, Matrix, and Paint paint.
Herb Derbyefe39bc2018-05-01 17:06:20 -04003343In paint: Paint_Style determines if rectangle is stroked or filled;
Cary Clark8032b982017-07-28 11:04:54 -04003344if stroked, Paint_Stroke_Width describes the line thickness, and
3345Paint_Stroke_Join draws the corners rounded or square.
3346
Cary Clarkbc5697d2017-10-04 14:31:33 -04003347#Param rect rectangle to draw ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003348#Param paint stroke or fill, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003349
3350#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003351void draw(SkCanvas* canvas) {
3352 SkPoint rectPts[] = { {64, 48}, {192, 160} };
3353 SkPaint paint;
3354 paint.setAntiAlias(true);
3355 paint.setStyle(SkPaint::kStroke_Style);
3356 paint.setStrokeWidth(20);
3357 paint.setStrokeJoin(SkPaint::kRound_Join);
3358 SkMatrix rotator;
3359 rotator.setRotate(30, 128, 128);
3360 for (auto color : { SK_ColorRED, SK_ColorBLUE, SK_ColorYELLOW, SK_ColorMAGENTA } ) {
3361 paint.setColor(color);
3362 SkRect rect;
3363 rect.set(rectPts[0], rectPts[1]);
3364 canvas->drawRect(rect, paint);
3365 rotator.mapPoints(rectPts, 2);
3366 }
Cary Clark8032b982017-07-28 11:04:54 -04003367}
3368##
3369
Herb Derbyefe39bc2018-05-01 17:06:20 -04003370#SeeAlso drawIRect drawRRect drawRoundRect drawRegion drawPath drawLine
Cary Clark8032b982017-07-28 11:04:54 -04003371
3372##
3373
3374# ------------------------------------------------------------------------------
3375
Herb Derbyefe39bc2018-05-01 17:06:20 -04003376#Method void drawIRect(const SkIRect& rect, const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05003377#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05003378#Line # draws IRect using Clip, Matrix, and Paint ##
Cary Clark80247e52018-07-11 16:18:41 -04003379Draws IRect rect using Clip, Matrix, and Paint paint.
Herb Derbyefe39bc2018-05-01 17:06:20 -04003380In paint: Paint_Style determines if rectangle is stroked or filled;
Cary Clark8032b982017-07-28 11:04:54 -04003381if stroked, Paint_Stroke_Width describes the line thickness, and
3382Paint_Stroke_Join draws the corners rounded or square.
3383
Cary Clarkbc5697d2017-10-04 14:31:33 -04003384#Param rect rectangle to draw ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003385#Param paint stroke or fill, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003386
3387#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003388 SkIRect rect = { 64, 48, 192, 160 };
3389 SkPaint paint;
3390 paint.setAntiAlias(true);
3391 paint.setStyle(SkPaint::kStroke_Style);
3392 paint.setStrokeWidth(20);
3393 paint.setStrokeJoin(SkPaint::kRound_Join);
3394 for (auto color : { SK_ColorRED, SK_ColorBLUE, SK_ColorYELLOW, SK_ColorMAGENTA } ) {
3395 paint.setColor(color);
3396 canvas->drawIRect(rect, paint);
3397 canvas->rotate(30, 128, 128);
3398 }
Cary Clark8032b982017-07-28 11:04:54 -04003399##
3400
Cary Clark2ade9972017-11-02 17:49:34 -04003401#SeeAlso drawRect drawRRect drawRoundRect drawRegion drawPath drawLine
Cary Clark8032b982017-07-28 11:04:54 -04003402
3403##
3404
3405# ------------------------------------------------------------------------------
3406
3407#Method void drawRegion(const SkRegion& region, const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05003408#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05003409#Line # draws Region using Clip, Matrix, and Paint ##
Cary Clark80247e52018-07-11 16:18:41 -04003410Draws Region region using Clip, Matrix, and Paint paint.
Herb Derbyefe39bc2018-05-01 17:06:20 -04003411In paint: Paint_Style determines if rectangle is stroked or filled;
Cary Clark8032b982017-07-28 11:04:54 -04003412if stroked, Paint_Stroke_Width describes the line thickness, and
3413Paint_Stroke_Join draws the corners rounded or square.
3414
Cary Clarkbc5697d2017-10-04 14:31:33 -04003415#Param region region to draw ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003416#Param paint Paint stroke or fill, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003417
3418#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003419void draw(SkCanvas* canvas) {
3420 SkRegion region;
3421 region.op( 10, 10, 50, 50, SkRegion::kUnion_Op);
3422 region.op( 10, 50, 90, 90, SkRegion::kUnion_Op);
3423 SkPaint paint;
3424 paint.setAntiAlias(true);
3425 paint.setStyle(SkPaint::kStroke_Style);
3426 paint.setStrokeWidth(20);
3427 paint.setStrokeJoin(SkPaint::kRound_Join);
3428 canvas->drawRegion(region, paint);
Cary Clark8032b982017-07-28 11:04:54 -04003429}
3430##
3431
Cary Clark2ade9972017-11-02 17:49:34 -04003432#SeeAlso drawRect drawIRect drawPath
Cary Clark8032b982017-07-28 11:04:54 -04003433
3434##
3435
3436# ------------------------------------------------------------------------------
3437
3438#Method void drawOval(const SkRect& oval, const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05003439#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05003440#Line # draws Oval using Clip, Matrix, and Paint ##
Cary Clark80247e52018-07-11 16:18:41 -04003441Draws Oval oval using Clip, Matrix, and Paint.
Herb Derbyefe39bc2018-05-01 17:06:20 -04003442In paint: Paint_Style determines if Oval is stroked or filled;
Cary Clark8032b982017-07-28 11:04:54 -04003443if stroked, Paint_Stroke_Width describes the line thickness.
3444
Cary Clarkbad5ad72017-08-03 17:14:08 -04003445#Param oval Rect bounds of Oval ##
3446#Param paint Paint stroke or fill, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003447
3448#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003449void draw(SkCanvas* canvas) {
3450 canvas->clear(0xFF3f5f9f);
3451 SkColor kColor1 = SkColorSetARGB(0xff, 0xff, 0x7f, 0);
3452 SkColor g1Colors[] = { kColor1, SkColorSetA(kColor1, 0x20) };
3453 SkPoint g1Points[] = { { 0, 0 }, { 0, 100 } };
3454 SkScalar pos[] = { 0.2f, 1.0f };
3455 SkRect bounds = SkRect::MakeWH(80, 70);
3456 SkPaint paint;
3457 paint.setAntiAlias(true);
3458 paint.setShader(SkGradientShader::MakeLinear(g1Points, g1Colors, pos, SK_ARRAY_COUNT(g1Colors),
3459 SkShader::kClamp_TileMode));
3460 canvas->drawOval(bounds , paint);
Cary Clark8032b982017-07-28 11:04:54 -04003461}
3462##
3463
Cary Clark2ade9972017-11-02 17:49:34 -04003464#SeeAlso drawCircle drawPoint drawPath drawRRect drawRoundRect
Cary Clark8032b982017-07-28 11:04:54 -04003465
3466##
3467
3468# ------------------------------------------------------------------------------
3469
3470#Method void drawRRect(const SkRRect& rrect, const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05003471#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05003472#Line # draws Round_Rect using Clip, Matrix, and Paint ##
Cary Clark80247e52018-07-11 16:18:41 -04003473Draws Round_Rect rrect using Clip, Matrix, and Paint paint.
Herb Derbyefe39bc2018-05-01 17:06:20 -04003474In paint: Paint_Style determines if rrect is stroked or filled;
Cary Clark8032b982017-07-28 11:04:54 -04003475if stroked, Paint_Stroke_Width describes the line thickness.
3476
Cary Clarkbad5ad72017-08-03 17:14:08 -04003477rrect may represent a rectangle, circle, oval, uniformly rounded rectangle, or
3478may have any combination of positive non-square radii for the four corners.
Cary Clark8032b982017-07-28 11:04:54 -04003479
Cary Clarkbad5ad72017-08-03 17:14:08 -04003480#Param rrect Round_Rect with up to eight corner radii to draw ##
3481#Param paint Paint stroke or fill, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003482
3483#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003484void draw(SkCanvas* canvas) {
3485 SkPaint paint;
3486 paint.setAntiAlias(true);
3487 SkRect outer = {30, 40, 210, 220};
3488 SkRect radii = {30, 50, 70, 90 };
3489 SkRRect rRect;
3490 rRect.setNinePatch(outer, radii.fLeft, radii.fTop, radii.fRight, radii.fBottom);
3491 canvas->drawRRect(rRect, paint);
3492 paint.setColor(SK_ColorWHITE);
3493 canvas->drawLine(outer.fLeft + radii.fLeft, outer.fTop,
3494 outer.fLeft + radii.fLeft, outer.fBottom, paint);
Herb Derbyefe39bc2018-05-01 17:06:20 -04003495 canvas->drawLine(outer.fRight - radii.fRight, outer.fTop,
Cary Clarkbad5ad72017-08-03 17:14:08 -04003496 outer.fRight - radii.fRight, outer.fBottom, paint);
Herb Derbyefe39bc2018-05-01 17:06:20 -04003497 canvas->drawLine(outer.fLeft, outer.fTop + radii.fTop,
Cary Clarkbad5ad72017-08-03 17:14:08 -04003498 outer.fRight, outer.fTop + radii.fTop, paint);
Herb Derbyefe39bc2018-05-01 17:06:20 -04003499 canvas->drawLine(outer.fLeft, outer.fBottom - radii.fBottom,
Cary Clarkbad5ad72017-08-03 17:14:08 -04003500 outer.fRight, outer.fBottom - radii.fBottom, paint);
3501}
Cary Clark8032b982017-07-28 11:04:54 -04003502##
3503
Cary Clark2ade9972017-11-02 17:49:34 -04003504#SeeAlso drawRect drawRoundRect drawDRRect drawCircle drawOval drawPath
Cary Clark8032b982017-07-28 11:04:54 -04003505
3506##
3507
3508# ------------------------------------------------------------------------------
3509
3510#Method void drawDRRect(const SkRRect& outer, const SkRRect& inner, const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05003511#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05003512#Line # draws double Round_Rect stroked or filled ##
Cary Clark80247e52018-07-11 16:18:41 -04003513Draws Round_Rect outer and inner
Herb Derbyefe39bc2018-05-01 17:06:20 -04003514using Clip, Matrix, and Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04003515outer must contain inner or the drawing is undefined.
Herb Derbyefe39bc2018-05-01 17:06:20 -04003516In paint: Paint_Style determines if Round_Rect is stroked or filled;
Cary Clark8032b982017-07-28 11:04:54 -04003517if stroked, Paint_Stroke_Width describes the line thickness.
Cary Clarkbad5ad72017-08-03 17:14:08 -04003518If stroked and Round_Rect corner has zero length radii, Paint_Stroke_Join can
Herb Derbyefe39bc2018-05-01 17:06:20 -04003519draw corners rounded or square.
Cary Clark8032b982017-07-28 11:04:54 -04003520
Cary Clarkbad5ad72017-08-03 17:14:08 -04003521GPU-backed platforms optimize drawing when both outer and inner are
Cary Clark8032b982017-07-28 11:04:54 -04003522concave and outer contains inner. These platforms may not be able to draw
Herb Derbyefe39bc2018-05-01 17:06:20 -04003523Path built with identical data as fast.
Cary Clark8032b982017-07-28 11:04:54 -04003524
Cary Clarkbad5ad72017-08-03 17:14:08 -04003525#Param outer Round_Rect outer bounds to draw ##
3526#Param inner Round_Rect inner bounds to draw ##
3527#Param paint Paint stroke or fill, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003528
3529#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003530void draw(SkCanvas* canvas) {
3531 SkRRect outer = SkRRect::MakeRect({20, 40, 210, 200});
3532 SkRRect inner = SkRRect::MakeOval({60, 70, 170, 160});
3533 SkPaint paint;
3534 canvas->drawDRRect(outer, inner, paint);
Cary Clark8032b982017-07-28 11:04:54 -04003535}
3536##
3537
3538#Example
3539#Description
3540 Outer Rect has no corner radii, but stroke join is rounded.
3541 Inner Round_Rect has corner radii; outset stroke increases radii of corners.
3542 Stroke join does not affect inner Round_Rect since it has no sharp corners.
3543##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003544void draw(SkCanvas* canvas) {
3545 SkRRect outer = SkRRect::MakeRect({20, 40, 210, 200});
3546 SkRRect inner = SkRRect::MakeRectXY({60, 70, 170, 160}, 10, 10);
3547 SkPaint paint;
3548 paint.setAntiAlias(true);
3549 paint.setStyle(SkPaint::kStroke_Style);
3550 paint.setStrokeWidth(20);
3551 paint.setStrokeJoin(SkPaint::kRound_Join);
3552 canvas->drawDRRect(outer, inner, paint);
3553 paint.setStrokeWidth(1);
3554 paint.setColor(SK_ColorWHITE);
3555 canvas->drawDRRect(outer, inner, paint);
Cary Clark8032b982017-07-28 11:04:54 -04003556}
3557##
3558
Cary Clark2ade9972017-11-02 17:49:34 -04003559#SeeAlso drawRect drawRoundRect drawRRect drawCircle drawOval drawPath
Cary Clark8032b982017-07-28 11:04:54 -04003560
3561##
3562
3563# ------------------------------------------------------------------------------
3564
3565#Method void drawCircle(SkScalar cx, SkScalar cy, SkScalar radius, const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05003566#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05003567#Line # draws Circle using Clip, Matrix, and Paint ##
Cary Clark80247e52018-07-11 16:18:41 -04003568Draws Circle at (cx, cy) with radius using Clip, Matrix, and Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04003569If radius is zero or less, nothing is drawn.
Herb Derbyefe39bc2018-05-01 17:06:20 -04003570In paint: Paint_Style determines if Circle is stroked or filled;
Cary Clark8032b982017-07-28 11:04:54 -04003571if stroked, Paint_Stroke_Width describes the line thickness.
3572
Cary Clarkbad5ad72017-08-03 17:14:08 -04003573#Param cx Circle center on the x-axis ##
3574#Param cy Circle center on the y-axis ##
3575#Param radius half the diameter of Circle ##
3576#Param paint Paint stroke or fill, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003577
3578#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003579 void draw(SkCanvas* canvas) {
3580 SkPaint paint;
3581 paint.setAntiAlias(true);
3582 canvas->drawCircle(128, 128, 90, paint);
3583 paint.setColor(SK_ColorWHITE);
3584 canvas->drawCircle(86, 86, 20, paint);
3585 canvas->drawCircle(160, 76, 20, paint);
3586 canvas->drawCircle(140, 150, 35, paint);
3587 }
3588##
3589
Cary Clark2ade9972017-11-02 17:49:34 -04003590#SeeAlso drawOval drawRRect drawRoundRect drawPath drawArc drawPoint drawLine
Cary Clarkbad5ad72017-08-03 17:14:08 -04003591
3592##
3593
3594#Method void drawCircle(SkPoint center, SkScalar radius, const SkPaint& paint)
3595
Cary Clark80247e52018-07-11 16:18:41 -04003596Draws Circle at center with radius using Clip, Matrix, and Paint paint.
Cary Clarkbad5ad72017-08-03 17:14:08 -04003597If radius is zero or less, nothing is drawn.
Herb Derbyefe39bc2018-05-01 17:06:20 -04003598In paint: Paint_Style determines if Circle is stroked or filled;
Cary Clarkbad5ad72017-08-03 17:14:08 -04003599if stroked, Paint_Stroke_Width describes the line thickness.
3600
3601#Param center Circle center ##
3602#Param radius half the diameter of Circle ##
3603#Param paint Paint stroke or fill, blend, color, and so on, used to draw ##
3604
3605#Example
3606 void draw(SkCanvas* canvas) {
3607 SkPaint paint;
3608 paint.setAntiAlias(true);
3609 canvas->drawCircle(128, 128, 90, paint);
3610 paint.setColor(SK_ColorWHITE);
3611 canvas->drawCircle({86, 86}, 20, paint);
3612 canvas->drawCircle({160, 76}, 20, paint);
3613 canvas->drawCircle({140, 150}, 35, paint);
3614 }
Cary Clark8032b982017-07-28 11:04:54 -04003615##
3616
Cary Clark2ade9972017-11-02 17:49:34 -04003617#SeeAlso drawOval drawRRect drawRoundRect drawPath drawArc drawPoint drawLine
Cary Clark8032b982017-07-28 11:04:54 -04003618
3619##
3620
3621# ------------------------------------------------------------------------------
3622
3623#Method void drawArc(const SkRect& oval, SkScalar startAngle, SkScalar sweepAngle,
3624 bool useCenter, const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05003625#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05003626#Line # draws Arc using Clip, Matrix, and Paint ##
Cary Clark8032b982017-07-28 11:04:54 -04003627
Cary Clark80247e52018-07-11 16:18:41 -04003628Draws Arc using Clip, Matrix, and Paint paint.
Cary Clarkbad5ad72017-08-03 17:14:08 -04003629
Cary Clark8032b982017-07-28 11:04:54 -04003630Arc is part of Oval bounded by oval, sweeping from startAngle to startAngle plus
3631sweepAngle. startAngle and sweepAngle are in degrees.
Cary Clarkbad5ad72017-08-03 17:14:08 -04003632
Cary Clark8032b982017-07-28 11:04:54 -04003633startAngle of zero places start point at the right middle edge of oval.
3634A positive sweepAngle places Arc end point clockwise from start point;
3635a negative sweepAngle places Arc end point counterclockwise from start point.
3636sweepAngle may exceed 360 degrees, a full circle.
3637If useCenter is true, draw a wedge that includes lines from oval
3638center to Arc end points. If useCenter is false, draw Arc between end points.
3639
3640If Rect oval is empty or sweepAngle is zero, nothing is drawn.
3641
Cary Clarkbad5ad72017-08-03 17:14:08 -04003642#Param oval Rect bounds of Oval containing Arc to draw ##
3643#Param startAngle angle in degrees where Arc begins ##
3644#Param sweepAngle sweep angle in degrees; positive is clockwise ##
3645#Param useCenter if true, include the center of the oval ##
3646#Param paint Paint stroke or fill, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003647
3648#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04003649 void draw(SkCanvas* canvas) {
3650 SkPaint paint;
3651 paint.setAntiAlias(true);
3652 SkRect oval = { 4, 4, 60, 60};
3653 for (auto useCenter : { false, true } ) {
3654 for (auto style : { SkPaint::kFill_Style, SkPaint::kStroke_Style } ) {
3655 paint.setStyle(style);
3656 for (auto degrees : { 45, 90, 180, 360} ) {
3657 canvas->drawArc(oval, 0, degrees , useCenter, paint);
3658 canvas->translate(64, 0);
3659 }
3660 canvas->translate(-256, 64);
3661 }
3662 }
Cary Clark8032b982017-07-28 11:04:54 -04003663 }
3664##
3665
3666#Example
3667#Height 64
Cary Clarkbad5ad72017-08-03 17:14:08 -04003668 void draw(SkCanvas* canvas) {
3669 SkPaint paint;
3670 paint.setAntiAlias(true);
3671 paint.setStyle(SkPaint::kStroke_Style);
3672 paint.setStrokeWidth(4);
3673 SkRect oval = { 4, 4, 60, 60};
3674 float intervals[] = { 5, 5 };
3675 paint.setPathEffect(SkDashPathEffect::Make(intervals, 2, 2.5f));
3676 for (auto degrees : { 270, 360, 540, 720 } ) {
3677 canvas->drawArc(oval, 0, degrees, false, paint);
3678 canvas->translate(64, 0);
3679 }
Cary Clark8032b982017-07-28 11:04:54 -04003680 }
3681##
3682
Cary Clark2ade9972017-11-02 17:49:34 -04003683#SeeAlso SkPath::arcTo drawCircle drawOval drawPath
Cary Clark8032b982017-07-28 11:04:54 -04003684
3685##
3686
3687# ------------------------------------------------------------------------------
3688
3689#Method void drawRoundRect(const SkRect& rect, SkScalar rx, SkScalar ry, const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05003690#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05003691#Line # draws Round_Rect using Clip, Matrix, and Paint ##
Cary Clark80247e52018-07-11 16:18:41 -04003692Draws Round_Rect bounded by Rect rect, with corner radii (rx, ry) using Clip,
Cary Clarkbad5ad72017-08-03 17:14:08 -04003693Matrix, and Paint paint.
3694
Herb Derbyefe39bc2018-05-01 17:06:20 -04003695In paint: Paint_Style determines if Round_Rect is stroked or filled;
Cary Clark8032b982017-07-28 11:04:54 -04003696if stroked, Paint_Stroke_Width describes the line thickness.
3697If rx or ry are less than zero, they are treated as if they are zero.
3698If rx plus ry exceeds rect width or rect height, radii are scaled down to fit.
Cary Clarkbad5ad72017-08-03 17:14:08 -04003699If rx and ry are zero, Round_Rect is drawn as Rect and if stroked is affected by
3700Paint_Stroke_Join.
Cary Clark8032b982017-07-28 11:04:54 -04003701
Cary Clarkbad5ad72017-08-03 17:14:08 -04003702#Param rect Rect bounds of Round_Rect to draw ##
Cary Clark5538c132018-06-14 12:28:14 -04003703#Param rx axis length on x-axis of oval describing rounded corners ##
3704#Param ry axis length on y-axis of oval describing rounded corners ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003705#Param paint stroke, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003706
3707#Example
3708#Description
3709 Top row has a zero radius a generates a rectangle.
3710 Second row radii sum to less than sides.
3711 Third row radii sum equals sides.
3712 Fourth row radii sum exceeds sides; radii are scaled to fit.
3713##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003714 void draw(SkCanvas* canvas) {
3715 SkVector radii[] = { {0, 20}, {10, 10}, {10, 20}, {10, 40} };
3716 SkPaint paint;
3717 paint.setStrokeWidth(15);
3718 paint.setStrokeJoin(SkPaint::kRound_Join);
3719 paint.setAntiAlias(true);
3720 for (auto style : { SkPaint::kStroke_Style, SkPaint::kFill_Style } ) {
3721 paint.setStyle(style );
3722 for (size_t i = 0; i < SK_ARRAY_COUNT(radii); ++i) {
3723 canvas->drawRoundRect({10, 10, 60, 40}, radii[i].fX, radii[i].fY, paint);
3724 canvas->translate(0, 60);
3725 }
3726 canvas->translate(80, -240);
3727 }
Cary Clark8032b982017-07-28 11:04:54 -04003728 }
3729##
3730
Cary Clark2ade9972017-11-02 17:49:34 -04003731#SeeAlso DrawRRect drawRect drawDRRect drawPath drawCircle drawOval drawPoint
Cary Clark8032b982017-07-28 11:04:54 -04003732
3733##
3734
3735# ------------------------------------------------------------------------------
3736
3737#Method void drawPath(const SkPath& path, const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05003738#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05003739#Line # draws Path using Clip, Matrix, and Paint ##
Cary Clark80247e52018-07-11 16:18:41 -04003740Draws Path path using Clip, Matrix, and Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04003741Path contains an array of Path_Contour, each of which may be open or closed.
3742
3743In paint: Paint_Style determines if Round_Rect is stroked or filled:
Cary Clarkbad5ad72017-08-03 17:14:08 -04003744if filled, Path_Fill_Type determines whether Path_Contour describes inside or
3745outside of fill; if stroked, Paint_Stroke_Width describes the line thickness,
3746Paint_Stroke_Cap describes line ends, and Paint_Stroke_Join describes how
3747corners are drawn.
Cary Clark8032b982017-07-28 11:04:54 -04003748
Cary Clarkbad5ad72017-08-03 17:14:08 -04003749#Param path Path to draw ##
3750#Param paint stroke, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04003751
3752#Example
3753#Description
3754 Top rows draw stroked path with combinations of joins and caps. The open contour
3755 is affected by caps; the closed contour is affected by joins.
Herb Derbyefe39bc2018-05-01 17:06:20 -04003756 Bottom row draws fill the same for open and closed contour.
Cary Clark8032b982017-07-28 11:04:54 -04003757 First bottom column shows winding fills overlap.
3758 Second bottom column shows even odd fills exclude overlap.
3759 Third bottom column shows inverse winding fills area outside both contours.
3760##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003761void draw(SkCanvas* canvas) {
3762 SkPath path;
3763 path.moveTo(20, 20);
3764 path.quadTo(60, 20, 60, 60);
3765 path.close();
3766 path.moveTo(60, 20);
3767 path.quadTo(60, 60, 20, 60);
3768 SkPaint paint;
3769 paint.setStrokeWidth(10);
3770 paint.setAntiAlias(true);
3771 paint.setStyle(SkPaint::kStroke_Style);
3772 for (auto join: { SkPaint::kBevel_Join, SkPaint::kRound_Join, SkPaint::kMiter_Join } ) {
3773 paint.setStrokeJoin(join);
3774 for (auto cap: { SkPaint::kButt_Cap, SkPaint::kSquare_Cap, SkPaint::kRound_Cap } ) {
3775 paint.setStrokeCap(cap);
3776 canvas->drawPath(path, paint);
3777 canvas->translate(80, 0);
3778 }
3779 canvas->translate(-240, 60);
3780 }
3781 paint.setStyle(SkPaint::kFill_Style);
Herb Derbyefe39bc2018-05-01 17:06:20 -04003782 for (auto fill : { SkPath::kWinding_FillType,
3783 SkPath::kEvenOdd_FillType,
Cary Clarkbad5ad72017-08-03 17:14:08 -04003784 SkPath::kInverseWinding_FillType } ) {
3785 path.setFillType(fill);
3786 canvas->save();
3787 canvas->clipRect({0, 10, 80, 70});
3788 canvas->drawPath(path, paint);
3789 canvas->restore();
3790 canvas->translate(80, 0);
3791 }
Cary Clark8032b982017-07-28 11:04:54 -04003792}
3793##
3794
Cary Clark2ade9972017-11-02 17:49:34 -04003795#SeeAlso SkPath drawLine drawArc drawRect drawPoints
Cary Clark8032b982017-07-28 11:04:54 -04003796
3797##
3798
3799# ------------------------------------------------------------------------------
Cary Clark08895c42018-02-01 09:37:32 -05003800#Subtopic Draw_Image
3801#Line # draws Image to Canvas ##
Cary Clark8032b982017-07-28 11:04:54 -04003802
Cary Clarkbad5ad72017-08-03 17:14:08 -04003803drawImage, drawImageRect, and drawImageNine can be called with a bare pointer or
3804a smart pointer as a convenience. The pairs of calls are otherwise identical.
Cary Clark8032b982017-07-28 11:04:54 -04003805
Cary Clark73fa9722017-08-29 17:36:51 -04003806#Method void drawImage(const SkImage* image, SkScalar left, SkScalar top, const SkPaint* paint = nullptr)
Cary Clarkab2621d2018-01-30 10:08:57 -05003807#In Draw_Image
Cary Clark78de7512018-02-07 07:27:09 -05003808#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05003809#Line # draws Image at (x, y) position ##
Cary Clark80247e52018-07-11 16:18:41 -04003810Draws Image image, with its top-left corner at (left, top),
Cary Clark8032b982017-07-28 11:04:54 -04003811using Clip, Matrix, and optional Paint paint.
3812
Cary Clarkbad5ad72017-08-03 17:14:08 -04003813If paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter, Blend_Mode,
3814and Draw_Looper. If image is kAlpha_8_SkColorType, apply Shader.
3815If paint contains Mask_Filter, generate mask from image bounds. If generated
3816mask extends beyond image bounds, replicate image edge colors, just as Shader
3817made from SkImage::makeShader with SkShader::kClamp_TileMode set replicates the
Herb Derbyefe39bc2018-05-01 17:06:20 -04003818image edge color when it samples outside of its bounds.
Cary Clark8032b982017-07-28 11:04:54 -04003819
Cary Clarkbad5ad72017-08-03 17:14:08 -04003820#Param image uncompressed rectangular map of pixels ##
3821#Param left left side of image ##
3822#Param top top side of image ##
3823#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
3824 and so on; or nullptr
3825##
Cary Clark8032b982017-07-28 11:04:54 -04003826
3827#Example
3828#Height 64
3829#Image 4
Cary Clarkbad5ad72017-08-03 17:14:08 -04003830void draw(SkCanvas* canvas) {
3831 // sk_sp<SkImage> image;
3832 SkImage* imagePtr = image.get();
3833 canvas->drawImage(imagePtr, 0, 0);
3834 SkPaint paint;
3835 canvas->drawImage(imagePtr, 80, 0, &paint);
3836 paint.setAlpha(0x80);
3837 canvas->drawImage(imagePtr, 160, 0, &paint);
Cary Clark8032b982017-07-28 11:04:54 -04003838}
3839##
3840
Cary Clark2ade9972017-11-02 17:49:34 -04003841#SeeAlso drawBitmap drawImageLattice drawImageNine drawImageRect SkPaint::setImageFilter
Cary Clark8032b982017-07-28 11:04:54 -04003842
3843##
3844
3845# ------------------------------------------------------------------------------
3846
3847#Method void drawImage(const sk_sp<SkImage>& image, SkScalar left, SkScalar top,
Herb Derbyefe39bc2018-05-01 17:06:20 -04003848 const SkPaint* paint = nullptr)
Cary Clark8032b982017-07-28 11:04:54 -04003849
Cary Clark80247e52018-07-11 16:18:41 -04003850Draws Image image, with its top-left corner at (left, top),
Cary Clark8032b982017-07-28 11:04:54 -04003851using Clip, Matrix, and optional Paint paint.
3852
Cary Clarkbad5ad72017-08-03 17:14:08 -04003853If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
3854Blend_Mode, and Draw_Looper. If image is kAlpha_8_SkColorType, apply Shader.
3855If paint contains Mask_Filter, generate mask from image bounds. If generated
3856mask extends beyond image bounds, replicate image edge colors, just as Shader
3857made from SkImage::makeShader with SkShader::kClamp_TileMode set replicates the
Herb Derbyefe39bc2018-05-01 17:06:20 -04003858image edge color when it samples outside of its bounds.
Cary Clark8032b982017-07-28 11:04:54 -04003859
Cary Clarkbad5ad72017-08-03 17:14:08 -04003860#Param image uncompressed rectangular map of pixels ##
3861#Param left left side of image ##
3862#Param top pop side of image ##
3863#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
3864 and so on; or nullptr
3865##
Cary Clark8032b982017-07-28 11:04:54 -04003866
3867#Example
3868#Height 64
3869#Image 4
Cary Clarkbad5ad72017-08-03 17:14:08 -04003870void draw(SkCanvas* canvas) {
3871 // sk_sp<SkImage> image;
3872 canvas->drawImage(image, 0, 0);
3873 SkPaint paint;
3874 canvas->drawImage(image, 80, 0, &paint);
3875 paint.setAlpha(0x80);
3876 canvas->drawImage(image, 160, 0, &paint);
Cary Clark8032b982017-07-28 11:04:54 -04003877}
3878##
3879
Cary Clark2ade9972017-11-02 17:49:34 -04003880#SeeAlso drawBitmap drawImageLattice drawImageNine drawImageRect SkPaint::setImageFilter
Cary Clark8032b982017-07-28 11:04:54 -04003881
3882##
3883
3884# ------------------------------------------------------------------------------
3885
3886#Enum SrcRectConstraint
Cary Clark08895c42018-02-01 09:37:32 -05003887#Line # sets drawImageRect options ##
Cary Clark8032b982017-07-28 11:04:54 -04003888
3889#Code
Cary Clark61313f32018-10-08 14:57:48 -04003890#Populate
Cary Clark8032b982017-07-28 11:04:54 -04003891##
3892
Cary Clarkce101242017-09-01 15:51:02 -04003893SrcRectConstraint controls the behavior at the edge of source Rect,
3894provided to drawImageRect, trading off speed for precision.
Cary Clark8032b982017-07-28 11:04:54 -04003895
Cary Clarkce101242017-09-01 15:51:02 -04003896Image_Filter in Paint may sample multiple pixels in the image. Source Rect
Cary Clarkbad5ad72017-08-03 17:14:08 -04003897restricts the bounds of pixels that may be read. Image_Filter may slow down if
Herb Derbyefe39bc2018-05-01 17:06:20 -04003898it cannot read outside the bounds, when sampling near the edge of source Rect.
Cary Clark8032b982017-07-28 11:04:54 -04003899SrcRectConstraint specifies whether an Image_Filter is allowed to read pixels
Cary Clarkce101242017-09-01 15:51:02 -04003900outside source Rect.
Cary Clark8032b982017-07-28 11:04:54 -04003901
Cary Clark682c58d2018-05-16 07:07:07 -04003902#Const kStrict_SrcRectConstraint 0
3903#Line # sample only inside bounds; slower ##
Cary Clarkce101242017-09-01 15:51:02 -04003904 Requires Image_Filter to respect source Rect,
Cary Clark8032b982017-07-28 11:04:54 -04003905 sampling only inside of its bounds, possibly with a performance penalty.
3906##
3907
Cary Clark682c58d2018-05-16 07:07:07 -04003908#Const kFast_SrcRectConstraint 1
3909#Line # sample outside bounds; faster ##
Cary Clarkce101242017-09-01 15:51:02 -04003910 Permits Image_Filter to sample outside of source Rect
Cary Clark8032b982017-07-28 11:04:54 -04003911 by half the width of Image_Filter, permitting it to run faster but with
3912 error at the image edges.
3913##
3914
3915#Example
3916#Height 64
3917#Description
3918 redBorder contains a black and white checkerboard bordered by red.
3919 redBorder is drawn scaled by 16 on the left.
Cary Clarkce101242017-09-01 15:51:02 -04003920 The middle and right bitmaps are filtered checkerboards.
Cary Clark8032b982017-07-28 11:04:54 -04003921 Drawing the checkerboard with kStrict_SrcRectConstraint shows only a blur of black and white.
3922 Drawing the checkerboard with kFast_SrcRectConstraint allows red to bleed in the corners.
3923##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003924void draw(SkCanvas* canvas) {
3925 SkBitmap redBorder;
3926 redBorder.allocPixels(SkImageInfo::MakeN32Premul(4, 4));
3927 SkCanvas checkRed(redBorder);
3928 checkRed.clear(SK_ColorRED);
3929 uint32_t checkers[][2] = { { SK_ColorBLACK, SK_ColorWHITE },
3930 { SK_ColorWHITE, SK_ColorBLACK } };
3931 checkRed.writePixels(
3932 SkImageInfo::MakeN32Premul(2, 2), (void*) checkers, sizeof(checkers[0]), 1, 1);
3933 canvas->scale(16, 16);
3934 canvas->drawBitmap(redBorder, 0, 0, nullptr);
3935 canvas->resetMatrix();
3936 sk_sp<SkImage> image = SkImage::MakeFromBitmap(redBorder);
3937 SkPaint lowPaint;
3938 lowPaint.setFilterQuality(kLow_SkFilterQuality);
3939 for (auto constraint : { SkCanvas::kStrict_SrcRectConstraint,
3940 SkCanvas::kFast_SrcRectConstraint } ) {
3941 canvas->translate(80, 0);
3942 canvas->drawImageRect(image.get(), SkRect::MakeLTRB(1, 1, 3, 3),
3943 SkRect::MakeLTRB(16, 16, 48, 48), &lowPaint, constraint);
3944 }
Cary Clark8032b982017-07-28 11:04:54 -04003945}
3946##
3947
Cary Clark2ade9972017-11-02 17:49:34 -04003948#SeeAlso drawImageRect drawImage SkPaint::setImageFilter
Cary Clark8032b982017-07-28 11:04:54 -04003949
3950##
3951
3952# ------------------------------------------------------------------------------
3953
3954#Method void drawImageRect(const SkImage* image, const SkRect& src, const SkRect& dst,
3955 const SkPaint* paint,
3956 SrcRectConstraint constraint = kStrict_SrcRectConstraint)
Cary Clarkab2621d2018-01-30 10:08:57 -05003957#In Draw_Image
Cary Clark78de7512018-02-07 07:27:09 -05003958#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05003959#Line # draws Image, source Rect to destination Rect ##
Cary Clark8032b982017-07-28 11:04:54 -04003960
Cary Clark80247e52018-07-11 16:18:41 -04003961Draws Rect src of Image image, scaled and translated to fill Rect dst.
Cary Clark8032b982017-07-28 11:04:54 -04003962Additionally transform draw using Clip, Matrix, and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04003963
Cary Clarkbad5ad72017-08-03 17:14:08 -04003964If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
3965Blend_Mode, and Draw_Looper. If image is kAlpha_8_SkColorType, apply Shader.
3966If paint contains Mask_Filter, generate mask from image bounds.
3967
3968If generated mask extends beyond image bounds, replicate image edge colors, just
3969as Shader made from SkImage::makeShader with SkShader::kClamp_TileMode set
Cary Clarkbc5697d2017-10-04 14:31:33 -04003970replicates the image edge color when it samples outside of its bounds.
Cary Clarkbad5ad72017-08-03 17:14:08 -04003971
3972constraint set to kStrict_SrcRectConstraint limits Paint Filter_Quality to
3973sample within src; set to kFast_SrcRectConstraint allows sampling outside to
3974improve performance.
3975
3976#Param image Image containing pixels, dimensions, and format ##
3977#Param src source Rect of image to draw from ##
3978#Param dst destination Rect of image to draw to ##
3979#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
3980 and so on; or nullptr
3981##
3982#Param constraint filter strictly within src or draw faster ##
Cary Clark8032b982017-07-28 11:04:54 -04003983
3984#Example
3985#Height 64
3986#Description
3987 The left bitmap draws with Paint default kNone_SkFilterQuality, and stays within
Cary Clarkbc5697d2017-10-04 14:31:33 -04003988 its bounds; there is no bleeding with kFast_SrcRectConstraint.
Cary Clark8032b982017-07-28 11:04:54 -04003989 the middle and right bitmaps draw with kLow_SkFilterQuality; with
3990 kStrict_SrcRectConstraint, the filter remains within the checkerboard, and
3991 with kFast_SrcRectConstraint red bleeds on the edges.
3992##
Cary Clarkbad5ad72017-08-03 17:14:08 -04003993void draw(SkCanvas* canvas) {
Herb Derbyefe39bc2018-05-01 17:06:20 -04003994 uint32_t pixels[][4] = {
Cary Clarkbad5ad72017-08-03 17:14:08 -04003995 { 0xFFFF0000, 0xFFFF0000, 0xFFFF0000, 0xFFFF0000 },
3996 { 0xFFFF0000, 0xFF000000, 0xFFFFFFFF, 0xFFFF0000 },
3997 { 0xFFFF0000, 0xFFFFFFFF, 0xFF000000, 0xFFFF0000 },
3998 { 0xFFFF0000, 0xFFFF0000, 0xFFFF0000, 0xFFFF0000 } };
3999 SkBitmap redBorder;
Herb Derbyefe39bc2018-05-01 17:06:20 -04004000 redBorder.installPixels(SkImageInfo::MakeN32Premul(4, 4),
Cary Clarkbad5ad72017-08-03 17:14:08 -04004001 (void*) pixels, sizeof(pixels[0]));
4002 sk_sp<SkImage> image = SkImage::MakeFromBitmap(redBorder);
4003 SkPaint lowPaint;
4004 for (auto constraint : {
4005 SkCanvas::kFast_SrcRectConstraint,
4006 SkCanvas::kStrict_SrcRectConstraint,
4007 SkCanvas::kFast_SrcRectConstraint } ) {
4008 canvas->drawImageRect(image.get(), SkRect::MakeLTRB(1, 1, 3, 3),
4009 SkRect::MakeLTRB(16, 16, 48, 48), &lowPaint, constraint);
4010 lowPaint.setFilterQuality(kLow_SkFilterQuality);
4011 canvas->translate(80, 0);
4012 }
4013}
Cary Clark8032b982017-07-28 11:04:54 -04004014##
4015
Cary Clark2ade9972017-11-02 17:49:34 -04004016#SeeAlso SrcRectConstraint drawImage drawImageLattice drawImageNine
Cary Clark8032b982017-07-28 11:04:54 -04004017
4018##
4019
4020# ------------------------------------------------------------------------------
4021
4022#Method void drawImageRect(const SkImage* image, const SkIRect& isrc, const SkRect& dst,
4023 const SkPaint* paint, SrcRectConstraint constraint = kStrict_SrcRectConstraint)
Cary Clarkab2621d2018-01-30 10:08:57 -05004024#In Draw_Image
Cary Clark78de7512018-02-07 07:27:09 -05004025#In Draw
Cary Clark8032b982017-07-28 11:04:54 -04004026
Cary Clark80247e52018-07-11 16:18:41 -04004027Draws IRect isrc of Image image, scaled and translated to fill Rect dst.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004028Note that isrc is on integer pixel boundaries; dst may include fractional
4029boundaries. Additionally transform draw using Clip, Matrix, and optional Paint
Herb Derbyefe39bc2018-05-01 17:06:20 -04004030paint.
Cary Clark8032b982017-07-28 11:04:54 -04004031
Cary Clarkbad5ad72017-08-03 17:14:08 -04004032If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4033Blend_Mode, and Draw_Looper. If image is kAlpha_8_SkColorType, apply Shader.
4034If paint contains Mask_Filter, generate mask from image bounds.
4035
4036If generated mask extends beyond image bounds, replicate image edge colors, just
4037as Shader made from SkImage::makeShader with SkShader::kClamp_TileMode set
Cary Clarkbc5697d2017-10-04 14:31:33 -04004038replicates the image edge color when it samples outside of its bounds.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004039
4040constraint set to kStrict_SrcRectConstraint limits Paint Filter_Quality to
Cary Clarkce101242017-09-01 15:51:02 -04004041sample within isrc; set to kFast_SrcRectConstraint allows sampling outside to
Cary Clarkbad5ad72017-08-03 17:14:08 -04004042improve performance.
4043
4044#Param image Image containing pixels, dimensions, and format ##
4045#Param isrc source IRect of image to draw from ##
4046#Param dst destination Rect of image to draw to ##
4047#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4048 and so on; or nullptr
4049##
Cary Clarkce101242017-09-01 15:51:02 -04004050#Param constraint filter strictly within isrc or draw faster ##
Cary Clark8032b982017-07-28 11:04:54 -04004051
4052#Example
4053#Image 4
Cary Clarkbad5ad72017-08-03 17:14:08 -04004054void draw(SkCanvas* canvas) {
4055 // sk_sp<SkImage> image;
4056 for (auto i : { 1, 2, 4, 8 } ) {
Herb Derbyefe39bc2018-05-01 17:06:20 -04004057 canvas->drawImageRect(image.get(), SkIRect::MakeLTRB(0, 0, 100, 100),
Cary Clarkbad5ad72017-08-03 17:14:08 -04004058 SkRect::MakeXYWH(i * 20, i * 20, i * 20, i * 20), nullptr);
4059 }
Cary Clark8032b982017-07-28 11:04:54 -04004060}
4061##
4062
Cary Clark2ade9972017-11-02 17:49:34 -04004063#SeeAlso SrcRectConstraint drawImage drawImageLattice drawImageNine
Cary Clark8032b982017-07-28 11:04:54 -04004064
4065##
4066
4067# ------------------------------------------------------------------------------
4068
4069#Method void drawImageRect(const SkImage* image, const SkRect& dst, const SkPaint* paint,
4070 SrcRectConstraint constraint = kStrict_SrcRectConstraint)
Cary Clarkab2621d2018-01-30 10:08:57 -05004071#In Draw_Image
Cary Clark78de7512018-02-07 07:27:09 -05004072#In Draw
Cary Clark8032b982017-07-28 11:04:54 -04004073
Cary Clark80247e52018-07-11 16:18:41 -04004074Draws Image image, scaled and translated to fill Rect dst, using Clip, Matrix,
Cary Clarkbad5ad72017-08-03 17:14:08 -04004075and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004076
Cary Clarkbad5ad72017-08-03 17:14:08 -04004077If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4078Blend_Mode, and Draw_Looper. If image is kAlpha_8_SkColorType, apply Shader.
4079If paint contains Mask_Filter, generate mask from image bounds.
4080
4081If generated mask extends beyond image bounds, replicate image edge colors, just
4082as Shader made from SkImage::makeShader with SkShader::kClamp_TileMode set
Cary Clarkbc5697d2017-10-04 14:31:33 -04004083replicates the image edge color when it samples outside of its bounds.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004084
4085constraint set to kStrict_SrcRectConstraint limits Paint Filter_Quality to
Cary Clarkce101242017-09-01 15:51:02 -04004086sample within image; set to kFast_SrcRectConstraint allows sampling outside to
Cary Clarkbad5ad72017-08-03 17:14:08 -04004087improve performance.
4088
4089#Param image Image containing pixels, dimensions, and format ##
4090#Param dst destination Rect of image to draw to ##
4091#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4092 and so on; or nullptr
4093##
Cary Clarkce101242017-09-01 15:51:02 -04004094#Param constraint filter strictly within image or draw faster ##
Cary Clark8032b982017-07-28 11:04:54 -04004095
4096#Example
4097#Image 4
Cary Clarkbad5ad72017-08-03 17:14:08 -04004098void draw(SkCanvas* canvas) {
4099 // sk_sp<SkImage> image;
4100 for (auto i : { 20, 40, 80, 160 } ) {
4101 canvas->drawImageRect(image.get(), SkRect::MakeXYWH(i, i, i, i), nullptr);
4102 }
Cary Clark8032b982017-07-28 11:04:54 -04004103}
4104##
4105
Cary Clark2ade9972017-11-02 17:49:34 -04004106#SeeAlso SrcRectConstraint drawImage drawImageLattice drawImageNine
Cary Clark8032b982017-07-28 11:04:54 -04004107
4108##
4109
4110# ------------------------------------------------------------------------------
4111
4112#Method void drawImageRect(const sk_sp<SkImage>& image, const SkRect& src, const SkRect& dst,
4113 const SkPaint* paint,
Herb Derbyefe39bc2018-05-01 17:06:20 -04004114 SrcRectConstraint constraint = kStrict_SrcRectConstraint)
Cary Clarkab2621d2018-01-30 10:08:57 -05004115#In Draw_Image
Cary Clark78de7512018-02-07 07:27:09 -05004116#In Draw
Cary Clark80247e52018-07-11 16:18:41 -04004117Draws Rect src of Image image, scaled and translated to fill Rect dst.
Cary Clark8032b982017-07-28 11:04:54 -04004118Additionally transform draw using Clip, Matrix, and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004119
Cary Clarkbad5ad72017-08-03 17:14:08 -04004120If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4121Blend_Mode, and Draw_Looper. If image is kAlpha_8_SkColorType, apply Shader.
4122If paint contains Mask_Filter, generate mask from image bounds.
4123
4124If generated mask extends beyond image bounds, replicate image edge colors, just
4125as Shader made from SkImage::makeShader with SkShader::kClamp_TileMode set
Cary Clarkbc5697d2017-10-04 14:31:33 -04004126replicates the image edge color when it samples outside of its bounds.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004127
4128constraint set to kStrict_SrcRectConstraint limits Paint Filter_Quality to
4129sample within src; set to kFast_SrcRectConstraint allows sampling outside to
4130improve performance.
4131
4132#Param image Image containing pixels, dimensions, and format ##
4133#Param src source Rect of image to draw from ##
4134#Param dst destination Rect of image to draw to ##
4135#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4136 and so on; or nullptr
4137##
4138#Param constraint filter strictly within src or draw faster ##
Cary Clark8032b982017-07-28 11:04:54 -04004139
4140#Example
4141#Height 64
4142#Description
4143 Canvas scales and translates; transformation from src to dst also scales.
4144 The two matrices are concatenated to create the final transformation.
4145##
Cary Clarkbad5ad72017-08-03 17:14:08 -04004146void draw(SkCanvas* canvas) {
4147 uint32_t pixels[][2] = { { SK_ColorBLACK, SK_ColorWHITE },
4148 { SK_ColorWHITE, SK_ColorBLACK } };
4149 SkBitmap bitmap;
Herb Derbyefe39bc2018-05-01 17:06:20 -04004150 bitmap.installPixels(SkImageInfo::MakeN32Premul(2, 2),
Cary Clarkbad5ad72017-08-03 17:14:08 -04004151 (void*) pixels, sizeof(pixels[0]));
4152 sk_sp<SkImage> image = SkImage::MakeFromBitmap(bitmap);
4153 SkPaint paint;
4154 canvas->scale(4, 4);
4155 for (auto alpha : { 50, 100, 150, 255 } ) {
4156 paint.setAlpha(alpha);
4157 canvas->drawImageRect(image, SkRect::MakeWH(2, 2), SkRect::MakeWH(8, 8), &paint);
4158 canvas->translate(8, 0);
4159 }
4160}
Cary Clark8032b982017-07-28 11:04:54 -04004161##
4162
Cary Clark2ade9972017-11-02 17:49:34 -04004163#SeeAlso SrcRectConstraint drawImage drawImageLattice drawImageNine
Cary Clark8032b982017-07-28 11:04:54 -04004164
4165##
4166
4167# ------------------------------------------------------------------------------
4168
4169#Method void drawImageRect(const sk_sp<SkImage>& image, const SkIRect& isrc, const SkRect& dst,
Herb Derbyefe39bc2018-05-01 17:06:20 -04004170 const SkPaint* paint, SrcRectConstraint constraint = kStrict_SrcRectConstraint)
Cary Clarkab2621d2018-01-30 10:08:57 -05004171#In Draw_Image
Cary Clark78de7512018-02-07 07:27:09 -05004172#In Draw
Cary Clark80247e52018-07-11 16:18:41 -04004173Draws IRect isrc of Image image, scaled and translated to fill Rect dst.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004174isrc is on integer pixel boundaries; dst may include fractional boundaries.
Cary Clark8032b982017-07-28 11:04:54 -04004175Additionally transform draw using Clip, Matrix, and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004176
Cary Clarkbad5ad72017-08-03 17:14:08 -04004177If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4178Blend_Mode, and Draw_Looper. If image is kAlpha_8_SkColorType, apply Shader.
4179If paint contains Mask_Filter, generate mask from image bounds.
4180
4181If generated mask extends beyond image bounds, replicate image edge colors, just
4182as Shader made from SkImage::makeShader with SkShader::kClamp_TileMode set
Cary Clarkbc5697d2017-10-04 14:31:33 -04004183replicates the image edge color when it samples outside of its bounds.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004184
4185constraint set to kStrict_SrcRectConstraint limits Paint Filter_Quality to
Cary Clarkce101242017-09-01 15:51:02 -04004186sample within image; set to kFast_SrcRectConstraint allows sampling outside to
Cary Clarkbad5ad72017-08-03 17:14:08 -04004187improve performance.
4188
4189#Param image Image containing pixels, dimensions, and format ##
4190#Param isrc source IRect of image to draw from ##
4191#Param dst destination Rect of image to draw to ##
4192#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4193 and so on; or nullptr
4194##
Cary Clarkce101242017-09-01 15:51:02 -04004195#Param constraint filter strictly within image or draw faster ##
Cary Clark8032b982017-07-28 11:04:54 -04004196
4197#Example
4198#Height 64
Cary Clarkbad5ad72017-08-03 17:14:08 -04004199void draw(SkCanvas* canvas) {
4200 uint32_t pixels[][2] = { { 0x00000000, 0x55555555},
4201 { 0xAAAAAAAA, 0xFFFFFFFF} };
4202 SkBitmap bitmap;
Herb Derbyefe39bc2018-05-01 17:06:20 -04004203 bitmap.installPixels(SkImageInfo::MakeN32Premul(2, 2),
Cary Clarkbad5ad72017-08-03 17:14:08 -04004204 (void*) pixels, sizeof(pixels[0]));
4205 sk_sp<SkImage> image = SkImage::MakeFromBitmap(bitmap);
4206 SkPaint paint;
4207 canvas->scale(4, 4);
4208 for (auto color : { SK_ColorRED, SK_ColorBLUE, SK_ColorGREEN } ) {
4209 paint.setColorFilter(SkColorFilter::MakeModeFilter(color, SkBlendMode::kPlus));
4210 canvas->drawImageRect(image, SkIRect::MakeWH(2, 2), SkRect::MakeWH(8, 8), &paint);
4211 canvas->translate(8, 0);
4212 }
Cary Clark8032b982017-07-28 11:04:54 -04004213}
4214##
4215
Cary Clark2ade9972017-11-02 17:49:34 -04004216#SeeAlso SrcRectConstraint drawImage drawImageLattice drawImageNine
4217
Cary Clark8032b982017-07-28 11:04:54 -04004218##
4219
4220# ------------------------------------------------------------------------------
4221
4222#Method void drawImageRect(const sk_sp<SkImage>& image, const SkRect& dst, const SkPaint* paint,
Herb Derbyefe39bc2018-05-01 17:06:20 -04004223 SrcRectConstraint constraint = kStrict_SrcRectConstraint)
Cary Clarkab2621d2018-01-30 10:08:57 -05004224#In Draw_Image
Cary Clark78de7512018-02-07 07:27:09 -05004225#In Draw
Cary Clark80247e52018-07-11 16:18:41 -04004226Draws Image image, scaled and translated to fill Rect dst,
Cary Clark8032b982017-07-28 11:04:54 -04004227using Clip, Matrix, and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004228
Cary Clarkbad5ad72017-08-03 17:14:08 -04004229If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4230Blend_Mode, and Draw_Looper. If image is kAlpha_8_SkColorType, apply Shader.
4231If paint contains Mask_Filter, generate mask from image bounds.
4232
4233If generated mask extends beyond image bounds, replicate image edge colors, just
4234as Shader made from SkImage::makeShader with SkShader::kClamp_TileMode set
Cary Clarkbc5697d2017-10-04 14:31:33 -04004235replicates the image edge color when it samples outside of its bounds.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004236
4237constraint set to kStrict_SrcRectConstraint limits Paint Filter_Quality to
Cary Clarkce101242017-09-01 15:51:02 -04004238sample within image; set to kFast_SrcRectConstraint allows sampling outside to
Cary Clarkbad5ad72017-08-03 17:14:08 -04004239improve performance.
4240
4241#Param image Image containing pixels, dimensions, and format ##
4242#Param dst destination Rect of image to draw to ##
4243#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4244 and so on; or nullptr
4245##
Cary Clarkce101242017-09-01 15:51:02 -04004246#Param constraint filter strictly within image or draw faster ##
Cary Clark8032b982017-07-28 11:04:54 -04004247
4248#Example
4249#Height 64
Cary Clarkbad5ad72017-08-03 17:14:08 -04004250void draw(SkCanvas* canvas) {
4251 uint32_t pixels[][2] = { { 0x00000000, 0x55550000},
4252 { 0xAAAA0000, 0xFFFF0000} };
4253 SkBitmap bitmap;
Herb Derbyefe39bc2018-05-01 17:06:20 -04004254 bitmap.installPixels(SkImageInfo::MakeN32Premul(2, 2),
Cary Clarkbad5ad72017-08-03 17:14:08 -04004255 (void*) pixels, sizeof(pixels[0]));
4256 sk_sp<SkImage> image = SkImage::MakeFromBitmap(bitmap);
4257 SkPaint paint;
4258 canvas->scale(4, 4);
4259 for (auto color : { SK_ColorRED, SK_ColorBLUE, SK_ColorGREEN } ) {
4260 paint.setColorFilter(SkColorFilter::MakeModeFilter(color, SkBlendMode::kPlus));
4261 canvas->drawImageRect(image, SkRect::MakeWH(8, 8), &paint);
4262 canvas->translate(8, 0);
4263 }
Cary Clark8032b982017-07-28 11:04:54 -04004264}
4265##
4266
Cary Clark2ade9972017-11-02 17:49:34 -04004267#SeeAlso SrcRectConstraint drawImage drawImageLattice drawImageNine
Cary Clark8032b982017-07-28 11:04:54 -04004268
4269##
4270
4271# ------------------------------------------------------------------------------
4272
4273#Method void drawImageNine(const SkImage* image, const SkIRect& center, const SkRect& dst,
4274 const SkPaint* paint = nullptr)
Cary Clarkab2621d2018-01-30 10:08:57 -05004275#In Draw_Image
Cary Clark78de7512018-02-07 07:27:09 -05004276#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05004277#Line # draws Nine_Patch Image ##
Cary Clark8032b982017-07-28 11:04:54 -04004278
Cary Clark80247e52018-07-11 16:18:41 -04004279Draws Image image stretched proportionally to fit into Rect dst.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004280IRect center divides the image into nine sections: four sides, four corners, and
Cary Clarkce101242017-09-01 15:51:02 -04004281the center. Corners are unmodified or scaled down proportionately if their sides
Cary Clarkbad5ad72017-08-03 17:14:08 -04004282are larger than dst; center and four sides are scaled to fit remaining space, if any.
Cary Clark8032b982017-07-28 11:04:54 -04004283
Cary Clarkbad5ad72017-08-03 17:14:08 -04004284Additionally transform draw using Clip, Matrix, and optional Paint paint.
4285
Cary Clark682c58d2018-05-16 07:07:07 -04004286#paint_as_used_by_draw_lattice_or_draw_nine(image)#
Cary Clarkbad5ad72017-08-03 17:14:08 -04004287
4288If generated mask extends beyond image bounds, replicate image edge colors, just
4289as Shader made from SkImage::makeShader with SkShader::kClamp_TileMode set
Cary Clarkbc5697d2017-10-04 14:31:33 -04004290replicates the image edge color when it samples outside of its bounds.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004291
4292#Param image Image containing pixels, dimensions, and format ##
4293#Param center IRect edge of image corners and sides ##
4294#Param dst destination Rect of image to draw to ##
4295#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4296 and so on; or nullptr
4297##
Cary Clark8032b982017-07-28 11:04:54 -04004298
4299#Example
4300#Height 128
4301#Description
4302 The leftmost image is smaller than center; only corners are drawn, all scaled to fit.
Cary Clarkce101242017-09-01 15:51:02 -04004303 The second image equals the size of center; only corners are drawn without scaling.
4304 The remaining images are larger than center. All corners draw without scaling.
4305 The sides and center are scaled if needed to take up the remaining space.
Cary Clark8032b982017-07-28 11:04:54 -04004306##
Cary Clarkbad5ad72017-08-03 17:14:08 -04004307void draw(SkCanvas* canvas) {
4308 SkIRect center = { 20, 10, 50, 40 };
4309 SkBitmap bitmap;
4310 bitmap.allocPixels(SkImageInfo::MakeN32Premul(60, 60));
4311 SkCanvas bitCanvas(bitmap);
4312 SkPaint paint;
4313 SkColor gray = 0xFF000000;
4314 int left = 0;
4315 for (auto right: { center.fLeft, center.fRight, bitmap.width() } ) {
4316 int top = 0;
4317 for (auto bottom: { center.fTop, center.fBottom, bitmap.height() } ) {
4318 paint.setColor(gray);
4319 bitCanvas.drawIRect(SkIRect::MakeLTRB(left, top, right, bottom), paint);
4320 gray += 0x001f1f1f;
4321 top = bottom;
4322 }
Herb Derbyefe39bc2018-05-01 17:06:20 -04004323 left = right;
Cary Clarkbad5ad72017-08-03 17:14:08 -04004324 }
4325 sk_sp<SkImage> image = SkImage::MakeFromBitmap(bitmap);
4326 SkImage* imagePtr = image.get();
4327 for (auto dest: { 20, 30, 40, 60, 90 } ) {
4328 canvas->drawImageNine(imagePtr, center, SkRect::MakeWH(dest, dest), nullptr);
4329 canvas->translate(dest + 4, 0);
4330 }
Cary Clark8032b982017-07-28 11:04:54 -04004331}
4332##
4333
Cary Clark2ade9972017-11-02 17:49:34 -04004334#SeeAlso drawImage drawBitmapNine drawImageLattice drawImageRect
Cary Clark8032b982017-07-28 11:04:54 -04004335
4336##
4337
4338# ------------------------------------------------------------------------------
4339
4340#Method void drawImageNine(const sk_sp<SkImage>& image, const SkIRect& center, const SkRect& dst,
Herb Derbyefe39bc2018-05-01 17:06:20 -04004341 const SkPaint* paint = nullptr)
Cary Clarkab2621d2018-01-30 10:08:57 -05004342#In Draw_Image
Cary Clark78de7512018-02-07 07:27:09 -05004343#In Draw
Cary Clark80247e52018-07-11 16:18:41 -04004344Draws Image image stretched proportionally to fit into Rect dst.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004345IRect center divides the image into nine sections: four sides, four corners, and
Cary Clarkce101242017-09-01 15:51:02 -04004346the center. Corners are not scaled, or scaled down proportionately if their sides
Cary Clarkbad5ad72017-08-03 17:14:08 -04004347are larger than dst; center and four sides are scaled to fit remaining space, if any.
Cary Clark8032b982017-07-28 11:04:54 -04004348
Cary Clarkbad5ad72017-08-03 17:14:08 -04004349Additionally transform draw using Clip, Matrix, and optional Paint paint.
4350
Cary Clark137b8742018-05-30 09:21:49 -04004351#paint_as_used_by_draw_lattice_or_draw_nine(image)#
Cary Clarkbad5ad72017-08-03 17:14:08 -04004352
4353If generated mask extends beyond image bounds, replicate image edge colors, just
4354as Shader made from SkImage::makeShader with SkShader::kClamp_TileMode set
Cary Clarkbc5697d2017-10-04 14:31:33 -04004355replicates the image edge color when it samples outside of its bounds.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004356
4357#Param image Image containing pixels, dimensions, and format ##
4358#Param center IRect edge of image corners and sides ##
4359#Param dst destination Rect of image to draw to ##
4360#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4361 and so on; or nullptr
4362##
Cary Clark8032b982017-07-28 11:04:54 -04004363
4364#Example
4365#Height 128
4366#Description
4367 The two leftmost images has four corners and sides to the left and right of center.
4368 The leftmost image scales the width of corners proportionately to fit.
Herb Derbyefe39bc2018-05-01 17:06:20 -04004369 The third and fourth image corners are not scaled; the sides and center are scaled to
Cary Clark8032b982017-07-28 11:04:54 -04004370 fill the remaining space.
4371 The rightmost image has four corners scaled vertically to fit, and uses sides above
4372 and below center to fill the remaining space.
4373##
Cary Clarkbad5ad72017-08-03 17:14:08 -04004374void draw(SkCanvas* canvas) {
4375 SkIRect center = { 20, 10, 50, 40 };
4376 SkBitmap bitmap;
4377 bitmap.allocPixels(SkImageInfo::MakeN32Premul(60, 60));
4378 SkCanvas bitCanvas(bitmap);
4379 SkPaint paint;
4380 SkColor gray = 0xFF000000;
4381 int left = 0;
4382 for (auto right: { center.fLeft, center.fRight, bitmap.width() } ) {
4383 int top = 0;
4384 for (auto bottom: { center.fTop, center.fBottom, bitmap.height() } ) {
4385 paint.setColor(gray);
4386 bitCanvas.drawIRect(SkIRect::MakeLTRB(left, top, right, bottom), paint);
4387 gray += 0x001f1f1f;
4388 top = bottom;
4389 }
Herb Derbyefe39bc2018-05-01 17:06:20 -04004390 left = right;
Cary Clarkbad5ad72017-08-03 17:14:08 -04004391 }
4392 sk_sp<SkImage> image = SkImage::MakeFromBitmap(bitmap);
4393 for (auto dest: { 20, 30, 40, 60, 90 } ) {
4394 canvas->drawImageNine(image, center, SkRect::MakeWH(dest, 110 - dest), nullptr);
4395 canvas->translate(dest + 4, 0);
4396 }
Cary Clark8032b982017-07-28 11:04:54 -04004397}
4398##
4399
Cary Clark2ade9972017-11-02 17:49:34 -04004400#SeeAlso drawImage drawBitmapNine drawImageLattice drawImageRect
Cary Clark8032b982017-07-28 11:04:54 -04004401
4402##
4403
4404# ------------------------------------------------------------------------------
4405
4406#Method void drawBitmap(const SkBitmap& bitmap, SkScalar left, SkScalar top,
Cary Clark73fa9722017-08-29 17:36:51 -04004407 const SkPaint* paint = nullptr)
Cary Clarkab2621d2018-01-30 10:08:57 -05004408#In Draw_Image
Cary Clark78de7512018-02-07 07:27:09 -05004409#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05004410#Line # draws Bitmap at (x, y) position ##
Cary Clark8032b982017-07-28 11:04:54 -04004411
Cary Clark80247e52018-07-11 16:18:41 -04004412Draws Bitmap bitmap, with its top-left corner at (left, top),
Cary Clark8032b982017-07-28 11:04:54 -04004413using Clip, Matrix, and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004414
Cary Clarka560c472017-11-27 10:44:06 -05004415If Paint paint is not nullptr, apply Color_Filter, Color_Alpha, Image_Filter,
Cary Clarkbad5ad72017-08-03 17:14:08 -04004416Blend_Mode, and Draw_Looper. If bitmap is kAlpha_8_SkColorType, apply Shader.
4417If paint contains Mask_Filter, generate mask from bitmap bounds.
4418
4419If generated mask extends beyond bitmap bounds, replicate bitmap edge colors,
4420just as Shader made from SkShader::MakeBitmapShader with
Cary Clarkbc5697d2017-10-04 14:31:33 -04004421SkShader::kClamp_TileMode set replicates the bitmap edge color when it samples
Herb Derbyefe39bc2018-05-01 17:06:20 -04004422outside of its bounds.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004423
4424#Param bitmap Bitmap containing pixels, dimensions, and format ##
4425#Param left left side of bitmap ##
4426#Param top top side of bitmap ##
4427#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4428 and so on; or nullptr
4429##
Cary Clark8032b982017-07-28 11:04:54 -04004430
4431#Example
4432#Height 64
Cary Clarkbad5ad72017-08-03 17:14:08 -04004433void draw(SkCanvas* canvas) {
4434 uint8_t pixels[][8] = { { 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00},
4435 { 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00},
4436 { 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00},
4437 { 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF},
4438 { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
4439 { 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00},
4440 { 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0x00},
4441 { 0xFF, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0xFF} };
4442 SkBitmap bitmap;
Herb Derbyefe39bc2018-05-01 17:06:20 -04004443 bitmap.installPixels(SkImageInfo::MakeA8(8, 8),
Cary Clarkbad5ad72017-08-03 17:14:08 -04004444 (void*) pixels, sizeof(pixels[0]));
4445 SkPaint paint;
4446 canvas->scale(4, 4);
4447 for (auto color : { SK_ColorRED, SK_ColorBLUE, 0xFF007F00} ) {
4448 paint.setColor(color);
4449 canvas->drawBitmap(bitmap, 0, 0, &paint);
4450 canvas->translate(12, 0);
4451 }
Cary Clark8032b982017-07-28 11:04:54 -04004452}
4453##
4454
Cary Clark2ade9972017-11-02 17:49:34 -04004455#SeeAlso drawImage drawBitmapLattice drawBitmapNine drawBitmapRect SkBitmap::readPixels SkBitmap::writePixels
Cary Clark8032b982017-07-28 11:04:54 -04004456
4457##
4458
4459# ------------------------------------------------------------------------------
4460
4461#Method void drawBitmapRect(const SkBitmap& bitmap, const SkRect& src, const SkRect& dst,
4462 const SkPaint* paint, SrcRectConstraint constraint = kStrict_SrcRectConstraint)
Cary Clarkab2621d2018-01-30 10:08:57 -05004463#In Draw_Image
Cary Clark78de7512018-02-07 07:27:09 -05004464#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05004465#Line # draws Bitmap, source Rect to destination Rect ##
Cary Clark8032b982017-07-28 11:04:54 -04004466
Cary Clark80247e52018-07-11 16:18:41 -04004467Draws Rect src of Bitmap bitmap, scaled and translated to fill Rect dst.
Cary Clark8032b982017-07-28 11:04:54 -04004468Additionally transform draw using Clip, Matrix, and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004469
Cary Clarkbad5ad72017-08-03 17:14:08 -04004470If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4471Blend_Mode, and Draw_Looper. If bitmap is kAlpha_8_SkColorType, apply Shader.
4472If paint contains Mask_Filter, generate mask from bitmap bounds.
4473
4474If generated mask extends beyond bitmap bounds, replicate bitmap edge colors,
4475just as Shader made from SkShader::MakeBitmapShader with
Cary Clarkbc5697d2017-10-04 14:31:33 -04004476SkShader::kClamp_TileMode set replicates the bitmap edge color when it samples
Cary Clarkbad5ad72017-08-03 17:14:08 -04004477outside of its bounds.
4478
4479constraint set to kStrict_SrcRectConstraint limits Paint Filter_Quality to
4480sample within src; set to kFast_SrcRectConstraint allows sampling outside to
4481improve performance.
4482
4483#Param bitmap Bitmap containing pixels, dimensions, and format ##
4484#Param src source Rect of image to draw from ##
4485#Param dst destination Rect of image to draw to ##
4486#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4487 and so on; or nullptr
4488##
4489#Param constraint filter strictly within src or draw faster ##
Cary Clark8032b982017-07-28 11:04:54 -04004490
4491#Example
4492#Height 64
Cary Clarkbad5ad72017-08-03 17:14:08 -04004493void draw(SkCanvas* canvas) {
4494 uint8_t pixels[][8] = { { 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00},
4495 { 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00},
4496 { 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00},
4497 { 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF},
4498 { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
4499 { 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00},
4500 { 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00},
4501 { 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00} };
4502 SkBitmap bitmap;
Herb Derbyefe39bc2018-05-01 17:06:20 -04004503 bitmap.installPixels(SkImageInfo::MakeA8(8, 8),
Cary Clarkbad5ad72017-08-03 17:14:08 -04004504 (void*) pixels, sizeof(pixels[0]));
4505 SkPaint paint;
Cary Clark681287e2018-03-16 11:34:15 -04004506 paint.setMaskFilter(SkMaskFilter::MakeBlur(kSolid_SkBlurStyle, 6));
Cary Clarkbad5ad72017-08-03 17:14:08 -04004507 for (auto color : { SK_ColorRED, SK_ColorBLUE, 0xFF007F00} ) {
4508 paint.setColor(color);
4509 canvas->drawBitmapRect(bitmap, SkRect::MakeWH(8, 8), SkRect::MakeWH(32, 32), &paint);
4510 canvas->translate(48, 0);
4511 }
Cary Clark8032b982017-07-28 11:04:54 -04004512}
4513##
4514
Cary Clark2ade9972017-11-02 17:49:34 -04004515#SeeAlso drawImageRect drawBitmap drawBitmapLattice drawBitmapNine
Cary Clark8032b982017-07-28 11:04:54 -04004516
4517##
4518
4519# ------------------------------------------------------------------------------
4520
4521#Method void drawBitmapRect(const SkBitmap& bitmap, const SkIRect& isrc, const SkRect& dst,
4522 const SkPaint* paint, SrcRectConstraint constraint = kStrict_SrcRectConstraint)
Cary Clarkab2621d2018-01-30 10:08:57 -05004523#In Draw_Image
Cary Clark78de7512018-02-07 07:27:09 -05004524#In Draw
Cary Clark80247e52018-07-11 16:18:41 -04004525Draws IRect isrc of Bitmap bitmap, scaled and translated to fill Rect dst.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004526isrc is on integer pixel boundaries; dst may include fractional boundaries.
Cary Clark8032b982017-07-28 11:04:54 -04004527Additionally transform draw using Clip, Matrix, and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004528
Cary Clarkbad5ad72017-08-03 17:14:08 -04004529If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4530Blend_Mode, and Draw_Looper. If bitmap is kAlpha_8_SkColorType, apply Shader.
4531If paint contains Mask_Filter, generate mask from bitmap bounds.
4532
4533If generated mask extends beyond bitmap bounds, replicate bitmap edge colors,
4534just as Shader made from SkShader::MakeBitmapShader with
Cary Clarkbc5697d2017-10-04 14:31:33 -04004535SkShader::kClamp_TileMode set replicates the bitmap edge color when it samples
Cary Clarkbad5ad72017-08-03 17:14:08 -04004536outside of its bounds.
4537
4538constraint set to kStrict_SrcRectConstraint limits Paint Filter_Quality to
Cary Clarkce101242017-09-01 15:51:02 -04004539sample within isrc; set to kFast_SrcRectConstraint allows sampling outside to
Cary Clarkbad5ad72017-08-03 17:14:08 -04004540improve performance.
4541
4542#Param bitmap Bitmap containing pixels, dimensions, and format ##
4543#Param isrc source IRect of image to draw from ##
4544#Param dst destination Rect of image to draw to ##
4545#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4546 and so on; or nullptr
4547##
Cary Clarkce101242017-09-01 15:51:02 -04004548#Param constraint sample strictly within isrc, or draw faster ##
Cary Clark8032b982017-07-28 11:04:54 -04004549
4550#Example
4551#Height 64
Cary Clarkbad5ad72017-08-03 17:14:08 -04004552void draw(SkCanvas* canvas) {
4553 uint8_t pixels[][8] = { { 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00},
4554 { 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00},
4555 { 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0xFF},
4556 { 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0xFF},
4557 { 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF},
4558 { 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF},
4559 { 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00},
4560 { 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00} };
4561 SkBitmap bitmap;
Herb Derbyefe39bc2018-05-01 17:06:20 -04004562 bitmap.installPixels(SkImageInfo::MakeA8(8, 8),
Cary Clarkbad5ad72017-08-03 17:14:08 -04004563 (void*) pixels, sizeof(pixels[0]));
4564 SkPaint paint;
4565 paint.setFilterQuality(kHigh_SkFilterQuality);
4566 for (auto color : { SK_ColorRED, SK_ColorBLUE, 0xFF007F00, 0xFF7f007f} ) {
4567 paint.setColor(color);
4568 canvas->drawBitmapRect(bitmap, SkIRect::MakeWH(8, 8), SkRect::MakeWH(32, 32), &paint);
4569 canvas->translate(48.25f, 0);
4570 }
Cary Clark8032b982017-07-28 11:04:54 -04004571}
4572##
4573
Cary Clark2ade9972017-11-02 17:49:34 -04004574#SeeAlso drawImageRect drawBitmap drawBitmapLattice drawBitmapNine
Cary Clark8032b982017-07-28 11:04:54 -04004575
4576##
4577
4578# ------------------------------------------------------------------------------
4579
4580#Method void drawBitmapRect(const SkBitmap& bitmap, const SkRect& dst, const SkPaint* paint,
4581 SrcRectConstraint constraint = kStrict_SrcRectConstraint)
Cary Clarkab2621d2018-01-30 10:08:57 -05004582#In Draw_Image
Cary Clark78de7512018-02-07 07:27:09 -05004583#In Draw
Cary Clark80247e52018-07-11 16:18:41 -04004584Draws Bitmap bitmap, scaled and translated to fill Rect dst.
Cary Clarkce101242017-09-01 15:51:02 -04004585bitmap bounds is on integer pixel boundaries; dst may include fractional boundaries.
Cary Clark8032b982017-07-28 11:04:54 -04004586Additionally transform draw using Clip, Matrix, and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004587
Cary Clarkbad5ad72017-08-03 17:14:08 -04004588If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4589Blend_Mode, and Draw_Looper. If bitmap is kAlpha_8_SkColorType, apply Shader.
4590If paint contains Mask_Filter, generate mask from bitmap bounds.
4591
4592If generated mask extends beyond bitmap bounds, replicate bitmap edge colors,
4593just as Shader made from SkShader::MakeBitmapShader with
Cary Clarkbc5697d2017-10-04 14:31:33 -04004594SkShader::kClamp_TileMode set replicates the bitmap edge color when it samples
Cary Clarkbad5ad72017-08-03 17:14:08 -04004595outside of its bounds.
4596
4597constraint set to kStrict_SrcRectConstraint limits Paint Filter_Quality to
Cary Clarkce101242017-09-01 15:51:02 -04004598sample within bitmap; set to kFast_SrcRectConstraint allows sampling outside to
Cary Clarkbad5ad72017-08-03 17:14:08 -04004599improve performance.
4600
4601#Param bitmap Bitmap containing pixels, dimensions, and format ##
4602#Param dst destination Rect of image to draw to ##
4603#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4604 and so on; or nullptr
4605##
Cary Clarkce101242017-09-01 15:51:02 -04004606#Param constraint filter strictly within bitmap or draw faster ##
Cary Clark8032b982017-07-28 11:04:54 -04004607
4608#Example
4609#Height 64
Cary Clarkbad5ad72017-08-03 17:14:08 -04004610void draw(SkCanvas* canvas) {
4611 uint32_t pixels[][2] = { { 0x00000000, 0x55550000},
4612 { 0xAAAA0000, 0xFFFF0000} };
4613 SkBitmap bitmap;
Herb Derbyefe39bc2018-05-01 17:06:20 -04004614 bitmap.installPixels(SkImageInfo::MakeN32Premul(2, 2),
Cary Clarkbad5ad72017-08-03 17:14:08 -04004615 (void*) pixels, sizeof(pixels[0]));
4616 SkPaint paint;
4617 canvas->scale(4, 4);
4618 for (auto color : { SK_ColorRED, SK_ColorBLUE, SK_ColorGREEN } ) {
4619 paint.setColorFilter(SkColorFilter::MakeModeFilter(color, SkBlendMode::kPlus));
4620 canvas->drawBitmapRect(bitmap, SkRect::MakeWH(8, 8), &paint);
4621 canvas->translate(8, 0);
4622 }
Cary Clark8032b982017-07-28 11:04:54 -04004623}
4624##
4625
Cary Clark2ade9972017-11-02 17:49:34 -04004626#SeeAlso drawImageRect drawBitmap drawBitmapLattice drawBitmapNine
Cary Clark8032b982017-07-28 11:04:54 -04004627
4628##
4629
4630# ------------------------------------------------------------------------------
4631
Cary Clark682c58d2018-05-16 07:07:07 -04004632#PhraseDef paint_as_used_by_draw_lattice_or_draw_nine(bitmap_or_image)
4633If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter,
4634Blend_Mode, and Draw_Looper. If #bitmap_or_image# is kAlpha_8_SkColorType, apply Shader.
4635If paint contains Mask_Filter, generate mask from #bitmap_or_image# bounds. If paint
4636Filter_Quality set to kNone_SkFilterQuality, disable pixel filtering. For all
4637other values of paint Filter_Quality, use kLow_SkFilterQuality to filter pixels.
Cary Clark137b8742018-05-30 09:21:49 -04004638Any SkMaskFilter on paint is ignored as is paint Anti_Aliasing state.
Cary Clark682c58d2018-05-16 07:07:07 -04004639##
4640
Cary Clark8032b982017-07-28 11:04:54 -04004641#Method void drawBitmapNine(const SkBitmap& bitmap, const SkIRect& center, const SkRect& dst,
Cary Clark73fa9722017-08-29 17:36:51 -04004642 const SkPaint* paint = nullptr)
Cary Clarkab2621d2018-01-30 10:08:57 -05004643#In Draw_Image
Cary Clark78de7512018-02-07 07:27:09 -05004644#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05004645#Line # draws Nine_Patch Bitmap ##
Cary Clark8032b982017-07-28 11:04:54 -04004646
Cary Clark80247e52018-07-11 16:18:41 -04004647Draws Bitmap bitmap stretched proportionally to fit into Rect dst.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004648IRect center divides the bitmap into nine sections: four sides, four corners,
Cary Clarkce101242017-09-01 15:51:02 -04004649and the center. Corners are not scaled, or scaled down proportionately if their
Cary Clarkbad5ad72017-08-03 17:14:08 -04004650sides are larger than dst; center and four sides are scaled to fit remaining
4651space, if any.
Cary Clark8032b982017-07-28 11:04:54 -04004652
Cary Clarkbad5ad72017-08-03 17:14:08 -04004653Additionally transform draw using Clip, Matrix, and optional Paint paint.
4654
Cary Clark682c58d2018-05-16 07:07:07 -04004655#paint_as_used_by_draw_lattice_or_draw_nine(bitmap)#
Cary Clarkbad5ad72017-08-03 17:14:08 -04004656
4657If generated mask extends beyond bitmap bounds, replicate bitmap edge colors,
4658just as Shader made from SkShader::MakeBitmapShader with
Cary Clarkbc5697d2017-10-04 14:31:33 -04004659SkShader::kClamp_TileMode set replicates the bitmap edge color when it samples
Cary Clarkbad5ad72017-08-03 17:14:08 -04004660outside of its bounds.
4661
4662#Param bitmap Bitmap containing pixels, dimensions, and format ##
4663#Param center IRect edge of image corners and sides ##
4664#Param dst destination Rect of image to draw to ##
4665#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4666 and so on; or nullptr
4667##
Cary Clark8032b982017-07-28 11:04:54 -04004668
4669#Example
4670#Height 128
4671#Description
4672 The two leftmost bitmap draws has four corners and sides to the left and right of center.
4673 The leftmost bitmap draw scales the width of corners proportionately to fit.
Herb Derbyefe39bc2018-05-01 17:06:20 -04004674 The third and fourth draw corners are not scaled; the sides and center are scaled to
Cary Clark8032b982017-07-28 11:04:54 -04004675 fill the remaining space.
4676 The rightmost bitmap draw has four corners scaled vertically to fit, and uses sides above
4677 and below center to fill the remaining space.
4678##
Cary Clarkbad5ad72017-08-03 17:14:08 -04004679void draw(SkCanvas* canvas) {
4680 SkIRect center = { 20, 10, 50, 40 };
4681 SkBitmap bitmap;
4682 bitmap.allocPixels(SkImageInfo::MakeN32Premul(60, 60));
4683 SkCanvas bitCanvas(bitmap);
4684 SkPaint paint;
4685 SkColor gray = 0xFF000000;
4686 int left = 0;
4687 for (auto right: { center.fLeft, center.fRight, bitmap.width() } ) {
4688 int top = 0;
4689 for (auto bottom: { center.fTop, center.fBottom, bitmap.height() } ) {
4690 paint.setColor(gray);
4691 bitCanvas.drawIRect(SkIRect::MakeLTRB(left, top, right, bottom), paint);
4692 gray += 0x001f1f1f;
4693 top = bottom;
4694 }
Herb Derbyefe39bc2018-05-01 17:06:20 -04004695 left = right;
Cary Clarkbad5ad72017-08-03 17:14:08 -04004696 }
4697 for (auto dest: { 20, 30, 40, 60, 90 } ) {
4698 canvas->drawBitmapNine(bitmap, center, SkRect::MakeWH(dest, 110 - dest), nullptr);
4699 canvas->translate(dest + 4, 0);
4700 }
Cary Clark8032b982017-07-28 11:04:54 -04004701}
4702##
4703
Cary Clark2ade9972017-11-02 17:49:34 -04004704#SeeAlso drawImageNine drawBitmap drawBitmapLattice drawBitmapRect
Cary Clark8032b982017-07-28 11:04:54 -04004705
4706##
4707
4708# ------------------------------------------------------------------------------
Cary Clark682c58d2018-05-16 07:07:07 -04004709#Subtopic Lattice
4710#Line # divides Bitmap or Image into a rectangular grid ##
4711
Cary Clark8032b982017-07-28 11:04:54 -04004712#Struct Lattice
Cary Clark08895c42018-02-01 09:37:32 -05004713#Line # divides Bitmap or Image into a rectangular grid ##
Cary Clark682c58d2018-05-16 07:07:07 -04004714
Cary Clark8032b982017-07-28 11:04:54 -04004715#Code
Cary Clark61313f32018-10-08 14:57:48 -04004716#Populate
Cary Clark8032b982017-07-28 11:04:54 -04004717##
4718
Cary Clark137b8742018-05-30 09:21:49 -04004719Lattice divides Bitmap or Image into a rectangular grid.
4720Grid entries on even columns and even rows are fixed; these entries are
4721always drawn at their original size if the destination is large enough.
4722If the destination side is too small to hold the fixed entries, all fixed
4723entries are proportionately scaled down to fit.
4724The grid entries not on even columns and rows are scaled to fit the
4725remaining space, if any.
4726
Cary Clark2f466242017-12-11 16:03:17 -05004727 #Enum RectType
Cary Clark682c58d2018-05-16 07:07:07 -04004728 #Line # optional setting per rectangular grid entry ##
Cary Clark8032b982017-07-28 11:04:54 -04004729 #Code
Cary Clark61313f32018-10-08 14:57:48 -04004730 #Populate
Cary Clark8032b982017-07-28 11:04:54 -04004731 ##
4732
Cary Clark2f466242017-12-11 16:03:17 -05004733 Optional setting per rectangular grid entry to make it transparent,
4734 or to fill the grid entry with a color.
Cary Clark8032b982017-07-28 11:04:54 -04004735
Cary Clark2f466242017-12-11 16:03:17 -05004736 #Const kDefault 0
Cary Clark682c58d2018-05-16 07:07:07 -04004737 #Line # draws Bitmap into lattice rectangle ##
Cary Clark2f466242017-12-11 16:03:17 -05004738 ##
4739
4740 #Const kTransparent 1
Cary Clark682c58d2018-05-16 07:07:07 -04004741 #Line # skips lattice rectangle by making it transparent ##
Cary Clark2f466242017-12-11 16:03:17 -05004742 ##
4743
4744 #Const kFixedColor 2
Cary Clark682c58d2018-05-16 07:07:07 -04004745 #Line # draws one of fColors into lattice rectangle ##
Cary Clark8032b982017-07-28 11:04:54 -04004746 ##
4747 ##
4748
Cary Clark61313f32018-10-08 14:57:48 -04004749#Subtopic Members
Cary Clark682c58d2018-05-16 07:07:07 -04004750##
4751
Cary Clark8032b982017-07-28 11:04:54 -04004752 #Member const int* fXDivs
Cary Clark5538c132018-06-14 12:28:14 -04004753 #Line # x-axis values dividing bitmap ##
4754 Array of x-axis values that divide the bitmap vertically.
Cary Clarkbad5ad72017-08-03 17:14:08 -04004755 Array entries must be unique, increasing, greater than or equal to
4756 fBounds left edge, and less than fBounds right edge.
4757 Set the first element to fBounds left to collapse the left column of
4758 fixed grid entries.
Cary Clark8032b982017-07-28 11:04:54 -04004759 ##
4760
4761 #Member const int* fYDivs
Cary Clark5538c132018-06-14 12:28:14 -04004762 #Line # y-axis values dividing bitmap ##
4763 Array of y-axis values 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
Cary Clark682c58d2018-05-16 07:07:07 -04004771 #Line # array of fill types ##
Cary Clark2f466242017-12-11 16:03:17 -05004772 Optional array of fill types, one per rectangular grid entry:
Cary Clark2be81cf2018-09-13 12:04:30 -04004773 array length must be #Formula # (fXCount + 1) * (fYCount + 1) ##.
Cary Clark6fc50412017-09-21 12:31:06 -04004774
Cary Clark2f466242017-12-11 16:03:17 -05004775 Each RectType is one of: kDefault, kTransparent, kFixedColor.
4776
Cary Clark8032b982017-07-28 11:04:54 -04004777 Array entries correspond to the rectangular grid entries, ascending
4778 left to right and then top to bottom.
4779 ##
4780
4781 #Member int fXCount
Cary Clark682c58d2018-05-16 07:07:07 -04004782 #Line # number of x-coordinates ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04004783 Number of entries in fXDivs array; one less than the number of
4784 horizontal divisions.
Cary Clark8032b982017-07-28 11:04:54 -04004785 ##
4786
4787 #Member int fYCount
Cary Clark682c58d2018-05-16 07:07:07 -04004788 #Line # number of y-coordinates ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04004789 Number of entries in fYDivs array; one less than the number of vertical
4790 divisions.
Cary Clark8032b982017-07-28 11:04:54 -04004791 ##
4792
4793 #Member const SkIRect* fBounds
Cary Clark682c58d2018-05-16 07:07:07 -04004794 #Line # source bounds to draw from ##
Cary Clark8032b982017-07-28 11:04:54 -04004795 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
Cary Clark682c58d2018-05-16 07:07:07 -04004800 #Line # array of colors ##
Cary Clark2f466242017-12-11 16:03:17 -05004801 Optional array of colors, one per rectangular grid entry.
Cary Clark2be81cf2018-09-13 12:04:30 -04004802 Array length must be #Formula # (fXCount + 1) * (fYCount + 1) ##.
Cary Clark2f466242017-12-11 16:03:17 -05004803
4804 Array entries correspond to the rectangular grid entries, ascending
4805 left to right, then top to bottom.
4806 ##
4807
Cary Clark8032b982017-07-28 11:04:54 -04004808#Struct Lattice ##
4809
4810#Method void drawBitmapLattice(const SkBitmap& bitmap, const Lattice& lattice, const SkRect& dst,
4811 const SkPaint* paint = nullptr)
Cary Clarkab2621d2018-01-30 10:08:57 -05004812#In Draw_Image
Cary Clark78de7512018-02-07 07:27:09 -05004813#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05004814#Line # draws proportionally stretched Bitmap ##
Cary Clark8032b982017-07-28 11:04:54 -04004815
Cary Clark80247e52018-07-11 16:18:41 -04004816Draws Bitmap bitmap stretched proportionally to fit into Rect dst.
Cary Clark8032b982017-07-28 11:04:54 -04004817
4818Lattice lattice divides bitmap into a rectangular grid.
4819Each intersection of an even-numbered row and column is fixed; like the corners
Cary Clarkbad5ad72017-08-03 17:14:08 -04004820of drawBitmapNine, fixed lattice elements never scale larger than their initial
Cary Clarkbc5697d2017-10-04 14:31:33 -04004821size and shrink proportionately when all fixed elements exceed the bitmap
Cary Clarkbad5ad72017-08-03 17:14:08 -04004822dimension. All other grid elements scale to fill the available space, if any.
Cary Clark8032b982017-07-28 11:04:54 -04004823
4824Additionally transform draw using Clip, Matrix, and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004825
Cary Clark682c58d2018-05-16 07:07:07 -04004826#paint_as_used_by_draw_lattice_or_draw_nine(bitmap)#
Cary Clarkbad5ad72017-08-03 17:14:08 -04004827
4828If generated mask extends beyond bitmap bounds, replicate bitmap edge colors,
4829just as Shader made from SkShader::MakeBitmapShader with
Cary Clarkbc5697d2017-10-04 14:31:33 -04004830SkShader::kClamp_TileMode set replicates the bitmap edge color when it samples
Cary Clarkbad5ad72017-08-03 17:14:08 -04004831outside of its bounds.
4832
4833#Param bitmap Bitmap containing pixels, dimensions, and format ##
4834#Param lattice division of bitmap into fixed and variable rectangles ##
4835#Param dst destination Rect of image to draw to ##
4836#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4837 and so on; or nullptr
4838##
Cary Clark8032b982017-07-28 11:04:54 -04004839
4840#Example
4841#Height 128
4842#Description
4843 The two leftmost bitmap draws has four corners and sides to the left and right of center.
4844 The leftmost bitmap draw scales the width of corners proportionately to fit.
Herb Derbyefe39bc2018-05-01 17:06:20 -04004845 The third and fourth draw corners are not scaled; the sides are scaled to
Cary Clark8032b982017-07-28 11:04:54 -04004846 fill the remaining space; the center is transparent.
4847 The rightmost bitmap draw has four corners scaled vertically to fit, and uses sides above
4848 and below center to fill the remaining space.
4849##
Cary Clarkbad5ad72017-08-03 17:14:08 -04004850void draw(SkCanvas* canvas) {
4851 SkIRect center = { 20, 10, 50, 40 };
4852 SkBitmap bitmap;
4853 bitmap.allocPixels(SkImageInfo::MakeN32Premul(60, 60));
4854 SkCanvas bitCanvas(bitmap);
4855 SkPaint paint;
4856 SkColor gray = 0xFF000000;
4857 int left = 0;
4858 for (auto right: { center.fLeft, center.fRight, bitmap.width() } ) {
4859 int top = 0;
4860 for (auto bottom: { center.fTop, center.fBottom, bitmap.height() } ) {
4861 paint.setColor(gray);
4862 bitCanvas.drawIRect(SkIRect::MakeLTRB(left, top, right, bottom), paint);
4863 gray += 0x001f1f1f;
4864 top = bottom;
4865 }
Herb Derbyefe39bc2018-05-01 17:06:20 -04004866 left = right;
Cary Clarkbad5ad72017-08-03 17:14:08 -04004867 }
4868 const int xDivs[] = { center.fLeft, center.fRight };
4869 const int yDivs[] = { center.fTop, center.fBottom };
Cary Clarkca3ebcd2017-12-12 11:22:38 -05004870 SkCanvas::Lattice::RectType fillTypes[3][3];
4871 memset(fillTypes, 0, sizeof(fillTypes));
4872 fillTypes[1][1] = SkCanvas::Lattice::kTransparent;
4873 SkColor dummy[9]; // temporary pending bug fix
4874 SkCanvas::Lattice lattice = { xDivs, yDivs, fillTypes[0], SK_ARRAY_COUNT(xDivs),
4875 SK_ARRAY_COUNT(yDivs), nullptr, dummy };
Cary Clarkbad5ad72017-08-03 17:14:08 -04004876 for (auto dest: { 20, 30, 40, 60, 90 } ) {
Cary Clarkca3ebcd2017-12-12 11:22:38 -05004877 canvas->drawBitmapLattice(bitmap, lattice, SkRect::MakeWH(dest, 110 - dest), nullptr);
Cary Clarkbad5ad72017-08-03 17:14:08 -04004878 canvas->translate(dest + 4, 0);
4879 }
Cary Clark8032b982017-07-28 11:04:54 -04004880}
4881##
4882
Cary Clark2ade9972017-11-02 17:49:34 -04004883#SeeAlso drawImageLattice drawBitmap drawBitmapNine Lattice
Cary Clark8032b982017-07-28 11:04:54 -04004884
4885##
4886
4887# ------------------------------------------------------------------------------
4888
4889#Method void drawImageLattice(const SkImage* image, const Lattice& lattice, const SkRect& dst,
4890 const SkPaint* paint = nullptr)
Cary Clarkab2621d2018-01-30 10:08:57 -05004891#In Draw_Image
Cary Clark78de7512018-02-07 07:27:09 -05004892#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05004893#Line # draws proportionally stretched Image ##
Cary Clark8032b982017-07-28 11:04:54 -04004894
Cary Clark80247e52018-07-11 16:18:41 -04004895Draws Image image stretched proportionally to fit into Rect dst.
Cary Clark8032b982017-07-28 11:04:54 -04004896
4897Lattice lattice divides image into a rectangular grid.
4898Each intersection of an even-numbered row and column is fixed; like the corners
Cary Clarkbad5ad72017-08-03 17:14:08 -04004899of drawBitmapNine, fixed lattice elements never scale larger than their initial
Cary Clarkbc5697d2017-10-04 14:31:33 -04004900size and shrink proportionately when all fixed elements exceed the bitmap
Cary Clarkbad5ad72017-08-03 17:14:08 -04004901dimension. All other grid elements scale to fill the available space, if any.
Cary Clark8032b982017-07-28 11:04:54 -04004902
4903Additionally transform draw using Clip, Matrix, and optional Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04004904
Cary Clark682c58d2018-05-16 07:07:07 -04004905#paint_as_used_by_draw_lattice_or_draw_nine(image)#
Cary Clarkbad5ad72017-08-03 17:14:08 -04004906
4907If generated mask extends beyond bitmap bounds, replicate bitmap edge colors,
4908just as Shader made from SkShader::MakeBitmapShader with
Cary Clarkbc5697d2017-10-04 14:31:33 -04004909SkShader::kClamp_TileMode set replicates the bitmap edge color when it samples
Cary Clarkbad5ad72017-08-03 17:14:08 -04004910outside of its bounds.
4911
4912#Param image Image containing pixels, dimensions, and format ##
4913#Param lattice division of bitmap into fixed and variable rectangles ##
4914#Param dst destination Rect of image to draw to ##
4915#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter,
4916 and so on; or nullptr
4917##
Cary Clark8032b982017-07-28 11:04:54 -04004918
4919#Example
4920#Height 128
4921#Description
4922 The leftmost image is smaller than center; only corners are drawn, all scaled to fit.
Cary Clarkce101242017-09-01 15:51:02 -04004923 The second image equals the size of center; only corners are drawn without scaling.
4924 The remaining images are larger than center. All corners draw without scaling. The sides
Cary Clark8032b982017-07-28 11:04:54 -04004925 are scaled if needed to take up the remaining space; the center is transparent.
4926##
Cary Clarkbad5ad72017-08-03 17:14:08 -04004927void draw(SkCanvas* canvas) {
4928 SkIRect center = { 20, 10, 50, 40 };
4929 SkBitmap bitmap;
4930 bitmap.allocPixels(SkImageInfo::MakeN32Premul(60, 60));
4931 SkCanvas bitCanvas(bitmap);
4932 SkPaint paint;
4933 SkColor gray = 0xFF000000;
4934 int left = 0;
4935 for (auto right: { center.fLeft, center.fRight, bitmap.width() } ) {
4936 int top = 0;
4937 for (auto bottom: { center.fTop, center.fBottom, bitmap.height() } ) {
4938 paint.setColor(gray);
4939 bitCanvas.drawIRect(SkIRect::MakeLTRB(left, top, right, bottom), paint);
4940 gray += 0x001f1f1f;
4941 top = bottom;
4942 }
Herb Derbyefe39bc2018-05-01 17:06:20 -04004943 left = right;
Cary Clarkbad5ad72017-08-03 17:14:08 -04004944 }
Cary Clarkbad5ad72017-08-03 17:14:08 -04004945 sk_sp<SkImage> image = SkImage::MakeFromBitmap(bitmap);
4946 SkImage* imagePtr = image.get();
4947 for (auto dest: { 20, 30, 40, 60, 90 } ) {
4948 canvas->drawImageNine(imagePtr, center, SkRect::MakeWH(dest, dest), nullptr);
4949 canvas->translate(dest + 4, 0);
4950 }
Cary Clark8032b982017-07-28 11:04:54 -04004951}
4952##
4953
Cary Clark2ade9972017-11-02 17:49:34 -04004954#SeeAlso drawBitmapLattice drawImage drawImageNine Lattice
Cary Clark8032b982017-07-28 11:04:54 -04004955
4956##
4957
Cary Clark682c58d2018-05-16 07:07:07 -04004958#Subtopic Lattice ##
4959
Brian Salomond7065e72018-10-12 11:42:02 -04004960# ------------------------------------------------------------------------------
4961
4962#Enum QuadAAFlags
4963#Line # don't use this ##
4964#Private
4965##
4966#NoExample
4967##
4968##
4969
4970# ------------------------------------------------------------------------------
4971
4972#Struct ImageSetEntry
4973#Line # don't use this ##
4974#Private
4975##
4976
4977#Member SkImage* fImage
4978#Line # image to draw ##
4979##
4980
4981#Member SkRect fSrcRect
4982#Line # image src rectangle ##
4983##
4984
4985#Member SkRect fDstRect
4986#Line # local space rectangle ##
4987##
4988
4989#Member unsigned fAAFlags
4990#Line # antialiasing flags ##
4991##
4992
4993#NoExample
4994##
4995
4996##
4997
4998# ------------------------------------------------------------------------------
4999
5000#Method void experimental_DrawImageSetV0(const ImageSetEntry imageSet[], int cnt, float alpha,
5001 SkFilterQuality quality, SkBlendMode mode);
5002#Private
5003##
5004#In Draw_Image
5005#In Draw
5006#Line # draws a set a of images (don't call this) ##
5007
5008Draws a set of images. Do not use this method.
5009
5010#Param imageSet images ##
5011#Param cnt number of images ##
5012#Param alpha alpha ##
5013#Param quality filter quality ##
5014#Param mode blend mode ##
5015
5016#NoExample
5017##
5018
5019##
5020
Cary Clark08895c42018-02-01 09:37:32 -05005021#Subtopic Draw_Image ##
Cary Clark8032b982017-07-28 11:04:54 -04005022
5023# ------------------------------------------------------------------------------
Cary Clark78de7512018-02-07 07:27:09 -05005024#Subtopic Draw_Text
Cary Clark78de7512018-02-07 07:27:09 -05005025#Line # draws text into Canvas ##
5026##
Cary Clark8032b982017-07-28 11:04:54 -04005027
5028#Method void drawText(const void* text, size_t byteLength, SkScalar x, SkScalar y,
5029 const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05005030#In Draw_Text
5031#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05005032#Line # draws text at (x, y), using font advance ##
Cary Clark8032b982017-07-28 11:04:54 -04005033
Cary Clark80247e52018-07-11 16:18:41 -04005034Draws text, with origin at (x, y), using Clip, Matrix, and Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04005035
Cary Clarkbc5697d2017-10-04 14:31:33 -04005036text meaning depends on Paint_Text_Encoding; by default, text is encoded as
Cary Clarkbad5ad72017-08-03 17:14:08 -04005037UTF-8.
Cary Clark8032b982017-07-28 11:04:54 -04005038
Cary Clarkbad5ad72017-08-03 17:14:08 -04005039x and y meaning depends on Paint_Text_Align and Paint_Vertical_Text; by default
Cary Clarkbc5697d2017-10-04 14:31:33 -04005040text draws left to right, positioning the first glyph left side bearing at x
Herb Derbyefe39bc2018-05-01 17:06:20 -04005041and its baseline at y. Text size is affected by Matrix and Paint_Text_Size.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005042
Mike Reed8ad91a92018-01-19 19:09:32 -05005043All elements of paint: Path_Effect, Mask_Filter, Shader,
Cary Clarkbad5ad72017-08-03 17:14:08 -04005044Color_Filter, Image_Filter, and Draw_Looper; apply to text. By default, draws
Cary Clarkce101242017-09-01 15:51:02 -04005045filled 12 point black Glyphs.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005046
Cary Clarkce101242017-09-01 15:51:02 -04005047#Param text character code points or Glyphs drawn ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005048#Param byteLength byte length of text array ##
5049#Param x start of text on x-axis ##
5050#Param y start of text on y-axis ##
5051#Param paint text size, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005052
5053#Example
5054#Height 200
5055#Description
5056 The same text is drawn varying Paint_Text_Size and varying
Herb Derbyefe39bc2018-05-01 17:06:20 -04005057 Matrix.
Cary Clark8032b982017-07-28 11:04:54 -04005058##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005059void draw(SkCanvas* canvas) {
5060 SkPaint paint;
5061 paint.setAntiAlias(true);
5062 float textSizes[] = { 12, 18, 24, 36 };
5063 for (auto size: textSizes ) {
5064 paint.setTextSize(size);
5065 canvas->drawText("Aa", 2, 10, 20, paint);
5066 canvas->translate(0, size * 2);
5067 }
5068 paint.reset();
5069 paint.setAntiAlias(true);
5070 float yPos = 20;
5071 for (auto size: textSizes ) {
5072 float scale = size / 12.f;
5073 canvas->resetMatrix();
5074 canvas->translate(100, 0);
5075 canvas->scale(scale, scale);
5076 canvas->drawText("Aa", 2, 10 / scale, yPos / scale, paint);
Herb Derbyefe39bc2018-05-01 17:06:20 -04005077 yPos += size * 2;
Cary Clarkbad5ad72017-08-03 17:14:08 -04005078 }
5079}
Cary Clark8032b982017-07-28 11:04:54 -04005080##
5081
Cary Clark153e76d2018-08-28 11:48:28 -04005082#SeeAlso drawString drawPosText drawPosTextH drawTextBlob drawTextRSXform
Cary Clark8032b982017-07-28 11:04:54 -04005083
5084##
5085
5086#Method void drawString(const char* string, SkScalar x, SkScalar y, const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05005087#In Draw_Text
5088#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05005089#Line # draws null terminated string at (x, y) using font advance ##
Cary Clark682c58d2018-05-16 07:07:07 -04005090Draws null terminated string, with origin at (x, y), using Clip, Matrix, and
5091Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04005092
Cary Clarkbc5697d2017-10-04 14:31:33 -04005093string meaning depends on Paint_Text_Encoding; by default, strings are encoded
5094as UTF-8. Other values of Paint_Text_Encoding are unlikely to produce the desired
Cary Clarkbad5ad72017-08-03 17:14:08 -04005095results, since zero bytes may be embedded in the string.
Cary Clark8032b982017-07-28 11:04:54 -04005096
Cary Clarkbad5ad72017-08-03 17:14:08 -04005097x and y meaning depends on Paint_Text_Align and Paint_Vertical_Text; by default
Cary Clarkbc5697d2017-10-04 14:31:33 -04005098string draws left to right, positioning the first glyph left side bearing at x
Herb Derbyefe39bc2018-05-01 17:06:20 -04005099and its baseline at y. Text size is affected by Matrix and Paint_Text_Size.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005100
Mike Reed8ad91a92018-01-19 19:09:32 -05005101All elements of paint: Path_Effect, Mask_Filter, Shader,
Cary Clarkbad5ad72017-08-03 17:14:08 -04005102Color_Filter, Image_Filter, and Draw_Looper; apply to text. By default, draws
Cary Clarkce101242017-09-01 15:51:02 -04005103filled 12 point black Glyphs.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005104
Cary Clarkce101242017-09-01 15:51:02 -04005105#Param string character code points or Glyphs drawn,
Cary Clarkbad5ad72017-08-03 17:14:08 -04005106 ending with a char value of zero
5107##
5108#Param x start of string on x-axis ##
5109#Param y start of string on y-axis ##
5110#Param paint text size, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005111
5112#Example
Cary Clarkffb3d682018-05-17 12:17:28 -04005113#Height 48
Cary Clark8032b982017-07-28 11:04:54 -04005114 SkPaint paint;
5115 canvas->drawString("a small hello", 20, 20, paint);
5116##
5117
Cary Clark153e76d2018-08-28 11:48:28 -04005118#SeeAlso drawText drawPosText drawPosTextH drawTextBlob drawTextRSXform
Cary Clark8032b982017-07-28 11:04:54 -04005119
5120##
5121
5122#Method void drawString(const SkString& string, SkScalar x, SkScalar y, const SkPaint& paint)
5123
Cary Clark80247e52018-07-11 16:18:41 -04005124Draws null terminated string, with origin at (x, y), using Clip, Matrix, and
Cary Clarkbad5ad72017-08-03 17:14:08 -04005125Paint paint.
Cary Clark8032b982017-07-28 11:04:54 -04005126
Cary Clarkbc5697d2017-10-04 14:31:33 -04005127string meaning depends on Paint_Text_Encoding; by default, strings are encoded
5128as UTF-8. Other values of Paint_Text_Encoding are unlikely to produce the desired
Cary Clarkbad5ad72017-08-03 17:14:08 -04005129results, since zero bytes may be embedded in the string.
Cary Clark8032b982017-07-28 11:04:54 -04005130
Cary Clarkbad5ad72017-08-03 17:14:08 -04005131x and y meaning depends on Paint_Text_Align and Paint_Vertical_Text; by default
Cary Clarkbc5697d2017-10-04 14:31:33 -04005132string draws left to right, positioning the first glyph left side bearing at x
Herb Derbyefe39bc2018-05-01 17:06:20 -04005133and its baseline at y. Text size is affected by Matrix and Paint_Text_Size.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005134
Mike Reed8ad91a92018-01-19 19:09:32 -05005135All elements of paint: Path_Effect, Mask_Filter, Shader,
Cary Clarkbad5ad72017-08-03 17:14:08 -04005136Color_Filter, Image_Filter, and Draw_Looper; apply to text. By default, draws
Cary Clarkce101242017-09-01 15:51:02 -04005137filled 12 point black Glyphs.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005138
Cary Clarkce101242017-09-01 15:51:02 -04005139#Param string character code points or Glyphs drawn,
Cary Clarkbad5ad72017-08-03 17:14:08 -04005140 ending with a char value of zero
5141##
5142#Param x start of string on x-axis ##
5143#Param y start of string on y-axis ##
5144#Param paint text size, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005145
5146#Example
5147 SkPaint paint;
5148 SkString string("a small hello");
5149 canvas->drawString(string, 20, 20, paint);
5150##
5151
Cary Clark153e76d2018-08-28 11:48:28 -04005152#SeeAlso drawText drawPosText drawPosTextH drawTextBlob drawTextRSXform
Cary Clark8032b982017-07-28 11:04:54 -04005153
5154##
5155
5156# ------------------------------------------------------------------------------
5157
5158#Method void drawPosText(const void* text, size_t byteLength, const SkPoint pos[],
5159 const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05005160#In Draw_Text
5161#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05005162#Line # draws text at array of (x, y) positions ##
Cary Clark8032b982017-07-28 11:04:54 -04005163
Cary Clark80247e52018-07-11 16:18:41 -04005164Draws each glyph in text with the origin in pos array, using Clip, Matrix, and
Cary Clarkce101242017-09-01 15:51:02 -04005165Paint paint. The number of entries in pos array must match the number of Glyphs
Cary Clarkbad5ad72017-08-03 17:14:08 -04005166described by byteLength of text.
Cary Clark8032b982017-07-28 11:04:54 -04005167
Cary Clarkbc5697d2017-10-04 14:31:33 -04005168text meaning depends on Paint_Text_Encoding; by default, text is encoded as
Cary Clark5538c132018-06-14 12:28:14 -04005169UTF-8. pos elements meaning depends on Paint_Vertical_Text; by default
5170glyph left side bearing and baseline are relative to Point in pos array.
5171Text size is affected by Matrix and Paint_Text_Size.
Cary Clark8032b982017-07-28 11:04:54 -04005172
Mike Reed8ad91a92018-01-19 19:09:32 -05005173All elements of paint: Path_Effect, Mask_Filter, Shader,
Cary Clarkbad5ad72017-08-03 17:14:08 -04005174Color_Filter, Image_Filter, and Draw_Looper; apply to text. By default, draws
Cary Clarkce101242017-09-01 15:51:02 -04005175filled 12 point black Glyphs.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005176
5177Layout engines such as Harfbuzz typically position each glyph
Cary Clarkbc5697d2017-10-04 14:31:33 -04005178rather than using the font advance widths.
Cary Clark8032b982017-07-28 11:04:54 -04005179
Cary Clarkce101242017-09-01 15:51:02 -04005180#Param text character code points or Glyphs drawn ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005181#Param byteLength byte length of text array ##
5182#Param pos array of glyph origins ##
5183#Param paint text size, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005184
5185#Example
5186#Height 120
Cary Clarkbad5ad72017-08-03 17:14:08 -04005187void draw(SkCanvas* canvas) {
5188 const char hello[] = "HeLLo!";
5189 const SkPoint pos[] = { {40, 100}, {82, 95}, {115, 110}, {130, 95}, {145, 85},
5190 {172, 100} };
5191 SkPaint paint;
5192 paint.setTextSize(60);
5193 canvas->drawPosText(hello, strlen(hello), pos, paint);
Cary Clark8032b982017-07-28 11:04:54 -04005194}
5195##
5196
Cary Clark153e76d2018-08-28 11:48:28 -04005197#SeeAlso drawText drawPosTextH drawTextBlob drawTextRSXform
Cary Clark8032b982017-07-28 11:04:54 -04005198
5199##
5200
5201# ------------------------------------------------------------------------------
5202
5203#Method void drawPosTextH(const void* text, size_t byteLength, const SkScalar xpos[], SkScalar constY,
5204 const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05005205#In Draw_Text
5206#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05005207#Line # draws text at x positions with common baseline ##
Cary Clark8032b982017-07-28 11:04:54 -04005208
Cary Clark80247e52018-07-11 16:18:41 -04005209Draws each glyph in text with its (x, y) origin composed from xpos array and
Cary Clarkbad5ad72017-08-03 17:14:08 -04005210constY, using Clip, Matrix, and Paint paint. The number of entries in xpos array
Cary Clarkce101242017-09-01 15:51:02 -04005211must match the number of Glyphs described by byteLength of text.
Cary Clark8032b982017-07-28 11:04:54 -04005212
Cary Clarkbc5697d2017-10-04 14:31:33 -04005213text meaning depends on Paint_Text_Encoding; by default, text is encoded as
Cary Clark137b8742018-05-30 09:21:49 -04005214UTF-8. xpos elements meaning depends on Paint_Vertical_Text;
Cary Clarkbc5697d2017-10-04 14:31:33 -04005215by default each glyph left side bearing is positioned at an xpos element and
Cary Clarkbad5ad72017-08-03 17:14:08 -04005216its baseline is positioned at constY. Text size is affected by Matrix and
Herb Derbyefe39bc2018-05-01 17:06:20 -04005217Paint_Text_Size.
Cary Clark8032b982017-07-28 11:04:54 -04005218
Mike Reed8ad91a92018-01-19 19:09:32 -05005219All elements of paint: Path_Effect, Mask_Filter, Shader,
Cary Clarkbad5ad72017-08-03 17:14:08 -04005220Color_Filter, Image_Filter, and Draw_Looper; apply to text. By default, draws
Cary Clarkce101242017-09-01 15:51:02 -04005221filled 12 point black Glyphs.
Cary Clark8032b982017-07-28 11:04:54 -04005222
Cary Clarkbad5ad72017-08-03 17:14:08 -04005223Layout engines such as Harfbuzz typically position each glyph
Cary Clarkbc5697d2017-10-04 14:31:33 -04005224rather than using the font advance widths if all Glyphs share the same
Cary Clarkbad5ad72017-08-03 17:14:08 -04005225baseline.
5226
Cary Clarkce101242017-09-01 15:51:02 -04005227#Param text character code points or Glyphs drawn ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005228#Param byteLength byte length of text array ##
Cary Clark5538c132018-06-14 12:28:14 -04005229#Param xpos array of x-axis positions, used to position each glyph ##
5230#Param constY shared y-axis value for all of x-axis positions ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005231#Param paint text size, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005232
5233#Example
5234#Height 40
Cary Clarkbad5ad72017-08-03 17:14:08 -04005235 void draw(SkCanvas* canvas) {
5236 SkScalar xpos[] = { 20, 40, 80, 160 };
5237 SkPaint paint;
5238 canvas->drawPosTextH("XXXX", 4, xpos, 20, paint);
5239 }
Cary Clark8032b982017-07-28 11:04:54 -04005240##
5241
Cary Clark153e76d2018-08-28 11:48:28 -04005242#SeeAlso drawText drawPosText drawTextBlob drawTextRSXform
Cary Clark8032b982017-07-28 11:04:54 -04005243
5244##
5245
5246# ------------------------------------------------------------------------------
5247
Cary Clark8032b982017-07-28 11:04:54 -04005248#Method void drawTextRSXform(const void* text, size_t byteLength, const SkRSXform xform[],
5249 const SkRect* cullRect, const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05005250#In Draw_Text
5251#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05005252#Line # draws text with array of RSXform ##
Cary Clark8032b982017-07-28 11:04:54 -04005253
Cary Clark80247e52018-07-11 16:18:41 -04005254Draws text, transforming each glyph by the corresponding SkRSXform,
Cary Clark8032b982017-07-28 11:04:54 -04005255using Clip, Matrix, and Paint paint.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005256
Cary Clark137b8742018-05-30 09:21:49 -04005257RSXform xform array specifies a separate square scale, rotation, and translation
5258for each glyph. xform does not affect paint Shader.
Cary Clark8032b982017-07-28 11:04:54 -04005259
Cary Clarkbad5ad72017-08-03 17:14:08 -04005260Optional Rect cullRect is a conservative bounds of text, taking into account
Cary Clarkce101242017-09-01 15:51:02 -04005261RSXform and paint. If cullRect is outside of Clip, canvas can skip drawing.
Cary Clark8032b982017-07-28 11:04:54 -04005262
Mike Reed8ad91a92018-01-19 19:09:32 -05005263All elements of paint: Path_Effect, Mask_Filter, Shader,
Cary Clarkbad5ad72017-08-03 17:14:08 -04005264Color_Filter, Image_Filter, and Draw_Looper; apply to text. By default, draws
Cary Clarkce101242017-09-01 15:51:02 -04005265filled 12 point black Glyphs.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005266
Cary Clarkce101242017-09-01 15:51:02 -04005267#Param text character code points or Glyphs drawn ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005268#Param byteLength byte length of text array ##
5269#Param xform RSXform rotates, scales, and translates each glyph individually ##
5270#Param cullRect Rect bounds of text for efficient clipping; or nullptr ##
5271#Param paint text size, blend, color, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005272
5273#Example
Herb Derbyefe39bc2018-05-01 17:06:20 -04005274void draw(SkCanvas* canvas) {
Cary Clarkbad5ad72017-08-03 17:14:08 -04005275 const int iterations = 26;
5276 SkRSXform transforms[iterations];
5277 char alphabet[iterations];
5278 SkScalar angle = 0;
5279 SkScalar scale = 1;
5280 for (size_t i = 0; i < SK_ARRAY_COUNT(transforms); ++i) {
5281 const SkScalar s = SkScalarSin(angle) * scale;
5282 const SkScalar c = SkScalarCos(angle) * scale;
5283 transforms[i] = SkRSXform::Make(-c, -s, -s * 16, c * 16);
5284 angle += .45;
5285 scale += .2;
5286 alphabet[i] = 'A' + i;
5287 }
5288 SkPaint paint;
5289 paint.setTextAlign(SkPaint::kCenter_Align);
5290 canvas->translate(110, 138);
5291 canvas->drawTextRSXform(alphabet, sizeof(alphabet), transforms, nullptr, paint);
Cary Clark8032b982017-07-28 11:04:54 -04005292}
5293##
5294
Cary Clark153e76d2018-08-28 11:48:28 -04005295#SeeAlso drawText drawPosText drawTextBlob
Cary Clark8032b982017-07-28 11:04:54 -04005296
5297##
5298
5299# ------------------------------------------------------------------------------
5300
5301#Method void drawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y, const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05005302#In Draw_Text
5303#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05005304#Line # draws text with arrays of positions and Paint ##
Cary Clark80247e52018-07-11 16:18:41 -04005305Draws Text_Blob blob at (x, y), using Clip, Matrix, and Paint paint.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005306
Cary Clarkce101242017-09-01 15:51:02 -04005307blob contains Glyphs, their positions, and paint attributes specific to text:
Cary Clarkd2ca79c2018-08-10 13:09:13 -04005308#paint_font_metrics#.
Cary Clark8032b982017-07-28 11:04:54 -04005309
Cary Clark3cd22cc2017-12-01 11:49:58 -05005310Paint_Text_Encoding must be set to SkPaint::kGlyphID_TextEncoding.
5311
Cary Clarkd2ca79c2018-08-10 13:09:13 -04005312Elements of paint: Anti_Alias, Blend_Mode, Color including Color_Alpha,
5313Color_Filter, Paint_Dither, Draw_Looper, Mask_Filter, Path_Effect, Shader, and
Cary Clark61313f32018-10-08 14:57:48 -04005314Paint_Style; apply to blob. If Paint contains SkPaint::kStroke_Style:
Cary Clarkd2ca79c2018-08-10 13:09:13 -04005315Paint_Miter_Limit, Paint_Stroke_Cap, Paint_Stroke_Join, and Paint_Stroke_Width;
5316apply to Path created from blob.
Cary Clark8032b982017-07-28 11:04:54 -04005317
Cary Clarkce101242017-09-01 15:51:02 -04005318#Param blob Glyphs, positions, and their paints' text size, typeface, and so on ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005319#Param x horizontal offset applied to blob ##
5320#Param y vertical offset applied to blob ##
5321#Param paint blend, color, stroking, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005322
5323#Example
5324#Height 120
Cary Clarke80cd442018-07-17 13:19:56 -04005325void draw(SkCanvas* canvas) {
5326 SkTextBlobBuilder textBlobBuilder;
5327 const char bunny[] = "/(^x^)\\";
5328 const int len = sizeof(bunny) - 1;
5329 uint16_t glyphs[len];
5330 SkPaint paint;
5331 paint.textToGlyphs(bunny, len, glyphs);
5332 paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
5333 int runs[] = { 3, 1, 3 };
5334 SkPoint textPos = { 20, 100 };
5335 int glyphIndex = 0;
5336 for (auto runLen : runs) {
5337 paint.setTextSize(1 == runLen ? 20 : 50);
5338 const SkTextBlobBuilder::RunBuffer& run =
5339 textBlobBuilder.allocRun(paint, runLen, textPos.fX, textPos.fY);
5340 memcpy(run.glyphs, &glyphs[glyphIndex], sizeof(glyphs[0]) * runLen);
5341 textPos.fX += paint.measureText(&glyphs[glyphIndex], sizeof(glyphs[0]) * runLen, nullptr);
5342 glyphIndex += runLen;
Cary Clark8032b982017-07-28 11:04:54 -04005343 }
Cary Clarke80cd442018-07-17 13:19:56 -04005344 sk_sp<const SkTextBlob> blob = textBlobBuilder.make();
5345 paint.reset();
5346 canvas->drawTextBlob(blob.get(), 0, 0, paint);
5347}
Cary Clark8032b982017-07-28 11:04:54 -04005348##
5349
Cary Clark2ade9972017-11-02 17:49:34 -04005350#SeeAlso drawText drawPosText drawPosTextH
Cary Clark8032b982017-07-28 11:04:54 -04005351
5352##
5353
5354# ------------------------------------------------------------------------------
5355
Herb Derbyefe39bc2018-05-01 17:06:20 -04005356#Method void drawTextBlob(const sk_sp<SkTextBlob>& blob, SkScalar x, SkScalar y, const SkPaint& paint)
Cary Clark8032b982017-07-28 11:04:54 -04005357
Cary Clark80247e52018-07-11 16:18:41 -04005358Draws Text_Blob blob at (x, y), using Clip, Matrix, and Paint paint.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005359
Cary Clarkce101242017-09-01 15:51:02 -04005360blob contains Glyphs, their positions, and paint attributes specific to text:
Cary Clarkd2ca79c2018-08-10 13:09:13 -04005361#paint_font_metrics#.
Cary Clark8032b982017-07-28 11:04:54 -04005362
Cary Clark3cd22cc2017-12-01 11:49:58 -05005363Paint_Text_Encoding must be set to SkPaint::kGlyphID_TextEncoding.
5364
Herb Derbyefe39bc2018-05-01 17:06:20 -04005365Elements of paint: Path_Effect, Mask_Filter, Shader, Color_Filter,
Cary Clark8032b982017-07-28 11:04:54 -04005366Image_Filter, and Draw_Looper; apply to blob.
5367
Cary Clarkce101242017-09-01 15:51:02 -04005368#Param blob Glyphs, positions, and their paints' text size, typeface, and so on ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005369#Param x horizontal offset applied to blob ##
5370#Param y vertical offset applied to blob ##
5371#Param paint blend, color, stroking, and so on, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005372
5373#Example
5374#Height 120
5375#Description
5376Paint attributes unrelated to text, like color, have no effect on paint in allocated Text_Blob.
5377Paint attributes related to text, like text size, have no effect on paint passed to drawTextBlob.
5378##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005379 void draw(SkCanvas* canvas) {
5380 SkTextBlobBuilder textBlobBuilder;
5381 SkPaint paint;
5382 paint.setTextSize(50);
5383 paint.setColor(SK_ColorRED);
Cary Clark2f466242017-12-11 16:03:17 -05005384 paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
Herb Derbyefe39bc2018-05-01 17:06:20 -04005385 const SkTextBlobBuilder::RunBuffer& run =
Cary Clarkbad5ad72017-08-03 17:14:08 -04005386 textBlobBuilder.allocRun(paint, 1, 20, 100);
5387 run.glyphs[0] = 20;
5388 sk_sp<const SkTextBlob> blob = textBlobBuilder.make();
5389 paint.setTextSize(10);
5390 paint.setColor(SK_ColorBLUE);
5391 canvas->drawTextBlob(blob.get(), 0, 0, paint);
5392 }
Cary Clark8032b982017-07-28 11:04:54 -04005393##
5394
Cary Clark2ade9972017-11-02 17:49:34 -04005395#SeeAlso drawText drawPosText drawPosTextH
Cary Clark8032b982017-07-28 11:04:54 -04005396
5397##
5398
5399# ------------------------------------------------------------------------------
5400
Herb Derbyefe39bc2018-05-01 17:06:20 -04005401#Method void drawPicture(const SkPicture* picture)
Cary Clark78de7512018-02-07 07:27:09 -05005402#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05005403#Line # draws Picture using Clip and Matrix ##
Cary Clark80247e52018-07-11 16:18:41 -04005404Draws Picture picture, using Clip and Matrix.
Cary Clark8032b982017-07-28 11:04:54 -04005405Clip and Matrix are unchanged by picture contents, as if
5406save() was called before and restore() was called after drawPicture.
5407
5408Picture records a series of draw commands for later playback.
5409
Cary Clarkbad5ad72017-08-03 17:14:08 -04005410#Param picture recorded drawing commands to play ##
Cary Clark8032b982017-07-28 11:04:54 -04005411
5412#Example
Herb Derbyefe39bc2018-05-01 17:06:20 -04005413void draw(SkCanvas* canvas) {
Cary Clarkbad5ad72017-08-03 17:14:08 -04005414 SkPictureRecorder recorder;
5415 SkCanvas* recordingCanvas = recorder.beginRecording(50, 50);
5416 for (auto color : { SK_ColorRED, SK_ColorBLUE, 0xff007f00 } ) {
5417 SkPaint paint;
5418 paint.setColor(color);
5419 recordingCanvas->drawRect({10, 10, 30, 40}, paint);
5420 recordingCanvas->translate(10, 10);
5421 recordingCanvas->scale(1.2f, 1.4f);
5422 }
5423 sk_sp<SkPicture> playback = recorder.finishRecordingAsPicture();
Cary Clarkbad5ad72017-08-03 17:14:08 -04005424 canvas->drawPicture(playback);
5425 canvas->scale(2, 2);
5426 canvas->translate(50, 0);
5427 canvas->drawPicture(playback);
Cary Clark8032b982017-07-28 11:04:54 -04005428}
5429##
5430
Cary Clark2ade9972017-11-02 17:49:34 -04005431#SeeAlso drawDrawable SkPicture SkPicture::playback
Cary Clark8032b982017-07-28 11:04:54 -04005432
5433##
5434
5435# ------------------------------------------------------------------------------
5436
Herb Derbyefe39bc2018-05-01 17:06:20 -04005437#Method void drawPicture(const sk_sp<SkPicture>& picture)
Cary Clark8032b982017-07-28 11:04:54 -04005438
Cary Clark80247e52018-07-11 16:18:41 -04005439Draws Picture picture, using Clip and Matrix.
Cary Clark8032b982017-07-28 11:04:54 -04005440Clip and Matrix are unchanged by picture contents, as if
5441save() was called before and restore() was called after drawPicture.
5442
5443Picture records a series of draw commands for later playback.
5444
Cary Clarkbad5ad72017-08-03 17:14:08 -04005445#Param picture recorded drawing commands to play ##
Cary Clark8032b982017-07-28 11:04:54 -04005446
5447#Example
Herb Derbyefe39bc2018-05-01 17:06:20 -04005448void draw(SkCanvas* canvas) {
Cary Clarkbad5ad72017-08-03 17:14:08 -04005449 SkPictureRecorder recorder;
5450 SkCanvas* recordingCanvas = recorder.beginRecording(50, 50);
5451 for (auto color : { SK_ColorRED, SK_ColorBLUE, 0xff007f00 } ) {
5452 SkPaint paint;
5453 paint.setColor(color);
5454 recordingCanvas->drawRect({10, 10, 30, 40}, paint);
5455 recordingCanvas->translate(10, 10);
5456 recordingCanvas->scale(1.2f, 1.4f);
5457 }
5458 sk_sp<SkPicture> playback = recorder.finishRecordingAsPicture();
5459 canvas->drawPicture(playback);
5460 canvas->scale(2, 2);
5461 canvas->translate(50, 0);
5462 canvas->drawPicture(playback);
Cary Clark8032b982017-07-28 11:04:54 -04005463}
5464##
5465
Cary Clark2ade9972017-11-02 17:49:34 -04005466#SeeAlso drawDrawable SkPicture SkPicture::playback
Cary Clark8032b982017-07-28 11:04:54 -04005467
5468##
5469
5470# ------------------------------------------------------------------------------
5471
5472#Method void drawPicture(const SkPicture* picture, const SkMatrix* matrix, const SkPaint* paint)
5473
Cary Clark80247e52018-07-11 16:18:41 -04005474Draws Picture picture, using Clip and Matrix; transforming picture with
Cary Clarkbad5ad72017-08-03 17:14:08 -04005475Matrix matrix, if provided; and use Paint paint Color_Alpha, Color_Filter,
5476Image_Filter, and Blend_Mode, if provided.
Cary Clark8032b982017-07-28 11:04:54 -04005477
5478matrix transformation is equivalent to: save(), concat(), drawPicture, restore().
5479paint use is equivalent to: saveLayer, drawPicture, restore().
5480
Cary Clarkbad5ad72017-08-03 17:14:08 -04005481#Param picture recorded drawing commands to play ##
5482#Param matrix Matrix to rotate, scale, translate, and so on; may be nullptr ##
5483#Param paint Paint to apply transparency, filtering, and so on; may be nullptr ##
Cary Clark8032b982017-07-28 11:04:54 -04005484
5485#Example
Herb Derbyefe39bc2018-05-01 17:06:20 -04005486void draw(SkCanvas* canvas) {
Cary Clarkbad5ad72017-08-03 17:14:08 -04005487 SkPaint paint;
5488 SkPictureRecorder recorder;
5489 SkCanvas* recordingCanvas = recorder.beginRecording(50, 50);
5490 for (auto color : { SK_ColorRED, SK_ColorBLUE, 0xff007f00 } ) {
5491 paint.setColor(color);
5492 recordingCanvas->drawRect({10, 10, 30, 40}, paint);
5493 recordingCanvas->translate(10, 10);
5494 recordingCanvas->scale(1.2f, 1.4f);
5495 }
5496 sk_sp<SkPicture> playback = recorder.finishRecordingAsPicture();
5497 const SkPicture* playbackPtr = playback.get();
5498 SkMatrix matrix;
5499 matrix.reset();
5500 for (auto alpha : { 70, 140, 210 } ) {
5501 paint.setAlpha(alpha);
5502 canvas->drawPicture(playbackPtr, &matrix, &paint);
5503 matrix.preTranslate(70, 70);
5504 }
Cary Clark8032b982017-07-28 11:04:54 -04005505}
5506##
5507
Cary Clark2ade9972017-11-02 17:49:34 -04005508#SeeAlso drawDrawable SkPicture SkPicture::playback
Cary Clark8032b982017-07-28 11:04:54 -04005509
5510##
5511
5512# ------------------------------------------------------------------------------
5513
Herb Derbyefe39bc2018-05-01 17:06:20 -04005514#Method void drawPicture(const sk_sp<SkPicture>& picture, const SkMatrix* matrix, const SkPaint* paint)
Cary Clark8032b982017-07-28 11:04:54 -04005515
Cary Clark80247e52018-07-11 16:18:41 -04005516Draws Picture picture, using Clip and Matrix; transforming picture with
Cary Clarkbad5ad72017-08-03 17:14:08 -04005517Matrix matrix, if provided; and use Paint paint Color_Alpha, Color_Filter,
5518Image_Filter, and Blend_Mode, if provided.
Cary Clark8032b982017-07-28 11:04:54 -04005519
5520matrix transformation is equivalent to: save(), concat(), drawPicture, restore().
5521paint use is equivalent to: saveLayer, drawPicture, restore().
5522
Cary Clarkbad5ad72017-08-03 17:14:08 -04005523#Param picture recorded drawing commands to play ##
5524#Param matrix Matrix to rotate, scale, translate, and so on; may be nullptr ##
5525#Param paint Paint to apply transparency, filtering, and so on; may be nullptr ##
Cary Clark8032b982017-07-28 11:04:54 -04005526
5527#Example
Herb Derbyefe39bc2018-05-01 17:06:20 -04005528void draw(SkCanvas* canvas) {
Cary Clarkbad5ad72017-08-03 17:14:08 -04005529 SkPaint paint;
5530 SkPictureRecorder recorder;
5531 SkCanvas* recordingCanvas = recorder.beginRecording(50, 50);
5532 for (auto color : { SK_ColorRED, SK_ColorBLUE, 0xff007f00 } ) {
5533 paint.setColor(color);
5534 recordingCanvas->drawRect({10, 10, 30, 40}, paint);
5535 recordingCanvas->translate(10, 10);
5536 recordingCanvas->scale(1.2f, 1.4f);
5537 }
5538 sk_sp<SkPicture> playback = recorder.finishRecordingAsPicture();
5539 SkMatrix matrix;
5540 matrix.reset();
5541 for (auto alpha : { 70, 140, 210 } ) {
5542 paint.setAlpha(alpha);
5543 canvas->drawPicture(playback, &matrix, &paint);
5544 matrix.preTranslate(70, 70);
5545 }
Cary Clark8032b982017-07-28 11:04:54 -04005546}
5547##
5548
Cary Clark2ade9972017-11-02 17:49:34 -04005549#SeeAlso drawDrawable SkPicture SkPicture::playback
Cary Clark8032b982017-07-28 11:04:54 -04005550
5551##
5552
5553# ------------------------------------------------------------------------------
5554
5555#Method void drawVertices(const SkVertices* vertices, SkBlendMode mode, const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05005556#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05005557#Line # draws Vertices, a triangle mesh ##
Cary Clark80247e52018-07-11 16:18:41 -04005558Draws Vertices vertices, a triangle mesh, using Clip and Matrix.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005559If Vertices_Texs and Vertices_Colors are defined in vertices, and Paint paint
5560contains Shader, Blend_Mode mode combines Vertices_Colors with Shader.
Cary Clark8032b982017-07-28 11:04:54 -04005561
Cary Clarkbad5ad72017-08-03 17:14:08 -04005562#Param vertices triangle mesh to draw ##
5563#Param mode combines Vertices_Colors with Shader, if both are present ##
5564#Param paint specifies the Shader, used as Vertices texture; may be nullptr ##
Cary Clark8032b982017-07-28 11:04:54 -04005565
5566#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04005567void draw(SkCanvas* canvas) {
5568 SkPaint paint;
5569 SkPoint points[] = { { 0, 0 }, { 250, 0 }, { 100, 100 }, { 0, 250 } };
5570 SkColor colors[] = { SK_ColorRED, SK_ColorBLUE, SK_ColorYELLOW, SK_ColorCYAN };
5571 auto vertices = SkVertices::MakeCopy(SkVertices::kTriangleFan_VertexMode,
5572 SK_ARRAY_COUNT(points), points, nullptr, colors);
5573 canvas->drawVertices(vertices.get(), SkBlendMode::kSrc, paint);
5574}
Cary Clark8032b982017-07-28 11:04:54 -04005575##
5576
Cary Clark2ade9972017-11-02 17:49:34 -04005577#SeeAlso drawPatch drawPicture
Cary Clark8032b982017-07-28 11:04:54 -04005578
5579##
5580
5581# ------------------------------------------------------------------------------
5582
5583#Method void drawVertices(const sk_sp<SkVertices>& vertices, SkBlendMode mode, const SkPaint& paint)
5584
Cary Clark80247e52018-07-11 16:18:41 -04005585Draws Vertices vertices, a triangle mesh, using Clip and Matrix.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005586If Vertices_Texs and Vertices_Colors are defined in vertices, and Paint paint
5587contains Shader, Blend_Mode mode combines Vertices_Colors with Shader.
Cary Clark8032b982017-07-28 11:04:54 -04005588
Cary Clarkbad5ad72017-08-03 17:14:08 -04005589#Param vertices triangle mesh to draw ##
5590#Param mode combines Vertices_Colors with Shader, if both are present ##
5591#Param paint specifies the Shader, used as Vertices texture, may be nullptr ##
Cary Clark8032b982017-07-28 11:04:54 -04005592
5593#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04005594void draw(SkCanvas* canvas) {
5595 SkPaint paint;
5596 SkPoint points[] = { { 0, 0 }, { 250, 0 }, { 100, 100 }, { 0, 250 } };
5597 SkPoint texs[] = { { 0, 0 }, { 0, 250 }, { 250, 250 }, { 250, 0 } };
5598 SkColor colors[] = { SK_ColorRED, SK_ColorBLUE, SK_ColorYELLOW, SK_ColorCYAN };
5599 paint.setShader(SkGradientShader::MakeLinear(points, colors, nullptr, 4,
5600 SkShader::kClamp_TileMode));
5601 auto vertices = SkVertices::MakeCopy(SkVertices::kTriangleFan_VertexMode,
5602 SK_ARRAY_COUNT(points), points, texs, colors);
Ruiqi Mao94d57c42018-07-02 15:20:10 -04005603 canvas->drawVertices(vertices, SkBlendMode::kDarken, paint);
5604}
5605##
5606
5607#SeeAlso drawPatch drawPicture
5608
5609##
5610
5611# ------------------------------------------------------------------------------
5612
Ruiqi Maoc97a3392018-08-15 10:44:19 -04005613#Method void drawVertices(const SkVertices* vertices, const SkVertices::Bone bones[],
5614 int boneCount, SkBlendMode mode, const SkPaint& paint)
Ruiqi Mao94d57c42018-07-02 15:20:10 -04005615
Cary Clark80247e52018-07-11 16:18:41 -04005616Draws Vertices vertices, a triangle mesh, using Clip and Matrix. Bone data is used to
Ruiqi Mao94d57c42018-07-02 15:20:10 -04005617deform vertices with bone weights.
5618If Vertices_Texs and Vertices_Colors are defined in vertices, and Paint paint
5619contains Shader, Blend_Mode mode combines Vertices_Colors with Shader.
5620The first element of bones should be an object to world space transformation matrix that
5621will be applied before performing mesh deformations. If no such transformation is needed,
5622it should be the identity matrix.
Ruiqi Maoc97a3392018-08-15 10:44:19 -04005623boneCount must be at most 80, and thus the size of bones should be at most 80.
Ruiqi Mao94d57c42018-07-02 15:20:10 -04005624
5625#Param vertices triangle mesh to draw ##
5626#Param bones bone matrix data ##
5627#Param boneCount number of bone matrices ##
5628#Param mode combines Vertices_Colors with Shader, if both are present ##
5629#Param paint specifies the Shader, used as Vertices texture, may be nullptr ##
5630
Ruiqi Maoc97a3392018-08-15 10:44:19 -04005631#NoExample
Ruiqi Mao94d57c42018-07-02 15:20:10 -04005632void draw(SkCanvas* canvas) {
5633 SkPaint paint;
5634 SkPoint points[] = { { 0, 0 }, { 250, 0 }, { 100, 100 }, { 0, 250 } };
5635 SkPoint texs[] = { { 0, 0 }, { 0, 250 }, { 250, 250 }, { 250, 0 } };
5636 SkColor colors[] = { SK_ColorRED, SK_ColorBLUE, SK_ColorYELLOW, SK_ColorCYAN };
5637 SkVertices::BoneIndices boneIndices[] = { { 0, 0, 0, 0 },
5638 { 1, 0, 0, 0 },
5639 { 2, 0, 0, 0 },
5640 { 3, 0, 0, 0 } };
5641 SkVertices::BoneWeights boneWeights[] = { { 0.0f, 0.0f, 0.0f, 0.0f },
5642 { 1.0f, 0.0f, 0.0f, 0.0f },
5643 { 1.0f, 0.0f, 0.0f, 0.0f },
5644 { 1.0f, 0.0f, 0.0f, 0.0f } };
Ruiqi Maoc97a3392018-08-15 10:44:19 -04005645 SkVertices::Bone bones[] = { {{ 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f }},
5646 {{ 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 20.0f }},
5647 {{ 1.0f, 0.0f, 0.0f, 1.0f, 50.0f, 50.0f }},
5648 {{ 1.0f, 0.0f, 0.0f, 1.0f, 20.0f, 0.0f }} };
Ruiqi Mao94d57c42018-07-02 15:20:10 -04005649 paint.setShader(SkGradientShader::MakeLinear(points, colors, nullptr, 4,
5650 SkShader::kClamp_TileMode));
5651 auto vertices = SkVertices::MakeCopy(SkVertices::kTriangleFan_VertexMode,
5652 SK_ARRAY_COUNT(points), points, texs, colors, boneIndices, boneWeights);
5653 canvas->drawVertices(vertices.get(), bones, SK_ARRAY_COUNT(bones), SkBlendMode::kDarken, paint);
5654}
5655##
5656
5657#SeeAlso drawPatch drawPicture
5658
5659##
5660
5661# ------------------------------------------------------------------------------
5662
Ruiqi Maoc97a3392018-08-15 10:44:19 -04005663#Method void drawVertices(const sk_sp<SkVertices>& vertices, const SkVertices::Bone bones[],
5664 int boneCount, SkBlendMode mode, const SkPaint& paint)
Ruiqi Mao94d57c42018-07-02 15:20:10 -04005665
Cary Clark80247e52018-07-11 16:18:41 -04005666Draws Vertices vertices, a triangle mesh, using Clip and Matrix. Bone data is used to
Ruiqi Mao94d57c42018-07-02 15:20:10 -04005667deform vertices with bone weights.
5668If Vertices_Texs and Vertices_Colors are defined in vertices, and Paint paint
5669contains Shader, Blend_Mode mode combines Vertices_Colors with Shader.
5670The first element of bones should be an object to world space transformation matrix that
5671will be applied before performing mesh deformations. If no such transformation is needed,
5672it should be the identity matrix.
Ruiqi Maoc97a3392018-08-15 10:44:19 -04005673boneCount must be at most 80, and thus the size of bones should be at most 80.
Ruiqi Mao94d57c42018-07-02 15:20:10 -04005674
5675#Param vertices triangle mesh to draw ##
5676#Param bones bone matrix data ##
5677#Param boneCount number of bone matrices ##
5678#Param mode combines Vertices_Colors with Shader, if both are present ##
5679#Param paint specifies the Shader, used as Vertices texture, may be nullptr ##
5680
Ruiqi Maoc97a3392018-08-15 10:44:19 -04005681#NoExample
Ruiqi Mao94d57c42018-07-02 15:20:10 -04005682void draw(SkCanvas* canvas) {
5683 SkPaint paint;
5684 SkPoint points[] = { { 0, 0 }, { 250, 0 }, { 100, 100 }, { 0, 250 } };
5685 SkPoint texs[] = { { 0, 0 }, { 0, 250 }, { 250, 250 }, { 250, 0 } };
5686 SkColor colors[] = { SK_ColorRED, SK_ColorBLUE, SK_ColorYELLOW, SK_ColorCYAN };
5687 SkVertices::BoneIndices boneIndices[] = { { 0, 0, 0, 0 },
5688 { 1, 0, 0, 0 },
5689 { 2, 0, 0, 0 },
5690 { 3, 0, 0, 0 } };
5691 SkVertices::BoneWeights boneWeights[] = { { 0.0f, 0.0f, 0.0f, 0.0f },
5692 { 1.0f, 0.0f, 0.0f, 0.0f },
5693 { 1.0f, 0.0f, 0.0f, 0.0f },
5694 { 1.0f, 0.0f, 0.0f, 0.0f } };
Ruiqi Maoc97a3392018-08-15 10:44:19 -04005695 SkVertices::Bone bones[] = { {{ 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f }},
5696 {{ 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 20.0f }},
5697 {{ 1.0f, 0.0f, 0.0f, 1.0f, 50.0f, 50.0f }},
5698 {{ 1.0f, 0.0f, 0.0f, 1.0f, 20.0f, 0.0f }} };
Ruiqi Mao94d57c42018-07-02 15:20:10 -04005699 paint.setShader(SkGradientShader::MakeLinear(points, colors, nullptr, 4,
5700 SkShader::kClamp_TileMode));
5701 auto vertices = SkVertices::MakeCopy(SkVertices::kTriangleFan_VertexMode,
5702 SK_ARRAY_COUNT(points), points, texs, colors, boneIndices, boneWeights);
5703 canvas->drawVertices(vertices, bones, SK_ARRAY_COUNT(bones), SkBlendMode::kDarken, paint);
Cary Clark8032b982017-07-28 11:04:54 -04005704}
5705##
5706
Cary Clark2ade9972017-11-02 17:49:34 -04005707#SeeAlso drawPatch drawPicture
Cary Clark8032b982017-07-28 11:04:54 -04005708
5709##
5710
5711# ------------------------------------------------------------------------------
5712
5713#Method void drawPatch(const SkPoint cubics[12], const SkColor colors[4],
5714 const SkPoint texCoords[4], SkBlendMode mode, const SkPaint& paint)
Cary Clark78de7512018-02-07 07:27:09 -05005715#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05005716#Line # draws Coons_Patch ##
Cary Clark8032b982017-07-28 11:04:54 -04005717
Herb Derbyefe39bc2018-05-01 17:06:20 -04005718Draws a Coons_Patch: the interpolation of four cubics with shared corners,
Cary Clark5538c132018-06-14 12:28:14 -04005719associating a color, and optionally a texture Point, with each corner.
Cary Clark8032b982017-07-28 11:04:54 -04005720
Cary Clarka560c472017-11-27 10:44:06 -05005721Coons_Patch uses Clip and Matrix, paint Shader, Color_Filter,
Cary Clarkbad5ad72017-08-03 17:14:08 -04005722Color_Alpha, Image_Filter, and Blend_Mode. If Shader is provided it is treated
Cary Clarka560c472017-11-27 10:44:06 -05005723as Coons_Patch texture; Blend_Mode mode combines Color colors and Shader if
Cary Clarkbad5ad72017-08-03 17:14:08 -04005724both are provided.
Cary Clark8032b982017-07-28 11:04:54 -04005725
Herb Derbyefe39bc2018-05-01 17:06:20 -04005726Point array cubics specifies four Cubics starting at the top-left corner,
Cary Clarkce101242017-09-01 15:51:02 -04005727in clockwise order, sharing every fourth point. The last Cubic ends at the
Cary Clarkbad5ad72017-08-03 17:14:08 -04005728first point.
Cary Clark8032b982017-07-28 11:04:54 -04005729
Cary Clarkbc5697d2017-10-04 14:31:33 -04005730Color array color associates colors with corners in top-left, top-right,
5731bottom-right, bottom-left order.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005732
5733If paint contains Shader, Point array texCoords maps Shader as texture to
Cary Clarkbc5697d2017-10-04 14:31:33 -04005734corners in top-left, top-right, bottom-right, bottom-left order.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005735
Cary Clarka523d2d2017-08-30 08:58:10 -04005736#Param cubics Path_Cubic array, sharing common points ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005737#Param colors Color array, one for each corner ##
Cary Clarkce101242017-09-01 15:51:02 -04005738#Param texCoords Point array of texture coordinates, mapping Shader to corners;
Herb Derbyefe39bc2018-05-01 17:06:20 -04005739 may be nullptr
Cary Clark579985c2017-07-31 11:48:27 -04005740#Param ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005741#Param mode Blend_Mode for colors, and for Shader if paint has one ##
5742#Param paint Shader, Color_Filter, Blend_Mode, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005743
5744#Example
5745#Image 5
Cary Clarkbad5ad72017-08-03 17:14:08 -04005746void draw(SkCanvas* canvas) {
5747 // SkBitmap source = cmbkygk;
5748 SkPaint paint;
5749 paint.setFilterQuality(kLow_SkFilterQuality);
5750 paint.setAntiAlias(true);
5751 SkPoint cubics[] = { { 3, 1 }, { 4, 2 }, { 5, 1 }, { 7, 3 },
5752 /* { 7, 3 }, */ { 6, 4 }, { 7, 5 }, { 5, 7 },
5753 /* { 5, 7 }, */ { 4, 6 }, { 3, 7 }, { 1, 5 },
5754 /* { 1, 5 }, */ { 2, 4 }, { 1, 3 }, /* { 3, 1 } */ };
5755 SkColor colors[] = { 0xbfff0000, 0xbf0000ff, 0xbfff00ff, 0xbf00ffff };
5756 SkPoint texCoords[] = { { -30, -30 }, { 162, -30}, { 162, 162}, { -30, 162} };
5757 paint.setShader(SkShader::MakeBitmapShader(source, SkShader::kClamp_TileMode,
5758 SkShader::kClamp_TileMode, nullptr));
5759 canvas->scale(15, 15);
5760 for (auto blend : { SkBlendMode::kSrcOver, SkBlendMode::kModulate, SkBlendMode::kXor } ) {
5761 canvas->drawPatch(cubics, colors, texCoords, blend, paint);
5762 canvas->translate(4, 4);
5763 }
Cary Clark8032b982017-07-28 11:04:54 -04005764}
5765##
5766
Cary Clark2ade9972017-11-02 17:49:34 -04005767#ToDo can patch use image filter? ##
5768#SeeAlso SeeAlso drawVertices drawPicture
Cary Clark8032b982017-07-28 11:04:54 -04005769
5770##
5771
5772# ------------------------------------------------------------------------------
5773
5774#Method void drawPatch(const SkPoint cubics[12], const SkColor colors[4],
Herb Derbyefe39bc2018-05-01 17:06:20 -04005775 const SkPoint texCoords[4], const SkPaint& paint)
Cary Clark8032b982017-07-28 11:04:54 -04005776
Herb Derbyefe39bc2018-05-01 17:06:20 -04005777Draws Cubic Coons_Patch: the interpolation of four cubics with shared corners,
Cary Clark5538c132018-06-14 12:28:14 -04005778associating a color, and optionally a texture Point, with each corner.
Cary Clark8032b982017-07-28 11:04:54 -04005779
Cary Clarka560c472017-11-27 10:44:06 -05005780Coons_Patch uses Clip and Matrix, paint Shader, Color_Filter,
Cary Clarkbad5ad72017-08-03 17:14:08 -04005781Color_Alpha, Image_Filter, and Blend_Mode. If Shader is provided it is treated
Cary Clarka560c472017-11-27 10:44:06 -05005782as Coons_Patch texture; Blend_Mode mode combines Color colors and Shader if
Cary Clarkbad5ad72017-08-03 17:14:08 -04005783both are provided.
Cary Clark8032b982017-07-28 11:04:54 -04005784
Herb Derbyefe39bc2018-05-01 17:06:20 -04005785Point array cubics specifies four Cubics starting at the top-left corner,
Cary Clarkce101242017-09-01 15:51:02 -04005786in clockwise order, sharing every fourth point. The last Cubic ends at the
Cary Clarkbad5ad72017-08-03 17:14:08 -04005787first point.
5788
Cary Clarkbc5697d2017-10-04 14:31:33 -04005789Color array color associates colors with corners in top-left, top-right,
5790bottom-right, bottom-left order.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005791
5792If paint contains Shader, Point array texCoords maps Shader as texture to
Cary Clarkbc5697d2017-10-04 14:31:33 -04005793corners in top-left, top-right, bottom-right, bottom-left order.
Cary Clarkbad5ad72017-08-03 17:14:08 -04005794
Cary Clarka523d2d2017-08-30 08:58:10 -04005795#Param cubics Path_Cubic array, sharing common points ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005796#Param colors Color array, one for each corner ##
Cary Clarkce101242017-09-01 15:51:02 -04005797#Param texCoords Point array of texture coordinates, mapping Shader to corners;
Herb Derbyefe39bc2018-05-01 17:06:20 -04005798 may be nullptr
Cary Clark579985c2017-07-31 11:48:27 -04005799#Param ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005800#Param paint Shader, Color_Filter, Blend_Mode, used to draw ##
Cary Clark8032b982017-07-28 11:04:54 -04005801
5802#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04005803void draw(SkCanvas* canvas) {
5804 SkPaint paint;
5805 paint.setAntiAlias(true);
5806 SkPoint cubics[] = { { 3, 1 }, { 4, 2 }, { 5, 1 }, { 7, 3 },
5807 /* { 7, 3 }, */ { 6, 4 }, { 7, 5 }, { 5, 7 },
5808 /* { 5, 7 }, */ { 4, 6 }, { 3, 7 }, { 1, 5 },
5809 /* { 1, 5 }, */ { 2, 4 }, { 1, 3 }, /* { 3, 1 } */ };
5810 SkColor colors[] = { SK_ColorRED, SK_ColorBLUE, SK_ColorYELLOW, SK_ColorCYAN };
5811 canvas->scale(30, 30);
5812 canvas->drawPatch(cubics, colors, nullptr, paint);
5813 SkPoint text[] = { {3,0.9f}, {4,2.5f}, {5,0.9f}, {7.5f,3.2f}, {5.5f,4.2f},
5814 {7.5f,5.2f}, {5,7.5f}, {4,5.9f}, {3,7.5f}, {0.5f,5.2f}, {2.5f,4.2f},
5815 {0.5f,3.2f} };
5816 paint.setTextSize(18.f / 30);
5817 paint.setTextAlign(SkPaint::kCenter_Align);
5818 for (int i = 0; i< 10; ++i) {
5819 char digit = '0' + i;
5820 canvas->drawText(&digit, 1, text[i].fX, text[i].fY, paint);
5821 }
5822 canvas->drawString("10", text[10].fX, text[10].fY, paint);
5823 canvas->drawString("11", text[11].fX, text[11].fY, paint);
5824 paint.setStyle(SkPaint::kStroke_Style);
5825 canvas->drawPoints(SkCanvas::kPolygon_PointMode, 12, cubics, paint);
5826 canvas->drawLine(cubics[11].fX, cubics[11].fY, cubics[0].fX, cubics[0].fY, paint);
Cary Clark8032b982017-07-28 11:04:54 -04005827}
5828##
5829
5830#Example
5831#Image 6
Cary Clarkbad5ad72017-08-03 17:14:08 -04005832void draw(SkCanvas* canvas) {
5833 // SkBitmap source = checkerboard;
5834 SkPaint paint;
5835 paint.setFilterQuality(kLow_SkFilterQuality);
5836 paint.setAntiAlias(true);
5837 SkPoint cubics[] = { { 3, 1 }, { 4, 2 }, { 5, 1 }, { 7, 3 },
5838 /* { 7, 3 }, */ { 6, 4 }, { 7, 5 }, { 5, 7 },
5839 /* { 5, 7 }, */ { 4, 6 }, { 3, 7 }, { 1, 5 },
5840 /* { 1, 5 }, */ { 2, 4 }, { 1, 3 }, /* { 3, 1 } */ };
5841 SkPoint texCoords[] = { { 0, 0 }, { 0, 62}, { 62, 62}, { 62, 0 } };
5842 paint.setShader(SkShader::MakeBitmapShader(source, SkShader::kClamp_TileMode,
5843 SkShader::kClamp_TileMode, nullptr));
5844 canvas->scale(30, 30);
5845 canvas->drawPatch(cubics, nullptr, texCoords, paint);
Cary Clark8032b982017-07-28 11:04:54 -04005846}
5847##
5848
Cary Clark2ade9972017-11-02 17:49:34 -04005849#ToDo can patch use image filter? ##
5850#SeeAlso SeeAlso drawVertices drawPicture
Cary Clark8032b982017-07-28 11:04:54 -04005851
5852##
5853
5854# ------------------------------------------------------------------------------
5855
5856#Method void drawAtlas(const SkImage* atlas, const SkRSXform xform[], const SkRect tex[],
5857 const SkColor colors[], int count, SkBlendMode mode, const SkRect* cullRect,
5858 const SkPaint* paint)
Cary Clark78de7512018-02-07 07:27:09 -05005859#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05005860#Line # draws sprites using Clip, Matrix, and Paint ##
Cary Clark8032b982017-07-28 11:04:54 -04005861
Cary Clark80247e52018-07-11 16:18:41 -04005862Draws a set of sprites from atlas, using Clip, Matrix, and optional Paint paint.
Cary Clarkffb3d682018-05-17 12:17:28 -04005863paint uses Anti_Alias, Color_Alpha, Color_Filter, Image_Filter, and Blend_Mode
Cary Clarkbad5ad72017-08-03 17:14:08 -04005864to draw, if present. For each entry in the array, Rect tex locates sprite in
5865atlas, and RSXform xform transforms it into destination space.
5866
Cary Clark8032b982017-07-28 11:04:54 -04005867xform, text, and colors if present, must contain count entries.
Cary Clark224c7002018-06-27 11:00:21 -04005868Optional colors are applied for each sprite using Blend_Mode mode, treating
5869sprite as source and colors as destination.
Herb Derbyefe39bc2018-05-01 17:06:20 -04005870Optional cullRect is a conservative bounds of all transformed sprites.
Cary Clarkce101242017-09-01 15:51:02 -04005871If cullRect is outside of Clip, canvas can skip drawing.
Cary Clark8032b982017-07-28 11:04:54 -04005872
Cary Clark224c7002018-06-27 11:00:21 -04005873
5874
Cary Clarkbad5ad72017-08-03 17:14:08 -04005875#Param atlas Image containing sprites ##
5876#Param xform RSXform mappings for sprites in atlas ##
5877#Param tex Rect locations of sprites in atlas ##
Cary Clark6fc50412017-09-21 12:31:06 -04005878#Param colors one per sprite, blended with sprite using Blend_Mode; may be nullptr ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005879#Param count number of sprites to draw ##
5880#Param mode Blend_Mode combining colors and sprites ##
Cary Clark6fc50412017-09-21 12:31:06 -04005881#Param cullRect bounds of transformed sprites for efficient clipping; may be nullptr ##
5882#Param paint Color_Filter, Image_Filter, Blend_Mode, and so on; may be nullptr ##
Cary Clark8032b982017-07-28 11:04:54 -04005883
5884#Example
5885#Image 3
Cary Clarkbad5ad72017-08-03 17:14:08 -04005886void draw(SkCanvas* canvas) {
5887 // SkBitmap source = mandrill;
5888 SkRSXform xforms[] = { { .5f, 0, 0, 0 }, {0, .5f, 200, 100 } };
5889 SkRect tex[] = { { 0, 0, 250, 250 }, { 0, 0, 250, 250 } };
5890 SkColor colors[] = { 0x7f55aa00, 0x7f3333bf };
5891 const SkImage* imagePtr = image.get();
5892 canvas->drawAtlas(imagePtr, xforms, tex, colors, 2, SkBlendMode::kSrcOver, nullptr, nullptr);
Cary Clark8032b982017-07-28 11:04:54 -04005893}
5894##
5895
Cary Clark2ade9972017-11-02 17:49:34 -04005896#SeeAlso drawBitmap drawImage
Cary Clark8032b982017-07-28 11:04:54 -04005897
5898##
5899
5900# ------------------------------------------------------------------------------
5901
5902#Method void drawAtlas(const sk_sp<SkImage>& atlas, const SkRSXform xform[], const SkRect tex[],
5903 const SkColor colors[], int count, SkBlendMode mode, const SkRect* cullRect,
Herb Derbyefe39bc2018-05-01 17:06:20 -04005904 const SkPaint* paint)
Cary Clark8032b982017-07-28 11:04:54 -04005905
Cary Clark80247e52018-07-11 16:18:41 -04005906Draws a set of sprites from atlas, using Clip, Matrix, and optional Paint paint.
Cary Clarkffb3d682018-05-17 12:17:28 -04005907paint uses Anti_Alias, Color_Alpha, Color_Filter, Image_Filter, and Blend_Mode
Cary Clarkbad5ad72017-08-03 17:14:08 -04005908to draw, if present. For each entry in the array, Rect tex locates sprite in
5909atlas, and RSXform xform transforms it into destination space.
5910
Cary Clark8032b982017-07-28 11:04:54 -04005911xform, text, and colors if present, must contain count entries.
5912Optional colors is applied for each sprite using Blend_Mode.
Herb Derbyefe39bc2018-05-01 17:06:20 -04005913Optional cullRect is a conservative bounds of all transformed sprites.
Cary Clarkce101242017-09-01 15:51:02 -04005914If cullRect is outside of Clip, canvas can skip drawing.
Cary Clark8032b982017-07-28 11:04:54 -04005915
Cary Clarkbad5ad72017-08-03 17:14:08 -04005916#Param atlas Image containing sprites ##
5917#Param xform RSXform mappings for sprites in atlas ##
5918#Param tex Rect locations of sprites in atlas ##
Cary Clark6fc50412017-09-21 12:31:06 -04005919#Param colors one per sprite, blended with sprite using Blend_Mode; may be nullptr ##
Cary Clarkbad5ad72017-08-03 17:14:08 -04005920#Param count number of sprites to draw ##
5921#Param mode Blend_Mode combining colors and sprites ##
Cary Clark6fc50412017-09-21 12:31:06 -04005922#Param cullRect bounds of transformed sprites for efficient clipping; may be nullptr ##
5923#Param paint Color_Filter, Image_Filter, Blend_Mode, and so on; may be nullptr ##
Cary Clark8032b982017-07-28 11:04:54 -04005924
5925#Example
5926#Image 3
Cary Clarkbad5ad72017-08-03 17:14:08 -04005927void draw(SkCanvas* canvas) {
5928 // SkBitmap source = mandrill;
5929 SkRSXform xforms[] = { { .5f, 0, 0, 0 }, {0, .5f, 200, 100 } };
5930 SkRect tex[] = { { 0, 0, 250, 250 }, { 0, 0, 250, 250 } };
5931 SkColor colors[] = { 0x7f55aa00, 0x7f3333bf };
5932 SkPaint paint;
5933 paint.setAlpha(127);
5934 canvas->drawAtlas(image, xforms, tex, colors, 2, SkBlendMode::kPlus, nullptr, &paint);
Cary Clark8032b982017-07-28 11:04:54 -04005935}
5936##
5937
5938#ToDo bug in example on cpu side, gpu looks ok ##
5939
Cary Clark2ade9972017-11-02 17:49:34 -04005940#SeeAlso drawBitmap drawImage
5941
Cary Clark8032b982017-07-28 11:04:54 -04005942##
5943
5944# ------------------------------------------------------------------------------
5945
5946#Method void drawAtlas(const SkImage* atlas, const SkRSXform xform[], const SkRect tex[], int count,
Herb Derbyefe39bc2018-05-01 17:06:20 -04005947 const SkRect* cullRect, const SkPaint* paint)
Cary Clark8032b982017-07-28 11:04:54 -04005948
Cary Clark80247e52018-07-11 16:18:41 -04005949Draws a set of sprites from atlas, using Clip, Matrix, and optional Paint paint.
Cary Clarkffb3d682018-05-17 12:17:28 -04005950paint uses Anti_Alias, Color_Alpha, Color_Filter, Image_Filter, and Blend_Mode
Cary Clarkbad5ad72017-08-03 17:14:08 -04005951to draw, if present. For each entry in the array, Rect tex locates sprite in
5952atlas, and RSXform xform transforms it into destination space.
5953
Cary Clark8032b982017-07-28 11:04:54 -04005954xform and text must contain count entries.
Herb Derbyefe39bc2018-05-01 17:06:20 -04005955Optional cullRect is a conservative bounds of all transformed sprites.
Cary Clarkce101242017-09-01 15:51:02 -04005956If cullRect is outside of Clip, canvas can skip drawing.
Cary Clark8032b982017-07-28 11:04:54 -04005957
Cary Clarkbad5ad72017-08-03 17:14:08 -04005958#Param atlas Image containing sprites ##
5959#Param xform RSXform mappings for sprites in atlas ##
5960#Param tex Rect locations of sprites in atlas ##
5961#Param count number of sprites to draw ##
Cary Clark6fc50412017-09-21 12:31:06 -04005962#Param cullRect bounds of transformed sprites for efficient clipping; may be nullptr ##
5963#Param paint Color_Filter, Image_Filter, Blend_Mode, and so on; may be nullptr ##
Cary Clark8032b982017-07-28 11:04:54 -04005964
5965#Example
5966#Image 3
Cary Clarkbad5ad72017-08-03 17:14:08 -04005967void draw(SkCanvas* canvas) {
5968 // sk_sp<SkImage> image = mandrill;
5969 SkRSXform xforms[] = { { .5f, 0, 0, 0 }, {0, .5f, 200, 100 } };
5970 SkRect tex[] = { { 0, 0, 250, 250 }, { 0, 0, 250, 250 } };
5971 const SkImage* imagePtr = image.get();
5972 canvas->drawAtlas(imagePtr, xforms, tex, 2, nullptr, nullptr);
Cary Clark8032b982017-07-28 11:04:54 -04005973}
5974##
5975
Cary Clark2ade9972017-11-02 17:49:34 -04005976#SeeAlso drawBitmap drawImage
Cary Clark8032b982017-07-28 11:04:54 -04005977
5978##
5979
5980# ------------------------------------------------------------------------------
5981
5982#Method void drawAtlas(const sk_sp<SkImage>& atlas, const SkRSXform xform[], const SkRect tex[],
Herb Derbyefe39bc2018-05-01 17:06:20 -04005983 int count, const SkRect* cullRect, const SkPaint* paint)
Cary Clark8032b982017-07-28 11:04:54 -04005984
Cary Clark80247e52018-07-11 16:18:41 -04005985Draws a set of sprites from atlas, using Clip, Matrix, and optional Paint paint.
Cary Clarkffb3d682018-05-17 12:17:28 -04005986paint uses Anti_Alias, Color_Alpha, Color_Filter, Image_Filter, and Blend_Mode
Cary Clarkbad5ad72017-08-03 17:14:08 -04005987to draw, if present. For each entry in the array, Rect tex locates sprite in
5988atlas, and RSXform xform transforms it into destination space.
5989
Cary Clark8032b982017-07-28 11:04:54 -04005990xform and text must contain count entries.
Herb Derbyefe39bc2018-05-01 17:06:20 -04005991Optional cullRect is a conservative bounds of all transformed sprites.
Cary Clarkce101242017-09-01 15:51:02 -04005992If cullRect is outside of Clip, canvas can skip drawing.
Cary Clark8032b982017-07-28 11:04:54 -04005993
Cary Clarkbad5ad72017-08-03 17:14:08 -04005994#Param atlas Image containing sprites ##
5995#Param xform RSXform mappings for sprites in atlas ##
5996#Param tex Rect locations of sprites in atlas ##
5997#Param count number of sprites to draw ##
Cary Clark6fc50412017-09-21 12:31:06 -04005998#Param cullRect bounds of transformed sprites for efficient clipping; may be nullptr ##
5999#Param paint Color_Filter, Image_Filter, Blend_Mode, and so on; may be nullptr ##
Cary Clark8032b982017-07-28 11:04:54 -04006000
6001#Example
6002#Image 3
Cary Clarkbad5ad72017-08-03 17:14:08 -04006003void draw(SkCanvas* canvas) {
6004 // sk_sp<SkImage> image = mandrill;
6005 SkRSXform xforms[] = { { 1, 0, 0, 0 }, {0, 1, 300, 100 } };
6006 SkRect tex[] = { { 0, 0, 200, 200 }, { 200, 0, 400, 200 } };
6007 canvas->drawAtlas(image, xforms, tex, 2, nullptr, nullptr);
Cary Clark8032b982017-07-28 11:04:54 -04006008}
6009##
6010
Cary Clark2ade9972017-11-02 17:49:34 -04006011#SeeAlso drawBitmap drawImage
Cary Clark8032b982017-07-28 11:04:54 -04006012
6013##
6014
6015# ------------------------------------------------------------------------------
6016
Cary Clark73fa9722017-08-29 17:36:51 -04006017#Method void drawDrawable(SkDrawable* drawable, const SkMatrix* matrix = nullptr)
Cary Clark78de7512018-02-07 07:27:09 -05006018#In Draw
Cary Clarkab2621d2018-01-30 10:08:57 -05006019#Line # draws Drawable, encapsulated drawing commands ##
Cary Clark80247e52018-07-11 16:18:41 -04006020Draws Drawable drawable using Clip and Matrix, concatenated with
Cary Clark8032b982017-07-28 11:04:54 -04006021optional matrix.
6022
Herb Derbyefe39bc2018-05-01 17:06:20 -04006023If Canvas has an asynchronous implementation, as is the case
Cary Clark8032b982017-07-28 11:04:54 -04006024when it is recording into Picture, then drawable will be referenced,
6025so that SkDrawable::draw() can be called when the operation is finalized. To force
6026immediate drawing, call SkDrawable::draw() instead.
6027
Cary Clarkbad5ad72017-08-03 17:14:08 -04006028#Param drawable custom struct encapsulating drawing commands ##
6029#Param matrix transformation applied to drawing; may be nullptr ##
Cary Clark8032b982017-07-28 11:04:54 -04006030
6031#Example
6032#Height 100
6033#Function
Cary Clarkbad5ad72017-08-03 17:14:08 -04006034struct MyDrawable : public SkDrawable {
6035 SkRect onGetBounds() override { return SkRect::MakeWH(50, 100); }
6036
6037 void onDraw(SkCanvas* canvas) override {
6038 SkPath path;
6039 path.conicTo(10, 90, 50, 90, 0.9f);
6040 SkPaint paint;
6041 paint.setColor(SK_ColorBLUE);
6042 canvas->drawRect(path.getBounds(), paint);
6043 paint.setAntiAlias(true);
6044 paint.setColor(SK_ColorWHITE);
6045 canvas->drawPath(path, paint);
6046 }
6047};
6048
6049#Function ##
6050void draw(SkCanvas* canvas) {
6051 sk_sp<SkDrawable> drawable(new MyDrawable);
6052 SkMatrix matrix;
6053 matrix.setTranslate(10, 10);
6054 canvas->drawDrawable(drawable.get(), &matrix);
Cary Clark8032b982017-07-28 11:04:54 -04006055}
6056##
6057
Cary Clark2ade9972017-11-02 17:49:34 -04006058#SeeAlso SkDrawable drawPicture
Cary Clark8032b982017-07-28 11:04:54 -04006059
6060##
6061
6062# ------------------------------------------------------------------------------
6063
6064#Method void drawDrawable(SkDrawable* drawable, SkScalar x, SkScalar y)
6065
Cary Clark80247e52018-07-11 16:18:41 -04006066Draws Drawable drawable using Clip and Matrix, offset by (x, y).
Cary Clark8032b982017-07-28 11:04:54 -04006067
Herb Derbyefe39bc2018-05-01 17:06:20 -04006068If Canvas has an asynchronous implementation, as is the case
Cary Clark8032b982017-07-28 11:04:54 -04006069when it is recording into Picture, then drawable will be referenced,
6070so that SkDrawable::draw() can be called when the operation is finalized. To force
6071immediate drawing, call SkDrawable::draw() instead.
6072
Cary Clarkbad5ad72017-08-03 17:14:08 -04006073#Param drawable custom struct encapsulating drawing commands ##
Cary Clark5538c132018-06-14 12:28:14 -04006074#Param x offset into Canvas writable pixels on x-axis ##
6075#Param y offset into Canvas writable pixels on y-axis ##
Cary Clark8032b982017-07-28 11:04:54 -04006076
6077#Example
6078#Height 100
6079#Function
Cary Clarkbad5ad72017-08-03 17:14:08 -04006080struct MyDrawable : public SkDrawable {
6081 SkRect onGetBounds() override { return SkRect::MakeWH(50, 100); }
6082
6083 void onDraw(SkCanvas* canvas) override {
6084 SkPath path;
6085 path.conicTo(10, 90, 50, 90, 0.9f);
6086 SkPaint paint;
6087 paint.setColor(SK_ColorBLUE);
6088 canvas->drawRect(path.getBounds(), paint);
6089 paint.setAntiAlias(true);
6090 paint.setColor(SK_ColorWHITE);
6091 canvas->drawPath(path, paint);
6092 }
6093};
6094
6095#Function ##
6096void draw(SkCanvas* canvas) {
6097 sk_sp<SkDrawable> drawable(new MyDrawable);
6098 canvas->drawDrawable(drawable.get(), 10, 10);
Cary Clark8032b982017-07-28 11:04:54 -04006099}
6100##
6101
Cary Clark2ade9972017-11-02 17:49:34 -04006102#SeeAlso SkDrawable drawPicture
Cary Clark8032b982017-07-28 11:04:54 -04006103
6104##
6105
6106# ------------------------------------------------------------------------------
6107
6108#Method void drawAnnotation(const SkRect& rect, const char key[], SkData* value)
Cary Clark78de7512018-02-07 07:27:09 -05006109#In Draw
6110#In Utility
Cary Clarkab2621d2018-01-30 10:08:57 -05006111#Line # associates a Rect with a key-value pair ##
Cary Clark80247e52018-07-11 16:18:41 -04006112Associates Rect on Canvas with an annotation; a key-value pair, where the key is
Cary Clark8032b982017-07-28 11:04:54 -04006113a null-terminated utf8 string, and optional value is stored as Data.
6114
Herb Derbyefe39bc2018-05-01 17:06:20 -04006115Only some canvas implementations, such as recording to Picture, or drawing to
Cary Clark8032b982017-07-28 11:04:54 -04006116Document_PDF, use annotations.
6117
Cary Clarkbad5ad72017-08-03 17:14:08 -04006118#Param rect Rect extent of canvas to annotate ##
6119#Param key string used for lookup ##
6120#Param value data holding value stored in annotation ##
Cary Clark8032b982017-07-28 11:04:54 -04006121
6122#Example
6123 #Height 1
6124 const char text[] = "Click this link!";
6125 SkRect bounds;
6126 SkPaint paint;
6127 paint.setTextSize(40);
6128 (void)paint.measureText(text, strlen(text), &bounds);
6129 const char url[] = "https://www.google.com/";
6130 sk_sp<SkData> urlData(SkData::MakeWithCString(url));
6131 canvas->drawAnnotation(bounds, "url_key", urlData.get());
6132##
6133
Cary Clark2ade9972017-11-02 17:49:34 -04006134#SeeAlso SkPicture SkDocument
Cary Clark8032b982017-07-28 11:04:54 -04006135
6136##
6137
6138# ------------------------------------------------------------------------------
6139
Herb Derbyefe39bc2018-05-01 17:06:20 -04006140#Method void drawAnnotation(const SkRect& rect, const char key[], const sk_sp<SkData>& value)
Cary Clark8032b982017-07-28 11:04:54 -04006141
Cary Clark80247e52018-07-11 16:18:41 -04006142Associates Rect on Canvas when an annotation; a key-value pair, where the key is
Cary Clark8032b982017-07-28 11:04:54 -04006143a null-terminated utf8 string, and optional value is stored as Data.
6144
Herb Derbyefe39bc2018-05-01 17:06:20 -04006145Only some canvas implementations, such as recording to Picture, or drawing to
Cary Clark8032b982017-07-28 11:04:54 -04006146Document_PDF, use annotations.
6147
Cary Clarkbad5ad72017-08-03 17:14:08 -04006148#Param rect Rect extent of canvas to annotate ##
6149#Param key string used for lookup ##
6150#Param value data holding value stored in annotation ##
Cary Clark8032b982017-07-28 11:04:54 -04006151
6152#Example
6153#Height 1
6154 const char text[] = "Click this link!";
6155 SkRect bounds;
6156 SkPaint paint;
6157 paint.setTextSize(40);
6158 (void)paint.measureText(text, strlen(text), &bounds);
6159 const char url[] = "https://www.google.com/";
6160 sk_sp<SkData> urlData(SkData::MakeWithCString(url));
6161 canvas->drawAnnotation(bounds, "url_key", urlData.get());
6162##
6163
Cary Clark2ade9972017-11-02 17:49:34 -04006164#SeeAlso SkPicture SkDocument
Cary Clark8032b982017-07-28 11:04:54 -04006165
6166##
6167
Cary Clark8032b982017-07-28 11:04:54 -04006168# ------------------------------------------------------------------------------
6169
6170#Method virtual bool isClipEmpty() const
Cary Clark78de7512018-02-07 07:27:09 -05006171#In Property
Cary Clarkab2621d2018-01-30 10:08:57 -05006172#Line # returns if Clip is empty ##
Cary Clark8032b982017-07-28 11:04:54 -04006173Returns true if Clip is empty; that is, nothing will draw.
6174
Cary Clarkbad5ad72017-08-03 17:14:08 -04006175May do work when called; it should not be called
Cary Clark8032b982017-07-28 11:04:54 -04006176more often than needed. However, once called, subsequent calls perform no
6177work until Clip changes.
6178
Cary Clarkbad5ad72017-08-03 17:14:08 -04006179#Return true if Clip is empty ##
Cary Clark8032b982017-07-28 11:04:54 -04006180
6181#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04006182 void draw(SkCanvas* canvas) {
6183 SkDebugf("clip is%s empty\n", canvas->isClipEmpty() ? "" : " not");
6184 SkPath path;
6185 canvas->clipPath(path);
6186 SkDebugf("clip is%s empty\n", canvas->isClipEmpty() ? "" : " not");
Cary Clark8032b982017-07-28 11:04:54 -04006187 }
6188 #StdOut
Cary Clarkbad5ad72017-08-03 17:14:08 -04006189 clip is not empty
Cary Clark8032b982017-07-28 11:04:54 -04006190 clip is empty
6191 ##
6192##
6193
Cary Clark2ade9972017-11-02 17:49:34 -04006194#SeeAlso isClipRect getLocalClipBounds getDeviceClipBounds
Cary Clark8032b982017-07-28 11:04:54 -04006195
6196##
6197
6198# ------------------------------------------------------------------------------
6199
6200#Method virtual bool isClipRect() const
Cary Clark78de7512018-02-07 07:27:09 -05006201#In Property
Cary Clarkab2621d2018-01-30 10:08:57 -05006202#Line # returns if Clip is Rect and not empty ##
Cary Clark8032b982017-07-28 11:04:54 -04006203Returns true if Clip is Rect and not empty.
6204Returns false if the clip is empty, or if it is not Rect.
6205
Cary Clarkbad5ad72017-08-03 17:14:08 -04006206#Return true if Clip is Rect and not empty ##
Cary Clark8032b982017-07-28 11:04:54 -04006207
6208#Example
Cary Clarkbad5ad72017-08-03 17:14:08 -04006209 void draw(SkCanvas* canvas) {
6210 SkDebugf("clip is%s rect\n", canvas->isClipRect() ? "" : " not");
6211 canvas->clipRect({0, 0, 0, 0});
6212 SkDebugf("clip is%s rect\n", canvas->isClipRect() ? "" : " not");
Cary Clark8032b982017-07-28 11:04:54 -04006213 }
6214 #StdOut
Cary Clarkbad5ad72017-08-03 17:14:08 -04006215 clip is rect
Cary Clark8032b982017-07-28 11:04:54 -04006216 clip is not rect
6217 ##
6218##
6219
Cary Clark2ade9972017-11-02 17:49:34 -04006220#SeeAlso isClipEmpty getLocalClipBounds getDeviceClipBounds
Cary Clark8032b982017-07-28 11:04:54 -04006221
6222##
6223
6224#Class SkCanvas ##
Cary Clark884dd7d2017-10-11 10:37:52 -04006225
Cary Clark8032b982017-07-28 11:04:54 -04006226#Topic Canvas ##