WPF Sample for Drawing Text


In my earlier post, I mentioned the different consideration when dealing with rtl (or Bidi) text.  This time I’m going to post the sample with more in-depth discussion.


1)      I created a WPF Windows application: RTLApplication.  


2)      Created a CustomControl and called it RTL Control. This is the rendering code, and the highlight shows the differences to insure that RTL rendering is correct:


protected override void OnRender(DrawingContext drawingContext)


{


  // Draw a rectangle at the beginning


  Rect rect = new Rect(new Point(5, 5), new Size(25, 25));


  drawingContext.DrawRectangle(Brushes.Brown, (Pen)null, rect);


  // Prepare to draw the text


  String Text = أهلاً Hello و مرحباً بكم.”;


  Geometry textGeometry;


  Point origin = new Point();


  origin.Y = 0;


  int x_margin = 40;


  origin.X = x_margin;


  // Create the formatted text based on the properties set.


  FormattedText formattedText = new FormattedText(


      Text,CultureInfo.CurrentUICulture,


FlowDirection,


new Typeface(“Arial”), 36, Brushes.Black);


   //Use a gradient to display red- green- and blue


   GradientStopCollection gsc = new GradientStopCollection();


   gsc.Add(new GradientStop(Colors.Red, 0));


   gsc.Add(new GradientStop(Colors.Green, 0.5));


   gsc.Add(new GradientStop(Colors.Blue, 1));


   // Build the geometry object that represents the text.


   if (FlowDirection == FlowDirection.RightToLeft)


   {


     double m11 = -1;


     double m22 = 1;


     double offsetX = formattedText.Width;


     double offsetY = 0;


     drawingContext.PushTransform(


     new MatrixTransform(m11, 0, 0, m22, offsetX, offsetY));


     origin.X = formattedText.Width – x_margin;


    }


    textGeometry = formattedText.BuildGeometry(origin);


    drawingContext.DrawGeometry(new LinearGradientBrush(gsc),


      new System.Windows.Media.Pen(Brushes.Blue, 0),


      textGeometry);


    if (FlowDirection == FlowDirection.RightToLeft)


      drawingContext.Pop();


    // Draw a circle at the end


    drawingContext.DrawEllipse(Brushes.DeepSkyBlue, (Pen)null,


new Point(formattedText.Width + x_margin + 10, 17), 12, 12);


  }


3)      Then I’ll go back to my MainWindow. I’ll add reference to my application to access my control:


xmlns:MyNamespace=”clr-namespace:RTLApplication”


4)      Add a button to switch the FlowDirection:


if (FlowDirection == FlowDirection.RightToLeft)


FlowDirection = FlowDirection.LeftToRight;


else


FlowDirection = FlowDirection.RightToLeft;


5)      Finally run the application.


This is a complete application, enjoy!

RTLApplication.zip