Flutter Engine
The Flutter Engine
Functions
SkMatrixUtils.h File Reference
#include "include/core/SkPoint.h"
#include "include/core/SkSize.h"

Go to the source code of this file.

Functions

bool SkTreatAsSprite (const SkMatrix &, const SkISize &size, const SkSamplingOptions &, bool isAntiAlias)
 
bool SkDecomposeUpper2x2 (const SkMatrix &matrix, SkPoint *rotation1, SkPoint *scale, SkPoint *rotation2)
 

Function Documentation

◆ SkDecomposeUpper2x2()

bool SkDecomposeUpper2x2 ( const SkMatrix matrix,
SkPoint rotation1,
SkPoint scale,
SkPoint rotation2 
)

Decomposes the upper-left 2x2 of the matrix into a rotation (represented by the cosine and sine of the rotation angle), followed by a non-uniform scale, followed by another rotation. If there is a reflection, one of the scale factors will be negative. Returns true if successful. Returns false if the matrix is degenerate.

Definition at line 1689 of file SkMatrix.cpp.

1692 {
1693
1698
1699 if (is_degenerate_2x2(A, B, C, D)) {
1700 return false;
1701 }
1702
1703 double w1, w2;
1704 SkScalar cos1, sin1;
1705 SkScalar cos2, sin2;
1706
1707 // do polar decomposition (M = Q*S)
1708 SkScalar cosQ, sinQ;
1709 double Sa, Sb, Sd;
1710 // if M is already symmetric (i.e., M = I*S)
1711 if (SkScalarNearlyEqual(B, C)) {
1712 cosQ = 1;
1713 sinQ = 0;
1714
1715 Sa = A;
1716 Sb = B;
1717 Sd = D;
1718 } else {
1719 cosQ = A + D;
1720 sinQ = C - B;
1721 SkScalar reciplen = SkScalarInvert(SkScalarSqrt(cosQ*cosQ + sinQ*sinQ));
1722 cosQ *= reciplen;
1723 sinQ *= reciplen;
1724
1725 // S = Q^-1*M
1726 // we don't calc Sc since it's symmetric
1727 Sa = A*cosQ + C*sinQ;
1728 Sb = B*cosQ + D*sinQ;
1729 Sd = -B*sinQ + D*cosQ;
1730 }
1731
1732 // Now we need to compute eigenvalues of S (our scale factors)
1733 // and eigenvectors (bases for our rotation)
1734 // From this, should be able to reconstruct S as U*W*U^T
1736 // already diagonalized
1737 cos1 = 1;
1738 sin1 = 0;
1739 w1 = Sa;
1740 w2 = Sd;
1741 cos2 = cosQ;
1742 sin2 = sinQ;
1743 } else {
1744 double diff = Sa - Sd;
1745 double discriminant = sqrt(diff*diff + 4.0*Sb*Sb);
1746 double trace = Sa + Sd;
1747 if (diff > 0) {
1748 w1 = 0.5*(trace + discriminant);
1749 w2 = 0.5*(trace - discriminant);
1750 } else {
1751 w1 = 0.5*(trace - discriminant);
1752 w2 = 0.5*(trace + discriminant);
1753 }
1754
1755 cos1 = SkDoubleToScalar(Sb); sin1 = SkDoubleToScalar(w1 - Sa);
1756 SkScalar reciplen = SkScalarInvert(SkScalarSqrt(cos1*cos1 + sin1*sin1));
1757 cos1 *= reciplen;
1758 sin1 *= reciplen;
1759
1760 // rotation 2 is composition of Q and U
1761 cos2 = cos1*cosQ - sin1*sinQ;
1762 sin2 = sin1*cosQ + cos1*sinQ;
1763
1764 // rotation 1 is U^T
1765 sin1 = -sin1;
1766 }
1767
1768 if (scale) {
1769 scale->fX = SkDoubleToScalar(w1);
1770 scale->fY = SkDoubleToScalar(w2);
1771 }
1772 if (rotation1) {
1773 rotation1->fX = cos1;
1774 rotation1->fY = sin1;
1775 }
1776 if (rotation2) {
1777 rotation2->fX = cos2;
1778 rotation2->fY = sin2;
1779 }
1780
1781 return true;
1782}
static bool is_degenerate_2x2(SkScalar scaleX, SkScalar skewX, SkScalar skewY, SkScalar scaleY)
Definition: SkMatrix.cpp:172
#define SkScalarInvert(x)
Definition: SkScalar.h:73
static bool SkScalarNearlyZero(SkScalar x, SkScalar tolerance=SK_ScalarNearlyZero)
Definition: SkScalar.h:101
static bool SkScalarNearlyEqual(SkScalar x, SkScalar y, SkScalar tolerance=SK_ScalarNearlyZero)
Definition: SkScalar.h:107
#define SkDoubleToScalar(x)
Definition: SkScalar.h:64
#define SkScalarSqrt(x)
Definition: SkScalar.h:42
static constexpr int kMScaleX
horizontal scale factor
Definition: SkMatrix.h:353
static constexpr int kMSkewY
vertical skew factor
Definition: SkMatrix.h:356
static constexpr int kMScaleY
vertical scale factor
Definition: SkMatrix.h:357
static constexpr int kMSkewX
horizontal skew factor
Definition: SkMatrix.h:354
float SkScalar
Definition: extension.cpp:12
#define B
unsigned useCenter Optional< SkMatrix > matrix
Definition: SkRecords.h:258
SIN Vec< N, float > sqrt(const Vec< N, float > &x)
Definition: SkVx.h:706
const Scalar scale
float fX
x-axis value
Definition: SkPoint_impl.h:164
float fY
y-axis value
Definition: SkPoint_impl.h:165

