2

Does anyone know of a way to get IDWriteTextLayout to adjust the layout so that glyphs will not overhang the layout boundaries? This is particularly an issue with italics such as 'f' under some fonts when aligned to the LHS or RHS.

GDI+ by default behaves this way (see: StringformatFlagsNoFitBlackBox). One option is to implement a custom layout.. but that seems overly complicated. I would much prefer to use the standard layout if at all possible.

johnny209
  • 21
  • 2

2 Answers2

0

IDWriteTextLayout always aligns glyphs to the layout extents using the layout bounds of the glyph (glyph origin and advance width) rather than the ink, meaning the ink can indeed spill outside due to italic slope or decorations like Gabriola's fancy swashes (at least on Win7&8).

I think your best bet, short of writing your own custom layout, would be to include some explicit margin (make the layout size smaller than the control area) or expand any clip region to permit the ink to spill outside some. That's one reason why the common EDIT control and CSS default to some padding. To estimate that padding, you could just use a fixed value derived from other UI settings, a proportion of the font size, or measure once to get the DWRITE_OVERHANG_METRICS and resize a second time with an adjusted/shrunk size.

textLayout->SetMaxWidth(initialMaxWidth);
textLayout->GetOverhangMetrics(OUT &overhangMetrics);
float newSmallerWidth = initialMaxWidth
                      - std::max(overhangMetrics.left,  0.0f)
                      - std::max(overhangMetrics.right, 0.0f);
textLayout->SetMaxWidth(newSmallerWidth);
Dwayne Robinson
  • 2,034
  • 1
  • 24
  • 39
0

There is SetOpticalAlignment(DWRITE_OPTICAL_ALIGNMENT opticalAlignment) in IDWriteTextFormat1 and IDWriteTextLayout2. According to the docs,

By default, glyphs are aligned to the margin by the default origin and side-bearings of the glyph. If you specify DWRITE_OPTICAL_ALIGNMENT_NO_SIDE_BEARINGS, then the alignment uses the side bearings to offset the glyph from the aligned edge to ensure the ink of the glyphs are aligned.

However, in DWRITE_2.H there is a comment for DWRITE_OPTICAL_ALIGNMENT_NO_SIDE_BEARINGS stating:

/// Align glyphs to the margins. Without this, some small whitespace
/// may be present between the text and the margin from the glyph's side
/// bearing values. Note that glyphs may still overhang outside the
/// margin, such as flourishes or italic slants.

I have not tried it, so I cannot say if it works for your case or not. :-(

Pablo H
  • 609
  • 4
  • 22