w32tex
About: TeX Live provides a comprehensive TeX system including all the major TeX-related programs, macro packages, and fonts that are free software. Windows sources.
  Fossies Dox: w32tex-src.tar.xz  ("unofficial" and yet experimental doxygen-generated source code documentation)  

glyf.c
Go to the documentation of this file.
1 /* glyf.c -- Load and print Glyf outline data
2  * Copyright (C) 1996 Li-Da Lho, All right reserved
3  */
4 #ifdef HAVE_CONFIG_H
5 #include <config.h>
6 #endif
7 
8 #include <stdio.h>
9 #include <stdlib.h>
10 #include <string.h>
11 #include "ttf.h"
12 #include "ttfutil.h"
13 
14 /* $Id: glyf.c,v 1.1.1.1 1998/06/05 07:47:52 robert Exp $ */
15 
16 static void ttfLoadSimpleGlyph(FILE *fp,GLYFPtr glyf,ULONG offset);
17 static void ttfPrintSimpleGlyph(FILE *fp,GLYFPtr glyf);
18 static void ttfLoadCompositeGlyph(FILE *fp,GLYFPtr glyf,ULONG offset);
19 static void ttfPrintCompositeGlyph(FILE*fp,GLYFPtr glyf);
20 static void ttfFreeCompositeGlyph(GLYFPtr glyf);
21 double fix2dbl(F2Dot14 fixed);
22 
23 /* Naming convention about GLYF and Glyph:
24  * High level functions which are exported should have their name
25  * contain GLYF, on the other hand, low level function (or structures)
26  * which is not intended to be exported should have their name
27  * contain Glyph
28  */
30 {
31  ULONG tag = FT_MAKE_TAG ('g', 'l', 'y', 'f');
32  TableDirPtr ptd;
33 
34  if ((ptd = ttfLookUpTableDir(tag, font)) != NULL)
35  {
36  font->glyphOffset = ptd->offset;
37  }
38 }
39 /* offset: where the specified glyph really starts
40  * callers should compute this themself form the loca tables */
42 {
43  xfseek(fp, offset, SEEK_SET, "ttfLoadGLYF");
44 
46  glyf->xMin = ttfGetFWord(fp);
47  glyf->yMin = ttfGetFWord(fp);
48  glyf->xMax = ttfGetFWord(fp);
49  glyf->yMax = ttfGetFWord(fp);
50 
51  offset += sizeof(USHORT) + 4*sizeof(FWord);
52 
53  if (glyf->numberOfContours >= 0)
55  else
57 }
59 {
60  fprintf(fp,"\t numberOfContours:\t %d%s\n", glyf->numberOfContours,
61  glyf->numberOfContours == -1 ? " (Composite)": "");
62  fprintf(fp,"\t xMin:\t\t\t %d\n", glyf->xMin);
63  fprintf(fp,"\t yMin:\t\t\t %d\n", glyf->yMin);
64  fprintf(fp,"\t xMax:\t\t\t %d\n", glyf->xMax);
65  fprintf(fp,"\t yMax:\t\t\t %d\n\n", glyf->yMax);
66 
67  if (glyf->numberOfContours >= 0)
68  ttfPrintSimpleGlyph(fp, glyf);
69  else
71 }
72 void ttfFreeGLYF(GLYFPtr glyf)
73 {
74  if (glyf->numberOfContours < 0)
76 }
78 {
79  SHORT nCnts = glyf->numberOfContours;
80  USHORT i,nIns,nPts;
81 
82  xfseek(fp, offset, SEEK_SET, "ttfLoadSimpleGlyph");
83 
84  if (nCnts != 0)
85  {
86  ttfReadUSHORT (glyf->endPtsOfContours, nCnts, fp);
87  nPts = (glyf->endPtsOfContours)[nCnts-1]+1;
88  }
89  else
90  /* there seems to be something wrong with my interpretation of
91  * NOGLYPH chars, doing this way in case there is a char that has
92  * zero contour */
93  nPts = 0;
94 
95  /* how to deal with zero instruction glyf properly ?? */
96  glyf->instructionLength = nIns = ttfGetUSHORT(fp);
97  if (nIns != 0)
98  {
99  if (fread(glyf->instructions, sizeof(BYTE), nIns, fp) != nIns)
100  ttfError("Error when getting instructions\n");
101  }
102 
103  for (i=0;i<nPts;i++)
104  {
105  BYTE j,c;
106  if (((glyf->flags)[i] = c = ttfGetBYTE(fp)) & FLAGS_REPEAT)
107  { /* if this flag should be repeated */
108  j = ttfGetBYTE(fp); /* j times */
109  while (j--)
110  {
111  i++;
112  (glyf->flags)[i] = c;
113 
114  }
115  }
116  }
117 
118  for (i=0;i<nPts;i++)
119  {
120  BYTE flag;
121  flag = (glyf->flags)[i];
122 
124  { /* if the coordinate is a BYTE */
125  if (flag & FLAGS_X_SAME)
126  (glyf->xCoordinates)[i] = (SHORT) ttfGetBYTE(fp);
127  else
128  (glyf->xCoordinates)[i] = (SHORT) -ttfGetBYTE(fp);
129  }
130  else
131  { /* the coordiante is a SHORT */
132  if (flag & FLAGS_X_SAME)
133  (glyf->xCoordinates)[i] = 0;
134  else
135  (glyf->xCoordinates)[i] = ttfGetSHORT(fp);
136  }
137  }
138  for (i=0;i<nPts;i++)
139  {
140  BYTE flag;
141  flag = (glyf->flags)[i];
142 
144  { /* if the coordinate is a BYTE */
145  if (flag & FLAGS_Y_SAME)
146  (glyf->yCoordinates)[i] = (SHORT) ttfGetBYTE(fp);
147  else
148  (glyf->yCoordinates)[i] = (SHORT) -ttfGetBYTE(fp);
149  }
150  else
151  { /* the coordiante is a SHORT */
152  if (flag & FLAGS_Y_SAME)
153  (glyf->yCoordinates)[i] = 0;
154  else
155  (glyf->yCoordinates)[i] = ttfGetSHORT(fp);
156  }
157  }
158 }
159 static void ttfPrintSimpleGlyph(FILE *fp, GLYFPtr glyf)
160 {
161  USHORT i, nPts, nCnts;
162  SHORT x=0, y=0;
163 
164  nPts = (glyf->endPtsOfContours)[glyf->numberOfContours-1]+1;
165  nCnts = glyf->numberOfContours;
166 
167  fprintf(fp,"\t EndPoints\n");
168  fprintf(fp,"\t ---------\n");
169  for (i=0;i<nCnts;i++)
170  fprintf(fp,"\t %d: %2d\n",i,(glyf->endPtsOfContours)[i]);
171  fprintf(fp,"\n");
172 
173  fprintf(fp,"\t Length of Instructions: %2d\n\n",glyf->instructionLength);
175 
176  fprintf(fp,"\t Flags\n");
177  fprintf(fp,"\t -----\n");
178  for (i=0;i<nPts;i++)
179  {
180  BYTE flag;
181  char buf[80];
182 
183  flag = (glyf->flags)[i];
184 
185  if (flag & FLAGS_Y_SAME)
186  sprintf(buf,"YDual ");
187  else
188  sprintf(buf," ");
189  if (flag & FLAGS_X_SAME)
190  strcat(buf,"XDual ");
191  else
192  strcat(buf," ");
193  if (flag & FLAGS_REPEAT)
194  strcat(buf,"Repeat ");
195  else
196  strcat(buf," ");
198  strcat(buf,"Y-Short ");
199  else
200  strcat(buf," ");
202  strcat(buf,"X-Short ");
203  else
204  strcat(buf," ");
205  if (flag & FLAGS_ON_CURVE)
206  strcat(buf,"On\n");
207  else
208  strcat(buf,"Off\n");
209 
210  fprintf(fp,"\t %2d: %s",i,buf);
211  }
212  fprintf(fp,"\n");
213  fprintf(fp,"\t Coordinates\n");
214  fprintf(fp,"\t -----------\n");
215  for (i=0;i<nPts;i++)
216  {
217  x += (glyf->xCoordinates)[i];
218  y += (glyf->yCoordinates)[i];
219  fprintf(fp,"\t %2d Rel ( %6d, %6d) -> Abs ( %6d, %6d)\n", i,
220  (glyf->xCoordinates)[i], (glyf->yCoordinates)[i], x, y);
221  }
222  fprintf(fp,"\n");
223 }
224 
226 {
227  USHORT nIns,flags;
228  Component *cur;
229 
230  xfseek(fp, offset, SEEK_SET, "ttfLoadCompositeGlyph");
231 
232  glyf->comp = cur = XCALLOC1 (Component);
233  cur->previous = NULL; /* beginning of a linked list */
234 
235  do {
236  cur->flags = flags = ttfGetUSHORT(fp);
237  cur->glyphIndex = ttfGetUSHORT(fp);
239  {
240  (cur->data).args[0] = ttfGetSHORT(fp);
241  (cur->data).args[1] = ttfGetSHORT(fp);
242  }
243  else
244  (cur->data).args[0] = ttfGetUSHORT(fp);
245 
246  if (flags & WE_HAVE_A_SCALE)
247  {
248  (cur->data).transform.scale = ttfGetF2Dot14(fp);
249  }
250  else if (flags & WE_HAVE_AN_X_AND_Y_SCALE)
251  {
252  (cur->data).transform.vector.xscale = ttfGetF2Dot14(fp);
253  (cur->data).transform.vector.yscale = ttfGetF2Dot14(fp);
254  }
255  else if (flags & WE_HAVE_A_TWO_BY_TWO)
256  {
257  (cur->data).transform.tensor.xscale = ttfGetF2Dot14(fp);
258  (cur->data).transform.tensor.scale01 = ttfGetF2Dot14(fp);
259  (cur->data).transform.tensor.scale10 = ttfGetF2Dot14(fp);
260  (cur->data).transform.tensor.yscale = ttfGetF2Dot14(fp);
261  }
262  /* allocate next component */
263  cur->next = XCALLOC1 (Component);
264  cur->next->previous = cur;
265  cur = cur->next; /* move to next component */
266  } while (flags & MORE_COMPONENT);
267  cur->next = NULL; /* end of the linked list */
268 
270  {
271  glyf->instructionLength = nIns = ttfGetUSHORT(fp);
272  if (fread(glyf->instructions, sizeof(BYTE), nIns, fp) != nIns)
273  ttfError("Error when loading instructions\n");
274  }
275  else
276  {
277  glyf->instructionLength = 0;
278  }
279 }
281 {
282  int i = 0;
283  char buf[80];
284  USHORT flags;
285  Component *cur;
286 
287  cur = glyf->comp;
288 
289  do {
290  flags = cur->flags;
291  fprintf(fp, "\t %d: Flags:\t 0x%x\n", i, flags);
292  fprintf(fp, "\t Glyf Index:\t %d\n", cur->glyphIndex);
294  {
296  {
297  fprintf(fp, "\t X WOffset:\t %d\n", (cur->data).args[0]);
298  fprintf(fp, "\t Y WOffset:\t %d\n", (cur->data).args[1]);
299  }
300  else
301  {
302  fprintf(fp, "\t X BOffset:\t %d\n",
303  (signed char) ((cur->data).args[0] >> 8 & 0xff));
304  fprintf(fp, "\t Y BOffset:\t %d\n",
305  (signed char) ((cur->data).args[0] & 0xff));
306  }
307  }
308  else
309  {
310  /* what the hell are the "patch points" ?? */
311  }
312 
313  if (flags & WE_HAVE_A_SCALE)
314  {
315  fprintf(fp, "\t X,Y Scale:\t %f\n",
316  fix2dbl((cur->data).transform.scale));
317  }
318  else if (flags & WE_HAVE_AN_X_AND_Y_SCALE)
319  {
320  fprintf(fp, "\t X Scale:\t %f\n",
321  fix2dbl((cur->data).transform.vector.xscale));
322  fprintf(fp, "\t Y Scale:\t %f\n",
323  fix2dbl((cur->data).transform.vector.yscale));
324  }
325  else if (flags & WE_HAVE_A_TWO_BY_TWO)
326  {
327  fprintf(fp, "\t X Scale:\t %f\n",
328  fix2dbl((cur->data).transform.tensor.xscale));
329  fprintf(fp, "\t X,Y Scale:\t %f\n",
330  fix2dbl((cur->data).transform.tensor.scale01));
331  fprintf(fp, "\t Y,X Scale:\t %f\n",
332  fix2dbl((cur->data).transform.tensor.scale10));
333  fprintf(fp, "\t Y Scale:\t %f\n",
334  fix2dbl((cur->data).transform.tensor.yscale));
335  }
336 
337  if (flags & ROUND_XY_TO_GRID)
338  sprintf(buf, "Round X,Y to Grid ");
339  else
340  sprintf(buf, " ");
341 
342  if (flags & NO_OVERLAP)
343  strcat(buf, "NO Overlap ");
344  else
345  strcat(buf, " ");
346 
347  if (flags & USE_MY_METRICS)
348  strcat(buf, "Use My Metrics ");
349  else
350  strcat(buf, " ");
351 
352  fprintf(fp, "\t Others:\t %s\n\n", buf);
353 
354  i++;
355  cur = cur->next;
356  } while (cur->next != NULL);
357 
358  fprintf(fp, "\n");
359 
361  {
362  fprintf(fp,"\t Length of Instructions: %2d\n\n",
363  glyf->instructionLength);
365  }
366 }
368 {
369  Component *cur,*next;
370 
371  cur = glyf->comp;
372 
373  do {
374  next = cur->next;
375  free(cur);
376  cur = next;
377  } while (cur != NULL);
378 }
379 
380 /* what I want:
381  * outter procedures should not have any ideas about where the glyph starts,
382  *
383  * it just provide the TTFont structure and the character code or the index
384  * of that glyph. Procedures below should do:
385  * 1. look up where the glyph data is.
386  * 2. provided some glyph cache mechanism for the reason that
387  * a. it is not necessary to load all glyph into memory, especially for
388  * eastern languages.
389  * b. if a glyph data has been loaded previously, it is not necessary to
390  * load it again.
391  * c. malloc and free are SLOW !!
392  */
393 /* Load a glyph by glyph index */
395 {
396  ULONG pos;
397  GLYFPtr glyf;
398 
399  /* compute the actual place where the glyph stored */
400  pos = font->glyphOffset + ttfLookUpGlyfLOCA(font->loca, idx);
401  glyf = ttfLoadGlyphCached(font, pos);
402 
403  return glyf;
404 }
405 /* Load a glyph by character code in the current encoding scheme */
407 {
408  USHORT index;
409 
410  index = ttfLookUpCMAP(font->encoding->map,cc);
411  return ttfLoadGlyphIndex(font,index);
412 }
413 
415 {
416  double mantissa, fraction;
417 
418  mantissa = (double) (fixed >> 14);
419 
420  fraction = (double) (double)(fixed & 0x3fff) / 16384.0;
421 
422  return mantissa+fraction;
423 }
#define next(a)
Definition: aptex-macros.h:924
static point_t cur
Definition: backend_eps.c:108
#define free(a)
Definition: decNumber.cpp:310
#define fread
Definition: xxstdio.h:25
long int flag
Definition: f2c.h:53
#define c(n)
Definition: gpos-common.c:150
#define SEEK_SET
Definition: jmemansi.c:26
#define FT_MAKE_TAG(_x1, _x2, _x3, _x4)
Definition: fttypes.h:488
#define NULL
Definition: ftobjs.h:61
small capitals from c petite p scientific i
Definition: afcover.h:80
FT_UInt idx
Definition: cffcmap.c:135
kerning y
Definition: ttdriver.c:212
#define WE_HAVE_A_SCALE
Definition: ttgload.c:73
#define USE_MY_METRICS
Definition: ttgload.c:79
#define ARGS_ARE_XY_VALUES
Definition: ttgload.c:71
#define ROUND_XY_TO_GRID
Definition: ttgload.c:72
#define buf
signed short SHORT
Definition: sfnt.h:37
unsigned char BYTE
Definition: sfnt.h:34
short FWord
Definition: sfnt.h:41
unsigned short USHORT
Definition: sfnt.h:36
#define WE_HAVE_INSTRUCTIONS
Definition: tt_glyf.c:196
#define WE_HAVE_AN_X_AND_Y_SCALE
Definition: tt_glyf.c:194
#define MORE_COMPONENT
Definition: tt_glyf.c:193
#define WE_HAVE_A_TWO_BY_TWO
Definition: tt_glyf.c:195
#define ARG_1_AND_2_ARE_WORDS
Definition: tt_glyf.c:188
KPSEDLL void xfseek(FILE *fp, long offset, int wherefrom, const_string filename)
Definition: xfseek.c:22
#define fprintf
Definition: mendex.h:64
#define SHORT
Definition: ttf.h:12
#define USHORT
Definition: ttf.h:11
#define NO_OVERLAP
Definition: tables.h:287
#define FLAGS_ON_CURVE
Definition: tables.h:274
#define FLAGS_REPEAT
Definition: tables.h:277
#define FLAGS_Y_SAME
Definition: tables.h:279
#define FLAGS_Y_SHORT_VECTOR
Definition: tables.h:276
#define FLAGS_X_SHORT_VECTOR
Definition: tables.h:275
#define FLAGS_X_SAME
Definition: tables.h:278
SHORT ttfGetSHORT(FILE *fp)
Definition: ttfread.c:57
FWord ttfGetFWord(FILE *fp)
Definition: ttfread.c:98
USHORT ttfGetUSHORT(FILE *fp)
Definition: ttfread.c:48
F2Dot14 ttfGetF2Dot14(FILE *fp)
Definition: ttfread.c:108
SHORT F2Dot14
Definition: ttf.h:31
void ttfReadUSHORT(USHORT *array, size_t nelem, FILE *fp)
Definition: ttfread.c:114
static void ttfFreeCompositeGlyph(GLYFPtr glyf)
Definition: glyf.c:367
static void ttfPrintSimpleGlyph(FILE *fp, GLYFPtr glyf)
Definition: glyf.c:159
static void ttfPrintCompositeGlyph(FILE *fp, GLYFPtr glyf)
Definition: glyf.c:280
void ttfInitGLYF(TTFontPtr font)
Definition: glyf.c:29
GLYFPtr ttfLoadGlyphIndex(TTFont *font, USHORT idx)
Definition: glyf.c:394
static void ttfLoadCompositeGlyph(FILE *fp, GLYFPtr glyf, ULONG offset)
Definition: glyf.c:225
void ttfPrintGLYF(FILE *fp, GLYFPtr glyf)
Definition: glyf.c:58
void ttfFreeGLYF(GLYFPtr glyf)
Definition: glyf.c:72
GLYFPtr ttfLoadGlyphCode(TTFont *font, USHORT cc)
Definition: glyf.c:406
void ttfLoadGLYF(FILE *fp, GLYFPtr glyf, ULONG offset)
Definition: glyf.c:41
double fix2dbl(F2Dot14 fixed)
Definition: glyf.c:414
static void ttfLoadSimpleGlyph(FILE *fp, GLYFPtr glyf, ULONG offset)
Definition: glyf.c:77
#define sprintf
Definition: snprintf.c:44
USHORT ttfLookUpCMAP(MapPtr map, USHORT cc)
Definition: cmap.c:185
void ttfPrintInstructions(FILE *fp, BYTE *ins)
Definition: disasm.c:12
ULONG ttfLookUpGlyfLOCA(LOCAPtr loca, USHORT idx)
Definition: loca.c:87
GLYFPtr ttfLoadGlyphCached(TTFontPtr font, ULONG offset)
Definition: gcache.c:127
TableDirPtr ttfLookUpTableDir(ULONG tag, TTFontPtr font)
Definition: tabledir.c:61
const int * pos
Definition: combiners.h:905
float x
Definition: cordic.py:15
unsigned long ULONG
Definition: pdfgen.h:158
#define fp
#define index(s, c)
Definition: plain2.h:351
static int offset
Definition: ppmtogif.c:642
#define flags
le_int32 fixed
Definition: sfnt.h:144
#define flag
Definition: round_prec.c:45
Definition: tables.h:253
FWord yMax
Definition: tables.h:258
BYTE * flags
Definition: tables.h:263
SHORT * yCoordinates
Definition: tables.h:267
SHORT numberOfContours
Definition: tables.h:254
USHORT * endPtsOfContours
Definition: tables.h:260
USHORT instructionLength
Definition: tables.h:261
FWord xMax
Definition: tables.h:257
Component * comp
Definition: tables.h:268
SHORT * xCoordinates
Definition: tables.h:266
FWord yMin
Definition: tables.h:256
FWord xMin
Definition: tables.h:255
BYTE * instructions
Definition: tables.h:262
Definition: ttf.h:110
ULONG offset
Definition: tables.h:30
Definition: usprintf.c:39
Definition: pbmfont.h:11
Definition: mendex.h:20
Definition: xmlparse.c:179
#define FILE
Definition: t1stdio.h:34
int j
Definition: t4ht.c:1589
BYTE ttfGetBYTE(FILE *)
Definition: ttfread.c:22
#define XCALLOC1(t)
Definition: ttfutil.h:60
void ttfError(const char *msg)
Definition: ttfutil.c:32