1ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/***************************************************************************/ 2ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* */ 3ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* ftobjs.c */ 4ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* */ 5ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* The FreeType private base classes (body). */ 6ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* */ 7ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* Copyright 1996-2013 by */ 8ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* David Turner, Robert Wilhelm, and Werner Lemberg. */ 9ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* */ 10ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* This file is part of the FreeType project, and may only be used, */ 11ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* modified, and distributed under the terms of the FreeType project */ 12ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ 13ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* this file you indicate that you have read the license and */ 14ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* understand and accept it fully. */ 15ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* */ 16ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/***************************************************************************/ 17ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 18ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 19ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "../../include/ft2build.h" 20ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "../../include/freetype/ftlist.h" 21ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "../../include/freetype/ftoutln.h" 22ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "../../include/freetype/internal/ftvalid.h" 23ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "../../include/freetype/internal/ftobjs.h" 24ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "../../include/freetype/internal/ftdebug.h" 25ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "../../include/freetype/internal/ftrfork.h" 26ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "../../include/freetype/internal/ftstream.h" 27ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "../../include/freetype/internal/sfnt.h" /* for SFNT_Load_Table_Func */ 28ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "../../include/freetype/tttables.h" 29ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "../../include/freetype/tttags.h" 30ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "../../include/freetype/ttnameid.h" 31ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 32ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "../../include/freetype/internal/services/svprop.h" 33ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "../../include/freetype/internal/services/svsfnt.h" 34ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "../../include/freetype/internal/services/svpostnm.h" 35ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "../../include/freetype/internal/services/svgldict.h" 36ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "../../include/freetype/internal/services/svttcmap.h" 37ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "../../include/freetype/internal/services/svkern.h" 38ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "../../include/freetype/internal/services/svtteng.h" 39ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 40ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#ifdef FT_CONFIG_OPTION_MAC_FONTS 41ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "ftbase.h" 42ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif 43ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 44ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 45ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#ifdef FT_DEBUG_LEVEL_TRACE 46ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 47ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "../../include/freetype/ftbitmap.h" 48ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 49ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#if defined( _MSC_VER ) /* Visual C++ (and Intel C++) */ 50ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* We disable the warning `conversion from XXX to YYY, */ 51ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* possible loss of data' in order to compile cleanly with */ 52ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* the maximum level of warnings: `md5.c' is non-FreeType */ 53ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* code, and it gets used during development builds only. */ 54ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#pragma warning( push ) 55ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#pragma warning( disable : 4244 ) 56ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif /* _MSC_VER */ 57ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 58ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* it's easiest to include `md5.c' directly */ 59ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define free md5_free /* suppress a shadow warning */ 60ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "md5.c" 61ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#undef free 62ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 63ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#if defined( _MSC_VER ) 64ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#pragma warning( pop ) 65ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif 66ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 67ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif /* FT_DEBUG_LEVEL_TRACE */ 68ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 69ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 70ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define GRID_FIT_METRICS 71ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 72ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 73ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_BASE_DEF( FT_Pointer ) 74ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ft_service_list_lookup( FT_ServiceDesc service_descriptors, 75ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov const char* service_id ) 76ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 77ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Pointer result = NULL; 78ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ServiceDesc desc = service_descriptors; 79ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 80ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 81ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( desc && service_id ) 82ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 83ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for ( ; desc->serv_id != NULL; desc++ ) 84ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 85ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( ft_strcmp( desc->serv_id, service_id ) == 0 ) 86ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 87ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov result = (FT_Pointer)desc->serv_data; 88ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov break; 89ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 90ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 91ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 92ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 93ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return result; 94ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 95ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 96ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 97ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_BASE_DEF( void ) 98ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ft_validator_init( FT_Validator valid, 99ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov const FT_Byte* base, 100ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov const FT_Byte* limit, 101ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ValidationLevel level ) 102ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 103ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov valid->base = base; 104ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov valid->limit = limit; 105ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov valid->level = level; 106ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov valid->error = FT_Err_Ok; 107ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 108ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 109ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 110ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_BASE_DEF( FT_Int ) 111ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ft_validator_run( FT_Validator valid ) 112ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 113ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* This function doesn't work! None should call it. */ 114ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UNUSED( valid ); 115ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 116ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return -1; 117ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 118ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 119ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 120ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_BASE_DEF( void ) 121ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ft_validator_error( FT_Validator valid, 122ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Error error ) 123ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 124ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* since the cast below also disables the compiler's */ 125ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* type check, we introduce a dummy variable, which */ 126ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* will be optimized away */ 127ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov volatile ft_jmp_buf* jump_buffer = &valid->jump_buffer; 128ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 129ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 130ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov valid->error = error; 131ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 132ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* throw away volatileness; use `jump_buffer' or the */ 133ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* compiler may warn about an unused local variable */ 134ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ft_longjmp( *(ft_jmp_buf*) jump_buffer, 1 ); 135ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 136ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 137ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 138ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 139ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 140ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 141ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /**** ****/ 142ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /**** ****/ 143ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /**** S T R E A M ****/ 144ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /**** ****/ 145ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /**** ****/ 146ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 147ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 148ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 149ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 150ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 151ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* create a new input stream from an FT_Open_Args structure */ 152ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 153ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_BASE_DEF( FT_Error ) 154ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Stream_New( FT_Library library, 155ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov const FT_Open_Args* args, 156ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Stream *astream ) 157ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 158ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Error error; 159ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Memory memory; 160ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Stream stream = NULL; 161ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 162ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 163ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *astream = 0; 164ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 165ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( !library ) 166ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FT_THROW( Invalid_Library_Handle ); 167ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 168ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( !args ) 169ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FT_THROW( Invalid_Argument ); 170ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 171ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov memory = library->memory; 172ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 173ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( FT_NEW( stream ) ) 174ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Exit; 175ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 176ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov stream->memory = memory; 177ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 178ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( args->flags & FT_OPEN_MEMORY ) 179ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 180ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* create a memory-based stream */ 181ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Stream_OpenMemory( stream, 182ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov (const FT_Byte*)args->memory_base, 183ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov args->memory_size ); 184ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 185ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 186ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#ifndef FT_CONFIG_OPTION_DISABLE_STREAM_SUPPORT 187ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 188ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else if ( args->flags & FT_OPEN_PATHNAME ) 189ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 190ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* create a normal system stream */ 191ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = FT_Stream_Open( stream, args->pathname ); 192ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov stream->pathname.pointer = args->pathname; 193ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 194ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else if ( ( args->flags & FT_OPEN_STREAM ) && args->stream ) 195ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 196ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* use an existing, user-provided stream */ 197ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 198ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* in this case, we do not need to allocate a new stream object */ 199ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* since the caller is responsible for closing it himself */ 200ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FREE( stream ); 201ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov stream = args->stream; 202ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 203ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 204ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif 205ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 206ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else 207ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = FT_THROW( Invalid_Argument ); 208ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 209ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( error ) 210ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FREE( stream ); 211ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else 212ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov stream->memory = memory; /* just to be certain */ 213ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 214ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *astream = stream; 215ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 216ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Exit: 217ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return error; 218ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 219ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 220ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 221ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_BASE_DEF( void ) 222ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Stream_Free( FT_Stream stream, 223ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Int external ) 224ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 225ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( stream ) 226ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 227ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Memory memory = stream->memory; 228ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 229ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 230ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Stream_Close( stream ); 231ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 232ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( !external ) 233ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FREE( stream ); 234ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 235ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 236ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 237ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 238ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 239ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 240ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ 241ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ 242ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* messages during execution. */ 243ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 244ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#undef FT_COMPONENT 245ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define FT_COMPONENT trace_objs 246ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 247ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 248ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 249ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 250ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 251ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /**** ****/ 252ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /**** ****/ 253ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /**** FACE, SIZE & GLYPH SLOT OBJECTS ****/ 254ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /**** ****/ 255ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /**** ****/ 256ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 257ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 258ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 259ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 260ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 261ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov static FT_Error 262ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ft_glyphslot_init( FT_GlyphSlot slot ) 263ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 264ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Driver driver = slot->face->driver; 265ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Driver_Class clazz = driver->clazz; 266ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Memory memory = driver->root.memory; 267ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Error error = FT_Err_Ok; 268ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Slot_Internal internal = NULL; 269ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 270ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 271ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov slot->library = driver->root.library; 272ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 273ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( FT_NEW( internal ) ) 274ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Exit; 275ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 276ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov slot->internal = internal; 277ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 278ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( FT_DRIVER_USES_OUTLINES( driver ) ) 279ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = FT_GlyphLoader_New( memory, &internal->loader ); 280ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 281ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( !error && clazz->init_slot ) 282ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = clazz->init_slot( slot ); 283ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 284ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Exit: 285ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return error; 286ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 287ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 288ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 289ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_BASE_DEF( void ) 290ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ft_glyphslot_free_bitmap( FT_GlyphSlot slot ) 291ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 292ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( slot->internal && ( slot->internal->flags & FT_GLYPH_OWN_BITMAP ) ) 293ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 294ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Memory memory = FT_FACE_MEMORY( slot->face ); 295ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 296ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 297ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FREE( slot->bitmap.buffer ); 298ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov slot->internal->flags &= ~FT_GLYPH_OWN_BITMAP; 299ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 300ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else 301ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 302ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* assume that the bitmap buffer was stolen or not */ 303ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* allocated from the heap */ 304ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov slot->bitmap.buffer = NULL; 305ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 306ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 307ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 308ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 309ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_BASE_DEF( void ) 310ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ft_glyphslot_set_bitmap( FT_GlyphSlot slot, 311ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte* buffer ) 312ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 313ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ft_glyphslot_free_bitmap( slot ); 314ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 315ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov slot->bitmap.buffer = buffer; 316ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 317ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ASSERT( (slot->internal->flags & FT_GLYPH_OWN_BITMAP) == 0 ); 318ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 319ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 320ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 321ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_BASE_DEF( FT_Error ) 322ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ft_glyphslot_alloc_bitmap( FT_GlyphSlot slot, 323ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ULong size ) 324ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 325ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Memory memory = FT_FACE_MEMORY( slot->face ); 326ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Error error; 327ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 328ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 329ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( slot->internal->flags & FT_GLYPH_OWN_BITMAP ) 330ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FREE( slot->bitmap.buffer ); 331ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else 332ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov slot->internal->flags |= FT_GLYPH_OWN_BITMAP; 333ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 334ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov (void)FT_ALLOC( slot->bitmap.buffer, size ); 335ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return error; 336ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 337ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 338ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 339ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov static void 340ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ft_glyphslot_clear( FT_GlyphSlot slot ) 341ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 342ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* free bitmap if needed */ 343ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ft_glyphslot_free_bitmap( slot ); 344ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 345ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* clear all public fields in the glyph slot */ 346ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ZERO( &slot->metrics ); 347ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ZERO( &slot->outline ); 348ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 349ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov slot->bitmap.width = 0; 350ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov slot->bitmap.rows = 0; 351ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov slot->bitmap.pitch = 0; 352ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov slot->bitmap.pixel_mode = 0; 353ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* `slot->bitmap.buffer' has been handled by ft_glyphslot_free_bitmap */ 354ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 355ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov slot->bitmap_left = 0; 356ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov slot->bitmap_top = 0; 357ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov slot->num_subglyphs = 0; 358ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov slot->subglyphs = 0; 359ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov slot->control_data = 0; 360ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov slot->control_len = 0; 361ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov slot->other = 0; 362ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov slot->format = FT_GLYPH_FORMAT_NONE; 363ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 364ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov slot->linearHoriAdvance = 0; 365ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov slot->linearVertAdvance = 0; 366ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov slot->lsb_delta = 0; 367ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov slot->rsb_delta = 0; 368ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 369ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 370ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 371ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov static void 372ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ft_glyphslot_done( FT_GlyphSlot slot ) 373ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 374ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Driver driver = slot->face->driver; 375ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Driver_Class clazz = driver->clazz; 376ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Memory memory = driver->root.memory; 377ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 378ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 379ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( clazz->done_slot ) 380ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov clazz->done_slot( slot ); 381ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 382ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* free bitmap buffer if needed */ 383ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ft_glyphslot_free_bitmap( slot ); 384ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 385ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* slot->internal might be NULL in out-of-memory situations */ 386ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( slot->internal ) 387ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 388ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* free glyph loader */ 389ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( FT_DRIVER_USES_OUTLINES( driver ) ) 390ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 391ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_GlyphLoader_Done( slot->internal->loader ); 392ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov slot->internal->loader = 0; 393ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 394ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 395ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FREE( slot->internal ); 396ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 397ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 398ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 399ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 400ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* documentation is in ftobjs.h */ 401ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 402ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_BASE_DEF( FT_Error ) 403ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_New_GlyphSlot( FT_Face face, 404ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_GlyphSlot *aslot ) 405ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 406ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Error error; 407ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Driver driver; 408ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Driver_Class clazz; 409ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Memory memory; 410ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_GlyphSlot slot = NULL; 411ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 412ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 413ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( !face || !face->driver ) 414ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FT_THROW( Invalid_Argument ); 415ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 416ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov driver = face->driver; 417ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov clazz = driver->clazz; 418ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov memory = driver->root.memory; 419ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 420ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_TRACE4(( "FT_New_GlyphSlot: Creating new slot object\n" )); 421ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( !FT_ALLOC( slot, clazz->slot_object_size ) ) 422ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 423ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov slot->face = face; 424ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 425ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = ft_glyphslot_init( slot ); 426ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( error ) 427ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 428ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ft_glyphslot_done( slot ); 429ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FREE( slot ); 430ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Exit; 431ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 432ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 433ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov slot->next = face->glyph; 434ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov face->glyph = slot; 435ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 436ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( aslot ) 437ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *aslot = slot; 438ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 439ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else if ( aslot ) 440ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *aslot = 0; 441ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 442ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 443ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Exit: 444ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_TRACE4(( "FT_New_GlyphSlot: Return %d\n", error )); 445ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return error; 446ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 447ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 448ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 449ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* documentation is in ftobjs.h */ 450ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 451ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_BASE_DEF( void ) 452ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Done_GlyphSlot( FT_GlyphSlot slot ) 453ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 454ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( slot ) 455ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 456ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Driver driver = slot->face->driver; 457ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Memory memory = driver->root.memory; 458ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_GlyphSlot prev; 459ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_GlyphSlot cur; 460ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 461ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 462ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Remove slot from its parent face's list */ 463ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov prev = NULL; 464ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cur = slot->face->glyph; 465ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 466ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov while ( cur ) 467ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 468ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( cur == slot ) 469ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 470ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( !prev ) 471ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov slot->face->glyph = cur->next; 472ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else 473ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov prev->next = cur->next; 474ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 475ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* finalize client-specific data */ 476ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( slot->generic.finalizer ) 477ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov slot->generic.finalizer( slot ); 478ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 479ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ft_glyphslot_done( slot ); 480ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FREE( slot ); 481ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov break; 482ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 483ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov prev = cur; 484ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cur = cur->next; 485ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 486ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 487ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 488ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 489ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 490ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* documentation is in freetype.h */ 491ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 492ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_EXPORT_DEF( void ) 493ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Set_Transform( FT_Face face, 494ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Matrix* matrix, 495ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Vector* delta ) 496ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 497ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Face_Internal internal; 498ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 499ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 500ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( !face ) 501ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return; 502ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 503ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov internal = face->internal; 504ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 505ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov internal->transform_flags = 0; 506ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 507ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( !matrix ) 508ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 509ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov internal->transform_matrix.xx = 0x10000L; 510ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov internal->transform_matrix.xy = 0; 511ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov internal->transform_matrix.yx = 0; 512ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov internal->transform_matrix.yy = 0x10000L; 513ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov matrix = &internal->transform_matrix; 514ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 515ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else 516ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov internal->transform_matrix = *matrix; 517ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 518ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* set transform_flags bit flag 0 if `matrix' isn't the identity */ 519ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( ( matrix->xy | matrix->yx ) || 520ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov matrix->xx != 0x10000L || 521ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov matrix->yy != 0x10000L ) 522ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov internal->transform_flags |= 1; 523ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 524ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( !delta ) 525ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 526ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov internal->transform_delta.x = 0; 527ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov internal->transform_delta.y = 0; 528ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov delta = &internal->transform_delta; 529ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 530ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else 531ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov internal->transform_delta = *delta; 532ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 533ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* set transform_flags bit flag 1 if `delta' isn't the null vector */ 534ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( delta->x | delta->y ) 535ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov internal->transform_flags |= 2; 536ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 537ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 538ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 539ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov static FT_Renderer 540ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ft_lookup_glyph_renderer( FT_GlyphSlot slot ); 541ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 542ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 543ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#ifdef GRID_FIT_METRICS 544ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov static void 545ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ft_glyphslot_grid_fit_metrics( FT_GlyphSlot slot, 546ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Bool vertical ) 547ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 548ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Glyph_Metrics* metrics = &slot->metrics; 549ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Pos right, bottom; 550ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 551ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 552ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( vertical ) 553ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 554ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov metrics->horiBearingX = FT_PIX_FLOOR( metrics->horiBearingX ); 555ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov metrics->horiBearingY = FT_PIX_CEIL ( metrics->horiBearingY ); 556ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 557ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov right = FT_PIX_CEIL( metrics->vertBearingX + metrics->width ); 558ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov bottom = FT_PIX_CEIL( metrics->vertBearingY + metrics->height ); 559ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 560ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov metrics->vertBearingX = FT_PIX_FLOOR( metrics->vertBearingX ); 561ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov metrics->vertBearingY = FT_PIX_FLOOR( metrics->vertBearingY ); 562ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 563ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov metrics->width = right - metrics->vertBearingX; 564ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov metrics->height = bottom - metrics->vertBearingY; 565ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 566ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else 567ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 568ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov metrics->vertBearingX = FT_PIX_FLOOR( metrics->vertBearingX ); 569ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov metrics->vertBearingY = FT_PIX_FLOOR( metrics->vertBearingY ); 570ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 571ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov right = FT_PIX_CEIL ( metrics->horiBearingX + metrics->width ); 572ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov bottom = FT_PIX_FLOOR( metrics->horiBearingY - metrics->height ); 573ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 574ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov metrics->horiBearingX = FT_PIX_FLOOR( metrics->horiBearingX ); 575ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov metrics->horiBearingY = FT_PIX_CEIL ( metrics->horiBearingY ); 576ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 577ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov metrics->width = right - metrics->horiBearingX; 578ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov metrics->height = metrics->horiBearingY - bottom; 579ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 580ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 581ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov metrics->horiAdvance = FT_PIX_ROUND( metrics->horiAdvance ); 582ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov metrics->vertAdvance = FT_PIX_ROUND( metrics->vertAdvance ); 583ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 584ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif /* GRID_FIT_METRICS */ 585ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 586ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 587ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* documentation is in freetype.h */ 588ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 589ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_EXPORT_DEF( FT_Error ) 590ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Load_Glyph( FT_Face face, 591ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt glyph_index, 592ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Int32 load_flags ) 593ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 594ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Error error; 595ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Driver driver; 596ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_GlyphSlot slot; 597ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Library library; 598ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Bool autohint = FALSE; 599ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Module hinter; 600ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov TT_Face ttface = (TT_Face)face; 601ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 602ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 603ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( !face || !face->size || !face->glyph ) 604ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FT_THROW( Invalid_Face_Handle ); 605ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 606ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* The validity test for `glyph_index' is performed by the */ 607ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* font drivers. */ 608ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 609ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov slot = face->glyph; 610ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ft_glyphslot_clear( slot ); 611ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 612ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov driver = face->driver; 613ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov library = driver->root.library; 614ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov hinter = library->auto_hinter; 615ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 616ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* resolve load flags dependencies */ 617ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 618ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( load_flags & FT_LOAD_NO_RECURSE ) 619ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov load_flags |= FT_LOAD_NO_SCALE | 620ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_LOAD_IGNORE_TRANSFORM; 621ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 622ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( load_flags & FT_LOAD_NO_SCALE ) 623ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 624ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov load_flags |= FT_LOAD_NO_HINTING | 625ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_LOAD_NO_BITMAP; 626ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 627ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov load_flags &= ~FT_LOAD_RENDER; 628ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 629ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 630ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* 631ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * Determine whether we need to auto-hint or not. 632ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * The general rules are: 633ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * 634ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * - Do only auto-hinting if we have a hinter module, a scalable font 635ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * format dealing with outlines, and no transforms except simple 636ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * slants and/or rotations by integer multiples of 90 degrees. 637ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * 638ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * - Then, auto-hint if FT_LOAD_FORCE_AUTOHINT is set or if we don't 639ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * have a native font hinter. 640ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * 641ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * - Otherwise, auto-hint for LIGHT hinting mode or if there isn't 642ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * any hinting bytecode in the TrueType/OpenType font. 643ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * 644ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * - Exception: The font is `tricky' and requires the native hinter to 645ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * load properly. 646ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov */ 647ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 648ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( hinter && 649ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov !( load_flags & FT_LOAD_NO_HINTING ) && 650ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov !( load_flags & FT_LOAD_NO_AUTOHINT ) && 651ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_DRIVER_IS_SCALABLE( driver ) && 652ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_DRIVER_USES_OUTLINES( driver ) && 653ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov !FT_IS_TRICKY( face ) && 654ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ( ( load_flags & FT_LOAD_IGNORE_TRANSFORM ) || 655ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ( face->internal->transform_matrix.yx == 0 && 656ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov face->internal->transform_matrix.xx != 0 ) || 657ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ( face->internal->transform_matrix.xx == 0 && 658ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov face->internal->transform_matrix.yx != 0 ) ) ) 659ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 660ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( ( load_flags & FT_LOAD_FORCE_AUTOHINT ) || 661ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov !FT_DRIVER_HAS_HINTER( driver ) ) 662ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov autohint = TRUE; 663ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else 664ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 665ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Render_Mode mode = FT_LOAD_TARGET_MODE( load_flags ); 666ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 667ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 668ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* the check for `num_locations' assures that we actually */ 669ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* test for instructions in a TTF and not in a CFF-based OTF */ 670ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( mode == FT_RENDER_MODE_LIGHT || 671ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov face->internal->ignore_unpatented_hinter || 672ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ( FT_IS_SFNT( face ) && 673ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ttface->num_locations && 674ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ttface->max_profile.maxSizeOfInstructions == 0 ) ) 675ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov autohint = TRUE; 676ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 677ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 678ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 679ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( autohint ) 680ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 681ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_AutoHinter_Interface hinting; 682ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 683ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 684ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* try to load embedded bitmaps first if available */ 685ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 686ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* XXX: This is really a temporary hack that should disappear */ 687ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* promptly with FreeType 2.1! */ 688ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 689ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( FT_HAS_FIXED_SIZES( face ) && 690ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ( load_flags & FT_LOAD_NO_BITMAP ) == 0 ) 691ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 692ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = driver->clazz->load_glyph( slot, face->size, 693ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov glyph_index, 694ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov load_flags | FT_LOAD_SBITS_ONLY ); 695ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 696ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( !error && slot->format == FT_GLYPH_FORMAT_BITMAP ) 697ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Load_Ok; 698ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 699ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 700ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 701ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Face_Internal internal = face->internal; 702ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Int transform_flags = internal->transform_flags; 703ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 704ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 705ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* since the auto-hinter calls FT_Load_Glyph by itself, */ 706ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* make sure that glyphs aren't transformed */ 707ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov internal->transform_flags = 0; 708ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 709ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* load auto-hinted outline */ 710ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov hinting = (FT_AutoHinter_Interface)hinter->clazz->module_interface; 711ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 712ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = hinting->load_glyph( (FT_AutoHinter)hinter, 713ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov slot, face->size, 714ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov glyph_index, load_flags ); 715ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 716ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov internal->transform_flags = transform_flags; 717ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 718ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 719ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else 720ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 721ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = driver->clazz->load_glyph( slot, 722ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov face->size, 723ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov glyph_index, 724ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov load_flags ); 725ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( error ) 726ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Exit; 727ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 728ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( slot->format == FT_GLYPH_FORMAT_OUTLINE ) 729ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 730ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* check that the loaded outline is correct */ 731ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = FT_Outline_Check( &slot->outline ); 732ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( error ) 733ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Exit; 734ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 735ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#ifdef GRID_FIT_METRICS 736ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( !( load_flags & FT_LOAD_NO_HINTING ) ) 737ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ft_glyphslot_grid_fit_metrics( slot, 738ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_BOOL( load_flags & FT_LOAD_VERTICAL_LAYOUT ) ); 739ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif 740ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 741ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 742ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 743ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Load_Ok: 744ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* compute the advance */ 745ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( load_flags & FT_LOAD_VERTICAL_LAYOUT ) 746ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 747ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov slot->advance.x = 0; 748ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov slot->advance.y = slot->metrics.vertAdvance; 749ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 750ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else 751ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 752ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov slot->advance.x = slot->metrics.horiAdvance; 753ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov slot->advance.y = 0; 754ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 755ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 756ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* compute the linear advance in 16.16 pixels */ 757ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( ( load_flags & FT_LOAD_LINEAR_DESIGN ) == 0 && 758ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ( FT_IS_SCALABLE( face ) ) ) 759ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 760ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Size_Metrics* metrics = &face->size->metrics; 761ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 762ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 763ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* it's tricky! */ 764ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov slot->linearHoriAdvance = FT_MulDiv( slot->linearHoriAdvance, 765ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov metrics->x_scale, 64 ); 766ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 767ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov slot->linearVertAdvance = FT_MulDiv( slot->linearVertAdvance, 768ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov metrics->y_scale, 64 ); 769ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 770ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 771ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( ( load_flags & FT_LOAD_IGNORE_TRANSFORM ) == 0 ) 772ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 773ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Face_Internal internal = face->internal; 774ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 775ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 776ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* now, transform the glyph image if needed */ 777ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( internal->transform_flags ) 778ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 779ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* get renderer */ 780ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Renderer renderer = ft_lookup_glyph_renderer( slot ); 781ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 782ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 783ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( renderer ) 784ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = renderer->clazz->transform_glyph( 785ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov renderer, slot, 786ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov &internal->transform_matrix, 787ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov &internal->transform_delta ); 788ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else if ( slot->format == FT_GLYPH_FORMAT_OUTLINE ) 789ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 790ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* apply `standard' transformation if no renderer is available */ 791ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( internal->transform_flags & 1 ) 792ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Outline_Transform( &slot->outline, 793ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov &internal->transform_matrix ); 794ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 795ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( internal->transform_flags & 2 ) 796ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Outline_Translate( &slot->outline, 797ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov internal->transform_delta.x, 798ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov internal->transform_delta.y ); 799ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 800ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 801ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* transform advance */ 802ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Vector_Transform( &slot->advance, &internal->transform_matrix ); 803ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 804ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 805ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 806ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_TRACE5(( " x advance: %d\n" , slot->advance.x )); 807ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_TRACE5(( " y advance: %d\n" , slot->advance.y )); 808ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 809ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_TRACE5(( " linear x advance: %d\n" , slot->linearHoriAdvance )); 810ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_TRACE5(( " linear y advance: %d\n" , slot->linearVertAdvance )); 811ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 812ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* do we need to render the image now? */ 813ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( !error && 814ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov slot->format != FT_GLYPH_FORMAT_BITMAP && 815ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov slot->format != FT_GLYPH_FORMAT_COMPOSITE && 816ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov load_flags & FT_LOAD_RENDER ) 817ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 818ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Render_Mode mode = FT_LOAD_TARGET_MODE( load_flags ); 819ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 820ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 821ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( mode == FT_RENDER_MODE_NORMAL && 822ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov (load_flags & FT_LOAD_MONOCHROME ) ) 823ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov mode = FT_RENDER_MODE_MONO; 824ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 825ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = FT_Render_Glyph( slot, mode ); 826ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 827ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 828ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Exit: 829ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return error; 830ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 831ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 832ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 833ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* documentation is in freetype.h */ 834ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 835ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_EXPORT_DEF( FT_Error ) 836ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Load_Char( FT_Face face, 837ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ULong char_code, 838ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Int32 load_flags ) 839ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 840ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt glyph_index; 841ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 842ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 843ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( !face ) 844ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FT_THROW( Invalid_Face_Handle ); 845ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 846ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov glyph_index = (FT_UInt)char_code; 847ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( face->charmap ) 848ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov glyph_index = FT_Get_Char_Index( face, char_code ); 849ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 850ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FT_Load_Glyph( face, glyph_index, load_flags ); 851ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 852ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 853ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 854ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* destructor for sizes list */ 855ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov static void 856ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov destroy_size( FT_Memory memory, 857ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Size size, 858ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Driver driver ) 859ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 860ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* finalize client-specific data */ 861ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( size->generic.finalizer ) 862ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov size->generic.finalizer( size ); 863ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 864ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* finalize format-specific stuff */ 865ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( driver->clazz->done_size ) 866ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov driver->clazz->done_size( size ); 867ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 868ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FREE( size->internal ); 869ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FREE( size ); 870ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 871ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 872ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 873ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov static void 874ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ft_cmap_done_internal( FT_CMap cmap ); 875ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 876ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 877ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov static void 878ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov destroy_charmaps( FT_Face face, 879ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Memory memory ) 880ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 881ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Int n; 882ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 883ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 884ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( !face ) 885ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return; 886ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 887ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for ( n = 0; n < face->num_charmaps; n++ ) 888ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 889ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_CMap cmap = FT_CMAP( face->charmaps[n] ); 890ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 891ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 892ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ft_cmap_done_internal( cmap ); 893ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 894ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov face->charmaps[n] = NULL; 895ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 896ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 897ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FREE( face->charmaps ); 898ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov face->num_charmaps = 0; 899ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 900ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 901ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 902ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* destructor for faces list */ 903ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov static void 904ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov destroy_face( FT_Memory memory, 905ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Face face, 906ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Driver driver ) 907ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 908ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Driver_Class clazz = driver->clazz; 909ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 910ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 911ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* discard auto-hinting data */ 912ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( face->autohint.finalizer ) 913ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov face->autohint.finalizer( face->autohint.data ); 914ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 915ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Discard glyph slots for this face. */ 916ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Beware! FT_Done_GlyphSlot() changes the field `face->glyph' */ 917ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov while ( face->glyph ) 918ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Done_GlyphSlot( face->glyph ); 919ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 920ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* discard all sizes for this face */ 921ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_List_Finalize( &face->sizes_list, 922ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov (FT_List_Destructor)destroy_size, 923ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov memory, 924ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov driver ); 925ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov face->size = 0; 926ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 927ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* now discard client data */ 928ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( face->generic.finalizer ) 929ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov face->generic.finalizer( face ); 930ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 931ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* discard charmaps */ 932ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov destroy_charmaps( face, memory ); 933ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 934ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* finalize format-specific stuff */ 935ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( clazz->done_face ) 936ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov clazz->done_face( face ); 937ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 938ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* close the stream for this face if needed */ 939ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Stream_Free( 940ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov face->stream, 941ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ( face->face_flags & FT_FACE_FLAG_EXTERNAL_STREAM ) != 0 ); 942ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 943ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov face->stream = 0; 944ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 945ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* get rid of it */ 946ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( face->internal ) 947ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 948ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FREE( face->internal ); 949ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 950ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FREE( face ); 951ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 952ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 953ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 954ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov static void 955ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Destroy_Driver( FT_Driver driver ) 956ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 957ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_List_Finalize( &driver->faces_list, 958ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov (FT_List_Destructor)destroy_face, 959ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov driver->root.memory, 960ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov driver ); 961ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 962ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* check whether we need to drop the driver's glyph loader */ 963ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( FT_DRIVER_USES_OUTLINES( driver ) ) 964ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_GlyphLoader_Done( driver->glyph_loader ); 965ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 966ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 967ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 968ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 969ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 970ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* <Function> */ 971ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* find_unicode_charmap */ 972ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 973ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* <Description> */ 974ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* This function finds a Unicode charmap, if there is one. */ 975ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* And if there is more than one, it tries to favour the more */ 976ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* extensive one, i.e., one that supports UCS-4 against those which */ 977ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* are limited to the BMP (said UCS-2 encoding.) */ 978ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 979ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* This function is called from open_face() (just below), and also */ 980ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* from FT_Select_Charmap( ..., FT_ENCODING_UNICODE ). */ 981ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 982ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov static FT_Error 983ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov find_unicode_charmap( FT_Face face ) 984ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 985ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_CharMap* first; 986ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_CharMap* cur; 987ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 988ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 989ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* caller should have already checked that `face' is valid */ 990ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ASSERT( face ); 991ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 992ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov first = face->charmaps; 993ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 994ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( !first ) 995ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FT_THROW( Invalid_CharMap_Handle ); 996ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 997ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* 998ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * The original TrueType specification(s) only specified charmap 999ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * formats that are capable of mapping 8 or 16 bit character codes to 1000ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * glyph indices. 1001ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * 1002ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * However, recent updates to the Apple and OpenType specifications 1003ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * introduced new formats that are capable of mapping 32-bit character 1004ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * codes as well. And these are already used on some fonts, mainly to 1005ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * map non-BMP Asian ideographs as defined in Unicode. 1006ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * 1007ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * For compatibility purposes, these fonts generally come with 1008ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * *several* Unicode charmaps: 1009ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * 1010ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * - One of them in the "old" 16-bit format, that cannot access 1011ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * all glyphs in the font. 1012ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * 1013ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * - Another one in the "new" 32-bit format, that can access all 1014ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * the glyphs. 1015ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * 1016ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * This function has been written to always favor a 32-bit charmap 1017ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * when found. Otherwise, a 16-bit one is returned when found. 1018ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov */ 1019ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1020ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Since the `interesting' table, with IDs (3,10), is normally the */ 1021ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* last one, we loop backwards. This loses with type1 fonts with */ 1022ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* non-BMP characters (<.0001%), this wins with .ttf with non-BMP */ 1023ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* chars (.01% ?), and this is the same about 99.99% of the time! */ 1024ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1025ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cur = first + face->num_charmaps; /* points after the last one */ 1026ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1027ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for ( ; --cur >= first; ) 1028ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1029ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( cur[0]->encoding == FT_ENCODING_UNICODE ) 1030ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1031ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* XXX If some new encodings to represent UCS-4 are added, */ 1032ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* they should be added here. */ 1033ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( ( cur[0]->platform_id == TT_PLATFORM_MICROSOFT && 1034ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cur[0]->encoding_id == TT_MS_ID_UCS_4 ) || 1035ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ( cur[0]->platform_id == TT_PLATFORM_APPLE_UNICODE && 1036ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cur[0]->encoding_id == TT_APPLE_ID_UNICODE_32 ) ) 1037ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1038ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#ifdef FT_MAX_CHARMAP_CACHEABLE 1039ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( cur - first > FT_MAX_CHARMAP_CACHEABLE ) 1040ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1041ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ERROR(( "find_unicode_charmap: UCS-4 cmap is found " 1042ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov "at too late position (%d)\n", cur - first )); 1043ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov continue; 1044ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1045ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif 1046ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov face->charmap = cur[0]; 1047ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FT_Err_Ok; 1048ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1049ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1050ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1051ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1052ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* We do not have any UCS-4 charmap. */ 1053ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Do the loop again and search for UCS-2 charmaps. */ 1054ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cur = first + face->num_charmaps; 1055ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1056ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for ( ; --cur >= first; ) 1057ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1058ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( cur[0]->encoding == FT_ENCODING_UNICODE ) 1059ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1060ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#ifdef FT_MAX_CHARMAP_CACHEABLE 1061ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( cur - first > FT_MAX_CHARMAP_CACHEABLE ) 1062ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1063ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ERROR(( "find_unicode_charmap: UCS-2 cmap is found " 1064ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov "at too late position (%d)\n", cur - first )); 1065ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov continue; 1066ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1067ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif 1068ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov face->charmap = cur[0]; 1069ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FT_Err_Ok; 1070ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1071ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1072ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1073ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FT_THROW( Invalid_CharMap_Handle ); 1074ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1075ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1076ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1077ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 1078ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 1079ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* <Function> */ 1080ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* find_variant_selector_charmap */ 1081ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 1082ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* <Description> */ 1083ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* This function finds the variant selector charmap, if there is one. */ 1084ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* There can only be one (platform=0, specific=5, format=14). */ 1085ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 1086ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov static FT_CharMap 1087ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov find_variant_selector_charmap( FT_Face face ) 1088ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1089ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_CharMap* first; 1090ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_CharMap* end; 1091ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_CharMap* cur; 1092ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1093ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1094ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* caller should have already checked that `face' is valid */ 1095ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ASSERT( face ); 1096ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1097ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov first = face->charmaps; 1098ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1099ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( !first ) 1100ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return NULL; 1101ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1102ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov end = first + face->num_charmaps; /* points after the last one */ 1103ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1104ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for ( cur = first; cur < end; ++cur ) 1105ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1106ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( cur[0]->platform_id == TT_PLATFORM_APPLE_UNICODE && 1107ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cur[0]->encoding_id == TT_APPLE_ID_VARIANT_SELECTOR && 1108ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Get_CMap_Format( cur[0] ) == 14 ) 1109ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1110ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#ifdef FT_MAX_CHARMAP_CACHEABLE 1111ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( cur - first > FT_MAX_CHARMAP_CACHEABLE ) 1112ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1113ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ERROR(( "find_unicode_charmap: UVS cmap is found " 1114ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov "at too late position (%d)\n", cur - first )); 1115ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov continue; 1116ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1117ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif 1118ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return cur[0]; 1119ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1120ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1121ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1122ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return NULL; 1123ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1124ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1125ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1126ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 1127ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 1128ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* <Function> */ 1129ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* open_face */ 1130ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 1131ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* <Description> */ 1132ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* This function does some work for FT_Open_Face(). */ 1133ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 1134ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov static FT_Error 1135ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov open_face( FT_Driver driver, 1136ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Stream stream, 1137ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Long face_index, 1138ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Int num_params, 1139ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Parameter* params, 1140ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Face *aface ) 1141ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1142ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Memory memory; 1143ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Driver_Class clazz; 1144ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Face face = 0; 1145ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Error error, error2; 1146ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Face_Internal internal = NULL; 1147ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1148ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1149ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov clazz = driver->clazz; 1150ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov memory = driver->root.memory; 1151ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1152ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* allocate the face object and perform basic initialization */ 1153ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( FT_ALLOC( face, clazz->face_object_size ) ) 1154ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Fail; 1155ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1156ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov face->driver = driver; 1157ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov face->memory = memory; 1158ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov face->stream = stream; 1159ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1160ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( FT_NEW( internal ) ) 1161ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Fail; 1162ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1163ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov face->internal = internal; 1164ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1165ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#ifdef FT_CONFIG_OPTION_INCREMENTAL 1166ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1167ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov int i; 1168ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1169ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1170ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov face->internal->incremental_interface = 0; 1171ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for ( i = 0; i < num_params && !face->internal->incremental_interface; 1172ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov i++ ) 1173ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( params[i].tag == FT_PARAM_TAG_INCREMENTAL ) 1174ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov face->internal->incremental_interface = 1175ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov (FT_Incremental_Interface)params[i].data; 1176ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1177ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif 1178ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1179ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( clazz->init_face ) 1180ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = clazz->init_face( stream, 1181ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov face, 1182ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov (FT_Int)face_index, 1183ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov num_params, 1184ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov params ); 1185ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( error ) 1186ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Fail; 1187ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1188ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* select Unicode charmap by default */ 1189ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error2 = find_unicode_charmap( face ); 1190ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1191ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* if no Unicode charmap can be found, FT_Err_Invalid_CharMap_Handle */ 1192ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* is returned. */ 1193ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1194ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* no error should happen, but we want to play safe */ 1195ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( error2 && FT_ERR_NEQ( error2, Invalid_CharMap_Handle ) ) 1196ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1197ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = error2; 1198ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Fail; 1199ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1200ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1201ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *aface = face; 1202ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1203ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Fail: 1204ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( error ) 1205ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1206ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov destroy_charmaps( face, memory ); 1207ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( clazz->done_face ) 1208ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov clazz->done_face( face ); 1209ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FREE( internal ); 1210ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FREE( face ); 1211ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *aface = 0; 1212ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1213ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1214ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return error; 1215ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1216ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1217ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1218ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* there's a Mac-specific extended implementation of FT_New_Face() */ 1219ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* in src/base/ftmac.c */ 1220ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1221ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov//#ifndef FT_MACINTOSH 1222ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1223ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* documentation is in freetype.h */ 1224ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1225ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_EXPORT_DEF( FT_Error ) 1226ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_New_Face( FT_Library library, 1227ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov const char* pathname, 1228ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Long face_index, 1229ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Face *aface ) 1230ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1231ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Open_Args args; 1232ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1233ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1234ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* test for valid `library' and `aface' delayed to FT_Open_Face() */ 1235ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( !pathname ) 1236ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FT_THROW( Invalid_Argument ); 1237ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1238ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov args.flags = FT_OPEN_PATHNAME; 1239ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov args.pathname = (char*)pathname; 1240ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov args.stream = NULL; 1241ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1242ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FT_Open_Face( library, &args, face_index, aface ); 1243ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1244ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1245ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov//#endif 1246ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1247ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1248ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* documentation is in freetype.h */ 1249ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1250ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_EXPORT_DEF( FT_Error ) 1251ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_New_Memory_Face( FT_Library library, 1252ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov const FT_Byte* file_base, 1253ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Long file_size, 1254ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Long face_index, 1255ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Face *aface ) 1256ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1257ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Open_Args args; 1258ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1259ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1260ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* test for valid `library' and `face' delayed to FT_Open_Face() */ 1261ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( !file_base ) 1262ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FT_THROW( Invalid_Argument ); 1263ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1264ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov args.flags = FT_OPEN_MEMORY; 1265ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov args.memory_base = file_base; 1266ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov args.memory_size = file_size; 1267ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov args.stream = NULL; 1268ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1269ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FT_Open_Face( library, &args, face_index, aface ); 1270ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1271ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1272ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1273ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#ifdef FT_CONFIG_OPTION_MAC_FONTS 1274ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1275ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* The behavior here is very similar to that in base/ftmac.c, but it */ 1276ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* is designed to work on non-mac systems, so no mac specific calls. */ 1277ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 1278ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* We look at the file and determine if it is a mac dfont file or a mac */ 1279ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* resource file, or a macbinary file containing a mac resource file. */ 1280ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 1281ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Unlike ftmac I'm not going to look at a `FOND'. I don't really see */ 1282ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* the point, especially since there may be multiple `FOND' resources. */ 1283ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Instead I'll just look for `sfnt' and `POST' resources, ordered as */ 1284ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* they occur in the file. */ 1285ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 1286ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Note that multiple `POST' resources do not mean multiple postscript */ 1287ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* fonts; they all get jammed together to make what is essentially a */ 1288ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* pfb file. */ 1289ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 1290ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* We aren't interested in `NFNT' or `FONT' bitmap resources. */ 1291ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 1292ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* As soon as we get an `sfnt' load it into memory and pass it off to */ 1293ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* FT_Open_Face. */ 1294ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 1295ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* If we have a (set of) `POST' resources, massage them into a (memory) */ 1296ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* pfb file and pass that to FT_Open_Face. (As with ftmac.c I'm not */ 1297ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* going to try to save the kerning info. After all that lives in the */ 1298ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* `FOND' which isn't in the file containing the `POST' resources so */ 1299ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* we don't really have access to it. */ 1300ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1301ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1302ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Finalizer for a memory stream; gets called by FT_Done_Face(). */ 1303ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* It frees the memory it uses. */ 1304ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* From ftmac.c. */ 1305ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov static void 1306ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov memory_stream_close( FT_Stream stream ) 1307ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1308ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Memory memory = stream->memory; 1309ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1310ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1311ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FREE( stream->base ); 1312ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1313ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov stream->size = 0; 1314ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov stream->base = 0; 1315ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov stream->close = 0; 1316ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1317ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1318ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1319ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Create a new memory stream from a buffer and a size. */ 1320ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* From ftmac.c. */ 1321ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov static FT_Error 1322ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov new_memory_stream( FT_Library library, 1323ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte* base, 1324ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ULong size, 1325ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Stream_CloseFunc close, 1326ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Stream *astream ) 1327ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1328ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Error error; 1329ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Memory memory; 1330ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Stream stream = NULL; 1331ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1332ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1333ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( !library ) 1334ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FT_THROW( Invalid_Library_Handle ); 1335ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1336ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( !base ) 1337ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FT_THROW( Invalid_Argument ); 1338ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1339ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *astream = 0; 1340ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov memory = library->memory; 1341ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( FT_NEW( stream ) ) 1342ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Exit; 1343ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1344ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Stream_OpenMemory( stream, base, size ); 1345ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1346ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov stream->close = close; 1347ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1348ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *astream = stream; 1349ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1350ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Exit: 1351ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return error; 1352ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1353ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1354ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1355ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Create a new FT_Face given a buffer and a driver name. */ 1356ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* from ftmac.c */ 1357ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_LOCAL_DEF( FT_Error ) 1358ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov open_face_from_buffer( FT_Library library, 1359ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte* base, 1360ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ULong size, 1361ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Long face_index, 1362ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov const char* driver_name, 1363ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Face *aface ) 1364ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1365ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Open_Args args; 1366ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Error error; 1367ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Stream stream = NULL; 1368ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Memory memory = library->memory; 1369ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1370ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1371ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = new_memory_stream( library, 1372ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov base, 1373ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov size, 1374ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov memory_stream_close, 1375ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov &stream ); 1376ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( error ) 1377ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1378ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FREE( base ); 1379ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return error; 1380ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1381ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1382ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov args.flags = FT_OPEN_STREAM; 1383ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov args.stream = stream; 1384ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( driver_name ) 1385ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1386ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov args.flags = args.flags | FT_OPEN_DRIVER; 1387ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov args.driver = FT_Get_Module( library, driver_name ); 1388ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1389ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1390ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#ifdef FT_MACINTOSH 1391ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* At this point, face_index has served its purpose; */ 1392ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* whoever calls this function has already used it to */ 1393ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* locate the correct font data. We should not propagate */ 1394ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* this index to FT_Open_Face() (unless it is negative). */ 1395ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1396ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( face_index > 0 ) 1397ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov face_index = 0; 1398ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif 1399ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1400ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = FT_Open_Face( library, &args, face_index, aface ); 1401ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1402ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( error == FT_Err_Ok ) 1403ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov (*aface)->face_flags &= ~FT_FACE_FLAG_EXTERNAL_STREAM; 1404ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else 1405ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#ifdef FT_MACINTOSH 1406ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Stream_Free( stream, 0 ); 1407ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#else 1408ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1409ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Stream_Close( stream ); 1410ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FREE( stream ); 1411ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1412ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif 1413ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1414ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return error; 1415ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1416ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1417ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1418ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Look up `TYP1' or `CID ' table from sfnt table directory. */ 1419ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* `offset' and `length' must exclude the binary header in tables. */ 1420ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1421ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Type 1 and CID-keyed font drivers should recognize sfnt-wrapped */ 1422ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* format too. Here, since we can't expect that the TrueType font */ 1423ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* driver is loaded unconditially, we must parse the font by */ 1424ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* ourselves. We are only interested in the name of the table and */ 1425ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* the offset. */ 1426ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1427ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov static FT_Error 1428ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ft_lookup_PS_in_sfnt_stream( FT_Stream stream, 1429ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Long face_index, 1430ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ULong* offset, 1431ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ULong* length, 1432ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Bool* is_sfnt_cid ) 1433ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1434ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Error error; 1435ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UShort numTables; 1436ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Long pstable_index; 1437ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ULong tag; 1438ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov int i; 1439ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1440ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1441ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *offset = 0; 1442ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *length = 0; 1443ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *is_sfnt_cid = FALSE; 1444ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1445ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* TODO: support for sfnt-wrapped PS/CID in TTC format */ 1446ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1447ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* version check for 'typ1' (should be ignored?) */ 1448ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( FT_READ_ULONG( tag ) ) 1449ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return error; 1450ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( tag != TTAG_typ1 ) 1451ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FT_THROW( Unknown_File_Format ); 1452ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1453ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( FT_READ_USHORT( numTables ) ) 1454ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return error; 1455ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( FT_STREAM_SKIP( 2 * 3 ) ) /* skip binary search header */ 1456ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return error; 1457ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1458ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pstable_index = -1; 1459ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *is_sfnt_cid = FALSE; 1460ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1461ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for ( i = 0; i < numTables; i++ ) 1462ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1463ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( FT_READ_ULONG( tag ) || FT_STREAM_SKIP( 4 ) || 1464ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_READ_ULONG( *offset ) || FT_READ_ULONG( *length ) ) 1465ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return error; 1466ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1467ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( tag == TTAG_CID ) 1468ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1469ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pstable_index++; 1470ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *offset += 22; 1471ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *length -= 22; 1472ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *is_sfnt_cid = TRUE; 1473ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( face_index < 0 ) 1474ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FT_Err_Ok; 1475ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1476ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else if ( tag == TTAG_TYP1 ) 1477ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1478ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pstable_index++; 1479ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *offset += 24; 1480ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *length -= 24; 1481ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *is_sfnt_cid = FALSE; 1482ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( face_index < 0 ) 1483ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FT_Err_Ok; 1484ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1485ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( face_index >= 0 && pstable_index == face_index ) 1486ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FT_Err_Ok; 1487ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1488ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FT_THROW( Table_Missing ); 1489ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1490ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1491ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1492ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_LOCAL_DEF( FT_Error ) 1493ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov open_face_PS_from_sfnt_stream( FT_Library library, 1494ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Stream stream, 1495ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Long face_index, 1496ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Int num_params, 1497ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Parameter *params, 1498ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Face *aface ) 1499ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1500ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Error error; 1501ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Memory memory = library->memory; 1502ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ULong offset, length; 1503ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Long pos; 1504ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Bool is_sfnt_cid; 1505ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte* sfnt_ps = NULL; 1506ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1507ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UNUSED( num_params ); 1508ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UNUSED( params ); 1509ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1510ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1511ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pos = FT_Stream_Pos( stream ); 1512ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1513ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = ft_lookup_PS_in_sfnt_stream( stream, 1514ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov face_index, 1515ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov &offset, 1516ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov &length, 1517ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov &is_sfnt_cid ); 1518ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( error ) 1519ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Exit; 1520ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1521ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( FT_Stream_Seek( stream, pos + offset ) ) 1522ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Exit; 1523ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1524ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( FT_ALLOC( sfnt_ps, (FT_Long)length ) ) 1525ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Exit; 1526ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1527ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = FT_Stream_Read( stream, (FT_Byte *)sfnt_ps, length ); 1528ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( error ) 1529ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Exit; 1530ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1531ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = open_face_from_buffer( library, 1532ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov sfnt_ps, 1533ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov length, 1534ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_MIN( face_index, 0 ), 1535ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov is_sfnt_cid ? "cid" : "type1", 1536ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov aface ); 1537ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Exit: 1538ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1539ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Error error1; 1540ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1541ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1542ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( FT_ERR_EQ( error, Unknown_File_Format ) ) 1543ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1544ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error1 = FT_Stream_Seek( stream, pos ); 1545ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( error1 ) 1546ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return error1; 1547ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1548ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1549ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return error; 1550ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1551ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1552ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1553ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1554ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#ifndef FT_MACINTOSH 1555ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1556ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* The resource header says we've got resource_cnt `POST' (type1) */ 1557ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* resources in this file. They all need to be coalesced into */ 1558ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* one lump which gets passed on to the type1 driver. */ 1559ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Here can be only one PostScript font in a file so face_index */ 1560ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* must be 0 (or -1). */ 1561ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 1562ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov static FT_Error 1563ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Mac_Read_POST_Resource( FT_Library library, 1564ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Stream stream, 1565ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Long *offsets, 1566ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Long resource_cnt, 1567ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Long face_index, 1568ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Face *aface ) 1569ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1570ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Error error = FT_ERR( Cannot_Open_Resource ); 1571ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Memory memory = library->memory; 1572ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte* pfb_data = NULL; 1573ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov int i, type, flags; 1574ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Long len; 1575ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Long pfb_len, pfb_pos, pfb_lenpos; 1576ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Long rlen, temp; 1577ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1578ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1579ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( face_index == -1 ) 1580ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov face_index = 0; 1581ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( face_index != 0 ) 1582ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return error; 1583ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1584ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Find the length of all the POST resources, concatenated. Assume */ 1585ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* worst case (each resource in its own section). */ 1586ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pfb_len = 0; 1587ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for ( i = 0; i < resource_cnt; ++i ) 1588ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1589ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = FT_Stream_Seek( stream, offsets[i] ); 1590ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( error ) 1591ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Exit; 1592ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( FT_READ_LONG( temp ) ) 1593ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Exit; 1594ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pfb_len += temp + 6; 1595ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1596ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1597ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( FT_ALLOC( pfb_data, (FT_Long)pfb_len + 2 ) ) 1598ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Exit; 1599ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1600ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pfb_data[0] = 0x80; 1601ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pfb_data[1] = 1; /* Ascii section */ 1602ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pfb_data[2] = 0; /* 4-byte length, fill in later */ 1603ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pfb_data[3] = 0; 1604ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pfb_data[4] = 0; 1605ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pfb_data[5] = 0; 1606ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pfb_pos = 6; 1607ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pfb_lenpos = 2; 1608ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1609ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov len = 0; 1610ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov type = 1; 1611ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for ( i = 0; i < resource_cnt; ++i ) 1612ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1613ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = FT_Stream_Seek( stream, offsets[i] ); 1614ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( error ) 1615ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Exit2; 1616ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( FT_READ_LONG( rlen ) ) 1617ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Exit; 1618ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( FT_READ_USHORT( flags ) ) 1619ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Exit; 1620ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_TRACE3(( "POST fragment[%d]: offsets=0x%08x, rlen=0x%08x, flags=0x%04x\n", 1621ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov i, offsets[i], rlen, flags )); 1622ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1623ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* postpone the check of rlen longer than buffer until FT_Stream_Read() */ 1624ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( ( flags >> 8 ) == 0 ) /* Comment, should not be loaded */ 1625ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov continue; 1626ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1627ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* the flags are part of the resource, so rlen >= 2. */ 1628ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* but some fonts declare rlen = 0 for empty fragment */ 1629ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( rlen > 2 ) 1630ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov rlen -= 2; 1631ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else 1632ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov rlen = 0; 1633ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1634ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( ( flags >> 8 ) == type ) 1635ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov len += rlen; 1636ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else 1637ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1638ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( pfb_lenpos + 3 > pfb_len + 2 ) 1639ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Exit2; 1640ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pfb_data[pfb_lenpos ] = (FT_Byte)( len ); 1641ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pfb_data[pfb_lenpos + 1] = (FT_Byte)( len >> 8 ); 1642ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pfb_data[pfb_lenpos + 2] = (FT_Byte)( len >> 16 ); 1643ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pfb_data[pfb_lenpos + 3] = (FT_Byte)( len >> 24 ); 1644ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1645ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( ( flags >> 8 ) == 5 ) /* End of font mark */ 1646ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov break; 1647ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1648ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( pfb_pos + 6 > pfb_len + 2 ) 1649ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Exit2; 1650ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pfb_data[pfb_pos++] = 0x80; 1651ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1652ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov type = flags >> 8; 1653ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov len = rlen; 1654ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1655ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pfb_data[pfb_pos++] = (FT_Byte)type; 1656ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pfb_lenpos = pfb_pos; 1657ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pfb_data[pfb_pos++] = 0; /* 4-byte length, fill in later */ 1658ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pfb_data[pfb_pos++] = 0; 1659ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pfb_data[pfb_pos++] = 0; 1660ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pfb_data[pfb_pos++] = 0; 1661ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1662ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1663ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = FT_ERR( Cannot_Open_Resource ); 1664ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( pfb_pos > pfb_len || pfb_pos + rlen > pfb_len ) 1665ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Exit2; 1666ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1667ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = FT_Stream_Read( stream, (FT_Byte *)pfb_data + pfb_pos, rlen ); 1668ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( error ) 1669ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Exit2; 1670ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pfb_pos += rlen; 1671ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1672ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1673ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( pfb_pos + 2 > pfb_len + 2 ) 1674ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Exit2; 1675ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pfb_data[pfb_pos++] = 0x80; 1676ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pfb_data[pfb_pos++] = 3; 1677ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1678ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( pfb_lenpos + 3 > pfb_len + 2 ) 1679ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Exit2; 1680ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pfb_data[pfb_lenpos ] = (FT_Byte)( len ); 1681ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pfb_data[pfb_lenpos + 1] = (FT_Byte)( len >> 8 ); 1682ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pfb_data[pfb_lenpos + 2] = (FT_Byte)( len >> 16 ); 1683ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pfb_data[pfb_lenpos + 3] = (FT_Byte)( len >> 24 ); 1684ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1685ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return open_face_from_buffer( library, 1686ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pfb_data, 1687ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pfb_pos, 1688ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov face_index, 1689ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov "type1", 1690ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov aface ); 1691ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1692ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Exit2: 1693ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FREE( pfb_data ); 1694ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1695ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Exit: 1696ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return error; 1697ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1698ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1699ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1700ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* The resource header says we've got resource_cnt `sfnt' */ 1701ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* (TrueType/OpenType) resources in this file. Look through */ 1702ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* them for the one indicated by face_index, load it into mem, */ 1703ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* pass it on the the truetype driver and return it. */ 1704ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 1705ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov static FT_Error 1706ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Mac_Read_sfnt_Resource( FT_Library library, 1707ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Stream stream, 1708ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Long *offsets, 1709ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Long resource_cnt, 1710ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Long face_index, 1711ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Face *aface ) 1712ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1713ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Memory memory = library->memory; 1714ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte* sfnt_data = NULL; 1715ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Error error; 1716ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Long flag_offset; 1717ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Long rlen; 1718ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov int is_cff; 1719ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Long face_index_in_resource = 0; 1720ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1721ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1722ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( face_index == -1 ) 1723ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov face_index = 0; 1724ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( face_index >= resource_cnt ) 1725ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FT_THROW( Cannot_Open_Resource ); 1726ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1727ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov flag_offset = offsets[face_index]; 1728ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = FT_Stream_Seek( stream, flag_offset ); 1729ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( error ) 1730ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Exit; 1731ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1732ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( FT_READ_LONG( rlen ) ) 1733ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Exit; 1734ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( rlen == -1 ) 1735ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FT_THROW( Cannot_Open_Resource ); 1736ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1737ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = open_face_PS_from_sfnt_stream( library, 1738ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov stream, 1739ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov face_index, 1740ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 0, NULL, 1741ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov aface ); 1742ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( !error ) 1743ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Exit; 1744ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1745ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* rewind sfnt stream before open_face_PS_from_sfnt_stream() */ 1746ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( FT_Stream_Seek( stream, flag_offset + 4 ) ) 1747ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Exit; 1748ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1749ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( FT_ALLOC( sfnt_data, (FT_Long)rlen ) ) 1750ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return error; 1751ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = FT_Stream_Read( stream, (FT_Byte *)sfnt_data, rlen ); 1752ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( error ) 1753ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Exit; 1754ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1755ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov is_cff = rlen > 4 && !ft_memcmp( sfnt_data, "OTTO", 4 ); 1756ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = open_face_from_buffer( library, 1757ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov sfnt_data, 1758ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov rlen, 1759ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov face_index_in_resource, 1760ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov is_cff ? "cff" : "truetype", 1761ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov aface ); 1762ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1763ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Exit: 1764ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return error; 1765ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1766ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1767ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1768ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Check for a valid resource fork header, or a valid dfont */ 1769ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* header. In a resource fork the first 16 bytes are repeated */ 1770ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* at the location specified by bytes 4-7. In a dfont bytes */ 1771ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* 4-7 point to 16 bytes of zeroes instead. */ 1772ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 1773ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov static FT_Error 1774ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov IsMacResource( FT_Library library, 1775ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Stream stream, 1776ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Long resource_offset, 1777ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Long face_index, 1778ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Face *aface ) 1779ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1780ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Memory memory = library->memory; 1781ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Error error; 1782ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Long map_offset, rdara_pos; 1783ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Long *data_offsets; 1784ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Long count; 1785ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1786ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1787ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = FT_Raccess_Get_HeaderInfo( library, stream, resource_offset, 1788ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov &map_offset, &rdara_pos ); 1789ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( error ) 1790ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return error; 1791ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1792ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = FT_Raccess_Get_DataOffsets( library, stream, 1793ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov map_offset, rdara_pos, 1794ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov TTAG_POST, 1795ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov &data_offsets, &count ); 1796ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( !error ) 1797ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1798ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = Mac_Read_POST_Resource( library, stream, data_offsets, count, 1799ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov face_index, aface ); 1800ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FREE( data_offsets ); 1801ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* POST exists in an LWFN providing a single face */ 1802ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( !error ) 1803ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov (*aface)->num_faces = 1; 1804ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return error; 1805ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1806ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1807ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = FT_Raccess_Get_DataOffsets( library, stream, 1808ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov map_offset, rdara_pos, 1809ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov TTAG_sfnt, 1810ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov &data_offsets, &count ); 1811ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( !error ) 1812ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1813ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Long face_index_internal = face_index % count; 1814ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1815ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1816ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = Mac_Read_sfnt_Resource( library, stream, data_offsets, count, 1817ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov face_index_internal, aface ); 1818ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FREE( data_offsets ); 1819ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( !error ) 1820ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov (*aface)->num_faces = count; 1821ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1822ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1823ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return error; 1824ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1825ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1826ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1827ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Check for a valid macbinary header, and if we find one */ 1828ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* check that the (flattened) resource fork in it is valid. */ 1829ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 1830ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov static FT_Error 1831ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov IsMacBinary( FT_Library library, 1832ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Stream stream, 1833ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Long face_index, 1834ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Face *aface ) 1835ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1836ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov unsigned char header[128]; 1837ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Error error; 1838ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Long dlen, offset; 1839ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1840ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1841ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( NULL == stream ) 1842ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FT_THROW( Invalid_Stream_Operation ); 1843ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1844ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = FT_Stream_Seek( stream, 0 ); 1845ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( error ) 1846ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Exit; 1847ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1848ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = FT_Stream_Read( stream, (FT_Byte*)header, 128 ); 1849ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( error ) 1850ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Exit; 1851ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1852ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( header[ 0] != 0 || 1853ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov header[74] != 0 || 1854ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov header[82] != 0 || 1855ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov header[ 1] == 0 || 1856ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov header[ 1] > 33 || 1857ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov header[63] != 0 || 1858ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov header[2 + header[1]] != 0 ) 1859ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FT_THROW( Unknown_File_Format ); 1860ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1861ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov dlen = ( header[0x53] << 24 ) | 1862ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ( header[0x54] << 16 ) | 1863ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ( header[0x55] << 8 ) | 1864ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov header[0x56]; 1865ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#if 0 1866ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov rlen = ( header[0x57] << 24 ) | 1867ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ( header[0x58] << 16 ) | 1868ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ( header[0x59] << 8 ) | 1869ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov header[0x5a]; 1870ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif /* 0 */ 1871ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov offset = 128 + ( ( dlen + 127 ) & ~127 ); 1872ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1873ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return IsMacResource( library, stream, offset, face_index, aface ); 1874ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1875ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Exit: 1876ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return error; 1877ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1878ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1879ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1880ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov static FT_Error 1881ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov load_face_in_embedded_rfork( FT_Library library, 1882ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Stream stream, 1883ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Long face_index, 1884ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Face *aface, 1885ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov const FT_Open_Args *args ) 1886ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1887ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1888ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#undef FT_COMPONENT 1889ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define FT_COMPONENT trace_raccess 1890ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1891ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Memory memory = library->memory; 1892ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Error error = FT_ERR( Unknown_File_Format ); 1893ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov int i; 1894ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1895ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov char * file_names[FT_RACCESS_N_RULES]; 1896ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Long offsets[FT_RACCESS_N_RULES]; 1897ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Error errors[FT_RACCESS_N_RULES]; 1898ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Bool is_darwin_vfs, vfs_rfork_has_no_font = FALSE; /* not tested */ 1899ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1900ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Open_Args args2; 1901ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Stream stream2 = 0; 1902ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1903ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1904ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Raccess_Guess( library, stream, 1905ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov args->pathname, file_names, offsets, errors ); 1906ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1907ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for ( i = 0; i < FT_RACCESS_N_RULES; i++ ) 1908ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1909ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov is_darwin_vfs = ft_raccess_rule_by_darwin_vfs( library, i ); 1910ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( is_darwin_vfs && vfs_rfork_has_no_font ) 1911ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1912ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_TRACE3(( "Skip rule %d: darwin vfs resource fork" 1913ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov " is already checked and" 1914ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov " no font is found\n", i )); 1915ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov continue; 1916ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1917ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1918ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( errors[i] ) 1919ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1920ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_TRACE3(( "Error[%d] has occurred in rule %d\n", errors[i], i )); 1921ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov continue; 1922ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1923ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1924ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov args2.flags = FT_OPEN_PATHNAME; 1925ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov args2.pathname = file_names[i] ? file_names[i] : args->pathname; 1926ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1927ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_TRACE3(( "Try rule %d: %s (offset=%d) ...", 1928ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov i, args2.pathname, offsets[i] )); 1929ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1930ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = FT_Stream_New( library, &args2, &stream2 ); 1931ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( is_darwin_vfs && FT_ERR_EQ( error, Cannot_Open_Stream ) ) 1932ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov vfs_rfork_has_no_font = TRUE; 1933ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1934ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( error ) 1935ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1936ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_TRACE3(( "failed\n" )); 1937ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov continue; 1938ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1939ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1940ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = IsMacResource( library, stream2, offsets[i], 1941ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov face_index, aface ); 1942ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Stream_Free( stream2, 0 ); 1943ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1944ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_TRACE3(( "%s\n", error ? "failed": "successful" )); 1945ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1946ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( !error ) 1947ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov break; 1948ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else if ( is_darwin_vfs ) 1949ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov vfs_rfork_has_no_font = TRUE; 1950ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1951ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1952ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for (i = 0; i < FT_RACCESS_N_RULES; i++) 1953ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1954ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( file_names[i] ) 1955ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FREE( file_names[i] ); 1956ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1957ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1958ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Caller (load_mac_face) requires FT_Err_Unknown_File_Format. */ 1959ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( error ) 1960ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = FT_ERR( Unknown_File_Format ); 1961ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1962ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return error; 1963ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1964ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#undef FT_COMPONENT 1965ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define FT_COMPONENT trace_objs 1966ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1967ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1968ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1969ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1970ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Check for some macintosh formats without Carbon framework. */ 1971ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Is this a macbinary file? If so look at the resource fork. */ 1972ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Is this a mac dfont file? */ 1973ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Is this an old style resource fork? (in data) */ 1974ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Else call load_face_in_embedded_rfork to try extra rules */ 1975ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* (defined in `ftrfork.c'). */ 1976ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 1977ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov static FT_Error 1978ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov load_mac_face( FT_Library library, 1979ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Stream stream, 1980ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Long face_index, 1981ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Face *aface, 1982ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov const FT_Open_Args *args ) 1983ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1984ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Error error; 1985ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UNUSED( args ); 1986ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1987ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1988ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = IsMacBinary( library, stream, face_index, aface ); 1989ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( FT_ERR_EQ( error, Unknown_File_Format ) ) 1990ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1991ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1992ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#undef FT_COMPONENT 1993ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define FT_COMPONENT trace_raccess 1994ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1995ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_TRACE3(( "Try as dfont: %s ...", args->pathname )); 1996ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1997ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = IsMacResource( library, stream, 0, face_index, aface ); 1998ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1999ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_TRACE3(( "%s\n", error ? "failed" : "successful" )); 2000ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2001ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#undef FT_COMPONENT 2002ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define FT_COMPONENT trace_objs 2003ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2004ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2005ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2006ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( ( FT_ERR_EQ( error, Unknown_File_Format ) || 2007ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ERR_EQ( error, Invalid_Stream_Operation ) ) && 2008ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ( args->flags & FT_OPEN_PATHNAME ) ) 2009ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = load_face_in_embedded_rfork( library, stream, 2010ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov face_index, aface, args ); 2011ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return error; 2012ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2013ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif 2014ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2015ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif /* !FT_MACINTOSH && FT_CONFIG_OPTION_MAC_FONTS */ 2016ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2017ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2018ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* documentation is in freetype.h */ 2019ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2020ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_EXPORT_DEF( FT_Error ) 2021ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Open_Face( FT_Library library, 2022ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov const FT_Open_Args* args, 2023ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Long face_index, 2024ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Face *aface ) 2025ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 2026ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Error error; 2027ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Driver driver = NULL; 2028ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Memory memory = NULL; 2029ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Stream stream = NULL; 2030ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Face face = NULL; 2031ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ListNode node = NULL; 2032ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Bool external_stream; 2033ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Module* cur; 2034ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Module* limit; 2035ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2036ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2037ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* test for valid `library' delayed to */ 2038ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* FT_Stream_New() */ 2039ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2040ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( ( !aface && face_index >= 0 ) || !args ) 2041ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FT_THROW( Invalid_Argument ); 2042ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2043ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov external_stream = FT_BOOL( ( args->flags & FT_OPEN_STREAM ) && 2044ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov args->stream ); 2045ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2046ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* create input stream */ 2047ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = FT_Stream_New( library, args, &stream ); 2048ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( error ) 2049ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Fail3; 2050ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2051ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov memory = library->memory; 2052ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2053ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* If the font driver is specified in the `args' structure, use */ 2054ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* it. Otherwise, we scan the list of registered drivers. */ 2055ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( ( args->flags & FT_OPEN_DRIVER ) && args->driver ) 2056ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 2057ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov driver = FT_DRIVER( args->driver ); 2058ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2059ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* not all modules are drivers, so check... */ 2060ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( FT_MODULE_IS_DRIVER( driver ) ) 2061ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 2062ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Int num_params = 0; 2063ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Parameter* params = 0; 2064ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2065ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2066ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( args->flags & FT_OPEN_PARAMS ) 2067ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 2068ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov num_params = args->num_params; 2069ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov params = args->params; 2070ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2071ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2072ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = open_face( driver, stream, face_index, 2073ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov num_params, params, &face ); 2074ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( !error ) 2075ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Success; 2076ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2077ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else 2078ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = FT_THROW( Invalid_Handle ); 2079ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2080ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Stream_Free( stream, external_stream ); 2081ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Fail; 2082ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2083ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else 2084ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 2085ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = FT_ERR( Missing_Module ); 2086ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2087ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* check each font driver for an appropriate format */ 2088ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cur = library->modules; 2089ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov limit = cur + library->num_modules; 2090ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2091ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for ( ; cur < limit; cur++ ) 2092ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 2093ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* not all modules are font drivers, so check... */ 2094ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( FT_MODULE_IS_DRIVER( cur[0] ) ) 2095ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 2096ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Int num_params = 0; 2097ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Parameter* params = 0; 2098ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2099ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2100ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov driver = FT_DRIVER( cur[0] ); 2101ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2102ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( args->flags & FT_OPEN_PARAMS ) 2103ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 2104ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov num_params = args->num_params; 2105ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov params = args->params; 2106ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2107ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2108ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = open_face( driver, stream, face_index, 2109ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov num_params, params, &face ); 2110ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( !error ) 2111ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Success; 2112ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2113ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#ifdef FT_CONFIG_OPTION_MAC_FONTS 2114ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( ft_strcmp( cur[0]->clazz->module_name, "truetype" ) == 0 && 2115ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ERR_EQ( error, Table_Missing ) ) 2116ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 2117ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* TrueType but essential tables are missing */ 2118ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( FT_Stream_Seek( stream, 0 ) ) 2119ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov break; 2120ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2121ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = open_face_PS_from_sfnt_stream( library, 2122ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov stream, 2123ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov face_index, 2124ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov num_params, 2125ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov params, 2126ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov aface ); 2127ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( !error ) 2128ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 2129ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Stream_Free( stream, external_stream ); 2130ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return error; 2131ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2132ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2133ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif 2134ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2135ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( FT_ERR_NEQ( error, Unknown_File_Format ) ) 2136ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Fail3; 2137ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2138ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2139ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2140ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Fail3: 2141ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* If we are on the mac, and we get an */ 2142ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* FT_Err_Invalid_Stream_Operation it may be because we have an */ 2143ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* empty data fork, so we need to check the resource fork. */ 2144ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( FT_ERR_NEQ( error, Cannot_Open_Stream ) && 2145ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ERR_NEQ( error, Unknown_File_Format ) && 2146ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ERR_NEQ( error, Invalid_Stream_Operation ) ) 2147ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Fail2; 2148ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2149ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#if !defined( FT_MACINTOSH ) && defined( FT_CONFIG_OPTION_MAC_FONTS ) 2150ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = load_mac_face( library, stream, face_index, aface, args ); 2151ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( !error ) 2152ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 2153ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* We don't want to go to Success here. We've already done that. */ 2154ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* On the other hand, if we succeeded we still need to close this */ 2155ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* stream (we opened a different stream which extracted the */ 2156ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* interesting information out of this stream here. That stream */ 2157ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* will still be open and the face will point to it). */ 2158ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Stream_Free( stream, external_stream ); 2159ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return error; 2160ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2161ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2162ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( FT_ERR_NEQ( error, Unknown_File_Format ) ) 2163ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Fail2; 2164ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif /* !FT_MACINTOSH && FT_CONFIG_OPTION_MAC_FONTS */ 2165ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2166ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* no driver is able to handle this format */ 2167ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = FT_THROW( Unknown_File_Format ); 2168ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2169ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Fail2: 2170ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Stream_Free( stream, external_stream ); 2171ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Fail; 2172ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2173ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2174ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Success: 2175ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_TRACE4(( "FT_Open_Face: New face object, adding to list\n" )); 2176ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2177ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* set the FT_FACE_FLAG_EXTERNAL_STREAM bit for FT_Done_Face */ 2178ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( external_stream ) 2179ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov face->face_flags |= FT_FACE_FLAG_EXTERNAL_STREAM; 2180ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2181ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* add the face object to its driver's list */ 2182ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( FT_NEW( node ) ) 2183ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Fail; 2184ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2185ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov node->data = face; 2186ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* don't assume driver is the same as face->driver, so use */ 2187ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* face->driver instead. */ 2188ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_List_Add( &face->driver->faces_list, node ); 2189ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2190ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* now allocate a glyph slot object for the face */ 2191ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_TRACE4(( "FT_Open_Face: Creating glyph slot\n" )); 2192ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2193ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( face_index >= 0 ) 2194ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 2195ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = FT_New_GlyphSlot( face, NULL ); 2196ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( error ) 2197ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Fail; 2198ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2199ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* finally, allocate a size object for the face */ 2200ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 2201ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Size size; 2202ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2203ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2204ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_TRACE4(( "FT_Open_Face: Creating size object\n" )); 2205ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2206ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = FT_New_Size( face, &size ); 2207ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( error ) 2208ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Fail; 2209ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2210ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov face->size = size; 2211ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2212ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2213ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2214ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* some checks */ 2215ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2216ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( FT_IS_SCALABLE( face ) ) 2217ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 2218ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( face->height < 0 ) 2219ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov face->height = (FT_Short)-face->height; 2220ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2221ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( !FT_HAS_VERTICAL( face ) ) 2222ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov face->max_advance_height = (FT_Short)face->height; 2223ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2224ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2225ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( FT_HAS_FIXED_SIZES( face ) ) 2226ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 2227ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Int i; 2228ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2229ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2230ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for ( i = 0; i < face->num_fixed_sizes; i++ ) 2231ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 2232ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Bitmap_Size* bsize = face->available_sizes + i; 2233ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2234ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2235ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( bsize->height < 0 ) 2236ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov bsize->height = (FT_Short)-bsize->height; 2237ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( bsize->x_ppem < 0 ) 2238ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov bsize->x_ppem = (FT_Short)-bsize->x_ppem; 2239ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( bsize->y_ppem < 0 ) 2240ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov bsize->y_ppem = -bsize->y_ppem; 2241ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2242ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2243ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2244ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* initialize internal face data */ 2245ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 2246ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Face_Internal internal = face->internal; 2247ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2248ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2249ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov internal->transform_matrix.xx = 0x10000L; 2250ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov internal->transform_matrix.xy = 0; 2251ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov internal->transform_matrix.yx = 0; 2252ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov internal->transform_matrix.yy = 0x10000L; 2253ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2254ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov internal->transform_delta.x = 0; 2255ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov internal->transform_delta.y = 0; 2256ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2257ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov internal->refcount = 1; 2258ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2259ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2260ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( aface ) 2261ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *aface = face; 2262ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else 2263ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Done_Face( face ); 2264ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2265ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Exit; 2266ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2267ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Fail: 2268ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( node ) 2269ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Done_Face( face ); /* face must be in the driver's list */ 2270ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else if ( face ) 2271ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov destroy_face( memory, face, driver ); 2272ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2273ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Exit: 2274ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_TRACE4(( "FT_Open_Face: Return %d\n", error )); 2275ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2276ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return error; 2277ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2278ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2279ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2280ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* documentation is in freetype.h */ 2281ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2282ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_EXPORT_DEF( FT_Error ) 2283ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Attach_File( FT_Face face, 2284ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov const char* filepathname ) 2285ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 2286ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Open_Args open; 2287ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2288ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2289ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* test for valid `face' delayed to FT_Attach_Stream() */ 2290ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2291ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( !filepathname ) 2292ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FT_THROW( Invalid_Argument ); 2293ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2294ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov open.stream = NULL; 2295ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov open.flags = FT_OPEN_PATHNAME; 2296ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov open.pathname = (char*)filepathname; 2297ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2298ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FT_Attach_Stream( face, &open ); 2299ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2300ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2301ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2302ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* documentation is in freetype.h */ 2303ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2304ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_EXPORT_DEF( FT_Error ) 2305ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Attach_Stream( FT_Face face, 2306ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Open_Args* parameters ) 2307ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 2308ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Stream stream; 2309ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Error error; 2310ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Driver driver; 2311ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2312ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Driver_Class clazz; 2313ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2314ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2315ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* test for valid `parameters' delayed to FT_Stream_New() */ 2316ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2317ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( !face ) 2318ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FT_THROW( Invalid_Face_Handle ); 2319ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2320ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov driver = face->driver; 2321ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( !driver ) 2322ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FT_THROW( Invalid_Driver_Handle ); 2323ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2324ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = FT_Stream_New( driver->root.library, parameters, &stream ); 2325ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( error ) 2326ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Exit; 2327ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2328ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* we implement FT_Attach_Stream in each driver through the */ 2329ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* `attach_file' interface */ 2330ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2331ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = FT_ERR( Unimplemented_Feature ); 2332ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov clazz = driver->clazz; 2333ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( clazz->attach_file ) 2334ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = clazz->attach_file( face, stream ); 2335ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2336ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* close the attached stream */ 2337ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Stream_Free( stream, 2338ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov (FT_Bool)( parameters->stream && 2339ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ( parameters->flags & FT_OPEN_STREAM ) ) ); 2340ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2341ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Exit: 2342ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return error; 2343ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2344ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2345ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2346ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* documentation is in freetype.h */ 2347ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2348ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_EXPORT_DEF( FT_Error ) 2349ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Reference_Face( FT_Face face ) 2350ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 2351ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov face->internal->refcount++; 2352ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2353ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FT_Err_Ok; 2354ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2355ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2356ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2357ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* documentation is in freetype.h */ 2358ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2359ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_EXPORT_DEF( FT_Error ) 2360ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Done_Face( FT_Face face ) 2361ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 2362ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Error error; 2363ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Driver driver; 2364ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Memory memory; 2365ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ListNode node; 2366ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2367ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2368ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = FT_ERR( Invalid_Face_Handle ); 2369ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( face && face->driver ) 2370ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 2371ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov face->internal->refcount--; 2372ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( face->internal->refcount > 0 ) 2373ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = FT_Err_Ok; 2374ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else 2375ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 2376ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov driver = face->driver; 2377ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov memory = driver->root.memory; 2378ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2379ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* find face in driver's list */ 2380ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov node = FT_List_Find( &driver->faces_list, face ); 2381ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( node ) 2382ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 2383ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* remove face object from the driver's list */ 2384ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_List_Remove( &driver->faces_list, node ); 2385ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FREE( node ); 2386ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2387ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* now destroy the object proper */ 2388ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov destroy_face( memory, face, driver ); 2389ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = FT_Err_Ok; 2390ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2391ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2392ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2393ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2394ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return error; 2395ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2396ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2397ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2398ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* documentation is in ftobjs.h */ 2399ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2400ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_EXPORT_DEF( FT_Error ) 2401ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_New_Size( FT_Face face, 2402ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Size *asize ) 2403ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 2404ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Error error; 2405ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Memory memory; 2406ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Driver driver; 2407ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Driver_Class clazz; 2408ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2409ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Size size = 0; 2410ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ListNode node = 0; 2411ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2412ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2413ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( !face ) 2414ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FT_THROW( Invalid_Face_Handle ); 2415ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2416ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( !asize ) 2417ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FT_THROW( Invalid_Size_Handle ); 2418ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2419ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( !face->driver ) 2420ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FT_THROW( Invalid_Driver_Handle ); 2421ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2422ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *asize = 0; 2423ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2424ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov driver = face->driver; 2425ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov clazz = driver->clazz; 2426ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov memory = face->memory; 2427ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2428ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Allocate new size object and perform basic initialisation */ 2429ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( FT_ALLOC( size, clazz->size_object_size ) || FT_NEW( node ) ) 2430ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Exit; 2431ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2432ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov size->face = face; 2433ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2434ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* for now, do not use any internal fields in size objects */ 2435ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov size->internal = 0; 2436ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2437ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( clazz->init_size ) 2438ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = clazz->init_size( size ); 2439ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2440ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* in case of success, add to the face's list */ 2441ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( !error ) 2442ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 2443ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *asize = size; 2444ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov node->data = size; 2445ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_List_Add( &face->sizes_list, node ); 2446ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2447ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2448ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Exit: 2449ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( error ) 2450ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 2451ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FREE( node ); 2452ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FREE( size ); 2453ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2454ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2455ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return error; 2456ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2457ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2458ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2459ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* documentation is in ftobjs.h */ 2460ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2461ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_EXPORT_DEF( FT_Error ) 2462ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Done_Size( FT_Size size ) 2463ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 2464ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Error error; 2465ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Driver driver; 2466ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Memory memory; 2467ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Face face; 2468ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ListNode node; 2469ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2470ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2471ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( !size ) 2472ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FT_THROW( Invalid_Size_Handle ); 2473ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2474ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov face = size->face; 2475ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( !face ) 2476ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FT_THROW( Invalid_Face_Handle ); 2477ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2478ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov driver = face->driver; 2479ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( !driver ) 2480ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FT_THROW( Invalid_Driver_Handle ); 2481ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2482ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov memory = driver->root.memory; 2483ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2484ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = FT_Err_Ok; 2485ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov node = FT_List_Find( &face->sizes_list, size ); 2486ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( node ) 2487ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 2488ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_List_Remove( &face->sizes_list, node ); 2489ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FREE( node ); 2490ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2491ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( face->size == size ) 2492ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 2493ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov face->size = 0; 2494ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( face->sizes_list.head ) 2495ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov face->size = (FT_Size)(face->sizes_list.head->data); 2496ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2497ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2498ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov destroy_size( memory, size, driver ); 2499ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2500ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else 2501ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = FT_THROW( Invalid_Size_Handle ); 2502ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2503ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return error; 2504ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2505ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2506ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2507ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* documentation is in ftobjs.h */ 2508ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2509ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_BASE_DEF( FT_Error ) 2510ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Match_Size( FT_Face face, 2511ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Size_Request req, 2512ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Bool ignore_width, 2513ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ULong* size_index ) 2514ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 2515ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Int i; 2516ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Long w, h; 2517ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2518ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2519ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( !FT_HAS_FIXED_SIZES( face ) ) 2520ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FT_THROW( Invalid_Face_Handle ); 2521ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2522ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* FT_Bitmap_Size doesn't provide enough info... */ 2523ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( req->type != FT_SIZE_REQUEST_TYPE_NOMINAL ) 2524ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FT_THROW( Unimplemented_Feature ); 2525ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2526ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov w = FT_REQUEST_WIDTH ( req ); 2527ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov h = FT_REQUEST_HEIGHT( req ); 2528ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2529ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( req->width && !req->height ) 2530ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov h = w; 2531ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else if ( !req->width && req->height ) 2532ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov w = h; 2533ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2534ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov w = FT_PIX_ROUND( w ); 2535ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov h = FT_PIX_ROUND( h ); 2536ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2537ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for ( i = 0; i < face->num_fixed_sizes; i++ ) 2538ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 2539ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Bitmap_Size* bsize = face->available_sizes + i; 2540ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2541ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2542ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( h != FT_PIX_ROUND( bsize->y_ppem ) ) 2543ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov continue; 2544ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2545ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( w == FT_PIX_ROUND( bsize->x_ppem ) || ignore_width ) 2546ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 2547ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_TRACE3(( "FT_Match_Size: bitmap strike %d matches\n", i )); 2548ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2549ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( size_index ) 2550ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *size_index = (FT_ULong)i; 2551ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2552ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FT_Err_Ok; 2553ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2554ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2555ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2556ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FT_THROW( Invalid_Pixel_Size ); 2557ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2558ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2559ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2560ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* documentation is in ftobjs.h */ 2561ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2562ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_BASE_DEF( void ) 2563ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ft_synthesize_vertical_metrics( FT_Glyph_Metrics* metrics, 2564ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Pos advance ) 2565ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 2566ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Pos height = metrics->height; 2567ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2568ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2569ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* compensate for glyph with bbox above/below the baseline */ 2570ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( metrics->horiBearingY < 0 ) 2571ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 2572ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( height < metrics->horiBearingY ) 2573ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov height = metrics->horiBearingY; 2574ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2575ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else if ( metrics->horiBearingY > 0 ) 2576ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov height -= metrics->horiBearingY; 2577ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2578ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* the factor 1.2 is a heuristical value */ 2579ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( !advance ) 2580ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov advance = height * 12 / 10; 2581ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2582ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov metrics->vertBearingX = metrics->horiBearingX - metrics->horiAdvance / 2; 2583ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov metrics->vertBearingY = ( advance - height ) / 2; 2584ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov metrics->vertAdvance = advance; 2585ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2586ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2587ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2588ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov static void 2589ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ft_recompute_scaled_metrics( FT_Face face, 2590ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Size_Metrics* metrics ) 2591ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 2592ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Compute root ascender, descender, test height, and max_advance */ 2593ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2594ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#ifdef GRID_FIT_METRICS 2595ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov metrics->ascender = FT_PIX_CEIL( FT_MulFix( face->ascender, 2596ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov metrics->y_scale ) ); 2597ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2598ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov metrics->descender = FT_PIX_FLOOR( FT_MulFix( face->descender, 2599ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov metrics->y_scale ) ); 2600ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2601ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov metrics->height = FT_PIX_ROUND( FT_MulFix( face->height, 2602ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov metrics->y_scale ) ); 2603ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2604ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov metrics->max_advance = FT_PIX_ROUND( FT_MulFix( face->max_advance_width, 2605ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov metrics->x_scale ) ); 2606ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#else /* !GRID_FIT_METRICS */ 2607ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov metrics->ascender = FT_MulFix( face->ascender, 2608ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov metrics->y_scale ); 2609ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2610ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov metrics->descender = FT_MulFix( face->descender, 2611ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov metrics->y_scale ); 2612ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2613ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov metrics->height = FT_MulFix( face->height, 2614ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov metrics->y_scale ); 2615ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2616ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov metrics->max_advance = FT_MulFix( face->max_advance_width, 2617ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov metrics->x_scale ); 2618ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif /* !GRID_FIT_METRICS */ 2619ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2620ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2621ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2622ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_BASE_DEF( void ) 2623ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Select_Metrics( FT_Face face, 2624ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ULong strike_index ) 2625ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 2626ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Size_Metrics* metrics; 2627ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Bitmap_Size* bsize; 2628ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2629ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2630ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov metrics = &face->size->metrics; 2631ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov bsize = face->available_sizes + strike_index; 2632ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2633ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov metrics->x_ppem = (FT_UShort)( ( bsize->x_ppem + 32 ) >> 6 ); 2634ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov metrics->y_ppem = (FT_UShort)( ( bsize->y_ppem + 32 ) >> 6 ); 2635ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2636ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( FT_IS_SCALABLE( face ) ) 2637ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 2638ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov metrics->x_scale = FT_DivFix( bsize->x_ppem, 2639ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov face->units_per_EM ); 2640ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov metrics->y_scale = FT_DivFix( bsize->y_ppem, 2641ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov face->units_per_EM ); 2642ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2643ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ft_recompute_scaled_metrics( face, metrics ); 2644ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2645ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else 2646ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 2647ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov metrics->x_scale = 1L << 16; 2648ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov metrics->y_scale = 1L << 16; 2649ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov metrics->ascender = bsize->y_ppem; 2650ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov metrics->descender = 0; 2651ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov metrics->height = bsize->height << 6; 2652ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov metrics->max_advance = bsize->x_ppem; 2653ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2654ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2655ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_TRACE5(( "FT_Select_Metrics:\n" )); 2656ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_TRACE5(( " x scale: %d (%f)\n", 2657ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov metrics->x_scale, metrics->x_scale / 65536.0 )); 2658ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_TRACE5(( " y scale: %d (%f)\n", 2659ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov metrics->y_scale, metrics->y_scale / 65536.0 )); 2660ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_TRACE5(( " ascender: %f\n", metrics->ascender / 64.0 )); 2661ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_TRACE5(( " descender: %f\n", metrics->descender / 64.0 )); 2662ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_TRACE5(( " height: %f\n", metrics->height / 64.0 )); 2663ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_TRACE5(( " max advance: %f\n", metrics->max_advance / 64.0 )); 2664ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_TRACE5(( " x ppem: %d\n", metrics->x_ppem )); 2665ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_TRACE5(( " y ppem: %d\n", metrics->y_ppem )); 2666ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2667ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2668ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2669ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_BASE_DEF( void ) 2670ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Request_Metrics( FT_Face face, 2671ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Size_Request req ) 2672ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 2673ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Size_Metrics* metrics; 2674ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2675ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2676ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov metrics = &face->size->metrics; 2677ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2678ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( FT_IS_SCALABLE( face ) ) 2679ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 2680ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Long w = 0, h = 0, scaled_w = 0, scaled_h = 0; 2681ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2682ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2683ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov switch ( req->type ) 2684ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 2685ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov case FT_SIZE_REQUEST_TYPE_NOMINAL: 2686ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov w = h = face->units_per_EM; 2687ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov break; 2688ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2689ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov case FT_SIZE_REQUEST_TYPE_REAL_DIM: 2690ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov w = h = face->ascender - face->descender; 2691ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov break; 2692ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2693ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov case FT_SIZE_REQUEST_TYPE_BBOX: 2694ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov w = face->bbox.xMax - face->bbox.xMin; 2695ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov h = face->bbox.yMax - face->bbox.yMin; 2696ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov break; 2697ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2698ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov case FT_SIZE_REQUEST_TYPE_CELL: 2699ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov w = face->max_advance_width; 2700ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov h = face->ascender - face->descender; 2701ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov break; 2702ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2703ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov case FT_SIZE_REQUEST_TYPE_SCALES: 2704ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov metrics->x_scale = (FT_Fixed)req->width; 2705ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov metrics->y_scale = (FT_Fixed)req->height; 2706ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( !metrics->x_scale ) 2707ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov metrics->x_scale = metrics->y_scale; 2708ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else if ( !metrics->y_scale ) 2709ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov metrics->y_scale = metrics->x_scale; 2710ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Calculate_Ppem; 2711ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2712ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov case FT_SIZE_REQUEST_TYPE_MAX: 2713ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov break; 2714ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2715ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2716ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* to be on the safe side */ 2717ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( w < 0 ) 2718ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov w = -w; 2719ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2720ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( h < 0 ) 2721ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov h = -h; 2722ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2723ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov scaled_w = FT_REQUEST_WIDTH ( req ); 2724ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov scaled_h = FT_REQUEST_HEIGHT( req ); 2725ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2726ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* determine scales */ 2727ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( req->width ) 2728ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 2729ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov metrics->x_scale = FT_DivFix( scaled_w, w ); 2730ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2731ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( req->height ) 2732ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 2733ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov metrics->y_scale = FT_DivFix( scaled_h, h ); 2734ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2735ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( req->type == FT_SIZE_REQUEST_TYPE_CELL ) 2736ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 2737ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( metrics->y_scale > metrics->x_scale ) 2738ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov metrics->y_scale = metrics->x_scale; 2739ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else 2740ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov metrics->x_scale = metrics->y_scale; 2741ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2742ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2743ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else 2744ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 2745ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov metrics->y_scale = metrics->x_scale; 2746ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov scaled_h = FT_MulDiv( scaled_w, h, w ); 2747ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2748ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2749ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else 2750ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 2751ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov metrics->x_scale = metrics->y_scale = FT_DivFix( scaled_h, h ); 2752ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov scaled_w = FT_MulDiv( scaled_h, w, h ); 2753ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2754ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2755ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Calculate_Ppem: 2756ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* calculate the ppems */ 2757ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( req->type != FT_SIZE_REQUEST_TYPE_NOMINAL ) 2758ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 2759ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov scaled_w = FT_MulFix( face->units_per_EM, metrics->x_scale ); 2760ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov scaled_h = FT_MulFix( face->units_per_EM, metrics->y_scale ); 2761ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2762ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2763ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov metrics->x_ppem = (FT_UShort)( ( scaled_w + 32 ) >> 6 ); 2764ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov metrics->y_ppem = (FT_UShort)( ( scaled_h + 32 ) >> 6 ); 2765ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2766ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ft_recompute_scaled_metrics( face, metrics ); 2767ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2768ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else 2769ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 2770ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ZERO( metrics ); 2771ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov metrics->x_scale = 1L << 16; 2772ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov metrics->y_scale = 1L << 16; 2773ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2774ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2775ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_TRACE5(( "FT_Request_Metrics:\n" )); 2776ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_TRACE5(( " x scale: %d (%f)\n", 2777ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov metrics->x_scale, metrics->x_scale / 65536.0 )); 2778ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_TRACE5(( " y scale: %d (%f)\n", 2779ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov metrics->y_scale, metrics->y_scale / 65536.0 )); 2780ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_TRACE5(( " ascender: %f\n", metrics->ascender / 64.0 )); 2781ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_TRACE5(( " descender: %f\n", metrics->descender / 64.0 )); 2782ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_TRACE5(( " height: %f\n", metrics->height / 64.0 )); 2783ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_TRACE5(( " max advance: %f\n", metrics->max_advance / 64.0 )); 2784ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_TRACE5(( " x ppem: %d\n", metrics->x_ppem )); 2785ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_TRACE5(( " y ppem: %d\n", metrics->y_ppem )); 2786ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2787ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2788ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2789ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* documentation is in freetype.h */ 2790ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2791ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_EXPORT_DEF( FT_Error ) 2792ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Select_Size( FT_Face face, 2793ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Int strike_index ) 2794ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 2795ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Driver_Class clazz; 2796ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2797ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2798ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( !face || !FT_HAS_FIXED_SIZES( face ) ) 2799ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FT_THROW( Invalid_Face_Handle ); 2800ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2801ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( strike_index < 0 || strike_index >= face->num_fixed_sizes ) 2802ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FT_THROW( Invalid_Argument ); 2803ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2804ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov clazz = face->driver->clazz; 2805ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2806ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( clazz->select_size ) 2807ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 2808ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Error error; 2809ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2810ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2811ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = clazz->select_size( face->size, (FT_ULong)strike_index ); 2812ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2813ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#ifdef FT_DEBUG_LEVEL_TRACE 2814ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 2815ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Size_Metrics* metrics = &face->size->metrics; 2816ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2817ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2818ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_TRACE5(( "FT_Select_Size (font driver's `select_size'):\n" )); 2819ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_TRACE5(( " x scale: %d (%f)\n", 2820ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov metrics->x_scale, metrics->x_scale / 65536.0 )); 2821ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_TRACE5(( " y scale: %d (%f)\n", 2822ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov metrics->y_scale, metrics->y_scale / 65536.0 )); 2823ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_TRACE5(( " ascender: %f\n", metrics->ascender / 64.0 )); 2824ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_TRACE5(( " descender: %f\n", metrics->descender / 64.0 )); 2825ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_TRACE5(( " height: %f\n", metrics->height / 64.0 )); 2826ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_TRACE5(( " max advance: %f\n", metrics->max_advance / 64.0 )); 2827ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_TRACE5(( " x ppem: %d\n", metrics->x_ppem )); 2828ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_TRACE5(( " y ppem: %d\n", metrics->y_ppem )); 2829ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2830ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif 2831ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2832ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return error; 2833ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2834ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2835ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Select_Metrics( face, (FT_ULong)strike_index ); 2836ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2837ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FT_Err_Ok; 2838ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2839ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2840ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2841ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* documentation is in freetype.h */ 2842ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2843ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_EXPORT_DEF( FT_Error ) 2844ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Request_Size( FT_Face face, 2845ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Size_Request req ) 2846ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 2847ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Driver_Class clazz; 2848ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ULong strike_index; 2849ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2850ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2851ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( !face ) 2852ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FT_THROW( Invalid_Face_Handle ); 2853ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2854ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( !req || req->width < 0 || req->height < 0 || 2855ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov req->type >= FT_SIZE_REQUEST_TYPE_MAX ) 2856ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FT_THROW( Invalid_Argument ); 2857ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2858ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov clazz = face->driver->clazz; 2859ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2860ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( clazz->request_size ) 2861ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 2862ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Error error; 2863ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2864ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2865ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = clazz->request_size( face->size, req ); 2866ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2867ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#ifdef FT_DEBUG_LEVEL_TRACE 2868ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 2869ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Size_Metrics* metrics = &face->size->metrics; 2870ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2871ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2872ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_TRACE5(( "FT_Request_Size (font driver's `request_size'):\n" )); 2873ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_TRACE5(( " x scale: %d (%f)\n", 2874ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov metrics->x_scale, metrics->x_scale / 65536.0 )); 2875ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_TRACE5(( " y scale: %d (%f)\n", 2876ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov metrics->y_scale, metrics->y_scale / 65536.0 )); 2877ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_TRACE5(( " ascender: %f\n", metrics->ascender / 64.0 )); 2878ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_TRACE5(( " descender: %f\n", metrics->descender / 64.0 )); 2879ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_TRACE5(( " height: %f\n", metrics->height / 64.0 )); 2880ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_TRACE5(( " max advance: %f\n", metrics->max_advance / 64.0 )); 2881ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_TRACE5(( " x ppem: %d\n", metrics->x_ppem )); 2882ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_TRACE5(( " y ppem: %d\n", metrics->y_ppem )); 2883ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2884ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif 2885ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2886ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return error; 2887ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2888ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2889ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* 2890ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * The reason that a driver doesn't have `request_size' defined is 2891ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * either that the scaling here suffices or that the supported formats 2892ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * are bitmap-only and size matching is not implemented. 2893ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * 2894ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * In the latter case, a simple size matching is done. 2895ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov */ 2896ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( !FT_IS_SCALABLE( face ) && FT_HAS_FIXED_SIZES( face ) ) 2897ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 2898ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Error error; 2899ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2900ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2901ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = FT_Match_Size( face, req, 0, &strike_index ); 2902ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( error ) 2903ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return error; 2904ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2905ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FT_Select_Size( face, (FT_Int)strike_index ); 2906ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2907ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2908ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Request_Metrics( face, req ); 2909ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2910ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FT_Err_Ok; 2911ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2912ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2913ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2914ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* documentation is in freetype.h */ 2915ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2916ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_EXPORT_DEF( FT_Error ) 2917ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Set_Char_Size( FT_Face face, 2918ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_F26Dot6 char_width, 2919ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_F26Dot6 char_height, 2920ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt horz_resolution, 2921ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt vert_resolution ) 2922ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 2923ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Size_RequestRec req; 2924ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2925ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2926ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( !char_width ) 2927ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov char_width = char_height; 2928ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else if ( !char_height ) 2929ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov char_height = char_width; 2930ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2931ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( !horz_resolution ) 2932ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov horz_resolution = vert_resolution; 2933ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else if ( !vert_resolution ) 2934ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov vert_resolution = horz_resolution; 2935ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2936ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( char_width < 1 * 64 ) 2937ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov char_width = 1 * 64; 2938ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( char_height < 1 * 64 ) 2939ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov char_height = 1 * 64; 2940ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2941ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( !horz_resolution ) 2942ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov horz_resolution = vert_resolution = 72; 2943ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2944ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov req.type = FT_SIZE_REQUEST_TYPE_NOMINAL; 2945ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov req.width = char_width; 2946ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov req.height = char_height; 2947ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov req.horiResolution = horz_resolution; 2948ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov req.vertResolution = vert_resolution; 2949ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2950ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FT_Request_Size( face, &req ); 2951ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2952ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2953ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2954ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* documentation is in freetype.h */ 2955ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2956ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_EXPORT_DEF( FT_Error ) 2957ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Set_Pixel_Sizes( FT_Face face, 2958ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt pixel_width, 2959ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt pixel_height ) 2960ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 2961ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Size_RequestRec req; 2962ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2963ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2964ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( pixel_width == 0 ) 2965ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pixel_width = pixel_height; 2966ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else if ( pixel_height == 0 ) 2967ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pixel_height = pixel_width; 2968ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2969ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( pixel_width < 1 ) 2970ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pixel_width = 1; 2971ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( pixel_height < 1 ) 2972ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pixel_height = 1; 2973ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2974ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* use `>=' to avoid potential compiler warning on 16bit platforms */ 2975ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( pixel_width >= 0xFFFFU ) 2976ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pixel_width = 0xFFFFU; 2977ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( pixel_height >= 0xFFFFU ) 2978ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pixel_height = 0xFFFFU; 2979ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2980ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov req.type = FT_SIZE_REQUEST_TYPE_NOMINAL; 2981ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov req.width = pixel_width << 6; 2982ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov req.height = pixel_height << 6; 2983ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov req.horiResolution = 0; 2984ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov req.vertResolution = 0; 2985ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2986ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FT_Request_Size( face, &req ); 2987ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2988ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2989ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2990ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* documentation is in freetype.h */ 2991ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2992ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_EXPORT_DEF( FT_Error ) 2993ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Get_Kerning( FT_Face face, 2994ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt left_glyph, 2995ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt right_glyph, 2996ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt kern_mode, 2997ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Vector *akerning ) 2998ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 2999ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Error error = FT_Err_Ok; 3000ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Driver driver; 3001ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3002ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3003ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( !face ) 3004ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FT_THROW( Invalid_Face_Handle ); 3005ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3006ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( !akerning ) 3007ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FT_THROW( Invalid_Argument ); 3008ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3009ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov driver = face->driver; 3010ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3011ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov akerning->x = 0; 3012ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov akerning->y = 0; 3013ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3014ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( driver->clazz->get_kerning ) 3015ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 3016ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = driver->clazz->get_kerning( face, 3017ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov left_glyph, 3018ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov right_glyph, 3019ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov akerning ); 3020ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( !error ) 3021ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 3022ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( kern_mode != FT_KERNING_UNSCALED ) 3023ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 3024ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov akerning->x = FT_MulFix( akerning->x, face->size->metrics.x_scale ); 3025ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov akerning->y = FT_MulFix( akerning->y, face->size->metrics.y_scale ); 3026ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3027ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( kern_mode != FT_KERNING_UNFITTED ) 3028ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 3029ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* we scale down kerning values for small ppem values */ 3030ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* to avoid that rounding makes them too big. */ 3031ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* `25' has been determined heuristically. */ 3032ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( face->size->metrics.x_ppem < 25 ) 3033ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov akerning->x = FT_MulDiv( akerning->x, 3034ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov face->size->metrics.x_ppem, 25 ); 3035ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( face->size->metrics.y_ppem < 25 ) 3036ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov akerning->y = FT_MulDiv( akerning->y, 3037ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov face->size->metrics.y_ppem, 25 ); 3038ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3039ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov akerning->x = FT_PIX_ROUND( akerning->x ); 3040ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov akerning->y = FT_PIX_ROUND( akerning->y ); 3041ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 3042ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 3043ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 3044ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 3045ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3046ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return error; 3047ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 3048ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3049ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3050ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* documentation is in freetype.h */ 3051ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3052ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_EXPORT_DEF( FT_Error ) 3053ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Get_Track_Kerning( FT_Face face, 3054ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Fixed point_size, 3055ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Int degree, 3056ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Fixed* akerning ) 3057ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 3058ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Service_Kerning service; 3059ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Error error = FT_Err_Ok; 3060ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3061ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3062ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( !face ) 3063ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FT_THROW( Invalid_Face_Handle ); 3064ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3065ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( !akerning ) 3066ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FT_THROW( Invalid_Argument ); 3067ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3068ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FACE_FIND_SERVICE( face, service, KERNING ); 3069ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( !service ) 3070ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FT_THROW( Unimplemented_Feature ); 3071ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3072ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = service->get_track( face, 3073ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov point_size, 3074ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov degree, 3075ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov akerning ); 3076ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3077ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return error; 3078ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 3079ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3080ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3081ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* documentation is in freetype.h */ 3082ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3083ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_EXPORT_DEF( FT_Error ) 3084ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Select_Charmap( FT_Face face, 3085ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Encoding encoding ) 3086ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 3087ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_CharMap* cur; 3088ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_CharMap* limit; 3089ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3090ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3091ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( !face ) 3092ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FT_THROW( Invalid_Face_Handle ); 3093ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3094ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( encoding == FT_ENCODING_NONE ) 3095ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FT_THROW( Invalid_Argument ); 3096ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3097ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* FT_ENCODING_UNICODE is special. We try to find the `best' Unicode */ 3098ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* charmap available, i.e., one with UCS-4 characters, if possible. */ 3099ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 3100ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* This is done by find_unicode_charmap() above, to share code. */ 3101ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( encoding == FT_ENCODING_UNICODE ) 3102ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return find_unicode_charmap( face ); 3103ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3104ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cur = face->charmaps; 3105ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( !cur ) 3106ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FT_THROW( Invalid_CharMap_Handle ); 3107ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3108ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov limit = cur + face->num_charmaps; 3109ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3110ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for ( ; cur < limit; cur++ ) 3111ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 3112ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( cur[0]->encoding == encoding ) 3113ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 3114ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#ifdef FT_MAX_CHARMAP_CACHEABLE 3115ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( cur - face->charmaps > FT_MAX_CHARMAP_CACHEABLE ) 3116ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 3117ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ERROR(( "FT_Select_Charmap: requested charmap is found (%d), " 3118ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov "but in too late position to cache\n", 3119ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cur - face->charmaps )); 3120ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov continue; 3121ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 3122ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif 3123ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov face->charmap = cur[0]; 3124ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return 0; 3125ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 3126ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 3127ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3128ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FT_THROW( Invalid_Argument ); 3129ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 3130ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3131ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3132ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* documentation is in freetype.h */ 3133ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3134ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_EXPORT_DEF( FT_Error ) 3135ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Set_Charmap( FT_Face face, 3136ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_CharMap charmap ) 3137ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 3138ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_CharMap* cur; 3139ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_CharMap* limit; 3140ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3141ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3142ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( !face ) 3143ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FT_THROW( Invalid_Face_Handle ); 3144ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3145ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cur = face->charmaps; 3146ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( !cur ) 3147ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FT_THROW( Invalid_CharMap_Handle ); 3148ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( FT_Get_CMap_Format( charmap ) == 14 ) 3149ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FT_THROW( Invalid_Argument ); 3150ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3151ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov limit = cur + face->num_charmaps; 3152ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3153ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for ( ; cur < limit; cur++ ) 3154ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 3155ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( cur[0] == charmap ) 3156ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 3157ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#ifdef FT_MAX_CHARMAP_CACHEABLE 3158ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( cur - face->charmaps > FT_MAX_CHARMAP_CACHEABLE ) 3159ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 3160ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ERROR(( "FT_Set_Charmap: requested charmap is found (%d), " 3161ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov "but in too late position to cache\n", 3162ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cur - face->charmaps )); 3163ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov continue; 3164ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 3165ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif 3166ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov face->charmap = cur[0]; 3167ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return 0; 3168ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 3169ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 3170ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FT_THROW( Invalid_Argument ); 3171ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 3172ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3173ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3174ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* documentation is in freetype.h */ 3175ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3176ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_EXPORT_DEF( FT_Int ) 3177ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Get_Charmap_Index( FT_CharMap charmap ) 3178ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 3179ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Int i; 3180ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3181ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3182ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( !charmap || !charmap->face ) 3183ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return -1; 3184ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3185ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for ( i = 0; i < charmap->face->num_charmaps; i++ ) 3186ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( charmap->face->charmaps[i] == charmap ) 3187ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov break; 3188ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3189ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ASSERT( i < charmap->face->num_charmaps ); 3190ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3191ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#ifdef FT_MAX_CHARMAP_CACHEABLE 3192ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( i > FT_MAX_CHARMAP_CACHEABLE ) 3193ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 3194ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ERROR(( "FT_Get_Charmap_Index: requested charmap is found (%d), " 3195ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov "but in too late position to cache\n", 3196ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov i )); 3197ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return -i; 3198ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 3199ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif 3200ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return i; 3201ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 3202ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3203ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3204ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov static void 3205ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ft_cmap_done_internal( FT_CMap cmap ) 3206ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 3207ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_CMap_Class clazz = cmap->clazz; 3208ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Face face = cmap->charmap.face; 3209ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Memory memory = FT_FACE_MEMORY( face ); 3210ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3211ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3212ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( clazz->done ) 3213ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov clazz->done( cmap ); 3214ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3215ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FREE( cmap ); 3216ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 3217ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3218ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3219ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_BASE_DEF( void ) 3220ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_CMap_Done( FT_CMap cmap ) 3221ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 3222ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( cmap ) 3223ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 3224ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Face face = cmap->charmap.face; 3225ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Memory memory = FT_FACE_MEMORY( face ); 3226ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Error error; 3227ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Int i, j; 3228ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3229ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3230ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for ( i = 0; i < face->num_charmaps; i++ ) 3231ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 3232ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( (FT_CMap)face->charmaps[i] == cmap ) 3233ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 3234ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_CharMap last_charmap = face->charmaps[face->num_charmaps - 1]; 3235ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3236ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3237ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( FT_RENEW_ARRAY( face->charmaps, 3238ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov face->num_charmaps, 3239ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov face->num_charmaps - 1 ) ) 3240ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return; 3241ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3242ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* remove it from our list of charmaps */ 3243ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for ( j = i + 1; j < face->num_charmaps; j++ ) 3244ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 3245ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( j == face->num_charmaps - 1 ) 3246ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov face->charmaps[j - 1] = last_charmap; 3247ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else 3248ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov face->charmaps[j - 1] = face->charmaps[j]; 3249ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 3250ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3251ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov face->num_charmaps--; 3252ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3253ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( (FT_CMap)face->charmap == cmap ) 3254ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov face->charmap = NULL; 3255ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3256ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ft_cmap_done_internal( cmap ); 3257ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3258ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov break; 3259ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 3260ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 3261ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 3262ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 3263ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3264ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3265ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_BASE_DEF( FT_Error ) 3266ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_CMap_New( FT_CMap_Class clazz, 3267ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Pointer init_data, 3268ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_CharMap charmap, 3269ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_CMap *acmap ) 3270ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 3271ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Error error = FT_Err_Ok; 3272ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Face face; 3273ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Memory memory; 3274ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_CMap cmap = NULL; 3275ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3276ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3277ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( clazz == NULL || charmap == NULL || charmap->face == NULL ) 3278ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FT_THROW( Invalid_Argument ); 3279ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3280ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov face = charmap->face; 3281ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov memory = FT_FACE_MEMORY( face ); 3282ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3283ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( !FT_ALLOC( cmap, clazz->size ) ) 3284ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 3285ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmap->charmap = *charmap; 3286ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmap->clazz = clazz; 3287ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3288ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( clazz->init ) 3289ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 3290ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = clazz->init( cmap, init_data ); 3291ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( error ) 3292ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Fail; 3293ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 3294ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3295ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* add it to our list of charmaps */ 3296ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( FT_RENEW_ARRAY( face->charmaps, 3297ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov face->num_charmaps, 3298ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov face->num_charmaps + 1 ) ) 3299ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Fail; 3300ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3301ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov face->charmaps[face->num_charmaps++] = (FT_CharMap)cmap; 3302ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 3303ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3304ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Exit: 3305ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( acmap ) 3306ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *acmap = cmap; 3307ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3308ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return error; 3309ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3310ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Fail: 3311ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ft_cmap_done_internal( cmap ); 3312ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmap = NULL; 3313ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Exit; 3314ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 3315ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3316ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3317ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* documentation is in freetype.h */ 3318ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3319ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_EXPORT_DEF( FT_UInt ) 3320ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Get_Char_Index( FT_Face face, 3321ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ULong charcode ) 3322ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 3323ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt result = 0; 3324ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3325ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3326ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( face && face->charmap ) 3327ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 3328ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_CMap cmap = FT_CMAP( face->charmap ); 3329ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3330ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3331ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( charcode > 0xFFFFFFFFUL ) 3332ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 3333ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_TRACE1(( "FT_Get_Char_Index: too large charcode" )); 3334ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_TRACE1(( " 0x%x is truncated\n", charcode )); 3335ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 3336ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov result = cmap->clazz->char_index( cmap, (FT_UInt32)charcode ); 3337ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 3338ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return result; 3339ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 3340ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3341ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3342ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* documentation is in freetype.h */ 3343ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3344ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_EXPORT_DEF( FT_ULong ) 3345ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Get_First_Char( FT_Face face, 3346ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt *agindex ) 3347ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 3348ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ULong result = 0; 3349ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt gindex = 0; 3350ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3351ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3352ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( face && face->charmap && face->num_glyphs ) 3353ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 3354ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov gindex = FT_Get_Char_Index( face, 0 ); 3355ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( gindex == 0 || gindex >= (FT_UInt)face->num_glyphs ) 3356ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov result = FT_Get_Next_Char( face, 0, &gindex ); 3357ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 3358ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3359ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( agindex ) 3360ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *agindex = gindex; 3361ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3362ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return result; 3363ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 3364ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3365ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3366ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* documentation is in freetype.h */ 3367ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3368ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_EXPORT_DEF( FT_ULong ) 3369ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Get_Next_Char( FT_Face face, 3370ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ULong charcode, 3371ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt *agindex ) 3372ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 3373ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ULong result = 0; 3374ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt gindex = 0; 3375ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3376ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3377ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( face && face->charmap && face->num_glyphs ) 3378ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 3379ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt32 code = (FT_UInt32)charcode; 3380ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_CMap cmap = FT_CMAP( face->charmap ); 3381ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3382ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3383ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov do { 3384ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov gindex = cmap->clazz->char_next( cmap, &code ); 3385ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } while ( gindex >= (FT_UInt)face->num_glyphs ); 3386ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3387ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov result = ( gindex == 0 ) ? 0 : code; 3388ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 3389ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3390ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( agindex ) 3391ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *agindex = gindex; 3392ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3393ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return result; 3394ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 3395ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3396ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3397ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* documentation is in freetype.h */ 3398ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3399ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_EXPORT_DEF( FT_UInt ) 3400ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Face_GetCharVariantIndex( FT_Face face, 3401ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ULong charcode, 3402ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ULong variantSelector ) 3403ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 3404ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt result = 0; 3405ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3406ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3407ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( face && face->charmap && 3408ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov face->charmap->encoding == FT_ENCODING_UNICODE ) 3409ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 3410ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_CharMap charmap = find_variant_selector_charmap( face ); 3411ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_CMap ucmap = FT_CMAP( face->charmap ); 3412ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3413ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3414ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( charmap != NULL ) 3415ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 3416ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_CMap vcmap = FT_CMAP( charmap ); 3417ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3418ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3419ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( charcode > 0xFFFFFFFFUL ) 3420ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 3421ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_TRACE1(( "FT_Get_Char_Index: too large charcode" )); 3422ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_TRACE1(( " 0x%x is truncated\n", charcode )); 3423ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 3424ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( variantSelector > 0xFFFFFFFFUL ) 3425ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 3426ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_TRACE1(( "FT_Get_Char_Index: too large variantSelector" )); 3427ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_TRACE1(( " 0x%x is truncated\n", variantSelector )); 3428ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 3429ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3430ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov result = vcmap->clazz->char_var_index( vcmap, ucmap, 3431ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov (FT_UInt32)charcode, 3432ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov (FT_UInt32)variantSelector ); 3433ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 3434ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 3435ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3436ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return result; 3437ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 3438ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3439ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3440ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* documentation is in freetype.h */ 3441ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3442ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_EXPORT_DEF( FT_Int ) 3443ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Face_GetCharVariantIsDefault( FT_Face face, 3444ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ULong charcode, 3445ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ULong variantSelector ) 3446ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 3447ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Int result = -1; 3448ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3449ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3450ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( face ) 3451ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 3452ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_CharMap charmap = find_variant_selector_charmap( face ); 3453ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3454ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3455ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( charmap != NULL ) 3456ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 3457ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_CMap vcmap = FT_CMAP( charmap ); 3458ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3459ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3460ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( charcode > 0xFFFFFFFFUL ) 3461ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 3462ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_TRACE1(( "FT_Get_Char_Index: too large charcode" )); 3463ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_TRACE1(( " 0x%x is truncated\n", charcode )); 3464ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 3465ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( variantSelector > 0xFFFFFFFFUL ) 3466ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 3467ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_TRACE1(( "FT_Get_Char_Index: too large variantSelector" )); 3468ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_TRACE1(( " 0x%x is truncated\n", variantSelector )); 3469ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 3470ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3471ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov result = vcmap->clazz->char_var_default( vcmap, 3472ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov (FT_UInt32)charcode, 3473ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov (FT_UInt32)variantSelector ); 3474ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 3475ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 3476ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3477ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return result; 3478ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 3479ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3480ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3481ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* documentation is in freetype.h */ 3482ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3483ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_EXPORT_DEF( FT_UInt32* ) 3484ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Face_GetVariantSelectors( FT_Face face ) 3485ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 3486ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt32 *result = NULL; 3487ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3488ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3489ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( face ) 3490ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 3491ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_CharMap charmap = find_variant_selector_charmap( face ); 3492ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3493ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3494ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( charmap != NULL ) 3495ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 3496ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_CMap vcmap = FT_CMAP( charmap ); 3497ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Memory memory = FT_FACE_MEMORY( face ); 3498ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3499ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3500ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov result = vcmap->clazz->variant_list( vcmap, memory ); 3501ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 3502ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 3503ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3504ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return result; 3505ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 3506ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3507ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3508ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* documentation is in freetype.h */ 3509ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3510ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_EXPORT_DEF( FT_UInt32* ) 3511ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Face_GetVariantsOfChar( FT_Face face, 3512ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ULong charcode ) 3513ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 3514ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt32 *result = NULL; 3515ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3516ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3517ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( face ) 3518ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 3519ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_CharMap charmap = find_variant_selector_charmap( face ); 3520ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3521ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3522ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( charmap != NULL ) 3523ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 3524ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_CMap vcmap = FT_CMAP( charmap ); 3525ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Memory memory = FT_FACE_MEMORY( face ); 3526ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3527ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3528ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( charcode > 0xFFFFFFFFUL ) 3529ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 3530ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_TRACE1(( "FT_Get_Char_Index: too large charcode" )); 3531ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_TRACE1(( " 0x%x is truncated\n", charcode )); 3532ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 3533ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3534ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov result = vcmap->clazz->charvariant_list( vcmap, memory, 3535ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov (FT_UInt32)charcode ); 3536ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 3537ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 3538ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return result; 3539ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 3540ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3541ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3542ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* documentation is in freetype.h */ 3543ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3544ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_EXPORT_DEF( FT_UInt32* ) 3545ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Face_GetCharsOfVariant( FT_Face face, 3546ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ULong variantSelector ) 3547ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 3548ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt32 *result = NULL; 3549ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3550ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3551ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( face ) 3552ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 3553ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_CharMap charmap = find_variant_selector_charmap( face ); 3554ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3555ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3556ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( charmap != NULL ) 3557ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 3558ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_CMap vcmap = FT_CMAP( charmap ); 3559ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Memory memory = FT_FACE_MEMORY( face ); 3560ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3561ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3562ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( variantSelector > 0xFFFFFFFFUL ) 3563ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 3564ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_TRACE1(( "FT_Get_Char_Index: too large variantSelector" )); 3565ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_TRACE1(( " 0x%x is truncated\n", variantSelector )); 3566ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 3567ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3568ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov result = vcmap->clazz->variantchar_list( vcmap, memory, 3569ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov (FT_UInt32)variantSelector ); 3570ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 3571ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 3572ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3573ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return result; 3574ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 3575ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3576ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3577ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* documentation is in freetype.h */ 3578ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3579ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_EXPORT_DEF( FT_UInt ) 3580ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Get_Name_Index( FT_Face face, 3581ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_String* glyph_name ) 3582ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 3583ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt result = 0; 3584ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3585ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3586ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( face && FT_HAS_GLYPH_NAMES( face ) ) 3587ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 3588ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Service_GlyphDict service; 3589ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3590ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3591ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FACE_LOOKUP_SERVICE( face, 3592ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov service, 3593ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov GLYPH_DICT ); 3594ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3595ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( service && service->name_index ) 3596ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov result = service->name_index( face, glyph_name ); 3597ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 3598ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3599ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return result; 3600ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 3601ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3602ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3603ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* documentation is in freetype.h */ 3604ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3605ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_EXPORT_DEF( FT_Error ) 3606ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Get_Glyph_Name( FT_Face face, 3607ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt glyph_index, 3608ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Pointer buffer, 3609ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt buffer_max ) 3610ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 3611ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Error error = FT_ERR( Invalid_Argument ); 3612ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3613ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3614ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* clean up buffer */ 3615ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( buffer && buffer_max > 0 ) 3616ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ((FT_Byte*)buffer)[0] = 0; 3617ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3618ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( face && 3619ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov (FT_Long)glyph_index <= face->num_glyphs && 3620ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_HAS_GLYPH_NAMES( face ) ) 3621ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 3622ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Service_GlyphDict service; 3623ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3624ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3625ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FACE_LOOKUP_SERVICE( face, 3626ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov service, 3627ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov GLYPH_DICT ); 3628ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3629ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( service && service->get_name ) 3630ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = service->get_name( face, glyph_index, buffer, buffer_max ); 3631ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 3632ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3633ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return error; 3634ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 3635ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3636ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3637ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* documentation is in freetype.h */ 3638ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3639ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_EXPORT_DEF( const char* ) 3640ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Get_Postscript_Name( FT_Face face ) 3641ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 3642ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov const char* result = NULL; 3643ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3644ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3645ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( !face ) 3646ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Exit; 3647ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3648ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( !result ) 3649ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 3650ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Service_PsFontName service; 3651ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3652ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3653ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FACE_LOOKUP_SERVICE( face, 3654ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov service, 3655ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov POSTSCRIPT_FONT_NAME ); 3656ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3657ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( service && service->get_ps_font_name ) 3658ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov result = service->get_ps_font_name( face ); 3659ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 3660ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3661ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Exit: 3662ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return result; 3663ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 3664ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3665ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3666ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* documentation is in tttables.h */ 3667ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3668ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_EXPORT_DEF( void* ) 3669ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Get_Sfnt_Table( FT_Face face, 3670ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Sfnt_Tag tag ) 3671ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 3672ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov void* table = 0; 3673ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Service_SFNT_Table service; 3674ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3675ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3676ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( face && FT_IS_SFNT( face ) ) 3677ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 3678ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FACE_FIND_SERVICE( face, service, SFNT_TABLE ); 3679ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( service != NULL ) 3680ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov table = service->get_table( face, tag ); 3681ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 3682ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3683ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return table; 3684ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 3685ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3686ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3687ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* documentation is in tttables.h */ 3688ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3689ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_EXPORT_DEF( FT_Error ) 3690ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Load_Sfnt_Table( FT_Face face, 3691ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ULong tag, 3692ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Long offset, 3693ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte* buffer, 3694ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ULong* length ) 3695ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 3696ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Service_SFNT_Table service; 3697ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3698ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3699ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( !face || !FT_IS_SFNT( face ) ) 3700ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FT_THROW( Invalid_Face_Handle ); 3701ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3702ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FACE_FIND_SERVICE( face, service, SFNT_TABLE ); 3703ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( service == NULL ) 3704ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FT_THROW( Unimplemented_Feature ); 3705ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3706ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return service->load_table( face, tag, offset, buffer, length ); 3707ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 3708ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3709ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3710ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* documentation is in tttables.h */ 3711ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3712ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_EXPORT_DEF( FT_Error ) 3713ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Sfnt_Table_Info( FT_Face face, 3714ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt table_index, 3715ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ULong *tag, 3716ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ULong *length ) 3717ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 3718ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Service_SFNT_Table service; 3719ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ULong offset; 3720ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3721ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3722ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( !face || !FT_IS_SFNT( face ) ) 3723ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FT_THROW( Invalid_Face_Handle ); 3724ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3725ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FACE_FIND_SERVICE( face, service, SFNT_TABLE ); 3726ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( service == NULL ) 3727ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FT_THROW( Unimplemented_Feature ); 3728ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3729ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return service->table_info( face, table_index, tag, &offset, length ); 3730ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 3731ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3732ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3733ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* documentation is in tttables.h */ 3734ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3735ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_EXPORT_DEF( FT_ULong ) 3736ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Get_CMap_Language_ID( FT_CharMap charmap ) 3737ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 3738ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Service_TTCMaps service; 3739ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Face face; 3740ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov TT_CMapInfo cmap_info; 3741ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3742ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3743ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( !charmap || !charmap->face ) 3744ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return 0; 3745ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3746ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov face = charmap->face; 3747ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FACE_FIND_SERVICE( face, service, TT_CMAP ); 3748ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( service == NULL ) 3749ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return 0; 3750ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( service->get_cmap_info( charmap, &cmap_info )) 3751ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return 0; 3752ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3753ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return cmap_info.language; 3754ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 3755ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3756ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3757ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* documentation is in tttables.h */ 3758ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3759ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_EXPORT_DEF( FT_Long ) 3760ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Get_CMap_Format( FT_CharMap charmap ) 3761ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 3762ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Service_TTCMaps service; 3763ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Face face; 3764ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov TT_CMapInfo cmap_info; 3765ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3766ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3767ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( !charmap || !charmap->face ) 3768ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return -1; 3769ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3770ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov face = charmap->face; 3771ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FACE_FIND_SERVICE( face, service, TT_CMAP ); 3772ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( service == NULL ) 3773ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return -1; 3774ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( service->get_cmap_info( charmap, &cmap_info )) 3775ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return -1; 3776ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3777ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return cmap_info.format; 3778ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 3779ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3780ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3781ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* documentation is in ftsizes.h */ 3782ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3783ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_EXPORT_DEF( FT_Error ) 3784ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Activate_Size( FT_Size size ) 3785ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 3786ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Face face; 3787ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3788ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3789ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( size == NULL ) 3790ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FT_THROW( Invalid_Argument ); 3791ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3792ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov face = size->face; 3793ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( face == NULL || face->driver == NULL ) 3794ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FT_THROW( Invalid_Argument ); 3795ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3796ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* we don't need anything more complex than that; all size objects */ 3797ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* are already listed by the face */ 3798ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov face->size = size; 3799ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3800ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FT_Err_Ok; 3801ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 3802ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3803ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3804ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 3805ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 3806ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 3807ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /**** ****/ 3808ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /**** ****/ 3809ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /**** R E N D E R E R S ****/ 3810ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /**** ****/ 3811ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /**** ****/ 3812ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 3813ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 3814ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 3815ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3816ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* lookup a renderer by glyph format in the library's list */ 3817ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_BASE_DEF( FT_Renderer ) 3818ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Lookup_Renderer( FT_Library library, 3819ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Glyph_Format format, 3820ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ListNode* node ) 3821ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 3822ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ListNode cur; 3823ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Renderer result = 0; 3824ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3825ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3826ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( !library ) 3827ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Exit; 3828ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3829ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cur = library->renderers.head; 3830ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3831ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( node ) 3832ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 3833ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( *node ) 3834ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cur = (*node)->next; 3835ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *node = 0; 3836ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 3837ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3838ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov while ( cur ) 3839ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 3840ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Renderer renderer = FT_RENDERER( cur->data ); 3841ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3842ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3843ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( renderer->glyph_format == format ) 3844ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 3845ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( node ) 3846ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *node = cur; 3847ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3848ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov result = renderer; 3849ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov break; 3850ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 3851ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cur = cur->next; 3852ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 3853ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3854ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Exit: 3855ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return result; 3856ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 3857ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3858ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3859ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov static FT_Renderer 3860ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ft_lookup_glyph_renderer( FT_GlyphSlot slot ) 3861ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 3862ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Face face = slot->face; 3863ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Library library = FT_FACE_LIBRARY( face ); 3864ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Renderer result = library->cur_renderer; 3865ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3866ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3867ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( !result || result->glyph_format != slot->format ) 3868ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov result = FT_Lookup_Renderer( library, slot->format, 0 ); 3869ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3870ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return result; 3871ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 3872ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3873ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3874ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov static void 3875ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ft_set_current_renderer( FT_Library library ) 3876ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 3877ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Renderer renderer; 3878ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3879ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3880ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov renderer = FT_Lookup_Renderer( library, FT_GLYPH_FORMAT_OUTLINE, 0 ); 3881ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov library->cur_renderer = renderer; 3882ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 3883ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3884ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3885ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov static FT_Error 3886ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ft_add_renderer( FT_Module module ) 3887ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 3888ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Library library = module->library; 3889ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Memory memory = library->memory; 3890ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Error error; 3891ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ListNode node = NULL; 3892ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3893ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3894ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( FT_NEW( node ) ) 3895ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Exit; 3896ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3897ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 3898ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Renderer render = FT_RENDERER( module ); 3899ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Renderer_Class* clazz = (FT_Renderer_Class*)module->clazz; 3900ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3901ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3902ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov render->clazz = clazz; 3903ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov render->glyph_format = clazz->glyph_format; 3904ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3905ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* allocate raster object if needed */ 3906ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( clazz->glyph_format == FT_GLYPH_FORMAT_OUTLINE && 3907ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov clazz->raster_class->raster_new ) 3908ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 3909ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = clazz->raster_class->raster_new( memory, &render->raster ); 3910ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( error ) 3911ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Fail; 3912ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3913ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov render->raster_render = clazz->raster_class->raster_render; 3914ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov render->render = clazz->render_glyph; 3915ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 3916ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3917ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* add to list */ 3918ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov node->data = module; 3919ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_List_Add( &library->renderers, node ); 3920ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3921ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ft_set_current_renderer( library ); 3922ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 3923ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3924ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Fail: 3925ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( error ) 3926ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FREE( node ); 3927ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3928ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Exit: 3929ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return error; 3930ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 3931ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3932ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3933ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov static void 3934ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ft_remove_renderer( FT_Module module ) 3935ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 3936ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Library library = module->library; 3937ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Memory memory = library->memory; 3938ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ListNode node; 3939ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3940ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3941ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov node = FT_List_Find( &library->renderers, module ); 3942ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( node ) 3943ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 3944ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Renderer render = FT_RENDERER( module ); 3945ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3946ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3947ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* release raster object, if any */ 3948ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( render->clazz->glyph_format == FT_GLYPH_FORMAT_OUTLINE && 3949ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov render->raster ) 3950ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov render->clazz->raster_class->raster_done( render->raster ); 3951ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3952ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* remove from list */ 3953ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_List_Remove( &library->renderers, node ); 3954ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FREE( node ); 3955ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3956ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ft_set_current_renderer( library ); 3957ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 3958ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 3959ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3960ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3961ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* documentation is in ftrender.h */ 3962ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3963ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_EXPORT_DEF( FT_Renderer ) 3964ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Get_Renderer( FT_Library library, 3965ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Glyph_Format format ) 3966ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 3967ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* test for valid `library' delayed to FT_Lookup_Renderer() */ 3968ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3969ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FT_Lookup_Renderer( library, format, 0 ); 3970ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 3971ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3972ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3973ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* documentation is in ftrender.h */ 3974ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3975ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_EXPORT_DEF( FT_Error ) 3976ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Set_Renderer( FT_Library library, 3977ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Renderer renderer, 3978ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt num_params, 3979ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Parameter* parameters ) 3980ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 3981ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ListNode node; 3982ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Error error = FT_Err_Ok; 3983ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3984ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3985ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( !library ) 3986ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FT_THROW( Invalid_Library_Handle ); 3987ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3988ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( !renderer ) 3989ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FT_THROW( Invalid_Argument ); 3990ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3991ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov node = FT_List_Find( &library->renderers, renderer ); 3992ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( !node ) 3993ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 3994ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = FT_THROW( Invalid_Argument ); 3995ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Exit; 3996ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 3997ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3998ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_List_Up( &library->renderers, node ); 3999ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4000ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( renderer->glyph_format == FT_GLYPH_FORMAT_OUTLINE ) 4001ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov library->cur_renderer = renderer; 4002ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4003ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( num_params > 0 ) 4004ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 4005ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Renderer_SetModeFunc set_mode = renderer->clazz->set_mode; 4006ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4007ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4008ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for ( ; num_params > 0; num_params-- ) 4009ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 4010ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = set_mode( renderer, parameters->tag, parameters->data ); 4011ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( error ) 4012ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov break; 4013ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov parameters++; 4014ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 4015ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 4016ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4017ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Exit: 4018ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return error; 4019ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 4020ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4021ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4022ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_BASE_DEF( FT_Error ) 4023ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Render_Glyph_Internal( FT_Library library, 4024ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_GlyphSlot slot, 4025ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Render_Mode render_mode ) 4026ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 4027ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Error error = FT_Err_Ok; 4028ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Renderer renderer; 4029ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4030ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4031ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* if it is already a bitmap, no need to do anything */ 4032ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov switch ( slot->format ) 4033ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 4034ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov case FT_GLYPH_FORMAT_BITMAP: /* already a bitmap, don't do anything */ 4035ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov break; 4036ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4037ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov default: 4038ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 4039ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ListNode node = 0; 4040ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Bool update = 0; 4041ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4042ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4043ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* small shortcut for the very common case */ 4044ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( slot->format == FT_GLYPH_FORMAT_OUTLINE ) 4045ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 4046ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov renderer = library->cur_renderer; 4047ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov node = library->renderers.head; 4048ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 4049ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else 4050ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov renderer = FT_Lookup_Renderer( library, slot->format, &node ); 4051ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4052ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = FT_ERR( Unimplemented_Feature ); 4053ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov while ( renderer ) 4054ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 4055ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = renderer->render( renderer, slot, render_mode, NULL ); 4056ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( !error || 4057ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ERR_NEQ( error, Cannot_Render_Glyph ) ) 4058ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov break; 4059ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4060ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* FT_Err_Cannot_Render_Glyph is returned if the render mode */ 4061ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* is unsupported by the current renderer for this glyph image */ 4062ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* format. */ 4063ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4064ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* now, look for another renderer that supports the same */ 4065ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* format. */ 4066ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov renderer = FT_Lookup_Renderer( library, slot->format, &node ); 4067ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov update = 1; 4068ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 4069ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4070ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* if we changed the current renderer for the glyph image format */ 4071ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* we need to select it as the next current one */ 4072ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( !error && update && renderer ) 4073ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Set_Renderer( library, renderer, 0, 0 ); 4074ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 4075ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 4076ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4077ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#ifdef FT_DEBUG_LEVEL_TRACE 4078ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4079ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#undef FT_COMPONENT 4080ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define FT_COMPONENT trace_bitmap 4081ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4082ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* we convert to a single bitmap format for computing the checksum */ 4083ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 4084ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Bitmap bitmap; 4085ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Error err; 4086ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4087ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4088ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Bitmap_New( &bitmap ); 4089ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4090ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov err = FT_Bitmap_Convert( library, &slot->bitmap, &bitmap, 1 ); 4091ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( !err ) 4092ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 4093ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov MD5_CTX ctx; 4094ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov unsigned char md5[16]; 4095ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov int i; 4096ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4097ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4098ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov MD5_Init( &ctx); 4099ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov MD5_Update( &ctx, bitmap.buffer, bitmap.rows * bitmap.pitch ); 4100ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov MD5_Final( md5, &ctx ); 4101ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4102ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_TRACE3(( "MD5 checksum for %dx%d bitmap:\n" 4103ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov " ", 4104ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov bitmap.rows, bitmap.pitch )); 4105ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for ( i = 0; i < 16; i++ ) 4106ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_TRACE3(( "%02X", md5[i] )); 4107ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_TRACE3(( "\n" )); 4108ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 4109ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4110ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Bitmap_Done( library, &bitmap ); 4111ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 4112ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4113ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#undef FT_COMPONENT 4114ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define FT_COMPONENT trace_objs 4115ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4116ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif /* FT_DEBUG_LEVEL_TRACE */ 4117ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4118ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return error; 4119ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 4120ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4121ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* documentation is in freetype.h */ 4122ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4123ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_EXPORT_DEF( FT_Error ) 4124ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Render_Glyph( FT_GlyphSlot slot, 4125ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Render_Mode render_mode ) 4126ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 4127ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Library library; 4128ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4129ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( !slot || !slot->face ) 4130ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FT_THROW( Invalid_Argument ); 4131ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4132ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov library = FT_FACE_LIBRARY( slot->face ); 4133ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4134ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FT_Render_Glyph_Internal( library, slot, render_mode ); 4135ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 4136ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4137ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4138ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 4139ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 4140ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 4141ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /**** ****/ 4142ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /**** ****/ 4143ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /**** M O D U L E S ****/ 4144ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /**** ****/ 4145ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /**** ****/ 4146ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 4147ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 4148ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 4149ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4150ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4151ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 4152ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 4153ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* <Function> */ 4154ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Destroy_Module */ 4155ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 4156ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* <Description> */ 4157ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Destroys a given module object. For drivers, this also destroys */ 4158ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* all child faces. */ 4159ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 4160ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* <InOut> */ 4161ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* module :: A handle to the target driver object. */ 4162ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 4163ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* <Note> */ 4164ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* The driver _must_ be LOCKED! */ 4165ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 4166ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov static void 4167ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Destroy_Module( FT_Module module ) 4168ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 4169ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Memory memory = module->memory; 4170ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Module_Class* clazz = module->clazz; 4171ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Library library = module->library; 4172ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4173ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4174ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( library && library->auto_hinter == module ) 4175ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov library->auto_hinter = 0; 4176ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4177ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* if the module is a renderer */ 4178ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( FT_MODULE_IS_RENDERER( module ) ) 4179ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ft_remove_renderer( module ); 4180ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4181ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* if the module is a font driver, add some steps */ 4182ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( FT_MODULE_IS_DRIVER( module ) ) 4183ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Destroy_Driver( FT_DRIVER( module ) ); 4184ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4185ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* finalize the module object */ 4186ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( clazz->module_done ) 4187ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov clazz->module_done( module ); 4188ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4189ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* discard it */ 4190ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FREE( module ); 4191ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 4192ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4193ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4194ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* documentation is in ftmodapi.h */ 4195ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4196ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_EXPORT_DEF( FT_Error ) 4197ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Add_Module( FT_Library library, 4198ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov const FT_Module_Class* clazz ) 4199ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 4200ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Error error; 4201ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Memory memory; 4202ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Module module; 4203ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt nn; 4204ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4205ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4206ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define FREETYPE_VER_FIXED ( ( (FT_Long)FREETYPE_MAJOR << 16 ) | \ 4207ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FREETYPE_MINOR ) 4208ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4209ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( !library ) 4210ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FT_THROW( Invalid_Library_Handle ); 4211ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4212ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( !clazz ) 4213ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FT_THROW( Invalid_Argument ); 4214ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4215ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* check freetype version */ 4216ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( clazz->module_requires > FREETYPE_VER_FIXED ) 4217ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FT_THROW( Invalid_Version ); 4218ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4219ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* look for a module with the same name in the library's table */ 4220ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for ( nn = 0; nn < library->num_modules; nn++ ) 4221ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 4222ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov module = library->modules[nn]; 4223ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( ft_strcmp( module->clazz->module_name, clazz->module_name ) == 0 ) 4224ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 4225ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* this installed module has the same name, compare their versions */ 4226ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( clazz->module_version <= module->clazz->module_version ) 4227ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FT_THROW( Lower_Module_Version ); 4228ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4229ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* remove the module from our list, then exit the loop to replace */ 4230ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* it by our new version.. */ 4231ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Remove_Module( library, module ); 4232ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov break; 4233ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 4234ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 4235ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4236ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov memory = library->memory; 4237ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = FT_Err_Ok; 4238ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4239ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( library->num_modules >= FT_MAX_MODULES ) 4240ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 4241ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = FT_THROW( Too_Many_Drivers ); 4242ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Exit; 4243ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 4244ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4245ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* allocate module object */ 4246ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( FT_ALLOC( module, clazz->module_size ) ) 4247ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Exit; 4248ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4249ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* base initialization */ 4250ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov module->library = library; 4251ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov module->memory = memory; 4252ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov module->clazz = (FT_Module_Class*)clazz; 4253ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4254ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* check whether the module is a renderer - this must be performed */ 4255ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* before the normal module initialization */ 4256ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( FT_MODULE_IS_RENDERER( module ) ) 4257ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 4258ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* add to the renderers list */ 4259ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = ft_add_renderer( module ); 4260ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( error ) 4261ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Fail; 4262ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 4263ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4264ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* is the module a auto-hinter? */ 4265ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( FT_MODULE_IS_HINTER( module ) ) 4266ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov library->auto_hinter = module; 4267ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4268ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* if the module is a font driver */ 4269ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( FT_MODULE_IS_DRIVER( module ) ) 4270ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 4271ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* allocate glyph loader if needed */ 4272ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Driver driver = FT_DRIVER( module ); 4273ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4274ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4275ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov driver->clazz = (FT_Driver_Class)module->clazz; 4276ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( FT_DRIVER_USES_OUTLINES( driver ) ) 4277ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 4278ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = FT_GlyphLoader_New( memory, &driver->glyph_loader ); 4279ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( error ) 4280ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Fail; 4281ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 4282ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 4283ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4284ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( clazz->module_init ) 4285ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 4286ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = clazz->module_init( module ); 4287ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( error ) 4288ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Fail; 4289ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 4290ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4291ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* add module to the library's table */ 4292ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov library->modules[library->num_modules++] = module; 4293ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4294ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Exit: 4295ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return error; 4296ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4297ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Fail: 4298ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( FT_MODULE_IS_DRIVER( module ) ) 4299ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 4300ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Driver driver = FT_DRIVER( module ); 4301ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4302ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4303ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( FT_DRIVER_USES_OUTLINES( driver ) ) 4304ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_GlyphLoader_Done( driver->glyph_loader ); 4305ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 4306ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4307ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( FT_MODULE_IS_RENDERER( module ) ) 4308ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 4309ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Renderer renderer = FT_RENDERER( module ); 4310ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4311ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4312ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( renderer->clazz && 4313ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov renderer->clazz->glyph_format == FT_GLYPH_FORMAT_OUTLINE && 4314ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov renderer->raster ) 4315ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov renderer->clazz->raster_class->raster_done( renderer->raster ); 4316ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 4317ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4318ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FREE( module ); 4319ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Exit; 4320ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 4321ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4322ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4323ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* documentation is in ftmodapi.h */ 4324ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4325ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_EXPORT_DEF( FT_Module ) 4326ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Get_Module( FT_Library library, 4327ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov const char* module_name ) 4328ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 4329ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Module result = 0; 4330ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Module* cur; 4331ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Module* limit; 4332ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4333ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4334ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( !library || !module_name ) 4335ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return result; 4336ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4337ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cur = library->modules; 4338ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov limit = cur + library->num_modules; 4339ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4340ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for ( ; cur < limit; cur++ ) 4341ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( ft_strcmp( cur[0]->clazz->module_name, module_name ) == 0 ) 4342ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 4343ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov result = cur[0]; 4344ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov break; 4345ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 4346ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4347ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return result; 4348ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 4349ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4350ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4351ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* documentation is in ftobjs.h */ 4352ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4353ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_BASE_DEF( const void* ) 4354ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Get_Module_Interface( FT_Library library, 4355ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov const char* mod_name ) 4356ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 4357ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Module module; 4358ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4359ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4360ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* test for valid `library' delayed to FT_Get_Module() */ 4361ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4362ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov module = FT_Get_Module( library, mod_name ); 4363ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4364ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return module ? module->clazz->module_interface : 0; 4365ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 4366ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4367ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4368ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_BASE_DEF( FT_Pointer ) 4369ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ft_module_get_service( FT_Module module, 4370ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov const char* service_id ) 4371ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 4372ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Pointer result = NULL; 4373ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4374ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4375ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( module ) 4376ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 4377ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ASSERT( module->clazz && module->clazz->get_interface ); 4378ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4379ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* first, look for the service in the module */ 4380ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( module->clazz->get_interface ) 4381ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov result = module->clazz->get_interface( module, service_id ); 4382ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4383ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( result == NULL ) 4384ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 4385ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* we didn't find it, look in all other modules then */ 4386ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Library library = module->library; 4387ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Module* cur = library->modules; 4388ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Module* limit = cur + library->num_modules; 4389ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4390ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4391ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for ( ; cur < limit; cur++ ) 4392ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 4393ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( cur[0] != module ) 4394ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 4395ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ASSERT( cur[0]->clazz ); 4396ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4397ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( cur[0]->clazz->get_interface ) 4398ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 4399ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov result = cur[0]->clazz->get_interface( cur[0], service_id ); 4400ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( result != NULL ) 4401ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov break; 4402ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 4403ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 4404ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 4405ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 4406ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 4407ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4408ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return result; 4409ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 4410ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4411ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4412ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* documentation is in ftmodapi.h */ 4413ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4414ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_EXPORT_DEF( FT_Error ) 4415ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Remove_Module( FT_Library library, 4416ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Module module ) 4417ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 4418ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* try to find the module from the table, then remove it from there */ 4419ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4420ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( !library ) 4421ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FT_THROW( Invalid_Library_Handle ); 4422ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4423ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( module ) 4424ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 4425ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Module* cur = library->modules; 4426ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Module* limit = cur + library->num_modules; 4427ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4428ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4429ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for ( ; cur < limit; cur++ ) 4430ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 4431ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( cur[0] == module ) 4432ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 4433ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* remove it from the table */ 4434ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov library->num_modules--; 4435ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov limit--; 4436ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov while ( cur < limit ) 4437ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 4438ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cur[0] = cur[1]; 4439ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cur++; 4440ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 4441ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov limit[0] = 0; 4442ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4443ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* destroy the module */ 4444ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Destroy_Module( module ); 4445ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4446ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FT_Err_Ok; 4447ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 4448ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 4449ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 4450ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FT_THROW( Invalid_Driver_Handle ); 4451ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 4452ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4453ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4454ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Error 4455ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ft_property_do( FT_Library library, 4456ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov const FT_String* module_name, 4457ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov const FT_String* property_name, 4458ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov void* value, 4459ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Bool set ) 4460ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 4461ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Module* cur; 4462ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Module* limit; 4463ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Module_Interface interface1; 4464ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Service_Properties service; 4465ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4466ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#ifdef FT_DEBUG_LEVEL_ERROR 4467ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov const FT_String* set_name = "FT_Property_Set"; 4468ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov const FT_String* get_name = "FT_Property_Get"; 4469ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov const FT_String* func_name = set ? set_name : get_name; 4470ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif 4471ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4472ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Bool missing_func; 4473ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4474ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4475ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( !library ) 4476ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FT_THROW( Invalid_Library_Handle ); 4477ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4478ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( !module_name || !property_name || !value ) 4479ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FT_THROW( Invalid_Argument ); 4480ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4481ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cur = library->modules; 4482ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov limit = cur + library->num_modules; 4483ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4484ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* search module */ 4485ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for ( ; cur < limit; cur++ ) 4486ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( !ft_strcmp( cur[0]->clazz->module_name, module_name ) ) 4487ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov break; 4488ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4489ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( cur == limit ) 4490ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 4491ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ERROR(( "%s: can't find module `%s'\n", 4492ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov func_name, module_name )); 4493ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FT_THROW( Missing_Module ); 4494ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 4495ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4496ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* check whether we have a service interface */ 4497ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( !cur[0]->clazz->get_interface ) 4498ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 4499ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ERROR(( "%s: module `%s' doesn't support properties\n", 4500ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov func_name, module_name )); 4501ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FT_THROW( Unimplemented_Feature ); 4502ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 4503ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4504ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* search property service */ 4505ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov interface1 = cur[0]->clazz->get_interface( cur[0], 4506ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_SERVICE_ID_PROPERTIES ); 4507ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( !interface1 ) 4508ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 4509ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ERROR(( "%s: module `%s' doesn't support properties\n", 4510ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov func_name, module_name )); 4511ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FT_THROW( Unimplemented_Feature ); 4512ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 4513ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4514ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov service = (FT_Service_Properties)interface1; 4515ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4516ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( set ) 4517ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov missing_func = (FT_Bool)( !service->set_property ); 4518ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else 4519ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov missing_func = (FT_Bool)( !service->get_property ); 4520ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4521ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( missing_func ) 4522ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 4523ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ERROR(( "%s: property service of module `%s' is broken\n", 4524ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov func_name, module_name )); 4525ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FT_THROW( Unimplemented_Feature ); 4526ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 4527ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4528ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return set ? service->set_property( cur[0], property_name, value ) 4529ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov : service->get_property( cur[0], property_name, value ); 4530ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 4531ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4532ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4533ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* documentation is in ftmodapi.h */ 4534ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4535ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_EXPORT_DEF( FT_Error ) 4536ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Property_Set( FT_Library library, 4537ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov const FT_String* module_name, 4538ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov const FT_String* property_name, 4539ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov const void* value ) 4540ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 4541ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return ft_property_do( library, 4542ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov module_name, 4543ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov property_name, 4544ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov (void*)value, 4545ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov TRUE ); 4546ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 4547ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4548ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4549ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* documentation is in ftmodapi.h */ 4550ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4551ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_EXPORT_DEF( FT_Error ) 4552ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Property_Get( FT_Library library, 4553ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov const FT_String* module_name, 4554ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov const FT_String* property_name, 4555ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov void* value ) 4556ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 4557ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return ft_property_do( library, 4558ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov module_name, 4559ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov property_name, 4560ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov value, 4561ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FALSE ); 4562ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 4563ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4564ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4565ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 4566ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 4567ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 4568ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /**** ****/ 4569ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /**** ****/ 4570ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /**** L I B R A R Y ****/ 4571ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /**** ****/ 4572ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /**** ****/ 4573ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 4574ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 4575ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 4576ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4577ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4578ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* documentation is in ftmodapi.h */ 4579ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4580ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_EXPORT_DEF( FT_Error ) 4581ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Reference_Library( FT_Library library ) 4582ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 4583ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov library->refcount++; 4584ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4585ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FT_Err_Ok; 4586ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 4587ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4588ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4589ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* documentation is in ftmodapi.h */ 4590ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4591ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_EXPORT_DEF( FT_Error ) 4592ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_New_Library( FT_Memory memory, 4593ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Library *alibrary ) 4594ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 4595ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Library library = NULL; 4596ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Error error; 4597ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4598ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4599ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( !memory ) 4600ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FT_THROW( Invalid_Argument ); 4601ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4602ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#ifdef FT_DEBUG_LEVEL_ERROR 4603ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* init debugging support */ 4604ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ft_debug_init(); 4605ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif 4606ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4607ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* first of all, allocate the library object */ 4608ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( FT_NEW( library ) ) 4609ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return error; 4610ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4611ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov library->memory = memory; 4612ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4613ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#ifdef FT_CONFIG_OPTION_PIC 4614ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* initialize position independent code containers */ 4615ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = ft_pic_container_init( library ); 4616ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( error ) 4617ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Fail; 4618ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif 4619ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4620ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* allocate the render pool */ 4621ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov library->raster_pool_size = FT_RENDER_POOL_SIZE; 4622ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#if FT_RENDER_POOL_SIZE > 0 4623ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( FT_ALLOC( library->raster_pool, FT_RENDER_POOL_SIZE ) ) 4624ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Fail; 4625ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif 4626ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4627ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov library->version_major = FREETYPE_MAJOR; 4628ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov library->version_minor = FREETYPE_MINOR; 4629ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov library->version_patch = FREETYPE_PATCH; 4630ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4631ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov library->refcount = 1; 4632ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4633ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* That's ok now */ 4634ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *alibrary = library; 4635ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4636ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FT_Err_Ok; 4637ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4638ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Fail: 4639ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#ifdef FT_CONFIG_OPTION_PIC 4640ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ft_pic_container_destroy( library ); 4641ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif 4642ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FREE( library ); 4643ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return error; 4644ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 4645ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4646ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4647ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* documentation is in freetype.h */ 4648ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4649ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_EXPORT_DEF( void ) 4650ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Library_Version( FT_Library library, 4651ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Int *amajor, 4652ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Int *aminor, 4653ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Int *apatch ) 4654ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 4655ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Int major = 0; 4656ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Int minor = 0; 4657ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Int patch = 0; 4658ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4659ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4660ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( library ) 4661ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 4662ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov major = library->version_major; 4663ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov minor = library->version_minor; 4664ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov patch = library->version_patch; 4665ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 4666ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4667ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( amajor ) 4668ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *amajor = major; 4669ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4670ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( aminor ) 4671ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *aminor = minor; 4672ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4673ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( apatch ) 4674ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *apatch = patch; 4675ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 4676ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4677ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4678ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* documentation is in ftmodapi.h */ 4679ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4680ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_EXPORT_DEF( FT_Error ) 4681ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Done_Library( FT_Library library ) 4682ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 4683ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Memory memory; 4684ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4685ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4686ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( !library ) 4687ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FT_THROW( Invalid_Library_Handle ); 4688ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4689ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov library->refcount--; 4690ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( library->refcount > 0 ) 4691ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Exit; 4692ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4693ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov memory = library->memory; 4694ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4695ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* 4696ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * Close all faces in the library. If we don't do this, we can have 4697ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * some subtle memory leaks. 4698ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * 4699ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * Example: 4700ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * 4701ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * - the cff font driver uses the pshinter module in cff_size_done 4702ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * - if the pshinter module is destroyed before the cff font driver, 4703ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * opened FT_Face objects managed by the driver are not properly 4704ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * destroyed, resulting in a memory leak 4705ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * 4706ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * Some faces are dependent on other faces, like Type42 faces that 4707ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * depend on TrueType faces synthesized internally. 4708ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * 4709ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * The order of drivers should be specified in driver_name[]. 4710ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov */ 4711ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 4712ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt m, n; 4713ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov const char* driver_name[] = { "type42", NULL }; 4714ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4715ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4716ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for ( m = 0; 4717ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov m < sizeof ( driver_name ) / sizeof ( driver_name[0] ); 4718ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov m++ ) 4719ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 4720ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for ( n = 0; n < library->num_modules; n++ ) 4721ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 4722ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Module module = library->modules[n]; 4723ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov const char* module_name = module->clazz->module_name; 4724ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_List faces; 4725ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4726ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4727ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( driver_name[m] && 4728ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ft_strcmp( module_name, driver_name[m] ) != 0 ) 4729ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov continue; 4730ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4731ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( ( module->clazz->module_flags & FT_MODULE_FONT_DRIVER ) == 0 ) 4732ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov continue; 4733ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4734ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_TRACE7(( "FT_Done_Library: close faces for %s\n", module_name )); 4735ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4736ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov faces = &FT_DRIVER( module )->faces_list; 4737ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov while ( faces->head ) 4738ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 4739ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Done_Face( FT_FACE( faces->head->data ) ); 4740ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( faces->head ) 4741ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_TRACE0(( "FT_Done_Library: failed to free some faces\n" )); 4742ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 4743ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 4744ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 4745ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 4746ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4747ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Close all other modules in the library */ 4748ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#if 1 4749ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* XXX Modules are removed in the reversed order so that */ 4750ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* type42 module is removed before truetype module. This */ 4751ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* avoids double free in some occasions. It is a hack. */ 4752ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov while ( library->num_modules > 0 ) 4753ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Remove_Module( library, 4754ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov library->modules[library->num_modules - 1] ); 4755ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#else 4756ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 4757ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt n; 4758ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4759ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4760ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for ( n = 0; n < library->num_modules; n++ ) 4761ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 4762ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Module module = library->modules[n]; 4763ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4764ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4765ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( module ) 4766ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 4767ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Destroy_Module( module ); 4768ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov library->modules[n] = 0; 4769ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 4770ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 4771ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 4772ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif 4773ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4774ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Destroy raster objects */ 4775ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FREE( library->raster_pool ); 4776ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov library->raster_pool_size = 0; 4777ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4778ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#ifdef FT_CONFIG_OPTION_PIC 4779ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Destroy pic container contents */ 4780ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ft_pic_container_destroy( library ); 4781ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif 4782ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4783ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FREE( library ); 4784ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4785ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Exit: 4786ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FT_Err_Ok; 4787ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 4788ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4789ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4790ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* documentation is in ftmodapi.h */ 4791ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4792ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_EXPORT_DEF( void ) 4793ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Set_Debug_Hook( FT_Library library, 4794ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt hook_index, 4795ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_DebugHook_Func debug_hook ) 4796ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 4797ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( library && debug_hook && 4798ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov hook_index < 4799ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ( sizeof ( library->debug_hooks ) / sizeof ( void* ) ) ) 4800ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov library->debug_hooks[hook_index] = debug_hook; 4801ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 4802ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4803ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4804ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* documentation is in ftmodapi.h */ 4805ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4806ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_EXPORT_DEF( FT_TrueTypeEngineType ) 4807ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Get_TrueType_Engine_Type( FT_Library library ) 4808ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 4809ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_TrueTypeEngineType result = FT_TRUETYPE_ENGINE_TYPE_NONE; 4810ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4811ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4812ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( library ) 4813ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 4814ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Module module = FT_Get_Module( library, "truetype" ); 4815ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4816ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4817ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( module ) 4818ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 4819ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Service_TrueTypeEngine service; 4820ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4821ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4822ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov service = (FT_Service_TrueTypeEngine) 4823ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ft_module_get_service( module, 4824ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_SERVICE_ID_TRUETYPE_ENGINE ); 4825ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( service ) 4826ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov result = service->engine_type; 4827ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 4828ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 4829ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4830ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return result; 4831ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 4832ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4833ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4834ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* documentation is in freetype.h */ 4835ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4836ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_EXPORT_DEF( FT_Error ) 4837ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Get_SubGlyph_Info( FT_GlyphSlot glyph, 4838ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt sub_index, 4839ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Int *p_index, 4840ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt *p_flags, 4841ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Int *p_arg1, 4842ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Int *p_arg2, 4843ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Matrix *p_transform ) 4844ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 4845ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Error error = FT_ERR( Invalid_Argument ); 4846ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4847ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4848ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( glyph && 4849ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov glyph->subglyphs && 4850ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov glyph->format == FT_GLYPH_FORMAT_COMPOSITE && 4851ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov sub_index < glyph->num_subglyphs ) 4852ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 4853ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_SubGlyph subg = glyph->subglyphs + sub_index; 4854ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4855ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4856ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *p_index = subg->index; 4857ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *p_flags = subg->flags; 4858ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *p_arg1 = subg->arg1; 4859ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *p_arg2 = subg->arg2; 4860ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *p_transform = subg->transform; 4861ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 4862ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4863ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return error; 4864ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 4865ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4866ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4867ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* END */ 4868