翻转绘制文本/字符串的GraphicsPath

Ter*_*Dog 3 c# text gdi+ winforms graphicspath

我在我的Text Class中有这个方法,我似乎无法翻转整个文本.
我正在使用Matrix来转换GraphicsPath用于绘制字符串的内容.

以下是我使用@ Jimi答案的代码:

    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);
    }
Run Code Online (Sandbox Code Playgroud)

现在的问题是,它走出了图片框的中心.

Jim*_*imi 9

有一个简单的方法翻转一个Graphics对象.
创建一个矩阵,它是需要应用于指定对象的所有变换的矩阵乘法的结果.

Matrix转换可以应用于GraphicsPath对象或Graphics对象.或者两者都需要顺序执行多次转换.

.Net System.Drawing.Drawing2DMatrix类没有预构建Flip(镜像)转换,但是这个Matrix结构已经众所周知(我不确定这就是Matrix类中没有特定方法的原因):

| 1 | 0 | 0 |       |-1 | 0 | 0 |       | 1 | 0 | 0 |
| 0 | 1 | 0 |       | 0 | 1 | 0 |       | 0 |-1 | 0 |
| 0 | 0 | 1 |       | 0 | 0 | 1 |       | 0 | 0 | 1 |

   Identity         Mirror X-Axis       Mirror Y-Axis
    Matrix              Matrix             Matrix
Run Code Online (Sandbox Code Playgroud)

您可以注意到(在Docs中也有报告)第3列始终是相同的,因此,在构建新Matrix时,第3列值是隐含的并由Matrix类初始化提供,因此我们仅指定元素前两列.

重要说明,直接来自Matrix类文档:

注意:
复合变换的顺序很重要.通常,旋转,然后缩放,然后平移与缩放不同,然后旋转,然后平移.类似地,矩阵乘法的顺序很重要.一般来说,ABC与BAC不同

Panel使用 GraphicsPath.AddString() 方法绘制的字符串示例.
将两个Matrix变换添加到GraphicsPath对象:
a Flip-X和a Flip-Y,它们使用以下Matrix.Multiply()方法组合:

Flip-XFlip-Y矩阵是建立包括XY翻译,适用于每一个的第三排Matrix.平移值由Canvas维度确定.
例如,Flip-X矩阵:

使用a [Canvas].Width = 100 =>:
旋转元素:在原点上旋转X轴180°(-1弧度)Point(0, 0).
翻译元素:将X位置100图形单位翻译到右侧(正值).

| -1  |  0  |  0  |
|  0  |  1  |  0  |
| 100 |  0  |  1  |

   Mirror X-Axis
  Translate X +100
      Matrix 
Run Code Online (Sandbox Code Playgroud)

效果的直观表示.
代码中引用的控件与您在此处可以看到的相同(如果需要重现它).

矩阵翻转

using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Text;

bool flipX = false;
bool flipY = false;
bool outlined = false;
float sampleFontEmSize = 28f;
string sampleText = "Sample Text to Flip";
FontFamily sampleFont = new FontFamily("Segoe UI");

private void panel1_Paint(object sender, PaintEventArgs e)
{
    Panel panel = sender as Panel;
    e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;

    using (GraphicsPath path = new GraphicsPath())
    using (StringFormat format = new StringFormat(StringFormatFlags.NoClip | StringFormatFlags.NoWrap))
    {
        format.Alignment = StringAlignment.Center;
        format.LineAlignment = StringAlignment.Center;
        path.AddString(sampleText, sampleFont, (int)FontStyle.Regular, sampleFontEmSize, panel.ClientRectangle, format);

        using (Matrix flipXMatrix = new Matrix(-1, 0, 0, 1, panel.Width, 0))
        using (Matrix flipYMatrix = new Matrix(1, 0, 0, -1, 0, panel.Height))
        using (Matrix transformMatrix = new Matrix())
        {
            if (flipX) {
                transformMatrix.Multiply(flipXMatrix);
            }
            if (flipY) {
                transformMatrix.Multiply(flipYMatrix);
            }
            path.Transform(transformMatrix);
            //Or e.Graphics.Transform = TransformMatrix;

            if (outlined) {
                e.Graphics.DrawPath(Pens.LawnGreen, path);
            }
            else {
                e.Graphics.FillPath(Brushes.Orange, path);
            }
        }
    }
}

private void btnFlipX_Click(object sender, EventArgs e)
{
    FlipX = !FlipX;
    panel1.Invalidate();
}

private void btnFlipY_Click(object sender, EventArgs e)
{
    FlipY = !FlipY;
    panel1.Invalidate();
}

private void chkOutlined_CheckedChanged(object sender, EventArgs e)
{
    Outlined = chkOutlined.Checked;
    panel1.Invalidate();
}
Run Code Online (Sandbox Code Playgroud)