◆ SkTreatAsSprite()

bool SkTreatAsSprite ( const SkMatrix mat,
const SkISize size,
const SkSamplingOptions sampling,
bool  isAntiAlias 
)

Given a matrix, size and an antialias setting, return true if the computed dst-rect would align such that there is a 1-to-1 coorspondence between src and dst pixels. This can be called by drawing code to see if drawBitmap can be turned into drawSprite (which is faster).

The src-rect is defined to be { 0, 0, size.width(), size.height() }

Definition at line 1614 of file SkMatrix.cpp.

1615 {
1617 return false;
1618 }
1619
1620 // Our path aa is 2-bits, and our rect aa is 8, so we could use 8,
1621 // but in practice 4 seems enough (still looks smooth) and allows
1622 // more slightly fractional cases to fall into the fast (sprite) case.
1623 static const unsigned kAntiAliasSubpixelBits = 4;
1624
1625 const unsigned subpixelBits = isAntiAlias ? kAntiAliasSubpixelBits : 0;
1626
1627 // quick reject on affine or perspective
1629 return false;
1630 }
1631
1632 // We don't want to snap to pixels if we're asking for linear filtering with
1633 // a subpixel translation. (b/41322892).
1634 // This mirrors `tweak_sampling` in SkImageShader.cpp
1636 (mat.getTranslateX() != (int)mat.getTranslateX() ||
1637 mat.getTranslateY() != (int)mat.getTranslateY())) {
1638 return false;
1639 }
1640
1641 // quick success check
1642 if (!subpixelBits && !(mat.getType() & ~SkMatrix::kTranslate_Mask)) {
1643 return true;
1644 }
1645
1646 // mapRect supports negative scales, so we eliminate those first
1647 if (mat.getScaleX() < 0 || mat.getScaleY() < 0) {
1648 return false;
1649 }
1650
1651 SkRect dst;
1653
1654 {
1655 SkRect src;
1656 src.set(isrc);
1657 mat.mapRect(&dst, src);
1658 }
1659
1660 // just apply the translate to isrc
1663
1664 if (subpixelBits) {
1665 isrc.fLeft = SkLeftShift(isrc.fLeft, subpixelBits);
1666 isrc.fTop = SkLeftShift(isrc.fTop, subpixelBits);
1667 isrc.fRight = SkLeftShift(isrc.fRight, subpixelBits);
1668 isrc.fBottom = SkLeftShift(isrc.fBottom, subpixelBits);
1669
1670 const float scale = 1 << subpixelBits;
1671 dst.fLeft *= scale;
1672 dst.fTop *= scale;
1673 dst.fRight *= scale;
1674 dst.fBottom *= scale;
1675 }
1676
1677 SkIRect idst;
1678 dst.round(&idst);
1679 return isrc == idst;
1680}
static constexpr int32_t SkLeftShift(int32_t value, int32_t shift)
Definition: SkMath.h:37
#define SkScalarRoundToInt(x)
Definition: SkScalar.h:37
SkScalar getTranslateY() const
Definition: SkMatrix.h:452
SkScalar getScaleX() const
Definition: SkMatrix.h:415
SkScalar getScaleY() const
Definition: SkMatrix.h:422
bool mapRect(SkRect *dst, const SkRect &src, SkApplyPerspectiveClip pc=SkApplyPerspectiveClip::kYes) const
Definition: SkMatrix.cpp:1141
SkScalar getTranslateX() const
Definition: SkMatrix.h:445
@ kTranslate_Mask
translation SkMatrix
Definition: SkMatrix.h:193
@ kScale_Mask
scale SkMatrix
Definition: SkMatrix.h:194
TypeMask getType() const
Definition: SkMatrix.h:207
static bool NoChangeWithIdentityMatrix(const SkSamplingOptions &sampling)
SkSamplingOptions sampling
Definition: SkRecords.h:337
it will be possible to load the file into Perfetto s trace viewer disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font Indicates whether the embedding started a prefetch of the default font manager before creating the engine run In non interactive keep the shell running after the Dart script has completed enable serial On low power devices with low core running concurrent GC tasks on threads can cause them to contend with the UI thread which could potentially lead to jank This option turns off all concurrent GC activities domain network JSON encoded network policy per domain This overrides the DisallowInsecureConnections switch Embedder can specify whether to allow or disallow insecure connections at a domain level old gen heap size
Definition: switches.h:259
dst
Definition: cp.py:12
Definition: SkRect.h:32
int32_t fBottom
larger y-axis bounds
Definition: SkRect.h:36
int32_t fTop
smaller y-axis bounds
Definition: SkRect.h:34
static constexpr SkIRect MakeSize(const SkISize &size)
Definition: SkRect.h:66
void offset(int32_t dx, int32_t dy)
Definition: SkRect.h:367
int32_t fLeft
smaller x-axis bounds
Definition: SkRect.h:33
int32_t fRight
larger x-axis bounds
Definition: SkRect.h:35
const SkFilterMode filter