Mercurial > hgrepos > Python2 > PyMuPDF
comparison mupdf-source/include/mupdf/fitz/geometry.h @ 2:b50eed0cc0ef upstream
ADD: MuPDF v1.26.7: the MuPDF source as downloaded by a default build of PyMuPDF 1.26.4.
The directory name has changed: no version number in the expanded directory now.
| author | Franz Glasner <fzglas.hg@dom66.de> |
|---|---|
| date | Mon, 15 Sep 2025 11:43:07 +0200 |
| parents | |
| children |
comparison
equal
deleted
inserted
replaced
| 1:1d09e1dec1d9 | 2:b50eed0cc0ef |
|---|---|
| 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 | |
| 23 #ifndef MUPDF_FITZ_MATH_H | |
| 24 #define MUPDF_FITZ_MATH_H | |
| 25 | |
| 26 #include "mupdf/fitz/system.h" | |
| 27 | |
| 28 #include <math.h> | |
| 29 #include <assert.h> | |
| 30 | |
| 31 #ifndef M_PI | |
| 32 #define M_PI 3.14159265358979323846 | |
| 33 #endif | |
| 34 | |
| 35 /** | |
| 36 Multiply scaled two integers in the 0..255 range | |
| 37 */ | |
| 38 static inline int fz_mul255(int a, int b) | |
| 39 { | |
| 40 /* see Jim Blinn's book "Dirty Pixels" for how this works */ | |
| 41 int x = a * b + 128; | |
| 42 x += x >> 8; | |
| 43 return x >> 8; | |
| 44 } | |
| 45 | |
| 46 /** | |
| 47 Undo alpha premultiplication. | |
| 48 */ | |
| 49 static inline int fz_div255(int c, int a) | |
| 50 { | |
| 51 return a ? c * (255 * 256 / a) >> 8 : 0; | |
| 52 } | |
| 53 | |
| 54 /** | |
| 55 Expand a value A from the 0...255 range to the 0..256 range | |
| 56 */ | |
| 57 #define FZ_EXPAND(A) ((A)+((A)>>7)) | |
| 58 | |
| 59 /** | |
| 60 Combine values A (in any range) and B (in the 0..256 range), | |
| 61 to give a single value in the same range as A was. | |
| 62 */ | |
| 63 #define FZ_COMBINE(A,B) (((A)*(B))>>8) | |
| 64 | |
| 65 /** | |
| 66 Combine values A and C (in the same (any) range) and B and D (in | |
| 67 the 0..256 range), to give a single value in the same range as A | |
| 68 and C were. | |
| 69 */ | |
| 70 #define FZ_COMBINE2(A,B,C,D) (((A) * (B) + (C) * (D))>>8) | |
| 71 | |
| 72 /** | |
| 73 Blend SRC and DST (in the same range) together according to | |
| 74 AMOUNT (in the 0...256 range). | |
| 75 */ | |
| 76 #define FZ_BLEND(SRC, DST, AMOUNT) ((((SRC)-(DST))*(AMOUNT) + ((DST)<<8))>>8) | |
| 77 | |
| 78 /** | |
| 79 Range checking atof | |
| 80 */ | |
| 81 float fz_atof(const char *s); | |
| 82 | |
| 83 /** | |
| 84 atoi that copes with NULL | |
| 85 */ | |
| 86 int fz_atoi(const char *s); | |
| 87 | |
| 88 /** | |
| 89 64bit atoi that copes with NULL | |
| 90 */ | |
| 91 int64_t fz_atoi64(const char *s); | |
| 92 | |
| 93 /** | |
| 94 size_t atoi that copes with NULL. | |
| 95 | |
| 96 NOTE: limited to 63bits. Negative numbers | |
| 97 are returned as 0. | |
| 98 */ | |
| 99 size_t fz_atoz(const char *s); | |
| 100 | |
| 101 /** | |
| 102 Some standard math functions, done as static inlines for speed. | |
| 103 People with compilers that do not adequately implement inline | |
| 104 may like to reimplement these using macros. | |
| 105 */ | |
| 106 static inline float fz_abs(float f) | |
| 107 { | |
| 108 return (f < 0 ? -f : f); | |
| 109 } | |
| 110 | |
| 111 static inline int fz_absi(int i) | |
| 112 { | |
| 113 return (i < 0 ? -i : i); | |
| 114 } | |
| 115 | |
| 116 static inline float fz_min(float a, float b) | |
| 117 { | |
| 118 return (a < b ? a : b); | |
| 119 } | |
| 120 | |
| 121 static inline int fz_mini(int a, int b) | |
| 122 { | |
| 123 return (a < b ? a : b); | |
| 124 } | |
| 125 | |
| 126 static inline size_t fz_minz(size_t a, size_t b) | |
| 127 { | |
| 128 return (a < b ? a : b); | |
| 129 } | |
| 130 | |
| 131 static inline int64_t fz_mini64(int64_t a, int64_t b) | |
| 132 { | |
| 133 return (a < b ? a : b); | |
| 134 } | |
| 135 | |
| 136 static inline float fz_max(float a, float b) | |
| 137 { | |
| 138 return (a > b ? a : b); | |
| 139 } | |
| 140 | |
| 141 static inline int fz_maxi(int a, int b) | |
| 142 { | |
| 143 return (a > b ? a : b); | |
| 144 } | |
| 145 | |
| 146 static inline size_t fz_maxz(size_t a, size_t b) | |
| 147 { | |
| 148 return (a > b ? a : b); | |
| 149 } | |
| 150 | |
| 151 static inline int64_t fz_maxi64(int64_t a, int64_t b) | |
| 152 { | |
| 153 return (a > b ? a : b); | |
| 154 } | |
| 155 | |
| 156 static inline float fz_clamp(float x, float min, float max) | |
| 157 { | |
| 158 return x < min ? min : x > max ? max : x; | |
| 159 } | |
| 160 | |
| 161 static inline int fz_clampi(int x, int min, int max) | |
| 162 { | |
| 163 return x < min ? min : x > max ? max : x; | |
| 164 } | |
| 165 | |
| 166 static inline int64_t fz_clamp64(int64_t x, int64_t min, int64_t max) | |
| 167 { | |
| 168 return x < min ? min : x > max ? max : x; | |
| 169 } | |
| 170 | |
| 171 static inline double fz_clampd(double x, double min, double max) | |
| 172 { | |
| 173 return x < min ? min : x > max ? max : x; | |
| 174 } | |
| 175 | |
| 176 static inline void *fz_clampp(void *x, void *min, void *max) | |
| 177 { | |
| 178 return x < min ? min : x > max ? max : x; | |
| 179 } | |
| 180 | |
| 181 #define DIV_BY_ZERO(a, b, min, max) (((a) < 0) ^ ((b) < 0) ? (min) : (max)) | |
| 182 | |
| 183 /** | |
| 184 fz_point is a point in a two-dimensional space. | |
| 185 */ | |
| 186 typedef struct | |
| 187 { | |
| 188 float x, y; | |
| 189 } fz_point; | |
| 190 | |
| 191 static inline fz_point fz_make_point(float x, float y) | |
| 192 { | |
| 193 fz_point p = { x, y }; | |
| 194 return p; | |
| 195 } | |
| 196 | |
| 197 /** | |
| 198 fz_rect is a rectangle represented by two diagonally opposite | |
| 199 corners at arbitrary coordinates. | |
| 200 | |
| 201 Rectangles are always axis-aligned with the X- and Y- axes. We | |
| 202 wish to distinguish rectangles in 3 categories; infinite, finite, | |
| 203 and invalid. Zero area rectangles are a sub-category of finite | |
| 204 ones. | |
| 205 | |
| 206 For all valid rectangles, x0 <= x1 and y0 <= y1 in all cases. | |
| 207 Infinite rectangles have x0 = y0 = FZ_MIN_INF_RECT, | |
| 208 x1 = y1 = FZ_MAX_INF_RECT. For any non infinite valid rectangle, | |
| 209 the area is defined as (x1 - x0) * (y1 - y0). | |
| 210 | |
| 211 To check for empty or infinite rectangles use fz_is_empty_rect | |
| 212 and fz_is_infinite_rect. To check for valid rectangles use | |
| 213 fz_is_valid_rect. | |
| 214 | |
| 215 We choose this representation, so that we can easily distinguish | |
| 216 the difference between intersecting 2 valid rectangles and | |
| 217 getting an invalid one, as opposed to getting a zero area one | |
| 218 (which nonetheless has valid bounds within the plane). | |
| 219 | |
| 220 x0, y0: The top left corner. | |
| 221 | |
| 222 x1, y1: The bottom right corner. | |
| 223 | |
| 224 We choose FZ_{MIN,MAX}_INF_RECT to be the largest 32bit signed | |
| 225 integer values that survive roundtripping to floats. | |
| 226 */ | |
| 227 #define FZ_MIN_INF_RECT ((int)0x80000000) | |
| 228 #define FZ_MAX_INF_RECT ((int)0x7fffff80) | |
| 229 | |
| 230 typedef struct | |
| 231 { | |
| 232 float x0, y0; | |
| 233 float x1, y1; | |
| 234 } fz_rect; | |
| 235 | |
| 236 static inline fz_rect fz_make_rect(float x0, float y0, float x1, float y1) | |
| 237 { | |
| 238 fz_rect r = { x0, y0, x1, y1 }; | |
| 239 return r; | |
| 240 } | |
| 241 | |
| 242 /** | |
| 243 fz_irect is a rectangle using integers instead of floats. | |
| 244 | |
| 245 It's used in the draw device and for pixmap dimensions. | |
| 246 */ | |
| 247 typedef struct | |
| 248 { | |
| 249 int x0, y0; | |
| 250 int x1, y1; | |
| 251 } fz_irect; | |
| 252 | |
| 253 static inline fz_irect fz_make_irect(int x0, int y0, int x1, int y1) | |
| 254 { | |
| 255 fz_irect r = { x0, y0, x1, y1 }; | |
| 256 return r; | |
| 257 } | |
| 258 | |
| 259 /** | |
| 260 A rectangle with sides of length one. | |
| 261 | |
| 262 The bottom left corner is at (0, 0) and the top right corner | |
| 263 is at (1, 1). | |
| 264 */ | |
| 265 FZ_DATA extern const fz_rect fz_unit_rect; | |
| 266 | |
| 267 /** | |
| 268 An empty rectangle with an area equal to zero. | |
| 269 */ | |
| 270 FZ_DATA extern const fz_rect fz_empty_rect; | |
| 271 FZ_DATA extern const fz_irect fz_empty_irect; | |
| 272 | |
| 273 /** | |
| 274 An infinite rectangle. | |
| 275 */ | |
| 276 FZ_DATA extern const fz_rect fz_infinite_rect; | |
| 277 FZ_DATA extern const fz_irect fz_infinite_irect; | |
| 278 | |
| 279 /** | |
| 280 An invalid rectangle. | |
| 281 */ | |
| 282 FZ_DATA extern const fz_rect fz_invalid_rect; | |
| 283 FZ_DATA extern const fz_irect fz_invalid_irect; | |
| 284 | |
| 285 /** | |
| 286 Check if rectangle is empty. | |
| 287 | |
| 288 An empty rectangle is defined as one whose area is zero. | |
| 289 All invalid rectangles are empty. | |
| 290 */ | |
| 291 static inline int fz_is_empty_rect(fz_rect r) | |
| 292 { | |
| 293 return (r.x0 >= r.x1 || r.y0 >= r.y1); | |
| 294 } | |
| 295 | |
| 296 static inline int fz_is_empty_irect(fz_irect r) | |
| 297 { | |
| 298 return (r.x0 >= r.x1 || r.y0 >= r.y1); | |
| 299 } | |
| 300 | |
| 301 /** | |
| 302 Check if rectangle is infinite. | |
| 303 */ | |
| 304 static inline int fz_is_infinite_rect(fz_rect r) | |
| 305 { | |
| 306 return (r.x0 == FZ_MIN_INF_RECT && r.x1 == FZ_MAX_INF_RECT && | |
| 307 r.y0 == FZ_MIN_INF_RECT && r.y1 == FZ_MAX_INF_RECT); | |
| 308 } | |
| 309 | |
| 310 /** | |
| 311 Check if an integer rectangle | |
| 312 is infinite. | |
| 313 */ | |
| 314 static inline int fz_is_infinite_irect(fz_irect r) | |
| 315 { | |
| 316 return (r.x0 == FZ_MIN_INF_RECT && r.x1 == FZ_MAX_INF_RECT && | |
| 317 r.y0 == FZ_MIN_INF_RECT && r.y1 == FZ_MAX_INF_RECT); | |
| 318 } | |
| 319 | |
| 320 /** | |
| 321 Check if rectangle is valid. | |
| 322 */ | |
| 323 static inline int fz_is_valid_rect(fz_rect r) | |
| 324 { | |
| 325 return (r.x0 <= r.x1 && r.y0 <= r.y1); | |
| 326 } | |
| 327 | |
| 328 /** | |
| 329 Check if an integer rectangle is valid. | |
| 330 */ | |
| 331 static inline int fz_is_valid_irect(fz_irect r) | |
| 332 { | |
| 333 return (r.x0 <= r.x1 && r.y0 <= r.y1); | |
| 334 } | |
| 335 | |
| 336 /** | |
| 337 Return the width of an irect. Invalid irects return 0. | |
| 338 */ | |
| 339 static inline unsigned int | |
| 340 fz_irect_width(fz_irect r) | |
| 341 { | |
| 342 unsigned int w; | |
| 343 if (r.x0 >= r.x1) | |
| 344 return 0; | |
| 345 /* Check for w overflowing. This should never happen, but | |
| 346 * if it does, it's pretty likely an indication of a severe | |
| 347 * problem. */ | |
| 348 w = (unsigned int)r.x1 - r.x0; | |
| 349 assert((int)w >= 0); | |
| 350 if ((int)w < 0) | |
| 351 return 0; | |
| 352 return (int)w; | |
| 353 } | |
| 354 | |
| 355 /** | |
| 356 Return the height of an irect. Invalid irects return 0. | |
| 357 */ | |
| 358 static inline int | |
| 359 fz_irect_height(fz_irect r) | |
| 360 { | |
| 361 unsigned int h; | |
| 362 if (r.y0 >= r.y1) | |
| 363 return 0; | |
| 364 /* Check for h overflowing. This should never happen, but | |
| 365 * if it does, it's pretty likely an indication of a severe | |
| 366 * problem. */ | |
| 367 h = (unsigned int)(r.y1 - r.y0); | |
| 368 assert((int)h >= 0); | |
| 369 if ((int)h < 0) | |
| 370 return 0; | |
| 371 return (int)h; | |
| 372 } | |
| 373 | |
| 374 /** | |
| 375 fz_matrix is a row-major 3x3 matrix used for representing | |
| 376 transformations of coordinates throughout MuPDF. | |
| 377 | |
| 378 Since all points reside in a two-dimensional space, one vector | |
| 379 is always a constant unit vector; hence only some elements may | |
| 380 vary in a matrix. Below is how the elements map between | |
| 381 different representations. | |
| 382 | |
| 383 / a b 0 \ | |
| 384 | c d 0 | normally represented as [ a b c d e f ]. | |
| 385 \ e f 1 / | |
| 386 */ | |
| 387 typedef struct | |
| 388 { | |
| 389 float a, b, c, d, e, f; | |
| 390 } fz_matrix; | |
| 391 | |
| 392 /** | |
| 393 Identity transform matrix. | |
| 394 */ | |
| 395 FZ_DATA extern const fz_matrix fz_identity; | |
| 396 | |
| 397 static inline fz_matrix fz_make_matrix(float a, float b, float c, float d, float e, float f) | |
| 398 { | |
| 399 fz_matrix m = { a, b, c, d, e, f }; | |
| 400 return m; | |
| 401 } | |
| 402 | |
| 403 static inline int fz_is_identity(fz_matrix m) | |
| 404 { | |
| 405 return m.a == 1 && m.b == 0 && m.c == 0 && m.d == 1 && m.e == 0 && m.f == 0; | |
| 406 } | |
| 407 | |
| 408 /** | |
| 409 Multiply two matrices. | |
| 410 | |
| 411 The order of the two matrices are important since matrix | |
| 412 multiplication is not commutative. | |
| 413 | |
| 414 Returns result. | |
| 415 */ | |
| 416 fz_matrix fz_concat(fz_matrix left, fz_matrix right); | |
| 417 | |
| 418 /** | |
| 419 Create a scaling matrix. | |
| 420 | |
| 421 The returned matrix is of the form [ sx 0 0 sy 0 0 ]. | |
| 422 | |
| 423 m: Pointer to the matrix to populate | |
| 424 | |
| 425 sx, sy: Scaling factors along the X- and Y-axes. A scaling | |
| 426 factor of 1.0 will not cause any scaling along the relevant | |
| 427 axis. | |
| 428 | |
| 429 Returns m. | |
| 430 */ | |
| 431 fz_matrix fz_scale(float sx, float sy); | |
| 432 | |
| 433 /** | |
| 434 Scale a matrix by premultiplication. | |
| 435 | |
| 436 m: Pointer to the matrix to scale | |
| 437 | |
| 438 sx, sy: Scaling factors along the X- and Y-axes. A scaling | |
| 439 factor of 1.0 will not cause any scaling along the relevant | |
| 440 axis. | |
| 441 | |
| 442 Returns m (updated). | |
| 443 */ | |
| 444 fz_matrix fz_pre_scale(fz_matrix m, float sx, float sy); | |
| 445 | |
| 446 /** | |
| 447 Scale a matrix by postmultiplication. | |
| 448 | |
| 449 m: Pointer to the matrix to scale | |
| 450 | |
| 451 sx, sy: Scaling factors along the X- and Y-axes. A scaling | |
| 452 factor of 1.0 will not cause any scaling along the relevant | |
| 453 axis. | |
| 454 | |
| 455 Returns m (updated). | |
| 456 */ | |
| 457 fz_matrix fz_post_scale(fz_matrix m, float sx, float sy); | |
| 458 | |
| 459 /** | |
| 460 Create a shearing matrix. | |
| 461 | |
| 462 The returned matrix is of the form [ 1 sy sx 1 0 0 ]. | |
| 463 | |
| 464 m: pointer to place to store returned matrix | |
| 465 | |
| 466 sx, sy: Shearing factors. A shearing factor of 0.0 will not | |
| 467 cause any shearing along the relevant axis. | |
| 468 | |
| 469 Returns m. | |
| 470 */ | |
| 471 fz_matrix fz_shear(float sx, float sy); | |
| 472 | |
| 473 /** | |
| 474 Premultiply a matrix with a shearing matrix. | |
| 475 | |
| 476 The shearing matrix is of the form [ 1 sy sx 1 0 0 ]. | |
| 477 | |
| 478 m: pointer to matrix to premultiply | |
| 479 | |
| 480 sx, sy: Shearing factors. A shearing factor of 0.0 will not | |
| 481 cause any shearing along the relevant axis. | |
| 482 | |
| 483 Returns m (updated). | |
| 484 */ | |
| 485 fz_matrix fz_pre_shear(fz_matrix m, float sx, float sy); | |
| 486 | |
| 487 /** | |
| 488 Create a rotation matrix. | |
| 489 | |
| 490 The returned matrix is of the form | |
| 491 [ cos(deg) sin(deg) -sin(deg) cos(deg) 0 0 ]. | |
| 492 | |
| 493 m: Pointer to place to store matrix | |
| 494 | |
| 495 degrees: Degrees of counter clockwise rotation. Values less | |
| 496 than zero and greater than 360 are handled as expected. | |
| 497 | |
| 498 Returns m. | |
| 499 */ | |
| 500 fz_matrix fz_rotate(float degrees); | |
| 501 | |
| 502 /** | |
| 503 Rotate a transformation by premultiplying. | |
| 504 | |
| 505 The premultiplied matrix is of the form | |
| 506 [ cos(deg) sin(deg) -sin(deg) cos(deg) 0 0 ]. | |
| 507 | |
| 508 m: Pointer to matrix to premultiply. | |
| 509 | |
| 510 degrees: Degrees of counter clockwise rotation. Values less | |
| 511 than zero and greater than 360 are handled as expected. | |
| 512 | |
| 513 Returns m (updated). | |
| 514 */ | |
| 515 fz_matrix fz_pre_rotate(fz_matrix m, float degrees); | |
| 516 | |
| 517 /** | |
| 518 Create a translation matrix. | |
| 519 | |
| 520 The returned matrix is of the form [ 1 0 0 1 tx ty ]. | |
| 521 | |
| 522 m: A place to store the created matrix. | |
| 523 | |
| 524 tx, ty: Translation distances along the X- and Y-axes. A | |
| 525 translation of 0 will not cause any translation along the | |
| 526 relevant axis. | |
| 527 | |
| 528 Returns m. | |
| 529 */ | |
| 530 fz_matrix fz_translate(float tx, float ty); | |
| 531 | |
| 532 /** | |
| 533 Translate a matrix by premultiplication. | |
| 534 | |
| 535 m: The matrix to translate | |
| 536 | |
| 537 tx, ty: Translation distances along the X- and Y-axes. A | |
| 538 translation of 0 will not cause any translation along the | |
| 539 relevant axis. | |
| 540 | |
| 541 Returns m. | |
| 542 */ | |
| 543 fz_matrix fz_pre_translate(fz_matrix m, float tx, float ty); | |
| 544 | |
| 545 /** | |
| 546 Create transform matrix to draw page | |
| 547 at a given resolution and rotation. Adjusts the scaling | |
| 548 factors so that the page covers whole number of | |
| 549 pixels and adjust the page origin to be at 0,0. | |
| 550 */ | |
| 551 fz_matrix fz_transform_page(fz_rect mediabox, float resolution, float rotate); | |
| 552 | |
| 553 /** | |
| 554 Create an inverse matrix. | |
| 555 | |
| 556 matrix: Matrix to invert. A degenerate matrix, where the | |
| 557 determinant is equal to zero, can not be inverted and the | |
| 558 original matrix is returned instead. | |
| 559 | |
| 560 Returns inverse. | |
| 561 */ | |
| 562 fz_matrix fz_invert_matrix(fz_matrix matrix); | |
| 563 | |
| 564 /** | |
| 565 Attempt to create an inverse matrix. | |
| 566 | |
| 567 inv: Place to store inverse matrix. | |
| 568 | |
| 569 src: Matrix to invert. A degenerate matrix, where the | |
| 570 determinant is equal to zero, can not be inverted. | |
| 571 | |
| 572 Returns 1 if matrix is degenerate (singular), or 0 otherwise. | |
| 573 */ | |
| 574 int fz_try_invert_matrix(fz_matrix *inv, fz_matrix src); | |
| 575 | |
| 576 /** | |
| 577 Check if a transformation is rectilinear. | |
| 578 | |
| 579 Rectilinear means that no shearing is present and that any | |
| 580 rotations present are a multiple of 90 degrees. Usually this | |
| 581 is used to make sure that axis-aligned rectangles before the | |
| 582 transformation are still axis-aligned rectangles afterwards. | |
| 583 */ | |
| 584 int fz_is_rectilinear(fz_matrix m); | |
| 585 | |
| 586 /** | |
| 587 Calculate average scaling factor of matrix. | |
| 588 */ | |
| 589 float fz_matrix_expansion(fz_matrix m); | |
| 590 | |
| 591 /** | |
| 592 Compute intersection of two rectangles. | |
| 593 | |
| 594 Given two rectangles, update the first to be the smallest | |
| 595 axis-aligned rectangle that covers the area covered by both | |
| 596 given rectangles. If either rectangle is empty then the | |
| 597 intersection is also empty. If either rectangle is infinite | |
| 598 then the intersection is simply the non-infinite rectangle. | |
| 599 Should both rectangles be infinite, then the intersection is | |
| 600 also infinite. | |
| 601 */ | |
| 602 fz_rect fz_intersect_rect(fz_rect a, fz_rect b); | |
| 603 | |
| 604 /** | |
| 605 Compute intersection of two bounding boxes. | |
| 606 | |
| 607 Similar to fz_intersect_rect but operates on two bounding | |
| 608 boxes instead of two rectangles. | |
| 609 */ | |
| 610 fz_irect fz_intersect_irect(fz_irect a, fz_irect b); | |
| 611 | |
| 612 /** | |
| 613 Compute union of two rectangles. | |
| 614 | |
| 615 Given two rectangles, update the first to be the smallest | |
| 616 axis-aligned rectangle that encompasses both given rectangles. | |
| 617 If either rectangle is infinite then the union is also infinite. | |
| 618 If either rectangle is empty then the union is simply the | |
| 619 non-empty rectangle. Should both rectangles be empty, then the | |
| 620 union is also empty. | |
| 621 */ | |
| 622 fz_rect fz_union_rect(fz_rect a, fz_rect b); | |
| 623 | |
| 624 /** | |
| 625 Convert a rect into the minimal bounding box | |
| 626 that covers the rectangle. | |
| 627 | |
| 628 Coordinates in a bounding box are integers, so rounding of the | |
| 629 rects coordinates takes place. The top left corner is rounded | |
| 630 upwards and left while the bottom right corner is rounded | |
| 631 downwards and to the right. | |
| 632 */ | |
| 633 fz_irect fz_irect_from_rect(fz_rect rect); | |
| 634 | |
| 635 /** | |
| 636 Round rectangle coordinates. | |
| 637 | |
| 638 Coordinates in a bounding box are integers, so rounding of the | |
| 639 rects coordinates takes place. The top left corner is rounded | |
| 640 upwards and left while the bottom right corner is rounded | |
| 641 downwards and to the right. | |
| 642 | |
| 643 This differs from fz_irect_from_rect, in that fz_irect_from_rect | |
| 644 slavishly follows the numbers (i.e any slight over/under | |
| 645 calculations can cause whole extra pixels to be added). | |
| 646 fz_round_rect allows for a small amount of rounding error when | |
| 647 calculating the bbox. | |
| 648 */ | |
| 649 fz_irect fz_round_rect(fz_rect rect); | |
| 650 | |
| 651 /** | |
| 652 Convert a bbox into a rect. | |
| 653 | |
| 654 For our purposes, a rect can represent all the values we meet in | |
| 655 a bbox, so nothing can go wrong. | |
| 656 | |
| 657 rect: A place to store the generated rectangle. | |
| 658 | |
| 659 bbox: The bbox to convert. | |
| 660 | |
| 661 Returns rect (updated). | |
| 662 */ | |
| 663 fz_rect fz_rect_from_irect(fz_irect bbox); | |
| 664 | |
| 665 /** | |
| 666 Expand a bbox by a given amount in all directions. | |
| 667 */ | |
| 668 fz_rect fz_expand_rect(fz_rect b, float expand); | |
| 669 fz_irect fz_expand_irect(fz_irect a, int expand); | |
| 670 | |
| 671 /** | |
| 672 Expand a bbox to include a given point. | |
| 673 To create a rectangle that encompasses a sequence of points, the | |
| 674 rectangle must first be set to be the empty rectangle at one of | |
| 675 the points before including the others. | |
| 676 */ | |
| 677 fz_rect fz_include_point_in_rect(fz_rect r, fz_point p); | |
| 678 | |
| 679 /** | |
| 680 Translate bounding box. | |
| 681 | |
| 682 Translate a bbox by a given x and y offset. Allows for overflow. | |
| 683 */ | |
| 684 fz_rect fz_translate_rect(fz_rect a, float xoff, float yoff); | |
| 685 fz_irect fz_translate_irect(fz_irect a, int xoff, int yoff); | |
| 686 | |
| 687 /** | |
| 688 Test rectangle inclusion. | |
| 689 | |
| 690 Return true if a entirely contains b. | |
| 691 */ | |
| 692 int fz_contains_rect(fz_rect a, fz_rect b); | |
| 693 | |
| 694 /** | |
| 695 Apply a transformation to a point. | |
| 696 | |
| 697 transform: Transformation matrix to apply. See fz_concat, | |
| 698 fz_scale, fz_rotate and fz_translate for how to create a | |
| 699 matrix. | |
| 700 | |
| 701 point: Pointer to point to update. | |
| 702 | |
| 703 Returns transform (unchanged). | |
| 704 */ | |
| 705 fz_point fz_transform_point(fz_point point, fz_matrix m); | |
| 706 fz_point fz_transform_point_xy(float x, float y, fz_matrix m); | |
| 707 | |
| 708 /** | |
| 709 Apply a transformation to a vector. | |
| 710 | |
| 711 transform: Transformation matrix to apply. See fz_concat, | |
| 712 fz_scale and fz_rotate for how to create a matrix. Any | |
| 713 translation will be ignored. | |
| 714 | |
| 715 vector: Pointer to vector to update. | |
| 716 */ | |
| 717 fz_point fz_transform_vector(fz_point vector, fz_matrix m); | |
| 718 | |
| 719 /** | |
| 720 Apply a transform to a rectangle. | |
| 721 | |
| 722 After the four corner points of the axis-aligned rectangle | |
| 723 have been transformed it may not longer be axis-aligned. So a | |
| 724 new axis-aligned rectangle is created covering at least the | |
| 725 area of the transformed rectangle. | |
| 726 | |
| 727 transform: Transformation matrix to apply. See fz_concat, | |
| 728 fz_scale and fz_rotate for how to create a matrix. | |
| 729 | |
| 730 rect: Rectangle to be transformed. The two special cases | |
| 731 fz_empty_rect and fz_infinite_rect, may be used but are | |
| 732 returned unchanged as expected. | |
| 733 */ | |
| 734 fz_rect fz_transform_rect(fz_rect rect, fz_matrix m); | |
| 735 | |
| 736 /** | |
| 737 Normalize a vector to length one. | |
| 738 */ | |
| 739 fz_point fz_normalize_vector(fz_point p); | |
| 740 | |
| 741 /** | |
| 742 Grid fit a matrix. | |
| 743 | |
| 744 as_tiled = 0 => adjust the matrix so that the image of the unit | |
| 745 square completely covers any pixel that was touched by the | |
| 746 image of the unit square under the original matrix. | |
| 747 | |
| 748 as_tiled = 1 => adjust the matrix so that the corners of the | |
| 749 image of the unit square align with the closest integer corner | |
| 750 of the image of the unit square under the original matrix. | |
| 751 */ | |
| 752 fz_matrix fz_gridfit_matrix(int as_tiled, fz_matrix m); | |
| 753 | |
| 754 /** | |
| 755 Find the largest expansion performed by this matrix. | |
| 756 (i.e. max(abs(m.a),abs(m.b),abs(m.c),abs(m.d)) | |
| 757 */ | |
| 758 float fz_matrix_max_expansion(fz_matrix m); | |
| 759 | |
| 760 /** | |
| 761 A representation for a region defined by 4 points. | |
| 762 | |
| 763 The significant difference between quads and rects is that | |
| 764 the edges of quads are not axis aligned. | |
| 765 */ | |
| 766 typedef struct | |
| 767 { | |
| 768 fz_point ul, ur, ll, lr; | |
| 769 } fz_quad; | |
| 770 | |
| 771 /** | |
| 772 Inline convenience construction function. | |
| 773 */ | |
| 774 static inline fz_quad fz_make_quad( | |
| 775 float ul_x, float ul_y, | |
| 776 float ur_x, float ur_y, | |
| 777 float ll_x, float ll_y, | |
| 778 float lr_x, float lr_y) | |
| 779 { | |
| 780 fz_quad q = { | |
| 781 { ul_x, ul_y }, | |
| 782 { ur_x, ur_y }, | |
| 783 { ll_x, ll_y }, | |
| 784 { lr_x, lr_y }, | |
| 785 }; | |
| 786 return q; | |
| 787 } | |
| 788 | |
| 789 FZ_DATA extern const fz_quad fz_invalid_quad; | |
| 790 FZ_DATA extern const fz_quad fz_infinite_quad; | |
| 791 | |
| 792 /** | |
| 793 Is a quad valid? | |
| 794 */ | |
| 795 int fz_is_valid_quad(fz_quad q); | |
| 796 | |
| 797 /** | |
| 798 Is a quad empty? | |
| 799 */ | |
| 800 int fz_is_empty_quad(fz_quad q); | |
| 801 | |
| 802 /** | |
| 803 Is a quad infinite? | |
| 804 */ | |
| 805 int fz_is_infinite_quad(fz_quad q); | |
| 806 | |
| 807 /** | |
| 808 Convert a rect to a quad (losslessly). | |
| 809 */ | |
| 810 fz_quad fz_quad_from_rect(fz_rect r); | |
| 811 | |
| 812 /** | |
| 813 Convert a quad to the smallest rect that covers it. | |
| 814 */ | |
| 815 fz_rect fz_rect_from_quad(fz_quad q); | |
| 816 | |
| 817 /** | |
| 818 Transform a quad by a matrix. | |
| 819 */ | |
| 820 fz_quad fz_transform_quad(fz_quad q, fz_matrix m); | |
| 821 | |
| 822 /** | |
| 823 Inclusion test for quads. | |
| 824 */ | |
| 825 int fz_is_point_inside_quad(fz_point p, fz_quad q); | |
| 826 | |
| 827 /** | |
| 828 Inclusion test for rects. (Rect is assumed to be open, i.e. | |
| 829 top right corner is not included). | |
| 830 */ | |
| 831 int fz_is_point_inside_rect(fz_point p, fz_rect r); | |
| 832 | |
| 833 /** | |
| 834 Inclusion test for irects. (Rect is assumed to be open, i.e. | |
| 835 top right corner is not included). | |
| 836 */ | |
| 837 int fz_is_point_inside_irect(int x, int y, fz_irect r); | |
| 838 | |
| 839 /** | |
| 840 Inclusion test for rects. | |
| 841 | |
| 842 rects are assumed to be both open or both closed. | |
| 843 | |
| 844 No invalid rect can include any other rect. | |
| 845 No invalid rect can be included by any rect. | |
| 846 Empty (point) rects can include themselves. | |
| 847 Empty (line) rects can include many (subline) rects. | |
| 848 */ | |
| 849 int fz_is_rect_inside_rect(fz_rect inner, fz_rect outer); | |
| 850 | |
| 851 /** | |
| 852 Inclusion test for irects. | |
| 853 | |
| 854 rects are assumed to be both open or both closed. | |
| 855 | |
| 856 No invalid rect can include any other rect. | |
| 857 No invalid rect can be included by any rect. | |
| 858 Empty (point) rects can include themselves. | |
| 859 Empty (line) rects can include many (subline) rects. | |
| 860 */ | |
| 861 int fz_is_irect_inside_irect(fz_irect inner, fz_irect outer); | |
| 862 | |
| 863 /** | |
| 864 Inclusion test for quad in quad. | |
| 865 | |
| 866 This may break down if quads are not 'well formed'. | |
| 867 */ | |
| 868 int fz_is_quad_inside_quad(fz_quad needle, fz_quad haystack); | |
| 869 | |
| 870 /** | |
| 871 Intersection test for quads. | |
| 872 | |
| 873 This may break down if quads are not 'well formed'. | |
| 874 */ | |
| 875 int fz_is_quad_intersecting_quad(fz_quad a, fz_quad b); | |
| 876 | |
| 877 #endif |
