beta-0.89.2
[luatex.git] / source / texk / web2c / luatexdir / luafontloader / fontforge / fontforge / splinerefigure.c
blobb651a241960caaec7d81dd5fddd0b66d29f7b51b
1 /* Copyright (C) 2000-2008 by George Williams */
2 /*
3 * Redistribution and use in source and binary forms, with or without
4 * modification, are permitted provided that the following conditions are met:
6 * Redistributions of source code must retain the above copyright notice, this
7 * list of conditions and the following disclaimer.
9 * Redistributions in binary form must reproduce the above copyright notice,
10 * this list of conditions and the following disclaimer in the documentation
11 * and/or other materials provided with the distribution.
13 * The name of the author may not be used to endorse or promote products
14 * derived from this software without specific prior written permission.
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
19 * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
22 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
23 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
24 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
25 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 #include "pfaedit.h"
28 #include <stdio.h>
29 #include <math.h>
30 #include "splinefont.h"
31 #ifdef HAVE_IEEEFP_H
32 # include <ieeefp.h> /* Solaris defines isnan in ieeefp rather than math.h */
33 #endif
35 /* The slight errors introduced by the optimizer turn out to have nasty */
36 /* side effects. An error on the order of 7e-8 in splines[1].b caused */
37 /* the rasterizer to have kaniptions */
38 void SplineRefigure3(Spline *spline) {
39 SplinePoint *from = spline->from, *to = spline->to;
40 Spline1D *xsp = &spline->splines[0], *ysp = &spline->splines[1];
41 Spline old;
43 #ifdef DEBUG
44 if ( RealNear(from->me.x,to->me.x) && RealNear(from->me.y,to->me.y))
45 IError("Zero length spline created");
46 #endif
47 if ( spline->acceptableextrema )
48 old = *spline;
49 xsp->d = from->me.x; ysp->d = from->me.y;
50 if ( from->nonextcp ) from->nextcp = from->me;
51 else if ( from->nextcp.x==from->me.x && from->nextcp.y == from->me.y ) from->nonextcp = true;
52 if ( to->noprevcp ) to->prevcp = to->me;
53 else if ( to->prevcp.x==to->me.x && to->prevcp.y == to->me.y ) to->noprevcp = true;
54 if ( from->nonextcp && to->noprevcp ) {
55 spline->islinear = true;
56 xsp->c = to->me.x-from->me.x;
57 ysp->c = to->me.y-from->me.y;
58 xsp->a = xsp->b = 0;
59 ysp->a = ysp->b = 0;
60 } else {
61 /* from p. 393 (Operator Details, curveto) Postscript Lang. Ref. Man. (Red book) */
62 xsp->c = 3*(from->nextcp.x-from->me.x);
63 ysp->c = 3*(from->nextcp.y-from->me.y);
64 xsp->b = 3*(to->prevcp.x-from->nextcp.x)-xsp->c;
65 ysp->b = 3*(to->prevcp.y-from->nextcp.y)-ysp->c;
66 xsp->a = to->me.x-from->me.x-xsp->c-xsp->b;
67 ysp->a = to->me.y-from->me.y-ysp->c-ysp->b;
68 if ( RealNear(xsp->c,0)) xsp->c=0;
69 if ( RealNear(ysp->c,0)) ysp->c=0;
70 if ( RealNear(xsp->b,0)) xsp->b=0;
71 if ( RealNear(ysp->b,0)) ysp->b=0;
72 if ( RealNear(xsp->a,0)) xsp->a=0;
73 if ( RealNear(ysp->a,0)) ysp->a=0;
74 spline->islinear = false;
75 if ( ysp->a==0 && xsp->a==0 && ysp->b==0 && xsp->b==0 )
76 spline->islinear = true; /* This seems extremely unlikely... */
78 if ( !finite(ysp->a) || !finite(xsp->a) || !finite(ysp->c) || !finite(xsp->c) || !finite(ysp->d) || !finite(xsp->d))
79 IError("NaN value in spline creation");
80 LinearApproxFree(spline->approx);
81 spline->approx = NULL;
82 spline->knowncurved = false;
83 spline->knownlinear = spline->islinear;
84 SplineIsLinear(spline);
85 spline->isquadratic = false;
86 if ( !spline->knownlinear && xsp->a==0 && ysp->a==0 )
87 spline->isquadratic = true; /* Only likely if we read in a TTF */
88 spline->order2 = false;
90 if ( spline->acceptableextrema ) {
91 /* I don't check "d", because changes to that reflect simple */
92 /* translations which will not affect the shape of the spline */
93 if ( !RealNear(old.splines[0].a,spline->splines[0].a) ||
94 !RealNear(old.splines[0].b,spline->splines[0].b) ||
95 !RealNear(old.splines[0].c,spline->splines[0].c) ||
96 !RealNear(old.splines[1].a,spline->splines[1].a) ||
97 !RealNear(old.splines[1].b,spline->splines[1].b) ||
98 !RealNear(old.splines[1].c,spline->splines[1].c) )
99 spline->acceptableextrema = false;