1049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/***************************************************************************/ 2049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/* */ 3049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/* ttsbit0.c */ 4049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/* */ 5049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/* TrueType and OpenType embedded bitmap support (body). */ 6049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/* This is a heap-optimized version. */ 7049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/* */ 877f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner/* Copyright 2005, 2006, 2007, 2008, 2009 by */ 9049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/* David Turner, Robert Wilhelm, and Werner Lemberg. */ 10049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/* */ 11049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/* This file is part of the FreeType project, and may only be used, */ 12049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/* modified, and distributed under the terms of the FreeType project */ 13049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ 14049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/* this file you indicate that you have read the license and */ 15049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/* understand and accept it fully. */ 16049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/* */ 17049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/***************************************************************************/ 18049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 19049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 20049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/* This file is included by ttsbit.c */ 21049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 22049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 23049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include <ft2build.h> 24049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include FT_INTERNAL_DEBUG_H 25049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include FT_INTERNAL_STREAM_H 26049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include FT_TRUETYPE_TAGS_H 27049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include "ttsbit.h" 28049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 29049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include "sferrors.h" 30049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 31049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 32049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /*************************************************************************/ 33049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 34049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ 35049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ 36049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* messages during execution. */ 37049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 38049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#undef FT_COMPONENT 39049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define FT_COMPONENT trace_ttsbit 40049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 41049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 42049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_LOCAL_DEF( FT_Error ) 43049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project tt_face_load_eblc( TT_Face face, 44049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Stream stream ) 45049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 4677f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner FT_Error error = SFNT_Err_Ok; 4777f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner FT_Fixed version; 4877f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner FT_ULong num_strikes, table_size; 4977f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner FT_Byte* p; 5077f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner FT_Byte* p_limit; 5177f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner FT_UInt count; 52049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 53049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 54049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project face->sbit_num_strikes = 0; 55049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 56049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* this table is optional */ 57049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project error = face->goto_table( face, TTAG_EBLC, stream, &table_size ); 58049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( error ) 59049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project error = face->goto_table( face, TTAG_bloc, stream, &table_size ); 60049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( error ) 61049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project goto Exit; 62049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 63049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( table_size < 8 ) 64049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 65295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner FT_ERROR(( "tt_face_load_sbit_strikes: table too short\n" )); 66049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project error = SFNT_Err_Invalid_File_Format; 67049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project goto Exit; 68049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 69049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 70049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( FT_FRAME_EXTRACT( table_size, face->sbit_table ) ) 71049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project goto Exit; 72049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 73049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project face->sbit_table_size = table_size; 74049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 75049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project p = face->sbit_table; 76049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project p_limit = p + table_size; 77049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 78049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project version = FT_NEXT_ULONG( p ); 79049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project num_strikes = FT_NEXT_ULONG( p ); 80049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 81049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( version != 0x00020000UL || num_strikes >= 0x10000UL ) 82049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 83295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner FT_ERROR(( "tt_face_load_sbit_strikes: invalid table version\n" )); 84049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project error = SFNT_Err_Invalid_File_Format; 85049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project goto Fail; 86049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 87049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 88049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* 89049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project * Count the number of strikes available in the table. We are a bit 90049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project * paranoid there and don't trust the data. 91049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project */ 92049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project count = (FT_UInt)num_strikes; 93049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( 8 + 48UL * count > table_size ) 94049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project count = (FT_UInt)( ( p_limit - p ) / 48 ); 95049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 96049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project face->sbit_num_strikes = count; 97049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 98049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_TRACE3(( "sbit_num_strikes: %u\n", count )); 99049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project Exit: 100049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return error; 101049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 102049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project Fail: 103049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_FRAME_RELEASE( face->sbit_table ); 104049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project face->sbit_table_size = 0; 105049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project goto Exit; 106049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 107049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 108049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 109049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_LOCAL_DEF( void ) 110049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project tt_face_free_eblc( TT_Face face ) 111049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 112049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Stream stream = face->root.stream; 113049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 114049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 115049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_FRAME_RELEASE( face->sbit_table ); 116049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project face->sbit_table_size = 0; 117049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project face->sbit_num_strikes = 0; 118049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 119049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 120049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 121049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_LOCAL_DEF( FT_Error ) 122049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project tt_face_set_sbit_strike( TT_Face face, 123049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Size_Request req, 124049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_ULong* astrike_index ) 125049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 126049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return FT_Match_Size( (FT_Face)face, req, 0, astrike_index ); 127049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 128049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 129049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 130049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_LOCAL_DEF( FT_Error ) 131049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project tt_face_load_strike_metrics( TT_Face face, 132049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_ULong strike_index, 133049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Size_Metrics* metrics ) 134049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 13577f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner FT_Byte* strike; 136049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 137049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 138049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( strike_index >= (FT_ULong)face->sbit_num_strikes ) 139049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return SFNT_Err_Invalid_Argument; 140049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 141049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project strike = face->sbit_table + 8 + strike_index * 48; 142049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 143049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project metrics->x_ppem = (FT_UShort)strike[44]; 144049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project metrics->y_ppem = (FT_UShort)strike[45]; 145049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 146049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project metrics->ascender = (FT_Char)strike[16] << 6; /* hori.ascender */ 147049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project metrics->descender = (FT_Char)strike[17] << 6; /* hori.descender */ 148049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project metrics->height = metrics->ascender - metrics->descender; 149049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 150049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* XXX: Is this correct? */ 151049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project metrics->max_advance = ( (FT_Char)strike[22] + /* min_origin_SB */ 152049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project strike[18] + /* max_width */ 153049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project (FT_Char)strike[23] /* min_advance_SB */ 154049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project ) << 6; 155049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 156049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return SFNT_Err_Ok; 157049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 158049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 159049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 160049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project typedef struct TT_SBitDecoderRec_ 161049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 162049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project TT_Face face; 163049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Stream stream; 164049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Bitmap* bitmap; 165049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project TT_SBit_Metrics metrics; 166049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Bool metrics_loaded; 167049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Bool bitmap_allocated; 168049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Byte bit_depth; 169049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 170049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_ULong ebdt_start; 171049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_ULong ebdt_size; 172049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 173049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_ULong strike_index_array; 174049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_ULong strike_index_count; 175049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Byte* eblc_base; 176049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Byte* eblc_limit; 177049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 178049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } TT_SBitDecoderRec, *TT_SBitDecoder; 179049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 180049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 181049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project static FT_Error 182049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project tt_sbit_decoder_init( TT_SBitDecoder decoder, 183049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project TT_Face face, 184049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_ULong strike_index, 185049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project TT_SBit_MetricsRec* metrics ) 186049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 187049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Error error; 188049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Stream stream = face->root.stream; 189049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_ULong ebdt_size; 190049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 191049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 192049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project error = face->goto_table( face, TTAG_EBDT, stream, &ebdt_size ); 193049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( error ) 194049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project error = face->goto_table( face, TTAG_bdat, stream, &ebdt_size ); 195049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( error ) 196049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project goto Exit; 197049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 198049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project decoder->face = face; 199049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project decoder->stream = stream; 200049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project decoder->bitmap = &face->root.glyph->bitmap; 201049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project decoder->metrics = metrics; 202049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 203049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project decoder->metrics_loaded = 0; 204049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project decoder->bitmap_allocated = 0; 205049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 206049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project decoder->ebdt_start = FT_STREAM_POS(); 207049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project decoder->ebdt_size = ebdt_size; 208049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 209049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project decoder->eblc_base = face->sbit_table; 210049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project decoder->eblc_limit = face->sbit_table + face->sbit_table_size; 211049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 212049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* now find the strike corresponding to the index */ 213049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 214049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Byte* p; 215049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 216049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 217049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( 8 + 48 * strike_index + 3 * 4 + 34 + 1 > face->sbit_table_size ) 218049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 219049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project error = SFNT_Err_Invalid_File_Format; 220049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project goto Exit; 221049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 222049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 223049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project p = decoder->eblc_base + 8 + 48 * strike_index; 224049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 225049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project decoder->strike_index_array = FT_NEXT_ULONG( p ); 226049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project p += 4; 227049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project decoder->strike_index_count = FT_NEXT_ULONG( p ); 228049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project p += 34; 229049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project decoder->bit_depth = *p; 230049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 231049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( decoder->strike_index_array > face->sbit_table_size || 232049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project decoder->strike_index_array + 8 * decoder->strike_index_count > 233049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project face->sbit_table_size ) 234049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project error = SFNT_Err_Invalid_File_Format; 235049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 236049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 237049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project Exit: 238049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return error; 239049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 240049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 241049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 242049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project static void 243049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project tt_sbit_decoder_done( TT_SBitDecoder decoder ) 244049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 245049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UNUSED( decoder ); 246049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 247049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 248049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 249049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project static FT_Error 250049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project tt_sbit_decoder_alloc_bitmap( TT_SBitDecoder decoder ) 251049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 252049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Error error = SFNT_Err_Ok; 253049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt width, height; 254049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Bitmap* map = decoder->bitmap; 255049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Long size; 256049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 257049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 258049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( !decoder->metrics_loaded ) 259049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 260049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project error = SFNT_Err_Invalid_Argument; 261049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project goto Exit; 262049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 263049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 264049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project width = decoder->metrics->width; 265049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project height = decoder->metrics->height; 266049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 267049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project map->width = (int)width; 268049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project map->rows = (int)height; 269049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 270049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project switch ( decoder->bit_depth ) 271049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 272049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project case 1: 273049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project map->pixel_mode = FT_PIXEL_MODE_MONO; 274049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project map->pitch = ( map->width + 7 ) >> 3; 275049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project break; 276049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 277049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project case 2: 278049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project map->pixel_mode = FT_PIXEL_MODE_GRAY2; 279049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project map->pitch = ( map->width + 3 ) >> 2; 280049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project break; 281049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 282049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project case 4: 283049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project map->pixel_mode = FT_PIXEL_MODE_GRAY4; 284049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project map->pitch = ( map->width + 1 ) >> 1; 285049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project break; 286049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 287049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project case 8: 288049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project map->pixel_mode = FT_PIXEL_MODE_GRAY; 289049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project map->pitch = map->width; 290049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project break; 291049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 292049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project default: 293049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project error = SFNT_Err_Invalid_File_Format; 294049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project goto Exit; 295049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 296049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 297049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project size = map->rows * map->pitch; 298049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 299049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* check that there is no empty image */ 300049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( size == 0 ) 301049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project goto Exit; /* exit successfully! */ 302049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 303049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project error = ft_glyphslot_alloc_bitmap( decoder->face->root.glyph, size ); 304049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( error ) 305049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project goto Exit; 306049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 307049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project decoder->bitmap_allocated = 1; 308049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 309049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project Exit: 310049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return error; 311049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 312049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 313049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 314049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project static FT_Error 315049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project tt_sbit_decoder_load_metrics( TT_SBitDecoder decoder, 316049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Byte* *pp, 317049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Byte* limit, 318049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Bool big ) 319049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 320049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Byte* p = *pp; 321049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project TT_SBit_Metrics metrics = decoder->metrics; 322049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 323049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 324049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( p + 5 > limit ) 325049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project goto Fail; 326049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 32777f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner metrics->height = p[0]; 32877f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner metrics->width = p[1]; 32977f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner metrics->horiBearingX = (FT_Char)p[2]; 33077f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner metrics->horiBearingY = (FT_Char)p[3]; 33177f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner metrics->horiAdvance = p[4]; 332049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 333049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project p += 5; 334049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( big ) 335049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 336049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( p + 3 > limit ) 337049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project goto Fail; 338049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 33977f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner metrics->vertBearingX = (FT_Char)p[0]; 34077f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner metrics->vertBearingY = (FT_Char)p[1]; 34177f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner metrics->vertAdvance = p[2]; 342049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 343049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project p += 3; 344049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 345049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 346049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project decoder->metrics_loaded = 1; 347049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project *pp = p; 34877f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner return SFNT_Err_Ok; 349049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 350049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project Fail: 351049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return SFNT_Err_Invalid_Argument; 352049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 353049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 354049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 355049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* forward declaration */ 356049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project static FT_Error 357049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project tt_sbit_decoder_load_image( TT_SBitDecoder decoder, 358049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt glyph_index, 359049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Int x_pos, 360049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Int y_pos ); 361049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 362049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project typedef FT_Error (*TT_SBitDecoder_LoadFunc)( TT_SBitDecoder decoder, 363049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Byte* p, 364049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Byte* plimit, 365049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Int x_pos, 366049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Int y_pos ); 367049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 368049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 369049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project static FT_Error 370049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project tt_sbit_decoder_load_byte_aligned( TT_SBitDecoder decoder, 371049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Byte* p, 372049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Byte* limit, 373049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Int x_pos, 374049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Int y_pos ) 375049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 376049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Error error = SFNT_Err_Ok; 377049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Byte* line; 378049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Int bit_height, bit_width, pitch, width, height, h; 379049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Bitmap* bitmap; 380049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 381049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 382049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( !decoder->bitmap_allocated ) 383049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 384049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project error = tt_sbit_decoder_alloc_bitmap( decoder ); 385049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( error ) 386049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project goto Exit; 387049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 388049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 389049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* check that we can write the glyph into the bitmap */ 390049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project bitmap = decoder->bitmap; 391049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project bit_width = bitmap->width; 392049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project bit_height = bitmap->rows; 393049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project pitch = bitmap->pitch; 394049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project line = bitmap->buffer; 395049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 396049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project width = decoder->metrics->width; 397049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project height = decoder->metrics->height; 398049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 399049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( x_pos < 0 || x_pos + width > bit_width || 400049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project y_pos < 0 || y_pos + height > bit_height ) 401049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 402049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project error = SFNT_Err_Invalid_File_Format; 403049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project goto Exit; 404049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 405049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 406049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( p + ( ( width + 7 ) >> 3 ) * height > limit ) 407049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 408049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project error = SFNT_Err_Invalid_File_Format; 409049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project goto Exit; 410049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 411049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 412049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* now do the blit */ 413049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project line += y_pos * pitch + ( x_pos >> 3 ); 414049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project x_pos &= 7; 415049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 416049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( x_pos == 0 ) /* the easy one */ 417049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 418049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project for ( h = height; h > 0; h--, line += pitch ) 419049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 420049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Byte* write = line; 421049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Int w; 422049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 423049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 424049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project for ( w = width; w >= 8; w -= 8 ) 425049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 426049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project write[0] = (FT_Byte)( write[0] | *p++ ); 427049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project write += 1; 428049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 429049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 430049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( w > 0 ) 431049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project write[0] = (FT_Byte)( write[0] | ( *p++ & ( 0xFF00U >> w ) ) ); 432049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 433049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 434049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project else /* x_pos > 0 */ 435049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 436049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project for ( h = height; h > 0; h--, line += pitch ) 437049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 438049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Byte* write = line; 439049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Int w; 440049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt wval = 0; 441049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 442049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 443049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project for ( w = width; w >= 8; w -= 8 ) 444049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 445049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project wval = (FT_UInt)( wval | *p++ ); 446049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project write[0] = (FT_Byte)( write[0] | ( wval >> x_pos ) ); 447049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project write += 1; 448049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project wval <<= 8; 449049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 450049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 451049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( w > 0 ) 452049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project wval = (FT_UInt)( wval | ( *p++ & ( 0xFF00U >> w ) ) ); 453049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 45477f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner /* all bits read and there are `x_pos + w' bits to be written */ 455049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 456049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project write[0] = (FT_Byte)( write[0] | ( wval >> x_pos ) ); 457049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 458049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( x_pos + w > 8 ) 459049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 460049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project write++; 461049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project wval <<= 8; 462049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project write[0] = (FT_Byte)( write[0] | ( wval >> x_pos ) ); 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 Exit: 468049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return error; 469049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 470049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 471049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 472295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner /* 473295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner * Load a bit-aligned bitmap (with pointer `p') into a line-aligned bitmap 474295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner * (with pointer `write'). In the example below, the width is 3 pixel, 475295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner * and `x_pos' is 1 pixel. 476295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner * 477295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner * p p+1 478295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner * | | | 479295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner * | 7 6 5 4 3 2 1 0 | 7 6 5 4 3 2 1 0 |... 480295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner * | | | 481295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner * +-------+ +-------+ +-------+ ... 482295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner * . . . 483295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner * . . . 484295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner * v . . 485295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner * +-------+ . . 486295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner * | | . 487295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner * | 7 6 5 4 3 2 1 0 | . 488295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner * | | . 489295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner * write . . 490295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner * . . 491295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner * v . 492295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner * +-------+ . 493295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner * | | 494295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner * | 7 6 5 4 3 2 1 0 | 495295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner * | | 496295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner * write+1 . 497295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner * . 498295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner * v 499295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner * +-------+ 500295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner * | | 501295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner * | 7 6 5 4 3 2 1 0 | 502295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner * | | 503295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner * write+2 504295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner * 505295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner */ 506295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner 507049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project static FT_Error 508049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project tt_sbit_decoder_load_bit_aligned( TT_SBitDecoder decoder, 509049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Byte* p, 510049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Byte* limit, 511049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Int x_pos, 512049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Int y_pos ) 513049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 514049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Error error = SFNT_Err_Ok; 515049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Byte* line; 516049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Int bit_height, bit_width, pitch, width, height, h, nbits; 517049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Bitmap* bitmap; 518049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UShort rval; 519049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 520049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 521049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( !decoder->bitmap_allocated ) 522049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 523049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project error = tt_sbit_decoder_alloc_bitmap( decoder ); 524049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( error ) 525049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project goto Exit; 526049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 527049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 528049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* check that we can write the glyph into the bitmap */ 529049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project bitmap = decoder->bitmap; 530049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project bit_width = bitmap->width; 531049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project bit_height = bitmap->rows; 532049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project pitch = bitmap->pitch; 533049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project line = bitmap->buffer; 534049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 535049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project width = decoder->metrics->width; 536049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project height = decoder->metrics->height; 537049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 538049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( x_pos < 0 || x_pos + width > bit_width || 539049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project y_pos < 0 || y_pos + height > bit_height ) 540049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 541049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project error = SFNT_Err_Invalid_File_Format; 542049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project goto Exit; 543049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 544049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 545049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( p + ( ( width * height + 7 ) >> 3 ) > limit ) 546049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 547049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project error = SFNT_Err_Invalid_File_Format; 548049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project goto Exit; 549049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 550049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 551049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* now do the blit */ 552295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner 553295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner /* adjust `line' to point to the first byte of the bitmap */ 554049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project line += y_pos * pitch + ( x_pos >> 3 ); 555049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project x_pos &= 7; 556049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 557049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* the higher byte of `rval' is used as a buffer */ 558049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project rval = 0; 559049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project nbits = 0; 560049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 561049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project for ( h = height; h > 0; h--, line += pitch ) 562049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 563049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Byte* write = line; 564295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner FT_Int w = width; 565049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 566049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 567295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner /* handle initial byte (in target bitmap) specially if necessary */ 568049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( x_pos ) 569049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 570049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project w = ( width < 8 - x_pos ) ? width : 8 - x_pos; 571049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 57277f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner if ( h == height ) 57377f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner { 574295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner rval = *p++; 575295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner nbits = x_pos; 57677f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner } 57777f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner else if ( nbits < w ) 578049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 579295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner if ( p < limit ) 580295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner rval |= *p++; 581049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project nbits += 8 - w; 582049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 583049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project else 584049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 585049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project rval >>= 8; 586049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project nbits -= w; 587049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 588049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 58977f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner *write++ |= ( ( rval >> nbits ) & 0xFF ) & 59077f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner ( ~( 0xFF << w ) << ( 8 - w - x_pos ) ); 591049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project rval <<= 8; 592049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 593049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project w = width - w; 594049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 595049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 596295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner /* handle medial bytes */ 597049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project for ( ; w >= 8; w -= 8 ) 598049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 599049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project rval |= *p++; 600049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project *write++ |= ( rval >> nbits ) & 0xFF; 601049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 602049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project rval <<= 8; 603049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 604049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 605295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner /* handle final byte if necessary */ 606049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( w > 0 ) 607049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 608049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( nbits < w ) 609049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 610295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner if ( p < limit ) 611295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner rval |= *p++; 612049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project *write |= ( ( rval >> nbits ) & 0xFF ) & ( 0xFF00U >> w ); 613049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project nbits += 8 - w; 614049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 615049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project rval <<= 8; 616049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 617049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project else 618049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 619049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project *write |= ( ( rval >> nbits ) & 0xFF ) & ( 0xFF00U >> w ); 620049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project nbits -= w; 621049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 622049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 623049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 624049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 625049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project Exit: 626049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return error; 627049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 628049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 629049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 630049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project static FT_Error 631049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project tt_sbit_decoder_load_compound( TT_SBitDecoder decoder, 632049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Byte* p, 633049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Byte* limit, 634049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Int x_pos, 635049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Int y_pos ) 636049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 637049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Error error = SFNT_Err_Ok; 638049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt num_components, nn; 639049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 64077f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner FT_Char horiBearingX = decoder->metrics->horiBearingX; 64177f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner FT_Char horiBearingY = decoder->metrics->horiBearingY; 64277f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner FT_Byte horiAdvance = decoder->metrics->horiAdvance; 64377f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner FT_Char vertBearingX = decoder->metrics->vertBearingX; 64477f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner FT_Char vertBearingY = decoder->metrics->vertBearingY; 64577f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner FT_Byte vertAdvance = decoder->metrics->vertAdvance; 64677f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner 647049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 648049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( p + 2 > limit ) 649049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project goto Fail; 650049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 651049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project num_components = FT_NEXT_USHORT( p ); 652049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( p + 4 * num_components > limit ) 653049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project goto Fail; 654049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 65577f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner if ( !decoder->bitmap_allocated ) 65677f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner { 65777f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner error = tt_sbit_decoder_alloc_bitmap( decoder ); 65877f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner if ( error ) 65977f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner goto Exit; 66077f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner } 66177f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner 662049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project for ( nn = 0; nn < num_components; nn++ ) 663049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 664049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt gindex = FT_NEXT_USHORT( p ); 665049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Byte dx = FT_NEXT_BYTE( p ); 666049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Byte dy = FT_NEXT_BYTE( p ); 667049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 668049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 669049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* NB: a recursive call */ 670049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project error = tt_sbit_decoder_load_image( decoder, gindex, 671049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project x_pos + dx, y_pos + dy ); 672049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( error ) 673049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project break; 674049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 675049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 67677f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner decoder->metrics->horiBearingX = horiBearingX; 67777f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner decoder->metrics->horiBearingY = horiBearingY; 67877f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner decoder->metrics->horiAdvance = horiAdvance; 67977f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner decoder->metrics->vertBearingX = vertBearingX; 68077f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner decoder->metrics->vertBearingY = vertBearingY; 68177f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner decoder->metrics->vertAdvance = vertAdvance; 68277f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner decoder->metrics->width = (FT_UInt)decoder->bitmap->width; 68377f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner decoder->metrics->height = (FT_UInt)decoder->bitmap->rows; 68477f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner 685049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project Exit: 686049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return error; 687049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 688049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project Fail: 689049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project error = SFNT_Err_Invalid_File_Format; 690049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project goto Exit; 691049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 692049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 693049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 694049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project static FT_Error 695049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project tt_sbit_decoder_load_bitmap( TT_SBitDecoder decoder, 696049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt glyph_format, 697049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_ULong glyph_start, 698049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_ULong glyph_size, 699049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Int x_pos, 700049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Int y_pos ) 701049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 702049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Error error; 703049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Stream stream = decoder->stream; 704049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Byte* p; 705049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Byte* p_limit; 706049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Byte* data; 707049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 708049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 709049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* seek into the EBDT table now */ 710049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( glyph_start + glyph_size > decoder->ebdt_size ) 711049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 712049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project error = SFNT_Err_Invalid_Argument; 713049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project goto Exit; 714049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 715049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 716049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( FT_STREAM_SEEK( decoder->ebdt_start + glyph_start ) || 717049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_FRAME_EXTRACT( glyph_size, data ) ) 718049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project goto Exit; 719049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 720049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project p = data; 721049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project p_limit = p + glyph_size; 722049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 723049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* read the data, depending on the glyph format */ 724049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project switch ( glyph_format ) 725049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 726049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project case 1: 727049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project case 2: 728049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project case 8: 729049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project error = tt_sbit_decoder_load_metrics( decoder, &p, p_limit, 0 ); 730049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project break; 731049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 732049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project case 6: 733049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project case 7: 734049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project case 9: 735049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project error = tt_sbit_decoder_load_metrics( decoder, &p, p_limit, 1 ); 736049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project break; 737049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 738049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project default: 739049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project error = SFNT_Err_Ok; 740049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 741049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 742049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( error ) 743049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project goto Fail; 744049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 745049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 746049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project TT_SBitDecoder_LoadFunc loader; 747049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 748049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 749049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project switch ( glyph_format ) 750049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 751049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project case 1: 752049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project case 6: 753049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project loader = tt_sbit_decoder_load_byte_aligned; 754049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project break; 755049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 756049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project case 2: 757049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project case 5: 758049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project case 7: 759049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project loader = tt_sbit_decoder_load_bit_aligned; 760049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project break; 761049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 762049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project case 8: 763049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( p + 1 > p_limit ) 764049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project goto Fail; 765049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 766049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project p += 1; /* skip padding */ 767049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* fall-through */ 768049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 769049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project case 9: 770049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project loader = tt_sbit_decoder_load_compound; 771049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project break; 772049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 773049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project default: 774049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project goto Fail; 775049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 776049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 777049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project error = loader( decoder, p, p_limit, x_pos, y_pos ); 778049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 779049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 780049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project Fail: 781049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_FRAME_RELEASE( data ); 782049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 783049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project Exit: 784049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return error; 785049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 786049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 787049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 788049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project static FT_Error 789049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project tt_sbit_decoder_load_image( TT_SBitDecoder decoder, 790049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt glyph_index, 791049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Int x_pos, 792049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Int y_pos ) 793049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 794049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* 795049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project * First, we find the correct strike range that applies to this 796049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project * glyph index. 797049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project */ 798049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 799049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Byte* p = decoder->eblc_base + decoder->strike_index_array; 800049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Byte* p_limit = decoder->eblc_limit; 801049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_ULong num_ranges = decoder->strike_index_count; 802049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt start, end, index_format, image_format; 803049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_ULong image_start = 0, image_end = 0, image_offset; 804049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 805049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 806049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project for ( ; num_ranges > 0; num_ranges-- ) 807049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 808049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project start = FT_NEXT_USHORT( p ); 809049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project end = FT_NEXT_USHORT( p ); 810049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 811049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( glyph_index >= start && glyph_index <= end ) 812049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project goto FoundRange; 813049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 814049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project p += 4; /* ignore index offset */ 815049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 816049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project goto NoBitmap; 817049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 818049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FoundRange: 819049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project image_offset = FT_NEXT_ULONG( p ); 820049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 821049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* overflow check */ 822049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( decoder->eblc_base + decoder->strike_index_array + image_offset < 823049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project decoder->eblc_base ) 824049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project goto Failure; 825049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 826049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project p = decoder->eblc_base + decoder->strike_index_array + image_offset; 827049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( p + 8 > p_limit ) 828049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project goto NoBitmap; 829049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 830049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* now find the glyph's location and extend within the ebdt table */ 831049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project index_format = FT_NEXT_USHORT( p ); 832049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project image_format = FT_NEXT_USHORT( p ); 833049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project image_offset = FT_NEXT_ULONG ( p ); 834049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 835049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project switch ( index_format ) 836049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 837049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project case 1: /* 4-byte offsets relative to `image_offset' */ 838049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 839049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project p += 4 * ( glyph_index - start ); 840049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( p + 8 > p_limit ) 841049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project goto NoBitmap; 842049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 843049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project image_start = FT_NEXT_ULONG( p ); 844049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project image_end = FT_NEXT_ULONG( p ); 845049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 846049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( image_start == image_end ) /* missing glyph */ 847049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project goto NoBitmap; 848049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 849049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project break; 850049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 851049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project case 2: /* big metrics, constant image size */ 852049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 853049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_ULong image_size; 854049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 855049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 856049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( p + 12 > p_limit ) 857049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project goto NoBitmap; 858049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 859049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project image_size = FT_NEXT_ULONG( p ); 860049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 861049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( tt_sbit_decoder_load_metrics( decoder, &p, p_limit, 1 ) ) 862049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project goto NoBitmap; 863049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 864049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project image_start = image_size * ( glyph_index - start ); 865049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project image_end = image_start + image_size; 866049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 867049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project break; 868049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 869049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project case 3: /* 2-byte offsets relative to 'image_offset' */ 870049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 871049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project p += 2 * ( glyph_index - start ); 872049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( p + 4 > p_limit ) 873049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project goto NoBitmap; 874049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 875049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project image_start = FT_NEXT_USHORT( p ); 876049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project image_end = FT_NEXT_USHORT( p ); 877049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 878049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( image_start == image_end ) /* missing glyph */ 879049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project goto NoBitmap; 880049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 881049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project break; 882049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 883049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project case 4: /* sparse glyph array with (glyph,offset) pairs */ 884049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 885049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_ULong mm, num_glyphs; 886049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 887049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 888049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( p + 4 > p_limit ) 889049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project goto NoBitmap; 890049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 891049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project num_glyphs = FT_NEXT_ULONG( p ); 892049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 893049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* overflow check */ 894049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( p + ( num_glyphs + 1 ) * 4 < p ) 895049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project goto Failure; 896049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 897049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( p + ( num_glyphs + 1 ) * 4 > p_limit ) 898049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project goto NoBitmap; 899049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 900049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project for ( mm = 0; mm < num_glyphs; mm++ ) 901049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 902049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt gindex = FT_NEXT_USHORT( p ); 903049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 904049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 905049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( gindex == glyph_index ) 906049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 907049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project image_start = FT_NEXT_USHORT( p ); 908049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project p += 2; 909049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project image_end = FT_PEEK_USHORT( p ); 910049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project break; 911049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 912049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project p += 2; 913049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 914049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 915049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( mm >= num_glyphs ) 916049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project goto NoBitmap; 917049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 918049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project break; 919049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 920049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project case 5: /* constant metrics with sparse glyph codes */ 921049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 922049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_ULong image_size, mm, num_glyphs; 923049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 924049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 925049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( p + 16 > p_limit ) 926049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project goto NoBitmap; 927049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 928049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project image_size = FT_NEXT_ULONG( p ); 929049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 930049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( tt_sbit_decoder_load_metrics( decoder, &p, p_limit, 1 ) ) 931049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project goto NoBitmap; 932049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 933049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project num_glyphs = FT_NEXT_ULONG( p ); 934049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 935049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* overflow check */ 936049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( p + 2 * num_glyphs < p ) 937049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project goto Failure; 938049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 939049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( p + 2 * num_glyphs > p_limit ) 940049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project goto NoBitmap; 941049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 942049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project for ( mm = 0; mm < num_glyphs; mm++ ) 943049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 944049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt gindex = FT_NEXT_USHORT( p ); 945049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 946049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 947049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( gindex == glyph_index ) 948049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project break; 949049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 950049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 951049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( mm >= num_glyphs ) 952049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project goto NoBitmap; 953049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 954049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project image_start = image_size * mm; 955049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project image_end = image_start + image_size; 956049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 957049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project break; 958049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 959049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project default: 960049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project goto NoBitmap; 961049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 962049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 963049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( image_start > image_end ) 964049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project goto NoBitmap; 965049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 966049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project image_end -= image_start; 967049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project image_start = image_offset + image_start; 968049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 969049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return tt_sbit_decoder_load_bitmap( decoder, 970049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project image_format, 971049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project image_start, 972049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project image_end, 973049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project x_pos, 974049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project y_pos ); 975049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 976049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project Failure: 977049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return SFNT_Err_Invalid_Table; 978049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 979049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project NoBitmap: 980049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return SFNT_Err_Invalid_Argument; 981049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 982049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 983049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 984049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_LOCAL( FT_Error ) 985049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project tt_face_load_sbit_image( TT_Face face, 986049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_ULong strike_index, 987049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt glyph_index, 988049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt load_flags, 989049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Stream stream, 990049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Bitmap *map, 991049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project TT_SBit_MetricsRec *metrics ) 992049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 993049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project TT_SBitDecoderRec decoder[1]; 994049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Error error; 995049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 996049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UNUSED( load_flags ); 997049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UNUSED( stream ); 998049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UNUSED( map ); 999049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1000049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1001049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project error = tt_sbit_decoder_init( decoder, face, strike_index, metrics ); 1002049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( !error ) 1003049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1004049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project error = tt_sbit_decoder_load_image( decoder, glyph_index, 0, 0 ); 1005049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project tt_sbit_decoder_done( decoder ); 1006049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1007049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1008049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return error; 1009049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1010049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1011049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/* EOF */ 1012