freetype
[Top][All Lists]
Advanced

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

[ft] FreeType Library Question


From: Stoiko Todorov
Subject: [ft] FreeType Library Question
Date: Tue, 23 Nov 2010 14:54:42 +0200

Lifted directly from the FT FAQ:

---------------
I set the pixel size to 8×8, but the resulting glyphs are larger (or
smaller) than that. Why?

A lot of people have difficulties to understand this topic, because
they think of glyphs as fixed-width or fixed-height ‘cells’, like
those of fonts used in terminals/consoles. This assumption is not
valid with most ‘modern’ font formats, even for bitmapped-based ones
like PCF or BDF.

Be aware that the character size that is set either through
FT_Set_Char_Size() or FT_Set_Pixel_Sizes() isn't directly related to
the dimension of the generated glyph bitmaps!

Rather, the character size is indeed the size of an abstract square,
called the EM, used by typographers to design fonts. Scaling two
distinct fonts to the same character size, be it expressed in points
or pixels, generally results in bitmaps with distinct dimensions!

Note that historically, the EM corresponded to the width of a capital
‘M’ in Latin typefaces. However, later improvements in typography led
to designs that greatly deviate from this rule. Today, it is not
possible to connect the EM size to a specific font ‘feature’ in a
reliable way.
----------------


You can always scale the glyph to fit where you need it (i dont see
why anyone would need this except if separate glyphs are rendered).
from the freetype docs:

----------------
It is possible to specify an affine transformation to be applied to
glyph images when they are loaded. Of course, this will only work for
scalable (vectorial) font formats.

To do that, simply call FT_Set_Transform, as in:


 error = FT_Set_Transform(
           face,       /* target face object    */
           &matrix,    /* pointer to 2x2 matrix */
           &delta );   /* pointer to 2d vector  */
----------------

I guess this (again googled) gives an answer to your "outline"
rendering question:

----------------
... note that the anti-aliased renderer allows you to convert a
vectorial glyph outline into a list of ‘spans’ (i.e., horizontal pixel
segments with the same coverage) that can be rendered through
user-provided callbacks.

By providing the appropriate span callback, you can render
anti-aliased text to any kind of surface. You can also use any colour,
fill pattern or fill image if you want to. This process is called
direct rendering.

   FT_Raster_Params  params;
   FT_Outline        outline;


   ... load vectorial glyph in ‘outline’ ...

   params.flags      = FT_RASTER_FLAG_AA | FT_RASTER_FLAG_DIRECT;
   params.gray_spans = (FT_Raster_Span_Func)your_own_span_function;
   params.user       = your_own_data_pointer;

   error = FT_Outline_Render( library, &outline, &params );
Note that direct rendering is not available with monochrome output, as
the current renderer uses a two-pass algorithm to generate glyphs with
correct drop-out control.
----------------


