zenilib  0.5.3.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
ttmtx.c
Go to the documentation of this file.
1 /***************************************************************************/
2 /* */
3 /* ttmtx.c */
4 /* */
5 /* Load the metrics tables common to TTF and OTF fonts (body). */
6 /* */
7 /* Copyright 2006-2009, 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 FT_INTERNAL_DEBUG_H
21 #include FT_INTERNAL_STREAM_H
22 #include FT_TRUETYPE_TAGS_H
23 #include "ttmtx.h"
24 
25 #include "sferrors.h"
26 
27 
28  /*************************************************************************/
29  /* */
30  /* The macro FT_COMPONENT is used in trace mode. It is an implicit */
31  /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */
32  /* messages during execution. */
33  /* */
34 #undef FT_COMPONENT
35 #define FT_COMPONENT trace_ttmtx
36 
37 
38  /*
39  * Unfortunately, we can't enable our memory optimizations if
40  * FT_CONFIG_OPTION_OLD_INTERNALS is defined. This is because at least
41  * one rogue client (libXfont in the X.Org XServer) is directly accessing
42  * the metrics.
43  */
44 
45  /*************************************************************************/
46  /* */
47  /* <Function> */
48  /* tt_face_load_hmtx */
49  /* */
50  /* <Description> */
51  /* Load the `hmtx' or `vmtx' table into a face object. */
52  /* */
53  /* <Input> */
54  /* face :: A handle to the target face object. */
55  /* */
56  /* stream :: The input stream. */
57  /* */
58  /* vertical :: A boolean flag. If set, load `vmtx'. */
59  /* */
60  /* <Return> */
61  /* FreeType error code. 0 means success. */
62  /* */
63 #ifndef FT_CONFIG_OPTION_OLD_INTERNALS
64 
68  FT_Bool vertical )
69  {
71  FT_ULong tag, table_size;
72  FT_ULong* ptable_offset;
73  FT_ULong* ptable_size;
74 
75 
76  if ( vertical )
77  {
78  tag = TTAG_vmtx;
79  ptable_offset = &face->vert_metrics_offset;
80  ptable_size = &face->vert_metrics_size;
81  }
82  else
83  {
84  tag = TTAG_hmtx;
85  ptable_offset = &face->horz_metrics_offset;
86  ptable_size = &face->horz_metrics_size;
87  }
88 
89  error = face->goto_table( face, tag, stream, &table_size );
90  if ( error )
91  goto Fail;
92 
93  *ptable_size = table_size;
94  *ptable_offset = FT_STREAM_POS();
95 
96  Fail:
97  return error;
98  }
99 
100 #else /* !FT_CONFIG_OPTION_OLD_INTERNALS */
101 
105  FT_Bool vertical )
106  {
107  FT_Error error;
108  FT_Memory memory = stream->memory;
109 
110  FT_ULong table_len;
111  FT_Long num_shorts, num_longs, num_shorts_checked;
112 
113  TT_LongMetrics* longs;
114  TT_ShortMetrics** shorts;
115  FT_Byte* p;
116 
117 
118  if ( vertical )
119  {
120  void* lm = &face->vertical.long_metrics;
121  void** sm = &face->vertical.short_metrics;
122 
123 
124  error = face->goto_table( face, TTAG_vmtx, stream, &table_len );
125  if ( error )
126  goto Fail;
127 
128  num_longs = face->vertical.number_Of_VMetrics;
129  if ( (FT_ULong)num_longs > table_len / 4 )
130  num_longs = (FT_Long)( table_len / 4 );
131 
132  face->vertical.number_Of_VMetrics = 0;
133 
134  longs = (TT_LongMetrics*)lm;
135  shorts = (TT_ShortMetrics**)sm;
136  }
137  else
138  {
139  void* lm = &face->horizontal.long_metrics;
140  void** sm = &face->horizontal.short_metrics;
141 
142 
143  error = face->goto_table( face, TTAG_hmtx, stream, &table_len );
144  if ( error )
145  goto Fail;
146 
147  num_longs = face->horizontal.number_Of_HMetrics;
148  if ( (FT_ULong)num_longs > table_len / 4 )
149  num_longs = (FT_Long)( table_len / 4 );
150 
151  face->horizontal.number_Of_HMetrics = 0;
152 
153  longs = (TT_LongMetrics*)lm;
154  shorts = (TT_ShortMetrics**)sm;
155  }
156 
157  /* never trust derived values */
158 
159  num_shorts = face->max_profile.numGlyphs - num_longs;
160  num_shorts_checked = ( table_len - num_longs * 4L ) / 2;
161 
162  if ( num_shorts < 0 )
163  {
164  FT_TRACE0(( "tt_face_load_hmtx:"
165  " %cmtx has more metrics than glyphs.\n",
166  vertical ? 'v' : 'h' ));
167 
168  /* Adobe simply ignores this problem. So we shall do the same. */
169 #if 0
170  error = vertical ? SFNT_Err_Invalid_Vert_Metrics
171  : SFNT_Err_Invalid_Horiz_Metrics;
172  goto Exit;
173 #else
174  num_shorts = 0;
175 #endif
176  }
177 
178  if ( FT_QNEW_ARRAY( *longs, num_longs ) ||
179  FT_QNEW_ARRAY( *shorts, num_shorts ) )
180  goto Fail;
181 
182  if ( FT_FRAME_ENTER( table_len ) )
183  goto Fail;
184 
185  p = stream->cursor;
186 
187  {
188  TT_LongMetrics cur = *longs;
189  TT_LongMetrics limit = cur + num_longs;
190 
191 
192  for ( ; cur < limit; cur++ )
193  {
194  cur->advance = FT_NEXT_USHORT( p );
195  cur->bearing = FT_NEXT_SHORT( p );
196  }
197  }
198 
199  /* do we have an inconsistent number of metric values? */
200  {
201  TT_ShortMetrics* cur = *shorts;
202  TT_ShortMetrics* limit = cur +
203  FT_MIN( num_shorts, num_shorts_checked );
204 
205 
206  for ( ; cur < limit; cur++ )
207  *cur = FT_NEXT_SHORT( p );
208 
209  /* We fill up the missing left side bearings with the */
210  /* last valid value. Since this will occur for buggy CJK */
211  /* fonts usually only, nothing serious will happen. */
212  if ( num_shorts > num_shorts_checked && num_shorts_checked > 0 )
213  {
214  FT_Short val = (*shorts)[num_shorts_checked - 1];
215 
216 
217  limit = *shorts + num_shorts;
218  for ( ; cur < limit; cur++ )
219  *cur = val;
220  }
221  }
222 
223  FT_FRAME_EXIT();
224 
225  if ( vertical )
226  face->vertical.number_Of_VMetrics = (FT_UShort)num_longs;
227  else
228  face->horizontal.number_Of_HMetrics = (FT_UShort)num_longs;
229 
230  Fail:
231  return error;
232  }
233 
234 #endif /* !FT_CONFIG_OPTION_OLD_INTERNALS */
235 
236 
237  /*************************************************************************/
238  /* */
239  /* <Function> */
240  /* tt_face_load_hhea */
241  /* */
242  /* <Description> */
243  /* Load the `hhea' or 'vhea' table into a face object. */
244  /* */
245  /* <Input> */
246  /* face :: A handle to the target face object. */
247  /* */
248  /* stream :: The input stream. */
249  /* */
250  /* vertical :: A boolean flag. If set, load `vhea'. */
251  /* */
252  /* <Return> */
253  /* FreeType error code. 0 means success. */
254  /* */
257  FT_Stream stream,
258  FT_Bool vertical )
259  {
260  FT_Error error;
262 
263  const FT_Frame_Field metrics_header_fields[] =
264  {
265 #undef FT_STRUCTURE
266 #define FT_STRUCTURE TT_HoriHeader
267 
268  FT_FRAME_START( 36 ),
269  FT_FRAME_ULONG ( Version ),
270  FT_FRAME_SHORT ( Ascender ),
271  FT_FRAME_SHORT ( Descender ),
272  FT_FRAME_SHORT ( Line_Gap ),
273  FT_FRAME_USHORT( advance_Width_Max ),
274  FT_FRAME_SHORT ( min_Left_Side_Bearing ),
275  FT_FRAME_SHORT ( min_Right_Side_Bearing ),
276  FT_FRAME_SHORT ( xMax_Extent ),
277  FT_FRAME_SHORT ( caret_Slope_Rise ),
278  FT_FRAME_SHORT ( caret_Slope_Run ),
279  FT_FRAME_SHORT ( caret_Offset ),
280  FT_FRAME_SHORT ( Reserved[0] ),
281  FT_FRAME_SHORT ( Reserved[1] ),
282  FT_FRAME_SHORT ( Reserved[2] ),
283  FT_FRAME_SHORT ( Reserved[3] ),
284  FT_FRAME_SHORT ( metric_Data_Format ),
285  FT_FRAME_USHORT( number_Of_HMetrics ),
287  };
288 
289 
290  if ( vertical )
291  {
292  void *v = &face->vertical;
293 
294 
295  error = face->goto_table( face, TTAG_vhea, stream, 0 );
296  if ( error )
297  goto Fail;
298 
299  header = (TT_HoriHeader*)v;
300  }
301  else
302  {
303  error = face->goto_table( face, TTAG_hhea, stream, 0 );
304  if ( error )
305  goto Fail;
306 
307  header = &face->horizontal;
308  }
309 
310  if ( FT_STREAM_READ_FIELDS( metrics_header_fields, header ) )
311  goto Fail;
312 
313  FT_TRACE3(( "Ascender: %5d\n", header->Ascender ));
314  FT_TRACE3(( "Descender: %5d\n", header->Descender ));
315  FT_TRACE3(( "number_Of_Metrics: %5u\n", header->number_Of_HMetrics ));
316 
317  header->long_metrics = NULL;
318  header->short_metrics = NULL;
319 
320  Fail:
321  return error;
322  }
323 
324 
325  /*************************************************************************/
326  /* */
327  /* <Function> */
328  /* tt_face_get_metrics */
329  /* */
330  /* <Description> */
331  /* Returns the horizontal or vertical metrics in font units for a */
332  /* given glyph. The metrics are the left side bearing (resp. top */
333  /* side bearing) and advance width (resp. advance height). */
334  /* */
335  /* <Input> */
336  /* header :: A pointer to either the horizontal or vertical metrics */
337  /* structure. */
338  /* */
339  /* idx :: The glyph index. */
340  /* */
341  /* <Output> */
342  /* bearing :: The bearing, either left side or top side. */
343  /* */
344  /* advance :: The advance width resp. advance height. */
345  /* */
346 #ifndef FT_CONFIG_OPTION_OLD_INTERNALS
347 
350  FT_Bool vertical,
351  FT_UInt gindex,
352  FT_Short *abearing,
353  FT_UShort *aadvance )
354  {
355  FT_Error error;
356  FT_Stream stream = face->root.stream;
358  FT_ULong table_pos, table_size, table_end;
359  FT_UShort k;
360 
361 
362  if ( vertical )
363  {
364  void* v = &face->vertical;
365 
366 
367  header = (TT_HoriHeader*)v;
368  table_pos = face->vert_metrics_offset;
369  table_size = face->vert_metrics_size;
370  }
371  else
372  {
373  header = &face->horizontal;
374  table_pos = face->horz_metrics_offset;
375  table_size = face->horz_metrics_size;
376  }
377 
378  table_end = table_pos + table_size;
379 
380  k = header->number_Of_HMetrics;
381 
382  if ( k > 0 )
383  {
384  if ( gindex < (FT_UInt)k )
385  {
386  table_pos += 4 * gindex;
387  if ( table_pos + 4 > table_end )
388  goto NoData;
389 
390  if ( FT_STREAM_SEEK( table_pos ) ||
391  FT_READ_USHORT( *aadvance ) ||
392  FT_READ_SHORT( *abearing ) )
393  goto NoData;
394  }
395  else
396  {
397  table_pos += 4 * ( k - 1 );
398  if ( table_pos + 4 > table_end )
399  goto NoData;
400 
401  if ( FT_STREAM_SEEK( table_pos ) ||
402  FT_READ_USHORT( *aadvance ) )
403  goto NoData;
404 
405  table_pos += 4 + 2 * ( gindex - k );
406  if ( table_pos + 2 > table_end )
407  *abearing = 0;
408  else
409  {
410  if ( !FT_STREAM_SEEK( table_pos ) )
411  (void)FT_READ_SHORT( *abearing );
412  }
413  }
414  }
415  else
416  {
417  NoData:
418  *abearing = 0;
419  *aadvance = 0;
420  }
421 
422  return SFNT_Err_Ok;
423  }
424 
425 #else /* !FT_CONFIG_OPTION_OLD_INTERNALS */
426 
429  FT_Bool vertical,
430  FT_UInt gindex,
431  FT_Short* abearing,
432  FT_UShort* aadvance )
433  {
434  void* v = &face->vertical;
435  void* h = &face->horizontal;
436  TT_HoriHeader* header = vertical ? (TT_HoriHeader*)v
437  : (TT_HoriHeader*)h;
438  TT_LongMetrics longs_m;
439  FT_UShort k = header->number_Of_HMetrics;
440 
441 
442  if ( k == 0 ||
443  !header->long_metrics ||
444  gindex >= (FT_UInt)face->max_profile.numGlyphs )
445  {
446  *abearing = *aadvance = 0;
447  return SFNT_Err_Ok;
448  }
449 
450  if ( gindex < (FT_UInt)k )
451  {
452  longs_m = (TT_LongMetrics)header->long_metrics + gindex;
453  *abearing = longs_m->bearing;
454  *aadvance = longs_m->advance;
455  }
456  else
457  {
458  *abearing = ((TT_ShortMetrics*)header->short_metrics)[gindex - k];
459  *aadvance = ((TT_LongMetrics)header->long_metrics)[k - 1].advance;
460  }
461 
462  return SFNT_Err_Ok;
463  }
464 
465 #endif /* !FT_CONFIG_OPTION_OLD_INTERNALS */
466 
467 
468 /* END */
int FT_Error
Definition: fttypes.h:296
GLuint const GLfloat * val
Definition: glew.h:2715
signed long FT_Long
Definition: fttypes.h:238
cannot open resource broken file module version is too low unimplemented feature broken offset within table missing module invalid character code cannot render this glyph format invalid composite glyph invalid pixel size invalid library handle invalid face handle invalid glyph slot handle invalid cache manager handle too many modules out of memory cannot open stream invalid stream skip invalid stream operation nested frame access raster uninitialized raster overflow too many registered caches too few arguments code overflow division by zero found debug opcode nested DEFS execution context too long too many instruction definitions horizontal header(hhea) table missing" ) FT_ERRORDEF_( Locations_Missing
unsigned long FT_ULong
Definition: fttypes.h:249
GLfloat GLfloat GLfloat GLfloat h
Definition: glew.h:7294
tt_face_load_hhea(TT_Face face, FT_Stream stream, FT_Bool vertical)
Definition: ttmtx.c:256
#define NULL
Definition: ftobjs.h:61
int32_t k
Definition: e_log.c:102
GLuint GLuint stream
Definition: glew.h:6573
FT_UShort number_Of_HMetrics
Definition: tttables.h:199
#define TTAG_vhea
Definition: tttags.h:98
#define FT_MIN(a, b)
Definition: ftobjs.h:70
tt_face_get_metrics(TT_Face face, FT_Bool vertical, FT_UInt gindex, FT_Short *abearing, FT_UShort *aadvance)
Definition: ttmtx.c:349
#define FT_QNEW_ARRAY(ptr, count)
Definition: ftmemory.h:299
FT_UShort advance
Definition: tttypes.h:156
#define FT_READ_USHORT(var)
Definition: ftstream.h:316
if(!yyg->yy_init)
#define TTAG_hmtx
Definition: tttags.h:65
void * short_metrics
Definition: tttables.h:206
FT_BEGIN_HEADER typedef unsigned char FT_Bool
Definition: fttypes.h:104
FT_Short TT_ShortMetrics
Definition: tttypes.h:171
unsigned char FT_Byte
Definition: fttypes.h:150
#define TTAG_hhea
Definition: tttags.h:64
FT_Short Descender
Definition: tttables.h:184
#define FT_STREAM_READ_FIELDS(fields, object)
Definition: ftstream.h:513
FT_Short bearing
Definition: tttypes.h:157
FT_Short Ascender
Definition: tttables.h:183
#define FT_FRAME_END
Definition: ftstream.h:118
#define FT_FRAME_USHORT(f)
Definition: ftstream.h:123
#define FT_LOCAL_DEF(x)
Definition: ftconfig.h:467
const GLdouble * v
Definition: glew.h:1377
FT_Error error
Definition: cffdrivr.c:407
#define FT_TRACE0(varformat)
Definition: ftdebug.h:157
GLenum face
Definition: gl2ext.h:1490
GLfloat GLfloat p
Definition: glew.h:14938
GLint limit
Definition: glew.h:11829
GLenum const void GLbitfield GLuint GLsizei numGlyphs
Definition: glew.h:12411
signed short FT_Short
Definition: fttypes.h:194
typedefFT_BEGIN_HEADER struct FT_MemoryRec_ * FT_Memory
Definition: ftsystem.h:66
#define FT_FRAME_EXIT()
Definition: ftstream.h:521
#define FT_STREAM_SEEK(position)
Definition: ftstream.h:496
#define FT_NEXT_USHORT(buffer)
Definition: ftstream.h:233
#define TTAG_vmtx
Definition: tttags.h:99
#define FT_TRACE3(varformat)
Definition: ftdebug.h:160
#define FT_STREAM_POS()
Definition: ftstream.h:493
#define FT_FRAME_ULONG(f)
Definition: ftstream.h:121
unsigned int FT_UInt
Definition: fttypes.h:227
tt_face_load_hmtx(TT_Face face, FT_Stream stream, FT_Bool vertical)
Definition: ttmtx.c:66
#define FT_FRAME_ENTER(size)
Definition: ftstream.h:517
#define FT_NEXT_SHORT(buffer)
Definition: ftstream.h:230
#define FT_READ_SHORT(var)
Definition: ftstream.h:315
void * long_metrics
Definition: tttables.h:205
unsigned short FT_UShort
Definition: fttypes.h:205
#define FT_FRAME_SHORT(f)
Definition: ftstream.h:122
#define FT_FRAME_START(size)
Definition: ftstream.h:117
struct TT_LongMetricsRec_ * TT_LongMetrics