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);
|