freetype
[Top][All Lists]
Advanced

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

Re: [ft] Vertical font layout


From: mpsuzuki
Subject: Re: [ft] Vertical font layout
Date: Sun, 26 Mar 2006 16:20:02 +0900

Hi,

FreeType2 before 2006-02-27 had a bug that horizontal advance
is scaled but vertical advance is not scaled. The bug was fixed
on 2006-02-27, by Chia-I Wu.


2006-02-27  Chia-I Wu  <address@hidden>

        * src/base/ftobjs.c (GRID_FIT_METRICS): New macro.
        (ft_glyphslot_grid_fit_metrics, FT_Load_Glyph) [GRID_FIT_METRICS]:
        Re-enable glyph metrics grid-fitting.  It is now done in the base
        layer.
        (FT_Set_Char_Size, FT_Set_Pixel_Sizes): Make sure the width and
        height are not too small or too large, just like we were doing in
        2.1.10.

        * src/autofit/afloader.c (af_loader_load_g): The vertical metrics
        are not scaled.

By attached sample, I got following result:
        
        $ ./getmetrics_20060226.exe --size=14 --resolution=600 
--direction=horizontal --font=/home/mpsuzuki/.fonts/DejaVuSans.ttf a
        
        character [a]
          glyph slot data
            metrics.horiBearingX = 448, metrics.horiBearingY = 4160, 
metrics.horiAdvance = 4480
            metrics.vertBearingX = -473, metrics.vertBearingY = 436, 
metrics.vertAdvance = 2048
          control box data
            cbox.xMin = 7, cbox.xMax = 60
            cbox.yMin = -2, cbox.yMax = 65
          rasterized image data
            advance.x = 4587520, advance.y = 0
        
        $ ./getmetrics_20060226.exe --size=28 --resolution=600 
--direction=horizontal --font=/home/mpsuzuki/.fonts/DejaVuSans.ttf a
        character [a]
          glyph slot data
            metrics.horiBearingX = 896, metrics.horiBearingY = 8384, 
metrics.horiAdvance = 9152
            metrics.vertBearingX = -473, metrics.vertBearingY = 436, 
metrics.vertAdvance = 2048
          control box data
            cbox.xMin = 14, cbox.xMax = 122
            cbox.yMin = -3, cbox.yMax = 131
          rasterized image data
            advance.x = 9371648, advance.y = 0

You can find that horizontal metrics are different (it
depends on char size), but vertical metrics are same.
If I use FreeType2 on 2006-02-27 23:59:59, I got following
result.

        $ ./getmetrics_20060227.exe --size=14 --resolution=600 
--direction=horizontal --font=/home/mpsuzuki/.fonts/DejaVuSans.ttf a
        character [a]
          glyph slot data
            metrics.horiBearingX = 448, metrics.horiBearingY = 4160, 
metrics.horiAdvance = 4480
            metrics.vertBearingX = -1728, metrics.vertBearingY = 1536, 
metrics.vertAdvance = 7424
          control box data
            cbox.xMin = 7, cbox.xMax = 60
            cbox.yMin = -2, cbox.yMax = 65
          rasterized image data
            advance.x = 4587520, advance.y = 0
        
        $ ./getmetrics_20060227.exe --size=28 --resolution=600 
--direction=horizontal --font=/home/mpsuzuki/.fonts/DejaVuSans.ttf a
        character [a]
          glyph slot data
            metrics.horiBearingX = 896, metrics.horiBearingY = 8384, 
metrics.horiAdvance = 9152
            metrics.vertBearingX = -3456, metrics.vertBearingY = 3136, 
metrics.vertAdvance = 14976
          control box data
            cbox.xMin = 14, cbox.xMax = 122
            cbox.yMin = -3, cbox.yMax = 131
          rasterized image data
            advance.x = 9371648, advance.y = 0

You can find vertical metrics are different (it depends on
char size).

So, I recommend you to migrate latest FreeType2 on CVS
or wait for next freetype-2.2 release.

