[gs-cvs] rev 7753 - in trunk/gs: doc src
leonardo at ghostscript.com
leonardo at ghostscript.com
Thu Mar 1 07:27:40 PST 2007
Author: leonardo
Date: 2007-03-01 07:27:39 -0800 (Thu, 01 Mar 2007)
New Revision: 7753
Modified:
trunk/gs/doc/pscet_status.txt
trunk/gs/src/gspath1.c
Log:
Fix (graphics) : Imprecise current point after drawing an arc (continued).
DETAILS :
The old code uses 'fixed' representation for an angle of an arc.
It appears insufficiently precise.
The new code performs the angle computations in doubles.
The patch intentionally doesn't change the algorithm.
EXPECTED DIFFERENCES :
None with comparefiles (wondering).
CET :
11-01-1 progression
11-02-1 progression
11-17-1 unimportant single pixel difference
11-17-2 unimportant single pixel difference
Modified: trunk/gs/doc/pscet_status.txt
===================================================================
--- trunk/gs/doc/pscet_status.txt 2007-03-01 12:50:10 UTC (rev 7752)
+++ trunk/gs/doc/pscet_status.txt 2007-03-01 15:27:39 UTC (rev 7753)
@@ -1573,7 +1573,7 @@
10-16-6 OK Minor differences in positions and character shapes - ADC
-11-01-1 DIFF Slightly different coords in 2 cases. assign igor
+11-01-1 AOK Matches Tek. CPSI slightly differs in few coordinates.
11-01-2 OK
@@ -1590,7 +1590,7 @@
which depends on the flattening factor of the original curve.
With CPSI look30 has a smaller number of peaks.
-11-02-1 DIFF Same as 11-01-1 assign igor
+11-02-1 AOK Same as 11-01-1
11-02-2 OK Minor differences visually reviewed by RJJ
Modified: trunk/gs/src/gspath1.c
===================================================================
--- trunk/gs/src/gspath1.c 2007-03-01 12:50:10 UTC (rev 7752)
+++ trunk/gs/src/gspath1.c 2007-03-01 15:27:39 UTC (rev 7753)
@@ -47,7 +47,7 @@
segment_notes notes;
gs_point p0, p3, pt;
gs_sincos_t sincos; /* (not used by arc_add) */
- fixed angle; /* (not used by arc_add) */
+ double angle; /* (not used by arc_add) */
int fast_quadrant; /* 0 = not calculated, -1 = not fast, */
/* 1 = fast (only used for quadrants) */
/* The following are set once iff fast_quadrant > 0. */
@@ -117,17 +117,17 @@
/* Compute the next curve as part of an arc. */
private int
-next_arc_curve(arc_curve_params_t * arc, fixed anext)
+next_arc_curve(arc_curve_params_t * arc, double anext)
{
double x0 = arc->p0.x = arc->p3.x;
double y0 = arc->p0.y = arc->p3.y;
double trad = arc->radius *
- tan(fixed2float(anext - arc->angle) *
+ tan((anext - arc->angle) *
(degrees_to_radians / 2));
arc->pt.x = x0 - trad * arc->sincos.sin;
arc->pt.y = y0 + trad * arc->sincos.cos;
- gs_sincos_degrees(fixed2float(anext), &arc->sincos);
+ gs_sincos_degrees(anext, &arc->sincos);
arc->p3.x = arc->center.x + arc->radius * arc->sincos.cos;
arc->p3.y = arc->center.y + arc->radius * arc->sincos.sin;
arc->angle = anext;
@@ -138,7 +138,7 @@
* and anext = arc.angle +/- 90.
*/
private int
-next_arc_quadrant(arc_curve_params_t * arc, fixed anext)
+next_arc_quadrant(arc_curve_params_t * arc, double anext)
{
double x0 = arc->p0.x = arc->p3.x;
double y0 = arc->p0.y = arc->p3.y;
@@ -171,7 +171,7 @@
* We know that anext is a multiple of 90 (as a fixed); we want
* (anext / 90) & 3. The following is much faster than a division.
*/
- switch ((fixed2int(anext) >> 1) & 3) {
+ switch (((int)anext >> 1) & 3) {
case 0:
arc->sincos.sin = 0, arc->sincos.cos = 1;
arc->p3.x = x0 = arc->center.x + arc->radius;
@@ -204,7 +204,7 @@
bool add_line, gs_point *p3)
{
double ar = arad;
- fixed ang1 = float2fixed(aang1), ang2 = float2fixed(aang2), anext;
+ double ang1 = aang1, ang2 = aang2, anext;
double ang1r; /* reduced angle */
arc_curve_params_t arc;
int code;
@@ -213,27 +213,24 @@
arc.pis = pis;
arc.center.x = axc;
arc.center.y = ayc;
-#define fixed_90 int2fixed(90)
-#define fixed_180 int2fixed(180)
-#define fixed_360 int2fixed(360)
if (ar < 0) {
- ang1 += fixed_180;
- ang2 += fixed_180;
+ ang1 += 180;
+ ang2 += 180;
ar = -ar;
}
arc.radius = ar;
arc.action = (add_line ? arc_lineto : arc_moveto);
arc.notes = sn_none;
arc.fast_quadrant = 0;
- ang1r = fixed2float(ang1 % fixed_360);
+ ang1r = fmod(ang1, 360);
gs_sincos_degrees(ang1r, &arc.sincos);
arc.p3.x = axc + ar * arc.sincos.cos;
arc.p3.y = ayc + ar * arc.sincos.sin;
if (clockwise) {
while (ang1 < ang2)
- ang2 -= fixed_360;
+ ang2 -= 360;
if (ang2 < 0) {
- fixed adjust = ROUND_UP(-ang2, fixed_360);
+ double adjust = ceil(-ang2 / 360) * 360;
ang1 += adjust, ang2 += adjust;
}
@@ -242,7 +239,7 @@
goto last;
/* Do the first part, up to a multiple of 90 degrees. */
if (!arc.sincos.orthogonal) {
- anext = ROUND_DOWN(arc.angle - fixed_epsilon, fixed_90);
+ anext = floor(arc.angle / 90) * 90;
if (anext < ang2)
goto last;
code = next_arc_curve(&arc, anext);
@@ -252,7 +249,7 @@
arc.notes = sn_not_first;
}
/* Do multiples of 90 degrees. Invariant: ang1 >= ang2 >= 0. */
- while ((anext = arc.angle - fixed_90) >= ang2) {
+ while ((anext = arc.angle - 90) >= ang2) {
code = next_arc_quadrant(&arc, anext);
if (code < 0)
return code;
@@ -261,9 +258,9 @@
}
} else {
while (ang2 < ang1)
- ang2 += fixed_360;
+ ang2 += 360;
if (ang1 < 0) {
- fixed adjust = ROUND_UP(-ang1, fixed_360);
+ double adjust = ceil(-ang1 / 360) * 360;
ang1 += adjust, ang2 += adjust;
}
@@ -276,7 +273,7 @@
}
/* Do the first part, up to a multiple of 90 degrees. */
if (!arc.sincos.orthogonal) {
- anext = ROUND_UP(arc.angle + fixed_epsilon, fixed_90);
+ anext = ceil(arc.angle / 90) * 90;
if (anext > ang2)
goto last;
code = next_arc_curve(&arc, anext);
@@ -286,7 +283,7 @@
arc.notes = sn_not_first;
}
/* Do multiples of 90 degrees. Invariant: 0 <= ang1 <= ang2. */
- while ((anext = arc.angle + fixed_90) <= ang2) {
+ while ((anext = arc.angle + 90) <= ang2) {
code = next_arc_quadrant(&arc, anext);
if (code < 0)
return code;
More information about the gs-cvs
mailing list