1 *37da2899SCharles.Forsyth /***************************************************************************/ 2 *37da2899SCharles.Forsyth /* */ 3 *37da2899SCharles.Forsyth /* pfrload.c */ 4 *37da2899SCharles.Forsyth /* */ 5 *37da2899SCharles.Forsyth /* FreeType PFR loader (body). */ 6 *37da2899SCharles.Forsyth /* */ 7 *37da2899SCharles.Forsyth /* Copyright 2002 by */ 8 *37da2899SCharles.Forsyth /* David Turner, Robert Wilhelm, and Werner Lemberg. */ 9 *37da2899SCharles.Forsyth /* */ 10 *37da2899SCharles.Forsyth /* This file is part of the FreeType project, and may only be used, */ 11 *37da2899SCharles.Forsyth /* modified, and distributed under the terms of the FreeType project */ 12 *37da2899SCharles.Forsyth /* license, LICENSE.TXT. By continuing to use, modify, or distribute */ 13 *37da2899SCharles.Forsyth /* this file you indicate that you have read the license and */ 14 *37da2899SCharles.Forsyth /* understand and accept it fully. */ 15 *37da2899SCharles.Forsyth /* */ 16 *37da2899SCharles.Forsyth /***************************************************************************/ 17 *37da2899SCharles.Forsyth 18 *37da2899SCharles.Forsyth 19 *37da2899SCharles.Forsyth #include "pfrload.h" 20 *37da2899SCharles.Forsyth #include FT_INTERNAL_DEBUG_H 21 *37da2899SCharles.Forsyth #include FT_INTERNAL_STREAM_H 22 *37da2899SCharles.Forsyth 23 *37da2899SCharles.Forsyth #include "pfrerror.h" 24 *37da2899SCharles.Forsyth 25 *37da2899SCharles.Forsyth #undef FT_COMPONENT 26 *37da2899SCharles.Forsyth #define FT_COMPONENT trace_pfr 27 *37da2899SCharles.Forsyth 28 *37da2899SCharles.Forsyth 29 *37da2899SCharles.Forsyth /*************************************************************************/ 30 *37da2899SCharles.Forsyth /*************************************************************************/ 31 *37da2899SCharles.Forsyth /***** *****/ 32 *37da2899SCharles.Forsyth /***** EXTRA ITEMS *****/ 33 *37da2899SCharles.Forsyth /***** *****/ 34 *37da2899SCharles.Forsyth /*************************************************************************/ 35 *37da2899SCharles.Forsyth /*************************************************************************/ 36 *37da2899SCharles.Forsyth 37 *37da2899SCharles.Forsyth 38 *37da2899SCharles.Forsyth FT_LOCAL_DEF( FT_Error ) pfr_extra_items_skip(FT_Byte ** pp,FT_Byte * limit)39 *37da2899SCharles.Forsyth pfr_extra_items_skip( FT_Byte* *pp, 40 *37da2899SCharles.Forsyth FT_Byte* limit ) 41 *37da2899SCharles.Forsyth { 42 *37da2899SCharles.Forsyth return pfr_extra_items_parse( pp, limit, NULL, NULL ); 43 *37da2899SCharles.Forsyth } 44 *37da2899SCharles.Forsyth 45 *37da2899SCharles.Forsyth 46 *37da2899SCharles.Forsyth FT_LOCAL_DEF( FT_Error ) pfr_extra_items_parse(FT_Byte ** pp,FT_Byte * limit,PFR_ExtraItem item_list,FT_Pointer item_data)47 *37da2899SCharles.Forsyth pfr_extra_items_parse( FT_Byte* *pp, 48 *37da2899SCharles.Forsyth FT_Byte* limit, 49 *37da2899SCharles.Forsyth PFR_ExtraItem item_list, 50 *37da2899SCharles.Forsyth FT_Pointer item_data ) 51 *37da2899SCharles.Forsyth { 52 *37da2899SCharles.Forsyth FT_Error error = 0; 53 *37da2899SCharles.Forsyth FT_Byte* p = *pp; 54 *37da2899SCharles.Forsyth FT_UInt num_items, item_type, item_size; 55 *37da2899SCharles.Forsyth 56 *37da2899SCharles.Forsyth 57 *37da2899SCharles.Forsyth PFR_CHECK( 1 ); 58 *37da2899SCharles.Forsyth num_items = PFR_NEXT_BYTE( p ); 59 *37da2899SCharles.Forsyth 60 *37da2899SCharles.Forsyth for ( ; num_items > 0; num_items-- ) 61 *37da2899SCharles.Forsyth { 62 *37da2899SCharles.Forsyth PFR_CHECK( 2 ); 63 *37da2899SCharles.Forsyth item_size = PFR_NEXT_BYTE( p ); 64 *37da2899SCharles.Forsyth item_type = PFR_NEXT_BYTE( p ); 65 *37da2899SCharles.Forsyth 66 *37da2899SCharles.Forsyth PFR_CHECK( item_size ); 67 *37da2899SCharles.Forsyth 68 *37da2899SCharles.Forsyth if ( item_list ) 69 *37da2899SCharles.Forsyth { 70 *37da2899SCharles.Forsyth PFR_ExtraItem extra = item_list; 71 *37da2899SCharles.Forsyth 72 *37da2899SCharles.Forsyth 73 *37da2899SCharles.Forsyth for ( extra = item_list; extra->parser != NULL; extra++ ) 74 *37da2899SCharles.Forsyth { 75 *37da2899SCharles.Forsyth if ( extra->type == item_type ) 76 *37da2899SCharles.Forsyth { 77 *37da2899SCharles.Forsyth error = extra->parser( p, p + item_size, item_data ); 78 *37da2899SCharles.Forsyth if ( error ) goto Exit; 79 *37da2899SCharles.Forsyth 80 *37da2899SCharles.Forsyth break; 81 *37da2899SCharles.Forsyth } 82 *37da2899SCharles.Forsyth } 83 *37da2899SCharles.Forsyth } 84 *37da2899SCharles.Forsyth 85 *37da2899SCharles.Forsyth p += item_size; 86 *37da2899SCharles.Forsyth } 87 *37da2899SCharles.Forsyth 88 *37da2899SCharles.Forsyth Exit: 89 *37da2899SCharles.Forsyth *pp = p; 90 *37da2899SCharles.Forsyth return error; 91 *37da2899SCharles.Forsyth 92 *37da2899SCharles.Forsyth Too_Short: 93 *37da2899SCharles.Forsyth FT_ERROR(( "pfr_extra_items_parse: invalid extra items table\n" )); 94 *37da2899SCharles.Forsyth error = PFR_Err_Invalid_Table; 95 *37da2899SCharles.Forsyth goto Exit; 96 *37da2899SCharles.Forsyth } 97 *37da2899SCharles.Forsyth 98 *37da2899SCharles.Forsyth 99 *37da2899SCharles.Forsyth /*************************************************************************/ 100 *37da2899SCharles.Forsyth /*************************************************************************/ 101 *37da2899SCharles.Forsyth /***** *****/ 102 *37da2899SCharles.Forsyth /***** PFR HEADER *****/ 103 *37da2899SCharles.Forsyth /***** *****/ 104 *37da2899SCharles.Forsyth /*************************************************************************/ 105 *37da2899SCharles.Forsyth /*************************************************************************/ 106 *37da2899SCharles.Forsyth 107 *37da2899SCharles.Forsyth static const FT_Frame_Field pfr_header_fields[] = 108 *37da2899SCharles.Forsyth { 109 *37da2899SCharles.Forsyth #undef FT_STRUCTURE 110 *37da2899SCharles.Forsyth #define FT_STRUCTURE PFR_HeaderRec 111 *37da2899SCharles.Forsyth 112 *37da2899SCharles.Forsyth FT_FRAME_START( 58 ), 113 *37da2899SCharles.Forsyth FT_FRAME_ULONG ( signature ), 114 *37da2899SCharles.Forsyth FT_FRAME_USHORT( version ), 115 *37da2899SCharles.Forsyth FT_FRAME_USHORT( signature2 ), 116 *37da2899SCharles.Forsyth FT_FRAME_USHORT( header_size ), 117 *37da2899SCharles.Forsyth 118 *37da2899SCharles.Forsyth FT_FRAME_USHORT( log_dir_size ), 119 *37da2899SCharles.Forsyth FT_FRAME_USHORT( log_dir_offset ), 120 *37da2899SCharles.Forsyth 121 *37da2899SCharles.Forsyth FT_FRAME_USHORT( log_font_max_size ), 122 *37da2899SCharles.Forsyth FT_FRAME_UOFF3 ( log_font_section_size ), 123 *37da2899SCharles.Forsyth FT_FRAME_UOFF3 ( log_font_section_offset ), 124 *37da2899SCharles.Forsyth 125 *37da2899SCharles.Forsyth FT_FRAME_USHORT( phy_font_max_size ), 126 *37da2899SCharles.Forsyth FT_FRAME_UOFF3 ( phy_font_section_size ), 127 *37da2899SCharles.Forsyth FT_FRAME_UOFF3 ( phy_font_section_offset ), 128 *37da2899SCharles.Forsyth 129 *37da2899SCharles.Forsyth FT_FRAME_USHORT( gps_max_size ), 130 *37da2899SCharles.Forsyth FT_FRAME_UOFF3 ( gps_section_size ), 131 *37da2899SCharles.Forsyth FT_FRAME_UOFF3 ( gps_section_offset ), 132 *37da2899SCharles.Forsyth 133 *37da2899SCharles.Forsyth FT_FRAME_BYTE ( max_blue_values ), 134 *37da2899SCharles.Forsyth FT_FRAME_BYTE ( max_x_orus ), 135 *37da2899SCharles.Forsyth FT_FRAME_BYTE ( max_y_orus ), 136 *37da2899SCharles.Forsyth 137 *37da2899SCharles.Forsyth FT_FRAME_BYTE ( phy_font_max_size_high ), 138 *37da2899SCharles.Forsyth FT_FRAME_BYTE ( color_flags ), 139 *37da2899SCharles.Forsyth 140 *37da2899SCharles.Forsyth FT_FRAME_UOFF3 ( bct_max_size ), 141 *37da2899SCharles.Forsyth FT_FRAME_UOFF3 ( bct_set_max_size ), 142 *37da2899SCharles.Forsyth FT_FRAME_UOFF3 ( phy_bct_set_max_size ), 143 *37da2899SCharles.Forsyth 144 *37da2899SCharles.Forsyth FT_FRAME_USHORT( num_phy_fonts ), 145 *37da2899SCharles.Forsyth FT_FRAME_BYTE ( max_vert_stem_snap ), 146 *37da2899SCharles.Forsyth FT_FRAME_BYTE ( max_horz_stem_snap ), 147 *37da2899SCharles.Forsyth FT_FRAME_USHORT( max_chars ), 148 *37da2899SCharles.Forsyth FT_FRAME_END 149 *37da2899SCharles.Forsyth }; 150 *37da2899SCharles.Forsyth 151 *37da2899SCharles.Forsyth 152 *37da2899SCharles.Forsyth FT_LOCAL_DEF( FT_Error ) pfr_header_load(PFR_Header header,FT_Stream stream)153 *37da2899SCharles.Forsyth pfr_header_load( PFR_Header header, 154 *37da2899SCharles.Forsyth FT_Stream stream ) 155 *37da2899SCharles.Forsyth { 156 *37da2899SCharles.Forsyth FT_Error error; 157 *37da2899SCharles.Forsyth 158 *37da2899SCharles.Forsyth 159 *37da2899SCharles.Forsyth /* read header directly */ 160 *37da2899SCharles.Forsyth if ( !FT_STREAM_SEEK( 0 ) && 161 *37da2899SCharles.Forsyth !FT_STREAM_READ_FIELDS( pfr_header_fields, header ) ) 162 *37da2899SCharles.Forsyth { 163 *37da2899SCharles.Forsyth /* make a few adjustments to the header */ 164 *37da2899SCharles.Forsyth header->phy_font_max_size += 165 *37da2899SCharles.Forsyth (FT_UInt32)header->phy_font_max_size_high << 16; 166 *37da2899SCharles.Forsyth } 167 *37da2899SCharles.Forsyth 168 *37da2899SCharles.Forsyth return error; 169 *37da2899SCharles.Forsyth } 170 *37da2899SCharles.Forsyth 171 *37da2899SCharles.Forsyth 172 *37da2899SCharles.Forsyth FT_LOCAL_DEF( FT_Bool ) pfr_header_check(PFR_Header header)173 *37da2899SCharles.Forsyth pfr_header_check( PFR_Header header ) 174 *37da2899SCharles.Forsyth { 175 *37da2899SCharles.Forsyth FT_Bool result = 1; 176 *37da2899SCharles.Forsyth 177 *37da2899SCharles.Forsyth 178 *37da2899SCharles.Forsyth /* check signature and header size */ 179 *37da2899SCharles.Forsyth if ( header->signature != 0x50465230L || /* "PFR0" */ 180 *37da2899SCharles.Forsyth header->version > 4 || 181 *37da2899SCharles.Forsyth header->header_size < 58 || 182 *37da2899SCharles.Forsyth header->signature2 != 0x0d0a ) /* CR/LF */ 183 *37da2899SCharles.Forsyth { 184 *37da2899SCharles.Forsyth result = 0; 185 *37da2899SCharles.Forsyth } 186 *37da2899SCharles.Forsyth return result; 187 *37da2899SCharles.Forsyth } 188 *37da2899SCharles.Forsyth 189 *37da2899SCharles.Forsyth 190 *37da2899SCharles.Forsyth /***********************************************************************/ 191 *37da2899SCharles.Forsyth /***********************************************************************/ 192 *37da2899SCharles.Forsyth /***** *****/ 193 *37da2899SCharles.Forsyth /***** PFR LOGICAL FONTS *****/ 194 *37da2899SCharles.Forsyth /***** *****/ 195 *37da2899SCharles.Forsyth /***********************************************************************/ 196 *37da2899SCharles.Forsyth /***********************************************************************/ 197 *37da2899SCharles.Forsyth 198 *37da2899SCharles.Forsyth 199 *37da2899SCharles.Forsyth FT_LOCAL_DEF( FT_Error ) pfr_log_font_count(FT_Stream stream,FT_UInt32 section_offset,FT_UInt * acount)200 *37da2899SCharles.Forsyth pfr_log_font_count( FT_Stream stream, 201 *37da2899SCharles.Forsyth FT_UInt32 section_offset, 202 *37da2899SCharles.Forsyth FT_UInt *acount ) 203 *37da2899SCharles.Forsyth { 204 *37da2899SCharles.Forsyth FT_Error error; 205 *37da2899SCharles.Forsyth FT_UInt count; 206 *37da2899SCharles.Forsyth FT_UInt result = 0; 207 *37da2899SCharles.Forsyth 208 *37da2899SCharles.Forsyth 209 *37da2899SCharles.Forsyth if ( FT_STREAM_SEEK( section_offset ) || FT_READ_USHORT( count ) ) 210 *37da2899SCharles.Forsyth goto Exit; 211 *37da2899SCharles.Forsyth 212 *37da2899SCharles.Forsyth result = count; 213 *37da2899SCharles.Forsyth 214 *37da2899SCharles.Forsyth Exit: 215 *37da2899SCharles.Forsyth *acount = result; 216 *37da2899SCharles.Forsyth return error; 217 *37da2899SCharles.Forsyth } 218 *37da2899SCharles.Forsyth 219 *37da2899SCharles.Forsyth 220 *37da2899SCharles.Forsyth FT_LOCAL_DEF( FT_Error ) pfr_log_font_load(PFR_LogFont log_font,FT_Stream stream,FT_UInt idx,FT_UInt32 section_offset,FT_Bool size_increment)221 *37da2899SCharles.Forsyth pfr_log_font_load( PFR_LogFont log_font, 222 *37da2899SCharles.Forsyth FT_Stream stream, 223 *37da2899SCharles.Forsyth FT_UInt idx, 224 *37da2899SCharles.Forsyth FT_UInt32 section_offset, 225 *37da2899SCharles.Forsyth FT_Bool size_increment ) 226 *37da2899SCharles.Forsyth { 227 *37da2899SCharles.Forsyth FT_UInt num_log_fonts; 228 *37da2899SCharles.Forsyth FT_UInt flags; 229 *37da2899SCharles.Forsyth FT_UInt32 offset; 230 *37da2899SCharles.Forsyth FT_UInt32 size; 231 *37da2899SCharles.Forsyth FT_Error error; 232 *37da2899SCharles.Forsyth 233 *37da2899SCharles.Forsyth 234 *37da2899SCharles.Forsyth if ( FT_STREAM_SEEK( section_offset ) || 235 *37da2899SCharles.Forsyth FT_READ_USHORT( num_log_fonts ) ) 236 *37da2899SCharles.Forsyth goto Exit; 237 *37da2899SCharles.Forsyth 238 *37da2899SCharles.Forsyth if ( idx >= num_log_fonts ) 239 *37da2899SCharles.Forsyth return PFR_Err_Invalid_Argument; 240 *37da2899SCharles.Forsyth 241 *37da2899SCharles.Forsyth if ( FT_STREAM_SKIP( idx * 5 ) || 242 *37da2899SCharles.Forsyth FT_READ_USHORT( size ) || 243 *37da2899SCharles.Forsyth FT_READ_UOFF3 ( offset ) ) 244 *37da2899SCharles.Forsyth goto Exit; 245 *37da2899SCharles.Forsyth 246 *37da2899SCharles.Forsyth /* save logical font size and offset */ 247 *37da2899SCharles.Forsyth log_font->size = size; 248 *37da2899SCharles.Forsyth log_font->offset = offset; 249 *37da2899SCharles.Forsyth 250 *37da2899SCharles.Forsyth /* now, check the rest of the table before loading it */ 251 *37da2899SCharles.Forsyth { 252 *37da2899SCharles.Forsyth FT_Byte* p; 253 *37da2899SCharles.Forsyth FT_Byte* limit; 254 *37da2899SCharles.Forsyth FT_UInt local; 255 *37da2899SCharles.Forsyth 256 *37da2899SCharles.Forsyth 257 *37da2899SCharles.Forsyth if ( FT_STREAM_SEEK( offset ) || FT_FRAME_ENTER( size ) ) 258 *37da2899SCharles.Forsyth goto Exit; 259 *37da2899SCharles.Forsyth 260 *37da2899SCharles.Forsyth p = stream->cursor; 261 *37da2899SCharles.Forsyth limit = p + size; 262 *37da2899SCharles.Forsyth 263 *37da2899SCharles.Forsyth PFR_CHECK(13); 264 *37da2899SCharles.Forsyth 265 *37da2899SCharles.Forsyth log_font->matrix[0] = PFR_NEXT_LONG( p ); 266 *37da2899SCharles.Forsyth log_font->matrix[1] = PFR_NEXT_LONG( p ); 267 *37da2899SCharles.Forsyth log_font->matrix[2] = PFR_NEXT_LONG( p ); 268 *37da2899SCharles.Forsyth log_font->matrix[3] = PFR_NEXT_LONG( p ); 269 *37da2899SCharles.Forsyth 270 *37da2899SCharles.Forsyth flags = PFR_NEXT_BYTE( p ); 271 *37da2899SCharles.Forsyth 272 *37da2899SCharles.Forsyth local = 0; 273 *37da2899SCharles.Forsyth if ( flags & PFR_LOG_STROKE ) 274 *37da2899SCharles.Forsyth { 275 *37da2899SCharles.Forsyth local++; 276 *37da2899SCharles.Forsyth if ( flags & PFR_LOG_2BYTE_STROKE ) 277 *37da2899SCharles.Forsyth local++; 278 *37da2899SCharles.Forsyth 279 *37da2899SCharles.Forsyth if ( (flags & PFR_LINE_JOIN_MASK) == PFR_LINE_JOIN_MITER ) 280 *37da2899SCharles.Forsyth local += 3; 281 *37da2899SCharles.Forsyth } 282 *37da2899SCharles.Forsyth if ( flags & PFR_LOG_BOLD ) 283 *37da2899SCharles.Forsyth { 284 *37da2899SCharles.Forsyth local++; 285 *37da2899SCharles.Forsyth if ( flags & PFR_LOG_2BYTE_BOLD ) 286 *37da2899SCharles.Forsyth local++; 287 *37da2899SCharles.Forsyth } 288 *37da2899SCharles.Forsyth 289 *37da2899SCharles.Forsyth PFR_CHECK( local ); 290 *37da2899SCharles.Forsyth 291 *37da2899SCharles.Forsyth if ( flags & PFR_LOG_STROKE ) 292 *37da2899SCharles.Forsyth { 293 *37da2899SCharles.Forsyth log_font->stroke_thickness = ( flags & PFR_LOG_2BYTE_STROKE ) 294 *37da2899SCharles.Forsyth ? PFR_NEXT_SHORT( p ) 295 *37da2899SCharles.Forsyth : PFR_NEXT_BYTE( p ); 296 *37da2899SCharles.Forsyth 297 *37da2899SCharles.Forsyth if ( ( flags & PFR_LINE_JOIN_MASK ) == PFR_LINE_JOIN_MITER ) 298 *37da2899SCharles.Forsyth log_font->miter_limit = PFR_NEXT_LONG( p ); 299 *37da2899SCharles.Forsyth } 300 *37da2899SCharles.Forsyth 301 *37da2899SCharles.Forsyth if ( flags & PFR_LOG_BOLD ) 302 *37da2899SCharles.Forsyth { 303 *37da2899SCharles.Forsyth log_font->bold_thickness = ( flags & PFR_LOG_2BYTE_BOLD ) 304 *37da2899SCharles.Forsyth ? PFR_NEXT_SHORT( p ) 305 *37da2899SCharles.Forsyth : PFR_NEXT_BYTE( p ); 306 *37da2899SCharles.Forsyth } 307 *37da2899SCharles.Forsyth 308 *37da2899SCharles.Forsyth if ( flags & PFR_LOG_EXTRA_ITEMS ) 309 *37da2899SCharles.Forsyth { 310 *37da2899SCharles.Forsyth error = pfr_extra_items_skip( &p, limit ); 311 *37da2899SCharles.Forsyth if (error) goto Fail; 312 *37da2899SCharles.Forsyth } 313 *37da2899SCharles.Forsyth 314 *37da2899SCharles.Forsyth PFR_CHECK(5); 315 *37da2899SCharles.Forsyth log_font->phys_size = PFR_NEXT_USHORT( p ); 316 *37da2899SCharles.Forsyth log_font->phys_offset = PFR_NEXT_ULONG( p ); 317 *37da2899SCharles.Forsyth if ( size_increment ) 318 *37da2899SCharles.Forsyth { 319 *37da2899SCharles.Forsyth PFR_CHECK( 1 ); 320 *37da2899SCharles.Forsyth log_font->phys_size += (FT_UInt32)PFR_NEXT_BYTE( p ) << 16; 321 *37da2899SCharles.Forsyth } 322 *37da2899SCharles.Forsyth } 323 *37da2899SCharles.Forsyth 324 *37da2899SCharles.Forsyth Fail: 325 *37da2899SCharles.Forsyth FT_FRAME_EXIT(); 326 *37da2899SCharles.Forsyth 327 *37da2899SCharles.Forsyth Exit: 328 *37da2899SCharles.Forsyth return error; 329 *37da2899SCharles.Forsyth 330 *37da2899SCharles.Forsyth Too_Short: 331 *37da2899SCharles.Forsyth FT_ERROR(( "pfr_log_font_load: invalid logical font table\n" )); 332 *37da2899SCharles.Forsyth error = PFR_Err_Invalid_Table; 333 *37da2899SCharles.Forsyth goto Fail; 334 *37da2899SCharles.Forsyth } 335 *37da2899SCharles.Forsyth 336 *37da2899SCharles.Forsyth 337 *37da2899SCharles.Forsyth /***********************************************************************/ 338 *37da2899SCharles.Forsyth /***********************************************************************/ 339 *37da2899SCharles.Forsyth /***** *****/ 340 *37da2899SCharles.Forsyth /***** PFR PHYSICAL FONTS *****/ 341 *37da2899SCharles.Forsyth /***** *****/ 342 *37da2899SCharles.Forsyth /***********************************************************************/ 343 *37da2899SCharles.Forsyth /***********************************************************************/ 344 *37da2899SCharles.Forsyth 345 *37da2899SCharles.Forsyth 346 *37da2899SCharles.Forsyth /* load bitmap strikes lists */ 347 *37da2899SCharles.Forsyth FT_CALLBACK_DEF( FT_Error ) pfr_extra_item_load_bitmap_info(FT_Byte * p,FT_Byte * limit,PFR_PhyFont phy_font)348 *37da2899SCharles.Forsyth pfr_extra_item_load_bitmap_info( FT_Byte* p, 349 *37da2899SCharles.Forsyth FT_Byte* limit, 350 *37da2899SCharles.Forsyth PFR_PhyFont phy_font ) 351 *37da2899SCharles.Forsyth { 352 *37da2899SCharles.Forsyth FT_Memory memory = phy_font->memory; 353 *37da2899SCharles.Forsyth PFR_Strike strike; 354 *37da2899SCharles.Forsyth FT_UInt flags0; 355 *37da2899SCharles.Forsyth FT_UInt n, count, size1; 356 *37da2899SCharles.Forsyth FT_Error error = 0; 357 *37da2899SCharles.Forsyth 358 *37da2899SCharles.Forsyth 359 *37da2899SCharles.Forsyth PFR_CHECK( 5 ); 360 *37da2899SCharles.Forsyth 361 *37da2899SCharles.Forsyth p += 3; /* skip bctSize */ 362 *37da2899SCharles.Forsyth flags0 = PFR_NEXT_BYTE( p ); 363 *37da2899SCharles.Forsyth count = PFR_NEXT_BYTE( p ); 364 *37da2899SCharles.Forsyth 365 *37da2899SCharles.Forsyth /* re-allocate when needed */ 366 *37da2899SCharles.Forsyth if ( phy_font->num_strikes + count > phy_font->max_strikes ) 367 *37da2899SCharles.Forsyth { 368 *37da2899SCharles.Forsyth FT_UInt new_max = (phy_font->num_strikes + count + 3) & -4; 369 *37da2899SCharles.Forsyth 370 *37da2899SCharles.Forsyth if ( FT_RENEW_ARRAY( phy_font->strikes, 371 *37da2899SCharles.Forsyth phy_font->num_strikes, 372 *37da2899SCharles.Forsyth new_max ) ) 373 *37da2899SCharles.Forsyth goto Exit; 374 *37da2899SCharles.Forsyth 375 *37da2899SCharles.Forsyth phy_font->max_strikes = new_max; 376 *37da2899SCharles.Forsyth } 377 *37da2899SCharles.Forsyth 378 *37da2899SCharles.Forsyth size1 = 1 + 1 + 1 + 2 + 2 + 1; 379 *37da2899SCharles.Forsyth if ( flags0 & PFR_STRIKE_2BYTE_XPPM ) 380 *37da2899SCharles.Forsyth size1++; 381 *37da2899SCharles.Forsyth 382 *37da2899SCharles.Forsyth if ( flags0 & PFR_STRIKE_2BYTE_YPPM ) 383 *37da2899SCharles.Forsyth size1++; 384 *37da2899SCharles.Forsyth 385 *37da2899SCharles.Forsyth if ( flags0 & PFR_STRIKE_3BYTE_SIZE ) 386 *37da2899SCharles.Forsyth size1++; 387 *37da2899SCharles.Forsyth 388 *37da2899SCharles.Forsyth if ( flags0 & PFR_STRIKE_3BYTE_OFFSET ) 389 *37da2899SCharles.Forsyth size1++; 390 *37da2899SCharles.Forsyth 391 *37da2899SCharles.Forsyth if ( flags0 & PFR_STRIKE_2BYTE_COUNT ) 392 *37da2899SCharles.Forsyth size1++; 393 *37da2899SCharles.Forsyth 394 *37da2899SCharles.Forsyth strike = phy_font->strikes + phy_font->num_strikes; 395 *37da2899SCharles.Forsyth 396 *37da2899SCharles.Forsyth PFR_CHECK( count * size1 ); 397 *37da2899SCharles.Forsyth 398 *37da2899SCharles.Forsyth for ( n = 0; n < count; n++, strike++ ) 399 *37da2899SCharles.Forsyth { 400 *37da2899SCharles.Forsyth strike->x_ppm = ( flags0 & PFR_STRIKE_2BYTE_XPPM ) 401 *37da2899SCharles.Forsyth ? PFR_NEXT_USHORT( p ) 402 *37da2899SCharles.Forsyth : PFR_NEXT_BYTE( p ); 403 *37da2899SCharles.Forsyth 404 *37da2899SCharles.Forsyth strike->y_ppm = ( flags0 & PFR_STRIKE_2BYTE_YPPM ) 405 *37da2899SCharles.Forsyth ? PFR_NEXT_USHORT( p ) 406 *37da2899SCharles.Forsyth : PFR_NEXT_BYTE( p ); 407 *37da2899SCharles.Forsyth 408 *37da2899SCharles.Forsyth strike->flags = PFR_NEXT_BYTE( p ); 409 *37da2899SCharles.Forsyth 410 *37da2899SCharles.Forsyth strike->bct_size = ( flags0 & PFR_STRIKE_3BYTE_SIZE ) 411 *37da2899SCharles.Forsyth ? PFR_NEXT_ULONG( p ) 412 *37da2899SCharles.Forsyth : PFR_NEXT_USHORT( p ); 413 *37da2899SCharles.Forsyth 414 *37da2899SCharles.Forsyth strike->bct_offset = ( flags0 & PFR_STRIKE_3BYTE_OFFSET ) 415 *37da2899SCharles.Forsyth ? PFR_NEXT_ULONG( p ) 416 *37da2899SCharles.Forsyth : PFR_NEXT_USHORT( p ); 417 *37da2899SCharles.Forsyth 418 *37da2899SCharles.Forsyth strike->num_bitmaps = ( flags0 & PFR_STRIKE_2BYTE_COUNT ) 419 *37da2899SCharles.Forsyth ? PFR_NEXT_USHORT( p ) 420 *37da2899SCharles.Forsyth : PFR_NEXT_BYTE( p ); 421 *37da2899SCharles.Forsyth } 422 *37da2899SCharles.Forsyth 423 *37da2899SCharles.Forsyth phy_font->num_strikes += count; 424 *37da2899SCharles.Forsyth 425 *37da2899SCharles.Forsyth Exit: 426 *37da2899SCharles.Forsyth return error; 427 *37da2899SCharles.Forsyth 428 *37da2899SCharles.Forsyth Too_Short: 429 *37da2899SCharles.Forsyth error = PFR_Err_Invalid_Table; 430 *37da2899SCharles.Forsyth FT_ERROR(( "pfr_extra_item_load_bitmap_info: invalid bitmap info table\n" )); 431 *37da2899SCharles.Forsyth goto Exit; 432 *37da2899SCharles.Forsyth } 433 *37da2899SCharles.Forsyth 434 *37da2899SCharles.Forsyth 435 *37da2899SCharles.Forsyth /* load font ID, i.e. name */ 436 *37da2899SCharles.Forsyth FT_CALLBACK_DEF( FT_Error ) pfr_extra_item_load_font_id(FT_Byte * p,FT_Byte * limit,PFR_PhyFont phy_font)437 *37da2899SCharles.Forsyth pfr_extra_item_load_font_id( FT_Byte* p, 438 *37da2899SCharles.Forsyth FT_Byte* limit, 439 *37da2899SCharles.Forsyth PFR_PhyFont phy_font ) 440 *37da2899SCharles.Forsyth { 441 *37da2899SCharles.Forsyth FT_Error error = 0; 442 *37da2899SCharles.Forsyth FT_Memory memory = phy_font->memory; 443 *37da2899SCharles.Forsyth FT_UInt len = (FT_UInt)( limit - p ); 444 *37da2899SCharles.Forsyth 445 *37da2899SCharles.Forsyth 446 *37da2899SCharles.Forsyth if ( phy_font->font_id != NULL ) 447 *37da2899SCharles.Forsyth goto Exit; 448 *37da2899SCharles.Forsyth 449 *37da2899SCharles.Forsyth if ( FT_ALLOC( phy_font->font_id, len+1 ) ) 450 *37da2899SCharles.Forsyth goto Exit; 451 *37da2899SCharles.Forsyth 452 *37da2899SCharles.Forsyth /* copy font ID name, and terminate it for safety */ 453 *37da2899SCharles.Forsyth FT_MEM_COPY( phy_font->font_id, p, len ); 454 *37da2899SCharles.Forsyth phy_font->font_id[len] = 0; 455 *37da2899SCharles.Forsyth 456 *37da2899SCharles.Forsyth Exit: 457 *37da2899SCharles.Forsyth return error; 458 *37da2899SCharles.Forsyth } 459 *37da2899SCharles.Forsyth 460 *37da2899SCharles.Forsyth 461 *37da2899SCharles.Forsyth /* load stem snap tables */ 462 *37da2899SCharles.Forsyth FT_CALLBACK_DEF( FT_Error ) pfr_extra_item_load_stem_snaps(FT_Byte * p,FT_Byte * limit,PFR_PhyFont phy_font)463 *37da2899SCharles.Forsyth pfr_extra_item_load_stem_snaps( FT_Byte* p, 464 *37da2899SCharles.Forsyth FT_Byte* limit, 465 *37da2899SCharles.Forsyth PFR_PhyFont phy_font ) 466 *37da2899SCharles.Forsyth { 467 *37da2899SCharles.Forsyth FT_UInt count, num_vert, num_horz; 468 *37da2899SCharles.Forsyth FT_Int* snaps; 469 *37da2899SCharles.Forsyth FT_Error error = 0; 470 *37da2899SCharles.Forsyth FT_Memory memory = phy_font->memory; 471 *37da2899SCharles.Forsyth 472 *37da2899SCharles.Forsyth 473 *37da2899SCharles.Forsyth if ( phy_font->vertical.stem_snaps != NULL ) 474 *37da2899SCharles.Forsyth goto Exit; 475 *37da2899SCharles.Forsyth 476 *37da2899SCharles.Forsyth PFR_CHECK( 1 ); 477 *37da2899SCharles.Forsyth count = PFR_NEXT_BYTE( p ); 478 *37da2899SCharles.Forsyth 479 *37da2899SCharles.Forsyth num_vert = count & 15; 480 *37da2899SCharles.Forsyth num_horz = count >> 4; 481 *37da2899SCharles.Forsyth count = num_vert + num_horz; 482 *37da2899SCharles.Forsyth 483 *37da2899SCharles.Forsyth PFR_CHECK( count * 2 ); 484 *37da2899SCharles.Forsyth 485 *37da2899SCharles.Forsyth if ( FT_NEW_ARRAY( snaps, count ) ) 486 *37da2899SCharles.Forsyth goto Exit; 487 *37da2899SCharles.Forsyth 488 *37da2899SCharles.Forsyth phy_font->vertical.stem_snaps = snaps; 489 *37da2899SCharles.Forsyth phy_font->horizontal.stem_snaps = snaps + num_vert; 490 *37da2899SCharles.Forsyth 491 *37da2899SCharles.Forsyth for ( ; count > 0; count--, snaps++ ) 492 *37da2899SCharles.Forsyth *snaps = FT_NEXT_SHORT( p ); 493 *37da2899SCharles.Forsyth 494 *37da2899SCharles.Forsyth Exit: 495 *37da2899SCharles.Forsyth return error; 496 *37da2899SCharles.Forsyth 497 *37da2899SCharles.Forsyth Too_Short: 498 *37da2899SCharles.Forsyth error = PFR_Err_Invalid_Table; 499 *37da2899SCharles.Forsyth FT_ERROR(( "pfr_exta_item_load_stem_snaps: invalid stem snaps table\n" )); 500 *37da2899SCharles.Forsyth goto Exit; 501 *37da2899SCharles.Forsyth } 502 *37da2899SCharles.Forsyth 503 *37da2899SCharles.Forsyth 504 *37da2899SCharles.Forsyth #if 0 505 *37da2899SCharles.Forsyth 506 *37da2899SCharles.Forsyth /* load kerning pair data */ 507 *37da2899SCharles.Forsyth FT_CALLBACK_DEF( FT_Error ) 508 *37da2899SCharles.Forsyth pfr_extra_item_load_kerning_pairs( FT_Byte* p, 509 *37da2899SCharles.Forsyth FT_Byte* limit, 510 *37da2899SCharles.Forsyth PFR_PhyFont phy_font ) 511 *37da2899SCharles.Forsyth { 512 *37da2899SCharles.Forsyth FT_Int count; 513 *37da2899SCharles.Forsyth FT_UShort base_adj; 514 *37da2899SCharles.Forsyth FT_UInt flags; 515 *37da2899SCharles.Forsyth FT_UInt num_pairs; 516 *37da2899SCharles.Forsyth PFR_KernPair pairs; 517 *37da2899SCharles.Forsyth FT_Error error = 0; 518 *37da2899SCharles.Forsyth FT_Memory memory = phy_font->memory; 519 *37da2899SCharles.Forsyth 520 *37da2899SCharles.Forsyth 521 *37da2899SCharles.Forsyth /* allocate a new kerning item */ 522 *37da2899SCharles.Forsyth /* XXX: there may be multiple extra items for kerning */ 523 *37da2899SCharles.Forsyth if ( phy_font->kern_pairs != NULL ) 524 *37da2899SCharles.Forsyth goto Exit; 525 *37da2899SCharles.Forsyth 526 *37da2899SCharles.Forsyth FT_TRACE2(( "pfr_extra_item_load_kerning_pairs()\n" )); 527 *37da2899SCharles.Forsyth 528 *37da2899SCharles.Forsyth PFR_CHECK( 4 ); 529 *37da2899SCharles.Forsyth 530 *37da2899SCharles.Forsyth num_pairs = PFR_NEXT_BYTE( p ); 531 *37da2899SCharles.Forsyth base_adj = PFR_NEXT_SHORT( p ); 532 *37da2899SCharles.Forsyth flags = PFR_NEXT_BYTE( p ); 533 *37da2899SCharles.Forsyth 534 *37da2899SCharles.Forsyth #ifndef PFR_CONFIG_NO_CHECKS 535 *37da2899SCharles.Forsyth count = 3; 536 *37da2899SCharles.Forsyth 537 *37da2899SCharles.Forsyth if ( flags & PFR_KERN_2BYTE_CHAR ) 538 *37da2899SCharles.Forsyth count += 2; 539 *37da2899SCharles.Forsyth 540 *37da2899SCharles.Forsyth if ( flags & PFR_KERN_2BYTE_ADJ ) 541 *37da2899SCharles.Forsyth count += 1; 542 *37da2899SCharles.Forsyth 543 *37da2899SCharles.Forsyth PFR_CHECK( num_pairs * count ); 544 *37da2899SCharles.Forsyth #endif 545 *37da2899SCharles.Forsyth 546 *37da2899SCharles.Forsyth if ( FT_NEW_ARRAY( pairs, num_pairs ) ) 547 *37da2899SCharles.Forsyth goto Exit; 548 *37da2899SCharles.Forsyth 549 *37da2899SCharles.Forsyth phy_font->num_kern_pairs = num_pairs; 550 *37da2899SCharles.Forsyth phy_font->kern_pairs = pairs; 551 *37da2899SCharles.Forsyth 552 *37da2899SCharles.Forsyth for (count = num_pairs ; count > 0; count--, pairs++ ) 553 *37da2899SCharles.Forsyth { 554 *37da2899SCharles.Forsyth if ( flags & PFR_KERN_2BYTE_CHAR ) 555 *37da2899SCharles.Forsyth { 556 *37da2899SCharles.Forsyth pairs->glyph1 = PFR_NEXT_USHORT( p ); 557 *37da2899SCharles.Forsyth pairs->glyph2 = PFR_NEXT_USHORT( p ); 558 *37da2899SCharles.Forsyth } 559 *37da2899SCharles.Forsyth else 560 *37da2899SCharles.Forsyth { 561 *37da2899SCharles.Forsyth pairs->glyph1 = PFR_NEXT_BYTE( p ); 562 *37da2899SCharles.Forsyth pairs->glyph2 = PFR_NEXT_BYTE( p ); 563 *37da2899SCharles.Forsyth } 564 *37da2899SCharles.Forsyth 565 *37da2899SCharles.Forsyth if ( flags & PFR_KERN_2BYTE_ADJ ) 566 *37da2899SCharles.Forsyth pairs->kerning.x = base_adj + PFR_NEXT_SHORT( p ); 567 *37da2899SCharles.Forsyth else 568 *37da2899SCharles.Forsyth pairs->kerning.x = base_adj + PFR_NEXT_INT8( p ); 569 *37da2899SCharles.Forsyth 570 *37da2899SCharles.Forsyth pairs->kerning.y = 0; 571 *37da2899SCharles.Forsyth 572 *37da2899SCharles.Forsyth FT_TRACE2(( "kerning %d <-> %d : %ld\n", 573 *37da2899SCharles.Forsyth pairs->glyph1, pairs->glyph2, pairs->kerning.x )); 574 *37da2899SCharles.Forsyth } 575 *37da2899SCharles.Forsyth 576 *37da2899SCharles.Forsyth Exit: 577 *37da2899SCharles.Forsyth return error; 578 *37da2899SCharles.Forsyth 579 *37da2899SCharles.Forsyth Too_Short: 580 *37da2899SCharles.Forsyth error = PFR_Err_Invalid_Table; 581 *37da2899SCharles.Forsyth FT_ERROR(( "pfr_extra_item_load_kerning_pairs: " 582 *37da2899SCharles.Forsyth "invalid kerning pairs table\n" )); 583 *37da2899SCharles.Forsyth goto Exit; 584 *37da2899SCharles.Forsyth } 585 *37da2899SCharles.Forsyth 586 *37da2899SCharles.Forsyth #else /* 0 */ 587 *37da2899SCharles.Forsyth 588 *37da2899SCharles.Forsyth /* load kerning pair data */ 589 *37da2899SCharles.Forsyth FT_CALLBACK_DEF( FT_Error ) pfr_extra_item_load_kerning_pairs(FT_Byte * p,FT_Byte * limit,PFR_PhyFont phy_font)590 *37da2899SCharles.Forsyth pfr_extra_item_load_kerning_pairs( FT_Byte* p, 591 *37da2899SCharles.Forsyth FT_Byte* limit, 592 *37da2899SCharles.Forsyth PFR_PhyFont phy_font ) 593 *37da2899SCharles.Forsyth { 594 *37da2899SCharles.Forsyth PFR_KernItem item; 595 *37da2899SCharles.Forsyth FT_Error error = 0; 596 *37da2899SCharles.Forsyth FT_Memory memory = phy_font->memory; 597 *37da2899SCharles.Forsyth 598 *37da2899SCharles.Forsyth 599 *37da2899SCharles.Forsyth FT_TRACE2(( "pfr_extra_item_load_kerning_pairs()\n" )); 600 *37da2899SCharles.Forsyth 601 *37da2899SCharles.Forsyth if ( FT_NEW( item ) ) 602 *37da2899SCharles.Forsyth goto Exit; 603 *37da2899SCharles.Forsyth 604 *37da2899SCharles.Forsyth PFR_CHECK( 4 ); 605 *37da2899SCharles.Forsyth 606 *37da2899SCharles.Forsyth item->pair_count = PFR_NEXT_BYTE( p ); 607 *37da2899SCharles.Forsyth item->base_adj = PFR_NEXT_SHORT( p ); 608 *37da2899SCharles.Forsyth item->flags = PFR_NEXT_BYTE( p ); 609 *37da2899SCharles.Forsyth item->offset = phy_font->offset + ( p - phy_font->cursor ); 610 *37da2899SCharles.Forsyth 611 *37da2899SCharles.Forsyth #ifndef PFR_CONFIG_NO_CHECKS 612 *37da2899SCharles.Forsyth item->pair_size = 3; 613 *37da2899SCharles.Forsyth 614 *37da2899SCharles.Forsyth if ( item->flags & PFR_KERN_2BYTE_CHAR ) 615 *37da2899SCharles.Forsyth item->pair_size += 2; 616 *37da2899SCharles.Forsyth 617 *37da2899SCharles.Forsyth if ( item->flags & PFR_KERN_2BYTE_ADJ ) 618 *37da2899SCharles.Forsyth item->pair_size += 1; 619 *37da2899SCharles.Forsyth 620 *37da2899SCharles.Forsyth PFR_CHECK( item->pair_count * item->pair_size ); 621 *37da2899SCharles.Forsyth #endif 622 *37da2899SCharles.Forsyth 623 *37da2899SCharles.Forsyth /* load first and last pairs into the item to speed up */ 624 *37da2899SCharles.Forsyth /* lookup later... */ 625 *37da2899SCharles.Forsyth if ( item->pair_count > 0 ) 626 *37da2899SCharles.Forsyth { 627 *37da2899SCharles.Forsyth FT_UInt char1, char2; 628 *37da2899SCharles.Forsyth FT_Byte* q; 629 *37da2899SCharles.Forsyth 630 *37da2899SCharles.Forsyth 631 *37da2899SCharles.Forsyth if ( item->flags & PFR_KERN_2BYTE_CHAR ) 632 *37da2899SCharles.Forsyth { 633 *37da2899SCharles.Forsyth q = p; 634 *37da2899SCharles.Forsyth char1 = PFR_NEXT_USHORT( q ); 635 *37da2899SCharles.Forsyth char2 = PFR_NEXT_USHORT( q ); 636 *37da2899SCharles.Forsyth 637 *37da2899SCharles.Forsyth item->pair1 = PFR_KERN_INDEX( char1, char2 ); 638 *37da2899SCharles.Forsyth 639 *37da2899SCharles.Forsyth q = p + item->pair_size * ( item->pair_count - 1 ); 640 *37da2899SCharles.Forsyth char1 = PFR_NEXT_USHORT( q ); 641 *37da2899SCharles.Forsyth char2 = PFR_NEXT_USHORT( q ); 642 *37da2899SCharles.Forsyth 643 *37da2899SCharles.Forsyth item->pair2 = PFR_KERN_INDEX( char1, char2 ); 644 *37da2899SCharles.Forsyth } 645 *37da2899SCharles.Forsyth else 646 *37da2899SCharles.Forsyth { 647 *37da2899SCharles.Forsyth q = p; 648 *37da2899SCharles.Forsyth char1 = PFR_NEXT_BYTE( q ); 649 *37da2899SCharles.Forsyth char2 = PFR_NEXT_BYTE( q ); 650 *37da2899SCharles.Forsyth 651 *37da2899SCharles.Forsyth item->pair1 = PFR_KERN_INDEX( char1, char2 ); 652 *37da2899SCharles.Forsyth 653 *37da2899SCharles.Forsyth q = p + item->pair_size * ( item->pair_count - 1 ); 654 *37da2899SCharles.Forsyth char1 = PFR_NEXT_BYTE( q ); 655 *37da2899SCharles.Forsyth char2 = PFR_NEXT_BYTE( q ); 656 *37da2899SCharles.Forsyth 657 *37da2899SCharles.Forsyth item->pair2 = PFR_KERN_INDEX( char1, char2 ); 658 *37da2899SCharles.Forsyth } 659 *37da2899SCharles.Forsyth 660 *37da2899SCharles.Forsyth /* add new item to the current list */ 661 *37da2899SCharles.Forsyth item->next = NULL; 662 *37da2899SCharles.Forsyth *phy_font->kern_items_tail = item; 663 *37da2899SCharles.Forsyth phy_font->kern_items_tail = &item->next; 664 *37da2899SCharles.Forsyth phy_font->num_kern_pairs += item->pair_count; 665 *37da2899SCharles.Forsyth } 666 *37da2899SCharles.Forsyth else 667 *37da2899SCharles.Forsyth { 668 *37da2899SCharles.Forsyth /* empty item! */ 669 *37da2899SCharles.Forsyth FT_FREE( item ); 670 *37da2899SCharles.Forsyth } 671 *37da2899SCharles.Forsyth 672 *37da2899SCharles.Forsyth Exit: 673 *37da2899SCharles.Forsyth return error; 674 *37da2899SCharles.Forsyth 675 *37da2899SCharles.Forsyth Too_Short: 676 *37da2899SCharles.Forsyth FT_FREE( item ); 677 *37da2899SCharles.Forsyth 678 *37da2899SCharles.Forsyth error = PFR_Err_Invalid_Table; 679 *37da2899SCharles.Forsyth FT_ERROR(( "pfr_extra_item_load_kerning_pairs: " 680 *37da2899SCharles.Forsyth "invalid kerning pairs table\n" )); 681 *37da2899SCharles.Forsyth goto Exit; 682 *37da2899SCharles.Forsyth } 683 *37da2899SCharles.Forsyth #endif /* 0 */ 684 *37da2899SCharles.Forsyth 685 *37da2899SCharles.Forsyth 686 *37da2899SCharles.Forsyth static const PFR_ExtraItemRec pfr_phy_font_extra_items[] = 687 *37da2899SCharles.Forsyth { 688 *37da2899SCharles.Forsyth { 1, (PFR_ExtraItem_ParseFunc) pfr_extra_item_load_bitmap_info }, 689 *37da2899SCharles.Forsyth { 2, (PFR_ExtraItem_ParseFunc) pfr_extra_item_load_font_id }, 690 *37da2899SCharles.Forsyth { 3, (PFR_ExtraItem_ParseFunc) pfr_extra_item_load_stem_snaps }, 691 *37da2899SCharles.Forsyth { 4, (PFR_ExtraItem_ParseFunc) pfr_extra_item_load_kerning_pairs }, 692 *37da2899SCharles.Forsyth { 0, NULL } 693 *37da2899SCharles.Forsyth }; 694 *37da2899SCharles.Forsyth 695 *37da2899SCharles.Forsyth 696 *37da2899SCharles.Forsyth FT_LOCAL_DEF( void ) pfr_phy_font_done(PFR_PhyFont phy_font,FT_Memory memory)697 *37da2899SCharles.Forsyth pfr_phy_font_done( PFR_PhyFont phy_font, 698 *37da2899SCharles.Forsyth FT_Memory memory ) 699 *37da2899SCharles.Forsyth { 700 *37da2899SCharles.Forsyth if ( phy_font->font_id ) 701 *37da2899SCharles.Forsyth FT_FREE( phy_font->font_id ); 702 *37da2899SCharles.Forsyth 703 *37da2899SCharles.Forsyth FT_FREE( phy_font->vertical.stem_snaps ); 704 *37da2899SCharles.Forsyth phy_font->vertical.num_stem_snaps = 0; 705 *37da2899SCharles.Forsyth 706 *37da2899SCharles.Forsyth phy_font->horizontal.stem_snaps = NULL; 707 *37da2899SCharles.Forsyth phy_font->horizontal.num_stem_snaps = 0; 708 *37da2899SCharles.Forsyth 709 *37da2899SCharles.Forsyth FT_FREE( phy_font->strikes ); 710 *37da2899SCharles.Forsyth phy_font->num_strikes = 0; 711 *37da2899SCharles.Forsyth phy_font->max_strikes = 0; 712 *37da2899SCharles.Forsyth 713 *37da2899SCharles.Forsyth FT_FREE( phy_font->chars ); 714 *37da2899SCharles.Forsyth phy_font->num_chars = 0; 715 *37da2899SCharles.Forsyth phy_font->chars_offset = 0; 716 *37da2899SCharles.Forsyth 717 *37da2899SCharles.Forsyth FT_FREE( phy_font->blue_values ); 718 *37da2899SCharles.Forsyth phy_font->num_blue_values = 0; 719 *37da2899SCharles.Forsyth 720 *37da2899SCharles.Forsyth { 721 *37da2899SCharles.Forsyth PFR_KernItem item, next; 722 *37da2899SCharles.Forsyth 723 *37da2899SCharles.Forsyth 724 *37da2899SCharles.Forsyth item = phy_font->kern_items; 725 *37da2899SCharles.Forsyth while ( item ) 726 *37da2899SCharles.Forsyth { 727 *37da2899SCharles.Forsyth next = item->next; 728 *37da2899SCharles.Forsyth FT_FREE( item ); 729 *37da2899SCharles.Forsyth item = next; 730 *37da2899SCharles.Forsyth } 731 *37da2899SCharles.Forsyth phy_font->kern_items = NULL; 732 *37da2899SCharles.Forsyth phy_font->kern_items_tail = NULL; 733 *37da2899SCharles.Forsyth } 734 *37da2899SCharles.Forsyth 735 *37da2899SCharles.Forsyth phy_font->num_kern_pairs = 0; 736 *37da2899SCharles.Forsyth } 737 *37da2899SCharles.Forsyth 738 *37da2899SCharles.Forsyth 739 *37da2899SCharles.Forsyth FT_LOCAL_DEF( FT_Error ) pfr_phy_font_load(PFR_PhyFont phy_font,FT_Stream stream,FT_UInt32 offset,FT_UInt32 size)740 *37da2899SCharles.Forsyth pfr_phy_font_load( PFR_PhyFont phy_font, 741 *37da2899SCharles.Forsyth FT_Stream stream, 742 *37da2899SCharles.Forsyth FT_UInt32 offset, 743 *37da2899SCharles.Forsyth FT_UInt32 size ) 744 *37da2899SCharles.Forsyth { 745 *37da2899SCharles.Forsyth FT_Error error; 746 *37da2899SCharles.Forsyth FT_Memory memory = stream->memory; 747 *37da2899SCharles.Forsyth FT_UInt flags, num_aux; 748 *37da2899SCharles.Forsyth FT_Byte* p; 749 *37da2899SCharles.Forsyth FT_Byte* limit; 750 *37da2899SCharles.Forsyth 751 *37da2899SCharles.Forsyth 752 *37da2899SCharles.Forsyth phy_font->memory = memory; 753 *37da2899SCharles.Forsyth phy_font->offset = offset; 754 *37da2899SCharles.Forsyth 755 *37da2899SCharles.Forsyth phy_font->kern_items = NULL; 756 *37da2899SCharles.Forsyth phy_font->kern_items_tail = &phy_font->kern_items; 757 *37da2899SCharles.Forsyth 758 *37da2899SCharles.Forsyth if ( FT_STREAM_SEEK( offset ) || FT_FRAME_ENTER( size ) ) 759 *37da2899SCharles.Forsyth goto Exit; 760 *37da2899SCharles.Forsyth 761 *37da2899SCharles.Forsyth phy_font->cursor = stream->cursor; 762 *37da2899SCharles.Forsyth 763 *37da2899SCharles.Forsyth p = stream->cursor; 764 *37da2899SCharles.Forsyth limit = p + size; 765 *37da2899SCharles.Forsyth 766 *37da2899SCharles.Forsyth PFR_CHECK( 15 ); 767 *37da2899SCharles.Forsyth phy_font->font_ref_number = PFR_NEXT_USHORT( p ); 768 *37da2899SCharles.Forsyth phy_font->outline_resolution = PFR_NEXT_USHORT( p ); 769 *37da2899SCharles.Forsyth phy_font->metrics_resolution = PFR_NEXT_USHORT( p ); 770 *37da2899SCharles.Forsyth phy_font->bbox.xMin = PFR_NEXT_SHORT( p ); 771 *37da2899SCharles.Forsyth phy_font->bbox.yMin = PFR_NEXT_SHORT( p ); 772 *37da2899SCharles.Forsyth phy_font->bbox.xMax = PFR_NEXT_SHORT( p ); 773 *37da2899SCharles.Forsyth phy_font->bbox.yMax = PFR_NEXT_SHORT( p ); 774 *37da2899SCharles.Forsyth phy_font->flags = flags = PFR_NEXT_BYTE( p ); 775 *37da2899SCharles.Forsyth 776 *37da2899SCharles.Forsyth /* get the standard advance for non-proprotional fonts */ 777 *37da2899SCharles.Forsyth if ( !(flags & PFR_PHY_PROPORTIONAL) ) 778 *37da2899SCharles.Forsyth { 779 *37da2899SCharles.Forsyth PFR_CHECK( 2 ); 780 *37da2899SCharles.Forsyth phy_font->standard_advance = PFR_NEXT_SHORT( p ); 781 *37da2899SCharles.Forsyth } 782 *37da2899SCharles.Forsyth 783 *37da2899SCharles.Forsyth /* load the extra items when present */ 784 *37da2899SCharles.Forsyth if ( flags & PFR_PHY_EXTRA_ITEMS ) 785 *37da2899SCharles.Forsyth { 786 *37da2899SCharles.Forsyth error = pfr_extra_items_parse( &p, limit, 787 *37da2899SCharles.Forsyth pfr_phy_font_extra_items, phy_font ); 788 *37da2899SCharles.Forsyth 789 *37da2899SCharles.Forsyth if ( error ) 790 *37da2899SCharles.Forsyth goto Fail; 791 *37da2899SCharles.Forsyth } 792 *37da2899SCharles.Forsyth 793 *37da2899SCharles.Forsyth /* skip the aux bytes */ 794 *37da2899SCharles.Forsyth PFR_CHECK( 3 ); 795 *37da2899SCharles.Forsyth num_aux = PFR_NEXT_ULONG( p ); 796 *37da2899SCharles.Forsyth 797 *37da2899SCharles.Forsyth PFR_CHECK( num_aux ); 798 *37da2899SCharles.Forsyth p += num_aux; 799 *37da2899SCharles.Forsyth 800 *37da2899SCharles.Forsyth /* read the blue values */ 801 *37da2899SCharles.Forsyth { 802 *37da2899SCharles.Forsyth FT_UInt n, count; 803 *37da2899SCharles.Forsyth 804 *37da2899SCharles.Forsyth PFR_CHECK( 1 ); 805 *37da2899SCharles.Forsyth phy_font->num_blue_values = count = PFR_NEXT_BYTE( p ); 806 *37da2899SCharles.Forsyth 807 *37da2899SCharles.Forsyth PFR_CHECK( count * 2 ); 808 *37da2899SCharles.Forsyth 809 *37da2899SCharles.Forsyth if ( FT_NEW_ARRAY( phy_font->blue_values, count ) ) 810 *37da2899SCharles.Forsyth goto Fail; 811 *37da2899SCharles.Forsyth 812 *37da2899SCharles.Forsyth for ( n = 0; n < count; n++ ) 813 *37da2899SCharles.Forsyth phy_font->blue_values[n] = PFR_NEXT_SHORT( p ); 814 *37da2899SCharles.Forsyth } 815 *37da2899SCharles.Forsyth 816 *37da2899SCharles.Forsyth PFR_CHECK( 8 ); 817 *37da2899SCharles.Forsyth phy_font->blue_fuzz = PFR_NEXT_BYTE( p ); 818 *37da2899SCharles.Forsyth phy_font->blue_scale = PFR_NEXT_BYTE( p ); 819 *37da2899SCharles.Forsyth 820 *37da2899SCharles.Forsyth phy_font->vertical.standard = PFR_NEXT_USHORT( p ); 821 *37da2899SCharles.Forsyth phy_font->horizontal.standard = PFR_NEXT_USHORT( p ); 822 *37da2899SCharles.Forsyth 823 *37da2899SCharles.Forsyth /* read the character descriptors */ 824 *37da2899SCharles.Forsyth { 825 *37da2899SCharles.Forsyth FT_UInt n, count, Size; 826 *37da2899SCharles.Forsyth 827 *37da2899SCharles.Forsyth 828 *37da2899SCharles.Forsyth phy_font->num_chars = count = PFR_NEXT_USHORT( p ); 829 *37da2899SCharles.Forsyth phy_font->chars_offset = offset + ( p - stream->cursor ); 830 *37da2899SCharles.Forsyth 831 *37da2899SCharles.Forsyth if ( FT_NEW_ARRAY( phy_font->chars, count ) ) 832 *37da2899SCharles.Forsyth goto Fail; 833 *37da2899SCharles.Forsyth 834 *37da2899SCharles.Forsyth Size = 1 + 1 + 2; 835 *37da2899SCharles.Forsyth if ( flags & PFR_PHY_2BYTE_CHARCODE ) 836 *37da2899SCharles.Forsyth Size += 1; 837 *37da2899SCharles.Forsyth 838 *37da2899SCharles.Forsyth if ( flags & PFR_PHY_PROPORTIONAL ) 839 *37da2899SCharles.Forsyth Size += 2; 840 *37da2899SCharles.Forsyth 841 *37da2899SCharles.Forsyth if ( flags & PFR_PHY_ASCII_CODE ) 842 *37da2899SCharles.Forsyth Size += 1; 843 *37da2899SCharles.Forsyth 844 *37da2899SCharles.Forsyth if ( flags & PFR_PHY_2BYTE_GPS_SIZE ) 845 *37da2899SCharles.Forsyth Size += 1; 846 *37da2899SCharles.Forsyth 847 *37da2899SCharles.Forsyth if ( flags & PFR_PHY_3BYTE_GPS_OFFSET ) 848 *37da2899SCharles.Forsyth Size += 1; 849 *37da2899SCharles.Forsyth 850 *37da2899SCharles.Forsyth PFR_CHECK( count * Size ); 851 *37da2899SCharles.Forsyth 852 *37da2899SCharles.Forsyth for ( n = 0; n < count; n++ ) 853 *37da2899SCharles.Forsyth { 854 *37da2899SCharles.Forsyth PFR_Char cur = &phy_font->chars[n]; 855 *37da2899SCharles.Forsyth 856 *37da2899SCharles.Forsyth 857 *37da2899SCharles.Forsyth cur->char_code = ( flags & PFR_PHY_2BYTE_CHARCODE ) 858 *37da2899SCharles.Forsyth ? PFR_NEXT_USHORT( p ) 859 *37da2899SCharles.Forsyth : PFR_NEXT_BYTE( p ); 860 *37da2899SCharles.Forsyth 861 *37da2899SCharles.Forsyth cur->advance = ( flags & PFR_PHY_PROPORTIONAL ) 862 *37da2899SCharles.Forsyth ? PFR_NEXT_SHORT( p ) 863 *37da2899SCharles.Forsyth : (FT_Int) phy_font->standard_advance; 864 *37da2899SCharles.Forsyth 865 *37da2899SCharles.Forsyth #if 0 866 *37da2899SCharles.Forsyth cur->ascii = ( flags & PFR_PHY_ASCII_CODE ) 867 *37da2899SCharles.Forsyth ? PFR_NEXT_BYTE( p ) 868 *37da2899SCharles.Forsyth : 0; 869 *37da2899SCharles.Forsyth #else 870 *37da2899SCharles.Forsyth if ( flags & PFR_PHY_ASCII_CODE ) 871 *37da2899SCharles.Forsyth p += 1; 872 *37da2899SCharles.Forsyth #endif 873 *37da2899SCharles.Forsyth cur->gps_size = ( flags & PFR_PHY_2BYTE_GPS_SIZE ) 874 *37da2899SCharles.Forsyth ? PFR_NEXT_USHORT( p ) 875 *37da2899SCharles.Forsyth : PFR_NEXT_BYTE( p ); 876 *37da2899SCharles.Forsyth 877 *37da2899SCharles.Forsyth cur->gps_offset = ( flags & PFR_PHY_3BYTE_GPS_OFFSET ) 878 *37da2899SCharles.Forsyth ? PFR_NEXT_ULONG( p ) 879 *37da2899SCharles.Forsyth : PFR_NEXT_USHORT( p ); 880 *37da2899SCharles.Forsyth } 881 *37da2899SCharles.Forsyth } 882 *37da2899SCharles.Forsyth 883 *37da2899SCharles.Forsyth /* that's it !! */ 884 *37da2899SCharles.Forsyth Fail: 885 *37da2899SCharles.Forsyth FT_FRAME_EXIT(); 886 *37da2899SCharles.Forsyth 887 *37da2899SCharles.Forsyth /* save position of bitmap info */ 888 *37da2899SCharles.Forsyth phy_font->bct_offset = FT_STREAM_POS(); 889 *37da2899SCharles.Forsyth phy_font->cursor = NULL; 890 *37da2899SCharles.Forsyth 891 *37da2899SCharles.Forsyth Exit: 892 *37da2899SCharles.Forsyth return error; 893 *37da2899SCharles.Forsyth 894 *37da2899SCharles.Forsyth Too_Short: 895 *37da2899SCharles.Forsyth error = PFR_Err_Invalid_Table; 896 *37da2899SCharles.Forsyth FT_ERROR(( "pfr_phy_font_load: invalid physical font table\n" )); 897 *37da2899SCharles.Forsyth goto Fail; 898 *37da2899SCharles.Forsyth } 899 *37da2899SCharles.Forsyth 900 *37da2899SCharles.Forsyth 901 *37da2899SCharles.Forsyth /* END */ 902