summaryrefslogtreecommitdiff
path: root/src/cairo-fixed-private.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/cairo-fixed-private.h')
-rw-r--r--[-rwxr-xr-x]src/cairo-fixed-private.h40
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