ttpload.c revision 295ffce55e0198e7a9f7d46b33f5c2b4147bf821
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/* */ 7295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner/* Copyright 1996-2001, 2002, 2004, 2005, 2006, 2007, 2008, 2009 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 1400a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project if ( new_loca_len <= dist ) 1410a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project { 142295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner face->num_locations = face->root.num_glyphs; 1430a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project table_len = new_loca_len; 1440a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project 1450a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project FT_TRACE2(( "adjusting num_locations to %d\n", 1460a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project face->num_locations )); 1470a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project } 1480a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project } 149049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 150049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 151049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* 152049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project * Extract the frame. We don't need to decompress it since 153049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project * we are able to parse it directly. 154049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project */ 155049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( FT_FRAME_EXTRACT( table_len, face->glyph_locations ) ) 156049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project goto Exit; 157049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 158049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_TRACE2(( "loaded\n" )); 159049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 160049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project Exit: 161049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return error; 162049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 163049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 164049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 165049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_LOCAL_DEF( FT_ULong ) 166049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project tt_face_get_location( TT_Face face, 167049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt gindex, 168049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt *asize ) 169049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 170049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_ULong pos1, pos2; 171049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Byte* p; 172049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Byte* p_limit; 173049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 174049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 175049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project pos1 = pos2 = 0; 176049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 177049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( gindex < face->num_locations ) 178049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 179049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( face->header.Index_To_Loc_Format != 0 ) 180049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 181049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project p = face->glyph_locations + gindex * 4; 182049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project p_limit = face->glyph_locations + face->num_locations * 4; 183049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 184049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project pos1 = FT_NEXT_ULONG( p ); 185049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project pos2 = pos1; 186049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 187049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( p + 4 <= p_limit ) 188049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project pos2 = FT_NEXT_ULONG( p ); 189049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 190049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project else 191049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 192049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project p = face->glyph_locations + gindex * 2; 193049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project p_limit = face->glyph_locations + face->num_locations * 2; 194049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 195049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project pos1 = FT_NEXT_USHORT( p ); 196049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project pos2 = pos1; 197049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 198049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( p + 2 <= p_limit ) 199049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project pos2 = FT_NEXT_USHORT( p ); 200049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 201049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project pos1 <<= 1; 202049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project pos2 <<= 1; 203049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 204049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 205049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 206295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner /* The `loca' table must be ordered; it refers to the length of */ 207295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner /* an entry as the difference between the current and the next */ 208295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner /* position. However, there do exist (malformed) fonts which */ 209295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner /* don't obey this rule, so we are only able to provide an */ 210295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner /* upper bound for the size. */ 2110a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project /* */ 2120a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project /* We get (intentionally) a wrong, non-zero result in case the */ 2130a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project /* `glyf' table is missing. */ 214049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( pos2 >= pos1 ) 215049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project *asize = (FT_UInt)( pos2 - pos1 ); 216049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project else 217049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project *asize = (FT_UInt)( face->glyf_len - pos1 ); 218049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 219049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return pos1; 220049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 221049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 222049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 223049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_LOCAL_DEF( void ) 224049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project tt_face_done_loca( TT_Face face ) 225049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 226049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Stream stream = face->root.stream; 227049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 228049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 229049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_FRAME_RELEASE( face->glyph_locations ); 230049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project face->num_locations = 0; 231049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 232049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 233049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 234049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 235049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /*************************************************************************/ 236049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 237049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* <Function> */ 238049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* tt_face_load_cvt */ 239049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 240049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* <Description> */ 241049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* Load the control value table into a face object. */ 242049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 243049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* <InOut> */ 244049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* face :: A handle to the target face object. */ 245049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 246049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* <Input> */ 247049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* stream :: A handle to the input stream. */ 248049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 249049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* <Return> */ 250049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* FreeType error code. 0 means success. */ 251049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 252049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_LOCAL_DEF( FT_Error ) 253049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project tt_face_load_cvt( TT_Face face, 254049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Stream stream ) 255049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 256049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#ifdef TT_USE_BYTECODE_INTERPRETER 257049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 258049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Error error; 259049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Memory memory = stream->memory; 260049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_ULong table_len; 261049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 262049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 263049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_TRACE2(( "CVT " )); 264049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 265049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project error = face->goto_table( face, TTAG_cvt, stream, &table_len ); 266049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( error ) 267049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 268295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner FT_TRACE2(( "is missing\n" )); 269049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 270049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project face->cvt_size = 0; 271049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project face->cvt = NULL; 272049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project error = TT_Err_Ok; 273049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 274049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project goto Exit; 275049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 276049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 277049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project face->cvt_size = table_len / 2; 278049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 279049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( FT_NEW_ARRAY( face->cvt, face->cvt_size ) ) 280049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project goto Exit; 281049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 282049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( FT_FRAME_ENTER( face->cvt_size * 2L ) ) 283049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project goto Exit; 284049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 285049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 286049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Short* cur = face->cvt; 287049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Short* limit = cur + face->cvt_size; 288049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 289049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 290049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project for ( ; cur < limit; cur++ ) 291049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project *cur = FT_GET_SHORT(); 292049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 293049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 294049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_FRAME_EXIT(); 295049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_TRACE2(( "loaded\n" )); 296049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 297049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT 298049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( face->doblend ) 299049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project error = tt_face_vary_cvt( face, stream ); 300049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#endif 301049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 302049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project Exit: 303049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return error; 304049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 305049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#else /* !TT_USE_BYTECODE_INTERPRETER */ 306049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 307049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UNUSED( face ); 308049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UNUSED( stream ); 309049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 310049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return TT_Err_Ok; 311049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 312049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#endif 313049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 314049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 315049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 316049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /*************************************************************************/ 317049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 318049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* <Function> */ 319049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* tt_face_load_fpgm */ 320049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 321049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* <Description> */ 322049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* Load the font program. */ 323049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 324049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* <InOut> */ 325049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* face :: A handle to the target face object. */ 326049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 327049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* <Input> */ 328049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* stream :: A handle to the input stream. */ 329049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 330049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* <Return> */ 331049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* FreeType error code. 0 means success. */ 332049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 333049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_LOCAL_DEF( FT_Error ) 334049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project tt_face_load_fpgm( TT_Face face, 335049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Stream stream ) 336049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 337049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#ifdef TT_USE_BYTECODE_INTERPRETER 338049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 339049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Error error; 340049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_ULong table_len; 341049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 342049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 343049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_TRACE2(( "Font program " )); 344049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 345049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* The font program is optional */ 346049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project error = face->goto_table( face, TTAG_fpgm, stream, &table_len ); 347049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( error ) 348049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 349049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project face->font_program = NULL; 350049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project face->font_program_size = 0; 351049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project error = TT_Err_Ok; 352049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 353295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner FT_TRACE2(( "is missing\n" )); 354049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 355049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project else 356049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 357049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project face->font_program_size = table_len; 358049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( FT_FRAME_EXTRACT( table_len, face->font_program ) ) 359049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project goto Exit; 360049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 361049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_TRACE2(( "loaded, %12d bytes\n", face->font_program_size )); 362049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 363049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 364049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project Exit: 365049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return error; 366049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 367049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#else /* !TT_USE_BYTECODE_INTERPRETER */ 368049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 369049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UNUSED( face ); 370049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UNUSED( stream ); 371049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 372049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return TT_Err_Ok; 373049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 374049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#endif 375049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 376049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 377049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 378049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /*************************************************************************/ 379049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 380049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* <Function> */ 381049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* tt_face_load_prep */ 382049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 383049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* <Description> */ 384049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* Load the cvt program. */ 385049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 386049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* <InOut> */ 387049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* face :: A handle to the target face object. */ 388049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 389049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* <Input> */ 390049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* stream :: A handle to the input stream. */ 391049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 392049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* <Return> */ 393049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* FreeType error code. 0 means success. */ 394049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 395049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_LOCAL_DEF( FT_Error ) 396049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project tt_face_load_prep( TT_Face face, 397049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Stream stream ) 398049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 399049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#ifdef TT_USE_BYTECODE_INTERPRETER 400049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 401049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Error error; 402049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_ULong table_len; 403049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 404049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 405049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_TRACE2(( "Prep program " )); 406049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 407049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project error = face->goto_table( face, TTAG_prep, stream, &table_len ); 408049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( error ) 409049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 410049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project face->cvt_program = NULL; 411049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project face->cvt_program_size = 0; 412049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project error = TT_Err_Ok; 413049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 414295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner FT_TRACE2(( "is missing\n" )); 415049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 416049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project else 417049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 418049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project face->cvt_program_size = table_len; 419049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( FT_FRAME_EXTRACT( table_len, face->cvt_program ) ) 420049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project goto Exit; 421049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 422049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_TRACE2(( "loaded, %12d bytes\n", face->cvt_program_size )); 423049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 424049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 425049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project Exit: 426049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return error; 427049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 428049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#else /* !TT_USE_BYTECODE_INTERPRETER */ 429049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 430049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UNUSED( face ); 431049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UNUSED( stream ); 432049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 433049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return TT_Err_Ok; 434049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 435049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#endif 436049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 437049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 438049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 439049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /*************************************************************************/ 440049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 441049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* <Function> */ 442049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* tt_face_load_hdmx */ 443049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 444049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* <Description> */ 445049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* Load the `hdmx' table into the face object. */ 446049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 447049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* <Input> */ 448049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* face :: A handle to the target face object. */ 449049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 450049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* stream :: A handle to the input stream. */ 451049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 452049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* <Return> */ 453049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* FreeType error code. 0 means success. */ 454049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 455049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 456049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_LOCAL_DEF( FT_Error ) 457049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project tt_face_load_hdmx( TT_Face face, 458049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Stream stream ) 459049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 460049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Error error; 461049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Memory memory = stream->memory; 462049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt version, nn, num_records; 463049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_ULong table_size, record_size; 464049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Byte* p; 465049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Byte* limit; 466049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 467049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 468049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* this table is optional */ 469049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project error = face->goto_table( face, TTAG_hdmx, stream, &table_size ); 470049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( error || table_size < 8 ) 471049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return TT_Err_Ok; 472049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 473049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( FT_FRAME_EXTRACT( table_size, face->hdmx_table ) ) 474049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project goto Exit; 475049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 476049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project p = face->hdmx_table; 477049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project limit = p + table_size; 478049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 479049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project version = FT_NEXT_USHORT( p ); 480049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project num_records = FT_NEXT_USHORT( p ); 481049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project record_size = FT_NEXT_ULONG( p ); 482049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 483049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* The maximum number of bytes in an hdmx device record is the */ 484049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* maximum number of glyphs + 2; this is 0xFFFF + 2; this is */ 485049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* the reason why `record_size' is a long (which we read as */ 486049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* unsigned long for convenience). In practice, two bytes */ 487049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* sufficient to hold the size value. */ 488049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 489049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* There are at least two fonts, HANNOM-A and HANNOM-B version */ 490049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* 2.0 (2005), which get this wrong: The upper two bytes of */ 491049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* the size value are set to 0xFF instead of 0x00. We catch */ 492049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* and fix this. */ 493049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 494049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( record_size >= 0xFFFF0000UL ) 495049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project record_size &= 0xFFFFU; 496049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 497049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* The limit for `num_records' is a heuristic value. */ 498049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 499049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( version != 0 || num_records > 255 || record_size > 0x10001L ) 500049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 501049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project error = TT_Err_Invalid_File_Format; 502049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project goto Fail; 503049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 504049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 505049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( FT_NEW_ARRAY( face->hdmx_record_sizes, num_records ) ) 506049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project goto Fail; 507049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 508049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project for ( nn = 0; nn < num_records; nn++ ) 509049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 510049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( p + record_size > limit ) 511049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project break; 512049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 513049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project face->hdmx_record_sizes[nn] = p[0]; 514049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project p += record_size; 515049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 516049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 517049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project face->hdmx_record_count = nn; 518049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project face->hdmx_table_size = table_size; 519049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project face->hdmx_record_size = record_size; 520049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 521049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project Exit: 522049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return error; 523049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 524049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project Fail: 525049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_FRAME_RELEASE( face->hdmx_table ); 526049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project face->hdmx_table_size = 0; 527049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project goto Exit; 528049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 529049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 530049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 531049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_LOCAL_DEF( void ) 532049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project tt_face_free_hdmx( TT_Face face ) 533049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 534049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Stream stream = face->root.stream; 535049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Memory memory = stream->memory; 536049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 537049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 538049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_FREE( face->hdmx_record_sizes ); 539049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_FRAME_RELEASE( face->hdmx_table ); 540049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 541049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 542049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 543049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /*************************************************************************/ 544049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 545049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* Return the advance width table for a given pixel size if it is found */ 546049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* in the font's `hdmx' table (if any). */ 547049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 548049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_LOCAL_DEF( FT_Byte* ) 549049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project tt_face_get_device_metrics( TT_Face face, 550049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt ppem, 551049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt gindex ) 552049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 553049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt nn; 554049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Byte* result = NULL; 555049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_ULong record_size = face->hdmx_record_size; 556049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Byte* record = face->hdmx_table + 8; 557049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 558049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 559049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project for ( nn = 0; nn < face->hdmx_record_count; nn++ ) 560049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( face->hdmx_record_sizes[nn] == ppem ) 561049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 562049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project gindex += 2; 563049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( gindex < record_size ) 564049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project result = record + nn * record_size + gindex; 565049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project break; 566049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 567049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 568049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return result; 569049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 570049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 571049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 572049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/* END */ 573