1*37da2899SCharles.Forsyth /***************************************************************************/ 2*37da2899SCharles.Forsyth /* */ 3*37da2899SCharles.Forsyth /* ftobjs.c */ 4*37da2899SCharles.Forsyth /* */ 5*37da2899SCharles.Forsyth /* The FreeType private base classes (body). */ 6*37da2899SCharles.Forsyth /* */ 7*37da2899SCharles.Forsyth /* Copyright 1996-2001, 2002 by */ 8*37da2899SCharles.Forsyth /* David Turner, Robert Wilhelm, and Werner Lemberg. */ 9*37da2899SCharles.Forsyth /* */ 10*37da2899SCharles.Forsyth /* This file is part of the FreeType project, and may only be used, */ 11*37da2899SCharles.Forsyth /* modified, and distributed under the terms of the FreeType project */ 12*37da2899SCharles.Forsyth /* license, LICENSE.TXT. By continuing to use, modify, or distribute */ 13*37da2899SCharles.Forsyth /* this file you indicate that you have read the license and */ 14*37da2899SCharles.Forsyth /* understand and accept it fully. */ 15*37da2899SCharles.Forsyth /* */ 16*37da2899SCharles.Forsyth /***************************************************************************/ 17*37da2899SCharles.Forsyth 18*37da2899SCharles.Forsyth 19*37da2899SCharles.Forsyth #include <ft2build.h> 20*37da2899SCharles.Forsyth #include FT_LIST_H 21*37da2899SCharles.Forsyth #include FT_OUTLINE_H 22*37da2899SCharles.Forsyth #include FT_INTERNAL_OBJECTS_H 23*37da2899SCharles.Forsyth #include FT_INTERNAL_DEBUG_H 24*37da2899SCharles.Forsyth #include FT_INTERNAL_STREAM_H 25*37da2899SCharles.Forsyth #include FT_TRUETYPE_TABLES_H 26*37da2899SCharles.Forsyth #include FT_OUTLINE_H 27*37da2899SCharles.Forsyth 28*37da2899SCharles.Forsyth 29*37da2899SCharles.Forsyth FT_BASE_DEF( void ) ft_validator_init(FT_Validator valid,const FT_Byte * base,const FT_Byte * limit,FT_ValidationLevel level)30*37da2899SCharles.Forsyth ft_validator_init( FT_Validator valid, 31*37da2899SCharles.Forsyth const FT_Byte* base, 32*37da2899SCharles.Forsyth const FT_Byte* limit, 33*37da2899SCharles.Forsyth FT_ValidationLevel level ) 34*37da2899SCharles.Forsyth { 35*37da2899SCharles.Forsyth valid->base = base; 36*37da2899SCharles.Forsyth valid->limit = limit; 37*37da2899SCharles.Forsyth valid->level = level; 38*37da2899SCharles.Forsyth valid->error = 0; 39*37da2899SCharles.Forsyth } 40*37da2899SCharles.Forsyth 41*37da2899SCharles.Forsyth 42*37da2899SCharles.Forsyth FT_BASE_DEF( FT_Int ) ft_validator_run(FT_Validator valid)43*37da2899SCharles.Forsyth ft_validator_run( FT_Validator valid ) 44*37da2899SCharles.Forsyth { 45*37da2899SCharles.Forsyth int result; 46*37da2899SCharles.Forsyth 47*37da2899SCharles.Forsyth 48*37da2899SCharles.Forsyth result = ft_setjmp( valid->jump_buffer ); 49*37da2899SCharles.Forsyth return result; 50*37da2899SCharles.Forsyth } 51*37da2899SCharles.Forsyth 52*37da2899SCharles.Forsyth 53*37da2899SCharles.Forsyth FT_BASE_DEF( void ) ft_validator_error(FT_Validator valid,FT_Error error)54*37da2899SCharles.Forsyth ft_validator_error( FT_Validator valid, 55*37da2899SCharles.Forsyth FT_Error error ) 56*37da2899SCharles.Forsyth { 57*37da2899SCharles.Forsyth valid->error = error; 58*37da2899SCharles.Forsyth ft_longjmp( valid->jump_buffer, 1 ); 59*37da2899SCharles.Forsyth } 60*37da2899SCharles.Forsyth 61*37da2899SCharles.Forsyth 62*37da2899SCharles.Forsyth /*************************************************************************/ 63*37da2899SCharles.Forsyth /*************************************************************************/ 64*37da2899SCharles.Forsyth /*************************************************************************/ 65*37da2899SCharles.Forsyth /**** ****/ 66*37da2899SCharles.Forsyth /**** ****/ 67*37da2899SCharles.Forsyth /**** S T R E A M ****/ 68*37da2899SCharles.Forsyth /**** ****/ 69*37da2899SCharles.Forsyth /**** ****/ 70*37da2899SCharles.Forsyth /*************************************************************************/ 71*37da2899SCharles.Forsyth /*************************************************************************/ 72*37da2899SCharles.Forsyth /*************************************************************************/ 73*37da2899SCharles.Forsyth 74*37da2899SCharles.Forsyth 75*37da2899SCharles.Forsyth /* create a new input stream from a FT_Open_Args structure */ 76*37da2899SCharles.Forsyth /* */ 77*37da2899SCharles.Forsyth static FT_Error ft_input_stream_new(FT_Library library,const FT_Open_Args * args,FT_Stream * astream)78*37da2899SCharles.Forsyth ft_input_stream_new( FT_Library library, 79*37da2899SCharles.Forsyth const FT_Open_Args* args, 80*37da2899SCharles.Forsyth FT_Stream* astream ) 81*37da2899SCharles.Forsyth { 82*37da2899SCharles.Forsyth FT_Error error; 83*37da2899SCharles.Forsyth FT_Memory memory; 84*37da2899SCharles.Forsyth FT_Stream stream; 85*37da2899SCharles.Forsyth 86*37da2899SCharles.Forsyth 87*37da2899SCharles.Forsyth if ( !library ) 88*37da2899SCharles.Forsyth return FT_Err_Invalid_Library_Handle; 89*37da2899SCharles.Forsyth 90*37da2899SCharles.Forsyth if ( !args ) 91*37da2899SCharles.Forsyth return FT_Err_Invalid_Argument; 92*37da2899SCharles.Forsyth 93*37da2899SCharles.Forsyth *astream = 0; 94*37da2899SCharles.Forsyth memory = library->memory; 95*37da2899SCharles.Forsyth 96*37da2899SCharles.Forsyth if ( FT_NEW( stream ) ) 97*37da2899SCharles.Forsyth goto Exit; 98*37da2899SCharles.Forsyth 99*37da2899SCharles.Forsyth stream->memory = memory; 100*37da2899SCharles.Forsyth 101*37da2899SCharles.Forsyth if ( args->flags & FT_OPEN_MEMORY ) 102*37da2899SCharles.Forsyth { 103*37da2899SCharles.Forsyth /* create a memory-based stream */ 104*37da2899SCharles.Forsyth FT_Stream_OpenMemory( stream, 105*37da2899SCharles.Forsyth (const FT_Byte*)args->memory_base, 106*37da2899SCharles.Forsyth args->memory_size ); 107*37da2899SCharles.Forsyth } 108*37da2899SCharles.Forsyth else if ( args->flags & FT_OPEN_PATHNAME ) 109*37da2899SCharles.Forsyth { 110*37da2899SCharles.Forsyth /* create a normal system stream */ 111*37da2899SCharles.Forsyth error = FT_Stream_Open( stream, args->pathname ); 112*37da2899SCharles.Forsyth stream->pathname.pointer = args->pathname; 113*37da2899SCharles.Forsyth } 114*37da2899SCharles.Forsyth else if ( ( args->flags & FT_OPEN_STREAM ) && args->stream ) 115*37da2899SCharles.Forsyth { 116*37da2899SCharles.Forsyth /* use an existing, user-provided stream */ 117*37da2899SCharles.Forsyth 118*37da2899SCharles.Forsyth /* in this case, we do not need to allocate a new stream object */ 119*37da2899SCharles.Forsyth /* since the caller is responsible for closing it himself */ 120*37da2899SCharles.Forsyth FT_FREE( stream ); 121*37da2899SCharles.Forsyth stream = args->stream; 122*37da2899SCharles.Forsyth } 123*37da2899SCharles.Forsyth else 124*37da2899SCharles.Forsyth error = FT_Err_Invalid_Argument; 125*37da2899SCharles.Forsyth 126*37da2899SCharles.Forsyth if ( error ) 127*37da2899SCharles.Forsyth FT_FREE( stream ); 128*37da2899SCharles.Forsyth else 129*37da2899SCharles.Forsyth stream->memory = memory; /* just to be certain */ 130*37da2899SCharles.Forsyth 131*37da2899SCharles.Forsyth *astream = stream; 132*37da2899SCharles.Forsyth 133*37da2899SCharles.Forsyth Exit: 134*37da2899SCharles.Forsyth return error; 135*37da2899SCharles.Forsyth } 136*37da2899SCharles.Forsyth 137*37da2899SCharles.Forsyth 138*37da2899SCharles.Forsyth static void ft_input_stream_free(FT_Stream stream,FT_Int external)139*37da2899SCharles.Forsyth ft_input_stream_free( FT_Stream stream, 140*37da2899SCharles.Forsyth FT_Int external ) 141*37da2899SCharles.Forsyth { 142*37da2899SCharles.Forsyth if ( stream ) 143*37da2899SCharles.Forsyth { 144*37da2899SCharles.Forsyth FT_Memory memory = stream->memory; 145*37da2899SCharles.Forsyth 146*37da2899SCharles.Forsyth 147*37da2899SCharles.Forsyth FT_Stream_Close( stream ); 148*37da2899SCharles.Forsyth 149*37da2899SCharles.Forsyth if ( !external ) 150*37da2899SCharles.Forsyth FT_FREE( stream ); 151*37da2899SCharles.Forsyth } 152*37da2899SCharles.Forsyth } 153*37da2899SCharles.Forsyth 154*37da2899SCharles.Forsyth 155*37da2899SCharles.Forsyth #undef FT_COMPONENT 156*37da2899SCharles.Forsyth #define FT_COMPONENT trace_objs 157*37da2899SCharles.Forsyth 158*37da2899SCharles.Forsyth 159*37da2899SCharles.Forsyth /*************************************************************************/ 160*37da2899SCharles.Forsyth /*************************************************************************/ 161*37da2899SCharles.Forsyth /*************************************************************************/ 162*37da2899SCharles.Forsyth /**** ****/ 163*37da2899SCharles.Forsyth /**** ****/ 164*37da2899SCharles.Forsyth /**** FACE, SIZE & GLYPH SLOT OBJECTS ****/ 165*37da2899SCharles.Forsyth /**** ****/ 166*37da2899SCharles.Forsyth /**** ****/ 167*37da2899SCharles.Forsyth /*************************************************************************/ 168*37da2899SCharles.Forsyth /*************************************************************************/ 169*37da2899SCharles.Forsyth /*************************************************************************/ 170*37da2899SCharles.Forsyth 171*37da2899SCharles.Forsyth 172*37da2899SCharles.Forsyth static FT_Error ft_glyphslot_init(FT_GlyphSlot slot)173*37da2899SCharles.Forsyth ft_glyphslot_init( FT_GlyphSlot slot ) 174*37da2899SCharles.Forsyth { 175*37da2899SCharles.Forsyth FT_Driver driver = slot->face->driver; 176*37da2899SCharles.Forsyth FT_Driver_Class clazz = driver->clazz; 177*37da2899SCharles.Forsyth FT_Memory memory = driver->root.memory; 178*37da2899SCharles.Forsyth FT_Error error = FT_Err_Ok; 179*37da2899SCharles.Forsyth FT_Slot_Internal internal; 180*37da2899SCharles.Forsyth 181*37da2899SCharles.Forsyth 182*37da2899SCharles.Forsyth slot->library = driver->root.library; 183*37da2899SCharles.Forsyth 184*37da2899SCharles.Forsyth if ( FT_NEW( internal ) ) 185*37da2899SCharles.Forsyth goto Exit; 186*37da2899SCharles.Forsyth 187*37da2899SCharles.Forsyth slot->internal = internal; 188*37da2899SCharles.Forsyth 189*37da2899SCharles.Forsyth if ( FT_DRIVER_USES_OUTLINES( driver ) ) 190*37da2899SCharles.Forsyth error = FT_GlyphLoader_New( memory, &internal->loader ); 191*37da2899SCharles.Forsyth 192*37da2899SCharles.Forsyth if ( !error && clazz->init_slot ) 193*37da2899SCharles.Forsyth error = clazz->init_slot( slot ); 194*37da2899SCharles.Forsyth 195*37da2899SCharles.Forsyth Exit: 196*37da2899SCharles.Forsyth return error; 197*37da2899SCharles.Forsyth } 198*37da2899SCharles.Forsyth 199*37da2899SCharles.Forsyth 200*37da2899SCharles.Forsyth static void ft_glyphslot_clear(FT_GlyphSlot slot)201*37da2899SCharles.Forsyth ft_glyphslot_clear( FT_GlyphSlot slot ) 202*37da2899SCharles.Forsyth { 203*37da2899SCharles.Forsyth /* free bitmap if needed */ 204*37da2899SCharles.Forsyth if ( slot->flags & FT_GLYPH_OWN_BITMAP ) 205*37da2899SCharles.Forsyth { 206*37da2899SCharles.Forsyth FT_Memory memory = FT_FACE_MEMORY( slot->face ); 207*37da2899SCharles.Forsyth 208*37da2899SCharles.Forsyth 209*37da2899SCharles.Forsyth FT_FREE( slot->bitmap.buffer ); 210*37da2899SCharles.Forsyth slot->flags &= ~FT_GLYPH_OWN_BITMAP; 211*37da2899SCharles.Forsyth } 212*37da2899SCharles.Forsyth 213*37da2899SCharles.Forsyth /* clear all public fields in the glyph slot */ 214*37da2899SCharles.Forsyth FT_ZERO( &slot->metrics ); 215*37da2899SCharles.Forsyth FT_ZERO( &slot->outline ); 216*37da2899SCharles.Forsyth 217*37da2899SCharles.Forsyth slot->bitmap.width = 0; 218*37da2899SCharles.Forsyth slot->bitmap.rows = 0; 219*37da2899SCharles.Forsyth slot->bitmap.pitch = 0; 220*37da2899SCharles.Forsyth slot->bitmap.pixel_mode = 0; 221*37da2899SCharles.Forsyth /* don't touch 'slot->bitmap.buffer' !! */ 222*37da2899SCharles.Forsyth 223*37da2899SCharles.Forsyth slot->bitmap_left = 0; 224*37da2899SCharles.Forsyth slot->bitmap_top = 0; 225*37da2899SCharles.Forsyth slot->num_subglyphs = 0; 226*37da2899SCharles.Forsyth slot->subglyphs = 0; 227*37da2899SCharles.Forsyth slot->control_data = 0; 228*37da2899SCharles.Forsyth slot->control_len = 0; 229*37da2899SCharles.Forsyth slot->other = 0; 230*37da2899SCharles.Forsyth slot->format = FT_GLYPH_FORMAT_NONE; 231*37da2899SCharles.Forsyth 232*37da2899SCharles.Forsyth slot->linearHoriAdvance = 0; 233*37da2899SCharles.Forsyth slot->linearVertAdvance = 0; 234*37da2899SCharles.Forsyth } 235*37da2899SCharles.Forsyth 236*37da2899SCharles.Forsyth 237*37da2899SCharles.Forsyth static void ft_glyphslot_done(FT_GlyphSlot slot)238*37da2899SCharles.Forsyth ft_glyphslot_done( FT_GlyphSlot slot ) 239*37da2899SCharles.Forsyth { 240*37da2899SCharles.Forsyth FT_Driver driver = slot->face->driver; 241*37da2899SCharles.Forsyth FT_Driver_Class clazz = driver->clazz; 242*37da2899SCharles.Forsyth FT_Memory memory = driver->root.memory; 243*37da2899SCharles.Forsyth 244*37da2899SCharles.Forsyth 245*37da2899SCharles.Forsyth if ( clazz->done_slot ) 246*37da2899SCharles.Forsyth clazz->done_slot( slot ); 247*37da2899SCharles.Forsyth 248*37da2899SCharles.Forsyth /* free bitmap buffer if needed */ 249*37da2899SCharles.Forsyth if ( slot->flags & FT_GLYPH_OWN_BITMAP ) 250*37da2899SCharles.Forsyth FT_FREE( slot->bitmap.buffer ); 251*37da2899SCharles.Forsyth 252*37da2899SCharles.Forsyth /* free glyph loader */ 253*37da2899SCharles.Forsyth if ( FT_DRIVER_USES_OUTLINES( driver ) ) 254*37da2899SCharles.Forsyth { 255*37da2899SCharles.Forsyth FT_GlyphLoader_Done( slot->internal->loader ); 256*37da2899SCharles.Forsyth slot->internal->loader = 0; 257*37da2899SCharles.Forsyth } 258*37da2899SCharles.Forsyth 259*37da2899SCharles.Forsyth FT_FREE( slot->internal ); 260*37da2899SCharles.Forsyth } 261*37da2899SCharles.Forsyth 262*37da2899SCharles.Forsyth 263*37da2899SCharles.Forsyth /* documentation is in ftobjs.h */ 264*37da2899SCharles.Forsyth 265*37da2899SCharles.Forsyth FT_BASE_DEF( FT_Error ) FT_New_GlyphSlot(FT_Face face,FT_GlyphSlot * aslot)266*37da2899SCharles.Forsyth FT_New_GlyphSlot( FT_Face face, 267*37da2899SCharles.Forsyth FT_GlyphSlot *aslot ) 268*37da2899SCharles.Forsyth { 269*37da2899SCharles.Forsyth FT_Error error; 270*37da2899SCharles.Forsyth FT_Driver driver; 271*37da2899SCharles.Forsyth FT_Driver_Class clazz; 272*37da2899SCharles.Forsyth FT_Memory memory; 273*37da2899SCharles.Forsyth FT_GlyphSlot slot; 274*37da2899SCharles.Forsyth 275*37da2899SCharles.Forsyth 276*37da2899SCharles.Forsyth if ( !face || !aslot || !face->driver ) 277*37da2899SCharles.Forsyth return FT_Err_Invalid_Argument; 278*37da2899SCharles.Forsyth 279*37da2899SCharles.Forsyth *aslot = 0; 280*37da2899SCharles.Forsyth 281*37da2899SCharles.Forsyth driver = face->driver; 282*37da2899SCharles.Forsyth clazz = driver->clazz; 283*37da2899SCharles.Forsyth memory = driver->root.memory; 284*37da2899SCharles.Forsyth 285*37da2899SCharles.Forsyth FT_TRACE4(( "FT_New_GlyphSlot: Creating new slot object\n" )); 286*37da2899SCharles.Forsyth if ( !FT_ALLOC( slot, clazz->slot_object_size ) ) 287*37da2899SCharles.Forsyth { 288*37da2899SCharles.Forsyth slot->face = face; 289*37da2899SCharles.Forsyth 290*37da2899SCharles.Forsyth error = ft_glyphslot_init( slot ); 291*37da2899SCharles.Forsyth if ( error ) 292*37da2899SCharles.Forsyth { 293*37da2899SCharles.Forsyth ft_glyphslot_done( slot ); 294*37da2899SCharles.Forsyth FT_FREE( slot ); 295*37da2899SCharles.Forsyth goto Exit; 296*37da2899SCharles.Forsyth } 297*37da2899SCharles.Forsyth 298*37da2899SCharles.Forsyth *aslot = slot; 299*37da2899SCharles.Forsyth } 300*37da2899SCharles.Forsyth 301*37da2899SCharles.Forsyth Exit: 302*37da2899SCharles.Forsyth FT_TRACE4(( "FT_New_GlyphSlot: Return %d\n", error )); 303*37da2899SCharles.Forsyth return error; 304*37da2899SCharles.Forsyth } 305*37da2899SCharles.Forsyth 306*37da2899SCharles.Forsyth 307*37da2899SCharles.Forsyth /* documentation is in ftobjs.h */ 308*37da2899SCharles.Forsyth 309*37da2899SCharles.Forsyth FT_BASE_DEF( void ) FT_Done_GlyphSlot(FT_GlyphSlot slot)310*37da2899SCharles.Forsyth FT_Done_GlyphSlot( FT_GlyphSlot slot ) 311*37da2899SCharles.Forsyth { 312*37da2899SCharles.Forsyth if ( slot ) 313*37da2899SCharles.Forsyth { 314*37da2899SCharles.Forsyth FT_Driver driver = slot->face->driver; 315*37da2899SCharles.Forsyth FT_Memory memory = driver->root.memory; 316*37da2899SCharles.Forsyth FT_GlyphSlot* parent; 317*37da2899SCharles.Forsyth FT_GlyphSlot cur; 318*37da2899SCharles.Forsyth 319*37da2899SCharles.Forsyth 320*37da2899SCharles.Forsyth /* Remove slot from its parent face's list */ 321*37da2899SCharles.Forsyth parent = &slot->face->glyph; 322*37da2899SCharles.Forsyth cur = *parent; 323*37da2899SCharles.Forsyth 324*37da2899SCharles.Forsyth while ( cur ) 325*37da2899SCharles.Forsyth { 326*37da2899SCharles.Forsyth if ( cur == slot ) 327*37da2899SCharles.Forsyth { 328*37da2899SCharles.Forsyth *parent = cur->next; 329*37da2899SCharles.Forsyth ft_glyphslot_done( slot ); 330*37da2899SCharles.Forsyth FT_FREE( slot ); 331*37da2899SCharles.Forsyth break; 332*37da2899SCharles.Forsyth } 333*37da2899SCharles.Forsyth cur = cur->next; 334*37da2899SCharles.Forsyth } 335*37da2899SCharles.Forsyth } 336*37da2899SCharles.Forsyth } 337*37da2899SCharles.Forsyth 338*37da2899SCharles.Forsyth 339*37da2899SCharles.Forsyth /* documentation is in freetype.h */ 340*37da2899SCharles.Forsyth 341*37da2899SCharles.Forsyth FT_EXPORT_DEF( void ) FT_Set_Transform(FT_Face face,FT_Matrix * matrix,FT_Vector * delta)342*37da2899SCharles.Forsyth FT_Set_Transform( FT_Face face, 343*37da2899SCharles.Forsyth FT_Matrix* matrix, 344*37da2899SCharles.Forsyth FT_Vector* delta ) 345*37da2899SCharles.Forsyth { 346*37da2899SCharles.Forsyth FT_Face_Internal internal; 347*37da2899SCharles.Forsyth 348*37da2899SCharles.Forsyth 349*37da2899SCharles.Forsyth if ( !face ) 350*37da2899SCharles.Forsyth return; 351*37da2899SCharles.Forsyth 352*37da2899SCharles.Forsyth internal = face->internal; 353*37da2899SCharles.Forsyth 354*37da2899SCharles.Forsyth internal->transform_flags = 0; 355*37da2899SCharles.Forsyth 356*37da2899SCharles.Forsyth if ( !matrix ) 357*37da2899SCharles.Forsyth { 358*37da2899SCharles.Forsyth internal->transform_matrix.xx = 0x10000L; 359*37da2899SCharles.Forsyth internal->transform_matrix.xy = 0; 360*37da2899SCharles.Forsyth internal->transform_matrix.yx = 0; 361*37da2899SCharles.Forsyth internal->transform_matrix.yy = 0x10000L; 362*37da2899SCharles.Forsyth matrix = &internal->transform_matrix; 363*37da2899SCharles.Forsyth } 364*37da2899SCharles.Forsyth else 365*37da2899SCharles.Forsyth internal->transform_matrix = *matrix; 366*37da2899SCharles.Forsyth 367*37da2899SCharles.Forsyth /* set transform_flags bit flag 0 if `matrix' isn't the identity */ 368*37da2899SCharles.Forsyth if ( ( matrix->xy | matrix->yx ) || 369*37da2899SCharles.Forsyth matrix->xx != 0x10000L || 370*37da2899SCharles.Forsyth matrix->yy != 0x10000L ) 371*37da2899SCharles.Forsyth internal->transform_flags |= 1; 372*37da2899SCharles.Forsyth 373*37da2899SCharles.Forsyth if ( !delta ) 374*37da2899SCharles.Forsyth { 375*37da2899SCharles.Forsyth internal->transform_delta.x = 0; 376*37da2899SCharles.Forsyth internal->transform_delta.y = 0; 377*37da2899SCharles.Forsyth delta = &internal->transform_delta; 378*37da2899SCharles.Forsyth } 379*37da2899SCharles.Forsyth else 380*37da2899SCharles.Forsyth internal->transform_delta = *delta; 381*37da2899SCharles.Forsyth 382*37da2899SCharles.Forsyth /* set transform_flags bit flag 1 if `delta' isn't the null vector */ 383*37da2899SCharles.Forsyth if ( delta->x | delta->y ) 384*37da2899SCharles.Forsyth internal->transform_flags |= 2; 385*37da2899SCharles.Forsyth } 386*37da2899SCharles.Forsyth 387*37da2899SCharles.Forsyth 388*37da2899SCharles.Forsyth /* documentation is in freetype.h */ 389*37da2899SCharles.Forsyth 390*37da2899SCharles.Forsyth FT_EXPORT_DEF( void ) FT_Set_Hint_Flags(FT_Face face,FT_ULong flags)391*37da2899SCharles.Forsyth FT_Set_Hint_Flags( FT_Face face, 392*37da2899SCharles.Forsyth FT_ULong flags ) 393*37da2899SCharles.Forsyth { 394*37da2899SCharles.Forsyth FT_Face_Internal internal; 395*37da2899SCharles.Forsyth 396*37da2899SCharles.Forsyth if ( !face ) 397*37da2899SCharles.Forsyth return; 398*37da2899SCharles.Forsyth 399*37da2899SCharles.Forsyth internal = face->internal; 400*37da2899SCharles.Forsyth 401*37da2899SCharles.Forsyth internal->hint_flags = (FT_UInt)flags; 402*37da2899SCharles.Forsyth } 403*37da2899SCharles.Forsyth 404*37da2899SCharles.Forsyth 405*37da2899SCharles.Forsyth static FT_Renderer 406*37da2899SCharles.Forsyth ft_lookup_glyph_renderer( FT_GlyphSlot slot ); 407*37da2899SCharles.Forsyth 408*37da2899SCharles.Forsyth 409*37da2899SCharles.Forsyth /* documentation is in freetype.h */ 410*37da2899SCharles.Forsyth 411*37da2899SCharles.Forsyth FT_EXPORT_DEF( FT_Error ) FT_Load_Glyph(FT_Face face,FT_UInt glyph_index,FT_Int32 load_flags)412*37da2899SCharles.Forsyth FT_Load_Glyph( FT_Face face, 413*37da2899SCharles.Forsyth FT_UInt glyph_index, 414*37da2899SCharles.Forsyth FT_Int32 load_flags ) 415*37da2899SCharles.Forsyth { 416*37da2899SCharles.Forsyth FT_Error error; 417*37da2899SCharles.Forsyth FT_Driver driver; 418*37da2899SCharles.Forsyth FT_GlyphSlot slot; 419*37da2899SCharles.Forsyth FT_Library library; 420*37da2899SCharles.Forsyth FT_Bool autohint; 421*37da2899SCharles.Forsyth FT_Module hinter; 422*37da2899SCharles.Forsyth 423*37da2899SCharles.Forsyth 424*37da2899SCharles.Forsyth if ( !face || !face->size || !face->glyph ) 425*37da2899SCharles.Forsyth return FT_Err_Invalid_Face_Handle; 426*37da2899SCharles.Forsyth 427*37da2899SCharles.Forsyth if ( glyph_index > (FT_UInt)face->num_glyphs ) 428*37da2899SCharles.Forsyth return FT_Err_Invalid_Argument; 429*37da2899SCharles.Forsyth 430*37da2899SCharles.Forsyth slot = face->glyph; 431*37da2899SCharles.Forsyth ft_glyphslot_clear( slot ); 432*37da2899SCharles.Forsyth 433*37da2899SCharles.Forsyth driver = face->driver; 434*37da2899SCharles.Forsyth 435*37da2899SCharles.Forsyth /* if the flag NO_RECURSE is set, we disable hinting and scaling */ 436*37da2899SCharles.Forsyth if ( load_flags & FT_LOAD_NO_RECURSE ) 437*37da2899SCharles.Forsyth { 438*37da2899SCharles.Forsyth /* disable scaling, hinting, and transformation */ 439*37da2899SCharles.Forsyth load_flags |= FT_LOAD_NO_SCALE | 440*37da2899SCharles.Forsyth FT_LOAD_NO_HINTING | 441*37da2899SCharles.Forsyth FT_LOAD_NO_BITMAP | 442*37da2899SCharles.Forsyth FT_LOAD_IGNORE_TRANSFORM; 443*37da2899SCharles.Forsyth 444*37da2899SCharles.Forsyth /* disable bitmap rendering */ 445*37da2899SCharles.Forsyth load_flags &= ~FT_LOAD_RENDER; 446*37da2899SCharles.Forsyth } 447*37da2899SCharles.Forsyth 448*37da2899SCharles.Forsyth /* do we need to load the glyph through the auto-hinter? */ 449*37da2899SCharles.Forsyth library = driver->root.library; 450*37da2899SCharles.Forsyth hinter = library->auto_hinter; 451*37da2899SCharles.Forsyth autohint = 452*37da2899SCharles.Forsyth FT_BOOL( hinter && 453*37da2899SCharles.Forsyth !( load_flags & ( FT_LOAD_NO_SCALE | 454*37da2899SCharles.Forsyth FT_LOAD_NO_HINTING | 455*37da2899SCharles.Forsyth FT_LOAD_NO_AUTOHINT ) ) && 456*37da2899SCharles.Forsyth FT_DRIVER_IS_SCALABLE( driver ) && 457*37da2899SCharles.Forsyth FT_DRIVER_USES_OUTLINES( driver ) ); 458*37da2899SCharles.Forsyth if ( autohint ) 459*37da2899SCharles.Forsyth { 460*37da2899SCharles.Forsyth if ( FT_DRIVER_HAS_HINTER( driver ) && 461*37da2899SCharles.Forsyth !( load_flags & FT_LOAD_FORCE_AUTOHINT ) ) 462*37da2899SCharles.Forsyth autohint = 0; 463*37da2899SCharles.Forsyth } 464*37da2899SCharles.Forsyth 465*37da2899SCharles.Forsyth if ( autohint ) 466*37da2899SCharles.Forsyth { 467*37da2899SCharles.Forsyth FT_AutoHinter_Service hinting; 468*37da2899SCharles.Forsyth 469*37da2899SCharles.Forsyth 470*37da2899SCharles.Forsyth /* try to load embedded bitmaps first if available */ 471*37da2899SCharles.Forsyth /* */ 472*37da2899SCharles.Forsyth /* XXX: This is really a temporary hack that should disappear */ 473*37da2899SCharles.Forsyth /* promptly with FreeType 2.1! */ 474*37da2899SCharles.Forsyth /* */ 475*37da2899SCharles.Forsyth if ( FT_HAS_FIXED_SIZES( face ) && 476*37da2899SCharles.Forsyth ( load_flags & FT_LOAD_NO_BITMAP ) == 0 ) 477*37da2899SCharles.Forsyth { 478*37da2899SCharles.Forsyth error = driver->clazz->load_glyph( slot, face->size, 479*37da2899SCharles.Forsyth glyph_index, 480*37da2899SCharles.Forsyth load_flags | FT_LOAD_SBITS_ONLY ); 481*37da2899SCharles.Forsyth 482*37da2899SCharles.Forsyth if ( !error && slot->format == FT_GLYPH_FORMAT_BITMAP ) 483*37da2899SCharles.Forsyth goto Load_Ok; 484*37da2899SCharles.Forsyth } 485*37da2899SCharles.Forsyth 486*37da2899SCharles.Forsyth /* load auto-hinted outline */ 487*37da2899SCharles.Forsyth hinting = (FT_AutoHinter_Service)hinter->clazz->module_interface; 488*37da2899SCharles.Forsyth 489*37da2899SCharles.Forsyth error = hinting->load_glyph( (FT_AutoHinter)hinter, 490*37da2899SCharles.Forsyth slot, face->size, 491*37da2899SCharles.Forsyth glyph_index, load_flags ); 492*37da2899SCharles.Forsyth } 493*37da2899SCharles.Forsyth else 494*37da2899SCharles.Forsyth { 495*37da2899SCharles.Forsyth error = driver->clazz->load_glyph( slot, 496*37da2899SCharles.Forsyth face->size, 497*37da2899SCharles.Forsyth glyph_index, 498*37da2899SCharles.Forsyth load_flags ); 499*37da2899SCharles.Forsyth if ( error ) 500*37da2899SCharles.Forsyth goto Exit; 501*37da2899SCharles.Forsyth 502*37da2899SCharles.Forsyth /* check that the loaded outline is correct */ 503*37da2899SCharles.Forsyth error = FT_Outline_Check( &slot->outline ); 504*37da2899SCharles.Forsyth if ( error ) 505*37da2899SCharles.Forsyth goto Exit; 506*37da2899SCharles.Forsyth } 507*37da2899SCharles.Forsyth 508*37da2899SCharles.Forsyth Load_Ok: 509*37da2899SCharles.Forsyth /* compute the advance */ 510*37da2899SCharles.Forsyth if ( load_flags & FT_LOAD_VERTICAL_LAYOUT ) 511*37da2899SCharles.Forsyth { 512*37da2899SCharles.Forsyth slot->advance.x = 0; 513*37da2899SCharles.Forsyth slot->advance.y = slot->metrics.vertAdvance; 514*37da2899SCharles.Forsyth } 515*37da2899SCharles.Forsyth else 516*37da2899SCharles.Forsyth { 517*37da2899SCharles.Forsyth slot->advance.x = slot->metrics.horiAdvance; 518*37da2899SCharles.Forsyth slot->advance.y = 0; 519*37da2899SCharles.Forsyth } 520*37da2899SCharles.Forsyth 521*37da2899SCharles.Forsyth /* compute the linear advance in 16.16 pixels */ 522*37da2899SCharles.Forsyth if ( ( load_flags & FT_LOAD_LINEAR_DESIGN ) == 0 ) 523*37da2899SCharles.Forsyth { 524*37da2899SCharles.Forsyth FT_UInt EM = face->units_per_EM; 525*37da2899SCharles.Forsyth FT_Size_Metrics* metrics = &face->size->metrics; 526*37da2899SCharles.Forsyth 527*37da2899SCharles.Forsyth 528*37da2899SCharles.Forsyth slot->linearHoriAdvance = FT_MulDiv( slot->linearHoriAdvance, 529*37da2899SCharles.Forsyth (FT_Long)metrics->x_ppem << 16, EM ); 530*37da2899SCharles.Forsyth 531*37da2899SCharles.Forsyth slot->linearVertAdvance = FT_MulDiv( slot->linearVertAdvance, 532*37da2899SCharles.Forsyth (FT_Long)metrics->y_ppem << 16, EM ); 533*37da2899SCharles.Forsyth } 534*37da2899SCharles.Forsyth 535*37da2899SCharles.Forsyth if ( ( load_flags & FT_LOAD_IGNORE_TRANSFORM ) == 0 ) 536*37da2899SCharles.Forsyth { 537*37da2899SCharles.Forsyth FT_Face_Internal internal = face->internal; 538*37da2899SCharles.Forsyth 539*37da2899SCharles.Forsyth 540*37da2899SCharles.Forsyth /* now, transform the glyph image if needed */ 541*37da2899SCharles.Forsyth if ( internal->transform_flags ) 542*37da2899SCharles.Forsyth { 543*37da2899SCharles.Forsyth /* get renderer */ 544*37da2899SCharles.Forsyth FT_Renderer renderer = ft_lookup_glyph_renderer( slot ); 545*37da2899SCharles.Forsyth 546*37da2899SCharles.Forsyth 547*37da2899SCharles.Forsyth if ( renderer ) 548*37da2899SCharles.Forsyth error = renderer->clazz->transform_glyph( 549*37da2899SCharles.Forsyth renderer, slot, 550*37da2899SCharles.Forsyth &internal->transform_matrix, 551*37da2899SCharles.Forsyth &internal->transform_delta ); 552*37da2899SCharles.Forsyth /* transform advance */ 553*37da2899SCharles.Forsyth FT_Vector_Transform( &slot->advance, &internal->transform_matrix ); 554*37da2899SCharles.Forsyth } 555*37da2899SCharles.Forsyth } 556*37da2899SCharles.Forsyth 557*37da2899SCharles.Forsyth /* do we need to render the image now? */ 558*37da2899SCharles.Forsyth if ( !error && 559*37da2899SCharles.Forsyth slot->format != FT_GLYPH_FORMAT_BITMAP && 560*37da2899SCharles.Forsyth slot->format != FT_GLYPH_FORMAT_COMPOSITE && 561*37da2899SCharles.Forsyth load_flags & FT_LOAD_RENDER ) 562*37da2899SCharles.Forsyth { 563*37da2899SCharles.Forsyth FT_Render_Mode mode = FT_LOAD_TARGET_MODE( load_flags ); 564*37da2899SCharles.Forsyth 565*37da2899SCharles.Forsyth 566*37da2899SCharles.Forsyth if ( mode == FT_RENDER_MODE_NORMAL && 567*37da2899SCharles.Forsyth (load_flags & FT_LOAD_MONOCHROME ) ) 568*37da2899SCharles.Forsyth mode = FT_RENDER_MODE_MONO; 569*37da2899SCharles.Forsyth 570*37da2899SCharles.Forsyth error = FT_Render_Glyph( slot, mode ); 571*37da2899SCharles.Forsyth } 572*37da2899SCharles.Forsyth 573*37da2899SCharles.Forsyth Exit: 574*37da2899SCharles.Forsyth return error; 575*37da2899SCharles.Forsyth } 576*37da2899SCharles.Forsyth 577*37da2899SCharles.Forsyth 578*37da2899SCharles.Forsyth /* documentation is in freetype.h */ 579*37da2899SCharles.Forsyth 580*37da2899SCharles.Forsyth FT_EXPORT_DEF( FT_Error ) FT_Load_Char(FT_Face face,FT_ULong char_code,FT_Int32 load_flags)581*37da2899SCharles.Forsyth FT_Load_Char( FT_Face face, 582*37da2899SCharles.Forsyth FT_ULong char_code, 583*37da2899SCharles.Forsyth FT_Int32 load_flags ) 584*37da2899SCharles.Forsyth { 585*37da2899SCharles.Forsyth FT_UInt glyph_index; 586*37da2899SCharles.Forsyth 587*37da2899SCharles.Forsyth 588*37da2899SCharles.Forsyth if ( !face ) 589*37da2899SCharles.Forsyth return FT_Err_Invalid_Face_Handle; 590*37da2899SCharles.Forsyth 591*37da2899SCharles.Forsyth glyph_index = (FT_UInt)char_code; 592*37da2899SCharles.Forsyth if ( face->charmap ) 593*37da2899SCharles.Forsyth glyph_index = FT_Get_Char_Index( face, char_code ); 594*37da2899SCharles.Forsyth 595*37da2899SCharles.Forsyth return FT_Load_Glyph( face, glyph_index, load_flags ); 596*37da2899SCharles.Forsyth } 597*37da2899SCharles.Forsyth 598*37da2899SCharles.Forsyth 599*37da2899SCharles.Forsyth /* destructor for sizes list */ 600*37da2899SCharles.Forsyth static void destroy_size(FT_Memory memory,FT_Size size,FT_Driver driver)601*37da2899SCharles.Forsyth destroy_size( FT_Memory memory, 602*37da2899SCharles.Forsyth FT_Size size, 603*37da2899SCharles.Forsyth FT_Driver driver ) 604*37da2899SCharles.Forsyth { 605*37da2899SCharles.Forsyth /* finalize client-specific data */ 606*37da2899SCharles.Forsyth if ( size->generic.finalizer ) 607*37da2899SCharles.Forsyth size->generic.finalizer( size ); 608*37da2899SCharles.Forsyth 609*37da2899SCharles.Forsyth /* finalize format-specific stuff */ 610*37da2899SCharles.Forsyth if ( driver->clazz->done_size ) 611*37da2899SCharles.Forsyth driver->clazz->done_size( size ); 612*37da2899SCharles.Forsyth 613*37da2899SCharles.Forsyth FT_FREE( size->internal ); 614*37da2899SCharles.Forsyth FT_FREE( size ); 615*37da2899SCharles.Forsyth } 616*37da2899SCharles.Forsyth 617*37da2899SCharles.Forsyth 618*37da2899SCharles.Forsyth /* destructor for faces list */ 619*37da2899SCharles.Forsyth static void destroy_face(FT_Memory memory,FT_Face face,FT_Driver driver)620*37da2899SCharles.Forsyth destroy_face( FT_Memory memory, 621*37da2899SCharles.Forsyth FT_Face face, 622*37da2899SCharles.Forsyth FT_Driver driver ) 623*37da2899SCharles.Forsyth { 624*37da2899SCharles.Forsyth FT_Driver_Class clazz = driver->clazz; 625*37da2899SCharles.Forsyth 626*37da2899SCharles.Forsyth 627*37da2899SCharles.Forsyth /* discard auto-hinting data */ 628*37da2899SCharles.Forsyth if ( face->autohint.finalizer ) 629*37da2899SCharles.Forsyth face->autohint.finalizer( face->autohint.data ); 630*37da2899SCharles.Forsyth 631*37da2899SCharles.Forsyth /* Discard glyph slots for this face. */ 632*37da2899SCharles.Forsyth /* Beware! FT_Done_GlyphSlot() changes the field `face->glyph' */ 633*37da2899SCharles.Forsyth while ( face->glyph ) 634*37da2899SCharles.Forsyth FT_Done_GlyphSlot( face->glyph ); 635*37da2899SCharles.Forsyth 636*37da2899SCharles.Forsyth /* discard all sizes for this face */ 637*37da2899SCharles.Forsyth FT_List_Finalize( &face->sizes_list, 638*37da2899SCharles.Forsyth (FT_List_Destructor)destroy_size, 639*37da2899SCharles.Forsyth memory, 640*37da2899SCharles.Forsyth driver ); 641*37da2899SCharles.Forsyth face->size = 0; 642*37da2899SCharles.Forsyth 643*37da2899SCharles.Forsyth /* now discard client data */ 644*37da2899SCharles.Forsyth if ( face->generic.finalizer ) 645*37da2899SCharles.Forsyth face->generic.finalizer( face ); 646*37da2899SCharles.Forsyth 647*37da2899SCharles.Forsyth /* discard charmaps */ 648*37da2899SCharles.Forsyth { 649*37da2899SCharles.Forsyth FT_Int n; 650*37da2899SCharles.Forsyth 651*37da2899SCharles.Forsyth 652*37da2899SCharles.Forsyth for ( n = 0; n < face->num_charmaps; n++ ) 653*37da2899SCharles.Forsyth { 654*37da2899SCharles.Forsyth FT_CMap cmap = FT_CMAP( face->charmaps[n] ); 655*37da2899SCharles.Forsyth 656*37da2899SCharles.Forsyth 657*37da2899SCharles.Forsyth FT_CMap_Done( cmap ); 658*37da2899SCharles.Forsyth 659*37da2899SCharles.Forsyth face->charmaps[n] = NULL; 660*37da2899SCharles.Forsyth } 661*37da2899SCharles.Forsyth 662*37da2899SCharles.Forsyth FT_FREE( face->charmaps ); 663*37da2899SCharles.Forsyth face->num_charmaps = 0; 664*37da2899SCharles.Forsyth } 665*37da2899SCharles.Forsyth 666*37da2899SCharles.Forsyth 667*37da2899SCharles.Forsyth /* finalize format-specific stuff */ 668*37da2899SCharles.Forsyth if ( clazz->done_face ) 669*37da2899SCharles.Forsyth clazz->done_face( face ); 670*37da2899SCharles.Forsyth 671*37da2899SCharles.Forsyth /* close the stream for this face if needed */ 672*37da2899SCharles.Forsyth ft_input_stream_free( 673*37da2899SCharles.Forsyth face->stream, 674*37da2899SCharles.Forsyth ( face->face_flags & FT_FACE_FLAG_EXTERNAL_STREAM ) != 0 ); 675*37da2899SCharles.Forsyth 676*37da2899SCharles.Forsyth face->stream = 0; 677*37da2899SCharles.Forsyth 678*37da2899SCharles.Forsyth /* get rid of it */ 679*37da2899SCharles.Forsyth if ( face->internal ) 680*37da2899SCharles.Forsyth { 681*37da2899SCharles.Forsyth FT_FREE( face->internal->postscript_name ); 682*37da2899SCharles.Forsyth FT_FREE( face->internal ); 683*37da2899SCharles.Forsyth } 684*37da2899SCharles.Forsyth FT_FREE( face ); 685*37da2899SCharles.Forsyth } 686*37da2899SCharles.Forsyth 687*37da2899SCharles.Forsyth 688*37da2899SCharles.Forsyth static void Destroy_Driver(FT_Driver driver)689*37da2899SCharles.Forsyth Destroy_Driver( FT_Driver driver ) 690*37da2899SCharles.Forsyth { 691*37da2899SCharles.Forsyth FT_List_Finalize( &driver->faces_list, 692*37da2899SCharles.Forsyth (FT_List_Destructor)destroy_face, 693*37da2899SCharles.Forsyth driver->root.memory, 694*37da2899SCharles.Forsyth driver ); 695*37da2899SCharles.Forsyth 696*37da2899SCharles.Forsyth /* check whether we need to drop the driver's glyph loader */ 697*37da2899SCharles.Forsyth if ( FT_DRIVER_USES_OUTLINES( driver ) ) 698*37da2899SCharles.Forsyth FT_GlyphLoader_Done( driver->glyph_loader ); 699*37da2899SCharles.Forsyth } 700*37da2899SCharles.Forsyth 701*37da2899SCharles.Forsyth 702*37da2899SCharles.Forsyth /*************************************************************************/ 703*37da2899SCharles.Forsyth /* */ 704*37da2899SCharles.Forsyth /* <Function> */ 705*37da2899SCharles.Forsyth /* open_face */ 706*37da2899SCharles.Forsyth /* */ 707*37da2899SCharles.Forsyth /* <Description> */ 708*37da2899SCharles.Forsyth /* This function does some work for FT_Open_Face(). */ 709*37da2899SCharles.Forsyth /* */ 710*37da2899SCharles.Forsyth static FT_Error open_face(FT_Driver driver,FT_Stream stream,FT_Long face_index,FT_Int num_params,FT_Parameter * params,FT_Face * aface)711*37da2899SCharles.Forsyth open_face( FT_Driver driver, 712*37da2899SCharles.Forsyth FT_Stream stream, 713*37da2899SCharles.Forsyth FT_Long face_index, 714*37da2899SCharles.Forsyth FT_Int num_params, 715*37da2899SCharles.Forsyth FT_Parameter* params, 716*37da2899SCharles.Forsyth FT_Face* aface ) 717*37da2899SCharles.Forsyth { 718*37da2899SCharles.Forsyth FT_Memory memory; 719*37da2899SCharles.Forsyth FT_Driver_Class clazz; 720*37da2899SCharles.Forsyth FT_Face face = 0; 721*37da2899SCharles.Forsyth FT_Error error; 722*37da2899SCharles.Forsyth FT_Face_Internal internal; 723*37da2899SCharles.Forsyth 724*37da2899SCharles.Forsyth 725*37da2899SCharles.Forsyth clazz = driver->clazz; 726*37da2899SCharles.Forsyth memory = driver->root.memory; 727*37da2899SCharles.Forsyth 728*37da2899SCharles.Forsyth /* allocate the face object and perform basic initialization */ 729*37da2899SCharles.Forsyth if ( FT_ALLOC( face, clazz->face_object_size ) ) 730*37da2899SCharles.Forsyth goto Fail; 731*37da2899SCharles.Forsyth 732*37da2899SCharles.Forsyth if ( FT_NEW( internal ) ) 733*37da2899SCharles.Forsyth goto Fail; 734*37da2899SCharles.Forsyth 735*37da2899SCharles.Forsyth face->internal = internal; 736*37da2899SCharles.Forsyth 737*37da2899SCharles.Forsyth face->driver = driver; 738*37da2899SCharles.Forsyth face->memory = memory; 739*37da2899SCharles.Forsyth face->stream = stream; 740*37da2899SCharles.Forsyth 741*37da2899SCharles.Forsyth #ifdef FT_CONFIG_OPTION_INCREMENTAL 742*37da2899SCharles.Forsyth { 743*37da2899SCharles.Forsyth int i; 744*37da2899SCharles.Forsyth 745*37da2899SCharles.Forsyth 746*37da2899SCharles.Forsyth face->internal->incremental_interface = 0; 747*37da2899SCharles.Forsyth for ( i = 0; i < num_params && !face->internal->incremental_interface; 748*37da2899SCharles.Forsyth i++ ) 749*37da2899SCharles.Forsyth if ( params[i].tag == FT_PARAM_TAG_INCREMENTAL ) 750*37da2899SCharles.Forsyth face->internal->incremental_interface = params[i].data; 751*37da2899SCharles.Forsyth } 752*37da2899SCharles.Forsyth #endif 753*37da2899SCharles.Forsyth 754*37da2899SCharles.Forsyth error = clazz->init_face( stream, 755*37da2899SCharles.Forsyth face, 756*37da2899SCharles.Forsyth (FT_Int)face_index, 757*37da2899SCharles.Forsyth num_params, 758*37da2899SCharles.Forsyth params ); 759*37da2899SCharles.Forsyth if ( error ) 760*37da2899SCharles.Forsyth goto Fail; 761*37da2899SCharles.Forsyth 762*37da2899SCharles.Forsyth /* select Unicode charmap by default */ 763*37da2899SCharles.Forsyth { 764*37da2899SCharles.Forsyth FT_Int nn; 765*37da2899SCharles.Forsyth FT_CharMap unicmap = NULL, cmap; 766*37da2899SCharles.Forsyth 767*37da2899SCharles.Forsyth 768*37da2899SCharles.Forsyth for ( nn = 0; nn < face->num_charmaps; nn++ ) 769*37da2899SCharles.Forsyth { 770*37da2899SCharles.Forsyth cmap = face->charmaps[nn]; 771*37da2899SCharles.Forsyth 772*37da2899SCharles.Forsyth if ( cmap->encoding == FT_ENCODING_UNICODE ) 773*37da2899SCharles.Forsyth { 774*37da2899SCharles.Forsyth unicmap = cmap; 775*37da2899SCharles.Forsyth break; 776*37da2899SCharles.Forsyth } 777*37da2899SCharles.Forsyth } 778*37da2899SCharles.Forsyth 779*37da2899SCharles.Forsyth if ( unicmap != NULL ) 780*37da2899SCharles.Forsyth face->charmap = unicmap; 781*37da2899SCharles.Forsyth } 782*37da2899SCharles.Forsyth 783*37da2899SCharles.Forsyth *aface = face; 784*37da2899SCharles.Forsyth 785*37da2899SCharles.Forsyth Fail: 786*37da2899SCharles.Forsyth if ( error ) 787*37da2899SCharles.Forsyth { 788*37da2899SCharles.Forsyth clazz->done_face( face ); 789*37da2899SCharles.Forsyth FT_FREE( face->internal ); 790*37da2899SCharles.Forsyth FT_FREE( face ); 791*37da2899SCharles.Forsyth *aface = 0; 792*37da2899SCharles.Forsyth } 793*37da2899SCharles.Forsyth 794*37da2899SCharles.Forsyth return error; 795*37da2899SCharles.Forsyth } 796*37da2899SCharles.Forsyth 797*37da2899SCharles.Forsyth 798*37da2899SCharles.Forsyth /* there's a Mac-specific extended implementation of FT_New_Face() */ 799*37da2899SCharles.Forsyth /* in src/base/ftmac.c */ 800*37da2899SCharles.Forsyth 801*37da2899SCharles.Forsyth #ifndef FT_MACINTOSH 802*37da2899SCharles.Forsyth 803*37da2899SCharles.Forsyth /* documentation is in freetype.h */ 804*37da2899SCharles.Forsyth 805*37da2899SCharles.Forsyth FT_EXPORT_DEF( FT_Error ) FT_New_Face(FT_Library library,const char * pathname,FT_Long face_index,FT_Face * aface)806*37da2899SCharles.Forsyth FT_New_Face( FT_Library library, 807*37da2899SCharles.Forsyth const char* pathname, 808*37da2899SCharles.Forsyth FT_Long face_index, 809*37da2899SCharles.Forsyth FT_Face *aface ) 810*37da2899SCharles.Forsyth { 811*37da2899SCharles.Forsyth FT_Open_Args args; 812*37da2899SCharles.Forsyth 813*37da2899SCharles.Forsyth 814*37da2899SCharles.Forsyth /* test for valid `library' and `aface' delayed to FT_Open_Face() */ 815*37da2899SCharles.Forsyth if ( !pathname ) 816*37da2899SCharles.Forsyth return FT_Err_Invalid_Argument; 817*37da2899SCharles.Forsyth 818*37da2899SCharles.Forsyth args.flags = FT_OPEN_PATHNAME; 819*37da2899SCharles.Forsyth args.pathname = (char*)pathname; 820*37da2899SCharles.Forsyth 821*37da2899SCharles.Forsyth return FT_Open_Face( library, &args, face_index, aface ); 822*37da2899SCharles.Forsyth } 823*37da2899SCharles.Forsyth 824*37da2899SCharles.Forsyth #endif /* !FT_MACINTOSH */ 825*37da2899SCharles.Forsyth 826*37da2899SCharles.Forsyth 827*37da2899SCharles.Forsyth /* documentation is in freetype.h */ 828*37da2899SCharles.Forsyth 829*37da2899SCharles.Forsyth FT_EXPORT_DEF( FT_Error ) FT_New_Memory_Face(FT_Library library,const FT_Byte * file_base,FT_Long file_size,FT_Long face_index,FT_Face * aface)830*37da2899SCharles.Forsyth FT_New_Memory_Face( FT_Library library, 831*37da2899SCharles.Forsyth const FT_Byte* file_base, 832*37da2899SCharles.Forsyth FT_Long file_size, 833*37da2899SCharles.Forsyth FT_Long face_index, 834*37da2899SCharles.Forsyth FT_Face *aface ) 835*37da2899SCharles.Forsyth { 836*37da2899SCharles.Forsyth FT_Open_Args args; 837*37da2899SCharles.Forsyth 838*37da2899SCharles.Forsyth 839*37da2899SCharles.Forsyth /* test for valid `library' and `face' delayed to FT_Open_Face() */ 840*37da2899SCharles.Forsyth if ( !file_base ) 841*37da2899SCharles.Forsyth return FT_Err_Invalid_Argument; 842*37da2899SCharles.Forsyth 843*37da2899SCharles.Forsyth args.flags = FT_OPEN_MEMORY; 844*37da2899SCharles.Forsyth args.memory_base = file_base; 845*37da2899SCharles.Forsyth args.memory_size = file_size; 846*37da2899SCharles.Forsyth 847*37da2899SCharles.Forsyth return FT_Open_Face( library, &args, face_index, aface ); 848*37da2899SCharles.Forsyth } 849*37da2899SCharles.Forsyth 850*37da2899SCharles.Forsyth 851*37da2899SCharles.Forsyth /* documentation is in freetype.h */ 852*37da2899SCharles.Forsyth 853*37da2899SCharles.Forsyth FT_EXPORT_DEF( FT_Error ) FT_Open_Face(FT_Library library,const FT_Open_Args * args,FT_Long face_index,FT_Face * aface)854*37da2899SCharles.Forsyth FT_Open_Face( FT_Library library, 855*37da2899SCharles.Forsyth const FT_Open_Args* args, 856*37da2899SCharles.Forsyth FT_Long face_index, 857*37da2899SCharles.Forsyth FT_Face *aface ) 858*37da2899SCharles.Forsyth { 859*37da2899SCharles.Forsyth FT_Error error; 860*37da2899SCharles.Forsyth FT_Driver driver; 861*37da2899SCharles.Forsyth FT_Memory memory; 862*37da2899SCharles.Forsyth FT_Stream stream; 863*37da2899SCharles.Forsyth FT_Face face = 0; 864*37da2899SCharles.Forsyth FT_ListNode node = 0; 865*37da2899SCharles.Forsyth FT_Bool external_stream; 866*37da2899SCharles.Forsyth 867*37da2899SCharles.Forsyth 868*37da2899SCharles.Forsyth /* test for valid `library' delayed to */ 869*37da2899SCharles.Forsyth /* ft_input_stream_new() */ 870*37da2899SCharles.Forsyth 871*37da2899SCharles.Forsyth if ( !aface || !args ) 872*37da2899SCharles.Forsyth return FT_Err_Invalid_Argument; 873*37da2899SCharles.Forsyth 874*37da2899SCharles.Forsyth *aface = 0; 875*37da2899SCharles.Forsyth 876*37da2899SCharles.Forsyth external_stream = FT_BOOL( ( args->flags & FT_OPEN_STREAM ) && 877*37da2899SCharles.Forsyth args->stream ); 878*37da2899SCharles.Forsyth 879*37da2899SCharles.Forsyth /* create input stream */ 880*37da2899SCharles.Forsyth error = ft_input_stream_new( library, args, &stream ); 881*37da2899SCharles.Forsyth if ( error ) 882*37da2899SCharles.Forsyth goto Exit; 883*37da2899SCharles.Forsyth 884*37da2899SCharles.Forsyth memory = library->memory; 885*37da2899SCharles.Forsyth 886*37da2899SCharles.Forsyth /* If the font driver is specified in the `args' structure, use */ 887*37da2899SCharles.Forsyth /* it. Otherwise, we scan the list of registered drivers. */ 888*37da2899SCharles.Forsyth if ( ( args->flags & FT_OPEN_DRIVER ) && args->driver ) 889*37da2899SCharles.Forsyth { 890*37da2899SCharles.Forsyth driver = FT_DRIVER( args->driver ); 891*37da2899SCharles.Forsyth 892*37da2899SCharles.Forsyth /* not all modules are drivers, so check... */ 893*37da2899SCharles.Forsyth if ( FT_MODULE_IS_DRIVER( driver ) ) 894*37da2899SCharles.Forsyth { 895*37da2899SCharles.Forsyth FT_Int num_params = 0; 896*37da2899SCharles.Forsyth FT_Parameter* params = 0; 897*37da2899SCharles.Forsyth 898*37da2899SCharles.Forsyth 899*37da2899SCharles.Forsyth if ( args->flags & FT_OPEN_PARAMS ) 900*37da2899SCharles.Forsyth { 901*37da2899SCharles.Forsyth num_params = args->num_params; 902*37da2899SCharles.Forsyth params = args->params; 903*37da2899SCharles.Forsyth } 904*37da2899SCharles.Forsyth 905*37da2899SCharles.Forsyth error = open_face( driver, stream, face_index, 906*37da2899SCharles.Forsyth num_params, params, &face ); 907*37da2899SCharles.Forsyth if ( !error ) 908*37da2899SCharles.Forsyth goto Success; 909*37da2899SCharles.Forsyth } 910*37da2899SCharles.Forsyth else 911*37da2899SCharles.Forsyth error = FT_Err_Invalid_Handle; 912*37da2899SCharles.Forsyth 913*37da2899SCharles.Forsyth ft_input_stream_free( stream, external_stream ); 914*37da2899SCharles.Forsyth goto Fail; 915*37da2899SCharles.Forsyth } 916*37da2899SCharles.Forsyth else 917*37da2899SCharles.Forsyth { 918*37da2899SCharles.Forsyth /* check each font driver for an appropriate format */ 919*37da2899SCharles.Forsyth FT_Module* cur = library->modules; 920*37da2899SCharles.Forsyth FT_Module* limit = cur + library->num_modules; 921*37da2899SCharles.Forsyth 922*37da2899SCharles.Forsyth 923*37da2899SCharles.Forsyth for ( ; cur < limit; cur++ ) 924*37da2899SCharles.Forsyth { 925*37da2899SCharles.Forsyth /* not all modules are font drivers, so check... */ 926*37da2899SCharles.Forsyth if ( FT_MODULE_IS_DRIVER( cur[0] ) ) 927*37da2899SCharles.Forsyth { 928*37da2899SCharles.Forsyth FT_Int num_params = 0; 929*37da2899SCharles.Forsyth FT_Parameter* params = 0; 930*37da2899SCharles.Forsyth 931*37da2899SCharles.Forsyth 932*37da2899SCharles.Forsyth driver = FT_DRIVER( cur[0] ); 933*37da2899SCharles.Forsyth 934*37da2899SCharles.Forsyth if ( args->flags & FT_OPEN_PARAMS ) 935*37da2899SCharles.Forsyth { 936*37da2899SCharles.Forsyth num_params = args->num_params; 937*37da2899SCharles.Forsyth params = args->params; 938*37da2899SCharles.Forsyth } 939*37da2899SCharles.Forsyth 940*37da2899SCharles.Forsyth error = open_face( driver, stream, face_index, 941*37da2899SCharles.Forsyth num_params, params, &face ); 942*37da2899SCharles.Forsyth if ( !error ) 943*37da2899SCharles.Forsyth goto Success; 944*37da2899SCharles.Forsyth 945*37da2899SCharles.Forsyth if ( FT_ERROR_BASE( error ) != FT_Err_Unknown_File_Format ) 946*37da2899SCharles.Forsyth goto Fail2; 947*37da2899SCharles.Forsyth } 948*37da2899SCharles.Forsyth } 949*37da2899SCharles.Forsyth 950*37da2899SCharles.Forsyth /* no driver is able to handle this format */ 951*37da2899SCharles.Forsyth error = FT_Err_Unknown_File_Format; 952*37da2899SCharles.Forsyth 953*37da2899SCharles.Forsyth Fail2: 954*37da2899SCharles.Forsyth ft_input_stream_free( stream, external_stream ); 955*37da2899SCharles.Forsyth goto Fail; 956*37da2899SCharles.Forsyth } 957*37da2899SCharles.Forsyth 958*37da2899SCharles.Forsyth Success: 959*37da2899SCharles.Forsyth FT_TRACE4(( "FT_Open_Face: New face object, adding to list\n" )); 960*37da2899SCharles.Forsyth 961*37da2899SCharles.Forsyth /* set the FT_FACE_FLAG_EXTERNAL_STREAM bit for FT_Done_Face */ 962*37da2899SCharles.Forsyth if ( external_stream ) 963*37da2899SCharles.Forsyth face->face_flags |= FT_FACE_FLAG_EXTERNAL_STREAM; 964*37da2899SCharles.Forsyth 965*37da2899SCharles.Forsyth /* add the face object to its driver's list */ 966*37da2899SCharles.Forsyth if ( FT_NEW( node ) ) 967*37da2899SCharles.Forsyth goto Fail; 968*37da2899SCharles.Forsyth 969*37da2899SCharles.Forsyth node->data = face; 970*37da2899SCharles.Forsyth /* don't assume driver is the same as face->driver, so use */ 971*37da2899SCharles.Forsyth /* face->driver instead. */ 972*37da2899SCharles.Forsyth FT_List_Add( &face->driver->faces_list, node ); 973*37da2899SCharles.Forsyth 974*37da2899SCharles.Forsyth /* now allocate a glyph slot object for the face */ 975*37da2899SCharles.Forsyth { 976*37da2899SCharles.Forsyth FT_GlyphSlot slot; 977*37da2899SCharles.Forsyth 978*37da2899SCharles.Forsyth 979*37da2899SCharles.Forsyth FT_TRACE4(( "FT_Open_Face: Creating glyph slot\n" )); 980*37da2899SCharles.Forsyth 981*37da2899SCharles.Forsyth error = FT_New_GlyphSlot( face, &slot ); 982*37da2899SCharles.Forsyth if ( error ) 983*37da2899SCharles.Forsyth goto Fail; 984*37da2899SCharles.Forsyth 985*37da2899SCharles.Forsyth face->glyph = slot; 986*37da2899SCharles.Forsyth } 987*37da2899SCharles.Forsyth 988*37da2899SCharles.Forsyth /* finally, allocate a size object for the face */ 989*37da2899SCharles.Forsyth { 990*37da2899SCharles.Forsyth FT_Size size; 991*37da2899SCharles.Forsyth 992*37da2899SCharles.Forsyth 993*37da2899SCharles.Forsyth FT_TRACE4(( "FT_Open_Face: Creating size object\n" )); 994*37da2899SCharles.Forsyth 995*37da2899SCharles.Forsyth error = FT_New_Size( face, &size ); 996*37da2899SCharles.Forsyth if ( error ) 997*37da2899SCharles.Forsyth goto Fail; 998*37da2899SCharles.Forsyth 999*37da2899SCharles.Forsyth face->size = size; 1000*37da2899SCharles.Forsyth } 1001*37da2899SCharles.Forsyth 1002*37da2899SCharles.Forsyth /* initialize internal face data */ 1003*37da2899SCharles.Forsyth { 1004*37da2899SCharles.Forsyth FT_Face_Internal internal = face->internal; 1005*37da2899SCharles.Forsyth 1006*37da2899SCharles.Forsyth 1007*37da2899SCharles.Forsyth internal->transform_matrix.xx = 0x10000L; 1008*37da2899SCharles.Forsyth internal->transform_matrix.xy = 0; 1009*37da2899SCharles.Forsyth internal->transform_matrix.yx = 0; 1010*37da2899SCharles.Forsyth internal->transform_matrix.yy = 0x10000L; 1011*37da2899SCharles.Forsyth 1012*37da2899SCharles.Forsyth internal->transform_delta.x = 0; 1013*37da2899SCharles.Forsyth internal->transform_delta.y = 0; 1014*37da2899SCharles.Forsyth } 1015*37da2899SCharles.Forsyth 1016*37da2899SCharles.Forsyth *aface = face; 1017*37da2899SCharles.Forsyth goto Exit; 1018*37da2899SCharles.Forsyth 1019*37da2899SCharles.Forsyth Fail: 1020*37da2899SCharles.Forsyth FT_Done_Face( face ); 1021*37da2899SCharles.Forsyth 1022*37da2899SCharles.Forsyth Exit: 1023*37da2899SCharles.Forsyth FT_TRACE4(( "FT_Open_Face: Return %d\n", error )); 1024*37da2899SCharles.Forsyth 1025*37da2899SCharles.Forsyth return error; 1026*37da2899SCharles.Forsyth } 1027*37da2899SCharles.Forsyth 1028*37da2899SCharles.Forsyth 1029*37da2899SCharles.Forsyth /* documentation is in freetype.h */ 1030*37da2899SCharles.Forsyth 1031*37da2899SCharles.Forsyth FT_EXPORT_DEF( FT_Error ) FT_Attach_File(FT_Face face,const char * filepathname)1032*37da2899SCharles.Forsyth FT_Attach_File( FT_Face face, 1033*37da2899SCharles.Forsyth const char* filepathname ) 1034*37da2899SCharles.Forsyth { 1035*37da2899SCharles.Forsyth FT_Open_Args open; 1036*37da2899SCharles.Forsyth 1037*37da2899SCharles.Forsyth 1038*37da2899SCharles.Forsyth /* test for valid `face' delayed to FT_Attach_Stream() */ 1039*37da2899SCharles.Forsyth 1040*37da2899SCharles.Forsyth if ( !filepathname ) 1041*37da2899SCharles.Forsyth return FT_Err_Invalid_Argument; 1042*37da2899SCharles.Forsyth 1043*37da2899SCharles.Forsyth open.flags = FT_OPEN_PATHNAME; 1044*37da2899SCharles.Forsyth open.pathname = (char*)filepathname; 1045*37da2899SCharles.Forsyth 1046*37da2899SCharles.Forsyth return FT_Attach_Stream( face, &open ); 1047*37da2899SCharles.Forsyth } 1048*37da2899SCharles.Forsyth 1049*37da2899SCharles.Forsyth 1050*37da2899SCharles.Forsyth /* documentation is in freetype.h */ 1051*37da2899SCharles.Forsyth 1052*37da2899SCharles.Forsyth FT_EXPORT_DEF( FT_Error ) FT_Attach_Stream(FT_Face face,FT_Open_Args * parameters)1053*37da2899SCharles.Forsyth FT_Attach_Stream( FT_Face face, 1054*37da2899SCharles.Forsyth FT_Open_Args* parameters ) 1055*37da2899SCharles.Forsyth { 1056*37da2899SCharles.Forsyth FT_Stream stream; 1057*37da2899SCharles.Forsyth FT_Error error; 1058*37da2899SCharles.Forsyth FT_Driver driver; 1059*37da2899SCharles.Forsyth 1060*37da2899SCharles.Forsyth FT_Driver_Class clazz; 1061*37da2899SCharles.Forsyth 1062*37da2899SCharles.Forsyth 1063*37da2899SCharles.Forsyth /* test for valid `parameters' delayed to ft_input_stream_new() */ 1064*37da2899SCharles.Forsyth 1065*37da2899SCharles.Forsyth if ( !face ) 1066*37da2899SCharles.Forsyth return FT_Err_Invalid_Face_Handle; 1067*37da2899SCharles.Forsyth 1068*37da2899SCharles.Forsyth driver = face->driver; 1069*37da2899SCharles.Forsyth if ( !driver ) 1070*37da2899SCharles.Forsyth return FT_Err_Invalid_Driver_Handle; 1071*37da2899SCharles.Forsyth 1072*37da2899SCharles.Forsyth error = ft_input_stream_new( driver->root.library, parameters, &stream ); 1073*37da2899SCharles.Forsyth if ( error ) 1074*37da2899SCharles.Forsyth goto Exit; 1075*37da2899SCharles.Forsyth 1076*37da2899SCharles.Forsyth /* we implement FT_Attach_Stream in each driver through the */ 1077*37da2899SCharles.Forsyth /* `attach_file' interface */ 1078*37da2899SCharles.Forsyth 1079*37da2899SCharles.Forsyth error = FT_Err_Unimplemented_Feature; 1080*37da2899SCharles.Forsyth clazz = driver->clazz; 1081*37da2899SCharles.Forsyth if ( clazz->attach_file ) 1082*37da2899SCharles.Forsyth error = clazz->attach_file( face, stream ); 1083*37da2899SCharles.Forsyth 1084*37da2899SCharles.Forsyth /* close the attached stream */ 1085*37da2899SCharles.Forsyth ft_input_stream_free( stream, 1086*37da2899SCharles.Forsyth (FT_Bool)( parameters->stream && 1087*37da2899SCharles.Forsyth ( parameters->flags & FT_OPEN_STREAM ) ) ); 1088*37da2899SCharles.Forsyth 1089*37da2899SCharles.Forsyth Exit: 1090*37da2899SCharles.Forsyth return error; 1091*37da2899SCharles.Forsyth } 1092*37da2899SCharles.Forsyth 1093*37da2899SCharles.Forsyth 1094*37da2899SCharles.Forsyth /* documentation is in freetype.h */ 1095*37da2899SCharles.Forsyth 1096*37da2899SCharles.Forsyth FT_EXPORT_DEF( FT_Error ) FT_Done_Face(FT_Face face)1097*37da2899SCharles.Forsyth FT_Done_Face( FT_Face face ) 1098*37da2899SCharles.Forsyth { 1099*37da2899SCharles.Forsyth FT_Error error; 1100*37da2899SCharles.Forsyth FT_Driver driver; 1101*37da2899SCharles.Forsyth FT_Memory memory; 1102*37da2899SCharles.Forsyth FT_ListNode node; 1103*37da2899SCharles.Forsyth 1104*37da2899SCharles.Forsyth 1105*37da2899SCharles.Forsyth error = FT_Err_Invalid_Face_Handle; 1106*37da2899SCharles.Forsyth if ( face && face->driver ) 1107*37da2899SCharles.Forsyth { 1108*37da2899SCharles.Forsyth driver = face->driver; 1109*37da2899SCharles.Forsyth memory = driver->root.memory; 1110*37da2899SCharles.Forsyth 1111*37da2899SCharles.Forsyth /* find face in driver's list */ 1112*37da2899SCharles.Forsyth node = FT_List_Find( &driver->faces_list, face ); 1113*37da2899SCharles.Forsyth if ( node ) 1114*37da2899SCharles.Forsyth { 1115*37da2899SCharles.Forsyth /* remove face object from the driver's list */ 1116*37da2899SCharles.Forsyth FT_List_Remove( &driver->faces_list, node ); 1117*37da2899SCharles.Forsyth FT_FREE( node ); 1118*37da2899SCharles.Forsyth 1119*37da2899SCharles.Forsyth /* now destroy the object proper */ 1120*37da2899SCharles.Forsyth destroy_face( memory, face, driver ); 1121*37da2899SCharles.Forsyth error = FT_Err_Ok; 1122*37da2899SCharles.Forsyth } 1123*37da2899SCharles.Forsyth } 1124*37da2899SCharles.Forsyth return error; 1125*37da2899SCharles.Forsyth } 1126*37da2899SCharles.Forsyth 1127*37da2899SCharles.Forsyth 1128*37da2899SCharles.Forsyth /* documentation is in ftobjs.h */ 1129*37da2899SCharles.Forsyth 1130*37da2899SCharles.Forsyth FT_EXPORT_DEF( FT_Error ) FT_New_Size(FT_Face face,FT_Size * asize)1131*37da2899SCharles.Forsyth FT_New_Size( FT_Face face, 1132*37da2899SCharles.Forsyth FT_Size *asize ) 1133*37da2899SCharles.Forsyth { 1134*37da2899SCharles.Forsyth FT_Error error; 1135*37da2899SCharles.Forsyth FT_Memory memory; 1136*37da2899SCharles.Forsyth FT_Driver driver; 1137*37da2899SCharles.Forsyth FT_Driver_Class clazz; 1138*37da2899SCharles.Forsyth 1139*37da2899SCharles.Forsyth FT_Size size = 0; 1140*37da2899SCharles.Forsyth FT_ListNode node = 0; 1141*37da2899SCharles.Forsyth 1142*37da2899SCharles.Forsyth 1143*37da2899SCharles.Forsyth if ( !face ) 1144*37da2899SCharles.Forsyth return FT_Err_Invalid_Face_Handle; 1145*37da2899SCharles.Forsyth 1146*37da2899SCharles.Forsyth if ( !asize ) 1147*37da2899SCharles.Forsyth return FT_Err_Invalid_Size_Handle; 1148*37da2899SCharles.Forsyth 1149*37da2899SCharles.Forsyth if ( !face->driver ) 1150*37da2899SCharles.Forsyth return FT_Err_Invalid_Driver_Handle; 1151*37da2899SCharles.Forsyth 1152*37da2899SCharles.Forsyth *asize = 0; 1153*37da2899SCharles.Forsyth 1154*37da2899SCharles.Forsyth driver = face->driver; 1155*37da2899SCharles.Forsyth clazz = driver->clazz; 1156*37da2899SCharles.Forsyth memory = face->memory; 1157*37da2899SCharles.Forsyth 1158*37da2899SCharles.Forsyth /* Allocate new size object and perform basic initialisation */ 1159*37da2899SCharles.Forsyth if ( FT_ALLOC( size, clazz->size_object_size ) || FT_NEW( node ) ) 1160*37da2899SCharles.Forsyth goto Exit; 1161*37da2899SCharles.Forsyth 1162*37da2899SCharles.Forsyth size->face = face; 1163*37da2899SCharles.Forsyth 1164*37da2899SCharles.Forsyth /* for now, do not use any internal fields in size objects */ 1165*37da2899SCharles.Forsyth size->internal = 0; 1166*37da2899SCharles.Forsyth 1167*37da2899SCharles.Forsyth if ( clazz->init_size ) 1168*37da2899SCharles.Forsyth error = clazz->init_size( size ); 1169*37da2899SCharles.Forsyth 1170*37da2899SCharles.Forsyth /* in case of success, add to the face's list */ 1171*37da2899SCharles.Forsyth if ( !error ) 1172*37da2899SCharles.Forsyth { 1173*37da2899SCharles.Forsyth *asize = size; 1174*37da2899SCharles.Forsyth node->data = size; 1175*37da2899SCharles.Forsyth FT_List_Add( &face->sizes_list, node ); 1176*37da2899SCharles.Forsyth } 1177*37da2899SCharles.Forsyth 1178*37da2899SCharles.Forsyth Exit: 1179*37da2899SCharles.Forsyth if ( error ) 1180*37da2899SCharles.Forsyth { 1181*37da2899SCharles.Forsyth FT_FREE( node ); 1182*37da2899SCharles.Forsyth FT_FREE( size ); 1183*37da2899SCharles.Forsyth } 1184*37da2899SCharles.Forsyth 1185*37da2899SCharles.Forsyth return error; 1186*37da2899SCharles.Forsyth } 1187*37da2899SCharles.Forsyth 1188*37da2899SCharles.Forsyth 1189*37da2899SCharles.Forsyth /* documentation is in ftobjs.h */ 1190*37da2899SCharles.Forsyth 1191*37da2899SCharles.Forsyth FT_EXPORT_DEF( FT_Error ) FT_Done_Size(FT_Size size)1192*37da2899SCharles.Forsyth FT_Done_Size( FT_Size size ) 1193*37da2899SCharles.Forsyth { 1194*37da2899SCharles.Forsyth FT_Error error; 1195*37da2899SCharles.Forsyth FT_Driver driver; 1196*37da2899SCharles.Forsyth FT_Memory memory; 1197*37da2899SCharles.Forsyth FT_Face face; 1198*37da2899SCharles.Forsyth FT_ListNode node; 1199*37da2899SCharles.Forsyth 1200*37da2899SCharles.Forsyth 1201*37da2899SCharles.Forsyth if ( !size ) 1202*37da2899SCharles.Forsyth return FT_Err_Invalid_Size_Handle; 1203*37da2899SCharles.Forsyth 1204*37da2899SCharles.Forsyth face = size->face; 1205*37da2899SCharles.Forsyth if ( !face ) 1206*37da2899SCharles.Forsyth return FT_Err_Invalid_Face_Handle; 1207*37da2899SCharles.Forsyth 1208*37da2899SCharles.Forsyth driver = face->driver; 1209*37da2899SCharles.Forsyth if ( !driver ) 1210*37da2899SCharles.Forsyth return FT_Err_Invalid_Driver_Handle; 1211*37da2899SCharles.Forsyth 1212*37da2899SCharles.Forsyth memory = driver->root.memory; 1213*37da2899SCharles.Forsyth 1214*37da2899SCharles.Forsyth error = FT_Err_Ok; 1215*37da2899SCharles.Forsyth node = FT_List_Find( &face->sizes_list, size ); 1216*37da2899SCharles.Forsyth if ( node ) 1217*37da2899SCharles.Forsyth { 1218*37da2899SCharles.Forsyth FT_List_Remove( &face->sizes_list, node ); 1219*37da2899SCharles.Forsyth FT_FREE( node ); 1220*37da2899SCharles.Forsyth 1221*37da2899SCharles.Forsyth if ( face->size == size ) 1222*37da2899SCharles.Forsyth { 1223*37da2899SCharles.Forsyth face->size = 0; 1224*37da2899SCharles.Forsyth if ( face->sizes_list.head ) 1225*37da2899SCharles.Forsyth face->size = (FT_Size)(face->sizes_list.head->data); 1226*37da2899SCharles.Forsyth } 1227*37da2899SCharles.Forsyth 1228*37da2899SCharles.Forsyth destroy_size( memory, size, driver ); 1229*37da2899SCharles.Forsyth } 1230*37da2899SCharles.Forsyth else 1231*37da2899SCharles.Forsyth error = FT_Err_Invalid_Size_Handle; 1232*37da2899SCharles.Forsyth 1233*37da2899SCharles.Forsyth return error; 1234*37da2899SCharles.Forsyth } 1235*37da2899SCharles.Forsyth 1236*37da2899SCharles.Forsyth 1237*37da2899SCharles.Forsyth static void ft_recompute_scaled_metrics(FT_Face face,FT_Size_Metrics * metrics)1238*37da2899SCharles.Forsyth ft_recompute_scaled_metrics( FT_Face face, 1239*37da2899SCharles.Forsyth FT_Size_Metrics* metrics ) 1240*37da2899SCharles.Forsyth { 1241*37da2899SCharles.Forsyth /* Compute root ascender, descender, test height, and max_advance */ 1242*37da2899SCharles.Forsyth 1243*37da2899SCharles.Forsyth metrics->ascender = ( FT_MulFix( face->ascender, 1244*37da2899SCharles.Forsyth metrics->y_scale ) + 32 ) & -64; 1245*37da2899SCharles.Forsyth 1246*37da2899SCharles.Forsyth metrics->descender = ( FT_MulFix( face->descender, 1247*37da2899SCharles.Forsyth metrics->y_scale ) + 32 ) & -64; 1248*37da2899SCharles.Forsyth 1249*37da2899SCharles.Forsyth metrics->height = ( FT_MulFix( face->height, 1250*37da2899SCharles.Forsyth metrics->y_scale ) + 32 ) & -64; 1251*37da2899SCharles.Forsyth 1252*37da2899SCharles.Forsyth metrics->max_advance = ( FT_MulFix( face->max_advance_width, 1253*37da2899SCharles.Forsyth metrics->x_scale ) + 32 ) & -64; 1254*37da2899SCharles.Forsyth } 1255*37da2899SCharles.Forsyth 1256*37da2899SCharles.Forsyth 1257*37da2899SCharles.Forsyth /* documentation is in freetype.h */ 1258*37da2899SCharles.Forsyth 1259*37da2899SCharles.Forsyth FT_EXPORT_DEF( FT_Error ) FT_Set_Char_Size(FT_Face face,FT_F26Dot6 char_width,FT_F26Dot6 char_height,FT_UInt horz_resolution,FT_UInt vert_resolution)1260*37da2899SCharles.Forsyth FT_Set_Char_Size( FT_Face face, 1261*37da2899SCharles.Forsyth FT_F26Dot6 char_width, 1262*37da2899SCharles.Forsyth FT_F26Dot6 char_height, 1263*37da2899SCharles.Forsyth FT_UInt horz_resolution, 1264*37da2899SCharles.Forsyth FT_UInt vert_resolution ) 1265*37da2899SCharles.Forsyth { 1266*37da2899SCharles.Forsyth FT_Error error = FT_Err_Ok; 1267*37da2899SCharles.Forsyth FT_Driver driver; 1268*37da2899SCharles.Forsyth FT_Driver_Class clazz; 1269*37da2899SCharles.Forsyth FT_Size_Metrics* metrics; 1270*37da2899SCharles.Forsyth FT_Long dim_x, dim_y; 1271*37da2899SCharles.Forsyth 1272*37da2899SCharles.Forsyth 1273*37da2899SCharles.Forsyth if ( !face || !face->size || !face->driver ) 1274*37da2899SCharles.Forsyth return FT_Err_Invalid_Face_Handle; 1275*37da2899SCharles.Forsyth 1276*37da2899SCharles.Forsyth driver = face->driver; 1277*37da2899SCharles.Forsyth metrics = &face->size->metrics; 1278*37da2899SCharles.Forsyth 1279*37da2899SCharles.Forsyth if ( !char_width ) 1280*37da2899SCharles.Forsyth char_width = char_height; 1281*37da2899SCharles.Forsyth 1282*37da2899SCharles.Forsyth else if ( !char_height ) 1283*37da2899SCharles.Forsyth char_height = char_width; 1284*37da2899SCharles.Forsyth 1285*37da2899SCharles.Forsyth if ( !horz_resolution ) 1286*37da2899SCharles.Forsyth horz_resolution = 72; 1287*37da2899SCharles.Forsyth 1288*37da2899SCharles.Forsyth if ( !vert_resolution ) 1289*37da2899SCharles.Forsyth vert_resolution = 72; 1290*37da2899SCharles.Forsyth 1291*37da2899SCharles.Forsyth driver = face->driver; 1292*37da2899SCharles.Forsyth clazz = driver->clazz; 1293*37da2899SCharles.Forsyth 1294*37da2899SCharles.Forsyth /* default processing -- this can be overridden by the driver */ 1295*37da2899SCharles.Forsyth if ( char_width < 1 * 64 ) 1296*37da2899SCharles.Forsyth char_width = 1 * 64; 1297*37da2899SCharles.Forsyth if ( char_height < 1 * 64 ) 1298*37da2899SCharles.Forsyth char_height = 1 * 64; 1299*37da2899SCharles.Forsyth 1300*37da2899SCharles.Forsyth /* Compute pixel sizes in 26.6 units */ 1301*37da2899SCharles.Forsyth dim_x = ( ( ( char_width * horz_resolution ) / 72 ) + 32 ) & -64; 1302*37da2899SCharles.Forsyth dim_y = ( ( ( char_height * vert_resolution ) / 72 ) + 32 ) & -64; 1303*37da2899SCharles.Forsyth 1304*37da2899SCharles.Forsyth metrics->x_ppem = (FT_UShort)( dim_x >> 6 ); 1305*37da2899SCharles.Forsyth metrics->y_ppem = (FT_UShort)( dim_y >> 6 ); 1306*37da2899SCharles.Forsyth 1307*37da2899SCharles.Forsyth metrics->x_scale = 0x10000L; 1308*37da2899SCharles.Forsyth metrics->y_scale = 0x10000L; 1309*37da2899SCharles.Forsyth 1310*37da2899SCharles.Forsyth if ( face->face_flags & FT_FACE_FLAG_SCALABLE ) 1311*37da2899SCharles.Forsyth { 1312*37da2899SCharles.Forsyth metrics->x_scale = FT_DivFix( dim_x, face->units_per_EM ); 1313*37da2899SCharles.Forsyth metrics->y_scale = FT_DivFix( dim_y, face->units_per_EM ); 1314*37da2899SCharles.Forsyth 1315*37da2899SCharles.Forsyth ft_recompute_scaled_metrics( face, metrics ); 1316*37da2899SCharles.Forsyth } 1317*37da2899SCharles.Forsyth 1318*37da2899SCharles.Forsyth if ( clazz->set_char_sizes ) 1319*37da2899SCharles.Forsyth error = clazz->set_char_sizes( face->size, 1320*37da2899SCharles.Forsyth char_width, 1321*37da2899SCharles.Forsyth char_height, 1322*37da2899SCharles.Forsyth horz_resolution, 1323*37da2899SCharles.Forsyth vert_resolution ); 1324*37da2899SCharles.Forsyth return error; 1325*37da2899SCharles.Forsyth } 1326*37da2899SCharles.Forsyth 1327*37da2899SCharles.Forsyth 1328*37da2899SCharles.Forsyth /* documentation is in freetype.h */ 1329*37da2899SCharles.Forsyth 1330*37da2899SCharles.Forsyth FT_EXPORT_DEF( FT_Error ) FT_Set_Pixel_Sizes(FT_Face face,FT_UInt pixel_width,FT_UInt pixel_height)1331*37da2899SCharles.Forsyth FT_Set_Pixel_Sizes( FT_Face face, 1332*37da2899SCharles.Forsyth FT_UInt pixel_width, 1333*37da2899SCharles.Forsyth FT_UInt pixel_height ) 1334*37da2899SCharles.Forsyth { 1335*37da2899SCharles.Forsyth FT_Error error = FT_Err_Ok; 1336*37da2899SCharles.Forsyth FT_Driver driver; 1337*37da2899SCharles.Forsyth FT_Driver_Class clazz; 1338*37da2899SCharles.Forsyth FT_Size_Metrics* metrics = &face->size->metrics; 1339*37da2899SCharles.Forsyth 1340*37da2899SCharles.Forsyth 1341*37da2899SCharles.Forsyth if ( !face || !face->size || !face->driver ) 1342*37da2899SCharles.Forsyth return FT_Err_Invalid_Face_Handle; 1343*37da2899SCharles.Forsyth 1344*37da2899SCharles.Forsyth driver = face->driver; 1345*37da2899SCharles.Forsyth clazz = driver->clazz; 1346*37da2899SCharles.Forsyth 1347*37da2899SCharles.Forsyth /* default processing -- this can be overridden by the driver */ 1348*37da2899SCharles.Forsyth if ( pixel_width == 0 ) 1349*37da2899SCharles.Forsyth pixel_width = pixel_height; 1350*37da2899SCharles.Forsyth 1351*37da2899SCharles.Forsyth else if ( pixel_height == 0 ) 1352*37da2899SCharles.Forsyth pixel_height = pixel_width; 1353*37da2899SCharles.Forsyth 1354*37da2899SCharles.Forsyth if ( pixel_width < 1 ) 1355*37da2899SCharles.Forsyth pixel_width = 1; 1356*37da2899SCharles.Forsyth if ( pixel_height < 1 ) 1357*37da2899SCharles.Forsyth pixel_height = 1; 1358*37da2899SCharles.Forsyth 1359*37da2899SCharles.Forsyth metrics->x_ppem = (FT_UShort)pixel_width; 1360*37da2899SCharles.Forsyth metrics->y_ppem = (FT_UShort)pixel_height; 1361*37da2899SCharles.Forsyth 1362*37da2899SCharles.Forsyth if ( face->face_flags & FT_FACE_FLAG_SCALABLE ) 1363*37da2899SCharles.Forsyth { 1364*37da2899SCharles.Forsyth metrics->x_scale = FT_DivFix( metrics->x_ppem << 6, 1365*37da2899SCharles.Forsyth face->units_per_EM ); 1366*37da2899SCharles.Forsyth 1367*37da2899SCharles.Forsyth metrics->y_scale = FT_DivFix( metrics->y_ppem << 6, 1368*37da2899SCharles.Forsyth face->units_per_EM ); 1369*37da2899SCharles.Forsyth 1370*37da2899SCharles.Forsyth ft_recompute_scaled_metrics( face, metrics ); 1371*37da2899SCharles.Forsyth } 1372*37da2899SCharles.Forsyth 1373*37da2899SCharles.Forsyth if ( clazz->set_pixel_sizes ) 1374*37da2899SCharles.Forsyth error = clazz->set_pixel_sizes( face->size, 1375*37da2899SCharles.Forsyth pixel_width, 1376*37da2899SCharles.Forsyth pixel_height ); 1377*37da2899SCharles.Forsyth return error; 1378*37da2899SCharles.Forsyth } 1379*37da2899SCharles.Forsyth 1380*37da2899SCharles.Forsyth 1381*37da2899SCharles.Forsyth /* documentation is in freetype.h */ 1382*37da2899SCharles.Forsyth 1383*37da2899SCharles.Forsyth FT_EXPORT_DEF( FT_Error ) FT_Get_Kerning(FT_Face face,FT_UInt left_glyph,FT_UInt right_glyph,FT_UInt kern_mode,FT_Vector * akerning)1384*37da2899SCharles.Forsyth FT_Get_Kerning( FT_Face face, 1385*37da2899SCharles.Forsyth FT_UInt left_glyph, 1386*37da2899SCharles.Forsyth FT_UInt right_glyph, 1387*37da2899SCharles.Forsyth FT_UInt kern_mode, 1388*37da2899SCharles.Forsyth FT_Vector *akerning ) 1389*37da2899SCharles.Forsyth { 1390*37da2899SCharles.Forsyth FT_Error error = FT_Err_Ok; 1391*37da2899SCharles.Forsyth FT_Driver driver; 1392*37da2899SCharles.Forsyth 1393*37da2899SCharles.Forsyth 1394*37da2899SCharles.Forsyth if ( !face ) 1395*37da2899SCharles.Forsyth return FT_Err_Invalid_Face_Handle; 1396*37da2899SCharles.Forsyth 1397*37da2899SCharles.Forsyth if ( !akerning ) 1398*37da2899SCharles.Forsyth return FT_Err_Invalid_Argument; 1399*37da2899SCharles.Forsyth 1400*37da2899SCharles.Forsyth driver = face->driver; 1401*37da2899SCharles.Forsyth 1402*37da2899SCharles.Forsyth akerning->x = 0; 1403*37da2899SCharles.Forsyth akerning->y = 0; 1404*37da2899SCharles.Forsyth 1405*37da2899SCharles.Forsyth if ( driver->clazz->get_kerning ) 1406*37da2899SCharles.Forsyth { 1407*37da2899SCharles.Forsyth error = driver->clazz->get_kerning( face, 1408*37da2899SCharles.Forsyth left_glyph, 1409*37da2899SCharles.Forsyth right_glyph, 1410*37da2899SCharles.Forsyth akerning ); 1411*37da2899SCharles.Forsyth if ( !error ) 1412*37da2899SCharles.Forsyth { 1413*37da2899SCharles.Forsyth if ( kern_mode != FT_KERNING_UNSCALED ) 1414*37da2899SCharles.Forsyth { 1415*37da2899SCharles.Forsyth akerning->x = FT_MulFix( akerning->x, face->size->metrics.x_scale ); 1416*37da2899SCharles.Forsyth akerning->y = FT_MulFix( akerning->y, face->size->metrics.y_scale ); 1417*37da2899SCharles.Forsyth 1418*37da2899SCharles.Forsyth if ( kern_mode != FT_KERNING_UNFITTED ) 1419*37da2899SCharles.Forsyth { 1420*37da2899SCharles.Forsyth akerning->x = ( akerning->x + 32 ) & -64; 1421*37da2899SCharles.Forsyth akerning->y = ( akerning->y + 32 ) & -64; 1422*37da2899SCharles.Forsyth } 1423*37da2899SCharles.Forsyth } 1424*37da2899SCharles.Forsyth } 1425*37da2899SCharles.Forsyth } 1426*37da2899SCharles.Forsyth 1427*37da2899SCharles.Forsyth return error; 1428*37da2899SCharles.Forsyth } 1429*37da2899SCharles.Forsyth 1430*37da2899SCharles.Forsyth 1431*37da2899SCharles.Forsyth /* documentation is in freetype.h */ 1432*37da2899SCharles.Forsyth 1433*37da2899SCharles.Forsyth FT_EXPORT_DEF( FT_Error ) FT_Select_Charmap(FT_Face face,FT_Encoding encoding)1434*37da2899SCharles.Forsyth FT_Select_Charmap( FT_Face face, 1435*37da2899SCharles.Forsyth FT_Encoding encoding ) 1436*37da2899SCharles.Forsyth { 1437*37da2899SCharles.Forsyth FT_CharMap* cur; 1438*37da2899SCharles.Forsyth FT_CharMap* limit; 1439*37da2899SCharles.Forsyth 1440*37da2899SCharles.Forsyth 1441*37da2899SCharles.Forsyth if ( !face ) 1442*37da2899SCharles.Forsyth return FT_Err_Invalid_Face_Handle; 1443*37da2899SCharles.Forsyth 1444*37da2899SCharles.Forsyth cur = face->charmaps; 1445*37da2899SCharles.Forsyth if ( !cur ) 1446*37da2899SCharles.Forsyth return FT_Err_Invalid_CharMap_Handle; 1447*37da2899SCharles.Forsyth 1448*37da2899SCharles.Forsyth limit = cur + face->num_charmaps; 1449*37da2899SCharles.Forsyth 1450*37da2899SCharles.Forsyth for ( ; cur < limit; cur++ ) 1451*37da2899SCharles.Forsyth { 1452*37da2899SCharles.Forsyth if ( cur[0]->encoding == encoding ) 1453*37da2899SCharles.Forsyth { 1454*37da2899SCharles.Forsyth face->charmap = cur[0]; 1455*37da2899SCharles.Forsyth return 0; 1456*37da2899SCharles.Forsyth } 1457*37da2899SCharles.Forsyth } 1458*37da2899SCharles.Forsyth 1459*37da2899SCharles.Forsyth return FT_Err_Invalid_Argument; 1460*37da2899SCharles.Forsyth } 1461*37da2899SCharles.Forsyth 1462*37da2899SCharles.Forsyth 1463*37da2899SCharles.Forsyth /* documentation is in freetype.h */ 1464*37da2899SCharles.Forsyth 1465*37da2899SCharles.Forsyth FT_EXPORT_DEF( FT_Error ) FT_Set_Charmap(FT_Face face,FT_CharMap charmap)1466*37da2899SCharles.Forsyth FT_Set_Charmap( FT_Face face, 1467*37da2899SCharles.Forsyth FT_CharMap charmap ) 1468*37da2899SCharles.Forsyth { 1469*37da2899SCharles.Forsyth FT_CharMap* cur; 1470*37da2899SCharles.Forsyth FT_CharMap* limit; 1471*37da2899SCharles.Forsyth 1472*37da2899SCharles.Forsyth 1473*37da2899SCharles.Forsyth if ( !face ) 1474*37da2899SCharles.Forsyth return FT_Err_Invalid_Face_Handle; 1475*37da2899SCharles.Forsyth 1476*37da2899SCharles.Forsyth cur = face->charmaps; 1477*37da2899SCharles.Forsyth if ( !cur ) 1478*37da2899SCharles.Forsyth return FT_Err_Invalid_CharMap_Handle; 1479*37da2899SCharles.Forsyth 1480*37da2899SCharles.Forsyth limit = cur + face->num_charmaps; 1481*37da2899SCharles.Forsyth 1482*37da2899SCharles.Forsyth for ( ; cur < limit; cur++ ) 1483*37da2899SCharles.Forsyth { 1484*37da2899SCharles.Forsyth if ( cur[0] == charmap ) 1485*37da2899SCharles.Forsyth { 1486*37da2899SCharles.Forsyth face->charmap = cur[0]; 1487*37da2899SCharles.Forsyth return 0; 1488*37da2899SCharles.Forsyth } 1489*37da2899SCharles.Forsyth } 1490*37da2899SCharles.Forsyth return FT_Err_Invalid_Argument; 1491*37da2899SCharles.Forsyth } 1492*37da2899SCharles.Forsyth 1493*37da2899SCharles.Forsyth 1494*37da2899SCharles.Forsyth FT_BASE_DEF( void ) FT_CMap_Done(FT_CMap cmap)1495*37da2899SCharles.Forsyth FT_CMap_Done( FT_CMap cmap ) 1496*37da2899SCharles.Forsyth { 1497*37da2899SCharles.Forsyth if ( cmap ) 1498*37da2899SCharles.Forsyth { 1499*37da2899SCharles.Forsyth FT_CMap_Class clazz = cmap->clazz; 1500*37da2899SCharles.Forsyth FT_Face face = cmap->charmap.face; 1501*37da2899SCharles.Forsyth FT_Memory memory = FT_FACE_MEMORY(face); 1502*37da2899SCharles.Forsyth 1503*37da2899SCharles.Forsyth 1504*37da2899SCharles.Forsyth if ( clazz->done ) 1505*37da2899SCharles.Forsyth clazz->done( cmap ); 1506*37da2899SCharles.Forsyth 1507*37da2899SCharles.Forsyth FT_FREE( cmap ); 1508*37da2899SCharles.Forsyth } 1509*37da2899SCharles.Forsyth } 1510*37da2899SCharles.Forsyth 1511*37da2899SCharles.Forsyth 1512*37da2899SCharles.Forsyth FT_BASE_DEF( FT_Error ) FT_CMap_New(FT_CMap_Class clazz,FT_Pointer init_data,FT_CharMap charmap,FT_CMap * acmap)1513*37da2899SCharles.Forsyth FT_CMap_New( FT_CMap_Class clazz, 1514*37da2899SCharles.Forsyth FT_Pointer init_data, 1515*37da2899SCharles.Forsyth FT_CharMap charmap, 1516*37da2899SCharles.Forsyth FT_CMap *acmap ) 1517*37da2899SCharles.Forsyth { 1518*37da2899SCharles.Forsyth FT_Error error = 0; 1519*37da2899SCharles.Forsyth FT_Face face; 1520*37da2899SCharles.Forsyth FT_Memory memory; 1521*37da2899SCharles.Forsyth FT_CMap cmap; 1522*37da2899SCharles.Forsyth 1523*37da2899SCharles.Forsyth 1524*37da2899SCharles.Forsyth if ( clazz == NULL || charmap == NULL || charmap->face == NULL ) 1525*37da2899SCharles.Forsyth return FT_Err_Invalid_Argument; 1526*37da2899SCharles.Forsyth 1527*37da2899SCharles.Forsyth face = charmap->face; 1528*37da2899SCharles.Forsyth memory = FT_FACE_MEMORY(face); 1529*37da2899SCharles.Forsyth 1530*37da2899SCharles.Forsyth if ( !FT_ALLOC( cmap, clazz->size ) ) 1531*37da2899SCharles.Forsyth { 1532*37da2899SCharles.Forsyth cmap->charmap = *charmap; 1533*37da2899SCharles.Forsyth cmap->clazz = clazz; 1534*37da2899SCharles.Forsyth 1535*37da2899SCharles.Forsyth if ( clazz->init ) 1536*37da2899SCharles.Forsyth { 1537*37da2899SCharles.Forsyth error = clazz->init( cmap, init_data ); 1538*37da2899SCharles.Forsyth if ( error ) 1539*37da2899SCharles.Forsyth goto Fail; 1540*37da2899SCharles.Forsyth } 1541*37da2899SCharles.Forsyth 1542*37da2899SCharles.Forsyth /* add it to our list of charmaps */ 1543*37da2899SCharles.Forsyth if ( FT_RENEW_ARRAY( face->charmaps, 1544*37da2899SCharles.Forsyth face->num_charmaps, 1545*37da2899SCharles.Forsyth face->num_charmaps+1 ) ) 1546*37da2899SCharles.Forsyth goto Fail; 1547*37da2899SCharles.Forsyth 1548*37da2899SCharles.Forsyth face->charmaps[face->num_charmaps++] = (FT_CharMap)cmap; 1549*37da2899SCharles.Forsyth } 1550*37da2899SCharles.Forsyth 1551*37da2899SCharles.Forsyth Exit: 1552*37da2899SCharles.Forsyth if ( acmap ) 1553*37da2899SCharles.Forsyth *acmap = cmap; 1554*37da2899SCharles.Forsyth 1555*37da2899SCharles.Forsyth return error; 1556*37da2899SCharles.Forsyth 1557*37da2899SCharles.Forsyth Fail: 1558*37da2899SCharles.Forsyth FT_CMap_Done( cmap ); 1559*37da2899SCharles.Forsyth cmap = NULL; 1560*37da2899SCharles.Forsyth goto Exit; 1561*37da2899SCharles.Forsyth } 1562*37da2899SCharles.Forsyth 1563*37da2899SCharles.Forsyth 1564*37da2899SCharles.Forsyth /* documentation is in freetype.h */ 1565*37da2899SCharles.Forsyth 1566*37da2899SCharles.Forsyth FT_EXPORT_DEF( FT_UInt ) FT_Get_Char_Index(FT_Face face,FT_ULong charcode)1567*37da2899SCharles.Forsyth FT_Get_Char_Index( FT_Face face, 1568*37da2899SCharles.Forsyth FT_ULong charcode ) 1569*37da2899SCharles.Forsyth { 1570*37da2899SCharles.Forsyth FT_UInt result = 0; 1571*37da2899SCharles.Forsyth 1572*37da2899SCharles.Forsyth 1573*37da2899SCharles.Forsyth if ( face && face->charmap ) 1574*37da2899SCharles.Forsyth { 1575*37da2899SCharles.Forsyth FT_CMap cmap = FT_CMAP( face->charmap ); 1576*37da2899SCharles.Forsyth 1577*37da2899SCharles.Forsyth 1578*37da2899SCharles.Forsyth result = cmap->clazz->char_index( cmap, charcode ); 1579*37da2899SCharles.Forsyth } 1580*37da2899SCharles.Forsyth return result; 1581*37da2899SCharles.Forsyth } 1582*37da2899SCharles.Forsyth 1583*37da2899SCharles.Forsyth 1584*37da2899SCharles.Forsyth 1585*37da2899SCharles.Forsyth /* documentation is in freetype.h */ 1586*37da2899SCharles.Forsyth 1587*37da2899SCharles.Forsyth FT_EXPORT_DEF( FT_ULong ) FT_Get_First_Char(FT_Face face,FT_UInt * agindex)1588*37da2899SCharles.Forsyth FT_Get_First_Char( FT_Face face, 1589*37da2899SCharles.Forsyth FT_UInt *agindex ) 1590*37da2899SCharles.Forsyth { 1591*37da2899SCharles.Forsyth FT_ULong result = 0; 1592*37da2899SCharles.Forsyth FT_UInt gindex = 0; 1593*37da2899SCharles.Forsyth 1594*37da2899SCharles.Forsyth 1595*37da2899SCharles.Forsyth if ( face && face->charmap ) 1596*37da2899SCharles.Forsyth { 1597*37da2899SCharles.Forsyth gindex = FT_Get_Char_Index( face, 0 ); 1598*37da2899SCharles.Forsyth if ( gindex == 0 ) 1599*37da2899SCharles.Forsyth result = FT_Get_Next_Char( face, 0, &gindex ); 1600*37da2899SCharles.Forsyth } 1601*37da2899SCharles.Forsyth 1602*37da2899SCharles.Forsyth if ( agindex ) 1603*37da2899SCharles.Forsyth *agindex = gindex; 1604*37da2899SCharles.Forsyth 1605*37da2899SCharles.Forsyth return result; 1606*37da2899SCharles.Forsyth } 1607*37da2899SCharles.Forsyth 1608*37da2899SCharles.Forsyth /* documentation is in freetype.h */ 1609*37da2899SCharles.Forsyth 1610*37da2899SCharles.Forsyth 1611*37da2899SCharles.Forsyth FT_EXPORT_DEF( FT_ULong ) FT_Get_Next_Char(FT_Face face,FT_ULong charcode,FT_UInt * agindex)1612*37da2899SCharles.Forsyth FT_Get_Next_Char( FT_Face face, 1613*37da2899SCharles.Forsyth FT_ULong charcode, 1614*37da2899SCharles.Forsyth FT_UInt *agindex ) 1615*37da2899SCharles.Forsyth { 1616*37da2899SCharles.Forsyth FT_ULong result = 0; 1617*37da2899SCharles.Forsyth FT_UInt gindex = 0; 1618*37da2899SCharles.Forsyth 1619*37da2899SCharles.Forsyth 1620*37da2899SCharles.Forsyth if ( face && face->charmap ) 1621*37da2899SCharles.Forsyth { 1622*37da2899SCharles.Forsyth FT_UInt32 code = (FT_UInt32)charcode; 1623*37da2899SCharles.Forsyth FT_CMap cmap = FT_CMAP( face->charmap ); 1624*37da2899SCharles.Forsyth 1625*37da2899SCharles.Forsyth 1626*37da2899SCharles.Forsyth gindex = cmap->clazz->char_next( cmap, &code ); 1627*37da2899SCharles.Forsyth result = ( gindex == 0 ) ? 0 : code; 1628*37da2899SCharles.Forsyth } 1629*37da2899SCharles.Forsyth 1630*37da2899SCharles.Forsyth if ( agindex ) 1631*37da2899SCharles.Forsyth *agindex = gindex; 1632*37da2899SCharles.Forsyth 1633*37da2899SCharles.Forsyth return result; 1634*37da2899SCharles.Forsyth } 1635*37da2899SCharles.Forsyth 1636*37da2899SCharles.Forsyth 1637*37da2899SCharles.Forsyth 1638*37da2899SCharles.Forsyth /* documentation is in freetype.h */ 1639*37da2899SCharles.Forsyth 1640*37da2899SCharles.Forsyth FT_EXPORT_DEF( FT_UInt ) FT_Get_Name_Index(FT_Face face,FT_String * glyph_name)1641*37da2899SCharles.Forsyth FT_Get_Name_Index( FT_Face face, 1642*37da2899SCharles.Forsyth FT_String* glyph_name ) 1643*37da2899SCharles.Forsyth { 1644*37da2899SCharles.Forsyth FT_UInt result = 0; 1645*37da2899SCharles.Forsyth 1646*37da2899SCharles.Forsyth 1647*37da2899SCharles.Forsyth if ( face && FT_HAS_GLYPH_NAMES( face ) ) 1648*37da2899SCharles.Forsyth { 1649*37da2899SCharles.Forsyth /* now, lookup for glyph name */ 1650*37da2899SCharles.Forsyth FT_Driver driver = face->driver; 1651*37da2899SCharles.Forsyth FT_Module_Class* clazz = FT_MODULE_CLASS( driver ); 1652*37da2899SCharles.Forsyth 1653*37da2899SCharles.Forsyth 1654*37da2899SCharles.Forsyth if ( clazz->get_interface ) 1655*37da2899SCharles.Forsyth { 1656*37da2899SCharles.Forsyth FT_Face_GetGlyphNameIndexFunc requester; 1657*37da2899SCharles.Forsyth 1658*37da2899SCharles.Forsyth 1659*37da2899SCharles.Forsyth requester = (FT_Face_GetGlyphNameIndexFunc)clazz->get_interface( 1660*37da2899SCharles.Forsyth FT_MODULE( driver ), "name_index" ); 1661*37da2899SCharles.Forsyth if ( requester ) 1662*37da2899SCharles.Forsyth result = requester( face, glyph_name ); 1663*37da2899SCharles.Forsyth } 1664*37da2899SCharles.Forsyth } 1665*37da2899SCharles.Forsyth 1666*37da2899SCharles.Forsyth return result; 1667*37da2899SCharles.Forsyth } 1668*37da2899SCharles.Forsyth 1669*37da2899SCharles.Forsyth 1670*37da2899SCharles.Forsyth /* documentation is in freetype.h */ 1671*37da2899SCharles.Forsyth 1672*37da2899SCharles.Forsyth FT_EXPORT_DEF( FT_Error ) FT_Get_Glyph_Name(FT_Face face,FT_UInt glyph_index,FT_Pointer buffer,FT_UInt buffer_max)1673*37da2899SCharles.Forsyth FT_Get_Glyph_Name( FT_Face face, 1674*37da2899SCharles.Forsyth FT_UInt glyph_index, 1675*37da2899SCharles.Forsyth FT_Pointer buffer, 1676*37da2899SCharles.Forsyth FT_UInt buffer_max ) 1677*37da2899SCharles.Forsyth { 1678*37da2899SCharles.Forsyth FT_Error error = FT_Err_Invalid_Argument; 1679*37da2899SCharles.Forsyth 1680*37da2899SCharles.Forsyth 1681*37da2899SCharles.Forsyth /* clean up buffer */ 1682*37da2899SCharles.Forsyth if ( buffer && buffer_max > 0 ) 1683*37da2899SCharles.Forsyth ((FT_Byte*)buffer)[0] = 0; 1684*37da2899SCharles.Forsyth 1685*37da2899SCharles.Forsyth if ( face && 1686*37da2899SCharles.Forsyth glyph_index <= (FT_UInt)face->num_glyphs && 1687*37da2899SCharles.Forsyth FT_HAS_GLYPH_NAMES( face ) ) 1688*37da2899SCharles.Forsyth { 1689*37da2899SCharles.Forsyth /* now, lookup for glyph name */ 1690*37da2899SCharles.Forsyth FT_Driver driver = face->driver; 1691*37da2899SCharles.Forsyth FT_Module_Class* clazz = FT_MODULE_CLASS( driver ); 1692*37da2899SCharles.Forsyth 1693*37da2899SCharles.Forsyth 1694*37da2899SCharles.Forsyth if ( clazz->get_interface ) 1695*37da2899SCharles.Forsyth { 1696*37da2899SCharles.Forsyth FT_Face_GetGlyphNameFunc requester; 1697*37da2899SCharles.Forsyth 1698*37da2899SCharles.Forsyth 1699*37da2899SCharles.Forsyth requester = (FT_Face_GetGlyphNameFunc)clazz->get_interface( 1700*37da2899SCharles.Forsyth FT_MODULE( driver ), "glyph_name" ); 1701*37da2899SCharles.Forsyth if ( requester ) 1702*37da2899SCharles.Forsyth error = requester( face, glyph_index, buffer, buffer_max ); 1703*37da2899SCharles.Forsyth } 1704*37da2899SCharles.Forsyth } 1705*37da2899SCharles.Forsyth 1706*37da2899SCharles.Forsyth return error; 1707*37da2899SCharles.Forsyth } 1708*37da2899SCharles.Forsyth 1709*37da2899SCharles.Forsyth 1710*37da2899SCharles.Forsyth /* documentation is in freetype.h */ 1711*37da2899SCharles.Forsyth 1712*37da2899SCharles.Forsyth FT_EXPORT_DEF( const char* ) FT_Get_Postscript_Name(FT_Face face)1713*37da2899SCharles.Forsyth FT_Get_Postscript_Name( FT_Face face ) 1714*37da2899SCharles.Forsyth { 1715*37da2899SCharles.Forsyth const char* result = NULL; 1716*37da2899SCharles.Forsyth 1717*37da2899SCharles.Forsyth 1718*37da2899SCharles.Forsyth if ( !face ) 1719*37da2899SCharles.Forsyth goto Exit; 1720*37da2899SCharles.Forsyth 1721*37da2899SCharles.Forsyth result = face->internal->postscript_name; 1722*37da2899SCharles.Forsyth if ( !result ) 1723*37da2899SCharles.Forsyth { 1724*37da2899SCharles.Forsyth /* now, look up glyph name */ 1725*37da2899SCharles.Forsyth FT_Driver driver = face->driver; 1726*37da2899SCharles.Forsyth FT_Module_Class* clazz = FT_MODULE_CLASS( driver ); 1727*37da2899SCharles.Forsyth 1728*37da2899SCharles.Forsyth 1729*37da2899SCharles.Forsyth if ( clazz->get_interface ) 1730*37da2899SCharles.Forsyth { 1731*37da2899SCharles.Forsyth FT_Face_GetPostscriptNameFunc requester; 1732*37da2899SCharles.Forsyth 1733*37da2899SCharles.Forsyth 1734*37da2899SCharles.Forsyth requester = (FT_Face_GetPostscriptNameFunc)clazz->get_interface( 1735*37da2899SCharles.Forsyth FT_MODULE( driver ), "postscript_name" ); 1736*37da2899SCharles.Forsyth if ( requester ) 1737*37da2899SCharles.Forsyth result = requester( face ); 1738*37da2899SCharles.Forsyth } 1739*37da2899SCharles.Forsyth } 1740*37da2899SCharles.Forsyth Exit: 1741*37da2899SCharles.Forsyth return result; 1742*37da2899SCharles.Forsyth } 1743*37da2899SCharles.Forsyth 1744*37da2899SCharles.Forsyth 1745*37da2899SCharles.Forsyth /* documentation is in tttables.h */ 1746*37da2899SCharles.Forsyth 1747*37da2899SCharles.Forsyth FT_EXPORT_DEF( void* ) FT_Get_Sfnt_Table(FT_Face face,FT_Sfnt_Tag tag)1748*37da2899SCharles.Forsyth FT_Get_Sfnt_Table( FT_Face face, 1749*37da2899SCharles.Forsyth FT_Sfnt_Tag tag ) 1750*37da2899SCharles.Forsyth { 1751*37da2899SCharles.Forsyth void* table = 0; 1752*37da2899SCharles.Forsyth FT_Get_Sfnt_Table_Func func; 1753*37da2899SCharles.Forsyth FT_Driver driver; 1754*37da2899SCharles.Forsyth 1755*37da2899SCharles.Forsyth 1756*37da2899SCharles.Forsyth if ( !face || !FT_IS_SFNT( face ) ) 1757*37da2899SCharles.Forsyth goto Exit; 1758*37da2899SCharles.Forsyth 1759*37da2899SCharles.Forsyth driver = face->driver; 1760*37da2899SCharles.Forsyth func = (FT_Get_Sfnt_Table_Func)driver->root.clazz->get_interface( 1761*37da2899SCharles.Forsyth FT_MODULE( driver ), "get_sfnt" ); 1762*37da2899SCharles.Forsyth if ( func ) 1763*37da2899SCharles.Forsyth table = func( face, tag ); 1764*37da2899SCharles.Forsyth 1765*37da2899SCharles.Forsyth Exit: 1766*37da2899SCharles.Forsyth return table; 1767*37da2899SCharles.Forsyth } 1768*37da2899SCharles.Forsyth 1769*37da2899SCharles.Forsyth 1770*37da2899SCharles.Forsyth FT_EXPORT_DEF( FT_Error ) FT_Activate_Size(FT_Size size)1771*37da2899SCharles.Forsyth FT_Activate_Size( FT_Size size ) 1772*37da2899SCharles.Forsyth { 1773*37da2899SCharles.Forsyth FT_Face face; 1774*37da2899SCharles.Forsyth 1775*37da2899SCharles.Forsyth 1776*37da2899SCharles.Forsyth if ( size == NULL ) 1777*37da2899SCharles.Forsyth return FT_Err_Bad_Argument; 1778*37da2899SCharles.Forsyth 1779*37da2899SCharles.Forsyth face = size->face; 1780*37da2899SCharles.Forsyth if ( face == NULL || face->driver == NULL ) 1781*37da2899SCharles.Forsyth return FT_Err_Bad_Argument; 1782*37da2899SCharles.Forsyth 1783*37da2899SCharles.Forsyth /* we don't need anything more complex than that; all size objects */ 1784*37da2899SCharles.Forsyth /* are already listed by the face */ 1785*37da2899SCharles.Forsyth face->size = size; 1786*37da2899SCharles.Forsyth 1787*37da2899SCharles.Forsyth return FT_Err_Ok; 1788*37da2899SCharles.Forsyth } 1789*37da2899SCharles.Forsyth 1790*37da2899SCharles.Forsyth 1791*37da2899SCharles.Forsyth /*************************************************************************/ 1792*37da2899SCharles.Forsyth /*************************************************************************/ 1793*37da2899SCharles.Forsyth /*************************************************************************/ 1794*37da2899SCharles.Forsyth /**** ****/ 1795*37da2899SCharles.Forsyth /**** ****/ 1796*37da2899SCharles.Forsyth /**** R E N D E R E R S ****/ 1797*37da2899SCharles.Forsyth /**** ****/ 1798*37da2899SCharles.Forsyth /**** ****/ 1799*37da2899SCharles.Forsyth /*************************************************************************/ 1800*37da2899SCharles.Forsyth /*************************************************************************/ 1801*37da2899SCharles.Forsyth /*************************************************************************/ 1802*37da2899SCharles.Forsyth 1803*37da2899SCharles.Forsyth /* lookup a renderer by glyph format in the library's list */ 1804*37da2899SCharles.Forsyth FT_BASE_DEF( FT_Renderer ) FT_Lookup_Renderer(FT_Library library,FT_Glyph_Format format,FT_ListNode * node)1805*37da2899SCharles.Forsyth FT_Lookup_Renderer( FT_Library library, 1806*37da2899SCharles.Forsyth FT_Glyph_Format format, 1807*37da2899SCharles.Forsyth FT_ListNode* node ) 1808*37da2899SCharles.Forsyth { 1809*37da2899SCharles.Forsyth FT_ListNode cur; 1810*37da2899SCharles.Forsyth FT_Renderer result = 0; 1811*37da2899SCharles.Forsyth 1812*37da2899SCharles.Forsyth 1813*37da2899SCharles.Forsyth if ( !library ) 1814*37da2899SCharles.Forsyth goto Exit; 1815*37da2899SCharles.Forsyth 1816*37da2899SCharles.Forsyth cur = library->renderers.head; 1817*37da2899SCharles.Forsyth 1818*37da2899SCharles.Forsyth if ( node ) 1819*37da2899SCharles.Forsyth { 1820*37da2899SCharles.Forsyth if ( *node ) 1821*37da2899SCharles.Forsyth cur = (*node)->next; 1822*37da2899SCharles.Forsyth *node = 0; 1823*37da2899SCharles.Forsyth } 1824*37da2899SCharles.Forsyth 1825*37da2899SCharles.Forsyth while ( cur ) 1826*37da2899SCharles.Forsyth { 1827*37da2899SCharles.Forsyth FT_Renderer renderer = FT_RENDERER( cur->data ); 1828*37da2899SCharles.Forsyth 1829*37da2899SCharles.Forsyth 1830*37da2899SCharles.Forsyth if ( renderer->glyph_format == format ) 1831*37da2899SCharles.Forsyth { 1832*37da2899SCharles.Forsyth if ( node ) 1833*37da2899SCharles.Forsyth *node = cur; 1834*37da2899SCharles.Forsyth 1835*37da2899SCharles.Forsyth result = renderer; 1836*37da2899SCharles.Forsyth break; 1837*37da2899SCharles.Forsyth } 1838*37da2899SCharles.Forsyth cur = cur->next; 1839*37da2899SCharles.Forsyth } 1840*37da2899SCharles.Forsyth 1841*37da2899SCharles.Forsyth Exit: 1842*37da2899SCharles.Forsyth return result; 1843*37da2899SCharles.Forsyth } 1844*37da2899SCharles.Forsyth 1845*37da2899SCharles.Forsyth 1846*37da2899SCharles.Forsyth static FT_Renderer ft_lookup_glyph_renderer(FT_GlyphSlot slot)1847*37da2899SCharles.Forsyth ft_lookup_glyph_renderer( FT_GlyphSlot slot ) 1848*37da2899SCharles.Forsyth { 1849*37da2899SCharles.Forsyth FT_Face face = slot->face; 1850*37da2899SCharles.Forsyth FT_Library library = FT_FACE_LIBRARY( face ); 1851*37da2899SCharles.Forsyth FT_Renderer result = library->cur_renderer; 1852*37da2899SCharles.Forsyth 1853*37da2899SCharles.Forsyth 1854*37da2899SCharles.Forsyth if ( !result || result->glyph_format != slot->format ) 1855*37da2899SCharles.Forsyth result = FT_Lookup_Renderer( library, slot->format, 0 ); 1856*37da2899SCharles.Forsyth 1857*37da2899SCharles.Forsyth return result; 1858*37da2899SCharles.Forsyth } 1859*37da2899SCharles.Forsyth 1860*37da2899SCharles.Forsyth 1861*37da2899SCharles.Forsyth static void ft_set_current_renderer(FT_Library library)1862*37da2899SCharles.Forsyth ft_set_current_renderer( FT_Library library ) 1863*37da2899SCharles.Forsyth { 1864*37da2899SCharles.Forsyth FT_Renderer renderer; 1865*37da2899SCharles.Forsyth 1866*37da2899SCharles.Forsyth 1867*37da2899SCharles.Forsyth renderer = FT_Lookup_Renderer( library, FT_GLYPH_FORMAT_OUTLINE, 0 ); 1868*37da2899SCharles.Forsyth library->cur_renderer = renderer; 1869*37da2899SCharles.Forsyth } 1870*37da2899SCharles.Forsyth 1871*37da2899SCharles.Forsyth 1872*37da2899SCharles.Forsyth static FT_Error ft_add_renderer(FT_Module module)1873*37da2899SCharles.Forsyth ft_add_renderer( FT_Module module ) 1874*37da2899SCharles.Forsyth { 1875*37da2899SCharles.Forsyth FT_Library library = module->library; 1876*37da2899SCharles.Forsyth FT_Memory memory = library->memory; 1877*37da2899SCharles.Forsyth FT_Error error; 1878*37da2899SCharles.Forsyth FT_ListNode node; 1879*37da2899SCharles.Forsyth 1880*37da2899SCharles.Forsyth 1881*37da2899SCharles.Forsyth if ( FT_NEW( node ) ) 1882*37da2899SCharles.Forsyth goto Exit; 1883*37da2899SCharles.Forsyth 1884*37da2899SCharles.Forsyth { 1885*37da2899SCharles.Forsyth FT_Renderer render = FT_RENDERER( module ); 1886*37da2899SCharles.Forsyth FT_Renderer_Class* clazz = (FT_Renderer_Class*)module->clazz; 1887*37da2899SCharles.Forsyth 1888*37da2899SCharles.Forsyth 1889*37da2899SCharles.Forsyth render->clazz = clazz; 1890*37da2899SCharles.Forsyth render->glyph_format = clazz->glyph_format; 1891*37da2899SCharles.Forsyth 1892*37da2899SCharles.Forsyth /* allocate raster object if needed */ 1893*37da2899SCharles.Forsyth if ( clazz->glyph_format == FT_GLYPH_FORMAT_OUTLINE && 1894*37da2899SCharles.Forsyth clazz->raster_class->raster_new ) 1895*37da2899SCharles.Forsyth { 1896*37da2899SCharles.Forsyth error = clazz->raster_class->raster_new( memory, &render->raster ); 1897*37da2899SCharles.Forsyth if ( error ) 1898*37da2899SCharles.Forsyth goto Fail; 1899*37da2899SCharles.Forsyth 1900*37da2899SCharles.Forsyth render->raster_render = clazz->raster_class->raster_render; 1901*37da2899SCharles.Forsyth render->render = clazz->render_glyph; 1902*37da2899SCharles.Forsyth } 1903*37da2899SCharles.Forsyth 1904*37da2899SCharles.Forsyth /* add to list */ 1905*37da2899SCharles.Forsyth node->data = module; 1906*37da2899SCharles.Forsyth FT_List_Add( &library->renderers, node ); 1907*37da2899SCharles.Forsyth 1908*37da2899SCharles.Forsyth ft_set_current_renderer( library ); 1909*37da2899SCharles.Forsyth } 1910*37da2899SCharles.Forsyth 1911*37da2899SCharles.Forsyth Fail: 1912*37da2899SCharles.Forsyth if ( error ) 1913*37da2899SCharles.Forsyth FT_FREE( node ); 1914*37da2899SCharles.Forsyth 1915*37da2899SCharles.Forsyth Exit: 1916*37da2899SCharles.Forsyth return error; 1917*37da2899SCharles.Forsyth } 1918*37da2899SCharles.Forsyth 1919*37da2899SCharles.Forsyth 1920*37da2899SCharles.Forsyth static void ft_remove_renderer(FT_Module module)1921*37da2899SCharles.Forsyth ft_remove_renderer( FT_Module module ) 1922*37da2899SCharles.Forsyth { 1923*37da2899SCharles.Forsyth FT_Library library = module->library; 1924*37da2899SCharles.Forsyth FT_Memory memory = library->memory; 1925*37da2899SCharles.Forsyth FT_ListNode node; 1926*37da2899SCharles.Forsyth 1927*37da2899SCharles.Forsyth 1928*37da2899SCharles.Forsyth node = FT_List_Find( &library->renderers, module ); 1929*37da2899SCharles.Forsyth if ( node ) 1930*37da2899SCharles.Forsyth { 1931*37da2899SCharles.Forsyth FT_Renderer render = FT_RENDERER( module ); 1932*37da2899SCharles.Forsyth 1933*37da2899SCharles.Forsyth 1934*37da2899SCharles.Forsyth /* release raster object, if any */ 1935*37da2899SCharles.Forsyth if ( render->raster ) 1936*37da2899SCharles.Forsyth render->clazz->raster_class->raster_done( render->raster ); 1937*37da2899SCharles.Forsyth 1938*37da2899SCharles.Forsyth /* remove from list */ 1939*37da2899SCharles.Forsyth FT_List_Remove( &library->renderers, node ); 1940*37da2899SCharles.Forsyth FT_FREE( node ); 1941*37da2899SCharles.Forsyth 1942*37da2899SCharles.Forsyth ft_set_current_renderer( library ); 1943*37da2899SCharles.Forsyth } 1944*37da2899SCharles.Forsyth } 1945*37da2899SCharles.Forsyth 1946*37da2899SCharles.Forsyth 1947*37da2899SCharles.Forsyth /* documentation is in ftrender.h */ 1948*37da2899SCharles.Forsyth 1949*37da2899SCharles.Forsyth FT_EXPORT_DEF( FT_Renderer ) FT_Get_Renderer(FT_Library library,FT_Glyph_Format format)1950*37da2899SCharles.Forsyth FT_Get_Renderer( FT_Library library, 1951*37da2899SCharles.Forsyth FT_Glyph_Format format ) 1952*37da2899SCharles.Forsyth { 1953*37da2899SCharles.Forsyth /* test for valid `library' delayed to FT_Lookup_Renderer() */ 1954*37da2899SCharles.Forsyth 1955*37da2899SCharles.Forsyth return FT_Lookup_Renderer( library, format, 0 ); 1956*37da2899SCharles.Forsyth } 1957*37da2899SCharles.Forsyth 1958*37da2899SCharles.Forsyth 1959*37da2899SCharles.Forsyth /* documentation is in ftrender.h */ 1960*37da2899SCharles.Forsyth 1961*37da2899SCharles.Forsyth FT_EXPORT_DEF( FT_Error ) FT_Set_Renderer(FT_Library library,FT_Renderer renderer,FT_UInt num_params,FT_Parameter * parameters)1962*37da2899SCharles.Forsyth FT_Set_Renderer( FT_Library library, 1963*37da2899SCharles.Forsyth FT_Renderer renderer, 1964*37da2899SCharles.Forsyth FT_UInt num_params, 1965*37da2899SCharles.Forsyth FT_Parameter* parameters ) 1966*37da2899SCharles.Forsyth { 1967*37da2899SCharles.Forsyth FT_ListNode node; 1968*37da2899SCharles.Forsyth FT_Error error = FT_Err_Ok; 1969*37da2899SCharles.Forsyth 1970*37da2899SCharles.Forsyth 1971*37da2899SCharles.Forsyth if ( !library ) 1972*37da2899SCharles.Forsyth return FT_Err_Invalid_Library_Handle; 1973*37da2899SCharles.Forsyth 1974*37da2899SCharles.Forsyth if ( !renderer ) 1975*37da2899SCharles.Forsyth return FT_Err_Invalid_Argument; 1976*37da2899SCharles.Forsyth 1977*37da2899SCharles.Forsyth node = FT_List_Find( &library->renderers, renderer ); 1978*37da2899SCharles.Forsyth if ( !node ) 1979*37da2899SCharles.Forsyth { 1980*37da2899SCharles.Forsyth error = FT_Err_Invalid_Argument; 1981*37da2899SCharles.Forsyth goto Exit; 1982*37da2899SCharles.Forsyth } 1983*37da2899SCharles.Forsyth 1984*37da2899SCharles.Forsyth FT_List_Up( &library->renderers, node ); 1985*37da2899SCharles.Forsyth 1986*37da2899SCharles.Forsyth if ( renderer->glyph_format == FT_GLYPH_FORMAT_OUTLINE ) 1987*37da2899SCharles.Forsyth library->cur_renderer = renderer; 1988*37da2899SCharles.Forsyth 1989*37da2899SCharles.Forsyth if ( num_params > 0 ) 1990*37da2899SCharles.Forsyth { 1991*37da2899SCharles.Forsyth FT_Renderer_SetModeFunc set_mode = renderer->clazz->set_mode; 1992*37da2899SCharles.Forsyth 1993*37da2899SCharles.Forsyth 1994*37da2899SCharles.Forsyth for ( ; num_params > 0; num_params-- ) 1995*37da2899SCharles.Forsyth { 1996*37da2899SCharles.Forsyth error = set_mode( renderer, parameters->tag, parameters->data ); 1997*37da2899SCharles.Forsyth if ( error ) 1998*37da2899SCharles.Forsyth break; 1999*37da2899SCharles.Forsyth } 2000*37da2899SCharles.Forsyth } 2001*37da2899SCharles.Forsyth 2002*37da2899SCharles.Forsyth Exit: 2003*37da2899SCharles.Forsyth return error; 2004*37da2899SCharles.Forsyth } 2005*37da2899SCharles.Forsyth 2006*37da2899SCharles.Forsyth 2007*37da2899SCharles.Forsyth FT_BASE_DEF( FT_Error ) FT_Render_Glyph_Internal(FT_Library library,FT_GlyphSlot slot,FT_Render_Mode render_mode)2008*37da2899SCharles.Forsyth FT_Render_Glyph_Internal( FT_Library library, 2009*37da2899SCharles.Forsyth FT_GlyphSlot slot, 2010*37da2899SCharles.Forsyth FT_Render_Mode render_mode ) 2011*37da2899SCharles.Forsyth { 2012*37da2899SCharles.Forsyth FT_Error error = FT_Err_Ok; 2013*37da2899SCharles.Forsyth FT_Renderer renderer; 2014*37da2899SCharles.Forsyth 2015*37da2899SCharles.Forsyth 2016*37da2899SCharles.Forsyth /* if it is already a bitmap, no need to do anything */ 2017*37da2899SCharles.Forsyth switch ( slot->format ) 2018*37da2899SCharles.Forsyth { 2019*37da2899SCharles.Forsyth case FT_GLYPH_FORMAT_BITMAP: /* already a bitmap, don't do anything */ 2020*37da2899SCharles.Forsyth break; 2021*37da2899SCharles.Forsyth 2022*37da2899SCharles.Forsyth default: 2023*37da2899SCharles.Forsyth { 2024*37da2899SCharles.Forsyth FT_ListNode node = 0; 2025*37da2899SCharles.Forsyth FT_Bool update = 0; 2026*37da2899SCharles.Forsyth 2027*37da2899SCharles.Forsyth 2028*37da2899SCharles.Forsyth /* small shortcut for the very common case */ 2029*37da2899SCharles.Forsyth if ( slot->format == FT_GLYPH_FORMAT_OUTLINE ) 2030*37da2899SCharles.Forsyth { 2031*37da2899SCharles.Forsyth renderer = library->cur_renderer; 2032*37da2899SCharles.Forsyth node = library->renderers.head; 2033*37da2899SCharles.Forsyth } 2034*37da2899SCharles.Forsyth else 2035*37da2899SCharles.Forsyth renderer = FT_Lookup_Renderer( library, slot->format, &node ); 2036*37da2899SCharles.Forsyth 2037*37da2899SCharles.Forsyth error = FT_Err_Unimplemented_Feature; 2038*37da2899SCharles.Forsyth while ( renderer ) 2039*37da2899SCharles.Forsyth { 2040*37da2899SCharles.Forsyth error = renderer->render( renderer, slot, render_mode, NULL ); 2041*37da2899SCharles.Forsyth if ( !error || 2042*37da2899SCharles.Forsyth FT_ERROR_BASE( error ) != FT_Err_Cannot_Render_Glyph ) 2043*37da2899SCharles.Forsyth break; 2044*37da2899SCharles.Forsyth 2045*37da2899SCharles.Forsyth /* FT_Err_Cannot_Render_Glyph is returned if the render mode */ 2046*37da2899SCharles.Forsyth /* is unsupported by the current renderer for this glyph image */ 2047*37da2899SCharles.Forsyth /* format. */ 2048*37da2899SCharles.Forsyth 2049*37da2899SCharles.Forsyth /* now, look for another renderer that supports the same */ 2050*37da2899SCharles.Forsyth /* format. */ 2051*37da2899SCharles.Forsyth renderer = FT_Lookup_Renderer( library, slot->format, &node ); 2052*37da2899SCharles.Forsyth update = 1; 2053*37da2899SCharles.Forsyth } 2054*37da2899SCharles.Forsyth 2055*37da2899SCharles.Forsyth /* if we changed the current renderer for the glyph image format */ 2056*37da2899SCharles.Forsyth /* we need to select it as the next current one */ 2057*37da2899SCharles.Forsyth if ( !error && update && renderer ) 2058*37da2899SCharles.Forsyth FT_Set_Renderer( library, renderer, 0, 0 ); 2059*37da2899SCharles.Forsyth } 2060*37da2899SCharles.Forsyth } 2061*37da2899SCharles.Forsyth 2062*37da2899SCharles.Forsyth return error; 2063*37da2899SCharles.Forsyth } 2064*37da2899SCharles.Forsyth 2065*37da2899SCharles.Forsyth 2066*37da2899SCharles.Forsyth /* documentation is in freetype.h */ 2067*37da2899SCharles.Forsyth 2068*37da2899SCharles.Forsyth FT_EXPORT_DEF( FT_Error ) FT_Render_Glyph(FT_GlyphSlot slot,FT_Render_Mode render_mode)2069*37da2899SCharles.Forsyth FT_Render_Glyph( FT_GlyphSlot slot, 2070*37da2899SCharles.Forsyth FT_Render_Mode render_mode ) 2071*37da2899SCharles.Forsyth { 2072*37da2899SCharles.Forsyth FT_Library library; 2073*37da2899SCharles.Forsyth 2074*37da2899SCharles.Forsyth 2075*37da2899SCharles.Forsyth if ( !slot ) 2076*37da2899SCharles.Forsyth return FT_Err_Invalid_Argument; 2077*37da2899SCharles.Forsyth 2078*37da2899SCharles.Forsyth library = FT_FACE_LIBRARY( slot->face ); 2079*37da2899SCharles.Forsyth 2080*37da2899SCharles.Forsyth return FT_Render_Glyph_Internal( library, slot, render_mode ); 2081*37da2899SCharles.Forsyth } 2082*37da2899SCharles.Forsyth 2083*37da2899SCharles.Forsyth 2084*37da2899SCharles.Forsyth /*************************************************************************/ 2085*37da2899SCharles.Forsyth /*************************************************************************/ 2086*37da2899SCharles.Forsyth /*************************************************************************/ 2087*37da2899SCharles.Forsyth /**** ****/ 2088*37da2899SCharles.Forsyth /**** ****/ 2089*37da2899SCharles.Forsyth /**** M O D U L E S ****/ 2090*37da2899SCharles.Forsyth /**** ****/ 2091*37da2899SCharles.Forsyth /**** ****/ 2092*37da2899SCharles.Forsyth /*************************************************************************/ 2093*37da2899SCharles.Forsyth /*************************************************************************/ 2094*37da2899SCharles.Forsyth /*************************************************************************/ 2095*37da2899SCharles.Forsyth 2096*37da2899SCharles.Forsyth 2097*37da2899SCharles.Forsyth /*************************************************************************/ 2098*37da2899SCharles.Forsyth /* */ 2099*37da2899SCharles.Forsyth /* <Function> */ 2100*37da2899SCharles.Forsyth /* Destroy_Module */ 2101*37da2899SCharles.Forsyth /* */ 2102*37da2899SCharles.Forsyth /* <Description> */ 2103*37da2899SCharles.Forsyth /* Destroys a given module object. For drivers, this also destroys */ 2104*37da2899SCharles.Forsyth /* all child faces. */ 2105*37da2899SCharles.Forsyth /* */ 2106*37da2899SCharles.Forsyth /* <InOut> */ 2107*37da2899SCharles.Forsyth /* module :: A handle to the target driver object. */ 2108*37da2899SCharles.Forsyth /* */ 2109*37da2899SCharles.Forsyth /* <Note> */ 2110*37da2899SCharles.Forsyth /* The driver _must_ be LOCKED! */ 2111*37da2899SCharles.Forsyth /* */ 2112*37da2899SCharles.Forsyth static void Destroy_Module(FT_Module module)2113*37da2899SCharles.Forsyth Destroy_Module( FT_Module module ) 2114*37da2899SCharles.Forsyth { 2115*37da2899SCharles.Forsyth FT_Memory memory = module->memory; 2116*37da2899SCharles.Forsyth FT_Module_Class* clazz = module->clazz; 2117*37da2899SCharles.Forsyth FT_Library library = module->library; 2118*37da2899SCharles.Forsyth 2119*37da2899SCharles.Forsyth 2120*37da2899SCharles.Forsyth /* finalize client-data - before anything else */ 2121*37da2899SCharles.Forsyth if ( module->generic.finalizer ) 2122*37da2899SCharles.Forsyth module->generic.finalizer( module ); 2123*37da2899SCharles.Forsyth 2124*37da2899SCharles.Forsyth if ( library && library->auto_hinter == module ) 2125*37da2899SCharles.Forsyth library->auto_hinter = 0; 2126*37da2899SCharles.Forsyth 2127*37da2899SCharles.Forsyth /* if the module is a renderer */ 2128*37da2899SCharles.Forsyth if ( FT_MODULE_IS_RENDERER( module ) ) 2129*37da2899SCharles.Forsyth ft_remove_renderer( module ); 2130*37da2899SCharles.Forsyth 2131*37da2899SCharles.Forsyth /* if the module is a font driver, add some steps */ 2132*37da2899SCharles.Forsyth if ( FT_MODULE_IS_DRIVER( module ) ) 2133*37da2899SCharles.Forsyth Destroy_Driver( FT_DRIVER( module ) ); 2134*37da2899SCharles.Forsyth 2135*37da2899SCharles.Forsyth /* finalize the module object */ 2136*37da2899SCharles.Forsyth if ( clazz->module_done ) 2137*37da2899SCharles.Forsyth clazz->module_done( module ); 2138*37da2899SCharles.Forsyth 2139*37da2899SCharles.Forsyth /* discard it */ 2140*37da2899SCharles.Forsyth FT_FREE( module ); 2141*37da2899SCharles.Forsyth } 2142*37da2899SCharles.Forsyth 2143*37da2899SCharles.Forsyth 2144*37da2899SCharles.Forsyth /* documentation is in ftmodule.h */ 2145*37da2899SCharles.Forsyth 2146*37da2899SCharles.Forsyth FT_EXPORT_DEF( FT_Error ) FT_Add_Module(FT_Library library,const FT_Module_Class * clazz)2147*37da2899SCharles.Forsyth FT_Add_Module( FT_Library library, 2148*37da2899SCharles.Forsyth const FT_Module_Class* clazz ) 2149*37da2899SCharles.Forsyth { 2150*37da2899SCharles.Forsyth FT_Error error; 2151*37da2899SCharles.Forsyth FT_Memory memory; 2152*37da2899SCharles.Forsyth FT_Module module; 2153*37da2899SCharles.Forsyth FT_UInt nn; 2154*37da2899SCharles.Forsyth 2155*37da2899SCharles.Forsyth 2156*37da2899SCharles.Forsyth #define FREETYPE_VER_FIXED ( ( (FT_Long)FREETYPE_MAJOR << 16 ) | \ 2157*37da2899SCharles.Forsyth FREETYPE_MINOR ) 2158*37da2899SCharles.Forsyth 2159*37da2899SCharles.Forsyth if ( !library ) 2160*37da2899SCharles.Forsyth return FT_Err_Invalid_Library_Handle; 2161*37da2899SCharles.Forsyth 2162*37da2899SCharles.Forsyth if ( !clazz ) 2163*37da2899SCharles.Forsyth return FT_Err_Invalid_Argument; 2164*37da2899SCharles.Forsyth 2165*37da2899SCharles.Forsyth /* check freetype version */ 2166*37da2899SCharles.Forsyth if ( clazz->module_requires > FREETYPE_VER_FIXED ) 2167*37da2899SCharles.Forsyth return FT_Err_Invalid_Version; 2168*37da2899SCharles.Forsyth 2169*37da2899SCharles.Forsyth /* look for a module with the same name in the library's table */ 2170*37da2899SCharles.Forsyth for ( nn = 0; nn < library->num_modules; nn++ ) 2171*37da2899SCharles.Forsyth { 2172*37da2899SCharles.Forsyth module = library->modules[nn]; 2173*37da2899SCharles.Forsyth if ( ft_strcmp( module->clazz->module_name, clazz->module_name ) == 0 ) 2174*37da2899SCharles.Forsyth { 2175*37da2899SCharles.Forsyth /* this installed module has the same name, compare their versions */ 2176*37da2899SCharles.Forsyth if ( clazz->module_version <= module->clazz->module_version ) 2177*37da2899SCharles.Forsyth return FT_Err_Lower_Module_Version; 2178*37da2899SCharles.Forsyth 2179*37da2899SCharles.Forsyth /* remove the module from our list, then exit the loop to replace */ 2180*37da2899SCharles.Forsyth /* it by our new version.. */ 2181*37da2899SCharles.Forsyth FT_Remove_Module( library, module ); 2182*37da2899SCharles.Forsyth break; 2183*37da2899SCharles.Forsyth } 2184*37da2899SCharles.Forsyth } 2185*37da2899SCharles.Forsyth 2186*37da2899SCharles.Forsyth memory = library->memory; 2187*37da2899SCharles.Forsyth error = FT_Err_Ok; 2188*37da2899SCharles.Forsyth 2189*37da2899SCharles.Forsyth if ( library->num_modules >= FT_MAX_MODULES ) 2190*37da2899SCharles.Forsyth { 2191*37da2899SCharles.Forsyth error = FT_Err_Too_Many_Drivers; 2192*37da2899SCharles.Forsyth goto Exit; 2193*37da2899SCharles.Forsyth } 2194*37da2899SCharles.Forsyth 2195*37da2899SCharles.Forsyth /* allocate module object */ 2196*37da2899SCharles.Forsyth if ( FT_ALLOC( module, clazz->module_size ) ) 2197*37da2899SCharles.Forsyth goto Exit; 2198*37da2899SCharles.Forsyth 2199*37da2899SCharles.Forsyth /* base initialization */ 2200*37da2899SCharles.Forsyth module->library = library; 2201*37da2899SCharles.Forsyth module->memory = memory; 2202*37da2899SCharles.Forsyth module->clazz = (FT_Module_Class*)clazz; 2203*37da2899SCharles.Forsyth 2204*37da2899SCharles.Forsyth /* check whether the module is a renderer - this must be performed */ 2205*37da2899SCharles.Forsyth /* before the normal module initialization */ 2206*37da2899SCharles.Forsyth if ( FT_MODULE_IS_RENDERER( module ) ) 2207*37da2899SCharles.Forsyth { 2208*37da2899SCharles.Forsyth /* add to the renderers list */ 2209*37da2899SCharles.Forsyth error = ft_add_renderer( module ); 2210*37da2899SCharles.Forsyth if ( error ) 2211*37da2899SCharles.Forsyth goto Fail; 2212*37da2899SCharles.Forsyth } 2213*37da2899SCharles.Forsyth 2214*37da2899SCharles.Forsyth /* is the module a auto-hinter? */ 2215*37da2899SCharles.Forsyth if ( FT_MODULE_IS_HINTER( module ) ) 2216*37da2899SCharles.Forsyth library->auto_hinter = module; 2217*37da2899SCharles.Forsyth 2218*37da2899SCharles.Forsyth /* if the module is a font driver */ 2219*37da2899SCharles.Forsyth if ( FT_MODULE_IS_DRIVER( module ) ) 2220*37da2899SCharles.Forsyth { 2221*37da2899SCharles.Forsyth /* allocate glyph loader if needed */ 2222*37da2899SCharles.Forsyth FT_Driver driver = FT_DRIVER( module ); 2223*37da2899SCharles.Forsyth 2224*37da2899SCharles.Forsyth 2225*37da2899SCharles.Forsyth driver->clazz = (FT_Driver_Class)module->clazz; 2226*37da2899SCharles.Forsyth if ( FT_DRIVER_USES_OUTLINES( driver ) ) 2227*37da2899SCharles.Forsyth { 2228*37da2899SCharles.Forsyth error = FT_GlyphLoader_New( memory, &driver->glyph_loader ); 2229*37da2899SCharles.Forsyth if ( error ) 2230*37da2899SCharles.Forsyth goto Fail; 2231*37da2899SCharles.Forsyth } 2232*37da2899SCharles.Forsyth } 2233*37da2899SCharles.Forsyth 2234*37da2899SCharles.Forsyth if ( clazz->module_init ) 2235*37da2899SCharles.Forsyth { 2236*37da2899SCharles.Forsyth error = clazz->module_init( module ); 2237*37da2899SCharles.Forsyth if ( error ) 2238*37da2899SCharles.Forsyth goto Fail; 2239*37da2899SCharles.Forsyth } 2240*37da2899SCharles.Forsyth 2241*37da2899SCharles.Forsyth /* add module to the library's table */ 2242*37da2899SCharles.Forsyth library->modules[library->num_modules++] = module; 2243*37da2899SCharles.Forsyth 2244*37da2899SCharles.Forsyth Exit: 2245*37da2899SCharles.Forsyth return error; 2246*37da2899SCharles.Forsyth 2247*37da2899SCharles.Forsyth Fail: 2248*37da2899SCharles.Forsyth if ( FT_MODULE_IS_DRIVER( module ) ) 2249*37da2899SCharles.Forsyth { 2250*37da2899SCharles.Forsyth FT_Driver driver = FT_DRIVER( module ); 2251*37da2899SCharles.Forsyth 2252*37da2899SCharles.Forsyth 2253*37da2899SCharles.Forsyth if ( FT_DRIVER_USES_OUTLINES( driver ) ) 2254*37da2899SCharles.Forsyth FT_GlyphLoader_Done( driver->glyph_loader ); 2255*37da2899SCharles.Forsyth } 2256*37da2899SCharles.Forsyth 2257*37da2899SCharles.Forsyth if ( FT_MODULE_IS_RENDERER( module ) ) 2258*37da2899SCharles.Forsyth { 2259*37da2899SCharles.Forsyth FT_Renderer renderer = FT_RENDERER( module ); 2260*37da2899SCharles.Forsyth 2261*37da2899SCharles.Forsyth 2262*37da2899SCharles.Forsyth if ( renderer->raster ) 2263*37da2899SCharles.Forsyth renderer->clazz->raster_class->raster_done( renderer->raster ); 2264*37da2899SCharles.Forsyth } 2265*37da2899SCharles.Forsyth 2266*37da2899SCharles.Forsyth FT_FREE( module ); 2267*37da2899SCharles.Forsyth goto Exit; 2268*37da2899SCharles.Forsyth } 2269*37da2899SCharles.Forsyth 2270*37da2899SCharles.Forsyth 2271*37da2899SCharles.Forsyth /* documentation is in ftmodule.h */ 2272*37da2899SCharles.Forsyth 2273*37da2899SCharles.Forsyth FT_EXPORT_DEF( FT_Module ) FT_Get_Module(FT_Library library,const char * module_name)2274*37da2899SCharles.Forsyth FT_Get_Module( FT_Library library, 2275*37da2899SCharles.Forsyth const char* module_name ) 2276*37da2899SCharles.Forsyth { 2277*37da2899SCharles.Forsyth FT_Module result = 0; 2278*37da2899SCharles.Forsyth FT_Module* cur; 2279*37da2899SCharles.Forsyth FT_Module* limit; 2280*37da2899SCharles.Forsyth 2281*37da2899SCharles.Forsyth 2282*37da2899SCharles.Forsyth if ( !library || !module_name ) 2283*37da2899SCharles.Forsyth return result; 2284*37da2899SCharles.Forsyth 2285*37da2899SCharles.Forsyth cur = library->modules; 2286*37da2899SCharles.Forsyth limit = cur + library->num_modules; 2287*37da2899SCharles.Forsyth 2288*37da2899SCharles.Forsyth for ( ; cur < limit; cur++ ) 2289*37da2899SCharles.Forsyth if ( ft_strcmp( cur[0]->clazz->module_name, module_name ) == 0 ) 2290*37da2899SCharles.Forsyth { 2291*37da2899SCharles.Forsyth result = cur[0]; 2292*37da2899SCharles.Forsyth break; 2293*37da2899SCharles.Forsyth } 2294*37da2899SCharles.Forsyth 2295*37da2899SCharles.Forsyth return result; 2296*37da2899SCharles.Forsyth } 2297*37da2899SCharles.Forsyth 2298*37da2899SCharles.Forsyth 2299*37da2899SCharles.Forsyth /* documentation is in ftobjs.h */ 2300*37da2899SCharles.Forsyth 2301*37da2899SCharles.Forsyth FT_BASE_DEF( const void* ) FT_Get_Module_Interface(FT_Library library,const char * mod_name)2302*37da2899SCharles.Forsyth FT_Get_Module_Interface( FT_Library library, 2303*37da2899SCharles.Forsyth const char* mod_name ) 2304*37da2899SCharles.Forsyth { 2305*37da2899SCharles.Forsyth FT_Module module; 2306*37da2899SCharles.Forsyth 2307*37da2899SCharles.Forsyth 2308*37da2899SCharles.Forsyth /* test for valid `library' delayed to FT_Get_Module() */ 2309*37da2899SCharles.Forsyth 2310*37da2899SCharles.Forsyth module = FT_Get_Module( library, mod_name ); 2311*37da2899SCharles.Forsyth 2312*37da2899SCharles.Forsyth return module ? module->clazz->module_interface : 0; 2313*37da2899SCharles.Forsyth } 2314*37da2899SCharles.Forsyth 2315*37da2899SCharles.Forsyth 2316*37da2899SCharles.Forsyth /* documentation is in ftmodule.h */ 2317*37da2899SCharles.Forsyth 2318*37da2899SCharles.Forsyth FT_EXPORT_DEF( FT_Error ) FT_Remove_Module(FT_Library library,FT_Module module)2319*37da2899SCharles.Forsyth FT_Remove_Module( FT_Library library, 2320*37da2899SCharles.Forsyth FT_Module module ) 2321*37da2899SCharles.Forsyth { 2322*37da2899SCharles.Forsyth /* try to find the module from the table, then remove it from there */ 2323*37da2899SCharles.Forsyth 2324*37da2899SCharles.Forsyth if ( !library ) 2325*37da2899SCharles.Forsyth return FT_Err_Invalid_Library_Handle; 2326*37da2899SCharles.Forsyth 2327*37da2899SCharles.Forsyth if ( module ) 2328*37da2899SCharles.Forsyth { 2329*37da2899SCharles.Forsyth FT_Module* cur = library->modules; 2330*37da2899SCharles.Forsyth FT_Module* limit = cur + library->num_modules; 2331*37da2899SCharles.Forsyth 2332*37da2899SCharles.Forsyth 2333*37da2899SCharles.Forsyth for ( ; cur < limit; cur++ ) 2334*37da2899SCharles.Forsyth { 2335*37da2899SCharles.Forsyth if ( cur[0] == module ) 2336*37da2899SCharles.Forsyth { 2337*37da2899SCharles.Forsyth /* remove it from the table */ 2338*37da2899SCharles.Forsyth library->num_modules--; 2339*37da2899SCharles.Forsyth limit--; 2340*37da2899SCharles.Forsyth while ( cur < limit ) 2341*37da2899SCharles.Forsyth { 2342*37da2899SCharles.Forsyth cur[0] = cur[1]; 2343*37da2899SCharles.Forsyth cur++; 2344*37da2899SCharles.Forsyth } 2345*37da2899SCharles.Forsyth limit[0] = 0; 2346*37da2899SCharles.Forsyth 2347*37da2899SCharles.Forsyth /* destroy the module */ 2348*37da2899SCharles.Forsyth Destroy_Module( module ); 2349*37da2899SCharles.Forsyth 2350*37da2899SCharles.Forsyth return FT_Err_Ok; 2351*37da2899SCharles.Forsyth } 2352*37da2899SCharles.Forsyth } 2353*37da2899SCharles.Forsyth } 2354*37da2899SCharles.Forsyth return FT_Err_Invalid_Driver_Handle; 2355*37da2899SCharles.Forsyth } 2356*37da2899SCharles.Forsyth 2357*37da2899SCharles.Forsyth 2358*37da2899SCharles.Forsyth /*************************************************************************/ 2359*37da2899SCharles.Forsyth /*************************************************************************/ 2360*37da2899SCharles.Forsyth /*************************************************************************/ 2361*37da2899SCharles.Forsyth /**** ****/ 2362*37da2899SCharles.Forsyth /**** ****/ 2363*37da2899SCharles.Forsyth /**** L I B R A R Y ****/ 2364*37da2899SCharles.Forsyth /**** ****/ 2365*37da2899SCharles.Forsyth /**** ****/ 2366*37da2899SCharles.Forsyth /*************************************************************************/ 2367*37da2899SCharles.Forsyth /*************************************************************************/ 2368*37da2899SCharles.Forsyth /*************************************************************************/ 2369*37da2899SCharles.Forsyth 2370*37da2899SCharles.Forsyth 2371*37da2899SCharles.Forsyth /* documentation is in ftmodule.h */ 2372*37da2899SCharles.Forsyth 2373*37da2899SCharles.Forsyth FT_EXPORT_DEF( FT_Error ) FT_New_Library(FT_Memory memory,FT_Library * alibrary)2374*37da2899SCharles.Forsyth FT_New_Library( FT_Memory memory, 2375*37da2899SCharles.Forsyth FT_Library *alibrary ) 2376*37da2899SCharles.Forsyth { 2377*37da2899SCharles.Forsyth FT_Library library = 0; 2378*37da2899SCharles.Forsyth FT_Error error; 2379*37da2899SCharles.Forsyth 2380*37da2899SCharles.Forsyth 2381*37da2899SCharles.Forsyth if ( !memory ) 2382*37da2899SCharles.Forsyth return FT_Err_Invalid_Argument; 2383*37da2899SCharles.Forsyth 2384*37da2899SCharles.Forsyth #ifdef FT_DEBUG_LEVEL_ERROR 2385*37da2899SCharles.Forsyth /* init debugging support */ 2386*37da2899SCharles.Forsyth ft_debug_init(); 2387*37da2899SCharles.Forsyth #endif 2388*37da2899SCharles.Forsyth 2389*37da2899SCharles.Forsyth /* first of all, allocate the library object */ 2390*37da2899SCharles.Forsyth if ( FT_NEW( library ) ) 2391*37da2899SCharles.Forsyth return error; 2392*37da2899SCharles.Forsyth 2393*37da2899SCharles.Forsyth library->memory = memory; 2394*37da2899SCharles.Forsyth 2395*37da2899SCharles.Forsyth /* allocate the render pool */ 2396*37da2899SCharles.Forsyth library->raster_pool_size = FT_RENDER_POOL_SIZE; 2397*37da2899SCharles.Forsyth if ( FT_ALLOC( library->raster_pool, FT_RENDER_POOL_SIZE ) ) 2398*37da2899SCharles.Forsyth goto Fail; 2399*37da2899SCharles.Forsyth 2400*37da2899SCharles.Forsyth /* That's ok now */ 2401*37da2899SCharles.Forsyth *alibrary = library; 2402*37da2899SCharles.Forsyth 2403*37da2899SCharles.Forsyth return FT_Err_Ok; 2404*37da2899SCharles.Forsyth 2405*37da2899SCharles.Forsyth Fail: 2406*37da2899SCharles.Forsyth FT_FREE( library ); 2407*37da2899SCharles.Forsyth return error; 2408*37da2899SCharles.Forsyth } 2409*37da2899SCharles.Forsyth 2410*37da2899SCharles.Forsyth 2411*37da2899SCharles.Forsyth /* documentation is in freetype.h */ 2412*37da2899SCharles.Forsyth 2413*37da2899SCharles.Forsyth FT_EXPORT_DEF( void ) FT_Library_Version(FT_Library library,FT_Int * amajor,FT_Int * aminor,FT_Int * apatch)2414*37da2899SCharles.Forsyth FT_Library_Version( FT_Library library, 2415*37da2899SCharles.Forsyth FT_Int *amajor, 2416*37da2899SCharles.Forsyth FT_Int *aminor, 2417*37da2899SCharles.Forsyth FT_Int *apatch ) 2418*37da2899SCharles.Forsyth { 2419*37da2899SCharles.Forsyth FT_Int major = 0; 2420*37da2899SCharles.Forsyth FT_Int minor = 0; 2421*37da2899SCharles.Forsyth FT_Int patch = 0; 2422*37da2899SCharles.Forsyth 2423*37da2899SCharles.Forsyth 2424*37da2899SCharles.Forsyth if ( library ) 2425*37da2899SCharles.Forsyth { 2426*37da2899SCharles.Forsyth major = library->version_major; 2427*37da2899SCharles.Forsyth minor = library->version_minor; 2428*37da2899SCharles.Forsyth patch = library->version_patch; 2429*37da2899SCharles.Forsyth } 2430*37da2899SCharles.Forsyth 2431*37da2899SCharles.Forsyth if ( amajor ) 2432*37da2899SCharles.Forsyth *amajor = major; 2433*37da2899SCharles.Forsyth 2434*37da2899SCharles.Forsyth if ( aminor ) 2435*37da2899SCharles.Forsyth *aminor = minor; 2436*37da2899SCharles.Forsyth 2437*37da2899SCharles.Forsyth if ( apatch ) 2438*37da2899SCharles.Forsyth *apatch = patch; 2439*37da2899SCharles.Forsyth } 2440*37da2899SCharles.Forsyth 2441*37da2899SCharles.Forsyth 2442*37da2899SCharles.Forsyth /* documentation is in ftmodule.h */ 2443*37da2899SCharles.Forsyth 2444*37da2899SCharles.Forsyth FT_EXPORT_DEF( FT_Error ) FT_Done_Library(FT_Library library)2445*37da2899SCharles.Forsyth FT_Done_Library( FT_Library library ) 2446*37da2899SCharles.Forsyth { 2447*37da2899SCharles.Forsyth FT_Memory memory; 2448*37da2899SCharles.Forsyth 2449*37da2899SCharles.Forsyth 2450*37da2899SCharles.Forsyth if ( !library ) 2451*37da2899SCharles.Forsyth return FT_Err_Invalid_Library_Handle; 2452*37da2899SCharles.Forsyth 2453*37da2899SCharles.Forsyth memory = library->memory; 2454*37da2899SCharles.Forsyth 2455*37da2899SCharles.Forsyth /* Discard client-data */ 2456*37da2899SCharles.Forsyth if ( library->generic.finalizer ) 2457*37da2899SCharles.Forsyth library->generic.finalizer( library ); 2458*37da2899SCharles.Forsyth 2459*37da2899SCharles.Forsyth /* Close all modules in the library */ 2460*37da2899SCharles.Forsyth #if 1 2461*37da2899SCharles.Forsyth while ( library->num_modules > 0 ) 2462*37da2899SCharles.Forsyth FT_Remove_Module( library, library->modules[0] ); 2463*37da2899SCharles.Forsyth #else 2464*37da2899SCharles.Forsyth { 2465*37da2899SCharles.Forsyth FT_UInt n; 2466*37da2899SCharles.Forsyth 2467*37da2899SCharles.Forsyth 2468*37da2899SCharles.Forsyth for ( n = 0; n < library->num_modules; n++ ) 2469*37da2899SCharles.Forsyth { 2470*37da2899SCharles.Forsyth FT_Module module = library->modules[n]; 2471*37da2899SCharles.Forsyth 2472*37da2899SCharles.Forsyth 2473*37da2899SCharles.Forsyth if ( module ) 2474*37da2899SCharles.Forsyth { 2475*37da2899SCharles.Forsyth Destroy_Module( module ); 2476*37da2899SCharles.Forsyth library->modules[n] = 0; 2477*37da2899SCharles.Forsyth } 2478*37da2899SCharles.Forsyth } 2479*37da2899SCharles.Forsyth } 2480*37da2899SCharles.Forsyth #endif 2481*37da2899SCharles.Forsyth 2482*37da2899SCharles.Forsyth /* Destroy raster objects */ 2483*37da2899SCharles.Forsyth FT_FREE( library->raster_pool ); 2484*37da2899SCharles.Forsyth library->raster_pool_size = 0; 2485*37da2899SCharles.Forsyth 2486*37da2899SCharles.Forsyth FT_FREE( library ); 2487*37da2899SCharles.Forsyth return FT_Err_Ok; 2488*37da2899SCharles.Forsyth } 2489*37da2899SCharles.Forsyth 2490*37da2899SCharles.Forsyth 2491*37da2899SCharles.Forsyth /* documentation is in ftmodule.h */ 2492*37da2899SCharles.Forsyth 2493*37da2899SCharles.Forsyth FT_EXPORT_DEF( void ) FT_Set_Debug_Hook(FT_Library library,FT_UInt hook_index,FT_DebugHook_Func debug_hook)2494*37da2899SCharles.Forsyth FT_Set_Debug_Hook( FT_Library library, 2495*37da2899SCharles.Forsyth FT_UInt hook_index, 2496*37da2899SCharles.Forsyth FT_DebugHook_Func debug_hook ) 2497*37da2899SCharles.Forsyth { 2498*37da2899SCharles.Forsyth if ( library && debug_hook && 2499*37da2899SCharles.Forsyth hook_index < 2500*37da2899SCharles.Forsyth ( sizeof ( library->debug_hooks ) / sizeof ( void* ) ) ) 2501*37da2899SCharles.Forsyth library->debug_hooks[hook_index] = debug_hook; 2502*37da2899SCharles.Forsyth } 2503*37da2899SCharles.Forsyth 2504*37da2899SCharles.Forsyth 2505*37da2899SCharles.Forsyth /* END */ 2506