如何从WPF上的阿拉伯字符连接位置删除笔划?

时间:2014-08-19 11:46:20

标签: c# .net wpf

我的项目使用某种字体,如阿拉伯字符,我还需要在字体上使用笔划。 我已经尝试过某种方式来显示笔划,例如:

https://stackoverflow.com/a/9887123/1900498 (OuterTextBlock)

https://stackoverflow.com/a/97728/1900498 (OutlineText)

Stroke现在可以显示,但问题是阿拉伯字符连接位置仍显示一些笔划,所以我需要将其删除

结果如下: enter image description here

那么有什么方法可以从连接位置移除笔划?我的意思是如果角色是连接,只是在完整连接上的笔划超大,而不是所有字符笔划1次。

我需要这样的结果(我正在使用 PHOTOSHOP 编辑第二张图片并从字符连接位置删除笔划,而不是 WPF ,这只是为了让您了解WPF必须处理的正确结果) enter image description here

更新 请从2链接下载2类,然后使用此代码:

<Window x:Class="test.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:test"
    Title="MainWindow" Height="200" Width="400">
<Grid Background="Black">
    <local:OutlinedTextBlock  HorizontalAlignment="Left" Height="200" VerticalAlignment="Bottom"  FontSize="150" StrokeThickness="1" Fill="White" Stroke="Red" TextDecorations="">ئالما</local:OutlinedTextBlock>
    <local:OutlinedText  HorizontalAlignment="Right" Height="200" VerticalAlignment="Top"  FontSize="150" StrokeThickness="1" Fill="White" Stroke="Red" Text="ئالما"></local:OutlinedText>
</Grid>

1 个答案:

答案 0 :(得分:4)

初步观察:您看到的工件似乎是单个字符的实际边缘。字符会轻微触摸和重叠,而您希望将多个字符视为一个连续的形状。

我在评论中尝试了我的建议,将OutlinedTextBlock课程从first linked answer延伸到Kent Boogaart

来自GeometryOutlinedTextBlock获得的BuildGeometry method实例由嵌套的GeometryGroup个实例组成(至少在合并具有多个阅读方向的文本时会创建单独的此类组) 。在浏览这些组后,您会发现每个角色有一个PathGeometry个实例。

N.B。:这是我在查看数据时想到的。它可能没有文档(?),如果它发生变化,此解决方案可能不再起作用。

通过使用Geometry.Combine method,所有这些PathGeometry个实例都可以与GeometryCombineMode.Union结合使用,这意味着将合并重叠区域。

首先,我定义了一种查找所有PathGeometry个对象的方法。它递归地潜入GeometryGroup对象的层次结构中,并且效率不是很高,但它有助于证明这一点 - 随意优化这种性能:

private IEnumerable<PathGeometry> FindAllPathGeometries(Geometry geometry)
{
    var pathGeometry = geometry as PathGeometry;
    if (pathGeometry != null) {
        yield return pathGeometry;
    } else {
        var geoGroup = geometry as GeometryGroup;
        if (geoGroup != null) {
            foreach (var geo in geoGroup.Children) {
                foreach (var pg in FindAllPathGeometries(geo)) {
                    yield return pg;
                }
            }
        }
    }
}

然后,我修改了OutlinedTextBox.EnsureGeometry方法。最初,直接显示从BuildGeometry检索到的几何体:

private void EnsureGeometry()
{
    if (this.textGeometry != null) {
        return;
    }

    this.EnsureFormattedText();
    this.textGeometry = this.formattedText.BuildGeometry(new Point(0, 0));
}

相反,我现在通过迭代所有包含的PathGeometry实例并逐步将它们与Union模式组合来处理该几何体。为方便起见(因此您可以实际观察差异),我通过添加MergeShapes属性使该行为成为可选:

private void EnsureGeometry()
{
    if (this.textGeometry != null) {
        return;
    }

    this.EnsureFormattedText();
    var originalGeometry = this.formattedText.BuildGeometry(new Point(0, 0));

    if (MergeShapes) {
      PathGeometry newGeo = new PathGeometry();
      foreach (var pg in FindAllPathGeometries(originalGeometry)) {
        newGeo = Geometry.Combine(newGeo, pg, GeometryCombineMode.Union, null);
      }

      this.textGeometry = newGeo;
    } else {
        this.textGeometry = originalGeometry;
    }
}

public static readonly DependencyProperty MergeShapesProperty = DependencyProperty.Register("MergeShapes",
                                                                                            typeof(bool),
                                                                                            typeof(OutlinedTextBlock),
                                                                                            new FrameworkPropertyMetadata(OnFormattedTextUpdated));

public bool MergeShapes {
    get {
        return (bool)GetValue(MergeShapesProperty);
    }
    set {
        SetValue(MergeShapesProperty, value);
    }
}