blob: aefbae4d33fd5dbdb10c132c37bcc7ffbbaacbac [file] [log] [blame]
Cary Clark8032b982017-07-28 11:04:54 -04001#Topic Canvas
2
3Canvas provides an interface for drawing, and how the drawing is clipped and transformed.
4Canvas contains a stack of Matrix and Clip values.
5
6Canvas and Paint together provide the state to draw into Surface or Device.
7Each Canvas draw call transforms the geometry of the object by the concatenation of all Matrix
8values in the stack.
9The transformed geometry is clipped by the intersection of all of Clip values in the stack.
10The Canvas draw calls take Paint parameter for drawing state.
11Create Paint to supply the drawing state, such as Color,
12Typeface, Paint_Text_Size, Paint_Stroke_Width, Shader and so on.
13
14To draw to a pixel-based destination, create Raster_Surface or GPU_Surface.
15Request Canvas from Surface to obtain the interface to draw.
16Canvas generated by Raster_Surface draws to memory visible to the CPU.
17Canvas generated by GPU_Surface uses Vulkan or OpenGL to draw to the GPU.
18
19Canvas can be constructed to draw to Bitmap without first creating Raster_Surface.
20This approach may be deprecated in the future.
21
22To draw to a document, obtain Canvas from SVG_Canvas, Document_PDF, or Picture_Recorder.
23Document-based Canvas and other Canvas subclasses reference Device describing the destination.
24
25#Class SkCanvas
26
27#Topic Overview
28
29#Subtopic Subtopics
30#Table
31#Legend
32# topics # description ##
33#Legend ##
34#ToDo generate a TOC here ##
35#Table ##
36#Subtopic ##
37
38#Subtopic Constants
39#Table
40#Legend
41# constants # description ##
42#Legend ##
43# Lattice::Flags # Controls Lattice transparency. ##
44# PointMode # Sets drawPoints options. ##
45# SaveLayerFlags # Sets SaveLayerRec options. ##
46# SrcRectConstraint # Sets drawImageRect options. ##
47#Table ##
48#Subtopic ##
49
50#Subtopic Structs
51#Table
52#Legend
53# struct # description ##
54#Legend ##
55# Lattice # Divides Bitmap, Image into a rectangular grid. ##
56# SaveLayerRec # Contains state to create the layer offscreen. ##
57#Table ##
58#Subtopic ##
59
60#Subtopic Constructors
61
62Create the desired type of Surface to obtain its Canvas when possible. Constructors are useful
63when no Surface is required, and some helpers implicitly create Raster_Surface.
64
65#Table
66#Legend
67# # description ##
68#Legend ##
69# SkCanvas() # No Surface, no dimensions. ##
70# SkCanvas(int width, int height, const SkSurfaceProps* = NULL) # No Surface, set dimensions, Surface_Properties. ##
71# SkCanvas(SkBaseDevice* device) # Existing Device. (SkBaseDevice is private.) ##
72# SkCanvas(const SkBitmap& bitmap) # Uses existing Bitmap. ##
73# SkCanvas(const SkBitmap& bitmap, const SkSurfaceProps& props) # Uses existing Bitmap and Surface_Properties. ##
74# MakeRasterDirect # Creates from SkImageInfo and Pixel_Storage. ##
75# MakeRasterDirectN32 # Creates from image data and Pixel_Storage. ##
76#ToDo incomplete ##
77#Table ##
78#Subtopic ##
79
80#Subtopic Member_Functions
81#Table
82#Legend
83# function # description ##
84#Legend ##
85# accessTopLayerPixels # Returns writable pixel access if available. ##
86# accessTopRasterHandle # Returns context that tracks Clip and Matrix. ##
87# clear() # Fills Clip with Color. ##
88# clipPath # Combines Clip with Path. ##
89# clipRRect # Combines Clip with Round_Rect. ##
90# clipRect # Combines Clip with Rect. ##
91# clipRegion # Combines Clip with Region. ##
92# concat() # Multiplies Matrix by Matrix. ##
93# discard() # Makes Canvas contents undefined. ##
94# drawAnnotation # Associates a Rect with a key-value pair.##
95# drawArc # Draws Arc using Clip, Matrix, and Paint.##
96# drawAtlas # Draws sprites using Clip, Matrix, and Paint.##
97# drawBitmap # Draws Bitmap at (x, y) position. ##
98# drawBitmapLattice # Draws differentially stretched Bitmap. ##
99# drawBitmapNine # Draws Nine_Patch Bitmap. ##
100# drawBitmapRect # Draws Bitmap, source Rect to destination Rect. ##
101# drawCircle # Draws Circle using Clip, Matrix, and Paint. ##
102# drawColor # Fills Clip with Color and Blend_Mode. ##
103# drawDRRect # Draws double Round_Rect stroked or filled. ##
104# drawDrawable # Draws Drawable, encapsulated drawing commands. ##
105# drawIRect # Draws IRect using Clip, Matrix, and Paint. ##
106# drawImage # Draws Image at (x, y) position. ##
107# drawImageLattice # Draws differentially stretched Image. ##
108# drawImageNine # Draws Nine_Patch Image. ##
109# drawImageRect # Draws Image, source Rect to destination Rect. ##
110# drawLine # Draws line segment between two points.##
111# drawOval # Draws Oval using Clip, Matrix, and Paint. ##
112# drawPaint # Fills Clip with Paint. ##
113# drawPatch # Draws cubic Coons patch. ##
114# drawPath # Draws Path using Clip, Matrix, and Paint. ##
115# drawPicture # Draws Picture using Clip and Matrix. ##
116# drawPoint # Draws point at (x, y) position. ##
117# drawPoints # Draws array as points, lines, polygon. ##
118# drawPosText # Draws text at array of (x, y) positions. ##
119# drawPosTextH # Draws text at x positions with common baseline. ##
120# drawRRect # Draws Round_Rect using Clip, Matrix, and Paint. ##
121# drawRect # Draws Rect using Clip, Matrix, and Paint. ##
122# drawRegion # Draws Region using Clip, Matrix, and Paint. ##
123# drawRoundRect # Draws Round_Rect using Clip, Matrix, and Paint. ##
124# drawText # Draws text at (x, y), using font advance. ##
125# drawTextBlob # Draws text with arrays of positions and Paint. ##
126# drawTextOnPath # Draws text following Path contour. ##
127# drawTextOnPathHV # Draws text following Path with offsets. ##
128# drawTextRSXform # Draws text with array of RSXform. ##
129# drawString # Draws null terminated string at (x, y) using font advance. ##
130# drawVertices # Draws Vertices, a triangle mesh. ##
131# flush() # Triggers execution of all pending draw operations. ##
132# getBaseLayerSize # Gets size of base layer in global coordinates. ##
133# getDeviceClipBounds # Returns IRect bounds of Clip. ##
134# getDrawFilter # Legacy; to be deprecated. ##
135# getGrContext # Returns GPU_Context of the GPU_Surface. ##
136# getLocalClipBounds # Returns Clip bounds in source coordinates. ##
137# getMetaData # Associates additional data with the canvas. ##
138# getProps # Copies Surface_Properties if available. ##
139# getSaveCount # Returns depth of stack containing Clip and Matrix. ##
140# getTotalMatrix # Returns Matrix. ##
141# imageInfo # Returns Image_Info for Canvas. ##
142# isClipEmpty # Returns if Clip is empty. ##
143# isClipRect # Returns if Clip is Rect and not empty. ##
144# MakeRasterDirect # Creates Canvas from SkImageInfo and pixel data. ##
145# MakeRasterDirectN32 # Creates Canvas from image specifications and pixel data. ##
146# makeSurface # Creates Surface matching SkImageInfo and SkSurfaceProps. ##
147# peekPixels # Returns if Canvas has direct access to its pixels. ##
148# quickReject # Returns if Rect is outside Clip. ##
149# readPixels # Copies and converts rectangle of pixels from Canvas. ##
150# resetMatrix # Resets Matrix to identity. ##
151# restore() # Restores changes to Clip and Matrix, pops save stack. ##
152# restoreToCount # Restores changes to Clip and Matrix to given depth. ##
153# rotate() # Rotates Matrix. ##
154# save() # Saves Clip and Matrix on stack. ##
155# saveLayer # Saves Clip and Matrix on stack; creates offscreen. ##
156# saveLayerAlpha # Saves Clip and Matrix on stack; creates offscreen; sets opacity. ##
157# saveLayerPreserveLCDTextRequests # Saves Clip and Matrix on stack; creates offscreen for LCD text. ##
158# scale() # Scales Matrix. ##
159# setAllowSimplifyClip # Experimental. ##
160# setDrawFilter # Legacy; to be deprecated. ##
161# setMatrix # Sets Matrix. ##
162# skew() # Skews Matrix. #
163# translate() # Translates Matrix. ##
164# writePixels # Copies and converts rectangle of pixels to Canvas. ##
165#Table ##
166#Subtopic ##
167
168#Topic Overview ##
169
170# ------------------------------------------------------------------------------
171
172#Method static std::unique_ptr<SkCanvas> MakeRasterDirect(const SkImageInfo& info,
173 void* pixels, size_t rowBytes)
174
175Allocates raster canvas that will draw directly into pixels.
176To access pixels after drawing, call flush() or peekPixels.
177
178#Param info Width, height, Image_Color_Type, Image_Alpha_Type, Color_Space, of Raster_Surface.
179 Width, or height, or both, may be zero.
180##
181#Param pixels Pointer to destination pixels buffer. Buffer size should be info height
182 times rowBytes times bytes required for Image_Color_Type.
183##
184#Param rowBytes The interval from one Surface row to the next; equal to or greater than
185 info width times bytes required for Image_Color_Type.
186##
187
188#Return Canvas if all parameters are valid; otherwise, nullptr.
189 Valid parameters include: info dimensions must be zero or positive, and other checks;
190 info must contain Image_Color_Type and Image_Alpha_Type supported by Raster_Surface;
191 pixels must be not be nullptr;
192 rowBytes must be zero or large enough to contain width pixels of Image_Color_Type.
193##
194
195#Example
196 #Description
197 Allocates a three by three bitmap, clears it to white, and draws a black pixel
198 in the center.
199 ##
200void draw(SkCanvas* ) {
201 SkImageInfo info = SkImageInfo::MakeN32Premul(3, 3); // device aligned, 32 bpp, premultipled
202 const size_t minRowBytes = info.minRowBytes(); // bytes used by one bitmap row
203 const size_t size = info.getSafeSize(minRowBytes); // bytes used by all rows
204 SkAutoTMalloc<SkPMColor> storage(size); // allocate storage for pixels
205 SkPMColor* pixels = storage.get(); // get pointer to allocated storage
206 // create a SkCanvas backed by a raster device, and delete it when the
207 // function goes out of scope.
208 std::unique_ptr<SkCanvas> canvas = SkCanvas::MakeRasterDirect(info, pixels, minRowBytes);
209 canvas->clear(SK_ColorWHITE); // white is unpremultiplied, in ARGB order
210 canvas->flush(); // ensure that pixels are cleared
211 SkPMColor pmWhite = pixels[0]; // the premultiplied format may vary
212 SkPaint paint; // by default, draws black
213 canvas->drawPoint(1, 1, paint); // draw in the center
214 canvas->flush(); // ensure that point was drawn
215 for (int y = 0; y < info.height(); ++y) {
216 for (int x = 0; x < info.width(); ++x) {
217 SkDebugf("%c", *pixels++ == pmWhite ? '-' : 'x');
218 }
219 SkDebugf("\n");
220 }
221}
222 #StdOut
223 ---
224 -x-
225 ---
226 ##
227##
228
229#ToDo incomplete ##
230
231#SeeAlso MakeRasterDirectN32 SkSurface::MakeRasterDirect
232##
233
234# ------------------------------------------------------------------------------
235
236#Method static std::unique_ptr<SkCanvas> MakeRasterDirectN32(int width, int height, SkPMColor* pixels,
237 size_t rowBytes)
238
239Creates Canvas with Raster_Surface with inline image specification that draws into pixels.
240Image_Color_Type is set to kN32_SkColorType.
241Image_Alpha_Type is set to kPremul_SkAlphaType.
242To access pixels after drawing, call flush() or peekPixels.
243
244#Param width Pixel column count on Raster_Surface created. Must be zero or greater. ##
245#Param height Pixel row count on Raster_Surface created. Must be zero or greater. ##
246#Param pixels Pointer to destination pixels buffer. Buffer size should be height
247 times rowBytes times four.
248##
249#Param rowBytes The interval from one Surface row to the next; equal to or greater than
250 width times four.
251##
252
253#Return Canvas if all parameters are valid; otherwise, nullptr.
254 Valid parameters include: width and height must be zero or positive;
255 pixels must be not be nullptr;
256 rowBytes must be zero or large enough to contain width pixels of Image_Color_Type.
257##
258
259#Example
260 #Description
261 Allocates a three by three bitmap, clears it to white, and draws a black pixel
262 in the center.
263 ##
264void draw(SkCanvas* ) {
265 const int width = 3;
266 const int height = 3;
267 SkPMColor pixels[height][width]; // allocate a 3x3 premultiplied bitmap on the stack
268 // create a SkCanvas backed by a raster device, and delete it when the
269 // function goes out of scope.
270 std::unique_ptr<SkCanvas> canvas = SkCanvas::MakeRasterDirectN32(
271 width,
272 height,
273 pixels[0], // top left of the bitmap
274 sizeof(pixels[0])); // byte width of the each row
275 // write a pre-multiplied value for white into all pixels in the bitmap
276 canvas->clear(SK_ColorWHITE);
277 SkPMColor pmWhite = pixels[0][0]; // the premultiplied format may vary
278 SkPaint paint; // by default, draws black
279 canvas->drawPoint(1, 1, paint); // draw in the center
280 canvas->flush(); // ensure that pixels is ready to be read
281 for (int y = 0; y < height; ++y) {
282 for (int x = 0; x < width; ++x) {
283 SkDebugf("%c", pixels[y][x] == pmWhite ? '-' : 'x');
284 }
285 SkDebugf("\n");
286 }
287}
288 #StdOut
289 ---
290 -x-
291 ---
292 ##
293##
294
295#ToDo incomplete ##
296
297##
298
299# ------------------------------------------------------------------------------
300
301#Method SkCanvas()
302
303Creates an empty canvas with no backing device/pixels, and zero
304dimensions.
305
306#Return An empty canvas. ##
307
308#Example
309
310#Description
311Passes a placeholder to a function that requires one.
312##
313
314#Function
315// Returns true if either the canvas rotates the text by 90 degrees, or the paint does.
316static void check_for_up_and_down_text(const SkCanvas* canvas, const SkPaint& paint) {
317 bool paintHasVertical = paint.isVerticalText();
318 const SkMatrix& matrix = canvas->getTotalMatrix();
319 bool matrixIsVertical = matrix.preservesRightAngles() && !matrix.isScaleTranslate();
320 SkDebugf("paint draws text %s\n", paintHasVertical != matrixIsVertical ?
321 "top to bottom" : "left to right");
322}
323
324static void check_for_up_and_down_text(const SkPaint& paint) {
325 SkCanvas canvas; // placeholder only, does not have an associated device
326 check_for_up_and_down_text(&canvas, paint);
327}
328
329##
330void draw(SkCanvas* canvas) {
331 SkPaint paint;
332 check_for_up_and_down_text(paint); // paint draws text left to right
333 paint.setVerticalText(true);
334 check_for_up_and_down_text(paint); // paint draws text top to bottom
335 paint.setVerticalText(false);
336 canvas->rotate(90);
337 check_for_up_and_down_text(canvas, paint); // paint draws text top to bottom
338}
339
340 #StdOut
341 paint draws text left to right
342 paint draws text top to bottom
343 paint draws text top to bottom
344 ##
345##
346
347#ToDo incomplete ##
348
349##
350
351# ------------------------------------------------------------------------------
352
353#Method SkCanvas(int width, int height, const SkSurfaceProps* props = NULL)
354
355Creates Canvas of the specified dimensions without a Surface.
356Used by subclasses with custom implementations for draw methods.
357
358#Param width Zero or greater. ##
359#Param height Zero or greater. ##
360#Param props The LCD striping orientation and setting for device independent fonts.
361 If nullptr, use Legacy_Font_Host settings. ##
362
363#Return Canvas placeholder with dimensions. ##
364
365#Example
366 SkCanvas canvas(10, 20); // 10 units wide, 20 units high
367 canvas.clipRect(SkRect::MakeXYWH(30, 40, 5, 10)); // clip is outside canvas' device
368 SkDebugf("canvas %s empty\n", canvas.getDeviceClipBounds().isEmpty() ? "is" : "is not");
369
370 #StdOut
371 canvas is empty
372 ##
373##
374
375#ToDo incomplete ##
376
377##
378
379# ------------------------------------------------------------------------------
380
381#Method explicit SkCanvas(SkBaseDevice* device)
382
383Construct a canvas that draws into device.
384Used by child classes of SkCanvas.
385
386#ToDo Since SkBaseDevice is private, shouldn't this be private also? ##
387
388#Param device Specifies a device for the canvas to draw into. ##
389
390#Return Canvas that can be used to draw into device. ##
391
392#Example
393#Error "Unsure how to create a meaningful example."
394 SkPDFCanvas::SkPDFCanvas(const sk_sp<SkPDFDevice>& dev)
395 : SkCanvas(dev.get()) {}
396##
397
398#ToDo either remove doc of figure out a way to fiddle it ##
399
400##
401
402# ------------------------------------------------------------------------------
403
404#Method explicit SkCanvas(const SkBitmap& bitmap)
405
406Construct a canvas that draws into bitmap.
407Sets SkSurfaceProps::kLegacyFontHost_InitType in constructed Surface.
408
409#ToDo Should be deprecated? ##
410
411#Param bitmap Width, height, Image_Color_Type, Image_Alpha_Type, and pixel storage of Raster_Surface.
412 Bitmap is copied so that subsequently editing bitmap will not affect
413 constructed Canvas.
414##
415
416#Return Canvas that can be used to draw into bitmap. ##
417
418#Example
419#Description
420The actual output depends on the installed fonts.
421##
422 SkBitmap bitmap;
423 // create a bitmap 5 wide and 11 high
424 bitmap.allocPixels(SkImageInfo::MakeN32Premul(5, 11));
425 SkCanvas canvas(bitmap);
426 canvas.clear(SK_ColorWHITE); // white is unpremultiplied, in ARGB order
427 SkPixmap pixmap; // provides guaranteed access to the drawn pixels
428 if (!canvas.peekPixels(&pixmap)) {
429 SkDebugf("peekPixels should never fail.\n");
430 }
431 const SkPMColor* pixels = pixmap.addr32(); // points to top left of bitmap
432 SkPMColor pmWhite = pixels[0]; // the premultiplied format may vary
433 SkPaint paint; // by default, draws black, 12 point text
434 canvas.drawString("!", 1, 10, paint); // 1 char at baseline (1, 10)
435 for (int y = 0; y < bitmap.height(); ++y) {
436 for (int x = 0; x < bitmap.width(); ++x) {
437 SkDebugf("%c", *pixels++ == pmWhite ? '-' : 'x');
438 }
439 SkDebugf("\n");
440 }
441
442 #StdOut
443 -----
444 --x--
445 --x--
446 --x--
447 --x--
448 --x--
449 --x--
450 -----
451 --x--
452 --x--
453 -----
454 #StdOut ##
455##
456
457#ToDo incomplete ##
458
459##
460
461#Enum ColorBehavior
462
463#ToDo exclude this during build phase
464 (use SK_BUILD_FOR_ANDROID_FRAMEWORK as exclude directive)
465##
466
467#Private
468Android framework only.
469##
470
471#Code
472 enum class ColorBehavior {
473 kLegacy,
474 };
475##
476#Const kLegacy 0
477##
478##
479
480
481# ------------------------------------------------------------------------------
482
483#Method SkCanvas(const SkBitmap& bitmap, const SkSurfaceProps& props)
484
485Construct a canvas that draws into bitmap.
486Use props to match the device characteristics, like LCD striping.
487
488#Param bitmap Width, height, Image_Color_Type, Image_Alpha_Type, and pixel storage of Raster_Surface.
489 Bitmap is copied so that subsequently editing bitmap will not affect
490 constructed Canvas.
491##
492#Param props The order and orientation of RGB striping; and whether to use
493 device independent fonts.
494##
495
496#Return Canvas that can be used to draw into bitmap. ##
497
498#Example
499#Description
500The actual output depends on the installed fonts.
501##
502 SkBitmap bitmap;
503 // create a bitmap 5 wide and 11 high
504 bitmap.allocPixels(SkImageInfo::MakeN32Premul(5, 11));
505 SkCanvas canvas(bitmap, SkSurfaceProps(0, kUnknown_SkPixelGeometry));
506 canvas.clear(SK_ColorWHITE); // white is unpremultiplied, in ARGB order
507 SkPixmap pixmap; // provides guaranteed access to the drawn pixels
508 if (!canvas.peekPixels(&pixmap)) {
509 SkDebugf("peekPixels should never fail.\n");
510 }
511 const SkPMColor* pixels = pixmap.addr32(); // points to top left of bitmap
512 SkPMColor pmWhite = pixels[0]; // the premultiplied format may vary
513 SkPaint paint; // by default, draws black, 12 point text
514 canvas.drawString("!", 1, 10, paint); // 1 char at baseline (1, 10)
515 for (int y = 0; y < bitmap.height(); ++y) {
516 for (int x = 0; x < bitmap.width(); ++x) {
517 SkDebugf("%c", *pixels++ == pmWhite ? '-' : 'x');
518 }
519 SkDebugf("\n");
520 }
521
522 #StdOut
523 -----
524 ---x-
525 ---x-
526 ---x-
527 ---x-
528 ---x-
529 ---x-
530 -----
531 ---x-
532 ---x-
533 -----
534 #StdOut ##
535##
536
537#ToDo incomplete ##
538
539##
540
541# ------------------------------------------------------------------------------
542
543#Method virtual ~SkCanvas()
544
545Draws State_Stack_Layer, if any.
546Free up resources used by Canvas.
547
548#Example
549#Error "Haven't thought of a useful example to put here."
550##
551
552#ToDo create example to show how draw happens when canvas goes out of scope ##
553
554##
555
556# ------------------------------------------------------------------------------
557
558#Method SkMetaData& getMetaData()
559
560Associates additional data with the canvas.
561The storage is freed when Canvas is deleted.
562
563#Return storage that can be read from and written to. ##
564
565#Example
566 const char* kHelloMetaData = "HelloMetaData";
567 SkCanvas canvas;
568 SkMetaData& metaData = canvas.getMetaData();
569 SkDebugf("before: %s\n", metaData.findString(kHelloMetaData));
570 metaData.setString(kHelloMetaData, "Hello!");
571 SkDebugf("during: %s\n", metaData.findString(kHelloMetaData));
572 metaData.removeString(kHelloMetaData);
573 SkDebugf("after: %s\n", metaData.findString(kHelloMetaData));
574
575 #StdOut
576 before: (null)
577 during: Hello!
578 after: (null)
579 #StdOut ##
580##
581
582#ToDo incomplete ##
583
584##
585
586# ------------------------------------------------------------------------------
587
588#Method SkImageInfo imageInfo() const
589
590Returns Image_Info for Canvas. If Canvas is not associated with Raster_Surface or
591GPU_Surface, returns SkImageInfo::SkImageInfo() is returned Image_Color_Type is set to kUnknown_SkColorType.
592
593#Return dimensions and Image_Color_Type of Canvas. ##
594
595#Example
596 SkCanvas canvas;
597 SkImageInfo canvasInfo = canvas.imageInfo();
598 SkImageInfo emptyInfo;
599 SkDebugf("emptyInfo %c= canvasInfo\n", emptyInfo == canvasInfo ? '=' : '!');
600##
601
602#ToDo incomplete ##
603
604##
605
606# ------------------------------------------------------------------------------
607
608#Method bool getProps(SkSurfaceProps* props) const
609
610If Canvas is associated with Raster_Surface or
611GPU_Surface, copies Surface_Properties and returns true. Otherwise,
612return false and leave props unchanged.
613
614#Param props Pointer to writable SkSurfaceProps. ##
615
616#Return true if Surface_Properties was copied. ##
617
618#ToDo This seems old style. Deprecate? ##
619
620#Example
621 SkBitmap bitmap;
622 SkCanvas canvas(bitmap, SkSurfaceProps(0, kRGB_V_SkPixelGeometry));
623 SkSurfaceProps surfaceProps(0, kUnknown_SkPixelGeometry);
624 SkDebugf("isRGB:%d\n", SkPixelGeometryIsRGB(surfaceProps.pixelGeometry()));
625 if (!canvas.getProps(&surfaceProps)) {
626 SkDebugf("getProps failed unexpectedly.\n");
627 }
628 SkDebugf("isRGB:%d\n", SkPixelGeometryIsRGB(surfaceProps.pixelGeometry()));
629
630 #StdOut
631 isRGB:0
632 isRGB:1
633 #StdOut ##
634##
635
636#ToDo incomplete ##
637
638##
639
640# ------------------------------------------------------------------------------
641
642#Method void flush()
643
644Triggers the immediate execution of all pending draw operations.
645If Canvas is associated with GPU_Surface, resolve all pending GPU operations.
646
647#Example
648#Error "haven't thought of a useful example to put here"
649##
650
651#ToDo incomplete ##
652
653##
654
655# ------------------------------------------------------------------------------
656
657#Method virtual SkISize getBaseLayerSize() const
658
659Gets the size of the base or root layer in global canvas coordinates. The
660origin of the base layer is always (0,0). The current drawable area may be
661smaller (due to clipping or saveLayer).
662
663#Return Integral width and height of base layer. ##
664
665#Example
666 SkBitmap bitmap;
667 bitmap.allocPixels(SkImageInfo::MakeN32Premul(20, 30));
668 SkCanvas canvas(bitmap, SkSurfaceProps(0, kUnknown_SkPixelGeometry));
669 canvas.clipRect(SkRect::MakeWH(10, 40));
670 SkIRect clipDeviceBounds = canvas.getDeviceClipBounds();
671 if (clipDeviceBounds.isEmpty()) {
672 SkDebugf("Empty clip bounds is unexpected!\n");
673 }
674 SkDebugf("clip=%d,%d\n", clipDeviceBounds.width(), clipDeviceBounds.height());
675 SkISize baseLayerSize = canvas.getBaseLayerSize();
676 SkDebugf("size=%d,%d\n", baseLayerSize.width(), baseLayerSize.height());
677
678 #StdOut
679 clip=10,30
680 size=20,30
681 ##
682##
683
684#ToDo is this the same as the width and height of surface? ##
685
686##
687
688# ------------------------------------------------------------------------------
689
690#Method sk_sp<SkSurface> makeSurface(const SkImageInfo& info, const SkSurfaceProps* props = nullptr)
691
692Creates Surface matching info and props, and associates it with Canvas.
693If Canvas is already associated with Surface, it cannot create a new Surface.
694
695#Param info Initialize Surface with width, height, Image_Color_Type, Image_Alpha_Type, and Color_Space. ##
696#Param props Use to match if provided, or use the Surface_Properties in Canvas otherwise. ##
697
698#Return Surface matching info and props, or nullptr if no match is available. ##
699
700#Example
701 sk_sp<SkSurface> surface = SkSurface::MakeRasterN32Premul(5, 6);
702 SkCanvas* smallCanvas = surface->getCanvas();
703 SkImageInfo imageInfo = SkImageInfo::MakeN32Premul(3, 4);
704 sk_sp<SkSurface> compatible = smallCanvas->makeSurface(imageInfo);
705 SkDebugf("compatible %c= nullptr\n", compatible == nullptr ? '=' : '!');
706 SkDebugf("size = %d, %d\n", compatible->width(), compatible->height());
707
708 #StdOut
709 compatible != nullptr
710 size = 3, 4
711 ##
712##
713
714#ToDo incomplete ##
715
716##
717
718# ------------------------------------------------------------------------------
719
720#Method virtual GrContext* getGrContext()
721
722Returns GPU_Context of the GPU_Surface associated with Canvas.
723
724#Return GPU_Context, if available; nullptr otherwise. ##
725
726#Example
727void draw(SkCanvas* canvas) {
728 if (canvas->getGrContext()) {
729 canvas->clear(SK_ColorRED);
730 } else {
731 canvas->clear(SK_ColorBLUE);
732 }
733}
734##
735
736#ToDo fiddle should show both CPU and GPU out ##
737
738##
739
740# ------------------------------------------------------------------------------
741
742#Method void* accessTopLayerPixels(SkImageInfo* info, size_t* rowBytes, SkIPoint* origin = NULL)
743
744Returns the pixel base address, Image_Info, rowBytes, and origin if the pixels
745can be read directly.
746The returned address is only valid
747while Canvas is in scope and unchanged. Any Canvas call or Surface call
748may invalidate the returned address and other returned values.
749
750If pixels are inaccessible, info, rowBytes, and origin are unchanged.
751
752#Param info If not nullptr, copies writable pixels' Image_Info. ##
753#Param rowBytes If not nullptr, copies writable pixels' row bytes. ##
754#Param origin If not nullptr, copies Canvas top layer origin, its top left corner. ##
755
756#Return Address of pixels, or nullptr if inaccessible. ##
757
758#Example
759void draw(SkCanvas* canvas) {
760 if (canvas->accessTopLayerPixels(nullptr, nullptr)) {
761 canvas->clear(SK_ColorRED);
762 } else {
763 canvas->clear(SK_ColorBLUE);
764 }
765}
766##
767
768#Example
769#Description
770Draws "ABC" on the device. Then draws "DEF" in an offscreen layer, and reads the
771offscreen to add a large dotted "DEF". Finally blends the offscreen with the
772device.
773
774The offscreen and blended result appear on the CPU and GPU but the large dotted
775"DEF" appear only on the CPU.
776##
777void draw(SkCanvas* canvas) {
778 SkPaint paint;
779 paint.setTextSize(100);
780 canvas->drawString("ABC", 20, 160, paint);
781 SkRect layerBounds = SkRect::MakeXYWH(32, 32, 192, 192);
782 canvas->saveLayerAlpha(&layerBounds, 128);
783 canvas->clear(SK_ColorWHITE);
784 canvas->drawString("DEF", 20, 160, paint);
785 SkImageInfo imageInfo;
786 size_t rowBytes;
787 SkIPoint origin;
788 uint32_t* access = (uint32_t*) canvas->accessTopLayerPixels(&imageInfo, &rowBytes, &origin);
789 if (access) {
790 int h = imageInfo.height();
791 int v = imageInfo.width();
792 int rowWords = rowBytes / sizeof(uint32_t);
793 for (int y = 0; y < h; ++y) {
794 int newY = (y - h / 2) * 2 + h / 2;
795 if (newY < 0 || newY >= h) {
796 continue;
797 }
798 for (int x = 0; x < v; ++x) {
799 int newX = (x - v / 2) * 2 + v / 2;
800 if (newX < 0 || newX >= v) {
801 continue;
802 }
803 if (access[y * rowWords + x] == SK_ColorBLACK) {
804 access[newY * rowWords + newX] = SK_ColorGRAY;
805 }
806 }
807 }
808
809 }
810 canvas->restore();
811}
812##
813
814#ToDo there are no callers of this that I can find. Deprecate? ##
815#ToDo fiddle should show both CPU and GPU out ##
816
817##
818
819# ------------------------------------------------------------------------------
820
821#Method SkRasterHandleAllocator::Handle accessTopRasterHandle() const
822
823Returns custom context that tracks the Matrix and Clip.
824
825Use Raster_Handle_Allocator to blend Skia drawing with custom drawing, typically performed
826by the host platform's user interface. This accessor returns the custom context created
827when SkRasterHandleAllocator::MakeCanvas creates a custom canvas with raster storage for
828the drawing destination.
829
830#Return Context of custom allocator. ##
831
832#Example
833#Description
834#ToDo ##
835##
836#Function
837 static void DeleteCallback(void*, void* context) {
838 delete (char*) context;
839 }
840
841 class CustomAllocator : public SkRasterHandleAllocator {
842 public:
843 bool allocHandle(const SkImageInfo& info, Rec* rec) override {
844 char* context = new char[4]{'s', 'k', 'i', 'a'};
845 rec->fReleaseProc = DeleteCallback;
846 rec->fReleaseCtx = context;
847 rec->fHandle = context;
848 rec->fPixels = context;
849 rec->fRowBytes = 4;
850 return true;
851 }
852
853 void updateHandle(Handle handle, const SkMatrix& ctm, const SkIRect& clip_bounds) override {
854 // apply canvas matrix and clip to custom environment
855 }
856 };
857
858##
859 void draw(SkCanvas* canvas) {
860 const SkImageInfo info = SkImageInfo::MakeN32Premul(1, 1);
861 std::unique_ptr<SkCanvas> c2 =
862 SkRasterHandleAllocator::MakeCanvas(std::unique_ptr<CustomAllocator>(
863 new CustomAllocator()), info);
864 char* context = (char*) c2->accessTopRasterHandle();
865 SkDebugf("context = %.4s\n", context);
866
867 }
868 #StdOut
869 context = skia
870 ##
871 #ToDo skstd::make_unique could not be used because def is private -- note to fix in c++14? ##
872##
873
874#SeeAlso SkRasterHandleAllocator
875
876##
877
878# ------------------------------------------------------------------------------
879
880#Method bool peekPixels(SkPixmap* pixmap)
881
882Returns true if Canvas has direct access to its pixels.
883
884Pixels are readable when Device is raster. Pixels are not readable when SkCanvas is returned from
885GPU_Surface, returned by SkDocument::beginPage, returned by SkPictureRecorder::beginRecording,
886or SkCanvas is the base of a utility class like SkDumpCanvas.
887
888pixmap pixel address is only valid while Canvas is in scope and unchanged. Any Canvas or Surface call may
889invalidate the pixmap values.
890
891#Param pixmap storage for Canvas pixel state if Canvas pixels are readable; otherwise, ignored. ##
892
893#Return true if Canvas has direct access to pixels. ##
894
895#Example
896 SkPixmap pixmap;
897 if (canvas->peekPixels(&pixmap)) {
898 SkDebugf("width=%d height=%d\n", pixmap.bounds().width(), pixmap.bounds().height());
899 }
900 #StdOut
901 width=256 height=256
902 ##
903##
904
905##
906
907# ------------------------------------------------------------------------------
908
909#Method bool readPixels(const SkImageInfo& dstInfo, void* dstPixels, size_t dstRowBytes,
910 int srcX, int srcY)
911
912Copies rectangle of pixels from Canvas into dstPixels, converting their Image_Color_Type and Image_Alpha_Type.
913Pixels are readable when Device is raster. Pixels are not readable when SkCanvas is returned from
914GPU_Surface, returned by SkDocument::beginPage, returned by SkPictureRecorder::beginRecording,
915or SkCanvas is the base of a utility class like SkDumpCanvas.
916
917Pixel values are converted only if Canvas Image_Color_Type and Image_Alpha_Type does not match dstInfo.
918Only pixels within the rectangle that intersect Canvas pixels are copied.
919dstPixels outside the rectangle intersection are unchanged.
920
921#Table
922#Legend
923# source rectangle # value ##
924##
925# left # srcX ##
926# top # srcY ##
927# width # dstInfo.width() ##
928# height # dstInfo.height() ##
929##
930
931 #Table
932#Legend
933# canvas pixel bounds # value ##
934##
935# left # 0 ##
936# top # 0 ##
937# width # imageInfo().width() ##
938# height # imageInfo().height() ##
939##
940
941Does not copy, and returns false if:
942
943#List
944# Source rectangle and canvas pixel bounds do not intersect. ##
945# Canvas pixels could not be converted to dstInfo Image_Color_Type or dstInfo Image_Alpha_Type. ##
946# Canvas pixels are not readable; for instance, Canvas is not raster, or is document-based. ##
947# dstRowBytes is too small to contain one row of pixels. ##
948##
949
950#Param dstInfo Dimensions, Image_Color_Type, and Image_Alpha_Type of dstPixels. ##
951#Param dstPixels Storage for pixels, of size dstInfo.height() times dstRowBytes. ##
952#Param dstRowBytes Size of one destination row, dstInfo.width() times pixel size. ##
953#Param srcX Offset into readable pixels in x. ##
954#Param srcY Offset into readable pixels in y. ##
955
956#Return true if pixels were copied. ##
957
958#Example
959#Description
960 Canvas returned by Raster_Surface has premultiplied pixel values.
961 clear() takes unpremultiplied input with Color_Alpha equal 0x80
962 and Color_RGB equal 0x55, 0xAA, 0xFF. Color_RGB is multipled by Color_Alpha
963 to generate premultipled value 0x802B5580. readPixels converts pixel back
964 to unpremultipled value 0x8056A9FF, introducing error.
965##
966 canvas->clear(0x8055aaff);
967 for (SkAlphaType alphaType : { kPremul_SkAlphaType, kUnpremul_SkAlphaType } ) {
968 uint32_t pixel = 0;
969 SkImageInfo info = SkImageInfo::Make(1, 1, kBGRA_8888_SkColorType, alphaType);
970 if (canvas->readPixels(info, &pixel, 4, 0, 0)) {
971 SkDebugf("pixel = %08x\n", pixel);
972 }
973 }
974
975 #StdOut
976 pixel = 802b5580
977 pixel = 8056a9ff
978 ##
979##
980
981#ToDo incomplete ##
982
983##
984
985# ------------------------------------------------------------------------------
986
987#Method bool readPixels(const SkPixmap& pixmap, int srcX, int srcY)
988
989Copies rectangle of pixels from Canvas into Pixmap, converting their Image_Color_Type and Image_Alpha_Type.
990Pixels are readable when Device is raster. Pixels are not readable when SkCanvas is returned from
991GPU_Surface, returned by SkDocument::beginPage, returned by SkPictureRecorder::beginRecording,
992or SkCanvas is the base of a utility class like SkDumpCanvas.
993
994Pixel values are converted only if Canvas Image_Color_Type and Image_Alpha_Type does not match bitmap Image_Info.
995Only Pixmap pixels within the rectangle that intersect Canvas pixels are copied.
996Pixmap pixels outside the rectangle intersection are unchanged.
997
998#Table
999#Legend
1000# source rectangle # value ##
1001##
1002# left # srcX ##
1003# top # srcY ##
1004# width # bitmap.width() ##
1005# height # bitmap.height() ##
1006##
1007
1008 #Table
1009#Legend
1010# canvas pixel bounds # value ##
1011##
1012# left # 0 ##
1013# top # 0 ##
1014# width # imageInfo().width() ##
1015# height # imageInfo().height() ##
1016##
1017
1018Does not copy, and returns false if:
1019
1020#List
1021# Source rectangle and canvas pixel bounds do not intersect. ##
1022# Canvas pixels could not be converted to bitmap Image_Color_Type or bitmap Image_Alpha_Type. ##
1023# Canvas pixels are not readable; for instance, Canvas is not raster, or is document-based. ##
1024# bitmap pixels could not be allocated. ##
1025# Bitmap_Row_Bytes is too small to contain one row of pixels. ##
1026##
1027
1028#Param pixmap Receives pixels copied from Canvas. ##
1029#Param srcX Offset into readable pixels in x. ##
1030#Param srcY Offset into readable pixels in y. ##
1031
1032#Return true if pixels were copied. ##
1033
1034#Example
1035void draw(SkCanvas* canvas) {
1036 canvas->clear(0x8055aaff);
1037 uint32_t pixels[1] = { 0 };
1038 SkPixmap pixmap(SkImageInfo::MakeN32Premul(1, 1), pixels, 4);
1039 canvas->readPixels(pixmap, 0, 0);
1040 SkDebugf("pixel = %08x\n", pixels[0]);
1041}
1042 #StdOut
1043 pixel = 802b5580
1044 ##
1045##
1046
1047#ToDo incomplete ##
1048
1049##
1050
1051# ------------------------------------------------------------------------------
1052
1053#Method bool readPixels(const SkBitmap& bitmap, int srcX, int srcY)
1054
1055Copies pixels enclosed by bitmap offset to (x, y) from Canvas into bitmap, converting their Image_Color_Type and Image_Alpha_Type.
1056Pixels are readable when Device is raster. Pixels are not readable when SkCanvas is returned from
1057GPU_Surface, returned by SkDocument::beginPage, returned by SkPictureRecorder::beginRecording,
1058or SkCanvas is the base of a utility class like SkDumpCanvas.
1059Allocates pixel storage in bitmap if needed.
1060
1061Pixel values are converted only if Canvas Image_Color_Type and Image_Alpha_Type does not match bitmap Image_Info.
1062Only pixels within the rectangle that intersect Canvas pixels are copied.
1063Bitamp pixels outside the rectangle intersection are unchanged.
1064
1065 #Table
1066#Legend
1067# canvas pixel bounds # value ##
1068##
1069# left # 0 ##
1070# top # 0 ##
1071# width # imageInfo().width() ##
1072# height # imageInfo().height() ##
1073##
1074
1075Does not copy, and returns false if:
1076
1077#List
1078# Bounds formed by (x, y) and bitmap (width, height) and canvas pixel bounds do not intersect. ##
1079# Canvas pixels could not be converted to bitmap Image_Color_Type or bitmap Image_Alpha_Type. ##
1080# Canvas pixels are not readable; for instance, Canvas is not raster, or is document-based. ##
1081# bitmap pixels could not be allocated. ##
1082# Bitmap_Row_Bytes is too small to contain one row of pixels. ##
1083##
1084
1085#Param bitmap Receives pixels copied from Canvas. ##
1086#Param srcX Offset into readable pixels in x. ##
1087#Param srcY Offset into readable pixels in y. ##
1088
1089#Return true if pixels were copied. ##
1090
1091#Example
1092void draw(SkCanvas* canvas) {
1093 canvas->clear(0x8055aaff);
1094 SkBitmap bitmap;
1095 bitmap.allocPixels(SkImageInfo::MakeN32Premul(1, 1));
1096 canvas->readPixels(bitmap, 0, 0);
1097 SkDebugf("pixel = %08x\n", bitmap.getAddr32(0, 0)[0]);
1098}
1099 #StdOut
1100 pixel = 802b5580
1101 ##
1102##
1103
1104#ToDo incomplete ##
1105
1106##
1107
1108# ------------------------------------------------------------------------------
1109
1110#Method bool writePixels(const SkImageInfo& info, const void* pixels, size_t rowBytes, int x, int y)
1111
1112Copies to Canvas pixels, ignoring the Matrix and Clip, converting to match
1113info Image_Color_Type and info Image_Alpha_Type.
1114
1115Pixel values are converted only if Canvas Image_Color_Type and Image_Alpha_Type does not match info.
1116Only pixels within the source rectangle that intersect Canvas pixel bounds are copied.
1117Canvas pixels outside the rectangle intersection are unchanged.
1118
1119#Table
1120#Legend
1121# source rectangle # value ##
1122##
1123# left # x ##
1124# top # y ##
1125# width # info.width() ##
1126# height # info.height() ##
1127##
1128
1129 #Table
1130#Legend
1131# canvas pixel bounds # value ##
1132##
1133# left # 0 ##
1134# top # 0 ##
1135# width # imageInfo().width() ##
1136# height # imageInfo().height() ##
1137##
1138
1139Does not copy, and returns false if:
1140
1141#List
1142# Source rectangle and canvas pixel bounds do not intersect. ##
1143# pixels could not be converted to Canvas Image_Color_Type or Canvas Image_Alpha_Type. ##
1144# Canvas pixels are not writable; for instance, Canvas is document-based. ##
1145# rowBytes is too small to contain one row of pixels. ##
1146##
1147
1148#Param info Dimensions, Image_Color_Type, and Image_Alpha_Type of pixels. ##
1149#Param pixels Pixels to copy, of size info.height() times rowBytes. ##
1150#Param rowBytes Offset from one row to the next, usually info.width() times pixel size. ##
1151#Param x Offset into Canvas writable pixels in x. ##
1152#Param y Offset into Canvas writable pixels in y. ##
1153
1154#Return true if pixels were written to Canvas. ##
1155
1156#Example
1157 SkImageInfo imageInfo = SkImageInfo::MakeN32(256, 1, kPremul_SkAlphaType);
1158 for (int y = 0; y < 256; ++y) {
1159 uint32_t pixels[256];
1160 for (int x = 0; x < 256; ++x) {
1161 pixels[x] = SkColorSetARGB(x, x + y, x, x - y);
1162 }
1163 canvas->writePixels(imageInfo, &pixels, sizeof(pixels), 0, y);
1164 }
1165##
1166
1167#ToDo incomplete ##
1168
1169##
1170
1171# ------------------------------------------------------------------------------
1172
1173#Method bool writePixels(const SkBitmap& bitmap, int x, int y)
1174
1175Writes to Canvas pixels, ignoring the Matrix and Clip, converting to match
1176bitmap Image_Color_Type and bitmap Image_Alpha_Type.
1177
1178Pixel values are converted only if Canvas Image_Color_Type and Image_Alpha_Type does not match bitmap.
1179Only pixels within the source rectangle that intersect Canvas pixel bounds are copied.
1180Canvas pixels outside the rectangle intersection are unchanged.
1181
1182#Table
1183#Legend
1184# source rectangle # value ##
1185##
1186# left # x ##
1187# top # y ##
1188# width # bitmap.width() ##
1189# height # bitmap.height() ##
1190##
1191
1192 #Table
1193#Legend
1194# canvas pixel bounds # value ##
1195##
1196# left # 0 ##
1197# top # 0 ##
1198# width # imageInfo().width() ##
1199# height # imageInfo().height() ##
1200##
1201
1202Does not copy, and returns false if:
1203
1204#List
1205# Source rectangle and Canvas pixel bounds do not intersect. ##
1206# bitmap does not have allocated pixels. ##
1207# bitmap pixels could not be converted to Canvas Image_Color_Type or Canvas Image_Alpha_Type. ##
1208# Canvas pixels are not writable; for instance, Canvas is document-based. ##
1209# bitmap pixels are inaccessible; for instance, bitmap wraps a texture. ##
1210##
1211
1212#Param bitmap Provides pixels copied to Canvas. ##
1213#Param x Offset into Canvas writable pixels in x. ##
1214#Param y Offset into Canvas writable pixels in y. ##
1215
1216#Return true if pixels were written to Canvas. ##
1217
1218#Example
1219void draw(SkCanvas* canvas) {
1220 SkImageInfo imageInfo = SkImageInfo::MakeN32Premul(2, 2);
1221 SkBitmap bitmap;
1222 bitmap.setInfo(imageInfo);
1223 uint32_t pixels[4];
1224 bitmap.setPixels(pixels);
1225 for (int y = 0; y < 256; y += 2) {
1226 for (int x = 0; x < 256; x += 2) {
1227 pixels[0] = SkColorSetRGB(x, y, x | y);
1228 pixels[1] = SkColorSetRGB(x ^ y, y, x);
1229 pixels[2] = SkColorSetRGB(x, x & y, y);
1230 pixels[3] = SkColorSetRGB(~x, ~y, x);
1231 canvas->writePixels(bitmap, x, y);
1232 }
1233 }
1234}
1235##
1236
1237#ToDo incomplete ##
1238
1239##
1240
1241# ------------------------------------------------------------------------------
1242#Topic State_Stack
1243
1244Canvas maintains a stack of state that allows hierarchical drawing, commonly used
1245to implement windows and views. The initial state has an identity matrix and and an infinite clip.
1246Even with a wide-open clip, drawing is constrained by the bounds of the
1247Canvas Surface or Device.
1248
1249Canvas savable state consists of Clip, Matrix, and Draw_Filter.
1250Clip describes the area that may be drawn to.
1251Matrix transforms the geometry.
1252Draw_Filter (deprecated on most platforms) modifies the paint before drawing.
1253
1254save(), saveLayer, saveLayerPreserveLCDTextRequests, and saveLayerAlpha
1255save state and return the depth of the stack.
1256
1257restore() and restoreToCount revert state to its value when saved.
1258
1259Each state on the stack intersects Clip with the previous Clip,
1260and concatenates Matrix with the previous Matrix.
1261The intersected Clip makes the drawing area the same or smaller;
1262the concatenated Matrix may move the origin and potentially scale or rotate
1263the coordinate space.
1264
1265Canvas does not require balancing the state stack but it is a good idea
1266to do so. Calling save() without restore() will eventually cause Skia to fail;
1267mismatched save() and restore() create hard to find bugs.
1268
1269It is not possible to use state to draw outside of the clip defined by the
1270previous state.
1271
1272#Example
1273#Description
1274Draw to ever smaller clips; then restore drawing to full canvas.
1275Note that the second clipRect is not permitted to enlarge Clip.
1276##
1277#Height 160
1278void draw(SkCanvas* canvas) {
1279 SkPaint paint;
1280 canvas->save(); // records stack depth to restore
1281 canvas->clipRect(SkRect::MakeWH(100, 100)); // constrains drawing to clip
1282 canvas->clear(SK_ColorRED); // draws to limit of clip
1283 canvas->save(); // records stack depth to restore
1284 canvas->clipRect(SkRect::MakeWH(50, 150)); // Rect below 100 is ignored
1285 canvas->clear(SK_ColorBLUE); // draws to smaller clip
1286 canvas->restore(); // enlarges clip
1287 canvas->drawLine(20, 20, 150, 150, paint); // line below 100 is not drawn
1288 canvas->restore(); // enlarges clip
1289 canvas->drawLine(150, 20, 50, 120, paint); // line below 100 is drawn
1290}
1291##
1292
1293Each Clip uses the current Matrix for its coordinates.
1294
1295#Example
1296#Description
1297While clipRect is given the same rectangle twice, Matrix makes the second
1298clipRect draw at half the size of the first.
1299##
1300#Height 128
1301void draw(SkCanvas* canvas) {
1302 canvas->clipRect(SkRect::MakeWH(100, 100));
1303 canvas->clear(SK_ColorRED);
1304 canvas->scale(.5, .5);
1305 canvas->clipRect(SkRect::MakeWH(100, 100));
1306 canvas->clear(SK_ColorBLUE);
1307}
1308##
1309
1310#SeeAlso save() saveLayer saveLayerPreserveLCDTextRequests saveLayerAlpha restore() restoreToCount
1311
1312#Method int save()
1313
1314Saves Matrix, Clip, and Draw_Filter (Draw_Filter deprecated on most platforms).
1315Calling restore() discards changes to Matrix, Clip, and Draw_Filter,
1316restoring the Matrix, Clip, and Draw_Filter to their state when save() was called.
1317
1318Matrix may be changed by translate(), scale(), rotate(), skew(), concat(), setMatrix, and resetMatrix.
1319Clip may be changed by clipRect, clipRRect, clipPath, clipRegion.
1320
1321Saved Canvas state is put on a stack; multiple calls to save() should be balance by an equal number of
1322calls to restore().
1323
1324Call restoreToCount with result to restore this and subsequent saves.
1325
1326#Return Depth of saved stack. ##
1327
1328#Example
1329#Description
1330The black square is translated 50 pixels down and to the right.
1331Restoring Canvas state removes translate() from Canvas stack;
1332the red square is not translated, and is drawn at the origin.
1333##
1334#Height 100
1335void draw(SkCanvas* canvas) {
1336 SkPaint paint;
1337 SkRect rect = { 0, 0, 25, 25 };
1338 canvas->drawRect(rect, paint);
1339 canvas->save();
1340 canvas->translate(50, 50);
1341 canvas->drawRect(rect, paint);
1342 canvas->restore();
1343 paint.setColor(SK_ColorRED);
1344 canvas->drawRect(rect, paint);
1345}
1346##
1347
1348#ToDo incomplete ##
1349
1350##
1351
1352# ------------------------------------------------------------------------------
1353#Subtopic Layer
1354
1355Layer allocates a temporary offscreen Bitmap to draw into. When the drawing is complete,
1356the Bitmap is drawn into the Canvas.
1357
1358Layer is saved in a stack along with other saved state. When state with a Layer
1359is restored, the offscreen Bitmap is drawn into the previous layer.
1360
1361Layer may be initialized with the contents of the previous layer. When Layer is
1362restored, its Bitmap can be modified by Paint passed to Layer to apply Color_Alpha,
1363Color_Filter, Image_Filter, and Blend_Mode.
1364
1365#Method int saveLayer(const SkRect* bounds, const SkPaint* paint)
1366
1367Saves Matrix, Clip, and Draw_Filter (Draw_Filter deprecated on most platforms),
1368and allocates an offscreen Bitmap for subsequent drawing.
1369Calling restore() discards changes to Matrix, Clip, and Draw_Filter,
1370and draws the offscreen bitmap.
1371The Matrix, Clip, and Draw_Filter are restored to their state when save() was called.
1372
1373Matrix may be changed by translate(), scale(), rotate(), skew(), concat(), setMatrix, and resetMatrix.
1374Clip may be changed by clipRect, clipRRect, clipPath, clipRegion.
1375
1376Rect bounds suggests but does not define the offscreen size. To clip drawing to a specific rectangle,
1377use clipRect.
1378
1379Optional Paint paint applies Color_Alpha, Color_Filter, Image_Filter, and Blend_Mode when restore() is called.
1380
1381Call restoreToCount with result to restore this and subsequent saves.
1382
1383#Param bounds Used as a hint to limit the size of the offscreen; may be nullptr. ##
1384#Param paint Used when restore() is called to draw the offscreen; may be nullptr. ##
1385
1386#Return Depth of saved stack. ##
1387
1388#Example
1389#Description
1390Rectangles are blurred by Image_Filter when restore() draws offscreen to main Canvas.
1391##
1392#Height 128
1393void draw(SkCanvas* canvas) {
1394 SkPaint paint, blur;
1395 blur.setImageFilter(SkImageFilter::MakeBlur(3, 3, nullptr));
1396 canvas->saveLayer(nullptr, &blur);
1397 SkRect rect = { 25, 25, 50, 50};
1398 canvas->drawRect(rect, paint);
1399 canvas->translate(50, 50);
1400 paint.setColor(SK_ColorRED);
1401 canvas->drawRect(rect, paint);
1402 canvas->restore();
1403}
1404##
1405
1406#ToDo incomplete ##
1407
1408##
1409
1410#Method int saveLayer(const SkRect& bounds, const SkPaint* paint)
1411
1412Saves Matrix, Clip, and Draw_Filter (Draw_Filter deprecated on most platforms),
1413and allocates an offscreen Bitmap for subsequent drawing.
1414Calling restore() discards changes to Matrix, Clip, and Draw_Filter,
1415and draws the offscreen Bitmap.
1416The Matrix, Clip, and Draw_Filter are restored to their state when save() was called.
1417
1418Matrix may be changed by translate(), scale(), rotate(), skew(), concat(), setMatrix, and resetMatrix.
1419Clip may be changed by clipRect, clipRRect, clipPath, clipRegion.
1420
1421bounds suggests but does not define the offscreen size. To clip drawing to a specific rectangle,
1422use clipRect.
1423
1424Optional Paint paint applies Color_Alpha, Color_Filter, Image_Filter, and Blend_Mode when restore() is called.
1425
1426Call restoreToCount with result to restore this and subsequent saves.
1427
1428#Param bounds Used as a hint to limit the size of the offscreen; may be nullptr. ##
1429#Param paint Used when restore() is called to draw the offscreen; may be nullptr. ##
1430
1431#Return Depth of saved stack. ##
1432
1433#Example
1434#Description
1435Rectangles are blurred by Image_Filter when restore() draws offscreen to main Canvas.
1436The red rectangle is clipped; it does not fully fit on the offscreen Canvas.
1437Image_Filter blurs past edge of offscreen so red rectangle is blurred on all sides.
1438##
1439#Height 128
1440void draw(SkCanvas* canvas) {
1441 SkPaint paint, blur;
1442 blur.setImageFilter(SkImageFilter::MakeBlur(3, 3, nullptr));
1443 canvas->saveLayer(SkRect::MakeWH(90, 90), &blur);
1444 SkRect rect = { 25, 25, 50, 50};
1445 canvas->drawRect(rect, paint);
1446 canvas->translate(50, 50);
1447 paint.setColor(SK_ColorRED);
1448 canvas->drawRect(rect, paint);
1449 canvas->restore();
1450}
1451##
1452
1453#ToDo incomplete ##
1454
1455##
1456
1457#Method int saveLayerPreserveLCDTextRequests(const SkRect* bounds, const SkPaint* paint)
1458
1459Saves Matrix, Clip, and Draw_Filter (Draw_Filter deprecated on most platforms),
1460and allocates an offscreen bitmap for subsequent drawing.
1461LCD_Text is preserved when the offscreen is drawn to the prior layer.
1462
1463Draw text on an opaque background so that LCD_Text blends correctly with the prior layer.
1464
1465Calling restore() discards changes to Matrix, Clip, and Draw_Filter,
1466and draws the offscreen bitmap.
1467The Matrix, Clip, and Draw_Filter are restored to their state when save() was called.
1468
1469Matrix may be changed by translate(), scale(), rotate(), skew(), concat(), setMatrix, and resetMatrix.
1470Clip may be changed by clipRect, clipRRect, clipPath, clipRegion.
1471
1472Draw LCD_Text on an opaque background to get good results.
1473
1474bounds suggests but does not define the offscreen size. To clip drawing to a specific rectangle,
1475use clipRect.
1476
1477paint modifies how the offscreen overlays the prior layer. Color_Alpha, Blend_Mode,
1478Color_Filter, Draw_Looper, Image_Filter, and Mask_Filter, affect the offscreen draw.
1479
1480Call restoreToCount with result to restore this and subsequent saves.
1481
1482#Param bounds Used as a hint to limit the size of the offscreen; may be nullptr. ##
1483#Param paint Used when restore() is called to draw the offscreen; may be nullptr. ##
1484
1485#Return Depth of saved stack. ##
1486
1487#Example
1488 SkPaint paint;
1489 paint.setAntiAlias(true);
1490 paint.setLCDRenderText(true);
1491 paint.setTextSize(20);
1492 for (auto preserve : { false, true } ) {
1493 preserve ? canvas->saveLayerPreserveLCDTextRequests(nullptr, nullptr)
1494 : canvas->saveLayer(nullptr, nullptr);
1495 SkPaint p;
1496 p.setColor(SK_ColorWHITE);
1497 // Comment out the next line to draw on a non-opaque background.
1498 canvas->drawRect(SkRect::MakeLTRB(25, 40, 200, 70), p);
1499 canvas->drawString("Hamburgefons", 30, 60, paint);
1500
1501 p.setColor(0xFFCCCCCC);
1502 canvas->drawRect(SkRect::MakeLTRB(25, 70, 200, 100), p);
1503 canvas->drawString("Hamburgefons", 30, 90, paint);
1504
1505 canvas->restore();
1506 canvas->translate(0, 80);
1507 }
1508 ##
1509
1510#ToDo incomplete ##
1511
1512##
1513
1514#Method int saveLayerAlpha(const SkRect* bounds, U8CPU alpha)
1515
1516Saves Matrix, Clip, and Draw_Filter (Draw_Filter deprecated on most platforms),
1517and allocates an offscreen bitmap for subsequent drawing.
1518
1519Calling restore() discards changes to Matrix, Clip, and Draw_Filter,
1520and blends the offscreen bitmap with alpha opacity onto the prior layer.
1521The Matrix, Clip, and Draw_Filter are restored to their state when save() was called.
1522
1523Matrix may be changed by translate(), scale(), rotate(), skew(), concat(), setMatrix, and resetMatrix.
1524Clip may be changed by clipRect, clipRRect, clipPath, clipRegion.
1525
1526bounds suggests but does not define the offscreen size. To clip drawing to a specific rectangle,
1527use clipRect.
1528
1529Call restoreToCount with result to restore this and subsequent saves.
1530
1531#Param bounds Used as a hint to limit the size of the offscreen; may be nullptr. ##
1532#Param alpha The opacity of the offscreen; zero is fully transparent, 255 is fully opaque. ##
1533
1534#Return Depth of saved stack. ##
1535
1536#Example
1537 SkPaint paint;
1538 paint.setColor(SK_ColorRED);
1539 canvas->drawCircle(50, 50, 50, paint);
1540 canvas->saveLayerAlpha(nullptr, 128);
1541 paint.setColor(SK_ColorBLUE);
1542 canvas->drawCircle(100, 50, 50, paint);
1543 paint.setColor(SK_ColorGREEN);
1544 paint.setAlpha(128);
1545 canvas->drawCircle(75, 90, 50, paint);
1546 canvas->restore();
1547##
1548
1549#ToDo incomplete ##
1550
1551##
1552
1553#Enum SaveLayerFlags
1554
1555#Code
1556 enum {
1557 kIsOpaque_SaveLayerFlag = 1 << 0,
1558 kPreserveLCDText_SaveLayerFlag = 1 << 1,
1559 kInitWithPrevious_SaveLayerFlag = 1 << 2,
1560 };
1561
1562 typedef uint32_t SaveLayerFlags;
1563##
1564
1565SaveLayerFlags provides options that may be used in any combination in SaveLayerRec,
1566defining how the offscreen allocated by saveLayer operates.
1567
1568#Const kIsOpaque_SaveLayerFlag 1
1569 Creates offscreen without transparency. Flag is ignored if layer Paint contains
1570 Image_Filter or Color_Filter.
1571##
1572
1573#Const kPreserveLCDText_SaveLayerFlag 2
1574 Creates offscreen for LCD text. Flag is ignored if layer Paint contains
1575 Image_Filter or Color_Filter.
1576##
1577
1578#Const kInitWithPrevious_SaveLayerFlag 4
1579 Initializes offscreen with the contents of the previous layer.
1580##
1581
1582#Example
1583#Height 160
1584#Description
1585Canvas layer captures red and blue circles scaled up by four.
1586scalePaint blends offscreen back with transparency.
1587##
1588void draw(SkCanvas* canvas) {
1589 SkPaint redPaint, bluePaint, scalePaint;
1590 redPaint.setColor(SK_ColorRED);
1591 canvas->drawCircle(21, 21, 8, redPaint);
1592 bluePaint.setColor(SK_ColorBLUE);
1593 canvas->drawCircle(31, 21, 8, bluePaint);
1594 SkMatrix matrix;
1595 matrix.setScale(4, 4);
1596 scalePaint.setAlpha(0x40);
1597 scalePaint.setImageFilter(
1598 SkImageFilter::MakeMatrixFilter(matrix, kNone_SkFilterQuality, nullptr));
1599 SkCanvas::SaveLayerRec saveLayerRec(nullptr, &scalePaint,
1600 SkCanvas::kInitWithPrevious_SaveLayerFlag);
1601 canvas->saveLayer(saveLayerRec);
1602 canvas->restore();
1603}
1604##
1605
1606#ToDo incomplete ##
1607
1608#Enum ##
1609
1610#Struct SaveLayerRec
1611
1612#Code
1613 struct SaveLayerRec {
1614 SaveLayerRec*(...
1615
1616 const SkRect* fBounds;
1617 const SkPaint* fPaint;
1618 const SkImageFilter* fBackdrop;
1619 SaveLayerFlags fSaveLayerFlags;
1620 };
1621##
1622
1623SaveLayerRec contains the state used to create the layer offscreen.
1624
1625#Member const SkRect* fBounds
1626 fBounds is used as a hint to limit the size of the offscreen; may be nullptr.
1627 fBounds suggests but does not define the offscreen size. To clip drawing to a specific rectangle,
1628 use clipRect.
1629##
1630
1631#Member const SkPaint* fPaint
1632 fPaint modifies how the offscreen overlays the prior layer; may be nullptr. Color_Alpha, Blend_Mode,
1633 Color_Filter, Draw_Looper, Image_Filter, and Mask_Filter affect the offscreen draw.
1634##
1635
1636#Member const SkImageFilter* fBackdrop
1637 fBackdrop applies Image_Filter to the prior layer when copying to the layer offscreen; may be nullptr.
1638 Use kInitWithPrevious_SaveLayerFlag to copy the prior layer without a Image_Filter.
1639##
1640
1641#Member const SkImage* fClipMask
1642#ToDo header documentation is incomplete ##
1643 may be nullptr.
1644##
1645
1646#Member const SkMatrix* fClipMatrix
1647#ToDo header documentation is incomplete ##
1648 may be nullptr.
1649##
1650
1651#Member SaveLayerFlags fSaveLayerFlags
1652 fSaveLayerFlags are used to create layer offscreen without transparency, create layer offscreen for
1653 LCD text, and to create layer offscreen with the contents of the previous layer.
1654##
1655
1656#Example
1657#Height 160
1658#Description
1659Canvas layer captures a red anti-aliased circle and a blue aliased circle scaled up by four.
1660After drawing another unscaled red circle on top, the offscreen is transferred to the main canvas.
1661##
1662void draw(SkCanvas* canvas) {
1663 SkPaint redPaint, bluePaint;
1664 redPaint.setAntiAlias(true);
1665 redPaint.setColor(SK_ColorRED);
1666 canvas->drawCircle(21, 21, 8, redPaint);
1667 bluePaint.setColor(SK_ColorBLUE);
1668 canvas->drawCircle(31, 21, 8, bluePaint);
1669 SkMatrix matrix;
1670 matrix.setScale(4, 4);
1671 auto scaler = SkImageFilter::MakeMatrixFilter(matrix, kNone_SkFilterQuality, nullptr);
1672 SkCanvas::SaveLayerRec saveLayerRec(nullptr, nullptr, scaler.get(), 0);
1673 canvas->saveLayer(saveLayerRec);
1674 canvas->drawCircle(125, 85, 8, redPaint);
1675 canvas->restore();
1676}
1677##
1678
1679#Method SaveLayerRec()
1680
1681Sets fBounds, fPaint, and fBackdrop to nullptr. Clears fSaveLayerFlags.
1682
1683#Return empty SaveLayerRec. ##
1684
1685#Example
1686 SkCanvas::SaveLayerRec rec1;
1687 rec1.fSaveLayerFlags = SkCanvas::kIsOpaque_SaveLayerFlag;
1688 SkCanvas::SaveLayerRec rec2(nullptr, nullptr, SkCanvas::kIsOpaque_SaveLayerFlag);
1689 SkDebugf("rec1 %c= rec2\n", rec1.fBounds == rec2.fBounds
1690 && rec1.fPaint == rec2.fPaint
1691 && rec1.fBackdrop == rec2.fBackdrop
1692 && rec1.fSaveLayerFlags == rec2.fSaveLayerFlags ? '=' : '!');
1693 #StdOut
1694 rec1 == rec2
1695 ##
1696##
1697
1698##
1699
1700#Method SaveLayerRec(const SkRect* bounds, const SkPaint* paint, SaveLayerFlags saveLayerFlags = 0)
1701
1702Sets fBounds, fPaint, and fSaveLayerFlags; sets fBackdrop to nullptr.
1703
1704#Param bounds Offscreen dimensions; may be nullptr. ##
1705#Param paint Applied to offscreen when overlaying prior layer; may be nullptr. ##
1706#Param saveLayerFlags SaveLayerRec options to modify offscreen. ##
1707
1708#Return SaveLayerRec with empty backdrop. ##
1709
1710#Example
1711 SkCanvas::SaveLayerRec rec1;
1712 SkCanvas::SaveLayerRec rec2(nullptr, nullptr);
1713 SkDebugf("rec1 %c= rec2\n", rec1.fBounds == rec2.fBounds
1714 && rec1.fPaint == rec2.fPaint
1715 && rec1.fBackdrop == rec2.fBackdrop
1716 && rec1.fSaveLayerFlags == rec2.fSaveLayerFlags ? '=' : '!');
1717 #StdOut
1718 rec1 == rec2
1719 ##
1720##
1721
1722##
1723
1724#Method SaveLayerRec(const SkRect* bounds, const SkPaint* paint, const SkImageFilter* backdrop,
1725 SaveLayerFlags saveLayerFlags)
1726
1727Sets fBounds, fPaint, fBackdrop, and fSaveLayerFlags.
1728
1729#Param bounds Offscreen dimensions; may be nullptr. ##
1730#Param paint Applied to offscreen when overlaying prior layer; may be nullptr. ##
1731#Param backdrop Copies prior layer to offscreen with Image_Filter; may be nullptr. ##
1732#Param saveLayerFlags SaveLayerRec options to modify offscreen. ##
1733
1734#Return SaveLayerRec fully specified. ##
1735
1736#Example
1737 SkCanvas::SaveLayerRec rec1;
1738 SkCanvas::SaveLayerRec rec2(nullptr, nullptr, nullptr, 0);
1739 SkDebugf("rec1 %c= rec2\n", rec1.fBounds == rec2.fBounds
1740 && rec1.fPaint == rec2.fPaint
1741 && rec1.fBackdrop == rec2.fBackdrop
1742 && rec1.fSaveLayerFlags == rec2.fSaveLayerFlags ? '=' : '!');
1743 #StdOut
1744 rec1 == rec2
1745 ##
1746##
1747
1748##
1749
1750#Method SaveLayerRec(const SkRect* bounds, const SkPaint* paint, const SkImageFilter* backdrop,
1751 const SkImage* clipMask, const SkMatrix* clipMatrix,
1752 SaveLayerFlags saveLayerFlags)
1753
1754#Experimental
1755Not ready for general use.
1756##
1757
1758#Param bounds Offscreen dimensions; may be nullptr. ##
1759#Param paint Applied to offscreen when overlaying prior layer; may be nullptr. ##
1760#Param backdrop Copies prior layer to offscreen with Image_Filter; may be nullptr. ##
1761#Param clipMask May be nullptr. ##
1762#Param clipMatrix May be nullptr. ##
1763#Param saveLayerFlags SaveLayerRec options to modify offscreen. ##
1764
1765#Return SaveLayerRec fully specified. ##
1766
1767#ToDo incomplete ##
1768
1769##
1770
1771#Struct ##
1772
1773#Method int saveLayer(const SaveLayerRec& layerRec)
1774
1775Saves Matrix, Clip, and Draw_Filter (Draw_Filter deprecated on most platforms),
1776and allocates an offscreen bitmap for subsequent drawing.
1777
1778Calling restore() discards changes to Matrix, Clip, and Draw_Filter,
1779and blends the offscreen bitmap with alpha opacity onto the prior layer.
1780The Matrix, Clip, and Draw_Filter are restored to their state when save() was called.
1781
1782Matrix may be changed by translate(), scale(), rotate(), skew(), concat(), setMatrix, and resetMatrix.
1783Clip may be changed by clipRect, clipRRect, clipPath, clipRegion.
1784
1785SaveLayerRec contains the state used to create the layer offscreen.
1786
1787Call restoreToCount with result to restore this and subsequent saves.
1788
1789#Param layerRec offscreen state. ##
1790
1791#Return depth of save state stack. ##
1792
1793#Example
1794#Description
1795The example draws an image, and saves it into a layer with kInitWithPrevious_SaveLayerFlag.
1796Next it punches a hole in the layer and restore with SkBlendMode::kPlus.
1797Where the layer was cleared, the original image will draw unchanged.
1798Outside of the circle the mandrill is brightened.
1799##
1800 #Image 3
1801 // sk_sp<SkImage> image = GetResourceAsImage("mandrill_256.png");
1802 canvas->drawImage(image, 0, 0, nullptr);
1803 SkCanvas::SaveLayerRec rec;
1804 SkPaint paint;
1805 paint.setBlendMode(SkBlendMode::kPlus);
1806 rec.fSaveLayerFlags = SkCanvas::kInitWithPrevious_SaveLayerFlag;
1807 rec.fPaint = &paint;
1808 canvas->saveLayer(rec);
1809 paint.setBlendMode(SkBlendMode::kClear);
1810 canvas->drawCircle(128, 128, 96, paint);
1811 canvas->restore();
1812##
1813
1814#ToDo above example needs to replace GetResourceAsImage with way to select image in fiddle ##
1815
1816##
1817
1818#Subtopic Layer ##
1819
1820# ------------------------------------------------------------------------------
1821
1822#Method void restore()
1823
1824Removes changes to Matrix, Clip, and Draw_Filter since Canvas state was
1825last saved. The state is removed from the stack.
1826
1827Does nothing if the stack is empty.
1828
1829#Example
1830void draw(SkCanvas* canvas) {
1831 SkCanvas simple;
1832 SkDebugf("depth = %d\n", simple.getSaveCount());
1833 simple.restore();
1834 SkDebugf("depth = %d\n", simple.getSaveCount());
1835}
1836##
1837
1838##
1839
1840# ------------------------------------------------------------------------------
1841
1842#Method int getSaveCount() const
1843
1844Returns the number of saved states, each containing: Matrix, Clip, and Draw_Filter.
1845Equals the number of save() calls less the number of restore() calls plus one.
1846The save count of a new canvas is one.
1847
1848#Return depth of save state stack. ##
1849
1850#Example
1851void draw(SkCanvas* canvas) {
1852 SkCanvas simple;
1853 SkDebugf("depth = %d\n", simple.getSaveCount());
1854 simple.save();
1855 SkDebugf("depth = %d\n", simple.getSaveCount());
1856 simple.restore();
1857 SkDebugf("depth = %d\n", simple.getSaveCount());
1858}
1859#StdOut
1860depth = 1
1861depth = 2
1862depth = 1
1863##
1864##
1865
1866##
1867
1868# ------------------------------------------------------------------------------
1869
1870#Method void restoreToCount(int saveCount)
1871
1872Restores state to Matrix, Clip, and Draw_Filter
1873values when save(), saveLayer, saveLayerPreserveLCDTextRequests, or saveLayerAlpha
1874returned saveCount.
1875
1876Does nothing if saveCount is greater than state stack count.
1877Restores state to initial values if saveCount is less than or equal to one.
1878
1879#Param saveCount The depth of state stack to restore. ##
1880
1881#Example
1882void draw(SkCanvas* canvas) {
1883 SkDebugf("depth = %d\n", canvas->getSaveCount());
1884 canvas->save();
1885 canvas->save();
1886 SkDebugf("depth = %d\n", canvas->getSaveCount());
1887 canvas->restoreToCount(0);
1888 SkDebugf("depth = %d\n", canvas->getSaveCount());
1889}
1890#StdOut
1891depth = 1
1892depth = 3
1893depth = 1
1894##
1895##
1896
1897##
1898
1899#Topic State_Stack ##
1900
1901# ------------------------------------------------------------------------------
1902#Topic Matrix
1903
1904#Method void translate(SkScalar dx, SkScalar dy)
1905
1906Translate Matrix by dx along the x-axis and dy along the y-axis.
1907
1908Mathematically, replace Matrix with a translation matrix
1909pre-multiplied with Matrix.
1910
1911This has the effect of moving the drawing by (dx, dy) before transforming
1912the result with Matrix.
1913
1914#Param dx The distance to translate in x. ##
1915#Param dy The distance to translate in y. ##
1916
1917#Example
1918#Height 128
1919#Description
1920scale() followed by translate() produces different results from translate() followed
1921by scale().
1922
1923The blue stroke follows translate of (50, 50); a black
1924fill follows scale of (2, 1/2.f). After restoring the clip, which resets
1925Matrix, a red frame follows the same scale of (2, 1/2.f); a gray fill
1926follows translate of (50, 50).
1927##
1928void draw(SkCanvas* canvas) {
1929 SkPaint filledPaint;
1930 SkPaint outlinePaint;
1931 outlinePaint.setStyle(SkPaint::kStroke_Style);
1932 outlinePaint.setColor(SK_ColorBLUE);
1933 canvas->save();
1934 canvas->translate(50, 50);
1935 canvas->drawCircle(28, 28, 15, outlinePaint); // blue center: (50+28, 50+28)
1936 canvas->scale(2, 1/2.f);
1937 canvas->drawCircle(28, 28, 15, filledPaint); // black center: (50+(28*2), 50+(28/2))
1938 canvas->restore();
1939 filledPaint.setColor(SK_ColorGRAY);
1940 outlinePaint.setColor(SK_ColorRED);
1941 canvas->scale(2, 1/2.f);
1942 canvas->drawCircle(28, 28, 15, outlinePaint); // red center: (28*2, 28/2)
1943 canvas->translate(50, 50);
1944 canvas->drawCircle(28, 28, 15, filledPaint); // gray center: ((50+28)*2, (50+28)/2)
1945}
1946##
1947
1948#ToDo incomplete ##
1949
1950##
1951
1952# ------------------------------------------------------------------------------
1953
1954#Method void scale(SkScalar sx, SkScalar sy)
1955
1956Scale Matrix by sx on the x-axis and sy on the y-axis.
1957
1958Mathematically, replace Matrix with a scale matrix
1959pre-multiplied with Matrix.
1960
1961This has the effect of scaling the drawing by (sx, sy) before transforming
1962the result with Matrix.
1963
1964#Param sx The amount to scale in x. ##
1965#Param sy The amount to scale in y. ##
1966
1967#Example
1968#Height 160
1969void draw(SkCanvas* canvas) {
1970 SkPaint paint;
1971 SkRect rect = { 10, 20, 60, 120 };
1972 canvas->translate(20, 20);
1973 canvas->drawRect(rect, paint);
1974 canvas->scale(2, .5f);
1975 paint.setColor(SK_ColorGRAY);
1976 canvas->drawRect(rect, paint);
1977}
1978##
1979
1980#ToDo incomplete ##
1981
1982##
1983
1984# ------------------------------------------------------------------------------
1985
1986#Method void rotate(SkScalar degrees)
1987
1988Rotate Matrix by degrees. Positive degrees rotates clockwise.
1989
1990Mathematically, replace Matrix with a rotation matrix
1991pre-multiplied with Matrix.
1992
1993This has the effect of rotating the drawing by degrees before transforming
1994the result with Matrix.
1995
1996#Param degrees The amount to rotate, in degrees. ##
1997
1998#Example
1999#Description
2000Draw clock hands at time 5:10. The hour hand and minute hand point up and
2001are rotated clockwise.
2002##
2003void draw(SkCanvas* canvas) {
2004 SkPaint paint;
2005 paint.setStyle(SkPaint::kStroke_Style);
2006 canvas->translate(128, 128);
2007 canvas->drawCircle(0, 0, 60, paint);
2008 canvas->save();
2009 canvas->rotate(10 * 360 / 60); // 10 minutes of 60 scaled to 360 degrees
2010 canvas->drawLine(0, 0, 0, -50, paint);
2011 canvas->restore();
2012 canvas->rotate((5 + 10.f/60) * 360 / 12); // 5 and 10/60 hours of 12 scaled to 360 degrees
2013 canvas->drawLine(0, 0, 0, -30, paint);
2014}
2015##
2016
2017#ToDo incomplete ##
2018
2019##
2020
2021# ------------------------------------------------------------------------------
2022
2023#Method void rotate(SkScalar degrees, SkScalar px, SkScalar py)
2024
2025Rotate Matrix by degrees about a point at (px, py). Positive degrees rotates clockwise.
2026
2027Mathematically, construct a rotation matrix. Pre-multiply the rotation matrix by
2028a translation matrix, then replace Matrix with the resulting matrix
2029pre-multiplied with Matrix.
2030
2031This has the effect of rotating the drawing about a given point before transforming
2032the result with Matrix.
2033
2034#Param degrees The amount to rotate, in degrees. ##
2035#Param px The x coordinate of the point to rotate about. ##
2036#Param py The y coordinate of the point to rotate about. ##
2037
2038#Example
2039#Height 192
2040void draw(SkCanvas* canvas) {
2041 SkPaint paint;
2042 paint.setTextSize(96);
2043 canvas->drawString("A1", 130, 100, paint);
2044 canvas->rotate(180, 130, 100);
2045 canvas->drawString("A1", 130, 100, paint);
2046}
2047##
2048
2049#ToDo incomplete ##
2050
2051##
2052
2053# ------------------------------------------------------------------------------
2054
2055#Method void skew(SkScalar sx, SkScalar sy)
2056
2057Skew Matrix by sx on the x-axis and sy on the y-axis. A positive value of sx skews the
2058drawing right as y increases; a positive value of sy skews the drawing down as x increases.
2059
2060Mathematically, replace Matrix with a skew matrix
2061pre-multiplied with Matrix.
2062
2063Preconcat the current matrix with the specified skew.
2064#Param sx The amount to skew in x. ##
2065#Param sy The amount to skew in y. ##
2066
2067This has the effect of scaling the drawing by (sx, sy) before transforming
2068the result with Matrix.
2069
2070#Example
2071 #Description
2072 Black text mimics an oblique text style by using a negative skew in x that
2073 shifts the geometry to the right as the y values decrease.
2074 Red text uses a positive skew in y to shift the geometry down as the x values
2075 increase.
2076 Blue text combines x and y skew to rotate and scale.
2077 ##
2078 SkPaint paint;
2079 paint.setTextSize(128);
2080 canvas->translate(30, 130);
2081 canvas->save();
2082 canvas->skew(-.5, 0);
2083 canvas->drawString("A1", 0, 0, paint);
2084 canvas->restore();
2085 canvas->save();
2086 canvas->skew(0, .5);
2087 paint.setColor(SK_ColorRED);
2088 canvas->drawString("A1", 0, 0, paint);
2089 canvas->restore();
2090 canvas->skew(-.5, .5);
2091 paint.setColor(SK_ColorBLUE);
2092 canvas->drawString("A1", 0, 0, paint);
2093##
2094
2095#ToDo incomplete ##
2096
2097##
2098
2099# ------------------------------------------------------------------------------
2100
2101#Method void concat(const SkMatrix& matrix)
2102
2103Replace Matrix with matrix pre-multiplied with Matrix.
2104
2105This has the effect of transforming the drawn geometry by matrix, before transforming
2106the result with Matrix.
2107
2108#Param matrix Pre-multiply with Matrix. ##
2109
2110#Example
2111void draw(SkCanvas* canvas) {
2112 SkPaint paint;
2113 paint.setTextSize(80);
2114 paint.setTextScaleX(.3);
2115 SkMatrix matrix;
2116 SkRect rect[2] = {{ 10, 20, 90, 110 }, { 40, 130, 140, 180 }};
2117 matrix.setRectToRect(rect[0], rect[1], SkMatrix::kFill_ScaleToFit);
2118 canvas->drawRect(rect[0], paint);
2119 canvas->drawRect(rect[1], paint);
2120 paint.setColor(SK_ColorWHITE);
2121 canvas->drawString("Here", rect[0].fLeft + 10, rect[0].fBottom - 10, paint);
2122 canvas->concat(matrix);
2123 canvas->drawString("There", rect[0].fLeft + 10, rect[0].fBottom - 10, paint);
2124}
2125##
2126
2127#ToDo incomplete ##
2128
2129##
2130
2131# ------------------------------------------------------------------------------
2132
2133#Method void setMatrix(const SkMatrix& matrix)
2134
2135Replace Matrix with matrix.
2136Unlike concat(), any prior matrix state is overwritten.
2137
2138#Param matrix Copied into Matrix. ##
2139
2140#Example
2141#Height 128
2142void draw(SkCanvas* canvas) {
2143 SkPaint paint;
2144 canvas->scale(4, 6);
2145 canvas->drawString("truth", 2, 10, paint);
2146 SkMatrix matrix;
2147 matrix.setScale(2.8f, 6);
2148 canvas->setMatrix(matrix);
2149 canvas->drawString("consequences", 2, 20, paint);
2150}
2151##
2152
2153#ToDo incomplete ##
2154
2155##
2156
2157# ------------------------------------------------------------------------------
2158
2159#Method void resetMatrix()
2160
2161Sets Matrix to the identity matrix.
2162Any prior matrix state is overwritten.
2163
2164#Example
2165#Height 128
2166void draw(SkCanvas* canvas) {
2167 SkPaint paint;
2168 canvas->scale(4, 6);
2169 canvas->drawString("truth", 2, 10, paint);
2170 canvas->resetMatrix();
2171 canvas->scale(2.8f, 6);
2172 canvas->drawString("consequences", 2, 20, paint);
2173}
2174##
2175
2176#ToDo incomplete ##
2177
2178##
2179
2180# ------------------------------------------------------------------------------
2181
2182#Method const SkMatrix& getTotalMatrix() const
2183
2184Returns Matrix.
2185This does not account for translation by Device or Surface.
2186
2187#Return Matrix on Canvas. ##
2188
2189#Example
2190 SkDebugf("isIdentity %s\n", canvas->getTotalMatrix().isIdentity() ? "true" : "false");
2191 #StdOut
2192 isIdentity true
2193 ##
2194##
2195
2196#ToDo incomplete ##
2197
2198##
2199
2200#Topic Matrix ##
2201
2202# ------------------------------------------------------------------------------
2203#Topic Clip
2204
2205Clip is built from a stack of clipping paths. Each Path in the
2206stack can be constructed from one or more Path_Contour elements. The
2207Path_Contour may be composed of any number of Path_Verb segments. Each
2208Path_Contour forms a closed area; Path_Fill_Type defines the area enclosed
2209by Path_Contour.
2210
2211Clip stack of Path elements successfully restrict the Path area. Each
2212Path is transformed by Matrix, then intersected with or subtracted from the
2213prior Clip to form the replacement Clip. Use SkClipOp::kDifference
2214to subtract Path from Clip; use SkClipOp::kIntersect to intersect Path
2215with Clip.
2216
2217A clipping Path may be anti-aliased; if Path, after transformation, is
2218composed of horizontal and vertical lines, clearing Anti-alias allows whole pixels
2219to either be inside or outside the clip. The fastest drawing has a aliased,
2220rectanglar clip.
2221
2222If clipping Path has Anti-alias set, clip may partially clip a pixel, requiring
2223that drawing blend partially with the destination along the edge. A rotated
2224rectangular anti-aliased clip looks smoother but draws slower.
2225
2226Clip can combine with Rect and Round_Rect primitives; like
2227Path, these are transformed by Matrix before they are combined with Clip.
2228
2229Clip can combine with Region. Region is assumed to be in Device coordinates
2230and is unaffected by Matrix.
2231
2232#Example
2233#Height 90
2234 #Description
2235 Draw a red circle with an aliased clip and an anti-aliased clip.
2236 Use an image filter to zoom into the pixels drawn.
2237 The edge of the aliased clip fully draws pixels in the red circle.
2238 The edge of the anti-aliased clip partially draws pixels in the red circle.
2239 ##
2240 SkPaint redPaint, scalePaint;
2241 redPaint.setAntiAlias(true);
2242 redPaint.setColor(SK_ColorRED);
2243 canvas->save();
2244 for (bool antialias : { false, true } ) {
2245 canvas->save();
2246 canvas->clipRect(SkRect::MakeWH(19.5f, 11.5f), antialias);
2247 canvas->drawCircle(17, 11, 8, redPaint);
2248 canvas->restore();
2249 canvas->translate(16, 0);
2250 }
2251 canvas->restore();
2252 SkMatrix matrix;
2253 matrix.setScale(6, 6);
2254 scalePaint.setImageFilter(
2255 SkImageFilter::MakeMatrixFilter(matrix, kNone_SkFilterQuality, nullptr));
2256 SkCanvas::SaveLayerRec saveLayerRec(
2257 nullptr, &scalePaint, SkCanvas::kInitWithPrevious_SaveLayerFlag);
2258 canvas->saveLayer(saveLayerRec);
2259 canvas->restore();
2260##
2261
2262#Method void clipRect(const SkRect& rect, SkClipOp op, bool doAntiAlias)
2263
2264Replace Clip with the intersection or difference of Clip and rect,
2265with an aliased or anti-aliased clip edge. rect is transformed by Matrix
2266before it is combined with Clip.
2267
2268#Param rect Rectangle to combine with Clip. ##
2269#Param op Clip_Op to apply to Clip. ##
2270#Param doAntiAlias true if Clip is to be anti-aliased. ##
2271
2272#Example
2273#Height 128
2274void draw(SkCanvas* canvas) {
2275 canvas->rotate(10);
2276 SkPaint paint;
2277 paint.setAntiAlias(true);
2278 for (auto alias: { false, true } ) {
2279 canvas->save();
2280 canvas->clipRect(SkRect::MakeWH(90, 80), SkClipOp::kIntersect, alias);
2281 canvas->drawCircle(100, 60, 60, paint);
2282 canvas->restore();
2283 canvas->translate(80, 0);
2284 }
2285}
2286##
2287
2288#ToDo incomplete ##
2289
2290##
2291
2292#Method void clipRect(const SkRect& rect, SkClipOp op)
2293
2294Replace Clip with the intersection or difference of Clip and rect.
2295Resulting Clip is aliased; pixels are fully contained by the clip.
2296rect is transformed by Matrix
2297before it is combined with Clip.
2298
2299#Param rect Rectangle to combine with Clip. ##
2300#Param op Clip_Op to apply to Clip. ##
2301
2302#Example
2303#Height 192
2304#Width 280
2305void draw(SkCanvas* canvas) {
2306 SkPaint paint;
2307 for (SkClipOp op: { SkClipOp::kIntersect, SkClipOp::kDifference } ) {
2308 canvas->save();
2309 canvas->clipRect(SkRect::MakeWH(90, 120), op, false);
2310 canvas->drawCircle(100, 100, 60, paint);
2311 canvas->restore();
2312 canvas->translate(80, 0);
2313 }
2314}
2315##
2316
2317#ToDo incomplete ##
2318
2319##
2320
2321#Method void clipRect(const SkRect& rect, bool doAntiAlias = false)
2322
2323Replace Clip with the intersection of Clip and rect.
2324Resulting Clip is aliased; pixels are fully contained by the clip.
2325rect is transformed by Matrix
2326before it is combined with Clip.
2327
2328#Param rect Rectangle to combine with Clip. ##
2329#Param doAntiAlias true if Clip is to be anti-aliased. ##
2330
2331#Example
2332#Height 133
2333 #Description
2334 A circle drawn in pieces looks uniform when drawn aliased.
2335 The same circle pieces blend with pixels more than once when anti-aliased,
2336 visible as a thin pair of lines through the right circle.
2337 ##
2338void draw(SkCanvas* canvas) {
2339 canvas->clear(SK_ColorWHITE);
2340 SkPaint paint;
2341 paint.setAntiAlias(true);
2342 paint.setColor(0x8055aaff);
2343 SkRect clipRect = { 0, 0, 87.4f, 87.4f };
2344 for (auto alias: { false, true } ) {
2345 canvas->save();
2346 canvas->clipRect(clipRect, SkClipOp::kIntersect, alias);
2347 canvas->drawCircle(67, 67, 60, paint);
2348 canvas->restore();
2349 canvas->save();
2350 canvas->clipRect(clipRect, SkClipOp::kDifference, alias);
2351 canvas->drawCircle(67, 67, 60, paint);
2352 canvas->restore();
2353 canvas->translate(120, 0);
2354 }
2355}
2356##
2357
2358#ToDo incomplete ##
2359
2360##
2361
2362#Method void androidFramework_setDeviceClipRestriction(const SkIRect& rect)
2363
2364Sets the max clip rectangle, which can be set by clipRect, clipRRect and
2365clipPath and intersect the current clip with the specified rect.
2366The max clip affects only future ops (it is not retroactive).
2367The clip restriction is not recorded in pictures.
2368
2369#Private
2370This is private API to be used only by Android framework.
2371##
2372
2373#Param rect The maximum allowed clip in device coordinates.
2374Empty rect means max clip is not enforced. ##
2375
2376##
2377
2378#Method void clipRRect(const SkRRect& rrect, SkClipOp op, bool doAntiAlias)
2379
2380Replace Clip with the intersection or difference of Clip and rrect,
2381with an aliased or anti-aliased clip edge.
2382rrect is transformed by Matrix
2383before it is combined with Clip.
2384
2385#Param rrect Round_Rect to combine with Clip. ##
2386#Param op Clip_Op to apply to Clip. ##
2387#Param doAntiAlias true if Clip is to be antialiased. ##
2388
2389#Example
2390#Height 128
2391void draw(SkCanvas* canvas) {
2392 canvas->clear(SK_ColorWHITE);
2393 SkPaint paint;
2394 paint.setAntiAlias(true);
2395 paint.setColor(0x8055aaff);
2396 SkRRect oval;
2397 oval.setOval({10, 20, 90, 100});
2398 canvas->clipRRect(oval, SkClipOp::kIntersect, true);
2399 canvas->drawCircle(70, 100, 60, paint);
2400}
2401##
2402
2403#ToDo incomplete ##
2404
2405##
2406
2407#Method void clipRRect(const SkRRect& rrect, SkClipOp op)
2408
2409Replace Clip with the intersection or difference of Clip and rrect.
2410Resulting Clip is aliased; pixels are fully contained by the clip.
2411rrect is transformed by Matrix
2412before it is combined with Clip.
2413
2414#Param rrect Round_Rect to combine with Clip. ##
2415#Param op Clip_Op to apply to Clip. ##
2416
2417#Example
2418#Height 128
2419void draw(SkCanvas* canvas) {
2420 SkPaint paint;
2421 paint.setColor(0x8055aaff);
2422 auto oval = SkRRect::MakeOval({10, 20, 90, 100});
2423 canvas->clipRRect(oval, SkClipOp::kIntersect);
2424 canvas->drawCircle(70, 100, 60, paint);
2425}
2426##
2427
2428#ToDo incomplete ##
2429
2430##
2431
2432#Method void clipRRect(const SkRRect& rrect, bool doAntiAlias = false)
2433
2434Replace Clip with the intersection of Clip and rrect,
2435with an aliased or anti-aliased clip edge.
2436rrect is transformed by Matrix
2437before it is combined with Clip.
2438
2439#Param rrect Round_Rect to combine with Clip. ##
2440#Param doAntiAlias true if Clip is to be antialiased. ##
2441
2442#Example
2443#Height 128
2444void draw(SkCanvas* canvas) {
2445 SkPaint paint;
2446 paint.setAntiAlias(true);
2447 auto oval = SkRRect::MakeRectXY({10, 20, 90, 100}, 9, 13);
2448 canvas->clipRRect(oval, true);
2449 canvas->drawCircle(70, 100, 60, paint);
2450}
2451##
2452
2453#ToDo incomplete ##
2454
2455##
2456
2457#Method void clipPath(const SkPath& path, SkClipOp op, bool doAntiAlias)
2458
2459Replace Clip with the intersection or difference of Clip and path,
2460with an aliased or anti-aliased clip edge. Path_Fill_Type determines if path
2461describes the area inside or outside its contours; and if Path_Contour overlaps
2462itself or another Path_Contour, whether the overlaps form part of the area.
2463path is transformed by Matrix
2464before it is combined with Clip.
2465
2466#Param path Path to combine with Clip. ##
2467#Param op Clip_Op to apply to Clip. ##
2468#Param doAntiAlias true if Clip is to be antialiased. ##
2469
2470#Example
2471#Description
2472Top figure uses SkPath::kInverseWinding_FillType and SkClipOp::kDifference;
2473area outside clip is subtracted from circle.
2474
2475Bottom figure uses SkPath::kWinding_FillType and SkClipOp::kIntersect;
2476area inside clip is intersected with circle.
2477##
2478void draw(SkCanvas* canvas) {
2479 SkPaint paint;
2480 paint.setAntiAlias(true);
2481 SkPath path;
2482 path.addRect({20, 30, 100, 110});
2483 path.setFillType(SkPath::kInverseWinding_FillType);
2484 canvas->save();
2485 canvas->clipPath(path, SkClipOp::kDifference, false);
2486 canvas->drawCircle(70, 100, 60, paint);
2487 canvas->restore();
2488 canvas->translate(100, 100);
2489 path.setFillType(SkPath::kWinding_FillType);
2490 canvas->clipPath(path, SkClipOp::kIntersect, false);
2491 canvas->drawCircle(70, 100, 60, paint);
2492}
2493##
2494
2495#ToDo incomplete ##
2496
2497##
2498
2499#Method void clipPath(const SkPath& path, SkClipOp op)
2500
2501Replace Clip with the intersection or difference of Clip and path.
2502Resulting Clip is aliased; pixels are fully contained by the clip.
2503Path_Fill_Type determines if path
2504describes the area inside or outside its contours; and if Path_Contour overlaps
2505itself or another Path_Contour, whether the overlaps form part of the area.
2506path is transformed by Matrix
2507before it is combined with Clip.
2508
2509#Param path Path to combine with Clip. ##
2510#Param op Clip_Op to apply to Clip. ##
2511
2512#Example
2513#Description
2514Overlapping Rects form a clip. When clip's Path_Fill_Type is set to
2515SkPath::kWinding_FillType, the overlap is included. Set to
2516SkPath::kEvenOdd_FillType, the overlap is excluded and forms a hole.
2517##
2518void draw(SkCanvas* canvas) {
2519 SkPaint paint;
2520 paint.setAntiAlias(true);
2521 SkPath path;
2522 path.addRect({20, 15, 100, 95});
2523 path.addRect({50, 65, 130, 135});
2524 path.setFillType(SkPath::kWinding_FillType);
2525 canvas->save();
2526 canvas->clipPath(path, SkClipOp::kIntersect);
2527 canvas->drawCircle(70, 85, 60, paint);
2528 canvas->restore();
2529 canvas->translate(100, 100);
2530 path.setFillType(SkPath::kEvenOdd_FillType);
2531 canvas->clipPath(path, SkClipOp::kIntersect);
2532 canvas->drawCircle(70, 85, 60, paint);
2533}
2534##
2535
2536#ToDo incomplete ##
2537
2538##
2539
2540#Method void clipPath(const SkPath& path, bool doAntiAlias = false)
2541
2542Replace Clip with the intersection of Clip and path.
2543Resulting Clip is aliased; pixels are fully contained by the clip.
2544Path_Fill_Type determines if path
2545describes the area inside or outside its contours; and if Path_Contour overlaps
2546itself or another Path_Contour, whether the overlaps form part of the area.
2547path is transformed by Matrix
2548before it is combined with Clip.
2549
2550#Param path Path to combine with Clip. ##
2551#Param doAntiAlias true if Clip is to be antialiased. ##
2552
2553#Example
2554#Height 212
2555#Description
2556Clip loops over itself covering its center twice. When clip's Path_Fill_Type
2557is set to SkPath::kWinding_FillType, the overlap is included. Set to
2558SkPath::kEvenOdd_FillType, the overlap is excluded and forms a hole.
2559##
2560void draw(SkCanvas* canvas) {
2561 SkPaint paint;
2562 paint.setAntiAlias(true);
2563 SkPath path;
2564 SkPoint poly[] = {{20, 20}, { 80, 20}, { 80, 80}, {40, 80},
2565 {40, 40}, {100, 40}, {100, 100}, {20, 100}};
2566 path.addPoly(poly, SK_ARRAY_COUNT(poly), true);
2567 path.setFillType(SkPath::kWinding_FillType);
2568 canvas->save();
2569 canvas->clipPath(path, SkClipOp::kIntersect);
2570 canvas->drawCircle(50, 50, 45, paint);
2571 canvas->restore();
2572 canvas->translate(100, 100);
2573 path.setFillType(SkPath::kEvenOdd_FillType);
2574 canvas->clipPath(path, SkClipOp::kIntersect);
2575 canvas->drawCircle(50, 50, 45, paint);
2576}
2577##
2578
2579#ToDo incomplete ##
2580
2581##
2582
2583# ------------------------------------------------------------------------------
2584
2585#Method void setAllowSimplifyClip(bool allow)
2586
2587#Experimental
2588Only used for testing.
2589##
2590
2591Set to simplify clip stack using path ops.
2592
2593##
2594
2595# ------------------------------------------------------------------------------
2596
2597#Method void clipRegion(const SkRegion& deviceRgn, SkClipOp op = SkClipOp::kIntersect)
2598
2599Replace Clip with the intersection or difference of Clip and Region deviceRgn.
2600Resulting Clip is aliased; pixels are fully contained by the clip.
2601deviceRgn is unaffected by Matrix.
2602
2603#Param deviceRgn Region to combine with Clip. ##
2604#Param op Clip_Op to apply to Clip. ##
2605
2606#Example
2607#Description
2608 region is unaffected by canvas rotation; rect is affected by canvas rotation.
2609 Both clips are aliased; this is unnoticable on Region clip because it
2610 aligns to pixel boundaries.
2611##
2612void draw(SkCanvas* canvas) {
2613 SkPaint paint;
2614 paint.setAntiAlias(true);
2615 SkIRect iRect = {30, 40, 120, 130 };
2616 SkRegion region(iRect);
2617 canvas->rotate(10);
2618 canvas->save();
2619 canvas->clipRegion(region, SkClipOp::kIntersect);
2620 canvas->drawCircle(50, 50, 45, paint);
2621 canvas->restore();
2622 canvas->translate(100, 100);
2623 canvas->clipRect(SkRect::Make(iRect), SkClipOp::kIntersect);
2624 canvas->drawCircle(50, 50, 45, paint);
2625}
2626##
2627
2628#ToDo incomplete ##
2629
2630##
2631
2632#Method bool quickReject(const SkRect& rect) const
2633
2634Return true if Rect rect, transformed by Matrix, can be quickly determined to be
2635outside of Clip. May return false even though rect is outside of Clip.
2636
2637Use to check if an area to be drawn is clipped out, to skip subsequent draw calls.
2638
2639#Param rect Rect to compare with Clip. ##
2640
2641#Return true if rect, transformed by Matrix, does not intersect Clip. ##
2642
2643#Example
2644void draw(SkCanvas* canvas) {
2645 SkRect testRect = {30, 30, 120, 129 };
2646 SkRect clipRect = {30, 130, 120, 230 };
2647 canvas->save();
2648 canvas->clipRect(clipRect);
2649 SkDebugf("quickReject %s\n", canvas->quickReject(testRect) ? "true" : "false");
2650 canvas->restore();
2651 canvas->rotate(10);
2652 canvas->clipRect(clipRect);
2653 SkDebugf("quickReject %s\n", canvas->quickReject(testRect) ? "true" : "false");
2654}
2655 #StdOut
2656 quickReject true
2657 quickReject false
2658 ##
2659##
2660
2661#ToDo incomplete ##
2662
2663##
2664
2665#Method bool quickReject(const SkPath& path) const
2666
2667Return true if path, transformed by Matrix, can be quickly determined to be
2668outside of Clip. May return false even though path is outside of Clip.
2669
2670Use to check if an area to be drawn is clipped out, to skip subsequent draw calls.
2671
2672#Param path Path to compare with Clip. ##
2673
2674#Return true if path, transformed by Matrix, does not intersect Clip. ##
2675
2676#Example
2677void draw(SkCanvas* canvas) {
2678 SkPoint testPoints[] = {{30, 30}, {120, 30}, {120, 129} };
2679 SkPoint clipPoints[] = {{30, 130}, {120, 130}, {120, 230} };
2680 SkPath testPath, clipPath;
2681 testPath.addPoly(testPoints, SK_ARRAY_COUNT(testPoints), true);
2682 clipPath.addPoly(clipPoints, SK_ARRAY_COUNT(clipPoints), true);
2683 canvas->save();
2684 canvas->clipPath(clipPath);
2685 SkDebugf("quickReject %s\n", canvas->quickReject(testPath) ? "true" : "false");
2686 canvas->restore();
2687 canvas->rotate(10);
2688 canvas->clipPath(clipPath);
2689 SkDebugf("quickReject %s\n", canvas->quickReject(testPath) ? "true" : "false");
2690 #StdOut
2691 quickReject true
2692 quickReject false
2693 ##
2694}
2695##
2696
2697#ToDo incomplete ##
2698
2699##
2700
2701#Method SkRect getLocalClipBounds() const
2702
2703Return bounds of Clip, transformed by inverse of Matrix. If Clip is empty,
2704return SkRect::MakeEmpty, where all Rect sides equal zero.
2705
2706Rect returned is outset by one to account for partial pixel coverage if Clip
2707is anti-aliased.
2708
2709#Return bounds of Clip in local coordinates. ##
2710
2711#Example
2712 #Description
2713 Initial bounds is device bounds outset by 1 on all sides.
2714 Clipped bounds is clipPath bounds outset by 1 on all sides.
2715 Scaling the canvas by two in x and y scales the local bounds by 1/2 in x and y.
2716 ##
2717 SkCanvas local(256, 256);
2718 canvas = &local;
2719 SkRect bounds = canvas->getLocalClipBounds();
2720 SkDebugf("left:%g top:%g right:%g bottom:%g\n",
2721 bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom);
2722 SkPoint clipPoints[] = {{30, 130}, {120, 130}, {120, 230} };
2723 SkPath clipPath;
2724 clipPath.addPoly(clipPoints, SK_ARRAY_COUNT(clipPoints), true);
2725 canvas->clipPath(clipPath);
2726 bounds = canvas->getLocalClipBounds();
2727 SkDebugf("left:%g top:%g right:%g bottom:%g\n",
2728 bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom);
2729 canvas->scale(2, 2);
2730 bounds = canvas->getLocalClipBounds();
2731 SkDebugf("left:%g top:%g right:%g bottom:%g\n",
2732 bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom);
2733 #StdOut
2734 left:-1 top:-1 right:257 bottom:257
2735 left:29 top:129 right:121 bottom:231
2736 left:14.5 top:64.5 right:60.5 bottom:115.5
2737 ##
2738##
2739
2740# local canvas in example works around bug in fiddle ##
2741#Bug 6524 ##
2742
2743##
2744
2745#Method bool getLocalClipBounds(SkRect* bounds) const
2746
2747Return bounds of Clip, transformed by inverse of Matrix. If Clip is empty,
2748return false, and set bounds to SkRect::MakeEmpty, where all Rect sides equal zero.
2749
2750bounds is outset by one to account for partial pixel coverage if Clip
2751is anti-aliased.
2752
2753#Param bounds Rect of Clip in local coordinates. ##
2754
2755#Return true if Clip bounds is not empty. ##
2756
2757#Example
2758 void draw(SkCanvas* canvas) {
2759 SkCanvas local(256, 256);
2760 canvas = &local;
2761 SkRect bounds;
2762 SkDebugf("local bounds empty = %s\n", canvas->getLocalClipBounds(&bounds)
2763 ? "false" : "true");
2764 SkPath path;
2765 canvas->clipPath(path);
2766 SkDebugf("local bounds empty = %s\n", canvas->getLocalClipBounds(&bounds)
2767 ? "false" : "true");
2768 }
2769 #StdOut
2770 local bounds empty = false
2771 local bounds empty = true
2772 ##
2773##
2774
2775# local canvas in example works around bug in fiddle ##
2776#Bug 6524 ##
2777
2778##
2779
2780#Method SkIRect getDeviceClipBounds() const
2781
2782Return IRect bounds of Clip, unaffected by Matrix. If Clip is empty,
2783return SkRect::MakeEmpty, where all Rect sides equal zero.
2784
2785Unlike getLocalClipBounds, returned IRect is not outset.
2786
2787#Return bounds of Clip in Device coordinates. ##
2788
2789#Example
2790void draw(SkCanvas* canvas) {
2791 #Description
2792 Initial bounds is device bounds, not outset.
2793 Clipped bounds is clipPath bounds, not outset.
2794 Scaling the canvas by 1/2 in x and y scales the device bounds by 1/2 in x and y.
2795 ##
2796 SkCanvas device(256, 256);
2797 canvas = &device;
2798 SkIRect bounds = canvas->getDeviceClipBounds();
2799 SkDebugf("left:%d top:%d right:%d bottom:%d\n",
2800 bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom);
2801 SkPoint clipPoints[] = {{30, 130}, {120, 130}, {120, 230} };
2802 SkPath clipPath;
2803 clipPath.addPoly(clipPoints, SK_ARRAY_COUNT(clipPoints), true);
2804 canvas->save();
2805 canvas->clipPath(clipPath);
2806 bounds = canvas->getDeviceClipBounds();
2807 SkDebugf("left:%d top:%d right:%d bottom:%d\n",
2808 bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom);
2809 canvas->restore();
2810 canvas->scale(1.f/2, 1.f/2);
2811 canvas->clipPath(clipPath);
2812 bounds = canvas->getDeviceClipBounds();
2813 SkDebugf("left:%d top:%d right:%d bottom:%d\n",
2814 bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom);
2815 #StdOut
2816 left:0 top:0 right:256 bottom:256
2817 left:30 top:130 right:120 bottom:230
2818 left:15 top:65 right:60 bottom:115
2819 ##
2820}
2821##
2822
2823#ToDo some confusion on why with an identity Matrix local and device are different ##
2824
2825# device canvas in example works around bug in fiddle ##
2826#Bug 6524 ##
2827
2828##
2829
2830#Method bool getDeviceClipBounds(SkIRect* bounds) const
2831
2832Return IRect bounds of Clip, unaffected by Matrix. If Clip is empty,
2833return false, and set bounds to SkRect::MakeEmpty, where all Rect sides equal zero.
2834
2835Unlike getLocalClipBounds, bounds is not outset.
2836
2837#Param bounds Rect of Clip in device coordinates. ##
2838
2839#Return true if Clip bounds is not empty. ##
2840
2841#Example
2842 void draw(SkCanvas* canvas) {
2843 SkIRect bounds;
2844 SkDebugf("device bounds empty = %s\n", canvas->getDeviceClipBounds(&bounds)
2845 ? "false" : "true");
2846 SkPath path;
2847 canvas->clipPath(path);
2848 SkDebugf("device bounds empty = %s\n", canvas->getDeviceClipBounds(&bounds)
2849 ? "false" : "true");
2850 }
2851 #StdOut
2852 device bounds empty = false
2853 device bounds empty = true
2854 ##
2855##
2856
2857#ToDo incomplete ##
2858
2859##
2860
2861#Topic Clip ##
2862
2863# ------------------------------------------------------------------------------
2864
2865#Method void drawColor(SkColor color, SkBlendMode mode = SkBlendMode::kSrcOver)
2866
2867Fill Clip with Color color.
2868mode determines how Color_ARGB is combined with destination.
2869
2870#Param color Unpremultiplied Color_ARGB. ##
2871#Param mode SkBlendMode used to combine source color and destination. ##
2872
2873#Example
2874 canvas->drawColor(SK_ColorRED);
2875 canvas->clipRect(SkRect::MakeWH(150, 150));
2876 canvas->drawColor(SkColorSetARGB(0x80, 0x00, 0xFF, 0x00), SkBlendMode::kPlus);
2877 canvas->clipRect(SkRect::MakeWH(75, 75));
2878 canvas->drawColor(SkColorSetARGB(0x80, 0x00, 0x00, 0xFF), SkBlendMode::kPlus);
2879##
2880
2881#ToDo incomplete ##
2882
2883##
2884
2885# ------------------------------------------------------------------------------
2886
2887#Method void clear(SkColor color)
2888
2889Fill Clip with Color color using SkBlendMode::kSrc.
2890This has the effect of replacing all pixels contained by Clip with color.
2891
2892#Param color Unpremultiplied Color_ARGB. ##
2893
2894#Example
2895void draw(SkCanvas* canvas) {
2896 canvas->save();
2897 canvas->clipRect(SkRect::MakeWH(256, 128));
2898 canvas->clear(SkColorSetARGB(0x80, 0xFF, 0x00, 0x00));
2899 canvas->restore();
2900 canvas->save();
2901 canvas->clipRect(SkRect::MakeWH(150, 192));
2902 canvas->clear(SkColorSetARGB(0x80, 0x00, 0xFF, 0x00));
2903 canvas->restore();
2904 canvas->clipRect(SkRect::MakeWH(75, 256));
2905 canvas->clear(SkColorSetARGB(0x80, 0x00, 0x00, 0xFF));
2906}
2907##
2908
2909#ToDo incomplete ##
2910
2911##
2912
2913# ------------------------------------------------------------------------------
2914
2915#Method void discard()
2916
2917Make Canvas contents undefined. Subsequent calls that read Canvas pixels,
2918such as drawing with SkBlendMode, return undefined results. discard() does
2919not change Clip or Matrix.
2920
2921discard() may do nothing, depending on the implementation of Surface or Device
2922that created Canvas.
2923
2924discard() allows optimized performance on subsequent draws by removing
2925cached data associated with Surface or Device.
2926It is not necessary to call discard() once done with Canvas;
2927any cached data is deleted when owning Surface or Device is deleted.
2928
2929#ToDo example? not sure how to make this meaningful w/o more implementation detail ##
2930
2931#NoExample
2932##
2933
2934##
2935
2936# ------------------------------------------------------------------------------
2937
2938#Method void drawPaint(const SkPaint& paint)
2939
2940Fill Clip with Paint paint. drawPaint is affected by Paint components
2941Rasterizer, Mask_Filter, Shader, Color_Filter, Image_Filter, and Blend_Mode; but not by
2942Path_Effect.
2943
2944# can Path_Effect in paint ever alter drawPaint?
2945
2946#Param paint Used to fill the canvas. ##
2947
2948#Example
2949void draw(SkCanvas* canvas) {
2950 SkColor colors[] = { SK_ColorRED, SK_ColorGREEN, SK_ColorBLUE };
2951 SkScalar pos[] = { 0, SK_Scalar1/2, SK_Scalar1 };
2952 SkPaint paint;
2953 paint.setShader(SkGradientShader::MakeSweep(256, 256, colors, pos, SK_ARRAY_COUNT(colors)));
2954 canvas->drawPaint(paint);
2955}
2956##
2957
2958#ToDo incomplete ##
2959
2960##
2961
2962# ------------------------------------------------------------------------------
2963
2964#Enum PointMode
2965
2966#Code
2967 enum PointMode {
2968 kPoints_PointMode,
2969 kLines_PointMode,
2970 kPolygon_PointMode
2971 };
2972##
2973
2974Selects if an array of points are drawn as discrete points, as lines, or as
2975an open polygon.
2976
2977#Const kPoints_PointMode 0
2978 Draw each point separately.
2979##
2980
2981#Const kLines_PointMode 1
2982 Draw each pair of points as a line segment.
2983##
2984
2985#Const kPolygon_PointMode 2
2986 Draw the array of points as a open polygon.
2987##
2988
2989#Example
2990 #Description
2991 The upper left corner shows three squares when drawn as points.
2992 The upper right corner shows one line; when drawn as lines, two points are required per line.
2993 The lower right corner shows two lines; when draw as polygon, no miter is drawn at the corner.
2994 The lower left corner shows two lines with a miter when path contains polygon.
2995 ##
2996void draw(SkCanvas* canvas) {
2997 SkPaint paint;
2998 paint.setStyle(SkPaint::kStroke_Style);
2999 paint.setStrokeWidth(10);
3000 SkPoint points[] = {{64, 32}, {96, 96}, {32, 96}};
3001 canvas->drawPoints(SkCanvas::kPoints_PointMode, 3, points, paint);
3002 canvas->translate(128, 0);
3003 canvas->drawPoints(SkCanvas::kLines_PointMode, 3, points, paint);
3004 canvas->translate(0, 128);
3005 canvas->drawPoints(SkCanvas::kPolygon_PointMode, 3, points, paint);
3006 SkPath path;
3007 path.addPoly(points, 3, false);
3008 canvas->translate(-128, 0);
3009 canvas->drawPath(path, paint);
3010}
3011##
3012
3013#ToDo incomplete ##
3014
3015##
3016
3017# ------------------------------------------------------------------------------
3018
3019#Method void drawPoints(PointMode mode, size_t count, const SkPoint pts[], const SkPaint& paint)
3020
3021Draw pts using Clip, Matrix and Paint paint.
3022count is the number of points; if count is less than one, drawPoints has no effect.
3023mode may be one of: kPoints_PointMode, kLines_PointMode, or kPolygon_PointMode.
3024
3025If mode is kPoints_PointMode, the shape of point drawn depends on paint Paint_Stroke_Cap.
3026If paint is set to SkPaint::kRound_Cap, each point draws a circle of diameter Paint_Stroke_Width.
3027If paint is set to SkPaint::kSquare_Cap or SkPaint::kButt_Cap,
3028each point draws a square of width and height Paint_Stroke_Width.
3029
3030If mode is kLines_PointMode, each pair of points draws a line segment.
3031One line is drawn for every two points; each point is used once. If count is odd,
3032the final point is ignored.
3033
3034If mode is kPolygon_PointMode, each adjacent pair of points draws a line segment.
3035count minus one lines are drawn; the first and last point are used once.
3036
3037Each line segment respects paint Paint_Stroke_Cap and Paint_Stroke_Width.
3038Paint_Style is ignored, as if were set to SkPaint::kStroke_Style.
3039
3040drawPoints always draws each element one at a time; drawPoints is not affected by
3041Paint_Stroke_Join, and unlike drawPath, does not create a mask from all points and lines
3042before drawing.
3043
3044#Param mode Whether pts draws points or lines. ##
3045#Param count The number of points in the array. ##
3046#Param pts Array of points to draw. ##
3047#Param paint Stroke, blend, color, and so on, used to draw. ##
3048
3049#Example
3050#Height 200
3051 #Description
3052 #List
3053 # The first column draws points. ##
3054 # The second column draws points as lines. ##
3055 # The third column draws points as a polygon. ##
3056 # The fourth column draws points as a polygonal path. ##
3057 # The first row uses a round cap and round join. ##
3058 # The second row uses a square cap and a miter join. ##
3059 # The third row uses a butt cap and a bevel join. ##
3060 ##
3061 The transparent color makes multiple line draws visible;
3062 the path is drawn all at once.
3063 ##
3064void draw(SkCanvas* canvas) {
3065 SkPaint paint;
3066 paint.setAntiAlias(true);
3067 paint.setStyle(SkPaint::kStroke_Style);
3068 paint.setStrokeWidth(10);
3069 paint.setColor(0x80349a45);
3070 const SkPoint points[] = {{32, 16}, {48, 48}, {16, 32}};
3071 const SkPaint::Join join[] = { SkPaint::kRound_Join,
3072 SkPaint::kMiter_Join,
3073 SkPaint::kBevel_Join };
3074 int joinIndex = 0;
3075 SkPath path;
3076 path.addPoly(points, 3, false);
3077 for (const auto cap : { SkPaint::kRound_Cap, SkPaint::kSquare_Cap, SkPaint::kButt_Cap } ) {
3078 paint.setStrokeCap(cap);
3079 paint.setStrokeJoin(join[joinIndex++]);
3080 for (const auto mode : { SkCanvas::kPoints_PointMode,
3081 SkCanvas::kLines_PointMode,
3082 SkCanvas::kPolygon_PointMode } ) {
3083 canvas->drawPoints(mode, 3, points, paint);
3084 canvas->translate(64, 0);
3085 }
3086 canvas->drawPath(path, paint);
3087 canvas->translate(-192, 64);
3088 }
3089}
3090##
3091
3092#ToDo incomplete ##
3093
3094##
3095
3096# ------------------------------------------------------------------------------
3097
3098#Method void drawPoint(SkScalar x, SkScalar y, const SkPaint& paint)
3099
3100Draw point at (x, y) using Clip, Matrix and Paint paint.
3101
3102The shape of point drawn depends on paint Paint_Stroke_Cap.
3103If paint is set to SkPaint::kRound_Cap, draw a circle of diameter Paint_Stroke_Width.
3104If paint is set to SkPaint::kSquare_Cap or SkPaint::kButt_Cap,
3105draw a square of width and height Paint_Stroke_Width.
3106Paint_Style is ignored, as if were set to SkPaint::kStroke_Style.
3107
3108#Param x Left edge of circle or square. ##
3109#Param y Top edge of circle or square. ##
3110#Param paint Stroke, blend, color, and so on, used to draw. ##
3111
3112#Example
3113void draw(SkCanvas* canvas) {
3114 SkPaint paint;
3115 paint.setAntiAlias(true);
3116 paint.setColor(0x80349a45);
3117 paint.setStyle(SkPaint::kStroke_Style);
3118 paint.setStrokeWidth(100);
3119 paint.setStrokeCap(SkPaint::kRound_Cap);
3120 canvas->scale(1, 1.2f);
3121 canvas->drawPoint(64, 96, paint);
3122 canvas->scale(.6f, .8f);
3123 paint.setColor(SK_ColorWHITE);
3124 canvas->drawPoint(106, 120, paint);
3125}
3126##
3127
3128#ToDo incomplete ##
3129
3130##
3131
3132# ------------------------------------------------------------------------------
3133
3134#Method void drawLine(SkScalar x0, SkScalar y0, SkScalar x1, SkScalar y1, const SkPaint& paint)
3135
3136Draw line segment from (x0, y0) to (x1, y1) using Clip, Matrix, and Paint paint.
3137In paint: Paint_Stroke_Width describes the line thickness; Paint_Stroke_Cap draws the end rounded or square;
3138Paint_Style is ignored, as if were set to SkPaint::kStroke_Style.
3139
3140#Param x0 Start of line segment on x-axis. ##
3141#Param y0 Start of line segment on y-axis. ##
3142#Param x1 End of line segment on x-axis. ##
3143#Param y1 End of line segment on y-axis. ##
3144#Param paint Stroke, blend, color, and so on, used to draw. ##
3145
3146#Example
3147 SkPaint paint;
3148 paint.setAntiAlias(true);
3149 paint.setColor(0xFF9a67be);
3150 paint.setStrokeWidth(20);
3151 canvas->skew(1, 0);
3152 canvas->drawLine(32, 96, 32, 160, paint);
3153 canvas->skew(-2, 0);
3154 canvas->drawLine(288, 96, 288, 160, paint);
3155##
3156
3157#ToDo incomplete ##
3158
3159##
3160
3161# ------------------------------------------------------------------------------
3162
3163#Method void drawRect(const SkRect& rect, const SkPaint& paint)
3164
3165Draw Rect rect using Clip, Matrix, and Paint paint.
3166In paint: Paint_Style determines if rectangle is stroked or filled;
3167if stroked, Paint_Stroke_Width describes the line thickness, and
3168Paint_Stroke_Join draws the corners rounded or square.
3169
3170#Param rect The rectangle to be drawn. ##
3171#Param paint Stroke or fill, blend, color, and so on, used to draw. ##
3172
3173#Example
3174void draw(SkCanvas* canvas) {
3175 SkPoint rectPts[] = { {64, 48}, {192, 160} };
3176 SkPaint paint;
3177 paint.setAntiAlias(true);
3178 paint.setStyle(SkPaint::kStroke_Style);
3179 paint.setStrokeWidth(20);
3180 paint.setStrokeJoin(SkPaint::kRound_Join);
3181 SkMatrix rotator;
3182 rotator.setRotate(30, 128, 128);
3183 for (auto color : { SK_ColorRED, SK_ColorBLUE, SK_ColorYELLOW, SK_ColorMAGENTA } ) {
3184 paint.setColor(color);
3185 SkRect rect;
3186 rect.set(rectPts[0], rectPts[1]);
3187 canvas->drawRect(rect, paint);
3188 rotator.mapPoints(rectPts, 2);
3189 }
3190}
3191##
3192
3193#ToDo incomplete ##
3194
3195##
3196
3197# ------------------------------------------------------------------------------
3198
3199#Method void drawIRect(const SkIRect& rect, const SkPaint& paint)
3200
3201Draw IRect rect using Clip, Matrix, and Paint paint.
3202In paint: Paint_Style determines if rectangle is stroked or filled;
3203if stroked, Paint_Stroke_Width describes the line thickness, and
3204Paint_Stroke_Join draws the corners rounded or square.
3205
3206#Param rect The rectangle to be drawn. ##
3207#Param paint Stroke or fill, blend, color, and so on, used to draw. ##
3208
3209#Example
3210 SkIRect rect = { 64, 48, 192, 160 };
3211 SkPaint paint;
3212 paint.setAntiAlias(true);
3213 paint.setStyle(SkPaint::kStroke_Style);
3214 paint.setStrokeWidth(20);
3215 paint.setStrokeJoin(SkPaint::kRound_Join);
3216 for (auto color : { SK_ColorRED, SK_ColorBLUE, SK_ColorYELLOW, SK_ColorMAGENTA } ) {
3217 paint.setColor(color);
3218 canvas->drawIRect(rect, paint);
3219 canvas->rotate(30, 128, 128);
3220 }
3221##
3222
3223#ToDo incomplete ##
3224
3225##
3226
3227# ------------------------------------------------------------------------------
3228
3229#Method void drawRegion(const SkRegion& region, const SkPaint& paint)
3230
3231Draw Region region using Clip, Matrix, and Paint paint.
3232In paint: Paint_Style determines if rectangle is stroked or filled;
3233if stroked, Paint_Stroke_Width describes the line thickness, and
3234Paint_Stroke_Join draws the corners rounded or square.
3235
3236#Param region The region to be drawn. ##
3237#Param paint Paint stroke or fill, blend, color, and so on, used to draw. ##
3238
3239#Example
3240void draw(SkCanvas* canvas) {
3241 SkRegion region;
3242 region.op( 10, 10, 50, 50, SkRegion::kUnion_Op);
3243 region.op( 10, 50, 90, 90, SkRegion::kUnion_Op);
3244 SkPaint paint;
3245 paint.setAntiAlias(true);
3246 paint.setStyle(SkPaint::kStroke_Style);
3247 paint.setStrokeWidth(20);
3248 paint.setStrokeJoin(SkPaint::kRound_Join);
3249 canvas->drawRegion(region, paint);
3250}
3251##
3252
3253#ToDo incomplete ##
3254
3255##
3256
3257# ------------------------------------------------------------------------------
3258
3259#Method void drawOval(const SkRect& oval, const SkPaint& paint)
3260
3261Draw Oval oval using Clip, Matrix, and Paint.
3262In paint: Paint_Style determines if Oval is stroked or filled;
3263if stroked, Paint_Stroke_Width describes the line thickness.
3264
3265#Param oval Rect bounds of Oval. ##
3266#Param paint Paint stroke or fill, blend, color, and so on, used to draw. ##
3267
3268#Example
3269void draw(SkCanvas* canvas) {
3270 canvas->clear(0xFF3f5f9f);
3271 SkColor kColor1 = SkColorSetARGB(0xff, 0xff, 0x7f, 0);
3272 SkColor g1Colors[] = { kColor1, SkColorSetA(kColor1, 0x20) };
3273 SkPoint g1Points[] = { { 0, 0 }, { 0, 100 } };
3274 SkScalar pos[] = { 0.2f, 1.0f };
3275 SkRect bounds = SkRect::MakeWH(80, 70);
3276 SkPaint paint;
3277 paint.setAntiAlias(true);
3278 paint.setShader(SkGradientShader::MakeLinear(g1Points, g1Colors, pos, SK_ARRAY_COUNT(g1Colors),
3279 SkShader::kClamp_TileMode));
3280 canvas->drawOval(bounds , paint);
3281}
3282##
3283
3284#ToDo incomplete ##
3285
3286##
3287
3288# ------------------------------------------------------------------------------
3289
3290#Method void drawRRect(const SkRRect& rrect, const SkPaint& paint)
3291
3292Draw Round_Rect rrect using Clip, Matrix, and Paint paint.
3293In paint: Paint_Style determines if rrect is stroked or filled;
3294if stroked, Paint_Stroke_Width describes the line thickness.
3295
3296rrect may represent a rectangle, circle, oval, uniformly rounded rectangle, or may have
3297any combination of positive non-square radii for the four corners.
3298
3299#Param rrect Round_Rect with up to eight corner radii to draw. ##
3300#Param paint Paint stroke or fill, blend, color, and so on, used to draw. ##
3301
3302#Example
3303void draw(SkCanvas* canvas) {
3304 SkPaint paint;
3305 paint.setAntiAlias(true);
3306 SkRect outer = {30, 40, 210, 220};
3307 SkRect radii = {30, 50, 70, 90 };
3308 SkRRect rRect;
3309 rRect.setNinePatch(outer, radii.fLeft, radii.fTop, radii.fRight, radii.fBottom);
3310 canvas->drawRRect(rRect, paint);
3311 paint.setColor(SK_ColorWHITE);
3312 canvas->drawLine(outer.fLeft + radii.fLeft, outer.fTop,
3313 outer.fLeft + radii.fLeft, outer.fBottom, paint);
3314 canvas->drawLine(outer.fRight - radii.fRight, outer.fTop,
3315 outer.fRight - radii.fRight, outer.fBottom, paint);
3316 canvas->drawLine(outer.fLeft, outer.fTop + radii.fTop,
3317 outer.fRight, outer.fTop + radii.fTop, paint);
3318 canvas->drawLine(outer.fLeft, outer.fBottom - radii.fBottom,
3319 outer.fRight, outer.fBottom - radii.fBottom, paint);
3320}
3321##
3322
3323#ToDo incomplete ##
3324
3325##
3326
3327# ------------------------------------------------------------------------------
3328
3329#Method void drawDRRect(const SkRRect& outer, const SkRRect& inner, const SkPaint& paint)
3330
3331Draw Round_Rect outer and inner
3332using Clip, Matrix, and Paint paint.
3333outer must contain inner or the drawing is undefined.
3334In paint: Paint_Style determines if rrect is stroked or filled;
3335if stroked, Paint_Stroke_Width describes the line thickness.
3336If stroked and Round_Rect corner has zero length radii, Paint_Stroke_Join can draw
3337corners rounded or square.
3338
3339GPU-backed platforms take advantage of drawDRRect since both outer and inner are
3340concave and outer contains inner. These platforms may not be able to draw
3341Path built with identical data as fast.
3342
3343#Param outer Round_Rect outer bounds to draw. ##
3344#Param inner Round_Rect inner bounds to draw. ##
3345#Param paint Paint stroke or fill, blend, color, and so on, used to draw. ##
3346
3347#Example
3348void draw(SkCanvas* canvas) {
3349 SkRRect outer = SkRRect::MakeRect({20, 40, 210, 200});
3350 SkRRect inner = SkRRect::MakeOval({60, 70, 170, 160});
3351 SkPaint paint;
3352 canvas->drawDRRect(outer, inner, paint);
3353}
3354##
3355
3356#Example
3357#Description
3358 Outer Rect has no corner radii, but stroke join is rounded.
3359 Inner Round_Rect has corner radii; outset stroke increases radii of corners.
3360 Stroke join does not affect inner Round_Rect since it has no sharp corners.
3361##
3362void draw(SkCanvas* canvas) {
3363 SkRRect outer = SkRRect::MakeRect({20, 40, 210, 200});
3364 SkRRect inner = SkRRect::MakeRectXY({60, 70, 170, 160}, 10, 10);
3365 SkPaint paint;
3366 paint.setAntiAlias(true);
3367 paint.setStyle(SkPaint::kStroke_Style);
3368 paint.setStrokeWidth(20);
3369 paint.setStrokeJoin(SkPaint::kRound_Join);
3370 canvas->drawDRRect(outer, inner, paint);
3371 paint.setStrokeWidth(1);
3372 paint.setColor(SK_ColorWHITE);
3373 canvas->drawDRRect(outer, inner, paint);
3374}
3375##
3376
3377#ToDo incomplete ##
3378
3379##
3380
3381# ------------------------------------------------------------------------------
3382
3383#Method void drawCircle(SkScalar cx, SkScalar cy, SkScalar radius, const SkPaint& paint)
3384
3385Draw Circle at (cx, cy) with radius using Clip, Matrix, and Paint paint.
3386If radius is zero or less, nothing is drawn.
3387In paint: Paint_Style determines if Circle is stroked or filled;
3388if stroked, Paint_Stroke_Width describes the line thickness.
3389
3390#Param cx Circle center on the x-axis. ##
3391#Param cy Circle center on the y-axis. ##
3392#Param radius Half the diameter of Circle. ##
3393#Param paint Paint stroke or fill, blend, color, and so on, used to draw. ##
3394
3395#Example
3396 void draw(SkCanvas* canvas) {
3397 SkPaint paint;
3398 paint.setAntiAlias(true);
3399 canvas->drawCircle(128, 128, 90, paint);
3400 paint.setColor(SK_ColorWHITE);
3401 canvas->drawCircle(86, 86, 20, paint);
3402 canvas->drawCircle(160, 76, 20, paint);
3403 canvas->drawCircle(140, 150, 35, paint);
3404 }
3405##
3406
3407#ToDo incomplete ##
3408
3409##
3410
3411# ------------------------------------------------------------------------------
3412
3413#Method void drawArc(const SkRect& oval, SkScalar startAngle, SkScalar sweepAngle,
3414 bool useCenter, const SkPaint& paint)
3415
3416Draw Arc using Clip, Matrix, and Paint paint.
3417Arc is part of Oval bounded by oval, sweeping from startAngle to startAngle plus
3418sweepAngle. startAngle and sweepAngle are in degrees.
3419startAngle of zero places start point at the right middle edge of oval.
3420A positive sweepAngle places Arc end point clockwise from start point;
3421a negative sweepAngle places Arc end point counterclockwise from start point.
3422sweepAngle may exceed 360 degrees, a full circle.
3423If useCenter is true, draw a wedge that includes lines from oval
3424center to Arc end points. If useCenter is false, draw Arc between end points.
3425
3426If Rect oval is empty or sweepAngle is zero, nothing is drawn.
3427
3428#Param oval Rect bounds of Oval containing Arc to draw. ##
3429#Param startAngle Angle in degrees where Arc begins. ##
3430#Param sweepAngle Sweep angle in degrees; positive is clockwise. ##
3431#Param useCenter If true include the center of the oval. ##
3432#Param paint Paint stroke or fill, blend, color, and so on, used to draw. ##
3433
3434#Example
3435 void draw(SkCanvas* canvas) {
3436 SkPaint paint;
3437 paint.setAntiAlias(true);
3438 SkRect oval = { 4, 4, 60, 60};
3439 for (auto useCenter : { false, true } ) {
3440 for (auto style : { SkPaint::kFill_Style, SkPaint::kStroke_Style } ) {
3441 paint.setStyle(style);
3442 for (auto degrees : { 45, 90, 180, 360} ) {
3443 canvas->drawArc(oval, 0, degrees , useCenter, paint);
3444 canvas->translate(64, 0);
3445 }
3446 canvas->translate(-256, 64);
3447 }
3448 }
3449 }
3450##
3451
3452#Example
3453#Height 64
3454 void draw(SkCanvas* canvas) {
3455 SkPaint paint;
3456 paint.setAntiAlias(true);
3457 paint.setStyle(SkPaint::kStroke_Style);
3458 paint.setStrokeWidth(4);
3459 SkRect oval = { 4, 4, 60, 60};
3460 float intervals[] = { 5, 5 };
3461 paint.setPathEffect(SkDashPathEffect::Make(intervals, 2, 2.5f));
3462 for (auto degrees : { 270, 360, 540, 720 } ) {
3463 canvas->drawArc(oval, 0, degrees, false, paint);
3464 canvas->translate(64, 0);
3465 }
3466 }
3467##
3468
3469#ToDo incomplete ##
3470
3471##
3472
3473# ------------------------------------------------------------------------------
3474
3475#Method void drawRoundRect(const SkRect& rect, SkScalar rx, SkScalar ry, const SkPaint& paint)
3476
3477Draw Round_Rect bounded by Rect rect, with corner radii (rx, ry) using Clip, Matrix,
3478and Paint paint.
3479In paint: Paint_Style determines if Round_Rect is stroked or filled;
3480if stroked, Paint_Stroke_Width describes the line thickness.
3481If rx or ry are less than zero, they are treated as if they are zero.
3482If rx plus ry exceeds rect width or rect height, radii are scaled down to fit.
3483If rx and ry are zero, Round_Rect is drawn as Rect and if stroked is affected by Paint_Stroke_Join.
3484
3485#Param rect Rect bounds of Round_Rect to draw. ##
3486#Param rx Semiaxis length in x of oval describing rounded corners. ##
3487#Param ry Semiaxis length in y of oval describing rounded corners. ##
3488#Param paint Stroke, blend, color, and so on, used to draw. ##
3489
3490#Example
3491#Description
3492 Top row has a zero radius a generates a rectangle.
3493 Second row radii sum to less than sides.
3494 Third row radii sum equals sides.
3495 Fourth row radii sum exceeds sides; radii are scaled to fit.
3496##
3497 void draw(SkCanvas* canvas) {
3498 SkVector radii[] = { {0, 20}, {10, 10}, {10, 20}, {10, 40} };
3499 SkPaint paint;
3500 paint.setStrokeWidth(15);
3501 paint.setStrokeJoin(SkPaint::kRound_Join);
3502 paint.setAntiAlias(true);
3503 for (auto style : { SkPaint::kStroke_Style, SkPaint::kFill_Style } ) {
3504 paint.setStyle(style );
3505 for (size_t i = 0; i < SK_ARRAY_COUNT(radii); ++i) {
3506 canvas->drawRoundRect({10, 10, 60, 40}, radii[i].fX, radii[i].fY, paint);
3507 canvas->translate(0, 60);
3508 }
3509 canvas->translate(80, -240);
3510 }
3511 }
3512##
3513
3514#ToDo incomplete ##
3515
3516##
3517
3518# ------------------------------------------------------------------------------
3519
3520#Method void drawPath(const SkPath& path, const SkPaint& paint)
3521
3522Draw Path path using Clip, Matrix, and Paint paint.
3523Path contains an array of Path_Contour, each of which may be open or closed.
3524
3525In paint: Paint_Style determines if Round_Rect is stroked or filled:
3526if filled, Path_Fill_Type determines whether Path_Contour describes inside or outside of fill;
3527if stroked, Paint_Stroke_Width describes the line thickness, Paint_Stroke_Cap describes line ends,
3528and Paint_Stroke_Join describes how corners are drawn.
3529
3530#Param path Path to draw. ##
3531#Param paint Stroke, blend, color, and so on, used to draw. ##
3532
3533#Example
3534#Description
3535 Top rows draw stroked path with combinations of joins and caps. The open contour
3536 is affected by caps; the closed contour is affected by joins.
3537 Bottom row draws fill the same for open and closed contour.
3538 First bottom column shows winding fills overlap.
3539 Second bottom column shows even odd fills exclude overlap.
3540 Third bottom column shows inverse winding fills area outside both contours.
3541##
3542void draw(SkCanvas* canvas) {
3543 SkPath path;
3544 path.moveTo(20, 20);
3545 path.quadTo(60, 20, 60, 60);
3546 path.close();
3547 path.moveTo(60, 20);
3548 path.quadTo(60, 60, 20, 60);
3549 SkPaint paint;
3550 paint.setStrokeWidth(10);
3551 paint.setAntiAlias(true);
3552 paint.setStyle(SkPaint::kStroke_Style);
3553 for (auto join: { SkPaint::kBevel_Join, SkPaint::kRound_Join, SkPaint::kMiter_Join } ) {
3554 paint.setStrokeJoin(join);
3555 for (auto cap: { SkPaint::kButt_Cap, SkPaint::kSquare_Cap, SkPaint::kRound_Cap } ) {
3556 paint.setStrokeCap(cap);
3557 canvas->drawPath(path, paint);
3558 canvas->translate(80, 0);
3559 }
3560 canvas->translate(-240, 60);
3561 }
3562 paint.setStyle(SkPaint::kFill_Style);
3563 for (auto fill : { SkPath::kWinding_FillType,
3564 SkPath::kEvenOdd_FillType,
3565 SkPath::kInverseWinding_FillType } ) {
3566 path.setFillType(fill);
3567 canvas->save();
3568 canvas->clipRect({0, 10, 80, 70});
3569 canvas->drawPath(path, paint);
3570 canvas->restore();
3571 canvas->translate(80, 0);
3572 }
3573}
3574##
3575
3576#ToDo incomplete ##
3577
3578##
3579
3580# ------------------------------------------------------------------------------
3581#Topic Draw_Image
3582
3583drawImage, drawImageRect, and drawImageNine can be called with a bare pointer or a smart pointer as a convenience.
3584The pairs of calls are otherwise identical.
3585
3586
3587#Method void drawImage(const SkImage* image, SkScalar left, SkScalar top, const SkPaint* paint = NULL)
3588
3589Draw Image image, with its top-left corner at (left, top),
3590using Clip, Matrix, and optional Paint paint.
3591
3592If paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter, Blend_Mode, and Draw_Looper.
3593If image is kAlpha_8_SkColorType, apply Shader.
3594if paint contains Mask_Filter, generate mask from image bounds. If generated mask extends
3595beyond image bounds, replicate image edge colors, just as Shader made from
3596SkImage::makeShader with SkShader::kClamp_TileMode set replicates the image's edge
3597color when it samples outside of its bounds.
3598
3599#Param image Uncompressed rectangular map of pixels. ##
3600#Param left Left side of image. ##
3601#Param top Top side of image. ##
3602#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter, and so on; or nullptr. ##
3603
3604#Example
3605#Height 64
3606#Image 4
3607void draw(SkCanvas* canvas) {
3608 // sk_sp<SkImage> image;
3609 SkImage* imagePtr = image.get();
3610 canvas->drawImage(imagePtr, 0, 0);
3611 SkPaint paint;
3612 canvas->drawImage(imagePtr, 80, 0, &paint);
3613 paint.setAlpha(0x80);
3614 canvas->drawImage(imagePtr, 160, 0, &paint);
3615}
3616##
3617
3618#ToDo incomplete ##
3619
3620##
3621
3622# ------------------------------------------------------------------------------
3623
3624#Method void drawImage(const sk_sp<SkImage>& image, SkScalar left, SkScalar top,
3625 const SkPaint* paint = NULL)
3626
3627Draw Image image, with its top-left corner at (left, top),
3628using Clip, Matrix, and optional Paint paint.
3629
3630If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter, Blend_Mode, and Draw_Looper.
3631If image is kAlpha_8_SkColorType, apply Shader.
3632if paint contains Mask_Filter, generate mask from image bounds. If generated mask extends
3633beyond image bounds, replicate image edge colors, just as Shader made from
3634SkImage::makeShader with SkShader::kClamp_TileMode set replicates the image's edge
3635color when it samples outside of its bounds.
3636
3637#Param image Uncompressed rectangular map of pixels. ##
3638#Param left Left side of image. ##
3639#Param top Top side of image. ##
3640#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter, and so on; or nullptr. ##
3641
3642#Example
3643#Height 64
3644#Image 4
3645void draw(SkCanvas* canvas) {
3646 // sk_sp<SkImage> image;
3647 canvas->drawImage(image, 0, 0);
3648 SkPaint paint;
3649 canvas->drawImage(image, 80, 0, &paint);
3650 paint.setAlpha(0x80);
3651 canvas->drawImage(image, 160, 0, &paint);
3652}
3653##
3654
3655#ToDo incomplete ##
3656
3657##
3658
3659# ------------------------------------------------------------------------------
3660
3661#Enum SrcRectConstraint
3662
3663#Code
3664 enum SrcRectConstraint {
3665 kStrict_SrcRectConstraint,
3666 kFast_SrcRectConstraint,
3667 };
3668##
3669
3670SrcRectConstraint controls the behavior at the edge of the Rect src, provided to drawImageRect,
3671trading off speed for precision.
3672
3673Image_Filter in Paint may sample multiple pixels in the image.
3674Rect src restricts the bounds of pixels that may be read. Image_Filter may slow
3675down if it cannot read outside the bounds, when sampling near the edge of Rect src.
3676SrcRectConstraint specifies whether an Image_Filter is allowed to read pixels
3677outside Rect src.
3678
3679#Const kStrict_SrcRectConstraint
3680 Requires Image_Filter to respect Rect src,
3681 sampling only inside of its bounds, possibly with a performance penalty.
3682##
3683
3684#Const kFast_SrcRectConstraint
3685 Permits Image_Filter to sample outside of Rect src
3686 by half the width of Image_Filter, permitting it to run faster but with
3687 error at the image edges.
3688##
3689
3690#Example
3691#Height 64
3692#Description
3693 redBorder contains a black and white checkerboard bordered by red.
3694 redBorder is drawn scaled by 16 on the left.
3695 The middle and right bitmaps are filtered checkboards.
3696 Drawing the checkerboard with kStrict_SrcRectConstraint shows only a blur of black and white.
3697 Drawing the checkerboard with kFast_SrcRectConstraint allows red to bleed in the corners.
3698##
3699void draw(SkCanvas* canvas) {
3700 SkBitmap redBorder;
3701 redBorder.allocPixels(SkImageInfo::MakeN32Premul(4, 4));
3702 SkCanvas checkRed(redBorder);
3703 checkRed.clear(SK_ColorRED);
3704 uint32_t checkers[][2] = { { SK_ColorBLACK, SK_ColorWHITE },
3705 { SK_ColorWHITE, SK_ColorBLACK } };
3706 checkRed.writePixels(
3707 SkImageInfo::MakeN32Premul(2, 2), (void*) checkers, sizeof(checkers[0]), 1, 1);
3708 canvas->scale(16, 16);
3709 canvas->drawBitmap(redBorder, 0, 0, nullptr);
3710 canvas->resetMatrix();
3711 sk_sp<SkImage> image = SkImage::MakeFromBitmap(redBorder);
3712 SkPaint lowPaint;
3713 lowPaint.setFilterQuality(kLow_SkFilterQuality);
3714 for (auto constraint : { SkCanvas::kStrict_SrcRectConstraint,
3715 SkCanvas::kFast_SrcRectConstraint } ) {
3716 canvas->translate(80, 0);
3717 canvas->drawImageRect(image.get(), SkRect::MakeLTRB(1, 1, 3, 3),
3718 SkRect::MakeLTRB(16, 16, 48, 48), &lowPaint, constraint);
3719 }
3720}
3721##
3722
3723#ToDo incomplete ##
3724
3725##
3726
3727# ------------------------------------------------------------------------------
3728
3729#Method void drawImageRect(const SkImage* image, const SkRect& src, const SkRect& dst,
3730 const SkPaint* paint,
3731 SrcRectConstraint constraint = kStrict_SrcRectConstraint)
3732
3733Draw Rect src of Image image, scaled and translated to fill Rect dst.
3734Additionally transform draw using Clip, Matrix, and optional Paint paint.
3735If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter, Blend_Mode, and Draw_Looper.
3736If image is kAlpha_8_SkColorType, apply Shader.
3737if paint contains Mask_Filter, generate mask from image bounds. If generated mask extends
3738beyond image bounds, replicate image edge colors, just as Shader made from
3739SkImage::makeShader with SkShader::kClamp_TileMode set replicates the image's edge
3740color when it samples outside of its bounds.
3741constraint set to kStrict_SrcRectConstraint limits Paint Filter_Quality to sample within src;
3742set to kFast_SrcRectConstraint allows sampling outside to improve performance.
3743
3744#Param image Image containing pixels, dimensions, and format. ##
3745#Param src Source Rect of image to draw from. ##
3746#Param dst Destination Rect of image to draw to. ##
3747#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter, and so on; or nullptr. ##
3748#Param constraint Filter strictly within src or draw faster. ##
3749
3750#Example
3751#Height 64
3752#Description
3753 The left bitmap draws with Paint default kNone_SkFilterQuality, and stays within
3754 its bounds; there's no bleeding with kFast_SrcRectConstraint.
3755 the middle and right bitmaps draw with kLow_SkFilterQuality; with
3756 kStrict_SrcRectConstraint, the filter remains within the checkerboard, and
3757 with kFast_SrcRectConstraint red bleeds on the edges.
3758##
3759void draw(SkCanvas* canvas) {
3760 uint32_t pixels[][4] = {
3761 { 0xFFFF0000, 0xFFFF0000, 0xFFFF0000, 0xFFFF0000 },
3762 { 0xFFFF0000, 0xFF000000, 0xFFFFFFFF, 0xFFFF0000 },
3763 { 0xFFFF0000, 0xFFFFFFFF, 0xFF000000, 0xFFFF0000 },
3764 { 0xFFFF0000, 0xFFFF0000, 0xFFFF0000, 0xFFFF0000 } };
3765 SkBitmap redBorder;
3766 redBorder.installPixels(SkImageInfo::MakeN32Premul(4, 4),
3767 (void*) pixels, sizeof(pixels[0]));
3768 sk_sp<SkImage> image = SkImage::MakeFromBitmap(redBorder);
3769 SkPaint lowPaint;
3770 for (auto constraint : {
3771 SkCanvas::kFast_SrcRectConstraint,
3772 SkCanvas::kStrict_SrcRectConstraint,
3773 SkCanvas::kFast_SrcRectConstraint } ) {
3774 canvas->drawImageRect(image.get(), SkRect::MakeLTRB(1, 1, 3, 3),
3775 SkRect::MakeLTRB(16, 16, 48, 48), &lowPaint, constraint);
3776 lowPaint.setFilterQuality(kLow_SkFilterQuality);
3777 canvas->translate(80, 0);
3778 }
3779}
3780##
3781
3782#ToDo incomplete ##
3783
3784##
3785
3786# ------------------------------------------------------------------------------
3787
3788#Method void drawImageRect(const SkImage* image, const SkIRect& isrc, const SkRect& dst,
3789 const SkPaint* paint, SrcRectConstraint constraint = kStrict_SrcRectConstraint)
3790
3791Draw IRect isrc of Image image, scaled and translated to fill Rect dst.
3792Note that isrc is on integer pixel boundaries; dst may include fractional boundaries.
3793Additionally transform draw using Clip, Matrix, and optional Paint paint.
3794If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter, Blend_Mode, and Draw_Looper.
3795If image is kAlpha_8_SkColorType, apply Shader.
3796if paint contains Mask_Filter, generate mask from image bounds. If generated mask extends
3797beyond image bounds, replicate image edge colors, just as Shader made from
3798SkImage::makeShader with SkShader::kClamp_TileMode set replicates the image's edge
3799color when it samples outside of its bounds.
3800constraint set to kStrict_SrcRectConstraint limits Paint Filter_Quality to sample within src;
3801set to kFast_SrcRectConstraint allows sampling outside to improve performance.
3802
3803#Param image Image containing pixels, dimensions, and format. ##
3804#Param isrc Source IRect of image to draw from. ##
3805#Param dst Destination Rect of image to draw to. ##
3806#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter, and so on; or nullptr. ##
3807#Param constraint Filter strictly within src or draw faster. ##
3808
3809#Example
3810#Image 4
3811void draw(SkCanvas* canvas) {
3812 // sk_sp<SkImage> image;
3813 for (auto i : { 1, 2, 4, 8 } ) {
3814 canvas->drawImageRect(image.get(), SkIRect::MakeLTRB(0, 0, 100, 100),
3815 SkRect::MakeXYWH(i * 20, i * 20, i * 20, i * 20), nullptr);
3816 }
3817}
3818##
3819
3820#ToDo incomplete ##
3821
3822##
3823
3824# ------------------------------------------------------------------------------
3825
3826#Method void drawImageRect(const SkImage* image, const SkRect& dst, const SkPaint* paint,
3827 SrcRectConstraint constraint = kStrict_SrcRectConstraint)
3828
3829Draw Image image, scaled and translated to fill Rect dst,
3830using Clip, Matrix, and optional Paint paint.
3831If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter, Blend_Mode, and Draw_Looper.
3832If image is kAlpha_8_SkColorType, apply Shader.
3833if paint contains Mask_Filter, generate mask from image bounds. If generated mask extends
3834beyond image bounds, replicate image edge colors, just as Shader made from
3835SkImage::makeShader with SkShader::kClamp_TileMode set replicates the image's edge
3836color when it samples outside of its bounds.
3837Use constaint to choose kStrict_SrcRectConstraint or kFast_SrcRectConstraint.
3838
3839#Param image Image containing pixels, dimensions, and format. ##
3840#Param dst Destination Rect of image to draw to. ##
3841#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter, and so on; or nullptr. ##
3842#Param constraint Filter strictly within src or draw faster. ##
3843
3844#Example
3845#Image 4
3846void draw(SkCanvas* canvas) {
3847 // sk_sp<SkImage> image;
3848 for (auto i : { 20, 40, 80, 160 } ) {
3849 canvas->drawImageRect(image.get(), SkRect::MakeXYWH(i, i, i, i), nullptr);
3850 }
3851}
3852##
3853
3854#ToDo incomplete ##
3855
3856##
3857
3858# ------------------------------------------------------------------------------
3859
3860#Method void drawImageRect(const sk_sp<SkImage>& image, const SkRect& src, const SkRect& dst,
3861 const SkPaint* paint,
3862 SrcRectConstraint constraint = kStrict_SrcRectConstraint)
3863
3864Draw Rect src of Image image, scaled and translated to fill Rect dst.
3865Additionally transform draw using Clip, Matrix, and optional Paint paint.
3866If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter, Blend_Mode, and Draw_Looper.
3867If image is kAlpha_8_SkColorType, apply Shader.
3868if paint contains Mask_Filter, generate mask from image bounds. If generated mask extends
3869beyond image bounds, replicate image edge colors, just as Shader made from
3870SkImage::makeShader with SkShader::kClamp_TileMode set replicates the image's edge
3871color when it samples outside of its bounds.
3872constraint set to kStrict_SrcRectConstraint limits Paint Filter_Quality to sample within src;
3873set to kFast_SrcRectConstraint allows sampling outside to improve performance.
3874
3875#Param image Image containing pixels, dimensions, and format. ##
3876#Param src Source Rect of image to draw from. ##
3877#Param dst Destination Rect of image to draw to. ##
3878#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter, and so on; or nullptr. ##
3879#Param constraint Filter strictly within src or draw faster. ##
3880
3881#Example
3882#Height 64
3883#Description
3884 Canvas scales and translates; transformation from src to dst also scales.
3885 The two matrices are concatenated to create the final transformation.
3886##
3887void draw(SkCanvas* canvas) {
3888 uint32_t pixels[][2] = { { SK_ColorBLACK, SK_ColorWHITE },
3889 { SK_ColorWHITE, SK_ColorBLACK } };
3890 SkBitmap bitmap;
3891 bitmap.installPixels(SkImageInfo::MakeN32Premul(2, 2),
3892 (void*) pixels, sizeof(pixels[0]));
3893 sk_sp<SkImage> image = SkImage::MakeFromBitmap(bitmap);
3894 SkPaint paint;
3895 canvas->scale(4, 4);
3896 for (auto alpha : { 50, 100, 150, 255 } ) {
3897 paint.setAlpha(alpha);
3898 canvas->drawImageRect(image, SkRect::MakeWH(2, 2), SkRect::MakeWH(8, 8), &paint);
3899 canvas->translate(8, 0);
3900 }
3901}
3902##
3903
3904#ToDo incomplete ##
3905
3906##
3907
3908# ------------------------------------------------------------------------------
3909
3910#Method void drawImageRect(const sk_sp<SkImage>& image, const SkIRect& isrc, const SkRect& dst,
3911 const SkPaint* paint, SrcRectConstraint constraint = kStrict_SrcRectConstraint)
3912
3913Draw IRect isrc of Image image, scaled and translated to fill Rect dst.
3914Note that isrc is on integer pixel boundaries; dst may include fractional boundaries.
3915Additionally transform draw using Clip, Matrix, and optional Paint paint.
3916If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter, Blend_Mode, and Draw_Looper.
3917If image is kAlpha_8_SkColorType, apply Shader.
3918if paint contains Mask_Filter, generate mask from image bounds. If generated mask extends
3919beyond image bounds, replicate image edge colors, just as Shader made from
3920SkShader::MakeBitmapShader with SkShader::kClamp_TileMode set replicates the image's edge
3921color when it samples outside of its bounds.
3922cons set to kStrict_SrcRectConstraint limits Paint Filter_Quality to sample within src;
3923set to kFast_SrcRectConstraint allows sampling outside to improve performance.
3924
3925#Param image Image containing pixels, dimensions, and format. ##
3926#Param isrc Source IRect of image to draw from. ##
3927#Param dst Destination Rect of image to draw to. ##
3928#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter, and so on; or nullptr. ##
3929#Param constraint Filter strictly within src or draw faster. ##
3930
3931#Example
3932#Height 64
3933void draw(SkCanvas* canvas) {
3934 uint32_t pixels[][2] = { { 0x00000000, 0x55555555},
3935 { 0xAAAAAAAA, 0xFFFFFFFF} };
3936 SkBitmap bitmap;
3937 bitmap.installPixels(SkImageInfo::MakeN32Premul(2, 2),
3938 (void*) pixels, sizeof(pixels[0]));
3939 sk_sp<SkImage> image = SkImage::MakeFromBitmap(bitmap);
3940 SkPaint paint;
3941 canvas->scale(4, 4);
3942 for (auto color : { SK_ColorRED, SK_ColorBLUE, SK_ColorGREEN } ) {
3943 paint.setColorFilter(SkColorFilter::MakeModeFilter(color, SkBlendMode::kPlus));
3944 canvas->drawImageRect(image, SkIRect::MakeWH(2, 2), SkRect::MakeWH(8, 8), &paint);
3945 canvas->translate(8, 0);
3946 }
3947}
3948##
3949
3950#ToDo incomplete ##
3951##
3952
3953# ------------------------------------------------------------------------------
3954
3955#Method void drawImageRect(const sk_sp<SkImage>& image, const SkRect& dst, const SkPaint* paint,
3956 SrcRectConstraint constraint = kStrict_SrcRectConstraint)
3957
3958Draw Image image, scaled and translated to fill Rect dst,
3959using Clip, Matrix, and optional Paint paint.
3960If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter, Blend_Mode, and Draw_Looper.
3961If image is kAlpha_8_SkColorType, apply Shader.
3962if paint contains Mask_Filter, generate mask from image bounds. If generated mask extends
3963beyond image bounds, replicate image edge colors, just as Shader made from
3964SkImage::makeShader with SkShader::kClamp_TileMode set replicates the image's edge
3965color when it samples outside of its bounds.
3966constraint set to kStrict_SrcRectConstraint limits Paint Filter_Quality to sample within src;
3967set to kFast_SrcRectConstraint allows sampling outside to improve performance.
3968
3969#Param image Image containing pixels, dimensions, and format. ##
3970#Param dst Destination Rect of image to draw to. ##
3971#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter, and so on; or nullptr. ##
3972#Param constraint Filter strictly within src or draw faster. ##
3973
3974#Example
3975#Height 64
3976void draw(SkCanvas* canvas) {
3977 uint32_t pixels[][2] = { { 0x00000000, 0x55550000},
3978 { 0xAAAA0000, 0xFFFF0000} };
3979 SkBitmap bitmap;
3980 bitmap.installPixels(SkImageInfo::MakeN32Premul(2, 2),
3981 (void*) pixels, sizeof(pixels[0]));
3982 sk_sp<SkImage> image = SkImage::MakeFromBitmap(bitmap);
3983 SkPaint paint;
3984 canvas->scale(4, 4);
3985 for (auto color : { SK_ColorRED, SK_ColorBLUE, SK_ColorGREEN } ) {
3986 paint.setColorFilter(SkColorFilter::MakeModeFilter(color, SkBlendMode::kPlus));
3987 canvas->drawImageRect(image, SkRect::MakeWH(8, 8), &paint);
3988 canvas->translate(8, 0);
3989 }
3990}
3991##
3992
3993#ToDo incomplete ##
3994
3995##
3996
3997# ------------------------------------------------------------------------------
3998
3999#Method void drawImageNine(const SkImage* image, const SkIRect& center, const SkRect& dst,
4000 const SkPaint* paint = nullptr)
4001
4002Draw Image image stretched differentially to fit into Rect dst.
4003IRect center divides the image into nine sections: four sides, four corners, and the center.
4004corners are unscaled or scaled down proportionately if their sides are larger than dst;
4005center and four sides are scaled to fit remaining space, if any.
4006Additionally transform draw using Clip, Matrix, and optional Paint paint.
4007If paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter, Blend_Mode, and Draw_Looper.
4008If image is kAlpha_8_SkColorType, apply Shader.
4009if paint contains Mask_Filter, generate mask from image bounds. If generated mask extends
4010beyond image bounds, replicate image edge colors, just as Shader made from
4011SkShader::MakeBitmapShader with SkShader::kClamp_TileMode set replicates the image's edge
4012color when it samples outside of its bounds.
4013
4014#Param image Image containing pixels, dimensions, and format. ##
4015#Param center IRect edge of image corners and sides. ##
4016#Param dst Destination Rect of image to draw to. ##
4017#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter, and so on; or nullptr. ##
4018
4019#Example
4020#Height 128
4021#Description
4022 The leftmost image is smaller than center; only corners are drawn, all scaled to fit.
4023 The second image equals the size of center; only corners are drawn, unscaled.
4024 The remaining images are larger than center. All corners draw unscaled. The sides
4025 and center are scaled if needed to take up the remaining space.
4026##
4027void draw(SkCanvas* canvas) {
4028 SkIRect center = { 20, 10, 50, 40 };
4029 SkBitmap bitmap;
4030 bitmap.allocPixels(SkImageInfo::MakeN32Premul(60, 60));
4031 SkCanvas bitCanvas(bitmap);
4032 SkPaint paint;
4033 SkColor gray = 0xFF000000;
4034 int left = 0;
4035 for (auto right: { center.fLeft, center.fRight, bitmap.width() } ) {
4036 int top = 0;
4037 for (auto bottom: { center.fTop, center.fBottom, bitmap.height() } ) {
4038 paint.setColor(gray);
4039 bitCanvas.drawIRect(SkIRect::MakeLTRB(left, top, right, bottom), paint);
4040 gray += 0x001f1f1f;
4041 top = bottom;
4042 }
4043 left = right;
4044 }
4045 sk_sp<SkImage> image = SkImage::MakeFromBitmap(bitmap);
4046 SkImage* imagePtr = image.get();
4047 for (auto dest: { 20, 30, 40, 60, 90 } ) {
4048 canvas->drawImageNine(imagePtr, center, SkRect::MakeWH(dest, dest), nullptr);
4049 canvas->translate(dest + 4, 0);
4050 }
4051}
4052##
4053
4054#ToDo incomplete ##
4055
4056##
4057
4058# ------------------------------------------------------------------------------
4059
4060#Method void drawImageNine(const sk_sp<SkImage>& image, const SkIRect& center, const SkRect& dst,
4061 const SkPaint* paint = nullptr)
4062
4063Draw Image image stretched differentially to fit into Rect dst.
4064IRect center divides the image into nine sections: four sides, four corners, and the center.
4065corners are unscaled or scaled down proportionately if their sides are larger than dst;
4066center and four sides are scaled to fit remaining space, if any.
4067Additionally transform draw using Clip, Matrix, and optional Paint paint.
4068If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter, Blend_Mode, and Draw_Looper.
4069If image is kAlpha_8_SkColorType, apply Shader.
4070if paint contains Mask_Filter, generate mask from image bounds. If generated mask extends
4071beyond image bounds, replicate image edge colors, just as Shader made from
4072SkShader::MakeBitmapShader with SkShader::kClamp_TileMode set replicates the image's edge
4073color when it samples outside of its bounds.
4074
4075#Param image Image containing pixels, dimensions, and format. ##
4076#Param center IRect edge of image corners and sides. ##
4077#Param dst Destination Rect of image to draw to. ##
4078#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter, and so on; or nullptr. ##
4079
4080#Example
4081#Height 128
4082#Description
4083 The two leftmost images has four corners and sides to the left and right of center.
4084 The leftmost image scales the width of corners proportionately to fit.
4085 The third and fourth image corners are unscaled; the sides and center are scaled to
4086 fill the remaining space.
4087 The rightmost image has four corners scaled vertically to fit, and uses sides above
4088 and below center to fill the remaining space.
4089##
4090void draw(SkCanvas* canvas) {
4091 SkIRect center = { 20, 10, 50, 40 };
4092 SkBitmap bitmap;
4093 bitmap.allocPixels(SkImageInfo::MakeN32Premul(60, 60));
4094 SkCanvas bitCanvas(bitmap);
4095 SkPaint paint;
4096 SkColor gray = 0xFF000000;
4097 int left = 0;
4098 for (auto right: { center.fLeft, center.fRight, bitmap.width() } ) {
4099 int top = 0;
4100 for (auto bottom: { center.fTop, center.fBottom, bitmap.height() } ) {
4101 paint.setColor(gray);
4102 bitCanvas.drawIRect(SkIRect::MakeLTRB(left, top, right, bottom), paint);
4103 gray += 0x001f1f1f;
4104 top = bottom;
4105 }
4106 left = right;
4107 }
4108 sk_sp<SkImage> image = SkImage::MakeFromBitmap(bitmap);
4109 for (auto dest: { 20, 30, 40, 60, 90 } ) {
4110 canvas->drawImageNine(image, center, SkRect::MakeWH(dest, 110 - dest), nullptr);
4111 canvas->translate(dest + 4, 0);
4112 }
4113}
4114##
4115
4116#ToDo incomplete ##
4117
4118##
4119
4120# ------------------------------------------------------------------------------
4121
4122#Method void drawBitmap(const SkBitmap& bitmap, SkScalar left, SkScalar top,
4123 const SkPaint* paint = NULL)
4124
4125Draw Bitmap bitmap, with its top-left corner at (left, top),
4126using Clip, Matrix, and optional Paint paint.
4127If paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter, Blend_Mode, and Draw_Looper.
4128If bitmap is kAlpha_8_SkColorType, apply Shader.
4129if paint contains Mask_Filter, generate mask from bitmap bounds. If generated mask extends
4130beyond bitmap bounds, replicate bitmap edge colors, just as Shader made from
4131SkShader::MakeBitmapShader with SkShader::kClamp_TileMode set replicates the bitmap's edge
4132color when it samples outside of its bounds.
4133
4134#Param bitmap Bitmap containing pixels, dimensions, and format. ##
4135#Param left Left side of bitmap. ##
4136#Param top Top side of bitmap. ##
4137#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter, and so on; or nullptr. ##
4138
4139#Example
4140#Height 64
4141void draw(SkCanvas* canvas) {
4142 uint8_t pixels[][8] = { { 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00},
4143 { 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00},
4144 { 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00},
4145 { 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF},
4146 { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
4147 { 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00},
4148 { 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0x00},
4149 { 0xFF, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0xFF} };
4150 SkBitmap bitmap;
4151 bitmap.installPixels(SkImageInfo::MakeA8(8, 8),
4152 (void*) pixels, sizeof(pixels[0]));
4153 SkPaint paint;
4154 canvas->scale(4, 4);
4155 for (auto color : { SK_ColorRED, SK_ColorBLUE, 0xFF007F00} ) {
4156 paint.setColor(color);
4157 canvas->drawBitmap(bitmap, 0, 0, &paint);
4158 canvas->translate(12, 0);
4159 }
4160}
4161##
4162
4163#ToDo incomplete ##
4164
4165##
4166
4167# ------------------------------------------------------------------------------
4168
4169#Method void drawBitmapRect(const SkBitmap& bitmap, const SkRect& src, const SkRect& dst,
4170 const SkPaint* paint, SrcRectConstraint constraint = kStrict_SrcRectConstraint)
4171
4172Draw Rect src of Bitmap bitmap, scaled and translated to fill Rect dst.
4173Additionally transform draw using Clip, Matrix, and optional Paint paint.
4174If paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter, Blend_Mode, and Draw_Looper.
4175If bitmap is kAlpha_8_SkColorType, apply Shader.
4176if paint contains Mask_Filter, generate mask from bitmap bounds. If generated mask extends
4177beyond bitmap bounds, replicate bitmap edge colors, just as Shader made from
4178SkShader::MakeBitmapShader with SkShader::kClamp_TileMode set replicates the bitmap's edge
4179color when it samples outside of its bounds.
4180constraint set to kStrict_SrcRectConstraint limits Paint Filter_Quality to sample within src;
4181set to kFast_SrcRectConstraint allows sampling outside to improve performance.
4182
4183#Param bitmap Bitmap containing pixels, dimensions, and format. ##
4184#Param src Source Rect of image to draw from. ##
4185#Param dst Destination Rect of image to draw to. ##
4186#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter, and so on; or nullptr. ##
4187#Param constraint Filter strictly within src or draw faster. ##
4188
4189#Example
4190#Height 64
4191void draw(SkCanvas* canvas) {
4192 uint8_t pixels[][8] = { { 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00},
4193 { 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00},
4194 { 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00},
4195 { 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF},
4196 { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
4197 { 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00},
4198 { 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00},
4199 { 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00} };
4200 SkBitmap bitmap;
4201 bitmap.installPixels(SkImageInfo::MakeA8(8, 8),
4202 (void*) pixels, sizeof(pixels[0]));
4203 SkPaint paint;
4204 paint.setMaskFilter(SkBlurMaskFilter::Make(kSolid_SkBlurStyle, 6));
4205 for (auto color : { SK_ColorRED, SK_ColorBLUE, 0xFF007F00} ) {
4206 paint.setColor(color);
4207 canvas->drawBitmapRect(bitmap, SkRect::MakeWH(8, 8), SkRect::MakeWH(32, 32), &paint);
4208 canvas->translate(48, 0);
4209 }
4210}
4211##
4212
4213#ToDo incomplete ##
4214
4215##
4216
4217# ------------------------------------------------------------------------------
4218
4219#Method void drawBitmapRect(const SkBitmap& bitmap, const SkIRect& isrc, const SkRect& dst,
4220 const SkPaint* paint, SrcRectConstraint constraint = kStrict_SrcRectConstraint)
4221
4222Draw IRect isrc of Bitmap bitmap, scaled and translated to fill Rect dst.
4223Note that isrc is on integer pixel boundaries; dst may include fractional boundaries.
4224Additionally transform draw using Clip, Matrix, and optional Paint paint.
4225If paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter, Blend_Mode, and Draw_Looper.
4226If bitmap is kAlpha_8_SkColorType, apply Shader.
4227if paint contains Mask_Filter, generate mask from bitmap bounds. If generated mask extends
4228beyond bitmap bounds, replicate bitmap edge colors, just as Shader made from
4229SkShader::MakeBitmapShader with SkShader::kClamp_TileMode set replicates the bitmap's edge
4230color when it samples outside of its bounds.
4231constraint set to kStrict_SrcRectConstraint limits Paint Filter_Quality to sample within src;
4232set to kFast_SrcRectConstraint allows sampling outside to improve performance.
4233
4234#Param bitmap Bitmap containing pixels, dimensions, and format. ##
4235#Param isrc Source IRect of image to draw from. ##
4236#Param dst Destination Rect of image to draw to. ##
4237#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter, and so on; or nullptr. ##
4238#Param constraint Filter strictly within src or draw faster. ##
4239
4240#Example
4241#Height 64
4242void draw(SkCanvas* canvas) {
4243 uint8_t pixels[][8] = { { 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00},
4244 { 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00},
4245 { 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0xFF},
4246 { 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0xFF},
4247 { 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF},
4248 { 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF},
4249 { 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00},
4250 { 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00} };
4251 SkBitmap bitmap;
4252 bitmap.installPixels(SkImageInfo::MakeA8(8, 8),
4253 (void*) pixels, sizeof(pixels[0]));
4254 SkPaint paint;
4255 paint.setFilterQuality(kHigh_SkFilterQuality);
4256 for (auto color : { SK_ColorRED, SK_ColorBLUE, 0xFF007F00, 0xFF7f007f} ) {
4257 paint.setColor(color);
4258 canvas->drawBitmapRect(bitmap, SkIRect::MakeWH(8, 8), SkRect::MakeWH(32, 32), &paint);
4259 canvas->translate(48.25f, 0);
4260 }
4261}
4262##
4263
4264#ToDo incomplete ##
4265
4266##
4267
4268# ------------------------------------------------------------------------------
4269
4270#Method void drawBitmapRect(const SkBitmap& bitmap, const SkRect& dst, const SkPaint* paint,
4271 SrcRectConstraint constraint = kStrict_SrcRectConstraint)
4272
4273Draw Bitmap bitmap, scaled and translated to fill Rect dst.
4274Note that isrc is on integer pixel boundaries; dst may include fractional boundaries.
4275Additionally transform draw using Clip, Matrix, and optional Paint paint.
4276If paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter, Blend_Mode, and Draw_Looper.
4277If bitmap is kAlpha_8_SkColorType, apply Shader.
4278if paint contains Mask_Filter, generate mask from bitmap bounds. If generated mask extends
4279beyond bitmap bounds, replicate bitmap edge colors, just as Shader made from
4280SkShader::MakeBitmapShader with SkShader::kClamp_TileMode set replicates the bitmap's edge
4281color when it samples outside of its bounds.
4282constraint set to kStrict_SrcRectConstraint limits Paint Filter_Quality to sample within src;
4283set to kFast_SrcRectConstraint allows sampling outside to improve performance.
4284
4285#Param bitmap Bitmap containing pixels, dimensions, and format. ##
4286#Param dst Destination Rect of image to draw to. ##
4287#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter, and so on; or nullptr. ##
4288#Param constraint Filter strictly within src or draw faster. ##
4289
4290#Example
4291#Height 64
4292void draw(SkCanvas* canvas) {
4293 uint32_t pixels[][2] = { { 0x00000000, 0x55550000},
4294 { 0xAAAA0000, 0xFFFF0000} };
4295 SkBitmap bitmap;
4296 bitmap.installPixels(SkImageInfo::MakeN32Premul(2, 2),
4297 (void*) pixels, sizeof(pixels[0]));
4298 SkPaint paint;
4299 canvas->scale(4, 4);
4300 for (auto color : { SK_ColorRED, SK_ColorBLUE, SK_ColorGREEN } ) {
4301 paint.setColorFilter(SkColorFilter::MakeModeFilter(color, SkBlendMode::kPlus));
4302 canvas->drawBitmapRect(bitmap, SkRect::MakeWH(8, 8), &paint);
4303 canvas->translate(8, 0);
4304 }
4305}
4306##
4307
4308#ToDo incomplete ##
4309
4310##
4311
4312# ------------------------------------------------------------------------------
4313
4314#Method void drawBitmapNine(const SkBitmap& bitmap, const SkIRect& center, const SkRect& dst,
4315 const SkPaint* paint = NULL)
4316
4317Draw Bitmap bitmap stretched differentially to fit into Rect dst.
4318IRect center divides the bitmap into nine sections: four sides, four corners, and the center.
4319corners are unscaled or scaled down proportionately if their sides are larger than dst;
4320center and four sides are scaled to fit remaining space, if any.
4321Additionally transform draw using Clip, Matrix, and optional Paint paint.
4322If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter, Blend_Mode, and Draw_Looper.
4323If bitmap is kAlpha_8_SkColorType, apply Shader.
4324if paint contains Mask_Filter, generate mask from bitmap bounds. If generated mask extends
4325beyond bitmap bounds, replicate bitmap edge colors, just as Shader made from
4326SkShader::MakeBitmapShader with SkShader::kClamp_TileMode set replicates the bitmap's edge
4327color when it samples outside of its bounds.
4328
4329#Param bitmap Bitmap containing pixels, dimensions, and format. ##
4330#Param center IRect edge of image corners and sides. ##
4331#Param dst Destination Rect of image to draw to. ##
4332#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter, and so on; or nullptr. ##
4333
4334#Example
4335#Height 128
4336#Description
4337 The two leftmost bitmap draws has four corners and sides to the left and right of center.
4338 The leftmost bitmap draw scales the width of corners proportionately to fit.
4339 The third and fourth draw corners are unscaled; the sides and center are scaled to
4340 fill the remaining space.
4341 The rightmost bitmap draw has four corners scaled vertically to fit, and uses sides above
4342 and below center to fill the remaining space.
4343##
4344void draw(SkCanvas* canvas) {
4345 SkIRect center = { 20, 10, 50, 40 };
4346 SkBitmap bitmap;
4347 bitmap.allocPixels(SkImageInfo::MakeN32Premul(60, 60));
4348 SkCanvas bitCanvas(bitmap);
4349 SkPaint paint;
4350 SkColor gray = 0xFF000000;
4351 int left = 0;
4352 for (auto right: { center.fLeft, center.fRight, bitmap.width() } ) {
4353 int top = 0;
4354 for (auto bottom: { center.fTop, center.fBottom, bitmap.height() } ) {
4355 paint.setColor(gray);
4356 bitCanvas.drawIRect(SkIRect::MakeLTRB(left, top, right, bottom), paint);
4357 gray += 0x001f1f1f;
4358 top = bottom;
4359 }
4360 left = right;
4361 }
4362 for (auto dest: { 20, 30, 40, 60, 90 } ) {
4363 canvas->drawBitmapNine(bitmap, center, SkRect::MakeWH(dest, 110 - dest), nullptr);
4364 canvas->translate(dest + 4, 0);
4365 }
4366}
4367##
4368
4369#ToDo incomplete ##
4370
4371##
4372
4373# ------------------------------------------------------------------------------
4374#Struct Lattice
4375
4376 Lattice divides Bitmap or Image into a rectangular grid.
4377 Grid entries on even columns and even rows are fixed; these entries are
4378 always drawn at their original size if the destination is large enough.
4379 If the destination side is too small to hold the fixed entries, all fixed
4380 entries are proportionately scaled down to fit.
4381 The grid entries not on even columns and rows are scaled to fit the
4382 remaining space, if any.
4383
4384#Code
4385 struct Lattice {
4386 enum Flags {...
4387
4388 const int* fXDivs;
4389 const int* fYDivs;
4390 const Flags* fFlags;
4391 int fXCount;
4392 int fYCount;
4393 const SkIRect* fBounds;
4394 };
4395##
4396
4397 #Enum Flags
4398 #Code
4399 enum Flags : uint8_t {
4400 kTransparent_Flags = 1 << 0,
4401 };
4402 ##
4403
4404 Optional setting per rectangular grid entry to make it transparent.
4405
4406 #Const kTransparent_Flags 1
4407 Set to skip lattice rectangle by making it transparent.
4408 ##
4409 ##
4410
4411 #Member const int* fXDivs
4412 Array of x-coordinates that divide the bitmap vertically.
4413 Array entries must be unique, increasing, greater than or equal to fBounds left edge,
4414 and less than fBounds right edge.
4415 Set the first element to fBounds left to collapse the left column of fixed grid entries.
4416 ##
4417
4418 #Member const int* fYDivs
4419 Array of y-coordinates that divide the bitmap horizontally.
4420 Array entries must be unique, increasing, greater than or equal to fBounds top edge,
4421 and less than fBounds bottom edge.
4422 Set the first element to fBounds top to collapse the top row of fixed grid entries.
4423 ##
4424
4425 #Member const Flags* fFlags
4426 Optional array of Flags, one per rectangular grid entry:
4427 array length must be (fXCount + 1) * (fYCount + 1).
4428 Array entries correspond to the rectangular grid entries, ascending
4429 left to right and then top to bottom.
4430 ##
4431
4432 #Member int fXCount
4433 Number of entries in fXDivs array; one less than the number of horizontal divisions.
4434 ##
4435
4436 #Member int fYCount
4437 Number of entries in fYDivs array; one less than the number of vertical divisions.
4438 ##
4439
4440 #Member const SkIRect* fBounds
4441 Optional subset IRect source to draw from.
4442 If nullptr, source bounds is dimensions of Bitmap or Image.
4443 ##
4444
4445#Struct Lattice ##
4446
4447#Method void drawBitmapLattice(const SkBitmap& bitmap, const Lattice& lattice, const SkRect& dst,
4448 const SkPaint* paint = nullptr)
4449
4450Draw Bitmap bitmap stretched differentially to fit into Rect dst.
4451
4452Lattice lattice divides bitmap into a rectangular grid.
4453Each intersection of an even-numbered row and column is fixed; like the corners
4454of drawBitmapNine, fixed lattice elements never scale larger than their initial size
4455and shrink proportionately when all fixed elements exceed the bitmap's dimension.
4456All other grid elements scale to fill the available space, if any.
4457
4458Additionally transform draw using Clip, Matrix, and optional Paint paint.
4459If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter, Blend_Mode, and Draw_Looper.
4460If bitmap is kAlpha_8_SkColorType, apply Shader.
4461if paint contains Mask_Filter, generate mask from bitmap bounds. If generated mask extends
4462beyond bitmap bounds, replicate bitmap edge colors, just as Shader made from
4463SkShader::MakeBitmapShader with SkShader::kClamp_TileMode set replicates the bitmap's edge
4464color when it samples outside of its bounds.
4465
4466#Param bitmap Bitmap containing pixels, dimensions, and format. ##
4467#Param lattice Division of bitmap into fixed and variable rectangles. ##
4468#Param dst Destination Rect of image to draw to. ##
4469#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter, and so on; or nullptr. ##
4470
4471#Example
4472#Height 128
4473#Description
4474 The two leftmost bitmap draws has four corners and sides to the left and right of center.
4475 The leftmost bitmap draw scales the width of corners proportionately to fit.
4476 The third and fourth draw corners are unscaled; the sides are scaled to
4477 fill the remaining space; the center is transparent.
4478 The rightmost bitmap draw has four corners scaled vertically to fit, and uses sides above
4479 and below center to fill the remaining space.
4480##
4481void draw(SkCanvas* canvas) {
4482 SkIRect center = { 20, 10, 50, 40 };
4483 SkBitmap bitmap;
4484 bitmap.allocPixels(SkImageInfo::MakeN32Premul(60, 60));
4485 SkCanvas bitCanvas(bitmap);
4486 SkPaint paint;
4487 SkColor gray = 0xFF000000;
4488 int left = 0;
4489 for (auto right: { center.fLeft, center.fRight, bitmap.width() } ) {
4490 int top = 0;
4491 for (auto bottom: { center.fTop, center.fBottom, bitmap.height() } ) {
4492 paint.setColor(gray);
4493 bitCanvas.drawIRect(SkIRect::MakeLTRB(left, top, right, bottom), paint);
4494 gray += 0x001f1f1f;
4495 top = bottom;
4496 }
4497 left = right;
4498 }
4499 const int xDivs[] = { center.fLeft, center.fRight };
4500 const int yDivs[] = { center.fTop, center.fBottom };
4501 SkCanvas::Lattice::Flags flags[3][3];
4502 memset(flags, 0, sizeof(flags));
4503 flags[1][1] = SkCanvas::Lattice::kTransparent_Flags;
4504 SkCanvas::Lattice lattice = { xDivs, yDivs, flags[0], SK_ARRAY_COUNT(xDivs),
4505 SK_ARRAY_COUNT(yDivs), nullptr };
4506 for (auto dest: { 20, 30, 40, 60, 90 } ) {
4507 canvas->drawBitmapLattice(bitmap, lattice , SkRect::MakeWH(dest, 110 - dest), nullptr);
4508 canvas->translate(dest + 4, 0);
4509 }
4510}
4511##
4512
4513#ToDo incomplete ##
4514
4515##
4516
4517# ------------------------------------------------------------------------------
4518
4519#Method void drawImageLattice(const SkImage* image, const Lattice& lattice, const SkRect& dst,
4520 const SkPaint* paint = nullptr)
4521
4522Draw Image image stretched differentially to fit into Rect dst.
4523
4524Lattice lattice divides image into a rectangular grid.
4525Each intersection of an even-numbered row and column is fixed; like the corners
4526of drawImageNine, fixed lattice elements never scale larger than their initial size
4527and shrink proportionately when all fixed elements exceed the bitmap's dimension.
4528All other grid elements scale to fill the available space, if any.
4529
4530Additionally transform draw using Clip, Matrix, and optional Paint paint.
4531If Paint paint is supplied, apply Color_Filter, Color_Alpha, Image_Filter, Blend_Mode, and Draw_Looper.
4532If image is kAlpha_8_SkColorType, apply Shader.
4533if paint contains Mask_Filter, generate mask from image bounds. If generated mask extends
4534beyond image bounds, replicate image edge colors, just as Shader made from
4535SkShader::MakeBitmapShader with SkShader::kClamp_TileMode set replicates the image's edge
4536color when it samples outside of its bounds.
4537
4538#Param image Image containing pixels, dimensions, and format. ##
4539#Param lattice Division of bitmap into fixed and variable rectangles. ##
4540#Param dst Destination Rect of image to draw to. ##
4541#Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter, and so on; or nullptr. ##
4542
4543#Example
4544#Height 128
4545#Description
4546 The leftmost image is smaller than center; only corners are drawn, all scaled to fit.
4547 The second image equals the size of center; only corners are drawn, unscaled.
4548 The remaining images are larger than center. All corners draw unscaled. The sides
4549 are scaled if needed to take up the remaining space; the center is transparent.
4550##
4551void draw(SkCanvas* canvas) {
4552 SkIRect center = { 20, 10, 50, 40 };
4553 SkBitmap bitmap;
4554 bitmap.allocPixels(SkImageInfo::MakeN32Premul(60, 60));
4555 SkCanvas bitCanvas(bitmap);
4556 SkPaint paint;
4557 SkColor gray = 0xFF000000;
4558 int left = 0;
4559 for (auto right: { center.fLeft, center.fRight, bitmap.width() } ) {
4560 int top = 0;
4561 for (auto bottom: { center.fTop, center.fBottom, bitmap.height() } ) {
4562 paint.setColor(gray);
4563 bitCanvas.drawIRect(SkIRect::MakeLTRB(left, top, right, bottom), paint);
4564 gray += 0x001f1f1f;
4565 top = bottom;
4566 }
4567 left = right;
4568 }
4569 const int xDivs[] = { center.fLeft, center.fRight };
4570 const int yDivs[] = { center.fTop, center.fBottom };
4571 SkCanvas::Lattice::Flags flags[3][3];
4572 memset(flags, 0, sizeof(flags));
4573 flags[1][1] = SkCanvas::Lattice::kTransparent_Flags;
4574 SkCanvas::Lattice lattice = { xDivs, yDivs, flags[0], SK_ARRAY_COUNT(xDivs),
4575 SK_ARRAY_COUNT(yDivs), nullptr };
4576 sk_sp<SkImage> image = SkImage::MakeFromBitmap(bitmap);
4577 SkImage* imagePtr = image.get();
4578 for (auto dest: { 20, 30, 40, 60, 90 } ) {
4579 canvas->drawImageNine(imagePtr, center, SkRect::MakeWH(dest, dest), nullptr);
4580 canvas->translate(dest + 4, 0);
4581 }
4582}
4583##
4584
4585#ToDo incomplete ##
4586
4587##
4588
4589#Topic Draw_Image ##
4590
4591# ------------------------------------------------------------------------------
4592
4593#Method void drawText(const void* text, size_t byteLength, SkScalar x, SkScalar y,
4594 const SkPaint& paint)
4595
4596Draw text, with origin at (x, y), using Clip, Matrix, and Paint paint.
4597text's meaning depends on Paint_Text_Encoding; by default, text encoding is UTF-8.
4598x and y meaning depends on Paint_Text_Align and Paint_Vertical_Text; by default text
4599draws left to right, positioning the first glyph's left side bearing at x and its
4600baseline at y. Text size is affected by Matrix and Paint_Text_Size.
4601
4602All elements of paint: Path_Effect, Rasterizer, Mask_Filter, Shader, Color_Filter,
4603Image_Filter, and Draw_Looper; apply to text. By default, drawText draws filled 12 point black
4604glyphs.
4605
4606#Param text Character code points or glyphs drawn. ##
4607#Param byteLength Byte length of text array. ##
4608#Param x Start of text on x-axis. ##
4609#Param y Start of text on y-axis. ##
4610#Param paint Text size, blend, color, and so on, used to draw. ##
4611
4612#Example
4613#Height 200
4614#Description
4615 The same text is drawn varying Paint_Text_Size and varying
4616 Matrix.
4617##
4618void draw(SkCanvas* canvas) {
4619 SkPaint paint;
4620 paint.setAntiAlias(true);
4621 float textSizes[] = { 12, 18, 24, 36 };
4622 for (auto size: textSizes ) {
4623 paint.setTextSize(size);
4624 canvas->drawText("Aa", 2, 10, 20, paint);
4625 canvas->translate(0, size * 2);
4626 }
4627 paint.reset();
4628 paint.setAntiAlias(true);
4629 float yPos = 20;
4630 for (auto size: textSizes ) {
4631 float scale = size / 12.f;
4632 canvas->resetMatrix();
4633 canvas->translate(100, 0);
4634 canvas->scale(scale, scale);
4635 canvas->drawText("Aa", 2, 10 / scale, yPos / scale, paint);
4636 yPos += size * 2;
4637 }
4638}
4639##
4640
4641#ToDo incomplete ##
4642
4643##
4644
4645#Method void drawString(const char* string, SkScalar x, SkScalar y, const SkPaint& paint)
4646
4647Draw null terminated string, with origin at (x, y), using Clip, Matrix, and Paint paint.
4648string's meaning depends on Paint_Text_Encoding; by default, string encoding is UTF-8.
4649Other values of Paint_Text_Encoding are unlikely to produce the desired results, since
4650zero bytes may be embedded in the string.
4651x and y meaning depends on Paint_Text_Align and Paint_Vertical_Text; by default string
4652draws left to right, positioning the first glyph's left side bearing at x and its
4653baseline at y. Text size is affected by Matrix and Paint_Text_Size.
4654
4655All elements of paint: Path_Effect, Rasterizer, Mask_Filter, Shader, Color_Filter,
4656Image_Filter, and Draw_Looper; apply to string. By default, drawString draws filled 12 point black
4657glyphs.
4658
4659#Param string Character code points or glyphs drawn, ending with a char value of zero. ##
4660#Param x Start of string on x-axis. ##
4661#Param y Start of string on y-axis. ##
4662#Param paint Text size, blend, color, and so on, used to draw. ##
4663
4664#Example
4665 SkPaint paint;
4666 canvas->drawString("a small hello", 20, 20, paint);
4667##
4668
4669#SeeAlso drawText
4670
4671##
4672
4673#Method void drawString(const SkString& string, SkScalar x, SkScalar y, const SkPaint& paint)
4674
4675Draw null terminated string, with origin at (x, y), using Clip, Matrix, and Paint paint.
4676string's meaning depends on Paint_Text_Encoding; by default, string encoding is UTF-8.
4677Other values of Paint_Text_Encoding are unlikely to produce the desired results, since
4678zero bytes may be embedded in the string.
4679x and y meaning depends on Paint_Text_Align and Paint_Vertical_Text; by default string
4680draws left to right, positioning the first glyph's left side bearing at x and its
4681baseline at y. Text size is affected by Matrix and Paint_Text_Size.
4682
4683All elements of paint: Path_Effect, Rasterizer, Mask_Filter, Shader, Color_Filter,
4684Image_Filter, and Draw_Looper; apply to string. By default, drawString draws filled 12 point black
4685glyphs.
4686
4687#Param string Character code points or glyphs drawn, ending with a char value of zero. ##
4688#Param x Start of string on x-axis. ##
4689#Param y Start of string on y-axis. ##
4690#Param paint Text size, blend, color, and so on, used to draw. ##
4691
4692#Example
4693 SkPaint paint;
4694 SkString string("a small hello");
4695 canvas->drawString(string, 20, 20, paint);
4696##
4697
4698#SeeAlso drawText
4699
4700##
4701
4702# ------------------------------------------------------------------------------
4703
4704#Method void drawPosText(const void* text, size_t byteLength, const SkPoint pos[],
4705 const SkPaint& paint)
4706
4707Draw each glyph in text with the origin in pos array, using Clip, Matrix, and Paint paint.
4708The number of entries in pos array must match the number of glyphs described by byteLength of text.
4709text's meaning depends on Paint_Text_Encoding; by default, text encoding is UTF-8.
4710pos elements' meaning depends on Paint_Text_Align and Paint_Vertical_Text; by default each
4711glyph's left side bearing is positioned at x and its
4712baseline is positioned at y. Text size is affected by Matrix and Paint_Text_Size.
4713
4714All elements of paint: Path_Effect, Rasterizer, Mask_Filter, Shader, Color_Filter,
4715Image_Filter, and Draw_Looper; apply to text. By default, drawPosText draws filled 12 point black
4716glyphs.
4717
4718Layout engines such as Harfbuzz typically use drawPosText to position each glyph
4719rather than using the font's advance widths.
4720
4721#Param text Character code points or glyphs drawn. ##
4722#Param byteLength Byte length of text array. ##
4723#Param pos Array of glyph origins. ##
4724#Param paint Text size, blend, color, and so on, used to draw. ##
4725
4726#Example
4727#Height 120
4728void draw(SkCanvas* canvas) {
4729 const char hello[] = "HeLLo!";
4730 const SkPoint pos[] = { {40, 100}, {82, 95}, {115, 110}, {130, 95}, {145, 85},
4731 {172, 100} };
4732 SkPaint paint;
4733 paint.setTextSize(60);
4734 canvas->drawPosText(hello, strlen(hello), pos, paint);
4735}
4736##
4737
4738#ToDo incomplete ##
4739
4740##
4741
4742# ------------------------------------------------------------------------------
4743
4744#Method void drawPosTextH(const void* text, size_t byteLength, const SkScalar xpos[], SkScalar constY,
4745 const SkPaint& paint)
4746
4747Draw each glyph in text with its (x, y) origin composed from xpos array and constY, using Clip, Matrix, and Paint paint.
4748The number of entries in xpos array must match the number of glyphs described by byteLength of text.
4749text's meaning depends on Paint_Text_Encoding; by default, text encoding is UTF-8.
4750pos elements' meaning depends on Paint_Text_Align and Paint_Vertical_Text; by default each
4751glyph's left side bearing is positioned at an xpos element and its
4752baseline is positioned at constY. Text size is affected by Matrix and Paint_Text_Size.
4753
4754All elements of paint: Path_Effect, Rasterizer, Mask_Filter, Shader, Color_Filter,
4755Image_Filter, and Draw_Looper; apply to text. By default, drawPosTextH draws filled 12 point black
4756glyphs.
4757
4758Layout engines such as Harfbuzz typically use drawPosTextH to position each glyph
4759rather than using the font's advance widths if all glyphs share the same baseline.
4760
4761#Param text Character code points or glyphs drawn. ##
4762#Param byteLength Byte length of text array. ##
4763#Param xpos Array of x positions, used to position each glyph. ##
4764#Param constY Shared y coordinate for all of x positions. ##
4765#Param paint Text size, blend, color, and so on, used to draw. ##
4766
4767#Example
4768#Height 40
4769 void draw(SkCanvas* canvas) {
4770 SkScalar xpos[] = { 20, 40, 80, 160 };
4771 SkPaint paint;
4772 canvas->drawPosTextH("XXXX", 4, xpos, 20, paint);
4773 }
4774##
4775
4776#ToDo incomplete ##
4777
4778##
4779
4780# ------------------------------------------------------------------------------
4781
4782#Method void drawTextOnPathHV(const void* text, size_t byteLength, const SkPath& path, SkScalar hOffset,
4783 SkScalar vOffset, const SkPaint& paint)
4784
4785Draw text on Path path, using Clip, Matrix, and Paint paint.
4786Origin of text is at distance hOffset along the path, offset by a perpendicular vector of
4787length vOffset. If the path section corresponding the glyph advance is curved, the glyph
4788is drawn curved to match; control points in the glyph are mapped to projected points parallel
4789to the path. If the text's advance is larger than the path length, the excess text is clipped.
4790
4791text's meaning depends on Paint_Text_Encoding; by default, text encoding is UTF-8.
4792Origin meaning depends on Paint_Text_Align and Paint_Vertical_Text; by default text
4793positions the first glyph's left side bearing at origin x and its
4794baseline at origin y. Text size is affected by Matrix and Paint_Text_Size.
4795
4796All elements of paint: Path_Effect, Rasterizer, Mask_Filter, Shader, Color_Filter,
4797Image_Filter, and Draw_Looper; apply to text. By default, drawTextOnPathHV draws filled 12 point black
4798glyphs.
4799
4800#Param text Character code points or glyphs drawn. ##
4801#Param byteLength Byte length of text array. ##
4802#Param path Path providing text baseline. ##
4803#Param hOffset Distance along path to offset origin. ##
4804#Param vOffset Offset of text above (if negative) or below (if positive) the path. ##
4805#Param paint Text size, blend, color, and so on, used to draw. ##
4806
4807#Example
4808 void draw(SkCanvas* canvas) {
4809 const char aero[] = "correo a" "\xC3" "\xA9" "reo";
4810 const size_t len = sizeof(aero) - 1;
4811 SkPath path;
4812 path.addOval({43-26, 43-26, 43+26, 43+26}, SkPath::kCW_Direction, 3);
4813 SkPaint paint;
4814 paint.setTextSize(24);
4815 for (auto offset : { 0, 10, 20 } ) {
4816 canvas->drawTextOnPathHV(aero, len, path, 0, -offset, paint);
4817 canvas->translate(70 + offset, 70 + offset);
4818 }
4819 }
4820##
4821
4822#ToDo incomplete ##
4823
4824##
4825
4826# ------------------------------------------------------------------------------
4827
4828#Method void drawTextOnPath(const void* text, size_t byteLength, const SkPath& path,
4829 const SkMatrix* matrix, const SkPaint& paint)
4830
4831Draw text on Path path, using Clip, Matrix, and Paint paint.
4832Origin of text is at beginning of path offset by matrix, if provided, before it is mapped to path.
4833If the path section corresponding the glyph advance is curved, the glyph
4834is drawn curved to match; control points in the glyph are mapped to projected points parallel
4835to the path. If the text's advance is larger than the path length, the excess text is clipped.
4836
4837text's meaning depends on Paint_Text_Encoding; by default, text encoding is UTF-8.
4838Origin meaning depends on Paint_Text_Align and Paint_Vertical_Text; by default text
4839positions the first glyph's left side bearing at origin x and its
4840baseline at origin y. Text size is affected by Matrix and Paint_Text_Size.
4841
4842All elements of paint: Path_Effect, Rasterizer, Mask_Filter, Shader, Color_Filter,
4843Image_Filter, and Draw_Looper; apply to text. By default, drawTextOnPath draws filled 12 point black
4844glyphs.
4845
4846#Param text Character code points or glyphs drawn. ##
4847#Param byteLength Byte length of text array. ##
4848#Param path Path providing text baseline. ##
4849#Param matrix Optional transform of glyphs before mapping to path; or nullptr. ##
4850#Param paint Text size, blend, color, and so on, used to draw. ##
4851
4852#Example
4853 void draw(SkCanvas* canvas) {
4854 const char roller[] = "rollercoaster";
4855 const size_t len = sizeof(roller) - 1;
4856 SkPath path;
4857 path.cubicTo(40, -80, 120, 80, 160, -40);
4858 SkPaint paint;
4859 paint.setTextSize(32);
4860 paint.setStyle(SkPaint::kStroke_Style);
4861 SkMatrix matrix;
4862 matrix.setIdentity();
4863 for (int i = 0; i < 3; ++i) {
4864 canvas->translate(25, 60);
4865 canvas->drawPath(path, paint);
4866 canvas->drawTextOnPath(roller, len, path, &matrix, paint);
4867 matrix.preTranslate(0, 10);
4868 }
4869 }
4870##
4871
4872#ToDo incomplete ##
4873
4874##
4875
4876# ------------------------------------------------------------------------------
4877
4878#Method void drawTextRSXform(const void* text, size_t byteLength, const SkRSXform xform[],
4879 const SkRect* cullRect, const SkPaint& paint)
4880
4881Draw text, transforming each glyph by the corresponding SkRSXform,
4882using Clip, Matrix, and Paint paint.
4883RSXform array specifies a separate square scale, rotation, and translation for
4884each glyph.
4885Optional Rect cullRect is a conservative bounds of text,
4886taking into account RSXform and paint. If cullrect is outside of Clip, canvas can
4887skip drawing.
4888
4889All elements of paint: Path_Effect, Rasterizer, Mask_Filter, Shader, Color_Filter,
4890Image_Filter, and Draw_Looper; apply to text. By default, drawTextRSXform draws filled 12 point black
4891glyphs.
4892
4893#Param text Character code points or glyphs drawn. ##
4894#Param byteLength Byte length of text array. ##
4895#Param xform RSXform rotates, scales, and translates each glyph individually. ##
4896#Param cullRect Rect bounds of text for efficient clipping; or nullptr. ##
4897#Param paint Text size, blend, color, and so on, used to draw. ##
4898
4899#Example
4900void draw(SkCanvas* canvas) {
4901 const int iterations = 26;
4902 SkRSXform transforms[iterations];
4903 char alphabet[iterations];
4904 SkScalar angle = 0;
4905 SkScalar scale = 1;
4906 for (size_t i = 0; i < SK_ARRAY_COUNT(transforms); ++i) {
4907 const SkScalar s = SkScalarSin(angle) * scale;
4908 const SkScalar c = SkScalarCos(angle) * scale;
4909 transforms[i] = SkRSXform::Make(-c, -s, -s * 16, c * 16);
4910 angle += .45;
4911 scale += .2;
4912 alphabet[i] = 'A' + i;
4913 }
4914 SkPaint paint;
4915 paint.setTextAlign(SkPaint::kCenter_Align);
4916 canvas->translate(110, 138);
4917 canvas->drawTextRSXform(alphabet, sizeof(alphabet), transforms, nullptr, paint);
4918}
4919##
4920
4921#ToDo incomplete ##
4922
4923##
4924
4925# ------------------------------------------------------------------------------
4926
4927#Method void drawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y, const SkPaint& paint)
4928
4929Draw Text_Blob blob at (x, y), using Clip, Matrix, and Paint paint.
4930blob contains glyphs, their positions, and paint attributes specific to text:
4931Typeface, Paint_Text_Size, Paint_Text_Scale_X, Paint_Text_Skew_X, Paint_Text_Align,
4932Paint_Hinting, Anti-alias, Paint_Fake_Bold, Font_Embedded_Bitmaps, Full_Hinting_Spacing,
4933LCD_Text, Linear_Text, Subpixel_Text, and Paint_Vertical_Text.
4934
4935Elements of paint: Path_Effect, Rasterizer, Mask_Filter, Shader, Color_Filter,
4936Image_Filter, and Draw_Looper; apply to blob.
4937
4938#Param blob Glyphs, positions, and their paints' text size, typeface, and so on. ##
4939#Param x Horizontal offset applied to blob. ##
4940#Param y Vertical offset applied to blob. ##
4941#Param paint Blend, color, stroking, and so on, used to draw. ##
4942
4943#Example
4944#Height 120
4945 void draw(SkCanvas* canvas) {
4946 SkTextBlobBuilder textBlobBuilder;
4947 const char bunny[] = "/(^x^)\\";
4948 const int len = sizeof(bunny) - 1;
4949 uint16_t glyphs[len];
4950 SkPaint paint;
4951 paint.textToGlyphs(bunny, len, glyphs);
4952 int runs[] = { 3, 1, 3 };
4953 SkPoint textPos = { 20, 100 };
4954 int glyphIndex = 0;
4955 for (auto runLen : runs) {
4956 paint.setTextSize(1 == runLen ? 20 : 50);
4957 const SkTextBlobBuilder::RunBuffer& run =
4958 textBlobBuilder.allocRun(paint, runLen, textPos.fX, textPos.fY);
4959 memcpy(run.glyphs, &glyphs[glyphIndex], sizeof(glyphs[0]) * runLen);
4960 textPos.fX += paint.measureText(&bunny[glyphIndex], runLen, nullptr);
4961 glyphIndex += runLen;
4962 }
4963 sk_sp<const SkTextBlob> blob = textBlobBuilder.make();
4964 paint.reset();
4965 canvas->drawTextBlob(blob.get(), 0, 0, paint);
4966 }
4967##
4968
4969#ToDo incomplete ##
4970
4971##
4972
4973# ------------------------------------------------------------------------------
4974
4975#Method void drawTextBlob(const sk_sp<SkTextBlob>& blob, SkScalar x, SkScalar y, const SkPaint& paint)
4976
4977Draw Text_Blob blob at (x, y), using Clip, Matrix, and Paint paint.
4978blob contains glyphs, their positions, and paint attributes specific to text:
4979Typeface, Paint_Text_Size, Paint_Text_Scale_X, Paint_Text_Skew_X, Paint_Text_Align,
4980Paint_Hinting, Anti-alias, Paint_Fake_Bold, Font_Embedded_Bitmaps, Full_Hinting_Spacing,
4981LCD_Text, Linear_Text, Subpixel_Text, and Paint_Vertical_Text.
4982
4983Elements of paint: Path_Effect, Rasterizer, Mask_Filter, Shader, Color_Filter,
4984Image_Filter, and Draw_Looper; apply to blob.
4985
4986#Param blob Glyphs, positions, and their paints' text size, typeface, and so on. ##
4987#Param x Horizontal offset applied to blob. ##
4988#Param y Vertical offset applied to blob. ##
4989#Param paint Blend, color, stroking, and so on, used to draw. ##
4990
4991#Example
4992#Height 120
4993#Description
4994Paint attributes unrelated to text, like color, have no effect on paint in allocated Text_Blob.
4995Paint attributes related to text, like text size, have no effect on paint passed to drawTextBlob.
4996##
4997 void draw(SkCanvas* canvas) {
4998 SkTextBlobBuilder textBlobBuilder;
4999 SkPaint paint;
5000 paint.setTextSize(50);
5001 paint.setColor(SK_ColorRED);
5002 const SkTextBlobBuilder::RunBuffer& run =
5003 textBlobBuilder.allocRun(paint, 1, 20, 100);
5004 run.glyphs[0] = 20;
5005 sk_sp<const SkTextBlob> blob = textBlobBuilder.make();
5006 paint.setTextSize(10);
5007 paint.setColor(SK_ColorBLUE);
5008 canvas->drawTextBlob(blob.get(), 0, 0, paint);
5009 }
5010##
5011
5012#ToDo incomplete ##
5013
5014##
5015
5016# ------------------------------------------------------------------------------
5017
5018#Method void drawPicture(const SkPicture* picture)
5019
5020Draw Picture picture, using Clip and Matrix.
5021Clip and Matrix are unchanged by picture contents, as if
5022save() was called before and restore() was called after drawPicture.
5023
5024Picture records a series of draw commands for later playback.
5025
5026#Param picture Recorded drawing commands to play. ##
5027
5028#Example
5029void draw(SkCanvas* canvas) {
5030 SkPictureRecorder recorder;
5031 SkCanvas* recordingCanvas = recorder.beginRecording(50, 50);
5032 for (auto color : { SK_ColorRED, SK_ColorBLUE, 0xff007f00 } ) {
5033 SkPaint paint;
5034 paint.setColor(color);
5035 recordingCanvas->drawRect({10, 10, 30, 40}, paint);
5036 recordingCanvas->translate(10, 10);
5037 recordingCanvas->scale(1.2f, 1.4f);
5038 }
5039 sk_sp<SkPicture> playback = recorder.finishRecordingAsPicture();
5040 const SkPicture* playbackPtr = playback.get();
5041 canvas->drawPicture(playback);
5042 canvas->scale(2, 2);
5043 canvas->translate(50, 0);
5044 canvas->drawPicture(playback);
5045}
5046##
5047
5048#ToDo incomplete ##
5049
5050##
5051
5052# ------------------------------------------------------------------------------
5053
5054#Method void drawPicture(const sk_sp<SkPicture>& picture)
5055
5056Draw Picture picture, using Clip and Matrix.
5057Clip and Matrix are unchanged by picture contents, as if
5058save() was called before and restore() was called after drawPicture.
5059
5060Picture records a series of draw commands for later playback.
5061
5062#Param picture Recorded drawing commands to play. ##
5063
5064#Example
5065void draw(SkCanvas* canvas) {
5066 SkPictureRecorder recorder;
5067 SkCanvas* recordingCanvas = recorder.beginRecording(50, 50);
5068 for (auto color : { SK_ColorRED, SK_ColorBLUE, 0xff007f00 } ) {
5069 SkPaint paint;
5070 paint.setColor(color);
5071 recordingCanvas->drawRect({10, 10, 30, 40}, paint);
5072 recordingCanvas->translate(10, 10);
5073 recordingCanvas->scale(1.2f, 1.4f);
5074 }
5075 sk_sp<SkPicture> playback = recorder.finishRecordingAsPicture();
5076 canvas->drawPicture(playback);
5077 canvas->scale(2, 2);
5078 canvas->translate(50, 0);
5079 canvas->drawPicture(playback);
5080}
5081##
5082
5083#ToDo incomplete ##
5084
5085##
5086
5087# ------------------------------------------------------------------------------
5088
5089#Method void drawPicture(const SkPicture* picture, const SkMatrix* matrix, const SkPaint* paint)
5090
5091Draw Picture picture, using Clip and Matrix;
5092transforming picture with Matrix matrix, if provided;
5093and use Paint paint Color_Alpha, Color_Filter, Image_Filter, and Blend_Mode, if provided.
5094
5095matrix transformation is equivalent to: save(), concat(), drawPicture, restore().
5096paint use is equivalent to: saveLayer, drawPicture, restore().
5097
5098#Param picture Recorded drawing commands to play. ##
5099#Param matrix Optional Matrix to rotate, scale, translate, and so on; or nullptr. ##
5100#Param paint Optional Paint to apply transparency, filtering, and so on; or nullptr. ##
5101
5102#Example
5103void draw(SkCanvas* canvas) {
5104 SkPaint paint;
5105 SkPictureRecorder recorder;
5106 SkCanvas* recordingCanvas = recorder.beginRecording(50, 50);
5107 for (auto color : { SK_ColorRED, SK_ColorBLUE, 0xff007f00 } ) {
5108 paint.setColor(color);
5109 recordingCanvas->drawRect({10, 10, 30, 40}, paint);
5110 recordingCanvas->translate(10, 10);
5111 recordingCanvas->scale(1.2f, 1.4f);
5112 }
5113 sk_sp<SkPicture> playback = recorder.finishRecordingAsPicture();
5114 const SkPicture* playbackPtr = playback.get();
5115 SkMatrix matrix;
5116 matrix.reset();
5117 for (auto alpha : { 70, 140, 210 } ) {
5118 paint.setAlpha(alpha);
5119 canvas->drawPicture(playbackPtr, &matrix, &paint);
5120 matrix.preTranslate(70, 70);
5121 }
5122}
5123##
5124
5125#ToDo incomplete ##
5126
5127##
5128
5129# ------------------------------------------------------------------------------
5130
5131#Method void drawPicture(const sk_sp<SkPicture>& picture, const SkMatrix* matrix, const SkPaint* paint)
5132
5133Draw Picture picture, using Clip and Matrix;
5134transforming picture with Matrix matrix, if provided;
5135and use Paint paint Color_Alpha, Color_Filter, Image_Filter, and Blend_Mode, if provided.
5136
5137matrix transformation is equivalent to: save(), concat(), drawPicture, restore().
5138paint use is equivalent to: saveLayer, drawPicture, restore().
5139
5140#Param picture Recorded drawing commands to play. ##
5141#Param matrix Optional Matrix to rotate, scale, translate, and so on; or nullptr. ##
5142#Param paint Optional Paint to apply transparency, filtering, and so on; or nullptr. ##
5143
5144#Example
5145void draw(SkCanvas* canvas) {
5146 SkPaint paint;
5147 SkPictureRecorder recorder;
5148 SkCanvas* recordingCanvas = recorder.beginRecording(50, 50);
5149 for (auto color : { SK_ColorRED, SK_ColorBLUE, 0xff007f00 } ) {
5150 paint.setColor(color);
5151 recordingCanvas->drawRect({10, 10, 30, 40}, paint);
5152 recordingCanvas->translate(10, 10);
5153 recordingCanvas->scale(1.2f, 1.4f);
5154 }
5155 sk_sp<SkPicture> playback = recorder.finishRecordingAsPicture();
5156 SkMatrix matrix;
5157 matrix.reset();
5158 for (auto alpha : { 70, 140, 210 } ) {
5159 paint.setAlpha(alpha);
5160 canvas->drawPicture(playback, &matrix, &paint);
5161 matrix.preTranslate(70, 70);
5162 }
5163}
5164##
5165
5166#ToDo incomplete ##
5167
5168##
5169
5170# ------------------------------------------------------------------------------
5171
5172#Method void drawVertices(const SkVertices* vertices, SkBlendMode mode, const SkPaint& paint)
5173
5174Draw Vertices vertices, a triangle mesh, using Clip and Matrix.
5175If Vertices_Texs and Vertices_Colors are defined in vertices, and Paint paint contains Shader,
5176Blend_Mode mode combines Vertices_Colors with Shader.
5177
5178#Param vertices The triangle mesh to draw. ##
5179#Param mode Combines Vertices_Colors with Shader, if both are present. ##
5180#Param paint Specifies the Shader, used as Vertices texture, if present. ##
5181
5182#Example
5183void draw(SkCanvas* canvas) {
5184 SkPaint paint;
5185 SkPoint points[] = { { 0, 0 }, { 250, 0 }, { 100, 100 }, { 0, 250 } };
5186 SkColor colors[] = { SK_ColorRED, SK_ColorBLUE, SK_ColorYELLOW, SK_ColorCYAN };
5187 auto vertices = SkVertices::MakeCopy(SkVertices::kTriangleFan_VertexMode,
5188 SK_ARRAY_COUNT(points), points, nullptr, colors);
5189 canvas->drawVertices(vertices.get(), SkBlendMode::kSrc, paint);
5190}
5191##
5192
5193#ToDo incomplete ##
5194
5195##
5196
5197# ------------------------------------------------------------------------------
5198
5199#Method void drawVertices(const sk_sp<SkVertices>& vertices, SkBlendMode mode, const SkPaint& paint)
5200
5201Draw Vertices vertices, a triangle mesh, using Clip and Matrix.
5202If Vertices_Texs and Vertices_Colors are defined in vertices, and Paint paint contains Shader,
5203Blend_Mode mode combines Vertices_Colors with Shader.
5204
5205#Param vertices The triangle mesh to draw. ##
5206#Param mode Combines Vertices_Colors with Shader, if both are present. ##
5207#Param paint Specifies the Shader, used as Vertices texture, if present. ##
5208
5209#Example
5210void draw(SkCanvas* canvas) {
5211 SkPaint paint;
5212 SkPoint points[] = { { 0, 0 }, { 250, 0 }, { 100, 100 }, { 0, 250 } };
5213 SkPoint texs[] = { { 0, 0 }, { 0, 250 }, { 250, 250 }, { 250, 0 } };
5214 SkColor colors[] = { SK_ColorRED, SK_ColorBLUE, SK_ColorYELLOW, SK_ColorCYAN };
5215 paint.setShader(SkGradientShader::MakeLinear(points, colors, nullptr, 4,
5216 SkShader::kClamp_TileMode));
5217 auto vertices = SkVertices::MakeCopy(SkVertices::kTriangleFan_VertexMode,
5218 SK_ARRAY_COUNT(points), points, texs, colors);
5219 canvas->drawVertices(vertices.get(), SkBlendMode::kDarken, paint);
5220}
5221##
5222
5223#ToDo incomplete ##
5224
5225##
5226
5227# ------------------------------------------------------------------------------
5228
5229#Method void drawPatch(const SkPoint cubics[12], const SkColor colors[4],
5230 const SkPoint texCoords[4], SkBlendMode mode, const SkPaint& paint)
5231
5232Draw a cubic Coons patch: the interpolation of four cubics with shared corners,
5233associating a color, and optionally a texture coordinate, with each corner.
5234
5235#ToDo can patch use image filter? ##
5236
5237The Coons patch uses Clip and Matrix, Paint paint's Shader, Color_Filter, Color_Alpha,
5238Image_Filter, and Blend_Mode. If Shader is provided it is treated as the Coons
5239patch texture; Blend_Mode mode combines Color colors and Shader if both are provided.
5240
5241#Param cubics Point array cubics specifying the four cubics starting at the top left corner,
5242in clockwise order, sharing every fourth point. The last cubic ends at the first point. ##
5243#Param colors Color array color associating colors with corners in top left, top right, bottom right,
5244bottom left order. ##
5245#Param texCoords Point array texCoords mapping Shader as texture to corners in same order, if paint
5246contains Shader; or nullptr. ##
5247#Param mode Blend_Mode for colors and Shader if present. ##
5248#Param paint Shader, Color_Filter, Blend_Mode, used to draw. ##
5249
5250#Example
5251#Image 5
5252void draw(SkCanvas* canvas) {
5253 // SkBitmap source = cmbkygk;
5254 SkPaint paint;
5255 paint.setFilterQuality(kLow_SkFilterQuality);
5256 paint.setAntiAlias(true);
5257 SkPoint cubics[] = { { 3, 1 }, { 4, 2 }, { 5, 1 }, { 7, 3 },
5258 /* { 7, 3 }, */ { 6, 4 }, { 7, 5 }, { 5, 7 },
5259 /* { 5, 7 }, */ { 4, 6 }, { 3, 7 }, { 1, 5 },
5260 /* { 1, 5 }, */ { 2, 4 }, { 1, 3 }, /* { 3, 1 } */ };
5261 SkColor colors[] = { 0xbfff0000, 0xbf0000ff, 0xbfff00ff, 0xbf00ffff };
5262 SkPoint texCoords[] = { { -30, -30 }, { 162, -30}, { 162, 162}, { -30, 162} };
5263 paint.setShader(SkShader::MakeBitmapShader(source, SkShader::kClamp_TileMode,
5264 SkShader::kClamp_TileMode, nullptr));
5265 canvas->scale(15, 15);
5266 for (auto blend : { SkBlendMode::kSrcOver, SkBlendMode::kModulate, SkBlendMode::kXor } ) {
5267 canvas->drawPatch(cubics, colors, texCoords, blend, paint);
5268 canvas->translate(4, 4);
5269 }
5270}
5271##
5272
5273#ToDo incomplete ##
5274
5275##
5276
5277# ------------------------------------------------------------------------------
5278
5279#Method void drawPatch(const SkPoint cubics[12], const SkColor colors[4],
5280 const SkPoint texCoords[4], const SkPaint& paint)
5281
5282Draw a cubic Coons patch: the interpolation of four cubics with shared corners,
5283associating a color, a texture coordinate, or both, with each corner.
5284
5285The Coons patch uses Clip and Matrix, Paint paint's Shader, Color_Filter, Color_Alpha,
5286Image_Filter, (?) and Blend_Mode. If Shader is provided it is treated as the Coons
5287patch texture.
5288
5289#Param cubics Point array cubics specifying the four cubics starting at the top left corner,
5290in clockwise order, sharing every fourth point. The last cubic ends at the first point. ##
5291#Param colors Color array color associating colors with corners in top left, top right, bottom right,
5292bottom left order; or nullptr. ##
5293#Param texCoords Point array texCoords mapping Shader as texture to corners in same order, if paint
5294contains Shader; or nullptr. ##
5295#Param paint Shader, Color_Filter, Blend_Mode, used to draw. ##
5296
5297#Example
5298void draw(SkCanvas* canvas) {
5299 SkPaint paint;
5300 paint.setAntiAlias(true);
5301 SkPoint cubics[] = { { 3, 1 }, { 4, 2 }, { 5, 1 }, { 7, 3 },
5302 /* { 7, 3 }, */ { 6, 4 }, { 7, 5 }, { 5, 7 },
5303 /* { 5, 7 }, */ { 4, 6 }, { 3, 7 }, { 1, 5 },
5304 /* { 1, 5 }, */ { 2, 4 }, { 1, 3 }, /* { 3, 1 } */ };
5305 SkColor colors[] = { SK_ColorRED, SK_ColorBLUE, SK_ColorYELLOW, SK_ColorCYAN };
5306 canvas->scale(30, 30);
5307 canvas->drawPatch(cubics, colors, nullptr, paint);
5308 SkPoint text[] = { {3,0.9f}, {4,2.5f}, {5,0.9f}, {7.5f,3.2f}, {5.5f,4.2f},
5309 {7.5f,5.2f}, {5,7.5f}, {4,5.9f}, {3,7.5f}, {0.5f,5.2f}, {2.5f,4.2f},
5310 {0.5f,3.2f} };
5311 paint.setTextSize(18.f / 30);
5312 paint.setTextAlign(SkPaint::kCenter_Align);
5313 for (int i = 0; i< 10; ++i) {
5314 char digit = '0' + i;
5315 canvas->drawText(&digit, 1, text[i].fX, text[i].fY, paint);
5316 }
5317 canvas->drawString("10", text[10].fX, text[10].fY, paint);
5318 canvas->drawString("11", text[11].fX, text[11].fY, paint);
5319 paint.setStyle(SkPaint::kStroke_Style);
5320 canvas->drawPoints(SkCanvas::kPolygon_PointMode, 12, cubics, paint);
5321 canvas->drawLine(cubics[11].fX, cubics[11].fY, cubics[0].fX, cubics[0].fY, paint);
5322}
5323##
5324
5325#Example
5326#Image 6
5327void draw(SkCanvas* canvas) {
5328 // SkBitmap source = checkerboard;
5329 SkPaint paint;
5330 paint.setFilterQuality(kLow_SkFilterQuality);
5331 paint.setAntiAlias(true);
5332 SkPoint cubics[] = { { 3, 1 }, { 4, 2 }, { 5, 1 }, { 7, 3 },
5333 /* { 7, 3 }, */ { 6, 4 }, { 7, 5 }, { 5, 7 },
5334 /* { 5, 7 }, */ { 4, 6 }, { 3, 7 }, { 1, 5 },
5335 /* { 1, 5 }, */ { 2, 4 }, { 1, 3 }, /* { 3, 1 } */ };
5336 SkPoint texCoords[] = { { 0, 0 }, { 0, 62}, { 62, 62}, { 62, 0 } };
5337 paint.setShader(SkShader::MakeBitmapShader(source, SkShader::kClamp_TileMode,
5338 SkShader::kClamp_TileMode, nullptr));
5339 canvas->scale(30, 30);
5340 canvas->drawPatch(cubics, nullptr, texCoords, paint);
5341}
5342##
5343
5344#ToDo incomplete ##
5345
5346##
5347
5348# ------------------------------------------------------------------------------
5349
5350#Method void drawAtlas(const SkImage* atlas, const SkRSXform xform[], const SkRect tex[],
5351 const SkColor colors[], int count, SkBlendMode mode, const SkRect* cullRect,
5352 const SkPaint* paint)
5353
5354Draw a set of sprites from atlas, using Clip, Matrix, and optional Paint paint.
5355paint uses Anti-alias, Color_Alpha, Color_Filter, Image_Filter, and Blend_Mode to draw, if present.
5356For each entry in the array, Rect tex locates sprite in atlas, and RSXform xform transforms it
5357into destination space.
5358xform, text, and colors if present, must contain count entries.
5359Optional colors is applied for each sprite using Blend_Mode.
5360Optional cullRect is a conservative bounds of all transformed sprites.
5361If cullrect is outside of Clip, canvas can skip drawing.
5362
5363#Param atlas Image containing sprites. ##
5364#Param xform RSXform mappings for sprites in atlas. ##
5365#Param tex Rect locations of sprites in atlas. ##
5366#Param colors Color, one per sprite, blended with sprite using Blend_Mode; or nullptr. ##
5367#Param count Number of sprites to draw. ##
5368#Param mode Blend_Mode combining colors and sprites. ##
5369#Param cullRect Rect bounds of transformed sprites for efficient clipping; or nullptr. ##
5370#Param paint Paint Color_Filter, Image_Filter, Blend_Mode, and so on; or nullptr. ##
5371
5372#Example
5373#Image 3
5374void draw(SkCanvas* canvas) {
5375 // SkBitmap source = mandrill;
5376 SkRSXform xforms[] = { { .5f, 0, 0, 0 }, {0, .5f, 200, 100 } };
5377 SkRect tex[] = { { 0, 0, 250, 250 }, { 0, 0, 250, 250 } };
5378 SkColor colors[] = { 0x7f55aa00, 0x7f3333bf };
5379 const SkImage* imagePtr = image.get();
5380 canvas->drawAtlas(imagePtr, xforms, tex, colors, 2, SkBlendMode::kSrcOver, nullptr, nullptr);
5381}
5382##
5383
5384#ToDo incomplete ##
5385
5386##
5387
5388# ------------------------------------------------------------------------------
5389
5390#Method void drawAtlas(const sk_sp<SkImage>& atlas, const SkRSXform xform[], const SkRect tex[],
5391 const SkColor colors[], int count, SkBlendMode mode, const SkRect* cullRect,
5392 const SkPaint* paint)
5393
5394Draw a set of sprites from atlas, using Clip, Matrix, and optional Paint paint.
5395paint uses Anti-alias, Color_Alpha, Color_Filter, Image_Filter, and Blend_Mode to draw, if present.
5396For each entry in the array, Rect tex locates sprite in atlas, and RSXform xform transforms it
5397into destination space.
5398xform, text, and colors if present, must contain count entries.
5399Optional colors is applied for each sprite using Blend_Mode.
5400Optional cullRect is a conservative bounds of all transformed sprites.
5401If cullrect is outside of Clip, canvas can skip drawing.
5402
5403#Param atlas Image containing sprites. ##
5404#Param xform RSXform mappings for sprites in atlas. ##
5405#Param tex Rect locations of sprites in atlas. ##
5406#Param colors Color, one per sprite, blended with sprite using Blend_Mode; or nullptr. ##
5407#Param count Number of sprites to draw. ##
5408#Param mode Blend_Mode combining colors and sprites. ##
5409#Param cullRect Rect bounds of transformed sprites for efficient clipping; or nullptr. ##
5410#Param paint Paint Color_Filter, Image_Filter, Blend_Mode, and so on; or nullptr. ##
5411
5412#Example
5413#Image 3
5414void draw(SkCanvas* canvas) {
5415 // SkBitmap source = mandrill;
5416 SkRSXform xforms[] = { { .5f, 0, 0, 0 }, {0, .5f, 200, 100 } };
5417 SkRect tex[] = { { 0, 0, 250, 250 }, { 0, 0, 250, 250 } };
5418 SkColor colors[] = { 0x7f55aa00, 0x7f3333bf };
5419 SkPaint paint;
5420 paint.setAlpha(127);
5421 canvas->drawAtlas(image, xforms, tex, colors, 2, SkBlendMode::kPlus, nullptr, &paint);
5422}
5423##
5424
5425#ToDo bug in example on cpu side, gpu looks ok ##
5426
5427##
5428
5429# ------------------------------------------------------------------------------
5430
5431#Method void drawAtlas(const SkImage* atlas, const SkRSXform xform[], const SkRect tex[], int count,
5432 const SkRect* cullRect, const SkPaint* paint)
5433
5434Draw a set of sprites from atlas, using Clip, Matrix, and optional Paint paint.
5435paint uses Anti-alias, Color_Alpha, Color_Filter, Image_Filter, and Blend_Mode to draw, if present.
5436For each entry in the array, Rect tex locates sprite in atlas, and RSXform xform transforms it
5437into destination space.
5438xform and text must contain count entries.
5439Optional cullRect is a conservative bounds of all transformed sprites.
5440If cullrect is outside of Clip, canvas can skip drawing.
5441
5442#Param atlas Image containing sprites. ##
5443#Param xform RSXform mappings for sprites in atlas. ##
5444#Param tex Rect locations of sprites in atlas. ##
5445#Param count Number of sprites to draw. ##
5446#Param cullRect Rect bounds of transformed sprites for efficient clipping; or nullptr. ##
5447#Param paint Paint Color_Filter, Image_Filter, Blend_Mode, and so on; or nullptr. ##
5448
5449#Example
5450#Image 3
5451void draw(SkCanvas* canvas) {
5452 // sk_sp<SkImage> image = mandrill;
5453 SkRSXform xforms[] = { { .5f, 0, 0, 0 }, {0, .5f, 200, 100 } };
5454 SkRect tex[] = { { 0, 0, 250, 250 }, { 0, 0, 250, 250 } };
5455 const SkImage* imagePtr = image.get();
5456 canvas->drawAtlas(imagePtr, xforms, tex, 2, nullptr, nullptr);
5457}
5458##
5459
5460#ToDo incomplete ##
5461
5462##
5463
5464# ------------------------------------------------------------------------------
5465
5466#Method void drawAtlas(const sk_sp<SkImage>& atlas, const SkRSXform xform[], const SkRect tex[],
5467 int count, const SkRect* cullRect, const SkPaint* paint)
5468
5469Draw a set of sprites from atlas, using Clip, Matrix, and optional Paint paint.
5470paint uses Anti-alias, Color_Alpha, Color_Filter, Image_Filter, and Blend_Mode to draw, if present.
5471For each entry in the array, Rect tex locates sprite in atlas, and RSXform xform transforms it
5472into destination space.
5473xform and text must contain count entries.
5474Optional cullRect is a conservative bounds of all transformed sprites.
5475If cullrect is outside of Clip, canvas can skip drawing.
5476
5477#Param atlas Image containing sprites. ##
5478#Param xform RSXform mappings for sprites in atlas. ##
5479#Param tex Rect locations of sprites in atlas. ##
5480#Param count Number of sprites to draw. ##
5481#Param cullRect Rect bounds of transformed sprites for efficient clipping; or nullptr. ##
5482#Param paint Paint Color_Filter, Image_Filter, Blend_Mode, and so on; or nullptr. ##
5483
5484#Example
5485#Image 3
5486void draw(SkCanvas* canvas) {
5487 // sk_sp<SkImage> image = mandrill;
5488 SkRSXform xforms[] = { { 1, 0, 0, 0 }, {0, 1, 300, 100 } };
5489 SkRect tex[] = { { 0, 0, 200, 200 }, { 200, 0, 400, 200 } };
5490 canvas->drawAtlas(image, xforms, tex, 2, nullptr, nullptr);
5491}
5492##
5493
5494#ToDo incomplete ##
5495
5496##
5497
5498# ------------------------------------------------------------------------------
5499
5500#Method void drawDrawable(SkDrawable* drawable, const SkMatrix* matrix = NULL)
5501
5502Draw Drawable drawable using Clip and Matrix, concatenated with
5503optional matrix.
5504
5505If Canvas has an asynchronous implementation, as is the case
5506when it is recording into Picture, then drawable will be referenced,
5507so that SkDrawable::draw() can be called when the operation is finalized. To force
5508immediate drawing, call SkDrawable::draw() instead.
5509
5510#Param drawable Custom struct encapsulating drawing commands. ##
5511#Param matrix Transformation applied to drawing; or nullptr. ##
5512
5513#Example
5514#Height 100
5515#Function
5516struct MyDrawable : public SkDrawable {
5517 SkRect onGetBounds() override { return SkRect::MakeWH(50, 100); }
5518
5519 void onDraw(SkCanvas* canvas) override {
5520 SkPath path;
5521 path.conicTo(10, 90, 50, 90, 0.9f);
5522 SkPaint paint;
5523 paint.setColor(SK_ColorBLUE);
5524 canvas->drawRect(path.getBounds(), paint);
5525 paint.setAntiAlias(true);
5526 paint.setColor(SK_ColorWHITE);
5527 canvas->drawPath(path, paint);
5528 }
5529};
5530
5531#Function ##
5532void draw(SkCanvas* canvas) {
5533 sk_sp<SkDrawable> drawable(new MyDrawable);
5534 SkMatrix matrix;
5535 matrix.setTranslate(10, 10);
5536 canvas->drawDrawable(drawable.get(), &matrix);
5537}
5538##
5539
5540#ToDo incomplete ##
5541
5542##
5543
5544# ------------------------------------------------------------------------------
5545
5546#Method void drawDrawable(SkDrawable* drawable, SkScalar x, SkScalar y)
5547
5548Draw Drawable drawable using Clip and Matrix, offset by (x, y).
5549
5550If Canvas has an asynchronous implementation, as is the case
5551when it is recording into Picture, then drawable will be referenced,
5552so that SkDrawable::draw() can be called when the operation is finalized. To force
5553immediate drawing, call SkDrawable::draw() instead.
5554
5555#Param drawable Custom struct encapsulating drawing commands. ##
5556#Param x Offset into Canvas writable pixels in x. ##
5557#Param y Offset into Canvas writable pixels in y. ##
5558
5559#Example
5560#Height 100
5561#Function
5562struct MyDrawable : public SkDrawable {
5563 SkRect onGetBounds() override { return SkRect::MakeWH(50, 100); }
5564
5565 void onDraw(SkCanvas* canvas) override {
5566 SkPath path;
5567 path.conicTo(10, 90, 50, 90, 0.9f);
5568 SkPaint paint;
5569 paint.setColor(SK_ColorBLUE);
5570 canvas->drawRect(path.getBounds(), paint);
5571 paint.setAntiAlias(true);
5572 paint.setColor(SK_ColorWHITE);
5573 canvas->drawPath(path, paint);
5574 }
5575};
5576
5577#Function ##
5578void draw(SkCanvas* canvas) {
5579 sk_sp<SkDrawable> drawable(new MyDrawable);
5580 canvas->drawDrawable(drawable.get(), 10, 10);
5581}
5582##
5583
5584#ToDo incomplete ##
5585
5586##
5587
5588# ------------------------------------------------------------------------------
5589
5590#Method void drawAnnotation(const SkRect& rect, const char key[], SkData* value)
5591
5592Associate Rect on Canvas when an annotation; a key-value pair, where the key is
5593a null-terminated utf8 string, and optional value is stored as Data.
5594
5595Only some canvas implementations, such as recording to Picture, or drawing to
5596Document_PDF, use annotations.
5597
5598#Param rect Rect extent of canvas to annotate. ##
5599#Param key String used for lookup. ##
5600#Param value Data holding value stored in annotation. ##
5601
5602#Example
5603 #Height 1
5604 const char text[] = "Click this link!";
5605 SkRect bounds;
5606 SkPaint paint;
5607 paint.setTextSize(40);
5608 (void)paint.measureText(text, strlen(text), &bounds);
5609 const char url[] = "https://www.google.com/";
5610 sk_sp<SkData> urlData(SkData::MakeWithCString(url));
5611 canvas->drawAnnotation(bounds, "url_key", urlData.get());
5612##
5613
5614#ToDo incomplete ##
5615
5616##
5617
5618# ------------------------------------------------------------------------------
5619
5620#Method void drawAnnotation(const SkRect& rect, const char key[], const sk_sp<SkData>& value)
5621
5622Associate Rect on Canvas when an annotation; a key-value pair, where the key is
5623a null-terminated utf8 string, and optional value is stored as Data.
5624
5625Only some canvas implementations, such as recording to Picture, or drawing to
5626Document_PDF, use annotations.
5627
5628#Param rect Rect extent of canvas to annotate. ##
5629#Param key String used for lookup. ##
5630#Param value Data holding value stored in annotation. ##
5631
5632#Example
5633#Height 1
5634 const char text[] = "Click this link!";
5635 SkRect bounds;
5636 SkPaint paint;
5637 paint.setTextSize(40);
5638 (void)paint.measureText(text, strlen(text), &bounds);
5639 const char url[] = "https://www.google.com/";
5640 sk_sp<SkData> urlData(SkData::MakeWithCString(url));
5641 canvas->drawAnnotation(bounds, "url_key", urlData.get());
5642##
5643
5644#ToDo incomplete ##
5645
5646##
5647
5648#Method SkDrawFilter* getDrawFilter() const
5649
5650Legacy call to be deprecated.
5651
5652#Deprecated
5653##
5654
5655##
5656
5657#Method virtual SkDrawFilter* setDrawFilter(SkDrawFilter* filter)
5658
5659Legacy call to be deprecated.
5660
5661#Deprecated
5662##
5663
5664##
5665
5666# ------------------------------------------------------------------------------
5667
5668#Method virtual bool isClipEmpty() const
5669
5670Returns true if Clip is empty; that is, nothing will draw.
5671
5672isClipEmpty may do work when called; it should not be called
5673more often than needed. However, once called, subsequent calls perform no
5674work until Clip changes.
5675
5676#Return true if Clip is empty. ##
5677
5678#Example
5679 void draw(SkCanvas* canvas) {
5680 SkDebugf("clip is%s empty\n", canvas->isClipEmpty() ? "" : " not");
5681 SkPath path;
5682 canvas->clipPath(path);
5683 SkDebugf("clip is%s empty\n", canvas->isClipEmpty() ? "" : " not");
5684 }
5685 #StdOut
5686 clip is not empty
5687 clip is empty
5688 ##
5689##
5690
5691#ToDo incomplete ##
5692
5693##
5694
5695# ------------------------------------------------------------------------------
5696
5697#Method virtual bool isClipRect() const
5698
5699Returns true if Clip is Rect and not empty.
5700Returns false if the clip is empty, or if it is not Rect.
5701
5702#Return true if Clip is Rect and not empty. ##
5703
5704#Example
5705 void draw(SkCanvas* canvas) {
5706 SkDebugf("clip is%s rect\n", canvas->isClipRect() ? "" : " not");
5707 canvas->clipRect({0, 0, 0, 0});
5708 SkDebugf("clip is%s rect\n", canvas->isClipRect() ? "" : " not");
5709 }
5710 #StdOut
5711 clip is rect
5712 clip is not rect
5713 ##
5714##
5715
5716#ToDo incomplete ##
5717
5718##
5719
5720#Class SkCanvas ##
5721#Topic Canvas ##