ttpload.c revision 7f08cbd7d6dcf19b8d8e4328e33032aee342e3b4
1049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/***************************************************************************/ 2049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/* */ 3049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/* ttpload.c */ 4049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/* */ 5049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/* TrueType-specific tables loader (body). */ 6049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/* */ 77f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner/* Copyright 1996-2001, 2002, 2004, 2005, 2006, 2007, 2008, 2009, 2010 by */ 8049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/* David Turner, Robert Wilhelm, and Werner Lemberg. */ 9049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/* */ 10049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/* This file is part of the FreeType project, and may only be used, */ 11049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/* modified, and distributed under the terms of the FreeType project */ 12049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ 13049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/* this file you indicate that you have read the license and */ 14049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/* understand and accept it fully. */ 15049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/* */ 16049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/***************************************************************************/ 17049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 18049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 19049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include <ft2build.h> 20049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include FT_INTERNAL_DEBUG_H 21049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include FT_INTERNAL_OBJECTS_H 22049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include FT_INTERNAL_STREAM_H 23049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include FT_TRUETYPE_TAGS_H 24049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 25049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include "ttpload.h" 26049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 27049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT 28049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include "ttgxvar.h" 29049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#endif 30049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 31049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include "tterrors.h" 32049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 33049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 34049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /*************************************************************************/ 35049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 36049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ 37049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ 38049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* messages during execution. */ 39049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 40049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#undef FT_COMPONENT 41049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define FT_COMPONENT trace_ttpload 42049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 43049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 44049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /*************************************************************************/ 45049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 46049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* <Function> */ 47049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* tt_face_load_loca */ 48049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 49049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* <Description> */ 50049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* Load the locations table. */ 51049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 52049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* <InOut> */ 53049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* face :: A handle to the target face object. */ 54049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 55049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* <Input> */ 56049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* stream :: The input stream. */ 57049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 58049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* <Return> */ 59049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* FreeType error code. 0 means success. */ 60049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 61049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_LOCAL_DEF( FT_Error ) 62049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project tt_face_load_loca( TT_Face face, 63049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Stream stream ) 64049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 65049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Error error; 66049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_ULong table_len; 670a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project FT_Int shift; 68049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 69049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 70049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* we need the size of the `glyf' table for malformed `loca' tables */ 71049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project error = face->goto_table( face, TTAG_glyf, stream, &face->glyf_len ); 720a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project 730a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project /* it is possible that a font doesn't have a glyf table at all */ 740a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project /* or its size is zero */ 750a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project if ( error == TT_Err_Table_Missing ) 760a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project face->glyf_len = 0; 770a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project else if ( error ) 78049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project goto Exit; 79049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 80049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_TRACE2(( "Locations " )); 81049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project error = face->goto_table( face, TTAG_loca, stream, &table_len ); 82049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( error ) 83049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 84049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project error = TT_Err_Locations_Missing; 85049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project goto Exit; 86049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 87049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 88049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( face->header.Index_To_Loc_Format != 0 ) 89049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 900a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project shift = 2; 910a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project 92049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( table_len >= 0x40000L ) 93049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 94295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner FT_TRACE2(( "table too large\n" )); 95049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project error = TT_Err_Invalid_Table; 96049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project goto Exit; 97049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 98295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner face->num_locations = table_len >> shift; 99049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 100049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project else 101049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1020a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project shift = 1; 1030a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project 104049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( table_len >= 0x20000L ) 105049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 106295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner FT_TRACE2(( "table too large\n" )); 107049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project error = TT_Err_Invalid_Table; 108049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project goto Exit; 109049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 110295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner face->num_locations = table_len >> shift; 1110a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project } 1120a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project 113295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner if ( face->num_locations != (FT_ULong)face->root.num_glyphs ) 1140a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project { 1150a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project FT_TRACE2(( "glyph count mismatch! loca: %d, maxp: %d\n", 1160a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project face->num_locations, face->root.num_glyphs )); 1170a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project 1180a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project /* we only handle the case where `maxp' gives a larger value */ 119295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner if ( face->num_locations < (FT_ULong)face->root.num_glyphs ) 1200a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project { 1210a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project FT_Long new_loca_len = (FT_Long)face->root.num_glyphs << shift; 1220a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project 1230a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project TT_Table entry = face->dir_tables; 1240a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project TT_Table limit = entry + face->num_tables; 1250a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project 1260a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project FT_Long pos = FT_Stream_Pos( stream ); 1270a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project FT_Long dist = 0x7FFFFFFFL; 1280a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project 1290a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project 1300a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project /* compute the distance to next table in font file */ 1310a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project for ( ; entry < limit; entry++ ) 1320a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project { 1330a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project FT_Long diff = entry->Offset - pos; 1340a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project 1350a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project 1360a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project if ( diff > 0 && diff < dist ) 1370a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project dist = diff; 1380a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project } 1390a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project 1407f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner if ( entry == limit ) 1417f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner { 1427f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner /* `loca' is the last table */ 1437f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner dist = stream->size - pos; 1447f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner } 1457f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner 1460a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project if ( new_loca_len <= dist ) 1470a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project { 148295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner face->num_locations = face->root.num_glyphs; 1490a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project table_len = new_loca_len; 1500a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project 1510a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project FT_TRACE2(( "adjusting num_locations to %d\n", 1520a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project face->num_locations )); 1530a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project } 1540a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project } 155049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 156049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 157049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* 158049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project * Extract the frame. We don't need to decompress it since 159049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project * we are able to parse it directly. 160049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project */ 161049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( FT_FRAME_EXTRACT( table_len, face->glyph_locations ) ) 162049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project goto Exit; 163049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 164049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_TRACE2(( "loaded\n" )); 165049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 166049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project Exit: 167049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return error; 168049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 169049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 170049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 171049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_LOCAL_DEF( FT_ULong ) 172049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project tt_face_get_location( TT_Face face, 173049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt gindex, 174049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt *asize ) 175049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 176049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_ULong pos1, pos2; 177049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Byte* p; 178049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Byte* p_limit; 179049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 180049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 181049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project pos1 = pos2 = 0; 182049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 183049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( gindex < face->num_locations ) 184049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 185049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( face->header.Index_To_Loc_Format != 0 ) 186049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 187049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project p = face->glyph_locations + gindex * 4; 188049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project p_limit = face->glyph_locations + face->num_locations * 4; 189049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 190049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project pos1 = FT_NEXT_ULONG( p ); 191049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project pos2 = pos1; 192049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 193049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( p + 4 <= p_limit ) 194049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project pos2 = FT_NEXT_ULONG( p ); 195049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 196049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project else 197049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 198049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project p = face->glyph_locations + gindex * 2; 199049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project p_limit = face->glyph_locations + face->num_locations * 2; 200049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 201049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project pos1 = FT_NEXT_USHORT( p ); 202049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project pos2 = pos1; 203049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 204049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( p + 2 <= p_limit ) 205049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project pos2 = FT_NEXT_USHORT( p ); 206049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 207049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project pos1 <<= 1; 208049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project pos2 <<= 1; 209049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 210049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 211049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2127f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner /* Check broken location data */ 2137f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner if ( pos1 >= face->glyf_len ) 2147f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner { 2157f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner FT_TRACE1(( "tt_face_get_location:" 2167f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner " too large offset=0x%08lx found for gid=0x%04lx," 2177f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner " exceeding the end of glyf table (0x%08lx)\n", 2187f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner pos1, gindex, face->glyf_len )); 2197f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner *asize = 0; 2207f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner return 0; 2217f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner } 2227f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner 2237f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner if ( pos2 >= face->glyf_len ) 2247f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner { 2257f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner FT_TRACE1(( "tt_face_get_location:" 2267f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner " too large offset=0x%08lx found for gid=0x%04lx," 2277f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner " truncate at the end of glyf table (0x%08lx)\n", 2287f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner pos2, gindex + 1, face->glyf_len )); 2297f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner pos2 = face->glyf_len; 2307f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner } 2317f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner 232295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner /* The `loca' table must be ordered; it refers to the length of */ 233295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner /* an entry as the difference between the current and the next */ 234295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner /* position. However, there do exist (malformed) fonts which */ 235295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner /* don't obey this rule, so we are only able to provide an */ 236295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner /* upper bound for the size. */ 2370a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project /* */ 2380a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project /* We get (intentionally) a wrong, non-zero result in case the */ 2390a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project /* `glyf' table is missing. */ 240049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( pos2 >= pos1 ) 241049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project *asize = (FT_UInt)( pos2 - pos1 ); 242049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project else 243049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project *asize = (FT_UInt)( face->glyf_len - pos1 ); 244049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 245049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return pos1; 246049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 247049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 248049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 249049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_LOCAL_DEF( void ) 250049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project tt_face_done_loca( TT_Face face ) 251049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 252049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Stream stream = face->root.stream; 253049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 254049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 255049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_FRAME_RELEASE( face->glyph_locations ); 256049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project face->num_locations = 0; 257049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 258049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 259049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 260049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 261049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /*************************************************************************/ 262049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 263049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* <Function> */ 264049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* tt_face_load_cvt */ 265049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 266049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* <Description> */ 267049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* Load the control value table into a face object. */ 268049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 269049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* <InOut> */ 270049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* face :: A handle to the target face object. */ 271049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 272049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* <Input> */ 273049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* stream :: A handle to the input stream. */ 274049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 275049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* <Return> */ 276049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* FreeType error code. 0 means success. */ 277049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 278049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_LOCAL_DEF( FT_Error ) 279049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project tt_face_load_cvt( TT_Face face, 280049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Stream stream ) 281049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 282049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#ifdef TT_USE_BYTECODE_INTERPRETER 283049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 284049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Error error; 285049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Memory memory = stream->memory; 286049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_ULong table_len; 287049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 288049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 289049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_TRACE2(( "CVT " )); 290049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 291049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project error = face->goto_table( face, TTAG_cvt, stream, &table_len ); 292049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( error ) 293049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 294295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner FT_TRACE2(( "is missing\n" )); 295049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 296049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project face->cvt_size = 0; 297049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project face->cvt = NULL; 298049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project error = TT_Err_Ok; 299049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 300049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project goto Exit; 301049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 302049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 303049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project face->cvt_size = table_len / 2; 304049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 305049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( FT_NEW_ARRAY( face->cvt, face->cvt_size ) ) 306049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project goto Exit; 307049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 308049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( FT_FRAME_ENTER( face->cvt_size * 2L ) ) 309049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project goto Exit; 310049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 311049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 312049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Short* cur = face->cvt; 313049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Short* limit = cur + face->cvt_size; 314049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 315049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3167f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner for ( ; cur < limit; cur++ ) 317049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project *cur = FT_GET_SHORT(); 318049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 319049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 320049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_FRAME_EXIT(); 321049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_TRACE2(( "loaded\n" )); 322049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 323049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT 324049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( face->doblend ) 325049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project error = tt_face_vary_cvt( face, stream ); 326049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#endif 327049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 328049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project Exit: 329049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return error; 330049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 331049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#else /* !TT_USE_BYTECODE_INTERPRETER */ 332049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 333049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UNUSED( face ); 334049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UNUSED( stream ); 335049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 336049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return TT_Err_Ok; 337049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 338049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#endif 339049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 340049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 341049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 342049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /*************************************************************************/ 343049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 344049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* <Function> */ 345049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* tt_face_load_fpgm */ 346049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 347049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* <Description> */ 348049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* Load the font program. */ 349049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 350049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* <InOut> */ 351049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* face :: A handle to the target face object. */ 352049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 353049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* <Input> */ 354049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* stream :: A handle to the input stream. */ 355049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 356049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* <Return> */ 357049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* FreeType error code. 0 means success. */ 358049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 359049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_LOCAL_DEF( FT_Error ) 360049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project tt_face_load_fpgm( TT_Face face, 361049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Stream stream ) 362049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 363049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#ifdef TT_USE_BYTECODE_INTERPRETER 364049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 365049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Error error; 366049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_ULong table_len; 367049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 368049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 369049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_TRACE2(( "Font program " )); 370049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 371049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* The font program is optional */ 372049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project error = face->goto_table( face, TTAG_fpgm, stream, &table_len ); 373049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( error ) 374049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 375049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project face->font_program = NULL; 376049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project face->font_program_size = 0; 377049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project error = TT_Err_Ok; 378049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 379295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner FT_TRACE2(( "is missing\n" )); 380049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 381049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project else 382049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 383049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project face->font_program_size = table_len; 384049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( FT_FRAME_EXTRACT( table_len, face->font_program ) ) 385049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project goto Exit; 386049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 387049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_TRACE2(( "loaded, %12d bytes\n", face->font_program_size )); 388049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 389049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 390049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project Exit: 391049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return error; 392049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 393049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#else /* !TT_USE_BYTECODE_INTERPRETER */ 394049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 395049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UNUSED( face ); 396049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UNUSED( stream ); 397049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 398049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return TT_Err_Ok; 399049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 400049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#endif 401049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 402049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 403049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 404049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /*************************************************************************/ 405049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 406049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* <Function> */ 407049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* tt_face_load_prep */ 408049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 409049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* <Description> */ 410049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* Load the cvt program. */ 411049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 412049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* <InOut> */ 413049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* face :: A handle to the target face object. */ 414049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 415049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* <Input> */ 416049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* stream :: A handle to the input stream. */ 417049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 418049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* <Return> */ 419049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* FreeType error code. 0 means success. */ 420049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 421049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_LOCAL_DEF( FT_Error ) 422049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project tt_face_load_prep( TT_Face face, 423049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Stream stream ) 424049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 425049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#ifdef TT_USE_BYTECODE_INTERPRETER 426049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 427049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Error error; 428049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_ULong table_len; 429049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 430049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 431049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_TRACE2(( "Prep program " )); 432049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 433049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project error = face->goto_table( face, TTAG_prep, stream, &table_len ); 434049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( error ) 435049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 436049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project face->cvt_program = NULL; 437049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project face->cvt_program_size = 0; 438049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project error = TT_Err_Ok; 439049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 440295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner FT_TRACE2(( "is missing\n" )); 441049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 442049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project else 443049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 444049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project face->cvt_program_size = table_len; 445049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( FT_FRAME_EXTRACT( table_len, face->cvt_program ) ) 446049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project goto Exit; 447049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 448049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_TRACE2(( "loaded, %12d bytes\n", face->cvt_program_size )); 449049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 450049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 451049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project Exit: 452049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return error; 453049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 454049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#else /* !TT_USE_BYTECODE_INTERPRETER */ 455049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 456049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UNUSED( face ); 457049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UNUSED( stream ); 458049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 459049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return TT_Err_Ok; 460049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 461049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#endif 462049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 463049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 464049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 465049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /*************************************************************************/ 466049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 467049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* <Function> */ 468049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* tt_face_load_hdmx */ 469049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 470049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* <Description> */ 471049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* Load the `hdmx' table into the face object. */ 472049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 473049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* <Input> */ 474049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* face :: A handle to the target face object. */ 475049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 476049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* stream :: A handle to the input stream. */ 477049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 478049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* <Return> */ 479049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* FreeType error code. 0 means success. */ 480049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 481049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 482049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_LOCAL_DEF( FT_Error ) 483049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project tt_face_load_hdmx( TT_Face face, 484049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Stream stream ) 485049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 486049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Error error; 487049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Memory memory = stream->memory; 488049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt version, nn, num_records; 489049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_ULong table_size, record_size; 490049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Byte* p; 491049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Byte* limit; 492049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 493049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 494049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* this table is optional */ 495049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project error = face->goto_table( face, TTAG_hdmx, stream, &table_size ); 496049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( error || table_size < 8 ) 497049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return TT_Err_Ok; 498049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 499049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( FT_FRAME_EXTRACT( table_size, face->hdmx_table ) ) 500049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project goto Exit; 501049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 502049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project p = face->hdmx_table; 503049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project limit = p + table_size; 504049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 505049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project version = FT_NEXT_USHORT( p ); 506049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project num_records = FT_NEXT_USHORT( p ); 507049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project record_size = FT_NEXT_ULONG( p ); 508049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 509049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* The maximum number of bytes in an hdmx device record is the */ 510049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* maximum number of glyphs + 2; this is 0xFFFF + 2; this is */ 511049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* the reason why `record_size' is a long (which we read as */ 512049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* unsigned long for convenience). In practice, two bytes */ 513049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* sufficient to hold the size value. */ 514049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 515049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* There are at least two fonts, HANNOM-A and HANNOM-B version */ 516049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* 2.0 (2005), which get this wrong: The upper two bytes of */ 517049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* the size value are set to 0xFF instead of 0x00. We catch */ 518049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* and fix this. */ 519049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 520049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( record_size >= 0xFFFF0000UL ) 521049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project record_size &= 0xFFFFU; 522049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 523049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* The limit for `num_records' is a heuristic value. */ 524049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 525049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( version != 0 || num_records > 255 || record_size > 0x10001L ) 526049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 527049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project error = TT_Err_Invalid_File_Format; 528049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project goto Fail; 529049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 530049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 531049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( FT_NEW_ARRAY( face->hdmx_record_sizes, num_records ) ) 532049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project goto Fail; 533049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 534049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project for ( nn = 0; nn < num_records; nn++ ) 535049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 536049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( p + record_size > limit ) 537049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project break; 538049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 539049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project face->hdmx_record_sizes[nn] = p[0]; 540049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project p += record_size; 541049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 542049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 543049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project face->hdmx_record_count = nn; 544049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project face->hdmx_table_size = table_size; 545049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project face->hdmx_record_size = record_size; 546049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 547049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project Exit: 548049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return error; 549049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 550049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project Fail: 551049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_FRAME_RELEASE( face->hdmx_table ); 552049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project face->hdmx_table_size = 0; 553049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project goto Exit; 554049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 555049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 556049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 557049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_LOCAL_DEF( void ) 558049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project tt_face_free_hdmx( TT_Face face ) 559049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 560049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Stream stream = face->root.stream; 561049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Memory memory = stream->memory; 562049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 563049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 564049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_FREE( face->hdmx_record_sizes ); 565049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_FRAME_RELEASE( face->hdmx_table ); 566049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 567049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 568049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 569049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /*************************************************************************/ 570049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 571049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* Return the advance width table for a given pixel size if it is found */ 572049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* in the font's `hdmx' table (if any). */ 573049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 574049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_LOCAL_DEF( FT_Byte* ) 575049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project tt_face_get_device_metrics( TT_Face face, 576049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt ppem, 577049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt gindex ) 578049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 579049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt nn; 580049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Byte* result = NULL; 581049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_ULong record_size = face->hdmx_record_size; 582049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Byte* record = face->hdmx_table + 8; 583049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 584049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 585049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project for ( nn = 0; nn < face->hdmx_record_count; nn++ ) 586049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( face->hdmx_record_sizes[nn] == ppem ) 587049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 588049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project gindex += 2; 589049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( gindex < record_size ) 590049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project result = record + nn * record_size + gindex; 591049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project break; 592049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 593049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 594049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return result; 595049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 596049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 597049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 598049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/* END */ 599