init commit
This commit is contained in:
@@ -1,9 +1,33 @@
|
||||
// Copyright (C) 2004-2022 Artifex Software, Inc.
|
||||
//
|
||||
// This file is part of MuPDF.
|
||||
//
|
||||
// MuPDF is free software: you can redistribute it and/or modify it under the
|
||||
// terms of the GNU Affero General Public License as published by the Free
|
||||
// Software Foundation, either version 3 of the License, or (at your option)
|
||||
// any later version.
|
||||
//
|
||||
// MuPDF is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
// FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
|
||||
// details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with MuPDF. If not, see <https://www.gnu.org/licenses/agpl-3.0.en.html>
|
||||
//
|
||||
// Alternative licensing terms are available from the licensor.
|
||||
// For commercial licensing, see <https://www.artifex.com/> or contact
|
||||
// Artifex Software, Inc., 39 Mesa Street, Suite 108A, San Francisco,
|
||||
// CA 94129, USA, for further information.
|
||||
|
||||
#ifndef MUPDF_FITZ_MATH_H
|
||||
#define MUPDF_FITZ_MATH_H
|
||||
|
||||
#include "mupdf/fitz/system.h"
|
||||
|
||||
/*
|
||||
#include <assert.h>
|
||||
|
||||
/**
|
||||
Multiply scaled two integers in the 0..255 range
|
||||
*/
|
||||
static inline int fz_mul255(int a, int b)
|
||||
@@ -14,45 +38,57 @@ static inline int fz_mul255(int a, int b)
|
||||
return x >> 8;
|
||||
}
|
||||
|
||||
/*
|
||||
/**
|
||||
Undo alpha premultiplication.
|
||||
*/
|
||||
static inline int fz_div255(int c, int a)
|
||||
{
|
||||
return a ? c * (255 * 256 / a) >> 8 : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
Expand a value A from the 0...255 range to the 0..256 range
|
||||
*/
|
||||
#define FZ_EXPAND(A) ((A)+((A)>>7))
|
||||
|
||||
/*
|
||||
/**
|
||||
Combine values A (in any range) and B (in the 0..256 range),
|
||||
to give a single value in the same range as A was.
|
||||
*/
|
||||
#define FZ_COMBINE(A,B) (((A)*(B))>>8)
|
||||
|
||||
/*
|
||||
/**
|
||||
Combine values A and C (in the same (any) range) and B and D (in
|
||||
the 0..256 range), to give a single value in the same range as A
|
||||
and C were.
|
||||
*/
|
||||
#define FZ_COMBINE2(A,B,C,D) (((A) * (B) + (C) * (D))>>8)
|
||||
|
||||
/*
|
||||
/**
|
||||
Blend SRC and DST (in the same range) together according to
|
||||
AMOUNT (in the 0...256 range).
|
||||
*/
|
||||
#define FZ_BLEND(SRC, DST, AMOUNT) ((((SRC)-(DST))*(AMOUNT) + ((DST)<<8))>>8)
|
||||
|
||||
/*
|
||||
/**
|
||||
Range checking atof
|
||||
*/
|
||||
float fz_atof(const char *s);
|
||||
|
||||
/*
|
||||
/**
|
||||
atoi that copes with NULL
|
||||
*/
|
||||
int fz_atoi(const char *s);
|
||||
|
||||
/**
|
||||
64bit atoi that copes with NULL
|
||||
*/
|
||||
int64_t fz_atoi64(const char *s);
|
||||
|
||||
/*
|
||||
/**
|
||||
Some standard math functions, done as static inlines for speed.
|
||||
People with compilers that do not adequately implement inlines may
|
||||
like to reimplement these using macros.
|
||||
People with compilers that do not adequately implement inline
|
||||
may like to reimplement these using macros.
|
||||
*/
|
||||
static inline float fz_abs(float f)
|
||||
{
|
||||
@@ -79,6 +115,11 @@ static inline size_t fz_minz(size_t a, size_t b)
|
||||
return (a < b ? a : b);
|
||||
}
|
||||
|
||||
static inline int64_t fz_mini64(int64_t a, int64_t b)
|
||||
{
|
||||
return (a < b ? a : b);
|
||||
}
|
||||
|
||||
static inline float fz_max(float a, float b)
|
||||
{
|
||||
return (a > b ? a : b);
|
||||
@@ -89,41 +130,50 @@ static inline int fz_maxi(int a, int b)
|
||||
return (a > b ? a : b);
|
||||
}
|
||||
|
||||
static inline size_t fz_maxz(size_t a, size_t b)
|
||||
{
|
||||
return (a > b ? a : b);
|
||||
}
|
||||
|
||||
static inline int64_t fz_maxi64(int64_t a, int64_t b)
|
||||
{
|
||||
return (a > b ? a : b);
|
||||
}
|
||||
|
||||
static inline float fz_clamp(float f, float min, float max)
|
||||
static inline float fz_clamp(float x, float min, float max)
|
||||
{
|
||||
return (f > min ? (f < max ? f : max) : min);
|
||||
return x < min ? min : x > max ? max : x;
|
||||
}
|
||||
|
||||
static inline int fz_clampi(int i, int min, int max)
|
||||
static inline int fz_clampi(int x, int min, int max)
|
||||
{
|
||||
return (i > min ? (i < max ? i : max) : min);
|
||||
return x < min ? min : x > max ? max : x;
|
||||
}
|
||||
|
||||
static inline double fz_clampd(double d, double min, double max)
|
||||
static inline int64_t fz_clamp64(int64_t x, int64_t min, int64_t max)
|
||||
{
|
||||
return (d > min ? (d < max ? d : max) : min);
|
||||
return x < min ? min : x > max ? max : x;
|
||||
}
|
||||
|
||||
static inline void *fz_clampp(void *p, void *min, void *max)
|
||||
static inline double fz_clampd(double x, double min, double max)
|
||||
{
|
||||
return (p > min ? (p < max ? p : max) : min);
|
||||
return x < min ? min : x > max ? max : x;
|
||||
}
|
||||
|
||||
static inline void *fz_clampp(void *x, void *min, void *max)
|
||||
{
|
||||
return x < min ? min : x > max ? max : x;
|
||||
}
|
||||
|
||||
#define DIV_BY_ZERO(a, b, min, max) (((a) < 0) ^ ((b) < 0) ? (min) : (max))
|
||||
|
||||
/*
|
||||
/**
|
||||
fz_point is a point in a two-dimensional space.
|
||||
*/
|
||||
typedef struct fz_point_s fz_point;
|
||||
struct fz_point_s
|
||||
typedef struct
|
||||
{
|
||||
float x, y;
|
||||
};
|
||||
} fz_point;
|
||||
|
||||
static inline fz_point fz_make_point(float x, float y)
|
||||
{
|
||||
@@ -131,30 +181,44 @@ static inline fz_point fz_make_point(float x, float y)
|
||||
return p;
|
||||
}
|
||||
|
||||
/*
|
||||
/**
|
||||
fz_rect is a rectangle represented by two diagonally opposite
|
||||
corners at arbitrary coordinates.
|
||||
|
||||
Rectangles are always axis-aligned with the X- and Y- axes.
|
||||
The relationship between the coordinates are that x0 <= x1 and
|
||||
y0 <= y1 in all cases except for infinite rectangles. The area
|
||||
of a rectangle is defined as (x1 - x0) * (y1 - y0). If either
|
||||
x0 > x1 or y0 > y1 is true for a given rectangle then it is
|
||||
defined to be infinite.
|
||||
Rectangles are always axis-aligned with the X- and Y- axes. We
|
||||
wish to distinguish rectangles in 3 categories; infinite, finite,
|
||||
and invalid. Zero area rectangles are a sub-category of finite
|
||||
ones.
|
||||
|
||||
For all valid rectangles, x0 <= x1 and y0 <= y1 in all cases.
|
||||
Infinite rectangles have x0 = y0 = FZ_MIN_INF_RECT,
|
||||
x1 = y1 = FZ_MAX_INF_RECT. For any non infinite valid rectangle,
|
||||
the area is defined as (x1 - x0) * (y1 - y0).
|
||||
|
||||
To check for empty or infinite rectangles use fz_is_empty_rect
|
||||
and fz_is_infinite_rect.
|
||||
and fz_is_infinite_rect. To check for valid rectangles use
|
||||
fz_is_valid_rect.
|
||||
|
||||
We choose this representation, so that we can easily distinguish
|
||||
the difference between intersecting 2 valid rectangles and
|
||||
getting an invalid one, as opposed to getting a zero area one
|
||||
(which nonetheless has valid bounds within the plane).
|
||||
|
||||
x0, y0: The top left corner.
|
||||
|
||||
x1, y1: The bottom right corner.
|
||||
|
||||
We choose FZ_{MIN,MAX}_INF_RECT to be the largest 32bit signed
|
||||
integer values that survive roundtripping to floats.
|
||||
*/
|
||||
typedef struct fz_rect_s fz_rect;
|
||||
struct fz_rect_s
|
||||
#define FZ_MIN_INF_RECT ((int)0x80000000)
|
||||
#define FZ_MAX_INF_RECT ((int)0x7fffff80)
|
||||
|
||||
typedef struct
|
||||
{
|
||||
float x0, y0;
|
||||
float x1, y1;
|
||||
};
|
||||
} fz_rect;
|
||||
|
||||
static inline fz_rect fz_make_rect(float x0, float y0, float x1, float y1)
|
||||
{
|
||||
@@ -162,33 +226,16 @@ static inline fz_rect fz_make_rect(float x0, float y0, float x1, float y1)
|
||||
return r;
|
||||
}
|
||||
|
||||
/*
|
||||
fz_rect_min: get the minimum point from a rectangle as a fz_point.
|
||||
*/
|
||||
static inline fz_point *fz_rect_min(fz_rect *f)
|
||||
{
|
||||
return (fz_point *)&f->x0;
|
||||
}
|
||||
|
||||
/*
|
||||
fz_rect_max: get the maximum point from a rectangle as a fz_point.
|
||||
*/
|
||||
static inline fz_point *fz_rect_max(fz_rect *f)
|
||||
{
|
||||
return (fz_point *)&f->x1;
|
||||
}
|
||||
|
||||
/*
|
||||
/**
|
||||
fz_irect is a rectangle using integers instead of floats.
|
||||
|
||||
It's used in the draw device and for pixmap dimensions.
|
||||
*/
|
||||
typedef struct fz_irect_s fz_irect;
|
||||
struct fz_irect_s
|
||||
typedef struct
|
||||
{
|
||||
int x0, y0;
|
||||
int x1, y1;
|
||||
};
|
||||
} fz_irect;
|
||||
|
||||
static inline fz_irect fz_make_irect(int x0, int y0, int x1, int y1)
|
||||
{
|
||||
@@ -196,74 +243,116 @@ static inline fz_irect fz_make_irect(int x0, int y0, int x1, int y1)
|
||||
return r;
|
||||
}
|
||||
|
||||
/*
|
||||
/**
|
||||
A rectangle with sides of length one.
|
||||
|
||||
The bottom left corner is at (0, 0) and the top right corner
|
||||
is at (1, 1).
|
||||
*/
|
||||
extern const fz_rect fz_unit_rect;
|
||||
FZ_DATA extern const fz_rect fz_unit_rect;
|
||||
|
||||
/*
|
||||
/**
|
||||
An empty rectangle with an area equal to zero.
|
||||
|
||||
Both the top left and bottom right corner are at (0, 0).
|
||||
*/
|
||||
extern const fz_rect fz_empty_rect;
|
||||
extern const fz_irect fz_empty_irect;
|
||||
FZ_DATA extern const fz_rect fz_empty_rect;
|
||||
FZ_DATA extern const fz_irect fz_empty_irect;
|
||||
|
||||
/*
|
||||
An infinite rectangle with negative area.
|
||||
|
||||
The corner (x0, y0) is at (1, 1) while the corner (x1, y1) is
|
||||
at (-1, -1).
|
||||
/**
|
||||
An infinite rectangle.
|
||||
*/
|
||||
extern const fz_rect fz_infinite_rect;
|
||||
extern const fz_irect fz_infinite_irect;
|
||||
FZ_DATA extern const fz_rect fz_infinite_rect;
|
||||
FZ_DATA extern const fz_irect fz_infinite_irect;
|
||||
|
||||
/*
|
||||
fz_is_empty_rect: Check if rectangle is empty.
|
||||
/**
|
||||
Check if rectangle is empty.
|
||||
|
||||
An empty rectangle is defined as one whose area is zero.
|
||||
All invalid rectangles are empty.
|
||||
*/
|
||||
static inline int
|
||||
fz_is_empty_rect(const fz_rect *r)
|
||||
static inline int fz_is_empty_rect(fz_rect r)
|
||||
{
|
||||
return ((r)->x0 == (r)->x1 || (r)->y0 == (r)->y1);
|
||||
return (r.x0 >= r.x1 || r.y0 >= r.y1);
|
||||
}
|
||||
|
||||
static inline int
|
||||
fz_is_empty_irect(const fz_irect *r)
|
||||
static inline int fz_is_empty_irect(fz_irect r)
|
||||
{
|
||||
return ((r)->x0 == (r)->x1 || (r)->y0 == (r)->y1);
|
||||
return (r.x0 >= r.x1 || r.y0 >= r.y1);
|
||||
}
|
||||
|
||||
/*
|
||||
fz_is_infinite_rect: Check if rectangle is infinite.
|
||||
|
||||
An infinite rectangle is defined as one where either of the
|
||||
two relationships between corner coordinates are not true.
|
||||
/**
|
||||
Check if rectangle is infinite.
|
||||
*/
|
||||
static inline int
|
||||
fz_is_infinite_rect(const fz_rect *r)
|
||||
static inline int fz_is_infinite_rect(fz_rect r)
|
||||
{
|
||||
return ((r)->x0 > (r)->x1 || (r)->y0 > (r)->y1);
|
||||
return (r.x0 == FZ_MIN_INF_RECT && r.x1 == FZ_MAX_INF_RECT &&
|
||||
r.y0 == FZ_MIN_INF_RECT && r.y1 == FZ_MAX_INF_RECT);
|
||||
}
|
||||
|
||||
/*
|
||||
fz_is_infinite_irect: Check if an integer rectangle
|
||||
/**
|
||||
Check if an integer rectangle
|
||||
is infinite.
|
||||
|
||||
An infinite rectangle is defined as one where either of the
|
||||
two relationships between corner coordinates are not true.
|
||||
*/
|
||||
static inline int
|
||||
fz_is_infinite_irect(const fz_irect *r)
|
||||
static inline int fz_is_infinite_irect(fz_irect r)
|
||||
{
|
||||
return ((r)->x0 > (r)->x1 || (r)->y0 > (r)->y1);
|
||||
return (r.x0 == FZ_MIN_INF_RECT && r.x1 == FZ_MAX_INF_RECT &&
|
||||
r.y0 == FZ_MIN_INF_RECT && r.y1 == FZ_MAX_INF_RECT);
|
||||
}
|
||||
|
||||
/*
|
||||
/**
|
||||
Check if rectangle is valid.
|
||||
*/
|
||||
static inline int fz_is_valid_rect(fz_rect r)
|
||||
{
|
||||
return (r.x0 <= r.x1 && r.y0 <= r.y1);
|
||||
}
|
||||
|
||||
/**
|
||||
Check if an integer rectangle is valid.
|
||||
*/
|
||||
static inline int fz_is_valid_irect(fz_irect r)
|
||||
{
|
||||
return (r.x0 <= r.x1 && r.y0 <= r.y1);
|
||||
}
|
||||
|
||||
/**
|
||||
Return the width of an irect. Invalid irects return 0.
|
||||
*/
|
||||
static inline unsigned int
|
||||
fz_irect_width(fz_irect r)
|
||||
{
|
||||
unsigned int w;
|
||||
if (r.x0 >= r.x1)
|
||||
return 0;
|
||||
/* Check for w overflowing. This should never happen, but
|
||||
* if it does, it's pretty likely an indication of a severe
|
||||
* problem. */
|
||||
w = (unsigned int)r.x1 - r.x0;
|
||||
assert((int)w >= 0);
|
||||
if ((int)w < 0)
|
||||
return 0;
|
||||
return (int)w;
|
||||
}
|
||||
|
||||
/**
|
||||
Return the height of an irect. Invalid irects return 0.
|
||||
*/
|
||||
static inline int
|
||||
fz_irect_height(fz_irect r)
|
||||
{
|
||||
unsigned int h;
|
||||
if (r.y0 >= r.y1)
|
||||
return 0;
|
||||
/* Check for h overflowing. This should never happen, but
|
||||
* if it does, it's pretty likely an indication of a severe
|
||||
* problem. */
|
||||
h = (unsigned int)(r.y1 - r.y0);
|
||||
assert((int)h >= 0);
|
||||
if ((int)h < 0)
|
||||
return 0;
|
||||
return (int)h;
|
||||
}
|
||||
|
||||
/**
|
||||
fz_matrix is a row-major 3x3 matrix used for representing
|
||||
transformations of coordinates throughout MuPDF.
|
||||
|
||||
@@ -276,16 +365,15 @@ fz_is_infinite_irect(const fz_irect *r)
|
||||
| c d 0 | normally represented as [ a b c d e f ].
|
||||
\ e f 1 /
|
||||
*/
|
||||
typedef struct fz_matrix_s fz_matrix;
|
||||
struct fz_matrix_s
|
||||
typedef struct
|
||||
{
|
||||
float a, b, c, d, e, f;
|
||||
};
|
||||
} fz_matrix;
|
||||
|
||||
/*
|
||||
fz_identity: Identity transform matrix.
|
||||
/**
|
||||
Identity transform matrix.
|
||||
*/
|
||||
extern const fz_matrix fz_identity;
|
||||
FZ_DATA extern const fz_matrix fz_identity;
|
||||
|
||||
static inline fz_matrix fz_make_matrix(float a, float b, float c, float d, float e, float f)
|
||||
{
|
||||
@@ -293,24 +381,23 @@ static inline fz_matrix fz_make_matrix(float a, float b, float c, float d, float
|
||||
return m;
|
||||
}
|
||||
|
||||
static inline fz_matrix *fz_copy_matrix(fz_matrix *restrict m, const fz_matrix *restrict s)
|
||||
static inline int fz_is_identity(fz_matrix m)
|
||||
{
|
||||
*m = *s;
|
||||
return m;
|
||||
return m.a == 1 && m.b == 0 && m.c == 0 && m.d == 1 && m.e == 0 && m.f == 0;
|
||||
}
|
||||
|
||||
/*
|
||||
fz_concat: Multiply two matrices.
|
||||
/**
|
||||
Multiply two matrices.
|
||||
|
||||
The order of the two matrices are important since matrix
|
||||
multiplication is not commutative.
|
||||
|
||||
Returns result.
|
||||
*/
|
||||
fz_matrix *fz_concat(fz_matrix *result, const fz_matrix *left, const fz_matrix *right);
|
||||
fz_matrix fz_concat(fz_matrix left, fz_matrix right);
|
||||
|
||||
/*
|
||||
fz_scale: Create a scaling matrix.
|
||||
/**
|
||||
Create a scaling matrix.
|
||||
|
||||
The returned matrix is of the form [ sx 0 0 sy 0 0 ].
|
||||
|
||||
@@ -322,10 +409,10 @@ fz_matrix *fz_concat(fz_matrix *result, const fz_matrix *left, const fz_matrix *
|
||||
|
||||
Returns m.
|
||||
*/
|
||||
fz_matrix *fz_scale(fz_matrix *m, float sx, float sy);
|
||||
fz_matrix fz_scale(float sx, float sy);
|
||||
|
||||
/*
|
||||
fz_pre_scale: Scale a matrix by premultiplication.
|
||||
/**
|
||||
Scale a matrix by premultiplication.
|
||||
|
||||
m: Pointer to the matrix to scale
|
||||
|
||||
@@ -335,10 +422,10 @@ fz_matrix *fz_scale(fz_matrix *m, float sx, float sy);
|
||||
|
||||
Returns m (updated).
|
||||
*/
|
||||
fz_matrix *fz_pre_scale(fz_matrix *m, float sx, float sy);
|
||||
fz_matrix fz_pre_scale(fz_matrix m, float sx, float sy);
|
||||
|
||||
/*
|
||||
fz_post_scale: Scale a matrix by postmultiplication.
|
||||
/**
|
||||
Scale a matrix by postmultiplication.
|
||||
|
||||
m: Pointer to the matrix to scale
|
||||
|
||||
@@ -348,10 +435,10 @@ fz_matrix *fz_pre_scale(fz_matrix *m, float sx, float sy);
|
||||
|
||||
Returns m (updated).
|
||||
*/
|
||||
fz_matrix *fz_post_scale(fz_matrix *m, float sx, float sy);
|
||||
fz_matrix fz_post_scale(fz_matrix m, float sx, float sy);
|
||||
|
||||
/*
|
||||
fz_shear: Create a shearing matrix.
|
||||
/**
|
||||
Create a shearing matrix.
|
||||
|
||||
The returned matrix is of the form [ 1 sy sx 1 0 0 ].
|
||||
|
||||
@@ -362,10 +449,10 @@ fz_matrix *fz_post_scale(fz_matrix *m, float sx, float sy);
|
||||
|
||||
Returns m.
|
||||
*/
|
||||
fz_matrix *fz_shear(fz_matrix *m, float sx, float sy);
|
||||
fz_matrix fz_shear(float sx, float sy);
|
||||
|
||||
/*
|
||||
fz_pre_shear: Premultiply a matrix with a shearing matrix.
|
||||
/**
|
||||
Premultiply a matrix with a shearing matrix.
|
||||
|
||||
The shearing matrix is of the form [ 1 sy sx 1 0 0 ].
|
||||
|
||||
@@ -376,10 +463,10 @@ fz_matrix *fz_shear(fz_matrix *m, float sx, float sy);
|
||||
|
||||
Returns m (updated).
|
||||
*/
|
||||
fz_matrix *fz_pre_shear(fz_matrix *m, float sx, float sy);
|
||||
fz_matrix fz_pre_shear(fz_matrix m, float sx, float sy);
|
||||
|
||||
/*
|
||||
fz_rotate: Create a rotation matrix.
|
||||
/**
|
||||
Create a rotation matrix.
|
||||
|
||||
The returned matrix is of the form
|
||||
[ cos(deg) sin(deg) -sin(deg) cos(deg) 0 0 ].
|
||||
@@ -391,10 +478,10 @@ fz_matrix *fz_pre_shear(fz_matrix *m, float sx, float sy);
|
||||
|
||||
Returns m.
|
||||
*/
|
||||
fz_matrix *fz_rotate(fz_matrix *m, float degrees);
|
||||
fz_matrix fz_rotate(float degrees);
|
||||
|
||||
/*
|
||||
fz_pre_rotate: Rotate a transformation by premultiplying.
|
||||
/**
|
||||
Rotate a transformation by premultiplying.
|
||||
|
||||
The premultiplied matrix is of the form
|
||||
[ cos(deg) sin(deg) -sin(deg) cos(deg) 0 0 ].
|
||||
@@ -406,10 +493,10 @@ fz_matrix *fz_rotate(fz_matrix *m, float degrees);
|
||||
|
||||
Returns m (updated).
|
||||
*/
|
||||
fz_matrix *fz_pre_rotate(fz_matrix *m, float degrees);
|
||||
fz_matrix fz_pre_rotate(fz_matrix m, float degrees);
|
||||
|
||||
/*
|
||||
fz_translate: Create a translation matrix.
|
||||
/**
|
||||
Create a translation matrix.
|
||||
|
||||
The returned matrix is of the form [ 1 0 0 1 tx ty ].
|
||||
|
||||
@@ -421,10 +508,10 @@ fz_matrix *fz_pre_rotate(fz_matrix *m, float degrees);
|
||||
|
||||
Returns m.
|
||||
*/
|
||||
fz_matrix *fz_translate(fz_matrix *m, float tx, float ty);
|
||||
fz_matrix fz_translate(float tx, float ty);
|
||||
|
||||
/*
|
||||
fz_pre_translate: Translate a matrix by premultiplication.
|
||||
/**
|
||||
Translate a matrix by premultiplication.
|
||||
|
||||
m: The matrix to translate
|
||||
|
||||
@@ -434,10 +521,18 @@ fz_matrix *fz_translate(fz_matrix *m, float tx, float ty);
|
||||
|
||||
Returns m.
|
||||
*/
|
||||
fz_matrix *fz_pre_translate(fz_matrix *m, float tx, float ty);
|
||||
fz_matrix fz_pre_translate(fz_matrix m, float tx, float ty);
|
||||
|
||||
/*
|
||||
fz_invert_matrix: Create an inverse matrix.
|
||||
/**
|
||||
Create transform matrix to draw page
|
||||
at a given resolution and rotation. Adjusts the scaling
|
||||
factors so that the page covers whole number of
|
||||
pixels and adjust the page origin to be at 0,0.
|
||||
*/
|
||||
fz_matrix fz_transform_page(fz_rect mediabox, float resolution, float rotate);
|
||||
|
||||
/**
|
||||
Create an inverse matrix.
|
||||
|
||||
inverse: Place to store inverse matrix.
|
||||
|
||||
@@ -447,10 +542,10 @@ fz_matrix *fz_pre_translate(fz_matrix *m, float tx, float ty);
|
||||
|
||||
Returns inverse.
|
||||
*/
|
||||
fz_matrix *fz_invert_matrix(fz_matrix *inverse, const fz_matrix *matrix);
|
||||
fz_matrix fz_invert_matrix(fz_matrix matrix);
|
||||
|
||||
/*
|
||||
fz_try_invert_matrix: Attempt to create an inverse matrix.
|
||||
/**
|
||||
Attempt to create an inverse matrix.
|
||||
|
||||
inverse: Place to store inverse matrix.
|
||||
|
||||
@@ -459,25 +554,25 @@ fz_matrix *fz_invert_matrix(fz_matrix *inverse, const fz_matrix *matrix);
|
||||
|
||||
Returns 1 if matrix is degenerate (singular), or 0 otherwise.
|
||||
*/
|
||||
int fz_try_invert_matrix(fz_matrix *inverse, const fz_matrix *matrix);
|
||||
int fz_try_invert_matrix(fz_matrix *inv, fz_matrix src);
|
||||
|
||||
/*
|
||||
fz_is_rectilinear: Check if a transformation is rectilinear.
|
||||
/**
|
||||
Check if a transformation is rectilinear.
|
||||
|
||||
Rectilinear means that no shearing is present and that any
|
||||
rotations present are a multiple of 90 degrees. Usually this
|
||||
is used to make sure that axis-aligned rectangles before the
|
||||
transformation are still axis-aligned rectangles afterwards.
|
||||
*/
|
||||
int fz_is_rectilinear(const fz_matrix *m);
|
||||
int fz_is_rectilinear(fz_matrix m);
|
||||
|
||||
/*
|
||||
fz_matrix_expansion: Calculate average scaling factor of matrix.
|
||||
/**
|
||||
Calculate average scaling factor of matrix.
|
||||
*/
|
||||
float fz_matrix_expansion(const fz_matrix *m); /* sumatrapdf */
|
||||
float fz_matrix_expansion(fz_matrix m);
|
||||
|
||||
/*
|
||||
fz_intersect_rect: Compute intersection of two rectangles.
|
||||
/**
|
||||
Compute intersection of two rectangles.
|
||||
|
||||
Given two rectangles, update the first to be the smallest
|
||||
axis-aligned rectangle that covers the area covered by both
|
||||
@@ -487,18 +582,18 @@ float fz_matrix_expansion(const fz_matrix *m); /* sumatrapdf */
|
||||
Should both rectangles be infinite, then the intersection is
|
||||
also infinite.
|
||||
*/
|
||||
fz_rect *fz_intersect_rect(fz_rect *restrict a, const fz_rect *restrict b);
|
||||
fz_rect fz_intersect_rect(fz_rect a, fz_rect b);
|
||||
|
||||
/*
|
||||
fz_intersect_irect: Compute intersection of two bounding boxes.
|
||||
/**
|
||||
Compute intersection of two bounding boxes.
|
||||
|
||||
Similar to fz_intersect_rect but operates on two bounding
|
||||
boxes instead of two rectangles.
|
||||
*/
|
||||
fz_irect *fz_intersect_irect(fz_irect *restrict a, const fz_irect *restrict b);
|
||||
fz_irect fz_intersect_irect(fz_irect a, fz_irect b);
|
||||
|
||||
/*
|
||||
fz_union_rect: Compute union of two rectangles.
|
||||
/**
|
||||
Compute union of two rectangles.
|
||||
|
||||
Given two rectangles, update the first to be the smallest
|
||||
axis-aligned rectangle that encompasses both given rectangles.
|
||||
@@ -507,28 +602,21 @@ fz_irect *fz_intersect_irect(fz_irect *restrict a, const fz_irect *restrict b);
|
||||
non-empty rectangle. Should both rectangles be empty, then the
|
||||
union is also empty.
|
||||
*/
|
||||
fz_rect *fz_union_rect(fz_rect *restrict a, const fz_rect *restrict b);
|
||||
fz_rect fz_union_rect(fz_rect a, fz_rect b);
|
||||
|
||||
/*
|
||||
fz_irect_from_rect: Convert a rect into the minimal bounding box
|
||||
/**
|
||||
Convert a rect into the minimal bounding box
|
||||
that covers the rectangle.
|
||||
|
||||
bbox: Place to store the returned bbox.
|
||||
|
||||
rect: The rectangle to convert to a bbox.
|
||||
|
||||
Coordinates in a bounding box are integers, so rounding of the
|
||||
rects coordinates takes place. The top left corner is rounded
|
||||
upwards and left while the bottom right corner is rounded
|
||||
downwards and to the right.
|
||||
|
||||
Returns bbox (updated).
|
||||
*/
|
||||
fz_irect fz_irect_from_rect(fz_rect rect);
|
||||
|
||||
fz_irect *fz_irect_from_rect(fz_irect *restrict bbox, const fz_rect *restrict rect);
|
||||
|
||||
/*
|
||||
fz_round_rect: Round rectangle coordinates.
|
||||
/**
|
||||
Round rectangle coordinates.
|
||||
|
||||
Coordinates in a bounding box are integers, so rounding of the
|
||||
rects coordinates takes place. The top left corner is rounded
|
||||
@@ -536,15 +624,15 @@ fz_irect *fz_irect_from_rect(fz_irect *restrict bbox, const fz_rect *restrict re
|
||||
downwards and to the right.
|
||||
|
||||
This differs from fz_irect_from_rect, in that fz_irect_from_rect
|
||||
slavishly follows the numbers (i.e any slight over/under calculations
|
||||
can cause whole extra pixels to be added). fz_round_rect
|
||||
allows for a small amount of rounding error when calculating
|
||||
the bbox.
|
||||
slavishly follows the numbers (i.e any slight over/under
|
||||
calculations can cause whole extra pixels to be added).
|
||||
fz_round_rect allows for a small amount of rounding error when
|
||||
calculating the bbox.
|
||||
*/
|
||||
fz_irect *fz_round_rect(fz_irect *restrict bbox, const fz_rect *restrict rect);
|
||||
fz_irect fz_round_rect(fz_rect rect);
|
||||
|
||||
/*
|
||||
fz_rect_from_irect: Convert a bbox into a rect.
|
||||
/**
|
||||
Convert a bbox into a rect.
|
||||
|
||||
For our purposes, a rect can represent all the values we meet in
|
||||
a bbox, so nothing can go wrong.
|
||||
@@ -555,39 +643,39 @@ fz_irect *fz_round_rect(fz_irect *restrict bbox, const fz_rect *restrict rect);
|
||||
|
||||
Returns rect (updated).
|
||||
*/
|
||||
fz_rect *fz_rect_from_irect(fz_rect *restrict rect, const fz_irect *restrict bbox);
|
||||
fz_rect fz_rect_from_irect(fz_irect bbox);
|
||||
|
||||
/*
|
||||
fz_expand_rect: Expand a bbox by a given amount in all directions.
|
||||
/**
|
||||
Expand a bbox by a given amount in all directions.
|
||||
*/
|
||||
fz_rect *fz_expand_rect(fz_rect *b, float expand);
|
||||
fz_irect *fz_expand_irect(fz_irect *a, int expand);
|
||||
fz_rect fz_expand_rect(fz_rect b, float expand);
|
||||
fz_irect fz_expand_irect(fz_irect a, int expand);
|
||||
|
||||
/*
|
||||
fz_include_point_in_rect: Expand a bbox to include a given point.
|
||||
/**
|
||||
Expand a bbox to include a given point.
|
||||
To create a rectangle that encompasses a sequence of points, the
|
||||
rectangle must first be set to be the empty rectangle at one of
|
||||
the points before including the others.
|
||||
*/
|
||||
fz_rect *fz_include_point_in_rect(fz_rect *r, const fz_point *p);
|
||||
fz_rect fz_include_point_in_rect(fz_rect r, fz_point p);
|
||||
|
||||
/*
|
||||
fz_translate_irect: Translate bounding box.
|
||||
/**
|
||||
Translate bounding box.
|
||||
|
||||
Translate a bbox by a given x and y offset. Allows for overflow.
|
||||
*/
|
||||
fz_rect *fz_translate_rect(fz_rect *a, float xoff, float yoff);
|
||||
fz_irect *fz_translate_irect(fz_irect *a, int xoff, int yoff);
|
||||
fz_rect fz_translate_rect(fz_rect a, float xoff, float yoff);
|
||||
fz_irect fz_translate_irect(fz_irect a, int xoff, int yoff);
|
||||
|
||||
/*
|
||||
fz_contains_rect: Test rectangle inclusion.
|
||||
/**
|
||||
Test rectangle inclusion.
|
||||
|
||||
Return true if a entirely contains b.
|
||||
*/
|
||||
int fz_contains_rect(const fz_rect *a, const fz_rect *b);
|
||||
int fz_contains_rect(fz_rect a, fz_rect b);
|
||||
|
||||
/*
|
||||
fz_transform_point: Apply a transformation to a point.
|
||||
/**
|
||||
Apply a transformation to a point.
|
||||
|
||||
transform: Transformation matrix to apply. See fz_concat,
|
||||
fz_scale, fz_rotate and fz_translate for how to create a
|
||||
@@ -597,11 +685,11 @@ int fz_contains_rect(const fz_rect *a, const fz_rect *b);
|
||||
|
||||
Returns transform (unchanged).
|
||||
*/
|
||||
fz_point *fz_transform_point(fz_point *restrict point, const fz_matrix *restrict transform);
|
||||
fz_point *fz_transform_point_xy(fz_point *restrict point, const fz_matrix *restrict transform, float x, float y);
|
||||
fz_point fz_transform_point(fz_point point, fz_matrix m);
|
||||
fz_point fz_transform_point_xy(float x, float y, fz_matrix m);
|
||||
|
||||
/*
|
||||
fz_transform_vector: Apply a transformation to a vector.
|
||||
/**
|
||||
Apply a transformation to a vector.
|
||||
|
||||
transform: Transformation matrix to apply. See fz_concat,
|
||||
fz_scale and fz_rotate for how to create a matrix. Any
|
||||
@@ -609,10 +697,10 @@ fz_point *fz_transform_point_xy(fz_point *restrict point, const fz_matrix *restr
|
||||
|
||||
vector: Pointer to vector to update.
|
||||
*/
|
||||
fz_point *fz_transform_vector(fz_point *restrict vector, const fz_matrix *restrict transform);
|
||||
fz_point fz_transform_vector(fz_point vector, fz_matrix m);
|
||||
|
||||
/*
|
||||
fz_transform_rect: Apply a transform to a rectangle.
|
||||
/**
|
||||
Apply a transform to a rectangle.
|
||||
|
||||
After the four corner points of the axis-aligned rectangle
|
||||
have been transformed it may not longer be axis-aligned. So a
|
||||
@@ -626,15 +714,105 @@ fz_point *fz_transform_vector(fz_point *restrict vector, const fz_matrix *restri
|
||||
fz_empty_rect and fz_infinite_rect, may be used but are
|
||||
returned unchanged as expected.
|
||||
*/
|
||||
fz_rect *fz_transform_rect(fz_rect *restrict rect, const fz_matrix *restrict transform);
|
||||
fz_rect fz_transform_rect(fz_rect rect, fz_matrix m);
|
||||
|
||||
/*
|
||||
fz_normalize_vector: Normalize a vector to length one.
|
||||
/**
|
||||
Normalize a vector to length one.
|
||||
*/
|
||||
void fz_normalize_vector(fz_point *p);
|
||||
fz_point fz_normalize_vector(fz_point p);
|
||||
|
||||
void fz_gridfit_matrix(int as_tiled, fz_matrix *m);
|
||||
/**
|
||||
Grid fit a matrix.
|
||||
|
||||
float fz_matrix_max_expansion(const fz_matrix *m);
|
||||
as_tiled = 0 => adjust the matrix so that the image of the unit
|
||||
square completely covers any pixel that was touched by the
|
||||
image of the unit square under the original matrix.
|
||||
|
||||
as_tiled = 1 => adjust the matrix so that the corners of the
|
||||
image of the unit square align with the closest integer corner
|
||||
of the image of the unit square under the original matrix.
|
||||
*/
|
||||
fz_matrix fz_gridfit_matrix(int as_tiled, fz_matrix m);
|
||||
|
||||
/**
|
||||
Find the largest expansion performed by this matrix.
|
||||
(i.e. max(abs(m.a),abs(m.b),abs(m.c),abs(m.d))
|
||||
*/
|
||||
float fz_matrix_max_expansion(fz_matrix m);
|
||||
|
||||
/**
|
||||
A representation for a region defined by 4 points.
|
||||
|
||||
The significant difference between quads and rects is that
|
||||
the edges of quads are not axis aligned.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
fz_point ul, ur, ll, lr;
|
||||
} fz_quad;
|
||||
|
||||
/**
|
||||
Inline convenience construction function.
|
||||
*/
|
||||
static inline fz_quad fz_make_quad(
|
||||
float ul_x, float ul_y,
|
||||
float ur_x, float ur_y,
|
||||
float ll_x, float ll_y,
|
||||
float lr_x, float lr_y)
|
||||
{
|
||||
fz_quad q = {
|
||||
{ ul_x, ul_y },
|
||||
{ ur_x, ur_y },
|
||||
{ ll_x, ll_y },
|
||||
{ lr_x, lr_y },
|
||||
};
|
||||
return q;
|
||||
}
|
||||
|
||||
/**
|
||||
Convert a rect to a quad (losslessly).
|
||||
*/
|
||||
fz_quad fz_quad_from_rect(fz_rect r);
|
||||
|
||||
/**
|
||||
Convert a quad to the smallest rect that covers it.
|
||||
*/
|
||||
fz_rect fz_rect_from_quad(fz_quad q);
|
||||
|
||||
/**
|
||||
Transform a quad by a matrix.
|
||||
*/
|
||||
fz_quad fz_transform_quad(fz_quad q, fz_matrix m);
|
||||
|
||||
/**
|
||||
Inclusion test for quads.
|
||||
*/
|
||||
int fz_is_point_inside_quad(fz_point p, fz_quad q);
|
||||
|
||||
/**
|
||||
Inclusion test for rects. (Rect is assumed to be open, i.e.
|
||||
top right corner is not included).
|
||||
*/
|
||||
int fz_is_point_inside_rect(fz_point p, fz_rect r);
|
||||
|
||||
/**
|
||||
Inclusion test for irects. (Rect is assumed to be open, i.e.
|
||||
top right corner is not included).
|
||||
*/
|
||||
int fz_is_point_inside_irect(int x, int y, fz_irect r);
|
||||
|
||||
/**
|
||||
Inclusion test for quad in quad.
|
||||
|
||||
This may break down if quads are not 'well formed'.
|
||||
*/
|
||||
int fz_is_quad_inside_quad(fz_quad needle, fz_quad haystack);
|
||||
|
||||
/**
|
||||
Intersection test for quads.
|
||||
|
||||
This may break down if quads are not 'well formed'.
|
||||
*/
|
||||
int fz_is_quad_intersecting_quad(fz_quad a, fz_quad b);
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user