protected override Rectangle DrawShape(Rectangle r, Layer l) { Path path = PintaCore.Layers.SelectionPath; using (Context g = new Context (l.Surface)) PintaCore.Layers.SelectionPath = g.CreateEllipsePath (r); (path as IDisposable).Dispose (); return r; }
protected override Rectangle DrawShape(Rectangle r, Layer l) { Document doc = PintaCore.Workspace.ActiveDocument; Path path = doc.SelectionPath; using (Context g = new Context (l.Surface)) doc.SelectionPath = g.CreateEllipsePath (r); (path as IDisposable).Dispose (); return r; }
/// <summary> /// Create an elliptical Selection from a bounding Rectangle. /// </summary> /// <param name="selectionSurface">The selection surface to use for calculating the elliptical Path.</param> /// <param name="r">The bounding Rectangle surrounding the ellipse.</param> public void CreateEllipseSelection(Surface selectionSurface, Rectangle r) { using (Context g = new Context(selectionSurface)) { SelectionPath = g.CreateEllipsePath(r); } //These values were calculated in the static CreateEllipsePath method //in Pinta.Core.CairoExtensions, so they were used here as well. double rx = r.Width / 2; //1/2 of the bounding Rectangle Width. double ry = r.Height / 2; //1/2 of the bounding Rectangle Height. double cx = r.X + rx; //The middle of the bounding Rectangle, horizontally speaking. double cy = r.Y + ry; //The middle of the bounding Rectangle, vertically speaking. double c1 = 0.552285; //A constant factor used to give the least approximation error. //Clear the Selection Polygons collection to start from a clean slate. SelectionPolygons.Clear(); //Calculate an appropriate interval at which to increment t based on //the bounding Rectangle's Width and Height properties. The increment //for t determines how many intermediate Points to calculate for the //ellipse. For each curve, t will go from tInterval to 1. The lower //the value of tInterval, the higher number of intermediate Points //that will be calculated and stored into the Polygon collection. double tInterval = 1d / (r.Width + r.Height); //Create a new Polygon to store the upcoming ellipse. List<IntPoint> newPolygon = new List<IntPoint>(); //These values were also calculated in the CreateEllipsePath method. This is where //the ellipse's 4 curves (and all of the Points on each curve) are determined. //Note: each curve is consecutive to the previous one, but they *do not* overlap, //other than the first/last Point (which is how it is supposed to work). //The starting Point. newPolygon.Add(new IntPoint((long)(cx + rx), (long)cy)); //Curve 1. newPolygon.AddRange(CalculateCurvePoints(tInterval, cx + rx, cy, cx + rx, cy - c1 * ry, cx + c1 * rx, cy - ry, cx, cy - ry)); //Curve 2. newPolygon.AddRange(CalculateCurvePoints(tInterval, cx, cy - ry, cx - c1 * rx, cy - ry, cx - rx, cy - c1 * ry, cx - rx, cy)); //Curve 3. newPolygon.AddRange(CalculateCurvePoints(tInterval, cx - rx, cy, cx - rx, cy + c1 * ry, cx - c1 * rx, cy + ry, cx, cy + ry)); //Curve 4. newPolygon.AddRange(CalculateCurvePoints(tInterval, cx, cy + ry, cx + c1 * rx, cy + ry, cx + rx, cy + c1 * ry, cx + rx, cy)); //Add the newly calculated elliptical Polygon. SelectionPolygons.Add(newPolygon); }