David Turner | d2b1f35 | 1999-12-16 23:11:37 +0000 | [diff] [blame] | 1 | /***************************************************************************/ |
| 2 | /* */ |
David Turner | 19ed8af | 2000-12-08 02:42:29 +0000 | [diff] [blame] | 3 | /* ttpload.c */ |
David Turner | d2b1f35 | 1999-12-16 23:11:37 +0000 | [diff] [blame] | 4 | /* */ |
| 5 | /* TrueType glyph data/program tables loader (body). */ |
| 6 | /* */ |
Werner Lemberg | 415235d | 2001-06-28 17:49:10 +0000 | [diff] [blame] | 7 | /* Copyright 1996-2001 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 | |
Werner Lemberg | cc069be | 2000-12-08 16:17:16 +0000 | [diff] [blame] | 18 | |
David Turner | 19ed8af | 2000-12-08 02:42:29 +0000 | [diff] [blame] | 19 | #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 Lemberg | 1f7f0e8 | 2001-06-06 17:30:41 +0000 | [diff] [blame] | 24 | |
David Turner | 8d3a401 | 2001-03-20 11:14:24 +0000 | [diff] [blame] | 25 | #include "ttpload.h" |
Werner Lemberg | 1f7f0e8 | 2001-06-06 17:30:41 +0000 | [diff] [blame] | 26 | |
| 27 | #include "tterrors.h" |
David Turner | d2b1f35 | 1999-12-16 23:11:37 +0000 | [diff] [blame] | 28 | |
Werner Lemberg | 78575dc | 2000-06-12 19:36:41 +0000 | [diff] [blame] | 29 | |
| 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 Turner | d2b1f35 | 1999-12-16 23:11:37 +0000 | [diff] [blame] | 36 | #undef FT_COMPONENT |
Werner Lemberg | 78575dc | 2000-06-12 19:36:41 +0000 | [diff] [blame] | 37 | #define FT_COMPONENT trace_ttpload |
| 38 | |
David Turner | d2b1f35 | 1999-12-16 23:11:37 +0000 | [diff] [blame] | 39 | |
| 40 | /*************************************************************************/ |
| 41 | /* */ |
| 42 | /* <Function> */ |
| 43 | /* TT_Load_Locations */ |
| 44 | /* */ |
| 45 | /* <Description> */ |
| 46 | /* Loads the locations table. */ |
| 47 | /* */ |
Werner Lemberg | 78575dc | 2000-06-12 19:36:41 +0000 | [diff] [blame] | 48 | /* <InOut> */ |
David Turner | d2b1f35 | 1999-12-16 23:11:37 +0000 | [diff] [blame] | 49 | /* face :: A handle to the target face object. */ |
Werner Lemberg | 78575dc | 2000-06-12 19:36:41 +0000 | [diff] [blame] | 50 | /* */ |
| 51 | /* <Input> */ |
David Turner | d2b1f35 | 1999-12-16 23:11:37 +0000 | [diff] [blame] | 52 | /* stream :: The input stream. */ |
| 53 | /* */ |
| 54 | /* <Return> */ |
Werner Lemberg | 9ca2af3 | 2000-06-21 03:03:28 +0000 | [diff] [blame] | 55 | /* FreeType error code. 0 means success. */ |
David Turner | d2b1f35 | 1999-12-16 23:11:37 +0000 | [diff] [blame] | 56 | /* */ |
David Turner | bc82f1b | 2002-03-01 02:26:22 +0000 | [diff] [blame] | 57 | FT_LOCAL_DEF( FT_Error ) |
Werner Lemberg | 4a2305c | 2001-06-28 07:17:51 +0000 | [diff] [blame] | 58 | TT_Load_Locations( TT_Face face, |
| 59 | FT_Stream stream ) |
David Turner | d2b1f35 | 1999-12-16 23:11:37 +0000 | [diff] [blame] | 60 | { |
David Turner | f9b8dec | 2000-06-16 19:34:52 +0000 | [diff] [blame] | 61 | FT_Error error; |
David Turner | d2b1f35 | 1999-12-16 23:11:37 +0000 | [diff] [blame] | 62 | FT_Memory memory = stream->memory; |
David Turner | f9b8dec | 2000-06-16 19:34:52 +0000 | [diff] [blame] | 63 | FT_Short LongOffsets; |
| 64 | FT_ULong table_len; |
David Turner | d2b1f35 | 1999-12-16 23:11:37 +0000 | [diff] [blame] | 65 | |
Werner Lemberg | 78575dc | 2000-06-12 19:36:41 +0000 | [diff] [blame] | 66 | |
David Turner | d2b1f35 | 1999-12-16 23:11:37 +0000 | [diff] [blame] | 67 | FT_TRACE2(( "Locations " )); |
| 68 | LongOffsets = face->header.Index_To_Loc_Format; |
| 69 | |
| 70 | error = face->goto_table( face, TTAG_loca, stream, &table_len ); |
Werner Lemberg | 78575dc | 2000-06-12 19:36:41 +0000 | [diff] [blame] | 71 | if ( error ) |
David Turner | d2b1f35 | 1999-12-16 23:11:37 +0000 | [diff] [blame] | 72 | { |
| 73 | error = TT_Err_Locations_Missing; |
| 74 | goto Exit; |
| 75 | } |
| 76 | |
| 77 | if ( LongOffsets != 0 ) |
| 78 | { |
David Turner | f9b8dec | 2000-06-16 19:34:52 +0000 | [diff] [blame] | 79 | face->num_locations = (FT_UShort)( table_len >> 2 ); |
David Turner | d2b1f35 | 1999-12-16 23:11:37 +0000 | [diff] [blame] | 80 | |
Werner Lemberg | 78575dc | 2000-06-12 19:36:41 +0000 | [diff] [blame] | 81 | FT_TRACE2(( "(32bit offsets): %12d ", face->num_locations )); |
David Turner | d2b1f35 | 1999-12-16 23:11:37 +0000 | [diff] [blame] | 82 | |
David Turner | e459d74 | 2002-03-22 13:52:37 +0000 | [diff] [blame^] | 83 | if ( FT_NEW_ARRAY( face->glyph_locations, face->num_locations ) ) |
David Turner | d2b1f35 | 1999-12-16 23:11:37 +0000 | [diff] [blame] | 84 | goto Exit; |
| 85 | |
David Turner | 7d3a264 | 2002-03-20 10:49:31 +0000 | [diff] [blame] | 86 | if ( FT_FRAME_ENTER( face->num_locations * 4L ) ) |
David Turner | d2b1f35 | 1999-12-16 23:11:37 +0000 | [diff] [blame] | 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++ ) |
David Turner | a890c29 | 2002-03-22 12:55:23 +0000 | [diff] [blame] | 95 | *loc = FT_GET_LONG(); |
David Turner | d2b1f35 | 1999-12-16 23:11:37 +0000 | [diff] [blame] | 96 | } |
| 97 | |
David Turner | 7d3a264 | 2002-03-20 10:49:31 +0000 | [diff] [blame] | 98 | FT_FRAME_EXIT(); |
David Turner | d2b1f35 | 1999-12-16 23:11:37 +0000 | [diff] [blame] | 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 | |
David Turner | e459d74 | 2002-03-22 13:52:37 +0000 | [diff] [blame^] | 106 | if ( FT_NEW_ARRAY( face->glyph_locations, face->num_locations ) ) |
David Turner | d2b1f35 | 1999-12-16 23:11:37 +0000 | [diff] [blame] | 107 | goto Exit; |
| 108 | |
David Turner | 7d3a264 | 2002-03-20 10:49:31 +0000 | [diff] [blame] | 109 | if ( FT_FRAME_ENTER( face->num_locations * 2L ) ) |
David Turner | d2b1f35 | 1999-12-16 23:11:37 +0000 | [diff] [blame] | 110 | goto Exit; |
| 111 | { |
David Turner | f9b8dec | 2000-06-16 19:34:52 +0000 | [diff] [blame] | 112 | FT_Long* loc = face->glyph_locations; |
| 113 | FT_Long* limit = loc + face->num_locations; |
David Turner | d2b1f35 | 1999-12-16 23:11:37 +0000 | [diff] [blame] | 114 | |
Werner Lemberg | 78575dc | 2000-06-12 19:36:41 +0000 | [diff] [blame] | 115 | |
David Turner | d2b1f35 | 1999-12-16 23:11:37 +0000 | [diff] [blame] | 116 | for ( ; loc < limit; loc++ ) |
David Turner | a890c29 | 2002-03-22 12:55:23 +0000 | [diff] [blame] | 117 | *loc = (FT_Long)( (FT_ULong)FT_GET_USHORT() * 2 ); |
David Turner | d2b1f35 | 1999-12-16 23:11:37 +0000 | [diff] [blame] | 118 | } |
David Turner | 7d3a264 | 2002-03-20 10:49:31 +0000 | [diff] [blame] | 119 | FT_FRAME_EXIT(); |
David Turner | d2b1f35 | 1999-12-16 23:11:37 +0000 | [diff] [blame] | 120 | } |
| 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 Lemberg | 78575dc | 2000-06-12 19:36:41 +0000 | [diff] [blame] | 137 | /* <InOut> */ |
David Turner | d2b1f35 | 1999-12-16 23:11:37 +0000 | [diff] [blame] | 138 | /* face :: A handle to the target face object. */ |
Werner Lemberg | 78575dc | 2000-06-12 19:36:41 +0000 | [diff] [blame] | 139 | /* */ |
| 140 | /* <Input> */ |
David Turner | d2b1f35 | 1999-12-16 23:11:37 +0000 | [diff] [blame] | 141 | /* stream :: A handle to the input stream. */ |
| 142 | /* */ |
| 143 | /* <Return> */ |
Werner Lemberg | 9ca2af3 | 2000-06-21 03:03:28 +0000 | [diff] [blame] | 144 | /* FreeType error code. 0 means success. */ |
David Turner | d2b1f35 | 1999-12-16 23:11:37 +0000 | [diff] [blame] | 145 | /* */ |
David Turner | bc82f1b | 2002-03-01 02:26:22 +0000 | [diff] [blame] | 146 | FT_LOCAL_DEF( FT_Error ) |
Werner Lemberg | 4a2305c | 2001-06-28 07:17:51 +0000 | [diff] [blame] | 147 | TT_Load_CVT( TT_Face face, |
| 148 | FT_Stream stream ) |
David Turner | d2b1f35 | 1999-12-16 23:11:37 +0000 | [diff] [blame] | 149 | { |
David Turner | f9b8dec | 2000-06-16 19:34:52 +0000 | [diff] [blame] | 150 | FT_Error error; |
David Turner | d2b1f35 | 1999-12-16 23:11:37 +0000 | [diff] [blame] | 151 | FT_Memory memory = stream->memory; |
David Turner | f9b8dec | 2000-06-16 19:34:52 +0000 | [diff] [blame] | 152 | FT_ULong table_len; |
David Turner | d2b1f35 | 1999-12-16 23:11:37 +0000 | [diff] [blame] | 153 | |
Werner Lemberg | 78575dc | 2000-06-12 19:36:41 +0000 | [diff] [blame] | 154 | |
David Turner | d2b1f35 | 1999-12-16 23:11:37 +0000 | [diff] [blame] | 155 | FT_TRACE2(( "CVT " )); |
| 156 | |
| 157 | error = face->goto_table( face, TTAG_cvt, stream, &table_len ); |
Werner Lemberg | 78575dc | 2000-06-12 19:36:41 +0000 | [diff] [blame] | 158 | if ( error ) |
David Turner | d2b1f35 | 1999-12-16 23:11:37 +0000 | [diff] [blame] | 159 | { |
| 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 Turner | e459d74 | 2002-03-22 13:52:37 +0000 | [diff] [blame^] | 171 | if ( FT_NEW_ARRAY( face->cvt, face->cvt_size ) ) |
David Turner | d2b1f35 | 1999-12-16 23:11:37 +0000 | [diff] [blame] | 172 | goto Exit; |
| 173 | |
David Turner | 7d3a264 | 2002-03-20 10:49:31 +0000 | [diff] [blame] | 174 | if ( FT_FRAME_ENTER( face->cvt_size * 2L ) ) |
David Turner | d2b1f35 | 1999-12-16 23:11:37 +0000 | [diff] [blame] | 175 | goto Exit; |
| 176 | |
| 177 | { |
David Turner | f9b8dec | 2000-06-16 19:34:52 +0000 | [diff] [blame] | 178 | FT_Short* cur = face->cvt; |
| 179 | FT_Short* limit = cur + face->cvt_size; |
David Turner | d2b1f35 | 1999-12-16 23:11:37 +0000 | [diff] [blame] | 180 | |
Werner Lemberg | 78575dc | 2000-06-12 19:36:41 +0000 | [diff] [blame] | 181 | |
David Turner | d2b1f35 | 1999-12-16 23:11:37 +0000 | [diff] [blame] | 182 | for ( ; cur < limit; cur++ ) |
David Turner | a890c29 | 2002-03-22 12:55:23 +0000 | [diff] [blame] | 183 | *cur = FT_GET_SHORT(); |
David Turner | d2b1f35 | 1999-12-16 23:11:37 +0000 | [diff] [blame] | 184 | } |
| 185 | |
David Turner | 7d3a264 | 2002-03-20 10:49:31 +0000 | [diff] [blame] | 186 | FT_FRAME_EXIT(); |
David Turner | d2b1f35 | 1999-12-16 23:11:37 +0000 | [diff] [blame] | 187 | 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 Lemberg | 78575dc | 2000-06-12 19:36:41 +0000 | [diff] [blame] | 202 | /* <InOut> */ |
David Turner | d2b1f35 | 1999-12-16 23:11:37 +0000 | [diff] [blame] | 203 | /* face :: A handle to the target face object. */ |
Werner Lemberg | 78575dc | 2000-06-12 19:36:41 +0000 | [diff] [blame] | 204 | /* */ |
| 205 | /* <Input> */ |
David Turner | d2b1f35 | 1999-12-16 23:11:37 +0000 | [diff] [blame] | 206 | /* stream :: A handle to the input stream. */ |
| 207 | /* */ |
| 208 | /* <Return> */ |
Werner Lemberg | 9ca2af3 | 2000-06-21 03:03:28 +0000 | [diff] [blame] | 209 | /* FreeType error code. 0 means success. */ |
David Turner | d2b1f35 | 1999-12-16 23:11:37 +0000 | [diff] [blame] | 210 | /* */ |
David Turner | bc82f1b | 2002-03-01 02:26:22 +0000 | [diff] [blame] | 211 | FT_LOCAL_DEF( FT_Error ) |
Werner Lemberg | 4a2305c | 2001-06-28 07:17:51 +0000 | [diff] [blame] | 212 | TT_Load_Programs( TT_Face face, |
| 213 | FT_Stream stream ) |
David Turner | d2b1f35 | 1999-12-16 23:11:37 +0000 | [diff] [blame] | 214 | { |
David Turner | f9b8dec | 2000-06-16 19:34:52 +0000 | [diff] [blame] | 215 | FT_Error error; |
| 216 | FT_ULong table_len; |
David Turner | d2b1f35 | 1999-12-16 23:11:37 +0000 | [diff] [blame] | 217 | |
Werner Lemberg | 78575dc | 2000-06-12 19:36:41 +0000 | [diff] [blame] | 218 | |
Werner Lemberg | f697866 | 2000-01-08 20:00:54 +0000 | [diff] [blame] | 219 | FT_TRACE2(( "Font program " )); |
David Turner | d2b1f35 | 1999-12-16 23:11:37 +0000 | [diff] [blame] | 220 | |
| 221 | /* The font program is optional */ |
| 222 | error = face->goto_table( face, TTAG_fpgm, stream, &table_len ); |
Werner Lemberg | f697866 | 2000-01-08 20:00:54 +0000 | [diff] [blame] | 223 | if ( error ) |
David Turner | d2b1f35 | 1999-12-16 23:11:37 +0000 | [diff] [blame] | 224 | { |
| 225 | face->font_program = NULL; |
| 226 | face->font_program_size = 0; |
Werner Lemberg | 78575dc | 2000-06-12 19:36:41 +0000 | [diff] [blame] | 227 | |
David Turner | d2b1f35 | 1999-12-16 23:11:37 +0000 | [diff] [blame] | 228 | FT_TRACE2(( "is missing!\n" )); |
| 229 | } |
| 230 | else |
| 231 | { |
| 232 | face->font_program_size = table_len; |
David Turner | 7d3a264 | 2002-03-20 10:49:31 +0000 | [diff] [blame] | 233 | if ( FT_FRAME_EXTRACT( table_len, face->font_program ) ) |
David Turner | d2b1f35 | 1999-12-16 23:11:37 +0000 | [diff] [blame] | 234 | 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 Lemberg | f697866 | 2000-01-08 20:00:54 +0000 | [diff] [blame] | 242 | if ( error ) |
David Turner | d2b1f35 | 1999-12-16 23:11:37 +0000 | [diff] [blame] | 243 | { |
| 244 | face->cvt_program = NULL; |
| 245 | face->cvt_program_size = 0; |
Werner Lemberg | f697866 | 2000-01-08 20:00:54 +0000 | [diff] [blame] | 246 | error = TT_Err_Ok; |
David Turner | d2b1f35 | 1999-12-16 23:11:37 +0000 | [diff] [blame] | 247 | |
| 248 | FT_TRACE2(( "is missing!\n" )); |
| 249 | } |
| 250 | else |
| 251 | { |
| 252 | face->cvt_program_size = table_len; |
David Turner | 7d3a264 | 2002-03-20 10:49:31 +0000 | [diff] [blame] | 253 | if ( FT_FRAME_EXTRACT( table_len, face->cvt_program ) ) |
David Turner | 2e42131 | 2000-05-26 22:13:17 +0000 | [diff] [blame] | 254 | goto Exit; |
Werner Lemberg | 78575dc | 2000-06-12 19:36:41 +0000 | [diff] [blame] | 255 | |
David Turner | d2b1f35 | 1999-12-16 23:11:37 +0000 | [diff] [blame] | 256 | FT_TRACE2(( "loaded, %12d bytes\n", face->cvt_program_size )); |
| 257 | } |
| 258 | |
| 259 | Exit: |
| 260 | return error; |
| 261 | } |
| 262 | |
| 263 | |
| 264 | /* END */ |