1ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/***************************************************************************/ 2ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* */ 3ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* ttload.c */ 4ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* */ 5ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* Load the basic TrueType tables, i.e., tables that can be either in */ 6ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* TTF or OTF fonts (body). */ 7ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* */ 8e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov/* Copyright 1996-2010, 2012-2014 by */ 9ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* David Turner, Robert Wilhelm, and Werner Lemberg. */ 10ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* */ 11ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* This file is part of the FreeType project, and may only be used, */ 12ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* modified, and distributed under the terms of the FreeType project */ 13ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ 14ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* this file you indicate that you have read the license and */ 15ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* understand and accept it fully. */ 16ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* */ 17ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/***************************************************************************/ 18ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 19ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 20e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov#include <ft2build.h> 21e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov#include FT_INTERNAL_DEBUG_H 22e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov#include FT_INTERNAL_STREAM_H 23e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov#include FT_TRUETYPE_TAGS_H 24ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "ttload.h" 25ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 26ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "sferrors.h" 27ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 28ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 29ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 30ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 31ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ 32ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ 33ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* messages during execution. */ 34ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 35ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#undef FT_COMPONENT 36ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define FT_COMPONENT trace_ttload 37ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 38ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 39ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 40ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 41ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* <Function> */ 42ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* tt_face_lookup_table */ 43ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 44ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* <Description> */ 45ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Looks for a TrueType table by name. */ 46ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 47ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* <Input> */ 48ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* face :: A face object handle. */ 49ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 50ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* tag :: The searched tag. */ 51ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 52ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* <Return> */ 53ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* A pointer to the table directory entry. 0 if not found. */ 54ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 55ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_LOCAL_DEF( TT_Table ) 56ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov tt_face_lookup_table( TT_Face face, 57ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ULong tag ) 58ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 59ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov TT_Table entry; 60ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov TT_Table limit; 61ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#ifdef FT_DEBUG_LEVEL_TRACE 62ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Bool zero_length = FALSE; 63ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif 64ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 65ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 66ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_TRACE4(( "tt_face_lookup_table: %08p, `%c%c%c%c' -- ", 67ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov face, 68ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov (FT_Char)( tag >> 24 ), 69ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov (FT_Char)( tag >> 16 ), 70ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov (FT_Char)( tag >> 8 ), 71ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov (FT_Char)( tag ) )); 72ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 73ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov entry = face->dir_tables; 74ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov limit = entry + face->num_tables; 75ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 76ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for ( ; entry < limit; entry++ ) 77ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 78ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* For compatibility with Windows, we consider */ 79ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* zero-length tables the same as missing tables. */ 80ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( entry->Tag == tag ) 81ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 82ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( entry->Length != 0 ) 83ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 84ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_TRACE4(( "found table.\n" )); 85ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return entry; 86ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 87ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#ifdef FT_DEBUG_LEVEL_TRACE 88ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov zero_length = TRUE; 89ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif 90ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 91ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 92ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 93ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#ifdef FT_DEBUG_LEVEL_TRACE 94ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( zero_length ) 95ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_TRACE4(( "ignoring empty table\n" )); 96ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else 97ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_TRACE4(( "could not find table\n" )); 98ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif 99ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 100ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return NULL; 101ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 102ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 103ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 104ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 105ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 106ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* <Function> */ 107ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* tt_face_goto_table */ 108ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 109ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* <Description> */ 110ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Looks for a TrueType table by name, then seek a stream to it. */ 111ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 112ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* <Input> */ 113ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* face :: A face object handle. */ 114ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 115ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* tag :: The searched tag. */ 116ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 117ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* stream :: The stream to seek when the table is found. */ 118ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 119ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* <Output> */ 120ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* length :: The length of the table if found, undefined otherwise. */ 121ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 122ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* <Return> */ 123ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* FreeType error code. 0 means success. */ 124ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 125ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_LOCAL_DEF( FT_Error ) 126ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov tt_face_goto_table( TT_Face face, 127ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ULong tag, 128ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Stream stream, 129ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ULong* length ) 130ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 131ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov TT_Table table; 132e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov FT_Error error; 133ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 134ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 135ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov table = tt_face_lookup_table( face, tag ); 136ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( table ) 137ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 138ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( length ) 139ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *length = table->Length; 140ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 141ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( FT_STREAM_SEEK( table->Offset ) ) 142ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Exit; 143ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 144ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else 145ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = FT_THROW( Table_Missing ); 146ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 147ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Exit: 148ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return error; 149ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 150ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 151ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 152ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Here, we */ 153ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 154ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* - check that `num_tables' is valid (and adjust it if necessary) */ 155ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 156ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* - look for a `head' table, check its size, and parse it to check */ 157ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* whether its `magic' field is correctly set */ 158ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 159ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* - errors (except errors returned by stream handling) */ 160ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 161ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* SFNT_Err_Unknown_File_Format: */ 162ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* no table is defined in directory, it is not sfnt-wrapped */ 163ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* data */ 164ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* SFNT_Err_Table_Missing: */ 165ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* table directory is valid, but essential tables */ 166ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* (head/bhed/SING) are missing */ 167ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 168ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov static FT_Error 169ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov check_table_dir( SFNT_Header sfnt, 170ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Stream stream ) 171ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 172ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Error error; 173ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UShort nn, valid_entries = 0; 174ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt has_head = 0, has_sing = 0, has_meta = 0; 175ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ULong offset = sfnt->offset + 12; 176ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 177ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov static const FT_Frame_Field table_dir_entry_fields[] = 178ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 179ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#undef FT_STRUCTURE 180ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define FT_STRUCTURE TT_TableRec 181ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 182ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FRAME_START( 16 ), 183ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FRAME_ULONG( Tag ), 184ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FRAME_ULONG( CheckSum ), 185ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FRAME_ULONG( Offset ), 186ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FRAME_ULONG( Length ), 187ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FRAME_END 188ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov }; 189ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 190ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 191ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( FT_STREAM_SEEK( offset ) ) 192ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Exit; 193ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 194ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for ( nn = 0; nn < sfnt->num_tables; nn++ ) 195ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 196ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov TT_TableRec table; 197ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 198ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 199ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( FT_STREAM_READ_FIELDS( table_dir_entry_fields, &table ) ) 200ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 201ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov nn--; 202ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_TRACE2(( "check_table_dir:" 203ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov " can read only %d table%s in font (instead of %d)\n", 204ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov nn, nn == 1 ? "" : "s", sfnt->num_tables )); 205ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov sfnt->num_tables = nn; 206ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov break; 207ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 208ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 209ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* we ignore invalid tables */ 210e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov 211e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov /* table.Offset + table.Length > stream->size ? */ 212e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov if ( table.Length > stream->size || 213e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov table.Offset > stream->size - table.Length ) 214ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 215ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_TRACE2(( "check_table_dir: table entry %d invalid\n", nn )); 216ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov continue; 217ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 218ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else 219ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov valid_entries++; 220ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 221ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( table.Tag == TTAG_head || table.Tag == TTAG_bhed ) 222ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 223ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt32 magic; 224ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 225ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 226ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#ifndef TT_CONFIG_OPTION_EMBEDDED_BITMAPS 227ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( table.Tag == TTAG_head ) 228ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif 229ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov has_head = 1; 230ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 231ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* 232ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * The table length should be 0x36, but certain font tools make it 233ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * 0x38, so we will just check that it is greater. 234ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * 235ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * Note that according to the specification, the table must be 236ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * padded to 32-bit lengths, but this doesn't apply to the value of 237ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * its `Length' field! 238ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * 239ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov */ 240ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( table.Length < 0x36 ) 241ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 242e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov FT_TRACE2(( "check_table_dir:" 243e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov " `head' or `bhed' table too small\n" )); 244ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = FT_THROW( Table_Missing ); 245ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Exit; 246ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 247ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 248ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( FT_STREAM_SEEK( table.Offset + 12 ) || 249ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_READ_ULONG( magic ) ) 250ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Exit; 251ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 252ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( magic != 0x5F0F3CF5UL ) 253ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_TRACE2(( "check_table_dir:" 254e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov " invalid magic number in `head' or `bhed' table\n")); 255ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 256ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( FT_STREAM_SEEK( offset + ( nn + 1 ) * 16 ) ) 257ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Exit; 258ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 259ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else if ( table.Tag == TTAG_SING ) 260ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov has_sing = 1; 261ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else if ( table.Tag == TTAG_META ) 262ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov has_meta = 1; 263ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 264ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 265ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov sfnt->num_tables = valid_entries; 266ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 267ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( sfnt->num_tables == 0 ) 268ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 269ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_TRACE2(( "check_table_dir: no tables found\n" )); 270ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = FT_THROW( Unknown_File_Format ); 271ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Exit; 272ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 273ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 274ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* if `sing' and `meta' tables are present, there is no `head' table */ 275ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( has_head || ( has_sing && has_meta ) ) 276ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 277ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = FT_Err_Ok; 278ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Exit; 279ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 280ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else 281ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 282ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_TRACE2(( "check_table_dir:" )); 283ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS 284ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_TRACE2(( " neither `head', `bhed', nor `sing' table found\n" )); 285ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#else 286ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_TRACE2(( " neither `head' nor `sing' table found\n" )); 287ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif 288ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = FT_THROW( Table_Missing ); 289ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 290ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 291ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Exit: 292ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return error; 293ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 294ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 295ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 296ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 297ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 298ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* <Function> */ 299ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* tt_face_load_font_dir */ 300ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 301ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* <Description> */ 302ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Loads the header of a SFNT font file. */ 303ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 304ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* <Input> */ 305ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* face :: A handle to the target face object. */ 306ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 307ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* stream :: The input stream. */ 308ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 309ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* <Output> */ 310ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* sfnt :: The SFNT header. */ 311ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 312ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* <Return> */ 313ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* FreeType error code. 0 means success. */ 314ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 315ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* <Note> */ 316ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* The stream cursor must be at the beginning of the font directory. */ 317ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 318ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_LOCAL_DEF( FT_Error ) 319ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov tt_face_load_font_dir( TT_Face face, 320ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Stream stream ) 321ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 322ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov SFNT_HeaderRec sfnt; 323ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Error error; 324ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Memory memory = stream->memory; 325ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov TT_TableRec* entry; 326ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Int nn; 327ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 328ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov static const FT_Frame_Field offset_table_fields[] = 329ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 330ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#undef FT_STRUCTURE 331ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define FT_STRUCTURE SFNT_HeaderRec 332ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 333ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FRAME_START( 8 ), 334ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FRAME_USHORT( num_tables ), 335ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FRAME_USHORT( search_range ), 336ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FRAME_USHORT( entry_selector ), 337ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FRAME_USHORT( range_shift ), 338ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FRAME_END 339ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov }; 340ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 341ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 342ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_TRACE2(( "tt_face_load_font_dir: %08p\n", face )); 343ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 344ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* read the offset table */ 345ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 346ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov sfnt.offset = FT_STREAM_POS(); 347ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 348ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( FT_READ_ULONG( sfnt.format_tag ) || 349ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_STREAM_READ_FIELDS( offset_table_fields, &sfnt ) ) 350ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Exit; 351ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 352ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* many fonts don't have these fields set correctly */ 353ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#if 0 354ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( sfnt.search_range != 1 << ( sfnt.entry_selector + 4 ) || 355ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov sfnt.search_range + sfnt.range_shift != sfnt.num_tables << 4 ) 356ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FT_THROW( Unknown_File_Format ); 357ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif 358ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 359ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* load the table directory */ 360ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 361ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_TRACE2(( "-- Number of tables: %10u\n", sfnt.num_tables )); 362ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_TRACE2(( "-- Format version: 0x%08lx\n", sfnt.format_tag )); 363ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 364ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( sfnt.format_tag != TTAG_OTTO ) 365ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 366ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* check first */ 367ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = check_table_dir( &sfnt, stream ); 368ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( error ) 369ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 370ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_TRACE2(( "tt_face_load_font_dir:" 371ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov " invalid table directory for TrueType\n" )); 372ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 373ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Exit; 374ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 375ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 376ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 377ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov face->num_tables = sfnt.num_tables; 378ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov face->format_tag = sfnt.format_tag; 379ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 380ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( FT_QNEW_ARRAY( face->dir_tables, face->num_tables ) ) 381ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Exit; 382ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 383ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( FT_STREAM_SEEK( sfnt.offset + 12 ) || 384ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FRAME_ENTER( face->num_tables * 16L ) ) 385ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Exit; 386ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 387ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov entry = face->dir_tables; 388ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 389ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_TRACE2(( "\n" 390ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov " tag offset length checksum\n" 391ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov " ----------------------------------\n" )); 392ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 393ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for ( nn = 0; nn < sfnt.num_tables; nn++ ) 394ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 395ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov entry->Tag = FT_GET_TAG4(); 396ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov entry->CheckSum = FT_GET_ULONG(); 397e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov entry->Offset = FT_GET_ULONG(); 398e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov entry->Length = FT_GET_ULONG(); 399ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 400ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* ignore invalid tables */ 401e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov 402e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov /* entry->Offset + entry->Length > stream->size ? */ 403e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov if ( entry->Length > stream->size || 404e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov entry->Offset > stream->size - entry->Length ) 405ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov continue; 406ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else 407ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 408ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_TRACE2(( " %c%c%c%c %08lx %08lx %08lx\n", 409ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov (FT_Char)( entry->Tag >> 24 ), 410ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov (FT_Char)( entry->Tag >> 16 ), 411ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov (FT_Char)( entry->Tag >> 8 ), 412ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov (FT_Char)( entry->Tag ), 413ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov entry->Offset, 414ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov entry->Length, 415ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov entry->CheckSum )); 416ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov entry++; 417ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 418ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 419ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 420ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FRAME_EXIT(); 421ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 422ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_TRACE2(( "table directory loaded\n\n" )); 423ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 424ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Exit: 425ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return error; 426ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 427ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 428ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 429ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 430ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 431ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* <Function> */ 432ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* tt_face_load_any */ 433ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 434ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* <Description> */ 435ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Loads any font table into client memory. */ 436ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 437ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* <Input> */ 438ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* face :: The face object to look for. */ 439ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 440ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* tag :: The tag of table to load. Use the value 0 if you want */ 441ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* to access the whole font file, else set this parameter */ 442ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* to a valid TrueType table tag that you can forge with */ 443ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* the MAKE_TT_TAG macro. */ 444ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 445ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* offset :: The starting offset in the table (or the file if */ 446ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* tag == 0). */ 447ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 448ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* length :: The address of the decision variable: */ 449ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 450ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* If length == NULL: */ 451ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Loads the whole table. Returns an error if */ 452ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* `offset' == 0! */ 453ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 454ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* If *length == 0: */ 455ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Exits immediately; returning the length of the given */ 456ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* table or of the font file, depending on the value of */ 457ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* `tag'. */ 458ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 459ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* If *length != 0: */ 460ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Loads the next `length' bytes of table or font, */ 461ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* starting at offset `offset' (in table or font too). */ 462ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 463ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* <Output> */ 464ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* buffer :: The address of target buffer. */ 465ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 466ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* <Return> */ 467ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* FreeType error code. 0 means success. */ 468ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 469ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_LOCAL_DEF( FT_Error ) 470ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov tt_face_load_any( TT_Face face, 471ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ULong tag, 472ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Long offset, 473ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte* buffer, 474ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ULong* length ) 475ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 476ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Error error; 477ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Stream stream; 478ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov TT_Table table; 479ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ULong size; 480ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 481ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 482ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( tag != 0 ) 483ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 484ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* look for tag in font directory */ 485ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov table = tt_face_lookup_table( face, tag ); 486ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( !table ) 487ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 488ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = FT_THROW( Table_Missing ); 489ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Exit; 490ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 491ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 492ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov offset += table->Offset; 493ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov size = table->Length; 494ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 495ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else 496ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* tag == 0 -- the user wants to access the font file directly */ 497ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov size = face->root.stream->size; 498ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 499ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( length && *length == 0 ) 500ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 501ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *length = size; 502ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 503ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FT_Err_Ok; 504ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 505ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 506ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( length ) 507ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov size = *length; 508ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 509ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov stream = face->root.stream; 510ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* the `if' is syntactic sugar for picky compilers */ 511ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( FT_STREAM_READ_AT( offset, buffer, size ) ) 512ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Exit; 513ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 514ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Exit: 515ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return error; 516ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 517ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 518ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 519ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 520ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 521ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* <Function> */ 522ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* tt_face_load_generic_header */ 523ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 524ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* <Description> */ 525ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Loads the TrueType table `head' or `bhed'. */ 526ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 527ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* <Input> */ 528ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* face :: A handle to the target face object. */ 529ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 530ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* stream :: The input stream. */ 531ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 532ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* <Return> */ 533ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* FreeType error code. 0 means success. */ 534ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 535ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov static FT_Error 536ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov tt_face_load_generic_header( TT_Face face, 537ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Stream stream, 538ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ULong tag ) 539ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 540ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Error error; 541ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov TT_Header* header; 542ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 543ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov static const FT_Frame_Field header_fields[] = 544ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 545ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#undef FT_STRUCTURE 546ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define FT_STRUCTURE TT_Header 547ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 548ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FRAME_START( 54 ), 549ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FRAME_ULONG ( Table_Version ), 550ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FRAME_ULONG ( Font_Revision ), 551ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FRAME_LONG ( CheckSum_Adjust ), 552ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FRAME_LONG ( Magic_Number ), 553ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FRAME_USHORT( Flags ), 554ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FRAME_USHORT( Units_Per_EM ), 555ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FRAME_LONG ( Created[0] ), 556ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FRAME_LONG ( Created[1] ), 557ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FRAME_LONG ( Modified[0] ), 558ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FRAME_LONG ( Modified[1] ), 559ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FRAME_SHORT ( xMin ), 560ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FRAME_SHORT ( yMin ), 561ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FRAME_SHORT ( xMax ), 562ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FRAME_SHORT ( yMax ), 563ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FRAME_USHORT( Mac_Style ), 564ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FRAME_USHORT( Lowest_Rec_PPEM ), 565ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FRAME_SHORT ( Font_Direction ), 566ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FRAME_SHORT ( Index_To_Loc_Format ), 567ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FRAME_SHORT ( Glyph_Data_Format ), 568ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FRAME_END 569ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov }; 570ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 571ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 572ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = face->goto_table( face, tag, stream, 0 ); 573ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( error ) 574ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Exit; 575ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 576ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov header = &face->header; 577ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 578ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( FT_STREAM_READ_FIELDS( header_fields, header ) ) 579ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Exit; 580ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 581ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_TRACE3(( "Units per EM: %4u\n", header->Units_Per_EM )); 582ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_TRACE3(( "IndexToLoc: %4d\n", header->Index_To_Loc_Format )); 583ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 584ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Exit: 585ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return error; 586ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 587ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 588ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 589ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_LOCAL_DEF( FT_Error ) 590ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov tt_face_load_head( TT_Face face, 591ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Stream stream ) 592ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 593ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return tt_face_load_generic_header( face, stream, TTAG_head ); 594ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 595ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 596ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 597ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS 598ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 599ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_LOCAL_DEF( FT_Error ) 600ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov tt_face_load_bhed( TT_Face face, 601ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Stream stream ) 602ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 603ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return tt_face_load_generic_header( face, stream, TTAG_bhed ); 604ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 605ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 606ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */ 607ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 608ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 609ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 610ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 611ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* <Function> */ 612ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* tt_face_load_max_profile */ 613ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 614ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* <Description> */ 615ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Loads the maximum profile into a face object. */ 616ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 617ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* <Input> */ 618ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* face :: A handle to the target face object. */ 619ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 620ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* stream :: The input stream. */ 621ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 622ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* <Return> */ 623ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* FreeType error code. 0 means success. */ 624ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 625ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_LOCAL_DEF( FT_Error ) 626ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov tt_face_load_maxp( TT_Face face, 627ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Stream stream ) 628ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 629ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Error error; 630ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov TT_MaxProfile* maxProfile = &face->max_profile; 631ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 632ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov static const FT_Frame_Field maxp_fields[] = 633ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 634ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#undef FT_STRUCTURE 635ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define FT_STRUCTURE TT_MaxProfile 636ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 637ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FRAME_START( 6 ), 638ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FRAME_LONG ( version ), 639ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FRAME_USHORT( numGlyphs ), 640ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FRAME_END 641ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov }; 642ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 643ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov static const FT_Frame_Field maxp_fields_extra[] = 644ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 645ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FRAME_START( 26 ), 646ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FRAME_USHORT( maxPoints ), 647ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FRAME_USHORT( maxContours ), 648ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FRAME_USHORT( maxCompositePoints ), 649ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FRAME_USHORT( maxCompositeContours ), 650ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FRAME_USHORT( maxZones ), 651ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FRAME_USHORT( maxTwilightPoints ), 652ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FRAME_USHORT( maxStorage ), 653ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FRAME_USHORT( maxFunctionDefs ), 654ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FRAME_USHORT( maxInstructionDefs ), 655ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FRAME_USHORT( maxStackElements ), 656ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FRAME_USHORT( maxSizeOfInstructions ), 657ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FRAME_USHORT( maxComponentElements ), 658ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FRAME_USHORT( maxComponentDepth ), 659ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FRAME_END 660ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov }; 661ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 662ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 663ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = face->goto_table( face, TTAG_maxp, stream, 0 ); 664ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( error ) 665ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Exit; 666ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 667ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( FT_STREAM_READ_FIELDS( maxp_fields, maxProfile ) ) 668ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Exit; 669ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 670ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov maxProfile->maxPoints = 0; 671ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov maxProfile->maxContours = 0; 672ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov maxProfile->maxCompositePoints = 0; 673ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov maxProfile->maxCompositeContours = 0; 674ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov maxProfile->maxZones = 0; 675ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov maxProfile->maxTwilightPoints = 0; 676ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov maxProfile->maxStorage = 0; 677ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov maxProfile->maxFunctionDefs = 0; 678ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov maxProfile->maxInstructionDefs = 0; 679ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov maxProfile->maxStackElements = 0; 680ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov maxProfile->maxSizeOfInstructions = 0; 681ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov maxProfile->maxComponentElements = 0; 682ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov maxProfile->maxComponentDepth = 0; 683ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 684ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( maxProfile->version >= 0x10000L ) 685ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 686ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( FT_STREAM_READ_FIELDS( maxp_fields_extra, maxProfile ) ) 687ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Exit; 688ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 689ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* XXX: an adjustment that is necessary to load certain */ 690ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* broken fonts like `Keystrokes MT' :-( */ 691ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 692ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* We allocate 64 function entries by default when */ 693ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* the maxFunctionDefs value is smaller. */ 694ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 695ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( maxProfile->maxFunctionDefs < 64 ) 696ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov maxProfile->maxFunctionDefs = 64; 697ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 698ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* we add 4 phantom points later */ 699ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( maxProfile->maxTwilightPoints > ( 0xFFFFU - 4 ) ) 700ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 701ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_TRACE0(( "tt_face_load_maxp:" 702ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov " too much twilight points in `maxp' table;\n" 703ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov " " 704ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov " some glyphs might be rendered incorrectly\n" )); 705ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 706ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov maxProfile->maxTwilightPoints = 0xFFFFU - 4; 707ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 708ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 709ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* we arbitrarily limit recursion to avoid stack exhaustion */ 710ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( maxProfile->maxComponentDepth > 100 ) 711ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 712ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_TRACE0(( "tt_face_load_maxp:" 713ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov " abnormally large component depth (%d) set to 100\n", 714ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov maxProfile->maxComponentDepth )); 715ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov maxProfile->maxComponentDepth = 100; 716ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 717ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 718ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 719ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_TRACE3(( "numGlyphs: %u\n", maxProfile->numGlyphs )); 720ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 721ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Exit: 722ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return error; 723ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 724ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 725ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 726ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 727ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 728ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* <Function> */ 729ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* tt_face_load_name */ 730ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 731ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* <Description> */ 732ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Loads the name records. */ 733ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 734ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* <Input> */ 735ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* face :: A handle to the target face object. */ 736ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 737ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* stream :: The input stream. */ 738ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 739ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* <Return> */ 740ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* FreeType error code. 0 means success. */ 741ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 742ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_LOCAL_DEF( FT_Error ) 743ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov tt_face_load_name( TT_Face face, 744ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Stream stream ) 745ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 746ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Error error; 747ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Memory memory = stream->memory; 748ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ULong table_pos, table_len; 749ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ULong storage_start, storage_limit; 750ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt count; 751ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov TT_NameTable table; 752ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 753ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov static const FT_Frame_Field name_table_fields[] = 754ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 755ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#undef FT_STRUCTURE 756ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define FT_STRUCTURE TT_NameTableRec 757ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 758ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FRAME_START( 6 ), 759ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FRAME_USHORT( format ), 760ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FRAME_USHORT( numNameRecords ), 761ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FRAME_USHORT( storageOffset ), 762ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FRAME_END 763ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov }; 764ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 765ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov static const FT_Frame_Field name_record_fields[] = 766ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 767ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#undef FT_STRUCTURE 768ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define FT_STRUCTURE TT_NameEntryRec 769ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 770ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* no FT_FRAME_START */ 771ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FRAME_USHORT( platformID ), 772ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FRAME_USHORT( encodingID ), 773ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FRAME_USHORT( languageID ), 774ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FRAME_USHORT( nameID ), 775ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FRAME_USHORT( stringLength ), 776ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FRAME_USHORT( stringOffset ), 777ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FRAME_END 778ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov }; 779ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 780ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 781ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov table = &face->name_table; 782ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov table->stream = stream; 783ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 784ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = face->goto_table( face, TTAG_name, stream, &table_len ); 785ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( error ) 786ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Exit; 787ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 788ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov table_pos = FT_STREAM_POS(); 789ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 790ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 791ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( FT_STREAM_READ_FIELDS( name_table_fields, table ) ) 792ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Exit; 793ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 794ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Some popular Asian fonts have an invalid `storageOffset' value */ 795ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* (it should be at least "6 + 12*num_names"). However, the string */ 796ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* offsets, computed as "storageOffset + entry->stringOffset", are */ 797ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* valid pointers within the name table... */ 798ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 799ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* We thus can't check `storageOffset' right now. */ 800ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 801ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov storage_start = table_pos + 6 + 12*table->numNameRecords; 802ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov storage_limit = table_pos + table_len; 803ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 804ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( storage_start > storage_limit ) 805ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 806ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ERROR(( "tt_face_load_name: invalid `name' table\n" )); 807ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = FT_THROW( Name_Table_Missing ); 808ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Exit; 809ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 810ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 811ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Allocate the array of name records. */ 812ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov count = table->numNameRecords; 813ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov table->numNameRecords = 0; 814ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 815ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( FT_NEW_ARRAY( table->names, count ) || 816ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FRAME_ENTER( count * 12 ) ) 817ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Exit; 818ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 819ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Load the name records and determine how much storage is needed */ 820ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* to hold the strings themselves. */ 821ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 822ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov TT_NameEntryRec* entry = table->names; 823ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 824ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 825ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for ( ; count > 0; count-- ) 826ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 827ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( FT_STREAM_READ_FIELDS( name_record_fields, entry ) ) 828ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov continue; 829ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 830ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* check that the name is not empty */ 831ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( entry->stringLength == 0 ) 832ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov continue; 833ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 834ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* check that the name string is within the table */ 835ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov entry->stringOffset += table_pos + table->storageOffset; 836ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( entry->stringOffset < storage_start || 837ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov entry->stringOffset + entry->stringLength > storage_limit ) 838ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 839ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* invalid entry - ignore it */ 840ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov entry->stringOffset = 0; 841ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov entry->stringLength = 0; 842ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov continue; 843ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 844ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 845ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov entry++; 846ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 847ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 848ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov table->numNameRecords = (FT_UInt)( entry - table->names ); 849ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 850ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 851ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FRAME_EXIT(); 852ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 853ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* everything went well, update face->num_names */ 854ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov face->num_names = (FT_UShort) table->numNameRecords; 855ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 856ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Exit: 857ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return error; 858ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 859ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 860ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 861ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 862ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 863ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* <Function> */ 864ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* tt_face_free_names */ 865ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 866ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* <Description> */ 867ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Frees the name records. */ 868ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 869ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* <Input> */ 870ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* face :: A handle to the target face object. */ 871ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 872ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_LOCAL_DEF( void ) 873ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov tt_face_free_name( TT_Face face ) 874ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 875ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Memory memory = face->root.driver->root.memory; 876ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov TT_NameTable table = &face->name_table; 877ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov TT_NameEntry entry = table->names; 878ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt count = table->numNameRecords; 879ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 880ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 881ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( table->names ) 882ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 883ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for ( ; count > 0; count--, entry++ ) 884ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 885ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FREE( entry->string ); 886ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov entry->stringLength = 0; 887ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 888ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 889ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* free strings table */ 890ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FREE( table->names ); 891ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 892ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 893ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov table->numNameRecords = 0; 894ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov table->format = 0; 895ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov table->storageOffset = 0; 896ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 897ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 898ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 899ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 900ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 901ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* <Function> */ 902ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* tt_face_load_cmap */ 903ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 904ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* <Description> */ 905ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Loads the cmap directory in a face object. The cmaps themselves */ 906ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* are loaded on demand in the `ttcmap.c' module. */ 907ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 908ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* <Input> */ 909ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* face :: A handle to the target face object. */ 910ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 911ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* stream :: A handle to the input stream. */ 912ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 913ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* <Return> */ 914ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* FreeType error code. 0 means success. */ 915ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 916ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 917ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_LOCAL_DEF( FT_Error ) 918ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov tt_face_load_cmap( TT_Face face, 919ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Stream stream ) 920ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 921ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Error error; 922ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 923ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 924ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = face->goto_table( face, TTAG_cmap, stream, &face->cmap_size ); 925ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( error ) 926ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Exit; 927ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 928ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( FT_FRAME_EXTRACT( face->cmap_size, face->cmap_table ) ) 929ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov face->cmap_size = 0; 930ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 931ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Exit: 932ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return error; 933ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 934ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 935ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 936ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 937ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 938ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 939ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* <Function> */ 940ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* tt_face_load_os2 */ 941ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 942ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* <Description> */ 943ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Loads the OS2 table. */ 944ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 945ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* <Input> */ 946ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* face :: A handle to the target face object. */ 947ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 948ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* stream :: A handle to the input stream. */ 949ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 950ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* <Return> */ 951ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* FreeType error code. 0 means success. */ 952ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 953ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_LOCAL_DEF( FT_Error ) 954ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov tt_face_load_os2( TT_Face face, 955ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Stream stream ) 956ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 957ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Error error; 958ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov TT_OS2* os2; 959ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 960ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov static const FT_Frame_Field os2_fields[] = 961ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 962ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#undef FT_STRUCTURE 963ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define FT_STRUCTURE TT_OS2 964ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 965ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FRAME_START( 78 ), 966ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FRAME_USHORT( version ), 967ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FRAME_SHORT ( xAvgCharWidth ), 968ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FRAME_USHORT( usWeightClass ), 969ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FRAME_USHORT( usWidthClass ), 970ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FRAME_SHORT ( fsType ), 971ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FRAME_SHORT ( ySubscriptXSize ), 972ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FRAME_SHORT ( ySubscriptYSize ), 973ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FRAME_SHORT ( ySubscriptXOffset ), 974ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FRAME_SHORT ( ySubscriptYOffset ), 975ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FRAME_SHORT ( ySuperscriptXSize ), 976ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FRAME_SHORT ( ySuperscriptYSize ), 977ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FRAME_SHORT ( ySuperscriptXOffset ), 978ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FRAME_SHORT ( ySuperscriptYOffset ), 979ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FRAME_SHORT ( yStrikeoutSize ), 980ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FRAME_SHORT ( yStrikeoutPosition ), 981ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FRAME_SHORT ( sFamilyClass ), 982ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FRAME_BYTE ( panose[0] ), 983ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FRAME_BYTE ( panose[1] ), 984ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FRAME_BYTE ( panose[2] ), 985ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FRAME_BYTE ( panose[3] ), 986ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FRAME_BYTE ( panose[4] ), 987ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FRAME_BYTE ( panose[5] ), 988ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FRAME_BYTE ( panose[6] ), 989ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FRAME_BYTE ( panose[7] ), 990ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FRAME_BYTE ( panose[8] ), 991ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FRAME_BYTE ( panose[9] ), 992ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FRAME_ULONG ( ulUnicodeRange1 ), 993ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FRAME_ULONG ( ulUnicodeRange2 ), 994ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FRAME_ULONG ( ulUnicodeRange3 ), 995ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FRAME_ULONG ( ulUnicodeRange4 ), 996ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FRAME_BYTE ( achVendID[0] ), 997ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FRAME_BYTE ( achVendID[1] ), 998ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FRAME_BYTE ( achVendID[2] ), 999ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FRAME_BYTE ( achVendID[3] ), 1000ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1001ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FRAME_USHORT( fsSelection ), 1002ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FRAME_USHORT( usFirstCharIndex ), 1003ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FRAME_USHORT( usLastCharIndex ), 1004ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FRAME_SHORT ( sTypoAscender ), 1005ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FRAME_SHORT ( sTypoDescender ), 1006ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FRAME_SHORT ( sTypoLineGap ), 1007ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FRAME_USHORT( usWinAscent ), 1008ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FRAME_USHORT( usWinDescent ), 1009ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FRAME_END 1010ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov }; 1011ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1012e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov /* `OS/2' version 1 and newer */ 1013e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov static const FT_Frame_Field os2_fields_extra1[] = 1014ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1015ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FRAME_START( 8 ), 1016ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FRAME_ULONG( ulCodePageRange1 ), 1017ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FRAME_ULONG( ulCodePageRange2 ), 1018ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FRAME_END 1019ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov }; 1020ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1021e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov /* `OS/2' version 2 and newer */ 1022ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov static const FT_Frame_Field os2_fields_extra2[] = 1023ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1024ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FRAME_START( 10 ), 1025ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FRAME_SHORT ( sxHeight ), 1026ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FRAME_SHORT ( sCapHeight ), 1027ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FRAME_USHORT( usDefaultChar ), 1028ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FRAME_USHORT( usBreakChar ), 1029ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FRAME_USHORT( usMaxContext ), 1030ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FRAME_END 1031ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov }; 1032ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1033e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov /* `OS/2' version 5 and newer */ 1034e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov static const FT_Frame_Field os2_fields_extra5[] = 1035e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov { 1036e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov FT_FRAME_START( 4 ), 1037e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov FT_FRAME_USHORT( usLowerOpticalPointSize ), 1038e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov FT_FRAME_USHORT( usUpperOpticalPointSize ), 1039e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov FT_FRAME_END 1040e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov }; 1041e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov 1042ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1043ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* We now support old Mac fonts where the OS/2 table doesn't */ 1044ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* exist. Simply put, we set the `version' field to 0xFFFF */ 1045ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* and test this value each time we need to access the table. */ 1046ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = face->goto_table( face, TTAG_OS2, stream, 0 ); 1047ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( error ) 1048ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Exit; 1049ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1050ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov os2 = &face->os2; 1051ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1052ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( FT_STREAM_READ_FIELDS( os2_fields, os2 ) ) 1053ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Exit; 1054ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1055e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov os2->ulCodePageRange1 = 0; 1056e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov os2->ulCodePageRange2 = 0; 1057e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov os2->sxHeight = 0; 1058e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov os2->sCapHeight = 0; 1059e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov os2->usDefaultChar = 0; 1060e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov os2->usBreakChar = 0; 1061e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov os2->usMaxContext = 0; 1062e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov os2->usLowerOpticalPointSize = 0; 1063e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov os2->usUpperOpticalPointSize = 0xFFFF; 1064ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1065ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( os2->version >= 0x0001 ) 1066ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1067ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* only version 1 tables */ 1068e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov if ( FT_STREAM_READ_FIELDS( os2_fields_extra1, os2 ) ) 1069ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Exit; 1070ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1071ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( os2->version >= 0x0002 ) 1072ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1073ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* only version 2 tables */ 1074ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( FT_STREAM_READ_FIELDS( os2_fields_extra2, os2 ) ) 1075ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Exit; 1076e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov 1077e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov if ( os2->version >= 0x0005 ) 1078e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov { 1079e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov /* only version 5 tables */ 1080e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov if ( FT_STREAM_READ_FIELDS( os2_fields_extra5, os2 ) ) 1081e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov goto Exit; 1082e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov } 1083ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1084ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1085ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1086ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_TRACE3(( "sTypoAscender: %4d\n", os2->sTypoAscender )); 1087ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_TRACE3(( "sTypoDescender: %4d\n", os2->sTypoDescender )); 1088ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_TRACE3(( "usWinAscent: %4u\n", os2->usWinAscent )); 1089ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_TRACE3(( "usWinDescent: %4u\n", os2->usWinDescent )); 1090ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_TRACE3(( "fsSelection: 0x%2x\n", os2->fsSelection )); 1091ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1092ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Exit: 1093e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov return error; 1094ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1095ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1096ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1097ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 1098ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 1099ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* <Function> */ 1100ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* tt_face_load_postscript */ 1101ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 1102ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* <Description> */ 1103ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Loads the Postscript table. */ 1104ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 1105ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* <Input> */ 1106ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* face :: A handle to the target face object. */ 1107ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 1108ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* stream :: A handle to the input stream. */ 1109ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 1110ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* <Return> */ 1111ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* FreeType error code. 0 means success. */ 1112ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 1113ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_LOCAL_DEF( FT_Error ) 1114ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov tt_face_load_post( TT_Face face, 1115ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Stream stream ) 1116ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1117ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Error error; 1118ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov TT_Postscript* post = &face->postscript; 1119ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1120ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov static const FT_Frame_Field post_fields[] = 1121ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1122ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#undef FT_STRUCTURE 1123ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define FT_STRUCTURE TT_Postscript 1124ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1125ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FRAME_START( 32 ), 1126ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FRAME_ULONG( FormatType ), 1127ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FRAME_ULONG( italicAngle ), 1128ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FRAME_SHORT( underlinePosition ), 1129ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FRAME_SHORT( underlineThickness ), 1130ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FRAME_ULONG( isFixedPitch ), 1131ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FRAME_ULONG( minMemType42 ), 1132ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FRAME_ULONG( maxMemType42 ), 1133ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FRAME_ULONG( minMemType1 ), 1134ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FRAME_ULONG( maxMemType1 ), 1135ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FRAME_END 1136ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov }; 1137ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1138ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1139ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = face->goto_table( face, TTAG_post, stream, 0 ); 1140ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( error ) 1141ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return error; 1142ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1143ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( FT_STREAM_READ_FIELDS( post_fields, post ) ) 1144ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return error; 1145ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1146ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* we don't load the glyph names, we do that in another */ 1147ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* module (ttpost). */ 1148ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1149ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_TRACE3(( "FormatType: 0x%x\n", post->FormatType )); 1150ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_TRACE3(( "isFixedPitch: %s\n", post->isFixedPitch 1151ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ? " yes" : " no" )); 1152ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1153ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FT_Err_Ok; 1154ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1155ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1156ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1157ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 1158ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 1159ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* <Function> */ 1160ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* tt_face_load_pclt */ 1161ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 1162ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* <Description> */ 1163ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Loads the PCL 5 Table. */ 1164ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 1165ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* <Input> */ 1166ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* face :: A handle to the target face object. */ 1167ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 1168ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* stream :: A handle to the input stream. */ 1169ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 1170ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* <Return> */ 1171ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* FreeType error code. 0 means success. */ 1172ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 1173ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_LOCAL_DEF( FT_Error ) 1174ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov tt_face_load_pclt( TT_Face face, 1175ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Stream stream ) 1176ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1177ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov static const FT_Frame_Field pclt_fields[] = 1178ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1179ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#undef FT_STRUCTURE 1180ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define FT_STRUCTURE TT_PCLT 1181ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1182ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FRAME_START( 54 ), 1183ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FRAME_ULONG ( Version ), 1184ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FRAME_ULONG ( FontNumber ), 1185ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FRAME_USHORT( Pitch ), 1186ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FRAME_USHORT( xHeight ), 1187ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FRAME_USHORT( Style ), 1188ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FRAME_USHORT( TypeFamily ), 1189ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FRAME_USHORT( CapHeight ), 1190e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov FT_FRAME_USHORT( SymbolSet ), 1191ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FRAME_BYTES ( TypeFace, 16 ), 1192ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FRAME_BYTES ( CharacterComplement, 8 ), 1193ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FRAME_BYTES ( FileName, 6 ), 1194ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FRAME_CHAR ( StrokeWeight ), 1195ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FRAME_CHAR ( WidthType ), 1196ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FRAME_BYTE ( SerifStyle ), 1197ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FRAME_BYTE ( Reserved ), 1198ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FRAME_END 1199ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov }; 1200ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1201ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Error error; 1202ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov TT_PCLT* pclt = &face->pclt; 1203ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1204ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1205ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* optional table */ 1206ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = face->goto_table( face, TTAG_PCLT, stream, 0 ); 1207ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( error ) 1208ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Exit; 1209ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1210ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( FT_STREAM_READ_FIELDS( pclt_fields, pclt ) ) 1211ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Exit; 1212ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1213ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Exit: 1214ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return error; 1215ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1216ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1217ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1218ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 1219ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 1220ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* <Function> */ 1221ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* tt_face_load_gasp */ 1222ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 1223ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* <Description> */ 1224ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Loads the `gasp' table into a face object. */ 1225ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 1226ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* <Input> */ 1227ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* face :: A handle to the target face object. */ 1228ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 1229ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* stream :: The input stream. */ 1230ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 1231ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* <Return> */ 1232ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* FreeType error code. 0 means success. */ 1233ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 1234ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_LOCAL_DEF( FT_Error ) 1235ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov tt_face_load_gasp( TT_Face face, 1236ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Stream stream ) 1237ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1238ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Error error; 1239ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Memory memory = stream->memory; 1240ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1241ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt j,num_ranges; 1242ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov TT_GaspRange gaspranges = NULL; 1243ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1244ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1245ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* the gasp table is optional */ 1246ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = face->goto_table( face, TTAG_gasp, stream, 0 ); 1247ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( error ) 1248ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Exit; 1249ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1250ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( FT_FRAME_ENTER( 4L ) ) 1251ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Exit; 1252ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1253ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov face->gasp.version = FT_GET_USHORT(); 1254ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov face->gasp.numRanges = FT_GET_USHORT(); 1255ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1256ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FRAME_EXIT(); 1257ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1258ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* only support versions 0 and 1 of the table */ 1259ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( face->gasp.version >= 2 ) 1260ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1261ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov face->gasp.numRanges = 0; 1262ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = FT_THROW( Invalid_Table ); 1263ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Exit; 1264ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1265ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1266ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov num_ranges = face->gasp.numRanges; 1267ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_TRACE3(( "numRanges: %u\n", num_ranges )); 1268ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1269ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( FT_QNEW_ARRAY( face->gasp.gaspRanges, num_ranges ) || 1270ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FRAME_ENTER( num_ranges * 4L ) ) 1271ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Exit; 1272ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1273ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov gaspranges = face->gasp.gaspRanges; 1274ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1275ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for ( j = 0; j < num_ranges; j++ ) 1276ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1277ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov gaspranges[j].maxPPEM = FT_GET_USHORT(); 1278ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov gaspranges[j].gaspFlag = FT_GET_USHORT(); 1279ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1280ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_TRACE3(( "gaspRange %d: rangeMaxPPEM %5d, rangeGaspBehavior 0x%x\n", 1281ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov j, 1282ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov gaspranges[j].maxPPEM, 1283ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov gaspranges[j].gaspFlag )); 1284ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1285ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1286ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FRAME_EXIT(); 1287ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1288ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Exit: 1289ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return error; 1290ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1291ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1292ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1293ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* END */ 1294