1*37da2899SCharles.Forsyth /***************************************************************************/ 2*37da2899SCharles.Forsyth /* */ 3*37da2899SCharles.Forsyth /* ftglyph.c */ 4*37da2899SCharles.Forsyth /* */ 5*37da2899SCharles.Forsyth /* FreeType convenience functions to handle glyphs (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 /* */ 20*37da2899SCharles.Forsyth /* This file contains the definition of several convenience functions */ 21*37da2899SCharles.Forsyth /* that can be used by client applications to easily retrieve glyph */ 22*37da2899SCharles.Forsyth /* bitmaps and outlines from a given face. */ 23*37da2899SCharles.Forsyth /* */ 24*37da2899SCharles.Forsyth /* These functions should be optional if you are writing a font server */ 25*37da2899SCharles.Forsyth /* or text layout engine on top of FreeType. However, they are pretty */ 26*37da2899SCharles.Forsyth /* handy for many other simple uses of the library. */ 27*37da2899SCharles.Forsyth /* */ 28*37da2899SCharles.Forsyth /*************************************************************************/ 29*37da2899SCharles.Forsyth 30*37da2899SCharles.Forsyth 31*37da2899SCharles.Forsyth #include <ft2build.h> 32*37da2899SCharles.Forsyth #include FT_GLYPH_H 33*37da2899SCharles.Forsyth #include FT_OUTLINE_H 34*37da2899SCharles.Forsyth #include FT_INTERNAL_OBJECTS_H 35*37da2899SCharles.Forsyth 36*37da2899SCharles.Forsyth 37*37da2899SCharles.Forsyth /*************************************************************************/ 38*37da2899SCharles.Forsyth /* */ 39*37da2899SCharles.Forsyth /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ 40*37da2899SCharles.Forsyth /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ 41*37da2899SCharles.Forsyth /* messages during execution. */ 42*37da2899SCharles.Forsyth /* */ 43*37da2899SCharles.Forsyth #undef FT_COMPONENT 44*37da2899SCharles.Forsyth #define FT_COMPONENT trace_glyph 45*37da2899SCharles.Forsyth 46*37da2899SCharles.Forsyth 47*37da2899SCharles.Forsyth /*************************************************************************/ 48*37da2899SCharles.Forsyth /*************************************************************************/ 49*37da2899SCharles.Forsyth /**** ****/ 50*37da2899SCharles.Forsyth /**** Convenience functions ****/ 51*37da2899SCharles.Forsyth /**** ****/ 52*37da2899SCharles.Forsyth /*************************************************************************/ 53*37da2899SCharles.Forsyth /*************************************************************************/ 54*37da2899SCharles.Forsyth 55*37da2899SCharles.Forsyth 56*37da2899SCharles.Forsyth /* documentation is in ftglyph.h */ 57*37da2899SCharles.Forsyth 58*37da2899SCharles.Forsyth FT_EXPORT_DEF( void ) FT_Matrix_Multiply(FT_Matrix * a,FT_Matrix * b)59*37da2899SCharles.Forsyth FT_Matrix_Multiply( FT_Matrix* a, 60*37da2899SCharles.Forsyth FT_Matrix* b ) 61*37da2899SCharles.Forsyth { 62*37da2899SCharles.Forsyth FT_Fixed xx, xy, yx, yy; 63*37da2899SCharles.Forsyth 64*37da2899SCharles.Forsyth 65*37da2899SCharles.Forsyth if ( !a || !b ) 66*37da2899SCharles.Forsyth return; 67*37da2899SCharles.Forsyth 68*37da2899SCharles.Forsyth xx = FT_MulFix( a->xx, b->xx ) + FT_MulFix( a->xy, b->yx ); 69*37da2899SCharles.Forsyth xy = FT_MulFix( a->xx, b->xy ) + FT_MulFix( a->xy, b->yy ); 70*37da2899SCharles.Forsyth yx = FT_MulFix( a->yx, b->xx ) + FT_MulFix( a->yy, b->yx ); 71*37da2899SCharles.Forsyth yy = FT_MulFix( a->yx, b->xy ) + FT_MulFix( a->yy, b->yy ); 72*37da2899SCharles.Forsyth 73*37da2899SCharles.Forsyth b->xx = xx; b->xy = xy; 74*37da2899SCharles.Forsyth b->yx = yx; b->yy = yy; 75*37da2899SCharles.Forsyth } 76*37da2899SCharles.Forsyth 77*37da2899SCharles.Forsyth 78*37da2899SCharles.Forsyth /* documentation is in ftglyph.h */ 79*37da2899SCharles.Forsyth 80*37da2899SCharles.Forsyth FT_EXPORT_DEF( FT_Error ) FT_Matrix_Invert(FT_Matrix * matrix)81*37da2899SCharles.Forsyth FT_Matrix_Invert( FT_Matrix* matrix ) 82*37da2899SCharles.Forsyth { 83*37da2899SCharles.Forsyth FT_Pos delta, xx, yy; 84*37da2899SCharles.Forsyth 85*37da2899SCharles.Forsyth 86*37da2899SCharles.Forsyth if ( !matrix ) 87*37da2899SCharles.Forsyth return FT_Err_Invalid_Argument; 88*37da2899SCharles.Forsyth 89*37da2899SCharles.Forsyth /* compute discriminant */ 90*37da2899SCharles.Forsyth delta = FT_MulFix( matrix->xx, matrix->yy ) - 91*37da2899SCharles.Forsyth FT_MulFix( matrix->xy, matrix->yx ); 92*37da2899SCharles.Forsyth 93*37da2899SCharles.Forsyth if ( !delta ) 94*37da2899SCharles.Forsyth return FT_Err_Invalid_Argument; /* matrix can't be inverted */ 95*37da2899SCharles.Forsyth 96*37da2899SCharles.Forsyth matrix->xy = - FT_DivFix( matrix->xy, delta ); 97*37da2899SCharles.Forsyth matrix->yx = - FT_DivFix( matrix->yx, delta ); 98*37da2899SCharles.Forsyth 99*37da2899SCharles.Forsyth xx = matrix->xx; 100*37da2899SCharles.Forsyth yy = matrix->yy; 101*37da2899SCharles.Forsyth 102*37da2899SCharles.Forsyth matrix->xx = FT_DivFix( yy, delta ); 103*37da2899SCharles.Forsyth matrix->yy = FT_DivFix( xx, delta ); 104*37da2899SCharles.Forsyth 105*37da2899SCharles.Forsyth return FT_Err_Ok; 106*37da2899SCharles.Forsyth } 107*37da2899SCharles.Forsyth 108*37da2899SCharles.Forsyth 109*37da2899SCharles.Forsyth /*************************************************************************/ 110*37da2899SCharles.Forsyth /*************************************************************************/ 111*37da2899SCharles.Forsyth /**** ****/ 112*37da2899SCharles.Forsyth /**** FT_BitmapGlyph support ****/ 113*37da2899SCharles.Forsyth /**** ****/ 114*37da2899SCharles.Forsyth /*************************************************************************/ 115*37da2899SCharles.Forsyth /*************************************************************************/ 116*37da2899SCharles.Forsyth 117*37da2899SCharles.Forsyth static FT_Error ft_bitmap_copy(FT_Memory memory,FT_Bitmap * source,FT_Bitmap * target)118*37da2899SCharles.Forsyth ft_bitmap_copy( FT_Memory memory, 119*37da2899SCharles.Forsyth FT_Bitmap* source, 120*37da2899SCharles.Forsyth FT_Bitmap* target ) 121*37da2899SCharles.Forsyth { 122*37da2899SCharles.Forsyth FT_Error error; 123*37da2899SCharles.Forsyth FT_Int pitch = source->pitch; 124*37da2899SCharles.Forsyth FT_ULong size; 125*37da2899SCharles.Forsyth 126*37da2899SCharles.Forsyth 127*37da2899SCharles.Forsyth *target = *source; 128*37da2899SCharles.Forsyth 129*37da2899SCharles.Forsyth if ( pitch < 0 ) 130*37da2899SCharles.Forsyth pitch = -pitch; 131*37da2899SCharles.Forsyth 132*37da2899SCharles.Forsyth size = (FT_ULong)( pitch * source->rows ); 133*37da2899SCharles.Forsyth 134*37da2899SCharles.Forsyth if ( !FT_ALLOC( target->buffer, size ) ) 135*37da2899SCharles.Forsyth FT_MEM_COPY( target->buffer, source->buffer, size ); 136*37da2899SCharles.Forsyth 137*37da2899SCharles.Forsyth return error; 138*37da2899SCharles.Forsyth } 139*37da2899SCharles.Forsyth 140*37da2899SCharles.Forsyth 141*37da2899SCharles.Forsyth static FT_Error ft_bitmap_glyph_init(FT_BitmapGlyph glyph,FT_GlyphSlot slot)142*37da2899SCharles.Forsyth ft_bitmap_glyph_init( FT_BitmapGlyph glyph, 143*37da2899SCharles.Forsyth FT_GlyphSlot slot ) 144*37da2899SCharles.Forsyth { 145*37da2899SCharles.Forsyth FT_Error error = FT_Err_Ok; 146*37da2899SCharles.Forsyth FT_Library library = FT_GLYPH(glyph)->library; 147*37da2899SCharles.Forsyth FT_Memory memory = library->memory; 148*37da2899SCharles.Forsyth 149*37da2899SCharles.Forsyth 150*37da2899SCharles.Forsyth if ( slot->format != FT_GLYPH_FORMAT_BITMAP ) 151*37da2899SCharles.Forsyth { 152*37da2899SCharles.Forsyth error = FT_Err_Invalid_Glyph_Format; 153*37da2899SCharles.Forsyth goto Exit; 154*37da2899SCharles.Forsyth } 155*37da2899SCharles.Forsyth 156*37da2899SCharles.Forsyth /* grab the bitmap in the slot - do lazy copying whenever possible */ 157*37da2899SCharles.Forsyth glyph->bitmap = slot->bitmap; 158*37da2899SCharles.Forsyth glyph->left = slot->bitmap_left; 159*37da2899SCharles.Forsyth glyph->top = slot->bitmap_top; 160*37da2899SCharles.Forsyth 161*37da2899SCharles.Forsyth if ( slot->flags & FT_GLYPH_OWN_BITMAP ) 162*37da2899SCharles.Forsyth slot->flags &= ~FT_GLYPH_OWN_BITMAP; 163*37da2899SCharles.Forsyth else 164*37da2899SCharles.Forsyth { 165*37da2899SCharles.Forsyth /* copy the bitmap into a new buffer */ 166*37da2899SCharles.Forsyth error = ft_bitmap_copy( memory, &slot->bitmap, &glyph->bitmap ); 167*37da2899SCharles.Forsyth } 168*37da2899SCharles.Forsyth 169*37da2899SCharles.Forsyth Exit: 170*37da2899SCharles.Forsyth return error; 171*37da2899SCharles.Forsyth } 172*37da2899SCharles.Forsyth 173*37da2899SCharles.Forsyth 174*37da2899SCharles.Forsyth static FT_Error ft_bitmap_glyph_copy(FT_BitmapGlyph source,FT_BitmapGlyph target)175*37da2899SCharles.Forsyth ft_bitmap_glyph_copy( FT_BitmapGlyph source, 176*37da2899SCharles.Forsyth FT_BitmapGlyph target ) 177*37da2899SCharles.Forsyth { 178*37da2899SCharles.Forsyth FT_Memory memory = source->root.library->memory; 179*37da2899SCharles.Forsyth 180*37da2899SCharles.Forsyth 181*37da2899SCharles.Forsyth target->left = source->left; 182*37da2899SCharles.Forsyth target->top = source->top; 183*37da2899SCharles.Forsyth 184*37da2899SCharles.Forsyth return ft_bitmap_copy( memory, &source->bitmap, &target->bitmap ); 185*37da2899SCharles.Forsyth } 186*37da2899SCharles.Forsyth 187*37da2899SCharles.Forsyth 188*37da2899SCharles.Forsyth static void ft_bitmap_glyph_done(FT_BitmapGlyph glyph)189*37da2899SCharles.Forsyth ft_bitmap_glyph_done( FT_BitmapGlyph glyph ) 190*37da2899SCharles.Forsyth { 191*37da2899SCharles.Forsyth FT_Memory memory = FT_GLYPH(glyph)->library->memory; 192*37da2899SCharles.Forsyth 193*37da2899SCharles.Forsyth 194*37da2899SCharles.Forsyth FT_FREE( glyph->bitmap.buffer ); 195*37da2899SCharles.Forsyth } 196*37da2899SCharles.Forsyth 197*37da2899SCharles.Forsyth 198*37da2899SCharles.Forsyth static void ft_bitmap_glyph_bbox(FT_BitmapGlyph glyph,FT_BBox * cbox)199*37da2899SCharles.Forsyth ft_bitmap_glyph_bbox( FT_BitmapGlyph glyph, 200*37da2899SCharles.Forsyth FT_BBox* cbox ) 201*37da2899SCharles.Forsyth { 202*37da2899SCharles.Forsyth cbox->xMin = glyph->left << 6; 203*37da2899SCharles.Forsyth cbox->xMax = cbox->xMin + ( glyph->bitmap.width << 6 ); 204*37da2899SCharles.Forsyth cbox->yMax = glyph->top << 6; 205*37da2899SCharles.Forsyth cbox->yMin = cbox->yMax - ( glyph->bitmap.rows << 6 ); 206*37da2899SCharles.Forsyth } 207*37da2899SCharles.Forsyth 208*37da2899SCharles.Forsyth 209*37da2899SCharles.Forsyth const FT_Glyph_Class ft_bitmap_glyph_class = 210*37da2899SCharles.Forsyth { 211*37da2899SCharles.Forsyth sizeof( FT_BitmapGlyphRec ), 212*37da2899SCharles.Forsyth FT_GLYPH_FORMAT_BITMAP, 213*37da2899SCharles.Forsyth 214*37da2899SCharles.Forsyth (FT_Glyph_InitFunc) ft_bitmap_glyph_init, 215*37da2899SCharles.Forsyth (FT_Glyph_DoneFunc) ft_bitmap_glyph_done, 216*37da2899SCharles.Forsyth (FT_Glyph_CopyFunc) ft_bitmap_glyph_copy, 217*37da2899SCharles.Forsyth (FT_Glyph_TransformFunc)0, 218*37da2899SCharles.Forsyth (FT_Glyph_GetBBoxFunc) ft_bitmap_glyph_bbox, 219*37da2899SCharles.Forsyth (FT_Glyph_PrepareFunc) 0 220*37da2899SCharles.Forsyth }; 221*37da2899SCharles.Forsyth 222*37da2899SCharles.Forsyth 223*37da2899SCharles.Forsyth /*************************************************************************/ 224*37da2899SCharles.Forsyth /*************************************************************************/ 225*37da2899SCharles.Forsyth /**** ****/ 226*37da2899SCharles.Forsyth /**** FT_OutlineGlyph support ****/ 227*37da2899SCharles.Forsyth /**** ****/ 228*37da2899SCharles.Forsyth /*************************************************************************/ 229*37da2899SCharles.Forsyth /*************************************************************************/ 230*37da2899SCharles.Forsyth 231*37da2899SCharles.Forsyth 232*37da2899SCharles.Forsyth static FT_Error ft_outline_glyph_init(FT_OutlineGlyph glyph,FT_GlyphSlot slot)233*37da2899SCharles.Forsyth ft_outline_glyph_init( FT_OutlineGlyph glyph, 234*37da2899SCharles.Forsyth FT_GlyphSlot slot ) 235*37da2899SCharles.Forsyth { 236*37da2899SCharles.Forsyth FT_Error error = FT_Err_Ok; 237*37da2899SCharles.Forsyth FT_Library library = FT_GLYPH(glyph)->library; 238*37da2899SCharles.Forsyth FT_Outline* source = &slot->outline; 239*37da2899SCharles.Forsyth FT_Outline* target = &glyph->outline; 240*37da2899SCharles.Forsyth 241*37da2899SCharles.Forsyth 242*37da2899SCharles.Forsyth /* check format in glyph slot */ 243*37da2899SCharles.Forsyth if ( slot->format != FT_GLYPH_FORMAT_OUTLINE ) 244*37da2899SCharles.Forsyth { 245*37da2899SCharles.Forsyth error = FT_Err_Invalid_Glyph_Format; 246*37da2899SCharles.Forsyth goto Exit; 247*37da2899SCharles.Forsyth } 248*37da2899SCharles.Forsyth 249*37da2899SCharles.Forsyth /* allocate new outline */ 250*37da2899SCharles.Forsyth error = FT_Outline_New( library, source->n_points, source->n_contours, 251*37da2899SCharles.Forsyth &glyph->outline ); 252*37da2899SCharles.Forsyth if ( error ) 253*37da2899SCharles.Forsyth goto Exit; 254*37da2899SCharles.Forsyth 255*37da2899SCharles.Forsyth /* copy it */ 256*37da2899SCharles.Forsyth FT_MEM_COPY( target->points, source->points, 257*37da2899SCharles.Forsyth source->n_points * sizeof ( FT_Vector ) ); 258*37da2899SCharles.Forsyth 259*37da2899SCharles.Forsyth FT_MEM_COPY( target->tags, source->tags, 260*37da2899SCharles.Forsyth source->n_points * sizeof ( FT_Byte ) ); 261*37da2899SCharles.Forsyth 262*37da2899SCharles.Forsyth FT_MEM_COPY( target->contours, source->contours, 263*37da2899SCharles.Forsyth source->n_contours * sizeof ( FT_Short ) ); 264*37da2899SCharles.Forsyth 265*37da2899SCharles.Forsyth /* copy all flags, except the `FT_OUTLINE_OWNER' one */ 266*37da2899SCharles.Forsyth target->flags = source->flags | FT_OUTLINE_OWNER; 267*37da2899SCharles.Forsyth 268*37da2899SCharles.Forsyth Exit: 269*37da2899SCharles.Forsyth return error; 270*37da2899SCharles.Forsyth } 271*37da2899SCharles.Forsyth 272*37da2899SCharles.Forsyth 273*37da2899SCharles.Forsyth static void ft_outline_glyph_done(FT_OutlineGlyph glyph)274*37da2899SCharles.Forsyth ft_outline_glyph_done( FT_OutlineGlyph glyph ) 275*37da2899SCharles.Forsyth { 276*37da2899SCharles.Forsyth FT_Outline_Done( FT_GLYPH( glyph )->library, &glyph->outline ); 277*37da2899SCharles.Forsyth } 278*37da2899SCharles.Forsyth 279*37da2899SCharles.Forsyth 280*37da2899SCharles.Forsyth static FT_Error ft_outline_glyph_copy(FT_OutlineGlyph source,FT_OutlineGlyph target)281*37da2899SCharles.Forsyth ft_outline_glyph_copy( FT_OutlineGlyph source, 282*37da2899SCharles.Forsyth FT_OutlineGlyph target ) 283*37da2899SCharles.Forsyth { 284*37da2899SCharles.Forsyth FT_Error error; 285*37da2899SCharles.Forsyth FT_Library library = FT_GLYPH( source )->library; 286*37da2899SCharles.Forsyth 287*37da2899SCharles.Forsyth 288*37da2899SCharles.Forsyth error = FT_Outline_New( library, source->outline.n_points, 289*37da2899SCharles.Forsyth source->outline.n_contours, &target->outline ); 290*37da2899SCharles.Forsyth if ( !error ) 291*37da2899SCharles.Forsyth FT_Outline_Copy( &source->outline, &target->outline ); 292*37da2899SCharles.Forsyth 293*37da2899SCharles.Forsyth return error; 294*37da2899SCharles.Forsyth } 295*37da2899SCharles.Forsyth 296*37da2899SCharles.Forsyth 297*37da2899SCharles.Forsyth static void ft_outline_glyph_transform(FT_OutlineGlyph glyph,FT_Matrix * matrix,FT_Vector * delta)298*37da2899SCharles.Forsyth ft_outline_glyph_transform( FT_OutlineGlyph glyph, 299*37da2899SCharles.Forsyth FT_Matrix* matrix, 300*37da2899SCharles.Forsyth FT_Vector* delta ) 301*37da2899SCharles.Forsyth { 302*37da2899SCharles.Forsyth if ( matrix ) 303*37da2899SCharles.Forsyth FT_Outline_Transform( &glyph->outline, matrix ); 304*37da2899SCharles.Forsyth 305*37da2899SCharles.Forsyth if ( delta ) 306*37da2899SCharles.Forsyth FT_Outline_Translate( &glyph->outline, delta->x, delta->y ); 307*37da2899SCharles.Forsyth } 308*37da2899SCharles.Forsyth 309*37da2899SCharles.Forsyth 310*37da2899SCharles.Forsyth static void ft_outline_glyph_bbox(FT_OutlineGlyph glyph,FT_BBox * bbox)311*37da2899SCharles.Forsyth ft_outline_glyph_bbox( FT_OutlineGlyph glyph, 312*37da2899SCharles.Forsyth FT_BBox* bbox ) 313*37da2899SCharles.Forsyth { 314*37da2899SCharles.Forsyth FT_Outline_Get_CBox( &glyph->outline, bbox ); 315*37da2899SCharles.Forsyth } 316*37da2899SCharles.Forsyth 317*37da2899SCharles.Forsyth 318*37da2899SCharles.Forsyth static FT_Error ft_outline_glyph_prepare(FT_OutlineGlyph glyph,FT_GlyphSlot slot)319*37da2899SCharles.Forsyth ft_outline_glyph_prepare( FT_OutlineGlyph glyph, 320*37da2899SCharles.Forsyth FT_GlyphSlot slot ) 321*37da2899SCharles.Forsyth { 322*37da2899SCharles.Forsyth slot->format = FT_GLYPH_FORMAT_OUTLINE; 323*37da2899SCharles.Forsyth slot->outline = glyph->outline; 324*37da2899SCharles.Forsyth slot->outline.flags &= ~FT_OUTLINE_OWNER; 325*37da2899SCharles.Forsyth 326*37da2899SCharles.Forsyth return FT_Err_Ok; 327*37da2899SCharles.Forsyth } 328*37da2899SCharles.Forsyth 329*37da2899SCharles.Forsyth 330*37da2899SCharles.Forsyth const FT_Glyph_Class ft_outline_glyph_class = 331*37da2899SCharles.Forsyth { 332*37da2899SCharles.Forsyth sizeof( FT_OutlineGlyphRec ), 333*37da2899SCharles.Forsyth FT_GLYPH_FORMAT_OUTLINE, 334*37da2899SCharles.Forsyth 335*37da2899SCharles.Forsyth (FT_Glyph_InitFunc) ft_outline_glyph_init, 336*37da2899SCharles.Forsyth (FT_Glyph_DoneFunc) ft_outline_glyph_done, 337*37da2899SCharles.Forsyth (FT_Glyph_CopyFunc) ft_outline_glyph_copy, 338*37da2899SCharles.Forsyth (FT_Glyph_TransformFunc)ft_outline_glyph_transform, 339*37da2899SCharles.Forsyth (FT_Glyph_GetBBoxFunc) ft_outline_glyph_bbox, 340*37da2899SCharles.Forsyth (FT_Glyph_PrepareFunc) ft_outline_glyph_prepare 341*37da2899SCharles.Forsyth }; 342*37da2899SCharles.Forsyth 343*37da2899SCharles.Forsyth 344*37da2899SCharles.Forsyth /*************************************************************************/ 345*37da2899SCharles.Forsyth /*************************************************************************/ 346*37da2899SCharles.Forsyth /**** ****/ 347*37da2899SCharles.Forsyth /**** FT_Glyph class and API ****/ 348*37da2899SCharles.Forsyth /**** ****/ 349*37da2899SCharles.Forsyth /*************************************************************************/ 350*37da2899SCharles.Forsyth /*************************************************************************/ 351*37da2899SCharles.Forsyth 352*37da2899SCharles.Forsyth static FT_Error ft_new_glyph(FT_Library library,const FT_Glyph_Class * clazz,FT_Glyph * aglyph)353*37da2899SCharles.Forsyth ft_new_glyph( FT_Library library, 354*37da2899SCharles.Forsyth const FT_Glyph_Class* clazz, 355*37da2899SCharles.Forsyth FT_Glyph* aglyph ) 356*37da2899SCharles.Forsyth { 357*37da2899SCharles.Forsyth FT_Memory memory = library->memory; 358*37da2899SCharles.Forsyth FT_Error error; 359*37da2899SCharles.Forsyth FT_Glyph glyph; 360*37da2899SCharles.Forsyth 361*37da2899SCharles.Forsyth 362*37da2899SCharles.Forsyth *aglyph = 0; 363*37da2899SCharles.Forsyth 364*37da2899SCharles.Forsyth if ( !FT_ALLOC( glyph, clazz->glyph_size ) ) 365*37da2899SCharles.Forsyth { 366*37da2899SCharles.Forsyth glyph->library = library; 367*37da2899SCharles.Forsyth glyph->clazz = clazz; 368*37da2899SCharles.Forsyth glyph->format = clazz->glyph_format; 369*37da2899SCharles.Forsyth 370*37da2899SCharles.Forsyth *aglyph = glyph; 371*37da2899SCharles.Forsyth } 372*37da2899SCharles.Forsyth 373*37da2899SCharles.Forsyth return error; 374*37da2899SCharles.Forsyth } 375*37da2899SCharles.Forsyth 376*37da2899SCharles.Forsyth 377*37da2899SCharles.Forsyth /* documentation is in ftglyph.h */ 378*37da2899SCharles.Forsyth 379*37da2899SCharles.Forsyth FT_EXPORT_DEF( FT_Error ) FT_Glyph_Copy(FT_Glyph source,FT_Glyph * target)380*37da2899SCharles.Forsyth FT_Glyph_Copy( FT_Glyph source, 381*37da2899SCharles.Forsyth FT_Glyph *target ) 382*37da2899SCharles.Forsyth { 383*37da2899SCharles.Forsyth FT_Glyph copy; 384*37da2899SCharles.Forsyth FT_Error error; 385*37da2899SCharles.Forsyth const FT_Glyph_Class* clazz; 386*37da2899SCharles.Forsyth 387*37da2899SCharles.Forsyth 388*37da2899SCharles.Forsyth /* check arguments */ 389*37da2899SCharles.Forsyth if ( !target || !source || !source->clazz ) 390*37da2899SCharles.Forsyth { 391*37da2899SCharles.Forsyth error = FT_Err_Invalid_Argument; 392*37da2899SCharles.Forsyth goto Exit; 393*37da2899SCharles.Forsyth } 394*37da2899SCharles.Forsyth 395*37da2899SCharles.Forsyth *target = 0; 396*37da2899SCharles.Forsyth 397*37da2899SCharles.Forsyth clazz = source->clazz; 398*37da2899SCharles.Forsyth error = ft_new_glyph( source->library, clazz, © ); 399*37da2899SCharles.Forsyth if ( error ) 400*37da2899SCharles.Forsyth goto Exit; 401*37da2899SCharles.Forsyth 402*37da2899SCharles.Forsyth copy->advance = source->advance; 403*37da2899SCharles.Forsyth copy->format = source->format; 404*37da2899SCharles.Forsyth 405*37da2899SCharles.Forsyth if ( clazz->glyph_copy ) 406*37da2899SCharles.Forsyth error = clazz->glyph_copy( source, copy ); 407*37da2899SCharles.Forsyth 408*37da2899SCharles.Forsyth if ( error ) 409*37da2899SCharles.Forsyth FT_Done_Glyph( copy ); 410*37da2899SCharles.Forsyth else 411*37da2899SCharles.Forsyth *target = copy; 412*37da2899SCharles.Forsyth 413*37da2899SCharles.Forsyth Exit: 414*37da2899SCharles.Forsyth return error; 415*37da2899SCharles.Forsyth } 416*37da2899SCharles.Forsyth 417*37da2899SCharles.Forsyth 418*37da2899SCharles.Forsyth /* documentation is in ftglyph.h */ 419*37da2899SCharles.Forsyth 420*37da2899SCharles.Forsyth FT_EXPORT_DEF( FT_Error ) FT_Get_Glyph(FT_GlyphSlot slot,FT_Glyph * aglyph)421*37da2899SCharles.Forsyth FT_Get_Glyph( FT_GlyphSlot slot, 422*37da2899SCharles.Forsyth FT_Glyph *aglyph ) 423*37da2899SCharles.Forsyth { 424*37da2899SCharles.Forsyth FT_Library library = slot->library; 425*37da2899SCharles.Forsyth FT_Error error; 426*37da2899SCharles.Forsyth FT_Glyph glyph; 427*37da2899SCharles.Forsyth 428*37da2899SCharles.Forsyth const FT_Glyph_Class* clazz = 0; 429*37da2899SCharles.Forsyth 430*37da2899SCharles.Forsyth 431*37da2899SCharles.Forsyth if ( !slot ) 432*37da2899SCharles.Forsyth return FT_Err_Invalid_Slot_Handle; 433*37da2899SCharles.Forsyth 434*37da2899SCharles.Forsyth if ( !aglyph ) 435*37da2899SCharles.Forsyth return FT_Err_Invalid_Argument; 436*37da2899SCharles.Forsyth 437*37da2899SCharles.Forsyth /* if it is a bitmap, that's easy :-) */ 438*37da2899SCharles.Forsyth if ( slot->format == FT_GLYPH_FORMAT_BITMAP ) 439*37da2899SCharles.Forsyth clazz = &ft_bitmap_glyph_class; 440*37da2899SCharles.Forsyth 441*37da2899SCharles.Forsyth /* it it is an outline too */ 442*37da2899SCharles.Forsyth else if ( slot->format == FT_GLYPH_FORMAT_OUTLINE ) 443*37da2899SCharles.Forsyth clazz = &ft_outline_glyph_class; 444*37da2899SCharles.Forsyth 445*37da2899SCharles.Forsyth else 446*37da2899SCharles.Forsyth { 447*37da2899SCharles.Forsyth /* try to find a renderer that supports the glyph image format */ 448*37da2899SCharles.Forsyth FT_Renderer render = FT_Lookup_Renderer( library, slot->format, 0 ); 449*37da2899SCharles.Forsyth 450*37da2899SCharles.Forsyth 451*37da2899SCharles.Forsyth if ( render ) 452*37da2899SCharles.Forsyth clazz = &render->glyph_class; 453*37da2899SCharles.Forsyth } 454*37da2899SCharles.Forsyth 455*37da2899SCharles.Forsyth if ( !clazz ) 456*37da2899SCharles.Forsyth { 457*37da2899SCharles.Forsyth error = FT_Err_Invalid_Glyph_Format; 458*37da2899SCharles.Forsyth goto Exit; 459*37da2899SCharles.Forsyth } 460*37da2899SCharles.Forsyth 461*37da2899SCharles.Forsyth /* create FT_Glyph object */ 462*37da2899SCharles.Forsyth error = ft_new_glyph( library, clazz, &glyph ); 463*37da2899SCharles.Forsyth if ( error ) 464*37da2899SCharles.Forsyth goto Exit; 465*37da2899SCharles.Forsyth 466*37da2899SCharles.Forsyth /* copy advance while converting it to 16.16 format */ 467*37da2899SCharles.Forsyth glyph->advance.x = slot->advance.x << 10; 468*37da2899SCharles.Forsyth glyph->advance.y = slot->advance.y << 10; 469*37da2899SCharles.Forsyth 470*37da2899SCharles.Forsyth /* now import the image from the glyph slot */ 471*37da2899SCharles.Forsyth error = clazz->glyph_init( glyph, slot ); 472*37da2899SCharles.Forsyth 473*37da2899SCharles.Forsyth /* if an error occurred, destroy the glyph */ 474*37da2899SCharles.Forsyth if ( error ) 475*37da2899SCharles.Forsyth FT_Done_Glyph( glyph ); 476*37da2899SCharles.Forsyth else 477*37da2899SCharles.Forsyth *aglyph = glyph; 478*37da2899SCharles.Forsyth 479*37da2899SCharles.Forsyth Exit: 480*37da2899SCharles.Forsyth return error; 481*37da2899SCharles.Forsyth } 482*37da2899SCharles.Forsyth 483*37da2899SCharles.Forsyth 484*37da2899SCharles.Forsyth /* documentation is in ftglyph.h */ 485*37da2899SCharles.Forsyth 486*37da2899SCharles.Forsyth FT_EXPORT_DEF( FT_Error ) FT_Glyph_Transform(FT_Glyph glyph,FT_Matrix * matrix,FT_Vector * delta)487*37da2899SCharles.Forsyth FT_Glyph_Transform( FT_Glyph glyph, 488*37da2899SCharles.Forsyth FT_Matrix* matrix, 489*37da2899SCharles.Forsyth FT_Vector* delta ) 490*37da2899SCharles.Forsyth { 491*37da2899SCharles.Forsyth const FT_Glyph_Class* clazz; 492*37da2899SCharles.Forsyth FT_Error error = FT_Err_Ok; 493*37da2899SCharles.Forsyth 494*37da2899SCharles.Forsyth 495*37da2899SCharles.Forsyth if ( !glyph || !glyph->clazz ) 496*37da2899SCharles.Forsyth error = FT_Err_Invalid_Argument; 497*37da2899SCharles.Forsyth else 498*37da2899SCharles.Forsyth { 499*37da2899SCharles.Forsyth clazz = glyph->clazz; 500*37da2899SCharles.Forsyth if ( clazz->glyph_transform ) 501*37da2899SCharles.Forsyth { 502*37da2899SCharles.Forsyth /* transform glyph image */ 503*37da2899SCharles.Forsyth clazz->glyph_transform( glyph, matrix, delta ); 504*37da2899SCharles.Forsyth 505*37da2899SCharles.Forsyth /* transform advance vector */ 506*37da2899SCharles.Forsyth if ( matrix ) 507*37da2899SCharles.Forsyth FT_Vector_Transform( &glyph->advance, matrix ); 508*37da2899SCharles.Forsyth } 509*37da2899SCharles.Forsyth else 510*37da2899SCharles.Forsyth error = FT_Err_Invalid_Glyph_Format; 511*37da2899SCharles.Forsyth } 512*37da2899SCharles.Forsyth return error; 513*37da2899SCharles.Forsyth } 514*37da2899SCharles.Forsyth 515*37da2899SCharles.Forsyth 516*37da2899SCharles.Forsyth /* documentation is in ftglyph.h */ 517*37da2899SCharles.Forsyth 518*37da2899SCharles.Forsyth FT_EXPORT_DEF( void ) FT_Glyph_Get_CBox(FT_Glyph glyph,FT_UInt bbox_mode,FT_BBox * acbox)519*37da2899SCharles.Forsyth FT_Glyph_Get_CBox( FT_Glyph glyph, 520*37da2899SCharles.Forsyth FT_UInt bbox_mode, 521*37da2899SCharles.Forsyth FT_BBox *acbox ) 522*37da2899SCharles.Forsyth { 523*37da2899SCharles.Forsyth const FT_Glyph_Class* clazz; 524*37da2899SCharles.Forsyth 525*37da2899SCharles.Forsyth 526*37da2899SCharles.Forsyth if ( !acbox ) 527*37da2899SCharles.Forsyth return; 528*37da2899SCharles.Forsyth 529*37da2899SCharles.Forsyth acbox->xMin = acbox->yMin = acbox->xMax = acbox->yMax = 0; 530*37da2899SCharles.Forsyth 531*37da2899SCharles.Forsyth if ( !glyph || !glyph->clazz ) 532*37da2899SCharles.Forsyth return; 533*37da2899SCharles.Forsyth else 534*37da2899SCharles.Forsyth { 535*37da2899SCharles.Forsyth clazz = glyph->clazz; 536*37da2899SCharles.Forsyth if ( !clazz->glyph_bbox ) 537*37da2899SCharles.Forsyth return; 538*37da2899SCharles.Forsyth else 539*37da2899SCharles.Forsyth { 540*37da2899SCharles.Forsyth /* retrieve bbox in 26.6 coordinates */ 541*37da2899SCharles.Forsyth clazz->glyph_bbox( glyph, acbox ); 542*37da2899SCharles.Forsyth 543*37da2899SCharles.Forsyth /* perform grid fitting if needed */ 544*37da2899SCharles.Forsyth if ( bbox_mode & ft_glyph_bbox_gridfit ) 545*37da2899SCharles.Forsyth { 546*37da2899SCharles.Forsyth acbox->xMin &= -64; 547*37da2899SCharles.Forsyth acbox->yMin &= -64; 548*37da2899SCharles.Forsyth acbox->xMax = ( acbox->xMax + 63 ) & -64; 549*37da2899SCharles.Forsyth acbox->yMax = ( acbox->yMax + 63 ) & -64; 550*37da2899SCharles.Forsyth } 551*37da2899SCharles.Forsyth 552*37da2899SCharles.Forsyth /* convert to integer pixels if needed */ 553*37da2899SCharles.Forsyth if ( bbox_mode & ft_glyph_bbox_truncate ) 554*37da2899SCharles.Forsyth { 555*37da2899SCharles.Forsyth acbox->xMin >>= 6; 556*37da2899SCharles.Forsyth acbox->yMin >>= 6; 557*37da2899SCharles.Forsyth acbox->xMax >>= 6; 558*37da2899SCharles.Forsyth acbox->yMax >>= 6; 559*37da2899SCharles.Forsyth } 560*37da2899SCharles.Forsyth } 561*37da2899SCharles.Forsyth } 562*37da2899SCharles.Forsyth return; 563*37da2899SCharles.Forsyth } 564*37da2899SCharles.Forsyth 565*37da2899SCharles.Forsyth 566*37da2899SCharles.Forsyth /* documentation is in ftglyph.h */ 567*37da2899SCharles.Forsyth 568*37da2899SCharles.Forsyth FT_EXPORT_DEF( FT_Error ) FT_Glyph_To_Bitmap(FT_Glyph * the_glyph,FT_Render_Mode render_mode,FT_Vector * origin,FT_Bool destroy)569*37da2899SCharles.Forsyth FT_Glyph_To_Bitmap( FT_Glyph* the_glyph, 570*37da2899SCharles.Forsyth FT_Render_Mode render_mode, 571*37da2899SCharles.Forsyth FT_Vector* origin, 572*37da2899SCharles.Forsyth FT_Bool destroy ) 573*37da2899SCharles.Forsyth { 574*37da2899SCharles.Forsyth FT_GlyphSlotRec dummy; 575*37da2899SCharles.Forsyth FT_Error error = FT_Err_Ok; 576*37da2899SCharles.Forsyth FT_Glyph glyph; 577*37da2899SCharles.Forsyth FT_BitmapGlyph bitmap = NULL; 578*37da2899SCharles.Forsyth 579*37da2899SCharles.Forsyth const FT_Glyph_Class* clazz; 580*37da2899SCharles.Forsyth 581*37da2899SCharles.Forsyth 582*37da2899SCharles.Forsyth /* check argument */ 583*37da2899SCharles.Forsyth if ( !the_glyph ) 584*37da2899SCharles.Forsyth goto Bad; 585*37da2899SCharles.Forsyth 586*37da2899SCharles.Forsyth /* we render the glyph into a glyph bitmap using a `dummy' glyph slot */ 587*37da2899SCharles.Forsyth /* then calling FT_Render_Glyph_Internal() */ 588*37da2899SCharles.Forsyth 589*37da2899SCharles.Forsyth glyph = *the_glyph; 590*37da2899SCharles.Forsyth if ( !glyph ) 591*37da2899SCharles.Forsyth goto Bad; 592*37da2899SCharles.Forsyth 593*37da2899SCharles.Forsyth clazz = glyph->clazz; 594*37da2899SCharles.Forsyth 595*37da2899SCharles.Forsyth /* when called with a bitmap glyph, do nothing and return succesfully */ 596*37da2899SCharles.Forsyth if ( clazz == &ft_bitmap_glyph_class ) 597*37da2899SCharles.Forsyth goto Exit; 598*37da2899SCharles.Forsyth 599*37da2899SCharles.Forsyth if ( !clazz || !clazz->glyph_prepare ) 600*37da2899SCharles.Forsyth goto Bad; 601*37da2899SCharles.Forsyth 602*37da2899SCharles.Forsyth FT_MEM_ZERO( &dummy, sizeof ( dummy ) ); 603*37da2899SCharles.Forsyth dummy.library = glyph->library; 604*37da2899SCharles.Forsyth dummy.format = clazz->glyph_format; 605*37da2899SCharles.Forsyth 606*37da2899SCharles.Forsyth /* create result bitmap glyph */ 607*37da2899SCharles.Forsyth error = ft_new_glyph( glyph->library, &ft_bitmap_glyph_class, 608*37da2899SCharles.Forsyth (FT_Glyph*)&bitmap ); 609*37da2899SCharles.Forsyth if ( error ) 610*37da2899SCharles.Forsyth goto Exit; 611*37da2899SCharles.Forsyth 612*37da2899SCharles.Forsyth #if 0 613*37da2899SCharles.Forsyth /* if `origin' is set, translate the glyph image */ 614*37da2899SCharles.Forsyth if ( origin ) 615*37da2899SCharles.Forsyth FT_Glyph_Transform( glyph, 0, origin ); 616*37da2899SCharles.Forsyth #else 617*37da2899SCharles.Forsyth FT_UNUSED( origin ); 618*37da2899SCharles.Forsyth #endif 619*37da2899SCharles.Forsyth 620*37da2899SCharles.Forsyth /* prepare dummy slot for rendering */ 621*37da2899SCharles.Forsyth error = clazz->glyph_prepare( glyph, &dummy ); 622*37da2899SCharles.Forsyth if ( !error ) 623*37da2899SCharles.Forsyth error = FT_Render_Glyph_Internal( glyph->library, &dummy, render_mode ); 624*37da2899SCharles.Forsyth 625*37da2899SCharles.Forsyth #if 0 626*37da2899SCharles.Forsyth if ( !destroy && origin ) 627*37da2899SCharles.Forsyth { 628*37da2899SCharles.Forsyth FT_Vector v; 629*37da2899SCharles.Forsyth 630*37da2899SCharles.Forsyth 631*37da2899SCharles.Forsyth v.x = -origin->x; 632*37da2899SCharles.Forsyth v.y = -origin->y; 633*37da2899SCharles.Forsyth FT_Glyph_Transform( glyph, 0, &v ); 634*37da2899SCharles.Forsyth } 635*37da2899SCharles.Forsyth #endif 636*37da2899SCharles.Forsyth 637*37da2899SCharles.Forsyth if ( error ) 638*37da2899SCharles.Forsyth goto Exit; 639*37da2899SCharles.Forsyth 640*37da2899SCharles.Forsyth /* in case of success, copy the bitmap to the glyph bitmap */ 641*37da2899SCharles.Forsyth error = ft_bitmap_glyph_init( bitmap, &dummy ); 642*37da2899SCharles.Forsyth if ( error ) 643*37da2899SCharles.Forsyth goto Exit; 644*37da2899SCharles.Forsyth 645*37da2899SCharles.Forsyth /* copy advance */ 646*37da2899SCharles.Forsyth bitmap->root.advance = glyph->advance; 647*37da2899SCharles.Forsyth 648*37da2899SCharles.Forsyth if ( destroy ) 649*37da2899SCharles.Forsyth FT_Done_Glyph( glyph ); 650*37da2899SCharles.Forsyth 651*37da2899SCharles.Forsyth *the_glyph = FT_GLYPH( bitmap ); 652*37da2899SCharles.Forsyth 653*37da2899SCharles.Forsyth Exit: 654*37da2899SCharles.Forsyth if ( error && bitmap ) 655*37da2899SCharles.Forsyth FT_Done_Glyph( FT_GLYPH( bitmap ) ); 656*37da2899SCharles.Forsyth 657*37da2899SCharles.Forsyth return error; 658*37da2899SCharles.Forsyth 659*37da2899SCharles.Forsyth Bad: 660*37da2899SCharles.Forsyth error = FT_Err_Invalid_Argument; 661*37da2899SCharles.Forsyth goto Exit; 662*37da2899SCharles.Forsyth } 663*37da2899SCharles.Forsyth 664*37da2899SCharles.Forsyth 665*37da2899SCharles.Forsyth /* documentation is in ftglyph.h */ 666*37da2899SCharles.Forsyth 667*37da2899SCharles.Forsyth FT_EXPORT_DEF( void ) FT_Done_Glyph(FT_Glyph glyph)668*37da2899SCharles.Forsyth FT_Done_Glyph( FT_Glyph glyph ) 669*37da2899SCharles.Forsyth { 670*37da2899SCharles.Forsyth if ( glyph ) 671*37da2899SCharles.Forsyth { 672*37da2899SCharles.Forsyth FT_Memory memory = glyph->library->memory; 673*37da2899SCharles.Forsyth const FT_Glyph_Class* clazz = glyph->clazz; 674*37da2899SCharles.Forsyth 675*37da2899SCharles.Forsyth 676*37da2899SCharles.Forsyth if ( clazz->glyph_done ) 677*37da2899SCharles.Forsyth clazz->glyph_done( glyph ); 678*37da2899SCharles.Forsyth 679*37da2899SCharles.Forsyth FT_FREE( glyph ); 680*37da2899SCharles.Forsyth } 681*37da2899SCharles.Forsyth } 682*37da2899SCharles.Forsyth 683*37da2899SCharles.Forsyth 684*37da2899SCharles.Forsyth /* END */ 685