1049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/***************************************************************************/ 2049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/* */ 3049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/* ttsbit.c */ 4049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/* */ 5049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/* TrueType and OpenType embedded bitmap support (body). */ 6049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/* */ 79c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod/* Copyright 2005-2009, 2013, 2014 by */ 8049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/* David Turner, Robert Wilhelm, and Werner Lemberg. */ 9049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/* */ 10727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease/* Copyright 2013 by Google, Inc. */ 11727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease/* Google Author(s): Behdad Esfahbod. */ 12727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease/* */ 13049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/* This file is part of the FreeType project, and may only be used, */ 14049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/* modified, and distributed under the terms of the FreeType project */ 15049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ 16049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/* this file you indicate that you have read the license and */ 17049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/* understand and accept it fully. */ 18049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/* */ 19049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/***************************************************************************/ 20049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 21049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 22049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include <ft2build.h> 23049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include FT_INTERNAL_DEBUG_H 24049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include FT_INTERNAL_STREAM_H 25049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include FT_TRUETYPE_TAGS_H 26727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease#include FT_BITMAP_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 31ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease#include "ttmtx.h" 32727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease#include "pngshim.h" 33727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease 34049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 35049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /*************************************************************************/ 36049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 37049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ 38049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ 39049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* messages during execution. */ 40049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 41049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#undef FT_COMPONENT 42049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define FT_COMPONENT trace_ttsbit 43049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 44049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 45727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease FT_LOCAL_DEF( FT_Error ) 46ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease tt_face_load_sbit( TT_Face face, 47727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease FT_Stream stream ) 48049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 49ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease FT_Error error; 50ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease FT_ULong table_size; 51049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 52049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 53ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease face->sbit_table = NULL; 54ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease face->sbit_table_size = 0; 55ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease face->sbit_table_type = TT_SBIT_TABLE_TYPE_NONE; 56727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease face->sbit_num_strikes = 0; 57727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease 58727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease error = face->goto_table( face, TTAG_CBLC, stream, &table_size ); 59ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease if ( !error ) 60ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease face->sbit_table_type = TT_SBIT_TABLE_TYPE_CBLC; 61ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease else 62ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease { 63727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease error = face->goto_table( face, TTAG_EBLC, stream, &table_size ); 64ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease if ( error ) 65ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease error = face->goto_table( face, TTAG_bloc, stream, &table_size ); 66ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease if ( !error ) 67ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease face->sbit_table_type = TT_SBIT_TABLE_TYPE_EBLC; 68ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease } 69ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease 70727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease if ( error ) 71ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease { 72ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease error = face->goto_table( face, TTAG_sbix, stream, &table_size ); 73ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease if ( !error ) 74ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease face->sbit_table_type = TT_SBIT_TABLE_TYPE_SBIX; 75ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease } 76727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease if ( error ) 77727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease goto Exit; 78049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 79727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease if ( table_size < 8 ) 80727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease { 81727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease FT_ERROR(( "tt_face_load_sbit_strikes: table too short\n" )); 82727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease error = FT_THROW( Invalid_File_Format ); 83727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease goto Exit; 84727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease } 85049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 86ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease switch ( (FT_UInt)face->sbit_table_type ) 87ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease { 88ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease case TT_SBIT_TABLE_TYPE_EBLC: 89ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease case TT_SBIT_TABLE_TYPE_CBLC: 90ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease { 91ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease FT_Byte* p; 92ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease FT_Fixed version; 93ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease FT_ULong num_strikes; 94ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease FT_UInt count; 95049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 96049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 97ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease if ( FT_FRAME_EXTRACT( table_size, face->sbit_table ) ) 98ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease goto Exit; 99049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 100ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease face->sbit_table_size = table_size; 101049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 102ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease p = face->sbit_table; 103ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease 104ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease version = FT_NEXT_ULONG( p ); 105ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease num_strikes = FT_NEXT_ULONG( p ); 106ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease 107ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease if ( ( version & 0xFFFF0000UL ) != 0x00020000UL ) 108ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease { 109ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease error = FT_THROW( Unknown_File_Format ); 110ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease goto Exit; 111ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease } 112ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease 113ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease if ( num_strikes >= 0x10000UL ) 114ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease { 115ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease error = FT_THROW( Invalid_File_Format ); 116ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease goto Exit; 117ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease } 118ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease 119ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease /* 120ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease * Count the number of strikes available in the table. We are a bit 121ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease * paranoid there and don't trust the data. 122ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease */ 123ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease count = (FT_UInt)num_strikes; 124ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease if ( 8 + 48UL * count > table_size ) 125ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease count = (FT_UInt)( ( table_size - 8 ) / 48 ); 126ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease 127ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease face->sbit_num_strikes = count; 128ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease } 129ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease break; 130ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease 131ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease case TT_SBIT_TABLE_TYPE_SBIX: 132ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease { 133ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease FT_UShort version; 134ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease FT_UShort flags; 135ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease FT_ULong num_strikes; 136ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease FT_UInt count; 137ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease 138ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease 139ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease if ( FT_FRAME_ENTER( 8 ) ) 140ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease goto Exit; 141ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease 142ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease version = FT_GET_USHORT(); 143ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease flags = FT_GET_USHORT(); 144ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease num_strikes = FT_GET_ULONG(); 145ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease 146ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease FT_FRAME_EXIT(); 147ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease 148ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease if ( version < 1 ) 149ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease { 150ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease error = FT_THROW( Unknown_File_Format ); 151ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease goto Exit; 152ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease } 153ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease if ( flags != 0x0001 || num_strikes >= 0x10000UL ) 154ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease { 155ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease error = FT_THROW( Invalid_File_Format ); 156ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease goto Exit; 157ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease } 158ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease 159ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease /* 160ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease * Count the number of strikes available in the table. We are a bit 161ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease * paranoid there and don't trust the data. 162ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease */ 163ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease count = (FT_UInt)num_strikes; 164ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease if ( 8 + 4UL * count > table_size ) 165ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease count = (FT_UInt)( ( table_size - 8 ) / 4 ); 166ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease 167ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease if ( FT_STREAM_SEEK( FT_STREAM_POS() - 8 ) ) 168ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease goto Exit; 169ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease 170ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease face->sbit_table_size = 8 + count * 4; 171ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease if ( FT_FRAME_EXTRACT( face->sbit_table_size, face->sbit_table ) ) 172ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease goto Exit; 173ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease 174ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease face->sbit_num_strikes = count; 175ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease } 176ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease break; 177ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease 178ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease default: 179ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease error = FT_THROW( Unknown_File_Format ); 180ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease break; 181727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease } 182049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 183ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease if ( !error ) 184ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease FT_TRACE3(( "sbit_num_strikes: %u\n", face->sbit_num_strikes )); 185049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 186ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease return FT_Err_Ok; 187049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 188727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease Exit: 189ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease if ( error ) 190ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease { 191ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease if ( face->sbit_table ) 192ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease FT_FRAME_RELEASE( face->sbit_table ); 193ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease face->sbit_table_size = 0; 194ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease face->sbit_table_type = TT_SBIT_TABLE_TYPE_NONE; 195ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease } 196049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 197ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease return error; 198727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease } 199049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 200049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 201727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease FT_LOCAL_DEF( void ) 202ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease tt_face_free_sbit( TT_Face face ) 203727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease { 204727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease FT_Stream stream = face->root.stream; 205049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 206049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 207727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease FT_FRAME_RELEASE( face->sbit_table ); 208727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease face->sbit_table_size = 0; 209ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease face->sbit_table_type = TT_SBIT_TABLE_TYPE_NONE; 210727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease face->sbit_num_strikes = 0; 211727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease } 212049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 213049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 214727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease FT_LOCAL_DEF( FT_Error ) 215727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease tt_face_set_sbit_strike( TT_Face face, 216727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease FT_Size_Request req, 217727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease FT_ULong* astrike_index ) 218727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease { 219727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease return FT_Match_Size( (FT_Face)face, req, 0, astrike_index ); 220049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 221049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 222049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 223727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease FT_LOCAL_DEF( FT_Error ) 224727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease tt_face_load_strike_metrics( TT_Face face, 225727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease FT_ULong strike_index, 226727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease FT_Size_Metrics* metrics ) 227049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 228727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease if ( strike_index >= (FT_ULong)face->sbit_num_strikes ) 229727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease return FT_THROW( Invalid_Argument ); 230049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 231ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease switch ( (FT_UInt)face->sbit_table_type ) 232ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease { 233ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease case TT_SBIT_TABLE_TYPE_EBLC: 234ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease case TT_SBIT_TABLE_TYPE_CBLC: 235ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease { 236ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease FT_Byte* strike; 237049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 238049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 239ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease strike = face->sbit_table + 8 + strike_index * 48; 240727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease 241ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease metrics->x_ppem = (FT_UShort)strike[44]; 242ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease metrics->y_ppem = (FT_UShort)strike[45]; 243727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease 244ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease metrics->ascender = (FT_Char)strike[16] << 6; /* hori.ascender */ 245ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease metrics->descender = (FT_Char)strike[17] << 6; /* hori.descender */ 246ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease metrics->height = metrics->ascender - metrics->descender; 247ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease 248ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease /* Is this correct? */ 249ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease metrics->max_advance = ( (FT_Char)strike[22] + /* min_origin_SB */ 250ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease strike[18] + /* max_width */ 251ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease (FT_Char)strike[23] /* min_advance_SB */ 252ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease ) << 6; 253ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease return FT_Err_Ok; 254ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease } 255ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease 256ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease case TT_SBIT_TABLE_TYPE_SBIX: 257ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease { 258ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease FT_Stream stream = face->root.stream; 2599c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod FT_UInt offset, upem; 2609c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod FT_UShort ppem, resolution; 261ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease TT_HoriHeader *hori; 262ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease FT_ULong table_size; 263ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease 264ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease FT_Error error; 265ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease FT_Byte* p; 266ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease 267ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease 268ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease p = face->sbit_table + 8 + 4 * strike_index; 269ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease offset = FT_NEXT_ULONG( p ); 270ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease 271ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease error = face->goto_table( face, TTAG_sbix, stream, &table_size ); 272ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease if ( error ) 273ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease return error; 274ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease 275ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease if ( offset + 4 > table_size ) 276ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease return FT_THROW( Invalid_File_Format ); 277ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease 278ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease if ( FT_STREAM_SEEK( FT_STREAM_POS() + offset ) || 279ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease FT_FRAME_ENTER( 4 ) ) 280ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease return error; 281ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease 282ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease ppem = FT_GET_USHORT(); 283ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease resolution = FT_GET_USHORT(); 284ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease 285ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease FT_UNUSED( resolution ); /* What to do with this? */ 286ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease 287ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease FT_FRAME_EXIT(); 288ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease 289ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease upem = face->header.Units_Per_EM; 290ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease hori = &face->horizontal; 291ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease 292ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease metrics->x_ppem = ppem; 293ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease metrics->y_ppem = ppem; 294ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease 295ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease metrics->ascender = ppem * hori->Ascender * 64 / upem; 296ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease metrics->descender = ppem * hori->Descender * 64 / upem; 297ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease metrics->height = ppem * ( hori->Ascender - 298ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease hori->Descender + 299ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease hori->Line_Gap ) * 64 / upem; 300ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease metrics->max_advance = ppem * hori->advance_Width_Max * 64 / upem; 301ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease 302ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease return error; 303ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease } 304ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease 305ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease default: 306ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease return FT_THROW( Unknown_File_Format ); 307ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease } 308727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease } 309727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease 310727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease 311727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease typedef struct TT_SBitDecoderRec_ 312049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 313727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease TT_Face face; 314727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease FT_Stream stream; 315727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease FT_Bitmap* bitmap; 316727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease TT_SBit_Metrics metrics; 317727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease FT_Bool metrics_loaded; 318727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease FT_Bool bitmap_allocated; 319727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease FT_Byte bit_depth; 320049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 321727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease FT_ULong ebdt_start; 322727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease FT_ULong ebdt_size; 323049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 324727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease FT_ULong strike_index_array; 325727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease FT_ULong strike_index_count; 326727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease FT_Byte* eblc_base; 327727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease FT_Byte* eblc_limit; 328049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 329727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease } TT_SBitDecoderRec, *TT_SBitDecoder; 330049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 331049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 332049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project static FT_Error 333727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease tt_sbit_decoder_init( TT_SBitDecoder decoder, 334727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease TT_Face face, 335727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease FT_ULong strike_index, 336727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease TT_SBit_MetricsRec* metrics ) 337049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 338049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Error error; 339727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease FT_Stream stream = face->root.stream; 340727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease FT_ULong ebdt_size; 341049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 342049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 343727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease error = face->goto_table( face, TTAG_CBDT, stream, &ebdt_size ); 344727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease if ( error ) 345727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease error = face->goto_table( face, TTAG_EBDT, stream, &ebdt_size ); 346727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease if ( error ) 347727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease error = face->goto_table( face, TTAG_bdat, stream, &ebdt_size ); 348727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease if ( error ) 349049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project goto Exit; 350049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 351727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease decoder->face = face; 352727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease decoder->stream = stream; 353727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease decoder->bitmap = &face->root.glyph->bitmap; 354727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease decoder->metrics = metrics; 355049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 356727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease decoder->metrics_loaded = 0; 357727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease decoder->bitmap_allocated = 0; 358049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 359727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease decoder->ebdt_start = FT_STREAM_POS(); 360727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease decoder->ebdt_size = ebdt_size; 361049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 362727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease decoder->eblc_base = face->sbit_table; 363727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease decoder->eblc_limit = face->sbit_table + face->sbit_table_size; 364049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 365727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease /* now find the strike corresponding to the index */ 366049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 367727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease FT_Byte* p; 368049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 369049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 370727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease if ( 8 + 48 * strike_index + 3 * 4 + 34 + 1 > face->sbit_table_size ) 371727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease { 372727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease error = FT_THROW( Invalid_File_Format ); 373727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease goto Exit; 374727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease } 375727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease 376727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease p = decoder->eblc_base + 8 + 48 * strike_index; 377727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease 378727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease decoder->strike_index_array = FT_NEXT_ULONG( p ); 379727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease p += 4; 380727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease decoder->strike_index_count = FT_NEXT_ULONG( p ); 381727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease p += 34; 382727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease decoder->bit_depth = *p; 383727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease 384727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease if ( decoder->strike_index_array > face->sbit_table_size || 385727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease decoder->strike_index_array + 8 * decoder->strike_index_count > 386727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease face->sbit_table_size ) 387727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease error = FT_THROW( Invalid_File_Format ); 388727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease } 389049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 390049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project Exit: 391049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return error; 392049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 393049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 394049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 395727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease static void 396727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease tt_sbit_decoder_done( TT_SBitDecoder decoder ) 397049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 398727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease FT_UNUSED( decoder ); 399727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease } 400049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 401049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 402727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease static FT_Error 403ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease tt_sbit_decoder_alloc_bitmap( TT_SBitDecoder decoder ) 404727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease { 405727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease FT_Error error = FT_Err_Ok; 406727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease FT_UInt width, height; 407727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease FT_Bitmap* map = decoder->bitmap; 408727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease FT_Long size; 409049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 410049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 411727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease if ( !decoder->metrics_loaded ) 412727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease { 413727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease error = FT_THROW( Invalid_Argument ); 414727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease goto Exit; 415727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease } 416049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 417727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease width = decoder->metrics->width; 418727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease height = decoder->metrics->height; 419049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 420727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease map->width = (int)width; 421727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease map->rows = (int)height; 422049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 423727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease switch ( decoder->bit_depth ) 424727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease { 425727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease case 1: 426727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease map->pixel_mode = FT_PIXEL_MODE_MONO; 427727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease map->pitch = ( map->width + 7 ) >> 3; 428727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease map->num_grays = 2; 429049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project break; 430049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 431727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease case 2: 432727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease map->pixel_mode = FT_PIXEL_MODE_GRAY2; 433727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease map->pitch = ( map->width + 3 ) >> 2; 434727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease map->num_grays = 4; 435049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project break; 436049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 437049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project case 4: 438727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease map->pixel_mode = FT_PIXEL_MODE_GRAY4; 439727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease map->pitch = ( map->width + 1 ) >> 1; 440727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease map->num_grays = 16; 441727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease break; 442727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease 443727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease case 8: 444727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease map->pixel_mode = FT_PIXEL_MODE_GRAY; 445727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease map->pitch = map->width; 446727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease map->num_grays = 256; 447049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project break; 448049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 449727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease case 32: 450ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease map->pixel_mode = FT_PIXEL_MODE_BGRA; 451ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease map->pitch = map->width * 4; 452ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease map->num_grays = 256; 453049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project break; 454049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 455049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project default: 456727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease error = FT_THROW( Invalid_File_Format ); 457727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease goto Exit; 458049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 459049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 460727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease size = map->rows * map->pitch; 461727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease 462727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease /* check that there is no empty image */ 463727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease if ( size == 0 ) 464727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease goto Exit; /* exit successfully! */ 465727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease 466727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease error = ft_glyphslot_alloc_bitmap( decoder->face->root.glyph, size ); 467727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease if ( error ) 468727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease goto Exit; 469727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease 470727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease decoder->bitmap_allocated = 1; 471727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease 472049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project Exit: 473049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return error; 474049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 475049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 476049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 477727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease static FT_Error 478727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease tt_sbit_decoder_load_metrics( TT_SBitDecoder decoder, 479727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease FT_Byte* *pp, 480727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease FT_Byte* limit, 481727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease FT_Bool big ) 482049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 483727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease FT_Byte* p = *pp; 484727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease TT_SBit_Metrics metrics = decoder->metrics; 485049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 486727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease 487727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease if ( p + 5 > limit ) 488727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease goto Fail; 489727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease 490727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease metrics->height = p[0]; 491727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease metrics->width = p[1]; 492727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease metrics->horiBearingX = (FT_Char)p[2]; 493727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease metrics->horiBearingY = (FT_Char)p[3]; 494727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease metrics->horiAdvance = p[4]; 495727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease 496727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease p += 5; 497727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease if ( big ) 498049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 499727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease if ( p + 3 > limit ) 500727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease goto Fail; 501049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 502727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease metrics->vertBearingX = (FT_Char)p[0]; 503727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease metrics->vertBearingY = (FT_Char)p[1]; 504727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease metrics->vertAdvance = p[2]; 505049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 506727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease p += 3; 507727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease } 508049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 509727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease decoder->metrics_loaded = 1; 510727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease *pp = p; 511727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease return FT_Err_Ok; 512049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 513727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease Fail: 514727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease FT_TRACE1(( "tt_sbit_decoder_load_metrics: broken table" )); 515727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease return FT_THROW( Invalid_Argument ); 516727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease } 517049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 518049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 519727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease /* forward declaration */ 520727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease static FT_Error 521727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease tt_sbit_decoder_load_image( TT_SBitDecoder decoder, 522727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease FT_UInt glyph_index, 523727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease FT_Int x_pos, 524727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease FT_Int y_pos ); 525049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 526727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease typedef FT_Error (*TT_SBitDecoder_LoadFunc)( TT_SBitDecoder decoder, 527727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease FT_Byte* p, 528727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease FT_Byte* plimit, 529727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease FT_Int x_pos, 530727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease FT_Int y_pos ); 531049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 532049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 533727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease static FT_Error 534727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease tt_sbit_decoder_load_byte_aligned( TT_SBitDecoder decoder, 535727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease FT_Byte* p, 536727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease FT_Byte* limit, 537727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease FT_Int x_pos, 538727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease FT_Int y_pos ) 539727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease { 540727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease FT_Error error = FT_Err_Ok; 541727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease FT_Byte* line; 542727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease FT_Int bit_height, bit_width, pitch, width, height, line_bits, h; 543727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease FT_Bitmap* bitmap; 544049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 545049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 546727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease /* check that we can write the glyph into the bitmap */ 547727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease bitmap = decoder->bitmap; 548727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease bit_width = bitmap->width; 549727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease bit_height = bitmap->rows; 550727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease pitch = bitmap->pitch; 551727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease line = bitmap->buffer; 552049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 553727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease width = decoder->metrics->width; 554727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease height = decoder->metrics->height; 555049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 556727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease line_bits = width * decoder->bit_depth; 557049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 558727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease if ( x_pos < 0 || x_pos + width > bit_width || 559727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease y_pos < 0 || y_pos + height > bit_height ) 560727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease { 561727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease FT_TRACE1(( "tt_sbit_decoder_load_byte_aligned:" 562727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease " invalid bitmap dimensions\n" )); 563727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease error = FT_THROW( Invalid_File_Format ); 564727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease goto Exit; 565049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 566049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 567727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease if ( p + ( ( line_bits + 7 ) >> 3 ) * height > limit ) 568049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 569727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease FT_TRACE1(( "tt_sbit_decoder_load_byte_aligned: broken bitmap\n" )); 570727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease error = FT_THROW( Invalid_File_Format ); 571727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease goto Exit; 572727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease } 573049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 574727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease /* now do the blit */ 575727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease line += y_pos * pitch + ( x_pos >> 3 ); 576727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease x_pos &= 7; 577049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 578727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease if ( x_pos == 0 ) /* the easy one */ 579727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease { 580727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease for ( h = height; h > 0; h--, line += pitch ) 581049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 582727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease FT_Byte* pwrite = line; 583727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease FT_Int w; 584049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 585049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 586727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease for ( w = line_bits; w >= 8; w -= 8 ) 587049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 588727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease pwrite[0] = (FT_Byte)( pwrite[0] | *p++ ); 589727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease pwrite += 1; 590049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 591049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 592727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease if ( w > 0 ) 593727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease pwrite[0] = (FT_Byte)( pwrite[0] | ( *p++ & ( 0xFF00U >> w ) ) ); 594727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease } 595727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease } 596727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease else /* x_pos > 0 */ 597727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease { 598727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease for ( h = height; h > 0; h--, line += pitch ) 599727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease { 600727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease FT_Byte* pwrite = line; 601727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease FT_Int w; 602727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease FT_UInt wval = 0; 603727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease 604049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 605727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease for ( w = line_bits; w >= 8; w -= 8 ) 606049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 607727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease wval = (FT_UInt)( wval | *p++ ); 608727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease pwrite[0] = (FT_Byte)( pwrite[0] | ( wval >> x_pos ) ); 609727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease pwrite += 1; 610727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease wval <<= 8; 611727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease } 612049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 613727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease if ( w > 0 ) 614727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease wval = (FT_UInt)( wval | ( *p++ & ( 0xFF00U >> w ) ) ); 615049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 616727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease /* all bits read and there are `x_pos + w' bits to be written */ 617049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 618727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease pwrite[0] = (FT_Byte)( pwrite[0] | ( wval >> x_pos ) ); 619049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 620727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease if ( x_pos + w > 8 ) 621727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease { 622727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease pwrite++; 623727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease wval <<= 8; 624727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease pwrite[0] = (FT_Byte)( pwrite[0] | ( wval >> x_pos ) ); 625049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 626049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 627049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 628049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 629049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project Exit: 630727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease if ( !error ) 631727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease FT_TRACE3(( "tt_sbit_decoder_load_byte_aligned: loaded\n" )); 632049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return error; 633049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 634049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 635049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 636727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease /* 637727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease * Load a bit-aligned bitmap (with pointer `p') into a line-aligned bitmap 638727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease * (with pointer `pwrite'). In the example below, the width is 3 pixel, 639727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease * and `x_pos' is 1 pixel. 640727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease * 641727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease * p p+1 642727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease * | | | 643727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease * | 7 6 5 4 3 2 1 0 | 7 6 5 4 3 2 1 0 |... 644727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease * | | | 645727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease * +-------+ +-------+ +-------+ ... 646727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease * . . . 647727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease * . . . 648727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease * v . . 649727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease * +-------+ . . 650727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease * | | . 651727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease * | 7 6 5 4 3 2 1 0 | . 652727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease * | | . 653727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease * pwrite . . 654727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease * . . 655727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease * v . 656727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease * +-------+ . 657727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease * | | 658727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease * | 7 6 5 4 3 2 1 0 | 659727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease * | | 660727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease * pwrite+1 . 661727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease * . 662727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease * v 663727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease * +-------+ 664727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease * | | 665727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease * | 7 6 5 4 3 2 1 0 | 666727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease * | | 667727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease * pwrite+2 668727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease * 669727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease */ 670727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease 671727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease static FT_Error 672727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease tt_sbit_decoder_load_bit_aligned( TT_SBitDecoder decoder, 673727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease FT_Byte* p, 674727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease FT_Byte* limit, 675727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease FT_Int x_pos, 676727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease FT_Int y_pos ) 677049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 678727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease FT_Error error = FT_Err_Ok; 679727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease FT_Byte* line; 680727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease FT_Int bit_height, bit_width, pitch, width, height, line_bits, h, nbits; 681727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease FT_Bitmap* bitmap; 682727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease FT_UShort rval; 683049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 684049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 685727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease /* check that we can write the glyph into the bitmap */ 686727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease bitmap = decoder->bitmap; 687727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease bit_width = bitmap->width; 688727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease bit_height = bitmap->rows; 689727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease pitch = bitmap->pitch; 690727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease line = bitmap->buffer; 691049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 692727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease width = decoder->metrics->width; 693727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease height = decoder->metrics->height; 694727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease 695727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease line_bits = width * decoder->bit_depth; 696727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease 697727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease if ( x_pos < 0 || x_pos + width > bit_width || 698727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease y_pos < 0 || y_pos + height > bit_height ) 699727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease { 700727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease FT_TRACE1(( "tt_sbit_decoder_load_bit_aligned:" 701727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease " invalid bitmap dimensions\n" )); 702727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease error = FT_THROW( Invalid_File_Format ); 703727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease goto Exit; 704049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 705049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 706727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease if ( p + ( ( line_bits * height + 7 ) >> 3 ) > limit ) 707727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease { 708727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease FT_TRACE1(( "tt_sbit_decoder_load_bit_aligned: broken bitmap\n" )); 709727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease error = FT_THROW( Invalid_File_Format ); 710727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease goto Exit; 711727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease } 712049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 713727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease /* now do the blit */ 714049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 715727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease /* adjust `line' to point to the first byte of the bitmap */ 716727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease line += y_pos * pitch + ( x_pos >> 3 ); 717727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease x_pos &= 7; 718049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 719727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease /* the higher byte of `rval' is used as a buffer */ 720727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease rval = 0; 721727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease nbits = 0; 722049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 723727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease for ( h = height; h > 0; h--, line += pitch ) 724727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease { 725727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease FT_Byte* pwrite = line; 726727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease FT_Int w = line_bits; 727049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 728049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 729727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease /* handle initial byte (in target bitmap) specially if necessary */ 730727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease if ( x_pos ) 731727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease { 732727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease w = ( line_bits < 8 - x_pos ) ? line_bits : 8 - x_pos; 733049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 734727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease if ( h == height ) 735727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease { 736727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease rval = *p++; 737727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease nbits = x_pos; 738727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease } 739727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease else if ( nbits < w ) 740727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease { 741727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease if ( p < limit ) 742727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease rval |= *p++; 743727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease nbits += 8 - w; 744727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease } 745727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease else 746727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease { 747727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease rval >>= 8; 748727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease nbits -= w; 749727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease } 750049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 751727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease *pwrite++ |= ( ( rval >> nbits ) & 0xFF ) & 752727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease ( ~( 0xFF << w ) << ( 8 - w - x_pos ) ); 753727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease rval <<= 8; 754049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 755727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease w = line_bits - w; 756727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease } 757049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 758727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease /* handle medial bytes */ 759727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease for ( ; w >= 8; w -= 8 ) 760727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease { 761727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease rval |= *p++; 762727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease *pwrite++ |= ( rval >> nbits ) & 0xFF; 763049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 764727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease rval <<= 8; 765727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease } 766727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease 767727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease /* handle final byte if necessary */ 768727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease if ( w > 0 ) 769727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease { 770727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease if ( nbits < w ) 771727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease { 772727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease if ( p < limit ) 773727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease rval |= *p++; 774727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease *pwrite |= ( ( rval >> nbits ) & 0xFF ) & ( 0xFF00U >> w ); 775727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease nbits += 8 - w; 776727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease 777727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease rval <<= 8; 778727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease } 779727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease else 780727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease { 781727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease *pwrite |= ( ( rval >> nbits ) & 0xFF ) & ( 0xFF00U >> w ); 782727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease nbits -= w; 783727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease } 784727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease } 785727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease } 786727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease 787727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease Exit: 788727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease if ( !error ) 789727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease FT_TRACE3(( "tt_sbit_decoder_load_bit_aligned: loaded\n" )); 790727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease return error; 791727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease } 792049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 793049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 794049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project static FT_Error 795727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease tt_sbit_decoder_load_compound( TT_SBitDecoder decoder, 796727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease FT_Byte* p, 797727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease FT_Byte* limit, 798727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease FT_Int x_pos, 799727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease FT_Int y_pos ) 800049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 801727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease FT_Error error = FT_Err_Ok; 802727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease FT_UInt num_components, nn; 803049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 8049c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod FT_Char horiBearingX = (FT_Char)decoder->metrics->horiBearingX; 8059c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod FT_Char horiBearingY = (FT_Char)decoder->metrics->horiBearingY; 8069c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod FT_Byte horiAdvance = (FT_Byte)decoder->metrics->horiAdvance; 8079c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod FT_Char vertBearingX = (FT_Char)decoder->metrics->vertBearingX; 8089c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod FT_Char vertBearingY = (FT_Char)decoder->metrics->vertBearingY; 8099c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod FT_Byte vertAdvance = (FT_Byte)decoder->metrics->vertAdvance; 810049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 811049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 812727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease if ( p + 2 > limit ) 813049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project goto Fail; 814049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 815727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease num_components = FT_NEXT_USHORT( p ); 816727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease if ( p + 4 * num_components > limit ) 817049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 818727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease FT_TRACE1(( "tt_sbit_decoder_load_compound: broken table\n" )); 819727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease goto Fail; 820727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease } 821049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 822727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease FT_TRACE3(( "tt_sbit_decoder_load_compound: loading %d components\n", 823727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease num_components )); 824049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 825727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease for ( nn = 0; nn < num_components; nn++ ) 826727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease { 827727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease FT_UInt gindex = FT_NEXT_USHORT( p ); 828727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease FT_Byte dx = FT_NEXT_BYTE( p ); 829727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease FT_Byte dy = FT_NEXT_BYTE( p ); 830049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 831049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 832727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease /* NB: a recursive call */ 833ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease error = tt_sbit_decoder_load_image( decoder, gindex, 834727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease x_pos + dx, y_pos + dy ); 835727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease if ( error ) 836727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease break; 837049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 838049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 839727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease FT_TRACE3(( "tt_sbit_decoder_load_compound: done\n" )); 840049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 841727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease decoder->metrics->horiBearingX = horiBearingX; 842727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease decoder->metrics->horiBearingY = horiBearingY; 843727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease decoder->metrics->horiAdvance = horiAdvance; 844727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease decoder->metrics->vertBearingX = vertBearingX; 845727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease decoder->metrics->vertBearingY = vertBearingY; 846727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease decoder->metrics->vertAdvance = vertAdvance; 847727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease decoder->metrics->width = (FT_Byte)decoder->bitmap->width; 848727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease decoder->metrics->height = (FT_Byte)decoder->bitmap->rows; 849049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 850727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease Exit: 851727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease return error; 852049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 853727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease Fail: 854727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease error = FT_THROW( Invalid_File_Format ); 855727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease goto Exit; 856727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease } 857049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 858049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 859727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease#ifdef FT_CONFIG_OPTION_USE_PNG 860049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 861727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease static FT_Error 862727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease tt_sbit_decoder_load_png( TT_SBitDecoder decoder, 863727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease FT_Byte* p, 864727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease FT_Byte* limit, 865727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease FT_Int x_pos, 866727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease FT_Int y_pos ) 867727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease { 868727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease FT_Error error = FT_Err_Ok; 869727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease FT_ULong png_len; 870049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 871049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 872727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease if ( limit - p < 4 ) 873727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease { 874727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease FT_TRACE1(( "tt_sbit_decoder_load_png: broken bitmap\n" )); 875727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease error = FT_THROW( Invalid_File_Format ); 876727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease goto Exit; 877727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease } 878049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 879727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease png_len = FT_NEXT_ULONG( p ); 880727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease if ( (FT_ULong)( limit - p ) < png_len ) 881727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease { 882727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease FT_TRACE1(( "tt_sbit_decoder_load_png: broken bitmap\n" )); 883727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease error = FT_THROW( Invalid_File_Format ); 884727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease goto Exit; 885727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease } 886727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease 887ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease error = Load_SBit_Png( decoder->face->root.glyph, 888727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease x_pos, 889727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease y_pos, 890727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease decoder->bit_depth, 891727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease decoder->metrics, 892727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease decoder->stream->memory, 893727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease p, 894ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease png_len, 895ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease FALSE ); 896049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 897727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease Exit: 898727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease if ( !error ) 899727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease FT_TRACE3(( "tt_sbit_decoder_load_png: loaded\n" )); 900727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease return error; 901049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 902049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 903727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease#endif /* FT_CONFIG_OPTION_USE_PNG */ 904049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 905727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease 906727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease static FT_Error 907727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease tt_sbit_decoder_load_bitmap( TT_SBitDecoder decoder, 908727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease FT_UInt glyph_format, 909727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease FT_ULong glyph_start, 910727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease FT_ULong glyph_size, 911727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease FT_Int x_pos, 912727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease FT_Int y_pos ) 913049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 914727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease FT_Error error; 915727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease FT_Stream stream = decoder->stream; 916727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease FT_Byte* p; 917727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease FT_Byte* p_limit; 918727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease FT_Byte* data; 919049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 920049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 921727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease /* seek into the EBDT table now */ 922727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease if ( glyph_start + glyph_size > decoder->ebdt_size ) 923727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease { 924727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease error = FT_THROW( Invalid_Argument ); 925727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease goto Exit; 926727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease } 927727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease 928727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease if ( FT_STREAM_SEEK( decoder->ebdt_start + glyph_start ) || 929727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease FT_FRAME_EXTRACT( glyph_size, data ) ) 930727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease goto Exit; 931727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease 932727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease p = data; 933727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease p_limit = p + glyph_size; 934727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease 935727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease /* read the data, depending on the glyph format */ 936727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease switch ( glyph_format ) 937049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 938049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project case 1: 939049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project case 2: 940049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project case 8: 941727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease case 17: 942727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease error = tt_sbit_decoder_load_metrics( decoder, &p, p_limit, 0 ); 943049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project break; 944049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 945049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project case 6: 946049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project case 7: 947049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project case 9: 948727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease case 18: 949727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease error = tt_sbit_decoder_load_metrics( decoder, &p, p_limit, 1 ); 950049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project break; 951049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 952727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease default: 953727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease error = FT_Err_Ok; 954727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease } 955049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 956727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease if ( error ) 957727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease goto Fail; 958049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 959049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 960727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease TT_SBitDecoder_LoadFunc loader; 961049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 962049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 963727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease switch ( glyph_format ) 964049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 965727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease case 1: 966727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease case 6: 967727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease loader = tt_sbit_decoder_load_byte_aligned; 968727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease break; 969049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 970727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease case 2: 971727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease case 7: 972ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease { 973ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease /* Don't trust `glyph_format'. For example, Apple's main Korean */ 974ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease /* system font, `AppleMyungJo.ttf' (version 7.0d2e6), uses glyph */ 975ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease /* format 7, but the data is format 6. We check whether we have */ 976ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease /* an excessive number of bytes in the image: If it is equal to */ 977ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease /* the value for a byte-aligned glyph, use the other loading */ 978ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease /* routine. */ 979ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease /* */ 980ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease /* Note that for some (width,height) combinations, where the */ 981ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease /* width is not a multiple of 8, the sizes for bit- and */ 982ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease /* byte-aligned data are equal, for example (7,7) or (15,6). We */ 983ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease /* then prefer what `glyph_format' specifies. */ 984ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease 985ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease FT_UInt width = decoder->metrics->width; 986ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease FT_UInt height = decoder->metrics->height; 987ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease 988ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease FT_UInt bit_size = ( width * height + 7 ) >> 3; 989ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease FT_UInt byte_size = height * ( ( width + 7 ) >> 3 ); 990ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease 991ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease 992ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease if ( bit_size < byte_size && 993ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease byte_size == (FT_UInt)( p_limit - p ) ) 994ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease loader = tt_sbit_decoder_load_byte_aligned; 995ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease else 996ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease loader = tt_sbit_decoder_load_bit_aligned; 997ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease } 998727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease break; 999049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 10009c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod case 5: 10019c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod loader = tt_sbit_decoder_load_bit_aligned; 10029c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod break; 10039c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod 1004727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease case 8: 1005727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease if ( p + 1 > p_limit ) 1006727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease goto Fail; 1007049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1008727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease p += 1; /* skip padding */ 1009727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease /* fall-through */ 1010049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1011727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease case 9: 1012727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease loader = tt_sbit_decoder_load_compound; 1013727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease break; 1014049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1015727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease case 17: /* small metrics, PNG image data */ 1016727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease case 18: /* big metrics, PNG image data */ 1017727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease case 19: /* metrics in EBLC, PNG image data */ 1018ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease#ifdef FT_CONFIG_OPTION_USE_PNG 1019727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease loader = tt_sbit_decoder_load_png; 10209c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod break; 1021ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease#else 1022ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease error = FT_THROW( Unimplemented_Feature ); 10239c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod goto Fail; 1024727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease#endif /* FT_CONFIG_OPTION_USE_PNG */ 1025049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1026727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease default: 1027727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease error = FT_THROW( Invalid_Table ); 1028727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease goto Fail; 1029049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1030049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1031727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease if ( !decoder->bitmap_allocated ) 1032049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1033ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease error = tt_sbit_decoder_alloc_bitmap( decoder ); 1034727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease if ( error ) 1035727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease goto Fail; 1036049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1037049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1038ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease error = loader( decoder, p, p_limit, x_pos, y_pos ); 1039727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease } 1040049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1041727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease Fail: 1042727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease FT_FRAME_RELEASE( data ); 1043049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1044727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease Exit: 1045727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease return error; 1046049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1047049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1048049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1049049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project static FT_Error 1050727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease tt_sbit_decoder_load_image( TT_SBitDecoder decoder, 1051727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease FT_UInt glyph_index, 1052727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease FT_Int x_pos, 1053727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease FT_Int y_pos ) 1054049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1055727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease /* 1056727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease * First, we find the correct strike range that applies to this 1057727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease * glyph index. 1058727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease */ 1059727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease 1060727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease FT_Byte* p = decoder->eblc_base + decoder->strike_index_array; 1061727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease FT_Byte* p_limit = decoder->eblc_limit; 1062727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease FT_ULong num_ranges = decoder->strike_index_count; 1063727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease FT_UInt start, end, index_format, image_format; 1064727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease FT_ULong image_start = 0, image_end = 0, image_offset; 1065049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1066049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1067727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease for ( ; num_ranges > 0; num_ranges-- ) 1068049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1069727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease start = FT_NEXT_USHORT( p ); 1070727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease end = FT_NEXT_USHORT( p ); 1071049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1072727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease if ( glyph_index >= start && glyph_index <= end ) 1073727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease goto FoundRange; 1074727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease 1075727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease p += 4; /* ignore index offset */ 1076049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1077727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease goto NoBitmap; 1078049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1079727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease FoundRange: 1080727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease image_offset = FT_NEXT_ULONG( p ); 1081049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1082727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease /* overflow check */ 1083727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease p = decoder->eblc_base + decoder->strike_index_array; 1084727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease if ( image_offset > (FT_ULong)( p_limit - p ) ) 1085727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease goto Failure; 1086049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1087727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease p += image_offset; 1088727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease if ( p + 8 > p_limit ) 1089727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease goto NoBitmap; 1090049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1091727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease /* now find the glyph's location and extend within the ebdt table */ 1092727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease index_format = FT_NEXT_USHORT( p ); 1093727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease image_format = FT_NEXT_USHORT( p ); 1094727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease image_offset = FT_NEXT_ULONG ( p ); 1095049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1096727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease switch ( index_format ) 1097727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease { 1098727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease case 1: /* 4-byte offsets relative to `image_offset' */ 1099ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease p += 4 * ( glyph_index - start ); 1100ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease if ( p + 8 > p_limit ) 1101ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease goto NoBitmap; 1102049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1103ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease image_start = FT_NEXT_ULONG( p ); 1104ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease image_end = FT_NEXT_ULONG( p ); 1105049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1106ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease if ( image_start == image_end ) /* missing glyph */ 1107ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease goto NoBitmap; 1108727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease break; 1109049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1110727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease case 2: /* big metrics, constant image size */ 1111727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease { 1112727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease FT_ULong image_size; 1113049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1114049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1115727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease if ( p + 12 > p_limit ) 1116727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease goto NoBitmap; 1117049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1118727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease image_size = FT_NEXT_ULONG( p ); 1119049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1120727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease if ( tt_sbit_decoder_load_metrics( decoder, &p, p_limit, 1 ) ) 1121727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease goto NoBitmap; 1122049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1123727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease image_start = image_size * ( glyph_index - start ); 1124727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease image_end = image_start + image_size; 1125727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease } 1126727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease break; 1127049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1128727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease case 3: /* 2-byte offsets relative to 'image_offset' */ 1129ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease p += 2 * ( glyph_index - start ); 1130ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease if ( p + 4 > p_limit ) 1131ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease goto NoBitmap; 1132049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1133ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease image_start = FT_NEXT_USHORT( p ); 1134ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease image_end = FT_NEXT_USHORT( p ); 1135049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1136ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease if ( image_start == image_end ) /* missing glyph */ 1137ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease goto NoBitmap; 1138727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease break; 1139049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1140727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease case 4: /* sparse glyph array with (glyph,offset) pairs */ 1141727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease { 1142727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease FT_ULong mm, num_glyphs; 1143049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1144049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1145727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease if ( p + 4 > p_limit ) 1146727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease goto NoBitmap; 1147049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1148727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease num_glyphs = FT_NEXT_ULONG( p ); 1149049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1150727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease /* overflow check for p + ( num_glyphs + 1 ) * 4 */ 1151727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease if ( num_glyphs > (FT_ULong)( ( ( p_limit - p ) >> 2 ) - 1 ) ) 1152727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease goto NoBitmap; 1153049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1154727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease for ( mm = 0; mm < num_glyphs; mm++ ) 1155727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease { 1156727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease FT_UInt gindex = FT_NEXT_USHORT( p ); 1157049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1158049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1159727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease if ( gindex == glyph_index ) 1160727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease { 1161727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease image_start = FT_NEXT_USHORT( p ); 1162727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease p += 2; 1163727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease image_end = FT_PEEK_USHORT( p ); 1164727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease break; 1165727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease } 1166727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease p += 2; 1167727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease } 1168049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1169727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease if ( mm >= num_glyphs ) 1170727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease goto NoBitmap; 1171727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease } 1172727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease break; 1173049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1174727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease case 5: /* constant metrics with sparse glyph codes */ 1175727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease case 19: 1176727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease { 1177727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease FT_ULong image_size, mm, num_glyphs; 1178049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1179049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1180727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease if ( p + 16 > p_limit ) 1181727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease goto NoBitmap; 1182049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1183727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease image_size = FT_NEXT_ULONG( p ); 1184049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1185727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease if ( tt_sbit_decoder_load_metrics( decoder, &p, p_limit, 1 ) ) 1186727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease goto NoBitmap; 1187049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1188727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease num_glyphs = FT_NEXT_ULONG( p ); 1189049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1190727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease /* overflow check for p + 2 * num_glyphs */ 1191727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease if ( num_glyphs > (FT_ULong)( ( p_limit - p ) >> 1 ) ) 1192727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease goto NoBitmap; 1193049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1194727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease for ( mm = 0; mm < num_glyphs; mm++ ) 1195727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease { 1196727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease FT_UInt gindex = FT_NEXT_USHORT( p ); 1197049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1198049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1199727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease if ( gindex == glyph_index ) 1200727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease break; 1201727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease } 1202049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1203727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease if ( mm >= num_glyphs ) 1204727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease goto NoBitmap; 1205049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1206727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease image_start = image_size * mm; 1207727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease image_end = image_start + image_size; 1208049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1209727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease break; 1210049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1211727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease default: 1212727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease goto NoBitmap; 1213727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease } 1214049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1215727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease if ( image_start > image_end ) 1216727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease goto NoBitmap; 1217049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1218727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease image_end -= image_start; 1219727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease image_start = image_offset + image_start; 1220049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1221727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease FT_TRACE3(( "tt_sbit_decoder_load_image:" 1222727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease " found sbit (format %d) for glyph index %d\n", 1223727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease image_format, glyph_index )); 1224049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1225727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease return tt_sbit_decoder_load_bitmap( decoder, 1226727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease image_format, 1227727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease image_start, 1228727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease image_end, 1229727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease x_pos, 1230727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease y_pos ); 1231049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1232727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease Failure: 1233727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease return FT_THROW( Invalid_Table ); 1234727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease 1235727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease NoBitmap: 1236727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease FT_TRACE4(( "tt_sbit_decoder_load_image:" 1237727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease " no sbit found for glyph index %d\n", glyph_index )); 1238727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease 1239727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease return FT_THROW( Invalid_Argument ); 1240049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1241049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1242049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1243ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease static FT_Error 1244ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease tt_face_load_sbix_image( TT_Face face, 1245ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease FT_ULong strike_index, 1246ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease FT_UInt glyph_index, 1247ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease FT_Stream stream, 1248ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease FT_Bitmap *map, 1249ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease TT_SBit_MetricsRec *metrics ) 1250ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease { 12519c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod FT_UInt sbix_pos, strike_offset, glyph_start, glyph_end; 12529c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod FT_ULong table_size; 12539c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod FT_Int originOffsetX, originOffsetY; 12549c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod FT_Tag graphicType; 12559c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod FT_Int recurse_depth = 0; 1256ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease 1257ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease FT_Error error; 1258ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease FT_Byte* p; 1259ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease 1260ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease FT_UNUSED( map ); 1261ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease 1262ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease 1263ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease metrics->width = 0; 1264ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease metrics->height = 0; 1265ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease 1266ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease p = face->sbit_table + 8 + 4 * strike_index; 1267ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease strike_offset = FT_NEXT_ULONG( p ); 1268ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease 1269ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease error = face->goto_table( face, TTAG_sbix, stream, &table_size ); 1270ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease if ( error ) 1271ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease return error; 1272ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease sbix_pos = FT_STREAM_POS(); 1273ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease 1274ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease retry: 1275ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease if ( glyph_index > (FT_UInt)face->root.num_glyphs ) 1276ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease return FT_THROW( Invalid_Argument ); 1277ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease 1278ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease if ( strike_offset >= table_size || 1279ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease table_size - strike_offset < 4 + glyph_index * 4 + 8 ) 1280ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease return FT_THROW( Invalid_File_Format ); 1281ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease 1282ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease if ( FT_STREAM_SEEK( sbix_pos + strike_offset + 4 + glyph_index * 4 ) || 1283ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease FT_FRAME_ENTER( 8 ) ) 1284ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease return error; 1285ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease 1286ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease glyph_start = FT_GET_ULONG(); 1287ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease glyph_end = FT_GET_ULONG(); 1288ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease 1289ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease FT_FRAME_EXIT(); 1290ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease 1291ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease if ( glyph_start == glyph_end ) 1292ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease return FT_THROW( Invalid_Argument ); 1293ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease if ( glyph_start > glyph_end || 1294ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease glyph_end - glyph_start < 8 || 1295ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease table_size - strike_offset < glyph_end ) 1296ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease return FT_THROW( Invalid_File_Format ); 1297ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease 1298ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease if ( FT_STREAM_SEEK( sbix_pos + strike_offset + glyph_start ) || 1299ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease FT_FRAME_ENTER( glyph_end - glyph_start ) ) 1300ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease return error; 1301ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease 1302ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease originOffsetX = FT_GET_SHORT(); 1303ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease originOffsetY = FT_GET_SHORT(); 1304ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease 1305ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease graphicType = FT_GET_TAG4(); 1306ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease 1307ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease switch ( graphicType ) 1308ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease { 1309ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease case FT_MAKE_TAG( 'd', 'u', 'p', 'e' ): 1310ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease if ( recurse_depth < 4 ) 1311ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease { 1312ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease glyph_index = FT_GET_USHORT(); 1313ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease FT_FRAME_EXIT(); 1314ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease recurse_depth++; 1315ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease goto retry; 1316ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease } 1317ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease error = FT_THROW( Invalid_File_Format ); 1318ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease break; 1319ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease 1320ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease case FT_MAKE_TAG( 'p', 'n', 'g', ' ' ): 1321ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease#ifdef FT_CONFIG_OPTION_USE_PNG 1322ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease error = Load_SBit_Png( face->root.glyph, 1323ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease 0, 1324ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease 0, 1325ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease 32, 1326ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease metrics, 1327ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease stream->memory, 1328ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease stream->cursor, 13299c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod glyph_end - glyph_start - 8, 1330ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease TRUE ); 1331ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease#else 1332ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease error = FT_THROW( Unimplemented_Feature ); 1333ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease#endif 1334ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease break; 1335ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease 1336ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease case FT_MAKE_TAG( 'j', 'p', 'g', ' ' ): 1337ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease case FT_MAKE_TAG( 't', 'i', 'f', 'f' ): 1338ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease error = FT_THROW( Unknown_File_Format ); 1339ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease break; 1340ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease 1341ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease default: 1342ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease error = FT_THROW( Unimplemented_Feature ); 1343ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease break; 1344ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease } 1345ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease 1346ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease FT_FRAME_EXIT(); 1347ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease 1348ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease if ( !error ) 1349ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease { 1350ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease FT_Short abearing; 1351ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease FT_UShort aadvance; 1352ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease 1353ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease 1354ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease tt_face_get_metrics( face, FALSE, glyph_index, &abearing, &aadvance ); 1355ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease 13569c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod metrics->horiBearingX = (FT_Short)originOffsetX; 13579c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod metrics->horiBearingY = (FT_Short)( -originOffsetY + metrics->height ); 13589c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod metrics->horiAdvance = (FT_Short)( aadvance * 13599c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod face->root.size->metrics.x_ppem / 13609c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod face->header.Units_Per_EM ); 1361ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease } 1362ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease 1363ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease return error; 1364ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease } 1365ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease 1366727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease FT_LOCAL( FT_Error ) 1367049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project tt_face_load_sbit_image( TT_Face face, 1368049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_ULong strike_index, 1369049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt glyph_index, 1370049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt load_flags, 1371049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Stream stream, 1372049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Bitmap *map, 1373049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project TT_SBit_MetricsRec *metrics ) 1374049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1375ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease FT_Error error = FT_Err_Ok; 1376049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1377049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1378ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease switch ( (FT_UInt)face->sbit_table_type ) 1379ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease { 1380ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease case TT_SBIT_TABLE_TYPE_EBLC: 1381ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease case TT_SBIT_TABLE_TYPE_CBLC: 1382ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease { 1383ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease TT_SBitDecoderRec decoder[1]; 1384049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1385ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease 1386ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease error = tt_sbit_decoder_init( decoder, face, strike_index, metrics ); 1387ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease if ( !error ) 1388ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease { 1389ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease error = tt_sbit_decoder_load_image( decoder, 1390ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease glyph_index, 1391ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease 0, 1392ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease 0 ); 1393ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease tt_sbit_decoder_done( decoder ); 1394ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease } 1395ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease } 1396ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease break; 1397ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease 1398ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease case TT_SBIT_TABLE_TYPE_SBIX: 1399ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease error = tt_face_load_sbix_image( face, 1400ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease strike_index, 1401ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease glyph_index, 1402ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease stream, 1403ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease map, 1404ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease metrics ); 1405ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease break; 1406ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease 1407ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease default: 1408ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease error = FT_THROW( Unknown_File_Format ); 1409ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease break; 1410ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease } 1411ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease 1412ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease /* Flatten color bitmaps if color was not requested. */ 1413ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease if ( !error && 1414ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease !( load_flags & FT_LOAD_COLOR ) && 1415ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease map->pixel_mode == FT_PIXEL_MODE_BGRA ) 1416049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1417ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease FT_Bitmap new_map; 1418ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease FT_Library library = face->root.glyph->library; 1419ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease 1420ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease 1421ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease FT_Bitmap_New( &new_map ); 1422ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease 1423ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease /* Convert to 8bit grayscale. */ 1424ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease error = FT_Bitmap_Convert( library, map, &new_map, 1 ); 1425ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease if ( error ) 1426ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease FT_Bitmap_Done( library, &new_map ); 1427ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease else 1428ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease { 1429ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease map->pixel_mode = new_map.pixel_mode; 1430ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease map->pitch = new_map.pitch; 1431ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease map->num_grays = new_map.num_grays; 1432ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease 1433ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease ft_glyphslot_set_bitmap( face->root.glyph, new_map.buffer ); 1434ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease face->root.glyph->internal->flags |= FT_GLYPH_OWN_BITMAP; 1435ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease } 1436049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1437049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1438049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return error; 1439049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1440049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1441049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1442727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease/* EOF */ 1443