Exemplo n.º 1
0
        internal double CalcWidth(ReadOnlySpan <char> text)
        {
            if (NumberHelper.AreCloseZero(_fontSize))
            {
                return(0);
            }

            if (text.Length == 0)
            {
                return(0);
            }

            var textHashCode = HashCodeMaker.Make(text);

            if (_textWidthCache.TryGetValue(textHashCode, out var textWidth))
            {
                return(textWidth);
            }

            foreach (var c in text)
            {
                textWidth += CalcWidth(c);
            }

            _textWidthCache.Add(textHashCode, textWidth);

            return(textWidth);
        }
Exemplo n.º 2
0
        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();
            }
        }
Exemplo n.º 3
0
        internal double Draw(
            Visual visual,
            ReadOnlySpan <char> text,
            double x,
            double y,
            Brush brush,
            DrawingContext dc,
            double maxWidth,
            TextAlignment align,
            BiaTextTrimmingMode trimming,
            bool isUseCache)
        {
            if (NumberHelper.AreCloseZero(_fontSize))
            {
                return(0);
            }

            if (text.Length == 0)
            {
                return(0);
            }

            maxWidth = Math.Ceiling(maxWidth);

            if (maxWidth <= 0)
            {
                return(0);
            }

            var gr = trimming switch
            {
                BiaTextTrimmingMode.None => MakeGlyphRunNone(visual, text, maxWidth, isUseCache),
                BiaTextTrimmingMode.Standard => MakeGlyphRunStandard(visual, text, maxWidth, isUseCache),
                BiaTextTrimmingMode.Filepath => MakeGlyphRunFilepath(visual, text, maxWidth, isUseCache),
                _ => throw new ArgumentOutOfRangeException(nameof(trimming), trimming, null)
            };

            if (gr == default)
            {
                return(0);
            }

            switch (align)
            {
            case TextAlignment.Left:
                break;

            case TextAlignment.Right:
                x += maxWidth - gr.Width;
                break;

            case TextAlignment.Center:
                x += (maxWidth - gr.Width) / 2;
                break;

            default:
                throw new ArgumentOutOfRangeException(nameof(align), align, null);
            }

            if (NumberHelper.AreCloseZero(x) && NumberHelper.AreCloseZero(y))
            {
                dc.DrawGlyphRun(brush, gr.GlyphRun);
            }
            else
            {
                var hash = HashCodeMaker.Make(x, y);

                if (_translateCache.TryGetValue(hash, out var t) == false)
                {
                    t = new TranslateTransform(x, y);
                    _translateCache.Add(hash, t);
                }

                dc.PushTransform(t);
                dc.DrawGlyphRun(brush, gr.GlyphRun);
                dc.Pop();
            }

            return(gr.Width);
        }