ftc_image_node_init( FTC_ImageNode inode, FTC_GlyphQuery gquery, FTC_Cache cache ) { FTC_ImageFamily ifam = FTC_IMAGE_FAMILY( gquery->query.family ); FT_Error error; FT_Face face; FT_Size size; /* initialize its inner fields */ ftc_glyph_node_init( FTC_GLYPH_NODE( inode ), gquery->gindex, FTC_GLYPH_FAMILY( ifam ) ); /* we will now load the glyph image */ error = FTC_Manager_Lookup_Size( FTC_FAMILY( ifam )->cache->manager, &ifam->type.font, &face, &size ); if ( !error ) { FT_UInt gindex = FTC_GLYPH_NODE_GINDEX( inode ); error = FT_Load_Glyph( face, gindex, ifam->type.flags ); if ( !error ) { if ( face->glyph->format == FT_GLYPH_FORMAT_BITMAP || face->glyph->format == FT_GLYPH_FORMAT_OUTLINE ) { /* ok, copy it */ FT_Glyph glyph; error = FT_Get_Glyph( face->glyph, &glyph ); if ( !error ) { inode->glyph = glyph; goto Exit; } } else error = FTC_Err_Invalid_Argument; } } /* in case of error */ ftc_glyph_node_done( FTC_GLYPH_NODE(inode), cache ); Exit: return error; }
ftc_sbit_node_done( FTC_SBitNode snode, FTC_Cache cache ) { FTC_SBit sbit = snode->sbits; FT_UInt count = FTC_GLYPH_NODE( snode )->item_count; FT_Memory memory = cache->memory; for ( ; count > 0; sbit++, count-- ) FT_FREE( sbit->buffer ); ftc_glyph_node_done( FTC_GLYPH_NODE( snode ), cache ); }
ftc_image_node_done( FTC_ImageNode inode, FTC_Cache cache ) { if ( inode->glyph ) { FT_Done_Glyph( inode->glyph ); inode->glyph = NULL; } ftc_glyph_node_done( FTC_GLYPH_NODE( inode ), cache ); }
static FT_Error ftc_sbit_node_load( FTC_SBitNode snode, FTC_Manager manager, FTC_SBitFamily sfam, FT_UInt gindex, FT_ULong *asize ) { FT_Error error; FTC_GlyphNode gnode = FTC_GLYPH_NODE( snode ); FT_Memory memory; FT_Face face; FT_Size size; FTC_SBit sbit; if ( gindex < (FT_UInt)gnode->item_start || gindex >= (FT_UInt)gnode->item_start + gnode->item_count ) { FT_ERROR(( "ftc_sbit_node_load: invalid glyph index" )); return FTC_Err_Invalid_Argument; } memory = manager->library->memory; sbit = snode->sbits + ( gindex - gnode->item_start ); error = FTC_Manager_Lookup_Size( manager, &sfam->type.font, &face, &size ); if ( !error ) { /* by default, indicates a `missing' glyph */ sbit->buffer = 0; error = FT_Load_Glyph( face, gindex, sfam->type.flags | FT_LOAD_RENDER ); if ( !error ) { FT_Int temp; FT_GlyphSlot slot = face->glyph; FT_Bitmap* bitmap = &slot->bitmap; FT_Int xadvance, yadvance; /* check that our values fit into 8-bit containers! */ /* If this is not the case, our bitmap is too large */ /* and we will leave it as `missing' with sbit.buffer = 0 */ #define CHECK_CHAR( d ) ( temp = (FT_Char)d, temp == d ) #define CHECK_BYTE( d ) ( temp = (FT_Byte)d, temp == d ) /* XXX: FIXME: add support for vertical layouts maybe */ /* horizontal advance in pixels */ xadvance = ( slot->metrics.horiAdvance + 32 ) >> 6; yadvance = ( slot->metrics.vertAdvance + 32 ) >> 6; if ( CHECK_BYTE( bitmap->rows ) && CHECK_BYTE( bitmap->width ) && CHECK_CHAR( bitmap->pitch ) && CHECK_CHAR( slot->bitmap_left ) && CHECK_CHAR( slot->bitmap_top ) && CHECK_CHAR( xadvance ) && CHECK_CHAR( yadvance ) ) { sbit->width = (FT_Byte)bitmap->width; sbit->height = (FT_Byte)bitmap->rows; sbit->pitch = (FT_Char)bitmap->pitch; sbit->left = (FT_Char)slot->bitmap_left; sbit->top = (FT_Char)slot->bitmap_top; sbit->xadvance = (FT_Char)xadvance; sbit->yadvance = (FT_Char)yadvance; sbit->format = (FT_Byte)bitmap->pixel_mode; sbit->max_grays = (FT_Byte)(bitmap->num_grays - 1); #if 0 /* this doesn't work well with embedded bitmaps */ /* grab the bitmap when possible - this is a hack! */ if ( slot->internal->flags & FT_GLYPH_OWN_BITMAP ) { slot->internal->flags &= ~FT_GLYPH_OWN_BITMAP; sbit->buffer = bitmap->buffer; } else #endif { /* copy the bitmap into a new buffer -- ignore error */ error = ftc_sbit_copy_bitmap( sbit, bitmap, memory ); } /* now, compute size */ if ( asize ) *asize = ABS( sbit->pitch ) * sbit->height; } /* glyph dimensions ok */ } /* glyph loading successful */