SkMatrix.cpp 59 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800
  1. /*
  2. * Copyright 2006 The Android Open Source Project
  3. *
  4. * Use of this source code is governed by a BSD-style license that can be
  5. * found in the LICENSE file.
  6. */
  7. #include "include/core/SkMatrix.h"
  8. #include "include/core/SkPaint.h"
  9. #include "include/core/SkPoint3.h"
  10. #include "include/core/SkRSXform.h"
  11. #include "include/core/SkString.h"
  12. #include "include/private/SkFloatBits.h"
  13. #include "include/private/SkNx.h"
  14. #include "include/private/SkTo.h"
  15. #include "src/core/SkMathPriv.h"
  16. #include "src/core/SkMatrixPriv.h"
  17. #include <cstddef>
  18. #include <utility>
  19. static void normalize_perspective(SkScalar mat[9]) {
  20. // If it was interesting to never store the last element, we could divide all 8 other
  21. // elements here by the 9th, making it 1.0...
  22. //
  23. // When SkScalar was SkFixed, we would sometimes rescale the entire matrix to keep its
  24. // component values from getting too large. This is not a concern when using floats/doubles,
  25. // so we do nothing now.
  26. // Disable this for now, but it could be enabled.
  27. #if 0
  28. if (0 == mat[SkMatrix::kMPersp0] && 0 == mat[SkMatrix::kMPersp1]) {
  29. SkScalar p2 = mat[SkMatrix::kMPersp2];
  30. if (p2 != 0 && p2 != 1) {
  31. double inv = 1.0 / p2;
  32. for (int i = 0; i < 6; ++i) {
  33. mat[i] = SkDoubleToScalar(mat[i] * inv);
  34. }
  35. mat[SkMatrix::kMPersp2] = 1;
  36. }
  37. }
  38. #endif
  39. }
  40. // In a few places, we performed the following
  41. // a * b + c * d + e
  42. // as
  43. // a * b + (c * d + e)
  44. //
  45. // sdot and scross are indended to capture these compound operations into a
  46. // function, with an eye toward considering upscaling the intermediates to
  47. // doubles for more precision (as we do in concat and invert).
  48. //
  49. // However, these few lines that performed the last add before the "dot", cause
  50. // tiny image differences, so we guard that change until we see the impact on
  51. // chrome's layouttests.
  52. //
  53. #define SK_LEGACY_MATRIX_MATH_ORDER
  54. /* [scale-x skew-x trans-x] [X] [X']
  55. [skew-y scale-y trans-y] * [Y] = [Y']
  56. [persp-0 persp-1 persp-2] [1] [1 ]
  57. */
  58. SkMatrix& SkMatrix::reset() { *this = SkMatrix(); return *this; }
  59. SkMatrix& SkMatrix::set9(const SkScalar buffer[]) {
  60. memcpy(fMat, buffer, 9 * sizeof(SkScalar));
  61. normalize_perspective(fMat);
  62. this->setTypeMask(kUnknown_Mask);
  63. return *this;
  64. }
  65. SkMatrix& SkMatrix::setAffine(const SkScalar buffer[]) {
  66. fMat[kMScaleX] = buffer[kAScaleX];
  67. fMat[kMSkewX] = buffer[kASkewX];
  68. fMat[kMTransX] = buffer[kATransX];
  69. fMat[kMSkewY] = buffer[kASkewY];
  70. fMat[kMScaleY] = buffer[kAScaleY];
  71. fMat[kMTransY] = buffer[kATransY];
  72. fMat[kMPersp0] = 0;
  73. fMat[kMPersp1] = 0;
  74. fMat[kMPersp2] = 1;
  75. this->setTypeMask(kUnknown_Mask);
  76. return *this;
  77. }
  78. // this guy aligns with the masks, so we can compute a mask from a varaible 0/1
  79. enum {
  80. kTranslate_Shift,
  81. kScale_Shift,
  82. kAffine_Shift,
  83. kPerspective_Shift,
  84. kRectStaysRect_Shift
  85. };
  86. static const int32_t kScalar1Int = 0x3f800000;
  87. uint8_t SkMatrix::computePerspectiveTypeMask() const {
  88. // Benchmarking suggests that replacing this set of SkScalarAs2sCompliment
  89. // is a win, but replacing those below is not. We don't yet understand
  90. // that result.
  91. if (fMat[kMPersp0] != 0 || fMat[kMPersp1] != 0 || fMat[kMPersp2] != 1) {
  92. // If this is a perspective transform, we return true for all other
  93. // transform flags - this does not disable any optimizations, respects
  94. // the rule that the type mask must be conservative, and speeds up
  95. // type mask computation.
  96. return SkToU8(kORableMasks);
  97. }
  98. return SkToU8(kOnlyPerspectiveValid_Mask | kUnknown_Mask);
  99. }
  100. uint8_t SkMatrix::computeTypeMask() const {
  101. unsigned mask = 0;
  102. if (fMat[kMPersp0] != 0 || fMat[kMPersp1] != 0 || fMat[kMPersp2] != 1) {
  103. // Once it is determined that that this is a perspective transform,
  104. // all other flags are moot as far as optimizations are concerned.
  105. return SkToU8(kORableMasks);
  106. }
  107. if (fMat[kMTransX] != 0 || fMat[kMTransY] != 0) {
  108. mask |= kTranslate_Mask;
  109. }
  110. int m00 = SkScalarAs2sCompliment(fMat[SkMatrix::kMScaleX]);
  111. int m01 = SkScalarAs2sCompliment(fMat[SkMatrix::kMSkewX]);
  112. int m10 = SkScalarAs2sCompliment(fMat[SkMatrix::kMSkewY]);
  113. int m11 = SkScalarAs2sCompliment(fMat[SkMatrix::kMScaleY]);
  114. if (m01 | m10) {
  115. // The skew components may be scale-inducing, unless we are dealing
  116. // with a pure rotation. Testing for a pure rotation is expensive,
  117. // so we opt for being conservative by always setting the scale bit.
  118. // along with affine.
  119. // By doing this, we are also ensuring that matrices have the same
  120. // type masks as their inverses.
  121. mask |= kAffine_Mask | kScale_Mask;
  122. // For rectStaysRect, in the affine case, we only need check that
  123. // the primary diagonal is all zeros and that the secondary diagonal
  124. // is all non-zero.
  125. // map non-zero to 1
  126. m01 = m01 != 0;
  127. m10 = m10 != 0;
  128. int dp0 = 0 == (m00 | m11) ; // true if both are 0
  129. int ds1 = m01 & m10; // true if both are 1
  130. mask |= (dp0 & ds1) << kRectStaysRect_Shift;
  131. } else {
  132. // Only test for scale explicitly if not affine, since affine sets the
  133. // scale bit.
  134. if ((m00 ^ kScalar1Int) | (m11 ^ kScalar1Int)) {
  135. mask |= kScale_Mask;
  136. }
  137. // Not affine, therefore we already know secondary diagonal is
  138. // all zeros, so we just need to check that primary diagonal is
  139. // all non-zero.
  140. // map non-zero to 1
  141. m00 = m00 != 0;
  142. m11 = m11 != 0;
  143. // record if the (p)rimary diagonal is all non-zero
  144. mask |= (m00 & m11) << kRectStaysRect_Shift;
  145. }
  146. return SkToU8(mask);
  147. }
  148. ///////////////////////////////////////////////////////////////////////////////
  149. bool operator==(const SkMatrix& a, const SkMatrix& b) {
  150. const SkScalar* SK_RESTRICT ma = a.fMat;
  151. const SkScalar* SK_RESTRICT mb = b.fMat;
  152. return ma[0] == mb[0] && ma[1] == mb[1] && ma[2] == mb[2] &&
  153. ma[3] == mb[3] && ma[4] == mb[4] && ma[5] == mb[5] &&
  154. ma[6] == mb[6] && ma[7] == mb[7] && ma[8] == mb[8];
  155. }
  156. ///////////////////////////////////////////////////////////////////////////////
  157. // helper function to determine if upper-left 2x2 of matrix is degenerate
  158. static inline bool is_degenerate_2x2(SkScalar scaleX, SkScalar skewX,
  159. SkScalar skewY, SkScalar scaleY) {
  160. SkScalar perp_dot = scaleX*scaleY - skewX*skewY;
  161. return SkScalarNearlyZero(perp_dot, SK_ScalarNearlyZero*SK_ScalarNearlyZero);
  162. }
  163. ///////////////////////////////////////////////////////////////////////////////
  164. bool SkMatrix::isSimilarity(SkScalar tol) const {
  165. // if identity or translate matrix
  166. TypeMask mask = this->getType();
  167. if (mask <= kTranslate_Mask) {
  168. return true;
  169. }
  170. if (mask & kPerspective_Mask) {
  171. return false;
  172. }
  173. SkScalar mx = fMat[kMScaleX];
  174. SkScalar my = fMat[kMScaleY];
  175. // if no skew, can just compare scale factors
  176. if (!(mask & kAffine_Mask)) {
  177. return !SkScalarNearlyZero(mx) && SkScalarNearlyEqual(SkScalarAbs(mx), SkScalarAbs(my));
  178. }
  179. SkScalar sx = fMat[kMSkewX];
  180. SkScalar sy = fMat[kMSkewY];
  181. if (is_degenerate_2x2(mx, sx, sy, my)) {
  182. return false;
  183. }
  184. // upper 2x2 is rotation/reflection + uniform scale if basis vectors
  185. // are 90 degree rotations of each other
  186. return (SkScalarNearlyEqual(mx, my, tol) && SkScalarNearlyEqual(sx, -sy, tol))
  187. || (SkScalarNearlyEqual(mx, -my, tol) && SkScalarNearlyEqual(sx, sy, tol));
  188. }
  189. bool SkMatrix::preservesRightAngles(SkScalar tol) const {
  190. TypeMask mask = this->getType();
  191. if (mask <= kTranslate_Mask) {
  192. // identity, translate and/or scale
  193. return true;
  194. }
  195. if (mask & kPerspective_Mask) {
  196. return false;
  197. }
  198. SkASSERT(mask & (kAffine_Mask | kScale_Mask));
  199. SkScalar mx = fMat[kMScaleX];
  200. SkScalar my = fMat[kMScaleY];
  201. SkScalar sx = fMat[kMSkewX];
  202. SkScalar sy = fMat[kMSkewY];
  203. if (is_degenerate_2x2(mx, sx, sy, my)) {
  204. return false;
  205. }
  206. // upper 2x2 is scale + rotation/reflection if basis vectors are orthogonal
  207. SkVector vec[2];
  208. vec[0].set(mx, sy);
  209. vec[1].set(sx, my);
  210. return SkScalarNearlyZero(vec[0].dot(vec[1]), SkScalarSquare(tol));
  211. }
  212. ///////////////////////////////////////////////////////////////////////////////
  213. static inline SkScalar sdot(SkScalar a, SkScalar b, SkScalar c, SkScalar d) {
  214. return a * b + c * d;
  215. }
  216. static inline SkScalar sdot(SkScalar a, SkScalar b, SkScalar c, SkScalar d,
  217. SkScalar e, SkScalar f) {
  218. return a * b + c * d + e * f;
  219. }
  220. static inline SkScalar scross(SkScalar a, SkScalar b, SkScalar c, SkScalar d) {
  221. return a * b - c * d;
  222. }
  223. SkMatrix& SkMatrix::setTranslate(SkScalar dx, SkScalar dy) {
  224. *this = SkMatrix(1, 0, dx,
  225. 0, 1, dy,
  226. 0, 0, 1,
  227. (dx != 0 || dy != 0) ? kTranslate_Mask | kRectStaysRect_Mask
  228. : kIdentity_Mask | kRectStaysRect_Mask);
  229. return *this;
  230. }
  231. SkMatrix& SkMatrix::preTranslate(SkScalar dx, SkScalar dy) {
  232. const unsigned mask = this->getType();
  233. if (mask <= kTranslate_Mask) {
  234. fMat[kMTransX] += dx;
  235. fMat[kMTransY] += dy;
  236. } else if (mask & kPerspective_Mask) {
  237. SkMatrix m;
  238. m.setTranslate(dx, dy);
  239. return this->preConcat(m);
  240. } else {
  241. fMat[kMTransX] += sdot(fMat[kMScaleX], dx, fMat[kMSkewX], dy);
  242. fMat[kMTransY] += sdot(fMat[kMSkewY], dx, fMat[kMScaleY], dy);
  243. }
  244. this->updateTranslateMask();
  245. return *this;
  246. }
  247. SkMatrix& SkMatrix::postTranslate(SkScalar dx, SkScalar dy) {
  248. if (this->hasPerspective()) {
  249. SkMatrix m;
  250. m.setTranslate(dx, dy);
  251. this->postConcat(m);
  252. } else {
  253. fMat[kMTransX] += dx;
  254. fMat[kMTransY] += dy;
  255. this->updateTranslateMask();
  256. }
  257. return *this;
  258. }
  259. ///////////////////////////////////////////////////////////////////////////////
  260. SkMatrix& SkMatrix::setScale(SkScalar sx, SkScalar sy, SkScalar px, SkScalar py) {
  261. if (1 == sx && 1 == sy) {
  262. this->reset();
  263. } else {
  264. this->setScaleTranslate(sx, sy, px - sx * px, py - sy * py);
  265. }
  266. return *this;
  267. }
  268. SkMatrix& SkMatrix::setScale(SkScalar sx, SkScalar sy) {
  269. *this = SkMatrix(sx, 0, 0,
  270. 0, sy, 0,
  271. 0, 0, 1,
  272. (sx == 1 && sy == 1) ? kIdentity_Mask | kRectStaysRect_Mask
  273. : kScale_Mask | kRectStaysRect_Mask);
  274. return *this;
  275. }
  276. SkMatrix& SkMatrix::preScale(SkScalar sx, SkScalar sy, SkScalar px, SkScalar py) {
  277. if (1 == sx && 1 == sy) {
  278. return *this;
  279. }
  280. SkMatrix m;
  281. m.setScale(sx, sy, px, py);
  282. return this->preConcat(m);
  283. }
  284. SkMatrix& SkMatrix::preScale(SkScalar sx, SkScalar sy) {
  285. if (1 == sx && 1 == sy) {
  286. return *this;
  287. }
  288. // the assumption is that these multiplies are very cheap, and that
  289. // a full concat and/or just computing the matrix type is more expensive.
  290. // Also, the fixed-point case checks for overflow, but the float doesn't,
  291. // so we can get away with these blind multiplies.
  292. fMat[kMScaleX] *= sx;
  293. fMat[kMSkewY] *= sx;
  294. fMat[kMPersp0] *= sx;
  295. fMat[kMSkewX] *= sy;
  296. fMat[kMScaleY] *= sy;
  297. fMat[kMPersp1] *= sy;
  298. // Attempt to simplify our type when applying an inverse scale.
  299. // TODO: The persp/affine preconditions are in place to keep the mask consistent with
  300. // what computeTypeMask() would produce (persp/skew always implies kScale).
  301. // We should investigate whether these flag dependencies are truly needed.
  302. if (fMat[kMScaleX] == 1 && fMat[kMScaleY] == 1
  303. && !(fTypeMask & (kPerspective_Mask | kAffine_Mask))) {
  304. this->clearTypeMask(kScale_Mask);
  305. } else {
  306. this->orTypeMask(kScale_Mask);
  307. }
  308. return *this;
  309. }
  310. SkMatrix& SkMatrix::postScale(SkScalar sx, SkScalar sy, SkScalar px, SkScalar py) {
  311. if (1 == sx && 1 == sy) {
  312. return *this;
  313. }
  314. SkMatrix m;
  315. m.setScale(sx, sy, px, py);
  316. return this->postConcat(m);
  317. }
  318. SkMatrix& SkMatrix::postScale(SkScalar sx, SkScalar sy) {
  319. if (1 == sx && 1 == sy) {
  320. return *this;
  321. }
  322. SkMatrix m;
  323. m.setScale(sx, sy);
  324. return this->postConcat(m);
  325. }
  326. // this guy perhaps can go away, if we have a fract/high-precision way to
  327. // scale matrices
  328. bool SkMatrix::postIDiv(int divx, int divy) {
  329. if (divx == 0 || divy == 0) {
  330. return false;
  331. }
  332. const float invX = 1.f / divx;
  333. const float invY = 1.f / divy;
  334. fMat[kMScaleX] *= invX;
  335. fMat[kMSkewX] *= invX;
  336. fMat[kMTransX] *= invX;
  337. fMat[kMScaleY] *= invY;
  338. fMat[kMSkewY] *= invY;
  339. fMat[kMTransY] *= invY;
  340. this->setTypeMask(kUnknown_Mask);
  341. return true;
  342. }
  343. ////////////////////////////////////////////////////////////////////////////////////
  344. SkMatrix& SkMatrix::setSinCos(SkScalar sinV, SkScalar cosV, SkScalar px, SkScalar py) {
  345. const SkScalar oneMinusCosV = 1 - cosV;
  346. fMat[kMScaleX] = cosV;
  347. fMat[kMSkewX] = -sinV;
  348. fMat[kMTransX] = sdot(sinV, py, oneMinusCosV, px);
  349. fMat[kMSkewY] = sinV;
  350. fMat[kMScaleY] = cosV;
  351. fMat[kMTransY] = sdot(-sinV, px, oneMinusCosV, py);
  352. fMat[kMPersp0] = fMat[kMPersp1] = 0;
  353. fMat[kMPersp2] = 1;
  354. this->setTypeMask(kUnknown_Mask | kOnlyPerspectiveValid_Mask);
  355. return *this;
  356. }
  357. SkMatrix& SkMatrix::setRSXform(const SkRSXform& xform) {
  358. fMat[kMScaleX] = xform.fSCos;
  359. fMat[kMSkewX] = -xform.fSSin;
  360. fMat[kMTransX] = xform.fTx;
  361. fMat[kMSkewY] = xform.fSSin;
  362. fMat[kMScaleY] = xform.fSCos;
  363. fMat[kMTransY] = xform.fTy;
  364. fMat[kMPersp0] = fMat[kMPersp1] = 0;
  365. fMat[kMPersp2] = 1;
  366. this->setTypeMask(kUnknown_Mask | kOnlyPerspectiveValid_Mask);
  367. return *this;
  368. }
  369. SkMatrix& SkMatrix::setSinCos(SkScalar sinV, SkScalar cosV) {
  370. fMat[kMScaleX] = cosV;
  371. fMat[kMSkewX] = -sinV;
  372. fMat[kMTransX] = 0;
  373. fMat[kMSkewY] = sinV;
  374. fMat[kMScaleY] = cosV;
  375. fMat[kMTransY] = 0;
  376. fMat[kMPersp0] = fMat[kMPersp1] = 0;
  377. fMat[kMPersp2] = 1;
  378. this->setTypeMask(kUnknown_Mask | kOnlyPerspectiveValid_Mask);
  379. return *this;
  380. }
  381. SkMatrix& SkMatrix::setRotate(SkScalar degrees, SkScalar px, SkScalar py) {
  382. SkScalar rad = SkDegreesToRadians(degrees);
  383. return this->setSinCos(SkScalarSinSnapToZero(rad), SkScalarCosSnapToZero(rad), px, py);
  384. }
  385. SkMatrix& SkMatrix::setRotate(SkScalar degrees) {
  386. SkScalar rad = SkDegreesToRadians(degrees);
  387. return this->setSinCos(SkScalarSinSnapToZero(rad), SkScalarCosSnapToZero(rad));
  388. }
  389. SkMatrix& SkMatrix::preRotate(SkScalar degrees, SkScalar px, SkScalar py) {
  390. SkMatrix m;
  391. m.setRotate(degrees, px, py);
  392. return this->preConcat(m);
  393. }
  394. SkMatrix& SkMatrix::preRotate(SkScalar degrees) {
  395. SkMatrix m;
  396. m.setRotate(degrees);
  397. return this->preConcat(m);
  398. }
  399. SkMatrix& SkMatrix::postRotate(SkScalar degrees, SkScalar px, SkScalar py) {
  400. SkMatrix m;
  401. m.setRotate(degrees, px, py);
  402. return this->postConcat(m);
  403. }
  404. SkMatrix& SkMatrix::postRotate(SkScalar degrees) {
  405. SkMatrix m;
  406. m.setRotate(degrees);
  407. return this->postConcat(m);
  408. }
  409. ////////////////////////////////////////////////////////////////////////////////////
  410. SkMatrix& SkMatrix::setSkew(SkScalar sx, SkScalar sy, SkScalar px, SkScalar py) {
  411. *this = SkMatrix(1, sx, -sx * py,
  412. sy, 1, -sy * px,
  413. 0, 0, 1,
  414. kUnknown_Mask | kOnlyPerspectiveValid_Mask);
  415. return *this;
  416. }
  417. SkMatrix& SkMatrix::setSkew(SkScalar sx, SkScalar sy) {
  418. fMat[kMScaleX] = 1;
  419. fMat[kMSkewX] = sx;
  420. fMat[kMTransX] = 0;
  421. fMat[kMSkewY] = sy;
  422. fMat[kMScaleY] = 1;
  423. fMat[kMTransY] = 0;
  424. fMat[kMPersp0] = fMat[kMPersp1] = 0;
  425. fMat[kMPersp2] = 1;
  426. this->setTypeMask(kUnknown_Mask | kOnlyPerspectiveValid_Mask);
  427. return *this;
  428. }
  429. SkMatrix& SkMatrix::preSkew(SkScalar sx, SkScalar sy, SkScalar px, SkScalar py) {
  430. SkMatrix m;
  431. m.setSkew(sx, sy, px, py);
  432. return this->preConcat(m);
  433. }
  434. SkMatrix& SkMatrix::preSkew(SkScalar sx, SkScalar sy) {
  435. SkMatrix m;
  436. m.setSkew(sx, sy);
  437. return this->preConcat(m);
  438. }
  439. SkMatrix& SkMatrix::postSkew(SkScalar sx, SkScalar sy, SkScalar px, SkScalar py) {
  440. SkMatrix m;
  441. m.setSkew(sx, sy, px, py);
  442. return this->postConcat(m);
  443. }
  444. SkMatrix& SkMatrix::postSkew(SkScalar sx, SkScalar sy) {
  445. SkMatrix m;
  446. m.setSkew(sx, sy);
  447. return this->postConcat(m);
  448. }
  449. ///////////////////////////////////////////////////////////////////////////////
  450. bool SkMatrix::setRectToRect(const SkRect& src, const SkRect& dst, ScaleToFit align) {
  451. if (src.isEmpty()) {
  452. this->reset();
  453. return false;
  454. }
  455. if (dst.isEmpty()) {
  456. sk_bzero(fMat, 8 * sizeof(SkScalar));
  457. fMat[kMPersp2] = 1;
  458. this->setTypeMask(kScale_Mask | kRectStaysRect_Mask);
  459. } else {
  460. SkScalar tx, sx = dst.width() / src.width();
  461. SkScalar ty, sy = dst.height() / src.height();
  462. bool xLarger = false;
  463. if (align != kFill_ScaleToFit) {
  464. if (sx > sy) {
  465. xLarger = true;
  466. sx = sy;
  467. } else {
  468. sy = sx;
  469. }
  470. }
  471. tx = dst.fLeft - src.fLeft * sx;
  472. ty = dst.fTop - src.fTop * sy;
  473. if (align == kCenter_ScaleToFit || align == kEnd_ScaleToFit) {
  474. SkScalar diff;
  475. if (xLarger) {
  476. diff = dst.width() - src.width() * sy;
  477. } else {
  478. diff = dst.height() - src.height() * sy;
  479. }
  480. if (align == kCenter_ScaleToFit) {
  481. diff = SkScalarHalf(diff);
  482. }
  483. if (xLarger) {
  484. tx += diff;
  485. } else {
  486. ty += diff;
  487. }
  488. }
  489. this->setScaleTranslate(sx, sy, tx, ty);
  490. }
  491. return true;
  492. }
  493. ///////////////////////////////////////////////////////////////////////////////
  494. static inline float muladdmul(float a, float b, float c, float d) {
  495. return sk_double_to_float((double)a * b + (double)c * d);
  496. }
  497. static inline float rowcol3(const float row[], const float col[]) {
  498. return row[0] * col[0] + row[1] * col[3] + row[2] * col[6];
  499. }
  500. static bool only_scale_and_translate(unsigned mask) {
  501. return 0 == (mask & (SkMatrix::kAffine_Mask | SkMatrix::kPerspective_Mask));
  502. }
  503. SkMatrix& SkMatrix::setConcat(const SkMatrix& a, const SkMatrix& b) {
  504. TypeMask aType = a.getType();
  505. TypeMask bType = b.getType();
  506. if (a.isTriviallyIdentity()) {
  507. *this = b;
  508. } else if (b.isTriviallyIdentity()) {
  509. *this = a;
  510. } else if (only_scale_and_translate(aType | bType)) {
  511. this->setScaleTranslate(a.fMat[kMScaleX] * b.fMat[kMScaleX],
  512. a.fMat[kMScaleY] * b.fMat[kMScaleY],
  513. a.fMat[kMScaleX] * b.fMat[kMTransX] + a.fMat[kMTransX],
  514. a.fMat[kMScaleY] * b.fMat[kMTransY] + a.fMat[kMTransY]);
  515. } else {
  516. SkMatrix tmp;
  517. if ((aType | bType) & kPerspective_Mask) {
  518. tmp.fMat[kMScaleX] = rowcol3(&a.fMat[0], &b.fMat[0]);
  519. tmp.fMat[kMSkewX] = rowcol3(&a.fMat[0], &b.fMat[1]);
  520. tmp.fMat[kMTransX] = rowcol3(&a.fMat[0], &b.fMat[2]);
  521. tmp.fMat[kMSkewY] = rowcol3(&a.fMat[3], &b.fMat[0]);
  522. tmp.fMat[kMScaleY] = rowcol3(&a.fMat[3], &b.fMat[1]);
  523. tmp.fMat[kMTransY] = rowcol3(&a.fMat[3], &b.fMat[2]);
  524. tmp.fMat[kMPersp0] = rowcol3(&a.fMat[6], &b.fMat[0]);
  525. tmp.fMat[kMPersp1] = rowcol3(&a.fMat[6], &b.fMat[1]);
  526. tmp.fMat[kMPersp2] = rowcol3(&a.fMat[6], &b.fMat[2]);
  527. normalize_perspective(tmp.fMat);
  528. tmp.setTypeMask(kUnknown_Mask);
  529. } else {
  530. tmp.fMat[kMScaleX] = muladdmul(a.fMat[kMScaleX],
  531. b.fMat[kMScaleX],
  532. a.fMat[kMSkewX],
  533. b.fMat[kMSkewY]);
  534. tmp.fMat[kMSkewX] = muladdmul(a.fMat[kMScaleX],
  535. b.fMat[kMSkewX],
  536. a.fMat[kMSkewX],
  537. b.fMat[kMScaleY]);
  538. tmp.fMat[kMTransX] = muladdmul(a.fMat[kMScaleX],
  539. b.fMat[kMTransX],
  540. a.fMat[kMSkewX],
  541. b.fMat[kMTransY]) + a.fMat[kMTransX];
  542. tmp.fMat[kMSkewY] = muladdmul(a.fMat[kMSkewY],
  543. b.fMat[kMScaleX],
  544. a.fMat[kMScaleY],
  545. b.fMat[kMSkewY]);
  546. tmp.fMat[kMScaleY] = muladdmul(a.fMat[kMSkewY],
  547. b.fMat[kMSkewX],
  548. a.fMat[kMScaleY],
  549. b.fMat[kMScaleY]);
  550. tmp.fMat[kMTransY] = muladdmul(a.fMat[kMSkewY],
  551. b.fMat[kMTransX],
  552. a.fMat[kMScaleY],
  553. b.fMat[kMTransY]) + a.fMat[kMTransY];
  554. tmp.fMat[kMPersp0] = 0;
  555. tmp.fMat[kMPersp1] = 0;
  556. tmp.fMat[kMPersp2] = 1;
  557. //SkDebugf("Concat mat non-persp type: %d\n", tmp.getType());
  558. //SkASSERT(!(tmp.getType() & kPerspective_Mask));
  559. tmp.setTypeMask(kUnknown_Mask | kOnlyPerspectiveValid_Mask);
  560. }
  561. *this = tmp;
  562. }
  563. return *this;
  564. }
  565. SkMatrix& SkMatrix::preConcat(const SkMatrix& mat) {
  566. // check for identity first, so we don't do a needless copy of ourselves
  567. // to ourselves inside setConcat()
  568. if(!mat.isIdentity()) {
  569. this->setConcat(*this, mat);
  570. }
  571. return *this;
  572. }
  573. SkMatrix& SkMatrix::postConcat(const SkMatrix& mat) {
  574. // check for identity first, so we don't do a needless copy of ourselves
  575. // to ourselves inside setConcat()
  576. if (!mat.isIdentity()) {
  577. this->setConcat(mat, *this);
  578. }
  579. return *this;
  580. }
  581. ///////////////////////////////////////////////////////////////////////////////
  582. /* Matrix inversion is very expensive, but also the place where keeping
  583. precision may be most important (here and matrix concat). Hence to avoid
  584. bitmap blitting artifacts when walking the inverse, we use doubles for
  585. the intermediate math, even though we know that is more expensive.
  586. */
  587. static inline SkScalar scross_dscale(SkScalar a, SkScalar b,
  588. SkScalar c, SkScalar d, double scale) {
  589. return SkDoubleToScalar(scross(a, b, c, d) * scale);
  590. }
  591. static inline double dcross(double a, double b, double c, double d) {
  592. return a * b - c * d;
  593. }
  594. static inline SkScalar dcross_dscale(double a, double b,
  595. double c, double d, double scale) {
  596. return SkDoubleToScalar(dcross(a, b, c, d) * scale);
  597. }
  598. static double sk_inv_determinant(const float mat[9], int isPerspective) {
  599. double det;
  600. if (isPerspective) {
  601. det = mat[SkMatrix::kMScaleX] *
  602. dcross(mat[SkMatrix::kMScaleY], mat[SkMatrix::kMPersp2],
  603. mat[SkMatrix::kMTransY], mat[SkMatrix::kMPersp1])
  604. +
  605. mat[SkMatrix::kMSkewX] *
  606. dcross(mat[SkMatrix::kMTransY], mat[SkMatrix::kMPersp0],
  607. mat[SkMatrix::kMSkewY], mat[SkMatrix::kMPersp2])
  608. +
  609. mat[SkMatrix::kMTransX] *
  610. dcross(mat[SkMatrix::kMSkewY], mat[SkMatrix::kMPersp1],
  611. mat[SkMatrix::kMScaleY], mat[SkMatrix::kMPersp0]);
  612. } else {
  613. det = dcross(mat[SkMatrix::kMScaleX], mat[SkMatrix::kMScaleY],
  614. mat[SkMatrix::kMSkewX], mat[SkMatrix::kMSkewY]);
  615. }
  616. // Since the determinant is on the order of the cube of the matrix members,
  617. // compare to the cube of the default nearly-zero constant (although an
  618. // estimate of the condition number would be better if it wasn't so expensive).
  619. if (SkScalarNearlyZero(sk_double_to_float(det),
  620. SK_ScalarNearlyZero * SK_ScalarNearlyZero * SK_ScalarNearlyZero)) {
  621. return 0;
  622. }
  623. return 1.0 / det;
  624. }
  625. void SkMatrix::SetAffineIdentity(SkScalar affine[6]) {
  626. affine[kAScaleX] = 1;
  627. affine[kASkewY] = 0;
  628. affine[kASkewX] = 0;
  629. affine[kAScaleY] = 1;
  630. affine[kATransX] = 0;
  631. affine[kATransY] = 0;
  632. }
  633. bool SkMatrix::asAffine(SkScalar affine[6]) const {
  634. if (this->hasPerspective()) {
  635. return false;
  636. }
  637. if (affine) {
  638. affine[kAScaleX] = this->fMat[kMScaleX];
  639. affine[kASkewY] = this->fMat[kMSkewY];
  640. affine[kASkewX] = this->fMat[kMSkewX];
  641. affine[kAScaleY] = this->fMat[kMScaleY];
  642. affine[kATransX] = this->fMat[kMTransX];
  643. affine[kATransY] = this->fMat[kMTransY];
  644. }
  645. return true;
  646. }
  647. void SkMatrix::mapPoints(SkPoint dst[], const SkPoint src[], int count) const {
  648. SkASSERT((dst && src && count > 0) || 0 == count);
  649. // no partial overlap
  650. SkASSERT(src == dst || &dst[count] <= &src[0] || &src[count] <= &dst[0]);
  651. this->getMapPtsProc()(*this, dst, src, count);
  652. }
  653. void SkMatrix::mapXY(SkScalar x, SkScalar y, SkPoint* result) const {
  654. SkASSERT(result);
  655. this->getMapXYProc()(*this, x, y, result);
  656. }
  657. void SkMatrix::ComputeInv(SkScalar dst[9], const SkScalar src[9], double invDet, bool isPersp) {
  658. SkASSERT(src != dst);
  659. SkASSERT(src && dst);
  660. if (isPersp) {
  661. dst[kMScaleX] = scross_dscale(src[kMScaleY], src[kMPersp2], src[kMTransY], src[kMPersp1], invDet);
  662. dst[kMSkewX] = scross_dscale(src[kMTransX], src[kMPersp1], src[kMSkewX], src[kMPersp2], invDet);
  663. dst[kMTransX] = scross_dscale(src[kMSkewX], src[kMTransY], src[kMTransX], src[kMScaleY], invDet);
  664. dst[kMSkewY] = scross_dscale(src[kMTransY], src[kMPersp0], src[kMSkewY], src[kMPersp2], invDet);
  665. dst[kMScaleY] = scross_dscale(src[kMScaleX], src[kMPersp2], src[kMTransX], src[kMPersp0], invDet);
  666. dst[kMTransY] = scross_dscale(src[kMTransX], src[kMSkewY], src[kMScaleX], src[kMTransY], invDet);
  667. dst[kMPersp0] = scross_dscale(src[kMSkewY], src[kMPersp1], src[kMScaleY], src[kMPersp0], invDet);
  668. dst[kMPersp1] = scross_dscale(src[kMSkewX], src[kMPersp0], src[kMScaleX], src[kMPersp1], invDet);
  669. dst[kMPersp2] = scross_dscale(src[kMScaleX], src[kMScaleY], src[kMSkewX], src[kMSkewY], invDet);
  670. } else { // not perspective
  671. dst[kMScaleX] = SkDoubleToScalar(src[kMScaleY] * invDet);
  672. dst[kMSkewX] = SkDoubleToScalar(-src[kMSkewX] * invDet);
  673. dst[kMTransX] = dcross_dscale(src[kMSkewX], src[kMTransY], src[kMScaleY], src[kMTransX], invDet);
  674. dst[kMSkewY] = SkDoubleToScalar(-src[kMSkewY] * invDet);
  675. dst[kMScaleY] = SkDoubleToScalar(src[kMScaleX] * invDet);
  676. dst[kMTransY] = dcross_dscale(src[kMSkewY], src[kMTransX], src[kMScaleX], src[kMTransY], invDet);
  677. dst[kMPersp0] = 0;
  678. dst[kMPersp1] = 0;
  679. dst[kMPersp2] = 1;
  680. }
  681. }
  682. bool SkMatrix::invertNonIdentity(SkMatrix* inv) const {
  683. SkASSERT(!this->isIdentity());
  684. TypeMask mask = this->getType();
  685. if (0 == (mask & ~(kScale_Mask | kTranslate_Mask))) {
  686. bool invertible = true;
  687. if (inv) {
  688. if (mask & kScale_Mask) {
  689. SkScalar invX = fMat[kMScaleX];
  690. SkScalar invY = fMat[kMScaleY];
  691. if (0 == invX || 0 == invY) {
  692. return false;
  693. }
  694. invX = SkScalarInvert(invX);
  695. invY = SkScalarInvert(invY);
  696. // Must be careful when writing to inv, since it may be the
  697. // same memory as this.
  698. inv->fMat[kMSkewX] = inv->fMat[kMSkewY] =
  699. inv->fMat[kMPersp0] = inv->fMat[kMPersp1] = 0;
  700. inv->fMat[kMScaleX] = invX;
  701. inv->fMat[kMScaleY] = invY;
  702. inv->fMat[kMPersp2] = 1;
  703. inv->fMat[kMTransX] = -fMat[kMTransX] * invX;
  704. inv->fMat[kMTransY] = -fMat[kMTransY] * invY;
  705. inv->setTypeMask(mask | kRectStaysRect_Mask);
  706. } else {
  707. // translate only
  708. inv->setTranslate(-fMat[kMTransX], -fMat[kMTransY]);
  709. }
  710. } else { // inv is nullptr, just check if we're invertible
  711. if (!fMat[kMScaleX] || !fMat[kMScaleY]) {
  712. invertible = false;
  713. }
  714. }
  715. return invertible;
  716. }
  717. int isPersp = mask & kPerspective_Mask;
  718. double invDet = sk_inv_determinant(fMat, isPersp);
  719. if (invDet == 0) { // underflow
  720. return false;
  721. }
  722. bool applyingInPlace = (inv == this);
  723. SkMatrix* tmp = inv;
  724. SkMatrix storage;
  725. if (applyingInPlace || nullptr == tmp) {
  726. tmp = &storage; // we either need to avoid trampling memory or have no memory
  727. }
  728. ComputeInv(tmp->fMat, fMat, invDet, isPersp);
  729. if (!tmp->isFinite()) {
  730. return false;
  731. }
  732. tmp->setTypeMask(fTypeMask);
  733. if (applyingInPlace) {
  734. *inv = storage; // need to copy answer back
  735. }
  736. return true;
  737. }
  738. ///////////////////////////////////////////////////////////////////////////////
  739. void SkMatrix::Identity_pts(const SkMatrix& m, SkPoint dst[], const SkPoint src[], int count) {
  740. SkASSERT(m.getType() == 0);
  741. if (dst != src && count > 0) {
  742. memcpy(dst, src, count * sizeof(SkPoint));
  743. }
  744. }
  745. void SkMatrix::Trans_pts(const SkMatrix& m, SkPoint dst[], const SkPoint src[], int count) {
  746. SkASSERT(m.getType() <= SkMatrix::kTranslate_Mask);
  747. if (count > 0) {
  748. SkScalar tx = m.getTranslateX();
  749. SkScalar ty = m.getTranslateY();
  750. if (count & 1) {
  751. dst->fX = src->fX + tx;
  752. dst->fY = src->fY + ty;
  753. src += 1;
  754. dst += 1;
  755. }
  756. Sk4s trans4(tx, ty, tx, ty);
  757. count >>= 1;
  758. if (count & 1) {
  759. (Sk4s::Load(src) + trans4).store(dst);
  760. src += 2;
  761. dst += 2;
  762. }
  763. count >>= 1;
  764. for (int i = 0; i < count; ++i) {
  765. (Sk4s::Load(src+0) + trans4).store(dst+0);
  766. (Sk4s::Load(src+2) + trans4).store(dst+2);
  767. src += 4;
  768. dst += 4;
  769. }
  770. }
  771. }
  772. void SkMatrix::Scale_pts(const SkMatrix& m, SkPoint dst[], const SkPoint src[], int count) {
  773. SkASSERT(m.getType() <= (SkMatrix::kScale_Mask | SkMatrix::kTranslate_Mask));
  774. if (count > 0) {
  775. SkScalar tx = m.getTranslateX();
  776. SkScalar ty = m.getTranslateY();
  777. SkScalar sx = m.getScaleX();
  778. SkScalar sy = m.getScaleY();
  779. if (count & 1) {
  780. dst->fX = src->fX * sx + tx;
  781. dst->fY = src->fY * sy + ty;
  782. src += 1;
  783. dst += 1;
  784. }
  785. Sk4s trans4(tx, ty, tx, ty);
  786. Sk4s scale4(sx, sy, sx, sy);
  787. count >>= 1;
  788. if (count & 1) {
  789. (Sk4s::Load(src) * scale4 + trans4).store(dst);
  790. src += 2;
  791. dst += 2;
  792. }
  793. count >>= 1;
  794. for (int i = 0; i < count; ++i) {
  795. (Sk4s::Load(src+0) * scale4 + trans4).store(dst+0);
  796. (Sk4s::Load(src+2) * scale4 + trans4).store(dst+2);
  797. src += 4;
  798. dst += 4;
  799. }
  800. }
  801. }
  802. void SkMatrix::Persp_pts(const SkMatrix& m, SkPoint dst[],
  803. const SkPoint src[], int count) {
  804. SkASSERT(m.hasPerspective());
  805. if (count > 0) {
  806. do {
  807. SkScalar sy = src->fY;
  808. SkScalar sx = src->fX;
  809. src += 1;
  810. SkScalar x = sdot(sx, m.fMat[kMScaleX], sy, m.fMat[kMSkewX]) + m.fMat[kMTransX];
  811. SkScalar y = sdot(sx, m.fMat[kMSkewY], sy, m.fMat[kMScaleY]) + m.fMat[kMTransY];
  812. #ifdef SK_LEGACY_MATRIX_MATH_ORDER
  813. SkScalar z = sx * m.fMat[kMPersp0] + (sy * m.fMat[kMPersp1] + m.fMat[kMPersp2]);
  814. #else
  815. SkScalar z = sdot(sx, m.fMat[kMPersp0], sy, m.fMat[kMPersp1]) + m.fMat[kMPersp2];
  816. #endif
  817. if (z) {
  818. z = 1 / z;
  819. }
  820. dst->fY = y * z;
  821. dst->fX = x * z;
  822. dst += 1;
  823. } while (--count);
  824. }
  825. }
  826. void SkMatrix::Affine_vpts(const SkMatrix& m, SkPoint dst[], const SkPoint src[], int count) {
  827. SkASSERT(m.getType() != SkMatrix::kPerspective_Mask);
  828. if (count > 0) {
  829. SkScalar tx = m.getTranslateX();
  830. SkScalar ty = m.getTranslateY();
  831. SkScalar sx = m.getScaleX();
  832. SkScalar sy = m.getScaleY();
  833. SkScalar kx = m.getSkewX();
  834. SkScalar ky = m.getSkewY();
  835. if (count & 1) {
  836. dst->set(src->fX * sx + src->fY * kx + tx,
  837. src->fX * ky + src->fY * sy + ty);
  838. src += 1;
  839. dst += 1;
  840. }
  841. Sk4s trans4(tx, ty, tx, ty);
  842. Sk4s scale4(sx, sy, sx, sy);
  843. Sk4s skew4(kx, ky, kx, ky); // applied to swizzle of src4
  844. count >>= 1;
  845. for (int i = 0; i < count; ++i) {
  846. Sk4s src4 = Sk4s::Load(src);
  847. Sk4s swz4 = SkNx_shuffle<1,0,3,2>(src4); // y0 x0, y1 x1
  848. (src4 * scale4 + swz4 * skew4 + trans4).store(dst);
  849. src += 2;
  850. dst += 2;
  851. }
  852. }
  853. }
  854. const SkMatrix::MapPtsProc SkMatrix::gMapPtsProcs[] = {
  855. SkMatrix::Identity_pts, SkMatrix::Trans_pts,
  856. SkMatrix::Scale_pts, SkMatrix::Scale_pts,
  857. SkMatrix::Affine_vpts, SkMatrix::Affine_vpts,
  858. SkMatrix::Affine_vpts, SkMatrix::Affine_vpts,
  859. // repeat the persp proc 8 times
  860. SkMatrix::Persp_pts, SkMatrix::Persp_pts,
  861. SkMatrix::Persp_pts, SkMatrix::Persp_pts,
  862. SkMatrix::Persp_pts, SkMatrix::Persp_pts,
  863. SkMatrix::Persp_pts, SkMatrix::Persp_pts
  864. };
  865. ///////////////////////////////////////////////////////////////////////////////
  866. void SkMatrixPriv::MapHomogeneousPointsWithStride(const SkMatrix& mx, SkPoint3 dst[],
  867. size_t dstStride, const SkPoint3 src[],
  868. size_t srcStride, int count) {
  869. SkASSERT((dst && src && count > 0) || 0 == count);
  870. // no partial overlap
  871. SkASSERT(src == dst || &dst[count] <= &src[0] || &src[count] <= &dst[0]);
  872. if (count > 0) {
  873. if (mx.isIdentity()) {
  874. if (src != dst) {
  875. if (srcStride == sizeof(SkPoint3) && dstStride == sizeof(SkPoint3)) {
  876. memcpy(dst, src, count * sizeof(SkPoint3));
  877. } else {
  878. for (int i = 0; i < count; ++i) {
  879. *dst = *src;
  880. dst = reinterpret_cast<SkPoint3*>(reinterpret_cast<char*>(dst) + dstStride);
  881. src = reinterpret_cast<const SkPoint3*>(reinterpret_cast<const char*>(src) +
  882. srcStride);
  883. }
  884. }
  885. }
  886. return;
  887. }
  888. do {
  889. SkScalar sx = src->fX;
  890. SkScalar sy = src->fY;
  891. SkScalar sw = src->fZ;
  892. src = reinterpret_cast<const SkPoint3*>(reinterpret_cast<const char*>(src) + srcStride);
  893. const SkScalar* mat = mx.fMat;
  894. typedef SkMatrix M;
  895. SkScalar x = sdot(sx, mat[M::kMScaleX], sy, mat[M::kMSkewX], sw, mat[M::kMTransX]);
  896. SkScalar y = sdot(sx, mat[M::kMSkewY], sy, mat[M::kMScaleY], sw, mat[M::kMTransY]);
  897. SkScalar w = sdot(sx, mat[M::kMPersp0], sy, mat[M::kMPersp1], sw, mat[M::kMPersp2]);
  898. dst->set(x, y, w);
  899. dst = reinterpret_cast<SkPoint3*>(reinterpret_cast<char*>(dst) + dstStride);
  900. } while (--count);
  901. }
  902. }
  903. void SkMatrix::mapHomogeneousPoints(SkPoint3 dst[], const SkPoint3 src[], int count) const {
  904. SkMatrixPriv::MapHomogeneousPointsWithStride(*this, dst, sizeof(SkPoint3), src,
  905. sizeof(SkPoint3), count);
  906. }
  907. ///////////////////////////////////////////////////////////////////////////////
  908. void SkMatrix::mapVectors(SkPoint dst[], const SkPoint src[], int count) const {
  909. if (this->hasPerspective()) {
  910. SkPoint origin;
  911. MapXYProc proc = this->getMapXYProc();
  912. proc(*this, 0, 0, &origin);
  913. for (int i = count - 1; i >= 0; --i) {
  914. SkPoint tmp;
  915. proc(*this, src[i].fX, src[i].fY, &tmp);
  916. dst[i].set(tmp.fX - origin.fX, tmp.fY - origin.fY);
  917. }
  918. } else {
  919. SkMatrix tmp = *this;
  920. tmp.fMat[kMTransX] = tmp.fMat[kMTransY] = 0;
  921. tmp.clearTypeMask(kTranslate_Mask);
  922. tmp.mapPoints(dst, src, count);
  923. }
  924. }
  925. static Sk4f sort_as_rect(const Sk4f& ltrb) {
  926. Sk4f rblt(ltrb[2], ltrb[3], ltrb[0], ltrb[1]);
  927. Sk4f min = Sk4f::Min(ltrb, rblt);
  928. Sk4f max = Sk4f::Max(ltrb, rblt);
  929. // We can extract either pair [0,1] or [2,3] from min and max and be correct, but on
  930. // ARM this sequence generates the fastest (a single instruction).
  931. return Sk4f(min[2], min[3], max[0], max[1]);
  932. }
  933. void SkMatrix::mapRectScaleTranslate(SkRect* dst, const SkRect& src) const {
  934. SkASSERT(dst);
  935. SkASSERT(this->isScaleTranslate());
  936. SkScalar sx = fMat[kMScaleX];
  937. SkScalar sy = fMat[kMScaleY];
  938. SkScalar tx = fMat[kMTransX];
  939. SkScalar ty = fMat[kMTransY];
  940. Sk4f scale(sx, sy, sx, sy);
  941. Sk4f trans(tx, ty, tx, ty);
  942. sort_as_rect(Sk4f::Load(&src.fLeft) * scale + trans).store(&dst->fLeft);
  943. }
  944. bool SkMatrix::mapRect(SkRect* dst, const SkRect& src) const {
  945. SkASSERT(dst);
  946. if (this->getType() <= kTranslate_Mask) {
  947. SkScalar tx = fMat[kMTransX];
  948. SkScalar ty = fMat[kMTransY];
  949. Sk4f trans(tx, ty, tx, ty);
  950. sort_as_rect(Sk4f::Load(&src.fLeft) + trans).store(&dst->fLeft);
  951. return true;
  952. }
  953. if (this->isScaleTranslate()) {
  954. this->mapRectScaleTranslate(dst, src);
  955. return true;
  956. } else {
  957. SkPoint quad[4];
  958. src.toQuad(quad);
  959. this->mapPoints(quad, quad, 4);
  960. dst->setBoundsNoCheck(quad, 4);
  961. return this->rectStaysRect(); // might still return true if rotated by 90, etc.
  962. }
  963. }
  964. SkScalar SkMatrix::mapRadius(SkScalar radius) const {
  965. SkVector vec[2];
  966. vec[0].set(radius, 0);
  967. vec[1].set(0, radius);
  968. this->mapVectors(vec, 2);
  969. SkScalar d0 = vec[0].length();
  970. SkScalar d1 = vec[1].length();
  971. // return geometric mean
  972. return SkScalarSqrt(d0 * d1);
  973. }
  974. ///////////////////////////////////////////////////////////////////////////////
  975. void SkMatrix::Persp_xy(const SkMatrix& m, SkScalar sx, SkScalar sy,
  976. SkPoint* pt) {
  977. SkASSERT(m.hasPerspective());
  978. SkScalar x = sdot(sx, m.fMat[kMScaleX], sy, m.fMat[kMSkewX]) + m.fMat[kMTransX];
  979. SkScalar y = sdot(sx, m.fMat[kMSkewY], sy, m.fMat[kMScaleY]) + m.fMat[kMTransY];
  980. SkScalar z = sdot(sx, m.fMat[kMPersp0], sy, m.fMat[kMPersp1]) + m.fMat[kMPersp2];
  981. if (z) {
  982. z = 1 / z;
  983. }
  984. pt->fX = x * z;
  985. pt->fY = y * z;
  986. }
  987. void SkMatrix::RotTrans_xy(const SkMatrix& m, SkScalar sx, SkScalar sy,
  988. SkPoint* pt) {
  989. SkASSERT((m.getType() & (kAffine_Mask | kPerspective_Mask)) == kAffine_Mask);
  990. #ifdef SK_LEGACY_MATRIX_MATH_ORDER
  991. pt->fX = sx * m.fMat[kMScaleX] + (sy * m.fMat[kMSkewX] + m.fMat[kMTransX]);
  992. pt->fY = sx * m.fMat[kMSkewY] + (sy * m.fMat[kMScaleY] + m.fMat[kMTransY]);
  993. #else
  994. pt->fX = sdot(sx, m.fMat[kMScaleX], sy, m.fMat[kMSkewX]) + m.fMat[kMTransX];
  995. pt->fY = sdot(sx, m.fMat[kMSkewY], sy, m.fMat[kMScaleY]) + m.fMat[kMTransY];
  996. #endif
  997. }
  998. void SkMatrix::Rot_xy(const SkMatrix& m, SkScalar sx, SkScalar sy,
  999. SkPoint* pt) {
  1000. SkASSERT((m.getType() & (kAffine_Mask | kPerspective_Mask))== kAffine_Mask);
  1001. SkASSERT(0 == m.fMat[kMTransX]);
  1002. SkASSERT(0 == m.fMat[kMTransY]);
  1003. #ifdef SK_LEGACY_MATRIX_MATH_ORDER
  1004. pt->fX = sx * m.fMat[kMScaleX] + (sy * m.fMat[kMSkewX] + m.fMat[kMTransX]);
  1005. pt->fY = sx * m.fMat[kMSkewY] + (sy * m.fMat[kMScaleY] + m.fMat[kMTransY]);
  1006. #else
  1007. pt->fX = sdot(sx, m.fMat[kMScaleX], sy, m.fMat[kMSkewX]) + m.fMat[kMTransX];
  1008. pt->fY = sdot(sx, m.fMat[kMSkewY], sy, m.fMat[kMScaleY]) + m.fMat[kMTransY];
  1009. #endif
  1010. }
  1011. void SkMatrix::ScaleTrans_xy(const SkMatrix& m, SkScalar sx, SkScalar sy,
  1012. SkPoint* pt) {
  1013. SkASSERT((m.getType() & (kScale_Mask | kAffine_Mask | kPerspective_Mask))
  1014. == kScale_Mask);
  1015. pt->fX = sx * m.fMat[kMScaleX] + m.fMat[kMTransX];
  1016. pt->fY = sy * m.fMat[kMScaleY] + m.fMat[kMTransY];
  1017. }
  1018. void SkMatrix::Scale_xy(const SkMatrix& m, SkScalar sx, SkScalar sy,
  1019. SkPoint* pt) {
  1020. SkASSERT((m.getType() & (kScale_Mask | kAffine_Mask | kPerspective_Mask))
  1021. == kScale_Mask);
  1022. SkASSERT(0 == m.fMat[kMTransX]);
  1023. SkASSERT(0 == m.fMat[kMTransY]);
  1024. pt->fX = sx * m.fMat[kMScaleX];
  1025. pt->fY = sy * m.fMat[kMScaleY];
  1026. }
  1027. void SkMatrix::Trans_xy(const SkMatrix& m, SkScalar sx, SkScalar sy,
  1028. SkPoint* pt) {
  1029. SkASSERT(m.getType() == kTranslate_Mask);
  1030. pt->fX = sx + m.fMat[kMTransX];
  1031. pt->fY = sy + m.fMat[kMTransY];
  1032. }
  1033. void SkMatrix::Identity_xy(const SkMatrix& m, SkScalar sx, SkScalar sy,
  1034. SkPoint* pt) {
  1035. SkASSERT(0 == m.getType());
  1036. pt->fX = sx;
  1037. pt->fY = sy;
  1038. }
  1039. const SkMatrix::MapXYProc SkMatrix::gMapXYProcs[] = {
  1040. SkMatrix::Identity_xy, SkMatrix::Trans_xy,
  1041. SkMatrix::Scale_xy, SkMatrix::ScaleTrans_xy,
  1042. SkMatrix::Rot_xy, SkMatrix::RotTrans_xy,
  1043. SkMatrix::Rot_xy, SkMatrix::RotTrans_xy,
  1044. // repeat the persp proc 8 times
  1045. SkMatrix::Persp_xy, SkMatrix::Persp_xy,
  1046. SkMatrix::Persp_xy, SkMatrix::Persp_xy,
  1047. SkMatrix::Persp_xy, SkMatrix::Persp_xy,
  1048. SkMatrix::Persp_xy, SkMatrix::Persp_xy
  1049. };
  1050. ///////////////////////////////////////////////////////////////////////////////
  1051. // if its nearly zero (just made up 26, perhaps it should be bigger or smaller)
  1052. #define PerspNearlyZero(x) SkScalarNearlyZero(x, (1.0f / (1 << 26)))
  1053. bool SkMatrix::isFixedStepInX() const {
  1054. return PerspNearlyZero(fMat[kMPersp0]);
  1055. }
  1056. SkVector SkMatrix::fixedStepInX(SkScalar y) const {
  1057. SkASSERT(PerspNearlyZero(fMat[kMPersp0]));
  1058. if (PerspNearlyZero(fMat[kMPersp1]) &&
  1059. PerspNearlyZero(fMat[kMPersp2] - 1)) {
  1060. return SkVector::Make(fMat[kMScaleX], fMat[kMSkewY]);
  1061. } else {
  1062. SkScalar z = y * fMat[kMPersp1] + fMat[kMPersp2];
  1063. return SkVector::Make(fMat[kMScaleX] / z, fMat[kMSkewY] / z);
  1064. }
  1065. }
  1066. ///////////////////////////////////////////////////////////////////////////////
  1067. static inline bool checkForZero(float x) {
  1068. return x*x == 0;
  1069. }
  1070. bool SkMatrix::Poly2Proc(const SkPoint srcPt[], SkMatrix* dst) {
  1071. dst->fMat[kMScaleX] = srcPt[1].fY - srcPt[0].fY;
  1072. dst->fMat[kMSkewY] = srcPt[0].fX - srcPt[1].fX;
  1073. dst->fMat[kMPersp0] = 0;
  1074. dst->fMat[kMSkewX] = srcPt[1].fX - srcPt[0].fX;
  1075. dst->fMat[kMScaleY] = srcPt[1].fY - srcPt[0].fY;
  1076. dst->fMat[kMPersp1] = 0;
  1077. dst->fMat[kMTransX] = srcPt[0].fX;
  1078. dst->fMat[kMTransY] = srcPt[0].fY;
  1079. dst->fMat[kMPersp2] = 1;
  1080. dst->setTypeMask(kUnknown_Mask);
  1081. return true;
  1082. }
  1083. bool SkMatrix::Poly3Proc(const SkPoint srcPt[], SkMatrix* dst) {
  1084. dst->fMat[kMScaleX] = srcPt[2].fX - srcPt[0].fX;
  1085. dst->fMat[kMSkewY] = srcPt[2].fY - srcPt[0].fY;
  1086. dst->fMat[kMPersp0] = 0;
  1087. dst->fMat[kMSkewX] = srcPt[1].fX - srcPt[0].fX;
  1088. dst->fMat[kMScaleY] = srcPt[1].fY - srcPt[0].fY;
  1089. dst->fMat[kMPersp1] = 0;
  1090. dst->fMat[kMTransX] = srcPt[0].fX;
  1091. dst->fMat[kMTransY] = srcPt[0].fY;
  1092. dst->fMat[kMPersp2] = 1;
  1093. dst->setTypeMask(kUnknown_Mask);
  1094. return true;
  1095. }
  1096. bool SkMatrix::Poly4Proc(const SkPoint srcPt[], SkMatrix* dst) {
  1097. float a1, a2;
  1098. float x0, y0, x1, y1, x2, y2;
  1099. x0 = srcPt[2].fX - srcPt[0].fX;
  1100. y0 = srcPt[2].fY - srcPt[0].fY;
  1101. x1 = srcPt[2].fX - srcPt[1].fX;
  1102. y1 = srcPt[2].fY - srcPt[1].fY;
  1103. x2 = srcPt[2].fX - srcPt[3].fX;
  1104. y2 = srcPt[2].fY - srcPt[3].fY;
  1105. /* check if abs(x2) > abs(y2) */
  1106. if ( x2 > 0 ? y2 > 0 ? x2 > y2 : x2 > -y2 : y2 > 0 ? -x2 > y2 : x2 < y2) {
  1107. float denom = sk_ieee_float_divide(x1 * y2, x2) - y1;
  1108. if (checkForZero(denom)) {
  1109. return false;
  1110. }
  1111. a1 = (((x0 - x1) * y2 / x2) - y0 + y1) / denom;
  1112. } else {
  1113. float denom = x1 - sk_ieee_float_divide(y1 * x2, y2);
  1114. if (checkForZero(denom)) {
  1115. return false;
  1116. }
  1117. a1 = (x0 - x1 - sk_ieee_float_divide((y0 - y1) * x2, y2)) / denom;
  1118. }
  1119. /* check if abs(x1) > abs(y1) */
  1120. if ( x1 > 0 ? y1 > 0 ? x1 > y1 : x1 > -y1 : y1 > 0 ? -x1 > y1 : x1 < y1) {
  1121. float denom = y2 - sk_ieee_float_divide(x2 * y1, x1);
  1122. if (checkForZero(denom)) {
  1123. return false;
  1124. }
  1125. a2 = (y0 - y2 - sk_ieee_float_divide((x0 - x2) * y1, x1)) / denom;
  1126. } else {
  1127. float denom = sk_ieee_float_divide(y2 * x1, y1) - x2;
  1128. if (checkForZero(denom)) {
  1129. return false;
  1130. }
  1131. a2 = (sk_ieee_float_divide((y0 - y2) * x1, y1) - x0 + x2) / denom;
  1132. }
  1133. dst->fMat[kMScaleX] = a2 * srcPt[3].fX + srcPt[3].fX - srcPt[0].fX;
  1134. dst->fMat[kMSkewY] = a2 * srcPt[3].fY + srcPt[3].fY - srcPt[0].fY;
  1135. dst->fMat[kMPersp0] = a2;
  1136. dst->fMat[kMSkewX] = a1 * srcPt[1].fX + srcPt[1].fX - srcPt[0].fX;
  1137. dst->fMat[kMScaleY] = a1 * srcPt[1].fY + srcPt[1].fY - srcPt[0].fY;
  1138. dst->fMat[kMPersp1] = a1;
  1139. dst->fMat[kMTransX] = srcPt[0].fX;
  1140. dst->fMat[kMTransY] = srcPt[0].fY;
  1141. dst->fMat[kMPersp2] = 1;
  1142. dst->setTypeMask(kUnknown_Mask);
  1143. return true;
  1144. }
  1145. typedef bool (*PolyMapProc)(const SkPoint[], SkMatrix*);
  1146. /* Adapted from Rob Johnson's original sample code in QuickDraw GX
  1147. */
  1148. bool SkMatrix::setPolyToPoly(const SkPoint src[], const SkPoint dst[], int count) {
  1149. if ((unsigned)count > 4) {
  1150. SkDebugf("--- SkMatrix::setPolyToPoly count out of range %d\n", count);
  1151. return false;
  1152. }
  1153. if (0 == count) {
  1154. this->reset();
  1155. return true;
  1156. }
  1157. if (1 == count) {
  1158. this->setTranslate(dst[0].fX - src[0].fX, dst[0].fY - src[0].fY);
  1159. return true;
  1160. }
  1161. const PolyMapProc gPolyMapProcs[] = {
  1162. SkMatrix::Poly2Proc, SkMatrix::Poly3Proc, SkMatrix::Poly4Proc
  1163. };
  1164. PolyMapProc proc = gPolyMapProcs[count - 2];
  1165. SkMatrix tempMap, result;
  1166. if (!proc(src, &tempMap)) {
  1167. return false;
  1168. }
  1169. if (!tempMap.invert(&result)) {
  1170. return false;
  1171. }
  1172. if (!proc(dst, &tempMap)) {
  1173. return false;
  1174. }
  1175. this->setConcat(tempMap, result);
  1176. return true;
  1177. }
  1178. ///////////////////////////////////////////////////////////////////////////////
  1179. enum MinMaxOrBoth {
  1180. kMin_MinMaxOrBoth,
  1181. kMax_MinMaxOrBoth,
  1182. kBoth_MinMaxOrBoth
  1183. };
  1184. template <MinMaxOrBoth MIN_MAX_OR_BOTH> bool get_scale_factor(SkMatrix::TypeMask typeMask,
  1185. const SkScalar m[9],
  1186. SkScalar results[/*1 or 2*/]) {
  1187. if (typeMask & SkMatrix::kPerspective_Mask) {
  1188. return false;
  1189. }
  1190. if (SkMatrix::kIdentity_Mask == typeMask) {
  1191. results[0] = SK_Scalar1;
  1192. if (kBoth_MinMaxOrBoth == MIN_MAX_OR_BOTH) {
  1193. results[1] = SK_Scalar1;
  1194. }
  1195. return true;
  1196. }
  1197. if (!(typeMask & SkMatrix::kAffine_Mask)) {
  1198. if (kMin_MinMaxOrBoth == MIN_MAX_OR_BOTH) {
  1199. results[0] = SkMinScalar(SkScalarAbs(m[SkMatrix::kMScaleX]),
  1200. SkScalarAbs(m[SkMatrix::kMScaleY]));
  1201. } else if (kMax_MinMaxOrBoth == MIN_MAX_OR_BOTH) {
  1202. results[0] = SkMaxScalar(SkScalarAbs(m[SkMatrix::kMScaleX]),
  1203. SkScalarAbs(m[SkMatrix::kMScaleY]));
  1204. } else {
  1205. results[0] = SkScalarAbs(m[SkMatrix::kMScaleX]);
  1206. results[1] = SkScalarAbs(m[SkMatrix::kMScaleY]);
  1207. if (results[0] > results[1]) {
  1208. using std::swap;
  1209. swap(results[0], results[1]);
  1210. }
  1211. }
  1212. return true;
  1213. }
  1214. // ignore the translation part of the matrix, just look at 2x2 portion.
  1215. // compute singular values, take largest or smallest abs value.
  1216. // [a b; b c] = A^T*A
  1217. SkScalar a = sdot(m[SkMatrix::kMScaleX], m[SkMatrix::kMScaleX],
  1218. m[SkMatrix::kMSkewY], m[SkMatrix::kMSkewY]);
  1219. SkScalar b = sdot(m[SkMatrix::kMScaleX], m[SkMatrix::kMSkewX],
  1220. m[SkMatrix::kMScaleY], m[SkMatrix::kMSkewY]);
  1221. SkScalar c = sdot(m[SkMatrix::kMSkewX], m[SkMatrix::kMSkewX],
  1222. m[SkMatrix::kMScaleY], m[SkMatrix::kMScaleY]);
  1223. // eigenvalues of A^T*A are the squared singular values of A.
  1224. // characteristic equation is det((A^T*A) - l*I) = 0
  1225. // l^2 - (a + c)l + (ac-b^2)
  1226. // solve using quadratic equation (divisor is non-zero since l^2 has 1 coeff
  1227. // and roots are guaranteed to be pos and real).
  1228. SkScalar bSqd = b * b;
  1229. // if upper left 2x2 is orthogonal save some math
  1230. if (bSqd <= SK_ScalarNearlyZero*SK_ScalarNearlyZero) {
  1231. if (kMin_MinMaxOrBoth == MIN_MAX_OR_BOTH) {
  1232. results[0] = SkMinScalar(a, c);
  1233. } else if (kMax_MinMaxOrBoth == MIN_MAX_OR_BOTH) {
  1234. results[0] = SkMaxScalar(a, c);
  1235. } else {
  1236. results[0] = a;
  1237. results[1] = c;
  1238. if (results[0] > results[1]) {
  1239. using std::swap;
  1240. swap(results[0], results[1]);
  1241. }
  1242. }
  1243. } else {
  1244. SkScalar aminusc = a - c;
  1245. SkScalar apluscdiv2 = SkScalarHalf(a + c);
  1246. SkScalar x = SkScalarHalf(SkScalarSqrt(aminusc * aminusc + 4 * bSqd));
  1247. if (kMin_MinMaxOrBoth == MIN_MAX_OR_BOTH) {
  1248. results[0] = apluscdiv2 - x;
  1249. } else if (kMax_MinMaxOrBoth == MIN_MAX_OR_BOTH) {
  1250. results[0] = apluscdiv2 + x;
  1251. } else {
  1252. results[0] = apluscdiv2 - x;
  1253. results[1] = apluscdiv2 + x;
  1254. }
  1255. }
  1256. if (!SkScalarIsFinite(results[0])) {
  1257. return false;
  1258. }
  1259. // Due to the floating point inaccuracy, there might be an error in a, b, c
  1260. // calculated by sdot, further deepened by subsequent arithmetic operations
  1261. // on them. Therefore, we allow and cap the nearly-zero negative values.
  1262. SkASSERT(results[0] >= -SK_ScalarNearlyZero);
  1263. if (results[0] < 0) {
  1264. results[0] = 0;
  1265. }
  1266. results[0] = SkScalarSqrt(results[0]);
  1267. if (kBoth_MinMaxOrBoth == MIN_MAX_OR_BOTH) {
  1268. if (!SkScalarIsFinite(results[1])) {
  1269. return false;
  1270. }
  1271. SkASSERT(results[1] >= -SK_ScalarNearlyZero);
  1272. if (results[1] < 0) {
  1273. results[1] = 0;
  1274. }
  1275. results[1] = SkScalarSqrt(results[1]);
  1276. }
  1277. return true;
  1278. }
  1279. SkScalar SkMatrix::getMinScale() const {
  1280. SkScalar factor;
  1281. if (get_scale_factor<kMin_MinMaxOrBoth>(this->getType(), fMat, &factor)) {
  1282. return factor;
  1283. } else {
  1284. return -1;
  1285. }
  1286. }
  1287. SkScalar SkMatrix::getMaxScale() const {
  1288. SkScalar factor;
  1289. if (get_scale_factor<kMax_MinMaxOrBoth>(this->getType(), fMat, &factor)) {
  1290. return factor;
  1291. } else {
  1292. return -1;
  1293. }
  1294. }
  1295. bool SkMatrix::getMinMaxScales(SkScalar scaleFactors[2]) const {
  1296. return get_scale_factor<kBoth_MinMaxOrBoth>(this->getType(), fMat, scaleFactors);
  1297. }
  1298. const SkMatrix& SkMatrix::I() {
  1299. static constexpr SkMatrix identity;
  1300. SkASSERT(identity.isIdentity());
  1301. return identity;
  1302. }
  1303. const SkMatrix& SkMatrix::InvalidMatrix() {
  1304. static constexpr SkMatrix invalid(SK_ScalarMax, SK_ScalarMax, SK_ScalarMax,
  1305. SK_ScalarMax, SK_ScalarMax, SK_ScalarMax,
  1306. SK_ScalarMax, SK_ScalarMax, SK_ScalarMax,
  1307. kTranslate_Mask | kScale_Mask |
  1308. kAffine_Mask | kPerspective_Mask);
  1309. return invalid;
  1310. }
  1311. bool SkMatrix::decomposeScale(SkSize* scale, SkMatrix* remaining) const {
  1312. if (this->hasPerspective()) {
  1313. return false;
  1314. }
  1315. const SkScalar sx = SkVector::Length(this->getScaleX(), this->getSkewY());
  1316. const SkScalar sy = SkVector::Length(this->getSkewX(), this->getScaleY());
  1317. if (!SkScalarIsFinite(sx) || !SkScalarIsFinite(sy) ||
  1318. SkScalarNearlyZero(sx) || SkScalarNearlyZero(sy)) {
  1319. return false;
  1320. }
  1321. if (scale) {
  1322. scale->set(sx, sy);
  1323. }
  1324. if (remaining) {
  1325. *remaining = *this;
  1326. remaining->preScale(SkScalarInvert(sx), SkScalarInvert(sy));
  1327. }
  1328. return true;
  1329. }
  1330. ///////////////////////////////////////////////////////////////////////////////
  1331. size_t SkMatrix::writeToMemory(void* buffer) const {
  1332. // TODO write less for simple matrices
  1333. static const size_t sizeInMemory = 9 * sizeof(SkScalar);
  1334. if (buffer) {
  1335. memcpy(buffer, fMat, sizeInMemory);
  1336. }
  1337. return sizeInMemory;
  1338. }
  1339. size_t SkMatrix::readFromMemory(const void* buffer, size_t length) {
  1340. static const size_t sizeInMemory = 9 * sizeof(SkScalar);
  1341. if (length < sizeInMemory) {
  1342. return 0;
  1343. }
  1344. memcpy(fMat, buffer, sizeInMemory);
  1345. this->setTypeMask(kUnknown_Mask);
  1346. return sizeInMemory;
  1347. }
  1348. void SkMatrix::dump() const {
  1349. SkString str;
  1350. str.appendf("[%8.4f %8.4f %8.4f][%8.4f %8.4f %8.4f][%8.4f %8.4f %8.4f]",
  1351. fMat[0], fMat[1], fMat[2], fMat[3], fMat[4], fMat[5],
  1352. fMat[6], fMat[7], fMat[8]);
  1353. SkDebugf("%s\n", str.c_str());
  1354. }
  1355. ///////////////////////////////////////////////////////////////////////////////
  1356. #include "src/core/SkMatrixUtils.h"
  1357. bool SkTreatAsSprite(const SkMatrix& mat, const SkISize& size, const SkPaint& paint) {
  1358. // Our path aa is 2-bits, and our rect aa is 8, so we could use 8,
  1359. // but in practice 4 seems enough (still looks smooth) and allows
  1360. // more slightly fractional cases to fall into the fast (sprite) case.
  1361. static const unsigned kAntiAliasSubpixelBits = 4;
  1362. const unsigned subpixelBits = paint.isAntiAlias() ? kAntiAliasSubpixelBits : 0;
  1363. // quick reject on affine or perspective
  1364. if (mat.getType() & ~(SkMatrix::kScale_Mask | SkMatrix::kTranslate_Mask)) {
  1365. return false;
  1366. }
  1367. // quick success check
  1368. if (!subpixelBits && !(mat.getType() & ~SkMatrix::kTranslate_Mask)) {
  1369. return true;
  1370. }
  1371. // mapRect supports negative scales, so we eliminate those first
  1372. if (mat.getScaleX() < 0 || mat.getScaleY() < 0) {
  1373. return false;
  1374. }
  1375. SkRect dst;
  1376. SkIRect isrc = SkIRect::MakeSize(size);
  1377. {
  1378. SkRect src;
  1379. src.set(isrc);
  1380. mat.mapRect(&dst, src);
  1381. }
  1382. // just apply the translate to isrc
  1383. isrc.offset(SkScalarRoundToInt(mat.getTranslateX()),
  1384. SkScalarRoundToInt(mat.getTranslateY()));
  1385. if (subpixelBits) {
  1386. isrc.fLeft = SkLeftShift(isrc.fLeft, subpixelBits);
  1387. isrc.fTop = SkLeftShift(isrc.fTop, subpixelBits);
  1388. isrc.fRight = SkLeftShift(isrc.fRight, subpixelBits);
  1389. isrc.fBottom = SkLeftShift(isrc.fBottom, subpixelBits);
  1390. const float scale = 1 << subpixelBits;
  1391. dst.fLeft *= scale;
  1392. dst.fTop *= scale;
  1393. dst.fRight *= scale;
  1394. dst.fBottom *= scale;
  1395. }
  1396. SkIRect idst;
  1397. dst.round(&idst);
  1398. return isrc == idst;
  1399. }
  1400. // A square matrix M can be decomposed (via polar decomposition) into two matrices --
  1401. // an orthogonal matrix Q and a symmetric matrix S. In turn we can decompose S into U*W*U^T,
  1402. // where U is another orthogonal matrix and W is a scale matrix. These can be recombined
  1403. // to give M = (Q*U)*W*U^T, i.e., the product of two orthogonal matrices and a scale matrix.
  1404. //
  1405. // The one wrinkle is that traditionally Q may contain a reflection -- the
  1406. // calculation has been rejiggered to put that reflection into W.
  1407. bool SkDecomposeUpper2x2(const SkMatrix& matrix,
  1408. SkPoint* rotation1,
  1409. SkPoint* scale,
  1410. SkPoint* rotation2) {
  1411. SkScalar A = matrix[SkMatrix::kMScaleX];
  1412. SkScalar B = matrix[SkMatrix::kMSkewX];
  1413. SkScalar C = matrix[SkMatrix::kMSkewY];
  1414. SkScalar D = matrix[SkMatrix::kMScaleY];
  1415. if (is_degenerate_2x2(A, B, C, D)) {
  1416. return false;
  1417. }
  1418. double w1, w2;
  1419. SkScalar cos1, sin1;
  1420. SkScalar cos2, sin2;
  1421. // do polar decomposition (M = Q*S)
  1422. SkScalar cosQ, sinQ;
  1423. double Sa, Sb, Sd;
  1424. // if M is already symmetric (i.e., M = I*S)
  1425. if (SkScalarNearlyEqual(B, C)) {
  1426. cosQ = 1;
  1427. sinQ = 0;
  1428. Sa = A;
  1429. Sb = B;
  1430. Sd = D;
  1431. } else {
  1432. cosQ = A + D;
  1433. sinQ = C - B;
  1434. SkScalar reciplen = SkScalarInvert(SkScalarSqrt(cosQ*cosQ + sinQ*sinQ));
  1435. cosQ *= reciplen;
  1436. sinQ *= reciplen;
  1437. // S = Q^-1*M
  1438. // we don't calc Sc since it's symmetric
  1439. Sa = A*cosQ + C*sinQ;
  1440. Sb = B*cosQ + D*sinQ;
  1441. Sd = -B*sinQ + D*cosQ;
  1442. }
  1443. // Now we need to compute eigenvalues of S (our scale factors)
  1444. // and eigenvectors (bases for our rotation)
  1445. // From this, should be able to reconstruct S as U*W*U^T
  1446. if (SkScalarNearlyZero(SkDoubleToScalar(Sb))) {
  1447. // already diagonalized
  1448. cos1 = 1;
  1449. sin1 = 0;
  1450. w1 = Sa;
  1451. w2 = Sd;
  1452. cos2 = cosQ;
  1453. sin2 = sinQ;
  1454. } else {
  1455. double diff = Sa - Sd;
  1456. double discriminant = sqrt(diff*diff + 4.0*Sb*Sb);
  1457. double trace = Sa + Sd;
  1458. if (diff > 0) {
  1459. w1 = 0.5*(trace + discriminant);
  1460. w2 = 0.5*(trace - discriminant);
  1461. } else {
  1462. w1 = 0.5*(trace - discriminant);
  1463. w2 = 0.5*(trace + discriminant);
  1464. }
  1465. cos1 = SkDoubleToScalar(Sb); sin1 = SkDoubleToScalar(w1 - Sa);
  1466. SkScalar reciplen = SkScalarInvert(SkScalarSqrt(cos1*cos1 + sin1*sin1));
  1467. cos1 *= reciplen;
  1468. sin1 *= reciplen;
  1469. // rotation 2 is composition of Q and U
  1470. cos2 = cos1*cosQ - sin1*sinQ;
  1471. sin2 = sin1*cosQ + cos1*sinQ;
  1472. // rotation 1 is U^T
  1473. sin1 = -sin1;
  1474. }
  1475. if (scale) {
  1476. scale->fX = SkDoubleToScalar(w1);
  1477. scale->fY = SkDoubleToScalar(w2);
  1478. }
  1479. if (rotation1) {
  1480. rotation1->fX = cos1;
  1481. rotation1->fY = sin1;
  1482. }
  1483. if (rotation2) {
  1484. rotation2->fX = cos2;
  1485. rotation2->fY = sin2;
  1486. }
  1487. return true;
  1488. }
  1489. //////////////////////////////////////////////////////////////////////////////////////////////////
  1490. void SkRSXform::toQuad(SkScalar width, SkScalar height, SkPoint quad[4]) const {
  1491. #if 0
  1492. // This is the slow way, but it documents what we're doing
  1493. quad[0].set(0, 0);
  1494. quad[1].set(width, 0);
  1495. quad[2].set(width, height);
  1496. quad[3].set(0, height);
  1497. SkMatrix m;
  1498. m.setRSXform(*this).mapPoints(quad, quad, 4);
  1499. #else
  1500. const SkScalar m00 = fSCos;
  1501. const SkScalar m01 = -fSSin;
  1502. const SkScalar m02 = fTx;
  1503. const SkScalar m10 = -m01;
  1504. const SkScalar m11 = m00;
  1505. const SkScalar m12 = fTy;
  1506. quad[0].set(m02, m12);
  1507. quad[1].set(m00 * width + m02, m10 * width + m12);
  1508. quad[2].set(m00 * width + m01 * height + m02, m10 * width + m11 * height + m12);
  1509. quad[3].set(m01 * height + m02, m11 * height + m12);
  1510. #endif
  1511. }
  1512. void SkRSXform::toTriStrip(SkScalar width, SkScalar height, SkPoint strip[4]) const {
  1513. const SkScalar m00 = fSCos;
  1514. const SkScalar m01 = -fSSin;
  1515. const SkScalar m02 = fTx;
  1516. const SkScalar m10 = -m01;
  1517. const SkScalar m11 = m00;
  1518. const SkScalar m12 = fTy;
  1519. strip[0].set(m02, m12);
  1520. strip[1].set(m01 * height + m02, m11 * height + m12);
  1521. strip[2].set(m00 * width + m02, m10 * width + m12);
  1522. strip[3].set(m00 * width + m01 * height + m02, m10 * width + m11 * height + m12);
  1523. }