freetype-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Devel] a quick exit for FT_Set_Char_Size


From: Graham Asher
Subject: [Devel] a quick exit for FT_Set_Char_Size
Date: Wed, 11 Feb 2004 16:51:46 -0000

Dear FreeTypers,

while working on speeding up my cartographic library CartoType, of which
FreeType is an essential part, I found that a lot of time was spent
recomputing font instance metrics (for example, TrueType fonts often require
the execution of a large hinting program that recomputes values used at a
particular size) when this was actually unnecessary. I put a small patch
into FT_Set_Char_Size that exits immediately if the sizes are unchanged, and
it helped a lot.

Here is the patch. I am not sure whether it is official FreeType policy to
add logic like this or whether calling routines are intended to do their own
checking, so I don't know whether David or Werner will approve it, but it
has been helpful to me. I give the new version of FT_Set_Char_Size including
the patch, which I have commented starting with 'GA:'.

  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 )
  {
    FT_Error          error = FT_Err_Ok;
    FT_Driver         driver;
    FT_Driver_Class   clazz;
    FT_Size_Metrics*  metrics;
    FT_Long           dim_x, dim_y;


    if ( !face || !face->size || !face->driver )
      return FT_Err_Invalid_Face_Handle;

    driver  = face->driver;
    metrics = &face->size->metrics;

    if ( !char_width )
      char_width = char_height;

    else if ( !char_height )
      char_height = char_width;

    if ( !horz_resolution )
      horz_resolution = 72;

    if ( !vert_resolution )
      vert_resolution = 72;

    driver = face->driver;
    clazz  = driver->clazz;

    /* default processing -- this can be overridden by the driver */
    if ( char_width  < 1 * 64 )
      char_width  = 1 * 64;
    if ( char_height < 1 * 64 )
      char_height = 1 * 64;

   /* Compute pixel sizes in 26.6 units. we use rounding
    */
    dim_x = ( ( char_width  * horz_resolution + (36+32*72) ) / 72 ) & -64;
    dim_y = ( ( char_height * vert_resolution + (36+32*72) ) / 72 ) & -64;

    /* GA: added quick exit to avoid very slow recomputation of instance
metrics; e.g., when interpreting the TrueType face program. */
    if (metrics->x_ppem == (FT_UShort)( dim_x >> 6 ) &&
        metrics->y_ppem == (FT_UShort)( dim_y >> 6 ))
      return FT_Err_Ok;

    metrics->x_ppem  = (FT_UShort)( dim_x >> 6 );
    metrics->y_ppem  = (FT_UShort)( dim_y >> 6 );

    metrics->x_scale = 0x10000L;
    metrics->y_scale = 0x10000L;

    if ( face->face_flags & FT_FACE_FLAG_SCALABLE )
    {
      metrics->x_scale = FT_DivFix( dim_x, face->units_per_EM );
      metrics->y_scale = FT_DivFix( dim_y, face->units_per_EM );

      ft_recompute_scaled_metrics( face, metrics );
    }

    if ( clazz->set_char_sizes )
      error = clazz->set_char_sizes( face->size,
                                     char_width,
                                     char_height,
                                     horz_resolution,
                                     vert_resolution );
    return error;
  }

Best wishes,

Graham Asher






reply via email to

[Prev in Thread] Current Thread [Next in Thread]