You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
3052 lines
78 KiB
3052 lines
78 KiB
#Topic Matrix |
|
#Alias Matrices ## |
|
#Alias Matrix_Reference ## |
|
|
|
#Class SkMatrix |
|
|
|
#Code |
|
#Populate |
|
## |
|
|
|
Matrix holds a 3 by 3 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. |
|
|
|
# ------------------------------------------------------------------------------ |
|
|
|
#Method static SkMatrix MakeScale(SkScalar sx, SkScalar sy) |
|
#In Constructors |
|
#Line # constructs from scale on x-axis and y-axis ## |
|
#Populate |
|
|
|
#Example |
|
#Image 4 |
|
canvas->concat(SkMatrix::MakeScale(4, 3)); |
|
canvas->drawBitmap(source, 0, 0); |
|
## |
|
|
|
#SeeAlso setScale postScale preScale |
|
|
|
## |
|
|
|
# ------------------------------------------------------------------------------ |
|
|
|
#Method static SkMatrix MakeScale(SkScalar scale) |
|
#Populate |
|
|
|
#Example |
|
#Image 4 |
|
canvas->concat(SkMatrix::MakeScale(4)); |
|
canvas->drawBitmap(source, 0, 0); |
|
## |
|
|
|
#SeeAlso setScale postScale preScale |
|
|
|
## |
|
|
|
# ------------------------------------------------------------------------------ |
|
|
|
#Method static SkMatrix MakeTrans(SkScalar dx, SkScalar dy) |
|
#In Constructors |
|
#Line # constructs from translate on x-axis and y-axis ## |
|
#Populate |
|
|
|
#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 MakeAll(SkScalar scaleX, SkScalar skewX, SkScalar transX, |
|
SkScalar skewY, SkScalar scaleY, SkScalar transY, |
|
SkScalar pers0, SkScalar pers1, SkScalar pers2) |
|
#In Constructors |
|
#Line # constructs all nine values ## |
|
#Populate |
|
|
|
#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 |
|
#Line # bit field for Matrix complexity ## |
|
#Code |
|
#Populate |
|
## |
|
|
|
Enumeration of bit fields for mask returned by getType. |
|
Used to identify the complexity of Matrix, to optimize performance. |
|
|
|
#Const kIdentity_Mask 0 |
|
#Line # identity Matrix; all bits clear ## |
|
all bits clear if Matrix is identity |
|
## |
|
#Const kTranslate_Mask 1 |
|
#Line # translation Matrix ## |
|
set if Matrix has translation |
|
## |
|
#Const kScale_Mask 2 |
|
#Line # scale Matrix ## |
|
set if Matrix scales x-axis or y-axis |
|
## |
|
#Const kAffine_Mask 4 |
|
#Line # skew or rotate Matrix ## |
|
set if Matrix skews or rotates |
|
## |
|
#Const kPerspective_Mask 8 |
|
#Line # perspective Matrix ## |
|
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 |
|
|
|
## |
|
|
|
# ------------------------------------------------------------------------------ |
|
#Subtopic Property |
|
#Line # values and attributes ## |
|
## |
|
|
|
#Method TypeMask getType() const |
|
#In Property |
|
#Line # returns transform complexity ## |
|
#Populate |
|
|
|
#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 |
|
#In Property |
|
#Line # returns if matrix equals the identity Matrix ## |
|
#Populate |
|
|
|
#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 |
|
#In Property |
|
#Line # returns if transform is limited to scale and translate ## |
|
#Populate |
|
|
|
#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 |
|
#In Property |
|
#Line # returns if transform is limited to translate ## |
|
#Populate |
|
|
|
#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 |
|
#In Property |
|
#Line # returns if mapped Rect can be represented by another Rect ## |
|
#Populate |
|
|
|
#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 |
|
#In Property |
|
#Line # returns if mapping restricts to 90 degree multiples and mirroring ## |
|
#Populate |
|
|
|
#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 |
|
#In Property |
|
#Line # returns if transform includes perspective ## |
|
#Populate |
|
|
|
#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 |
|
#In Property |
|
#Line # returns if transform is limited to square scale and rotation ## |
|
#Populate |
|
|
|
#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 |
|
#In Property |
|
#Line # returns if mapped 90 angle remains 90 degrees ## |
|
#Populate |
|
|
|
#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 |
|
|
|
## |
|
|
|
# ------------------------------------------------------------------------------ |
|
|
|
#Subtopic MemberIndex |
|
#In Constant |
|
#Line # member indices ## |
|
#Filter kM |
|
#Code |
|
#Populate |
|
## |
|
|
|
Matrix organizes its values in row order. These members correspond to |
|
each value in Matrix. |
|
|
|
#Const kMScaleX 0 |
|
#Line # horizontal scale factor ## |
|
## |
|
#Const kMSkewX 1 |
|
#Line # horizontal skew factor ## |
|
## |
|
#Const kMTransX 2 |
|
#Line # horizontal translation ## |
|
## |
|
#Const kMSkewY 3 |
|
#Line # vertical skew factor ## |
|
## |
|
#Const kMScaleY 4 |
|
#Line # vertical scale factor ## |
|
## |
|
#Const kMTransY 5 |
|
#Line # vertical translation ## |
|
## |
|
#Const kMPersp0 6 |
|
#Line # input x perspective factor ## |
|
## |
|
#Const kMPersp1 7 |
|
#Line # input y perspective factor ## |
|
## |
|
#Const kMPersp2 8 |
|
#Line # 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() |
|
|
|
## |
|
|
|
# ------------------------------------------------------------------------------ |
|
|
|
#Subtopic AffineIndex |
|
#In Constant |
|
#Line # affine member indices ## |
|
#Filter KA |
|
|
|
#Code |
|
#Populate |
|
## |
|
|
|
Affine arrays are in column major order to match the matrix used by |
|
PDF and XPS. |
|
|
|
#Const kAScaleX 0 |
|
#Line # horizontal scale factor ## |
|
## |
|
#Const kASkewY 1 |
|
#Line # vertical skew factor ## |
|
## |
|
#Const kASkewX 2 |
|
#Line # horizontal skew factor ## |
|
## |
|
#Const kAScaleY 3 |
|
#Line # vertical scale factor ## |
|
## |
|
#Const kATransX 4 |
|
#Line # horizontal translation ## |
|
## |
|
#Const kATransY 5 |
|
#Line # vertical translation ## |
|
## |
|
|
|
#NoExample |
|
## |
|
|
|
#SeeAlso SetAffineIdentity asAffine setAffine |
|
|
|
## |
|
|
|
# ------------------------------------------------------------------------------ |
|
|
|
#Method SkScalar operator[](int index) const |
|
|
|
#Line # returns Matrix value ## |
|
#Populate |
|
|
|
#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 |
|
#In Property |
|
#Line # returns one of nine Matrix values ## |
|
#Populate |
|
|
|
#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 |
|
#In Property |
|
#Line # returns horizontal scale factor ## |
|
#Populate |
|
|
|
#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 |
|
#In Property |
|
#Line # returns vertical scale factor ## |
|
#Populate |
|
|
|
#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 |
|
#In Property |
|
#Line # returns vertical skew factor ## |
|
#Populate |
|
|
|
#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 |
|
#In Property |
|
#Line # returns horizontal skew factor ## |
|
#Populate |
|
|
|
#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 |
|
#In Property |
|
#Line # returns horizontal translation ## |
|
#Populate |
|
|
|
#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 |
|
#In Property |
|
#Line # returns vertical translation ## |
|
#Populate |
|
|
|
#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 |
|
#In Property |
|
#Line # returns input x perspective factor ## |
|
#Populate |
|
|
|
#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 |
|
#In Property |
|
#Line # returns input y perspective factor ## |
|
#Populate |
|
|
|
#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) |
|
|
|
#Line # returns writable reference to Matrix value ## |
|
#Populate |
|
|
|
#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 |
|
|
|
## |
|
|
|
# ------------------------------------------------------------------------------ |
|
#Subtopic Set |
|
#Line # sets one or more matrix values ## |
|
## |
|
|
|
#Method void set(int index, SkScalar value) |
|
#In Set |
|
#Line # sets one value ## |
|
#Populate |
|
|
|
#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) |
|
#In Set |
|
#Line # sets horizontal scale factor ## |
|
#Populate |
|
|
|
#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) |
|
#In Set |
|
#Line # sets vertical scale factor ## |
|
#Populate |
|
|
|
#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) |
|
#In Set |
|
#Line # sets vertical skew factor ## |
|
#Populate |
|
|
|
#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) |
|
#In Set |
|
#Line # sets horizontal skew factor ## |
|
#Populate |
|
|
|
#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) |
|
#In Set |
|
#Line # sets horizontal translation ## |
|
#Populate |
|
|
|
#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) |
|
#In Set |
|
#Line # sets vertical translation ## |
|
#Populate |
|
|
|
#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) |
|
#In Set |
|
#Line # sets input x perspective factor ## |
|
#Populate |
|
|
|
#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) |
|
#In Set |
|
#Line # sets input y perspective factor ## |
|
#Populate |
|
|
|
#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) |
|
#In Set |
|
#Line # sets all values from parameters ## |
|
#Populate |
|
|
|
#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 |
|
#In Property |
|
#Line # returns all nine Matrix values ## |
|
#Populate |
|
|
|
#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]) |
|
#In Set |
|
#In Constructors |
|
#Line # sets all values from Scalar array ## |
|
#Populate |
|
|
|
#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() |
|
#In Constructors |
|
#In Set |
|
#Line # sets Matrix to identity ## |
|
#Populate |
|
|
|
#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() |
|
#In Constructors |
|
#In Set |
|
#Line # sets Matrix to identity ## |
|
#Populate |
|
|
|
#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) |
|
#In Constructors |
|
#In Set |
|
#Line # sets to translate on x-axis and y-axis ## |
|
#Populate |
|
|
|
#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) |
|
#Populate |
|
|
|
#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) |
|
#In Constructors |
|
#In Set |
|
#Line # sets to scale about a point ## |
|
#Populate |
|
|
|
#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) |
|
#Populate |
|
|
|
#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) |
|
#In Constructors |
|
#In Set |
|
#Line # sets to rotate about a point ## |
|
#Populate |
|
|
|
#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) |
|
#Populate |
|
|
|
#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) |
|
#In Constructors |
|
#In Set |
|
#Line # sets to rotate and scale about a point ## |
|
#Populate |
|
|
|
#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) |
|
#Populate |
|
|
|
#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) |
|
#In Constructors |
|
#In Set |
|
#Line # sets to rotate, scale, and translate ## |
|
#Populate |
|
|
|
#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) |
|
#In Constructors |
|
#In Set |
|
#Line # sets to skew about a point ## |
|
#Populate |
|
|
|
#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) |
|
#Populate |
|
|
|
#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) |
|
#In Constructors |
|
#In Set |
|
#Line # sets to Matrix parameter multiplied by Matrix parameter ## |
|
#Populate |
|
|
|
#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) |
|
#In Set |
|
#In Operators |
|
#Line # pre-multiplies Matrix by translation ## |
|
#Populate |
|
|
|
#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) |
|
#In Set |
|
#In Operators |
|
#Line # pre-multiplies Matrix by scale ## |
|
#Populate |
|
|
|
#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) |
|
#In Set |
|
#In Operators |
|
#Populate |
|
|
|
#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) |
|
#In Set |
|
#In Operators |
|
#Line # pre-multiplies Matrix by rotation ## |
|
#Populate |
|
|
|
#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) |
|
#Populate |
|
|
|
#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) |
|
#In Set |
|
#In Operators |
|
#Line # pre-multiplies Matrix by skew ## |
|
#Populate |
|
|
|
#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) |
|
#Populate |
|
|
|
#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) |
|
#In Set |
|
#In Operators |
|
#Line # pre-multiplies Matrix by Matrix parameter ## |
|
#Populate |
|
|
|
#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) |
|
#In Set |
|
#In Operators |
|
#Line # post-multiplies Matrix by translation ## |
|
#Populate |
|
|
|
#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) |
|
#In Set |
|
#In Operators |
|
#Line # post-multiplies Matrix by scale ## |
|
#Populate |
|
|
|
#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) |
|
#Populate |
|
|
|
#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) |
|
#In Set |
|
#In Operators |
|
#Line # post-multiplies Matrix by inverse scale ## |
|
Sets Matrix to Matrix constructed from scaling by (1/divx, 1/divy), |
|
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 on x-axis ## |
|
#Param divy integer divisor for inverse scale on y-axis ## |
|
|
|
#Return true on successful scale ## |
|
|
|
#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.postIDiv(1, 2); |
|
canvas->concat(matrix); |
|
canvas->drawBitmap(source, 0, 0); |
|
## |
|
|
|
#SeeAlso postScale MakeScale |
|
|
|
## |
|
|
|
# ------------------------------------------------------------------------------ |
|
|
|
#Method void postRotate(SkScalar degrees, SkScalar px, SkScalar py) |
|
#In Set |
|
#In Operators |
|
#Line # post-multiplies Matrix by rotation ## |
|
#Populate |
|
|
|
#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) |
|
#Populate |
|
|
|
#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) |
|
#In Set |
|
#In Operators |
|
#Line # post-multiplies Matrix by skew ## |
|
#Populate |
|
|
|
#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) |
|
#Populate |
|
|
|
#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) |
|
#In Set |
|
#In Operators |
|
#Line # post-multiplies Matrix by Matrix parameter ## |
|
#Populate |
|
|
|
#Example |
|
#Image 3 |
|
#Height 64 |
|
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.postConcat(matrix); |
|
canvas->concat(matrix); |
|
canvas->drawBitmap(source, 0, 0); |
|
## |
|
|
|
#SeeAlso preConcat setConcat Concat |
|
|
|
## |
|
|
|
# ------------------------------------------------------------------------------ |
|
|
|
#Enum ScaleToFit |
|
#Line # options to map Rects ## |
|
#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 |
|
#Line # scales about x-axis and y-axis to fill destination Rect ## |
|
Computes Matrix that scales about x-axis and y-axis independently, so that |
|
source Rect is mapped to completely fill destination Rect. The aspect ratio |
|
of source Rect may change. |
|
## |
|
#Const kStart_ScaleToFit 1 |
|
#Line # scales and aligns to left and top ## |
|
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 |
|
#Line # scales and aligns to center ## |
|
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 |
|
#Line # scales and aligns to right and bottom ## |
|
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) |
|
#In Set |
|
#Line # sets to map one Rect to another ## |
|
#Populate |
|
|
|
#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) |
|
#In Constructors |
|
#Line # constructs from source Rect to destination Rect ## |
|
#Populate |
|
|
|
#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) |
|
#In Set |
|
#Line # sets to map one to four points to an equal array of points ## |
|
#Populate |
|
|
|
#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 invert(SkMatrix* inverse) const |
|
#In Operators |
|
#Line # returns inverse, if possible ## |
|
#Populate |
|
|
|
#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); |
|
if (matrix.invert(&matrix)) { |
|
canvas->concat(matrix); |
|
canvas->drawPoints(SkCanvas::kPoints_PointMode, 4, dst, paint); |
|
} |
|
## |
|
|
|
#SeeAlso Concat |
|
|
|
## |
|
|
|
# ------------------------------------------------------------------------------ |
|
|
|
#Method static void SetAffineIdentity(SkScalar affine[6]) |
|
#In Constructors |
|
#Line # sets 3x2 array to identity ## |
|
#Populate |
|
|
|
#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 asAffine(SkScalar affine[6]) const |
|
#In Constructors |
|
#Line # copies to 3x2 array ## |
|
#Populate |
|
|
|
#Example |
|
SkMatrix matrix; |
|
matrix.setAll(2, 3, 4, 5, 6, 7, 0, 0, 1); |
|
SkScalar affine[6]; |
|
if (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]) |
|
#In Constructors |
|
#In Set |
|
#Line # sets left two columns ## |
|
#Populate |
|
|
|
#Example |
|
SkMatrix matrix; |
|
matrix.setAll(2, 3, 4, 5, 6, 7, 0, 0, 1); |
|
SkScalar affine[6]; |
|
if (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 |
|
|
|
## |
|
|
|
# ------------------------------------------------------------------------------ |
|
#Subtopic Transform |
|
#Line # map points with Matrix ## |
|
## |
|
|
|
#Method void mapPoints(SkPoint dst[], const SkPoint src[], int count) const |
|
#In Transform |
|
#Line # maps Point array ## |
|
#Populate |
|
|
|
#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 |
|
#Populate |
|
|
|
#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 |
|
#In Transform |
|
#Line # maps Point3 array ## |
|
#Populate |
|
|
|
#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 |
|
#In Transform |
|
#Line # maps Point ## |
|
#Populate |
|
|
|
#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 |
|
#Populate |
|
|
|
#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 |
|
#In Transform |
|
#Line # maps Vector array ## |
|
#Populate |
|
|
|
#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 |
|
#Populate |
|
|
|
#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 |
|
#In Transform |
|
#Line # maps Vector ## |
|
#Populate |
|
|
|
#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 |
|
#Populate |
|
|
|
#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 |
|
#In Transform |
|
#Line # returns bounds of mapped Rect ## |
|
#Populate |
|
|
|
#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 |
|
#Populate |
|
|
|
#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 SkRect mapRect(const SkRect& src) const |
|
#Populate |
|
|
|
#Example |
|
SkRect rect{110, 50, 180, 100}; |
|
SkMatrix matrix; |
|
matrix.setRotate(50, 28, 28); |
|
SkRect mapped = matrix.mapRect(rect); |
|
SkPaint paint; |
|
paint.setAntiAlias(true); |
|
paint.setStyle(SkPaint::kStroke_Style); |
|
canvas->drawRect(rect, paint); |
|
canvas->drawRect(mapped, paint); |
|
canvas->concat(matrix); |
|
canvas->drawRect(rect, paint); |
|
## |
|
|
|
#SeeAlso mapRectToQuad mapRectScaleTranslate |
|
#Method ## |
|
|
|
# ------------------------------------------------------------------------------ |
|
|
|
#Method void mapRectToQuad(SkPoint dst[4], const SkRect& rect) const |
|
#In Transform |
|
#Line # maps Rect to Point array ## |
|
#Populate |
|
|
|
#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 |
|
#In Transform |
|
#Line # returns bounds of mapped Rect ## |
|
#Populate |
|
|
|
#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 |
|
#In Transform |
|
#Line # returns mean radius of mapped Circle ## |
|
#Populate |
|
|
|
#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 |
|
#In Property |
|
#Line # returns if transformation supports fixed step on x-axis ## |
|
#Populate |
|
|
|
#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 |
|
#In Property |
|
#Line # returns step on x-axis for a position on y-axis ## |
|
#Populate |
|
|
|
#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 |
|
#In Operators |
|
#Line # compares Matrix pair using memcmp() ## |
|
#Populate |
|
|
|
#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) |
|
|
|
#Line # returns true if members are equal ## |
|
#Populate |
|
|
|
#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) |
|
|
|
#Line # returns true if members are unequal ## |
|
#Populate |
|
|
|
#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); |
|
if (a.invert(&b)) { |
|
debugster("identity", a, b); |
|
} |
|
## |
|
|
|
#SeeAlso cheapEqualTo operator==(const SkMatrix& a, const SkMatrix& b) |
|
|
|
## |
|
|
|
# ------------------------------------------------------------------------------ |
|
#Subtopic Utility |
|
#Line # rarely called management functions ## |
|
## |
|
|
|
#Method void dump() const |
|
#In Utility |
|
#Line # sends text representation using floats to standard output ## |
|
#Populate |
|
|
|
#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 SkPath::dump |
|
|
|
## |
|
|
|
# ------------------------------------------------------------------------------ |
|
|
|
#Method SkScalar getMinScale() const |
|
#In Property |
|
#Line # returns minimum scaling, if possible ## |
|
#Populate |
|
|
|
#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 |
|
#In Property |
|
#Line # returns maximum scaling, if possible ## |
|
#Populate |
|
|
|
#Example |
|
SkMatrix matrix; |
|
matrix.setScale(42, 24); |
|
SkDebugf("matrix.getMaxScale() %g\n", matrix.getMaxScale()); |
|
#StdOut |
|
matrix.getMaxScale() 42 |
|
## |
|
## |
|
|
|
#SeeAlso getMinScale getMinMaxScales |
|
|
|
## |
|
|
|
# ------------------------------------------------------------------------------ |
|
|
|
#Method bool getMinMaxScales(SkScalar scaleFactors[2]) const |
|
#In Property |
|
#Line # returns minimum and maximum scaling, if possible ## |
|
#Populate |
|
|
|
#Example |
|
SkMatrix matrix; |
|
matrix.setAll(1, 0, 0, 0, 1, 0, 0, 0, 0); |
|
if (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 |
|
#In Property |
|
#Line # separates scale if possible ## |
|
Decomposes Matrix into scale components and whatever remains. Returns false if |
|
Matrix could not be decomposed. |
|
|
|
Sets scale to portion of Matrix that scale axes. Sets remaining to Matrix |
|
with 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 axes 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() |
|
#In Constructors |
|
#Line # returns a reference to a const identity Matrix ## |
|
#Populate |
|
|
|
#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() |
|
#In Constructors |
|
#Line # returns a reference to a const invalid Matrix ## |
|
#Populate |
|
|
|
#Example |
|
SkDebugf("scaleX %g\n", SkMatrix::InvalidMatrix().getScaleX()); |
|
#StdOut |
|
scaleX 3.40282e+38 |
|
## |
|
## |
|
|
|
#SeeAlso getType |
|
|
|
## |
|
|
|
# ------------------------------------------------------------------------------ |
|
|
|
#Method static SkMatrix Concat(const SkMatrix& a, const SkMatrix& b) |
|
#In Operators |
|
#Line # returns the concatenation of Matrix pair ## |
|
#Populate |
|
|
|
#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() |
|
#In Utility |
|
#Line # sets internal cache to unknown state ## |
|
#Populate |
|
|
|
#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) |
|
#In Constructors |
|
#In Set |
|
#Line # sets to scale and translate ## |
|
#Populate |
|
|
|
#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 |
|
#In Property |
|
#Line # returns if all Matrix values are not infinity, NaN ## |
|
#Populate |
|
|
|
#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 ##
|
|
|