SkMatrix.h 67 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863
  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. /* Generated by tools/bookmaker from include/core/SkMatrix.h and docs/SkMatrix_Reference.bmh
  8. on 2018-09-13 13:59:55. Additional documentation and examples can be found at:
  9. https://skia.org/user/api/SkMatrix_Reference
  10. You may edit either file directly. Structural changes to public interfaces require
  11. editing both files. After editing docs/SkMatrix_Reference.bmh, run:
  12. bookmaker -b docs -i include/core/SkMatrix.h -p
  13. to create an updated version of this file.
  14. */
  15. #ifndef SkMatrix_DEFINED
  16. #define SkMatrix_DEFINED
  17. #include "../private/SkMacros.h"
  18. #include "../private/SkTo.h"
  19. #include "SkRect.h"
  20. struct SkRSXform;
  21. struct SkPoint3;
  22. class SkString;
  23. /** \class SkMatrix
  24. SkMatrix holds a 3x3 matrix for transforming coordinates. This allows mapping
  25. SkPoint and vectors with translation, scaling, skewing, rotation, and
  26. perspective.
  27. SkMatrix elements are in row major order. SkMatrix does not have a constructor,
  28. so it must be explicitly initialized. setIdentity() initializes SkMatrix
  29. so it has no effect. setTranslate(), setScale(), setSkew(), setRotate(), set9 and setAll()
  30. initializes all SkMatrix elements with the corresponding mapping.
  31. SkMatrix includes a hidden variable that classifies the type of matrix to
  32. improve performance. SkMatrix is not thread safe unless getType() is called first.
  33. */
  34. SK_BEGIN_REQUIRE_DENSE
  35. class SK_API SkMatrix {
  36. public:
  37. /** Sets SkMatrix to scale by (sx, sy). Returned matrix is:
  38. | sx 0 0 |
  39. | 0 sy 0 |
  40. | 0 0 1 |
  41. @param sx horizontal scale factor
  42. @param sy vertical scale factor
  43. @return SkMatrix with scale
  44. */
  45. static SkMatrix SK_WARN_UNUSED_RESULT MakeScale(SkScalar sx, SkScalar sy) {
  46. SkMatrix m;
  47. m.setScale(sx, sy);
  48. return m;
  49. }
  50. /** Sets SkMatrix to scale by (scale, scale). Returned matrix is:
  51. | scale 0 0 |
  52. | 0 scale 0 |
  53. | 0 0 1 |
  54. @param scale horizontal and vertical scale factor
  55. @return SkMatrix with scale
  56. */
  57. static SkMatrix SK_WARN_UNUSED_RESULT MakeScale(SkScalar scale) {
  58. SkMatrix m;
  59. m.setScale(scale, scale);
  60. return m;
  61. }
  62. /** Sets SkMatrix to translate by (dx, dy). Returned matrix is:
  63. | 1 0 dx |
  64. | 0 1 dy |
  65. | 0 0 1 |
  66. @param dx horizontal translation
  67. @param dy vertical translation
  68. @return SkMatrix with translation
  69. */
  70. static SkMatrix SK_WARN_UNUSED_RESULT MakeTrans(SkScalar dx, SkScalar dy) {
  71. SkMatrix m;
  72. m.setTranslate(dx, dy);
  73. return m;
  74. }
  75. /** Sets SkMatrix to:
  76. | scaleX skewX transX |
  77. | skewY scaleY transY |
  78. | pers0 pers1 pers2 |
  79. @param scaleX horizontal scale factor
  80. @param skewX horizontal skew factor
  81. @param transX horizontal translation
  82. @param skewY vertical skew factor
  83. @param scaleY vertical scale factor
  84. @param transY vertical translation
  85. @param pers0 input x-axis perspective factor
  86. @param pers1 input y-axis perspective factor
  87. @param pers2 perspective scale factor
  88. @return SkMatrix constructed from parameters
  89. */
  90. static SkMatrix SK_WARN_UNUSED_RESULT MakeAll(SkScalar scaleX, SkScalar skewX, SkScalar transX,
  91. SkScalar skewY, SkScalar scaleY, SkScalar transY,
  92. SkScalar pers0, SkScalar pers1, SkScalar pers2) {
  93. SkMatrix m;
  94. m.setAll(scaleX, skewX, transX, skewY, scaleY, transY, pers0, pers1, pers2);
  95. return m;
  96. }
  97. /** \enum SkMatrix::TypeMask
  98. Enum of bit fields for mask returned by getType().
  99. Used to identify the complexity of SkMatrix, to optimize performance.
  100. */
  101. enum TypeMask {
  102. kIdentity_Mask = 0, //!< identity SkMatrix; all bits clear
  103. kTranslate_Mask = 0x01, //!< translation SkMatrix
  104. kScale_Mask = 0x02, //!< scale SkMatrix
  105. kAffine_Mask = 0x04, //!< skew or rotate SkMatrix
  106. kPerspective_Mask = 0x08, //!< perspective SkMatrix
  107. };
  108. /** Returns a bit field describing the transformations the matrix may
  109. perform. The bit field is computed conservatively, so it may include
  110. false positives. For example, when kPerspective_Mask is set, all
  111. other bits are set.
  112. @return kIdentity_Mask, or combinations of: kTranslate_Mask, kScale_Mask,
  113. kAffine_Mask, kPerspective_Mask
  114. */
  115. TypeMask getType() const {
  116. if (fTypeMask & kUnknown_Mask) {
  117. fTypeMask = this->computeTypeMask();
  118. }
  119. // only return the public masks
  120. return (TypeMask)(fTypeMask & 0xF);
  121. }
  122. /** Returns true if SkMatrix is identity. Identity matrix is:
  123. | 1 0 0 |
  124. | 0 1 0 |
  125. | 0 0 1 |
  126. @return true if SkMatrix has no effect
  127. */
  128. bool isIdentity() const {
  129. return this->getType() == 0;
  130. }
  131. /** Returns true if SkMatrix at most scales and translates. SkMatrix may be identity,
  132. contain only scale elements, only translate elements, or both. SkMatrix form is:
  133. | scale-x 0 translate-x |
  134. | 0 scale-y translate-y |
  135. | 0 0 1 |
  136. @return true if SkMatrix is identity; or scales, translates, or both
  137. */
  138. bool isScaleTranslate() const {
  139. return !(this->getType() & ~(kScale_Mask | kTranslate_Mask));
  140. }
  141. /** Returns true if SkMatrix is identity, or translates. SkMatrix form is:
  142. | 1 0 translate-x |
  143. | 0 1 translate-y |
  144. | 0 0 1 |
  145. @return true if SkMatrix is identity, or translates
  146. */
  147. bool isTranslate() const { return !(this->getType() & ~(kTranslate_Mask)); }
  148. /** Returns true SkMatrix maps SkRect to another SkRect. If true, SkMatrix is identity,
  149. or scales, or rotates a multiple of 90 degrees, or mirrors on axes. In all
  150. cases, SkMatrix may also have translation. SkMatrix form is either:
  151. | scale-x 0 translate-x |
  152. | 0 scale-y translate-y |
  153. | 0 0 1 |
  154. or
  155. | 0 rotate-x translate-x |
  156. | rotate-y 0 translate-y |
  157. | 0 0 1 |
  158. for non-zero values of scale-x, scale-y, rotate-x, and rotate-y.
  159. Also called preservesAxisAlignment(); use the one that provides better inline
  160. documentation.
  161. @return true if SkMatrix maps one SkRect into another
  162. */
  163. bool rectStaysRect() const {
  164. if (fTypeMask & kUnknown_Mask) {
  165. fTypeMask = this->computeTypeMask();
  166. }
  167. return (fTypeMask & kRectStaysRect_Mask) != 0;
  168. }
  169. /** Returns true SkMatrix maps SkRect to another SkRect. If true, SkMatrix is identity,
  170. or scales, or rotates a multiple of 90 degrees, or mirrors on axes. In all
  171. cases, SkMatrix may also have translation. SkMatrix form is either:
  172. | scale-x 0 translate-x |
  173. | 0 scale-y translate-y |
  174. | 0 0 1 |
  175. or
  176. | 0 rotate-x translate-x |
  177. | rotate-y 0 translate-y |
  178. | 0 0 1 |
  179. for non-zero values of scale-x, scale-y, rotate-x, and rotate-y.
  180. Also called rectStaysRect(); use the one that provides better inline
  181. documentation.
  182. @return true if SkMatrix maps one SkRect into another
  183. */
  184. bool preservesAxisAlignment() const { return this->rectStaysRect(); }
  185. /** Returns true if the matrix contains perspective elements. SkMatrix form is:
  186. | -- -- -- |
  187. | -- -- -- |
  188. | perspective-x perspective-y perspective-scale |
  189. where perspective-x or perspective-y is non-zero, or perspective-scale is
  190. not one. All other elements may have any value.
  191. @return true if SkMatrix is in most general form
  192. */
  193. bool hasPerspective() const {
  194. return SkToBool(this->getPerspectiveTypeMaskOnly() &
  195. kPerspective_Mask);
  196. }
  197. /** Returns true if SkMatrix contains only translation, rotation, reflection, and
  198. uniform scale.
  199. Returns false if SkMatrix contains different scales, skewing, perspective, or
  200. degenerate forms that collapse to a line or point.
  201. Describes that the SkMatrix makes rendering with and without the matrix are
  202. visually alike; a transformed circle remains a circle. Mathematically, this is
  203. referred to as similarity of a Euclidean space, or a similarity transformation.
  204. Preserves right angles, keeping the arms of the angle equal lengths.
  205. @param tol to be deprecated
  206. @return true if SkMatrix only rotates, uniformly scales, translates
  207. */
  208. bool isSimilarity(SkScalar tol = SK_ScalarNearlyZero) const;
  209. /** Returns true if SkMatrix contains only translation, rotation, reflection, and
  210. scale. Scale may differ along rotated axes.
  211. Returns false if SkMatrix skewing, perspective, or degenerate forms that collapse
  212. to a line or point.
  213. Preserves right angles, but not requiring that the arms of the angle
  214. retain equal lengths.
  215. @param tol to be deprecated
  216. @return true if SkMatrix only rotates, scales, translates
  217. */
  218. bool preservesRightAngles(SkScalar tol = SK_ScalarNearlyZero) const;
  219. /** SkMatrix organizes its values in row order. These members correspond to
  220. each value in SkMatrix.
  221. */
  222. static constexpr int kMScaleX = 0; //!< horizontal scale factor
  223. static constexpr int kMSkewX = 1; //!< horizontal skew factor
  224. static constexpr int kMTransX = 2; //!< horizontal translation
  225. static constexpr int kMSkewY = 3; //!< vertical skew factor
  226. static constexpr int kMScaleY = 4; //!< vertical scale factor
  227. static constexpr int kMTransY = 5; //!< vertical translation
  228. static constexpr int kMPersp0 = 6; //!< input x perspective factor
  229. static constexpr int kMPersp1 = 7; //!< input y perspective factor
  230. static constexpr int kMPersp2 = 8; //!< perspective bias
  231. /** Affine arrays are in column major order to match the matrix used by
  232. PDF and XPS.
  233. */
  234. static constexpr int kAScaleX = 0; //!< horizontal scale factor
  235. static constexpr int kASkewY = 1; //!< vertical skew factor
  236. static constexpr int kASkewX = 2; //!< horizontal skew factor
  237. static constexpr int kAScaleY = 3; //!< vertical scale factor
  238. static constexpr int kATransX = 4; //!< horizontal translation
  239. static constexpr int kATransY = 5; //!< vertical translation
  240. /** Returns one matrix value. Asserts if index is out of range and SK_DEBUG is
  241. defined.
  242. @param index one of: kMScaleX, kMSkewX, kMTransX, kMSkewY, kMScaleY, kMTransY,
  243. kMPersp0, kMPersp1, kMPersp2
  244. @return value corresponding to index
  245. */
  246. SkScalar operator[](int index) const {
  247. SkASSERT((unsigned)index < 9);
  248. return fMat[index];
  249. }
  250. /** Returns one matrix value. Asserts if index is out of range and SK_DEBUG is
  251. defined.
  252. @param index one of: kMScaleX, kMSkewX, kMTransX, kMSkewY, kMScaleY, kMTransY,
  253. kMPersp0, kMPersp1, kMPersp2
  254. @return value corresponding to index
  255. */
  256. SkScalar get(int index) const {
  257. SkASSERT((unsigned)index < 9);
  258. return fMat[index];
  259. }
  260. /** Returns scale factor multiplied by x-axis input, contributing to x-axis output.
  261. With mapPoints(), scales SkPoint along the x-axis.
  262. @return horizontal scale factor
  263. */
  264. SkScalar getScaleX() const { return fMat[kMScaleX]; }
  265. /** Returns scale factor multiplied by y-axis input, contributing to y-axis output.
  266. With mapPoints(), scales SkPoint along the y-axis.
  267. @return vertical scale factor
  268. */
  269. SkScalar getScaleY() const { return fMat[kMScaleY]; }
  270. /** Returns scale factor multiplied by x-axis input, contributing to y-axis output.
  271. With mapPoints(), skews SkPoint along the y-axis.
  272. Skewing both axes can rotate SkPoint.
  273. @return vertical skew factor
  274. */
  275. SkScalar getSkewY() const { return fMat[kMSkewY]; }
  276. /** Returns scale factor multiplied by y-axis input, contributing to x-axis output.
  277. With mapPoints(), skews SkPoint along the x-axis.
  278. Skewing both axes can rotate SkPoint.
  279. @return horizontal scale factor
  280. */
  281. SkScalar getSkewX() const { return fMat[kMSkewX]; }
  282. /** Returns translation contributing to x-axis output.
  283. With mapPoints(), moves SkPoint along the x-axis.
  284. @return horizontal translation factor
  285. */
  286. SkScalar getTranslateX() const { return fMat[kMTransX]; }
  287. /** Returns translation contributing to y-axis output.
  288. With mapPoints(), moves SkPoint along the y-axis.
  289. @return vertical translation factor
  290. */
  291. SkScalar getTranslateY() const { return fMat[kMTransY]; }
  292. /** Returns factor scaling input x-axis relative to input y-axis.
  293. @return input x-axis perspective factor
  294. */
  295. SkScalar getPerspX() const { return fMat[kMPersp0]; }
  296. /** Returns factor scaling input y-axis relative to input x-axis.
  297. @return input y-axis perspective factor
  298. */
  299. SkScalar getPerspY() const { return fMat[kMPersp1]; }
  300. /** Returns writable SkMatrix value. Asserts if index is out of range and SK_DEBUG is
  301. defined. Clears internal cache anticipating that caller will change SkMatrix value.
  302. Next call to read SkMatrix state may recompute cache; subsequent writes to SkMatrix
  303. value must be followed by dirtyMatrixTypeCache().
  304. @param index one of: kMScaleX, kMSkewX, kMTransX, kMSkewY, kMScaleY, kMTransY,
  305. kMPersp0, kMPersp1, kMPersp2
  306. @return writable value corresponding to index
  307. */
  308. SkScalar& operator[](int index) {
  309. SkASSERT((unsigned)index < 9);
  310. this->setTypeMask(kUnknown_Mask);
  311. return fMat[index];
  312. }
  313. /** Sets SkMatrix value. Asserts if index is out of range and SK_DEBUG is
  314. defined. Safer than operator[]; internal cache is always maintained.
  315. @param index one of: kMScaleX, kMSkewX, kMTransX, kMSkewY, kMScaleY, kMTransY,
  316. kMPersp0, kMPersp1, kMPersp2
  317. @param value scalar to store in SkMatrix
  318. */
  319. void set(int index, SkScalar value) {
  320. SkASSERT((unsigned)index < 9);
  321. fMat[index] = value;
  322. this->setTypeMask(kUnknown_Mask);
  323. }
  324. /** Sets horizontal scale factor.
  325. @param v horizontal scale factor to store
  326. */
  327. void setScaleX(SkScalar v) { this->set(kMScaleX, v); }
  328. /** Sets vertical scale factor.
  329. @param v vertical scale factor to store
  330. */
  331. void setScaleY(SkScalar v) { this->set(kMScaleY, v); }
  332. /** Sets vertical skew factor.
  333. @param v vertical skew factor to store
  334. */
  335. void setSkewY(SkScalar v) { this->set(kMSkewY, v); }
  336. /** Sets horizontal skew factor.
  337. @param v horizontal skew factor to store
  338. */
  339. void setSkewX(SkScalar v) { this->set(kMSkewX, v); }
  340. /** Sets horizontal translation.
  341. @param v horizontal translation to store
  342. */
  343. void setTranslateX(SkScalar v) { this->set(kMTransX, v); }
  344. /** Sets vertical translation.
  345. @param v vertical translation to store
  346. */
  347. void setTranslateY(SkScalar v) { this->set(kMTransY, v); }
  348. /** Sets input x-axis perspective factor, which causes mapXY() to vary input x-axis values
  349. inversely proportional to input y-axis values.
  350. @param v perspective factor
  351. */
  352. void setPerspX(SkScalar v) { this->set(kMPersp0, v); }
  353. /** Sets input y-axis perspective factor, which causes mapXY() to vary input y-axis values
  354. inversely proportional to input x-axis values.
  355. @param v perspective factor
  356. */
  357. void setPerspY(SkScalar v) { this->set(kMPersp1, v); }
  358. /** Sets all values from parameters. Sets matrix to:
  359. | scaleX skewX transX |
  360. | skewY scaleY transY |
  361. | persp0 persp1 persp2 |
  362. @param scaleX horizontal scale factor to store
  363. @param skewX horizontal skew factor to store
  364. @param transX horizontal translation to store
  365. @param skewY vertical skew factor to store
  366. @param scaleY vertical scale factor to store
  367. @param transY vertical translation to store
  368. @param persp0 input x-axis values perspective factor to store
  369. @param persp1 input y-axis values perspective factor to store
  370. @param persp2 perspective scale factor to store
  371. */
  372. void setAll(SkScalar scaleX, SkScalar skewX, SkScalar transX,
  373. SkScalar skewY, SkScalar scaleY, SkScalar transY,
  374. SkScalar persp0, SkScalar persp1, SkScalar persp2) {
  375. fMat[kMScaleX] = scaleX;
  376. fMat[kMSkewX] = skewX;
  377. fMat[kMTransX] = transX;
  378. fMat[kMSkewY] = skewY;
  379. fMat[kMScaleY] = scaleY;
  380. fMat[kMTransY] = transY;
  381. fMat[kMPersp0] = persp0;
  382. fMat[kMPersp1] = persp1;
  383. fMat[kMPersp2] = persp2;
  384. this->setTypeMask(kUnknown_Mask);
  385. }
  386. /** Copies nine scalar values contained by SkMatrix into buffer, in member value
  387. ascending order: kMScaleX, kMSkewX, kMTransX, kMSkewY, kMScaleY, kMTransY,
  388. kMPersp0, kMPersp1, kMPersp2.
  389. @param buffer storage for nine scalar values
  390. */
  391. void get9(SkScalar buffer[9]) const {
  392. memcpy(buffer, fMat, 9 * sizeof(SkScalar));
  393. }
  394. /** Sets SkMatrix to nine scalar values in buffer, in member value ascending order:
  395. kMScaleX, kMSkewX, kMTransX, kMSkewY, kMScaleY, kMTransY, kMPersp0, kMPersp1,
  396. kMPersp2.
  397. Sets matrix to:
  398. | buffer[0] buffer[1] buffer[2] |
  399. | buffer[3] buffer[4] buffer[5] |
  400. | buffer[6] buffer[7] buffer[8] |
  401. In the future, set9 followed by get9 may not return the same values. Since SkMatrix
  402. maps non-homogeneous coordinates, scaling all nine values produces an equivalent
  403. transformation, possibly improving precision.
  404. @param buffer nine scalar values
  405. */
  406. void set9(const SkScalar buffer[9]);
  407. /** Sets SkMatrix to identity; which has no effect on mapped SkPoint. Sets SkMatrix to:
  408. | 1 0 0 |
  409. | 0 1 0 |
  410. | 0 0 1 |
  411. Also called setIdentity(); use the one that provides better inline
  412. documentation.
  413. */
  414. void reset();
  415. /** Sets SkMatrix to identity; which has no effect on mapped SkPoint. Sets SkMatrix to:
  416. | 1 0 0 |
  417. | 0 1 0 |
  418. | 0 0 1 |
  419. Also called reset(); use the one that provides better inline
  420. documentation.
  421. */
  422. void setIdentity() { this->reset(); }
  423. /** Sets SkMatrix to translate by (dx, dy).
  424. @param dx horizontal translation
  425. @param dy vertical translation
  426. */
  427. void setTranslate(SkScalar dx, SkScalar dy);
  428. /** Sets SkMatrix to translate by (v.fX, v.fY).
  429. @param v vector containing horizontal and vertical translation
  430. */
  431. void setTranslate(const SkVector& v) { this->setTranslate(v.fX, v.fY); }
  432. /** Sets SkMatrix to scale by sx and sy, about a pivot point at (px, py).
  433. The pivot point is unchanged when mapped with SkMatrix.
  434. @param sx horizontal scale factor
  435. @param sy vertical scale factor
  436. @param px pivot on x-axis
  437. @param py pivot on y-axis
  438. */
  439. void setScale(SkScalar sx, SkScalar sy, SkScalar px, SkScalar py);
  440. /** Sets SkMatrix to scale by sx and sy about at pivot point at (0, 0).
  441. @param sx horizontal scale factor
  442. @param sy vertical scale factor
  443. */
  444. void setScale(SkScalar sx, SkScalar sy);
  445. /** Sets SkMatrix to rotate by degrees about a pivot point at (px, py).
  446. The pivot point is unchanged when mapped with SkMatrix.
  447. Positive degrees rotates clockwise.
  448. @param degrees angle of axes relative to upright axes
  449. @param px pivot on x-axis
  450. @param py pivot on y-axis
  451. */
  452. void setRotate(SkScalar degrees, SkScalar px, SkScalar py);
  453. /** Sets SkMatrix to rotate by degrees about a pivot point at (0, 0).
  454. Positive degrees rotates clockwise.
  455. @param degrees angle of axes relative to upright axes
  456. */
  457. void setRotate(SkScalar degrees);
  458. /** Sets SkMatrix to rotate by sinValue and cosValue, about a pivot point at (px, py).
  459. The pivot point is unchanged when mapped with SkMatrix.
  460. Vector (sinValue, cosValue) describes the angle of rotation relative to (0, 1).
  461. Vector length specifies scale.
  462. @param sinValue rotation vector x-axis component
  463. @param cosValue rotation vector y-axis component
  464. @param px pivot on x-axis
  465. @param py pivot on y-axis
  466. */
  467. void setSinCos(SkScalar sinValue, SkScalar cosValue,
  468. SkScalar px, SkScalar py);
  469. /** Sets SkMatrix to rotate by sinValue and cosValue, about a pivot point at (0, 0).
  470. Vector (sinValue, cosValue) describes the angle of rotation relative to (0, 1).
  471. Vector length specifies scale.
  472. @param sinValue rotation vector x-axis component
  473. @param cosValue rotation vector y-axis component
  474. */
  475. void setSinCos(SkScalar sinValue, SkScalar cosValue);
  476. /** Sets SkMatrix to rotate, scale, and translate using a compressed matrix form.
  477. Vector (rsxForm.fSSin, rsxForm.fSCos) describes the angle of rotation relative
  478. to (0, 1). Vector length specifies scale. Mapped point is rotated and scaled
  479. by vector, then translated by (rsxForm.fTx, rsxForm.fTy).
  480. @param rsxForm compressed SkRSXform matrix
  481. @return reference to SkMatrix
  482. */
  483. SkMatrix& setRSXform(const SkRSXform& rsxForm);
  484. /** Sets SkMatrix to skew by kx and ky, about a pivot point at (px, py).
  485. The pivot point is unchanged when mapped with SkMatrix.
  486. @param kx horizontal skew factor
  487. @param ky vertical skew factor
  488. @param px pivot on x-axis
  489. @param py pivot on y-axis
  490. */
  491. void setSkew(SkScalar kx, SkScalar ky, SkScalar px, SkScalar py);
  492. /** Sets SkMatrix to skew by kx and ky, about a pivot point at (0, 0).
  493. @param kx horizontal skew factor
  494. @param ky vertical skew factor
  495. */
  496. void setSkew(SkScalar kx, SkScalar ky);
  497. /** Sets SkMatrix to SkMatrix a multiplied by SkMatrix b. Either a or b may be this.
  498. Given:
  499. | A B C | | J K L |
  500. a = | D E F |, b = | M N O |
  501. | G H I | | P Q R |
  502. sets SkMatrix to:
  503. | A B C | | J K L | | AJ+BM+CP AK+BN+CQ AL+BO+CR |
  504. a * b = | D E F | * | M N O | = | DJ+EM+FP DK+EN+FQ DL+EO+FR |
  505. | G H I | | P Q R | | GJ+HM+IP GK+HN+IQ GL+HO+IR |
  506. @param a SkMatrix on left side of multiply expression
  507. @param b SkMatrix on right side of multiply expression
  508. */
  509. void setConcat(const SkMatrix& a, const SkMatrix& b);
  510. /** Sets SkMatrix to SkMatrix multiplied by SkMatrix constructed from translation (dx, dy).
  511. This can be thought of as moving the point to be mapped before applying SkMatrix.
  512. Given:
  513. | A B C | | 1 0 dx |
  514. Matrix = | D E F |, T(dx, dy) = | 0 1 dy |
  515. | G H I | | 0 0 1 |
  516. sets SkMatrix to:
  517. | A B C | | 1 0 dx | | A B A*dx+B*dy+C |
  518. Matrix * T(dx, dy) = | D E F | | 0 1 dy | = | D E D*dx+E*dy+F |
  519. | G H I | | 0 0 1 | | G H G*dx+H*dy+I |
  520. @param dx x-axis translation before applying SkMatrix
  521. @param dy y-axis translation before applying SkMatrix
  522. */
  523. void preTranslate(SkScalar dx, SkScalar dy);
  524. /** Sets SkMatrix to SkMatrix multiplied by SkMatrix constructed from scaling by (sx, sy)
  525. about pivot point (px, py).
  526. This can be thought of as scaling about a pivot point before applying SkMatrix.
  527. Given:
  528. | A B C | | sx 0 dx |
  529. Matrix = | D E F |, S(sx, sy, px, py) = | 0 sy dy |
  530. | G H I | | 0 0 1 |
  531. where
  532. dx = px - sx * px
  533. dy = py - sy * py
  534. sets SkMatrix to:
  535. | A B C | | sx 0 dx | | A*sx B*sy A*dx+B*dy+C |
  536. Matrix * S(sx, sy, px, py) = | D E F | | 0 sy dy | = | D*sx E*sy D*dx+E*dy+F |
  537. | G H I | | 0 0 1 | | G*sx H*sy G*dx+H*dy+I |
  538. @param sx horizontal scale factor
  539. @param sy vertical scale factor
  540. @param px pivot on x-axis
  541. @param py pivot on y-axis
  542. */
  543. void preScale(SkScalar sx, SkScalar sy, SkScalar px, SkScalar py);
  544. /** Sets SkMatrix to SkMatrix multiplied by SkMatrix constructed from scaling by (sx, sy)
  545. about pivot point (0, 0).
  546. This can be thought of as scaling about the origin before applying SkMatrix.
  547. Given:
  548. | A B C | | sx 0 0 |
  549. Matrix = | D E F |, S(sx, sy) = | 0 sy 0 |
  550. | G H I | | 0 0 1 |
  551. sets SkMatrix to:
  552. | A B C | | sx 0 0 | | A*sx B*sy C |
  553. Matrix * S(sx, sy) = | D E F | | 0 sy 0 | = | D*sx E*sy F |
  554. | G H I | | 0 0 1 | | G*sx H*sy I |
  555. @param sx horizontal scale factor
  556. @param sy vertical scale factor
  557. */
  558. void preScale(SkScalar sx, SkScalar sy);
  559. /** Sets SkMatrix to SkMatrix multiplied by SkMatrix constructed from rotating by degrees
  560. about pivot point (px, py).
  561. This can be thought of as rotating about a pivot point before applying SkMatrix.
  562. Positive degrees rotates clockwise.
  563. Given:
  564. | A B C | | c -s dx |
  565. Matrix = | D E F |, R(degrees, px, py) = | s c dy |
  566. | G H I | | 0 0 1 |
  567. where
  568. c = cos(degrees)
  569. s = sin(degrees)
  570. dx = s * py + (1 - c) * px
  571. dy = -s * px + (1 - c) * py
  572. sets SkMatrix to:
  573. | A B C | | c -s dx | | Ac+Bs -As+Bc A*dx+B*dy+C |
  574. Matrix * R(degrees, px, py) = | D E F | | s c dy | = | Dc+Es -Ds+Ec D*dx+E*dy+F |
  575. | G H I | | 0 0 1 | | Gc+Hs -Gs+Hc G*dx+H*dy+I |
  576. @param degrees angle of axes relative to upright axes
  577. @param px pivot on x-axis
  578. @param py pivot on y-axis
  579. */
  580. void preRotate(SkScalar degrees, SkScalar px, SkScalar py);
  581. /** Sets SkMatrix to SkMatrix multiplied by SkMatrix constructed from rotating by degrees
  582. about pivot point (0, 0).
  583. This can be thought of as rotating about the origin before applying SkMatrix.
  584. Positive degrees rotates clockwise.
  585. Given:
  586. | A B C | | c -s 0 |
  587. Matrix = | D E F |, R(degrees, px, py) = | s c 0 |
  588. | G H I | | 0 0 1 |
  589. where
  590. c = cos(degrees)
  591. s = sin(degrees)
  592. sets SkMatrix to:
  593. | A B C | | c -s 0 | | Ac+Bs -As+Bc C |
  594. Matrix * R(degrees, px, py) = | D E F | | s c 0 | = | Dc+Es -Ds+Ec F |
  595. | G H I | | 0 0 1 | | Gc+Hs -Gs+Hc I |
  596. @param degrees angle of axes relative to upright axes
  597. */
  598. void preRotate(SkScalar degrees);
  599. /** Sets SkMatrix to SkMatrix multiplied by SkMatrix constructed from skewing by (kx, ky)
  600. about pivot point (px, py).
  601. This can be thought of as skewing about a pivot point before applying SkMatrix.
  602. Given:
  603. | A B C | | 1 kx dx |
  604. Matrix = | D E F |, K(kx, ky, px, py) = | ky 1 dy |
  605. | G H I | | 0 0 1 |
  606. where
  607. dx = -kx * py
  608. dy = -ky * px
  609. sets SkMatrix to:
  610. | A B C | | 1 kx dx | | A+B*ky A*kx+B A*dx+B*dy+C |
  611. Matrix * K(kx, ky, px, py) = | D E F | | ky 1 dy | = | D+E*ky D*kx+E D*dx+E*dy+F |
  612. | G H I | | 0 0 1 | | G+H*ky G*kx+H G*dx+H*dy+I |
  613. @param kx horizontal skew factor
  614. @param ky vertical skew factor
  615. @param px pivot on x-axis
  616. @param py pivot on y-axis
  617. */
  618. void preSkew(SkScalar kx, SkScalar ky, SkScalar px, SkScalar py);
  619. /** Sets SkMatrix to SkMatrix multiplied by SkMatrix constructed from skewing by (kx, ky)
  620. about pivot point (0, 0).
  621. This can be thought of as skewing about the origin before applying SkMatrix.
  622. Given:
  623. | A B C | | 1 kx 0 |
  624. Matrix = | D E F |, K(kx, ky) = | ky 1 0 |
  625. | G H I | | 0 0 1 |
  626. sets SkMatrix to:
  627. | A B C | | 1 kx 0 | | A+B*ky A*kx+B C |
  628. Matrix * K(kx, ky) = | D E F | | ky 1 0 | = | D+E*ky D*kx+E F |
  629. | G H I | | 0 0 1 | | G+H*ky G*kx+H I |
  630. @param kx horizontal skew factor
  631. @param ky vertical skew factor
  632. */
  633. void preSkew(SkScalar kx, SkScalar ky);
  634. /** Sets SkMatrix to SkMatrix multiplied by SkMatrix other.
  635. This can be thought of mapping by other before applying SkMatrix.
  636. Given:
  637. | A B C | | J K L |
  638. Matrix = | D E F |, other = | M N O |
  639. | G H I | | P Q R |
  640. sets SkMatrix to:
  641. | A B C | | J K L | | AJ+BM+CP AK+BN+CQ AL+BO+CR |
  642. Matrix * other = | D E F | * | M N O | = | DJ+EM+FP DK+EN+FQ DL+EO+FR |
  643. | G H I | | P Q R | | GJ+HM+IP GK+HN+IQ GL+HO+IR |
  644. @param other SkMatrix on right side of multiply expression
  645. */
  646. void preConcat(const SkMatrix& other);
  647. /** Sets SkMatrix to SkMatrix constructed from translation (dx, dy) multiplied by SkMatrix.
  648. This can be thought of as moving the point to be mapped after applying SkMatrix.
  649. Given:
  650. | J K L | | 1 0 dx |
  651. Matrix = | M N O |, T(dx, dy) = | 0 1 dy |
  652. | P Q R | | 0 0 1 |
  653. sets SkMatrix to:
  654. | 1 0 dx | | J K L | | J+dx*P K+dx*Q L+dx*R |
  655. T(dx, dy) * Matrix = | 0 1 dy | | M N O | = | M+dy*P N+dy*Q O+dy*R |
  656. | 0 0 1 | | P Q R | | P Q R |
  657. @param dx x-axis translation after applying SkMatrix
  658. @param dy y-axis translation after applying SkMatrix
  659. */
  660. void postTranslate(SkScalar dx, SkScalar dy);
  661. /** Sets SkMatrix to SkMatrix constructed from scaling by (sx, sy) about pivot point
  662. (px, py), multiplied by SkMatrix.
  663. This can be thought of as scaling about a pivot point after applying SkMatrix.
  664. Given:
  665. | J K L | | sx 0 dx |
  666. Matrix = | M N O |, S(sx, sy, px, py) = | 0 sy dy |
  667. | P Q R | | 0 0 1 |
  668. where
  669. dx = px - sx * px
  670. dy = py - sy * py
  671. sets SkMatrix to:
  672. | sx 0 dx | | J K L | | sx*J+dx*P sx*K+dx*Q sx*L+dx+R |
  673. S(sx, sy, px, py) * Matrix = | 0 sy dy | | M N O | = | sy*M+dy*P sy*N+dy*Q sy*O+dy*R |
  674. | 0 0 1 | | P Q R | | P Q R |
  675. @param sx horizontal scale factor
  676. @param sy vertical scale factor
  677. @param px pivot on x-axis
  678. @param py pivot on y-axis
  679. */
  680. void postScale(SkScalar sx, SkScalar sy, SkScalar px, SkScalar py);
  681. /** Sets SkMatrix to SkMatrix constructed from scaling by (sx, sy) about pivot point
  682. (0, 0), multiplied by SkMatrix.
  683. This can be thought of as scaling about the origin after applying SkMatrix.
  684. Given:
  685. | J K L | | sx 0 0 |
  686. Matrix = | M N O |, S(sx, sy) = | 0 sy 0 |
  687. | P Q R | | 0 0 1 |
  688. sets SkMatrix to:
  689. | sx 0 0 | | J K L | | sx*J sx*K sx*L |
  690. S(sx, sy) * Matrix = | 0 sy 0 | | M N O | = | sy*M sy*N sy*O |
  691. | 0 0 1 | | P Q R | | P Q R |
  692. @param sx horizontal scale factor
  693. @param sy vertical scale factor
  694. */
  695. void postScale(SkScalar sx, SkScalar sy);
  696. /** Sets SkMatrix to SkMatrix constructed from scaling by (1/divx, 1/divy),
  697. about pivot point (px, py), multiplied by SkMatrix.
  698. Returns false if either divx or divy is zero.
  699. Given:
  700. | J K L | | sx 0 0 |
  701. Matrix = | M N O |, I(divx, divy) = | 0 sy 0 |
  702. | P Q R | | 0 0 1 |
  703. where
  704. sx = 1 / divx
  705. sy = 1 / divy
  706. sets SkMatrix to:
  707. | sx 0 0 | | J K L | | sx*J sx*K sx*L |
  708. I(divx, divy) * Matrix = | 0 sy 0 | | M N O | = | sy*M sy*N sy*O |
  709. | 0 0 1 | | P Q R | | P Q R |
  710. @param divx integer divisor for inverse scale in x
  711. @param divy integer divisor for inverse scale in y
  712. @return true on successful scale
  713. */
  714. bool postIDiv(int divx, int divy);
  715. /** Sets SkMatrix to SkMatrix constructed from rotating by degrees about pivot point
  716. (px, py), multiplied by SkMatrix.
  717. This can be thought of as rotating about a pivot point after applying SkMatrix.
  718. Positive degrees rotates clockwise.
  719. Given:
  720. | J K L | | c -s dx |
  721. Matrix = | M N O |, R(degrees, px, py) = | s c dy |
  722. | P Q R | | 0 0 1 |
  723. where
  724. c = cos(degrees)
  725. s = sin(degrees)
  726. dx = s * py + (1 - c) * px
  727. dy = -s * px + (1 - c) * py
  728. sets SkMatrix to:
  729. |c -s dx| |J K L| |cJ-sM+dx*P cK-sN+dx*Q cL-sO+dx+R|
  730. R(degrees, px, py) * Matrix = |s c dy| |M N O| = |sJ+cM+dy*P sK+cN+dy*Q sL+cO+dy*R|
  731. |0 0 1| |P Q R| | P Q R|
  732. @param degrees angle of axes relative to upright axes
  733. @param px pivot on x-axis
  734. @param py pivot on y-axis
  735. */
  736. void postRotate(SkScalar degrees, SkScalar px, SkScalar py);
  737. /** Sets SkMatrix to SkMatrix constructed from rotating by degrees about pivot point
  738. (0, 0), multiplied by SkMatrix.
  739. This can be thought of as rotating about the origin after applying SkMatrix.
  740. Positive degrees rotates clockwise.
  741. Given:
  742. | J K L | | c -s 0 |
  743. Matrix = | M N O |, R(degrees, px, py) = | s c 0 |
  744. | P Q R | | 0 0 1 |
  745. where
  746. c = cos(degrees)
  747. s = sin(degrees)
  748. sets SkMatrix to:
  749. | c -s dx | | J K L | | cJ-sM cK-sN cL-sO |
  750. R(degrees, px, py) * Matrix = | s c dy | | M N O | = | sJ+cM sK+cN sL+cO |
  751. | 0 0 1 | | P Q R | | P Q R |
  752. @param degrees angle of axes relative to upright axes
  753. */
  754. void postRotate(SkScalar degrees);
  755. /** Sets SkMatrix to SkMatrix constructed from skewing by (kx, ky) about pivot point
  756. (px, py), multiplied by SkMatrix.
  757. This can be thought of as skewing about a pivot point after applying SkMatrix.
  758. Given:
  759. | J K L | | 1 kx dx |
  760. Matrix = | M N O |, K(kx, ky, px, py) = | ky 1 dy |
  761. | P Q R | | 0 0 1 |
  762. where
  763. dx = -kx * py
  764. dy = -ky * px
  765. sets SkMatrix to:
  766. | 1 kx dx| |J K L| |J+kx*M+dx*P K+kx*N+dx*Q L+kx*O+dx+R|
  767. K(kx, ky, px, py) * Matrix = |ky 1 dy| |M N O| = |ky*J+M+dy*P ky*K+N+dy*Q ky*L+O+dy*R|
  768. | 0 0 1| |P Q R| | P Q R|
  769. @param kx horizontal skew factor
  770. @param ky vertical skew factor
  771. @param px pivot on x-axis
  772. @param py pivot on y-axis
  773. */
  774. void postSkew(SkScalar kx, SkScalar ky, SkScalar px, SkScalar py);
  775. /** Sets SkMatrix to SkMatrix constructed from skewing by (kx, ky) about pivot point
  776. (0, 0), multiplied by SkMatrix.
  777. This can be thought of as skewing about the origin after applying SkMatrix.
  778. Given:
  779. | J K L | | 1 kx 0 |
  780. Matrix = | M N O |, K(kx, ky) = | ky 1 0 |
  781. | P Q R | | 0 0 1 |
  782. sets SkMatrix to:
  783. | 1 kx 0 | | J K L | | J+kx*M K+kx*N L+kx*O |
  784. K(kx, ky) * Matrix = | ky 1 0 | | M N O | = | ky*J+M ky*K+N ky*L+O |
  785. | 0 0 1 | | P Q R | | P Q R |
  786. @param kx horizontal skew factor
  787. @param ky vertical skew factor
  788. */
  789. void postSkew(SkScalar kx, SkScalar ky);
  790. /** Sets SkMatrix to SkMatrix other multiplied by SkMatrix.
  791. This can be thought of mapping by other after applying SkMatrix.
  792. Given:
  793. | J K L | | A B C |
  794. Matrix = | M N O |, other = | D E F |
  795. | P Q R | | G H I |
  796. sets SkMatrix to:
  797. | A B C | | J K L | | AJ+BM+CP AK+BN+CQ AL+BO+CR |
  798. other * Matrix = | D E F | * | M N O | = | DJ+EM+FP DK+EN+FQ DL+EO+FR |
  799. | G H I | | P Q R | | GJ+HM+IP GK+HN+IQ GL+HO+IR |
  800. @param other SkMatrix on left side of multiply expression
  801. */
  802. void postConcat(const SkMatrix& other);
  803. /** \enum SkMatrix::ScaleToFit
  804. ScaleToFit describes how SkMatrix is constructed to map one SkRect to another.
  805. ScaleToFit may allow SkMatrix to have unequal horizontal and vertical scaling,
  806. or may restrict SkMatrix to square scaling. If restricted, ScaleToFit specifies
  807. how SkMatrix maps to the side or center of the destination SkRect.
  808. */
  809. enum ScaleToFit {
  810. kFill_ScaleToFit, //!< scales in x and y to fill destination SkRect
  811. kStart_ScaleToFit, //!< scales and aligns to left and top
  812. kCenter_ScaleToFit, //!< scales and aligns to center
  813. kEnd_ScaleToFit, //!< scales and aligns to right and bottom
  814. };
  815. /** Sets SkMatrix to scale and translate src SkRect to dst SkRect. stf selects whether
  816. mapping completely fills dst or preserves the aspect ratio, and how to align
  817. src within dst. Returns false if src is empty, and sets SkMatrix to identity.
  818. Returns true if dst is empty, and sets SkMatrix to:
  819. | 0 0 0 |
  820. | 0 0 0 |
  821. | 0 0 1 |
  822. @param src SkRect to map from
  823. @param dst SkRect to map to
  824. @param stf one of: kFill_ScaleToFit, kStart_ScaleToFit,
  825. kCenter_ScaleToFit, kEnd_ScaleToFit
  826. @return true if SkMatrix can represent SkRect mapping
  827. */
  828. bool setRectToRect(const SkRect& src, const SkRect& dst, ScaleToFit stf);
  829. /** Returns SkMatrix set to scale and translate src SkRect to dst SkRect. stf selects
  830. whether mapping completely fills dst or preserves the aspect ratio, and how to
  831. align src within dst. Returns the identity SkMatrix if src is empty. If dst is
  832. empty, returns SkMatrix set to:
  833. | 0 0 0 |
  834. | 0 0 0 |
  835. | 0 0 1 |
  836. @param src SkRect to map from
  837. @param dst SkRect to map to
  838. @param stf one of: kFill_ScaleToFit, kStart_ScaleToFit,
  839. kCenter_ScaleToFit, kEnd_ScaleToFit
  840. @return SkMatrix mapping src to dst
  841. */
  842. static SkMatrix MakeRectToRect(const SkRect& src, const SkRect& dst, ScaleToFit stf) {
  843. SkMatrix m;
  844. m.setRectToRect(src, dst, stf);
  845. return m;
  846. }
  847. /** Sets SkMatrix to map src to dst. count must be zero or greater, and four or less.
  848. If count is zero, sets SkMatrix to identity and returns true.
  849. If count is one, sets SkMatrix to translate and returns true.
  850. If count is two or more, sets SkMatrix to map SkPoint if possible; returns false
  851. if SkMatrix cannot be constructed. If count is four, SkMatrix may include
  852. perspective.
  853. @param src SkPoint to map from
  854. @param dst SkPoint to map to
  855. @param count number of SkPoint in src and dst
  856. @return true if SkMatrix was constructed successfully
  857. */
  858. bool setPolyToPoly(const SkPoint src[], const SkPoint dst[], int count);
  859. /** Sets inverse to reciprocal matrix, returning true if SkMatrix can be inverted.
  860. Geometrically, if SkMatrix maps from source to destination, inverse SkMatrix
  861. maps from destination to source. If SkMatrix can not be inverted, inverse is
  862. unchanged.
  863. @param inverse storage for inverted SkMatrix; may be nullptr
  864. @return true if SkMatrix can be inverted
  865. */
  866. bool SK_WARN_UNUSED_RESULT invert(SkMatrix* inverse) const {
  867. // Allow the trivial case to be inlined.
  868. if (this->isIdentity()) {
  869. if (inverse) {
  870. inverse->reset();
  871. }
  872. return true;
  873. }
  874. return this->invertNonIdentity(inverse);
  875. }
  876. /** Fills affine with identity values in column major order.
  877. Sets affine to:
  878. | 1 0 0 |
  879. | 0 1 0 |
  880. Affine 3 by 2 matrices in column major order are used by OpenGL and XPS.
  881. @param affine storage for 3 by 2 affine matrix
  882. */
  883. static void SetAffineIdentity(SkScalar affine[6]);
  884. /** Fills affine in column major order. Sets affine to:
  885. | scale-x skew-x translate-x |
  886. | skew-y scale-y translate-y |
  887. If SkMatrix contains perspective, returns false and leaves affine unchanged.
  888. @param affine storage for 3 by 2 affine matrix; may be nullptr
  889. @return true if SkMatrix does not contain perspective
  890. */
  891. bool SK_WARN_UNUSED_RESULT asAffine(SkScalar affine[6]) const;
  892. /** Sets SkMatrix to affine values, passed in column major order. Given affine,
  893. column, then row, as:
  894. | scale-x skew-x translate-x |
  895. | skew-y scale-y translate-y |
  896. SkMatrix is set, row, then column, to:
  897. | scale-x skew-x translate-x |
  898. | skew-y scale-y translate-y |
  899. | 0 0 1 |
  900. @param affine 3 by 2 affine matrix
  901. */
  902. void setAffine(const SkScalar affine[6]);
  903. /** Maps src SkPoint array of length count to dst SkPoint array of equal or greater
  904. length. SkPoint are mapped by multiplying each SkPoint by SkMatrix. Given:
  905. | A B C | | x |
  906. Matrix = | D E F |, pt = | y |
  907. | G H I | | 1 |
  908. where
  909. for (i = 0; i < count; ++i) {
  910. x = src[i].fX
  911. y = src[i].fY
  912. }
  913. each dst SkPoint is computed as:
  914. |A B C| |x| Ax+By+C Dx+Ey+F
  915. Matrix * pt = |D E F| |y| = |Ax+By+C Dx+Ey+F Gx+Hy+I| = ------- , -------
  916. |G H I| |1| Gx+Hy+I Gx+Hy+I
  917. src and dst may point to the same storage.
  918. @param dst storage for mapped SkPoint
  919. @param src SkPoint to transform
  920. @param count number of SkPoint to transform
  921. */
  922. void mapPoints(SkPoint dst[], const SkPoint src[], int count) const {
  923. SkASSERT((dst && src && count > 0) || 0 == count);
  924. // no partial overlap
  925. SkASSERT(src == dst || &dst[count] <= &src[0] || &src[count] <= &dst[0]);
  926. this->getMapPtsProc()(*this, dst, src, count);
  927. }
  928. /** Maps pts SkPoint array of length count in place. SkPoint are mapped by multiplying
  929. each SkPoint by SkMatrix. Given:
  930. | A B C | | x |
  931. Matrix = | D E F |, pt = | y |
  932. | G H I | | 1 |
  933. where
  934. for (i = 0; i < count; ++i) {
  935. x = pts[i].fX
  936. y = pts[i].fY
  937. }
  938. each resulting pts SkPoint is computed as:
  939. |A B C| |x| Ax+By+C Dx+Ey+F
  940. Matrix * pt = |D E F| |y| = |Ax+By+C Dx+Ey+F Gx+Hy+I| = ------- , -------
  941. |G H I| |1| Gx+Hy+I Gx+Hy+I
  942. @param pts storage for mapped SkPoint
  943. @param count number of SkPoint to transform
  944. */
  945. void mapPoints(SkPoint pts[], int count) const {
  946. this->mapPoints(pts, pts, count);
  947. }
  948. /** Maps src SkPoint3 array of length count to dst SkPoint3 array, which must of length count or
  949. greater. SkPoint3 array is mapped by multiplying each SkPoint3 by SkMatrix. Given:
  950. | A B C | | x |
  951. Matrix = | D E F |, src = | y |
  952. | G H I | | z |
  953. each resulting dst SkPoint is computed as:
  954. |A B C| |x|
  955. Matrix * src = |D E F| |y| = |Ax+By+Cz Dx+Ey+Fz Gx+Hy+Iz|
  956. |G H I| |z|
  957. @param dst storage for mapped SkPoint3 array
  958. @param src SkPoint3 array to transform
  959. @param count items in SkPoint3 array to transform
  960. */
  961. void mapHomogeneousPoints(SkPoint3 dst[], const SkPoint3 src[], int count) const;
  962. /** Maps SkPoint (x, y) to result. SkPoint is mapped by multiplying by SkMatrix. Given:
  963. | A B C | | x |
  964. Matrix = | D E F |, pt = | y |
  965. | G H I | | 1 |
  966. result is computed as:
  967. |A B C| |x| Ax+By+C Dx+Ey+F
  968. Matrix * pt = |D E F| |y| = |Ax+By+C Dx+Ey+F Gx+Hy+I| = ------- , -------
  969. |G H I| |1| Gx+Hy+I Gx+Hy+I
  970. @param x x-axis value of SkPoint to map
  971. @param y y-axis value of SkPoint to map
  972. @param result storage for mapped SkPoint
  973. */
  974. void mapXY(SkScalar x, SkScalar y, SkPoint* result) const {
  975. SkASSERT(result);
  976. this->getMapXYProc()(*this, x, y, result);
  977. }
  978. /** Returns SkPoint (x, y) multiplied by SkMatrix. Given:
  979. | A B C | | x |
  980. Matrix = | D E F |, pt = | y |
  981. | G H I | | 1 |
  982. result is computed as:
  983. |A B C| |x| Ax+By+C Dx+Ey+F
  984. Matrix * pt = |D E F| |y| = |Ax+By+C Dx+Ey+F Gx+Hy+I| = ------- , -------
  985. |G H I| |1| Gx+Hy+I Gx+Hy+I
  986. @param x x-axis value of SkPoint to map
  987. @param y y-axis value of SkPoint to map
  988. @return mapped SkPoint
  989. */
  990. SkPoint mapXY(SkScalar x, SkScalar y) const {
  991. SkPoint result;
  992. this->getMapXYProc()(*this, x, y, &result);
  993. return result;
  994. }
  995. /** Maps src vector array of length count to vector SkPoint array of equal or greater
  996. length. Vectors are mapped by multiplying each vector by SkMatrix, treating
  997. SkMatrix translation as zero. Given:
  998. | A B 0 | | x |
  999. Matrix = | D E 0 |, src = | y |
  1000. | G H I | | 1 |
  1001. where
  1002. for (i = 0; i < count; ++i) {
  1003. x = src[i].fX
  1004. y = src[i].fY
  1005. }
  1006. each dst vector is computed as:
  1007. |A B 0| |x| Ax+By Dx+Ey
  1008. Matrix * src = |D E 0| |y| = |Ax+By Dx+Ey Gx+Hy+I| = ------- , -------
  1009. |G H I| |1| Gx+Hy+I Gx+Hy+I
  1010. src and dst may point to the same storage.
  1011. @param dst storage for mapped vectors
  1012. @param src vectors to transform
  1013. @param count number of vectors to transform
  1014. */
  1015. void mapVectors(SkVector dst[], const SkVector src[], int count) const;
  1016. /** Maps vecs vector array of length count in place, multiplying each vector by
  1017. SkMatrix, treating SkMatrix translation as zero. Given:
  1018. | A B 0 | | x |
  1019. Matrix = | D E 0 |, vec = | y |
  1020. | G H I | | 1 |
  1021. where
  1022. for (i = 0; i < count; ++i) {
  1023. x = vecs[i].fX
  1024. y = vecs[i].fY
  1025. }
  1026. each result vector is computed as:
  1027. |A B 0| |x| Ax+By Dx+Ey
  1028. Matrix * vec = |D E 0| |y| = |Ax+By Dx+Ey Gx+Hy+I| = ------- , -------
  1029. |G H I| |1| Gx+Hy+I Gx+Hy+I
  1030. @param vecs vectors to transform, and storage for mapped vectors
  1031. @param count number of vectors to transform
  1032. */
  1033. void mapVectors(SkVector vecs[], int count) const {
  1034. this->mapVectors(vecs, vecs, count);
  1035. }
  1036. /** Maps vector (dx, dy) to result. Vector is mapped by multiplying by SkMatrix,
  1037. treating SkMatrix translation as zero. Given:
  1038. | A B 0 | | dx |
  1039. Matrix = | D E 0 |, vec = | dy |
  1040. | G H I | | 1 |
  1041. each result vector is computed as:
  1042. |A B 0| |dx| A*dx+B*dy D*dx+E*dy
  1043. Matrix * vec = |D E 0| |dy| = |A*dx+B*dy D*dx+E*dy G*dx+H*dy+I| = ----------- , -----------
  1044. |G H I| | 1| G*dx+H*dy+I G*dx+*dHy+I
  1045. @param dx x-axis value of vector to map
  1046. @param dy y-axis value of vector to map
  1047. @param result storage for mapped vector
  1048. */
  1049. void mapVector(SkScalar dx, SkScalar dy, SkVector* result) const {
  1050. SkVector vec = { dx, dy };
  1051. this->mapVectors(result, &vec, 1);
  1052. }
  1053. /** Returns vector (dx, dy) multiplied by SkMatrix, treating SkMatrix translation as zero.
  1054. Given:
  1055. | A B 0 | | dx |
  1056. Matrix = | D E 0 |, vec = | dy |
  1057. | G H I | | 1 |
  1058. each result vector is computed as:
  1059. |A B 0| |dx| A*dx+B*dy D*dx+E*dy
  1060. Matrix * vec = |D E 0| |dy| = |A*dx+B*dy D*dx+E*dy G*dx+H*dy+I| = ----------- , -----------
  1061. |G H I| | 1| G*dx+H*dy+I G*dx+*dHy+I
  1062. @param dx x-axis value of vector to map
  1063. @param dy y-axis value of vector to map
  1064. @return mapped vector
  1065. */
  1066. SkVector mapVector(SkScalar dx, SkScalar dy) const {
  1067. SkVector vec = { dx, dy };
  1068. this->mapVectors(&vec, &vec, 1);
  1069. return vec;
  1070. }
  1071. /** Sets dst to bounds of src corners mapped by SkMatrix.
  1072. Returns true if mapped corners are dst corners.
  1073. Returned value is the same as calling rectStaysRect().
  1074. @param dst storage for bounds of mapped SkPoint
  1075. @param src SkRect to map
  1076. @return true if dst is equivalent to mapped src
  1077. */
  1078. bool mapRect(SkRect* dst, const SkRect& src) const;
  1079. /** Sets rect to bounds of rect corners mapped by SkMatrix.
  1080. Returns true if mapped corners are computed rect corners.
  1081. Returned value is the same as calling rectStaysRect().
  1082. @param rect rectangle to map, and storage for bounds of mapped corners
  1083. @return true if result is equivalent to mapped rect
  1084. */
  1085. bool mapRect(SkRect* rect) const {
  1086. return this->mapRect(rect, *rect);
  1087. }
  1088. /** Returns bounds of src corners mapped by SkMatrix.
  1089. @param src rectangle to map
  1090. @return mapped bounds
  1091. */
  1092. SkRect mapRect(const SkRect& src) const {
  1093. SkRect dst;
  1094. (void)this->mapRect(&dst, src);
  1095. return dst;
  1096. }
  1097. /** Maps four corners of rect to dst. SkPoint are mapped by multiplying each
  1098. rect corner by SkMatrix. rect corner is processed in this order:
  1099. (rect.fLeft, rect.fTop), (rect.fRight, rect.fTop), (rect.fRight, rect.fBottom),
  1100. (rect.fLeft, rect.fBottom).
  1101. rect may be empty: rect.fLeft may be greater than or equal to rect.fRight;
  1102. rect.fTop may be greater than or equal to rect.fBottom.
  1103. Given:
  1104. | A B C | | x |
  1105. Matrix = | D E F |, pt = | y |
  1106. | G H I | | 1 |
  1107. where pt is initialized from each of (rect.fLeft, rect.fTop),
  1108. (rect.fRight, rect.fTop), (rect.fRight, rect.fBottom), (rect.fLeft, rect.fBottom),
  1109. each dst SkPoint is computed as:
  1110. |A B C| |x| Ax+By+C Dx+Ey+F
  1111. Matrix * pt = |D E F| |y| = |Ax+By+C Dx+Ey+F Gx+Hy+I| = ------- , -------
  1112. |G H I| |1| Gx+Hy+I Gx+Hy+I
  1113. @param dst storage for mapped corner SkPoint
  1114. @param rect SkRect to map
  1115. */
  1116. void mapRectToQuad(SkPoint dst[4], const SkRect& rect) const {
  1117. // This could potentially be faster if we only transformed each x and y of the rect once.
  1118. rect.toQuad(dst);
  1119. this->mapPoints(dst, 4);
  1120. }
  1121. /** Sets dst to bounds of src corners mapped by SkMatrix. If matrix contains
  1122. elements other than scale or translate: asserts if SK_DEBUG is defined;
  1123. otherwise, results are undefined.
  1124. @param dst storage for bounds of mapped SkPoint
  1125. @param src SkRect to map
  1126. */
  1127. void mapRectScaleTranslate(SkRect* dst, const SkRect& src) const;
  1128. /** Returns geometric mean radius of ellipse formed by constructing circle of
  1129. size radius, and mapping constructed circle with SkMatrix. The result squared is
  1130. equal to the major axis length times the minor axis length.
  1131. Result is not meaningful if SkMatrix contains perspective elements.
  1132. @param radius circle size to map
  1133. @return average mapped radius
  1134. */
  1135. SkScalar mapRadius(SkScalar radius) const;
  1136. /** Returns true if a unit step on x-axis at some y-axis value mapped through SkMatrix
  1137. can be represented by a constant vector. Returns true if getType() returns
  1138. kIdentity_Mask, or combinations of: kTranslate_Mask, kScale_Mask, and kAffine_Mask.
  1139. May return true if getType() returns kPerspective_Mask, but only when SkMatrix
  1140. does not include rotation or skewing along the y-axis.
  1141. @return true if SkMatrix does not have complex perspective
  1142. */
  1143. bool isFixedStepInX() const;
  1144. /** Returns vector representing a unit step on x-axis at y mapped through SkMatrix.
  1145. If isFixedStepInX() is false, returned value is undefined.
  1146. @param y position of line parallel to x-axis
  1147. @return vector advance of mapped unit step on x-axis
  1148. */
  1149. SkVector fixedStepInX(SkScalar y) const;
  1150. /** Returns true if SkMatrix equals m, using an efficient comparison.
  1151. Returns false when the sign of zero values is the different; when one
  1152. matrix has positive zero value and the other has negative zero value.
  1153. Returns true even when both SkMatrix contain NaN.
  1154. NaN never equals any value, including itself. To improve performance, NaN values
  1155. are treated as bit patterns that are equal if their bit patterns are equal.
  1156. @param m SkMatrix to compare
  1157. @return true if m and SkMatrix are represented by identical bit patterns
  1158. */
  1159. bool cheapEqualTo(const SkMatrix& m) const {
  1160. return 0 == memcmp(fMat, m.fMat, sizeof(fMat));
  1161. }
  1162. /** Compares a and b; returns true if a and b are numerically equal. Returns true
  1163. even if sign of zero values are different. Returns false if either SkMatrix
  1164. contains NaN, even if the other SkMatrix also contains NaN.
  1165. @param a SkMatrix to compare
  1166. @param b SkMatrix to compare
  1167. @return true if SkMatrix a and SkMatrix b are numerically equal
  1168. */
  1169. friend SK_API bool operator==(const SkMatrix& a, const SkMatrix& b);
  1170. /** Compares a and b; returns true if a and b are not numerically equal. Returns false
  1171. even if sign of zero values are different. Returns true if either SkMatrix
  1172. contains NaN, even if the other SkMatrix also contains NaN.
  1173. @param a SkMatrix to compare
  1174. @param b SkMatrix to compare
  1175. @return true if SkMatrix a and SkMatrix b are numerically not equal
  1176. */
  1177. friend SK_API bool operator!=(const SkMatrix& a, const SkMatrix& b) {
  1178. return !(a == b);
  1179. }
  1180. /** Writes text representation of SkMatrix to standard output. Floating point values
  1181. are written with limited precision; it may not be possible to reconstruct
  1182. original SkMatrix from output.
  1183. */
  1184. void dump() const;
  1185. /** Returns the minimum scaling factor of SkMatrix by decomposing the scaling and
  1186. skewing elements.
  1187. Returns -1 if scale factor overflows or SkMatrix contains perspective.
  1188. @return minimum scale factor
  1189. */
  1190. SkScalar getMinScale() const;
  1191. /** Returns the maximum scaling factor of SkMatrix by decomposing the scaling and
  1192. skewing elements.
  1193. Returns -1 if scale factor overflows or SkMatrix contains perspective.
  1194. @return maximum scale factor
  1195. */
  1196. SkScalar getMaxScale() const;
  1197. /** Sets scaleFactors[0] to the minimum scaling factor, and scaleFactors[1] to the
  1198. maximum scaling factor. Scaling factors are computed by decomposing
  1199. the SkMatrix scaling and skewing elements.
  1200. Returns true if scaleFactors are found; otherwise, returns false and sets
  1201. scaleFactors to undefined values.
  1202. @param scaleFactors storage for minimum and maximum scale factors
  1203. @return true if scale factors were computed correctly
  1204. */
  1205. bool SK_WARN_UNUSED_RESULT getMinMaxScales(SkScalar scaleFactors[2]) const;
  1206. /** Decomposes SkMatrix into scale components and whatever remains. Returns false if
  1207. SkMatrix could not be decomposed.
  1208. Sets scale to portion of SkMatrix that scale axes. Sets remaining to SkMatrix
  1209. with scaling factored out. remaining may be passed as nullptr
  1210. to determine if SkMatrix can be decomposed without computing remainder.
  1211. Returns true if scale components are found. scale and remaining are
  1212. unchanged if SkMatrix contains perspective; scale factors are not finite, or
  1213. are nearly zero.
  1214. On success: Matrix = scale * Remaining.
  1215. @param scale axes scaling factors; may be nullptr
  1216. @param remaining SkMatrix without scaling; may be nullptr
  1217. @return true if scale can be computed
  1218. */
  1219. bool decomposeScale(SkSize* scale, SkMatrix* remaining = nullptr) const;
  1220. /** Returns reference to const identity SkMatrix. Returned SkMatrix is set to:
  1221. | 1 0 0 |
  1222. | 0 1 0 |
  1223. | 0 0 1 |
  1224. @return const identity SkMatrix
  1225. */
  1226. static const SkMatrix& I();
  1227. /** Returns reference to a const SkMatrix with invalid values. Returned SkMatrix is set
  1228. to:
  1229. | SK_ScalarMax SK_ScalarMax SK_ScalarMax |
  1230. | SK_ScalarMax SK_ScalarMax SK_ScalarMax |
  1231. | SK_ScalarMax SK_ScalarMax SK_ScalarMax |
  1232. @return const invalid SkMatrix
  1233. */
  1234. static const SkMatrix& InvalidMatrix();
  1235. /** Returns SkMatrix a multiplied by SkMatrix b.
  1236. Given:
  1237. | A B C | | J K L |
  1238. a = | D E F |, b = | M N O |
  1239. | G H I | | P Q R |
  1240. sets SkMatrix to:
  1241. | A B C | | J K L | | AJ+BM+CP AK+BN+CQ AL+BO+CR |
  1242. a * b = | D E F | * | M N O | = | DJ+EM+FP DK+EN+FQ DL+EO+FR |
  1243. | G H I | | P Q R | | GJ+HM+IP GK+HN+IQ GL+HO+IR |
  1244. @param a SkMatrix on left side of multiply expression
  1245. @param b SkMatrix on right side of multiply expression
  1246. @return SkMatrix computed from a times b
  1247. */
  1248. static SkMatrix Concat(const SkMatrix& a, const SkMatrix& b) {
  1249. SkMatrix result;
  1250. result.setConcat(a, b);
  1251. return result;
  1252. }
  1253. /** Sets internal cache to unknown state. Use to force update after repeated
  1254. modifications to SkMatrix element reference returned by operator[](int index).
  1255. */
  1256. void dirtyMatrixTypeCache() {
  1257. this->setTypeMask(kUnknown_Mask);
  1258. }
  1259. /** Initializes SkMatrix with scale and translate elements.
  1260. | sx 0 tx |
  1261. | 0 sy ty |
  1262. | 0 0 1 |
  1263. @param sx horizontal scale factor to store
  1264. @param sy vertical scale factor to store
  1265. @param tx horizontal translation to store
  1266. @param ty vertical translation to store
  1267. */
  1268. void setScaleTranslate(SkScalar sx, SkScalar sy, SkScalar tx, SkScalar ty) {
  1269. fMat[kMScaleX] = sx;
  1270. fMat[kMSkewX] = 0;
  1271. fMat[kMTransX] = tx;
  1272. fMat[kMSkewY] = 0;
  1273. fMat[kMScaleY] = sy;
  1274. fMat[kMTransY] = ty;
  1275. fMat[kMPersp0] = 0;
  1276. fMat[kMPersp1] = 0;
  1277. fMat[kMPersp2] = 1;
  1278. unsigned mask = 0;
  1279. if (sx != 1 || sy != 1) {
  1280. mask |= kScale_Mask;
  1281. }
  1282. if (tx || ty) {
  1283. mask |= kTranslate_Mask;
  1284. }
  1285. this->setTypeMask(mask | kRectStaysRect_Mask);
  1286. }
  1287. /** Returns true if all elements of the matrix are finite. Returns false if any
  1288. element is infinity, or NaN.
  1289. @return true if matrix has only finite elements
  1290. */
  1291. bool isFinite() const { return SkScalarsAreFinite(fMat, 9); }
  1292. private:
  1293. /** Set if the matrix will map a rectangle to another rectangle. This
  1294. can be true if the matrix is scale-only, or rotates a multiple of
  1295. 90 degrees.
  1296. This bit will be set on identity matrices
  1297. */
  1298. static constexpr int kRectStaysRect_Mask = 0x10;
  1299. /** Set if the perspective bit is valid even though the rest of
  1300. the matrix is Unknown.
  1301. */
  1302. static constexpr int kOnlyPerspectiveValid_Mask = 0x40;
  1303. static constexpr int kUnknown_Mask = 0x80;
  1304. static constexpr int kORableMasks = kTranslate_Mask |
  1305. kScale_Mask |
  1306. kAffine_Mask |
  1307. kPerspective_Mask;
  1308. static constexpr int kAllMasks = kTranslate_Mask |
  1309. kScale_Mask |
  1310. kAffine_Mask |
  1311. kPerspective_Mask |
  1312. kRectStaysRect_Mask;
  1313. SkScalar fMat[9];
  1314. mutable uint32_t fTypeMask;
  1315. static void ComputeInv(SkScalar dst[9], const SkScalar src[9], double invDet, bool isPersp);
  1316. uint8_t computeTypeMask() const;
  1317. uint8_t computePerspectiveTypeMask() const;
  1318. void setTypeMask(int mask) {
  1319. // allow kUnknown or a valid mask
  1320. SkASSERT(kUnknown_Mask == mask || (mask & kAllMasks) == mask ||
  1321. ((kUnknown_Mask | kOnlyPerspectiveValid_Mask) & mask)
  1322. == (kUnknown_Mask | kOnlyPerspectiveValid_Mask));
  1323. fTypeMask = SkToU8(mask);
  1324. }
  1325. void orTypeMask(int mask) {
  1326. SkASSERT((mask & kORableMasks) == mask);
  1327. fTypeMask = SkToU8(fTypeMask | mask);
  1328. }
  1329. void clearTypeMask(int mask) {
  1330. // only allow a valid mask
  1331. SkASSERT((mask & kAllMasks) == mask);
  1332. fTypeMask = fTypeMask & ~mask;
  1333. }
  1334. TypeMask getPerspectiveTypeMaskOnly() const {
  1335. if ((fTypeMask & kUnknown_Mask) &&
  1336. !(fTypeMask & kOnlyPerspectiveValid_Mask)) {
  1337. fTypeMask = this->computePerspectiveTypeMask();
  1338. }
  1339. return (TypeMask)(fTypeMask & 0xF);
  1340. }
  1341. /** Returns true if we already know that the matrix is identity;
  1342. false otherwise.
  1343. */
  1344. bool isTriviallyIdentity() const {
  1345. if (fTypeMask & kUnknown_Mask) {
  1346. return false;
  1347. }
  1348. return ((fTypeMask & 0xF) == 0);
  1349. }
  1350. inline void updateTranslateMask() {
  1351. if ((fMat[kMTransX] != 0) | (fMat[kMTransY] != 0)) {
  1352. fTypeMask |= kTranslate_Mask;
  1353. } else {
  1354. fTypeMask &= ~kTranslate_Mask;
  1355. }
  1356. }
  1357. typedef void (*MapXYProc)(const SkMatrix& mat, SkScalar x, SkScalar y,
  1358. SkPoint* result);
  1359. static MapXYProc GetMapXYProc(TypeMask mask) {
  1360. SkASSERT((mask & ~kAllMasks) == 0);
  1361. return gMapXYProcs[mask & kAllMasks];
  1362. }
  1363. MapXYProc getMapXYProc() const {
  1364. return GetMapXYProc(this->getType());
  1365. }
  1366. typedef void (*MapPtsProc)(const SkMatrix& mat, SkPoint dst[],
  1367. const SkPoint src[], int count);
  1368. static MapPtsProc GetMapPtsProc(TypeMask mask) {
  1369. SkASSERT((mask & ~kAllMasks) == 0);
  1370. return gMapPtsProcs[mask & kAllMasks];
  1371. }
  1372. MapPtsProc getMapPtsProc() const {
  1373. return GetMapPtsProc(this->getType());
  1374. }
  1375. bool SK_WARN_UNUSED_RESULT invertNonIdentity(SkMatrix* inverse) const;
  1376. static bool Poly2Proc(const SkPoint[], SkMatrix*);
  1377. static bool Poly3Proc(const SkPoint[], SkMatrix*);
  1378. static bool Poly4Proc(const SkPoint[], SkMatrix*);
  1379. static void Identity_xy(const SkMatrix&, SkScalar, SkScalar, SkPoint*);
  1380. static void Trans_xy(const SkMatrix&, SkScalar, SkScalar, SkPoint*);
  1381. static void Scale_xy(const SkMatrix&, SkScalar, SkScalar, SkPoint*);
  1382. static void ScaleTrans_xy(const SkMatrix&, SkScalar, SkScalar, SkPoint*);
  1383. static void Rot_xy(const SkMatrix&, SkScalar, SkScalar, SkPoint*);
  1384. static void RotTrans_xy(const SkMatrix&, SkScalar, SkScalar, SkPoint*);
  1385. static void Persp_xy(const SkMatrix&, SkScalar, SkScalar, SkPoint*);
  1386. static const MapXYProc gMapXYProcs[];
  1387. static void Identity_pts(const SkMatrix&, SkPoint[], const SkPoint[], int);
  1388. static void Trans_pts(const SkMatrix&, SkPoint dst[], const SkPoint[], int);
  1389. static void Scale_pts(const SkMatrix&, SkPoint dst[], const SkPoint[], int);
  1390. static void ScaleTrans_pts(const SkMatrix&, SkPoint dst[], const SkPoint[],
  1391. int count);
  1392. static void Persp_pts(const SkMatrix&, SkPoint dst[], const SkPoint[], int);
  1393. static void Affine_vpts(const SkMatrix&, SkPoint dst[], const SkPoint[], int);
  1394. static const MapPtsProc gMapPtsProcs[];
  1395. // return the number of bytes written, whether or not buffer is null
  1396. size_t writeToMemory(void* buffer) const;
  1397. /**
  1398. * Reads data from the buffer parameter
  1399. *
  1400. * @param buffer Memory to read from
  1401. * @param length Amount of memory available in the buffer
  1402. * @return number of bytes read (must be a multiple of 4) or
  1403. * 0 if there was not enough memory available
  1404. */
  1405. size_t readFromMemory(const void* buffer, size_t length);
  1406. friend class SkPerspIter;
  1407. friend class SkMatrixPriv;
  1408. friend class SkReader32;
  1409. friend class SerializationTest;
  1410. };
  1411. SK_END_REQUIRE_DENSE
  1412. #endif