zenilib  0.5.3.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
t1afm.c
Go to the documentation of this file.
1 /***************************************************************************/
2 /* */
3 /* t1afm.c */
4 /* */
5 /* AFM support for Type 1 fonts (body). */
6 /* */
7 /* Copyright 1996-2011 by */
8 /* David Turner, Robert Wilhelm, and Werner Lemberg. */
9 /* */
10 /* This file is part of the FreeType project, and may only be used, */
11 /* modified, and distributed under the terms of the FreeType project */
12 /* license, LICENSE.TXT. By continuing to use, modify, or distribute */
13 /* this file you indicate that you have read the license and */
14 /* understand and accept it fully. */
15 /* */
16 /***************************************************************************/
17 
18 
19 #include <ft2build.h>
20 #include "t1afm.h"
21 #include "t1errors.h"
22 #include FT_INTERNAL_STREAM_H
23 #include FT_INTERNAL_POSTSCRIPT_AUX_H
24 
25 
26  /*************************************************************************/
27  /* */
28  /* The macro FT_COMPONENT is used in trace mode. It is an implicit */
29  /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */
30  /* messages during execution. */
31  /* */
32 #undef FT_COMPONENT
33 #define FT_COMPONENT trace_t1afm
34 
35 
36  FT_LOCAL_DEF( void )
38  AFM_FontInfo fi )
39  {
40  FT_FREE( fi->KernPairs );
41  fi->NumKernPair = 0;
42 
43  FT_FREE( fi->TrackKerns );
44  fi->NumTrackKern = 0;
45 
46  FT_FREE( fi );
47  }
48 
49 
50  /* read a glyph name and return the equivalent glyph index */
51  static FT_Int
52  t1_get_index( const char* name,
53  FT_Offset len,
54  void* user_data )
55  {
56  T1_Font type1 = (T1_Font)user_data;
57  FT_Int n;
58 
59 
60  /* PS string/name length must be < 16-bit */
61  if ( len > 0xFFFFU )
62  return 0;
63 
64  for ( n = 0; n < type1->num_glyphs; n++ )
65  {
66  char* gname = (char*)type1->glyph_names[n];
67 
68 
69  if ( gname && gname[0] == name[0] &&
70  ft_strlen( gname ) == len &&
71  ft_strncmp( gname, name, len ) == 0 )
72  return n;
73  }
74 
75  return 0;
76  }
77 
78 
79 #undef KERN_INDEX
80 #define KERN_INDEX( g1, g2 ) ( ( (FT_ULong)(g1) << 16 ) | (g2) )
81 
82 
83  /* compare two kerning pairs */
84  FT_CALLBACK_DEF( int )
86  const void* b )
87  {
88  AFM_KernPair pair1 = (AFM_KernPair)a;
89  AFM_KernPair pair2 = (AFM_KernPair)b;
90 
91  FT_ULong index1 = KERN_INDEX( pair1->index1, pair1->index2 );
92  FT_ULong index2 = KERN_INDEX( pair2->index1, pair2->index2 );
93 
94 
95  if ( index1 > index2 )
96  return 1;
97  else if ( index1 < index2 )
98  return -1;
99  else
100  return 0;
101  }
102 
103 
104  /* parse a PFM file -- for now, only read the kerning pairs */
105  static FT_Error
108  AFM_FontInfo fi )
109  {
110  FT_Error error = T1_Err_Ok;
111  FT_Memory memory = stream->memory;
112  FT_Byte* start;
113  FT_Byte* limit;
114  FT_Byte* p;
115  AFM_KernPair kp;
116  FT_Int width_table_length;
117  FT_CharMap oldcharmap;
118  FT_CharMap charmap;
119  FT_Int n;
120 
121 
122  start = (FT_Byte*)stream->cursor;
123  limit = (FT_Byte*)stream->limit;
124  p = start;
125 
126  /* Figure out how long the width table is. */
127  /* This info is a little-endian short at offset 99. */
128  p = start + 99;
129  if ( p + 2 > limit )
130  {
131  error = T1_Err_Unknown_File_Format;
132  goto Exit;
133  }
134  width_table_length = FT_PEEK_USHORT_LE( p );
135 
136  p += 18 + width_table_length;
137  if ( p + 0x12 > limit || FT_PEEK_USHORT_LE( p ) < 0x12 )
138  /* extension table is probably optional */
139  goto Exit;
140 
141  /* Kerning offset is 14 bytes from start of extensions table. */
142  p += 14;
143  p = start + FT_PEEK_ULONG_LE( p );
144 
145  if ( p == start )
146  /* zero offset means no table */
147  goto Exit;
148 
149  if ( p + 2 > limit )
150  {
151  error = T1_Err_Unknown_File_Format;
152  goto Exit;
153  }
154 
155  fi->NumKernPair = FT_PEEK_USHORT_LE( p );
156  p += 2;
157  if ( p + 4 * fi->NumKernPair > limit )
158  {
159  error = T1_Err_Unknown_File_Format;
160  goto Exit;
161  }
162 
163  /* Actually, kerning pairs are simply optional! */
164  if ( fi->NumKernPair == 0 )
165  goto Exit;
166 
167  /* allocate the pairs */
168  if ( FT_QNEW_ARRAY( fi->KernPairs, fi->NumKernPair ) )
169  goto Exit;
170 
171  /* now, read each kern pair */
172  kp = fi->KernPairs;
173  limit = p + 4 * fi->NumKernPair;
174 
175  /* PFM kerning data are stored by encoding rather than glyph index, */
176  /* so find the PostScript charmap of this font and install it */
177  /* temporarily. If we find no PostScript charmap, then just use */
178  /* the default and hope it is the right one. */
179  oldcharmap = t1_face->charmap;
180  charmap = NULL;
181 
182  for ( n = 0; n < t1_face->num_charmaps; n++ )
183  {
184  charmap = t1_face->charmaps[n];
185  /* check against PostScript pseudo platform */
186  if ( charmap->platform_id == 7 )
187  {
188  error = FT_Set_Charmap( t1_face, charmap );
189  if ( error )
190  goto Exit;
191  break;
192  }
193  }
194 
195  /* Kerning info is stored as: */
196  /* */
197  /* encoding of first glyph (1 byte) */
198  /* encoding of second glyph (1 byte) */
199  /* offset (little-endian short) */
200  for ( ; p < limit ; p += 4 )
201  {
202  kp->index1 = FT_Get_Char_Index( t1_face, p[0] );
203  kp->index2 = FT_Get_Char_Index( t1_face, p[1] );
204 
205  kp->x = (FT_Int)FT_PEEK_SHORT_LE(p + 2);
206  kp->y = 0;
207 
208  kp++;
209  }
210 
211  if ( oldcharmap != NULL )
212  error = FT_Set_Charmap( t1_face, oldcharmap );
213  if ( error )
214  goto Exit;
215 
216  /* now, sort the kern pairs according to their glyph indices */
219 
220  Exit:
221  if ( error )
222  {
223  FT_FREE( fi->KernPairs );
224  fi->NumKernPair = 0;
225  }
226 
227  return error;
228  }
229 
230 
231  /* parse a metrics file -- either AFM or PFM depending on what */
232  /* it turns out to be */
235  FT_Stream stream )
236  {
237  PSAux_Service psaux;
238  FT_Memory memory = stream->memory;
239  AFM_ParserRec parser;
240  AFM_FontInfo fi = NULL;
241  FT_Error error = T1_Err_Unknown_File_Format;
242  T1_Font t1_font = &( (T1_Face)t1_face )->type1;
243 
244 
245  if ( FT_NEW( fi ) ||
246  FT_FRAME_ENTER( stream->size ) )
247  goto Exit;
248 
249  fi->FontBBox = t1_font->font_bbox;
250  fi->Ascender = t1_font->font_bbox.yMax;
251  fi->Descender = t1_font->font_bbox.yMin;
252 
253  psaux = (PSAux_Service)( (T1_Face)t1_face )->psaux;
254  if ( psaux->afm_parser_funcs )
255  {
256  error = psaux->afm_parser_funcs->init( &parser,
257  stream->memory,
258  stream->cursor,
259  stream->limit );
260 
261  if ( !error )
262  {
263  parser.FontInfo = fi;
264  parser.get_index = t1_get_index;
265  parser.user_data = t1_font;
266 
267  error = psaux->afm_parser_funcs->parse( &parser );
268  psaux->afm_parser_funcs->done( &parser );
269  }
270  }
271 
272  if ( error == T1_Err_Unknown_File_Format )
273  {
274  FT_Byte* start = stream->cursor;
275 
276 
277  /* MS Windows allows versions up to 0x3FF without complaining */
278  if ( stream->size > 6 &&
279  start[1] < 4 &&
280  FT_PEEK_ULONG_LE( start + 2 ) == stream->size )
281  error = T1_Read_PFM( t1_face, stream, fi );
282  }
283 
284  if ( !error )
285  {
286  t1_font->font_bbox = fi->FontBBox;
287 
288  t1_face->bbox.xMin = fi->FontBBox.xMin >> 16;
289  t1_face->bbox.yMin = fi->FontBBox.yMin >> 16;
290  /* no `U' suffix here to 0xFFFF! */
291  t1_face->bbox.xMax = ( fi->FontBBox.xMax + 0xFFFF ) >> 16;
292  t1_face->bbox.yMax = ( fi->FontBBox.yMax + 0xFFFF ) >> 16;
293 
294  /* no `U' suffix here to 0x8000! */
295  t1_face->ascender = (FT_Short)( ( fi->Ascender + 0x8000 ) >> 16 );
296  t1_face->descender = (FT_Short)( ( fi->Descender + 0x8000 ) >> 16 );
297 
298  if ( fi->NumKernPair )
299  {
300  t1_face->face_flags |= FT_FACE_FLAG_KERNING;
301  ( (T1_Face)t1_face )->afm_data = fi;
302  fi = NULL;
303  }
304  }
305 
306  FT_FRAME_EXIT();
307 
308  Exit:
309  if ( fi != NULL )
310  T1_Done_Metrics( memory, fi );
311 
312  return error;
313  }
314 
315 
316  /* find the kerning for a given glyph pair */
317  FT_LOCAL_DEF( void )
319  FT_UInt glyph1,
320  FT_UInt glyph2,
321  FT_Vector* kerning )
322  {
323  AFM_KernPair min, mid, max;
324  FT_ULong idx = KERN_INDEX( glyph1, glyph2 );
325 
326 
327  /* simple binary search */
328  min = fi->KernPairs;
329  max = min + fi->NumKernPair - 1;
330 
331  while ( min <= max )
332  {
333  FT_ULong midi;
334 
335 
336  mid = min + ( max - min ) / 2;
337  midi = KERN_INDEX( mid->index1, mid->index2 );
338 
339  if ( midi == idx )
340  {
341  kerning->x = mid->x;
342  kerning->y = mid->y;
343 
344  return;
345  }
346 
347  if ( midi < idx )
348  min = mid + 1;
349  else
350  max = mid - 1;
351  }
352 
353  kerning->x = 0;
354  kerning->y = 0;
355  }
356 
357 
360  FT_Fixed ptsize,
361  FT_Int degree,
362  FT_Fixed* kerning )
363  {
364  AFM_FontInfo fi = (AFM_FontInfo)( (T1_Face)face )->afm_data;
365  FT_Int i;
366 
367 
368  if ( !fi )
369  return T1_Err_Invalid_Argument;
370 
371  for ( i = 0; i < fi->NumTrackKern; i++ )
372  {
373  AFM_TrackKern tk = fi->TrackKerns + i;
374 
375 
376  if ( tk->degree != degree )
377  continue;
378 
379  if ( ptsize < tk->min_ptsize )
380  *kerning = tk->min_kern;
381  else if ( ptsize > tk->max_ptsize )
382  *kerning = tk->max_kern;
383  else
384  {
385  *kerning = FT_MulDiv( ptsize - tk->min_ptsize,
386  tk->max_kern - tk->min_kern,
387  tk->max_ptsize - tk->min_ptsize ) +
388  tk->min_kern;
389  }
390  }
391 
392  return T1_Err_Ok;
393  }
394 
395 
396 /* END */
int FT_Error
Definition: fttypes.h:296
#define ft_strncmp
Definition: ftstdlib.h:88
struct AFM_KernPairRec_ * AFM_KernPair
compare_kern_pairs(const void *a, const void *b)
Definition: t1afm.c:85
unsigned long FT_ULong
Definition: fttypes.h:249
const AFM_Parser_FuncsRec * afm_parser_funcs
Definition: psaux.h:810
struct T1_FaceRec_ * T1_Face
Definition: t1types.h:194
FT_Fixed max_ptsize
Definition: t1types.h:153
#define KERN_INDEX(g1, g2)
Definition: t1afm.c:80
FT_CharMap charmap
Definition: freetype.h:951
FT_Memory memory
Definition: psaux.h:751
#define NULL
Definition: ftobjs.h:61
signed int FT_Int
Definition: fttypes.h:216
GLuint start
Definition: glew.h:1239
unsigned char * cursor
Definition: ftsystem.h:333
GLuint GLuint stream
Definition: glew.h:6573
GLclampd n
Definition: glew.h:7287
FT_Int num_glyphs
Definition: t1types.h:111
FT_UShort platform_id
Definition: freetype.h:740
FT_Error(* init)(AFM_Parser parser, FT_Memory memory, FT_Byte *base, FT_Byte *limit)
Definition: psaux.h:713
#define FT_QNEW_ARRAY(ptr, count)
Definition: ftmemory.h:299
GLboolean GLboolean GLboolean GLboolean a
Definition: glew.h:8736
EGLImageKHR EGLint * name
Definition: eglext.h:284
FT_Int NumTrackKern
Definition: t1types.h:174
void * user_data
Definition: psaux.h:761
GLenum GLsizei len
Definition: glew.h:7035
FT_Fixed min_kern
Definition: t1types.h:152
T1_Done_Metrics(FT_Memory memory, AFM_FontInfo fi)
Definition: t1afm.c:37
if(!yyg->yy_init)
FT_Int index2
Definition: t1types.h:161
#define ft_qsort
Definition: ftstdlib.h:121
unsigned char FT_Byte
Definition: fttypes.h:150
struct T1_FontRec_ * T1_Font
static FT_Error T1_Read_PFM(FT_Face t1_face, FT_Stream stream, AFM_FontInfo fi)
Definition: t1afm.c:106
FT_Memory memory
Definition: ftsystem.h:332
FT_Int num_charmaps
Definition: freetype.h:928
#define FT_FREE(ptr)
Definition: ftmemory.h:286
FT_Fixed Descender
Definition: t1types.h:172
FT_Pos yMax
Definition: ftimage.h:119
#define FT_LOCAL_DEF(x)
Definition: ftconfig.h:467
FT_Pos xMin
Definition: ftimage.h:118
FT_Get_Char_Index(FT_Face face, FT_ULong charcode)
Definition: ftobjs.c:3290
FT_Fixed min_ptsize
Definition: t1types.h:151
FT_UInt idx
Definition: cffcmap.c:125
FT_MulDiv(FT_Long a, FT_Long b, FT_Long c)
Definition: ftcalc.c:358
FT_Error error
Definition: cffdrivr.c:407
static FT_Int t1_get_index(const char *name, FT_Offset len, void *user_data)
Definition: t1afm.c:52
GLenum face
Definition: gl2ext.h:1490
GLfloat GLfloat p
Definition: glew.h:14938
struct PSAux_ServiceRec_ * PSAux_Service
GLint limit
Definition: glew.h:11829
T1_Read_Metrics(FT_Face t1_face, FT_Stream stream)
Definition: t1afm.c:234
struct AFM_FontInfoRec_ * AFM_FontInfo
#define FT_CALLBACK_DEF(x)
Definition: ftconfig.h:554
AFM_KernPair KernPairs
Definition: t1types.h:175
FT_Pos xMax
Definition: ftimage.h:119
FT_CharMap * charmaps
Definition: freetype.h:929
FT_Set_Charmap(FT_Face face, FT_CharMap charmap)
Definition: ftobjs.c:3105
#define FT_PEEK_ULONG_LE(p)
Definition: ftstream.h:210
signed short FT_Short
Definition: fttypes.h:194
#define FT_PEEK_USHORT_LE(p)
Definition: ftstream.h:202
typedefFT_BEGIN_HEADER struct FT_MemoryRec_ * FT_Memory
Definition: ftsystem.h:66
FT_Fixed max_kern
Definition: t1types.h:154
#define FT_FRAME_EXIT()
Definition: ftstream.h:521
sizeof(FT_AutofitterRec)
#define FT_PEEK_SHORT_LE(p)
Definition: ftstream.h:199
FT_BBox font_bbox
Definition: t1types.h:120
FT_Error(* parse)(AFM_Parser parser)
Definition: psaux.h:722
#define const
Definition: zconf.h:91
signed long FT_Fixed
Definition: fttypes.h:284
unsigned int FT_UInt
Definition: fttypes.h:227
AFM_TrackKern TrackKerns
Definition: t1types.h:173
void(* done)(AFM_Parser parser)
Definition: psaux.h:719
unsigned char * limit
Definition: ftsystem.h:334
FT_Int index1
Definition: t1types.h:160
#define FT_FACE_FLAG_KERNING
Definition: freetype.h:1075
FT_Fixed Ascender
Definition: t1types.h:171
GLdouble GLdouble GLdouble b
Definition: glew.h:8383
#define FT_FRAME_ENTER(size)
Definition: ftstream.h:517
#define min(x, y)
Definition: os.h:75
FT_BBox FontBBox
Definition: t1types.h:170
#define FT_NEW(ptr)
Definition: ftmemory.h:288
int i
Definition: pngrutil.c:1377
AFM_FontInfo FontInfo
Definition: psaux.h:754
FT_Int(* get_index)(const char *name, FT_Offset len, void *user_data)
Definition: psaux.h:757
#define max(x, y)
Definition: os.h:79
T1_Get_Track_Kerning(FT_Face face, FT_Fixed ptsize, FT_Int degree, FT_Fixed *kerning)
Definition: t1afm.c:359
T1_Get_Kerning(AFM_FontInfo fi, FT_UInt glyph1, FT_UInt glyph2, FT_Vector *kerning)
Definition: t1afm.c:318
FT_Pos yMin
Definition: ftimage.h:118
#define ft_strlen
Definition: ftstdlib.h:87
FT_Int NumKernPair
Definition: t1types.h:176
size_t FT_Offset
Definition: fttypes.h:320
FT_String ** glyph_names
Definition: t1types.h:112