/* * 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( FILE *afm_file, int code, int glyphno); void print_glyph_metrics_ufm( FILE *ufm_file, 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);