8

I need to be able to rotate text in a label and align it to the left, right or center. So far I am able to do rotation with this code in the derived label's onPaint method:

 float width = graphics.MeasureString(Text, this.Font).Width;
 float height = graphics.MeasureString(Text, this.Font).Height;

 double angle = (_rotationAngle / 180) * Math.PI;
 graphics.TranslateTransform(
     (ClientRectangle.Width + (float)(height * Math.Sin(angle)) - (float)(width * Math.Cos(angle))) / 2,
     (ClientRectangle.Height - (float)(height * Math.Cos(angle)) - (float)(width * Math.Sin(angle))) / 2);
 graphics.RotateTransform(270f);
 graphics.DrawString(Text, this.Font, textBrush, new PointF(0,0), stringFormat);
 graphics.ResetTransform();

And it works fine. I can see text rotated 270 degrees.

But when I try to set alignment in stringFormat it goes crazy, and I can't figure out what's going on.

How can I have text rotated by 270 degrees and align it to up?

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Adrian Serafin
  • 7,665
  • 5
  • 46
  • 67

2 Answers2

26

In case somebody was looking for tips, here is the solution for 0, 90, 180, 270, and 360 degrees rotation, where StringAligment works.

One thing was choosing the right point for moving the origin to, and the second one was to modify the display rectangle according to rotation.

StringFormat format = new StringFormat();
format.Alignment = StringAlignment.Center;

SizeF txt = e.Graphics.MeasureString(Text, this.Font);
SizeF sz = e.Graphics.VisibleClipBounds.Size;

//90 degrees
e.Graphics.TranslateTransform(sz.Width, 0);
e.Graphics.RotateTransform(90);
e.Graphics.DrawString(Text, this.Font, Brushes.Black, new RectangleF(0, 0, sz.Height, sz.Width), format);
e.Graphics.ResetTransform();

//180 degrees
e.Graphics.TranslateTransform(sz.Width, sz.Height);
e.Graphics.RotateTransform(180);
e.Graphics.DrawString(Text, this.Font, Brushes.Black, new RectangleF(0, 0, sz.Width, sz.Height), format);
e.Graphics.ResetTransform();

//270 degrees
e.Graphics.TranslateTransform(0, sz.Height);
e.Graphics.RotateTransform(270);
e.Graphics.DrawString(Text, this.Font, Brushes.Black, new RectangleF(0, 0, sz.Height, sz.Width), format);
e.Graphics.ResetTransform();

//0 = 360 degrees
e.Graphics.TranslateTransform(0, 0);
e.Graphics.RotateTransform(0);
e.Graphics.DrawString(Text, this.Font, Brushes.Black, new RectangleF(0, 0, sz.Width, sz.Height), format);
e.Graphics.ResetTransform();

If you put this code in label's OnPaint event, it would display your rotated form's title four times.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Adrian Serafin
  • 7,665
  • 5
  • 46
  • 67
  • This works but the quality is worse than on a normal Forms.Label on Windows 10. The drawing quality of GDI+ is a shame. I had to implement drawing into a Bitmap with the DrawTextW() API and rotate that Bitmap with RotateFlip() to get high quality! – Elmue Jan 26 '21 at 19:35
  • What is 'e'? It isn't defined in the code – David Lindon Aug 04 '23 at 07:53
0

Extension of Adrian Serafin's answer if you need to draw at a non-0 X,Y:

//90 degrees
e.Graphics.TranslateTransform(sz.Width, 0);
e.Graphics.RotateTransform(90);
e.Graphics.DrawString(Text, this.Font, Brushes.Black,
  new RectangleF(sz.ToPointF().Y, sz.ToPointF().X, sz.Height, sz.Width), format);
e.Graphics.ResetTransform();
//180 degrees
e.Graphics.TranslateTransform(sz.Width, sz.Height);
e.Graphics.RotateTransform(180 this.Font, Brushes.Black,
  new RectangleF(-sz.ToPointF().X, -sz.ToPointF().Y, sz.Width, sz.Height), format);
e.Graphics.ResetTransform();
//270 degrees
e.Graphics.TranslateTransform(0, sz.Height);
e.Graphics.RotateTransform(270);
e.Graphics.DrawString(Text, this.Font, Brushes.Black,
  new RectangleF(-sz.ToPointF().Y, sz.ToPointF().X, sz.Height, sz.Width), format);
//0 = 360 degrees
e.Graphics.TranslateTransform(0, 0);
e.Graphics.RotateTransform(0);
e.Graphics.DrawString(Text, this.Font, Brushes.Black,
  new RectangleF(sz.ToPointF().X, sz.ToPointF().Y, sz.Width, sz.Height), format);
e.Graphics.ResetTransform();
DKATyler
  • 914
  • 10
  • 16
  • can we use this to draw the string with the custom angles like 45, 60, 12? – Adhi Apr 18 '18 at 06:50
  • @Adhi It's trigonometry. Sin 90=1, Cos 90=0. Sin 180=-1, Cos 180=-1. I suppose a more robust answer might be to use the Math library to dynamically calculate the x,y coordinates based on the angle. I no longer have an application that this would feed into to test with. – DKATyler Apr 19 '18 at 23:21