示例#1
0
 void UpdateCache(ref CachedRenderString cache, string fontName, float size, string text, bool underline, TextAlignment alignment)
 {
     if (cache == null)
     {
         cache = new DirectWriteCachedText()
         {
             FontName  = fontName, FontSize = size, Text = text, Underline = underline,
             Alignment = alignment
         };
     }
     if (cache is not DirectWriteCachedText pc)
     {
         throw new ArgumentException("cache");
     }
     if (pc.quads == null || pc.Update(fontName, text, size, underline, alignment))
     {
         using (var layout = new TextLayout(dwFactory, text, GetFormat(fontName, ConvertSize(size)), float.MaxValue, float.MaxValue))
         {
             layout.TextAlignment = CastAlignment(alignment);
             layout.SetDrawingEffect(new ColorDrawingEffect(Color4.White, new TextShadow()), new TextRange(0, text.Length));
             layout.Draw(Renderer, 0, 0);
             pc.quads       = Renderer.Quads.ToArray();
             Renderer.Quads = new List <DrawQuad>();
             var metrics = layout.Metrics;
             pc.size = new Point((int)metrics.WidthIncludingTrailingWhitespace, (int)metrics.Height);
         }
     }
 }
示例#2
0
        public async Task TextLayout_Basic()
        {
            // Skip test on OSX: text rendering is subtly different.
            if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
            {
                return;
            }

            var t = new TextLayout(
                "Avalonia!",
                new Typeface(TestFontFamily),
                24,
                Brushes.Black);

            var target = new Border
            {
                Width      = 200,
                Height     = 200,
                Background = Brushes.White,
                Child      = new DrawnControl(c =>
                {
                    var textRect = t.Bounds;
                    var bounds   = new Rect(0, 0, 200, 200);
                    var rect     = bounds.CenterRect(textRect);
                    c.DrawRectangle(Brushes.Yellow, null, rect);
                    t.Draw(c, rect.Position);
                }),
            };

            await RenderToFile(target);

            CompareImages();
        }
示例#3
0
        public void Draw()
        {
            if (rectEnabled)
            {
                renderer.brush2d.Color = rectColor;
                renderer.rtv2d.FillRectangle(rect, renderer.brush2d);
            }

            float x = hookViewport ? pos.X + renderer.GetViewport.X : pos.X;
            float y = hookViewport ? pos.Y + renderer.GetViewport.Y : pos.Y;

            renderer.brush2d.Color = color;

            if (renderer.msgToSurf[OSDMessage.Type.Subtitles] == name)
            {
                y -= renderer.SubsPosition;
                //renderer.rtv2d.DrawTextLayout(new RawVector2(x, y), layout, renderer.brush2d);
                try
                {
                    // Draw outline
                    layout.Draw(renderer.outlineRenderer, x, y);
                } catch (Exception)
                {
                    // Fallback in failure (will happen if custom effect were applied)
                    renderer.rtv2d.DrawTextLayout(new RawVector2(x, y), layout, renderer.brush2d);
                }
            }
            else
            {
                renderer.rtv2d.DrawTextLayout(new RawVector2(x, y), layout, renderer.brush2d);
            }
        }
