David Turner | d2b1f35 | 1999-12-16 23:11:37 +0000 | [diff] [blame] | 1 | /***************************************************************************/ |
| 2 | /* */ |
| 3 | /* ttpload.h */ |
| 4 | /* */ |
| 5 | /* TrueType glyph data/program tables loader (body). */ |
| 6 | /* */ |
Werner Lemberg | 78575dc | 2000-06-12 19:36:41 +0000 | [diff] [blame] | 7 | /* Copyright 1996-2000 by */ |
David Turner | d2b1f35 | 1999-12-16 23:11:37 +0000 | [diff] [blame] | 8 | /* David Turner, Robert Wilhelm, and Werner Lemberg. */ |
| 9 | /* */ |
Werner Lemberg | 78575dc | 2000-06-12 19:36:41 +0000 | [diff] [blame] | 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 */ |
David Turner | d2b1f35 | 1999-12-16 23:11:37 +0000 | [diff] [blame] | 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 | |
David Turner | efce08d | 2000-05-11 18:23:52 +0000 | [diff] [blame] | 19 | #include <freetype/internal/ftdebug.h> |
| 20 | #include <freetype/internal/ftobjs.h> |
| 21 | #include <freetype/internal/ftstream.h> |
| 22 | #include <freetype/tttags.h> |
David Turner | d2b1f35 | 1999-12-16 23:11:37 +0000 | [diff] [blame] | 23 | |
| 24 | #include <ttpload.h> |
Werner Lemberg | e1d5dd7 | 2000-06-07 04:48:12 +0000 | [diff] [blame] | 25 | #include <freetype/internal/tterrors.h> |
David Turner | d2b1f35 | 1999-12-16 23:11:37 +0000 | [diff] [blame] | 26 | |
Werner Lemberg | 78575dc | 2000-06-12 19:36:41 +0000 | [diff] [blame] | 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 | /* */ |
David Turner | d2b1f35 | 1999-12-16 23:11:37 +0000 | [diff] [blame] | 34 | #undef FT_COMPONENT |
Werner Lemberg | 78575dc | 2000-06-12 19:36:41 +0000 | [diff] [blame] | 35 | #define FT_COMPONENT trace_ttpload |
| 36 | |
David Turner | d2b1f35 | 1999-12-16 23:11:37 +0000 | [diff] [blame] | 37 | |
| 38 | /*************************************************************************/ |
| 39 | /* */ |
| 40 | /* <Function> */ |
| 41 | /* TT_Load_Locations */ |
| 42 | /* */ |
| 43 | /* <Description> */ |
| 44 | /* Loads the locations table. */ |
| 45 | /* */ |
Werner Lemberg | 78575dc | 2000-06-12 19:36:41 +0000 | [diff] [blame] | 46 | /* <InOut> */ |
David Turner | d2b1f35 | 1999-12-16 23:11:37 +0000 | [diff] [blame] | 47 | /* face :: A handle to the target face object. */ |
Werner Lemberg | 78575dc | 2000-06-12 19:36:41 +0000 | [diff] [blame] | 48 | /* */ |
| 49 | /* <Input> */ |
David Turner | d2b1f35 | 1999-12-16 23:11:37 +0000 | [diff] [blame] | 50 | /* stream :: The input stream. */ |
| 51 | /* */ |
| 52 | /* <Return> */ |
| 53 | /* TrueType error code. 0 means success. */ |
| 54 | /* */ |
| 55 | LOCAL_FUNC |
David Turner | f9b8dec | 2000-06-16 19:34:52 +0000 | [diff] [blame^] | 56 | FT_Error TT_Load_Locations( TT_Face face, |
David Turner | d2b1f35 | 1999-12-16 23:11:37 +0000 | [diff] [blame] | 57 | FT_Stream stream ) |
| 58 | { |
David Turner | f9b8dec | 2000-06-16 19:34:52 +0000 | [diff] [blame^] | 59 | FT_Error error; |
David Turner | d2b1f35 | 1999-12-16 23:11:37 +0000 | [diff] [blame] | 60 | FT_Memory memory = stream->memory; |
David Turner | f9b8dec | 2000-06-16 19:34:52 +0000 | [diff] [blame^] | 61 | FT_Short LongOffsets; |
| 62 | FT_ULong table_len; |
David Turner | d2b1f35 | 1999-12-16 23:11:37 +0000 | [diff] [blame] | 63 | |
Werner Lemberg | 78575dc | 2000-06-12 19:36:41 +0000 | [diff] [blame] | 64 | |
David Turner | d2b1f35 | 1999-12-16 23:11:37 +0000 | [diff] [blame] | 65 | FT_TRACE2(( "Locations " )); |
| 66 | LongOffsets = face->header.Index_To_Loc_Format; |
| 67 | |
| 68 | error = face->goto_table( face, TTAG_loca, stream, &table_len ); |
Werner Lemberg | 78575dc | 2000-06-12 19:36:41 +0000 | [diff] [blame] | 69 | if ( error ) |
David Turner | d2b1f35 | 1999-12-16 23:11:37 +0000 | [diff] [blame] | 70 | { |
| 71 | error = TT_Err_Locations_Missing; |
| 72 | goto Exit; |
| 73 | } |
| 74 | |
| 75 | if ( LongOffsets != 0 ) |
| 76 | { |
David Turner | f9b8dec | 2000-06-16 19:34:52 +0000 | [diff] [blame^] | 77 | face->num_locations = (FT_UShort)( table_len >> 2 ); |
David Turner | d2b1f35 | 1999-12-16 23:11:37 +0000 | [diff] [blame] | 78 | |
Werner Lemberg | 78575dc | 2000-06-12 19:36:41 +0000 | [diff] [blame] | 79 | FT_TRACE2(( "(32bit offsets): %12d ", face->num_locations )); |
David Turner | d2b1f35 | 1999-12-16 23:11:37 +0000 | [diff] [blame] | 80 | |
| 81 | if ( ALLOC_ARRAY( face->glyph_locations, |
| 82 | face->num_locations, |
David Turner | f9b8dec | 2000-06-16 19:34:52 +0000 | [diff] [blame^] | 83 | FT_Long ) ) |
David Turner | d2b1f35 | 1999-12-16 23:11:37 +0000 | [diff] [blame] | 84 | goto Exit; |
| 85 | |
| 86 | if ( ACCESS_Frame( face->num_locations * 4L ) ) |
| 87 | goto Exit; |
| 88 | |
| 89 | { |
David Turner | f9b8dec | 2000-06-16 19:34:52 +0000 | [diff] [blame^] | 90 | FT_Long* loc = face->glyph_locations; |
| 91 | FT_Long* limit = loc + face->num_locations; |
David Turner | d2b1f35 | 1999-12-16 23:11:37 +0000 | [diff] [blame] | 92 | |
Werner Lemberg | 78575dc | 2000-06-12 19:36:41 +0000 | [diff] [blame] | 93 | |
David Turner | d2b1f35 | 1999-12-16 23:11:37 +0000 | [diff] [blame] | 94 | for ( ; loc < limit; loc++ ) |
| 95 | *loc = GET_Long(); |
| 96 | } |
| 97 | |
| 98 | FORGET_Frame(); |
| 99 | } |
| 100 | else |
| 101 | { |
David Turner | f9b8dec | 2000-06-16 19:34:52 +0000 | [diff] [blame^] | 102 | face->num_locations = (FT_UShort)( table_len >> 1 ); |
David Turner | d2b1f35 | 1999-12-16 23:11:37 +0000 | [diff] [blame] | 103 | |
Werner Lemberg | 78575dc | 2000-06-12 19:36:41 +0000 | [diff] [blame] | 104 | FT_TRACE2(( "(16bit offsets): %12d ", face->num_locations )); |
David Turner | d2b1f35 | 1999-12-16 23:11:37 +0000 | [diff] [blame] | 105 | |
| 106 | if ( ALLOC_ARRAY( face->glyph_locations, |
| 107 | face->num_locations, |
David Turner | f9b8dec | 2000-06-16 19:34:52 +0000 | [diff] [blame^] | 108 | FT_Long ) ) |
David Turner | d2b1f35 | 1999-12-16 23:11:37 +0000 | [diff] [blame] | 109 | goto Exit; |
| 110 | |
| 111 | if ( ACCESS_Frame( face->num_locations * 2L ) ) |
| 112 | goto Exit; |
| 113 | { |
David Turner | f9b8dec | 2000-06-16 19:34:52 +0000 | [diff] [blame^] | 114 | FT_Long* loc = face->glyph_locations; |
| 115 | FT_Long* limit = loc + face->num_locations; |
David Turner | d2b1f35 | 1999-12-16 23:11:37 +0000 | [diff] [blame] | 116 | |
Werner Lemberg | 78575dc | 2000-06-12 19:36:41 +0000 | [diff] [blame] | 117 | |
David Turner | d2b1f35 | 1999-12-16 23:11:37 +0000 | [diff] [blame] | 118 | for ( ; loc < limit; loc++ ) |
David Turner | f9b8dec | 2000-06-16 19:34:52 +0000 | [diff] [blame^] | 119 | *loc = (FT_Long)( (FT_ULong)GET_UShort() * 2 ); |
David Turner | d2b1f35 | 1999-12-16 23:11:37 +0000 | [diff] [blame] | 120 | } |
| 121 | FORGET_Frame(); |
| 122 | } |
| 123 | |
| 124 | FT_TRACE2(( "loaded\n" )); |
| 125 | |
| 126 | Exit: |
| 127 | return error; |
| 128 | } |
| 129 | |
| 130 | |
| 131 | /*************************************************************************/ |
| 132 | /* */ |
| 133 | /* <Function> */ |
| 134 | /* TT_Load_CVT */ |
| 135 | /* */ |
| 136 | /* <Description> */ |
| 137 | /* Loads the control value table into a face object. */ |
| 138 | /* */ |
Werner Lemberg | 78575dc | 2000-06-12 19:36:41 +0000 | [diff] [blame] | 139 | /* <InOut> */ |
David Turner | d2b1f35 | 1999-12-16 23:11:37 +0000 | [diff] [blame] | 140 | /* face :: A handle to the target face object. */ |
Werner Lemberg | 78575dc | 2000-06-12 19:36:41 +0000 | [diff] [blame] | 141 | /* */ |
| 142 | /* <Input> */ |
David Turner | d2b1f35 | 1999-12-16 23:11:37 +0000 | [diff] [blame] | 143 | /* stream :: A handle to the input stream. */ |
| 144 | /* */ |
| 145 | /* <Return> */ |
| 146 | /* TrueType error code. 0 means success. */ |
| 147 | /* */ |
| 148 | LOCAL_FUNC |
David Turner | f9b8dec | 2000-06-16 19:34:52 +0000 | [diff] [blame^] | 149 | FT_Error TT_Load_CVT( TT_Face face, |
David Turner | d2b1f35 | 1999-12-16 23:11:37 +0000 | [diff] [blame] | 150 | FT_Stream stream ) |
| 151 | { |
David Turner | f9b8dec | 2000-06-16 19:34:52 +0000 | [diff] [blame^] | 152 | FT_Error error; |
David Turner | d2b1f35 | 1999-12-16 23:11:37 +0000 | [diff] [blame] | 153 | FT_Memory memory = stream->memory; |
David Turner | f9b8dec | 2000-06-16 19:34:52 +0000 | [diff] [blame^] | 154 | FT_ULong table_len; |
David Turner | d2b1f35 | 1999-12-16 23:11:37 +0000 | [diff] [blame] | 155 | |
Werner Lemberg | 78575dc | 2000-06-12 19:36:41 +0000 | [diff] [blame] | 156 | |
David Turner | d2b1f35 | 1999-12-16 23:11:37 +0000 | [diff] [blame] | 157 | FT_TRACE2(( "CVT " )); |
| 158 | |
| 159 | error = face->goto_table( face, TTAG_cvt, stream, &table_len ); |
Werner Lemberg | 78575dc | 2000-06-12 19:36:41 +0000 | [diff] [blame] | 160 | if ( error ) |
David Turner | d2b1f35 | 1999-12-16 23:11:37 +0000 | [diff] [blame] | 161 | { |
| 162 | FT_TRACE2(( "is missing!\n" )); |
| 163 | |
| 164 | face->cvt_size = 0; |
| 165 | face->cvt = NULL; |
| 166 | error = TT_Err_Ok; |
| 167 | |
| 168 | goto Exit; |
| 169 | } |
| 170 | |
| 171 | face->cvt_size = table_len / 2; |
| 172 | |
| 173 | if ( ALLOC_ARRAY( face->cvt, |
| 174 | face->cvt_size, |
David Turner | f9b8dec | 2000-06-16 19:34:52 +0000 | [diff] [blame^] | 175 | FT_Short ) ) |
David Turner | d2b1f35 | 1999-12-16 23:11:37 +0000 | [diff] [blame] | 176 | goto Exit; |
| 177 | |
| 178 | if ( ACCESS_Frame( face->cvt_size * 2L ) ) |
| 179 | goto Exit; |
| 180 | |
| 181 | { |
David Turner | f9b8dec | 2000-06-16 19:34:52 +0000 | [diff] [blame^] | 182 | FT_Short* cur = face->cvt; |
| 183 | FT_Short* limit = cur + face->cvt_size; |
David Turner | d2b1f35 | 1999-12-16 23:11:37 +0000 | [diff] [blame] | 184 | |
Werner Lemberg | 78575dc | 2000-06-12 19:36:41 +0000 | [diff] [blame] | 185 | |
David Turner | d2b1f35 | 1999-12-16 23:11:37 +0000 | [diff] [blame] | 186 | for ( ; cur < limit; cur++ ) |
| 187 | *cur = GET_Short(); |
| 188 | } |
| 189 | |
| 190 | FORGET_Frame(); |
| 191 | FT_TRACE2(( "loaded\n" )); |
| 192 | |
| 193 | Exit: |
| 194 | return error; |
| 195 | } |
| 196 | |
| 197 | |
| 198 | /*************************************************************************/ |
| 199 | /* */ |
| 200 | /* <Function> */ |
| 201 | /* TT_Load_Progams */ |
| 202 | /* */ |
| 203 | /* <Description> */ |
| 204 | /* Loads the font program and the cvt program. */ |
| 205 | /* */ |
Werner Lemberg | 78575dc | 2000-06-12 19:36:41 +0000 | [diff] [blame] | 206 | /* <InOut> */ |
David Turner | d2b1f35 | 1999-12-16 23:11:37 +0000 | [diff] [blame] | 207 | /* face :: A handle to the target face object. */ |
Werner Lemberg | 78575dc | 2000-06-12 19:36:41 +0000 | [diff] [blame] | 208 | /* */ |
| 209 | /* <Input> */ |
David Turner | d2b1f35 | 1999-12-16 23:11:37 +0000 | [diff] [blame] | 210 | /* stream :: A handle to the input stream. */ |
| 211 | /* */ |
| 212 | /* <Return> */ |
| 213 | /* TrueType error code. 0 means success. */ |
| 214 | /* */ |
| 215 | LOCAL_FUNC |
David Turner | f9b8dec | 2000-06-16 19:34:52 +0000 | [diff] [blame^] | 216 | FT_Error TT_Load_Programs( TT_Face face, |
David Turner | d2b1f35 | 1999-12-16 23:11:37 +0000 | [diff] [blame] | 217 | FT_Stream stream ) |
| 218 | { |
David Turner | f9b8dec | 2000-06-16 19:34:52 +0000 | [diff] [blame^] | 219 | FT_Error error; |
| 220 | FT_ULong table_len; |
David Turner | d2b1f35 | 1999-12-16 23:11:37 +0000 | [diff] [blame] | 221 | |
Werner Lemberg | 78575dc | 2000-06-12 19:36:41 +0000 | [diff] [blame] | 222 | |
Werner Lemberg | f697866 | 2000-01-08 20:00:54 +0000 | [diff] [blame] | 223 | FT_TRACE2(( "Font program " )); |
David Turner | d2b1f35 | 1999-12-16 23:11:37 +0000 | [diff] [blame] | 224 | |
| 225 | /* The font program is optional */ |
| 226 | error = face->goto_table( face, TTAG_fpgm, stream, &table_len ); |
Werner Lemberg | f697866 | 2000-01-08 20:00:54 +0000 | [diff] [blame] | 227 | if ( error ) |
David Turner | d2b1f35 | 1999-12-16 23:11:37 +0000 | [diff] [blame] | 228 | { |
| 229 | face->font_program = NULL; |
| 230 | face->font_program_size = 0; |
Werner Lemberg | 78575dc | 2000-06-12 19:36:41 +0000 | [diff] [blame] | 231 | |
David Turner | d2b1f35 | 1999-12-16 23:11:37 +0000 | [diff] [blame] | 232 | FT_TRACE2(( "is missing!\n" )); |
| 233 | } |
| 234 | else |
| 235 | { |
| 236 | face->font_program_size = table_len; |
David Turner | 2e42131 | 2000-05-26 22:13:17 +0000 | [diff] [blame] | 237 | if ( EXTRACT_Frame( table_len, face->font_program ) ) |
David Turner | d2b1f35 | 1999-12-16 23:11:37 +0000 | [diff] [blame] | 238 | goto Exit; |
| 239 | |
| 240 | FT_TRACE2(( "loaded, %12d bytes\n", face->font_program_size )); |
| 241 | } |
| 242 | |
| 243 | FT_TRACE2(( "Prep program " )); |
| 244 | |
| 245 | error = face->goto_table( face, TTAG_prep, stream, &table_len ); |
Werner Lemberg | f697866 | 2000-01-08 20:00:54 +0000 | [diff] [blame] | 246 | if ( error ) |
David Turner | d2b1f35 | 1999-12-16 23:11:37 +0000 | [diff] [blame] | 247 | { |
| 248 | face->cvt_program = NULL; |
| 249 | face->cvt_program_size = 0; |
Werner Lemberg | f697866 | 2000-01-08 20:00:54 +0000 | [diff] [blame] | 250 | error = TT_Err_Ok; |
David Turner | d2b1f35 | 1999-12-16 23:11:37 +0000 | [diff] [blame] | 251 | |
| 252 | FT_TRACE2(( "is missing!\n" )); |
| 253 | } |
| 254 | else |
| 255 | { |
| 256 | face->cvt_program_size = table_len; |
David Turner | 2e42131 | 2000-05-26 22:13:17 +0000 | [diff] [blame] | 257 | if ( EXTRACT_Frame( table_len, face->cvt_program ) ) |
| 258 | goto Exit; |
Werner Lemberg | 78575dc | 2000-06-12 19:36:41 +0000 | [diff] [blame] | 259 | |
David Turner | d2b1f35 | 1999-12-16 23:11:37 +0000 | [diff] [blame] | 260 | FT_TRACE2(( "loaded, %12d bytes\n", face->cvt_program_size )); |
| 261 | } |
| 262 | |
| 263 | Exit: |
| 264 | return error; |
| 265 | } |
| 266 | |
| 267 | |
| 268 | /* END */ |