fa3783f17d
Use private version already in SkMatrixPriv. Change-Id: I6e9546afdf2b072402f9deecec99a6d236e2c7f4 Reviewed-on: https://skia-review.googlesource.com/91400 Reviewed-by: Robert Phillips <robertphillips@google.com> Commit-Queue: Brian Salomon <bsalomon@google.com>
4414 lines
118 KiB
Plaintext
4414 lines
118 KiB
Plaintext
#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. ##
|
|
# 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 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 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, src, count);
|
|
debugster(src);
|
|
##
|
|
|
|
#SeeAlso mapPoints mapXY 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 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 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 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 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 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 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 ##
|