SkMatrixPriv.h 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. /*
  2. * Copyright 2016 Google Inc.
  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. #ifndef SkMatrixPriv_DEFINE
  8. #define SkMatrixPriv_DEFINE
  9. #include "include/core/SkMatrix.h"
  10. #include "include/private/SkNx.h"
  11. #include "src/core/SkPointPriv.h"
  12. class SkMatrixPriv {
  13. public:
  14. enum {
  15. // writeTo/readFromMemory will never return a value larger than this
  16. kMaxFlattenSize = 9 * sizeof(SkScalar) + sizeof(uint32_t),
  17. };
  18. static size_t WriteToMemory(const SkMatrix& matrix, void* buffer) {
  19. return matrix.writeToMemory(buffer);
  20. }
  21. static size_t ReadFromMemory(SkMatrix* matrix, const void* buffer, size_t length) {
  22. return matrix->readFromMemory(buffer, length);
  23. }
  24. typedef SkMatrix::MapXYProc MapXYProc;
  25. typedef SkMatrix::MapPtsProc MapPtsProc;
  26. static MapPtsProc GetMapPtsProc(const SkMatrix& matrix) {
  27. return SkMatrix::GetMapPtsProc(matrix.getType());
  28. }
  29. static MapXYProc GetMapXYProc(const SkMatrix& matrix) {
  30. return SkMatrix::GetMapXYProc(matrix.getType());
  31. }
  32. /**
  33. * Attempt to map the rect through the inverse of the matrix. If it is not invertible,
  34. * then this returns false and dst is unchanged.
  35. */
  36. static bool SK_WARN_UNUSED_RESULT InverseMapRect(const SkMatrix& mx,
  37. SkRect* dst, const SkRect& src) {
  38. if (mx.getType() <= SkMatrix::kTranslate_Mask) {
  39. SkScalar tx = mx.getTranslateX();
  40. SkScalar ty = mx.getTranslateY();
  41. Sk4f trans(tx, ty, tx, ty);
  42. (Sk4f::Load(&src.fLeft) - trans).store(&dst->fLeft);
  43. return true;
  44. }
  45. // Insert other special-cases here (e.g. scale+translate)
  46. // general case
  47. SkMatrix inverse;
  48. if (mx.invert(&inverse)) {
  49. inverse.mapRect(dst, src);
  50. return true;
  51. }
  52. return false;
  53. }
  54. /** Maps count pts, skipping stride bytes to advance from one SkPoint to the next.
  55. Points are mapped by multiplying each SkPoint by SkMatrix. Given:
  56. | A B C | | x |
  57. Matrix = | D E F |, pt = | y |
  58. | G H I | | 1 |
  59. each resulting pts SkPoint is computed as:
  60. |A B C| |x| Ax+By+C Dx+Ey+F
  61. Matrix * pt = |D E F| |y| = |Ax+By+C Dx+Ey+F Gx+Hy+I| = ------- , -------
  62. |G H I| |1| Gx+Hy+I Gx+Hy+I
  63. @param mx matrix used to map the points
  64. @param pts storage for mapped points
  65. @param stride size of record starting with SkPoint, in bytes
  66. @param count number of points to transform
  67. */
  68. static void MapPointsWithStride(const SkMatrix& mx, SkPoint pts[], size_t stride, int count) {
  69. SkASSERT(stride >= sizeof(SkPoint));
  70. SkASSERT(0 == stride % sizeof(SkScalar));
  71. SkMatrix::TypeMask tm = mx.getType();
  72. if (SkMatrix::kIdentity_Mask == tm) {
  73. return;
  74. }
  75. if (SkMatrix::kTranslate_Mask == tm) {
  76. const SkScalar tx = mx.getTranslateX();
  77. const SkScalar ty = mx.getTranslateY();
  78. Sk2s trans(tx, ty);
  79. for (int i = 0; i < count; ++i) {
  80. (Sk2s::Load(&pts->fX) + trans).store(&pts->fX);
  81. pts = (SkPoint*)((intptr_t)pts + stride);
  82. }
  83. return;
  84. }
  85. // Insert other special-cases here (e.g. scale+translate)
  86. // general case
  87. SkMatrix::MapXYProc proc = mx.getMapXYProc();
  88. for (int i = 0; i < count; ++i) {
  89. proc(mx, pts->fX, pts->fY, pts);
  90. pts = (SkPoint*)((intptr_t)pts + stride);
  91. }
  92. }
  93. /** Maps src SkPoint array of length count to dst SkPoint array, skipping stride bytes
  94. to advance from one SkPoint to the next.
  95. Points are mapped by multiplying each SkPoint by SkMatrix. Given:
  96. | A B C | | x |
  97. Matrix = | D E F |, src = | y |
  98. | G H I | | 1 |
  99. each resulting dst SkPoint is computed as:
  100. |A B C| |x| Ax+By+C Dx+Ey+F
  101. Matrix * pt = |D E F| |y| = |Ax+By+C Dx+Ey+F Gx+Hy+I| = ------- , -------
  102. |G H I| |1| Gx+Hy+I Gx+Hy+I
  103. @param mx matrix used to map the points
  104. @param dst storage for mapped points
  105. @param src points to transform
  106. @param stride size of record starting with SkPoint, in bytes
  107. @param count number of points to transform
  108. */
  109. static void MapPointsWithStride(const SkMatrix& mx, SkPoint dst[], size_t dstStride,
  110. const SkPoint src[], size_t srcStride, int count) {
  111. SkASSERT(srcStride >= sizeof(SkPoint));
  112. SkASSERT(dstStride >= sizeof(SkPoint));
  113. SkASSERT(0 == srcStride % sizeof(SkScalar));
  114. SkASSERT(0 == dstStride % sizeof(SkScalar));
  115. for (int i = 0; i < count; ++i) {
  116. mx.mapPoints(dst, src, 1);
  117. src = (SkPoint*)((intptr_t)src + srcStride);
  118. dst = (SkPoint*)((intptr_t)dst + dstStride);
  119. }
  120. }
  121. static void MapHomogeneousPointsWithStride(const SkMatrix& mx, SkPoint3 dst[], size_t dstStride,
  122. const SkPoint3 src[], size_t srcStride, int count);
  123. };
  124. #endif