Re: Query regarding CFF font handling
Tony Smith <[email protected]> Thu, 23 Oct 2025 15:09:26 +0100
| Newsgroups | gmane.comp.fonts.freetype.devel |
|---|---|
| Message-ID | <CAK57--xc7iMevqydxwdkOBs0t23+2h+FeaC=KmJfZFnYtkNt_w@mail.gmail.com> |
--000000000000c8bb3b0641d3fb4b
Content-Type: text/plain; charset="UTF-8"
Thanks for the quick response Alexei.
I hope I am understanding the issue correctly regarding the use of
FT_ADVANCE_FLAG_FAST_ONLY .
I've used both the 2.13.2 release and the 2.14.1 release.
I am loading in a ccf font.
In 2.13.2, the call to FT_Get_Advance always succeeds.
In 2.14.1, it always fails, regardless of the FT_ADVANCE_FLAG_FAST_ONLY
flag.
My code did set FT_ADVANCE_FLAG_FAST_ONLY.
Specifically I was setting the flag to the following
flag = (FT_LOAD_NO_SCALE | FT_ADVANCE_FLAG_FAST_ONLY );
and this would then call
FT_Get_Advance(face, glyph_index, flag, &nonscaledAdvance);
This call to FT_Get_Advance fails using the 2.14.1 release.
(As a note, we will always be doing a fast check because we set
FT_LOAD_NO_SCALE - in the function FT_Get_Advance, the call to the
LOAD_ADVANCE_FAST_CHECK macro will return true.)
Next I tested removing FT_ADVANCE_FLAG_FAST_ONLY.
So this is just
flag = FT_LOAD_NO_SCALE;
again calling
FT_Get_Advance(face, glyph_index, flag, &nonscaledAdvance);
This call to FT_Get_Advance also fails in the 2.14.1 code.
The reason for the failure is that the first check in the function
cff_get_advance, shown below, always fails. At no point is there a check
for FT_ADVANCE_FLAG_FAST_ONLY of the flag passed into the function.
cff_get_advance( ... )
{
if ( !FT_IS_SFNT( face ) ) // <-----
always fails, regardless of the flags
return FT_THROW( Unimplemented_Feature );
...
}
In the 2.13.2 release, the cff_get_advances function doesn't fail because
it drops down to some code which works on the glyphs:
cff_get_advances( ... )
{
...
...
...
flags |= (FT_UInt32)FT_LOAD_ADVANCE_ONLY;
for ( nn = 0; nn < count; nn++ )
{
error = cff_glyph_load( slot, face->size, start + nn, flags );
if ( error )
break;
advances[nn] = ( flags & FT_LOAD_VERTICAL_LAYOUT )
? slot->linearVertAdvance
: slot->linearHoriAdvance;
}
}
Finally looking at the documentation
https://freetype.org/freetype2/docs/reference/ft2-quick_advance.html
This says
This function may fail if you use FT_ADVANCE_FLAG_FAST_ONLY
<https://freetype.org/freetype2/docs/reference/ft2-quick_advance.html#ft_advance_flag_fast_only>
and if the corresponding font backend doesn't have a quick way to retrieve
the advances.
But we're now seeing a failure even if we don't use this flag.
I can see that this discussion is now getting quite involved but hopefully
my explanation makes sense.
Again thanks for the help in discussing this issue, Tony Smith
On Wed, 22 Oct 2025 at 18:05, Alexei Podtelezhnikov <[email protected]>
wrote:
>
> > Otherwise, let TT_Get_Advances fall back on cff_load_glyph to do
> > slow advances. This avoids unchecked access to cff_load_glyph and
> > this is how tt_get_advances is implemented.
>
> Reading src/base/ftadvanc.c , this is exactly what should happen *unless*
> FT_ADVANCE_FLAG_FAST_ONLY is set. No?
>
>
>
>
>
>
--
This e-mail message has been scanned and cleared by Google Message Security
and the UNICOM Global security systems. This message is for the named
person's use only. If you receive this message in error, please delete it
and notify the sender.
--000000000000c8bb3b0641d3fb4b
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><div>Thanks for the quick response Alexei.</div><div><br><=
/div><div>I hope I am understanding the issue correctly regarding the use o=
f=C2=A0
FT_ADVANCE_FLAG_FAST_ONLY=20
.</div><div><br></div><div>I've used both the 2.13.2 release and the 2.=
14.1 release.</div><div>I am loading in a ccf font.<br></div><div><br></div=
><div>In 2.13.2, the call to=20
FT_Get_Advance=C2=A0always succeeds.</div><div><br></div><div>In 2.14.1, it=
always fails, regardless of the FT_ADVANCE_FLAG_FAST_ONLY flag.</div><div>=
<br></div><div>My code did set=C2=A0
FT_ADVANCE_FLAG_FAST_ONLY.</div><div>Specifically I was setting the flag to=
the following</div><div>=C2=A0 flag=C2=A0=3D (FT_LOAD_NO_SCALE | FT_ADVANC=
E_FLAG_FAST_ONLY );</div><div>and this would then call</div><div>=C2=A0 FT_=
Get_Advance(face, glyph_index, flag, &nonscaledAdvance);</div><div><br>=
</div><div>This=C2=A0call to FT_Get_Advance fails=C2=A0using the 2.14.1 rel=
ease.</div><div><br></div><div><div>(As a note, we will always be doing a f=
ast check because we set FT_LOAD_NO_SCALE -=20
=C2=A0in the function FT_Get_Advance, the call to the LOAD_ADVANCE_FAST_CHE=
CK=20
macro will return true.)</div>
<div>=C2=A0=C2=A0</div></div><div>Next=C2=A0I=C2=A0tested removing=C2=A0
FT_ADVANCE_FLAG_FAST_ONLY.</div><div>So this is just</div><div><div>=C2=A0 =
flag=C2=A0=3D=C2=A0FT_LOAD_NO_SCALE;</div>
<div>again=C2=A0calling</div>
<div>=C2=A0 FT_Get_Advance(face, glyph_index, flag, &nonscaledAdvance);=
</div>
<div>=C2=A0=C2=A0</div><div>This call to=20
FT_Get_Advance also fails=C2=A0in the 2.14.1=C2=A0code.</div><div><br></div=
><div><br></div><div>The reason for the failure is that the first check in =
the function cff_get_advance, shown below, always fails.=C2=A0 At no point =
is there a check for FT_ADVANCE_FLAG_FAST_ONLY of the flag passed into the =
function.</div>
<div><br></div></div><blockquote style=3D"margin:0 0 0 40px;border:none;pad=
ding:0px"><div><div>cff_get_advance( ... )=C2=A0 =C2=A0</div></div><div><di=
v>{</div></div><div><div>=C2=A0 =C2=A0 if ( !FT_IS_SFNT( face ) )=C2=A0 =C2=
=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 // <----- always fails, regardless of=
the flags</div></div><div><div>=C2=A0 =C2=A0 =C2=A0 return FT_THROW( Unimp=
lemented_Feature );</div></div><div><div>=C2=A0 ...</div></div><div><div>}<=
/div></div></blockquote><div><div><br></div><div>In the=20
2.13.2 release, the=C2=A0cff_get_advances function doesn't fail because=
it drops down to some code which=C2=A0works on the glyphs:</div><div><br><=
/div></div><blockquote style=3D"margin:0 0 0 40px;border:none;padding:0px">=
<div><div>cff_get_advances( ... )=C2=A0 =C2=A0</div></div><div><div>{</div>=
</div><div><div>...</div></div><div><div>...</div></div><div><div>...</div>=
</div><div><div>=C2=A0 =C2=A0 =C2=A0flags |=3D (FT_UInt32)FT_LOAD_ADVANCE_O=
NLY;</div></div></blockquote><div>
<div><br></div></div><blockquote style=3D"margin:0 0 0 40px;border:none;pad=
ding:0px"><div><div>=C2=A0 =C2=A0 for ( nn =3D 0; nn < count; nn++ )</di=
v></div><div><div>=C2=A0 =C2=A0 {</div></div><div><div>=C2=A0 =C2=A0 =C2=A0=
error =3D cff_glyph_load( slot, face->size, start + nn, flags );</div><=
/div><div><div>=C2=A0 =C2=A0 =C2=A0 if ( error )</div></div><div><div>=C2=
=A0 =C2=A0 =C2=A0 =C2=A0 break;</div></div></blockquote><div><div><br></div=
></div><blockquote style=3D"margin:0 0 0 40px;border:none;padding:0px"><div=
><div>=C2=A0 =C2=A0 =C2=A0 advances[nn] =3D ( flags & FT_LOAD_VERTICAL_=
LAYOUT )</div></div><div><div>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0? slot->linearVertAdvance</div></div><div=
><div>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0=
=C2=A0: slot->linearHoriAdvance;</div></div><div><div>=C2=A0 =C2=A0 }</=
div></div></blockquote><blockquote style=3D"margin:0 0 0 40px;border:none;p=
adding:0px"><div><div>}</div></div></blockquote><div><div><br></div><div>Fi=
nally looking at the documentation</div><div><a href=3D"https://freetype.or=
g/freetype2/docs/reference/ft2-quick_advance.html">https://freetype.org/fre=
etype2/docs/reference/ft2-quick_advance.html</a></div><div><br></div><div>T=
his says</div><div>=C2=A0This function may fail if you use <code><a href=3D=
"https://freetype.org/freetype2/docs/reference/ft2-quick_advance.html#ft_ad=
vance_flag_fast_only">FT_ADVANCE_FLAG_FAST_ONLY</a></code> and if the corre=
sponding font backend doesn't have a quick way to retrieve the advances=
.=C2=A0=C2=A0</div><div>But we're now seeing a failure even if we don&#=
39;t use this flag.</div><div><br></div><div>I can see that this discussion=
is now getting quite involved but hopefully my explanation makes sense.</d=
iv><div><br></div><div>Again thanks for the help in discussing this issue, =
Tony Smith</div><div><br></div></div><div class=3D"gmail_quote gmail_quote_=
container"><div dir=3D"ltr" class=3D"gmail_attr">On Wed, 22 Oct 2025 at 18:=
05, Alexei Podtelezhnikov <<a href=3D"mailto:[email protected]">apodtel=
[email protected]</a>> wrote:<br></div><blockquote class=3D"gmail_quote" style=
=3D"margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding=
-left:1ex"><br>> Otherwise, let TT_Get_Advances fall back on cff_load_gl=
yph to do<br>> slow advances. This avoids unchecked access to cff_load_g=
lyph and<br>>=C2=A0 this is how tt_get_advances is implemented.<br><br>R=
eading src/base/ftadvanc.c , this is exactly what should happen *unless* FT=
_ADVANCE_FLAG_FAST_ONLY is set. No?</blockquote><blockquote class=3D"gmail_=
quote" style=3D"margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,=
204);padding-left:1ex"><br></blockquote><blockquote class=3D"gmail_quote" s=
tyle=3D"margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);pad=
ding-left:1ex"><br></blockquote><blockquote class=3D"gmail_quote" style=3D"=
margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-lef=
t:1ex"><br></blockquote><blockquote class=3D"gmail_quote" style=3D"margin:0=
px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><=
br></blockquote><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0=
px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><br></blo=
ckquote><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex=
;border-left:1px solid rgb(204,204,204);padding-left:1ex"><br></blockquote>=
</div></div>
<br>
<font size=3D"1">This e-mail message has been scanned and cleared by Google=
Message Security and the UNICOM Global security systems. This message is f=
or the named person's use only. If you receive this message in error, p=
lease delete it and notify the sender. </font><br>
--000000000000c8bb3b0641d3fb4b--