Browse Source

Fix the width of tabs with IndentationSize=1.

See http://community.sharpdevelop.net/forums/t/14176.aspx
Tab markers now report a size one pixel smaller than the tab glyph.

The problem was that if the tab glyph already advanced to (or over) the next multiple of the indentation size, the normal tab character advanced the rendering position a second time. This always happened if the IndentationSize was 1, but it could also happen in some other cases, for example when IndentationSize=4 and Text="aaa\t".

The issue is complicated by proportional fonts: there, a tab can be very small (maybe only a single pixel) if there is text in front of the tab that almost reaches the next tab position. In this case, we have only two choices: make the tab larger than it would be without the tab glyph, or have the tab glyph overlap with the next character after the tab. (a third choice would be not to draw or clip the tab glyph if there's not enough room, but that's difficult to do with the WPF text layout engine)
This fix makes the TabGlyphRun report a size one pixel smaller than the actual width of the glyph. This way the invisible tab character can fit in that one-pixel gap, which fixes the issue for monospaced fonts. But if there isn't enough room for the tab glyph (as can happen with proportional fonts), the tab will still be larger than it should be.
pull/21/merge
Daniel Grunwald 14 years ago
parent
commit
8b0de6243f
  1. 8
      src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Rendering/SingleCharacterElementGenerator.cs

8
src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Rendering/SingleCharacterElementGenerator.cs

@ -197,14 +197,14 @@ namespace ICSharpCode.AvalonEdit.Rendering @@ -197,14 +197,14 @@ namespace ICSharpCode.AvalonEdit.Rendering
public override TextEmbeddedObjectMetrics Format(double remainingParagraphWidth)
{
return new TextEmbeddedObjectMetrics(element.text.WidthIncludingTrailingWhitespace,
element.text.Height,
element.text.Baseline);
double width = Math.Min(0, element.text.WidthIncludingTrailingWhitespace - 1);
return new TextEmbeddedObjectMetrics(width, element.text.Height, element.text.Baseline);
}
public override Rect ComputeBoundingBox(bool rightToLeft, bool sideways)
{
return new Rect(0, 0, element.text.WidthIncludingTrailingWhitespace, element.text.Height);
double width = Math.Min(0, element.text.WidthIncludingTrailingWhitespace - 1);
return new Rect(0, 0, width, element.text.Height);
}
public override void Draw(DrawingContext drawingContext, Point origin, bool rightToLeft, bool sideways)

Loading…
Cancel
Save