public void FillPolygon(DUIBrush brush, PointF[] points) { bool closed = true; if (points == null) { return; } if (points.Length < 3) { return; } brush.RenderTarget = this.target; using (SharpDX.Direct2D1.PathGeometry pathGeometry = new SharpDX.Direct2D1.PathGeometry(this.target.RenderTarget.Factory)) using (SharpDX.Direct2D1.GeometrySink geometrySink = pathGeometry.Open()) { geometrySink.SetFillMode(SharpDX.Direct2D1.FillMode.Alternate); geometrySink.BeginFigure(DxConvert.ToVector2(points[0]), SharpDX.Direct2D1.FigureBegin.Filled); for (int i = 1; i < points.Length; i++) { geometrySink.AddLine(DxConvert.ToVector2(points[i])); } geometrySink.EndFigure(closed ? SharpDX.Direct2D1.FigureEnd.Closed : SharpDX.Direct2D1.FigureEnd.Open); geometrySink.Close(); this.target.RenderTarget.FillGeometry(pathGeometry, brush); } }
public void DrawImage(DUIImage image, PointF[] polygon, GraphicsUnit srcUnit, float opacity) { image.RenderTarget = this.target; using (DirectUI.Common.DUIBitmapBrush dbs = new DirectUI.Common.DUIBitmapBrush(image, DUIExtendMode.Clamp, opacity)) using (SharpDX.Direct2D1.PathGeometry pathGeometry = new SharpDX.Direct2D1.PathGeometry(this.target.RenderTarget.Factory)) using (SharpDX.Direct2D1.GeometrySink gs1 = pathGeometry.Open()) { dbs.RenderTarget = this.target; gs1.SetFillMode(SharpDX.Direct2D1.FillMode.Alternate); gs1.BeginFigure(DxConvert.ToVector2(polygon[0]), SharpDX.Direct2D1.FigureBegin.Filled); for (int i = 1; i < polygon.Length; i++) { gs1.AddLine(DxConvert.ToVector2(polygon[i])); } gs1.EndFigure(SharpDX.Direct2D1.FigureEnd.Closed); gs1.Close(); this.target.RenderTarget.FillGeometry(pathGeometry, dbs); } }
public void DrawImage(DUIImage image, PointF[] destTriangle, PointF[] srcTriangle, GraphicsUnit srcUnit, float opacity) { PointF t1 = destTriangle[0]; PointF t2 = destTriangle[1]; PointF t3 = destTriangle[2]; image.RenderTarget = this.target; using (DirectUI.Common.DUIBitmapBrush dbs = new DirectUI.Common.DUIBitmapBrush(image, DUIExtendMode.Clamp, opacity)) using (SharpDX.Direct2D1.PathGeometry pathGeometry = new SharpDX.Direct2D1.PathGeometry(this.target.RenderTarget.Factory)) using (SharpDX.Direct2D1.GeometrySink gs1 = pathGeometry.Open()) { dbs.RenderTarget = this.target; gs1.SetFillMode(SharpDX.Direct2D1.FillMode.Alternate); gs1.BeginFigure(DxConvert.ToVector2(t1), SharpDX.Direct2D1.FigureBegin.Filled); gs1.AddLine(DxConvert.ToVector2(t2)); gs1.AddLine(DxConvert.ToVector2(t3)); gs1.EndFigure(SharpDX.Direct2D1.FigureEnd.Closed); gs1.Close(); dbs.Transform = MatrixTools.ThreePointsAffine(srcTriangle, destTriangle); this.target.RenderTarget.FillGeometry(pathGeometry, dbs); } }
public override void OnRender(ChartControl chartControl, ChartScale chartScale) { if (Series1 == null) { return; } NinjaScriptBase nsb = AttachedTo.ChartObject as NinjaScriptBase; ChartBars chartBars = (AttachedTo.ChartObject as Gui.NinjaScript.IChartBars).ChartBars; if (nsb == null || chartBars == null || Math.Abs(Series1.Count - chartBars.Count) > 1) { return; } int startBarIdx; int endBarIdx; if (chartControl.BarSpacingType == BarSpacingType.TimeBased) { startBarIdx = chartBars.GetBarIdxByTime(chartControl, StartAnchor.Time); endBarIdx = chartBars.GetBarIdxByTime(chartControl, EndAnchor.Time); } else { startBarIdx = StartAnchor.DrawnOnBar - StartAnchor.BarsAgo; endBarIdx = EndAnchor.DrawnOnBar - EndAnchor.BarsAgo; if (startBarIdx == endBarIdx) { startBarIdx = chartBars.GetBarIdxByTime(chartControl, StartAnchor.Time); endBarIdx = chartBars.GetBarIdxByTime(chartControl, EndAnchor.Time); } } int startIdx = Math.Min(startBarIdx, endBarIdx); int endIdx = Math.Max(startBarIdx, endBarIdx); // Now cap start/end by visibly painted bars! // If you dont do this it will absolutely crush performance on larger regions int firstVisibleIdx = Math.Max(nsb.BarsRequiredToPlot + Displacement, chartBars.GetBarIdxByTime(chartControl, chartControl.GetTimeByX(0)) - 1); int lastVisibleIdx = Math.Max(chartBars.ToIndex, chartBars.GetBarIdxByTime(chartControl, chartControl.LastTimePainted)) + 1; // Update indicies for displacement startIdx = Math.Max(0, Math.Max(firstVisibleIdx, startIdx + Displacement)); endIdx = Math.Max(0, Math.Min(endIdx + Displacement, lastVisibleIdx)); // we're completely not visible if (startIdx > lastVisibleIdx || endIdx < firstVisibleIdx) { return; } /* NOTE: Calling GetValueAt() on an ISeries<double> interface with a concrete * type of NinjaScriptBase will get the *bar* value which is not what we want, * in this case, default to first values (indicator) series */ ISeries <double> series1Adjusted = Series1; ISeries <double> series2Adjusted = Series2; NinjaScriptBase series1NsBase = Series1 as NinjaScriptBase; if (series1NsBase != null) { series1Adjusted = series1NsBase.Value; } if (series1Adjusted == null) { return; } NinjaScriptBase series2NsBase = Series2 as NinjaScriptBase; if (series2NsBase != null) { series2Adjusted = series2NsBase.Value; } // take care to wind the points correctly so our geometry builds as a solid, not flipped inside out SharpDX.Vector2[] points; SharpDX.Vector2[] points2 = new SharpDX.Vector2[0]; int pointIdx = 0; int pointIdx2 = 0; if (series2Adjusted == null) { points = new SharpDX.Vector2[endIdx - startIdx + 1 + 2]; for (int i = startIdx; i <= endIdx; ++i) { if (i < Math.Max(0, Displacement) || i > Math.Max(chartBars.Count - (nsb.Calculate == Calculate.OnBarClose ? 2 : 1) + Displacement, endIdx)) { continue; } int displacedIndex = Math.Min(chartBars.Count - (nsb.Calculate == Calculate.OnBarClose ? 2 : 1), Math.Max(0, i - Displacement)); double seriesValue = series1Adjusted.GetValueAt(displacedIndex); float y = chartScale.GetYByValue(seriesValue); float x = chartControl.BarSpacingType == BarSpacingType.TimeBased || chartControl.BarSpacingType == BarSpacingType.EquidistantMulti && i >= chartBars.Count //i is already displaced ? chartControl.GetXByTime(chartBars.GetTimeByBarIdx(chartControl, i)) : chartControl.GetXByBarIndex(chartBars, i); double pixXAdjust = x % 1 != 0 ? 0 : 0.5d; double pixYAdjust = y % 1 != 0 ? 0 : 0.5d; Vector pixelAdjustVec = new Vector(pixXAdjust, pixYAdjust); Point adjusted = new Point(x, y) + pixelAdjustVec; points[pointIdx] = adjusted.ToVector2(); ++pointIdx; } // cap it end->start points[pointIdx].X = chartControl.BarSpacingType == BarSpacingType.TimeBased || chartControl.BarSpacingType == BarSpacingType.EquidistantMulti && endIdx >= chartBars.Count ? chartControl.GetXByTime(chartBars.GetTimeByBarIdx(chartControl, endIdx)) : chartControl.GetXByBarIndex(chartBars, endIdx); points[pointIdx++].Y = chartScale.GetYByValue(Math.Max(chartScale.MinValue, Math.Min(chartScale.MaxValue, Price))); points[pointIdx].X = chartControl.BarSpacingType == BarSpacingType.TimeBased || chartControl.BarSpacingType == BarSpacingType.EquidistantMulti && startIdx >= chartBars.Count ? chartControl.GetXByTime(chartBars.GetTimeByBarIdx(chartControl, startIdx)) : chartControl.GetXByBarIndex(chartBars, startIdx); points[pointIdx++].Y = chartScale.GetYByValue(Math.Max(chartScale.MinValue, Math.Min(chartScale.MaxValue, Price))); } else { points = new SharpDX.Vector2[endIdx - startIdx + 1]; points2 = new SharpDX.Vector2[endIdx - startIdx + 1]; // fill clockwise from series1, the counter clockwise for series 2 for correct point poly winding for (int i = startIdx; i <= endIdx; ++i) { if (i < Math.Max(0, Displacement) || i > Math.Max(chartBars.Count - (nsb.Calculate == Calculate.OnBarClose ? 2 : 1) + Displacement, endIdx)) { continue; } int displacedIndex = Math.Min(chartBars.Count - (nsb.Calculate == Calculate.OnBarClose ? 2 : 1), Math.Max(0, i - Displacement)); float x = chartControl.BarSpacingType == BarSpacingType.TimeBased || chartControl.BarSpacingType == BarSpacingType.EquidistantMulti && i >= chartBars.Count //i is already displaced ? chartControl.GetXByTime(chartBars.GetTimeByBarIdx(chartControl, i)) : chartControl.GetXByBarIndex(chartBars, i); if (!series1Adjusted.IsValidDataPointAt(displacedIndex)) { continue; } double seriesValue = series1Adjusted.GetValueAt(displacedIndex); float y = chartScale.GetYByValue(seriesValue); double pixXAdjust = x % 1 != 0 ? 0 : 0.5d; double pixYAdjust = y % 1 != 0 ? 0 : 0.5d; Vector pixelAdjustVec = new Vector(pixXAdjust, pixYAdjust); Point adjusted = new Point(x, y) + pixelAdjustVec; points[pointIdx] = adjusted.ToVector2(); ++pointIdx; if (!series2Adjusted.IsValidDataPointAt(displacedIndex)) { continue; } seriesValue = series2Adjusted.GetValueAt(displacedIndex); y = chartScale.GetYByValue(seriesValue); pixYAdjust = y % 1 != 0 ? 0 : 0.5d; pixelAdjustVec = new Vector(pixXAdjust, pixYAdjust); adjusted = new Point(x, y) + pixelAdjustVec; points2[pointIdx2] = adjusted.ToVector2(); ++pointIdx2; } } if (pointIdx + pointIdx2 > 2) { RenderTarget.AntialiasMode = SharpDX.Direct2D1.AntialiasMode.PerPrimitive; if (OutlineStroke != null) { OutlineStroke.RenderTarget = RenderTarget; } if (AreaBrush != null) { if (areaBrushDevice.Brush == null) { Brush brushCopy = areaBrush.Clone(); brushCopy.Opacity = areaOpacity / 100d; areaBrushDevice.Brush = brushCopy; } areaBrushDevice.RenderTarget = RenderTarget; } SharpDX.Direct2D1.PathGeometry polyGeo = new SharpDX.Direct2D1.PathGeometry(Core.Globals.D2DFactory); SharpDX.Direct2D1.GeometrySink geoSink = polyGeo.Open(); double pixXAdjust = points[0].X % 1 != 0 ? 0 : 0.5d; double pixYAdjust = points[0].Y % 1 != 0 ? 0 : 0.5d; Vector pixelAdjustVec = new Vector(pixXAdjust, pixYAdjust); Point startPt = new Point(points[0].X, points[0].Y) + pixelAdjustVec; geoSink.BeginFigure(startPt.ToVector2(), SharpDX.Direct2D1.FigureBegin.Filled); geoSink.SetFillMode(SharpDX.Direct2D1.FillMode.Winding); // NOTE: We skip our first point since that is where the path will start for (int i = 1; i < pointIdx; i++) { geoSink.AddLine(points[i]); } for (int i = pointIdx2 - 1; i >= 0; i--) { geoSink.AddLine(points2[i]); } geoSink.EndFigure(SharpDX.Direct2D1.FigureEnd.Closed); geoSink.Close(); SharpDX.Direct2D1.Brush tmpBrush = IsInHitTest ? chartControl.SelectionBrush : areaBrushDevice == null ? null : areaBrushDevice.BrushDX; if (tmpBrush != null) { RenderTarget.FillGeometry(polyGeo, tmpBrush); } tmpBrush = IsInHitTest ? chartControl.SelectionBrush : OutlineStroke == null ? null : OutlineStroke.BrushDX; if (tmpBrush != null) { RenderTarget.DrawGeometry(polyGeo, OutlineStroke.BrushDX, OutlineStroke.Width); } polyGeo.Dispose(); } }