示例#4
0
        public void Draw()
        {
            if (rectEnabled)
            {
                renderer.brush2d.Color = rectColor;
                renderer.rtv2d.FillRectangle(rect, renderer.brush2d);
            }

            float x = hookViewport ? pos.X + renderer.GetViewport.X : pos.X;
            float y = hookViewport ? pos.Y + renderer.GetViewport.Y : pos.Y;

            renderer.brush2d.Color = color;

            // Outline: For better performance maybe should create new fonts with outline
            if (renderer.msgToSurf[OSDMessage.Type.Subtitles] == name)
            {
                y -= renderer.SubsPosition;
                renderer.rtv2d.DrawTextLayout(new RawVector2(x, y), layout, renderer.brush2d);
                layout.Draw(renderer.outlineRenderer, x, y);
            }
            else
            {
                renderer.rtv2d.DrawTextLayout(new RawVector2(x, y), layout, renderer.brush2d);
            }
        }
 public override void DrawStringBaseline(string fontName, float size, string text, float x, float y, float start_x, Color4 color, bool underline = false, TextShadow shadow = default)
 {
     using (var layout = new TextLayout(dwFactory, text, GetFormat(fontName, ConvertSize(size)), float.MaxValue, float.MaxValue))
     {
         var indent = (x - start_x);
         if (Math.Abs(indent) > 0.001f)
         {
             layout.SetInlineObject(new Indent(indent), new TextRange(0, 0));
         }
         layout.SetDrawingEffect(new ColorDrawingEffect(color, shadow), new TextRange(0, text.Length));
         layout.Draw(Renderer, 0, 0);
         foreach (var q in Renderer.Quads)
         {
             var d = q.Destination;
             d.X += (int)start_x;
             d.Y += (int)y;
             if (q.Texture == null)
             {
                 render2d.FillRectangle(d, q.Color);
             }
             else
             {
                 render2d.Draw(q.Texture, q.Source, d, q.Color);
             }
         }
         Renderer.Quads = new List <DrawQuad>();
     }
 }
 public static void DrawTextLayout(
     RenderTarget renderTarget,
     Vector2 origin,
     TextLayout textLayout,
     Brush defaultForegroundBrush,
     DrawTextOptions options = DrawTextOptions.None)
 {
     if (options.HasFlag(DrawTextOptions.Clip))
     {
         renderTarget.PushAxisAlignedClip(new global::SharpDX.RectangleF(origin.X, origin.Y, textLayout.MaxWidth, textLayout.MaxHeight), renderTarget.AntialiasMode);
         using (var renderer = new CustomBrushTextRenderer(renderTarget, defaultForegroundBrush, options.HasFlag(DrawTextOptions.NoSnap)))
             textLayout.Draw(renderer, origin.X, origin.Y);
         renderTarget.PopAxisAlignedClip();
     }
     else
     {
         using (var renderer = new CustomBrushTextRenderer(renderTarget, defaultForegroundBrush, options.HasFlag(DrawTextOptions.NoSnap)))
             textLayout.Draw(renderer, origin.X, origin.Y);
     }
 }
示例#7
0
        public override void Render(DrawingContext context)
        {
            var background = Background;

            if (background != null)
            {
                context.FillRectangle(background, new Rect(Bounds.Size));
            }

            var padding = Padding;

            if (TextLayout != null)
            {
                _textWidth  = TextLayout.Size.Width;
                _textHeight = TextLayout.Size.Height;

                var constraints      = Bounds.Deflate(Padding);
                var constraintsWidth = constraints.Width;

                //让文字不要在宽度合适的时候滚动
                _isConstrained = _textWidth > constraintsWidth + 1;

                if (_isConstrained & !_waiting)
                {
                    _animate = true;
                    var tOffset = padding.Left - _offset;

                    _offsets[0] = tOffset;
                    _offsets[1] = tOffset + _textWidth + TextGap;
                    _offsets[2] = tOffset + (_textWidth + TextGap) * 2;

                    foreach (var offset in _offsets)
                    {
                        var nR = new Rect(offset, padding.Top, _textWidth, _textHeight);
                        var nC = new Rect(0, padding.Top, constraintsWidth, constraints.Height);

                        if (nC.Intersects(nR))
                        {
                            using (context.PushPostTransform(Matrix.CreateTranslation(offset, padding.Top)))
                                //TextLayout.Draw(context, new Point(Padding.Left, Padding.Top));
                                TextLayout.Draw(context);
                        }
                    }
                }
                else
                {
                    _animate = false;

                    using (context.PushPostTransform(Matrix.CreateTranslation(padding.Left, padding.Top)))
                        //TextLayout.Draw(context, new Point(Padding.Left, Padding.Top));
                        TextLayout.Draw(context);
                }
            }
        }
示例#8
0
        private void DrawCharacter(string character, bool stretched, TextLayout layout)
        {
            if (!_drawingOutline)
            {
                DeviceContext.DrawTextLayout(_baselineOrigin, layout, _whiteBrush);
            }
            else
            {
                layout.Draw(_outlineRenderer, _baselineOrigin.X, _baselineOrigin.Y);
            }

            _widths[_idxCurrent] = Measure(character, layout, stretched);
            _idxCurrent++;
        }
