I have this method in my Text Class and I can't seem to flip the whole text.
I am using a Matrix to transform the GraphicsPath
which is used to draw the string.
Here's the code since I used @Jimi's answer:
public LayerClass DrawString(LayerClass.Type _text, string text, RectangleF rect, Font _fontStyle, Brush brush, float angle, PaintEventArgs e)
{
using (StringFormat string_format = new StringFormat())
{
SizeF stringSize = e.Graphics.MeasureString(text, _fontStyle);
rect.Location = new PointF(Shape.center.X - (rect.Width / 2), Shape.center.Y - (rect.Height / 2));
GraphicsContainer gc = e.Graphics.BeginContainer();
e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
e.Graphics.CompositingQuality = CompositingQuality.HighQuality;
//e.Graphics.DrawRectangle(Pens.Red, Rectangle.Round(rect));
RectangleF r = new RectangleF(rect.Location, rect.Size);
GraphicsPath path = new GraphicsPath();
if (text == "" || text == " ")
path.Dispose(); //Disposes the path to prevent OutOfMemoryExcetption
else
{
path.AddString(text, _fontStyle.FontFamily, Convert.ToInt32(_fontStyle.Style), _fontStyle.Height, new Point(0,0), string_format);
RectangleF text_rectf = path.GetBounds();
PointF[] target_pts = {
new PointF(r.Left, r.Top),
new PointF(r.Right, r.Top),
new PointF(r.Left, r.Bottom)};
//e.Graphics.DrawRectangle(Pens.Red, Rectangle.Round(r));
using (Matrix m = new Matrix(text_rectf, target_pts))
using (Matrix rotate = new Matrix())
using (Matrix FlipXMatrix = new Matrix(-1, 0, 0, 1, 0, 0))
using (Matrix FlipYMatrix = new Matrix(1, 0, 0, -1, 0, 0))
using (Matrix TransformMatrix = new Matrix())
{
TransformMatrix.Multiply(m);
m.RotateAt(angle, new PointF(0 + (stringSize.Width / 2), +(r.Height * 2)));
rotate.RotateAt(angle, new PointF(r.X, r.Y));
TransformMatrix.Multiply(rotate);
if (flipped)
{
TransformMatrix.Multiply(FlipXMatrix);
}
path.Transform(TransformMatrix);
if (flipY)
{
TransformMatrix.Multiply(FlipYMatrix);
path.Transform(TransformMatrix);
}
//Checks if the user wants the text filled or outlined
if (!isOutlined)
e.Graphics.FillPath(Brushes.Red, path);
else
e.Graphics.DrawPath(Pens.Red, path);
}
}
e.Graphics.EndContainer(gc);
}
this._Text = text;
this._TextRect = rect;
this.brush = brush;
this._Angle = angle;
return new LayerClass(_text, this, text, rect);
}
Now the problem is, it goes out the center of the picturebox.
There is a simpler way to flip a
Graphics
object.Create a Matrix which is the result of the Matrix multiplication of all the transformations that need to be applied to the specified object.
A Matrix transformation can be applied to either the GraphicsPath object or the
Graphics
object. Or both, when multiple transformation need to be performed sequentially.The .Net
System.Drawing.Drawing2D
Matrix class does not have a pre-builtFlip
(mirroring) transformation, but this Matrix structure is already well known (I'm not sure this is the reason why there isn't a specific method in the Matrix class):You can notice (it's also reported in the Docs) that the 3rd column is always the same, therefore, when building a new Matrix, the 3rd column values are implied and are provided by the Matrix class initialization, so we specify just the elements in the first 2 columns.
Important note, straight from the Matrix class Docs:
An example of a string drawn on a
Panel
using the GraphicsPath.AddString() method.Two Matrix transformations are added to the
GraphicsPath
object:a
Flip-X
and aFlip-Y
, which are combined using theMatrix.Multiply()
method:The
Flip-X
andFlip-Y
Matrices are built including theX
andY
translations, applied to the 3rd row of eachMatrix
. The translation values are determined by the Canvas dimensions.For example, the
Flip-X
Matrix:With a
[Canvas].Width = 100 =>
:Rotation Element : Rotate the X-Axis 180° (-1 radians) on the origin
Point(0, 0)
.Translate Element: Translate the
X
Position100
Graphics Units to the right (positive value).A visual representation of the effect.
The Controls referenced in the code are the same you can see here (if you need to reproduce it).