ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

ftglyph.c
Go to the documentation of this file.
00001 /***************************************************************************/
00002 /*                                                                         */
00003 /*  ftglyph.c                                                              */
00004 /*                                                                         */
00005 /*    FreeType convenience functions to handle glyphs (body).              */
00006 /*                                                                         */
00007 /*  Copyright 1996-2001, 2002, 2003, 2004, 2005, 2007, 2008, 2010 by       */
00008 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
00009 /*                                                                         */
00010 /*  This file is part of the FreeType project, and may only be used,       */
00011 /*  modified, and distributed under the terms of the FreeType project      */
00012 /*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
00013 /*  this file you indicate that you have read the license and              */
00014 /*  understand and accept it fully.                                        */
00015 /*                                                                         */
00016 /***************************************************************************/
00017 
00018   /*************************************************************************/
00019   /*                                                                       */
00020   /*  This file contains the definition of several convenience functions   */
00021   /*  that can be used by client applications to easily retrieve glyph     */
00022   /*  bitmaps and outlines from a given face.                              */
00023   /*                                                                       */
00024   /*  These functions should be optional if you are writing a font server  */
00025   /*  or text layout engine on top of FreeType.  However, they are pretty  */
00026   /*  handy for many other simple uses of the library.                     */
00027   /*                                                                       */
00028   /*************************************************************************/
00029 
00030 
00031 #include <ft2build.h>
00032 #include FT_GLYPH_H
00033 #include FT_OUTLINE_H
00034 #include FT_BITMAP_H
00035 #include FT_INTERNAL_OBJECTS_H
00036 
00037 #include "basepic.h"
00038 
00039   /*************************************************************************/
00040   /*                                                                       */
00041   /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */
00042   /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */
00043   /* messages during execution.                                            */
00044   /*                                                                       */
00045 #undef  FT_COMPONENT
00046 #define FT_COMPONENT  trace_glyph
00047 
00048 
00049   /*************************************************************************/
00050   /*************************************************************************/
00051   /****                                                                 ****/
00052   /****   FT_BitmapGlyph support                                        ****/
00053   /****                                                                 ****/
00054   /*************************************************************************/
00055   /*************************************************************************/
00056 
00057   FT_CALLBACK_DEF( FT_Error )
00058   ft_bitmap_glyph_init( FT_Glyph      bitmap_glyph,
00059                         FT_GlyphSlot  slot )
00060   {
00061     FT_BitmapGlyph  glyph   = (FT_BitmapGlyph)bitmap_glyph;
00062     FT_Error        error   = FT_Err_Ok;
00063     FT_Library      library = FT_GLYPH( glyph )->library;
00064 
00065 
00066     if ( slot->format != FT_GLYPH_FORMAT_BITMAP )
00067     {
00068       error = FT_Err_Invalid_Glyph_Format;
00069       goto Exit;
00070     }
00071 
00072     glyph->left = slot->bitmap_left;
00073     glyph->top  = slot->bitmap_top;
00074 
00075     /* do lazy copying whenever possible */
00076     if ( slot->internal->flags & FT_GLYPH_OWN_BITMAP )
00077     {
00078       glyph->bitmap = slot->bitmap;
00079       slot->internal->flags &= ~FT_GLYPH_OWN_BITMAP;
00080     }
00081     else
00082     {
00083       FT_Bitmap_New( &glyph->bitmap );
00084       error = FT_Bitmap_Copy( library, &slot->bitmap, &glyph->bitmap );
00085     }
00086 
00087   Exit:
00088     return error;
00089   }
00090 
00091 
00092   FT_CALLBACK_DEF( FT_Error )
00093   ft_bitmap_glyph_copy( FT_Glyph  bitmap_source,
00094                         FT_Glyph  bitmap_target )
00095   {
00096     FT_Library      library = bitmap_source->library;
00097     FT_BitmapGlyph  source  = (FT_BitmapGlyph)bitmap_source;
00098     FT_BitmapGlyph  target  = (FT_BitmapGlyph)bitmap_target;
00099 
00100 
00101     target->left = source->left;
00102     target->top  = source->top;
00103 
00104     return FT_Bitmap_Copy( library, &source->bitmap, &target->bitmap );
00105   }
00106 
00107 
00108   FT_CALLBACK_DEF( void )
00109   ft_bitmap_glyph_done( FT_Glyph  bitmap_glyph )
00110   {
00111     FT_BitmapGlyph  glyph   = (FT_BitmapGlyph)bitmap_glyph;
00112     FT_Library      library = FT_GLYPH( glyph )->library;
00113 
00114 
00115     FT_Bitmap_Done( library, &glyph->bitmap );
00116   }
00117 
00118 
00119   FT_CALLBACK_DEF( void )
00120   ft_bitmap_glyph_bbox( FT_Glyph  bitmap_glyph,
00121                         FT_BBox*  cbox )
00122   {
00123     FT_BitmapGlyph  glyph = (FT_BitmapGlyph)bitmap_glyph;
00124 
00125 
00126     cbox->xMin = glyph->left << 6;
00127     cbox->xMax = cbox->xMin + ( glyph->bitmap.width << 6 );
00128     cbox->yMax = glyph->top << 6;
00129     cbox->yMin = cbox->yMax - ( glyph->bitmap.rows << 6 );
00130   }
00131 
00132 
00133   FT_DEFINE_GLYPH(ft_bitmap_glyph_class,
00134     sizeof ( FT_BitmapGlyphRec ),
00135     FT_GLYPH_FORMAT_BITMAP,
00136 
00137     ft_bitmap_glyph_init,
00138     ft_bitmap_glyph_done,
00139     ft_bitmap_glyph_copy,
00140     0,                          /* FT_Glyph_TransformFunc */
00141     ft_bitmap_glyph_bbox,
00142     0                           /* FT_Glyph_PrepareFunc   */
00143   )
00144 
00145 
00146   /*************************************************************************/
00147   /*************************************************************************/
00148   /****                                                                 ****/
00149   /****   FT_OutlineGlyph support                                       ****/
00150   /****                                                                 ****/
00151   /*************************************************************************/
00152   /*************************************************************************/
00153 
00154 
00155   FT_CALLBACK_DEF( FT_Error )
00156   ft_outline_glyph_init( FT_Glyph      outline_glyph,
00157                          FT_GlyphSlot  slot )
00158   {
00159     FT_OutlineGlyph  glyph   = (FT_OutlineGlyph)outline_glyph;
00160     FT_Error         error   = FT_Err_Ok;
00161     FT_Library       library = FT_GLYPH( glyph )->library;
00162     FT_Outline*      source  = &slot->outline;
00163     FT_Outline*      target  = &glyph->outline;
00164 
00165 
00166     /* check format in glyph slot */
00167     if ( slot->format != FT_GLYPH_FORMAT_OUTLINE )
00168     {
00169       error = FT_Err_Invalid_Glyph_Format;
00170       goto Exit;
00171     }
00172 
00173     /* allocate new outline */
00174     error = FT_Outline_New( library, source->n_points, source->n_contours,
00175                             &glyph->outline );
00176     if ( error )
00177       goto Exit;
00178 
00179     FT_Outline_Copy( source, target );
00180 
00181   Exit:
00182     return error;
00183   }
00184 
00185 
00186   FT_CALLBACK_DEF( void )
00187   ft_outline_glyph_done( FT_Glyph  outline_glyph )
00188   {
00189     FT_OutlineGlyph  glyph = (FT_OutlineGlyph)outline_glyph;
00190 
00191 
00192     FT_Outline_Done( FT_GLYPH( glyph )->library, &glyph->outline );
00193   }
00194 
00195 
00196   FT_CALLBACK_DEF( FT_Error )
00197   ft_outline_glyph_copy( FT_Glyph  outline_source,
00198                          FT_Glyph  outline_target )
00199   {
00200     FT_OutlineGlyph  source  = (FT_OutlineGlyph)outline_source;
00201     FT_OutlineGlyph  target  = (FT_OutlineGlyph)outline_target;
00202     FT_Error         error;
00203     FT_Library       library = FT_GLYPH( source )->library;
00204 
00205 
00206     error = FT_Outline_New( library, source->outline.n_points,
00207                             source->outline.n_contours, &target->outline );
00208     if ( !error )
00209       FT_Outline_Copy( &source->outline, &target->outline );
00210 
00211     return error;
00212   }
00213 
00214 
00215   FT_CALLBACK_DEF( void )
00216   ft_outline_glyph_transform( FT_Glyph          outline_glyph,
00217                               const FT_Matrix*  matrix,
00218                               const FT_Vector*  delta )
00219   {
00220     FT_OutlineGlyph  glyph = (FT_OutlineGlyph)outline_glyph;
00221 
00222 
00223     if ( matrix )
00224       FT_Outline_Transform( &glyph->outline, matrix );
00225 
00226     if ( delta )
00227       FT_Outline_Translate( &glyph->outline, delta->x, delta->y );
00228   }
00229 
00230 
00231   FT_CALLBACK_DEF( void )
00232   ft_outline_glyph_bbox( FT_Glyph  outline_glyph,
00233                          FT_BBox*  bbox )
00234   {
00235     FT_OutlineGlyph  glyph = (FT_OutlineGlyph)outline_glyph;
00236 
00237 
00238     FT_Outline_Get_CBox( &glyph->outline, bbox );
00239   }
00240 
00241 
00242   FT_CALLBACK_DEF( FT_Error )
00243   ft_outline_glyph_prepare( FT_Glyph      outline_glyph,
00244                             FT_GlyphSlot  slot )
00245   {
00246     FT_OutlineGlyph  glyph = (FT_OutlineGlyph)outline_glyph;
00247 
00248 
00249     slot->format         = FT_GLYPH_FORMAT_OUTLINE;
00250     slot->outline        = glyph->outline;
00251     slot->outline.flags &= ~FT_OUTLINE_OWNER;
00252 
00253     return FT_Err_Ok;
00254   }
00255 
00256 
00257   FT_DEFINE_GLYPH( ft_outline_glyph_class, 
00258     sizeof ( FT_OutlineGlyphRec ),
00259     FT_GLYPH_FORMAT_OUTLINE,
00260 
00261     ft_outline_glyph_init,
00262     ft_outline_glyph_done,
00263     ft_outline_glyph_copy,
00264     ft_outline_glyph_transform,
00265     ft_outline_glyph_bbox,
00266     ft_outline_glyph_prepare
00267   )
00268 
00269 
00270   /*************************************************************************/
00271   /*************************************************************************/
00272   /****                                                                 ****/
00273   /****   FT_Glyph class and API                                        ****/
00274   /****                                                                 ****/
00275   /*************************************************************************/
00276   /*************************************************************************/
00277 
00278    static FT_Error
00279    ft_new_glyph( FT_Library             library,
00280                  const FT_Glyph_Class*  clazz,
00281                  FT_Glyph*              aglyph )
00282    {
00283      FT_Memory  memory = library->memory;
00284      FT_Error   error;
00285      FT_Glyph   glyph  = NULL;
00286 
00287 
00288      *aglyph = 0;
00289 
00290      if ( !FT_ALLOC( glyph, clazz->glyph_size ) )
00291      {
00292        glyph->library = library;
00293        glyph->clazz   = clazz;
00294        glyph->format  = clazz->glyph_format;
00295 
00296        *aglyph = glyph;
00297      }
00298 
00299      return error;
00300    }
00301 
00302 
00303   /* documentation is in ftglyph.h */
00304 
00305   FT_EXPORT_DEF( FT_Error )
00306   FT_Glyph_Copy( FT_Glyph   source,
00307                  FT_Glyph  *target )
00308   {
00309     FT_Glyph               copy;
00310     FT_Error               error;
00311     const FT_Glyph_Class*  clazz;
00312 
00313 
00314     /* check arguments */
00315     if ( !target )
00316     {
00317       error = FT_Err_Invalid_Argument;
00318       goto Exit;
00319     }
00320 
00321     *target = 0;
00322 
00323     if ( !source || !source->clazz )
00324     {
00325       error = FT_Err_Invalid_Argument;
00326       goto Exit;
00327     }
00328 
00329     clazz = source->clazz;
00330     error = ft_new_glyph( source->library, clazz, &copy );
00331     if ( error )
00332       goto Exit;
00333 
00334     copy->advance = source->advance;
00335     copy->format  = source->format;
00336 
00337     if ( clazz->glyph_copy )
00338       error = clazz->glyph_copy( source, copy );
00339 
00340     if ( error )
00341       FT_Done_Glyph( copy );
00342     else
00343       *target = copy;
00344 
00345   Exit:
00346     return error;
00347   }
00348 
00349 
00350   /* documentation is in ftglyph.h */
00351 
00352   FT_EXPORT_DEF( FT_Error )
00353   FT_Get_Glyph( FT_GlyphSlot  slot,
00354                 FT_Glyph     *aglyph )
00355   {
00356     FT_Library  library;
00357     FT_Error    error;
00358     FT_Glyph    glyph;
00359 
00360     const FT_Glyph_Class*  clazz = 0;
00361 
00362 
00363     if ( !slot )
00364       return FT_Err_Invalid_Slot_Handle;
00365 
00366     library = slot->library;
00367 
00368     if ( !aglyph )
00369       return FT_Err_Invalid_Argument;
00370 
00371     /* if it is a bitmap, that's easy :-) */
00372     if ( slot->format == FT_GLYPH_FORMAT_BITMAP )
00373       clazz = FT_BITMAP_GLYPH_CLASS_GET;
00374 
00375     /* if it is an outline */
00376     else if ( slot->format == FT_GLYPH_FORMAT_OUTLINE )
00377       clazz = FT_OUTLINE_GLYPH_CLASS_GET;
00378 
00379     else
00380     {
00381       /* try to find a renderer that supports the glyph image format */
00382       FT_Renderer  render = FT_Lookup_Renderer( library, slot->format, 0 );
00383 
00384 
00385       if ( render )
00386         clazz = &render->glyph_class;
00387     }
00388 
00389     if ( !clazz )
00390     {
00391       error = FT_Err_Invalid_Glyph_Format;
00392       goto Exit;
00393     }
00394 
00395     /* create FT_Glyph object */
00396     error = ft_new_glyph( library, clazz, &glyph );
00397     if ( error )
00398       goto Exit;
00399 
00400     /* copy advance while converting it to 16.16 format */
00401     glyph->advance.x = slot->advance.x << 10;
00402     glyph->advance.y = slot->advance.y << 10;
00403 
00404     /* now import the image from the glyph slot */
00405     error = clazz->glyph_init( glyph, slot );
00406 
00407     /* if an error occurred, destroy the glyph */
00408     if ( error )
00409       FT_Done_Glyph( glyph );
00410     else
00411       *aglyph = glyph;
00412 
00413   Exit:
00414     return error;
00415   }
00416 
00417 
00418   /* documentation is in ftglyph.h */
00419 
00420   FT_EXPORT_DEF( FT_Error )
00421   FT_Glyph_Transform( FT_Glyph    glyph,
00422                       FT_Matrix*  matrix,
00423                       FT_Vector*  delta )
00424   {
00425     const FT_Glyph_Class*  clazz;
00426     FT_Error               error = FT_Err_Ok;
00427 
00428 
00429     if ( !glyph || !glyph->clazz )
00430       error = FT_Err_Invalid_Argument;
00431     else
00432     {
00433       clazz = glyph->clazz;
00434       if ( clazz->glyph_transform )
00435       {
00436         /* transform glyph image */
00437         clazz->glyph_transform( glyph, matrix, delta );
00438 
00439         /* transform advance vector */
00440         if ( matrix )
00441           FT_Vector_Transform( &glyph->advance, matrix );
00442       }
00443       else
00444         error = FT_Err_Invalid_Glyph_Format;
00445     }
00446     return error;
00447   }
00448 
00449 
00450   /* documentation is in ftglyph.h */
00451 
00452   FT_EXPORT_DEF( void )
00453   FT_Glyph_Get_CBox( FT_Glyph  glyph,
00454                      FT_UInt   bbox_mode,
00455                      FT_BBox  *acbox )
00456   {
00457     const FT_Glyph_Class*  clazz;
00458 
00459 
00460     if ( !acbox )
00461       return;
00462 
00463     acbox->xMin = acbox->yMin = acbox->xMax = acbox->yMax = 0;
00464 
00465     if ( !glyph || !glyph->clazz )
00466       return;
00467     else
00468     {
00469       clazz = glyph->clazz;
00470       if ( !clazz->glyph_bbox )
00471         return;
00472       else
00473       {
00474         /* retrieve bbox in 26.6 coordinates */
00475         clazz->glyph_bbox( glyph, acbox );
00476 
00477         /* perform grid fitting if needed */
00478         if ( bbox_mode == FT_GLYPH_BBOX_GRIDFIT ||
00479              bbox_mode == FT_GLYPH_BBOX_PIXELS  )
00480         {
00481           acbox->xMin = FT_PIX_FLOOR( acbox->xMin );
00482           acbox->yMin = FT_PIX_FLOOR( acbox->yMin );
00483           acbox->xMax = FT_PIX_CEIL( acbox->xMax );
00484           acbox->yMax = FT_PIX_CEIL( acbox->yMax );
00485         }
00486 
00487         /* convert to integer pixels if needed */
00488         if ( bbox_mode == FT_GLYPH_BBOX_TRUNCATE ||
00489              bbox_mode == FT_GLYPH_BBOX_PIXELS   )
00490         {
00491           acbox->xMin >>= 6;
00492           acbox->yMin >>= 6;
00493           acbox->xMax >>= 6;
00494           acbox->yMax >>= 6;
00495         }
00496       }
00497     }
00498     return;
00499   }
00500 
00501 
00502   /* documentation is in ftglyph.h */
00503 
00504   FT_EXPORT_DEF( FT_Error )
00505   FT_Glyph_To_Bitmap( FT_Glyph*       the_glyph,
00506                       FT_Render_Mode  render_mode,
00507                       FT_Vector*      origin,
00508                       FT_Bool         destroy )
00509   {
00510     FT_GlyphSlotRec           dummy;
00511     FT_GlyphSlot_InternalRec  dummy_internal;
00512     FT_Error                  error = FT_Err_Ok;
00513     FT_Glyph                  glyph;
00514     FT_BitmapGlyph            bitmap = NULL;
00515 
00516     const FT_Glyph_Class*     clazz;
00517 
00518 #ifdef FT_CONFIG_OPTION_PIC
00519     FT_Library                library = FT_GLYPH( glyph )->library;
00520 #endif
00521 
00522 
00523     /* check argument */
00524     if ( !the_glyph )
00525       goto Bad;
00526 
00527     /* we render the glyph into a glyph bitmap using a `dummy' glyph slot */
00528     /* then calling FT_Render_Glyph_Internal()                            */
00529 
00530     glyph = *the_glyph;
00531     if ( !glyph )
00532       goto Bad;
00533 
00534     clazz = glyph->clazz;
00535 
00536     /* when called with a bitmap glyph, do nothing and return successfully */
00537     if ( clazz == FT_BITMAP_GLYPH_CLASS_GET )
00538       goto Exit;
00539 
00540     if ( !clazz || !clazz->glyph_prepare )
00541       goto Bad;
00542 
00543     FT_MEM_ZERO( &dummy, sizeof ( dummy ) );
00544     FT_MEM_ZERO( &dummy_internal, sizeof ( dummy_internal ) );
00545     dummy.internal = &dummy_internal;
00546     dummy.library  = glyph->library;
00547     dummy.format   = clazz->glyph_format;
00548 
00549     /* create result bitmap glyph */
00550     error = ft_new_glyph( glyph->library, FT_BITMAP_GLYPH_CLASS_GET,
00551                           (FT_Glyph*)(void*)&bitmap );
00552     if ( error )
00553       goto Exit;
00554 
00555 #if 1
00556     /* if `origin' is set, translate the glyph image */
00557     if ( origin )
00558       FT_Glyph_Transform( glyph, 0, origin );
00559 #else
00560     FT_UNUSED( origin );
00561 #endif
00562 
00563     /* prepare dummy slot for rendering */
00564     error = clazz->glyph_prepare( glyph, &dummy );
00565     if ( !error )
00566       error = FT_Render_Glyph_Internal( glyph->library, &dummy, render_mode );
00567 
00568 #if 1
00569     if ( !destroy && origin )
00570     {
00571       FT_Vector  v;
00572 
00573 
00574       v.x = -origin->x;
00575       v.y = -origin->y;
00576       FT_Glyph_Transform( glyph, 0, &v );
00577     }
00578 #endif
00579 
00580     if ( error )
00581       goto Exit;
00582 
00583     /* in case of success, copy the bitmap to the glyph bitmap */
00584     error = ft_bitmap_glyph_init( (FT_Glyph)bitmap, &dummy );
00585     if ( error )
00586       goto Exit;
00587 
00588     /* copy advance */
00589     bitmap->root.advance = glyph->advance;
00590 
00591     if ( destroy )
00592       FT_Done_Glyph( glyph );
00593 
00594     *the_glyph = FT_GLYPH( bitmap );
00595 
00596   Exit:
00597     if ( error && bitmap )
00598       FT_Done_Glyph( FT_GLYPH( bitmap ) );
00599 
00600     return error;
00601 
00602   Bad:
00603     error = FT_Err_Invalid_Argument;
00604     goto Exit;
00605   }
00606 
00607 
00608   /* documentation is in ftglyph.h */
00609 
00610   FT_EXPORT_DEF( void )
00611   FT_Done_Glyph( FT_Glyph  glyph )
00612   {
00613     if ( glyph )
00614     {
00615       FT_Memory              memory = glyph->library->memory;
00616       const FT_Glyph_Class*  clazz  = glyph->clazz;
00617 
00618 
00619       if ( clazz->glyph_done )
00620         clazz->glyph_done( glyph );
00621 
00622       FT_FREE( glyph );
00623     }
00624   }
00625 
00626 
00627 /* END */

Generated on Mon May 28 2012 04:33:34 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.