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