Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Printing Right-To-Left in c#

According to msdn: http://www.microsoft.com/middleeast/msdn/arabicsupp.aspx (Link Expired!)

How GDI+ Support Arabic?

GDI+ supports Arabic text manipulation including print text with RTL reading order for both output devices, Screen and Printer. The Graphics.DrawString method draws the specified text string at a designated x, y location or rectangle (according to its overloading), with the specified Brush and Font objects using the formatting attributes of the specified StringFormat object. The StringFormat object includes text layout information such as text reading order.

Therefore, you can easily move the origin of the graphics object to be Right-Top, instead of Left-Top, to print out the Arabic text in the designated location on the screen smoothly, without having to calculate locations explicit.

While this is true when setting (X,Y) coordination to (0,0) but if I want to increase X coordination to print at specific area on the paper, the X coordination will increase to the right side of the paper not to the left as it supposed to when printing in Right-to-left; which means print outside of the paper. See this demo:

static void Main(string[] args)
{
    PrintDocument p = new PrintDocument();
    p.PrintPage += new PrintPageEventHandler(PrintPage);
    p.Print();
}

static void PrintPage(object sender, PrintPageEventArgs e)
{
    string drawString = "إختبار الرسم";
    SolidBrush drawBrush = new SolidBrush(Color.Black);
    Font drawFont = new System.Drawing.Font("Arail", 16);
    RectangleF recAtZero = new RectangleF(0, 0, e.PageBounds.Width, e.PageBounds.Height);
    StringFormat drawFormat = new StringFormat();

    drawFormat.FormatFlags = StringFormatFlags.DirectionRightToLeft;

    e.Graphics.DrawString(drawString, drawFont, drawBrush, recAtZero, drawFormat);
    RectangleF recAtGreaterThantZero = new RectangleF(300, 0, e.PageBounds.Width, e.PageBounds.Height);
    e.Graphics.DrawString(drawString, drawFont, drawBrush, recAtGreaterThantZero, drawFormat);
}

How to move the origin of the graphics object to be Right-Top instead of Left-Top and when increase X coordination it advance the printing point to the left not to the right.

PS: What I am doing now is setting X coordination to negative to force it move to left. Simple digagram

like image 202
Abdullah BaMusa Avatar asked May 25 '11 12:05

Abdullah BaMusa


People also ask

Does printf work from right to left?

Most of the compilers takes each parameter of printf() from right to left. So in the first printf() statement, the last parameter is x++, so this will be executed first, it will print 20, after that increase the value from 20 to 21.

How will you align the output left or right in C programming?

By using justifications in printf statement we can arrange the data in any format. To implement the right justification, insert a minus sign before the width value in the %s character.

What is %5d in C language?

Example: "%05d" will be "00123" after processing. - period followed by the second string of numbers specifies accuracy, i.e. maximum number of decimal places. Example: "%6.3f" will be "12.345" after processing, "%. 2f" will be "12.34" after processing.


2 Answers

Use StringFormatFlags.DirectionRightToLeft, like this:

StringFormat format = new StringFormat(StringFormatFlags.DirectionRightToLeft);
e.Graphics.DrawString("سلام",
                this.Font,
                new SolidBrush(Color.Red),
                r1,
                format);
like image 130
kazem Avatar answered Oct 02 '22 01:10

kazem


You could make a very simple coordinate transformation:

public static class CoordinateConverter
{
    public static RectangleF Convert(RectangleF source, RectangleF drawArea)
    {
        // I assume drawArea.X to be 0
        return new RectangleF(
            drawArea.Width - source.X - source.Width,
            source.Y,
            source.Width,
            source.Height);
    }

    public static RectangleF ConvertBack(Rectangle source, RectangleF drawArea)
    {
       return new RectangleF(
           source.X + source.Width - drawArea.Width,
           source.Y,
           source.Width,
           source.Height);
    }
}

Now every time you want something texty to be drawn, you can use this converter to change the coordinates. Of course you could also ref a rectangle so you don't create new ones all the time. But the principle stays the same. I hope I understood your question correctly.

like image 40
LueTm Avatar answered Oct 02 '22 00:10

LueTm