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/* */ 7a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang/* Copyright 1996-2002, 2004-2013 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 */ 75a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang if ( FT_ERR_EQ( error, 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 { 84a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang error = FT_THROW( 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" )); 95a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang error = FT_THROW( 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" )); 107a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang error = FT_THROW( 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 113c3ee10bfa1f76a18500b487de9c85757375b48f3David 'Digit' Turner if ( face->num_locations != (FT_ULong)face->root.num_glyphs + 1 ) 1140a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project { 1150a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project FT_TRACE2(( "glyph count mismatch! loca: %d, maxp: %d\n", 116c3ee10bfa1f76a18500b487de9c85757375b48f3David 'Digit' Turner face->num_locations - 1, 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 */ 119c3ee10bfa1f76a18500b487de9c85757375b48f3David 'Digit' Turner if ( face->num_locations <= (FT_ULong)face->root.num_glyphs ) 1200a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project { 121c3ee10bfa1f76a18500b487de9c85757375b48f3David 'Digit' Turner FT_Long new_loca_len = 122c3ee10bfa1f76a18500b487de9c85757375b48f3David 'Digit' Turner ( (FT_Long)( face->root.num_glyphs ) + 1 ) << shift; 1230a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project 1240a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project TT_Table entry = face->dir_tables; 1250a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project TT_Table limit = entry + face->num_tables; 1260a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project 1270a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project FT_Long pos = FT_Stream_Pos( stream ); 1280a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project FT_Long dist = 0x7FFFFFFFL; 1290a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project 1300a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project 1310a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project /* compute the distance to next table in font file */ 1320a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project for ( ; entry < limit; entry++ ) 1330a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project { 1340a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project FT_Long diff = entry->Offset - pos; 1350a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project 1360a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project 1370a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project if ( diff > 0 && diff < dist ) 1380a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project dist = diff; 1390a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project } 1400a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project 1418583905b8952672a083f21fd8945f329b98aa35bDavid 'Digit' Turner if ( entry == limit ) 1428583905b8952672a083f21fd8945f329b98aa35bDavid 'Digit' Turner { 1438583905b8952672a083f21fd8945f329b98aa35bDavid 'Digit' Turner /* `loca' is the last table */ 1448583905b8952672a083f21fd8945f329b98aa35bDavid 'Digit' Turner dist = stream->size - pos; 1458583905b8952672a083f21fd8945f329b98aa35bDavid 'Digit' Turner } 1468583905b8952672a083f21fd8945f329b98aa35bDavid 'Digit' Turner 1470a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project if ( new_loca_len <= dist ) 1480a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project { 149c3ee10bfa1f76a18500b487de9c85757375b48f3David 'Digit' Turner face->num_locations = face->root.num_glyphs + 1; 1500a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project table_len = new_loca_len; 1510a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project 1520a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project FT_TRACE2(( "adjusting num_locations to %d\n", 1530a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project face->num_locations )); 1540a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project } 1550a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project } 156049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 157049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 158049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* 159049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project * Extract the frame. We don't need to decompress it since 160049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project * we are able to parse it directly. 161049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project */ 162049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( FT_FRAME_EXTRACT( table_len, face->glyph_locations ) ) 163049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project goto Exit; 164049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 165049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_TRACE2(( "loaded\n" )); 166049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 167049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project Exit: 168049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return error; 169049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 170049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 171049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 172049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_LOCAL_DEF( FT_ULong ) 173049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project tt_face_get_location( TT_Face face, 174049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt gindex, 175049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt *asize ) 176049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 177049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_ULong pos1, pos2; 178049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Byte* p; 179049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Byte* p_limit; 180049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 181049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 182049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project pos1 = pos2 = 0; 183049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 184049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( gindex < face->num_locations ) 185049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 186049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( face->header.Index_To_Loc_Format != 0 ) 187049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 188049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project p = face->glyph_locations + gindex * 4; 189049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project p_limit = face->glyph_locations + face->num_locations * 4; 190049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 191049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project pos1 = FT_NEXT_ULONG( p ); 192049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project pos2 = pos1; 193049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 194049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( p + 4 <= p_limit ) 195049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project pos2 = FT_NEXT_ULONG( p ); 196049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 197049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project else 198049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 199049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project p = face->glyph_locations + gindex * 2; 200049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project p_limit = face->glyph_locations + face->num_locations * 2; 201049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 202049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project pos1 = FT_NEXT_USHORT( p ); 203049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project pos2 = pos1; 204049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 205049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( p + 2 <= p_limit ) 206049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project pos2 = FT_NEXT_USHORT( p ); 207049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 208049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project pos1 <<= 1; 209049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project pos2 <<= 1; 210049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 211049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 212049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2138583905b8952672a083f21fd8945f329b98aa35bDavid 'Digit' Turner /* Check broken location data */ 214e3b631da8034f7c6ecc6d809cd9e46d306215c32Xianzhu Wang if ( pos1 > face->glyf_len ) 2158583905b8952672a083f21fd8945f329b98aa35bDavid 'Digit' Turner { 2168583905b8952672a083f21fd8945f329b98aa35bDavid 'Digit' Turner FT_TRACE1(( "tt_face_get_location:" 217e3b631da8034f7c6ecc6d809cd9e46d306215c32Xianzhu Wang " too large offset=0x%08lx found for gid=0x%04lx," 218e3b631da8034f7c6ecc6d809cd9e46d306215c32Xianzhu Wang " exceeding the end of glyf table (0x%08lx)\n", 219e3b631da8034f7c6ecc6d809cd9e46d306215c32Xianzhu Wang pos1, gindex, face->glyf_len )); 2208583905b8952672a083f21fd8945f329b98aa35bDavid 'Digit' Turner *asize = 0; 2218583905b8952672a083f21fd8945f329b98aa35bDavid 'Digit' Turner return 0; 2228583905b8952672a083f21fd8945f329b98aa35bDavid 'Digit' Turner } 2238583905b8952672a083f21fd8945f329b98aa35bDavid 'Digit' Turner 224e3b631da8034f7c6ecc6d809cd9e46d306215c32Xianzhu Wang if ( pos2 > face->glyf_len ) 2258583905b8952672a083f21fd8945f329b98aa35bDavid 'Digit' Turner { 2268583905b8952672a083f21fd8945f329b98aa35bDavid 'Digit' Turner FT_TRACE1(( "tt_face_get_location:" 227e3b631da8034f7c6ecc6d809cd9e46d306215c32Xianzhu Wang " too large offset=0x%08lx found for gid=0x%04lx," 228e3b631da8034f7c6ecc6d809cd9e46d306215c32Xianzhu Wang " truncate at the end of glyf table (0x%08lx)\n", 229e3b631da8034f7c6ecc6d809cd9e46d306215c32Xianzhu Wang pos2, gindex + 1, face->glyf_len )); 2308583905b8952672a083f21fd8945f329b98aa35bDavid 'Digit' Turner pos2 = face->glyf_len; 2318583905b8952672a083f21fd8945f329b98aa35bDavid 'Digit' Turner } 2328583905b8952672a083f21fd8945f329b98aa35bDavid 'Digit' Turner 233295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner /* The `loca' table must be ordered; it refers to the length of */ 234295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner /* an entry as the difference between the current and the next */ 235295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner /* position. However, there do exist (malformed) fonts which */ 236295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner /* don't obey this rule, so we are only able to provide an */ 237295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner /* upper bound for the size. */ 2380a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project /* */ 2390a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project /* We get (intentionally) a wrong, non-zero result in case the */ 2400a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project /* `glyf' table is missing. */ 241049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( pos2 >= pos1 ) 242049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project *asize = (FT_UInt)( pos2 - pos1 ); 243049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project else 244049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project *asize = (FT_UInt)( face->glyf_len - pos1 ); 245049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 246049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return pos1; 247049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 248049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 249049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 250049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_LOCAL_DEF( void ) 251049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project tt_face_done_loca( TT_Face face ) 252049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 253049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Stream stream = face->root.stream; 254049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 255049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 256049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_FRAME_RELEASE( face->glyph_locations ); 257049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project face->num_locations = 0; 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 /* */ 264049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* <Function> */ 265049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* tt_face_load_cvt */ 266049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 267049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* <Description> */ 268049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* Load the control value table into a face object. */ 269049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 270049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* <InOut> */ 271049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* face :: A handle to the target face object. */ 272049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 273049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* <Input> */ 274049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* stream :: A handle to the input stream. */ 275049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 276049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* <Return> */ 277049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* FreeType error code. 0 means success. */ 278049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 279049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_LOCAL_DEF( FT_Error ) 280049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project tt_face_load_cvt( TT_Face face, 281049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Stream stream ) 282049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 283049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#ifdef TT_USE_BYTECODE_INTERPRETER 284049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 285049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Error error; 286049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Memory memory = stream->memory; 287049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_ULong table_len; 288049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 289049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 290049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_TRACE2(( "CVT " )); 291049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 292049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project error = face->goto_table( face, TTAG_cvt, stream, &table_len ); 293049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( error ) 294049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 295295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner FT_TRACE2(( "is missing\n" )); 296049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 297049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project face->cvt_size = 0; 298049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project face->cvt = NULL; 299a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang error = FT_Err_Ok; 300049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 301049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project goto Exit; 302049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 303049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 304049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project face->cvt_size = table_len / 2; 305049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 306049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( FT_NEW_ARRAY( face->cvt, face->cvt_size ) ) 307049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project goto Exit; 308049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 309049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( FT_FRAME_ENTER( face->cvt_size * 2L ) ) 310049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project goto Exit; 311049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 312049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 313049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Short* cur = face->cvt; 314049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Short* limit = cur + face->cvt_size; 315049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 316049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3178583905b8952672a083f21fd8945f329b98aa35bDavid 'Digit' Turner for ( ; cur < limit; cur++ ) 318049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project *cur = FT_GET_SHORT(); 319049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 320049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 321049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_FRAME_EXIT(); 322049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_TRACE2(( "loaded\n" )); 323049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 324049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT 325049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( face->doblend ) 326049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project error = tt_face_vary_cvt( face, stream ); 327049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#endif 328049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 329049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project Exit: 330049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return error; 331049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 332049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#else /* !TT_USE_BYTECODE_INTERPRETER */ 333049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 334049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UNUSED( face ); 335049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UNUSED( stream ); 336049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 337a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang return FT_Err_Ok; 338049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 339049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#endif 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 /* */ 345049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* <Function> */ 346049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* tt_face_load_fpgm */ 347049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 348049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* <Description> */ 349049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* Load the font program. */ 350049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 351049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* <InOut> */ 352049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* face :: A handle to the target face object. */ 353049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 354049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* <Input> */ 355049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* stream :: A handle to the input stream. */ 356049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 357049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* <Return> */ 358049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* FreeType error code. 0 means success. */ 359049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 360049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_LOCAL_DEF( FT_Error ) 361049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project tt_face_load_fpgm( TT_Face face, 362049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Stream stream ) 363049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 364049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#ifdef TT_USE_BYTECODE_INTERPRETER 365049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 366049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Error error; 367049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_ULong table_len; 368049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 369049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 370049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_TRACE2(( "Font program " )); 371049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 372049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* The font program is optional */ 373049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project error = face->goto_table( face, TTAG_fpgm, stream, &table_len ); 374049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( error ) 375049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 376049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project face->font_program = NULL; 377049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project face->font_program_size = 0; 378a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang error = FT_Err_Ok; 379049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 380295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner FT_TRACE2(( "is missing\n" )); 381049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 382049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project else 383049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 384049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project face->font_program_size = table_len; 385049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( FT_FRAME_EXTRACT( table_len, face->font_program ) ) 386049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project goto Exit; 387049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 388049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_TRACE2(( "loaded, %12d bytes\n", face->font_program_size )); 389049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 390049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 391049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project Exit: 392049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return error; 393049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 394049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#else /* !TT_USE_BYTECODE_INTERPRETER */ 395049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 396049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UNUSED( face ); 397049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UNUSED( stream ); 398049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 399a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang return FT_Err_Ok; 400049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 401049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#endif 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 /* */ 407049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* <Function> */ 408049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* tt_face_load_prep */ 409049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 410049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* <Description> */ 411049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* Load the cvt program. */ 412049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 413049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* <InOut> */ 414049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* face :: A handle to the target face object. */ 415049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 416049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* <Input> */ 417049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* stream :: A handle to the input stream. */ 418049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 419049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* <Return> */ 420049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* FreeType error code. 0 means success. */ 421049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 422049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_LOCAL_DEF( FT_Error ) 423049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project tt_face_load_prep( TT_Face face, 424049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Stream stream ) 425049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 426049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#ifdef TT_USE_BYTECODE_INTERPRETER 427049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 428049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Error error; 429049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_ULong table_len; 430049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 431049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 432049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_TRACE2(( "Prep program " )); 433049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 434049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project error = face->goto_table( face, TTAG_prep, stream, &table_len ); 435049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( error ) 436049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 437049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project face->cvt_program = NULL; 438049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project face->cvt_program_size = 0; 439a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang error = FT_Err_Ok; 440049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 441295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner FT_TRACE2(( "is missing\n" )); 442049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 443049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project else 444049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 445049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project face->cvt_program_size = table_len; 446049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( FT_FRAME_EXTRACT( table_len, face->cvt_program ) ) 447049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project goto Exit; 448049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 449049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_TRACE2(( "loaded, %12d bytes\n", face->cvt_program_size )); 450049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 451049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 452049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project Exit: 453049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return error; 454049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 455049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#else /* !TT_USE_BYTECODE_INTERPRETER */ 456049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 457049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UNUSED( face ); 458049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UNUSED( stream ); 459049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 460a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang return FT_Err_Ok; 461049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 462049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#endif 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 /* */ 468049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* <Function> */ 469049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* tt_face_load_hdmx */ 470049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 471049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* <Description> */ 472049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* Load the `hdmx' table into the face object. */ 473049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 474049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* <Input> */ 475049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* face :: A handle to the target face object. */ 476049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 477049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* stream :: A handle to the input stream. */ 478049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 479049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* <Return> */ 480049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* FreeType error code. 0 means success. */ 481049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 482049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 483049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_LOCAL_DEF( FT_Error ) 484049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project tt_face_load_hdmx( TT_Face face, 485049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Stream stream ) 486049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 487049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Error error; 488049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Memory memory = stream->memory; 489049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt version, nn, num_records; 490049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_ULong table_size, record_size; 491049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Byte* p; 492049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Byte* limit; 493049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 494049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 495049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* this table is optional */ 496049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project error = face->goto_table( face, TTAG_hdmx, stream, &table_size ); 497049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( error || table_size < 8 ) 498a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang return FT_Err_Ok; 499049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 500049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( FT_FRAME_EXTRACT( table_size, face->hdmx_table ) ) 501049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project goto Exit; 502049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 503049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project p = face->hdmx_table; 504049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project limit = p + table_size; 505049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 506049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project version = FT_NEXT_USHORT( p ); 507049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project num_records = FT_NEXT_USHORT( p ); 508049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project record_size = FT_NEXT_ULONG( p ); 509049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 510049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* The maximum number of bytes in an hdmx device record is the */ 511049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* maximum number of glyphs + 2; this is 0xFFFF + 2; this is */ 512049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* the reason why `record_size' is a long (which we read as */ 513049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* unsigned long for convenience). In practice, two bytes */ 514049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* sufficient to hold the size value. */ 515049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 516049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* There are at least two fonts, HANNOM-A and HANNOM-B version */ 517049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* 2.0 (2005), which get this wrong: The upper two bytes of */ 518049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* the size value are set to 0xFF instead of 0x00. We catch */ 519049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* and fix this. */ 520049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 521049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( record_size >= 0xFFFF0000UL ) 522049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project record_size &= 0xFFFFU; 523049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 524049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* The limit for `num_records' is a heuristic value. */ 525049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 526049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( version != 0 || num_records > 255 || record_size > 0x10001L ) 527049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 528a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang error = FT_THROW( Invalid_File_Format ); 529049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project goto Fail; 530049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 531049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 532049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( FT_NEW_ARRAY( face->hdmx_record_sizes, num_records ) ) 533049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project goto Fail; 534049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 535049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project for ( nn = 0; nn < num_records; nn++ ) 536049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 537049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( p + record_size > limit ) 538049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project break; 539049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 540049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project face->hdmx_record_sizes[nn] = p[0]; 541049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project p += record_size; 542049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 543049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 544049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project face->hdmx_record_count = nn; 545049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project face->hdmx_table_size = table_size; 546049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project face->hdmx_record_size = record_size; 547049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 548049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project Exit: 549049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return error; 550049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 551049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project Fail: 552049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_FRAME_RELEASE( face->hdmx_table ); 553049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project face->hdmx_table_size = 0; 554049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project goto Exit; 555049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 556049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 557049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 558049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_LOCAL_DEF( void ) 559049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project tt_face_free_hdmx( TT_Face face ) 560049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 561049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Stream stream = face->root.stream; 562049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Memory memory = stream->memory; 563049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 564049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 565049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_FREE( face->hdmx_record_sizes ); 566049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_FRAME_RELEASE( face->hdmx_table ); 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 /* */ 572049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* Return the advance width table for a given pixel size if it is found */ 573049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* in the font's `hdmx' table (if any). */ 574049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 575049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_LOCAL_DEF( FT_Byte* ) 576049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project tt_face_get_device_metrics( TT_Face face, 577049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt ppem, 578049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt gindex ) 579049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 580049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt nn; 581049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Byte* result = NULL; 582049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_ULong record_size = face->hdmx_record_size; 583049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Byte* record = face->hdmx_table + 8; 584049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 585049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 586049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project for ( nn = 0; nn < face->hdmx_record_count; nn++ ) 587049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( face->hdmx_record_sizes[nn] == ppem ) 588049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 589049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project gindex += 2; 590049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( gindex < record_size ) 591049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project result = record + nn * record_size + gindex; 592049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project break; 593049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 594049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 595049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return result; 596049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 597049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 598049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 599049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/* END */ 600