FT_Slot_LoadFunc load_flags info?

View: New views
11 Messages — Rating Filter:   Alert me  

FT_Slot_LoadFunc load_flags info?

by Ian Britten :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hi all,
As discussed here before a bit, I'm in the awkward position of
having a custom (unsanctioned) FT_Driver, for accessing our custom
font file format via FT.  (Generally works well though! :) )

I'm wondering if there's any docs (or if anyone can summarize)
which of the various FT_LOAD_* flags my FT_Slot_LoadFunc function
is responsible for detecting/obeying, and which ones I can ignore?
http://freetype.sourceforge.net/freetype2/docs/reference/ft2-base_interface.html#FT_LOAD_XXX

In our initial rendering pipeline, this wasn't much of a problem,
since we controlled the rendering, and didn't use (m)any of these
flags.  However, I'm now using Cairo some, and am finding my font
not working in some workflows.  It seems to be due to my driver
basically ignoring the load_flags parameter, which I'm now trying
to fix.

I've already learnt that FT_LOAD_NO_SCALE needs to be handled [*],
and I'm thinking maybe FT_LOAD_IGNORE_TRANSFORM needs to be handled
too (Or, maybe I am supposed to be doing something when that flag
*isn't* present?  Hmmm...).
Any others?


[*] Can someone sanity-check my pseudo-calculations for NO_SCALE?
        double xScale, yScale;
        if (load_flags & FT_LOAD_NO_SCALE)
               xScale = yScale = inSlot->face->scale;
        else
               xScale = inSlot->face->scale *
                     inSize->metrics.x_scale / (double)(0x10000);
               yScale = inSlot->face->scale *
                     inSize->metrics.y_scale / (double)(0x10000);
        ...
        currPnt.x = xScale * myPnt.x;
        currPnt.y = yScale * myPnt.y;
        inSlot->face->glyph_loader->current.outline.points[count]
                                                    = currPnt;

Many thanks for any info/help!
Ian


_______________________________________________
Freetype-devel mailing list
Freetype-devel@...
http://lists.nongnu.org/mailman/listinfo/freetype-devel

Re: FT_Slot_LoadFunc load_flags info?

by Ian Britten :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Ian Britten wrote:
   [ snip ]
> However, I'm now using Cairo some, and am finding my font
> not working in some workflows.  It seems to be due to my driver
> basically ignoring the load_flags parameter, which I'm now trying
> to fix.
   [ snip ]
> I'm thinking maybe FT_LOAD_IGNORE_TRANSFORM needs to be handled

Ok, maybe all that was too much for one message... :P

How about a couple of specific questions?
- Is a font driver responsible for checking for the presence/absence
   of the FT_LOAD_IGNORE_TRANSFORM bit when loading a glyph?  I
   didn't see any of the other drivers doing anything with it...

Assuming 'yes', what is the correct behaviour?
- If the bit is set, then return the points as I currently am?
   (Ignoring stuff is easy! :)
- If the bit is absent, then ...  transform ... ?? by ??

OTOH, if the IGNORE_TRANSFORM bit isn't my concern, then I must
be pursuing the wrong problem ...

Many thanks for any information!
Ian


_______________________________________________
Freetype-devel mailing list
Freetype-devel@...
http://lists.nongnu.org/mailman/listinfo/freetype-devel

Re: FT_Slot_LoadFunc load_flags info?

by Werner LEMBERG :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message


Sorry for the late reply.

> I'm wondering if there's any docs (or if anyone can summarize) which
> of the various FT_LOAD_* flags my FT_Slot_LoadFunc function is
> responsible for detecting/obeying, and which ones I can ignore?

No, there isn't.

> I've already learnt that FT_LOAD_NO_SCALE needs to be handled [*],
> and I'm thinking maybe FT_LOAD_IGNORE_TRANSFORM needs to be handled
> too (Or, maybe I am supposed to be doing something when that flag
> *isn't* present?  Hmmm...).  Any others?

I suggest that you check which of those flags is used in the files
located in the src/base subdirectory -- a grep for `FT_LOAD_' gives 28
lines.

> [*] Can someone sanity-check my pseudo-calculations for NO_SCALE?
>        double xScale, yScale;
>        if (load_flags & FT_LOAD_NO_SCALE)
>               xScale = yScale = inSlot->face->scale;
>        else
>               xScale = inSlot->face->scale *
>                     inSize->metrics.x_scale / (double)(0x10000);
>               yScale = inSlot->face->scale *
>                     inSize->metrics.y_scale / (double)(0x10000);
>        ...
>        currPnt.x = xScale * myPnt.x;
>        currPnt.y = yScale * myPnt.y;
>        inSlot->face->glyph_loader->current.outline.points[count]
>                                                    = currPnt;

I always have difficulties with the scaling parameters :-) In
ttgload.c, function TT_Process_Simple_Glyph, you can find

  FT_Vector*  vec     = outline->points;
  FT_Vector*  limit   = outline->points + n_points;
  FT_Fixed    x_scale = ((TT_Size)loader->size)->metrics.x_scale;
  FT_Fixed    y_scale = ((TT_Size)loader->size)->metrics.y_scale;


  for ( ; vec < limit; vec++ )
  {
    vec->x = FT_MulFix( vec->x, x_scale );
    vec->y = FT_MulFix( vec->y, y_scale );
  }


    Werner


_______________________________________________
Freetype-devel mailing list
Freetype-devel@...
http://lists.nongnu.org/mailman/listinfo/freetype-devel

Re: FT_Slot_LoadFunc load_flags info?

by Werner LEMBERG :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message


> - Is a font driver responsible for checking for the presence/absence
>   of the FT_LOAD_IGNORE_TRANSFORM bit when loading a glyph?

No.  Transforming happens after the font driver has done its job; this
flag is used in files from the `src/base' directory only[1].


    Werner


[1] The exception is the `autofit' module which just uses this flag as
    an application would do.


_______________________________________________
Freetype-devel mailing list
Freetype-devel@...
http://lists.nongnu.org/mailman/listinfo/freetype-devel

Re: FT_Slot_LoadFunc load_flags info?

by Ian Britten :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Werner LEMBERG wrote:
>> - Is a font driver responsible for checking for the presence/absence
>>   of the FT_LOAD_IGNORE_TRANSFORM bit when loading a glyph?
>
> No.  Transforming happens after the font driver has done its job; this
> flag is used in files from the `src/base' directory only[1].

Many thanks for the clarification!  While grubbing through the TT
driver, I had basically come to the same conclusion.

Further digging now has me focused on the various 'advance' fields
the driver may return.  Altering their values improves some results,
but I still can't get things fully correct...
Maybe I can bug you a bit more?  :)

First, I'm trying to reconcile the font definitions from
http://freetype.sourceforge.net/freetype2/docs/glyphs/glyphs-3.html#section-1
with my fonts, and finally with the plethora of different 'advance'
fields in the FT_GlyphSlotRec that I think I'm expected to populate.
[ As well, doubles vs 26.6 vs 16.16 ... ]

My glyphs are very simple/dumb, consisting solely of their geometry,
and no bearings, advances, etc.  The only quirk is that (0,0) is
typically their centre, not the lower-left corner, and I'm not sure
if that needs to be reflected in some of these settings or not.

Solely based on experimentation of what works so far, here's my latest
take on what to set:

         // These are obvious
         slot->metrics.width = myWidth;
         slot->metrics.height = myHeight;

         // Bearings
         slot->metrics.horiBearingX = myMinX; // NEGATIVE ?
         slot->metrics.horiBearingY = myMaxY;

         // Advance #1
         slot->metrics.horiAdvance = 0;
         ft_synthesize_vertical_metrics(&slot->metrics,
                                        slot->metrics.vertAdvance);

         // Advance #2 (What's the diff?)
         slot->linearHoriAdvance = 0;
         slot->linearVertAdvance = 0;

         // Advance #3 (Unused?)
         slot->advance.x = 0;
         slot->advance.y = 0;

         // Presumably none of the other fields are relevant to
         // this discussion ...

With this, my glyphs still draw in our existing (non-Cairo) rendering
code, and also for rendering to an *upright* Cairo surface.  However,
once I set a rotation on Cairo, it seems to render text via a
different path, which presumably uses some fields I [still] don't have
set correctly.  Similarly, rendering the filled glyphs vs just their
outlines (via cairo_glyph_path()) is another case that I'm
struggling with.
Note that I'm doing all my rendering with FT_LOAD_NO_HINTING.

So basically, I'm hoping that if I can get these fields correctly set,
then all cases will automagically work, and I won't have to try to
debug the the FreeType/me/Cairo combination ... :P

As such, any information/suggestions would be greatly appreciated!
Or, if any more information would be helpful, please ask.
Many thanks in advance!
Ian


_______________________________________________
Freetype-devel mailing list
Freetype-devel@...
http://lists.nongnu.org/mailman/listinfo/freetype-devel

Re: FT_Slot_LoadFunc load_flags info?

by Werner LEMBERG :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message


Ian,

you are obviously talking about an FT_GlyphSlotRec structure:

>         // These are obvious
>         slot->metrics.width = myWidth;
>         slot->metrics.height = myHeight;

Depending on the FT_LOAD_NO_SCALE flag, the values are either in
(scaled) 26.6 format or unscaled font units, representing the
dimensions of the *hinted* metrics.

>         slot->metrics.horiBearingX = myMinX; // NEGATIVE ?
>         slot->metrics.horiBearingY = myMaxY;

Yes, these values can be negative too.  Depending on the
FT_LOAD_NO_SCALE flag, the values are either in (scaled) 26.6 format
or unscaled font units, again representing *hinted* metrics.

>         // Advance #1
>         slot->metrics.horiAdvance = 0;
>         ft_synthesize_vertical_metrics(&slot->metrics,
>                                        slot->metrics.vertAdvance);

The horizontal advance is the amount you have to move the cursor to
the right (or down for vertical layouts); this is a *hinted* value.
Depending on the FT_LOAD_NO_SCALE flag, the values are either in
(scaled) 26.6 format or unscaled font units.

>         // Advance #2 (What's the diff?)
>         slot->linearHoriAdvance = 0;
>         slot->linearVertAdvance = 0;

These are *unhinted* values, as needed for device-independent layout.
Depending on the FT_LOAD_LINEAR_DESIGN flag, the values are either in
(scaled) 16.16 format or unscaled font units.

>         // Advance #3 (Unused?)
>         slot->advance.x = 0;
>         slot->advance.y = 0;

This is a shorthand: Depending on FT_LOAD_VERTICAL_LAYOUT, this value
contains either metrics.horiAdvance or metrics.vertAdvance;
additionally, depending on FT_LOAD_IGNORE_TRANSFORM, the
transformation matrix has been applied to it.  I'll try to improve the
documentation which is a bit fuzzy here.

Hopefully, I've got everything right :-)


    Werner


_______________________________________________
Freetype-devel mailing list
Freetype-devel@...
http://lists.nongnu.org/mailman/listinfo/freetype-devel

Re: FT_Slot_LoadFunc load_flags info?

by Ian Britten :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Werner LEMBERG wrote:

> you are obviously talking about an FT_GlyphSlotRec structure:

Ya, sorry if I wasn't clear about that.

Many thanks for the info - very helpful!  If you can put up with me
a bit more, I'd like to clarify just a couple more points though,
mostly about what the fields represent, since you've largely
covered scaling, 26.6, etc...

Just to recap:  My font driver is generally working correctly, in
both our custom rendering code, and when the font is rendered via
Cairo.  There's just a couple of rendering cases that aren't working
correctly, and my suspicion is that in those cases, Cairo is using
some fields of my FT_GlyphSlotRec that aren't populated correctly.

For clarity, lets imagine a simple glyph/example, and work with real
numbers:
- The font has no hinting, so the geometry is always just it's points
   (Besides, I always call load_glyph() with the NO_HINTING flag).
- It's cover is [(-800, -1000), (800, 1000)], as an example.
- Imagine NO_SCALE is passed in, so all(?) values are in font units.
   Obviously, the code needs to be updated accordingly for this flag.

>>         // These are obvious
>>         slot->metrics.width = 1600;
>>         slot->metrics.height = 2000;

>>         slot->metrics.horiBearingX = -800;
>>         slot->metrics.horiBearingY = 1000;

Since my origin is in the centre of the glyph, these are basically
half the width/height, right?

>>         // Advance #1 (Hinted)
>>         slot->metrics.horiAdvance = ;
>>         slot->metrics.vertAdvance = 0;
>
> The horizontal advance is the amount you have to move the cursor to
> the right (or down for vertical layouts);

This is where I start to scratch my head ...
- Should this be the width of my glyph?
- Or maybe half the width (From the Origin to the right edge)?
- Or should it be zero?  Zero seems to work in _some_ cases...

This also seems to be one of the key fields that is giving me grief.
In some cases, zero seems right, but in other cases, 'width' seems
right.  I suspect something else may be wrong elsewhere, but I'd
like to ensure I've got these numbers/fields right first ...

>>         // Advance #2 (Unhinted)
>>         slot->linearHoriAdvance = slot->metrics.horiAdvance;
>>         slot->linearVertAdvance = slot->metrics.vertAdvance;
 >
> These are *unhinted* values, as needed for device-independent layout.

Since I have no hinting, these just the same as the
slot->metrics values, right?

>>         // Advance #3
>>         slot->advance.x = slot->metrics.horiAdvance;
>>         slot->advance.y = 0;
>
> This is a shorthand: Depending on FT_LOAD_VERTICAL_LAYOUT, this value
> contains either metrics.horiAdvance or metrics.vertAdvance;


FYI...
I also seem to be getting a FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH flag?
Do I need to alter anything due to this, or is it something the caller
is responsible for?  The comments in src/truetype/ttgload.c almost
suggest I shouldn't be seeing this flag ...

> Hopefully, I've got everything right :-)

Any info you can provide will hopefully make my stuff "more right"
than it currently is!  I must confess that getting this stuff to work
correctly through all 3 codebases (Me, FT, Cairo) is pretty
confusing ...
[ And actually, it's *4*, since we use ICU for layout/kerning/etc ]

Again, many thanks!
Ian



_______________________________________________
Freetype-devel mailing list
Freetype-devel@...
http://lists.nongnu.org/mailman/listinfo/freetype-devel

Re: FT_Slot_LoadFunc load_flags info?

by Werner LEMBERG :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message


> - It's cover is [(-800, -1000), (800, 1000)], as an example.

This is quite unusual for a glyph...

>>>         // These are obvious
>>>         slot->metrics.width = 1600;
>>>         slot->metrics.height = 2000;
>
>>>         slot->metrics.horiBearingX = -800;
>>>         slot->metrics.horiBearingY = 1000;
>
> Since my origin is in the centre of the glyph,

This is unusual, too.  Normally, the origin is left of the glyph (or
above the glyph in case for vertical typesetting).

> these are basically half the width/height, right?

Yes.  Look at the attached image (from the tutorial); note that
horiBearingX is negative for your glyph dimensions.

>> The horizontal advance is the amount you have to move the cursor to
>> the right (or down for vertical layouts);
>
> This is where I start to scratch my head ...
> - Should this be the width of my glyph?

This value is completely independent from the actual glyph!  It's up
to you how much whitespace you want to have between your glyphs.
Basically, it's a design decision; of course, in most cases the
advance width is larger than the glyph's width.

To summarize: The advance width gives the distance from the origin of
a glyph to the origin of the next glyph.

> - Or should it be zero?  Zero seems to work in _some_ cases...

This surprises me.  Zero should make all glyphs positioned at the same
place, overwriting each other.

>>>         // Advance #2 (Unhinted)
>>>         slot->linearHoriAdvance = slot->metrics.horiAdvance;
>>>         slot->linearVertAdvance = slot->metrics.vertAdvance;
>>
>> These are *unhinted* values, as needed for device-independent
>> layout.
>
> Since I have no hinting, these just the same as the slot->metrics
> values, right?

Yes, but possibly with another scaling (in case you don't use font
units).

> I also seem to be getting a FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH
> flag?

Uh, how comes?  You should never need this flag.

> The comments in src/truetype/ttgload.c almost suggest I shouldn't be
> seeing this flag ...

Exactly.


    Werner


_______________________________________________
Freetype-devel mailing list
Freetype-devel@...
http://lists.nongnu.org/mailman/listinfo/freetype-devel

metrics.png (2K) Download Attachment

Re: FT_Slot_LoadFunc load_flags info?

by Ian Britten :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Werner LEMBERG wrote:
>> - It's cover is [(-800, -1000), (800, 1000)], as an example.
>
> This is quite unusual for a glyph...

>> Since my origin is in the centre of the glyph,
>
> This is unusual, too.  Normally, the origin is left of the glyph (or
> above the glyph in case for vertical typesetting).

Ya, no kidding ...  :P
These 'fonts' are an old, home-grown solution dating back before
TT/FT/etc, and violate lots of conventions/assumptions:  Arbitrary
origins, open path strokes, variable line thicknesses, etc... :(

[ Aside ] I'm just (really) happy that I can generally hide most of
the details/discrepancies within a single custom FT driver, and
keep most of the calling code in all our applications clean and
simple!  Thanks!  :)

>> these are basically half the width/height, right?
>
> Yes.  Look at the attached image (from the tutorial); note that
> horiBearingX is negative for your glyph dimensions.

Ya, thanks.  That's what I was working from.  I was just hesitant
since the accompanying docs say: "It is positive for horizontal
layouts..." and I wasn't sure whether my negative value would work.

>>> The horizontal advance is the amount you have to move the cursor to
>>> the right (or down for vertical layouts);
>> This is where I start to scratch my head ...
>> - Should this be the width of my glyph?
>
> This value is completely independent from the actual glyph!  It's up
> to you how much whitespace you want to have between your glyphs.
> Basically, it's a design decision; of course, in most cases the
> advance width is larger than the glyph's width.
>
> To summarize: The advance width gives the distance from the origin of
> a glyph to the origin of the next glyph.

Hmmm, so if I set the advance equal to the glyph width, they should
be packed tight together?

I wonder if we have crossed some wires/concepts in our higher-level
layout code?  I know we have "pair kerning", and I return some info
from these fonts in response to that request.

However, our (font-agnostic) layout code works correctly with TT
fonts, which is why I keep suspecting something in this driver...

>> - Or should it be zero?  Zero seems to work in _some_ cases...
>
> This surprises me.  Zero should make all glyphs positioned at the same
> place, overwriting each other.

Until I opened this rats-nest, it seems we were always returning
zero, and maybe our layout handles advancing itself?  We do lots of
wacky text rendering, including text-along-curves, track-kerning,
block/HTML-like text, etc.

When I change the advance to be the glyph width, one of the
problematic Cairo cases seems better.  However, that makes little
sense to be, since we only ever draw text one glyph at a time, with
our layout determining the position/size/angle/etc of each glyph.

The mystery deepens ...  :/
[ Again though, the more confidence I have that my driver is
returning the correct information, the more chance I can unravel
this ... ]

>> I also seem to be getting a FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH
>> flag?
>
> Uh, how comes?  You should never need this flag.

Don't ask me - I'm just a font driver!  :)

Seriously though, when we load glyphs (either via FT or Cairo),
we only use NO_HINTING (And IGNORE_TRANSFORM it seems, in one case).
All the other flags my driver receives, including
IGNORE_GLOBAL_ADVANCE_WIDTH, are being turned on by FT/Cairo.

In this particular case though, _cairo_ft_scaled_glyph_init()
(src/cairo-ft-font.c) contains this line:
     /* Ignore global advance unconditionally */
     load_flags |= FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH;
I don't know why ...

This gets back to the root of my original question though - Which
FT_LOAD_ flags does my driver need to handle, and which ones are
just being turned on due to higher-level processing (But which my
driver can ignore)...

Anyways, this thread has given me a lot to digest so far.  I'm
going to try and incorporate the definitive information you've
provided, review our layout/advance stuff, and see where I stand
after that.
As always, many thanks!
Ian



_______________________________________________
Freetype-devel mailing list
Freetype-devel@...
http://lists.nongnu.org/mailman/listinfo/freetype-devel

Re: FT_Slot_LoadFunc load_flags info?

by Werner LEMBERG :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message


>> To summarize: The advance width gives the distance from the origin
>> of a glyph to the origin of the next glyph.
>
> Hmmm, so if I set the advance equal to the glyph width, they should
> be packed tight together?

Yes (if there is no kerning, of course).

> When I change the advance to be the glyph width, one of the
> problematic Cairo cases seems better.  However, that makes little
> sense to be, since we only ever draw text one glyph at a time, with
> our layout determining the position/size/angle/etc of each glyph.

I fear you have to debug this issue by yourself...

> Seriously though, when we load glyphs (either via FT or Cairo), we
> only use NO_HINTING (And IGNORE_TRANSFORM it seems, in one case).
> All the other flags my driver receives, including
> IGNORE_GLOBAL_ADVANCE_WIDTH, are being turned on by FT/Cairo.

Hmm.

> In this particular case though, _cairo_ft_scaled_glyph_init()
> (src/cairo-ft-font.c) contains this line:
>     /* Ignore global advance unconditionally */
>     load_flags |= FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH;
> I don't know why ...

You should ask the Cairo developers for the reasons.


    Werner


_______________________________________________
Freetype-devel mailing list
Freetype-devel@...
http://lists.nongnu.org/mailman/listinfo/freetype-devel

Re: FT_Slot_LoadFunc load_flags info?

by Ian Britten :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Werner LEMBERG wrote:
>>> The horizontal advance is the amount you have to move the cursor to
>>> the right (or down for vertical layouts);

> This value is completely independent from the actual glyph!  It's up
> to you how much whitespace you want to have between your glyphs.
> Basically, it's a design decision; of course, in most cases the
> advance width is larger than the glyph's width.
>
> To summarize: The advance width gives the distance from the origin of
> a glyph to the origin of the next glyph.
>
>> - Or should it be zero?  Zero seems to work in _some_ cases...
>
> This surprises me.  Zero should make all glyphs positioned at the same
> place, overwriting each other.

Werner,
Based on this (and the previous) info, I think I've got my driver
updated, and it seems to have resolved most of my Cairo-related
problems! :)  (But broke some of our existing stuff).

Furthermore, tracking down the regressions this triggered in the rest
of our code eventually revealed that our 'advance' and 'kerning'
values were getting intertwined.  Basically, the font driver was
leaving the 'advance' value as zero, and the 'kerning' value being
returned was sortof an advance+kerning value.  (Not quite, and I'm
not sure how I'll resolve it, but it's entirely my problem - Not FT).

My sincere thanks for your patience and help!  I've still got issues
to get cleaned up and finalized, but I think the worst has passed! :)
Many thanks!
Ian


_______________________________________________
Freetype-devel mailing list
Freetype-devel@...
http://lists.nongnu.org/mailman/listinfo/freetype-devel