mirror of
https://gitlab.freedesktop.org/cairo/cairo.git
synced 2026-05-05 11:08:12 +02:00
Introduced cairo_fixed_*_t types. Converted several functions from floating to fixed point.
This commit is contained in:
parent
6ef8b5cdf4
commit
ee146c4740
7 changed files with 124 additions and 70 deletions
18
ChangeLog
18
ChangeLog
|
|
@ -1,3 +1,21 @@
|
|||
2003-07-23 Carl Worth <cworth@isi.edu>
|
||||
|
||||
* src/cairoint.h: Introduced some cairo_fixed_*_t types. This is
|
||||
the first baby step toward ripping X dependencies out of the Cairo
|
||||
headers.
|
||||
|
||||
* src/cairo_traps.c (_compute_x): Converted from floating point to
|
||||
fixed point.
|
||||
(_line_seg_intersection_ceil): Now increments y value once if the
|
||||
initial y value computed is less than the actual intersection
|
||||
point.
|
||||
|
||||
* src/cairo_traps.c (_compare_cairo_edge_by_slope): Converted from
|
||||
floating point to fixed point.
|
||||
|
||||
* src/cairo_pen.c (_slope_clockwise): Converted from floating
|
||||
point to fixed point.
|
||||
|
||||
2003-07-19 Carl Worth <cworth@isi.edu>
|
||||
|
||||
* src/cairo_traps.c (cairo_traps_tessellate_polygon): Fixed some
|
||||
|
|
|
|||
|
|
@ -233,12 +233,8 @@ _cairo_pen_compute_slopes (cairo_pen_t *pen)
|
|||
static int
|
||||
_slope_clockwise (cairo_slope_fixed_t *a, cairo_slope_fixed_t *b)
|
||||
{
|
||||
double a_dx = XFixedToDouble (a->dx);
|
||||
double a_dy = XFixedToDouble (a->dy);
|
||||
double b_dx = XFixedToDouble (b->dx);
|
||||
double b_dy = XFixedToDouble (b->dy);
|
||||
|
||||
return b_dy * a_dx > a_dy * b_dx;
|
||||
return ((cairo_fixed_48_16_t) b->dy * (cairo_fixed_48_16_t) a->dx
|
||||
> (cairo_fixed_48_16_t) a->dy * (cairo_fixed_48_16_t) b->dx);
|
||||
}
|
||||
|
||||
static int
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright © 2002 Keith Packard, member of The XFree86 Project, Inc.
|
||||
* Copyright © 2002 Keith Packard
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and its
|
||||
* documentation for any purpose is hereby granted without fee, provided that
|
||||
|
|
@ -46,7 +46,7 @@ _compare_point_fixed_by_y (const void *av, const void *bv);
|
|||
static int
|
||||
_compare_cairo_edge_by_top (const void *av, const void *bv);
|
||||
|
||||
static XFixed
|
||||
static cairo_fixed_16_16_t
|
||||
_compute_x (XLineFixed *line, XFixed y);
|
||||
|
||||
static double
|
||||
|
|
@ -56,7 +56,7 @@ static double
|
|||
_compute_x_intercept (XLineFixed *l, double inverse_slope);
|
||||
|
||||
static XFixed
|
||||
_lines_intersect (XLineFixed *l1, XLineFixed *l2, XFixed *intersection);
|
||||
_line_seg_intersection_ceil (XLineFixed *left, XLineFixed *right, XFixed *intersection);
|
||||
|
||||
void
|
||||
cairo_traps_init (cairo_traps_t *traps)
|
||||
|
|
@ -164,7 +164,7 @@ cairo_traps_tessellate_triangle (cairo_traps_t *traps, XPointFixed t[3])
|
|||
{
|
||||
cairo_status_t status;
|
||||
XLineFixed line;
|
||||
double intersect;
|
||||
cairo_fixed_16_16_t intersect;
|
||||
XPointFixed tsort[3];
|
||||
|
||||
memcpy (tsort, t, 3 * sizeof (XPointFixed));
|
||||
|
|
@ -281,17 +281,25 @@ static int
|
|||
_compare_cairo_edge_by_slope (const void *av, const void *bv)
|
||||
{
|
||||
const cairo_edge_t *a = av, *b = bv;
|
||||
cairo_fixed_32_32_t d;
|
||||
|
||||
double a_dx = XFixedToDouble (a->edge.p2.x - a->edge.p1.x);
|
||||
double a_dy = XFixedToDouble (a->edge.p2.y - a->edge.p1.y);
|
||||
double b_dx = XFixedToDouble (b->edge.p2.x - b->edge.p1.x);
|
||||
double b_dy = XFixedToDouble (b->edge.p2.y - b->edge.p1.y);
|
||||
cairo_fixed_48_16_t a_dx = a->edge.p2.x - a->edge.p1.x;
|
||||
cairo_fixed_48_16_t a_dy = a->edge.p2.y - a->edge.p1.y;
|
||||
cairo_fixed_48_16_t b_dx = b->edge.p2.x - b->edge.p1.x;
|
||||
cairo_fixed_48_16_t b_dy = b->edge.p2.y - b->edge.p1.y;
|
||||
|
||||
return b_dy * a_dx - a_dy * b_dx;
|
||||
d = b_dy * a_dx - a_dy * b_dx;
|
||||
|
||||
if (d > 0)
|
||||
return 1;
|
||||
else if (d == 0)
|
||||
return 0;
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int
|
||||
_compare_cairo_edge_by_current_xthen_slope (const void *av, const void *bv)
|
||||
_compare_cairo_edge_by_current_x_then_slope (const void *av, const void *bv)
|
||||
{
|
||||
const cairo_edge_t *a = av, *b = bv;
|
||||
int ret;
|
||||
|
|
@ -354,12 +362,12 @@ _lines_intersect (XLineFixed *l1, XLineFixed *l2, XFixed *y_intersection)
|
|||
return 1;
|
||||
}
|
||||
*/
|
||||
static XFixed
|
||||
static cairo_fixed_16_16_t
|
||||
_compute_x (XLineFixed *line, XFixed y)
|
||||
{
|
||||
XFixed dx = line->p2.x - line->p1.x;
|
||||
double ex = (double) (y - line->p1.y) * (double) dx;
|
||||
XFixed dy = line->p2.y - line->p1.y;
|
||||
cairo_fixed_16_16_t dx = line->p2.x - line->p1.x;
|
||||
cairo_fixed_32_32_t ex = (cairo_fixed_48_16_t) (y - line->p1.y) * (cairo_fixed_48_16_t) dx;
|
||||
cairo_fixed_16_16_t dy = line->p2.y - line->p1.y;
|
||||
|
||||
return line->p1.x + (ex / dy);
|
||||
}
|
||||
|
|
@ -378,7 +386,7 @@ _compute_x_intercept (XLineFixed *l, double inverse_slope)
|
|||
}
|
||||
|
||||
static int
|
||||
_lines_intersect (XLineFixed *l1, XLineFixed *l2, XFixed *y_intersection)
|
||||
_line_seg_intersection_ceil (XLineFixed *left, XLineFixed *right, XFixed *y_intersection)
|
||||
{
|
||||
/*
|
||||
* x = m1y + b1
|
||||
|
|
@ -387,15 +395,22 @@ _lines_intersect (XLineFixed *l1, XLineFixed *l2, XFixed *y_intersection)
|
|||
* y * (m1 - m2) = b2 - b1
|
||||
* y = (b2 - b1) / (m1 - m2)
|
||||
*/
|
||||
double m1 = _compute_inverse_slope (l1);
|
||||
double b1 = _compute_x_intercept (l1, m1);
|
||||
double m2 = _compute_inverse_slope (l2);
|
||||
double b2 = _compute_x_intercept (l2, m2);
|
||||
cairo_fixed_16_16_t y;
|
||||
double m1 = _compute_inverse_slope (left);
|
||||
double b1 = _compute_x_intercept (left, m1);
|
||||
double m2 = _compute_inverse_slope (right);
|
||||
double b2 = _compute_x_intercept (right, m2);
|
||||
|
||||
if (m1 == m2)
|
||||
return 0;
|
||||
|
||||
*y_intersection = XDoubleToFixed ((b2 - b1) / (m1 - m2));
|
||||
y = XDoubleToFixed ((b2 - b1) / (m1 - m2));
|
||||
|
||||
if (_compute_x (right, y) < _compute_x (left, y))
|
||||
y++;
|
||||
|
||||
*y_intersection = y;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
@ -414,7 +429,7 @@ _SortEdgeList (cairo_edge_t **active)
|
|||
*/
|
||||
for (en = next; en; en = en->next)
|
||||
{
|
||||
if (_compare_cairo_edge_by_current_xthen_slope (e, en) > 0)
|
||||
if (_compare_cairo_edge_by_current_x_then_slope (e, en) > 0)
|
||||
{
|
||||
/*
|
||||
* insert en before e
|
||||
|
|
@ -531,14 +546,9 @@ cairo_traps_tessellate_polygon (cairo_traps_t *traps,
|
|||
next_y = e->edge.p2.y;
|
||||
/* check intersect */
|
||||
if (en && e->current_x != en->current_x)
|
||||
if (_lines_intersect (&e->edge, &en->edge, &intersect)) {
|
||||
/* Need to make sure that when we next compute X
|
||||
values for these two edges, that they will sort
|
||||
as if after the intersection. */
|
||||
intersect++;
|
||||
if (_line_seg_intersection_ceil (&e->edge, &en->edge, &intersect))
|
||||
if (intersect > y && intersect < next_y)
|
||||
next_y = intersect;
|
||||
}
|
||||
}
|
||||
/* check next inactive point */
|
||||
if (inactive < num_edges && edges[inactive].edge.p1.y < next_y)
|
||||
|
|
|
|||
|
|
@ -667,15 +667,15 @@ cairo_show_text (cairo_t *cr, const unsigned char *utf8)
|
|||
|
||||
void
|
||||
cairo_show_surface (cairo_t *cr,
|
||||
cairo_surface_t *surface,
|
||||
int width,
|
||||
int height)
|
||||
cairo_surface_t *surface,
|
||||
int width,
|
||||
int height)
|
||||
{
|
||||
if (cr->status)
|
||||
return;
|
||||
|
||||
cr->status = _cairo_gstate_show_surface (cr->gstate,
|
||||
surface, width, height);
|
||||
surface, width, height);
|
||||
}
|
||||
|
||||
cairo_status_t
|
||||
|
|
|
|||
|
|
@ -233,12 +233,8 @@ _cairo_pen_compute_slopes (cairo_pen_t *pen)
|
|||
static int
|
||||
_slope_clockwise (cairo_slope_fixed_t *a, cairo_slope_fixed_t *b)
|
||||
{
|
||||
double a_dx = XFixedToDouble (a->dx);
|
||||
double a_dy = XFixedToDouble (a->dy);
|
||||
double b_dx = XFixedToDouble (b->dx);
|
||||
double b_dy = XFixedToDouble (b->dy);
|
||||
|
||||
return b_dy * a_dx > a_dy * b_dx;
|
||||
return ((cairo_fixed_48_16_t) b->dy * (cairo_fixed_48_16_t) a->dx
|
||||
> (cairo_fixed_48_16_t) a->dy * (cairo_fixed_48_16_t) b->dx);
|
||||
}
|
||||
|
||||
static int
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright © 2002 Keith Packard, member of The XFree86 Project, Inc.
|
||||
* Copyright © 2002 Keith Packard
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and its
|
||||
* documentation for any purpose is hereby granted without fee, provided that
|
||||
|
|
@ -46,7 +46,7 @@ _compare_point_fixed_by_y (const void *av, const void *bv);
|
|||
static int
|
||||
_compare_cairo_edge_by_top (const void *av, const void *bv);
|
||||
|
||||
static XFixed
|
||||
static cairo_fixed_16_16_t
|
||||
_compute_x (XLineFixed *line, XFixed y);
|
||||
|
||||
static double
|
||||
|
|
@ -56,7 +56,7 @@ static double
|
|||
_compute_x_intercept (XLineFixed *l, double inverse_slope);
|
||||
|
||||
static XFixed
|
||||
_lines_intersect (XLineFixed *l1, XLineFixed *l2, XFixed *intersection);
|
||||
_line_seg_intersection_ceil (XLineFixed *left, XLineFixed *right, XFixed *intersection);
|
||||
|
||||
void
|
||||
cairo_traps_init (cairo_traps_t *traps)
|
||||
|
|
@ -164,7 +164,7 @@ cairo_traps_tessellate_triangle (cairo_traps_t *traps, XPointFixed t[3])
|
|||
{
|
||||
cairo_status_t status;
|
||||
XLineFixed line;
|
||||
double intersect;
|
||||
cairo_fixed_16_16_t intersect;
|
||||
XPointFixed tsort[3];
|
||||
|
||||
memcpy (tsort, t, 3 * sizeof (XPointFixed));
|
||||
|
|
@ -281,17 +281,25 @@ static int
|
|||
_compare_cairo_edge_by_slope (const void *av, const void *bv)
|
||||
{
|
||||
const cairo_edge_t *a = av, *b = bv;
|
||||
cairo_fixed_32_32_t d;
|
||||
|
||||
double a_dx = XFixedToDouble (a->edge.p2.x - a->edge.p1.x);
|
||||
double a_dy = XFixedToDouble (a->edge.p2.y - a->edge.p1.y);
|
||||
double b_dx = XFixedToDouble (b->edge.p2.x - b->edge.p1.x);
|
||||
double b_dy = XFixedToDouble (b->edge.p2.y - b->edge.p1.y);
|
||||
cairo_fixed_48_16_t a_dx = a->edge.p2.x - a->edge.p1.x;
|
||||
cairo_fixed_48_16_t a_dy = a->edge.p2.y - a->edge.p1.y;
|
||||
cairo_fixed_48_16_t b_dx = b->edge.p2.x - b->edge.p1.x;
|
||||
cairo_fixed_48_16_t b_dy = b->edge.p2.y - b->edge.p1.y;
|
||||
|
||||
return b_dy * a_dx - a_dy * b_dx;
|
||||
d = b_dy * a_dx - a_dy * b_dx;
|
||||
|
||||
if (d > 0)
|
||||
return 1;
|
||||
else if (d == 0)
|
||||
return 0;
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int
|
||||
_compare_cairo_edge_by_current_xthen_slope (const void *av, const void *bv)
|
||||
_compare_cairo_edge_by_current_x_then_slope (const void *av, const void *bv)
|
||||
{
|
||||
const cairo_edge_t *a = av, *b = bv;
|
||||
int ret;
|
||||
|
|
@ -354,12 +362,12 @@ _lines_intersect (XLineFixed *l1, XLineFixed *l2, XFixed *y_intersection)
|
|||
return 1;
|
||||
}
|
||||
*/
|
||||
static XFixed
|
||||
static cairo_fixed_16_16_t
|
||||
_compute_x (XLineFixed *line, XFixed y)
|
||||
{
|
||||
XFixed dx = line->p2.x - line->p1.x;
|
||||
double ex = (double) (y - line->p1.y) * (double) dx;
|
||||
XFixed dy = line->p2.y - line->p1.y;
|
||||
cairo_fixed_16_16_t dx = line->p2.x - line->p1.x;
|
||||
cairo_fixed_32_32_t ex = (cairo_fixed_48_16_t) (y - line->p1.y) * (cairo_fixed_48_16_t) dx;
|
||||
cairo_fixed_16_16_t dy = line->p2.y - line->p1.y;
|
||||
|
||||
return line->p1.x + (ex / dy);
|
||||
}
|
||||
|
|
@ -378,7 +386,7 @@ _compute_x_intercept (XLineFixed *l, double inverse_slope)
|
|||
}
|
||||
|
||||
static int
|
||||
_lines_intersect (XLineFixed *l1, XLineFixed *l2, XFixed *y_intersection)
|
||||
_line_seg_intersection_ceil (XLineFixed *left, XLineFixed *right, XFixed *y_intersection)
|
||||
{
|
||||
/*
|
||||
* x = m1y + b1
|
||||
|
|
@ -387,15 +395,22 @@ _lines_intersect (XLineFixed *l1, XLineFixed *l2, XFixed *y_intersection)
|
|||
* y * (m1 - m2) = b2 - b1
|
||||
* y = (b2 - b1) / (m1 - m2)
|
||||
*/
|
||||
double m1 = _compute_inverse_slope (l1);
|
||||
double b1 = _compute_x_intercept (l1, m1);
|
||||
double m2 = _compute_inverse_slope (l2);
|
||||
double b2 = _compute_x_intercept (l2, m2);
|
||||
cairo_fixed_16_16_t y;
|
||||
double m1 = _compute_inverse_slope (left);
|
||||
double b1 = _compute_x_intercept (left, m1);
|
||||
double m2 = _compute_inverse_slope (right);
|
||||
double b2 = _compute_x_intercept (right, m2);
|
||||
|
||||
if (m1 == m2)
|
||||
return 0;
|
||||
|
||||
*y_intersection = XDoubleToFixed ((b2 - b1) / (m1 - m2));
|
||||
y = XDoubleToFixed ((b2 - b1) / (m1 - m2));
|
||||
|
||||
if (_compute_x (right, y) < _compute_x (left, y))
|
||||
y++;
|
||||
|
||||
*y_intersection = y;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
@ -414,7 +429,7 @@ _SortEdgeList (cairo_edge_t **active)
|
|||
*/
|
||||
for (en = next; en; en = en->next)
|
||||
{
|
||||
if (_compare_cairo_edge_by_current_xthen_slope (e, en) > 0)
|
||||
if (_compare_cairo_edge_by_current_x_then_slope (e, en) > 0)
|
||||
{
|
||||
/*
|
||||
* insert en before e
|
||||
|
|
@ -531,14 +546,9 @@ cairo_traps_tessellate_polygon (cairo_traps_t *traps,
|
|||
next_y = e->edge.p2.y;
|
||||
/* check intersect */
|
||||
if (en && e->current_x != en->current_x)
|
||||
if (_lines_intersect (&e->edge, &en->edge, &intersect)) {
|
||||
/* Need to make sure that when we next compute X
|
||||
values for these two edges, that they will sort
|
||||
as if after the intersection. */
|
||||
intersect++;
|
||||
if (_line_seg_intersection_ceil (&e->edge, &en->edge, &intersect))
|
||||
if (intersect > y && intersect < next_y)
|
||||
next_y = intersect;
|
||||
}
|
||||
}
|
||||
/* check next inactive point */
|
||||
if (inactive < num_edges && edges[inactive].edge.p1.y < next_y)
|
||||
|
|
|
|||
|
|
@ -36,6 +36,8 @@
|
|||
#ifndef _CAIROINT_H_
|
||||
#define _CAIROINT_H_
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#include <math.h>
|
||||
#include <X11/Xlibint.h>
|
||||
#include <X11/Xft/Xft.h>
|
||||
|
|
@ -46,6 +48,28 @@
|
|||
#define __attribute__(x)
|
||||
#endif
|
||||
|
||||
#ifdef WIN32
|
||||
typedef __int64 cairo_fixed_32_32_t;
|
||||
#else
|
||||
# if defined(__alpha__) || defined(__alpha) || \
|
||||
defined(ia64) || defined(__ia64__) || \
|
||||
defined(__sparc64__) || \
|
||||
defined(__s390x__) || \
|
||||
defined(x86_64) || defined (__x86_64__)
|
||||
typedef long cairo_fixed_32_32_t;
|
||||
# else
|
||||
# if defined(__GNUC__) && \
|
||||
((__GNUC__ > 2) || \
|
||||
((__GNUC__ == 2) && defined(__GNUC_MINOR__) && (__GNUC_MINOR__ > 7)))
|
||||
__extension__
|
||||
# endif
|
||||
typedef long long int cairo_fixed_32_32_t;
|
||||
# endif
|
||||
#endif
|
||||
|
||||
typedef cairo_fixed_32_32_t cairo_fixed_48_16_t;
|
||||
typedef int32_t cairo_fixed_16_16_t;
|
||||
|
||||
/* Sure wish C had a real enum type so that this would be distinct
|
||||
from cairo_status_t. Oh well, without that, I'll use this bogus 1000
|
||||
offset */
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue