XFA: merge patch from CL 817753002
[pdfium.git] / core / src / fxge / fx_freetype / fxft2.5.01 / src / sfnt / ttmtx.c
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 "../../include/ft2build.h"
20 #include "../../include/freetype/internal/ftdebug.h"
21 #include "../../include/freetype/internal/ftstream.h"
22 #include "../../include/freetype/tttags.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 )
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 0
82     if ( error )
83       goto Fail;
84
85     *ptable_size   = table_size;
86     *ptable_offset = FT_STREAM_POS();
87
88   Fail:
89     return error;
90 #else
91         *ptable_size   =  error ? 0 : table_size;
92         *ptable_offset = FT_STREAM_POS();
93
94         return 0;
95 #endif
96   }
97
98
99   /*************************************************************************/
100   /*                                                                       */
101   /* <Function>                                                            */
102   /*    tt_face_load_hhea                                                  */
103   /*                                                                       */
104   /* <Description>                                                         */
105   /*    Load the `hhea' or 'vhea' table into a face object.                */
106   /*                                                                       */
107   /* <Input>                                                               */
108   /*    face     :: A handle to the target face object.                    */
109   /*                                                                       */
110   /*    stream   :: The input stream.                                      */
111   /*                                                                       */
112   /*    vertical :: A boolean flag.  If set, load `vhea'.                  */
113   /*                                                                       */
114   /* <Return>                                                              */
115   /*    FreeType error code.  0 means success.                             */
116   /*                                                                       */
117   FT_LOCAL_DEF( FT_Error )
118   tt_face_load_hhea( TT_Face    face,
119                      FT_Stream  stream,
120                      FT_Bool    vertical )
121   {
122     FT_Error        error;
123     TT_HoriHeader*  header;
124
125     static const FT_Frame_Field  metrics_header_fields[] =
126     {
127 #undef  FT_STRUCTURE
128 #define FT_STRUCTURE  TT_HoriHeader
129
130       FT_FRAME_START( 36 ),
131         FT_FRAME_ULONG ( Version ),
132         FT_FRAME_SHORT ( Ascender ),
133         FT_FRAME_SHORT ( Descender ),
134         FT_FRAME_SHORT ( Line_Gap ),
135         FT_FRAME_USHORT( advance_Width_Max ),
136         FT_FRAME_SHORT ( min_Left_Side_Bearing ),
137         FT_FRAME_SHORT ( min_Right_Side_Bearing ),
138         FT_FRAME_SHORT ( xMax_Extent ),
139         FT_FRAME_SHORT ( caret_Slope_Rise ),
140         FT_FRAME_SHORT ( caret_Slope_Run ),
141         FT_FRAME_SHORT ( caret_Offset ),
142         FT_FRAME_SHORT ( Reserved[0] ),
143         FT_FRAME_SHORT ( Reserved[1] ),
144         FT_FRAME_SHORT ( Reserved[2] ),
145         FT_FRAME_SHORT ( Reserved[3] ),
146         FT_FRAME_SHORT ( metric_Data_Format ),
147         FT_FRAME_USHORT( number_Of_HMetrics ),
148       FT_FRAME_END
149     };
150
151
152     if ( vertical )
153     {
154       void  *v = &face->vertical;
155
156
157       error = face->goto_table( face, TTAG_vhea, stream, 0 );
158       if ( error )
159         goto Fail;
160
161       header = (TT_HoriHeader*)v;
162     }
163     else
164     {
165       error = face->goto_table( face, TTAG_hhea, stream, 0 );
166       if ( error )
167         goto Fail;
168
169       header = &face->horizontal;
170     }
171
172     if ( FT_STREAM_READ_FIELDS( metrics_header_fields, header ) )
173       goto Fail;
174
175     FT_TRACE3(( "Ascender:          %5d\n", header->Ascender ));
176     FT_TRACE3(( "Descender:         %5d\n", header->Descender ));
177     FT_TRACE3(( "number_Of_Metrics: %5u\n", header->number_Of_HMetrics ));
178
179     header->long_metrics  = NULL;
180     header->short_metrics = NULL;
181
182   Fail:
183     return error;
184   }
185
186
187   /*************************************************************************/
188   /*                                                                       */
189   /* <Function>                                                            */
190   /*    tt_face_get_metrics                                                */
191   /*                                                                       */
192   /* <Description>                                                         */
193   /*    Returns the horizontal or vertical metrics in font units for a     */
194   /*    given glyph.  The metrics are the left side bearing (resp. top     */
195   /*    side bearing) and advance width (resp. advance height).            */
196   /*                                                                       */
197   /* <Input>                                                               */
198   /*    header  :: A pointer to either the horizontal or vertical metrics  */
199   /*               structure.                                              */
200   /*                                                                       */
201   /*    idx     :: The glyph index.                                        */
202   /*                                                                       */
203   /* <Output>                                                              */
204   /*    bearing :: The bearing, either left side or top side.              */
205   /*                                                                       */
206   /*    advance :: The advance width resp. advance height.                 */
207   /*                                                                       */
208   FT_LOCAL_DEF( FT_Error )
209   tt_face_get_metrics( TT_Face     face,
210                        FT_Bool     vertical,
211                        FT_UInt     gindex,
212                        FT_Short   *abearing,
213                        FT_UShort  *aadvance )
214   {
215     FT_Error        error;
216     FT_Stream       stream = face->root.stream;
217     TT_HoriHeader*  header;
218     FT_ULong        table_pos, table_size, table_end;
219     FT_UShort       k;
220
221
222     if ( vertical )
223     {
224       void*  v = &face->vertical;
225
226
227       header     = (TT_HoriHeader*)v;
228       table_pos  = face->vert_metrics_offset;
229       table_size = face->vert_metrics_size;
230     }
231     else
232     {
233       header     = &face->horizontal;
234       table_pos  = face->horz_metrics_offset;
235       table_size = face->horz_metrics_size;
236     }
237
238     table_end = table_pos + table_size;
239
240     k = header->number_Of_HMetrics;
241
242     if ( k > 0 )
243     {
244       if ( gindex < (FT_UInt)k )
245       {
246         table_pos += 4 * gindex;
247         if ( table_pos + 4 > table_end )
248           goto NoData;
249
250         if ( FT_STREAM_SEEK( table_pos ) ||
251              FT_READ_USHORT( *aadvance ) ||
252              FT_READ_SHORT( *abearing )  )
253           goto NoData;
254       }
255       else
256       {
257         table_pos += 4 * ( k - 1 );
258         if ( table_pos + 4 > table_end )
259           goto NoData;
260
261         if ( FT_STREAM_SEEK( table_pos ) ||
262              FT_READ_USHORT( *aadvance ) )
263           goto NoData;
264
265         table_pos += 4 + 2 * ( gindex - k );
266         if ( table_pos + 2 > table_end )
267           *abearing = 0;
268         else
269         {
270           if ( !FT_STREAM_SEEK( table_pos ) )
271             (void)FT_READ_SHORT( *abearing );
272         }
273       }
274     }
275     else
276     {
277     NoData:
278       *abearing = 0;
279       *aadvance = 0;
280     }
281
282     return FT_Err_Ok;
283   }
284
285
286 /* END */