Regards,
mpsuzuki

On Tue, 14 Mar 2006 00:49:48 UT
Paresh Deshmukh <address@hidden> wrote:

>I have no idea how to get scaled value for vertical advance, please help.
>I also wonder if this is the case why Im getting proper value for Horizontal
>advance for horizontal advance??
>
>Thanks
>Paresh
>
>>
>> On Sun, 2006-03-12 at 22:42, Paresh Deshmukh wrote:
>> > Hi,
>> >
>> > 256 is incompatible with other value, I check bbox values it is perfectly
>fine.
>> > Here is some values:
>> > Char A:
>> > BBox Info:                 Bitmap Info:
>> > xMin 3                     Rows: 35
>> > yMin 1                     Width: 37
>> > xMax 40                    Pitch: 37
>> > yMax 36
>> > advance(x,y) value is (0,256).
>> Vertical advance is usually constant. It sounds to me that you have got
>> hold of an unscaled value for the vertical advance and a scaled value
>> for the bounding box.



/* ----------------------------------------------------- */

#include <ft2build.h>
#include FT_FREETYPE_H
#include FT_SFNT_NAMES_H
#include FT_TRUETYPE_IDS_H
#include FT_GLYPH_H

#include FT_MODULE_H

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

/* ----------------------------------------------------- */

#define OPTION_FONT     "--font="
#define OPTION_FACE     "--face="
#define OPTION_SIZE     "--size="
#define OPTION_RESOLUTION       "--resolution="
#define OPTION_DIRECTION        "--direction="
#define OPTION_SCALE    "--scale="

/* ----------------------------------------------------- */

void  dump_metrics( FT_Face  face,
                    FT_Bool  vertical,
                    FT_Bool  scale,
                    char     c );

void  error_exit( char* msg );

/* ----------------------------------------------------- */

int  main( int  argc, char**  argv )
{
  FT_Library  lib;
  FT_Face     face;
  int         i;
  FT_Bool     vertical = 0;
  FT_Bool     scale    = 1;


  if ( FT_Init_FreeType( &lib ) )
    error_exit( "Fail to initialize FreeType2" );

  {
    char*    ttf_path     = NULL;
    int      ttf_face_idx = 0;
    int      char_size    = 14;
    int      resolution   = 72;

    for ( i = 1; i < argc; i++ )
    {
      if ( 0 == strncmp( argv[i], OPTION_FONT, sizeof( OPTION_FONT ) - 1 ) )
        ttf_path = argv[i] + sizeof( OPTION_FONT ) - 1;
      else if ( 0 == strncmp( argv[i], OPTION_FACE, sizeof( OPTION_FACE ) - 1 ) 
)
        ttf_face_idx = atoi( argv[i] + sizeof( OPTION_FACE ) - 1 );
      else if ( 0 == strncmp( argv[i], OPTION_SIZE, sizeof( OPTION_SIZE ) - 1 ) 
)
        char_size = atoi( argv[i] + sizeof( OPTION_SIZE ) - 1 );
      else if ( 0 == strncmp( argv[i], OPTION_RESOLUTION, sizeof( 
OPTION_RESOLUTION ) - 1 ) )
        resolution = atoi( argv[i] + sizeof( OPTION_RESOLUTION ) - 1 );
      else if ( 0 == strncmp( argv[i], OPTION_DIRECTION, sizeof( 
OPTION_DIRECTION ) - 1 ) )
      {
        switch ( argv[i][ sizeof( OPTION_DIRECTION ) - 1 ] )
        {
          case 'v':
          case 'V':
            vertical = 1;
            break;

          default:
            vertical = 0;
        }
      }
      else if ( 0 == strncmp( argv[i], OPTION_SCALE, sizeof( OPTION_SCALE ) - 1 
) )
      {
        if ( 0 == strcasecmp( argv[i] + sizeof( OPTION_DIRECTION ) - 1, "yes" ) 
)
          scale = 1; 
        else if ( 0 == strcasecmp( argv[i] + sizeof( OPTION_DIRECTION ) - 1, 
"no" ) )
          scale = 0; 
      }
    }

    if ( NULL == ttf_path )
      error_exit( "No font file is specified" );
    else if ( FT_New_Face( lib, ttf_path, ttf_face_idx, &face ) )
      error_exit( "Fail to open font" );

    if ( FT_Set_Char_Size( face,
                           char_size * ( 1 << 6 ), char_size * ( 1 << 6 ),
                           resolution, resolution ) )
      error_exit( "Fail to set char size or resolution" );
  }

  for ( i = 1; i < argc; i++ )
    if ( 1 == strlen( argv[i] ) )
      dump_metrics( face, vertical, scale, argv[i][0] );
}


