geometry.c 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885
  1. // Copyright (C) 2004-2025 Artifex Software, Inc.
  2. //
  3. // This file is part of MuPDF.
  4. //
  5. // MuPDF is free software: you can redistribute it and/or modify it under the
  6. // terms of the GNU Affero General Public License as published by the Free
  7. // Software Foundation, either version 3 of the License, or (at your option)
  8. // any later version.
  9. //
  10. // MuPDF is distributed in the hope that it will be useful, but WITHOUT ANY
  11. // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
  12. // FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
  13. // details.
  14. //
  15. // You should have received a copy of the GNU Affero General Public License
  16. // along with MuPDF. If not, see <https://www.gnu.org/licenses/agpl-3.0.en.html>
  17. //
  18. // Alternative licensing terms are available from the licensor.
  19. // For commercial licensing, see <https://www.artifex.com/> or contact
  20. // Artifex Software, Inc., 39 Mesa Street, Suite 108A, San Francisco,
  21. // CA 94129, USA, for further information.
  22. #include "mupdf/fitz.h"
  23. #include <math.h>
  24. #include <float.h>
  25. #include <limits.h>
  26. #define MAX4(a,b,c,d) fz_max(fz_max(a,b), fz_max(c,d))
  27. #define MIN4(a,b,c,d) fz_min(fz_min(a,b), fz_min(c,d))
  28. /* A useful macro to add with overflow detection and clamping.
  29. We want to do "b = a + x", but to allow for overflow. Consider the
  30. top bits, and the cases in which overflow occurs:
  31. overflow a x b ~a^x a^b (~a^x)&(a^b)
  32. no 0 0 0 1 0 0
  33. yes 0 0 1 1 1 1
  34. no 0 1 0 0 0 0
  35. no 0 1 1 0 1 0
  36. no 1 0 0 0 1 0
  37. no 1 0 1 0 0 0
  38. yes 1 1 0 1 1 1
  39. no 1 1 1 1 0 0
  40. */
  41. #define ADD_WITH_SAT(b,a,x) \
  42. ((b) = (a) + (x), (b) = (((~(a)^(x))&((a)^(b))) < 0 ? ((x) < 0 ? INT_MIN : INT_MAX) : (b)))
  43. /* Matrices, points and affine transformations */
  44. const fz_matrix fz_identity = { 1, 0, 0, 1, 0, 0 };
  45. fz_matrix
  46. fz_concat(fz_matrix one, fz_matrix two)
  47. {
  48. fz_matrix dst;
  49. dst.a = one.a * two.a + one.b * two.c;
  50. dst.b = one.a * two.b + one.b * two.d;
  51. dst.c = one.c * two.a + one.d * two.c;
  52. dst.d = one.c * two.b + one.d * two.d;
  53. dst.e = one.e * two.a + one.f * two.c + two.e;
  54. dst.f = one.e * two.b + one.f * two.d + two.f;
  55. return dst;
  56. }
  57. fz_matrix
  58. fz_scale(float sx, float sy)
  59. {
  60. fz_matrix m;
  61. m.a = sx; m.b = 0;
  62. m.c = 0; m.d = sy;
  63. m.e = 0; m.f = 0;
  64. return m;
  65. }
  66. fz_matrix
  67. fz_pre_scale(fz_matrix m, float sx, float sy)
  68. {
  69. m.a *= sx;
  70. m.b *= sx;
  71. m.c *= sy;
  72. m.d *= sy;
  73. return m;
  74. }
  75. fz_matrix
  76. fz_post_scale(fz_matrix m, float sx, float sy)
  77. {
  78. m.a *= sx;
  79. m.b *= sy;
  80. m.c *= sx;
  81. m.d *= sy;
  82. m.e *= sx;
  83. m.f *= sy;
  84. return m;
  85. }
  86. fz_matrix
  87. fz_shear(float h, float v)
  88. {
  89. fz_matrix m;
  90. m.a = 1; m.b = v;
  91. m.c = h; m.d = 1;
  92. m.e = 0; m.f = 0;
  93. return m;
  94. }
  95. fz_matrix
  96. fz_pre_shear(fz_matrix m, float h, float v)
  97. {
  98. float a = m.a;
  99. float b = m.b;
  100. m.a += v * m.c;
  101. m.b += v * m.d;
  102. m.c += h * a;
  103. m.d += h * b;
  104. return m;
  105. }
  106. fz_matrix
  107. fz_rotate(float theta)
  108. {
  109. fz_matrix m;
  110. float s;
  111. float c;
  112. while (theta < 0)
  113. theta += 360;
  114. while (theta >= 360)
  115. theta -= 360;
  116. if (fabsf(0 - theta) < FLT_EPSILON)
  117. {
  118. s = 0;
  119. c = 1;
  120. }
  121. else if (fabsf(90.0f - theta) < FLT_EPSILON)
  122. {
  123. s = 1;
  124. c = 0;
  125. }
  126. else if (fabsf(180.0f - theta) < FLT_EPSILON)
  127. {
  128. s = 0;
  129. c = -1;
  130. }
  131. else if (fabsf(270.0f - theta) < FLT_EPSILON)
  132. {
  133. s = -1;
  134. c = 0;
  135. }
  136. else
  137. {
  138. s = sinf(theta * FZ_PI / 180);
  139. c = cosf(theta * FZ_PI / 180);
  140. }
  141. m.a = c; m.b = s;
  142. m.c = -s; m.d = c;
  143. m.e = 0; m.f = 0;
  144. return m;
  145. }
  146. fz_matrix
  147. fz_pre_rotate(fz_matrix m, float theta)
  148. {
  149. while (theta < 0)
  150. theta += 360;
  151. while (theta >= 360)
  152. theta -= 360;
  153. if (fabsf(0 - theta) < FLT_EPSILON)
  154. {
  155. /* Nothing to do */
  156. }
  157. else if (fabsf(90.0f - theta) < FLT_EPSILON)
  158. {
  159. float a = m.a;
  160. float b = m.b;
  161. m.a = m.c;
  162. m.b = m.d;
  163. m.c = -a;
  164. m.d = -b;
  165. }
  166. else if (fabsf(180.0f - theta) < FLT_EPSILON)
  167. {
  168. m.a = -m.a;
  169. m.b = -m.b;
  170. m.c = -m.c;
  171. m.d = -m.d;
  172. }
  173. else if (fabsf(270.0f - theta) < FLT_EPSILON)
  174. {
  175. float a = m.a;
  176. float b = m.b;
  177. m.a = -m.c;
  178. m.b = -m.d;
  179. m.c = a;
  180. m.d = b;
  181. }
  182. else
  183. {
  184. float s = sinf(theta * FZ_PI / 180);
  185. float c = cosf(theta * FZ_PI / 180);
  186. float a = m.a;
  187. float b = m.b;
  188. m.a = c * a + s * m.c;
  189. m.b = c * b + s * m.d;
  190. m.c =-s * a + c * m.c;
  191. m.d =-s * b + c * m.d;
  192. }
  193. return m;
  194. }
  195. fz_matrix
  196. fz_translate(float tx, float ty)
  197. {
  198. fz_matrix m;
  199. m.a = 1; m.b = 0;
  200. m.c = 0; m.d = 1;
  201. m.e = tx; m.f = ty;
  202. return m;
  203. }
  204. fz_matrix
  205. fz_pre_translate(fz_matrix m, float tx, float ty)
  206. {
  207. m.e += tx * m.a + ty * m.c;
  208. m.f += tx * m.b + ty * m.d;
  209. return m;
  210. }
  211. fz_matrix
  212. fz_transform_page(fz_rect mediabox, float resolution, float rotate)
  213. {
  214. float user_w, user_h, pixel_w, pixel_h;
  215. fz_rect pixel_box;
  216. fz_matrix matrix;
  217. /* Adjust scaling factors to cover whole pixels */
  218. user_w = mediabox.x1 - mediabox.x0;
  219. user_h = mediabox.y1 - mediabox.y0;
  220. pixel_w = floorf(user_w * resolution / 72 + 0.5f);
  221. pixel_h = floorf(user_h * resolution / 72 + 0.5f);
  222. matrix = fz_pre_rotate(fz_scale(pixel_w / user_w, pixel_h / user_h), rotate);
  223. /* Adjust the page origin to sit at 0,0 after rotation */
  224. pixel_box = fz_transform_rect(mediabox, matrix);
  225. matrix.e -= pixel_box.x0;
  226. matrix.f -= pixel_box.y0;
  227. return matrix;
  228. }
  229. fz_matrix
  230. fz_invert_matrix(fz_matrix src)
  231. {
  232. float a = src.a;
  233. float det = a * src.d - src.b * src.c;
  234. if (det < -FLT_EPSILON || det > FLT_EPSILON)
  235. {
  236. fz_matrix dst;
  237. float rdet = 1 / det;
  238. dst.a = src.d * rdet;
  239. dst.b = -src.b * rdet;
  240. dst.c = -src.c * rdet;
  241. dst.d = a * rdet;
  242. a = -src.e * dst.a - src.f * dst.c;
  243. dst.f = -src.e * dst.b - src.f * dst.d;
  244. dst.e = a;
  245. return dst;
  246. }
  247. return src;
  248. }
  249. int
  250. fz_try_invert_matrix(fz_matrix *dst, fz_matrix src)
  251. {
  252. double sa = (double)src.a;
  253. double sb = (double)src.b;
  254. double sc = (double)src.c;
  255. double sd = (double)src.d;
  256. double da, db, dc, dd;
  257. double det = sa * sd - sb * sc;
  258. if (det >= -DBL_EPSILON && det <= DBL_EPSILON)
  259. return 1;
  260. det = 1 / det;
  261. da = sd * det;
  262. dst->a = (float)da;
  263. db = -sb * det;
  264. dst->b = (float)db;
  265. dc = -sc * det;
  266. dst->c = (float)dc;
  267. dd = sa * det;
  268. dst->d = (float)dd;
  269. da = -src.e * da - src.f * dc;
  270. dst->f = (float)(-src.e * db - src.f * dd);
  271. dst->e = (float)da;
  272. return 0;
  273. }
  274. int
  275. fz_is_rectilinear(fz_matrix m)
  276. {
  277. return (fabsf(m.b) < FLT_EPSILON && fabsf(m.c) < FLT_EPSILON) ||
  278. (fabsf(m.a) < FLT_EPSILON && fabsf(m.d) < FLT_EPSILON);
  279. }
  280. float
  281. fz_matrix_expansion(fz_matrix m)
  282. {
  283. return sqrtf(fabsf(m.a * m.d - m.b * m.c));
  284. }
  285. float
  286. fz_matrix_max_expansion(fz_matrix m)
  287. {
  288. float max = fabsf(m.a);
  289. float x = fabsf(m.b);
  290. if (max < x)
  291. max = x;
  292. x = fabsf(m.c);
  293. if (max < x)
  294. max = x;
  295. x = fabsf(m.d);
  296. if (max < x)
  297. max = x;
  298. return max;
  299. }
  300. fz_point
  301. fz_transform_point(fz_point p, fz_matrix m)
  302. {
  303. float x = p.x;
  304. p.x = x * m.a + p.y * m.c + m.e;
  305. p.y = x * m.b + p.y * m.d + m.f;
  306. return p;
  307. }
  308. fz_point
  309. fz_transform_point_xy(float x, float y, fz_matrix m)
  310. {
  311. fz_point p;
  312. p.x = x * m.a + y * m.c + m.e;
  313. p.y = x * m.b + y * m.d + m.f;
  314. return p;
  315. }
  316. fz_point
  317. fz_transform_vector(fz_point p, fz_matrix m)
  318. {
  319. float x = p.x;
  320. p.x = x * m.a + p.y * m.c;
  321. p.y = x * m.b + p.y * m.d;
  322. return p;
  323. }
  324. fz_point
  325. fz_normalize_vector(fz_point p)
  326. {
  327. float len = p.x * p.x + p.y * p.y;
  328. if (len != 0)
  329. {
  330. len = sqrtf(len);
  331. p.x /= len;
  332. p.y /= len;
  333. }
  334. return p;
  335. }
  336. /* Rectangles and bounding boxes */
  337. /* biggest and smallest integers that a float can represent perfectly (i.e. 24 bits) */
  338. #define MAX_SAFE_INT 16777216
  339. #define MIN_SAFE_INT -16777216
  340. const fz_rect fz_infinite_rect = { FZ_MIN_INF_RECT, FZ_MIN_INF_RECT, FZ_MAX_INF_RECT, FZ_MAX_INF_RECT };
  341. const fz_rect fz_empty_rect = { FZ_MAX_INF_RECT, FZ_MAX_INF_RECT, FZ_MIN_INF_RECT, FZ_MIN_INF_RECT };
  342. const fz_rect fz_invalid_rect = { 0, 0, -1, -1 };
  343. const fz_rect fz_unit_rect = { 0, 0, 1, 1 };
  344. const fz_irect fz_infinite_irect = { FZ_MIN_INF_RECT, FZ_MIN_INF_RECT, FZ_MAX_INF_RECT, FZ_MAX_INF_RECT };
  345. const fz_irect fz_empty_irect = { FZ_MAX_INF_RECT, FZ_MAX_INF_RECT, FZ_MIN_INF_RECT, FZ_MIN_INF_RECT };
  346. const fz_irect fz_invalid_irect = { 0, 0, -1, -1 };
  347. const fz_irect fz_unit_bbox = { 0, 0, 1, 1 };
  348. const fz_quad fz_infinite_quad = { { -INFINITY, INFINITY}, {INFINITY, INFINITY}, {-INFINITY, -INFINITY}, {INFINITY, -INFINITY} };
  349. const fz_quad fz_invalid_quad = { {NAN, NAN}, {NAN, NAN}, {NAN, NAN}, {NAN, NAN} };
  350. fz_irect
  351. fz_irect_from_rect(fz_rect r)
  352. {
  353. fz_irect b;
  354. if (fz_is_infinite_rect(r))
  355. return fz_infinite_irect;
  356. if (!fz_is_valid_rect(r))
  357. return fz_invalid_irect;
  358. b.x0 = fz_clamp(floorf(r.x0), MIN_SAFE_INT, MAX_SAFE_INT);
  359. b.y0 = fz_clamp(floorf(r.y0), MIN_SAFE_INT, MAX_SAFE_INT);
  360. b.x1 = fz_clamp(ceilf(r.x1), MIN_SAFE_INT, MAX_SAFE_INT);
  361. b.y1 = fz_clamp(ceilf(r.y1), MIN_SAFE_INT, MAX_SAFE_INT);
  362. return b;
  363. }
  364. fz_rect
  365. fz_rect_from_irect(fz_irect a)
  366. {
  367. fz_rect r;
  368. if (fz_is_infinite_irect(a))
  369. return fz_infinite_rect;
  370. r.x0 = a.x0;
  371. r.y0 = a.y0;
  372. r.x1 = a.x1;
  373. r.y1 = a.y1;
  374. return r;
  375. }
  376. fz_irect
  377. fz_round_rect(fz_rect r)
  378. {
  379. fz_irect b;
  380. float f;
  381. f = floorf(r.x0 + 0.001f);
  382. b.x0 = fz_clamp(f, MIN_SAFE_INT, MAX_SAFE_INT);
  383. f = floorf(r.y0 + 0.001f);
  384. b.y0 = fz_clamp(f, MIN_SAFE_INT, MAX_SAFE_INT);
  385. f = ceilf(r.x1 - 0.001f);
  386. b.x1 = fz_clamp(f, MIN_SAFE_INT, MAX_SAFE_INT);
  387. f = ceilf(r.y1 - 0.001f);
  388. b.y1 = fz_clamp(f, MIN_SAFE_INT, MAX_SAFE_INT);
  389. return b;
  390. }
  391. fz_rect
  392. fz_intersect_rect(fz_rect a, fz_rect b)
  393. {
  394. if (fz_is_infinite_rect(b)) return a;
  395. if (fz_is_infinite_rect(a)) return b;
  396. if (a.x0 < b.x0)
  397. a.x0 = b.x0;
  398. if (a.y0 < b.y0)
  399. a.y0 = b.y0;
  400. if (a.x1 > b.x1)
  401. a.x1 = b.x1;
  402. if (a.y1 > b.y1)
  403. a.y1 = b.y1;
  404. return a;
  405. }
  406. fz_irect
  407. fz_intersect_irect(fz_irect a, fz_irect b)
  408. {
  409. if (fz_is_infinite_irect(b)) return a;
  410. if (fz_is_infinite_irect(a)) return b;
  411. if (a.x0 < b.x0)
  412. a.x0 = b.x0;
  413. if (a.y0 < b.y0)
  414. a.y0 = b.y0;
  415. if (a.x1 > b.x1)
  416. a.x1 = b.x1;
  417. if (a.y1 > b.y1)
  418. a.y1 = b.y1;
  419. return a;
  420. }
  421. fz_rect
  422. fz_union_rect(fz_rect a, fz_rect b)
  423. {
  424. /* Check for empty box before infinite box */
  425. if (!fz_is_valid_rect(b)) return a;
  426. if (!fz_is_valid_rect(a)) return b;
  427. if (fz_is_infinite_rect(a)) return a;
  428. if (fz_is_infinite_rect(b)) return b;
  429. if (a.x0 > b.x0)
  430. a.x0 = b.x0;
  431. if (a.y0 > b.y0)
  432. a.y0 = b.y0;
  433. if (a.x1 < b.x1)
  434. a.x1 = b.x1;
  435. if (a.y1 < b.y1)
  436. a.y1 = b.y1;
  437. return a;
  438. }
  439. fz_rect
  440. fz_translate_rect(fz_rect a, float xoff, float yoff)
  441. {
  442. if (fz_is_infinite_rect(a)) return a;
  443. a.x0 += xoff;
  444. a.y0 += yoff;
  445. a.x1 += xoff;
  446. a.y1 += yoff;
  447. return a;
  448. }
  449. fz_irect
  450. fz_translate_irect(fz_irect a, int xoff, int yoff)
  451. {
  452. int t;
  453. if (fz_is_empty_irect(a)) return a;
  454. if (fz_is_infinite_irect(a)) return a;
  455. a.x0 = ADD_WITH_SAT(t, a.x0, xoff);
  456. a.y0 = ADD_WITH_SAT(t, a.y0, yoff);
  457. a.x1 = ADD_WITH_SAT(t, a.x1, xoff);
  458. a.y1 = ADD_WITH_SAT(t, a.y1, yoff);
  459. return a;
  460. }
  461. fz_rect
  462. fz_transform_rect(fz_rect r, fz_matrix m)
  463. {
  464. fz_point s, t, u, v;
  465. int invalid;
  466. if (fz_is_infinite_rect(r))
  467. return r;
  468. if (fabsf(m.b) < FLT_EPSILON && fabsf(m.c) < FLT_EPSILON)
  469. {
  470. if (m.a < 0)
  471. {
  472. float f = r.x0;
  473. r.x0 = r.x1;
  474. r.x1 = f;
  475. }
  476. if (m.d < 0)
  477. {
  478. float f = r.y0;
  479. r.y0 = r.y1;
  480. r.y1 = f;
  481. }
  482. s = fz_transform_point_xy(r.x0, r.y0, m);
  483. t = fz_transform_point_xy(r.x1, r.y1, m);
  484. r.x0 = s.x; r.y0 = s.y;
  485. r.x1 = t.x; r.y1 = t.y;
  486. /* If r was invalid coming in, it'll still be invalid now. */
  487. return r;
  488. }
  489. else if (fabsf(m.a) < FLT_EPSILON && fabsf(m.d) < FLT_EPSILON)
  490. {
  491. if (m.b < 0)
  492. {
  493. float f = r.x0;
  494. r.x0 = r.x1;
  495. r.x1 = f;
  496. }
  497. if (m.c < 0)
  498. {
  499. float f = r.y0;
  500. r.y0 = r.y1;
  501. r.y1 = f;
  502. }
  503. s = fz_transform_point_xy(r.x0, r.y0, m);
  504. t = fz_transform_point_xy(r.x1, r.y1, m);
  505. r.x0 = s.x; r.y0 = s.y;
  506. r.x1 = t.x; r.y1 = t.y;
  507. /* If r was invalid coming in, it'll still be invalid now. */
  508. return r;
  509. }
  510. invalid = (r.x0 > r.x1) || (r.y0 > r.y1);
  511. s.x = r.x0; s.y = r.y0;
  512. t.x = r.x0; t.y = r.y1;
  513. u.x = r.x1; u.y = r.y1;
  514. v.x = r.x1; v.y = r.y0;
  515. s = fz_transform_point(s, m);
  516. t = fz_transform_point(t, m);
  517. u = fz_transform_point(u, m);
  518. v = fz_transform_point(v, m);
  519. r.x0 = MIN4(s.x, t.x, u.x, v.x);
  520. r.y0 = MIN4(s.y, t.y, u.y, v.y);
  521. r.x1 = MAX4(s.x, t.x, u.x, v.x);
  522. r.y1 = MAX4(s.y, t.y, u.y, v.y);
  523. /* If we were called with an invalid rectangle, return an
  524. * invalid rectangle after transformation. */
  525. if (invalid)
  526. {
  527. float f;
  528. f = r.x0; r.x0 = r.x1; r.x1 = f;
  529. f = r.y0; r.y0 = r.y1; r.y1 = f;
  530. }
  531. return r;
  532. }
  533. fz_irect
  534. fz_expand_irect(fz_irect a, int expand)
  535. {
  536. if (fz_is_infinite_irect(a)) return a;
  537. if (!fz_is_valid_irect(a)) return a;
  538. a.x0 -= expand;
  539. a.y0 -= expand;
  540. a.x1 += expand;
  541. a.y1 += expand;
  542. return a;
  543. }
  544. fz_rect
  545. fz_expand_rect(fz_rect a, float expand)
  546. {
  547. if (fz_is_infinite_rect(a)) return a;
  548. if (!fz_is_valid_rect(a)) return a;
  549. a.x0 -= expand;
  550. a.y0 -= expand;
  551. a.x1 += expand;
  552. a.y1 += expand;
  553. return a;
  554. }
  555. /* Adding a point to an invalid rectangle makes the zero area rectangle
  556. * that contains just that point. */
  557. fz_rect fz_include_point_in_rect(fz_rect r, fz_point p)
  558. {
  559. if (fz_is_infinite_rect(r)) return r;
  560. if (p.x < r.x0) r.x0 = p.x;
  561. if (p.x > r.x1) r.x1 = p.x;
  562. if (p.y < r.y0) r.y0 = p.y;
  563. if (p.y > r.y1) r.y1 = p.y;
  564. return r;
  565. }
  566. int fz_contains_rect(fz_rect a, fz_rect b)
  567. {
  568. /* An invalid rect can't contain anything */
  569. if (!fz_is_valid_rect(a))
  570. return 0;
  571. /* Any valid rect contains all invalid rects */
  572. if (!fz_is_valid_rect(b))
  573. return 1;
  574. return ((a.x0 <= b.x0) &&
  575. (a.y0 <= b.y0) &&
  576. (a.x1 >= b.x1) &&
  577. (a.y1 >= b.y1));
  578. }
  579. int
  580. fz_is_valid_quad(fz_quad q)
  581. {
  582. return (!isnan(q.ll.x) &&
  583. !isnan(q.ll.y) &&
  584. !isnan(q.ul.x) &&
  585. !isnan(q.ul.y) &&
  586. !isnan(q.lr.x) &&
  587. !isnan(q.lr.y) &&
  588. !isnan(q.ur.x) &&
  589. !isnan(q.ur.y));
  590. }
  591. int
  592. fz_is_infinite_quad(fz_quad q)
  593. {
  594. /* For a quad to be infinite, all the ordinates need to be infinite. */
  595. if (!isinf(q.ll.x) ||
  596. !isinf(q.ll.y) ||
  597. !isinf(q.ul.x) ||
  598. !isinf(q.ul.y) ||
  599. !isinf(q.lr.x) ||
  600. !isinf(q.lr.y) ||
  601. !isinf(q.ur.x) ||
  602. !isinf(q.ur.y))
  603. return 0;
  604. /* Just because all the ordinates are infinite, we don't necessarily have an infinite quad. */
  605. /* The quad points in order are: ll, ul, ur, lr OR reversed: ll, lr, ur, ul */
  606. /* The required points are: (-inf, -inf) (-inf, inf) (inf, inf) (inf, -inf) */
  607. /* Not the fastest way to code it, but easy to understand! */
  608. #define INF_QUAD_TEST(A,B,C,D) \
  609. if (q.A.x < 0 && q.A.y < 0 && q.B.x < 0 && q.B.y > 0 && q.C.x > 0 && q.C.y > 0 && q.D.x > 0 && q.D.y < 0) return 1
  610. INF_QUAD_TEST(ll, ul, ur, lr);
  611. INF_QUAD_TEST(ul, ur, lr, ll);
  612. INF_QUAD_TEST(ur, lr, ll, ul);
  613. INF_QUAD_TEST(lr, ll, ul, ur);
  614. INF_QUAD_TEST(ll, lr, ur, ul);
  615. INF_QUAD_TEST(lr, ur, ul, ll);
  616. INF_QUAD_TEST(ur, ul, ll, lr);
  617. INF_QUAD_TEST(ul, ll, lr, ur);
  618. #undef INF_QUAD_TEST
  619. return 0;
  620. }
  621. int fz_is_empty_quad(fz_quad q)
  622. {
  623. /* Using "Shoelace" formula */
  624. float area;
  625. if (fz_is_infinite_quad(q))
  626. return 0;
  627. if (!fz_is_valid_quad(q))
  628. return 1; /* All invalid quads are empty */
  629. area = q.ll.x * q.lr.y +
  630. q.lr.x * q.ur.y +
  631. q.ur.x * q.ul.y +
  632. q.ul.x * q.ll.y -
  633. q.lr.x * q.ll.y -
  634. q.ur.x * q.lr.y -
  635. q.ul.x * q.ur.y -
  636. q.ll.x * q.ul.y;
  637. return area == 0;
  638. }
  639. fz_rect
  640. fz_rect_from_quad(fz_quad q)
  641. {
  642. fz_rect r;
  643. if (!fz_is_valid_quad(q))
  644. return fz_invalid_rect;
  645. if (fz_is_infinite_quad(q))
  646. return fz_infinite_rect;
  647. r.x0 = MIN4(q.ll.x, q.lr.x, q.ul.x, q.ur.x);
  648. r.y0 = MIN4(q.ll.y, q.lr.y, q.ul.y, q.ur.y);
  649. r.x1 = MAX4(q.ll.x, q.lr.x, q.ul.x, q.ur.x);
  650. r.y1 = MAX4(q.ll.y, q.lr.y, q.ul.y, q.ur.y);
  651. return r;
  652. }
  653. fz_quad
  654. fz_transform_quad(fz_quad q, fz_matrix m)
  655. {
  656. if (!fz_is_valid_quad(q))
  657. return q;
  658. if (fz_is_infinite_quad(q))
  659. return q;
  660. q.ul = fz_transform_point(q.ul, m);
  661. q.ur = fz_transform_point(q.ur, m);
  662. q.ll = fz_transform_point(q.ll, m);
  663. q.lr = fz_transform_point(q.lr, m);
  664. return q;
  665. }
  666. fz_quad
  667. fz_quad_from_rect(fz_rect r)
  668. {
  669. fz_quad q;
  670. if (!fz_is_valid_rect(r))
  671. return fz_invalid_quad;
  672. if (fz_is_infinite_rect(r))
  673. return fz_infinite_quad;
  674. q.ul = fz_make_point(r.x0, r.y0);
  675. q.ur = fz_make_point(r.x1, r.y0);
  676. q.ll = fz_make_point(r.x0, r.y1);
  677. q.lr = fz_make_point(r.x1, r.y1);
  678. return q;
  679. }
  680. int fz_is_point_inside_rect(fz_point p, fz_rect r)
  681. {
  682. return (p.x >= r.x0 && p.x < r.x1 && p.y >= r.y0 && p.y < r.y1);
  683. }
  684. int fz_is_point_inside_irect(int x, int y, fz_irect r)
  685. {
  686. return (x >= r.x0 && x < r.x1 && y >= r.y0 && y < r.y1);
  687. }
  688. int fz_is_rect_inside_rect(fz_rect inner, fz_rect outer)
  689. {
  690. if (!fz_is_valid_rect(outer))
  691. return 0;
  692. if (!fz_is_valid_rect(inner))
  693. return 0;
  694. if (inner.x0 >= outer.x0 && inner.x1 <= outer.x1 && inner.y0 >= outer.y0 && inner.y1 <= outer.y1)
  695. return 1;
  696. return 0;
  697. }
  698. int fz_is_irect_inside_irect(fz_irect inner, fz_irect outer)
  699. {
  700. if (!fz_is_valid_irect(outer))
  701. return 0;
  702. if (!fz_is_valid_irect(inner))
  703. return 0;
  704. if (inner.x0 >= outer.x0 && inner.x1 <= outer.x1 && inner.y0 >= outer.y0 && inner.y1 <= outer.y1)
  705. return 1;
  706. return 0;
  707. }
  708. /* cross (b-a) with (p-a) */
  709. static float
  710. cross(fz_point a, fz_point b, fz_point p)
  711. {
  712. b.x -= a.x;
  713. b.y -= a.y;
  714. p.x -= a.x;
  715. p.y -= a.y;
  716. return b.x * p.y - b.y * p.x;
  717. }
  718. static int fz_is_point_inside_triangle(fz_point p, fz_point a, fz_point b, fz_point c)
  719. {
  720. /* Consider the following:
  721. *
  722. * P
  723. * /|
  724. * / |
  725. * / |
  726. * A +---+-------+ B
  727. * M
  728. *
  729. * The cross product of vector AB and vector AP is the distance PM.
  730. * The sign of this distance depends on what side of the line AB, P lies on.
  731. *
  732. * So, for a triangle ABC, if we take cross products of:
  733. *
  734. * AB and AP
  735. * BC and BP
  736. * CA and CP
  737. *
  738. * P can only be inside the triangle if the signs are all identical.
  739. *
  740. * One of the cross products being 0 indicates that the point is on a line.
  741. * Two of the cross products being 0 indicates that the point is on a vertex.
  742. *
  743. * If 2 of the vertices are the same, the algorithm still works.
  744. * Iff all 3 of the vertices are the same, the cross products are all zero. The
  745. * value of p is irrelevant.
  746. */
  747. float crossa = cross(a, b, p);
  748. float crossb = cross(b, c, p);
  749. float crossc = cross(c, a, p);
  750. /* Check for degenerate case. All vertices the same. */
  751. if (crossa == 0 && crossb == 0 && crossc == 0)
  752. return a.x == p.x && a.y == p.y;
  753. if (crossa >= 0 && crossb >= 0 && crossc >= 0)
  754. return 1;
  755. if (crossa <= 0 && crossb <= 0 && crossc <= 0)
  756. return 1;
  757. return 0;
  758. }
  759. int fz_is_point_inside_quad(fz_point p, fz_quad q)
  760. {
  761. if (!fz_is_valid_quad(q))
  762. return 0;
  763. if (fz_is_infinite_quad(q))
  764. return 1;
  765. return
  766. fz_is_point_inside_triangle(p, q.ul, q.ur, q.lr) ||
  767. fz_is_point_inside_triangle(p, q.ul, q.lr, q.ll);
  768. }
  769. int fz_is_quad_inside_quad(fz_quad needle, fz_quad haystack)
  770. {
  771. if (!fz_is_valid_quad(needle) || !fz_is_valid_quad(haystack))
  772. return 0;
  773. if (fz_is_infinite_quad(haystack))
  774. return 1;
  775. return
  776. fz_is_point_inside_quad(needle.ul, haystack) &&
  777. fz_is_point_inside_quad(needle.ur, haystack) &&
  778. fz_is_point_inside_quad(needle.ll, haystack) &&
  779. fz_is_point_inside_quad(needle.lr, haystack);
  780. }
  781. int fz_is_quad_intersecting_quad(fz_quad a, fz_quad b)
  782. {
  783. fz_rect ar = fz_rect_from_quad(a);
  784. fz_rect br = fz_rect_from_quad(b);
  785. return !fz_is_empty_rect(fz_intersect_rect(ar, br));
  786. }