Visualization Library 2.0.0-b5

A lightweight C++ OpenGL middleware for 2D/3D graphics

VL     Star     Watch     Fork     Issue

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