void  dump_metrics( FT_Face  face,
                    FT_Bool  vertical,
                    FT_Bool  scale,
                    char     c )
{
  unsigned int  gid;
  FT_Glyph      glyph_img;
  FT_BBox       glyph_bbox;
  FT_Matrix     matrix = { 0x00010000, 0,   /* xx, xy */
                           0, 0x00010000 }; /* yx, yy */
  FT_Vector     img_origin = { 0, 0 };
  FT_Int32      bbox_mode, load_flags;


  gid = FT_Get_Char_Index( face, c );

  if ( 0 < vertical )
    load_flags = FT_LOAD_NO_BITMAP | FT_LOAD_VERTICAL_LAYOUT;
  else
    load_flags = FT_LOAD_NO_BITMAP | FT_LOAD_DEFAULT;

  if ( 0 < scale )
  {
    bbox_mode   = FT_GLYPH_BBOX_PIXELS;
    // load_flags |= FT_LOAD_RENDER;
  }
  else
  {
    bbox_mode   = FT_GLYPH_BBOX_UNSCALED;
    // load_flags |= FT_LOAD_NO_SCALE;
  }

  if ( FT_Load_Glyph( face, gid, load_flags ) )
    error_exit( "Fail to load glyph" );

  if ( FT_Get_Glyph( face->glyph, &glyph_img ) )
    error_exit( "Fail to get glyph image" );

  if ( FT_Glyph_Transform( glyph_img, &matrix, 0 ) )
    error_exit( "Fail to transform glyph image" );

  FT_Glyph_Get_CBox( glyph_img, bbox_mode, &glyph_bbox );

  if ( FT_Glyph_To_Bitmap( &glyph_img, FT_RENDER_MODE_MONO, &img_origin, 1 ) )
    error_exit( "Fail to rasterize glyph" );

  printf( "character [%c]\n", c );
  printf( "  glyph slot data\n" );
  printf( "    " );
  printf( "metrics.horiBearingX = %d, ", face->glyph->metrics.horiBearingX );
  printf( "metrics.horiBearingY = %d, ", face->glyph->metrics.horiBearingY );
  printf( "metrics.horiAdvance = %d\n",  face->glyph->metrics.horiAdvance );
  printf( "    " );
  printf( "metrics.vertBearingX = %d, ", face->glyph->metrics.vertBearingX );
  printf( "metrics.vertBearingY = %d, ", face->glyph->metrics.vertBearingY );
  printf( "metrics.vertAdvance = %d\n",  face->glyph->metrics.vertAdvance );
  printf( "  control box data\n" );
  printf( "    " );
  printf( "cbox.xMin = %d, ", glyph_bbox.xMin );
  printf( "cbox.xMax = %d\n", glyph_bbox.xMax );
  printf( "    " );
  printf( "cbox.yMin = %d, ", glyph_bbox.yMin );
  printf( "cbox.yMax = %d\n", glyph_bbox.yMax );
  printf( "  rasterized image data\n" );
  printf( "    " );
  printf( "advance.x = %d, ", glyph_img->advance.x );
  printf( "advance.y = %d\n", glyph_img->advance.y );
}


void  error_exit( char*  msg )
{
  fprintf( stderr, "%s\n", msg );
  exit( -1 );
}




reply via email to

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