private void DrawTriangles(Context g) { int px, py; Gdk.ModifierType mask; GdkWindow.GetPointer (out px, out py, out mask); Rectangle rect = GradientRectangle; Rectangle all = Allocation.ToCairoRectangle(); int index = FindValueIndex (py); for (int i = 0; i < Count; i++) { double val = vals [i]; double y = GetYFromValue (val); bool hoover = ((index == i)) && (all.ContainsPoint (px, py) || ValueIndex != -1); Color color = hoover ? new Color (0.1, 0.1, 0.9) : new Color (0.1, 0.1, 0.1); //left triangle PointD[] points = new PointD[] { new PointD (rect.X, y), new PointD (rect.X - xpad * rect.Width, y + ypad * rect.Height), new PointD (rect.X - xpad * rect.Width, y - ypad * rect.Height) }; g.FillPolygonal (points, color); double x = rect.X + rect.Width; //right triangle PointD[] points2 = new PointD[] { new PointD (x , y), new PointD (x + xpad * rect.Width, y + ypad * rect.Height), new PointD (x + xpad * rect.Width, y - ypad * rect.Height) }; g.FillPolygonal (points2, color); } }
protected Rectangle DrawShape(ShapeEngine engine, Layer l, bool drawCP, bool drawHoverSelection) { Document doc = PintaCore.Workspace.ActiveDocument; Rectangle? dirty = null; ShapeEngine activeEngine = ActiveShapeEngine; if (activeEngine != null) { using (Context g = new Context(l.Surface)) { g.AppendPath(doc.Selection.SelectionPath); g.FillRule = FillRule.EvenOdd; g.Clip(); g.Antialias = activeEngine.AntiAliasing ? Antialias.Subpixel : Antialias.None; g.SetDash(DashPatternBox.GenerateDashArray(activeEngine.DashPattern, activeEngine.BrushWidth), 0.0); g.LineWidth = activeEngine.BrushWidth; //Draw the shape. if (activeEngine.ControlPoints.Count > 0) { //Generate the points that make up the shape. activeEngine.GeneratePoints(activeEngine.BrushWidth); PointD[] points = activeEngine.GetActualPoints (); //Expand the invalidation rectangle as necessary. if (FillShape) { Color fill_color = StrokeShape ? activeEngine.FillColor : activeEngine.OutlineColor; dirty = dirty.UnionRectangles (g.FillPolygonal (points, fill_color)); } if (StrokeShape) { dirty = dirty.UnionRectangles(g.DrawPolygonal(points, activeEngine.OutlineColor)); } } g.SetDash(new double[] { }, 0.0); //Draw anything extra (that not every shape has), like arrows. DrawExtras(ref dirty, g, engine); if (drawCP) { DrawControlPoints(g, drawHoverSelection); } } } return dirty ?? new Rectangle(0d, 0d, 0d, 0d); }
private void DrawChannel(Context g, ColorBgra color, int channel, long max, float mean) { Rectangle rect = Allocation.ToCairoRectangle (); Histogram histogram = Histogram; int l = (int)rect.X; int t = (int)rect.Y; int r = (int)(rect.X + rect.Width); int b = (int)(rect.Y + rect.Height); int entries = histogram.Entries; long[] hist = histogram.HistogramValues [channel]; ++max; if (FlipHorizontal) { Utility.Swap(ref l, ref r); } if (!FlipVertical) { Utility.Swap(ref t, ref b); } PointD[] points = new PointD[entries + 2]; points[entries] = new PointD (Utility.Lerp (l, r, -1), Utility.Lerp (t, b, 20)); points[entries + 1] = new PointD (Utility.Lerp (l, r, -1), Utility.Lerp (b, t, 20)); for (int i = 0; i < entries; i += entries - 1) { points[i] = new PointD ( Utility.Lerp (l, r, (float)hist[i] / (float)max), Utility.Lerp (t, b, (float)i / (float)entries)); CheckPoint (rect, points [i]); } long sum3 = hist[0] + hist[1]; for (int i = 1; i < entries - 1; ++i) { sum3 += hist[i + 1]; points[i] = new PointD( Utility.Lerp(l, r, (float)(sum3) / (float)(max * 3.1f)), Utility.Lerp(t, b, (float)i / (float)entries)); CheckPoint (rect, points [i]); sum3 -= hist[i - 1]; } byte intensity = selected[channel] ? (byte)96 : (byte)32; ColorBgra pen_color = ColorBgra.Blend (ColorBgra.Black, color, intensity); ColorBgra brush_color = color; brush_color.A = intensity; g.LineWidth = 1; g.Rectangle (rect); g.Clip (); g.DrawPolygonal (points, pen_color.ToCairoColor ()); g.FillPolygonal (points, brush_color.ToCairoColor ()); }
/// <summary> /// Draws the arrow. /// </summary> /// <param name="g">The drawing context.</param> /// <param name="endPoint">The end point of a shape.</param> /// <param name="almostEndPoint">The point right before the end point.</param> public Rectangle? Draw(Context g, Color outlineColor, PointD endPoint, PointD almostEndPoint) { //First, calculate the ending angle. double endingAngle = Math.Atan(Math.Abs(endPoint.Y - almostEndPoint.Y) / Math.Abs(endPoint.X - almostEndPoint.X)) * invRadiansToDegrees; //This is necessary to have a properly calculated ending angle. if (endPoint.Y - almostEndPoint.Y > 0) { if (endPoint.X - almostEndPoint.X > 0) { endingAngle = 180d - endingAngle; } } else { if (endPoint.X - almostEndPoint.X > 0) { endingAngle += 180d; } else { endingAngle = 360d - endingAngle; } } //Calculate the points of the arrow. PointD[] arrowPoints = { endPoint, new PointD( endPoint.X + Math.Cos((endingAngle + 270 + AngleOffset) * radiansToDegrees) * ArrowSize, endPoint.Y + Math.Sin((endingAngle + 270 + AngleOffset) * radiansToDegrees) * ArrowSize * -1d), new PointD( endPoint.X + Math.Cos((endingAngle + 180) * radiansToDegrees) * (ArrowSize + LengthOffset), endPoint.Y + Math.Sin((endingAngle + 180) * radiansToDegrees) * (ArrowSize + LengthOffset) * -1d), new PointD( endPoint.X + Math.Cos((endingAngle + 90 - AngleOffset) * radiansToDegrees) * ArrowSize, endPoint.Y + Math.Sin((endingAngle + 90 - AngleOffset) * radiansToDegrees) * ArrowSize * -1d) }; //Draw the arrow. g.FillPolygonal(arrowPoints, outlineColor); //Calculate the minimum bounding rectangle for the arrowhead and return it so //that it can be unioned with the existing invalidation rectangle. double minX = Math.Min(Math.Min(arrowPoints[1].X, arrowPoints[2].X), arrowPoints[3].X); double minY = Math.Min(Math.Min(arrowPoints[1].Y, arrowPoints[2].Y), arrowPoints[3].Y); return new Rectangle(minX, minY, Math.Max(Math.Max(arrowPoints[1].X, arrowPoints[2].X), arrowPoints[3].X) - minX, Math.Max(Math.Max(arrowPoints[1].Y, arrowPoints[2].Y), arrowPoints[3].Y) - minY); }