简体   繁体   中英

Rendering font character LSB or placement varies

I am running into inconsistencies with how glyphs are spaced in some situations.

I am using DirectWrite with a IDWriteFontFace and using the GetGlyphIndices with GetDesignGlyphMetrics to get the metrics of the glyphs so I can take each glyph, store it as an image, then reconstruct the whole string using the glyph information (advance, lsb, rsb, etc). I am rendering each glyph using ID2D1RenderTarget.DrawTextLayout with WIC bitmaps. While 99% of tests I have done seem to work, I am running into inconsistent spacing and I have no idea what is causing it. Maybe someone can shed some light, but I am not sure where to start.

From my basic interpretation the font layout is composed of rendering the glyphs as lsb + width, and then the place to put the next character is called the advance and the advance width is composed of lsb, glyph width, rsb.


I am using this Zapfino font, because it seems fairly complex and a good metric to test if things are rendering correctly.

So here are some rendering comparisons line by line:

  1. correct render: Here are two different strings left and right, correctly rendered through paint.net

  2. my render: I include the advance placements (red) and the starting position (yellow). On the left, we have World, rendered, and the orld. is correctly placed, but the distance between W and o is too large now compared to the correct rendering.

    On the right side we have Hold. rendered and for the most part is consistent with the paint.net render.

  3. I overlap both to give a better idea of comparison. I align the left of the orld, so you can see that atleast that part is consistent. it's the W is off. Right side is almost identical.

  4. Paint.net shows the cursor position in what I assume is the advance. You can see that the advance placement, the o is right on top of it. But with o on the right side, you can see it has distance from advance to the o. When rendering the o at the front (5), next to a different character, or by itself, it still has that distance. I believe (appearance wise) it's the LSB that seems to shrink?

  5. orld.rendered with paint.net with the cursor. You can see the o is intersecting the advance, Some other examples, We has the same problem as Wo, shrunk LSB, but for instance in Wi, the glyph has proper distance from the advance. like it would be on its own.

在此处输入图像描述

What is this effect called where it shrinks the LSB or moves the placement of the glyph depending on characters? How can I detect such behavior through glyph data?

Shaping takes care of GPOS kerning automatically, you don't need to access values directly. Layout goes through shaping obviously, applying kerning this way. IDWriteTextLayout1 interface allows enabling pair kerning per range, but that probably only used if no kerning GPOS feature is available.

Basically, rendering with plain design advances and nominal glyphs is only useful for demonstration purposes, everything else should go through shaping process, either with layout API or manually through GetGlyphs()/GetGlyphPlacements().

I figured it out, it is kerning. I was thrown off because when I checked the font, DirectWrite returns 0 for HasKerningPairs . However, I opened up the font in a font editor and could see it does have kerning pairs. Further looking at the docs it says:

Newer fonts may have only GPOS kerning instead of the legacy pair-table kerning. Such fonts, like Gabriola, will only return 0's for adjustments. GetKerningPairAdjustments doesn't virtualize and flatten these GPOS entries into kerning pairs.

They don't offer any other way to grab them, so this is a dead end. There is no way to get these variables from the font in DirectWrite, which I find odd because the built in TextLayout makes these adjustments internally. However, as such there is no solution to this issue with the API provided by DirectWrite, this can be marked solved and unresolved.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM