Werner Lemberg | 7fa51b5 | 2000-07-08 19:51:42 +0000 | [diff] [blame] | 1 | /***************************************************************************/ |
| 2 | /* */ |
Werner Lemberg | b5084e1 | 2000-10-28 17:10:06 +0000 | [diff] [blame] | 3 | /* t1gload.c */ |
Werner Lemberg | 7fa51b5 | 2000-07-08 19:51:42 +0000 | [diff] [blame] | 4 | /* */ |
Werner Lemberg | b5084e1 | 2000-10-28 17:10:06 +0000 | [diff] [blame] | 5 | /* Type 1 Glyph Loader (body). */ |
Werner Lemberg | 7fa51b5 | 2000-07-08 19:51:42 +0000 | [diff] [blame] | 6 | /* */ |
Werner Lemberg | b442ca1 | 2003-04-23 15:50:27 +0000 | [diff] [blame] | 7 | /* Copyright 1996-2001, 2002, 2003 by */ |
Werner Lemberg | 7fa51b5 | 2000-07-08 19:51:42 +0000 | [diff] [blame] | 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 | |
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> |
David Turner | 8d3a401 | 2001-03-20 11:14:24 +0000 | [diff] [blame] | 20 | #include "t1gload.h" |
David Turner | 19ed8af | 2000-12-08 02:42:29 +0000 | [diff] [blame] | 21 | #include FT_INTERNAL_DEBUG_H |
| 22 | #include FT_INTERNAL_STREAM_H |
| 23 | #include FT_OUTLINE_H |
| 24 | #include FT_INTERNAL_POSTSCRIPT_AUX_H |
Werner Lemberg | cc069be | 2000-12-08 16:17:16 +0000 | [diff] [blame] | 25 | |
Werner Lemberg | 1f7f0e8 | 2001-06-06 17:30:41 +0000 | [diff] [blame] | 26 | #include "t1errors.h" |
| 27 | |
Werner Lemberg | 7fa51b5 | 2000-07-08 19:51:42 +0000 | [diff] [blame] | 28 | |
| 29 | /*************************************************************************/ |
| 30 | /* */ |
| 31 | /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ |
| 32 | /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ |
| 33 | /* messages during execution. */ |
| 34 | /* */ |
| 35 | #undef FT_COMPONENT |
Werner Lemberg | b5084e1 | 2000-10-28 17:10:06 +0000 | [diff] [blame] | 36 | #define FT_COMPONENT trace_t1gload |
Werner Lemberg | 7fa51b5 | 2000-07-08 19:51:42 +0000 | [diff] [blame] | 37 | |
| 38 | |
Werner Lemberg | 7fa51b5 | 2000-07-08 19:51:42 +0000 | [diff] [blame] | 39 | /*************************************************************************/ |
| 40 | /*************************************************************************/ |
| 41 | /*************************************************************************/ |
| 42 | /********** *********/ |
| 43 | /********** COMPUTE THE MAXIMUM ADVANCE WIDTH *********/ |
| 44 | /********** *********/ |
| 45 | /********** The following code is in charge of computing *********/ |
| 46 | /********** the maximum advance width of the font. It *********/ |
| 47 | /********** quickly processes each glyph charstring to *********/ |
| 48 | /********** extract the value from either a `sbw' or `seac' *********/ |
| 49 | /********** operator. *********/ |
| 50 | /********** *********/ |
| 51 | /*************************************************************************/ |
| 52 | /*************************************************************************/ |
| 53 | /*************************************************************************/ |
David Turner | 2dfb5ac | 2000-01-27 14:02:04 +0000 | [diff] [blame] | 54 | |
David Turner | 2dfb5ac | 2000-01-27 14:02:04 +0000 | [diff] [blame] | 55 | |
Werner Lemberg | 7f74a52 | 2002-07-26 09:09:10 +0000 | [diff] [blame] | 56 | FT_LOCAL_DEF( FT_Error ) |
| 57 | T1_Parse_Glyph_And_Get_Char_String( T1_Decoder decoder, |
| 58 | FT_UInt glyph_index, |
| 59 | FT_Data* char_string ) |
David Turner | 9748807 | 2000-08-22 22:36:33 +0000 | [diff] [blame] | 60 | { |
Werner Lemberg | 7f74a52 | 2002-07-26 09:09:10 +0000 | [diff] [blame] | 61 | T1_Face face = (T1_Face)decoder->builder.face; |
| 62 | T1_Font type1 = &face->type1; |
| 63 | FT_Error error = 0; |
| 64 | |
David Turner | 34f1c2f | 2000-08-23 22:47:44 +0000 | [diff] [blame] | 65 | |
| 66 | decoder->font_matrix = type1->font_matrix; |
| 67 | decoder->font_offset = type1->font_offset; |
Werner Lemberg | 8728f29 | 2000-08-23 17:32:42 +0000 | [diff] [blame] | 68 | |
Graham Asher | bd8b085 | 2002-07-18 16:57:43 +0000 | [diff] [blame] | 69 | #ifdef FT_CONFIG_OPTION_INCREMENTAL |
Werner Lemberg | 7f74a52 | 2002-07-26 09:09:10 +0000 | [diff] [blame] | 70 | |
| 71 | /* For incremental fonts get the character data using the */ |
| 72 | /* callback function. */ |
Graham Asher | ce12182 | 2002-08-01 15:29:17 +0000 | [diff] [blame] | 73 | if ( face->root.internal->incremental_interface ) |
| 74 | error = face->root.internal->incremental_interface->funcs->get_glyph_data( |
| 75 | face->root.internal->incremental_interface->object, |
Werner Lemberg | 7f74a52 | 2002-07-26 09:09:10 +0000 | [diff] [blame] | 76 | glyph_index, char_string ); |
Graham Asher | bd8b085 | 2002-07-18 16:57:43 +0000 | [diff] [blame] | 77 | else |
Werner Lemberg | 7f74a52 | 2002-07-26 09:09:10 +0000 | [diff] [blame] | 78 | |
Graham Asher | 46960df | 2003-02-13 17:49:27 +0000 | [diff] [blame] | 79 | #endif /* FT_CONFIG_OPTION_INCREMENTAL */ |
Graham Asher | bd8b085 | 2002-07-18 16:57:43 +0000 | [diff] [blame] | 80 | |
| 81 | /* For ordinary fonts get the character data stored in the face record. */ |
| 82 | { |
| 83 | char_string->pointer = type1->charstrings[glyph_index]; |
Werner Lemberg | fb4bfdd | 2003-12-13 18:42:31 +0000 | [diff] [blame] | 84 | char_string->length = (FT_Int)type1->charstrings_len[glyph_index]; |
Graham Asher | bd8b085 | 2002-07-18 16:57:43 +0000 | [diff] [blame] | 85 | } |
| 86 | |
Werner Lemberg | 7f74a52 | 2002-07-26 09:09:10 +0000 | [diff] [blame] | 87 | if ( !error ) |
| 88 | error = decoder->funcs.parse_charstrings( |
| 89 | decoder, (FT_Byte*)char_string->pointer, |
| 90 | char_string->length ); |
Graham Asher | bd8b085 | 2002-07-18 16:57:43 +0000 | [diff] [blame] | 91 | |
| 92 | #ifdef FT_CONFIG_OPTION_INCREMENTAL |
Werner Lemberg | 7f74a52 | 2002-07-26 09:09:10 +0000 | [diff] [blame] | 93 | |
Graham Asher | bd8b085 | 2002-07-18 16:57:43 +0000 | [diff] [blame] | 94 | /* Incremental fonts can optionally override the metrics. */ |
Graham Asher | ce12182 | 2002-08-01 15:29:17 +0000 | [diff] [blame] | 95 | if ( !error && face->root.internal->incremental_interface && |
| 96 | face->root.internal->incremental_interface->funcs->get_glyph_metrics ) |
Graham Asher | bd8b085 | 2002-07-18 16:57:43 +0000 | [diff] [blame] | 97 | { |
Graham Asher | ce12182 | 2002-08-01 15:29:17 +0000 | [diff] [blame] | 98 | FT_Incremental_MetricsRec metrics; |
Werner Lemberg | 7f74a52 | 2002-07-26 09:09:10 +0000 | [diff] [blame] | 99 | |
Werner Lemberg | fb4bfdd | 2003-12-13 18:42:31 +0000 | [diff] [blame] | 100 | |
Graham Asher | 46960df | 2003-02-13 17:49:27 +0000 | [diff] [blame] | 101 | metrics.bearing_x = decoder->builder.left_bearing.x; |
Werner Lemberg | b442ca1 | 2003-04-23 15:50:27 +0000 | [diff] [blame] | 102 | metrics.bearing_y = decoder->builder.left_bearing.y; |
| 103 | metrics.advance = decoder->builder.advance.x; |
Graham Asher | ce12182 | 2002-08-01 15:29:17 +0000 | [diff] [blame] | 104 | error = face->root.internal->incremental_interface->funcs->get_glyph_metrics( |
| 105 | face->root.internal->incremental_interface->object, |
Graham Asher | 46960df | 2003-02-13 17:49:27 +0000 | [diff] [blame] | 106 | glyph_index, FALSE, &metrics ); |
| 107 | decoder->builder.left_bearing.x = metrics.bearing_x; |
| 108 | decoder->builder.left_bearing.y = metrics.bearing_y; |
| 109 | decoder->builder.advance.x = metrics.advance; |
| 110 | decoder->builder.advance.y = 0; |
Graham Asher | bd8b085 | 2002-07-18 16:57:43 +0000 | [diff] [blame] | 111 | } |
Werner Lemberg | 7f74a52 | 2002-07-26 09:09:10 +0000 | [diff] [blame] | 112 | |
Graham Asher | 46960df | 2003-02-13 17:49:27 +0000 | [diff] [blame] | 113 | #endif /* FT_CONFIG_OPTION_INCREMENTAL */ |
Graham Asher | bd8b085 | 2002-07-18 16:57:43 +0000 | [diff] [blame] | 114 | |
Werner Lemberg | fb4bfdd | 2003-12-13 18:42:31 +0000 | [diff] [blame] | 115 | return error; |
Graham Asher | bd8b085 | 2002-07-18 16:57:43 +0000 | [diff] [blame] | 116 | } |
| 117 | |
| 118 | |
| 119 | FT_CALLBACK_DEF( FT_Error ) |
| 120 | T1_Parse_Glyph( T1_Decoder decoder, |
| 121 | FT_UInt glyph_index ) |
| 122 | { |
Werner Lemberg | 3c403e4 | 2002-08-06 21:47:40 +0000 | [diff] [blame] | 123 | FT_Data glyph_data; |
David Turner | 87c0d30 | 2003-12-24 01:10:46 +0000 | [diff] [blame] | 124 | FT_Error error = T1_Parse_Glyph_And_Get_Char_String( |
Werner Lemberg | 3c403e4 | 2002-08-06 21:47:40 +0000 | [diff] [blame] | 125 | decoder, glyph_index, &glyph_data ); |
| 126 | |
Graham Asher | ce12182 | 2002-08-01 15:29:17 +0000 | [diff] [blame] | 127 | |
| 128 | #ifdef FT_CONFIG_OPTION_INCREMENTAL |
Werner Lemberg | fb4bfdd | 2003-12-13 18:42:31 +0000 | [diff] [blame] | 129 | |
Werner Lemberg | 3c403e4 | 2002-08-06 21:47:40 +0000 | [diff] [blame] | 130 | if ( !error ) |
Graham Asher | ce12182 | 2002-08-01 15:29:17 +0000 | [diff] [blame] | 131 | { |
Werner Lemberg | 3c403e4 | 2002-08-06 21:47:40 +0000 | [diff] [blame] | 132 | T1_Face face = (T1_Face)decoder->builder.face; |
Werner Lemberg | 7f74a52 | 2002-07-26 09:09:10 +0000 | [diff] [blame] | 133 | |
| 134 | |
Werner Lemberg | b442ca1 | 2003-04-23 15:50:27 +0000 | [diff] [blame] | 135 | if ( face->root.internal->incremental_interface ) |
Werner Lemberg | 3c403e4 | 2002-08-06 21:47:40 +0000 | [diff] [blame] | 136 | face->root.internal->incremental_interface->funcs->free_glyph_data( |
| 137 | face->root.internal->incremental_interface->object, |
| 138 | &glyph_data ); |
Graham Asher | ce12182 | 2002-08-01 15:29:17 +0000 | [diff] [blame] | 139 | } |
Werner Lemberg | fb4bfdd | 2003-12-13 18:42:31 +0000 | [diff] [blame] | 140 | |
Graham Asher | 46960df | 2003-02-13 17:49:27 +0000 | [diff] [blame] | 141 | #endif /* FT_CONFIG_OPTION_INCREMENTAL */ |
Graham Asher | ce12182 | 2002-08-01 15:29:17 +0000 | [diff] [blame] | 142 | |
| 143 | return error; |
David Turner | 9748807 | 2000-08-22 22:36:33 +0000 | [diff] [blame] | 144 | } |
| 145 | |
Werner Lemberg | 8728f29 | 2000-08-23 17:32:42 +0000 | [diff] [blame] | 146 | |
David Turner | bc82f1b | 2002-03-01 02:26:22 +0000 | [diff] [blame] | 147 | FT_LOCAL_DEF( FT_Error ) |
Werner Lemberg | 4a2305c | 2001-06-28 07:17:51 +0000 | [diff] [blame] | 148 | T1_Compute_Max_Advance( T1_Face face, |
Werner Lemberg | 7386197 | 2003-06-05 04:31:05 +0000 | [diff] [blame] | 149 | FT_Pos* max_advance ) |
David Turner | 2dfb5ac | 2000-01-27 14:02:04 +0000 | [diff] [blame] | 150 | { |
Werner Lemberg | efa9961 | 2002-04-01 22:01:46 +0000 | [diff] [blame] | 151 | FT_Error error; |
| 152 | T1_DecoderRec decoder; |
| 153 | FT_Int glyph_index; |
| 154 | T1_Font type1 = &face->type1; |
David Turner | 4e7eeee | 2002-02-28 16:10:29 +0000 | [diff] [blame] | 155 | PSAux_Service psaux = (PSAux_Service)face->psaux; |
David Turner | 2dfb5ac | 2000-01-27 14:02:04 +0000 | [diff] [blame] | 156 | |
Werner Lemberg | 7fa51b5 | 2000-07-08 19:51:42 +0000 | [diff] [blame] | 157 | |
David Turner | 2dfb5ac | 2000-01-27 14:02:04 +0000 | [diff] [blame] | 158 | *max_advance = 0; |
| 159 | |
Werner Lemberg | 8728f29 | 2000-08-23 17:32:42 +0000 | [diff] [blame] | 160 | /* initialize load decoder */ |
David Turner | 9748807 | 2000-08-22 22:36:33 +0000 | [diff] [blame] | 161 | error = psaux->t1_decoder_funcs->init( &decoder, |
| 162 | (FT_Face)face, |
| 163 | 0, /* size */ |
| 164 | 0, /* glyph slot */ |
| 165 | (FT_Byte**)type1->glyph_names, |
| 166 | face->blend, |
David Turner | 5893c1b | 2001-10-18 11:49:26 +0000 | [diff] [blame] | 167 | 0, |
Werner Lemberg | 6b5c669 | 2002-09-05 15:10:54 +0000 | [diff] [blame] | 168 | FT_RENDER_MODE_NORMAL, |
Werner Lemberg | b5084e1 | 2000-10-28 17:10:06 +0000 | [diff] [blame] | 169 | T1_Parse_Glyph ); |
Werner Lemberg | d1b7475 | 2000-08-24 16:29:15 +0000 | [diff] [blame] | 170 | if ( error ) |
David Turner | 34f1c2f | 2000-08-23 22:47:44 +0000 | [diff] [blame] | 171 | return error; |
Werner Lemberg | e4b32a5 | 2000-10-31 20:42:18 +0000 | [diff] [blame] | 172 | |
David Turner | 0dd3434 | 2000-02-02 12:20:53 +0000 | [diff] [blame] | 173 | decoder.builder.metrics_only = 1; |
| 174 | decoder.builder.load_points = 0; |
David Turner | 2dfb5ac | 2000-01-27 14:02:04 +0000 | [diff] [blame] | 175 | |
David Turner | 9748807 | 2000-08-22 22:36:33 +0000 | [diff] [blame] | 176 | decoder.num_subrs = type1->num_subrs; |
| 177 | decoder.subrs = type1->subrs; |
| 178 | decoder.subrs_len = type1->subrs_len; |
| 179 | |
David Turner | 11cfdd0 | 2002-04-17 09:37:59 +0000 | [diff] [blame] | 180 | *max_advance = 0; |
| 181 | |
Werner Lemberg | 7fa51b5 | 2000-07-08 19:51:42 +0000 | [diff] [blame] | 182 | /* for each glyph, parse the glyph charstring and extract */ |
| 183 | /* the advance width */ |
David Turner | 2dfb5ac | 2000-01-27 14:02:04 +0000 | [diff] [blame] | 184 | for ( glyph_index = 0; glyph_index < type1->num_glyphs; glyph_index++ ) |
| 185 | { |
| 186 | /* now get load the unscaled outline */ |
Werner Lemberg | b5084e1 | 2000-10-28 17:10:06 +0000 | [diff] [blame] | 187 | error = T1_Parse_Glyph( &decoder, glyph_index ); |
David Turner | 11cfdd0 | 2002-04-17 09:37:59 +0000 | [diff] [blame] | 188 | if ( glyph_index == 0 || decoder.builder.advance.x > *max_advance ) |
| 189 | *max_advance = decoder.builder.advance.x; |
David Turner | 87c0d30 | 2003-12-24 01:10:46 +0000 | [diff] [blame] | 190 | |
Werner Lemberg | 7386197 | 2003-06-05 04:31:05 +0000 | [diff] [blame] | 191 | /* ignore the error if one occurred - skip to next glyph */ |
David Turner | 2dfb5ac | 2000-01-27 14:02:04 +0000 | [diff] [blame] | 192 | } |
| 193 | |
Werner Lemberg | 1429db6 | 2001-04-02 23:54:01 +0000 | [diff] [blame] | 194 | return T1_Err_Ok; |
David Turner | 2dfb5ac | 2000-01-27 14:02:04 +0000 | [diff] [blame] | 195 | } |
| 196 | |
| 197 | |
Werner Lemberg | 7fa51b5 | 2000-07-08 19:51:42 +0000 | [diff] [blame] | 198 | /*************************************************************************/ |
| 199 | /*************************************************************************/ |
| 200 | /*************************************************************************/ |
| 201 | /********** *********/ |
| 202 | /********** UNHINTED GLYPH LOADER *********/ |
| 203 | /********** *********/ |
| 204 | /********** The following code is in charge of loading a *********/ |
| 205 | /********** single outline. It completely ignores hinting *********/ |
| 206 | /********** and is used when FT_LOAD_NO_HINTING is set. *********/ |
| 207 | /********** *********/ |
| 208 | /********** The Type 1 hinter is located in `t1hint.c' *********/ |
| 209 | /********** *********/ |
| 210 | /*************************************************************************/ |
| 211 | /*************************************************************************/ |
| 212 | /*************************************************************************/ |
David Turner | 2dfb5ac | 2000-01-27 14:02:04 +0000 | [diff] [blame] | 213 | |
| 214 | |
David Turner | bc82f1b | 2002-03-01 02:26:22 +0000 | [diff] [blame] | 215 | FT_LOCAL_DEF( FT_Error ) |
Werner Lemberg | 4a2305c | 2001-06-28 07:17:51 +0000 | [diff] [blame] | 216 | T1_Load_Glyph( T1_GlyphSlot glyph, |
| 217 | T1_Size size, |
David Turner | 609e28c | 2002-04-19 15:13:47 +0000 | [diff] [blame] | 218 | FT_UInt glyph_index, |
David Turner | d1245c0 | 2002-08-27 22:34:20 +0000 | [diff] [blame] | 219 | FT_Int32 load_flags ) |
David Turner | 2dfb5ac | 2000-01-27 14:02:04 +0000 | [diff] [blame] | 220 | { |
David Turner | 9748807 | 2000-08-22 22:36:33 +0000 | [diff] [blame] | 221 | FT_Error error; |
David Turner | 4e7eeee | 2002-02-28 16:10:29 +0000 | [diff] [blame] | 222 | T1_DecoderRec decoder; |
David Turner | 9748807 | 2000-08-22 22:36:33 +0000 | [diff] [blame] | 223 | T1_Face face = (T1_Face)glyph->root.face; |
| 224 | FT_Bool hinting; |
Werner Lemberg | efa9961 | 2002-04-01 22:01:46 +0000 | [diff] [blame] | 225 | T1_Font type1 = &face->type1; |
David Turner | 4e7eeee | 2002-02-28 16:10:29 +0000 | [diff] [blame] | 226 | PSAux_Service psaux = (PSAux_Service)face->psaux; |
| 227 | const T1_Decoder_Funcs decoder_funcs = psaux->t1_decoder_funcs; |
David Turner | 2dfb5ac | 2000-01-27 14:02:04 +0000 | [diff] [blame] | 228 | |
David Turner | 34f1c2f | 2000-08-23 22:47:44 +0000 | [diff] [blame] | 229 | FT_Matrix font_matrix; |
| 230 | FT_Vector font_offset; |
Graham Asher | ce12182 | 2002-08-01 15:29:17 +0000 | [diff] [blame] | 231 | FT_Data glyph_data; |
Werner Lemberg | 319c00d | 2003-04-23 19:48:24 +0000 | [diff] [blame] | 232 | #ifdef FT_CONFIG_OPTION_INCREMENTAL |
Werner Lemberg | 3c403e4 | 2002-08-06 21:47:40 +0000 | [diff] [blame] | 233 | FT_Bool glyph_data_loaded = 0; |
Werner Lemberg | 319c00d | 2003-04-23 19:48:24 +0000 | [diff] [blame] | 234 | #endif |
Werner Lemberg | 3c403e4 | 2002-08-06 21:47:40 +0000 | [diff] [blame] | 235 | |
Werner Lemberg | efa9961 | 2002-04-01 22:01:46 +0000 | [diff] [blame] | 236 | |
Werner Lemberg | 7fa51b5 | 2000-07-08 19:51:42 +0000 | [diff] [blame] | 237 | if ( load_flags & FT_LOAD_NO_RECURSE ) |
David Turner | ed7f62a | 2000-03-28 11:19:28 +0000 | [diff] [blame] | 238 | load_flags |= FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING; |
| 239 | |
David Turner | 2dfb5ac | 2000-01-27 14:02:04 +0000 | [diff] [blame] | 240 | glyph->x_scale = size->root.metrics.x_scale; |
| 241 | glyph->y_scale = size->root.metrics.y_scale; |
| 242 | |
| 243 | glyph->root.outline.n_points = 0; |
| 244 | glyph->root.outline.n_contours = 0; |
Werner Lemberg | e4b32a5 | 2000-10-31 20:42:18 +0000 | [diff] [blame] | 245 | |
David Turner | 8edbcab | 2001-06-19 08:28:24 +0000 | [diff] [blame] | 246 | hinting = FT_BOOL( ( load_flags & FT_LOAD_NO_SCALE ) == 0 && |
| 247 | ( load_flags & FT_LOAD_NO_HINTING ) == 0 ); |
David Turner | 2dfb5ac | 2000-01-27 14:02:04 +0000 | [diff] [blame] | 248 | |
David Turner | b08fe2d | 2002-08-27 20:20:29 +0000 | [diff] [blame] | 249 | glyph->root.format = FT_GLYPH_FORMAT_OUTLINE; |
David Turner | 2dfb5ac | 2000-01-27 14:02:04 +0000 | [diff] [blame] | 250 | |
David Turner | 9748807 | 2000-08-22 22:36:33 +0000 | [diff] [blame] | 251 | error = decoder_funcs->init( &decoder, |
| 252 | (FT_Face)face, |
| 253 | (FT_Size)size, |
| 254 | (FT_GlyphSlot)glyph, |
| 255 | (FT_Byte**)type1->glyph_names, |
| 256 | face->blend, |
Werner Lemberg | c3b2160 | 2001-12-05 01:22:05 +0000 | [diff] [blame] | 257 | FT_BOOL( hinting ), |
David Turner | d1245c0 | 2002-08-27 22:34:20 +0000 | [diff] [blame] | 258 | FT_LOAD_TARGET_MODE(load_flags), |
Werner Lemberg | b5084e1 | 2000-10-28 17:10:06 +0000 | [diff] [blame] | 259 | T1_Parse_Glyph ); |
Werner Lemberg | 8728f29 | 2000-08-23 17:32:42 +0000 | [diff] [blame] | 260 | if ( error ) |
David Turner | 9748807 | 2000-08-22 22:36:33 +0000 | [diff] [blame] | 261 | goto Exit; |
Werner Lemberg | e4b32a5 | 2000-10-31 20:42:18 +0000 | [diff] [blame] | 262 | |
Werner Lemberg | 8eb0353 | 2001-06-19 23:03:41 +0000 | [diff] [blame] | 263 | decoder.builder.no_recurse = FT_BOOL( |
| 264 | ( load_flags & FT_LOAD_NO_RECURSE ) != 0 ); |
Werner Lemberg | 7fa51b5 | 2000-07-08 19:51:42 +0000 | [diff] [blame] | 265 | |
David Turner | 9748807 | 2000-08-22 22:36:33 +0000 | [diff] [blame] | 266 | decoder.num_subrs = type1->num_subrs; |
| 267 | decoder.subrs = type1->subrs; |
| 268 | decoder.subrs_len = type1->subrs_len; |
Werner Lemberg | e4b32a5 | 2000-10-31 20:42:18 +0000 | [diff] [blame] | 269 | |
Werner Lemberg | 7fa51b5 | 2000-07-08 19:51:42 +0000 | [diff] [blame] | 270 | /* now load the unscaled outline */ |
Werner Lemberg | 7f74a52 | 2002-07-26 09:09:10 +0000 | [diff] [blame] | 271 | error = T1_Parse_Glyph_And_Get_Char_String( &decoder, glyph_index, |
Graham Asher | ce12182 | 2002-08-01 15:29:17 +0000 | [diff] [blame] | 272 | &glyph_data ); |
Werner Lemberg | 8728f29 | 2000-08-23 17:32:42 +0000 | [diff] [blame] | 273 | if ( error ) |
David Turner | 9748807 | 2000-08-22 22:36:33 +0000 | [diff] [blame] | 274 | goto Exit; |
Werner Lemberg | 319c00d | 2003-04-23 19:48:24 +0000 | [diff] [blame] | 275 | #ifdef FT_CONFIG_OPTION_INCREMENTAL |
Werner Lemberg | 3c403e4 | 2002-08-06 21:47:40 +0000 | [diff] [blame] | 276 | glyph_data_loaded = 1; |
Werner Lemberg | 319c00d | 2003-04-23 19:48:24 +0000 | [diff] [blame] | 277 | #endif |
Werner Lemberg | 7fa51b5 | 2000-07-08 19:51:42 +0000 | [diff] [blame] | 278 | |
David Turner | 34f1c2f | 2000-08-23 22:47:44 +0000 | [diff] [blame] | 279 | font_matrix = decoder.font_matrix; |
| 280 | font_offset = decoder.font_offset; |
| 281 | |
Werner Lemberg | 7fa51b5 | 2000-07-08 19:51:42 +0000 | [diff] [blame] | 282 | /* save new glyph tables */ |
David Turner | 9748807 | 2000-08-22 22:36:33 +0000 | [diff] [blame] | 283 | decoder_funcs->done( &decoder ); |
Werner Lemberg | 7fa51b5 | 2000-07-08 19:51:42 +0000 | [diff] [blame] | 284 | |
| 285 | /* now, set the metrics -- this is rather simple, as */ |
| 286 | /* the left side bearing is the xMin, and the top side */ |
| 287 | /* bearing the yMax */ |
| 288 | if ( !error ) |
David Turner | 2dfb5ac | 2000-01-27 14:02:04 +0000 | [diff] [blame] | 289 | { |
David Turner | b08fe2d | 2002-08-27 20:20:29 +0000 | [diff] [blame] | 290 | glyph->root.outline.flags &= FT_OUTLINE_OWNER; |
| 291 | glyph->root.outline.flags |= FT_OUTLINE_REVERSE_FILL; |
Werner Lemberg | e4b32a5 | 2000-10-31 20:42:18 +0000 | [diff] [blame] | 292 | |
Werner Lemberg | 7fa51b5 | 2000-07-08 19:51:42 +0000 | [diff] [blame] | 293 | /* for composite glyphs, return only left side bearing and */ |
| 294 | /* advance width */ |
David Turner | ed7f62a | 2000-03-28 11:19:28 +0000 | [diff] [blame] | 295 | if ( load_flags & FT_LOAD_NO_RECURSE ) |
David Turner | 2dfb5ac | 2000-01-27 14:02:04 +0000 | [diff] [blame] | 296 | { |
David Turner | 54e7574 | 2000-11-04 02:52:02 +0000 | [diff] [blame] | 297 | FT_Slot_Internal internal = glyph->root.internal; |
Werner Lemberg | 415235d | 2001-06-28 17:49:10 +0000 | [diff] [blame] | 298 | |
| 299 | |
David Turner | ed7f62a | 2000-03-28 11:19:28 +0000 | [diff] [blame] | 300 | glyph->root.metrics.horiBearingX = decoder.builder.left_bearing.x; |
| 301 | glyph->root.metrics.horiAdvance = decoder.builder.advance.x; |
Werner Lemberg | dc72aff | 2000-11-04 08:33:38 +0000 | [diff] [blame] | 302 | internal->glyph_matrix = font_matrix; |
| 303 | internal->glyph_delta = font_offset; |
| 304 | internal->glyph_transformed = 1; |
David Turner | 2dfb5ac | 2000-01-27 14:02:04 +0000 | [diff] [blame] | 305 | } |
David Turner | ed7f62a | 2000-03-28 11:19:28 +0000 | [diff] [blame] | 306 | else |
David Turner | 2dfb5ac | 2000-01-27 14:02:04 +0000 | [diff] [blame] | 307 | { |
Werner Lemberg | 8728f29 | 2000-08-23 17:32:42 +0000 | [diff] [blame] | 308 | FT_BBox cbox; |
| 309 | FT_Glyph_Metrics* metrics = &glyph->root.metrics; |
Werner Lemberg | e8ff769 | 2003-08-06 04:40:48 +0000 | [diff] [blame] | 310 | FT_Vector advance; |
David Turner | e49ab25 | 2000-05-16 23:44:38 +0000 | [diff] [blame] | 311 | |
Werner Lemberg | 7fa51b5 | 2000-07-08 19:51:42 +0000 | [diff] [blame] | 312 | |
David Turner | ed7f62a | 2000-03-28 11:19:28 +0000 | [diff] [blame] | 313 | /* copy the _unscaled_ advance width */ |
Werner Lemberg | dc72aff | 2000-11-04 08:33:38 +0000 | [diff] [blame] | 314 | metrics->horiAdvance = decoder.builder.advance.x; |
| 315 | glyph->root.linearHoriAdvance = decoder.builder.advance.x; |
David Turner | 54e7574 | 2000-11-04 02:52:02 +0000 | [diff] [blame] | 316 | glyph->root.internal->glyph_transformed = 0; |
David Turner | e49ab25 | 2000-05-16 23:44:38 +0000 | [diff] [blame] | 317 | |
David Turner | ed7f62a | 2000-03-28 11:19:28 +0000 | [diff] [blame] | 318 | /* make up vertical metrics */ |
| 319 | metrics->vertBearingX = 0; |
| 320 | metrics->vertBearingY = 0; |
| 321 | metrics->vertAdvance = 0; |
David Turner | e49ab25 | 2000-05-16 23:44:38 +0000 | [diff] [blame] | 322 | |
David Turner | b881717 | 2000-09-15 17:17:17 +0000 | [diff] [blame] | 323 | glyph->root.linearVertAdvance = 0; |
| 324 | |
David Turner | b08fe2d | 2002-08-27 20:20:29 +0000 | [diff] [blame] | 325 | glyph->root.format = FT_GLYPH_FORMAT_OUTLINE; |
David Turner | e49ab25 | 2000-05-16 23:44:38 +0000 | [diff] [blame] | 326 | |
David Turner | d8723b4 | 2000-04-14 11:29:14 +0000 | [diff] [blame] | 327 | if ( size && size->root.metrics.y_ppem < 24 ) |
David Turner | b08fe2d | 2002-08-27 20:20:29 +0000 | [diff] [blame] | 328 | glyph->root.outline.flags |= FT_OUTLINE_HIGH_PRECISION; |
David Turner | 82942cc | 2000-03-30 08:43:03 +0000 | [diff] [blame] | 329 | |
David Turner | 85eb669 | 2001-12-20 09:36:21 +0000 | [diff] [blame] | 330 | #if 1 |
Werner Lemberg | c3b2160 | 2001-12-05 01:22:05 +0000 | [diff] [blame] | 331 | /* apply the font matrix, if any */ |
David Turner | 34f1c2f | 2000-08-23 22:47:44 +0000 | [diff] [blame] | 332 | FT_Outline_Transform( &glyph->root.outline, &font_matrix ); |
David Turner | 24d7024 | 2000-08-17 01:09:06 +0000 | [diff] [blame] | 333 | |
| 334 | FT_Outline_Translate( &glyph->root.outline, |
David Turner | 34f1c2f | 2000-08-23 22:47:44 +0000 | [diff] [blame] | 335 | font_offset.x, |
| 336 | font_offset.y ); |
Werner Lemberg | e8ff769 | 2003-08-06 04:40:48 +0000 | [diff] [blame] | 337 | |
| 338 | advance.x = metrics->horiAdvance; |
Werner Lemberg | e52c4ba | 2003-08-06 17:27:14 +0000 | [diff] [blame] | 339 | advance.y = 0; |
| 340 | FT_Vector_Transform( &advance, &font_matrix ); |
| 341 | metrics->horiAdvance = advance.x + font_offset.x; |
| 342 | advance.x = 0; |
Werner Lemberg | e8ff769 | 2003-08-06 04:40:48 +0000 | [diff] [blame] | 343 | advance.y = metrics->vertAdvance; |
| 344 | FT_Vector_Transform( &advance, &font_matrix ); |
Werner Lemberg | e52c4ba | 2003-08-06 17:27:14 +0000 | [diff] [blame] | 345 | metrics->vertAdvance = advance.y + font_offset.y; |
David Turner | 5893c1b | 2001-10-18 11:49:26 +0000 | [diff] [blame] | 346 | #endif |
David Turner | e49ab25 | 2000-05-16 23:44:38 +0000 | [diff] [blame] | 347 | |
Werner Lemberg | 7fa51b5 | 2000-07-08 19:51:42 +0000 | [diff] [blame] | 348 | if ( ( load_flags & FT_LOAD_NO_SCALE ) == 0 ) |
David Turner | ed7f62a | 2000-03-28 11:19:28 +0000 | [diff] [blame] | 349 | { |
| 350 | /* scale the outline and the metrics */ |
David Turner | f9b8dec | 2000-06-16 19:34:52 +0000 | [diff] [blame] | 351 | FT_Int n; |
David Turner | f0df85b | 2000-06-22 00:17:42 +0000 | [diff] [blame] | 352 | FT_Outline* cur = decoder.builder.base; |
David Turner | f9b8dec | 2000-06-16 19:34:52 +0000 | [diff] [blame] | 353 | FT_Vector* vec = cur->points; |
| 354 | FT_Fixed x_scale = glyph->x_scale; |
| 355 | FT_Fixed y_scale = glyph->y_scale; |
David Turner | e49ab25 | 2000-05-16 23:44:38 +0000 | [diff] [blame] | 356 | |
Werner Lemberg | 7fa51b5 | 2000-07-08 19:51:42 +0000 | [diff] [blame] | 357 | |
Werner Lemberg | c3b2160 | 2001-12-05 01:22:05 +0000 | [diff] [blame] | 358 | /* First of all, scale the points, if we are not hinting */ |
David Turner | 5893c1b | 2001-10-18 11:49:26 +0000 | [diff] [blame] | 359 | if ( !hinting ) |
| 360 | for ( n = cur->n_points; n > 0; n--, vec++ ) |
| 361 | { |
| 362 | vec->x = FT_MulFix( vec->x, x_scale ); |
| 363 | vec->y = FT_MulFix( vec->y, y_scale ); |
| 364 | } |
David Turner | d8723b4 | 2000-04-14 11:29:14 +0000 | [diff] [blame] | 365 | |
| 366 | FT_Outline_Get_CBox( &glyph->root.outline, &cbox ); |
David Turner | e49ab25 | 2000-05-16 23:44:38 +0000 | [diff] [blame] | 367 | |
David Turner | ed7f62a | 2000-03-28 11:19:28 +0000 | [diff] [blame] | 368 | /* Then scale the metrics */ |
David Turner | ed7f62a | 2000-03-28 11:19:28 +0000 | [diff] [blame] | 369 | metrics->horiAdvance = FT_MulFix( metrics->horiAdvance, x_scale ); |
Werner Lemberg | ac39ecd | 2000-06-30 22:24:36 +0000 | [diff] [blame] | 370 | metrics->vertAdvance = FT_MulFix( metrics->vertAdvance, y_scale ); |
David Turner | e49ab25 | 2000-05-16 23:44:38 +0000 | [diff] [blame] | 371 | |
David Turner | ed7f62a | 2000-03-28 11:19:28 +0000 | [diff] [blame] | 372 | metrics->vertBearingX = FT_MulFix( metrics->vertBearingX, x_scale ); |
| 373 | metrics->vertBearingY = FT_MulFix( metrics->vertBearingY, y_scale ); |
David Turner | bce2986 | 2001-12-14 14:52:58 +0000 | [diff] [blame] | 374 | |
| 375 | if ( hinting ) |
| 376 | { |
David Turner | 87c0d30 | 2003-12-24 01:10:46 +0000 | [diff] [blame] | 377 | metrics->horiAdvance = FT_PIX_ROUND( metrics->horiAdvance ); |
| 378 | metrics->vertAdvance = FT_PIX_ROUND( metrics->vertAdvance ); |
David Turner | bce2986 | 2001-12-14 14:52:58 +0000 | [diff] [blame] | 379 | |
David Turner | 87c0d30 | 2003-12-24 01:10:46 +0000 | [diff] [blame] | 380 | metrics->vertBearingX = FT_PIX_ROUND( metrics->vertBearingX ); |
| 381 | metrics->vertBearingY = FT_PIX_ROUND( metrics->vertBearingY ); |
David Turner | bce2986 | 2001-12-14 14:52:58 +0000 | [diff] [blame] | 382 | } |
David Turner | ed7f62a | 2000-03-28 11:19:28 +0000 | [diff] [blame] | 383 | } |
David Turner | d8723b4 | 2000-04-14 11:29:14 +0000 | [diff] [blame] | 384 | |
| 385 | /* compute the other metrics */ |
| 386 | FT_Outline_Get_CBox( &glyph->root.outline, &cbox ); |
David Turner | e49ab25 | 2000-05-16 23:44:38 +0000 | [diff] [blame] | 387 | |
David Turner | d8723b4 | 2000-04-14 11:29:14 +0000 | [diff] [blame] | 388 | /* grid fit the bounding box if necessary */ |
Werner Lemberg | 7fa51b5 | 2000-07-08 19:51:42 +0000 | [diff] [blame] | 389 | if ( hinting ) |
David Turner | d8723b4 | 2000-04-14 11:29:14 +0000 | [diff] [blame] | 390 | { |
David Turner | 87c0d30 | 2003-12-24 01:10:46 +0000 | [diff] [blame] | 391 | cbox.xMin = FT_PIX_FLOOR( cbox.xMin ); |
| 392 | cbox.yMin = FT_PIX_FLOOR( cbox.yMin ); |
| 393 | cbox.xMax = FT_PIX_CEIL( cbox.xMax ); |
| 394 | cbox.yMax = FT_PIX_CEIL( cbox.yMax ); |
David Turner | d8723b4 | 2000-04-14 11:29:14 +0000 | [diff] [blame] | 395 | } |
| 396 | |
| 397 | metrics->width = cbox.xMax - cbox.xMin; |
| 398 | metrics->height = cbox.yMax - cbox.yMin; |
| 399 | |
| 400 | metrics->horiBearingX = cbox.xMin; |
| 401 | metrics->horiBearingY = cbox.yMax; |
David Turner | 2dfb5ac | 2000-01-27 14:02:04 +0000 | [diff] [blame] | 402 | } |
Werner Lemberg | 415235d | 2001-06-28 17:49:10 +0000 | [diff] [blame] | 403 | |
Werner Lemberg | e274cfd | 2001-03-04 21:53:08 +0000 | [diff] [blame] | 404 | /* Set control data to the glyph charstrings. Note that this is */ |
| 405 | /* _not_ zero-terminated. */ |
Graham Asher | ce12182 | 2002-08-01 15:29:17 +0000 | [diff] [blame] | 406 | glyph->root.control_data = (FT_Byte*)glyph_data.pointer; |
| 407 | glyph->root.control_len = glyph_data.length; |
David Turner | 2dfb5ac | 2000-01-27 14:02:04 +0000 | [diff] [blame] | 408 | } |
Werner Lemberg | 8728f29 | 2000-08-23 17:32:42 +0000 | [diff] [blame] | 409 | |
Graham Asher | ce12182 | 2002-08-01 15:29:17 +0000 | [diff] [blame] | 410 | |
David Turner | 9748807 | 2000-08-22 22:36:33 +0000 | [diff] [blame] | 411 | Exit: |
Graham Asher | ce12182 | 2002-08-01 15:29:17 +0000 | [diff] [blame] | 412 | |
| 413 | #ifdef FT_CONFIG_OPTION_INCREMENTAL |
| 414 | if ( glyph_data_loaded && face->root.internal->incremental_interface ) |
| 415 | { |
| 416 | face->root.internal->incremental_interface->funcs->free_glyph_data( |
Werner Lemberg | 3c403e4 | 2002-08-06 21:47:40 +0000 | [diff] [blame] | 417 | face->root.internal->incremental_interface->object, |
| 418 | &glyph_data ); |
Graham Asher | ce12182 | 2002-08-01 15:29:17 +0000 | [diff] [blame] | 419 | |
| 420 | /* Set the control data to null - it is no longer available if */ |
Werner Lemberg | 3c403e4 | 2002-08-06 21:47:40 +0000 | [diff] [blame] | 421 | /* loaded incrementally. */ |
Graham Asher | ce12182 | 2002-08-01 15:29:17 +0000 | [diff] [blame] | 422 | glyph->root.control_data = 0; |
| 423 | glyph->root.control_len = 0; |
| 424 | } |
| 425 | #endif |
| 426 | |
David Turner | 2dfb5ac | 2000-01-27 14:02:04 +0000 | [diff] [blame] | 427 | return error; |
| 428 | } |
| 429 | |
Werner Lemberg | 7fa51b5 | 2000-07-08 19:51:42 +0000 | [diff] [blame] | 430 | |
| 431 | /* END */ |