1*37da2899SCharles.Forsyth /***************************************************************************/ 2*37da2899SCharles.Forsyth /* */ 3*37da2899SCharles.Forsyth /* ftcsbits.c */ 4*37da2899SCharles.Forsyth /* */ 5*37da2899SCharles.Forsyth /* FreeType sbits manager (body). */ 6*37da2899SCharles.Forsyth /* */ 7*37da2899SCharles.Forsyth /* Copyright 2000-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_CACHE_H 21*37da2899SCharles.Forsyth #include FT_CACHE_SMALL_BITMAPS_H 22*37da2899SCharles.Forsyth #include FT_CACHE_INTERNAL_GLYPH_H 23*37da2899SCharles.Forsyth #include FT_INTERNAL_OBJECTS_H 24*37da2899SCharles.Forsyth #include FT_INTERNAL_DEBUG_H 25*37da2899SCharles.Forsyth #include FT_ERRORS_H 26*37da2899SCharles.Forsyth 27*37da2899SCharles.Forsyth #include "ftcerror.h" 28*37da2899SCharles.Forsyth 29*37da2899SCharles.Forsyth 30*37da2899SCharles.Forsyth #define FTC_SBIT_ITEMS_PER_NODE 16 31*37da2899SCharles.Forsyth 32*37da2899SCharles.Forsyth 33*37da2899SCharles.Forsyth typedef struct FTC_SBitNodeRec_* FTC_SBitNode; 34*37da2899SCharles.Forsyth 35*37da2899SCharles.Forsyth typedef struct FTC_SBitNodeRec_ 36*37da2899SCharles.Forsyth { 37*37da2899SCharles.Forsyth FTC_GlyphNodeRec gnode; 38*37da2899SCharles.Forsyth FTC_SBitRec sbits[FTC_SBIT_ITEMS_PER_NODE]; 39*37da2899SCharles.Forsyth 40*37da2899SCharles.Forsyth } FTC_SBitNodeRec; 41*37da2899SCharles.Forsyth 42*37da2899SCharles.Forsyth 43*37da2899SCharles.Forsyth #define FTC_SBIT_NODE( x ) ( (FTC_SBitNode)( x ) ) 44*37da2899SCharles.Forsyth 45*37da2899SCharles.Forsyth 46*37da2899SCharles.Forsyth typedef struct FTC_SBitQueryRec_ 47*37da2899SCharles.Forsyth { 48*37da2899SCharles.Forsyth FTC_GlyphQueryRec gquery; 49*37da2899SCharles.Forsyth FTC_ImageTypeRec type; 50*37da2899SCharles.Forsyth 51*37da2899SCharles.Forsyth } FTC_SBitQueryRec, *FTC_SBitQuery; 52*37da2899SCharles.Forsyth 53*37da2899SCharles.Forsyth 54*37da2899SCharles.Forsyth #define FTC_SBIT_QUERY( x ) ( (FTC_SBitQuery)( x ) ) 55*37da2899SCharles.Forsyth 56*37da2899SCharles.Forsyth 57*37da2899SCharles.Forsyth typedef struct FTC_SBitFamilyRec_* FTC_SBitFamily; 58*37da2899SCharles.Forsyth 59*37da2899SCharles.Forsyth /* sbit family structure */ 60*37da2899SCharles.Forsyth typedef struct FTC_SBitFamilyRec_ 61*37da2899SCharles.Forsyth { 62*37da2899SCharles.Forsyth FTC_GlyphFamilyRec gfam; 63*37da2899SCharles.Forsyth FTC_ImageTypeRec type; 64*37da2899SCharles.Forsyth 65*37da2899SCharles.Forsyth } FTC_SBitFamilyRec; 66*37da2899SCharles.Forsyth 67*37da2899SCharles.Forsyth 68*37da2899SCharles.Forsyth #define FTC_SBIT_FAMILY( x ) ( (FTC_SBitFamily)( x ) ) 69*37da2899SCharles.Forsyth #define FTC_SBIT_FAMILY_MEMORY( x ) FTC_GLYPH_FAMILY_MEMORY( &( x )->cset ) 70*37da2899SCharles.Forsyth 71*37da2899SCharles.Forsyth 72*37da2899SCharles.Forsyth /*************************************************************************/ 73*37da2899SCharles.Forsyth /*************************************************************************/ 74*37da2899SCharles.Forsyth /***** *****/ 75*37da2899SCharles.Forsyth /***** SBIT CACHE NODES *****/ 76*37da2899SCharles.Forsyth /***** *****/ 77*37da2899SCharles.Forsyth /*************************************************************************/ 78*37da2899SCharles.Forsyth /*************************************************************************/ 79*37da2899SCharles.Forsyth 80*37da2899SCharles.Forsyth 81*37da2899SCharles.Forsyth static FT_Error ftc_sbit_copy_bitmap(FTC_SBit sbit,FT_Bitmap * bitmap,FT_Memory memory)82*37da2899SCharles.Forsyth ftc_sbit_copy_bitmap( FTC_SBit sbit, 83*37da2899SCharles.Forsyth FT_Bitmap* bitmap, 84*37da2899SCharles.Forsyth FT_Memory memory ) 85*37da2899SCharles.Forsyth { 86*37da2899SCharles.Forsyth FT_Error error; 87*37da2899SCharles.Forsyth FT_Int pitch = bitmap->pitch; 88*37da2899SCharles.Forsyth FT_ULong size; 89*37da2899SCharles.Forsyth 90*37da2899SCharles.Forsyth 91*37da2899SCharles.Forsyth if ( pitch < 0 ) 92*37da2899SCharles.Forsyth pitch = -pitch; 93*37da2899SCharles.Forsyth 94*37da2899SCharles.Forsyth size = (FT_ULong)( pitch * bitmap->rows ); 95*37da2899SCharles.Forsyth 96*37da2899SCharles.Forsyth if ( !FT_ALLOC( sbit->buffer, size ) ) 97*37da2899SCharles.Forsyth FT_MEM_COPY( sbit->buffer, bitmap->buffer, size ); 98*37da2899SCharles.Forsyth 99*37da2899SCharles.Forsyth return error; 100*37da2899SCharles.Forsyth } 101*37da2899SCharles.Forsyth 102*37da2899SCharles.Forsyth 103*37da2899SCharles.Forsyth FT_CALLBACK_DEF( void ) ftc_sbit_node_done(FTC_SBitNode snode,FTC_Cache cache)104*37da2899SCharles.Forsyth ftc_sbit_node_done( FTC_SBitNode snode, 105*37da2899SCharles.Forsyth FTC_Cache cache ) 106*37da2899SCharles.Forsyth { 107*37da2899SCharles.Forsyth FTC_SBit sbit = snode->sbits; 108*37da2899SCharles.Forsyth FT_UInt count = FTC_GLYPH_NODE( snode )->item_count; 109*37da2899SCharles.Forsyth FT_Memory memory = cache->memory; 110*37da2899SCharles.Forsyth 111*37da2899SCharles.Forsyth 112*37da2899SCharles.Forsyth for ( ; count > 0; sbit++, count-- ) 113*37da2899SCharles.Forsyth FT_FREE( sbit->buffer ); 114*37da2899SCharles.Forsyth 115*37da2899SCharles.Forsyth ftc_glyph_node_done( FTC_GLYPH_NODE( snode ), cache ); 116*37da2899SCharles.Forsyth } 117*37da2899SCharles.Forsyth 118*37da2899SCharles.Forsyth 119*37da2899SCharles.Forsyth static FT_Error ftc_sbit_node_load(FTC_SBitNode snode,FTC_Manager manager,FTC_SBitFamily sfam,FT_UInt gindex,FT_ULong * asize)120*37da2899SCharles.Forsyth ftc_sbit_node_load( FTC_SBitNode snode, 121*37da2899SCharles.Forsyth FTC_Manager manager, 122*37da2899SCharles.Forsyth FTC_SBitFamily sfam, 123*37da2899SCharles.Forsyth FT_UInt gindex, 124*37da2899SCharles.Forsyth FT_ULong *asize ) 125*37da2899SCharles.Forsyth { 126*37da2899SCharles.Forsyth FT_Error error; 127*37da2899SCharles.Forsyth FTC_GlyphNode gnode = FTC_GLYPH_NODE( snode ); 128*37da2899SCharles.Forsyth FT_Memory memory; 129*37da2899SCharles.Forsyth FT_Face face; 130*37da2899SCharles.Forsyth FT_Size size; 131*37da2899SCharles.Forsyth FTC_SBit sbit; 132*37da2899SCharles.Forsyth 133*37da2899SCharles.Forsyth 134*37da2899SCharles.Forsyth if ( gindex < (FT_UInt)gnode->item_start || 135*37da2899SCharles.Forsyth gindex >= (FT_UInt)gnode->item_start + gnode->item_count ) 136*37da2899SCharles.Forsyth { 137*37da2899SCharles.Forsyth FT_ERROR(( "ftc_sbit_node_load: invalid glyph index" )); 138*37da2899SCharles.Forsyth return FTC_Err_Invalid_Argument; 139*37da2899SCharles.Forsyth } 140*37da2899SCharles.Forsyth 141*37da2899SCharles.Forsyth memory = manager->library->memory; 142*37da2899SCharles.Forsyth 143*37da2899SCharles.Forsyth sbit = snode->sbits + ( gindex - gnode->item_start ); 144*37da2899SCharles.Forsyth 145*37da2899SCharles.Forsyth error = FTC_Manager_Lookup_Size( manager, &sfam->type.font, 146*37da2899SCharles.Forsyth &face, &size ); 147*37da2899SCharles.Forsyth if ( !error ) 148*37da2899SCharles.Forsyth { 149*37da2899SCharles.Forsyth /* by default, indicates a `missing' glyph */ 150*37da2899SCharles.Forsyth sbit->buffer = 0; 151*37da2899SCharles.Forsyth 152*37da2899SCharles.Forsyth error = FT_Load_Glyph( face, gindex, sfam->type.flags | FT_LOAD_RENDER ); 153*37da2899SCharles.Forsyth if ( !error ) 154*37da2899SCharles.Forsyth { 155*37da2899SCharles.Forsyth FT_Int temp; 156*37da2899SCharles.Forsyth FT_GlyphSlot slot = face->glyph; 157*37da2899SCharles.Forsyth FT_Bitmap* bitmap = &slot->bitmap; 158*37da2899SCharles.Forsyth FT_Int xadvance, yadvance; 159*37da2899SCharles.Forsyth 160*37da2899SCharles.Forsyth 161*37da2899SCharles.Forsyth /* check that our values fit into 8-bit containers! */ 162*37da2899SCharles.Forsyth /* If this is not the case, our bitmap is too large */ 163*37da2899SCharles.Forsyth /* and we will leave it as `missing' with sbit.buffer = 0 */ 164*37da2899SCharles.Forsyth 165*37da2899SCharles.Forsyth #define CHECK_CHAR( d ) ( temp = (FT_Char)d, temp == d ) 166*37da2899SCharles.Forsyth #define CHECK_BYTE( d ) ( temp = (FT_Byte)d, temp == d ) 167*37da2899SCharles.Forsyth 168*37da2899SCharles.Forsyth /* XXX: FIXME: add support for vertical layouts maybe */ 169*37da2899SCharles.Forsyth 170*37da2899SCharles.Forsyth /* horizontal advance in pixels */ 171*37da2899SCharles.Forsyth xadvance = ( slot->metrics.horiAdvance + 32 ) >> 6; 172*37da2899SCharles.Forsyth yadvance = ( slot->metrics.vertAdvance + 32 ) >> 6; 173*37da2899SCharles.Forsyth 174*37da2899SCharles.Forsyth if ( CHECK_BYTE( bitmap->rows ) && 175*37da2899SCharles.Forsyth CHECK_BYTE( bitmap->width ) && 176*37da2899SCharles.Forsyth CHECK_CHAR( bitmap->pitch ) && 177*37da2899SCharles.Forsyth CHECK_CHAR( slot->bitmap_left ) && 178*37da2899SCharles.Forsyth CHECK_CHAR( slot->bitmap_top ) && 179*37da2899SCharles.Forsyth CHECK_CHAR( xadvance ) && 180*37da2899SCharles.Forsyth CHECK_CHAR( yadvance ) ) 181*37da2899SCharles.Forsyth { 182*37da2899SCharles.Forsyth sbit->width = (FT_Byte)bitmap->width; 183*37da2899SCharles.Forsyth sbit->height = (FT_Byte)bitmap->rows; 184*37da2899SCharles.Forsyth sbit->pitch = (FT_Char)bitmap->pitch; 185*37da2899SCharles.Forsyth sbit->left = (FT_Char)slot->bitmap_left; 186*37da2899SCharles.Forsyth sbit->top = (FT_Char)slot->bitmap_top; 187*37da2899SCharles.Forsyth sbit->xadvance = (FT_Char)xadvance; 188*37da2899SCharles.Forsyth sbit->yadvance = (FT_Char)yadvance; 189*37da2899SCharles.Forsyth sbit->format = (FT_Byte)bitmap->pixel_mode; 190*37da2899SCharles.Forsyth sbit->max_grays = (FT_Byte)(bitmap->num_grays - 1); 191*37da2899SCharles.Forsyth 192*37da2899SCharles.Forsyth #if 0 /* this doesn't work well with embedded bitmaps !! */ 193*37da2899SCharles.Forsyth 194*37da2899SCharles.Forsyth /* grab the bitmap when possible - this is a hack! */ 195*37da2899SCharles.Forsyth if ( slot->flags & FT_GLYPH_OWN_BITMAP ) 196*37da2899SCharles.Forsyth { 197*37da2899SCharles.Forsyth slot->flags &= ~FT_GLYPH_OWN_BITMAP; 198*37da2899SCharles.Forsyth sbit->buffer = bitmap->buffer; 199*37da2899SCharles.Forsyth } 200*37da2899SCharles.Forsyth else 201*37da2899SCharles.Forsyth #endif 202*37da2899SCharles.Forsyth { 203*37da2899SCharles.Forsyth /* copy the bitmap into a new buffer -- ignore error */ 204*37da2899SCharles.Forsyth error = ftc_sbit_copy_bitmap( sbit, bitmap, memory ); 205*37da2899SCharles.Forsyth } 206*37da2899SCharles.Forsyth 207*37da2899SCharles.Forsyth /* now, compute size */ 208*37da2899SCharles.Forsyth if ( asize ) 209*37da2899SCharles.Forsyth *asize = ABS( sbit->pitch ) * sbit->height; 210*37da2899SCharles.Forsyth 211*37da2899SCharles.Forsyth } /* glyph dimensions ok */ 212*37da2899SCharles.Forsyth 213*37da2899SCharles.Forsyth } /* glyph loading successful */ 214*37da2899SCharles.Forsyth 215*37da2899SCharles.Forsyth /* ignore the errors that might have occurred -- */ 216*37da2899SCharles.Forsyth /* we mark unloaded glyphs with `sbit.buffer == 0' */ 217*37da2899SCharles.Forsyth /* and 'width == 255', 'height == 0' */ 218*37da2899SCharles.Forsyth /* */ 219*37da2899SCharles.Forsyth if ( error ) 220*37da2899SCharles.Forsyth { 221*37da2899SCharles.Forsyth sbit->width = 255; 222*37da2899SCharles.Forsyth error = 0; 223*37da2899SCharles.Forsyth /* sbit->buffer == NULL too! */ 224*37da2899SCharles.Forsyth } 225*37da2899SCharles.Forsyth } 226*37da2899SCharles.Forsyth 227*37da2899SCharles.Forsyth return error; 228*37da2899SCharles.Forsyth } 229*37da2899SCharles.Forsyth 230*37da2899SCharles.Forsyth 231*37da2899SCharles.Forsyth FT_CALLBACK_DEF( FT_Error ) ftc_sbit_node_init(FTC_SBitNode snode,FTC_GlyphQuery gquery,FTC_Cache cache)232*37da2899SCharles.Forsyth ftc_sbit_node_init( FTC_SBitNode snode, 233*37da2899SCharles.Forsyth FTC_GlyphQuery gquery, 234*37da2899SCharles.Forsyth FTC_Cache cache ) 235*37da2899SCharles.Forsyth { 236*37da2899SCharles.Forsyth FT_Error error; 237*37da2899SCharles.Forsyth 238*37da2899SCharles.Forsyth 239*37da2899SCharles.Forsyth ftc_glyph_node_init( FTC_GLYPH_NODE( snode ), 240*37da2899SCharles.Forsyth gquery->gindex, 241*37da2899SCharles.Forsyth FTC_GLYPH_FAMILY( gquery->query.family ) ); 242*37da2899SCharles.Forsyth 243*37da2899SCharles.Forsyth error = ftc_sbit_node_load( snode, 244*37da2899SCharles.Forsyth cache->manager, 245*37da2899SCharles.Forsyth FTC_SBIT_FAMILY( FTC_QUERY( gquery )->family ), 246*37da2899SCharles.Forsyth gquery->gindex, 247*37da2899SCharles.Forsyth NULL ); 248*37da2899SCharles.Forsyth if ( error ) 249*37da2899SCharles.Forsyth ftc_glyph_node_done( FTC_GLYPH_NODE( snode ), cache ); 250*37da2899SCharles.Forsyth 251*37da2899SCharles.Forsyth return error; 252*37da2899SCharles.Forsyth } 253*37da2899SCharles.Forsyth 254*37da2899SCharles.Forsyth 255*37da2899SCharles.Forsyth FT_CALLBACK_DEF( FT_ULong ) ftc_sbit_node_weight(FTC_SBitNode snode)256*37da2899SCharles.Forsyth ftc_sbit_node_weight( FTC_SBitNode snode ) 257*37da2899SCharles.Forsyth { 258*37da2899SCharles.Forsyth FTC_GlyphNode gnode = FTC_GLYPH_NODE( snode ); 259*37da2899SCharles.Forsyth FT_UInt count = gnode->item_count; 260*37da2899SCharles.Forsyth FTC_SBit sbit = snode->sbits; 261*37da2899SCharles.Forsyth FT_Int pitch; 262*37da2899SCharles.Forsyth FT_ULong size; 263*37da2899SCharles.Forsyth 264*37da2899SCharles.Forsyth 265*37da2899SCharles.Forsyth /* the node itself */ 266*37da2899SCharles.Forsyth size = sizeof ( *snode ); 267*37da2899SCharles.Forsyth 268*37da2899SCharles.Forsyth /* the sbit records */ 269*37da2899SCharles.Forsyth size += FTC_GLYPH_NODE( snode )->item_count * sizeof ( FTC_SBitRec ); 270*37da2899SCharles.Forsyth 271*37da2899SCharles.Forsyth for ( ; count > 0; count--, sbit++ ) 272*37da2899SCharles.Forsyth { 273*37da2899SCharles.Forsyth if ( sbit->buffer ) 274*37da2899SCharles.Forsyth { 275*37da2899SCharles.Forsyth pitch = sbit->pitch; 276*37da2899SCharles.Forsyth if ( pitch < 0 ) 277*37da2899SCharles.Forsyth pitch = -pitch; 278*37da2899SCharles.Forsyth 279*37da2899SCharles.Forsyth /* add the size of a given glyph image */ 280*37da2899SCharles.Forsyth size += pitch * sbit->height; 281*37da2899SCharles.Forsyth } 282*37da2899SCharles.Forsyth } 283*37da2899SCharles.Forsyth 284*37da2899SCharles.Forsyth return size; 285*37da2899SCharles.Forsyth } 286*37da2899SCharles.Forsyth 287*37da2899SCharles.Forsyth 288*37da2899SCharles.Forsyth FT_CALLBACK_DEF( FT_Bool ) ftc_sbit_node_compare(FTC_SBitNode snode,FTC_SBitQuery squery,FTC_Cache cache)289*37da2899SCharles.Forsyth ftc_sbit_node_compare( FTC_SBitNode snode, 290*37da2899SCharles.Forsyth FTC_SBitQuery squery, 291*37da2899SCharles.Forsyth FTC_Cache cache ) 292*37da2899SCharles.Forsyth { 293*37da2899SCharles.Forsyth FTC_GlyphQuery gquery = FTC_GLYPH_QUERY( squery ); 294*37da2899SCharles.Forsyth FTC_GlyphNode gnode = FTC_GLYPH_NODE( snode ); 295*37da2899SCharles.Forsyth FT_Bool result; 296*37da2899SCharles.Forsyth 297*37da2899SCharles.Forsyth 298*37da2899SCharles.Forsyth result = ftc_glyph_node_compare( gnode, gquery ); 299*37da2899SCharles.Forsyth if ( result ) 300*37da2899SCharles.Forsyth { 301*37da2899SCharles.Forsyth /* check if we need to load the glyph bitmap now */ 302*37da2899SCharles.Forsyth FT_UInt gindex = gquery->gindex; 303*37da2899SCharles.Forsyth FTC_SBit sbit = snode->sbits + ( gindex - gnode->item_start ); 304*37da2899SCharles.Forsyth 305*37da2899SCharles.Forsyth 306*37da2899SCharles.Forsyth if ( sbit->buffer == NULL && sbit->width != 255 ) 307*37da2899SCharles.Forsyth { 308*37da2899SCharles.Forsyth FT_ULong size; 309*37da2899SCharles.Forsyth 310*37da2899SCharles.Forsyth 311*37da2899SCharles.Forsyth /* yes, it's safe to ignore errors here */ 312*37da2899SCharles.Forsyth ftc_sbit_node_load( snode, 313*37da2899SCharles.Forsyth cache->manager, 314*37da2899SCharles.Forsyth FTC_SBIT_FAMILY( FTC_QUERY( squery )->family ), 315*37da2899SCharles.Forsyth gindex, 316*37da2899SCharles.Forsyth &size ); 317*37da2899SCharles.Forsyth 318*37da2899SCharles.Forsyth cache->manager->cur_weight += size; 319*37da2899SCharles.Forsyth } 320*37da2899SCharles.Forsyth } 321*37da2899SCharles.Forsyth 322*37da2899SCharles.Forsyth return result; 323*37da2899SCharles.Forsyth } 324*37da2899SCharles.Forsyth 325*37da2899SCharles.Forsyth 326*37da2899SCharles.Forsyth /*************************************************************************/ 327*37da2899SCharles.Forsyth /*************************************************************************/ 328*37da2899SCharles.Forsyth /***** *****/ 329*37da2899SCharles.Forsyth /***** SBITS FAMILIES *****/ 330*37da2899SCharles.Forsyth /***** *****/ 331*37da2899SCharles.Forsyth /*************************************************************************/ 332*37da2899SCharles.Forsyth /*************************************************************************/ 333*37da2899SCharles.Forsyth 334*37da2899SCharles.Forsyth 335*37da2899SCharles.Forsyth FT_CALLBACK_DEF( FT_Error ) ftc_sbit_family_init(FTC_SBitFamily sfam,FTC_SBitQuery squery,FTC_Cache cache)336*37da2899SCharles.Forsyth ftc_sbit_family_init( FTC_SBitFamily sfam, 337*37da2899SCharles.Forsyth FTC_SBitQuery squery, 338*37da2899SCharles.Forsyth FTC_Cache cache ) 339*37da2899SCharles.Forsyth { 340*37da2899SCharles.Forsyth FTC_Manager manager = cache->manager; 341*37da2899SCharles.Forsyth FT_Error error; 342*37da2899SCharles.Forsyth FT_Face face; 343*37da2899SCharles.Forsyth 344*37da2899SCharles.Forsyth 345*37da2899SCharles.Forsyth sfam->type = squery->type; 346*37da2899SCharles.Forsyth 347*37da2899SCharles.Forsyth /* we need to compute "cquery.item_total" now */ 348*37da2899SCharles.Forsyth error = FTC_Manager_Lookup_Face( manager, 349*37da2899SCharles.Forsyth squery->type.font.face_id, 350*37da2899SCharles.Forsyth &face ); 351*37da2899SCharles.Forsyth if ( !error ) 352*37da2899SCharles.Forsyth { 353*37da2899SCharles.Forsyth error = ftc_glyph_family_init( FTC_GLYPH_FAMILY( sfam ), 354*37da2899SCharles.Forsyth FTC_IMAGE_TYPE_HASH( &sfam->type ), 355*37da2899SCharles.Forsyth FTC_SBIT_ITEMS_PER_NODE, 356*37da2899SCharles.Forsyth face->num_glyphs, 357*37da2899SCharles.Forsyth FTC_GLYPH_QUERY( squery ), 358*37da2899SCharles.Forsyth cache ); 359*37da2899SCharles.Forsyth } 360*37da2899SCharles.Forsyth 361*37da2899SCharles.Forsyth return error; 362*37da2899SCharles.Forsyth } 363*37da2899SCharles.Forsyth 364*37da2899SCharles.Forsyth 365*37da2899SCharles.Forsyth FT_CALLBACK_DEF( FT_Bool ) ftc_sbit_family_compare(FTC_SBitFamily sfam,FTC_SBitQuery squery)366*37da2899SCharles.Forsyth ftc_sbit_family_compare( FTC_SBitFamily sfam, 367*37da2899SCharles.Forsyth FTC_SBitQuery squery ) 368*37da2899SCharles.Forsyth { 369*37da2899SCharles.Forsyth FT_Bool result; 370*37da2899SCharles.Forsyth 371*37da2899SCharles.Forsyth 372*37da2899SCharles.Forsyth /* we need to set the "cquery.cset" field or our query for */ 373*37da2899SCharles.Forsyth /* faster glyph comparisons in ftc_sbit_node_compare */ 374*37da2899SCharles.Forsyth /* */ 375*37da2899SCharles.Forsyth result = FT_BOOL( FTC_IMAGE_TYPE_COMPARE( &sfam->type, &squery->type ) ); 376*37da2899SCharles.Forsyth if ( result ) 377*37da2899SCharles.Forsyth FTC_GLYPH_FAMILY_FOUND( sfam, squery ); 378*37da2899SCharles.Forsyth 379*37da2899SCharles.Forsyth return result; 380*37da2899SCharles.Forsyth } 381*37da2899SCharles.Forsyth 382*37da2899SCharles.Forsyth 383*37da2899SCharles.Forsyth /*************************************************************************/ 384*37da2899SCharles.Forsyth /*************************************************************************/ 385*37da2899SCharles.Forsyth /***** *****/ 386*37da2899SCharles.Forsyth /***** SBITS CACHE *****/ 387*37da2899SCharles.Forsyth /***** *****/ 388*37da2899SCharles.Forsyth /*************************************************************************/ 389*37da2899SCharles.Forsyth /*************************************************************************/ 390*37da2899SCharles.Forsyth 391*37da2899SCharles.Forsyth 392*37da2899SCharles.Forsyth FT_CALLBACK_TABLE_DEF 393*37da2899SCharles.Forsyth const FTC_Cache_ClassRec ftc_sbit_cache_class = 394*37da2899SCharles.Forsyth { 395*37da2899SCharles.Forsyth sizeof ( FTC_CacheRec ), 396*37da2899SCharles.Forsyth (FTC_Cache_InitFunc) ftc_cache_init, 397*37da2899SCharles.Forsyth (FTC_Cache_ClearFunc)ftc_cache_clear, 398*37da2899SCharles.Forsyth (FTC_Cache_DoneFunc) ftc_cache_done, 399*37da2899SCharles.Forsyth 400*37da2899SCharles.Forsyth sizeof ( FTC_SBitFamilyRec ), 401*37da2899SCharles.Forsyth (FTC_Family_InitFunc) ftc_sbit_family_init, 402*37da2899SCharles.Forsyth (FTC_Family_CompareFunc)ftc_sbit_family_compare, 403*37da2899SCharles.Forsyth (FTC_Family_DoneFunc) ftc_glyph_family_done, 404*37da2899SCharles.Forsyth 405*37da2899SCharles.Forsyth sizeof ( FTC_SBitNodeRec ), 406*37da2899SCharles.Forsyth (FTC_Node_InitFunc) ftc_sbit_node_init, 407*37da2899SCharles.Forsyth (FTC_Node_WeightFunc) ftc_sbit_node_weight, 408*37da2899SCharles.Forsyth (FTC_Node_CompareFunc)ftc_sbit_node_compare, 409*37da2899SCharles.Forsyth (FTC_Node_DoneFunc) ftc_sbit_node_done 410*37da2899SCharles.Forsyth }; 411*37da2899SCharles.Forsyth 412*37da2899SCharles.Forsyth 413*37da2899SCharles.Forsyth /* documentation is in ftcsbits.h */ 414*37da2899SCharles.Forsyth 415*37da2899SCharles.Forsyth FT_EXPORT_DEF( FT_Error ) FTC_SBitCache_New(FTC_Manager manager,FTC_SBitCache * acache)416*37da2899SCharles.Forsyth FTC_SBitCache_New( FTC_Manager manager, 417*37da2899SCharles.Forsyth FTC_SBitCache *acache ) 418*37da2899SCharles.Forsyth { 419*37da2899SCharles.Forsyth return FTC_Manager_Register_Cache( manager, 420*37da2899SCharles.Forsyth &ftc_sbit_cache_class, 421*37da2899SCharles.Forsyth (FTC_Cache*)acache ); 422*37da2899SCharles.Forsyth } 423*37da2899SCharles.Forsyth 424*37da2899SCharles.Forsyth 425*37da2899SCharles.Forsyth /* documentation is in ftcsbits.h */ 426*37da2899SCharles.Forsyth 427*37da2899SCharles.Forsyth #ifdef FTC_CACHE_USE_INLINE 428*37da2899SCharles.Forsyth 429*37da2899SCharles.Forsyth #define GEN_CACHE_FAMILY_COMPARE( f, q, c ) \ 430*37da2899SCharles.Forsyth ftc_sbit_family_compare( (FTC_SBitFamily)(f), (FTC_SBitQuery)(q) ) 431*37da2899SCharles.Forsyth 432*37da2899SCharles.Forsyth #define GEN_CACHE_NODE_COMPARE( n, q, c ) \ 433*37da2899SCharles.Forsyth ftc_sbit_node_compare( (FTC_SBitNode)(n), (FTC_SBitQuery)(q), c ) 434*37da2899SCharles.Forsyth 435*37da2899SCharles.Forsyth #define GEN_CACHE_LOOKUP ftc_sbit_cache_lookup 436*37da2899SCharles.Forsyth #include "ftccache.i" 437*37da2899SCharles.Forsyth 438*37da2899SCharles.Forsyth #else /* !FTC_CACHE_USE_INLINE */ 439*37da2899SCharles.Forsyth 440*37da2899SCharles.Forsyth #define ftc_sbit_cache_lookup ftc_cache_lookup 441*37da2899SCharles.Forsyth 442*37da2899SCharles.Forsyth #endif /* !FTC_CACHE_USE_INLINE */ 443*37da2899SCharles.Forsyth 444*37da2899SCharles.Forsyth FT_EXPORT_DEF( FT_Error ) FTC_SBitCache_Lookup(FTC_SBitCache cache,FTC_ImageType type,FT_UInt gindex,FTC_SBit * ansbit,FTC_Node * anode)445*37da2899SCharles.Forsyth FTC_SBitCache_Lookup( FTC_SBitCache cache, 446*37da2899SCharles.Forsyth FTC_ImageType type, 447*37da2899SCharles.Forsyth FT_UInt gindex, 448*37da2899SCharles.Forsyth FTC_SBit *ansbit, 449*37da2899SCharles.Forsyth FTC_Node *anode ) 450*37da2899SCharles.Forsyth { 451*37da2899SCharles.Forsyth FT_Error error; 452*37da2899SCharles.Forsyth FTC_SBitQueryRec squery; 453*37da2899SCharles.Forsyth FTC_SBitNode node; 454*37da2899SCharles.Forsyth 455*37da2899SCharles.Forsyth 456*37da2899SCharles.Forsyth /* other argument checks delayed to ftc_cache_lookup */ 457*37da2899SCharles.Forsyth if ( !ansbit ) 458*37da2899SCharles.Forsyth return FTC_Err_Invalid_Argument; 459*37da2899SCharles.Forsyth 460*37da2899SCharles.Forsyth *ansbit = NULL; 461*37da2899SCharles.Forsyth 462*37da2899SCharles.Forsyth if ( anode ) 463*37da2899SCharles.Forsyth *anode = NULL; 464*37da2899SCharles.Forsyth 465*37da2899SCharles.Forsyth squery.gquery.gindex = gindex; 466*37da2899SCharles.Forsyth squery.type = *type; 467*37da2899SCharles.Forsyth 468*37da2899SCharles.Forsyth error = ftc_sbit_cache_lookup( FTC_CACHE( cache ), 469*37da2899SCharles.Forsyth FTC_QUERY( &squery ), 470*37da2899SCharles.Forsyth (FTC_Node*)&node ); 471*37da2899SCharles.Forsyth if ( !error ) 472*37da2899SCharles.Forsyth { 473*37da2899SCharles.Forsyth *ansbit = node->sbits + ( gindex - FTC_GLYPH_NODE( node )->item_start ); 474*37da2899SCharles.Forsyth 475*37da2899SCharles.Forsyth if ( anode ) 476*37da2899SCharles.Forsyth { 477*37da2899SCharles.Forsyth *anode = FTC_NODE( node ); 478*37da2899SCharles.Forsyth FTC_NODE( node )->ref_count++; 479*37da2899SCharles.Forsyth } 480*37da2899SCharles.Forsyth } 481*37da2899SCharles.Forsyth return error; 482*37da2899SCharles.Forsyth } 483*37da2899SCharles.Forsyth 484*37da2899SCharles.Forsyth 485*37da2899SCharles.Forsyth /* backwards-compatibility functions */ 486*37da2899SCharles.Forsyth 487*37da2899SCharles.Forsyth FT_EXPORT_DEF( FT_Error ) FTC_SBit_Cache_New(FTC_Manager manager,FTC_SBit_Cache * acache)488*37da2899SCharles.Forsyth FTC_SBit_Cache_New( FTC_Manager manager, 489*37da2899SCharles.Forsyth FTC_SBit_Cache *acache ) 490*37da2899SCharles.Forsyth { 491*37da2899SCharles.Forsyth return FTC_SBitCache_New( manager, (FTC_SBitCache*)acache ); 492*37da2899SCharles.Forsyth } 493*37da2899SCharles.Forsyth 494*37da2899SCharles.Forsyth 495*37da2899SCharles.Forsyth FT_EXPORT_DEF( FT_Error ) FTC_SBit_Cache_Lookup(FTC_SBit_Cache cache,FTC_Image_Desc * desc,FT_UInt gindex,FTC_SBit * ansbit)496*37da2899SCharles.Forsyth FTC_SBit_Cache_Lookup( FTC_SBit_Cache cache, 497*37da2899SCharles.Forsyth FTC_Image_Desc* desc, 498*37da2899SCharles.Forsyth FT_UInt gindex, 499*37da2899SCharles.Forsyth FTC_SBit *ansbit ) 500*37da2899SCharles.Forsyth { 501*37da2899SCharles.Forsyth FTC_ImageTypeRec type0; 502*37da2899SCharles.Forsyth 503*37da2899SCharles.Forsyth 504*37da2899SCharles.Forsyth if ( !desc ) 505*37da2899SCharles.Forsyth return FTC_Err_Invalid_Argument; 506*37da2899SCharles.Forsyth 507*37da2899SCharles.Forsyth type0.font = desc->font; 508*37da2899SCharles.Forsyth type0.flags = 0; 509*37da2899SCharles.Forsyth 510*37da2899SCharles.Forsyth /* convert image type flags to load flags */ 511*37da2899SCharles.Forsyth { 512*37da2899SCharles.Forsyth FT_UInt load_flags = FT_LOAD_DEFAULT; 513*37da2899SCharles.Forsyth FT_UInt type = desc->image_type; 514*37da2899SCharles.Forsyth 515*37da2899SCharles.Forsyth 516*37da2899SCharles.Forsyth /* determine load flags, depending on the font description's */ 517*37da2899SCharles.Forsyth /* image type */ 518*37da2899SCharles.Forsyth 519*37da2899SCharles.Forsyth if ( ftc_image_format( type ) == ftc_image_format_bitmap ) 520*37da2899SCharles.Forsyth { 521*37da2899SCharles.Forsyth if ( type & ftc_image_flag_monochrome ) 522*37da2899SCharles.Forsyth load_flags |= FT_LOAD_MONOCHROME; 523*37da2899SCharles.Forsyth 524*37da2899SCharles.Forsyth /* disable embedded bitmaps loading if necessary */ 525*37da2899SCharles.Forsyth if ( type & ftc_image_flag_no_sbits ) 526*37da2899SCharles.Forsyth load_flags |= FT_LOAD_NO_BITMAP; 527*37da2899SCharles.Forsyth } 528*37da2899SCharles.Forsyth else 529*37da2899SCharles.Forsyth { 530*37da2899SCharles.Forsyth /* we want an outline, don't load embedded bitmaps */ 531*37da2899SCharles.Forsyth load_flags |= FT_LOAD_NO_BITMAP; 532*37da2899SCharles.Forsyth 533*37da2899SCharles.Forsyth if ( type & ftc_image_flag_unscaled ) 534*37da2899SCharles.Forsyth load_flags |= FT_LOAD_NO_SCALE; 535*37da2899SCharles.Forsyth } 536*37da2899SCharles.Forsyth 537*37da2899SCharles.Forsyth /* always render glyphs to bitmaps */ 538*37da2899SCharles.Forsyth load_flags |= FT_LOAD_RENDER; 539*37da2899SCharles.Forsyth 540*37da2899SCharles.Forsyth if ( type & ftc_image_flag_unhinted ) 541*37da2899SCharles.Forsyth load_flags |= FT_LOAD_NO_HINTING; 542*37da2899SCharles.Forsyth 543*37da2899SCharles.Forsyth if ( type & ftc_image_flag_autohinted ) 544*37da2899SCharles.Forsyth load_flags |= FT_LOAD_FORCE_AUTOHINT; 545*37da2899SCharles.Forsyth 546*37da2899SCharles.Forsyth type0.flags = load_flags; 547*37da2899SCharles.Forsyth } 548*37da2899SCharles.Forsyth 549*37da2899SCharles.Forsyth return FTC_SBitCache_Lookup( (FTC_SBitCache)cache, 550*37da2899SCharles.Forsyth &type0, 551*37da2899SCharles.Forsyth gindex, 552*37da2899SCharles.Forsyth ansbit, 553*37da2899SCharles.Forsyth NULL ); 554*37da2899SCharles.Forsyth } 555*37da2899SCharles.Forsyth 556*37da2899SCharles.Forsyth 557*37da2899SCharles.Forsyth /* END */ 558