示例#9
0
        public override void Render(DrawingContext context)
        {
            var background = Background;

            if (background != null)
            {
                context.FillRectangle(background, new Rect(Bounds.Size));
            }

            var padding = Padding;

            if (TextLayout != null)
            {
                _textWidth  = TextLayout.Bounds.Width;
                _textHeight = TextLayout.Bounds.Height;

                var constraints      = this.Bounds.Deflate(Padding);
                var constraintsWidth = constraints.Width;

                _isConstrained = _textWidth >= constraintsWidth;

                if (_isConstrained & !_waiting)
                {
                    _animate = true;
                    var tOffset = padding.Left - _offset;

                    _offsets[0] = tOffset;
                    _offsets[1] = tOffset + _textWidth + this.TextGap;
                    _offsets[2] = tOffset + (_textWidth + this.TextGap) * 2;

                    foreach (var offset in _offsets)
                    {
                        var nR = new Rect(offset, padding.Top, _textWidth, _textHeight);
                        var nC = new Rect(0, padding.Top, constraintsWidth, constraints.Height);

                        if (nC.Intersects(nR))
                        {
                            TextLayout.Draw(context.PlatformImpl, new Point(offset, padding.Top));
                        }
                    }
                }
                else
                {
                    _animate = false;
                    TextLayout.Draw(context.PlatformImpl, new Point(padding.Left, padding.Top));
                }
            }
        }
示例#10
0
        public async Task TextLayout_Rotated()
        {
            // Skip test on OSX: text rendering is subtly different.
            if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
            {
                return;
            }

            var t = new TextLayout(
                "Avalonia!",
                new Typeface(TestFontFamily),
                24,
                Brushes.Black);

            var target = new Border
            {
                Width      = 200,
                Height     = 200,
                Background = Brushes.White,
                Child      = new DrawnControl(c =>
                {
                    var textRect = t.Bounds;
                    var bounds   = new Rect(0, 0, 200, 200);
                    var rect     = bounds.CenterRect(textRect);
                    var rotate   = Matrix.CreateTranslation(-100, -100) *
                                   Matrix.CreateRotation(MathUtilities.Deg2Rad(90)) *
                                   Matrix.CreateTranslation(100, 100);
                    using var transform = c.PushPreTransform(rotate);
                    c.DrawRectangle(Brushes.Yellow, null, rect);
                    t.Draw(c, rect.Position);
                }),
            };

            await RenderToFile(target);

            CompareImages();
        }
示例#11
0
        internal override void Draw()
        {
            base.Draw();

            lock (Locker)
            {
                if (_textLayout == null)
                {
                    UpdateTextLayout();
                }

                Debug.Assert(_textLayout != null, "_textLayout != null");

                if (_textRenderer.OutlineBrush.Opacity > 0)
                {
                    _textRenderer.Location = RenderRect.Location;
                    _textLayout.Draw(_textRenderer, 0, 0);
                }
                else
                {
                    Renderer.Context2D.DrawTextLayout(RenderRect.Location, _textLayout, _textRenderer.FillBrush, DrawTextOptions.EnableColorFont);
                }
            }
        }
