1ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/***************************************************************************/ 2ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* */ 3ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* ttsbit.c */ 4ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* */ 5ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* TrueType and OpenType embedded bitmap support (body). */ 6ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* */ 7ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* Copyright 2005-2009, 2013 by */ 8ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* David Turner, Robert Wilhelm, and Werner Lemberg. */ 9ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* */ 10ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* Copyright 2013 by Google, Inc. */ 11ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* Google Author(s): Behdad Esfahbod. */ 12ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* */ 13ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* This file is part of the FreeType project, and may only be used, */ 14ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* modified, and distributed under the terms of the FreeType project */ 15ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ 16ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* this file you indicate that you have read the license and */ 17ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* understand and accept it fully. */ 18ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* */ 19ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/***************************************************************************/ 20ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 21ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 22ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "../../include/ft2build.h" 23ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "../../include/freetype/internal/ftdebug.h" 24ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "../../include/freetype/internal/ftstream.h" 25ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "../../include/freetype/tttags.h" 26ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "../../include/freetype/ftbitmap.h" 27ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "ttsbit.h" 28ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 29ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "sferrors.h" 30ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 31ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "pngshim.h" 32ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 33ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 34ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 35ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 36ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ 37ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ 38ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* messages during execution. */ 39ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 40ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#undef FT_COMPONENT 41ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define FT_COMPONENT trace_ttsbit 42ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 43ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 44ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_LOCAL_DEF( FT_Error ) 45ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov tt_face_load_eblc( TT_Face face, 46ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Stream stream ) 47ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 48ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Error error = FT_Err_Ok; 49ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Fixed version; 50ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ULong num_strikes, table_size; 51ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte* p; 52ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte* p_limit; 53ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt count; 54ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 55ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 56ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov face->sbit_num_strikes = 0; 57ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 58ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* this table is optional */ 59ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = face->goto_table( face, TTAG_CBLC, stream, &table_size ); 60ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( error ) 61ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = face->goto_table( face, TTAG_EBLC, stream, &table_size ); 62ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( error ) 63ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = face->goto_table( face, TTAG_bloc, stream, &table_size ); 64ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( error ) 65ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Exit; 66ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 67ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( table_size < 8 ) 68ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 69ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ERROR(( "tt_face_load_sbit_strikes: table too short\n" )); 70ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = FT_THROW( Invalid_File_Format ); 71ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Exit; 72ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 73ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 74ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( FT_FRAME_EXTRACT( table_size, face->sbit_table ) ) 75ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Exit; 76ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 77ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov face->sbit_table_size = table_size; 78ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 79ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov p = face->sbit_table; 80ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov p_limit = p + table_size; 81ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 82ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov version = FT_NEXT_ULONG( p ); 83ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov num_strikes = FT_NEXT_ULONG( p ); 84ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 85ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( version != 0x00020000UL || num_strikes >= 0x10000UL ) 86ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 87ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ERROR(( "tt_face_load_sbit_strikes: invalid table version\n" )); 88ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = FT_THROW( Invalid_File_Format ); 89ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Fail; 90ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 91ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 92ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* 93ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * Count the number of strikes available in the table. We are a bit 94ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * paranoid there and don't trust the data. 95ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov */ 96ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov count = (FT_UInt)num_strikes; 97ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( 8 + 48UL * count > table_size ) 98ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov count = (FT_UInt)( ( p_limit - p ) / 48 ); 99ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 100ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov face->sbit_num_strikes = count; 101ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 102ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_TRACE3(( "sbit_num_strikes: %u\n", count )); 103ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Exit: 104ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return error; 105ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 106ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Fail: 107ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FRAME_RELEASE( face->sbit_table ); 108ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov face->sbit_table_size = 0; 109ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Exit; 110ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 111ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 112ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 113ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_LOCAL_DEF( void ) 114ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov tt_face_free_eblc( TT_Face face ) 115ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 116ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Stream stream = face->root.stream; 117ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 118ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 119ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FRAME_RELEASE( face->sbit_table ); 120ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov face->sbit_table_size = 0; 121ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov face->sbit_num_strikes = 0; 122ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 123ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 124ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 125ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_LOCAL_DEF( FT_Error ) 126ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov tt_face_set_sbit_strike( TT_Face face, 127ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Size_Request req, 128ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ULong* astrike_index ) 129ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 130ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FT_Match_Size( (FT_Face)face, req, 0, astrike_index ); 131ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 132ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 133ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 134ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_LOCAL_DEF( FT_Error ) 135ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov tt_face_load_strike_metrics( TT_Face face, 136ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ULong strike_index, 137ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Size_Metrics* metrics ) 138ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 139ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte* strike; 140ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 141ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 142ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( strike_index >= (FT_ULong)face->sbit_num_strikes ) 143ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FT_THROW( Invalid_Argument ); 144ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 145ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov strike = face->sbit_table + 8 + strike_index * 48; 146ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 147ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov metrics->x_ppem = (FT_UShort)strike[44]; 148ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov metrics->y_ppem = (FT_UShort)strike[45]; 149ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 150ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov metrics->ascender = (FT_Char)strike[16] << 6; /* hori.ascender */ 151ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov metrics->descender = (FT_Char)strike[17] << 6; /* hori.descender */ 152ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov metrics->height = metrics->ascender - metrics->descender; 153ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 154ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* XXX: Is this correct? */ 155ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov metrics->max_advance = ( (FT_Char)strike[22] + /* min_origin_SB */ 156ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov strike[18] + /* max_width */ 157ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov (FT_Char)strike[23] /* min_advance_SB */ 158ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ) << 6; 159ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 160ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FT_Err_Ok; 161ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 162ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 163ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 164ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov typedef struct TT_SBitDecoderRec_ 165ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 166ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov TT_Face face; 167ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Stream stream; 168ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Bitmap* bitmap; 169ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov TT_SBit_Metrics metrics; 170ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Bool metrics_loaded; 171ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Bool bitmap_allocated; 172ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte bit_depth; 173ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 174ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ULong ebdt_start; 175ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ULong ebdt_size; 176ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 177ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ULong strike_index_array; 178ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ULong strike_index_count; 179ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte* eblc_base; 180ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte* eblc_limit; 181ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 182ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } TT_SBitDecoderRec, *TT_SBitDecoder; 183ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 184ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 185ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov static FT_Error 186ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov tt_sbit_decoder_init( TT_SBitDecoder decoder, 187ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov TT_Face face, 188ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ULong strike_index, 189ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov TT_SBit_MetricsRec* metrics ) 190ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 191ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Error error; 192ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Stream stream = face->root.stream; 193ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ULong ebdt_size; 194ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 195ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 196ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = face->goto_table( face, TTAG_CBDT, stream, &ebdt_size ); 197ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( error ) 198ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = face->goto_table( face, TTAG_EBDT, stream, &ebdt_size ); 199ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( error ) 200ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = face->goto_table( face, TTAG_bdat, stream, &ebdt_size ); 201ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( error ) 202ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Exit; 203ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 204ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov decoder->face = face; 205ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov decoder->stream = stream; 206ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov decoder->bitmap = &face->root.glyph->bitmap; 207ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov decoder->metrics = metrics; 208ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 209ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov decoder->metrics_loaded = 0; 210ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov decoder->bitmap_allocated = 0; 211ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 212ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov decoder->ebdt_start = FT_STREAM_POS(); 213ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov decoder->ebdt_size = ebdt_size; 214ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 215ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov decoder->eblc_base = face->sbit_table; 216ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov decoder->eblc_limit = face->sbit_table + face->sbit_table_size; 217ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 218ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* now find the strike corresponding to the index */ 219ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 220ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte* p; 221ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 222ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 223ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( 8 + 48 * strike_index + 3 * 4 + 34 + 1 > face->sbit_table_size ) 224ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 225ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = FT_THROW( Invalid_File_Format ); 226ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Exit; 227ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 228ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 229ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov p = decoder->eblc_base + 8 + 48 * strike_index; 230ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 231ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov decoder->strike_index_array = FT_NEXT_ULONG( p ); 232ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov p += 4; 233ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov decoder->strike_index_count = FT_NEXT_ULONG( p ); 234ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov p += 34; 235ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov decoder->bit_depth = *p; 236ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 237ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( decoder->strike_index_array > face->sbit_table_size || 238ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov decoder->strike_index_array + 8 * decoder->strike_index_count > 239ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov face->sbit_table_size ) 240ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = FT_THROW( Invalid_File_Format ); 241ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 242ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 243ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Exit: 244ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return error; 245ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 246ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 247ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 248ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov static void 249ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov tt_sbit_decoder_done( TT_SBitDecoder decoder ) 250ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 251ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UNUSED( decoder ); 252ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 253ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 254ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 255ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov static FT_Error 256ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov tt_sbit_decoder_alloc_bitmap( TT_SBitDecoder decoder, 257ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt load_flags ) 258ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 259ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Error error = FT_Err_Ok; 260ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt width, height; 261ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Bitmap* map = decoder->bitmap; 262ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Long size; 263ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 264ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 265ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( !decoder->metrics_loaded ) 266ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 267ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = FT_THROW( Invalid_Argument ); 268ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Exit; 269ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 270ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 271ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov width = decoder->metrics->width; 272ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov height = decoder->metrics->height; 273ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 274ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov map->width = (int)width; 275ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov map->rows = (int)height; 276ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 277ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov switch ( decoder->bit_depth ) 278ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 279ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov case 1: 280ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov map->pixel_mode = FT_PIXEL_MODE_MONO; 281ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov map->pitch = ( map->width + 7 ) >> 3; 282ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov map->num_grays = 2; 283ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov break; 284ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 285ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov case 2: 286ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov map->pixel_mode = FT_PIXEL_MODE_GRAY2; 287ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov map->pitch = ( map->width + 3 ) >> 2; 288ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov map->num_grays = 4; 289ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov break; 290ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 291ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov case 4: 292ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov map->pixel_mode = FT_PIXEL_MODE_GRAY4; 293ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov map->pitch = ( map->width + 1 ) >> 1; 294ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov map->num_grays = 16; 295ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov break; 296ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 297ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov case 8: 298ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov map->pixel_mode = FT_PIXEL_MODE_GRAY; 299ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov map->pitch = map->width; 300ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov map->num_grays = 256; 301ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov break; 302ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 303ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov case 32: 304ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( load_flags & FT_LOAD_COLOR ) 305ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 306ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov map->pixel_mode = FT_PIXEL_MODE_BGRA; 307ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov map->pitch = map->width * 4; 308ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov map->num_grays = 256; 309ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 310ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else 311ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 312ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov map->pixel_mode = FT_PIXEL_MODE_GRAY; 313ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov map->pitch = map->width; 314ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov map->num_grays = 256; 315ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 316ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov break; 317ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 318ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov default: 319ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = FT_THROW( Invalid_File_Format ); 320ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Exit; 321ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 322ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 323ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov size = map->rows * map->pitch; 324ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 325ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* check that there is no empty image */ 326ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( size == 0 ) 327ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Exit; /* exit successfully! */ 328ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 329ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = ft_glyphslot_alloc_bitmap( decoder->face->root.glyph, size ); 330ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( error ) 331ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Exit; 332ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 333ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov decoder->bitmap_allocated = 1; 334ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 335ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Exit: 336ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return error; 337ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 338ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 339ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 340ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov static FT_Error 341ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov tt_sbit_decoder_load_metrics( TT_SBitDecoder decoder, 342ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte* *pp, 343ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte* limit, 344ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Bool big ) 345ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 346ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte* p = *pp; 347ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov TT_SBit_Metrics metrics = decoder->metrics; 348ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 349ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 350ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( p + 5 > limit ) 351ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Fail; 352ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 353ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov metrics->height = p[0]; 354ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov metrics->width = p[1]; 355ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov metrics->horiBearingX = (FT_Char)p[2]; 356ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov metrics->horiBearingY = (FT_Char)p[3]; 357ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov metrics->horiAdvance = p[4]; 358ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 359ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov p += 5; 360ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( big ) 361ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 362ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( p + 3 > limit ) 363ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Fail; 364ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 365ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov metrics->vertBearingX = (FT_Char)p[0]; 366ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov metrics->vertBearingY = (FT_Char)p[1]; 367ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov metrics->vertAdvance = p[2]; 368ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 369ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov p += 3; 370ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 371ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 372ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov decoder->metrics_loaded = 1; 373ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *pp = p; 374ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FT_Err_Ok; 375ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 376ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Fail: 377ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_TRACE1(( "tt_sbit_decoder_load_metrics: broken table" )); 378ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FT_THROW( Invalid_Argument ); 379ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 380ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 381ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 382ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* forward declaration */ 383ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov static FT_Error 384ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov tt_sbit_decoder_load_image( TT_SBitDecoder decoder, 385ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt load_flags, 386ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt glyph_index, 387ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Int x_pos, 388ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Int y_pos ); 389ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 390ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov typedef FT_Error (*TT_SBitDecoder_LoadFunc)( TT_SBitDecoder decoder, 391ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt load_flags, 392ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte* p, 393ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte* plimit, 394ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Int x_pos, 395ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Int y_pos ); 396ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 397ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 398ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov static FT_Error 399ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov tt_sbit_decoder_load_byte_aligned( TT_SBitDecoder decoder, 400ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt load_flags, 401ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte* p, 402ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte* limit, 403ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Int x_pos, 404ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Int y_pos ) 405ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 406ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Error error = FT_Err_Ok; 407ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte* line; 408ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Int bit_height, bit_width, pitch, width, height, line_bits, h; 409ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Bitmap* bitmap; 410ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 411ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UNUSED( load_flags ); 412ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 413ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 414ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* check that we can write the glyph into the bitmap */ 415ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov bitmap = decoder->bitmap; 416ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov bit_width = bitmap->width; 417ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov bit_height = bitmap->rows; 418ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pitch = bitmap->pitch; 419ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov line = bitmap->buffer; 420ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 421ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov width = decoder->metrics->width; 422ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov height = decoder->metrics->height; 423ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 424ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov line_bits = width * decoder->bit_depth; 425ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 426ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( x_pos < 0 || x_pos + width > bit_width || 427ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov y_pos < 0 || y_pos + height > bit_height ) 428ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 429ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_TRACE1(( "tt_sbit_decoder_load_byte_aligned:" 430ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov " invalid bitmap dimensions\n" )); 431ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = FT_THROW( Invalid_File_Format ); 432ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Exit; 433ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 434ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 435ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( p + ( ( line_bits + 7 ) >> 3 ) * height > limit ) 436ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 437ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_TRACE1(( "tt_sbit_decoder_load_byte_aligned: broken bitmap\n" )); 438ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = FT_THROW( Invalid_File_Format ); 439ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Exit; 440ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 441ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 442ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* now do the blit */ 443ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov line += y_pos * pitch + ( x_pos >> 3 ); 444ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov x_pos &= 7; 445ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 446ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( x_pos == 0 ) /* the easy one */ 447ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 448ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for ( h = height; h > 0; h--, line += pitch ) 449ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 450ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte* pwrite = line; 451ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Int w; 452ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 453ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 454ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for ( w = line_bits; w >= 8; w -= 8 ) 455ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 456ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pwrite[0] = (FT_Byte)( pwrite[0] | *p++ ); 457ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pwrite += 1; 458ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 459ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 460ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( w > 0 ) 461ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pwrite[0] = (FT_Byte)( pwrite[0] | ( *p++ & ( 0xFF00U >> w ) ) ); 462ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 463ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 464ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else /* x_pos > 0 */ 465ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 466ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for ( h = height; h > 0; h--, line += pitch ) 467ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 468ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte* pwrite = line; 469ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Int w; 470ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt wval = 0; 471ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 472ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 473ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for ( w = line_bits; w >= 8; w -= 8 ) 474ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 475ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov wval = (FT_UInt)( wval | *p++ ); 476ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pwrite[0] = (FT_Byte)( pwrite[0] | ( wval >> x_pos ) ); 477ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pwrite += 1; 478ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov wval <<= 8; 479ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 480ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 481ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( w > 0 ) 482ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov wval = (FT_UInt)( wval | ( *p++ & ( 0xFF00U >> w ) ) ); 483ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 484ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* all bits read and there are `x_pos + w' bits to be written */ 485ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 486ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pwrite[0] = (FT_Byte)( pwrite[0] | ( wval >> x_pos ) ); 487ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 488ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( x_pos + w > 8 ) 489ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 490ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pwrite++; 491ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov wval <<= 8; 492ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pwrite[0] = (FT_Byte)( pwrite[0] | ( wval >> x_pos ) ); 493ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 494ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 495ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 496ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 497ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Exit: 498ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( !error ) 499ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_TRACE3(( "tt_sbit_decoder_load_byte_aligned: loaded\n" )); 500ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return error; 501ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 502ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 503ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 504ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* 505ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * Load a bit-aligned bitmap (with pointer `p') into a line-aligned bitmap 506ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * (with pointer `pwrite'). In the example below, the width is 3 pixel, 507ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * and `x_pos' is 1 pixel. 508ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * 509ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * p p+1 510ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * | | | 511ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * | 7 6 5 4 3 2 1 0 | 7 6 5 4 3 2 1 0 |... 512ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * | | | 513ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * +-------+ +-------+ +-------+ ... 514ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * . . . 515ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * . . . 516ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * v . . 517ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * +-------+ . . 518ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * | | . 519ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * | 7 6 5 4 3 2 1 0 | . 520ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * | | . 521ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * pwrite . . 522ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * . . 523ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * v . 524ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * +-------+ . 525ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * | | 526ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * | 7 6 5 4 3 2 1 0 | 527ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * | | 528ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * pwrite+1 . 529ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * . 530ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * v 531ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * +-------+ 532ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * | | 533ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * | 7 6 5 4 3 2 1 0 | 534ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * | | 535ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * pwrite+2 536ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * 537ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov */ 538ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 539ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov static FT_Error 540ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov tt_sbit_decoder_load_bit_aligned( TT_SBitDecoder decoder, 541ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt load_flags, 542ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte* p, 543ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte* limit, 544ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Int x_pos, 545ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Int y_pos ) 546ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 547ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Error error = FT_Err_Ok; 548ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte* line; 549ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Int bit_height, bit_width, pitch, width, height, line_bits, h, nbits; 550ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Bitmap* bitmap; 551ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UShort rval; 552ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 553ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UNUSED( load_flags ); 554ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 555ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 556ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* check that we can write the glyph into the bitmap */ 557ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov bitmap = decoder->bitmap; 558ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov bit_width = bitmap->width; 559ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov bit_height = bitmap->rows; 560ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pitch = bitmap->pitch; 561ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov line = bitmap->buffer; 562ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 563ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov width = decoder->metrics->width; 564ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov height = decoder->metrics->height; 565ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 566ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov line_bits = width * decoder->bit_depth; 567ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 568ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( x_pos < 0 || x_pos + width > bit_width || 569ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov y_pos < 0 || y_pos + height > bit_height ) 570ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 571ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_TRACE1(( "tt_sbit_decoder_load_bit_aligned:" 572ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov " invalid bitmap dimensions\n" )); 573ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = FT_THROW( Invalid_File_Format ); 574ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Exit; 575ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 576ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 577ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( p + ( ( line_bits * height + 7 ) >> 3 ) > limit ) 578ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 579ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_TRACE1(( "tt_sbit_decoder_load_bit_aligned: broken bitmap\n" )); 580ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = FT_THROW( Invalid_File_Format ); 581ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Exit; 582ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 583ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 584ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* now do the blit */ 585ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 586ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* adjust `line' to point to the first byte of the bitmap */ 587ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov line += y_pos * pitch + ( x_pos >> 3 ); 588ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov x_pos &= 7; 589ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 590ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* the higher byte of `rval' is used as a buffer */ 591ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov rval = 0; 592ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov nbits = 0; 593ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 594ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for ( h = height; h > 0; h--, line += pitch ) 595ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 596ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte* pwrite = line; 597ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Int w = line_bits; 598ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 599ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 600ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* handle initial byte (in target bitmap) specially if necessary */ 601ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( x_pos ) 602ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 603ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov w = ( line_bits < 8 - x_pos ) ? line_bits : 8 - x_pos; 604ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 605ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( h == height ) 606ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 607ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov rval = *p++; 608ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov nbits = x_pos; 609ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 610ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else if ( nbits < w ) 611ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 612ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( p < limit ) 613ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov rval |= *p++; 614ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov nbits += 8 - w; 615ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 616ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else 617ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 618ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov rval >>= 8; 619ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov nbits -= w; 620ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 621ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 622ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *pwrite++ |= ( ( rval >> nbits ) & 0xFF ) & 623ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ( ~( 0xFF << w ) << ( 8 - w - x_pos ) ); 624ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov rval <<= 8; 625ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 626ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov w = line_bits - w; 627ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 628ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 629ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* handle medial bytes */ 630ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for ( ; w >= 8; w -= 8 ) 631ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 632ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov rval |= *p++; 633ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *pwrite++ |= ( rval >> nbits ) & 0xFF; 634ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 635ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov rval <<= 8; 636ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 637ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 638ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* handle final byte if necessary */ 639ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( w > 0 ) 640ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 641ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( nbits < w ) 642ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 643ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( p < limit ) 644ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov rval |= *p++; 645ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *pwrite |= ( ( rval >> nbits ) & 0xFF ) & ( 0xFF00U >> w ); 646ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov nbits += 8 - w; 647ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 648ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov rval <<= 8; 649ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 650ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else 651ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 652ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *pwrite |= ( ( rval >> nbits ) & 0xFF ) & ( 0xFF00U >> w ); 653ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov nbits -= w; 654ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 655ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 656ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 657ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 658ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Exit: 659ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( !error ) 660ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_TRACE3(( "tt_sbit_decoder_load_bit_aligned: loaded\n" )); 661ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return error; 662ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 663ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 664ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 665ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov static FT_Error 666ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov tt_sbit_decoder_load_compound( TT_SBitDecoder decoder, 667ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt load_flags, 668ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte* p, 669ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte* limit, 670ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Int x_pos, 671ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Int y_pos ) 672ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 673ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Error error = FT_Err_Ok; 674ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt num_components, nn; 675ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 676ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Char horiBearingX = decoder->metrics->horiBearingX; 677ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Char horiBearingY = decoder->metrics->horiBearingY; 678ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte horiAdvance = decoder->metrics->horiAdvance; 679ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Char vertBearingX = decoder->metrics->vertBearingX; 680ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Char vertBearingY = decoder->metrics->vertBearingY; 681ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte vertAdvance = decoder->metrics->vertAdvance; 682ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 683ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 684ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( p + 2 > limit ) 685ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Fail; 686ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 687ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov num_components = FT_NEXT_USHORT( p ); 688ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( p + 4 * num_components > limit ) 689ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 690ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_TRACE1(( "tt_sbit_decoder_load_compound: broken table\n" )); 691ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Fail; 692ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 693ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 694ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_TRACE3(( "tt_sbit_decoder_load_compound: loading %d components\n", 695ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov num_components )); 696ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 697ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for ( nn = 0; nn < num_components; nn++ ) 698ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 699ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt gindex = FT_NEXT_USHORT( p ); 700ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte dx = FT_NEXT_BYTE( p ); 701ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte dy = FT_NEXT_BYTE( p ); 702ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 703ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 704ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* NB: a recursive call */ 705ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = tt_sbit_decoder_load_image( decoder, load_flags, gindex, 706ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov x_pos + dx, y_pos + dy ); 707ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( error ) 708ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov break; 709ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 710ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 711ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_TRACE3(( "tt_sbit_decoder_load_compound: done\n" )); 712ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 713ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov decoder->metrics->horiBearingX = horiBearingX; 714ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov decoder->metrics->horiBearingY = horiBearingY; 715ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov decoder->metrics->horiAdvance = horiAdvance; 716ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov decoder->metrics->vertBearingX = vertBearingX; 717ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov decoder->metrics->vertBearingY = vertBearingY; 718ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov decoder->metrics->vertAdvance = vertAdvance; 719ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov decoder->metrics->width = (FT_Byte)decoder->bitmap->width; 720ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov decoder->metrics->height = (FT_Byte)decoder->bitmap->rows; 721ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 722ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Exit: 723ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return error; 724ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 725ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Fail: 726ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = FT_THROW( Invalid_File_Format ); 727ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Exit; 728ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 729ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 730ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 731ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#ifdef FT_CONFIG_OPTION_USE_PNG 732ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 733ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov static FT_Error 734ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov tt_sbit_decoder_load_png( TT_SBitDecoder decoder, 735ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt load_flags, 736ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte* p, 737ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte* limit, 738ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Int x_pos, 739ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Int y_pos ) 740ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 741ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Error error = FT_Err_Ok; 742ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ULong png_len; 743ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 744ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UNUSED( load_flags ); 745ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 746ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 747ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( limit - p < 4 ) 748ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 749ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_TRACE1(( "tt_sbit_decoder_load_png: broken bitmap\n" )); 750ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = FT_THROW( Invalid_File_Format ); 751ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Exit; 752ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 753ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 754ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov png_len = FT_NEXT_ULONG( p ); 755ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( (FT_ULong)( limit - p ) < png_len ) 756ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 757ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_TRACE1(( "tt_sbit_decoder_load_png: broken bitmap\n" )); 758ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = FT_THROW( Invalid_File_Format ); 759ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Exit; 760ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 761ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 762ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = Load_SBit_Png( decoder->bitmap, 763ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov x_pos, 764ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov y_pos, 765ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov decoder->bit_depth, 766ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov decoder->metrics, 767ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov decoder->stream->memory, 768ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov p, 769ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov png_len ); 770ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 771ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Exit: 772ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( !error ) 773ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_TRACE3(( "tt_sbit_decoder_load_png: loaded\n" )); 774ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return error; 775ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 776ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 777ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif /* FT_CONFIG_OPTION_USE_PNG */ 778ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 779ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 780ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov static FT_Error 781ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov tt_sbit_decoder_load_bitmap( TT_SBitDecoder decoder, 782ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt load_flags, 783ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt glyph_format, 784ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ULong glyph_start, 785ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ULong glyph_size, 786ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Int x_pos, 787ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Int y_pos ) 788ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 789ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Error error; 790ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Stream stream = decoder->stream; 791ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte* p; 792ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte* p_limit; 793ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte* data; 794ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 795ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 796ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* seek into the EBDT table now */ 797ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( glyph_start + glyph_size > decoder->ebdt_size ) 798ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 799ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = FT_THROW( Invalid_Argument ); 800ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Exit; 801ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 802ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 803ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( FT_STREAM_SEEK( decoder->ebdt_start + glyph_start ) || 804ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FRAME_EXTRACT( glyph_size, data ) ) 805ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Exit; 806ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 807ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov p = data; 808ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov p_limit = p + glyph_size; 809ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 810ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* read the data, depending on the glyph format */ 811ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov switch ( glyph_format ) 812ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 813ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov case 1: 814ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov case 2: 815ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov case 8: 816ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov case 17: 817ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = tt_sbit_decoder_load_metrics( decoder, &p, p_limit, 0 ); 818ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov break; 819ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 820ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov case 6: 821ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov case 7: 822ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov case 9: 823ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov case 18: 824ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = tt_sbit_decoder_load_metrics( decoder, &p, p_limit, 1 ); 825ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov break; 826ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 827ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov default: 828ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = FT_Err_Ok; 829ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 830ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 831ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( error ) 832ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Fail; 833ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 834ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 835ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov TT_SBitDecoder_LoadFunc loader; 836ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 837ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 838ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov switch ( glyph_format ) 839ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 840ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov case 1: 841ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov case 6: 842ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov loader = tt_sbit_decoder_load_byte_aligned; 843ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov break; 844ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 845ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov case 2: 846ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov case 5: 847ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov case 7: 848ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov loader = tt_sbit_decoder_load_bit_aligned; 849ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov break; 850ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 851ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov case 8: 852ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( p + 1 > p_limit ) 853ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Fail; 854ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 855ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov p += 1; /* skip padding */ 856ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* fall-through */ 857ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 858ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov case 9: 859ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov loader = tt_sbit_decoder_load_compound; 860ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov break; 861ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 862ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#ifdef FT_CONFIG_OPTION_USE_PNG 863ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov case 17: /* small metrics, PNG image data */ 864ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov case 18: /* big metrics, PNG image data */ 865ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov case 19: /* metrics in EBLC, PNG image data */ 866ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov loader = tt_sbit_decoder_load_png; 867ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov break; 868ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif /* FT_CONFIG_OPTION_USE_PNG */ 869ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 870ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov default: 871ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = FT_THROW( Invalid_Table ); 872ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Fail; 873ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 874ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 875ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( !decoder->bitmap_allocated ) 876ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 877ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = tt_sbit_decoder_alloc_bitmap( decoder, load_flags ); 878ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( error ) 879ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Fail; 880ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 881ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 882ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( decoder->bit_depth == 32 && 883ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov decoder->bitmap->pixel_mode != FT_PIXEL_MODE_BGRA ) 884ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 885ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Flatten color bitmaps if color was not requested. */ 886ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 887ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Library library = decoder->face->root.glyph->library; 888ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Memory memory = decoder->stream->memory; 889ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 890ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Bitmap color, *orig; 891ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 892ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 893ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( decoder->bitmap->pixel_mode != FT_PIXEL_MODE_GRAY || 894ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov x_pos != 0 || y_pos != 0 ) 895ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 896ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Shouldn't happen. */ 897ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = FT_THROW( Invalid_Table ); 898ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Fail; 899ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 900ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 901ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Bitmap_New( &color ); 902ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 903ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov color.rows = decoder->bitmap->rows; 904ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov color.width = decoder->bitmap->width; 905ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov color.pitch = color.width * 4; 906ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov color.pixel_mode = FT_PIXEL_MODE_BGRA; 907ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 908ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( FT_ALLOC( color.buffer, color.rows * color.pitch ) ) 909ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Fail; 910ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 911ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov orig = decoder->bitmap; 912ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov decoder->bitmap = &color; 913ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 914ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = loader( decoder, load_flags, p, p_limit, x_pos, y_pos ); 915ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 916ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov decoder->bitmap = orig; 917ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 918ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* explicitly test against FT_Err_Ok to avoid compiler warnings */ 919ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* (we do an assignment within a conditional) */ 920ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( error || 921ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ( error = FT_Bitmap_Convert( library, 922ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov &color, 923ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov decoder->bitmap, 924ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1 ) ) != FT_Err_Ok ) 925ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 926ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Bitmap_Done( library, &color ); 927ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Fail; 928ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 929ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 930ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Bitmap_Done( library, &color ); 931ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 932ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 933ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else 934ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = loader( decoder, load_flags, p, p_limit, x_pos, y_pos ); 935ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 936ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 937ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Fail: 938ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FRAME_RELEASE( data ); 939ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 940ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Exit: 941ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return error; 942ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 943ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 944ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 945ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov static FT_Error 946ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov tt_sbit_decoder_load_image( TT_SBitDecoder decoder, 947ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt load_flags, 948ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt glyph_index, 949ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Int x_pos, 950ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Int y_pos ) 951ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 952ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* 953ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * First, we find the correct strike range that applies to this 954ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * glyph index. 955ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov */ 956ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 957ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte* p = decoder->eblc_base + decoder->strike_index_array; 958ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte* p_limit = decoder->eblc_limit; 959ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ULong num_ranges = decoder->strike_index_count; 960ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt start, end, index_format, image_format; 961ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ULong image_start = 0, image_end = 0, image_offset; 962ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 963ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 964ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for ( ; num_ranges > 0; num_ranges-- ) 965ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 966ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov start = FT_NEXT_USHORT( p ); 967ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov end = FT_NEXT_USHORT( p ); 968ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 969ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( glyph_index >= start && glyph_index <= end ) 970ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto FoundRange; 971ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 972ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov p += 4; /* ignore index offset */ 973ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 974ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto NoBitmap; 975ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 976ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FoundRange: 977ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov image_offset = FT_NEXT_ULONG( p ); 978ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 979ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* overflow check */ 980ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov p = decoder->eblc_base + decoder->strike_index_array; 981ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( image_offset > (FT_ULong)( p_limit - p ) ) 982ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Failure; 983ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 984ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov p += image_offset; 985ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( p + 8 > p_limit ) 986ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto NoBitmap; 987ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 988ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* now find the glyph's location and extend within the ebdt table */ 989ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov index_format = FT_NEXT_USHORT( p ); 990ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov image_format = FT_NEXT_USHORT( p ); 991ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov image_offset = FT_NEXT_ULONG ( p ); 992ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 993ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov switch ( index_format ) 994ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 995ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov case 1: /* 4-byte offsets relative to `image_offset' */ 996ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 997ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov p += 4 * ( glyph_index - start ); 998ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( p + 8 > p_limit ) 999ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto NoBitmap; 1000ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1001ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov image_start = FT_NEXT_ULONG( p ); 1002ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov image_end = FT_NEXT_ULONG( p ); 1003ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1004ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( image_start == image_end ) /* missing glyph */ 1005ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto NoBitmap; 1006ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1007ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov break; 1008ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1009ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov case 2: /* big metrics, constant image size */ 1010ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1011ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ULong image_size; 1012ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1013ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1014ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( p + 12 > p_limit ) 1015ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto NoBitmap; 1016ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1017ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov image_size = FT_NEXT_ULONG( p ); 1018ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1019ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( tt_sbit_decoder_load_metrics( decoder, &p, p_limit, 1 ) ) 1020ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto NoBitmap; 1021ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1022ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov image_start = image_size * ( glyph_index - start ); 1023ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov image_end = image_start + image_size; 1024ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1025ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov break; 1026ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1027ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov case 3: /* 2-byte offsets relative to 'image_offset' */ 1028ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1029ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov p += 2 * ( glyph_index - start ); 1030ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( p + 4 > p_limit ) 1031ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto NoBitmap; 1032ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1033ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov image_start = FT_NEXT_USHORT( p ); 1034ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov image_end = FT_NEXT_USHORT( p ); 1035ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1036ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( image_start == image_end ) /* missing glyph */ 1037ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto NoBitmap; 1038ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1039ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov break; 1040ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1041ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov case 4: /* sparse glyph array with (glyph,offset) pairs */ 1042ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1043ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ULong mm, num_glyphs; 1044ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1045ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1046ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( p + 4 > p_limit ) 1047ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto NoBitmap; 1048ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1049ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov num_glyphs = FT_NEXT_ULONG( p ); 1050ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1051ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* overflow check for p + ( num_glyphs + 1 ) * 4 */ 1052ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( num_glyphs > (FT_ULong)( ( ( p_limit - p ) >> 2 ) - 1 ) ) 1053ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto NoBitmap; 1054ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1055ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for ( mm = 0; mm < num_glyphs; mm++ ) 1056ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1057ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt gindex = FT_NEXT_USHORT( p ); 1058ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1059ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1060ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( gindex == glyph_index ) 1061ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1062ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov image_start = FT_NEXT_USHORT( p ); 1063ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov p += 2; 1064ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov image_end = FT_PEEK_USHORT( p ); 1065ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov break; 1066ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1067ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov p += 2; 1068ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1069ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1070ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( mm >= num_glyphs ) 1071ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto NoBitmap; 1072ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1073ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov break; 1074ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1075ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov case 5: /* constant metrics with sparse glyph codes */ 1076ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov case 19: 1077ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1078ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ULong image_size, mm, num_glyphs; 1079ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1080ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1081ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( p + 16 > p_limit ) 1082ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto NoBitmap; 1083ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1084ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov image_size = FT_NEXT_ULONG( p ); 1085ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1086ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( tt_sbit_decoder_load_metrics( decoder, &p, p_limit, 1 ) ) 1087ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto NoBitmap; 1088ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1089ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov num_glyphs = FT_NEXT_ULONG( p ); 1090ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1091ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* overflow check for p + 2 * num_glyphs */ 1092ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( num_glyphs > (FT_ULong)( ( p_limit - p ) >> 1 ) ) 1093ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto NoBitmap; 1094ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1095ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for ( mm = 0; mm < num_glyphs; mm++ ) 1096ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1097ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt gindex = FT_NEXT_USHORT( p ); 1098ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1099ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1100ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( gindex == glyph_index ) 1101ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov break; 1102ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1103ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1104ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( mm >= num_glyphs ) 1105ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto NoBitmap; 1106ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1107ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov image_start = image_size * mm; 1108ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov image_end = image_start + image_size; 1109ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1110ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov break; 1111ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1112ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov default: 1113ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto NoBitmap; 1114ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1115ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1116ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( image_start > image_end ) 1117ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto NoBitmap; 1118ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1119ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov image_end -= image_start; 1120ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov image_start = image_offset + image_start; 1121ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1122ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_TRACE3(( "tt_sbit_decoder_load_image:" 1123ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov " found sbit (format %d) for glyph index %d\n", 1124ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov image_format, glyph_index )); 1125ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1126ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return tt_sbit_decoder_load_bitmap( decoder, 1127ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov load_flags, 1128ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov image_format, 1129ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov image_start, 1130ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov image_end, 1131ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov x_pos, 1132ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov y_pos ); 1133ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1134ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Failure: 1135ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FT_THROW( Invalid_Table ); 1136ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1137ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov NoBitmap: 1138ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_TRACE4(( "tt_sbit_decoder_load_image:" 1139ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov " no sbit found for glyph index %d\n", glyph_index )); 1140ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1141ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FT_THROW( Invalid_Argument ); 1142ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1143ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1144ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1145ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_LOCAL( FT_Error ) 1146ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov tt_face_load_sbit_image( TT_Face face, 1147ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ULong strike_index, 1148ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt glyph_index, 1149ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt load_flags, 1150ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Stream stream, 1151ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Bitmap *map, 1152ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov TT_SBit_MetricsRec *metrics ) 1153ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1154ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov TT_SBitDecoderRec decoder[1]; 1155ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Error error; 1156ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1157ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UNUSED( load_flags ); 1158ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UNUSED( stream ); 1159ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UNUSED( map ); 1160ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1161ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1162ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = tt_sbit_decoder_init( decoder, face, strike_index, metrics ); 1163ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( !error ) 1164ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1165ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = tt_sbit_decoder_load_image( decoder, 1166ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov load_flags, 1167ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov glyph_index, 1168ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 0, 1169ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 0 ); 1170ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov tt_sbit_decoder_done( decoder ); 1171ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1172ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1173ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return error; 1174ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1175ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1176ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1177ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* EOF */ 1178