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