示例#12
0
        protected override DX11VertexGeometry GetGeom(DX11RenderContext device, int slice)
        {
            if (d2dFactory == null)
            {
                d2dFactory = new D2DFactory();
                dwFactory  = new DWriteFactory(SharpDX.DirectWrite.FactoryType.Shared);
            }

            TextFormat fmt = new TextFormat(dwFactory, this.FFontInput[slice].Name, FFontSize[slice]);
            TextLayout tl  = new TextLayout(dwFactory, FText[slice], fmt, 0.0f, 32.0f);

            tl.WordWrapping       = WordWrapping.NoWrap;
            tl.TextAlignment      = FHAlignment[slice];
            tl.ParagraphAlignment = FVAlignment[slice];

            OutlineRenderer renderer = new OutlineRenderer(d2dFactory);
            Extruder        ex       = new Extruder(d2dFactory);


            tl.Draw(renderer, 0.0f, 0.0f);

            var outlinedGeometry = renderer.GetGeometry();

            ex.GetVertices(outlinedGeometry, vertexList, this.FExtrude[slice]);
            outlinedGeometry.Dispose();

            Vector3 min = new Vector3(float.MaxValue);
            Vector3 max = new Vector3(float.MinValue);

            for (int i = 0; i < vertexList.Count; i++)
            {
                Pos3Norm3VertexSDX pn = vertexList[i];

                min.X = pn.Position.X < min.X ? pn.Position.X : min.X;
                min.Y = pn.Position.Y < min.Y ? pn.Position.Y : min.Y;
                min.Z = pn.Position.Z < min.Z ? pn.Position.Z : min.Z;

                max.X = pn.Position.X > max.X ? pn.Position.X : max.X;
                max.Y = pn.Position.Y > max.Y ? pn.Position.Y : max.Y;
                max.Z = pn.Position.Z > max.Z ? pn.Position.Z : max.Z;
            }

            SlimDX.DataStream ds = new SlimDX.DataStream(vertexList.Count * Pos3Norm3VertexSDX.VertexSize, true, true);
            ds.Position = 0;

            for (int i = 0; i < vertexList.Count; i++)
            {
                ds.Write(vertexList[i]);
            }

            ds.Position = 0;

            var vbuffer = new SlimDX.Direct3D11.Buffer(device.Device, ds, new SlimDX.Direct3D11.BufferDescription()
            {
                BindFlags      = SlimDX.Direct3D11.BindFlags.VertexBuffer,
                CpuAccessFlags = SlimDX.Direct3D11.CpuAccessFlags.None,
                OptionFlags    = SlimDX.Direct3D11.ResourceOptionFlags.None,
                SizeInBytes    = (int)ds.Length,
                Usage          = SlimDX.Direct3D11.ResourceUsage.Default
            });

            ds.Dispose();

            DX11VertexGeometry vg = new DX11VertexGeometry(device);

            vg.InputLayout    = Pos3Norm3VertexSDX.Layout;
            vg.Topology       = SlimDX.Direct3D11.PrimitiveTopology.TriangleList;
            vg.VertexBuffer   = vbuffer;
            vg.VertexSize     = Pos3Norm3VertexSDX.VertexSize;
            vg.VerticesCount  = vertexList.Count;
            vg.HasBoundingBox = true;
            vg.BoundingBox    = new SlimDX.BoundingBox(new SlimDX.Vector3(min.X, min.Y, min.Z), new SlimDX.Vector3(max.X, max.Y, max.Z));

            renderer.Dispose();
            fmt.Dispose();
            tl.Dispose();

            return(vg);
        }
示例#13
0
 public override void Render()
 {
     TextLayout.Draw(textRenderer, AbsolutePosition.X, AbsolutePosition.Y);
 }
示例#14
0
        public static DX11VertexGeometry Text3d(DX11RenderContext device, string text, string fontName, float fontSize, float extrude, TextAlignment textAlignment, ParagraphAlignment paragraphAlignment)
        {
            //Dictionary<DX11RenderContext, DX11VertexGeometry> deviceDict = null;
            //if (TextGeometryCache.TryGetValue(text, out deviceDict))
            //{
            //    DX11VertexGeometry geom;
            //    if(deviceDict.TryGetValue(device, out geom))
            //    {
            //        return geom;
            //    }
            //}

            if (d2dFactory == null)
            {
                d2dFactory = new D2DFactory();
                dwFactory  = new DWriteFactory(SharpDX.DirectWrite.FactoryType.Shared);
            }

            TextFormat fmt = new TextFormat(dwFactory, fontName, fontSize);

            TextLayout tl = new TextLayout(dwFactory, text, fmt, 0.0f, .0f);

            tl.WordWrapping       = WordWrapping.NoWrap;
            tl.TextAlignment      = (SharpDX.DirectWrite.TextAlignment)textAlignment;
            tl.ParagraphAlignment = (SharpDX.DirectWrite.ParagraphAlignment)paragraphAlignment;

            OutlineRenderer renderer = new OutlineRenderer(d2dFactory);
            Extruder        ex       = new Extruder(d2dFactory);

            tl.Draw(renderer, 0.0f, 0.0f);

            var geo    = renderer.GetGeometry();
            var result = ex.GetVertices(geo, extrude).ToArray();

            renderer.Dispose();
            geo.Dispose();
            fmt.Dispose();
            tl.Dispose();

            Vector3 min = new Vector3(float.MaxValue);
            Vector3 max = new Vector3(float.MinValue);

            foreach (var pn in result)
            {
                min.X = pn.Position.X < min.X ? pn.Position.X : min.X;
                min.Y = pn.Position.Y < min.Y ? pn.Position.Y : min.Y;
                min.Z = pn.Position.Z < min.Z ? pn.Position.Z : min.Z;

                max.X = pn.Position.X > max.X ? pn.Position.X : max.X;
                max.Y = pn.Position.Y > max.Y ? pn.Position.Y : max.Y;
                max.Z = pn.Position.Z > max.Z ? pn.Position.Z : max.Z;
            }

            SlimDX.DataStream ds = new SlimDX.DataStream(result.Length * Pos3Norm3VertexSDX.VertexSize, true, true);
            ds.Position = 0;

            ds.WriteRange(result);

            ds.Position = 0;

            var vbuffer = new SlimDX.Direct3D11.Buffer(device.Device, ds, new SlimDX.Direct3D11.BufferDescription()
            {
                BindFlags      = SlimDX.Direct3D11.BindFlags.VertexBuffer,
                CpuAccessFlags = SlimDX.Direct3D11.CpuAccessFlags.None,
                OptionFlags    = SlimDX.Direct3D11.ResourceOptionFlags.None,
                SizeInBytes    = (int)ds.Length,
                Usage          = SlimDX.Direct3D11.ResourceUsage.Default,
            });

            ds.Dispose();

            DX11VertexGeometry vg = new DX11VertexGeometry(device);

            vg.InputLayout    = Pos3Norm3VertexSDX.Layout;
            vg.Topology       = SlimDX.Direct3D11.PrimitiveTopology.TriangleList;
            vg.VertexBuffer   = vbuffer;
            vg.VertexSize     = Pos3Norm3VertexSDX.VertexSize;
            vg.VerticesCount  = result.Length;
            vg.HasBoundingBox = true;
            vg.BoundingBox    = new SlimDX.BoundingBox(new SlimDX.Vector3(min.X, min.Y, min.Z), new SlimDX.Vector3(max.X, max.Y, max.Z));


            //if(deviceDict != null)
            //{
            //    deviceDict[device] = vg;
            //}
            //else
            //{
            //    deviceDict = new Dictionary<DX11RenderContext, DX11VertexGeometry>();
            //    deviceDict[device] = vg;
            //    TextGeometryCache[text] = deviceDict;
            //}

            return(vg);
        }
        protected override void OnRender(WindowRenderTarget renderTarget)
        {
            PointF origin = new PointF(0, 0);

            _textLayout.Draw(_customRenderer, origin.X, origin.Y);
        }
