summaryrefslogtreecommitdiffstats
path: root/src/path/splinefit/splinefont.h
blob: 83db934cec41f3d69d79b249e440ef81c25d6381 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
// SPDX-License-Identifier: GPL-2.0-or-later

#ifndef _SEEN_SPLINEFONT_H_
#define _SEEN_SPLINEFONT_H_

#include <glib.h>

typedef double real;
typedef double bigreal;
typedef double extended;
typedef int BOOL;

#define chunkalloc(size)	calloc(1,size)
#define chunkfree(item,size)	free(item)

typedef struct basepoint {
    real x;
    real y;
} BasePoint;

typedef struct ipoint {
    int x;
    int y;
} IPoint;

enum pointtype { pt_curve, pt_corner, pt_tangent, pt_hvcurve };
typedef struct splinepoint {
    BasePoint me;
    BasePoint nextcp;		/* control point */
    BasePoint prevcp;		/* control point */
    unsigned int nonextcp:1;
    unsigned int noprevcp:1;
    unsigned int nextcpdef:1;
    unsigned int prevcpdef:1;
    unsigned int selected:1;	/* for UI */
    unsigned int nextcpselected: 2; /* Is the next BCP selected */
    unsigned int prevcpselected: 2; /* Is the prev BCP selected */
    unsigned int pointtype:2;
    unsigned int isintersection: 1;
    unsigned int flexy: 1;	/* When "freetype_markup" is on in charview.c:DrawPoint */
    unsigned int flexx: 1;	/* flexy means select nextcp, and flexx means draw circle around nextcp */
    unsigned int roundx: 1;	/* For true type hinting */
    unsigned int roundy: 1;	/* For true type hinting */
    unsigned int dontinterpolate: 1;	/* in ttf, don't imply point by interpolating between cps */
    unsigned int ticked: 1;
    unsigned int watched: 1;
	/* 1 bits left... */
    uint16_t ptindex;		/* Temporary value used by metafont routine */
    uint16_t ttfindex;		/* Truetype point index */
	/* Special values 0xffff => point implied by averaging control points */
	/*		  0xfffe => point created with no real number yet */
	/* (or perhaps point in context where no number is possible as in a glyph with points & refs) */
    uint16_t nextcpindex;		/* Truetype point index */
    struct spline *next;
    struct spline *prev;
    /* Inkscape: not used; HintMask *hintmask; */
	char* name;
} SplinePoint;


typedef struct spline1d {
    real a, b, c, d;
} Spline1D;

typedef struct spline {
    unsigned int islinear: 1;		/* No control points */
    unsigned int isquadratic: 1;	/* probably read in from ttf */
    unsigned int isticked: 1;
    unsigned int isneeded: 1;		/* Used in remove overlap */
    unsigned int isunneeded: 1;		/* Used in remove overlap */
    unsigned int exclude: 1;		/* Used in remove overlap variant: exclude */
    unsigned int ishorvert: 1;
    unsigned int knowncurved: 1;	/* We know that it curves */
    unsigned int knownlinear: 1;	/* it might have control points, but still traces out a line */
	/* If neither knownlinear nor curved then we haven't checked */
    unsigned int order2: 1;		/* It's a bezier curve with only one cp */
    unsigned int touched: 1;
    unsigned int leftedge: 1;
    unsigned int rightedge: 1;
    unsigned int acceptableextrema: 1;	/* This spline has extrema, but we don't care */
    SplinePoint *from;
    SplinePoint *to;
    Spline1D splines[2];		/* splines[0] is the x spline, splines[1] is y */
    struct linearapprox *approx;
    /* Possible optimizations:
	Precalculate bounding box
	Precalculate min/max/ points of inflection
    */
} Spline;

typedef struct splinepointlist {
    SplinePoint *first, *last;
    struct splinepointlist *next;
    /* Not used:   spiro_cp *spiros; */
    uint16_t spiro_cnt, spiro_max;
	/* These could be bit fields, but bytes are easier to access and we */
	/*  don't need the space (yet) */
    uint8_t ticked;
    uint8_t beziers_need_optimizer;	/* If the spiros have changed in spiro mode, then reverting to bezier mode might, someday, run a simplifier */
    uint8_t is_clip_path;			/* In type3/svg fonts */
    int start_offset; // This indicates which point is the canonical first for purposes of outputting to U. F. O..
    char *contour_name;
} SplinePointList, SplineSet;

typedef struct dbounds {
    real minx, maxx;
    real miny, maxy;
} DBounds;

typedef struct quartic {
    bigreal a,b,c,d,e;
} Quartic;


int RealWithin(real a,real b,real fudge);
BOOL RealNear(real a, real b);

Spline *SplineMake(SplinePoint *from, SplinePoint *to, int order2);
Spline *SplineMake2(SplinePoint *from, SplinePoint *to);
Spline *SplineMake3(SplinePoint *from, SplinePoint *to);
SplinePoint *SplinePointCreate(real x, real y);

void SplineRefigure3(Spline *spline);
void SplineRefigure(Spline *spline);
int SplineIsLinear(Spline *spline);
void SplineFindExtrema(const Spline1D *sp, extended *_t1, extended *_t2 );
bigreal SplineMinDistanceToPoint(Spline *s, BasePoint *p);

void SplinePointFree(SplinePoint *sp);
void SplineFree(Spline *spline);
void SplinePointListFree(SplinePointList *spl);

bigreal BPDot(BasePoint v1, BasePoint v2);
bigreal BPCross(BasePoint v1, BasePoint v2);
BasePoint BPRev(BasePoint v);

int _CubicSolve(const Spline1D *sp,bigreal sought, extended ts[3]);
int _QuarticSolve(Quartic *q,extended ts[4]);
int IntersectLines(BasePoint *inter,
	BasePoint *line1_1, BasePoint *line1_2,
	BasePoint *line2_1, BasePoint *line2_2);

#define IError(msg) g_warning(msg)
#define TRACE g_message

enum linelist_flags { cvli_onscreen=0x1, cvli_clipped=0x2 };

typedef struct linelist {
    IPoint here;
    struct linelist *next;
    /* The first two fields are constant for the linelist, the next ones */
    /*  refer to a particular screen. If some portion of the line from */
    /*  this point to the next one is on the screen then set cvli_onscreen */
    /*  if this point needs to be clipped then set cvli_clipped */
    /*  asend and asstart are the actual screen locations where this point */
    /*  intersects the clip edge. */
    enum linelist_flags flags;
    IPoint asend, asstart;
} LineList;

typedef struct linearapprox {
    real scale;
    unsigned int oneline: 1;
    unsigned int onepoint: 1;
    unsigned int any: 1;		/* refers to a particular screen */
    struct linelist *lines;
    struct linearapprox *next;
} LinearApprox;

void LinearApproxFree(LinearApprox *la);

int Within16RoundingErrors(bigreal v1, bigreal v2);

enum pconvert_flags {
	// Point selection (mutually exclusive)
	pconvert_flag_none = 0x01,
	pconvert_flag_all = 0x02,
	pconvert_flag_smooth = 0x04,
	pconvert_flag_incompat = 0x08,
	// Conversion modes (mutually exclusive)
	pconvert_flag_by_geom = 0x100,
	pconvert_flag_force_type = 0x200,
	pconvert_flag_downgrade = 0x400,
	pconvert_flag_check_compat = 0x0800,
	// Additional
	pconvert_flag_hvcurve = 0x4000
};

void SplinesRemoveBetween(SplinePoint *from, SplinePoint *to, int type);

#endif // _SEEN_SPLINEFONT_H_