matrix.h 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  1. /*
  2. * File : matrix.h
  3. * This file is part of RT-Thread GUI Engine
  4. * COPYRIGHT (C) 2006 - 2017, RT-Thread Development Team
  5. *
  6. * This program is free software; you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation; either version 2 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License along
  17. * with this program; if not, write to the Free Software Foundation, Inc.,
  18. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  19. *
  20. * Change Logs:
  21. * Date Author Notes
  22. * 2010-04-10 Grissiom The first version
  23. */
  24. #ifndef __MATRIX_H__
  25. #define __MATRIX_H__
  26. /* Port from ejoy2d: https://github.com/cloudwu/ejoy2d/blob/master/LICENSE
  27. * Original License:
  28. *
  29. * The MIT License (MIT)
  30. *
  31. * Copyright (c) 2013 Ejoy.com Inc.
  32. *
  33. * Permission is hereby granted, free of charge, to any person obtaining a copy of
  34. * this software and associated documentation files (the "Software"), to deal in
  35. * the Software without restriction, including without limitation the rights to
  36. * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
  37. * the Software, and to permit persons to whom the Software is furnished to do so,
  38. * subject to the following conditions:
  39. *
  40. * The above copyright notice and this permission notice shall be included in all
  41. * copies or substantial portions of the Software.
  42. *
  43. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  44. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
  45. * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
  46. * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
  47. * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  48. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  49. */
  50. /* Port to RTGUI and modified by Grissiom */
  51. #ifdef _MSC_VER
  52. typedef __int32 int32_t;
  53. typedef unsigned __int32 uint32_t;
  54. typedef __int64 int64_t;
  55. typedef unsigned __int64 uint64_t;
  56. #else
  57. #include <stdint.h>
  58. #endif
  59. #define RTGUI_MATRIX_FRAC_BITS 11
  60. #define RTGUI_MATRIX_FRAC (1 << RTGUI_MATRIX_FRAC_BITS)
  61. struct rtgui_matrix
  62. {
  63. /* The matrix format is :
  64. *
  65. * | m[0] m[1] 0 |
  66. * | m[2] m[3] 0 |
  67. * | m[4] m[5] 1 |
  68. *
  69. * The format of the coordinate of a point is:
  70. *
  71. * | x y 1 |
  72. *
  73. * So, if you want to transform a point p with a matrix m, do:
  74. *
  75. * p * m
  76. *
  77. * Note: m[0-3] is in fix presentation that has 10 bits decimal
  78. * fraction(m/RTGUI_MATRIX_FRAC). While the unit of m[4-5] is pixel.
  79. *
  80. */
  81. int m[6];
  82. };
  83. rt_inline int32_t _rtgui_matrix_round_div32(int32_t n, int32_t d)
  84. {
  85. if (n == 0)
  86. return 0;
  87. if (d < 0)
  88. {
  89. d = -d;
  90. n = -n;
  91. }
  92. if (n > 0)
  93. return (n + d / 2) / d;
  94. else
  95. return (n - d / 2) / d;
  96. }
  97. rt_inline int32_t _rtgui_matrix_round_div6432(int64_t n, int32_t d)
  98. {
  99. if (n == 0)
  100. return 0;
  101. if (d < 0)
  102. {
  103. d = -d;
  104. n = -n;
  105. }
  106. if (n > 0)
  107. return (n + d / 2) / d;
  108. else
  109. return (n - d / 2) / d;
  110. }
  111. /* mm = mm1 * mm2 */
  112. rt_inline void rtgui_matrix_mul(struct rtgui_matrix *mm,
  113. const struct rtgui_matrix *mm1,
  114. const struct rtgui_matrix *mm2)
  115. {
  116. int *m = mm->m;
  117. const int *m1 = mm1->m;
  118. const int *m2 = mm2->m;
  119. m[0] = _rtgui_matrix_round_div32(m1[0] * m2[0] + m1[1] * m2[2], RTGUI_MATRIX_FRAC);
  120. m[1] = _rtgui_matrix_round_div32(m1[0] * m2[1] + m1[1] * m2[3], RTGUI_MATRIX_FRAC);
  121. m[2] = _rtgui_matrix_round_div32(m1[2] * m2[0] + m1[3] * m2[2], RTGUI_MATRIX_FRAC);
  122. m[3] = _rtgui_matrix_round_div32(m1[2] * m2[1] + m1[3] * m2[3], RTGUI_MATRIX_FRAC);
  123. m[4] = _rtgui_matrix_round_div32(m1[4] * m2[0] + m1[5] * m2[2], RTGUI_MATRIX_FRAC) + m2[4];
  124. m[5] = _rtgui_matrix_round_div32(m1[4] * m2[1] + m1[5] * m2[3], RTGUI_MATRIX_FRAC) + m2[5];
  125. }
  126. /* Matrix multiply point[(p) = (x, y) * m], ignore the movement components. */
  127. rt_inline void rtgui_matrix_mul_point_nomove(struct rtgui_point *p,
  128. int x, int y,
  129. struct rtgui_matrix *m)
  130. {
  131. int *mm = m->m;
  132. p->x = _rtgui_matrix_round_div32(x * mm[0] + y * mm[2], RTGUI_MATRIX_FRAC);
  133. p->y = _rtgui_matrix_round_div32(x * mm[1] + y * mm[3], RTGUI_MATRIX_FRAC);
  134. }
  135. /* Matrix multiply point[(p) = (x, y) * m]. */
  136. rt_inline void rtgui_matrix_mul_point(struct rtgui_point *p,
  137. int x, int y,
  138. struct rtgui_matrix *m)
  139. {
  140. int *mm = m->m;
  141. p->x = _rtgui_matrix_round_div32(x * mm[0] + y * mm[2], RTGUI_MATRIX_FRAC) + mm[4];
  142. p->y = _rtgui_matrix_round_div32(x * mm[1] + y * mm[3], RTGUI_MATRIX_FRAC) + mm[5];
  143. }
  144. /** Set @mm to an identity matrix. */
  145. rt_inline void rtgu_matrix_identity(struct rtgui_matrix *mm)
  146. {
  147. int *mat = mm->m;
  148. mat[0] = RTGUI_MATRIX_FRAC;
  149. mat[1] = 0;
  150. mat[2] = 0;
  151. mat[3] = RTGUI_MATRIX_FRAC;
  152. mat[4] = 0;
  153. mat[5] = 0;
  154. }
  155. /** Save the inversed matrix of @mm to @mo.
  156. *
  157. * @return If the matrix is not inversale, return 1. Otherwise, return 0. */
  158. int rtgui_matrix_inverse(const struct rtgui_matrix *mm, struct rtgui_matrix *mo);
  159. /** @degree range from 0 ~ 512. */
  160. void rtgui_matrix_rotate(struct rtgui_matrix *m, int degree);
  161. /** The unit is fixed point number. RTGUI_MATRIX_FRAC means 1.0. */
  162. void rtgui_matrix_scale(struct rtgui_matrix *m, int sx, int sy);
  163. /** The unit is pixel. Not the fixed point number. */
  164. void rtgui_matrix_move(struct rtgui_matrix *m, int dx, int dy);
  165. #endif /* end of include guard: __MATRIX_H__ */