How to control the orientation of Drawstring? - c#

I want to draw a string as an axis label. When I draw the string with following code, I can read it "from the left". The base line of the text is at the left side.
StringFormat format = CustomGraphics.StringFormat(ContentAlignment.MiddleCenter);
format.FormatFlags |= StringFormatFlags.DirectionVertical;
e.Graphics.DrawString(this.yAxis.Title.Text, this.yAxis.Title.Font,
textBrush, e.Bounds, format);
format.FormatFlags &= ~StringFormatFlags.DirectionVertical;
I want to draw vertical but turn the orientation by 180 degrees. How can I control this? Is there another method that I should use?

Use Graphics.RotateTransform() to get the string rotated the way you want it. You'll need TranslateTransform() and MeasureText() to get the start-point right.

How do I rotate a label in C#? contains a long and powerful paint method, based originally on http://www.codeproject.com/KB/miscctrl/customtext.aspx

Related

How can I make the picture smaller in the picture box without affecting the coordination?

I want to let the user define the area that they want to extract the text, but for the line item, the picture is too large and it make the rectangle cannot include the whole table.
I found a solution that able to smaller the picture but the coordinate also changed. For example, I draw the rectangle area at the "Malarvili" but the rectangle coordinate is not same as what I had drawn. Because of this, the extracted text is wrong.
So I want to know any solution to make the picture becomes smaller in the picturebox without affecting the original rectangle coordinate? Or using my original solution which is using the "autosize" without changing the picture size, but I have also facing a problem which is when i drawing the rectangle to the right, the scrollbar will not autoscroll and it makes me cannot draw the rectangle to the end of the right.
Any solution to solve these problems? Thanks a lot.
You can calculate the ratios (x and y axis) between the resize image (pictureBox with StretchImage mode) and the original image, and then calculate back the rectangle for original image from the rectangle you drawed in the pictureBox using these ratios.
pictureBox.SizeMode = PictureBoxSizeMode.StretchImage;
ratio_X = (double) pictureBox.Width/original_image;
ratio_Y = (double) pictureBox.Height/original_image;
//suppose you have the rect drawed in the pictureBox: pictureBox_rect
//now make a rect for original_image
Rectangle original_rect = new Rect((int)pictureBox_rect.X * ratio_X,
(int)pictureBox_rect.Y * ratio_Y,
(int)pictureBox_rect.Width * ratio_X,
(int)pictureBox_rect.Height * ratio_Y)

Drawing custom sprites onto a button in monogame

I'm using monogame. I want to overlay Text onto one of my button images, but I want to use the image way of drawing;
spriteBatch.Draw(texture, destinationRectangle, sourceRectangle, Color.White);
so that I can control how the text is handled inside the bounds of the button image rectangle, like trim excess.
Is there a way to draw strings using the fontsprite, without using the spriteBatch.DrawString method, or is there more to this method that I haven't learned yet? It just seems limiting from its input parameters.
You can use Font.MeasureString to get the width and height of a string as a Vector2. You can subtract half of it from the center position of a Rectangle and you get your centered text.

Justify text with DrawString right -and- left

Let's say I have 200 pixels of space and I want to draw two strings into it:
- the first string should be left justified
- right second string should be right justified
- But not overlap if they do not both fit (then do whatever my String.Trimming options say)
Am I going to have to measure each and draw this manually, or does DrawString have some way to support what I'm trying to do without me reinventing the wheel?
Imagine that \l and \r were escapes that did this, then I could say
graphics.Drawstring("\lfirst\rsecond", ...);
and I'd wind up with something like
"first second"
At least that's what I'd like to have happen (I know \l and \r do not exist). Is there a way?
I've ignored your flags and instead I'm showing you (roughly) how you can align text. It's easy enough to pick out your text, split it up and draw it as two separate strings!
string text2 = "Use TextFormatFlags and Rectangle objects to"
+ " align text in a rectangle.";
using (Font font2 = new Font("Arial", 12, FontStyle.Bold, GraphicsUnit.Point))
{
Rectangle rect2 = new Rectangle(150, 10, 130, 140);
// Create a TextFormatFlags with word wrapping, horizontal center and
// vertical center specified.
TextFormatFlags flags = TextFormatFlags.HorizontalLeft |
TextFormatFlags.VerticalCenter | TextFormatFlags.WordBreak;
// Draw the text and the surrounding rectangle.
TextRenderer.DrawText(e.Graphics, text2, font2, rect2, Color.Blue, flags);
e.Graphics.DrawRectangle(Pens.Black, rect2);
}
In the long run here's what I wound up doing:
Call MeasureString on left string
Call MeasureString on right string
Draw left string, left-justified
If the sum of the width of the two strings is less than width of the available space, draw the right string right-justified.
Pretty straightforward, though I was hoping there was something in the framework that would have done the work for me.

Can I use graphics.RotateTransform() without these artifacts?

I'm implementing a colour picker component as described in this seminal article.
As you can see, I've got the basics sorted:
One of the requirements however, is the ability to have the colour wheel rotated by an arbitrary amount. Thinking this would be easy, I some arithmetic to the mouse location -> colour value code and the following code to the bit that actually paints the wheel:
newGraphics.TranslateTransform((float)this.Radius, (float)this.Radius);
newGraphics.RotateTransform((float)this.offset);
newGraphics.TranslateTransform((float)this.Radius * -1, (float)this.Radius * -1);
Unfortunately, rotating the bitmap like this actually produces this:
Note the artefacts that appear either side of the centre.
Am I using the wrong approach? Or is there a way to get rid of these nasty rips?
Looking at the source code from that Microsoft example, I made the following change to the UpdateDisplay method by adding a matrix and setting the RotateAt method.
private void UpdateDisplay() {
// Update the gradients, and place the
// pointers correctly based on colors and
// brightness.
using (Brush selectedBrush = new SolidBrush(selectedColor)) {
using (Matrix m = new Matrix()) {
m.RotateAt(35f, centerPoint);
g.Transform = m;
// Draw the saved color wheel image.
g.DrawImage(colorImage, colorRectangle);
g.ResetTransform();
}
// Draw the "selected color" rectangle.
g.FillRectangle(selectedBrush, selectedColorRectangle);
// Draw the "brightness" rectangle.
DrawLinearGradient(fullColor);
// Draw the two pointers.
DrawColorPointer(colorPoint);
DrawBrightnessPointer(brightnessPoint);
}
}
It rotated the wheel 35 degrees (although the color selection was off now by, well, 35 degrees since I didn't mess with all the code) and it didn't produce any tearing.
Not 100% sure this is the answer (but too long for a comment), so maybe this is helpful.

How do I draw double height text using Graphics.DrawString?

I am trying to emulate a POS printer with System.Drawing and one of the functions I need is to draw text at double height. Any idea how I can do this using .Net's Graphics class?
Do I need to draw the text twice as large and condense it or draw normal size and then stretch? Both seem like messy options but is there an alternative?
Look at the transformation matrix on the Graphics object - you can control horizontal and vertical scaling independently.
Use a ScaleTransform and only scale up the y.

Categories