blob: 212d484eae58a2bc2ef1c1deef96812ce0daa2dc [file] [log] [blame]
David Turnerd2b1f351999-12-16 23:11:37 +00001/***************************************************************************/
2/* */
David Turner19ed8af2000-12-08 02:42:29 +00003/* ttpload.c */
David Turnerd2b1f351999-12-16 23:11:37 +00004/* */
5/* TrueType glyph data/program tables loader (body). */
6/* */
Werner Lemberg415235d2001-06-28 17:49:10 +00007/* Copyright 1996-2001 by */
David Turnerd2b1f351999-12-16 23:11:37 +00008/* David Turner, Robert Wilhelm, and Werner Lemberg. */
9/* */
Werner Lemberg78575dc2000-06-12 19:36:41 +000010/* This file is part of the FreeType project, and may only be used, */
11/* modified, and distributed under the terms of the FreeType project */
David Turnerd2b1f351999-12-16 23:11:37 +000012/* 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
Werner Lembergcc069be2000-12-08 16:17:16 +000018
David Turner19ed8af2000-12-08 02:42:29 +000019#include <ft2build.h>
20#include FT_INTERNAL_DEBUG_H
21#include FT_INTERNAL_OBJECTS_H
22#include FT_INTERNAL_STREAM_H
23#include FT_TRUETYPE_TAGS_H
Werner Lemberg1f7f0e82001-06-06 17:30:41 +000024
David Turner8d3a4012001-03-20 11:14:24 +000025#include "ttpload.h"
Werner Lemberg1f7f0e82001-06-06 17:30:41 +000026
27#include "tterrors.h"
David Turnerd2b1f351999-12-16 23:11:37 +000028
Werner Lemberg78575dc2000-06-12 19:36:41 +000029
30 /*************************************************************************/
31 /* */
32 /* The macro FT_COMPONENT is used in trace mode. It is an implicit */
33 /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */
34 /* messages during execution. */
35 /* */
David Turnerd2b1f351999-12-16 23:11:37 +000036#undef FT_COMPONENT
Werner Lemberg78575dc2000-06-12 19:36:41 +000037#define FT_COMPONENT trace_ttpload
38
David Turnerd2b1f351999-12-16 23:11:37 +000039
40 /*************************************************************************/
41 /* */
42 /* <Function> */
43 /* TT_Load_Locations */
44 /* */
45 /* <Description> */
46 /* Loads the locations table. */
47 /* */
Werner Lemberg78575dc2000-06-12 19:36:41 +000048 /* <InOut> */
David Turnerd2b1f351999-12-16 23:11:37 +000049 /* face :: A handle to the target face object. */
Werner Lemberg78575dc2000-06-12 19:36:41 +000050 /* */
51 /* <Input> */
David Turnerd2b1f351999-12-16 23:11:37 +000052 /* stream :: The input stream. */
53 /* */
54 /* <Return> */
Werner Lemberg9ca2af32000-06-21 03:03:28 +000055 /* FreeType error code. 0 means success. */
David Turnerd2b1f351999-12-16 23:11:37 +000056 /* */
David Turnerbc82f1b2002-03-01 02:26:22 +000057 FT_LOCAL_DEF( FT_Error )
Werner Lemberg4a2305c2001-06-28 07:17:51 +000058 TT_Load_Locations( TT_Face face,
59 FT_Stream stream )
David Turnerd2b1f351999-12-16 23:11:37 +000060 {
David Turnerf9b8dec2000-06-16 19:34:52 +000061 FT_Error error;
David Turnerd2b1f351999-12-16 23:11:37 +000062 FT_Memory memory = stream->memory;
David Turnerf9b8dec2000-06-16 19:34:52 +000063 FT_Short LongOffsets;
64 FT_ULong table_len;
David Turnerd2b1f351999-12-16 23:11:37 +000065
Werner Lemberg78575dc2000-06-12 19:36:41 +000066
David Turnerd2b1f351999-12-16 23:11:37 +000067 FT_TRACE2(( "Locations " ));
68 LongOffsets = face->header.Index_To_Loc_Format;
69
70 error = face->goto_table( face, TTAG_loca, stream, &table_len );
Werner Lemberg78575dc2000-06-12 19:36:41 +000071 if ( error )
David Turnerd2b1f351999-12-16 23:11:37 +000072 {
73 error = TT_Err_Locations_Missing;
74 goto Exit;
75 }
76
77 if ( LongOffsets != 0 )
78 {
David Turnerf9b8dec2000-06-16 19:34:52 +000079 face->num_locations = (FT_UShort)( table_len >> 2 );
David Turnerd2b1f351999-12-16 23:11:37 +000080
Werner Lemberg78575dc2000-06-12 19:36:41 +000081 FT_TRACE2(( "(32bit offsets): %12d ", face->num_locations ));
David Turnerd2b1f351999-12-16 23:11:37 +000082
David Turnere459d742002-03-22 13:52:37 +000083 if ( FT_NEW_ARRAY( face->glyph_locations, face->num_locations ) )
David Turnerd2b1f351999-12-16 23:11:37 +000084 goto Exit;
85
David Turner7d3a2642002-03-20 10:49:31 +000086 if ( FT_FRAME_ENTER( face->num_locations * 4L ) )
David Turnerd2b1f351999-12-16 23:11:37 +000087 goto Exit;
88
89 {
David Turnerf9b8dec2000-06-16 19:34:52 +000090 FT_Long* loc = face->glyph_locations;
91 FT_Long* limit = loc + face->num_locations;
David Turnerd2b1f351999-12-16 23:11:37 +000092
Werner Lemberg78575dc2000-06-12 19:36:41 +000093
David Turnerd2b1f351999-12-16 23:11:37 +000094 for ( ; loc < limit; loc++ )
David Turnera890c292002-03-22 12:55:23 +000095 *loc = FT_GET_LONG();
David Turnerd2b1f351999-12-16 23:11:37 +000096 }
97
David Turner7d3a2642002-03-20 10:49:31 +000098 FT_FRAME_EXIT();
David Turnerd2b1f351999-12-16 23:11:37 +000099 }
100 else
101 {
David Turnerf9b8dec2000-06-16 19:34:52 +0000102 face->num_locations = (FT_UShort)( table_len >> 1 );
David Turnerd2b1f351999-12-16 23:11:37 +0000103
Werner Lemberg78575dc2000-06-12 19:36:41 +0000104 FT_TRACE2(( "(16bit offsets): %12d ", face->num_locations ));
David Turnerd2b1f351999-12-16 23:11:37 +0000105
David Turnere459d742002-03-22 13:52:37 +0000106 if ( FT_NEW_ARRAY( face->glyph_locations, face->num_locations ) )
David Turnerd2b1f351999-12-16 23:11:37 +0000107 goto Exit;
108
David Turner7d3a2642002-03-20 10:49:31 +0000109 if ( FT_FRAME_ENTER( face->num_locations * 2L ) )
David Turnerd2b1f351999-12-16 23:11:37 +0000110 goto Exit;
111 {
David Turnerf9b8dec2000-06-16 19:34:52 +0000112 FT_Long* loc = face->glyph_locations;
113 FT_Long* limit = loc + face->num_locations;
David Turnerd2b1f351999-12-16 23:11:37 +0000114
Werner Lemberg78575dc2000-06-12 19:36:41 +0000115
David Turnerd2b1f351999-12-16 23:11:37 +0000116 for ( ; loc < limit; loc++ )
David Turnera890c292002-03-22 12:55:23 +0000117 *loc = (FT_Long)( (FT_ULong)FT_GET_USHORT() * 2 );
David Turnerd2b1f351999-12-16 23:11:37 +0000118 }
David Turner7d3a2642002-03-20 10:49:31 +0000119 FT_FRAME_EXIT();
David Turnerd2b1f351999-12-16 23:11:37 +0000120 }
121
122 FT_TRACE2(( "loaded\n" ));
123
124 Exit:
125 return error;
126 }
127
128
129 /*************************************************************************/
130 /* */
131 /* <Function> */
132 /* TT_Load_CVT */
133 /* */
134 /* <Description> */
135 /* Loads the control value table into a face object. */
136 /* */
Werner Lemberg78575dc2000-06-12 19:36:41 +0000137 /* <InOut> */
David Turnerd2b1f351999-12-16 23:11:37 +0000138 /* face :: A handle to the target face object. */
Werner Lemberg78575dc2000-06-12 19:36:41 +0000139 /* */
140 /* <Input> */
David Turnerd2b1f351999-12-16 23:11:37 +0000141 /* stream :: A handle to the input stream. */
142 /* */
143 /* <Return> */
Werner Lemberg9ca2af32000-06-21 03:03:28 +0000144 /* FreeType error code. 0 means success. */
David Turnerd2b1f351999-12-16 23:11:37 +0000145 /* */
David Turnerbc82f1b2002-03-01 02:26:22 +0000146 FT_LOCAL_DEF( FT_Error )
Werner Lemberg4a2305c2001-06-28 07:17:51 +0000147 TT_Load_CVT( TT_Face face,
148 FT_Stream stream )
David Turnerd2b1f351999-12-16 23:11:37 +0000149 {
David Turnerf9b8dec2000-06-16 19:34:52 +0000150 FT_Error error;
David Turnerd2b1f351999-12-16 23:11:37 +0000151 FT_Memory memory = stream->memory;
David Turnerf9b8dec2000-06-16 19:34:52 +0000152 FT_ULong table_len;
David Turnerd2b1f351999-12-16 23:11:37 +0000153
Werner Lemberg78575dc2000-06-12 19:36:41 +0000154
David Turnerd2b1f351999-12-16 23:11:37 +0000155 FT_TRACE2(( "CVT " ));
156
157 error = face->goto_table( face, TTAG_cvt, stream, &table_len );
Werner Lemberg78575dc2000-06-12 19:36:41 +0000158 if ( error )
David Turnerd2b1f351999-12-16 23:11:37 +0000159 {
160 FT_TRACE2(( "is missing!\n" ));
161
162 face->cvt_size = 0;
163 face->cvt = NULL;
164 error = TT_Err_Ok;
165
166 goto Exit;
167 }
168
169 face->cvt_size = table_len / 2;
170
David Turnere459d742002-03-22 13:52:37 +0000171 if ( FT_NEW_ARRAY( face->cvt, face->cvt_size ) )
David Turnerd2b1f351999-12-16 23:11:37 +0000172 goto Exit;
173
David Turner7d3a2642002-03-20 10:49:31 +0000174 if ( FT_FRAME_ENTER( face->cvt_size * 2L ) )
David Turnerd2b1f351999-12-16 23:11:37 +0000175 goto Exit;
176
177 {
David Turnerf9b8dec2000-06-16 19:34:52 +0000178 FT_Short* cur = face->cvt;
179 FT_Short* limit = cur + face->cvt_size;
David Turnerd2b1f351999-12-16 23:11:37 +0000180
Werner Lemberg78575dc2000-06-12 19:36:41 +0000181
David Turnerd2b1f351999-12-16 23:11:37 +0000182 for ( ; cur < limit; cur++ )
David Turnera890c292002-03-22 12:55:23 +0000183 *cur = FT_GET_SHORT();
David Turnerd2b1f351999-12-16 23:11:37 +0000184 }
185
David Turner7d3a2642002-03-20 10:49:31 +0000186 FT_FRAME_EXIT();
David Turnerd2b1f351999-12-16 23:11:37 +0000187 FT_TRACE2(( "loaded\n" ));
188
189 Exit:
190 return error;
191 }
192
193
194 /*************************************************************************/
195 /* */
196 /* <Function> */
197 /* TT_Load_Progams */
198 /* */
199 /* <Description> */
200 /* Loads the font program and the cvt program. */
201 /* */
Werner Lemberg78575dc2000-06-12 19:36:41 +0000202 /* <InOut> */
David Turnerd2b1f351999-12-16 23:11:37 +0000203 /* face :: A handle to the target face object. */
Werner Lemberg78575dc2000-06-12 19:36:41 +0000204 /* */
205 /* <Input> */
David Turnerd2b1f351999-12-16 23:11:37 +0000206 /* stream :: A handle to the input stream. */
207 /* */
208 /* <Return> */
Werner Lemberg9ca2af32000-06-21 03:03:28 +0000209 /* FreeType error code. 0 means success. */
David Turnerd2b1f351999-12-16 23:11:37 +0000210 /* */
David Turnerbc82f1b2002-03-01 02:26:22 +0000211 FT_LOCAL_DEF( FT_Error )
Werner Lemberg4a2305c2001-06-28 07:17:51 +0000212 TT_Load_Programs( TT_Face face,
213 FT_Stream stream )
David Turnerd2b1f351999-12-16 23:11:37 +0000214 {
David Turnerf9b8dec2000-06-16 19:34:52 +0000215 FT_Error error;
216 FT_ULong table_len;
David Turnerd2b1f351999-12-16 23:11:37 +0000217
Werner Lemberg78575dc2000-06-12 19:36:41 +0000218
Werner Lembergf6978662000-01-08 20:00:54 +0000219 FT_TRACE2(( "Font program " ));
David Turnerd2b1f351999-12-16 23:11:37 +0000220
221 /* The font program is optional */
222 error = face->goto_table( face, TTAG_fpgm, stream, &table_len );
Werner Lembergf6978662000-01-08 20:00:54 +0000223 if ( error )
David Turnerd2b1f351999-12-16 23:11:37 +0000224 {
225 face->font_program = NULL;
226 face->font_program_size = 0;
Werner Lemberg78575dc2000-06-12 19:36:41 +0000227
David Turnerd2b1f351999-12-16 23:11:37 +0000228 FT_TRACE2(( "is missing!\n" ));
229 }
230 else
231 {
232 face->font_program_size = table_len;
David Turner7d3a2642002-03-20 10:49:31 +0000233 if ( FT_FRAME_EXTRACT( table_len, face->font_program ) )
David Turnerd2b1f351999-12-16 23:11:37 +0000234 goto Exit;
235
236 FT_TRACE2(( "loaded, %12d bytes\n", face->font_program_size ));
237 }
238
239 FT_TRACE2(( "Prep program " ));
240
241 error = face->goto_table( face, TTAG_prep, stream, &table_len );
Werner Lembergf6978662000-01-08 20:00:54 +0000242 if ( error )
David Turnerd2b1f351999-12-16 23:11:37 +0000243 {
244 face->cvt_program = NULL;
245 face->cvt_program_size = 0;
Werner Lembergf6978662000-01-08 20:00:54 +0000246 error = TT_Err_Ok;
David Turnerd2b1f351999-12-16 23:11:37 +0000247
248 FT_TRACE2(( "is missing!\n" ));
249 }
250 else
251 {
252 face->cvt_program_size = table_len;
David Turner7d3a2642002-03-20 10:49:31 +0000253 if ( FT_FRAME_EXTRACT( table_len, face->cvt_program ) )
David Turner2e421312000-05-26 22:13:17 +0000254 goto Exit;
Werner Lemberg78575dc2000-06-12 19:36:41 +0000255
David Turnerd2b1f351999-12-16 23:11:37 +0000256 FT_TRACE2(( "loaded, %12d bytes\n", face->cvt_program_size ));
257 }
258
259 Exit:
260 return error;
261 }
262
263
264/* END */