使用TextAlignment.Center在FormattedText实例上计算x偏移

时间:2018-11-16 17:59:04

标签: c# .net wpf

我有一个从Shape继承的类,还需要在OnRender(DrawingContect drawingContext)方法内精确绘制一些多行文本。

我可以填充一个矩形,该矩形恰好填充文本的矩形大小:

enter image description here

以及相关的简化代码段:

protected override void OnRender(DrawingContext drawingContext)
{
    ...

    var formattedText = new FormattedText(
        Text,
        CultureInfo.CurrentCulture,
        CultureInfo.CurrentCulture.TextInfo.IsRightToLeft
            ? FlowDirection.RightToLeft
            : FlowDirection.LeftToRight,
        TypeFace,
        FontSize,
        TextBrush
    );
    formattedText.TextAlignment = TextAlignment.Left;
    formattedText.Trimming = TextTrimming.CharacterEllipsis;
    formattedText.SetFontWeight(FontWeight);
    formattedText.MaxTextWidth = Width;
    formattedText.MaxTextHeight = Height;

    ...

    DrawShape(
        drawingContext,
        new List<Point>
        {
            new Point(0, 0),
            new Point(formattedText.Width, 0),
            new Point(formattedText.Width, formattedText.Height),
            new Point(0, formattedText.Height)
        },
        brush,
        pen
    );
    drawingContext.DrawText(formattedText, new Point(0, 0));

    ... 
}

void DrawShape(DrawingContext dc, List<Point> points, Brush fill, Pen pen)
{
    var streamGeometry = new StreamGeometry();
    using (var ctx = streamGeometry.Open())
    {
        ctx.BeginFigure(points[0], true, true);
        foreach (var point in points)
        {
            ctx.LineTo(point, true, true);
        }
    }
    streamGeometry.Freeze();
    dc.DrawGeometry(fill, pen, streamGeometry);
}

我的问题是,当我尝试使用与上面相同的代码,但是使用TextAlignment.Center时,我无法正确地将该矩形放置在文本后面:

enter image description here

如何获取x偏移以正确绘制该矩形?

这不是我要实现的目标,而是一个简化的示例,突出了此问题。

1 个答案:

答案 0 :(得分:0)

有两个属性OverhandLeadingOverhandTrailing提供了以下信息:

enter image description here

我本来就忽略了这些,因为它们没有给我预期的性能,但是事实证明,我有一些不正确的逻辑来计算真实形状上的旋转中心点。

因此,对于上面的示例,要点是:

new Point(formattedText.OverhangLeading, 0),
new Point(formattedText.Width - formattedText.OverhangTrailing, 0),
new Point(formattedText.Width - formattedText.OverhangTrailing, formattedText.Height),
new Point(formattedText.OverhangLeading, formattedText.Height)