aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar Cary Clark <caryclark@skia.org>2017-10-26 07:58:48 -0400
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2017-10-26 12:17:36 +0000
commit154beea85961f73ed7f0da047b7ebd16d2a2d829 (patch)
tree1e128ab8ce82ea6fd9c1a933d5bb36516dd9af4e
parent456b292956bbc8e90a50be74fc9ccb95ebf11ebd (diff)
Add docs for SkMatrix, SkRect, SkIRect, SkBitmap
Also minor changes to earlier docs. Many small changes to improve indentation in generated includes. Added support for matrix math illustrations. Docs-Preview: https://skia.org/?cl=58500 Bug: skia:6898 Change-Id: I7da58ad55f82d7fd41d19288beb2cd71730fb01f Reviewed-on: https://skia-review.googlesource.com/58500 Commit-Queue: Cary Clark <caryclark@skia.org> Reviewed-by: Cary Clark <caryclark@google.com> Reviewed-by: Cary Clark <caryclark@skia.org>
-rw-r--r--docs/SkBitmap_Reference.bmh239
-rw-r--r--docs/SkCanvas_Reference.bmh115
-rw-r--r--docs/SkIRect_Reference.bmh2548
-rw-r--r--docs/SkMatrix_Reference.bmh3924
-rw-r--r--docs/SkPaint_Reference.bmh28
-rw-r--r--docs/SkPath_Reference.bmh47
-rw-r--r--docs/SkPixmap_Reference.bmh101
-rw-r--r--docs/SkRect_Reference.bmh1155
-rw-r--r--docs/undocumented.bmh20
-rw-r--r--site/user/api/SkBitmap_Reference.md248
-rw-r--r--site/user/api/SkCanvas_Reference.md84
-rw-r--r--site/user/api/SkIRect_Reference.md20
-rw-r--r--site/user/api/SkMatrix_Reference.md4459
-rw-r--r--site/user/api/SkPaint_Reference.md51
-rw-r--r--site/user/api/SkPath_Reference.md71
-rw-r--r--site/user/api/SkPixmap_Reference.md91
-rw-r--r--site/user/api/SkRect_Reference.md11
-rw-r--r--site/user/api/undocumented.md21
-rw-r--r--site/user/api/usingBookmaker.md22
-rw-r--r--tools/bookmaker/bookmaker.cpp8
-rw-r--r--tools/bookmaker/bookmaker.h138
-rw-r--r--tools/bookmaker/includeParser.cpp45
-rw-r--r--tools/bookmaker/includeWriter.cpp289
-rw-r--r--tools/bookmaker/mdOut.cpp32
-rw-r--r--tools/bookmaker/parserCommon.cpp133
-rw-r--r--tools/bookmaker/spellCheck.cpp8
26 files changed, 10204 insertions, 3704 deletions
diff --git a/docs/SkBitmap_Reference.bmh b/docs/SkBitmap_Reference.bmh
index 27580233da..75cd57ed99 100644
--- a/docs/SkBitmap_Reference.bmh
+++ b/docs/SkBitmap_Reference.bmh
@@ -89,8 +89,7 @@ is useful to position one or more Bitmaps within a shared pixel array.
# bytesPerPixel # Returns number of bytes in pixel based on Color_Type. ##
# colorSpace # Returns Image_Info Color_Space. ##
# colorType # Returns Image_Info Color_Type. ##
-# computeSafeSize64 # Returns minimum size required for pixels in 64 bits. ##
-# computeSize64 # Returns conservative size required for pixels. ##
+# computeByteSize # Returns size required for pixels. ##
# dimensions # Returns width and height. ##
# drawsNothing # Returns true if no width, no height, or no Pixel_Ref. ##
# empty() # Returns true if Image_Info has zero width or height. ##
@@ -98,7 +97,7 @@ is useful to position one or more Bitmaps within a shared pixel array.
# eraseARGB # Writes Color to pixels. ##
# eraseArea # Deprecated ##
# eraseColor # Writes Color to pixels. ##
-# eraseRGB # Writes opaque Color to pixels. ##
+# eraseRGB # Deprecated ##
# extractAlpha # Creates Bitmap containing Alpha of pixels. ##
# extractSubset # Creates Bitmap, sharing pixels if possible. ##
# getAddr # Returns readable pixel address as void pointer. ##
@@ -109,8 +108,6 @@ is useful to position one or more Bitmaps within a shared pixel array.
# getColor # Returns one pixel as Unpremultiplied Color. ##
# getGenerationID # Returns unique ID. ##
# getPixels # Returns address of pixels. ##
-# getSafeSize # Returns minimum size required for pixels in 32 bits. ##
-# getSize # Returns conservative size required for pixels in 32 bits. ##
# getSubset # Returns bounds offset by origin. ##
# hasHardwareMipMap # Returns Mip_Map support present; Android only. ##
# height # Returns pixel row count. ##
@@ -144,6 +141,7 @@ is useful to position one or more Bitmaps within a shared pixel array.
# tryAllocN32Pixels # Allocates compatible Color_ARGB pixels if possible. ##
# tryAllocPixels # Allocates pixels from Image_Info if possible. ##
# tryAllocPixelsFlags # Allocates pixels from Image_Info with options if possible. ##
+# validate() # Asserts if Bitmap is invalid (debug only). ##
# width() # Returns pixel column count. ##
# writePixels # Copies and converts pixels. ##
#Table ##
@@ -480,6 +478,7 @@ width: 56 height: 56 color: BGRA_8888 alpha: Opaque
#Method int width() const
Returns pixel count in each pixel row. Should be equal or less than:
+
#Formula
rowBytes() / info().bytesPerPixel()
##
@@ -1004,171 +1003,6 @@ width: 1000000 height: 1000000 computeByteSize: 4999999000000
# ------------------------------------------------------------------------------
-#Method size_t getSize() const
-
-Returns conservative memory required for pixel storage.
-Includes unused memory on last row when rowBytesAsPixels exceeds width().
-
-Does not check to see if result fits in 32 bits. Use getSize64() if the
-result may exceed 32 bits.
-
-#Return height() times rowBytes() ##
-
-#Example
-#Description
-getSize results are not useful when width() and height() are large.
-##
-void draw(SkCanvas* canvas) {
- SkBitmap bitmap;
- for (int width : { 1, 1000, 1000000 } ) {
- for (int height: { 1, 1000, 1000000 } ) {
- SkImageInfo imageInfo = SkImageInfo::MakeN32(width, height, kPremul_SkAlphaType);
- bitmap.setInfo(imageInfo, width * 5);
- SkDebugf("width: %7d height: %7d getSize: %9zu\n", width, height, bitmap.getSize());
- }
- }
-}
-#StdOut
-width: 1 height: 1 getSize: 5
-width: 1 height: 1000 getSize: 5000
-width: 1 height: 1000000 getSize: 5000000
-width: 1000 height: 1 getSize: 5000
-width: 1000 height: 1000 getSize: 5000000
-width: 1000 height: 1000000 getSize: 705032704
-width: 1000000 height: 1 getSize: 5000000
-width: 1000000 height: 1000 getSize: 705032704
-width: 1000000 height: 1000000 getSize: 658067456
-##
-##
-
-#SeeAlso getSafeSize computeSize64 rowBytes width()
-
-##
-
-# ------------------------------------------------------------------------------
-
-#Method size_t getSafeSize() const
-
-Returns minimum memory required for pixel storage.
-Does not include unused memory on last row when rowBytesAsPixels exceeds width().
-
-Returns zero if size does not fit in 32 bits. Use computeSafeSize64 if the
-result may exceed 32 bits.
-
-The pixel storage visible may be a subset of the Pixel_Ref. Accessing memory
-beyond the result may generate an exception.
-
-#Return exact pixel storage size ##
-
-#Example
-#Description
-getSafeSize results are not useful when width() and height() are large.
-##
-void draw(SkCanvas* canvas) {
- SkBitmap bitmap;
- for (int width : { 1, 1000, 1000000 } ) {
- for (int height: { 1, 1000, 1000000 } ) {
- SkImageInfo imageInfo = SkImageInfo::MakeN32(width, height, kPremul_SkAlphaType);
- bitmap.setInfo(imageInfo, width * 5);
- SkDebugf("width: %7d height: %7d getSafeSize: %9zu\n", width, height, bitmap.getSafeSize());
- }
- }
-}
-#StdOut
-width: 1 height: 1 getSafeSize: 4
-width: 1 height: 1000 getSafeSize: 4999
-width: 1 height: 1000000 getSafeSize: 4999999
-width: 1000 height: 1 getSafeSize: 4000
-width: 1000 height: 1000 getSafeSize: 4999000
-width: 1000 height: 1000000 getSafeSize: 0
-width: 1000000 height: 1 getSafeSize: 4000000
-width: 1000000 height: 1000 getSafeSize: 0
-width: 1000000 height: 1000000 getSafeSize: 0
-##
-##
-
-#SeeAlso getSize computeSafeSize64 rowBytes width()
-
-##
-
-# ------------------------------------------------------------------------------
-
-#Method int64_t computeSize64() const
-
-Returns conservative memory required for pixel storage.
-Includes unused memory on last row when rowBytesAsPixels exceeds width().
-
-#Return conservative pixel storage size ##
-
-#Example
-void draw(SkCanvas* canvas) {
- SkBitmap bitmap;
- for (int width : { 1, 1000, 1000000 } ) {
- for (int height: { 1, 1000, 1000000 } ) {
- SkImageInfo imageInfo = SkImageInfo::MakeN32(width, height, kPremul_SkAlphaType);
- bitmap.setInfo(imageInfo, width * 5);
- SkDebugf("width: %7d height: %7d computeSize64: %13lld\n", width, height,
- bitmap.computeSize64());
- }
- }
-}
-#StdOut
-width: 1 height: 1 computeSize64: 5
-width: 1 height: 1000 computeSize64: 5000
-width: 1 height: 1000000 computeSize64: 5000000
-width: 1000 height: 1 computeSize64: 5000
-width: 1000 height: 1000 computeSize64: 5000000
-width: 1000 height: 1000000 computeSize64: 5000000000
-width: 1000000 height: 1 computeSize64: 5000000
-width: 1000000 height: 1000 computeSize64: 5000000000
-width: 1000000 height: 1000000 computeSize64: 5000000000000
-##
-##
-
-#SeeAlso getSize computeSafeSize64 rowBytes width()
-
-##
-
-# ------------------------------------------------------------------------------
-
-#Method int64_t computeSafeSize64() const
-
-Returns minimum memory required for pixel storage.
-Does not include unused memory on last row when rowBytesAsPixels exceeds width().
-
-#Return exact pixel storage size ##
-
-#Example
-void draw(SkCanvas* canvas) {
- SkBitmap bitmap;
- for (int width : { 1, 1000, 1000000 } ) {
- for (int height: { 1, 1000, 1000000 } ) {
- SkImageInfo imageInfo = SkImageInfo::MakeN32(width, height, kPremul_SkAlphaType);
- bitmap.setInfo(imageInfo, width * 5);
- SkDebugf("width: %7d height: %7d computeSafeSize64: %13lld\n", width, height,
- bitmap.computeSafeSize64());
- }
- }
-}
-#StdOut
-width: 1 height: 1 computeSafeSize64: 4
-width: 1 height: 1000 computeSafeSize64: 4999
-width: 1 height: 1000000 computeSafeSize64: 4999999
-width: 1000 height: 1 computeSafeSize64: 4000
-width: 1000 height: 1000 computeSafeSize64: 4999000
-width: 1000 height: 1000000 computeSafeSize64: 4999999000
-width: 1000000 height: 1 computeSafeSize64: 4000000
-width: 1000000 height: 1000 computeSafeSize64: 4999000000
-width: 1000000 height: 1000000 computeSafeSize64: 4999999000000
-##
-##
-
-#SeeAlso getSafeSize computeSize64 rowBytes width()
-
-##
-
-# ------------------------------------------------------------------------------
-
#Method bool isImmutable() const
Returns true if pixels can not change.
@@ -1201,9 +1035,9 @@ copy is immutable
#Method void setImmutable()
-Once set, pixels can not change. Any other bitmap sharing the same Pixel_Ref
-are also marked as immutable. Once Pixel_Ref is marked immutable, the setting
-cannot be cleared.
+Sets internal flag to mark Bitmap as immutable. Once set, pixels can not change.
+Any other bitmap sharing the same Pixel_Ref are also marked as immutable.
+Once Pixel_Ref is marked immutable, the setting cannot be cleared.
Writing to immutable Bitmap pixels triggers an assert on debug builds.
@@ -2547,7 +2381,7 @@ then Color_RGB is ignored.
canvas->drawBitmap(bitmap, 0, 0);
##
-#SeeAlso eraseARGB eraseRGB erase
+#SeeAlso eraseARGB erase
##
@@ -2576,7 +2410,7 @@ then r, g, and b are ignored.
canvas->drawBitmap(bitmap, .5f, .5f);
##
-#SeeAlso eraseColor eraseRGB erase
+#SeeAlso eraseColor erase
##
@@ -2584,22 +2418,13 @@ then r, g, and b are ignored.
#Method void eraseRGB(U8CPU r, U8CPU g, U8CPU b) const
-Replaces pixel values with Color built from r, g, and b with Color_Alpha set
-to 255. All pixels contained by bounds() are affected.
-If colorType is kAlpha_8_SkColorType, all pixels are set to 255.
+Deprecated. Use eraseARGB or eraseColor.
-#Param r amount of Color_RGB_Red, from no red (0) to full red (255) ##
-#Param g amount of Color_RGB_Green, from no green (0) to full green (255) ##
-#Param b amount of Color_RGB_Blue, from no blue (0) to full blue (255) ##
+#Param r amount of red ##
+#Param g amount of green ##
+#Param b amount of blue ##
-#Example
-#Height 80
- SkBitmap bitmap;
- bitmap.allocPixels(SkImageInfo::MakeN32(1, 1, kPremul_SkAlphaType));
- bitmap.eraseRGB(0xff, 0x7f, 0x3f);
- canvas->scale(50, 50);
- canvas->drawBitmap(bitmap, 0, 0);
- canvas->drawBitmap(bitmap, .5f, .5f);
+#NoExample
##
#SeeAlso eraseColor eraseARGB erase
@@ -2950,7 +2775,8 @@ match. If this->colorSpace is nullptr, dstInfo.colorSpace must match. Returns
false if pixel conversion is not possible.
srcX and srcY may be negative to copy only top or left of source. Returns
-false if width() or height() is zero or negative. Returns false if
+false if width() or height() is zero or negative.
+Returns false if
#Formula
abs(srcX) >= this->width()
##
@@ -3034,7 +2860,8 @@ match. If this->colorSpace is nullptr, dstInfo.colorSpace must match. Returns
false if pixel conversion is not possible.
srcX and srcY may be negative to copy only top or left of source. Returns
-false if width() or height() is zero or negative. Returns false if
+false if width() or height() is zero or negative.
+Returns false if
#Formula
abs(srcX) >= this->width()
##
@@ -3108,7 +2935,8 @@ match. If this->colorSpace is nullptr, dst Color_Space must match. Returns
false if pixel conversion is not possible.
srcX and srcY may be negative to copy only top or left of source. Returns
-false if width() or height() is zero or negative. Returns false if
+false if width() or height() is zero or negative.
+Returns false if
#Formula
abs(srcX) >= this->width()
##
@@ -3220,7 +3048,8 @@ match. If this->colorSpace is nullptr, src Color_Space must match. Returns
false if pixel conversion is not possible.
dstX and dstY may be negative to copy only top or left of source. Returns
-false if width() or height() is zero or negative. Returns false if
+false if width() or height() is zero or negative.
+Returns false if
#Formula
abs(dstX) >= this->width()
##
@@ -3541,11 +3370,11 @@ mask.
#Method bool peekPixels(SkPixmap* pixmap) const
-If the pixels are available from this bitmap return true, and fill out the
-specified pixmap (if not null). If there are no pixels, return false and
-ignore the pixmap parameter.
-Note: if this returns true, the results (in the pixmap) are only valid until the bitmap
-is changed in any way, in which case the results are invalid.
+Copies Bitmap pixel address, row bytes, and Image_Info to pixmap, if address
+is available, and returns true. If pixel address is not available, return
+false and leave pixmap unchanged.
+
+pixmap contents become invalid on any future change to Bitmap.
#Param pixmap storage for pixel state if pixels are readable; otherwise, ignored ##
@@ -3590,6 +3419,20 @@ is changed in any way, in which case the results are invalid.
# ------------------------------------------------------------------------------
+#Method void validate() const;
+
+Asserts if internal values are illegal or inconsistent. Only available if
+SK_DEBUG is defined at compile time.
+
+#NoExample
+##
+
+#SeeAlso SkImageInfo::validate()
+
+##
+
+# ------------------------------------------------------------------------------
+
#Method void toString(SkString* str) const;
#DefinedBy SK_TO_STRING_NONVIRT() ##
diff --git a/docs/SkCanvas_Reference.bmh b/docs/SkCanvas_Reference.bmh
index 486fe46d71..3c836b41d3 100644
--- a/docs/SkCanvas_Reference.bmh
+++ b/docs/SkCanvas_Reference.bmh
@@ -975,14 +975,11 @@ Canvas or Surface call may invalidate the pixmap values.
#Method bool readPixels(const SkImageInfo& dstInfo, void* dstPixels, size_t dstRowBytes,
int srcX, int srcY)
-Copies rectangle of pixels from Canvas into dstPixels. Matrix and Clip are
-ignored. Source rectangle corners are (srcX, srcY) and
-#Formula
-(this->imageInfo.width(), this->imageInfo.height())
-##
-.
+Copies Rect of pixels from Canvas into dstPixels. Matrix and Clip are
+ignored. Source Rect corners are (srcX, srcY) and
+(imageInfo().width(), imageInfo().height()).
-Destination rectangle corners are (0, 0) and (bitmap.width(), bitmap.height()).
+Destination Rect corners are (0, 0) and (bitmap.width(), bitmap.height()).
Copies each readable pixel intersecting both rectangles, without scaling,
converting to dstInfo.colorType() and dstInfo.alphaType() if required.
@@ -995,7 +992,7 @@ The destination pixel storage must be allocated by the caller.
Pixel values are converted only if Image_Color_Type and Image_Alpha_Type
do not match. Only pixels within both source and destination rectangles
-are copied. dstPixels contents outside the rectangle intersection are unchanged.
+are copied. dstPixels contents outside Rect intersection are unchanged.
Pass negative values for srcX or srcY to offset pixels across or down destination.
@@ -1070,14 +1067,11 @@ Does not copy, and returns false if:
#Method bool readPixels(const SkPixmap& pixmap, int srcX, int srcY)
-Copies rectangle of pixels from Canvas into pixmap. Matrix and Clip are
-ignored. Source rectangle corners are (srcX, srcY) and
-#Formula
-(this->imageInfo.width(), this->imageInfo.height())
-##
-.
+Copies Rect of pixels from Canvas into pixmap. Matrix and Clip are
+ignored. Source Rect corners are (srcX, srcY) and
+(imageInfo().width(), imageInfo().height()).
-Destination rectangle corners are (0, 0) and (bitmap.width(), bitmap.height()).
+Destination Rect corners are (0, 0) and (bitmap.width(), bitmap.height()).
Copies each readable pixel intersecting both rectangles, without scaling,
converting to pixmap.colorType() and pixmap.alphaType() if required.
@@ -1089,8 +1083,8 @@ class like SkDumpCanvas.
Caller must allocate pixel storage in pixmap if needed.
Pixel values are converted only if Image_Color_Type and Image_Alpha_Type
-do not match. Only pixels within both source and destination rectangles
-are copied. pixmap pixels contents outside the rectangle intersection are unchanged.
+do not match. Only pixels within both source and destination Rects
+are copied. pixmap pixels contents outside Rect intersection are unchanged.
Pass negative values for srcX or srcY to offset pixels across or down pixmap.
@@ -1136,14 +1130,11 @@ Does not copy, and returns false if:
#Method bool readPixels(const SkBitmap& bitmap, int srcX, int srcY)
-Copies rectangle of pixels from Canvas into bitmap. Matrix and Clip are
-ignored. Source rectangle corners are (srcX, srcY) and
-#Formula
-(this->imageInfo.width(), this->imageInfo.height())
-##
-.
+Copies Rect of pixels from Canvas into bitmap. Matrix and Clip are
+ignored. Source Rect corners are (srcX, srcY) and
+(imageInfo().width(), imageInfo().height()).
-Destination rectangle corners are (0, 0) and (bitmap.width(), bitmap.height()).
+Destination Rect corners are (0, 0) and (bitmap.width(), bitmap.height()).
Copies each readable pixel intersecting both rectangles, without scaling,
converting to bitmap.colorType() and bitmap.alphaType() if required.
@@ -1156,7 +1147,7 @@ Caller must allocate pixel storage in bitmap if needed.
Bitmap values are converted only if Image_Color_Type and Image_Alpha_Type
do not match. Only pixels within both source and destination rectangles
-are copied. Bitmap pixels outside the rectangle intersection are unchanged.
+are copied. Bitmap pixels outside Rect intersection are unchanged.
Pass negative values for srcX or srcY to offset pixels across or down bitmap.
@@ -1202,24 +1193,13 @@ void draw(SkCanvas* canvas) {
#Method bool writePixels(const SkImageInfo& info, const void* pixels, size_t rowBytes, int x, int y)
-Copies rectangle from pixels to Canvas. Matrix and Clip are ignored.
-Source rectangle corners are (0, 0) and (info.width(), info.height()).
-Destination rectangle corners are (x, y) and
-#Formula
-(this->imageInfo.width(), this->imageInfo.height())
-##
-.
+Copies Rect from pixels to Canvas. Matrix and Clip are ignored.
+Source Rect corners are (0, 0) and (info.width(), info.height()).
+Destination Rect corners are (x, y) and
+(imageInfo().width(), imageInfo().height()).
Copies each readable pixel intersecting both rectangles, without scaling,
-converting to
-#Formula
-this->imageInfo.colorType()
-##
-and
-#Formula
-this->imageInfo.alphaType()
-##
-if required.
+converting to imageInfo().colorType() and imageInfo().alphaType() if required.
Pixels are writable when Device is raster, or backed by a GPU.
Pixels are not writable when SkCanvas is returned by SkDocument::beginPage,
@@ -1228,7 +1208,7 @@ class like SkDumpCanvas.
Pixel values are converted only if Image_Color_Type and Image_Alpha_Type
do not match. Only pixels within both source and destination rectangles
-are copied. Canvas pixels outside the rectangle intersection are unchanged.
+are copied. Canvas pixels outside Rect intersection are unchanged.
Pass negative values for x or y to offset pixels to the left or
above Canvas pixels.
@@ -1237,8 +1217,8 @@ Does not copy, and returns false if:
#List
# Source and destination rectangles do not intersect. ##
-# pixels could not be converted to this->imageInfo.colorType() or
-this->imageInfo.alphaType(). ##
+# pixels could not be converted to this->imageInfo().colorType() or
+this->imageInfo().alphaType(). ##
# Canvas pixels are not writable; for instance, Canvas is document-based. ##
# rowBytes is too small to contain one row of pixels. ##
##
@@ -1270,25 +1250,14 @@ this->imageInfo.alphaType(). ##
#Method bool writePixels(const SkBitmap& bitmap, int x, int y)
-Copies rectangle from pixels to Canvas. Matrix and Clip are ignored.
-Source rectangle corners are (0, 0) and (bitmap.width(), bitmap.height()).
+Copies Rect from pixels to Canvas. Matrix and Clip are ignored.
+Source Rect corners are (0, 0) and (bitmap.width(), bitmap.height()).
-Destination rectangle corners are (x, y) and
-#Formula
-(this->imageInfo.width(), this->imageInfo.height())
-##
-.
+Destination Rect corners are (x, y) and
+(imageInfo().width(), imageInfo().height()).
Copies each readable pixel intersecting both rectangles, without scaling,
-converting to
-#Formula
-this->imageInfo.colorType()
-##
-and
-#Formula
-this->imageInfo.alphaType()
-##
-if required.
+converting to imageInfo().colorType() and imageInfo().alphaType() if required.
Pixels are writable when Device is raster, or backed by a GPU.
Pixels are not writable when SkCanvas is returned by SkDocument::beginPage,
@@ -1297,7 +1266,7 @@ class like SkDumpCanvas.
Pixel values are converted only if Image_Color_Type and Image_Alpha_Type
do not match. Only pixels within both source and destination rectangles
-are copied. Canvas pixels outside the rectangle intersection are unchanged.
+are copied. Canvas pixels outside Rect intersection are unchanged.
Pass negative values for x or y to offset pixels to the left or
above Canvas pixels.
@@ -1307,8 +1276,8 @@ Does not copy, and returns false if:
#List
# Source and destination rectangles do not intersect. ##
# bitmap does not have allocated pixels. ##
-# bitmap pixels could not be converted to this->imageInfo.colorType() or
-this->imageInfo.alphaType(). ##
+# bitmap pixels could not be converted to this->imageInfo().colorType() or
+this->imageInfo().alphaType(). ##
# Canvas pixels are not writable; for instance, Canvas is document based. ##
# bitmap pixels are inaccessible; for instance, bitmap wraps a texture. ##
##
@@ -4687,14 +4656,6 @@ void draw(SkCanvas* canvas) {
# ------------------------------------------------------------------------------
#Struct Lattice
- Lattice divides Bitmap or Image into a rectangular grid.
- Grid entries on even columns and even rows are fixed; these entries are
- always drawn at their original size if the destination is large enough.
- If the destination side is too small to hold the fixed entries, all fixed
- entries are proportionately scaled down to fit.
- The grid entries not on even columns and rows are scaled to fit the
- remaining space, if any.
-
#Code
struct Lattice {
enum Flags {...
@@ -4708,6 +4669,14 @@ void draw(SkCanvas* canvas) {
};
##
+ Lattice divides Bitmap or Image into a rectangular grid.
+ Grid entries on even columns and even rows are fixed; these entries are
+ always drawn at their original size if the destination is large enough.
+ If the destination side is too small to hold the fixed entries, all fixed
+ entries are proportionately scaled down to fit.
+ The grid entries not on even columns and rows are scaled to fit the
+ remaining space, if any.
+
#Enum Flags
#Code
enum Flags : uint8_t {
@@ -6142,8 +6111,8 @@ Restores Canvas to saved state.
#Method void restore()
-Restores Canvas to saved state immediately. Subsequent calls and class
-destructor have no effect.
+Restores Canvas to saved state immediately. Subsequent calls and
+~SkAutoCanvasRestore have no effect.
#Example
// incomplete
diff --git a/docs/SkIRect_Reference.bmh b/docs/SkIRect_Reference.bmh
index d92c08715d..bdc694f8d5 100644
--- a/docs/SkIRect_Reference.bmh
+++ b/docs/SkIRect_Reference.bmh
@@ -1,121 +1,121 @@
-#Topic IRect
-#Alias IRect_Reference
-
-#Struct SkIRect
-
-SkIRect holds four 32 bit integer coordinates describing the upper and
-lower bounds of a rectangle. SkIRect may be created from outer bounds or
-from position, width, and height. SkIRect describes an area; if its right
-is less than or equal to its left, or if its bottom is less than or equal to
-its top, it is considered empty.
-
-#Topic Overview
-
-#Subtopic Subtopics
-#ToDo manually add subtopics ##
-#Table
-#Legend
-# topics # description ##
-#Legend ##
-#Table ##
-##
-
-#Subtopic Operators
-#Table
-#Legend
-# description # function ##
-#Legend ##
-# bool operator!=(const SkIRect& a, const SkIRect& b) # Returns true if members are unequal. ##
-# bool operator==(const SkIRect& a, const SkIRect& b) # Returns true if members are equal. ##
-#Table ##
-#Subtopic ##
-
-#Subtopic Member_Functions
-#Table
-#Legend
-# description # function ##
-#Legend ##
-# EmptyIRect # Returns immutable bounds of (0, 0, 0, 0). ##
-# Intersects # Returns true if areas overlap. ##
-# IntersectsNoEmptyCheck # Returns true if areas overlap. Skips empty check. ##
-# MakeEmpty # Returns bounds of (0, 0, 0, 0). ##
-# MakeLTRB # Constructs from int left, top, right, bottom. ##
-# MakeLargest # Constructs from (SK_MinS32, SK_MinS32, SK_MaxS32, SK_MaxS32). ##
-# MakeSize # Constructs from ISize returning (0, 0, width, height). ##
-# MakeWH # Constructs from int input returning (0, 0, width, height). ##
-# MakeXYWH # Constructs from int input returning (x, y, width, height). ##
-# bottom() # Returns larger bounds in y, if sorted. ##
-# centerX # Returns midpoint in x. ##
-# centerY # Returns midpoint in y. ##
-# contains() # Returns true if points are equal or inside. ##
-# containsNoEmptyCheck # Returns true if points are equal or inside. Skips empty check. ##
-# height() # Returns span in y. ##
-# inset() # Moves the sides symmetrically about the center. ##
-# intersect # Sets to shared area; returns true if not empty. ##
-# intersectNoEmptyCheck # Sets to shared area; returns true if not empty. Skips empty check. ##
-# is16Bit # Returns true if members fit in 16-bit word. ##
-# isEmpty # Returns true if width or height are zero or negative. ##
-# isLargest # Returns true if equal to (SK_MinS32, SK_MinS32, SK_MaxS32, SK_MaxS32). ##
-# join() # Sets to union of bounds. ##
-# left() # Returns smaller bounds in x, if sorted. ##
-# makeInset # Constructs from sides moved symmetrically about the center. ##
-# makeOffset # Constructs from translated sides. ##
-# makeOutset # Constructs from sides moved symmetrically about the center. ##
-# makeSorted # Constructs, ordering sides from smaller to larger. ##
-# offset() # Translates sides without changing width and height. ##
-# offsetTo # Translates to (x, y) without changing width and height. ##
-# outset() # Moves the sides symmetrically about the center. ##
-# quickReject # Returns true if rectangles do not intersect. ##
-# right() # Returns larger bounds in x, if sorted. ##
-# set() # Sets to (left, top, right, bottom). ##
-# setEmpty # Sets to (0, 0, 0, 0). ##
-# setLTRB # Sets to SkScalar input (left, top, right, bottom). ##
-# setLargest # Sets to (SK_MinS32, SK_MinS32, SK_MaxS32, SK_MaxS32). ##
-# setLargestInverted # Sets to (SK_MaxS32, SK_MaxS32, SK_MinS32, SK_MinS32). ##
-# setXYWH # Sets to (x, y, width, height). ##
-# size() # Returns ISize (width, height). ##
-# sort() # Orders sides from smaller to larger. ##
-# top() # Returns smaller bounds in y, if sorted. ##
-# width() # Returns span in x. ##
-# x() # Returns bounds left. ##
-# y() # Returns bounds top. ##
-#Table ##
-#Subtopic ##
-
-#Topic ##
-
-#Member int32_t fLeft
-May contain any value. The smaller of the horizontal values when sorted.
-When equal to or greater than fRight, IRect is empty.
-##
-
-#Member int32_t fTop
-May contain any value. The smaller of the horizontal values when sorted.
-When equal to or greater than fBottom, IRect is empty.
-##
-
-#Member int32_t fRight
-May contain any value. The larger of the vertical values when sorted.
-When equal to or less than fLeft, IRect is empty.
-##
-
-#Member int32_t fBottom
-May contain any value. The larger of the vertical values when sorted.
-When equal to or less than fTop, IRect is empty.
-##
-
-# ------------------------------------------------------------------------------
-
-#Method static constexpr SkIRect SK_WARN_UNUSED_RESULT MakeEmpty()
-
-Returns constructed IRect set to (0, 0, 0, 0).
-Many other rectangles are empty; if left is equal to or greater than right,
-or if top is equal to or greater than bottom. Setting all members to zero
-is a convenience, but does not designate a special empty rectangle.
-
-#Return bounds (0, 0, 0, 0) ##
-
-#Example
+#Topic IRect
+#Alias IRect_Reference
+
+#Struct SkIRect
+
+SkIRect holds four 32 bit integer coordinates describing the upper and
+lower bounds of a rectangle. SkIRect may be created from outer bounds or
+from position, width, and height. SkIRect describes an area; if its right
+is less than or equal to its left, or if its bottom is less than or equal to
+its top, it is considered empty.
+
+#Topic Overview
+
+#Subtopic Subtopics
+#ToDo manually add subtopics ##
+#Table
+#Legend
+# topics # description ##
+#Legend ##
+#Table ##
+##
+
+#Subtopic Operators
+#Table
+#Legend
+# description # function ##
+#Legend ##
+# bool operator!=(const SkIRect& a, const SkIRect& b) # Returns true if members are unequal. ##
+# bool operator==(const SkIRect& a, const SkIRect& b) # Returns true if members are equal. ##
+#Table ##
+#Subtopic ##
+
+#Subtopic Member_Functions
+#Table
+#Legend
+# description # function ##
+#Legend ##
+# EmptyIRect # Returns immutable bounds of (0, 0, 0, 0). ##
+# Intersects # Returns true if areas overlap. ##
+# IntersectsNoEmptyCheck # Returns true if areas overlap. Skips empty check. ##
+# MakeEmpty # Returns bounds of (0, 0, 0, 0). ##
+# MakeLTRB # Constructs from int left, top, right, bottom. ##
+# MakeLargest # Constructs from (SK_MinS32, SK_MinS32, SK_MaxS32, SK_MaxS32). ##
+# MakeSize # Constructs from ISize returning (0, 0, width, height). ##
+# MakeWH # Constructs from int input returning (0, 0, width, height). ##
+# MakeXYWH # Constructs from int input returning (x, y, width, height). ##
+# bottom() # Returns larger bounds in y, if sorted. ##
+# centerX # Returns midpoint in x. ##
+# centerY # Returns midpoint in y. ##
+# contains() # Returns true if points are equal or inside. ##
+# containsNoEmptyCheck # Returns true if points are equal or inside. Skips empty check. ##
+# height() # Returns span in y. ##
+# inset() # Moves the sides symmetrically about the center. ##
+# intersect # Sets to shared area; returns true if not empty. ##
+# intersectNoEmptyCheck # Sets to shared area; returns true if not empty. Skips empty check. ##
+# is16Bit # Returns true if members fit in 16-bit word. ##
+# isEmpty # Returns true if width or height are zero or negative. ##
+# isLargest # Returns true if equal to (SK_MinS32, SK_MinS32, SK_MaxS32, SK_MaxS32). ##
+# join() # Sets to union of bounds. ##
+# left() # Returns smaller bounds in x, if sorted. ##
+# makeInset # Constructs from sides moved symmetrically about the center. ##
+# makeOffset # Constructs from translated sides. ##
+# makeOutset # Constructs from sides moved symmetrically about the center. ##
+# makeSorted # Constructs, ordering sides from smaller to larger. ##
+# offset() # Translates sides without changing width and height. ##
+# offsetTo # Translates to (x, y) without changing width and height. ##
+# outset() # Moves the sides symmetrically about the center. ##
+# quickReject # Returns true if rectangles do not intersect. ##
+# right() # Returns larger bounds in x, if sorted. ##
+# set() # Sets to (left, top, right, bottom). ##
+# setEmpty # Sets to (0, 0, 0, 0). ##
+# setLTRB # Sets to SkScalar input (left, top, right, bottom). ##
+# setLargest # Sets to (SK_MinS32, SK_MinS32, SK_MaxS32, SK_MaxS32). ##
+# setLargestInverted # Sets to (SK_MaxS32, SK_MaxS32, SK_MinS32, SK_MinS32). ##
+# setXYWH # Sets to (x, y, width, height). ##
+# size() # Returns ISize (width, height). ##
+# sort() # Orders sides from smaller to larger. ##
+# top() # Returns smaller bounds in y, if sorted. ##
+# width() # Returns span in x. ##
+# x() # Returns bounds left. ##
+# y() # Returns bounds top. ##
+#Table ##
+#Subtopic ##
+
+#Topic ##
+
+#Member int32_t fLeft
+May contain any value. The smaller of the horizontal values when sorted.
+When equal to or greater than fRight, IRect is empty.
+##
+
+#Member int32_t fTop
+May contain any value. The smaller of the horizontal values when sorted.
+When equal to or greater than fBottom, IRect is empty.
+##
+
+#Member int32_t fRight
+May contain any value. The larger of the vertical values when sorted.
+When equal to or less than fLeft, IRect is empty.
+##
+
+#Member int32_t fBottom
+May contain any value. The larger of the vertical values when sorted.
+When equal to or less than fTop, IRect is empty.
+##
+
+# ------------------------------------------------------------------------------
+
+#Method static constexpr SkIRect SK_WARN_UNUSED_RESULT MakeEmpty()
+
+Returns constructed IRect set to (0, 0, 0, 0).
+Many other rectangles are empty; if left is equal to or greater than right,
+or if top is equal to or greater than bottom. Setting all members to zero
+is a convenience, but does not designate a special empty rectangle.
+
+#Return bounds (0, 0, 0, 0) ##
+
+#Example
SkIRect rect = SkIRect::MakeEmpty();
SkDebugf("MakeEmpty isEmpty: %s\n", rect.isEmpty() ? "true" : "false");
rect.offset(10, 10);
@@ -130,22 +130,22 @@ offset rect isEmpty: true
inset rect isEmpty: true
outset rect isEmpty: false
##
-##
-
-#SeeAlso EmptyIRect isEmpty setEmpty setLargestInverted SkRect::MakeEmpty
-
-##
-
-# ------------------------------------------------------------------------------
-
-#Method static SkIRect SK_WARN_UNUSED_RESULT MakeLargest()
-
-Returns constructed IRect setting left and top to most negative value, and
-setting right and bottom to most positive value.
-
-#Return bounds (SK_MinS32, SK_MinS32, SK_MaxS32, SK_MaxS32) ##
-
-#Example
+##
+
+#SeeAlso EmptyIRect isEmpty setEmpty setLargestInverted SkRect::MakeEmpty
+
+##
+
+# ------------------------------------------------------------------------------
+
+#Method static SkIRect SK_WARN_UNUSED_RESULT MakeLargest()
+
+Returns constructed IRect setting left and top to most negative value, and
+setting right and bottom to most positive value.
+
+#Return bounds (SK_MinS32, SK_MinS32, SK_MaxS32, SK_MaxS32) ##
+
+#Example
SkIRect rect = SkIRect::MakeLargest();
SkDebugf("MakeLargest isLargest: %s\n", rect.isLargest() ? "true" : "false");
SkDebugf("MakeLargest isEmpty: %s\n", rect.isEmpty() ? "true" : "false");
@@ -158,335 +158,335 @@ MakeLargest isEmpty: false
outset isLargest: false
outset isEmpty: true
##
-##
-
-#SeeAlso isLargest setLargest SkRect::MakeLargest
-
-##
-
-# ------------------------------------------------------------------------------
-
-#Method static constexpr SkIRect SK_WARN_UNUSED_RESULT MakeWH(int32_t w, int32_t h)
-
-Returns constructed IRect set to (0, 0, w, h). Does not validate input; w or h
-may be negative.
-
-#Param w width of constructed Rect ##
-#Param h height of constructed Rect ##
-
-#Return bounds (0, 0, w, h) ##
-
-#Example
+##
+
+#SeeAlso isLargest setLargest SkRect::MakeLargest
+
+##
+
+# ------------------------------------------------------------------------------
+
+#Method static constexpr SkIRect SK_WARN_UNUSED_RESULT MakeWH(int32_t w, int32_t h)
+
+Returns constructed IRect set to (0, 0, w, h). Does not validate input; w or h
+may be negative.
+
+#Param w width of constructed Rect ##
+#Param h height of constructed Rect ##
+
+#Return bounds (0, 0, w, h) ##
+
+#Example
SkIRect rect1 = SkIRect::MakeWH(25, 35);
SkIRect rect2 = SkIRect::MakeSize({25, 35});
SkIRect rect3 = SkIRect::MakeXYWH(0, 0, 25, 35);
SkIRect rect4 = SkIRect::MakeLTRB(0, 0, 25, 35);
SkDebugf("all %s" "equal\n", rect1 == rect2 && rect2 == rect3 && rect3 == rect4 ?
"" : "not ");
-#StdOut
-all equal
-##
-##
-
-#SeeAlso MakeSize MakeXYWH SkRect::MakeWH SkRect::MakeIWH
-
-##
-
-# ------------------------------------------------------------------------------
-
-#Method static constexpr SkIRect SK_WARN_UNUSED_RESULT MakeSize(const SkISize& size)
-
-Returns constructed IRect set to (0, 0, size.width(), size.height()).
-Does not validate input; size.width() or size.height() may be negative.
-
-#Param size values for Rect width and height ##
-
-#Return bounds (0, 0, size.width(), size.height()) ##
-
-#Example
+#StdOut
+all equal
+##
+##
+
+#SeeAlso MakeSize MakeXYWH SkRect::MakeWH SkRect::MakeIWH
+
+##
+
+# ------------------------------------------------------------------------------
+
+#Method static constexpr SkIRect SK_WARN_UNUSED_RESULT MakeSize(const SkISize& size)
+
+Returns constructed IRect set to (0, 0, size.width(), size.height()).
+Does not validate input; size.width() or size.height() may be negative.
+
+#Param size values for Rect width and height ##
+
+#Return bounds (0, 0, size.width(), size.height()) ##
+
+#Example
SkSize size = {25.5f, 35.5f};
SkIRect rect = SkIRect::MakeSize(size.toRound());
SkDebugf("round width: %d height: %d\n", rect.width(), rect.height());
rect = SkIRect::MakeSize(size.toFloor());
SkDebugf("floor width: %d height: %d\n", rect.width(), rect.height());
-#StdOut
+#StdOut
round width: 26 height: 36
-floor width: 25 height: 35
-##
-##
-
-#SeeAlso MakeWH MakeXYWH SkRect::Make SkRect::MakeIWH
-
-##
-
-# ------------------------------------------------------------------------------
-
-#Method static constexpr SkIRect SK_WARN_UNUSED_RESULT MakeLTRB(int32_t l, int32_t t, int32_t r, int32_t b)
-
-Returns constructed IRect set to (l, t, r, b). Does not sort input; Rect may
-result in fLeft greater than fRight, or fTop greater than fBottom.
-
-#Param l integer stored in fLeft ##
-#Param t integer stored in fTop ##
-#Param r integer stored in fRight ##
-#Param b integer stored in fBottom ##
-
-#Return bounds (l, t, r, b) ##
-
-#Example
+floor width: 25 height: 35
+##
+##
+
+#SeeAlso MakeWH MakeXYWH SkRect::Make SkRect::MakeIWH
+
+##
+
+# ------------------------------------------------------------------------------
+
+#Method static constexpr SkIRect SK_WARN_UNUSED_RESULT MakeLTRB(int32_t l, int32_t t, int32_t r, int32_t b)
+
+Returns constructed IRect set to (l, t, r, b). Does not sort input; Rect may
+result in fLeft greater than fRight, or fTop greater than fBottom.
+
+#Param l integer stored in fLeft ##
+#Param t integer stored in fTop ##
+#Param r integer stored in fRight ##
+#Param b integer stored in fBottom ##
+
+#Return bounds (l, t, r, b) ##
+
+#Example
SkIRect rect = SkIRect::MakeLTRB(5, 35, 15, 25);
SkDebugf("rect: %d, %d, %d, %d isEmpty: %s\n", rect.left(), rect.top(), rect.right(),
rect.bottom(), rect.isEmpty() ? "true" : "false");
rect.sort();
SkDebugf("rect: %d, %d, %d, %d isEmpty: %s\n", rect.left(), rect.top(), rect.right(),
rect.bottom(), rect.isEmpty() ? "true" : "false");
-#StdOut
+#StdOut
rect: 5, 35, 15, 25 isEmpty: true
-rect: 5, 25, 15, 35 isEmpty: false
-##
-##
-
-#SeeAlso MakeXYWH SkRect::MakeLTRB
-
-##
-
-# ------------------------------------------------------------------------------
-
-#Method static constexpr SkIRect SK_WARN_UNUSED_RESULT MakeXYWH(int32_t x, int32_t y, int32_t w, int32_t h)
-
-Returns constructed IRect set to
-#Formula
-(x, y, x + w, y + h)
-##
-. Does not validate input;
-w or h may be negative.
-
-#Param x stored in fLeft ##
-#Param y stored in fTop ##
-#Param w added to x and stored in fRight ##
-#Param h added to y and stored in fBottom ##
-
-#Return bounds at (x, y) with width w and height h ##
-
-#Example
+rect: 5, 25, 15, 35 isEmpty: false
+##
+##
+
+#SeeAlso MakeXYWH SkRect::MakeLTRB
+
+##
+
+# ------------------------------------------------------------------------------
+
+#Method static constexpr SkIRect SK_WARN_UNUSED_RESULT MakeXYWH(int32_t x, int32_t y, int32_t w, int32_t h)
+
+Returns constructed IRect set to:
+#Formula
+(x, y, x + w, y + h)
+##
+. Does not validate input;
+w or h may be negative.
+
+#Param x stored in fLeft ##
+#Param y stored in fTop ##
+#Param w added to x and stored in fRight ##
+#Param h added to y and stored in fBottom ##
+
+#Return bounds at (x, y) with width w and height h ##
+
+#Example
SkIRect rect = SkIRect::MakeXYWH(5, 35, -15, 25);
SkDebugf("rect: %d, %d, %d, %d isEmpty: %s\n", rect.left(), rect.top(), rect.right(),
rect.bottom(), rect.isEmpty() ? "true" : "false");
rect.sort();
SkDebugf("rect: %d, %d, %d, %d isEmpty: %s\n", rect.left(), rect.top(), rect.right(),
rect.bottom(), rect.isEmpty() ? "true" : "false");
-#StdOut
+#StdOut
rect: 5, 35, -10, 60 isEmpty: true
-rect: -10, 35, 5, 60 isEmpty: false
-##
-##
-
-#SeeAlso MakeLTRB SkRect::MakeXYWH
-
-##
-
-# ------------------------------------------------------------------------------
-
-#Method int left() const
-
-Returns left edge of IRect, if sorted.
-Call sort() to reverse fLeft and fRight if needed.
-
-#Return fLeft ##
-
-#Example
+rect: -10, 35, 5, 60 isEmpty: false
+##
+##
+
+#SeeAlso MakeLTRB SkRect::MakeXYWH
+
+##
+
+# ------------------------------------------------------------------------------
+
+#Method int left() const
+
+Returns left edge of IRect, if sorted.
+Call sort() to reverse fLeft and fRight if needed.
+
+#Return fLeft ##
+
+#Example
SkIRect unsorted = { 15, 5, 10, 25 };
SkDebugf("unsorted.fLeft: %d unsorted.left(): %d\n", unsorted.fLeft, unsorted.left());
SkIRect sorted = unsorted.makeSorted();
SkDebugf("sorted.fLeft: %d sorted.left(): %d\n", sorted.fLeft, sorted.left());
-#StdOut
+#StdOut
unsorted.fLeft: 15 unsorted.left(): 15
-sorted.fLeft: 10 sorted.left(): 10
-##
-##
-
-#SeeAlso fLeft x() SkRect::left()
-
-##
-
-# ------------------------------------------------------------------------------
-
-#Method int top() const
-
-Returns top edge of IRect, if sorted. Call isEmpty to see if IRect may be invalid,
-and sort() to reverse fTop and fBottom if needed.
-
-#Return fTop ##
-
-#Example
+sorted.fLeft: 10 sorted.left(): 10
+##
+##
+
+#SeeAlso fLeft x() SkRect::left()
+
+##
+
+# ------------------------------------------------------------------------------
+
+#Method int top() const
+
+Returns top edge of IRect, if sorted. Call isEmpty to see if IRect may be invalid,
+and sort() to reverse fTop and fBottom if needed.
+
+#Return fTop ##
+
+#Example
SkIRect unsorted = { 15, 25, 10, 5 };
SkDebugf("unsorted.fTop: %d unsorted.top(): %d\n", unsorted.fTop, unsorted.top());
SkIRect sorted = unsorted.makeSorted();
- SkDebugf("sorted.fTop: %d sorted.top(): %d\n", sorted.fTop, sorted.top());
-#StdOut
+ SkDebugf("sorted.fTop: %d sorted.top(): %d\n", sorted.fTop, sorted.top());
+#StdOut
unsorted.fTop: 25 unsorted.top(): 25
-sorted.fTop: 5 sorted.top(): 5
-##
-##
-
-#SeeAlso fTop y() SkRect::top()
-
-##
-
-# ------------------------------------------------------------------------------
-
-#Method int right() const
-
-Returns right edge of IRect, if sorted.
-Call sort() to reverse fLeft and fRight if needed.
-
-#Return fRight ##
-
-#Example
+sorted.fTop: 5 sorted.top(): 5
+##
+##
+
+#SeeAlso fTop y() SkRect::top()
+
+##
+
+# ------------------------------------------------------------------------------
+
+#Method int right() const
+
+Returns right edge of IRect, if sorted.
+Call sort() to reverse fLeft and fRight if needed.
+
+#Return fRight ##
+
+#Example
SkIRect unsorted = { 15, 25, 10, 5 };
SkDebugf("unsorted.fRight: %d unsorted.right(): %d\n", unsorted.fRight, unsorted.right());
SkIRect sorted = unsorted.makeSorted();
SkDebugf("sorted.fRight: %d sorted.right(): %d\n", sorted.fRight, sorted.right());
-#StdOut
+#StdOut
unsorted.fRight: 10 unsorted.right(): 10
-sorted.fRight: 15 sorted.right(): 15
-##
-##
-
-#SeeAlso fRight SkRect::right()
-
-##
-
-# ------------------------------------------------------------------------------
-
-#Method int bottom() const
-
-Returns bottom edge of IRect, if sorted. Call isEmpty to see if IRect may be invalid,
-and sort() to reverse fTop and fBottom if needed.
-
-#Return fBottom ##
-
-#Example
+sorted.fRight: 15 sorted.right(): 15
+##
+##
+
+#SeeAlso fRight SkRect::right()
+
+##
+
+# ------------------------------------------------------------------------------
+
+#Method int bottom() const
+
+Returns bottom edge of IRect, if sorted. Call isEmpty to see if IRect may be invalid,
+and sort() to reverse fTop and fBottom if needed.
+
+#Return fBottom ##
+
+#Example
SkIRect unsorted = { 15, 25, 10, 5 };
SkDebugf("unsorted.fBottom: %d unsorted.bottom(): %d\n", unsorted.fBottom, unsorted.bottom());
SkIRect sorted = unsorted.makeSorted();
SkDebugf("sorted.fBottom: %d sorted.bottom(): %d\n", sorted.fBottom, sorted.bottom());
-#StdOut
+#StdOut
unsorted.fBottom: 5 unsorted.bottom(): 5
-sorted.fBottom: 25 sorted.bottom(): 25
-##
-##
-
-#SeeAlso fBottom SkRect::bottom()
-
-##
-
-# ------------------------------------------------------------------------------
-
-#Method int x() const
-
-Returns left edge of IRect, if sorted. Call isEmpty to see if IRect may be invalid,
-and sort() to reverse fLeft and fRight if needed.
-
-#Return fLeft ##
-
-#Example
+sorted.fBottom: 25 sorted.bottom(): 25
+##
+##
+
+#SeeAlso fBottom SkRect::bottom()
+
+##
+
+# ------------------------------------------------------------------------------
+
+#Method int x() const
+
+Returns left edge of IRect, if sorted. Call isEmpty to see if IRect may be invalid,
+and sort() to reverse fLeft and fRight if needed.
+
+#Return fLeft ##
+
+#Example
SkIRect unsorted = { 15, 5, 10, 25 };
SkDebugf("unsorted.fLeft: %d unsorted.x(): %d\n", unsorted.fLeft, unsorted.x());
SkIRect sorted = unsorted.makeSorted();
SkDebugf("sorted.fLeft: %d sorted.x(): %d\n", sorted.fLeft, sorted.x());
-#StdOut
+#StdOut
unsorted.fLeft: 15 unsorted.x(): 15
-sorted.fLeft: 10 sorted.x(): 10
-##
-##
-
-#SeeAlso fLeft left() y() SkRect::x()
-
-##
-
-# ------------------------------------------------------------------------------
-
-#Method int y() const
-
-Returns top edge of IRect, if sorted. Call isEmpty to see if IRect may be invalid,
-and sort() to reverse fTop and fBottom if needed.
-
-#Return fTop ##
-
-#Example
+sorted.fLeft: 10 sorted.x(): 10
+##
+##
+
+#SeeAlso fLeft left() y() SkRect::x()
+
+##
+
+# ------------------------------------------------------------------------------
+
+#Method int y() const
+
+Returns top edge of IRect, if sorted. Call isEmpty to see if IRect may be invalid,
+and sort() to reverse fTop and fBottom if needed.
+
+#Return fTop ##
+
+#Example
SkIRect unsorted = { 15, 25, 10, 5 };
SkDebugf("unsorted.fTop: %d unsorted.y(): %d\n", unsorted.fTop, unsorted.y());
SkIRect sorted = unsorted.makeSorted();
- SkDebugf("sorted.fTop: %d sorted.y(): %d\n", sorted.fTop, sorted.y());
-#StdOut
+ SkDebugf("sorted.fTop: %d sorted.y(): %d\n", sorted.fTop, sorted.y());
+#StdOut
unsorted.fTop: 25 unsorted.y(): 25
-sorted.fTop: 5 sorted.y(): 5
-##
-##
-
-#SeeAlso fTop top() x() SkRect::y()
-
-##
-
-# ------------------------------------------------------------------------------
-
-#Method int width() const
-
-Returns span on the x-axis. This does not check if IRect is sorted, or if
-result fits in 32-bit signed integer; result may be negative.
-
-#Return fRight minus fLeft ##
-
-#Example
+sorted.fTop: 5 sorted.y(): 5
+##
+##
+
+#SeeAlso fTop top() x() SkRect::y()
+
+##
+
+# ------------------------------------------------------------------------------
+
+#Method int width() const
+
+Returns span on the x-axis. This does not check if IRect is sorted, or if
+result fits in 32-bit signed integer; result may be negative.
+
+#Return fRight minus fLeft ##
+
+#Example
SkIRect unsorted = { 15, 25, 10, 5 };
SkDebugf("unsorted width: %d\n", unsorted.width());
SkIRect large = { -2147483647, 1, 2147483644, 2 };
SkDebugf("large width: %d\n", large.width());
-#StdOut
+#StdOut
unsorted width: -5
-large width: -5
-##
-##
-
-#SeeAlso height() SkRect::width()
-
-##
-
-# ------------------------------------------------------------------------------
-
-#Method int height() const
-
-Returns span on the y-axis. This does not check if IRect is sorted, or if
-result fits in 32-bit signed integer; result may be negative.
-
-#Return fBottom minus fTop ##
-
-#Example
+large width: -5
+##
+##
+
+#SeeAlso height() SkRect::width()
+
+##
+
+# ------------------------------------------------------------------------------
+
+#Method int height() const
+
+Returns span on the y-axis. This does not check if IRect is sorted, or if
+result fits in 32-bit signed integer; result may be negative.
+
+#Return fBottom minus fTop ##
+
+#Example
SkIRect unsorted = { 15, 25, 10, 20 };
SkDebugf("unsorted height: %d\n", unsorted.height());
SkIRect large = { 1, -2147483647, 2, 2147483644 };
SkDebugf("large height: %d\n", large.height());
-#StdOut
+#StdOut
unsorted height: -5
-large height: -5
-##
-##
-
-#SeeAlso width() SkRect::height()
-
-##
-
-# ------------------------------------------------------------------------------
-
-#Method SkISize size() const
-
-Returns spans on the x-axis and y-axis. This does not check if IRect is sorted,
-or if result fits in 32-bit signed integer; result may be negative.
-
-#Return ISize (width, height) ##
-
-#Example
+large height: -5
+##
+##
+
+#SeeAlso width() SkRect::height()
+
+##
+
+# ------------------------------------------------------------------------------
+
+#Method SkISize size() const
+
+Returns spans on the x-axis and y-axis. This does not check if IRect is sorted,
+or if result fits in 32-bit signed integer; result may be negative.
+
+#Return ISize (width, height) ##
+
+#Example
auto debugster = [](const char* prefix, const SkIRect& rect) -> void {
SkISize size = rect.size();
SkDebugf("%s ", prefix);
@@ -498,85 +498,85 @@ or if result fits in 32-bit signed integer; result may be negative.
rect.offset(20, 20);
debugster(" offset", rect);
rect.outset(20, 20);
- debugster(" outset", rect);
-#StdOut
+ debugster(" outset", rect);
+#StdOut
original rect: 20, 30, 40, 50 size: 20, 20
offset rect: 40, 50, 60, 70 size: 20, 20
- outset rect: 20, 30, 80, 90 size: 60, 60
-##
-##
-
-#SeeAlso height() width() MakeSize
-
-##
-
-# ------------------------------------------------------------------------------
-
-#Method int centerX() const
-
-Returns average of left edge and right edge. Result does not change if Rect
-is sorted. Result may be incorrect if Rect is far from the origin.
-
-Result is rounded down.
-
-#Return midpoint in x ##
-
-#Example
-#Description
-Dividing by two rounds towards zero. centerX uses a bit shift and rounds down.
-##
+ outset rect: 20, 30, 80, 90 size: 60, 60
+##
+##
+
+#SeeAlso height() width() MakeSize
+
+##
+
+# ------------------------------------------------------------------------------
+
+#Method int centerX() const
+
+Returns average of left edge and right edge. Result does not change if Rect
+is sorted. Result may be incorrect if Rect is far from the origin.
+
+Result is rounded down.
+
+#Return midpoint in x ##
+
+#Example
+#Description
+Dividing by two rounds towards zero. centerX uses a bit shift and rounds down.
+##
SkIRect tests[] = {{20, 30, 41, 51}, {-20, -30, -41, -51}, {-10, -10, 11, 11}};
for (auto rect : tests) {
SkDebugf("left: %3d right: %3d centerX: %3d ", rect.left(), rect.right(), rect.centerX());
SkDebugf("div2: %3d\n", (rect.left() + rect.right()) / 2);
}
-#StdOut
+#StdOut
left: 20 right: 41 centerX: 30 div2: 30
left: -20 right: -41 centerX: -31 div2: -30
-left: -10 right: 11 centerX: 0 div2: 0
-##
-##
-
-#SeeAlso centerY SkRect::centerX
-
-##
-
-# ------------------------------------------------------------------------------
-
-#Method int centerY() const
-
-Returns average of top edge and bottom edge. Result does not change if Rect
-is sorted. Result may be incorrect if Rect is far from the origin.
-
-Result is rounded down.
-
-#Return midpoint in y ##
-
-#Example
+left: -10 right: 11 centerX: 0 div2: 0
+##
+##
+
+#SeeAlso centerY SkRect::centerX
+
+##
+
+# ------------------------------------------------------------------------------
+
+#Method int centerY() const
+
+Returns average of top edge and bottom edge. Result does not change if Rect
+is sorted. Result may be incorrect if Rect is far from the origin.
+
+Result is rounded down.
+
+#Return midpoint in y ##
+
+#Example
SkIRect rect = { 0, 0, 2, 2 };
rect.offset(0x40000000, 0x40000000);
SkDebugf("left: %d right: %d centerX: %d ", rect.left(), rect.right(), rect.centerX());
- SkDebugf("safe mid x: %d\n", rect.left() / 2 + rect.right() / 2);
-#StdOut
-left: 1073741824 right: 1073741826 centerX: -1073741823 safe mid x: 1073741825
-##
-##
-
-#SeeAlso centerX SkRect::centerY
-
-##
-
-# ------------------------------------------------------------------------------
-
-#Method bool isEmpty() const
-
-Returns true if fLeft is equal to or greater than fRight, or if fTop is equal
-to or greater than fBottom. Call sort() to reverse rectangles with negative
-width() or height().
-
-#Return true if width() or height() are zero or negative ##
-
-#Example
+ SkDebugf("safe mid x: %d\n", rect.left() / 2 + rect.right() / 2);
+#StdOut
+left: 1073741824 right: 1073741826 centerX: -1073741823 safe mid x: 1073741825
+##
+##
+
+#SeeAlso centerX SkRect::centerY
+
+##
+
+# ------------------------------------------------------------------------------
+
+#Method bool isEmpty() const
+
+Returns true if fLeft is equal to or greater than fRight, or if fTop is equal
+to or greater than fBottom. Call sort() to reverse rectangles with negative
+width() or height().
+
+#Return true if width() or height() are zero or negative ##
+
+#Example
SkIRect tests[] = {{20, 40, 10, 50}, {20, 40, 20, 50}};
for (auto rect : tests) {
SkDebugf("rect: {%d, %d, %d, %d} is" "%s empty\n", rect.left(), rect.top(), rect.right(),
@@ -584,107 +584,107 @@ width() or height().
rect.sort();
SkDebugf("sorted: {%d, %d, %d, %d} is" "%s empty\n", rect.left(), rect.top(), rect.right(),
rect.bottom(), rect.isEmpty() ? "" : " not");
- }
+ }
#StdOut
rect: {20, 40, 10, 50} is empty
sorted: {10, 40, 20, 50} is not empty
rect: {20, 40, 20, 50} is empty
sorted: {20, 40, 20, 50} is empty
##
-##
-
-#SeeAlso EmptyIRect MakeEmpty sort SkRect::isEmpty
-
-##
-
-# ------------------------------------------------------------------------------
-
-#Method bool isLargest() const
-
-Returns true if IRect encloses largest possible area.
-
-#Return true if equal to (SK_MinS32, SK_MinS32, SK_MaxS32, SK_MaxS32) ##
-
-#Example
-#Description
-Note that the width is not negative, yet it cannot be represented as a 32-bit
-signed integer.
-##
+##
+
+#SeeAlso EmptyIRect MakeEmpty sort SkRect::isEmpty
+
+##
+
+# ------------------------------------------------------------------------------
+
+#Method bool isLargest() const
+
+Returns true if IRect encloses largest possible area.
+
+#Return true if equal to (SK_MinS32, SK_MinS32, SK_MaxS32, SK_MaxS32) ##
+
+#Example
+#Description
+Note that the width is not negative, yet it cannot be represented as a 32-bit
+signed integer.
+##
SkIRect large = SkIRect::MakeLargest();
SkDebugf("large is largest: %s\n" ,large.isLargest() ? "true" : "false");
SkDebugf("large width %d\n", large.width());
- SkDebugf("large is empty: %s\n", large.isEmpty() ? "true" : "false");
+ SkDebugf("large is empty: %s\n", large.isEmpty() ? "true" : "false");
#StdOut
large is largest: true
large width -2
large is empty: false
##
-##
-
-#SeeAlso MakeLargest SkRect::isLargest
-
-##
-
-# ------------------------------------------------------------------------------
-
-#Method bool operator==(const SkIRect& a, const SkIRect& b)
-
-Returns true if all members in a: fLeft, fTop, fRight, and fBottom; are
-identical to corresponding members in b.
-
-#Param a IRect to compare ##
-#Param b IRect to compare ##
-
-#Return true if members are equal ##
-
-#Example
+##
+
+#SeeAlso MakeLargest SkRect::isLargest
+
+##
+
+# ------------------------------------------------------------------------------
+
+#Method bool operator==(const SkIRect& a, const SkIRect& b)
+
+Returns true if all members in a: fLeft, fTop, fRight, and fBottom; are
+identical to corresponding members in b.
+
+#Param a IRect to compare ##
+#Param b IRect to compare ##
+
+#Return true if members are equal ##
+
+#Example
SkIRect test = {0, 0, 2, 2};
SkIRect sorted = test.makeSorted();
- SkDebugf("test %c= sorted\n", test == sorted ? '=' : '!');
+ SkDebugf("test %c= sorted\n", test == sorted ? '=' : '!');
#StdOut
test == sorted
##
-##
-
-#SeeAlso operator!=(const SkIRect& a, const SkIRect& b)
-
-##
-
-# ------------------------------------------------------------------------------
-
-#Method bool operator!=(const SkIRect& a, const SkIRect& b)
-
-Returns true if any member in a: fLeft, fTop, fRight, and fBottom; is not
-identical to the corresponding member in b.
-
-#Param a IRect to compare ##
-#Param b IRect to compare ##
-
-#Return true if members are not equal ##
-
-#Example
+##
+
+#SeeAlso operator!=(const SkIRect& a, const SkIRect& b)
+
+##
+
+# ------------------------------------------------------------------------------
+
+#Method bool operator!=(const SkIRect& a, const SkIRect& b)
+
+Returns true if any member in a: fLeft, fTop, fRight, and fBottom; is not
+identical to the corresponding member in b.
+
+#Param a IRect to compare ##
+#Param b IRect to compare ##
+
+#Return true if members are not equal ##
+
+#Example
SkIRect test = {2, 2, 0, 0};
SkIRect sorted = test.makeSorted();
SkDebugf("test %c= sorted\n", test != sorted ? '!' : '=');
#StdOut
test != sorted
##
-##
-
-#SeeAlso operator==(const SkIRect& a, const SkIRect& b)
-
-##
-
-# ------------------------------------------------------------------------------
-
-#Method bool is16Bit() const
-
-Returns true if all members: fLeft, fTop, fRight, and fBottom; values are
-equal to or larger than -32768 and equal to or smaller than 32767.
-
-#Return true if members fit in 16-bit word ##
-
-#Example
+##
+
+#SeeAlso operator==(const SkIRect& a, const SkIRect& b)
+
+##
+
+# ------------------------------------------------------------------------------
+
+#Method bool is16Bit() const
+
+Returns true if all members: fLeft, fTop, fRight, and fBottom; values are
+equal to or larger than -32768 and equal to or smaller than 32767.
+
+#Return true if members fit in 16-bit word ##
+
+#Example
SkIRect tests[] = {{-32768, -32768, 32767, 32767}, {-32768, -32768, 32768, 32768}};
for (auto rect : tests) {
SkDebugf("{%d, %d, %d, %d} %s in 16 bits\n", rect.fLeft, rect.fTop, rect.fRight,
@@ -694,23 +694,23 @@ equal to or larger than -32768 and equal to or smaller than 32767.
{-32768, -32768, 32767, 32767} fits in 16 bits
{-32768, -32768, 32768, 32768} does not fit in 16 bits
##
-##
-
-#SeeAlso SkTFitsIn
-
-##
-
-# ------------------------------------------------------------------------------
-
-#Method void setEmpty()
-
-Sets IRect to (0, 0, 0, 0).
-
-Many other rectangles are empty; if left is equal to or greater than right,
-or if top is equal to or greater than bottom. Setting all members to zero
-is a convenience, but does not designate a special empty rectangle.
-
-#Example
+##
+
+#SeeAlso SkTFitsIn
+
+##
+
+# ------------------------------------------------------------------------------
+
+#Method void setEmpty()
+
+Sets IRect to (0, 0, 0, 0).
+
+Many other rectangles are empty; if left is equal to or greater than right,
+or if top is equal to or greater than bottom. Setting all members to zero
+is a convenience, but does not designate a special empty rectangle.
+
+#Example
SkIRect rect = {3, 4, 1, 2};
for (int i = 0; i < 2; ++i) {
SkDebugf("rect: {%d, %d, %d, %d} is %s" "empty\n", rect.fLeft, rect.fTop,
@@ -721,26 +721,26 @@ is a convenience, but does not designate a special empty rectangle.
rect: {3, 4, 1, 2} is empty
rect: {0, 0, 0, 0} is empty
##
-##
-
-#SeeAlso MakeEmpty SkRect::setEmpty
-
-##
-
-# ------------------------------------------------------------------------------
-
-#Method void set(int32_t left, int32_t top, int32_t right, int32_t bottom)
-
-Sets IRect to (left, top, right, bottom).
-left and right are not sorted; left is not necessarily less than right.
-top and bottom are not sorted; top is not necessarily less than bottom.
-
-#Param left assigned to fLeft ##
-#Param top assigned to fTop ##
-#Param right assigned to fRight ##
-#Param bottom assigned to fBottom ##
-
-#Example
+##
+
+#SeeAlso MakeEmpty SkRect::setEmpty
+
+##
+
+# ------------------------------------------------------------------------------
+
+#Method void set(int32_t left, int32_t top, int32_t right, int32_t bottom)
+
+Sets IRect to (left, top, right, bottom).
+left and right are not sorted; left is not necessarily less than right.
+top and bottom are not sorted; top is not necessarily less than bottom.
+
+#Param left assigned to fLeft ##
+#Param top assigned to fTop ##
+#Param right assigned to fRight ##
+#Param bottom assigned to fBottom ##
+
+#Example
SkIRect rect1 = {3, 4, 1, 2};
SkDebugf("rect1: {%d, %d, %d, %d}\n", rect1.fLeft, rect1.fTop, rect1.fRight, rect1.fBottom);
SkIRect rect2;
@@ -750,26 +750,26 @@ top and bottom are not sorted; top is not necessarily less than bottom.
rect1: {3, 4, 1, 2}
rect2: {3, 4, 1, 2}
##
-##
-
-#SeeAlso setLTRB setXYWH SkRect::set
-
-##
-
-# ------------------------------------------------------------------------------
-
-#Method void setLTRB(int32_t left, int32_t top, int32_t right, int32_t bottom)
-
-Sets IRect to (left, top, right, bottom).
-left and right are not sorted; left is not necessarily less than right.
-top and bottom are not sorted; top is not necessarily less than bottom.
-
-#Param left stored in fLeft ##
-#Param top stored in fTop ##
-#Param right stored in fRight ##
-#Param bottom stored in fBottom ##
-
-#Example
+##
+
+#SeeAlso setLTRB setXYWH SkRect::set
+
+##
+
+# ------------------------------------------------------------------------------
+
+#Method void setLTRB(int32_t left, int32_t top, int32_t right, int32_t bottom)
+
+Sets IRect to (left, top, right, bottom).
+left and right are not sorted; left is not necessarily less than right.
+top and bottom are not sorted; top is not necessarily less than bottom.
+
+#Param left stored in fLeft ##
+#Param top stored in fTop ##
+#Param right stored in fRight ##
+#Param bottom stored in fBottom ##
+
+#Example
SkIRect rect1 = {3, 4, 1, 2};
SkDebugf("rect1: {%d, %d, %d, %d}\n", rect1.fLeft, rect1.fTop, rect1.fRight, rect1.fBottom);
SkIRect rect2;
@@ -779,29 +779,29 @@ top and bottom are not sorted; top is not necessarily less than bottom.
rect1: {3, 4, 1, 2}
rect2: {3, 4, 1, 2}
##
-##
-
-#SeeAlso set setXYWH SkRect::setLTRB
-
-##
-
-# ------------------------------------------------------------------------------
-
-#Method void setXYWH(int32_t x, int32_t y, int32_t width, int32_t height)
-
-Sets IRect to
-#Formula
-(x, y, x + width, y + height)
-##
-. Does not validate input;
-width or height may be negative.
-
-#Param x stored in fLeft ##
-#Param y stored in fTop ##
-#Param width added to x and stored in fRight ##
-#Param height added to y and stored in fBottom ##
-
-#Example
+##
+
+#SeeAlso set setXYWH SkRect::setLTRB
+
+##
+
+# ------------------------------------------------------------------------------
+
+#Method void setXYWH(int32_t x, int32_t y, int32_t width, int32_t height)
+
+Sets IRect to:
+#Formula
+(x, y, x + width, y + height)
+##
+. Does not validate input;
+width or height may be negative.
+
+#Param x stored in fLeft ##
+#Param y stored in fTop ##
+#Param width added to x and stored in fRight ##
+#Param height added to y and stored in fBottom ##
+
+#Example
SkIRect rect;
rect.setXYWH(5, 35, -15, 25);
SkDebugf("rect: %d, %d, %d, %d isEmpty: %s\n", rect.left(), rect.top(), rect.right(),
@@ -809,24 +809,24 @@ width or height may be negative.
rect.sort();
SkDebugf("rect: %d, %d, %d, %d isEmpty: %s\n", rect.left(), rect.top(), rect.right(),
rect.bottom(), rect.isEmpty() ? "true" : "false");
-#StdOut
+#StdOut
rect: 5, 35, -10, 60 isEmpty: true
-rect: -10, 35, 5, 60 isEmpty: false
-##
-##
-
-#SeeAlso MakeXYWH setLTRB set SkRect::setXYWH
-
-##
-
-# ------------------------------------------------------------------------------
-
-#Method void setLargest()
-
-Sets rectangle left and top to most negative value, and sets
-right and bottom to most positive value.
-
-#Example
+rect: -10, 35, 5, 60 isEmpty: false
+##
+##
+
+#SeeAlso MakeXYWH setLTRB set SkRect::setXYWH
+
+##
+
+# ------------------------------------------------------------------------------
+
+#Method void setLargest()
+
+Sets rectangle left and top to most negative value, and sets
+right and bottom to most positive value.
+
+#Example
SkIRect rect;
rect.setLargest();
SkDebugf("MakeLargest isLargest: %s\n", rect.isLargest() ? "true" : "false");
@@ -840,46 +840,46 @@ MakeLargest isEmpty: false
outset isLargest: false
outset isEmpty: true
##
-##
-
-#SeeAlso MakeLargest isLargest setLargestInverted SK_MinS32 SK_MaxS32
-
-##
-
-# ------------------------------------------------------------------------------
-
-#Method void setLargestInverted()
-#ToDo move this to private
-##
-
-Sets rectangle left and top to most positive value, and sets
-right and bottom to most negative value. This is used internally to
-flag that a condition is met, but otherwise has no special purpose.
-
-#NoExample
-##
-
-#SeeAlso setEmpty setLargest
-
-##
-
-# ------------------------------------------------------------------------------
-
-#Method SkIRect makeOffset(int32_t dx, int32_t dy) const
-
-Returns IRect offset by (dx, dy).
-
-If dx is negative, IRect returned is moved to the left.
-If dx is positive, IRect returned is moved to the right.
-If dy is negative, IRect returned is moved upward.
-If dy is positive, IRect returned is moved downward.
-
-#Param dx offset added to fLeft and fRight ##
-#Param dy offset added to fTop and fBottom ##
-
-#Return Rect offset in x or y, with original width and height ##
-
-#Example
+##
+
+#SeeAlso MakeLargest isLargest setLargestInverted SK_MinS32 SK_MaxS32
+
+##
+
+# ------------------------------------------------------------------------------
+
+#Method void setLargestInverted()
+#ToDo move this to private
+##
+
+Sets rectangle left and top to most positive value, and sets
+right and bottom to most negative value. This is used internally to
+flag that a condition is met, but otherwise has no special purpose.
+
+#NoExample
+##
+
+#SeeAlso setEmpty setLargest
+
+##
+
+# ------------------------------------------------------------------------------
+
+#Method SkIRect makeOffset(int32_t dx, int32_t dy) const
+
+Returns IRect offset by (dx, dy).
+
+If dx is negative, IRect returned is moved to the left.
+If dx is positive, IRect returned is moved to the right.
+If dy is negative, IRect returned is moved upward.
+If dy is positive, IRect returned is moved downward.
+
+#Param dx offset added to fLeft and fRight ##
+#Param dy offset added to fTop and fBottom ##
+
+#Return Rect offset in x or y, with original width and height ##
+
+#Example
SkIRect rect = { 10, 50, 20, 60 };
SkDebugf("rect: %d, %d, %d, %d isEmpty: %s\n", rect.left(), rect.top(), rect.right(),
rect.bottom(), rect.isEmpty() ? "true" : "false");
@@ -890,29 +890,29 @@ If dy is positive, IRect returned is moved downward.
rect: 10, 50, 20, 60 isEmpty: false
rect: 25, 82, 35, 92 isEmpty: false
##
-##
-
-#SeeAlso offset() makeInset makeOutset SkRect::makeOffset
-
-##
-
-# ------------------------------------------------------------------------------
-
-#Method SkIRect makeInset(int32_t dx, int32_t dy) const
-
-Returns IRect, inset by (dx, dy).
-
-If dx is negative, IRect returned is wider.
-If dx is positive, IRect returned is narrower.
-If dy is negative, IRect returned is taller.
-If dy is positive, IRect returned is shorter.
-
-#Param dx offset added to fLeft and subtracted from fRight ##
-#Param dy offset added to fTop and subtracted from fBottom ##
-
-#Return Rect inset symmetrically left and right, top and bottom ##
-
-#Example
+##
+
+#SeeAlso offset() makeInset makeOutset SkRect::makeOffset
+
+##
+
+# ------------------------------------------------------------------------------
+
+#Method SkIRect makeInset(int32_t dx, int32_t dy) const
+
+Returns IRect, inset by (dx, dy).
+
+If dx is negative, IRect returned is wider.
+If dx is positive, IRect returned is narrower.
+If dy is negative, IRect returned is taller.
+If dy is positive, IRect returned is shorter.
+
+#Param dx offset added to fLeft and subtracted from fRight ##
+#Param dy offset added to fTop and subtracted from fBottom ##
+
+#Return Rect inset symmetrically left and right, top and bottom ##
+
+#Example
SkIRect rect = { 10, 50, 20, 60 };
SkDebugf("rect: %d, %d, %d, %d isEmpty: %s\n", rect.left(), rect.top(), rect.right(),
rect.bottom(), rect.isEmpty() ? "true" : "false");
@@ -923,29 +923,29 @@ If dy is positive, IRect returned is shorter.
rect: 10, 50, 20, 60 isEmpty: false
rect: 25, 82, 5, 28 isEmpty: true
##
-##
-
-#SeeAlso inset() makeOffset makeOutset SkRect::makeInset
-
-##
-
-# ------------------------------------------------------------------------------
-
-#Method SkIRect makeOutset(int32_t dx, int32_t dy) const
-
-Returns IRect, outset by (dx, dy).
-
-If dx is negative, IRect returned is narrower.
-If dx is positive, IRect returned is wider.
-If dy is negative, IRect returned is shorter.
-If dy is positive, IRect returned is taller.
-
-#Param dx offset subtracted to fLeft and added from fRight ##
-#Param dy offset subtracted to fTop and added from fBottom ##
-
-#Return Rect outset symmetrically left and right, top and bottom ##
-
-#Example
+##
+
+#SeeAlso inset() makeOffset makeOutset SkRect::makeInset
+
+##
+
+# ------------------------------------------------------------------------------
+
+#Method SkIRect makeOutset(int32_t dx, int32_t dy) const
+
+Returns IRect, outset by (dx, dy).
+
+If dx is negative, IRect returned is narrower.
+If dx is positive, IRect returned is wider.
+If dy is negative, IRect returned is shorter.
+If dy is positive, IRect returned is taller.
+
+#Param dx offset subtracted to fLeft and added from fRight ##
+#Param dy offset subtracted to fTop and added from fBottom ##
+
+#Return Rect outset symmetrically left and right, top and bottom ##
+
+#Example
SkIRect rect = { 10, 50, 20, 60 };
SkDebugf("rect: %d, %d, %d, %d isEmpty: %s\n", rect.left(), rect.top(), rect.right(),
rect.bottom(), rect.isEmpty() ? "true" : "false");
@@ -956,164 +956,164 @@ If dy is positive, IRect returned is taller.
rect: 10, 50, 20, 60 isEmpty: false
rect: -5, 18, 35, 92 isEmpty: false
##
-##
-
-#SeeAlso outset() makeOffset makeInset SkRect::makeOutset
-
-##
-
-# ------------------------------------------------------------------------------
-
-#Method void offset(int32_t dx, int32_t dy)
-
-Offsets IRect by adding dx to fLeft, fRight; and by adding dy to fTop, fBottom.
-
-If dx is negative, moves IRect returned to the left.
-If dx is positive, moves IRect returned to the right.
-If dy is negative, moves IRect returned upward.
-If dy is positive, moves IRect returned downward.
-
-#Param dx offset added to fLeft and fRight ##
-#Param dy offset added to fTop and fBottom ##
-
-#Example
+##
+
+#SeeAlso outset() makeOffset makeInset SkRect::makeOutset
+
+##
+
+# ------------------------------------------------------------------------------
+
+#Method void offset(int32_t dx, int32_t dy)
+
+Offsets IRect by adding dx to fLeft, fRight; and by adding dy to fTop, fBottom.
+
+If dx is negative, moves IRect returned to the left.
+If dx is positive, moves IRect returned to the right.
+If dy is negative, moves IRect returned upward.
+If dy is positive, moves IRect returned downward.
+
+#Param dx offset added to fLeft and fRight ##
+#Param dy offset added to fTop and fBottom ##
+
+#Example
SkIRect rect = { 10, 14, 50, 73 };
rect.offset(5, 13);
SkDebugf("rect: %d, %d, %d, %d\n", rect.fLeft, rect.fTop, rect.fRight, rect.fBottom);
#StdOut
rect: 15, 27, 55, 86
##
-##
-
-#SeeAlso offsetTo makeOffset SkRect::offset
-
-##
-
-# ------------------------------------------------------------------------------
-
-#Method void offset(const SkIPoint& delta)
-
-Offsets IRect by adding delta.fX to fLeft, fRight; and by adding delta.fY to
-fTop, fBottom.
-
-If delta.fX is negative, moves IRect returned to the left.
-If delta.fX is positive, moves IRect returned to the right.
-If delta.fY is negative, moves IRect returned upward.
-If delta.fY is positive, moves IRect returned downward.
-
-#Param delta offset added to IRect ##
-
-#Example
+##
+
+#SeeAlso offsetTo makeOffset SkRect::offset
+
+##
+
+# ------------------------------------------------------------------------------
+
+#Method void offset(const SkIPoint& delta)
+
+Offsets IRect by adding delta.fX to fLeft, fRight; and by adding delta.fY to
+fTop, fBottom.
+
+If delta.fX is negative, moves IRect returned to the left.
+If delta.fX is positive, moves IRect returned to the right.
+If delta.fY is negative, moves IRect returned upward.
+If delta.fY is positive, moves IRect returned downward.
+
+#Param delta offset added to IRect ##
+
+#Example
SkIRect rect = { 10, 14, 50, 73 };
rect.offset({5, 13});
SkDebugf("rect: %d, %d, %d, %d\n", rect.fLeft, rect.fTop, rect.fRight, rect.fBottom);
#StdOut
rect: 15, 27, 55, 86
##
-##
-
-#SeeAlso offsetTo makeOffset SkRect::offset
-
-##
-
-# ------------------------------------------------------------------------------
-
-#Method void offsetTo(int32_t newX, int32_t newY)
-
-Offsets IRect so that fLeft equals newX, and fTop equals newY. width and height
-are unchanged.
-
-#Param newX stored in fLeft, preserving width() ##
-#Param newY stored in fTop, preserving height() ##
-
-#Example
+##
+
+#SeeAlso offsetTo makeOffset SkRect::offset
+
+##
+
+# ------------------------------------------------------------------------------
+
+#Method void offsetTo(int32_t newX, int32_t newY)
+
+Offsets IRect so that fLeft equals newX, and fTop equals newY. width and height
+are unchanged.
+
+#Param newX stored in fLeft, preserving width() ##
+#Param newY stored in fTop, preserving height() ##
+
+#Example
SkIRect rect = { 10, 14, 50, 73 };
rect.offsetTo(15, 27);
SkDebugf("rect: %d, %d, %d, %d\n", rect.fLeft, rect.fTop, rect.fRight, rect.fBottom);
#StdOut
rect: 15, 27, 55, 86
##
-##
-
-#SeeAlso offset makeOffset setXYWH SkRect::offsetTo
-
-##
-
-# ------------------------------------------------------------------------------
-
-#Method void inset(int32_t dx, int32_t dy)
-
-Insets IRect by (dx,dy).
-
-If dx is positive, makes IRect narrower.
-If dx is negative, makes IRect wider.
-If dy is positive, makes IRect shorter.
-If dy is negative, makes IRect taller.
-
-#Param dx offset added to fLeft and subtracted from fRight ##
-#Param dy offset added to fTop and subtracted from fBottom ##
-
-#Example
+##
+
+#SeeAlso offset makeOffset setXYWH SkRect::offsetTo
+
+##
+
+# ------------------------------------------------------------------------------
+
+#Method void inset(int32_t dx, int32_t dy)
+
+Insets IRect by (dx,dy).
+
+If dx is positive, makes IRect narrower.
+If dx is negative, makes IRect wider.
+If dy is positive, makes IRect shorter.
+If dy is negative, makes IRect taller.
+
+#Param dx offset added to fLeft and subtracted from fRight ##
+#Param dy offset added to fTop and subtracted from fBottom ##
+
+#Example
SkIRect rect = { 10, 14, 50, 73 };
rect.inset(5, 13);
SkDebugf("rect: %d, %d, %d, %d\n", rect.fLeft, rect.fTop, rect.fRight, rect.fBottom);
#StdOut
rect: 15, 27, 45, 60
##
-##
-
-#SeeAlso outset makeInset SkRect::inset
-
-##
-
-# ------------------------------------------------------------------------------
-
-#Method void outset(int32_t dx, int32_t dy)
-
-Outsets IRect by (dx, dy).
-
-If dx is positive, makes Rect wider.
-If dx is negative, makes Rect narrower.
-If dy is positive, makes Rect taller.
-If dy is negative, makes Rect shorter.
-
-#Param dx subtracted to fLeft and added from fRight ##
-#Param dy subtracted to fTop and added from fBottom ##
-
-#Example
+##
+
+#SeeAlso outset makeInset SkRect::inset
+
+##
+
+# ------------------------------------------------------------------------------
+
+#Method void outset(int32_t dx, int32_t dy)
+
+Outsets IRect by (dx, dy).
+
+If dx is positive, makes Rect wider.
+If dx is negative, makes Rect narrower.
+If dy is positive, makes Rect taller.
+If dy is negative, makes Rect shorter.
+
+#Param dx subtracted to fLeft and added from fRight ##
+#Param dy subtracted to fTop and added from fBottom ##
+
+#Example
SkIRect rect = { 10, 14, 50, 73 };
rect.outset(5, 13);
SkDebugf("rect: %d, %d, %d, %d\n", rect.fLeft, rect.fTop, rect.fRight, rect.fBottom);
#StdOut
rect: 5, 1, 55, 86
##
-##
-
-#SeeAlso inset makeOutset SkRect::outset
-
-##
-
-# ------------------------------------------------------------------------------
-
-#Method bool quickReject(int l, int t, int r, int b) const
-
-Constructs IRect (l, t, r, b) and returns true if constructed IRect does not
-intersect IRect. Does not check to see if construction or IRect is empty.
-
-Is implemented with short circuit logic so that true can be returned after
-a single compare.
-
-#Param l x minimum of constructed Rect ##
-#Param t y minimum of constructed Rect ##
-#Param r x maximum of constructed Rect ##
-#Param b y maximum of constructed Rect ##
-
-#Return true if construction and IRect have no area in common ##
-
-#Example
-#Description
-quickReject is the complement of Intersects.
-##
+##
+
+#SeeAlso inset makeOutset SkRect::outset
+
+##
+
+# ------------------------------------------------------------------------------
+
+#Method bool quickReject(int l, int t, int r, int b) const
+
+Constructs IRect (l, t, r, b) and returns true if constructed IRect does not
+intersect IRect. Does not check to see if construction or IRect is empty.
+
+Is implemented with short circuit logic so that true can be returned after
+a single compare.
+
+#Param l x minimum of constructed Rect ##
+#Param t y minimum of constructed Rect ##
+#Param r x maximum of constructed Rect ##
+#Param b y maximum of constructed Rect ##
+
+#Return true if construction and IRect have no area in common ##
+
+#Example
+#Description
+quickReject is the complement of Intersects.
+##
const SkIRect rect = {7, 11, 13, 17};
const int32_t* r = &rect.fLeft;
const SkIRect tests[] = { {13, 11, 15, 17}, { 7, 7, 13, 11 }, { 12, 16, 14, 18 } };
@@ -1129,32 +1129,36 @@ rect (7, 11, 13, 17) test(13, 11, 15, 17) quickReject true; intersects false
rect (7, 11, 13, 17) test(7, 7, 13, 11) quickReject true; intersects false
rect (7, 11, 13, 17) test(12, 16, 14, 18) quickReject false; intersects true
##
-##
-
-#SeeAlso Intersects
-
-##
-
-# ------------------------------------------------------------------------------
-
-#Method bool contains(int32_t x, int32_t y) const
-
-Returns true if
-#Formula
-fLeft <= x < fRight && fTop <= y < fBottom
-##
-.
-Returns false if Rect is empty.
-
-Considers input to describe constructed IRect (x, y, x + 1, y + 1) and
-returns true if constructed area is completely enclosed by IRect area.
-
-#Param x test Point x-coordinate ##
-#Param y test Point y-coordinate ##
-
-#Return true if (x, y) is inside IRect ##
-
-#Example
+##
+
+#SeeAlso Intersects
+
+##
+
+# ------------------------------------------------------------------------------
+
+#Method bool contains(int32_t x, int32_t y) const
+
+Returns true if:
+#Formula
+fLeft <= x < fRight && fTop <= y < fBottom
+##
+.
+Returns false if Rect is empty.
+
+Considers input to describe constructed IRect:
+#Formula
+(x, y, x + 1, y + 1)
+##
+and
+returns true if constructed area is completely enclosed by IRect area.
+
+#Param x test Point x-coordinate ##
+#Param y test Point y-coordinate ##
+
+#Return true if (x, y) is inside IRect ##
+
+#Example
SkIRect rect = { 30, 50, 40, 60 };
SkIPoint pts[] = { { 30, 50}, { 40, 50}, { 30, 60} };
for (auto pt : pts) {
@@ -1167,30 +1171,30 @@ rect: (30, 50, 40, 60) contains (30, 50)
rect: (30, 50, 40, 60) does not contain (40, 50)
rect: (30, 50, 40, 60) does not contain (30, 60)
##
-##
-
-#SeeAlso containsNoEmptyCheck SkRect::contains
-
-##
-
-# ------------------------------------------------------------------------------
-
-#Method bool contains(int32_t left, int32_t top, int32_t right, int32_t bottom) const
-
-Constructs Rect to intersect from (left, top, right, bottom). Does not sort
-construction.
-
-Returns true if Rect contains construction.
-Returns false if Rect is empty or construction is empty.
-
-#Param left x minimum of constructed Rect ##
-#Param top y minimum of constructed Rect ##
-#Param right x maximum of constructed Rect ##
-#Param bottom y maximum of constructed Rect ##
-
-#Return true if all sides of IRect are outside construction ##
-
-#Example
+##
+
+#SeeAlso containsNoEmptyCheck SkRect::contains
+
+##
+
+# ------------------------------------------------------------------------------
+
+#Method bool contains(int32_t left, int32_t top, int32_t right, int32_t bottom) const
+
+Constructs Rect to intersect from (left, top, right, bottom). Does not sort
+construction.
+
+Returns true if Rect contains construction.
+Returns false if Rect is empty or construction is empty.
+
+#Param left x minimum of constructed Rect ##
+#Param top y minimum of constructed Rect ##
+#Param right x maximum of constructed Rect ##
+#Param bottom y maximum of constructed Rect ##
+
+#Return true if all sides of IRect are outside construction ##
+
+#Example
SkIRect rect = { 30, 50, 40, 60 };
SkIRect tests[] = { { 30, 50, 31, 51}, { 39, 49, 40, 50}, { 29, 59, 30, 60} };
for (auto contained : tests) {
@@ -1206,26 +1210,26 @@ rect: (30, 50, 40, 60) contains (30, 50, 31, 51)
rect: (30, 50, 40, 60) does not contain (39, 49, 40, 50)
rect: (30, 50, 40, 60) does not contain (29, 59, 30, 60)
##
-##
-
-#SeeAlso containsNoEmptyCheck SkRect::contains
-
-##
-
-# ------------------------------------------------------------------------------
-
-#Method bool contains(const SkIRect& r) const
-
-Returns true if Rect contains r.
-Returns false if Rect is empty or r is empty.
-
-Rect contains r when Rect area completely includes r area.
-
-#Param r IRect contained ##
-
-#Return true if all sides of IRect are outside r ##
-
-#Example
+##
+
+#SeeAlso containsNoEmptyCheck SkRect::contains
+
+##
+
+# ------------------------------------------------------------------------------
+
+#Method bool contains(const SkIRect& r) const
+
+Returns true if Rect contains r.
+Returns false if Rect is empty or r is empty.
+
+Rect contains r when Rect area completely includes r area.
+
+#Param r IRect contained ##
+
+#Return true if all sides of IRect are outside r ##
+
+#Example
SkIRect rect = { 30, 50, 40, 60 };
SkIRect tests[] = { { 30, 50, 31, 51}, { 39, 49, 40, 50}, { 29, 59, 30, 60} };
for (auto contained : tests) {
@@ -1239,26 +1243,26 @@ rect: (30, 50, 40, 60) contains (30, 50, 31, 51)
rect: (30, 50, 40, 60) does not contain (39, 49, 40, 50)
rect: (30, 50, 40, 60) does not contain (29, 59, 30, 60)
##
-##
-
-#SeeAlso containsNoEmptyCheck SkRect::contains
-
-##
-
-# ------------------------------------------------------------------------------
-
-#Method bool contains(const SkRect& r) const
-
-Returns true if Rect contains r.
-Returns false if Rect is empty or r is empty.
-
-Rect contains r when Rect area completely includes r area.
-
-#Param r Rect contained ##
-
-#Return true if all sides of IRect are outside r ##
-
-#Example
+##
+
+#SeeAlso containsNoEmptyCheck SkRect::contains
+
+##
+
+# ------------------------------------------------------------------------------
+
+#Method bool contains(const SkRect& r) const
+
+Returns true if Rect contains r.
+Returns false if Rect is empty or r is empty.
+
+Rect contains r when Rect area completely includes r area.
+
+#Param r Rect contained ##
+
+#Return true if all sides of IRect are outside r ##
+
+#Example
SkIRect rect = { 30, 50, 40, 60 };
SkRect tests[] = { { 30, 50, 31, 51}, { 39, 49, 40, 50}, { 29, 59, 30, 60} };
for (auto contained : tests) {
@@ -1272,33 +1276,33 @@ rect: (30, 50, 40, 60) contains (30, 50, 31, 51)
rect: (30, 50, 40, 60) does not contain (39, 49, 40, 50)
rect: (30, 50, 40, 60) does not contain (29, 59, 30, 60)
##
-##
-
-#SeeAlso containsNoEmptyCheck SkRect::contains
-
-##
-
-# ------------------------------------------------------------------------------
-
-#Method bool containsNoEmptyCheck(int32_t left, int32_t top,
- int32_t right, int32_t bottom) const
-
-Constructs IRect from (left, top, right, bottom). Does not sort
-construction.
-
-Returns true if Rect contains construction.
-Asserts if IRect is empty or construction is empty, and if SK_DEBUG is defined.
-
-Return is undefined if Rect is empty or construction is empty.
-
-#Param left x minimum of constructed Rect ##
-#Param top y minimum of constructed Rect ##
-#Param right x maximum of constructed Rect ##
-#Param bottom y maximum of constructed Rect ##
-
-#Return true if all sides of IRect are outside construction ##
-
-#Example
+##
+
+#SeeAlso containsNoEmptyCheck SkRect::contains
+
+##
+
+# ------------------------------------------------------------------------------
+
+#Method bool containsNoEmptyCheck(int32_t left, int32_t top,
+ int32_t right, int32_t bottom) const
+
+Constructs IRect from (left, top, right, bottom). Does not sort
+construction.
+
+Returns true if Rect contains construction.
+Asserts if IRect is empty or construction is empty, and if SK_DEBUG is defined.
+
+Return is undefined if Rect is empty or construction is empty.
+
+#Param left x minimum of constructed Rect ##
+#Param top y minimum of constructed Rect ##
+#Param right x maximum of constructed Rect ##
+#Param bottom y maximum of constructed Rect ##
+
+#Return true if all sides of IRect are outside construction ##
+
+#Example
SkIRect rect = { 30, 50, 40, 60 };
SkIRect tests[] = { { 30, 50, 31, 51}, { 39, 49, 40, 50}, { 29, 59, 30, 60} };
for (auto contained : tests) {
@@ -1314,26 +1318,26 @@ rect: (30, 50, 40, 60) contains (30, 50, 31, 51)
rect: (30, 50, 40, 60) does not contain (39, 49, 40, 50)
rect: (30, 50, 40, 60) does not contain (29, 59, 30, 60)
##
-##
-
-#SeeAlso contains SkRect::contains
-
-##
-
-# ------------------------------------------------------------------------------
-
-#Method bool containsNoEmptyCheck(const SkIRect& r) const
-
-Returns true if Rect contains construction.
-Asserts if IRect is empty or construction is empty, and if SK_DEBUG is defined.
-
-Return is undefined if Rect is empty or construction is empty.
-
-#Param r Rect contained ##
-
-#Return true if all sides of IRect are outside r ##
-
-#Example
+##
+
+#SeeAlso contains SkRect::contains
+
+##
+
+# ------------------------------------------------------------------------------
+
+#Method bool containsNoEmptyCheck(const SkIRect& r) const
+
+Returns true if Rect contains construction.
+Asserts if IRect is empty or construction is empty, and if SK_DEBUG is defined.
+
+Return is undefined if Rect is empty or construction is empty.
+
+#Param r Rect contained ##
+
+#Return true if all sides of IRect are outside r ##
+
+#Example
SkIRect rect = { 30, 50, 40, 60 };
SkIRect tests[] = { { 30, 50, 31, 51}, { 39, 49, 40, 50}, { 29, 59, 30, 60} };
for (auto contained : tests) {
@@ -1347,321 +1351,321 @@ rect: (30, 50, 40, 60) contains (30, 50, 31, 51)
rect: (30, 50, 40, 60) does not contain (39, 49, 40, 50)
rect: (30, 50, 40, 60) does not contain (29, 59, 30, 60)
##
-##
-
-#SeeAlso contains SkRect::contains
-
-##
-
-#Topic Intersection
-
-IRects intersect when they enclose a common area. To intersect, each of the pair
-must describe area; fLeft is less than fRight, and fTop is less than fBottom;
-empty() returns false. The intersection of IRect a and IRect b can be described by:
-#Formula
-(max(a.fLeft, b.fLeft), max(a.fTop, b.fTop),
- min(a.fRight, b.fRight), min(a.fBottom, b.fBottom))
-##
-The intersection is only meaningful if the resulting IRect is not empty and
-describes an area: fLeft is less than fRight, and fTop is less than fBottom.
-
-# ------------------------------------------------------------------------------
-
-#Method bool intersect(const SkIRect& r)
-
-Returns true if IRect intersects r, and sets IRect to intersection.
-Returns false if IRect does not intersect r, and leaves IRect unchanged.
-
-Returns false if either r or IRect is empty, leaving IRect unchanged.
-
-#Param r limit of result ##
-
-#Return true if r and Rect have area in common ##
-
-#Example
-#Description
-Two SkDebugf calls are required. If the calls are combined, their arguments
-may not be evaluated in left to right order: the printed intersection may
-be before or after the call to intersect.
-##
+##
+
+#SeeAlso contains SkRect::contains
+
+##
+
+#Topic Intersection
+
+IRects intersect when they enclose a common area. To intersect, each of the pair
+must describe area; fLeft is less than fRight, and fTop is less than fBottom;
+empty() returns false. The intersection of IRect pair can be described by:
+#Formula
+(max(a.fLeft, b.fLeft), max(a.fTop, b.fTop),
+ min(a.fRight, b.fRight), min(a.fBottom, b.fBottom))
+##
+The intersection is only meaningful if the resulting IRect is not empty and
+describes an area: fLeft is less than fRight, and fTop is less than fBottom.
+
+# ------------------------------------------------------------------------------
+
+#Method bool intersect(const SkIRect& r)
+
+Returns true if IRect intersects r, and sets IRect to intersection.
+Returns false if IRect does not intersect r, and leaves IRect unchanged.
+
+Returns false if either r or IRect is empty, leaving IRect unchanged.
+
+#Param r limit of result ##
+
+#Return true if r and Rect have area in common ##
+
+#Example
+#Description
+Two SkDebugf calls are required. If the calls are combined, their arguments
+may not be evaluated in left to right order: the printed intersection may
+be before or after the call to intersect.
+##
SkIRect leftRect = { 10, 40, 50, 80 };
SkIRect rightRect = { 30, 60, 70, 90 };
SkDebugf("%s intersection: ", leftRect.intersect(rightRect) ? "" : "no ");
SkDebugf("%d, %d, %d, %d\n", leftRect.left(), leftRect.top(),
- leftRect.right(), leftRect.bottom());
-#StdOut
- intersection: 30, 60, 50, 80
-##
-##
-
-#SeeAlso Intersects intersectNoEmptyCheck join SkRect::intersect
-
-##
-
-# ------------------------------------------------------------------------------
-
-#Method bool SK_WARN_UNUSED_RESULT intersect(const SkIRect& a, const SkIRect& b)
-
-Returns true if a intersects b, and sets IRect to intersection.
-Returns false if a does not intersect b, and leaves IRect unchanged.
-
-Returns false if either a or b is empty, leaving IRect unchanged.
-
-#Param a IRect to intersect ##
-#Param b IRect to intersect ##
-
-#Return true if a and b have area in common ##
-
-#Example
+ leftRect.right(), leftRect.bottom());
+#StdOut
+ intersection: 30, 60, 50, 80
+##
+##
+
+#SeeAlso Intersects intersectNoEmptyCheck join SkRect::intersect
+
+##
+
+# ------------------------------------------------------------------------------
+
+#Method bool SK_WARN_UNUSED_RESULT intersect(const SkIRect& a, const SkIRect& b)
+
+Returns true if a intersects b, and sets IRect to intersection.
+Returns false if a does not intersect b, and leaves IRect unchanged.
+
+Returns false if either a or b is empty, leaving IRect unchanged.
+
+#Param a IRect to intersect ##
+#Param b IRect to intersect ##
+
+#Return true if a and b have area in common ##
+
+#Example
SkIRect result;
bool intersected = result.intersect({ 10, 40, 50, 80 }, { 30, 60, 70, 90 });
SkDebugf("%s intersection: %d, %d, %d, %d\n", intersected ? "" : "no ",
result.left(), result.top(), result.right(), result.bottom());
-#StdOut
- intersection: 30, 60, 50, 80
-##
-##
-
-#SeeAlso Intersects intersectNoEmptyCheck join SkRect::intersect
-
-##
-
-# ------------------------------------------------------------------------------
-
-#Method bool SK_WARN_UNUSED_RESULT intersectNoEmptyCheck(const SkIRect& a, const SkIRect& b)
-
-Returns true if a intersects b, and sets IRect to intersection.
-Returns false if a does not intersect b, and leaves IRect unchanged.
-
-Asserts if either a or b is empty, and if SK_DEBUG is defined.
-
-#Param a IRect to intersect ##
-#Param b IRect to intersect ##
-
-#Return true if a and b have area in common ##
-
-#Example
+#StdOut
+ intersection: 30, 60, 50, 80
+##
+##
+
+#SeeAlso Intersects intersectNoEmptyCheck join SkRect::intersect
+
+##
+
+# ------------------------------------------------------------------------------
+
+#Method bool SK_WARN_UNUSED_RESULT intersectNoEmptyCheck(const SkIRect& a, const SkIRect& b)
+
+Returns true if a intersects b, and sets IRect to intersection.
+Returns false if a does not intersect b, and leaves IRect unchanged.
+
+Asserts if either a or b is empty, and if SK_DEBUG is defined.
+
+#Param a IRect to intersect ##
+#Param b IRect to intersect ##
+
+#Return true if a and b have area in common ##
+
+#Example
SkIRect result;
bool intersected = result.intersectNoEmptyCheck({ 10, 40, 50, 80 }, { 30, 60, 70, 90 });
SkDebugf("intersection: %d, %d, %d, %d\n",
result.left(), result.top(), result.right(), result.bottom());
-#StdOut
- intersection: 30, 60, 50, 80
-##
-##
-
-#SeeAlso Intersects intersect join SkRect::intersect
-
-##
-
-# ------------------------------------------------------------------------------
-
-#Method bool intersect(int32_t left, int32_t top, int32_t right, int32_t bottom)
-
-Constructs IRect to intersect from (left, top, right, bottom). Does not sort
-construction.
-
-Returns true if IRect intersects construction, and sets IRect to intersection.
-Returns false if IRect does not intersect construction, and leaves IRect unchanged.
-
-Returns false if either construction or IRect is empty, leaving IRect unchanged.
-
-#Param left x minimum of constructed IRect ##
-#Param top y minimum of constructed IRect ##
-#Param right x maximum of constructed IRect ##
-#Param bottom y maximum of constructed IRect ##
-
-#Return true if construction and IRect have area in common ##
-
-#Example
-#Description
-Two SkDebugf calls are required. If the calls are combined, their arguments
-may not be evaluated in left to right order: the printed intersection may
-be before or after the call to intersect.
-##
+#StdOut
+ intersection: 30, 60, 50, 80
+##
+##
+
+#SeeAlso Intersects intersect join SkRect::intersect
+
+##
+
+# ------------------------------------------------------------------------------
+
+#Method bool intersect(int32_t left, int32_t top, int32_t right, int32_t bottom)
+
+Constructs IRect to intersect from (left, top, right, bottom). Does not sort
+construction.
+
+Returns true if IRect intersects construction, and sets IRect to intersection.
+Returns false if IRect does not intersect construction, and leaves IRect unchanged.
+
+Returns false if either construction or IRect is empty, leaving IRect unchanged.
+
+#Param left x minimum of constructed IRect ##
+#Param top y minimum of constructed IRect ##
+#Param right x maximum of constructed IRect ##
+#Param bottom y maximum of constructed IRect ##
+
+#Return true if construction and IRect have area in common ##
+
+#Example
+#Description
+Two SkDebugf calls are required. If the calls are combined, their arguments
+may not be evaluated in left to right order: the printed intersection may
+be before or after the call to intersect.
+##
SkIRect leftRect = { 10, 40, 50, 80 };
SkDebugf("%s intersection: ", leftRect.intersect(30, 60, 70, 90) ? "" : "no ");
SkDebugf("%d, %d, %d, %d\n", leftRect.left(), leftRect.top(),
- leftRect.right(), leftRect.bottom());
-#StdOut
- intersection: 30, 60, 50, 80
-##
-##
-
-#SeeAlso intersectNoEmptyCheck Intersects join SkRect::intersect
-
-##
-
-# ------------------------------------------------------------------------------
-
-#Method static bool Intersects(const SkIRect& a, const SkIRect& b)
-
-Returns true if a intersects b.
-Returns false if either a or b is empty, or do not intersect.
-
-#Param a IRect to intersect ##
-#Param b IRect to intersect ##
-
-#Return true if a and b have area in common ##
-
-#Example
+ leftRect.right(), leftRect.bottom());
+#StdOut
+ intersection: 30, 60, 50, 80
+##
+##
+
+#SeeAlso intersectNoEmptyCheck Intersects join SkRect::intersect
+
+##
+
+# ------------------------------------------------------------------------------
+
+#Method static bool Intersects(const SkIRect& a, const SkIRect& b)
+
+Returns true if a intersects b.
+Returns false if either a or b is empty, or do not intersect.
+
+#Param a IRect to intersect ##
+#Param b IRect to intersect ##
+
+#Return true if a and b have area in common ##
+
+#Example
SkDebugf("%s intersection", SkIRect::Intersects({10, 40, 50, 80}, {30, 60, 70, 90}) ? "" : "no ");
-#StdOut
- intersection
-##
-##
-
-#SeeAlso IntersectsNoEmptyCheck intersect SkRect::intersect
-
-##
-
-# ------------------------------------------------------------------------------
-
-#Method static bool IntersectsNoEmptyCheck(const SkIRect& a, const SkIRect& b)
-
-Returns true if a intersects b.
-Asserts if either a or b is empty, and if SK_DEBUG is defined.
-
-#Param a IRect to intersect ##
-#Param b IRect to intersect ##
-
-#Return true if a and b have area in common ##
-
-#Example
+#StdOut
+ intersection
+##
+##
+
+#SeeAlso IntersectsNoEmptyCheck intersect SkRect::intersect
+
+##
+
+# ------------------------------------------------------------------------------
+
+#Method static bool IntersectsNoEmptyCheck(const SkIRect& a, const SkIRect& b)
+
+Returns true if a intersects b.
+Asserts if either a or b is empty, and if SK_DEBUG is defined.
+
+#Param a IRect to intersect ##
+#Param b IRect to intersect ##
+
+#Return true if a and b have area in common ##
+
+#Example
SkDebugf("%s intersection", SkIRect::IntersectsNoEmptyCheck(
{10, 40, 50, 80}, {30, 60, 70, 90}) ? "" : "no ");
-#StdOut
- intersection
-##
-##
-
-#SeeAlso Intersects intersect SkRect::intersect
-
-##
-
-#Topic Intersection ##
-
-# ------------------------------------------------------------------------------
-
-#Method void join(int32_t left, int32_t top, int32_t right, int32_t bottom)
-
-Constructs Rect to intersect from (left, top, right, bottom). Does not sort
-construction.
-
-Sets Rect to the union of itself and the construction.
-
-Has no effect if construction is empty. Otherwise, if Rect is empty, sets
-Rect to construction.
-
-#Param left x minimum of constructed Rect ##
-#Param top y minimum of constructed Rect ##
-#Param right x maximum of constructed Rect ##
-#Param bottom y maximum of constructed Rect ##
-
-#Example
+#StdOut
+ intersection
+##
+##
+
+#SeeAlso Intersects intersect SkRect::intersect
+
+##
+
+#Topic Intersection ##
+
+# ------------------------------------------------------------------------------
+
+#Method void join(int32_t left, int32_t top, int32_t right, int32_t bottom)
+
+Constructs Rect to intersect from (left, top, right, bottom). Does not sort
+construction.
+
+Sets Rect to the union of itself and the construction.
+
+Has no effect if construction is empty. Otherwise, if Rect is empty, sets
+Rect to construction.
+
+#Param left x minimum of constructed Rect ##
+#Param top y minimum of constructed Rect ##
+#Param right x maximum of constructed Rect ##
+#Param bottom y maximum of constructed Rect ##
+
+#Example
SkIRect rect = { 10, 20, 15, 25};
rect.join(50, 60, 55, 65);
SkDebugf("join: %d, %d, %d, %d\n", rect.fLeft, rect.fTop, rect.fRight, rect.fBottom);
-#StdOut
- join: 10, 20, 55, 65
-##
-##
-
-#SeeAlso set SkRect::join
-
-##
-
-# ------------------------------------------------------------------------------
-
-#Method void join(const SkIRect& r)
-
-Sets Rect to the union of itself and r.
-
-Has no effect if r is empty. Otherwise, if Rect is empty, sets Rect to r.
-
-#Param r expansion Rect ##
-
-#Example
+#StdOut
+ join: 10, 20, 55, 65
+##
+##
+
+#SeeAlso set SkRect::join
+
+##
+
+# ------------------------------------------------------------------------------
+
+#Method void join(const SkIRect& r)
+
+Sets Rect to the union of itself and r.
+
+Has no effect if r is empty. Otherwise, if Rect is empty, sets Rect to r.
+
+#Param r expansion Rect ##
+
+#Example
SkIRect rect = { 10, 20, 15, 25};
rect.join({50, 60, 55, 65});
SkDebugf("join: %d, %d, %d, %d\n", rect.fLeft, rect.fTop, rect.fRight, rect.fBottom);
-#StdOut
- join: 10, 20, 55, 65
-##
-##
-
-#SeeAlso set SkRect::join
-
-##
-
-# ------------------------------------------------------------------------------
-
-#Method void sort()
-
-Swaps fLeft and fRight if fLeft is greater than fRight; and swaps
-fTop and fBottom if fTop is greater than fBottom. Result may be empty,
-and width() and height() will be zero or positive.
-
-#Example
+#StdOut
+ join: 10, 20, 55, 65
+##
+##
+
+#SeeAlso set SkRect::join
+
+##
+
+# ------------------------------------------------------------------------------
+
+#Method void sort()
+
+Swaps fLeft and fRight if fLeft is greater than fRight; and swaps
+fTop and fBottom if fTop is greater than fBottom. Result may be empty,
+and width() and height() will be zero or positive.
+
+#Example
SkIRect rect = { 30, 50, 20, 10 };
SkDebugf("rect: %d, %d, %d, %d\n", rect.fLeft, rect.fTop, rect.fRight, rect.fBottom);
rect.sort();
SkDebugf("sorted: %d, %d, %d, %d\n", rect.fLeft, rect.fTop, rect.fRight, rect.fBottom);
-#StdOut
+#StdOut
rect: 30, 50, 20, 10
-sorted: 20, 10, 30, 50
-##
-##
-
-#SeeAlso makeSorted SkRect::sort
-
-##
-
-# ------------------------------------------------------------------------------
-
-#Method SkIRect makeSorted() const
-
-Returns Rect with fLeft and fRight swapped if fLeft is greater than fRight; and
-with fTop and fBottom swapped if fTop is greater than fBottom. Result may be empty;
-and width() and height() will be zero or positive.
-
-#Return sorted IRect ##
-
-#Example
+sorted: 20, 10, 30, 50
+##
+##
+
+#SeeAlso makeSorted SkRect::sort
+
+##
+
+# ------------------------------------------------------------------------------
+
+#Method SkIRect makeSorted() const
+
+Returns Rect with fLeft and fRight swapped if fLeft is greater than fRight; and
+with fTop and fBottom swapped if fTop is greater than fBottom. Result may be empty;
+and width() and height() will be zero or positive.
+
+#Return sorted IRect ##
+
+#Example
SkIRect rect = { 30, 50, 20, 10 };
SkDebugf("rect: %d, %d, %d, %d\n", rect.fLeft, rect.fTop, rect.fRight, rect.fBottom);
SkIRect sort = rect.makeSorted();
SkDebugf("sorted: %d, %d, %d, %d\n", sort.fLeft, sort.fTop, sort.fRight, sort.fBottom);
-#StdOut
+#StdOut
rect: 30, 50, 20, 10
-sorted: 20, 10, 30, 50
-##
-##
-
-#SeeAlso sort SkRect::makeSorted
-
-##
-
-# ------------------------------------------------------------------------------
-
-#Method static const SkIRect& SK_WARN_UNUSED_RESULT EmptyIRect()
-
-Returns a reference to immutable empty IRect, set to (0, 0, 0, 0).
-
-#Return global IRect set to all zeroes ##
-
-#Example
+sorted: 20, 10, 30, 50
+##
+##
+
+#SeeAlso sort SkRect::makeSorted
+
+##
+
+# ------------------------------------------------------------------------------
+
+#Method static const SkIRect& SK_WARN_UNUSED_RESULT EmptyIRect()
+
+Returns a reference to immutable empty IRect, set to (0, 0, 0, 0).
+
+#Return global IRect set to all zeroes ##
+
+#Example
const SkIRect& rect = SkIRect::EmptyIRect();
SkDebugf("rect: %d, %d, %d, %d\n", rect.fLeft, rect.fTop, rect.fRight, rect.fBottom);
-#StdOut
-rect: 0, 0, 0, 0
-##
-##
-
-#SeeAlso MakeEmpty
-
-##
-
-#Struct SkIRect ##
-
-#Topic IRect ##
+#StdOut
+rect: 0, 0, 0, 0
+##
+##
+
+#SeeAlso MakeEmpty
+
+##
+
+#Struct SkIRect ##
+
+#Topic IRect ##
diff --git a/docs/SkMatrix_Reference.bmh b/docs/SkMatrix_Reference.bmh
index 0db0fa881e..f91e0096b4 100644
--- a/docs/SkMatrix_Reference.bmh
+++ b/docs/SkMatrix_Reference.bmh
@@ -1,16 +1,20 @@
#Topic Matrix
+#Alias Matrices
#Alias Matrix_Reference
#Class SkMatrix
-Matrix holds a 3x3 matrix for transforming coordinates.
-Matrix elements are in column major order.
+Matrix holds a 3x3 matrix for transforming coordinates. This allows mapping
+Points and Vectors with translation, scaling, skewing, rotation, and
+perspective.
-SkMatrix does not have a constructor, so it must be explicitly initialized
-using either reset() - to construct an identity matrix, or one of the set
-functions (e.g. setTranslate, setRotate, etc.).
+Matrix elements are in row major order. Matrix does not have a constructor,
+so it must be explicitly initialized. setIdentity initializes Matrix
+so it has no effect. setTranslate, setScale, setSkew, setRotate, set9 and setAll
+initializes all Matrix elements with the corresponding mapping.
-SkMatrix is not thread safe unless getType is called first.
+Matrix includes a hidden variable that classifies the type of matrix to
+improve performance. Matrix is not thread safe unless getType is called first.
#Topic Overview
@@ -26,111 +30,104 @@ SkMatrix is not thread safe unless getType is called first.
#Subtopic Operators
#Table
#Legend
-# description # function ##
+# function # description ##
#Legend ##
-# friend SK_API bool operator!=(const SkMatrix& a, const SkMatrix& b) # Returns true if members are unequal. ##
-# friend SK_API bool operator==(const SkMatrix& a, const SkMatrix& b) # Returns true if members are equal. ##
-# SkScalar operator[](int index) const # Returns one of nine Matrix values. ##
-# SkScalar& operator[](int index) # Returns a writable reference to one of nine Matrix values. ##
+# operator!=(const SkMatrix& a, const SkMatrix& b) # Returns true if members are unequal. ##
+# operator==(const SkMatrix& a, const SkMatrix& b) # Returns true if members are equal. ##
+# operator[](int index) const # Returns Matrix value. ##
+# operator[](int index) # Returns writable reference to Matrix value. ##
#Table ##
#Subtopic ##
#Subtopic Member_Functions
#Table
#Legend
-# description # function ##
+# function # description ##
#Legend ##
# Concat # Returns the concatenation of Matrix pair. ##
-# GetMapPtsProc # Returns optimal function to map Point array. ##
-# GetMapXYProc # Returns optimal function to map one Point. ##
# I # Returns a reference to a const identity Matrix. ##
# InvalidMatrix # Returns a reference to a const invalid Matrix. ##
# MakeRectToRect # Constructs from source Rect to destination Rect. ##
# MakeScale # Constructs from scale in x and y. ##
# MakeTrans # Constructs from translate in x and y. ##
-# SetAffineIdentity # Sets 2x3 array to identity. ##
-# asAffine # Copies to 2x3 array. ##
+# SetAffineIdentity # Sets 3x2 array to identity. ##
+# asAffine # Copies to 3x2 array. ##
# cheapEqualTo # Compares Matrix pair using memcmp(). ##
# decomposeScale # Separates scale if possible. ##
-# dirtyMatrixTypeCache # Private; used by testing. ##
-# dump # Sends text representation using floats to standard output. ##
+# dirtyMatrixTypeCache # Sets internal cache to unknown state. ##
+# dump() # Sends text representation using floats to standard output. ##
# fixedStepInX # Returns step in x for a position in y. ##
-# get # Returns one of nine Matrix values. ##
+# get() # Returns one of nine Matrix values. ##
# get9 # Returns all nine Matrix values. ##
-# getMapPtsProc # Returns optimal function to map Point array. ##
-# getMapXYProc # Returns optimal function to map one Point. ##
# getMaxScale # Returns maximum scaling, if possible. ##
# getMinMaxScales # Returns minimum and maximum scaling, if possible. ##
# getMinScale # Returns minimum scaling, if possible. ##
-# getPerspX # Returns horizontal perspective factor. ##
-# getPerspY # Returns vertical perspective factor. ##
+# getPerspX # Returns input x perspective factor. ##
+# getPerspY # Returns input y perspective factor. ##
# getScaleX # Returns horizontal scale factor. ##
-# getScaleY # Returns vertical scale factor.##
+# getScaleY # Returns vertical scale factor. ##
# getSkewX # Returns horizontal skew factor. ##
# getSkewY # Returns vertical skew factor. ##
-# getTranslateX # Returns horizontal translation factor. ##
-# getTranslateY # Returns vertical translation factor. ##
+# getTranslateX # Returns horizontal translation. ##
+# getTranslateY # Returns vertical translation. ##
# getType # Returns transform complexity. ##
# hasPerspective # Returns if transform includes perspective. ##
-# invert # Returns inverse, if possible. ##
+# invert() # Returns inverse, if possible. ##
# isFinite # Returns if all Matrix values are not infinity, NaN. ##
# isFixedStepInX # Returns if transformation supports fixed step in x. ##
# isIdentity # Returns if matrix equals the identity Matrix .##
# isScaleTranslate # Returns if transform is limited to scale and translate. ##
# isSimilarity # Returns if transform is limited to square scale and rotation. ##
# isTranslate # Returns if transform is limited to translate. ##
-# mapHomogeneousPoints # ##
-# mapPoints # ##
-# mapPointsWithStride # ##
-# mapRadius # ##
-# mapRect # ##
-# mapRectScaleTranslate # ##
-# mapRectToQuad # ##
-# mapVector # ##
-# mapVectors # ##
-# mapXY # ##
-# postConcat # ##
-# postIDiv # ##
-# postRotate # ##
-# postScale # ##
-# postSkew # ##
-# postTranslate # ##
-# preConcat # ##
-# preRotate # ##
-# preScale # ##
-# preSkew # ##
-# preTranslate # ##
-# preservesAxisAlignment # ##
-# preservesRightAngles # ##
-# readFromMemory # ##
-# rectStaysRect # ##
-# reset # ##
-# set # ##
-# set9 # ##
-# setAffine # ##
-# setAll # ##
-# setConcat # ##
-# setIDiv # ##
-# setIdentity # ##
-# setPerspX # ##
-# setPerspY # ##
-# setPolyToPoly # ##
-# setRSXform # ##
-# setRectToRect # ##
-# setRotate # ##
-# setScale # ##
-# setScaleTranslate # ##
-# setScaleX # ##
-# setScaleY # ##
-# setSinCos # ##
-# setSkew # ##
-# setSkewX # ##
-# setSkewY # ##
-# setTranslate # ##
-# setTranslateX # ##
-# setTranslateY # ##
-# toString # ##
-# writeToMemory # ##
+# mapHomogeneousPoints # Maps Point3 array. ##
+# mapPoints # Maps Point array. ##
+# mapPointsWithStride # Maps Point array with padding. ##
+# mapRadius # Returns mean radius of mapped Circle. ##
+# mapRect # Returns bounds of mapped Rect. ##
+# mapRectScaleTranslate # Returns bounds of mapped Rect. ##
+# mapRectToQuad # Maps Rect to Point array. ##
+# mapVector # Maps Vector. ##
+# mapVectors # Maps Vector array. ##
+# mapXY # Maps Point. ##
+# postConcat # Post-multiplies Matrix by Matrix parameter. ##
+# postIDiv # Post-multiplies Matrix by inverse scale. ##
+# postRotate # Post-multiplies Matrix by rotation. ##
+# postScale # Post-multiplies Matrix by scale. ##
+# postSkew # Post-multiplies Matrix by skew. ##
+# postTranslate # Post-multiplies Matrix by translation. ##
+# preConcat # Pre-multiplies Matrix by Matrix parameter.##
+# preRotate # Pre-multiplies Matrix by rotation. ##
+# preScale # Pre-multiplies Matrix by scale. ##
+# preSkew # Pre-multiplies Matrix by skew. ##
+# preTranslate # Pre-multiplies Matrix by translation. ##
+# preservesAxisAlignment # Returns if mapping restricts to 90 degree multiples and mirroring. ##
+# preservesRightAngles # Returns if mapped 90 angle remains 90 degrees. ##
+# rectStaysRect # Returns if mapped Rect can be represented by another Rect. ##
+# reset() # Sets Matrix to identity. ##
+# set() # Sets one value. ##
+# set9 # Sets all values from Scalar array. ##
+# setAffine # Sets left two columns. ##
+# setAll # Sets all values from parameters. ##
+# setConcat # Sets to Matrix parameter multiplied by Matrix parameter. ##
+# setIdentity # Sets Matrix to identity. ##
+# setPerspX # Sets input x perspective factor. ##
+# setPerspY # Sets input y perspective factor. ##
+# setPolyToPoly # Sets to map one to four points to an equal array of points. ##
+# setRSXform # Sets to rotate, scale, and translate. ##
+# setRectToRect # Sets to map one Rect to another. ##
+# setRotate # Sets to rotate about a point. ##
+# setScale # Sets to scale about a point. ##
+# setScaleTranslate # Sets to scale and translate. ##
+# setScaleX # Sets horizontal scale factor. ##
+# setScaleY # Sets vertical scale factor ##
+# setSinCos # Sets to rotate and scale about a point. ##
+# setSkew # Sets to skew about a point. ##
+# setSkewX # Sets horizontal skew factor. ##
+# setSkewY # Sets vertical skew factor. ##
+# setTranslate # Sets to translate in x and y. ##
+# setTranslateX # Sets horizontal translation. ##
+# setTranslateY # Sets vertical translation. ##
+# toString # Converts Matrix to machine readable form. ##
#Table ##
#Subtopic ##
@@ -140,16 +137,27 @@ SkMatrix is not thread safe unless getType is called first.
#Method static SkMatrix SK_WARN_UNUSED_RESULT MakeScale(SkScalar sx, SkScalar sy)
-#Param sx incomplete ##
-#Param sy incomplete ##
+Sets Matrix to scale by (sx, sy). Returned matrix is:
-#Return incomplete ##
+#Code
+#Literal
+| sx 0 0 |
+| 0 sy 0 |
+| 0 0 1 |
+##
+
+#Param sx horizontal scale factor ##
+#Param sy vertical scale factor ##
+
+#Return Matrix with scale ##
#Example
-// incomplete
+#Image 4
+canvas->concat(SkMatrix::MakeScale(4, 3));
+canvas->drawBitmap(source, 0, 0);
##
-#ToDo incomplete ##
+#SeeAlso setScale postScale preScale
##
@@ -157,15 +165,26 @@ SkMatrix is not thread safe unless getType is called first.
#Method static SkMatrix SK_WARN_UNUSED_RESULT MakeScale(SkScalar scale)
-#Param scale incomplete ##
+Sets Matrix to scale by (scale, scale). Returned matrix is:
+
+#Code
+#Literal
+| scale 0 0 |
+| 0 scale 0 |
+| 0 0 1 |
+##
+
+#Param scale horizontal and vertical scale factor ##
-#Return incomplete ##
+#Return Matrix with scale ##
#Example
-// incomplete
+#Image 4
+canvas->concat(SkMatrix::MakeScale(4));
+canvas->drawBitmap(source, 0, 0);
##
-#ToDo incomplete ##
+#SeeAlso setScale postScale preScale
##
@@ -173,16 +192,30 @@ SkMatrix is not thread safe unless getType is called first.
#Method static SkMatrix SK_WARN_UNUSED_RESULT MakeTrans(SkScalar dx, SkScalar dy)
-#Param dx incomplete ##
-#Param dy incomplete ##
+Sets Matrix to translate by (dx, dy). Returned matrix is:
-#Return incomplete ##
+#Code
+#Literal
+| 1 0 0 |
+| 0 1 0 |
+| dx dy 1 |
+##
+
+#Param dx horizontal translation ##
+#Param dy vertical translation ##
+
+#Return Matrix with translation ##
#Example
-// incomplete
+#Image 4
+SkMatrix matrix = SkMatrix::MakeTrans(64, 48);
+for (int i = 0; i < 4; ++i) {
+ canvas->drawBitmap(source, 0, 0);
+ canvas->concat(matrix);
+}
##
-#ToDo incomplete ##
+#SeeAlso setTranslate postTranslate preTranslate
##
@@ -200,29 +233,57 @@ SkMatrix is not thread safe unless getType is called first.
};
##
-Enum of bit fields for the mask return by getType().
-Use this to identify the complexity of the matrix.
+Enum of bit fields for mask returned by getType.
+Used to identify the complexity of Matrix, to optimize performance.
-#Const kIdentity_Mask = 0
+#Const kIdentity_Mask 0
+all bits clear if Matrix is identity
##
-#Const kTranslate_Mask = 0x01
-set if the matrix has translation
+#Const kTranslate_Mask 1
+set if Matrix has translation
##
-#Const kScale_Mask = 0x02
-set if the matrix has x or y scale
+#Const kScale_Mask 2
+set if Matrix has x or y scale
##
-#Const kAffine_Mask = 0x04
-set if the matrix skews or rotates
+#Const kAffine_Mask 4
+set if Matrix skews or rotates
##
-#Const kPerspective_Mask = 0x08
-set if the matrix is in perspective
+#Const kPerspective_Mask 8
+set if Matrix has perspective
##
#Example
-// incomplete
+ auto debugster = [](const char* prefix, const SkMatrix& matrix) -> void {
+ SkString typeMask;
+ typeMask += SkMatrix::kIdentity_Mask == matrix.getType() ? "kIdentity_Mask " : "";
+ typeMask += SkMatrix::kTranslate_Mask & matrix.getType() ? "kTranslate_Mask " : "";
+ typeMask += SkMatrix::kScale_Mask & matrix.getType() ? "kScale_Mask " : "";
+ typeMask += SkMatrix::kAffine_Mask & matrix.getType() ? "kAffine_Mask " : "";
+ typeMask += SkMatrix::kPerspective_Mask & matrix.getType() ? "kPerspective_Mask" : "";
+ SkDebugf("after %s: %s\n", prefix, typeMask.c_str());
+ };
+SkMatrix matrix;
+matrix.reset();
+debugster("reset", matrix);
+matrix.postTranslate(1, 0);
+debugster("postTranslate", matrix);
+matrix.postScale(2, 1);
+debugster("postScale", matrix);
+matrix.postRotate(45);
+debugster("postScale", matrix);
+SkPoint polys[][4] = {{{0, 0}, {0, 1}, {1, 1}, {1, 0}}, {{0, 0}, {0, 1}, {2, 1}, {1, 0}}};
+matrix.setPolyToPoly(polys[0], polys[1], 4);
+debugster("setPolyToPoly", matrix);
+#StdOut
+after reset: kIdentity_Mask
+after postTranslate: kTranslate_Mask
+after postScale: kTranslate_Mask kScale_Mask
+after postScale: kTranslate_Mask kScale_Mask kAffine_Mask
+after setPolyToPoly: kTranslate_Mask kScale_Mask kAffine_Mask kPerspective_Mask
+##
##
-#ToDo incomplete ##
+#SeeAlso getType
##
@@ -232,17 +293,26 @@ set if the matrix is in perspective
Returns a bit field describing the transformations the matrix may
perform. The bit field is computed conservatively, so it may include
-false positives. For example, when kPerspective_Mask is true, all
-other bits may be set to true even in the case of a pure perspective
-transform.
+false positives. For example, when kPerspective_Mask is set, all
+other bits are set.
-#Return incomplete ##
+#Return kIdentity_Mask, or combinations of: kTranslate_Mask, kScale_Mask,
+ kAffine_Mask, kPerspective_Mask
+##
#Example
-// incomplete
+SkMatrix matrix;
+matrix.setAll(1, 0, 0, 0, 1, 0, 0, 0, 1);
+SkDebugf("identity flags hex: %0x decimal: %d\n", matrix.getType(), matrix.getType());
+matrix.setAll(1, 0, 0, 0, 1, 0, 0, 0, .5f);
+SkDebugf("set all flags hex: %0x decimal: %d\n", matrix.getType(), matrix.getType());
+#StdOut
+identity flags hex: 0 decimal: 0
+set all flags hex: f decimal: 15
+##
##
-#ToDo incomplete ##
+#SeeAlso TypeMask
##
@@ -250,15 +320,30 @@ transform.
#Method bool isIdentity() const
-Returns true if the matrix is identity.
+Returns true if Matrix is identity. Identity matrix is:
+
+#Code
+#Literal
+| 1 0 0 |
+| 0 1 0 |
+| 0 0 1 |
+##
-#Return incomplete ##
+#Return true if Matrix has no effect ##
#Example
-// incomplete
+SkMatrix matrix;
+matrix.setAll(1, 0, 0, 0, 1, 0, 0, 0, 1);
+SkDebugf("is identity: %s\n", matrix.isIdentity() ? "true" : "false");
+matrix.setAll(1, 0, 0, 0, 1, 0, 0, 0, 2);
+SkDebugf("is identity: %s\n", matrix.isIdentity() ? "true" : "false");
+#StdOut
+is identity: true
+is identity: false
+##
##
-#ToDo incomplete ##
+#SeeAlso reset() setIdentity getType
##
@@ -266,13 +351,35 @@ Returns true if the matrix is identity.
#Method bool isScaleTranslate() const
-#Return incomplete ##
+Returns true if Matrix at most scales and translates. Matrix may be identity,
+contain only scale elements, only translate elements, or both. Matrix form is:
+
+#Code
+#Literal
+| scale-x 0 translate-x |
+| 0 scale-y translate-y |
+| 0 0 1 |
+##
+
+#Return true if Matrix is identity; or scales, translates, or both ##
#Example
-// incomplete
+SkMatrix matrix;
+for (SkScalar scaleX : { 1, 2 } ) {
+ for (SkScalar translateX : { 0, 20 } ) {
+ matrix.setAll(scaleX, 0, translateX, 0, 1, 0, 0, 0, 1);
+ SkDebugf("is scale-translate: %s\n", matrix.isScaleTranslate() ? "true" : "false");
+ }
+}
+#StdOut
+is scale-translate: true
+is scale-translate: true
+is scale-translate: true
+is scale-translate: true
+##
##
-#ToDo incomplete ##
+#SeeAlso setScale isTranslate setTranslate getType
##
@@ -280,13 +387,34 @@ Returns true if the matrix is identity.
#Method bool isTranslate() const
-#Return incomplete ##
+Returns true if Matrix is identity, or translates. Matrix form is:
+
+#Code
+#Literal
+| 1 0 translate-x |
+| 0 1 translate-y |
+| 0 0 1 |
+##
+
+#Return true if Matrix is identity, or translates ##
#Example
-// incomplete
+SkMatrix matrix;
+for (SkScalar scaleX : { 1, 2 } ) {
+ for (SkScalar translateX : { 0, 20 } ) {
+ matrix.setAll(scaleX, 0, translateX, 0, 1, 0, 0, 0, 1);
+ SkDebugf("is translate: %s\n", matrix.isTranslate() ? "true" : "false");
+ }
+}
+#StdOut
+is translate: true
+is translate: true
+is translate: false
+is translate: false
+##
##
-#ToDo incomplete ##
+#SeeAlso setTranslate getType
##
@@ -294,17 +422,48 @@ Returns true if the matrix is identity.
#Method bool rectStaysRect() const
-Returns true if will map a rectangle to another rectangle. This can be
-true if the matrix is identity, scale-only, or rotates a multiple of
-90 degrees, or mirrors in x or y.
+Returns true Matrix maps Rect to another Rect. If true, Matrix is identity,
+or scales, or rotates a multiple of 90 degrees, or mirrors in x or y. In all
+cases, Matrix may also have translation. Matrix form is either:
+
+#Code
+#Literal
+| scale-x 0 translate-x |
+| 0 scale-y translate-y |
+| 0 0 1 |
+##
+
+or
+
+#Code
+#Literal
+| 0 rotate-x translate-x |
+| rotate-y 0 translate-y |
+| 0 0 1 |
+##
+
+for non-zero values of scale-x, scale-y, rotate-x, and rotate-y.
+
+Also called preservesAxisAlignment; use the one that provides better inline
+documentation.
-#Return incomplete ##
+#Return true if Matrix maps one Rect into another ##
#Example
-// incomplete
+SkMatrix matrix;
+for (SkScalar angle: { 0, 90, 180, 270 } ) {
+ matrix.setRotate(angle);
+ SkDebugf("rectStaysRect: %s\n", matrix.rectStaysRect() ? "true" : "false");
+}
+#StdOut
+rectStaysRect: true
+rectStaysRect: true
+rectStaysRect: true
+rectStaysRect: true
+##
##
-#ToDo incomplete ##
+#SeeAlso preservesAxisAlignment preservesRightAngles
##
@@ -312,15 +471,49 @@ true if the matrix is identity, scale-only, or rotates a multiple of
#Method bool preservesAxisAlignment() const
-alias for rectStaysRect()
-#Return incomplete ##
+Returns true Matrix maps Rect to another Rect. If true, Matrix is identity,
+or scales, or rotates a multiple of 90 degrees, or mirrors in x or y. In all
+cases, Matrix may also have translation. Matrix form is either:
+
+#Code
+#Literal
+| scale-x 0 translate-x |
+| 0 scale-y translate-y |
+| 0 0 1 |
+##
+
+or
+
+#Code
+#Literal
+| 0 rotate-x translate-x |
+| rotate-y 0 translate-y |
+| 0 0 1 |
+##
+
+for non-zero values of scale-x, scale-y, rotate-x, and rotate-y.
+
+Also called rectStaysRect; use the one that provides better inline
+documentation.
+
+#Return true if Matrix maps one Rect into another ##
#Example
-// incomplete
+SkMatrix matrix;
+for (SkScalar angle: { 0, 90, 180, 270 } ) {
+ matrix.setRotate(angle);
+ SkDebugf("preservesAxisAlignment: %s\n", matrix.preservesAxisAlignment() ? "true" : "false");
+}
+#StdOut
+preservesAxisAlignment: true
+preservesAxisAlignment: true
+preservesAxisAlignment: true
+preservesAxisAlignment: true
+##
##
-#ToDo incomplete ##
+#SeeAlso rectStaysRect preservesRightAngles
##
@@ -328,15 +521,37 @@ alias for rectStaysRect()
#Method bool hasPerspective() const
-Returns true if the matrix contains perspective elements.
+Returns true if the matrix contains perspective elements. Matrix form is:
-#Return incomplete ##
+#Code
+#Literal
+| -- -- -- |
+| -- -- -- |
+| perspective-x perspective-y perspective-scale |
+##
+
+where perspective-x or perspective-y is non-zero, or perspective-scale is
+not one. All other elements may have any value.
+
+#Return true if Matrix is in most general form ##
#Example
-// incomplete
+#Image 4
+SkMatrix matrix;
+SkPoint bitmapBounds[4], perspect[4] = {{50, 10}, {180, 40}, {236, 176}, {10, 206}};
+SkRect::Make(source.bounds()).toQuad(bitmapBounds);
+matrix.setPolyToPoly(bitmapBounds, perspect, 4);
+canvas->concat(matrix);
+SkString string;
+string.printf("hasPerspective %s", matrix.hasPerspective() ? "true" : "false");
+canvas->drawBitmap(source, 0, 0);
+SkPaint paint;
+paint.setAntiAlias(true);
+paint.setTextSize(48);
+canvas->drawString(string, 0, source.bounds().height() + 48, paint);
##
-#ToDo incomplete ##
+#SeeAlso setAll set9
##
@@ -344,18 +559,50 @@ Returns true if the matrix contains perspective elements.
#Method bool isSimilarity(SkScalar tol = SK_ScalarNearlyZero) const
-Returns true if the matrix contains only translation, rotation/reflection or uniform scale.
-Returns false if other transformation types are included or is degenerate
+Returns true if Matrix contains only translation, rotation, reflection, and
+uniform scale.
+Returns false if Matrix contains different scales, skewing, perspective, or
+degenerate forms that collapse to a line or point.
-#Param tol incomplete ##
+Describes that the Matrix makes rendering with and without the matrix are
+visually alike; a transformed circle remains a circle. Mathematically, this is
+referred to as similarity of a Euclidean space, or a similarity transformation.
-#Return incomplete ##
+Preserves right angles, keeping the arms of the angle equal lengths.
-#Example
-// incomplete
-##
+#Param tol to be deprecated ##
+
+#Return true if Matrix only rotates, uniformly scales, translates ##
-#ToDo incomplete ##
+#Example
+#Description
+String is drawn four times through but only two are visible. Drawing the pair
+with isSimilarity false reveals the pair not visible through the matrix.
+##
+ SkPaint p;
+ p.setAntiAlias(true);
+ SkMatrix m;
+ int below = 175;
+ for (SkScalar sx : { -1, 1 } ) {
+ for (SkScalar sy : { -1, 1 } ) {
+ m.setAll(sx, 1, 128, 1, sy, 32, 0, 0, 1);
+ bool isSimilarity = m.isSimilarity();
+ SkString str;
+ str.printf("sx: %g sy: %g sim: %s", sx, sy, isSimilarity ? "true" : "false");
+ {
+ SkAutoCanvasRestore autoRestore(canvas, true);
+ canvas->concat(m);
+ canvas->drawString(str, 0, 0, p);
+ }
+ if (!isSimilarity) {
+ canvas->drawString(str, 40, below, p);
+ below += 20;
+ }
+ }
+ }
+##
+
+#SeeAlso isScaleTranslate preservesRightAngles rectStaysRect isFixedStepInX
##
@@ -363,25 +610,52 @@ Returns false if other transformation types are included or is degenerate
#Method bool preservesRightAngles(SkScalar tol = SK_ScalarNearlyZero) const
-Returns true if the matrix contains only translation, rotation/reflection or scale
-(non-uniform scale is allowed).
-Returns false if other transformation types are included or is degenerate
+Returns true if Matrix contains only translation, rotation, reflection, and
+scale. Scale may differ along rotated axes.
+Returns false if Matrix skewing, perspective, or degenerate forms that collapse
+to a line or point.
-#Param tol incomplete ##
+Preserves right angles, but not requiring that the arms of the angle
+retain equal lengths.
-#Return incomplete ##
+#Param tol to be deprecated ##
-#Example
-// incomplete
-##
+#Return true if Matrix only rotates, scales, translates ##
-#ToDo incomplete ##
+#Example
+#Height 128
+#Description
+Equal scale is both similar and preserves right angles.
+Unequal scale is not similar but preserves right angles.
+Skews are not similar and do not preserve right angles.
+##
+SkPaint p;
+p.setAntiAlias(true);
+SkMatrix m;
+int pos = 0;
+for (SkScalar sx : { 1, 2 } ) {
+ for (SkScalar kx : { 0, 1 } ) {
+ m.setAll(sx, kx, 16, 0, 1, 32, 0, 0, 1);
+ bool isSimilarity = m.isSimilarity();
+ bool preservesRightAngles = m.preservesRightAngles();
+ SkString str;
+ str.printf("sx: %g kx: %g %s %s", sx, kx, isSimilarity ? "sim" : "",
+ preservesRightAngles ? "right" : "");
+ SkAutoCanvasRestore autoRestore(canvas, true);
+ canvas->concat(m);
+ canvas->drawString(str, 0, pos, p);
+ pos += 20;
+ }
+}
+##
+
+#SeeAlso isScaleTranslate isSimilarity rectStaysRect isFixedStepInX
##
# ------------------------------------------------------------------------------
-#Enum _anonymous
+#Enum
#Code
enum {
@@ -397,36 +671,65 @@ Returns false if other transformation types are included or is degenerate
};
##
+Matrix organizes its values in row order. These members correspond to
+each value in Matrix.
+
#Const kMScaleX 0
+horizontal scale factor
##
#Const kMSkewX 1
+horizontal skew factor
##
#Const kMTransX 2
+horizontal translation
##
#Const kMSkewY 3
+vertical skew factor
##
#Const kMScaleY 4
+vertical scale factor
##
#Const kMTransY 5
+vertical translation
##
#Const kMPersp0 6
+input x perspective factor
##
#Const kMPersp1 7
+input y perspective factor
##
#Const kMPersp2 8
+perspective bias
##
#Example
-// incomplete
-##
-
-#ToDo incomplete ##
+SkPaint black;
+black.setAntiAlias(true);
+black.setTextSize(48);
+SkPaint gray = black;
+gray.setColor(0xFF9f9f9f);
+SkScalar offset[] = { 1.5f, 1.5f, 20, 1.5f, 1.5f, 20, .03f, .01f, 2 };
+for (int i : { SkMatrix::kMScaleX, SkMatrix::kMSkewX, SkMatrix::kMTransX,
+ SkMatrix::kMSkewY, SkMatrix::kMScaleY, SkMatrix::kMTransY,
+ SkMatrix::kMPersp0, SkMatrix::kMPersp1, SkMatrix::kMPersp2 } ) {
+ SkMatrix m;
+ m.setIdentity();
+ m.set(i, offset[i]);
+ SkAutoCanvasRestore autoRestore(canvas, true);
+ canvas->translate(22 + (i % 3) * 88, 44 + (i / 3) * 88);
+ canvas->drawString("&", 0, 0, gray);
+ canvas->concat(m);
+ canvas->drawString("&", 0, 0, black);
+}
+##
+
+#SeeAlso get() set()
##
# ------------------------------------------------------------------------------
-#Enum _anonymous_2
+#Enum
#Code
enum {
@@ -439,27 +742,32 @@ Returns false if other transformation types are included or is degenerate
};
##
-Affine arrays are in column major order
-because that is how PDF and XPS like it.
+Affine arrays are in column major order to match the matrix used by
+PDF and XPS.
#Const kAScaleX 0
+horizontal scale factor
##
#Const kASkewY 1
+vertical skew factor
##
#Const kASkewX 2
+horizontal skew factor
##
#Const kAScaleY 3
+vertical scale factor
##
#Const kATransX 4
+horizontal translation
##
#Const kATransY 5
+vertical translation
##
-#Example
-// incomplete
+#NoExample
##
-#ToDo incomplete ##
+#SeeAlso SetAffineIdentity asAffine setAffine
##
@@ -467,15 +775,27 @@ because that is how PDF and XPS like it.
#Method SkScalar operator[](int index) const
-#Param index incomplete ##
+Returns one matrix value. Asserts if index is out of range and SK_DEBUG is
+defined.
+
+#Param index one of: kMScaleX, kMSkewX, kMTransX, kMSkewY, kMScaleY, kMTransY,
+ kMPersp0, kMPersp1, kMPersp2
+##
-#Return incomplete ##
+#Return value corresponding to index ##
#Example
-// incomplete
+SkMatrix matrix;
+matrix.setScale(42, 24);
+SkDebugf("matrix[SkMatrix::kMScaleX] %c= 42\n", matrix[SkMatrix::kMScaleX] == 42 ? '=' : '!');
+SkDebugf("matrix[SkMatrix::kMScaleY] %c= 24\n", matrix[SkMatrix::kMScaleY] == 24 ? '=' : '!');
+#StdOut
+matrix[SkMatrix::kMScaleX] == 42
+matrix[SkMatrix::kMScaleY] == 24
+##
##
-#ToDo incomplete ##
+#SeeAlso get set
##
@@ -483,15 +803,29 @@ because that is how PDF and XPS like it.
#Method SkScalar get(int index) const
-#Param index incomplete ##
+Returns one matrix value. Asserts if index is out of range and SK_DEBUG is
+defined.
-#Return incomplete ##
+#Param index one of: kMScaleX, kMSkewX, kMTransX, kMSkewY, kMScaleY, kMTransY,
+ kMPersp0, kMPersp1, kMPersp2
+##
+
+#Return value corresponding to index ##
#Example
-// incomplete
+SkMatrix matrix;
+matrix.setSkew(42, 24);
+SkDebugf("matrix.get(SkMatrix::kMSkewX) %c= 42\n",
+ matrix.get(SkMatrix::kMSkewX) == 42 ? '=' : '!');
+SkDebugf("matrix.get(SkMatrix::kMSkewY) %c= 24\n",
+ matrix.get(SkMatrix::kMSkewY) == 24 ? '=' : '!');
+#StdOut
+matrix.get(SkMatrix::kMSkewX) == 42
+matrix.get(SkMatrix::kMSkewY) == 24
+##
##
-#ToDo incomplete ##
+#SeeAlso operator[](int index) set
##
@@ -499,13 +833,21 @@ because that is how PDF and XPS like it.
#Method SkScalar getScaleX() const
-#Return incomplete ##
+Returns scale factor multiplied by x input, contributing to x output.
+With mapPoints, scales Points along the x-axis.
+
+#Return horizontal scale factor ##
#Example
-// incomplete
+SkMatrix matrix;
+matrix.setScale(42, 24);
+SkDebugf("matrix.getScaleX() %c= 42\n", matrix.getScaleX() == 42 ? '=' : '!');
+#StdOut
+matrix.getScaleX() == 42
+##
##
-#ToDo incomplete ##
+#SeeAlso get getScaleY setScaleX setScale
##
@@ -513,13 +855,21 @@ because that is how PDF and XPS like it.
#Method SkScalar getScaleY() const
-#Return incomplete ##
+Returns scale factor multiplied by y input, contributing to y output.
+With mapPoints, scales Points along the y-axis.
+
+#Return vertical scale factor ##
#Example
-// incomplete
+SkMatrix matrix;
+matrix.setScale(42, 24);
+SkDebugf("matrix.getScaleY() %c= 24\n", matrix.getScaleY() == 24 ? '=' : '!');
+#StdOut
+matrix.getScaleY() == 24
+##
##
-#ToDo incomplete ##
+#SeeAlso get getScaleX setScaleY setScale
##
@@ -527,13 +877,22 @@ because that is how PDF and XPS like it.
#Method SkScalar getSkewY() const
-#Return incomplete ##
+Returns scale factor multiplied by x input, contributing to y output.
+With mapPoints, skews Points along the y-axis.
+Skew x and y together can rotate Points.
+
+#Return vertical skew factor ##
#Example
-// incomplete
+SkMatrix matrix;
+matrix.setSkew(42, 24);
+SkDebugf("matrix.getSkewY() %c= 24\n", matrix.getSkewY() == 24 ? '=' : '!');
+#StdOut
+matrix.getSkewY() == 24
+##
##
-#ToDo incomplete ##
+#SeeAlso get getSkewX setSkewY setSkew
##
@@ -541,13 +900,22 @@ because that is how PDF and XPS like it.
#Method SkScalar getSkewX() const
-#Return incomplete ##
+Returns scale factor multiplied by y input, contributing to x output.
+With mapPoints, skews Points along the x-axis.
+Skew x and y together can rotate Points.
+
+#Return horizontal scale factor ##
#Example
-// incomplete
+SkMatrix matrix;
+matrix.setSkew(42, 24);
+SkDebugf("matrix.getSkewX() %c= 42\n", matrix.getSkewX() == 42 ? '=' : '!');
+#StdOut
+matrix.getSkewX() == 42
+##
##
-#ToDo incomplete ##
+#SeeAlso get getSkewY setSkewX setSkew
##
@@ -555,13 +923,21 @@ because that is how PDF and XPS like it.
#Method SkScalar getTranslateX() const
-#Return incomplete ##
+Returns translation contributing to x output.
+With mapPoints, moves Points along the x-axis.
+
+#Return horizontal translation factor ##
#Example
-// incomplete
+SkMatrix matrix;
+matrix.setTranslate(42, 24);
+SkDebugf("matrix.getTranslateX() %c= 42\n", matrix.getTranslateX() == 42 ? '=' : '!');
+#StdOut
+matrix.getTranslateX() == 42
+##
##
-#ToDo incomplete ##
+#SeeAlso get getTranslateY setTranslateX setTranslate
##
@@ -569,13 +945,21 @@ because that is how PDF and XPS like it.
#Method SkScalar getTranslateY() const
-#Return incomplete ##
+Returns translation contributing to y output.
+With mapPoints, moves Points along the y-axis.
+
+#Return vertical translation factor ##
#Example
-// incomplete
+SkMatrix matrix;
+matrix.setTranslate(42, 24);
+SkDebugf("matrix.getTranslateY() %c= 24\n", matrix.getTranslateY() == 24 ? '=' : '!');
+#StdOut
+matrix.getTranslateY() == 24
+##
##
-#ToDo incomplete ##
+#SeeAlso get getTranslateX setTranslateY setTranslate
##
@@ -583,13 +967,29 @@ because that is how PDF and XPS like it.
#Method SkScalar getPerspX() const
-#Return incomplete ##
+Returns factor scaling input x relative to input y.
+
+#Return input x perspective factor ##
#Example
-// incomplete
+ SkMatrix m;
+ m.setIdentity();
+ m.set(SkMatrix::kMPersp0, -0.004f);
+ SkAutoCanvasRestore autoRestore(canvas, true);
+ canvas->translate(22, 144);
+ SkPaint black;
+ black.setAntiAlias(true);
+ black.setTextSize(24);
+ SkPaint gray = black;
+ gray.setColor(0xFF9f9f9f);
+ SkString string;
+ string.appendScalar(m.getPerspX());
+ canvas->drawString(string, 0, -72, gray);
+ canvas->concat(m);
+ canvas->drawString(string, 0, 0, black);
##
-#ToDo incomplete ##
+#SeeAlso kMPersp0 getPerspY
##
@@ -597,29 +997,69 @@ because that is how PDF and XPS like it.
#Method SkScalar getPerspY() const
-#Return incomplete ##
+
+Returns factor scaling input y relative to input x.
+
+#Return input y perspective factor ##
#Example
-// incomplete
+ SkMatrix m;
+ m.setIdentity();
+ m.set(SkMatrix::kMPersp1, -0.004f);
+ SkAutoCanvasRestore autoRestore(canvas, true);
+ canvas->translate(22, 144);
+ SkPaint black;
+ black.setAntiAlias(true);
+ black.setTextSize(24);
+ SkPaint gray = black;
+ gray.setColor(0xFF9f9f9f);
+ SkString string;
+ string.appendScalar(m.getPerspY());
+ canvas->drawString(string, 0, -72, gray);
+ canvas->concat(m);
+ canvas->drawString(string, 0, 0, black);
##
-#ToDo incomplete ##
+#SeeAlso kMPersp1 getPerspX
##
# ------------------------------------------------------------------------------
-#Method SkScalar operator[](int index)
+#Method SkScalar& operator[](int index)
-#Param index incomplete ##
+Returns writable Matrix value. Asserts if index is out of range and SK_DEBUG is
+defined. Clears internal cache anticipating that caller will change Matrix value.
-#Return incomplete ##
+Next call to read Matrix state may recompute cache; subsequent writes to Matrix
+value must be followed by dirtyMatrixTypeCache.
+
+#Param index one of: kMScaleX, kMSkewX, kMTransX, kMSkewY, kMScaleY, kMTransY,
+ kMPersp0, kMPersp1, kMPersp2
+##
+
+#Return writable value corresponding to index ##
#Example
-// incomplete
+SkMatrix matrix;
+matrix.setIdentity();
+SkDebugf("with identity matrix: x = %g\n", matrix.mapXY(24, 42).fX);
+SkScalar& skewRef = matrix[SkMatrix::kMSkewX];
+skewRef = 0;
+SkDebugf("after skew x mod: x = %g\n", matrix.mapXY(24, 42).fX);
+skewRef = 1;
+SkDebugf("after 2nd skew x mod: x = %g\n", matrix.mapXY(24, 42).fX);
+matrix.dirtyMatrixTypeCache();
+SkDebugf("after dirty cache: x = %g\n", matrix.mapXY(24, 42).fX);
+#StdOut
+with identity matrix: x = 24
+after skew x mod: x = 24
+after 2nd skew x mod: x = 24
+after dirty cache: x = 66
+##
##
-#ToDo incomplete ##
+#SeeAlso get dirtyMatrixTypeCache set
##
@@ -627,128 +1067,236 @@ because that is how PDF and XPS like it.
#Method void set(int index, SkScalar value)
-#Param index incomplete ##
-#Param value incomplete ##
+Sets Matrix value. Asserts if index is out of range and SK_DEBUG is
+defined. Safer than operator[]; internal cache is always maintained.
+
+#Param index one of: kMScaleX, kMSkewX, kMTransX, kMSkewY, kMScaleY, kMTransY,
+ kMPersp0, kMPersp1, kMPersp2
+##
+#Param value Scalar to store in Matrix ##
#Example
-// incomplete
+SkMatrix matrix;
+matrix.setIdentity();
+SkDebugf("with identity matrix: x = %g\n", matrix.mapXY(24, 42).fX);
+matrix.set(SkMatrix::kMSkewX, 0);
+SkDebugf("after skew x mod: x = %g\n", matrix.mapXY(24, 42).fX);
+matrix.set(SkMatrix::kMSkewX, 1);
+SkDebugf("after 2nd skew x mod: x = %g\n", matrix.mapXY(24, 42).fX);
+#StdOut
+with identity matrix: x = 24
+after skew x mod: x = 24
+after 2nd skew x mod: x = 66
+##
##
-#ToDo incomplete ##
+#SeeAlso operator[] get
-##
+#Method ##
# ------------------------------------------------------------------------------
#Method void setScaleX(SkScalar v)
-#Param v incomplete ##
+Sets horizontal scale factor.
+
+#Param v horizontal scale factor to store ##
#Example
-// incomplete
+#Height 64
+SkPaint paint;
+paint.setAntiAlias(true);
+paint.setTextSize(24);
+canvas->drawString("normal", 12, 24, paint);
+SkMatrix matrix;
+matrix.setIdentity();
+matrix.setScaleX(3);
+canvas->concat(matrix);
+canvas->drawString("x scale", 0, 48, paint);
##
-#ToDo incomplete ##
+#SeeAlso set setScale setScaleY
-##
+#Method ##
# ------------------------------------------------------------------------------
#Method void setScaleY(SkScalar v)
-#Param v incomplete ##
+Sets vertical scale factor.
+
+#Param v vertical scale factor to store ##
#Example
-// incomplete
+#Height 192
+SkPaint paint;
+paint.setAntiAlias(true);
+paint.setTextSize(24);
+canvas->drawString("normal", 12, 24, paint);
+SkMatrix matrix;
+matrix.setIdentity();
+matrix.setScaleY(3);
+canvas->concat(matrix);
+canvas->drawString("y scale", 12, 48, paint);
##
-#ToDo incomplete ##
+#SeeAlso set setScale setScaleX
-##
+#Method ##
# ------------------------------------------------------------------------------
#Method void setSkewY(SkScalar v)
-#Param v incomplete ##
+Sets vertical skew factor.
+
+#Param v vertical skew factor to store ##
#Example
-// incomplete
+#Height 96
+SkPaint paint;
+paint.setAntiAlias(true);
+paint.setTextSize(24);
+canvas->drawString("normal", 12, 24, paint);
+SkMatrix matrix;
+matrix.setIdentity();
+matrix.setSkewY(.3f);
+canvas->concat(matrix);
+canvas->drawString("y skew", 12, 48, paint);
##
-#ToDo incomplete ##
+#SeeAlso set setSkew setSkewX
-##
+#Method ##
# ------------------------------------------------------------------------------
#Method void setSkewX(SkScalar v)
-#Param v incomplete ##
+Sets horizontal skew factor.
+
+#Param v horizontal skew factor to store ##
#Example
-// incomplete
+#Height 64
+SkPaint paint;
+paint.setAntiAlias(true);
+paint.setTextSize(24);
+canvas->drawString("normal", 12, 24, paint);
+SkMatrix matrix;
+matrix.setIdentity();
+matrix.setSkewX(-.7f);
+canvas->concat(matrix);
+canvas->drawString("x skew", 36, 48, paint);
##
-#ToDo incomplete ##
+#SeeAlso set setSkew setSkewX
-##
+#Method ##
# ------------------------------------------------------------------------------
#Method void setTranslateX(SkScalar v)
-#Param v incomplete ##
+Sets horizontal translation.
+
+#Param v horizontal translation to store ##
#Example
-// incomplete
+#Height 48
+SkPaint paint;
+paint.setAntiAlias(true);
+paint.setTextSize(24);
+canvas->drawString("normal", 8, 24, paint);
+SkMatrix matrix;
+matrix.setIdentity();
+matrix.setTranslateX(96);
+canvas->concat(matrix);
+canvas->drawString("x translate", 8, 24, paint);
##
-#ToDo incomplete ##
+#SeeAlso set setTranslate setTranslateY
-##
+#Method ##
# ------------------------------------------------------------------------------
#Method void setTranslateY(SkScalar v)
-#Param v incomplete ##
+Sets vertical translation.
+
+#Param v vertical translation to store ##
#Example
-// incomplete
+#Height 64
+SkPaint paint;
+paint.setAntiAlias(true);
+paint.setTextSize(24);
+canvas->drawString("normal", 8, 24, paint);
+SkMatrix matrix;
+matrix.setIdentity();
+matrix.setTranslateY(24);
+canvas->concat(matrix);
+canvas->drawString("y translate", 8, 24, paint);
##
-#ToDo incomplete ##
+#SeeAlso set setTranslate setTranslateX
-##
+#Method ##
# ------------------------------------------------------------------------------
#Method void setPerspX(SkScalar v)
-#Param v incomplete ##
+Sets input x perspective factor, which causes mapXY to vary input x inversely
+proportional to input y.
+
+#Param v perspective factor ##
#Example
-// incomplete
+#Image 4
+for (SkScalar perspX : { -.003f, 0.f, .003f, .012f } ) {
+ SkMatrix matrix;
+ matrix.setIdentity();
+ matrix.setPerspX(perspX);
+ canvas->save();
+ canvas->concat(matrix);
+ canvas->drawBitmap(source, 0, 0);
+ canvas->restore();
+ canvas->translate(64, 64);
+}
##
-#ToDo incomplete ##
+#SeeAlso getPerspX set setAll set9
-##
+#Method ##
# ------------------------------------------------------------------------------
#Method void setPerspY(SkScalar v)
-#Param v incomplete ##
+Sets input y perspective factor, which causes mapXY to vary input y inversely
+proportional to input x.
+
+#Param v perspective factor ##
#Example
-// incomplete
+#Image 4
+for (SkScalar perspX : { -.003f, 0.f, .003f, .012f } ) {
+ SkMatrix matrix;
+ matrix.setIdentity();
+ matrix.setPerspY(perspX);
+ canvas->save();
+ canvas->concat(matrix);
+ canvas->drawBitmap(source, 0, 0);
+ canvas->restore();
+ canvas->translate(64, 64);
+}
##
-#ToDo incomplete ##
+#SeeAlso getPerspY set setAll set9
-##
+#Method ##
# ------------------------------------------------------------------------------
@@ -756,528 +1304,1066 @@ because that is how PDF and XPS like it.
SkScalar skewY, SkScalar scaleY, SkScalar transY,
SkScalar persp0, SkScalar persp1, SkScalar persp2)
-#Param scaleX incomplete ##
-#Param skewX incomplete ##
-#Param transX incomplete ##
-#Param skewY incomplete ##
-#Param scaleY incomplete ##
-#Param transY incomplete ##
-#Param persp0 incomplete ##
-#Param persp1 incomplete ##
-#Param persp2 incomplete ##
+Sets all values from parameters. Sets matrix to:
+
+#Code
+#Literal
+| scaleX skewX transX |
+| skewY scaleY transY |
+| persp0 persp1 persp2 |
+##
+
+#Param scaleX horizontal scale factor to store ##
+#Param skewX horizontal skew factor to store ##
+#Param transX horizontal translation to store ##
+#Param skewY vertical skew factor to store ##
+#Param scaleY vertical scale factor to store ##
+#Param transY vertical translation to store ##
+#Param persp0 input x perspective factor to store ##
+#Param persp1 input y perspective factor to store ##
+#Param persp2 perspective scale factor to store ##
#Example
-// incomplete
+ SkPaint p;
+ p.setAntiAlias(true);
+ p.setTextSize(64);
+ SkMatrix m;
+ for (SkScalar sx : { -1, 1 } ) {
+ for (SkScalar sy : { -1, 1 } ) {
+ SkAutoCanvasRestore autoRestore(canvas, true);
+ m.setAll(sx, 1, 128, 0, sy, 128, 0, 0, 1);
+ canvas->concat(m);
+ canvas->drawString("K", 0, 0, p);
+ }
+ }
##
-#ToDo incomplete ##
+#SeeAlso set9
-##
+#Method ##
# ------------------------------------------------------------------------------
#Method void get9(SkScalar buffer[9]) const
-Copy the 9 scalars for this matrix into buffer, in member value ascending order:
-kMScaleX, kMSkewX, kMTransX, kMSkewY, kMScaleY, kMTransY, kMPersp0, kMPersp1, kMPersp2.
+Copies nine Scalar values contained by Matrix into buffer, in member value
+ascending order: kMScaleX, kMSkewX, kMTransX, kMSkewY, kMScaleY, kMTransY,
+kMPersp0, kMPersp1, kMPersp2.
-#Param buffer incomplete ##
+#Param buffer storage for nine Scalar values ##
#Example
-// incomplete
+SkMatrix matrix = SkMatrix::MakeRectToRect({0, 0, 1, 1}, {3, 4, 7, 9},
+ SkMatrix::kFill_ScaleToFit);
+SkScalar b[9];
+matrix.get9(b);
+SkDebugf("{%g, %g, %g},\n{%g, %g, %g},\n{%g, %g, %g}\n", b[0], b[1], b[2],
+ b[3], b[4], b[5], b[6], b[7], b[8]);
+#StdOut
+{4, 0, 3},
+{0, 5, 4},
+{0, 0, 1}
+##
##
-#ToDo incomplete ##
+#SeeAlso set9
-##
+#Method ##
# ------------------------------------------------------------------------------
#Method void set9(const SkScalar buffer[9])
-Set this matrix to the 9 scalars from the buffer, in member value ascending order:
-kMScaleX, kMSkewX, kMTransX, kMSkewY, kMScaleY, kMTransY, kMPersp0, kMPersp1, kMPersp2.
+Sets Matrix to nine Scalar values in buffer, in member value ascending order:
+kMScaleX, kMSkewX, kMTransX, kMSkewY, kMScaleY, kMTransY, kMPersp0, kMPersp1,
+kMPersp2.
+
+Sets matrix to:
-Note: calling set9 followed by get9 may not return the exact same values. Since the matrix
-is used to map non-homogeneous coordinates, it is free to scale the 9 values as needed.
+#Code
+#Literal
+| buffer[0] buffer[1] buffer[2] |
+| buffer[3] buffer[4] buffer[5] |
+| buffer[6] buffer[7] buffer[8] |
+##
+
+In the future, set9 followed by get9 may not return the same values. Since Matrix
+maps non-homogeneous coordinates, scaling all nine values produces an equivalent
+transformation, possibly improving precision.
-#Param buffer incomplete ##
+#Param buffer nine Scalar values ##
#Example
-// incomplete
+#Image 4
+SkMatrix m;
+SkScalar buffer[9] = {4, 0, 3, 0, 5, 4, 0, 0, 1};
+m.set9(buffer);
+canvas->concat(m);
+canvas->drawBitmap(source, 0, 0);
##
-#ToDo incomplete ##
+#SeeAlso setAll get9
-##
+#Method ##
# ------------------------------------------------------------------------------
#Method void reset()
-Set the matrix to identity
+Sets Matrix to identity; which has no effect on mapped Points. Sets Matrix to:
-#Example
-// incomplete
+#Code
+#Literal
+| 1 0 0 |
+| 0 1 0 |
+| 0 0 1 |
##
-#ToDo incomplete ##
+Also called setIdentity(); use the one that provides better inline
+documentation.
+#Example
+SkMatrix m;
+m.reset();
+SkDebugf("m.isIdentity(): %s\n", m.isIdentity() ? "true" : "false");
+#StdOut
+m.isIdentity(): true
+##
##
+#SeeAlso isIdentity setIdentity
+
+#Method ##
+
# ------------------------------------------------------------------------------
#Method void setIdentity()
-alias for reset()
+Sets Matrix to identity; which has no effect on mapped Points. Sets Matrix to:
-#Example
-// incomplete
+#Code
+#Literal
+| 1 0 0 |
+| 0 1 0 |
+| 0 0 1 |
##
-#ToDo incomplete ##
+Also called reset(); use the one that provides better inline
+documentation.
+#Example
+SkMatrix m;
+m.setIdentity();
+SkDebugf("m.isIdentity(): %s\n", m.isIdentity() ? "true" : "false");
+#StdOut
+m.isIdentity(): true
+##
##
+#SeeAlso isIdentity reset
+
+#Method ##
+
# ------------------------------------------------------------------------------
#Method void setTranslate(SkScalar dx, SkScalar dy)
-Set the matrix to translate by (dx, dy).
+Sets Matrix to translate by (dx, dy).
-#Param dx incomplete ##
-#Param dy incomplete ##
+#Param dx horizontal translation ##
+#Param dy vertical translation ##
#Example
-// incomplete
+#Height 64
+SkPaint paint;
+paint.setAntiAlias(true);
+paint.setTextSize(24);
+canvas->drawString("normal", 8, 24, paint);
+SkMatrix matrix;
+matrix.setTranslate(96, 24);
+canvas->concat(matrix);
+canvas->drawString("translate", 8, 24, paint);
##
-#ToDo incomplete ##
+#SeeAlso setTranslateX setTranslateY
-##
+#Method ##
# ------------------------------------------------------------------------------
#Method void setTranslate(const SkVector& v)
-#Param v incomplete ##
+Sets Matrix to translate by (v.fX, v.fY).
+
+#Param v Vector containing horizontal and vertical translation ##
#Example
-// incomplete
+#Height 64
+SkPaint paint;
+paint.setAntiAlias(true);
+paint.setTextSize(24);
+canvas->drawString("normal", 8, 24, paint);
+SkMatrix matrix;
+matrix.setTranslate({96, 24});
+canvas->concat(matrix);
+canvas->drawString("translate", 8, 24, paint);
##
-#ToDo incomplete ##
+#SeeAlso setTranslateX setTranslateY MakeTrans
-##
+#Method ##
# ------------------------------------------------------------------------------
#Method void setScale(SkScalar sx, SkScalar sy, SkScalar px, SkScalar py)
-Set the matrix to scale by sx and sy, with a pivot point at (px, py).
-The pivot point is the coordinate that should remain unchanged by the
-specified transformation.
+Sets Matrix to scale by sx and sy, about a pivot point at (px, py).
+The pivot point is unchanged when mapped with Matrix.
-#Param sx incomplete ##
-#Param sy incomplete ##
-#Param px incomplete ##
-#Param py incomplete ##
+#Param sx horizontal scale factor ##
+#Param sy vertical scale factor ##
+#Param px pivot x ##
+#Param py pivot y ##
#Example
-// incomplete
+ SkPaint p;
+ p.setAntiAlias(true);
+ p.setTextSize(64);
+ SkMatrix m;
+ for (SkScalar sx : { -1, 1 } ) {
+ for (SkScalar sy : { -1, 1 } ) {
+ SkAutoCanvasRestore autoRestore(canvas, true);
+ m.setScale(sx, sy, 128, 128);
+ canvas->concat(m);
+ canvas->drawString("K", 128, 128, p);
+ }
+ }
##
-#ToDo incomplete ##
+#SeeAlso setScaleX setScaleY MakeScale preScale postScale
-##
+#Method ##
# ------------------------------------------------------------------------------
#Method void setScale(SkScalar sx, SkScalar sy)
-Set the matrix to scale by sx and sy.
-
-#Param sx incomplete ##
-#Param sy incomplete ##
-
-#Example
-// incomplete
-##
-
-#ToDo incomplete ##
-
-##
-
-# ------------------------------------------------------------------------------
-
-#Method bool setIDiv(int divx, int divy)
-
-Set the matrix to scale by 1/divx and 1/divy. Returns false and does not
-touch the matrix if either divx or divy is zero.
-
-#Param divx incomplete ##
-#Param divy incomplete ##
+Sets Matrix to scale by sx and sy about at pivot point at (0, 0).
-#Return incomplete ##
+#Param sx horizontal scale factor ##
+#Param sy vertical scale factor ##
#Example
-// incomplete
+ SkPaint p;
+ p.setAntiAlias(true);
+ p.setTextSize(64);
+ SkMatrix m;
+ for (SkScalar sx : { -1, 1 } ) {
+ for (SkScalar sy : { -1, 1 } ) {
+ SkAutoCanvasRestore autoRestore(canvas, true);
+ m.setScale(sx, sy);
+ m.postTranslate(128, 128);
+ canvas->concat(m);
+ canvas->drawString("K", 0, 0, p);
+ }
+ }
##
-#ToDo incomplete ##
+#SeeAlso setScaleX setScaleY MakeScale preScale postScale
-##
+#Method ##
# ------------------------------------------------------------------------------
#Method void setRotate(SkScalar degrees, SkScalar px, SkScalar py)
-Set the matrix to rotate by the specified number of degrees, with a
-pivot point at (px, py). The pivot point is the coordinate that should
-remain unchanged by the specified transformation.
+Sets Matrix to rotate by degrees about a pivot point at (px, py).
+The pivot point is unchanged when mapped with Matrix.
+
+Positive degrees rotates clockwise.
-#Param degrees incomplete ##
-#Param px incomplete ##
-#Param py incomplete ##
+#Param degrees angle of axes relative to upright axes ##
+#Param px pivot x ##
+#Param py pivot y ##
#Example
-// incomplete
+#Height 128
+ SkPaint paint;
+ paint.setColor(SK_ColorGRAY);
+ paint.setAntiAlias(true);
+ SkRect rect = {20, 20, 100, 100};
+ canvas->drawRect(rect, paint);
+ paint.setColor(SK_ColorRED);
+ SkMatrix matrix;
+ matrix.setRotate(25, rect.centerX(), rect.centerY());
+ canvas->concat(matrix);
+ canvas->drawRect(rect, paint);
##
-#ToDo incomplete ##
+#SeeAlso setSinCos preRotate postRotate
-##
+#Method ##
# ------------------------------------------------------------------------------
#Method void setRotate(SkScalar degrees)
-Set the matrix to rotate about (0,0) by the specified number of degrees.
+Sets Matrix to rotate by degrees about a pivot point at (0, 0).
+Positive degrees rotates clockwise.
-#Param degrees incomplete ##
+#Param degrees angle of axes relative to upright axes ##
#Example
-// incomplete
+#Height 128
+ SkPaint paint;
+ paint.setColor(SK_ColorGRAY);
+ paint.setAntiAlias(true);
+ SkRect rect = {20, 20, 100, 100};
+ canvas->drawRect(rect, paint);
+ paint.setColor(SK_ColorRED);
+ SkMatrix matrix;
+ matrix.setRotate(25);
+ canvas->translate(rect.centerX(), rect.centerY());
+ canvas->concat(matrix);
+ canvas->translate(-rect.centerX(), -rect.centerY());
+ canvas->drawRect(rect, paint);
##
-#ToDo incomplete ##
+#SeeAlso setSinCos preRotate postRotate
-##
+#Method ##
# ------------------------------------------------------------------------------
#Method void setSinCos(SkScalar sinValue, SkScalar cosValue,
SkScalar px, SkScalar py)
-Set the matrix to rotate by the specified sine and cosine values, with
-a pivot point at (px, py). The pivot point is the coordinate that
-should remain unchanged by the specified transformation.
+Sets Matrix to rotate by sinValue and cosValue, about a pivot point at (px, py).
+The pivot point is unchanged when mapped with Matrix.
+
+Vector (sinValue, cosValue) describes the angle of rotation relative to (0, 1).
+Vector length specifies scale.
-#Param sinValue incomplete ##
-#Param cosValue incomplete ##
-#Param px incomplete ##
-#Param py incomplete ##
+#Param sinValue rotation vector x component ##
+#Param cosValue rotation vector y component ##
+#Param px pivot x ##
+#Param py pivot y ##
#Example
-// incomplete
+#Height 128
+ SkPaint paint;
+ paint.setColor(SK_ColorGRAY);
+ paint.setAntiAlias(true);
+ SkRect rect = {20, 20, 100, 100};
+ canvas->drawRect(rect, paint);
+ paint.setColor(SK_ColorRED);
+ SkMatrix matrix;
+ matrix.setSinCos(.25f, .85f, rect.centerX(), rect.centerY());
+ canvas->concat(matrix);
+ canvas->drawRect(rect, paint);
##
-#ToDo incomplete ##
+#SeeAlso setRotate setScale setRSXform
-##
+#Method ##
# ------------------------------------------------------------------------------
#Method void setSinCos(SkScalar sinValue, SkScalar cosValue)
-Set the matrix to rotate by the specified sine and cosine values.
+Sets Matrix to rotate by sinValue and cosValue, about a pivot point at (0, 0).
+
+Vector (sinValue, cosValue) describes the angle of rotation relative to (0, 1).
+Vector length specifies scale.
-#Param sinValue incomplete ##
-#Param cosValue incomplete ##
+#Param sinValue rotation vector x component ##
+#Param cosValue rotation vector y component ##
#Example
-// incomplete
+#Description
+Canvas needs offset after applying Matrix to pivot about Rect center.
+##
+#Height 128
+ SkPaint paint;
+ paint.setColor(SK_ColorGRAY);
+ paint.setAntiAlias(true);
+ SkRect rect = {20, 20, 100, 100};
+ canvas->drawRect(rect, paint);
+ paint.setColor(SK_ColorRED);
+ SkMatrix matrix;
+ matrix.setSinCos(.25f, .85f);
+ matrix.postTranslate(rect.centerX(), rect.centerY());
+ canvas->concat(matrix);
+ canvas->translate(-rect.centerX(), -rect.centerY());
+ canvas->drawRect(rect, paint);
##
-#ToDo incomplete ##
+#SeeAlso setRotate setScale setRSXform
-##
+#Method ##
# ------------------------------------------------------------------------------
#Method SkMatrix& setRSXform(const SkRSXform& rsxForm)
-#Param rsxForm incomplete ##
+Sets Matrix to rotate, scale, and translate using a compressed matrix form.
+
+Vector (rsxForm.fSSin, rsxForm.fSCos) describes the angle of rotation relative
+to (0, 1). Vector length specifies scale. Mapped point is rotated and scaled
+by Vector, then translated by (rsxForm.fTx, rsxForm.fTy).
-#Return incomplete ##
+#Param rsxForm compressed RSXform matrix ##
+
+#Return reference to Matrix ##
#Example
-// incomplete
+#Description
+Canvas needs offset after applying Matrix to pivot about Rect center.
+##
+#Height 128
+ SkPaint paint;
+ paint.setColor(SK_ColorGRAY);
+ paint.setAntiAlias(true);
+ SkRect rect = {20, 20, 100, 100};
+ canvas->drawRect(rect, paint);
+ paint.setColor(SK_ColorRED);
+ SkMatrix matrix;
+ matrix.setRSXform(SkRSXform::Make(.85f, .25f, rect.centerX(), rect.centerY()));
+ canvas->concat(matrix);
+ canvas->translate(-rect.centerX(), -rect.centerY());
+ canvas->drawRect(rect, paint);
##
-#ToDo incomplete ##
+#SeeAlso setSinCos setScale setTranslate
-##
+#Method ##
# ------------------------------------------------------------------------------
#Method void setSkew(SkScalar kx, SkScalar ky, SkScalar px, SkScalar py)
-Set the matrix to skew by kx and ky, with a pivot point at (px, py).
-The pivot point is the coordinate that should remain unchanged by the
-specified transformation.
+Sets Matrix to skew by kx and ky, about a pivot point at (px, py).
+The pivot point is unchanged when mapped with Matrix.
-#Param kx incomplete ##
-#Param ky incomplete ##
-#Param px incomplete ##
-#Param py incomplete ##
+#Param kx horizontal skew factor ##
+#Param ky vertical skew factor ##
+#Param px pivot x ##
+#Param py pivot y ##
#Example
-// incomplete
+ SkPaint p;
+ p.setAntiAlias(true);
+ p.setTextSize(48);
+ SkMatrix m;
+ for (SkScalar sx : { -1, 0, 1 } ) {
+ for (SkScalar sy : { -1, 0, 1 } ) {
+ SkAutoCanvasRestore autoRestore(canvas, true);
+ m.setSkew(sx, sy, 96 + 64 * sx, 128 + 48 * sy);
+ canvas->concat(m);
+ canvas->drawString("K", 96 + 64 * sx, 128 + 48 * sy, p);
+ }
+ }
##
-#ToDo incomplete ##
+#SeeAlso setSkewX setSkewY preSkew postSkew
-##
+#Method ##
# ------------------------------------------------------------------------------
#Method void setSkew(SkScalar kx, SkScalar ky)
-Set the matrix to skew by kx and ky.
+Sets Matrix to skew by kx and ky, about a pivot point at (0, 0).
-#Param kx incomplete ##
-#Param ky incomplete ##
+#Param kx horizontal skew factor ##
+#Param ky vertical skew factor ##
#Example
-// incomplete
+ SkPaint p;
+ p.setAntiAlias(true);
+ p.setTextSize(48);
+ SkMatrix m;
+ for (SkScalar sx : { -1, 0, 1 } ) {
+ for (SkScalar sy : { -1, 0, 1 } ) {
+ SkAutoCanvasRestore autoRestore(canvas, true);
+ m.setSkew(sx, sy);
+ m.postTranslate(96 + 64 * sx, 128 + 48 * sy);
+ canvas->concat(m);
+ canvas->drawString("K", 0, 0, p);
+ }
+ }
##
-#ToDo incomplete ##
+#SeeAlso setSkewX setSkewY preSkew postSkew
-##
+#Method ##
# ------------------------------------------------------------------------------
#Method void setConcat(const SkMatrix& a, const SkMatrix& b)
-Set the matrix to the concatenation of the two specified matrices.
-Either of the two matrices may also be the target matrix.
-this = a * b;
+Sets Matrix to Matrix a multiplied by Matrix b. Either a or b may be this.
-#Param a incomplete ##
-#Param b incomplete ##
+Given:
-#Example
-// incomplete
+#Code
+#Literal
+ | A B C | | J K L |
+a = | D E F |, b = | M N O |
+ | G H I | | P Q R |
##
-#ToDo incomplete ##
+sets Matrix to:
+#Code
+#Literal
+ | A B C | | J K L | | AJ+BM+CP AK+BN+CQ AL+BO+CR |
+a * b = | D E F | * | M N O | = | DJ+EM+FP DK+EN+FQ DL+EO+FR |
+ | G H I | | P Q R | | GJ+HM+IP GK+HN+IQ GL+HO+IR |
##
+#Param a Matrix on left side of multiply expression ##
+#Param b Matrix on right side of multiply expression ##
+
+#Example
+#Image 3
+#Description
+setPolyToPoly creates perspective matrices, one the inverse of the other.
+Multiplying the matrix by its inverse turns into an identity matrix.
+##
+SkMatrix matrix, matrix2;
+SkPoint bitmapBounds[4], perspect[4] = {{50, 10}, {180, 40}, {236, 176}, {10, 206}};
+SkRect::Make(source.bounds()).toQuad(bitmapBounds);
+matrix.setPolyToPoly(bitmapBounds, perspect, 4);
+matrix2.setPolyToPoly(perspect, bitmapBounds, 4);
+matrix.setConcat(matrix, matrix2);
+canvas->concat(matrix);
+canvas->drawBitmap(source, 0, 0);
+##
+
+#SeeAlso Concat preConcat postConcat SkCanvas::concat
+
+#Method ##
+
# ------------------------------------------------------------------------------
#Method void preTranslate(SkScalar dx, SkScalar dy)
-Preconcats the matrix with the specified translation.
-#Formula
-M' = M * T(dx, dy)
-##
+Sets Matrix to Matrix multiplied by Matrix constructed from translation (dx, dy).
+This can be thought of as moving the point to be mapped before applying Matrix.
-#Param dx incomplete ##
-#Param dy incomplete ##
+Given:
-#Example
-// incomplete
+#Code
+#Literal
+ | A B C | | 1 0 dx |
+Matrix = | D E F |, T(dx, dy) = | 0 1 dy |
+ | G H I | | 0 0 1 |
##
-#ToDo incomplete ##
+sets Matrix to:
+#Code
+#Literal
+ | A B C | | 1 0 dx | | A B A*dx+B*dy+C |
+Matrix * T(dx, dy) = | D E F | | 0 1 dy | = | D E D*dx+E*dy+F |
+ | G H I | | 0 0 1 | | G H G*dx+H*dy+I |
##
+#Param dx x translation before applying Matrix ##
+#Param dy y translation before applying Matrix ##
+
+#Example
+#Height 160
+ SkPaint paint;
+ paint.setAntiAlias(true);
+ SkRect rect = {20, 20, 100, 100};
+ for (int i = 0; i < 2; ++i ) {
+ SkMatrix matrix;
+ i == 0 ? matrix.reset(): matrix.setRotate(25, rect.centerX(), 320);
+ {
+ SkAutoCanvasRestore acr(canvas, true);
+ canvas->concat(matrix);
+ paint.setColor(SK_ColorGRAY);
+ canvas->drawRect(rect, paint);
+ }
+ paint.setColor(SK_ColorRED);
+ for (int j = 0; j < 2; ++j ) {
+ SkAutoCanvasRestore acr(canvas, true);
+ matrix.preTranslate(40, 40);
+ canvas->concat(matrix);
+ canvas->drawCircle(0, 0, 3, paint);
+ }
+ }
+##
+
+#SeeAlso postTranslate setTranslate MakeTrans
+
+#Method ##
+
# ------------------------------------------------------------------------------
#Method void preScale(SkScalar sx, SkScalar sy, SkScalar px, SkScalar py)
-Preconcats the matrix with the specified scale.
-#Formula
-M' = M * S(sx, sy, px, py)
+Sets Matrix to Matrix multiplied by Matrix constructed from scaling by (sx, sy)
+about pivot point (px, py).
+This can be thought of as scaling about a pivot point before applying Matrix.
+
+Given:
+
+#Code
+#Literal
+ | A B C | | sx 0 dx |
+Matrix = | D E F |, S(sx, sy, px, py) = | 0 sy dy |
+ | G H I | | 0 0 1 |
##
-#Param sx incomplete ##
-#Param sy incomplete ##
-#Param px incomplete ##
-#Param py incomplete ##
+where
-#Example
-// incomplete
+#Code
+#Literal
+dx = px - sx * px
+dy = py - sy * py
+##
+
+sets Matrix to:
+
+#Code
+#Literal
+ | A B C | | sx 0 dx | | A*sx B*sy A*dx+B*dy+C |
+Matrix * S(sx, sy, px, py) = | D E F | | 0 sy dy | = | D*sx E*sy D*dx+E*dy+F |
+ | G H I | | 0 0 1 | | G*sx H*sy G*dx+H*dy+I |
##
-#ToDo incomplete ##
+#Param sx horizontal scale factor ##
+#Param sy vertical scale factor ##
+#Param px pivot x ##
+#Param py pivot y ##
+#Example
+#Image 3
+SkMatrix matrix;
+SkPoint bitmapBounds[4], perspect[4] = {{50, 10}, {180, 40}, {236, 176}, {10, 206}};
+SkRect::Make(source.bounds()).toQuad(bitmapBounds);
+matrix.setPolyToPoly(bitmapBounds, perspect, 4);
+matrix.preScale(.75f, 1.5f, source.width() / 2, source.height() / 2);
+canvas->concat(matrix);
+canvas->drawBitmap(source, 0, 0);
##
+#SeeAlso postScale setScale MakeScale
+
+#Method ##
+
# ------------------------------------------------------------------------------
#Method void preScale(SkScalar sx, SkScalar sy)
-Preconcats the matrix with the specified scale.
-#Formula
-M' = M * S(sx, sy)
+Sets Matrix to Matrix multiplied by Matrix constructed from scaling by (sx, sy)
+about pivot point (0, 0).
+This can be thought of as scaling about the origin before applying Matrix.
+
+Given:
+
+#Code
+#Literal
+ | A B C | | sx 0 0 |
+Matrix = | D E F |, S(sx, sy) = | 0 sy 0 |
+ | G H I | | 0 0 1 |
##
-#Param sx incomplete ##
-#Param sy incomplete ##
+sets Matrix to:
-#Example
-// incomplete
+#Code
+#Literal
+ | A B C | | sx 0 0 | | A*sx B*sy C |
+Matrix * S(sx, sy) = | D E F | | 0 sy 0 | = | D*sx E*sy F |
+ | G H I | | 0 0 1 | | G*sx H*sy I |
##
-#ToDo incomplete ##
+#Param sx horizontal scale factor ##
+#Param sy vertical scale factor ##
+#Example
+#Image 3
+SkMatrix matrix;
+SkPoint bitmapBounds[4], perspect[4] = {{50, 10}, {180, 40}, {236, 176}, {10, 206}};
+SkRect::Make(source.bounds()).toQuad(bitmapBounds);
+matrix.setPolyToPoly(bitmapBounds, perspect, 4);
+matrix.preScale(.75f, 1.5f);
+canvas->concat(matrix);
+canvas->drawBitmap(source, 0, 0);
##
+#SeeAlso postScale setScale MakeScale
+
+#Method ##
+
# ------------------------------------------------------------------------------
#Method void preRotate(SkScalar degrees, SkScalar px, SkScalar py)
-Preconcats the matrix with the specified rotation.
-#Formula
-M' = M * R(degrees, px, py)
+Sets Matrix to Matrix multiplied by Matrix constructed from rotating by degrees
+about pivot point (px, py).
+This can be thought of as rotating about a pivot point before applying Matrix.
+
+Positive degrees rotates clockwise.
+
+Given:
+
+#Code
+#Literal
+ | A B C | | c -s dx |
+Matrix = | D E F |, R(degrees, px, py) = | s c dy |
+ | G H I | | 0 0 1 |
##
-#Param degrees incomplete ##
-#Param px incomplete ##
-#Param py incomplete ##
+where
-#Example
-// incomplete
+#Code
+#Literal
+c = cos(degrees)
+s = sin(degrees)
+dx = s * py + (1 - c) * px
+dy = -s * px + (1 - c) * py
+##
+
+sets Matrix to:
+
+#Code
+#Literal
+ | A B C | | c -s dx | | Ac+Bs -As+Bc A*dx+B*dy+C |
+Matrix * R(degrees, px, py) = | D E F | | s c dy | = | Dc+Es -Ds+Ec D*dx+E*dy+F |
+ | G H I | | 0 0 1 | | Gc+Hs -Gs+Hc G*dx+H*dy+I |
##
-#ToDo incomplete ##
+#Param degrees angle of axes relative to upright axes ##
+#Param px pivot x ##
+#Param py pivot y ##
+#Example
+#Image 3
+SkMatrix matrix;
+SkPoint bitmapBounds[4], perspect[4] = {{50, 10}, {180, 40}, {236, 176}, {10, 206}};
+SkRect::Make(source.bounds()).toQuad(bitmapBounds);
+matrix.setPolyToPoly(bitmapBounds, perspect, 4);
+matrix.preRotate(45, source.width() / 2, source.height() / 2);
+canvas->concat(matrix);
+canvas->drawBitmap(source, 0, 0);
##
+#SeeAlso postRotate setRotate
+
+#Method ##
+
# ------------------------------------------------------------------------------
#Method void preRotate(SkScalar degrees)
-Preconcats the matrix with the specified rotation.
-#Formula
-M' = M * R(degrees)
+Sets Matrix to Matrix multiplied by Matrix constructed from rotating by degrees
+about pivot point (0, 0).
+This can be thought of as rotating about the origin before applying Matrix.
+
+Positive degrees rotates clockwise.
+
+Given:
+
+#Code
+#Literal
+ | A B C | | c -s 0 |
+Matrix = | D E F |, R(degrees, px, py) = | s c 0 |
+ | G H I | | 0 0 1 |
##
-#Param degrees incomplete ##
+where
-#Example
-// incomplete
+#Code
+#Literal
+c = cos(degrees)
+s = sin(degrees)
+##
+
+sets Matrix to:
+
+#Code
+#Literal
+ | A B C | | c -s 0 | | Ac+Bs -As+Bc C |
+Matrix * R(degrees, px, py) = | D E F | | s c 0 | = | Dc+Es -Ds+Ec F |
+ | G H I | | 0 0 1 | | Gc+Hs -Gs+Hc I |
##
-#ToDo incomplete ##
+#Param degrees angle of axes relative to upright axes ##
+#Example
+#Image 3
+SkMatrix matrix;
+SkPoint bitmapBounds[4], perspect[4] = {{50, 10}, {180, 40}, {236, 176}, {10, 206}};
+SkRect::Make(source.bounds()).toQuad(bitmapBounds);
+matrix.setPolyToPoly(bitmapBounds, perspect, 4);
+matrix.preRotate(45);
+canvas->concat(matrix);
+canvas->drawBitmap(source, 0, 0);
##
+#SeeAlso postRotate setRotate
+
+#Method ##
+
# ------------------------------------------------------------------------------
#Method void preSkew(SkScalar kx, SkScalar ky, SkScalar px, SkScalar py)
-Preconcats the matrix with the specified skew.
-#Formula
-M' = M * K(kx, ky, px, py)
+Sets Matrix to Matrix multiplied by Matrix constructed from skewing by (kx, ky)
+about pivot point (px, py).
+This can be thought of as skewing about a pivot point before applying Matrix.
+
+Given:
+
+#Code
+#Literal
+ | A B C | | 1 kx dx |
+Matrix = | D E F |, K(kx, ky, px, py) = | ky 1 dy |
+ | G H I | | 0 0 1 |
##
-#Param kx incomplete ##
-#Param ky incomplete ##
-#Param px incomplete ##
-#Param py incomplete ##
+where
-#Example
-// incomplete
+#Code
+#Literal
+dx = -kx * py
+dy = -ky * px
##
-#ToDo incomplete ##
+sets Matrix to:
+#Code
+#Literal
+ | A B C | | 1 kx dx | | A+B*ky A*kx+B A*dx+B*dy+C |
+Matrix * K(kx, ky, px, py) = | D E F | | ky 1 dy | = | D+E*ky D*kx+E D*dx+E*dy+F |
+ | G H I | | 0 0 1 | | G+H*ky G*kx+H G*dx+H*dy+I |
##
+#Param kx horizontal skew factor ##
+#Param ky vertical skew factor ##
+#Param px pivot x ##
+#Param py pivot y ##
+
+#Example
+#Image 3
+SkMatrix matrix;
+SkPoint bitmapBounds[4], perspect[4] = {{50, 10}, {180, 40}, {236, 176}, {10, 206}};
+SkRect::Make(source.bounds()).toQuad(bitmapBounds);
+matrix.setPolyToPoly(bitmapBounds, perspect, 4);
+matrix.preSkew(.5f, 0, source.width() / 2, source.height() / 2);
+canvas->concat(matrix);
+canvas->drawBitmap(source, 0, 0);
+##
+
+#SeeAlso postSkew setSkew
+
+#Method ##
+
# ------------------------------------------------------------------------------
#Method void preSkew(SkScalar kx, SkScalar ky)
-Preconcats the matrix with the specified skew.
-#Formula
-M' = M * K(kx, ky)
+Sets Matrix to Matrix multiplied by Matrix constructed from skewing by (kx, ky)
+about pivot point (0, 0).
+This can be thought of as skewing about the origin before applying Matrix.
+
+Given:
+
+#Code
+#Literal
+ | A B C | | 1 kx 0 |
+Matrix = | D E F |, K(kx, ky) = | ky 1 0 |
+ | G H I | | 0 0 1 |
##
-#Param kx incomplete ##
-#Param ky incomplete ##
+sets Matrix to:
-#Example
-// incomplete
+#Code
+#Literal
+ | A B C | | 1 kx 0 | | A+B*ky A*kx+B C |
+Matrix * K(kx, ky) = | D E F | | ky 1 0 | = | D+E*ky D*kx+E F |
+ | G H I | | 0 0 1 | | G+H*ky G*kx+H I |
##
-#ToDo incomplete ##
+#Param kx horizontal skew factor ##
+#Param ky vertical skew factor ##
+#Example
+#Image 3
+SkMatrix matrix;
+SkPoint bitmapBounds[4], perspect[4] = {{50, 10}, {180, 40}, {236, 176}, {10, 206}};
+SkRect::Make(source.bounds()).toQuad(bitmapBounds);
+matrix.setPolyToPoly(bitmapBounds, perspect, 4);
+matrix.preSkew(.5f, 0);
+canvas->concat(matrix);
+canvas->drawBitmap(source, 0, 0);
##
+#SeeAlso postSkew setSkew
+
+#Method ##
+
# ------------------------------------------------------------------------------
#Method void preConcat(const SkMatrix& other)
-Preconcats the matrix with the specified matrix.
-#Formula
-M' = M * other
+Sets Matrix to Matrix multiplied by Matrix other.
+This can be thought of mapping by other before applying Matrix.
+
+Given:
+
+#Code
+#Literal
+ | A B C | | J K L |
+Matrix = | D E F |, other = | M N O |
+ | G H I | | P Q R |
##
-#Param other incomplete ##
+sets Matrix to:
-#Example
-// incomplete
+#Code
+#Literal
+ | A B C | | J K L | | AJ+BM+CP AK+BN+CQ AL+BO+CR |
+Matrix * other = | D E F | * | M N O | = | DJ+EM+FP DK+EN+FQ DL+EO+FR |
+ | G H I | | P Q R | | GJ+HM+IP GK+HN+IQ GL+HO+IR |
##
-#ToDo incomplete ##
+#Param other Matrix on right side of multiply expression ##
+#Example
+#Image 3
+#Description
+setPolyToPoly creates perspective matrices, one the inverse of the other.
+Multiplying the matrix by its inverse turns into an identity matrix.
+##
+SkMatrix matrix, matrix2;
+SkPoint bitmapBounds[4], perspect[4] = {{50, 10}, {180, 40}, {236, 176}, {10, 206}};
+SkRect::Make(source.bounds()).toQuad(bitmapBounds);
+matrix.setPolyToPoly(bitmapBounds, perspect, 4);
+matrix2.setPolyToPoly(perspect, bitmapBounds, 4);
+matrix.preConcat(matrix2);
+canvas->concat(matrix);
+canvas->drawBitmap(source, 0, 0);
##
+#SeeAlso postConcat setConcat Concat
+
+#Method ##
+
# ------------------------------------------------------------------------------
#Method void postTranslate(SkScalar dx, SkScalar dy)
-Postconcats the matrix with the specified translation.
-#Formula
-M' = T(dx, dy) * M
-##
+Sets Matrix to Matrix constructed from translation (dx, dy) multiplied by Matrix.
+This can be thought of as moving the point to be mapped after applying Matrix.
-#Param dx incomplete ##
-#Param dy incomplete ##
+Given:
-#Example
-// incomplete
+#Code
+#Literal
+ | J K L | | 1 0 dx |
+Matrix = | M N O |, T(dx, dy) = | 0 1 dy |
+ | P Q R | | 0 0 1 |
##
-#ToDo incomplete ##
+sets Matrix to:
+#Code
+#Literal
+ | 1 0 dx | | J K L | | J+dx*P K+dx*Q L+dx*R |
+T(dx, dy) * Matrix = | 0 1 dy | | M N O | = | M+dy*P N+dy*Q O+dy*R |
+ | 0 0 1 | | P Q R | | P Q R |
##
+#Param dx x translation after applying Matrix ##
+#Param dy y translation after applying Matrix ##
+
+#Example
+#Height 160
+#Description
+Compare with preTranslate example.
+##
+ SkPaint paint;
+ paint.setAntiAlias(true);
+ SkRect rect = {20, 20, 100, 100};
+ for (int i = 0; i < 2; ++i ) {
+ SkMatrix matrix;
+ i == 0 ? matrix.reset(): matrix.setRotate(25, rect.centerX(), 320);
+ {
+ SkAutoCanvasRestore acr(canvas, true);
+ canvas->concat(matrix);
+ paint.setColor(SK_ColorGRAY);
+ canvas->drawRect(rect, paint);
+ }
+ paint.setColor(SK_ColorRED);
+ for (int j = 0; j < 2; ++j ) {
+ SkAutoCanvasRestore acr(canvas, true);
+ matrix.postTranslate(40, 40);
+ canvas->concat(matrix);
+ canvas->drawCircle(0, 0, 3, paint);
+ }
+ }
+##
+
+#SeeAlso preTranslate setTranslate MakeTrans
+
+#Method ##
+
# ------------------------------------------------------------------------------
#Method void postScale(SkScalar sx, SkScalar sy, SkScalar px, SkScalar py)
-Postconcats the matrix with the specified scale.
-#Formula
-M' = S(sx, sy, px, py) * M
+Sets Matrix to Matrix constructed from scaling by (sx, sy) about pivot point
+(px, py), multiplied by Matrix.
+This can be thought of as scaling about a pivot point after applying Matrix.
+
+Given:
+
+#Code
+#Literal
+ | J K L | | sx 0 dx |
+Matrix = | M N O |, S(sx, sy, px, py) = | 0 sy dy |
+ | P Q R | | 0 0 1 |
##
-#Param sx incomplete ##
-#Param sy incomplete ##
-#Param px incomplete ##
-#Param py incomplete ##
+where
+
+#Code
+#Literal
+dx = px - sx * px
+dy = py - sy * py
+##
+
+sets Matrix to:
+
+#Code
+#Literal
+ | sx 0 dx | | J K L | | sx*J+dx*P sx*K+dx*Q sx*L+dx+R |
+S(sx, sy, px, py) * Matrix = | 0 sy dy | | M N O | = | sy*M+dy*P sy*N+dy*Q sy*O+dy*R |
+ | 0 0 1 | | P Q R | | P Q R |
+##
+
+#Param sx horizontal scale factor ##
+#Param sy vertical scale factor ##
+#Param px pivot x ##
+#Param py pivot y ##
#Example
-// incomplete
+#Image 3
+SkMatrix matrix;
+SkPoint bitmapBounds[4], perspect[4] = {{50, 10}, {180, 40}, {236, 176}, {10, 206}};
+SkRect::Make(source.bounds()).toQuad(bitmapBounds);
+matrix.setPolyToPoly(bitmapBounds, perspect, 4);
+matrix.postScale(.75f, 1.5f, source.width() / 2, source.height() / 2);
+canvas->concat(matrix);
+canvas->drawBitmap(source, 0, 0);
##
-#ToDo incomplete ##
+#SeeAlso preScale setScale MakeScale
##
@@ -1285,19 +2371,43 @@ M' = S(sx, sy, px, py) * M
#Method void postScale(SkScalar sx, SkScalar sy)
-Postconcats the matrix with the specified scale.
-#Formula
-M' = S(sx, sy) * M
+Sets Matrix to Matrix constructed from scaling by (sx, sy) about pivot point
+(0, 0), multiplied by Matrix.
+This can be thought of as scaling about the origin after applying Matrix.
+
+Given:
+
+#Code
+#Literal
+ | J K L | | sx 0 0 |
+Matrix = | M N O |, S(sx, sy) = | 0 sy 0 |
+ | P Q R | | 0 0 1 |
##
-#Param sx incomplete ##
-#Param sy incomplete ##
+sets Matrix to:
+
+#Code
+#Literal
+ | sx 0 0 | | J K L | | sx*J sx*K sx*L |
+S(sx, sy) * Matrix = | 0 sy 0 | | M N O | = | sy*M sy*N sy*O |
+ | 0 0 1 | | P Q R | | P Q R |
+##
+
+#Param sx horizontal scale factor ##
+#Param sy vertical scale factor ##
#Example
-// incomplete
+#Image 3
+SkMatrix matrix;
+SkPoint bitmapBounds[4], perspect[4] = {{50, 10}, {180, 40}, {236, 176}, {10, 206}};
+SkRect::Make(source.bounds()).toQuad(bitmapBounds);
+matrix.setPolyToPoly(bitmapBounds, perspect, 4);
+matrix.postScale(.75f, 1.5f);
+canvas->concat(matrix);
+canvas->drawBitmap(source, 0, 0);
##
-#ToDo incomplete ##
+#SeeAlso preScale setScale MakeScale
##
@@ -1305,21 +2415,57 @@ M' = S(sx, sy) * M
#Method bool postIDiv(int divx, int divy)
-Postconcats the matrix by dividing it by the specified integers.
+Sets Matrix to Matrix constructed from scaling by
#Formula
-M' = S(1/divx, 1/divy, 0, 0) * M
+(1/divx, 1/divy)
##
+about pivot point (px, py), multiplied by Matrix.
-#Param divx incomplete ##
-#Param divy incomplete ##
+Returns false if either divx or divy is zero.
-#Return incomplete ##
+Given:
+
+#Code
+#Literal
+ | J K L | | sx 0 0 |
+Matrix = | M N O |, I(divx, divy) = | 0 sy 0 |
+ | P Q R | | 0 0 1 |
+##
+
+where
+
+#Code
+#Literal
+sx = 1 / divx
+sy = 1 / divy
+##
+
+sets Matrix to:
+
+#Code
+#Literal
+ | sx 0 0 | | J K L | | sx*J sx*K sx*L |
+I(divx, divy) * Matrix = | 0 sy 0 | | M N O | = | sy*M sy*N sy*O |
+ | 0 0 1 | | P Q R | | P Q R |
+##
+
+#Param divx integer divisor for inverse scale in x ##
+#Param divy integer divisor for inverse scale in y ##
+
+#Return true on successful scale ##
#Example
-// incomplete
+#Image 3
+SkMatrix matrix, matrix2;
+SkPoint bitmapBounds[4], perspect[4] = {{50, 10}, {180, 40}, {236, 176}, {10, 206}};
+SkRect::Make(source.bounds()).toQuad(bitmapBounds);
+matrix.setPolyToPoly(bitmapBounds, perspect, 4);
+matrix.postIDiv(1, 2);
+canvas->concat(matrix);
+canvas->drawBitmap(source, 0, 0);
##
-#ToDo incomplete ##
+#SeeAlso postScale MakeScale
##
@@ -1327,20 +2473,56 @@ M' = S(1/divx, 1/divy, 0, 0) * M
#Method void postRotate(SkScalar degrees, SkScalar px, SkScalar py)
-Postconcats the matrix with the specified rotation.
-#Formula
-M' = R(degrees, px, py) * M
+Sets Matrix to Matrix constructed from rotating by degrees about pivot point
+(px, py), multiplied by Matrix.
+This can be thought of as rotating about a pivot point after applying Matrix.
+
+Positive degrees rotates clockwise.
+
+Given:
+
+#Code
+#Literal
+ | J K L | | c -s dx |
+Matrix = | M N O |, R(degrees, px, py) = | s c dy |
+ | P Q R | | 0 0 1 |
##
-#Param degrees incomplete ##
-#Param px incomplete ##
-#Param py incomplete ##
+where
+
+#Code
+#Literal
+c = cos(degrees)
+s = sin(degrees)
+dx = s * py + (1 - c) * px
+dy = -s * px + (1 - c) * py
+##
+
+sets Matrix to:
+
+#Code
+#Literal
+ |c -s dx| |J K L| |cJ-sM+dx*P cK-sN+dx*Q cL-sO+dx+R|
+R(degrees, px, py) * Matrix = |s c dy| |M N O| = |sJ+cM+dy*P sK+cN+dy*Q sL+cO+dy*R|
+ |0 0 1| |P Q R| | P Q R|
+##
+
+#Param degrees angle of axes relative to upright axes ##
+#Param px pivot x ##
+#Param py pivot y ##
#Example
-// incomplete
+#Image 3
+SkMatrix matrix;
+SkPoint bitmapBounds[4], perspect[4] = {{50, 10}, {180, 40}, {236, 176}, {10, 206}};
+SkRect::Make(source.bounds()).toQuad(bitmapBounds);
+matrix.setPolyToPoly(bitmapBounds, perspect, 4);
+matrix.postRotate(45, source.width() / 2, source.height() / 2);
+canvas->concat(matrix);
+canvas->drawBitmap(source, 0, 0);
##
-#ToDo incomplete ##
+#SeeAlso preRotate setRotate
##
@@ -1348,18 +2530,52 @@ M' = R(degrees, px, py) * M
#Method void postRotate(SkScalar degrees)
-Postconcats the matrix with the specified rotation.
-#Formula
-M' = R(degrees) * M
+Sets Matrix to Matrix constructed from rotating by degrees about pivot point
+(0, 0), multiplied by Matrix.
+This can be thought of as rotating about the origin after applying Matrix.
+
+Positive degrees rotates clockwise.
+
+Given:
+
+#Code
+#Literal
+ | J K L | | c -s 0 |
+Matrix = | M N O |, R(degrees, px, py) = | s c 0 |
+ | P Q R | | 0 0 1 |
+##
+
+where
+
+#Code
+#Literal
+c = cos(degrees)
+s = sin(degrees)
##
-#Param degrees incomplete ##
+sets Matrix to:
+
+#Code
+#Literal
+ | c -s dx | | J K L | | cJ-sM cK-sN cL-sO |
+R(degrees, px, py) * Matrix = | s c dy | | M N O | = | sJ+cM sK+cN sL+cO |
+ | 0 0 1 | | P Q R | | P Q R |
+##
+
+#Param degrees angle of axes relative to upright axes ##
#Example
-// incomplete
+#Image 3
+SkMatrix matrix;
+SkPoint bitmapBounds[4], perspect[4] = {{50, 10}, {180, 40}, {236, 176}, {10, 206}};
+SkRect::Make(source.bounds()).toQuad(bitmapBounds);
+matrix.setPolyToPoly(bitmapBounds, perspect, 4);
+matrix.postRotate(45);
+canvas->concat(matrix);
+canvas->drawBitmap(source, 0, 0);
##
-#ToDo incomplete ##
+#SeeAlso preRotate setRotate
##
@@ -1367,21 +2583,53 @@ M' = R(degrees) * M
#Method void postSkew(SkScalar kx, SkScalar ky, SkScalar px, SkScalar py)
-Postconcats the matrix with the specified skew.
-#Formula
-M' = K(kx, ky, px, py) * M
+Sets Matrix to Matrix constructed from skewing by (kx, ky) about pivot point
+(px, py), multiplied by Matrix.
+This can be thought of as skewing about a pivot point after applying Matrix.
+
+Given:
+
+#Code
+#Literal
+ | J K L | | 1 kx dx |
+Matrix = | M N O |, K(kx, ky, px, py) = | ky 1 dy |
+ | P Q R | | 0 0 1 |
+##
+
+where
+
+#Code
+#Literal
+dx = -kx * py
+dy = -ky * px
##
-#Param kx incomplete ##
-#Param ky incomplete ##
-#Param px incomplete ##
-#Param py incomplete ##
+sets Matrix to:
+
+#Code
+#Literal
+ | 1 kx dx| |J K L| |J+kx*M+dx*P K+kx*N+dx*Q L+kx*O+dx+R|
+K(kx, ky, px, py) * Matrix = |ky 1 dy| |M N O| = |ky*J+M+dy*P ky*K+N+dy*Q ky*L+O+dy*R|
+ | 0 0 1| |P Q R| | P Q R|
+##
+
+#Param kx horizontal skew factor ##
+#Param ky vertical skew factor ##
+#Param px pivot x ##
+#Param py pivot y ##
#Example
-// incomplete
+#Image 3
+SkMatrix matrix;
+SkPoint bitmapBounds[4], perspect[4] = {{50, 10}, {180, 40}, {236, 176}, {10, 206}};
+SkRect::Make(source.bounds()).toQuad(bitmapBounds);
+matrix.setPolyToPoly(bitmapBounds, perspect, 4);
+matrix.postSkew(.5f, 0, source.width() / 2, source.height() / 2);
+canvas->concat(matrix);
+canvas->drawBitmap(source, 0, 0);
##
-#ToDo incomplete ##
+#SeeAlso preSkew setSkew
##
@@ -1389,19 +2637,43 @@ M' = K(kx, ky, px, py) * M
#Method void postSkew(SkScalar kx, SkScalar ky)
-Postconcats the matrix with the specified skew.
-#Formula
-M' = K(kx, ky) * M
+Sets Matrix to Matrix constructed from skewing by (kx, ky) about pivot point
+(0, 0), multiplied by Matrix.
+This can be thought of as skewing about the origin after applying Matrix.
+
+Given:
+
+#Code
+#Literal
+ | J K L | | 1 kx 0 |
+Matrix = | M N O |, K(kx, ky) = | ky 1 0 |
+ | P Q R | | 0 0 1 |
##
-#Param kx incomplete ##
-#Param ky incomplete ##
+sets Matrix to:
+
+#Code
+#Literal
+ | 1 kx 0 | | J K L | | J+kx*M K+kx*N L+kx*O |
+K(kx, ky) * Matrix = | ky 1 0 | | M N O | = | ky*J+M ky*K+N ky*L+O |
+ | 0 0 1 | | P Q R | | P Q R |
+##
+
+#Param kx horizontal skew factor ##
+#Param ky vertical skew factor ##
#Example
-// incomplete
+#Image 3
+SkMatrix matrix;
+SkPoint bitmapBounds[4], perspect[4] = {{50, 10}, {180, 40}, {236, 176}, {10, 206}};
+SkRect::Make(source.bounds()).toQuad(bitmapBounds);
+matrix.setPolyToPoly(bitmapBounds, perspect, 4);
+matrix.postSkew(.5f, 0);
+canvas->concat(matrix);
+canvas->drawBitmap(source, 0, 0);
##
-#ToDo incomplete ##
+#SeeAlso preSkew setSkew
##
@@ -1409,18 +2681,42 @@ M' = K(kx, ky) * M
#Method void postConcat(const SkMatrix& other)
-Postconcats the matrix with the specified matrix.
-#Formula
-M' = other * M
+Sets Matrix to Matrix other multiplied by Matrix.
+This can be thought of mapping by other after applying Matrix.
+
+Given:
+
+#Code
+#Literal
+ | J K L | | A B C |
+Matrix = | M N O |, other = | D E F |
+ | P Q R | | G H I |
##
-#Param other incomplete ##
+sets Matrix to:
+
+#Code
+#Literal
+ | A B C | | J K L | | AJ+BM+CP AK+BN+CQ AL+BO+CR |
+other * Matrix = | D E F | * | M N O | = | DJ+EM+FP DK+EN+FQ DL+EO+FR |
+ | G H I | | P Q R | | GJ+HM+IP GK+HN+IQ GL+HO+IR |
+##
+
+#Param other Matrix on left side of multiply expression ##
#Example
-// incomplete
+#Image 3
+#Height 64
+SkMatrix matrix, matrix2;
+SkPoint bitmapBounds[4], perspect[4] = {{50, 10}, {180, 40}, {236, 176}, {10, 206}};
+SkRect::Make(source.bounds()).toQuad(bitmapBounds);
+matrix.setPolyToPoly(bitmapBounds, perspect, 4);
+matrix.postConcat(matrix);
+canvas->concat(matrix);
+canvas->drawBitmap(source, 0, 0);
##
-#ToDo incomplete ##
+#SeeAlso preConcat setConcat Concat
##
@@ -1437,33 +2733,57 @@ M' = other * M
};
##
-#Const kFill_ScaleToFit
-Scale in X and Y independently, so that src matches dst exactly.
-This may change the aspect ratio of the src.
+ScaleToFit describes how Matrix is constructed to map one Rect to another.
+ScaleToFit may allow Matrix to have unequal horizontal and vertical scaling,
+or may restrict Matrix to square scaling. If restricted, ScaleToFit specifies
+how Matrix maps to the side or center of the destination Rect.
+
+#Const kFill_ScaleToFit 0
+ Computes Matrix that scales in x and y independently, so that source Rect is
+ mapped to completely fill destination Rect. The aspect ratio of source Rect
+ may change.
##
-#Const kStart_ScaleToFit
-Compute a scale that will maintain the original src aspect ratio,
-but will also ensure that src fits entirely inside dst. At least one
-axis (x or y) will fit exactly. Aligns the result to the
-left and top edges of dst.
+#Const kStart_ScaleToFit 1
+ Computes Matrix that maintains source Rect aspect ratio, mapping source Rect
+ width or height to destination Rect. Aligns mapping to left and top edges
+ of destination Rect.
##
-#Const kCenter_ScaleToFit
-Compute a scale that will maintain the original src aspect ratio,
-but will also ensure that src fits entirely inside dst. At least one
-axis (x or y) will fit exactly. The result is centered inside dst.
+#Const kCenter_ScaleToFit 2
+ Computes Matrix that maintains source Rect aspect ratio, mapping source Rect
+ width or height to destination Rect. Aligns mapping to center of destination
+ Rect.
##
-#Const kEnd_ScaleToFit
-Compute a scale that will maintain the original src aspect ratio,
-but will also ensure that src fits entirely inside dst. At least one
-axis (x or y) will fit exactly. Aligns the result to the
-right and bottom edges of dst.
+#Const kEnd_ScaleToFit 3
+ Computes Matrix that maintains source Rect aspect ratio, mapping source Rect
+ width or height to destination Rect. Aligns mapping to right and bottom
+ edges of destination Rect.
##
#Example
-// incomplete
-##
-
-#ToDo incomplete ##
+ const char* labels[] = { "Fill", "Start", "Center", "End" };
+ SkRect rects[] = {{5, 5, 59, 59}, {5, 74, 59, 108}, {10, 123, 44, 172}, {10, 187, 54, 231}};
+ SkRect bounds;
+ source.getBounds(&bounds);
+ SkPaint paint;
+ paint.setAntiAlias(true);
+ for (auto fit : { SkMatrix::kFill_ScaleToFit, SkMatrix::kStart_ScaleToFit,
+ SkMatrix::kCenter_ScaleToFit, SkMatrix::kEnd_ScaleToFit } ) {
+ for (auto rect : rects ) {
+ canvas->drawRect(rect, paint);
+ SkMatrix matrix;
+ if (!matrix.setRectToRect(bounds, rect, fit)) {
+ continue;
+ }
+ SkAutoCanvasRestore acr(canvas, true);
+ canvas->concat(matrix);
+ canvas->drawBitmap(source, 0, 0);
+ }
+ canvas->drawString(labels[fit], 10, 255, paint);
+ canvas->translate(64, 0);
+ }
+##
+
+#SeeAlso setRectToRect MakeRectToRect setPolyToPoly
##
@@ -1471,25 +2791,53 @@ right and bottom edges of dst.
#Method bool setRectToRect(const SkRect& src, const SkRect& dst, ScaleToFit stf)
-Set the matrix to the scale and translate values that map the source
-rectangle to the destination rectangle, returning true if the the result
-can be represented.
+Sets Matrix to scale and translate src Rect to dst Rect. stf selects whether
+mapping completely fills dst or preserves the aspect ratio, and how to align
+src within dst. Returns false if src is empty, and sets Matrix to identity.
+Returns true if dst is empty, and sets Matrix to:
-#Param src the source rectangle to map from
-##
-#Param dst the destination rectangle to map to
-##
-#Param stf the ScaleToFit option
+#Code
+#Literal
+| 0 0 0 |
+| 0 0 0 |
+| 0 0 1 |
##
-#Return true if the matrix can be represented by the rectangle mapping
+#Param src Rect to map from ##
+#Param dst Rect to map to ##
+#Param stf one of: kFill_ScaleToFit, kStart_ScaleToFit,
+ kCenter_ScaleToFit, kEnd_ScaleToFit
##
-#Example
-// incomplete
-##
+#Return true if Matrix can represent Rect mapping ##
-#ToDo incomplete ##
+#Example
+ const SkRect srcs[] = { {0, 0, 0, 0}, {1, 2, 3, 4} };
+ const SkRect dsts[] = { {0, 0, 0, 0}, {5, 6, 8, 9} };
+ for (auto src : srcs) {
+ for (auto dst : dsts) {
+ SkMatrix matrix;
+ matrix.setAll(-1, -1, -1, -1, -1, -1, -1, -1, -1);
+ bool success = matrix.setRectToRect(src, dst, SkMatrix::kFill_ScaleToFit);
+ SkDebugf("src: %g, %g, %g, %g dst: %g, %g, %g, %g success: %s\n",
+ src.fLeft, src.fTop, src.fRight, src.fBottom,
+ dst.fLeft, dst.fTop, dst.fRight, dst.fBottom, success ? "true" : "false");
+ matrix.dump();
+ }
+ }
+#StdOut
+src: 0, 0, 0, 0 dst: 0, 0, 0, 0 success: false
+[ 1.0000 0.0000 0.0000][ 0.0000 1.0000 0.0000][ 0.0000 0.0000 1.0000]
+src: 0, 0, 0, 0 dst: 5, 6, 8, 9 success: false
+[ 1.0000 0.0000 0.0000][ 0.0000 1.0000 0.0000][ 0.0000 0.0000 1.0000]
+src: 1, 2, 3, 4 dst: 0, 0, 0, 0 success: true
+[ 0.0000 0.0000 0.0000][ 0.0000 0.0000 0.0000][ 0.0000 0.0000 1.0000]
+src: 1, 2, 3, 4 dst: 5, 6, 8, 9 success: true
+[ 1.5000 0.0000 3.5000][ 0.0000 1.5000 3.0000][ 0.0000 0.0000 1.0000]
+##
+##
+
+#SeeAlso MakeRectToRect ScaleToFit setPolyToPoly SkRect::isEmpty
##
@@ -1497,17 +2845,51 @@ can be represented.
#Method static SkMatrix MakeRectToRect(const SkRect& src, const SkRect& dst, ScaleToFit stf)
-#Param src incomplete ##
-#Param dst incomplete ##
-#Param stf incomplete ##
+Returns Matrix set to scale and translate src Rect to dst Rect. stf selects
+whether mapping completely fills dst or preserves the aspect ratio, and how to
+align src within dst. Returns the identity Matrix if src is empty. If dst is
+empty, returns Matrix set to:
+
+#Code
+#Literal
+| 0 0 0 |
+| 0 0 0 |
+| 0 0 1 |
+##
+
+#Param src Rect to map from ##
+#Param dst Rect to map to ##
+#Param stf one of: kFill_ScaleToFit, kStart_ScaleToFit,
+ kCenter_ScaleToFit, kEnd_ScaleToFit
+##
-#Return incomplete ##
+#Return Matrix mapping src to dst ##
#Example
-// incomplete
+ const SkRect srcs[] = { {0, 0, 0, 0}, {1, 2, 3, 4} };
+ const SkRect dsts[] = { {0, 0, 0, 0}, {5, 6, 8, 9} };
+ for (auto src : srcs) {
+ for (auto dst : dsts) {
+ SkMatrix matrix = SkMatrix::MakeRectToRect(src, dst, SkMatrix::kFill_ScaleToFit);
+ SkDebugf("src: %g, %g, %g, %g dst: %g, %g, %g, %g\n",
+ src.fLeft, src.fTop, src.fRight, src.fBottom,
+ dst.fLeft, dst.fTop, dst.fRight, dst.fBottom);
+ matrix.dump();
+ }
+ }
+#StdOut
+src: 0, 0, 0, 0 dst: 0, 0, 0, 0
+[ 1.0000 0.0000 0.0000][ 0.0000 1.0000 0.0000][ 0.0000 0.0000 1.0000]
+src: 0, 0, 0, 0 dst: 5, 6, 8, 9
+[ 1.0000 0.0000 0.0000][ 0.0000 1.0000 0.0000][ 0.0000 0.0000 1.0000]
+src: 1, 2, 3, 4 dst: 0, 0, 0, 0
+[ 0.0000 0.0000 0.0000][ 0.0000 0.0000 0.0000][ 0.0000 0.0000 1.0000]
+src: 1, 2, 3, 4 dst: 5, 6, 8, 9
+[ 1.5000 0.0000 3.5000][ 0.0000 1.5000 3.0000][ 0.0000 0.0000 1.0000]
+##
##
-#ToDo incomplete ##
+#SeeAlso setRectToRect ScaleToFit setPolyToPoly SkRect::isEmpty
##
@@ -1515,24 +2897,49 @@ can be represented.
#Method bool setPolyToPoly(const SkPoint src[], const SkPoint dst[], int count)
-Set the matrix such that the specified src points would map to the
-specified dst points. count must be within [0..4].
+Sets Matrix to map src to dst. count must be zero or greater, and four or less.
-#Param src array of src points
-##
-#Param dst array of dst points
-##
-#Param count number of points to use for the transformation
-##
+If count is zero, sets Matrix to identity and returns true.
+If count is one, sets Matrix to translate and returns true.
+If count is two or more, sets Matrix to map Points if possible; returns false
+if Matrix cannot be constructed. If count is four, Matrix may include
+perspective.
-#Return true if the matrix was set to the specified transformation
-##
+#Param src Points to map from ##
+#Param dst Points to map to ##
+#Param count number of Points in src and dst ##
-#Example
-// incomplete
+#Return true if Matrix was constructed successfully
##
-#ToDo incomplete ##
+#Example
+ const SkPoint src[] = { { 0, 0}, {30, 0}, {30, -30}, { 0, -30} };
+ const SkPoint dst[] = { {50, 0}, {80, -10}, {90, -30}, {60, -40} };
+ SkPaint blackPaint;
+ blackPaint.setAntiAlias(true);
+ blackPaint.setTextSize(42);
+ SkPaint redPaint = blackPaint;
+ redPaint.setColor(SK_ColorRED);
+ for (int count : { 1, 2, 3, 4 } ) {
+ canvas->translate(35, 55);
+ for (int index = 0; index < count; ++index) {
+ canvas->drawCircle(src[index], 3, blackPaint);
+ canvas->drawCircle(dst[index], 3, blackPaint);
+ if (index > 0) {
+ canvas->drawLine(src[index], src[index - 1], blackPaint);
+ canvas->drawLine(dst[index], dst[index - 1], blackPaint);
+ }
+ }
+ SkMatrix matrix;
+ matrix.setPolyToPoly(src, dst, count);
+ canvas->drawString("A", src[0].fX, src[0].fY, redPaint);
+ SkAutoCanvasRestore acr(canvas, true);
+ canvas->concat(matrix);
+ canvas->drawString("A", src[0].fX, src[0].fY, redPaint);
+ }
+##
+
+#SeeAlso setRectToRect MakeRectToRect
##
@@ -1540,19 +2947,35 @@ specified dst points. count must be within [0..4].
#Method bool SK_WARN_UNUSED_RESULT invert(SkMatrix* inverse) const
-If this matrix can be inverted, return true and if inverse is not null,
-set inverse to be the inverse of this matrix. If this matrix cannot be
-inverted, ignore inverse and return false
+Sets inverse to reciprocal matrix, returning true if Matrix can be inverted.
+Geometrically, if Matrix maps from source to destination, inverse Matrix
+maps from destination to source. If Matrix can not be inverted, inverse is
+unchanged.
-#Param inverse incomplete ##
+#Param inverse storage for inverted Matrix; may be nullptr ##
-#Return incomplete ##
+#Return true if Matrix can be inverted ##
#Example
-// incomplete
+#Height 128
+ const SkPoint src[] = { { 10, 120}, {120, 120}, {120, 10}, { 10, 10} };
+ const SkPoint dst[] = { {150, 120}, {200, 100}, {240, 30}, { 130, 40} };
+ SkPaint paint;
+ paint.setAntiAlias(true);
+ SkMatrix matrix;
+ matrix.setPolyToPoly(src, dst, 4);
+ canvas->drawPoints(SkCanvas::kPolygon_PointMode, 4, src, paint);
+ canvas->drawPoints(SkCanvas::kPolygon_PointMode, 4, dst, paint);
+ paint.setColor(SK_ColorBLUE);
+ paint.setStrokeWidth(3);
+ paint.setStrokeCap(SkPaint::kRound_Cap);
+ canvas->drawPoints(SkCanvas::kPoints_PointMode, 4, dst, paint);
+ matrix.invert(&matrix);
+ canvas->concat(matrix);
+ canvas->drawPoints(SkCanvas::kPoints_PointMode, 4, dst, paint);
##
-#ToDo incomplete ##
+#SeeAlso Concat
##
@@ -1560,19 +2983,33 @@ inverted, ignore inverse and return false
#Method static void SetAffineIdentity(SkScalar affine[6])
-Fills the passed array with affine identity values
-in column major order.
+Fills affine with identity values in column major order.
+Sets affine to:
-#Param affine array to fill with affine identity values; must not be nullptr
+#Code
+#Literal
+| 1 0 0 |
+| 0 1 0 |
##
-#Return incomplete ##
+Affine 3x2 matrices in column major order are used by OpenGL and XPS.
+
+#Param affine storage for 3x2 affine matrix ##
#Example
-// incomplete
+ SkScalar affine[6];
+ SkMatrix::SetAffineIdentity(affine);
+ const char* names[] = { "ScaleX", "SkewY", "SkewX", "ScaleY", "TransX", "TransY" };
+ for (int i = 0; i < 6; ++i) {
+ SkDebugf("%s: %g ", names[i], affine[i]);
+ }
+ SkDebugf("\n");
+#StdOut
+ScaleX: 1 SkewY: 0 SkewX: 0 ScaleY: 1 TransX: 0 TransY: 0
+##
##
-#ToDo incomplete ##
+#SeeAlso setAffine asAffine
##
@@ -1580,20 +3017,36 @@ in column major order.
#Method bool SK_WARN_UNUSED_RESULT asAffine(SkScalar affine[6]) const
-Fills the passed array with the affine values in column major order.
-If the matrix is a perspective transform, returns false
-and does not change the passed array.
+Fills affine in column major order. Sets affine to:
-#Param affine array to fill with affine values; ignored if nullptr
+#Code
+#Literal
+| scale-x skew-x translate-x |
+| skew-y scale-y translate-y |
##
-#Return incomplete ##
+If Matrix contains perspective, returns false and leaves affine unchanged.
+
+#Param affine storage for 3x2 affine matrix; may be nullptr ##
+
+#Return true if Matrix does not contain perspective ##
#Example
-// incomplete
+SkMatrix matrix;
+matrix.setAll(2, 3, 4, 5, 6, 7, 0, 0, 1);
+SkScalar affine[6];
+matrix.asAffine(affine);
+const char* names[] = { "ScaleX", "SkewY", "SkewX", "ScaleY", "TransX", "TransY" };
+for (int i = 0; i < 6; ++i) {
+ SkDebugf("%s: %g ", names[i], affine[i]);
+}
+SkDebugf("\n");
+#StdOut
+ScaleX: 2 SkewY: 5 SkewX: 3 ScaleY: 6 TransX: 4 TransY: 7
+##
##
-#ToDo incomplete ##
+#SeeAlso setAffine SetAffineIdentity
##
@@ -1601,16 +3054,46 @@ and does not change the passed array.
#Method void setAffine(const SkScalar affine[6])
-Set the matrix to the specified affine values.
-Note: these are passed in column major order.
+Sets Matrix to affine values, passed in column major order. Given affine,
+column, then row, as:
+
+#Code
+#Literal
+| scale-x skew-x translate-x |
+| skew-y scale-y translate-y |
+##
-#Param affine incomplete ##
+Matrix is set, row, then column, to:
+
+#Code
+#Literal
+| scale-x skew-x translate-x |
+| skew-y scale-y translate-y |
+| 0 0 1 |
+##
+
+#Param affine 3x2 affine matrix ##
#Example
-// incomplete
+SkMatrix matrix;
+matrix.setAll(2, 3, 4, 5, 6, 7, 0, 0, 1);
+SkScalar affine[6];
+matrix.asAffine(affine);
+const char* names[] = { "ScaleX", "SkewY", "SkewX", "ScaleY", "TransX", "TransY" };
+for (int i = 0; i < 6; ++i) {
+ SkDebugf("%s: %g ", names[i], affine[i]);
+}
+SkDebugf("\n");
+matrix.reset();
+matrix.setAffine(affine);
+matrix.dump();
+#StdOut
+ScaleX: 2 SkewY: 5 SkewX: 3 ScaleY: 6 TransX: 4 TransY: 7
+[ 2.0000 3.0000 4.0000][ 5.0000 6.0000 7.0000][ 0.0000 0.0000 1.0000]
+##
##
-#ToDo incomplete ##
+#SeeAlso asAffine SetAffineIdentity
##
@@ -1618,27 +3101,58 @@ Note: these are passed in column major order.
#Method void mapPoints(SkPoint dst[], const SkPoint src[], int count) const
-Apply this matrix to the array of points specified by src, and write
-the transformed points into the array of points specified by dst.
-#Formula
-dst[] = M * src[]
-##
+Maps src Point array of length count to dst Point array of equal or greater
+length. Points are mapped by multiplying each Point by Matrix. Given:
-#Param dst storage for transformed coordinates; must
- allow count entries
+#Code
+#Literal
+ | A B C | | x |
+Matrix = | D E F |, pt = | y |
+ | G H I | | 1 |
##
-#Param src original coordinates that are to be transformed;
- must allow count entries
+
+where
+
+#Code
+#Literal
+for (i = 0; i < count; ++i) {
+ x = src[i].fX
+ y = src[i].fY
+}
##
-#Param count number of points in src to read, and then transform
- into dst
+
+each dst Point is computed as:
+
+#Code
+#Literal
+ |A B C| |x| Ax+By+C Dx+Ey+F
+Matrix * pt = |D E F| |y| = |Ax+By+C Dx+Ey+F Gx+Hy+I| = ------- , -------
+ |G H I| |1| Gx+Hy+I Gx+Hy+I
##
+src and dst may point to the same storage.
+
+#Param dst storage for mapped Points ##
+#Param src Points to transform ##
+#Param count number of Points to transform ##
+
#Example
-// incomplete
+ SkMatrix matrix;
+ matrix.reset();
+ const int count = 4;
+ SkPoint src[count];
+ matrix.mapRectToQuad(src, {40, 70, 180, 220} );
+ SkPaint paint;
+ paint.setARGB(77, 23, 99, 154);
+ for (int i = 0; i < 5; ++i) {
+ SkPoint dst[count];
+ matrix.mapPoints(dst, src, count);
+ canvas->drawPoints(SkCanvas::kPolygon_PointMode, count, dst, paint);
+ matrix.preRotate(35, 128, 128);
+ }
##
-#ToDo incomplete ##
+#SeeAlso mapPointsWithStride mapXY mapHomogeneousPoints mapVectors
##
@@ -1646,22 +3160,53 @@ dst[] = M * src[]
#Method void mapPoints(SkPoint pts[], int count) const
-Apply this matrix to the array of points, overwriting it with the
-transformed values.
-#Formula
-dst[] = M * pts[]
+Maps pts Point array of length count in place. Points are mapped by multiplying
+each Point by Matrix. Given:
+
+#Code
+#Literal
+ | A B C | | x |
+Matrix = | D E F |, pt = | y |
+ | G H I | | 1 |
##
-#Param pts storage for transformed points; must allow count entries
+where
+
+#Code
+#Literal
+for (i = 0; i < count; ++i) {
+ x = pts[i].fX
+ y = pts[i].fY
+}
##
-#Param count number of points in pts
+
+each resulting pts Point is computed as:
+
+#Code
+#Literal
+ |A B C| |x| Ax+By+C Dx+Ey+F
+Matrix * pt = |D E F| |y| = |Ax+By+C Dx+Ey+F Gx+Hy+I| = ------- , -------
+ |G H I| |1| Gx+Hy+I Gx+Hy+I
##
+#Param pts storage for mapped Points ##
+#Param count number of Points to transform ##
+
#Example
-// incomplete
+ SkMatrix matrix;
+ matrix.setRotate(35, 128, 128);
+ const int count = 4;
+ SkPoint pts[count];
+ matrix.mapRectToQuad(pts, {40, 70, 180, 220} );
+ SkPaint paint;
+ paint.setARGB(77, 23, 99, 154);
+ for (int i = 0; i < 5; ++i) {
+ canvas->drawPoints(SkCanvas::kPolygon_PointMode, count, pts, paint);
+ matrix.mapPoints(pts, count);
+ }
##
-#ToDo incomplete ##
+#SeeAlso mapPointsWithStride mapXY mapHomogeneousPoints mapVectors
##
@@ -1669,507 +3214,862 @@ dst[] = M * pts[]
#Method void mapPointsWithStride(SkPoint pts[], size_t stride, int count) const
-Like mapPoints but with custom byte stride between the points. Stride
-should be a multiple of
-#Formula
-sizeof(SkScalar)
-##
-.
-
-#Param pts incomplete ##
-#Param stride incomplete ##
-#Param count incomplete ##
+Maps count pts, skipping stride bytes to advance from one Point to the next.
+Points are mapped by multiplying each Point by Matrix. Given:
-#Example
-// incomplete
+#Code
+#Literal
+ | A B C | | x |
+Matrix = | D E F |, pt = | y |
+ | G H I | | 1 |
##
-#ToDo incomplete ##
+each resulting pts Point is computed as:
+#Code
+#Literal
+ |A B C| |x| Ax+By+C Dx+Ey+F
+Matrix * pt = |D E F| |y| = |Ax+By+C Dx+Ey+F Gx+Hy+I| = ------- , -------
+ |G H I| |1| Gx+Hy+I Gx+Hy+I
##
-# ------------------------------------------------------------------------------
-
-#Method void mapPointsWithStride(SkPoint dst[], const SkPoint src[], size_t stride, int count) const
-
-Like mapPoints but with custom byte stride between the points.
-
-#Param dst incomplete ##
-#Param src incomplete ##
-#Param stride incomplete ##
-#Param count incomplete ##
+#Param pts storage for mapped Points ##
+#Param stride size of record starting with Point, in bytes ##
+#Param count number of Points to transform ##
#Example
-// incomplete
+ SkMatrix matrix;
+ matrix.reset();
+ struct PointZ {
+ SkPoint fPt;
+ SkPoint fStationary;
+ } pts[] = {{{40, 70}, {40, 70}}, {{180, 70}, {180, 70}}, {{180, 220}, {180, 220}},
+ {{40, 220}, {40, 220}}};
+ constexpr int count = SK_ARRAY_COUNT(pts);
+ SkPaint paint;
+ paint.setARGB(77, 23, 99, 154);
+ for (int i = 0; i < 5; ++i) {
+ matrix.preRotate(10, 128, 128);
+ matrix.mapPointsWithStride(&pts[0].fPt, sizeof(PointZ), count);
+ canvas->drawPoints(SkCanvas::kPolygon_PointMode, count * 2, &pts[0].fPt, paint);
+ }
##
-#ToDo incomplete ##
+#SeeAlso mapPoints mapXY mapHomogeneousPoints mapVectors
##
# ------------------------------------------------------------------------------
-#Method void mapHomogeneousPoints(SkScalar dst[], const SkScalar src[], int count) const
+#Method void mapPointsWithStride(SkPoint dst[], const SkPoint src[], size_t stride, int count) const
-Apply this matrix to the array of homogeneous points, specified by src,
-where a homogeneous point is defined by 3 contiguous scalar values,
-and write the transformed points into the array of scalars specified by dst.
-#Formula
-dst[] = M * src[]
-##
+Maps src Point array of length count to dst Point array, skipping stride bytes
+to advance from one Point to the next.
+Points are mapped by multiplying each Point by Matrix. Given:
-#Param dst storage for transformed coordinates; must
- allow 3 * count entries
-##
-#Param src original coordinates to be transformed;
- must contain at least 3 * count entries
+#Code
+#Literal
+ | A B C | | x |
+Matrix = | D E F |, src = | y |
+ | G H I | | 1 |
##
-#Param count number of triples (homogeneous points) in src to read,
- and then transform into dst
+
+each resulting dst Point is computed as:
+
+#Code
+#Literal
+ |A B C| |x| Ax+By+C Dx+Ey+F
+Matrix * pt = |D E F| |y| = |Ax+By+C Dx+Ey+F Gx+Hy+I| = ------- , -------
+ |G H I| |1| Gx+Hy+I Gx+Hy+I
##
+#Param dst storage for mapped Points ##
+#Param src Points to transform ##
+#Param stride size of record starting with Point, in bytes ##
+#Param count number of Points to transform ##
+
#Example
-// incomplete
+ struct PointZ {
+ SkPoint fPt;
+ const SkPoint fStationary;
+ };
+ const PointZ src[] = {{{40, 70}, {40, 70}}, {{180, 70}, {180, 70}}, {{180, 220}, {180, 220}},
+ {{40, 220}, {40, 220}}};
+ PointZ dst[] = {{{0, 0}, {60, 80}}, {{0, 0}, {150, 40}}, {{0, 0}, {100, 240}},
+ {{0, 0}, {10, 250}}};
+ constexpr int count = SK_ARRAY_COUNT(src);
+ SkPaint paint;
+ paint.setARGB(77, 23, 99, 154);
+ for (int i = 0; i < 5; ++i) {
+ SkMatrix matrix;
+ matrix.setRotate(10 * i, 128, 128);
+ matrix.mapPointsWithStride(&dst[0].fPt, &src[0].fPt, sizeof(PointZ), count);
+ canvas->drawPoints(SkCanvas::kPolygon_PointMode, count * 2, &dst[0].fPt, paint);
+ }
##
-#ToDo incomplete ##
+#SeeAlso mapPoints mapXY mapHomogeneousPoints mapVectors
##
# ------------------------------------------------------------------------------
-#Method void mapXY(SkScalar x, SkScalar y, SkPoint* result) const
+#Method void mapHomogeneousPoints(SkPoint3 dst[], const SkPoint3 src[], int count) const
-#Param x incomplete ##
-#Param y incomplete ##
-#Param result incomplete ##
+Maps src Point3 array of length count to dst Point3 array, which must of length count or
+greater. Point3 array is mapped by multiplying each Point3 by Matrix. Given:
-#Example
-// incomplete
+#Code
+#Literal
+ | A B C | | x |
+Matrix = | D E F |, src = | y |
+ | G H I | | z |
##
-#ToDo incomplete ##
+each resulting dst Point is computed as:
+#Code
+#Literal
+ |A B C| |x|
+Matrix * src = |D E F| |y| = |Ax+By+Cz Dx+Ey+Fz Gx+Hy+Iz|
+ |G H I| |z|
##
-# ------------------------------------------------------------------------------
-
-#Method SkPoint mapXY(SkScalar x, SkScalar y) const
-
-#Param x incomplete ##
-#Param y incomplete ##
-
-#Return incomplete ##
+#Param dst storage for mapped Point3 array ##
+#Param src Point3 array to transform ##
+#Param count items in Point3 array to transform ##
#Example
-// incomplete
+ SkPoint3 src[] = {{3, 3, 1}, {8, 2, 2}, {5, 0, 4}, {0, 1, 3},
+ {3, 7, 1}, {8, 6, 2}, {5, 4, 4}, {0, 5, 3}};
+ int lines[] = { 0, 1, 1, 2, 2, 3, 3, 0, 4, 5, 5, 6, 6, 7, 7, 4, 0, 4, 1, 5, 2, 6, 3, 7 };
+ constexpr int count = SK_ARRAY_COUNT(src);
+ auto debugster = [=](SkPoint3 src[]) -> void {
+ for (size_t i = 0; i < SK_ARRAY_COUNT(lines); i += 2) {
+ const SkPoint3& s = src[lines[i]];
+ const SkPoint3& e = src[lines[i + 1]];
+ SkPaint paint;
+ paint.setARGB(77, 23, 99, 154);
+ canvas->drawLine(s.fX / s.fZ, s.fY / s.fZ, e.fX / e.fZ, e.fY / e.fZ, paint);
+ }
+ };
+ canvas->save();
+ canvas->translate(5, 5);
+ canvas->scale(15, 15);
+ debugster(src);
+ canvas->restore();
+ canvas->translate(128, 128);
+ SkMatrix matrix;
+ matrix.setAll(15, 0, 0, 0, 15, 0, -0.08, 0.04, 1);
+ matrix.mapHomogeneousPoints(&src[0].fX, &src[0].fX, count);
+ debugster(src);
##
-#ToDo incomplete ##
+#SeeAlso mapPoints mapXY mapPointsWithStride mapVectors
##
# ------------------------------------------------------------------------------
-#Method void mapVectors(SkVector dst[], const SkVector src[], int count) const
+#Method void mapXY(SkScalar x, SkScalar y, SkPoint* result) const
-Apply this matrix to the array of vectors specified by src, and write
-the transformed vectors into the array of vectors specified by dst.
-This is similar to mapPoints, but ignores any translation in the matrix.
+Maps Point (x, y) to result. Point is mapped by multiplying by Matrix. Given:
-#Param dst storage for transformed coordinates; must
- allow count entries
-##
-#Param src coordinates to be transformed;
- must contain at least count entries
+#Code
+#Literal
+ | A B C | | x |
+Matrix = | D E F |, pt = | y |
+ | G H I | | 1 |
##
-#Param count number of vectors in src to read and transform
- into dst
+
+result is computed as:
+
+#Code
+#Literal
+ |A B C| |x| Ax+By+C Dx+Ey+F
+Matrix * pt = |D E F| |y| = |Ax+By+C Dx+Ey+F Gx+Hy+I| = ------- , -------
+ |G H I| |1| Gx+Hy+I Gx+Hy+I
##
+#Param x x-coordinate of Point to map ##
+#Param y y-coordinate of Point to map ##
+#Param result storage for mapped Point ##
+
#Example
-// incomplete
+ SkPaint paint;
+ paint.setAntiAlias(true);
+ SkMatrix matrix;
+ matrix.setRotate(60, 128, 128);
+ SkPoint lines[] = {{50, 50}, {150, 50}, {150, 150}};
+ for (size_t i = 0; i < SK_ARRAY_COUNT(lines); ++i) {
+ SkPoint pt;
+ matrix.mapXY(lines[i].fX, lines[i].fY, &pt);
+ canvas->drawCircle(pt.fX, pt.fY, 3, paint);
+ }
+ canvas->concat(matrix);
+ canvas->drawPoints(SkCanvas::kPolygon_PointMode, SK_ARRAY_COUNT(lines), lines, paint);
##
-#ToDo incomplete ##
+#SeeAlso mapPoints mapPointsWithStride mapVectors
##
# ------------------------------------------------------------------------------
-#Method void mapVectors(SkVector vecs[], int count) const
+#Method SkPoint mapXY(SkScalar x, SkScalar y) const
-Apply this matrix to count vectors in array vecs.
-This is similar to mapPoints, but ignores any translation in the matrix.
+Returns Point (x, y) multiplied by Matrix. Given:
-#Param vecs vectors to transform; must contain at least
- count entries
+#Code
+#Literal
+ | A B C | | x |
+Matrix = | D E F |, pt = | y |
+ | G H I | | 1 |
##
-#Param count number of vectors in vecs
+
+result is computed as:
+
+#Code
+#Literal
+ |A B C| |x| Ax+By+C Dx+Ey+F
+Matrix * pt = |D E F| |y| = |Ax+By+C Dx+Ey+F Gx+Hy+I| = ------- , -------
+ |G H I| |1| Gx+Hy+I Gx+Hy+I
##
+#Param x x-coordinate of Point to map ##
+#Param y y-coordinate of Point to map ##
+
+#Return mapped Point ##
+
#Example
-// incomplete
+#Image 4
+SkMatrix matrix;
+SkPoint bitmapBounds[4], perspect[4] = {{50, 10}, {180, 40}, {236, 176}, {30, 206}};
+SkRect::Make(source.bounds()).toQuad(bitmapBounds);
+matrix.setPolyToPoly(bitmapBounds, perspect, 4);
+SkPaint paint;
+paint.setAntiAlias(true);
+paint.setStrokeWidth(3);
+for (int x : { 0, source.width() } ) {
+ for (int y : { 0, source.height() } ) {
+ canvas->drawPoint(matrix.mapXY(x, y), paint);
+ }
+}
+canvas->concat(matrix);
+canvas->drawBitmap(source, 0, 0);
##
-#ToDo incomplete ##
+#SeeAlso mapPoints mapPointsWithStride mapVectors
##
# ------------------------------------------------------------------------------
-#Method void mapVector(SkScalar dx, SkScalar dy, SkVector* result) const
+#Method void mapVectors(SkVector dst[], const SkVector src[], int count) const
-#Param dx incomplete ##
-#Param dy incomplete ##
-#Param result incomplete ##
+Maps src Vector array of length count to Vector Point array of equal or greater
+length. Vectors are mapped by multiplying each Vector by Matrix, treating
+Matrix translation as zero. Given:
-#Example
-// incomplete
+#Code
+#Literal
+ | A B 0 | | x |
+Matrix = | D E 0 |, src = | y |
+ | G H I | | 1 |
##
-#ToDo incomplete ##
+where
+#Code
+#Literal
+for (i = 0; i < count; ++i) {
+ x = src[i].fX
+ y = src[i].fY
+}
##
-# ------------------------------------------------------------------------------
+each dst Vector is computed as:
-#Method SkVector mapVector(SkScalar dx, SkScalar dy) const
+#Code
+#Literal
+ |A B 0| |x| Ax+By Dx+Ey
+Matrix * src = |D E 0| |y| = |Ax+By Dx+Ey Gx+Hy+I| = ------- , -------
+ |G H I| |1| Gx+Hy+I Gx+Hy+I
+##
-#Param dx incomplete ##
-#Param dy incomplete ##
+src and dst may point to the same storage.
-#Return incomplete ##
+#Param dst storage for mapped Vectors ##
+#Param src Vectors to transform ##
+#Param count number of Vectors to transform ##
#Example
-// incomplete
+ SkPaint paint;
+ paint.setAntiAlias(true);
+ paint.setStyle(SkPaint::kStroke_Style);
+ SkMatrix matrix;
+ matrix.reset();
+ const SkVector radii[] = {{8, 4}, {9, 1}, {6, 2}, {7, 3}};
+ for (int i = 0; i < 4; ++i) {
+ SkVector rScaled[4];
+ matrix.preScale(1.5f, 2.f);
+ matrix.mapVectors(rScaled, radii, SK_ARRAY_COUNT(radii));
+ SkRRect rrect;
+ rrect.setRectRadii({20, 20, 180, 70}, rScaled);
+ canvas->drawRRect(rrect, paint);
+ canvas->translate(0, 60);
+ }
##
-#ToDo incomplete ##
+#SeeAlso mapVector mapPoints mapPointsWithStride mapXY
##
# ------------------------------------------------------------------------------
-#Method bool mapRect(SkRect* dst, const SkRect& src) const
-
-Apply this matrix to the src rectangle, and write the transformed
-rectangle into dst. This is accomplished by transforming the 4 corners
-of src, and then setting dst to the bounds of those points.
-
-#Param dst storage for transformed rectangle ##
-#Param src rectangle to transform ##
+#Method void mapVectors(SkVector vecs[], int count) const
-#Return result of calling rectStaysRect
-##
+Maps vecs Vector array of length count in place, multiplying each Vector by
+Matrix, treating Matrix translation as zero. Given:
-#Example
-// incomplete
+#Code
+#Literal
+ | A B 0 | | x |
+Matrix = | D E 0 |, vec = | y |
+ | G H I | | 1 |
##
-#ToDo incomplete ##
+where
+#Code
+#Literal
+for (i = 0; i < count; ++i) {
+ x = vecs[i].fX
+ y = vecs[i].fY
+}
##
-# ------------------------------------------------------------------------------
-
-#Method bool mapRect(SkRect* rect) const
-
-Apply this matrix to the rectangle, and write the transformed rectangle
-back into it. This is accomplished by transforming the 4 corners of
-rect, and then setting it to the bounds of those points
+each result Vector is computed as:
-#Param rect rectangle to transform
+#Code
+#Literal
+ |A B 0| |x| Ax+By Dx+Ey
+Matrix * vec = |D E 0| |y| = |Ax+By Dx+Ey Gx+Hy+I| = ------- , -------
+ |G H I| |1| Gx+Hy+I Gx+Hy+I
##
-#Return the result of calling rectStaysRect
-##
+#Param vecs Vectors to transform, and storage for mapped Vectors ##
+#Param count number of Vectors to transform ##
#Example
-// incomplete
+ SkPaint paint;
+ paint.setAntiAlias(true);
+ paint.setStyle(SkPaint::kStroke_Style);
+ SkMatrix matrix;
+ matrix.setScale(2, 3);
+ SkVector radii[] = {{7, 7}, {3, 3}, {2, 2}, {4, 0}};
+ for (int i = 0; i < 4; ++i) {
+ SkRRect rrect;
+ rrect.setRectRadii({20, 20, 180, 70}, radii);
+ canvas->drawRRect(rrect, paint);
+ canvas->translate(0, 60);
+ matrix.mapVectors(radii, SK_ARRAY_COUNT(radii));
+ }
##
-#ToDo incomplete ##
+#SeeAlso mapVector mapPoints mapPointsWithStride mapXY
##
# ------------------------------------------------------------------------------
-#Method void mapRectToQuad(SkPoint dst[4], const SkRect& rect) const
+#Method void mapVector(SkScalar dx, SkScalar dy, SkVector* result) const
-Applies Matrix to rect, and write the four transformed
-points into dst. The points written to dst will be the original top-left, top-right,
-bottom-right, and bottom-left points transformed by Matrix.
+Maps Vector (x, y) to result. Vector is mapped by multiplying by Matrix,
+treating Matrix translation as zero. Given:
-#Param dst storage for transformed quad
+#Code
+#Literal
+ | A B 0 | | dx |
+Matrix = | D E 0 |, vec = | dy |
+ | G H I | | 1 |
##
-#Param rect rectangle to transform
+
+each result Vector is computed as:
+
+#Code
+#Literal
+#Outdent
+ |A B 0| |dx| A*dx+B*dy D*dx+E*dy
+Matrix * vec = |D E 0| |dy| = |A*dx+B*dy D*dx+E*dy G*dx+H*dy+I| = ----------- , -----------
+ |G H I| | 1| G*dx+H*dy+I G*dx+*dHy+I
##
+#Param dx x-coordinate of Vector to map ##
+#Param dy y-coordinate of Vector to map ##
+#Param result storage for mapped Vector ##
+
#Example
-// incomplete
+ SkPaint paint;
+ paint.setColor(SK_ColorGREEN);
+ paint.setAntiAlias(true);
+ paint.setTextSize(48);
+ SkMatrix matrix;
+ matrix.setRotate(90);
+ SkVector offset = { 7, 7 };
+ for (int i = 0; i < 4; ++i) {
+ paint.setImageFilter(SkDropShadowImageFilter::Make(offset.fX, offset.fY, 3, 3,
+ SK_ColorBLUE, SkDropShadowImageFilter::kDrawShadowAndForeground_ShadowMode, nullptr));
+ matrix.mapVector(offset.fX, offset.fY, &offset);
+ canvas->translate(0, 60);
+ canvas->drawString("Text", 50, 0, paint);
+ }
##
-#ToDo incomplete ##
+#SeeAlso mapVectors mapPoints mapPointsWithStride mapXY
##
# ------------------------------------------------------------------------------
-#Method void mapRectScaleTranslate(SkRect* dst, const SkRect& src) const
-
-Maps a rectangle to another rectangle, asserting (in debug mode) that the matrix only contains
-scale and translate elements. If it contains other elements, the results are undefined.
+#Method SkVector mapVector(SkScalar dx, SkScalar dy) const
-#Param dst incomplete ##
-#Param src incomplete ##
+Returns Vector (x, y) multiplied by Matrix, treating Matrix translation as zero.
+Given:
-#Example
-// incomplete
+#Code
+#Literal
+ | A B 0 | | dx |
+Matrix = | D E 0 |, vec = | dy |
+ | G H I | | 1 |
##
-#ToDo incomplete ##
+each result Vector is computed as:
+#Code
+#Literal
+#Outdent
+ |A B 0| |dx| A*dx+B*dy D*dx+E*dy
+Matrix * vec = |D E 0| |dy| = |A*dx+B*dy D*dx+E*dy G*dx+H*dy+I| = ----------- , -----------
+ |G H I| | 1| G*dx+H*dy+I G*dx+*dHy+I
##
-# ------------------------------------------------------------------------------
-
-#Method SkScalar mapRadius(SkScalar radius) const
+#Param dx x-coordinate of Vector to map ##
+#Param dy y-coordinate of Vector to map ##
-Return the mean radius of a circle after it has been mapped by
-this matrix. NOTE: in perspective this value assumes the circle
-has its center at the origin.
-
-#Param radius incomplete ##
-
-#Return incomplete ##
+#Return mapped Vector ##
#Example
-// incomplete
+ SkPaint paint;
+ paint.setColor(SK_ColorGREEN);
+ paint.setAntiAlias(true);
+ paint.setTextSize(48);
+ SkMatrix matrix;
+ matrix.setRotate(90);
+ SkVector offset = { 7, 7 };
+ for (int i = 0; i < 4; ++i) {
+ paint.setImageFilter(SkDropShadowImageFilter::Make(offset.fX, offset.fY, 3, 3,
+ SK_ColorBLUE, SkDropShadowImageFilter::kDrawShadowAndForeground_ShadowMode, nullptr));
+ offset = matrix.mapVector(offset.fX, offset.fY);
+ canvas->translate(0, 60);
+ canvas->drawString("Text", 50, 0, paint);
+ }
##
-#ToDo incomplete ##
+#SeeAlso mapVectors mapPoints mapPointsWithStride mapXY
##
# ------------------------------------------------------------------------------
-#Method static MapXYProc GetMapXYProc(TypeMask mask)
+#Method bool mapRect(SkRect* dst, const SkRect& src) const
+
+Sets dst to bounds of src corners mapped by Matrix.
+Returns true if mapped corners are dst corners.
+
+Returned value is the same as calling rectStaysRect.
-#Param mask incomplete ##
+#Param dst storage for bounds of mapped Points ##
+#Param src Rect to map ##
-#Return incomplete ##
+#Return true if dst is equivalent to mapped src ##
#Example
-// incomplete
+ SkPaint paint;
+ paint.setAntiAlias(true);
+ SkMatrix matrix;
+ matrix.setRotate(45, 128, 128);
+ SkRect rotatedBounds, bounds = {40, 50, 190, 200};
+ matrix.mapRect(&rotatedBounds, bounds );
+ paint.setColor(SK_ColorGRAY);
+ canvas->drawRect(rotatedBounds, paint);
+ canvas->concat(matrix);
+ paint.setColor(SK_ColorRED);
+ canvas->drawRect(bounds, paint);
##
-#ToDo incomplete ##
+#SeeAlso mapPoints rectStaysRect
##
# ------------------------------------------------------------------------------
-#Method MapXYProc getMapXYProc() const
+#Method bool mapRect(SkRect* rect) const
+
+Sets rect to bounds of rect corners mapped by Matrix.
+Returns true if mapped corners are computed rect corners.
+
+Returned value is the same as calling rectStaysRect.
+
+#Param rect rectangle to map, and storage for bounds of mapped corners ##
-#Return incomplete ##
+#Return true if result is equivalent to mapped src ##
#Example
-// incomplete
+ SkPaint paint;
+ paint.setAntiAlias(true);
+ SkMatrix matrix;
+ matrix.setRotate(45, 128, 128);
+ SkRect bounds = {40, 50, 190, 200};
+ matrix.mapRect(&bounds);
+ paint.setColor(SK_ColorGRAY);
+ canvas->drawRect(bounds, paint);
+ canvas->concat(matrix);
+ paint.setColor(SK_ColorRED);
+ canvas->drawRect({40, 50, 190, 200}, paint);
##
-#ToDo incomplete ##
+#SeeAlso mapRectScaleTranslate mapPoints rectStaysRect
##
# ------------------------------------------------------------------------------
-#Method static MapPtsProc GetMapPtsProc(TypeMask mask)
+#Method void mapRectToQuad(SkPoint dst[4], const SkRect& rect) const
-#Param mask incomplete ##
+Maps four corners of rect to dst. Points are mapped by multiplying each
+rect corner by Matrix. rect corner is processed in this order:
+(rect.fLeft, rect.fTop), (rect.fRight, rect.fTop), (rect.fRight, rect.fBottom),
+(rect.fLeft, rect.fBottom).
-#Return incomplete ##
+rect may be empty: rect.fLeft may be greater than or equal to rect.fRight;
+rect.fTop may be greater than or equal to rect.fBottom.
-#Example
-// incomplete
-##
-
-#ToDo incomplete ##
+Given:
+#Code
+#Literal
+ | A B C | | x |
+Matrix = | D E F |, pt = | y |
+ | G H I | | 1 |
##
-# ------------------------------------------------------------------------------
+where pt is initialized from each of (rect.fLeft, rect.fTop),
+(rect.fRight, rect.fTop), (rect.fRight, rect.fBottom), (rect.fLeft, rect.fBottom),
+each dst Point is computed as:
-#Method MapPtsProc getMapPtsProc() const
+#Code
+#Literal
+ |A B C| |x| Ax+By+C Dx+Ey+F
+Matrix * pt = |D E F| |y| = |Ax+By+C Dx+Ey+F Gx+Hy+I| = ------- , -------
+ |G H I| |1| Gx+Hy+I Gx+Hy+I
+##
-#Return incomplete ##
+#Param dst storage for mapped corner Points ##
+#Param rect Rect to map ##
#Example
-// incomplete
+ SkPaint paint;
+ paint.setAntiAlias(true);
+ SkMatrix matrix;
+ matrix.setRotate(60, 128, 128);
+ SkRect rect = {50, 50, 150, 150};
+ SkPoint pts[4];
+ matrix.mapRectToQuad(pts, rect);
+ for (int i = 0; i < 4; ++i) {
+ canvas->drawCircle(pts[i].fX, pts[i].fY, 3, paint);
+ }
+ canvas->concat(matrix);
+ paint.setStyle(SkPaint::kStroke_Style);
+ canvas->drawRect(rect, paint);
##
-#ToDo incomplete ##
+#SeeAlso mapRect mapRectScaleTranslate
##
# ------------------------------------------------------------------------------
-#Method bool isFixedStepInX() const
+#Method void mapRectScaleTranslate(SkRect* dst, const SkRect& src) const
-Returns true if the matrix can be stepped in x (not complex
-perspective).
+Sets dst to bounds of src corners mapped by Matrix. If matrix contains
+elements other than scale or translate: asserts if SK_DEBUG is defined;
+otherwise, results are undefined.
-#Return incomplete ##
+#Param dst storage for bounds of mapped Points ##
+#Param src Rect to map ##
#Example
-// incomplete
+ SkPaint paint;
+ SkMatrix matrix;
+ SkRect rect = {100, 50, 150, 180};
+ matrix.setScale(2, .5f, rect.centerX(), rect.centerY());
+ SkRect rotated;
+ matrix.mapRectScaleTranslate(&rotated, rect);
+ paint.setStyle(SkPaint::kStroke_Style);
+ canvas->drawRect(rect, paint);
+ paint.setColor(SK_ColorRED);
+ canvas->drawRect(rotated, paint);
##
-#ToDo incomplete ##
+#SeeAlso mapRect mapRectToQuad isScaleTranslate rectStaysRect
##
# ------------------------------------------------------------------------------
-#Method SkVector fixedStepInX(SkScalar y) const
+#Method SkScalar mapRadius(SkScalar radius) const
-If the matrix can be stepped in x (not complex perspective)
-then return the step value.
-If it cannot, behavior is undefined.
+Returns geometric mean radius of ellipse formed by constructing Circle of
+size radius, and mapping constructed Circle with Matrix. The result squared is
+equal to the major axis length times the minor axis length.
+Result is not meaningful if Matrix contains perspective elements.
-#Param y incomplete ##
+#Param radius Circle size to map ##
-#Return incomplete ##
+#Return average mapped radius ##
#Example
-// incomplete
-##
-
-#ToDo incomplete ##
+#Description
+The area enclosed by a square with sides equal to mappedRadius is the same as
+the area enclosed by the ellipse major and minor axes.
+##
+ SkPaint paint;
+ paint.setAntiAlias(true);
+ SkMatrix matrix;
+ const SkPoint center = {108, 93};
+ matrix.setScale(2, .5f, center.fX, center.fY);
+ matrix.postRotate(45, center.fX, center.fY);
+ const SkScalar circleRadius = 50;
+ SkScalar mappedRadius = matrix.mapRadius(circleRadius);
+ SkVector minorAxis, majorAxis;
+ matrix.mapVector(0, circleRadius, &minorAxis);
+ matrix.mapVector(circleRadius, 0, &majorAxis);
+ SkString mappedArea;
+ mappedArea.printf("area = %g", mappedRadius * mappedRadius);
+ canvas->drawString(mappedArea, 145, 250, paint);
+ canvas->drawString("mappedRadius", center.fX + mappedRadius + 3, center.fY, paint);
+ paint.setColor(SK_ColorRED);
+ SkString axArea;
+ axArea.printf("area = %g", majorAxis.length() * minorAxis.length());
+ paint.setStyle(SkPaint::kFill_Style);
+ canvas->drawString(axArea, 15, 250, paint);
+ paint.setStyle(SkPaint::kStroke_Style);
+ canvas->drawRect({10, 200, 10 + majorAxis.length(), 200 + minorAxis.length()}, paint);
+ paint.setColor(SK_ColorBLACK);
+ canvas->drawLine(center.fX, center.fY, center.fX + mappedRadius, center.fY, paint);
+ canvas->drawLine(center.fX, center.fY, center.fX, center.fY + mappedRadius, paint);
+ canvas->drawRect({140, 180, 140 + mappedRadius, 180 + mappedRadius}, paint);
+ canvas->concat(matrix);
+ canvas->drawCircle(center.fX, center.fY, circleRadius, paint);
+ paint.setColor(SK_ColorRED);
+ canvas->drawLine(center.fX, center.fY, center.fX + circleRadius, center.fY, paint);
+ canvas->drawLine(center.fX, center.fY, center.fX, center.fY + circleRadius, paint);
+##
+
+#SeeAlso mapVector
##
# ------------------------------------------------------------------------------
-#Method bool cheapEqualTo(const SkMatrix& m) const
-
-Returns true if Matrix equals m, using an efficient comparison.
-
-Return false when the sign of zero values is the different, that is, one
-matrix has positive zero value and the other has negative zero value.
+#Method bool isFixedStepInX() const
-Normally, comparing NaN prevents the value from equaling any other value,
-including itself. To improve performance, NaN values are treated as bit patterns
-that are equal if their bit patterns are equal.
+Returns true if a unit step in x at some y mapped through Matrix can be
+represented by a constant Vector. Returns true if getType returns kIdentity_Mask,
+or combinations of: kTranslate_Mask, kScale_Mask, and kAffine_Mask.
-#Param m incomplete ##
+May return true if getType returns kPerspective_Mask, but only when Matrix
+does not include rotation or skewing along the y-axis.
-#Return incomplete ##
+#Return true if Matrix does not have complex perspective ##
#Example
-// incomplete
-##
-
-#ToDo incomplete ##
+ SkMatrix matrix;
+ for (SkScalar px : { 0.0f, 0.1f } ) {
+ for (SkScalar py : { 0.0f, 0.1f } ) {
+ for (SkScalar sy : { 1, 2 } ) {
+ matrix.setAll(1, 0, 0, 0, sy, 0, px, py, 1);
+ matrix.dump();
+ SkDebugf("isFixedStepInX: %s\n", matrix.isFixedStepInX() ? "true" : "false");
+ }
+ }
+ }
+#StdOut
+[ 1.0000 0.0000 0.0000][ 0.0000 1.0000 0.0000][ 0.0000 0.0000 1.0000]
+isFixedStepInX: true
+[ 1.0000 0.0000 0.0000][ 0.0000 2.0000 0.0000][ 0.0000 0.0000 1.0000]
+isFixedStepInX: true
+[ 1.0000 0.0000 0.0000][ 0.0000 1.0000 0.0000][ 0.0000 0.1000 1.0000]
+isFixedStepInX: true
+[ 1.0000 0.0000 0.0000][ 0.0000 2.0000 0.0000][ 0.0000 0.1000 1.0000]
+isFixedStepInX: true
+[ 1.0000 0.0000 0.0000][ 0.0000 1.0000 0.0000][ 0.1000 0.0000 1.0000]
+isFixedStepInX: false
+[ 1.0000 0.0000 0.0000][ 0.0000 2.0000 0.0000][ 0.1000 0.0000 1.0000]
+isFixedStepInX: false
+[ 1.0000 0.0000 0.0000][ 0.0000 1.0000 0.0000][ 0.1000 0.1000 1.0000]
+isFixedStepInX: false
+[ 1.0000 0.0000 0.0000][ 0.0000 2.0000 0.0000][ 0.1000 0.1000 1.0000]
+isFixedStepInX: false
+##
+##
+
+#SeeAlso fixedStepInX getType
##
# ------------------------------------------------------------------------------
-#Method friend SK_API bool operator==(const SkMatrix& a, const SkMatrix& b)
+#Method SkVector fixedStepInX(SkScalar y) const
-mac chromium debug build requires SK_API to make operator== visible
+Returns Vector representing a unit step in x at y mapped through Matrix.
+If isFixedStepInX is false, returned value is undefined.
-#Param a incomplete ##
-#Param b incomplete ##
+#Param y position of line parallel to x-axis ##
-#Return incomplete ##
+#Return Vector advance of mapped unit step in x ##
#Example
-// incomplete
-##
-
-#ToDo incomplete ##
+#Image 3
+ SkMatrix matrix;
+ const SkPoint center = { 128, 128 };
+ matrix.setScale(20, 25, center.fX, center.fY);
+ matrix.postRotate(75, center.fX, center.fY);
+ {
+ SkAutoCanvasRestore acr(canvas, true);
+ canvas->concat(matrix);
+ canvas->drawBitmap(source, 0, 0);
+ }
+ if (matrix.isFixedStepInX()) {
+ SkPaint paint;
+ paint.setAntiAlias(true);
+ SkVector step = matrix.fixedStepInX(128);
+ SkVector end = center + step;
+ canvas->drawLine(center, end, paint);
+ SkVector arrow = { step.fX + step.fY, step.fY - step.fX};
+ arrow = arrow * .25f;
+ canvas->drawLine(end, end - arrow, paint);
+ canvas->drawLine(end, {end.fX + arrow.fY, end.fY - arrow.fX}, paint);
+ }
+##
+
+#SeeAlso isFixedStepInX getType
##
# ------------------------------------------------------------------------------
-#Method friend SK_API bool operator!=(const SkMatrix& a, const SkMatrix& b)
-
-#Param a incomplete ##
-#Param b incomplete ##
+#Method bool cheapEqualTo(const SkMatrix& m) const
-#Return incomplete ##
+Returns true if Matrix equals m, using an efficient comparison.
-#Example
-// incomplete
-##
+Returns false when the sign of zero values is the different; when one
+matrix has positive zero value and the other has negative zero value.
-#ToDo incomplete ##
+Returns true even when both Matrices contain NaN.
-##
+NaN never equals any value, including itself. To improve performance, NaN values
+are treated as bit patterns that are equal if their bit patterns are equal.
-# ------------------------------------------------------------------------------
+#Param m Matrix to compare ##
-#Enum _anonymous_3
+#Return true if m and Matrix are represented by identical bit patterns ##
-#Code
- enum {
- kMaxFlattenSize = 9 * sizeof(SkScalar) + sizeof(uint32_t),
+#Example
+ auto debugster = [](const char* prefix, const SkMatrix& a, const SkMatrix& b) -> void {
+ SkDebugf("%s: a %c= b a.cheapEqualTo(b): %s\n", prefix,
+ a == b ? '=' : '!', a.cheapEqualTo(b) ? "true" : "false");
};
+ SkMatrix a, b;
+ a.setAll(1, 0, 0, 0, 1, 0, 0, 0, 1);
+ b.setIdentity();
+ debugster("identity", a, b);
+ a.setAll(1, -0.0f, 0, 0, 1, 0, 0, 0, 1);
+ debugster("neg zero", a, b);
+ a.setAll(1, SK_ScalarNaN, 0, 0, 1, 0, 0, 0, 1);
+ debugster(" one NaN", a, b);
+ b.setAll(1, SK_ScalarNaN, 0, 0, 1, 0, 0, 0, 1);
+ debugster("both NaN", a, b);
+#StdOut
+identity: a == b a.cheapEqualTo(b): true
+neg zero: a == b a.cheapEqualTo(b): false
+ one NaN: a != b a.cheapEqualTo(b): false
+both NaN: a != b a.cheapEqualTo(b): true
##
-
-#Const kMaxFlattenSize = 9 * sizeof(SkScalar) + sizeof(uint32_t)
- writeToMemory and readFromMemory will never return a value larger than this
-##
-
-#Example
-// incomplete
##
-#ToDo incomplete ##
+#SeeAlso operator==(const SkMatrix& a, const SkMatrix& b)
##
# ------------------------------------------------------------------------------
-#Method size_t writeToMemory(void* buffer) const
+#Method bool operator==(const SkMatrix& a, const SkMatrix& b)
-return the number of bytes written, whether or not buffer is null
+Compares a and b; returns true if a and b are numerically equal. Returns true
+even if sign of zero values are different. Returns false if either Matrix
+contains NaN, even if the other Matrix also contains NaN.
-#Param buffer incomplete ##
+#Param a Matrix to compare ##
+#Param b Matrix to compare ##
-#Return incomplete ##
+#Return true if m and Matrix are numerically equal ##
#Example
-// incomplete
+ auto debugster = [](const char* prefix, const SkMatrix& a, const SkMatrix& b) -> void {
+ SkDebugf("%s: a %c= b a.cheapEqualTo(b): %s\n", prefix,
+ a == b ? '=' : '!', a.cheapEqualTo(b) ? "true" : "false");
+ };
+ SkMatrix a, b;
+ a.setAll(1, 0, 0, 0, 1, 0, 0, 0, 1);
+ b.setScale(2, 4);
+ b.postScale(0.5f, 0.25f);
+ debugster("identity", a, b);
+#StdOut
+identity: a == b a.cheapEqualTo(b): true
+##
##
-#ToDo incomplete ##
+#SeeAlso cheapEqualTo operator!=(const SkMatrix& a, const SkMatrix& b)
##
# ------------------------------------------------------------------------------
-#Method size_t readFromMemory(const void* buffer, size_t length)
+#Method bool operator!=(const SkMatrix& a, const SkMatrix& b)
-Reads data from the buffer parameter
+Compares a and b; returns true if a and b are not numerically equal. Returns false
+even if sign of zero values are different. Returns true if either Matrix
+contains NaN, even if the other Matrix also contains NaN.
-#Param buffer memory to read from
-##
-#Param length amount of memory available in the buffer
-##
+#Param a Matrix to compare ##
+#Param b Matrix to compare ##
-#Return number of bytes read (must be a multiple of 4) or
- 0 if there was not enough memory available
-##
+#Return true if m and Matrix are numerically not equal ##
#Example
-// incomplete
+ auto debugster = [](const char* prefix, const SkMatrix& a, const SkMatrix& b) -> void {
+ SkDebugf("%s: a %c= b a.cheapEqualTo(b): %s\n", prefix,
+ a != b ? '!' : '=', a.cheapEqualTo(b) ? "true" : "false");
+ };
+ SkMatrix a, b;
+ a.setAll(1, 0, 0, 0, 1, 0, 1, 0, 1);
+ a.invert(&b);
+ debugster("identity", a, b);
##
-#ToDo incomplete ##
+#SeeAlso cheapEqualTo operator==(const SkMatrix& a, const SkMatrix& b)
##
@@ -2177,11 +4077,26 @@ Reads data from the buffer parameter
#Method void dump() const
+Writes text representation of Matrix to standard output. Floating point values
+are written with limited precision; it may not be possible to reconstruct
+original Matrix from output.
+
#Example
-// incomplete
+ SkMatrix matrix;
+ matrix.setRotate(45);
+ matrix.dump();
+ SkMatrix nearlyEqual;
+ nearlyEqual.setAll(0.7071f, -0.7071f, 0, 0.7071f, 0.7071f, 0, 0, 0, 1);
+ nearlyEqual.dump();
+ SkDebugf("matrix %c= nearlyEqual\n", matrix == nearlyEqual ? '=' : '!');
+#StdOut
+[ 0.7071 -0.7071 0.0000][ 0.7071 0.7071 0.0000][ 0.0000 0.0000 1.0000]
+[ 0.7071 -0.7071 0.0000][ 0.7071 0.7071 0.0000][ 0.0000 0.0000 1.0000]
+matrix != nearlyEqual
+##
##
-#ToDo incomplete ##
+#SeeAlso toString
##
@@ -2189,13 +4104,31 @@ Reads data from the buffer parameter
#Method void toString(SkString* str) const
-#Param str incomplete ##
+Creates string representation of Matrix. Floating point values
+are written with limited precision; it may not be possible to reconstruct
+original Matrix from output.
+
+#Param str storage for string representation of Matrix ##
#Example
-// incomplete
+ SkMatrix matrix;
+ matrix.setRotate(45);
+ SkString mStr, neStr;
+ matrix.toString(&mStr);
+ SkMatrix nearlyEqual;
+ nearlyEqual.setAll(0.7071f, -0.7071f, 0, 0.7071f, 0.7071f, 0, 0, 0, 1);
+ nearlyEqual.toString(&neStr);
+ SkDebugf("mStr %s\n", mStr.c_str());
+ SkDebugf("neStr %s\n", neStr.c_str());
+ SkDebugf("matrix %c= nearlyEqual\n", matrix == nearlyEqual ? '=' : '!');
+#StdOut
+mStr [ 0.7071 -0.7071 0.0000][ 0.7071 0.7071 0.0000][ 0.0000 0.0000 1.0000]
+neStr [ 0.7071 -0.7071 0.0000][ 0.7071 0.7071 0.0000][ 0.0000 0.0000 1.0000]
+matrix != nearlyEqual
+##
##
-#ToDo incomplete ##
+#SeeAlso dump
##
@@ -2203,19 +4136,23 @@ Reads data from the buffer parameter
#Method SkScalar getMinScale() const
-Calculates the minimum scaling factor of the matrix as computed from the
-singular value decomposition of the upper
-left 2x2. If the max scale factor cannot be computed (for example overflow or perspective)
--1 is returned.
+Returns the minimum scaling factor of Matrix by decomposing the scaling and
+skewing elements.
+Returns -1 if scale factor overflows or Matrix contains perspective.
#Return minimum scale factor
##
#Example
-// incomplete
+ SkMatrix matrix;
+ matrix.setScale(42, 24);
+ SkDebugf("matrix.getMinScale() %g\n", matrix.getMinScale());
+#StdOut
+matrix.getMinScale() 24
+##
##
-#ToDo incomplete ##
+#SeeAlso getMaxScale getMinMaxScales
##
@@ -2223,19 +4160,23 @@ left 2x2. If the max scale factor cannot be computed (for example overflow or pe
#Method SkScalar getMaxScale() const
-Calculates the maximum scaling factor of the matrix as computed from the
-singular value decomposition of the upper
-left 2x2. If the max scale factor cannot be computed (for example overflow or perspective)
--1 is returned.
+Returns the maximum scaling factor of Matrix by decomposing the scaling and
+skewing elements.
+Returns -1 if scale factor overflows or Matrix contains perspective.
#Return maximum scale factor
##
#Example
-// incomplete
+ SkMatrix matrix;
+ matrix.setScale(42, 24);
+ SkDebugf("matrix.getMaxScale() %g\n", matrix.getMaxScale());
+#StdOut
+matrix.getMaxScale() 42
+##
##
-#ToDo incomplete ##
+#SeeAlso getMinScale getMinMaxScales
##
@@ -2243,19 +4184,30 @@ left 2x2. If the max scale factor cannot be computed (for example overflow or pe
#Method bool SK_WARN_UNUSED_RESULT getMinMaxScales(SkScalar scaleFactors[2]) const
-Gets both the min and max scale factors. The min scale factor is scaleFactors[0] and the max
-is scaleFactors[1]. If the min/max scale factors cannot be computed false is returned and the
-values of scaleFactors[] are undefined.
+Sets scaleFactors[0] to the minimum scaling factor, and scaleFactors[1] to the
+maximum scaling factor. Scaling factors are computed by decomposing
+the Matrix scaling and skewing elements.
+
+Returns true if scaleFactors are found; otherwise, returns false and sets
+scaleFactors to undefined values.
-#Param scaleFactors incomplete ##
+#Param scaleFactors storage for minimum and maximum scale factors ##
-#Return incomplete ##
+#Return true if scale factors were computed correctly ##
#Example
-// incomplete
+ SkMatrix matrix;
+ matrix.setAll(1, 0, 0, 0, 1, 0, 0, 0, 0);
+ matrix.invert(&matrix);
+ SkScalar factor[2] = {2, 2};
+ bool result = matrix.getMinMaxScales(factor);
+ SkDebugf("matrix.getMinMaxScales() %s %g %g\n", result ? "true" : "false", factor[0], factor[1]);
+#StdOut
+matrix.getMinMaxScales() false 2 2
+##
##
-#ToDo incomplete ##
+#SeeAlso getMinScale getMaxScale
##
@@ -2263,25 +4215,52 @@ values of scaleFactors[] are undefined.
#Method bool decomposeScale(SkSize* scale, SkMatrix* remaining = nullptr) const
-Attempt to decompose this matrix into a scale-only component and whatever remains, where
-the scale component is to be applied first.
+Decomposes Matrix into scale components and whatever remains. Returns false if
+Matrix could not be decomposed.
+
+Sets scale to portion of Matrix that scales in x and y. Sets remaining to Matrix
+with x and y scaling factored out. remaining may be passed as nullptr
+to determine if Matrix can be decomposed without computing remainder.
+
+Returns true if scale components are found. scale and remaining are
+unchanged if Matrix contains perspective; scale factors are not finite, or
+are nearly zero.
+
+On success
+
#Formula
-M -> Remaining * Scale
+Matrix = scale * Remaining
##
-On success, return true and assign the scale and remaining components (assuming their
-respective parameters are not null). On failure return false and ignore the parameters.
-Possible reasons to fail: perspective, one or more scale factors are zero.
-#Param scale incomplete ##
-#Param remaining incomplete ##
+#Param scale x and y scaling factors; may be nullptr ##
+#Param remaining Matrix without scaling; may be nullptr ##
-#Return incomplete ##
+#Return true if scale can be computed ##
#Example
-// incomplete
+ SkMatrix matrix;
+ matrix.setRotate(90 * SK_Scalar1);
+ matrix.postScale(1.f / 4, 1.f / 2);
+ matrix.dump();
+ SkSize scale = {SK_ScalarNaN, SK_ScalarNaN};
+ SkMatrix remaining;
+ remaining.reset();
+ bool success = matrix.decomposeScale(&scale, &remaining);
+ SkDebugf("success: %s ", success ? "true" : "false");
+ SkDebugf("scale: %g, %g\n", scale.width(), scale.height());
+ remaining.dump();
+ SkMatrix scaleMatrix = SkMatrix::MakeScale(scale.width(), scale.height());
+ SkMatrix combined = SkMatrix::Concat(scaleMatrix, remaining);
+ combined.dump();
+#StdOut
+[ 0.0000 -0.2500 0.0000][ 0.5000 0.0000 0.0000][ 0.0000 0.0000 1.0000]
+success: true scale: 0.5, 0.25
+[ 0.0000 -0.5000 0.0000][ 2.0000 0.0000 0.0000][ 0.0000 0.0000 1.0000]
+[ 0.0000 -0.2500 0.0000][ 0.5000 0.0000 0.0000][ 0.0000 0.0000 1.0000]
+##
##
-#ToDo incomplete ##
+#SeeAlso setScale MakeScale
##
@@ -2289,15 +4268,31 @@ Possible reasons to fail: perspective, one or more scale factors are zero.
#Method static const SkMatrix& I()
-Return a reference to a const identity matrix
+Returns reference to const identity Matrix. Returned Matrix is set to:
-#Return incomplete ##
+#Code
+#Literal
+| 1 0 0 |
+| 0 1 0 |
+| 0 0 1 |
+##
+
+#Return const identity Matrix ##
#Example
-// incomplete
+ SkMatrix m1, m2, m3;
+ m1.reset();
+ m2.setIdentity();
+ m3 = SkMatrix::I();
+ SkDebugf("m1 %c= m2\n", m1 == m2 ? '=' : '!');
+ SkDebugf("m2 %c= m3\n", m1 == m2 ? '=' : '!');
+#StdOut
+m1 == m2
+m2 == m3
+##
##
-#ToDo incomplete ##
+#SeeAlso reset() setIdentity
##
@@ -2305,16 +4300,26 @@ Return a reference to a const identity matrix
#Method static const SkMatrix& InvalidMatrix()
-Return a reference to a const matrix that is "invalid", one that could
-never be used.
+Returns reference to a const Matrix with invalid values. Returned Matrix is set
+to:
+
+#Code
+#Literal
+| SK_ScalarMax SK_ScalarMax SK_ScalarMax |
+| SK_ScalarMax SK_ScalarMax SK_ScalarMax |
+| SK_ScalarMax SK_ScalarMax SK_ScalarMax |
+##
-#Return incomplete ##
+#Return const invalid Matrix ##
#Example
-// incomplete
+ SkDebugf("scaleX %g\n", SkMatrix::InvalidMatrix().getScaleX());
+#StdOut
+scaleX 3.40282e+38
+##
##
-#ToDo incomplete ##
+#SeeAlso SeeAlso getType
##
@@ -2322,18 +4327,49 @@ never be used.
#Method static SkMatrix Concat(const SkMatrix& a, const SkMatrix& b)
-Return the concatenation of two matrices, a * b.
+Returns Matrix a multiplied by Matrix b.
+
+Given:
+
+#Code
+#Literal
+ | A B C | | J K L |
+a = | D E F |, b = | M N O |
+ | G H I | | P Q R |
+##
+
+sets Matrix to:
+
+#Code
+#Literal
+ | A B C | | J K L | | AJ+BM+CP AK+BN+CQ AL+BO+CR |
+a * b = | D E F | * | M N O | = | DJ+EM+FP DK+EN+FQ DL+EO+FR |
+ | G H I | | P Q R | | GJ+HM+IP GK+HN+IQ GL+HO+IR |
+##
-#Param a incomplete ##
-#Param b incomplete ##
+#Param a Matrix on left side of multiply expression ##
+#Param b Matrix on right side of multiply expression ##
-#Return incomplete ##
+#Return Matrix computed from a times b ##
#Example
-// incomplete
+#Height 64
+#Image 4
+#Description
+setPolyToPoly creates perspective matrices, one the inverse of the other.
+Multiplying the matrix by its inverse turns into an identity matrix.
+##
+SkMatrix matrix, matrix2;
+SkPoint bitmapBounds[4], perspect[4] = {{50, 10}, {180, 40}, {236, 176}, {10, 206}};
+SkRect::Make(source.bounds()).toQuad(bitmapBounds);
+matrix.setPolyToPoly(bitmapBounds, perspect, 4);
+matrix2.setPolyToPoly(perspect, bitmapBounds, 4);
+SkMatrix concat = SkMatrix::Concat(matrix, matrix2);
+canvas->concat(concat);
+canvas->drawBitmap(source, 0, 0);
##
-#ToDo incomplete ##
+#SeeAlso preConcat postConcat
##
@@ -2341,14 +4377,29 @@ Return the concatenation of two matrices, a * b.
#Method void dirtyMatrixTypeCache()
-Testing routine; the matrix type cache should never need to be
-manually invalidated during normal use.
+Sets internal cache to unknown state. Use to force update after repeated
+modifications to Matrix element reference returned by operator[](int index).
#Example
-// incomplete
+SkMatrix matrix;
+matrix.setIdentity();
+SkDebugf("with identity matrix: x = %g\n", matrix.mapXY(24, 42).fX);
+SkScalar& skewRef = matrix[SkMatrix::kMSkewX];
+skewRef = 0;
+SkDebugf("after skew x mod: x = %g\n", matrix.mapXY(24, 42).fX);
+skewRef = 1;
+SkDebugf("after 2nd skew x mod: x = %g\n", matrix.mapXY(24, 42).fX);
+matrix.dirtyMatrixTypeCache();
+SkDebugf("after dirty cache: x = %g\n", matrix.mapXY(24, 42).fX);
+#StdOut
+with identity matrix: x = 24
+after skew x mod: x = 24
+after 2nd skew x mod: x = 24
+after dirty cache: x = 66
+##
##
-#ToDo incomplete ##
+#SeeAlso operator[](int index) getType
##
@@ -2356,18 +4407,30 @@ manually invalidated during normal use.
#Method void setScaleTranslate(SkScalar sx, SkScalar sy, SkScalar tx, SkScalar ty)
-Initialize the matrix to be scale + post-translate.
+Initializes Matrix with scale and translate elements.
-#Param sx incomplete ##
-#Param sy incomplete ##
-#Param tx incomplete ##
-#Param ty incomplete ##
+#Code
+#Literal
+| sx 0 tx |
+| 0 sy ty |
+| 0 0 1 |
+##
+
+#Param sx horizontal scale factor to store ##
+#Param sy vertical scale factor to store ##
+#Param tx horizontal translation to store ##
+#Param ty vertical translation to store ##
#Example
-// incomplete
+SkMatrix matrix;
+matrix.setScaleTranslate(1, 2, 3, 4);
+matrix.dump();
+#StdOut
+[ 1.0000 0.0000 3.0000][ 0.0000 2.0000 4.0000][ 0.0000 0.0000 1.0000]
+##
##
-#ToDo incomplete ##
+#SeeAlso setScale preTranslate postTranslate
##
@@ -2375,15 +4438,24 @@ Initialize the matrix to be scale + post-translate.
#Method bool isFinite() const
-Are all elements of the matrix finite?
+Returns true if all elements of the matrix are finite. Returns false if any
+element is infinity, or NaN.
-#Return incomplete ##
+#Return true if matrix has only finite elements ##
#Example
-// incomplete
+SkMatrix matrix = SkMatrix::MakeTrans(SK_ScalarNaN, 0);
+matrix.dump();
+SkDebugf("matrix is finite: %s\n", matrix.isFinite() ? "true" : "false");
+SkDebugf("matrix %c= matrix\n", matrix == matrix ? '=' : '!');
+#StdOut
+[ 1.0000 0.0000 nan][ 0.0000 1.0000 0.0000][ 0.0000 0.0000 1.0000]
+matrix is finite: false
+matrix != matrix
+##
##
-#ToDo incomplete ##
+#SeeAlso operator==
##
diff --git a/docs/SkPaint_Reference.bmh b/docs/SkPaint_Reference.bmh
index 96822f950f..3369cd2861 100644
--- a/docs/SkPaint_Reference.bmh
+++ b/docs/SkPaint_Reference.bmh
@@ -4177,16 +4177,6 @@ void draw(SkCanvas* canvas) {
#Struct FontMetrics
- FontMetrics is filled out by getFontMetrics. FontMetrics contents reflect the values
- computed by Font_Manager using Typeface. Values are set to zero if they are
- not available.
-
- fUnderlineThickness and fUnderlinePosition have a bit set in fFlags if their values
- are valid, since their value may be zero.
-
- fStrikeoutThickness and fStrikeoutPosition have a bit set in fFlags if their values
- are valid, since their value may be zero.
-
#Code
struct FontMetrics {
enum FontMetricsFlags {
@@ -4220,11 +4210,17 @@ void draw(SkCanvas* canvas) {
};
##
- #Enum FontMetricsFlags
+ FontMetrics is filled out by getFontMetrics. FontMetrics contents reflect the values
+ computed by Font_Manager using Typeface. Values are set to zero if they are
+ not available.
- FontMetricsFlags are set in fFlags when underline and strikeout metrics are valid;
- the underline or strikeout metric may be valid and zero.
- Fonts with embedded bitmaps may not have valid underline or strikeout metrics.
+ fUnderlineThickness and fUnderlinePosition have a bit set in fFlags if their values
+ are valid, since their value may be zero.
+
+ fStrikeoutThickness and fStrikeoutPosition have a bit set in fFlags if their values
+ are valid, since their value may be zero.
+
+ #Enum FontMetricsFlags
#Code
enum FontMetricsFlags {
@@ -4235,6 +4231,10 @@ void draw(SkCanvas* canvas) {
};
##
+ FontMetricsFlags are set in fFlags when underline and strikeout metrics are valid;
+ the underline or strikeout metric may be valid and zero.
+ Fonts with embedded bitmaps may not have valid underline or strikeout metrics.
+
#Const kUnderlineThicknessIsValid_Flag 0x0001
Set if fUnderlineThickness is valid.
##
diff --git a/docs/SkPath_Reference.bmh b/docs/SkPath_Reference.bmh
index e38b30da77..9caad2d481 100644
--- a/docs/SkPath_Reference.bmh
+++ b/docs/SkPath_Reference.bmh
@@ -456,10 +456,10 @@ kCW_Direction travel clockwise; the same added with kCCW_Direction
travel counterclockwise.
#Const kCW_Direction 0
- Contour travels in a clockwise direction.
+ Contour travels in a clockwise direction
##
#Const kCCW_Direction 1
- Contour travels in a counterclockwise direction.
+ Contour travels in a counterclockwise direction
##
@@ -744,6 +744,7 @@ Point_Array, using the formula:
#Formula
(this->points * weight) + ending->points * (1 - weight)
##
+.
weight is most useful when between zero (ending Point_Array) and
one (this Point_Array); will work with values outside of this
@@ -3464,10 +3465,10 @@ Four Oval parts with radii (rx, ry) start at last Path Point and ends at (x, y).
ArcSize and Direction select one of the four Oval parts.
#Const kSmall_ArcSize 0
-Smaller of Arc pair.
+smaller of Arc pair
##
#Const kLarge_ArcSize 1
-Larger of Arc pair.
+larger of Arc pair
##
#Example
@@ -3505,18 +3506,20 @@ void draw(SkCanvas* canvas) {
#Method void arcTo(SkScalar rx, SkScalar ry, SkScalar xAxisRotate, ArcSize largeArc,
Direction sweep, SkScalar x, SkScalar y)
-Append Arc to Path. Arc is implemented by one or more Conics weighted to describe part of Oval
-with radii (rx, ry) rotated by xAxisRotate degrees. Arc curves from last Path Point to (x, y),
-choosing one of four possible routes: clockwise or counterclockwise, and smaller or larger.
+Append Arc to Path. Arc is implemented by one or more Conics weighted to
+describe part of Oval with radii (rx, ry) rotated by xAxisRotate degrees. Arc
+curves from last Path Point to (x, y), choosing one of four possible routes:
+clockwise or counterclockwise, and smaller or larger.
-Arc sweep is always less than 360 degrees. arcTo appends Line to (x, y) if either radii are zero,
-or if last Path Point equals (x, y). arcTo scales radii (rx, ry) to fit last Path Point and
-(x, y) if both are greater than zero but too small.
+Arc sweep is always less than 360 degrees. arcTo appends Line to (x, y) if
+either radii are zero, or if last Path Point equals (x, y). arcTo scales radii
+(rx, ry) to fit last Path Point and (x, y) if both are greater than zero but
+too small.
arcTo appends up to four Conic curves.
-arcTo implements the functionality of SVG_Arc, although SVG "sweep-flag" value is
-opposite the integer value of sweep; SVG "sweep-flag" uses 1 for clockwise, while kCW_Direction
-cast to int is zero.
+arcTo implements the functionality of SVG_Arc, although SVG "sweep-flag" value
+is opposite the integer value of sweep; SVG "sweep-flag" uses 1 for clockwise,
+while kCW_Direction cast to int is zero.
#Param rx radius in x before x-axis rotation ##
#Param ry radius in y before x-axis rotation ##
@@ -3601,7 +3604,8 @@ void draw(SkCanvas* canvas) {
Append Arc to Path, relative to last Path Point. Arc is implemented by one or
more Conic, weighted to describe part of Oval with radii (rx, ry) rotated by
-xAxisRotate degrees. Arc curves from last Path Point (x0, y0) to end Point
+xAxisRotate degrees. Arc curves from last Path Point (x0, y0) to end Point:
+
#Formula
(x0 + dx, y0 + dy)
##
@@ -3812,8 +3816,9 @@ next Quad. Maximum pts storage size is given by:
#Formula
(1 + 2 * (1 << pow2)) * sizeof(SkPoint)
##
+.
-ConvertConicToQuads returns Quad count used the approximation, which may be smaller
+Returns Quad count used the approximation, which may be smaller
than the number requested.
Conic_Weight determines the amount of influence Conic control point has on the curve.
@@ -4200,12 +4205,12 @@ void draw(SkCanvas* canvas) {
Direction dir = kCW_Direction)
Add Circle centered at (x, y) of size radius to Path, appending kMove_Verb,
-four kConic_Verb, and kClose_Verb. Circle begins at
+four kConic_Verb, and kClose_Verb. Circle begins at:
#Formula
(x + radius, y)
##
-, continuing clockwise if dir is kCW_Direction, and counterclockwise if dir is
-kCCW_Direction.
+, continuing
+clockwise if dir is kCW_Direction, and counterclockwise if dir is kCCW_Direction.
Has no effect if radius is zero or negative.
@@ -5040,9 +5045,9 @@ for (int y = 2; y < 256; y += 9) {
#Method void dump(SkWStream* stream, bool forceClose, bool dumpAsHex) const
-Writes text representation of Path to stream. If stream is nullptr, dump() writes to
-standard output. Set forceClose to true to get
-edges used to fill Path. Set dumpAsHex true to generate exact binary representations
+Writes text representation of Path to stream. If stream is nullptr, writes to
+standard output. Set forceClose to true to get edges used to fill Path.
+Set dumpAsHex true to generate exact binary representations
of floating point numbers used in Point_Array and Conic_Weights.
#Param stream writable Stream receiving Path text representation; may be nullptr ##
diff --git a/docs/SkPixmap_Reference.bmh b/docs/SkPixmap_Reference.bmh
index 837d3af153..9cec400b4b 100644
--- a/docs/SkPixmap_Reference.bmh
+++ b/docs/SkPixmap_Reference.bmh
@@ -55,13 +55,11 @@ to manage pixel memory; Pixel_Ref is safe across threads.
# bounds() # Returns width and height as Rectangle. ##
# colorSpace # Returns Image_Info Color_Space. ##
# colorType # Returns Image_Info Color_Type. ##
+# computeByteSize # Returns size required for pixels. ##
# computeIsOpaque # Returns true if all pixels are opaque. ##
# erase() # Writes Color to pixels. ##
# extractSubset # Sets pointer to portion of original. ##
# getColor # Returns one pixel as Unpremultiplied Color. ##
-# getSafeSize # Returns minimum size required for pixels in 32 bits. ##
-# getSafeSize64 # Returns minimum size required for pixels in 64 bits. ##
-# getSize64 # Returns conservative size required for pixels. ##
# height() # Returns pixel row count. ##
# info() # Returns Image_Info. ##
# isOpaque # Returns true if Image_Info describes opaque pixels. ##
@@ -395,7 +393,7 @@ width: 384 height: 384 color: BGRA_8888 alpha: Opaque
#Method size_t rowBytes() const
Returns row bytes, the interval from one pixel row to the next. Row bytes
-is at least as large as
+is at least as large as:
#Formula
width() * info().bytesPerPixel()
##
@@ -461,6 +459,7 @@ inset address: 0x7f2a440fb210
#Method int width() const
Returns pixel count in each pixel row. Should be equal or less than:
+
#Formula
rowBytes() / info().bytesPerPixel()
##
@@ -622,11 +621,7 @@ isOpaque: true
#Method SkIRect bounds() const
-Returns IRect
-#Formula
-{ 0, 0, width(), height() }
-##
-.
+Returns IRect { 0, 0, width(), height() }.
#Return integral rectangle from origin to width() and height() ##
@@ -718,66 +713,6 @@ color: kRGBA_F16_SkColorType bytesPerPixel: 8 shiftPerPixel: 3
# ------------------------------------------------------------------------------
-#Method uint64_t getSize64() const
-
-#Deprecated
-##
-
-Returns conservative memory required for pixel storage.
-Includes unused memory on last row when rowBytesAsPixels exceeds width().
-
-#Return conservative pixel storage size ##
-
-#NoExample
-##
-
-#SeeAlso getSafeSize64 getSafeSize height() rowBytes width() SkImageInfo::bytesPerPixel
-
-##
-
-# ------------------------------------------------------------------------------
-
-#Method uint64_t getSafeSize64() const
-
-#Deprecated
-##
-
-Returns minimum memory required for pixel storage.
-Does not include unused memory on last row when rowBytesAsPixels exceeds width().
-
-#Return exact pixel storage size ##
-
-#NoExample
-##
-
-#SeeAlso getSize64 getSafeSize height() rowBytes width() SkImageInfo::bytesPerPixel
-
-##
-
-# ------------------------------------------------------------------------------
-
-#Method size_t getSafeSize() const
-
-#Deprecated
-##
-
-Returns minimum memory required for pixel storage.
-Does not include unused memory on last row when rowBytesAsPixels exceeds width().
-Returns zero if value is does not fit in a signed 32-bit integer.
-The largest value than can be returned is 2,147,483,647.
-
-#Return exact pixel storage size if size fits in signed 32 bits ##
-
-#NoExample
-##
-
-#SeeAlso getSize64 getSafeSize64 height() rowBytes width() SkImageInfo::bytesPerPixel sk_64_isS32
-
-##
-
-
-# ------------------------------------------------------------------------------
-
#Method size_t computeByteSize() const
Returns minimum memory required for pixel storage.
@@ -1574,11 +1509,8 @@ is drawn after overwriting bottom half float color with top half float color.
#Method bool readPixels(const SkImageInfo& dstInfo, void* dstPixels, size_t dstRowBytes,
int srcX, int srcY, SkTransferFunctionBehavior behavior) const
-Copies a Rect of pixels to dstPixels. Copy starts at (srcX, srcY), and does not exceed
-#Formula
-(this->width(), this->height())
-##
-.
+Copies a Rect of pixels to dstPixels. Copy starts at (srcX, srcY), and does not
+exceed (this->width(), this->height()).
dstInfo specifies width, height, Color_Type, Alpha_Type, and
Color_Space of destination. dstRowBytes specifics the gap from one destination
@@ -1593,7 +1525,8 @@ match. If this->colorSpace is nullptr, dstInfo.colorSpace must match. Returns
false if pixel conversion is not possible.
srcX and srcY may be negative to copy only top or left of source. Returns
-false if width() or height() is zero or negative. Returns false if
+false if width() or height() is zero or negative. Returns false if:
+
#Formula
abs(srcX) >= this->width()
##
@@ -1655,11 +1588,7 @@ void draw(SkCanvas* canvas) {
#Method bool readPixels(const SkImageInfo& dstInfo, void* dstPixels, size_t dstRowBytes) const
Copies a Rect of pixels to dstPixels. Copy starts at (0, 0), and does not
-exceed
-#Formula
-(this->width(), this->height())
-##
-.
+exceed (this->width(), this->height()).
dstInfo specifies width, height, Color_Type, Alpha_Type, and
Color_Space of destination. dstRowBytes specifics the gap from one destination
@@ -1722,11 +1651,7 @@ creates visible banding.
int srcY) const
Copies a Rect of pixels to dstPixels. Copy starts at (srcX, srcY), and does not
-exceed
-#Formula
-(this->width(), this->height())
-##
-.
+exceed (this->width(), this->height()).
dstInfo specifies width, height, Color_Type, Alpha_Type, and
Color_Space of destination. dstRowBytes specifics the gap from one destination
@@ -1741,7 +1666,8 @@ match. If this->colorSpace is nullptr, dstInfo.colorSpace must match. Returns
false if pixel conversion is not possible.
srcX and srcY may be negative to copy only top or left of source. Returns
-false if this->width() or this->height() is zero or negative. Returns false if
+false if this->width() or this->height() is zero or negative. Returns false if:
+
#Formula
abs(srcX) >= this->width()
##
@@ -1803,7 +1729,8 @@ match. If this->colorSpace is nullptr, dst.info().colorSpace must match. Returns
false if pixel conversion is not possible.
srcX and srcY may be negative to copy only top or left of source. Returns
-false this->width() or this->height() is zero or negative. Returns false if
+false this->width() or this->height() is zero or negative. Returns false if:
+
#Formula
abs(srcX) >= this->width()
##
diff --git a/docs/SkRect_Reference.bmh b/docs/SkRect_Reference.bmh
index 7dc1e3776a..1a28f1bd12 100644
--- a/docs/SkRect_Reference.bmh
+++ b/docs/SkRect_Reference.bmh
@@ -136,20 +136,20 @@ is a convenience, but does not designate a special empty rectangle.
#Return bounds (0, 0, 0, 0) ##
#Example
- SkRect rect = SkRect::MakeEmpty();
- SkDebugf("MakeEmpty isEmpty: %s\n", rect.isEmpty() ? "true" : "false");
- rect.offset(10, 10);
- SkDebugf("offset rect isEmpty: %s\n", rect.isEmpty() ? "true" : "false");
- rect.inset(10, 10);
- SkDebugf("inset rect isEmpty: %s\n", rect.isEmpty() ? "true" : "false");
- rect.outset(20, 20);
- SkDebugf("outset rect isEmpty: %s\n", rect.isEmpty() ? "true" : "false");
-#StdOut
-MakeEmpty isEmpty: true
-offset rect isEmpty: true
-inset rect isEmpty: true
-outset rect isEmpty: false
-##
+ SkRect rect = SkRect::MakeEmpty();
+ SkDebugf("MakeEmpty isEmpty: %s\n", rect.isEmpty() ? "true" : "false");
+ rect.offset(10, 10);
+ SkDebugf("offset rect isEmpty: %s\n", rect.isEmpty() ? "true" : "false");
+ rect.inset(10, 10);
+ SkDebugf("inset rect isEmpty: %s\n", rect.isEmpty() ? "true" : "false");
+ rect.outset(20, 20);
+ SkDebugf("outset rect isEmpty: %s\n", rect.isEmpty() ? "true" : "false");
+#StdOut
+MakeEmpty isEmpty: true
+offset rect isEmpty: true
+inset rect isEmpty: true
+outset rect isEmpty: false
+##
##
#SeeAlso isEmpty setEmpty setLargestInverted SkIRect::MakeEmpty
@@ -166,23 +166,23 @@ setting right and bottom to most positive finite value.
#Return bounds (SK_ScalarMin, SK_ScalarMin, SK_ScalarMax, SK_ScalarMax) ##
#Example
- SkRect rect = SkRect::MakeLargest();
- SkDebugf("MakeLargest isLargest: %s\n", rect.isLargest() ? "true" : "false");
- SkDebugf("MakeLargest isFinite: %s\n", rect.isFinite() ? "true" : "false");
- rect.outset(1e31, 1e31);
- SkDebugf("outset a little isLargest: %s\n", rect.isLargest() ? "true" : "false");
- SkDebugf("outset a little isFinite: %s\n", rect.isFinite() ? "true" : "false");
- rect.outset(1e32, 1e32);
- SkDebugf("outset a little more isLargest: %s\n", rect.isLargest() ? "true" : "false");
- SkDebugf("outset a little more isFinite: %s\n", rect.isFinite() ? "true" : "false");
-#StdOut
-MakeLargest isLargest: true
-MakeLargest isFinite: true
-outset a little isLargest: true
-outset a little isFinite: true
-outset a little more isLargest: false
-outset a little more isFinite: false
-##
+ SkRect rect = SkRect::MakeLargest();
+ SkDebugf("MakeLargest isLargest: %s\n", rect.isLargest() ? "true" : "false");
+ SkDebugf("MakeLargest isFinite: %s\n", rect.isFinite() ? "true" : "false");
+ rect.outset(1e31, 1e31);
+ SkDebugf("outset a little isLargest: %s\n", rect.isLargest() ? "true" : "false");
+ SkDebugf("outset a little isFinite: %s\n", rect.isFinite() ? "true" : "false");
+ rect.outset(1e32, 1e32);
+ SkDebugf("outset a little more isLargest: %s\n", rect.isLargest() ? "true" : "false");
+ SkDebugf("outset a little more isFinite: %s\n", rect.isFinite() ? "true" : "false");
+#StdOut
+MakeLargest isLargest: true
+MakeLargest isFinite: true
+outset a little isLargest: true
+outset a little isFinite: true
+outset a little more isLargest: false
+outset a little more isFinite: false
+##
##
#SeeAlso MakeLargestS32 isLargest setLargest SkIRect::MakeLargest
@@ -205,13 +205,13 @@ These are the largest values for which round() is well defined.
##
#Example
- SkRect f_rect = SkRect::MakeLargestS32();
- SkIRect i_rect = f_rect.round();
- SkRect r_rect = SkRect::Make(i_rect);
- SkDebugf("f_rect %c= r_rect\n", f_rect == r_rect ? '=' : '!');
-#StdOut
-f_rect == r_rect
-##
+ SkRect f_rect = SkRect::MakeLargestS32();
+ SkIRect i_rect = f_rect.round();
+ SkRect r_rect = SkRect::Make(i_rect);
+ SkDebugf("f_rect %c= r_rect\n", f_rect == r_rect ? '=' : '!');
+#StdOut
+f_rect == r_rect
+##
##
#SeeAlso MakeLargest isLargest setLargest SkIRect::MakeLargest
@@ -234,11 +234,11 @@ represent 32-bit integers exactly. Use SkIRect for an exact integer rectangle.
#Return bounds (0, 0, w, h) ##
#Example
- SkRect rect1 = SkRect::MakeWH(25, 35);
- SkRect rect2 = SkRect::MakeIWH(25, 35);
- SkRect rect3 = SkRect::MakeXYWH(0, 0, 25, 35);
- SkRect rect4 = SkRect::MakeLTRB(0, 0, 25, 35);
- SkDebugf("all %s" "equal\n", rect1 == rect2 && rect2 == rect3 && rect3 == rect4 ?
+ SkRect rect1 = SkRect::MakeWH(25, 35);
+ SkRect rect2 = SkRect::MakeIWH(25, 35);
+ SkRect rect3 = SkRect::MakeXYWH(0, 0, 25, 35);
+ SkRect rect4 = SkRect::MakeLTRB(0, 0, 25, 35);
+ SkDebugf("all %s" "equal\n", rect1 == rect2 && rect2 == rect3 && rect3 == rect4 ?
"" : "not ");
#StdOut
all equal
@@ -265,14 +265,14 @@ Use SkIRect for an exact integer rectangle.
#Return bounds (0, 0, w, h) ##
#Example
- SkIRect i_rect = SkIRect::MakeWH(25, 35);
- SkRect f_rect = SkRect::MakeIWH(25, 35);
- SkDebugf("i_rect width: %d f_rect width:%g\n", i_rect.width(), f_rect.width());
- i_rect = SkIRect::MakeWH(125000111, 0);
- f_rect = SkRect::MakeIWH(125000111, 0);
- SkDebugf("i_rect width: %d f_rect width:%.0f\n", i_rect.width(), f_rect.width());
+ SkIRect i_rect = SkIRect::MakeWH(25, 35);
+ SkRect f_rect = SkRect::MakeIWH(25, 35);
+ SkDebugf("i_rect width: %d f_rect width:%g\n", i_rect.width(), f_rect.width());
+ i_rect = SkIRect::MakeWH(125000111, 0);
+ f_rect = SkRect::MakeIWH(125000111, 0);
+ SkDebugf("i_rect width: %d f_rect width:%.0f\n", i_rect.width(), f_rect.width());
#StdOut
-i_rect width: 25 f_rect width:25
+i_rect width: 25 f_rect width:25
i_rect width: 125000111 f_rect width:125000112
##
##
@@ -293,14 +293,14 @@ validate input; size.width() or size.height() may be negative.
#Return bounds (0, 0, size.width(), size.height()) ##
#Example
- SkSize size = {25.5f, 35.5f};
- SkRect rect = SkRect::MakeSize(size);
- SkDebugf("rect width: %g height: %g\n", rect.width(), rect.height());
- SkISize floor = size.toFloor();
- rect = SkRect::MakeSize(SkSize::Make(floor));
- SkDebugf("floor width: %g height: %g\n", rect.width(), rect.height());
+ SkSize size = {25.5f, 35.5f};
+ SkRect rect = SkRect::MakeSize(size);
+ SkDebugf("rect width: %g height: %g\n", rect.width(), rect.height());
+ SkISize floor = size.toFloor();
+ rect = SkRect::MakeSize(SkSize::Make(floor));
+ SkDebugf("floor width: %g height: %g\n", rect.width(), rect.height());
#StdOut
-rect width: 25.5 height: 35.5
+rect width: 25.5 height: 35.5
floor width: 25 height: 35
##
##
@@ -325,14 +325,14 @@ result in fLeft greater than fRight, or fTop greater than fBottom.
#Return bounds (l, t, r, b) ##
#Example
- SkRect rect = SkRect::MakeLTRB(5, 35, 15, 25);
- SkDebugf("rect: %g, %g, %g, %g isEmpty: %s\n", rect.left(), rect.top(), rect.right(),
- rect.bottom(), rect.isEmpty() ? "true" : "false");
- rect.sort();
- SkDebugf("rect: %g, %g, %g, %g isEmpty: %s\n", rect.left(), rect.top(), rect.right(),
- rect.bottom(), rect.isEmpty() ? "true" : "false");
+ SkRect rect = SkRect::MakeLTRB(5, 35, 15, 25);
+ SkDebugf("rect: %g, %g, %g, %g isEmpty: %s\n", rect.left(), rect.top(), rect.right(),
+ rect.bottom(), rect.isEmpty() ? "true" : "false");
+ rect.sort();
+ SkDebugf("rect: %g, %g, %g, %g isEmpty: %s\n", rect.left(), rect.top(), rect.right(),
+ rect.bottom(), rect.isEmpty() ? "true" : "false");
#StdOut
-rect: 5, 35, 15, 25 isEmpty: true
+rect: 5, 35, 15, 25 isEmpty: true
rect: 5, 25, 15, 35 isEmpty: false
##
##
@@ -360,14 +360,14 @@ w or h may be negative.
#Return bounds at (x, y) with width w and height h ##
#Example
- SkRect rect = SkRect::MakeXYWH(5, 35, -15, 25);
- SkDebugf("rect: %g, %g, %g, %g isEmpty: %s\n", rect.left(), rect.top(), rect.right(),
- rect.bottom(), rect.isEmpty() ? "true" : "false");
- rect.sort();
- SkDebugf("rect: %g, %g, %g, %g isEmpty: %s\n", rect.left(), rect.top(), rect.right(),
- rect.bottom(), rect.isEmpty() ? "true" : "false");
+ SkRect rect = SkRect::MakeXYWH(5, 35, -15, 25);
+ SkDebugf("rect: %g, %g, %g, %g isEmpty: %s\n", rect.left(), rect.top(), rect.right(),
+ rect.bottom(), rect.isEmpty() ? "true" : "false");
+ rect.sort();
+ SkDebugf("rect: %g, %g, %g, %g isEmpty: %s\n", rect.left(), rect.top(), rect.right(),
+ rect.bottom(), rect.isEmpty() ? "true" : "false");
#StdOut
-rect: 5, 35, -10, 60 isEmpty: true
+rect: 5, 35, -10, 60 isEmpty: true
rect: -10, 35, 5, 60 isEmpty: false
##
##
@@ -408,9 +408,9 @@ Does not validate input; size.width() or size.height() may be negative.
#Return bounds (0, 0, size.width(), size.height()) ##
#Example
- SkRect rect1 = SkRect::MakeSize({2, 35});
- SkRect rect2 = SkRect::MakeIWH(2, 35);
- SkDebugf("rect1 %c= rect2\n", rect1 == rect2 ? '=' : '!');
+ SkRect rect1 = SkRect::MakeSize({2, 35});
+ SkRect rect2 = SkRect::MakeIWH(2, 35);
+ SkDebugf("rect1 %c= rect2\n", rect1 == rect2 ? '=' : '!');
#StdOut
rect1 == rect2
##
@@ -433,12 +433,12 @@ than fBottom.
#Return irect members converted to SkScalar ##
#Example
- SkIRect i_rect1 = {2, 35, 22, 53};
- SkRect f_rect = SkRect::Make(i_rect1);
- f_rect.offset(0.49f, 0.49f);
- SkIRect i_rect2;
- f_rect.round(&i_rect2);
- SkDebugf("i_rect1 %c= i_rect2\n", i_rect1 == i_rect2? '=' : '!');
+ SkIRect i_rect1 = {2, 35, 22, 53};
+ SkRect f_rect = SkRect::Make(i_rect1);
+ f_rect.offset(0.49f, 0.49f);
+ SkIRect i_rect2;
+ f_rect.round(&i_rect2);
+ SkDebugf("i_rect1 %c= i_rect2\n", i_rect1 == i_rect2? '=' : '!');
##
#SeeAlso MakeLTRB
@@ -456,20 +456,20 @@ width() or height().
#Return true if width() or height() are zero or negative ##
#Example
- SkRect tests[] = {{20, 40, 10, 50}, {20, 40, 20, 50}};
- for (auto rect : tests) {
- SkDebugf("rect: {%g, %g, %g, %g} is" "%s empty\n", rect.left(), rect.top(), rect.right(),
- rect.bottom(), rect.isEmpty() ? "" : " not");
- rect.sort();
- SkDebugf("sorted: {%g, %g, %g, %g} is" "%s empty\n", rect.left(), rect.top(), rect.right(),
- rect.bottom(), rect.isEmpty() ? "" : " not");
- }
-#StdOut
-rect: {20, 40, 10, 50} is empty
-sorted: {10, 40, 20, 50} is not empty
-rect: {20, 40, 20, 50} is empty
-sorted: {20, 40, 20, 50} is empty
-##
+ SkRect tests[] = {{20, 40, 10, 50}, {20, 40, 20, 50}};
+ for (auto rect : tests) {
+ SkDebugf("rect: {%g, %g, %g, %g} is" "%s empty\n", rect.left(), rect.top(), rect.right(),
+ rect.bottom(), rect.isEmpty() ? "" : " not");
+ rect.sort();
+ SkDebugf("sorted: {%g, %g, %g, %g} is" "%s empty\n", rect.left(), rect.top(), rect.right(),
+ rect.bottom(), rect.isEmpty() ? "" : " not");
+ }
+#StdOut
+rect: {20, 40, 10, 50} is empty
+sorted: {10, 40, 20, 50} is not empty
+rect: {20, 40, 20, 50} is empty
+sorted: {20, 40, 20, 50} is empty
+##
##
#SeeAlso MakeEmpty sort SkIRect::isEmpty
@@ -487,20 +487,20 @@ width() or height().
#Return true if width() or height() are zero or positive ##
#Example
- SkRect tests[] = {{20, 40, 10, 50}, {20, 40, 20, 50}};
- for (auto rect : tests) {
- SkDebugf("rect: {%g, %g, %g, %g} is" "%s sorted\n", rect.left(), rect.top(), rect.right(),
- rect.bottom(), rect.isSorted() ? "" : " not");
- rect.sort();
- SkDebugf("sorted: {%g, %g, %g, %g} is" "%s sorted\n", rect.left(), rect.top(), rect.right(),
- rect.bottom(), rect.isSorted() ? "" : " not");
- }
-#StdOut
-rect: {20, 40, 10, 50} is not sorted
-sorted: {10, 40, 20, 50} is sorted
-rect: {20, 40, 20, 50} is sorted
-sorted: {20, 40, 20, 50} is sorted
-##
+ SkRect tests[] = {{20, 40, 10, 50}, {20, 40, 20, 50}};
+ for (auto rect : tests) {
+ SkDebugf("rect: {%g, %g, %g, %g} is" "%s sorted\n", rect.left(), rect.top(), rect.right(),
+ rect.bottom(), rect.isSorted() ? "" : " not");
+ rect.sort();
+ SkDebugf("sorted: {%g, %g, %g, %g} is" "%s sorted\n", rect.left(), rect.top(), rect.right(),
+ rect.bottom(), rect.isSorted() ? "" : " not");
+ }
+#StdOut
+rect: {20, 40, 10, 50} is not sorted
+sorted: {10, 40, 20, 50} is sorted
+rect: {20, 40, 20, 50} is sorted
+sorted: {20, 40, 20, 50} is sorted
+##
##
#SeeAlso sort makeSorted isEmpty
@@ -519,16 +519,16 @@ Returns true if Rect encloses largest possible area.
#Description
Note that the width cannot be represented as a 32-bit finite value.
##
- SkRect large = SkRect::MakeLargest();
- SkDebugf("large is largest: %s\n" ,large.isLargest() ? "true" : "false");
- SkDebugf("large width %g\n", large.width());
- SkDebugf("large is empty: %s\n", large.isEmpty() ? "true" : "false");
+ SkRect large = SkRect::MakeLargest();
+ SkDebugf("large is largest: %s\n" ,large.isLargest() ? "true" : "false");
+ SkDebugf("large width %g\n", large.width());
+ SkDebugf("large is empty: %s\n", large.isEmpty() ? "true" : "false");
SkDebugf("large is sorted: %s\n", large.isSorted() ? "true" : "false");
- SkDebugf("large is finite: %s\n", large.isFinite() ? "true" : "false");
-#StdOut
-large is largest: true
-large width inf
-large is empty: false
+ SkDebugf("large is finite: %s\n", large.isFinite() ? "true" : "false");
+#StdOut
+large is largest: true
+large width inf
+large is empty: false
large is sorted: true
large is finite: true
##
@@ -548,14 +548,14 @@ and SK_ScalarMax or smaller.
#Return true if no member is infinite or NaN ##
#Example
- SkRect largest = SkRect::MakeLargest();
- SkDebugf("largest is finite: %s\n", largest.isFinite() ? "true" : "false");
- SkDebugf("large width %g\n", largest.width());
- SkRect widest = SkRect::MakeWH(largest.width(), largest.height());
- SkDebugf("widest is finite: %s\n", widest.isFinite() ? "true" : "false");
-#StdOut
-largest is finite: true
-large width inf
+ SkRect largest = SkRect::MakeLargest();
+ SkDebugf("largest is finite: %s\n", largest.isFinite() ? "true" : "false");
+ SkDebugf("large width %g\n", largest.width());
+ SkRect widest = SkRect::MakeWH(largest.width(), largest.height());
+ SkDebugf("widest is finite: %s\n", widest.isFinite() ? "true" : "false");
+#StdOut
+largest is finite: true
+large width inf
widest is finite: false
##
##
@@ -574,12 +574,12 @@ Call sort() to reverse fLeft and fRight if needed.
#Return fLeft ##
#Example
- SkRect unsorted = { 15, 5, 10, 25 };
- SkDebugf("unsorted.fLeft: %g unsorted.x(): %g\n", unsorted.fLeft, unsorted.x());
- SkRect sorted = unsorted.makeSorted();
- SkDebugf("sorted.fLeft: %g sorted.x(): %g\n", sorted.fLeft, sorted.x());
+ SkRect unsorted = { 15, 5, 10, 25 };
+ SkDebugf("unsorted.fLeft: %g unsorted.x(): %g\n", unsorted.fLeft, unsorted.x());
+ SkRect sorted = unsorted.makeSorted();
+ SkDebugf("sorted.fLeft: %g sorted.x(): %g\n", sorted.fLeft, sorted.x());
#StdOut
-unsorted.fLeft: 15 unsorted.x(): 15
+unsorted.fLeft: 15 unsorted.x(): 15
sorted.fLeft: 10 sorted.x(): 10
##
##
@@ -598,12 +598,12 @@ and sort() to reverse fTop and fBottom if needed.
#Return fTop ##
#Example
- SkRect unsorted = { 15, 25, 10, 5 };
- SkDebugf("unsorted.fTop: %g unsorted.y(): %g\n", unsorted.fTop, unsorted.y());
- SkRect sorted = unsorted.makeSorted();
+ SkRect unsorted = { 15, 25, 10, 5 };
+ SkDebugf("unsorted.fTop: %g unsorted.y(): %g\n", unsorted.fTop, unsorted.y());
+ SkRect sorted = unsorted.makeSorted();
SkDebugf("sorted.fTop: %g sorted.y(): %g\n", sorted.fTop, sorted.y());
#StdOut
-unsorted.fTop: 25 unsorted.y(): 25
+unsorted.fTop: 25 unsorted.y(): 25
sorted.fTop: 5 sorted.y(): 5
##
##
@@ -622,12 +622,12 @@ Call sort() to reverse fLeft and fRight if needed.
#Return fLeft ##
#Example
- SkRect unsorted = { 15, 5, 10, 25 };
- SkDebugf("unsorted.fLeft: %g unsorted.left(): %g\n", unsorted.fLeft, unsorted.left());
- SkRect sorted = unsorted.makeSorted();
- SkDebugf("sorted.fLeft: %g sorted.left(): %g\n", sorted.fLeft, sorted.left());
+ SkRect unsorted = { 15, 5, 10, 25 };
+ SkDebugf("unsorted.fLeft: %g unsorted.left(): %g\n", unsorted.fLeft, unsorted.left());
+ SkRect sorted = unsorted.makeSorted();
+ SkDebugf("sorted.fLeft: %g sorted.left(): %g\n", sorted.fLeft, sorted.left());
#StdOut
-unsorted.fLeft: 15 unsorted.left(): 15
+unsorted.fLeft: 15 unsorted.left(): 15
sorted.fLeft: 10 sorted.left(): 10
##
##
@@ -646,12 +646,12 @@ and sort() to reverse fTop and fBottom if needed.
#Return fTop ##
#Example
- SkRect unsorted = { 15, 25, 10, 5 };
- SkDebugf("unsorted.fTop: %g unsorted.top(): %g\n", unsorted.fTop, unsorted.top());
- SkRect sorted = unsorted.makeSorted();
+ SkRect unsorted = { 15, 25, 10, 5 };
+ SkDebugf("unsorted.fTop: %g unsorted.top(): %g\n", unsorted.fTop, unsorted.top());
+ SkRect sorted = unsorted.makeSorted();
SkDebugf("sorted.fTop: %g sorted.top(): %g\n", sorted.fTop, sorted.top());
#StdOut
-unsorted.fTop: 25 unsorted.top(): 25
+unsorted.fTop: 25 unsorted.top(): 25
sorted.fTop: 5 sorted.top(): 5
##
##
@@ -670,12 +670,12 @@ Call sort() to reverse fLeft and fRight if needed.
#Return fRight ##
#Example
- SkRect unsorted = { 15, 25, 10, 5 };
- SkDebugf("unsorted.fRight: %g unsorted.right(): %g\n", unsorted.fRight, unsorted.right());
- SkRect sorted = unsorted.makeSorted();
- SkDebugf("sorted.fRight: %g sorted.right(): %g\n", sorted.fRight, sorted.right());
+ SkRect unsorted = { 15, 25, 10, 5 };
+ SkDebugf("unsorted.fRight: %g unsorted.right(): %g\n", unsorted.fRight, unsorted.right());
+ SkRect sorted = unsorted.makeSorted();
+ SkDebugf("sorted.fRight: %g sorted.right(): %g\n", sorted.fRight, sorted.right());
#StdOut
-unsorted.fRight: 10 unsorted.right(): 10
+unsorted.fRight: 10 unsorted.right(): 10
sorted.fRight: 15 sorted.right(): 15
##
##
@@ -694,12 +694,12 @@ and sort() to reverse fTop and fBottom if needed.
#Return fBottom ##
#Example
- SkRect unsorted = { 15, 25, 10, 5 };
- SkDebugf("unsorted.fBottom: %g unsorted.bottom(): %g\n", unsorted.fBottom, unsorted.bottom());
- SkRect sorted = unsorted.makeSorted();
- SkDebugf("sorted.fBottom: %g sorted.bottom(): %g\n", sorted.fBottom, sorted.bottom());
+ SkRect unsorted = { 15, 25, 10, 5 };
+ SkDebugf("unsorted.fBottom: %g unsorted.bottom(): %g\n", unsorted.fBottom, unsorted.bottom());
+ SkRect sorted = unsorted.makeSorted();
+ SkDebugf("sorted.fBottom: %g sorted.bottom(): %g\n", sorted.fBottom, sorted.bottom());
#StdOut
-unsorted.fBottom: 5 unsorted.bottom(): 5
+unsorted.fBottom: 5 unsorted.bottom(): 5
sorted.fBottom: 25 sorted.bottom(): 25
##
##
@@ -721,12 +721,12 @@ result fits in 32-bit float; result may be negative or infinity.
#Description
Compare with SkIRect::width() example.
##
- SkRect unsorted = { 15, 25, 10, 5 };
- SkDebugf("unsorted width: %g\n", unsorted.width());
- SkRect large = { -2147483647.f, 1, 2147483644.f, 2 };
- SkDebugf("large width: %.0f\n", large.width());
+ SkRect unsorted = { 15, 25, 10, 5 };
+ SkDebugf("unsorted width: %g\n", unsorted.width());
+ SkRect large = { -2147483647.f, 1, 2147483644.f, 2 };
+ SkDebugf("large width: %.0f\n", large.width());
#StdOut
-unsorted width: -5
+unsorted width: -5
large width: 4294967296
##
##
@@ -748,12 +748,12 @@ result fits in 32-bit float; result may be negative or infinity.
#Description
Compare with SkIRect::height() example.
##
- SkRect unsorted = { 15, 25, 10, 20 };
- SkDebugf("unsorted height: %g\n", unsorted.height());
- SkRect large = { 1, -2147483647.f, 2, 2147483644.f };
- SkDebugf("large height: %.0f\n", large.height());
+ SkRect unsorted = { 15, 25, 10, 20 };
+ SkDebugf("unsorted height: %g\n", unsorted.height());
+ SkRect large = { 1, -2147483647.f, 2, 2147483644.f };
+ SkDebugf("large height: %.0f\n", large.height());
#StdOut
-unsorted height: -5
+unsorted height: -5
large height: 4294967296
##
##
@@ -772,16 +772,16 @@ is sorted. Result may overflow to infinity if Rect is far from the origin.
#Return midpoint in x ##
#Example
- SkRect tests[] = {{20, 30, 41, 51}, {-20, -30, -41, -51}};
- for (auto rect : tests) {
- SkDebugf("left: %3g right: %3g centerX: %3g\n", rect.left(), rect.right(), rect.centerX());
- rect.sort();
- SkDebugf("left: %3g right: %3g centerX: %3g\n", rect.left(), rect.right(), rect.centerX());
- }
+ SkRect tests[] = {{20, 30, 41, 51}, {-20, -30, -41, -51}};
+ for (auto rect : tests) {
+ SkDebugf("left: %3g right: %3g centerX: %3g\n", rect.left(), rect.right(), rect.centerX());
+ rect.sort();
+ SkDebugf("left: %3g right: %3g centerX: %3g\n", rect.left(), rect.right(), rect.centerX());
+ }
#StdOut
-left: 20 right: 41 centerX: 30.5
-left: 20 right: 41 centerX: 30.5
-left: -20 right: -41 centerX: -30.5
+left: 20 right: 41 centerX: 30.5
+left: 20 right: 41 centerX: 30.5
+left: -20 right: -41 centerX: -30.5
left: -41 right: -20 centerX: -30.5
##
##
@@ -800,9 +800,9 @@ is sorted. Result may overflow to infinity if Rect is far from the origin.
#Return midpoint in y ##
#Example
- SkRect rect = { 2e+38, 2e+38, 3e+38, 3e+38 };
- SkDebugf("left: %g right: %g centerX: %g ", rect.left(), rect.right(), rect.centerX());
- SkDebugf("safe mid x: %g\n", rect.left() / 2 + rect.right() / 2);
+ SkRect rect = { 2e+38, 2e+38, 3e+38, 3e+38 };
+ SkDebugf("left: %g right: %g centerX: %g ", rect.left(), rect.right(), rect.centerX());
+ SkDebugf("safe mid x: %g\n", rect.left() / 2 + rect.right() / 2);
#StdOut
left: 2e+38 right: 3e+38 centerX: inf safe mid x: 2.5e+38
##
@@ -828,25 +828,25 @@ contain zeroes width different signs.
#Return true if members are equal ##
#Example
- auto debugster = [](const SkRect& test) -> void {
- SkRect negZero = {-0.0f, -0.0f, 2, 2};
- SkDebugf("{%g, %g, %g, %g} %c= {%g, %g, %g, %g} %s numerically equal\n",
- test.fLeft, test.fTop, test.fRight, test.fBottom,
- negZero.fLeft, negZero.fTop, negZero.fRight, negZero.fBottom,
- test == negZero ? '=' : '!',
- test.fLeft == negZero.fLeft && test.fTop == negZero.fTop &&
- test.fRight == negZero.fRight && test.fBottom == negZero.fBottom ?
- "and are" : "yet are not");
- };
- SkRect tests[] = {{0, 0, 2, 2}, {-0, -0, 2, 2}, {0.0f, 0.0f, 2, 2}};
- SkDebugf("tests are %s" "equal\n", tests[0] == tests[1] && tests[1] == tests[2] ? "" : "not ");
- for (auto rect : tests) {
- debugster(rect);
+ auto debugster = [](const SkRect& test) -> void {
+ SkRect negZero = {-0.0f, -0.0f, 2, 2};
+ SkDebugf("{%g, %g, %g, %g} %c= {%g, %g, %g, %g} %s numerically equal\n",
+ test.fLeft, test.fTop, test.fRight, test.fBottom,
+ negZero.fLeft, negZero.fTop, negZero.fRight, negZero.fBottom,
+ test == negZero ? '=' : '!',
+ test.fLeft == negZero.fLeft && test.fTop == negZero.fTop &&
+ test.fRight == negZero.fRight && test.fBottom == negZero.fBottom ?
+ "and are" : "yet are not");
+ };
+ SkRect tests[] = {{0, 0, 2, 2}, {-0, -0, 2, 2}, {0.0f, 0.0f, 2, 2}};
+ SkDebugf("tests are %s" "equal\n", tests[0] == tests[1] && tests[1] == tests[2] ? "" : "not ");
+ for (auto rect : tests) {
+ debugster(rect);
}
-#StdOut
-tests are equal
-{0, 0, 2, 2} == {-0, -0, 2, 2} and are numerically equal
-{0, 0, 2, 2} == {-0, -0, 2, 2} and are numerically equal
+#StdOut
+tests are equal
+{0, 0, 2, 2} == {-0, -0, 2, 2} and are numerically equal
+{0, 0, 2, 2} == {-0, -0, 2, 2} and are numerically equal
{0, 0, 2, 2} == {-0, -0, 2, 2} and are numerically equal
##
##
@@ -871,9 +871,9 @@ contain zeroes width different signs.
#Return true if members are not equal ##
#Example
- SkRect test = {0, 0, 2, SK_ScalarNaN};
- SkDebugf("test with NaN is %s" "equal to itself\n", test == test ? "" : "not ");
-#StdOut
+ SkRect test = {0, 0, 2, SK_ScalarNaN};
+ SkDebugf("test with NaN is %s" "equal to itself\n", test == test ? "" : "not ");
+#StdOut
test with NaN is not equal to itself
##
##
@@ -896,17 +896,17 @@ Consider adding param to control whether quad is CW or CCW.
#Param quad storage for corners of Rect ##
#Example
- SkRect rect = {1, 2, 3, 4};
- SkPoint corners[4];
- rect.toQuad(corners);
- SkDebugf("rect: {%g, %g, %g, %g}\n", rect.fLeft, rect.fTop, rect.fRight, rect.fBottom);
- SkDebugf("corners:");
- for (auto corner : corners) {
- SkDebugf(" {%g, %g}", corner.fX, corner.fY);
- }
- SkDebugf("\n");
-#StdOut
-rect: {1, 2, 3, 4}
+ SkRect rect = {1, 2, 3, 4};
+ SkPoint corners[4];
+ rect.toQuad(corners);
+ SkDebugf("rect: {%g, %g, %g, %g}\n", rect.fLeft, rect.fTop, rect.fRight, rect.fBottom);
+ SkDebugf("corners:");
+ for (auto corner : corners) {
+ SkDebugf(" {%g, %g}", corner.fX, corner.fY);
+ }
+ SkDebugf("\n");
+#StdOut
+rect: {1, 2, 3, 4}
corners: {1, 2} {3, 2} {3, 4} {1, 4}
##
##
@@ -926,16 +926,16 @@ or if top is equal to or greater than bottom. Setting all members to zero
is a convenience, but does not designate a special empty rectangle.
#Example
- SkRect rect = {3, 4, 1, 2};
- for (int i = 0; i < 2; ++i) {
- SkDebugf("rect: {%g, %g, %g, %g} is %s" "empty\n", rect.fLeft, rect.fTop,
- rect.fRight, rect.fBottom, rect.isEmpty() ? "" : "not ");
- rect.setEmpty();
- }
-#StdOut
-rect: {3, 4, 1, 2} is empty
-rect: {0, 0, 0, 0} is empty
-##
+ SkRect rect = {3, 4, 1, 2};
+ for (int i = 0; i < 2; ++i) {
+ SkDebugf("rect: {%g, %g, %g, %g} is %s" "empty\n", rect.fLeft, rect.fTop,
+ rect.fRight, rect.fBottom, rect.isEmpty() ? "" : "not ");
+ rect.setEmpty();
+ }
+#StdOut
+rect: {3, 4, 1, 2} is empty
+rect: {0, 0, 0, 0} is empty
+##
##
#SeeAlso MakeEmpty SkIRect::setEmpty
@@ -952,15 +952,15 @@ Very large values in src may lose precision.
#Param src integer Rect ##
#Example
- SkIRect i_rect = {3, 4, 1, 2};
- SkDebugf("i_rect: {%d, %d, %d, %d}\n", i_rect.fLeft, i_rect.fTop, i_rect.fRight, i_rect.fBottom);
- SkRect f_rect;
- f_rect.set(i_rect);
- SkDebugf("f_rect: {%g, %g, %g, %g}\n", f_rect.fLeft, f_rect.fTop, f_rect.fRight, f_rect.fBottom);
-#StdOut
-i_rect: {3, 4, 1, 2}
-f_rect: {3, 4, 1, 2}
-##
+ SkIRect i_rect = {3, 4, 1, 2};
+ SkDebugf("i_rect: {%d, %d, %d, %d}\n", i_rect.fLeft, i_rect.fTop, i_rect.fRight, i_rect.fBottom);
+ SkRect f_rect;
+ f_rect.set(i_rect);
+ SkDebugf("f_rect: {%g, %g, %g, %g}\n", f_rect.fLeft, f_rect.fTop, f_rect.fRight, f_rect.fBottom);
+#StdOut
+i_rect: {3, 4, 1, 2}
+f_rect: {3, 4, 1, 2}
+##
##
#SeeAlso setLTRB SkIntToScalar
@@ -981,15 +981,15 @@ top and bottom are not sorted; top is not necessarily less than bottom.
#Param bottom stored in fBottom ##
#Example
- SkRect rect1 = {3, 4, 1, 2};
- SkDebugf("rect1: {%g, %g, %g, %g}\n", rect1.fLeft, rect1.fTop, rect1.fRight, rect1.fBottom);
- SkRect rect2;
- rect2.set(3, 4, 1, 2);
- SkDebugf("rect2: {%g, %g, %g, %g}\n", rect2.fLeft, rect2.fTop, rect2.fRight, rect2.fBottom);
-#StdOut
-rect1: {3, 4, 1, 2}
-rect2: {3, 4, 1, 2}
-##
+ SkRect rect1 = {3, 4, 1, 2};
+ SkDebugf("rect1: {%g, %g, %g, %g}\n", rect1.fLeft, rect1.fTop, rect1.fRight, rect1.fBottom);
+ SkRect rect2;
+ rect2.set(3, 4, 1, 2);
+ SkDebugf("rect2: {%g, %g, %g, %g}\n", rect2.fLeft, rect2.fTop, rect2.fRight, rect2.fBottom);
+#StdOut
+rect1: {3, 4, 1, 2}
+rect2: {3, 4, 1, 2}
+##
##
#SeeAlso setLTRB setXYWH SkIRect::set
@@ -1010,15 +1010,15 @@ top and bottom are not sorted; top is not necessarily less than bottom.
#Param bottom stored in fBottom ##
#Example
- SkRect rect1 = {3, 4, 1, 2};
- SkDebugf("rect1: {%g, %g, %g, %g}\n", rect1.fLeft, rect1.fTop, rect1.fRight, rect1.fBottom);
- SkRect rect2;
- rect2.setLTRB(3, 4, 1, 2);
- SkDebugf("rect2: {%g, %g, %g, %g}\n", rect2.fLeft, rect2.fTop, rect2.fRight, rect2.fBottom);
-#StdOut
-rect1: {3, 4, 1, 2}
-rect2: {3, 4, 1, 2}
-##
+ SkRect rect1 = {3, 4, 1, 2};
+ SkDebugf("rect1: {%g, %g, %g, %g}\n", rect1.fLeft, rect1.fTop, rect1.fRight, rect1.fBottom);
+ SkRect rect2;
+ rect2.setLTRB(3, 4, 1, 2);
+ SkDebugf("rect2: {%g, %g, %g, %g}\n", rect2.fLeft, rect2.fTop, rect2.fRight, rect2.fBottom);
+#StdOut
+rect1: {3, 4, 1, 2}
+rect2: {3, 4, 1, 2}
+##
##
#SeeAlso set setXYWH SkIRect::set
@@ -1040,15 +1040,15 @@ top and bottom are not sorted; top is not necessarily less than bottom.
#Param bottom promoted to SkScalar and stored in fBottom ##
#Example
- SkRect rect1 = {3, 4, 1, 2};
- SkDebugf("rect1: {%g, %g, %g, %g}\n", rect1.fLeft, rect1.fTop, rect1.fRight, rect1.fBottom);
- SkRect rect2;
- rect2.iset(3, 4, 1, 2);
- SkDebugf("rect2: {%g, %g, %g, %g}\n", rect2.fLeft, rect2.fTop, rect2.fRight, rect2.fBottom);
-#StdOut
-rect1: {3, 4, 1, 2}
-rect2: {3, 4, 1, 2}
-##
+ SkRect rect1 = {3, 4, 1, 2};
+ SkDebugf("rect1: {%g, %g, %g, %g}\n", rect1.fLeft, rect1.fTop, rect1.fRight, rect1.fBottom);
+ SkRect rect2;
+ rect2.iset(3, 4, 1, 2);
+ SkDebugf("rect2: {%g, %g, %g, %g}\n", rect2.fLeft, rect2.fTop, rect2.fRight, rect2.fBottom);
+#StdOut
+rect1: {3, 4, 1, 2}
+rect2: {3, 4, 1, 2}
+##
##
#SeeAlso set setLTRB SkIRect::set SkIntToScalar
@@ -1067,15 +1067,15 @@ integer to SkScalar, large values may lose precision.
#Param height promoted to SkScalar and stored in fBottom ##
#Example
- SkRect rect1 = {0, 0, 1, 2};
- SkDebugf("rect1: {%g, %g, %g, %g}\n", rect1.fLeft, rect1.fTop, rect1.fRight, rect1.fBottom);
- SkRect rect2;
- rect2.isetWH(1, 2);
+ SkRect rect1 = {0, 0, 1, 2};
+ SkDebugf("rect1: {%g, %g, %g, %g}\n", rect1.fLeft, rect1.fTop, rect1.fRight, rect1.fBottom);
+ SkRect rect2;
+ rect2.isetWH(1, 2);
SkDebugf("rect2: {%g, %g, %g, %g}\n", rect2.fLeft, rect2.fTop, rect2.fRight, rect2.fBottom);
-#StdOut
-rect1: {0, 0, 1, 2}
-rect2: {0, 0, 1, 2}
-##
+#StdOut
+rect1: {0, 0, 1, 2}
+rect2: {0, 0, 1, 2}
+##
##
#SeeAlso MakeWH MakeXYWH iset() SkIRect:MakeWH
@@ -1096,25 +1096,25 @@ fTop is less than or equal to fBottom.
#Param count entries in array ##
#Example
- SkPoint points[] = {{3, 4}, {1, 2}, {5, 6}, {SK_ScalarNaN, 8}};
- for (int count = 0; count <= (int) SK_ARRAY_COUNT(points); ++count) {
- SkRect rect;
- rect.set(points, count);
- if (count > 0) {
- SkDebugf("added: %3g, %g ", points[count - 1].fX, points[count - 1].fY);
- } else {
- SkDebugf("%14s", " ");
- }
- SkDebugf("count: %d rect: %g, %g, %g, %g\n", count,
- rect.fLeft, rect.fTop, rect.fRight, rect.fBottom);
- }
-#StdOut
- count: 0 rect: 0, 0, 0, 0
-added: 3, 4 count: 1 rect: 3, 4, 3, 4
-added: 1, 2 count: 2 rect: 1, 2, 3, 4
-added: 5, 6 count: 3 rect: 1, 2, 5, 6
-added: nan, 8 count: 4 rect: 0, 0, 0, 0
-##
+ SkPoint points[] = {{3, 4}, {1, 2}, {5, 6}, {SK_ScalarNaN, 8}};
+ for (int count = 0; count <= (int) SK_ARRAY_COUNT(points); ++count) {
+ SkRect rect;
+ rect.set(points, count);
+ if (count > 0) {
+ SkDebugf("added: %3g, %g ", points[count - 1].fX, points[count - 1].fY);
+ } else {
+ SkDebugf("%14s", " ");
+ }
+ SkDebugf("count: %d rect: %g, %g, %g, %g\n", count,
+ rect.fLeft, rect.fTop, rect.fRight, rect.fBottom);
+ }
+#StdOut
+ count: 0 rect: 0, 0, 0, 0
+added: 3, 4 count: 1 rect: 3, 4, 3, 4
+added: 1, 2 count: 2 rect: 1, 2, 3, 4
+added: 5, 6 count: 3 rect: 1, 2, 5, 6
+added: nan, 8 count: 4 rect: 0, 0, 0, 0
+##
##
#SeeAlso setBounds setBoundsCheck SkPath::addPoly
@@ -1135,25 +1135,25 @@ fTop is less than or equal to fBottom.
#Param count entries in array ##
#Example
- SkPoint points[] = {{3, 4}, {1, 2}, {5, 6}, {SK_ScalarNaN, 8}};
- for (int count = 0; count <= (int) SK_ARRAY_COUNT(points); ++count) {
- SkRect rect;
- rect.setBounds(points, count);
- if (count > 0) {
- SkDebugf("added: %3g, %g ", points[count - 1].fX, points[count - 1].fY);
- } else {
- SkDebugf("%14s", " ");
- }
- SkDebugf("count: %d rect: %g, %g, %g, %g\n", count,
- rect.fLeft, rect.fTop, rect.fRight, rect.fBottom);
- }
-#StdOut
- count: 0 rect: 0, 0, 0, 0
-added: 3, 4 count: 1 rect: 3, 4, 3, 4
-added: 1, 2 count: 2 rect: 1, 2, 3, 4
-added: 5, 6 count: 3 rect: 1, 2, 5, 6
-added: nan, 8 count: 4 rect: 0, 0, 0, 0
-##
+ SkPoint points[] = {{3, 4}, {1, 2}, {5, 6}, {SK_ScalarNaN, 8}};
+ for (int count = 0; count <= (int) SK_ARRAY_COUNT(points); ++count) {
+ SkRect rect;
+ rect.setBounds(points, count);
+ if (count > 0) {
+ SkDebugf("added: %3g, %g ", points[count - 1].fX, points[count - 1].fY);
+ } else {
+ SkDebugf("%14s", " ");
+ }
+ SkDebugf("count: %d rect: %g, %g, %g, %g\n", count,
+ rect.fLeft, rect.fTop, rect.fRight, rect.fBottom);
+ }
+#StdOut
+ count: 0 rect: 0, 0, 0, 0
+added: 3, 4 count: 1 rect: 3, 4, 3, 4
+added: 1, 2 count: 2 rect: 1, 2, 3, 4
+added: 5, 6 count: 3 rect: 1, 2, 5, 6
+added: nan, 8 count: 4 rect: 0, 0, 0, 0
+##
##
#SeeAlso set setBoundsCheck SkPath::addPoly
@@ -1177,25 +1177,25 @@ fTop is less than or equal to fBottom.
#Return true if all Point values are finite ##
#Example
- SkPoint points[] = {{3, 4}, {1, 2}, {5, 6}, {SK_ScalarNaN, 8}};
- for (int count = 0; count <= (int) SK_ARRAY_COUNT(points); ++count) {
- SkRect rect;
- bool success = rect.setBoundsCheck(points, count);
- if (count > 0) {
- SkDebugf("added: %3g, %g ", points[count - 1].fX, points[count - 1].fY);
- } else {
- SkDebugf("%14s", " ");
- }
- SkDebugf("count: %d rect: %g, %g, %g, %g success: %s\n", count,
- rect.fLeft, rect.fTop, rect.fRight, rect.fBottom, success ? "true" : "false");
- }
-#StdOut
- count: 0 rect: 0, 0, 0, 0 success: true
-added: 3, 4 count: 1 rect: 3, 4, 3, 4 success: true
-added: 1, 2 count: 2 rect: 1, 2, 3, 4 success: true
-added: 5, 6 count: 3 rect: 1, 2, 5, 6 success: true
-added: nan, 8 count: 4 rect: 0, 0, 0, 0 success: false
-##
+ SkPoint points[] = {{3, 4}, {1, 2}, {5, 6}, {SK_ScalarNaN, 8}};
+ for (int count = 0; count <= (int) SK_ARRAY_COUNT(points); ++count) {
+ SkRect rect;
+ bool success = rect.setBoundsCheck(points, count);
+ if (count > 0) {
+ SkDebugf("added: %3g, %g ", points[count - 1].fX, points[count - 1].fY);
+ } else {
+ SkDebugf("%14s", " ");
+ }
+ SkDebugf("count: %d rect: %g, %g, %g, %g success: %s\n", count,
+ rect.fLeft, rect.fTop, rect.fRight, rect.fBottom, success ? "true" : "false");
+ }
+#StdOut
+ count: 0 rect: 0, 0, 0, 0 success: true
+added: 3, 4 count: 1 rect: 3, 4, 3, 4 success: true
+added: 1, 2 count: 2 rect: 1, 2, 3, 4 success: true
+added: 5, 6 count: 3 rect: 1, 2, 5, 6 success: true
+added: nan, 8 count: 4 rect: 0, 0, 0, 0 success: false
+##
##
#SeeAlso set setBounds SkPath::addPoly
@@ -1216,13 +1216,13 @@ sorted and may be empty. Does not check to see if values are finite.
#Description
p0 and p1 may be swapped and have the same effect unless one contains NaN.
##
- SkPoint point1 = {SK_ScalarNaN, 8};
- SkPoint point2 = {3, 4};
- SkRect rect;
- rect.set(point1, point2);
- SkDebugf("rect: %g, %g, %g, %g\n", rect.fLeft, rect.fTop, rect.fRight, rect.fBottom);
- rect.set(point2, point1);
- SkDebugf("rect: %g, %g, %g, %g\n", rect.fLeft, rect.fTop, rect.fRight, rect.fBottom);
+ SkPoint point1 = {SK_ScalarNaN, 8};
+ SkPoint point2 = {3, 4};
+ SkRect rect;
+ rect.set(point1, point2);
+ SkDebugf("rect: %g, %g, %g, %g\n", rect.fLeft, rect.fTop, rect.fRight, rect.fBottom);
+ rect.set(point2, point1);
+ SkDebugf("rect: %g, %g, %g, %g\n", rect.fLeft, rect.fTop, rect.fRight, rect.fBottom);
##
#SeeAlso setBounds setBoundsCheck
@@ -1246,15 +1246,15 @@ width or height may be negative.
#Param height added to y and stored in fBottom ##
#Example
- SkRect rect;
- rect.setXYWH(5, 35, -15, 25);
- SkDebugf("rect: %g, %g, %g, %g isEmpty: %s\n", rect.left(), rect.top(), rect.right(),
- rect.bottom(), rect.isEmpty() ? "true" : "false");
- rect.sort();
- SkDebugf("rect: %g, %g, %g, %g isEmpty: %s\n", rect.left(), rect.top(), rect.right(),
- rect.bottom(), rect.isEmpty() ? "true" : "false");
+ SkRect rect;
+ rect.setXYWH(5, 35, -15, 25);
+ SkDebugf("rect: %g, %g, %g, %g isEmpty: %s\n", rect.left(), rect.top(), rect.right(),
+ rect.bottom(), rect.isEmpty() ? "true" : "false");
+ rect.sort();
+ SkDebugf("rect: %g, %g, %g, %g isEmpty: %s\n", rect.left(), rect.top(), rect.right(),
+ rect.bottom(), rect.isEmpty() ? "true" : "false");
#StdOut
-rect: 5, 35, -10, 60 isEmpty: true
+rect: 5, 35, -10, 60 isEmpty: true
rect: -10, 35, 5, 60 isEmpty: false
##
##
@@ -1274,15 +1274,15 @@ width or height may be negative.
#Param height stored in fBottom ##
#Example
- SkRect rect;
- rect.setWH(-15, 25);
- SkDebugf("rect: %g, %g, %g, %g isEmpty: %s\n", rect.left(), rect.top(), rect.right(),
- rect.bottom(), rect.isEmpty() ? "true" : "false");
- rect.sort();
- SkDebugf("rect: %g, %g, %g, %g isEmpty: %s\n", rect.left(), rect.top(), rect.right(),
- rect.bottom(), rect.isEmpty() ? "true" : "false");
+ SkRect rect;
+ rect.setWH(-15, 25);
+ SkDebugf("rect: %g, %g, %g, %g isEmpty: %s\n", rect.left(), rect.top(), rect.right(),
+ rect.bottom(), rect.isEmpty() ? "true" : "false");
+ rect.sort();
+ SkDebugf("rect: %g, %g, %g, %g isEmpty: %s\n", rect.left(), rect.top(), rect.right(),
+ rect.bottom(), rect.isEmpty() ? "true" : "false");
#StdOut
-rect: 0, 0, -15, 25 isEmpty: true
+rect: 0, 0, -15, 25 isEmpty: true
rect: -15, 0, 0, 25 isEmpty: false
##
##
@@ -1299,24 +1299,24 @@ Sets rectangle left and top to most negative finite value, and sets
right and bottom to most positive finite value.
#Example
- SkRect rect;
- rect.setLargest();
- SkDebugf("MakeLargest isLargest: %s\n", rect.isLargest() ? "true" : "false");
- SkDebugf("MakeLargest isFinite: %s\n", rect.isFinite() ? "true" : "false");
- rect.outset(1e31, 1e31);
- SkDebugf("outset a little isLargest: %s\n", rect.isLargest() ? "true" : "false");
- SkDebugf("outset a little isFinite: %s\n", rect.isFinite() ? "true" : "false");
- rect.outset(1e32, 1e32);
- SkDebugf("outset a little more isLargest: %s\n", rect.isLargest() ? "true" : "false");
- SkDebugf("outset a little more isFinite: %s\n", rect.isFinite() ? "true" : "false");
-#StdOut
-MakeLargest isLargest: true
-MakeLargest isFinite: true
-outset a little isLargest: true
-outset a little isFinite: true
-outset a little more isLargest: false
-outset a little more isFinite: false
-##
+ SkRect rect;
+ rect.setLargest();
+ SkDebugf("MakeLargest isLargest: %s\n", rect.isLargest() ? "true" : "false");
+ SkDebugf("MakeLargest isFinite: %s\n", rect.isFinite() ? "true" : "false");
+ rect.outset(1e31, 1e31);
+ SkDebugf("outset a little isLargest: %s\n", rect.isLargest() ? "true" : "false");
+ SkDebugf("outset a little isFinite: %s\n", rect.isFinite() ? "true" : "false");
+ rect.outset(1e32, 1e32);
+ SkDebugf("outset a little more isLargest: %s\n", rect.isLargest() ? "true" : "false");
+ SkDebugf("outset a little more isFinite: %s\n", rect.isFinite() ? "true" : "false");
+#StdOut
+MakeLargest isLargest: true
+MakeLargest isFinite: true
+outset a little isLargest: true
+outset a little isFinite: true
+outset a little more isLargest: false
+outset a little more isFinite: false
+##
##
#SeeAlso MakeLargest isLargest setLargestInverted SK_ScalarMin SK_ScalarMax
@@ -1333,20 +1333,20 @@ right and bottom to most negative finite value.
Use to initial Rect before one or more calls to growToInclude.
#Example
- auto debugster = [](const char* prefix, const SkRect& rect) -> void {
- SkDebugf("%s ", prefix);
- SkDebugf("rect: %g, %g, %g, %g ", rect.left(), rect.top(), rect.right(), rect.bottom());
- SkDebugf("isEmpty: %s\n", rect.isEmpty() ? "true" : "false");
- };
- SkRect ptBounds;
- ptBounds.setLargestInverted();
- debugster("original", ptBounds);
- ptBounds.growToInclude( { 42, 24 } );
+ auto debugster = [](const char* prefix, const SkRect& rect) -> void {
+ SkDebugf("%s ", prefix);
+ SkDebugf("rect: %g, %g, %g, %g ", rect.left(), rect.top(), rect.right(), rect.bottom());
+ SkDebugf("isEmpty: %s\n", rect.isEmpty() ? "true" : "false");
+ };
+ SkRect ptBounds;
+ ptBounds.setLargestInverted();
+ debugster("original", ptBounds);
+ ptBounds.growToInclude( { 42, 24 } );
debugster("grown", ptBounds);
-#StdOut
-original rect: 3.40282e+38, 3.40282e+38, -3.40282e+38, -3.40282e+38 isEmpty: true
-grown rect: 42, 24, 42, 24 isEmpty: true
-##
+#StdOut
+original rect: 3.40282e+38, 3.40282e+38, -3.40282e+38, -3.40282e+38 isEmpty: true
+grown rect: 42, 24, 42, 24 isEmpty: true
+##
##
#SeeAlso growToInclude setEmpty setLargest
@@ -1370,16 +1370,16 @@ If dy is positive, Rect returned is moved downward.
#Return Rect offset in x or y, with original width and height ##
#Example
- SkRect rect = { 10, 50, 20, 60 };
- SkDebugf("rect: %g, %g, %g, %g isEmpty: %s\n", rect.left(), rect.top(), rect.right(),
- rect.bottom(), rect.isEmpty() ? "true" : "false");
- rect = rect.makeOffset(15, 32);
- SkDebugf("rect: %g, %g, %g, %g isEmpty: %s\n", rect.left(), rect.top(), rect.right(),
- rect.bottom(), rect.isEmpty() ? "true" : "false");
-#StdOut
-rect: 10, 50, 20, 60 isEmpty: false
-rect: 25, 82, 35, 92 isEmpty: false
-##
+ SkRect rect = { 10, 50, 20, 60 };
+ SkDebugf("rect: %g, %g, %g, %g isEmpty: %s\n", rect.left(), rect.top(), rect.right(),
+ rect.bottom(), rect.isEmpty() ? "true" : "false");
+ rect = rect.makeOffset(15, 32);
+ SkDebugf("rect: %g, %g, %g, %g isEmpty: %s\n", rect.left(), rect.top(), rect.right(),
+ rect.bottom(), rect.isEmpty() ? "true" : "false");
+#StdOut
+rect: 10, 50, 20, 60 isEmpty: false
+rect: 25, 82, 35, 92 isEmpty: false
+##
##
#SeeAlso offset() makeInset makeOutset SkIRect::makeOffset
@@ -1403,16 +1403,16 @@ If dy is positive, Rect returned is shorter.
#Return Rect inset symmetrically left and right, top and bottom ##
#Example
- SkRect rect = { 10, 50, 20, 60 };
- SkDebugf("rect: %g, %g, %g, %g isEmpty: %s\n", rect.left(), rect.top(), rect.right(),
- rect.bottom(), rect.isEmpty() ? "true" : "false");
- rect = rect.makeInset(15, 32);
- SkDebugf("rect: %g, %g, %g, %g isEmpty: %s\n", rect.left(), rect.top(), rect.right(),
- rect.bottom(), rect.isEmpty() ? "true" : "false");
-#StdOut
-rect: 10, 50, 20, 60 isEmpty: false
-rect: 25, 82, 5, 28 isEmpty: true
-##
+ SkRect rect = { 10, 50, 20, 60 };
+ SkDebugf("rect: %g, %g, %g, %g isEmpty: %s\n", rect.left(), rect.top(), rect.right(),
+ rect.bottom(), rect.isEmpty() ? "true" : "false");
+ rect = rect.makeInset(15, 32);
+ SkDebugf("rect: %g, %g, %g, %g isEmpty: %s\n", rect.left(), rect.top(), rect.right(),
+ rect.bottom(), rect.isEmpty() ? "true" : "false");
+#StdOut
+rect: 10, 50, 20, 60 isEmpty: false
+rect: 25, 82, 5, 28 isEmpty: true
+##
##
#SeeAlso inset() makeOffset makeOutset SkIRect::makeInset
@@ -1436,16 +1436,16 @@ If dy is positive, Rect returned is taller.
#Return Rect outset symmetrically left and right, top and bottom ##
#Example
- SkRect rect = { 10, 50, 20, 60 };
- SkDebugf("rect: %g, %g, %g, %g isEmpty: %s\n", rect.left(), rect.top(), rect.right(),
- rect.bottom(), rect.isEmpty() ? "true" : "false");
- rect = rect.makeOutset(15, 32);
- SkDebugf("rect: %g, %g, %g, %g isEmpty: %s\n", rect.left(), rect.top(), rect.right(),
- rect.bottom(), rect.isEmpty() ? "true" : "false");
-#StdOut
-rect: 10, 50, 20, 60 isEmpty: false
-rect: -5, 18, 35, 92 isEmpty: false
-##
+ SkRect rect = { 10, 50, 20, 60 };
+ SkDebugf("rect: %g, %g, %g, %g isEmpty: %s\n", rect.left(), rect.top(), rect.right(),
+ rect.bottom(), rect.isEmpty() ? "true" : "false");
+ rect = rect.makeOutset(15, 32);
+ SkDebugf("rect: %g, %g, %g, %g isEmpty: %s\n", rect.left(), rect.top(), rect.right(),
+ rect.bottom(), rect.isEmpty() ? "true" : "false");
+#StdOut
+rect: 10, 50, 20, 60 isEmpty: false
+rect: -5, 18, 35, 92 isEmpty: false
+##
##
#SeeAlso outset() makeOffset makeInset SkIRect::makeOutset
@@ -1467,12 +1467,12 @@ If dy is positive, moves Rect downward.
#Param dy offset added to fTop and fBottom ##
#Example
- SkRect rect = { 10, 14, 50, 73 };
- rect.offset(5, 13);
- SkDebugf("rect: %g, %g, %g, %g\n", rect.fLeft, rect.fTop, rect.fRight, rect.fBottom);
-#StdOut
-rect: 15, 27, 55, 86
-##
+ SkRect rect = { 10, 14, 50, 73 };
+ rect.offset(5, 13);
+ SkDebugf("rect: %g, %g, %g, %g\n", rect.fLeft, rect.fTop, rect.fRight, rect.fBottom);
+#StdOut
+rect: 15, 27, 55, 86
+##
##
#SeeAlso offsetTo makeOffset SkIRect::offset
@@ -1494,12 +1494,12 @@ If delta.fY is positive, moves Rect downward.
#Param delta added to Rect ##
#Example
- SkRect rect = { 10, 14, 50, 73 };
- rect.offset({5, 13});
- SkDebugf("rect: %g, %g, %g, %g\n", rect.fLeft, rect.fTop, rect.fRight, rect.fBottom);
-#StdOut
-rect: 15, 27, 55, 86
-##
+ SkRect rect = { 10, 14, 50, 73 };
+ rect.offset({5, 13});
+ SkDebugf("rect: %g, %g, %g, %g\n", rect.fLeft, rect.fTop, rect.fRight, rect.fBottom);
+#StdOut
+rect: 15, 27, 55, 86
+##
##
#SeeAlso offsetTo makeOffset SkIRect::offset
@@ -1517,12 +1517,12 @@ are unchanged.
#Param newY stored in fTop, preserving height() ##
#Example
- SkRect rect = { 10, 14, 50, 73 };
- rect.offsetTo(15, 27);
- SkDebugf("rect: %g, %g, %g, %g\n", rect.fLeft, rect.fTop, rect.fRight, rect.fBottom);
-#StdOut
-rect: 15, 27, 55, 86
-##
+ SkRect rect = { 10, 14, 50, 73 };
+ rect.offsetTo(15, 27);
+ SkDebugf("rect: %g, %g, %g, %g\n", rect.fLeft, rect.fTop, rect.fRight, rect.fBottom);
+#StdOut
+rect: 15, 27, 55, 86
+##
##
#SeeAlso offset makeOffset setXYWH SkIRect::offsetTo
@@ -1544,12 +1544,12 @@ If dy is negative, makes Rect taller.
#Param dy added to fTop and subtracted from fBottom ##
#Example
- SkRect rect = { 10, 14, 50, 73 };
- rect.inset(5, 13);
- SkDebugf("rect: %g, %g, %g, %g\n", rect.fLeft, rect.fTop, rect.fRight, rect.fBottom);
-#StdOut
-rect: 15, 27, 45, 60
-##
+ SkRect rect = { 10, 14, 50, 73 };
+ rect.inset(5, 13);
+ SkDebugf("rect: %g, %g, %g, %g\n", rect.fLeft, rect.fTop, rect.fRight, rect.fBottom);
+#StdOut
+rect: 15, 27, 45, 60
+##
##
#SeeAlso outset makeInset SkIRect::inset
@@ -1571,12 +1571,12 @@ If dy is negative, makes Rect shorter.
#Param dy subtracted to fTop and added from fBottom ##
#Example
- SkRect rect = { 10, 14, 50, 73 };
- rect.outset(5, 13);
- SkDebugf("rect: %g, %g, %g, %g\n", rect.fLeft, rect.fTop, rect.fRight, rect.fBottom);
-#StdOut
-rect: 5, 1, 55, 86
-##
+ SkRect rect = { 10, 14, 50, 73 };
+ rect.outset(5, 13);
+ SkDebugf("rect: %g, %g, %g, %g\n", rect.fLeft, rect.fTop, rect.fRight, rect.fBottom);
+#StdOut
+rect: 5, 1, 55, 86
+##
##
#SeeAlso inset makeOutset SkIRect::outset
@@ -1587,11 +1587,14 @@ rect: 5, 1, 55, 86
Rects intersect when they enclose a common area. To intersect, each of the pair
must describe area; fLeft is less than fRight, and fTop is less than fBottom;
-empty() returns false. The intersection of Rect a and Rect b can be described by:
+empty() returns false. The intersection of Rect pair can be described by:
+
#Formula
(max(a.fLeft, b.fLeft), max(a.fTop, b.fTop),
min(a.fRight, b.fRight), min(a.fBottom, b.fBottom))
##
+.
+
The intersection is only meaningful if the resulting Rect is not empty and
describes an area: fLeft is less than fRight, and fTop is less than fBottom.
@@ -1614,10 +1617,10 @@ Two SkDebugf calls are required. If the calls are combined, their arguments
may not be evaluated in left to right order: the printed intersection may
be before or after the call to intersect.
##
- SkRect leftRect = { 10, 40, 50, 80 };
- SkRect rightRect = { 30, 60, 70, 90 };
- SkDebugf("%s intersection: ", leftRect.intersect(rightRect) ? "" : "no ");
- SkDebugf("%g, %g, %g, %g\n", leftRect.left(), leftRect.top(),
+ SkRect leftRect = { 10, 40, 50, 80 };
+ SkRect rightRect = { 30, 60, 70, 90 };
+ SkDebugf("%s intersection: ", leftRect.intersect(rightRect) ? "" : "no ");
+ SkDebugf("%g, %g, %g, %g\n", leftRect.left(), leftRect.top(),
leftRect.right(), leftRect.bottom());
#StdOut
intersection: 30, 60, 50, 80
@@ -1653,9 +1656,9 @@ Two SkDebugf calls are required. If the calls are combined, their arguments
may not be evaluated in left to right order: the printed intersection may
be before or after the call to intersect.
##
- SkRect leftRect = { 10, 40, 50, 80 };
- SkDebugf("%s intersection: ", leftRect.intersect(30, 60, 70, 90) ? "" : "no ");
- SkDebugf("%g, %g, %g, %g\n", leftRect.left(), leftRect.top(),
+ SkRect leftRect = { 10, 40, 50, 80 };
+ SkDebugf("%s intersection: ", leftRect.intersect(30, 60, 70, 90) ? "" : "no ");
+ SkDebugf("%g, %g, %g, %g\n", leftRect.left(), leftRect.top(),
leftRect.right(), leftRect.bottom());
#StdOut
intersection: 30, 60, 50, 80
@@ -1681,10 +1684,10 @@ Returns false if either a or b is empty, leaving Rect unchanged.
#Return true if a and b have area in common ##
#Example
- SkRect result;
- bool intersected = result.intersect({ 10, 40, 50, 80 }, { 30, 60, 70, 90 });
- SkDebugf("%s intersection: %g, %g, %g, %g\n", intersected ? "" : "no ",
- result.left(), result.top(), result.right(), result.bottom());
+ SkRect result;
+ bool intersected = result.intersect({ 10, 40, 50, 80 }, { 30, 60, 70, 90 });
+ SkDebugf("%s intersection: %g, %g, %g, %g\n", intersected ? "" : "no ",
+ result.left(), result.top(), result.right(), result.bottom());
#StdOut
intersection: 30, 60, 50, 80
##
@@ -1712,8 +1715,8 @@ Returns false if either construction or Rect is empty, or do not intersect.
#Return true if construction and Rect have area in common ##
#Example
- SkRect rect = { 10, 40, 50, 80 };
- SkDebugf("%s intersection", rect.intersects(30, 60, 70, 90) ? "" : "no ");
+ SkRect rect = { 10, 40, 50, 80 };
+ SkDebugf("%s intersection", rect.intersects(30, 60, 70, 90) ? "" : "no ");
#StdOut
intersection
##
@@ -1735,8 +1738,8 @@ Returns false if either r or Rect is empty, or do not intersect.
#Return true if r and Rect have area in common ##
#Example
- SkRect rect = { 10, 40, 50, 80 };
- SkDebugf("%s intersection", rect.intersects({30, 60, 70, 90}) ? "" : "no ");
+ SkRect rect = { 10, 40, 50, 80 };
+ SkDebugf("%s intersection", rect.intersects({30, 60, 70, 90}) ? "" : "no ");
#StdOut
intersection
##
@@ -1759,7 +1762,7 @@ Returns false if either a or b is empty, or do not intersect.
#Return true if a and b have area in common ##
#Example
- SkDebugf("%s intersection", SkRect::Intersects({10, 40, 50, 80}, {30, 60, 70, 90}) ? "" : "no ");
+ SkDebugf("%s intersection", SkRect::Intersects({10, 40, 50, 80}, {30, 60, 70, 90}) ? "" : "no ");
#StdOut
intersection
##
@@ -1790,9 +1793,9 @@ Rect to construction.
#Param bottom y maximum of constructed Rect ##
#Example
- SkRect rect = { 10, 20, 15, 25};
- rect.join(50, 60, 55, 65);
- SkDebugf("join: %g, %g, %g, %g\n", rect.fLeft, rect.fTop, rect.fRight, rect.fBottom);
+ SkRect rect = { 10, 20, 15, 25};
+ rect.join(50, 60, 55, 65);
+ SkDebugf("join: %g, %g, %g, %g\n", rect.fLeft, rect.fTop, rect.fRight, rect.fBottom);
#StdOut
join: 10, 20, 55, 65
##
@@ -1814,9 +1817,9 @@ Rect to r.
#Param r expansion Rect ##
#Example
- SkRect rect = { 10, 20, 15, 25};
- rect.join({50, 60, 55, 65});
- SkDebugf("join: %g, %g, %g, %g\n", rect.fLeft, rect.fTop, rect.fRight, rect.fBottom);
+ SkRect rect = { 10, 20, 15, 25};
+ rect.join({50, 60, 55, 65});
+ SkDebugf("join: %g, %g, %g, %g\n", rect.fLeft, rect.fTop, rect.fRight, rect.fBottom);
#StdOut
join: 10, 20, 55, 65
##
@@ -1843,15 +1846,15 @@ May produce incorrect results if r is empty.
#Description
Since Rect is not sorted, first result is copy of toJoin.
##
- SkRect rect = { 10, 100, 15, 0};
- SkRect sorted = rect.makeSorted();
- SkRect toJoin = { 50, 60, 55, 65 };
- rect.joinNonEmptyArg(toJoin);
- SkDebugf("rect: %g, %g, %g, %g\n", rect.fLeft, rect.fTop, rect.fRight, rect.fBottom);
- sorted.joinNonEmptyArg(toJoin);
+ SkRect rect = { 10, 100, 15, 0};
+ SkRect sorted = rect.makeSorted();
+ SkRect toJoin = { 50, 60, 55, 65 };
+ rect.joinNonEmptyArg(toJoin);
+ SkDebugf("rect: %g, %g, %g, %g\n", rect.fLeft, rect.fTop, rect.fRight, rect.fBottom);
+ sorted.joinNonEmptyArg(toJoin);
SkDebugf("sorted: %g, %g, %g, %g\n", sorted.fLeft, sorted.fTop, sorted.fRight, sorted.fBottom);
#StdOut
-rect: 50, 60, 55, 65
+rect: 50, 60, 55, 65
sorted: 10, 0, 55, 100
##
##
@@ -1874,15 +1877,15 @@ May produce incorrect results if Rect or r is empty.
#Description
Since Rect is not sorted, first result is not useful.
##
- SkRect rect = { 10, 100, 15, 0};
- SkRect sorted = rect.makeSorted();
- SkRect toJoin = { 50, 60, 55, 65 };
- rect.joinPossiblyEmptyRect(toJoin);
- SkDebugf("rect: %g, %g, %g, %g\n", rect.fLeft, rect.fTop, rect.fRight, rect.fBottom);
- sorted.joinPossiblyEmptyRect(toJoin);
- SkDebugf("sorted: %g, %g, %g, %g\n", sorted.fLeft, sorted.fTop, sorted.fRight, sorted.fBottom);
+ SkRect rect = { 10, 100, 15, 0};
+ SkRect sorted = rect.makeSorted();
+ SkRect toJoin = { 50, 60, 55, 65 };
+ rect.joinPossiblyEmptyRect(toJoin);
+ SkDebugf("rect: %g, %g, %g, %g\n", rect.fLeft, rect.fTop, rect.fRight, rect.fBottom);
+ sorted.joinPossiblyEmptyRect(toJoin);
+ SkDebugf("sorted: %g, %g, %g, %g\n", sorted.fLeft, sorted.fTop, sorted.fRight, sorted.fBottom);
#StdOut
-rect: 10, 60, 55, 65
+rect: 10, 60, 55, 65
sorted: 10, 0, 55, 100
##
##
@@ -1896,6 +1899,7 @@ sorted: 10, 0, 55, 100
#Method void growToInclude(SkPoint pt)
Grows Rect to include (pt.fX, pt.fY), modifying it so that:
+
#Formula
fLeft <= pt.fX <= fRight && fTop <= pt.fY <= fBottom
##
@@ -1907,11 +1911,11 @@ Points after one or more calls. In this case, Rect is empty after first call.
#Param pt Point to include ##
#Example
- SkRect rect;
- rect.setLargestInverted();
- rect.growToInclude( { 42, 24 } );
- SkDebugf("rect: %g, %g, %g, %g ", rect.left(), rect.top(), rect.right(), rect.bottom());
- SkDebugf("isEmpty: %s\n", rect.isEmpty() ? "true" : "false");
+ SkRect rect;
+ rect.setLargestInverted();
+ rect.growToInclude( { 42, 24 } );
+ SkDebugf("rect: %g, %g, %g, %g ", rect.left(), rect.top(), rect.right(), rect.bottom());
+ SkDebugf("isEmpty: %s\n", rect.isEmpty() ? "true" : "false");
#StdOut
rect: 42, 24, 42, 24 isEmpty: true
##
@@ -1939,11 +1943,11 @@ Points after one or more calls. In this case, Rect is empty after first call.
#Param count number of points in array ##
#Example
- SkPoint pts[] = { { 30, 50 }, { 40, 50 }, { 30, 60 } };
- SkRect rect = { pts[0].fX, pts[0].fY, pts[0].fX, pts[0].fY };
- rect.growToInclude( pts[1] );
- rect.growToInclude( pts[2] );
- SkDebugf("rect: %g, %g, %g, %g ", rect.left(), rect.top(), rect.right(), rect.bottom());
+ SkPoint pts[] = { { 30, 50 }, { 40, 50 }, { 30, 60 } };
+ SkRect rect = { pts[0].fX, pts[0].fY, pts[0].fX, pts[0].fY };
+ rect.growToInclude( pts[1] );
+ rect.growToInclude( pts[2] );
+ SkDebugf("rect: %g, %g, %g, %g ", rect.left(), rect.top(), rect.right(), rect.bottom());
#StdOut
rect: 30, 50, 40, 60
##
@@ -1962,8 +1966,10 @@ it so that:
#Formula
fLeft <= pt.fX <= fRight && fTop <= pt.fY <= fBottom
##
-. Point may be followed with other data in each array element. stride is number
- of bytes in element; the interval to skip to advance from one Point to
+.
+
+Point may be followed with other data in each array element. stride is number
+of bytes in element; the interval to skip to advance from one Point to
the next.
If Rect is initialized with setLargestInverted, then Rect will contain bounds of
@@ -1975,11 +1981,11 @@ Points after one or more calls. In this case, Rect is empty after first call.
#Bug 7142 ##
#Example
- SkPoint3 pts[] = { { 30, 50, -1 }, { 40, 50, -1 }, { 30, 60, -1 } };
- SkRect rect;
- rect.setLargestInverted();
- rect.growToInclude((SkPoint* ) &pts[0].fX, sizeof(SkPoint3), SK_ARRAY_COUNT(pts));
- SkDebugf("rect: %g, %g, %g, %g ", rect.left(), rect.top(), rect.right(), rect.bottom());
+ SkPoint3 pts[] = { { 30, 50, -1 }, { 40, 50, -1 }, { 30, 60, -1 } };
+ SkRect rect;
+ rect.setLargestInverted();
+ rect.growToInclude((SkPoint* ) &pts[0].fX, sizeof(SkPoint3), SK_ARRAY_COUNT(pts));
+ SkDebugf("rect: %g, %g, %g, %g ", rect.left(), rect.top(), rect.right(), rect.bottom());
#StdOut
#Volatile
rect: 30, 50, 40, 60
@@ -2004,19 +2010,19 @@ Rect contains r when Rect area completely includes r area.
#Return true if all sides of Rect are outside r ##
#Example
- SkRect rect = { 30, 50, 40, 60 };
- SkRect tests[] = { { 30, 50, 31, 51}, { 39, 49, 40, 50}, { 29, 59, 30, 60} };
- for (auto contained : tests) {
- SkDebugf("rect: (%g, %g, %g, %g) %s (%g, %g, %g, %g)\n",
- rect.left(), rect.top(), rect.right(), rect.bottom(),
- rect.contains(contained) ? "contains" : "does not contain",
- contained.left(), contained.top(), contained.right(), contained.bottom());
- }
-#StdOut
-rect: (30, 50, 40, 60) contains (30, 50, 31, 51)
-rect: (30, 50, 40, 60) does not contain (39, 49, 40, 50)
-rect: (30, 50, 40, 60) does not contain (29, 59, 30, 60)
-##
+ SkRect rect = { 30, 50, 40, 60 };
+ SkRect tests[] = { { 30, 50, 31, 51}, { 39, 49, 40, 50}, { 29, 59, 30, 60} };
+ for (auto contained : tests) {
+ SkDebugf("rect: (%g, %g, %g, %g) %s (%g, %g, %g, %g)\n",
+ rect.left(), rect.top(), rect.right(), rect.bottom(),
+ rect.contains(contained) ? "contains" : "does not contain",
+ contained.left(), contained.top(), contained.right(), contained.bottom());
+ }
+#StdOut
+rect: (30, 50, 40, 60) contains (30, 50, 31, 51)
+rect: (30, 50, 40, 60) does not contain (39, 49, 40, 50)
+rect: (30, 50, 40, 60) does not contain (29, 59, 30, 60)
+##
##
#SeeAlso SkIRect::contains
@@ -2037,19 +2043,19 @@ Rect contains r when Rect area completely includes r area.
#Return true if all sides of Rect are outside r ##
#Example
- SkRect rect = { 30, 50, 40, 60 };
- SkIRect tests[] = { { 30, 50, 31, 51}, { 39, 49, 40, 50}, { 29, 59, 30, 60} };
- for (auto contained : tests) {
- SkDebugf("rect: (%g, %g, %g, %g) %s (%d, %d, %d, %d)\n",
- rect.left(), rect.top(), rect.right(), rect.bottom(),
- rect.contains(contained) ? "contains" : "does not contain",
- contained.left(), contained.top(), contained.right(), contained.bottom());
- }
-#StdOut
-rect: (30, 50, 40, 60) contains (30, 50, 31, 51)
-rect: (30, 50, 40, 60) does not contain (39, 49, 40, 50)
-rect: (30, 50, 40, 60) does not contain (29, 59, 30, 60)
-##
+ SkRect rect = { 30, 50, 40, 60 };
+ SkIRect tests[] = { { 30, 50, 31, 51}, { 39, 49, 40, 50}, { 29, 59, 30, 60} };
+ for (auto contained : tests) {
+ SkDebugf("rect: (%g, %g, %g, %g) %s (%d, %d, %d, %d)\n",
+ rect.left(), rect.top(), rect.right(), rect.bottom(),
+ rect.contains(contained) ? "contains" : "does not contain",
+ contained.left(), contained.top(), contained.right(), contained.bottom());
+ }
+#StdOut
+rect: (30, 50, 40, 60) contains (30, 50, 31, 51)
+rect: (30, 50, 40, 60) does not contain (39, 49, 40, 50)
+rect: (30, 50, 40, 60) does not contain (29, 59, 30, 60)
+##
##
#SeeAlso SkIRect::contains
@@ -2073,10 +2079,10 @@ members, using
#Param dst storage for IRect ##
#Example
- SkRect rect = { 30.5f, 50.5f, 40.5f, 60.5f };
- SkIRect round;
- rect.round(&round);
- SkDebugf("round: %d, %d, %d, %d\n", round.fLeft, round.fTop, round.fRight, round.fBottom);
+ SkRect rect = { 30.5f, 50.5f, 40.5f, 60.5f };
+ SkIRect round;
+ rect.round(&round);
+ SkDebugf("round: %d, %d, %d, %d\n", round.fLeft, round.fTop, round.fRight, round.fBottom);
#StdOut
round: 31, 51, 41, 61
##
@@ -2101,10 +2107,10 @@ rounding up fRight and FBottom, using
#Param dst storage for IRect ##
#Example
- SkRect rect = { 30.5f, 50.5f, 40.5f, 60.5f };
- SkIRect round;
- rect.roundOut(&round);
- SkDebugf("round: %d, %d, %d, %d\n", round.fLeft, round.fTop, round.fRight, round.fBottom);
+ SkRect rect = { 30.5f, 50.5f, 40.5f, 60.5f };
+ SkIRect round;
+ rect.roundOut(&round);
+ SkDebugf("round: %d, %d, %d, %d\n", round.fLeft, round.fTop, round.fRight, round.fBottom);
#StdOut
round: 30, 50, 41, 61
##
@@ -2129,10 +2135,10 @@ rounding up fRight and FBottom, using
#Param dst storage for Rect ##
#Example
- SkRect rect = { 30.5f, 50.5f, 40.5f, 60.5f };
- SkRect round;
- rect.roundOut(&round);
- SkDebugf("round: %g, %g, %g, %g\n", round.fLeft, round.fTop, round.fRight, round.fBottom);
+ SkRect rect = { 30.5f, 50.5f, 40.5f, 60.5f };
+ SkRect round;
+ rect.roundOut(&round);
+ SkDebugf("round: %g, %g, %g, %g\n", round.fLeft, round.fTop, round.fRight, round.fBottom);
#StdOut
round: 30, 50, 41, 61
##
@@ -2148,6 +2154,7 @@ round: 30, 50, 41, 61
Sets Rect by rounding up fLeft and fTop; and
discarding the fractional portion of fRight and FBottom, using
+
#Formula
(SkScalarCeilToInt(fLeft), SkScalarCeilToInt(fTop),
SkScalarFloorToInt(fRight), SkScalarFloorToInt(fBottom))
@@ -2157,12 +2164,12 @@ discarding the fractional portion of fRight and FBottom, using
#Param dst storage for IRect ##
#Example
- SkRect rect = { 30.5f, 50.5f, 40.5f, 60.5f };
- SkIRect round;
- rect.roundIn(&round);
- SkDebugf("round: %d, %d, %d, %d\n", round.fLeft, round.fTop, round.fRight, round.fBottom);
+ SkRect rect = { 30.5f, 50.5f, 40.5f, 60.5f };
+ SkIRect round;
+ rect.roundIn(&round);
+ SkDebugf("round: %d, %d, %d, %d\n", round.fLeft, round.fTop, round.fRight, round.fBottom);
#StdOut
-round: 31, 51, 40, 60
+round: 31, 51, 40, 60
##
##
@@ -2185,11 +2192,11 @@ members, using
#Return rounded IRect ##
#Example
- SkRect rect = { 30.5f, 50.5f, 40.5f, 60.5f };
- SkIRect round = rect.round();
- SkDebugf("round: %d, %d, %d, %d\n", round.fLeft, round.fTop, round.fRight, round.fBottom);
+ SkRect rect = { 30.5f, 50.5f, 40.5f, 60.5f };
+ SkIRect round = rect.round();
+ SkDebugf("round: %d, %d, %d, %d\n", round.fLeft, round.fTop, round.fRight, round.fBottom);
#StdOut
-round: 31, 51, 41, 61
+round: 31, 51, 41, 61
##
##
@@ -2212,11 +2219,11 @@ rounding up fRight and FBottom, using
#Return rounded IRect ##
#Example
- SkRect rect = { 30.5f, 50.5f, 40.5f, 60.5f };
- SkIRect round = rect.roundOut();
- SkDebugf("round: %d, %d, %d, %d\n", round.fLeft, round.fTop, round.fRight, round.fBottom);
+ SkRect rect = { 30.5f, 50.5f, 40.5f, 60.5f };
+ SkIRect round = rect.roundOut();
+ SkDebugf("round: %d, %d, %d, %d\n", round.fLeft, round.fTop, round.fRight, round.fBottom);
#StdOut
-round: 30, 50, 41, 61
+round: 30, 50, 41, 61
##
##
@@ -2235,12 +2242,12 @@ fTop and fBottom if fTop is greater than fBottom. Result may be empty;
and width() and height() will be zero or positive.
#Example
- SkRect rect = { 30.5f, 50.5f, 20.5f, 10.5f };
- SkDebugf("rect: %g, %g, %g, %g\n", rect.fLeft, rect.fTop, rect.fRight, rect.fBottom);
- rect.sort();
- SkDebugf("sorted: %g, %g, %g, %g\n", rect.fLeft, rect.fTop, rect.fRight, rect.fBottom);
+ SkRect rect = { 30.5f, 50.5f, 20.5f, 10.5f };
+ SkDebugf("rect: %g, %g, %g, %g\n", rect.fLeft, rect.fTop, rect.fRight, rect.fBottom);
+ rect.sort();
+ SkDebugf("sorted: %g, %g, %g, %g\n", rect.fLeft, rect.fTop, rect.fRight, rect.fBottom);
#StdOut
-rect: 30.5, 50.5, 20.5, 10.5
+rect: 30.5, 50.5, 20.5, 10.5
sorted: 20.5, 10.5, 30.5, 50.5
##
##
@@ -2260,12 +2267,12 @@ and width() and height() will be zero or positive.
#Return sorted Rect ##
#Example
- SkRect rect = { 30.5f, 50.5f, 20.5f, 10.5f };
- SkDebugf("rect: %g, %g, %g, %g\n", rect.fLeft, rect.fTop, rect.fRight, rect.fBottom);
- SkRect sort = rect.makeSorted();
- SkDebugf("sorted: %g, %g, %g, %g\n", sort.fLeft, sort.fTop, sort.fRight, sort.fBottom);
+ SkRect rect = { 30.5f, 50.5f, 20.5f, 10.5f };
+ SkDebugf("rect: %g, %g, %g, %g\n", rect.fLeft, rect.fTop, rect.fRight, rect.fBottom);
+ SkRect sort = rect.makeSorted();
+ SkDebugf("sorted: %g, %g, %g, %g\n", sort.fLeft, sort.fTop, sort.fRight, sort.fBottom);
#StdOut
-rect: 30.5, 50.5, 20.5, 10.5
+rect: 30.5, 50.5, 20.5, 10.5
sorted: 20.5, 10.5, 30.5, 50.5
##
##
@@ -2284,11 +2291,11 @@ entries.
#Return pointer to fLeft ##
#Example
- SkRect rect = {7, 11, 13, 17};
-SkDebugf("rect.asScalars() %c= &rect.fLeft\n", rect.asScalars() == &rect.fLeft? '=' : '!');
-#StdOut
-rect.asScalars() == &rect.fLeft
-##
+ SkRect rect = {7, 11, 13, 17};
+SkDebugf("rect.asScalars() %c= &rect.fLeft\n", rect.asScalars() == &rect.fLeft? '=' : '!');
+#StdOut
+rect.asScalars() == &rect.fLeft
+##
##
#SeeAlso toQuad
@@ -2311,12 +2318,12 @@ generate exact binary representations of floating point numbers.
SkDebugf("\n");
}
#StdOut
-SkRect::MakeLTRB(20, 30, 40, 50);
-
-SkRect::MakeLTRB(SkBits2Float(0x41a00000), /* 20.000000 */
- SkBits2Float(0x41f00000), /* 30.000000 */
- SkBits2Float(0x42200000), /* 40.000000 */
- SkBits2Float(0x42480000) /* 50.000000 */);
+SkRect::MakeLTRB(20, 30, 40, 50);
+
+SkRect::MakeLTRB(SkBits2Float(0x41a00000), /* 20.000000 */
+ SkBits2Float(0x41f00000), /* 30.000000 */
+ SkBits2Float(0x42200000), /* 40.000000 */
+ SkBits2Float(0x42480000) /* 50.000000 */);
##
##
@@ -2334,12 +2341,12 @@ with limited precision; it may not be possible to reconstruct original Rect
from output.
#Example
-SkRect rect = {6.f / 7, 2.f / 3, 26.f / 10, 42.f / 6};
-rect.dump();
-SkRect copy = SkRect::MakeLTRB(0.857143f, 0.666667f, 2.6f, 7);
-SkDebugf("rect is " "%s" "equal to copy\n", rect == copy ? "" : "not ");
+SkRect rect = {6.f / 7, 2.f / 3, 26.f / 10, 42.f / 6};
+rect.dump();
+SkRect copy = SkRect::MakeLTRB(0.857143f, 0.666667f, 2.6f, 7);
+SkDebugf("rect is " "%s" "equal to copy\n", rect == copy ? "" : "not ");
#StdOut
-SkRect::MakeLTRB(0.857143f, 0.666667f, 2.6f, 7);
+SkRect::MakeLTRB(0.857143f, 0.666667f, 2.6f, 7);
rect is not equal to copy
##
##
@@ -2362,18 +2369,18 @@ Use instead of dump() when submitting
.
#Example
- SkRect rect = {6.f / 7, 2.f / 3, 26.f / 10, 42.f / 6};
-rect.dumpHex();
-SkRect copy = SkRect::MakeLTRB(SkBits2Float(0x3f5b6db7), /* 0.857143 */
- SkBits2Float(0x3f2aaaab), /* 0.666667 */
- SkBits2Float(0x40266666), /* 2.600000 */
- SkBits2Float(0x40e00000) /* 7.000000 */);
+ SkRect rect = {6.f / 7, 2.f / 3, 26.f / 10, 42.f / 6};
+rect.dumpHex();
+SkRect copy = SkRect::MakeLTRB(SkBits2Float(0x3f5b6db7), /* 0.857143 */
+ SkBits2Float(0x3f2aaaab), /* 0.666667 */
+ SkBits2Float(0x40266666), /* 2.600000 */
+ SkBits2Float(0x40e00000) /* 7.000000 */);
SkDebugf("rect is " "%s" "equal to copy\n", rect == copy ? "" : "not ");
#StdOut
-SkRect::MakeLTRB(SkBits2Float(0x3f5b6db7), /* 0.857143 */
- SkBits2Float(0x3f2aaaab), /* 0.666667 */
- SkBits2Float(0x40266666), /* 2.600000 */
- SkBits2Float(0x40e00000) /* 7.000000 */);
+SkRect::MakeLTRB(SkBits2Float(0x3f5b6db7), /* 0.857143 */
+ SkBits2Float(0x3f2aaaab), /* 0.666667 */
+ SkBits2Float(0x40266666), /* 2.600000 */
+ SkBits2Float(0x40e00000) /* 7.000000 */);
rect is equal to copy
##
##
diff --git a/docs/undocumented.bmh b/docs/undocumented.bmh
index 0239034eec..8a57459607 100644
--- a/docs/undocumented.bmh
+++ b/docs/undocumented.bmh
@@ -11,7 +11,7 @@
PDF XPS
RFC
NaN NaNs
- Bezier Coons Cartesian
+ Bezier Coons Cartesian Euclidean
C C++ Destructor Subclasses
SaveLayerFlags # not external; need to add typedef support
SkUserConfig # not external, but still thinking about how markup refers to this
@@ -336,6 +336,8 @@ FT_Load_Glyph
##
#Method size_t computeByteSize(size_t rowBytes) const
##
+ #Method void validate() const
+ ##
##
#Subtopic ##
#Class SkImage
@@ -362,6 +364,11 @@ FT_Load_Glyph
#Topic Image_Scaling
##
+#Topic ISize
+#Struct SkISize
+##
+##
+
#Topic Left_Side_Bearing
##
@@ -559,6 +566,11 @@ FT_Load_Glyph
#Subtopic ##
#Topic ##
+#Topic Point3
+#Struct SkPoint3
+##
+#Topic ##
+
#Topic PostScript
#Substitute PostScript
#Subtopic Arct
@@ -637,7 +649,8 @@ FT_Load_Glyph
#Topic ##
#Topic Size
-#Alias ISize
+#Struct SkSize
+##
##
#Topic Sprite
@@ -645,7 +658,7 @@ FT_Load_Glyph
#Topic ##
#Topic Stream
-#Class SkFlattenable
+#Class SkStream
#Class ##
#Topic ##
@@ -702,6 +715,7 @@ FT_Load_Glyph
##
#Topic Vector
+#Alias Vectors
#Struct SkVector
##
##
diff --git a/site/user/api/SkBitmap_Reference.md b/site/user/api/SkBitmap_Reference.md
index abff9ffbb1..4182c50733 100644
--- a/site/user/api/SkBitmap_Reference.md
+++ b/site/user/api/SkBitmap_Reference.md
@@ -74,8 +74,7 @@ is useful to position one or more <a href="#Bitmap">Bitmaps</a> within a shared
| <a href="#SkBitmap_bytesPerPixel">bytesPerPixel</a> | Returns number of bytes in pixel based on <a href="undocumented#Color_Type">Color Type</a>. |
| <a href="#SkBitmap_colorSpace">colorSpace</a> | Returns <a href="#Info">Image Info</a> <a href="undocumented#Color_Space">Color Space</a>. |
| <a href="#SkBitmap_colorType">colorType</a> | Returns <a href="#Info">Image Info</a> <a href="undocumented#Color_Type">Color Type</a>. |
-| <a href="#SkBitmap_computeSafeSize64">computeSafeSize64</a> | Returns minimum size required for pixels in 64 bits. |
-| <a href="#SkBitmap_computeSize64">computeSize64</a> | Returns conservative size required for pixels. |
+| <a href="#SkBitmap_computeByteSize">computeByteSize</a> | Returns size required for pixels. |
| <a href="#SkBitmap_dimensions">dimensions</a> | Returns <a href="#SkBitmap_width">width</a> and <a href="#SkBitmap_height">height</a>. |
| <a href="#SkBitmap_drawsNothing">drawsNothing</a> | Returns true if no <a href="#SkBitmap_width">width</a>, no <a href="#SkBitmap_height">height</a>, or no <a href="undocumented#Pixel_Ref">Pixel Ref</a>. |
| <a href="#SkBitmap_empty">empty</a> | Returns true if <a href="#Info">Image Info</a> has zero <a href="#SkBitmap_width">width</a> or <a href="#SkBitmap_height">height</a>. |
@@ -83,7 +82,7 @@ is useful to position one or more <a href="#Bitmap">Bitmaps</a> within a shared
| <a href="#SkBitmap_eraseARGB">eraseARGB</a> | Writes <a href="undocumented#Color">Color</a> to pixels. |
| <a href="#SkBitmap_eraseArea">eraseArea</a> | Deprecated |
| <a href="#SkBitmap_eraseColor">eraseColor</a> | Writes <a href="undocumented#Color">Color</a> to pixels. |
-| <a href="#SkBitmap_eraseRGB">eraseRGB</a> | Writes opaque <a href="undocumented#Color">Color</a> to pixels. |
+| <a href="#SkBitmap_eraseRGB">eraseRGB</a> | Deprecated |
| <a href="#SkBitmap_extractAlpha">extractAlpha</a> | Creates <a href="#Bitmap">Bitmap</a> containing <a href="#Alpha">Alpha</a> of pixels. |
| <a href="#SkBitmap_extractSubset">extractSubset</a> | Creates <a href="#Bitmap">Bitmap</a>, sharing pixels if possible. |
| <a href="#SkBitmap_getAddr">getAddr</a> | Returns readable pixel address as void pointer. |
@@ -94,8 +93,6 @@ is useful to position one or more <a href="#Bitmap">Bitmaps</a> within a shared
| <a href="#SkBitmap_getColor">getColor</a> | Returns one pixel as <a href="#Unpremultiply">Unpremultiplied</a> <a href="undocumented#Color">Color</a>. |
| <a href="#SkBitmap_getGenerationID">getGenerationID</a> | Returns unique ID. |
| <a href="#SkBitmap_getPixels">getPixels</a> | Returns address of pixels. |
-| <a href="#SkBitmap_getSafeSize">getSafeSize</a> | Returns minimum size required for pixels in 32 bits. |
-| <a href="#SkBitmap_getSize">getSize</a> | Returns conservative size required for pixels in 32 bits. |
| <a href="#SkBitmap_getSubset">getSubset</a> | Returns <a href="#SkBitmap_bounds">bounds</a> offset by origin. |
| <a href="#SkBitmap_hasHardwareMipMap">hasHardwareMipMap</a> | Returns <a href="undocumented#Mip_Map">Mip Map</a> support present; <a href="undocumented#Android">Android</a> only. |
| <a href="#SkBitmap_height">height</a> | Returns pixel row count. |
@@ -129,12 +126,13 @@ is useful to position one or more <a href="#Bitmap">Bitmaps</a> within a shared
| <a href="#SkBitmap_tryAllocN32Pixels">tryAllocN32Pixels</a> | Allocates compatible <a href="#ARGB">Color ARGB</a> pixels if possible. |
| <a href="#SkBitmap_tryAllocPixels">tryAllocPixels</a> | Allocates pixels from <a href="#Info">Image Info</a> if possible. |
| <a href="#SkBitmap_tryAllocPixelsFlags">tryAllocPixelsFlags</a> | Allocates pixels from <a href="#Info">Image Info</a> with options if possible. |
+| <a href="#SkBitmap_validate">validate</a> | Asserts if <a href="#Bitmap">Bitmap</a> is invalid (debug only). |
| <a href="#SkBitmap_width">width</a> | Returns pixel column count. |
| <a href="#SkBitmap_writePixels">writePixels</a> | Copies and converts pixels. |
# <a name="SkBitmap::Allocator"></a> Class SkBitmap::Allocator
-<pre style="padding: 1em 1em 1em 1em;width: 44em; background-color: #f0f0f0">
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
class <a href="#SkBitmap_Allocator">Allocator</a> : public <a href="undocumented#SkRefCnt">SkRefCnt</a> {
public:
virtual bool <a href="#SkBitmap_Allocator_allocPixelRef">allocPixelRef(SkBitmap* bitmap)</a> = 0;
@@ -172,7 +170,7 @@ true if <a href="undocumented#Pixel_Ref">Pixel Ref</a> was allocated
# <a name="SkBitmap::HeapAllocator"></a> Class SkBitmap::HeapAllocator
-<pre style="padding: 1em 1em 1em 1em;width: 44em; background-color: #f0f0f0">
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
class <a href="#SkBitmap_HeapAllocator">HeapAllocator</a> : public <a href="#SkBitmap_Allocator">Allocator</a> {
public:
bool <a href="#SkBitmap_HeapAllocator_allocPixelRef">allocPixelRef(SkBitmap* bitmap)</a> override;
@@ -516,6 +514,7 @@ int width() const
</pre>
Returns pixel count in each pixel row. Should be equal or less than:
+
<a href="#SkBitmap_rowBytes">rowBytes</a> / <a href="#SkBitmap_info">info</a>.<a href="#SkBitmap_bytesPerPixel">bytesPerPixel</a>.
Maybe be less than <a href="#SkBitmap_pixelRef">pixelRef</a>.<a href="#SkBitmap_width">width</a>. Will not exceed <a href="#SkBitmap_pixelRef">pixelRef</a>.<a href="#SkBitmap_width">width</a> less
@@ -1096,175 +1095,6 @@ width: 1000000 height: 1000000 computeByteSize: 4999999000000
---
-<a name="SkBitmap_getSize"></a>
-## getSize
-
-<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
-size_t getSize() const
-</pre>
-
-Returns conservative memory required for pixel storage.
-Includes unused memory on last row when <a href="#SkBitmap_rowBytesAsPixels">rowBytesAsPixels</a> exceeds <a href="#SkBitmap_width">width</a>.
-
-Does not check to see if result fits in 32 bits. Use getSize64() if the
-result may exceed 32 bits.
-
-### Return Value
-
-<a href="#SkBitmap_height">height</a> times <a href="#SkBitmap_rowBytes">rowBytes</a>
-
-### Example
-
-<div><fiddle-embed name="798d5f259dbd1ead4f3b1eac955c2cde"><div><a href="#SkBitmap_getSize">getSize</a> results are not useful when <a href="#SkBitmap_width">width</a> and <a href="#SkBitmap_height">height</a> are large.</div>
-
-#### Example Output
-
-~~~~
-width: 1 height: 1 getSize: 5
-width: 1 height: 1000 getSize: 5000
-width: 1 height: 1000000 getSize: 5000000
-width: 1000 height: 1 getSize: 5000
-width: 1000 height: 1000 getSize: 5000000
-width: 1000 height: 1000000 getSize: 705032704
-width: 1000000 height: 1 getSize: 5000000
-width: 1000000 height: 1000 getSize: 705032704
-width: 1000000 height: 1000000 getSize: 658067456
-~~~~
-
-</fiddle-embed></div>
-
-### See Also
-
-<a href="#SkBitmap_getSafeSize">getSafeSize</a> <a href="#SkBitmap_computeSize64">computeSize64</a> <a href="#SkBitmap_rowBytes">rowBytes</a> <a href="#SkBitmap_width">width</a>
-
----
-
-<a name="SkBitmap_getSafeSize"></a>
-## getSafeSize
-
-<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
-size_t getSafeSize() const
-</pre>
-
-Returns minimum memory required for pixel storage.
-Does not include unused memory on last row when <a href="#SkBitmap_rowBytesAsPixels">rowBytesAsPixels</a> exceeds <a href="#SkBitmap_width">width</a>.
-
-Returns zero if size does not fit in 32 bits. Use <a href="#SkBitmap_computeSafeSize64">computeSafeSize64</a> if the
-result may exceed 32 bits.
-
-The pixel storage visible may be a subset of the <a href="undocumented#Pixel_Ref">Pixel Ref</a>. Accessing memory
-beyond the result may generate an exception.
-
-### Return Value
-
-exact pixel storage size
-
-### Example
-
-<div><fiddle-embed name="47a93c44326c86371dbf42d2544e76be"><div><a href="#SkBitmap_getSafeSize">getSafeSize</a> results are not useful when <a href="#SkBitmap_width">width</a> and <a href="#SkBitmap_height">height</a> are large.</div>
-
-#### Example Output
-
-~~~~
-width: 1 height: 1 getSafeSize: 4
-width: 1 height: 1000 getSafeSize: 4999
-width: 1 height: 1000000 getSafeSize: 4999999
-width: 1000 height: 1 getSafeSize: 4000
-width: 1000 height: 1000 getSafeSize: 4999000
-width: 1000 height: 1000000 getSafeSize: 0
-width: 1000000 height: 1 getSafeSize: 4000000
-width: 1000000 height: 1000 getSafeSize: 0
-width: 1000000 height: 1000000 getSafeSize: 0
-~~~~
-
-</fiddle-embed></div>
-
-### See Also
-
-<a href="#SkBitmap_getSize">getSize</a> <a href="#SkBitmap_computeSafeSize64">computeSafeSize64</a> <a href="#SkBitmap_rowBytes">rowBytes</a> <a href="#SkBitmap_width">width</a>
-
----
-
-<a name="SkBitmap_computeSize64"></a>
-## computeSize64
-
-<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
-int64_t computeSize64() const
-</pre>
-
-Returns conservative memory required for pixel storage.
-Includes unused memory on last row when <a href="#SkBitmap_rowBytesAsPixels">rowBytesAsPixels</a> exceeds <a href="#SkBitmap_width">width</a>.
-
-### Return Value
-
-conservative pixel storage size
-
-### Example
-
-<div><fiddle-embed name="e7deb420416751aa68c1bd7956596833">
-
-#### Example Output
-
-~~~~
-width: 1 height: 1 computeSize64: 5
-width: 1 height: 1000 computeSize64: 5000
-width: 1 height: 1000000 computeSize64: 5000000
-width: 1000 height: 1 computeSize64: 5000
-width: 1000 height: 1000 computeSize64: 5000000
-width: 1000 height: 1000000 computeSize64: 5000000000
-width: 1000000 height: 1 computeSize64: 5000000
-width: 1000000 height: 1000 computeSize64: 5000000000
-width: 1000000 height: 1000000 computeSize64: 5000000000000
-~~~~
-
-</fiddle-embed></div>
-
-### See Also
-
-<a href="#SkBitmap_getSize">getSize</a> <a href="#SkBitmap_computeSafeSize64">computeSafeSize64</a> <a href="#SkBitmap_rowBytes">rowBytes</a> <a href="#SkBitmap_width">width</a>
-
----
-
-<a name="SkBitmap_computeSafeSize64"></a>
-## computeSafeSize64
-
-<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
-int64_t computeSafeSize64() const
-</pre>
-
-Returns minimum memory required for pixel storage.
-Does not include unused memory on last row when <a href="#SkBitmap_rowBytesAsPixels">rowBytesAsPixels</a> exceeds <a href="#SkBitmap_width">width</a>.
-
-### Return Value
-
-exact pixel storage size
-
-### Example
-
-<div><fiddle-embed name="ff12ff8354c1add9ea00797412f6342c">
-
-#### Example Output
-
-~~~~
-width: 1 height: 1 computeSafeSize64: 4
-width: 1 height: 1000 computeSafeSize64: 4999
-width: 1 height: 1000000 computeSafeSize64: 4999999
-width: 1000 height: 1 computeSafeSize64: 4000
-width: 1000 height: 1000 computeSafeSize64: 4999000
-width: 1000 height: 1000000 computeSafeSize64: 4999999000
-width: 1000000 height: 1 computeSafeSize64: 4000000
-width: 1000000 height: 1000 computeSafeSize64: 4999000000
-width: 1000000 height: 1000000 computeSafeSize64: 4999999000000
-~~~~
-
-</fiddle-embed></div>
-
-### See Also
-
-<a href="#SkBitmap_getSafeSize">getSafeSize</a> <a href="#SkBitmap_computeSize64">computeSize64</a> <a href="#SkBitmap_rowBytes">rowBytes</a> <a href="#SkBitmap_width">width</a>
-
----
-
<a name="SkBitmap_isImmutable"></a>
## isImmutable
@@ -1306,9 +1136,9 @@ copy is immutable
void setImmutable()
</pre>
-Once set, pixels can not change. Any other bitmap sharing the same <a href="undocumented#Pixel_Ref">Pixel Ref</a>
-are also marked as immutable. Once <a href="undocumented#Pixel_Ref">Pixel Ref</a> is marked immutable, the setting
-cannot be cleared.
+Sets internal flag to mark <a href="#Bitmap">Bitmap</a> as immutable. Once set, pixels can not change.
+Any other bitmap sharing the same <a href="undocumented#Pixel_Ref">Pixel Ref</a> are also marked as immutable.
+Once <a href="undocumented#Pixel_Ref">Pixel Ref</a> is marked immutable, the setting cannot be cleared.
Writing to immutable <a href="#Bitmap">Bitmap</a> pixels triggers an assert on debug builds.
@@ -1591,7 +1421,7 @@ integral rectangle from origin to <a href="#SkBitmap_width">width</a> and <a hre
SkISize dimensions() const
</pre>
-Returns <a href="#Size">ISize</a> { <a href="#SkBitmap_width">width</a>, <a href="#SkBitmap_height">height</a> }.
+Returns <a href="undocumented#ISize">ISize</a> { <a href="#SkBitmap_width">width</a>, <a href="#SkBitmap_height">height</a> }.
### Return Value
@@ -1699,7 +1529,7 @@ true if <a href="#Info">Image Info</a> set successfully
## <a name="SkBitmap_AllocFlags"></a> Enum SkBitmap::AllocFlags
-<pre style="padding: 1em 1em 1em 1em;width: 44em; background-color: #f0f0f0">
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
enum <a href="#SkBitmap_AllocFlags">AllocFlags</a> {
<a href="#SkBitmap_kZeroPixels_AllocFlag">kZeroPixels AllocFlag</a> = 1 << 0,
};</pre>
@@ -2577,7 +2407,7 @@ then <a href="#RGB">Color RGB</a> is ignored.
### See Also
-<a href="#SkBitmap_eraseARGB">eraseARGB</a> <a href="#SkBitmap_eraseRGB">eraseRGB</a> <a href="#SkBitmap_erase">erase</a>
+<a href="#SkBitmap_eraseARGB">eraseARGB</a> <a href="#SkBitmap_erase">erase</a>
---
@@ -2613,7 +2443,7 @@ amount of <a href="#RGB_Blue">Color RGB Blue</a>, from no blue (0) to full blue
### See Also
-<a href="#SkBitmap_eraseColor">eraseColor</a> <a href="#SkBitmap_eraseRGB">eraseRGB</a> <a href="#SkBitmap_erase">erase</a>
+<a href="#SkBitmap_eraseColor">eraseColor</a> <a href="#SkBitmap_erase">erase</a>
---
@@ -2624,25 +2454,19 @@ amount of <a href="#RGB_Blue">Color RGB Blue</a>, from no blue (0) to full blue
void eraseRGB(U8CPU r, U8CPU g, U8CPU b) const
</pre>
-Replaces pixel values with <a href="undocumented#Color">Color</a> built from <a href="#SkBitmap_eraseRGB_r">r</a>, <a href="#SkBitmap_eraseRGB_g">g</a>, and <a href="#SkBitmap_eraseRGB_b">b</a> with <a href="#Alpha">Color Alpha</a> set
-to 255. All pixels contained by <a href="#SkBitmap_bounds">bounds</a> are affected.
-If <a href="#SkBitmap_colorType">colorType</a> is <a href="undocumented#SkColorType">kAlpha 8 SkColorType</a>, all pixels are set to 255.
+Deprecated. Use <a href="#SkBitmap_eraseARGB">eraseARGB</a> or <a href="#SkBitmap_eraseColor">eraseColor</a>.
### Parameters
<table> <tr> <td><a name="SkBitmap_eraseRGB_r"> <code><strong>r </strong></code> </a></td> <td>
-amount of <a href="#RGB_Red">Color RGB Red</a>, from no red (0) to full red (255)</td>
+amount of red</td>
</tr> <tr> <td><a name="SkBitmap_eraseRGB_g"> <code><strong>g </strong></code> </a></td> <td>
-amount of <a href="#RGB_Green">Color RGB Green</a>, from no green (0) to full green (255)</td>
+amount of green</td>
</tr> <tr> <td><a name="SkBitmap_eraseRGB_b"> <code><strong>b </strong></code> </a></td> <td>
-amount of <a href="#RGB_Blue">Color RGB Blue</a>, from no blue (0) to full blue (255)</td>
+amount of blue</td>
</tr>
</table>
-### Example
-
-<div><fiddle-embed name="3088f4d6cf8a01644ffd41bfddad5e03"></fiddle-embed></div>
-
### See Also
<a href="#SkBitmap_eraseColor">eraseColor</a> <a href="#SkBitmap_eraseARGB">eraseARGB</a> <a href="#SkBitmap_erase">erase</a>
@@ -3041,7 +2865,8 @@ If this-><a href="#SkBitmap_alphaType">alphaType</a> is <a href="undocumented#Sk
match. If this-><a href="#SkBitmap_colorSpace">colorSpace</a> is nullptr, <a href="#SkBitmap_readPixels_dstInfo">dstInfo</a>.<a href="#SkBitmap_colorSpace">colorSpace</a> must match. Returns
false if pixel conversion is not possible.
<a href="#SkBitmap_readPixels_srcX">srcX</a> and <a href="#SkBitmap_readPixels_srcY">srcY</a> may be negative to copy only top or left of source. Returns
-false if <a href="#SkBitmap_width">width</a> or <a href="#SkBitmap_height">height</a> is zero or negative. Returns false ifabs(srcX) >= this-><a href="#SkBitmap_width">width</a>,
+false if <a href="#SkBitmap_width">width</a> or <a href="#SkBitmap_height">height</a> is zero or negative.
+Returns false ifabs(srcX) >= this-><a href="#SkBitmap_width">width</a>,
or ifabs(srcY) >= this-><a href="#SkBitmap_height">height</a>.
If <a href="#SkBitmap_readPixels_behavior">behavior</a> is <a href="#SkTransferFunctionBehavior_kRespect">SkTransferFunctionBehavior::kRespect</a>: converts source
@@ -3106,7 +2931,8 @@ If this-><a href="#SkBitmap_alphaType">alphaType</a> is <a href="undocumented#Sk
match. If this-><a href="#SkBitmap_colorSpace">colorSpace</a> is nullptr, <a href="#SkBitmap_readPixels_2_dstInfo">dstInfo</a>.<a href="#SkBitmap_colorSpace">colorSpace</a> must match. Returns
false if pixel conversion is not possible.
<a href="#SkBitmap_readPixels_2_srcX">srcX</a> and <a href="#SkBitmap_readPixels_2_srcY">srcY</a> may be negative to copy only top or left of source. Returns
-false if <a href="#SkBitmap_width">width</a> or <a href="#SkBitmap_height">height</a> is zero or negative. Returns false ifabs(srcX) >= this-><a href="#SkBitmap_width">width</a>,
+false if <a href="#SkBitmap_width">width</a> or <a href="#SkBitmap_height">height</a> is zero or negative.
+Returns false ifabs(srcX) >= this-><a href="#SkBitmap_width">width</a>,
or ifabs(srcY) >= this-><a href="#SkBitmap_height">height</a>.
### Parameters
@@ -3163,7 +2989,8 @@ If this-><a href="#SkBitmap_alphaType">alphaType</a> is <a href="undocumented#Sk
match. If this-><a href="#SkBitmap_colorSpace">colorSpace</a> is nullptr, <a href="#SkBitmap_readPixels_3_dst">dst</a> <a href="undocumented#Color_Space">Color Space</a> must match. Returns
false if pixel conversion is not possible.
<a href="#SkBitmap_readPixels_3_srcX">srcX</a> and <a href="#SkBitmap_readPixels_3_srcY">srcY</a> may be negative to copy only top or left of source. Returns
-false if <a href="#SkBitmap_width">width</a> or <a href="#SkBitmap_height">height</a> is zero or negative. Returns false ifabs(srcX) >= this-><a href="#SkBitmap_width">width</a>,
+false if <a href="#SkBitmap_width">width</a> or <a href="#SkBitmap_height">height</a> is zero or negative.
+Returns false ifabs(srcX) >= this-><a href="#SkBitmap_width">width</a>,
or ifabs(srcY) >= this-><a href="#SkBitmap_height">height</a>.
### Parameters
@@ -3263,7 +3090,8 @@ If this-><a href="#SkBitmap_alphaType">alphaType</a> is <a href="undocumented#Sk
match. If this-><a href="#SkBitmap_colorSpace">colorSpace</a> is nullptr, <a href="#SkBitmap_writePixels_src">src</a> <a href="undocumented#Color_Space">Color Space</a> must match. Returns
false if pixel conversion is not possible.
<a href="#SkBitmap_writePixels_dstX">dstX</a> and <a href="#SkBitmap_writePixels_dstY">dstY</a> may be negative to copy only top or left of source. Returns
-false if <a href="#SkBitmap_width">width</a> or <a href="#SkBitmap_height">height</a> is zero or negative. Returns false ifabs(dstX) >= this-><a href="#SkBitmap_width">width</a>,
+false if <a href="#SkBitmap_width">width</a> or <a href="#SkBitmap_height">height</a> is zero or negative.
+Returns false ifabs(dstX) >= this-><a href="#SkBitmap_width">width</a>,
or ifabs(dstY) >= this-><a href="#SkBitmap_height">height</a>.
### Parameters
@@ -3550,11 +3378,11 @@ true if <a href="#Alpha">Alpha</a> layer was constructed in <a href="#SkBitmap_e
bool peekPixels(SkPixmap* pixmap) const
</pre>
-If the pixels are available from this bitmap return true, and fill out the
-specified <a href="#SkBitmap_peekPixels_pixmap">pixmap</a> (if not null). If there are no pixels, return false and
-ignore the <a href="#SkBitmap_peekPixels_pixmap">pixmap</a> parameter.
-Note: if this returns true, the results (in the <a href="#SkBitmap_peekPixels_pixmap">pixmap</a>) are only valid until the bitmap
-is changed in any way, in which case the results are invalid.
+Copies <a href="#Bitmap">Bitmap</a> pixel address, row bytes, and <a href="#Info">Image Info</a> to <a href="#SkBitmap_peekPixels_pixmap">pixmap</a>, if address
+is available, and returns true. If pixel address is not available, return
+false and leave <a href="#SkBitmap_peekPixels_pixmap">pixmap</a> unchanged.
+
+<a href="#SkBitmap_peekPixels_pixmap">pixmap</a> contents become invalid on any future change to <a href="#Bitmap">Bitmap</a>.
### Parameters
@@ -3595,6 +3423,22 @@ true if <a href="#Bitmap">Bitmap</a> has direct access to pixels
---
+<a name="SkBitmap_validate"></a>
+## validate
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+void validate() const;
+</pre>
+
+Asserts if internal values are illegal or inconsistent. Only available if
+<a href="undocumented#SK_DEBUG">SK DEBUG</a> is defined at compile time.
+
+### See Also
+
+<a href="#SkImageInfo_validate">SkImageInfo::validate()</a>
+
+---
+
<a name="SkBitmap_toString"></a>
## toString
diff --git a/site/user/api/SkCanvas_Reference.md b/site/user/api/SkCanvas_Reference.md
index 8d39ac47ed..5d59fd4dd4 100644
--- a/site/user/api/SkCanvas_Reference.md
+++ b/site/user/api/SkCanvas_Reference.md
@@ -430,7 +430,7 @@ storage of <a href="undocumented#Raster_Surface">Raster Surface</a></td>
## <a name="SkCanvas_ColorBehavior"></a> Enum SkCanvas::ColorBehavior
-<pre style="padding: 1em 1em 1em 1em;width: 44em; background-color: #f0f0f0">
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
enum class <a href="#SkCanvas_ColorBehavior">ColorBehavior</a> {
<a href="#SkCanvas_ColorBehavior_kLegacy">kLegacy</a>,
};</pre>
@@ -875,10 +875,11 @@ bool readPixels(const SkImageInfo& dstInfo, void* dstPixels, size_t dstRowBytes,
int srcX, int srcY)
</pre>
-Copies rectangle of pixels from <a href="#Canvas">Canvas</a> into <a href="#SkCanvas_readPixels_dstPixels">dstPixels</a>. <a href="#Matrix">Matrix</a> and <a href="#Clip">Clip</a> are
-ignored. Source rectangle corners are (<a href="#SkCanvas_readPixels_srcX">srcX</a>, <a href="#SkCanvas_readPixels_srcY">srcY</a>) and(this-><a href="#SkCanvas_imageInfo">imageInfo</a>.width(), this-><a href="#SkCanvas_imageInfo">imageInfo</a>.height()).
+Copies <a href="SkRect_Reference#Rect">Rect</a> of pixels from <a href="#Canvas">Canvas</a> into <a href="#SkCanvas_readPixels_dstPixels">dstPixels</a>. <a href="#Matrix">Matrix</a> and <a href="#Clip">Clip</a> are
+ignored. Source <a href="SkRect_Reference#Rect">Rect</a> corners are (<a href="#SkCanvas_readPixels_srcX">srcX</a>, <a href="#SkCanvas_readPixels_srcY">srcY</a>) and
+(<a href="#SkCanvas_imageInfo">imageInfo</a>.width(), <a href="#SkCanvas_imageInfo">imageInfo</a>.height()).
-Destination rectangle corners are (0, 0) and (bitmap.width(), bitmap.height()).
+Destination <a href="SkRect_Reference#Rect">Rect</a> corners are (0, 0) and (bitmap.width(), bitmap.height()).
Copies each readable pixel intersecting both rectangles, without scaling,
converting to <a href="#SkCanvas_readPixels_dstInfo">dstInfo</a>.colorType() and <a href="#SkCanvas_readPixels_dstInfo">dstInfo</a>.alphaType() if required.
@@ -891,7 +892,7 @@ The destination pixel storage must be allocated by the caller.
<a href="undocumented#Pixel">Pixel</a> values are converted only if <a href="#Color_Type">Image Color Type</a> and <a href="#Alpha_Type">Image Alpha Type</a>
do not match. Only pixels within both source and destination rectangles
-are copied. <a href="#SkCanvas_readPixels_dstPixels">dstPixels</a> contents outside the rectangle intersection are unchanged.
+are copied. <a href="#SkCanvas_readPixels_dstPixels">dstPixels</a> contents outside <a href="SkRect_Reference#Rect">Rect</a> intersection are unchanged.
Pass negative values for <a href="#SkCanvas_readPixels_srcX">srcX</a> or <a href="#SkCanvas_readPixels_srcY">srcY</a> to offset pixels across or down destination.
@@ -956,10 +957,11 @@ pixel = 8056a9ff
bool readPixels(const SkPixmap& pixmap, int srcX, int srcY)
</pre>
-Copies rectangle of pixels from <a href="#Canvas">Canvas</a> into <a href="#SkCanvas_readPixels_2_pixmap">pixmap</a>. <a href="#Matrix">Matrix</a> and <a href="#Clip">Clip</a> are
-ignored. Source rectangle corners are (<a href="#SkCanvas_readPixels_2_srcX">srcX</a>, <a href="#SkCanvas_readPixels_2_srcY">srcY</a>) and(this-><a href="#SkCanvas_imageInfo">imageInfo</a>.width(), this-><a href="#SkCanvas_imageInfo">imageInfo</a>.height()).
+Copies <a href="SkRect_Reference#Rect">Rect</a> of pixels from <a href="#Canvas">Canvas</a> into <a href="#SkCanvas_readPixels_2_pixmap">pixmap</a>. <a href="#Matrix">Matrix</a> and <a href="#Clip">Clip</a> are
+ignored. Source <a href="SkRect_Reference#Rect">Rect</a> corners are (<a href="#SkCanvas_readPixels_2_srcX">srcX</a>, <a href="#SkCanvas_readPixels_2_srcY">srcY</a>) and
+(<a href="#SkCanvas_imageInfo">imageInfo</a>.width(), <a href="#SkCanvas_imageInfo">imageInfo</a>.height()).
-Destination rectangle corners are (0, 0) and (bitmap.width(), bitmap.height()).
+Destination <a href="SkRect_Reference#Rect">Rect</a> corners are (0, 0) and (bitmap.width(), bitmap.height()).
Copies each readable pixel intersecting both rectangles, without scaling,
converting to <a href="#SkCanvas_readPixels_2_pixmap">pixmap</a>.colorType() and <a href="#SkCanvas_readPixels_2_pixmap">pixmap</a>.alphaType() if required.
@@ -971,8 +973,8 @@ class like <a href="undocumented#SkDumpCanvas">SkDumpCanvas</a>.
Caller must allocate pixel storage in <a href="#SkCanvas_readPixels_2_pixmap">pixmap</a> if needed.
<a href="undocumented#Pixel">Pixel</a> values are converted only if <a href="#Color_Type">Image Color Type</a> and <a href="#Alpha_Type">Image Alpha Type</a>
-do not match. Only pixels within both source and destination rectangles
-are copied. <a href="#SkCanvas_readPixels_2_pixmap">pixmap</a> pixels contents outside the rectangle intersection are unchanged.
+do not match. Only pixels within both source and destination <a href="#Rect">Rects</a>
+are copied. <a href="#SkCanvas_readPixels_2_pixmap">pixmap</a> pixels contents outside <a href="SkRect_Reference#Rect">Rect</a> intersection are unchanged.
Pass negative values for <a href="#SkCanvas_readPixels_2_srcX">srcX</a> or <a href="#SkCanvas_readPixels_2_srcY">srcY</a> to offset pixels across or down <a href="#SkCanvas_readPixels_2_pixmap">pixmap</a>.
@@ -1025,10 +1027,11 @@ pixel = 802b5580
bool readPixels(const SkBitmap& bitmap, int srcX, int srcY)
</pre>
-Copies rectangle of pixels from <a href="#Canvas">Canvas</a> into <a href="#SkCanvas_readPixels_3_bitmap">bitmap</a>. <a href="#Matrix">Matrix</a> and <a href="#Clip">Clip</a> are
-ignored. Source rectangle corners are (<a href="#SkCanvas_readPixels_3_srcX">srcX</a>, <a href="#SkCanvas_readPixels_3_srcY">srcY</a>) and(this-><a href="#SkCanvas_imageInfo">imageInfo</a>.width(), this-><a href="#SkCanvas_imageInfo">imageInfo</a>.height()).
+Copies <a href="SkRect_Reference#Rect">Rect</a> of pixels from <a href="#Canvas">Canvas</a> into <a href="#SkCanvas_readPixels_3_bitmap">bitmap</a>. <a href="#Matrix">Matrix</a> and <a href="#Clip">Clip</a> are
+ignored. Source <a href="SkRect_Reference#Rect">Rect</a> corners are (<a href="#SkCanvas_readPixels_3_srcX">srcX</a>, <a href="#SkCanvas_readPixels_3_srcY">srcY</a>) and
+(<a href="#SkCanvas_imageInfo">imageInfo</a>.width(), <a href="#SkCanvas_imageInfo">imageInfo</a>.height()).
-Destination rectangle corners are (0, 0) and (<a href="#SkCanvas_readPixels_3_bitmap">bitmap</a>.width(), <a href="#SkCanvas_readPixels_3_bitmap">bitmap</a>.height()).
+Destination <a href="SkRect_Reference#Rect">Rect</a> corners are (0, 0) and (<a href="#SkCanvas_readPixels_3_bitmap">bitmap</a>.width(), <a href="#SkCanvas_readPixels_3_bitmap">bitmap</a>.height()).
Copies each readable pixel intersecting both rectangles, without scaling,
converting to <a href="#SkCanvas_readPixels_3_bitmap">bitmap</a>.colorType() and <a href="#SkCanvas_readPixels_3_bitmap">bitmap</a>.alphaType() if required.
@@ -1041,7 +1044,7 @@ Caller must allocate pixel storage in <a href="#SkCanvas_readPixels_3_bitmap">bi
<a href="SkBitmap_Reference#Bitmap">Bitmap</a> values are converted only if <a href="#Color_Type">Image Color Type</a> and <a href="#Alpha_Type">Image Alpha Type</a>
do not match. Only pixels within both source and destination rectangles
-are copied. <a href="SkBitmap_Reference#Bitmap">Bitmap</a> pixels outside the rectangle intersection are unchanged.
+are copied. <a href="SkBitmap_Reference#Bitmap">Bitmap</a> pixels outside <a href="SkRect_Reference#Rect">Rect</a> intersection are unchanged.
Pass negative values for <a href="#SkCanvas_readPixels_3_srcX">srcX</a> or <a href="#SkCanvas_readPixels_3_srcY">srcY</a> to offset pixels across or down <a href="#SkCanvas_readPixels_3_bitmap">bitmap</a>.
@@ -1098,12 +1101,13 @@ bool writePixels(const SkImageInfo& info, const void* pixels, size_t rowBytes,
int x, int y)
</pre>
-Copies rectangle from <a href="#SkCanvas_writePixels_pixels">pixels</a> to <a href="#Canvas">Canvas</a>. <a href="#Matrix">Matrix</a> and <a href="#Clip">Clip</a> are ignored.
-Source rectangle corners are (0, 0) and (<a href="#SkCanvas_writePixels_info">info</a>.width(), <a href="#SkCanvas_writePixels_info">info</a>.height()).
-Destination rectangle corners are (<a href="#SkCanvas_writePixels_x">x</a>, <a href="#SkCanvas_writePixels_y">y</a>) and(this-><a href="#SkCanvas_imageInfo">imageInfo</a>.width(), this-><a href="#SkCanvas_imageInfo">imageInfo</a>.height()).
+Copies <a href="SkRect_Reference#Rect">Rect</a> from <a href="#SkCanvas_writePixels_pixels">pixels</a> to <a href="#Canvas">Canvas</a>. <a href="#Matrix">Matrix</a> and <a href="#Clip">Clip</a> are ignored.
+Source <a href="SkRect_Reference#Rect">Rect</a> corners are (0, 0) and (<a href="#SkCanvas_writePixels_info">info</a>.width(), <a href="#SkCanvas_writePixels_info">info</a>.height()).
+Destination <a href="SkRect_Reference#Rect">Rect</a> corners are (<a href="#SkCanvas_writePixels_x">x</a>, <a href="#SkCanvas_writePixels_y">y</a>) and
+(<a href="#SkCanvas_imageInfo">imageInfo</a>.width(), <a href="#SkCanvas_imageInfo">imageInfo</a>.height()).
Copies each readable pixel intersecting both rectangles, without scaling,
-converting tothis-><a href="#SkCanvas_imageInfo">imageInfo</a>.colorType()andthis-><a href="#SkCanvas_imageInfo">imageInfo</a>.alphaType()if required.
+converting to <a href="#SkCanvas_imageInfo">imageInfo</a>.colorType() and <a href="#SkCanvas_imageInfo">imageInfo</a>.alphaType() if required.
Pixels are writable when <a href="undocumented#Device">Device</a> is raster, or backed by a <a href="undocumented#GPU">GPU</a>.
Pixels are not writable when <a href="#SkCanvas">SkCanvas</a> is returned by <a href="#SkDocument_beginPage">SkDocument::beginPage</a>,
@@ -1112,7 +1116,7 @@ class like <a href="undocumented#SkDumpCanvas">SkDumpCanvas</a>.
<a href="undocumented#Pixel">Pixel</a> values are converted only if <a href="#Color_Type">Image Color Type</a> and <a href="#Alpha_Type">Image Alpha Type</a>
do not match. Only <a href="#SkCanvas_writePixels_pixels">pixels</a> within both source and destination rectangles
-are copied. <a href="#Canvas">Canvas</a> <a href="#SkCanvas_writePixels_pixels">pixels</a> outside the rectangle intersection are unchanged.
+are copied. <a href="#Canvas">Canvas</a> <a href="#SkCanvas_writePixels_pixels">pixels</a> outside <a href="SkRect_Reference#Rect">Rect</a> intersection are unchanged.
Pass negative values for <a href="#SkCanvas_writePixels_x">x</a> or <a href="#SkCanvas_writePixels_y">y</a> to offset <a href="#SkCanvas_writePixels_pixels">pixels</a> to the left or
above <a href="#Canvas">Canvas</a> <a href="#SkCanvas_writePixels_pixels">pixels</a>.
@@ -1160,13 +1164,14 @@ true if <a href="#SkCanvas_writePixels_pixels">pixels</a> were written to <a hre
bool writePixels(const SkBitmap& bitmap, int x, int y)
</pre>
-Copies rectangle from pixels to <a href="#Canvas">Canvas</a>. <a href="#Matrix">Matrix</a> and <a href="#Clip">Clip</a> are ignored.
-Source rectangle corners are (0, 0) and (<a href="#SkCanvas_writePixels_2_bitmap">bitmap</a>.width(), <a href="#SkCanvas_writePixels_2_bitmap">bitmap</a>.height()).
+Copies <a href="SkRect_Reference#Rect">Rect</a> from pixels to <a href="#Canvas">Canvas</a>. <a href="#Matrix">Matrix</a> and <a href="#Clip">Clip</a> are ignored.
+Source <a href="SkRect_Reference#Rect">Rect</a> corners are (0, 0) and (<a href="#SkCanvas_writePixels_2_bitmap">bitmap</a>.width(), <a href="#SkCanvas_writePixels_2_bitmap">bitmap</a>.height()).
-Destination rectangle corners are (<a href="#SkCanvas_writePixels_2_x">x</a>, <a href="#SkCanvas_writePixels_2_y">y</a>) and(this-><a href="#SkCanvas_imageInfo">imageInfo</a>.width(), this-><a href="#SkCanvas_imageInfo">imageInfo</a>.height()).
+Destination <a href="SkRect_Reference#Rect">Rect</a> corners are (<a href="#SkCanvas_writePixels_2_x">x</a>, <a href="#SkCanvas_writePixels_2_y">y</a>) and
+(<a href="#SkCanvas_imageInfo">imageInfo</a>.width(), <a href="#SkCanvas_imageInfo">imageInfo</a>.height()).
Copies each readable pixel intersecting both rectangles, without scaling,
-converting tothis-><a href="#SkCanvas_imageInfo">imageInfo</a>.colorType()andthis-><a href="#SkCanvas_imageInfo">imageInfo</a>.alphaType()if required.
+converting to <a href="#SkCanvas_imageInfo">imageInfo</a>.colorType() and <a href="#SkCanvas_imageInfo">imageInfo</a>.alphaType() if required.
Pixels are writable when <a href="undocumented#Device">Device</a> is raster, or backed by a <a href="undocumented#GPU">GPU</a>.
Pixels are not writable when <a href="#SkCanvas">SkCanvas</a> is returned by <a href="#SkDocument_beginPage">SkDocument::beginPage</a>,
@@ -1175,7 +1180,7 @@ class like <a href="undocumented#SkDumpCanvas">SkDumpCanvas</a>.
<a href="undocumented#Pixel">Pixel</a> values are converted only if <a href="#Color_Type">Image Color Type</a> and <a href="#Alpha_Type">Image Alpha Type</a>
do not match. Only pixels within both source and destination rectangles
-are copied. <a href="#Canvas">Canvas</a> pixels outside the rectangle intersection are unchanged.
+are copied. <a href="#Canvas">Canvas</a> pixels outside <a href="SkRect_Reference#Rect">Rect</a> intersection are unchanged.
Pass negative values for <a href="#SkCanvas_writePixels_2_x">x</a> or <a href="#SkCanvas_writePixels_2_y">y</a> to offset pixels to the left or
above <a href="#Canvas">Canvas</a> pixels.
@@ -1554,7 +1559,7 @@ depth of saved stack
## <a name="SkCanvas__anonymous"></a> Enum SkCanvas::_anonymous
-<pre style="padding: 1em 1em 1em 1em;width: 44em; background-color: #f0f0f0">
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
enum {
<a href="#SkCanvas_kIsOpaque_SaveLayerFlag">kIsOpaque SaveLayerFlag</a> = 1 << 0,
<a href="#SkCanvas_kPreserveLCDText_SaveLayerFlag">kPreserveLCDText SaveLayerFlag</a> = 1 << 1,
@@ -1596,7 +1601,7 @@ scalePaint blends <a href="#Layer">Layer</a> back with transparency.</div></fidd
# <a name="SkCanvas_SaveLayerRec"></a> Struct SkCanvas::SaveLayerRec
-<pre style="padding: 1em 1em 1em 1em;width: 44em; background-color: #f0f0f0">
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
struct <a href="#SkCanvas_SaveLayerRec_SaveLayerRec">SaveLayerRec</a> {
<a href="#SkCanvas_SaveLayerRec_SaveLayerRec">SaveLayerRec</a>*(...
@@ -2732,7 +2737,7 @@ graphics state used to fill <a href="#Canvas">Canvas</a></td>
## <a name="SkCanvas_PointMode"></a> Enum SkCanvas::PointMode
-<pre style="padding: 1em 1em 1em 1em;width: 44em; background-color: #f0f0f0">
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
enum <a href="#SkCanvas_PointMode">PointMode</a> {
<a href="#SkCanvas_kPoints_PointMode">kPoints PointMode</a>,
<a href="#SkCanvas_kLines_PointMode">kLines PointMode</a>,
@@ -3389,7 +3394,7 @@ and so on; or nullptr</td>
## <a name="SkCanvas_SrcRectConstraint"></a> Enum SkCanvas::SrcRectConstraint
-<pre style="padding: 1em 1em 1em 1em;width: 44em; background-color: #f0f0f0">
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
enum <a href="#SkCanvas_SrcRectConstraint">SrcRectConstraint</a> {
<a href="#SkCanvas_kStrict_SrcRectConstraint">kStrict SrcRectConstraint</a>,
<a href="#SkCanvas_kFast_SrcRectConstraint">kFast SrcRectConstraint</a>,
@@ -4007,15 +4012,8 @@ and below <a href="#SkCanvas_drawBitmapNine_center">center</a> to fill the remai
---
# <a name="SkCanvas_Lattice"></a> Struct SkCanvas::Lattice
-<a href="#SkCanvas_Lattice">Lattice</a> divides <a href="SkBitmap_Reference#Bitmap">Bitmap</a> or <a href="undocumented#Image">Image</a> into a rectangular grid.
-Grid entries on even columns and even rows are fixed; these entries are
-always drawn at their original size if the destination is large enough.
-If the destination side is too small to hold the fixed entries, all fixed
-entries are proportionately scaled down to fit.
-The grid entries not on even columns and rows are scaled to fit the
-remaining space, if any.
-<pre style="padding: 1em 1em 1em 1em;width: 44em; background-color: #f0f0f0">
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
struct <a href="#SkCanvas_Lattice">Lattice</a> {
enum <a href="#SkCanvas_Lattice_Flags">Flags</a> {...
@@ -4027,9 +4025,17 @@ int <a href="#SkCanvas_Lattice_fYCount">fYCount</a>;
const <a href="SkIRect_Reference#SkIRect">SkIRect</a>* <a href="#SkCanvas_Lattice_fBounds">fBounds</a>;
};</pre>
+<a href="#SkCanvas_Lattice">Lattice</a> divides <a href="SkBitmap_Reference#Bitmap">Bitmap</a> or <a href="undocumented#Image">Image</a> into a rectangular grid.
+Grid entries on even columns and even rows are fixed; these entries are
+always drawn at their original size if the destination is large enough.
+If the destination side is too small to hold the fixed entries, all fixed
+entries are proportionately scaled down to fit.
+The grid entries not on even columns and rows are scaled to fit the
+remaining space, if any.
+
## <a name="SkCanvas_Lattice_Flags"></a> Enum SkCanvas::Lattice::Flags
-<pre style="padding: 1em 1em 1em 1em;width: 44em; background-color: #f0f0f0">
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
enum <a href="#SkCanvas_Lattice_Flags">Flags</a> : uint8_t {
<a href="#SkCanvas_Lattice_kTransparent_Flags">kTransparent Flags</a> = 1 << 0,
};</pre>
@@ -5306,8 +5312,8 @@ Restores <a href="#Canvas">Canvas</a> to saved state.
void restore()
</pre>
-Restores <a href="#Canvas">Canvas</a> to saved state immediately. Subsequent calls and class
-destructor have no effect.
+Restores <a href="#Canvas">Canvas</a> to saved state immediately. Subsequent calls and
+<a href="#SkAutoCanvasRestore_destructor">~SkAutoCanvasRestore</a> have no effect.
### Example
diff --git a/site/user/api/SkIRect_Reference.md b/site/user/api/SkIRect_Reference.md
index 1982c5094d..7022cc6aec 100644
--- a/site/user/api/SkIRect_Reference.md
+++ b/site/user/api/SkIRect_Reference.md
@@ -34,7 +34,7 @@ its <a href="#SkIRect_top">top</a>, it is considered empty.
| <a href="#SkIRect_MakeEmpty">MakeEmpty</a> | Returns bounds of (0, 0, 0, 0). |
| <a href="#SkIRect_MakeLTRB">MakeLTRB</a> | Constructs from int <a href="#SkIRect_left">left</a>, <a href="#SkIRect_top">top</a>, <a href="#SkIRect_right">right</a>, <a href="#SkIRect_bottom">bottom</a>. |
| <a href="#SkIRect_MakeLargest">MakeLargest</a> | Constructs from (<a href="undocumented#SK_MinS32">SK MinS32</a>, <a href="undocumented#SK_MinS32">SK MinS32</a>, <a href="undocumented#SK_MaxS32">SK MaxS32</a>, <a href="undocumented#SK_MaxS32">SK MaxS32</a>). |
-| <a href="#SkIRect_MakeSize">MakeSize</a> | Constructs from <a href="#Size">ISize</a> returning (0, 0, <a href="#SkIRect_width">width</a>, <a href="#SkIRect_height">height</a>). |
+| <a href="#SkIRect_MakeSize">MakeSize</a> | Constructs from <a href="undocumented#ISize">ISize</a> returning (0, 0, <a href="#SkIRect_width">width</a>, <a href="#SkIRect_height">height</a>). |
| <a href="#SkIRect_MakeWH">MakeWH</a> | Constructs from int input returning (0, 0, <a href="#SkIRect_width">width</a>, <a href="#SkIRect_height">height</a>). |
| <a href="#SkIRect_MakeXYWH">MakeXYWH</a> | Constructs from int input returning (<a href="#SkIRect_x">x</a>, <a href="#SkIRect_y">y</a>, <a href="#SkIRect_width">width</a>, <a href="#SkIRect_height">height</a>). |
| <a href="#SkIRect_bottom">bottom</a> | Returns larger bounds in <a href="#SkIRect_y">y</a>, if sorted. |
@@ -66,7 +66,7 @@ its <a href="#SkIRect_top">top</a>, it is considered empty.
| <a href="#SkIRect_setLargest">setLargest</a> | Sets to (<a href="undocumented#SK_MinS32">SK MinS32</a>, <a href="undocumented#SK_MinS32">SK MinS32</a>, <a href="undocumented#SK_MaxS32">SK MaxS32</a>, <a href="undocumented#SK_MaxS32">SK MaxS32</a>). |
| <a href="#SkIRect_setLargestInverted">setLargestInverted</a> | Sets to (<a href="undocumented#SK_MaxS32">SK MaxS32</a>, <a href="undocumented#SK_MaxS32">SK MaxS32</a>, <a href="undocumented#SK_MinS32">SK MinS32</a>, <a href="undocumented#SK_MinS32">SK MinS32</a>). |
| <a href="#SkIRect_setXYWH">setXYWH</a> | Sets to (<a href="#SkIRect_x">x</a>, <a href="#SkIRect_y">y</a>, <a href="#SkIRect_width">width</a>, <a href="#SkIRect_height">height</a>). |
-| <a href="#SkIRect_size">size</a> | Returns <a href="#Size">ISize</a> (<a href="#SkIRect_width">width</a>, <a href="#SkIRect_height">height</a>). |
+| <a href="#SkIRect_size">size</a> | Returns <a href="undocumented#ISize">ISize</a> (<a href="#SkIRect_width">width</a>, <a href="#SkIRect_height">height</a>). |
| <a href="#SkIRect_sort">sort</a> | Orders sides from smaller to larger. |
| <a href="#SkIRect_top">top</a> | Returns smaller bounds in <a href="#SkIRect_y">y</a>, if sorted. |
| <a href="#SkIRect_width">width</a> | Returns span in <a href="#SkIRect_x">x</a>. |
@@ -301,7 +301,8 @@ static constexpr SkIRect SK_WARN_UNUSED_RESULT MakeXYWH(int32_t x, int32_t y,
int32_t w, int32_t h)
</pre>
-Returns constructed <a href="#IRect">IRect</a> <a href="#SkIRect_set">set</a> to(<a href="#SkIRect_x">x</a>, <a href="#SkIRect_y">y</a>, <a href="#SkIRect_x">x</a> + <a href="#SkIRect_MakeXYWH_w">w</a>, <a href="#SkIRect_y">y</a> + <a href="#SkIRect_MakeXYWH_h">h</a>).
+Returns constructed <a href="#IRect">IRect</a> <a href="#SkIRect_set">set</a> to:
+(<a href="#SkIRect_x">x</a>, <a href="#SkIRect_y">y</a>, <a href="#SkIRect_x">x</a> + <a href="#SkIRect_MakeXYWH_w">w</a>, <a href="#SkIRect_y">y</a> + <a href="#SkIRect_MakeXYWH_h">h</a>).
Does not validate input;
<a href="#SkIRect_MakeXYWH_w">w</a> or <a href="#SkIRect_MakeXYWH_h">h</a> may be negative.
@@ -617,7 +618,7 @@ or if result fits in 32-bit signed integer; result may be negative.
### Return Value
-<a href="#Size">ISize</a> (<a href="#SkIRect_width">width</a>, <a href="#SkIRect_height">height</a>)
+<a href="undocumented#ISize">ISize</a> (<a href="#SkIRect_width">width</a>, <a href="#SkIRect_height">height</a>)
### Example
@@ -1019,7 +1020,8 @@ rect2: {3, 4, 1, 2}
void setXYWH(int32_t x, int32_t y, int32_t width, int32_t height)
</pre>
-Sets <a href="#IRect">IRect</a> to(<a href="#SkIRect_x">x</a>, <a href="#SkIRect_y">y</a>, <a href="#SkIRect_x">x</a> + <a href="#SkIRect_width">width</a>, <a href="#SkIRect_y">y</a> + <a href="#SkIRect_height">height</a>).
+Sets <a href="#IRect">IRect</a> to:
+(<a href="#SkIRect_x">x</a>, <a href="#SkIRect_y">y</a>, <a href="#SkIRect_x">x</a> + <a href="#SkIRect_width">width</a>, <a href="#SkIRect_y">y</a> + <a href="#SkIRect_height">height</a>).
Does not validate input;
<a href="#SkIRect_width">width</a> or <a href="#SkIRect_height">height</a> may be negative.
@@ -1495,11 +1497,13 @@ rect (7, 11, 13, 17) test(12, 16, 14, 18) quickReject false; intersects true
bool contains(int32_t x, int32_t y) const
</pre>
-Returns true if<a href="#SkIRect_fLeft">fLeft</a> <= <a href="#SkIRect_x">x</a> < <a href="#SkIRect_fRight">fRight</a> && <a href="#SkIRect_fTop">fTop</a> <= <a href="#SkIRect_y">y</a> < <a href="#SkIRect_fBottom">fBottom</a>.
+Returns true if:
+<a href="#SkIRect_fLeft">fLeft</a> <= <a href="#SkIRect_x">x</a> < <a href="#SkIRect_fRight">fRight</a> && <a href="#SkIRect_fTop">fTop</a> <= <a href="#SkIRect_y">y</a> < <a href="#SkIRect_fBottom">fBottom</a>.
Returns false if <a href="SkRect_Reference#Rect">Rect</a> is empty.
-Considers input to describe constructed <a href="#IRect">IRect</a> (<a href="#SkIRect_x">x</a>, <a href="#SkIRect_y">y</a>, <a href="#SkIRect_x">x</a> + 1, <a href="#SkIRect_y">y</a> + 1) and
+Considers input to describe constructed <a href="#IRect">IRect</a>:
+(<a href="#SkIRect_x">x</a>, <a href="#SkIRect_y">y</a>, <a href="#SkIRect_x">x</a> + 1, <a href="#SkIRect_y">y</a> + 1)and
returns true if constructed area is completely enclosed by <a href="#IRect">IRect</a> area.
### Parameters
@@ -1758,7 +1762,7 @@ rect: (30, 50, 40, 60) does not contain (29, 59, 30, 60)
# <a name="Intersection"></a> Intersection
IRects <a href="#SkIRect_intersect">intersect</a> when they enclose a common area. To <a href="#SkIRect_intersect">intersect</a>, each of the pair
must describe area; <a href="#SkIRect_fLeft">fLeft</a> is less than <a href="#SkIRect_fRight">fRight</a>, and <a href="#SkIRect_fTop">fTop</a> is less than <a href="#SkIRect_fBottom">fBottom</a>;
-empty() returns false. The intersection of <a href="#IRect">IRect</a> a and <a href="#IRect">IRect</a> b can be described by:
+empty() returns false. The intersection of <a href="#IRect">IRect</a> pair can be described by:
(max(a.fLeft, b.fLeft), max(a.fTop, b.fTop),
min(a.fRight, b.fRight), min(a.fBottom, b.fBottom))The intersection is only meaningful if the resulting <a href="#IRect">IRect</a> is not empty and
describes an area: <a href="#SkIRect_fLeft">fLeft</a> is less than <a href="#SkIRect_fRight">fRight</a>, and <a href="#SkIRect_fTop">fTop</a> is less than <a href="#SkIRect_fBottom">fBottom</a>.
diff --git a/site/user/api/SkMatrix_Reference.md b/site/user/api/SkMatrix_Reference.md
new file mode 100644
index 0000000000..46cca59545
--- /dev/null
+++ b/site/user/api/SkMatrix_Reference.md
@@ -0,0 +1,4459 @@
+SkMatrix Reference
+===
+
+# <a name="Matrix"></a> Matrix
+
+# <a name="SkMatrix"></a> Class SkMatrix
+<a href="#Matrix">Matrix</a> holds a 3x3 matrix for transforming coordinates. This allows mapping
+<a href="#Point">Points</a> and <a href="#Vector">Vectors</a> with translation, scaling, skewing, rotation, and
+perspective.
+
+<a href="#Matrix">Matrix</a> elements are in row major order. <a href="#Matrix">Matrix</a> does not have a constructor,
+so it must be explicitly initialized. <a href="#SkMatrix_setIdentity">setIdentity</a> initializes <a href="#Matrix">Matrix</a>
+so it has no effect. <a href="#SkMatrix_setTranslate">setTranslate</a>, <a href="#SkMatrix_setScale">setScale</a>, <a href="#SkMatrix_setSkew">setSkew</a>, <a href="#SkMatrix_setRotate">setRotate</a>, <a href="#SkMatrix_set9">set9</a> and <a href="#SkMatrix_setAll">setAll</a>
+initializes all <a href="#Matrix">Matrix</a> elements with the corresponding mapping.
+
+<a href="#Matrix">Matrix</a> includes a hidden variable that classifies the type of matrix to
+improve performance. <a href="#Matrix">Matrix</a> is not thread safe unless <a href="#SkMatrix_getType">getType</a> is called first.
+
+# <a name="Overview"></a> Overview
+
+## <a name="Subtopics"></a> Subtopics
+
+| topics | description |
+| --- | --- |
+
+## <a name="Operators"></a> Operators
+
+| function | description |
+| --- | --- |
+| <a href="#SkMatrix_not_equal_operator">operator!=(const SkMatrix& a, const SkMatrix& b)</a> | Returns true if members are unequal. |
+| <a href="#SkMatrix_equal_operator">operator==(const SkMatrix& a, const SkMatrix& b)</a> | Returns true if members are equal. |
+| <a href="#SkMatrix_subscript_operator_const">operator[](int index)</a> const | Returns <a href="#Matrix">Matrix</a> value. |
+| <a href="#SkMatrix_subscript_operator_const">operator[](int index)</a> | Returns writable reference to <a href="#Matrix">Matrix</a> value. |
+
+## <a name="Member_Functions"></a> Member Functions
+
+| function | description |
+| --- | --- |
+| <a href="#SkMatrix_Concat">Concat</a> | Returns the concatenation of <a href="#Matrix">Matrix</a> pair. |
+| <a href="#SkMatrix_I">I</a> | Returns a reference to a const identity <a href="#Matrix">Matrix</a>. |
+| <a href="#SkMatrix_InvalidMatrix">InvalidMatrix</a> | Returns a reference to a const invalid <a href="#Matrix">Matrix</a>. |
+| <a href="#SkMatrix_MakeRectToRect">MakeRectToRect</a> | Constructs from source <a href="SkRect_Reference#Rect">Rect</a> to destination <a href="SkRect_Reference#Rect">Rect</a>. |
+| <a href="#SkMatrix_MakeScale">MakeScale</a> | Constructs from scale in x and y. |
+| <a href="#SkMatrix_MakeTrans">MakeTrans</a> | Constructs from translate in x and y. |
+| <a href="#SkMatrix_SetAffineIdentity">SetAffineIdentity</a> | Sets 3x2 array to identity. |
+| <a href="#SkMatrix_asAffine">asAffine</a> | Copies to 3x2 array. |
+| <a href="#SkMatrix_cheapEqualTo">cheapEqualTo</a> | Compares <a href="#Matrix">Matrix</a> pair using memcmp(). |
+| <a href="#SkMatrix_decomposeScale">decomposeScale</a> | Separates scale if possible. |
+| <a href="#SkMatrix_dirtyMatrixTypeCache">dirtyMatrixTypeCache</a> | Sets internal cache to unknown state. |
+| <a href="#SkMatrix_dump">dump</a> | Sends text representation using floats to standard output. |
+| <a href="#SkMatrix_fixedStepInX">fixedStepInX</a> | Returns step in x for a position in y. |
+| <a href="#SkMatrix_get">get</a> | Returns one of nine <a href="#Matrix">Matrix</a> values. |
+| <a href="#SkMatrix_get9">get9</a> | Returns all nine <a href="#Matrix">Matrix</a> values. |
+| <a href="#SkMatrix_getMaxScale">getMaxScale</a> | Returns maximum scaling, if possible. |
+| <a href="#SkMatrix_getMinMaxScales">getMinMaxScales</a> | Returns minimum and maximum scaling, if possible. |
+| <a href="#SkMatrix_getMinScale">getMinScale</a> | Returns minimum scaling, if possible. |
+| <a href="#SkMatrix_getPerspX">getPerspX</a> | Returns input x perspective factor. |
+| <a href="#SkMatrix_getPerspY">getPerspY</a> | Returns input y perspective factor. |
+| <a href="#SkMatrix_getScaleX">getScaleX</a> | Returns horizontal scale factor. |
+| <a href="#SkMatrix_getScaleY">getScaleY</a> | Returns vertical scale factor. |
+| <a href="#SkMatrix_getSkewX">getSkewX</a> | Returns horizontal skew factor. |
+| <a href="#SkMatrix_getSkewY">getSkewY</a> | Returns vertical skew factor. |
+| <a href="#SkMatrix_getTranslateX">getTranslateX</a> | Returns horizontal translation. |
+| <a href="#SkMatrix_getTranslateY">getTranslateY</a> | Returns vertical translation. |
+| <a href="#SkMatrix_getType">getType</a> | Returns transform complexity. |
+| <a href="#SkMatrix_hasPerspective">hasPerspective</a> | Returns if transform includes perspective. |
+| <a href="#SkMatrix_invert">invert</a> | Returns inverse, if possible. |
+| <a href="#SkMatrix_isFinite">isFinite</a> | Returns if all <a href="#Matrix">Matrix</a> values are not infinity, <a href="undocumented#NaN">NaN</a>. |
+| <a href="#SkMatrix_isFixedStepInX">isFixedStepInX</a> | Returns if transformation supports fixed step in x. |
+| <a href="#SkMatrix_isIdentity">isIdentity</a> | Returns if matrix equals the identity <a href="#Matrix">Matrix</a> . |
+| <a href="#SkMatrix_isScaleTranslate">isScaleTranslate</a> | Returns if transform is limited to scale and translate. |
+| <a href="#SkMatrix_isSimilarity">isSimilarity</a> | Returns if transform is limited to square scale and rotation. |
+| <a href="#SkMatrix_isTranslate">isTranslate</a> | Returns if transform is limited to translate. |
+| <a href="#SkMatrix_mapHomogeneousPoints">mapHomogeneousPoints</a> | Maps <a href="undocumented#Point3">Point3</a> array. |
+| <a href="#SkMatrix_mapPoints">mapPoints</a> | Maps <a href="undocumented#Point">Point</a> array. |
+| <a href="#SkMatrix_mapPointsWithStride">mapPointsWithStride</a> | Maps <a href="undocumented#Point">Point</a> array with padding. |
+| <a href="#SkMatrix_mapRadius">mapRadius</a> | Returns mean radius of mapped <a href="undocumented#Circle">Circle</a>. |
+| <a href="#SkMatrix_mapRect">mapRect</a> | Returns bounds of mapped <a href="SkRect_Reference#Rect">Rect</a>. |
+| <a href="#SkMatrix_mapRectScaleTranslate">mapRectScaleTranslate</a> | Returns bounds of mapped <a href="SkRect_Reference#Rect">Rect</a>. |
+| <a href="#SkMatrix_mapRectToQuad">mapRectToQuad</a> | Maps <a href="SkRect_Reference#Rect">Rect</a> to <a href="undocumented#Point">Point</a> array. |
+| <a href="#SkMatrix_mapVector">mapVector</a> | Maps <a href="undocumented#Vector">Vector</a>. |
+| <a href="#SkMatrix_mapVectors">mapVectors</a> | Maps <a href="undocumented#Vector">Vector</a> array. |
+| <a href="#SkMatrix_mapXY">mapXY</a> | Maps <a href="undocumented#Point">Point</a>. |
+| <a href="#SkMatrix_postConcat">postConcat</a> | Post-multiplies <a href="#Matrix">Matrix</a> by <a href="#Matrix">Matrix</a> parameter. |
+| <a href="#SkMatrix_postIDiv">postIDiv</a> | Post-multiplies <a href="#Matrix">Matrix</a> by inverse scale. |
+| <a href="#SkMatrix_postRotate">postRotate</a> | Post-multiplies <a href="#Matrix">Matrix</a> by rotation. |
+| <a href="#SkMatrix_postScale">postScale</a> | Post-multiplies <a href="#Matrix">Matrix</a> by scale. |
+| <a href="#SkMatrix_postSkew">postSkew</a> | Post-multiplies <a href="#Matrix">Matrix</a> by skew. |
+| <a href="#SkMatrix_postTranslate">postTranslate</a> | Post-multiplies <a href="#Matrix">Matrix</a> by translation. |
+| <a href="#SkMatrix_preConcat">preConcat</a> | Pre-multiplies <a href="#Matrix">Matrix</a> by <a href="#Matrix">Matrix</a> parameter. |
+| <a href="#SkMatrix_preRotate">preRotate</a> | Pre-multiplies <a href="#Matrix">Matrix</a> by rotation. |
+| <a href="#SkMatrix_preScale">preScale</a> | Pre-multiplies <a href="#Matrix">Matrix</a> by scale. |
+| <a href="#SkMatrix_preSkew">preSkew</a> | Pre-multiplies <a href="#Matrix">Matrix</a> by skew. |
+| <a href="#SkMatrix_preTranslate">preTranslate</a> | Pre-multiplies <a href="#Matrix">Matrix</a> by translation. |
+| <a href="#SkMatrix_preservesAxisAlignment">preservesAxisAlignment</a> | Returns if mapping restricts to 90 degree multiples and mirroring. |
+| <a href="#SkMatrix_preservesRightAngles">preservesRightAngles</a> | Returns if mapped 90 angle remains 90 degrees. |
+| <a href="#SkMatrix_rectStaysRect">rectStaysRect</a> | Returns if mapped <a href="SkRect_Reference#Rect">Rect</a> can be represented by another <a href="SkRect_Reference#Rect">Rect</a>. |
+| <a href="#SkMatrix_reset">reset</a> | Sets <a href="#Matrix">Matrix</a> to identity. |
+| <a href="#SkMatrix_set">set</a> | Sets one value. |
+| <a href="#SkMatrix_set9">set9</a> | Sets all values from <a href="#Scalar">Scalar</a> array. |
+| <a href="#SkMatrix_setAffine">setAffine</a> | Sets left two columns. |
+| <a href="#SkMatrix_setAll">setAll</a> | Sets all values from parameters. |
+| <a href="#SkMatrix_setConcat">setConcat</a> | Sets to <a href="#Matrix">Matrix</a> parameter multiplied by <a href="#Matrix">Matrix</a> parameter. |
+| <a href="#SkMatrix_setIdentity">setIdentity</a> | Sets <a href="#Matrix">Matrix</a> to identity. |
+| <a href="#SkMatrix_setPerspX">setPerspX</a> | Sets input x perspective factor. |
+| <a href="#SkMatrix_setPerspY">setPerspY</a> | Sets input y perspective factor. |
+| <a href="#SkMatrix_setPolyToPoly">setPolyToPoly</a> | Sets to map one to four points to an equal array of points. |
+| <a href="#SkMatrix_setRSXform">setRSXform</a> | Sets to rotate, scale, and translate. |
+| <a href="#SkMatrix_setRectToRect">setRectToRect</a> | Sets to map one <a href="SkRect_Reference#Rect">Rect</a> to another. |
+| <a href="#SkMatrix_setRotate">setRotate</a> | Sets to rotate about a point. |
+| <a href="#SkMatrix_setScale">setScale</a> | Sets to scale about a point. |
+| <a href="#SkMatrix_setScaleTranslate">setScaleTranslate</a> | Sets to scale and translate. |
+| <a href="#SkMatrix_setScaleX">setScaleX</a> | Sets horizontal scale factor. |
+| <a href="#SkMatrix_setScaleY">setScaleY</a> | Sets vertical scale factor |
+| <a href="#SkMatrix_setSinCos">setSinCos</a> | Sets to rotate and scale about a point. |
+| <a href="#SkMatrix_setSkew">setSkew</a> | Sets to skew about a point. |
+| <a href="#SkMatrix_setSkewX">setSkewX</a> | Sets horizontal skew factor. |
+| <a href="#SkMatrix_setSkewY">setSkewY</a> | Sets vertical skew factor. |
+| <a href="#SkMatrix_setTranslate">setTranslate</a> | Sets to translate in x and y. |
+| <a href="#SkMatrix_setTranslateX">setTranslateX</a> | Sets horizontal translation. |
+| <a href="#SkMatrix_setTranslateY">setTranslateY</a> | Sets vertical translation. |
+| <a href="#SkMatrix_toString">toString</a> | Converts <a href="#Matrix">Matrix</a> to machine readable form. |
+
+<a name="SkMatrix_MakeScale"></a>
+## MakeScale
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+static SkMatrix SK_WARN_UNUSED_RESULT MakeScale(SkScalar sx, SkScalar sy)
+</pre>
+
+Sets <a href="#Matrix">Matrix</a> to scale by (<a href="#SkMatrix_MakeScale_sx">sx</a>, <a href="#SkMatrix_MakeScale_sy">sy</a>). Returned matrix is:
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+| sx 0 0 |
+| 0 sy 0 |
+| 0 0 1 |</pre>
+
+### Parameters
+
+<table> <tr> <td><a name="SkMatrix_MakeScale_sx"> <code><strong>sx </strong></code> </a></td> <td>
+horizontal scale factor</td>
+ </tr> <tr> <td><a name="SkMatrix_MakeScale_sy"> <code><strong>sy </strong></code> </a></td> <td>
+vertical scale factor</td>
+ </tr>
+</table>
+
+### Return Value
+
+<a href="#Matrix">Matrix</a> with scale
+
+### Example
+
+<div><fiddle-embed name="7ff17718111df6d6f95381d8a8f1b389"></fiddle-embed></div>
+
+### See Also
+
+<a href="#SkMatrix_setScale">setScale</a> <a href="#SkMatrix_postScale">postScale</a> <a href="#SkMatrix_preScale">preScale</a>
+
+---
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+static SkMatrix SK_WARN_UNUSED_RESULT MakeScale(SkScalar scale)
+</pre>
+
+Sets <a href="#Matrix">Matrix</a> to <a href="#SkMatrix_MakeScale_2_scale">scale</a> by (<a href="#SkMatrix_MakeScale_2_scale">scale</a>, <a href="#SkMatrix_MakeScale_2_scale">scale</a>). Returned matrix is:
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+| scale 0 0 |
+| 0 scale 0 |
+| 0 0 1 |</pre>
+
+### Parameters
+
+<table> <tr> <td><a name="SkMatrix_MakeScale_2_scale"> <code><strong>scale </strong></code> </a></td> <td>
+horizontal and vertical <a href="#SkMatrix_MakeScale_2_scale">scale</a> factor</td>
+ </tr>
+</table>
+
+### Return Value
+
+<a href="#Matrix">Matrix</a> with <a href="#SkMatrix_MakeScale_2_scale">scale</a>
+
+### Example
+
+<div><fiddle-embed name="2956aeb50fa862cdb13995e1e56a4bc8"></fiddle-embed></div>
+
+### See Also
+
+<a href="#SkMatrix_setScale">setScale</a> <a href="#SkMatrix_postScale">postScale</a> <a href="#SkMatrix_preScale">preScale</a>
+
+---
+
+<a name="SkMatrix_MakeTrans"></a>
+## MakeTrans
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+static SkMatrix SK_WARN_UNUSED_RESULT MakeTrans(SkScalar dx, SkScalar dy)
+</pre>
+
+Sets <a href="#Matrix">Matrix</a> to translate by (<a href="#SkMatrix_MakeTrans_dx">dx</a>, <a href="#SkMatrix_MakeTrans_dy">dy</a>). Returned matrix is:
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+| 1 0 0 |
+| 0 1 0 |
+| dx dy 1 |</pre>
+
+### Parameters
+
+<table> <tr> <td><a name="SkMatrix_MakeTrans_dx"> <code><strong>dx </strong></code> </a></td> <td>
+horizontal translation</td>
+ </tr> <tr> <td><a name="SkMatrix_MakeTrans_dy"> <code><strong>dy </strong></code> </a></td> <td>
+vertical translation</td>
+ </tr>
+</table>
+
+### Return Value
+
+<a href="#Matrix">Matrix</a> with translation
+
+### Example
+
+<div><fiddle-embed name="b2479df0d9cf296ff64ac31e36684557"></fiddle-embed></div>
+
+### See Also
+
+<a href="#SkMatrix_setTranslate">setTranslate</a> <a href="#SkMatrix_postTranslate">postTranslate</a> <a href="#SkMatrix_preTranslate">preTranslate</a>
+
+---
+
+## <a name="SkMatrix_TypeMask"></a> Enum SkMatrix::TypeMask
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+enum <a href="#SkMatrix_TypeMask">TypeMask</a> {
+<a href="#SkMatrix_kIdentity_Mask">kIdentity Mask</a> = 0,
+<a href="#SkMatrix_kTranslate_Mask">kTranslate Mask</a> = 0x01,
+<a href="#SkMatrix_kScale_Mask">kScale Mask</a> = 0x02,
+<a href="#SkMatrix_kAffine_Mask">kAffine Mask</a> = 0x04,
+<a href="#SkMatrix_kPerspective_Mask">kPerspective Mask</a> = 0x08,
+};</pre>
+
+Enum of bit fields for mask returned by <a href="#SkMatrix_getType">getType</a>.
+Used to identify the complexity of <a href="#Matrix">Matrix</a>, to optimize performance.
+
+### Constants
+
+<table>
+ <tr>
+ <td><a name="SkMatrix_kIdentity_Mask"> <code><strong>SkMatrix::kIdentity_Mask </strong></code> </a></td><td>0</td><td>all bits clear if <a href="#Matrix">Matrix</a> is identity</td>
+ </tr>
+ <tr>
+ <td><a name="SkMatrix_kTranslate_Mask"> <code><strong>SkMatrix::kTranslate_Mask </strong></code> </a></td><td>1</td><td><a href="#SkMatrix_set">set</a> if <a href="#Matrix">Matrix</a> has translation</td>
+ </tr>
+ <tr>
+ <td><a name="SkMatrix_kScale_Mask"> <code><strong>SkMatrix::kScale_Mask </strong></code> </a></td><td>2</td><td><a href="#SkMatrix_set">set</a> if <a href="#Matrix">Matrix</a> has x or y scale</td>
+ </tr>
+ <tr>
+ <td><a name="SkMatrix_kAffine_Mask"> <code><strong>SkMatrix::kAffine_Mask </strong></code> </a></td><td>4</td><td><a href="#SkMatrix_set">set</a> if <a href="#Matrix">Matrix</a> skews or rotates</td>
+ </tr>
+ <tr>
+ <td><a name="SkMatrix_kPerspective_Mask"> <code><strong>SkMatrix::kPerspective_Mask </strong></code> </a></td><td>8</td><td><a href="#SkMatrix_set">set</a> if <a href="#Matrix">Matrix</a> has perspective</td>
+ </tr>
+</table>
+
+### Example
+
+<div><fiddle-embed name="ba19b36df8cd78586f3dff54e2d4c093">
+
+#### Example Output
+
+~~~~
+after reset: kIdentity_Mask
+after postTranslate: kTranslate_Mask
+after postScale: kTranslate_Mask kScale_Mask
+after postScale: kTranslate_Mask kScale_Mask kAffine_Mask
+after setPolyToPoly: kTranslate_Mask kScale_Mask kAffine_Mask kPerspective_Mask
+~~~~
+
+</fiddle-embed></div>
+
+### See Also
+
+<a href="#SkMatrix_getType">getType</a>
+
+
+
+<a name="SkMatrix_getType"></a>
+## getType
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+TypeMask getType() const
+</pre>
+
+Returns a bit field describing the transformations the matrix may
+perform. The bit field is computed conservatively, so it may include
+false positives. For example, when <a href="#SkMatrix_kPerspective_Mask">kPerspective Mask</a> is <a href="#SkMatrix_set">set</a>, all
+other bits are <a href="#SkMatrix_set">set</a>.
+
+### Return Value
+
+<a href="#SkMatrix_kIdentity_Mask">kIdentity Mask</a>, or combinations of: <a href="#SkMatrix_kTranslate_Mask">kTranslate Mask</a>, <a href="#SkMatrix_kScale_Mask">kScale Mask</a>,
+<a href="#SkMatrix_kAffine_Mask">kAffine Mask</a>, <a href="#SkMatrix_kPerspective_Mask">kPerspective Mask</a>
+
+### Example
+
+<div><fiddle-embed name="8e45fe2dd52731bb2d4318686257e1d7">
+
+#### Example Output
+
+~~~~
+identity flags hex: 0 decimal: 0
+set all flags hex: f decimal: 15
+~~~~
+
+</fiddle-embed></div>
+
+### See Also
+
+<a href="#SkMatrix_TypeMask">TypeMask</a>
+
+---
+
+<a name="SkMatrix_isIdentity"></a>
+## isIdentity
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+bool isIdentity() const
+</pre>
+
+Returns true if <a href="#Matrix">Matrix</a> is identity. Identity matrix is:
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+| 1 0 0 |
+| 0 1 0 |
+| 0 0 1 |</pre>
+
+### Return Value
+
+true if <a href="#Matrix">Matrix</a> has no effect
+
+### Example
+
+<div><fiddle-embed name="780ab376325b3cfa889ea26c0769ec11">
+
+#### Example Output
+
+~~~~
+is identity: true
+is identity: false
+~~~~
+
+</fiddle-embed></div>
+
+### See Also
+
+<a href="#SkMatrix_reset">reset</a> <a href="#SkMatrix_setIdentity">setIdentity</a> <a href="#SkMatrix_getType">getType</a>
+
+---
+
+<a name="SkMatrix_isScaleTranslate"></a>
+## isScaleTranslate
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+bool isScaleTranslate() const
+</pre>
+
+Returns true if <a href="#Matrix">Matrix</a> at most scales and translates. <a href="#Matrix">Matrix</a> may be identity,
+contain only scale elements, only translate elements, or both. <a href="#Matrix">Matrix</a> form is:
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+| scale-x 0 translate-x |
+| 0 scale-y translate-y |
+| 0 0 1 |</pre>
+
+### Return Value
+
+true if <a href="#Matrix">Matrix</a> is identity; or scales, translates, or both
+
+### Example
+
+<div><fiddle-embed name="6287e29674a487eb94174992d45b9a34">
+
+#### Example Output
+
+~~~~
+is scale-translate: true
+is scale-translate: true
+is scale-translate: true
+is scale-translate: true
+~~~~
+
+</fiddle-embed></div>
+
+### See Also
+
+<a href="#SkMatrix_setScale">setScale</a> <a href="#SkMatrix_isTranslate">isTranslate</a> <a href="#SkMatrix_setTranslate">setTranslate</a> <a href="#SkMatrix_getType">getType</a>
+
+---
+
+<a name="SkMatrix_isTranslate"></a>
+## isTranslate
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+bool isTranslate() const
+</pre>
+
+Returns true if <a href="#Matrix">Matrix</a> is identity, or translates. <a href="#Matrix">Matrix</a> form is:
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+| 1 0 translate-x |
+| 0 1 translate-y |
+| 0 0 1 |</pre>
+
+### Return Value
+
+true if <a href="#Matrix">Matrix</a> is identity, or translates
+
+### Example
+
+<div><fiddle-embed name="73ac71a8a30841873577c11c6c9b38ee">
+
+#### Example Output
+
+~~~~
+is translate: true
+is translate: true
+is translate: false
+is translate: false
+~~~~
+
+</fiddle-embed></div>
+
+### See Also
+
+<a href="#SkMatrix_setTranslate">setTranslate</a> <a href="#SkMatrix_getType">getType</a>
+
+---
+
+<a name="SkMatrix_rectStaysRect"></a>
+## rectStaysRect
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+bool rectStaysRect() const
+</pre>
+
+Returns true <a href="#Matrix">Matrix</a> maps <a href="SkRect_Reference#Rect">Rect</a> to another <a href="SkRect_Reference#Rect">Rect</a>. If true, <a href="#Matrix">Matrix</a> is identity,
+or scales, or rotates a multiple of 90 degrees, or mirrors in x or y. In all
+cases, <a href="#Matrix">Matrix</a> may also have translation. <a href="#Matrix">Matrix</a> form is either:
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+| scale-x 0 translate-x |
+| 0 scale-y translate-y |
+| 0 0 1 |</pre>
+
+or
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+| 0 rotate-x translate-x |
+| rotate-y 0 translate-y |
+| 0 0 1 |</pre>
+
+for non-zero values of scale-x, scale-y, rotate-x, and rotate-y.
+
+Also called <a href="#SkMatrix_preservesAxisAlignment">preservesAxisAlignment</a>; use the one that provides better inline
+documentation.
+
+### Return Value
+
+true if <a href="#Matrix">Matrix</a> maps one <a href="SkRect_Reference#Rect">Rect</a> into another
+
+### Example
+
+<div><fiddle-embed name="ce5319c036c9b5086da8a0009fe409f8">
+
+#### Example Output
+
+~~~~
+rectStaysRect: true
+rectStaysRect: true
+rectStaysRect: true
+rectStaysRect: true
+~~~~
+
+</fiddle-embed></div>
+
+### See Also
+
+<a href="#SkMatrix_preservesAxisAlignment">preservesAxisAlignment</a> <a href="#SkMatrix_preservesRightAngles">preservesRightAngles</a>
+
+---
+
+<a name="SkMatrix_preservesAxisAlignment"></a>
+## preservesAxisAlignment
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+bool preservesAxisAlignment() const
+</pre>
+
+Returns true <a href="#Matrix">Matrix</a> maps <a href="SkRect_Reference#Rect">Rect</a> to another <a href="SkRect_Reference#Rect">Rect</a>. If true, <a href="#Matrix">Matrix</a> is identity,
+or scales, or rotates a multiple of 90 degrees, or mirrors in x or y. In all
+cases, <a href="#Matrix">Matrix</a> may also have translation. <a href="#Matrix">Matrix</a> form is either:
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+| scale-x 0 translate-x |
+| 0 scale-y translate-y |
+| 0 0 1 |</pre>
+
+or
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+| 0 rotate-x translate-x |
+| rotate-y 0 translate-y |
+| 0 0 1 |</pre>
+
+for non-zero values of scale-x, scale-y, rotate-x, and rotate-y.
+
+Also called <a href="#SkMatrix_rectStaysRect">rectStaysRect</a>; use the one that provides better inline
+documentation.
+
+### Return Value
+
+true if <a href="#Matrix">Matrix</a> maps one <a href="SkRect_Reference#Rect">Rect</a> into another
+
+### Example
+
+<div><fiddle-embed name="7a234c96608fb7cb8135b9940b0b15f7">
+
+#### Example Output
+
+~~~~
+preservesAxisAlignment: true
+preservesAxisAlignment: true
+preservesAxisAlignment: true
+preservesAxisAlignment: true
+~~~~
+
+</fiddle-embed></div>
+
+### See Also
+
+<a href="#SkMatrix_rectStaysRect">rectStaysRect</a> <a href="#SkMatrix_preservesRightAngles">preservesRightAngles</a>
+
+---
+
+<a name="SkMatrix_hasPerspective"></a>
+## hasPerspective
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+bool hasPerspective() const
+</pre>
+
+Returns true if the matrix contains perspective elements. <a href="#Matrix">Matrix</a> form is:
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+| -- -- -- |
+| -- -- -- |
+| perspective-x perspective-y perspective-scale |</pre>
+
+where perspective-x or perspective-y is non-zero, or perspective-scale is
+not one. All other elements may have any value.
+
+### Return Value
+
+true if <a href="#Matrix">Matrix</a> is in most general form
+
+### Example
+
+<div><fiddle-embed name="688123908c733169bbbfaf11f41ecff6"></fiddle-embed></div>
+
+### See Also
+
+<a href="#SkMatrix_setAll">setAll</a> <a href="#SkMatrix_set9">set9</a>
+
+---
+
+<a name="SkMatrix_isSimilarity"></a>
+## isSimilarity
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+bool isSimilarity(SkScalar tol = SK_ScalarNearlyZero) const
+</pre>
+
+Returns true if <a href="#Matrix">Matrix</a> contains only translation, rotation, reflection, and
+uniform scale.
+Returns false if <a href="#Matrix">Matrix</a> contains different scales, skewing, perspective, or
+degenerate forms that collapse to a line or point.
+
+Describes that the <a href="#Matrix">Matrix</a> makes rendering with and without the matrix are
+visually alike; a transformed circle remains a circle. Mathematically, this is
+referred to as similarity of a <a href="undocumented#Euclidean">Euclidean</a> space, or a similarity transformation.
+
+Preserves right angles, keeping the arms of the angle equal lengths.
+
+### Parameters
+
+<table> <tr> <td><a name="SkMatrix_isSimilarity_tol"> <code><strong>tol </strong></code> </a></td> <td>
+to be deprecated</td>
+ </tr>
+</table>
+
+### Return Value
+
+true if <a href="#Matrix">Matrix</a> only rotates, uniformly scales, translates
+
+### Example
+
+<div><fiddle-embed name="98d60230ad633ae74d851de3a65d72d6"><div><a href="undocumented#String">String</a> is drawn four times through but only two are visible. Drawing the pair
+with <a href="#SkMatrix_isSimilarity">isSimilarity</a> false reveals the pair not visible through the matrix.</div></fiddle-embed></div>
+
+### See Also
+
+<a href="#SkMatrix_isScaleTranslate">isScaleTranslate</a> <a href="#SkMatrix_preservesRightAngles">preservesRightAngles</a> <a href="#SkMatrix_rectStaysRect">rectStaysRect</a> <a href="#SkMatrix_isFixedStepInX">isFixedStepInX</a>
+
+---
+
+<a name="SkMatrix_preservesRightAngles"></a>
+## preservesRightAngles
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+bool preservesRightAngles(SkScalar tol = SK_ScalarNearlyZero) const
+</pre>
+
+Returns true if <a href="#Matrix">Matrix</a> contains only translation, rotation, reflection, and
+scale. Scale may differ along rotated axes.
+Returns false if <a href="#Matrix">Matrix</a> skewing, perspective, or degenerate forms that collapse
+to a line or point.
+
+Preserves right angles, but not requiring that the arms of the angle
+retain equal lengths.
+
+### Parameters
+
+<table> <tr> <td><a name="SkMatrix_preservesRightAngles_tol"> <code><strong>tol </strong></code> </a></td> <td>
+to be deprecated</td>
+ </tr>
+</table>
+
+### Return Value
+
+true if <a href="#Matrix">Matrix</a> only rotates, scales, translates
+
+### Example
+
+<div><fiddle-embed name="a3d5bfebc1c3423fb983d30aaf4ac5f4"><div>Equal scale is both similar and preserves right angles.
+Unequal scale is not similar but preserves right angles.
+Skews are not similar and do not preserve right angles.</div></fiddle-embed></div>
+
+### See Also
+
+<a href="#SkMatrix_isScaleTranslate">isScaleTranslate</a> <a href="#SkMatrix_isSimilarity">isSimilarity</a> <a href="#SkMatrix_rectStaysRect">rectStaysRect</a> <a href="#SkMatrix_isFixedStepInX">isFixedStepInX</a>
+
+---
+
+## <a name="SkMatrix__anonymous"></a> Enum SkMatrix::_anonymous
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+enum {
+<a href="#SkMatrix_kMScaleX">kMScaleX</a>,
+<a href="#SkMatrix_kMSkewX">kMSkewX</a>,
+<a href="#SkMatrix_kMTransX">kMTransX</a>,
+<a href="#SkMatrix_kMSkewY">kMSkewY</a>,
+<a href="#SkMatrix_kMScaleY">kMScaleY</a>,
+<a href="#SkMatrix_kMTransY">kMTransY</a>,
+<a href="#SkMatrix_kMPersp0">kMPersp0</a>,
+<a href="#SkMatrix_kMPersp1">kMPersp1</a>,
+<a href="#SkMatrix_kMPersp2">kMPersp2</a>,
+};</pre>
+
+<a href="#Matrix">Matrix</a> organizes its values in row order. These members correspond to
+each value in <a href="#Matrix">Matrix</a>.
+
+### Constants
+
+<table>
+ <tr>
+ <td><a name="SkMatrix_kMScaleX"> <code><strong>SkMatrix::kMScaleX </strong></code> </a></td><td>0</td><td>horizontal scale factor</td>
+ </tr>
+ <tr>
+ <td><a name="SkMatrix_kMSkewX"> <code><strong>SkMatrix::kMSkewX </strong></code> </a></td><td>1</td><td>horizontal skew factor</td>
+ </tr>
+ <tr>
+ <td><a name="SkMatrix_kMTransX"> <code><strong>SkMatrix::kMTransX </strong></code> </a></td><td>2</td><td>horizontal translation</td>
+ </tr>
+ <tr>
+ <td><a name="SkMatrix_kMSkewY"> <code><strong>SkMatrix::kMSkewY </strong></code> </a></td><td>3</td><td>vertical skew factor</td>
+ </tr>
+ <tr>
+ <td><a name="SkMatrix_kMScaleY"> <code><strong>SkMatrix::kMScaleY </strong></code> </a></td><td>4</td><td>vertical scale factor</td>
+ </tr>
+ <tr>
+ <td><a name="SkMatrix_kMTransY"> <code><strong>SkMatrix::kMTransY </strong></code> </a></td><td>5</td><td>vertical translation</td>
+ </tr>
+ <tr>
+ <td><a name="SkMatrix_kMPersp0"> <code><strong>SkMatrix::kMPersp0 </strong></code> </a></td><td>6</td><td>input x perspective factor</td>
+ </tr>
+ <tr>
+ <td><a name="SkMatrix_kMPersp1"> <code><strong>SkMatrix::kMPersp1 </strong></code> </a></td><td>7</td><td>input y perspective factor</td>
+ </tr>
+ <tr>
+ <td><a name="SkMatrix_kMPersp2"> <code><strong>SkMatrix::kMPersp2 </strong></code> </a></td><td>8</td><td>perspective bias</td>
+ </tr>
+</table>
+
+### Example
+
+<div><fiddle-embed name="3bbf75f4748420810aa2586e3c8548d9"></fiddle-embed></div>
+
+### See Also
+
+<a href="#SkMatrix_get">get</a> <a href="#SkMatrix_set">set</a>
+
+
+
+## <a name="SkMatrix__anonymous_2"></a> Enum SkMatrix::_anonymous_2
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+enum {
+<a href="#SkMatrix_kAScaleX">kAScaleX</a>,
+<a href="#SkMatrix_kASkewY">kASkewY</a>,
+<a href="#SkMatrix_kASkewX">kASkewX</a>,
+<a href="#SkMatrix_kAScaleY">kAScaleY</a>,
+<a href="#SkMatrix_kATransX">kATransX</a>,
+<a href="#SkMatrix_kATransY">kATransY</a>,
+};</pre>
+
+Affine arrays are in column major order to match the matrix used by
+<a href="undocumented#PDF">PDF</a> and <a href="undocumented#XPS">XPS</a>.
+
+### Constants
+
+<table>
+ <tr>
+ <td><a name="SkMatrix_kAScaleX"> <code><strong>SkMatrix::kAScaleX </strong></code> </a></td><td>0</td><td>horizontal scale factor</td>
+ </tr>
+ <tr>
+ <td><a name="SkMatrix_kASkewY"> <code><strong>SkMatrix::kASkewY </strong></code> </a></td><td>1</td><td>vertical skew factor</td>
+ </tr>
+ <tr>
+ <td><a name="SkMatrix_kASkewX"> <code><strong>SkMatrix::kASkewX </strong></code> </a></td><td>2</td><td>horizontal skew factor</td>
+ </tr>
+ <tr>
+ <td><a name="SkMatrix_kAScaleY"> <code><strong>SkMatrix::kAScaleY </strong></code> </a></td><td>3</td><td>vertical scale factor</td>
+ </tr>
+ <tr>
+ <td><a name="SkMatrix_kATransX"> <code><strong>SkMatrix::kATransX </strong></code> </a></td><td>4</td><td>horizontal translation</td>
+ </tr>
+ <tr>
+ <td><a name="SkMatrix_kATransY"> <code><strong>SkMatrix::kATransY </strong></code> </a></td><td>5</td><td>vertical translation</td>
+ </tr>
+</table>
+
+### See Also
+
+<a href="#SkMatrix_SetAffineIdentity">SetAffineIdentity</a> <a href="#SkMatrix_asAffine">asAffine</a> <a href="#SkMatrix_setAffine">setAffine</a>
+
+
+
+<a name="SkMatrix_subscript_operator_const"></a>
+## operator[]
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+SkScalar operator[](int index) const
+</pre>
+
+Returns one matrix value. Asserts if <a href="#SkMatrix_subscript_operator_const_index">index</a> is out of range and <a href="undocumented#SK_DEBUG">SK DEBUG</a> is
+defined.
+
+### Parameters
+
+<table> <tr> <td><a name="SkMatrix_subscript_operator_const_index"> <code><strong>index </strong></code> </a></td> <td>
+one of: <a href="#SkMatrix_kMScaleX">kMScaleX</a>, <a href="#SkMatrix_kMSkewX">kMSkewX</a>, <a href="#SkMatrix_kMTransX">kMTransX</a>, <a href="#SkMatrix_kMSkewY">kMSkewY</a>, <a href="#SkMatrix_kMScaleY">kMScaleY</a>, <a href="#SkMatrix_kMTransY">kMTransY</a>,
+<a href="#SkMatrix_kMPersp0">kMPersp0</a>, <a href="#SkMatrix_kMPersp1">kMPersp1</a>, <a href="#SkMatrix_kMPersp2">kMPersp2</a></td>
+ </tr>
+</table>
+
+### Return Value
+
+value corresponding to <a href="#SkMatrix_subscript_operator_const_index">index</a>
+
+### Example
+
+<div><fiddle-embed name="e8740493abdf0c6341762db9cee56b89">
+
+#### Example Output
+
+~~~~
+matrix[SkMatrix::kMScaleX] == 42
+matrix[SkMatrix::kMScaleY] == 24
+~~~~
+
+</fiddle-embed></div>
+
+### See Also
+
+<a href="#SkMatrix_get">get</a> <a href="#SkMatrix_set">set</a>
+
+---
+
+<a name="SkMatrix_get"></a>
+## get
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+SkScalar get(int index) const
+</pre>
+
+Returns one matrix value. Asserts if <a href="#SkMatrix_get_index">index</a> is out of range and <a href="undocumented#SK_DEBUG">SK DEBUG</a> is
+defined.
+
+### Parameters
+
+<table> <tr> <td><a name="SkMatrix_get_index"> <code><strong>index </strong></code> </a></td> <td>
+one of: <a href="#SkMatrix_kMScaleX">kMScaleX</a>, <a href="#SkMatrix_kMSkewX">kMSkewX</a>, <a href="#SkMatrix_kMTransX">kMTransX</a>, <a href="#SkMatrix_kMSkewY">kMSkewY</a>, <a href="#SkMatrix_kMScaleY">kMScaleY</a>, <a href="#SkMatrix_kMTransY">kMTransY</a>,
+<a href="#SkMatrix_kMPersp0">kMPersp0</a>, <a href="#SkMatrix_kMPersp1">kMPersp1</a>, <a href="#SkMatrix_kMPersp2">kMPersp2</a></td>
+ </tr>
+</table>
+
+### Return Value
+
+value corresponding to <a href="#SkMatrix_get_index">index</a>
+
+### Example
+
+<div><fiddle-embed name="f5ed382bd04fa7d50b2398cce2fca23a">
+
+#### Example Output
+
+~~~~
+matrix.get(SkMatrix::kMSkewX) == 42
+matrix.get(SkMatrix::kMSkewY) == 24
+~~~~
+
+</fiddle-embed></div>
+
+### See Also
+
+<a href="#SkMatrix_subscript_operator_const">operator[](int index)</a> <a href="#SkMatrix_set">set</a>
+
+---
+
+<a name="SkMatrix_getScaleX"></a>
+## getScaleX
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+SkScalar getScaleX() const
+</pre>
+
+Returns scale factor multiplied by x input, contributing to x output.
+With <a href="#SkMatrix_mapPoints">mapPoints</a>, scales <a href="#Point">Points</a> along the x-axis.
+
+### Return Value
+
+horizontal scale factor
+
+### Example
+
+<div><fiddle-embed name="ab746d9be63975041ae8e50cba84dc3d">
+
+#### Example Output
+
+~~~~
+matrix.getScaleX() == 42
+~~~~
+
+</fiddle-embed></div>
+
+### See Also
+
+<a href="#SkMatrix_get">get</a> <a href="#SkMatrix_getScaleY">getScaleY</a> <a href="#SkMatrix_setScaleX">setScaleX</a> <a href="#SkMatrix_setScale">setScale</a>
+
+---
+
+<a name="SkMatrix_getScaleY"></a>
+## getScaleY
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+SkScalar getScaleY() const
+</pre>
+
+Returns scale factor multiplied by y input, contributing to y output.
+With <a href="#SkMatrix_mapPoints">mapPoints</a>, scales <a href="#Point">Points</a> along the y-axis.
+
+### Return Value
+
+vertical scale factor
+
+### Example
+
+<div><fiddle-embed name="708b1a548a2f8661b2ab570782fbc751">
+
+#### Example Output
+
+~~~~
+matrix.getScaleY() == 24
+~~~~
+
+</fiddle-embed></div>
+
+### See Also
+
+<a href="#SkMatrix_get">get</a> <a href="#SkMatrix_getScaleX">getScaleX</a> <a href="#SkMatrix_setScaleY">setScaleY</a> <a href="#SkMatrix_setScale">setScale</a>
+
+---
+
+<a name="SkMatrix_getSkewY"></a>
+## getSkewY
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+SkScalar getSkewY() const
+</pre>
+
+Returns scale factor multiplied by x input, contributing to y output.
+With <a href="#SkMatrix_mapPoints">mapPoints</a>, skews <a href="#Point">Points</a> along the y-axis.
+Skew x and y together can rotate <a href="#Point">Points</a>.
+
+### Return Value
+
+vertical skew factor
+
+### Example
+
+<div><fiddle-embed name="6be5704506d029ffc91ba03b1d3e674b">
+
+#### Example Output
+
+~~~~
+matrix.getSkewY() == 24
+~~~~
+
+</fiddle-embed></div>
+
+### See Also
+
+<a href="#SkMatrix_get">get</a> <a href="#SkMatrix_getSkewX">getSkewX</a> <a href="#SkMatrix_setSkewY">setSkewY</a> <a href="#SkMatrix_setSkew">setSkew</a>
+
+---
+
+<a name="SkMatrix_getSkewX"></a>
+## getSkewX
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+SkScalar getSkewX() const
+</pre>
+
+Returns scale factor multiplied by y input, contributing to x output.
+With <a href="#SkMatrix_mapPoints">mapPoints</a>, skews <a href="#Point">Points</a> along the x-axis.
+Skew x and y together can rotate <a href="#Point">Points</a>.
+
+### Return Value
+
+horizontal scale factor
+
+### Example
+
+<div><fiddle-embed name="df3a5d3c688e7597eae1e4e07bf91ae6">
+
+#### Example Output
+
+~~~~
+matrix.getSkewX() == 42
+~~~~
+
+</fiddle-embed></div>
+
+### See Also
+
+<a href="#SkMatrix_get">get</a> <a href="#SkMatrix_getSkewY">getSkewY</a> <a href="#SkMatrix_setSkewX">setSkewX</a> <a href="#SkMatrix_setSkew">setSkew</a>
+
+---
+
+<a name="SkMatrix_getTranslateX"></a>
+## getTranslateX
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+SkScalar getTranslateX() const
+</pre>
+
+Returns translation contributing to x output.
+With <a href="#SkMatrix_mapPoints">mapPoints</a>, moves <a href="#Point">Points</a> along the x-axis.
+
+### Return Value
+
+horizontal translation factor
+
+### Example
+
+<div><fiddle-embed name="6236f7f2b91aff977a66ba2ee2558ca4">
+
+#### Example Output
+
+~~~~
+matrix.getTranslateX() == 42
+~~~~
+
+</fiddle-embed></div>
+
+### See Also
+
+<a href="#SkMatrix_get">get</a> <a href="#SkMatrix_getTranslateY">getTranslateY</a> <a href="#SkMatrix_setTranslateX">setTranslateX</a> <a href="#SkMatrix_setTranslate">setTranslate</a>
+
+---
+
+<a name="SkMatrix_getTranslateY"></a>
+## getTranslateY
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+SkScalar getTranslateY() const
+</pre>
+
+Returns translation contributing to y output.
+With <a href="#SkMatrix_mapPoints">mapPoints</a>, moves <a href="#Point">Points</a> along the y-axis.
+
+### Return Value
+
+vertical translation factor
+
+### Example
+
+<div><fiddle-embed name="08464e32d22421d2b254c71a84545ef5">
+
+#### Example Output
+
+~~~~
+matrix.getTranslateY() == 24
+~~~~
+
+</fiddle-embed></div>
+
+### See Also
+
+<a href="#SkMatrix_get">get</a> <a href="#SkMatrix_getTranslateX">getTranslateX</a> <a href="#SkMatrix_setTranslateY">setTranslateY</a> <a href="#SkMatrix_setTranslate">setTranslate</a>
+
+---
+
+<a name="SkMatrix_getPerspX"></a>
+## getPerspX
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+SkScalar getPerspX() const
+</pre>
+
+Returns factor scaling input x relative to input y.
+
+### Return Value
+
+input x perspective factor
+
+### Example
+
+<div><fiddle-embed name="a0f5bf4b55e8c33bfda29bf67e34306f"></fiddle-embed></div>
+
+### See Also
+
+<a href="#SkMatrix_kMPersp0">kMPersp0</a> <a href="#SkMatrix_getPerspY">getPerspY</a>
+
+---
+
+<a name="SkMatrix_getPerspY"></a>
+## getPerspY
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+SkScalar getPerspY() const
+</pre>
+
+Returns factor scaling input y relative to input x.
+
+### Return Value
+
+input y perspective factor
+
+### Example
+
+<div><fiddle-embed name="424a00a73675dbd99ad20feb0267442b"></fiddle-embed></div>
+
+### See Also
+
+<a href="#SkMatrix_kMPersp1">kMPersp1</a> <a href="#SkMatrix_getPerspX">getPerspX</a>
+
+---
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+SkScalar& operator[](int index)
+</pre>
+
+Returns writable <a href="#Matrix">Matrix</a> value. Asserts if <a href="#SkMatrix_subscript_operator_index">index</a> is out of range and <a href="undocumented#SK_DEBUG">SK DEBUG</a> is
+defined. Clears internal cache anticipating that caller will change <a href="#Matrix">Matrix</a> value.
+
+Next call to read <a href="#Matrix">Matrix</a> state may recompute cache; subsequent writes to <a href="#Matrix">Matrix</a>
+value must be followed by <a href="#SkMatrix_dirtyMatrixTypeCache">dirtyMatrixTypeCache</a>.
+
+### Parameters
+
+<table> <tr> <td><a name="SkMatrix_subscript_operator_index"> <code><strong>index </strong></code> </a></td> <td>
+one of: <a href="#SkMatrix_kMScaleX">kMScaleX</a>, <a href="#SkMatrix_kMSkewX">kMSkewX</a>, <a href="#SkMatrix_kMTransX">kMTransX</a>, <a href="#SkMatrix_kMSkewY">kMSkewY</a>, <a href="#SkMatrix_kMScaleY">kMScaleY</a>, <a href="#SkMatrix_kMTransY">kMTransY</a>,
+<a href="#SkMatrix_kMPersp0">kMPersp0</a>, <a href="#SkMatrix_kMPersp1">kMPersp1</a>, <a href="#SkMatrix_kMPersp2">kMPersp2</a></td>
+ </tr>
+</table>
+
+### Return Value
+
+writable value corresponding to <a href="#SkMatrix_subscript_operator_index">index</a>
+
+### Example
+
+<div><fiddle-embed name="f4365ef332f51f7fd25040e0771ba9a2">
+
+#### Example Output
+
+~~~~
+with identity matrix: x = 24
+after skew x mod: x = 24
+after 2nd skew x mod: x = 24
+after dirty cache: x = 66
+~~~~
+
+</fiddle-embed></div>
+
+### See Also
+
+<a href="#SkMatrix_get">get</a> <a href="#SkMatrix_dirtyMatrixTypeCache">dirtyMatrixTypeCache</a> <a href="#SkMatrix_set">set</a>
+
+---
+
+<a name="SkMatrix_set"></a>
+## set
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+void set(int index, SkScalar value)
+</pre>
+
+Sets <a href="#Matrix">Matrix</a> <a href="#SkMatrix_set_value">value</a>. Asserts if <a href="#SkMatrix_set_index">index</a> is out of range and <a href="undocumented#SK_DEBUG">SK DEBUG</a> is
+defined. Safer than operator[]; internal cache is always maintained.
+
+### Parameters
+
+<table> <tr> <td><a name="SkMatrix_set_index"> <code><strong>index </strong></code> </a></td> <td>
+one of: <a href="#SkMatrix_kMScaleX">kMScaleX</a>, <a href="#SkMatrix_kMSkewX">kMSkewX</a>, <a href="#SkMatrix_kMTransX">kMTransX</a>, <a href="#SkMatrix_kMSkewY">kMSkewY</a>, <a href="#SkMatrix_kMScaleY">kMScaleY</a>, <a href="#SkMatrix_kMTransY">kMTransY</a>,
+<a href="#SkMatrix_kMPersp0">kMPersp0</a>, <a href="#SkMatrix_kMPersp1">kMPersp1</a>, <a href="#SkMatrix_kMPersp2">kMPersp2</a></td>
+ </tr> <tr> <td><a name="SkMatrix_set_value"> <code><strong>value </strong></code> </a></td> <td>
+<a href="#Scalar">Scalar</a> to store in <a href="#Matrix">Matrix</a></td>
+ </tr>
+</table>
+
+### Example
+
+<div><fiddle-embed name="1d400a92ca826cc89bcb88ea051f28c8">
+
+#### Example Output
+
+~~~~
+with identity matrix: x = 24
+after skew x mod: x = 24
+after 2nd skew x mod: x = 66
+~~~~
+
+</fiddle-embed></div>
+
+### See Also
+
+operator[] <a href="#SkMatrix_get">get</a>
+
+---
+
+<a name="SkMatrix_setScaleX"></a>
+## setScaleX
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+void setScaleX(SkScalar v)
+</pre>
+
+Sets horizontal scale factor.
+
+### Parameters
+
+<table> <tr> <td><a name="SkMatrix_setScaleX_v"> <code><strong>v </strong></code> </a></td> <td>
+horizontal scale factor to store</td>
+ </tr>
+</table>
+
+### Example
+
+<div><fiddle-embed name="a39dfed98c3c3c3a56be9ad59fe4e21e"></fiddle-embed></div>
+
+### See Also
+
+<a href="#SkMatrix_set">set</a> <a href="#SkMatrix_setScale">setScale</a> <a href="#SkMatrix_setScaleY">setScaleY</a>
+
+---
+
+<a name="SkMatrix_setScaleY"></a>
+## setScaleY
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+void setScaleY(SkScalar v)
+</pre>
+
+Sets vertical scale factor.
+
+### Parameters
+
+<table> <tr> <td><a name="SkMatrix_setScaleY_v"> <code><strong>v </strong></code> </a></td> <td>
+vertical scale factor to store</td>
+ </tr>
+</table>
+
+### Example
+
+<div><fiddle-embed name="f040c6dd85a02e94eaca00d5c2832604"></fiddle-embed></div>
+
+### See Also
+
+<a href="#SkMatrix_set">set</a> <a href="#SkMatrix_setScale">setScale</a> <a href="#SkMatrix_setScaleX">setScaleX</a>
+
+---
+
+<a name="SkMatrix_setSkewY"></a>
+## setSkewY
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+void setSkewY(SkScalar v)
+</pre>
+
+Sets vertical skew factor.
+
+### Parameters
+
+<table> <tr> <td><a name="SkMatrix_setSkewY_v"> <code><strong>v </strong></code> </a></td> <td>
+vertical skew factor to store</td>
+ </tr>
+</table>
+
+### Example
+
+<div><fiddle-embed name="b418d15df9829aefcc6aca93a37428bb"></fiddle-embed></div>
+
+### See Also
+
+<a href="#SkMatrix_set">set</a> <a href="#SkMatrix_setSkew">setSkew</a> <a href="#SkMatrix_setSkewX">setSkewX</a>
+
+---
+
+<a name="SkMatrix_setSkewX"></a>
+## setSkewX
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+void setSkewX(SkScalar v)
+</pre>
+
+Sets horizontal skew factor.
+
+### Parameters
+
+<table> <tr> <td><a name="SkMatrix_setSkewX_v"> <code><strong>v </strong></code> </a></td> <td>
+horizontal skew factor to store</td>
+ </tr>
+</table>
+
+### Example
+
+<div><fiddle-embed name="c7177a6fbc1545be95a5ebca87e0cd0d"></fiddle-embed></div>
+
+### See Also
+
+<a href="#SkMatrix_set">set</a> <a href="#SkMatrix_setSkew">setSkew</a> <a href="#SkMatrix_setSkewX">setSkewX</a>
+
+---
+
+<a name="SkMatrix_setTranslateX"></a>
+## setTranslateX
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+void setTranslateX(SkScalar v)
+</pre>
+
+Sets horizontal translation.
+
+### Parameters
+
+<table> <tr> <td><a name="SkMatrix_setTranslateX_v"> <code><strong>v </strong></code> </a></td> <td>
+horizontal translation to store</td>
+ </tr>
+</table>
+
+### Example
+
+<div><fiddle-embed name="a18bc2e3607ac3a8e438bcb61fb13130"></fiddle-embed></div>
+
+### See Also
+
+<a href="#SkMatrix_set">set</a> <a href="#SkMatrix_setTranslate">setTranslate</a> <a href="#SkMatrix_setTranslateY">setTranslateY</a>
+
+---
+
+<a name="SkMatrix_setTranslateY"></a>
+## setTranslateY
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+void setTranslateY(SkScalar v)
+</pre>
+
+Sets vertical translation.
+
+### Parameters
+
+<table> <tr> <td><a name="SkMatrix_setTranslateY_v"> <code><strong>v </strong></code> </a></td> <td>
+vertical translation to store</td>
+ </tr>
+</table>
+
+### Example
+
+<div><fiddle-embed name="34e3c70a72b836abf7f4858d35eecc98"></fiddle-embed></div>
+
+### See Also
+
+<a href="#SkMatrix_set">set</a> <a href="#SkMatrix_setTranslate">setTranslate</a> <a href="#SkMatrix_setTranslateX">setTranslateX</a>
+
+---
+
+<a name="SkMatrix_setPerspX"></a>
+## setPerspX
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+void setPerspX(SkScalar v)
+</pre>
+
+Sets input x perspective factor, which causes <a href="#SkMatrix_mapXY">mapXY</a> to vary input x inversely
+proportional to input y.
+
+### Parameters
+
+<table> <tr> <td><a name="SkMatrix_setPerspX_v"> <code><strong>v </strong></code> </a></td> <td>
+perspective factor</td>
+ </tr>
+</table>
+
+### Example
+
+<div><fiddle-embed name="830a9e4e4bb93d25afd83b2fea63929e"></fiddle-embed></div>
+
+### See Also
+
+<a href="#SkMatrix_getPerspX">getPerspX</a> <a href="#SkMatrix_set">set</a> <a href="#SkMatrix_setAll">setAll</a> <a href="#SkMatrix_set9">set9</a>
+
+---
+
+<a name="SkMatrix_setPerspY"></a>
+## setPerspY
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+void setPerspY(SkScalar v)
+</pre>
+
+Sets input y perspective factor, which causes <a href="#SkMatrix_mapXY">mapXY</a> to vary input y inversely
+proportional to input x.
+
+### Parameters
+
+<table> <tr> <td><a name="SkMatrix_setPerspY_v"> <code><strong>v </strong></code> </a></td> <td>
+perspective factor</td>
+ </tr>
+</table>
+
+### Example
+
+<div><fiddle-embed name="aeb258b7922c1a11b698b00f562182ec"></fiddle-embed></div>
+
+### See Also
+
+<a href="#SkMatrix_getPerspY">getPerspY</a> <a href="#SkMatrix_set">set</a> <a href="#SkMatrix_setAll">setAll</a> <a href="#SkMatrix_set9">set9</a>
+
+---
+
+<a name="SkMatrix_setAll"></a>
+## setAll
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+void setAll(SkScalar scaleX, SkScalar skewX, SkScalar transX, SkScalar skewY,
+ SkScalar scaleY, SkScalar transY, SkScalar persp0, SkScalar persp1,
+ SkScalar persp2)
+</pre>
+
+Sets all values from parameters. Sets matrix to:
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+| scaleX skewX transX |
+| skewY scaleY transY |
+| persp0 persp1 persp2 |</pre>
+
+### Parameters
+
+<table> <tr> <td><a name="SkMatrix_setAll_scaleX"> <code><strong>scaleX </strong></code> </a></td> <td>
+horizontal scale factor to store</td>
+ </tr> <tr> <td><a name="SkMatrix_setAll_skewX"> <code><strong>skewX </strong></code> </a></td> <td>
+horizontal skew factor to store</td>
+ </tr> <tr> <td><a name="SkMatrix_setAll_transX"> <code><strong>transX </strong></code> </a></td> <td>
+horizontal translation to store</td>
+ </tr> <tr> <td><a name="SkMatrix_setAll_skewY"> <code><strong>skewY </strong></code> </a></td> <td>
+vertical skew factor to store</td>
+ </tr> <tr> <td><a name="SkMatrix_setAll_scaleY"> <code><strong>scaleY </strong></code> </a></td> <td>
+vertical scale factor to store</td>
+ </tr> <tr> <td><a name="SkMatrix_setAll_transY"> <code><strong>transY </strong></code> </a></td> <td>
+vertical translation to store</td>
+ </tr> <tr> <td><a name="SkMatrix_setAll_persp0"> <code><strong>persp0 </strong></code> </a></td> <td>
+input x perspective factor to store</td>
+ </tr> <tr> <td><a name="SkMatrix_setAll_persp1"> <code><strong>persp1 </strong></code> </a></td> <td>
+input y perspective factor to store</td>
+ </tr> <tr> <td><a name="SkMatrix_setAll_persp2"> <code><strong>persp2 </strong></code> </a></td> <td>
+perspective scale factor to store</td>
+ </tr>
+</table>
+
+### Example
+
+<div><fiddle-embed name="c51d81b637b58da30fb9ae2d68877167"></fiddle-embed></div>
+
+### See Also
+
+<a href="#SkMatrix_set9">set9</a>
+
+---
+
+<a name="SkMatrix_get9"></a>
+## get9
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+void get9(SkScalar buffer[9]) const
+</pre>
+
+Copies nine <a href="#Scalar">Scalar</a> values contained by <a href="#Matrix">Matrix</a> into <a href="#SkMatrix_get9_buffer">buffer</a>, in member value
+ascending order: <a href="#SkMatrix_kMScaleX">kMScaleX</a>, <a href="#SkMatrix_kMSkewX">kMSkewX</a>, <a href="#SkMatrix_kMTransX">kMTransX</a>, <a href="#SkMatrix_kMSkewY">kMSkewY</a>, <a href="#SkMatrix_kMScaleY">kMScaleY</a>, <a href="#SkMatrix_kMTransY">kMTransY</a>,
+<a href="#SkMatrix_kMPersp0">kMPersp0</a>, <a href="#SkMatrix_kMPersp1">kMPersp1</a>, <a href="#SkMatrix_kMPersp2">kMPersp2</a>.
+
+### Parameters
+
+<table> <tr> <td><a name="SkMatrix_get9_buffer"> <code><strong>buffer </strong></code> </a></td> <td>
+storage for nine <a href="#Scalar">Scalar</a> values</td>
+ </tr>
+</table>
+
+### Example
+
+<div><fiddle-embed name="df509d73b47cb98b0475e4465db7b246">
+
+#### Example Output
+
+~~~~
+{4, 0, 3},
+{0, 5, 4},
+{0, 0, 1}
+~~~~
+
+</fiddle-embed></div>
+
+### See Also
+
+<a href="#SkMatrix_set9">set9</a>
+
+---
+
+<a name="SkMatrix_set9"></a>
+## set9
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+void set9(const SkScalar buffer[9])
+</pre>
+
+Sets <a href="#Matrix">Matrix</a> to nine <a href="#Scalar">Scalar</a> values in <a href="#SkMatrix_set9_buffer">buffer</a>, in member value ascending order:
+<a href="#SkMatrix_kMScaleX">kMScaleX</a>, <a href="#SkMatrix_kMSkewX">kMSkewX</a>, <a href="#SkMatrix_kMTransX">kMTransX</a>, <a href="#SkMatrix_kMSkewY">kMSkewY</a>, <a href="#SkMatrix_kMScaleY">kMScaleY</a>, <a href="#SkMatrix_kMTransY">kMTransY</a>, <a href="#SkMatrix_kMPersp0">kMPersp0</a>, <a href="#SkMatrix_kMPersp1">kMPersp1</a>,
+<a href="#SkMatrix_kMPersp2">kMPersp2</a>.
+
+Sets matrix to:
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+| buffer[0] buffer[1] buffer[2] |
+| buffer[3] buffer[4] buffer[5] |
+| buffer[6] buffer[7] buffer[8] |</pre>
+
+In the future, <a href="#SkMatrix_set9">set9</a> followed by <a href="#SkMatrix_get9">get9</a> may not return the same values. Since <a href="#Matrix">Matrix</a>
+maps non-homogeneous coordinates, scaling all nine values produces an equivalent
+transformation, possibly improving precision.
+
+### Parameters
+
+<table> <tr> <td><a name="SkMatrix_set9_buffer"> <code><strong>buffer </strong></code> </a></td> <td>
+nine <a href="#Scalar">Scalar</a> values</td>
+ </tr>
+</table>
+
+### Example
+
+<div><fiddle-embed name="ec5de0d23e5fe28ba7628625d1402e85"></fiddle-embed></div>
+
+### See Also
+
+<a href="#SkMatrix_setAll">setAll</a> <a href="#SkMatrix_get9">get9</a>
+
+---
+
+<a name="SkMatrix_reset"></a>
+## reset
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+void reset()
+</pre>
+
+Sets <a href="#Matrix">Matrix</a> to identity; which has no effect on mapped <a href="#Point">Points</a>. Sets <a href="#Matrix">Matrix</a> to:
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+| 1 0 0 |
+| 0 1 0 |
+| 0 0 1 |</pre>
+
+Also called <a href="#SkMatrix_setIdentity">setIdentity</a>; use the one that provides better inline
+documentation.
+
+### Example
+
+<div><fiddle-embed name="ca94f7922bc37ef03bbc51ad70536fcf">
+
+#### Example Output
+
+~~~~
+m.isIdentity(): true
+~~~~
+
+</fiddle-embed></div>
+
+### See Also
+
+<a href="#SkMatrix_isIdentity">isIdentity</a> <a href="#SkMatrix_setIdentity">setIdentity</a>
+
+---
+
+<a name="SkMatrix_setIdentity"></a>
+## setIdentity
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+void setIdentity()
+</pre>
+
+Sets <a href="#Matrix">Matrix</a> to identity; which has no effect on mapped <a href="#Point">Points</a>. Sets <a href="#Matrix">Matrix</a> to:
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+| 1 0 0 |
+| 0 1 0 |
+| 0 0 1 |</pre>
+
+Also called <a href="#SkMatrix_reset">reset</a>; use the one that provides better inline
+documentation.
+
+### Example
+
+<div><fiddle-embed name="3979c865bb482e6ef1fafc71e56bbb91">
+
+#### Example Output
+
+~~~~
+m.isIdentity(): true
+~~~~
+
+</fiddle-embed></div>
+
+### See Also
+
+<a href="#SkMatrix_isIdentity">isIdentity</a> <a href="#SkMatrix_reset">reset</a>
+
+---
+
+<a name="SkMatrix_setTranslate"></a>
+## setTranslate
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+void setTranslate(SkScalar dx, SkScalar dy)
+</pre>
+
+Sets <a href="#Matrix">Matrix</a> to translate by (<a href="#SkMatrix_setTranslate_dx">dx</a>, <a href="#SkMatrix_setTranslate_dy">dy</a>).
+
+### Parameters
+
+<table> <tr> <td><a name="SkMatrix_setTranslate_dx"> <code><strong>dx </strong></code> </a></td> <td>
+horizontal translation</td>
+ </tr> <tr> <td><a name="SkMatrix_setTranslate_dy"> <code><strong>dy </strong></code> </a></td> <td>
+vertical translation</td>
+ </tr>
+</table>
+
+### Example
+
+<div><fiddle-embed name="63ca62985741b1bccb5e8b9cf734874e"></fiddle-embed></div>
+
+### See Also
+
+<a href="#SkMatrix_setTranslateX">setTranslateX</a> <a href="#SkMatrix_setTranslateY">setTranslateY</a>
+
+---
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+void setTranslate(const SkVector& v)
+</pre>
+
+Sets <a href="#Matrix">Matrix</a> to translate by (<a href="#SkMatrix_setTranslate_2_v">v</a>.fX, <a href="#SkMatrix_setTranslate_2_v">v</a>.fY).
+
+### Parameters
+
+<table> <tr> <td><a name="SkMatrix_setTranslate_2_v"> <code><strong>v </strong></code> </a></td> <td>
+<a href="undocumented#Vector">Vector</a> containing horizontal and vertical translation</td>
+ </tr>
+</table>
+
+### Example
+
+<div><fiddle-embed name="ccfc734aff2ddea0b097c83f5621de5e"></fiddle-embed></div>
+
+### See Also
+
+<a href="#SkMatrix_setTranslateX">setTranslateX</a> <a href="#SkMatrix_setTranslateY">setTranslateY</a> <a href="#SkMatrix_MakeTrans">MakeTrans</a>
+
+---
+
+<a name="SkMatrix_setScale"></a>
+## setScale
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+void setScale(SkScalar sx, SkScalar sy, SkScalar px, SkScalar py)
+</pre>
+
+Sets <a href="#Matrix">Matrix</a> to scale by <a href="#SkMatrix_setScale_sx">sx</a> and <a href="#SkMatrix_setScale_sy">sy</a>, about a pivot point at (<a href="#SkMatrix_setScale_px">px</a>, <a href="#SkMatrix_setScale_py">py</a>).
+The pivot point is unchanged when mapped with <a href="#Matrix">Matrix</a>.
+
+### Parameters
+
+<table> <tr> <td><a name="SkMatrix_setScale_sx"> <code><strong>sx </strong></code> </a></td> <td>
+horizontal scale factor</td>
+ </tr> <tr> <td><a name="SkMatrix_setScale_sy"> <code><strong>sy </strong></code> </a></td> <td>
+vertical scale factor</td>
+ </tr> <tr> <td><a name="SkMatrix_setScale_px"> <code><strong>px </strong></code> </a></td> <td>
+pivot x</td>
+ </tr> <tr> <td><a name="SkMatrix_setScale_py"> <code><strong>py </strong></code> </a></td> <td>
+pivot y</td>
+ </tr>
+</table>
+
+### Example
+
+<div><fiddle-embed name="397db8da89bc92e7c576ad013d64ed24"></fiddle-embed></div>
+
+### See Also
+
+<a href="#SkMatrix_setScaleX">setScaleX</a> <a href="#SkMatrix_setScaleY">setScaleY</a> <a href="#SkMatrix_MakeScale">MakeScale</a> <a href="#SkMatrix_preScale">preScale</a> <a href="#SkMatrix_postScale">postScale</a>
+
+---
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+void setScale(SkScalar sx, SkScalar sy)
+</pre>
+
+Sets <a href="#Matrix">Matrix</a> to scale by <a href="#SkMatrix_setScale_2_sx">sx</a> and <a href="#SkMatrix_setScale_2_sy">sy</a> about at pivot point at (0, 0).
+
+### Parameters
+
+<table> <tr> <td><a name="SkMatrix_setScale_2_sx"> <code><strong>sx </strong></code> </a></td> <td>
+horizontal scale factor</td>
+ </tr> <tr> <td><a name="SkMatrix_setScale_2_sy"> <code><strong>sy </strong></code> </a></td> <td>
+vertical scale factor</td>
+ </tr>
+</table>
+
+### Example
+
+<div><fiddle-embed name="94a9ec11b994580dca14aa2159a796a9"></fiddle-embed></div>
+
+### See Also
+
+<a href="#SkMatrix_setScaleX">setScaleX</a> <a href="#SkMatrix_setScaleY">setScaleY</a> <a href="#SkMatrix_MakeScale">MakeScale</a> <a href="#SkMatrix_preScale">preScale</a> <a href="#SkMatrix_postScale">postScale</a>
+
+---
+
+<a name="SkMatrix_setRotate"></a>
+## setRotate
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+void setRotate(SkScalar degrees, SkScalar px, SkScalar py)
+</pre>
+
+Sets <a href="#Matrix">Matrix</a> to rotate by <a href="#SkMatrix_setRotate_degrees">degrees</a> about a pivot point at (<a href="#SkMatrix_setRotate_px">px</a>, <a href="#SkMatrix_setRotate_py">py</a>).
+The pivot point is unchanged when mapped with <a href="#Matrix">Matrix</a>.
+
+Positive <a href="#SkMatrix_setRotate_degrees">degrees</a> rotates clockwise.
+
+### Parameters
+
+<table> <tr> <td><a name="SkMatrix_setRotate_degrees"> <code><strong>degrees </strong></code> </a></td> <td>
+angle of axes relative to upright axes</td>
+ </tr> <tr> <td><a name="SkMatrix_setRotate_px"> <code><strong>px </strong></code> </a></td> <td>
+pivot x</td>
+ </tr> <tr> <td><a name="SkMatrix_setRotate_py"> <code><strong>py </strong></code> </a></td> <td>
+pivot y</td>
+ </tr>
+</table>
+
+### Example
+
+<div><fiddle-embed name="8c28db3add9cd0177225088f6df6bbb5"></fiddle-embed></div>
+
+### See Also
+
+<a href="#SkMatrix_setSinCos">setSinCos</a> <a href="#SkMatrix_preRotate">preRotate</a> <a href="#SkMatrix_postRotate">postRotate</a>
+
+---
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+void setRotate(SkScalar degrees)
+</pre>
+
+Sets <a href="#Matrix">Matrix</a> to rotate by <a href="#SkMatrix_setRotate_2_degrees">degrees</a> about a pivot point at (0, 0).
+Positive <a href="#SkMatrix_setRotate_2_degrees">degrees</a> rotates clockwise.
+
+### Parameters
+
+<table> <tr> <td><a name="SkMatrix_setRotate_2_degrees"> <code><strong>degrees </strong></code> </a></td> <td>
+angle of axes relative to upright axes</td>
+ </tr>
+</table>
+
+### Example
+
+<div><fiddle-embed name="93efb9d191bf1b9710c173513e014d6c"></fiddle-embed></div>
+
+### See Also
+
+<a href="#SkMatrix_setSinCos">setSinCos</a> <a href="#SkMatrix_preRotate">preRotate</a> <a href="#SkMatrix_postRotate">postRotate</a>
+
+---
+
+<a name="SkMatrix_setSinCos"></a>
+## setSinCos
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+void setSinCos(SkScalar sinValue, SkScalar cosValue, SkScalar px, SkScalar py)
+</pre>
+
+Sets <a href="#Matrix">Matrix</a> to rotate by <a href="#SkMatrix_setSinCos_sinValue">sinValue</a> and <a href="#SkMatrix_setSinCos_cosValue">cosValue</a>, about a pivot point at (<a href="#SkMatrix_setSinCos_px">px</a>, <a href="#SkMatrix_setSinCos_py">py</a>).
+The pivot point is unchanged when mapped with <a href="#Matrix">Matrix</a>.
+
+<a href="undocumented#Vector">Vector</a> (<a href="#SkMatrix_setSinCos_sinValue">sinValue</a>, <a href="#SkMatrix_setSinCos_cosValue">cosValue</a>) describes the angle of rotation relative to (0, 1).
+<a href="undocumented#Vector">Vector</a> length specifies scale.
+
+### Parameters
+
+<table> <tr> <td><a name="SkMatrix_setSinCos_sinValue"> <code><strong>sinValue </strong></code> </a></td> <td>
+rotation vector x component</td>
+ </tr> <tr> <td><a name="SkMatrix_setSinCos_cosValue"> <code><strong>cosValue </strong></code> </a></td> <td>
+rotation vector y component</td>
+ </tr> <tr> <td><a name="SkMatrix_setSinCos_px"> <code><strong>px </strong></code> </a></td> <td>
+pivot x</td>
+ </tr> <tr> <td><a name="SkMatrix_setSinCos_py"> <code><strong>py </strong></code> </a></td> <td>
+pivot y</td>
+ </tr>
+</table>
+
+### Example
+
+<div><fiddle-embed name="187e1d9228e2e4341ef820bd77b6fda9"></fiddle-embed></div>
+
+### See Also
+
+<a href="#SkMatrix_setRotate">setRotate</a> <a href="#SkMatrix_setScale">setScale</a> <a href="#SkMatrix_setRSXform">setRSXform</a>
+
+---
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+void setSinCos(SkScalar sinValue, SkScalar cosValue)
+</pre>
+
+Sets <a href="#Matrix">Matrix</a> to rotate by <a href="#SkMatrix_setSinCos_2_sinValue">sinValue</a> and <a href="#SkMatrix_setSinCos_2_cosValue">cosValue</a>, about a pivot point at (0, 0).
+
+<a href="undocumented#Vector">Vector</a> (<a href="#SkMatrix_setSinCos_2_sinValue">sinValue</a>, <a href="#SkMatrix_setSinCos_2_cosValue">cosValue</a>) describes the angle of rotation relative to (0, 1).
+<a href="undocumented#Vector">Vector</a> length specifies scale.
+
+### Parameters
+
+<table> <tr> <td><a name="SkMatrix_setSinCos_2_sinValue"> <code><strong>sinValue </strong></code> </a></td> <td>
+rotation vector x component</td>
+ </tr> <tr> <td><a name="SkMatrix_setSinCos_2_cosValue"> <code><strong>cosValue </strong></code> </a></td> <td>
+rotation vector y component</td>
+ </tr>
+</table>
+
+### Example
+
+<div><fiddle-embed name="e37a94a53c959951b059fcd624639ef6"><div><a href="SkCanvas_Reference#Canvas">Canvas</a> needs offset after applying <a href="#Matrix">Matrix</a> to pivot about <a href="SkRect_Reference#Rect">Rect</a> center.</div></fiddle-embed></div>
+
+### See Also
+
+<a href="#SkMatrix_setRotate">setRotate</a> <a href="#SkMatrix_setScale">setScale</a> <a href="#SkMatrix_setRSXform">setRSXform</a>
+
+---
+
+<a name="SkMatrix_setRSXform"></a>
+## setRSXform
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+SkMatrix& setRSXform(const SkRSXform& rsxForm)
+</pre>
+
+Sets <a href="#Matrix">Matrix</a> to rotate, scale, and translate using a compressed matrix form.
+
+<a href="undocumented#Vector">Vector</a> (<a href="#SkMatrix_setRSXform_rsxForm">rsxForm</a>.fSSin, <a href="#SkMatrix_setRSXform_rsxForm">rsxForm</a>.fSCos) describes the angle of rotation relative
+to (0, 1). <a href="undocumented#Vector">Vector</a> length specifies scale. Mapped point is rotated and scaled
+by <a href="undocumented#Vector">Vector</a>, then translated by (<a href="#SkMatrix_setRSXform_rsxForm">rsxForm</a>.fTx, <a href="#SkMatrix_setRSXform_rsxForm">rsxForm</a>.fTy).
+
+### Parameters
+
+<table> <tr> <td><a name="SkMatrix_setRSXform_rsxForm"> <code><strong>rsxForm </strong></code> </a></td> <td>
+compressed <a href="undocumented#RSXform">RSXform</a> matrix</td>
+ </tr>
+</table>
+
+### Return Value
+
+reference to <a href="#Matrix">Matrix</a>
+
+### Example
+
+<div><fiddle-embed name="c3f5faddca466f78278b32b88fd5f5eb"><div><a href="SkCanvas_Reference#Canvas">Canvas</a> needs offset after applying <a href="#Matrix">Matrix</a> to pivot about <a href="SkRect_Reference#Rect">Rect</a> center.</div></fiddle-embed></div>
+
+### See Also
+
+<a href="#SkMatrix_setSinCos">setSinCos</a> <a href="#SkMatrix_setScale">setScale</a> <a href="#SkMatrix_setTranslate">setTranslate</a>
+
+---
+
+<a name="SkMatrix_setSkew"></a>
+## setSkew
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+void setSkew(SkScalar kx, SkScalar ky, SkScalar px, SkScalar py)
+</pre>
+
+Sets <a href="#Matrix">Matrix</a> to skew by <a href="#SkMatrix_setSkew_kx">kx</a> and <a href="#SkMatrix_setSkew_ky">ky</a>, about a pivot point at (<a href="#SkMatrix_setSkew_px">px</a>, <a href="#SkMatrix_setSkew_py">py</a>).
+The pivot point is unchanged when mapped with <a href="#Matrix">Matrix</a>.
+
+### Parameters
+
+<table> <tr> <td><a name="SkMatrix_setSkew_kx"> <code><strong>kx </strong></code> </a></td> <td>
+horizontal skew factor</td>
+ </tr> <tr> <td><a name="SkMatrix_setSkew_ky"> <code><strong>ky </strong></code> </a></td> <td>
+vertical skew factor</td>
+ </tr> <tr> <td><a name="SkMatrix_setSkew_px"> <code><strong>px </strong></code> </a></td> <td>
+pivot x</td>
+ </tr> <tr> <td><a name="SkMatrix_setSkew_py"> <code><strong>py </strong></code> </a></td> <td>
+pivot y</td>
+ </tr>
+</table>
+
+### Example
+
+<div><fiddle-embed name="55e0431adc6c5b1987ebb8123cc10342"></fiddle-embed></div>
+
+### See Also
+
+<a href="#SkMatrix_setSkewX">setSkewX</a> <a href="#SkMatrix_setSkewY">setSkewY</a> <a href="#SkMatrix_preSkew">preSkew</a> <a href="#SkMatrix_postSkew">postSkew</a>
+
+---
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+void setSkew(SkScalar kx, SkScalar ky)
+</pre>
+
+Sets <a href="#Matrix">Matrix</a> to skew by <a href="#SkMatrix_setSkew_2_kx">kx</a> and <a href="#SkMatrix_setSkew_2_ky">ky</a>, about a pivot point at (0, 0).
+
+### Parameters
+
+<table> <tr> <td><a name="SkMatrix_setSkew_2_kx"> <code><strong>kx </strong></code> </a></td> <td>
+horizontal skew factor</td>
+ </tr> <tr> <td><a name="SkMatrix_setSkew_2_ky"> <code><strong>ky </strong></code> </a></td> <td>
+vertical skew factor</td>
+ </tr>
+</table>
+
+### Example
+
+<div><fiddle-embed name="05be7844e9afdd7b9bfc31c5423a70a2"></fiddle-embed></div>
+
+### See Also
+
+<a href="#SkMatrix_setSkewX">setSkewX</a> <a href="#SkMatrix_setSkewY">setSkewY</a> <a href="#SkMatrix_preSkew">preSkew</a> <a href="#SkMatrix_postSkew">postSkew</a>
+
+---
+
+<a name="SkMatrix_setConcat"></a>
+## setConcat
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+void setConcat(const SkMatrix& a, const SkMatrix& b)
+</pre>
+
+Sets <a href="#Matrix">Matrix</a> to <a href="#Matrix">Matrix</a> <a href="#SkMatrix_setConcat_a">a</a> multiplied by <a href="#Matrix">Matrix</a> <a href="#SkMatrix_setConcat_b">b</a>. Either <a href="#SkMatrix_setConcat_a">a</a> or <a href="#SkMatrix_setConcat_b">b</a> may be this.
+
+Given:
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+ | A B C | | J K L |
+a = | D E F |, b = | M N O |
+ | G H I | | P Q R |</pre>
+
+sets <a href="#Matrix">Matrix</a> to:
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+ | A B C | | J K L | | AJ+BM+CP AK+BN+CQ AL+BO+CR |
+a * b = | D E F | * | M N O | = | DJ+EM+FP DK+EN+FQ DL+EO+FR |
+ | G H I | | P Q R | | GJ+HM+IP GK+HN+IQ GL+HO+IR |</pre>
+
+### Parameters
+
+<table> <tr> <td><a name="SkMatrix_setConcat_a"> <code><strong>a </strong></code> </a></td> <td>
+<a href="#Matrix">Matrix</a> on left side of multiply expression</td>
+ </tr> <tr> <td><a name="SkMatrix_setConcat_b"> <code><strong>b </strong></code> </a></td> <td>
+<a href="#Matrix">Matrix</a> on right side of multiply expression</td>
+ </tr>
+</table>
+
+### Example
+
+<div><fiddle-embed name="0381a10ac69bdefdf9d15b47cbb9fefe"><div><a href="#SkMatrix_setPolyToPoly">setPolyToPoly</a> creates perspective matrices, one the inverse of the other.
+Multiplying the matrix by its inverse turns into an identity matrix.</div></fiddle-embed></div>
+
+### See Also
+
+<a href="#SkMatrix_Concat">Concat</a> <a href="#SkMatrix_preConcat">preConcat</a> <a href="#SkMatrix_postConcat">postConcat</a> <a href="#SkCanvas_concat">SkCanvas::concat</a>
+
+---
+
+<a name="SkMatrix_preTranslate"></a>
+## preTranslate
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+void preTranslate(SkScalar dx, SkScalar dy)
+</pre>
+
+Sets <a href="#Matrix">Matrix</a> to <a href="#Matrix">Matrix</a> multiplied by <a href="#Matrix">Matrix</a> constructed from translation (<a href="#SkMatrix_preTranslate_dx">dx</a>, <a href="#SkMatrix_preTranslate_dy">dy</a>).
+This can be thought of as moving the point to be mapped before applying <a href="#Matrix">Matrix</a>.
+
+Given:
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+ | A B C | | 1 0 dx |
+Matrix = | D E F |, T(dx, dy) = | 0 1 dy |
+ | G H I | | 0 0 1 |</pre>
+
+sets <a href="#Matrix">Matrix</a> to:
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+ | A B C | | 1 0 dx | | A B A*dx+B*dy+C |
+Matrix * T(dx, dy) = | D E F | | 0 1 dy | = | D E D*dx+E*dy+F |
+ | G H I | | 0 0 1 | | G H G*dx+H*dy+I |</pre>
+
+### Parameters
+
+<table> <tr> <td><a name="SkMatrix_preTranslate_dx"> <code><strong>dx </strong></code> </a></td> <td>
+x translation before applying <a href="#Matrix">Matrix</a></td>
+ </tr> <tr> <td><a name="SkMatrix_preTranslate_dy"> <code><strong>dy </strong></code> </a></td> <td>
+y translation before applying <a href="#Matrix">Matrix</a></td>
+ </tr>
+</table>
+
+### Example
+
+<div><fiddle-embed name="08f6749933f4ce541073077ab506fd9b"></fiddle-embed></div>
+
+### See Also
+
+<a href="#SkMatrix_postTranslate">postTranslate</a> <a href="#SkMatrix_setTranslate">setTranslate</a> <a href="#SkMatrix_MakeTrans">MakeTrans</a>
+
+---
+
+<a name="SkMatrix_preScale"></a>
+## preScale
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+void preScale(SkScalar sx, SkScalar sy, SkScalar px, SkScalar py)
+</pre>
+
+Sets <a href="#Matrix">Matrix</a> to <a href="#Matrix">Matrix</a> multiplied by <a href="#Matrix">Matrix</a> constructed from scaling by (<a href="#SkMatrix_preScale_sx">sx</a>, <a href="#SkMatrix_preScale_sy">sy</a>)
+about pivot point (<a href="#SkMatrix_preScale_px">px</a>, <a href="#SkMatrix_preScale_py">py</a>).
+This can be thought of as scaling about a pivot point before applying <a href="#Matrix">Matrix</a>.
+
+Given:
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+ | A B C | | sx 0 dx |
+Matrix = | D E F |, S(sx, sy, px, py) = | 0 sy dy |
+ | G H I | | 0 0 1 |</pre>
+
+where
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+dx = px - sx * px
+dy = py - sy * py</pre>
+
+sets <a href="#Matrix">Matrix</a> to:
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+ | A B C | | sx 0 dx | | A*sx B*sy A*dx+B*dy+C |
+Matrix * S(sx, sy, px, py) = | D E F | | 0 sy dy | = | D*sx E*sy D*dx+E*dy+F |
+ | G H I | | 0 0 1 | | G*sx H*sy G*dx+H*dy+I |</pre>
+
+### Parameters
+
+<table> <tr> <td><a name="SkMatrix_preScale_sx"> <code><strong>sx </strong></code> </a></td> <td>
+horizontal scale factor</td>
+ </tr> <tr> <td><a name="SkMatrix_preScale_sy"> <code><strong>sy </strong></code> </a></td> <td>
+vertical scale factor</td>
+ </tr> <tr> <td><a name="SkMatrix_preScale_px"> <code><strong>px </strong></code> </a></td> <td>
+pivot x</td>
+ </tr> <tr> <td><a name="SkMatrix_preScale_py"> <code><strong>py </strong></code> </a></td> <td>
+pivot y</td>
+ </tr>
+</table>
+
+### Example
+
+<div><fiddle-embed name="2531f8d1e05d7b6dc22f3efcd2fb84e4"></fiddle-embed></div>
+
+### See Also
+
+<a href="#SkMatrix_postScale">postScale</a> <a href="#SkMatrix_setScale">setScale</a> <a href="#SkMatrix_MakeScale">MakeScale</a>
+
+---
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+void preScale(SkScalar sx, SkScalar sy)
+</pre>
+
+Sets <a href="#Matrix">Matrix</a> to <a href="#Matrix">Matrix</a> multiplied by <a href="#Matrix">Matrix</a> constructed from scaling by (<a href="#SkMatrix_preScale_2_sx">sx</a>, <a href="#SkMatrix_preScale_2_sy">sy</a>)
+about pivot point (0, 0).
+This can be thought of as scaling about the origin before applying <a href="#Matrix">Matrix</a>.
+
+Given:
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+ | A B C | | sx 0 0 |
+Matrix = | D E F |, S(sx, sy) = | 0 sy 0 |
+ | G H I | | 0 0 1 |</pre>
+
+sets <a href="#Matrix">Matrix</a> to:
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+ | A B C | | sx 0 0 | | A*sx B*sy C |
+Matrix * S(sx, sy) = | D E F | | 0 sy 0 | = | D*sx E*sy F |
+ | G H I | | 0 0 1 | | G*sx H*sy I |</pre>
+
+### Parameters
+
+<table> <tr> <td><a name="SkMatrix_preScale_2_sx"> <code><strong>sx </strong></code> </a></td> <td>
+horizontal scale factor</td>
+ </tr> <tr> <td><a name="SkMatrix_preScale_2_sy"> <code><strong>sy </strong></code> </a></td> <td>
+vertical scale factor</td>
+ </tr>
+</table>
+
+### Example
+
+<div><fiddle-embed name="3edbdea8e43d06086abf33ec4a9b415b"></fiddle-embed></div>
+
+### See Also
+
+<a href="#SkMatrix_postScale">postScale</a> <a href="#SkMatrix_setScale">setScale</a> <a href="#SkMatrix_MakeScale">MakeScale</a>
+
+---
+
+<a name="SkMatrix_preRotate"></a>
+## preRotate
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+void preRotate(SkScalar degrees, SkScalar px, SkScalar py)
+</pre>
+
+Sets <a href="#Matrix">Matrix</a> to <a href="#Matrix">Matrix</a> multiplied by <a href="#Matrix">Matrix</a> constructed from rotating by <a href="#SkMatrix_preRotate_degrees">degrees</a>
+about pivot point (<a href="#SkMatrix_preRotate_px">px</a>, <a href="#SkMatrix_preRotate_py">py</a>).
+This can be thought of as rotating about a pivot point before applying <a href="#Matrix">Matrix</a>.
+
+Positive <a href="#SkMatrix_preRotate_degrees">degrees</a> rotates clockwise.
+
+Given:
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+ | A B C | | c -s dx |
+Matrix = | D E F |, R(degrees, px, py) = | s c dy |
+ | G H I | | 0 0 1 |</pre>
+
+where
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+c = cos(degrees)
+s = sin(degrees)
+dx = s * py + (1 - c) * px
+dy = -s * px + (1 - c) * py</pre>
+
+sets <a href="#Matrix">Matrix</a> to:
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+ | A B C | | c -s dx | | Ac+Bs -As+Bc A*dx+B*dy+C |
+Matrix * R(degrees, px, py) = | D E F | | s c dy | = | Dc+Es -Ds+Ec D*dx+E*dy+F |
+ | G H I | | 0 0 1 | | Gc+Hs -Gs+Hc G*dx+H*dy+I |</pre>
+
+### Parameters
+
+<table> <tr> <td><a name="SkMatrix_preRotate_degrees"> <code><strong>degrees </strong></code> </a></td> <td>
+angle of axes relative to upright axes</td>
+ </tr> <tr> <td><a name="SkMatrix_preRotate_px"> <code><strong>px </strong></code> </a></td> <td>
+pivot x</td>
+ </tr> <tr> <td><a name="SkMatrix_preRotate_py"> <code><strong>py </strong></code> </a></td> <td>
+pivot y</td>
+ </tr>
+</table>
+
+### Example
+
+<div><fiddle-embed name="a70bb18d67c06a20ab514e7a47924e5a"></fiddle-embed></div>
+
+### See Also
+
+<a href="#SkMatrix_postRotate">postRotate</a> <a href="#SkMatrix_setRotate">setRotate</a>
+
+---
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+void preRotate(SkScalar degrees)
+</pre>
+
+Sets <a href="#Matrix">Matrix</a> to <a href="#Matrix">Matrix</a> multiplied by <a href="#Matrix">Matrix</a> constructed from rotating by <a href="#SkMatrix_preRotate_2_degrees">degrees</a>
+about pivot point (0, 0).
+This can be thought of as rotating about the origin before applying <a href="#Matrix">Matrix</a>.
+
+Positive <a href="#SkMatrix_preRotate_2_degrees">degrees</a> rotates clockwise.
+
+Given:
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+ | A B C | | c -s 0 |
+Matrix = | D E F |, R(degrees, px, py) = | s c 0 |
+ | G H I | | 0 0 1 |</pre>
+
+where
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+c = cos(degrees)
+s = sin(degrees)</pre>
+
+sets <a href="#Matrix">Matrix</a> to:
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+ | A B C | | c -s 0 | | Ac+Bs -As+Bc C |
+Matrix * R(degrees, px, py) = | D E F | | s c 0 | = | Dc+Es -Ds+Ec F |
+ | G H I | | 0 0 1 | | Gc+Hs -Gs+Hc I |</pre>
+
+### Parameters
+
+<table> <tr> <td><a name="SkMatrix_preRotate_2_degrees"> <code><strong>degrees </strong></code> </a></td> <td>
+angle of axes relative to upright axes</td>
+ </tr>
+</table>
+
+### Example
+
+<div><fiddle-embed name="5acd49bd931c79a808dd6c7cc0e92f72"></fiddle-embed></div>
+
+### See Also
+
+<a href="#SkMatrix_postRotate">postRotate</a> <a href="#SkMatrix_setRotate">setRotate</a>
+
+---
+
+<a name="SkMatrix_preSkew"></a>
+## preSkew
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+void preSkew(SkScalar kx, SkScalar ky, SkScalar px, SkScalar py)
+</pre>
+
+Sets <a href="#Matrix">Matrix</a> to <a href="#Matrix">Matrix</a> multiplied by <a href="#Matrix">Matrix</a> constructed from skewing by (<a href="#SkMatrix_preSkew_kx">kx</a>, <a href="#SkMatrix_preSkew_ky">ky</a>)
+about pivot point (<a href="#SkMatrix_preSkew_px">px</a>, <a href="#SkMatrix_preSkew_py">py</a>).
+This can be thought of as skewing about a pivot point before applying <a href="#Matrix">Matrix</a>.
+
+Given:
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+ | A B C | | 1 kx dx |
+Matrix = | D E F |, K(kx, ky, px, py) = | ky 1 dy |
+ | G H I | | 0 0 1 |</pre>
+
+where
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+dx = -kx * py
+dy = -ky * px</pre>
+
+sets <a href="#Matrix">Matrix</a> to:
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+ | A B C | | 1 kx dx | | A+B*ky A*kx+B A*dx+B*dy+C |
+Matrix * K(kx, ky, px, py) = | D E F | | ky 1 dy | = | D+E*ky D*kx+E D*dx+E*dy+F |
+ | G H I | | 0 0 1 | | G+H*ky G*kx+H G*dx+H*dy+I |</pre>
+
+### Parameters
+
+<table> <tr> <td><a name="SkMatrix_preSkew_kx"> <code><strong>kx </strong></code> </a></td> <td>
+horizontal skew factor</td>
+ </tr> <tr> <td><a name="SkMatrix_preSkew_ky"> <code><strong>ky </strong></code> </a></td> <td>
+vertical skew factor</td>
+ </tr> <tr> <td><a name="SkMatrix_preSkew_px"> <code><strong>px </strong></code> </a></td> <td>
+pivot x</td>
+ </tr> <tr> <td><a name="SkMatrix_preSkew_py"> <code><strong>py </strong></code> </a></td> <td>
+pivot y</td>
+ </tr>
+</table>
+
+### Example
+
+<div><fiddle-embed name="199a18ad61d702664ce6df1d7037aa48"></fiddle-embed></div>
+
+### See Also
+
+<a href="#SkMatrix_postSkew">postSkew</a> <a href="#SkMatrix_setSkew">setSkew</a>
+
+---
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+void preSkew(SkScalar kx, SkScalar ky)
+</pre>
+
+Sets <a href="#Matrix">Matrix</a> to <a href="#Matrix">Matrix</a> multiplied by <a href="#Matrix">Matrix</a> constructed from skewing by (<a href="#SkMatrix_preSkew_2_kx">kx</a>, <a href="#SkMatrix_preSkew_2_ky">ky</a>)
+about pivot point (0, 0).
+This can be thought of as skewing about the origin before applying <a href="#Matrix">Matrix</a>.
+
+Given:
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+ | A B C | | 1 kx 0 |
+Matrix = | D E F |, K(kx, ky) = | ky 1 0 |
+ | G H I | | 0 0 1 |</pre>
+
+sets <a href="#Matrix">Matrix</a> to:
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+ | A B C | | 1 kx 0 | | A+B*ky A*kx+B C |
+Matrix * K(kx, ky) = | D E F | | ky 1 0 | = | D+E*ky D*kx+E F |
+ | G H I | | 0 0 1 | | G+H*ky G*kx+H I |</pre>
+
+### Parameters
+
+<table> <tr> <td><a name="SkMatrix_preSkew_2_kx"> <code><strong>kx </strong></code> </a></td> <td>
+horizontal skew factor</td>
+ </tr> <tr> <td><a name="SkMatrix_preSkew_2_ky"> <code><strong>ky </strong></code> </a></td> <td>
+vertical skew factor</td>
+ </tr>
+</table>
+
+### Example
+
+<div><fiddle-embed name="e100c543869fe8fd516ba69de79444ba"></fiddle-embed></div>
+
+### See Also
+
+<a href="#SkMatrix_postSkew">postSkew</a> <a href="#SkMatrix_setSkew">setSkew</a>
+
+---
+
+<a name="SkMatrix_preConcat"></a>
+## preConcat
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+void preConcat(const SkMatrix& other)
+</pre>
+
+Sets <a href="#Matrix">Matrix</a> to <a href="#Matrix">Matrix</a> multiplied by <a href="#Matrix">Matrix</a> <a href="#SkMatrix_preConcat_other">other</a>.
+This can be thought of mapping by <a href="#SkMatrix_preConcat_other">other</a> before applying <a href="#Matrix">Matrix</a>.
+
+Given:
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+ | A B C | | J K L |
+Matrix = | D E F |, other = | M N O |
+ | G H I | | P Q R |</pre>
+
+sets <a href="#Matrix">Matrix</a> to:
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+ | A B C | | J K L | | AJ+BM+CP AK+BN+CQ AL+BO+CR |
+Matrix * other = | D E F | * | M N O | = | DJ+EM+FP DK+EN+FQ DL+EO+FR |
+ | G H I | | P Q R | | GJ+HM+IP GK+HN+IQ GL+HO+IR |</pre>
+
+### Parameters
+
+<table> <tr> <td><a name="SkMatrix_preConcat_other"> <code><strong>other </strong></code> </a></td> <td>
+<a href="#Matrix">Matrix</a> on right side of multiply expression</td>
+ </tr>
+</table>
+
+### Example
+
+<div><fiddle-embed name="b07e62298e7b0ab5683db199faffceb2"><div><a href="#SkMatrix_setPolyToPoly">setPolyToPoly</a> creates perspective matrices, one the inverse of the <a href="#SkMatrix_preConcat_other">other</a>.
+Multiplying the matrix by its inverse turns into an identity matrix.</div></fiddle-embed></div>
+
+### See Also
+
+<a href="#SkMatrix_postConcat">postConcat</a> <a href="#SkMatrix_setConcat">setConcat</a> <a href="#SkMatrix_Concat">Concat</a>
+
+---
+
+<a name="SkMatrix_postTranslate"></a>
+## postTranslate
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+void postTranslate(SkScalar dx, SkScalar dy)
+</pre>
+
+Sets <a href="#Matrix">Matrix</a> to <a href="#Matrix">Matrix</a> constructed from translation (<a href="#SkMatrix_postTranslate_dx">dx</a>, <a href="#SkMatrix_postTranslate_dy">dy</a>) multiplied by <a href="#Matrix">Matrix</a>.
+This can be thought of as moving the point to be mapped after applying <a href="#Matrix">Matrix</a>.
+
+Given:
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+ | J K L | | 1 0 dx |
+Matrix = | M N O |, T(dx, dy) = | 0 1 dy |
+ | P Q R | | 0 0 1 |</pre>
+
+sets <a href="#Matrix">Matrix</a> to:
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+ | 1 0 dx | | J K L | | J+dx*P K+dx*Q L+dx*R |
+T(dx, dy) * Matrix = | 0 1 dy | | M N O | = | M+dy*P N+dy*Q O+dy*R |
+ | 0 0 1 | | P Q R | | P Q R |</pre>
+
+### Parameters
+
+<table> <tr> <td><a name="SkMatrix_postTranslate_dx"> <code><strong>dx </strong></code> </a></td> <td>
+x translation after applying <a href="#Matrix">Matrix</a></td>
+ </tr> <tr> <td><a name="SkMatrix_postTranslate_dy"> <code><strong>dy </strong></code> </a></td> <td>
+y translation after applying <a href="#Matrix">Matrix</a></td>
+ </tr>
+</table>
+
+### Example
+
+<div><fiddle-embed name="57e4cff302c0d754ac6c66050d741772"><div>Compare with <a href="#SkMatrix_preTranslate">preTranslate</a> example.</div></fiddle-embed></div>
+
+### See Also
+
+<a href="#SkMatrix_preTranslate">preTranslate</a> <a href="#SkMatrix_setTranslate">setTranslate</a> <a href="#SkMatrix_MakeTrans">MakeTrans</a>
+
+---
+
+<a name="SkMatrix_postScale"></a>
+## postScale
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+void postScale(SkScalar sx, SkScalar sy, SkScalar px, SkScalar py)
+</pre>
+
+Sets <a href="#Matrix">Matrix</a> to <a href="#Matrix">Matrix</a> constructed from scaling by (<a href="#SkMatrix_postScale_sx">sx</a>, <a href="#SkMatrix_postScale_sy">sy</a>) about pivot point
+(<a href="#SkMatrix_postScale_px">px</a>, <a href="#SkMatrix_postScale_py">py</a>), multiplied by <a href="#Matrix">Matrix</a>.
+This can be thought of as scaling about a pivot point after applying <a href="#Matrix">Matrix</a>.
+
+Given:
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+ | J K L | | sx 0 dx |
+Matrix = | M N O |, S(sx, sy, px, py) = | 0 sy dy |
+ | P Q R | | 0 0 1 |</pre>
+
+where
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+dx = px - sx * px
+dy = py - sy * py</pre>
+
+sets <a href="#Matrix">Matrix</a> to:
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+ | sx 0 dx | | J K L | | sx*J+dx*P sx*K+dx*Q sx*L+dx+R |
+S(sx, sy, px, py) * Matrix = | 0 sy dy | | M N O | = | sy*M+dy*P sy*N+dy*Q sy*O+dy*R |
+ | 0 0 1 | | P Q R | | P Q R |</pre>
+
+### Parameters
+
+<table> <tr> <td><a name="SkMatrix_postScale_sx"> <code><strong>sx </strong></code> </a></td> <td>
+horizontal scale factor</td>
+ </tr> <tr> <td><a name="SkMatrix_postScale_sy"> <code><strong>sy </strong></code> </a></td> <td>
+vertical scale factor</td>
+ </tr> <tr> <td><a name="SkMatrix_postScale_px"> <code><strong>px </strong></code> </a></td> <td>
+pivot x</td>
+ </tr> <tr> <td><a name="SkMatrix_postScale_py"> <code><strong>py </strong></code> </a></td> <td>
+pivot y</td>
+ </tr>
+</table>
+
+### Example
+
+<div><fiddle-embed name="ed3aa18ba0ea95c85cc49aa3829fe384"></fiddle-embed></div>
+
+### See Also
+
+<a href="#SkMatrix_preScale">preScale</a> <a href="#SkMatrix_setScale">setScale</a> <a href="#SkMatrix_MakeScale">MakeScale</a>
+
+---
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+void postScale(SkScalar sx, SkScalar sy)
+</pre>
+
+Sets <a href="#Matrix">Matrix</a> to <a href="#Matrix">Matrix</a> constructed from scaling by (<a href="#SkMatrix_postScale_2_sx">sx</a>, <a href="#SkMatrix_postScale_2_sy">sy</a>) about pivot point
+(0, 0), multiplied by <a href="#Matrix">Matrix</a>.
+This can be thought of as scaling about the origin after applying <a href="#Matrix">Matrix</a>.
+
+Given:
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+ | J K L | | sx 0 0 |
+Matrix = | M N O |, S(sx, sy) = | 0 sy 0 |
+ | P Q R | | 0 0 1 |</pre>
+
+sets <a href="#Matrix">Matrix</a> to:
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+ | sx 0 0 | | J K L | | sx*J sx*K sx*L |
+S(sx, sy) * Matrix = | 0 sy 0 | | M N O | = | sy*M sy*N sy*O |
+ | 0 0 1 | | P Q R | | P Q R |</pre>
+
+### Parameters
+
+<table> <tr> <td><a name="SkMatrix_postScale_2_sx"> <code><strong>sx </strong></code> </a></td> <td>
+horizontal scale factor</td>
+ </tr> <tr> <td><a name="SkMatrix_postScale_2_sy"> <code><strong>sy </strong></code> </a></td> <td>
+vertical scale factor</td>
+ </tr>
+</table>
+
+### Example
+
+<div><fiddle-embed name="1931017698766a67d3a26423453b8095"></fiddle-embed></div>
+
+### See Also
+
+<a href="#SkMatrix_preScale">preScale</a> <a href="#SkMatrix_setScale">setScale</a> <a href="#SkMatrix_MakeScale">MakeScale</a>
+
+---
+
+<a name="SkMatrix_postIDiv"></a>
+## postIDiv
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+bool postIDiv(int divx, int divy)
+</pre>
+
+Sets <a href="#Matrix">Matrix</a> to <a href="#Matrix">Matrix</a> constructed from scaling by(1/<a href="#SkMatrix_postIDiv_divx">divx</a>, 1/<a href="#SkMatrix_postIDiv_divy">divy</a>)about pivot point (px, py), multiplied by <a href="#Matrix">Matrix</a>.
+
+Returns false if either <a href="#SkMatrix_postIDiv_divx">divx</a> or <a href="#SkMatrix_postIDiv_divy">divy</a> is zero.
+
+Given:
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+ | J K L | | sx 0 0 |
+Matrix = | M N O |, I(divx, divy) = | 0 sy 0 |
+ | P Q R | | 0 0 1 |</pre>
+
+where
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+sx = 1 / divx
+sy = 1 / divy</pre>
+
+sets <a href="#Matrix">Matrix</a> to:
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+ | sx 0 0 | | J K L | | sx*J sx*K sx*L |
+I(divx, divy) * Matrix = | 0 sy 0 | | M N O | = | sy*M sy*N sy*O |
+ | 0 0 1 | | P Q R | | P Q R |</pre>
+
+### Parameters
+
+<table> <tr> <td><a name="SkMatrix_postIDiv_divx"> <code><strong>divx </strong></code> </a></td> <td>
+integer divisor for inverse scale in x</td>
+ </tr> <tr> <td><a name="SkMatrix_postIDiv_divy"> <code><strong>divy </strong></code> </a></td> <td>
+integer divisor for inverse scale in y</td>
+ </tr>
+</table>
+
+### Return Value
+
+true on successful scale
+
+### Example
+
+<div><fiddle-embed name="58c844b8f0c36acdbc8211e8c929c253"></fiddle-embed></div>
+
+### See Also
+
+<a href="#SkMatrix_postScale">postScale</a> <a href="#SkMatrix_MakeScale">MakeScale</a>
+
+---
+
+<a name="SkMatrix_postRotate"></a>
+## postRotate
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+void postRotate(SkScalar degrees, SkScalar px, SkScalar py)
+</pre>
+
+Sets <a href="#Matrix">Matrix</a> to <a href="#Matrix">Matrix</a> constructed from rotating by <a href="#SkMatrix_postRotate_degrees">degrees</a> about pivot point
+(<a href="#SkMatrix_postRotate_px">px</a>, <a href="#SkMatrix_postRotate_py">py</a>), multiplied by <a href="#Matrix">Matrix</a>.
+This can be thought of as rotating about a pivot point after applying <a href="#Matrix">Matrix</a>.
+
+Positive <a href="#SkMatrix_postRotate_degrees">degrees</a> rotates clockwise.
+
+Given:
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+ | J K L | | c -s dx |
+Matrix = | M N O |, R(degrees, px, py) = | s c dy |
+ | P Q R | | 0 0 1 |</pre>
+
+where
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+c = cos(degrees)
+s = sin(degrees)
+dx = s * py + (1 - c) * px
+dy = -s * px + (1 - c) * py</pre>
+
+sets <a href="#Matrix">Matrix</a> to:
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+ |c -s dx| |J K L| |cJ-sM+dx*P cK-sN+dx*Q cL-sO+dx+R|
+R(degrees, px, py) * Matrix = |s c dy| |M N O| = |sJ+cM+dy*P sK+cN+dy*Q sL+cO+dy*R|
+ |0 0 1| |P Q R| | P Q R|</pre>
+
+### Parameters
+
+<table> <tr> <td><a name="SkMatrix_postRotate_degrees"> <code><strong>degrees </strong></code> </a></td> <td>
+angle of axes relative to upright axes</td>
+ </tr> <tr> <td><a name="SkMatrix_postRotate_px"> <code><strong>px </strong></code> </a></td> <td>
+pivot x</td>
+ </tr> <tr> <td><a name="SkMatrix_postRotate_py"> <code><strong>py </strong></code> </a></td> <td>
+pivot y</td>
+ </tr>
+</table>
+
+### Example
+
+<div><fiddle-embed name="e09194ee48a81e7b375ade473d340f0d"></fiddle-embed></div>
+
+### See Also
+
+<a href="#SkMatrix_preRotate">preRotate</a> <a href="#SkMatrix_setRotate">setRotate</a>
+
+---
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+void postRotate(SkScalar degrees)
+</pre>
+
+Sets <a href="#Matrix">Matrix</a> to <a href="#Matrix">Matrix</a> constructed from rotating by <a href="#SkMatrix_postRotate_2_degrees">degrees</a> about pivot point
+(0, 0), multiplied by <a href="#Matrix">Matrix</a>.
+This can be thought of as rotating about the origin after applying <a href="#Matrix">Matrix</a>.
+
+Positive <a href="#SkMatrix_postRotate_2_degrees">degrees</a> rotates clockwise.
+
+Given:
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+ | J K L | | c -s 0 |
+Matrix = | M N O |, R(degrees, px, py) = | s c 0 |
+ | P Q R | | 0 0 1 |</pre>
+
+where
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+c = cos(degrees)
+s = sin(degrees)</pre>
+
+sets <a href="#Matrix">Matrix</a> to:
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+ | c -s dx | | J K L | | cJ-sM cK-sN cL-sO |
+R(degrees, px, py) * Matrix = | s c dy | | M N O | = | sJ+cM sK+cN sL+cO |
+ | 0 0 1 | | P Q R | | P Q R |</pre>
+
+### Parameters
+
+<table> <tr> <td><a name="SkMatrix_postRotate_2_degrees"> <code><strong>degrees </strong></code> </a></td> <td>
+angle of axes relative to upright axes</td>
+ </tr>
+</table>
+
+### Example
+
+<div><fiddle-embed name="52e4c53e26971af5576b30de60fa70c2"></fiddle-embed></div>
+
+### See Also
+
+<a href="#SkMatrix_preRotate">preRotate</a> <a href="#SkMatrix_setRotate">setRotate</a>
+
+---
+
+<a name="SkMatrix_postSkew"></a>
+## postSkew
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+void postSkew(SkScalar kx, SkScalar ky, SkScalar px, SkScalar py)
+</pre>
+
+Sets <a href="#Matrix">Matrix</a> to <a href="#Matrix">Matrix</a> constructed from skewing by (<a href="#SkMatrix_postSkew_kx">kx</a>, <a href="#SkMatrix_postSkew_ky">ky</a>) about pivot point
+(<a href="#SkMatrix_postSkew_px">px</a>, <a href="#SkMatrix_postSkew_py">py</a>), multiplied by <a href="#Matrix">Matrix</a>.
+This can be thought of as skewing about a pivot point after applying <a href="#Matrix">Matrix</a>.
+
+Given:
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+ | J K L | | 1 kx dx |
+Matrix = | M N O |, K(kx, ky, px, py) = | ky 1 dy |
+ | P Q R | | 0 0 1 |</pre>
+
+where
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+dx = -kx * py
+dy = -ky * px</pre>
+
+sets <a href="#Matrix">Matrix</a> to:
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+ | 1 kx dx| |J K L| |J+kx*M+dx*P K+kx*N+dx*Q L+kx*O+dx+R|
+K(kx, ky, px, py) * Matrix = |ky 1 dy| |M N O| = |ky*J+M+dy*P ky*K+N+dy*Q ky*L+O+dy*R|
+ | 0 0 1| |P Q R| | P Q R|</pre>
+
+### Parameters
+
+<table> <tr> <td><a name="SkMatrix_postSkew_kx"> <code><strong>kx </strong></code> </a></td> <td>
+horizontal skew factor</td>
+ </tr> <tr> <td><a name="SkMatrix_postSkew_ky"> <code><strong>ky </strong></code> </a></td> <td>
+vertical skew factor</td>
+ </tr> <tr> <td><a name="SkMatrix_postSkew_px"> <code><strong>px </strong></code> </a></td> <td>
+pivot x</td>
+ </tr> <tr> <td><a name="SkMatrix_postSkew_py"> <code><strong>py </strong></code> </a></td> <td>
+pivot y</td>
+ </tr>
+</table>
+
+### Example
+
+<div><fiddle-embed name="8c34ae3a2b7e2742bb969819737365ec"></fiddle-embed></div>
+
+### See Also
+
+<a href="#SkMatrix_preSkew">preSkew</a> <a href="#SkMatrix_setSkew">setSkew</a>
+
+---
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+void postSkew(SkScalar kx, SkScalar ky)
+</pre>
+
+Sets <a href="#Matrix">Matrix</a> to <a href="#Matrix">Matrix</a> constructed from skewing by (<a href="#SkMatrix_postSkew_2_kx">kx</a>, <a href="#SkMatrix_postSkew_2_ky">ky</a>) about pivot point
+(0, 0), multiplied by <a href="#Matrix">Matrix</a>.
+This can be thought of as skewing about the origin after applying <a href="#Matrix">Matrix</a>.
+
+Given:
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+ | J K L | | 1 kx 0 |
+Matrix = | M N O |, K(kx, ky) = | ky 1 0 |
+ | P Q R | | 0 0 1 |</pre>
+
+sets <a href="#Matrix">Matrix</a> to:
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+ | 1 kx 0 | | J K L | | J+kx*M K+kx*N L+kx*O |
+K(kx, ky) * Matrix = | ky 1 0 | | M N O | = | ky*J+M ky*K+N ky*L+O |
+ | 0 0 1 | | P Q R | | P Q R |</pre>
+
+### Parameters
+
+<table> <tr> <td><a name="SkMatrix_postSkew_2_kx"> <code><strong>kx </strong></code> </a></td> <td>
+horizontal skew factor</td>
+ </tr> <tr> <td><a name="SkMatrix_postSkew_2_ky"> <code><strong>ky </strong></code> </a></td> <td>
+vertical skew factor</td>
+ </tr>
+</table>
+
+### Example
+
+<div><fiddle-embed name="3aa2603225dff72ac53dd359f897f494"></fiddle-embed></div>
+
+### See Also
+
+<a href="#SkMatrix_preSkew">preSkew</a> <a href="#SkMatrix_setSkew">setSkew</a>
+
+---
+
+<a name="SkMatrix_postConcat"></a>
+## postConcat
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+void postConcat(const SkMatrix& other)
+</pre>
+
+Sets <a href="#Matrix">Matrix</a> to <a href="#Matrix">Matrix</a> <a href="#SkMatrix_postConcat_other">other</a> multiplied by <a href="#Matrix">Matrix</a>.
+This can be thought of mapping by <a href="#SkMatrix_postConcat_other">other</a> after applying <a href="#Matrix">Matrix</a>.
+
+Given:
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+ | J K L | | A B C |
+Matrix = | M N O |, other = | D E F |
+ | P Q R | | G H I |</pre>
+
+sets <a href="#Matrix">Matrix</a> to:
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+ | A B C | | J K L | | AJ+BM+CP AK+BN+CQ AL+BO+CR |
+other * Matrix = | D E F | * | M N O | = | DJ+EM+FP DK+EN+FQ DL+EO+FR |
+ | G H I | | P Q R | | GJ+HM+IP GK+HN+IQ GL+HO+IR |</pre>
+
+### Parameters
+
+<table> <tr> <td><a name="SkMatrix_postConcat_other"> <code><strong>other </strong></code> </a></td> <td>
+<a href="#Matrix">Matrix</a> on left side of multiply expression</td>
+ </tr>
+</table>
+
+### Example
+
+<div><fiddle-embed name="0a4214289249c77f48d59227c4ac4d9e"></fiddle-embed></div>
+
+### See Also
+
+<a href="#SkMatrix_preConcat">preConcat</a> <a href="#SkMatrix_setConcat">setConcat</a> <a href="#SkMatrix_Concat">Concat</a>
+
+---
+
+## <a name="SkMatrix_ScaleToFit"></a> Enum SkMatrix::ScaleToFit
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+enum <a href="#SkMatrix_ScaleToFit">ScaleToFit</a> {
+<a href="#SkMatrix_kFill_ScaleToFit">kFill ScaleToFit</a>,
+<a href="#SkMatrix_kStart_ScaleToFit">kStart ScaleToFit</a>,
+<a href="#SkMatrix_kCenter_ScaleToFit">kCenter ScaleToFit</a>,
+<a href="#SkMatrix_kEnd_ScaleToFit">kEnd ScaleToFit</a>,
+};</pre>
+
+<a href="#SkMatrix_ScaleToFit">ScaleToFit</a> describes how <a href="#Matrix">Matrix</a> is constructed to map one <a href="SkRect_Reference#Rect">Rect</a> to another.
+<a href="#SkMatrix_ScaleToFit">ScaleToFit</a> may allow <a href="#Matrix">Matrix</a> to have unequal horizontal and vertical scaling,
+or may restrict <a href="#Matrix">Matrix</a> to square scaling. If restricted, <a href="#SkMatrix_ScaleToFit">ScaleToFit</a> specifies
+how <a href="#Matrix">Matrix</a> maps to the side or center of the destination <a href="SkRect_Reference#Rect">Rect</a>.
+
+### Constants
+
+<table>
+ <tr>
+ <td><a name="SkMatrix_kFill_ScaleToFit"> <code><strong>SkMatrix::kFill_ScaleToFit </strong></code> </a></td><td>0</td><td>Computes <a href="#Matrix">Matrix</a> that scales in x and y independently, so that source <a href="SkRect_Reference#Rect">Rect</a> is
+mapped to completely fill destination <a href="SkRect_Reference#Rect">Rect</a>. The aspect ratio of source <a href="SkRect_Reference#Rect">Rect</a>
+may change.</td>
+ </tr>
+ <tr>
+ <td><a name="SkMatrix_kStart_ScaleToFit"> <code><strong>SkMatrix::kStart_ScaleToFit </strong></code> </a></td><td>1</td><td>Computes <a href="#Matrix">Matrix</a> that maintains source <a href="SkRect_Reference#Rect">Rect</a> aspect ratio, mapping source <a href="SkRect_Reference#Rect">Rect</a>
+width or height to destination <a href="SkRect_Reference#Rect">Rect</a>. Aligns mapping to left and top edges
+of destination <a href="SkRect_Reference#Rect">Rect</a>.</td>
+ </tr>
+ <tr>
+ <td><a name="SkMatrix_kCenter_ScaleToFit"> <code><strong>SkMatrix::kCenter_ScaleToFit </strong></code> </a></td><td>2</td><td>Computes <a href="#Matrix">Matrix</a> that maintains source <a href="SkRect_Reference#Rect">Rect</a> aspect ratio, mapping source <a href="SkRect_Reference#Rect">Rect</a>
+width or height to destination <a href="SkRect_Reference#Rect">Rect</a>. Aligns mapping to center of destination
+<a href="SkRect_Reference#Rect">Rect</a>.</td>
+ </tr>
+ <tr>
+ <td><a name="SkMatrix_kEnd_ScaleToFit"> <code><strong>SkMatrix::kEnd_ScaleToFit </strong></code> </a></td><td>3</td><td>Computes <a href="#Matrix">Matrix</a> that maintains source <a href="SkRect_Reference#Rect">Rect</a> aspect ratio, mapping source <a href="SkRect_Reference#Rect">Rect</a>
+width or height to destination <a href="SkRect_Reference#Rect">Rect</a>. Aligns mapping to right and bottom
+edges of destination <a href="SkRect_Reference#Rect">Rect</a>.</td>
+ </tr>
+</table>
+
+### Example
+
+<div><fiddle-embed name="17c3070b31b700ea8f52e48af9a66b6e"></fiddle-embed></div>
+
+### See Also
+
+<a href="#SkMatrix_setRectToRect">setRectToRect</a> <a href="#SkMatrix_MakeRectToRect">MakeRectToRect</a> <a href="#SkMatrix_setPolyToPoly">setPolyToPoly</a>
+
+
+
+<a name="SkMatrix_setRectToRect"></a>
+## setRectToRect
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+bool setRectToRect(const SkRect& src, const SkRect& dst, ScaleToFit stf)
+</pre>
+
+Sets <a href="#Matrix">Matrix</a> to scale and translate <a href="#SkMatrix_setRectToRect_src">src</a> <a href="SkRect_Reference#Rect">Rect</a> to <a href="#SkMatrix_setRectToRect_dst">dst</a> <a href="SkRect_Reference#Rect">Rect</a>. <a href="#SkMatrix_setRectToRect_stf">stf</a> selects whether
+mapping completely fills <a href="#SkMatrix_setRectToRect_dst">dst</a> or preserves the aspect ratio, and how to align
+<a href="#SkMatrix_setRectToRect_src">src</a> within <a href="#SkMatrix_setRectToRect_dst">dst</a>. Returns false if <a href="#SkMatrix_setRectToRect_src">src</a> is empty, and sets <a href="#Matrix">Matrix</a> to identity.
+Returns true if <a href="#SkMatrix_setRectToRect_dst">dst</a> is empty, and sets <a href="#Matrix">Matrix</a> to:
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+| 0 0 0 |
+| 0 0 0 |
+| 0 0 1 |</pre>
+
+### Parameters
+
+<table> <tr> <td><a name="SkMatrix_setRectToRect_src"> <code><strong>src </strong></code> </a></td> <td>
+<a href="SkRect_Reference#Rect">Rect</a> to map from</td>
+ </tr> <tr> <td><a name="SkMatrix_setRectToRect_dst"> <code><strong>dst </strong></code> </a></td> <td>
+<a href="SkRect_Reference#Rect">Rect</a> to map to</td>
+ </tr> <tr> <td><a name="SkMatrix_setRectToRect_stf"> <code><strong>stf </strong></code> </a></td> <td>
+one of: <a href="#SkMatrix_kFill_ScaleToFit">kFill ScaleToFit</a>, <a href="#SkMatrix_kStart_ScaleToFit">kStart ScaleToFit</a>,
+<a href="#SkMatrix_kCenter_ScaleToFit">kCenter ScaleToFit</a>, <a href="#SkMatrix_kEnd_ScaleToFit">kEnd ScaleToFit</a></td>
+ </tr>
+</table>
+
+### Return Value
+
+true if <a href="#Matrix">Matrix</a> can represent <a href="SkRect_Reference#Rect">Rect</a> mapping
+
+### Example
+
+<div><fiddle-embed name="69cdea599dcaaec35efcb24403f4287b">
+
+#### Example Output
+
+~~~~
+src: 0, 0, 0, 0 dst: 0, 0, 0, 0 success: false
+[ 1.0000 0.0000 0.0000][ 0.0000 1.0000 0.0000][ 0.0000 0.0000 1.0000]
+src: 0, 0, 0, 0 dst: 5, 6, 8, 9 success: false
+[ 1.0000 0.0000 0.0000][ 0.0000 1.0000 0.0000][ 0.0000 0.0000 1.0000]
+src: 1, 2, 3, 4 dst: 0, 0, 0, 0 success: true
+[ 0.0000 0.0000 0.0000][ 0.0000 0.0000 0.0000][ 0.0000 0.0000 1.0000]
+src: 1, 2, 3, 4 dst: 5, 6, 8, 9 success: true
+[ 1.5000 0.0000 3.5000][ 0.0000 1.5000 3.0000][ 0.0000 0.0000 1.0000]
+~~~~
+
+</fiddle-embed></div>
+
+### See Also
+
+<a href="#SkMatrix_MakeRectToRect">MakeRectToRect</a> <a href="#SkMatrix_ScaleToFit">ScaleToFit</a> <a href="#SkMatrix_setPolyToPoly">setPolyToPoly</a> <a href="#SkRect_isEmpty">SkRect::isEmpty</a>
+
+---
+
+<a name="SkMatrix_MakeRectToRect"></a>
+## MakeRectToRect
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+static SkMatrix MakeRectToRect(const SkRect& src, const SkRect& dst,
+ ScaleToFit stf)
+</pre>
+
+Returns <a href="#Matrix">Matrix</a> <a href="#SkMatrix_set">set</a> to scale and translate <a href="#SkMatrix_MakeRectToRect_src">src</a> <a href="SkRect_Reference#Rect">Rect</a> to <a href="#SkMatrix_MakeRectToRect_dst">dst</a> <a href="SkRect_Reference#Rect">Rect</a>. <a href="#SkMatrix_MakeRectToRect_stf">stf</a> selects
+whether mapping completely fills <a href="#SkMatrix_MakeRectToRect_dst">dst</a> or preserves the aspect ratio, and how to
+align <a href="#SkMatrix_MakeRectToRect_src">src</a> within <a href="#SkMatrix_MakeRectToRect_dst">dst</a>. Returns the identity <a href="#Matrix">Matrix</a> if <a href="#SkMatrix_MakeRectToRect_src">src</a> is empty. If <a href="#SkMatrix_MakeRectToRect_dst">dst</a> is
+empty, returns <a href="#Matrix">Matrix</a> <a href="#SkMatrix_set">set</a> to:
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+| 0 0 0 |
+| 0 0 0 |
+| 0 0 1 |</pre>
+
+### Parameters
+
+<table> <tr> <td><a name="SkMatrix_MakeRectToRect_src"> <code><strong>src </strong></code> </a></td> <td>
+<a href="SkRect_Reference#Rect">Rect</a> to map from</td>
+ </tr> <tr> <td><a name="SkMatrix_MakeRectToRect_dst"> <code><strong>dst </strong></code> </a></td> <td>
+<a href="SkRect_Reference#Rect">Rect</a> to map to</td>
+ </tr> <tr> <td><a name="SkMatrix_MakeRectToRect_stf"> <code><strong>stf </strong></code> </a></td> <td>
+one of: <a href="#SkMatrix_kFill_ScaleToFit">kFill ScaleToFit</a>, <a href="#SkMatrix_kStart_ScaleToFit">kStart ScaleToFit</a>,
+<a href="#SkMatrix_kCenter_ScaleToFit">kCenter ScaleToFit</a>, <a href="#SkMatrix_kEnd_ScaleToFit">kEnd ScaleToFit</a></td>
+ </tr>
+</table>
+
+### Return Value
+
+<a href="#Matrix">Matrix</a> mapping <a href="#SkMatrix_MakeRectToRect_src">src</a> to <a href="#SkMatrix_MakeRectToRect_dst">dst</a>
+
+### Example
+
+<div><fiddle-embed name="a1d6a6721b39350f81021f71a1b93208">
+
+#### Example Output
+
+~~~~
+src: 0, 0, 0, 0 dst: 0, 0, 0, 0
+[ 1.0000 0.0000 0.0000][ 0.0000 1.0000 0.0000][ 0.0000 0.0000 1.0000]
+src: 0, 0, 0, 0 dst: 5, 6, 8, 9
+[ 1.0000 0.0000 0.0000][ 0.0000 1.0000 0.0000][ 0.0000 0.0000 1.0000]
+src: 1, 2, 3, 4 dst: 0, 0, 0, 0
+[ 0.0000 0.0000 0.0000][ 0.0000 0.0000 0.0000][ 0.0000 0.0000 1.0000]
+src: 1, 2, 3, 4 dst: 5, 6, 8, 9
+[ 1.5000 0.0000 3.5000][ 0.0000 1.5000 3.0000][ 0.0000 0.0000 1.0000]
+~~~~
+
+</fiddle-embed></div>
+
+### See Also
+
+<a href="#SkMatrix_setRectToRect">setRectToRect</a> <a href="#SkMatrix_ScaleToFit">ScaleToFit</a> <a href="#SkMatrix_setPolyToPoly">setPolyToPoly</a> <a href="#SkRect_isEmpty">SkRect::isEmpty</a>
+
+---
+
+<a name="SkMatrix_setPolyToPoly"></a>
+## setPolyToPoly
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+bool setPolyToPoly(const SkPoint src[], const SkPoint dst[], int count)
+</pre>
+
+Sets <a href="#Matrix">Matrix</a> to map <a href="#SkMatrix_setPolyToPoly_src">src</a> to <a href="#SkMatrix_setPolyToPoly_dst">dst</a>. <a href="#SkMatrix_setPolyToPoly_count">count</a> must be zero or greater, and four or less.
+
+If <a href="#SkMatrix_setPolyToPoly_count">count</a> is zero, sets <a href="#Matrix">Matrix</a> to identity and returns true.
+If <a href="#SkMatrix_setPolyToPoly_count">count</a> is one, sets <a href="#Matrix">Matrix</a> to translate and returns true.
+If <a href="#SkMatrix_setPolyToPoly_count">count</a> is two or more, sets <a href="#Matrix">Matrix</a> to map <a href="#Point">Points</a> if possible; returns false
+if <a href="#Matrix">Matrix</a> cannot be constructed. If <a href="#SkMatrix_setPolyToPoly_count">count</a> is four, <a href="#Matrix">Matrix</a> may include
+perspective.
+
+### Parameters
+
+<table> <tr> <td><a name="SkMatrix_setPolyToPoly_src"> <code><strong>src </strong></code> </a></td> <td>
+<a href="#Point">Points</a> to map from</td>
+ </tr> <tr> <td><a name="SkMatrix_setPolyToPoly_dst"> <code><strong>dst </strong></code> </a></td> <td>
+<a href="#Point">Points</a> to map to</td>
+ </tr> <tr> <td><a name="SkMatrix_setPolyToPoly_count"> <code><strong>count </strong></code> </a></td> <td>
+number of <a href="#Point">Points</a> in <a href="#SkMatrix_setPolyToPoly_src">src</a> and <a href="#SkMatrix_setPolyToPoly_dst">dst</a></td>
+ </tr>
+</table>
+
+### Return Value
+
+true if <a href="#Matrix">Matrix</a> was constructed successfully
+
+### Example
+
+<div><fiddle-embed name="c851d1313e8909aaea4f0591699fdb7b"></fiddle-embed></div>
+
+### See Also
+
+<a href="#SkMatrix_setRectToRect">setRectToRect</a> <a href="#SkMatrix_MakeRectToRect">MakeRectToRect</a>
+
+---
+
+<a name="SkMatrix_invert"></a>
+## invert
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+bool SK_WARN_UNUSED_RESULT invert(SkMatrix* inverse) const
+</pre>
+
+Sets <a href="#SkMatrix_invert_inverse">inverse</a> to reciprocal matrix, returning true if <a href="#Matrix">Matrix</a> can be inverted.
+Geometrically, if <a href="#Matrix">Matrix</a> maps from source to destination, <a href="#SkMatrix_invert_inverse">inverse</a> <a href="#Matrix">Matrix</a>
+maps from destination to source. If <a href="#Matrix">Matrix</a> can not be inverted, <a href="#SkMatrix_invert_inverse">inverse</a> is
+unchanged.
+
+### Parameters
+
+<table> <tr> <td><a name="SkMatrix_invert_inverse"> <code><strong>inverse </strong></code> </a></td> <td>
+storage for inverted <a href="#Matrix">Matrix</a>; may be nullptr</td>
+ </tr>
+</table>
+
+### Return Value
+
+true if <a href="#Matrix">Matrix</a> can be inverted
+
+### Example
+
+<div><fiddle-embed name="10a10c5bf2ac7ec88e84204441fc83b6"></fiddle-embed></div>
+
+### See Also
+
+<a href="#SkMatrix_Concat">Concat</a>
+
+---
+
+<a name="SkMatrix_SetAffineIdentity"></a>
+## SetAffineIdentity
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+static void SetAffineIdentity(SkScalar affine[6])
+</pre>
+
+Fills <a href="#SkMatrix_SetAffineIdentity_affine">affine</a> with identity values in column major order.
+Sets <a href="#SkMatrix_SetAffineIdentity_affine">affine</a> to:
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+| 1 0 0 |
+| 0 1 0 |</pre>
+
+Affine 3x2 matrices in column major order are used by <a href="undocumented#OpenGL">OpenGL</a> and <a href="undocumented#XPS">XPS</a>.
+
+### Parameters
+
+<table> <tr> <td><a name="SkMatrix_SetAffineIdentity_affine"> <code><strong>affine </strong></code> </a></td> <td>
+storage for 3x2 <a href="#SkMatrix_SetAffineIdentity_affine">affine</a> matrix</td>
+ </tr>
+</table>
+
+### Example
+
+<div><fiddle-embed name="e10adbd0bcc940c5d4d872db0e78e892">
+
+#### Example Output
+
+~~~~
+ScaleX: 1 SkewY: 0 SkewX: 0 ScaleY: 1 TransX: 0 TransY: 0
+~~~~
+
+</fiddle-embed></div>
+
+### See Also
+
+<a href="#SkMatrix_setAffine">setAffine</a> <a href="#SkMatrix_asAffine">asAffine</a>
+
+---
+
+<a name="SkMatrix_asAffine"></a>
+## asAffine
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+bool SK_WARN_UNUSED_RESULT asAffine(SkScalar affine[6]) const
+</pre>
+
+Fills <a href="#SkMatrix_asAffine_affine">affine</a> in column major order. Sets <a href="#SkMatrix_asAffine_affine">affine</a> to:
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+| scale-x skew-x translate-x |
+| skew-y scale-y translate-y |</pre>
+
+If <a href="#Matrix">Matrix</a> contains perspective, returns false and leaves <a href="#SkMatrix_asAffine_affine">affine</a> unchanged.
+
+### Parameters
+
+<table> <tr> <td><a name="SkMatrix_asAffine_affine"> <code><strong>affine </strong></code> </a></td> <td>
+storage for 3x2 <a href="#SkMatrix_asAffine_affine">affine</a> matrix; may be nullptr</td>
+ </tr>
+</table>
+
+### Return Value
+
+true if <a href="#Matrix">Matrix</a> does not contain perspective
+
+### Example
+
+<div><fiddle-embed name="752e4a48ed1dae05765a2499c390f277">
+
+#### Example Output
+
+~~~~
+ScaleX: 2 SkewY: 5 SkewX: 3 ScaleY: 6 TransX: 4 TransY: 7
+~~~~
+
+</fiddle-embed></div>
+
+### See Also
+
+<a href="#SkMatrix_setAffine">setAffine</a> <a href="#SkMatrix_SetAffineIdentity">SetAffineIdentity</a>
+
+---
+
+<a name="SkMatrix_setAffine"></a>
+## setAffine
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+void setAffine(const SkScalar affine[6])
+</pre>
+
+Sets <a href="#Matrix">Matrix</a> to <a href="#SkMatrix_setAffine_affine">affine</a> values, passed in column major order. Given <a href="#SkMatrix_setAffine_affine">affine</a>,
+column, then row, as:
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+| scale-x skew-x translate-x |
+| skew-y scale-y translate-y |</pre>
+
+<a href="#Matrix">Matrix</a> is <a href="#SkMatrix_set">set</a>, row, then column, to:
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+| scale-x skew-x translate-x |
+| skew-y scale-y translate-y |
+| 0 0 1 |</pre>
+
+### Parameters
+
+<table> <tr> <td><a name="SkMatrix_setAffine_affine"> <code><strong>affine </strong></code> </a></td> <td>
+3x2 <a href="#SkMatrix_setAffine_affine">affine</a> matrix</td>
+ </tr>
+</table>
+
+### Example
+
+<div><fiddle-embed name="403370bd53526f59020a7141955d70b0">
+
+#### Example Output
+
+~~~~
+ScaleX: 2 SkewY: 5 SkewX: 3 ScaleY: 6 TransX: 4 TransY: 7
+[ 2.0000 3.0000 4.0000][ 5.0000 6.0000 7.0000][ 0.0000 0.0000 1.0000]
+~~~~
+
+</fiddle-embed></div>
+
+### See Also
+
+<a href="#SkMatrix_asAffine">asAffine</a> <a href="#SkMatrix_SetAffineIdentity">SetAffineIdentity</a>
+
+---
+
+<a name="SkMatrix_mapPoints"></a>
+## mapPoints
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+void mapPoints(SkPoint dst[], const SkPoint src[], int count) const
+</pre>
+
+Maps <a href="#SkMatrix_mapPoints_src">src</a> <a href="undocumented#Point">Point</a> array of length <a href="#SkMatrix_mapPoints_count">count</a> to <a href="#SkMatrix_mapPoints_dst">dst</a> <a href="undocumented#Point">Point</a> array of equal or greater
+length. <a href="#Point">Points</a> are mapped by multiplying each <a href="undocumented#Point">Point</a> by <a href="#Matrix">Matrix</a>. Given:
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+ | A B C | | x |
+Matrix = | D E F |, pt = | y |
+ | G H I | | 1 |</pre>
+
+where
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+for (i = 0; i < count; ++i) {
+ x = src[i].fX
+ y = src[i].fY
+}</pre>
+
+each <a href="#SkMatrix_mapPoints_dst">dst</a> <a href="undocumented#Point">Point</a> is computed as:
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+ |A B C| |x| Ax+By+C Dx+Ey+F
+Matrix * pt = |D E F| |y| = |Ax+By+C Dx+Ey+F Gx+Hy+I| = ------- , -------
+ |G H I| |1| Gx+Hy+I Gx+Hy+I</pre>
+
+<a href="#SkMatrix_mapPoints_src">src</a> and <a href="#SkMatrix_mapPoints_dst">dst</a> may point to the same storage.
+
+### Parameters
+
+<table> <tr> <td><a name="SkMatrix_mapPoints_dst"> <code><strong>dst </strong></code> </a></td> <td>
+storage for mapped <a href="#Point">Points</a></td>
+ </tr> <tr> <td><a name="SkMatrix_mapPoints_src"> <code><strong>src </strong></code> </a></td> <td>
+<a href="#Point">Points</a> to transform</td>
+ </tr> <tr> <td><a name="SkMatrix_mapPoints_count"> <code><strong>count </strong></code> </a></td> <td>
+number of <a href="#Point">Points</a> to transform</td>
+ </tr>
+</table>
+
+### Example
+
+<div><fiddle-embed name="f99dcb00296d0c56b6c0e178e94b3534"></fiddle-embed></div>
+
+### See Also
+
+<a href="#SkMatrix_mapPointsWithStride">mapPointsWithStride</a> <a href="#SkMatrix_mapXY">mapXY</a> <a href="#SkMatrix_mapHomogeneousPoints">mapHomogeneousPoints</a> <a href="#SkMatrix_mapVectors">mapVectors</a>
+
+---
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+void mapPoints(SkPoint pts[], int count) const
+</pre>
+
+Maps <a href="#SkMatrix_mapPoints_2_pts">pts</a> <a href="undocumented#Point">Point</a> array of length <a href="#SkMatrix_mapPoints_2_count">count</a> in place. <a href="#Point">Points</a> are mapped by multiplying
+each <a href="undocumented#Point">Point</a> by <a href="#Matrix">Matrix</a>. Given:
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+ | A B C | | x |
+Matrix = | D E F |, pt = | y |
+ | G H I | | 1 |</pre>
+
+where
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+for (i = 0; i < count; ++i) {
+ x = pts[i].fX
+ y = pts[i].fY
+}</pre>
+
+each resulting <a href="#SkMatrix_mapPoints_2_pts">pts</a> <a href="undocumented#Point">Point</a> is computed as:
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+ |A B C| |x| Ax+By+C Dx+Ey+F
+Matrix * pt = |D E F| |y| = |Ax+By+C Dx+Ey+F Gx+Hy+I| = ------- , -------
+ |G H I| |1| Gx+Hy+I Gx+Hy+I</pre>
+
+### Parameters
+
+<table> <tr> <td><a name="SkMatrix_mapPoints_2_pts"> <code><strong>pts </strong></code> </a></td> <td>
+storage for mapped <a href="#Point">Points</a></td>
+ </tr> <tr> <td><a name="SkMatrix_mapPoints_2_count"> <code><strong>count </strong></code> </a></td> <td>
+number of <a href="#Point">Points</a> to transform</td>
+ </tr>
+</table>
+
+### Example
+
+<div><fiddle-embed name="428ca171ae3bd0d3f992458ac598b97b"></fiddle-embed></div>
+
+### See Also
+
+<a href="#SkMatrix_mapPointsWithStride">mapPointsWithStride</a> <a href="#SkMatrix_mapXY">mapXY</a> <a href="#SkMatrix_mapHomogeneousPoints">mapHomogeneousPoints</a> <a href="#SkMatrix_mapVectors">mapVectors</a>
+
+---
+
+<a name="SkMatrix_mapPointsWithStride"></a>
+## mapPointsWithStride
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+void mapPointsWithStride(SkPoint pts[], size_t stride, int count) const
+</pre>
+
+Maps <a href="#SkMatrix_mapPointsWithStride_count">count</a> <a href="#SkMatrix_mapPointsWithStride_pts">pts</a>, skipping <a href="#SkMatrix_mapPointsWithStride_stride">stride</a> bytes to advance from one <a href="undocumented#Point">Point</a> to the next.
+<a href="#Point">Points</a> are mapped by multiplying each <a href="undocumented#Point">Point</a> by <a href="#Matrix">Matrix</a>. Given:
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+ | A B C | | x |
+Matrix = | D E F |, pt = | y |
+ | G H I | | 1 |</pre>
+
+each resulting <a href="#SkMatrix_mapPointsWithStride_pts">pts</a> <a href="undocumented#Point">Point</a> is computed as:
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+ |A B C| |x| Ax+By+C Dx+Ey+F
+Matrix * pt = |D E F| |y| = |Ax+By+C Dx+Ey+F Gx+Hy+I| = ------- , -------
+ |G H I| |1| Gx+Hy+I Gx+Hy+I</pre>
+
+### Parameters
+
+<table> <tr> <td><a name="SkMatrix_mapPointsWithStride_pts"> <code><strong>pts </strong></code> </a></td> <td>
+storage for mapped <a href="#Point">Points</a></td>
+ </tr> <tr> <td><a name="SkMatrix_mapPointsWithStride_stride"> <code><strong>stride </strong></code> </a></td> <td>
+size of record starting with <a href="undocumented#Point">Point</a>, in bytes</td>
+ </tr> <tr> <td><a name="SkMatrix_mapPointsWithStride_count"> <code><strong>count </strong></code> </a></td> <td>
+number of <a href="#Point">Points</a> to transform</td>
+ </tr>
+</table>
+
+### Example
+
+<div><fiddle-embed name="02c50c7bb5d5dd1fe7e54b0d3bf64c2a"></fiddle-embed></div>
+
+### See Also
+
+<a href="#SkMatrix_mapPoints">mapPoints</a> <a href="#SkMatrix_mapXY">mapXY</a> <a href="#SkMatrix_mapHomogeneousPoints">mapHomogeneousPoints</a> <a href="#SkMatrix_mapVectors">mapVectors</a>
+
+---
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+void mapPointsWithStride(SkPoint dst[], const SkPoint src[], size_t stride,
+ int count) const
+</pre>
+
+Maps <a href="#SkMatrix_mapPointsWithStride_2_src">src</a> <a href="undocumented#Point">Point</a> array of length <a href="#SkMatrix_mapPointsWithStride_2_count">count</a> to <a href="#SkMatrix_mapPointsWithStride_2_dst">dst</a> <a href="undocumented#Point">Point</a> array, skipping <a href="#SkMatrix_mapPointsWithStride_2_stride">stride</a> bytes
+to advance from one <a href="undocumented#Point">Point</a> to the next.
+<a href="#Point">Points</a> are mapped by multiplying each <a href="undocumented#Point">Point</a> by <a href="#Matrix">Matrix</a>. Given:
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+ | A B C | | x |
+Matrix = | D E F |, src = | y |
+ | G H I | | 1 |</pre>
+
+each resulting <a href="#SkMatrix_mapPointsWithStride_2_dst">dst</a> <a href="undocumented#Point">Point</a> is computed as:
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+ |A B C| |x| Ax+By+C Dx+Ey+F
+Matrix * pt = |D E F| |y| = |Ax+By+C Dx+Ey+F Gx+Hy+I| = ------- , -------
+ |G H I| |1| Gx+Hy+I Gx+Hy+I</pre>
+
+### Parameters
+
+<table> <tr> <td><a name="SkMatrix_mapPointsWithStride_2_dst"> <code><strong>dst </strong></code> </a></td> <td>
+storage for mapped <a href="#Point">Points</a></td>
+ </tr> <tr> <td><a name="SkMatrix_mapPointsWithStride_2_src"> <code><strong>src </strong></code> </a></td> <td>
+<a href="#Point">Points</a> to transform</td>
+ </tr> <tr> <td><a name="SkMatrix_mapPointsWithStride_2_stride"> <code><strong>stride </strong></code> </a></td> <td>
+size of record starting with <a href="undocumented#Point">Point</a>, in bytes</td>
+ </tr> <tr> <td><a name="SkMatrix_mapPointsWithStride_2_count"> <code><strong>count </strong></code> </a></td> <td>
+number of <a href="#Point">Points</a> to transform</td>
+ </tr>
+</table>
+
+### Example
+
+<div><fiddle-embed name="08e32de52131e6859db16729b2e56e4e"></fiddle-embed></div>
+
+### See Also
+
+<a href="#SkMatrix_mapPoints">mapPoints</a> <a href="#SkMatrix_mapXY">mapXY</a> <a href="#SkMatrix_mapHomogeneousPoints">mapHomogeneousPoints</a> <a href="#SkMatrix_mapVectors">mapVectors</a>
+
+---
+
+<a name="SkMatrix_mapHomogeneousPoints"></a>
+## mapHomogeneousPoints
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+void mapHomogeneousPoints(SkPoint3 dst[], const SkPoint3 src[], int count) const
+</pre>
+
+Maps <a href="#SkMatrix_mapHomogeneousPoints_src">src</a> <a href="undocumented#Point3">Point3</a> array of length <a href="#SkMatrix_mapHomogeneousPoints_count">count</a> to <a href="#SkMatrix_mapHomogeneousPoints_dst">dst</a> <a href="undocumented#Point3">Point3</a> array, which must of length <a href="#SkMatrix_mapHomogeneousPoints_count">count</a> or
+greater. <a href="undocumented#Point3">Point3</a> array is mapped by multiplying each <a href="undocumented#Point3">Point3</a> by <a href="#Matrix">Matrix</a>. Given:
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+ | A B C | | x |
+Matrix = | D E F |, src = | y |
+ | G H I | | z |</pre>
+
+each resulting <a href="#SkMatrix_mapHomogeneousPoints_dst">dst</a> <a href="undocumented#Point">Point</a> is computed as:
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+ |A B C| |x|
+Matrix * src = |D E F| |y| = |Ax+By+Cz Dx+Ey+Fz Gx+Hy+Iz|
+ |G H I| |z|</pre>
+
+### Parameters
+
+<table> <tr> <td><a name="SkMatrix_mapHomogeneousPoints_dst"> <code><strong>dst </strong></code> </a></td> <td>
+storage for mapped <a href="undocumented#Point3">Point3</a> array</td>
+ </tr> <tr> <td><a name="SkMatrix_mapHomogeneousPoints_src"> <code><strong>src </strong></code> </a></td> <td>
+<a href="undocumented#Point3">Point3</a> array to transform</td>
+ </tr> <tr> <td><a name="SkMatrix_mapHomogeneousPoints_count"> <code><strong>count </strong></code> </a></td> <td>
+items in <a href="undocumented#Point3">Point3</a> array to transform</td>
+ </tr>
+</table>
+
+### Example
+
+<div><fiddle-embed name="0d8c7aa7249048f2b83d32cf13f88560"></fiddle-embed></div>
+
+### See Also
+
+<a href="#SkMatrix_mapPoints">mapPoints</a> <a href="#SkMatrix_mapXY">mapXY</a> <a href="#SkMatrix_mapPointsWithStride">mapPointsWithStride</a> <a href="#SkMatrix_mapVectors">mapVectors</a>
+
+---
+
+<a name="SkMatrix_mapXY"></a>
+## mapXY
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+void mapXY(SkScalar x, SkScalar y, SkPoint* result) const
+</pre>
+
+Maps <a href="undocumented#Point">Point</a> (<a href="#SkMatrix_mapXY_x">x</a>, <a href="#SkMatrix_mapXY_y">y</a>) to <a href="#SkMatrix_mapXY_result">result</a>. <a href="undocumented#Point">Point</a> is mapped by multiplying by <a href="#Matrix">Matrix</a>. Given:
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+ | A B C | | x |
+Matrix = | D E F |, pt = | y |
+ | G H I | | 1 |</pre>
+
+<a href="#SkMatrix_mapXY_result">result</a> is computed as:
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+ |A B C| |x| Ax+By+C Dx+Ey+F
+Matrix * pt = |D E F| |y| = |Ax+By+C Dx+Ey+F Gx+Hy+I| = ------- , -------
+ |G H I| |1| Gx+Hy+I Gx+Hy+I</pre>
+
+### Parameters
+
+<table> <tr> <td><a name="SkMatrix_mapXY_x"> <code><strong>x </strong></code> </a></td> <td>
+x-coordinate of <a href="undocumented#Point">Point</a> to map</td>
+ </tr> <tr> <td><a name="SkMatrix_mapXY_y"> <code><strong>y </strong></code> </a></td> <td>
+y-coordinate of <a href="undocumented#Point">Point</a> to map</td>
+ </tr> <tr> <td><a name="SkMatrix_mapXY_result"> <code><strong>result </strong></code> </a></td> <td>
+storage for mapped <a href="undocumented#Point">Point</a></td>
+ </tr>
+</table>
+
+### Example
+
+<div><fiddle-embed name="9e50185d502dc6903783679a84106089"></fiddle-embed></div>
+
+### See Also
+
+<a href="#SkMatrix_mapPoints">mapPoints</a> <a href="#SkMatrix_mapPointsWithStride">mapPointsWithStride</a> <a href="#SkMatrix_mapVectors">mapVectors</a>
+
+---
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+SkPoint mapXY(SkScalar x, SkScalar y) const
+</pre>
+
+Returns <a href="undocumented#Point">Point</a> (<a href="#SkMatrix_mapXY_2_x">x</a>, <a href="#SkMatrix_mapXY_2_y">y</a>) multiplied by <a href="#Matrix">Matrix</a>. Given:
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+ | A B C | | x |
+Matrix = | D E F |, pt = | y |
+ | G H I | | 1 |</pre>
+
+result is computed as:
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+ |A B C| |x| Ax+By+C Dx+Ey+F
+Matrix * pt = |D E F| |y| = |Ax+By+C Dx+Ey+F Gx+Hy+I| = ------- , -------
+ |G H I| |1| Gx+Hy+I Gx+Hy+I</pre>
+
+### Parameters
+
+<table> <tr> <td><a name="SkMatrix_mapXY_2_x"> <code><strong>x </strong></code> </a></td> <td>
+x-coordinate of <a href="undocumented#Point">Point</a> to map</td>
+ </tr> <tr> <td><a name="SkMatrix_mapXY_2_y"> <code><strong>y </strong></code> </a></td> <td>
+y-coordinate of <a href="undocumented#Point">Point</a> to map</td>
+ </tr>
+</table>
+
+### Return Value
+
+mapped <a href="undocumented#Point">Point</a>
+
+### Example
+
+<div><fiddle-embed name="b1ead09c67a177ab8eace12b061610a7"></fiddle-embed></div>
+
+### See Also
+
+<a href="#SkMatrix_mapPoints">mapPoints</a> <a href="#SkMatrix_mapPointsWithStride">mapPointsWithStride</a> <a href="#SkMatrix_mapVectors">mapVectors</a>
+
+---
+
+<a name="SkMatrix_mapVectors"></a>
+## mapVectors
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+void mapVectors(SkVector dst[], const SkVector src[], int count) const
+</pre>
+
+Maps <a href="#SkMatrix_mapVectors_src">src</a> <a href="undocumented#Vector">Vector</a> array of length <a href="#SkMatrix_mapVectors_count">count</a> to <a href="undocumented#Vector">Vector</a> <a href="undocumented#Point">Point</a> array of equal or greater
+length. <a href="#Vector">Vectors</a> are mapped by multiplying each <a href="undocumented#Vector">Vector</a> by <a href="#Matrix">Matrix</a>, treating
+<a href="#Matrix">Matrix</a> translation as zero. Given:
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+ | A B 0 | | x |
+Matrix = | D E 0 |, src = | y |
+ | G H I | | 1 |</pre>
+
+where
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+for (i = 0; i < count; ++i) {
+ x = src[i].fX
+ y = src[i].fY
+}</pre>
+
+each <a href="#SkMatrix_mapVectors_dst">dst</a> <a href="undocumented#Vector">Vector</a> is computed as:
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+ |A B 0| |x| Ax+By Dx+Ey
+Matrix * src = |D E 0| |y| = |Ax+By Dx+Ey Gx+Hy+I| = ------- , -------
+ |G H I| |1| Gx+Hy+I Gx+Hy+I</pre>
+
+<a href="#SkMatrix_mapVectors_src">src</a> and <a href="#SkMatrix_mapVectors_dst">dst</a> may point to the same storage.
+
+### Parameters
+
+<table> <tr> <td><a name="SkMatrix_mapVectors_dst"> <code><strong>dst </strong></code> </a></td> <td>
+storage for mapped <a href="#Vector">Vectors</a></td>
+ </tr> <tr> <td><a name="SkMatrix_mapVectors_src"> <code><strong>src </strong></code> </a></td> <td>
+<a href="#Vector">Vectors</a> to transform</td>
+ </tr> <tr> <td><a name="SkMatrix_mapVectors_count"> <code><strong>count </strong></code> </a></td> <td>
+number of <a href="#Vector">Vectors</a> to transform</td>
+ </tr>
+</table>
+
+### Example
+
+<div><fiddle-embed name="918a9778c3d7d5cb306692784399f6dc"></fiddle-embed></div>
+
+### See Also
+
+<a href="#SkMatrix_mapVector">mapVector</a> <a href="#SkMatrix_mapPoints">mapPoints</a> <a href="#SkMatrix_mapPointsWithStride">mapPointsWithStride</a> <a href="#SkMatrix_mapXY">mapXY</a>
+
+---
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+void mapVectors(SkVector vecs[], int count) const
+</pre>
+
+Maps <a href="#SkMatrix_mapVectors_2_vecs">vecs</a> <a href="undocumented#Vector">Vector</a> array of length <a href="#SkMatrix_mapVectors_2_count">count</a> in place, multiplying each <a href="undocumented#Vector">Vector</a> by
+<a href="#Matrix">Matrix</a>, treating <a href="#Matrix">Matrix</a> translation as zero. Given:
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+ | A B 0 | | x |
+Matrix = | D E 0 |, vec = | y |
+ | G H I | | 1 |</pre>
+
+where
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+for (i = 0; i < count; ++i) {
+ x = vecs[i].fX
+ y = vecs[i].fY
+}</pre>
+
+each result <a href="undocumented#Vector">Vector</a> is computed as:
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+ |A B 0| |x| Ax+By Dx+Ey
+Matrix * vec = |D E 0| |y| = |Ax+By Dx+Ey Gx+Hy+I| = ------- , -------
+ |G H I| |1| Gx+Hy+I Gx+Hy+I</pre>
+
+### Parameters
+
+<table> <tr> <td><a name="SkMatrix_mapVectors_2_vecs"> <code><strong>vecs </strong></code> </a></td> <td>
+<a href="#Vector">Vectors</a> to transform, and storage for mapped <a href="#Vector">Vectors</a></td>
+ </tr> <tr> <td><a name="SkMatrix_mapVectors_2_count"> <code><strong>count </strong></code> </a></td> <td>
+number of <a href="#Vector">Vectors</a> to transform</td>
+ </tr>
+</table>
+
+### Example
+
+<div><fiddle-embed name="5754501a00a1323e76353fb53153e939"></fiddle-embed></div>
+
+### See Also
+
+<a href="#SkMatrix_mapVector">mapVector</a> <a href="#SkMatrix_mapPoints">mapPoints</a> <a href="#SkMatrix_mapPointsWithStride">mapPointsWithStride</a> <a href="#SkMatrix_mapXY">mapXY</a>
+
+---
+
+<a name="SkMatrix_mapVector"></a>
+## mapVector
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+void mapVector(SkScalar dx, SkScalar dy, SkVector* result) const
+</pre>
+
+Maps <a href="undocumented#Vector">Vector</a> (x, y) to <a href="#SkMatrix_mapVector_result">result</a>. <a href="undocumented#Vector">Vector</a> is mapped by multiplying by <a href="#Matrix">Matrix</a>,
+treating <a href="#Matrix">Matrix</a> translation as zero. Given:
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+ | A B 0 | | dx |
+Matrix = | D E 0 |, vec = | dy |
+ | G H I | | 1 |</pre>
+
+each <a href="#SkMatrix_mapVector_result">result</a> <a href="undocumented#Vector">Vector</a> is computed as:
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+ |A B 0| |dx| A*dx+B*dy D*dx+E*dy
+Matrix * vec = |D E 0| |dy| = |A*dx+B*dy D*dx+E*dy G*dx+H*dy+I| = ----------- , -----------
+ |G H I| | 1| G*dx+H*dy+I G*dx+*dHy+I</pre>
+
+### Parameters
+
+<table> <tr> <td><a name="SkMatrix_mapVector_dx"> <code><strong>dx </strong></code> </a></td> <td>
+x-coordinate of <a href="undocumented#Vector">Vector</a> to map</td>
+ </tr> <tr> <td><a name="SkMatrix_mapVector_dy"> <code><strong>dy </strong></code> </a></td> <td>
+y-coordinate of <a href="undocumented#Vector">Vector</a> to map</td>
+ </tr> <tr> <td><a name="SkMatrix_mapVector_result"> <code><strong>result </strong></code> </a></td> <td>
+storage for mapped <a href="undocumented#Vector">Vector</a></td>
+ </tr>
+</table>
+
+### Example
+
+<div><fiddle-embed name="aed143fc6cd0bce4ed029b98d1e61f2d"></fiddle-embed></div>
+
+### See Also
+
+<a href="#SkMatrix_mapVectors">mapVectors</a> <a href="#SkMatrix_mapPoints">mapPoints</a> <a href="#SkMatrix_mapPointsWithStride">mapPointsWithStride</a> <a href="#SkMatrix_mapXY">mapXY</a>
+
+---
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+SkVector mapVector(SkScalar dx, SkScalar dy) const
+</pre>
+
+Returns <a href="undocumented#Vector">Vector</a> (x, y) multiplied by <a href="#Matrix">Matrix</a>, treating <a href="#Matrix">Matrix</a> translation as zero.
+Given:
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+ | A B 0 | | dx |
+Matrix = | D E 0 |, vec = | dy |
+ | G H I | | 1 |</pre>
+
+each result <a href="undocumented#Vector">Vector</a> is computed as:
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+ |A B 0| |dx| A*dx+B*dy D*dx+E*dy
+Matrix * vec = |D E 0| |dy| = |A*dx+B*dy D*dx+E*dy G*dx+H*dy+I| = ----------- , -----------
+ |G H I| | 1| G*dx+H*dy+I G*dx+*dHy+I</pre>
+
+### Parameters
+
+<table> <tr> <td><a name="SkMatrix_mapVector_2_dx"> <code><strong>dx </strong></code> </a></td> <td>
+x-coordinate of <a href="undocumented#Vector">Vector</a> to map</td>
+ </tr> <tr> <td><a name="SkMatrix_mapVector_2_dy"> <code><strong>dy </strong></code> </a></td> <td>
+y-coordinate of <a href="undocumented#Vector">Vector</a> to map</td>
+ </tr>
+</table>
+
+### Return Value
+
+mapped <a href="undocumented#Vector">Vector</a>
+
+### Example
+
+<div><fiddle-embed name="8bf1518db3f369696cd3065b541a8bd7"></fiddle-embed></div>
+
+### See Also
+
+<a href="#SkMatrix_mapVectors">mapVectors</a> <a href="#SkMatrix_mapPoints">mapPoints</a> <a href="#SkMatrix_mapPointsWithStride">mapPointsWithStride</a> <a href="#SkMatrix_mapXY">mapXY</a>
+
+---
+
+<a name="SkMatrix_mapRect"></a>
+## mapRect
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+bool mapRect(SkRect* dst, const SkRect& src) const
+</pre>
+
+Sets <a href="#SkMatrix_mapRect_dst">dst</a> to bounds of <a href="#SkMatrix_mapRect_src">src</a> corners mapped by <a href="#Matrix">Matrix</a>.
+Returns true if mapped corners are <a href="#SkMatrix_mapRect_dst">dst</a> corners.
+
+Returned value is the same as calling <a href="#SkMatrix_rectStaysRect">rectStaysRect</a>.
+
+### Parameters
+
+<table> <tr> <td><a name="SkMatrix_mapRect_dst"> <code><strong>dst </strong></code> </a></td> <td>
+storage for bounds of mapped <a href="#Point">Points</a></td>
+ </tr> <tr> <td><a name="SkMatrix_mapRect_src"> <code><strong>src </strong></code> </a></td> <td>
+<a href="SkRect_Reference#Rect">Rect</a> to map</td>
+ </tr>
+</table>
+
+### Return Value
+
+true if <a href="#SkMatrix_mapRect_dst">dst</a> is equivalent to mapped <a href="#SkMatrix_mapRect_src">src</a>
+
+### Example
+
+<div><fiddle-embed name="dbcf928b035a31ca69c99392e2e2cca9"></fiddle-embed></div>
+
+### See Also
+
+<a href="#SkMatrix_mapPoints">mapPoints</a> <a href="#SkMatrix_rectStaysRect">rectStaysRect</a>
+
+---
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+bool mapRect(SkRect* rect) const
+</pre>
+
+Sets <a href="#SkMatrix_mapRect_2_rect">rect</a> to bounds of <a href="#SkMatrix_mapRect_2_rect">rect</a> corners mapped by <a href="#Matrix">Matrix</a>.
+Returns true if mapped corners are computed <a href="#SkMatrix_mapRect_2_rect">rect</a> corners.
+
+Returned value is the same as calling <a href="#SkMatrix_rectStaysRect">rectStaysRect</a>.
+
+### Parameters
+
+<table> <tr> <td><a name="SkMatrix_mapRect_2_rect"> <code><strong>rect </strong></code> </a></td> <td>
+rectangle to map, and storage for bounds of mapped corners</td>
+ </tr>
+</table>
+
+### Return Value
+
+true if result is equivalent to mapped src
+
+### Example
+
+<div><fiddle-embed name="5fafd0bd23d1ed37425b970b4a3c6cc9"></fiddle-embed></div>
+
+### See Also
+
+<a href="#SkMatrix_mapRectScaleTranslate">mapRectScaleTranslate</a> <a href="#SkMatrix_mapPoints">mapPoints</a> <a href="#SkMatrix_rectStaysRect">rectStaysRect</a>
+
+---
+
+<a name="SkMatrix_mapRectToQuad"></a>
+## mapRectToQuad
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+void mapRectToQuad(SkPoint dst[4], const SkRect& rect) const
+</pre>
+
+Maps four corners of <a href="#SkMatrix_mapRectToQuad_rect">rect</a> to <a href="#SkMatrix_mapRectToQuad_dst">dst</a>. <a href="#Point">Points</a> are mapped by multiplying each
+<a href="#SkMatrix_mapRectToQuad_rect">rect</a> corner by <a href="#Matrix">Matrix</a>. <a href="#SkMatrix_mapRectToQuad_rect">rect</a> corner is processed in this order:
+(<a href="#SkMatrix_mapRectToQuad_rect">rect</a>.fLeft, <a href="#SkMatrix_mapRectToQuad_rect">rect</a>.fTop), (<a href="#SkMatrix_mapRectToQuad_rect">rect</a>.fRight, <a href="#SkMatrix_mapRectToQuad_rect">rect</a>.fTop), (<a href="#SkMatrix_mapRectToQuad_rect">rect</a>.fRight, <a href="#SkMatrix_mapRectToQuad_rect">rect</a>.fBottom),
+(<a href="#SkMatrix_mapRectToQuad_rect">rect</a>.fLeft, <a href="#SkMatrix_mapRectToQuad_rect">rect</a>.fBottom).
+
+<a href="#SkMatrix_mapRectToQuad_rect">rect</a> may be empty: <a href="#SkMatrix_mapRectToQuad_rect">rect</a>.fLeft may be greater than or equal to <a href="#SkMatrix_mapRectToQuad_rect">rect</a>.fRight;
+<a href="#SkMatrix_mapRectToQuad_rect">rect</a>.fTop may be greater than or equal to <a href="#SkMatrix_mapRectToQuad_rect">rect</a>.fBottom.
+
+Given:
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+ | A B C | | x |
+Matrix = | D E F |, pt = | y |
+ | G H I | | 1 |</pre>
+
+where pt is initialized from each of (<a href="#SkMatrix_mapRectToQuad_rect">rect</a>.fLeft, <a href="#SkMatrix_mapRectToQuad_rect">rect</a>.fTop),
+(<a href="#SkMatrix_mapRectToQuad_rect">rect</a>.fRight, <a href="#SkMatrix_mapRectToQuad_rect">rect</a>.fTop), (<a href="#SkMatrix_mapRectToQuad_rect">rect</a>.fRight, <a href="#SkMatrix_mapRectToQuad_rect">rect</a>.fBottom), (<a href="#SkMatrix_mapRectToQuad_rect">rect</a>.fLeft, <a href="#SkMatrix_mapRectToQuad_rect">rect</a>.fBottom),
+each <a href="#SkMatrix_mapRectToQuad_dst">dst</a> <a href="undocumented#Point">Point</a> is computed as:
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+ |A B C| |x| Ax+By+C Dx+Ey+F
+Matrix * pt = |D E F| |y| = |Ax+By+C Dx+Ey+F Gx+Hy+I| = ------- , -------
+ |G H I| |1| Gx+Hy+I Gx+Hy+I</pre>
+
+### Parameters
+
+<table> <tr> <td><a name="SkMatrix_mapRectToQuad_dst"> <code><strong>dst </strong></code> </a></td> <td>
+storage for mapped corner <a href="#Point">Points</a></td>
+ </tr> <tr> <td><a name="SkMatrix_mapRectToQuad_rect"> <code><strong>rect </strong></code> </a></td> <td>
+<a href="SkRect_Reference#Rect">Rect</a> to map</td>
+ </tr>
+</table>
+
+### Example
+
+<div><fiddle-embed name="3bf9404624735d7cf34b47b9c7b27bcc"></fiddle-embed></div>
+
+### See Also
+
+<a href="#SkMatrix_mapRect">mapRect</a> <a href="#SkMatrix_mapRectScaleTranslate">mapRectScaleTranslate</a>
+
+---
+
+<a name="SkMatrix_mapRectScaleTranslate"></a>
+## mapRectScaleTranslate
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+void mapRectScaleTranslate(SkRect* dst, const SkRect& src) const
+</pre>
+
+Sets <a href="#SkMatrix_mapRectScaleTranslate_dst">dst</a> to bounds of <a href="#SkMatrix_mapRectScaleTranslate_src">src</a> corners mapped by <a href="#Matrix">Matrix</a>. If matrix contains
+elements other than scale or translate: asserts if <a href="undocumented#SK_DEBUG">SK DEBUG</a> is defined;
+otherwise, results are undefined.
+
+### Parameters
+
+<table> <tr> <td><a name="SkMatrix_mapRectScaleTranslate_dst"> <code><strong>dst </strong></code> </a></td> <td>
+storage for bounds of mapped <a href="#Point">Points</a></td>
+ </tr> <tr> <td><a name="SkMatrix_mapRectScaleTranslate_src"> <code><strong>src </strong></code> </a></td> <td>
+<a href="SkRect_Reference#Rect">Rect</a> to map</td>
+ </tr>
+</table>
+
+### Example
+
+<div><fiddle-embed name="62bc26989c2b4c2a54d516596a71dd97"></fiddle-embed></div>
+
+### See Also
+
+<a href="#SkMatrix_mapRect">mapRect</a> <a href="#SkMatrix_mapRectToQuad">mapRectToQuad</a> <a href="#SkMatrix_isScaleTranslate">isScaleTranslate</a> <a href="#SkMatrix_rectStaysRect">rectStaysRect</a>
+
+---
+
+<a name="SkMatrix_mapRadius"></a>
+## mapRadius
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+SkScalar mapRadius(SkScalar radius) const
+</pre>
+
+Returns geometric mean <a href="#SkMatrix_mapRadius_radius">radius</a> of ellipse formed by constructing <a href="undocumented#Circle">Circle</a> of
+size <a href="#SkMatrix_mapRadius_radius">radius</a>, and mapping constructed <a href="undocumented#Circle">Circle</a> with <a href="#Matrix">Matrix</a>. The result squared is
+equal to the major axis length times the minor axis length.
+Result is not meaningful if <a href="#Matrix">Matrix</a> contains perspective elements.
+
+### Parameters
+
+<table> <tr> <td><a name="SkMatrix_mapRadius_radius"> <code><strong>radius </strong></code> </a></td> <td>
+<a href="undocumented#Circle">Circle</a> size to map</td>
+ </tr>
+</table>
+
+### Return Value
+
+average mapped <a href="#SkMatrix_mapRadius_radius">radius</a>
+
+### Example
+
+<div><fiddle-embed name="6d6f2082fcf59d9f02bfb1758b87db69"><div>The area enclosed by a square with sides equal to mappedRadius is the same as
+the area enclosed by the ellipse major and minor axes.</div></fiddle-embed></div>
+
+### See Also
+
+<a href="#SkMatrix_mapVector">mapVector</a>
+
+---
+
+<a name="SkMatrix_isFixedStepInX"></a>
+## isFixedStepInX
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+bool isFixedStepInX() const
+</pre>
+
+Returns true if a unit step in x at some y mapped through <a href="#Matrix">Matrix</a> can be
+represented by a constant <a href="undocumented#Vector">Vector</a>. Returns true if <a href="#SkMatrix_getType">getType</a> returns <a href="#SkMatrix_kIdentity_Mask">kIdentity Mask</a>,
+or combinations of: <a href="#SkMatrix_kTranslate_Mask">kTranslate Mask</a>, <a href="#SkMatrix_kScale_Mask">kScale Mask</a>, and <a href="#SkMatrix_kAffine_Mask">kAffine Mask</a>.
+
+May return true if <a href="#SkMatrix_getType">getType</a> returns <a href="#SkMatrix_kPerspective_Mask">kPerspective Mask</a>, but only when <a href="#Matrix">Matrix</a>
+does not include rotation or skewing along the y-axis.
+
+### Return Value
+
+true if <a href="#Matrix">Matrix</a> does not have complex perspective
+
+### Example
+
+<div><fiddle-embed name="ab57b232acef69f26de9cb23d23c8a1a">
+
+#### Example Output
+
+~~~~
+[ 1.0000 0.0000 0.0000][ 0.0000 1.0000 0.0000][ 0.0000 0.0000 1.0000]
+isFixedStepInX: true
+[ 1.0000 0.0000 0.0000][ 0.0000 2.0000 0.0000][ 0.0000 0.0000 1.0000]
+isFixedStepInX: true
+[ 1.0000 0.0000 0.0000][ 0.0000 1.0000 0.0000][ 0.0000 0.1000 1.0000]
+isFixedStepInX: true
+[ 1.0000 0.0000 0.0000][ 0.0000 2.0000 0.0000][ 0.0000 0.1000 1.0000]
+isFixedStepInX: true
+[ 1.0000 0.0000 0.0000][ 0.0000 1.0000 0.0000][ 0.1000 0.0000 1.0000]
+isFixedStepInX: false
+[ 1.0000 0.0000 0.0000][ 0.0000 2.0000 0.0000][ 0.1000 0.0000 1.0000]
+isFixedStepInX: false
+[ 1.0000 0.0000 0.0000][ 0.0000 1.0000 0.0000][ 0.1000 0.1000 1.0000]
+isFixedStepInX: false
+[ 1.0000 0.0000 0.0000][ 0.0000 2.0000 0.0000][ 0.1000 0.1000 1.0000]
+isFixedStepInX: false
+~~~~
+
+</fiddle-embed></div>
+
+### See Also
+
+<a href="#SkMatrix_fixedStepInX">fixedStepInX</a> <a href="#SkMatrix_getType">getType</a>
+
+---
+
+<a name="SkMatrix_fixedStepInX"></a>
+## fixedStepInX
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+SkVector fixedStepInX(SkScalar y) const
+</pre>
+
+Returns <a href="undocumented#Vector">Vector</a> representing a unit step in x at <a href="#SkMatrix_fixedStepInX_y">y</a> mapped through <a href="#Matrix">Matrix</a>.
+If <a href="#SkMatrix_isFixedStepInX">isFixedStepInX</a> is false, returned value is undefined.
+
+### Parameters
+
+<table> <tr> <td><a name="SkMatrix_fixedStepInX_y"> <code><strong>y </strong></code> </a></td> <td>
+position of line parallel to x-axis</td>
+ </tr>
+</table>
+
+### Return Value
+
+<a href="undocumented#Vector">Vector</a> advance of mapped unit step in x
+
+### Example
+
+<div><fiddle-embed name="fad6b92b21b1e1deeae61978cec2d232"></fiddle-embed></div>
+
+### See Also
+
+<a href="#SkMatrix_isFixedStepInX">isFixedStepInX</a> <a href="#SkMatrix_getType">getType</a>
+
+---
+
+<a name="SkMatrix_cheapEqualTo"></a>
+## cheapEqualTo
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+bool cheapEqualTo(const SkMatrix& m) const
+</pre>
+
+Returns true if <a href="#Matrix">Matrix</a> equals <a href="#SkMatrix_cheapEqualTo_m">m</a>, using an efficient comparison.
+
+Returns false when the sign of zero values is the different; when one
+matrix has positive zero value and the other has negative zero value.
+
+Returns true even when both <a href="#Matrix">Matrices</a> contain <a href="undocumented#NaN">NaN</a>.
+
+<a href="undocumented#NaN">NaN</a> never equals any value, including itself. To improve performance, <a href="undocumented#NaN">NaN</a> values
+are treated as bit patterns that are equal if their bit patterns are equal.
+
+### Parameters
+
+<table> <tr> <td><a name="SkMatrix_cheapEqualTo_m"> <code><strong>m </strong></code> </a></td> <td>
+<a href="#Matrix">Matrix</a> to compare</td>
+ </tr>
+</table>
+
+### Return Value
+
+true if <a href="#SkMatrix_cheapEqualTo_m">m</a> and <a href="#Matrix">Matrix</a> are represented by identical bit patterns
+
+### Example
+
+<div><fiddle-embed name="39016b3cfc6bbabb09348a53822ce508">
+
+#### Example Output
+
+~~~~
+identity: a == b a.cheapEqualTo(b): true
+neg zero: a == b a.cheapEqualTo(b): false
+one NaN: a != b a.cheapEqualTo(b): false
+both NaN: a != b a.cheapEqualTo(b): true
+~~~~
+
+</fiddle-embed></div>
+
+### See Also
+
+<a href="#SkMatrix_equal_operator">operator==(const SkMatrix& a, const SkMatrix& b)</a>
+
+---
+
+<a name="SkMatrix_equal_operator"></a>
+## operator==
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+bool operator==(const SkMatrix& a, const SkMatrix& b)
+</pre>
+
+Compares <a href="#SkMatrix_equal_operator_a">a</a> and <a href="#SkMatrix_equal_operator_b">b</a>; returns true if <a href="#SkMatrix_equal_operator_a">a</a> and <a href="#SkMatrix_equal_operator_b">b</a> are numerically equal. Returns true
+even if sign of zero values are different. Returns false if either <a href="#Matrix">Matrix</a>
+contains <a href="undocumented#NaN">NaN</a>, even if the other <a href="#Matrix">Matrix</a> also contains <a href="undocumented#NaN">NaN</a>.
+
+### Parameters
+
+<table> <tr> <td><a name="SkMatrix_equal_operator_a"> <code><strong>a </strong></code> </a></td> <td>
+<a href="#Matrix">Matrix</a> to compare</td>
+ </tr> <tr> <td><a name="SkMatrix_equal_operator_b"> <code><strong>b </strong></code> </a></td> <td>
+<a href="#Matrix">Matrix</a> to compare</td>
+ </tr>
+</table>
+
+### Return Value
+
+true if m and <a href="#Matrix">Matrix</a> are numerically equal
+
+### Example
+
+<div><fiddle-embed name="3902859150b0f0c4aeb1f25d00434baa">
+
+#### Example Output
+
+~~~~
+identity: a == b a.cheapEqualTo(b): true
+~~~~
+
+</fiddle-embed></div>
+
+### See Also
+
+<a href="#SkMatrix_cheapEqualTo">cheapEqualTo</a> <a href="#SkMatrix_not_equal_operator">operator!=(const SkMatrix& a, const SkMatrix& b)</a>
+
+---
+
+<a name="SkMatrix_not_equal_operator"></a>
+## operator!=
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+bool operator!=(const SkMatrix& a, const SkMatrix& b)
+</pre>
+
+Compares <a href="#SkMatrix_not_equal_operator_a">a</a> and <a href="#SkMatrix_not_equal_operator_b">b</a>; returns true if <a href="#SkMatrix_not_equal_operator_a">a</a> and <a href="#SkMatrix_not_equal_operator_b">b</a> are not numerically equal. Returns false
+even if sign of zero values are different. Returns true if either <a href="#Matrix">Matrix</a>
+contains <a href="undocumented#NaN">NaN</a>, even if the other <a href="#Matrix">Matrix</a> also contains <a href="undocumented#NaN">NaN</a>.
+
+### Parameters
+
+<table> <tr> <td><a name="SkMatrix_not_equal_operator_a"> <code><strong>a </strong></code> </a></td> <td>
+<a href="#Matrix">Matrix</a> to compare</td>
+ </tr> <tr> <td><a name="SkMatrix_not_equal_operator_b"> <code><strong>b </strong></code> </a></td> <td>
+<a href="#Matrix">Matrix</a> to compare</td>
+ </tr>
+</table>
+
+### Return Value
+
+true if m and <a href="#Matrix">Matrix</a> are numerically not equal
+
+### Example
+
+<div><fiddle-embed name="8a8fadf5fd294daa4ee152833cc0dc0e"></fiddle-embed></div>
+
+### See Also
+
+<a href="#SkMatrix_cheapEqualTo">cheapEqualTo</a> <a href="#SkMatrix_equal_operator">operator==(const SkMatrix& a, const SkMatrix& b)</a>
+
+---
+
+<a name="SkMatrix_dump"></a>
+## dump
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+void dump() const
+</pre>
+
+Writes text representation of <a href="#Matrix">Matrix</a> to standard output. Floating point values
+are written with limited precision; it may not be possible to reconstruct
+original <a href="#Matrix">Matrix</a> from output.
+
+### Example
+
+<div><fiddle-embed name="8d72a4818e5a9188348f6c08ab5d8a40">
+
+#### Example Output
+
+~~~~
+[ 0.7071 -0.7071 0.0000][ 0.7071 0.7071 0.0000][ 0.0000 0.0000 1.0000]
+[ 0.7071 -0.7071 0.0000][ 0.7071 0.7071 0.0000][ 0.0000 0.0000 1.0000]
+matrix != nearlyEqual
+~~~~
+
+</fiddle-embed></div>
+
+### See Also
+
+<a href="#SkMatrix_toString">toString</a>
+
+---
+
+<a name="SkMatrix_toString"></a>
+## toString
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+void toString(SkString* str) const
+</pre>
+
+Creates string representation of <a href="#Matrix">Matrix</a>. Floating point values
+are written with limited precision; it may not be possible to reconstruct
+original <a href="#Matrix">Matrix</a> from output.
+
+### Parameters
+
+<table> <tr> <td><a name="SkMatrix_toString_str"> <code><strong>str </strong></code> </a></td> <td>
+storage for string representation of <a href="#Matrix">Matrix</a></td>
+ </tr>
+</table>
+
+### Example
+
+<div><fiddle-embed name="1d86e43958e42b8eaaa9b16df1baa4c8">
+
+#### Example Output
+
+~~~~
+mStr [ 0.7071 -0.7071 0.0000][ 0.7071 0.7071 0.0000][ 0.0000 0.0000 1.0000]
+neStr [ 0.7071 -0.7071 0.0000][ 0.7071 0.7071 0.0000][ 0.0000 0.0000 1.0000]
+matrix != nearlyEqual
+~~~~
+
+</fiddle-embed></div>
+
+### See Also
+
+<a href="#SkMatrix_dump">dump</a>
+
+---
+
+<a name="SkMatrix_getMinScale"></a>
+## getMinScale
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+SkScalar getMinScale() const
+</pre>
+
+Returns the minimum scaling factor of <a href="#Matrix">Matrix</a> by decomposing the scaling and
+skewing elements.
+Returns -1 if scale factor overflows or <a href="#Matrix">Matrix</a> contains perspective.
+
+### Return Value
+
+minimum scale factor
+
+### Example
+
+<div><fiddle-embed name="1d6f67904c88a806c3731879e9af4ae5">
+
+#### Example Output
+
+~~~~
+matrix.getMinScale() 24
+~~~~
+
+</fiddle-embed></div>
+
+### See Also
+
+<a href="#SkMatrix_getMaxScale">getMaxScale</a> <a href="#SkMatrix_getMinMaxScales">getMinMaxScales</a>
+
+---
+
+<a name="SkMatrix_getMaxScale"></a>
+## getMaxScale
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+SkScalar getMaxScale() const
+</pre>
+
+Returns the maximum scaling factor of <a href="#Matrix">Matrix</a> by decomposing the scaling and
+skewing elements.
+Returns -1 if scale factor overflows or <a href="#Matrix">Matrix</a> contains perspective.
+
+### Return Value
+
+maximum scale factor
+
+### Example
+
+<div><fiddle-embed name="3fee4364929899649cf9efc37897e964">
+
+#### Example Output
+
+~~~~
+matrix.getMaxScale() 42
+~~~~
+
+</fiddle-embed></div>
+
+### See Also
+
+<a href="#SkMatrix_getMinScale">getMinScale</a> <a href="#SkMatrix_getMinMaxScales">getMinMaxScales</a>
+
+---
+
+<a name="SkMatrix_getMinMaxScales"></a>
+## getMinMaxScales
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+bool SK_WARN_UNUSED_RESULT getMinMaxScales(SkScalar scaleFactors[2]) const
+</pre>
+
+Sets <a href="#SkMatrix_getMinMaxScales_scaleFactors">scaleFactors</a>[0] to the minimum scaling factor, and <a href="#SkMatrix_getMinMaxScales_scaleFactors">scaleFactors</a>[1] to the
+maximum scaling factor. Scaling factors are computed by decomposing
+the <a href="#Matrix">Matrix</a> scaling and skewing elements.
+
+Returns true if <a href="#SkMatrix_getMinMaxScales_scaleFactors">scaleFactors</a> are found; otherwise, returns false and sets
+<a href="#SkMatrix_getMinMaxScales_scaleFactors">scaleFactors</a> to undefined values.
+
+### Parameters
+
+<table> <tr> <td><a name="SkMatrix_getMinMaxScales_scaleFactors"> <code><strong>scaleFactors </strong></code> </a></td> <td>
+storage for minimum and maximum scale factors</td>
+ </tr>
+</table>
+
+### Return Value
+
+true if scale factors were computed correctly
+
+### Example
+
+<div><fiddle-embed name="cd4dc63d3e04226f0b5861ba8925e223">
+
+#### Example Output
+
+~~~~
+matrix.getMinMaxScales() false 2 2
+~~~~
+
+</fiddle-embed></div>
+
+### See Also
+
+<a href="#SkMatrix_getMinScale">getMinScale</a> <a href="#SkMatrix_getMaxScale">getMaxScale</a>
+
+---
+
+<a name="SkMatrix_decomposeScale"></a>
+## decomposeScale
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+bool decomposeScale(SkSize* scale, SkMatrix* remaining = nullptr) const
+</pre>
+
+Decomposes <a href="#Matrix">Matrix</a> into <a href="#SkMatrix_decomposeScale_scale">scale</a> components and whatever remains. Returns false if
+<a href="#Matrix">Matrix</a> could not be decomposed.
+
+Sets <a href="#SkMatrix_decomposeScale_scale">scale</a> to portion of <a href="#Matrix">Matrix</a> that scales in x and y. Sets <a href="#SkMatrix_decomposeScale_remaining">remaining</a> to <a href="#Matrix">Matrix</a>
+with x and y scaling factored out. <a href="#SkMatrix_decomposeScale_remaining">remaining</a> may be passed as nullptr
+to determine if <a href="#Matrix">Matrix</a> can be decomposed without computing remainder.
+
+Returns true if <a href="#SkMatrix_decomposeScale_scale">scale</a> components are found. <a href="#SkMatrix_decomposeScale_scale">scale</a> and <a href="#SkMatrix_decomposeScale_remaining">remaining</a> are
+unchanged if <a href="#Matrix">Matrix</a> contains perspective; <a href="#SkMatrix_decomposeScale_scale">scale</a> factors are not finite, or
+are nearly zero.
+
+On success<a href="#Matrix">Matrix</a> = <a href="#SkMatrix_decomposeScale_scale">scale</a> * Remaining
+
+### Parameters
+
+<table> <tr> <td><a name="SkMatrix_decomposeScale_scale"> <code><strong>scale </strong></code> </a></td> <td>
+x and y scaling factors; may be nullptr</td>
+ </tr> <tr> <td><a name="SkMatrix_decomposeScale_remaining"> <code><strong>remaining </strong></code> </a></td> <td>
+<a href="#Matrix">Matrix</a> without scaling; may be nullptr</td>
+ </tr>
+</table>
+
+### Return Value
+
+true if <a href="#SkMatrix_decomposeScale_scale">scale</a> can be computed
+
+### Example
+
+<div><fiddle-embed name="139b874da0a3ede1f3df88119085c0aa">
+
+#### Example Output
+
+~~~~
+[ 0.0000 -0.2500 0.0000][ 0.5000 0.0000 0.0000][ 0.0000 0.0000 1.0000]
+success: true scale: 0.5, 0.25
+[ 0.0000 -0.5000 0.0000][ 2.0000 0.0000 0.0000][ 0.0000 0.0000 1.0000]
+[ 0.0000 -0.2500 0.0000][ 0.5000 0.0000 0.0000][ 0.0000 0.0000 1.0000]
+~~~~
+
+</fiddle-embed></div>
+
+### See Also
+
+<a href="#SkMatrix_setScale">setScale</a> <a href="#SkMatrix_MakeScale">MakeScale</a>
+
+---
+
+<a name="SkMatrix_I"></a>
+## I
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+static const SkMatrix& I()
+</pre>
+
+Returns reference to const identity <a href="#Matrix">Matrix</a>. Returned <a href="#Matrix">Matrix</a> is <a href="#SkMatrix_set">set</a> to:
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+| 1 0 0 |
+| 0 1 0 |
+| 0 0 1 |</pre>
+
+### Return Value
+
+const identity <a href="#Matrix">Matrix</a>
+
+### Example
+
+<div><fiddle-embed name="d961d91020f19037204a8c3fd8cb1060">
+
+#### Example Output
+
+~~~~
+m1 == m2
+m2 == m3
+~~~~
+
+</fiddle-embed></div>
+
+### See Also
+
+<a href="#SkMatrix_reset">reset</a> <a href="#SkMatrix_setIdentity">setIdentity</a>
+
+---
+
+<a name="SkMatrix_InvalidMatrix"></a>
+## InvalidMatrix
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+static const SkMatrix& InvalidMatrix()
+</pre>
+
+Returns reference to a const <a href="#Matrix">Matrix</a> with invalid values. Returned <a href="#Matrix">Matrix</a> is <a href="#SkMatrix_set">set</a>
+to:
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+| SK_ScalarMax SK_ScalarMax SK_ScalarMax |
+| SK_ScalarMax SK_ScalarMax SK_ScalarMax |
+| SK_ScalarMax SK_ScalarMax SK_ScalarMax |</pre>
+
+### Return Value
+
+const invalid <a href="#Matrix">Matrix</a>
+
+### Example
+
+<div><fiddle-embed name="af0b72360c1c7a25b4754bfa47011dd5">
+
+#### Example Output
+
+~~~~
+scaleX 3.40282e+38
+~~~~
+
+</fiddle-embed></div>
+
+### See Also
+
+SeeAlso <a href="#SkMatrix_getType">getType</a>
+
+---
+
+<a name="SkMatrix_Concat"></a>
+## Concat
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+static SkMatrix Concat(const SkMatrix& a, const SkMatrix& b)
+</pre>
+
+Returns <a href="#Matrix">Matrix</a> <a href="#SkMatrix_Concat_a">a</a> multiplied by <a href="#Matrix">Matrix</a> <a href="#SkMatrix_Concat_b">b</a>.
+
+Given:
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+ | A B C | | J K L |
+a = | D E F |, b = | M N O |
+ | G H I | | P Q R |</pre>
+
+sets <a href="#Matrix">Matrix</a> to:
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+ | A B C | | J K L | | AJ+BM+CP AK+BN+CQ AL+BO+CR |
+a * b = | D E F | * | M N O | = | DJ+EM+FP DK+EN+FQ DL+EO+FR |
+ | G H I | | P Q R | | GJ+HM+IP GK+HN+IQ GL+HO+IR |</pre>
+
+### Parameters
+
+<table> <tr> <td><a name="SkMatrix_Concat_a"> <code><strong>a </strong></code> </a></td> <td>
+<a href="#Matrix">Matrix</a> on left side of multiply expression</td>
+ </tr> <tr> <td><a name="SkMatrix_Concat_b"> <code><strong>b </strong></code> </a></td> <td>
+<a href="#Matrix">Matrix</a> on right side of multiply expression</td>
+ </tr>
+</table>
+
+### Return Value
+
+<a href="#Matrix">Matrix</a> computed from <a href="#SkMatrix_Concat_a">a</a> times <a href="#SkMatrix_Concat_b">b</a>
+
+### Example
+
+<div><fiddle-embed name="6b4562c7052da94f3d5b2412dca41946"><div><a href="#SkMatrix_setPolyToPoly">setPolyToPoly</a> creates perspective matrices, one the inverse of the other.
+Multiplying the matrix by its inverse turns into an identity matrix.</div></fiddle-embed></div>
+
+### See Also
+
+<a href="#SkMatrix_preConcat">preConcat</a> <a href="#SkMatrix_postConcat">postConcat</a>
+
+---
+
+<a name="SkMatrix_dirtyMatrixTypeCache"></a>
+## dirtyMatrixTypeCache
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+void dirtyMatrixTypeCache()
+</pre>
+
+Sets internal cache to unknown state. Use to force update after repeated
+modifications to <a href="#Matrix">Matrix</a> element reference returned by <a href="#SkMatrix_subscript_operator_const">operator[](int index)</a>.
+
+### Example
+
+<div><fiddle-embed name="f4365ef332f51f7fd25040e0771ba9a2">
+
+#### Example Output
+
+~~~~
+with identity matrix: x = 24
+after skew x mod: x = 24
+after 2nd skew x mod: x = 24
+after dirty cache: x = 66
+~~~~
+
+</fiddle-embed></div>
+
+### See Also
+
+<a href="#SkMatrix_subscript_operator_const">operator[](int index)</a> <a href="#SkMatrix_getType">getType</a>
+
+---
+
+<a name="SkMatrix_setScaleTranslate"></a>
+## setScaleTranslate
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+void setScaleTranslate(SkScalar sx, SkScalar sy, SkScalar tx, SkScalar ty)
+</pre>
+
+Initializes <a href="#Matrix">Matrix</a> with scale and translate elements.
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+| sx 0 tx |
+| 0 sy ty |
+| 0 0 1 |</pre>
+
+### Parameters
+
+<table> <tr> <td><a name="SkMatrix_setScaleTranslate_sx"> <code><strong>sx </strong></code> </a></td> <td>
+horizontal scale factor to store</td>
+ </tr> <tr> <td><a name="SkMatrix_setScaleTranslate_sy"> <code><strong>sy </strong></code> </a></td> <td>
+vertical scale factor to store</td>
+ </tr> <tr> <td><a name="SkMatrix_setScaleTranslate_tx"> <code><strong>tx </strong></code> </a></td> <td>
+horizontal translation to store</td>
+ </tr> <tr> <td><a name="SkMatrix_setScaleTranslate_ty"> <code><strong>ty </strong></code> </a></td> <td>
+vertical translation to store</td>
+ </tr>
+</table>
+
+### Example
+
+<div><fiddle-embed name="fed43797f13796529cb6731385d6f8f3">
+
+#### Example Output
+
+~~~~
+[ 1.0000 0.0000 3.0000][ 0.0000 2.0000 4.0000][ 0.0000 0.0000 1.0000]
+~~~~
+
+</fiddle-embed></div>
+
+### See Also
+
+<a href="#SkMatrix_setScale">setScale</a> <a href="#SkMatrix_preTranslate">preTranslate</a> <a href="#SkMatrix_postTranslate">postTranslate</a>
+
+---
+
+<a name="SkMatrix_isFinite"></a>
+## isFinite
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+bool isFinite() const
+</pre>
+
+Returns true if all elements of the matrix are finite. Returns false if any
+element is infinity, or <a href="undocumented#NaN">NaN</a>.
+
+### Return Value
+
+true if matrix has only finite elements
+
+### Example
+
+<div><fiddle-embed name="bc6c6f6a5df770287120d87f81b922eb">
+
+#### Example Output
+
+~~~~
+[ 1.0000 0.0000 nan][ 0.0000 1.0000 0.0000][ 0.0000 0.0000 1.0000]
+matrix is finite: false
+matrix != matrix
+~~~~
+
+</fiddle-embed></div>
+
+### See Also
+
+operator==
+
+---
+
diff --git a/site/user/api/SkPaint_Reference.md b/site/user/api/SkPaint_Reference.md
index e539b3a628..ffab03e288 100644
--- a/site/user/api/SkPaint_Reference.md
+++ b/site/user/api/SkPaint_Reference.md
@@ -653,7 +653,7 @@ serialized data describing <a href="#Paint">Paint</a> content</td>
## <a name="SkPaint_Hinting"></a> Enum SkPaint::Hinting
-<pre style="padding: 1em 1em 1em 1em;width: 44em; background-color: #f0f0f0">
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
enum <a href="#Hinting">Hinting</a> {
<a href="#SkPaint_kNo_Hinting">kNo Hinting</a> = 0,
<a href="#SkPaint_kSlight_Hinting">kSlight Hinting</a> = 1,
@@ -776,7 +776,7 @@ paint1 == paint2
## <a name="SkPaint_Flags"></a> Enum SkPaint::Flags
-<pre style="padding: 1em 1em 1em 1em;width: 44em; background-color: #f0f0f0">
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
enum <a href="#Flags">Flags</a> {
<a href="#SkPaint_kAntiAlias_Flag">kAntiAlias Flag</a> = 0x01,
<a href="#SkPaint_kDither_Flag">kDither Flag</a> = 0x04,
@@ -845,7 +845,7 @@ multiple settings at once.
## <a name="SkPaint_ReserveFlags"></a> Enum SkPaint::ReserveFlags
-<pre style="padding: 1em 1em 1em 1em;width: 44em; background-color: #f0f0f0">
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
enum <a href="#SkPaint_ReserveFlags">ReserveFlags</a> {
<a href="#SkPaint_kUnderlineText_ReserveFlag">kUnderlineText ReserveFlag</a> = 0x08,
<a href="#SkPaint_kStrikeThruText_ReserveFlag">kStrikeThruText ReserveFlag</a> = 0x10,
@@ -1356,7 +1356,7 @@ the outline glyph if <a href="#SkPaint_kEmbeddedBitmapText_Flag">kEmbeddedBitmap
### Example
-<pre style="padding: 1em 1em 1em 1em;width: 44em; background-color: #f0f0f0">
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
<div>The "" <a href="undocumented#TrueType">TrueType</a> font in the <a href="undocumented#Skia">Skia</a> resources/fonts directory
includes an embedded bitmap <a href="undocumented#Glyph">Glyph</a> at odd font sizes. This example works
on platforms that use <a href="undocumented#FreeType">FreeType</a> as their <a href="#Engine">Font Engine</a>.
@@ -2066,7 +2066,7 @@ while stroking.
## <a name="SkPaint_Style"></a> Enum SkPaint::Style
-<pre style="padding: 1em 1em 1em 1em;width: 44em; background-color: #f0f0f0">
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
enum <a href="#SkPaint_Style">Style</a> {
<a href="#SkPaint_kFill_Style">kFill Style</a>,
<a href="#SkPaint_kStroke_Style">kStroke Style</a>,
@@ -2110,7 +2110,7 @@ and the set <a href="#Fill_Type">Path Fill Type</a> is ignored.</td>
## <a name="SkPaint__anonymous"></a> Enum SkPaint::_anonymous
-<pre style="padding: 1em 1em 1em 1em;width: 44em; background-color: #f0f0f0">
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
enum {
<a href="#SkPaint_kStyleCount">kStyleCount</a> = <a href="#SkPaint_kStrokeAndFill_Style">kStrokeAndFill Style</a> + 1,
};</pre>
@@ -2375,7 +2375,7 @@ default miter limit == 8
## <a name="SkPaint_Cap"></a> Enum SkPaint::Cap
-<pre style="padding: 1em 1em 1em 1em;width: 44em; background-color: #f0f0f0">
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
enum <a href="#SkPaint_Cap">Cap</a> {
<a href="#SkPaint_kButt_Cap">kButt Cap</a>,
<a href="#SkPaint_kRound_Cap">kRound Cap</a>,
@@ -2520,7 +2520,7 @@ the following curve, the pair of curves meet at <a href="#Stroke_Join">Stroke Jo
## <a name="SkPaint_Join"></a> Enum SkPaint::Join
-<pre style="padding: 1em 1em 1em 1em;width: 44em; background-color: #f0f0f0">
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
enum <a href="#SkPaint_Join">Join</a> {
<a href="#SkPaint_kMiter_Join">kMiter Join</a>,
<a href="#SkPaint_kRound_Join">kRound Join</a>,
@@ -3663,7 +3663,7 @@ sets <a href="undocumented#Draw_Looper">Draw Looper</a> to <a href="#SkPaint_set
## <a name="SkPaint_Align"></a> Enum SkPaint::Align
-<pre style="padding: 1em 1em 1em 1em;width: 44em; background-color: #f0f0f0">
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
enum <a href="#SkPaint_Align">Align</a> {
<a href="#SkPaint_kLeft_Align">kLeft Align</a>,
<a href="#SkPaint_kCenter_Align">kCenter Align</a>,
@@ -3706,7 +3706,7 @@ and by its height if <a href="#SkPaint_Flags">Flags</a> has <a href="#SkPaint_kV
## <a name="SkPaint__anonymous_2"></a> Enum SkPaint::_anonymous_2
-<pre style="padding: 1em 1em 1em 1em;width: 44em; background-color: #f0f0f0">
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
enum {
<a href="#SkPaint_kAlignCount">kAlignCount</a> = 3,
};</pre>
@@ -3944,7 +3944,7 @@ additional shear in x-axis relative to y-axis</td>
## <a name="SkPaint_TextEncoding"></a> Enum SkPaint::TextEncoding
-<pre style="padding: 1em 1em 1em 1em;width: 44em; background-color: #f0f0f0">
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
enum <a href="#SkPaint_TextEncoding">TextEncoding</a> {
<a href="#SkPaint_kUTF8_TextEncoding">kUTF8 TextEncoding</a>,
<a href="#SkPaint_kUTF16_TextEncoding">kUTF16 TextEncoding</a>,
@@ -4075,16 +4075,8 @@ Y-axis values above the baseline are negative, and below the baseline are positi
<div><fiddle-embed name="b5b76e0a15da0c3530071186a9006498"></fiddle-embed></div>
# <a name="SkPaint_FontMetrics"></a> Struct SkPaint::FontMetrics
-<a href="#SkPaint_FontMetrics">FontMetrics</a> is filled out by <a href="#SkPaint_getFontMetrics">getFontMetrics</a>. <a href="#SkPaint_FontMetrics">FontMetrics</a> contents reflect the values
-computed by <a href="undocumented#Font_Manager">Font Manager</a> using <a href="undocumented#Typeface">Typeface</a>. Values are set to zero if they are
-not available.
-
-<a href="#SkPaint_FontMetrics_fUnderlineThickness">fUnderlineThickness</a> and <a href="#SkPaint_FontMetrics_fUnderlinePosition">fUnderlinePosition</a> have a bit set in <a href="#SkPaint_FontMetrics_fFlags">fFlags</a> if their values
-are valid, since their value may be zero.
-<a href="#SkPaint_FontMetrics_fStrikeoutThickness">fStrikeoutThickness</a> and <a href="#SkPaint_FontMetrics_fStrikeoutPosition">fStrikeoutPosition</a> have a bit set in <a href="#SkPaint_FontMetrics_fFlags">fFlags</a> if their values
-are valid, since their value may be zero.
-<pre style="padding: 1em 1em 1em 1em;width: 44em; background-color: #f0f0f0">
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
struct <a href="#SkPaint_FontMetrics">FontMetrics</a> {
enum <a href="#SkPaint_FontMetrics_FontMetricsFlags">FontMetricsFlags</a> {
<a href="#SkPaint_FontMetrics_kUnderlineThicknessIsValid_Flag">kUnderlineThicknessIsValid Flag</a> = 1 << 0,
@@ -4116,13 +4108,18 @@ bool <a href="#SkPaint_FontMetrics_hasStrikeoutThickness">hasStrikeoutThickness(
bool <a href="#SkPaint_FontMetrics_hasStrikeoutPosition">hasStrikeoutPosition(SkScalar* position)</a> const;
};</pre>
-## <a name="SkPaint_FontMetrics_FontMetricsFlags"></a> Enum SkPaint::FontMetrics::FontMetricsFlags
+<a href="#SkPaint_FontMetrics">FontMetrics</a> is filled out by <a href="#SkPaint_getFontMetrics">getFontMetrics</a>. <a href="#SkPaint_FontMetrics">FontMetrics</a> contents reflect the values
+computed by <a href="undocumented#Font_Manager">Font Manager</a> using <a href="undocumented#Typeface">Typeface</a>. Values are set to zero if they are
+not available.
-<a href="#SkPaint_FontMetrics_FontMetricsFlags">FontMetricsFlags</a> are set in <a href="#SkPaint_FontMetrics_fFlags">fFlags</a> when underline and strikeout metrics are valid;
-the underline or strikeout metric may be valid and zero.
-Fonts with embedded bitmaps may not have valid underline or strikeout metrics.
+<a href="#SkPaint_FontMetrics_fUnderlineThickness">fUnderlineThickness</a> and <a href="#SkPaint_FontMetrics_fUnderlinePosition">fUnderlinePosition</a> have a bit set in <a href="#SkPaint_FontMetrics_fFlags">fFlags</a> if their values
+are valid, since their value may be zero.
+<a href="#SkPaint_FontMetrics_fStrikeoutThickness">fStrikeoutThickness</a> and <a href="#SkPaint_FontMetrics_fStrikeoutPosition">fStrikeoutPosition</a> have a bit set in <a href="#SkPaint_FontMetrics_fFlags">fFlags</a> if their values
+are valid, since their value may be zero.
-<pre style="padding: 1em 1em 1em 1em;width: 44em; background-color: #f0f0f0">
+## <a name="SkPaint_FontMetrics_FontMetricsFlags"></a> Enum SkPaint::FontMetrics::FontMetricsFlags
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
enum <a href="#SkPaint_FontMetrics_FontMetricsFlags">FontMetricsFlags</a> {
<a href="#SkPaint_FontMetrics_kUnderlineThicknessIsValid_Flag">kUnderlineThicknessIsValid Flag</a> = 1 << 0,
<a href="#SkPaint_FontMetrics_kUnderlinePositionIsValid_Flag">kUnderlinePositionIsValid Flag</a> = 1 << 1,
@@ -4130,6 +4127,10 @@ enum <a href="#SkPaint_FontMetrics_FontMetricsFlags">FontMetricsFlags</a> {
<a href="#SkPaint_FontMetrics_kStrikeoutPositionIsValid_Flag">kStrikeoutPositionIsValid Flag</a> = 1 << 3,
};</pre>
+<a href="#SkPaint_FontMetrics_FontMetricsFlags">FontMetricsFlags</a> are set in <a href="#SkPaint_FontMetrics_fFlags">fFlags</a> when underline and strikeout metrics are valid;
+the underline or strikeout metric may be valid and zero.
+Fonts with embedded bitmaps may not have valid underline or strikeout metrics.
+
### Constants
<table>
diff --git a/site/user/api/SkPath_Reference.md b/site/user/api/SkPath_Reference.md
index bb3634e373..154b66b27d 100644
--- a/site/user/api/SkPath_Reference.md
+++ b/site/user/api/SkPath_Reference.md
@@ -216,7 +216,7 @@ Internally, <a href="#Path">Path</a> lazily computes metrics likes bounds and co
## <a name="SkPath_Verb"></a> Enum SkPath::Verb
-<pre style="padding: 1em 1em 1em 1em;width: 44em; background-color: #f0f0f0">
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
enum <a href="#Verb">Verb</a> {
<a href="#SkPath_kMove_Verb">kMove Verb</a>,
<a href="#SkPath_kLine_Verb">kLine Verb</a>,
@@ -298,7 +298,7 @@ verbs: kMove_Verb kLine_Verb kQuad_Verb kClose_Verb kMove_Verb kCubic_Verb kConi
## <a name="SkPath_Direction"></a> Enum SkPath::Direction
-<pre style="padding: 1em 1em 1em 1em;width: 44em; background-color: #f0f0f0">
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
enum <a href="#Direction">Direction</a> {
<a href="#SkPath_kCW_Direction">kCW Direction</a>,
<a href="#SkPath_kCCW_Direction">kCCW Direction</a>,
@@ -320,10 +320,10 @@ travel counterclockwise.
<table>
<tr>
- <td><a name="SkPath_kCW_Direction"> <code><strong>SkPath::kCW_Direction </strong></code> </a></td><td>0</td><td><a href="#Contour">Contour</a> travels in a clockwise direction.</td>
+ <td><a name="SkPath_kCW_Direction"> <code><strong>SkPath::kCW_Direction </strong></code> </a></td><td>0</td><td><a href="#Contour">Contour</a> travels in a clockwise direction</td>
</tr>
<tr>
- <td><a name="SkPath_kCCW_Direction"> <code><strong>SkPath::kCCW_Direction </strong></code> </a></td><td>1</td><td><a href="#Contour">Contour</a> travels in a counterclockwise direction.</td>
+ <td><a name="SkPath_kCCW_Direction"> <code><strong>SkPath::kCCW_Direction </strong></code> </a></td><td>1</td><td><a href="#Contour">Contour</a> travels in a counterclockwise direction</td>
</tr>
</table>
@@ -617,7 +617,9 @@ Interpolate between <a href="#Path">Paths</a> with equal sized <a href="SkPath_R
Copy <a href="#Verb_Array">Verb Array</a> and <a href="#Weight">Weights</a> to <a href="#SkPath_interpolate_out">out</a>,
and set <a href="#SkPath_interpolate_out">out</a> <a href="#Point_Array">Point Array</a> to a weighted average of this <a href="#Point_Array">Point Array</a> and <a href="#SkPath_interpolate_ending">ending</a>
<a href="#Point_Array">Point Array</a>, using the formula:
-(this->points * <a href="#SkPath_interpolate_weight">weight</a>) + ending->points * (1 - <a href="#SkPath_interpolate_weight">weight</a>)<a href="#SkPath_interpolate_weight">weight</a> is most useful when between zero (<a href="#SkPath_interpolate_ending">ending</a> <a href="#Point_Array">Point Array</a>) and
+(this->points * <a href="#SkPath_interpolate_weight">weight</a>) + ending->points * (1 - <a href="#SkPath_interpolate_weight">weight</a>).
+
+<a href="#SkPath_interpolate_weight">weight</a> is most useful when between zero (<a href="#SkPath_interpolate_ending">ending</a> <a href="#Point_Array">Point Array</a>) and
one (this <a href="#Point_Array">Point Array</a>); will work with values outside of this
range.
@@ -668,7 +670,7 @@ true if <a href="#Path">Path</a> has one owner
## <a name="SkPath_FillType"></a> Enum SkPath::FillType
-<pre style="padding: 1em 1em 1em 1em;width: 44em; background-color: #f0f0f0">
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
enum <a href="#SkPath_FillType">FillType</a> {
<a href="#SkPath_kWinding_FillType">kWinding FillType</a>,
<a href="#SkPath_kEvenOdd_FillType">kEvenOdd FillType</a>,
@@ -842,7 +844,7 @@ unmodified by the original <a href="#SkPath_FillType">FillType</a>.
## <a name="SkPath_Convexity"></a> Enum SkPath::Convexity
-<pre style="padding: 1em 1em 1em 1em;width: 44em; background-color: #f0f0f0">
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
enum <a href="#Convexity">Convexity</a> : uint8_t {
<a href="#SkPath_kUnknown_Convexity">kUnknown Convexity</a>,
<a href="#SkPath_kConvex_Convexity">kConvex Convexity</a>,
@@ -2805,7 +2807,7 @@ line (156,20),(200,20)
## <a name="SkPath_ArcSize"></a> Enum SkPath::ArcSize
-<pre style="padding: 1em 1em 1em 1em;width: 44em; background-color: #f0f0f0">
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
enum <a href="#SkPath_ArcSize">ArcSize</a> {
<a href="#SkPath_kSmall_ArcSize">kSmall ArcSize</a>,
<a href="#SkPath_kLarge_ArcSize">kLarge ArcSize</a>,
@@ -2818,10 +2820,10 @@ Four <a href="undocumented#Oval">Oval</a> parts with radii (rx, ry) start at las
<table>
<tr>
- <td><a name="SkPath_kSmall_ArcSize"> <code><strong>SkPath::kSmall_ArcSize </strong></code> </a></td><td>0</td><td>Smaller of <a href="#Arc">Arc</a> pair.</td>
+ <td><a name="SkPath_kSmall_ArcSize"> <code><strong>SkPath::kSmall_ArcSize </strong></code> </a></td><td>0</td><td>smaller of <a href="#Arc">Arc</a> pair</td>
</tr>
<tr>
- <td><a name="SkPath_kLarge_ArcSize"> <code><strong>SkPath::kLarge_ArcSize </strong></code> </a></td><td>1</td><td>Larger of <a href="#Arc">Arc</a> pair.</td>
+ <td><a name="SkPath_kLarge_ArcSize"> <code><strong>SkPath::kLarge_ArcSize </strong></code> </a></td><td>1</td><td>larger of <a href="#Arc">Arc</a> pair</td>
</tr>
</table>
@@ -2840,18 +2842,20 @@ void arcTo(SkScalar rx, SkScalar ry, SkScalar xAxisRotate, ArcSize largeArc,
Direction sweep, SkScalar x, SkScalar y)
</pre>
-Append <a href="#Arc">Arc</a> to <a href="#Path">Path</a>. <a href="#Arc">Arc</a> is implemented by one or more <a href="#Conic">Conics</a> weighted to describe part of <a href="undocumented#Oval">Oval</a>
-with radii (<a href="#SkPath_arcTo_4_rx">rx</a>, <a href="#SkPath_arcTo_4_ry">ry</a>) rotated by <a href="#SkPath_arcTo_4_xAxisRotate">xAxisRotate</a> degrees. <a href="#Arc">Arc</a> curves from last <a href="#Path">Path</a> <a href="undocumented#Point">Point</a> to (<a href="#SkPath_arcTo_4_x">x</a>, <a href="#SkPath_arcTo_4_y">y</a>),
-choosing one of four possible routes: clockwise or counterclockwise, and smaller or larger.
+Append <a href="#Arc">Arc</a> to <a href="#Path">Path</a>. <a href="#Arc">Arc</a> is implemented by one or more <a href="#Conic">Conics</a> weighted to
+describe part of <a href="undocumented#Oval">Oval</a> with radii (<a href="#SkPath_arcTo_4_rx">rx</a>, <a href="#SkPath_arcTo_4_ry">ry</a>) rotated by <a href="#SkPath_arcTo_4_xAxisRotate">xAxisRotate</a> degrees. <a href="#Arc">Arc</a>
+curves from last <a href="#Path">Path</a> <a href="undocumented#Point">Point</a> to (<a href="#SkPath_arcTo_4_x">x</a>, <a href="#SkPath_arcTo_4_y">y</a>), choosing one of four possible routes:
+clockwise or counterclockwise, and smaller or larger.
-<a href="#Arc">Arc</a> <a href="#SkPath_arcTo_4_sweep">sweep</a> is always less than 360 degrees. <a href="#SkPath_arcTo">arcTo</a> appends <a href="undocumented#Line">Line</a> to (<a href="#SkPath_arcTo_4_x">x</a>, <a href="#SkPath_arcTo_4_y">y</a>) if either radii are zero,
-or if last <a href="#Path">Path</a> <a href="undocumented#Point">Point</a> equals (<a href="#SkPath_arcTo_4_x">x</a>, <a href="#SkPath_arcTo_4_y">y</a>). <a href="#SkPath_arcTo">arcTo</a> scales radii (<a href="#SkPath_arcTo_4_rx">rx</a>, <a href="#SkPath_arcTo_4_ry">ry</a>) to fit last <a href="#Path">Path</a> <a href="undocumented#Point">Point</a> and
-(<a href="#SkPath_arcTo_4_x">x</a>, <a href="#SkPath_arcTo_4_y">y</a>) if both are greater than zero but too small.
+<a href="#Arc">Arc</a> <a href="#SkPath_arcTo_4_sweep">sweep</a> is always less than 360 degrees. <a href="#SkPath_arcTo">arcTo</a> appends <a href="undocumented#Line">Line</a> to (<a href="#SkPath_arcTo_4_x">x</a>, <a href="#SkPath_arcTo_4_y">y</a>) if
+either radii are zero, or if last <a href="#Path">Path</a> <a href="undocumented#Point">Point</a> equals (<a href="#SkPath_arcTo_4_x">x</a>, <a href="#SkPath_arcTo_4_y">y</a>). <a href="#SkPath_arcTo">arcTo</a> scales radii
+(<a href="#SkPath_arcTo_4_rx">rx</a>, <a href="#SkPath_arcTo_4_ry">ry</a>) to fit last <a href="#Path">Path</a> <a href="undocumented#Point">Point</a> and (<a href="#SkPath_arcTo_4_x">x</a>, <a href="#SkPath_arcTo_4_y">y</a>) if both are greater than zero but
+too small.
<a href="#SkPath_arcTo">arcTo</a> appends up to four <a href="#Conic">Conic</a> curves.
-<a href="#SkPath_arcTo">arcTo</a> implements the functionality of <a href="#Arc">SVG Arc</a>, although <a href="undocumented#SVG">SVG</a> "" value is
-opposite the integer value of <a href="#SkPath_arcTo_4_sweep">sweep</a>; <a href="undocumented#SVG">SVG</a> "" uses 1 for clockwise, while <a href="#SkPath_kCW_Direction">kCW Direction</a>
-cast to int is zero.
+<a href="#SkPath_arcTo">arcTo</a> implements the functionality of <a href="#Arc">SVG Arc</a>, although <a href="undocumented#SVG">SVG</a> "" value
+is opposite the integer value of <a href="#SkPath_arcTo_4_sweep">sweep</a>; <a href="undocumented#SVG">SVG</a> "" uses 1 for clockwise,
+while <a href="#SkPath_kCW_Direction">kCW Direction</a> cast to int is zero.
### Parameters
@@ -2936,7 +2940,9 @@ void rArcTo(SkScalar rx, SkScalar ry, SkScalar xAxisRotate, ArcSize largeArc,
Append <a href="#Arc">Arc</a> to <a href="#Path">Path</a>, relative to last <a href="#Path">Path</a> <a href="undocumented#Point">Point</a>. <a href="#Arc">Arc</a> is implemented by one or
more <a href="#Conic">Conic</a>, weighted to describe part of <a href="undocumented#Oval">Oval</a> with radii (<a href="#SkPath_rArcTo_rx">rx</a>, <a href="#SkPath_rArcTo_ry">ry</a>) rotated by
-<a href="#SkPath_rArcTo_xAxisRotate">xAxisRotate</a> degrees. <a href="#Arc">Arc</a> curves from last <a href="#Path">Path</a> <a href="undocumented#Point">Point</a> (x0, y0) to end <a href="undocumented#Point">Point</a>(x0 + <a href="#SkPath_rArcTo_dx">dx</a>, y0 + <a href="#SkPath_rArcTo_dy">dy</a>),
+<a href="#SkPath_rArcTo_xAxisRotate">xAxisRotate</a> degrees. <a href="#Arc">Arc</a> curves from last <a href="#Path">Path</a> <a href="undocumented#Point">Point</a> (x0, y0) to end <a href="undocumented#Point">Point</a>:
+
+(x0 + <a href="#SkPath_rArcTo_dx">dx</a>, y0 + <a href="#SkPath_rArcTo_dy">dy</a>),
choosing one of four possible routes: clockwise or
counterclockwise, and smaller or larger. If <a href="#Path">Path</a> is empty, the start <a href="#Arc">Arc</a> <a href="undocumented#Point">Point</a>
is (0, 0).
@@ -3118,7 +3124,9 @@ control <a href="undocumented#Point">Point</a> <a href="#SkPath_ConvertConicToQu
Maximum <a href="#Quad">Quad</a> count is 2 to the <a href="#SkPath_ConvertConicToQuads_pow2">pow2</a>.
Every third point in array shares last <a href="undocumented#Point">Point</a> of previous <a href="#Quad">Quad</a> and first <a href="undocumented#Point">Point</a> of
next <a href="#Quad">Quad</a>. Maximum <a href="#SkPath_ConvertConicToQuads_pts">pts</a> storage size is given by:
-(1 + 2 * (1 << <a href="#SkPath_ConvertConicToQuads_pow2">pow2</a>)) * sizeof(SkPoint)<a href="#SkPath_ConvertConicToQuads">ConvertConicToQuads</a> returns <a href="#Quad">Quad</a> count used the approximation, which may be smaller
+(1 + 2 * (1 << <a href="#SkPath_ConvertConicToQuads_pow2">pow2</a>)) * sizeof(SkPoint).
+
+Returns <a href="#Quad">Quad</a> count used the approximation, which may be smaller
than the number requested.
<a href="#Conic_Weight">Conic Weight</a> determines the amount of influence <a href="#Conic">Conic</a> control point has on the curve.
<a href="#SkPath_ConvertConicToQuads_w">w</a> less than one represents an elliptical section. <a href="#SkPath_ConvertConicToQuads_w">w</a> greater than one represents
@@ -3446,9 +3454,10 @@ void addCircle(SkScalar x, SkScalar y, SkScalar radius,
</pre>
Add <a href="undocumented#Circle">Circle</a> centered at (<a href="#SkPath_addCircle_x">x</a>, <a href="#SkPath_addCircle_y">y</a>) of size <a href="#SkPath_addCircle_radius">radius</a> to <a href="#Path">Path</a>, appending <a href="#SkPath_kMove_Verb">kMove Verb</a>,
-four <a href="#SkPath_kConic_Verb">kConic Verb</a>, and <a href="#SkPath_kClose_Verb">kClose Verb</a>. <a href="undocumented#Circle">Circle</a> begins at(<a href="#SkPath_addCircle_x">x</a> + <a href="#SkPath_addCircle_radius">radius</a>, <a href="#SkPath_addCircle_y">y</a>),
-continuing clockwise if <a href="#SkPath_addCircle_dir">dir</a> is <a href="#SkPath_kCW_Direction">kCW Direction</a>, and counterclockwise if <a href="#SkPath_addCircle_dir">dir</a> is
-<a href="#SkPath_kCCW_Direction">kCCW Direction</a>.
+four <a href="#SkPath_kConic_Verb">kConic Verb</a>, and <a href="#SkPath_kClose_Verb">kClose Verb</a>. <a href="undocumented#Circle">Circle</a> begins at:
+(<a href="#SkPath_addCircle_x">x</a> + <a href="#SkPath_addCircle_radius">radius</a>, <a href="#SkPath_addCircle_y">y</a>),
+continuing
+clockwise if <a href="#SkPath_addCircle_dir">dir</a> is <a href="#SkPath_kCW_Direction">kCW Direction</a>, and counterclockwise if <a href="#SkPath_addCircle_dir">dir</a> is <a href="#SkPath_kCCW_Direction">kCCW Direction</a>.
Has no effect if <a href="#SkPath_addCircle_radius">radius</a> is zero or negative.
@@ -3725,7 +3734,7 @@ true to add <a href="undocumented#Line">Line</a> connecting <a href="#Contour">C
## <a name="SkPath_AddPathMode"></a> Enum SkPath::AddPathMode
-<pre style="padding: 1em 1em 1em 1em;width: 44em; background-color: #f0f0f0">
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
enum <a href="#SkPath_AddPathMode">AddPathMode</a> {
<a href="#SkPath_kAppend_AddPathMode">kAppend AddPathMode</a>,
<a href="#SkPath_kExtend_AddPathMode">kExtend AddPathMode</a>,
@@ -4096,7 +4105,7 @@ set value of <a href="#Last_Point">Last Point</a></td>
## <a name="SkPath_SegmentMask"></a> Enum SkPath::SegmentMask
-<pre style="padding: 1em 1em 1em 1em;width: 44em; background-color: #f0f0f0">
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
enum <a href="#SkPath_SegmentMask">SegmentMask</a> {
<a href="#SkPath_kLine_SegmentMask">kLine SegmentMask</a> = 1 << 0,
<a href="#SkPath_kQuad_SegmentMask">kQuad SegmentMask</a> = 1 << 1,
@@ -4225,9 +4234,9 @@ true if <a href="undocumented#Point">Point</a> is in <a href="#Path">Path</a>
void dump(SkWStream* stream, bool forceClose, bool dumpAsHex) const
</pre>
-Writes text representation of <a href="#Path">Path</a> to <a href="#SkPath_dump_stream">stream</a>. If <a href="#SkPath_dump_stream">stream</a> is nullptr, <a href="#SkPath_dump_2">dump</a> writes to
-standard output. Set <a href="#SkPath_dump_forceClose">forceClose</a> to true to get
-edges used to fill <a href="#Path">Path</a>. Set <a href="#SkPath_dump_dumpAsHex">dumpAsHex</a> true to generate exact binary representations
+Writes text representation of <a href="#Path">Path</a> to <a href="#SkPath_dump_stream">stream</a>. If <a href="#SkPath_dump_stream">stream</a> is nullptr, writes to
+standard output. Set <a href="#SkPath_dump_forceClose">forceClose</a> to true to get edges used to fill <a href="#Path">Path</a>.
+Set <a href="#SkPath_dump_dumpAsHex">dumpAsHex</a> true to generate exact binary representations
of floating point numbers used in <a href="#Point_Array">Point Array</a> and <a href="#Weight">Conic Weights</a>.
### Parameters
@@ -4554,7 +4563,7 @@ Iterates through <a href="#Verb_Array">Verb Array</a>, and associated <a href="#
Provides options to treat open <a href="#Contour">Contours</a> as closed, and to ignore
degenerate data.
-<pre style="padding: 1em 1em 1em 1em;width: 44em; background-color: #f0f0f0">
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
class <a href="#SkPath_Iter_Iter">Iter</a> {
public:
<a href="#SkPath_Iter_Iter">Iter()</a>;
@@ -4899,7 +4908,7 @@ with close(), forceClose is true : isClosedContour returns true
Iterates through <a href="#Verb_Array">Verb Array</a>, and associated <a href="#Point_Array">Point Array</a> and <a href="#Conic_Weight">Conic Weight</a>.
<a href="#Verb_Array">Verb Array</a>, <a href="#Point_Array">Point Array</a>, and <a href="#Conic_Weight">Conic Weight</a> are returned unaltered.
-<pre style="padding: 1em 1em 1em 1em;width: 44em; background-color: #f0f0f0">
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
class <a href="#SkPath_RawIter_RawIter">RawIter</a> {
public:
<a href="#SkPath_RawIter_RawIter">RawIter()</a>;
diff --git a/site/user/api/SkPixmap_Reference.md b/site/user/api/SkPixmap_Reference.md
index 9c7deb64cb..6e44b60aff 100644
--- a/site/user/api/SkPixmap_Reference.md
+++ b/site/user/api/SkPixmap_Reference.md
@@ -49,13 +49,11 @@ to manage pixel memory; <a href="undocumented#Pixel_Ref">Pixel Ref</a> is safe a
| <a href="#SkPixmap_bounds">bounds</a> | Returns <a href="#SkPixmap_width">width</a> and <a href="#SkPixmap_height">height</a> as Rectangle. |
| <a href="#SkPixmap_colorSpace">colorSpace</a> | Returns <a href="#Info">Image Info</a> <a href="undocumented#Color_Space">Color Space</a>. |
| <a href="#SkPixmap_colorType">colorType</a> | Returns <a href="#Info">Image Info</a> <a href="undocumented#Color_Type">Color Type</a>. |
+| <a href="#SkPixmap_computeByteSize">computeByteSize</a> | Returns size required for pixels. |
| <a href="#SkPixmap_computeIsOpaque">computeIsOpaque</a> | Returns true if all pixels are opaque. |
| <a href="#SkPixmap_erase">erase</a> | Writes <a href="undocumented#Color">Color</a> to pixels. |
| <a href="#SkPixmap_extractSubset">extractSubset</a> | Sets pointer to portion of original. |
| <a href="#SkPixmap_getColor">getColor</a> | Returns one pixel as <a href="#Unpremultiply">Unpremultiplied</a> <a href="undocumented#Color">Color</a>. |
-| <a href="#SkPixmap_getSafeSize">getSafeSize</a> | Returns minimum size required for pixels in 32 bits. |
-| <a href="#SkPixmap_getSafeSize64">getSafeSize64</a> | Returns minimum size required for pixels in 64 bits. |
-| <a href="#SkPixmap_getSize64">getSize64</a> | Returns conservative size required for pixels. |
| <a href="#SkPixmap_height">height</a> | Returns pixel row count. |
| <a href="#SkPixmap_info">info</a> | Returns <a href="#Info">Image Info</a>. |
| <a href="#SkPixmap_isOpaque">isOpaque</a> | Returns true if <a href="#Info">Image Info</a> describes opaque pixels. |
@@ -389,7 +387,8 @@ size_t rowBytes() const
</pre>
Returns row bytes, the interval from one pixel row to the next. Row bytes
-is at least as large as<a href="#SkPixmap_width">width</a> * <a href="#SkPixmap_info">info</a>.bytesPerPixel().
+is at least as large as:
+<a href="#SkPixmap_width">width</a> * <a href="#SkPixmap_info">info</a>.bytesPerPixel().
Returns zero if <a href="#SkPixmap_colorType">colorType</a> is <a href="undocumented#SkColorType">kUnknown SkColorType</a>.
It is up to the <a href="SkBitmap_Reference#Bitmap">Bitmap</a> creator to ensure that row bytes is a useful value.
@@ -460,6 +459,7 @@ int width() const
</pre>
Returns pixel count in each pixel row. Should be equal or less than:
+
<a href="#SkPixmap_rowBytes">rowBytes</a> / <a href="#SkPixmap_info">info</a>.bytesPerPixel().
### Return Value
@@ -657,7 +657,7 @@ isOpaque: true
SkIRect bounds() const
</pre>
-Returns <a href="SkIRect_Reference#IRect">IRect</a>{ 0, 0, <a href="#SkPixmap_width">width</a>, <a href="#SkPixmap_height">height</a> }.
+Returns <a href="SkIRect_Reference#IRect">IRect</a> { 0, 0, <a href="#SkPixmap_width">width</a>, <a href="#SkPixmap_height">height</a> }.
### Return Value
@@ -759,68 +759,6 @@ color: kRGBA_F16_SkColorType bytesPerPixel: 8 shiftPerPixel: 3
---
-<a name="SkPixmap_getSize64"></a>
-## getSize64
-
-<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
-uint64_t getSize64() const
-</pre>
-
-Returns conservative memory required for pixel storage.
-Includes unused memory on last row when <a href="#SkPixmap_rowBytesAsPixels">rowBytesAsPixels</a> exceeds <a href="#SkPixmap_width">width</a>.
-
-### Return Value
-
-conservative pixel storage size
-
-### See Also
-
-<a href="#SkPixmap_getSafeSize64">getSafeSize64</a> <a href="#SkPixmap_getSafeSize">getSafeSize</a> <a href="#SkPixmap_height">height</a> <a href="#SkPixmap_rowBytes">rowBytes</a> <a href="#SkPixmap_width">width</a> <a href="#SkImageInfo_bytesPerPixel">SkImageInfo::bytesPerPixel</a>
-
----
-
-<a name="SkPixmap_getSafeSize64"></a>
-## getSafeSize64
-
-<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
-uint64_t getSafeSize64() const
-</pre>
-
-Returns minimum memory required for pixel storage.
-Does not include unused memory on last row when <a href="#SkPixmap_rowBytesAsPixels">rowBytesAsPixels</a> exceeds <a href="#SkPixmap_width">width</a>.
-
-### Return Value
-
-exact pixel storage size
-
-### See Also
-
-<a href="#SkPixmap_getSize64">getSize64</a> <a href="#SkPixmap_getSafeSize">getSafeSize</a> <a href="#SkPixmap_height">height</a> <a href="#SkPixmap_rowBytes">rowBytes</a> <a href="#SkPixmap_width">width</a> <a href="#SkImageInfo_bytesPerPixel">SkImageInfo::bytesPerPixel</a>
-
----
-
-<a name="SkPixmap_getSafeSize"></a>
-## getSafeSize
-
-<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
-size_t getSafeSize() const
-</pre>
-
-Returns minimum memory required for pixel storage.
-Does not include unused memory on last row when <a href="#SkPixmap_rowBytesAsPixels">rowBytesAsPixels</a> exceeds <a href="#SkPixmap_width">width</a>.
-Returns zero if value is does not fit in a signed 32-bit integer.
-The largest value than can be returned is 2,147,483,647.
-
-### Return Value
-
-exact pixel storage size if size fits in signed 32 bits
-
-### See Also
-
-<a href="#SkPixmap_getSize64">getSize64</a> <a href="#SkPixmap_getSafeSize64">getSafeSize64</a> <a href="#SkPixmap_height">height</a> <a href="#SkPixmap_rowBytes">rowBytes</a> <a href="#SkPixmap_width">width</a> <a href="#SkImageInfo_bytesPerPixel">SkImageInfo::bytesPerPixel</a> <a href="undocumented#sk_64_isS32">sk 64 isS32</a>
-
----
-
<a name="SkPixmap_computeByteSize"></a>
## computeByteSize
@@ -1679,7 +1617,8 @@ bool readPixels(const SkImageInfo& dstInfo, void* dstPixels, size_t dstRowBytes,
int srcX, int srcY, SkTransferFunctionBehavior behavior) const
</pre>
-Copies a <a href="SkRect_Reference#Rect">Rect</a> of pixels to <a href="#SkPixmap_readPixels_dstPixels">dstPixels</a>. Copy starts at (<a href="#SkPixmap_readPixels_srcX">srcX</a>, <a href="#SkPixmap_readPixels_srcY">srcY</a>), and does not exceed(this-><a href="#SkPixmap_width">width</a>, this-><a href="#SkPixmap_height">height</a>).
+Copies a <a href="SkRect_Reference#Rect">Rect</a> of pixels to <a href="#SkPixmap_readPixels_dstPixels">dstPixels</a>. Copy starts at (<a href="#SkPixmap_readPixels_srcX">srcX</a>, <a href="#SkPixmap_readPixels_srcY">srcY</a>), and does not
+exceed (this-><a href="#SkPixmap_width">width</a>, this-><a href="#SkPixmap_height">height</a>).
<a href="#SkPixmap_readPixels_dstInfo">dstInfo</a> specifies <a href="#SkPixmap_width">width</a>, <a href="#SkPixmap_height">height</a>, <a href="undocumented#Color_Type">Color Type</a>, <a href="undocumented#Alpha_Type">Alpha Type</a>, and
<a href="undocumented#Color_Space">Color Space</a> of destination. <a href="#SkPixmap_readPixels_dstRowBytes">dstRowBytes</a> specifics the gap from one destination
@@ -1693,7 +1632,9 @@ If this-><a href="#SkPixmap_alphaType">alphaType</a> is <a href="undocumented#Sk
match. If this-><a href="#SkPixmap_colorSpace">colorSpace</a> is nullptr, <a href="#SkPixmap_readPixels_dstInfo">dstInfo</a>.<a href="#SkPixmap_colorSpace">colorSpace</a> must match. Returns
false if pixel conversion is not possible.
<a href="#SkPixmap_readPixels_srcX">srcX</a> and <a href="#SkPixmap_readPixels_srcY">srcY</a> may be negative to copy only top or left of source. Returns
-false if <a href="#SkPixmap_width">width</a> or <a href="#SkPixmap_height">height</a> is zero or negative. Returns false ifabs(srcX) >= this-><a href="#SkPixmap_width">width</a>,
+false if <a href="#SkPixmap_width">width</a> or <a href="#SkPixmap_height">height</a> is zero or negative. Returns false if:
+
+abs(srcX) >= this-><a href="#SkPixmap_width">width</a>,
or ifabs(srcY) >= this-><a href="#SkPixmap_height">height</a>.
If <a href="#SkPixmap_readPixels_behavior">behavior</a> is <a href="#SkTransferFunctionBehavior_kRespect">SkTransferFunctionBehavior::kRespect</a>: converts source
@@ -1738,7 +1679,7 @@ bool readPixels(const SkImageInfo& dstInfo, void* dstPixels, size_t dstRowBytes)
</pre>
Copies a <a href="SkRect_Reference#Rect">Rect</a> of pixels to <a href="#SkPixmap_readPixels_2_dstPixels">dstPixels</a>. Copy starts at (0, 0), and does not
-exceed(this-><a href="#SkPixmap_width">width</a>, this-><a href="#SkPixmap_height">height</a>).
+exceed (this-><a href="#SkPixmap_width">width</a>, this-><a href="#SkPixmap_height">height</a>).
<a href="#SkPixmap_readPixels_2_dstInfo">dstInfo</a> specifies <a href="#SkPixmap_width">width</a>, <a href="#SkPixmap_height">height</a>, <a href="undocumented#Color_Type">Color Type</a>, <a href="undocumented#Alpha_Type">Alpha Type</a>, and
<a href="undocumented#Color_Space">Color Space</a> of destination. <a href="#SkPixmap_readPixels_2_dstRowBytes">dstRowBytes</a> specifics the gap from one destination
@@ -1786,7 +1727,7 @@ bool readPixels(const SkImageInfo& dstInfo, void* dstPixels, size_t dstRowBytes,
</pre>
Copies a <a href="SkRect_Reference#Rect">Rect</a> of pixels to <a href="#SkPixmap_readPixels_3_dstPixels">dstPixels</a>. Copy starts at (<a href="#SkPixmap_readPixels_3_srcX">srcX</a>, <a href="#SkPixmap_readPixels_3_srcY">srcY</a>), and does not
-exceed(this-><a href="#SkPixmap_width">width</a>, this-><a href="#SkPixmap_height">height</a>).
+exceed (this-><a href="#SkPixmap_width">width</a>, this-><a href="#SkPixmap_height">height</a>).
<a href="#SkPixmap_readPixels_3_dstInfo">dstInfo</a> specifies <a href="#SkPixmap_width">width</a>, <a href="#SkPixmap_height">height</a>, <a href="undocumented#Color_Type">Color Type</a>, <a href="undocumented#Alpha_Type">Alpha Type</a>, and
<a href="undocumented#Color_Space">Color Space</a> of destination. <a href="#SkPixmap_readPixels_3_dstRowBytes">dstRowBytes</a> specifics the gap from one destination
@@ -1800,7 +1741,9 @@ If this-><a href="#SkPixmap_alphaType">alphaType</a> is <a href="undocumented#Sk
match. If this-><a href="#SkPixmap_colorSpace">colorSpace</a> is nullptr, <a href="#SkPixmap_readPixels_3_dstInfo">dstInfo</a>.<a href="#SkPixmap_colorSpace">colorSpace</a> must match. Returns
false if pixel conversion is not possible.
<a href="#SkPixmap_readPixels_3_srcX">srcX</a> and <a href="#SkPixmap_readPixels_3_srcY">srcY</a> may be negative to copy only top or left of source. Returns
-false if this-><a href="#SkPixmap_width">width</a> or this-><a href="#SkPixmap_height">height</a> is zero or negative. Returns false ifabs(srcX) >= this-><a href="#SkPixmap_width">width</a>,
+false if this-><a href="#SkPixmap_width">width</a> or this-><a href="#SkPixmap_height">height</a> is zero or negative. Returns false if:
+
+abs(srcX) >= this-><a href="#SkPixmap_width">width</a>,
or ifabs(srcY) >= this-><a href="#SkPixmap_height">height</a>.
### Parameters
@@ -1849,7 +1792,9 @@ If this-><a href="#SkPixmap_alphaType">alphaType</a> is <a href="undocumented#Sk
match. If this-><a href="#SkPixmap_colorSpace">colorSpace</a> is nullptr, <a href="#SkPixmap_readPixels_4_dst">dst</a>.<a href="#SkPixmap_info">info</a>.<a href="#SkPixmap_colorSpace">colorSpace</a> must match. Returns
false if pixel conversion is not possible.
<a href="#SkPixmap_readPixels_4_srcX">srcX</a> and <a href="#SkPixmap_readPixels_4_srcY">srcY</a> may be negative to copy only top or left of source. Returns
-false this-><a href="#SkPixmap_width">width</a> or this-><a href="#SkPixmap_height">height</a> is zero or negative. Returns false ifabs(srcX) >= this-><a href="#SkPixmap_width">width</a>,
+false this-><a href="#SkPixmap_width">width</a> or this-><a href="#SkPixmap_height">height</a> is zero or negative. Returns false if:
+
+abs(srcX) >= this-><a href="#SkPixmap_width">width</a>,
or ifabs(srcY) >= this-><a href="#SkPixmap_height">height</a>.
### Parameters
diff --git a/site/user/api/SkRect_Reference.md b/site/user/api/SkRect_Reference.md
index 4dd16b897e..fe1f090331 100644
--- a/site/user/api/SkRect_Reference.md
+++ b/site/user/api/SkRect_Reference.md
@@ -32,7 +32,7 @@ integer input cannot convert to <a href="undocumented#SkScalar">SkScalar</a> wit
| description | function |
| --- | --- |
| <a href="#SkRect_Intersects">Intersects</a> | Returns true if areas overlap. |
-| <a href="#SkRect_Make">Make</a> | Constructs from <a href="#Size">ISize</a> returning (0, 0, <a href="#SkRect_width">width</a>, <a href="#SkRect_height">height</a>). |
+| <a href="#SkRect_Make">Make</a> | Constructs from <a href="undocumented#ISize">ISize</a> returning (0, 0, <a href="#SkRect_width">width</a>, <a href="#SkRect_height">height</a>). |
| <a href="#SkRect_MakeEmpty">MakeEmpty</a> | Constructs from bounds of (0, 0, 0, 0). |
| <a href="#SkRect_MakeFromIRect">MakeFromIRect</a> | Deprecated. |
| <a href="#SkRect_MakeIWH">MakeIWH</a> | Constructs from int input returning (0, 0, <a href="#SkRect_width">width</a>, <a href="#SkRect_height">height</a>). |
@@ -2016,9 +2016,12 @@ rect: 5, 1, 55, 86
# <a name="Intersection"></a> Intersection
<a href="#Rect">Rects</a> <a href="#SkRect_intersect">intersect</a> when they enclose a common area. To <a href="#SkRect_intersect">intersect</a>, each of the pair
must describe area; <a href="#SkRect_fLeft">fLeft</a> is less than <a href="#SkRect_fRight">fRight</a>, and <a href="#SkRect_fTop">fTop</a> is less than <a href="#SkRect_fBottom">fBottom</a>;
-empty() returns false. The intersection of <a href="#Rect">Rect</a> a and <a href="#Rect">Rect</a> b can be described by:
+empty() returns false. The intersection of <a href="#Rect">Rect</a> pair can be described by:
+
(max(a.fLeft, b.fLeft), max(a.fTop, b.fTop),
-min(a.fRight, b.fRight), min(a.fBottom, b.fBottom))The intersection is only meaningful if the resulting <a href="#Rect">Rect</a> is not empty and
+min(a.fRight, b.fRight), min(a.fBottom, b.fBottom)).
+
+The intersection is only meaningful if the resulting <a href="#Rect">Rect</a> is not empty and
describes an area: <a href="#SkRect_fLeft">fLeft</a> is less than <a href="#SkRect_fRight">fRight</a>, and <a href="#SkRect_fTop">fTop</a> is less than <a href="#SkRect_fBottom">fBottom</a>.
<a name="SkRect_intersect"></a>
@@ -2443,6 +2446,7 @@ void growToInclude(SkPoint pt)
</pre>
Grows <a href="#Rect">Rect</a> to include (<a href="#SkRect_growToInclude_pt">pt</a>.fX, <a href="#SkRect_growToInclude_pt">pt</a>.fY), modifying it so that:
+
<a href="#SkRect_fLeft">fLeft</a> <= <a href="#SkRect_growToInclude_pt">pt</a>.fX <= <a href="#SkRect_fRight">fRight</a> && <a href="#SkRect_fTop">fTop</a> <= <a href="#SkRect_growToInclude_pt">pt</a>.fY <= <a href="#SkRect_fBottom">fBottom</a>.
If <a href="#Rect">Rect</a> is initialized with <a href="#SkRect_setLargestInverted">setLargestInverted</a>, then <a href="#Rect">Rect</a> will contain bounds of
@@ -2518,6 +2522,7 @@ void growToInclude(const SkPoint pts[], size_t stride, int count)
For each of <a href="#SkRect_growToInclude_3_count">count</a> <a href="undocumented#Point">Point</a> in <a href="#SkRect_growToInclude_3_pts">pts</a>, grows <a href="#Rect">Rect</a> to include (pt.fX, pt.fY), modifying
it so that:
<a href="#SkRect_fLeft">fLeft</a> <= pt.fX <= <a href="#SkRect_fRight">fRight</a> && <a href="#SkRect_fTop">fTop</a> <= pt.fY <= <a href="#SkRect_fBottom">fBottom</a>.
+
<a href="undocumented#Point">Point</a> may be followed with other data in each array element. <a href="#SkRect_growToInclude_3_stride">stride</a> is number
of bytes in element; the interval to skip to advance from one <a href="undocumented#Point">Point</a> to
the next.
diff --git a/site/user/api/undocumented.md b/site/user/api/undocumented.md
index cd6cb5fbd1..dc102f84ab 100644
--- a/site/user/api/undocumented.md
+++ b/site/user/api/undocumented.md
@@ -25,6 +25,8 @@ SkCanvas* beginPage(SkScalar width, SkScalar height,
# <a name="Size"></a> Size
+# <a name="SkSize"></a> Struct SkSize
+
# <a name="Arc"></a> Arc
# <a name="Line"></a> Line
@@ -85,6 +87,10 @@ bool equalsWithinTolerance(const SkPoint& p) const
## <a name="ArcTo"></a> ArcTo
+# <a name="ISize"></a> ISize
+
+# <a name="SkISize"></a> Struct SkISize
+
# <a name="Alias"></a> Alias
# <a name="Anti-alias"></a> Anti-alias
@@ -521,6 +527,15 @@ size_t computeByteSize(size_t rowBytes) const
---
+<a name="SkImageInfo_validate"></a>
+## validate
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+void validate() const
+</pre>
+
+---
+
# <a name="SkImage"></a> Class SkImage
<a name="SkImage_makeShader"></a>
@@ -874,6 +889,10 @@ void setImmutable()
---
+# <a name="Point3"></a> Point3
+
+# <a name="SkPoint3"></a> Struct SkPoint3
+
# <a name="Premultiply"></a> Premultiply
# <a name="Raster_Engine"></a> Raster Engine
@@ -952,7 +971,7 @@ static sk_sp&lt;SkShader&gt; MakeBitmapShader(const SkBitmap& src, TileMode tmx,
# <a name="Stream"></a> Stream
-# <a name="SkFlattenable"></a> Class SkFlattenable
+# <a name="SkStream"></a> Class SkStream
# <a name="String"></a> String
diff --git a/site/user/api/usingBookmaker.md b/site/user/api/usingBookmaker.md
index 7a93f7a304..96653510ba 100644
--- a/site/user/api/usingBookmaker.md
+++ b/site/user/api/usingBookmaker.md
@@ -8,22 +8,22 @@ Install<a href="usingBookmaker#Go">Go</a>if needed.
Get the fiddle command line interface tool.
By default this will appear in your home directory.
-<pre style="padding: 1em 1em 1em 1em;width: 44em; background-color: #f0f0f0">
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
$ go get go.skia.org/infra/fiddle/go/fiddlecli</pre>
Build <a href="#Bookmaker">Bookmaker</a>.
-<pre style="padding: 1em 1em 1em 1em;width: 44em; background-color: #f0f0f0">
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
$ ninja -<a href="undocumented#C">C</a> out/dir bookmaker</pre>
Generate an starter <a href="#Bookmaker">Bookmaker</a> file from an existing include.
-<pre style="padding: 1em 1em 1em 1em;width: 44em; background-color: #f0f0f0">
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
$ ./out/dir/bookmaker -i include/core/<a href="undocumented#SkXXX.h">SkXXX.h</a> -t docs</pre>
If a method or function has an unnamed parameter, bookmaker generates an error:
-<pre style="padding: 1em 1em 1em 1em;width: 44em; background-color: #f0f0f0">
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
<a href="undocumented#C">C</a>:/puregit/include/core/<a href="SkPixmap_Reference#SkPixmap">SkPixmap</a>.h(208): error: # missing param name
bool erase(const SkColor4f&, const SkIRect* subset = nullptr) const
^
@@ -34,14 +34,14 @@ them. After naming all parameters, check in the include before continuing.
A successful run generates
-<pre style="padding: 1em 1em 1em 1em;width: 44em; background-color: #f0f0f0">
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
docs/<a href="undocumented#SkXXX_Reference">SkXXX Reference</a>.bmh</pre>
.
Next, use your favorite editor to fill out
-<pre style="padding: 1em 1em 1em 1em;width: 44em; background-color: #f0f0f0">
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
docs/<a href="undocumented#SkXXX_Reference">SkXXX Reference</a>.bmh</pre>
.
@@ -82,13 +82,13 @@ correct parents.
If you run <a href="#Bookmaker">Bookmaker</a> inside <a href="usingBookmaker#Visual_Studio">Visual Studio</a>, you can click on errors and it
will take you to the source line in question.
-<pre style="padding: 1em 1em 1em 1em;width: 44em; background-color: #f0f0f0">
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
$ ./out/dir/bookmaker -e fiddle.json -b docs</pre>
Once complete, run fiddlecli to generate the example hashes.
Errors are contained by the output but aren't reported yet.
-<pre style="padding: 1em 1em 1em 1em;width: 44em; background-color: #f0f0f0">
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
$ $GOPATH/bin/fiddlecli --input fiddle.json --output fiddleout.json</pre>
Generate <a href="usingBookmaker#bmh_SkXXX">bmh SkXXX</a>.md from <a href="usingBookmaker#SkXXX">SkXXX</a>.bmh and fiddleout.json.
@@ -96,19 +96,19 @@ Error checking includes: undefined references, fiddle compiler errors,
missing or mismatched printf output.
Again, you can click on any errors inside <a href="usingBookmaker#Visual_Studio">Visual Studio</a>.
-<pre style="padding: 1em 1em 1em 1em;width: 44em; background-color: #f0f0f0">
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
$ ./out/dir/bookmaker -r site/user/api -b docs -f fiddleout.json</pre>
The original include may have changed since you started creating the markdown.
Check to see if it is up to date.
This reports if a method no longer exists or its parameters have changed.
-<pre style="padding: 1em 1em 1em 1em;width: 44em; background-color: #f0f0f0">
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
$ ./out/dir/bookmaker -x -b docs/<a href="usingBookmaker#SkXXX">SkXXX</a>.bmh -i include/core/<a href="usingBookmaker#SkXXX">SkXXX</a>.h</pre>
Generate an updated include header. Run:
-<pre style="padding: 1em 1em 1em 1em;width: 44em; background-color: #f0f0f0">
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
$ ./out/dir/bookmaker -p -b docs -i include/core/<a href="usingBookmaker#SkXXX">SkXXX</a>.h</pre>
to write the updated <a href="undocumented#SkXXX.h">SkXXX.h</a> to the current directory.
diff --git a/tools/bookmaker/bookmaker.cpp b/tools/bookmaker/bookmaker.cpp
index cc454982fd..e0694071e2 100644
--- a/tools/bookmaker/bookmaker.cpp
+++ b/tools/bookmaker/bookmaker.cpp
@@ -630,6 +630,9 @@ const Definition* Definition::hasParam(const string& ref) const {
}
bool Definition::methodHasReturn(const string& name, TextParser* methodParser) const {
+ if (methodParser->skipExact("static")) {
+ methodParser->skipWhiteSpace();
+ }
const char* lastStart = methodParser->fChar;
const char* nameInParser = methodParser->strnstr(name.c_str(), methodParser->fEnd);
methodParser->skipTo(nameInParser);
@@ -1160,6 +1163,8 @@ bool BmhParser::addDefinition(const char* defStart, bool hasEnd, MarkType markTy
case MarkType::kFile:
case MarkType::kHeight:
case MarkType::kImage:
+ case MarkType::kLiteral:
+ case MarkType::kOutdent:
case MarkType::kPlatform:
case MarkType::kSeeAlso:
case MarkType::kSubstitute:
@@ -2001,6 +2006,8 @@ vector<string> BmhParser::typeName(MarkType markType, bool* checkEnd) {
case MarkType::kFile:
case MarkType::kHeight:
case MarkType::kImage:
+ case MarkType::kLiteral:
+ case MarkType::kOutdent:
case MarkType::kPlatform:
case MarkType::kReturn:
case MarkType::kSeeAlso:
@@ -2335,6 +2342,7 @@ int main(int argc, char** const argv) {
}
if (!done && !FLAGS_spellcheck.isEmpty() && FLAGS_examples.isEmpty()) {
bmhParser.spellCheck(FLAGS_bmh[0], FLAGS_spellcheck);
+ bmhParser.fWroteOut = true;
done = true;
}
int examples = 0;
diff --git a/tools/bookmaker/bookmaker.h b/tools/bookmaker/bookmaker.h
index 857caf4c10..f5f53ff7ab 100644
--- a/tools/bookmaker/bookmaker.h
+++ b/tools/bookmaker/bookmaker.h
@@ -40,6 +40,7 @@ using std::vector;
enum class KeyWord {
kNone,
kSK_API,
+ kSK_BEGIN_REQUIRE_DENSE,
kBool,
kChar,
kClass,
@@ -107,10 +108,12 @@ enum class MarkType {
kLegend,
kLink,
kList,
+ kLiteral, // don't lookup hyperlinks, do substitution, etc
kMarkChar,
kMember,
kMethod,
kNoExample,
+ kOutdent,
kParam,
kPlatform,
kPrivate,
@@ -1063,6 +1066,7 @@ public:
fMaxLF = 2;
fPendingLF = 0;
fPendingSpace = 0;
+ fOutdentNext = false;
nl();
}
@@ -1078,46 +1082,14 @@ public:
fMaxLF = 1;
}
- bool writeBlockTrim(int size, const char* data) {
- while (size && ' ' >= data[0]) {
- ++data;
- --size;
- }
- while (size && ' ' >= data[size - 1]) {
- --size;
- }
- if (size <= 0) {
- fLastChar = '\0';
- return false;
- }
- SkASSERT(size < 16000);
- if (size > 3 && !strncmp("#end", data, 4)) {
- fMaxLF = 1;
- }
- if (this->leadingPunctuation(data, (size_t) size)) {
- fPendingSpace = 0;
- }
- writePending();
- if (fDebugOut) {
- string check(data, size);
- SkDebugf("%s", check.c_str());
- }
- fprintf(fOut, "%.*s", size, data);
- int added = 0;
- fLastChar = data[size - 1];
- while (size > 0 && '\n' != data[--size]) {
- ++added;
- }
- fColumn = size ? added : fColumn + added;
- fSpaces = 0;
- fLinefeeds = 0;
- fMaxLF = added > 2 && !strncmp("#if", &data[size + (size > 0)], 3) ? 1 : 2;
- return true;
- }
void writeBlock(int size, const char* data) {
SkAssertResult(writeBlockTrim(size, data));
}
+
+ void writeBlockIndent(int size, const char* data);
+ bool writeBlockTrim(int size, const char* data);
+
void writeCommentHeader() {
this->lf(2);
this->writeString("/**");
@@ -1129,6 +1101,8 @@ public:
this->lfcr();
}
+ void writePending();
+
// write a pending space, so that two consecutive calls
// don't double write, and trailing spaces on lines aren't written
void writeSpace(int count = 1) {
@@ -1139,62 +1113,12 @@ public:
fPendingSpace = count;
}
- void writeString(const char* str) {
- const size_t len = strlen(str);
- SkASSERT(len > 0);
- SkASSERT(' ' < str[0]);
- fLastChar = str[len - 1];
- SkASSERT(' ' < fLastChar);
- SkASSERT(!strchr(str, '\n'));
- if (this->leadingPunctuation(str, strlen(str))) {
- fPendingSpace = 0;
- }
- writePending();
- if (fDebugOut) {
- SkDebugf("%s", str);
- }
- fprintf(fOut, "%s", str);
- fColumn += len;
- fSpaces = 0;
- fLinefeeds = 0;
- fMaxLF = 2;
- }
+ void writeString(const char* str);
void writeString(const string& str) {
this->writeString(str.c_str());
}
- void writePending() {
- fPendingLF = SkTMin(fPendingLF, fMaxLF);
- bool wroteLF = false;
- while (fLinefeeds < fPendingLF) {
- if (fDebugOut) {
- SkDebugf("\n");
- }
- fprintf(fOut, "\n");
- ++fLinefeeds;
- wroteLF = true;
- }
- fPendingLF = 0;
- if (wroteLF) {
- SkASSERT(0 == fColumn);
- SkASSERT(fIndent >= fSpaces);
- if (fDebugOut) {
- SkDebugf("%*s", fIndent - fSpaces, "");
- }
- fprintf(fOut, "%*s", fIndent - fSpaces, "");
- fColumn = fIndent;
- fSpaces = fIndent;
- }
- for (int index = 0; index < fPendingSpace; ++index) {
- if (fDebugOut) {
- SkDebugf(" ");
- }
- fprintf(fOut, " ");
- ++fColumn;
- }
- fPendingSpace = 0;
- }
unordered_map<string, sk_sp<SkData>> fRawData;
unordered_map<string, vector<char>> fLFOnly;
@@ -1209,6 +1133,7 @@ public:
int fPendingSpace; // one or two spaces should preceed the next string or block
char fLastChar; // last written
bool fDebugOut; // set true to write to std out
+ bool fOutdentNext; // set at end of embedded struct to prevent premature outdent
private:
typedef TextParser INHERITED;
};
@@ -1226,6 +1151,7 @@ public:
kNo, // neither resolved nor output
kYes, // resolved, output
kOut, // not resolved, but output
+ kLiteral, // output untouched (FIXME: is this really different from kOut?)
};
enum class Exemplary {
@@ -1267,7 +1193,7 @@ public:
, { "Alias", nullptr, MarkType::kAlias, R_N, E_N, 0 }
, { "Bug", nullptr, MarkType::kBug, R_N, E_N, 0 }
, { "Class", &fClassMap, MarkType::kClass, R_Y, E_O, M_CSST | M(Root) }
-, { "Code", nullptr, MarkType::kCode, R_O, E_N, M_CSST | M_E }
+, { "Code", nullptr, MarkType::kCode, R_O, E_N, M_CSST | M_E | M(Method) }
, { "", nullptr, MarkType::kColumn, R_Y, E_N, M(Row) }
, { "", nullptr, MarkType::kComment, R_N, E_N, 0 }
, { "Const", &fConstMap, MarkType::kConst, R_Y, E_N, M_E | M_ST }
@@ -1291,10 +1217,12 @@ public:
, { "Legend", nullptr, MarkType::kLegend, R_Y, E_N, M(Table) }
, { "", nullptr, MarkType::kLink, R_N, E_N, M(Anchor) }
, { "List", nullptr, MarkType::kList, R_Y, E_N, M(Method) | M_CSST | M_E | M_D }
+, { "Literal", nullptr, MarkType::kLiteral, R_N, E_N, M(Code) }
, { "", nullptr, MarkType::kMarkChar, R_N, E_N, 0 }
, { "Member", nullptr, MarkType::kMember, R_Y, E_N, M(Class) | M(Struct) }
, { "Method", &fMethodMap, MarkType::kMethod, R_Y, E_Y, M_CSST }
, { "NoExample", nullptr, MarkType::kNoExample, R_Y, E_N, 0 }
+, { "Outdent", nullptr, MarkType::kOutdent, R_N, E_N, M(Code) }
, { "Param", nullptr, MarkType::kParam, R_Y, E_N, M(Method) }
, { "Platform", nullptr, MarkType::kPlatform, R_N, E_N, M(Example) }
, { "Private", nullptr, MarkType::kPrivate, R_N, E_N, 0 }
@@ -1474,10 +1402,12 @@ public:
, { nullptr, MarkType::kLegend }
, { nullptr, MarkType::kLink }
, { nullptr, MarkType::kList }
+ , { nullptr, MarkType::kLiteral }
, { nullptr, MarkType::kMarkChar }
, { nullptr, MarkType::kMember }
, { nullptr, MarkType::kMethod }
, { nullptr, MarkType::kNoExample }
+ , { nullptr, MarkType::kOutdent }
, { nullptr, MarkType::kParam }
, { nullptr, MarkType::kPlatform }
, { nullptr, MarkType::kPrivate }
@@ -1685,6 +1615,20 @@ public:
this->writeEndTag(tagType, tagID.c_str(), spaces);
}
+ void writeIncompleteTag(const char* tagType, const string& tagID, int spaces = 1) {
+ this->writeString(string("#") + tagType + " " + tagID);
+ this->writeSpace(spaces);
+ this->writeString("incomplete");
+ this->writeSpace();
+ this->writeString("##");
+ this->lf(1);
+ }
+
+ void writeIncompleteTag(const char* tagType) {
+ this->writeString(string("#") + tagType + " incomplete ##");
+ this->lf(1);
+ }
+
void writeTableHeader(const char* col1, size_t pad, const char* col2) {
this->lf(1);
this->writeString("#Table");
@@ -1858,11 +1802,13 @@ public:
fBmhParser = nullptr;
fEnumDef = nullptr;
fMethodDef = nullptr;
- fStructDef = nullptr;
+ fBmhStructDef = nullptr;
fAttrDeprecated = nullptr;
fAnonymousEnumCount = 1;
fInStruct = false;
fWroteMethod = false;
+ fIndentNext = false;
+ fPendingMethod = false;
}
string resolveMethod(const char* start, const char* end, bool first);
@@ -1880,7 +1826,7 @@ private:
const Definition* fBmhMethod;
const Definition* fEnumDef;
const Definition* fMethodDef;
- const Definition* fStructDef;
+ const Definition* fBmhStructDef;
const Definition* fAttrDeprecated;
const char* fContinuation; // used to construct paren-qualified method name
int fAnonymousEnumCount;
@@ -1891,6 +1837,8 @@ private:
int fStructCommentTab;
bool fInStruct;
bool fWroteMethod;
+ bool fIndentNext;
+ bool fPendingMethod;
typedef IncludeParser INHERITED;
};
@@ -1988,7 +1936,15 @@ private:
fInList = false;
}
- BmhParser::Resolvable resolvable(MarkType markType) {
+ BmhParser::Resolvable resolvable(const Definition* definition) const {
+ MarkType markType = definition->fMarkType;
+ if (MarkType::kCode == markType) {
+ for (auto child : definition->fChildren) {
+ if (MarkType::kLiteral == child->fMarkType) {
+ return BmhParser::Resolvable::kLiteral;
+ }
+ }
+ }
if ((MarkType::kExample == markType
|| MarkType::kFunction == markType) && fHasFiddle) {
return BmhParser::Resolvable::kNo;
diff --git a/tools/bookmaker/includeParser.cpp b/tools/bookmaker/includeParser.cpp
index 4ad83d8aa7..c4ee8e7217 100644
--- a/tools/bookmaker/includeParser.cpp
+++ b/tools/bookmaker/includeParser.cpp
@@ -10,6 +10,7 @@
const IncludeKey kKeyWords[] = {
{ "", KeyWord::kNone, KeyProperty::kNone },
{ "SK_API", KeyWord::kSK_API, KeyProperty::kModifier },
+ { "SK_BEGIN_REQUIRE_DENSE", KeyWord::kSK_BEGIN_REQUIRE_DENSE, KeyProperty::kModifier },
{ "bool", KeyWord::kBool, KeyProperty::kNumber },
{ "char", KeyWord::kChar, KeyProperty::kNumber },
{ "class", KeyWord::kClass, KeyProperty::kObject },
@@ -105,7 +106,7 @@ void IncludeParser::checkForMissingParams(const vector<string>& methodParams,
}
}
if (!found) {
- this->writeEndTag("Param", methodParam, 2);
+ this->writeIncompleteTag("Param", methodParam, 2);
}
}
for (auto& foundParam : foundParams) {
@@ -508,11 +509,16 @@ void IncludeParser::dumpClassTokens(IClassDefinition& classDef) {
}
this->lf(2);
this->writeTag("Example");
+ this->lf(1);
+ this->writeString("// incomplete");
+ this->lf(1);
this->writeEndTag();
this->lf(2);
- this->writeEndTag("ToDo", "incomplete");
+ this->writeTag("SeeAlso");
+ this->writeSpace();
+ this->writeString("incomplete");
this->lf(2);
- this->writeEndTag();
+ this->writeEndTag("Method");
this->lf(2);
}
}
@@ -673,7 +679,7 @@ void IncludeParser::dumpComment(const Definition& token) {
this->nl();
}
this->lf(2);
- this->writeEndTag("Return");
+ this->writeIncompleteTag("Return");
}
}
}
@@ -1389,11 +1395,36 @@ bool IncludeParser::parseMethod(Definition* child, Definition* markupDef) {
auto tokenIter = child->fParent->fTokens.begin();
std::advance(tokenIter, child->fParentIndex);
tokenIter = std::prev(tokenIter);
- string nameStr(tokenIter->fStart, tokenIter->fContentEnd - tokenIter->fStart);
+ const char* nameEnd = tokenIter->fContentEnd;
+ bool add2 = false;
+ if ('[' == tokenIter->fStart[0]) {
+ auto closeParen = std::next(tokenIter);
+ SkASSERT(Definition::Type::kBracket == closeParen->fType &&
+ '(' == closeParen->fContentStart[0]);
+ nameEnd = closeParen->fContentEnd + 1;
+ closeParen = std::next(closeParen);
+ add2 = true;
+ if (Definition::Type::kKeyWord == closeParen->fType &&
+ KeyWord::kConst == closeParen->fKeyWord) {
+ add2 = false;
+ }
+ tokenIter = std::prev(tokenIter);
+ }
+ string nameStr(tokenIter->fStart, nameEnd - tokenIter->fStart);
+ if (add2) {
+ nameStr += "_2";
+ }
while (tokenIter != child->fParent->fTokens.begin()) {
auto testIter = std::prev(tokenIter);
switch (testIter->fType) {
case Definition::Type::kWord:
+ if (testIter == child->fParent->fTokens.begin() &&
+ (KeyWord::kIfdef == child->fParent->fKeyWord ||
+ KeyWord::kIfndef == child->fParent->fKeyWord ||
+ KeyWord::kIf == child->fParent->fKeyWord)) {
+ std::next(tokenIter);
+ break;
+ }
goto keepGoing;
case Definition::Type::kKeyWord: {
KeyProperty keyProperty = kKeyWords[(int) testIter->fKeyWord].fProperty;
@@ -1608,7 +1639,9 @@ bool IncludeParser::parseObject(Definition* child, Definition* markupDef) {
// pick up templated function pieces when method is found
break;
case Bracket::kDebugCode:
- // todo: handle this
+ if (!this->parseObjects(child, markupDef)) {
+ return false;
+ }
break;
case Bracket::kSquare: {
// check to see if parent is operator, the only case we handle so far
diff --git a/tools/bookmaker/includeWriter.cpp b/tools/bookmaker/includeWriter.cpp
index ff7c0e3c56..399fd4688b 100644
--- a/tools/bookmaker/includeWriter.cpp
+++ b/tools/bookmaker/includeWriter.cpp
@@ -11,8 +11,44 @@ void IncludeWriter::descriptionOut(const Definition* def) {
const char* commentStart = def->fContentStart;
int commentLen = (int) (def->fContentEnd - commentStart);
bool breakOut = false;
+ SkDEBUGCODE(bool wroteCode = false);
for (auto prop : def->fChildren) {
switch (prop->fMarkType) {
+ case MarkType::kCode: {
+ bool literal = false;
+ bool literalOutdent = false;
+ commentLen = (int) (prop->fStart - commentStart);
+ if (commentLen > 0) {
+ SkASSERT(commentLen < 1000);
+ if (Wrote::kNone != this->rewriteBlock(commentLen, commentStart, Phrase::kNo)) {
+ this->lf(2);
+ }
+ }
+ size_t childSize = prop->fChildren.size();
+ if (childSize) {
+ SkASSERT(1 == childSize || 2 == childSize); // incomplete
+ SkASSERT(MarkType::kLiteral == prop->fChildren[0]->fMarkType);
+ SkASSERT(1 == childSize || MarkType::kOutdent == prop->fChildren[1]->fMarkType);
+ commentStart = prop->fChildren[childSize - 1]->fContentStart;
+ literal = true;
+ literalOutdent = 2 == childSize &&
+ MarkType::kOutdent == prop->fChildren[1]->fMarkType;
+ }
+ commentLen = (int) (prop->fContentEnd - commentStart);
+ SkASSERT(commentLen > 0);
+ if (literal) {
+ if (!literalOutdent) {
+ fIndent += 4;
+ }
+ this->writeBlockIndent(commentLen, commentStart);
+ this->lf(2);
+ if (!literalOutdent) {
+ fIndent -= 4;
+ }
+ commentStart = prop->fTerminator;
+ SkDEBUGCODE(wroteCode = true);
+ }
+ } break;
case MarkType::kDefinedBy:
commentStart = prop->fTerminator;
break;
@@ -48,20 +84,35 @@ void IncludeWriter::descriptionOut(const Definition* def) {
commentStart = prop->fTerminator;
commentLen = (int) (def->fContentEnd - commentStart);
break;
- case MarkType::kFormula:
+ case MarkType::kFormula: {
commentLen = prop->fStart - commentStart;
if (commentLen > 0) {
if (Wrote::kNone != this->rewriteBlock(commentLen, commentStart, Phrase::kNo)) {
- this->lfcr();
+ if (commentLen > 1 && '\n' == prop->fStart[-1] &&
+ '\n' == prop->fStart[-2]) {
+ this->lf(1);
+ } else {
+ this->writeSpace();
+ }
}
}
- this->writeBlock(prop->length(), prop->fContentStart);
+ int saveIndent = fIndent;
+ if (fIndent < fColumn + 1) {
+ fIndent = fColumn + 1;
+ }
+ this->writeBlockIndent(prop->length(), prop->fContentStart);
+ fIndent = saveIndent;
commentStart = prop->fTerminator;
commentLen = (int) (def->fContentEnd - commentStart);
- if ('\n' == commentStart[0] && '\n' == commentStart[1]) {
+ if (commentLen > 1 && '\n' == commentStart[0] && '\n' == commentStart[1]) {
this->lf(2);
+ } else {
+ SkASSERT('\n' == prop->fTerminator[0]);
+ if ('.' != prop->fTerminator[1] && !fLinefeeds) {
+ this->writeSpace();
+ }
}
- break;
+ } break;
case MarkType::kToDo:
commentLen = (int) (prop->fStart - commentStart);
if (commentLen > 0) {
@@ -105,8 +156,10 @@ void IncludeWriter::descriptionOut(const Definition* def) {
break;
}
}
- SkASSERT(commentLen > 0 && commentLen < 1500);
- this->rewriteBlock(commentLen, commentStart, Phrase::kNo);
+ SkASSERT(wroteCode || (commentLen > 0 && commentLen < 1500));
+ if (commentLen > 0) {
+ this->rewriteBlock(commentLen, commentStart, Phrase::kNo);
+ }
}
void IncludeWriter::enumHeaderOut(const RootDefinition* root,
@@ -116,6 +169,10 @@ void IncludeWriter::enumHeaderOut(const RootDefinition* root,
child.fContentStart;
this->writeBlockTrim((int) (bodyEnd - fStart), fStart); // may write nothing
this->lf(2);
+ if (fIndentNext) {
+ fIndent += 4;
+ fIndentNext = false;
+ }
fDeferComment = nullptr;
fStart = child.fContentStart;
const auto& nameDef = child.fTokens.front();
@@ -172,6 +229,9 @@ void IncludeWriter::enumHeaderOut(const RootDefinition* root,
const char* commentEnd = test->fStart;
if (!wroteHeader &&
!this->contentFree((int) (commentEnd - commentStart), commentStart)) {
+ if (fIndentNext) {
+ fIndent += 4;
+ }
this->writeCommentHeader();
this->writeString("\\enum");
if (fullName.length() > 0) {
@@ -193,9 +253,15 @@ void IncludeWriter::enumHeaderOut(const RootDefinition* root,
}
this->rewriteBlock((int) (commentEnd - commentStart), commentStart, Phrase::kNo);
if (MarkType::kAnchor == test->fMarkType) {
+ bool newLine = commentEnd - commentStart > 1 &&
+ '\n' == commentEnd[-1] && '\n' == commentEnd[-2];
commentStart = test->fContentStart;
commentEnd = test->fChildren[0]->fStart;
- this->writeSpace();
+ if (newLine) {
+ this->lf(2);
+ } else {
+ this->writeSpace();
+ }
this->rewriteBlock((int) (commentEnd - commentStart), commentStart, Phrase::kNo);
lastAnchor = true; // this->writeSpace();
}
@@ -518,12 +584,17 @@ void IncludeWriter::enumSizeItems(const Definition& child) {
// walk children and output complete method doxygen description
void IncludeWriter::methodOut(const Definition* method, const Definition& child) {
+ if (fPendingMethod) {
+ fIndent -= 4;
+ fPendingMethod = false;
+ }
fBmhMethod = method;
fMethodDef = &child;
fContinuation = nullptr;
fDeferComment = nullptr;
- if (0 == fIndent) {
- fIndent = 4;
+ if (0 == fIndent || fIndentNext) {
+ fIndent += 4;
+ fIndentNext = false;
}
this->writeCommentHeader();
fIndent += 4;
@@ -602,13 +673,17 @@ Definition* IncludeWriter::structMemberOut(const Definition* memberStart, const
const char* blockEnd = fWroteMethod && fDeferComment ? fDeferComment->fStart - 1 :
memberStart->fStart;
this->writeBlockTrim((int) (blockEnd - blockStart), blockStart);
+ if (fIndentNext) {
+ fIndent += 4;
+ fIndentNext = false;
+ }
fWroteMethod = false;
const char* commentStart = nullptr;
ptrdiff_t commentLen = 0;
string name(child.fContentStart, (int) (child.fContentEnd - child.fContentStart));
bool isShort;
Definition* commentBlock = nullptr;
- for (auto memberDef : fStructDef->fChildren) {
+ for (auto memberDef : fBmhStructDef->fChildren) {
if (memberDef->fName.length() - name.length() == memberDef->fName.find(name)) {
commentStart = memberDef->fContentStart;
commentLen = memberDef->fContentEnd - commentStart;
@@ -668,8 +743,8 @@ Definition* IncludeWriter::structMemberOut(const Definition* memberStart, const
this->writeString("//!<");
this->writeSpace();
this->rewriteBlock(commentLen, commentStart, Phrase::kNo);
- this->lfcr();
}
+ this->lf(2);
return valueEnd;
}
@@ -784,7 +859,7 @@ void IncludeWriter::structSizeMembers(const Definition& child) {
fStructValueTab -= 1 /* ; */ ;
}
// iterate through bmh children and see which comments fit on include lines
- for (auto& member : fStructDef->fChildren) {
+ for (auto& member : fBmhStructDef->fChildren) {
if (MarkType::kMember != member->fMarkType) {
continue;
}
@@ -800,6 +875,21 @@ void IncludeWriter::structSizeMembers(const Definition& child) {
}
}
+static bool find_start(const Definition* startDef, const char* start) {
+ for (const auto& child : startDef->fTokens) {
+ if (child.fContentStart == start) {
+ return MarkType::kMethod == child.fMarkType;
+ }
+ if (child.fContentStart >= start) {
+ break;
+ }
+ if (find_start(&child, start)) {
+ return true;
+ }
+ }
+ return false;
+}
+
bool IncludeWriter::populate(Definition* def, ParentPair* prevPair, RootDefinition* root) {
ParentPair pair = { def, prevPair };
// write bulk of original include up to class, method, enum, etc., excepting preceding comment
@@ -816,11 +906,30 @@ bool IncludeWriter::populate(Definition* def, ParentPair* prevPair, RootDefiniti
bool inStruct = false;
bool inConstructor = false;
bool inInline = false;
+ bool eatOperator = false;
+ const Definition* requireDense = nullptr;
+ const Definition* startDef = nullptr;
for (auto& child : def->fTokens) {
+ if (KeyWord::kOperator == child.fKeyWord && method &&
+ Definition::MethodType::kOperator == method->fMethodType) {
+ eatOperator = true;
+ continue;
+ }
+ if (eatOperator) {
+ if (Bracket::kSquare == child.fBracket || Bracket::kParen == child.fBracket) {
+ continue;
+ }
+ eatOperator = false;
+ fContinuation = nullptr;
+ if (KeyWord::kConst == child.fKeyWord) {
+ continue;
+ }
+ }
if (memberEnd) {
if (memberEnd != &child) {
continue;
}
+ startDef = &child;
fStart = child.fContentStart + 1;
memberEnd = nullptr;
}
@@ -958,6 +1067,7 @@ bool IncludeWriter::populate(Definition* def, ParentPair* prevPair, RootDefiniti
continue;
}
const char* bodyEnd = fDeferComment ? fDeferComment->fContentStart - 1 :
+ fAttrDeprecated ? fAttrDeprecated->fContentStart - 1 :
child.fContentStart;
// FIXME: roll end-trimming into writeBlockTrim call
while (fStart < bodyEnd && ' ' >= bodyEnd[-1]) {
@@ -967,11 +1077,15 @@ bool IncludeWriter::populate(Definition* def, ParentPair* prevPair, RootDefiniti
if (blockSize) {
this->writeBlock(blockSize, fStart);
}
+ startDef = &child;
fStart = child.fContentStart;
methodName = root->fName + "::" + child.fName;
inConstructor = root->fName == child.fName;
fContinuation = child.fContentEnd;
method = root->find(methodName, RootDefinition::AllowParens::kNo);
+// if (!method) {
+// method = root->find(methodName + "()", RootDefinition::AllowParens::kNo);
+// }
if (!method) {
continue;
}
@@ -981,13 +1095,26 @@ bool IncludeWriter::populate(Definition* def, ParentPair* prevPair, RootDefiniti
}
this->methodOut(method, child);
if (fAttrDeprecated) {
+ startDef = fAttrDeprecated;
fStart = fAttrDeprecated->fContentStart;
fAttrDeprecated = nullptr;
}
continue;
}
if (Definition::Type::kKeyWord == child.fType) {
- const Definition* structDef = nullptr;
+ if (fIndentNext) {
+ SkDebugf("");
+ // too soon
+#if 0 // makes struct Lattice indent when it oughtn't
+ if (KeyWord::kEnum == child.fKeyWord) {
+ fIndent += 4;
+ }
+ if (KeyWord::kPublic != child.fKeyWord) {
+ fIndentNext = false;
+ }
+#endif
+ }
+ const Definition* cIncludeStructDef = nullptr;
switch (child.fKeyWord) {
case KeyWord::kStruct:
case KeyWord::kClass:
@@ -1002,20 +1129,51 @@ bool IncludeWriter::populate(Definition* def, ParentPair* prevPair, RootDefiniti
}
}
if (fInStruct) {
+ // try child; root+child; root->parent+child; etc.
+ int trial = 0;
+ const RootDefinition* search = root;
+ const Definition* parent = search->fParent;
+ do {
+ string name;
+ if (0 == trial) {
+ name = child.fName;
+ } else if (1 == trial) {
+ name = root->fName + "::" + child.fName;
+ } else {
+ SkASSERT(parent);
+ name = parent->fName + "::" + child.fName;
+ search = parent->asRoot();
+ parent = search->fParent;
+ }
+ fBmhStructDef = search->find(name, RootDefinition::AllowParens::kNo);
+ } while (!fBmhStructDef && ++trial);
+ root = const_cast<RootDefinition*>(fBmhStructDef->asRoot());
+ SkASSERT(root);
fIndent += 4;
- fStructDef = root->find(child.fName, RootDefinition::AllowParens::kNo);
- if (nullptr == structDef) {
- fStructDef = root->find(root->fName + "::" + child.fName,
- RootDefinition::AllowParens::kNo);
- }
this->structSizeMembers(child);
fIndent -= 4;
+ SkASSERT(!fIndentNext);
+ fIndentNext = true;
}
if (child.fChildren.size() > 0) {
const char* bodyEnd = fDeferComment ? fDeferComment->fContentStart - 1 :
child.fContentStart;
this->writeBlockTrim((int) (bodyEnd - fStart), fStart);
- fStart = child.fContentStart;
+ if (fPendingMethod) {
+ fIndent -= 4;
+ fPendingMethod = false;
+ }
+ startDef = requireDense ? requireDense : &child;
+ fStart = requireDense ? requireDense->fContentStart : child.fContentStart;
+ requireDense = nullptr;
+ if (!fInStruct && child.fName != root->fName) {
+ root = &fBmhParser->fClassMap[child.fName];
+ fRootTopic = root->fParent;
+ SkASSERT(!root->fVisited);
+ root->clearVisited();
+ fIndent = 0;
+ fBmhStructDef = root;
+ }
if (child.fName == root->fName) {
if (Definition* parent = root->fParent) {
if (MarkType::kTopic == parent->fMarkType ||
@@ -1030,36 +1188,43 @@ bool IncludeWriter::populate(Definition* def, ParentPair* prevPair, RootDefiniti
SkASSERT(0); // incomplete
}
} else {
- structDef = root->find(child.fName, RootDefinition::AllowParens::kNo);
- if (nullptr == structDef) {
- structDef = root->find(root->fName + "::" + child.fName,
+ SkASSERT(fInStruct);
+ #if 0
+ fBmhStructDef = root->find(child.fName, RootDefinition::AllowParens::kNo);
+ if (nullptr == fBmhStructDef) {
+ fBmhStructDef = root->find(root->fName + "::" + child.fName,
RootDefinition::AllowParens::kNo);
}
- if (!structDef) {
+ if (!fBmhStructDef) {
this->lf(2);
fIndent = 0;
this->writeBlock((int) (fStart - bodyEnd), bodyEnd);
this->lfcr();
continue;
}
+ #endif
Definition* codeBlock = nullptr;
- SkDEBUGCODE(Definition* nextBlock = nullptr);
- for (auto test : structDef->fChildren) {
+ Definition* nextBlock = nullptr;
+ for (auto test : fBmhStructDef->fChildren) {
if (MarkType::kCode == test->fMarkType) {
SkASSERT(!codeBlock); // FIXME: check enum for correct order earlier
codeBlock = test;
continue;
}
if (codeBlock) {
- SkDEBUGCODE(nextBlock = test);
+ nextBlock = test;
break;
}
}
// FIXME: trigger error earlier if inner #Struct or #Class is missing #Code
SkASSERT(nextBlock); // FIXME: check enum for correct order earlier
- const char* commentStart = structDef->fContentStart;
- const char* commentEnd = codeBlock->fStart;
- this->structOut(root, *structDef, commentStart, commentEnd);
+ const char* commentStart = codeBlock->fTerminator;
+ const char* commentEnd = nextBlock->fStart;
+ if (fIndentNext) {
+// fIndent += 4;
+ }
+ fIndentNext = true;
+ this->structOut(root, *fBmhStructDef, commentStart, commentEnd);
}
fDeferComment = nullptr;
} else {
@@ -1096,17 +1261,21 @@ bool IncludeWriter::populate(Definition* def, ParentPair* prevPair, RootDefiniti
case KeyWord::kSK_API:
case KeyWord::kTypedef:
break;
+ case KeyWord::kSK_BEGIN_REQUIRE_DENSE:
+ requireDense = &child;
+ break;
default:
SkASSERT(0);
}
- if (structDef) {
+ if (cIncludeStructDef) {
TextParser structName(&child);
SkAssertResult(structName.skipToEndBracket('{'));
+ startDef = &child;
fStart = structName.fChar + 1;
this->writeBlock((int) (fStart - child.fStart), child.fStart);
this->lf(2);
fIndent += 4;
- if (!this->populate(&child, &pair, const_cast<Definition*>(structDef)->asRoot())) {
+ if (!this->populate(&child, &pair, const_cast<Definition*>(cIncludeStructDef)->asRoot())) {
return false;
}
// output any remaining definitions at current indent level
@@ -1126,8 +1295,28 @@ bool IncludeWriter::populate(Definition* def, ParentPair* prevPair, RootDefiniti
if (!this->populate(child.fChildren[0], &pair, root)) {
return false;
}
- } else if (!this->populate(&child, &pair, root)) {
- return false;
+ } else {
+ if (!this->populate(&child, &pair, root)) {
+ return false;
+ }
+ if (KeyWord::kClass == child.fKeyWord || KeyWord::kStruct == child.fKeyWord) {
+ fStructMemberTab = 0;
+ if (fInStruct) {
+ fInStruct = false;
+ do {
+ SkASSERT(root);
+ root = const_cast<RootDefinition*>(root->fParent->asRoot());
+ } while (MarkType::kTopic == root->fMarkType ||
+ MarkType::kSubtopic == root->fMarkType);
+ SkASSERT(MarkType::kStruct == root->fMarkType ||
+ MarkType::kClass == root->fMarkType);
+ fPendingMethod = false;
+ if (startDef) {
+ fPendingMethod = find_start(startDef, fStart);
+ }
+ fOutdentNext = !fPendingMethod;
+ }
+ }
}
}
continue;
@@ -1140,17 +1329,25 @@ bool IncludeWriter::populate(Definition* def, ParentPair* prevPair, RootDefiniti
this->enumMembersOut(root, child);
this->writeString("};");
this->lf(2);
+ startDef = child.fParent;
fStart = child.fParent->fContentEnd;
SkASSERT(';' == fStart[0]);
++fStart;
fDeferComment = nullptr;
fInEnum = false;
+ if (fIndentNext) {
+// fIndent -= 4;
+ fIndentNext = false;
+ }
continue;
}
if (fAttrDeprecated) {
continue;
}
fDeferComment = nullptr;
+ if (KeyWord::kClass == def->fKeyWord || KeyWord::kStruct == def->fKeyWord) {
+ fIndentNext = true;
+ }
if (!this->populate(&child, &pair, root)) {
return false;
}
@@ -1162,13 +1359,17 @@ bool IncludeWriter::populate(Definition* def, ParentPair* prevPair, RootDefiniti
auto iter = def->fTokens.begin();
std::advance(iter, child.fParentIndex - 1);
memberStart = &*iter;
- if (!fStructDef) {
+ if (!fStructMemberTab) {
SkASSERT(KeyWord::kStruct == def->fParent->fKeyWord);
- fStructDef = def->fParent;
- this->structSizeMembers(*fStructDef);
+ fIndent += 4;
+ this->structSizeMembers(*def->fParent);
+ fIndent -= 4;
+// SkASSERT(!fIndentNext);
+ fIndentNext = true;
}
}
memberEnd = this->structMemberOut(memberStart, child);
+ startDef = &child;
fStart = child.fContentEnd + 1;
fDeferComment = nullptr;
}
@@ -1322,8 +1523,8 @@ string IncludeWriter::resolveRef(const char* start, const char* end, bool first,
rootDefIter = fBmhParser->fTopicMap.find(prefixedName);
if (fBmhParser->fTopicMap.end() != rootDefIter) {
rootDef = rootDefIter->second;
- } else if (fStructDef) {
- string localPrefix = fStructDef->fFiddle + '_' + undername;
+ } else if (fBmhStructDef) {
+ string localPrefix = fBmhStructDef->fFiddle + '_' + undername;
rootDefIter = fBmhParser->fTopicMap.find(localPrefix);
if (fBmhParser->fTopicMap.end() != rootDefIter) {
rootDef = rootDefIter->second;
@@ -1648,7 +1849,7 @@ IncludeWriter::Wrote IncludeWriter::rewriteBlock(int size, const char* data, Phr
break;
case Word::kCap:
case Word::kFirst:
- if (!isupper(last)) {
+ if (!isupper(last) && '~' != last) {
word = Word::kMixed;
}
break;
@@ -1697,6 +1898,14 @@ IncludeWriter::Wrote IncludeWriter::rewriteBlock(int size, const char* data, Phr
hasIndirection |= embeddedIndirection;
hasSymbol |= embeddedSymbol;
break;
+ case '~':
+ SkASSERT(Word::kStart == word);
+ word = PunctuationState::kStart == punctuation ? Word::kFirst : Word::kCap;
+ start = run;
+ hasUpper = true;
+ hasIndirection |= embeddedIndirection;
+ hasSymbol |= embeddedSymbol;
+ break;
default:
SkASSERT(0);
}
diff --git a/tools/bookmaker/mdOut.cpp b/tools/bookmaker/mdOut.cpp
index 242d667736..ed3cd2bcaf 100644
--- a/tools/bookmaker/mdOut.cpp
+++ b/tools/bookmaker/mdOut.cpp
@@ -324,7 +324,7 @@ bool MdOut::buildRefFromFile(const char* name, const char* outDir) {
bool MdOut::checkParamReturnBody(const Definition* def) const {
TextParser paramBody(def);
const char* descriptionStart = paramBody.fChar;
- if (!islower(descriptionStart[0])) {
+ if (!islower(descriptionStart[0]) && !isdigit(descriptionStart[0])) {
paramBody.skipToNonAlphaNum();
string ref = string(descriptionStart, paramBody.fChar - descriptionStart);
if (!this->isDefined(paramBody, ref, true)) {
@@ -349,7 +349,7 @@ void MdOut::childrenOut(const Definition* def, const char* start) {
} else if (MarkType::kEnumClass == def->fMarkType) {
fEnumClass = def;
}
- BmhParser::Resolvable resolvable = this->resolvable(def->fMarkType);
+ BmhParser::Resolvable resolvable = this->resolvable(def);
for (auto& child : def->fChildren) {
end = child->fStart;
if (BmhParser::Resolvable::kNo != resolvable) {
@@ -640,7 +640,7 @@ void MdOut::markTypeOut(Definition* def) {
case MarkType::kCode:
this->lfAlways(2);
fprintf(fOut, "<pre style=\"padding: 1em 1em 1em 1em;"
- "width: 44em; background-color: #f0f0f0\">");
+ "width: 50em; background-color: #f0f0f0\">");
this->lf(1);
break;
case MarkType::kColumn:
@@ -714,7 +714,7 @@ void MdOut::markTypeOut(Definition* def) {
fprintf(fOut, "<div><fiddle-embed name=\"%s\">", def->fHash.c_str());
} else {
fprintf(fOut, "<pre style=\"padding: 1em 1em 1em 1em;"
- "width: 44em; background-color: #f0f0f0\">");
+ "width: 50em; background-color: #f0f0f0\">");
this->lf(1);
}
} break;
@@ -742,6 +742,8 @@ void MdOut::markTypeOut(Definition* def) {
fprintf(fOut, "<table>");
this->lf(1);
break;
+ case MarkType::kLiteral:
+ break;
case MarkType::kMarkChar:
fBmhParser.fMC = def->fContentStart[0];
break;
@@ -768,7 +770,7 @@ void MdOut::markTypeOut(Definition* def) {
}
// TODO: put in css spec that we can define somewhere else (if markup supports that)
- // TODO: 50em below should match limt = 80 in formatFunction()
+ // TODO: 50em below should match limit = 80 in formatFunction()
this->writePending();
string preformattedStr = preformat(formattedStr);
fprintf(fOut, "<pre style=\"padding: 1em 1em 1em 1em;"
@@ -781,6 +783,8 @@ void MdOut::markTypeOut(Definition* def) {
} break;
case MarkType::kNoExample:
break;
+ case MarkType::kOutdent:
+ break;
case MarkType::kParam: {
if (TableState::kNone == fTableState) {
this->mdHeaderOut(3);
@@ -1004,6 +1008,24 @@ void MdOut::mdHeaderOutLF(int depth, int lf) {
}
void MdOut::resolveOut(const char* start, const char* end, BmhParser::Resolvable resolvable) {
+ if (BmhParser::Resolvable::kLiteral == resolvable && end > start) {
+ while ('\n' == *start) {
+ ++start;
+ }
+ const char* spaceStart = start;
+ while (' ' == *start) {
+ ++start;
+ }
+ if (start > spaceStart) {
+ fIndent = start - spaceStart;
+ }
+ this->writeBlockTrim(end - start, start);
+ if ('\n' == end[-1]) {
+ this->lf(1);
+ }
+ fIndent = 0;
+ return;
+ }
// FIXME: this needs the markdown character present when the def was defined,
// not the last markdown character the parser would have seen...
while (fBmhParser.fMC == end[-1]) {
diff --git a/tools/bookmaker/parserCommon.cpp b/tools/bookmaker/parserCommon.cpp
index cb55bcb640..fbfcbae728 100644
--- a/tools/bookmaker/parserCommon.cpp
+++ b/tools/bookmaker/parserCommon.cpp
@@ -7,6 +7,11 @@
#include "bookmaker.h"
+static void debug_out(int len, const char* data) {
+ // convenient place to intercept arbitrary output
+ SkDebugf("%.*s", len, data);
+}
+
bool ParserCommon::parseSetup(const char* path) {
this->reset();
sk_sp<SkData> data = SkData::MakeFromFileName(path);
@@ -49,3 +54,131 @@ bool ParserCommon::parseSetup(const char* path) {
fLineCount = 1;
return true;
}
+
+void ParserCommon::writeBlockIndent(int size, const char* data) {
+ while (size && ' ' >= data[size - 1]) {
+ --size;
+ }
+ bool newLine = false;
+ while (size) {
+ while (size && ' ' > data[0]) {
+ ++data;
+ --size;
+ }
+ if (!size) {
+ return;
+ }
+ if (newLine) {
+ this->lf(1);
+ }
+ TextParser parser(fFileName, data, data + size, fLineCount);
+ const char* lineEnd = parser.strnchr('\n', data + size);
+ int len = lineEnd ? (int) (lineEnd - data) : size;
+ this->writePending();
+ this->indentToColumn(fIndent);
+ if (fDebugOut) {
+ debug_out(len, data);
+ }
+ fprintf(fOut, "%.*s", len, data);
+ size -= len;
+ data += len;
+ newLine = true;
+ }
+}
+
+bool ParserCommon::writeBlockTrim(int size, const char* data) {
+ if (fOutdentNext) {
+ fIndent -= 4;
+ fOutdentNext = false;
+ }
+ while (size && ' ' >= data[0]) {
+ ++data;
+ --size;
+ }
+ while (size && ' ' >= data[size - 1]) {
+ --size;
+ }
+ if (size <= 0) {
+ fLastChar = '\0';
+ return false;
+ }
+ SkASSERT(size < 16000);
+ if (size > 3 && !strncmp("#end", data, 4)) {
+ fMaxLF = 1;
+ }
+ if (this->leadingPunctuation(data, (size_t) size)) {
+ fPendingSpace = 0;
+ }
+ this->writePending();
+ if (fDebugOut) {
+ debug_out(size, data);
+ }
+ fprintf(fOut, "%.*s", size, data);
+ int added = 0;
+ fLastChar = data[size - 1];
+ while (size > 0 && '\n' != data[--size]) {
+ ++added;
+ }
+ fColumn = size ? added : fColumn + added;
+ fSpaces = 0;
+ fLinefeeds = 0;
+ fMaxLF = added > 2 && !strncmp("#if", &data[size + (size > 0)], 3) ? 1 : 2;
+ if (fOutdentNext) {
+ fIndent -= 4;
+ fOutdentNext = false;
+ }
+ return true;
+}
+
+void ParserCommon::writePending() {
+ fPendingLF = SkTMin(fPendingLF, fMaxLF);
+ bool wroteLF = false;
+ while (fLinefeeds < fPendingLF) {
+ if (fDebugOut) {
+ SkDebugf("\n");
+ }
+ fprintf(fOut, "\n");
+ ++fLinefeeds;
+ wroteLF = true;
+ }
+ fPendingLF = 0;
+ if (wroteLF) {
+ SkASSERT(0 == fColumn);
+ SkASSERT(fIndent >= fSpaces);
+ if (fDebugOut) {
+ SkDebugf("%*s", fIndent - fSpaces, "");
+ }
+ fprintf(fOut, "%*s", fIndent - fSpaces, "");
+ fColumn = fIndent;
+ fSpaces = fIndent;
+ }
+ for (int index = 0; index < fPendingSpace; ++index) {
+ if (fDebugOut) {
+ SkDebugf(" ");
+ }
+ fprintf(fOut, " ");
+ ++fColumn;
+ }
+ fPendingSpace = 0;
+}
+
+void ParserCommon::writeString(const char* str) {
+ const size_t len = strlen(str);
+ SkASSERT(len > 0);
+ SkASSERT(' ' < str[0]);
+ fLastChar = str[len - 1];
+ SkASSERT(' ' < fLastChar);
+ SkASSERT(!strchr(str, '\n'));
+ if (this->leadingPunctuation(str, strlen(str))) {
+ fPendingSpace = 0;
+ }
+ this->writePending();
+ if (fDebugOut) {
+ debug_out((int) strlen(str), str);
+ }
+ fprintf(fOut, "%s", str);
+ fColumn += len;
+ fSpaces = 0;
+ fLinefeeds = 0;
+ fMaxLF = 2;
+}
diff --git a/tools/bookmaker/spellCheck.cpp b/tools/bookmaker/spellCheck.cpp
index 3a32f37bc4..e2c4286e18 100644
--- a/tools/bookmaker/spellCheck.cpp
+++ b/tools/bookmaker/spellCheck.cpp
@@ -202,6 +202,8 @@ bool SpellCheck::check(Definition* def) {
break;
case MarkType::kList:
break;
+ case MarkType::kLiteral:
+ break;
case MarkType::kMarkChar:
break;
case MarkType::kMember:
@@ -220,6 +222,8 @@ bool SpellCheck::check(Definition* def) {
} break;
case MarkType::kNoExample:
break;
+ case MarkType::kOutdent:
+ break;
case MarkType::kParam: {
if (TableState::kNone == fTableState) {
fTableState = TableState::kRow;
@@ -490,6 +494,7 @@ void SpellCheck::report(SkCommandLineFlags::StringArray report) {
if (report.contains("all")) {
int column = 0;
char lastInitial = 'a';
+ int count = 0;
for (auto iter : elems) {
if (string::npos != iter.second.fFile.find("undocumented.bmh")) {
continue;
@@ -521,8 +526,9 @@ void SpellCheck::report(SkCommandLineFlags::StringArray report) {
}
SkDebugf("%s ", check.c_str());
column += check.length();
+ ++count;
}
- SkDebugf("\n\n");
+ SkDebugf("\n\ncount = %d\n", count);
return;
}
int index = 0;