|
View:
New views
11 Messages
—
Rating Filter:
Alert me
|
|
|
FT_Slot_LoadFunc load_flags info?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?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?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?> - 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?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?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?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?> - 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 |
|
|
Re: FT_Slot_LoadFunc load_flags info?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?>> 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?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 |
| Free embeddable forum powered by Nabble | Forum Help |