如何在字形中实现字符连字?

Ram*_*min 8 c# wpf xaml ligature glyphrun

我的问题是有关连字字形.msdn中有这个例子:

<!-- "Open file" with "fi" ligature -->
<Glyphs
FontUri             = "C:\WINDOWS\Fonts\TIMES.TTF"
FontRenderingEmSize = "36"
StyleSimulations    = "BoldSimulation"
UnicodeString       = "Open file"
Indices             = ";;;;;(2:1)191"
Fill                = "SlateGray"
OriginX             = "400"
OriginY             = "150"
/>
Run Code Online (Sandbox Code Playgroud)

我找不到任何详细的文件来解释Indices属性中发生的事情.当我尝试用波斯语字符创建一个字形时,让我们说"من",我明白了

???
Run Code Online (Sandbox Code Playgroud)

代替

??
Run Code Online (Sandbox Code Playgroud)

所以问题是:如何在字形中实现字符连字?
顺便说一句,我知道我可以使用FormattedTextTextFormatter.FormatLine(...)方法,但我想知道在GlyphsGlyphRun中是否有任何方法可以做到这一点.

Cle*_*ens 9

Indices属性的语法在MSDN 中的Glyphs.Indices文档的"备注"部分中进行了解释.

每个字形规范具有以下形式.

[GlyphIndex][,[Advance][,[uOffset][,[vOffset][,[Flags]]]]]

[]围绕每个字段的含义即是可选的.因此,所有字段都是可选的,这意味着字形索引规范可能完全为空.

";;;;;(2:1)191"示例中的值由六个这样的规范组成,以分号分隔,其中前五个是空的.如果字形索引规范为空,WPF将从GlyphTypeface.CharacterToGlyphMap属性中检索实际的字形索引.

文档还说

群集中第一个字形的规范之前是一个规范,表明有多少个字形和多少个代码点组合在一起形成集群.

这就是前缀的(2:1)含义.它指定源字符串中的两个字符由一个字形替换.当然,这个字形有索引191.

字形索引本身只是所选字体中特定字形的索引.在该示例中,它是fi字体中索引位置191处的连字字形(单个字形)Times.ttf.

在您的波斯字符示例中,这一切都取决于您使用的字体.您必须对其进行调查,以便为这两个字符找到合适的替换字形.仅仅用其他字符替换第二个字形也可能就足够了,在这种情况下,您可以省略(2:1)规范并只编写适当的字形索引.


更新:一个非常简单的工具来检查字体文件中的所有字形可能会这样写:

<ListBox ItemsSource="{Binding GlyphItems}">
    <ListBox.ItemTemplate>
        <DataTemplate>
            <Grid>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="50"/>
                    <ColumnDefinition/>
                </Grid.ColumnDefinitions>
                <Glyphs FontUri="{Binding FontUri}" Indices="{Binding Indices}"
                        FontRenderingEmSize="36" OriginX="10" OriginY="36"
                        Fill="Black"/>
                <TextBlock Grid.Column="1" VerticalAlignment="Center"
                           Text="{Binding Indices, StringFormat=Index {0}}"/>
            </Grid>
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>
Run Code Online (Sandbox Code Playgroud)

码:

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();

        GlyphItems = new List<object>();

        var font = @"C:\WINDOWS\Fonts\TIMES.TTF";

        for (int i = 0; i < new GlyphTypeface(new Uri(font)).GlyphCount; i++)
        {
            GlyphItems.Add(new { FontUri = font, Indices = i.ToString() });
        }

        DataContext = this;
    }

    public List<object> GlyphItems { get; set; }
}
Run Code Online (Sandbox Code Playgroud)