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
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
|
/*
* see COPYRIGHT
*/
/* glyph entry, one drawing command */
typedef struct gentry {
/* this list links all GENTRYs of a GLYPH sequentially */
struct gentry *next; /* double linked list */
struct gentry *prev;
/* this list links all GENTRYs of one contour -
* of types GE_LINE and GE_CURVE only
* bkwd is also reused: in the very first entry (normally
* of type GE_MOVE) it points to g->entries
*/
struct gentry *cntr[2]; /* double-linked circular list */
/* convenience handles */
#define bkwd cntr[0]
#define frwd cntr[1]
/* various extended structures used at some stage of transformation */
void *ext;
union {
struct {
int val[2][3]; /* integer values */
} i;
struct {
double val[2][3]; /* floating values */
} f;
} points; /* absolute values, NOT deltas */
/* convenience handles */
#define ipoints points.i.val
#define fpoints points.f.val
#define ixn ipoints[0]
#define iyn ipoints[1]
#define fxn fpoints[0]
#define fyn fpoints[1]
#define ix1 ixn[0]
#define ix2 ixn[1]
#define ix3 ixn[2]
#define iy1 iyn[0]
#define iy2 iyn[1]
#define iy3 iyn[2]
#define fx1 fxn[0]
#define fx2 fxn[1]
#define fx3 fxn[2]
#define fy1 fyn[0]
#define fy2 fyn[1]
#define fy3 fyn[2]
char flags;
#define GEF_FLOAT 0x02 /* entry contains floating point data */
#define GEF_LINE 0x04 /* entry looks like a line even if it's a curve */
unsigned char dir; /* used to temporarily store the values for
* the directions of the ends of curves */
/* front end */
#define CVDIR_FUP 0x02 /* goes over the line connecting the ends */
#define CVDIR_FEQUAL 0x01 /* coincides with the line connecting the
* ends */
#define CVDIR_FDOWN 0x00 /* goes under the line connecting the ends */
#define CVDIR_FRONT 0x0F /* mask of all front directions */
/* rear end */
#define CVDIR_RSAME 0x30 /* is the same as for the front end */
#define CVDIR_RUP 0x20 /* goes over the line connecting the ends */
#define CVDIR_REQUAL 0x10 /* coincides with the line connecting the
* ends */
#define CVDIR_RDOWN 0x00 /* goes under the line connecting the ends */
#define CVDIR_REAR 0xF0 /* mask of all rear directions */
signed char stemid; /* connection to the substituted stem group */
char type;
#define GE_HSBW 'B'
#define GE_MOVE 'M'
#define GE_LINE 'L'
#define GE_CURVE 'C'
#define GE_PATH 'P'
/* indexes of the points to be used for calculation of the tangents */
signed char ftg; /* front tangent */
signed char rtg; /* rear tangent, -1 means "idx 2 of the previous entry" */
} GENTRY;
/* stem structure, describes one [hv]stem */
/* acually, it describes one border of a stem */
/* the whole stem is a pair of these structures */
typedef struct stem {
short value; /* value of X or Y coordinate */
short origin; /* point of origin for curve stems */
GENTRY *ge; /* entry that has (value, origin) as its first dot */
/* also for all the stems the couple (value, origin)
* is used to determine whether a stem is relevant for a
* line, it's considered revelant if this tuple is
* equal to any of the ends of the line.
* ge is also used to resolve ambiguity if there is more than
* one line going through certain pointi, it is used to
* distinguish these lines.
*/
short from, to; /* values of other coordinate between
* which this stem is valid */
short flags;
/* ordering of ST_END, ST_FLAT, ST_ZONE is IMPORTANT for sorting */
#define ST_END 0x01 /* end of line, lowest priority */
#define ST_FLAT 0x02 /* stem is defined by a flat line, not a
* curve */
#define ST_ZONE 0x04 /* pseudo-stem, the limit of a blue zone */
#define ST_UP 0x08 /* the black area is to up or right from
* value */
#define ST_3 0x20 /* first stem of [hv]stem3 */
#define ST_BLUE 0x40 /* stem is in blue zone */
#define ST_TOPZONE 0x80 /* 1 - top zone, 0 - bottom zone */
#define ST_VERT 0x100 /* vertical stem (used in substitutions) */
} STEM;
#define MAX_STEMS 2000 /* we can't have more stems than path
* elements (or hope so) */
#define NSTEMGRP 50 /* maximal number of the substituted stem groups */
/* structure for economical representation of the
* substituted stems
*/
typedef struct stembounds {
short low; /* low bound */
short high; /* high bound */
char isvert; /* 1 - vertical, 0 - horizontal */
char already; /* temp. flag: is aleready included */
} STEMBOUNDS;
struct kern {
unsigned id; /* ID of the second glyph */
int val; /* kerning value */
};
typedef struct contour {
short ymin, xofmin;
short inside; /* inside which contour */
char direction;
#define DIR_OUTER 1
#define DIR_INNER 0
} CONTOUR;
typedef struct glyph {
int char_no;/* Encoding of glyph */
int orig_code;/* code of glyph in the font's original encoding */
char *name; /* Postscript name of glyph */
int xMin, yMin, xMax, yMax; /* values from TTF dictionary */
int lsb; /* left sidebearing */
int ttf_pathlen; /* total length of TTF paths */
short width;
short flags;
#define GF_USED 0x0001 /* whether is this glyph used in T1 font */
#define GF_FLOAT 0x0002 /* thys glyph contains floating point entries */
GENTRY *entries;/* doube linked list of entries */
GENTRY *lastentry; /* the last inserted entry */
GENTRY *path; /* beggining of the last path */
int oldwidth; /* actually also scaled */
int scaledwidth;
#define MAXLEGALWIDTH 10000
struct kern *kern; /* kerning data */
int kerncount; /* number of kerning pairs */
int kernalloc; /* for how many pairs we have space */
STEM *hstems; /* global horiz. and vert. stems */
STEM *vstems;
int nhs, nvs; /* numbers of stems */
STEMBOUNDS *sbstems; /* substituted stems for all the groups */
short *nsbs; /* indexes of the group ends in the common array */
int nsg; /* actual number of the stem groups */
int firstsubr; /* first substistuted stems subroutine number */
CONTOUR *contours; /* it is not used now */
int ncontours;
int rymin, rymax; /* real values */
/* do we have flat surfaces on top/bottom */
char flatymin, flatymax;
} GLYPH;
/* description of a dot for calculation of its distance to a curve */
struct dot_dist {
double p[2 /*X,Y*/]; /* coordinates of a dot */
double dist2; /* squared distance from the dot to the curve */
short seg; /* the closest segment of the curve */
};
extern int stdhw, stdvw; /* dominant stems widths */
extern int stemsnaph[12], stemsnapv[12]; /* most typical stem width */
extern int bluevalues[14];
extern int nblues;
extern int otherblues[10];
extern int notherb;
extern int bbox[4]; /* the FontBBox array */
extern double italic_angle;
extern GLYPH *glyph_list;
extern int encoding[]; /* inverse of glyph[].char_no */
/* prototypes of functions */
void rmoveto( int dx, int dy);
void rlineto( int dx, int dy);
void rrcurveto( int dx1, int dy1, int dx2, int dy2, int dx3, int dy3);
void assertpath( GENTRY * from, char *file, int line, char *name);
void fg_rmoveto( GLYPH * g, double x, double y);
void ig_rmoveto( GLYPH * g, int x, int y);
void fg_rlineto( GLYPH * g, double x, double y);
void ig_rlineto( GLYPH * g, int x, int y);
void fg_rrcurveto( GLYPH * g, double x1, double y1,
double x2, double y2, double x3, double y3);
void ig_rrcurveto( GLYPH * g, int x1, int y1,
int x2, int y2, int x3, int y3);
void g_closepath( GLYPH * g);
void pathtoint( GLYPH *g);
void ffixquadrants( GLYPH *g);
void flattencurves( GLYPH * g);
int checkcv( GENTRY * ge, int dx, int dy);
void iclosepaths( GLYPH * g);
void fclosepaths( GLYPH * g);
void smoothjoints( GLYPH * g);
void buildstems( GLYPH * g);
void fstraighten( GLYPH * g);
void istraighten( GLYPH * g, int zigonly);
void isplitzigzags( GLYPH * g);
void fsplitzigzags( GLYPH * g);
void fforceconcise( GLYPH * g);
void iforceconcise( GLYPH * g);
void reversepathsfromto( GENTRY * from, GENTRY * to);
void reversepaths( GLYPH * g);
void dumppaths( GLYPH * g, GENTRY *start, GENTRY *end);
void print_glyph( int glyphno);
int print_glyph_subs( int glyphno, int startid);
void print_glyph_metrics( int code, int glyphno);
void findblues(void);
void stemstatistics(void);
void docorrectwidth(void);
void addkernpair( unsigned id1, unsigned id2, int unscval);
void print_kerning( FILE *afm_file);
int fcrossrayscv( double curve[4][2], double *max1, double *max2);
int fcrossraysge( GENTRY *ge1, GENTRY *ge2, double *max1, double *max2,
double crossdot[2][2]);
double fdotsegdist2( double seg[2][2], double dot[2]);
double fdotcurvdist2( double curve[4][2], struct dot_dist *dots, int ndots, double *maxp);
void fapproxcurve( double cv[4][2], struct dot_dist *dots, int ndots);
|