[FREETYPE] Update to v2.6.3. CORE-10964
[reactos.git] / reactos / lib / 3rdparty / freetype / 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-2016 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 )
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 )
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 /* Return the horizontal or vertical metrics in font units for a */
187 /* given glyph. The values are the left side bearing (top side */
188 /* bearing for vertical metrics) and advance width (advance height */
189 /* for vertical metrics). */
190 /* */
191 /* <Input> */
192 /* face :: A pointer to the TrueType face structure. */
193 /* */
194 /* vertical :: If set to TRUE, get vertical metrics. */
195 /* */
196 /* gindex :: The glyph index. */
197 /* */
198 /* <Output> */
199 /* abearing :: The bearing, either left side or top side. */
200 /* */
201 /* aadvance :: The advance width or advance height, depending on */
202 /* the `vertical' flag. */
203 /* */
204 FT_LOCAL_DEF( void )
205 tt_face_get_metrics( TT_Face face,
206 FT_Bool vertical,
207 FT_UInt gindex,
208 FT_Short *abearing,
209 FT_UShort *aadvance )
210 {
211 FT_Error error;
212 FT_Stream stream = face->root.stream;
213 TT_HoriHeader* header;
214 FT_ULong table_pos, table_size, table_end;
215 FT_UShort k;
216
217
218 if ( vertical )
219 {
220 void* v = &face->vertical;
221
222
223 header = (TT_HoriHeader*)v;
224 table_pos = face->vert_metrics_offset;
225 table_size = face->vert_metrics_size;
226 }
227 else
228 {
229 header = &face->horizontal;
230 table_pos = face->horz_metrics_offset;
231 table_size = face->horz_metrics_size;
232 }
233
234 table_end = table_pos + table_size;
235
236 k = header->number_Of_HMetrics;
237
238 if ( k > 0 )
239 {
240 if ( gindex < (FT_UInt)k )
241 {
242 table_pos += 4 * gindex;
243 if ( table_pos + 4 > table_end )
244 goto NoData;
245
246 if ( FT_STREAM_SEEK( table_pos ) ||
247 FT_READ_USHORT( *aadvance ) ||
248 FT_READ_SHORT( *abearing ) )
249 goto NoData;
250 }
251 else
252 {
253 table_pos += 4 * ( k - 1 );
254 if ( table_pos + 4 > table_end )
255 goto NoData;
256
257 if ( FT_STREAM_SEEK( table_pos ) ||
258 FT_READ_USHORT( *aadvance ) )
259 goto NoData;
260
261 table_pos += 4 + 2 * ( gindex - k );
262 if ( table_pos + 2 > table_end )
263 *abearing = 0;
264 else
265 {
266 if ( !FT_STREAM_SEEK( table_pos ) )
267 (void)FT_READ_SHORT( *abearing );
268 }
269 }
270 }
271 else
272 {
273 NoData:
274 *abearing = 0;
275 *aadvance = 0;
276 }
277 }
278
279
280 /* END */