| #Topic Matrix |
| #Alias Matrices |
| #Alias Matrix_Reference |
| |
| #Class SkMatrix |
| |
| Matrix holds a 3x3 matrix for transforming coordinates. This allows mapping |
| Points and Vectors with translation, scaling, skewing, rotation, and |
| perspective. |
| |
| 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. |
| |
| 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 |
| |
| #Subtopic Subtopics |
| #ToDo manually add subtopics ## |
| #Table |
| #Legend |
| # topics # description ## |
| #Legend ## |
| #Table ## |
| ## |
| |
| #Subtopic Operators |
| #Table |
| #Legend |
| # function # description ## |
| #Legend ## |
| # 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 |
| # function # description ## |
| #Legend ## |
| # Concat # Returns the concatenation of Matrix pair. ## |
| # I # Returns a reference to a const identity Matrix. ## |
| # InvalidMatrix # Returns a reference to a const invalid Matrix. ## |
| # MakeAll # Constructs all nine values. ## |
| # 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 3x2 array to identity. ## |
| # asAffine # Copies to 3x2 array. ## |
| # cheapEqualTo # Compares Matrix pair using memcmp(). ## |
| # decomposeScale # Separates scale if possible. ## |
| # 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. ## |
| # get9 # Returns all nine Matrix values. ## |
| # getMaxScale # Returns maximum scaling, if possible. ## |
| # getMinMaxScales # Returns minimum and maximum scaling, if possible. ## |
| # getMinScale # Returns minimum scaling, if possible. ## |
| # getPerspX # Returns input x perspective factor. ## |
| # getPerspY # Returns input y perspective factor. ## |
| # getScaleX # Returns horizontal scale factor. ## |
| # getScaleY # Returns vertical scale factor. ## |
| # getSkewX # Returns horizontal skew factor. ## |
| # getSkewY # Returns vertical skew factor. ## |
| # getTranslateX # Returns horizontal translation. ## |
| # getTranslateY # Returns vertical translation. ## |
| # getType # Returns transform complexity. ## |
| # hasPerspective # Returns if transform includes perspective. ## |
| # 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 # 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 ## |
| |
| #Topic ## |
| |
| # ------------------------------------------------------------------------------ |
| |
| #Method static SkMatrix SK_WARN_UNUSED_RESULT MakeScale(SkScalar sx, SkScalar sy) |
| |
| Sets Matrix to scale by (sx, sy). Returned matrix is: |
| |
| #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 |
| #Image 4 |
| canvas->concat(SkMatrix::MakeScale(4, 3)); |
| canvas->drawBitmap(source, 0, 0); |
| ## |
| |
| #SeeAlso setScale postScale preScale |
| |
| ## |
| |
| # ------------------------------------------------------------------------------ |
| |
| #Method static SkMatrix SK_WARN_UNUSED_RESULT MakeScale(SkScalar scale) |
| |
| 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 Matrix with scale ## |
| |
| #Example |
| #Image 4 |
| canvas->concat(SkMatrix::MakeScale(4)); |
| canvas->drawBitmap(source, 0, 0); |
| ## |
| |
| #SeeAlso setScale postScale preScale |
| |
| ## |
| |
| # ------------------------------------------------------------------------------ |
| |
| #Method static SkMatrix SK_WARN_UNUSED_RESULT MakeTrans(SkScalar dx, SkScalar dy) |
| |
| Sets Matrix to translate by (dx, dy). Returned matrix is: |
| |
| #Code |
| #Literal |
| | 1 0 dx | |
| | 0 1 dy | |
| | 0 0 1 | |
| ## |
| |
| #Param dx horizontal translation ## |
| #Param dy vertical translation ## |
| |
| #Return Matrix with translation ## |
| |
| #Example |
| #Image 4 |
| SkMatrix matrix = SkMatrix::MakeTrans(64, 48); |
| for (int i = 0; i < 4; ++i) { |
| canvas->drawBitmap(source, 0, 0); |
| canvas->concat(matrix); |
| } |
| ## |
| |
| #SeeAlso setTranslate postTranslate preTranslate |
| |
| ## |
| |
| # ------------------------------------------------------------------------------ |
| |
| #Method static SkMatrix SK_WARN_UNUSED_RESULT MakeAll(SkScalar scaleX, SkScalar skewX, SkScalar transX, |
| SkScalar skewY, SkScalar scaleY, SkScalar transY, |
| SkScalar pers0, SkScalar pers1, SkScalar pers2) |
| |
| |
| Sets Matrix to: |
| |
| #Code |
| #Literal |
| | scaleX skewX transX | |
| | skewY scaleY transY | |
| | pers0 pers1 pers2 | |
| ## |
| |
| #Param scaleX horizontal scale factor ## |
| #Param skewX horizontal skew factor ## |
| #Param transX horizontal translation ## |
| #Param skewY vertical skew factor ## |
| #Param scaleY vertical scale factor ## |
| #Param transY vertical translation ## |
| #Param pers0 input x perspective factor ## |
| #Param pers1 input y perspective factor ## |
| #Param pers2 perspective scale factor ## |
| |
| #Return Matrix constructed from parameters ## |
| |
| #Example |
| SkPaint p; |
| p.setAntiAlias(true); |
| p.setTextSize(64); |
| for (SkScalar sx : { -1, 1 } ) { |
| for (SkScalar sy : { -1, 1 } ) { |
| SkAutoCanvasRestore autoRestore(canvas, true); |
| SkMatrix m = SkMatrix::MakeAll(sx, 1, 128, 0, sy, 128, 0, 0, 1); |
| canvas->concat(m); |
| canvas->drawString("K", 0, 0, p); |
| } |
| } |
| ## |
| |
| #SeeAlso setAll set9 postConcat preConcat |
| |
| ## |
| |
| |
| # ------------------------------------------------------------------------------ |
| |
| #Enum TypeMask |
| |
| #Code |
| enum TypeMask { |
| kIdentity_Mask = 0, |
| kTranslate_Mask = 0x01, |
| kScale_Mask = 0x02, |
| kAffine_Mask = 0x04, |
| kPerspective_Mask = 0x08, |
| }; |
| ## |
| |
| Enum of bit fields for mask returned by getType. |
| Used to identify the complexity of Matrix, to optimize performance. |
| |
| #Const kIdentity_Mask 0 |
| all bits clear if Matrix is identity |
| ## |
| #Const kTranslate_Mask 1 |
| set if Matrix has translation |
| ## |
| #Const kScale_Mask 2 |
| set if Matrix has x or y scale |
| ## |
| #Const kAffine_Mask 4 |
| set if Matrix skews or rotates |
| ## |
| #Const kPerspective_Mask 8 |
| set if Matrix has perspective |
| ## |
| |
| #Example |
| 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 |
| ## |
| ## |
| |
| #SeeAlso getType |
| |
| ## |
| |
| # ------------------------------------------------------------------------------ |
| |
| #Method TypeMask getType() const |
| |
| 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 set, all |
| other bits are set. |
| |
| #Return kIdentity_Mask, or combinations of: kTranslate_Mask, kScale_Mask, |
| kAffine_Mask, kPerspective_Mask |
| ## |
| |
| #Example |
| 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 |
| ## |
| ## |
| |
| #SeeAlso TypeMask |
| |
| ## |
| |
| # ------------------------------------------------------------------------------ |
| |
| #Method bool isIdentity() const |
| |
| Returns true if Matrix is identity. Identity matrix is: |
| |
| #Code |
| #Literal |
| | 1 0 0 | |
| | 0 1 0 | |
| | 0 0 1 | |
| ## |
| |
| #Return true if Matrix has no effect ## |
| |
| #Example |
| 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 |
| ## |
| ## |
| |
| #SeeAlso reset() setIdentity getType |
| |
| ## |
| |
| # ------------------------------------------------------------------------------ |
| |
| #Method bool isScaleTranslate() const |
| |
| 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 |
| 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 |
| ## |
| ## |
| |
| #SeeAlso setScale isTranslate setTranslate getType |
| |
| ## |
| |
| # ------------------------------------------------------------------------------ |
| |
| #Method bool isTranslate() const |
| |
| 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 |
| 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 |
| ## |
| ## |
| |
| #SeeAlso setTranslate getType |
| |
| ## |
| |
| # ------------------------------------------------------------------------------ |
| |
| #Method bool rectStaysRect() const |
| |
| Returns true Matrix maps Rect to another Rect. If true, Matrix is identity, |
| or scales, or rotates a multiple of 90 degrees, or mirrors in x or y. In all |
| cases, Matrix may also have translation. Matrix form is either: |
| |
| #Code |
| #Literal |
| | scale-x 0 translate-x | |
| | 0 scale-y translate-y | |
| | 0 0 1 | |
| ## |
| |
| or |
| |
| #Code |
| #Literal |
| | 0 rotate-x translate-x | |
| | rotate-y 0 translate-y | |
| | 0 0 1 | |
| ## |
| |
| for non-zero values of scale-x, scale-y, rotate-x, and rotate-y. |
| |
| Also called preservesAxisAlignment; use the one that provides better inline |
| documentation. |
| |
| #Return true if Matrix maps one Rect into another ## |
| |
| #Example |
| 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 |
| ## |
| ## |
| |
| #SeeAlso preservesAxisAlignment preservesRightAngles |
| |
| ## |
| |
| # ------------------------------------------------------------------------------ |
| |
| #Method bool preservesAxisAlignment() const |
| |
| |
| 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 |
| 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 |
| ## |
| ## |
| |
| #SeeAlso rectStaysRect preservesRightAngles |
| |
| ## |
| |
| # ------------------------------------------------------------------------------ |
| |
| #Method bool hasPerspective() const |
| |
| Returns true if the matrix contains perspective elements. Matrix form is: |
| |
| #Code |
| #Literal |
| | -- -- -- | |
| | -- -- -- | |
| | perspective-x perspective-y perspective-scale | |
| ## |
| |
| where perspective-x or perspective-y is non-zero, or perspective-scale is |
| not one. All other elements may have any value. |
| |
| #Return true if Matrix is in most general form ## |
| |
| #Example |
| #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); |
| ## |
| |
| #SeeAlso setAll set9 MakeAll |
| |
| ## |
| |
| # ------------------------------------------------------------------------------ |
| |
| #Method bool isSimilarity(SkScalar tol = SK_ScalarNearlyZero) const |
| |
| 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. |
| |
| 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. |
| |
| Preserves right angles, keeping the arms of the angle equal lengths. |
| |
| #Param tol to be deprecated ## |
| |
| #Return true if Matrix only rotates, uniformly scales, translates ## |
| |
| #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 |
| |
| ## |
| |
| # ------------------------------------------------------------------------------ |
| |
| #Method bool preservesRightAngles(SkScalar tol = SK_ScalarNearlyZero) const |
| |
| 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. |
| |
| Preserves right angles, but not requiring that the arms of the angle |
| retain equal lengths. |
| |
| #Param tol to be deprecated ## |
| |
| #Return true if Matrix only rotates, scales, translates ## |
| |
| #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 |
| |
| #Code |
| enum { |
| kMScaleX, |
| kMSkewX, |
| kMTransX, |
| kMSkewY, |
| kMScaleY, |
| kMTransY, |
| kMPersp0, |
| kMPersp1, |
| kMPersp2, |
| }; |
| ## |
| |
| 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 |
| 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 |
| |
| #Code |
| enum { |
| kAScaleX, |
| kASkewY, |
| kASkewX, |
| kAScaleY, |
| kATransX, |
| kATransY, |
| }; |
| ## |
| |
| 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 |
| ## |
| |
| #NoExample |
| ## |
| |
| #SeeAlso SetAffineIdentity asAffine setAffine |
| |
| ## |
| |
| # ------------------------------------------------------------------------------ |
| |
| #Method SkScalar operator[](int index) const |
| |
| 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 value corresponding to index ## |
| |
| #Example |
| 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 |
| ## |
| ## |
| |
| #SeeAlso get set |
| |
| ## |
| |
| # ------------------------------------------------------------------------------ |
| |
| #Method SkScalar get(int index) const |
| |
| 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 value corresponding to index ## |
| |
| #Example |
| 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 |
| ## |
| ## |
| |
| #SeeAlso operator[](int index) set |
| |
| ## |
| |
| # ------------------------------------------------------------------------------ |
| |
| #Method SkScalar getScaleX() const |
| |
| Returns scale factor multiplied by x input, contributing to x output. |
| With mapPoints, scales Points along the x-axis. |
| |
| #Return horizontal scale factor ## |
| |
| #Example |
| SkMatrix matrix; |
| matrix.setScale(42, 24); |
| SkDebugf("matrix.getScaleX() %c= 42\n", matrix.getScaleX() == 42 ? '=' : '!'); |
| #StdOut |
| matrix.getScaleX() == 42 |
| ## |
| ## |
| |
| #SeeAlso get getScaleY setScaleX setScale |
| |
| ## |
| |
| # ------------------------------------------------------------------------------ |
| |
| #Method SkScalar getScaleY() const |
| |
| Returns scale factor multiplied by y input, contributing to y output. |
| With mapPoints, scales Points along the y-axis. |
| |
| #Return vertical scale factor ## |
| |
| #Example |
| SkMatrix matrix; |
| matrix.setScale(42, 24); |
| SkDebugf("matrix.getScaleY() %c= 24\n", matrix.getScaleY() == 24 ? '=' : '!'); |
| #StdOut |
| matrix.getScaleY() == 24 |
| ## |
| ## |
| |
| #SeeAlso get getScaleX setScaleY setScale |
| |
| ## |
| |
| # ------------------------------------------------------------------------------ |
| |
| #Method SkScalar getSkewY() const |
| |
| 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 |
| SkMatrix matrix; |
| matrix.setSkew(42, 24); |
| SkDebugf("matrix.getSkewY() %c= 24\n", matrix.getSkewY() == 24 ? '=' : '!'); |
| #StdOut |
| matrix.getSkewY() == 24 |
| ## |
| ## |
| |
| #SeeAlso get getSkewX setSkewY setSkew |
| |
| ## |
| |
| # ------------------------------------------------------------------------------ |
| |
| #Method SkScalar getSkewX() const |
| |
| 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 |
| SkMatrix matrix; |
| matrix.setSkew(42, 24); |
| SkDebugf("matrix.getSkewX() %c= 42\n", matrix.getSkewX() == 42 ? '=' : '!'); |
| #StdOut |
| matrix.getSkewX() == 42 |
| ## |
| ## |
| |
| #SeeAlso get getSkewY setSkewX setSkew |
| |
| ## |
| |
| # ------------------------------------------------------------------------------ |
| |
| #Method SkScalar getTranslateX() const |
| |
| Returns translation contributing to x output. |
| With mapPoints, moves Points along the x-axis. |
| |
| #Return horizontal translation factor ## |
| |
| #Example |
| SkMatrix matrix; |
| matrix.setTranslate(42, 24); |
| SkDebugf("matrix.getTranslateX() %c= 42\n", matrix.getTranslateX() == 42 ? '=' : '!'); |
| #StdOut |
| matrix.getTranslateX() == 42 |
| ## |
| ## |
| |
| #SeeAlso get getTranslateY setTranslateX setTranslate |
| |
| ## |
| |
| # ------------------------------------------------------------------------------ |
| |
| #Method SkScalar getTranslateY() const |
| |
| Returns translation contributing to y output. |
| With mapPoints, moves Points along the y-axis. |
| |
| #Return vertical translation factor ## |
| |
| #Example |
| SkMatrix matrix; |
| matrix.setTranslate(42, 24); |
| SkDebugf("matrix.getTranslateY() %c= 24\n", matrix.getTranslateY() == 24 ? '=' : '!'); |
| #StdOut |
| matrix.getTranslateY() == 24 |
| ## |
| ## |
| |
| #SeeAlso get getTranslateX setTranslateY setTranslate |
| |
| ## |
| |
| # ------------------------------------------------------------------------------ |
| |
| #Method SkScalar getPerspX() const |
| |
| Returns factor scaling input x relative to input y. |
| |
| #Return input x perspective factor ## |
| |
| #Example |
| 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); |
| ## |
| |
| #SeeAlso kMPersp0 getPerspY |
| |
| ## |
| |
| # ------------------------------------------------------------------------------ |
| |
| #Method SkScalar getPerspY() const |
| |
| |
| Returns factor scaling input y relative to input x. |
| |
| #Return input y perspective factor ## |
| |
| #Example |
| 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); |
| ## |
| |
| #SeeAlso kMPersp1 getPerspX |
| |
| ## |
| |
| # ------------------------------------------------------------------------------ |
| |
| #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. |
| |
| Next call to read Matrix state may recompute cache; subsequent writes to Matrix |
| value must be followed by dirtyMatrixTypeCache. |
| |
| #Param index one of: kMScaleX, kMSkewX, kMTransX, kMSkewY, kMScaleY, kMTransY, |
| kMPersp0, kMPersp1, kMPersp2 |
| ## |
| |
| #Return writable value corresponding to index ## |
| |
| #Example |
| 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 |
| ## |
| ## |
| |
| #SeeAlso get dirtyMatrixTypeCache set |
| |
| ## |
| |
| # ------------------------------------------------------------------------------ |
| |
| #Method void set(int index, SkScalar value) |
| |
| 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 |
| 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 |
| ## |
| ## |
| |
| #SeeAlso operator[] get |
| |
| #Method ## |
| |
| # ------------------------------------------------------------------------------ |
| |
| #Method void setScaleX(SkScalar v) |
| |
| Sets horizontal scale factor. |
| |
| #Param v horizontal scale factor to store ## |
| |
| #Example |
| #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); |
| ## |
| |
| #SeeAlso set setScale setScaleY |
| |
| #Method ## |
| |
| # ------------------------------------------------------------------------------ |
| |
| #Method void setScaleY(SkScalar v) |
| |
| Sets vertical scale factor. |
| |
| #Param v vertical scale factor to store ## |
| |
| #Example |
| #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); |
| ## |
| |
| #SeeAlso set setScale setScaleX |
| |
| #Method ## |
| |
| # ------------------------------------------------------------------------------ |
| |
| #Method void setSkewY(SkScalar v) |
| |
| Sets vertical skew factor. |
| |
| #Param v vertical skew factor to store ## |
| |
| #Example |
| #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); |
| ## |
| |
| #SeeAlso set setSkew setSkewX |
| |
| #Method ## |
| |
| # ------------------------------------------------------------------------------ |
| |
| #Method void setSkewX(SkScalar v) |
| |
| Sets horizontal skew factor. |
| |
| #Param v horizontal skew factor to store ## |
| |
| #Example |
| #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); |
| ## |
| |
| #SeeAlso set setSkew setSkewX |
| |
| #Method ## |
| |
| # ------------------------------------------------------------------------------ |
| |
| #Method void setTranslateX(SkScalar v) |
| |
| Sets horizontal translation. |
| |
| #Param v horizontal translation to store ## |
| |
| #Example |
| #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); |
| ## |
| |
| #SeeAlso set setTranslate setTranslateY |
| |
| #Method ## |
| |
| # ------------------------------------------------------------------------------ |
| |
| #Method void setTranslateY(SkScalar v) |
| |
| Sets vertical translation. |
| |
| #Param v vertical translation to store ## |
| |
| #Example |
| #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); |
| ## |
| |
| #SeeAlso set setTranslate setTranslateX |
| |
| #Method ## |
| |
| # ------------------------------------------------------------------------------ |
| |
| #Method void setPerspX(SkScalar v) |
| |
| Sets input x perspective factor, which causes mapXY to vary input x inversely |
| proportional to input y. |
| |
| #Param v perspective factor ## |
| |
| #Example |
| #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); |
| } |
| ## |
| |
| #SeeAlso getPerspX set setAll set9 MakeAll |
| |
| #Method ## |
| |
| # ------------------------------------------------------------------------------ |
| |
| #Method void setPerspY(SkScalar v) |
| |
| Sets input y perspective factor, which causes mapXY to vary input y inversely |
| proportional to input x. |
| |
| #Param v perspective factor ## |
| |
| #Example |
| #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); |
| } |
| ## |
| |
| #SeeAlso getPerspY set setAll set9 MakeAll |
| |
| #Method ## |
| |
| # ------------------------------------------------------------------------------ |
| |
| #Method void setAll(SkScalar scaleX, SkScalar skewX, SkScalar transX, |
| SkScalar skewY, SkScalar scaleY, SkScalar transY, |
| SkScalar persp0, SkScalar persp1, SkScalar persp2) |
| |
| 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 |
| #Height 128 |
| 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, 64, 0, 0, 1); |
| canvas->concat(m); |
| canvas->drawString("K", 0, 0, p); |
| } |
| } |
| ## |
| |
| #SeeAlso set9 MakeAll |
| |
| #Method ## |
| |
| # ------------------------------------------------------------------------------ |
| |
| #Method void get9(SkScalar buffer[9]) const |
| |
| 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 storage for nine Scalar values ## |
| |
| #Example |
| 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} |
| ## |
| ## |
| |
| #SeeAlso set9 |
| |
| #Method ## |
| |
| # ------------------------------------------------------------------------------ |
| |
| #Method void set9(const SkScalar buffer[9]) |
| |
| 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: |
| |
| #Code |
| #Literal |
| | buffer[0] buffer[1] buffer[2] | |
| | buffer[3] buffer[4] buffer[5] | |
| | buffer[6] buffer[7] buffer[8] | |
| ## |
| |
| In the future, set9 followed by get9 may not return the same values. Since Matrix |
| maps non-homogeneous coordinates, scaling all nine values produces an equivalent |
| transformation, possibly improving precision. |
| |
| #Param buffer nine Scalar values ## |
| |
| #Example |
| #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); |
| ## |
| |
| #SeeAlso setAll get9 MakeAll |
| |
| #Method ## |
| |
| # ------------------------------------------------------------------------------ |
| |
| #Method void reset() |
| |
| Sets Matrix to identity; which has no effect on mapped Points. Sets Matrix to: |
| |
| #Code |
| #Literal |
| | 1 0 0 | |
| | 0 1 0 | |
| | 0 0 1 | |
| ## |
| |
| 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() |
| |
| Sets Matrix to identity; which has no effect on mapped Points. Sets Matrix to: |
| |
| #Code |
| #Literal |
| | 1 0 0 | |
| | 0 1 0 | |
| | 0 0 1 | |
| ## |
| |
| 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) |
| |
| Sets Matrix to translate by (dx, dy). |
| |
| #Param dx horizontal translation ## |
| #Param dy vertical translation ## |
| |
| #Example |
| #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); |
| ## |
| |
| #SeeAlso setTranslateX setTranslateY |
| |
| #Method ## |
| |
| # ------------------------------------------------------------------------------ |
| |
| #Method void setTranslate(const SkVector& v) |
| |
| Sets Matrix to translate by (v.fX, v.fY). |
| |
| #Param v Vector containing horizontal and vertical translation ## |
| |
| #Example |
| #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); |
| ## |
| |
| #SeeAlso setTranslateX setTranslateY MakeTrans |
| |
| #Method ## |
| |
| # ------------------------------------------------------------------------------ |
| |
| #Method void setScale(SkScalar sx, SkScalar sy, SkScalar px, SkScalar py) |
| |
| 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 horizontal scale factor ## |
| #Param sy vertical scale factor ## |
| #Param px pivot x ## |
| #Param py pivot y ## |
| |
| #Example |
| #Height 128 |
| 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, 64); |
| canvas->concat(m); |
| canvas->drawString("%", 128, 64, p); |
| } |
| } |
| ## |
| |
| #SeeAlso setScaleX setScaleY MakeScale preScale postScale |
| |
| #Method ## |
| |
| # ------------------------------------------------------------------------------ |
| |
| #Method void setScale(SkScalar sx, SkScalar sy) |
| |
| Sets Matrix to scale by sx and sy about at pivot point at (0, 0). |
| |
| #Param sx horizontal scale factor ## |
| #Param sy vertical scale factor ## |
| |
| #Example |
| #Height 128 |
| 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, 64); |
| canvas->concat(m); |
| canvas->drawString("@", 0, 0, p); |
| } |
| } |
| ## |
| |
| #SeeAlso setScaleX setScaleY MakeScale preScale postScale |
| |
| #Method ## |
| |
| # ------------------------------------------------------------------------------ |
| |
| #Method void setRotate(SkScalar degrees, SkScalar px, SkScalar py) |
| |
| 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 angle of axes relative to upright axes ## |
| #Param px pivot x ## |
| #Param py pivot y ## |
| |
| #Example |
| #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); |
| ## |
| |
| #SeeAlso setSinCos preRotate postRotate |
| |
| #Method ## |
| |
| # ------------------------------------------------------------------------------ |
| |
| #Method void setRotate(SkScalar degrees) |
| |
| Sets Matrix to rotate by degrees about a pivot point at (0, 0). |
| Positive degrees rotates clockwise. |
| |
| #Param degrees angle of axes relative to upright axes ## |
| |
| #Example |
| #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); |
| ## |
| |
| #SeeAlso setSinCos preRotate postRotate |
| |
| #Method ## |
| |
| # ------------------------------------------------------------------------------ |
| |
| #Method void setSinCos(SkScalar sinValue, SkScalar cosValue, |
| SkScalar px, SkScalar py) |
| |
| Sets Matrix to rotate by sinValue and cosValue, about a pivot point at (px, py). |
| The pivot point is unchanged when mapped with Matrix. |
| |
| Vector (sinValue, cosValue) describes the angle of rotation relative to (0, 1). |
| Vector length specifies scale. |
| |
| #Param sinValue rotation vector x component ## |
| #Param cosValue rotation vector y component ## |
| #Param px pivot x ## |
| #Param py pivot y ## |
| |
| #Example |
| #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); |
| ## |
| |
| #SeeAlso setRotate setScale setRSXform |
| |
| #Method ## |
| |
| # ------------------------------------------------------------------------------ |
| |
| #Method void setSinCos(SkScalar sinValue, SkScalar cosValue) |
| |
| Sets Matrix to rotate by sinValue and cosValue, about a pivot point at (0, 0). |
| |
| Vector (sinValue, cosValue) describes the angle of rotation relative to (0, 1). |
| Vector length specifies scale. |
| |
| #Param sinValue rotation vector x component ## |
| #Param cosValue rotation vector y component ## |
| |
| #Example |
| #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); |
| ## |
| |
| #SeeAlso setRotate setScale setRSXform |
| |
| #Method ## |
| |
| # ------------------------------------------------------------------------------ |
| |
| #Method SkMatrix& setRSXform(const SkRSXform& rsxForm) |
| |
| 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). |
| |
| #Param rsxForm compressed RSXform matrix ## |
| |
| #Return reference to Matrix ## |
| |
| #Example |
| #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); |
| ## |
| |
| #SeeAlso setSinCos setScale setTranslate |
| |
| #Method ## |
| |
| # ------------------------------------------------------------------------------ |
| |
| #Method void setSkew(SkScalar kx, SkScalar ky, SkScalar px, SkScalar py) |
| |
| 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 horizontal skew factor ## |
| #Param ky vertical skew factor ## |
| #Param px pivot x ## |
| #Param py pivot y ## |
| |
| #Example |
| 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); |
| } |
| } |
| ## |
| |
| #SeeAlso setSkewX setSkewY preSkew postSkew |
| |
| #Method ## |
| |
| # ------------------------------------------------------------------------------ |
| |
| #Method void setSkew(SkScalar kx, SkScalar ky) |
| |
| Sets Matrix to skew by kx and ky, about a pivot point at (0, 0). |
| |
| #Param kx horizontal skew factor ## |
| #Param ky vertical skew factor ## |
| |
| #Example |
| 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); |
| } |
| } |
| ## |
| |
| #SeeAlso setSkewX setSkewY preSkew postSkew |
| |
| #Method ## |
| |
| # ------------------------------------------------------------------------------ |
| |
| #Method void setConcat(const SkMatrix& a, const SkMatrix& b) |
| |
| Sets Matrix to Matrix a multiplied by Matrix b. Either a or b may be this. |
| |
| 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 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) |
| |
| 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. |
| |
| Given: |
| |
| #Code |
| #Literal |
| | A B C | | 1 0 dx | |
| Matrix = | D E F |, T(dx, dy) = | 0 1 dy | |
| | G H I | | 0 0 1 | |
| ## |
| |
| 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) |
| |
| Sets Matrix to Matrix multiplied by Matrix constructed from scaling by (sx, sy) |
| about pivot point (px, py). |
| This can be thought of as scaling about a pivot point before applying Matrix. |
| |
| Given: |
| |
| #Code |
| #Literal |
| | A B C | | sx 0 dx | |
| Matrix = | D E F |, S(sx, sy, px, py) = | 0 sy dy | |
| | G H I | | 0 0 1 | |
| ## |
| |
| where |
| |
| #Code |
| #Literal |
| dx = px - sx * px |
| dy = py - sy * py |
| ## |
| |
| sets Matrix to: |
| |
| #Code |
| #Literal |
| | A B C | | sx 0 dx | | A*sx B*sy A*dx+B*dy+C | |
| Matrix * S(sx, sy, px, py) = | D E F | | 0 sy dy | = | D*sx E*sy D*dx+E*dy+F | |
| | G H I | | 0 0 1 | | G*sx H*sy G*dx+H*dy+I | |
| ## |
| |
| #Param sx horizontal scale factor ## |
| #Param sy vertical scale factor ## |
| #Param px pivot x ## |
| #Param py pivot y ## |
| |
| #Example |
| #Image 3 |
| SkMatrix matrix; |
| SkPoint bitmapBounds[4], perspect[4] = {{50, 10}, {180, 40}, {236, 176}, {10, 206}}; |
| SkRect::Make(source.bounds()).toQuad(bitmapBounds); |
| matrix.setPolyToPoly(bitmapBounds, perspect, 4); |
| matrix.preScale(.75f, 1.5f, source.width() / 2, source.height() / 2); |
| canvas->concat(matrix); |
| canvas->drawBitmap(source, 0, 0); |
| ## |
| |
| #SeeAlso postScale setScale MakeScale |
| |
| #Method ## |
| |
| # ------------------------------------------------------------------------------ |
| |
| #Method void preScale(SkScalar sx, SkScalar sy) |
| |
| Sets Matrix to Matrix multiplied by Matrix constructed from scaling by (sx, sy) |
| about pivot point (0, 0). |
| This can be thought of as scaling about the origin before applying Matrix. |
| |
| Given: |
| |
| #Code |
| #Literal |
| | A B C | | sx 0 0 | |
| Matrix = | D E F |, S(sx, sy) = | 0 sy 0 | |
| | G H I | | 0 0 1 | |
| ## |
| |
| sets Matrix to: |
| |
| #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 sx horizontal scale factor ## |
| #Param sy vertical scale factor ## |
| |
| #Example |
| #Image 3 |
| SkMatrix matrix; |
| SkPoint bitmapBounds[4], perspect[4] = {{50, 10}, {180, 40}, {236, 176}, {10, 206}}; |
| SkRect::Make(source.bounds()).toQuad(bitmapBounds); |
| matrix.setPolyToPoly(bitmapBounds, perspect, 4); |
| matrix.preScale(.75f, 1.5f); |
| canvas->concat(matrix); |
| canvas->drawBitmap(source, 0, 0); |
| ## |
| |
| #SeeAlso postScale setScale MakeScale |
| |
| #Method ## |
| |
| # ------------------------------------------------------------------------------ |
| |
| #Method void preRotate(SkScalar degrees, SkScalar px, SkScalar py) |
| |
| Sets Matrix to Matrix multiplied by Matrix constructed from rotating by degrees |
| about pivot point (px, py). |
| This can be thought of as rotating about a pivot point before applying Matrix. |
| |
| Positive degrees rotates clockwise. |
| |
| Given: |
| |
| #Code |
| #Literal |
| | A B C | | c -s dx | |
| Matrix = | D E F |, R(degrees, px, py) = | s c dy | |
| | G H I | | 0 0 1 | |
| ## |
| |
| where |
| |
| #Code |
| #Literal |
| c = cos(degrees) |
| s = sin(degrees) |
| dx = s * py + (1 - c) * px |
| dy = -s * px + (1 - c) * py |
| ## |
| |
| sets Matrix to: |
| |
| #Code |
| #Literal |
| | 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 degrees angle of axes relative to upright axes ## |
| #Param px pivot x ## |
| #Param py pivot y ## |
| |
| #Example |
| #Image 3 |
| SkMatrix matrix; |
| SkPoint bitmapBounds[4], perspect[4] = {{50, 10}, {180, 40}, {236, 176}, {10, 206}}; |
| SkRect::Make(source.bounds()).toQuad(bitmapBounds); |
| matrix.setPolyToPoly(bitmapBounds, perspect, 4); |
| matrix.preRotate(45, source.width() / 2, source.height() / 2); |
| canvas->concat(matrix); |
| canvas->drawBitmap(source, 0, 0); |
| ## |
| |
| #SeeAlso postRotate setRotate |
| |
| #Method ## |
| |
| # ------------------------------------------------------------------------------ |
| |
| #Method void preRotate(SkScalar degrees) |
| |
| Sets Matrix to Matrix multiplied by Matrix constructed from rotating by degrees |
| about pivot point (0, 0). |
| This can be thought of as rotating about the origin before applying Matrix. |
| |
| Positive degrees rotates clockwise. |
| |
| Given: |
| |
| #Code |
| #Literal |
| | A B C | | c -s 0 | |
| Matrix = | D E F |, R(degrees, px, py) = | s c 0 | |
| | G H I | | 0 0 1 | |
| ## |
| |
| where |
| |
| #Code |
| #Literal |
| c = cos(degrees) |
| s = sin(degrees) |
| ## |
| |
| sets Matrix to: |
| |
| #Code |
| #Literal |
| | A B C | | c -s 0 | | Ac+Bs -As+Bc C | |
| Matrix * R(degrees, px, py) = | D E F | | s c 0 | = | Dc+Es -Ds+Ec F | |
| | G H I | | 0 0 1 | | Gc+Hs -Gs+Hc I | |
| ## |
| |
| #Param degrees angle of axes relative to upright axes ## |
| |
| #Example |
| #Image 3 |
| SkMatrix matrix; |
| SkPoint bitmapBounds[4], perspect[4] = {{50, 10}, {180, 40}, {236, 176}, {10, 206}}; |
| SkRect::Make(source.bounds()).toQuad(bitmapBounds); |
| matrix.setPolyToPoly(bitmapBounds, perspect, 4); |
| matrix.preRotate(45); |
| canvas->concat(matrix); |
| canvas->drawBitmap(source, 0, 0); |
| ## |
| |
| #SeeAlso postRotate setRotate |
| |
| #Method ## |
| |
| # ------------------------------------------------------------------------------ |
| |
| #Method void preSkew(SkScalar kx, SkScalar ky, SkScalar px, SkScalar py) |
| |
| Sets Matrix to Matrix multiplied by Matrix constructed from skewing by (kx, ky) |
| about pivot point (px, py). |
| This can be thought of as skewing about a pivot point before applying Matrix. |
| |
| Given: |
| |
| #Code |
| #Literal |
| | A B C | | 1 kx dx | |
| Matrix = | D E F |, K(kx, ky, px, py) = | ky 1 dy | |
| | G H I | | 0 0 1 | |
| ## |
| |
| where |
| |
| #Code |
| #Literal |
| dx = -kx * py |
| dy = -ky * px |
| ## |
| |
| sets Matrix to: |
| |
| #Code |
| #Literal |
| | A B C | | 1 kx dx | | A+B*ky A*kx+B A*dx+B*dy+C | |
| Matrix * K(kx, ky, px, py) = | D E F | | ky 1 dy | = | D+E*ky D*kx+E D*dx+E*dy+F | |
| | G H I | | 0 0 1 | | G+H*ky G*kx+H G*dx+H*dy+I | |
| ## |
| |
| #Param kx horizontal skew factor ## |
| #Param ky vertical skew factor ## |
| #Param px pivot x ## |
| #Param py pivot y ## |
| |
| #Example |
| #Image 3 |
| SkMatrix matrix; |
| SkPoint bitmapBounds[4], perspect[4] = {{50, 10}, {180, 40}, {236, 176}, {10, 206}}; |
| SkRect::Make(source.bounds()).toQuad(bitmapBounds); |
| matrix.setPolyToPoly(bitmapBounds, perspect, 4); |
| matrix.preSkew(.5f, 0, source.width() / 2, source.height() / 2); |
| canvas->concat(matrix); |
| canvas->drawBitmap(source, 0, 0); |
| ## |
| |
| #SeeAlso postSkew setSkew |
| |
| #Method ## |
| |
| # ------------------------------------------------------------------------------ |
| |
| #Method void preSkew(SkScalar kx, SkScalar ky) |
| |
| Sets Matrix to Matrix multiplied by Matrix constructed from skewing by (kx, ky) |
| about pivot point (0, 0). |
| This can be thought of as skewing about the origin before applying Matrix. |
| |
| Given: |
| |
| #Code |
| #Literal |
| | A B C | | 1 kx 0 | |
| Matrix = | D E F |, K(kx, ky) = | ky 1 0 | |
| | G H I | | 0 0 1 | |
| ## |
| |
| 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 preConcat(const SkMatrix& other) |
| |
| Sets Matrix to Matrix multiplied by Matrix other. |
| This can be thought of mapping by other before applying Matrix. |
| |
| Given: |
| |
| #Code |
| #Literal |
| | A B C | | J K L | |
| Matrix = | D E F |, other = | M N O | |
| | G H I | | P Q R | |
| ## |
| |
| sets Matrix to: |
| |
| #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 | |
| ## |
| |
| #Param other Matrix on right side of multiply expression ## |
| |
| #Example |
| #Image 3 |
| #Description |
| setPolyToPoly creates perspective matrices, one the inverse of the other. |
| Multiplying the matrix by its inverse turns into an identity matrix. |
| ## |
| SkMatrix matrix, matrix2; |
| SkPoint bitmapBounds[4], perspect[4] = {{50, 10}, {180, 40}, {236, 176}, {10, 206}}; |
| SkRect::Make(source.bounds()).toQuad(bitmapBounds); |
| matrix.setPolyToPoly(bitmapBounds, perspect, 4); |
| matrix2.setPolyToPoly(perspect, bitmapBounds, 4); |
| matrix.preConcat(matrix2); |
| canvas->concat(matrix); |
| canvas->drawBitmap(source, 0, 0); |
| ## |
| |
| #SeeAlso postConcat setConcat Concat |
| |
| #Method ## |
| |
| # ------------------------------------------------------------------------------ |
| |
| #Method void postTranslate(SkScalar dx, SkScalar dy) |
| |
| 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. |
| |
| Given: |
| |
| #Code |
| #Literal |
| | J K L | | 1 0 dx | |
| Matrix = | M N O |, T(dx, dy) = | 0 1 dy | |
| | P Q R | | 0 0 1 | |
| ## |
| |
| sets Matrix to: |
| |
| #Code |
| #Literal |
| | 1 0 dx | | J K L | | J+dx*P K+dx*Q L+dx*R | |
| T(dx, dy) * Matrix = | 0 1 dy | | M N O | = | M+dy*P N+dy*Q O+dy*R | |
| | 0 0 1 | | P Q R | | P Q R | |
| ## |
| |
| #Param dx x translation after applying Matrix ## |
| #Param dy y translation after applying Matrix ## |
| |
| #Example |
| #Height 160 |
| #Description |
| Compare with preTranslate example. |
| ## |
| SkPaint paint; |
| paint.setAntiAlias(true); |
| SkRect rect = {20, 20, 100, 100}; |
| for (int i = 0; i < 2; ++i ) { |
| SkMatrix matrix; |
| i == 0 ? matrix.reset(): matrix.setRotate(25, rect.centerX(), 320); |
| { |
| SkAutoCanvasRestore acr(canvas, true); |
| canvas->concat(matrix); |
| paint.setColor(SK_ColorGRAY); |
| canvas->drawRect(rect, paint); |
| } |
| paint.setColor(SK_ColorRED); |
| for (int j = 0; j < 2; ++j ) { |
| SkAutoCanvasRestore acr(canvas, true); |
| matrix.postTranslate(40, 40); |
| canvas->concat(matrix); |
| canvas->drawCircle(0, 0, 3, paint); |
| } |
| } |
| ## |
| |
| #SeeAlso preTranslate setTranslate MakeTrans |
| |
| #Method ## |
| |
| # ------------------------------------------------------------------------------ |
| |
| #Method void postScale(SkScalar sx, SkScalar sy, SkScalar px, SkScalar py) |
| |
| Sets Matrix to Matrix constructed from scaling by (sx, sy) about pivot point |
| (px, py), multiplied by Matrix. |
| This can be thought of as scaling about a pivot point after applying Matrix. |
| |
| Given: |
| |
| #Code |
| #Literal |
| | J K L | | sx 0 dx | |
| Matrix = | M N O |, S(sx, sy, px, py) = | 0 sy dy | |
| | P Q R | | 0 0 1 | |
| ## |
| |
| where |
| |
| #Code |
| #Literal |
| dx = px - sx * px |
| dy = py - sy * py |
| ## |
| |
| sets Matrix to: |
| |
| #Code |
| #Literal |
| | sx 0 dx | | J K L | | sx*J+dx*P sx*K+dx*Q sx*L+dx+R | |
| S(sx, sy, px, py) * Matrix = | 0 sy dy | | M N O | = | sy*M+dy*P sy*N+dy*Q sy*O+dy*R | |
| | 0 0 1 | | P Q R | | P Q R | |
| ## |
| |
| #Param sx horizontal scale factor ## |
| #Param sy vertical scale factor ## |
| #Param px pivot x ## |
| #Param py pivot y ## |
| |
| #Example |
| #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); |
| ## |
| |
| #SeeAlso preScale setScale MakeScale |
| |
| ## |
| |
| # ------------------------------------------------------------------------------ |
| |
| #Method void postScale(SkScalar sx, SkScalar sy) |
| |
| 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 sx horizontal scale factor ## |
| #Param sy vertical scale factor ## |
| |
| #Example |
| #Image 3 |
| SkMatrix matrix; |
| SkPoint bitmapBounds[4], perspect[4] = {{50, 10}, {180, 40}, {236, 176}, {10, 206}}; |
| SkRect::Make(source.bounds()).toQuad(bitmapBounds); |
| matrix.setPolyToPoly(bitmapBounds, perspect, 4); |
| matrix.postScale(.75f, 1.5f); |
| canvas->concat(matrix); |
| canvas->drawBitmap(source, 0, 0); |
| ## |
| |
| #SeeAlso preScale setScale MakeScale |
| |
| ## |
| |
| # ------------------------------------------------------------------------------ |
| |
| #Method bool postIDiv(int divx, int divy) |
| |
| Sets Matrix to Matrix constructed from scaling by |
| #Formula |
| (1/divx, 1/divy) |
| ## |
| about pivot point (px, py), multiplied by Matrix. |
| |
| 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 | |
| ## |
| |
| where |
| |
| #Code |
| #Literal |
| sx = 1 / divx |
| sy = 1 / divy |
| ## |
| |
| sets Matrix to: |
| |
| #Code |
| #Literal |
| | sx 0 0 | | J K L | | sx*J sx*K sx*L | |
| I(divx, divy) * Matrix = | 0 sy 0 | | M N O | = | sy*M sy*N sy*O | |
| | 0 0 1 | | P Q R | | P Q R | |
| ## |
| |
| #Param divx integer divisor for inverse scale in x ## |
| #Param divy integer divisor for inverse scale in y ## |
| |
| #Return true on successful scale ## |
| |
| #Example |
| #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); |
| ## |
| |
| #SeeAlso postScale MakeScale |
| |
| ## |
| |
| # ------------------------------------------------------------------------------ |
| |
| #Method void postRotate(SkScalar degrees, SkScalar px, SkScalar py) |
| |
| Sets Matrix to Matrix constructed from rotating by degrees about pivot point |
| (px, py), multiplied by Matrix. |
| This can be thought of as rotating about a pivot point after applying Matrix. |
| |
| Positive degrees rotates clockwise. |
| |
| Given: |
| |
| #Code |
| #Literal |
| | J K L | | c -s dx | |
| Matrix = | M N O |, R(degrees, px, py) = | s c dy | |
| | P Q R | | 0 0 1 | |
| ## |
| |
| where |
| |
| #Code |
| #Literal |
| c = cos(degrees) |
| s = sin(degrees) |
| dx = s * py + (1 - c) * px |
| dy = -s * px + (1 - c) * py |
| ## |
| |
| sets Matrix to: |
| |
| #Code |
| #Literal |
| |c -s dx| |J K L| |cJ-sM+dx*P cK-sN+dx*Q cL-sO+dx+R| |
| R(degrees, px, py) * Matrix = |s c dy| |M N O| = |sJ+cM+dy*P sK+cN+dy*Q sL+cO+dy*R| |
| |0 0 1| |P Q R| | P Q R| |
| ## |
| |
| #Param degrees angle of axes relative to upright axes ## |
| #Param px pivot x ## |
| #Param py pivot y ## |
| |
| #Example |
| #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); |
| ## |
| |
| #SeeAlso preRotate setRotate |
| |
| ## |
| |
| # ------------------------------------------------------------------------------ |
| |
| #Method void postRotate(SkScalar degrees) |
| |
| Sets Matrix to Matrix constructed from rotating by degrees about pivot point |
| (0, 0), multiplied by Matrix. |
| This can be thought of as rotating about the origin after applying Matrix. |
| |
| Positive degrees rotates clockwise. |
| |
| Given: |
| |
| #Code |
| #Literal |
| | J K L | | c -s 0 | |
| Matrix = | M N O |, R(degrees, px, py) = | s c 0 | |
| | P Q R | | 0 0 1 | |
| ## |
| |
| where |
| |
| #Code |
| #Literal |
| c = cos(degrees) |
| s = sin(degrees) |
| ## |
| |
| 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 |
| #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); |
| ## |
| |
| #SeeAlso preRotate setRotate |
| |
| ## |
| |
| # ------------------------------------------------------------------------------ |
| |
| #Method void postSkew(SkScalar kx, SkScalar ky, SkScalar px, SkScalar py) |
| |
| Sets Matrix to Matrix constructed from skewing by (kx, ky) about pivot point |
| (px, py), multiplied by Matrix. |
| This can be thought of as skewing about a pivot point after applying Matrix. |
| |
| Given: |
| |
| #Code |
| #Literal |
| | J K L | | 1 kx dx | |
| Matrix = | M N O |, K(kx, ky, px, py) = | ky 1 dy | |
| | P Q R | | 0 0 1 | |
| ## |
| |
| where |
| |
| #Code |
| #Literal |
| dx = -kx * py |
| dy = -ky * px |
| ## |
| |
| 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 |
| #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); |
| ## |
| |
| #SeeAlso preSkew setSkew |
| |
| ## |
| |
| # ------------------------------------------------------------------------------ |
| |
| #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 | |
| ## |
| |
| sets Matrix to: |
| |
| #Code |
| #Literal |
| | 1 kx 0 | | J K L | | J+kx*M K+kx*N L+kx*O | |
| K(kx, ky) * Matrix = | ky 1 0 | | M N O | = | ky*J+M ky*K+N ky*L+O | |
| | 0 0 1 | | P Q R | | P Q R | |
| ## |
| |
| #Param kx horizontal skew factor ## |
| #Param ky vertical skew factor ## |
| |
| #Example |
| #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); |
| ## |
| |
| #SeeAlso preSkew setSkew |
| |
| ## |
| |
| # ------------------------------------------------------------------------------ |
| |
| #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. |
| |
| Given: |
| |
| #Code |
| #Literal |
| | J K L | | A B C | |
| Matrix = | M N O |, other = | D E F | |
| | P Q R | | G H I | |
| ## |
| |
| 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 |
| #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); |
| ## |
| |
| #SeeAlso preConcat setConcat Concat |
| |
| ## |
| |
| # ------------------------------------------------------------------------------ |
| |
| #Enum ScaleToFit |
| |
| #Code |
| enum ScaleToFit { |
| kFill_ScaleToFit, |
| kStart_ScaleToFit, |
| kCenter_ScaleToFit, |
| kEnd_ScaleToFit, |
| }; |
| ## |
| |
| ScaleToFit describes how Matrix is constructed to map one Rect to another. |
| ScaleToFit may allow Matrix to have unequal horizontal and vertical scaling, |
| or may restrict Matrix to square scaling. If restricted, ScaleToFit specifies |
| how Matrix maps to the side or center of the destination Rect. |
| |
| #Const kFill_ScaleToFit 0 |
| Computes Matrix that scales in x and y independently, so that source Rect is |
| mapped to completely fill destination Rect. The aspect ratio of source Rect |
| may change. |
| ## |
| #Const kStart_ScaleToFit 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. |
| ## |
| |
| #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 bool setRectToRect(const SkRect& src, const SkRect& dst, ScaleToFit stf) |
| |
| 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: |
| |
| #Code |
| #Literal |
| | 0 0 0 | |
| | 0 0 0 | |
| | 0 0 1 | |
| ## |
| |
| #Param src Rect to map from ## |
| #Param dst Rect to map to ## |
| #Param stf one of: kFill_ScaleToFit, kStart_ScaleToFit, |
| kCenter_ScaleToFit, kEnd_ScaleToFit |
| ## |
| |
| #Return 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 static SkMatrix MakeRectToRect(const SkRect& src, const SkRect& dst, ScaleToFit stf) |
| |
| Returns Matrix set to scale and translate src Rect to dst Rect. stf selects |
| whether mapping completely fills dst or preserves the aspect ratio, and how to |
| align src within dst. Returns the identity Matrix if src is empty. If dst is |
| empty, returns Matrix set to: |
| |
| #Code |
| #Literal |
| | 0 0 0 | |
| | 0 0 0 | |
| | 0 0 1 | |
| ## |
| |
| #Param src Rect to map from ## |
| #Param dst Rect to map to ## |
| #Param stf one of: kFill_ScaleToFit, kStart_ScaleToFit, |
| kCenter_ScaleToFit, kEnd_ScaleToFit |
| ## |
| |
| #Return Matrix mapping src to dst ## |
| |
| #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 = 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] |
| ## |
| ## |
| |
| #SeeAlso setRectToRect ScaleToFit setPolyToPoly SkRect::isEmpty |
| |
| ## |
| |
| # ------------------------------------------------------------------------------ |
| |
| #Method bool setPolyToPoly(const SkPoint src[], const SkPoint dst[], int count) |
| |
| Sets Matrix to map src to dst. count must be zero or greater, and four or less. |
| |
| 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 |
| ## |
| |
| #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 |
| #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); |
| ## |
| |
| #SeeAlso Concat |
| |
| ## |
| |
| # ------------------------------------------------------------------------------ |
| |
| #Method static void SetAffineIdentity(SkScalar affine[6]) |
| |
| Fills affine with identity values in column major order. |
| Sets affine to: |
| |
| #Code |
| #Literal |
| | 1 0 0 | |
| | 0 1 0 | |
| ## |
| |
| Affine 3x2 matrices in column major order are used by OpenGL and XPS. |
| |
| #Param affine storage for 3x2 affine matrix ## |
| |
| #Example |
| 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 |
| ## |
| ## |
| |
| #SeeAlso setAffine asAffine |
| |
| ## |
| |
| # ------------------------------------------------------------------------------ |
| |
| #Method bool SK_WARN_UNUSED_RESULT asAffine(SkScalar affine[6]) const |
| |
| Fills affine in column major order. Sets affine to: |
| |
| #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 |
| 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 |
| ## |
| ## |
| |
| #SeeAlso setAffine SetAffineIdentity |
| |
| ## |
| |
| # ------------------------------------------------------------------------------ |
| |
| #Method void setAffine(const SkScalar affine[6]) |
| |
| Sets Matrix to affine values, passed in column major order. Given affine, |
| column, then row, as: |
| |
| #Code |
| #Literal |
| | scale-x skew-x translate-x | |
| | skew-y scale-y translate-y | |
| ## |
| |
| 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 |
| 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] |
| ## |
| ## |
| |
| #SeeAlso asAffine SetAffineIdentity |
| |
| ## |
| |
| # ------------------------------------------------------------------------------ |
| |
| #Method void mapPoints(SkPoint dst[], const SkPoint src[], int count) const |
| |
| 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: |
| |
| #Code |
| #Literal |
| | A B C | | x | |
| Matrix = | D E F |, pt = | y | |
| | G H I | | 1 | |
| ## |
| |
| where |
| |
| #Code |
| #Literal |
| for (i = 0; i < count; ++i) { |
| x = src[i].fX |
| y = src[i].fY |
| } |
| ## |
| |
| each dst Point is computed as: |
| |
| #Code |
| #Literal |
| |A B C| |x| Ax+By+C Dx+Ey+F |
| Matrix * pt = |D E F| |y| = |Ax+By+C Dx+Ey+F Gx+Hy+I| = ------- , ------- |
| |G H I| |1| Gx+Hy+I Gx+Hy+I |
| ## |
| |
| src and dst may point to the same storage. |
| |
| #Param dst storage for mapped Points ## |
| #Param src Points to transform ## |
| #Param count number of Points to transform ## |
| |
| #Example |
| 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); |
| } |
| ## |
| |
| #SeeAlso mapPointsWithStride mapXY mapHomogeneousPoints mapVectors |
| |
| ## |
| |
| # ------------------------------------------------------------------------------ |
| |
| #Method void mapPoints(SkPoint pts[], int count) const |
| |
| Maps pts Point array of length count in place. Points are mapped by multiplying |
| each Point by Matrix. Given: |
| |
| #Code |
| #Literal |
| | A B C | | x | |
| Matrix = | D E F |, pt = | y | |
| | G H I | | 1 | |
| ## |
| |
| where |
| |
| #Code |
| #Literal |
| for (i = 0; i < count; ++i) { |
| x = pts[i].fX |
| y = pts[i].fY |
| } |
| ## |
| |
| 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 |
| 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); |
| } |
| ## |
| |
| #SeeAlso mapPointsWithStride mapXY mapHomogeneousPoints mapVectors |
| |
| ## |
| |
| # ------------------------------------------------------------------------------ |
| |
| #Method void mapPointsWithStride(SkPoint pts[], size_t stride, int count) const |
| |
| Maps count pts, skipping stride bytes to advance from one Point to the next. |
| Points are mapped by multiplying each Point by Matrix. Given: |
| |
| #Code |
| #Literal |
| | A B C | | x | |
| Matrix = | D E F |, pt = | y | |
| | G H I | | 1 | |
| ## |
| |
| 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 |
| 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); |
| } |
| ## |
| |
| #SeeAlso mapPoints mapXY mapHomogeneousPoints mapVectors |
| |
| ## |
| |
| # ------------------------------------------------------------------------------ |
| |
| #Method void mapPointsWithStride(SkPoint dst[], const SkPoint src[], size_t stride, int count) const |
| |
| 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: |
| |
| #Code |
| #Literal |
| | A B C | | x | |
| Matrix = | D E F |, src = | y | |
| | G H I | | 1 | |
| ## |
| |
| each resulting dst Point is computed as: |
| |
| #Code |
| #Literal |
| |A B C| |x| Ax+By+C Dx+Ey+F |
| Matrix * pt = |D E F| |y| = |Ax+By+C Dx+Ey+F Gx+Hy+I| = ------- , ------- |
| |G H I| |1| Gx+Hy+I Gx+Hy+I |
| ## |
| |
| #Param dst storage for mapped Points ## |
| #Param src Points to transform ## |
| #Param stride size of record starting with Point, in bytes ## |
| #Param count number of Points to transform ## |
| |
| #Example |
| 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); |
| } |
| ## |
| |
| #SeeAlso mapPoints mapXY mapHomogeneousPoints mapVectors |
| |
| ## |
| |
| # ------------------------------------------------------------------------------ |
| |
| #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: |
| |
| #Code |
| #Literal |
| | A B C | | x | |
| Matrix = | D E F |, src = | y | |
| | G H I | | z | |
| ## |
| |
| each resulting dst Point is computed as: |
| |
| #Code |
| #Literal |
| |A B C| |x| |
| Matrix * src = |D E F| |y| = |Ax+By+Cz Dx+Ey+Fz Gx+Hy+Iz| |
| |G H I| |z| |
| ## |
| |
| #Param dst storage for mapped Point3 array ## |
| #Param src Point3 array to transform ## |
| #Param count items in Point3 array to transform ## |
| |
| #Example |
| 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); |
| ## |
| |
| #SeeAlso mapPoints mapXY mapPointsWithStride mapVectors |
| |
| ## |
| |
| # ------------------------------------------------------------------------------ |
| |
| #Method void mapXY(SkScalar x, SkScalar y, SkPoint* result) const |
| |
| Maps Point (x, y) to result. Point is mapped by multiplying by Matrix. Given: |
| |
| #Code |
| #Literal |
| | A B C | | x | |
| Matrix = | D E F |, pt = | y | |
| | G H I | | 1 | |
| ## |
| |
| 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 |
| 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); |
| ## |
| |
| #SeeAlso mapPoints mapPointsWithStride mapVectors |
| |
| ## |
| |
| # ------------------------------------------------------------------------------ |
| |
| #Method SkPoint mapXY(SkScalar x, SkScalar y) const |
| |
| Returns Point (x, y) multiplied by Matrix. Given: |
| |
| #Code |
| #Literal |
| | A B C | | x | |
| Matrix = | D E F |, pt = | y | |
| | G H I | | 1 | |
| ## |
| |
| 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 |
| #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); |
| ## |
| |
| #SeeAlso mapPoints mapPointsWithStride mapVectors |
| |
| ## |
| |
| # ------------------------------------------------------------------------------ |
| |
| #Method void mapVectors(SkVector dst[], const SkVector src[], int count) const |
| |
| 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: |
| |
| #Code |
| #Literal |
| | A B 0 | | x | |
| Matrix = | D E 0 |, src = | y | |
| | G H I | | 1 | |
| ## |
| |
| where |
| |
| #Code |
| #Literal |
| for (i = 0; i < count; ++i) { |
| x = src[i].fX |
| y = src[i].fY |
| } |
| ## |
| |
| each dst Vector is computed as: |
| |
| #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 |
| ## |
| |
| src and dst may point to the same storage. |
| |
| #Param dst storage for mapped Vectors ## |
| #Param src Vectors to transform ## |
| #Param count number of Vectors to transform ## |
| |
| #Example |
| 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); |
| } |
| ## |
| |
| #SeeAlso mapVector mapPoints mapPointsWithStride mapXY |
| |
| ## |
| |
| # ------------------------------------------------------------------------------ |
| |
| #Method void mapVectors(SkVector vecs[], int count) const |
| |
| Maps vecs Vector array of length count in place, multiplying each Vector by |
| Matrix, treating Matrix translation as zero. Given: |
| |
| #Code |
| #Literal |
| | A B 0 | | x | |
| Matrix = | D E 0 |, vec = | y | |
| | G H I | | 1 | |
| ## |
| |
| where |
| |
| #Code |
| #Literal |
| for (i = 0; i < count; ++i) { |
| x = vecs[i].fX |
| y = vecs[i].fY |
| } |
| ## |
| |
| each result Vector is computed as: |
| |
| #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 |
| ## |
| |
| #Param vecs Vectors to transform, and storage for mapped Vectors ## |
| #Param count number of Vectors to transform ## |
| |
| #Example |
| 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)); |
| } |
| ## |
| |
| #SeeAlso mapVector mapPoints mapPointsWithStride mapXY |
| |
| ## |
| |
| # ------------------------------------------------------------------------------ |
| |
| #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: |
| |
| #Code |
| #Literal |
| #Outdent |
| |A B 0| |dx| A*dx+B*dy D*dx+E*dy |
| Matrix * vec = |D E 0| |dy| = |A*dx+B*dy D*dx+E*dy G*dx+H*dy+I| = ----------- , ----------- |
| |G H I| | 1| G*dx+H*dy+I G*dx+*dHy+I |
| ## |
| |
| #Param dx x-coordinate of Vector to map ## |
| #Param dy y-coordinate of Vector to map ## |
| #Param result storage for mapped Vector ## |
| |
| #Example |
| 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); |
| } |
| ## |
| |
| #SeeAlso mapVectors mapPoints mapPointsWithStride mapXY |
| |
| ## |
| |
| # ------------------------------------------------------------------------------ |
| |
| #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 mapped Vector ## |
| |
| #Example |
| 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); |
| } |
| ## |
| |
| #SeeAlso mapVectors mapPoints mapPointsWithStride mapXY |
| |
| ## |
| |
| # ------------------------------------------------------------------------------ |
| |
| #Method bool mapRect(SkRect* dst, const SkRect& src) const |
| |
| Sets dst to bounds of src corners mapped by Matrix. |
| Returns true if mapped corners are dst corners. |
| |
| Returned value is the same as calling rectStaysRect. |
| |
| #Param dst storage for bounds of mapped Points ## |
| #Param src Rect to map ## |
| |
| #Return true if dst is equivalent to mapped src ## |
| |
| #Example |
| 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); |
| ## |
| |
| #SeeAlso mapPoints rectStaysRect |
| |
| ## |
| |
| # ------------------------------------------------------------------------------ |
| |
| #Method bool mapRect(SkRect* rect) const |
| |
| Sets rect to bounds of rect corners mapped by Matrix. |
| Returns true if mapped corners are computed rect corners. |
| |
| Returned value is the same as calling rectStaysRect. |
| |
| #Param rect rectangle to map, and storage for bounds of mapped corners ## |
| |
| #Return true if result is equivalent to mapped src ## |
| |
| #Example |
| 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); |
| ## |
| |
| #SeeAlso mapRectScaleTranslate mapPoints rectStaysRect |
| |
| ## |
| |
| # ------------------------------------------------------------------------------ |
| |
| #Method void mapRectToQuad(SkPoint dst[4], const SkRect& rect) const |
| |
| 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). |
| |
| 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. |
| |
| Given: |
| |
| #Code |
| #Literal |
| | A B C | | x | |
| Matrix = | D E F |, pt = | y | |
| | G H I | | 1 | |
| ## |
| |
| where pt is initialized from each of (rect.fLeft, rect.fTop), |
| (rect.fRight, rect.fTop), (rect.fRight, rect.fBottom), (rect.fLeft, rect.fBottom), |
| each dst Point is computed as: |
| |
| #Code |
| #Literal |
| |A B C| |x| Ax+By+C Dx+Ey+F |
| Matrix * pt = |D E F| |y| = |Ax+By+C Dx+Ey+F Gx+Hy+I| = ------- , ------- |
| |G H I| |1| Gx+Hy+I Gx+Hy+I |
| ## |
| |
| #Param dst storage for mapped corner Points ## |
| #Param rect Rect to map ## |
| |
| #Example |
| #Height 192 |
| 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); |
| ## |
| |
| #SeeAlso mapRect mapRectScaleTranslate |
| |
| ## |
| |
| # ------------------------------------------------------------------------------ |
| |
| #Method void mapRectScaleTranslate(SkRect* dst, const SkRect& src) const |
| |
| 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. |
| |
| #Param dst storage for bounds of mapped Points ## |
| #Param src Rect to map ## |
| |
| #Example |
| 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); |
| ## |
| |
| #SeeAlso mapRect mapRectToQuad isScaleTranslate rectStaysRect |
| |
| ## |
| |
| # ------------------------------------------------------------------------------ |
| |
| #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 radius Circle size to map ## |
| |
| #Return average mapped radius ## |
| |
| #Example |
| #Description |
| The area enclosed by a square with sides equal to mappedRadius is the same as |
| the area enclosed by the ellipse major and minor axes. |
| ## |
| SkPaint paint; |
| paint.setAntiAlias(true); |
| SkMatrix matrix; |
| const SkPoint center = {108, 93}; |
| matrix.setScale(2, .5f, center.fX, center.fY); |
| matrix.postRotate(45, center.fX, center.fY); |
| const SkScalar circleRadius = 50; |
| SkScalar mappedRadius = matrix.mapRadius(circleRadius); |
| SkVector minorAxis, majorAxis; |
| matrix.mapVector(0, circleRadius, &minorAxis); |
| matrix.mapVector(circleRadius, 0, &majorAxis); |
| SkString mappedArea; |
| mappedArea.printf("area = %g", mappedRadius * mappedRadius); |
| canvas->drawString(mappedArea, 145, 250, paint); |
| canvas->drawString("mappedRadius", center.fX + mappedRadius + 3, center.fY, paint); |
| paint.setColor(SK_ColorRED); |
| SkString axArea; |
| axArea.printf("area = %g", majorAxis.length() * minorAxis.length()); |
| paint.setStyle(SkPaint::kFill_Style); |
| canvas->drawString(axArea, 15, 250, paint); |
| paint.setStyle(SkPaint::kStroke_Style); |
| canvas->drawRect({10, 200, 10 + majorAxis.length(), 200 + minorAxis.length()}, paint); |
| paint.setColor(SK_ColorBLACK); |
| canvas->drawLine(center.fX, center.fY, center.fX + mappedRadius, center.fY, paint); |
| canvas->drawLine(center.fX, center.fY, center.fX, center.fY + mappedRadius, paint); |
| canvas->drawRect({140, 180, 140 + mappedRadius, 180 + mappedRadius}, paint); |
| canvas->concat(matrix); |
| canvas->drawCircle(center.fX, center.fY, circleRadius, paint); |
| paint.setColor(SK_ColorRED); |
| canvas->drawLine(center.fX, center.fY, center.fX + circleRadius, center.fY, paint); |
| canvas->drawLine(center.fX, center.fY, center.fX, center.fY + circleRadius, paint); |
| ## |
| |
| #SeeAlso mapVector |
| |
| ## |
| |
| # ------------------------------------------------------------------------------ |
| |
| #Method bool isFixedStepInX() const |
| |
| 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. |
| |
| 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 |
| SkMatrix matrix; |
| for (SkScalar px : { 0.0f, 0.1f } ) { |
| for (SkScalar py : { 0.0f, 0.1f } ) { |
| for (SkScalar sy : { 1, 2 } ) { |
| matrix.setAll(1, 0, 0, 0, sy, 0, px, py, 1); |
| matrix.dump(); |
| SkDebugf("isFixedStepInX: %s\n", matrix.isFixedStepInX() ? "true" : "false"); |
| } |
| } |
| } |
| #StdOut |
| [ 1.0000 0.0000 0.0000][ 0.0000 1.0000 0.0000][ 0.0000 0.0000 1.0000] |
| isFixedStepInX: true |
| [ 1.0000 0.0000 0.0000][ 0.0000 2.0000 0.0000][ 0.0000 0.0000 1.0000] |
| isFixedStepInX: true |
| [ 1.0000 0.0000 0.0000][ 0.0000 1.0000 0.0000][ 0.0000 0.1000 1.0000] |
| isFixedStepInX: true |
| [ 1.0000 0.0000 0.0000][ 0.0000 2.0000 0.0000][ 0.0000 0.1000 1.0000] |
| isFixedStepInX: true |
| [ 1.0000 0.0000 0.0000][ 0.0000 1.0000 0.0000][ 0.1000 0.0000 1.0000] |
| isFixedStepInX: false |
| [ 1.0000 0.0000 0.0000][ 0.0000 2.0000 0.0000][ 0.1000 0.0000 1.0000] |
| isFixedStepInX: false |
| [ 1.0000 0.0000 0.0000][ 0.0000 1.0000 0.0000][ 0.1000 0.1000 1.0000] |
| isFixedStepInX: false |
| [ 1.0000 0.0000 0.0000][ 0.0000 2.0000 0.0000][ 0.1000 0.1000 1.0000] |
| isFixedStepInX: false |
| ## |
| ## |
| |
| #SeeAlso fixedStepInX getType |
| |
| ## |
| |
| # ------------------------------------------------------------------------------ |
| |
| #Method 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 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. |
| |
| Returns true even when both Matrices contain NaN. |
| |
| NaN never equals any value, including itself. To improve performance, NaN values |
| are treated as bit patterns that are equal if their bit patterns are equal. |
| |
| #Param m Matrix to compare ## |
| |
| #Return true if m and Matrix are represented by identical bit patterns ## |
| |
| #Example |
| auto debugster = [](const char* prefix, const SkMatrix& a, const SkMatrix& b) -> void { |
| SkDebugf("%s: a %c= b a.cheapEqualTo(b): %s\n", prefix, |
| a == b ? '=' : '!', a.cheapEqualTo(b) ? "true" : "false"); |
| }; |
| SkMatrix a, b; |
| a.setAll(1, 0, 0, 0, 1, 0, 0, 0, 1); |
| b.setIdentity(); |
| debugster("identity", a, b); |
| a.setAll(1, -0.0f, 0, 0, 1, 0, 0, 0, 1); |
| debugster("neg zero", a, b); |
| a.setAll(1, SK_ScalarNaN, 0, 0, 1, 0, 0, 0, 1); |
| debugster(" one NaN", a, b); |
| b.setAll(1, SK_ScalarNaN, 0, 0, 1, 0, 0, 0, 1); |
| debugster("both NaN", a, b); |
| #StdOut |
| identity: a == b a.cheapEqualTo(b): true |
| neg zero: a == b a.cheapEqualTo(b): false |
| one NaN: a != b a.cheapEqualTo(b): false |
| both NaN: a != b a.cheapEqualTo(b): true |
| ## |
| ## |
| |
| #SeeAlso 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 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 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 |
| ## |
| ## |
| |
| #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 |
| 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); |
| ## |
| |
| #SeeAlso cheapEqualTo operator==(const SkMatrix& a, const SkMatrix& b) |
| |
| ## |
| |
| # ------------------------------------------------------------------------------ |
| |
| #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 |
| 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 |
| ## |
| ## |
| |
| #SeeAlso toString |
| |
| ## |
| |
| # ------------------------------------------------------------------------------ |
| |
| #Method void toString(SkString* str) const |
| |
| 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 |
| 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 |
| ## |
| ## |
| |
| #SeeAlso dump |
| |
| ## |
| |
| # ------------------------------------------------------------------------------ |
| |
| #Method SkScalar getMinScale() const |
| |
| 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 |
| SkMatrix matrix; |
| matrix.setScale(42, 24); |
| SkDebugf("matrix.getMinScale() %g\n", matrix.getMinScale()); |
| #StdOut |
| matrix.getMinScale() 24 |
| ## |
| ## |
| |
| #SeeAlso getMaxScale getMinMaxScales |
| |
| ## |
| |
| # ------------------------------------------------------------------------------ |
| |
| #Method SkScalar getMaxScale() const |
| |
| 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 |
| SkMatrix matrix; |
| matrix.setScale(42, 24); |
| SkDebugf("matrix.getMaxScale() %g\n", matrix.getMaxScale()); |
| #StdOut |
| matrix.getMaxScale() 42 |
| ## |
| ## |
| |
| #SeeAlso getMinScale getMinMaxScales |
| |
| ## |
| |
| # ------------------------------------------------------------------------------ |
| |
| #Method bool SK_WARN_UNUSED_RESULT getMinMaxScales(SkScalar scaleFactors[2]) const |
| |
| Sets scaleFactors[0] to the minimum scaling factor, and scaleFactors[1] to the |
| maximum scaling factor. Scaling factors are computed by decomposing |
| the Matrix scaling and skewing elements. |
| |
| Returns true if scaleFactors are found; otherwise, returns false and sets |
| scaleFactors to undefined values. |
| |
| #Param scaleFactors storage for minimum and maximum scale factors ## |
| |
| #Return true if scale factors were computed correctly ## |
| |
| #Example |
| 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 |
| ## |
| ## |
| |
| #SeeAlso getMinScale getMaxScale |
| |
| ## |
| |
| # ------------------------------------------------------------------------------ |
| |
| #Method bool decomposeScale(SkSize* scale, SkMatrix* remaining = nullptr) const |
| |
| 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 |
| Matrix = scale * Remaining |
| ## |
| |
| #Param scale x and y scaling factors; may be nullptr ## |
| #Param remaining Matrix without scaling; may be nullptr ## |
| |
| #Return true if scale can be computed ## |
| |
| #Example |
| 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] |
| ## |
| ## |
| |
| #SeeAlso setScale MakeScale |
| |
| ## |
| |
| # ------------------------------------------------------------------------------ |
| |
| #Method static const SkMatrix& I() |
| |
| Returns reference to const identity Matrix. Returned Matrix is set to: |
| |
| #Code |
| #Literal |
| | 1 0 0 | |
| | 0 1 0 | |
| | 0 0 1 | |
| ## |
| |
| #Return const identity Matrix ## |
| |
| #Example |
| 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 |
| ## |
| ## |
| |
| #SeeAlso reset() setIdentity |
| |
| ## |
| |
| # ------------------------------------------------------------------------------ |
| |
| #Method static const SkMatrix& InvalidMatrix() |
| |
| 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 const invalid Matrix ## |
| |
| #Example |
| SkDebugf("scaleX %g\n", SkMatrix::InvalidMatrix().getScaleX()); |
| #StdOut |
| scaleX 3.40282e+38 |
| ## |
| ## |
| |
| #SeeAlso SeeAlso getType |
| |
| ## |
| |
| # ------------------------------------------------------------------------------ |
| |
| #Method static SkMatrix Concat(const SkMatrix& a, const SkMatrix& 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 Matrix on left side of multiply expression ## |
| #Param b Matrix on right side of multiply expression ## |
| |
| #Return Matrix computed from a times b ## |
| |
| #Example |
| #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); |
| ## |
| |
| #SeeAlso preConcat postConcat |
| |
| ## |
| |
| # ------------------------------------------------------------------------------ |
| |
| #Method void dirtyMatrixTypeCache() |
| |
| Sets internal cache to unknown state. Use to force update after repeated |
| modifications to Matrix element reference returned by operator[](int index). |
| |
| #Example |
| 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 |
| ## |
| ## |
| |
| #SeeAlso operator[](int index) getType |
| |
| ## |
| |
| # ------------------------------------------------------------------------------ |
| |
| #Method void setScaleTranslate(SkScalar sx, SkScalar sy, SkScalar tx, SkScalar ty) |
| |
| Initializes Matrix with scale and translate elements. |
| |
| #Code |
| #Literal |
| | sx 0 tx | |
| | 0 sy ty | |
| | 0 0 1 | |
| ## |
| |
| #Param sx horizontal scale factor to store ## |
| #Param sy vertical scale factor to store ## |
| #Param tx horizontal translation to store ## |
| #Param ty vertical translation to store ## |
| |
| #Example |
| 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] |
| ## |
| ## |
| |
| #SeeAlso setScale preTranslate postTranslate |
| |
| ## |
| |
| # ------------------------------------------------------------------------------ |
| |
| #Method bool isFinite() const |
| |
| Returns true if all elements of the matrix are finite. Returns false if any |
| element is infinity, or NaN. |
| |
| #Return true if matrix has only finite elements ## |
| |
| #Example |
| 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 |
| ## |
| ## |
| |
| #SeeAlso operator== |
| |
| ## |
| |
| #Class SkMatrix ## |
| |
| #Topic Matrix ## |