示例#16
0
        static void Main(string[] args)
        {
            mainForm = new RenderForm("Advanced Text rendering demo");

            d2dFactory = new D2DFactory();
            dwFactory  = new DWriteFactory(SharpDX.DirectWrite.FactoryType.Shared);

            textRenderer = new CustomColorRenderer();

            CreateResources();

            var bgcolor = new Color4(0.1f, 0.1f, 0.1f, 1.0f);

            //This is the offset where we start our text layout
            Vector2 offset = new Vector2(202.0f, 250.0f);

            textFormat = new TextFormat(dwFactory, "Arial", FontWeight.Regular, FontStyle.Normal, 16.0f);
            textLayout = new TextLayout(dwFactory, introText, textFormat, 300.0f, 200.0f);

            //Apply various modifications to text
            textLayout.SetUnderline(true, new TextRange(0, 5));
            textLayout.SetDrawingEffect(greenBrush, new TextRange(10, 20));
            textLayout.SetFontSize(24.0f, new TextRange(6, 4));
            textLayout.SetFontFamilyName("Comic Sans MS", new TextRange(11, 7));

            //Measure full layout
            var textSize = textLayout.Metrics;

            fullTextBackground = new RectangleF(textSize.Left + offset.X, textSize.Top + offset.Y, textSize.Width, textSize.Height);

            //Measure text to apply background to
            var metrics = textLayout.HitTestTextRange(53, 4, 0.0f, 0.0f)[0];

            textRegionRect = new RectangleF(metrics.Left + offset.X, metrics.Top + offset.Y, metrics.Width, metrics.Height);

            //Assign render target and brush to our custom renderer
            textRenderer.AssignResources(renderTarget, defaultBrush);

            RenderLoop.Run(mainForm, () =>
            {
                renderTarget.BeginDraw();
                renderTarget.Clear(bgcolor);

                renderTarget.FillRectangle(fullTextBackground, backgroundBrush);

                renderTarget.FillRectangle(textRegionRect, redBrush);

                textLayout.Draw(textRenderer, offset.X, offset.Y);

                try
                {
                    renderTarget.EndDraw();
                }
                catch
                {
                    CreateResources();
                }
            });

            d2dFactory.Dispose();
            dwFactory.Dispose();
            renderTarget.Dispose();
        }