/// <summary>assumes no rotation or shearing; this is mainly used with our graphics which can be scaled and offset</summary> public static RectangleF TransformRectangle(this Matrix transform, RectangleF rct) { Debug.Assert(transform.Elements[1] == 0 && transform.Elements[2] == 0); // These are the 2 elements which link the X and Y and cause shearing or rotation PointF[] pt = { rct.Location, rct.BottomRight() }; transform.TransformPoints(pt); return(new RectangleF(Math.Min(pt[0].X, pt[1].X), Math.Min(pt[0].Y, pt[1].Y), Math.Abs(pt[0].X - pt[1].X), Math.Abs(pt[0].Y - pt[1].Y))); }
public static RectangleF TransformRect(this Matrix m, RectangleF rect) { var p = new[] { rect.TopLeft(), rect.BottomRight() }; m.TransformPoints(p); return(RectangleF.FromLTRB(p[0].X, p[0].Y, p[1].X, p[1].Y)); }
/// <summary> /// Performs component-wise linear mapping on all 4 points of the rectangle. <seealso cref="LinearMap(float,float,float,float,float)"/> /// </summary> public static RectangleF LinearMap(RectangleF value, RectangleF from, RectangleF to) { var tl = LinearMap(value.TopLeft(), from, to); var br = LinearMap(value.BottomRight(), from, to); return(RectangleF.FromExtremes(tl.X, tl.Y, br.X, br.Y)); }
public static void Draw(this OverlayNode on, Graphics dc, int Height) { Pen p = on.IsSelected ? PensAndBrushes.OverlayNodeSelPen : PensAndBrushes.OverlayNodePen; RectangleF lBB = on.BB.UpsideDown(Height).ToRectangleF(); dc.DrawLine(p, lBB.TopLeft(), lBB.BottomRight()); dc.DrawLine(p, lBB.BottomLeft(), lBB.TopRight()); }
public static PointF[] Get4Points(this RectangleF rect) { return(new PointF[] { rect.TopLeft(), rect.TopRight(), rect.BottomRight(), rect.BottomLeft() }); }
/// <summary> /// Draws an 'error rectangle' (red outline with a red cross through it) /// to the given <see cref="Graphics"/> instance. /// </summary> /// <param name="g">The graphics to draw to.</param> /// <param name="rect">The <see cref="Rectangle"/> dimensions to draw.</param> /// <param name="penWidth">The width of the <see cref="Pen"/> to draw with.</param> public static void DrawErrorRectangle(this Graphics g, RectangleF rect, float penWidth = 2.0f) { // deflate the rect so it doesn't draw out of the bounds if the width is thicker. int rectDeflatePixels = (int)penWidth - 1; rect = RectangleF.Inflate(rect, -rectDeflatePixels, -rectDeflatePixels); using Pen redPen = new(Color.Red, penWidth); g.DrawLine(redPen, rect.TopLeft(), rect.BottomRight()); g.DrawLine(redPen, rect.TopRight(), rect.BottomLeft()); g.DrawRectangle(redPen, rect); }
private int WritePageButtons(StringBuilder output, List <Scriptable> pageButtons, Page page) { // writes [MAIN] panel with the page change button. // only done from buttons on p1 as they are shared in irm // returns output.AppendLine("[MAIN]"); RectangleF bounds = Geometry.UnionRectangles(from button in pageButtons select button.Bounds); Geometry.Extend(ref bounds, page.Bounds.Location); bounds.Height *= 1.1f; // allow some for the separator - the actual line in the SAW document is ignored and the header size is determined from the buttons WriteElement(output, "FRMPIX", bounds.Size.ToPointF(), true); WriteElement(output, "SEP", bounds.BottomLeft()); WriteElement(output, "END", bounds.BottomRight(), true); foreach (var button in pageButtons) { WriteElement(output, "MOD", button.Bounds.Location); WriteElement(output, "SIZE", button.Bounds.Size.ToPointF()); WriteElement(output, "PANEL", button.Element.LabelText, true); } output.AppendLine("[END]"); output.AppendLine(); return((int)bounds.Height); }
private void renderAxisLabel(Graphics graphics, int index, string label) { var measure = graphics.MeasureString(label, _style.AxisCaptionFont); var origin = getPointOnLine(index, _style.AxisCaptionDistance + 1F); var point = origin; var rect = new RectangleF(point, measure); var mid = chartMiddle; var pen = new Pen(Color.Red, 1F); // get corner of rectangle which would move the rect furtest away from the axis if (point.X == mid.X && point.Y < mid.Y) { point = rect.BottomCenter(); } else if (point.X > mid.X && point.Y < mid.Y) { point = rect.BottomLeft(); } else if (point.X > mid.X && point.Y == mid.Y) { point = rect.CenterLeft(); } else if (point.X > mid.X && point.Y > mid.Y) { point = rect.TopLeft(); } else if (point.X == mid.X && point.Y > mid.Y) { point = rect.TopCenter(); } else if (point.X < mid.X && point.Y > mid.Y) { point = rect.TopRight(); } else if (point.X < mid.X && point.Y == mid.Y) { point = rect.CenterRight(); } else if (point.X < mid.X && point.Y < mid.Y) { point = rect.BottomRight(); } // translate the rectangle to the new location rect.X += origin.X - point.X; rect.Y += origin.Y - point.Y; //graphics.DrawRectangle(pen, rect.X, rect.Y, rect.Width, rect.Height); //graphics.DrawCircle(pen, rect.TopCenter(), 3); //graphics.DrawCircle(pen, rect.TopRight(), 3); //graphics.DrawCircle(pen, rect.CenterRight(), 3); //graphics.DrawCircle(pen, rect.BottomRight(), 3); //graphics.DrawCircle(pen, rect.BottomCenter(), 3); //graphics.DrawCircle(pen, rect.BottomLeft(), 3); //graphics.DrawCircle(pen, rect.CenterLeft(), 3); //graphics.DrawCircle(pen, rect.TopLeft(), 3); graphics.DrawString(label, _style.AxisCaptionFont, new SolidBrush(_style.TextColor), rect); }
/// <summary>More general version of TransformRectangle - returns the rectangle CONTAINING the transformed rectangle (which may no longer be orthogonal)</summary> public static RectangleF TransformRectangleBounds(this Matrix transform, RectangleF rct) { PointF[] points = { rct.Location, rct.BottomRight(), rct.TopRight(), rct.BottomLeft() }; transform.TransformPoints(points); return(new RectangleF(Math.Min(points[0].X, points[1].X), Math.Min(points[0].Y, points[1].Y), Math.Abs(points[0].X - points[1].X), Math.Abs(points[0].Y - points[1].Y))); }
/// <summary> /// Gets corner points /// </summary> public static PointF[] Corners(this RectangleF rect) => new[] { rect.TopLeft(), rect.TopRight(), rect.BottomRight(), rect.BottomLeft() };