/// <summary> /// Draws a geometry. /// </summary> /// <param name="brush">The fill brush.</param> /// <param name="pen">The stroke pen.</param> /// <param name="geometry">The geometry.</param> public void DrawGeometry(IBrush brush, IPen pen, IGeometryImpl geometry) { if (brush != null) { using (var d2dBrush = CreateBrush(brush, geometry.Bounds.Size)) { if (d2dBrush.PlatformBrush != null) { var impl = (GeometryImpl)geometry; _deviceContext.FillGeometry(impl.Geometry, d2dBrush.PlatformBrush); } } } if (pen != null) { using (var d2dBrush = CreateBrush(pen.Brush, geometry.GetRenderBounds(pen).Size)) using (var d2dStroke = pen.ToDirect2DStrokeStyle(_deviceContext)) { if (d2dBrush.PlatformBrush != null) { var impl = (GeometryImpl)geometry; _deviceContext.DrawGeometry(impl.Geometry, d2dBrush.PlatformBrush, (float)pen.Thickness, d2dStroke); } } } }
private void Render() { DeviceContext renderTarget = _deviceContext; renderTarget.BeginDraw(); List <Tuple <Geometry, Color> > copy = _task == null ? new List <Tuple <Geometry, Color> >() : _task.Result; _task = CreateGeometries(_time); if (_time == 0.1f) { renderTarget.Clear(Color.FromKnown(Colors.Black, 1f)); } renderTarget.FillRect(_brush, new RectF(0, 0, ClientSize.Width, ClientSize.Height)); for (int index = 0; index < copy.Count; ++index) { Tuple <Geometry, Color> tuple = copy[index]; using (Geometry geometry = tuple.Item1) { using (SolidColorBrush brush = renderTarget.CreateSolidColorBrush(tuple.Item2.AdjustContrast(1.5f))) { renderTarget.DrawGeometry(brush, 0.1f, geometry); } } } renderTarget.EndDraw(); _swapChain.Present(1, 0); _time += 0.002f; }
private void DrawCurves(DeviceContext target, bool isDrawArrow, float lineWidth) { if (_parent.LinksSource is null) { return; } var arrowSize = BaseArrowSize / (float)_parent.ScaleTransform.ScaleX; var inflate = arrowSize; var viewport = _parent.TransformRect(ActualWidth, ActualHeight); var lineCullingRect = new ImmutableRect_float( (float)viewport.X - inflate, (float)viewport.Y - inflate, (float)viewport.Width + inflate * 2f, (float)viewport.Height + inflate * 2f ); var hasHighlightCurves = false; var borderKey = HashCodeMaker.To32(ByteColor.Black.HashCode); if (ResourceCache.TryGetValue(borderKey, out var borderBrushObj) == false) { borderBrushObj = ResourceCache.Add(borderKey, t => ColorToBrushConv(t, ByteColor.Black)); } var borderBrush = borderBrushObj as Brush; Span <ImmutableVec2_float> bezier = stackalloc ImmutableVec2_float[4]; using var curves = new TempBuffer <(PathGeometry Geom, GeometrySink Sink, IBiaNodeLink Link)>(256); foreach (IBiaNodeLink?link in _parent.LinksSource) { if (link is null) { continue; } if (link.IsVisible == false) { continue; } if (link.IsLinked() == false) { continue; } var isHighlight = link.IsHighlight(); if (isHighlight) { hasHighlightCurves = true; } // ハイライトがあれば、非ハイライトを表示しない if (hasHighlightCurves && isHighlight == false) { continue; } link.MakeBezierCurve(bezier); var keyBezier = MakeHashCode(bezier); if (_boundingBoxCache.TryGetValue(keyBezier, out var bb) == false) { bb = BiaNodeEditorHelper.MakeBoundingBox(bezier); _boundingBoxCache.Add(keyBezier, bb); } if (bb.IntersectsWith(lineCullingRect) == false) { continue; } var curveGeom = new PathGeometry(target.Factory); var curveSink = curveGeom.Open(); curveSink.SetFillMode(FillMode.Winding); curveSink.BeginFigure(Unsafe.As <ImmutableVec2_float, RawVector2>(ref bezier[0]), FigureBegin.Hollow); curveSink.AddBezier(Unsafe.As <ImmutableVec2_float, BezierSegment>(ref bezier[1])); curveSink.EndFigure(FigureEnd.Open); if (isDrawArrow) { DrawArrow(curveSink, bezier, arrowSize); } curveSink.Close(); // ReSharper disable once PossiblyImpureMethodCallOnReadonlyVariable curves.Add((curveGeom, curveSink, link)); } foreach (var(geom, sink, link) in curves.Buffer) { var isHighlight = link.IsHighlight(); if (hasHighlightCurves == false || isHighlight) { var key = HashCodeMaker.Make(link.Color, isHighlight); var resKey = HashCodeMaker.To32(key); if (ResourceCache.TryGetValue(resKey, out var brush) == false) { brush = ResourceCache.Add(resKey, t => ColorToBrushConv(t, link.Color)); } target.DrawGeometry(geom, borderBrush, lineWidth * 2f); target.DrawGeometry(geom, brush as Brush, lineWidth); target.FillGeometry(geom, brush as Brush); } sink.Dispose(); geom.Dispose(); } }
internal override void DoWork(DeviceContext context) { context.DrawGeometry(Geometry, Brush, StrokeWidth, StrokeStyle); }