Search code examples
c#winformsdrawstring

Drawstring up to down textdirection right (like chinese old style)


I want to print using Graphics.DrawString() method but I want to print that up to down.

For example I have string "Hello" and I want to be printed

H
e
l
l
o

With only one Graphics.DrawString()

Is it possible or not? because I have dynamic length of text.


Solution

  • Here is code to show Text vertically, not rotated. In the 1st panel the text is left aligned, in the 2nd & 3rd Panel it is centered. The Text to be shown is simply the Panel.Text and the Font is the Panel's font.

    The 1st solution uses only one DrawString; it simply inserts linefeeds between all characters.

    The 2nd Panel looks much nicer and you can specify a positive or negative leading but the code is a bit more involved - you get what you pay for.

    (Except here on SO ;-)

    private void panel1_Paint(object sender, PaintEventArgs e)
    {
        string s = "";
        foreach(char c in panel1.Text) s += c.ToString() + "\r\n";
        e.Graphics.DrawString(s, panel1.Font, Brushes.Black, Point.Empty);
        SizeF sf = e.Graphics.MeasureString(s, panel1.Font);    //**
        panel1.Size = new Size((int)sf.Width, (int)sf.Height);  //**
    }
    
    private void panel2_Paint(object sender, PaintEventArgs e)
    {
        float leading = -1.75f;  // <-- depends on font and taste
        float maxWidth = 0f;  //**
        Dictionary<char, Size> charSizes = new Dictionary<char, Size>();
        foreach (char c in panel2.Text)
            if (!charSizes.ContainsKey(c))
            {
                SizeF sf = e.Graphics.MeasureString(c.ToString(), panel2.Font);
                charSizes.Add(c, new Size((int)sf.Width, (int)sf.Height) );
                if (maxWidth < (int)sf.Width) maxWidth = (int)sf.Width;   //**
            }
        panel2.Width = (int)(maxWidth * 2);   // for panel size  //**
        float y = 0f;
        foreach (char c in panel2.Text)
        {
            e.Graphics.DrawString(c.ToString(), panel2.Font, Brushes.Black, 
                       new Point( ( panel2.Width - charSizes[c].Width) / 2, (int)y) );
            y += charSizes[c].Height + leading;
        }
        panel2.Height = (int)y;  //**
    }
    

    Edit: //** added code to resize the panels

    Here is a screenshot; the middle panel has a leading of +2.75f the right one of +5f:

    screenshot