[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [ft-devel] FT_Get_Advance() docs
From: |
Werner LEMBERG |
Subject: |
Re: [ft-devel] FT_Get_Advance() docs |
Date: |
Sun, 11 Dec 2011 15:02:29 +0100 (CET) |
> [...] I also found this bug, and used about the same fix as you
> committed. The only difference is a minor nit, in the case
> FT_LOAD_NO_SCALE is used and the quick way failed with ErrNotImplem,
> <<10 scaling might not be done.
Patch, please (or please commit by yourself).
>> The next two are more subtle and not directly related to
>> `FT_Get_Advance' (I get wrong metrics from some fonts), and I need
>> more investigation to fix them.
>
> Details please. I did found something myself, most likely a double
> rounding issue (more below), but I cannot figure where is the
> problem exactly because I do not know the internals enough :-(.
Attached is my quick'n'dirty test program.
. In the font UnicodeAll.otf, a demo font written by Ken Lunde which
is a CFF with 256 CID-keyed subfonts covering all Unicode
characters[1], all glyphs have the same width, but `FT_Load_Glyph'
returns changing width values with light hinting.
. In a Type42 font, `ft_get_advance' returns funny values for empty
glyphs.
. In arial.ttf (version 2.76), I get different linearHoriAdvance
values(!) for glyph 556 (`afii10023') if I use normal or light
hinting.
I can send you my tests fonts privately if you want to play with them.
>>> Another thing we need to document is that the ->glyph instance
>>> inside the face object might be erased after a call through
>>> FT_Get_Advance().
>>
>> Yes. Can you provide a patch?
>
> Will do.
Thanks!
>> After some thinking I now believe that it is a bug that
>> `FT_Get_Advance' returns unrounded advance widths for the light
>> hinting mode.
>
> Okay, but then we have to mimic exactly the rounding process used by
> the Load_Glyph logic*s*...
Yes, this is what the advince width function hooks into the font
modules are good for.
>>>>> when the requested ppem has an associated hdmx/VDMX table within
>>>>> the font.
>>>>
>>>> Do you volunteer to implement support for those two tables?
>>>
>>> Yes, I will do that (but not today.)
>
> I looked at it, but it does not appear to be very easy to do,
> particularly because the current (*...clazz->get_advances)()
> functions returns _unscaled_ values (which are to be scaled within
> FT_Get_Advance while "hdmx" values are pixels, hence are already
> scaled.
Mhmm, I suggest that you don't use the `clazz' route. Instead, simply
add parsing code for those two tables to `ft_get_advance'.
>>> I wonder also about a new demo program to check whether
>>> FT_Get_Advance() gives, or not, the same results as
>>> FT_Load_Glyph().
>>
>> This might be useful, yes.
>
> Attached.
Very nice, thanks! Please add it to the freetype2-demos repository
(but not adding it to the `EXES' variable in the Makefile).
> The problem I detected then was the behaviour of invocations like
> [...]
I'll have a detailed look in the next days.
Werner
[1] Converting this 70kByte font with ttx gives a whopping 140MByte
XML file; if you omit the cmap, it's only 317kByte :-)
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <ft2build.h>
#include FT_FREETYPE_H
#include FT_ADVANCES_H
int
main(int argc,
char** argv)
{
FT_Library library;
FT_Face face;
FT_UShort i;
FT_Init_FreeType(&library);
FT_New_Face(library, argv[1], 0, &face);
FT_Set_Char_Size(face, 50 * 64, 0, 100, 0);
printf("glyph index:\n"
" advance.x (normal hinting/light hinting)\n"
" linearHoriAdvance\n"
" ft_get_advance (normal hinting/light hinting)\n");
for (i = 0; i < face->num_glyphs; i++)
{
FT_Fixed advance;
double normal_advance, light_advance;
double normal_get_advance, light_get_advance;
double normal_linearHoriAdvance, light_linearHoriAdvance;
FT_Load_Glyph(face, i, FT_LOAD_DEFAULT);
normal_advance = face->glyph->advance.x / 64.0;
normal_linearHoriAdvance = face->glyph->linearHoriAdvance / 65536.0;
FT_Load_Glyph(face, i, FT_LOAD_TARGET_LIGHT);
light_advance = face->glyph->advance.x / 64.0;
light_linearHoriAdvance = face->glyph->linearHoriAdvance / 65536.0;
FT_Get_Advance(face, i, FT_LOAD_DEFAULT, &advance);
normal_get_advance = advance / 65536.0;
FT_Get_Advance(face, i, FT_LOAD_TARGET_LIGHT, &advance);
light_get_advance = advance / 65536.0;
printf("%d:\n", i);
printf(" %f %f\n", normal_advance, light_advance);
printf(" %f\n", normal_linearHoriAdvance);
if (normal_linearHoriAdvance != light_linearHoriAdvance)
printf(" Urgh: %f\n", light_linearHoriAdvance);
printf(" %f %f\n", normal_get_advance, light_get_advance);
}
FT_Done_Face(face);
FT_Done_FreeType(library);
return 0;
}