WPF:字形从右到左文本渲染

Mit*_*a M 5 c# wpf text glyph

我想使用 Glyph 渲染从右到左的语言文本(例如阿拉伯语或混合英语和阿拉伯语)。

\n\n

我正在使用这段代码:

\n\n
    Typeface typeface = new Typeface(new FontFamily("Arial"),\n                      FontStyles.Italic,\n                      FontWeights.Normal,\n                      FontStretches.Normal);\n\n       GlyphTypeface glyphTypeface;\n       if (!typeface.TryGetGlyphTypeface(out glyphTypeface))\n           throw new InvalidOperationException("No glyphtypeface found");\n\n       string text = "Hello  ,  \xd8\xb3\xd9\x84\xd8\xa7\xd9\x85";\n       double size = 40;\n\n       ushort[] glyphIndexes = new ushort[text.Length];\n       double[] advanceWidths = new double[text.Length];\n\n       double totalWidth = 0;\n\n       for (int n = 0; n < text.Length; n++)\n       {\n           ushort glyphIndex = glyphTypeface.CharacterToGlyphMap[text[n]];\n           glyphIndexes[n] = glyphIndex;\n\n           double width = glyphTypeface.AdvanceWidths[glyphIndex] * size;\n           advanceWidths[n] = width;\n\n           totalWidth += width;\n       }\n\n       Point origin = new Point(50, 50);\n\n       GlyphRun glyphRun = new GlyphRun(glyphTypeface, 0, false, size,\n           glyphIndexes, origin, advanceWidths, null, null, null, null,\n           null, null);\n\n       dc.DrawGlyphRun(Brushes.Black, glyphRun);\n
Run Code Online (Sandbox Code Playgroud)\n\n

但问题是阿拉伯字符是分开显示的,如下所示:

\n\n
 Hello  ,  \xd8\xb3 \xd9\x84 \xd8\xa7 \xd9\x85\n
Run Code Online (Sandbox Code Playgroud)\n\n

请指导我

\n\n

-------------------------------------------------- ----

\n\n

更新:

\n\n

这是 Obfuscate 解决方案的结果:\n图片1

\n\n

问题在于阿拉伯字母是单独呈现的。

\n\n

但这就是我想要的:\n图片2

\n

cod*_*der 2

尝试使用不同的 CultureInfo 格式化两个字符串

\n\n
string x = string.Format(new CultureInfo("en-US"), "{0}" ,text1);\nstring y = string.Format(new CultureInfo("ar-SA"), "{0}", text2);\n
Run Code Online (Sandbox Code Playgroud)\n\n

使用解决方案更新... \nxaml 有一个画布。

\n\n
<Window x:Class="StackOverflowCS.MainWindow"\n        Title="MainWindow" Height="600" Width="800">\n    <Grid>\n        <Canvas Name="MyCanvas" Height="600"  Width="800"/>\n    </Grid>\n</Window>\n
Run Code Online (Sandbox Code Playgroud)\n\n

主窗口 (WPF)

\n\n
   public partial class MainWindow : Window\n    {\n        public MainWindow()\n        {\n            InitializeComponent();\n\n            Size s = new Size(200,50);\n            GlyphElement gex = new GlyphElement(\n               string.Format(new CultureInfo("en-US"), "{0}", "Hello"), Brushes.Red, s);\n            MyCanvas.Children.Add(gex);\n            Canvas.SetTop(gex, 10);\n            Canvas.SetLeft(gex, 10);\n\n            GlyphElement gey = new GlyphElement(\n               string.Format(new CultureInfo("ar-SA"), "{0}", "\xd8\xb3\xd9\x84\xd8\xa7\xd9\x85"), Brushes.Black, s);\n            MyCanvas.Children.Add(gey);\n            Canvas.SetTop(gey, 100);\n            Canvas.SetLeft(gey, 10);\n        }\n    }\n
Run Code Online (Sandbox Code Playgroud)\n\n

将 GlyphElement 包装在 FrameworkElement 中

\n\n
    class GlyphElement : FrameworkElement\n    {\n        private GlyphRunner gr;\n        public GlyphElement(string text, Brush br, Size size) { gr = new GlyphRunner(text, br, size); }\n        protected override Visual GetVisualChild(int index) { return gr; }\n        protected override int VisualChildrenCount { get { return 1; } }\n    }\n
Run Code Online (Sandbox Code Playgroud)\n\n

将 GlyphRunner 包装在 DrawingVisual 中

\n\n
    public class GlyphRunner : DrawingVisual\n    {\n        public GlyphRunner(string text, Brush bc, Size size)\n        {\n            DrawingImage di = CreateGlyph(text, new Point(0, 0), bc);\n            using (DrawingContext dc = RenderOpen())\n            {\n                dc.DrawImage(di,new Rect(size));\n            }\n        }\n\n        // small updates to your code follow     \n        public DrawingImage CreateGlyph(string text, Point origin, Brush bc)\n        {\n            Typeface typeface = new Typeface(new FontFamily("Arial"),\n                                 FontStyles.Normal,\n                                 FontWeights.Normal,\n                                 FontStretches.Normal);\n\n            GlyphTypeface glyphTypeface;\n            if (!typeface.TryGetGlyphTypeface(out glyphTypeface))\n                throw new InvalidOperationException("No glyphtypeface found");\n\n            ushort[] glyphIndexes = new ushort[text.Length];\n            double[] advanceWidths = new double[text.Length];\n\n            double totalWidth = 0;\n\n            for (int n = 0; n < text.Length; n++)\n            {\n                ushort glyphIndex = glyphTypeface.CharacterToGlyphMap[text[n]];\n                glyphIndexes[n] = glyphIndex;\n\n                double width = glyphTypeface.AdvanceWidths[glyphIndex];\n                advanceWidths[n] = width;\n\n                totalWidth += width;\n            }\n\n            float ppd = (float)VisualTreeHelper.GetDpi(this).PixelsPerDip;\n            GlyphRun gr =  new GlyphRun(glyphTypeface, 0, false, 1.0, ppd, glyphIndexes, origin, advanceWidths, null, null, null, null, null, null);\n            GlyphRunDrawing glyphRunDrawing = new GlyphRunDrawing(bc, gr);\n            return new DrawingImage(glyphRunDrawing);\n        }\n\n    }\n
Run Code Online (Sandbox Code Playgroud)\n