Rotated text align in C#
Asked Answered
E

2

9

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?

Eldwin answered 16/12, 2010 at 11:25 Comment(3)
What alignment are you setting?Nonsuch
Near at first, but then I want to change to Far and CenterEldwin
when you transform the graphics, the whole "World" gets transformed so the near is not really the same near. Can you not set it at the position you want?Nonsuch
E
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.

Eldwin answered 16/12, 2010 at 14:35 Comment(2)
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!Willams
What is 'e'? It isn't defined in the codeHippocrates
F
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();
Footboy answered 11/11, 2017 at 15:44 Comment(2)
can we use this to draw the string with the custom angles like 45, 60, 12?Peeler
@Peeler 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.Footboy

© 2022 - 2024 — McMap. All rights reserved.