From 154beea85961f73ed7f0da047b7ebd16d2a2d829 Mon Sep 17 00:00:00 2001 From: Cary Clark Date: Thu, 26 Oct 2017 07:58:48 -0400 Subject: 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 Reviewed-by: Cary Clark Reviewed-by: Cary Clark --- docs/SkBitmap_Reference.bmh | 239 +-- docs/SkCanvas_Reference.bmh | 115 +- docs/SkIRect_Reference.bmh | 2548 +++++++++++++-------------- docs/SkMatrix_Reference.bmh | 3978 ++++++++++++++++++++++++++++++++----------- docs/SkPaint_Reference.bmh | 28 +- docs/SkPath_Reference.bmh | 47 +- docs/SkPixmap_Reference.bmh | 101 +- docs/SkRect_Reference.bmh | 1155 ++++++------- docs/undocumented.bmh | 20 +- 9 files changed, 5036 insertions(+), 3195 deletions(-) (limited to 'docs') 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: -#Return incomplete ## +#Code +#Literal +| 1 0 0 | +| 0 1 0 | +| 0 0 1 | +## + +#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. -#Return incomplete ## +Also called preservesAxisAlignment; 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("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: + +#Code +#Literal +| -- -- -- | +| -- -- -- | +| perspective-x perspective-y perspective-scale | +## -#Return incomplete ## +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. + +#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.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) + +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. -#Param index incomplete ## +Next call to read Matrix state may recompute cache; subsequent writes to Matrix +value must be followed by dirtyMatrixTypeCache. -#Return incomplete ## +#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,1420 +1304,2772 @@ 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] | +## -#Param buffer incomplete ## +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 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. -#Param sinValue incomplete ## -#Param cosValue incomplete ## -#Param px incomplete ## -#Param py incomplete ## +Vector (sinValue, cosValue) describes the angle of rotation relative to (0, 1). +Vector length specifies scale. + +#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). -#Param sinValue incomplete ## -#Param cosValue incomplete ## +Vector (sinValue, cosValue) describes the angle of rotation relative to (0, 1). +Vector length specifies scale. + +#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 | +## + +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 | ## -#ToDo incomplete ## +#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. -#Param sx incomplete ## -#Param sy incomplete ## -#Param px incomplete ## -#Param py incomplete ## +Given: -#Example -// incomplete +#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 | ## -#ToDo incomplete ## +where +#Code +#Literal +dx = px - sx * px +dy = py - sy * py ## -# ------------------------------------------------------------------------------ - -#Method void preScale(SkScalar sx, SkScalar sy) +sets Matrix to: -Preconcats the matrix with the specified scale. -#Formula -M' = M * S(sx, sy) +#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 | ## -#Param sx incomplete ## -#Param sy incomplete ## +#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.preScale(.75f, 1.5f, source.width() / 2, source.height() / 2); +canvas->concat(matrix); +canvas->drawBitmap(source, 0, 0); ## -#ToDo incomplete ## +#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) -## - -#Param degrees incomplete ## -#Param px incomplete ## -#Param py incomplete ## +#Method void preScale(SkScalar sx, SkScalar sy) -#Example -// incomplete -## +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. -#ToDo incomplete ## +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 | ## -# ------------------------------------------------------------------------------ - -#Method void preRotate(SkScalar degrees) +sets Matrix to: -Preconcats the matrix with the specified rotation. -#Formula -M' = M * R(degrees) +#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 | ## -#Param degrees incomplete ## +#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.preScale(.75f, 1.5f); +canvas->concat(matrix); +canvas->drawBitmap(source, 0, 0); ## -#ToDo incomplete ## +#SeeAlso postScale setScale MakeScale -## +#Method ## # ------------------------------------------------------------------------------ -#Method void preSkew(SkScalar kx, SkScalar ky, SkScalar px, SkScalar py) +#Method void preRotate(SkScalar degrees, 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 rotating by degrees +about pivot point (px, py). +This can be thought of as rotating about a pivot point before applying Matrix. -#Param kx incomplete ## -#Param ky incomplete ## -#Param px incomplete ## -#Param py incomplete ## +Positive degrees rotates clockwise. -#Example -// incomplete +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 | ## -#ToDo incomplete ## +where +#Code +#Literal +c = cos(degrees) +s = sin(degrees) +dx = s * py + (1 - c) * px +dy = -s * px + (1 - c) * py ## -# ------------------------------------------------------------------------------ - -#Method void preSkew(SkScalar kx, SkScalar ky) +sets Matrix to: -Preconcats the matrix with the specified skew. -#Formula -M' = M * K(kx, ky) +#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 | ## -#Param kx incomplete ## -#Param ky incomplete ## +#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.preRotate(45, source.width() / 2, source.height() / 2); +canvas->concat(matrix); +canvas->drawBitmap(source, 0, 0); ## -#ToDo incomplete ## +#SeeAlso postRotate setRotate -## +#Method ## # ------------------------------------------------------------------------------ -#Method void preConcat(const SkMatrix& other) +#Method void preRotate(SkScalar degrees) -Preconcats the matrix with the specified matrix. -#Formula -M' = M * other -## +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. -#Param other incomplete ## +Positive degrees rotates clockwise. -#Example -// incomplete +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 | ## -#ToDo incomplete ## +where +#Code +#Literal +c = cos(degrees) +s = sin(degrees) ## -# ------------------------------------------------------------------------------ - -#Method void postTranslate(SkScalar dx, SkScalar dy) +sets Matrix to: -Postconcats the matrix with the specified translation. -#Formula -M' = T(dx, dy) * M +#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 | ## -#Param dx incomplete ## -#Param dy incomplete ## +#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.preRotate(45); +canvas->concat(matrix); +canvas->drawBitmap(source, 0, 0); ## -#ToDo incomplete ## +#SeeAlso postRotate setRotate -## +#Method ## # ------------------------------------------------------------------------------ -#Method void postScale(SkScalar sx, SkScalar sy, SkScalar px, SkScalar py) +#Method void preSkew(SkScalar kx, SkScalar ky, SkScalar px, SkScalar py) -Postconcats the matrix with the specified scale. -#Formula -M' = S(sx, sy, px, py) * M -## +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. -#Param sx incomplete ## -#Param sy incomplete ## -#Param px incomplete ## -#Param py incomplete ## +Given: -#Example -// incomplete +#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 | ## -#ToDo incomplete ## +where +#Code +#Literal +dx = -kx * py +dy = -ky * px ## -# ------------------------------------------------------------------------------ - -#Method void postScale(SkScalar sx, SkScalar sy) +sets Matrix to: -Postconcats the matrix with the specified scale. -#Formula -M' = S(sx, sy) * M +#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 sx incomplete ## -#Param sy incomplete ## +#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.preSkew(.5f, 0, source.width() / 2, source.height() / 2); +canvas->concat(matrix); +canvas->drawBitmap(source, 0, 0); ## -#ToDo incomplete ## +#SeeAlso postSkew setSkew -## +#Method ## # ------------------------------------------------------------------------------ -#Method bool postIDiv(int divx, int divy) - -Postconcats the matrix by dividing it by the specified integers. -#Formula -M' = S(1/divx, 1/divy, 0, 0) * M -## +#Method void preSkew(SkScalar kx, SkScalar ky) -#Param divx incomplete ## -#Param divy incomplete ## +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. -#Return incomplete ## +Given: -#Example -// incomplete +#Code +#Literal + | A B C | | 1 kx 0 | +Matrix = | D E F |, K(kx, ky) = | ky 1 0 | + | G H I | | 0 0 1 | ## -#ToDo incomplete ## +sets Matrix to: +#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 | ## +#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 postRotate(SkScalar degrees, SkScalar px, SkScalar py) +#Method void preConcat(const SkMatrix& other) -Postconcats the matrix with the specified rotation. -#Formula -M' = R(degrees, px, py) * M +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 degrees incomplete ## -#Param px incomplete ## -#Param py 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 postRotate(SkScalar degrees) +#Method void postTranslate(SkScalar dx, SkScalar dy) -Postconcats the matrix with the specified rotation. -#Formula -M' = R(degrees) * 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 degrees 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 postSkew(SkScalar kx, SkScalar ky, SkScalar px, SkScalar py) +#Method void postScale(SkScalar sx, SkScalar sy, 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 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. -#Param kx incomplete ## -#Param ky incomplete ## -#Param px incomplete ## -#Param py incomplete ## +Given: -#Example -// incomplete +#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 | ## -#ToDo incomplete ## +where +#Code +#Literal +dx = px - sx * px +dy = py - sy * py ## -# ------------------------------------------------------------------------------ - -#Method void postSkew(SkScalar kx, SkScalar ky) +sets Matrix to: -Postconcats the matrix with the specified skew. -#Formula -M' = K(kx, ky) * M +#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 kx incomplete ## -#Param ky incomplete ## +#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 ## # ------------------------------------------------------------------------------ -#Method void postConcat(const SkMatrix& other) +#Method void postScale(SkScalar sx, SkScalar sy) -Postconcats the matrix with the specified matrix. -#Formula -M' = other * 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 | +## + +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 other incomplete ## +#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 ## # ------------------------------------------------------------------------------ -#Enum ScaleToFit +#Method bool postIDiv(int divx, int divy) -#Code - enum ScaleToFit { - kFill_ScaleToFit, - kStart_ScaleToFit, - kCenter_ScaleToFit, - kEnd_ScaleToFit, - }; +Sets Matrix to Matrix constructed from scaling by +#Formula +(1/divx, 1/divy) ## +about pivot point (px, py), multiplied by Matrix. -#Const kFill_ScaleToFit -Scale in X and Y independently, so that src matches dst exactly. -This may change the aspect ratio of the src. -## -#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. +Returns false if either divx or divy is zero. + +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 | ## -#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. + +where + +#Code +#Literal +sx = 1 / divx +sy = 1 / divy ## -#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. + +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 ## # ------------------------------------------------------------------------------ -#Method bool setRectToRect(const SkRect& src, const SkRect& dst, ScaleToFit stf) +#Method void postRotate(SkScalar degrees, SkScalar px, SkScalar py) -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 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. -#Param src the source rectangle to map from -## -#Param dst the destination rectangle to map to +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 stf the ScaleToFit option + +where + +#Code +#Literal +c = cos(degrees) +s = sin(degrees) +dx = s * py + (1 - c) * px +dy = -s * px + (1 - c) * py ## -#Return true if the matrix can be represented by the rectangle mapping +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 ## # ------------------------------------------------------------------------------ -#Method static SkMatrix MakeRectToRect(const SkRect& src, const SkRect& dst, ScaleToFit stf) +#Method void postRotate(SkScalar degrees) -#Param src incomplete ## -#Param dst incomplete ## -#Param stf incomplete ## +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. -#Return incomplete ## +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) +## + +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 ## # ------------------------------------------------------------------------------ -#Method bool setPolyToPoly(const SkPoint src[], const SkPoint dst[], int count) +#Method void postSkew(SkScalar kx, SkScalar ky, SkScalar px, SkScalar py) -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 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. -#Param src array of src points -## -#Param dst array of dst points +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 | ## -#Param count number of points to use for the transformation + +where + +#Code +#Literal +dx = -kx * py +dy = -ky * px ## -#Return true if the matrix was set to the specified transformation +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 ## # ------------------------------------------------------------------------------ -#Method bool SK_WARN_UNUSED_RESULT invert(SkMatrix* inverse) const +#Method void postSkew(SkScalar kx, SkScalar ky) + +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 | +## -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 Matrix to: -#Param inverse incomplete ## +#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 | +## -#Return incomplete ## +#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 ## # ------------------------------------------------------------------------------ -#Method static void SetAffineIdentity(SkScalar affine[6]) +#Method void postConcat(const SkMatrix& other) + +Sets Matrix to Matrix other multiplied by Matrix. +This can be thought of mapping by other after applying Matrix. -Fills the passed array with affine identity values -in column major order. +Given: -#Param affine array to fill with affine identity values; must not be nullptr +#Code +#Literal + | J K L | | A B C | +Matrix = | M N O |, other = | D E F | + | P Q R | | G H I | ## -#Return 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 ## # ------------------------------------------------------------------------------ -#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. +#Enum ScaleToFit -#Param affine array to fill with affine values; ignored if nullptr +#Code + enum ScaleToFit { + kFill_ScaleToFit, + kStart_ScaleToFit, + kCenter_ScaleToFit, + kEnd_ScaleToFit, + }; ## -#Return incomplete ## +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. -#Example -// incomplete +#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 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 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 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. ## -#ToDo incomplete ## +#Example + 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 ## # ------------------------------------------------------------------------------ -#Method void setAffine(const SkScalar affine[6]) +#Method bool setRectToRect(const SkRect& src, const SkRect& dst, ScaleToFit stf) -Set the matrix to the specified affine values. -Note: these are passed in column major order. +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 affine incomplete ## +#Code +#Literal +| 0 0 0 | +| 0 0 0 | +| 0 0 1 | +## -#Example -// incomplete +#Param src Rect to map from ## +#Param dst Rect to map to ## +#Param stf one of: kFill_ScaleToFit, kStart_ScaleToFit, + kCenter_ScaleToFit, kEnd_ScaleToFit ## -#ToDo incomplete ## +#Return true if Matrix can represent Rect mapping ## + +#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 ## # ------------------------------------------------------------------------------ -#Method void mapPoints(SkPoint dst[], const SkPoint src[], int count) const +#Method static SkMatrix MakeRectToRect(const SkRect& src, const SkRect& dst, ScaleToFit stf) -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[] -## +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: -#Param dst storage for transformed coordinates; must - allow count entries -## -#Param src original coordinates that are to be transformed; - must allow count entries +#Code +#Literal +| 0 0 0 | +| 0 0 0 | +| 0 0 1 | ## -#Param count number of points in src to read, and then transform - into dst + +#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 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 ## # ------------------------------------------------------------------------------ -#Method void mapPoints(SkPoint pts[], int count) const +#Method bool setPolyToPoly(const SkPoint src[], const SkPoint dst[], int count) -Apply this matrix to the array of points, overwriting it with the -transformed values. -#Formula -dst[] = M * pts[] -## +Sets Matrix to map src to dst. count must be zero or greater, and four or less. -#Param pts storage for transformed points; must allow count entries +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. + +#Param src Points to map from ## +#Param dst Points to map to ## +#Param count number of Points in src and dst ## + +#Return true if Matrix was constructed successfully ## -#Param count number of points in pts + +#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 + ## +# ------------------------------------------------------------------------------ + +#Method bool SK_WARN_UNUSED_RESULT invert(SkMatrix* inverse) const + +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 storage for inverted Matrix; may be nullptr ## + +#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 ## # ------------------------------------------------------------------------------ -#Method void mapPointsWithStride(SkPoint pts[], size_t stride, int count) const +#Method static void SetAffineIdentity(SkScalar affine[6]) -Like mapPoints but with custom byte stride between the points. Stride -should be a multiple of -#Formula -sizeof(SkScalar) +Fills affine with identity values in column major order. +Sets affine to: + +#Code +#Literal +| 1 0 0 | +| 0 1 0 | ## -. -#Param pts incomplete ## -#Param stride incomplete ## -#Param count 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 ## # ------------------------------------------------------------------------------ -#Method void mapPointsWithStride(SkPoint dst[], const SkPoint src[], size_t stride, int count) const +#Method bool SK_WARN_UNUSED_RESULT asAffine(SkScalar affine[6]) const -Like mapPoints but with custom byte stride between the points. +Fills affine in column major order. Sets affine to: -#Param dst incomplete ## -#Param src incomplete ## -#Param stride incomplete ## -#Param count incomplete ## +#Code +#Literal +| scale-x skew-x translate-x | +| skew-y scale-y translate-y | +## + +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 ## # ------------------------------------------------------------------------------ -#Method void mapHomogeneousPoints(SkScalar dst[], const SkScalar src[], int count) const +#Method void setAffine(const SkScalar affine[6]) -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[] -## +Sets Matrix to affine values, passed in column major order. Given affine, +column, then row, as: -#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 +| scale-x skew-x translate-x | +| skew-y scale-y translate-y | ## -#Param count number of triples (homogeneous points) in src to read, - and then transform into dst + +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 ## # ------------------------------------------------------------------------------ -#Method void mapXY(SkScalar x, SkScalar y, SkPoint* result) const +#Method void mapPoints(SkPoint dst[], const SkPoint src[], int count) const -#Param x incomplete ## -#Param y incomplete ## -#Param result incomplete ## +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: -#Example -// incomplete +#Code +#Literal + | A B C | | x | +Matrix = | D E F |, pt = | 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 Point is computed as: -#Method SkPoint mapXY(SkScalar x, SkScalar y) 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 +## -#Param x incomplete ## -#Param y incomplete ## +src and dst may point to the same storage. -#Return incomplete ## +#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 ## # ------------------------------------------------------------------------------ -#Method void mapVectors(SkVector dst[], const SkVector src[], int count) const +#Method void mapPoints(SkPoint pts[], int count) 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 pts Point array of length count in place. 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 coordinates to be transformed; - must contain at least count entries + +where + +#Code +#Literal +for (i = 0; i < count; ++i) { + x = pts[i].fX + y = pts[i].fY +} ## -#Param count number of vectors in src to read and transform - into dst + +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 ## # ------------------------------------------------------------------------------ -#Method void mapVectors(SkVector vecs[], int count) const +#Method void mapPointsWithStride(SkPoint pts[], size_t stride, int count) const -Apply this matrix to count vectors in array vecs. -This is similar to mapPoints, but ignores any translation in the matrix. +Maps count pts, skipping stride bytes to advance from one Point to the next. +Points are mapped by multiplying each Point 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 + +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 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 mapVector(SkScalar dx, SkScalar dy, SkVector* result) const +#Method void mapPointsWithStride(SkPoint dst[], const SkPoint src[], size_t stride, int count) const -#Param dx incomplete ## -#Param dy incomplete ## -#Param result incomplete ## +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: -#Example -// incomplete +#Code +#Literal + | A B C | | x | +Matrix = | D E F |, src = | y | + | G H I | | 1 | ## -#ToDo incomplete ## +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 ## -# ------------------------------------------------------------------------------ - -#Method SkVector mapVector(SkScalar dx, SkScalar dy) const - -#Param dx incomplete ## -#Param dy incomplete ## - -#Return incomplete ## +#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 bool mapRect(SkRect* dst, const SkRect& src) const +#Method void mapHomogeneousPoints(SkPoint3 dst[], const SkPoint3 src[], int count) const + +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: -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. +#Code +#Literal + | A B C | | x | +Matrix = | D E F |, src = | y | + | G H I | | z | +## -#Param dst storage for transformed rectangle ## -#Param src rectangle to transform ## +each resulting dst Point is computed as: -#Return result of calling rectStaysRect +#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| ## +#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 bool mapRect(SkRect* rect) const +#Method void mapXY(SkScalar x, SkScalar y, SkPoint* result) 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 +Maps Point (x, y) to result. Point is mapped by multiplying by Matrix. Given: -#Param rect rectangle to transform +#Code +#Literal + | A B C | | x | +Matrix = | D E F |, pt = | y | + | G H I | | 1 | ## -#Return the result of calling rectStaysRect +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 mapRectToQuad(SkPoint dst[4], const SkRect& rect) const +#Method SkPoint mapXY(SkScalar x, SkScalar y) 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. +Returns Point (x, y) multiplied by Matrix. Given: -#Param dst storage for transformed quad +#Code +#Literal + | A B C | | x | +Matrix = | D E F |, pt = | y | + | G H I | | 1 | ## -#Param rect rectangle to transform + +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 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 void mapVectors(SkVector dst[], const SkVector src[], int count) const -#Param dst incomplete ## -#Param src 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 +} ## -# ------------------------------------------------------------------------------ - -#Method SkScalar mapRadius(SkScalar radius) const +each dst Vector is computed as: -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. +#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 radius 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 static MapXYProc GetMapXYProc(TypeMask mask) - -#Param mask incomplete ## +#Method void mapVectors(SkVector vecs[], int count) const -#Return incomplete ## +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 +} ## -# ------------------------------------------------------------------------------ +each result Vector is computed as: -#Method MapXYProc getMapXYProc() const +#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 incomplete ## +#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 static MapPtsProc GetMapPtsProc(TypeMask mask) +#Method void mapVector(SkScalar dx, SkScalar dy, SkVector* result) const + +Maps Vector (x, y) to result. Vector is mapped by multiplying by Matrix, +treating Matrix translation as zero. Given: + +#Code +#Literal + | A B 0 | | dx | +Matrix = | D E 0 |, vec = | dy | + | G H I | | 1 | +## + +each result Vector is computed as: -#Param mask incomplete ## +#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 +## -#Return incomplete ## +#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 MapPtsProc getMapPtsProc() const +#Method SkVector mapVector(SkScalar dx, SkScalar dy) const + +Returns Vector (x, y) multiplied by Matrix, treating Matrix translation as zero. +Given: + +#Code +#Literal + | A B 0 | | dx | +Matrix = | D E 0 |, vec = | dy | + | G H I | | 1 | +## + +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 ## -#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 bool isFixedStepInX() const +#Method bool mapRect(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. +Returns true if mapped corners are dst corners. -#Return incomplete ## +Returned value is the same as calling rectStaysRect. + +#Param dst storage for bounds of mapped Points ## +#Param src Rect to map ## + +#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 SkVector fixedStepInX(SkScalar y) 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. -If the matrix can be stepped in x (not complex perspective) -then return the step value. -If it cannot, behavior is undefined. +Returned value is the same as calling rectStaysRect. -#Param y incomplete ## +#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 bool cheapEqualTo(const SkMatrix& m) const +#Method void mapRectToQuad(SkPoint dst[4], const SkRect& rect) const -Returns true if Matrix equals m, using an efficient comparison. +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 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. +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. -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. +Given: -#Param m incomplete ## +#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: + +#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 friend SK_API bool operator==(const SkMatrix& a, const SkMatrix& b) - -mac chromium debug build requires SK_API to make operator== visible +#Method void mapRectScaleTranslate(SkRect* dst, const SkRect& src) const -#Param a incomplete ## -#Param b incomplete ## +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 friend SK_API bool operator!=(const SkMatrix& a, const SkMatrix& b) +#Method SkScalar mapRadius(SkScalar radius) const + +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 a incomplete ## -#Param b 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 ## # ------------------------------------------------------------------------------ -#Enum _anonymous_3 +#Method bool isFixedStepInX() const -#Code - enum { - kMaxFlattenSize = 9 * sizeof(SkScalar) + sizeof(uint32_t), - }; -## +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. -#Const kMaxFlattenSize = 9 * sizeof(SkScalar) + sizeof(uint32_t) - writeToMemory and readFromMemory will never return a value larger than this -## +May return true if getType returns kPerspective_Mask, but only when Matrix +does not include rotation or skewing along the y-axis. + +#Return true if Matrix does not have complex perspective ## #Example -// 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 + ## -#ToDo incomplete ## +# ------------------------------------------------------------------------------ + +#Method SkVector fixedStepInX(SkScalar y) const + +Returns Vector representing a unit step in x at y mapped through Matrix. +If isFixedStepInX is false, returned value is undefined. + +#Param y position of line parallel to x-axis ## + +#Return Vector advance of mapped unit step in x ## + +#Example +#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 size_t writeToMemory(void* buffer) const +#Method bool cheapEqualTo(const SkMatrix& m) const + +Returns true if Matrix equals m, 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. -return the number of bytes written, whether or not buffer is null +Returns true even when both Matrices contain NaN. -#Param buffer incomplete ## +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. -#Return incomplete ## +#Param m Matrix to compare ## + +#Return true if m and Matrix are represented by identical bit patterns ## #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.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 +## ## -#ToDo incomplete ## +#SeeAlso 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 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 memory to read from +#Param a Matrix to compare ## +#Param b Matrix to compare ## + +#Return true if m and Matrix are numerically equal ## + +#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.setScale(2, 4); + b.postScale(0.5f, 0.25f); + debugster("identity", a, b); +#StdOut +identity: a == b a.cheapEqualTo(b): true ## -#Param length amount of memory available in the buffer ## -#Return number of bytes read (must be a multiple of 4) or - 0 if there was not enough memory available +#SeeAlso cheapEqualTo operator!=(const SkMatrix& a, const SkMatrix& b) + ## +# ------------------------------------------------------------------------------ + +#Method bool operator!=(const SkMatrix& a, const SkMatrix& b) + +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 a Matrix to compare ## +#Param b Matrix to compare ## + +#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. -#Param scaleFactors incomplete ## +Returns true if scaleFactors are found; otherwise, returns false and sets +scaleFactors to undefined values. -#Return incomplete ## +#Param scaleFactors storage for minimum and maximum scale factors ## + +#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: + +#Code +#Literal +| 1 0 0 | +| 0 1 0 | +| 0 0 1 | +## -#Return incomplete ## +#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. + +#Code +#Literal +| sx 0 tx | +| 0 sy ty | +| 0 0 1 | +## -#Param sx incomplete ## -#Param sy incomplete ## -#Param tx incomplete ## -#Param ty incomplete ## +#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() ## @@ -716,66 +711,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 @@ -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 ## ## -- cgit v1.2.3