diff options
Diffstat (limited to 'src/cairo-fixed-private.h')
-rw-r--r--[-rwxr-xr-x] | src/cairo-fixed-private.h | 40 |
1 files changed, 38 insertions, 2 deletions
diff --git a/src/cairo-fixed-private.h b/src/cairo-fixed-private.h index b6cc6be7d..9ff8f7503 100755..100644 --- a/src/cairo-fixed-private.h +++ b/src/cairo-fixed-private.h @@ -40,12 +40,13 @@ #include "cairo-fixed-type-private.h" #include "cairo-wideint-private.h" +#include "cairoint.h" /* Implementation */ #if (CAIRO_FIXED_BITS != 32) # error CAIRO_FIXED_BITS must be 32, and the type must be a 32-bit type. -# error To remove this limitation, you will have to fix the tesselator. +# error To remove this limitation, you will have to fix the tessellator. #endif #define CAIRO_FIXED_ONE ((cairo_fixed_t)(1 << CAIRO_FIXED_FRAC_BITS)) @@ -311,7 +312,7 @@ _cairo_fixed_mul_div_floor (cairo_fixed_t a, cairo_fixed_t b, cairo_fixed_t c) return _cairo_int64_32_div (_cairo_int32x32_64_mul (a, b), c); } - +/* compute y from x so that (x,y), p1, and p2 are collinear */ static inline cairo_fixed_t _cairo_edge_compute_intersection_y_for_x (const cairo_point_t *p1, const cairo_point_t *p2, @@ -332,6 +333,7 @@ _cairo_edge_compute_intersection_y_for_x (const cairo_point_t *p1, return y; } +/* compute x from y so that (x,y), p1, and p2 are collinear */ static inline cairo_fixed_t _cairo_edge_compute_intersection_x_for_y (const cairo_point_t *p1, const cairo_point_t *p2, @@ -352,6 +354,40 @@ _cairo_edge_compute_intersection_x_for_y (const cairo_point_t *p1, return x; } +/* Intersect two segments based on the algorithm described at + * http://paulbourke.net/geometry/pointlineplane/. This implementation + * uses floating point math. */ +static inline cairo_bool_t +_slow_segment_intersection (const cairo_point_t *seg1_p1, + const cairo_point_t *seg1_p2, + const cairo_point_t *seg2_p1, + const cairo_point_t *seg2_p2, + cairo_point_t *intersection) +{ + double denominator, u_a, u_b; + double seg1_dx, seg1_dy, seg2_dx, seg2_dy, seg_start_dx, seg_start_dy; + + seg1_dx = _cairo_fixed_to_double (seg1_p2->x - seg1_p1->x); + seg1_dy = _cairo_fixed_to_double (seg1_p2->y - seg1_p1->y); + seg2_dx = _cairo_fixed_to_double (seg2_p2->x - seg2_p1->x); + seg2_dy = _cairo_fixed_to_double (seg2_p2->y - seg2_p1->y); + denominator = (seg2_dy * seg1_dx) - (seg2_dx * seg1_dy); + if (denominator == 0) + return FALSE; + + seg_start_dx = _cairo_fixed_to_double (seg1_p1->x - seg2_p1->x); + seg_start_dy = _cairo_fixed_to_double (seg1_p1->y - seg2_p1->y); + u_a = ((seg2_dx * seg_start_dy) - (seg2_dy * seg_start_dx)) / denominator; + u_b = ((seg1_dx * seg_start_dy) - (seg1_dy * seg_start_dx)) / denominator; + + if (u_a <= 0 || u_a >= 1 || u_b <= 0 || u_b >= 1) + return FALSE; + + intersection->x = seg1_p1->x + _cairo_fixed_from_double ((u_a * seg1_dx)); + intersection->y = seg1_p1->y + _cairo_fixed_from_double ((u_a * seg1_dy)); + return TRUE; +} + #else # error Please define multiplication and other operands for your fixed-point type size #endif |