WPF:字形从右到左的文本呈现 [英] WPF : Glyph right-to-left text rendering

查看:165
本文介绍了WPF:字形从右到左的文本呈现的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想使用Glyph来显示从右到左的语言文本(例如阿拉伯语或英语和阿拉伯语的混合文字).

I want to use Glyph to render right-to-left languages text (e.g. Arabic or mix English and Arabic).

我正在使用以下代码:

    Typeface typeface = new Typeface(new FontFamily("Arial"),
                      FontStyles.Italic,
                      FontWeights.Normal,
                      FontStretches.Normal);

       GlyphTypeface glyphTypeface;
       if (!typeface.TryGetGlyphTypeface(out glyphTypeface))
           throw new InvalidOperationException("No glyphtypeface found");

       string text = "Hello  ,  سلام";
       double size = 40;

       ushort[] glyphIndexes = new ushort[text.Length];
       double[] advanceWidths = new double[text.Length];

       double totalWidth = 0;

       for (int n = 0; n < text.Length; n++)
       {
           ushort glyphIndex = glyphTypeface.CharacterToGlyphMap[text[n]];
           glyphIndexes[n] = glyphIndex;

           double width = glyphTypeface.AdvanceWidths[glyphIndex] * size;
           advanceWidths[n] = width;

           totalWidth += width;
       }

       Point origin = new Point(50, 50);

       GlyphRun glyphRun = new GlyphRun(glyphTypeface, 0, false, size,
           glyphIndexes, origin, advanceWidths, null, null, null, null,
           null, null);

       dc.DrawGlyphRun(Brushes.Black, glyphRun);

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

But the problem is that Arabic characters are shown separately, like this:

 Hello  ,  س ل ا م

请指导我

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

更新:

这是Obfuscate解决方案的结果:

This is result of Obfuscate's solution:

问题是阿拉伯字母是单独呈现的.

但这是我想要的:

推荐答案

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

Try formatting two strings with different CultureInfo

string x = string.Format(new CultureInfo("en-US"), "{0}" ,text1);
string y = string.Format(new CultureInfo("ar-SA"), "{0}", text2);

已更新解决方案... xaml具有画布.

Updated with solution... The xaml has a Canvas.

<Window x:Class="StackOverflowCS.MainWindow"
        Title="MainWindow" Height="600" Width="800">
    <Grid>
        <Canvas Name="MyCanvas" Height="600"  Width="800"/>
    </Grid>
</Window>

主窗口(WPF)

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

            Size s = new Size(200,50);
            GlyphElement gex = new GlyphElement(
               string.Format(new CultureInfo("en-US"), "{0}", "Hello"), Brushes.Red, s);
            MyCanvas.Children.Add(gex);
            Canvas.SetTop(gex, 10);
            Canvas.SetLeft(gex, 10);

            GlyphElement gey = new GlyphElement(
               string.Format(new CultureInfo("ar-SA"), "{0}", "سلام"), Brushes.Black, s);
            MyCanvas.Children.Add(gey);
            Canvas.SetTop(gey, 100);
            Canvas.SetLeft(gey, 10);
        }
    }

将GlyphElement包裹在FrameworkElement中

Wrap the GlyphElement in a FrameworkElement

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

将GlyphRunner包装在DrawingVisual中

Wrap the GlyphRunner in a DrawingVisual

    public class GlyphRunner : DrawingVisual
    {
        public GlyphRunner(string text, Brush bc, Size size)
        {
            DrawingImage di = CreateGlyph(text, new Point(0, 0), bc);
            using (DrawingContext dc = RenderOpen())
            {
                dc.DrawImage(di,new Rect(size));
            }
        }

        // small updates to your code follow     
        public DrawingImage CreateGlyph(string text, Point origin, Brush bc)
        {
            Typeface typeface = new Typeface(new FontFamily("Arial"),
                                 FontStyles.Normal,
                                 FontWeights.Normal,
                                 FontStretches.Normal);

            GlyphTypeface glyphTypeface;
            if (!typeface.TryGetGlyphTypeface(out glyphTypeface))
                throw new InvalidOperationException("No glyphtypeface found");

            ushort[] glyphIndexes = new ushort[text.Length];
            double[] advanceWidths = new double[text.Length];

            double totalWidth = 0;

            for (int n = 0; n < text.Length; n++)
            {
                ushort glyphIndex = glyphTypeface.CharacterToGlyphMap[text[n]];
                glyphIndexes[n] = glyphIndex;

                double width = glyphTypeface.AdvanceWidths[glyphIndex];
                advanceWidths[n] = width;

                totalWidth += width;
            }

            float ppd = (float)VisualTreeHelper.GetDpi(this).PixelsPerDip;
            GlyphRun gr =  new GlyphRun(glyphTypeface, 0, false, 1.0, ppd, glyphIndexes, origin, advanceWidths, null, null, null, null, null, null);
            GlyphRunDrawing glyphRunDrawing = new GlyphRunDrawing(bc, gr);
            return new DrawingImage(glyphRunDrawing);
        }

    }

这篇关于WPF:字形从右到左的文本呈现的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