1 /*
2  * see COPYRIGHT
3  */
4 
5 
6 /* glyph entry, one drawing command */
7 typedef struct gentry {
8 	/* this list links all GENTRYs of a GLYPH sequentially */
9 	struct gentry  *next;	/* double linked list */
10 	struct gentry  *prev;
11 
12 	/* this list links all GENTRYs of one contour -
13 	 * of types GE_LINE and GE_CURVE only
14 	 * bkwd is also reused: in the very first entry (normally
15 	 * of type GE_MOVE) it points to g->entries
16 	 */
17 	struct gentry  *cntr[2]; /* double-linked circular list */
18 /* convenience handles */
19 #define bkwd cntr[0]
20 #define frwd cntr[1]
21 
22 	/* various extended structures used at some stage of transformation */
23 	void *ext;
24 
25 	union {
26 		struct {
27 			int  val[2][3];	/* integer values */
28 		} i;
29 		struct {
30 			double  val[2][3];	/* floating values */
31 		} f;
32 	} points; /* absolute values, NOT deltas */
33 /* convenience handles */
34 #define ipoints	points.i.val
35 #define fpoints	points.f.val
36 #define ixn ipoints[0]
37 #define iyn ipoints[1]
38 #define fxn fpoints[0]
39 #define fyn fpoints[1]
40 #define ix1	ixn[0]
41 #define ix2 ixn[1]
42 #define ix3 ixn[2]
43 #define iy1	iyn[0]
44 #define iy2 iyn[1]
45 #define iy3 iyn[2]
46 #define fx1	fxn[0]
47 #define fx2 fxn[1]
48 #define fx3 fxn[2]
49 #define fy1	fyn[0]
50 #define fy2 fyn[1]
51 #define fy3 fyn[2]
52 
53 	char            flags;
54 #define GEF_FLOAT	0x02 /* entry contains floating point data */
55 #define GEF_LINE	0x04 /* entry looks like a line even if it's a curve */
56 
57 	unsigned char	dir; /* used to temporarily store the values for
58 				* the directions of the ends of curves */
59 /* front end */
60 #define CVDIR_FUP	0x02	/* goes over the line connecting the ends */
61 #define CVDIR_FEQUAL	0x01	/* coincides with the line connecting the
62 				 * ends */
63 #define CVDIR_FDOWN	0x00	/* goes under the line connecting the ends */
64 #define CVDIR_FRONT	0x0F	/* mask of all front directions */
65 /* rear end */
66 #define CVDIR_RSAME	0x30	/* is the same as for the front end */
67 #define CVDIR_RUP	0x20	/* goes over the line connecting the ends */
68 #define CVDIR_REQUAL	0x10	/* coincides with the line connecting the
69 				 * ends */
70 #define CVDIR_RDOWN	0x00	/* goes under the line connecting the ends */
71 #define CVDIR_REAR	0xF0	/* mask of all rear directions */
72 
73 	signed char     stemid; /* connection to the substituted stem group */
74 	char            type;
75 #define GE_HSBW	'B'
76 #define GE_MOVE 'M'
77 #define GE_LINE 'L'
78 #define GE_CURVE 'C'
79 #define GE_PATH 'P'
80 
81 	/* indexes of the points to be used for calculation of the tangents */
82 	signed char     ftg; /* front tangent */
83 	signed char     rtg; /* rear tangent, -1 means "idx 2 of the previous entry" */
84 }               GENTRY;
85 
86 /* stem structure, describes one [hv]stem  */
87 /* acually, it describes one border of a stem */
88 /* the whole stem is a pair of these structures */
89 
90 typedef struct stem {
91 	short           value;	/* value of X or Y coordinate */
92 	short           origin;	/* point of origin for curve stems */
93 	GENTRY         *ge; /* entry that has (value, origin) as its first dot */
94 		/* also for all the stems the couple (value, origin)
95 		 * is used to determine whether a stem is relevant for a
96 		 * line, it's considered revelant if this tuple is
97 		 * equal to any of the ends of the line.
98 		 * ge is also used to resolve ambiguity if there is more than
99 		 * one line going through certain pointi, it is used to
100 		 * distinguish these lines.
101 		 */
102 
103 	short           from, to;	/* values of other coordinate between
104 					 * which this stem is valid */
105 
106 	short           flags;
107 	/* ordering of ST_END, ST_FLAT, ST_ZONE is IMPORTANT for sorting */
108 #define ST_END		0x01	/* end of line, lowest priority */
109 #define ST_FLAT		0x02	/* stem is defined by a flat line, not a
110 				 * curve */
111 #define ST_ZONE		0x04	/* pseudo-stem, the limit of a blue zone */
112 #define ST_UP		0x08	/* the black area is to up or right from
113 				 * value */
114 #define ST_3		0x20	/* first stem of [hv]stem3 */
115 #define ST_BLUE		0x40	/* stem is in blue zone */
116 #define ST_TOPZONE	0x80	/* 1 - top zone, 0 - bottom zone */
117 #define ST_VERT     0x100	/* vertical stem (used in substitutions) */
118 }               STEM;
119 
120 #define MAX_STEMS	2000	/* we can't have more stems than path
121 				 * elements (or hope so) */
122 #define NSTEMGRP	50	/* maximal number of the substituted stem groups */
123 
124 /* structure for economical representation of the
125  * substituted stems
126  */
127 
128 typedef struct stembounds {
129 	short low; /* low bound */
130 	short high; /* high bound */
131 	char isvert; /* 1 - vertical, 0 - horizontal */
132 	char already; /* temp. flag: is aleready included */
133 } STEMBOUNDS;
134 
135 struct kern {
136 	unsigned id; /* ID of the second glyph */
137 	int val; /* kerning value */
138 };
139 
140 typedef struct contour {
141 	short           ymin, xofmin;
142 	short           inside;	/* inside which contour */
143 	char            direction;
144 #define DIR_OUTER 1
145 #define DIR_INNER 0
146 }               CONTOUR;
147 
148 typedef struct glyph {
149 	int             char_no;/* Encoding of glyph */
150 	int             orig_code;/* code of glyph in the font's original encoding */
151 	char           *name;	/* Postscript name of glyph */
152 	int             xMin, yMin, xMax, yMax;	/* values from TTF dictionary */
153 	int             lsb; /* left sidebearing */
154 	int             ttf_pathlen; /* total length of TTF paths */
155 	short           width;
156 	short           flags;
157 #define GF_USED	0x0001		/* whether is this glyph used in T1 font */
158 #define GF_FLOAT 0x0002		/* thys glyph contains floating point entries */
159 
160 	GENTRY         *entries;/* doube linked list of entries */
161 	GENTRY         *lastentry;	/* the last inserted entry */
162 	GENTRY         *path;	/* beggining of the last path */
163 	int             oldwidth; /* actually also scaled */
164 	int             scaledwidth;
165 #define	MAXLEGALWIDTH	10000
166 
167 	struct kern    *kern; /* kerning data */
168 	int             kerncount; /* number of kerning pairs */
169 	int             kernalloc; /* for how many pairs we have space */
170 
171 	STEM           *hstems; /* global horiz. and vert. stems */
172 	STEM           *vstems;
173 	int             nhs, nvs;	/* numbers of stems */
174 
175 	STEMBOUNDS     *sbstems; /* substituted stems for all the groups */
176 	short          *nsbs; /* indexes of the group ends in the common array */
177 	int             nsg; /* actual number of the stem groups */
178 	int             firstsubr; /* first substistuted stems subroutine number */
179 
180 	CONTOUR        *contours;	/* it is not used now */
181 	int             ncontours;
182 
183 	int             rymin, rymax;	/* real values */
184 	/* do we have flat surfaces on top/bottom */
185 	char            flatymin, flatymax;
186 
187 }               GLYPH;
188 
189 /* description of a dot for calculation of its distance to a curve */
190 
191 struct dot_dist {
192 	double p[2 /*X,Y*/]; /* coordinates of a dot */
193 	double dist2; /* squared distance from the dot to the curve */
194 	short seg; /* the closest segment of the curve */
195 };
196 
197 extern int      stdhw, stdvw;	/* dominant stems widths */
198 extern int      stemsnaph[12], stemsnapv[12];	/* most typical stem width */
199 
200 extern int      bluevalues[14];
201 extern int      nblues;
202 extern int      otherblues[10];
203 extern int      notherb;
204 extern int      bbox[4];	/* the FontBBox array */
205 extern double   italic_angle;
206 
207 extern GLYPH   *glyph_list;
208 extern int    encoding[];	/* inverse of glyph[].char_no */
209 
210 /* prototypes of functions */
211 void rmoveto( int dx, int dy);
212 void rlineto( int dx, int dy);
213 void rrcurveto( int dx1, int dy1, int dx2, int dy2, int dx3, int dy3);
214 void assertpath( GENTRY * from, char *file, int line, char *name);
215 
216 void fg_rmoveto( GLYPH * g, double x, double y);
217 void ig_rmoveto( GLYPH * g, int x, int y);
218 void fg_rlineto( GLYPH * g, double x, double y);
219 void ig_rlineto( GLYPH * g, int x, int y);
220 void fg_rrcurveto( GLYPH * g, double x1, double y1,
221 	double x2, double y2, double x3, double y3);
222 void ig_rrcurveto( GLYPH * g, int x1, int y1,
223 	int x2, int y2, int x3, int y3);
224 void g_closepath( GLYPH * g);
225 
226 void pathtoint( GLYPH *g);
227 void ffixquadrants( GLYPH *g);
228 void flattencurves( GLYPH * g);
229 int checkcv( GENTRY * ge, int dx, int dy);
230 void iclosepaths( GLYPH * g);
231 void fclosepaths( GLYPH * g);
232 void smoothjoints( GLYPH * g);
233 void buildstems( GLYPH * g);
234 void fstraighten( GLYPH * g);
235 void istraighten( GLYPH * g, int zigonly);
236 void isplitzigzags( GLYPH * g);
237 void fsplitzigzags( GLYPH * g);
238 void fforceconcise( GLYPH * g);
239 void iforceconcise( GLYPH * g);
240 void reversepathsfromto( GENTRY * from, GENTRY * to);
241 void reversepaths( GLYPH * g);
242 void dumppaths( GLYPH * g, GENTRY *start, GENTRY *end);
243 void print_glyph( int glyphno);
244 int print_glyph_subs( int glyphno, int startid);
245 void print_glyph_metrics( int code, int glyphno);
246 void findblues(void);
247 void stemstatistics(void);
248 void docorrectwidth(void);
249 void addkernpair( unsigned id1, unsigned id2, int unscval);
250 void print_kerning( FILE *afm_file);
251 
252 int fcrossrayscv( double curve[4][2], double *max1, double *max2);
253 int fcrossraysge( GENTRY *ge1, GENTRY *ge2, double *max1, double *max2,
254 	double crossdot[2][2]);
255 double fdotsegdist2( double seg[2][2], double dot[2]);
256 double fdotcurvdist2( double curve[4][2], struct dot_dist *dots, int ndots, double *maxp);
257 void fapproxcurve( double cv[4][2], struct dot_dist *dots, int ndots);
258