2010/11/23 Ivailo Stoianov <address@hidden>:
> Hello FreeType Team,
>
> I am Ivailo Stoianov, and I am trying to use The FreeType Library (ver.
> 2.4.2) to use TrueType fonts.
>
> I have some issues about that, so I would like to ask you for help!
>
> My first question is about glyph size. When I specify exact pixel size for
> the glyph, the generated bitmap has smaller dimensions. For example: if I
> execute the folowing code (I am using standart Windows Arial font in all
> examples):
>
>     FT_Library library;
>     FT_Error result;
>     FT_Face face;
>     FT_Matrix matrix;
>     FT_Vector delta;
>
>     result = FT_Init_FreeType(&library);
>     result = FT_New_Face(library, "arial.ttf", 0, &face);
>
>     result = FT_Set_Pixel_Sizes(face, 250, 250);
>
>     delta.x = 0 * 64;
>     delta.y = 0 * 64;
>
>     matrix.xx = 0x10000L;
>     matrix.xy = 0x0000L;
>     matrix.yx = 0x0000L;
>     matrix.yy = 0x10000L;
>
>     FT_Set_Transform(face, &matrix, &delta);
>
>     result = FT_Load_Char(face, 'D' , FT_LOAD_RENDER | FT_LOAD_MONOCHROME);
>
> the 'face' object has the following fields:
>
>   FACE:
>
>      NUM. FACES(face->num_faces): '1'
>
>      FACE INDEX(face->face_index): '0'
>
>      FACE FLAGS(face->face_flags): '00000A59'
>
>      STYLE FLAGS(face->style_flags): '00000000'
>
>      NUM. GLYPHS(face->num_glyphs): '3415'
>
>      FAMILY NAME(face->family_name): 'Arial'
>
>      STYLE NAME(face->style_name): 'Regular'
>
>      NUM. CHARMAPS(face->num_charmaps): '3'
>
>    BBOX:
>
>      X MIN(face->bbox.xMin): '-1361'
>
>      X MAX(face->bbox.xMax): '4096'
>
>      Y MIN(face->bbox.yMin): '-665'
>
>      Y MAX(face->bbox.yMax): '2060'
>
>      UNITS PER EM(face->units_per_EM): '2048'
>
>      HEIGHT(face->height): '2355'
>
>      MAX ADVANCE WIDTH(face->max_advance_width): '4096'
>
>      MAX ADVANCE HEIGHT(face->max_advance_height): '2355'
>
>      UNDERLINE POSITION(face->underline_position): '-292'
>
>      UNDERLINE THICKNESS(face->underline_thickness): '150'
>
>    METRICS:
>
>      HEIGHT(face->glyph->metrics.height): '11456'
>
>      WIDTH(face->glyph->metrics.width): '9536'
>
>      HORIZONTAL ADVANCE(face->glyph->metrics.horiAdvance): '11584'
>
>      HORIZONTAL BEARING X(face->glyph->metrics.horiBearingX): '1280'
>
>      HORIZONTAL BEARING Y(face->glyph->metrics.horiBearingY): '11456'
>
>      LINEAR HORIZONTAL ADVANCE(face->glyph->linearHoriAdvance): '11832000'
>
>      LINEAR VERTICAL ADVANCE(face->glyph->linearVertAdvance): '15376000'
>
>      ADVANCE X(face->glyph->advance.x): '11584'
>
>      ADVANCE Y(face->glyph->advance.y): '0'
>
>      FORMAT(face->glyph->format): '62697473'
>
>    BITMAP:
>
>      ROWS(face->glyph->bitmap.rows): '179'
>
>      WIDTH(face->glyph->bitmap.width): '149'
>
>      PITCH(face->glyph->bitmap.pitch): '20'
>
>      BITMAP LEFT(face->glyph->bitmap_left): '20'
>
>      BITMAP TOP(face->glyph->bitmap_top): '179'
>
> The output bitmap has smaller dimensions than these specified in the '
> FT_Set_Pixel_Sizes' function. Specified size is 250x250, but the generated
> bitmap has this size - 149x179.
>
> Even if I use 'FT_Set_Char_Size' instead of ' FT_Set_Pixel_Sizes' the output
> size is not the expected by me. In the code above if I replace the row
> "result = FT_Set_Pixel_Sizes(face, 250, 250);" with "result =
> FT_Set_Char_Size(face, 50*64, 0, 96, 0);" (96 is the dpi of my monitor), the
> 'face' object has the following fields:
>
>    FACE:
>
>      NUM. FACES(face->num_faces): '1'
>
>      FACE INDEX(face->face_index): '0'
>
>      FACE FLAGS(face->face_flags): '00000A59'
>
>      STYLE FLAGS(face->style_flags): '00000000'
>
>      NUM. GLYPHS(face->num_glyphs): '3415'
>
>      FAMILY NAME(face->family_name): 'Arial'
>
>      STYLE NAME(face->style_name): 'Regular'
>
>      NUM. CHARMAPS(face->num_charmaps): '3'
>
>    BBOX:
>
>      X MIN(face->bbox.xMin): '-1361'
>
>      X MAX(face->bbox.xMax): '4096'
>
>      Y MIN(face->bbox.yMin): '-665'
>
>      Y MAX(face->bbox.yMax): '2060'
>
>      UNITS PER EM(face->units_per_EM): '2048'
>
>      HEIGHT(face->height): '2355'
>
>      MAX ADVANCE WIDTH(face->max_advance_width): '4096'
>
>      MAX ADVANCE HEIGHT(face->max_advance_height): '2355'
>
>      UNDERLINE POSITION(face->underline_position): '-292'
>
>      UNDERLINE THICKNESS(face->underline_thickness): '150'
>
>    METRICS:
>
>      HEIGHT(face->glyph->metrics.height): '3072'
>
>      WIDTH(face->glyph->metrics.width): '2560'
>
>      HORIZONTAL ADVANCE(face->glyph->metrics.horiAdvance): '3072'
>
>      HORIZONTAL BEARING X(face->glyph->metrics.horiBearingX): '320'
>
>      HORIZONTAL BEARING Y(face->glyph->metrics.horiBearingY): '3072'
>
>      LINEAR HORIZONTAL ADVANCE(face->glyph->linearHoriAdvance): '3155447'
>
>      LINEAR VERTICAL ADVANCE(face->glyph->linearVertAdvance): '4100587'
>
>      ADVANCE X(face->glyph->advance.x): '3072'
>
>      ADVANCE Y(face->glyph->advance.y): '0'
>
>      FORMAT(face->glyph->format): '62697473'
>
>    BITMAP:
>
>      ROWS(face->glyph->bitmap.rows): '48'
>
>      WIDTH(face->glyph->bitmap.width): '40'
>
>      PITCH(face->glyph->bitmap.pitch): '6'
>
>      BITMAP LEFT(face->glyph->bitmap_left): '5'
>
>      BITMAP TOP(face->glyph->bitmap_top): '48'
>
> If I use the formula "pixel_size = point_size * resolution / 72" from The
> FreeType Conventions the calculated size is 67 pixels, but the output size
> of the bitmap is smaller - 40x48 pixels. When I use 203 dpi in the function
> above (203 is the dpi of my target device), the 'face' object has the
> following fields:
>
>    FACE:
>
>      NUM. FACES(face->num_faces): '1'
>
>      FACE INDEX(face->face_index): '0'
>
>      FACE FLAGS(face->face_flags): '00000A59'
>
>      STYLE FLAGS(face->style_flags): '00000000'
>
>      NUM. GLYPHS(face->num_glyphs): '3415'
>
>      FAMILY NAME(face->family_name): 'Arial'
>
>      STYLE NAME(face->style_name): 'Regular'
>
>      NUM. CHARMAPS(face->num_charmaps): '3'
>
>    BBOX:
>
>      X MIN(face->bbox.xMin): '-1361'
>
>      X MAX(face->bbox.xMax): '4096'
>
>      Y MIN(face->bbox.yMin): '-665'
>
>      Y MAX(face->bbox.yMax): '2060'
>
>      UNITS PER EM(face->units_per_EM): '2048'
>
>      HEIGHT(face->height): '2355'
>
>      MAX ADVANCE WIDTH(face->max_advance_width): '4096'
>
>      MAX ADVANCE HEIGHT(face->max_advance_height): '2355'
>
>      UNDERLINE POSITION(face->underline_position): '-292'
>
>      UNDERLINE THICKNESS(face->underline_thickness): '150'
>
>    METRICS:
>
>      HEIGHT(face->glyph->metrics.height): '6464'
>
>      WIDTH(face->glyph->metrics.width): '5376'
>
>      HORIZONTAL ADVANCE(face->glyph->metrics.horiAdvance): '6528'
>
>      HORIZONTAL BEARING X(face->glyph->metrics.horiBearingX): '704'
>
>      HORIZONTAL BEARING Y(face->glyph->metrics.horiBearingY): '6464'
>
>      LINEAR HORIZONTAL ADVANCE(face->glyph->linearHoriAdvance): '6671769'
>
>      LINEAR VERTICAL ADVANCE(face->glyph->linearVertAdvance): '8670142'
>
>      ADVANCE X(face->glyph->advance.x): '6528'
>
>      ADVANCE Y(face->glyph->advance.y): '0'
>
>      FORMAT(face->glyph->format): '62697473'
>
>    BITMAP:
>
>      ROWS(face->glyph->bitmap.rows): '101'
>
>      WIDTH(face->glyph->bitmap.width): '84'
>
>      PITCH(face->glyph->bitmap.pitch): '12'
>
>      BITMAP LEFT(face->glyph->bitmap_left): '11'
>
>      BITMAP TOP(face->glyph->bitmap_top): '101'
>
> When I make the calculations again - the size expected by me is 141 pixels,
> but the generated image is smaller - 84x101 pixels.
>
> So, as a conclusion, my question is - Is it possible to generate birmap
> image with the size, desired by me? - for example if I want letter with size
> 200x200 pixels, the output bitmap image to be with this size or with size
> near to the desired one.
>
> My second qustion is - Is it possible to generate "outline letters" - letter
> only with outlines, without fill? - like this one Outline letter.
>
> If you need any additional information about my code(field data of other
> objects, return values of functions or something else), please, send me an
> e-mail and I will answer it as soon as possible.
>
> Thank you for the time spent on reading my mail! I look forward to your
> reply. Thanks in advance!
>
> Best regards!
>
> --
> Ivailo Stoianov - Firmware Engineer, DATECS LTD. Firmware Deparment
>
> _______________________________________________
> Freetype mailing list
> address@hidden
> http://lists.nongnu.org/mailman/listinfo/freetype
>
>



reply via email to

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