• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /***************************************************************************/
2 /*                                                                         */
3 /*  ttmtx.c                                                                */
4 /*                                                                         */
5 /*    Load the metrics tables common to TTF and OTF fonts (body).          */
6 /*                                                                         */
7 /*  Copyright 2006-2009, 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 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   /*                                                                       */
40   /* <Function>                                                            */
41   /*    tt_face_load_hmtx                                                  */
42   /*                                                                       */
43   /* <Description>                                                         */
44   /*    Load the `hmtx' or `vmtx' table into a face object.                */
45   /*                                                                       */
46   /* <Input>                                                               */
47   /*    face     :: A handle to the target face object.                    */
48   /*                                                                       */
49   /*    stream   :: The input stream.                                      */
50   /*                                                                       */
51   /*    vertical :: A boolean flag.  If set, load `vmtx'.                  */
52   /*                                                                       */
53   /* <Return>                                                              */
54   /*    FreeType error code.  0 means success.                             */
55   /*                                                                       */
56   FT_LOCAL_DEF( FT_Error )
tt_face_load_hmtx(TT_Face face,FT_Stream stream,FT_Bool vertical)57   tt_face_load_hmtx( TT_Face    face,
58                      FT_Stream  stream,
59                      FT_Bool    vertical )
60   {
61     FT_Error   error;
62     FT_ULong   tag, table_size;
63     FT_ULong*  ptable_offset;
64     FT_ULong*  ptable_size;
65 
66 
67     if ( vertical )
68     {
69       tag           = TTAG_vmtx;
70       ptable_offset = &face->vert_metrics_offset;
71       ptable_size   = &face->vert_metrics_size;
72     }
73     else
74     {
75       tag           = TTAG_hmtx;
76       ptable_offset = &face->horz_metrics_offset;
77       ptable_size   = &face->horz_metrics_size;
78     }
79 
80     error = face->goto_table( face, tag, stream, &table_size );
81     if ( error )
82       goto Fail;
83 
84     *ptable_size   = table_size;
85     *ptable_offset = FT_STREAM_POS();
86 
87   Fail:
88     return error;
89   }
90 
91 
92   /*************************************************************************/
93   /*                                                                       */
94   /* <Function>                                                            */
95   /*    tt_face_load_hhea                                                  */
96   /*                                                                       */
97   /* <Description>                                                         */
98   /*    Load the `hhea' or 'vhea' table into a face object.                */
99   /*                                                                       */
100   /* <Input>                                                               */
101   /*    face     :: A handle to the target face object.                    */
102   /*                                                                       */
103   /*    stream   :: The input stream.                                      */
104   /*                                                                       */
105   /*    vertical :: A boolean flag.  If set, load `vhea'.                  */
106   /*                                                                       */
107   /* <Return>                                                              */
108   /*    FreeType error code.  0 means success.                             */
109   /*                                                                       */
110   FT_LOCAL_DEF( FT_Error )
tt_face_load_hhea(TT_Face face,FT_Stream stream,FT_Bool vertical)111   tt_face_load_hhea( TT_Face    face,
112                      FT_Stream  stream,
113                      FT_Bool    vertical )
114   {
115     FT_Error        error;
116     TT_HoriHeader*  header;
117 
118     static const FT_Frame_Field  metrics_header_fields[] =
119     {
120 #undef  FT_STRUCTURE
121 #define FT_STRUCTURE  TT_HoriHeader
122 
123       FT_FRAME_START( 36 ),
124         FT_FRAME_ULONG ( Version ),
125         FT_FRAME_SHORT ( Ascender ),
126         FT_FRAME_SHORT ( Descender ),
127         FT_FRAME_SHORT ( Line_Gap ),
128         FT_FRAME_USHORT( advance_Width_Max ),
129         FT_FRAME_SHORT ( min_Left_Side_Bearing ),
130         FT_FRAME_SHORT ( min_Right_Side_Bearing ),
131         FT_FRAME_SHORT ( xMax_Extent ),
132         FT_FRAME_SHORT ( caret_Slope_Rise ),
133         FT_FRAME_SHORT ( caret_Slope_Run ),
134         FT_FRAME_SHORT ( caret_Offset ),
135         FT_FRAME_SHORT ( Reserved[0] ),
136         FT_FRAME_SHORT ( Reserved[1] ),
137         FT_FRAME_SHORT ( Reserved[2] ),
138         FT_FRAME_SHORT ( Reserved[3] ),
139         FT_FRAME_SHORT ( metric_Data_Format ),
140         FT_FRAME_USHORT( number_Of_HMetrics ),
141       FT_FRAME_END
142     };
143 
144 
145     if ( vertical )
146     {
147       void  *v = &face->vertical;
148 
149 
150       error = face->goto_table( face, TTAG_vhea, stream, 0 );
151       if ( error )
152         goto Fail;
153 
154       header = (TT_HoriHeader*)v;
155     }
156     else
157     {
158       error = face->goto_table( face, TTAG_hhea, stream, 0 );
159       if ( error )
160         goto Fail;
161 
162       header = &face->horizontal;
163     }
164 
165     if ( FT_STREAM_READ_FIELDS( metrics_header_fields, header ) )
166       goto Fail;
167 
168     FT_TRACE3(( "Ascender:          %5d\n", header->Ascender ));
169     FT_TRACE3(( "Descender:         %5d\n", header->Descender ));
170     FT_TRACE3(( "number_Of_Metrics: %5u\n", header->number_Of_HMetrics ));
171 
172     header->long_metrics  = NULL;
173     header->short_metrics = NULL;
174 
175   Fail:
176     return error;
177   }
178 
179 
180   /*************************************************************************/
181   /*                                                                       */
182   /* <Function>                                                            */
183   /*    tt_face_get_metrics                                                */
184   /*                                                                       */
185   /* <Description>                                                         */
186   /*    Returns the horizontal or vertical metrics in font units for a     */
187   /*    given glyph.  The metrics are the left side bearing (resp. top     */
188   /*    side bearing) and advance width (resp. advance height).            */
189   /*                                                                       */
190   /* <Input>                                                               */
191   /*    header  :: A pointer to either the horizontal or vertical metrics  */
192   /*               structure.                                              */
193   /*                                                                       */
194   /*    idx     :: The glyph index.                                        */
195   /*                                                                       */
196   /* <Output>                                                              */
197   /*    bearing :: The bearing, either left side or top side.              */
198   /*                                                                       */
199   /*    advance :: The advance width resp. advance height.                 */
200   /*                                                                       */
201   FT_LOCAL_DEF( FT_Error )
tt_face_get_metrics(TT_Face face,FT_Bool vertical,FT_UInt gindex,FT_Short * abearing,FT_UShort * aadvance)202   tt_face_get_metrics( TT_Face     face,
203                        FT_Bool     vertical,
204                        FT_UInt     gindex,
205                        FT_Short   *abearing,
206                        FT_UShort  *aadvance )
207   {
208     FT_Error        error;
209     FT_Stream       stream = face->root.stream;
210     TT_HoriHeader*  header;
211     FT_ULong        table_pos, table_size, table_end;
212     FT_UShort       k;
213 
214 
215     if ( vertical )
216     {
217       void*  v = &face->vertical;
218 
219 
220       header     = (TT_HoriHeader*)v;
221       table_pos  = face->vert_metrics_offset;
222       table_size = face->vert_metrics_size;
223     }
224     else
225     {
226       header     = &face->horizontal;
227       table_pos  = face->horz_metrics_offset;
228       table_size = face->horz_metrics_size;
229     }
230 
231     table_end = table_pos + table_size;
232 
233     k = header->number_Of_HMetrics;
234 
235     if ( k > 0 )
236     {
237       if ( gindex < (FT_UInt)k )
238       {
239         table_pos += 4 * gindex;
240         if ( table_pos + 4 > table_end )
241           goto NoData;
242 
243         if ( FT_STREAM_SEEK( table_pos ) ||
244              FT_READ_USHORT( *aadvance ) ||
245              FT_READ_SHORT( *abearing )  )
246           goto NoData;
247       }
248       else
249       {
250         table_pos += 4 * ( k - 1 );
251         if ( table_pos + 4 > table_end )
252           goto NoData;
253 
254         if ( FT_STREAM_SEEK( table_pos ) ||
255              FT_READ_USHORT( *aadvance ) )
256           goto NoData;
257 
258         table_pos += 4 + 2 * ( gindex - k );
259         if ( table_pos + 2 > table_end )
260           *abearing = 0;
261         else
262         {
263           if ( !FT_STREAM_SEEK( table_pos ) )
264             (void)FT_READ_SHORT( *abearing );
265         }
266       }
267     }
268     else
269     {
270     NoData:
271       *abearing = 0;
272       *aadvance = 0;
273     }
274 
275     return FT_Err_Ok;
276   }
277 
278 
279 /* END */
280