base_geometry.c 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461
  1. #include "fitz-internal.h"
  2. #define MAX4(a,b,c,d) fz_max(fz_max(a,b), fz_max(c,d))
  3. #define MIN4(a,b,c,d) fz_min(fz_min(a,b), fz_min(c,d))
  4. /* A useful macro to add with overflow detection and clamping.
  5. We want to do "b = a + x", but to allow for overflow. Consider the
  6. top bits, and the cases in which overflow occurs:
  7. overflow a x b ~a^x a^b (~a^x)&(a^b)
  8. no 0 0 0 1 0 0
  9. yes 0 0 1 1 1 1
  10. no 0 1 0 0 0 0
  11. no 0 1 1 0 1 0
  12. no 1 0 0 0 1 0
  13. no 1 0 1 0 0 0
  14. yes 1 1 0 1 1 1
  15. no 1 1 1 1 0 0
  16. */
  17. #define ADD_WITH_SAT(b,a,x) \
  18. ((b) = (a) + (x), (b) = (((~(a)^(x))&((a)^(b))) < 0 ? ((x) < 0 ? INT_MIN : INT_MAX) : (b)))
  19. /* Matrices, points and affine transformations */
  20. const fz_matrix fz_identity = { 1, 0, 0, 1, 0, 0 };
  21. fz_matrix *
  22. fz_concat(fz_matrix *dst, const fz_matrix *one, const fz_matrix *two)
  23. {
  24. fz_matrix dst2;
  25. dst2.a = one->a * two->a + one->b * two->c;
  26. dst2.b = one->a * two->b + one->b * two->d;
  27. dst2.c = one->c * two->a + one->d * two->c;
  28. dst2.d = one->c * two->b + one->d * two->d;
  29. dst2.e = one->e * two->a + one->f * two->c + two->e;
  30. dst2.f = one->e * two->b + one->f * two->d + two->f;
  31. *dst = dst2;
  32. return dst;
  33. }
  34. fz_matrix *
  35. fz_scale(fz_matrix *m, float sx, float sy)
  36. {
  37. m->a = sx; m->b = 0;
  38. m->c = 0; m->d = sy;
  39. m->e = 0; m->f = 0;
  40. return m;
  41. }
  42. fz_matrix *
  43. fz_pre_scale(fz_matrix *mat, float sx, float sy)
  44. {
  45. mat->a *= sx;
  46. mat->b *= sx;
  47. mat->c *= sy;
  48. mat->d *= sy;
  49. return mat;
  50. }
  51. fz_matrix *
  52. fz_shear(fz_matrix *mat, float h, float v)
  53. {
  54. mat->a = 1; mat->b = v;
  55. mat->c = h; mat->d = 1;
  56. mat->e = 0; mat->f = 0;
  57. return mat;
  58. }
  59. fz_matrix *
  60. fz_pre_shear(fz_matrix *mat, float h, float v)
  61. {
  62. float a = mat->a;
  63. float b = mat->b;
  64. mat->a += v * mat->c;
  65. mat->b += v * mat->d;
  66. mat->c += h * a;
  67. mat->d += h * b;
  68. return mat;
  69. }
  70. fz_matrix *
  71. fz_rotate(fz_matrix *m, float theta)
  72. {
  73. float s;
  74. float c;
  75. while (theta < 0)
  76. theta += 360;
  77. while (theta >= 360)
  78. theta -= 360;
  79. if (fabsf(0 - theta) < FLT_EPSILON)
  80. {
  81. s = 0;
  82. c = 1;
  83. }
  84. else if (fabsf(90.0f - theta) < FLT_EPSILON)
  85. {
  86. s = 1;
  87. c = 0;
  88. }
  89. else if (fabsf(180.0f - theta) < FLT_EPSILON)
  90. {
  91. s = 0;
  92. c = -1;
  93. }
  94. else if (fabsf(270.0f - theta) < FLT_EPSILON)
  95. {
  96. s = -1;
  97. c = 0;
  98. }
  99. else
  100. {
  101. s = sinf(theta * (float)M_PI / 180);
  102. c = cosf(theta * (float)M_PI / 180);
  103. }
  104. m->a = c; m->b = s;
  105. m->c = -s; m->d = c;
  106. m->e = 0; m->f = 0;
  107. return m;
  108. }
  109. fz_matrix *
  110. fz_pre_rotate(fz_matrix *m, float theta)
  111. {
  112. while (theta < 0)
  113. theta += 360;
  114. while (theta >= 360)
  115. theta -= 360;
  116. if (fabsf(0 - theta) < FLT_EPSILON)
  117. {
  118. /* Nothing to do */
  119. }
  120. else if (fabsf(90.0f - theta) < FLT_EPSILON)
  121. {
  122. float a = m->a;
  123. float b = m->b;
  124. m->a = m->c;
  125. m->b = m->d;
  126. m->c = -a;
  127. m->d = -b;
  128. }
  129. else if (fabsf(180.0f - theta) < FLT_EPSILON)
  130. {
  131. m->a = -m->a;
  132. m->b = -m->b;
  133. m->c = -m->c;
  134. m->d = -m->d;
  135. }
  136. else if (fabsf(270.0f - theta) < FLT_EPSILON)
  137. {
  138. float a = m->a;
  139. float b = m->b;
  140. m->a = -m->c;
  141. m->b = -m->d;
  142. m->c = a;
  143. m->d = b;
  144. }
  145. else
  146. {
  147. float s = sinf(theta * (float)M_PI / 180);
  148. float c = cosf(theta * (float)M_PI / 180);
  149. float a = m->a;
  150. float b = m->b;
  151. m->a = c * a + s * m->c;
  152. m->b = c * b + s * m->d;
  153. m->c =-s * a + c * m->c;
  154. m->d =-s * b + c * m->d;
  155. }
  156. return m;
  157. }
  158. fz_matrix *
  159. fz_translate(fz_matrix *m, float tx, float ty)
  160. {
  161. m->a = 1; m->b = 0;
  162. m->c = 0; m->d = 1;
  163. m->e = tx; m->f = ty;
  164. return m;
  165. }
  166. fz_matrix *
  167. fz_pre_translate(fz_matrix *mat, float tx, float ty)
  168. {
  169. mat->e += tx * mat->a + ty * mat->c;
  170. mat->f += tx * mat->b + ty * mat->d;
  171. return mat;
  172. }
  173. fz_matrix *
  174. fz_invert_matrix(fz_matrix *dst, const fz_matrix *src)
  175. {
  176. /* Be careful to cope with dst == src */
  177. float a = src->a;
  178. float det = a * src->d - src->b * src->c;
  179. if (det < -FLT_EPSILON || det > FLT_EPSILON)
  180. {
  181. float rdet = 1 / det;
  182. dst->a = src->d * rdet;
  183. dst->b = -src->b * rdet;
  184. dst->c = -src->c * rdet;
  185. dst->d = a * rdet;
  186. a = -src->e * dst->a - src->f * dst->c;
  187. dst->f = -src->e * dst->b - src->f * dst->d;
  188. dst->e = a;
  189. }
  190. else
  191. *dst = *src;
  192. return dst;
  193. }
  194. int
  195. fz_is_rectilinear(const fz_matrix *m)
  196. {
  197. return (fabsf(m->b) < FLT_EPSILON && fabsf(m->c) < FLT_EPSILON) ||
  198. (fabsf(m->a) < FLT_EPSILON && fabsf(m->d) < FLT_EPSILON);
  199. }
  200. float
  201. fz_matrix_expansion(const fz_matrix *m)
  202. {
  203. return sqrtf(fabsf(m->a * m->d - m->b * m->c));
  204. }
  205. float
  206. fz_matrix_max_expansion(const fz_matrix *m)
  207. {
  208. float max = fabsf(m->a);
  209. float x = fabsf(m->b);
  210. if (max < x)
  211. max = x;
  212. x = fabsf(m->c);
  213. if (max < x)
  214. max = x;
  215. x = fabsf(m->d);
  216. if (max < x)
  217. max = x;
  218. return max;
  219. }
  220. fz_point *
  221. fz_transform_point(fz_point *restrict p, const fz_matrix *restrict m)
  222. {
  223. float x = p->x;
  224. p->x = x * m->a + p->y * m->c + m->e;
  225. p->y = x * m->b + p->y * m->d + m->f;
  226. return p;
  227. }
  228. fz_point *
  229. fz_transform_vector(fz_point *restrict p, const fz_matrix *restrict m)
  230. {
  231. float x = p->x;
  232. p->x = x * m->a + p->y * m->c;
  233. p->y = x * m->b + p->y * m->d;
  234. return p;
  235. }
  236. /* Rectangles and bounding boxes */
  237. /* biggest and smallest integers that a float can represent perfectly (i.e. 24 bits) */
  238. #define MAX_SAFE_INT 16777216
  239. #define MIN_SAFE_INT -16777216
  240. const fz_rect fz_infinite_rect = { 1, 1, -1, -1 };
  241. const fz_rect fz_empty_rect = { 0, 0, 0, 0 };
  242. const fz_rect fz_unit_rect = { 0, 0, 1, 1 };
  243. const fz_irect fz_infinite_irect = { 1, 1, -1, -1 };
  244. const fz_irect fz_empty_irect = { 0, 0, 0, 0 };
  245. const fz_irect fz_unit_bbox = { 0, 0, 1, 1 };
  246. fz_irect *
  247. fz_irect_from_rect(fz_irect *restrict b, const fz_rect *restrict r)
  248. {
  249. b->x0 = fz_clamp(floorf(r->x0), MIN_SAFE_INT, MAX_SAFE_INT);
  250. b->y0 = fz_clamp(floorf(r->y0), MIN_SAFE_INT, MAX_SAFE_INT);
  251. b->x1 = fz_clamp(ceilf(r->x1), MIN_SAFE_INT, MAX_SAFE_INT);
  252. b->y1 = fz_clamp(ceilf(r->y1), MIN_SAFE_INT, MAX_SAFE_INT);
  253. return b;
  254. }
  255. fz_rect *
  256. fz_rect_from_irect(fz_rect *restrict r, const fz_irect *restrict a)
  257. {
  258. r->x0 = a->x0;
  259. r->y0 = a->y0;
  260. r->x1 = a->x1;
  261. r->y1 = a->y1;
  262. return r;
  263. }
  264. fz_irect *
  265. fz_round_rect(fz_irect * restrict b, const fz_rect *restrict r)
  266. {
  267. int i;
  268. i = floorf(r->x0 + 0.001);
  269. b->x0 = fz_clamp(i, MIN_SAFE_INT, MAX_SAFE_INT);
  270. i = floorf(r->y0 + 0.001);
  271. b->y0 = fz_clamp(i, MIN_SAFE_INT, MAX_SAFE_INT);
  272. i = ceilf(r->x1 - 0.001);
  273. b->x1 = fz_clamp(i, MIN_SAFE_INT, MAX_SAFE_INT);
  274. i = ceilf(r->y1 - 0.001);
  275. b->y1 = fz_clamp(i, MIN_SAFE_INT, MAX_SAFE_INT);
  276. return b;
  277. }
  278. fz_rect *
  279. fz_intersect_rect(fz_rect *restrict a, const fz_rect *restrict b)
  280. {
  281. /* Check for empty box before infinite box */
  282. if (fz_is_empty_rect(a)) return a;
  283. if (fz_is_empty_rect(b)) {
  284. *a = fz_empty_rect;
  285. return a;
  286. }
  287. if (fz_is_infinite_rect(b)) return a;
  288. if (fz_is_infinite_rect(a)) {
  289. *a = *b;
  290. return a;
  291. }
  292. if (a->x0 < b->x0)
  293. a->x0 = b->x0;
  294. if (a->y0 < b->y0)
  295. a->y0 = b->y0;
  296. if (a->x1 > b->x1)
  297. a->x1 = b->x1;
  298. if (a->y1 > b->y1)
  299. a->y1 = b->y1;
  300. if (a->x1 < a->x0 || a->y1 < a->y0)
  301. *a = fz_empty_rect;
  302. return a;
  303. }
  304. fz_irect *
  305. fz_intersect_irect(fz_irect *restrict a, const fz_irect *restrict b)
  306. {
  307. /* Check for empty box before infinite box */
  308. if (fz_is_empty_irect(a)) return a;
  309. if (fz_is_empty_irect(b))
  310. {
  311. *a = fz_empty_irect;
  312. return a;
  313. }
  314. if (fz_is_infinite_irect(b)) return a;
  315. if (fz_is_infinite_irect(a))
  316. {
  317. *a = *b;
  318. return a;
  319. }
  320. if (a->x0 < b->x0)
  321. a->x0 = b->x0;
  322. if (a->y0 < b->y0)
  323. a->y0 = b->y0;
  324. if (a->x1 > b->x1)
  325. a->x1 = b->x1;
  326. if (a->y1 > b->y1)
  327. a->y1 = b->y1;
  328. if (a->x1 < a->x0 || a->y1 < a->y0)
  329. *a = fz_empty_irect;
  330. return a;
  331. }
  332. fz_rect *
  333. fz_union_rect(fz_rect *restrict a, const fz_rect *restrict b)
  334. {
  335. /* Check for empty box before infinite box */
  336. if (fz_is_empty_rect(b)) return a;
  337. if (fz_is_empty_rect(a)) {
  338. *a = *b;
  339. return a;
  340. }
  341. if (fz_is_infinite_rect(a)) return a;
  342. if (fz_is_infinite_rect(b)) {
  343. *a = *b;
  344. return a;
  345. }
  346. if (a->x0 > b->x0)
  347. a->x0 = b->x0;
  348. if (a->y0 > b->y0)
  349. a->y0 = b->y0;
  350. if (a->x1 < b->x1)
  351. a->x1 = b->x1;
  352. if (a->y1 < b->y1)
  353. a->y1 = b->y1;
  354. return a;
  355. }
  356. fz_irect *
  357. fz_translate_irect(fz_irect *a, int xoff, int yoff)
  358. {
  359. int t;
  360. if (fz_is_empty_irect(a)) return a;
  361. if (fz_is_infinite_irect(a)) return a;
  362. a->x0 = ADD_WITH_SAT(t, a->x0, xoff);
  363. a->y0 = ADD_WITH_SAT(t, a->y0, yoff);
  364. a->x1 = ADD_WITH_SAT(t, a->x1, xoff);
  365. a->y1 = ADD_WITH_SAT(t, a->y1, yoff);
  366. return a;
  367. }
  368. fz_rect *
  369. fz_transform_rect(fz_rect *restrict r, const fz_matrix *restrict m)
  370. {
  371. fz_point s, t, u, v;
  372. if (fz_is_infinite_rect(r))
  373. return r;
  374. if (fabsf(m->b) < FLT_EPSILON && fabsf(m->c) < FLT_EPSILON)
  375. {
  376. if (m->a < 0)
  377. {
  378. float f = r->x0;
  379. r->x0 = r->x1;
  380. r->x1 = f;
  381. }
  382. if (m->d < 0)
  383. {
  384. float f = r->y0;
  385. r->y0 = r->y1;
  386. r->y1 = f;
  387. }
  388. fz_transform_point(fz_rect_min(r), m);
  389. fz_transform_point(fz_rect_max(r), m);
  390. return r;
  391. }
  392. s.x = r->x0; s.y = r->y0;
  393. t.x = r->x0; t.y = r->y1;
  394. u.x = r->x1; u.y = r->y1;
  395. v.x = r->x1; v.y = r->y0;
  396. fz_transform_point(&s, m);
  397. fz_transform_point(&t, m);
  398. fz_transform_point(&u, m);
  399. fz_transform_point(&v, m);
  400. r->x0 = MIN4(s.x, t.x, u.x, v.x);
  401. r->y0 = MIN4(s.y, t.y, u.y, v.y);
  402. r->x1 = MAX4(s.x, t.x, u.x, v.x);
  403. r->y1 = MAX4(s.y, t.y, u.y, v.y);
  404. return r;
  405. }
  406. fz_rect *
  407. fz_expand_rect(fz_rect *a, float expand)
  408. {
  409. if (fz_is_empty_rect(a)) return a;
  410. if (fz_is_infinite_rect(a)) return a;
  411. a->x0 -= expand;
  412. a->y0 -= expand;
  413. a->x1 += expand;
  414. a->y1 += expand;
  415. return a;
  416. }