2017-11-25 30 views
3

右から左の言語のテキスト(アラビア語または英語とアラビア語の組み合わせなど)をレンダリングするにはGlyphを使用します。WPF:グリフの右から左へのテキストのレンダリング

私はこのコードを使用しています:

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

2に侵入する必要がある場合があります文字列はLRTであり、O therはRTL – codebender

+0

なぜ最初にグリフを使用する必要がありますか?おそらく、テキストをレンダリングするために高水準の機能を利用するのではなく、レバーをあまりに低くしすぎているのでしょうか? WPFコントロールは最初にテキストをOKにしますか? –

+0

@George、私はGlyphを使用する必要があります(上記のコードは小さなサンプルです)、私はこの素晴らしいGithubプロジェクトがすべてのWPFテキストレンダリング手法をテストすることを発見しました(https://github.com/dgrunwald/WPF-Text-Rendering-Benchmark)、私はGlyphが必要なものであることに気付きました。 –

答えて

2

が異なるのCultureInfo

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

... XAMLキャンバスを持って2つの文字列を書式設定してください。

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

メインウィンドウ(WPF)での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で

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

関連する問題