2017-11-25 208 views
3

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

我使用这个代码:

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); 

但问题是,阿拉伯字符分开表示,像这样的:

Hello , س ل ا م 

请指导我

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

UPDATE:

这是模糊处理解决方案的结果是: image1

的问题是阿拉伯字母分别呈现。

但是,这是我想要的东西: image2

+0

可能不得不分成两个因为一个是LRT和o它是RTL – codebender

+0

为什么你需要首先使用字形?也许你工作的杠杆太低,而不是利用一些更高级别的工具来呈现文本? WPF控件是否首先呈现文本OK? –

+0

@George,因为性能需要使用字形(上面的代码是一个小示例),我发现[这个伟大的Github项目测试所有WPF文本渲染方法](https://github.com/dgrunwald/WPF-Text-Rendering-Benchmark),我意识到雕文是我需要的。 –

回答

2

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

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

与解决方案更新中... XAML中有一个画布。

<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的

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

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); 
     } 

    } 
+0

感谢您的回复,但是BidiLevel只影响像这样的方向:如果它设置为0:如果它设置为1或更多:سلا,,但我的问题是字符单独显示,阿拉伯字符应该是这样的:سلام –

+0

我也使用了XmlLanguage标志(最后一个参数)但不受影响。 –

+0

不要以为它可以在一个字符串中完成。 – codebender